edc_mca.c revision 1.10 1 /* $NetBSD: edc_mca.c,v 1.10 2001/11/13 07:46:25 lukem Exp $ */
2
3 /*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Jaromir Dolecek.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the NetBSD
20 * Foundation, Inc. and its contributors.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /*
37 * Driver for MCA ESDI controllers and disks conforming to IBM DASD
38 * spec.
39 *
40 * The driver was written with DASD Storage Interface Specification
41 * for MCA rev. 2.2 in hands, thanks to Scott Telford <st (at) epcc.ed.ac.uk>.
42 *
43 * TODO:
44 * - move the MCA DMA controller (edc_setup_dma()) goo to device driver
45 * independant location
46 * - improve error recovery
47 * add any soft resets when anything gets stuck?
48 * - test with > 1 disk (this is supported by some controllers), eliminate
49 * any remaining devno=0 assumptions if there are any still
50 * - test with > 1 ESDI controller in machine; shared interrupts
51 * necessary for this to work should be supported - edc_intr() specifically
52 * checks if the interrupt is for this controller
53 */
54
55 #include <sys/cdefs.h>
56 __KERNEL_RCSID(0, "$NetBSD: edc_mca.c,v 1.10 2001/11/13 07:46:25 lukem Exp $");
57
58 #include "rnd.h"
59
60 #include <sys/param.h>
61 #include <sys/systm.h>
62 #include <sys/errno.h>
63 #include <sys/device.h>
64 #include <sys/malloc.h>
65 #include <sys/endian.h>
66 #include <sys/disklabel.h>
67 #include <sys/disk.h>
68 #include <sys/syslog.h>
69 #include <sys/proc.h>
70 #include <sys/vnode.h>
71 #include <sys/kernel.h>
72 #if NRND > 0
73 #include <sys/rnd.h>
74 #endif
75
76 #include <machine/bus.h>
77 #include <machine/intr.h>
78
79 #include <dev/mca/mcareg.h>
80 #include <dev/mca/mcavar.h>
81 #include <dev/mca/mcadevs.h>
82
83 #include <dev/mca/edcreg.h>
84 #include <dev/mca/edvar.h>
85 #include <dev/mca/edcvar.h>
86
87 #define EDC_ATTN_MAXTRIES 10000 /* How many times check for unbusy */
88
89 struct edc_mca_softc {
90 struct device sc_dev;
91
92 bus_space_tag_t sc_iot;
93 bus_space_handle_t sc_ioh;
94
95 bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */
96 bus_space_handle_t sc_dmaextcmdh;
97 bus_space_handle_t sc_dmaexech;
98
99 void *sc_ih; /* interrupt handle */
100 int sc_drq; /* DRQ number */
101 int sc_cmd_async; /* asynchronous cmd pending */
102
103 int sc_flags;
104 #define DASD_QUIET 0x01 /* don't dump cmd error info */
105 #define DASD_MAXDEVS 8
106 struct ed_softc *sc_ed[DASD_MAXDEVS];
107 struct ed_softc sc_controller;
108 };
109
110 int edc_mca_probe __P((struct device *, struct cfdata *, void *));
111 void edc_mca_attach __P((struct device *, struct device *, void *));
112
113 struct cfattach edc_mca_ca = {
114 sizeof(struct edc_mca_softc), edc_mca_probe, edc_mca_attach
115 };
116
117 #define DMA_EXTCMD 0x18
118 #define DMA_EXEC 0x1A
119
120 static int edc_intr __P((void *));
121 static void edc_dump_status_block __P((struct edc_mca_softc *, int, int));
122 static int edc_setup_dma __P((struct edc_mca_softc *, int,
123 bus_addr_t, bus_size_t));
124 static int edc_do_attn __P((struct edc_mca_softc *, int, int, int));
125 static int edc_cmd_wait __P((struct edc_mca_softc *, int, int, int));
126
127 int
128 edc_mca_probe(parent, match, aux)
129 struct device *parent;
130 struct cfdata *match;
131 void *aux;
132 {
133 struct mca_attach_args *ma = aux;
134
135 switch (ma->ma_id) {
136 case MCA_PRODUCT_IBM_ESDIC:
137 case MCA_PRODUCT_IBM_ESDIC_IG:
138 return (1);
139 default:
140 return (0);
141 }
142 }
143
144 void
145 edc_mca_attach(parent, self, aux)
146 struct device *parent, *self;
147 void *aux;
148 {
149 struct edc_mca_softc *sc = (void *) self;
150 struct mca_attach_args *ma = aux;
151 int pos2, pos3, pos4;
152 int irq, drq, iobase;
153 const char *typestr;
154 struct ed_softc *ed;
155 struct ed_attach_args eda;
156 int devno, maxdevs;
157
158 pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2);
159 pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3);
160 pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4);
161
162 /*
163 * POS register 2: (adf pos0)
164 *
165 * 7 6 5 4 3 2 1 0
166 * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled
167 * \ \ \___ Primary/Alternate Port Adresses:
168 * \ \ 0=0x3510-3517 1=0x3518-0x351f
169 * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7
170 * \ 0000=0 0001=1 0011=3 0100=4
171 * \_________ Fairness On/Off: 1=On 0=Off
172 *
173 * POS register 3: (adf pos1)
174 *
175 * 7 6 5 4 3 2 1 0
176 * 0 0 \_/
177 * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms
178 * 01=16ms 00=Burst Disabled
179 *
180 * POS register 4: (adf pos2)
181 *
182 * 7 6 5 4 3 2 1 0
183 * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled
184 * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate
185 *
186 * IRQ is fixed to 14 (0x0e).
187 */
188
189 switch (ma->ma_id) {
190 case MCA_PRODUCT_IBM_ESDIC:
191 typestr = "IBM ESDI Fixed Disk Controller";
192 break;
193 case MCA_PRODUCT_IBM_ESDIC_IG:
194 typestr = "IBM Integ. ESDI Fixed Disk & Controller";
195 break;
196 default:
197 /* never reached */
198 }
199
200 irq = ESDIC_IRQ;
201 iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM;
202 drq = (pos2 & DRQ_MASK) >> 2;
203
204 printf(" slot %d irq %d drq %d: %s\n", ma->ma_slot+1,
205 irq, drq, typestr);
206
207 #ifdef DIAGNOSTIC
208 /*
209 * It's not strictly necessary to check this, machine configuration
210 * utility uses only valid adresses.
211 */
212 if (drq == 2 || drq >= 8) {
213 printf("%s: invalid DMA Arbitration Level %d\n",
214 sc->sc_dev.dv_xname, drq);
215 return;
216 }
217 #endif
218
219 printf("%s: Fairness %s, Release %s, ",
220 sc->sc_dev.dv_xname,
221 (pos2 & FAIRNESS_ENABLE) ? "On" : "Off",
222 (pos4 & RELEASE_1) ? "6ms"
223 : ((pos4 & RELEASE_2) ? "3ms" : "Immediate")
224 );
225 if ((pos4 & PACING_CTRL_DISABLE) == 0) {
226 static const char * const pacint[] =
227 { "disabled", "16ms", "24ms", "31ms"};
228 printf("DMA burst pacing interval %s\n",
229 pacint[(pos3 & PACING_INT_MASK) >> 4]);
230 } else
231 printf("DMA pacing control disabled\n");
232
233 sc->sc_iot = ma->ma_iot;
234 sc->sc_drq = drq;
235
236 if (bus_space_map(sc->sc_iot, iobase,
237 ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) {
238 printf("%s: couldn't map registers\n",
239 sc->sc_dev.dv_xname);
240 return;
241 }
242
243 if (bus_space_map(sc->sc_iot, DMA_EXTCMD, 1, 0, &sc->sc_dmaextcmdh)) {
244 printf("%s: couldn't map registers\n",
245 sc->sc_dev.dv_xname);
246 return;
247 }
248 if (bus_space_map(sc->sc_iot, DMA_EXEC, 1, 0, &sc->sc_dmaexech)) {
249 printf("%s: couldn't map registers\n",
250 sc->sc_dev.dv_xname);
251 return;
252 }
253
254 sc->sc_dmat = ma->ma_dmat;
255
256 sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, edc_intr, sc);
257 if (sc->sc_ih == NULL) {
258 printf("%s: couldn't establish interrupt handler\n",
259 sc->sc_dev.dv_xname);
260 return;
261 }
262
263 /*
264 * Integrated ESDI controller supports only one disk, other
265 * controllers support two disks.
266 */
267 if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG)
268 maxdevs = 1;
269 else
270 maxdevs = 2;
271
272 /*
273 * Initialize the controller ed softc. We could do without this,
274 * but absence of checks for controller devno simplifies code logic
275 * somewhat.
276 */
277 sc->sc_ed[DASD_DEVNO_CONTROLLER] = &sc->sc_controller;
278 strcpy(sc->sc_controller.sc_dev.dv_xname, sc->sc_dev.dv_xname);/*safe*/
279
280 /*
281 * Reset controller and attach individual disks. ed attach routine
282 * uses polling so that this works with interrupts disabled.
283 */
284
285 /* Do a reset to ensure sane state after warm boot. */
286 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) {
287 /* hard reset */
288 printf("%s: controller busy, performing hardware reset ...\n",
289 sc->sc_dev.dv_xname);
290 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
291 BCR_INT_ENABLE|BCR_RESET);
292 } else {
293 /* "SOFT" reset */
294 edc_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0);
295 }
296
297 /*
298 * Since interrupts are disabled ATM, it's necessary
299 * to detect the interrupt request and call edc_intr()
300 * explicitly. See also edc_run_cmd().
301 */
302 while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) {
303 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR)
304 edc_intr(sc);
305
306 delay(100);
307 }
308
309 /*
310 * Get dummy ed_softc to be used during probe. Once a disk is
311 * found, ed_mca_attach() calls edc_add_disk() to insert the
312 * right pointer into sc->sc_ed[] array.
313 */
314 MALLOC(ed, struct ed_softc *, sizeof(struct ed_softc),
315 M_TEMP, M_WAITOK);
316
317 /* be quiet duting probes */
318 sc->sc_flags |= DASD_QUIET;
319
320 /* check for attached disks */
321 for(devno=0; devno < maxdevs; devno++) {
322 eda.sc_devno = devno;
323 eda.sc_dmat = sc->sc_dmat;
324 sc->sc_ed[devno] = ed;
325 (void *) config_found_sm(self, &eda, NULL, NULL);
326 }
327
328 /* enable full error dumps again */
329 sc->sc_flags &= ~DASD_QUIET;
330
331 /* cleanup */
332 FREE(ed, M_TEMP);
333
334 /*
335 * Check if there are any disks attached. If not, disestablish
336 * the interrupt.
337 */
338 for(devno=0; devno < maxdevs; devno++) {
339 if (sc->sc_ed[devno] && (sc->sc_ed[devno]->sc_flags & EDF_INIT))
340 break;
341 }
342 if (devno == maxdevs) {
343 printf("%s: disabling controller (no drives attached)\n",
344 sc->sc_dev.dv_xname);
345 mca_intr_disestablish(ma->ma_mc, sc->sc_ih);
346 }
347 }
348
349 void
350 edc_add_disk(sc, ed, devno)
351 struct edc_mca_softc *sc;
352 struct ed_softc *ed;
353 int devno;
354 {
355 sc->sc_ed[devno] = ed;
356 }
357
358 static int
359 edc_intr(arg)
360 void *arg;
361 {
362 struct edc_mca_softc *sc = arg;
363 u_int8_t isr, intr_id;
364 u_int16_t sifr;
365 int cmd=-1, devno, bioerror=0;
366 struct ed_softc *ed=NULL;
367
368 /*
369 * Check if the interrupt was for us.
370 */
371 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0)
372 return (0);
373
374 /*
375 * Read ISR to find out interrupt type. This also clears the interrupt
376 * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2
377 * and 4 are reserved and not used.
378 */
379 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR);
380 intr_id = isr & ISR_INTR_ID_MASK;
381
382 #ifdef DEBUG
383 if (intr_id == 0 || intr_id == 2 || intr_id == 4) {
384 printf("%s: bogus interrupt id %d\n", sc->sc_dev.dv_xname,
385 (int) intr_id);
386 return (0);
387 }
388 #endif
389
390 /* Get number of device whose intr this was */
391 devno = (isr & 0xe0) >> 5;
392
393 /*
394 * Get Status block. Higher byte always says how long the status
395 * block is, rest is device number and command code.
396 * Check the status block length against our supported maximum length
397 * and fetch the data.
398 */
399 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL) {
400 size_t len;
401 int i;
402
403 sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
404 len = (sifr & 0xff00) >> 8;
405 #ifdef DEBUG
406 if (len > DASD_MAX_CMD_RES_LEN)
407 panic("%s: maximum Status Length exceeded: %d > %d",
408 sc->sc_dev.dv_xname,
409 len, DASD_MAX_CMD_RES_LEN);
410 #endif
411
412 /* Get command code */
413 cmd = sifr & SIFR_CMD_MASK;
414
415 /* Read whole status block */
416 ed = sc->sc_ed[devno];
417 ed->sc_status_block[0] = sifr;
418 for(i=1; i < len; i++) {
419 while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
420 & BSR_SIFR_FULL) == 0)
421 delay(1);
422
423 ed->sc_status_block[i] = le16toh(
424 bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
425 }
426 }
427
428 switch (intr_id) {
429 case ISR_DATA_TRANSFER_RDY:
430 /*
431 * Ready to do DMA, setup DMA controller and kick DASD
432 * controller to do the transfer.
433 */
434 ed = sc->sc_ed[devno];
435 if (!edc_setup_dma(sc, ed->sc_read,
436 ed->dmamap_xfer->dm_segs[0].ds_addr,
437 ed->dmamap_xfer->dm_segs[0].ds_len)) {
438 /* XXX bail out? */
439 printf("%s: edc_setup_dma() failed\n",
440 ed->sc_dev.dv_xname);
441 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
442 BCR_INT_ENABLE);
443 } else {
444 /* OK, proceed with DMA */
445 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
446 BCR_INT_ENABLE|BCR_DMA_ENABLE);
447 }
448 break;
449 case ISR_COMPLETED:
450 case ISR_COMPLETED_WITH_ECC:
451 case ISR_COMPLETED_RETRIES:
452 case ISR_COMPLETED_WARNING:
453 bioerror = 0;
454 break;
455 case ISR_RESET_COMPLETED:
456 case ISR_ABORT_COMPLETED:
457 /* nothing to do */
458 break;
459 default:
460 if ((sc->sc_flags & DASD_QUIET) == 0)
461 edc_dump_status_block(sc, devno, intr_id);
462
463 bioerror = EIO;
464 break;
465 }
466
467 /*
468 * Unless the interrupt is for Data Transfer Ready or
469 * Attention Error, finish by assertion EOI. This makes
470 * attachment aware the interrupt is processed and system
471 * is ready to accept another one.
472 */
473 if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR)
474 edc_do_attn(sc, ATN_END_INT, devno, intr_id);
475
476 /* If Read or Write Data, wakeup worker thread to finish it */
477 if (intr_id != ISR_DATA_TRANSFER_RDY
478 && (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)) {
479 sc->sc_ed[devno]->sc_error = bioerror;
480 wakeup_one(&sc->sc_ed[devno]->edc_softc);
481 }
482
483 return (1);
484 }
485
486 /*
487 * This follows the exact order for Attention Request as
488 * written in DASD Storage Interface Specification MC (Rev 2.2).
489 */
490 static int
491 edc_do_attn(sc, attn_type, devno, intr_id)
492 struct edc_mca_softc *sc;
493 int attn_type, devno, intr_id;
494 {
495 int tries;
496
497 /* 1. Disable interrupts in BCR. */
498 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0);
499
500 /*
501 * 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging
502 * a RESET COMPLETED interrupt.
503 */
504 if (intr_id != ISR_RESET_COMPLETED) {
505 for(tries=1; tries < EDC_ATTN_MAXTRIES; tries++) {
506 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
507 & BSR_BUSY) == 0) {
508 #ifdef DEBUG
509 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh,
510 BSR) & BSR_INT_PENDING) && intr_id)
511 panic("foobar");
512 #endif
513 break;
514 }
515 }
516
517 if (tries == EDC_ATTN_MAXTRIES) {
518 printf("%s: edc_do_attn: timeout waiting for attachment to become available\n",
519 sc->sc_ed[devno]->sc_dev.dv_xname);
520 return (EAGAIN);
521 }
522 }
523
524 /*
525 * 3. Write proper DEVICE NUMBER and Attention number to ATN.
526 */
527 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN,
528 attn_type | (devno << 5));
529
530 /*
531 * 4. Enable interrupts via BCR.
532 */
533 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE);
534
535 return (0);
536 }
537
538 /*
539 * Wait until command is processed, timeout after 'secs' seconds.
540 * We use mono_time, since we don't need actual RTC, just time
541 * interval.
542 */
543 static int
544 edc_cmd_wait(sc, devno, secs, poll)
545 struct edc_mca_softc *sc;
546 int devno, secs, poll;
547 {
548 int val, delayed;
549
550 delayed = 0;
551 do {
552 val = bus_space_read_1(sc->sc_iot,sc->sc_ioh, BSR);
553 if ((val & BSR_CMD_INPROGRESS) == 0)
554 break;
555
556 if (poll && (val & BSR_INTR))
557 goto out;
558
559 if (secs == 0)
560 break;
561
562 delay(1);
563
564 /*
565 * This is not as accurate as checking mono_time, but
566 * it works with hardclock interrupts disabled too.
567 */
568 delayed++;
569 if (delayed == 1000000) {
570 delayed = 0;
571 secs--;
572 }
573 #if 0
574 if (delayed % 1000)
575 printf("looping ...");
576 #endif
577 } while(1);
578
579 if (secs == 0 &&
580 bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CMD_INPROGRESS){
581 printf("%s: timed out waiting for previous cmd to finish\n",
582 sc->sc_ed[devno]->sc_dev.dv_xname);
583 return (EAGAIN);
584 }
585
586 out:
587 return (0);
588 }
589
590 int
591 edc_run_cmd(sc, cmd, devno, cmd_args, cmd_len, async, poll)
592 struct edc_mca_softc *sc;
593 int cmd;
594 int devno;
595 u_int16_t cmd_args[];
596 int cmd_len, async, poll;
597 {
598 int i, error, tries;
599 u_int16_t cmd0;
600
601 /*
602 * If there has been an asynchronous command executed, first wait for it
603 * to finish.
604 */
605 if (sc->sc_cmd_async) {
606 /* Wait maximum 15s */
607 if (edc_cmd_wait(sc, devno, 15, 0))
608 return (EAGAIN); /* Busy */
609
610 sc->sc_cmd_async = 0;
611 }
612
613 /* Do Attention Request for Command Request. */
614 if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0)))
615 return (error);
616
617 /*
618 * Construct the command. The bits are like this:
619 *
620 * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
621 * \_/ 0 0 1 0 \__/ \_____/
622 * \ \__________/ \ \_ Command Code (see CMD_*)
623 * \ \ \__ Device: 0 common, 7 controller
624 * \ \__ Options: reserved, bit 10=cache bypass bit
625 * \_ Type: 00=2B, 01=4B, 10 and 11 reserved
626 *
627 * We always use device 0 or 1, so difference is made only by Command
628 * Code, Command Options and command length.
629 */
630 cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0)
631 | (devno << 5)
632 | (cmd_args[0] << 8) | cmd;
633 cmd_args[0] = cmd0;
634
635 /*
636 * Write word of CMD to the CIFR. This sets "Command
637 * Interface Register Full (CMD IN)" in BSR. Once the attachment
638 * detects it, it reads the word and clears CMD IN.
639 */
640 for(i=0; i < cmd_len; i++) {
641 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR,
642 htole16(cmd_args[i]));
643
644 /*
645 * Wait until CMD IN is cleared. The 1ms delay for polling
646 * case is necessary, otherwise e.g. system dump gets stuck
647 * soon. Quirky hw ?
648 */
649 tries = 0;
650 while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CIFR_FULL)
651 delay(poll ? 1000 : 1);
652 }
653
654 /*
655 * Attachment is now executing the command. Unless we are executing
656 * command asynchronously, wait until it finishes.
657 */
658 if (async) {
659 sc->sc_cmd_async = 1;
660 return (0);
661 }
662
663 /* Wait for command to complete, but maximum 15 seconds. */
664 if (edc_cmd_wait(sc, devno, 15, poll))
665 return (EAGAIN);
666
667 /* If polling, call edc_intr() explicitly */
668 if (poll) {
669 edc_intr(sc);
670
671 /*
672 * If got attention id DATA TRANSFER READY, wait for
673 * the transfer to finish.
674 */
675 if (sc->sc_ed[devno]->sc_error == 0
676 && (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)) {
677 if (edc_cmd_wait(sc, devno, 15, 1))
678 return (EAGAIN);
679 edc_intr(sc);
680 }
681
682 if (edc_cmd_wait(sc, devno, 15, 0))
683 return (EAGAIN);
684 }
685
686 /* Check if the command completed successfully; if not, return error */
687 switch(SB_GET_CMD_STATUS(sc->sc_ed[devno]->sc_status_block)) {
688 case ISR_COMPLETED:
689 case ISR_COMPLETED_WITH_ECC:
690 case ISR_COMPLETED_RETRIES:
691 case ISR_COMPLETED_WARNING:
692 return (0);
693 default:
694 return (EIO);
695 }
696 }
697
698 static int
699 edc_setup_dma(sc, isread, phys, cnt)
700 struct edc_mca_softc *sc;
701 int isread;
702 bus_addr_t phys;
703 bus_size_t cnt;
704 {
705 /* XXX magic constants, should be moved to device-independant location*/
706 /* The exact sequence to setup MCA DMA controller is taken from Minix */
707
708 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0,
709 0x90 + sc->sc_drq);
710 /* Disable access to dma channel */
711 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0,
712 0x20 + sc->sc_drq);
713 /* Clear the address byte pointer */
714 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0,
715 (phys >> 0) & 0xff); /* address bits 0..7 */
716 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0,
717 (phys >> 8) & 0xff); /* address bits 8..15 */
718 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0,
719 (phys >> 16) & 0xff); /* address bits 16..23 */
720 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0,
721 0x40 + sc->sc_drq);
722 /* Clear the count byte pointer */
723 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0,
724 ((cnt - 1) >> 0) & 0xff); /* count bits 0..7 */
725 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0,
726 ((cnt - 1) >> 8) & 0xff); /* count bits 8..15 */
727 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0,
728 0x70 + sc->sc_drq);
729 /* Set the transfer mode */
730 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0,
731 (isread) ? 0x4C : 0x44);
732 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0,
733 0xA0 + sc->sc_drq);
734 /* Enable access to dma channel */
735
736 return (1);
737 }
738
739 static const char * const edc_commands[] = {
740 "Invalid Command",
741 "Read Data",
742 "Write Data",
743 "Read Verify",
744 "Write with Verify",
745 "Seek",
746 "Park Head",
747 "Get Command Complete Status",
748 "Get Device Status",
749 "Get Device Configuration",
750 "Get POS Information",
751 "Translate RBA",
752 "Write Attachment Buffer",
753 "Read Attachment Buffer",
754 "Run Diagnostic Test",
755 "Get Diagnostic Status Block",
756 "Get MFG Header",
757 "Format Unit",
758 "Format Prepare",
759 "Set MAX RBA",
760 "Set Power Saving Mode",
761 "Power Conservation Command",
762 };
763
764 static const char * const edc_cmd_status[256] = {
765 "Reserved",
766 "Command completed successfully",
767 "Reserved",
768 "Command completed successfully with ECC applied",
769 "Reserved",
770 "Command completed successfully with retries",
771 "Format Command partially completed", /* Status available */
772 "Command completed successfully with ECC and retries",
773 "Command completed with Warning", /* Command Error is available */
774 "Aborted",
775 "Reset completed",
776 "Data Transfer Ready", /* No Status Block available */
777 "Command terminated with failure", /* Device Error is available */
778 "DMA Error", /* Retry entire command as recovery */
779 "Command Block Error",
780 "Attention Error (Illegal Attention Code)",
781 /* 0x14 - 0xff reserved */
782 };
783
784 static const char * const edc_cmd_error[256] = {
785 "No Error",
786 "Invalid parameter in the command block",
787 "Reserved",
788 "Command not supported",
789 "Command Aborted per request",
790 "Reserved",
791 "Command rejected", /* Attachment diagnostic failure */
792 "Format Rejected", /* Prepare Format command is required */
793 "Format Error (Primary Map is not readable)",
794 "Format Error (Secondary map is not readable)",
795 "Format Error (Diagnostic Failure)",
796 "Format Warning (Secondary Map Overflow)",
797 "Reserved"
798 "Format Error (Host Checksum Error)",
799 "Reserved",
800 "Format Warning (Push table overflow)",
801 "Format Warning (More pushes than allowed)",
802 "Reserved",
803 "Format Warning (Error during verifying)",
804 "Invalid device number for the command",
805 /* 0x14-0xff reserved */
806 };
807
808 static const char * const edc_dev_errors[] = {
809 "No Error",
810 "Seek Fault", /* Device report */
811 "Interface Fault (Parity, Attn, or Cmd Complete Error)",
812 "Block not found (ID not found)",
813 "Block not found (AM not found)",
814 "Data ECC Error (hard error)",
815 "ID CRC Error",
816 "RBA Out of Range",
817 "Reserved",
818 "Defective Block",
819 "Reserved",
820 "Selection Error",
821 "Reserved",
822 "Write Fault",
823 "No index or sector pulse",
824 "Device Not Ready",
825 "Seek Error", /* Attachment report */
826 "Bad Format",
827 "Volume Overflow",
828 "No Data AM Found",
829 "Block not found (No ID AM or ID CRC error occurred)",
830 "Reserved",
831 "Reserved",
832 "No ID found on track (ID search)",
833 /* 0x19 - 0xff reserved */
834 };
835
836 static void
837 edc_dump_status_block(sc, devno, intr_id)
838 struct edc_mca_softc *sc;
839 int devno, intr_id;
840 {
841 struct ed_softc *ed = sc->sc_ed[devno];
842 printf("%s: Command: %s, Status: %s\n",
843 ed->sc_dev.dv_xname,
844 edc_commands[ed->sc_status_block[0] & 0x1f],
845 edc_cmd_status[SB_GET_CMD_STATUS(ed->sc_status_block)]
846 );
847 printf("%s: # left blocks: %u, last processed RBA: %u\n",
848 ed->sc_dev.dv_xname,
849 ed->sc_status_block[SB_RESBLKCNT_IDX],
850 (ed->sc_status_block[5] << 16) | ed->sc_status_block[4]);
851
852 if (intr_id == ISR_COMPLETED_WARNING) {
853 printf("%s: Command Error Code: %s\n",
854 ed->sc_dev.dv_xname,
855 edc_cmd_error[ed->sc_status_block[1] & 0xff]);
856 }
857
858 if (intr_id == ISR_CMD_FAILED) {
859 char buf[100];
860
861 printf("%s: Device Error Code: %s\n",
862 ed->sc_dev.dv_xname,
863 edc_dev_errors[ed->sc_status_block[2] & 0xff]);
864 bitmask_snprintf((ed->sc_status_block[2] & 0xff00) >> 8,
865 "\20"
866 "\01SeekOrCmdComplete"
867 "\02Track0Flag"
868 "\03WriteFault"
869 "\04Selected"
870 "\05Ready"
871 "\06Reserved0"
872 "\07STANDBY"
873 "\010Reserved0",
874 buf, sizeof(buf));
875 printf("%s: Device Status: %s\n",
876 ed->sc_dev.dv_xname, buf);
877 }
878 }
879