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