xref: /netbsd/sys/dev/mca/edc_mca.c (revision bf9ec67e)
1 /*	$NetBSD: edc_mca.c,v 1.16 2002/03/31 10:01:26 jdolecek Exp $	*/
2 
3 /*
4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by Jaromir Dolecek.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *        This product includes software developed by the NetBSD
20  *        Foundation, Inc. and its contributors.
21  * 4. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /*
37  * Driver for MCA ESDI controllers and disks conforming to IBM DASD
38  * spec.
39  *
40  * The driver was written with DASD Storage Interface Specification
41  * for MCA rev. 2.2 in hands, thanks to Scott Telford <st@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.16 2002/03/31 10:01:26 jdolecek Exp $");
54 
55 #include "rnd.h"
56 
57 #include <sys/param.h>
58 #include <sys/systm.h>
59 #include <sys/errno.h>
60 #include <sys/device.h>
61 #include <sys/malloc.h>
62 #include <sys/endian.h>
63 #include <sys/disklabel.h>
64 #include <sys/disk.h>
65 #include <sys/syslog.h>
66 #include <sys/proc.h>
67 #include <sys/vnode.h>
68 #include <sys/kernel.h>
69 #include <sys/kthread.h>
70 #if NRND > 0
71 #include <sys/rnd.h>
72 #endif
73 
74 #include <machine/bus.h>
75 #include <machine/intr.h>
76 
77 #include <dev/mca/mcareg.h>
78 #include <dev/mca/mcavar.h>
79 #include <dev/mca/mcadevs.h>
80 
81 #include <dev/mca/edcreg.h>
82 #include <dev/mca/edvar.h>
83 #include <dev/mca/edcvar.h>
84 
85 #define EDC_ATTN_MAXTRIES	10000	/* How many times check for unbusy */
86 #define EDC_MAX_CMD_RES_LEN	8
87 
88 struct edc_mca_softc {
89 	struct device sc_dev;
90 
91 	bus_space_tag_t	sc_iot;
92 	bus_space_handle_t sc_ioh;
93 
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 */
97 
98 	void	*sc_ih;				/* interrupt handle */
99 
100 	int	sc_flags;
101 #define	DASD_QUIET	0x01		/* don't dump cmd error info */
102 
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 */
107 
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 */
114 
115 	/* CMD status block - only set & used in edc_intr() */
116 	u_int16_t status_block[EDC_MAX_CMD_RES_LEN];
117 };
118 
119 int	edc_mca_probe	__P((struct device *, struct cfdata *, void *));
120 void	edc_mca_attach	__P((struct device *, struct device *, void *));
121 
122 struct cfattach edc_mca_ca = {
123 	sizeof(struct edc_mca_softc), edc_mca_probe, edc_mca_attach
124 };
125 
126 static int	edc_intr __P((void *));
127 static void	edc_dump_status_block __P((struct edc_mca_softc *,
128 		    u_int16_t *, int));
129 static int	edc_do_attn __P((struct edc_mca_softc *, int, int, int));
130 static void	edc_cmd_wait __P((struct edc_mca_softc *, int, int));
131 static void	edcworker __P((void *));
132 static void	edc_spawn_worker __P((void *));
133 
134 int
135 edc_mca_probe(parent, match, aux)
136 	struct device *parent;
137 	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(parent, self, aux)
153 	struct device *parent, *self;
154 	void *aux;
155 {
156 	struct edc_mca_softc *sc = (void *) self;
157 	struct mca_attach_args *ma = aux;
158 	struct ed_attach_args eda;
159 	int pos2, pos3, pos4;
160 	int irq, drq, iobase;
161 	const char *typestr;
162 	int devno, error;
163 
164 	pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2);
165 	pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3);
166 	pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4);
167 
168 	/*
169 	 * POS register 2: (adf pos0)
170 	 *
171 	 * 7 6 5 4 3 2 1 0
172 	 *   \ \____/  \ \__ enable: 0=adapter disabled, 1=adapter enabled
173 	 *    \     \   \___ Primary/Alternate Port Adresses:
174 	 *     \     \		0=0x3510-3517 1=0x3518-0x351f
175 	 *      \     \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7
176 	 *       \              0000=0 0001=1 0011=3 0100=4
177 	 *        \_________ Fairness On/Off: 1=On 0=Off
178 	 *
179 	 * POS register 3: (adf pos1)
180 	 *
181 	 * 7 6 5 4 3 2 1 0
182 	 * 0 0 \_/
183 	 *       \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms
184 	 *                     01=16ms 00=Burst Disabled
185 	 *
186 	 * POS register 4: (adf pos2)
187 	 *
188 	 * 7 6 5 4 3 2 1 0
189 	 *           \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled
190 	 *             \____ Time to Release: 1X=6ms 01=3ms 00=Immediate
191 	 *
192 	 * IRQ is fixed to 14 (0x0e).
193 	 */
194 
195 	switch (ma->ma_id) {
196 	case MCA_PRODUCT_IBM_ESDIC:
197 		typestr = "IBM ESDI Fixed Disk Controller";
198 		break;
199 	case MCA_PRODUCT_IBM_ESDIC_IG:
200 		typestr = "IBM Integ. ESDI Fixed Disk & Controller";
201 		break;
202 	default:
203 		/* never reached */ ;
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 adresses.
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 		sc->sc_ed[devno] =
310 			(void *) config_found_sm(self, &eda, NULL, NULL);
311 
312 		/* If initialization did not succeed, NULL the pointer. */
313 		if (sc->sc_ed[devno]
314 		    && (sc->sc_ed[devno]->sc_flags & EDF_INIT) == 0)
315 			sc->sc_ed[devno] = NULL;
316 	}
317 
318 	/* enable full error dumps again */
319 	sc->sc_flags &= ~DASD_QUIET;
320 
321 	/*
322 	 * Check if there are any disks attached. If not, disestablish
323 	 * the interrupt.
324 	 */
325 	for(devno=0; devno < sc->sc_maxdevs; devno++) {
326 		if (sc->sc_ed[devno])
327 			break;
328 	}
329 
330 	if (devno == sc->sc_maxdevs) {
331 		printf("%s: disabling controller (no drives attached)\n",
332 			sc->sc_dev.dv_xname);
333 		mca_intr_disestablish(ma->ma_mc, sc->sc_ih);
334 		return;
335 	}
336 
337 	/*
338 	 * Run the worker thread.
339 	 */
340 	config_pending_incr();
341 	kthread_create(edc_spawn_worker, (void *) sc);
342 }
343 
344 void
345 edc_add_disk(sc, ed)
346 	struct edc_mca_softc *sc;
347 	struct ed_softc *ed;
348 {
349 	sc->sc_ed[ed->sc_devno] = ed;
350 }
351 
352 static int
353 edc_intr(arg)
354 	void *arg;
355 {
356 	struct edc_mca_softc *sc = arg;
357 	u_int8_t isr, intr_id;
358 	u_int16_t sifr;
359 	int cmd=-1, devno;
360 
361 	/*
362 	 * Check if the interrupt was for us.
363 	 */
364 	if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0)
365 		return (0);
366 
367 	/*
368 	 * Read ISR to find out interrupt type. This also clears the interrupt
369 	 * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2
370 	 * and 4 are reserved and not used.
371 	 */
372 	isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR);
373 	intr_id = isr & ISR_INTR_ID_MASK;
374 
375 #ifdef EDC_DEBUG
376 	if (intr_id == 0 || intr_id == 2 || intr_id == 4) {
377 		printf("%s: bogus interrupt id %d\n", sc->sc_dev.dv_xname,
378 			(int) intr_id);
379 		return (0);
380 	}
381 #endif
382 
383 	/* Get number of device whose intr this was */
384 	devno = (isr & 0xe0) >> 5;
385 
386 	/*
387 	 * Get Status block. Higher byte always says how long the status
388 	 * block is, rest is device number and command code.
389 	 * Check the status block length against our supported maximum length
390 	 * and fetch the data.
391 	 */
392 	if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL) {
393 		size_t len;
394 		int i;
395 
396 		sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
397 		len = (sifr & 0xff00) >> 8;
398 #ifdef DEBUG
399 		if (len > EDC_MAX_CMD_RES_LEN)
400 			panic("%s: maximum Status Length exceeded: %d > %d",
401 				sc->sc_dev.dv_xname,
402 				len, EDC_MAX_CMD_RES_LEN);
403 #endif
404 
405 		/* Get command code */
406 		cmd = sifr & SIFR_CMD_MASK;
407 
408 		/* Read whole status block */
409 		sc->status_block[0] = sifr;
410 		for(i=1; i < len; i++) {
411 			while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
412 				& BSR_SIFR_FULL) == 0)
413 				;
414 
415 			sc->status_block[i] = le16toh(
416 				bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR));
417 		}
418 		/* zero out rest */
419 		if (i < EDC_MAX_CMD_RES_LEN) {
420 			memset(&sc->status_block[i], 0,
421 				(EDC_MAX_CMD_RES_LEN-i)*sizeof(u_int16_t));
422 		}
423 	}
424 
425 	switch (intr_id) {
426 	case ISR_DATA_TRANSFER_RDY:
427 		/*
428 		 * Ready to do DMA. The DMA controller has already been
429 		 * setup, now just kick disk controller to do the transfer.
430 		 */
431 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR,
432 			BCR_INT_ENABLE|BCR_DMA_ENABLE);
433 		break;
434 
435 	case ISR_COMPLETED:
436 	case ISR_COMPLETED_WITH_ECC:
437 	case ISR_COMPLETED_RETRIES:
438 	case ISR_COMPLETED_WARNING:
439 		/*
440 		 * Copy device config data if appropriate. sc->sc_ed[]
441 		 * entry might be NULL during probe.
442 		 */
443 		if (cmd == CMD_GET_DEV_CONF && sc->sc_ed[devno]) {
444 			memcpy(sc->sc_ed[devno]->sense_data, sc->status_block,
445 				sizeof(sc->sc_ed[devno]->sense_data));
446 		}
447 
448 		sc->sc_stat = STAT_DONE;
449 		break;
450 
451 	case ISR_RESET_COMPLETED:
452 	case ISR_ABORT_COMPLETED:
453 		/* nothing to do */
454 		break;
455 
456 	case ISR_ATTN_ERROR:
457 		/*
458 		 * Basically, this means driver bug or something seriously
459 		 * hosed. panic rather than extending the lossage.
460 		 * No status block available, so no further info.
461 		 */
462 		panic("%s: dev %d: attention error",
463 			sc->sc_dev.dv_xname,
464 			devno);
465 		/* NOTREACHED */
466 		break;
467 
468 	default:
469 		if ((sc->sc_flags & DASD_QUIET) == 0)
470 			edc_dump_status_block(sc, sc->status_block, intr_id);
471 
472 		sc->sc_stat = STAT_ERROR;
473 		break;
474 	}
475 
476 	/*
477 	 * Unless the interrupt is for Data Transfer Ready or
478 	 * Attention Error, finish by assertion EOI. This makes
479 	 * attachment aware the interrupt is processed and system
480 	 * is ready to accept another one.
481 	 */
482 	if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR)
483 		edc_do_attn(sc, ATN_END_INT, devno, intr_id);
484 
485 	/* If Read or Write Data, wakeup worker thread to finish it */
486 	if (intr_id != ISR_DATA_TRANSFER_RDY) {
487 	    	if (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)
488 			sc->sc_resblk = sc->status_block[SB_RESBLKCNT_IDX];
489 		wakeup_one(sc);
490 	}
491 
492 	return (1);
493 }
494 
495 /*
496  * This follows the exact order for Attention Request as
497  * written in DASD Storage Interface Specification MC (Rev 2.2).
498  */
499 static int
500 edc_do_attn(sc, attn_type, devno, intr_id)
501 	struct edc_mca_softc *sc;
502 	int attn_type, devno, intr_id;
503 {
504 	int tries;
505 
506 	/* 1. Disable interrupts in BCR. */
507 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0);
508 
509 	/*
510 	 * 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging
511 	 *    a RESET COMPLETED interrupt.
512 	 */
513 	if (intr_id != ISR_RESET_COMPLETED) {
514 #ifdef EDC_DEBUG
515 		if (attn_type == ATN_CMD_REQ
516 		    && (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
517 			    & BSR_INT_PENDING))
518 			panic("%s: edc int pending", sc->sc_dev.dv_xname);
519 #endif
520 
521 		for(tries=1; tries < EDC_ATTN_MAXTRIES; tries++) {
522 			if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
523 			     & BSR_BUSY) == 0)
524 				break;
525 		}
526 
527 		if (tries == EDC_ATTN_MAXTRIES) {
528 			printf("%s: edc_do_attn: timeout waiting for attachment to become available\n",
529 					sc->sc_ed[devno]->sc_dev.dv_xname);
530 			return (EIO);
531 		}
532 	}
533 
534 	/*
535 	 * 3. Write proper DEVICE NUMBER and Attention number to ATN.
536 	 */
537 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, attn_type | (devno<<5));
538 
539 	/*
540 	 * 4. Enable interrupts via BCR.
541 	 */
542 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE);
543 
544 	return (0);
545 }
546 
547 /*
548  * Wait until command is processed, timeout after 'secs' seconds.
549  * We use mono_time, since we don't need actual RTC, just time
550  * interval.
551  */
552 static void
553 edc_cmd_wait(sc, secs, poll)
554 	struct edc_mca_softc *sc;
555 	int secs, 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(sc, cmd, devno, cmd_args, cmd_len, poll)
584 	struct edc_mca_softc *sc;
585 	int cmd;
586 	int devno;
587 	u_int16_t cmd_args[];
588 	int cmd_len, poll;
589 {
590 	int i, error, tries;
591 	u_int16_t cmd0;
592 
593 	sc->sc_stat = STAT_START;
594 
595 	/* Do Attention Request for Command Request. */
596 	if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0)))
597 		return (error);
598 
599 	/*
600 	 * Construct the command. The bits are like this:
601 	 *
602 	 * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
603 	 *  \_/   0  0       1 0 \__/   \_____/
604 	 *    \    \__________/     \         \_ Command Code (see CMD_*)
605 	 *     \              \      \__ Device: 0 common, 7 controller
606 	 *      \              \__ Options: reserved, bit 10=cache bypass bit
607 	 *       \_ Type: 00=2B, 01=4B, 10 and 11 reserved
608 	 *
609 	 * We always use device 0 or 1, so difference is made only by Command
610 	 * Code, Command Options and command length.
611 	 */
612 	cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0)
613 		| (devno <<  5)
614 		| (cmd_args[0] << 8) | cmd;
615 	cmd_args[0] = cmd0;
616 
617 	/*
618 	 * Write word of CMD to the CIFR. This sets "Command
619 	 * Interface Register Full (CMD IN)" in BSR. Once the attachment
620 	 * detects it, it reads the word and clears CMD IN. This all should
621 	 * be quite fast, so don't sleep in !poll case neither.
622 	 */
623 	for(i=0; i < cmd_len; i++) {
624 		bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR,
625 			htole16(cmd_args[i]));
626 
627 		/* Wait until CMD IN is cleared. */
628 		tries = 0;
629 		for(; (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
630 		    & BSR_CIFR_FULL) && tries < 10000 ; tries++)
631 			delay(poll ? 1000 : 1);
632 			;
633 
634 		if (tries == 10000
635 		    && bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)
636 		       & BSR_CIFR_FULL) {
637 			printf("%s: device too slow to accept command %d\n",
638 				sc->sc_dev.dv_xname, cmd);
639 			return (EIO);
640 		}
641 	}
642 
643 	/* Wait for command to complete, but maximum 15 seconds. */
644 	edc_cmd_wait(sc, 15, poll);
645 
646 	return ((sc->sc_stat != STAT_DONE) ? EIO : 0);
647 }
648 
649 #ifdef EDC_DEBUG
650 static const char * const edc_commands[] = {
651 	"Invalid Command",
652 	"Read Data",
653 	"Write Data",
654 	"Read Verify",
655 	"Write with Verify",
656 	"Seek",
657 	"Park Head",
658 	"Get Command Complete Status",
659 	"Get Device Status",
660 	"Get Device Configuration",
661 	"Get POS Information",
662 	"Translate RBA",
663 	"Write Attachment Buffer",
664 	"Read Attachment Buffer",
665 	"Run Diagnostic Test",
666 	"Get Diagnostic Status Block",
667 	"Get MFG Header",
668 	"Format Unit",
669 	"Format Prepare",
670 	"Set MAX RBA",
671 	"Set Power Saving Mode",
672 	"Power Conservation Command",
673 };
674 
675 static const char * const edc_cmd_status[256] = {
676 	"Reserved",
677 	"Command completed successfully",
678 	"Reserved",
679 	"Command completed successfully with ECC applied",
680 	"Reserved",
681 	"Command completed successfully with retries",
682 	"Format Command partially completed",	/* Status available */
683 	"Command completed successfully with ECC and retries",
684 	"Command completed with Warning", 	/* Command Error is available */
685 	"Aborted",
686 	"Reset completed",
687 	"Data Transfer Ready",		/* No Status Block available */
688 	"Command terminated with failure",	/* Device Error is available */
689 	"DMA Error",			/* Retry entire command as recovery */
690 	"Command Block Error",
691 	"Attention Error (Illegal Attention Code)",
692 	/* 0x14 - 0xff reserved */
693 };
694 
695 static const char * const edc_cmd_error[256] = {
696 	"No Error",
697 	"Invalid parameter in the command block",
698 	"Reserved",
699 	"Command not supported",
700 	"Command Aborted per request",
701 	"Reserved",
702 	"Command rejected",	/* Attachment diagnostic failure */
703 	"Format Rejected",	/* Prepare Format command is required */
704 	"Format Error (Primary Map is not readable)",
705 	"Format Error (Secondary map is not readable)",
706 	"Format Error (Diagnostic Failure)",
707 	"Format Warning (Secondary Map Overflow)",
708 	"Reserved"
709 	"Format Error (Host Checksum Error)",
710 	"Reserved",
711 	"Format Warning (Push table overflow)",
712 	"Format Warning (More pushes than allowed)",
713 	"Reserved",
714 	"Format Warning (Error during verifying)",
715 	"Invalid device number for the command",
716 	/* 0x14-0xff reserved */
717 };
718 
719 static const char * const edc_dev_errors[] = {
720 	"No Error",
721 	"Seek Fault",	/* Device report */
722 	"Interface Fault (Parity, Attn, or Cmd Complete Error)",
723 	"Block not found (ID not found)",
724 	"Block not found (AM not found)",
725 	"Data ECC Error (hard error)",
726 	"ID CRC Error",
727 	"RBA Out of Range",
728 	"Reserved",
729 	"Defective Block",
730 	"Reserved",
731 	"Selection Error",
732 	"Reserved",
733 	"Write Fault",
734 	"No index or sector pulse",
735 	"Device Not Ready",
736 	"Seek Error",	/* Attachment report */
737 	"Bad Format",
738 	"Volume Overflow",
739 	"No Data AM Found",
740 	"Block not found (No ID AM or ID CRC error occurred)",
741 	"Reserved",
742 	"Reserved",
743 	"No ID found on track (ID search)",
744 	/* 0x19 - 0xff reserved */
745 };
746 #endif /* EDC_DEBUG */
747 
748 static void
749 edc_dump_status_block(sc, status_block, intr_id)
750 	struct edc_mca_softc *sc;
751 	u_int16_t *status_block;
752 	int intr_id;
753 {
754 #ifdef EDC_DEBUG
755 	printf("%s: Command: %s, Status: %s (intr %d)\n",
756 		sc->sc_dev.dv_xname,
757 		edc_commands[status_block[0] & 0x1f],
758 		edc_cmd_status[SB_GET_CMD_STATUS(status_block)],
759 		intr_id
760 		);
761 #else
762 	printf("%s: Command: %d, Status: %d (intr %d)\n",
763 		sc->sc_dev.dv_xname,
764 		status_block[0] & 0x1f,
765 		SB_GET_CMD_STATUS(status_block),
766 		intr_id
767 		);
768 #endif
769 	printf("%s: # left blocks: %u, last processed RBA: %u\n",
770 		sc->sc_dev.dv_xname,
771 		status_block[SB_RESBLKCNT_IDX],
772 		(status_block[5] << 16) | status_block[4]);
773 
774 	if (intr_id == ISR_COMPLETED_WARNING) {
775 #ifdef EDC_DEBUG
776 		printf("%s: Command Error Code: %s\n",
777 			sc->sc_dev.dv_xname,
778 			edc_cmd_error[status_block[1] & 0xff]);
779 #else
780 		printf("%s: Command Error Code: %d\n",
781 			sc->sc_dev.dv_xname,
782 			status_block[1] & 0xff);
783 #endif
784 	}
785 
786 	if (intr_id == ISR_CMD_FAILED) {
787 #ifdef EDC_DEBUG
788 		char buf[100];
789 
790 		printf("%s: Device Error Code: %s\n",
791 			sc->sc_dev.dv_xname,
792 			edc_dev_errors[status_block[2] & 0xff]);
793 		bitmask_snprintf((status_block[2] & 0xff00) >> 8,
794 			"\20"
795 			"\01SeekOrCmdComplete"
796 			"\02Track0Flag"
797 			"\03WriteFault"
798 			"\04Selected"
799 			"\05Ready"
800 			"\06Reserved0"
801 			"\07STANDBY"
802 			"\010Reserved0",
803 			buf, sizeof(buf));
804 		printf("%s: Device Status: %s\n",
805 			sc->sc_dev.dv_xname, buf);
806 #else
807 		printf("%s: Device Error Code: %d, Device Status: %d\n",
808 			sc->sc_dev.dv_xname,
809 			status_block[2] & 0xff,
810 			(status_block[2] & 0xff00) >> 8);
811 #endif
812 	}
813 }
814 
815 static void
816 edc_spawn_worker(arg)
817 	void *arg;
818 {
819 	struct edc_mca_softc *sc = (struct edc_mca_softc *) arg;
820 	int error;
821 	struct proc *wrk;
822 
823 	/* Now, everything is ready, start a kthread */
824 	if ((error = kthread_create1(edcworker, sc, &wrk,
825 			"%s", sc->sc_dev.dv_xname))) {
826 		printf("%s: cannot spawn worker thread: errno=%d\n",
827 			sc->sc_dev.dv_xname, error);
828 		panic("edc_spawn_worker");
829 	}
830 }
831 
832 /*
833  * Main worker thread function.
834  */
835 void
836 edcworker(arg)
837 	void *arg;
838 {
839 	struct edc_mca_softc *sc = (struct edc_mca_softc *) arg;
840 	struct ed_softc *ed;
841 	struct buf *bp;
842 	int i, error;
843 
844 	config_pending_decr();
845 
846 	for(;;) {
847 		/* Wait until awakened */
848 		(void) tsleep(sc, PRIBIO, "edcidle", 0);
849 
850 		for(i=0; i<sc->sc_maxdevs; ) {
851 			if ((ed = sc->sc_ed[i]) == NULL) {
852 				i++;
853 				continue;
854 			}
855 
856 			/* Is there a buf for us ? */
857 			simple_lock(&ed->sc_q_lock);
858 			if ((bp = BUFQ_FIRST(&ed->sc_q)) == NULL) {
859 				simple_unlock(&ed->sc_q_lock);
860 				i++;
861 				continue;
862 			}
863 			BUFQ_REMOVE(&ed->sc_q, bp);
864 			simple_unlock(&ed->sc_q_lock);
865 
866 			/* Instrumentation. */
867 			disk_busy(&ed->sc_dk);
868 
869 			error = edc_bio(sc, ed, bp->b_data, bp->b_bcount,
870 				bp->b_rawblkno, (bp->b_flags & B_READ), 0);
871 
872 			if (error) {
873 				bp->b_error = error;
874 				bp->b_flags |= B_ERROR;
875 			} else {
876 				/* Set resid, most commonly to zero. */
877 				bp->b_resid = sc->sc_resblk * DEV_BSIZE;
878 			}
879 
880 			disk_unbusy(&ed->sc_dk, (bp->b_bcount - bp->b_resid));
881 #if NRND > 0
882 			rnd_add_uint32(&ed->rnd_source, bp->b_blkno);
883 #endif
884 			biodone(bp);
885 		}
886 	}
887 }
888 
889 int
890 edc_bio(struct edc_mca_softc *sc, struct ed_softc *ed, void *data,
891 	size_t bcount, daddr_t rawblkno, int isread, int poll)
892 {
893 	u_int16_t cmd_args[4];
894 	int error=0, fl;
895 	u_int16_t track;
896 	u_int16_t cyl;
897 	u_int8_t head;
898 	u_int8_t sector;
899 
900 	mca_disk_busy();
901 
902 	/* set WAIT and R/W flag appropriately for the DMA transfer */
903 	fl = ((poll) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK)
904 		| ((isread) ? BUS_DMA_READ : BUS_DMA_WRITE);
905 
906 	/* Load the buffer for DMA transfer. */
907 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_xfer, data,
908 	    bcount, NULL, BUS_DMA_STREAMING|fl))) {
909 		printf("%s: ed_bio: unable to load DMA buffer - error %d\n",
910 			ed->sc_dev.dv_xname, error);
911 		goto out;
912 	}
913 
914 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0,
915 		bcount, (isread) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
916 
917 	track = rawblkno / ed->sectors;
918 	head = track % ed->heads;
919 	cyl = track / ed->heads;
920 	sector = rawblkno % ed->sectors;
921 
922 	/* Read or Write Data command */
923 	cmd_args[0] = 2;	/* Options 0000010 */
924 	cmd_args[1] = bcount / DEV_BSIZE;
925 	cmd_args[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
926 	cmd_args[3] = ((cyl & 0x3E0) >> 5);
927 	error = edc_run_cmd(sc,
928 			(isread) ? CMD_READ_DATA : CMD_WRITE_DATA,
929 			ed->sc_devno, cmd_args, 4, poll);
930 
931 	/* Sync the DMA memory */
932 	if (!error)  {
933 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, bcount,
934 			(isread)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
935 	}
936 
937 	/* We are done, unload buffer from DMA map */
938 	bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_xfer);
939 
940     out:
941 	mca_disk_unbusy();
942 
943 	return (error);
944 }
945