edc_mca.c revision 1.36 1 /* $NetBSD: edc_mca.c,v 1.36 2007/07/09 21:00:51 ad 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 * - improve error recovery
45 * Issue soft reset on error or timeout?
46 * - test with > 1 disk (this is supported by some controllers)
47 * - test with > 1 ESDI controller in machine; shared interrupts
48 * necessary for this to work should be supported - edc_intr() specifically
49 * checks if the interrupt is for this controller
50 */
51
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: edc_mca.c,v 1.36 2007/07/09 21:00:51 ad Exp $");
54
55 #include "rnd.h"
56
57 #include <sys/param.h>
58 #include <sys/systm.h>
59 #include <sys/buf.h>
60 #include <sys/bufq.h>
61 #include <sys/errno.h>
62 #include <sys/device.h>
63 #include <sys/malloc.h>
64 #include <sys/endian.h>
65 #include <sys/disklabel.h>
66 #include <sys/disk.h>
67 #include <sys/syslog.h>
68 #include <sys/proc.h>
69 #include <sys/vnode.h>
70 #include <sys/kernel.h>
71 #include <sys/kthread.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 #include "locators.h"
88
89 #define EDC_ATTN_MAXTRIES 10000 /* How many times check for unbusy */
90 #define EDC_MAX_CMD_RES_LEN 8
91
92 struct edc_mca_softc {
93 struct device sc_dev;
94
95 bus_space_tag_t sc_iot;
96 bus_space_handle_t sc_ioh;
97
98 /* DMA related stuff */
99 bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */
100 bus_dmamap_t sc_dmamap_xfer; /* transfer dma map */
101
102 void *sc_ih; /* interrupt handle */
103
104 int sc_flags;
105 #define DASD_QUIET 0x01 /* don't dump cmd error info */
106
107 #define DASD_MAXDEVS 8
108 struct ed_softc *sc_ed[DASD_MAXDEVS];
109 int sc_maxdevs; /* max number of disks attached to this
110 * controller */
111
112 /* I/O results variables */
113 volatile int sc_stat;
114 #define STAT_START 0
115 #define STAT_ERROR 1
116 #define STAT_DONE 2
117 volatile int sc_resblk; /* residual block count */
118
119 /* CMD status block - only set & used in edc_intr() */
120 u_int16_t status_block[EDC_MAX_CMD_RES_LEN];
121 };
122
123 int edc_mca_probe(struct device *, struct cfdata *, void *);
124 void edc_mca_attach(struct device *, struct device *, void *);
125
126 CFATTACH_DECL(edc_mca, sizeof(struct edc_mca_softc),
127 edc_mca_probe, edc_mca_attach, NULL, NULL);
128
129 static int edc_intr(void *);
130 static void edc_dump_status_block(struct edc_mca_softc *,
131 u_int16_t *, int);
132 static int edc_do_attn(struct edc_mca_softc *, int, int, int);
133 static void edc_cmd_wait(struct edc_mca_softc *, int, int);
134 static void edcworker(void *);
135
136 int
137 edc_mca_probe(struct device *parent, struct cfdata *match,
138 void *aux)
139 {
140 struct mca_attach_args *ma = aux;
141
142 switch (ma->ma_id) {
143 case MCA_PRODUCT_IBM_ESDIC:
144 case MCA_PRODUCT_IBM_ESDIC_IG:
145 return (1);
146 default:
147 return (0);
148 }
149 }
150
151 void
152 edc_mca_attach(struct device *parent, struct device *self, void *aux)
153 {
154 struct edc_mca_softc *sc = device_private(self);
155 struct mca_attach_args *ma = aux;
156 struct ed_attach_args eda;
157 int pos2, pos3, pos4;
158 int irq, drq, iobase;
159 const char *typestr;
160 int devno, error;
161 int locs[EDCCF_NLOCS];
162
163 pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2);
164 pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3);
165 pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4);
166
167 /*
168 * POS register 2: (adf pos0)
169 *
170 * 7 6 5 4 3 2 1 0
171 * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled
172 * \ \ \___ Primary/Alternate Port Addresses:
173 * \ \ 0=0x3510-3517 1=0x3518-0x351f
174 * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7
175 * \ 0000=0 0001=1 0011=3 0100=4
176 * \_________ Fairness On/Off: 1=On 0=Off
177 *
178 * POS register 3: (adf pos1)
179 *
180 * 7 6 5 4 3 2 1 0
181 * 0 0 \_/
182 * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms
183 * 01=16ms 00=Burst Disabled
184 *
185 * POS register 4: (adf pos2)
186 *
187 * 7 6 5 4 3 2 1 0
188 * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled
189 * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate
190 *
191 * IRQ is fixed to 14 (0x0e).
192 */
193
194 switch (ma->ma_id) {
195 case MCA_PRODUCT_IBM_ESDIC:
196 typestr = "IBM ESDI Fixed Disk Controller";
197 break;
198 case MCA_PRODUCT_IBM_ESDIC_IG:
199 typestr = "IBM Integ. ESDI Fixed Disk & Controller";
200 break;
201 default:
202 typestr = NULL;
203 break;
204 }
205
206 irq = ESDIC_IRQ;
207 iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM;
208 drq = (pos2 & DRQ_MASK) >> 2;
209
210 printf(" slot %d irq %d drq %d: %s\n", ma->ma_slot+1,
211 irq, drq, typestr);
212
213 #ifdef DIAGNOSTIC
214 /*
215 * It's not strictly necessary to check this, machine configuration
216 * utility uses only valid addresses.
217 */
218 if (drq == 2 || drq >= 8) {
219 printf("%s: invalid DMA Arbitration Level %d\n",
220 sc->sc_dev.dv_xname, drq);
221 return;
222 }
223 #endif
224
225 printf("%s: Fairness %s, Release %s, ",
226 sc->sc_dev.dv_xname,
227 (pos2 & FAIRNESS_ENABLE) ? "On" : "Off",
228 (pos4 & RELEASE_1) ? "6ms"
229 : ((pos4 & RELEASE_2) ? "3ms" : "Immediate")
230 );
231 if ((pos4 & PACING_CTRL_DISABLE) == 0) {
232 static const char * const pacint[] =
233 { "disabled", "16ms", "24ms", "31ms"};
234 printf("DMA burst pacing interval %s\n",
235 pacint[(pos3 & PACING_INT_MASK) >> 4]);
236 } else
237 printf("DMA pacing control disabled\n");
238
239 sc->sc_iot = ma->ma_iot;
240
241 if (bus_space_map(sc->sc_iot, iobase,
242 ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) {
243 printf("%s: couldn't map registers\n",
244 sc->sc_dev.dv_xname);
245 return;
246 }
247
248 sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, edc_intr, sc);
249 if (sc->sc_ih == NULL) {
250 printf("%s: couldn't establish interrupt handler\n",
251 sc->sc_dev.dv_xname);
252 return;
253 }
254
255 /* Create a MCA DMA map, used for data transfer */
256 sc->sc_dmat = ma->ma_dmat;
257 if ((error = mca_dmamap_create(sc->sc_dmat, MAXPHYS,
258 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | MCABUS_DMA_16BIT,
259 &sc->sc_dmamap_xfer, drq)) != 0){
260 printf("%s: couldn't create DMA map - error %d\n",
261 sc->sc_dev.dv_xname, error);
262 return;
263 }
264
265 /*
266 * Integrated ESDI controller supports only one disk, other
267 * controllers support two disks.
268 */
269 if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG)
270 sc->sc_maxdevs = 1;
271 else
272 sc->sc_maxdevs = 2;
273
274 /*
275 * Reset controller and attach individual disks. ed attach routine
276 * uses polling so that this works with interrupts disabled.
277 */
278
279 /* Do a reset to ensure sane state after warm boot. */
280 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) {
281 /* hard reset */
282 printf("%s: controller busy, performing hardware reset ...\n",
283 sc->sc_dev.dv_xname);
284 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
285 BCR_INT_ENABLE|BCR_RESET);
286 } else {
287 /* "SOFT" reset */
288 edc_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0);
289 }
290
291 /*
292 * Since interrupts are disabled, it's necessary
293 * to detect the interrupt request and call edc_intr()
294 * explicitly. See also edc_run_cmd().
295 */
296 while (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) {
297 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR)
298 edc_intr(sc);
299
300 delay(100);
301 }
302
303 /* be quiet during probes */
304 sc->sc_flags |= DASD_QUIET;
305
306 /* check for attached disks */
307 for (devno = 0; devno < sc->sc_maxdevs; devno++) {
308 eda.edc_drive = devno;
309 locs[EDCCF_DRIVE] = devno;
310 sc->sc_ed[devno] =
311 (void *) config_found_sm_loc(self, "edc", locs, &eda,
312 NULL, config_stdsubmatch);
313
314 /* If initialization did not succeed, NULL the pointer. */
315 if (sc->sc_ed[devno]
316 && (sc->sc_ed[devno]->sc_flags & EDF_INIT) == 0)
317 sc->sc_ed[devno] = NULL;
318 }
319
320 /* enable full error dumps again */
321 sc->sc_flags &= ~DASD_QUIET;
322
323 /*
324 * Check if there are any disks attached. If not, disestablish
325 * the interrupt.
326 */
327 for (devno = 0; devno < sc->sc_maxdevs; devno++) {
328 if (sc->sc_ed[devno])
329 break;
330 }
331
332 if (devno == sc->sc_maxdevs) {
333 printf("%s: disabling controller (no drives attached)\n",
334 sc->sc_dev.dv_xname);
335 mca_intr_disestablish(ma->ma_mc, sc->sc_ih);
336 return;
337 }
338
339 /*
340 * Run the worker thread.
341 */
342 config_pending_incr();
343 if ((error = kthread_create(PRI_NONE, 0, NULL, edcworker, sc, NULL,
344 "%s", sc->sc_dev.dv_xname))) {
345 printf("%s: cannot spawn worker thread: errno=%d\n",
346 sc->sc_dev.dv_xname, error);
347 panic("edc_mca_attach");
348 }
349 }
350
351 void
352 edc_add_disk(struct edc_mca_softc *sc, struct ed_softc *ed)
353 {
354 sc->sc_ed[ed->sc_devno] = ed;
355 }
356
357 static int
358 edc_intr(void *arg)
359 {
360 struct edc_mca_softc *sc = arg;
361 u_int8_t isr, intr_id;
362 u_int16_t sifr;
363 int cmd=-1, devno;
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 EDC_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 > EDC_MAX_CMD_RES_LEN)
404 panic("%s: maximum Status Length exceeded: %d > %d",
405 sc->sc_dev.dv_xname,
406 len, EDC_MAX_CMD_RES_LEN);
407 #endif
408
409 /* Get command code */
410 cmd = sifr & SIFR_CMD_MASK;
411
412 /* Read whole status block */
413 sc->status_block[0] = sifr;
414 for(i=1; i < len; i++) {
415 while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
416 & BSR_SIFR_FULL) == 0)
417 ;
418
419 sc->status_block[i] = le16toh(
420 bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
421 }
422 /* zero out rest */
423 if (i < EDC_MAX_CMD_RES_LEN) {
424 memset(&sc->status_block[i], 0,
425 (EDC_MAX_CMD_RES_LEN-i)*sizeof(u_int16_t));
426 }
427 }
428
429 switch (intr_id) {
430 case ISR_DATA_TRANSFER_RDY:
431 /*
432 * Ready to do DMA. The DMA controller has already been
433 * setup, now just kick disk controller to do the transfer.
434 */
435 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
436 BCR_INT_ENABLE|BCR_DMA_ENABLE);
437 break;
438
439 case ISR_COMPLETED:
440 case ISR_COMPLETED_WITH_ECC:
441 case ISR_COMPLETED_RETRIES:
442 case ISR_COMPLETED_WARNING:
443 /*
444 * Copy device config data if appropriate. sc->sc_ed[]
445 * entry might be NULL during probe.
446 */
447 if (cmd == CMD_GET_DEV_CONF && sc->sc_ed[devno]) {
448 memcpy(sc->sc_ed[devno]->sense_data, sc->status_block,
449 sizeof(sc->sc_ed[devno]->sense_data));
450 }
451
452 sc->sc_stat = STAT_DONE;
453 break;
454
455 case ISR_RESET_COMPLETED:
456 case ISR_ABORT_COMPLETED:
457 /* nothing to do */
458 break;
459
460 case ISR_ATTN_ERROR:
461 /*
462 * Basically, this means driver bug or something seriously
463 * hosed. panic rather than extending the lossage.
464 * No status block available, so no further info.
465 */
466 panic("%s: dev %d: attention error",
467 sc->sc_dev.dv_xname,
468 devno);
469 /* NOTREACHED */
470 break;
471
472 default:
473 if ((sc->sc_flags & DASD_QUIET) == 0)
474 edc_dump_status_block(sc, sc->status_block, intr_id);
475
476 sc->sc_stat = STAT_ERROR;
477 break;
478 }
479
480 /*
481 * Unless the interrupt is for Data Transfer Ready or
482 * Attention Error, finish by assertion EOI. This makes
483 * attachment aware the interrupt is processed and system
484 * is ready to accept another one.
485 */
486 if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR)
487 edc_do_attn(sc, ATN_END_INT, devno, intr_id);
488
489 /* If Read or Write Data, wakeup worker thread to finish it */
490 if (intr_id != ISR_DATA_TRANSFER_RDY) {
491 if (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)
492 sc->sc_resblk = sc->status_block[SB_RESBLKCNT_IDX];
493 wakeup_one(sc);
494 }
495
496 return (1);
497 }
498
499 /*
500 * This follows the exact order for Attention Request as
501 * written in DASD Storage Interface Specification MC (Rev 2.2).
502 */
503 static int
504 edc_do_attn(struct edc_mca_softc *sc, int attn_type, int devno, int intr_id)
505 {
506 int tries;
507
508 /* 1. Disable interrupts in BCR. */
509 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0);
510
511 /*
512 * 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging
513 * a RESET COMPLETED interrupt.
514 */
515 if (intr_id != ISR_RESET_COMPLETED) {
516 #ifdef EDC_DEBUG
517 if (attn_type == ATN_CMD_REQ
518 && (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
519 & BSR_INT_PENDING))
520 panic("%s: edc int pending", sc->sc_dev.dv_xname);
521 #endif
522
523 for(tries=1; tries < EDC_ATTN_MAXTRIES; tries++) {
524 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
525 & BSR_BUSY) == 0)
526 break;
527 }
528
529 if (tries == EDC_ATTN_MAXTRIES) {
530 printf("%s: edc_do_attn: timeout waiting for attachment to become available\n",
531 sc->sc_ed[devno]->sc_dev.dv_xname);
532 return (EIO);
533 }
534 }
535
536 /*
537 * 3. Write proper DEVICE NUMBER and Attention number to ATN.
538 */
539 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, attn_type | (devno<<5));
540
541 /*
542 * 4. Enable interrupts via BCR.
543 */
544 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE);
545
546 return (0);
547 }
548
549 /*
550 * Wait until command is processed, timeout after 'secs' seconds.
551 * We use mono_time, since we don't need actual RTC, just time
552 * interval.
553 */
554 static void
555 edc_cmd_wait(struct edc_mca_softc *sc, int secs, int poll)
556 {
557 int val;
558
559 if (!poll) {
560 int s;
561
562 /* Not polling, can sleep. Sleep until we are awakened,
563 * but maximum secs seconds.
564 */
565 s = splbio();
566 if (sc->sc_stat != STAT_DONE)
567 (void) tsleep(sc, PRIBIO, "edcwcmd", secs * hz);
568 splx(s);
569 }
570
571 /* Wait until the command is completely finished */
572 while((val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR))
573 & BSR_CMD_INPROGRESS) {
574 if (poll && (val & BSR_INTR))
575 edc_intr(sc);
576 }
577 }
578
579 /*
580 * Command controller to execute specified command on a device.
581 */
582 int
583 edc_run_cmd(struct edc_mca_softc *sc, int cmd, int devno,
584 u_int16_t cmd_args[], int cmd_len, int poll)
585 {
586 int i, error, tries;
587 u_int16_t cmd0;
588
589 sc->sc_stat = STAT_START;
590
591 /* Do Attention Request for Command Request. */
592 if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0)))
593 return (error);
594
595 /*
596 * Construct the command. The bits are like this:
597 *
598 * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
599 * \_/ 0 0 1 0 \__/ \_____/
600 * \ \__________/ \ \_ Command Code (see CMD_*)
601 * \ \ \__ Device: 0 common, 7 controller
602 * \ \__ Options: reserved, bit 10=cache bypass bit
603 * \_ Type: 00=2B, 01=4B, 10 and 11 reserved
604 *
605 * We always use device 0 or 1, so difference is made only by Command
606 * Code, Command Options and command length.
607 */
608 cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0)
609 | (devno << 5)
610 | (cmd_args[0] << 8) | cmd;
611 cmd_args[0] = cmd0;
612
613 /*
614 * Write word of CMD to the CIFR. This sets "Command
615 * Interface Register Full (CMD IN)" in BSR. Once the attachment
616 * detects it, it reads the word and clears CMD IN. This all should
617 * be quite fast, so don't sleep in !poll case neither.
618 */
619 for(i=0; i < cmd_len; i++) {
620 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR,
621 htole16(cmd_args[i]));
622
623 /* Wait until CMD IN is cleared. */
624 tries = 0;
625 for(; (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
626 & BSR_CIFR_FULL) && tries < 10000 ; tries++)
627 delay(poll ? 1000 : 1);
628 ;
629
630 if (tries == 10000
631 && bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
632 & BSR_CIFR_FULL) {
633 printf("%s: device too slow to accept command %d\n",
634 sc->sc_dev.dv_xname, cmd);
635 return (EIO);
636 }
637 }
638
639 /* Wait for command to complete, but maximum 15 seconds. */
640 edc_cmd_wait(sc, 15, poll);
641
642 return ((sc->sc_stat != STAT_DONE) ? EIO : 0);
643 }
644
645 #ifdef EDC_DEBUG
646 static const char * const edc_commands[] = {
647 "Invalid Command",
648 "Read Data",
649 "Write Data",
650 "Read Verify",
651 "Write with Verify",
652 "Seek",
653 "Park Head",
654 "Get Command Complete Status",
655 "Get Device Status",
656 "Get Device Configuration",
657 "Get POS Information",
658 "Translate RBA",
659 "Write Attachment Buffer",
660 "Read Attachment Buffer",
661 "Run Diagnostic Test",
662 "Get Diagnostic Status Block",
663 "Get MFG Header",
664 "Format Unit",
665 "Format Prepare",
666 "Set MAX RBA",
667 "Set Power Saving Mode",
668 "Power Conservation Command",
669 };
670
671 static const char * const edc_cmd_status[256] = {
672 "Reserved",
673 "Command completed successfully",
674 "Reserved",
675 "Command completed successfully with ECC applied",
676 "Reserved",
677 "Command completed successfully with retries",
678 "Format Command partially completed", /* Status available */
679 "Command completed successfully with ECC and retries",
680 "Command completed with Warning", /* Command Error is available */
681 "Aborted",
682 "Reset completed",
683 "Data Transfer Ready", /* No Status Block available */
684 "Command terminated with failure", /* Device Error is available */
685 "DMA Error", /* Retry entire command as recovery */
686 "Command Block Error",
687 "Attention Error (Illegal Attention Code)",
688 /* 0x14 - 0xff reserved */
689 };
690
691 static const char * const edc_cmd_error[256] = {
692 "No Error",
693 "Invalid parameter in the command block",
694 "Reserved",
695 "Command not supported",
696 "Command Aborted per request",
697 "Reserved",
698 "Command rejected", /* Attachment diagnostic failure */
699 "Format Rejected", /* Prepare Format command is required */
700 "Format Error (Primary Map is not readable)",
701 "Format Error (Secondary map is not readable)",
702 "Format Error (Diagnostic Failure)",
703 "Format Warning (Secondary Map Overflow)",
704 "Reserved"
705 "Format Error (Host Checksum Error)",
706 "Reserved",
707 "Format Warning (Push table overflow)",
708 "Format Warning (More pushes than allowed)",
709 "Reserved",
710 "Format Warning (Error during verifying)",
711 "Invalid device number for the command",
712 /* 0x14-0xff reserved */
713 };
714
715 static const char * const edc_dev_errors[] = {
716 "No Error",
717 "Seek Fault", /* Device report */
718 "Interface Fault (Parity, Attn, or Cmd Complete Error)",
719 "Block not found (ID not found)",
720 "Block not found (AM not found)",
721 "Data ECC Error (hard error)",
722 "ID CRC Error",
723 "RBA Out of Range",
724 "Reserved",
725 "Defective Block",
726 "Reserved",
727 "Selection Error",
728 "Reserved",
729 "Write Fault",
730 "No index or sector pulse",
731 "Device Not Ready",
732 "Seek Error", /* Attachment report */
733 "Bad Format",
734 "Volume Overflow",
735 "No Data AM Found",
736 "Block not found (No ID AM or ID CRC error occurred)",
737 "Reserved",
738 "Reserved",
739 "No ID found on track (ID search)",
740 /* 0x19 - 0xff reserved */
741 };
742 #endif /* EDC_DEBUG */
743
744 static void
745 edc_dump_status_block(struct edc_mca_softc *sc, u_int16_t *status_block,
746 int intr_id)
747 {
748 #ifdef EDC_DEBUG
749 printf("%s: Command: %s, Status: %s (intr %d)\n",
750 sc->sc_dev.dv_xname,
751 edc_commands[status_block[0] & 0x1f],
752 edc_cmd_status[SB_GET_CMD_STATUS(status_block)],
753 intr_id
754 );
755 #else
756 printf("%s: Command: %d, Status: %d (intr %d)\n",
757 sc->sc_dev.dv_xname,
758 status_block[0] & 0x1f,
759 SB_GET_CMD_STATUS(status_block),
760 intr_id
761 );
762 #endif
763 printf("%s: # left blocks: %u, last processed RBA: %u\n",
764 sc->sc_dev.dv_xname,
765 status_block[SB_RESBLKCNT_IDX],
766 (status_block[5] << 16) | status_block[4]);
767
768 if (intr_id == ISR_COMPLETED_WARNING) {
769 #ifdef EDC_DEBUG
770 printf("%s: Command Error Code: %s\n",
771 sc->sc_dev.dv_xname,
772 edc_cmd_error[status_block[1] & 0xff]);
773 #else
774 printf("%s: Command Error Code: %d\n",
775 sc->sc_dev.dv_xname,
776 status_block[1] & 0xff);
777 #endif
778 }
779
780 if (intr_id == ISR_CMD_FAILED) {
781 #ifdef EDC_DEBUG
782 char buf[100];
783
784 printf("%s: Device Error Code: %s\n",
785 sc->sc_dev.dv_xname,
786 edc_dev_errors[status_block[2] & 0xff]);
787 bitmask_snprintf((status_block[2] & 0xff00) >> 8,
788 "\20"
789 "\01SeekOrCmdComplete"
790 "\02Track0Flag"
791 "\03WriteFault"
792 "\04Selected"
793 "\05Ready"
794 "\06Reserved0"
795 "\07STANDBY"
796 "\010Reserved0",
797 buf, sizeof(buf));
798 printf("%s: Device Status: %s\n",
799 sc->sc_dev.dv_xname, buf);
800 #else
801 printf("%s: Device Error Code: %d, Device Status: %d\n",
802 sc->sc_dev.dv_xname,
803 status_block[2] & 0xff,
804 (status_block[2] & 0xff00) >> 8);
805 #endif
806 }
807 }
808 /*
809 * Main worker thread function.
810 */
811 void
812 edcworker(void *arg)
813 {
814 struct edc_mca_softc *sc = (struct edc_mca_softc *) arg;
815 struct ed_softc *ed;
816 struct buf *bp;
817 int i, error;
818
819 config_pending_decr();
820
821 for(;;) {
822 /* Wait until awakened */
823 (void) tsleep(sc, PRIBIO, "edcidle", 0);
824
825 for(i=0; i<sc->sc_maxdevs; ) {
826 if ((ed = sc->sc_ed[i]) == NULL) {
827 i++;
828 continue;
829 }
830
831 /* Is there a buf for us ? */
832 simple_lock(&ed->sc_q_lock);
833 if ((bp = BUFQ_GET(ed->sc_q)) == NULL) {
834 simple_unlock(&ed->sc_q_lock);
835 i++;
836 continue;
837 }
838 simple_unlock(&ed->sc_q_lock);
839
840 /* Instrumentation. */
841 disk_busy(&ed->sc_dk);
842
843 error = edc_bio(sc, ed, bp->b_data, bp->b_bcount,
844 bp->b_rawblkno, (bp->b_flags & B_READ), 0);
845
846 if (error) {
847 bp->b_error = error;
848 bp->b_flags |= B_ERROR;
849 } else {
850 /* Set resid, most commonly to zero. */
851 bp->b_resid = sc->sc_resblk * DEV_BSIZE;
852 }
853
854 disk_unbusy(&ed->sc_dk, (bp->b_bcount - bp->b_resid),
855 (bp->b_flags & B_READ));
856 #if NRND > 0
857 rnd_add_uint32(&ed->rnd_source, bp->b_blkno);
858 #endif
859 biodone(bp);
860 }
861 }
862 }
863
864 int
865 edc_bio(struct edc_mca_softc *sc, struct ed_softc *ed, void *data,
866 size_t bcount, daddr_t rawblkno, int isread, int poll)
867 {
868 u_int16_t cmd_args[4];
869 int error=0, fl;
870 u_int16_t track;
871 u_int16_t cyl;
872 u_int8_t head;
873 u_int8_t sector;
874
875 mca_disk_busy();
876
877 /* set WAIT and R/W flag appropriately for the DMA transfer */
878 fl = ((poll) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK)
879 | ((isread) ? BUS_DMA_READ : BUS_DMA_WRITE);
880
881 /* Load the buffer for DMA transfer. */
882 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_xfer, data,
883 bcount, NULL, BUS_DMA_STREAMING|fl))) {
884 printf("%s: ed_bio: unable to load DMA buffer - error %d\n",
885 ed->sc_dev.dv_xname, error);
886 goto out;
887 }
888
889 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0,
890 bcount, (isread) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
891
892 track = rawblkno / ed->sectors;
893 head = track % ed->heads;
894 cyl = track / ed->heads;
895 sector = rawblkno % ed->sectors;
896
897 /* Read or Write Data command */
898 cmd_args[0] = 2; /* Options 0000010 */
899 cmd_args[1] = bcount / DEV_BSIZE;
900 cmd_args[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
901 cmd_args[3] = ((cyl & 0x3E0) >> 5);
902 error = edc_run_cmd(sc,
903 (isread) ? CMD_READ_DATA : CMD_WRITE_DATA,
904 ed->sc_devno, cmd_args, 4, poll);
905
906 /* Sync the DMA memory */
907 if (!error) {
908 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, bcount,
909 (isread)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
910 }
911
912 /* We are done, unload buffer from DMA map */
913 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_xfer);
914
915 out:
916 mca_disk_unbusy();
917
918 return (error);
919 }
920