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