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