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