1 /* $NetBSD: edc_mca.c,v 1.43 2009/05/12 13:15:24 cegger Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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
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>.
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 $");
53 #include <sys/param.h>
54 #include <sys/systm.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>
63 #include <sys/syslog.h>
65 #include <sys/vnode.h>
66 #include <sys/kernel.h>
67 #include <sys/kthread.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>
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
{
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 */
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
108 /* I/O results variables */
109 volatile int sc_stat
;
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
*,
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
,
136 struct mca_attach_args
*ma
= aux
;
139 case MCA_PRODUCT_IBM_ESDIC
:
140 case MCA_PRODUCT_IBM_ESDIC_IG
:
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
;
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)
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)
178 * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms
179 * 01=16ms 00=Burst Disabled
181 * POS register 4: (adf pos2)
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).
191 case MCA_PRODUCT_IBM_ESDIC
:
192 typestr
= "IBM ESDI Fixed Disk Controller";
194 case MCA_PRODUCT_IBM_ESDIC_IG
:
195 typestr
= "IBM Integ. ESDI Fixed Disk & Controller";
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,
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
);
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]);
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");
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");
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
);
258 * Integrated ESDI controller supports only one disk, other
259 * controllers support two disks.
261 if (ma
->ma_id
== MCA_PRODUCT_IBM_ESDIC_IG
)
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
) {
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
);
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
)
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
;
303 (void *) config_found_sm_loc(self
, "edc", locs
, &eda
,
304 NULL
, config_stdsubmatch
);
306 /* If initialization did not succeed, NULL the pointer. */
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
319 for (devno
= 0; devno
< sc
->sc_maxdevs
; devno
++) {
320 if (sc
->sc_ed
[devno
])
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
);
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");
343 edc_add_disk(struct edc_mca_softc
*sc
, struct ed_softc
*ed
)
345 sc
->sc_ed
[ed
->sc_devno
] = ed
;
351 struct edc_mca_softc
*sc
= arg
;
352 u_int8_t isr
, intr_id
;
357 * Check if the interrupt was for us.
359 if ((bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, BSR
) & BSR_INTR
) == 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
;
371 if (intr_id
== 0 || intr_id
== 2 || intr_id
== 4) {
372 aprint_error_dev(&sc
->sc_dev
, "bogus interrupt id %d\n",
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
) {
391 sifr
= le16toh(bus_space_read_2(sc
->sc_iot
, sc
->sc_ioh
, SIFR
));
392 len
= (sifr
& 0xff00) >> 8;
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
);
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
));
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
));
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
);
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
;
446 case ISR_RESET_COMPLETED
:
447 case ISR_ABORT_COMPLETED
:
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
),
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
;
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
];
491 * This follows the exact order for Attention Request as
492 * written in DASD Storage Interface Specification MC (Rev 2.2).
495 edc_do_attn(struct edc_mca_softc
*sc
, int attn_type
, int devno
, int intr_id
)
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
) {
508 if (attn_type
== ATN_CMD_REQ
509 && (bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, BSR
)
511 panic("%s: edc int pending", device_xname(&sc
->sc_dev
));
514 for(tries
=1; tries
< EDC_ATTN_MAXTRIES
; tries
++) {
515 if ((bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, BSR
)
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
));
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
);
541 * Wait until command is processed, timeout after 'secs' seconds.
542 * We use mono_time, since we don't need actual RTC, just time
546 edc_cmd_wait(struct edc_mca_softc
*sc
, int secs
, int poll
)
553 /* Not polling, can sleep. Sleep until we are awakened,
554 * but maximum secs seconds.
557 if (sc
->sc_stat
!= STAT_DONE
)
558 (void) tsleep(sc
, PRIBIO
, "edcwcmd", secs
* hz
);
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
))
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
)
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)))
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)
601 | (cmd_args
[0] << 8) | cmd
;
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. */
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);
622 && bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, BSR
)
624 aprint_error_dev(&sc
->sc_dev
, "device too slow to accept command %d\n", cmd
);
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);
636 static const char * const edc_commands
[] = {
644 "Get Command Complete Status",
646 "Get Device Configuration",
647 "Get POS Information",
649 "Write Attachment Buffer",
650 "Read Attachment Buffer",
651 "Run Diagnostic Test",
652 "Get Diagnostic Status Block",
657 "Set Power Saving Mode",
658 "Power Conservation Command",
661 static const char * const edc_cmd_status
[256] = {
663 "Command completed successfully",
665 "Command completed successfully with ECC applied",
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 */
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] = {
683 "Invalid parameter in the command block",
685 "Command not supported",
686 "Command Aborted per request",
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)",
695 "Format Error (Host Checksum Error)",
697 "Format Warning (Push table overflow)",
698 "Format Warning (More pushes than allowed)",
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
[] = {
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)",
720 "No index or sector pulse",
722 "Seek Error", /* Attachment report */
726 "Block not found (No ID AM or ID CRC error occurred)",
729 "No ID found on track (ID search)",
730 /* 0x19 - 0xff reserved */
732 #endif /* EDC_DEBUG */
735 edc_dump_status_block(struct edc_mca_softc
*sc
, u_int16_t
*status_block
,
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
)],
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
),
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
) {
760 aprint_error_dev(&sc
->sc_dev
, "Command Error Code: %s\n",
761 edc_cmd_error
[status_block
[1] & 0xff]);
763 aprint_error_dev(&sc
->sc_dev
, "Command Error Code: %d\n",
764 status_block
[1] & 0xff);
768 if (intr_id
== ISR_CMD_FAILED
) {
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
),
777 "\01SeekOrCmdComplete"
784 "\010Reserved0", (status_block
[2] & 0xff00) >> 8);
786 printf("%s: Device Status: %s\n",
787 device_xname(&sc
->sc_dev
), buf
);
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);
797 * Main worker thread function.
802 struct edc_mca_softc
*sc
= (struct edc_mca_softc
*) arg
;
807 config_pending_decr();
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
) {
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
);
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);
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
));
844 rnd_add_uint32(&ed
->rnd_source
, bp
->b_blkno
);
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];
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
);
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 */
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
);