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