xref: /netbsd-src/sys/dev/mca/edc_mca.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: edc_mca.c,v 1.38 2007/10/19 12:00:34 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@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.38 2007/10/19 12:00:34 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 <sys/bus.h>
77 #include <sys/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 			} else {
849 				/* Set resid, most commonly to zero. */
850 				bp->b_resid = sc->sc_resblk * DEV_BSIZE;
851 			}
852 
853 			disk_unbusy(&ed->sc_dk, (bp->b_bcount - bp->b_resid),
854 			    (bp->b_flags & B_READ));
855 #if NRND > 0
856 			rnd_add_uint32(&ed->rnd_source, bp->b_blkno);
857 #endif
858 			biodone(bp);
859 		}
860 	}
861 }
862 
863 int
864 edc_bio(struct edc_mca_softc *sc, struct ed_softc *ed, void *data,
865 	size_t bcount, daddr_t rawblkno, int isread, int poll)
866 {
867 	u_int16_t cmd_args[4];
868 	int error=0, fl;
869 	u_int16_t track;
870 	u_int16_t cyl;
871 	u_int8_t head;
872 	u_int8_t sector;
873 
874 	mca_disk_busy();
875 
876 	/* set WAIT and R/W flag appropriately for the DMA transfer */
877 	fl = ((poll) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK)
878 		| ((isread) ? BUS_DMA_READ : BUS_DMA_WRITE);
879 
880 	/* Load the buffer for DMA transfer. */
881 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_xfer, data,
882 	    bcount, NULL, BUS_DMA_STREAMING|fl))) {
883 		printf("%s: ed_bio: unable to load DMA buffer - error %d\n",
884 			ed->sc_dev.dv_xname, error);
885 		goto out;
886 	}
887 
888 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0,
889 		bcount, (isread) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
890 
891 	track = rawblkno / ed->sectors;
892 	head = track % ed->heads;
893 	cyl = track / ed->heads;
894 	sector = rawblkno % ed->sectors;
895 
896 	/* Read or Write Data command */
897 	cmd_args[0] = 2;	/* Options 0000010 */
898 	cmd_args[1] = bcount / DEV_BSIZE;
899 	cmd_args[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
900 	cmd_args[3] = ((cyl & 0x3E0) >> 5);
901 	error = edc_run_cmd(sc,
902 			(isread) ? CMD_READ_DATA : CMD_WRITE_DATA,
903 			ed->sc_devno, cmd_args, 4, poll);
904 
905 	/* Sync the DMA memory */
906 	if (!error)  {
907 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, bcount,
908 			(isread)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
909 	}
910 
911 	/* We are done, unload buffer from DMA map */
912 	bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_xfer);
913 
914     out:
915 	mca_disk_unbusy();
916 
917 	return (error);
918 }
919