]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/mly/mly.c
Return BUS_PROBE_GENERIC rather than 0 in the probe routine.
[FreeBSD/FreeBSD.git] / sys / dev / mly / mly.c
1 /*-
2  * Copyright (c) 2000, 2001 Michael Smith
3  * Copyright (c) 2000 BSDi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *      $FreeBSD$
28  */
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/malloc.h>
33 #include <sys/kernel.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/ctype.h>
37 #include <sys/ioccom.h>
38 #include <sys/stat.h>
39
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/rman.h>
43
44 #include <cam/cam.h>
45 #include <cam/cam_ccb.h>
46 #include <cam/cam_periph.h>
47 #include <cam/cam_sim.h>
48 #include <cam/cam_xpt_sim.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_message.h>
51
52 #include <dev/pci/pcireg.h>
53 #include <dev/pci/pcivar.h>
54
55 #include <dev/mly/mlyreg.h>
56 #include <dev/mly/mlyio.h>
57 #include <dev/mly/mlyvar.h>
58 #include <dev/mly/mly_tables.h>
59
60 static int      mly_probe(device_t dev);
61 static int      mly_attach(device_t dev);
62 static int      mly_pci_attach(struct mly_softc *sc);
63 static int      mly_detach(device_t dev);
64 static int      mly_shutdown(device_t dev);
65 static void     mly_intr(void *arg);
66
67 static int      mly_sg_map(struct mly_softc *sc);
68 static void     mly_sg_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
69 static int      mly_mmbox_map(struct mly_softc *sc);
70 static void     mly_mmbox_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
71 static void     mly_free(struct mly_softc *sc);
72
73 static int      mly_get_controllerinfo(struct mly_softc *sc);
74 static void     mly_scan_devices(struct mly_softc *sc);
75 static void     mly_rescan_btl(struct mly_softc *sc, int bus, int target);
76 static void     mly_complete_rescan(struct mly_command *mc);
77 static int      mly_get_eventstatus(struct mly_softc *sc);
78 static int      mly_enable_mmbox(struct mly_softc *sc);
79 static int      mly_flush(struct mly_softc *sc);
80 static int      mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data, 
81                           size_t datasize, u_int8_t *status, void *sense_buffer, size_t *sense_length);
82 static void     mly_check_event(struct mly_softc *sc);
83 static void     mly_fetch_event(struct mly_softc *sc);
84 static void     mly_complete_event(struct mly_command *mc);
85 static void     mly_process_event(struct mly_softc *sc, struct mly_event *me);
86 static void     mly_periodic(void *data);
87
88 static int      mly_immediate_command(struct mly_command *mc);
89 static int      mly_start(struct mly_command *mc);
90 static void     mly_done(struct mly_softc *sc);
91 static void     mly_complete(void *context, int pending);
92
93 static int      mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp);
94 static void     mly_release_command(struct mly_command *mc);
95 static void     mly_alloc_commands_map(void *arg, bus_dma_segment_t *segs, int nseg, int error);
96 static int      mly_alloc_commands(struct mly_softc *sc);
97 static void     mly_release_commands(struct mly_softc *sc);
98 static void     mly_map_command(struct mly_command *mc);
99 static void     mly_unmap_command(struct mly_command *mc);
100
101 static int      mly_cam_attach(struct mly_softc *sc);
102 static void     mly_cam_detach(struct mly_softc *sc);
103 static void     mly_cam_rescan_btl(struct mly_softc *sc, int bus, int target);
104 static void     mly_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb);
105 static void     mly_cam_action(struct cam_sim *sim, union ccb *ccb);
106 static int      mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio);
107 static void     mly_cam_poll(struct cam_sim *sim);
108 static void     mly_cam_complete(struct mly_command *mc);
109 static struct cam_periph *mly_find_periph(struct mly_softc *sc, int bus, int target);
110 static int      mly_name_device(struct mly_softc *sc, int bus, int target);
111
112 static int      mly_fwhandshake(struct mly_softc *sc);
113
114 static void     mly_describe_controller(struct mly_softc *sc);
115 #ifdef MLY_DEBUG
116 static void     mly_printstate(struct mly_softc *sc);
117 static void     mly_print_command(struct mly_command *mc);
118 static void     mly_print_packet(struct mly_command *mc);
119 static void     mly_panic(struct mly_softc *sc, char *reason);
120 #endif
121 void            mly_print_controller(int controller);
122 static int      mly_timeout(struct mly_softc *sc);
123
124
125 static d_open_t         mly_user_open;
126 static d_close_t        mly_user_close;
127 static d_ioctl_t        mly_user_ioctl;
128 static int      mly_user_command(struct mly_softc *sc, struct mly_user_command *uc);
129 static int      mly_user_health(struct mly_softc *sc, struct mly_user_health *uh);
130
131 #define MLY_CMD_TIMEOUT         20
132
133 static device_method_t mly_methods[] = {
134     /* Device interface */
135     DEVMETHOD(device_probe,     mly_probe),
136     DEVMETHOD(device_attach,    mly_attach),
137     DEVMETHOD(device_detach,    mly_detach),
138     DEVMETHOD(device_shutdown,  mly_shutdown),
139     { 0, 0 }
140 };
141
142 static driver_t mly_pci_driver = {
143         "mly",
144         mly_methods,
145         sizeof(struct mly_softc)
146 };
147
148 static devclass_t       mly_devclass;
149 DRIVER_MODULE(mly, pci, mly_pci_driver, mly_devclass, 0, 0);
150
151 static struct cdevsw mly_cdevsw = {
152         .d_version =    D_VERSION,
153         .d_flags =      D_NEEDGIANT,
154         .d_open =       mly_user_open,
155         .d_close =      mly_user_close,
156         .d_ioctl =      mly_user_ioctl,
157         .d_name =       "mly",
158 };
159
160 /********************************************************************************
161  ********************************************************************************
162                                                                  Device Interface
163  ********************************************************************************
164  ********************************************************************************/
165
166 static struct mly_ident
167 {
168     u_int16_t           vendor;
169     u_int16_t           device;
170     u_int16_t           subvendor;
171     u_int16_t           subdevice;
172     int                 hwif;
173     char                *desc;
174 } mly_identifiers[] = {
175     {0x1069, 0xba56, 0x1069, 0x0040, MLY_HWIF_STRONGARM, "Mylex eXtremeRAID 2000"},
176     {0x1069, 0xba56, 0x1069, 0x0030, MLY_HWIF_STRONGARM, "Mylex eXtremeRAID 3000"},
177     {0x1069, 0x0050, 0x1069, 0x0050, MLY_HWIF_I960RX,    "Mylex AcceleRAID 352"},
178     {0x1069, 0x0050, 0x1069, 0x0052, MLY_HWIF_I960RX,    "Mylex AcceleRAID 170"},
179     {0x1069, 0x0050, 0x1069, 0x0054, MLY_HWIF_I960RX,    "Mylex AcceleRAID 160"},
180     {0, 0, 0, 0, 0, 0}
181 };
182
183 /********************************************************************************
184  * Compare the provided PCI device with the list we support.
185  */
186 static int
187 mly_probe(device_t dev)
188 {
189     struct mly_ident    *m;
190
191     debug_called(1);
192
193     for (m = mly_identifiers; m->vendor != 0; m++) {
194         if ((m->vendor == pci_get_vendor(dev)) &&
195             (m->device == pci_get_device(dev)) &&
196             ((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
197                                      (m->subdevice == pci_get_subdevice(dev))))) {
198             
199             device_set_desc(dev, m->desc);
200             return(BUS_PROBE_DEFAULT);  /* allow room to be overridden */
201         }
202     }
203     return(ENXIO);
204 }
205
206 /********************************************************************************
207  * Initialise the controller and softc
208  */
209 static int
210 mly_attach(device_t dev)
211 {
212     struct mly_softc    *sc = device_get_softc(dev);
213     int                 error;
214
215     debug_called(1);
216
217     sc->mly_dev = dev;
218
219 #ifdef MLY_DEBUG
220     if (device_get_unit(sc->mly_dev) == 0)
221         mly_softc0 = sc;
222 #endif    
223
224     /*
225      * Do PCI-specific initialisation.
226      */
227     if ((error = mly_pci_attach(sc)) != 0)
228         goto out;
229
230     /*
231      * Initialise per-controller queues.
232      */
233     mly_initq_free(sc);
234     mly_initq_busy(sc);
235     mly_initq_complete(sc);
236
237     /*
238      * Initialise command-completion task.
239      */
240     TASK_INIT(&sc->mly_task_complete, 0, mly_complete, sc);
241
242     /* disable interrupts before we start talking to the controller */
243     MLY_MASK_INTERRUPTS(sc);
244
245     /* 
246      * Wait for the controller to come ready, handshake with the firmware if required.
247      * This is typically only necessary on platforms where the controller BIOS does not
248      * run.
249      */
250     if ((error = mly_fwhandshake(sc)))
251         goto out;
252
253     /*
254      * Allocate initial command buffers.
255      */
256     if ((error = mly_alloc_commands(sc)))
257         goto out;
258
259     /* 
260      * Obtain controller feature information
261      */
262     if ((error = mly_get_controllerinfo(sc)))
263         goto out;
264
265     /*
266      * Reallocate command buffers now we know how many we want.
267      */
268     mly_release_commands(sc);
269     if ((error = mly_alloc_commands(sc)))
270         goto out;
271
272     /*
273      * Get the current event counter for health purposes, populate the initial
274      * health status buffer.
275      */
276     if ((error = mly_get_eventstatus(sc)))
277         goto out;
278
279     /*
280      * Enable memory-mailbox mode.
281      */
282     if ((error = mly_enable_mmbox(sc)))
283         goto out;
284
285     /*
286      * Attach to CAM.
287      */
288     if ((error = mly_cam_attach(sc)))
289         goto out;
290
291     /* 
292      * Print a little information about the controller 
293      */
294     mly_describe_controller(sc);
295
296     /*
297      * Mark all attached devices for rescan.
298      */
299     mly_scan_devices(sc);
300
301     /*
302      * Instigate the first status poll immediately.  Rescan completions won't
303      * happen until interrupts are enabled, which should still be before
304      * the SCSI subsystem gets to us, courtesy of the "SCSI settling delay".
305      */
306     mly_periodic((void *)sc);
307
308     /*
309      * Create the control device.
310      */
311     sc->mly_dev_t = make_dev(&mly_cdevsw, device_get_unit(sc->mly_dev), UID_ROOT, GID_OPERATOR,
312                              S_IRUSR | S_IWUSR, "mly%d", device_get_unit(sc->mly_dev));
313     sc->mly_dev_t->si_drv1 = sc;
314
315     /* enable interrupts now */
316     MLY_UNMASK_INTERRUPTS(sc);
317
318 #ifdef MLY_DEBUG
319     timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz);
320 #endif
321
322  out:
323     if (error != 0)
324         mly_free(sc);
325     return(error);
326 }
327
328 /********************************************************************************
329  * Perform PCI-specific initialisation.
330  */
331 static int
332 mly_pci_attach(struct mly_softc *sc)
333 {
334     int                 i, error;
335     u_int32_t           command;
336
337     debug_called(1);
338
339     /* assume failure is 'not configured' */
340     error = ENXIO;
341
342     /* 
343      * Verify that the adapter is correctly set up in PCI space.
344      * 
345      * XXX we shouldn't do this; the PCI code should.
346      */
347     command = pci_read_config(sc->mly_dev, PCIR_COMMAND, 2);
348     command |= PCIM_CMD_BUSMASTEREN;
349     pci_write_config(sc->mly_dev, PCIR_COMMAND, command, 2);
350     command = pci_read_config(sc->mly_dev, PCIR_COMMAND, 2);
351     if (!(command & PCIM_CMD_BUSMASTEREN)) {
352         mly_printf(sc, "can't enable busmaster feature\n");
353         goto fail;
354     }
355     if ((command & PCIM_CMD_MEMEN) == 0) {
356         mly_printf(sc, "memory window not available\n");
357         goto fail;
358     }
359
360     /*
361      * Allocate the PCI register window.
362      */
363     sc->mly_regs_rid = PCIR_BAR(0);     /* first base address register */
364     if ((sc->mly_regs_resource = bus_alloc_resource_any(sc->mly_dev, 
365             SYS_RES_MEMORY, &sc->mly_regs_rid, RF_ACTIVE)) == NULL) {
366         mly_printf(sc, "can't allocate register window\n");
367         goto fail;
368     }
369     sc->mly_btag = rman_get_bustag(sc->mly_regs_resource);
370     sc->mly_bhandle = rman_get_bushandle(sc->mly_regs_resource);
371
372     /* 
373      * Allocate and connect our interrupt.
374      */
375     sc->mly_irq_rid = 0;
376     if ((sc->mly_irq = bus_alloc_resource_any(sc->mly_dev, SYS_RES_IRQ, 
377                     &sc->mly_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
378         mly_printf(sc, "can't allocate interrupt\n");
379         goto fail;
380     }
381     if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY,  mly_intr, sc, &sc->mly_intr)) {
382         mly_printf(sc, "can't set up interrupt\n");
383         goto fail;
384     }
385
386     /* assume failure is 'out of memory' */
387     error = ENOMEM;
388
389     /*
390      * Allocate the parent bus DMA tag appropriate for our PCI interface.
391      * 
392      * Note that all of these controllers are 64-bit capable.
393      */
394     if (bus_dma_tag_create(NULL,                        /* parent */
395                            1, 0,                        /* alignment, boundary */
396                            BUS_SPACE_MAXADDR_32BIT,     /* lowaddr */
397                            BUS_SPACE_MAXADDR,           /* highaddr */
398                            NULL, NULL,                  /* filter, filterarg */
399                            MAXBSIZE, MLY_MAX_SGENTRIES, /* maxsize, nsegments */
400                            BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
401                            BUS_DMA_ALLOCNOW,            /* flags */
402                            NULL,                        /* lockfunc */
403                            NULL,                        /* lockarg */
404                            &sc->mly_parent_dmat)) {
405         mly_printf(sc, "can't allocate parent DMA tag\n");
406         goto fail;
407     }
408
409     /*
410      * Create DMA tag for mapping buffers into controller-addressable space.
411      */
412     if (bus_dma_tag_create(sc->mly_parent_dmat,         /* parent */
413                            1, 0,                        /* alignment, boundary */
414                            BUS_SPACE_MAXADDR,           /* lowaddr */
415                            BUS_SPACE_MAXADDR,           /* highaddr */
416                            NULL, NULL,                  /* filter, filterarg */
417                            MAXBSIZE, MLY_MAX_SGENTRIES, /* maxsize, nsegments */
418                            BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
419                            0,                           /* flags */
420                            busdma_lock_mutex,           /* lockfunc */
421                            &Giant,                      /* lockarg */
422                            &sc->mly_buffer_dmat)) {
423         mly_printf(sc, "can't allocate buffer DMA tag\n");
424         goto fail;
425     }
426
427     /*
428      * Initialise the DMA tag for command packets.
429      */
430     if (bus_dma_tag_create(sc->mly_parent_dmat,         /* parent */
431                            1, 0,                        /* alignment, boundary */
432                            BUS_SPACE_MAXADDR,           /* lowaddr */
433                            BUS_SPACE_MAXADDR,           /* highaddr */
434                            NULL, NULL,                  /* filter, filterarg */
435                            sizeof(union mly_command_packet) * MLY_MAX_COMMANDS, 1,      /* maxsize, nsegments */
436                            BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
437                            BUS_DMA_ALLOCNOW,            /* flags */
438                            NULL, NULL,                  /* lockfunc, lockarg */
439                            &sc->mly_packet_dmat)) {
440         mly_printf(sc, "can't allocate command packet DMA tag\n");
441         goto fail;
442     }
443
444     /* 
445      * Detect the hardware interface version 
446      */
447     for (i = 0; mly_identifiers[i].vendor != 0; i++) {
448         if ((mly_identifiers[i].vendor == pci_get_vendor(sc->mly_dev)) &&
449             (mly_identifiers[i].device == pci_get_device(sc->mly_dev))) {
450             sc->mly_hwif = mly_identifiers[i].hwif;
451             switch(sc->mly_hwif) {
452             case MLY_HWIF_I960RX:
453                 debug(1, "set hardware up for i960RX");
454                 sc->mly_doorbell_true = 0x00;
455                 sc->mly_command_mailbox =  MLY_I960RX_COMMAND_MAILBOX;
456                 sc->mly_status_mailbox =   MLY_I960RX_STATUS_MAILBOX;
457                 sc->mly_idbr =             MLY_I960RX_IDBR;
458                 sc->mly_odbr =             MLY_I960RX_ODBR;
459                 sc->mly_error_status =     MLY_I960RX_ERROR_STATUS;
460                 sc->mly_interrupt_status = MLY_I960RX_INTERRUPT_STATUS;
461                 sc->mly_interrupt_mask =   MLY_I960RX_INTERRUPT_MASK;
462                 break;
463             case MLY_HWIF_STRONGARM:
464                 debug(1, "set hardware up for StrongARM");
465                 sc->mly_doorbell_true = 0xff;           /* doorbell 'true' is 0 */
466                 sc->mly_command_mailbox =  MLY_STRONGARM_COMMAND_MAILBOX;
467                 sc->mly_status_mailbox =   MLY_STRONGARM_STATUS_MAILBOX;
468                 sc->mly_idbr =             MLY_STRONGARM_IDBR;
469                 sc->mly_odbr =             MLY_STRONGARM_ODBR;
470                 sc->mly_error_status =     MLY_STRONGARM_ERROR_STATUS;
471                 sc->mly_interrupt_status = MLY_STRONGARM_INTERRUPT_STATUS;
472                 sc->mly_interrupt_mask =   MLY_STRONGARM_INTERRUPT_MASK;
473                 break;
474             }
475             break;
476         }
477     }
478
479     /*
480      * Create the scatter/gather mappings.
481      */
482     if ((error = mly_sg_map(sc)))
483         goto fail;
484
485     /*
486      * Allocate and map the memory mailbox
487      */
488     if ((error = mly_mmbox_map(sc)))
489         goto fail;
490
491     error = 0;
492             
493 fail:
494     return(error);
495 }
496
497 /********************************************************************************
498  * Shut the controller down and detach all our resources.
499  */
500 static int
501 mly_detach(device_t dev)
502 {
503     int                 error;
504
505     if ((error = mly_shutdown(dev)) != 0)
506         return(error);
507     
508     mly_free(device_get_softc(dev));
509     return(0);
510 }
511
512 /********************************************************************************
513  * Bring the controller to a state where it can be safely left alone.
514  *
515  * Note that it should not be necessary to wait for any outstanding commands,
516  * as they should be completed prior to calling here.
517  *
518  * XXX this applies for I/O, but not status polls; we should beware of
519  *     the case where a status command is running while we detach.
520  */
521 static int
522 mly_shutdown(device_t dev)
523 {
524     struct mly_softc    *sc = device_get_softc(dev);
525
526     debug_called(1);
527     
528     if (sc->mly_state & MLY_STATE_OPEN)
529         return(EBUSY);
530
531     /* kill the periodic event */
532     untimeout(mly_periodic, sc, sc->mly_periodic);
533
534     /* flush controller */
535     mly_printf(sc, "flushing cache...");
536     printf("%s\n", mly_flush(sc) ? "failed" : "done");
537
538     MLY_MASK_INTERRUPTS(sc);
539
540     return(0);
541 }
542
543 /*******************************************************************************
544  * Take an interrupt, or be poked by other code to look for interrupt-worthy
545  * status.
546  */
547 static void
548 mly_intr(void *arg)
549 {
550     struct mly_softc    *sc = (struct mly_softc *)arg;
551
552     debug_called(2);
553
554     mly_done(sc);
555 };
556
557 /********************************************************************************
558  ********************************************************************************
559                                                 Bus-dependant Resource Management
560  ********************************************************************************
561  ********************************************************************************/
562
563 /********************************************************************************
564  * Allocate memory for the scatter/gather tables
565  */
566 static int
567 mly_sg_map(struct mly_softc *sc)
568 {
569     size_t      segsize;
570
571     debug_called(1);
572
573     /*
574      * Create a single tag describing a region large enough to hold all of
575      * the s/g lists we will need.
576      */
577     segsize = sizeof(struct mly_sg_entry) * MLY_MAX_COMMANDS *MLY_MAX_SGENTRIES;
578     if (bus_dma_tag_create(sc->mly_parent_dmat,         /* parent */
579                            1, 0,                        /* alignment,boundary */
580                            BUS_SPACE_MAXADDR,           /* lowaddr */
581                            BUS_SPACE_MAXADDR,           /* highaddr */
582                            NULL, NULL,                  /* filter, filterarg */
583                            segsize, 1,                  /* maxsize, nsegments */
584                            BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
585                            BUS_DMA_ALLOCNOW,            /* flags */
586                            NULL, NULL,                  /* lockfunc, lockarg */
587                            &sc->mly_sg_dmat)) {
588         mly_printf(sc, "can't allocate scatter/gather DMA tag\n");
589         return(ENOMEM);
590     }
591
592     /*
593      * Allocate enough s/g maps for all commands and permanently map them into
594      * controller-visible space.
595      *  
596      * XXX this assumes we can get enough space for all the s/g maps in one 
597      * contiguous slab.
598      */
599     if (bus_dmamem_alloc(sc->mly_sg_dmat, (void **)&sc->mly_sg_table,
600                          BUS_DMA_NOWAIT, &sc->mly_sg_dmamap)) {
601         mly_printf(sc, "can't allocate s/g table\n");
602         return(ENOMEM);
603     }
604     if (bus_dmamap_load(sc->mly_sg_dmat, sc->mly_sg_dmamap, sc->mly_sg_table,
605                         segsize, mly_sg_map_helper, sc, BUS_DMA_NOWAIT) != 0)
606         return (ENOMEM);
607     return(0);
608 }
609
610 /********************************************************************************
611  * Save the physical address of the base of the s/g table.
612  */
613 static void
614 mly_sg_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
615 {
616     struct mly_softc    *sc = (struct mly_softc *)arg;
617
618     debug_called(1);
619
620     /* save base of s/g table's address in bus space */
621     sc->mly_sg_busaddr = segs->ds_addr;
622 }
623
624 /********************************************************************************
625  * Allocate memory for the memory-mailbox interface
626  */
627 static int
628 mly_mmbox_map(struct mly_softc *sc)
629 {
630
631     /*
632      * Create a DMA tag for a single contiguous region large enough for the
633      * memory mailbox structure.
634      */
635     if (bus_dma_tag_create(sc->mly_parent_dmat,         /* parent */
636                            1, 0,                        /* alignment,boundary */
637                            BUS_SPACE_MAXADDR,           /* lowaddr */
638                            BUS_SPACE_MAXADDR,           /* highaddr */
639                            NULL, NULL,                  /* filter, filterarg */
640                            sizeof(struct mly_mmbox), 1, /* maxsize, nsegments */
641                            BUS_SPACE_MAXSIZE_32BIT,     /* maxsegsize */
642                            BUS_DMA_ALLOCNOW,            /* flags */
643                            NULL, NULL,                  /* lockfunc, lockarg */
644                            &sc->mly_mmbox_dmat)) {
645         mly_printf(sc, "can't allocate memory mailbox DMA tag\n");
646         return(ENOMEM);
647     }
648
649     /*
650      * Allocate the buffer
651      */
652     if (bus_dmamem_alloc(sc->mly_mmbox_dmat, (void **)&sc->mly_mmbox, BUS_DMA_NOWAIT, &sc->mly_mmbox_dmamap)) {
653         mly_printf(sc, "can't allocate memory mailbox\n");
654         return(ENOMEM);
655     }
656     if (bus_dmamap_load(sc->mly_mmbox_dmat, sc->mly_mmbox_dmamap, sc->mly_mmbox,
657                         sizeof(struct mly_mmbox), mly_mmbox_map_helper, sc, 
658                         BUS_DMA_NOWAIT) != 0)
659         return (ENOMEM);
660     bzero(sc->mly_mmbox, sizeof(*sc->mly_mmbox));
661     return(0);
662
663 }
664
665 /********************************************************************************
666  * Save the physical address of the memory mailbox 
667  */
668 static void
669 mly_mmbox_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
670 {
671     struct mly_softc    *sc = (struct mly_softc *)arg;
672
673     debug_called(1);
674
675     sc->mly_mmbox_busaddr = segs->ds_addr;
676 }
677
678 /********************************************************************************
679  * Free all of the resources associated with (sc)
680  *
681  * Should not be called if the controller is active.
682  */
683 static void
684 mly_free(struct mly_softc *sc)
685 {
686     
687     debug_called(1);
688
689     /* Remove the management device */
690     destroy_dev(sc->mly_dev_t);
691
692     /* detach from CAM */
693     mly_cam_detach(sc);
694
695     /* release command memory */
696     mly_release_commands(sc);
697     
698     /* throw away the controllerinfo structure */
699     if (sc->mly_controllerinfo != NULL)
700         free(sc->mly_controllerinfo, M_DEVBUF);
701
702     /* throw away the controllerparam structure */
703     if (sc->mly_controllerparam != NULL)
704         free(sc->mly_controllerparam, M_DEVBUF);
705
706     /* destroy data-transfer DMA tag */
707     if (sc->mly_buffer_dmat)
708         bus_dma_tag_destroy(sc->mly_buffer_dmat);
709
710     /* free and destroy DMA memory and tag for s/g lists */
711     if (sc->mly_sg_table) {
712         bus_dmamap_unload(sc->mly_sg_dmat, sc->mly_sg_dmamap);
713         bus_dmamem_free(sc->mly_sg_dmat, sc->mly_sg_table, sc->mly_sg_dmamap);
714     }
715     if (sc->mly_sg_dmat)
716         bus_dma_tag_destroy(sc->mly_sg_dmat);
717
718     /* free and destroy DMA memory and tag for memory mailbox */
719     if (sc->mly_mmbox) {
720         bus_dmamap_unload(sc->mly_mmbox_dmat, sc->mly_mmbox_dmamap);
721         bus_dmamem_free(sc->mly_mmbox_dmat, sc->mly_mmbox, sc->mly_mmbox_dmamap);
722     }
723     if (sc->mly_mmbox_dmat)
724         bus_dma_tag_destroy(sc->mly_mmbox_dmat);
725
726     /* disconnect the interrupt handler */
727     if (sc->mly_intr)
728         bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr);
729     if (sc->mly_irq != NULL)
730         bus_release_resource(sc->mly_dev, SYS_RES_IRQ, sc->mly_irq_rid, sc->mly_irq);
731
732     /* destroy the parent DMA tag */
733     if (sc->mly_parent_dmat)
734         bus_dma_tag_destroy(sc->mly_parent_dmat);
735
736     /* release the register window mapping */
737     if (sc->mly_regs_resource != NULL)
738         bus_release_resource(sc->mly_dev, SYS_RES_MEMORY, sc->mly_regs_rid, sc->mly_regs_resource);
739 }
740
741 /********************************************************************************
742  ********************************************************************************
743                                                                  Command Wrappers
744  ********************************************************************************
745  ********************************************************************************/
746
747 /********************************************************************************
748  * Fill in the mly_controllerinfo and mly_controllerparam fields in the softc.
749  */
750 static int
751 mly_get_controllerinfo(struct mly_softc *sc)
752 {
753     struct mly_command_ioctl    mci;
754     u_int8_t                    status;
755     int                         error;
756
757     debug_called(1);
758
759     if (sc->mly_controllerinfo != NULL)
760         free(sc->mly_controllerinfo, M_DEVBUF);
761
762     /* build the getcontrollerinfo ioctl and send it */
763     bzero(&mci, sizeof(mci));
764     sc->mly_controllerinfo = NULL;
765     mci.sub_ioctl = MDACIOCTL_GETCONTROLLERINFO;
766     if ((error = mly_ioctl(sc, &mci, (void **)&sc->mly_controllerinfo, sizeof(*sc->mly_controllerinfo),
767                            &status, NULL, NULL)))
768         return(error);
769     if (status != 0)
770         return(EIO);
771
772     if (sc->mly_controllerparam != NULL)
773         free(sc->mly_controllerparam, M_DEVBUF);
774
775     /* build the getcontrollerparameter ioctl and send it */
776     bzero(&mci, sizeof(mci));
777     sc->mly_controllerparam = NULL;
778     mci.sub_ioctl = MDACIOCTL_GETCONTROLLERPARAMETER;
779     if ((error = mly_ioctl(sc, &mci, (void **)&sc->mly_controllerparam, sizeof(*sc->mly_controllerparam),
780                            &status, NULL, NULL)))
781         return(error);
782     if (status != 0)
783         return(EIO);
784
785     return(0);
786 }
787
788 /********************************************************************************
789  * Schedule all possible devices for a rescan.
790  *
791  */
792 static void
793 mly_scan_devices(struct mly_softc *sc)
794 {
795     int         bus, target;
796
797     debug_called(1);
798
799     /*
800      * Clear any previous BTL information.
801      */
802     bzero(&sc->mly_btl, sizeof(sc->mly_btl));
803
804     /*
805      * Mark all devices as requiring a rescan, and let the next
806      * periodic scan collect them. 
807      */
808     for (bus = 0; bus < sc->mly_cam_channels; bus++)
809         if (MLY_BUS_IS_VALID(sc, bus)) 
810             for (target = 0; target < MLY_MAX_TARGETS; target++)
811                 sc->mly_btl[bus][target].mb_flags = MLY_BTL_RESCAN;
812
813 }
814
815 /********************************************************************************
816  * Rescan a device, possibly as a consequence of getting an event which suggests
817  * that it may have changed.
818  *
819  * If we suffer resource starvation, we can abandon the rescan as we'll be
820  * retried.
821  */
822 static void
823 mly_rescan_btl(struct mly_softc *sc, int bus, int target)
824 {
825     struct mly_command          *mc;
826     struct mly_command_ioctl    *mci;
827
828     debug_called(1);
829
830     /* check that this bus is valid */
831     if (!MLY_BUS_IS_VALID(sc, bus))
832         return;
833
834     /* get a command */
835     if (mly_alloc_command(sc, &mc))
836         return;
837
838     /* set up the data buffer */
839     if ((mc->mc_data = malloc(sizeof(union mly_devinfo), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
840         mly_release_command(mc);
841         return;
842     }
843     mc->mc_flags |= MLY_CMD_DATAIN;
844     mc->mc_complete = mly_complete_rescan;
845
846     /* 
847      * Build the ioctl.
848      */
849     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
850     mci->opcode = MDACMD_IOCTL;
851     mci->addr.phys.controller = 0;
852     mci->timeout.value = 30;
853     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
854     if (MLY_BUS_IS_VIRTUAL(sc, bus)) {
855         mc->mc_length = mci->data_size = sizeof(struct mly_ioctl_getlogdevinfovalid);
856         mci->sub_ioctl = MDACIOCTL_GETLOGDEVINFOVALID;
857         mci->addr.log.logdev = MLY_LOGDEV_ID(sc, bus, target);
858         debug(1, "logical device %d", mci->addr.log.logdev);
859     } else {
860         mc->mc_length = mci->data_size = sizeof(struct mly_ioctl_getphysdevinfovalid);
861         mci->sub_ioctl = MDACIOCTL_GETPHYSDEVINFOVALID;
862         mci->addr.phys.lun = 0;
863         mci->addr.phys.target = target;
864         mci->addr.phys.channel = bus;
865         debug(1, "physical device %d:%d", mci->addr.phys.channel, mci->addr.phys.target);
866     }
867     
868     /*
869      * Dispatch the command.  If we successfully send the command, clear the rescan
870      * bit.
871      */
872     if (mly_start(mc) != 0) {
873         mly_release_command(mc);
874     } else {
875         sc->mly_btl[bus][target].mb_flags &= ~MLY_BTL_RESCAN;   /* success */   
876     }
877 }
878
879 /********************************************************************************
880  * Handle the completion of a rescan operation
881  */
882 static void
883 mly_complete_rescan(struct mly_command *mc)
884 {
885     struct mly_softc                            *sc = mc->mc_sc;
886     struct mly_ioctl_getlogdevinfovalid         *ldi;
887     struct mly_ioctl_getphysdevinfovalid        *pdi;
888     struct mly_command_ioctl                    *mci;
889     struct mly_btl                              btl, *btlp;
890     int                                         bus, target, rescan;
891
892     debug_called(1);
893
894     /*
895      * Recover the bus and target from the command.  We need these even in
896      * the case where we don't have a useful response.
897      */
898     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
899     if (mci->sub_ioctl == MDACIOCTL_GETLOGDEVINFOVALID) {
900         bus = MLY_LOGDEV_BUS(sc, mci->addr.log.logdev);
901         target = MLY_LOGDEV_TARGET(sc, mci->addr.log.logdev);
902     } else {
903         bus = mci->addr.phys.channel;
904         target = mci->addr.phys.target;
905     }
906     /* XXX validate bus/target? */
907     
908     /* the default result is 'no device' */
909     bzero(&btl, sizeof(btl));
910
911     /* if the rescan completed OK, we have possibly-new BTL data */
912     if (mc->mc_status == 0) {
913         if (mc->mc_length == sizeof(*ldi)) {
914             ldi = (struct mly_ioctl_getlogdevinfovalid *)mc->mc_data;
915             if ((MLY_LOGDEV_BUS(sc, ldi->logical_device_number) != bus) ||
916                 (MLY_LOGDEV_TARGET(sc, ldi->logical_device_number) != target)) {
917                 mly_printf(sc, "WARNING: BTL rescan for %d:%d returned data for %d:%d instead\n",
918                            bus, target, MLY_LOGDEV_BUS(sc, ldi->logical_device_number),
919                            MLY_LOGDEV_TARGET(sc, ldi->logical_device_number));
920                 /* XXX what can we do about this? */
921             }
922             btl.mb_flags = MLY_BTL_LOGICAL;
923             btl.mb_type = ldi->raid_level;
924             btl.mb_state = ldi->state;
925             debug(1, "BTL rescan for %d returns %s, %s", ldi->logical_device_number, 
926                   mly_describe_code(mly_table_device_type, ldi->raid_level),
927                   mly_describe_code(mly_table_device_state, ldi->state));
928         } else if (mc->mc_length == sizeof(*pdi)) {
929             pdi = (struct mly_ioctl_getphysdevinfovalid *)mc->mc_data;
930             if ((pdi->channel != bus) || (pdi->target != target)) {
931                 mly_printf(sc, "WARNING: BTL rescan for %d:%d returned data for %d:%d instead\n",
932                            bus, target, pdi->channel, pdi->target);
933                 /* XXX what can we do about this? */
934             }
935             btl.mb_flags = MLY_BTL_PHYSICAL;
936             btl.mb_type = MLY_DEVICE_TYPE_PHYSICAL;
937             btl.mb_state = pdi->state;
938             btl.mb_speed = pdi->speed;
939             btl.mb_width = pdi->width;
940             if (pdi->state != MLY_DEVICE_STATE_UNCONFIGURED)
941                 sc->mly_btl[bus][target].mb_flags |= MLY_BTL_PROTECTED;
942             debug(1, "BTL rescan for %d:%d returns %s", bus, target, 
943                   mly_describe_code(mly_table_device_state, pdi->state));
944         } else {
945             mly_printf(sc, "BTL rescan result invalid\n");
946         }
947     }
948
949     free(mc->mc_data, M_DEVBUF);
950     mly_release_command(mc);
951
952     /*
953      * Decide whether we need to rescan the device.
954      */
955     rescan = 0;
956
957     /* device type changes (usually between 'nothing' and 'something') */
958     btlp = &sc->mly_btl[bus][target];
959     if (btl.mb_flags != btlp->mb_flags) {
960         debug(1, "flags changed, rescanning");
961         rescan = 1;
962     }
963     
964     /* XXX other reasons? */
965
966     /*
967      * Update BTL information.
968      */
969     *btlp = btl;
970
971     /*
972      * Perform CAM rescan if required.
973      */
974     if (rescan)
975         mly_cam_rescan_btl(sc, bus, target);
976 }
977
978 /********************************************************************************
979  * Get the current health status and set the 'next event' counter to suit.
980  */
981 static int
982 mly_get_eventstatus(struct mly_softc *sc)
983 {
984     struct mly_command_ioctl    mci;
985     struct mly_health_status    *mh;
986     u_int8_t                    status;
987     int                         error;
988
989     /* build the gethealthstatus ioctl and send it */
990     bzero(&mci, sizeof(mci));
991     mh = NULL;
992     mci.sub_ioctl = MDACIOCTL_GETHEALTHSTATUS;
993
994     if ((error = mly_ioctl(sc, &mci, (void **)&mh, sizeof(*mh), &status, NULL, NULL)))
995         return(error);
996     if (status != 0)
997         return(EIO);
998
999     /* get the event counter */
1000     sc->mly_event_change = mh->change_counter;
1001     sc->mly_event_waiting = mh->next_event;
1002     sc->mly_event_counter = mh->next_event;
1003
1004     /* save the health status into the memory mailbox */
1005     bcopy(mh, &sc->mly_mmbox->mmm_health.status, sizeof(*mh));
1006
1007     debug(1, "initial change counter %d, event counter %d", mh->change_counter, mh->next_event);
1008     
1009     free(mh, M_DEVBUF);
1010     return(0);
1011 }
1012
1013 /********************************************************************************
1014  * Enable the memory mailbox mode.
1015  */
1016 static int
1017 mly_enable_mmbox(struct mly_softc *sc)
1018 {
1019     struct mly_command_ioctl    mci;
1020     u_int8_t                    *sp, status;
1021     int                         error;
1022
1023     debug_called(1);
1024
1025     /* build the ioctl and send it */
1026     bzero(&mci, sizeof(mci));
1027     mci.sub_ioctl = MDACIOCTL_SETMEMORYMAILBOX;
1028     /* set buffer addresses */
1029     mci.param.setmemorymailbox.command_mailbox_physaddr = 
1030         sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_command);
1031     mci.param.setmemorymailbox.status_mailbox_physaddr = 
1032         sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_status);
1033     mci.param.setmemorymailbox.health_buffer_physaddr = 
1034         sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_health);
1035
1036     /* set buffer sizes - abuse of data_size field is revolting */
1037     sp = (u_int8_t *)&mci.data_size;
1038     sp[0] = ((sizeof(union mly_command_packet) * MLY_MMBOX_COMMANDS) / 1024);
1039     sp[1] = (sizeof(union mly_status_packet) * MLY_MMBOX_STATUS) / 1024;
1040     mci.param.setmemorymailbox.health_buffer_size = sizeof(union mly_health_region) / 1024;
1041
1042     debug(1, "memory mailbox at %p (0x%llx/%d 0x%llx/%d 0x%llx/%d", sc->mly_mmbox,
1043           mci.param.setmemorymailbox.command_mailbox_physaddr, sp[0],
1044           mci.param.setmemorymailbox.status_mailbox_physaddr, sp[1],
1045           mci.param.setmemorymailbox.health_buffer_physaddr, 
1046           mci.param.setmemorymailbox.health_buffer_size);
1047
1048     if ((error = mly_ioctl(sc, &mci, NULL, 0, &status, NULL, NULL)))
1049         return(error);
1050     if (status != 0)
1051         return(EIO);
1052     sc->mly_state |= MLY_STATE_MMBOX_ACTIVE;
1053     debug(1, "memory mailbox active");
1054     return(0);
1055 }
1056
1057 /********************************************************************************
1058  * Flush all pending I/O from the controller.
1059  */
1060 static int
1061 mly_flush(struct mly_softc *sc)
1062 {
1063     struct mly_command_ioctl    mci;
1064     u_int8_t                    status;
1065     int                         error;
1066
1067     debug_called(1);
1068
1069     /* build the ioctl */
1070     bzero(&mci, sizeof(mci));
1071     mci.sub_ioctl = MDACIOCTL_FLUSHDEVICEDATA;
1072     mci.param.deviceoperation.operation_device = MLY_OPDEVICE_PHYSICAL_CONTROLLER;
1073
1074     /* pass it off to the controller */
1075     if ((error = mly_ioctl(sc, &mci, NULL, 0, &status, NULL, NULL)))
1076         return(error);
1077
1078     return((status == 0) ? 0 : EIO);
1079 }
1080
1081 /********************************************************************************
1082  * Perform an ioctl command.
1083  *
1084  * If (data) is not NULL, the command requires data transfer.  If (*data) is NULL
1085  * the command requires data transfer from the controller, and we will allocate
1086  * a buffer for it.  If (*data) is not NULL, the command requires data transfer
1087  * to the controller.
1088  *
1089  * XXX passing in the whole ioctl structure is ugly.  Better ideas?
1090  *
1091  * XXX we don't even try to handle the case where datasize > 4k.  We should.
1092  */
1093 static int
1094 mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data, size_t datasize, 
1095           u_int8_t *status, void *sense_buffer, size_t *sense_length)
1096 {
1097     struct mly_command          *mc;
1098     struct mly_command_ioctl    *mci;
1099     int                         error;
1100
1101     debug_called(1);
1102
1103     mc = NULL;
1104     if (mly_alloc_command(sc, &mc)) {
1105         error = ENOMEM;
1106         goto out;
1107     }
1108
1109     /* copy the ioctl structure, but save some important fields and then fixup */
1110     mci = &mc->mc_packet->ioctl;
1111     ioctl->sense_buffer_address = mci->sense_buffer_address;
1112     ioctl->maximum_sense_size = mci->maximum_sense_size;
1113     *mci = *ioctl;
1114     mci->opcode = MDACMD_IOCTL;
1115     mci->timeout.value = 30;
1116     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
1117     
1118     /* handle the data buffer */
1119     if (data != NULL) {
1120         if (*data == NULL) {
1121             /* allocate data buffer */
1122             if ((mc->mc_data = malloc(datasize, M_DEVBUF, M_NOWAIT)) == NULL) {
1123                 error = ENOMEM;
1124                 goto out;
1125             }
1126             mc->mc_flags |= MLY_CMD_DATAIN;
1127         } else {
1128             mc->mc_data = *data;
1129             mc->mc_flags |= MLY_CMD_DATAOUT;
1130         }
1131         mc->mc_length = datasize;
1132         mc->mc_packet->generic.data_size = datasize;
1133     }
1134     
1135     /* run the command */
1136     if ((error = mly_immediate_command(mc)))
1137         goto out;
1138     
1139     /* clean up and return any data */
1140     *status = mc->mc_status;
1141     if ((mc->mc_sense > 0) && (sense_buffer != NULL)) {
1142         bcopy(mc->mc_packet, sense_buffer, mc->mc_sense);
1143         *sense_length = mc->mc_sense;
1144         goto out;
1145     }
1146
1147     /* should we return a data pointer? */
1148     if ((data != NULL) && (*data == NULL))
1149         *data = mc->mc_data;
1150
1151     /* command completed OK */
1152     error = 0;
1153
1154 out:
1155     if (mc != NULL) {
1156         /* do we need to free a data buffer we allocated? */
1157         if (error && (mc->mc_data != NULL) && (*data == NULL))
1158             free(mc->mc_data, M_DEVBUF);
1159         mly_release_command(mc);
1160     }
1161     return(error);
1162 }
1163
1164 /********************************************************************************
1165  * Check for event(s) outstanding in the controller.
1166  */
1167 static void
1168 mly_check_event(struct mly_softc *sc)
1169 {
1170     
1171     /*
1172      * The controller may have updated the health status information,
1173      * so check for it here.  Note that the counters are all in host memory,
1174      * so this check is very cheap.  Also note that we depend on checking on
1175      * completion 
1176      */
1177     if (sc->mly_mmbox->mmm_health.status.change_counter != sc->mly_event_change) {
1178         sc->mly_event_change = sc->mly_mmbox->mmm_health.status.change_counter;
1179         debug(1, "event change %d, event status update, %d -> %d", sc->mly_event_change,
1180               sc->mly_event_waiting, sc->mly_mmbox->mmm_health.status.next_event);
1181         sc->mly_event_waiting = sc->mly_mmbox->mmm_health.status.next_event;
1182
1183         /* wake up anyone that might be interested in this */
1184         wakeup(&sc->mly_event_change);
1185     }
1186     if (sc->mly_event_counter != sc->mly_event_waiting)
1187     mly_fetch_event(sc);
1188 }
1189
1190 /********************************************************************************
1191  * Fetch one event from the controller.
1192  *
1193  * If we fail due to resource starvation, we'll be retried the next time a 
1194  * command completes.
1195  */
1196 static void
1197 mly_fetch_event(struct mly_softc *sc)
1198 {
1199     struct mly_command          *mc;
1200     struct mly_command_ioctl    *mci;
1201     int                         s;
1202     u_int32_t                   event;
1203
1204     debug_called(1);
1205
1206     /* get a command */
1207     if (mly_alloc_command(sc, &mc))
1208         return;
1209
1210     /* set up the data buffer */
1211     if ((mc->mc_data = malloc(sizeof(struct mly_event), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
1212         mly_release_command(mc);
1213         return;
1214     }
1215     mc->mc_length = sizeof(struct mly_event);
1216     mc->mc_flags |= MLY_CMD_DATAIN;
1217     mc->mc_complete = mly_complete_event;
1218
1219     /*
1220      * Get an event number to fetch.  It's possible that we've raced with another
1221      * context for the last event, in which case there will be no more events.
1222      */
1223     s = splcam();
1224     if (sc->mly_event_counter == sc->mly_event_waiting) {
1225         mly_release_command(mc);
1226         splx(s);
1227         return;
1228     }
1229     event = sc->mly_event_counter++;
1230     splx(s);
1231
1232     /* 
1233      * Build the ioctl.
1234      *
1235      * At this point we are committed to sending this request, as it
1236      * will be the only one constructed for this particular event number.
1237      */
1238     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
1239     mci->opcode = MDACMD_IOCTL;
1240     mci->data_size = sizeof(struct mly_event);
1241     mci->addr.phys.lun = (event >> 16) & 0xff;
1242     mci->addr.phys.target = (event >> 24) & 0xff;
1243     mci->addr.phys.channel = 0;
1244     mci->addr.phys.controller = 0;
1245     mci->timeout.value = 30;
1246     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
1247     mci->sub_ioctl = MDACIOCTL_GETEVENT;
1248     mci->param.getevent.sequence_number_low = event & 0xffff;
1249
1250     debug(1, "fetch event %u", event);
1251
1252     /*
1253      * Submit the command.
1254      *
1255      * Note that failure of mly_start() will result in this event never being
1256      * fetched.
1257      */
1258     if (mly_start(mc) != 0) {
1259         mly_printf(sc, "couldn't fetch event %u\n", event);
1260         mly_release_command(mc);
1261     }
1262 }
1263
1264 /********************************************************************************
1265  * Handle the completion of an event poll.
1266  */
1267 static void
1268 mly_complete_event(struct mly_command *mc)
1269 {
1270     struct mly_softc    *sc = mc->mc_sc;
1271     struct mly_event    *me = (struct mly_event *)mc->mc_data;
1272
1273     debug_called(1);
1274
1275     /* 
1276      * If the event was successfully fetched, process it.
1277      */
1278     if (mc->mc_status == SCSI_STATUS_OK) {
1279         mly_process_event(sc, me);
1280         free(me, M_DEVBUF);
1281     }
1282     mly_release_command(mc);
1283
1284     /*
1285      * Check for another event.
1286      */
1287     mly_check_event(sc);
1288 }
1289
1290 /********************************************************************************
1291  * Process a controller event.
1292  */
1293 static void
1294 mly_process_event(struct mly_softc *sc, struct mly_event *me)
1295 {
1296     struct scsi_sense_data      *ssd = (struct scsi_sense_data *)&me->sense[0];
1297     char                        *fp, *tp;
1298     int                         bus, target, event, class, action;
1299
1300     /* 
1301      * Errors can be reported using vendor-unique sense data.  In this case, the
1302      * event code will be 0x1c (Request sense data present), the sense key will
1303      * be 0x09 (vendor specific), the MSB of the ASC will be set, and the 
1304      * actual event code will be a 16-bit value comprised of the ASCQ (low byte)
1305      * and low seven bits of the ASC (low seven bits of the high byte).
1306      */
1307     if ((me->code == 0x1c) && 
1308         ((ssd->flags & SSD_KEY) == SSD_KEY_Vendor_Specific) &&
1309         (ssd->add_sense_code & 0x80)) {
1310         event = ((int)(ssd->add_sense_code & ~0x80) << 8) + ssd->add_sense_code_qual;
1311     } else {
1312         event = me->code;
1313     }
1314
1315     /* look up event, get codes */
1316     fp = mly_describe_code(mly_table_event, event);
1317
1318     debug(1, "Event %d  code 0x%x", me->sequence_number, me->code);
1319
1320     /* quiet event? */
1321     class = fp[0];
1322     if (isupper(class) && bootverbose)
1323         class = tolower(class);
1324
1325     /* get action code, text string */
1326     action = fp[1];
1327     tp = &fp[2];
1328
1329     /*
1330      * Print some information about the event.
1331      *
1332      * This code uses a table derived from the corresponding portion of the Linux
1333      * driver, and thus the parser is very similar.
1334      */
1335     switch(class) {
1336     case 'p':           /* error on physical device */
1337         mly_printf(sc, "physical device %d:%d %s\n", me->channel, me->target, tp);
1338         if (action == 'r')
1339             sc->mly_btl[me->channel][me->target].mb_flags |= MLY_BTL_RESCAN;
1340         break;
1341     case 'l':           /* error on logical unit */
1342     case 'm':           /* message about logical unit */
1343         bus = MLY_LOGDEV_BUS(sc, me->lun);
1344         target = MLY_LOGDEV_TARGET(sc, me->lun);
1345         mly_name_device(sc, bus, target);
1346         mly_printf(sc, "logical device %d (%s) %s\n", me->lun, sc->mly_btl[bus][target].mb_name, tp);
1347         if (action == 'r')
1348             sc->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN;
1349         break;
1350       break;
1351     case 's':           /* report of sense data */
1352         if (((ssd->flags & SSD_KEY) == SSD_KEY_NO_SENSE) ||
1353             (((ssd->flags & SSD_KEY) == SSD_KEY_NOT_READY) && 
1354              (ssd->add_sense_code == 0x04) && 
1355              ((ssd->add_sense_code_qual == 0x01) || (ssd->add_sense_code_qual == 0x02))))
1356             break;      /* ignore NO_SENSE or NOT_READY in one case */
1357
1358         mly_printf(sc, "physical device %d:%d %s\n", me->channel, me->target, tp);
1359         mly_printf(sc, "  sense key %d  asc %02x  ascq %02x\n", 
1360                       ssd->flags & SSD_KEY, ssd->add_sense_code, ssd->add_sense_code_qual);
1361         mly_printf(sc, "  info %4D  csi %4D\n", ssd->info, "", ssd->cmd_spec_info, "");
1362         if (action == 'r')
1363             sc->mly_btl[me->channel][me->target].mb_flags |= MLY_BTL_RESCAN;
1364         break;
1365     case 'e':
1366         mly_printf(sc, tp, me->target, me->lun);
1367         printf("\n");
1368         break;
1369     case 'c':
1370         mly_printf(sc, "controller %s\n", tp);
1371         break;
1372     case '?':
1373         mly_printf(sc, "%s - %d\n", tp, me->code);
1374         break;
1375     default:    /* probably a 'noisy' event being ignored */
1376         break;
1377     }
1378 }
1379
1380 /********************************************************************************
1381  * Perform periodic activities.
1382  */
1383 static void
1384 mly_periodic(void *data)
1385 {
1386     struct mly_softc    *sc = (struct mly_softc *)data;
1387     int                 bus, target;
1388
1389     debug_called(2);
1390
1391     /*
1392      * Scan devices.
1393      */
1394     for (bus = 0; bus < sc->mly_cam_channels; bus++) {
1395         if (MLY_BUS_IS_VALID(sc, bus)) {
1396             for (target = 0; target < MLY_MAX_TARGETS; target++) {
1397
1398                 /* ignore the controller in this scan */
1399                 if (target == sc->mly_controllerparam->initiator_id)
1400                     continue;
1401
1402                 /* perform device rescan? */
1403                 if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_RESCAN)
1404                     mly_rescan_btl(sc, bus, target);
1405             }
1406         }
1407     }
1408     
1409     /* check for controller events */
1410     mly_check_event(sc);
1411
1412     /* reschedule ourselves */
1413     sc->mly_periodic = timeout(mly_periodic, sc, MLY_PERIODIC_INTERVAL * hz);
1414 }
1415
1416 /********************************************************************************
1417  ********************************************************************************
1418                                                                Command Processing
1419  ********************************************************************************
1420  ********************************************************************************/
1421
1422 /********************************************************************************
1423  * Run a command and wait for it to complete.
1424  *
1425  */
1426 static int
1427 mly_immediate_command(struct mly_command *mc)
1428 {
1429     struct mly_softc    *sc = mc->mc_sc;
1430     int                 error, s;
1431
1432     debug_called(1);
1433
1434     /* spinning at splcam is ugly, but we're only used during controller init */
1435     s = splcam();
1436     if ((error = mly_start(mc))) {
1437         splx(s);
1438         return(error);
1439     }
1440
1441     if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) {
1442         /* sleep on the command */
1443         while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
1444             tsleep(mc, PRIBIO, "mlywait", 0);
1445         }
1446     } else {
1447         /* spin and collect status while we do */
1448         while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
1449             mly_done(mc->mc_sc);
1450         }
1451     }
1452     splx(s);
1453     return(0);
1454 }
1455
1456 /********************************************************************************
1457  * Deliver a command to the controller.
1458  *
1459  * XXX it would be good to just queue commands that we can't submit immediately
1460  *     and send them later, but we probably want a wrapper for that so that
1461  *     we don't hang on a failed submission for an immediate command.
1462  */
1463 static int
1464 mly_start(struct mly_command *mc)
1465 {
1466     struct mly_softc            *sc = mc->mc_sc;
1467     union mly_command_packet    *pkt;
1468     int                         s;
1469
1470     debug_called(2);
1471
1472     /* 
1473      * Set the command up for delivery to the controller. 
1474      */
1475     mly_map_command(mc);
1476     mc->mc_packet->generic.command_id = mc->mc_slot;
1477
1478 #ifdef MLY_DEBUG
1479     mc->mc_timestamp = time_second;
1480 #endif
1481
1482     s = splcam();
1483
1484     /*
1485      * Do we have to use the hardware mailbox?
1486      */
1487     if (!(sc->mly_state & MLY_STATE_MMBOX_ACTIVE)) {
1488         /*
1489          * Check to see if the controller is ready for us.
1490          */
1491         if (MLY_IDBR_TRUE(sc, MLY_HM_CMDSENT)) {
1492             splx(s);
1493             return(EBUSY);
1494         }
1495         mc->mc_flags |= MLY_CMD_BUSY;
1496         
1497         /*
1498          * It's ready, send the command.
1499          */
1500         MLY_SET_MBOX(sc, sc->mly_command_mailbox, &mc->mc_packetphys);
1501         MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_CMDSENT);
1502
1503     } else {    /* use memory-mailbox mode */
1504
1505         pkt = &sc->mly_mmbox->mmm_command[sc->mly_mmbox_command_index];
1506
1507         /* check to see if the next index is free yet */
1508         if (pkt->mmbox.flag != 0) {
1509             splx(s);
1510             return(EBUSY);
1511         }
1512         mc->mc_flags |= MLY_CMD_BUSY;
1513         
1514         /* copy in new command */
1515         bcopy(mc->mc_packet->mmbox.data, pkt->mmbox.data, sizeof(pkt->mmbox.data));
1516         /* barrier to ensure completion of previous write before we write the flag */
1517         bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0,
1518             BUS_SPACE_BARRIER_WRITE);
1519         /* copy flag last */
1520         pkt->mmbox.flag = mc->mc_packet->mmbox.flag;
1521         /* barrier to ensure completion of previous write before we notify the controller */
1522         bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0,
1523             BUS_SPACE_BARRIER_WRITE);
1524
1525         /* signal controller, update index */
1526         MLY_SET_REG(sc, sc->mly_idbr, MLY_AM_CMDSENT);
1527         sc->mly_mmbox_command_index = (sc->mly_mmbox_command_index + 1) % MLY_MMBOX_COMMANDS;
1528     }
1529
1530     mly_enqueue_busy(mc);
1531     splx(s);
1532     return(0);
1533 }
1534
1535 /********************************************************************************
1536  * Pick up command status from the controller, schedule a completion event
1537  */
1538 static void
1539 mly_done(struct mly_softc *sc) 
1540 {
1541     struct mly_command          *mc;
1542     union mly_status_packet     *sp;
1543     u_int16_t                   slot;
1544     int                         s, worked;
1545
1546     s = splcam();
1547     worked = 0;
1548
1549     /* pick up hardware-mailbox commands */
1550     if (MLY_ODBR_TRUE(sc, MLY_HM_STSREADY)) {
1551         slot = MLY_GET_REG2(sc, sc->mly_status_mailbox);
1552         if (slot < MLY_SLOT_MAX) {
1553             mc = &sc->mly_command[slot - MLY_SLOT_START];
1554             mc->mc_status = MLY_GET_REG(sc, sc->mly_status_mailbox + 2);
1555             mc->mc_sense = MLY_GET_REG(sc, sc->mly_status_mailbox + 3);
1556             mc->mc_resid = MLY_GET_REG4(sc, sc->mly_status_mailbox + 4);
1557             mly_remove_busy(mc);
1558             mc->mc_flags &= ~MLY_CMD_BUSY;
1559             mly_enqueue_complete(mc);
1560             worked = 1;
1561         } else {
1562             /* slot 0xffff may mean "extremely bogus command" */
1563             mly_printf(sc, "got HM completion for illegal slot %u\n", slot);
1564         }
1565         /* unconditionally acknowledge status */
1566         MLY_SET_REG(sc, sc->mly_odbr, MLY_HM_STSREADY);
1567         MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_STSACK);
1568     }
1569
1570     /* pick up memory-mailbox commands */
1571     if (MLY_ODBR_TRUE(sc, MLY_AM_STSREADY)) {
1572         for (;;) {
1573             sp = &sc->mly_mmbox->mmm_status[sc->mly_mmbox_status_index];
1574
1575             /* check for more status */
1576             if (sp->mmbox.flag == 0)
1577                 break;
1578
1579             /* get slot number */
1580             slot = sp->status.command_id;
1581             if (slot < MLY_SLOT_MAX) {
1582                 mc = &sc->mly_command[slot - MLY_SLOT_START];
1583                 mc->mc_status = sp->status.status;
1584                 mc->mc_sense = sp->status.sense_length;
1585                 mc->mc_resid = sp->status.residue;
1586                 mly_remove_busy(mc);
1587                 mc->mc_flags &= ~MLY_CMD_BUSY;
1588                 mly_enqueue_complete(mc);
1589                 worked = 1;
1590             } else {
1591                 /* slot 0xffff may mean "extremely bogus command" */
1592                 mly_printf(sc, "got AM completion for illegal slot %u at %d\n", 
1593                            slot, sc->mly_mmbox_status_index);
1594             }
1595
1596             /* clear and move to next index */
1597             sp->mmbox.flag = 0;
1598             sc->mly_mmbox_status_index = (sc->mly_mmbox_status_index + 1) % MLY_MMBOX_STATUS;
1599         }
1600         /* acknowledge that we have collected status value(s) */
1601         MLY_SET_REG(sc, sc->mly_odbr, MLY_AM_STSREADY);
1602     }
1603
1604     splx(s);
1605     if (worked) {
1606         if (sc->mly_state & MLY_STATE_INTERRUPTS_ON)
1607             taskqueue_enqueue(taskqueue_swi_giant, &sc->mly_task_complete);
1608         else
1609             mly_complete(sc, 0);
1610     }
1611 }
1612
1613 /********************************************************************************
1614  * Process completed commands
1615  */
1616 static void
1617 mly_complete(void *context, int pending)
1618 {
1619     struct mly_softc    *sc = (struct mly_softc *)context;
1620     struct mly_command  *mc;
1621     void                (* mc_complete)(struct mly_command *mc);
1622
1623
1624     debug_called(2);
1625
1626     /* 
1627      * Spin pulling commands off the completed queue and processing them.
1628      */
1629     while ((mc = mly_dequeue_complete(sc)) != NULL) {
1630
1631         /*
1632          * Free controller resources, mark command complete.
1633          *
1634          * Note that as soon as we mark the command complete, it may be freed
1635          * out from under us, so we need to save the mc_complete field in
1636          * order to later avoid dereferencing mc.  (We would not expect to
1637          * have a polling/sleeping consumer with mc_complete != NULL).
1638          */
1639         mly_unmap_command(mc);
1640         mc_complete = mc->mc_complete;
1641         mc->mc_flags |= MLY_CMD_COMPLETE;
1642
1643         /* 
1644          * Call completion handler or wake up sleeping consumer.
1645          */
1646         if (mc_complete != NULL) {
1647             mc_complete(mc);
1648         } else {
1649             wakeup(mc);
1650         }
1651     }
1652     
1653     /*
1654      * XXX if we are deferring commands due to controller-busy status, we should
1655      *     retry submitting them here.
1656      */
1657 }
1658
1659 /********************************************************************************
1660  ********************************************************************************
1661                                                         Command Buffer Management
1662  ********************************************************************************
1663  ********************************************************************************/
1664
1665 /********************************************************************************
1666  * Allocate a command.
1667  */
1668 static int
1669 mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp)
1670 {
1671     struct mly_command  *mc;
1672
1673     debug_called(3);
1674
1675     if ((mc = mly_dequeue_free(sc)) == NULL)
1676         return(ENOMEM);
1677
1678     *mcp = mc;
1679     return(0);
1680 }
1681
1682 /********************************************************************************
1683  * Release a command back to the freelist.
1684  */
1685 static void
1686 mly_release_command(struct mly_command *mc)
1687 {
1688     debug_called(3);
1689
1690     /*
1691      * Fill in parts of the command that may cause confusion if
1692      * a consumer doesn't when we are later allocated.
1693      */
1694     mc->mc_data = NULL;
1695     mc->mc_flags = 0;
1696     mc->mc_complete = NULL;
1697     mc->mc_private = NULL;
1698
1699     /*
1700      * By default, we set up to overwrite the command packet with
1701      * sense information.
1702      */
1703     mc->mc_packet->generic.sense_buffer_address = mc->mc_packetphys;
1704     mc->mc_packet->generic.maximum_sense_size = sizeof(union mly_command_packet);
1705
1706     mly_enqueue_free(mc);
1707 }
1708
1709 /********************************************************************************
1710  * Map helper for command allocation.
1711  */
1712 static void
1713 mly_alloc_commands_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1714 {
1715     struct mly_softc    *sc = (struct mly_softc *)arg;
1716
1717     debug_called(1);
1718
1719     sc->mly_packetphys = segs[0].ds_addr;
1720 }
1721
1722 /********************************************************************************
1723  * Allocate and initialise command and packet structures.
1724  *
1725  * If the controller supports fewer than MLY_MAX_COMMANDS commands, limit our
1726  * allocation to that number.  If we don't yet know how many commands the
1727  * controller supports, allocate a very small set (suitable for initialisation
1728  * purposes only).
1729  */
1730 static int
1731 mly_alloc_commands(struct mly_softc *sc)
1732 {
1733     struct mly_command          *mc;
1734     int                         i, ncmd;
1735  
1736     if (sc->mly_controllerinfo == NULL) {
1737         ncmd = 4;
1738     } else {
1739         ncmd = min(MLY_MAX_COMMANDS, sc->mly_controllerinfo->maximum_parallel_commands);
1740     }
1741
1742     /*
1743      * Allocate enough space for all the command packets in one chunk and
1744      * map them permanently into controller-visible space.
1745      */
1746     if (bus_dmamem_alloc(sc->mly_packet_dmat, (void **)&sc->mly_packet, 
1747                          BUS_DMA_NOWAIT, &sc->mly_packetmap)) {
1748         return(ENOMEM);
1749     }
1750     if (bus_dmamap_load(sc->mly_packet_dmat, sc->mly_packetmap, sc->mly_packet, 
1751                         ncmd * sizeof(union mly_command_packet), 
1752                         mly_alloc_commands_map, sc, BUS_DMA_NOWAIT) != 0)
1753         return (ENOMEM);
1754
1755     for (i = 0; i < ncmd; i++) {
1756         mc = &sc->mly_command[i];
1757         bzero(mc, sizeof(*mc));
1758         mc->mc_sc = sc;
1759         mc->mc_slot = MLY_SLOT_START + i;
1760         mc->mc_packet = sc->mly_packet + i;
1761         mc->mc_packetphys = sc->mly_packetphys + (i * sizeof(union mly_command_packet));
1762         if (!bus_dmamap_create(sc->mly_buffer_dmat, 0, &mc->mc_datamap))
1763             mly_release_command(mc);
1764     }
1765     return(0);
1766 }
1767
1768 /********************************************************************************
1769  * Free all the storage held by commands.
1770  *
1771  * Must be called with all commands on the free list.
1772  */
1773 static void
1774 mly_release_commands(struct mly_softc *sc)
1775 {
1776     struct mly_command  *mc;
1777
1778     /* throw away command buffer DMA maps */
1779     while (mly_alloc_command(sc, &mc) == 0)
1780         bus_dmamap_destroy(sc->mly_buffer_dmat, mc->mc_datamap);
1781
1782     /* release the packet storage */
1783     if (sc->mly_packet != NULL) {
1784         bus_dmamap_unload(sc->mly_packet_dmat, sc->mly_packetmap);
1785         bus_dmamem_free(sc->mly_packet_dmat, sc->mly_packet, sc->mly_packetmap);
1786         sc->mly_packet = NULL;
1787     }
1788 }
1789
1790
1791 /********************************************************************************
1792  * Command-mapping helper function - populate this command's s/g table
1793  * with the s/g entries for its data.
1794  */
1795 static void
1796 mly_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1797 {
1798     struct mly_command          *mc = (struct mly_command *)arg;
1799     struct mly_softc            *sc = mc->mc_sc;
1800     struct mly_command_generic  *gen = &(mc->mc_packet->generic);
1801     struct mly_sg_entry         *sg;
1802     int                         i, tabofs;
1803
1804     debug_called(2);
1805
1806     /* can we use the transfer structure directly? */
1807     if (nseg <= 2) {
1808         sg = &gen->transfer.direct.sg[0];
1809         gen->command_control.extended_sg_table = 0;
1810     } else {
1811         tabofs = ((mc->mc_slot - MLY_SLOT_START) * MLY_MAX_SGENTRIES);
1812         sg = sc->mly_sg_table + tabofs;
1813         gen->transfer.indirect.entries[0] = nseg;
1814         gen->transfer.indirect.table_physaddr[0] = sc->mly_sg_busaddr + (tabofs * sizeof(struct mly_sg_entry));
1815         gen->command_control.extended_sg_table = 1;
1816     }
1817
1818     /* copy the s/g table */
1819     for (i = 0; i < nseg; i++) {
1820         sg[i].physaddr = segs[i].ds_addr;
1821         sg[i].length = segs[i].ds_len;
1822     }
1823
1824 }
1825
1826 #if 0
1827 /********************************************************************************
1828  * Command-mapping helper function - save the cdb's physical address.
1829  *
1830  * We don't support 'large' SCSI commands at this time, so this is unused.
1831  */
1832 static void
1833 mly_map_command_cdb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1834 {
1835     struct mly_command                  *mc = (struct mly_command *)arg;
1836
1837     debug_called(2);
1838
1839     /* XXX can we safely assume that a CDB will never cross a page boundary? */
1840     if ((segs[0].ds_addr % PAGE_SIZE) > 
1841         ((segs[0].ds_addr + mc->mc_packet->scsi_large.cdb_length) % PAGE_SIZE))
1842         panic("cdb crosses page boundary");
1843
1844     /* fix up fields in the command packet */
1845     mc->mc_packet->scsi_large.cdb_physaddr = segs[0].ds_addr;
1846 }
1847 #endif
1848
1849 /********************************************************************************
1850  * Map a command into controller-visible space
1851  */
1852 static void
1853 mly_map_command(struct mly_command *mc)
1854 {
1855     struct mly_softc    *sc = mc->mc_sc;
1856
1857     debug_called(2);
1858
1859     /* don't map more than once */
1860     if (mc->mc_flags & MLY_CMD_MAPPED)
1861         return;
1862
1863     /* does the command have a data buffer? */
1864     if (mc->mc_data != NULL) {
1865         bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap, mc->mc_data, mc->mc_length, 
1866                         mly_map_command_sg, mc, 0);
1867         
1868         if (mc->mc_flags & MLY_CMD_DATAIN)
1869             bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREREAD);
1870         if (mc->mc_flags & MLY_CMD_DATAOUT)
1871             bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREWRITE);
1872     }
1873     mc->mc_flags |= MLY_CMD_MAPPED;
1874 }
1875
1876 /********************************************************************************
1877  * Unmap a command from controller-visible space
1878  */
1879 static void
1880 mly_unmap_command(struct mly_command *mc)
1881 {
1882     struct mly_softc    *sc = mc->mc_sc;
1883
1884     debug_called(2);
1885
1886     if (!(mc->mc_flags & MLY_CMD_MAPPED))
1887         return;
1888
1889     /* does the command have a data buffer? */
1890     if (mc->mc_data != NULL) {
1891         if (mc->mc_flags & MLY_CMD_DATAIN)
1892             bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_POSTREAD);
1893         if (mc->mc_flags & MLY_CMD_DATAOUT)
1894             bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_POSTWRITE);
1895
1896         bus_dmamap_unload(sc->mly_buffer_dmat, mc->mc_datamap);
1897     }
1898     mc->mc_flags &= ~MLY_CMD_MAPPED;
1899 }
1900
1901
1902 /********************************************************************************
1903  ********************************************************************************
1904                                                                     CAM interface
1905  ********************************************************************************
1906  ********************************************************************************/
1907
1908 /********************************************************************************
1909  * Attach the physical and virtual SCSI busses to CAM.
1910  *
1911  * Physical bus numbering starts from 0, virtual bus numbering from one greater
1912  * than the highest physical bus.  Physical busses are only registered if
1913  * the kernel environment variable "hw.mly.register_physical_channels" is set.
1914  *
1915  * When we refer to a "bus", we are referring to the bus number registered with
1916  * the SIM, wheras a "channel" is a channel number given to the adapter.  In order
1917  * to keep things simple, we map these 1:1, so "bus" and "channel" may be used
1918  * interchangeably.
1919  */
1920 static int
1921 mly_cam_attach(struct mly_softc *sc)
1922 {
1923     struct cam_devq     *devq;
1924     int                 chn, i;
1925
1926     debug_called(1);
1927
1928     /*
1929      * Allocate a devq for all our channels combined.
1930      */
1931     if ((devq = cam_simq_alloc(sc->mly_controllerinfo->maximum_parallel_commands)) == NULL) {
1932         mly_printf(sc, "can't allocate CAM SIM queue\n");
1933         return(ENOMEM);
1934     }
1935
1936     /*
1937      * If physical channel registration has been requested, register these first.
1938      * Note that we enable tagged command queueing for physical channels.
1939      */
1940     if (testenv("hw.mly.register_physical_channels")) {
1941         chn = 0;
1942         for (i = 0; i < sc->mly_controllerinfo->physical_channels_present; i++, chn++) {
1943
1944             if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc,
1945                                                       device_get_unit(sc->mly_dev),
1946                                                       sc->mly_controllerinfo->maximum_parallel_commands,
1947                                                       1, devq)) == NULL) {
1948                 return(ENOMEM);
1949             }
1950             if (xpt_bus_register(sc->mly_cam_sim[chn], chn)) {
1951                 mly_printf(sc, "CAM XPT phsyical channel registration failed\n");
1952                 return(ENXIO);
1953             }
1954             debug(1, "registered physical channel %d", chn);
1955         }
1956     }
1957
1958     /*
1959      * Register our virtual channels, with bus numbers matching channel numbers.
1960      */
1961     chn = sc->mly_controllerinfo->physical_channels_present;
1962     for (i = 0; i < sc->mly_controllerinfo->virtual_channels_present; i++, chn++) {
1963         if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc,
1964                                                   device_get_unit(sc->mly_dev),
1965                                                   sc->mly_controllerinfo->maximum_parallel_commands,
1966                                                   0, devq)) == NULL) {
1967             return(ENOMEM);
1968         }
1969         if (xpt_bus_register(sc->mly_cam_sim[chn], chn)) {
1970             mly_printf(sc, "CAM XPT virtual channel registration failed\n");
1971             return(ENXIO);
1972         }
1973         debug(1, "registered virtual channel %d", chn);
1974     }
1975
1976     /*
1977      * This is the total number of channels that (might have been) registered with
1978      * CAM.  Some may not have been; check the mly_cam_sim array to be certain.
1979      */
1980     sc->mly_cam_channels = sc->mly_controllerinfo->physical_channels_present +
1981         sc->mly_controllerinfo->virtual_channels_present;
1982
1983     return(0);
1984 }
1985
1986 /********************************************************************************
1987  * Detach from CAM
1988  */
1989 static void
1990 mly_cam_detach(struct mly_softc *sc)
1991 {
1992     int         i;
1993     
1994     debug_called(1);
1995
1996     for (i = 0; i < sc->mly_cam_channels; i++) {
1997         if (sc->mly_cam_sim[i] != NULL) {
1998             xpt_bus_deregister(cam_sim_path(sc->mly_cam_sim[i]));
1999             cam_sim_free(sc->mly_cam_sim[i], 0);
2000         }
2001     }
2002     if (sc->mly_cam_devq != NULL)
2003         cam_simq_free(sc->mly_cam_devq);
2004 }
2005
2006 /************************************************************************
2007  * Rescan a device.
2008  */ 
2009 static void
2010 mly_cam_rescan_btl(struct mly_softc *sc, int bus, int target)
2011 {
2012     union ccb   *ccb;
2013
2014     debug_called(1);
2015
2016     if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) {
2017         mly_printf(sc, "rescan failed (can't allocate CCB)\n");
2018         return;
2019     }
2020     
2021     if (xpt_create_path(&sc->mly_cam_path, xpt_periph, 
2022                         cam_sim_path(sc->mly_cam_sim[bus]), target, 0) != CAM_REQ_CMP) {
2023         mly_printf(sc, "rescan failed (can't create path)\n");
2024         free(ccb, M_TEMP);
2025         return;
2026     }
2027     xpt_setup_ccb(&ccb->ccb_h, sc->mly_cam_path, 5/*priority (low)*/);
2028     ccb->ccb_h.func_code = XPT_SCAN_LUN;
2029     ccb->ccb_h.cbfcnp = mly_cam_rescan_callback;
2030     ccb->crcn.flags = CAM_FLAG_NONE;
2031     debug(1, "rescan target %d:%d", bus, target);
2032     xpt_action(ccb);
2033 }
2034
2035 static void
2036 mly_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
2037 {
2038     free(ccb, M_TEMP);
2039 }
2040
2041 /********************************************************************************
2042  * Handle an action requested by CAM
2043  */
2044 static void
2045 mly_cam_action(struct cam_sim *sim, union ccb *ccb)
2046 {
2047     struct mly_softc    *sc = cam_sim_softc(sim);
2048
2049     debug_called(2);
2050
2051     switch (ccb->ccb_h.func_code) {
2052
2053         /* perform SCSI I/O */
2054     case XPT_SCSI_IO:
2055         if (!mly_cam_action_io(sim, (struct ccb_scsiio *)&ccb->csio))
2056             return;
2057         break;
2058
2059         /* perform geometry calculations */
2060     case XPT_CALC_GEOMETRY:
2061     {
2062         struct ccb_calc_geometry        *ccg = &ccb->ccg;
2063         u_int32_t                       secs_per_cylinder;
2064
2065         debug(2, "XPT_CALC_GEOMETRY %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2066
2067         if (sc->mly_controllerparam->bios_geometry == MLY_BIOSGEOM_8G) {
2068             ccg->heads = 255;
2069             ccg->secs_per_track = 63;
2070         } else {                                /* MLY_BIOSGEOM_2G */
2071             ccg->heads = 128;
2072             ccg->secs_per_track = 32;
2073         }
2074         secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2075         ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2076         ccb->ccb_h.status = CAM_REQ_CMP;
2077         break;
2078     }
2079
2080         /* handle path attribute inquiry */
2081     case XPT_PATH_INQ:
2082     {
2083         struct ccb_pathinq      *cpi = &ccb->cpi;
2084
2085         debug(2, "XPT_PATH_INQ %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2086
2087         cpi->version_num = 1;
2088         cpi->hba_inquiry = PI_TAG_ABLE;         /* XXX extra flags for physical channels? */
2089         cpi->target_sprt = 0;
2090         cpi->hba_misc = 0;
2091         cpi->max_target = MLY_MAX_TARGETS - 1;
2092         cpi->max_lun = MLY_MAX_LUNS - 1;
2093         cpi->initiator_id = sc->mly_controllerparam->initiator_id;
2094         strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2095         strncpy(cpi->hba_vid, "FreeBSD", HBA_IDLEN);
2096         strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2097         cpi->unit_number = cam_sim_unit(sim);
2098         cpi->bus_id = cam_sim_bus(sim);
2099         cpi->base_transfer_speed = 132 * 1024;  /* XXX what to set this to? */
2100         ccb->ccb_h.status = CAM_REQ_CMP;
2101         break;
2102     }
2103
2104     case XPT_GET_TRAN_SETTINGS:
2105     {
2106         struct ccb_trans_settings       *cts = &ccb->cts;
2107         int                             bus, target;
2108
2109         bus = cam_sim_bus(sim);
2110         target = cts->ccb_h.target_id;
2111         /* XXX validate bus/target? */
2112
2113         debug(2, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target);
2114         cts->valid = 0;
2115
2116         /* logical device? */
2117         if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_LOGICAL) {
2118             /* nothing special for these */
2119
2120         /* physical device? */
2121         } else if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_PHYSICAL) {
2122             /* allow CAM to try tagged transactions */
2123             cts->flags |= CCB_TRANS_TAG_ENB;
2124             cts->valid |= CCB_TRANS_TQ_VALID;
2125
2126             /* convert speed (MHz) to usec */
2127             if (sc->mly_btl[bus][target].mb_speed == 0) {
2128                 cts->sync_period = 1000000 / 5;
2129             } else {
2130                 cts->sync_period = 1000000 / sc->mly_btl[bus][target].mb_speed;
2131             }
2132
2133             /* convert bus width to CAM internal encoding */
2134             switch (sc->mly_btl[bus][target].mb_width) {
2135             case 32:
2136                 cts->bus_width = MSG_EXT_WDTR_BUS_32_BIT;
2137                 break;
2138             case 16:
2139                 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2140                 break;
2141             case 8:
2142             default:
2143                 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2144                 break;
2145             }
2146             cts->valid |= CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_BUS_WIDTH_VALID;
2147
2148             /* not a device, bail out */
2149         } else {
2150             cts->ccb_h.status = CAM_REQ_CMP_ERR;
2151             break;
2152         }
2153
2154         /* disconnect always OK */
2155         cts->flags |= CCB_TRANS_DISC_ENB;
2156         cts->valid |= CCB_TRANS_DISC_VALID;
2157
2158         cts->ccb_h.status = CAM_REQ_CMP;
2159         break;
2160     }
2161
2162     default:            /* we can't do this */
2163         debug(2, "unspported func_code = 0x%x", ccb->ccb_h.func_code);
2164         ccb->ccb_h.status = CAM_REQ_INVALID;
2165         break;
2166     }
2167
2168     xpt_done(ccb);
2169 }
2170
2171 /********************************************************************************
2172  * Handle an I/O operation requested by CAM
2173  */
2174 static int
2175 mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
2176 {
2177     struct mly_softc                    *sc = cam_sim_softc(sim);
2178     struct mly_command                  *mc;
2179     struct mly_command_scsi_small       *ss;
2180     int                                 bus, target;
2181     int                                 error;
2182     int                                 s;
2183
2184     bus = cam_sim_bus(sim);
2185     target = csio->ccb_h.target_id;
2186
2187     debug(2, "XPT_SCSI_IO %d:%d:%d", bus, target, csio->ccb_h.target_lun);
2188
2189     /* validate bus number */
2190     if (!MLY_BUS_IS_VALID(sc, bus)) {
2191         debug(0, " invalid bus %d", bus);
2192         csio->ccb_h.status = CAM_REQ_CMP_ERR;
2193     }
2194
2195     /*  check for I/O attempt to a protected device */
2196     if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_PROTECTED) {
2197         debug(2, "  device protected");
2198         csio->ccb_h.status = CAM_REQ_CMP_ERR;
2199     }
2200
2201     /* check for I/O attempt to nonexistent device */
2202     if (!(sc->mly_btl[bus][target].mb_flags & (MLY_BTL_LOGICAL | MLY_BTL_PHYSICAL))) {
2203         debug(2, "  device %d:%d does not exist", bus, target);
2204         csio->ccb_h.status = CAM_REQ_CMP_ERR;
2205     }
2206
2207     /* XXX increase if/when we support large SCSI commands */
2208     if (csio->cdb_len > MLY_CMD_SCSI_SMALL_CDB) {
2209         debug(0, "  command too large (%d > %d)", csio->cdb_len, MLY_CMD_SCSI_SMALL_CDB);
2210         csio->ccb_h.status = CAM_REQ_CMP_ERR;
2211     }
2212
2213     /* check that the CDB pointer is not to a physical address */
2214     if ((csio->ccb_h.flags & CAM_CDB_POINTER) && (csio->ccb_h.flags & CAM_CDB_PHYS)) {
2215         debug(0, "  CDB pointer is to physical address");
2216         csio->ccb_h.status = CAM_REQ_CMP_ERR;
2217     }
2218
2219     /* if there is data transfer, it must be to/from a virtual address */
2220     if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
2221         if (csio->ccb_h.flags & CAM_DATA_PHYS) {                /* we can't map it */
2222             debug(0, "  data pointer is to physical address");
2223             csio->ccb_h.status = CAM_REQ_CMP_ERR;
2224         }
2225         if (csio->ccb_h.flags & CAM_SCATTER_VALID) {    /* we want to do the s/g setup */
2226             debug(0, "  data has premature s/g setup");
2227             csio->ccb_h.status = CAM_REQ_CMP_ERR;
2228         }
2229     }
2230
2231     /* abandon aborted ccbs or those that have failed validation */
2232     if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
2233         debug(2, "abandoning CCB due to abort/validation failure");
2234         return(EINVAL);
2235     }
2236
2237     /*
2238      * Get a command, or push the ccb back to CAM and freeze the queue.
2239      */
2240     if ((error = mly_alloc_command(sc, &mc))) {
2241         s = splcam();
2242         xpt_freeze_simq(sim, 1);
2243         csio->ccb_h.status |= CAM_REQUEUE_REQ;
2244         sc->mly_qfrzn_cnt++;
2245         splx(s);
2246         return(error);
2247     }
2248     
2249     /* build the command */
2250     mc->mc_data = csio->data_ptr;
2251     mc->mc_length = csio->dxfer_len;
2252     mc->mc_complete = mly_cam_complete;
2253     mc->mc_private = csio;
2254
2255     /* save the bus number in the ccb for later recovery XXX should be a better way */
2256      csio->ccb_h.sim_priv.entries[0].field = bus;
2257
2258     /* build the packet for the controller */
2259     ss = &mc->mc_packet->scsi_small;
2260     ss->opcode = MDACMD_SCSI;
2261     if (csio->ccb_h.flags & CAM_DIS_DISCONNECT)
2262         ss->command_control.disable_disconnect = 1;
2263     if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2264         ss->command_control.data_direction = MLY_CCB_WRITE;
2265     ss->data_size = csio->dxfer_len;
2266     ss->addr.phys.lun = csio->ccb_h.target_lun;
2267     ss->addr.phys.target = csio->ccb_h.target_id;
2268     ss->addr.phys.channel = bus;
2269     if (csio->ccb_h.timeout < (60 * 1000)) {
2270         ss->timeout.value = csio->ccb_h.timeout / 1000;
2271         ss->timeout.scale = MLY_TIMEOUT_SECONDS;
2272     } else if (csio->ccb_h.timeout < (60 * 60 * 1000)) {
2273         ss->timeout.value = csio->ccb_h.timeout / (60 * 1000);
2274         ss->timeout.scale = MLY_TIMEOUT_MINUTES;
2275     } else {
2276         ss->timeout.value = csio->ccb_h.timeout / (60 * 60 * 1000);     /* overflow? */
2277         ss->timeout.scale = MLY_TIMEOUT_HOURS;
2278     }
2279     ss->maximum_sense_size = csio->sense_len;
2280     ss->cdb_length = csio->cdb_len;
2281     if (csio->ccb_h.flags & CAM_CDB_POINTER) {
2282         bcopy(csio->cdb_io.cdb_ptr, ss->cdb, csio->cdb_len);
2283     } else {
2284         bcopy(csio->cdb_io.cdb_bytes, ss->cdb, csio->cdb_len);
2285     }
2286
2287     /* give the command to the controller */
2288     if ((error = mly_start(mc))) {
2289         s = splcam();
2290         xpt_freeze_simq(sim, 1);
2291         csio->ccb_h.status |= CAM_REQUEUE_REQ;
2292         sc->mly_qfrzn_cnt++;
2293         splx(s);
2294         return(error);
2295     }
2296
2297     return(0);
2298 }
2299
2300 /********************************************************************************
2301  * Check for possibly-completed commands.
2302  */
2303 static void
2304 mly_cam_poll(struct cam_sim *sim)
2305 {
2306     struct mly_softc    *sc = cam_sim_softc(sim);
2307
2308     debug_called(2);
2309
2310     mly_done(sc);
2311 }
2312
2313 /********************************************************************************
2314  * Handle completion of a command - pass results back through the CCB
2315  */
2316 static void
2317 mly_cam_complete(struct mly_command *mc)
2318 {
2319     struct mly_softc            *sc = mc->mc_sc;
2320     struct ccb_scsiio           *csio = (struct ccb_scsiio *)mc->mc_private;
2321     struct scsi_inquiry_data    *inq = (struct scsi_inquiry_data *)csio->data_ptr;
2322     struct mly_btl              *btl;
2323     u_int8_t                    cmd;
2324     int                         bus, target;
2325     int                         s;
2326
2327     debug_called(2);
2328
2329     csio->scsi_status = mc->mc_status;
2330     switch(mc->mc_status) {
2331     case SCSI_STATUS_OK:
2332         /*
2333          * In order to report logical device type and status, we overwrite
2334          * the result of the INQUIRY command to logical devices.
2335          */
2336         bus = csio->ccb_h.sim_priv.entries[0].field;
2337         target = csio->ccb_h.target_id;
2338         /* XXX validate bus/target? */
2339         if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_LOGICAL) {
2340             if (csio->ccb_h.flags & CAM_CDB_POINTER) {
2341                 cmd = *csio->cdb_io.cdb_ptr;
2342             } else {
2343                 cmd = csio->cdb_io.cdb_bytes[0];
2344             }
2345             if (cmd == INQUIRY) {
2346                 btl = &sc->mly_btl[bus][target];
2347                 padstr(inq->vendor, mly_describe_code(mly_table_device_type, btl->mb_type), 8);
2348                 padstr(inq->product, mly_describe_code(mly_table_device_state, btl->mb_state), 16);
2349                 padstr(inq->revision, "", 4);
2350             }
2351         }
2352
2353         debug(2, "SCSI_STATUS_OK");
2354         csio->ccb_h.status = CAM_REQ_CMP;
2355         break;
2356
2357     case SCSI_STATUS_CHECK_COND:
2358         debug(1, "SCSI_STATUS_CHECK_COND  sense %d  resid %d", mc->mc_sense, mc->mc_resid);
2359         csio->ccb_h.status = CAM_SCSI_STATUS_ERROR;
2360         bzero(&csio->sense_data, SSD_FULL_SIZE);
2361         bcopy(mc->mc_packet, &csio->sense_data, mc->mc_sense);
2362         csio->sense_len = mc->mc_sense;
2363         csio->ccb_h.status |= CAM_AUTOSNS_VALID;
2364         csio->resid = mc->mc_resid;     /* XXX this is a signed value... */
2365         break;
2366
2367     case SCSI_STATUS_BUSY:
2368         debug(1, "SCSI_STATUS_BUSY");
2369         csio->ccb_h.status = CAM_SCSI_BUSY;
2370         break;
2371
2372     default:
2373         debug(1, "unknown status 0x%x", csio->scsi_status);
2374         csio->ccb_h.status = CAM_REQ_CMP_ERR;
2375         break;
2376     }
2377
2378     s = splcam();
2379     if (sc->mly_qfrzn_cnt) {
2380         csio->ccb_h.status |= CAM_RELEASE_SIMQ;
2381         sc->mly_qfrzn_cnt--;
2382     }
2383     splx(s);
2384
2385     xpt_done((union ccb *)csio);
2386     mly_release_command(mc);
2387 }
2388
2389 /********************************************************************************
2390  * Find a peripheral attahed at (bus),(target)
2391  */
2392 static struct cam_periph *
2393 mly_find_periph(struct mly_softc *sc, int bus, int target)
2394 {
2395     struct cam_periph   *periph;
2396     struct cam_path     *path;
2397     int                 status;
2398
2399     status = xpt_create_path(&path, NULL, cam_sim_path(sc->mly_cam_sim[bus]), target, 0);
2400     if (status == CAM_REQ_CMP) {
2401         periph = cam_periph_find(path, NULL);
2402         xpt_free_path(path);
2403     } else {
2404         periph = NULL;
2405     }
2406     return(periph);
2407 }
2408
2409 /********************************************************************************
2410  * Name the device at (bus)(target)
2411  */
2412 static int
2413 mly_name_device(struct mly_softc *sc, int bus, int target)
2414 {
2415     struct cam_periph   *periph;
2416
2417     if ((periph = mly_find_periph(sc, bus, target)) != NULL) {
2418         sprintf(sc->mly_btl[bus][target].mb_name, "%s%d", periph->periph_name, periph->unit_number);
2419         return(0);
2420     }
2421     sc->mly_btl[bus][target].mb_name[0] = 0;
2422     return(ENOENT);
2423 }
2424
2425 /********************************************************************************
2426  ********************************************************************************
2427                                                                  Hardware Control
2428  ********************************************************************************
2429  ********************************************************************************/
2430
2431 /********************************************************************************
2432  * Handshake with the firmware while the card is being initialised.
2433  */
2434 static int
2435 mly_fwhandshake(struct mly_softc *sc) 
2436 {
2437     u_int8_t    error, param0, param1;
2438     int         spinup = 0;
2439
2440     debug_called(1);
2441
2442     /* set HM_STSACK and let the firmware initialise */
2443     MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_STSACK);
2444     DELAY(1000);        /* too short? */
2445
2446     /* if HM_STSACK is still true, the controller is initialising */
2447     if (!MLY_IDBR_TRUE(sc, MLY_HM_STSACK))
2448         return(0);
2449     mly_printf(sc, "controller initialisation started\n");
2450
2451     /* spin waiting for initialisation to finish, or for a message to be delivered */
2452     while (MLY_IDBR_TRUE(sc, MLY_HM_STSACK)) {
2453         /* check for a message */
2454         if (MLY_ERROR_VALID(sc)) {
2455             error = MLY_GET_REG(sc, sc->mly_error_status) & ~MLY_MSG_EMPTY;
2456             param0 = MLY_GET_REG(sc, sc->mly_command_mailbox);
2457             param1 = MLY_GET_REG(sc, sc->mly_command_mailbox + 1);
2458
2459             switch(error) {
2460             case MLY_MSG_SPINUP:
2461                 if (!spinup) {
2462                     mly_printf(sc, "drive spinup in progress\n");
2463                     spinup = 1;                 /* only print this once (should print drive being spun?) */
2464                 }
2465                 break;
2466             case MLY_MSG_RACE_RECOVERY_FAIL:
2467                 mly_printf(sc, "mirror race recovery failed, one or more drives offline\n");
2468                 break;
2469             case MLY_MSG_RACE_IN_PROGRESS:
2470                 mly_printf(sc, "mirror race recovery in progress\n");
2471                 break;
2472             case MLY_MSG_RACE_ON_CRITICAL:
2473                 mly_printf(sc, "mirror race recovery on a critical drive\n");
2474                 break;
2475             case MLY_MSG_PARITY_ERROR:
2476                 mly_printf(sc, "FATAL MEMORY PARITY ERROR\n");
2477                 return(ENXIO);
2478             default:
2479                 mly_printf(sc, "unknown initialisation code 0x%x\n", error);
2480             }
2481         }
2482     }
2483     return(0);
2484 }
2485
2486 /********************************************************************************
2487  ********************************************************************************
2488                                                         Debugging and Diagnostics
2489  ********************************************************************************
2490  ********************************************************************************/
2491
2492 /********************************************************************************
2493  * Print some information about the controller.
2494  */
2495 static void
2496 mly_describe_controller(struct mly_softc *sc)
2497 {
2498     struct mly_ioctl_getcontrollerinfo  *mi = sc->mly_controllerinfo;
2499
2500     mly_printf(sc, "%16s, %d channel%s, firmware %d.%02d-%d-%02d (%02d%02d%02d%02d), %dMB RAM\n", 
2501                mi->controller_name, mi->physical_channels_present, (mi->physical_channels_present) > 1 ? "s" : "",
2502                mi->fw_major, mi->fw_minor, mi->fw_turn, mi->fw_build,   /* XXX turn encoding? */
2503                mi->fw_century, mi->fw_year, mi->fw_month, mi->fw_day,
2504                mi->memory_size);
2505
2506     if (bootverbose) {
2507         mly_printf(sc, "%s %s (%x), %dMHz %d-bit %.16s\n", 
2508                    mly_describe_code(mly_table_oemname, mi->oem_information), 
2509                    mly_describe_code(mly_table_controllertype, mi->controller_type), mi->controller_type,
2510                    mi->interface_speed, mi->interface_width, mi->interface_name);
2511         mly_printf(sc, "%dMB %dMHz %d-bit %s%s%s, cache %dMB\n",
2512                    mi->memory_size, mi->memory_speed, mi->memory_width, 
2513                    mly_describe_code(mly_table_memorytype, mi->memory_type),
2514                    mi->memory_parity ? "+parity": "",mi->memory_ecc ? "+ECC": "",
2515                    mi->cache_size);
2516         mly_printf(sc, "CPU: %s @ %dMHZ\n", 
2517                    mly_describe_code(mly_table_cputype, mi->cpu[0].type), mi->cpu[0].speed);
2518         if (mi->l2cache_size != 0)
2519             mly_printf(sc, "%dKB L2 cache\n", mi->l2cache_size);
2520         if (mi->exmemory_size != 0)
2521             mly_printf(sc, "%dMB %dMHz %d-bit private %s%s%s\n",
2522                        mi->exmemory_size, mi->exmemory_speed, mi->exmemory_width,
2523                        mly_describe_code(mly_table_memorytype, mi->exmemory_type),
2524                        mi->exmemory_parity ? "+parity": "",mi->exmemory_ecc ? "+ECC": "");
2525         mly_printf(sc, "battery backup %s\n", mi->bbu_present ? "present" : "not installed");
2526         mly_printf(sc, "maximum data transfer %d blocks, maximum sg entries/command %d\n",
2527                    mi->maximum_block_count, mi->maximum_sg_entries);
2528         mly_printf(sc, "logical devices present/critical/offline %d/%d/%d\n",
2529                    mi->logical_devices_present, mi->logical_devices_critical, mi->logical_devices_offline);
2530         mly_printf(sc, "physical devices present %d\n",
2531                    mi->physical_devices_present);
2532         mly_printf(sc, "physical disks present/offline %d/%d\n",
2533                    mi->physical_disks_present, mi->physical_disks_offline);
2534         mly_printf(sc, "%d physical channel%s, %d virtual channel%s of %d possible\n",
2535                    mi->physical_channels_present, mi->physical_channels_present == 1 ? "" : "s",
2536                    mi->virtual_channels_present, mi->virtual_channels_present == 1 ? "" : "s",
2537                    mi->virtual_channels_possible);
2538         mly_printf(sc, "%d parallel commands supported\n", mi->maximum_parallel_commands);
2539         mly_printf(sc, "%dMB flash ROM, %d of %d maximum cycles\n",
2540                    mi->flash_size, mi->flash_age, mi->flash_maximum_age);
2541     }
2542 }
2543
2544 #ifdef MLY_DEBUG
2545 /********************************************************************************
2546  * Print some controller state
2547  */
2548 static void
2549 mly_printstate(struct mly_softc *sc)
2550 {
2551     mly_printf(sc, "IDBR %02x  ODBR %02x  ERROR %02x  (%x %x %x)\n",
2552                   MLY_GET_REG(sc, sc->mly_idbr),
2553                   MLY_GET_REG(sc, sc->mly_odbr),
2554                   MLY_GET_REG(sc, sc->mly_error_status),
2555                   sc->mly_idbr,
2556                   sc->mly_odbr,
2557                   sc->mly_error_status);
2558     mly_printf(sc, "IMASK %02x  ISTATUS %02x\n",
2559                   MLY_GET_REG(sc, sc->mly_interrupt_mask),
2560                   MLY_GET_REG(sc, sc->mly_interrupt_status));
2561     mly_printf(sc, "COMMAND %02x %02x %02x %02x %02x %02x %02x %02x\n",
2562                   MLY_GET_REG(sc, sc->mly_command_mailbox),
2563                   MLY_GET_REG(sc, sc->mly_command_mailbox + 1),
2564                   MLY_GET_REG(sc, sc->mly_command_mailbox + 2),
2565                   MLY_GET_REG(sc, sc->mly_command_mailbox + 3),
2566                   MLY_GET_REG(sc, sc->mly_command_mailbox + 4),
2567                   MLY_GET_REG(sc, sc->mly_command_mailbox + 5),
2568                   MLY_GET_REG(sc, sc->mly_command_mailbox + 6),
2569                   MLY_GET_REG(sc, sc->mly_command_mailbox + 7));
2570     mly_printf(sc, "STATUS  %02x %02x %02x %02x %02x %02x %02x %02x\n",
2571                   MLY_GET_REG(sc, sc->mly_status_mailbox),
2572                   MLY_GET_REG(sc, sc->mly_status_mailbox + 1),
2573                   MLY_GET_REG(sc, sc->mly_status_mailbox + 2),
2574                   MLY_GET_REG(sc, sc->mly_status_mailbox + 3),
2575                   MLY_GET_REG(sc, sc->mly_status_mailbox + 4),
2576                   MLY_GET_REG(sc, sc->mly_status_mailbox + 5),
2577                   MLY_GET_REG(sc, sc->mly_status_mailbox + 6),
2578                   MLY_GET_REG(sc, sc->mly_status_mailbox + 7));
2579     mly_printf(sc, "        %04x        %08x\n",
2580                   MLY_GET_REG2(sc, sc->mly_status_mailbox),
2581                   MLY_GET_REG4(sc, sc->mly_status_mailbox + 4));
2582 }
2583
2584 struct mly_softc        *mly_softc0 = NULL;
2585 void
2586 mly_printstate0(void)
2587 {
2588     if (mly_softc0 != NULL)
2589         mly_printstate(mly_softc0);
2590 }
2591
2592 /********************************************************************************
2593  * Print a command
2594  */
2595 static void
2596 mly_print_command(struct mly_command *mc)
2597 {
2598     struct mly_softc    *sc = mc->mc_sc;
2599     
2600     mly_printf(sc, "COMMAND @ %p\n", mc);
2601     mly_printf(sc, "  slot      %d\n", mc->mc_slot);
2602     mly_printf(sc, "  status    0x%x\n", mc->mc_status);
2603     mly_printf(sc, "  sense len %d\n", mc->mc_sense);
2604     mly_printf(sc, "  resid     %d\n", mc->mc_resid);
2605     mly_printf(sc, "  packet    %p/0x%llx\n", mc->mc_packet, mc->mc_packetphys);
2606     if (mc->mc_packet != NULL)
2607         mly_print_packet(mc);
2608     mly_printf(sc, "  data      %p/%d\n", mc->mc_data, mc->mc_length);
2609     mly_printf(sc, "  flags     %b\n", mc->mc_flags, "\20\1busy\2complete\3slotted\4mapped\5datain\6dataout\n");
2610     mly_printf(sc, "  complete  %p\n", mc->mc_complete);
2611     mly_printf(sc, "  private   %p\n", mc->mc_private);
2612 }
2613
2614 /********************************************************************************
2615  * Print a command packet
2616  */
2617 static void
2618 mly_print_packet(struct mly_command *mc)
2619 {
2620     struct mly_softc                    *sc = mc->mc_sc;
2621     struct mly_command_generic          *ge = (struct mly_command_generic *)mc->mc_packet;
2622     struct mly_command_scsi_small       *ss = (struct mly_command_scsi_small *)mc->mc_packet;
2623     struct mly_command_scsi_large       *sl = (struct mly_command_scsi_large *)mc->mc_packet;
2624     struct mly_command_ioctl            *io = (struct mly_command_ioctl *)mc->mc_packet;
2625     int                                 transfer;
2626
2627     mly_printf(sc, "   command_id           %d\n", ge->command_id);
2628     mly_printf(sc, "   opcode               %d\n", ge->opcode);
2629     mly_printf(sc, "   command_control      fua %d  dpo %d  est %d  dd %s  nas %d ddis %d\n",
2630                   ge->command_control.force_unit_access,
2631                   ge->command_control.disable_page_out,
2632                   ge->command_control.extended_sg_table,
2633                   (ge->command_control.data_direction == MLY_CCB_WRITE) ? "WRITE" : "READ",
2634                   ge->command_control.no_auto_sense,
2635                   ge->command_control.disable_disconnect);
2636     mly_printf(sc, "   data_size            %d\n", ge->data_size);
2637     mly_printf(sc, "   sense_buffer_address 0x%llx\n", ge->sense_buffer_address);
2638     mly_printf(sc, "   lun                  %d\n", ge->addr.phys.lun);
2639     mly_printf(sc, "   target               %d\n", ge->addr.phys.target);
2640     mly_printf(sc, "   channel              %d\n", ge->addr.phys.channel);
2641     mly_printf(sc, "   logical device       %d\n", ge->addr.log.logdev);
2642     mly_printf(sc, "   controller           %d\n", ge->addr.phys.controller);
2643     mly_printf(sc, "   timeout              %d %s\n", 
2644                   ge->timeout.value,
2645                   (ge->timeout.scale == MLY_TIMEOUT_SECONDS) ? "seconds" : 
2646                   ((ge->timeout.scale == MLY_TIMEOUT_MINUTES) ? "minutes" : "hours"));
2647     mly_printf(sc, "   maximum_sense_size   %d\n", ge->maximum_sense_size);
2648     switch(ge->opcode) {
2649     case MDACMD_SCSIPT:
2650     case MDACMD_SCSI:
2651         mly_printf(sc, "   cdb length           %d\n", ss->cdb_length);
2652         mly_printf(sc, "   cdb                  %*D\n", ss->cdb_length, ss->cdb, " ");
2653         transfer = 1;
2654         break;
2655     case MDACMD_SCSILC:
2656     case MDACMD_SCSILCPT:
2657         mly_printf(sc, "   cdb length           %d\n", sl->cdb_length);
2658         mly_printf(sc, "   cdb                  0x%llx\n", sl->cdb_physaddr);
2659         transfer = 1;
2660         break;
2661     case MDACMD_IOCTL:
2662         mly_printf(sc, "   sub_ioctl            0x%x\n", io->sub_ioctl);
2663         switch(io->sub_ioctl) {
2664         case MDACIOCTL_SETMEMORYMAILBOX:
2665             mly_printf(sc, "   health_buffer_size   %d\n", 
2666                           io->param.setmemorymailbox.health_buffer_size);
2667             mly_printf(sc, "   health_buffer_phys   0x%llx\n",
2668                           io->param.setmemorymailbox.health_buffer_physaddr);
2669             mly_printf(sc, "   command_mailbox      0x%llx\n",
2670                           io->param.setmemorymailbox.command_mailbox_physaddr);
2671             mly_printf(sc, "   status_mailbox       0x%llx\n",
2672                           io->param.setmemorymailbox.status_mailbox_physaddr);
2673             transfer = 0;
2674             break;
2675
2676         case MDACIOCTL_SETREALTIMECLOCK:
2677         case MDACIOCTL_GETHEALTHSTATUS:
2678         case MDACIOCTL_GETCONTROLLERINFO:
2679         case MDACIOCTL_GETLOGDEVINFOVALID:
2680         case MDACIOCTL_GETPHYSDEVINFOVALID:
2681         case MDACIOCTL_GETPHYSDEVSTATISTICS:
2682         case MDACIOCTL_GETLOGDEVSTATISTICS:
2683         case MDACIOCTL_GETCONTROLLERSTATISTICS:
2684         case MDACIOCTL_GETBDT_FOR_SYSDRIVE:         
2685         case MDACIOCTL_CREATENEWCONF:
2686         case MDACIOCTL_ADDNEWCONF:
2687         case MDACIOCTL_GETDEVCONFINFO:
2688         case MDACIOCTL_GETFREESPACELIST:
2689         case MDACIOCTL_MORE:
2690         case MDACIOCTL_SETPHYSDEVPARAMETER:
2691         case MDACIOCTL_GETPHYSDEVPARAMETER:
2692         case MDACIOCTL_GETLOGDEVPARAMETER:
2693         case MDACIOCTL_SETLOGDEVPARAMETER:
2694             mly_printf(sc, "   param                %10D\n", io->param.data.param, " ");
2695             transfer = 1;
2696             break;
2697
2698         case MDACIOCTL_GETEVENT:
2699             mly_printf(sc, "   event                %d\n", 
2700                        io->param.getevent.sequence_number_low + ((u_int32_t)io->addr.log.logdev << 16));
2701             transfer = 1;
2702             break;
2703
2704         case MDACIOCTL_SETRAIDDEVSTATE:
2705             mly_printf(sc, "   state                %d\n", io->param.setraiddevstate.state);
2706             transfer = 0;
2707             break;
2708
2709         case MDACIOCTL_XLATEPHYSDEVTORAIDDEV:
2710             mly_printf(sc, "   raid_device          %d\n", io->param.xlatephysdevtoraiddev.raid_device);
2711             mly_printf(sc, "   controller           %d\n", io->param.xlatephysdevtoraiddev.controller);
2712             mly_printf(sc, "   channel              %d\n", io->param.xlatephysdevtoraiddev.channel);
2713             mly_printf(sc, "   target               %d\n", io->param.xlatephysdevtoraiddev.target);
2714             mly_printf(sc, "   lun                  %d\n", io->param.xlatephysdevtoraiddev.lun);
2715             transfer = 0;
2716             break;
2717
2718         case MDACIOCTL_GETGROUPCONFINFO:
2719             mly_printf(sc, "   group                %d\n", io->param.getgroupconfinfo.group);
2720             transfer = 1;
2721             break;
2722
2723         case MDACIOCTL_GET_SUBSYSTEM_DATA:
2724         case MDACIOCTL_SET_SUBSYSTEM_DATA:
2725         case MDACIOCTL_STARTDISOCVERY:
2726         case MDACIOCTL_INITPHYSDEVSTART:
2727         case MDACIOCTL_INITPHYSDEVSTOP:
2728         case MDACIOCTL_INITRAIDDEVSTART:
2729         case MDACIOCTL_INITRAIDDEVSTOP:
2730         case MDACIOCTL_REBUILDRAIDDEVSTART:
2731         case MDACIOCTL_REBUILDRAIDDEVSTOP:
2732         case MDACIOCTL_MAKECONSISTENTDATASTART:
2733         case MDACIOCTL_MAKECONSISTENTDATASTOP:
2734         case MDACIOCTL_CONSISTENCYCHECKSTART:
2735         case MDACIOCTL_CONSISTENCYCHECKSTOP:
2736         case MDACIOCTL_RESETDEVICE:
2737         case MDACIOCTL_FLUSHDEVICEDATA:
2738         case MDACIOCTL_PAUSEDEVICE:
2739         case MDACIOCTL_UNPAUSEDEVICE:
2740         case MDACIOCTL_LOCATEDEVICE:
2741         case MDACIOCTL_SETMASTERSLAVEMODE:
2742         case MDACIOCTL_DELETERAIDDEV:
2743         case MDACIOCTL_REPLACEINTERNALDEV:
2744         case MDACIOCTL_CLEARCONF:
2745         case MDACIOCTL_GETCONTROLLERPARAMETER:
2746         case MDACIOCTL_SETCONTRLLERPARAMETER:
2747         case MDACIOCTL_CLEARCONFSUSPMODE:
2748         case MDACIOCTL_STOREIMAGE:
2749         case MDACIOCTL_READIMAGE:
2750         case MDACIOCTL_FLASHIMAGES:
2751         case MDACIOCTL_RENAMERAIDDEV:
2752         default:                        /* no idea what to print */
2753             transfer = 0;
2754             break;
2755         }
2756         break;
2757
2758     case MDACMD_IOCTLCHECK:
2759     case MDACMD_MEMCOPY:
2760     default:
2761         transfer = 0;
2762         break;  /* print nothing */
2763     }
2764     if (transfer) {
2765         if (ge->command_control.extended_sg_table) {
2766             mly_printf(sc, "   sg table             0x%llx/%d\n",
2767                           ge->transfer.indirect.table_physaddr[0], ge->transfer.indirect.entries[0]);
2768         } else {
2769             mly_printf(sc, "   0000                 0x%llx/%lld\n",
2770                           ge->transfer.direct.sg[0].physaddr, ge->transfer.direct.sg[0].length);
2771             mly_printf(sc, "   0001                 0x%llx/%lld\n",
2772                           ge->transfer.direct.sg[1].physaddr, ge->transfer.direct.sg[1].length);
2773         }
2774     }
2775 }
2776
2777 /********************************************************************************
2778  * Panic in a slightly informative fashion
2779  */
2780 static void
2781 mly_panic(struct mly_softc *sc, char *reason)
2782 {
2783     mly_printstate(sc);
2784     panic(reason);
2785 }
2786
2787 /********************************************************************************
2788  * Print queue statistics, callable from DDB.
2789  */
2790 void
2791 mly_print_controller(int controller)
2792 {
2793     struct mly_softc    *sc;
2794     
2795     if ((sc = devclass_get_softc(devclass_find("mly"), controller)) == NULL) {
2796         printf("mly: controller %d invalid\n", controller);
2797     } else {
2798         device_printf(sc->mly_dev, "queue    curr max\n");
2799         device_printf(sc->mly_dev, "free     %04d/%04d\n", 
2800                       sc->mly_qstat[MLYQ_FREE].q_length, sc->mly_qstat[MLYQ_FREE].q_max);
2801         device_printf(sc->mly_dev, "busy     %04d/%04d\n", 
2802                       sc->mly_qstat[MLYQ_BUSY].q_length, sc->mly_qstat[MLYQ_BUSY].q_max);
2803         device_printf(sc->mly_dev, "complete %04d/%04d\n", 
2804                       sc->mly_qstat[MLYQ_COMPLETE].q_length, sc->mly_qstat[MLYQ_COMPLETE].q_max);
2805     }
2806 }
2807 #endif
2808
2809
2810 /********************************************************************************
2811  ********************************************************************************
2812                                                          Control device interface
2813  ********************************************************************************
2814  ********************************************************************************/
2815
2816 /********************************************************************************
2817  * Accept an open operation on the control device.
2818  */
2819 static int
2820 mly_user_open(struct cdev *dev, int flags, int fmt, struct thread *td)
2821 {
2822     int                 unit = minor(dev);
2823     struct mly_softc    *sc = devclass_get_softc(devclass_find("mly"), unit);
2824
2825     sc->mly_state |= MLY_STATE_OPEN;
2826     return(0);
2827 }
2828
2829 /********************************************************************************
2830  * Accept the last close on the control device.
2831  */
2832 static int
2833 mly_user_close(struct cdev *dev, int flags, int fmt, struct thread *td)
2834 {
2835     int                 unit = minor(dev);
2836     struct mly_softc    *sc = devclass_get_softc(devclass_find("mly"), unit);
2837
2838     sc->mly_state &= ~MLY_STATE_OPEN;
2839     return (0);
2840 }
2841
2842 /********************************************************************************
2843  * Handle controller-specific control operations.
2844  */
2845 static int
2846 mly_user_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
2847                                 int32_t flag, struct thread *td)
2848 {
2849     struct mly_softc            *sc = (struct mly_softc *)dev->si_drv1;
2850     struct mly_user_command     *uc = (struct mly_user_command *)addr;
2851     struct mly_user_health      *uh = (struct mly_user_health *)addr;
2852     
2853     switch(cmd) {
2854     case MLYIO_COMMAND:
2855         return(mly_user_command(sc, uc));
2856     case MLYIO_HEALTH:
2857         return(mly_user_health(sc, uh));
2858     default:
2859         return(ENOIOCTL);
2860     }
2861 }
2862
2863 /********************************************************************************
2864  * Execute a command passed in from userspace.
2865  *
2866  * The control structure contains the actual command for the controller, as well
2867  * as the user-space data pointer and data size, and an optional sense buffer
2868  * size/pointer.  On completion, the data size is adjusted to the command
2869  * residual, and the sense buffer size to the size of the returned sense data.
2870  * 
2871  */
2872 static int
2873 mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
2874 {
2875     struct mly_command  *mc;
2876     int                 error, s;
2877
2878     /* allocate a command */
2879     if (mly_alloc_command(sc, &mc)) {
2880         error = ENOMEM;
2881         goto out;               /* XXX Linux version will wait for a command */
2882     }
2883
2884     /* handle data size/direction */
2885     mc->mc_length = (uc->DataTransferLength >= 0) ? uc->DataTransferLength : -uc->DataTransferLength;
2886     if (mc->mc_length > 0) {
2887         if ((mc->mc_data = malloc(mc->mc_length, M_DEVBUF, M_NOWAIT)) == NULL) {
2888             error = ENOMEM;
2889             goto out;
2890         }
2891     }
2892     if (uc->DataTransferLength > 0) {
2893         mc->mc_flags |= MLY_CMD_DATAIN;
2894         bzero(mc->mc_data, mc->mc_length);
2895     }
2896     if (uc->DataTransferLength < 0) {
2897         mc->mc_flags |= MLY_CMD_DATAOUT;
2898         if ((error = copyin(uc->DataTransferBuffer, mc->mc_data, mc->mc_length)) != 0)
2899             goto out;
2900     }
2901
2902     /* copy the controller command */
2903     bcopy(&uc->CommandMailbox, mc->mc_packet, sizeof(uc->CommandMailbox));
2904
2905     /* clear command completion handler so that we get woken up */
2906     mc->mc_complete = NULL;
2907
2908     /* execute the command */
2909     if ((error = mly_start(mc)) != 0)
2910         goto out;
2911     s = splcam();
2912     while (!(mc->mc_flags & MLY_CMD_COMPLETE))
2913         tsleep(mc, PRIBIO, "mlyioctl", 0);
2914     splx(s);
2915
2916     /* return the data to userspace */
2917     if (uc->DataTransferLength > 0)
2918         if ((error = copyout(mc->mc_data, uc->DataTransferBuffer, mc->mc_length)) != 0)
2919             goto out;
2920     
2921     /* return the sense buffer to userspace */
2922     if ((uc->RequestSenseLength > 0) && (mc->mc_sense > 0)) {
2923         if ((error = copyout(mc->mc_packet, uc->RequestSenseBuffer, 
2924                              min(uc->RequestSenseLength, mc->mc_sense))) != 0)
2925             goto out;
2926     }
2927     
2928     /* return command results to userspace (caller will copy out) */
2929     uc->DataTransferLength = mc->mc_resid;
2930     uc->RequestSenseLength = min(uc->RequestSenseLength, mc->mc_sense);
2931     uc->CommandStatus = mc->mc_status;
2932     error = 0;
2933
2934  out:
2935     if (mc->mc_data != NULL)
2936         free(mc->mc_data, M_DEVBUF);
2937     if (mc != NULL)
2938         mly_release_command(mc);
2939     return(error);
2940 }
2941
2942 /********************************************************************************
2943  * Return health status to userspace.  If the health change index in the user
2944  * structure does not match that currently exported by the controller, we
2945  * return the current status immediately.  Otherwise, we block until either
2946  * interrupted or new status is delivered.
2947  */
2948 static int
2949 mly_user_health(struct mly_softc *sc, struct mly_user_health *uh)
2950 {
2951     struct mly_health_status            mh;
2952     int                                 error, s;
2953     
2954     /* fetch the current health status from userspace */
2955     if ((error = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh))) != 0)
2956         return(error);
2957
2958     /* spin waiting for a status update */
2959     s = splcam();
2960     error = EWOULDBLOCK;
2961     while ((error != 0) && (sc->mly_event_change == mh.change_counter))
2962         error = tsleep(&sc->mly_event_change, PRIBIO | PCATCH, "mlyhealth", 0);
2963     splx(s);
2964     
2965     /* copy the controller's health status buffer out (there is a race here if it changes again) */
2966     error = copyout(&sc->mly_mmbox->mmm_health.status, uh->HealthStatusBuffer, 
2967                     sizeof(uh->HealthStatusBuffer));
2968     return(error);
2969 }
2970
2971 static int
2972 mly_timeout(struct mly_softc *sc)
2973 {
2974         struct mly_command *mc;
2975         int deadline;
2976
2977         deadline = time_second - MLY_CMD_TIMEOUT;
2978         TAILQ_FOREACH(mc, &sc->mly_busy, mc_link) {
2979                 if ((mc->mc_timestamp < deadline)) {
2980                         device_printf(sc->mly_dev,
2981                             "COMMAND %p TIMEOUT AFTER %d SECONDS\n", mc,
2982                             (int)(time_second - mc->mc_timestamp));
2983                 }
2984         }
2985
2986         timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz);
2987
2988         return (0);
2989 }