xref: /freebsd/sys/dev/mlx/mlx.c (revision 195ebc7e9e4b129de810833791a19dfb4349d6a9)
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/bus.h>
39 #include <sys/conf.h>
40 #include <sys/stat.h>
41 
42 #include <machine/resource.h>
43 #include <machine/bus.h>
44 #include <machine/clock.h>
45 #include <sys/rman.h>
46 
47 #include <geom/geom_disk.h>
48 
49 #include <dev/mlx/mlx_compat.h>
50 #include <dev/mlx/mlxio.h>
51 #include <dev/mlx/mlxvar.h>
52 #include <dev/mlx/mlxreg.h>
53 
54 static struct cdevsw mlx_cdevsw = {
55 	.d_version =	D_VERSION,
56 	.d_flags =	D_NEEDGIANT,
57 	.d_open =	mlx_open,
58 	.d_close =	mlx_close,
59 	.d_ioctl =	mlx_ioctl,
60 	.d_name =	"mlx",
61 };
62 
63 devclass_t	mlx_devclass;
64 
65 /*
66  * Per-interface accessor methods
67  */
68 static int			mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
69 static int			mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
70 static void			mlx_v3_intaction(struct mlx_softc *sc, int action);
71 static int			mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
72 
73 static int			mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
74 static int			mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
75 static void			mlx_v4_intaction(struct mlx_softc *sc, int action);
76 static int			mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
77 
78 static int			mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
79 static int			mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
80 static void			mlx_v5_intaction(struct mlx_softc *sc, int action);
81 static int			mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
82 
83 /*
84  * Status monitoring
85  */
86 static void			mlx_periodic(void *data);
87 static void			mlx_periodic_enquiry(struct mlx_command *mc);
88 static void			mlx_periodic_eventlog_poll(struct mlx_softc *sc);
89 static void			mlx_periodic_eventlog_respond(struct mlx_command *mc);
90 static void			mlx_periodic_rebuild(struct mlx_command *mc);
91 
92 /*
93  * Channel Pause
94  */
95 static void			mlx_pause_action(struct mlx_softc *sc);
96 static void			mlx_pause_done(struct mlx_command *mc);
97 
98 /*
99  * Command submission.
100  */
101 static void			*mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize,
102 					     void (*complete)(struct mlx_command *mc));
103 static int			mlx_flush(struct mlx_softc *sc);
104 static int			mlx_check(struct mlx_softc *sc, int drive);
105 static int			mlx_rebuild(struct mlx_softc *sc, int channel, int target);
106 static int			mlx_wait_command(struct mlx_command *mc);
107 static int			mlx_poll_command(struct mlx_command *mc);
108 void				mlx_startio_cb(void *arg,
109 					       bus_dma_segment_t *segs,
110 					       int nsegments, int error);
111 static void			mlx_startio(struct mlx_softc *sc);
112 static void			mlx_completeio(struct mlx_command *mc);
113 static int			mlx_user_command(struct mlx_softc *sc,
114 						 struct mlx_usercommand *mu);
115 void				mlx_user_cb(void *arg, bus_dma_segment_t *segs,
116 					    int nsegments, int error);
117 
118 /*
119  * Command buffer allocation.
120  */
121 static struct mlx_command	*mlx_alloccmd(struct mlx_softc *sc);
122 static void			mlx_releasecmd(struct mlx_command *mc);
123 static void			mlx_freecmd(struct mlx_command *mc);
124 
125 /*
126  * Command management.
127  */
128 static int			mlx_getslot(struct mlx_command *mc);
129 static void			mlx_setup_dmamap(struct mlx_command *mc,
130 						 bus_dma_segment_t *segs,
131 						 int nsegments, int error);
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 void			mlx_describe_controller(struct mlx_softc *sc);
142 static int			mlx_fw_message(struct mlx_softc *sc, int status, int param1, int param2);
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(1);
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, sc->mlx_mem_type, sc->mlx_mem_rid, sc->mlx_mem);
199 
200     /* free controller enquiry data */
201     if (sc->mlx_enq2 != NULL)
202 	free(sc->mlx_enq2, M_DEVBUF);
203 
204     /* destroy control device */
205     if (sc->mlx_dev_t != (struct cdev *)NULL)
206 	destroy_dev(sc->mlx_dev_t);
207 }
208 
209 /********************************************************************************
210  * Map the scatter/gather table into bus space
211  */
212 static void
213 mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
214 {
215     struct mlx_softc	*sc = (struct mlx_softc *)arg;
216 
217     debug_called(1);
218 
219     /* save base of s/g table's address in bus space */
220     sc->mlx_sgbusaddr = segs->ds_addr;
221 }
222 
223 static int
224 mlx_sglist_map(struct mlx_softc *sc)
225 {
226     size_t	segsize;
227     int		error, ncmd;
228 
229     debug_called(1);
230 
231     /* destroy any existing mappings */
232     if (sc->mlx_sgtable)
233 	bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
234     if (sc->mlx_sg_dmat)
235 	bus_dma_tag_destroy(sc->mlx_sg_dmat);
236 
237     /*
238      * Create a single tag describing a region large enough to hold all of
239      * the s/g lists we will need.  If we're called early on, we don't know how
240      * many commands we're going to be asked to support, so only allocate enough
241      * for a couple.
242      */
243     if (sc->mlx_enq2 == NULL) {
244 	ncmd = 2;
245     } else {
246 	ncmd = sc->mlx_enq2->me_max_commands;
247     }
248     segsize = sizeof(struct mlx_sgentry) * MLX_NSEG * ncmd;
249     error = bus_dma_tag_create(sc->mlx_parent_dmat, 	/* parent */
250 			       1, 0, 			/* alignment,boundary */
251 			       BUS_SPACE_MAXADDR,	/* lowaddr */
252 			       BUS_SPACE_MAXADDR, 	/* highaddr */
253 			       NULL, NULL, 		/* filter, filterarg */
254 			       segsize, 1,		/* maxsize, nsegments */
255 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
256 			       0,			/* flags */
257 			       NULL, NULL,		/* lockfunc, lockarg */
258 			       &sc->mlx_sg_dmat);
259     if (error != 0) {
260 	device_printf(sc->mlx_dev, "can't allocate scatter/gather DMA tag\n");
261 	return(ENOMEM);
262     }
263 
264     /*
265      * Allocate enough s/g maps for all commands and permanently map them into
266      * controller-visible space.
267      *
268      * XXX this assumes we can get enough space for all the s/g maps in one
269      * contiguous slab.  We may need to switch to a more complex arrangement
270      * where we allocate in smaller chunks and keep a lookup table from slot
271      * to bus address.
272      */
273     error = bus_dmamem_alloc(sc->mlx_sg_dmat, (void **)&sc->mlx_sgtable,
274 			     BUS_DMA_NOWAIT, &sc->mlx_sg_dmamap);
275     if (error) {
276 	device_printf(sc->mlx_dev, "can't allocate s/g table\n");
277 	return(ENOMEM);
278     }
279     (void)bus_dmamap_load(sc->mlx_sg_dmat, sc->mlx_sg_dmamap, sc->mlx_sgtable,
280 			  segsize, mlx_dma_map_sg, sc, 0);
281     return(0);
282 }
283 
284 /********************************************************************************
285  * Initialise the controller and softc
286  */
287 int
288 mlx_attach(struct mlx_softc *sc)
289 {
290     struct mlx_enquiry_old	*meo;
291     int				rid, error, fwminor, hscode, hserror, hsparam1, hsparam2, hsmsg;
292 
293     debug_called(1);
294 
295     /*
296      * Initialise per-controller queues.
297      */
298     TAILQ_INIT(&sc->mlx_work);
299     TAILQ_INIT(&sc->mlx_freecmds);
300     MLX_BIO_QINIT(sc->mlx_bioq);
301 
302     /*
303      * Select accessor methods based on controller interface type.
304      */
305     switch(sc->mlx_iftype) {
306     case MLX_IFTYPE_2:
307     case MLX_IFTYPE_3:
308 	sc->mlx_tryqueue	= mlx_v3_tryqueue;
309 	sc->mlx_findcomplete	= mlx_v3_findcomplete;
310 	sc->mlx_intaction	= mlx_v3_intaction;
311 	sc->mlx_fw_handshake	= mlx_v3_fw_handshake;
312 	break;
313     case MLX_IFTYPE_4:
314 	sc->mlx_tryqueue	= mlx_v4_tryqueue;
315 	sc->mlx_findcomplete	= mlx_v4_findcomplete;
316 	sc->mlx_intaction	= mlx_v4_intaction;
317 	sc->mlx_fw_handshake	= mlx_v4_fw_handshake;
318 	break;
319     case MLX_IFTYPE_5:
320 	sc->mlx_tryqueue	= mlx_v5_tryqueue;
321 	sc->mlx_findcomplete	= mlx_v5_findcomplete;
322 	sc->mlx_intaction	= mlx_v5_intaction;
323 	sc->mlx_fw_handshake	= mlx_v5_fw_handshake;
324 	break;
325     default:
326 	return(ENXIO);		/* should never happen */
327     }
328 
329     /* disable interrupts before we start talking to the controller */
330     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
331 
332     /*
333      * Wait for the controller to come ready, handshake with the firmware if required.
334      * This is typically only necessary on platforms where the controller BIOS does not
335      * run.
336      */
337     hsmsg = 0;
338     DELAY(1000);
339     while ((hscode = sc->mlx_fw_handshake(sc, &hserror, &hsparam1, &hsparam2)) != 0) {
340 	/* report first time around... */
341 	if (hsmsg == 0) {
342 	    device_printf(sc->mlx_dev, "controller initialisation in progress...\n");
343 	    hsmsg = 1;
344 	}
345 	/* did we get a real message? */
346 	if (hscode == 2) {
347 	    hscode = mlx_fw_message(sc, hserror, hsparam1, hsparam2);
348 	    /* fatal initialisation error? */
349 	    if (hscode != 0) {
350 		return(ENXIO);
351 	    }
352 	}
353     }
354     if (hsmsg == 1)
355 	device_printf(sc->mlx_dev, "initialisation complete.\n");
356 
357     /*
358      * Allocate and connect our interrupt.
359      */
360     rid = 0;
361     sc->mlx_irq = bus_alloc_resource_any(sc->mlx_dev, SYS_RES_IRQ, &rid,
362         RF_SHAREABLE | RF_ACTIVE);
363     if (sc->mlx_irq == NULL) {
364 	device_printf(sc->mlx_dev, "can't allocate interrupt\n");
365 	return(ENXIO);
366     }
367     error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO | INTR_ENTROPY, NULL, mlx_intr, sc, &sc->mlx_intr);
368     if (error) {
369 	device_printf(sc->mlx_dev, "can't set up interrupt\n");
370 	return(ENXIO);
371     }
372 
373     /*
374      * Create DMA tag for mapping buffers into controller-addressable space.
375      */
376     error = bus_dma_tag_create(sc->mlx_parent_dmat, 	/* parent */
377 			       1, 0, 			/* align, boundary */
378 			       BUS_SPACE_MAXADDR,	/* lowaddr */
379 			       BUS_SPACE_MAXADDR, 	/* highaddr */
380 			       NULL, NULL, 		/* filter, filterarg */
381 			       MAXBSIZE, MLX_NSEG,	/* maxsize, nsegments */
382 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
383 			       0,			/* flags */
384 			       busdma_lock_mutex,	/* lockfunc */
385 			       &Giant,			/* lockarg */
386 			       &sc->mlx_buffer_dmat);
387     if (error != 0) {
388 	device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n");
389 	return(ENOMEM);
390     }
391 
392     /*
393      * Create some initial scatter/gather mappings so we can run the probe
394      * commands.
395      */
396     error = mlx_sglist_map(sc);
397     if (error != 0) {
398 	device_printf(sc->mlx_dev, "can't make initial s/g list mapping\n");
399 	return(error);
400     }
401 
402     /*
403      * We don't (yet) know where the event log is up to.
404      */
405     sc->mlx_currevent = -1;
406 
407     /*
408      * Obtain controller feature information
409      */
410     if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) {
411 	device_printf(sc->mlx_dev, "ENQUIRY2 failed\n");
412 	return(ENXIO);
413     }
414 
415     /*
416      * Do quirk/feature related things.
417      */
418     fwminor = (sc->mlx_enq2->me_firmware_id >> 8) & 0xff;
419     switch(sc->mlx_iftype) {
420     case MLX_IFTYPE_2:
421 	/* These controllers don't report the firmware version in the ENQUIRY2 response */
422 	if ((meo = mlx_enquire(sc, MLX_CMD_ENQUIRY_OLD, sizeof(struct mlx_enquiry_old), NULL)) == NULL) {
423 	    device_printf(sc->mlx_dev, "ENQUIRY_OLD failed\n");
424 	    return(ENXIO);
425 	}
426 	sc->mlx_enq2->me_firmware_id = ('0' << 24) | (0 << 16) | (meo->me_fwminor << 8) | meo->me_fwmajor;
427 
428 	/* XXX require 2.42 or better (PCI) or 2.14 or better (EISA) */
429 	if (meo->me_fwminor < 42) {
430 	    device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
431 	    device_printf(sc->mlx_dev, " *** WARNING *** Use revision 2.42 or later\n");
432 	}
433 	free(meo, M_DEVBUF);
434 	break;
435     case MLX_IFTYPE_3:
436 	/* XXX certify 3.52? */
437 	if (fwminor < 51) {
438 	    device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
439 	    device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n");
440 	}
441 	break;
442     case MLX_IFTYPE_4:
443 	/* XXX certify firmware versions? */
444 	if (fwminor < 6) {
445 	    device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
446 	    device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n");
447 	}
448 	break;
449     case MLX_IFTYPE_5:
450 	if (fwminor < 7) {
451 	    device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
452 	    device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n");
453 	}
454 	break;
455     default:
456 	return(ENXIO);		/* should never happen */
457     }
458 
459     /*
460      * Create the final scatter/gather mappings now that we have characterised the controller.
461      */
462     error = mlx_sglist_map(sc);
463     if (error != 0) {
464 	device_printf(sc->mlx_dev, "can't make final s/g list mapping\n");
465 	return(error);
466     }
467 
468     /*
469      * No user-requested background operation is in progress.
470      */
471     sc->mlx_background = 0;
472     sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
473 
474     /*
475      * Create the control device.
476      */
477     sc->mlx_dev_t = make_dev(&mlx_cdevsw, 0, UID_ROOT, GID_OPERATOR,
478 			     S_IRUSR | S_IWUSR, "mlx%d", device_get_unit(sc->mlx_dev));
479     sc->mlx_dev_t->si_drv1 = sc;
480 
481     /*
482      * Start the timeout routine.
483      */
484     sc->mlx_timeout = timeout(mlx_periodic, sc, hz);
485 
486     /* print a little information about the controller */
487     mlx_describe_controller(sc);
488 
489     return(0);
490 }
491 
492 /********************************************************************************
493  * Locate disk resources and attach children to them.
494  */
495 void
496 mlx_startup(struct mlx_softc *sc)
497 {
498     struct mlx_enq_sys_drive	*mes;
499     struct mlx_sysdrive		*dr;
500     int				i, error;
501 
502     debug_called(1);
503 
504     /*
505      * Scan all the system drives and attach children for those that
506      * don't currently have them.
507      */
508     mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL);
509     if (mes == NULL) {
510 	device_printf(sc->mlx_dev, "error fetching drive status\n");
511 	return;
512     }
513 
514     /* iterate over drives returned */
515     for (i = 0, dr = &sc->mlx_sysdrive[0];
516 	 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
517 	 i++, dr++) {
518 	/* are we already attached to this drive? */
519     	if (dr->ms_disk == 0) {
520 	    /* pick up drive information */
521 	    dr->ms_size = mes[i].sd_size;
522 	    dr->ms_raidlevel = mes[i].sd_raidlevel & 0xf;
523 	    dr->ms_state = mes[i].sd_state;
524 
525 	    /* generate geometry information */
526 	    if (sc->mlx_geom == MLX_GEOM_128_32) {
527 		dr->ms_heads = 128;
528 		dr->ms_sectors = 32;
529 		dr->ms_cylinders = dr->ms_size / (128 * 32);
530 	    } else {        /* MLX_GEOM_255/63 */
531 		dr->ms_heads = 255;
532 		dr->ms_sectors = 63;
533 		dr->ms_cylinders = dr->ms_size / (255 * 63);
534 	    }
535 	    dr->ms_disk =  device_add_child(sc->mlx_dev, /*"mlxd"*/NULL, -1);
536 	    if (dr->ms_disk == 0)
537 		device_printf(sc->mlx_dev, "device_add_child failed\n");
538 	    device_set_ivars(dr->ms_disk, dr);
539 	}
540     }
541     free(mes, M_DEVBUF);
542     if ((error = bus_generic_attach(sc->mlx_dev)) != 0)
543 	device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error);
544 
545     /* mark controller back up */
546     sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
547 
548     /* enable interrupts */
549     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
550 }
551 
552 /********************************************************************************
553  * Disconnect from the controller completely, in preparation for unload.
554  */
555 int
556 mlx_detach(device_t dev)
557 {
558     struct mlx_softc	*sc = device_get_softc(dev);
559     struct mlxd_softc	*mlxd;
560     int			i, s, error;
561 
562     debug_called(1);
563 
564     error = EBUSY;
565     s = splbio();
566     if (sc->mlx_state & MLX_STATE_OPEN)
567 	goto out;
568 
569     for (i = 0; i < MLX_MAXDRIVES; i++) {
570 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
571 	    mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk);
572 	    if (mlxd->mlxd_flags & MLXD_OPEN) {		/* drive is mounted, abort detach */
573 		device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n");
574 		goto out;
575 	    }
576 	}
577     }
578     if ((error = mlx_shutdown(dev)))
579 	goto out;
580 
581     mlx_free(sc);
582 
583     error = 0;
584  out:
585     splx(s);
586     return(error);
587 }
588 
589 /********************************************************************************
590  * Bring the controller down to a dormant state and detach all child devices.
591  *
592  * This function is called before detach, system shutdown, or before performing
593  * an operation which may add or delete system disks.  (Call mlx_startup to
594  * resume normal operation.)
595  *
596  * Note that we can assume that the bioq on the controller is empty, as we won't
597  * allow shutdown if any device is open.
598  */
599 int
600 mlx_shutdown(device_t dev)
601 {
602     struct mlx_softc	*sc = device_get_softc(dev);
603     int			i, s, error;
604 
605     debug_called(1);
606 
607     s = splbio();
608     error = 0;
609 
610     sc->mlx_state |= MLX_STATE_SHUTDOWN;
611     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
612 
613     /* flush controller */
614     device_printf(sc->mlx_dev, "flushing cache...");
615     if (mlx_flush(sc)) {
616 	printf("failed\n");
617     } else {
618 	printf("done\n");
619     }
620 
621     /* delete all our child devices */
622     for (i = 0; i < MLX_MAXDRIVES; i++) {
623 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
624 	    if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0)
625 		goto out;
626 	    sc->mlx_sysdrive[i].ms_disk = 0;
627 	}
628     }
629 
630  out:
631     splx(s);
632     return(error);
633 }
634 
635 /********************************************************************************
636  * Bring the controller to a quiescent state, ready for system suspend.
637  */
638 int
639 mlx_suspend(device_t dev)
640 {
641     struct mlx_softc	*sc = device_get_softc(dev);
642     int			s;
643 
644     debug_called(1);
645 
646     s = splbio();
647     sc->mlx_state |= MLX_STATE_SUSPEND;
648 
649     /* flush controller */
650     device_printf(sc->mlx_dev, "flushing cache...");
651     printf("%s\n", mlx_flush(sc) ? "failed" : "done");
652 
653     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
654     splx(s);
655 
656     return(0);
657 }
658 
659 /********************************************************************************
660  * Bring the controller back to a state ready for operation.
661  */
662 int
663 mlx_resume(device_t dev)
664 {
665     struct mlx_softc	*sc = device_get_softc(dev);
666 
667     debug_called(1);
668 
669     sc->mlx_state &= ~MLX_STATE_SUSPEND;
670     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
671 
672     return(0);
673 }
674 
675 /*******************************************************************************
676  * Take an interrupt, or be poked by other code to look for interrupt-worthy
677  * status.
678  */
679 void
680 mlx_intr(void *arg)
681 {
682     struct mlx_softc	*sc = (struct mlx_softc *)arg;
683 
684     debug_called(1);
685 
686     /* collect finished commands, queue anything waiting */
687     mlx_done(sc);
688 };
689 
690 /*******************************************************************************
691  * Receive a buf structure from a child device and queue it on a particular
692  * disk resource, then poke the disk resource to start as much work as it can.
693  */
694 int
695 mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp)
696 {
697     int		s;
698 
699     debug_called(1);
700 
701     s = splbio();
702     MLX_BIO_QINSERT(sc->mlx_bioq, bp);
703     sc->mlx_waitbufs++;
704     splx(s);
705     mlx_startio(sc);
706     return(0);
707 }
708 
709 /********************************************************************************
710  * Accept an open operation on the control device.
711  */
712 int
713 mlx_open(struct cdev *dev, int flags, int fmt, struct thread *td)
714 {
715     struct mlx_softc	*sc = dev->si_drv1;
716 
717     sc->mlx_state |= MLX_STATE_OPEN;
718     return(0);
719 }
720 
721 /********************************************************************************
722  * Accept the last close on the control device.
723  */
724 int
725 mlx_close(struct cdev *dev, int flags, int fmt, struct thread *td)
726 {
727     struct mlx_softc	*sc = dev->si_drv1;
728 
729     sc->mlx_state &= ~MLX_STATE_OPEN;
730     return (0);
731 }
732 
733 /********************************************************************************
734  * Handle controller-specific control operations.
735  */
736 int
737 mlx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td)
738 {
739     struct mlx_softc		*sc = dev->si_drv1;
740     struct mlx_rebuild_request	*rb = (struct mlx_rebuild_request *)addr;
741     struct mlx_rebuild_status	*rs = (struct mlx_rebuild_status *)addr;
742     int				*arg = (int *)addr;
743     struct mlx_pause		*mp;
744     struct mlx_sysdrive		*dr;
745     struct mlxd_softc		*mlxd;
746     int				i, error;
747 
748     switch(cmd) {
749 	/*
750 	 * Enumerate connected system drives; returns the first system drive's
751 	 * unit number if *arg is -1, or the next unit after *arg if it's
752 	 * a valid unit on this controller.
753 	 */
754     case MLX_NEXT_CHILD:
755 	/* search system drives */
756 	for (i = 0; i < MLX_MAXDRIVES; i++) {
757 	    /* is this one attached? */
758 	    if (sc->mlx_sysdrive[i].ms_disk != 0) {
759 		/* looking for the next one we come across? */
760 		if (*arg == -1) {
761 		    *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk);
762 		    return(0);
763 		}
764 		/* we want the one after this one */
765 		if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
766 		    *arg = -1;
767 	    }
768 	}
769 	return(ENOENT);
770 
771 	/*
772 	 * Scan the controller to see whether new drives have appeared.
773 	 */
774     case MLX_RESCAN_DRIVES:
775 	mlx_startup(sc);
776 	return(0);
777 
778 	/*
779 	 * Disconnect from the specified drive; it may be about to go
780 	 * away.
781 	 */
782     case MLX_DETACH_DRIVE:			/* detach one drive */
783 
784 	if (((dr = mlx_findunit(sc, *arg)) == NULL) ||
785 	    ((mlxd = device_get_softc(dr->ms_disk)) == NULL))
786 	    return(ENOENT);
787 
788 	device_printf(dr->ms_disk, "detaching...");
789 	error = 0;
790 	if (mlxd->mlxd_flags & MLXD_OPEN) {
791 	    error = EBUSY;
792 	    goto detach_out;
793 	}
794 
795 	/* flush controller */
796 	if (mlx_flush(sc)) {
797 	    error = EBUSY;
798 	    goto detach_out;
799 	}
800 
801 	/* nuke drive */
802 	if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0)
803 	    goto detach_out;
804 	dr->ms_disk = 0;
805 
806     detach_out:
807 	if (error) {
808 	    printf("failed\n");
809 	} else {
810 	    printf("done\n");
811 	}
812 	return(error);
813 
814 	/*
815 	 * Pause one or more SCSI channels for a period of time, to assist
816 	 * in the process of hot-swapping devices.
817 	 *
818 	 * Note that at least the 3.51 firmware on the DAC960PL doesn't seem
819 	 * to do this right.
820 	 */
821     case MLX_PAUSE_CHANNEL:			/* schedule a channel pause */
822 	/* Does this command work on this firmware? */
823 	if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS))
824 	    return(EOPNOTSUPP);
825 
826 	mp = (struct mlx_pause *)addr;
827 	if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) {
828 	    /* cancel a pending pause operation */
829 	    sc->mlx_pause.mp_which = 0;
830 	} else {
831 	    /* fix for legal channels */
832 	    mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1);
833 	    /* check time values */
834 	    if ((mp->mp_when < 0) || (mp->mp_when > 3600))
835 		return(EINVAL);
836 	    if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30)))
837 		return(EINVAL);
838 
839 	    /* check for a pause currently running */
840 	    if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0))
841 		return(EBUSY);
842 
843 	    /* looks ok, go with it */
844 	    sc->mlx_pause.mp_which = mp->mp_which;
845 	    sc->mlx_pause.mp_when = time_second + mp->mp_when;
846 	    sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong;
847 	}
848 	return(0);
849 
850 	/*
851 	 * Accept a command passthrough-style.
852 	 */
853     case MLX_COMMAND:
854 	return(mlx_user_command(sc, (struct mlx_usercommand *)addr));
855 
856 	/*
857 	 * Start a rebuild on a given SCSI disk
858 	 */
859     case MLX_REBUILDASYNC:
860 	if (sc->mlx_background != 0) {
861 	    rb->rr_status = 0x0106;
862 	    return(EBUSY);
863 	}
864 	rb->rr_status = mlx_rebuild(sc, rb->rr_channel, rb->rr_target);
865 	switch (rb->rr_status) {
866 	case 0:
867 	    error = 0;
868 	    break;
869 	case 0x10000:
870 	    error = ENOMEM;		/* couldn't set up the command */
871 	    break;
872 	case 0x0002:
873 	    error = EBUSY;
874 	    break;
875 	case 0x0104:
876 	    error = EIO;
877 	    break;
878 	case 0x0105:
879 	    error = ERANGE;
880 	    break;
881 	case 0x0106:
882 	    error = EBUSY;
883 	    break;
884 	default:
885 	    error = EINVAL;
886 	    break;
887 	}
888 	if (error == 0)
889 	    sc->mlx_background = MLX_BACKGROUND_REBUILD;
890 	return(error);
891 
892 	/*
893 	 * Get the status of the current rebuild or consistency check.
894 	 */
895     case MLX_REBUILDSTAT:
896 	*rs = sc->mlx_rebuildstat;
897 	return(0);
898 
899 	/*
900 	 * Return the per-controller system drive number matching the
901 	 * disk device number in (arg), if it happens to belong to us.
902 	 */
903     case MLX_GET_SYSDRIVE:
904 	error = ENOENT;
905 	mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg);
906 	if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) &&
907 	    (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) {
908 	    error = 0;
909 	    *arg = mlxd->mlxd_drive - sc->mlx_sysdrive;
910 	}
911 	return(error);
912 
913     default:
914 	return(ENOTTY);
915     }
916 }
917 
918 /********************************************************************************
919  * Handle operations requested by a System Drive connected to this controller.
920  */
921 int
922 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd,
923 		caddr_t addr, int32_t flag, struct thread *td)
924 {
925     int				*arg = (int *)addr;
926     int				error, result;
927 
928     switch(cmd) {
929 	/*
930 	 * Return the current status of this drive.
931 	 */
932     case MLXD_STATUS:
933 	*arg = drive->ms_state;
934 	return(0);
935 
936 	/*
937 	 * Start a background consistency check on this drive.
938 	 */
939     case MLXD_CHECKASYNC:		/* start a background consistency check */
940 	if (sc->mlx_background != 0) {
941 	    *arg = 0x0106;
942 	    return(EBUSY);
943 	}
944 	result = mlx_check(sc, drive - &sc->mlx_sysdrive[0]);
945 	switch (result) {
946 	case 0:
947 	    error = 0;
948 	    break;
949 	case 0x10000:
950 	    error = ENOMEM;		/* couldn't set up the command */
951 	    break;
952 	case 0x0002:
953 	    error = EIO;
954 	    break;
955 	case 0x0105:
956 	    error = ERANGE;
957 	    break;
958 	case 0x0106:
959 	    error = EBUSY;
960 	    break;
961 	default:
962 	    error = EINVAL;
963 	    break;
964 	}
965 	if (error == 0)
966 	    sc->mlx_background = MLX_BACKGROUND_CHECK;
967 	*arg = result;
968 	return(error);
969 
970     }
971     return(ENOIOCTL);
972 }
973 
974 
975 /********************************************************************************
976  ********************************************************************************
977                                                                 Status Monitoring
978  ********************************************************************************
979  ********************************************************************************/
980 
981 /********************************************************************************
982  * Fire off commands to periodically check the status of connected drives.
983  */
984 static void
985 mlx_periodic(void *data)
986 {
987     struct mlx_softc *sc = (struct mlx_softc *)data;
988 
989     debug_called(1);
990 
991     /*
992      * Run a bus pause?
993      */
994     if ((sc->mlx_pause.mp_which != 0) &&
995 	(sc->mlx_pause.mp_when > 0) &&
996 	(time_second >= sc->mlx_pause.mp_when)){
997 
998 	mlx_pause_action(sc);		/* pause is running */
999 	sc->mlx_pause.mp_when = 0;
1000 	sysbeep(500, hz);
1001 
1002 	/*
1003 	 * Bus pause still running?
1004 	 */
1005     } else if ((sc->mlx_pause.mp_which != 0) &&
1006 	       (sc->mlx_pause.mp_when == 0)) {
1007 
1008 	/* time to stop bus pause? */
1009 	if (time_second >= sc->mlx_pause.mp_howlong) {
1010 	    mlx_pause_action(sc);
1011 	    sc->mlx_pause.mp_which = 0;	/* pause is complete */
1012 	    sysbeep(500, hz);
1013 	} else {
1014 	    sysbeep((time_second % 5) * 100 + 500, hz/8);
1015 	}
1016 
1017 	/*
1018 	 * Run normal periodic activities?
1019 	 */
1020     } else if (time_second > (sc->mlx_lastpoll + 10)) {
1021 	sc->mlx_lastpoll = time_second;
1022 
1023 	/*
1024 	 * Check controller status.
1025 	 *
1026 	 * XXX Note that this may not actually launch a command in situations of high load.
1027 	 */
1028 	mlx_enquire(sc, (sc->mlx_iftype == MLX_IFTYPE_2) ? MLX_CMD_ENQUIRY_OLD : MLX_CMD_ENQUIRY,
1029 		    imax(sizeof(struct mlx_enquiry), sizeof(struct mlx_enquiry_old)), mlx_periodic_enquiry);
1030 
1031 	/*
1032 	 * Check system drive status.
1033 	 *
1034 	 * XXX This might be better left to event-driven detection, eg. I/O to an offline
1035 	 *     drive will detect it's offline, rebuilds etc. should detect the drive is back
1036 	 *     online.
1037 	 */
1038 	mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES,
1039 			mlx_periodic_enquiry);
1040 
1041     }
1042 
1043     /* get drive rebuild/check status */
1044     /* XXX should check sc->mlx_background if this is only valid while in progress */
1045     mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
1046 
1047     /* deal with possibly-missed interrupts and timed-out commands */
1048     mlx_done(sc);
1049 
1050     /* reschedule another poll next second or so */
1051     sc->mlx_timeout = timeout(mlx_periodic, sc, hz);
1052 }
1053 
1054 /********************************************************************************
1055  * Handle the result of an ENQUIRY command instigated by periodic status polling.
1056  */
1057 static void
1058 mlx_periodic_enquiry(struct mlx_command *mc)
1059 {
1060     struct mlx_softc		*sc = mc->mc_sc;
1061 
1062     debug_called(1);
1063 
1064     /* Command completed OK? */
1065     if (mc->mc_status != 0) {
1066 	device_printf(sc->mlx_dev, "periodic enquiry failed - %s\n", mlx_diagnose_command(mc));
1067 	goto out;
1068     }
1069 
1070     /* respond to command */
1071     switch(mc->mc_mailbox[0]) {
1072 	/*
1073 	 * This is currently a bit fruitless, as we don't know how to extract the eventlog
1074 	 * pointer yet.
1075 	 */
1076     case MLX_CMD_ENQUIRY_OLD:
1077     {
1078 	struct mlx_enquiry		*me = (struct mlx_enquiry *)mc->mc_data;
1079 	struct mlx_enquiry_old		*meo = (struct mlx_enquiry_old *)mc->mc_data;
1080 	int				i;
1081 
1082 	/* convert data in-place to new format */
1083 	for (i = (sizeof(me->me_dead) / sizeof(me->me_dead[0])) - 1; i >= 0; i--) {
1084 	    me->me_dead[i].dd_chan = meo->me_dead[i].dd_chan;
1085 	    me->me_dead[i].dd_targ = meo->me_dead[i].dd_targ;
1086 	}
1087 	me->me_misc_flags        = 0;
1088 	me->me_rebuild_count     = meo->me_rebuild_count;
1089 	me->me_dead_count        = meo->me_dead_count;
1090 	me->me_critical_sd_count = meo->me_critical_sd_count;
1091 	me->me_event_log_seq_num = 0;
1092 	me->me_offline_sd_count  = meo->me_offline_sd_count;
1093 	me->me_max_commands      = meo->me_max_commands;
1094 	me->me_rebuild_flag      = meo->me_rebuild_flag;
1095 	me->me_fwmajor           = meo->me_fwmajor;
1096 	me->me_fwminor           = meo->me_fwminor;
1097 	me->me_status_flags      = meo->me_status_flags;
1098 	me->me_flash_age         = meo->me_flash_age;
1099 	for (i = (sizeof(me->me_drvsize) / sizeof(me->me_drvsize[0])) - 1; i >= 0; i--) {
1100 	    if (i > ((sizeof(meo->me_drvsize) / sizeof(meo->me_drvsize[0])) - 1)) {
1101 		me->me_drvsize[i] = 0;		/* drive beyond supported range */
1102 	    } else {
1103 		me->me_drvsize[i] = meo->me_drvsize[i];
1104 	    }
1105 	}
1106 	me->me_num_sys_drvs = meo->me_num_sys_drvs;
1107     }
1108     /* FALLTHROUGH */
1109 
1110 	/*
1111 	 * Generic controller status update.  We could do more with this than just
1112 	 * checking the event log.
1113 	 */
1114     case MLX_CMD_ENQUIRY:
1115     {
1116 	struct mlx_enquiry		*me = (struct mlx_enquiry *)mc->mc_data;
1117 
1118 	if (sc->mlx_currevent == -1) {
1119 	    /* initialise our view of the event log */
1120 	    sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num;
1121 	} else if ((me->me_event_log_seq_num != sc->mlx_lastevent) && !(sc->mlx_flags & MLX_EVENTLOG_BUSY)) {
1122 	    /* record where current events are up to */
1123 	    sc->mlx_currevent = me->me_event_log_seq_num;
1124 	    debug(1, "event log pointer was %d, now %d\n", sc->mlx_lastevent, sc->mlx_currevent);
1125 
1126 	    /* mark the event log as busy */
1127 	    atomic_set_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY);
1128 
1129 	    /* drain new eventlog entries */
1130 	    mlx_periodic_eventlog_poll(sc);
1131 	}
1132 	break;
1133     }
1134     case MLX_CMD_ENQSYSDRIVE:
1135     {
1136 	struct mlx_enq_sys_drive	*mes = (struct mlx_enq_sys_drive *)mc->mc_data;
1137 	struct mlx_sysdrive		*dr;
1138 	int				i;
1139 
1140 	for (i = 0, dr = &sc->mlx_sysdrive[0];
1141 	     (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
1142 	     i++) {
1143 
1144 	    /* has state been changed by controller? */
1145 	    if (dr->ms_state != mes[i].sd_state) {
1146 		switch(mes[i].sd_state) {
1147 		case MLX_SYSD_OFFLINE:
1148 		    device_printf(dr->ms_disk, "drive offline\n");
1149 		    break;
1150 		case MLX_SYSD_ONLINE:
1151 		    device_printf(dr->ms_disk, "drive online\n");
1152 		    break;
1153 		case MLX_SYSD_CRITICAL:
1154 		    device_printf(dr->ms_disk, "drive critical\n");
1155 		    break;
1156 		}
1157 		/* save new state */
1158 		dr->ms_state = mes[i].sd_state;
1159 	    }
1160 	}
1161 	break;
1162     }
1163     default:
1164 	device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __func__, mc->mc_mailbox[0]);
1165 	break;
1166     }
1167 
1168  out:
1169     free(mc->mc_data, M_DEVBUF);
1170     mlx_releasecmd(mc);
1171 }
1172 
1173 static void
1174 mlx_eventlog_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1175 {
1176     struct mlx_command *mc;
1177 
1178     mc = (struct mlx_command *)arg;
1179     mlx_setup_dmamap(mc, segs, nsegments, error);
1180 
1181     /* build the command to get one entry */
1182     mlx_make_type3(mc, MLX_CMD_LOGOP, MLX_LOGOP_GET, 1,
1183 		   mc->mc_sc->mlx_lastevent, 0, 0, mc->mc_dataphys, 0);
1184     mc->mc_complete = mlx_periodic_eventlog_respond;
1185     mc->mc_private = mc;
1186 
1187     /* start the command */
1188     if (mlx_start(mc) != 0) {
1189 	mlx_releasecmd(mc);
1190 	free(mc->mc_data, M_DEVBUF);
1191 	mc->mc_data = NULL;
1192     }
1193 
1194 }
1195 
1196 /********************************************************************************
1197  * Instigate a poll for one event log message on (sc).
1198  * We only poll for one message at a time, to keep our command usage down.
1199  */
1200 static void
1201 mlx_periodic_eventlog_poll(struct mlx_softc *sc)
1202 {
1203     struct mlx_command	*mc;
1204     void		*result = NULL;
1205     int			error = 0;
1206 
1207     debug_called(1);
1208 
1209     /* get ourselves a command buffer */
1210     error = 1;
1211     if ((mc = mlx_alloccmd(sc)) == NULL)
1212 	goto out;
1213 
1214     /* allocate the response structure */
1215     if ((result = malloc(/*sizeof(struct mlx_eventlog_entry)*/1024, M_DEVBUF,
1216 			 M_NOWAIT)) == NULL)
1217 	goto out;
1218 
1219     /* get a command slot */
1220     if (mlx_getslot(mc))
1221 	goto out;
1222 
1223     /* map the command so the controller can see it */
1224     mc->mc_data = result;
1225     mc->mc_length = /*sizeof(struct mlx_eventlog_entry)*/1024;
1226     error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1227 			    mc->mc_length, mlx_eventlog_cb, mc, BUS_DMA_NOWAIT);
1228 
1229  out:
1230     if (error != 0) {
1231 	if (mc != NULL)
1232 	    mlx_releasecmd(mc);
1233 	if ((result != NULL) && (mc->mc_data != NULL))
1234 	    free(result, M_DEVBUF);
1235     }
1236 }
1237 
1238 /********************************************************************************
1239  * Handle the result of polling for a log message, generate diagnostic output.
1240  * If this wasn't the last message waiting for us, we'll go collect another.
1241  */
1242 static char *mlx_sense_messages[] = {
1243     "because write recovery failed",
1244     "because of SCSI bus reset failure",
1245     "because of double check condition",
1246     "because it was removed",
1247     "because of gross error on SCSI chip",
1248     "because of bad tag returned from drive",
1249     "because of timeout on SCSI command",
1250     "because of reset SCSI command issued from system",
1251     "because busy or parity error count exceeded limit",
1252     "because of 'kill drive' command from system",
1253     "because of selection timeout",
1254     "due to SCSI phase sequence error",
1255     "due to unknown status"
1256 };
1257 
1258 static void
1259 mlx_periodic_eventlog_respond(struct mlx_command *mc)
1260 {
1261     struct mlx_softc		*sc = mc->mc_sc;
1262     struct mlx_eventlog_entry	*el = (struct mlx_eventlog_entry *)mc->mc_data;
1263     char			*reason;
1264 
1265     debug_called(1);
1266 
1267     sc->mlx_lastevent++;		/* next message... */
1268     if (mc->mc_status == 0) {
1269 
1270 	/* handle event log message */
1271 	switch(el->el_type) {
1272 	    /*
1273 	     * This is the only sort of message we understand at the moment.
1274 	     * The tests here are probably incomplete.
1275 	     */
1276 	case MLX_LOGMSG_SENSE:	/* sense data */
1277 	    /* Mylex vendor-specific message indicating a drive was killed? */
1278 	    if ((el->el_sensekey == 9) &&
1279 		(el->el_asc == 0x80)) {
1280 		if (el->el_asq < (sizeof(mlx_sense_messages) / sizeof(mlx_sense_messages[0]))) {
1281 		    reason = mlx_sense_messages[el->el_asq];
1282 		} else {
1283 		    reason = "for unknown reason";
1284 		}
1285 		device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n",
1286 			      el->el_channel, el->el_target, reason);
1287 	    }
1288 	    /* SCSI drive was reset? */
1289 	    if ((el->el_sensekey == 6) && (el->el_asc == 0x29)) {
1290 		device_printf(sc->mlx_dev, "physical drive %d:%d reset\n",
1291 			      el->el_channel, el->el_target);
1292 	    }
1293 	    /* SCSI drive error? */
1294 	    if (!((el->el_sensekey == 0) ||
1295 		  ((el->el_sensekey == 2) &&
1296 		   (el->el_asc == 0x04) &&
1297 		   ((el->el_asq == 0x01) ||
1298 		    (el->el_asq == 0x02))))) {
1299 		device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n",
1300 			      el->el_channel, el->el_target, el->el_sensekey, el->el_asc, el->el_asq);
1301 		device_printf(sc->mlx_dev, "  info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":");
1302 	    }
1303 	    break;
1304 
1305 	default:
1306 	    device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type);
1307 	    break;
1308 	}
1309     } else {
1310 	device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc));
1311 	/* give up on all the outstanding messages, as we may have come unsynched */
1312 	sc->mlx_lastevent = sc->mlx_currevent;
1313     }
1314 
1315     /* dispose of command and data */
1316     free(mc->mc_data, M_DEVBUF);
1317     mlx_releasecmd(mc);
1318 
1319     /* is there another message to obtain? */
1320     if (sc->mlx_lastevent != sc->mlx_currevent) {
1321 	mlx_periodic_eventlog_poll(sc);
1322     } else {
1323 	/* clear log-busy status */
1324 	atomic_clear_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY);
1325     }
1326 }
1327 
1328 /********************************************************************************
1329  * Handle check/rebuild operations in progress.
1330  */
1331 static void
1332 mlx_periodic_rebuild(struct mlx_command *mc)
1333 {
1334     struct mlx_softc		*sc = mc->mc_sc;
1335     struct mlx_rebuild_status	*mr = (struct mlx_rebuild_status *)mc->mc_data;
1336 
1337     switch(mc->mc_status) {
1338     case 0:				/* operation running, update stats */
1339 	sc->mlx_rebuildstat = *mr;
1340 
1341 	/* spontaneous rebuild/check? */
1342 	if (sc->mlx_background == 0) {
1343 	    sc->mlx_background = MLX_BACKGROUND_SPONTANEOUS;
1344 	    device_printf(sc->mlx_dev, "background check/rebuild operation started\n");
1345 	}
1346 	break;
1347 
1348     case 0x0105:			/* nothing running, finalise stats and report */
1349 	switch(sc->mlx_background) {
1350 	case MLX_BACKGROUND_CHECK:
1351 	    device_printf(sc->mlx_dev, "consistency check completed\n");	/* XXX print drive? */
1352 	    break;
1353 	case MLX_BACKGROUND_REBUILD:
1354 	    device_printf(sc->mlx_dev, "drive rebuild completed\n");	/* XXX print channel/target? */
1355 	    break;
1356 	case MLX_BACKGROUND_SPONTANEOUS:
1357 	default:
1358 	    /* if we have previously been non-idle, report the transition */
1359 	    if (sc->mlx_rebuildstat.rs_code != MLX_REBUILDSTAT_IDLE) {
1360 		device_printf(sc->mlx_dev, "background check/rebuild operation completed\n");
1361 	    }
1362 	}
1363 	sc->mlx_background = 0;
1364 	sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
1365 	break;
1366     }
1367     free(mc->mc_data, M_DEVBUF);
1368     mlx_releasecmd(mc);
1369 }
1370 
1371 /********************************************************************************
1372  ********************************************************************************
1373                                                                     Channel Pause
1374  ********************************************************************************
1375  ********************************************************************************/
1376 
1377 /********************************************************************************
1378  * It's time to perform a channel pause action for (sc), either start or stop
1379  * the pause.
1380  */
1381 static void
1382 mlx_pause_action(struct mlx_softc *sc)
1383 {
1384     struct mlx_command	*mc;
1385     int			failsafe, i, command;
1386 
1387     /* What are we doing here? */
1388     if (sc->mlx_pause.mp_when == 0) {
1389 	command = MLX_CMD_STARTCHANNEL;
1390 	failsafe = 0;
1391 
1392     } else {
1393 	command = MLX_CMD_STOPCHANNEL;
1394 
1395 	/*
1396 	 * Channels will always start again after the failsafe period,
1397 	 * which is specified in multiples of 30 seconds.
1398 	 * This constrains us to a maximum pause of 450 seconds.
1399 	 */
1400 	failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30;
1401 	if (failsafe > 0xf) {
1402 	    failsafe = 0xf;
1403 	    sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5;
1404 	}
1405     }
1406 
1407     /* build commands for every channel requested */
1408     for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) {
1409 	if ((1 << i) & sc->mlx_pause.mp_which) {
1410 
1411 	    /* get ourselves a command buffer */
1412 	    if ((mc = mlx_alloccmd(sc)) == NULL)
1413 		goto fail;
1414 	    /* get a command slot */
1415 	    mc->mc_flags |= MLX_CMD_PRIORITY;
1416 	    if (mlx_getslot(mc))
1417 		goto fail;
1418 
1419 	    /* build the command */
1420 	    mlx_make_type2(mc, command, (failsafe << 4) | i, 0, 0, 0, 0, 0, 0, 0);
1421 	    mc->mc_complete = mlx_pause_done;
1422 	    mc->mc_private = sc;		/* XXX not needed */
1423 	    if (mlx_start(mc))
1424 		goto fail;
1425 	    /* command submitted OK */
1426 	    return;
1427 
1428 	fail:
1429 	    device_printf(sc->mlx_dev, "%s failed for channel %d\n",
1430 			  command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", i);
1431 	    if (mc != NULL)
1432 		mlx_releasecmd(mc);
1433 	}
1434     }
1435 }
1436 
1437 static void
1438 mlx_pause_done(struct mlx_command *mc)
1439 {
1440     struct mlx_softc	*sc = mc->mc_sc;
1441     int			command = mc->mc_mailbox[0];
1442     int			channel = mc->mc_mailbox[2] & 0xf;
1443 
1444     if (mc->mc_status != 0) {
1445 	device_printf(sc->mlx_dev, "%s command failed - %s\n",
1446 		      command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", mlx_diagnose_command(mc));
1447     } else if (command == MLX_CMD_STOPCHANNEL) {
1448 	device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n",
1449 		      channel, (long)(sc->mlx_pause.mp_howlong - time_second));
1450     } else {
1451 	device_printf(sc->mlx_dev, "channel %d resuming\n", channel);
1452     }
1453     mlx_releasecmd(mc);
1454 }
1455 
1456 /********************************************************************************
1457  ********************************************************************************
1458                                                                Command Submission
1459  ********************************************************************************
1460  ********************************************************************************/
1461 
1462 static void
1463 mlx_enquire_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1464 {
1465     struct mlx_softc *sc;
1466     struct mlx_command *mc;
1467 
1468     mc = (struct mlx_command *)arg;
1469     if (error)
1470 	return;
1471 
1472     mlx_setup_dmamap(mc, segs, nsegments, error);
1473 
1474     /* build an enquiry command */
1475     sc = mc->mc_sc;
1476     mlx_make_type2(mc, mc->mc_command, 0, 0, 0, 0, 0, 0, mc->mc_dataphys, 0);
1477 
1478     /* do we want a completion callback? */
1479     if (mc->mc_complete != NULL) {
1480 	if ((error = mlx_start(mc)) != 0)
1481 	    return;
1482     } else {
1483 	/* run the command in either polled or wait mode */
1484 	if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) :
1485 						mlx_poll_command(mc))
1486 	    return;
1487 
1488 	/* command completed OK? */
1489 	if (mc->mc_status != 0) {
1490 	    device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n",
1491 			  mlx_diagnose_command(mc));
1492 	    return;
1493 	}
1494     }
1495 }
1496 
1497 /********************************************************************************
1498  * Perform an Enquiry command using a type-3 command buffer and a return a single
1499  * linear result buffer.  If the completion function is specified, it will
1500  * be called with the completed command (and the result response will not be
1501  * valid until that point).  Otherwise, the command will either be busy-waited
1502  * for (interrupts not enabled), or slept for.
1503  */
1504 static void *
1505 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc))
1506 {
1507     struct mlx_command	*mc;
1508     void		*result;
1509     int			error;
1510 
1511     debug_called(1);
1512 
1513     /* get ourselves a command buffer */
1514     error = 1;
1515     result = NULL;
1516     if ((mc = mlx_alloccmd(sc)) == NULL)
1517 	goto out;
1518     /* allocate the response structure */
1519     if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
1520 	goto out;
1521     /* get a command slot */
1522     mc->mc_flags |= MLX_CMD_PRIORITY | MLX_CMD_DATAOUT;
1523     if (mlx_getslot(mc))
1524 	goto out;
1525 
1526     /* map the command so the controller can see it */
1527     mc->mc_data = result;
1528     mc->mc_length = bufsize;
1529     mc->mc_command = command;
1530 
1531     if (complete != NULL) {
1532 	mc->mc_complete = complete;
1533 	mc->mc_private = mc;
1534     }
1535 
1536     error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1537 			    mc->mc_length, mlx_enquire_cb, mc, BUS_DMA_NOWAIT);
1538 
1539  out:
1540     /* we got a command, but nobody else will free it */
1541     if ((mc != NULL) && (mc->mc_complete == NULL))
1542 	mlx_releasecmd(mc);
1543     /* we got an error, and we allocated a result */
1544     if ((error != 0) && (result != NULL)) {
1545 	free(result, M_DEVBUF);
1546 	result = NULL;
1547     }
1548     return(result);
1549 }
1550 
1551 
1552 /********************************************************************************
1553  * Perform a Flush command on the nominated controller.
1554  *
1555  * May be called with interrupts enabled or disabled; will not return until
1556  * the flush operation completes or fails.
1557  */
1558 static int
1559 mlx_flush(struct mlx_softc *sc)
1560 {
1561     struct mlx_command	*mc;
1562     int			error;
1563 
1564     debug_called(1);
1565 
1566     /* get ourselves a command buffer */
1567     error = 1;
1568     if ((mc = mlx_alloccmd(sc)) == NULL)
1569 	goto out;
1570     /* get a command slot */
1571     if (mlx_getslot(mc))
1572 	goto out;
1573 
1574     /* build a flush command */
1575     mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0);
1576 
1577     /* can't assume that interrupts are going to work here, so play it safe */
1578     if (mlx_poll_command(mc))
1579 	goto out;
1580 
1581     /* command completed OK? */
1582     if (mc->mc_status != 0) {
1583 	device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc));
1584 	goto out;
1585     }
1586 
1587     error = 0;			/* success */
1588  out:
1589     if (mc != NULL)
1590 	mlx_releasecmd(mc);
1591     return(error);
1592 }
1593 
1594 /********************************************************************************
1595  * Start a background consistency check on (drive).
1596  *
1597  * May be called with interrupts enabled or disabled; will return as soon as the
1598  * operation has started or been refused.
1599  */
1600 static int
1601 mlx_check(struct mlx_softc *sc, int drive)
1602 {
1603     struct mlx_command	*mc;
1604     int			error;
1605 
1606     debug_called(1);
1607 
1608     /* get ourselves a command buffer */
1609     error = 0x10000;
1610     if ((mc = mlx_alloccmd(sc)) == NULL)
1611 	goto out;
1612     /* get a command slot */
1613     if (mlx_getslot(mc))
1614 	goto out;
1615 
1616     /* build a checkasync command, set the "fix it" flag */
1617     mlx_make_type2(mc, MLX_CMD_CHECKASYNC, 0, 0, 0, 0, 0, drive | 0x80, 0, 0);
1618 
1619     /* start the command and wait for it to be returned */
1620     if (mlx_wait_command(mc))
1621 	goto out;
1622 
1623     /* command completed OK? */
1624     if (mc->mc_status != 0) {
1625 	device_printf(sc->mlx_dev, "CHECK ASYNC failed - %s\n", mlx_diagnose_command(mc));
1626     } else {
1627 	device_printf(sc->mlx_sysdrive[drive].ms_disk, "consistency check started");
1628     }
1629     error = mc->mc_status;
1630 
1631  out:
1632     if (mc != NULL)
1633 	mlx_releasecmd(mc);
1634     return(error);
1635 }
1636 
1637 /********************************************************************************
1638  * Start a background rebuild of the physical drive at (channel),(target).
1639  *
1640  * May be called with interrupts enabled or disabled; will return as soon as the
1641  * operation has started or been refused.
1642  */
1643 static int
1644 mlx_rebuild(struct mlx_softc *sc, int channel, int target)
1645 {
1646     struct mlx_command	*mc;
1647     int			error;
1648 
1649     debug_called(1);
1650 
1651     /* get ourselves a command buffer */
1652     error = 0x10000;
1653     if ((mc = mlx_alloccmd(sc)) == NULL)
1654 	goto out;
1655     /* get a command slot */
1656     if (mlx_getslot(mc))
1657 	goto out;
1658 
1659     /* build a checkasync command, set the "fix it" flag */
1660     mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0, 0, 0);
1661 
1662     /* start the command and wait for it to be returned */
1663     if (mlx_wait_command(mc))
1664 	goto out;
1665 
1666     /* command completed OK? */
1667     if (mc->mc_status != 0) {
1668 	device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc));
1669     } else {
1670 	device_printf(sc->mlx_dev, "drive rebuild started for %d:%d\n", channel, target);
1671     }
1672     error = mc->mc_status;
1673 
1674  out:
1675     if (mc != NULL)
1676 	mlx_releasecmd(mc);
1677     return(error);
1678 }
1679 
1680 /********************************************************************************
1681  * Run the command (mc) and return when it completes.
1682  *
1683  * Interrupts need to be enabled; returns nonzero on error.
1684  */
1685 static int
1686 mlx_wait_command(struct mlx_command *mc)
1687 {
1688     struct mlx_softc	*sc = mc->mc_sc;
1689     int			error, count;
1690 
1691     debug_called(1);
1692 
1693     mc->mc_complete = NULL;
1694     mc->mc_private = mc;		/* wake us when you're done */
1695     if ((error = mlx_start(mc)) != 0)
1696 	return(error);
1697 
1698     count = 0;
1699     /* XXX better timeout? */
1700     while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 30)) {
1701 	tsleep(mc->mc_private, PRIBIO | PCATCH, "mlxwcmd", hz);
1702     }
1703 
1704     if (mc->mc_status != 0) {
1705 	device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1706 	return(EIO);
1707     }
1708     return(0);
1709 }
1710 
1711 
1712 /********************************************************************************
1713  * Start the command (mc) and busy-wait for it to complete.
1714  *
1715  * Should only be used when interrupts can't be relied upon. Returns 0 on
1716  * success, nonzero on error.
1717  * Successfully completed commands are dequeued.
1718  */
1719 static int
1720 mlx_poll_command(struct mlx_command *mc)
1721 {
1722     struct mlx_softc	*sc = mc->mc_sc;
1723     int			error, count, s;
1724 
1725     debug_called(1);
1726 
1727     mc->mc_complete = NULL;
1728     mc->mc_private = NULL;	/* we will poll for it */
1729     if ((error = mlx_start(mc)) != 0)
1730 	return(error);
1731 
1732     count = 0;
1733     do {
1734 	/* poll for completion */
1735 	mlx_done(mc->mc_sc);
1736 
1737     } while ((mc->mc_status == MLX_STATUS_BUSY) && (count++ < 15000000));
1738     if (mc->mc_status != MLX_STATUS_BUSY) {
1739 	s = splbio();
1740 	TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
1741 	splx(s);
1742 	return(0);
1743     }
1744     device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1745     return(EIO);
1746 }
1747 
1748 void
1749 mlx_startio_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1750 {
1751     struct mlx_command	*mc;
1752     struct mlxd_softc	*mlxd;
1753     struct mlx_softc	*sc;
1754     mlx_bio		*bp;
1755     int			blkcount;
1756     int			driveno;
1757     int			cmd;
1758 
1759     mc = (struct mlx_command *)arg;
1760     mlx_setup_dmamap(mc, segs, nsegments, error);
1761 
1762     sc = mc->mc_sc;
1763     bp = mc->mc_private;
1764 
1765     if (MLX_BIO_IS_READ(bp)) {
1766 	mc->mc_flags |= MLX_CMD_DATAIN;
1767 	cmd = MLX_CMD_READSG;
1768     } else {
1769 	mc->mc_flags |= MLX_CMD_DATAOUT;
1770 	cmd = MLX_CMD_WRITESG;
1771     }
1772 
1773     /* build a suitable I/O command (assumes 512-byte rounded transfers) */
1774     mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
1775     driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1776     blkcount = (MLX_BIO_LENGTH(bp) + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
1777 
1778     if ((MLX_BIO_LBA(bp) + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1779 	device_printf(sc->mlx_dev,
1780 		      "I/O beyond end of unit (%lld,%d > %lu)\n",
1781 		      (long long)MLX_BIO_LBA(bp), blkcount,
1782 		      (u_long)sc->mlx_sysdrive[driveno].ms_size);
1783 
1784     /*
1785      * Build the I/O command.  Note that the SG list type bits are set to zero,
1786      * denoting the format of SG list that we are using.
1787      */
1788     if (sc->mlx_iftype == MLX_IFTYPE_2) {
1789 	mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD :
1790 						      MLX_CMD_READSG_OLD,
1791 		       blkcount & 0xff, 	/* xfer length low byte */
1792 		       MLX_BIO_LBA(bp),		/* physical block number */
1793 		       driveno,			/* target drive number */
1794 		       mc->mc_sgphys,		/* location of SG list */
1795 		       mc->mc_nsgent & 0x3f);	/* size of SG list */
1796 	} else {
1797 	mlx_make_type5(mc, cmd,
1798 		       blkcount & 0xff, 	/* xfer length low byte */
1799 		       (driveno << 3) | ((blkcount >> 8) & 0x07),
1800 						/* target+length high 3 bits */
1801 		       MLX_BIO_LBA(bp),		/* physical block number */
1802 		       mc->mc_sgphys,		/* location of SG list */
1803 		       mc->mc_nsgent & 0x3f);	/* size of SG list */
1804     }
1805 
1806     /* try to give command to controller */
1807     if (mlx_start(mc) != 0) {
1808 	/* fail the command */
1809 	mc->mc_status = MLX_STATUS_WEDGED;
1810 	mlx_completeio(mc);
1811     }
1812 }
1813 
1814 /********************************************************************************
1815  * Pull as much work off the softc's work queue as possible and give it to the
1816  * controller.  Leave a couple of slots free for emergencies.
1817  *
1818  * Must be called at splbio or in an equivalent fashion that prevents
1819  * reentry or activity on the bioq.
1820  */
1821 static void
1822 mlx_startio(struct mlx_softc *sc)
1823 {
1824     struct mlx_command	*mc;
1825     mlx_bio		*bp;
1826     int			s;
1827     int			error;
1828 
1829     /* avoid reentrancy */
1830     if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
1831 	return;
1832 
1833     /* spin until something prevents us from doing any work */
1834     s = splbio();
1835     for (;;) {
1836 
1837 	/* see if there's work to be done */
1838 	if ((bp = MLX_BIO_QFIRST(sc->mlx_bioq)) == NULL)
1839 	    break;
1840 	/* get a command */
1841 	if ((mc = mlx_alloccmd(sc)) == NULL)
1842 	    break;
1843 	/* get a slot for the command */
1844 	if (mlx_getslot(mc) != 0) {
1845 	    mlx_releasecmd(mc);
1846 	    break;
1847 	}
1848 	/* get the buf containing our work */
1849 	MLX_BIO_QREMOVE(sc->mlx_bioq, bp);
1850 	sc->mlx_waitbufs--;
1851 	splx(s);
1852 
1853 	/* connect the buf to the command */
1854 	mc->mc_complete = mlx_completeio;
1855 	mc->mc_private = bp;
1856 	mc->mc_data = MLX_BIO_DATA(bp);
1857 	mc->mc_length = MLX_BIO_LENGTH(bp);
1858 
1859 	/* map the command so the controller can work with it */
1860 	error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1861 				mc->mc_length, mlx_startio_cb, mc, 0);
1862 	if (error == EINPROGRESS) {
1863 		break;
1864 	}
1865 
1866 	s = splbio();
1867     }
1868     splx(s);
1869     mlx_lock_clr(sc, MLX_LOCK_STARTING);
1870 }
1871 
1872 /********************************************************************************
1873  * Handle completion of an I/O command.
1874  */
1875 static void
1876 mlx_completeio(struct mlx_command *mc)
1877 {
1878     struct mlx_softc	*sc = mc->mc_sc;
1879     mlx_bio		*bp = (mlx_bio *)mc->mc_private;
1880     struct mlxd_softc	*mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
1881 
1882     if (mc->mc_status != MLX_STATUS_OK) {	/* could be more verbose here? */
1883 	MLX_BIO_SET_ERROR(bp, EIO);
1884 
1885 	switch(mc->mc_status) {
1886 	case MLX_STATUS_RDWROFFLINE:		/* system drive has gone offline */
1887 	    device_printf(mlxd->mlxd_dev, "drive offline\n");
1888 	    /* should signal this with a return code */
1889 	    mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1890 	    break;
1891 
1892 	default:				/* other I/O error */
1893 	    device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1894 #if 0
1895 	    device_printf(sc->mlx_dev, "  b_bcount %ld  blkcount %ld  b_pblkno %d\n",
1896 			  MLX_BIO_LENGTH(bp), MLX_BIO_LENGTH(bp) / MLX_BLKSIZE, MLX_BIO_LBA(bp));
1897 	    device_printf(sc->mlx_dev, "  %13D\n", mc->mc_mailbox, " ");
1898 #endif
1899 	    break;
1900 	}
1901     }
1902     mlx_releasecmd(mc);
1903     mlxd_intr(bp);
1904 }
1905 
1906 void
1907 mlx_user_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1908 {
1909     struct mlx_usercommand *mu;
1910     struct mlx_command *mc;
1911     struct mlx_dcdb	*dcdb;
1912 
1913     mc = (struct mlx_command *)arg;
1914     if (error)
1915 	return;
1916 
1917     mlx_setup_dmamap(mc, segs, nsegments, error);
1918 
1919     mu = (struct mlx_usercommand *)mc->mc_private;
1920     dcdb = NULL;
1921 
1922     /*
1923      * If this is a passthrough SCSI command, the DCDB is packed at the
1924      * beginning of the data area.  Fix up the DCDB to point to the correct
1925      * physical address and override any bufptr supplied by the caller since
1926      * we know what it's meant to be.
1927      */
1928     if (mc->mc_mailbox[0] == MLX_CMD_DIRECT_CDB) {
1929 	dcdb = (struct mlx_dcdb *)mc->mc_data;
1930 	dcdb->dcdb_physaddr = mc->mc_dataphys + sizeof(*dcdb);
1931 	mu->mu_bufptr = 8;
1932     }
1933 
1934     /*
1935      * If there's a data buffer, fix up the command's buffer pointer.
1936      */
1937     if (mu->mu_datasize > 0) {
1938 	mc->mc_mailbox[mu->mu_bufptr    ] =  mc->mc_dataphys        & 0xff;
1939 	mc->mc_mailbox[mu->mu_bufptr + 1] = (mc->mc_dataphys >> 8)  & 0xff;
1940 	mc->mc_mailbox[mu->mu_bufptr + 2] = (mc->mc_dataphys >> 16) & 0xff;
1941 	mc->mc_mailbox[mu->mu_bufptr + 3] = (mc->mc_dataphys >> 24) & 0xff;
1942     }
1943     debug(0, "command fixup");
1944 
1945     /* submit the command and wait */
1946     if (mlx_wait_command(mc) != 0)
1947 	return;
1948 
1949 }
1950 
1951 /********************************************************************************
1952  * Take a command from user-space and try to run it.
1953  *
1954  * XXX Note that this can't perform very much in the way of error checking, and
1955  *     as such, applications _must_ be considered trustworthy.
1956  * XXX Commands using S/G for data are not supported.
1957  */
1958 static int
1959 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu)
1960 {
1961     struct mlx_command	*mc;
1962     void		*kbuf;
1963     int			error;
1964 
1965     debug_called(0);
1966 
1967     kbuf = NULL;
1968     mc = NULL;
1969     error = ENOMEM;
1970 
1971     /* get ourselves a command and copy in from user space */
1972     if ((mc = mlx_alloccmd(sc)) == NULL)
1973 	return(error);
1974     bcopy(mu->mu_command, mc->mc_mailbox, sizeof(mc->mc_mailbox));
1975     debug(0, "got command buffer");
1976 
1977     /*
1978      * if we need a buffer for data transfer, allocate one and copy in its
1979      * initial contents
1980      */
1981     if (mu->mu_datasize > 0) {
1982 	if (mu->mu_datasize > MAXPHYS) {
1983 	    error = EINVAL;
1984 	    goto out;
1985 	}
1986 	if (((kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) ||
1987 	    (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize)))
1988 	    goto out;
1989 	debug(0, "got kernel buffer");
1990     }
1991 
1992     /* get a command slot */
1993     if (mlx_getslot(mc))
1994 	goto out;
1995     debug(0, "got a slot");
1996 
1997     if (mu->mu_datasize > 0) {
1998 
1999 	/* range check the pointer to physical buffer address */
2000 	if ((mu->mu_bufptr < 0) || (mu->mu_bufptr > (sizeof(mu->mu_command) -
2001 						     sizeof(u_int32_t)))) {
2002 	    error = EINVAL;
2003 	    goto out;
2004 	}
2005     }
2006 
2007     /* map the command so the controller can see it */
2008     mc->mc_data = kbuf;
2009     mc->mc_length = mu->mu_datasize;
2010     mc->mc_private = mu;
2011     error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
2012 			    mc->mc_length, mlx_user_cb, mc, BUS_DMA_NOWAIT);
2013 
2014     /* copy out status and data */
2015     mu->mu_status = mc->mc_status;
2016     if ((mu->mu_datasize > 0) &&
2017 	((error = copyout(kbuf, mu->mu_buf, mu->mu_datasize))))
2018 	goto out;
2019 
2020     error = 0;
2021 
2022  out:
2023     mlx_releasecmd(mc);
2024     if (kbuf != NULL)
2025 	free(kbuf, M_DEVBUF);
2026     return(error);
2027 }
2028 
2029 /********************************************************************************
2030  ********************************************************************************
2031                                                         Command I/O to Controller
2032  ********************************************************************************
2033  ********************************************************************************/
2034 
2035 /********************************************************************************
2036  * Find a free command slot for (mc).
2037  *
2038  * Don't hand out a slot to a normal-priority command unless there are at least
2039  * 4 slots free for priority commands.
2040  */
2041 static int
2042 mlx_getslot(struct mlx_command *mc)
2043 {
2044     struct mlx_softc	*sc = mc->mc_sc;
2045     int			s, slot, limit;
2046 
2047     debug_called(1);
2048 
2049     /*
2050      * Enforce slot-usage limit, if we have the required information.
2051      */
2052     if (sc->mlx_enq2 != NULL) {
2053 	limit = sc->mlx_enq2->me_max_commands;
2054     } else {
2055 	limit = 2;
2056     }
2057     if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? limit : limit - 4))
2058 	return(EBUSY);
2059 
2060     /*
2061      * Allocate an outstanding command slot
2062      *
2063      * XXX linear search is slow
2064      */
2065     s = splbio();
2066     for (slot = 0; slot < limit; slot++) {
2067 	debug(2, "try slot %d", slot);
2068 	if (sc->mlx_busycmd[slot] == NULL)
2069 	    break;
2070     }
2071     if (slot < limit) {
2072 	sc->mlx_busycmd[slot] = mc;
2073 	sc->mlx_busycmds++;
2074     }
2075     splx(s);
2076 
2077     /* out of slots? */
2078     if (slot >= limit)
2079 	return(EBUSY);
2080 
2081     debug(2, "got slot %d", slot);
2082     mc->mc_slot = slot;
2083     return(0);
2084 }
2085 
2086 /********************************************************************************
2087  * Map/unmap (mc)'s data in the controller's addressable space.
2088  */
2089 static void
2090 mlx_setup_dmamap(struct mlx_command *mc, bus_dma_segment_t *segs, int nsegments,
2091 		 int error)
2092 {
2093     struct mlx_softc	*sc = mc->mc_sc;
2094     struct mlx_sgentry	*sg;
2095     int			i;
2096 
2097     debug_called(1);
2098 
2099     /* XXX should be unnecessary */
2100     if (sc->mlx_enq2 && (nsegments > sc->mlx_enq2->me_max_sg))
2101 	panic("MLX: too many s/g segments (%d, max %d)", nsegments,
2102 	      sc->mlx_enq2->me_max_sg);
2103 
2104     /* get base address of s/g table */
2105     sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG);
2106 
2107     /* save s/g table information in command */
2108     mc->mc_nsgent = nsegments;
2109     mc->mc_sgphys = sc->mlx_sgbusaddr +
2110 		   (mc->mc_slot * MLX_NSEG * sizeof(struct mlx_sgentry));
2111     mc->mc_dataphys = segs[0].ds_addr;
2112 
2113     /* populate s/g table */
2114     for (i = 0; i < nsegments; i++, sg++) {
2115 	sg->sg_addr = segs[i].ds_addr;
2116 	sg->sg_count = segs[i].ds_len;
2117     }
2118 
2119     /* Make sure the buffers are visible on the bus. */
2120     if (mc->mc_flags & MLX_CMD_DATAIN)
2121 	bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap,
2122 			BUS_DMASYNC_PREREAD);
2123     if (mc->mc_flags & MLX_CMD_DATAOUT)
2124 	bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap,
2125 			BUS_DMASYNC_PREWRITE);
2126 }
2127 
2128 static void
2129 mlx_unmapcmd(struct mlx_command *mc)
2130 {
2131     struct mlx_softc	*sc = mc->mc_sc;
2132 
2133     debug_called(1);
2134 
2135     /* if the command involved data at all */
2136     if (mc->mc_data != NULL) {
2137 
2138 	if (mc->mc_flags & MLX_CMD_DATAIN)
2139 	    bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD);
2140 	if (mc->mc_flags & MLX_CMD_DATAOUT)
2141 	    bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE);
2142 
2143 	bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap);
2144     }
2145 }
2146 
2147 /********************************************************************************
2148  * Try to deliver (mc) to the controller.
2149  *
2150  * Can be called at any interrupt level, with or without interrupts enabled.
2151  */
2152 static int
2153 mlx_start(struct mlx_command *mc)
2154 {
2155     struct mlx_softc	*sc = mc->mc_sc;
2156     int			i, s, done;
2157 
2158     debug_called(1);
2159 
2160     /* save the slot number as ident so we can handle this command when complete */
2161     mc->mc_mailbox[0x1] = mc->mc_slot;
2162 
2163     /* mark the command as currently being processed */
2164     mc->mc_status = MLX_STATUS_BUSY;
2165 
2166     /* set a default 60-second timeout  XXX tunable?  XXX not currently used */
2167     mc->mc_timeout = time_second + 60;
2168 
2169     /* spin waiting for the mailbox */
2170     for (i = 100000, done = 0; (i > 0) && !done; i--) {
2171 	s = splbio();
2172 	if (sc->mlx_tryqueue(sc, mc)) {
2173 	    done = 1;
2174 	    /* move command to work queue */
2175 	    TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
2176 	}
2177 	splx(s);	/* drop spl to allow completion interrupts */
2178     }
2179 
2180     /* command is enqueued */
2181     if (done)
2182 	return(0);
2183 
2184     /*
2185      * We couldn't get the controller to take the command.  Revoke the slot
2186      * that the command was given and return it with a bad status.
2187      */
2188     sc->mlx_busycmd[mc->mc_slot] = NULL;
2189     device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n");
2190     mc->mc_status = MLX_STATUS_WEDGED;
2191     mlx_complete(sc);
2192     return(EIO);
2193 }
2194 
2195 /********************************************************************************
2196  * Poll the controller (sc) for completed commands.
2197  * Update command status and free slots for reuse.  If any slots were freed,
2198  * new commands may be posted.
2199  *
2200  * Returns nonzero if one or more commands were completed.
2201  */
2202 static int
2203 mlx_done(struct mlx_softc *sc)
2204 {
2205     struct mlx_command	*mc;
2206     int			s, result;
2207     u_int8_t		slot;
2208     u_int16_t		status;
2209 
2210     debug_called(2);
2211 
2212     result = 0;
2213 
2214     /* loop collecting completed commands */
2215     s = splbio();
2216     for (;;) {
2217 	/* poll for a completed command's identifier and status */
2218 	if (sc->mlx_findcomplete(sc, &slot, &status)) {
2219 	    result = 1;
2220 	    mc = sc->mlx_busycmd[slot];			/* find command */
2221 	    if (mc != NULL) {				/* paranoia */
2222 		if (mc->mc_status == MLX_STATUS_BUSY) {
2223 		    mc->mc_status = status;		/* save status */
2224 
2225 		    /* free slot for reuse */
2226 		    sc->mlx_busycmd[slot] = NULL;
2227 		    sc->mlx_busycmds--;
2228 		} else {
2229 		    device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
2230 		}
2231 	    } else {
2232 		device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot);
2233 	    }
2234 	} else {
2235 	    break;
2236 	}
2237     }
2238     splx(s);
2239 
2240     /* if we've completed any commands, try posting some more */
2241     if (result)
2242 	mlx_startio(sc);
2243 
2244     /* handle completion and timeouts */
2245     mlx_complete(sc);
2246 
2247     return(result);
2248 }
2249 
2250 /********************************************************************************
2251  * Perform post-completion processing for commands on (sc).
2252  */
2253 static void
2254 mlx_complete(struct mlx_softc *sc)
2255 {
2256     struct mlx_command	*mc, *nc;
2257     int			s, count;
2258 
2259     debug_called(2);
2260 
2261     /* avoid reentrancy  XXX might want to signal and request a restart */
2262     if (mlx_lock_tas(sc, MLX_LOCK_COMPLETING))
2263 	return;
2264 
2265     s = splbio();
2266     count = 0;
2267 
2268     /* scan the list of busy/done commands */
2269     mc = TAILQ_FIRST(&sc->mlx_work);
2270     while (mc != NULL) {
2271 	nc = TAILQ_NEXT(mc, mc_link);
2272 
2273 	/* Command has been completed in some fashion */
2274 	if (mc->mc_status != MLX_STATUS_BUSY) {
2275 
2276 	    /* unmap the command's data buffer */
2277 	    mlx_unmapcmd(mc);
2278 	    /*
2279 	     * Does the command have a completion handler?
2280 	     */
2281 	    if (mc->mc_complete != NULL) {
2282 		/* remove from list and give to handler */
2283 		TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2284 		mc->mc_complete(mc);
2285 
2286 		/*
2287 		 * Is there a sleeper waiting on this command?
2288 		 */
2289 	    } else if (mc->mc_private != NULL) {	/* sleeping caller wants to know about it */
2290 
2291 		/* remove from list and wake up sleeper */
2292 		TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2293 		wakeup_one(mc->mc_private);
2294 
2295 		/*
2296 		 * Leave the command for a caller that's polling for it.
2297 		 */
2298 	    } else {
2299 	    }
2300 	}
2301 	mc = nc;
2302     }
2303     splx(s);
2304 
2305     mlx_lock_clr(sc, MLX_LOCK_COMPLETING);
2306 }
2307 
2308 /********************************************************************************
2309  ********************************************************************************
2310                                                         Command Buffer Management
2311  ********************************************************************************
2312  ********************************************************************************/
2313 
2314 /********************************************************************************
2315  * Get a new command buffer.
2316  *
2317  * This may return NULL in low-memory cases.
2318  *
2319  * Note that using malloc() is expensive (the command buffer is << 1 page) but
2320  * necessary if we are to be a loadable module before the zone allocator is fixed.
2321  *
2322  * If possible, we recycle a command buffer that's been used before.
2323  *
2324  * XXX Note that command buffers are not cleaned out - it is the caller's
2325  *     responsibility to ensure that all required fields are filled in before
2326  *     using a buffer.
2327  */
2328 static struct mlx_command *
2329 mlx_alloccmd(struct mlx_softc *sc)
2330 {
2331     struct mlx_command	*mc;
2332     int			error;
2333     int			s;
2334 
2335     debug_called(1);
2336 
2337     s = splbio();
2338     if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL)
2339 	TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
2340     splx(s);
2341 
2342     /* allocate a new command buffer? */
2343     if (mc == NULL) {
2344 	mc = (struct mlx_command *)malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT | M_ZERO);
2345 	if (mc != NULL) {
2346 	    mc->mc_sc = sc;
2347 	    error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap);
2348 	    if (error) {
2349 		free(mc, M_DEVBUF);
2350 		return(NULL);
2351 	    }
2352 	}
2353     }
2354     return(mc);
2355 }
2356 
2357 /********************************************************************************
2358  * Release a command buffer for recycling.
2359  *
2360  * XXX It might be a good idea to limit the number of commands we save for reuse
2361  *     if it's shown that this list bloats out massively.
2362  */
2363 static void
2364 mlx_releasecmd(struct mlx_command *mc)
2365 {
2366     int		s;
2367 
2368     debug_called(1);
2369 
2370     s = splbio();
2371     TAILQ_INSERT_HEAD(&mc->mc_sc->mlx_freecmds, mc, mc_link);
2372     splx(s);
2373 }
2374 
2375 /********************************************************************************
2376  * Permanently discard a command buffer.
2377  */
2378 static void
2379 mlx_freecmd(struct mlx_command *mc)
2380 {
2381     struct mlx_softc	*sc = mc->mc_sc;
2382 
2383     debug_called(1);
2384     bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap);
2385     free(mc, M_DEVBUF);
2386 }
2387 
2388 
2389 /********************************************************************************
2390  ********************************************************************************
2391                                                 Type 3 interface accessor methods
2392  ********************************************************************************
2393  ********************************************************************************/
2394 
2395 /********************************************************************************
2396  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2397  * (the controller is not ready to take a command).
2398  *
2399  * Must be called at splbio or in a fashion that prevents reentry.
2400  */
2401 static int
2402 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2403 {
2404     int		i;
2405 
2406     debug_called(2);
2407 
2408     /* ready for our command? */
2409     if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) {
2410 	/* copy mailbox data to window */
2411 	for (i = 0; i < 13; i++)
2412 	    MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2413 
2414 	/* post command */
2415 	MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL);
2416 	return(1);
2417     }
2418     return(0);
2419 }
2420 
2421 /********************************************************************************
2422  * See if a command has been completed, if so acknowledge its completion
2423  * and recover the slot number and status code.
2424  *
2425  * Must be called at splbio or in a fashion that prevents reentry.
2426  */
2427 static int
2428 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2429 {
2430 
2431     debug_called(2);
2432 
2433     /* status available? */
2434     if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) {
2435 	*slot = MLX_V3_GET_STATUS_IDENT(sc);		/* get command identifier */
2436 	*status = MLX_V3_GET_STATUS(sc);		/* get status */
2437 
2438 	/* acknowledge completion */
2439 	MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL);
2440 	MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2441 	return(1);
2442     }
2443     return(0);
2444 }
2445 
2446 /********************************************************************************
2447  * Enable/disable interrupts as requested. (No acknowledge required)
2448  *
2449  * Must be called at splbio or in a fashion that prevents reentry.
2450  */
2451 static void
2452 mlx_v3_intaction(struct mlx_softc *sc, int action)
2453 {
2454     debug_called(1);
2455 
2456     switch(action) {
2457     case MLX_INTACTION_DISABLE:
2458 	MLX_V3_PUT_IER(sc, 0);
2459 	sc->mlx_state &= ~MLX_STATE_INTEN;
2460 	break;
2461     case MLX_INTACTION_ENABLE:
2462 	MLX_V3_PUT_IER(sc, 1);
2463 	sc->mlx_state |= MLX_STATE_INTEN;
2464 	break;
2465     }
2466 }
2467 
2468 /********************************************************************************
2469  * Poll for firmware error codes during controller initialisation.
2470  * Returns 0 if initialisation is complete, 1 if still in progress but no
2471  * error has been fetched, 2 if an error has been retrieved.
2472  */
2473 static int
2474 mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
2475 {
2476     u_int8_t	fwerror;
2477     static int	initted = 0;
2478 
2479     debug_called(2);
2480 
2481     /* first time around, clear any hardware completion status */
2482     if (!initted) {
2483 	MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2484 	DELAY(1000);
2485 	initted = 1;
2486     }
2487 
2488     /* init in progress? */
2489     if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_INIT_BUSY))
2490 	return(0);
2491 
2492     /* test error value */
2493     fwerror = MLX_V3_GET_FWERROR(sc);
2494     if (!(fwerror & MLX_V3_FWERROR_PEND))
2495 	return(1);
2496 
2497     /* mask status pending bit, fetch status */
2498     *error = fwerror & ~MLX_V3_FWERROR_PEND;
2499     *param1 = MLX_V3_GET_FWERROR_PARAM1(sc);
2500     *param2 = MLX_V3_GET_FWERROR_PARAM2(sc);
2501 
2502     /* acknowledge */
2503     MLX_V3_PUT_FWERROR(sc, 0);
2504 
2505     return(2);
2506 }
2507 
2508 /********************************************************************************
2509  ********************************************************************************
2510                                                 Type 4 interface accessor methods
2511  ********************************************************************************
2512  ********************************************************************************/
2513 
2514 /********************************************************************************
2515  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2516  * (the controller is not ready to take a command).
2517  *
2518  * Must be called at splbio or in a fashion that prevents reentry.
2519  */
2520 static int
2521 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2522 {
2523     int		i;
2524 
2525     debug_called(2);
2526 
2527     /* ready for our command? */
2528     if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) {
2529 	/* copy mailbox data to window */
2530 	for (i = 0; i < 13; i++)
2531 	    MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2532 
2533 	/* memory-mapped controller, so issue a write barrier to ensure the mailbox is filled */
2534 	bus_space_barrier(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH,
2535 			  BUS_SPACE_BARRIER_WRITE);
2536 
2537 	/* post command */
2538 	MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD);
2539 	return(1);
2540     }
2541     return(0);
2542 }
2543 
2544 /********************************************************************************
2545  * See if a command has been completed, if so acknowledge its completion
2546  * and recover the slot number and status code.
2547  *
2548  * Must be called at splbio or in a fashion that prevents reentry.
2549  */
2550 static int
2551 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2552 {
2553 
2554     debug_called(2);
2555 
2556     /* status available? */
2557     if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) {
2558 	*slot = MLX_V4_GET_STATUS_IDENT(sc);		/* get command identifier */
2559 	*status = MLX_V4_GET_STATUS(sc);		/* get status */
2560 
2561 	/* acknowledge completion */
2562 	MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK);
2563 	MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2564 	return(1);
2565     }
2566     return(0);
2567 }
2568 
2569 /********************************************************************************
2570  * Enable/disable interrupts as requested.
2571  *
2572  * Must be called at splbio or in a fashion that prevents reentry.
2573  */
2574 static void
2575 mlx_v4_intaction(struct mlx_softc *sc, int action)
2576 {
2577     debug_called(1);
2578 
2579     switch(action) {
2580     case MLX_INTACTION_DISABLE:
2581 	MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT);
2582 	sc->mlx_state &= ~MLX_STATE_INTEN;
2583 	break;
2584     case MLX_INTACTION_ENABLE:
2585 	MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT);
2586 	sc->mlx_state |= MLX_STATE_INTEN;
2587 	break;
2588     }
2589 }
2590 
2591 /********************************************************************************
2592  * Poll for firmware error codes during controller initialisation.
2593  * Returns 0 if initialisation is complete, 1 if still in progress but no
2594  * error has been fetched, 2 if an error has been retrieved.
2595  */
2596 static int
2597 mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
2598 {
2599     u_int8_t	fwerror;
2600     static int	initted = 0;
2601 
2602     debug_called(2);
2603 
2604     /* first time around, clear any hardware completion status */
2605     if (!initted) {
2606 	MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2607 	DELAY(1000);
2608 	initted = 1;
2609     }
2610 
2611     /* init in progress? */
2612     if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_INIT_BUSY))
2613 	return(0);
2614 
2615     /* test error value */
2616     fwerror = MLX_V4_GET_FWERROR(sc);
2617     if (!(fwerror & MLX_V4_FWERROR_PEND))
2618 	return(1);
2619 
2620     /* mask status pending bit, fetch status */
2621     *error = fwerror & ~MLX_V4_FWERROR_PEND;
2622     *param1 = MLX_V4_GET_FWERROR_PARAM1(sc);
2623     *param2 = MLX_V4_GET_FWERROR_PARAM2(sc);
2624 
2625     /* acknowledge */
2626     MLX_V4_PUT_FWERROR(sc, 0);
2627 
2628     return(2);
2629 }
2630 
2631 /********************************************************************************
2632  ********************************************************************************
2633                                                 Type 5 interface accessor methods
2634  ********************************************************************************
2635  ********************************************************************************/
2636 
2637 /********************************************************************************
2638  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2639  * (the controller is not ready to take a command).
2640  *
2641  * Must be called at splbio or in a fashion that prevents reentry.
2642  */
2643 static int
2644 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2645 {
2646     int		i;
2647 
2648     debug_called(2);
2649 
2650     /* ready for our command? */
2651     if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) {
2652 	/* copy mailbox data to window */
2653 	for (i = 0; i < 13; i++)
2654 	    MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2655 
2656 	/* post command */
2657 	MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD);
2658 	return(1);
2659     }
2660     return(0);
2661 }
2662 
2663 /********************************************************************************
2664  * See if a command has been completed, if so acknowledge its completion
2665  * and recover the slot number and status code.
2666  *
2667  * Must be called at splbio or in a fashion that prevents reentry.
2668  */
2669 static int
2670 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2671 {
2672 
2673     debug_called(2);
2674 
2675     /* status available? */
2676     if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) {
2677 	*slot = MLX_V5_GET_STATUS_IDENT(sc);		/* get command identifier */
2678 	*status = MLX_V5_GET_STATUS(sc);		/* get status */
2679 
2680 	/* acknowledge completion */
2681 	MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK);
2682 	MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2683 	return(1);
2684     }
2685     return(0);
2686 }
2687 
2688 /********************************************************************************
2689  * Enable/disable interrupts as requested.
2690  *
2691  * Must be called at splbio or in a fashion that prevents reentry.
2692  */
2693 static void
2694 mlx_v5_intaction(struct mlx_softc *sc, int action)
2695 {
2696     debug_called(1);
2697 
2698     switch(action) {
2699     case MLX_INTACTION_DISABLE:
2700 	MLX_V5_PUT_IER(sc, 0xff & MLX_V5_IER_DISINT);
2701 	sc->mlx_state &= ~MLX_STATE_INTEN;
2702 	break;
2703     case MLX_INTACTION_ENABLE:
2704 	MLX_V5_PUT_IER(sc, 0xff & ~MLX_V5_IER_DISINT);
2705 	sc->mlx_state |= MLX_STATE_INTEN;
2706 	break;
2707     }
2708 }
2709 
2710 /********************************************************************************
2711  * Poll for firmware error codes during controller initialisation.
2712  * Returns 0 if initialisation is complete, 1 if still in progress but no
2713  * error has been fetched, 2 if an error has been retrieved.
2714  */
2715 static int
2716 mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
2717 {
2718     u_int8_t	fwerror;
2719     static int	initted = 0;
2720 
2721     debug_called(2);
2722 
2723     /* first time around, clear any hardware completion status */
2724     if (!initted) {
2725 	MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2726 	DELAY(1000);
2727 	initted = 1;
2728     }
2729 
2730     /* init in progress? */
2731     if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_INIT_DONE)
2732 	return(0);
2733 
2734     /* test for error value */
2735     fwerror = MLX_V5_GET_FWERROR(sc);
2736     if (!(fwerror & MLX_V5_FWERROR_PEND))
2737 	return(1);
2738 
2739     /* mask status pending bit, fetch status */
2740     *error = fwerror & ~MLX_V5_FWERROR_PEND;
2741     *param1 = MLX_V5_GET_FWERROR_PARAM1(sc);
2742     *param2 = MLX_V5_GET_FWERROR_PARAM2(sc);
2743 
2744     /* acknowledge */
2745     MLX_V5_PUT_FWERROR(sc, 0xff);
2746 
2747     return(2);
2748 }
2749 
2750 /********************************************************************************
2751  ********************************************************************************
2752                                                                         Debugging
2753  ********************************************************************************
2754  ********************************************************************************/
2755 
2756 /********************************************************************************
2757  * Return a status message describing (mc)
2758  */
2759 static char *mlx_status_messages[] = {
2760     "normal completion",			/* 00 */
2761     "irrecoverable data error",			/* 01 */
2762     "drive does not exist, or is offline",	/* 02 */
2763     "attempt to write beyond end of drive",	/* 03 */
2764     "bad data encountered",			/* 04 */
2765     "invalid log entry request",		/* 05 */
2766     "attempt to rebuild online drive",		/* 06 */
2767     "new disk failed during rebuild",		/* 07 */
2768     "invalid channel/target",			/* 08 */
2769     "rebuild/check already in progress",	/* 09 */
2770     "one or more disks are dead",		/* 10 */
2771     "invalid or non-redundant drive",		/* 11 */
2772     "channel is busy",				/* 12 */
2773     "channel is not stopped",			/* 13 */
2774     "rebuild successfully terminated",		/* 14 */
2775     "unsupported command",			/* 15 */
2776     "check condition received",			/* 16 */
2777     "device is busy",				/* 17 */
2778     "selection or command timeout",		/* 18 */
2779     "command terminated abnormally",		/* 19 */
2780     ""
2781 };
2782 
2783 static struct
2784 {
2785     int		command;
2786     u_int16_t	status;
2787     int		msg;
2788 } mlx_messages[] = {
2789     {MLX_CMD_READSG,		0x0001,	 1},
2790     {MLX_CMD_READSG,		0x0002,	 1},
2791     {MLX_CMD_READSG,		0x0105,	 3},
2792     {MLX_CMD_READSG,		0x010c,	 4},
2793     {MLX_CMD_WRITESG,		0x0001,	 1},
2794     {MLX_CMD_WRITESG,		0x0002,	 1},
2795     {MLX_CMD_WRITESG,		0x0105,	 3},
2796     {MLX_CMD_READSG_OLD,	0x0001,	 1},
2797     {MLX_CMD_READSG_OLD,	0x0002,	 1},
2798     {MLX_CMD_READSG_OLD,	0x0105,	 3},
2799     {MLX_CMD_WRITESG_OLD,	0x0001,	 1},
2800     {MLX_CMD_WRITESG_OLD,	0x0002,	 1},
2801     {MLX_CMD_WRITESG_OLD,	0x0105,	 3},
2802     {MLX_CMD_LOGOP,		0x0105,	 5},
2803     {MLX_CMD_REBUILDASYNC,	0x0002,  6},
2804     {MLX_CMD_REBUILDASYNC,	0x0004,  7},
2805     {MLX_CMD_REBUILDASYNC,	0x0105,  8},
2806     {MLX_CMD_REBUILDASYNC,	0x0106,  9},
2807     {MLX_CMD_REBUILDASYNC,	0x0107, 14},
2808     {MLX_CMD_CHECKASYNC,	0x0002, 10},
2809     {MLX_CMD_CHECKASYNC,	0x0105, 11},
2810     {MLX_CMD_CHECKASYNC,	0x0106,  9},
2811     {MLX_CMD_STOPCHANNEL,	0x0106, 12},
2812     {MLX_CMD_STOPCHANNEL,	0x0105,  8},
2813     {MLX_CMD_STARTCHANNEL,	0x0005, 13},
2814     {MLX_CMD_STARTCHANNEL,	0x0105,  8},
2815     {MLX_CMD_DIRECT_CDB,	0x0002, 16},
2816     {MLX_CMD_DIRECT_CDB,	0x0008, 17},
2817     {MLX_CMD_DIRECT_CDB,	0x000e, 18},
2818     {MLX_CMD_DIRECT_CDB,	0x000f, 19},
2819     {MLX_CMD_DIRECT_CDB,	0x0105,  8},
2820 
2821     {0,				0x0104, 14},
2822     {-1, 0, 0}
2823 };
2824 
2825 static char *
2826 mlx_diagnose_command(struct mlx_command *mc)
2827 {
2828     static char	unkmsg[80];
2829     int		i;
2830 
2831     /* look up message in table */
2832     for (i = 0; mlx_messages[i].command != -1; i++)
2833 	if (((mc->mc_mailbox[0] == mlx_messages[i].command) || (mlx_messages[i].command == 0)) &&
2834 	    (mc->mc_status == mlx_messages[i].status))
2835 	    return(mlx_status_messages[mlx_messages[i].msg]);
2836 
2837     sprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]);
2838     return(unkmsg);
2839 }
2840 
2841 /*******************************************************************************
2842  * Print a string describing the controller (sc)
2843  */
2844 static struct
2845 {
2846     int		hwid;
2847     char	*name;
2848 } mlx_controller_names[] = {
2849     {0x01,	"960P/PD"},
2850     {0x02,	"960PL"},
2851     {0x10,	"960PG"},
2852     {0x11,	"960PJ"},
2853     {0x12,	"960PR"},
2854     {0x13,	"960PT"},
2855     {0x14,	"960PTL0"},
2856     {0x15,	"960PRL"},
2857     {0x16,	"960PTL1"},
2858     {0x20,	"1164PVX"},
2859     {-1, NULL}
2860 };
2861 
2862 static void
2863 mlx_describe_controller(struct mlx_softc *sc)
2864 {
2865     static char		buf[80];
2866     char		*model;
2867     int			i;
2868 
2869     for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) {
2870 	if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) {
2871 	    model = mlx_controller_names[i].name;
2872 	    break;
2873 	}
2874     }
2875     if (model == NULL) {
2876 	sprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff);
2877 	model = buf;
2878     }
2879     device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%02d, %dMB RAM\n",
2880 		  model,
2881 		  sc->mlx_enq2->me_actual_channels,
2882 		  sc->mlx_enq2->me_actual_channels > 1 ? "s" : "",
2883 		  sc->mlx_enq2->me_firmware_id & 0xff,
2884 		  (sc->mlx_enq2->me_firmware_id >> 8) & 0xff,
2885 		  (sc->mlx_enq2->me_firmware_id >> 24) & 0xff,
2886 		  (sc->mlx_enq2->me_firmware_id >> 16) & 0xff,
2887 		  sc->mlx_enq2->me_mem_size / (1024 * 1024));
2888 
2889     if (bootverbose) {
2890 	device_printf(sc->mlx_dev, "  Hardware ID                 0x%08x\n", sc->mlx_enq2->me_hardware_id);
2891 	device_printf(sc->mlx_dev, "  Firmware ID                 0x%08x\n", sc->mlx_enq2->me_firmware_id);
2892 	device_printf(sc->mlx_dev, "  Configured/Actual channels  %d/%d\n", sc->mlx_enq2->me_configured_channels,
2893 		      sc->mlx_enq2->me_actual_channels);
2894 	device_printf(sc->mlx_dev, "  Max Targets                 %d\n", sc->mlx_enq2->me_max_targets);
2895 	device_printf(sc->mlx_dev, "  Max Tags                    %d\n", sc->mlx_enq2->me_max_tags);
2896 	device_printf(sc->mlx_dev, "  Max System Drives           %d\n", sc->mlx_enq2->me_max_sys_drives);
2897 	device_printf(sc->mlx_dev, "  Max Arms                    %d\n", sc->mlx_enq2->me_max_arms);
2898 	device_printf(sc->mlx_dev, "  Max Spans                   %d\n", sc->mlx_enq2->me_max_spans);
2899 	device_printf(sc->mlx_dev, "  DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size,
2900 		      sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size);
2901 	device_printf(sc->mlx_dev, "  DRAM type                   %d\n", sc->mlx_enq2->me_mem_type);
2902 	device_printf(sc->mlx_dev, "  Clock Speed                 %dns\n", sc->mlx_enq2->me_clock_speed);
2903 	device_printf(sc->mlx_dev, "  Hardware Speed              %dns\n", sc->mlx_enq2->me_hardware_speed);
2904 	device_printf(sc->mlx_dev, "  Max Commands                %d\n", sc->mlx_enq2->me_max_commands);
2905 	device_printf(sc->mlx_dev, "  Max SG Entries              %d\n", sc->mlx_enq2->me_max_sg);
2906 	device_printf(sc->mlx_dev, "  Max DP                      %d\n", sc->mlx_enq2->me_max_dp);
2907 	device_printf(sc->mlx_dev, "  Max IOD                     %d\n", sc->mlx_enq2->me_max_iod);
2908 	device_printf(sc->mlx_dev, "  Max Comb                    %d\n", sc->mlx_enq2->me_max_comb);
2909 	device_printf(sc->mlx_dev, "  Latency                     %ds\n", sc->mlx_enq2->me_latency);
2910 	device_printf(sc->mlx_dev, "  SCSI Timeout                %ds\n", sc->mlx_enq2->me_scsi_timeout);
2911 	device_printf(sc->mlx_dev, "  Min Free Lines              %d\n", sc->mlx_enq2->me_min_freelines);
2912 	device_printf(sc->mlx_dev, "  Rate Constant               %d\n", sc->mlx_enq2->me_rate_const);
2913 	device_printf(sc->mlx_dev, "  MAXBLK                      %d\n", sc->mlx_enq2->me_maxblk);
2914 	device_printf(sc->mlx_dev, "  Blocking Factor             %d sectors\n", sc->mlx_enq2->me_blocking_factor);
2915 	device_printf(sc->mlx_dev, "  Cache Line Size             %d blocks\n", sc->mlx_enq2->me_cacheline);
2916 	device_printf(sc->mlx_dev, "  SCSI Capability             %s%dMHz, %d bit\n",
2917 		      sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "",
2918 		      (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10,
2919 		      8 << (sc->mlx_enq2->me_scsi_cap & 0x3));
2920 	device_printf(sc->mlx_dev, "  Firmware Build Number       %d\n", sc->mlx_enq2->me_firmware_build);
2921 	device_printf(sc->mlx_dev, "  Fault Management Type       %d\n", sc->mlx_enq2->me_fault_mgmt_type);
2922 	device_printf(sc->mlx_dev, "  Features                    %b\n", sc->mlx_enq2->me_firmware_features,
2923 		      "\20\4Background Init\3Read Ahead\2MORE\1Cluster\n");
2924 
2925     }
2926 }
2927 
2928 /*******************************************************************************
2929  * Emit a string describing the firmware handshake status code, and return a flag
2930  * indicating whether the code represents a fatal error.
2931  *
2932  * Error code interpretations are from the Linux driver, and don't directly match
2933  * the messages printed by Mylex's BIOS.  This may change if documentation on the
2934  * codes is forthcoming.
2935  */
2936 static int
2937 mlx_fw_message(struct mlx_softc *sc, int error, int param1, int param2)
2938 {
2939     switch(error) {
2940     case 0x00:
2941 	device_printf(sc->mlx_dev, "physical drive %d:%d not responding\n", param2, param1);
2942 	break;
2943     case 0x08:
2944 	/* we could be neater about this and give some indication when we receive more of them */
2945 	if (!(sc->mlx_flags & MLX_SPINUP_REPORTED)) {
2946 	    device_printf(sc->mlx_dev, "spinning up drives...\n");
2947 	    sc->mlx_flags |= MLX_SPINUP_REPORTED;
2948 	}
2949 	break;
2950     case 0x30:
2951 	device_printf(sc->mlx_dev, "configuration checksum error\n");
2952 	break;
2953     case 0x60:
2954 	device_printf(sc->mlx_dev, "mirror race recovery failed\n");
2955 	break;
2956     case 0x70:
2957 	device_printf(sc->mlx_dev, "mirror race recovery in progress\n");
2958 	break;
2959     case 0x90:
2960 	device_printf(sc->mlx_dev, "physical drive %d:%d COD mismatch\n", param2, param1);
2961 	break;
2962     case 0xa0:
2963 	device_printf(sc->mlx_dev, "logical drive installation aborted\n");
2964 	break;
2965     case 0xb0:
2966 	device_printf(sc->mlx_dev, "mirror race on a critical system drive\n");
2967 	break;
2968     case 0xd0:
2969 	device_printf(sc->mlx_dev, "new controller configuration found\n");
2970 	break;
2971     case 0xf0:
2972 	device_printf(sc->mlx_dev, "FATAL MEMORY PARITY ERROR\n");
2973 	return(1);
2974     default:
2975 	device_printf(sc->mlx_dev, "unknown firmware initialisation error %02x:%02x:%02x\n", error, param1, param2);
2976 	break;
2977     }
2978     return(0);
2979 }
2980 
2981 /********************************************************************************
2982  ********************************************************************************
2983                                                                 Utility Functions
2984  ********************************************************************************
2985  ********************************************************************************/
2986 
2987 /********************************************************************************
2988  * Find the disk whose unit number is (unit) on this controller
2989  */
2990 static struct mlx_sysdrive *
2991 mlx_findunit(struct mlx_softc *sc, int unit)
2992 {
2993     int		i;
2994 
2995     /* search system drives */
2996     for (i = 0; i < MLX_MAXDRIVES; i++) {
2997 	/* is this one attached? */
2998 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
2999 	    /* is this the one? */
3000 	    if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
3001 		return(&sc->mlx_sysdrive[i]);
3002 	}
3003     }
3004     return(NULL);
3005 }
3006