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