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