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