xref: /freebsd/sys/dev/mlx/mlx.c (revision 4cf49a43559ed9fdad601bdcccd2c55963008675)
1 /*-
2  * Copyright (c) 1999 Michael Smith
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$FreeBSD$
27  */
28 
29 /*
30  * Driver for the Mylex DAC960 family of RAID controllers.
31  */
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/kernel.h>
37 
38 #include <sys/buf.h>
39 #include <sys/bus.h>
40 #include <sys/conf.h>
41 #include <sys/devicestat.h>
42 #include <sys/disk.h>
43 
44 #include <machine/resource.h>
45 #include <machine/bus.h>
46 #include <machine/clock.h>
47 #include <sys/rman.h>
48 
49 #include <dev/mlx/mlxio.h>
50 #include <dev/mlx/mlxvar.h>
51 #include <dev/mlx/mlxreg.h>
52 
53 #if 0
54 #define debug(fmt, args...)	printf("%s: " fmt "\n", __FUNCTION__ , ##args)
55 #else
56 #define debug(fmt, args...)
57 #endif
58 
59 #define MLX_CDEV_MAJOR	130
60 
61 static struct cdevsw mlx_cdevsw = {
62 		/* open */	mlx_open,
63 		/* close */	mlx_close,
64 		/* read */	noread,
65 		/* write */	nowrite,
66 		/* ioctl */	mlx_ioctl,
67 		/* poll */	nopoll,
68 		/* mmap */	nommap,
69 		/* strategy */	nostrategy,
70 		/* name */ 	"mlx",
71 		/* maj */	MLX_CDEV_MAJOR,
72 		/* dump */	nodump,
73 		/* psize */ 	nopsize,
74 		/* flags */	0,
75 		/* bmaj */	-1
76 };
77 
78 static int	cdev_registered = 0;
79 devclass_t	mlx_devclass;
80 
81 /*
82  * Per-interface accessor methods
83  */
84 static int			mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
85 static int			mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
86 static void			mlx_v3_intaction(struct mlx_softc *sc, int action);
87 
88 static int			mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
89 static int			mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
90 static void			mlx_v4_intaction(struct mlx_softc *sc, int action);
91 
92 /*
93  * Status monitoring
94  */
95 static void			mlx_periodic(void *data);
96 static void			mlx_periodic_enquiry(struct mlx_command *mc);
97 static void			mlx_periodic_eventlog_poll(struct mlx_softc *sc);
98 static void			mlx_periodic_eventlog_respond(struct mlx_command *mc);
99 static void			mlx_periodic_rebuild(struct mlx_command *mc);
100 
101 /*
102  * Channel Pause
103  */
104 static void			mlx_pause_action(struct mlx_softc *sc);
105 static void			mlx_pause_done(struct mlx_command *mc);
106 
107 /*
108  * Command submission.
109  */
110 static void			*mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize,
111 					     void (*complete)(struct mlx_command *mc));
112 static int			mlx_flush(struct mlx_softc *sc);
113 static int			mlx_rebuild(struct mlx_softc *sc, int channel, int target);
114 static int			mlx_wait_command(struct mlx_command *mc);
115 static int			mlx_poll_command(struct mlx_command *mc);
116 static void			mlx_startio(struct mlx_softc *sc);
117 static void			mlx_completeio(struct mlx_command *mc);
118 static int			mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu);
119 
120 /*
121  * Command buffer allocation.
122  */
123 static struct mlx_command	*mlx_alloccmd(struct mlx_softc *sc);
124 static void			mlx_releasecmd(struct mlx_command *mc);
125 static void			mlx_freecmd(struct mlx_command *mc);
126 
127 /*
128  * Command management.
129  */
130 static int			mlx_getslot(struct mlx_command *mc);
131 static void			mlx_mapcmd(struct mlx_command *mc);
132 static void			mlx_unmapcmd(struct mlx_command *mc);
133 static int			mlx_start(struct mlx_command *mc);
134 static int			mlx_done(struct mlx_softc *sc);
135 static void			mlx_complete(struct mlx_softc *sc);
136 
137 /*
138  * Debugging.
139  */
140 static char			*mlx_diagnose_command(struct mlx_command *mc);
141 static char			*mlx_name_controller(u_int32_t hwid);
142 
143 
144 /*
145  * Utility functions.
146  */
147 static struct mlx_sysdrive	*mlx_findunit(struct mlx_softc *sc, int unit);
148 
149 /********************************************************************************
150  ********************************************************************************
151                                                                 Public Interfaces
152  ********************************************************************************
153  ********************************************************************************/
154 
155 /********************************************************************************
156  * Free all of the resources associated with (sc)
157  *
158  * Should not be called if the controller is active.
159  */
160 void
161 mlx_free(struct mlx_softc *sc)
162 {
163     struct mlx_command	*mc;
164 
165     debug("called");
166 
167     /* cancel status timeout */
168     untimeout(mlx_periodic, sc, sc->mlx_timeout);
169 
170     /* throw away any command buffers */
171     while ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) {
172 	TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
173 	mlx_freecmd(mc);
174     }
175 
176     /* destroy data-transfer DMA tag */
177     if (sc->mlx_buffer_dmat)
178 	bus_dma_tag_destroy(sc->mlx_buffer_dmat);
179 
180     /* free and destroy DMA memory and tag for s/g lists */
181     if (sc->mlx_sgtable)
182 	bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
183     if (sc->mlx_sg_dmat)
184 	bus_dma_tag_destroy(sc->mlx_sg_dmat);
185 
186     /* disconnect the interrupt handler */
187     if (sc->mlx_intr)
188 	bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr);
189     if (sc->mlx_irq != NULL)
190 	bus_release_resource(sc->mlx_dev, SYS_RES_IRQ, 0, sc->mlx_irq);
191 
192     /* destroy the parent DMA tag */
193     if (sc->mlx_parent_dmat)
194 	bus_dma_tag_destroy(sc->mlx_parent_dmat);
195 
196     /* release the register window mapping */
197     if (sc->mlx_mem != NULL)
198 	bus_release_resource(sc->mlx_dev, SYS_RES_MEMORY,
199 			     (sc->mlx_iftype == MLX_IFTYPE_3) ? MLX_CFG_BASE1 : MLX_CFG_BASE0, sc->mlx_mem);
200 }
201 
202 /********************************************************************************
203  * Map the scatter/gather table into bus space
204  */
205 static void
206 mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
207 {
208     struct mlx_softc	*sc = (struct mlx_softc *)arg;
209 
210     debug("called");
211 
212     /* save base of s/g table's address in bus space */
213     sc->mlx_sgbusaddr = segs->ds_addr;
214 }
215 
216 static int
217 mlx_sglist_map(struct mlx_softc *sc)
218 {
219     size_t	segsize;
220     int		error;
221 
222     debug("called");
223 
224     /* destroy any existing mappings */
225     if (sc->mlx_sgtable)
226 	bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
227     if (sc->mlx_sg_dmat)
228 	bus_dma_tag_destroy(sc->mlx_sg_dmat);
229 
230     /*
231      * Create a single tag describing a region large enough to hold all of
232      * the s/g lists we will need.
233      */
234     segsize = sizeof(struct mlx_sgentry) * MLX_NSEG * sc->mlx_maxiop;
235     error = bus_dma_tag_create(sc->mlx_parent_dmat, 	/* parent */
236 			       1, 0, 			/* alignment, boundary */
237 			       BUS_SPACE_MAXADDR,	/* lowaddr */
238 			       BUS_SPACE_MAXADDR, 	/* highaddr */
239 			       NULL, NULL, 		/* filter, filterarg */
240 			       segsize, 1,		/* maxsize, nsegments */
241 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
242 			       0,			/* flags */
243 			       &sc->mlx_sg_dmat);
244     if (error != 0) {
245 	device_printf(sc->mlx_dev, "can't allocate scatter/gather DMA tag\n");
246 	return(ENOMEM);
247     }
248 
249     /*
250      * Allocate enough s/g maps for all commands and permanently map them into
251      * controller-visible space.
252      *
253      * XXX this assumes we can get enough space for all the s/g maps in one
254      * contiguous slab.  We may need to switch to a more complex arrangement where
255      * we allocate in smaller chunks and keep a lookup table from slot to bus address.
256      */
257     error = bus_dmamem_alloc(sc->mlx_sg_dmat, (void **)&sc->mlx_sgtable, BUS_DMA_NOWAIT, &sc->mlx_sg_dmamap);
258     if (error) {
259 	device_printf(sc->mlx_dev, "can't allocate s/g table\n");
260 	return(ENOMEM);
261     }
262     bus_dmamap_load(sc->mlx_sg_dmat, sc->mlx_sg_dmamap, sc->mlx_sgtable, segsize, mlx_dma_map_sg, sc, 0);
263     return(0);
264 }
265 
266 /********************************************************************************
267  * Initialise the controller and softc
268  */
269 int
270 mlx_attach(struct mlx_softc *sc)
271 {
272     struct mlx_enquiry	*me;
273     struct mlx_enquiry2	*me2;
274     int			rid, error;
275 
276     debug("called");
277 
278     /*
279      * Initialise per-controller queues.
280      */
281     TAILQ_INIT(&sc->mlx_donecmd);
282     TAILQ_INIT(&sc->mlx_freecmds);
283     bufq_init(&sc->mlx_bufq);
284 
285     /*
286      * Select accessor methods based on controller interface type.
287      */
288     switch(sc->mlx_iftype) {
289     case MLX_IFTYPE_3:
290 	sc->mlx_tryqueue	= mlx_v3_tryqueue;
291 	sc->mlx_findcomplete	= mlx_v3_findcomplete;
292 	sc->mlx_intaction	= mlx_v3_intaction;
293 	break;
294     case MLX_IFTYPE_4:
295 	sc->mlx_tryqueue	= mlx_v4_tryqueue;
296 	sc->mlx_findcomplete	= mlx_v4_findcomplete;
297 	sc->mlx_intaction	= mlx_v4_intaction;
298 	break;
299     default:
300 	device_printf(sc->mlx_dev, "attaching unsupported interface version %d\n", sc->mlx_iftype);
301 	return(ENXIO);		/* should never happen */
302     }
303 
304     /* disable interrupts before we start talking to the controller */
305     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
306 
307     /*
308      * Allocate and connect our interrupt.
309      */
310     rid = 0;
311     sc->mlx_irq = bus_alloc_resource(sc->mlx_dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
312     if (sc->mlx_irq == NULL) {
313 	device_printf(sc->mlx_dev, "couldn't allocate interrupt\n");
314 	mlx_free(sc);
315 	return(ENXIO);
316     }
317     error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO,  mlx_intr, sc, &sc->mlx_intr);
318     if (error) {
319 	device_printf(sc->mlx_dev, "couldn't set up interrupt\n");
320 	mlx_free(sc);
321 	return(ENXIO);
322     }
323 
324     /*
325      * Create DMA tag for mapping buffers into controller-addressable space.
326      */
327     error = bus_dma_tag_create(sc->mlx_parent_dmat, 	/* parent */
328 			       1, 0, 			/* alignment, boundary */
329 			       BUS_SPACE_MAXADDR,	/* lowaddr */
330 			       BUS_SPACE_MAXADDR, 	/* highaddr */
331 			       NULL, NULL, 		/* filter, filterarg */
332 			       MAXBSIZE, MLX_NSEG,	/* maxsize, nsegments */
333 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
334 			       0,			/* flags */
335 			       &sc->mlx_buffer_dmat);
336     if (error != 0) {
337 	device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n");
338 	return(ENOMEM);
339     }
340 
341     /*
342      * Create an initial set of s/g mappings.
343      */
344     sc->mlx_maxiop = 2;
345     error = mlx_sglist_map(sc);
346     if (error != 0) {
347 	device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n");
348 	return(error);
349     }
350 
351     /*
352      * Probe the controller for more information.
353      */
354     /* send an ENQUIRY to the controller */
355     if ((me = mlx_enquire(sc, MLX_CMD_ENQUIRY, sizeof(*me), NULL)) == NULL) {
356 	device_printf(sc->mlx_dev, "ENQUIRY failed\n");
357 	return(ENXIO);
358     }
359 
360     /* pull information out of the ENQUIRY result */
361     sc->mlx_fwminor = me->me_fwminor;
362     sc->mlx_fwmajor = me->me_fwmajor;
363     sc->mlx_maxiop = me->me_max_commands;
364     sc->mlx_lastevent = sc->mlx_currevent = me->me_event_log_seq_num;
365     free(me, M_DEVBUF);
366 
367     /* send an ENQUIRY2 to the controller */
368     if ((me2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(*me2), NULL)) == NULL) {
369 	device_printf(sc->mlx_dev, "ENQUIRY2 failed\n");
370 	return(ENXIO);
371     }
372 
373     /* pull information out of the ENQUIRY2 result */
374     sc->mlx_nchan = me2->me_configured_channels;
375     sc->mlx_maxiosize = me2->me_maxblk;
376     sc->mlx_maxtarg = me2->me_max_targets;
377     sc->mlx_maxtags = me2->me_max_tags;
378     sc->mlx_scsicap = me2->me_scsi_cap;
379     sc->mlx_hwid = me2->me_hardware_id;
380 
381     /* print a little information about the controller and ourselves */
382     device_printf(sc->mlx_dev, "Mylex %s, firmware %d.%d, %dMB RAM\n",
383 	   mlx_name_controller(sc->mlx_hwid), sc->mlx_fwmajor, sc->mlx_fwminor,
384 	me2->me_mem_size / (1024 * 1024));
385     free(me2, M_DEVBUF);
386 
387     /*
388      * Do quirk/feature related things.
389      */
390     switch(sc->mlx_iftype) {
391     case MLX_IFTYPE_3:
392 	/* XXX certify 3.52? */
393 	if (sc->mlx_fwminor != 51) {
394 	    device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is NOT SUPPORTED\n");
395 	    device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 only\n");
396 	}
397 	break;
398     case MLX_IFTYPE_4:
399 	/* XXX certify firmware versions? */
400 	if (sc->mlx_fwminor != 6) {
401 	    device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is NOT SUPPORTED\n");
402 	    device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.6 only\n");
403 	}
404 	break;
405     default:
406 	device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype);
407 	return(ENXIO);		/* should never happen */
408     }
409 
410     /*
411      * Create the final set of s/g mappings now that we know how many commands
412      * the controller actually supports.
413      */
414     error = mlx_sglist_map(sc);
415     if (error != 0) {
416 	device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n");
417 	return(error);
418     }
419 
420     /*
421      * No rebuild or check is in progress.
422      */
423     sc->mlx_rebuild = -1;
424     sc->mlx_check = -1;
425 
426     /*
427      * Register the control device on first attach.
428      */
429     if (cdev_registered++ == 0)
430 	cdevsw_add(&mlx_cdevsw);
431 
432     /*
433      * Start the timeout routine.
434      */
435     sc->mlx_timeout = timeout(mlx_periodic, sc, hz);
436 
437     return(0);
438 }
439 
440 /********************************************************************************
441  * Locate disk resources and attach children to them.
442  */
443 void
444 mlx_startup(struct mlx_softc *sc)
445 {
446     struct mlx_enq_sys_drive	*mes;
447     struct mlx_sysdrive		*dr;
448     int				i, error;
449 
450     debug("called");
451 
452     /*
453      * Scan all the system drives and attach children for those that
454      * don't currently have them.
455      */
456     mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL);
457     if (mes == NULL) {
458 	device_printf(sc->mlx_dev, "error fetching drive status");
459 	return;
460     }
461 
462     /* iterate over drives returned */
463     for (i = 0, dr = &sc->mlx_sysdrive[0];
464 	 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
465 	 i++, dr++) {
466 	/* are we already attached to this drive? */
467     	if (dr->ms_disk == 0) {
468 	    /* pick up drive information */
469 	    dr->ms_size = mes[i].sd_size;
470 	    dr->ms_raidlevel = mes[i].sd_raidlevel & 0xf;
471 	    dr->ms_state = mes[i].sd_state;
472 
473 	    /* generate geometry information */
474 	    if (sc->mlx_geom == MLX_GEOM_128_32) {
475 		dr->ms_heads = 128;
476 		dr->ms_sectors = 32;
477 		dr->ms_cylinders = dr->ms_size / (128 * 32);
478 	    } else {        /* MLX_GEOM_255/63 */
479 		dr->ms_heads = 255;
480 		dr->ms_sectors = 63;
481 		dr->ms_cylinders = dr->ms_size / (255 * 63);
482 	    }
483 	    dr->ms_disk =  device_add_child(sc->mlx_dev, /*"mlxd"*/NULL, -1, dr);
484 	    if (dr->ms_disk == 0)
485 		device_printf(sc->mlx_dev, "device_add_child failed\n");
486 	}
487     }
488     free(mes, M_DEVBUF);
489     if ((error = bus_generic_attach(sc->mlx_dev)) != 0)
490 	device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error);
491 
492     /* mark controller back up */
493     sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
494 
495     /* enable interrupts */
496     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
497 }
498 
499 /********************************************************************************
500  * Disconnect from the controller completely, in preparation for unload.
501  */
502 int
503 mlx_detach(device_t dev)
504 {
505     struct mlx_softc	*sc = device_get_softc(dev);
506     int			error;
507 
508     debug("called");
509 
510     if (sc->mlx_state & MLX_STATE_OPEN)
511 	return(EBUSY);
512 
513     if ((error = mlx_shutdown(dev)))
514 	return(error);
515 
516     mlx_free(sc);
517 
518     /*
519      * Deregister the control device on last detach.
520      */
521     if (--cdev_registered == 0)
522 	cdevsw_remove(&mlx_cdevsw);
523 
524     return(0);
525 }
526 
527 /********************************************************************************
528  * Bring the controller down to a dormant state and detach all child devices.
529  *
530  * This function is called before detach, system shutdown, or before performing
531  * an operation which may add or delete system disks.  (Call mlx_startup to
532  * resume normal operation.)
533  *
534  * Note that we can assume that the bufq on the controller is empty, as we won't
535  * allow shutdown if any device is open.
536  */
537 int
538 mlx_shutdown(device_t dev)
539 {
540     struct mlx_softc	*sc = device_get_softc(dev);
541     struct mlxd_softc	*mlxd;
542     int			i, s, error;
543 
544     debug("called");
545 
546     s = splbio();
547     error = 0;
548 
549     /* assume we're going to shut down */
550     sc->mlx_state |= MLX_STATE_SHUTDOWN;
551     for (i = 0; i < MLX_MAXDRIVES; i++) {
552 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
553 	    mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk);
554 	    if (mlxd->mlxd_flags & MLXD_OPEN) {		/* drive is mounted, abort shutdown */
555 		sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
556 		device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't shutdown\n");
557 		error = EBUSY;
558 		goto out;
559 	    }
560 	}
561     }
562 
563     /* flush controller */
564     device_printf(sc->mlx_dev, "flushing cache...");
565     if (mlx_flush(sc)) {
566 	printf("failed\n");
567     } else {
568 	printf("done\n");
569     }
570 
571     /* delete all our child devices */
572     for (i = 0; i < MLX_MAXDRIVES; i++) {
573 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
574 	    if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0)
575 		goto out;
576 	    sc->mlx_sysdrive[i].ms_disk = 0;
577 	}
578     }
579 
580     bus_generic_detach(sc->mlx_dev);
581 
582  out:
583     splx(s);
584     return(error);
585 }
586 
587 /********************************************************************************
588  * Bring the controller to a quiescent state, ready for system suspend.
589  */
590 int
591 mlx_suspend(device_t dev)
592 {
593     struct mlx_softc	*sc = device_get_softc(dev);
594     int			s;
595 
596     debug("called");
597 
598     s = splbio();
599     sc->mlx_state |= MLX_STATE_SUSPEND;
600 
601     /* flush controller */
602     device_printf(sc->mlx_dev, "flushing cache...");
603     printf("%s\n", mlx_flush(sc) ? "failed" : "done");
604 
605     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
606     splx(s);
607 
608     return(0);
609 }
610 
611 /********************************************************************************
612  * Bring the controller back to a state ready for operation.
613  */
614 int
615 mlx_resume(device_t dev)
616 {
617     struct mlx_softc	*sc = device_get_softc(dev);
618 
619     debug("called");
620 
621     sc->mlx_state &= ~MLX_STATE_SUSPEND;
622     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
623 
624     return(0);
625 }
626 
627 /*******************************************************************************
628  * Take an interrupt, or be poked by other code to look for interrupt-worthy
629  * status.
630  */
631 void
632 mlx_intr(void *arg)
633 {
634     struct mlx_softc	*sc = (struct mlx_softc *)arg;
635     int			worked;
636 
637     debug("called");
638 
639     /* spin collecting finished commands */
640     worked = 0;
641     while (mlx_done(sc))
642 	worked = 1;
643 
644     /* did we do anything? */
645     if (worked)
646 	mlx_complete(sc);
647 };
648 
649 /*******************************************************************************
650  * Receive a buf structure from a child device and queue it on a particular
651  * disk resource, then poke the disk resource to start as much work as it can.
652  */
653 int
654 mlx_submit_buf(struct mlx_softc *sc, struct buf *bp)
655 {
656     debug("called");
657 
658     bufq_insert_tail(&sc->mlx_bufq, bp);
659     sc->mlx_waitbufs++;
660     mlx_startio(sc);
661     return(0);
662 }
663 
664 /********************************************************************************
665  * Accept an open operation on the control device.
666  */
667 int
668 mlx_open(dev_t dev, int flags, int fmt, struct proc *p)
669 {
670     int			unit = minor(dev);
671     struct mlx_softc	*sc = devclass_get_softc(mlx_devclass, unit);
672 
673     sc->mlx_state |= MLX_STATE_OPEN;
674     return(0);
675 }
676 
677 /********************************************************************************
678  * Accept the last close on the control device.
679  */
680 int
681 mlx_close(dev_t dev, int flags, int fmt, struct proc *p)
682 {
683     int			unit = minor(dev);
684     struct mlx_softc	*sc = devclass_get_softc(mlx_devclass, unit);
685 
686     sc->mlx_state &= ~MLX_STATE_OPEN;
687     return (0);
688 }
689 
690 /********************************************************************************
691  * Handle controller-specific control operations.
692  */
693 int
694 mlx_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
695 {
696     int			unit = minor(dev);
697     struct mlx_softc	*sc = devclass_get_softc(mlx_devclass, unit);
698     int			*arg = (int *)addr;
699     struct mlx_pause	*mp;
700     struct mlx_sysdrive	*dr;
701     struct mlxd_softc	*mlxd;
702     int			i, error;
703 
704     switch(cmd) {
705 	/*
706 	 * Enumerate connected system drives; returns the first system drive's
707 	 * unit number if *arg is -1, or the next unit after *arg if it's
708 	 * a valid unit on this controller.
709 	 */
710     case MLX_NEXT_CHILD:
711 	/* search system drives */
712 	for (i = 0; i < MLX_MAXDRIVES; i++) {
713 	    /* is this one attached? */
714 	    if (sc->mlx_sysdrive[i].ms_disk != 0) {
715 		/* looking for the next one we come across? */
716 		if (*arg == -1) {
717 		    *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk);
718 		    return(0);
719 		}
720 		/* we want the one after this one */
721 		if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
722 		    *arg = -1;
723 	    }
724 	}
725 	return(ENOENT);
726 
727 	/*
728 	 * Scan the controller to see whether new drives have appeared.
729 	 */
730     case MLX_RESCAN_DRIVES:
731 	mlx_startup(sc);
732 	return(0);
733 
734 	/*
735 	 * Disconnect from the specified drive; it may be about to go
736 	 * away.
737 	 */
738     case MLX_DETACH_DRIVE:			/* detach one drive */
739 
740 	if (((dr = mlx_findunit(sc, *arg)) == NULL) ||
741 	    ((mlxd = device_get_softc(dr->ms_disk)) == NULL))
742 	    return(ENOENT);
743 
744 	device_printf(dr->ms_disk, "detaching...");
745 	error = 0;
746 	if (mlxd->mlxd_flags & MLXD_OPEN) {
747 	    error = EBUSY;
748 	    goto detach_out;
749 	}
750 
751 	/* flush controller */
752 	if (mlx_flush(sc)) {
753 	    error = EBUSY;
754 	    goto detach_out;
755 	}
756 
757 	/* nuke drive */
758 	if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0)
759 	    goto detach_out;
760 	dr->ms_disk = 0;
761 	bus_generic_detach(sc->mlx_dev);
762 
763     detach_out:
764 	if (error) {
765 	    printf("failed\n");
766 	} else {
767 	    printf("done\n");
768 	}
769 	return(error);
770 
771 	/*
772 	 * Pause one or more SCSI channels for a period of time, to assist
773 	 * in the process of hot-swapping devices.
774 	 *
775 	 * Note that at least the 3.51 firmware on the DAC960PL doesn't seem
776 	 * to do this right.
777 	 */
778     case MLX_PAUSE_CHANNEL:			/* schedule a channel pause */
779 	/* Does this command work on this firmware? */
780 	if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS))
781 	    return(EOPNOTSUPP);
782 
783 	mp = (struct mlx_pause *)addr;
784 	if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) {
785 	    /* cancel a pending pause operation */
786 	    sc->mlx_pause.mp_which = 0;
787 	} else {
788 	    /* fix for legal channels */
789 	    mp->mp_which &= ((1 << sc->mlx_nchan) -1);
790 	    /* check time values */
791 	    if ((mp->mp_when < 0) || (mp->mp_when > 3600))
792 		return(EINVAL);
793 	    if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30)))
794 		return(EINVAL);
795 
796 	    /* check for a pause currently running */
797 	    if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0))
798 		return(EBUSY);
799 
800 	    /* looks ok, go with it */
801 	    sc->mlx_pause.mp_which = mp->mp_which;
802 	    sc->mlx_pause.mp_when = time_second + mp->mp_when;
803 	    sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong;
804 	}
805 	return(0);
806 
807 	/*
808 	 * Accept a command passthrough-style.
809 	 */
810     case MLX_COMMAND:
811 	return(mlx_user_command(sc, (struct mlx_usercommand *)addr));
812 
813     default:
814 	return(ENOTTY);
815     }
816 }
817 
818 /********************************************************************************
819  * Handle operations requested by a System Drive connected to this controller.
820  */
821 int
822 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd,
823 		caddr_t addr, int32_t flag, struct proc *p)
824 {
825     struct mlxd_rebuild		*mr = (struct mlxd_rebuild *)addr;
826     struct mlxd_rebuild_status	*mp = (struct mlxd_rebuild_status *)addr;
827     int				*arg = (int *)addr;
828     int				error;
829 
830     switch(cmd) {
831 	/*
832 	 * Return the current status of this drive.
833 	 */
834     case MLXD_STATUS:
835 	*arg = drive->ms_state;
836 	return(0);
837 
838 	/*
839 	 * Start a background rebuild on this drive.
840 	 */
841     case MLXD_REBUILDASYNC:
842 	/* XXX lock? */
843 	if (sc->mlx_rebuild >= 0)
844 	    return(EBUSY);
845 	sc->mlx_rebuild = drive - &sc->mlx_sysdrive[0];
846 
847 	switch (mlx_rebuild(sc, mr->rb_channel, mr->rb_target)) {
848 	case 0:
849 	    drive->ms_state = MLX_SYSD_REBUILD;
850 	    error = 0;
851 	    break;
852 	case 0x10000:
853 	    error = ENOMEM;		/* couldn't set up the command */
854 	    break;
855 	case 0x0002:
856 	case 0x0106:
857 	    error = EBUSY;
858 	    break;
859 	case 0x0004:
860 	    error = EIO;
861 	    break;
862 	case 0x0105:
863 	    error = ERANGE;
864 	    break;
865 	default:
866 	    error = EINVAL;
867 	    break;
868 	}
869 	if (error != 0)
870 	    sc->mlx_rebuild = -1;
871 	return(error);
872 
873 	/*
874 	 * Start a background consistency check on this drive.
875 	 */
876     case MLXD_CHECKASYNC:		/* start a background consistency check */
877 	/* XXX implement */
878 	break;
879 
880 	/*
881 	 * Get the status of the current rebuild or consistency check.
882 	 */
883     case MLXD_REBUILDSTAT:
884 
885 	if (sc->mlx_rebuild >= 0) {	/* may be a second or so out of date */
886 	    mp->rs_drive = sc->mlx_rebuild;
887 	    mp->rs_size = sc->mlx_sysdrive[sc->mlx_rebuild].ms_size;
888 	    mp->rs_remaining = sc->mlx_rebuildstat;
889 	    return(0);
890 	} else if (sc->mlx_check >= 0) {
891 	    /* XXX implement */
892 	} else {
893 	    /* XXX should return status of last completed operation? */
894 	    return(EINVAL);
895 	}
896 
897     }
898     return(ENOIOCTL);
899 }
900 
901 
902 /********************************************************************************
903  ********************************************************************************
904                                                                 Status Monitoring
905  ********************************************************************************
906  ********************************************************************************/
907 
908 #define MLX_PERIODIC_ISBUSY(sc)	(sc->mlx_polling <= 0)
909 #define MLX_PERIODIC_BUSY(sc)	atomic_add_int(&sc->mlx_polling, 1);
910 #define MLX_PERIODIC_UNBUSY(sc) atomic_subtract_int(&sc->mlx_polling, 1);
911 
912 /********************************************************************************
913  * Fire off commands to periodically check the status of connected drives.
914  */
915 static void
916 mlx_periodic(void *data)
917 {
918     struct mlx_softc *sc = (struct mlx_softc *)data;
919 
920     debug("called");
921 
922     /*
923      * Run a bus pause?
924      */
925     if ((sc->mlx_pause.mp_which != 0) &&
926 	(sc->mlx_pause.mp_when > 0) &&
927 	(time_second >= sc->mlx_pause.mp_when)){
928 
929 	mlx_pause_action(sc);		/* pause is running */
930 	sc->mlx_pause.mp_when = 0;
931 	sysbeep(500, hz);
932 
933 	/*
934 	 * Bus pause still running?
935 	 */
936     } else if ((sc->mlx_pause.mp_which != 0) &&
937 	       (sc->mlx_pause.mp_when == 0)) {
938 
939 	/* time to stop bus pause? */
940 	if (time_second >= sc->mlx_pause.mp_howlong) {
941 	    mlx_pause_action(sc);
942 	    sc->mlx_pause.mp_which = 0;	/* pause is complete */
943 	    sysbeep(500, hz);
944 	} else {
945 	    sysbeep((time_second % 5) * 100 + 500, hz/8);
946 	}
947 
948 	/*
949 	 * Run normal periodic activities?
950 	 */
951     } else if (MLX_PERIODIC_ISBUSY(sc)) {
952 
953 	/* time to perform a periodic status poll? XXX tuneable interval? */
954 	if (time_second > (sc->mlx_lastpoll + 10)) {
955 	    sc->mlx_lastpoll = time_second;
956 
957 	    /* for caution's sake */
958 	    if (sc->mlx_polling < 0) {
959 		device_printf(sc->mlx_dev, "mlx_polling < 0\n");
960 		atomic_set_int(&sc->mlx_polling, 0);
961 	    }
962 
963 	    /*
964 	     * Check controller status.
965 	     */
966 	    MLX_PERIODIC_BUSY(sc);
967 	    mlx_enquire(sc, MLX_CMD_ENQUIRY, sizeof(struct mlx_enquiry), mlx_periodic_enquiry);
968 
969 	    /*
970 	     * Check system drive status.
971 	     *
972 	     * XXX This might be better left to event-driven detection, eg. I/O to an offline
973 	     *     drive will detect it's offline, rebuilds etc. should detect the drive is back
974 	     *     online.
975 	     */
976 	    MLX_PERIODIC_BUSY(sc);
977 	    mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES,
978 			mlx_periodic_enquiry);
979 	}
980 
981 	/*
982 	 * Get drive rebuild/check status
983 	 */
984 	if (sc->mlx_rebuild >= 0) {
985 	    MLX_PERIODIC_BUSY(sc);
986 	    mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
987 	}
988     } else {
989 	/*
990 	 * If things are still running from the last poll, complain about it.
991 	 *
992 	 * XXX If this becomes an issue, we should have some way of telling what
993 	 *     has become stuck.
994 	 */
995 	device_printf(sc->mlx_dev, "poll still busy (%d)\n", sc->mlx_polling);
996     }
997 
998     /* XXX check for wedged/timed out commands? */
999 
1000     /* reschedule another poll next second or so */
1001     sc->mlx_timeout = timeout(mlx_periodic, sc, hz);
1002 }
1003 
1004 /********************************************************************************
1005  * Handle the result of an ENQUIRY command instigated by periodic status polling.
1006  */
1007 static void
1008 mlx_periodic_enquiry(struct mlx_command *mc)
1009 {
1010     struct mlx_softc		*sc = mc->mc_sc;
1011 
1012     debug("called");
1013 
1014     /* Command completed OK? */
1015     if (mc->mc_status != 0) {
1016 	device_printf(sc->mlx_dev, "periodic enquiry failed\n");
1017 	goto out;
1018     }
1019 
1020     /* respond to command */
1021     switch(mc->mc_mailbox[0]) {
1022 	/*
1023 	 * Generic controller status update.  We could do more with this than just
1024 	 * checking the event log.
1025 	 */
1026     case MLX_CMD_ENQUIRY:
1027     {
1028 	struct mlx_enquiry		*me = (struct mlx_enquiry *)mc->mc_data;
1029 
1030 	/* New stuff in the event log? */
1031 	if (me->me_event_log_seq_num != sc->mlx_lastevent) {
1032 	    /* record where current events are up to */
1033 	    sc->mlx_currevent = me->me_event_log_seq_num;
1034 	    device_printf(sc->mlx_dev, "event log pointer was %d, now %d\n",
1035 			  sc->mlx_lastevent, sc->mlx_currevent);
1036 
1037 	    /* start poll of event log */
1038 	    mlx_periodic_eventlog_poll(sc);
1039 	}
1040 	break;
1041     }
1042     case MLX_CMD_ENQSYSDRIVE:
1043     {
1044 	struct mlx_enq_sys_drive	*mes = (struct mlx_enq_sys_drive *)mc->mc_data;
1045 	struct mlx_sysdrive		*dr;
1046 	int				i;
1047 
1048 	for (i = 0, dr = &sc->mlx_sysdrive[0];
1049 	     (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
1050 	     i++) {
1051 
1052 	    /* if disk is being rebuilt, we should not check it */
1053 	    if (dr->ms_state == MLX_SYSD_REBUILD) {
1054 		/* has state been changed by controller? */
1055 		if (dr->ms_state != mes[i].sd_state) {
1056 		    switch(mes[i].sd_state) {
1057 		    case MLX_SYSD_OFFLINE:
1058 			device_printf(dr->ms_disk, "drive offline\n");
1059 			break;
1060 		    case MLX_SYSD_ONLINE:
1061 			device_printf(dr->ms_disk, "drive online\n");
1062 			break;
1063 		    case MLX_SYSD_CRITICAL:
1064 			device_printf(dr->ms_disk, "drive critical\n");
1065 			break;
1066 		    }
1067 		    /* save new state */
1068 		    dr->ms_state = mes[i].sd_state;
1069 		}
1070 	    }
1071 	}
1072 	break;
1073     }
1074     default:
1075 	break;
1076     }
1077 
1078  out:
1079     free(mc->mc_data, M_DEVBUF);
1080     mlx_releasecmd(mc);
1081     /* this event is done */
1082     MLX_PERIODIC_UNBUSY(sc);
1083 }
1084 
1085 /********************************************************************************
1086  * Instigate a poll for one event log message on (sc).
1087  * We only poll for one message at a time, to keep our command usage down.
1088  */
1089 static void
1090 mlx_periodic_eventlog_poll(struct mlx_softc *sc)
1091 {
1092     struct mlx_command	*mc;
1093     void		*result = NULL;
1094     int			error;
1095 
1096     debug("called");
1097 
1098     /* presume we are going to create another event */
1099     MLX_PERIODIC_BUSY(sc);
1100 
1101     /* get ourselves a command buffer */
1102     error = 1;
1103     if ((mc = mlx_alloccmd(sc)) == NULL)
1104 	goto out;
1105     /* allocate the response structure */
1106     if ((result = malloc(/*sizeof(struct mlx_eventlog_entry)*/1024, M_DEVBUF, M_NOWAIT)) == NULL)
1107 	goto out;
1108     /* get a command slot */
1109     if (mlx_getslot(mc))
1110 	goto out;
1111 
1112     /* map the command so the controller can see it */
1113     mc->mc_data = result;
1114     mc->mc_length = /*sizeof(struct mlx_eventlog_entry)*/1024;
1115     mlx_mapcmd(mc);
1116 
1117     /* build the command to get one entry */
1118     mlx_make_type3(mc, MLX_CMD_LOGOP, MLX_LOGOP_GET, 1, sc->mlx_lastevent, 0, 0, mc->mc_dataphys, 0);
1119     mc->mc_complete = mlx_periodic_eventlog_respond;
1120     mc->mc_private = mc;
1121 
1122     /* start the command */
1123     if ((error = mlx_start(mc)) != 0)
1124 	goto out;
1125 
1126     error = 0;			/* success */
1127  out:
1128     if (error != 0) {
1129 	if (mc != NULL)
1130 	    mlx_releasecmd(mc);
1131 	if (result != NULL)
1132 	    free(result, M_DEVBUF);
1133 	/* abort this event */
1134 	MLX_PERIODIC_UNBUSY(sc);
1135     }
1136 }
1137 
1138 /********************************************************************************
1139  * Handle the result of polling for a log message, generate diagnostic output.
1140  * If this wasn't the last message waiting for us, we'll go collect another.
1141  */
1142 static char *mlx_sense_messages[] = {
1143     "because write recovery failed",
1144     "because of SCSI bus reset failure",
1145     "because of double check condition",
1146     "because it was removed",
1147     "because of gross error on SCSI chip",
1148     "because of bad tag returned from drive",
1149     "because of timeout on SCSI command",
1150     "because of reset SCSI command issued from system",
1151     "because busy or parity error count exceeded limit",
1152     "because of 'kill drive' command from system",
1153     "because of selection timeout",
1154     "due to SCSI phase sequence error",
1155     "due to unknown status"
1156 };
1157 
1158 static void
1159 mlx_periodic_eventlog_respond(struct mlx_command *mc)
1160 {
1161     struct mlx_softc		*sc = mc->mc_sc;
1162     struct mlx_eventlog_entry	*el = (struct mlx_eventlog_entry *)mc->mc_data;
1163     char			*reason;
1164 
1165     debug("called");
1166 
1167     if (mc->mc_status == 0) {
1168 	sc->mlx_lastevent++;		/* got the message OK */
1169 
1170 	/* handle event log message */
1171 	switch(el->el_type) {
1172 	    /*
1173 	     * This is the only sort of message we understand at the moment.
1174 	     * The tests here are probably incomplete.
1175 	     */
1176 	case MLX_LOGMSG_SENSE:	/* sense data */
1177 	    /* Mylex vendor-specific message indicating a drive was killed? */
1178 	    if ((el->el_sensekey == 9) &&
1179 		(el->el_asc == 0x80)) {
1180 		if (el->el_asq < (sizeof(mlx_sense_messages) / sizeof(mlx_sense_messages[0]))) {
1181 		    reason = mlx_sense_messages[el->el_asq];
1182 		} else {
1183 		    reason = "for unknown reason";
1184 		}
1185 		device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n",
1186 			      el->el_channel, el->el_target, reason);
1187 	    }
1188 	    /* SCSI drive was reset? */
1189 	    if ((el->el_sensekey == 6) && (el->el_asc == 0x29)) {
1190 		device_printf(sc->mlx_dev, "physical drive %d:%d reset\n",
1191 			      el->el_channel, el->el_target);
1192 	    }
1193 	    /* SCSI drive error? */
1194 	    if (!((el->el_sensekey == 0) ||
1195 		  ((el->el_sensekey == 2) &&
1196 		   (el->el_asc == 0x04) &&
1197 		   ((el->el_asq == 0x01) ||
1198 		    (el->el_asq == 0x02))))) {
1199 		device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n",
1200 			      el->el_channel, el->el_target, el->el_sensekey, el->el_asc, el->el_asq);
1201 		device_printf(sc->mlx_dev, "  info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":");
1202 	    }
1203 	    break;
1204 
1205 	default:
1206 	    device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type);
1207 	    break;
1208 	}
1209     } else {
1210 	device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc));
1211     }
1212 
1213     /* dispose of command and data */
1214     free(mc->mc_data, M_DEVBUF);
1215     mlx_releasecmd(mc);
1216 
1217     /* is there another message to obtain? */
1218     if (sc->mlx_lastevent != sc->mlx_currevent)
1219 	mlx_periodic_eventlog_poll(sc);
1220 
1221     /* this event is done */
1222     MLX_PERIODIC_UNBUSY(sc);
1223 }
1224 
1225 /********************************************************************************
1226  * Handle the completion of a rebuild operation.
1227  */
1228 static void
1229 mlx_periodic_rebuild(struct mlx_command *mc)
1230 {
1231     struct mlx_softc		*sc = mc->mc_sc;
1232     struct mlx_rebuild_stat	*mr = (struct mlx_rebuild_stat *)mc->mc_private;
1233 
1234     switch(mc->mc_status) {
1235     case 0:				/* all OK, rebuild still running */
1236 	sc->mlx_rebuildstat = mr->rb_remaining;
1237 	break;
1238 
1239     case 0x0105:			/* rebuild/check finished */
1240 	if (sc->mlx_rebuild >= 0) {
1241 	    device_printf(sc->mlx_sysdrive[sc->mlx_rebuild].ms_disk, "rebuild completed\n");
1242 	    sc->mlx_rebuild = -1;
1243 	} else if (sc->mlx_check >= 0) {
1244 	    device_printf(sc->mlx_sysdrive[sc->mlx_check].ms_disk, "consistency check completed\n");
1245 	    sc->mlx_check = -1;
1246 	} else {
1247 	    device_printf(sc->mlx_dev, "consistency check completed\n");
1248 	}
1249 	break;
1250     }
1251     free(mc->mc_data, M_DEVBUF);
1252     mlx_releasecmd(mc);
1253     /* this event is done */
1254     MLX_PERIODIC_UNBUSY(sc);
1255 }
1256 
1257 /********************************************************************************
1258  ********************************************************************************
1259                                                                     Channel Pause
1260  ********************************************************************************
1261  ********************************************************************************/
1262 
1263 /********************************************************************************
1264  * It's time to perform a channel pause action for (sc), either start or stop
1265  * the pause.
1266  */
1267 static void
1268 mlx_pause_action(struct mlx_softc *sc)
1269 {
1270     struct mlx_command	*mc;
1271     int			failsafe, i, command;
1272 
1273     /* What are we doing here? */
1274     if (sc->mlx_pause.mp_when == 0) {
1275 	command = MLX_CMD_STARTCHANNEL;
1276 	failsafe = 0;
1277 
1278     } else {
1279 	command = MLX_CMD_STOPCHANNEL;
1280 
1281 	/*
1282 	 * Channels will always start again after the failsafe period,
1283 	 * which is specified in multiples of 30 seconds.
1284 	 * This constrains us to a maximum pause of 450 seconds.
1285 	 */
1286 	failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30;
1287 	if (failsafe > 0xf) {
1288 	    failsafe = 0xf;
1289 	    sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5;
1290 	}
1291     }
1292 
1293     /* build commands for every channel requested */
1294     for (i = 0; i < sc->mlx_nchan; i++) {
1295 	if ((1 << i) & sc->mlx_pause.mp_which) {
1296 
1297 	    /* get ourselves a command buffer */
1298 	    if ((mc = mlx_alloccmd(sc)) == NULL)
1299 		goto fail;
1300 	    /* get a command slot */
1301 	    mc->mc_flags |= MLX_CMD_PRIORITY;
1302 	    if (mlx_getslot(mc))
1303 		goto fail;
1304 
1305 	    /* build the command */
1306 	    mlx_make_type2(mc, command, (failsafe << 4) | i, 0, 0, 0, 0, 0, 0, 0);
1307 	    mc->mc_complete = mlx_pause_done;
1308 	    mc->mc_private = sc;		/* XXX not needed */
1309 	    if (mlx_start(mc))
1310 		goto fail;
1311 	    /* command submitted OK */
1312 	    return;
1313 
1314 	fail:
1315 	    device_printf(sc->mlx_dev, "%s failed for channel %d\n",
1316 			  command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", i);
1317 	    if (mc != NULL)
1318 		mlx_releasecmd(mc);
1319 	}
1320     }
1321 }
1322 
1323 static void
1324 mlx_pause_done(struct mlx_command *mc)
1325 {
1326     struct mlx_softc	*sc = mc->mc_sc;
1327     int			command = mc->mc_mailbox[0];
1328     int			channel = mc->mc_mailbox[2] & 0xf;
1329 
1330     if (mc->mc_status != 0) {
1331 	device_printf(sc->mlx_dev, "%s command failed - %s\n",
1332 		      command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", mlx_diagnose_command(mc));
1333     } else if (command == MLX_CMD_STOPCHANNEL) {
1334 	device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n",
1335 		      channel, sc->mlx_pause.mp_howlong - time_second);
1336     } else {
1337 	device_printf(sc->mlx_dev, "channel %d resuming\n", channel);
1338     }
1339     mlx_releasecmd(mc);
1340 }
1341 
1342 /********************************************************************************
1343  ********************************************************************************
1344                                                                Command Submission
1345  ********************************************************************************
1346  ********************************************************************************/
1347 
1348 /********************************************************************************
1349  * Perform an Enquiry command using a type-3 command buffer and a return a single
1350  * linear result buffer.  If the completion function is specified, it will
1351  * be called with the completed command (and the result response will not be
1352  * valid until that point).  Otherwise, the command will either be busy-waited
1353  * for (interrupts not enabled), or slept for.
1354  */
1355 static void *
1356 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc))
1357 {
1358     struct mlx_command	*mc;
1359     void		*result;
1360     int			error;
1361 
1362     debug("called");
1363 
1364     /* get ourselves a command buffer */
1365     error = 1;
1366     result = NULL;
1367     if ((mc = mlx_alloccmd(sc)) == NULL)
1368 	goto out;
1369     /* allocate the response structure */
1370     if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
1371 	goto out;
1372     /* get a command slot */
1373     mc->mc_flags |= MLX_CMD_PRIORITY | MLX_CMD_DATAOUT;
1374     if (mlx_getslot(mc))
1375 	goto out;
1376 
1377     /* map the command so the controller can see it */
1378     mc->mc_data = result;
1379     mc->mc_length = bufsize;
1380     mlx_mapcmd(mc);
1381 
1382     /* build an enquiry command */
1383     mlx_make_type2(mc, command, 0, 0, 0, 0, 0, 0, mc->mc_dataphys, 0);
1384 
1385     /* do we want a completion callback? */
1386     if (complete != NULL) {
1387 	mc->mc_complete = complete;
1388 	mc->mc_private = mc;
1389 	if ((error = mlx_start(mc)) != 0)
1390 	    goto out;
1391     } else {
1392 	/* run the command in either polled or wait mode */
1393 	if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc))
1394 	    goto out;
1395 
1396 	/* command completed OK? */
1397 	if (mc->mc_status != 0) {
1398 	    device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n", mlx_diagnose_command(mc));
1399 	    goto out;
1400 	}
1401     }
1402     error = 0;			/* success */
1403  out:
1404     /* we got a command, but nobody else will free it */
1405     if ((complete == NULL) && (mc != NULL))
1406 	mlx_releasecmd(mc);
1407     /* we got an error, and we allocated a result */
1408     if ((error != 0) && (result != NULL)) {
1409 	free(result, M_DEVBUF);
1410 	result = NULL;
1411     }
1412     return(result);
1413 }
1414 
1415 
1416 /********************************************************************************
1417  * Perform a Flush command on the nominated controller.
1418  *
1419  * May be called with interrupts enabled or disabled; will not return until
1420  * the flush operation completes or fails.
1421  */
1422 static int
1423 mlx_flush(struct mlx_softc *sc)
1424 {
1425     struct mlx_command	*mc;
1426     int			error;
1427 
1428     debug("called");
1429 
1430     /* get ourselves a command buffer */
1431     error = 1;
1432     if ((mc = mlx_alloccmd(sc)) == NULL)
1433 	goto out;
1434     /* get a command slot */
1435     if (mlx_getslot(mc))
1436 	goto out;
1437 
1438     /* build a flush command */
1439     mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0);
1440 
1441     /* run the command in either polled or wait mode */
1442     if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc))
1443 	goto out;
1444 
1445     /* command completed OK? */
1446     if (mc->mc_status != 0) {
1447 	device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc));
1448 	goto out;
1449     }
1450 
1451     error = 0;			/* success */
1452  out:
1453     if (mc != NULL)
1454 	mlx_releasecmd(mc);
1455     return(error);
1456 }
1457 
1458 /********************************************************************************
1459  * Start a background rebuild on the nominated controller/channel/target.
1460  *
1461  * May be called with interrupts enabled or disabled; will return as soon as the
1462  * operation has started or been refused.
1463  */
1464 static int
1465 mlx_rebuild(struct mlx_softc *sc, int channel, int target)
1466 {
1467     struct mlx_command	*mc;
1468     int			error;
1469 
1470     debug("called");
1471 
1472     /* get ourselves a command buffer */
1473     error = 0x10000;
1474     if ((mc = mlx_alloccmd(sc)) == NULL)
1475 	goto out;
1476     /* get a command slot */
1477     if (mlx_getslot(mc))
1478 	goto out;
1479 
1480     /* build a rebuild command */
1481     mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0, 0, 0);
1482 
1483     /* run the command in either polled or wait mode */
1484     if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc))
1485 	goto out;
1486 
1487     /* command completed OK? */
1488     if (mc->mc_status != 0) {
1489 	device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc));
1490     } else {
1491 	device_printf(sc->mlx_sysdrive[sc->mlx_rebuild].ms_disk, "rebuild started");
1492     }
1493     error = mc->mc_status;
1494 
1495  out:
1496     if (mc != NULL)
1497 	mlx_releasecmd(mc);
1498     return(error);
1499 }
1500 
1501 /********************************************************************************
1502  * Run the command (mc) and return when it completes.
1503  *
1504  * Interrupts need to be enabled; returns nonzero on error.
1505  */
1506 static int
1507 mlx_wait_command(struct mlx_command *mc)
1508 {
1509     struct mlx_softc	*sc = mc->mc_sc;
1510     int			error, count;
1511 
1512     debug("called");
1513 
1514     mc->mc_complete = NULL;
1515     mc->mc_private = mc;		/* wake us when you're done */
1516     if ((error = mlx_start(mc)) != 0)
1517 	return(error);
1518 
1519     count = 0;
1520     /* XXX better timeout? */
1521     while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 30)) {
1522 	tsleep(mc->mc_private, PRIBIO | PCATCH, "mlxwcmd", hz);
1523     }
1524 
1525     if (mc->mc_status != 0) {
1526 	device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status);
1527 	return(EIO);
1528     }
1529     return(0);
1530 }
1531 
1532 
1533 /********************************************************************************
1534  * Start the command (mc) and busy-wait for it to complete.
1535  *
1536  * Should only be used when interrupts are not available. Returns 0 on
1537  * success, nonzero on error.
1538  * Successfully completed commands are dequeued.
1539  */
1540 static int
1541 mlx_poll_command(struct mlx_command *mc)
1542 {
1543     struct mlx_softc	*sc = mc->mc_sc;
1544     int			error, count, s;
1545 
1546     debug("called");
1547 
1548     mc->mc_complete = NULL;
1549     mc->mc_private = NULL;	/* we will poll for it */
1550     if ((error = mlx_start(mc)) != 0)
1551 	return(error);
1552 
1553     count = 0;
1554     do {
1555 	/* poll for completion */
1556 	mlx_done(mc->mc_sc);
1557     } while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 10000));
1558     if (mc->mc_status != MLX_STATUS_BUSY) {
1559 	s = splbio();
1560 	TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
1561 	splx(s);
1562 	return(0);
1563     }
1564     device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status);
1565     return(EIO);
1566 }
1567 
1568 /********************************************************************************
1569  * Pull as much work off the softc's work queue as possible and give it to the
1570  * controller.  Leave a couple of slots free for emergencies.
1571  *
1572  * Must be called at splbio or in an equivalent fashion that prevents
1573  * reentry or activity on the bufq..
1574  */
1575 static void
1576 mlx_startio(struct mlx_softc *sc)
1577 {
1578     struct mlx_command	*mc;
1579     struct mlxd_softc	*mlxd;
1580     struct buf		*bp;
1581     int			blkcount;
1582     int			driveno;
1583     int			cmd;
1584 
1585     /* spin until something prevents us from doing any work */
1586     for (;;) {
1587 
1588 	/* see if there's work to be done */
1589 	if ((bp = bufq_first(&sc->mlx_bufq)) == NULL)
1590 	    break;
1591 	/* get a command */
1592 	if ((mc = mlx_alloccmd(sc)) == NULL)
1593 	    break;
1594 	/* get a slot for the command */
1595 	if (mlx_getslot(mc) != 0) {
1596 	    mlx_releasecmd(mc);
1597 	    break;
1598 	}
1599 	/* get the buf containing our work */
1600 	bufq_remove(&sc->mlx_bufq, bp);
1601 	sc->mlx_waitbufs--;
1602 
1603 	/* connect the buf to the command */
1604 	mc->mc_complete = mlx_completeio;
1605 	mc->mc_private = bp;
1606 	mc->mc_data = bp->b_data;
1607 	mc->mc_length = bp->b_bcount;
1608 	if (bp->b_flags & B_READ) {
1609 	    mc->mc_flags |= MLX_CMD_DATAIN;
1610 	    cmd = MLX_CMD_READOLDSG;
1611 	} else {
1612 	    mc->mc_flags |= MLX_CMD_DATAOUT;
1613 	    cmd = MLX_CMD_WRITEOLDSG;
1614 	}
1615 
1616 	/* map the command so the controller can work with it */
1617 	mlx_mapcmd(mc);
1618 
1619 	/* build a suitable I/O command (assumes 512-byte rounded transfers) */
1620 	mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1;
1621 	driveno = mlxd->mlxd_drive - &sc->mlx_sysdrive[0];
1622 	blkcount = bp->b_bcount / MLX_BLKSIZE;
1623 
1624 	if ((bp->b_blkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1625 	    device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n",
1626 			  bp->b_blkno, blkcount, sc->mlx_sysdrive[driveno].ms_size);
1627 
1628 	/*
1629 	 * Build the I/O command.  Note that the SG list type bits are set to zero,
1630 	 * denoting the format of SG list that we are using.
1631 	 */
1632 	mlx_make_type5(mc, cmd,
1633 		       blkcount & 0xff, 				/* xfer length low byte */
1634 		       (driveno << 3) | ((blkcount >> 8) & 0x07),	/* target and length high 3 bits */
1635 		       bp->b_blkno,					/* physical block number */
1636 		       mc->mc_sgphys,					/* location of SG list */
1637 		       mc->mc_nsgent & 0x3f);				/* size of SG list (top 2 bits clear) */
1638 
1639 
1640 	/* try to give command to controller */
1641 	if (mlx_start(mc) != 0) {
1642 	    /* fail the command */
1643 	    mc->mc_status = MLX_STATUS_WEDGED;
1644 	    mlx_completeio(mc);
1645 	}
1646     }
1647 }
1648 
1649 /********************************************************************************
1650  * Handle completion of an I/O command.
1651  */
1652 static void
1653 mlx_completeio(struct mlx_command *mc)
1654 {
1655     struct mlx_softc	*sc = mc->mc_sc;
1656     struct buf		*bp = (struct buf *)mc->mc_private;
1657     struct mlxd_softc	*mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1;
1658 
1659     if (mc->mc_status != MLX_STATUS_OK) {	/* could be more verbose here? */
1660 	bp->b_error = EIO;
1661 	bp->b_flags |= B_ERROR;
1662 
1663 	switch(mc->mc_status) {
1664 	case MLX_STATUS_RDWROFFLINE:		/* system drive has gone offline */
1665 	    device_printf(mlxd->mlxd_dev, "drive offline\n");
1666 	    /* should signal this with a return code */
1667 	    mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1668 	    break;
1669 
1670 	default:				/* other I/O error */
1671 	    device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1672 #if 0
1673 	    device_printf(sc->mlx_dev, "  b_bcount %ld  blkcount %ld  b_blkno %d\n",
1674 			  bp->b_bcount, bp->b_bcount / MLX_BLKSIZE, bp->b_blkno);
1675 	    device_printf(sc->mlx_dev, "  %13D\n", mc->mc_mailbox, " ");
1676 #endif
1677 	    break;
1678 	}
1679     }
1680     mlx_releasecmd(mc);
1681     mlxd_intr(bp);
1682 }
1683 
1684 /********************************************************************************
1685  * Take a command from user-space and try to run it.
1686  */
1687 static int
1688 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu)
1689 {
1690     struct mlx_command	*mc;
1691     void		*kbuf;
1692     int			error;
1693 
1694     kbuf = NULL;
1695     mc = NULL;
1696     error = ENOMEM;
1697     /* get a kernel buffer for the transfer */
1698     if (mu->mu_datasize > 0) {
1699 	if ((kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL)
1700 	    goto out;
1701 	if ((mu->mu_bufptr < 0) || (mu->mu_bufptr > (sizeof(mu->mu_command) < sizeof(u_int32_t)))) {
1702 	    error = EINVAL;
1703 	    goto out;
1704 	}
1705     }
1706     /* get ourselves a command buffer */
1707     if ((mc = mlx_alloccmd(sc)) == NULL)
1708 	goto out;
1709 
1710     /* copy the command and data */
1711     bcopy(mu->mu_command, mc->mc_mailbox, sizeof(mc->mc_mailbox));
1712     if ((mu->mu_datasize > 0) && ((error = copyin(mu->mu_buf, kbuf, mu->mu_datasize))))
1713 	goto out;
1714 
1715     /* get a command slot */
1716     if (mlx_getslot(mc))
1717 	goto out;
1718 
1719     /* map the command so the controller can see it */
1720     mc->mc_data = kbuf;
1721     mc->mc_length = mu->mu_datasize;
1722     mlx_mapcmd(mc);
1723 
1724     /* if there's a data buffer, fix up the command */
1725     if (mu->mu_datasize > 0) {
1726 	mc->mc_mailbox[mu->mu_bufptr    ] =  mc->mc_length        & 0xff;
1727 	mc->mc_mailbox[mu->mu_bufptr + 1] = (mc->mc_length >> 8)  & 0xff;
1728 	mc->mc_mailbox[mu->mu_bufptr + 2] = (mc->mc_length >> 16) & 0xff;
1729 	mc->mc_mailbox[mu->mu_bufptr + 3] = (mc->mc_length >> 24) & 0xff;
1730     }
1731 
1732     /* submit the command and wait */
1733     if ((error = mlx_wait_command(mc)) != 0)
1734 	goto out;
1735 
1736     /* copy out status and data */
1737     mu->mu_status = mc->mc_status;
1738     if ((mu->mu_datasize > 0) && ((error = copyout(kbuf, mu->mu_buf, mu->mu_datasize))))
1739 	goto out;
1740     error = 0;
1741 
1742  out:
1743     mlx_releasecmd(mc);
1744     if (kbuf != NULL)
1745 	free(kbuf, M_DEVBUF);
1746     return(error);
1747 }
1748 
1749 /********************************************************************************
1750  ********************************************************************************
1751                                                         Command I/O to Controller
1752  ********************************************************************************
1753  ********************************************************************************/
1754 
1755 /********************************************************************************
1756  * Find a free command slot for (mc).
1757  *
1758  * Don't hand out a slot to a normal-priority command unless there are at least
1759  * 4 slots free for priority commands.
1760  */
1761 static int
1762 mlx_getslot(struct mlx_command *mc)
1763 {
1764     struct mlx_softc	*sc = mc->mc_sc;
1765     int			s, slot, limit;
1766 
1767     debug("called  mc %p  sc %p", mc, sc);
1768 
1769     /* enforce slot-usage limit */
1770     limit = (mc->mc_flags & MLX_CMD_PRIORITY) ? sc->mlx_maxiop : sc->mlx_maxiop - 4;
1771     if (sc->mlx_busycmds > limit)
1772 	return(EBUSY);
1773 
1774     /*
1775      * Allocate an outstanding command slot
1776      *
1777      * XXX linear search is slow
1778      */
1779     s = splbio();
1780     for (slot = 0; slot < sc->mlx_maxiop; slot++) {
1781 	debug("try slot %d", slot);
1782 	if (sc->mlx_busycmd[slot] == NULL)
1783 	    break;
1784     }
1785     if (slot < sc->mlx_maxiop) {
1786 	sc->mlx_busycmd[slot] = mc;
1787 	sc->mlx_busycmds++;
1788     }
1789     splx(s);
1790 
1791     /* out of slots? */
1792     if (slot >= sc->mlx_maxiop)
1793 	return(EBUSY);
1794 
1795     debug("got slot %d", slot);
1796     mc->mc_slot = slot;
1797     return(0);
1798 }
1799 
1800 /********************************************************************************
1801  * Map/unmap (mc)'s data in the controller's addressable space.
1802  */
1803 static void
1804 mlx_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1805 {
1806     struct mlx_command	*mc = (struct mlx_command *)arg;
1807     struct mlx_softc	*sc = mc->mc_sc;
1808     struct mlx_sgentry	*sg;
1809     int			i;
1810 
1811     debug("called");
1812 
1813     /* get base address of s/g table */
1814     sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG);
1815 
1816     /* save s/g table information in command */
1817     mc->mc_nsgent = nsegments;
1818     mc->mc_sgphys = sc->mlx_sgbusaddr + (mc->mc_slot * MLX_NSEG * sizeof(struct mlx_sgentry));
1819     mc->mc_dataphys = segs[0].ds_addr;
1820 
1821     /* populate s/g table */
1822     for (i = 0; i < nsegments; i++, sg++) {
1823 	sg->sg_addr = segs[i].ds_addr;
1824 	sg->sg_count = segs[i].ds_len;
1825     }
1826 }
1827 
1828 static void
1829 mlx_mapcmd(struct mlx_command *mc)
1830 {
1831     struct mlx_softc	*sc = mc->mc_sc;
1832 
1833     debug("called");
1834 
1835     /* if the command involves data at all */
1836     if (mc->mc_data != NULL) {
1837 
1838 	/* map the data buffer into bus space and build the s/g list */
1839 	bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, mc->mc_length,
1840 			mlx_setup_dmamap, mc, 0);
1841 	if (mc->mc_flags & MLX_CMD_DATAIN)
1842 	    bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_PREREAD);
1843 	if (mc->mc_flags & MLX_CMD_DATAOUT)
1844 	    bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_PREWRITE);
1845     }
1846 }
1847 
1848 static void
1849 mlx_unmapcmd(struct mlx_command *mc)
1850 {
1851     struct mlx_softc	*sc = mc->mc_sc;
1852 
1853     debug("called");
1854 
1855     /* if the command involved data at all */
1856     if (mc->mc_data != NULL) {
1857 
1858 	if (mc->mc_flags & MLX_CMD_DATAIN)
1859 	    bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD);
1860 	if (mc->mc_flags & MLX_CMD_DATAOUT)
1861 	    bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE);
1862 
1863 	bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap);
1864     }
1865 }
1866 
1867 /********************************************************************************
1868  * Try to deliver (mc) to the controller.  Take care of any completed commands
1869  * that we encounter while doing so.
1870  *
1871  * Can be called at any interrupt level, with or without interrupts enabled.
1872  */
1873 static int
1874 mlx_start(struct mlx_command *mc)
1875 {
1876     struct mlx_softc	*sc = mc->mc_sc;
1877     int			i, s, done, worked;
1878 
1879     debug("called");
1880 
1881     /* save the slot number as ident so we can handle this command when complete */
1882     mc->mc_mailbox[0x1] = mc->mc_slot;
1883 
1884     /* set impossible status so that a woken sleeper can tell the command is in progress */
1885     mc->mc_status = MLX_STATUS_BUSY;
1886 
1887     /* assume we don't collect any completed commands */
1888     worked = 0;
1889 
1890     /* spin waiting for the mailbox */
1891     for (i = 100000, done = 0; (i > 0) && !done; i--) {
1892 	s = splbio();
1893 	done = sc->mlx_tryqueue(sc, mc);
1894 	splx(s);
1895 	/* check for command completion while we're at it */
1896 	if (mlx_done(sc))
1897 	    worked = 1;
1898     }
1899     /* check to see if we picked up any completed commands */
1900     if (worked)
1901 	mlx_complete(sc);
1902 
1903     /* command is enqueued */
1904     if (done)
1905 	return(0);
1906 
1907     /*
1908      * We couldn't get the controller to take the command.  Revoke the slot
1909      * that the command was given and return it with a bad status.
1910      */
1911     sc->mlx_busycmd[mc->mc_slot] = NULL;
1912     device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n");
1913     mc->mc_status = MLX_STATUS_WEDGED;
1914     return(EIO);
1915 }
1916 
1917 /********************************************************************************
1918  * Look at the controller (sc) and see if a command has been completed.
1919  * If so, move the command buffer to the done queue for later collection
1920  * and free the slot for immediate reuse.
1921  *
1922  * Returns nonzero if anything was added to the done queue.
1923  */
1924 static int
1925 mlx_done(struct mlx_softc *sc)
1926 {
1927     struct mlx_command	*mc;
1928     int			s;
1929     u_int8_t		slot;
1930     u_int16_t		status;
1931 
1932     debug("called");
1933 
1934     s = splbio();
1935     mc = NULL;
1936     slot = 0;
1937 
1938     /* poll for a completed command's identifier and status */
1939     if (sc->mlx_findcomplete(sc, &slot, &status)) {
1940 	mc = sc->mlx_busycmd[slot];		/* find command */
1941 	if (mc != NULL) {			/* paranoia */
1942 	    if (mc->mc_status == MLX_STATUS_BUSY) {
1943 		mc->mc_status = status;			/* save status */
1944 
1945 		/* move completed command to 'done' queue */
1946 		TAILQ_INSERT_TAIL(&sc->mlx_donecmd, mc, mc_link);
1947 
1948 		/* free slot for reuse */
1949 		sc->mlx_busycmd[slot] = NULL;
1950 		sc->mlx_busycmds--;
1951 	    } else {
1952 		device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
1953 		mc = NULL;
1954 	    }
1955 	} else {
1956 	    device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot);
1957 	}
1958     }
1959     splx(s);
1960 
1961     if (mc != NULL) {
1962 	/* unmap the command's data buffer */
1963 	mlx_unmapcmd(mc);
1964 	return(1);
1965     }
1966     return(0);
1967 }
1968 
1969 /********************************************************************************
1970  * Handle completion for all commands on (sc)'s done queue.
1971  */
1972 static void
1973 mlx_complete(struct mlx_softc *sc)
1974 {
1975     struct mlx_command	*mc, *nc;
1976     int			s, count;
1977 
1978     debug("called");
1979 
1980     s = splbio();
1981     count = 0;
1982 
1983     /* scan the list of done commands */
1984     mc = TAILQ_FIRST(&sc->mlx_donecmd);
1985     while (mc != NULL) {
1986 	nc = TAILQ_NEXT(mc, mc_link);
1987 
1988 	/* XXX this is slightly bogus */
1989 	if (count++ > (sc->mlx_maxiop * 2))
1990 	    panic("mlx_donecmd list corrupt!");
1991 
1992 	/*
1993 	 * Does the command have a completion handler?
1994 	 */
1995 	if (mc->mc_complete != NULL) {
1996 	    /* remove from list and give to handler */
1997 	    TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
1998 	    mc->mc_complete(mc);
1999 
2000 	    /*
2001 	     * Is there a sleeper waiting on this command?
2002 	     */
2003 	} else if (mc->mc_private != NULL) {	/* sleeping caller wants to know about it */
2004 
2005 	    /* remove from list and wake up sleeper */
2006 	    TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
2007 	    wakeup_one(mc->mc_private);
2008 
2009 	    /*
2010 	     * Leave the command for a caller that's polling for it.
2011 	     */
2012 	} else {
2013 	}
2014 	mc = nc;
2015     }
2016     splx(s);
2017 
2018     /* queue some more work if there is any */
2019     mlx_startio(sc);
2020 }
2021 
2022 /********************************************************************************
2023  ********************************************************************************
2024                                                         Command Buffer Management
2025  ********************************************************************************
2026  ********************************************************************************/
2027 
2028 /********************************************************************************
2029  * Get a new command buffer.
2030  *
2031  * This may return NULL in low-memory cases.
2032  *
2033  * Note that using malloc() is expensive (the command buffer is << 1 page) but
2034  * necessary if we are to be a loadable module before the zone allocator is fixed.
2035  *
2036  * If possible, we recycle a command buffer that's been used before.
2037  *
2038  * XXX Note that command buffers are not cleaned out - it is the caller's
2039  *     responsibility to ensure that all required fields are filled in before
2040  *     using a buffer.
2041  */
2042 static struct mlx_command *
2043 mlx_alloccmd(struct mlx_softc *sc)
2044 {
2045     struct mlx_command	*mc;
2046     int			error;
2047     int			s;
2048 
2049     debug("called");
2050 
2051     s = splbio();
2052     if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL)
2053 	TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
2054     splx(s);
2055 
2056     /* allocate a new command buffer? */
2057     if (mc == NULL) {
2058 	mc = (struct mlx_command *)malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT);
2059 	if (mc != NULL) {
2060 	    bzero(mc, sizeof(*mc));
2061 	    mc->mc_sc = sc;
2062 	    error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap);
2063 	    if (error) {
2064 		free(mc, M_DEVBUF);
2065 		return(NULL);
2066 	    }
2067 	}
2068     }
2069     return(mc);
2070 }
2071 
2072 /********************************************************************************
2073  * Release a command buffer for recycling.
2074  *
2075  * XXX It might be a good idea to limit the number of commands we save for reuse
2076  *     if it's shown that this list bloats out massively.
2077  */
2078 static void
2079 mlx_releasecmd(struct mlx_command *mc)
2080 {
2081     int		s;
2082 
2083     debug("called");
2084 
2085     s = splbio();
2086     TAILQ_INSERT_HEAD(&mc->mc_sc->mlx_freecmds, mc, mc_link);
2087     splx(s);
2088 }
2089 
2090 /********************************************************************************
2091  * Permanently discard a command buffer.
2092  */
2093 static void
2094 mlx_freecmd(struct mlx_command *mc)
2095 {
2096     struct mlx_softc	*sc = mc->mc_sc;
2097 
2098     debug("called");
2099 
2100     bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap);
2101     free(mc, M_DEVBUF);
2102 }
2103 
2104 
2105 /********************************************************************************
2106  ********************************************************************************
2107                                                 Type 3 interface accessor methods
2108  ********************************************************************************
2109  ********************************************************************************/
2110 
2111 /********************************************************************************
2112  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2113  * (the controller is not ready to take a command).
2114  *
2115  * Must be called at splbio or in a fashion that prevents reentry.
2116  */
2117 static int
2118 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2119 {
2120     int		i;
2121 
2122     debug("called");
2123 
2124     /* ready for our command? */
2125     if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) {
2126 	/* copy mailbox data to window */
2127 	for (i = 0; i < 13; i++)
2128 	    MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2129 
2130 	/* post command */
2131 	MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL);
2132 	return(1);
2133     }
2134     return(0);
2135 }
2136 
2137 /********************************************************************************
2138  * See if a command has been completed, if so acknowledge its completion
2139  * and recover the slot number and status code.
2140  *
2141  * Must be called at splbio or in a fashion that prevents reentry.
2142  */
2143 static int
2144 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2145 {
2146 
2147     debug("called");
2148 
2149     /* status available? */
2150     if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) {
2151 	*slot = MLX_V3_GET_STATUS_IDENT(sc);		/* get command identifier */
2152 	*status = MLX_V3_GET_STATUS(sc);		/* get status */
2153 
2154 	/* acknowledge completion */
2155 	MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL);
2156 	MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2157 	return(1);
2158     }
2159     return(0);
2160 }
2161 
2162 /********************************************************************************
2163  * Enable/disable interrupts as requested. (No acknowledge required)
2164  *
2165  * Must be called at splbio or in a fashion that prevents reentry.
2166  */
2167 static void
2168 mlx_v3_intaction(struct mlx_softc *sc, int action)
2169 {
2170     debug("called");
2171 
2172     switch(action) {
2173     case MLX_INTACTION_DISABLE:
2174 	MLX_V3_PUT_IER(sc, 0);
2175 	sc->mlx_state &= ~MLX_STATE_INTEN;
2176 	break;
2177     case MLX_INTACTION_ENABLE:
2178 	MLX_V3_PUT_IER(sc, 1);
2179 	sc->mlx_state |= MLX_STATE_INTEN;
2180 	break;
2181     }
2182 }
2183 
2184 
2185 /********************************************************************************
2186  ********************************************************************************
2187                                                 Type 4 interface accessor methods
2188  ********************************************************************************
2189  ********************************************************************************/
2190 
2191 /********************************************************************************
2192  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2193  * (the controller is not ready to take a command).
2194  *
2195  * Must be called at splbio or in a fashion that prevents reentry.
2196  */
2197 static int
2198 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2199 {
2200     int		i;
2201 
2202     debug("called");
2203 
2204     /* ready for our command? */
2205     if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) {
2206 	/* copy mailbox data to window */
2207 	for (i = 0; i < 13; i++)
2208 	    MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2209 
2210 	/* post command */
2211 	MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD);
2212 	return(1);
2213     }
2214     return(0);
2215 }
2216 
2217 /********************************************************************************
2218  * See if a command has been completed, if so acknowledge its completion
2219  * and recover the slot number and status code.
2220  *
2221  * Must be called at splbio or in a fashion that prevents reentry.
2222  */
2223 static int
2224 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2225 {
2226 
2227     debug("called");
2228 
2229     /* status available? */
2230     if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) {
2231 	*slot = MLX_V4_GET_STATUS_IDENT(sc);		/* get command identifier */
2232 	*status = MLX_V4_GET_STATUS(sc);		/* get status */
2233 
2234 	/* acknowledge completion */
2235 	MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK);
2236 	MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2237 	return(1);
2238     }
2239     return(0);
2240 }
2241 
2242 /********************************************************************************
2243  * Enable/disable interrupts as requested.
2244  *
2245  * Must be called at splbio or in a fashion that prevents reentry.
2246  */
2247 static void
2248 mlx_v4_intaction(struct mlx_softc *sc, int action)
2249 {
2250     debug("called");
2251 
2252     switch(action) {
2253     case MLX_INTACTION_DISABLE:
2254 	MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT);
2255 	sc->mlx_state &= ~MLX_STATE_INTEN;
2256 	break;
2257     case MLX_INTACTION_ENABLE:
2258 	MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT);
2259 	sc->mlx_state |= MLX_STATE_INTEN;
2260 	break;
2261     }
2262 }
2263 
2264 
2265 /********************************************************************************
2266  ********************************************************************************
2267                                                                         Debugging
2268  ********************************************************************************
2269  ********************************************************************************/
2270 
2271 /********************************************************************************
2272  * Return a status message describing (mc)
2273  */
2274 static char *mlx_status_messages[] = {
2275     "normal completion",			/* 00 */
2276     "irrecoverable data error",			/* 01 */
2277     "drive does not exist, or is offline",	/* 02 */
2278     "attempt to write beyond end of drive",	/* 03 */
2279     "bad data encountered",			/* 04 */
2280     "invalid log entry request",		/* 05 */
2281     "attempt to rebuild online drive",		/* 06 */
2282     "new disk failed during rebuild",		/* 07 */
2283     "invalid channel/target",			/* 08 */
2284     "rebuild/check already in progress",	/* 09 */
2285     "one or more disks are dead",		/* 10 */
2286     "invalid or non-redundant drive",		/* 11 */
2287     "channel is busy",				/* 12 */
2288     "channel is not stopped",			/* 13 */
2289 };
2290 
2291 static struct
2292 {
2293     int		command;
2294     u_int16_t	status;
2295     int		msg;
2296 } mlx_messages[] = {
2297     {MLX_CMD_READOLDSG,		0x0001,	 1},
2298     {MLX_CMD_READOLDSG,		0x0002,	 1},
2299     {MLX_CMD_READOLDSG,		0x0105,	 3},
2300     {MLX_CMD_READOLDSG,		0x010c,	 4},
2301     {MLX_CMD_WRITEOLDSG,	0x0001,	 1},
2302     {MLX_CMD_WRITEOLDSG,	0x0002,	 1},
2303     {MLX_CMD_WRITEOLDSG,	0x0105,	 3},
2304     {MLX_CMD_LOGOP,		0x0105,	 5},
2305     {MLX_CMD_REBUILDASYNC,	0x0002,  6},
2306     {MLX_CMD_REBUILDASYNC,	0x0004,  7},
2307     {MLX_CMD_REBUILDASYNC,	0x0105,  8},
2308     {MLX_CMD_REBUILDASYNC,	0x0106,  9},
2309     {MLX_CMD_CHECKASYNC,	0x0002, 10},
2310     {MLX_CMD_CHECKASYNC,	0x0105, 11},
2311     {MLX_CMD_CHECKASYNC,	0x0106,  9},
2312     {MLX_CMD_STOPCHANNEL,	0x0106, 12},
2313     {MLX_CMD_STOPCHANNEL,	0x0105,  8},
2314     {MLX_CMD_STARTCHANNEL,	0x0005, 13},
2315     {MLX_CMD_STARTCHANNEL,	0x0105,  8},
2316     {-1, 0, 0}
2317 };
2318 
2319 static char *
2320 mlx_diagnose_command(struct mlx_command *mc)
2321 {
2322     static char	unkmsg[80];
2323     int		i;
2324 
2325     /* look up message in table */
2326     for (i = 0; mlx_messages[i].command != -1; i++)
2327 	if ((mc->mc_mailbox[0] == mlx_messages[i].command) &&
2328 	    (mc->mc_status == mlx_messages[i].status))
2329 	    return(mlx_status_messages[mlx_messages[i].msg]);
2330 
2331     sprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]);
2332     return(unkmsg);
2333 }
2334 
2335 /*******************************************************************************
2336  * Return a string describing the controller (hwid)
2337  */
2338 static char *
2339 mlx_name_controller(u_int32_t hwid)
2340 {
2341     static char		buf[80];
2342     char		smbuf[16];
2343     char		*submodel;
2344     int			nchn;
2345 
2346     switch(hwid & 0xff) {
2347     case 0x01:
2348 	submodel = "P/PD";
2349 	break;
2350     case 0x02:
2351 	submodel = "PL";
2352 	break;
2353     case 0x10:
2354 	submodel = "PG";
2355 	break;
2356     case 0x11:
2357 	submodel = "PJ";
2358 	break;
2359     default:
2360 	sprintf(smbuf, " model 0x%x", hwid & 0xff);
2361 	submodel = smbuf;
2362 	break;
2363     }
2364     nchn = (hwid >> 8) & 0xff;
2365     sprintf(buf, "DAC960%s, %d channel%s", submodel, nchn, nchn > 1 ? "s" : "");
2366     return(buf);
2367 }
2368 
2369 /********************************************************************************
2370  ********************************************************************************
2371                                                                 Utility Functions
2372  ********************************************************************************
2373  ********************************************************************************/
2374 
2375 /********************************************************************************
2376  * Find the disk whose unit number is (unit) on this controller
2377  */
2378 static struct mlx_sysdrive *
2379 mlx_findunit(struct mlx_softc *sc, int unit)
2380 {
2381     int		i;
2382 
2383     /* search system drives */
2384     for (i = 0; i < MLX_MAXDRIVES; i++) {
2385 	/* is this one attached? */
2386 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
2387 	    /* is this the one? */
2388 	    if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
2389 		return(&sc->mlx_sysdrive[i]);
2390 	}
2391     }
2392     return(NULL);
2393 }
2394