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