No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / mca / edc_mca.c
blob502d11a532d66c4d213f2820c4c04cc43d50e366
1 /* $NetBSD: edc_mca.c,v 1.43 2009/05/12 13:15:24 cegger Exp $ */
3 /*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jaromir Dolecek.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Driver for MCA ESDI controllers and disks conforming to IBM DASD
34 * spec.
36 * The driver was written with DASD Storage Interface Specification
37 * for MCA rev. 2.2 in hands, thanks to Scott Telford <st@epcc.ed.ac.uk>.
39 * TODO:
40 * - improve error recovery
41 * Issue soft reset on error or timeout?
42 * - test with > 1 disk (this is supported by some controllers)
43 * - test with > 1 ESDI controller in machine; shared interrupts
44 * necessary for this to work should be supported - edc_intr() specifically
45 * checks if the interrupt is for this controller
48 #include <sys/cdefs.h>
49 __KERNEL_RCSID(0, "$NetBSD: edc_mca.c,v 1.43 2009/05/12 13:15:24 cegger Exp $");
51 #include "rnd.h"
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/buf.h>
56 #include <sys/bufq.h>
57 #include <sys/errno.h>
58 #include <sys/device.h>
59 #include <sys/malloc.h>
60 #include <sys/endian.h>
61 #include <sys/disklabel.h>
62 #include <sys/disk.h>
63 #include <sys/syslog.h>
64 #include <sys/proc.h>
65 #include <sys/vnode.h>
66 #include <sys/kernel.h>
67 #include <sys/kthread.h>
68 #if NRND > 0
69 #include <sys/rnd.h>
70 #endif
72 #include <sys/bus.h>
73 #include <sys/intr.h>
75 #include <dev/mca/mcareg.h>
76 #include <dev/mca/mcavar.h>
77 #include <dev/mca/mcadevs.h>
79 #include <dev/mca/edcreg.h>
80 #include <dev/mca/edvar.h>
81 #include <dev/mca/edcvar.h>
83 #include "locators.h"
85 #define EDC_ATTN_MAXTRIES 10000 /* How many times check for unbusy */
86 #define EDC_MAX_CMD_RES_LEN 8
88 struct edc_mca_softc {
89 struct device sc_dev;
91 bus_space_tag_t sc_iot;
92 bus_space_handle_t sc_ioh;
94 /* DMA related stuff */
95 bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */
96 bus_dmamap_t sc_dmamap_xfer; /* transfer dma map */
98 void *sc_ih; /* interrupt handle */
100 int sc_flags;
101 #define DASD_QUIET 0x01 /* don't dump cmd error info */
103 #define DASD_MAXDEVS 8
104 struct ed_softc *sc_ed[DASD_MAXDEVS];
105 int sc_maxdevs; /* max number of disks attached to this
106 * controller */
108 /* I/O results variables */
109 volatile int sc_stat;
110 #define STAT_START 0
111 #define STAT_ERROR 1
112 #define STAT_DONE 2
113 volatile int sc_resblk; /* residual block count */
115 /* CMD status block - only set & used in edc_intr() */
116 u_int16_t status_block[EDC_MAX_CMD_RES_LEN];
119 int edc_mca_probe(device_t, cfdata_t, void *);
120 void edc_mca_attach(device_t, device_t, void *);
122 CFATTACH_DECL(edc_mca, sizeof(struct edc_mca_softc),
123 edc_mca_probe, edc_mca_attach, NULL, NULL);
125 static int edc_intr(void *);
126 static void edc_dump_status_block(struct edc_mca_softc *,
127 u_int16_t *, int);
128 static int edc_do_attn(struct edc_mca_softc *, int, int, int);
129 static void edc_cmd_wait(struct edc_mca_softc *, int, int);
130 static void edcworker(void *);
133 edc_mca_probe(device_t parent, cfdata_t match,
134 void *aux)
136 struct mca_attach_args *ma = aux;
138 switch (ma->ma_id) {
139 case MCA_PRODUCT_IBM_ESDIC:
140 case MCA_PRODUCT_IBM_ESDIC_IG:
141 return (1);
142 default:
143 return (0);
147 void
148 edc_mca_attach(device_t parent, device_t self, void *aux)
150 struct edc_mca_softc *sc = device_private(self);
151 struct mca_attach_args *ma = aux;
152 struct ed_attach_args eda;
153 int pos2, pos3, pos4;
154 int irq, drq, iobase;
155 const char *typestr;
156 int devno, error;
157 int locs[EDCCF_NLOCS];
159 pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2);
160 pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3);
161 pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4);
164 * POS register 2: (adf pos0)
166 * 7 6 5 4 3 2 1 0
167 * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled
168 * \ \ \___ Primary/Alternate Port Addresses:
169 * \ \ 0=0x3510-3517 1=0x3518-0x351f
170 * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7
171 * \ 0000=0 0001=1 0011=3 0100=4
172 * \_________ Fairness On/Off: 1=On 0=Off
174 * POS register 3: (adf pos1)
176 * 7 6 5 4 3 2 1 0
177 * 0 0 \_/
178 * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms
179 * 01=16ms 00=Burst Disabled
181 * POS register 4: (adf pos2)
183 * 7 6 5 4 3 2 1 0
184 * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled
185 * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate
187 * IRQ is fixed to 14 (0x0e).
190 switch (ma->ma_id) {
191 case MCA_PRODUCT_IBM_ESDIC:
192 typestr = "IBM ESDI Fixed Disk Controller";
193 break;
194 case MCA_PRODUCT_IBM_ESDIC_IG:
195 typestr = "IBM Integ. ESDI Fixed Disk & Controller";
196 break;
197 default:
198 typestr = NULL;
199 break;
202 irq = ESDIC_IRQ;
203 iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM;
204 drq = (pos2 & DRQ_MASK) >> 2;
206 printf(" slot %d irq %d drq %d: %s\n", ma->ma_slot+1,
207 irq, drq, typestr);
209 #ifdef DIAGNOSTIC
211 * It's not strictly necessary to check this, machine configuration
212 * utility uses only valid addresses.
214 if (drq == 2 || drq >= 8) {
215 aprint_error_dev(&sc->sc_dev, "invalid DMA Arbitration Level %d\n", drq);
216 return;
218 #endif
220 printf("%s: Fairness %s, Release %s, ",
221 device_xname(&sc->sc_dev),
222 (pos2 & FAIRNESS_ENABLE) ? "On" : "Off",
223 (pos4 & RELEASE_1) ? "6ms"
224 : ((pos4 & RELEASE_2) ? "3ms" : "Immediate")
226 if ((pos4 & PACING_CTRL_DISABLE) == 0) {
227 static const char * const pacint[] =
228 { "disabled", "16ms", "24ms", "31ms"};
229 printf("DMA burst pacing interval %s\n",
230 pacint[(pos3 & PACING_INT_MASK) >> 4]);
231 } else
232 printf("DMA pacing control disabled\n");
234 sc->sc_iot = ma->ma_iot;
236 if (bus_space_map(sc->sc_iot, iobase,
237 ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) {
238 aprint_error_dev(&sc->sc_dev, "couldn't map registers\n");
239 return;
242 sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, edc_intr, sc);
243 if (sc->sc_ih == NULL) {
244 aprint_error_dev(&sc->sc_dev, "couldn't establish interrupt handler\n");
245 return;
248 /* Create a MCA DMA map, used for data transfer */
249 sc->sc_dmat = ma->ma_dmat;
250 if ((error = mca_dmamap_create(sc->sc_dmat, MAXPHYS,
251 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | MCABUS_DMA_16BIT,
252 &sc->sc_dmamap_xfer, drq)) != 0){
253 aprint_error_dev(&sc->sc_dev, "couldn't create DMA map - error %d\n", error);
254 return;
258 * Integrated ESDI controller supports only one disk, other
259 * controllers support two disks.
261 if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG)
262 sc->sc_maxdevs = 1;
263 else
264 sc->sc_maxdevs = 2;
267 * Reset controller and attach individual disks. ed attach routine
268 * uses polling so that this works with interrupts disabled.
271 /* Do a reset to ensure sane state after warm boot. */
272 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) {
273 /* hard reset */
274 printf("%s: controller busy, performing hardware reset ...\n",
275 device_xname(&sc->sc_dev));
276 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
277 BCR_INT_ENABLE|BCR_RESET);
278 } else {
279 /* "SOFT" reset */
280 edc_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0);
284 * Since interrupts are disabled, it's necessary
285 * to detect the interrupt request and call edc_intr()
286 * explicitly. See also edc_run_cmd().
288 while (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) {
289 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR)
290 edc_intr(sc);
292 delay(100);
295 /* be quiet during probes */
296 sc->sc_flags |= DASD_QUIET;
298 /* check for attached disks */
299 for (devno = 0; devno < sc->sc_maxdevs; devno++) {
300 eda.edc_drive = devno;
301 locs[EDCCF_DRIVE] = devno;
302 sc->sc_ed[devno] =
303 (void *) config_found_sm_loc(self, "edc", locs, &eda,
304 NULL, config_stdsubmatch);
306 /* If initialization did not succeed, NULL the pointer. */
307 if (sc->sc_ed[devno]
308 && (sc->sc_ed[devno]->sc_flags & EDF_INIT) == 0)
309 sc->sc_ed[devno] = NULL;
312 /* enable full error dumps again */
313 sc->sc_flags &= ~DASD_QUIET;
316 * Check if there are any disks attached. If not, disestablish
317 * the interrupt.
319 for (devno = 0; devno < sc->sc_maxdevs; devno++) {
320 if (sc->sc_ed[devno])
321 break;
324 if (devno == sc->sc_maxdevs) {
325 printf("%s: disabling controller (no drives attached)\n",
326 device_xname(&sc->sc_dev));
327 mca_intr_disestablish(ma->ma_mc, sc->sc_ih);
328 return;
332 * Run the worker thread.
334 config_pending_incr();
335 if ((error = kthread_create(PRI_NONE, 0, NULL, edcworker, sc, NULL,
336 "%s", device_xname(&sc->sc_dev)))) {
337 aprint_error_dev(&sc->sc_dev, "cannot spawn worker thread: errno=%d\n", error);
338 panic("edc_mca_attach");
342 void
343 edc_add_disk(struct edc_mca_softc *sc, struct ed_softc *ed)
345 sc->sc_ed[ed->sc_devno] = ed;
348 static int
349 edc_intr(void *arg)
351 struct edc_mca_softc *sc = arg;
352 u_int8_t isr, intr_id;
353 u_int16_t sifr;
354 int cmd=-1, devno;
357 * Check if the interrupt was for us.
359 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0)
360 return (0);
363 * Read ISR to find out interrupt type. This also clears the interrupt
364 * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2
365 * and 4 are reserved and not used.
367 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR);
368 intr_id = isr & ISR_INTR_ID_MASK;
370 #ifdef EDC_DEBUG
371 if (intr_id == 0 || intr_id == 2 || intr_id == 4) {
372 aprint_error_dev(&sc->sc_dev, "bogus interrupt id %d\n",
373 (int) intr_id);
374 return (0);
376 #endif
378 /* Get number of device whose intr this was */
379 devno = (isr & 0xe0) >> 5;
382 * Get Status block. Higher byte always says how long the status
383 * block is, rest is device number and command code.
384 * Check the status block length against our supported maximum length
385 * and fetch the data.
387 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL) {
388 size_t len;
389 int i;
391 sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
392 len = (sifr & 0xff00) >> 8;
393 #ifdef DEBUG
394 if (len > EDC_MAX_CMD_RES_LEN)
395 panic("%s: maximum Status Length exceeded: %d > %d",
396 device_xname(&sc->sc_dev),
397 len, EDC_MAX_CMD_RES_LEN);
398 #endif
400 /* Get command code */
401 cmd = sifr & SIFR_CMD_MASK;
403 /* Read whole status block */
404 sc->status_block[0] = sifr;
405 for(i=1; i < len; i++) {
406 while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
407 & BSR_SIFR_FULL) == 0)
410 sc->status_block[i] = le16toh(
411 bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
413 /* zero out rest */
414 if (i < EDC_MAX_CMD_RES_LEN) {
415 memset(&sc->status_block[i], 0,
416 (EDC_MAX_CMD_RES_LEN-i)*sizeof(u_int16_t));
420 switch (intr_id) {
421 case ISR_DATA_TRANSFER_RDY:
423 * Ready to do DMA. The DMA controller has already been
424 * setup, now just kick disk controller to do the transfer.
426 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
427 BCR_INT_ENABLE|BCR_DMA_ENABLE);
428 break;
430 case ISR_COMPLETED:
431 case ISR_COMPLETED_WITH_ECC:
432 case ISR_COMPLETED_RETRIES:
433 case ISR_COMPLETED_WARNING:
435 * Copy device config data if appropriate. sc->sc_ed[]
436 * entry might be NULL during probe.
438 if (cmd == CMD_GET_DEV_CONF && sc->sc_ed[devno]) {
439 memcpy(sc->sc_ed[devno]->sense_data, sc->status_block,
440 sizeof(sc->sc_ed[devno]->sense_data));
443 sc->sc_stat = STAT_DONE;
444 break;
446 case ISR_RESET_COMPLETED:
447 case ISR_ABORT_COMPLETED:
448 /* nothing to do */
449 break;
451 case ISR_ATTN_ERROR:
453 * Basically, this means driver bug or something seriously
454 * hosed. panic rather than extending the lossage.
455 * No status block available, so no further info.
457 panic("%s: dev %d: attention error",
458 device_xname(&sc->sc_dev),
459 devno);
460 /* NOTREACHED */
461 break;
463 default:
464 if ((sc->sc_flags & DASD_QUIET) == 0)
465 edc_dump_status_block(sc, sc->status_block, intr_id);
467 sc->sc_stat = STAT_ERROR;
468 break;
472 * Unless the interrupt is for Data Transfer Ready or
473 * Attention Error, finish by assertion EOI. This makes
474 * attachment aware the interrupt is processed and system
475 * is ready to accept another one.
477 if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR)
478 edc_do_attn(sc, ATN_END_INT, devno, intr_id);
480 /* If Read or Write Data, wakeup worker thread to finish it */
481 if (intr_id != ISR_DATA_TRANSFER_RDY) {
482 if (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)
483 sc->sc_resblk = sc->status_block[SB_RESBLKCNT_IDX];
484 wakeup_one(sc);
487 return (1);
491 * This follows the exact order for Attention Request as
492 * written in DASD Storage Interface Specification MC (Rev 2.2).
494 static int
495 edc_do_attn(struct edc_mca_softc *sc, int attn_type, int devno, int intr_id)
497 int tries;
499 /* 1. Disable interrupts in BCR. */
500 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0);
503 * 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging
504 * a RESET COMPLETED interrupt.
506 if (intr_id != ISR_RESET_COMPLETED) {
507 #ifdef EDC_DEBUG
508 if (attn_type == ATN_CMD_REQ
509 && (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
510 & BSR_INT_PENDING))
511 panic("%s: edc int pending", device_xname(&sc->sc_dev));
512 #endif
514 for(tries=1; tries < EDC_ATTN_MAXTRIES; tries++) {
515 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
516 & BSR_BUSY) == 0)
517 break;
520 if (tries == EDC_ATTN_MAXTRIES) {
521 printf("%s: edc_do_attn: timeout waiting for attachment to become available\n",
522 device_xname(&sc->sc_ed[devno]->sc_dev));
523 return (EIO);
528 * 3. Write proper DEVICE NUMBER and Attention number to ATN.
530 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, attn_type | (devno<<5));
533 * 4. Enable interrupts via BCR.
535 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE);
537 return (0);
541 * Wait until command is processed, timeout after 'secs' seconds.
542 * We use mono_time, since we don't need actual RTC, just time
543 * interval.
545 static void
546 edc_cmd_wait(struct edc_mca_softc *sc, int secs, int poll)
548 int val;
550 if (!poll) {
551 int s;
553 /* Not polling, can sleep. Sleep until we are awakened,
554 * but maximum secs seconds.
556 s = splbio();
557 if (sc->sc_stat != STAT_DONE)
558 (void) tsleep(sc, PRIBIO, "edcwcmd", secs * hz);
559 splx(s);
562 /* Wait until the command is completely finished */
563 while((val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR))
564 & BSR_CMD_INPROGRESS) {
565 if (poll && (val & BSR_INTR))
566 edc_intr(sc);
571 * Command controller to execute specified command on a device.
574 edc_run_cmd(struct edc_mca_softc *sc, int cmd, int devno,
575 u_int16_t cmd_args[], int cmd_len, int poll)
577 int i, error, tries;
578 u_int16_t cmd0;
580 sc->sc_stat = STAT_START;
582 /* Do Attention Request for Command Request. */
583 if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0)))
584 return (error);
587 * Construct the command. The bits are like this:
589 * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
590 * \_/ 0 0 1 0 \__/ \_____/
591 * \ \__________/ \ \_ Command Code (see CMD_*)
592 * \ \ \__ Device: 0 common, 7 controller
593 * \ \__ Options: reserved, bit 10=cache bypass bit
594 * \_ Type: 00=2B, 01=4B, 10 and 11 reserved
596 * We always use device 0 or 1, so difference is made only by Command
597 * Code, Command Options and command length.
599 cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0)
600 | (devno << 5)
601 | (cmd_args[0] << 8) | cmd;
602 cmd_args[0] = cmd0;
605 * Write word of CMD to the CIFR. This sets "Command
606 * Interface Register Full (CMD IN)" in BSR. Once the attachment
607 * detects it, it reads the word and clears CMD IN. This all should
608 * be quite fast, so don't sleep in !poll case neither.
610 for(i=0; i < cmd_len; i++) {
611 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR,
612 htole16(cmd_args[i]));
614 /* Wait until CMD IN is cleared. */
615 tries = 0;
616 for(; (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
617 & BSR_CIFR_FULL) && tries < 10000 ; tries++)
618 delay(poll ? 1000 : 1);
621 if (tries == 10000
622 && bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
623 & BSR_CIFR_FULL) {
624 aprint_error_dev(&sc->sc_dev, "device too slow to accept command %d\n", cmd);
625 return (EIO);
629 /* Wait for command to complete, but maximum 15 seconds. */
630 edc_cmd_wait(sc, 15, poll);
632 return ((sc->sc_stat != STAT_DONE) ? EIO : 0);
635 #ifdef EDC_DEBUG
636 static const char * const edc_commands[] = {
637 "Invalid Command",
638 "Read Data",
639 "Write Data",
640 "Read Verify",
641 "Write with Verify",
642 "Seek",
643 "Park Head",
644 "Get Command Complete Status",
645 "Get Device Status",
646 "Get Device Configuration",
647 "Get POS Information",
648 "Translate RBA",
649 "Write Attachment Buffer",
650 "Read Attachment Buffer",
651 "Run Diagnostic Test",
652 "Get Diagnostic Status Block",
653 "Get MFG Header",
654 "Format Unit",
655 "Format Prepare",
656 "Set MAX RBA",
657 "Set Power Saving Mode",
658 "Power Conservation Command",
661 static const char * const edc_cmd_status[256] = {
662 "Reserved",
663 "Command completed successfully",
664 "Reserved",
665 "Command completed successfully with ECC applied",
666 "Reserved",
667 "Command completed successfully with retries",
668 "Format Command partially completed", /* Status available */
669 "Command completed successfully with ECC and retries",
670 "Command completed with Warning", /* Command Error is available */
671 "Aborted",
672 "Reset completed",
673 "Data Transfer Ready", /* No Status Block available */
674 "Command terminated with failure", /* Device Error is available */
675 "DMA Error", /* Retry entire command as recovery */
676 "Command Block Error",
677 "Attention Error (Illegal Attention Code)",
678 /* 0x14 - 0xff reserved */
681 static const char * const edc_cmd_error[256] = {
682 "No Error",
683 "Invalid parameter in the command block",
684 "Reserved",
685 "Command not supported",
686 "Command Aborted per request",
687 "Reserved",
688 "Command rejected", /* Attachment diagnostic failure */
689 "Format Rejected", /* Prepare Format command is required */
690 "Format Error (Primary Map is not readable)",
691 "Format Error (Secondary map is not readable)",
692 "Format Error (Diagnostic Failure)",
693 "Format Warning (Secondary Map Overflow)",
694 "Reserved"
695 "Format Error (Host Checksum Error)",
696 "Reserved",
697 "Format Warning (Push table overflow)",
698 "Format Warning (More pushes than allowed)",
699 "Reserved",
700 "Format Warning (Error during verifying)",
701 "Invalid device number for the command",
702 /* 0x14-0xff reserved */
705 static const char * const edc_dev_errors[] = {
706 "No Error",
707 "Seek Fault", /* Device report */
708 "Interface Fault (Parity, Attn, or Cmd Complete Error)",
709 "Block not found (ID not found)",
710 "Block not found (AM not found)",
711 "Data ECC Error (hard error)",
712 "ID CRC Error",
713 "RBA Out of Range",
714 "Reserved",
715 "Defective Block",
716 "Reserved",
717 "Selection Error",
718 "Reserved",
719 "Write Fault",
720 "No index or sector pulse",
721 "Device Not Ready",
722 "Seek Error", /* Attachment report */
723 "Bad Format",
724 "Volume Overflow",
725 "No Data AM Found",
726 "Block not found (No ID AM or ID CRC error occurred)",
727 "Reserved",
728 "Reserved",
729 "No ID found on track (ID search)",
730 /* 0x19 - 0xff reserved */
732 #endif /* EDC_DEBUG */
734 static void
735 edc_dump_status_block(struct edc_mca_softc *sc, u_int16_t *status_block,
736 int intr_id)
738 #ifdef EDC_DEBUG
739 printf("%s: Command: %s, Status: %s (intr %d)\n",
740 device_xname(&sc->sc_dev),
741 edc_commands[status_block[0] & 0x1f],
742 edc_cmd_status[SB_GET_CMD_STATUS(status_block)],
743 intr_id
745 #else
746 printf("%s: Command: %d, Status: %d (intr %d)\n",
747 device_xname(&sc->sc_dev),
748 status_block[0] & 0x1f,
749 SB_GET_CMD_STATUS(status_block),
750 intr_id
752 #endif
753 printf("%s: # left blocks: %u, last processed RBA: %u\n",
754 device_xname(&sc->sc_dev),
755 status_block[SB_RESBLKCNT_IDX],
756 (status_block[5] << 16) | status_block[4]);
758 if (intr_id == ISR_COMPLETED_WARNING) {
759 #ifdef EDC_DEBUG
760 aprint_error_dev(&sc->sc_dev, "Command Error Code: %s\n",
761 edc_cmd_error[status_block[1] & 0xff]);
762 #else
763 aprint_error_dev(&sc->sc_dev, "Command Error Code: %d\n",
764 status_block[1] & 0xff);
765 #endif
768 if (intr_id == ISR_CMD_FAILED) {
769 #ifdef EDC_DEBUG
770 char buf[100];
772 printf("%s: Device Error Code: %s\n",
773 device_xname(&sc->sc_dev),
774 edc_dev_errors[status_block[2] & 0xff]);
775 snprintb(buf, sizeof(buf),
776 "\20"
777 "\01SeekOrCmdComplete"
778 "\02Track0Flag"
779 "\03WriteFault"
780 "\04Selected"
781 "\05Ready"
782 "\06Reserved0"
783 "\07STANDBY"
784 "\010Reserved0", (status_block[2] & 0xff00) >> 8);
786 printf("%s: Device Status: %s\n",
787 device_xname(&sc->sc_dev), buf);
788 #else
789 printf("%s: Device Error Code: %d, Device Status: %d\n",
790 device_xname(&sc->sc_dev),
791 status_block[2] & 0xff,
792 (status_block[2] & 0xff00) >> 8);
793 #endif
797 * Main worker thread function.
799 void
800 edcworker(void *arg)
802 struct edc_mca_softc *sc = (struct edc_mca_softc *) arg;
803 struct ed_softc *ed;
804 struct buf *bp;
805 int i, error;
807 config_pending_decr();
809 for(;;) {
810 /* Wait until awakened */
811 (void) tsleep(sc, PRIBIO, "edcidle", 0);
813 for(i=0; i<sc->sc_maxdevs; ) {
814 if ((ed = sc->sc_ed[i]) == NULL) {
815 i++;
816 continue;
819 /* Is there a buf for us ? */
820 simple_lock(&ed->sc_q_lock);
821 if ((bp = bufq_get(ed->sc_q)) == NULL) {
822 simple_unlock(&ed->sc_q_lock);
823 i++;
824 continue;
826 simple_unlock(&ed->sc_q_lock);
828 /* Instrumentation. */
829 disk_busy(&ed->sc_dk);
831 error = edc_bio(sc, ed, bp->b_data, bp->b_bcount,
832 bp->b_rawblkno, (bp->b_flags & B_READ), 0);
834 if (error) {
835 bp->b_error = error;
836 } else {
837 /* Set resid, most commonly to zero. */
838 bp->b_resid = sc->sc_resblk * DEV_BSIZE;
841 disk_unbusy(&ed->sc_dk, (bp->b_bcount - bp->b_resid),
842 (bp->b_flags & B_READ));
843 #if NRND > 0
844 rnd_add_uint32(&ed->rnd_source, bp->b_blkno);
845 #endif
846 biodone(bp);
852 edc_bio(struct edc_mca_softc *sc, struct ed_softc *ed, void *data,
853 size_t bcount, daddr_t rawblkno, int isread, int poll)
855 u_int16_t cmd_args[4];
856 int error=0, fl;
857 u_int16_t track;
858 u_int16_t cyl;
859 u_int8_t head;
860 u_int8_t sector;
862 mca_disk_busy();
864 /* set WAIT and R/W flag appropriately for the DMA transfer */
865 fl = ((poll) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK)
866 | ((isread) ? BUS_DMA_READ : BUS_DMA_WRITE);
868 /* Load the buffer for DMA transfer. */
869 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_xfer, data,
870 bcount, NULL, BUS_DMA_STREAMING|fl))) {
871 printf("%s: ed_bio: unable to load DMA buffer - error %d\n",
872 device_xname(&ed->sc_dev), error);
873 goto out;
876 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0,
877 bcount, (isread) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
879 track = rawblkno / ed->sectors;
880 head = track % ed->heads;
881 cyl = track / ed->heads;
882 sector = rawblkno % ed->sectors;
884 /* Read or Write Data command */
885 cmd_args[0] = 2; /* Options 0000010 */
886 cmd_args[1] = bcount / DEV_BSIZE;
887 cmd_args[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
888 cmd_args[3] = ((cyl & 0x3E0) >> 5);
889 error = edc_run_cmd(sc,
890 (isread) ? CMD_READ_DATA : CMD_WRITE_DATA,
891 ed->sc_devno, cmd_args, 4, poll);
893 /* Sync the DMA memory */
894 if (!error) {
895 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, bcount,
896 (isread)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
899 /* We are done, unload buffer from DMA map */
900 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_xfer);
902 out:
903 mca_disk_unbusy();
905 return (error);