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