xref: /dragonfly/sys/dev/raid/mly/mly.c (revision af79c6e5)
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: src/sys/dev/mly/mly.c,v 1.3.2.3 2001/03/05 20:17:24 msmith Exp $
28  *	$DragonFly: src/sys/dev/raid/mly/mly.c,v 1.6 2003/08/07 21:17:09 dillon Exp $
29  */
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/malloc.h>
34 #include <sys/kernel.h>
35 #include <sys/bus.h>
36 #include <sys/conf.h>
37 #include <sys/ctype.h>
38 #include <sys/ioccom.h>
39 #include <sys/stat.h>
40 
41 #include <machine/bus_memio.h>
42 #include <machine/bus.h>
43 #include <machine/resource.h>
44 #include <sys/rman.h>
45 
46 #include <bus/cam/scsi/scsi_all.h>
47 
48 #include "mlyreg.h"
49 #include "mlyio.h"
50 #include "mlyvar.h"
51 #define MLY_DEFINE_TABLES
52 #include "mly_tables.h"
53 
54 static int	mly_get_controllerinfo(struct mly_softc *sc);
55 static void	mly_scan_devices(struct mly_softc *sc);
56 static void	mly_rescan_btl(struct mly_softc *sc, int bus, int target);
57 static void	mly_complete_rescan(struct mly_command *mc);
58 static int	mly_get_eventstatus(struct mly_softc *sc);
59 static int	mly_enable_mmbox(struct mly_softc *sc);
60 static int	mly_flush(struct mly_softc *sc);
61 static int	mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data,
62 			  size_t datasize, u_int8_t *status, void *sense_buffer, size_t *sense_length);
63 static void	mly_fetch_event(struct mly_softc *sc);
64 static void	mly_complete_event(struct mly_command *mc);
65 static void	mly_process_event(struct mly_softc *sc, struct mly_event *me);
66 static void	mly_periodic(void *data);
67 
68 static int	mly_immediate_command(struct mly_command *mc);
69 static int	mly_start(struct mly_command *mc);
70 static void	mly_complete(void *context, int pending);
71 
72 static void	mly_alloc_commands_map(void *arg, bus_dma_segment_t *segs, int nseg, int error);
73 static int	mly_alloc_commands(struct mly_softc *sc);
74 static void	mly_map_command(struct mly_command *mc);
75 static void	mly_unmap_command(struct mly_command *mc);
76 
77 static int	mly_fwhandshake(struct mly_softc *sc);
78 
79 static void	mly_describe_controller(struct mly_softc *sc);
80 #ifdef MLY_DEBUG
81 static void	mly_printstate(struct mly_softc *sc);
82 static void	mly_print_command(struct mly_command *mc);
83 static void	mly_print_packet(struct mly_command *mc);
84 static void	mly_panic(struct mly_softc *sc, char *reason);
85 #endif
86 void		mly_print_controller(int controller);
87 
88 static d_open_t		mly_user_open;
89 static d_close_t	mly_user_close;
90 static d_ioctl_t	mly_user_ioctl;
91 static int	mly_user_command(struct mly_softc *sc, struct mly_user_command *uc);
92 static int	mly_user_health(struct mly_softc *sc, struct mly_user_health *uh);
93 
94 #define MLY_CDEV_MAJOR  158
95 
96 static struct cdevsw mly_cdevsw = {
97     /* name */	"mly",
98     /* cmaj */	MLY_CDEV_MAJOR,
99     /* flags */	0,
100     /* port */	NULL,
101     /* autoq */	0,
102 
103     mly_user_open,
104     mly_user_close,
105     noread,
106     nowrite,
107     mly_user_ioctl,
108     nopoll,
109     nommap,
110     nostrategy,
111     nodump,
112     nopsize
113 };
114 
115 /********************************************************************************
116  ********************************************************************************
117                                                                  Device Interface
118  ********************************************************************************
119  ********************************************************************************/
120 
121 /********************************************************************************
122  * Initialise the controller and softc
123  */
124 int
125 mly_attach(struct mly_softc *sc)
126 {
127     int		error;
128 
129     debug_called(1);
130 
131     /*
132      * Initialise per-controller queues.
133      */
134     mly_initq_free(sc);
135     mly_initq_ready(sc);
136     mly_initq_busy(sc);
137     mly_initq_complete(sc);
138 
139 #if __FreeBSD_version >= 500005
140     /*
141      * Initialise command-completion task.
142      */
143     TASK_INIT(&sc->mly_task_complete, 0, mly_complete, sc);
144 #endif
145 
146     /* disable interrupts before we start talking to the controller */
147     MLY_MASK_INTERRUPTS(sc);
148 
149     /*
150      * Wait for the controller to come ready, handshake with the firmware if required.
151      * This is typically only necessary on platforms where the controller BIOS does not
152      * run.
153      */
154     if ((error = mly_fwhandshake(sc)))
155 	return(error);
156 
157     /*
158      * Allocate command buffers
159      */
160     if ((error = mly_alloc_commands(sc)))
161 	return(error);
162 
163     /*
164      * Obtain controller feature information
165      */
166     if ((error = mly_get_controllerinfo(sc)))
167 	return(error);
168 
169     /*
170      * Get the current event counter for health purposes, populate the initial
171      * health status buffer.
172      */
173     if ((error = mly_get_eventstatus(sc)))
174 	return(error);
175 
176     /*
177      * Enable memory-mailbox mode
178      */
179     if ((error = mly_enable_mmbox(sc)))
180 	return(error);
181 
182     /*
183      * Attach to CAM.
184      */
185     if ((error = mly_cam_attach(sc)))
186 	return(error);
187 
188     /*
189      * Print a little information about the controller
190      */
191     mly_describe_controller(sc);
192 
193     /*
194      * Mark all attached devices for rescan
195      */
196     mly_scan_devices(sc);
197 
198     /*
199      * Instigate the first status poll immediately.  Rescan completions won't
200      * happen until interrupts are enabled, which should still be before
201      * the SCSI subsystem gets to us. (XXX assuming CAM and interrupt-driven
202      * discovery here...)
203      */
204     mly_periodic((void *)sc);
205 
206     /*
207      * Create the control device.
208      */
209     sc->mly_dev_t = make_dev(&mly_cdevsw, device_get_unit(sc->mly_dev), UID_ROOT, GID_OPERATOR,
210 			     S_IRUSR | S_IWUSR, "mly%d", device_get_unit(sc->mly_dev));
211     sc->mly_dev_t->si_drv1 = sc;
212 
213     /* enable interrupts now */
214     MLY_UNMASK_INTERRUPTS(sc);
215 
216     return(0);
217 }
218 
219 /********************************************************************************
220  * Bring the controller to a state where it can be safely left alone.
221  */
222 void
223 mly_detach(struct mly_softc *sc)
224 {
225 
226     debug_called(1);
227 
228     /* kill the periodic event */
229     untimeout(mly_periodic, sc, sc->mly_periodic);
230 
231     sc->mly_state |= MLY_STATE_SUSPEND;
232 
233     /* flush controller */
234     mly_printf(sc, "flushing cache...");
235     printf("%s\n", mly_flush(sc) ? "failed" : "done");
236 
237     MLY_MASK_INTERRUPTS(sc);
238 }
239 
240 /********************************************************************************
241  ********************************************************************************
242                                                                  Command Wrappers
243  ********************************************************************************
244  ********************************************************************************/
245 
246 /********************************************************************************
247  * Fill in the mly_controllerinfo and mly_controllerparam fields in the softc.
248  */
249 static int
250 mly_get_controllerinfo(struct mly_softc *sc)
251 {
252     struct mly_command_ioctl	mci;
253     u_int8_t			status;
254     int				error;
255 
256     debug_called(1);
257 
258     if (sc->mly_controllerinfo != NULL)
259 	free(sc->mly_controllerinfo, M_DEVBUF);
260 
261     /* build the getcontrollerinfo ioctl and send it */
262     bzero(&mci, sizeof(mci));
263     sc->mly_controllerinfo = NULL;
264     mci.sub_ioctl = MDACIOCTL_GETCONTROLLERINFO;
265     if ((error = mly_ioctl(sc, &mci, (void **)&sc->mly_controllerinfo, sizeof(*sc->mly_controllerinfo),
266 			   &status, NULL, NULL)))
267 	return(error);
268     if (status != 0)
269 	return(EIO);
270 
271     if (sc->mly_controllerparam != NULL)
272 	free(sc->mly_controllerparam, M_DEVBUF);
273 
274     /* build the getcontrollerparameter ioctl and send it */
275     bzero(&mci, sizeof(mci));
276     sc->mly_controllerparam = NULL;
277     mci.sub_ioctl = MDACIOCTL_GETCONTROLLERPARAMETER;
278     if ((error = mly_ioctl(sc, &mci, (void **)&sc->mly_controllerparam, sizeof(*sc->mly_controllerparam),
279 			   &status, NULL, NULL)))
280 	return(error);
281     if (status != 0)
282 	return(EIO);
283 
284     return(0);
285 }
286 
287 /********************************************************************************
288  * Schedule all possible devices for a rescan.
289  *
290  */
291 static void
292 mly_scan_devices(struct mly_softc *sc)
293 {
294     int		bus, target, nchn;
295 
296     debug_called(1);
297 
298     /*
299      * Clear any previous BTL information.
300      */
301     bzero(&sc->mly_btl, sizeof(sc->mly_btl));
302 
303     /*
304      * Mark all devices as requiring a rescan, and let the early periodic scan collect them.
305      */
306     nchn = sc->mly_controllerinfo->physical_channels_present +
307 	sc->mly_controllerinfo->virtual_channels_present;
308     for (bus = 0; bus < nchn; bus++)
309 	for (target = 0; target < MLY_MAX_TARGETS; target++)
310 	    sc->mly_btl[bus][target].mb_flags = MLY_BTL_RESCAN;
311 
312 }
313 
314 /********************************************************************************
315  * Rescan a device, possibly as a consequence of getting an event which suggests
316  * that it may have changed.
317  */
318 static void
319 mly_rescan_btl(struct mly_softc *sc, int bus, int target)
320 {
321     struct mly_command		*mc;
322     struct mly_command_ioctl	*mci;
323 
324     debug_called(2);
325 
326     /* get a command */
327     mc = NULL;
328     if (mly_alloc_command(sc, &mc))
329 	return;				/* we'll be retried soon */
330 
331     /* set up the data buffer */
332     if ((mc->mc_data = malloc(sizeof(union mly_devinfo), M_DEVBUF, M_NOWAIT)) == NULL) {
333 	mly_release_command(mc);
334 	return;				/* we'll get retried the next time a command completes */
335     }
336     bzero(mc->mc_data, sizeof(union mly_devinfo));
337     mc->mc_flags |= MLY_CMD_DATAIN;
338     mc->mc_complete = mly_complete_rescan;
339 
340     sc->mly_btl[bus][target].mb_flags &= ~MLY_BTL_RESCAN;
341 
342     /*
343      * Build the ioctl.
344      *
345      * At this point we are committed to sending this request, as it
346      * will be the only one constructed for this particular update.
347      */
348     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
349     mci->opcode = MDACMD_IOCTL;
350     mci->addr.phys.controller = 0;
351     mci->timeout.value = 30;
352     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
353     if (bus >= sc->mly_controllerinfo->physical_channels_present) {
354 	mc->mc_length = mci->data_size = sizeof(struct mly_ioctl_getlogdevinfovalid);
355 	mci->sub_ioctl = MDACIOCTL_GETLOGDEVINFOVALID;
356 	mci->addr.log.logdev = ((bus - sc->mly_controllerinfo->physical_channels_present) * MLY_MAX_TARGETS)
357 	    + target;
358 	debug(2, "logical device %d", mci->addr.log.logdev);
359     } else {
360 	mc->mc_length = mci->data_size = sizeof(struct mly_ioctl_getphysdevinfovalid);
361 	mci->sub_ioctl = MDACIOCTL_GETPHYSDEVINFOVALID;
362 	mci->addr.phys.lun = 0;
363 	mci->addr.phys.target = target;
364 	mci->addr.phys.channel = bus;
365 	debug(2, "physical device %d:%d", mci->addr.phys.channel, mci->addr.phys.target);
366     }
367 
368     /*
369      * Use the ready queue to get this command dispatched.
370      */
371     mly_enqueue_ready(mc);
372     mly_startio(sc);
373 }
374 
375 /********************************************************************************
376  * Handle the completion of a rescan operation
377  */
378 static void
379 mly_complete_rescan(struct mly_command *mc)
380 {
381     struct mly_softc				*sc = mc->mc_sc;
382     struct mly_ioctl_getlogdevinfovalid		*ldi;
383     struct mly_ioctl_getphysdevinfovalid	*pdi;
384     int						bus, target;
385 
386     debug_called(2);
387 
388     /* iff the command completed OK, we should use the result to update our data */
389     if (mc->mc_status == 0) {
390 	if (mc->mc_length == sizeof(*ldi)) {
391 	    ldi = (struct mly_ioctl_getlogdevinfovalid *)mc->mc_data;
392 	    bus = MLY_LOGDEV_BUS(sc, ldi->logical_device_number);
393 	    target = MLY_LOGDEV_TARGET(ldi->logical_device_number);
394 	    sc->mly_btl[bus][target].mb_flags = MLY_BTL_LOGICAL;	/* clears all other flags */
395 	    sc->mly_btl[bus][target].mb_type = ldi->raid_level;
396 	    sc->mly_btl[bus][target].mb_state = ldi->state;
397 	    debug(2, "BTL rescan for %d returns %s, %s", ldi->logical_device_number,
398 		  mly_describe_code(mly_table_device_type, ldi->raid_level),
399 		  mly_describe_code(mly_table_device_state, ldi->state));
400 	} else if (mc->mc_length == sizeof(*pdi)) {
401 	    pdi = (struct mly_ioctl_getphysdevinfovalid *)mc->mc_data;
402 	    bus = pdi->channel;
403 	    target = pdi->target;
404 	    sc->mly_btl[bus][target].mb_flags = MLY_BTL_PHYSICAL;	/* clears all other flags */
405 	    sc->mly_btl[bus][target].mb_type = MLY_DEVICE_TYPE_PHYSICAL;
406 	    sc->mly_btl[bus][target].mb_state = pdi->state;
407 	    sc->mly_btl[bus][target].mb_speed = pdi->speed;
408 	    sc->mly_btl[bus][target].mb_width = pdi->width;
409 	    if (pdi->state != MLY_DEVICE_STATE_UNCONFIGURED)
410 		sc->mly_btl[bus][target].mb_flags |= MLY_BTL_PROTECTED;
411 	    debug(2, "BTL rescan for %d:%d returns %s", bus, target,
412 		  mly_describe_code(mly_table_device_state, pdi->state));
413 	} else {
414 	    mly_printf(sc, "BTL rescan result corrupted\n");
415 	}
416     } else {
417 	/*
418 	 * A request sent for a device beyond the last device present will fail.
419 	 * We don't care about this, so we do nothing about it.
420 	 */
421     }
422     free(mc->mc_data, M_DEVBUF);
423     mly_release_command(mc);
424 }
425 
426 /********************************************************************************
427  * Get the current health status and set the 'next event' counter to suit.
428  */
429 static int
430 mly_get_eventstatus(struct mly_softc *sc)
431 {
432     struct mly_command_ioctl	mci;
433     struct mly_health_status	*mh;
434     u_int8_t			status;
435     int				error;
436 
437     /* build the gethealthstatus ioctl and send it */
438     bzero(&mci, sizeof(mci));
439     mh = NULL;
440     mci.sub_ioctl = MDACIOCTL_GETHEALTHSTATUS;
441 
442     if ((error = mly_ioctl(sc, &mci, (void **)&mh, sizeof(*mh), &status, NULL, NULL)))
443 	return(error);
444     if (status != 0)
445 	return(EIO);
446 
447     /* get the event counter */
448     sc->mly_event_change = mh->change_counter;
449     sc->mly_event_waiting = mh->next_event;
450     sc->mly_event_counter = mh->next_event;
451 
452     /* save the health status into the memory mailbox */
453     bcopy(mh, &sc->mly_mmbox->mmm_health.status, sizeof(*mh));
454 
455     debug(1, "initial change counter %d, event counter %d", mh->change_counter, mh->next_event);
456 
457     free(mh, M_DEVBUF);
458     return(0);
459 }
460 
461 /********************************************************************************
462  * Enable the memory mailbox mode.
463  */
464 static int
465 mly_enable_mmbox(struct mly_softc *sc)
466 {
467     struct mly_command_ioctl	mci;
468     u_int8_t			*sp, status;
469     int				error;
470 
471     debug_called(1);
472 
473     /* build the ioctl and send it */
474     bzero(&mci, sizeof(mci));
475     mci.sub_ioctl = MDACIOCTL_SETMEMORYMAILBOX;
476     /* set buffer addresses */
477     mci.param.setmemorymailbox.command_mailbox_physaddr =
478 	sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_command);
479     mci.param.setmemorymailbox.status_mailbox_physaddr =
480 	sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_status);
481     mci.param.setmemorymailbox.health_buffer_physaddr =
482 	sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_health);
483 
484     /* set buffer sizes - abuse of data_size field is revolting */
485     sp = (u_int8_t *)&mci.data_size;
486     sp[0] = ((sizeof(union mly_command_packet) * MLY_MMBOX_COMMANDS) / 1024);
487     sp[1] = (sizeof(union mly_status_packet) * MLY_MMBOX_STATUS) / 1024;
488     mci.param.setmemorymailbox.health_buffer_size = sizeof(union mly_health_region) / 1024;
489 
490     debug(1, "memory mailbox at %p (0x%llx/%d 0x%llx/%d 0x%llx/%d", sc->mly_mmbox,
491 	  mci.param.setmemorymailbox.command_mailbox_physaddr, sp[0],
492 	  mci.param.setmemorymailbox.status_mailbox_physaddr, sp[1],
493 	  mci.param.setmemorymailbox.health_buffer_physaddr,
494 	  mci.param.setmemorymailbox.health_buffer_size);
495 
496     if ((error = mly_ioctl(sc, &mci, NULL, 0, &status, NULL, NULL)))
497 	return(error);
498     if (status != 0)
499 	return(EIO);
500     sc->mly_state |= MLY_STATE_MMBOX_ACTIVE;
501     debug(1, "memory mailbox active");
502     return(0);
503 }
504 
505 /********************************************************************************
506  * Flush all pending I/O from the controller.
507  */
508 static int
509 mly_flush(struct mly_softc *sc)
510 {
511     struct mly_command_ioctl	mci;
512     u_int8_t			status;
513     int				error;
514 
515     debug_called(1);
516 
517     /* build the ioctl */
518     bzero(&mci, sizeof(mci));
519     mci.sub_ioctl = MDACIOCTL_FLUSHDEVICEDATA;
520     mci.param.deviceoperation.operation_device = MLY_OPDEVICE_PHYSICAL_CONTROLLER;
521 
522     /* pass it off to the controller */
523     if ((error = mly_ioctl(sc, &mci, NULL, 0, &status, NULL, NULL)))
524 	return(error);
525 
526     return((status == 0) ? 0 : EIO);
527 }
528 
529 /********************************************************************************
530  * Perform an ioctl command.
531  *
532  * If (data) is not NULL, the command requires data transfer.  If (*data) is NULL
533  * the command requires data transfer from the controller, and we will allocate
534  * a buffer for it.  If (*data) is not NULL, the command requires data transfer
535  * to the controller.
536  *
537  * XXX passing in the whole ioctl structure is ugly.  Better ideas?
538  *
539  * XXX we don't even try to handle the case where datasize > 4k.  We should.
540  */
541 static int
542 mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data, size_t datasize,
543 	  u_int8_t *status, void *sense_buffer, size_t *sense_length)
544 {
545     struct mly_command		*mc;
546     struct mly_command_ioctl	*mci;
547     int				error;
548 
549     debug_called(1);
550 
551     mc = NULL;
552     if (mly_alloc_command(sc, &mc)) {
553 	error = ENOMEM;
554 	goto out;
555     }
556 
557     /* copy the ioctl structure, but save some important fields and then fixup */
558     mci = &mc->mc_packet->ioctl;
559     ioctl->sense_buffer_address = mci->sense_buffer_address;
560     ioctl->maximum_sense_size = mci->maximum_sense_size;
561     *mci = *ioctl;
562     mci->opcode = MDACMD_IOCTL;
563     mci->timeout.value = 30;
564     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
565 
566     /* handle the data buffer */
567     if (data != NULL) {
568 	if (*data == NULL) {
569 	    /* allocate data buffer */
570 	    if ((mc->mc_data = malloc(datasize, M_DEVBUF, M_NOWAIT)) == NULL) {
571 		error = ENOMEM;
572 		goto out;
573 	    }
574 	    mc->mc_flags |= MLY_CMD_DATAIN;
575 	} else {
576 	    mc->mc_data = *data;
577 	    mc->mc_flags |= MLY_CMD_DATAOUT;
578 	}
579 	mc->mc_length = datasize;
580 	mc->mc_packet->generic.data_size = datasize;
581     }
582 
583     /* run the command */
584     if ((error = mly_immediate_command(mc)))
585 	goto out;
586 
587     /* clean up and return any data */
588     *status = mc->mc_status;
589     if ((mc->mc_sense > 0) && (sense_buffer != NULL)) {
590 	bcopy(mc->mc_packet, sense_buffer, mc->mc_sense);
591 	*sense_length = mc->mc_sense;
592 	goto out;
593     }
594 
595     /* should we return a data pointer? */
596     if ((data != NULL) && (*data == NULL))
597 	*data = mc->mc_data;
598 
599     /* command completed OK */
600     error = 0;
601 
602 out:
603     if (mc != NULL) {
604 	/* do we need to free a data buffer we allocated? */
605 	if (error && (mc->mc_data != NULL) && (*data == NULL))
606 	    free(mc->mc_data, M_DEVBUF);
607 	mly_release_command(mc);
608     }
609     return(error);
610 }
611 
612 /********************************************************************************
613  * Fetch one event from the controller.
614  */
615 static void
616 mly_fetch_event(struct mly_softc *sc)
617 {
618     struct mly_command		*mc;
619     struct mly_command_ioctl	*mci;
620     int				s;
621     u_int32_t			event;
622 
623     debug_called(2);
624 
625     /* get a command */
626     mc = NULL;
627     if (mly_alloc_command(sc, &mc))
628 	return;				/* we'll get retried the next time a command completes */
629 
630     /* set up the data buffer */
631     if ((mc->mc_data = malloc(sizeof(struct mly_event), M_DEVBUF, M_NOWAIT)) == NULL) {
632 	mly_release_command(mc);
633 	return;				/* we'll get retried the next time a command completes */
634     }
635     bzero(mc->mc_data, sizeof(struct mly_event));
636     mc->mc_length = sizeof(struct mly_event);
637     mc->mc_flags |= MLY_CMD_DATAIN;
638     mc->mc_complete = mly_complete_event;
639 
640     /*
641      * Get an event number to fetch.  It's possible that we've raced with another
642      * context for the last event, in which case there will be no more events.
643      */
644     s = splcam();
645     if (sc->mly_event_counter == sc->mly_event_waiting) {
646 	mly_release_command(mc);
647 	splx(s);
648 	return;
649     }
650     event = sc->mly_event_counter++;
651     splx(s);
652 
653     /*
654      * Build the ioctl.
655      *
656      * At this point we are committed to sending this request, as it
657      * will be the only one constructed for this particular event number.
658      */
659     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
660     mci->opcode = MDACMD_IOCTL;
661     mci->data_size = sizeof(struct mly_event);
662     mci->addr.phys.lun = (event >> 16) & 0xff;
663     mci->addr.phys.target = (event >> 24) & 0xff;
664     mci->addr.phys.channel = 0;
665     mci->addr.phys.controller = 0;
666     mci->timeout.value = 30;
667     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
668     mci->sub_ioctl = MDACIOCTL_GETEVENT;
669     mci->param.getevent.sequence_number_low = event & 0xffff;
670 
671     debug(2, "fetch event %u", event);
672 
673     /*
674      * Use the ready queue to get this command dispatched.
675      */
676     mly_enqueue_ready(mc);
677     mly_startio(sc);
678 }
679 
680 /********************************************************************************
681  * Handle the completion of an event poll.
682  *
683  * Note that we don't actually have to instigate another poll; the completion of
684  * this command will trigger that if there are any more events to poll for.
685  */
686 static void
687 mly_complete_event(struct mly_command *mc)
688 {
689     struct mly_softc	*sc = mc->mc_sc;
690     struct mly_event	*me = (struct mly_event *)mc->mc_data;
691 
692     debug_called(2);
693 
694     /*
695      * If the event was successfully fetched, process it.
696      */
697     if (mc->mc_status == SCSI_STATUS_OK) {
698 	mly_process_event(sc, me);
699 	free(me, M_DEVBUF);
700     }
701     mly_release_command(mc);
702 }
703 
704 /********************************************************************************
705  * Process a controller event.
706  */
707 static void
708 mly_process_event(struct mly_softc *sc, struct mly_event *me)
709 {
710     struct scsi_sense_data	*ssd = (struct scsi_sense_data *)&me->sense[0];
711     char			*fp, *tp;
712     int				bus, target, event, class, action;
713 
714     /*
715      * Errors can be reported using vendor-unique sense data.  In this case, the
716      * event code will be 0x1c (Request sense data present), the sense key will
717      * be 0x09 (vendor specific), the MSB of the ASC will be set, and the
718      * actual event code will be a 16-bit value comprised of the ASCQ (low byte)
719      * and low seven bits of the ASC (low seven bits of the high byte).
720      */
721     if ((me->code == 0x1c) &&
722 	((ssd->flags & SSD_KEY) == SSD_KEY_Vendor_Specific) &&
723 	(ssd->add_sense_code & 0x80)) {
724 	event = ((int)(ssd->add_sense_code & ~0x80) << 8) + ssd->add_sense_code_qual;
725     } else {
726 	event = me->code;
727     }
728 
729     /* look up event, get codes */
730     fp = mly_describe_code(mly_table_event, event);
731 
732     debug(2, "Event %d  code 0x%x", me->sequence_number, me->code);
733 
734     /* quiet event? */
735     class = fp[0];
736     if (isupper(class) && bootverbose)
737 	class = tolower(class);
738 
739     /* get action code, text string */
740     action = fp[1];
741     tp = &fp[2];
742 
743     /*
744      * Print some information about the event.
745      *
746      * This code uses a table derived from the corresponding portion of the Linux
747      * driver, and thus the parser is very similar.
748      */
749     switch(class) {
750     case 'p':		/* error on physical device */
751 	mly_printf(sc, "physical device %d:%d %s\n", me->channel, me->target, tp);
752 	if (action == 'r')
753 	    sc->mly_btl[me->channel][me->target].mb_flags |= MLY_BTL_RESCAN;
754 	break;
755     case 'l':		/* error on logical unit */
756     case 'm':		/* message about logical unit */
757 	bus = MLY_LOGDEV_BUS(sc, me->lun);
758 	target = MLY_LOGDEV_TARGET(me->lun);
759 	mly_name_device(sc, bus, target);
760 	mly_printf(sc, "logical device %d (%s) %s\n", me->lun, sc->mly_btl[bus][target].mb_name, tp);
761 	if (action == 'r')
762 	    sc->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN;
763 	break;
764       break;
765     case 's':		/* report of sense data */
766 	if (((ssd->flags & SSD_KEY) == SSD_KEY_NO_SENSE) ||
767 	    (((ssd->flags & SSD_KEY) == SSD_KEY_NOT_READY) &&
768 	     (ssd->add_sense_code == 0x04) &&
769 	     ((ssd->add_sense_code_qual == 0x01) || (ssd->add_sense_code_qual == 0x02))))
770 	    break;	/* ignore NO_SENSE or NOT_READY in one case */
771 
772 	mly_printf(sc, "physical device %d:%d %s\n", me->channel, me->target, tp);
773 	mly_printf(sc, "  sense key %d  asc %02x  ascq %02x\n",
774 		      ssd->flags & SSD_KEY, ssd->add_sense_code, ssd->add_sense_code_qual);
775 	mly_printf(sc, "  info %4D  csi %4D\n", ssd->info, "", ssd->cmd_spec_info, "");
776 	if (action == 'r')
777 	    sc->mly_btl[me->channel][me->target].mb_flags |= MLY_BTL_RESCAN;
778 	break;
779     case 'e':
780 	mly_printf(sc, tp, me->target, me->lun);
781 	break;
782     case 'c':
783 	mly_printf(sc, "controller %s\n", tp);
784 	break;
785     case '?':
786 	mly_printf(sc, "%s - %d\n", tp, me->code);
787 	break;
788     default:	/* probably a 'noisy' event being ignored */
789 	break;
790     }
791 }
792 
793 /********************************************************************************
794  * Perform periodic activities.
795  */
796 static void
797 mly_periodic(void *data)
798 {
799     struct mly_softc	*sc = (struct mly_softc *)data;
800     int			nchn, bus, target;
801 
802     debug_called(2);
803 
804     /*
805      * Scan devices.
806      */
807     nchn = sc->mly_controllerinfo->physical_channels_present +
808 	sc->mly_controllerinfo->virtual_channels_present;
809     for (bus = 0; bus < nchn; bus++) {
810 	for (target = 0; target < MLY_MAX_TARGETS; target++) {
811 
812 	    /* ignore the controller in this scan */
813 	    if (target == sc->mly_controllerparam->initiator_id)
814 		continue;
815 
816 	    /* perform device rescan? */
817 	    if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_RESCAN)
818 		mly_rescan_btl(sc, bus, target);
819 	}
820     }
821 
822     sc->mly_periodic = timeout(mly_periodic, sc, hz);
823 }
824 
825 /********************************************************************************
826  ********************************************************************************
827                                                                Command Processing
828  ********************************************************************************
829  ********************************************************************************/
830 
831 /********************************************************************************
832  * Run a command and wait for it to complete.
833  *
834  */
835 static int
836 mly_immediate_command(struct mly_command *mc)
837 {
838     struct mly_softc	*sc = mc->mc_sc;
839     int			error, s;
840 
841     debug_called(2);
842 
843     /* spinning at splcam is ugly, but we're only used during controller init */
844     s = splcam();
845     if ((error = mly_start(mc)))
846 	return(error);
847 
848     if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) {
849 	/* sleep on the command */
850 	while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
851 	    tsleep(mc, 0, "mlywait", 0);
852 	}
853     } else {
854 	/* spin and collect status while we do */
855 	while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
856 	    mly_done(mc->mc_sc);
857 	}
858     }
859     splx(s);
860     return(0);
861 }
862 
863 /********************************************************************************
864  * Start as much queued I/O as possible on the controller
865  */
866 void
867 mly_startio(struct mly_softc *sc)
868 {
869     struct mly_command	*mc;
870 
871     debug_called(2);
872 
873     for (;;) {
874 
875 	/* try for a ready command */
876 	mc = mly_dequeue_ready(sc);
877 
878 	/* try to build a command from a queued ccb */
879 	if (!mc)
880 	    mly_cam_command(sc, &mc);
881 
882 	/* no command == nothing to do */
883 	if (!mc)
884 	    break;
885 
886 	/* try to post the command */
887 	if (mly_start(mc)) {
888 	    /* controller busy, or no resources - defer for later */
889 	    mly_requeue_ready(mc);
890 	    break;
891 	}
892     }
893 }
894 
895 /********************************************************************************
896  * Deliver a command to the controller; allocate controller resources at the
897  * last moment.
898  */
899 static int
900 mly_start(struct mly_command *mc)
901 {
902     struct mly_softc		*sc = mc->mc_sc;
903     union mly_command_packet	*pkt;
904     int				s;
905 
906     debug_called(2);
907 
908     /*
909      * Set the command up for delivery to the controller.
910      */
911     mly_map_command(mc);
912     mc->mc_packet->generic.command_id = mc->mc_slot;
913 
914     s = splcam();
915 
916     /*
917      * Do we have to use the hardware mailbox?
918      */
919     if (!(sc->mly_state & MLY_STATE_MMBOX_ACTIVE)) {
920 	/*
921 	 * Check to see if the controller is ready for us.
922 	 */
923 	if (MLY_IDBR_TRUE(sc, MLY_HM_CMDSENT)) {
924 	    splx(s);
925 	    return(EBUSY);
926 	}
927 	mc->mc_flags |= MLY_CMD_BUSY;
928 
929 	/*
930 	 * It's ready, send the command.
931 	 */
932 	MLY_SET_MBOX(sc, sc->mly_command_mailbox, &mc->mc_packetphys);
933 	MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_CMDSENT);
934 
935     } else {	/* use memory-mailbox mode */
936 
937 	pkt = &sc->mly_mmbox->mmm_command[sc->mly_mmbox_command_index];
938 
939 	/* check to see if the next index is free yet */
940 	if (pkt->mmbox.flag != 0) {
941 	    splx(s);
942 	    return(EBUSY);
943 	}
944 	mc->mc_flags |= MLY_CMD_BUSY;
945 
946 	/* copy in new command */
947 	bcopy(mc->mc_packet->mmbox.data, pkt->mmbox.data, sizeof(pkt->mmbox.data));
948 	/* barrier to ensure completion of previous write before we write the flag */
949 	bus_space_barrier(NULL, NULL, 0, 0, BUS_SPACE_BARRIER_WRITE);	/* tag/handle? */
950 	/* copy flag last */
951 	pkt->mmbox.flag = mc->mc_packet->mmbox.flag;
952 	/* barrier to ensure completion of previous write before we notify the controller */
953 	bus_space_barrier(NULL, NULL, 0, 0, BUS_SPACE_BARRIER_WRITE);	/* tag/handle */
954 
955 	/* signal controller, update index */
956 	MLY_SET_REG(sc, sc->mly_idbr, MLY_AM_CMDSENT);
957 	sc->mly_mmbox_command_index = (sc->mly_mmbox_command_index + 1) % MLY_MMBOX_COMMANDS;
958     }
959 
960     mly_enqueue_busy(mc);
961     splx(s);
962     return(0);
963 }
964 
965 /********************************************************************************
966  * Pick up command status from the controller, schedule a completion event
967  */
968 void
969 mly_done(struct mly_softc *sc)
970 {
971     struct mly_command		*mc;
972     union mly_status_packet	*sp;
973     u_int16_t			slot;
974     int				s, worked;
975 
976     s = splcam();
977     worked = 0;
978 
979     /* pick up hardware-mailbox commands */
980     if (MLY_ODBR_TRUE(sc, MLY_HM_STSREADY)) {
981 	slot = MLY_GET_REG2(sc, sc->mly_status_mailbox);
982 	if (slot < MLY_SLOT_MAX) {
983 	    mc = &sc->mly_command[slot - MLY_SLOT_START];
984 	    mc->mc_status = MLY_GET_REG(sc, sc->mly_status_mailbox + 2);
985 	    mc->mc_sense = MLY_GET_REG(sc, sc->mly_status_mailbox + 3);
986 	    mc->mc_resid = MLY_GET_REG4(sc, sc->mly_status_mailbox + 4);
987 	    mly_remove_busy(mc);
988 	    mc->mc_flags &= ~MLY_CMD_BUSY;
989 	    mly_enqueue_complete(mc);
990 	    worked = 1;
991 	} else {
992 	    /* slot 0xffff may mean "extremely bogus command" */
993 	    mly_printf(sc, "got HM completion for illegal slot %u\n", slot);
994 	}
995 	/* unconditionally acknowledge status */
996 	MLY_SET_REG(sc, sc->mly_odbr, MLY_HM_STSREADY);
997 	MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_STSACK);
998     }
999 
1000     /* pick up memory-mailbox commands */
1001     if (MLY_ODBR_TRUE(sc, MLY_AM_STSREADY)) {
1002 	for (;;) {
1003 	    sp = &sc->mly_mmbox->mmm_status[sc->mly_mmbox_status_index];
1004 
1005 	    /* check for more status */
1006 	    if (sp->mmbox.flag == 0)
1007 		break;
1008 
1009 	    /* get slot number */
1010 	    slot = sp->status.command_id;
1011 	    if (slot < MLY_SLOT_MAX) {
1012 		mc = &sc->mly_command[slot - MLY_SLOT_START];
1013 		mc->mc_status = sp->status.status;
1014 		mc->mc_sense = sp->status.sense_length;
1015 		mc->mc_resid = sp->status.residue;
1016 		mly_remove_busy(mc);
1017 		mc->mc_flags &= ~MLY_CMD_BUSY;
1018 		mly_enqueue_complete(mc);
1019 		worked = 1;
1020 	    } else {
1021 		/* slot 0xffff may mean "extremely bogus command" */
1022 		mly_printf(sc, "got AM completion for illegal slot %u at %d\n",
1023 			   slot, sc->mly_mmbox_status_index);
1024 	    }
1025 
1026 	    /* clear and move to next index */
1027 	    sp->mmbox.flag = 0;
1028 	    sc->mly_mmbox_status_index = (sc->mly_mmbox_status_index + 1) % MLY_MMBOX_STATUS;
1029 	}
1030 	/* acknowledge that we have collected status value(s) */
1031 	MLY_SET_REG(sc, sc->mly_odbr, MLY_AM_STSREADY);
1032     }
1033 
1034     splx(s);
1035     if (worked) {
1036 #if __FreeBSD_version >= 500005
1037 	if (sc->mly_state & MLY_STATE_INTERRUPTS_ON)
1038 	    taskqueue_enqueue(taskqueue_swi, &sc->mly_task_complete);
1039 	else
1040 #endif
1041 	    mly_complete(sc, 0);
1042     }
1043 }
1044 
1045 /********************************************************************************
1046  * Process completed commands
1047  */
1048 static void
1049 mly_complete(void *context, int pending)
1050 {
1051     struct mly_softc	*sc = (struct mly_softc *)context;
1052     struct mly_command	*mc;
1053     void	        (* mc_complete)(struct mly_command *mc);
1054 
1055 
1056     debug_called(2);
1057 
1058     /*
1059      * Spin pulling commands off the completed queue and processing them.
1060      */
1061     while ((mc = mly_dequeue_complete(sc)) != NULL) {
1062 
1063 	/*
1064 	 * Free controller resources, mark command complete.
1065 	 *
1066 	 * Note that as soon as we mark the command complete, it may be freed
1067 	 * out from under us, so we need to save the mc_complete field in
1068 	 * order to later avoid dereferencing mc.  (We would not expect to
1069 	 * have a polling/sleeping consumer with mc_complete != NULL).
1070 	 */
1071 	mly_unmap_command(mc);
1072 	mc_complete = mc->mc_complete;
1073 	mc->mc_flags |= MLY_CMD_COMPLETE;
1074 
1075 	/*
1076 	 * Call completion handler or wake up sleeping consumer.
1077 	 */
1078 	if (mc_complete != NULL) {
1079 	    mc_complete(mc);
1080 	} else {
1081 	    wakeup(mc);
1082 	}
1083     }
1084 
1085     /*
1086      * We may have freed up controller resources which would allow us
1087      * to push more commands onto the controller, so we check here.
1088      */
1089     mly_startio(sc);
1090 
1091     /*
1092      * The controller may have updated the health status information,
1093      * so check for it here.
1094      *
1095      * Note that we only check for health status after a completed command.  It
1096      * might be wise to ping the controller occasionally if it's been idle for
1097      * a while just to check up on it.  While a filesystem is mounted, or I/O is
1098      * active this isn't really an issue.
1099      */
1100     if (sc->mly_mmbox->mmm_health.status.change_counter != sc->mly_event_change) {
1101 	sc->mly_event_change = sc->mly_mmbox->mmm_health.status.change_counter;
1102 	debug(1, "event change %d, event status update, %d -> %d", sc->mly_event_change,
1103 	      sc->mly_event_waiting, sc->mly_mmbox->mmm_health.status.next_event);
1104 	sc->mly_event_waiting = sc->mly_mmbox->mmm_health.status.next_event;
1105 
1106 	/* wake up anyone that might be interested in this */
1107 	wakeup(&sc->mly_event_change);
1108     }
1109     if (sc->mly_event_counter != sc->mly_event_waiting)
1110 	mly_fetch_event(sc);
1111 }
1112 
1113 /********************************************************************************
1114  ********************************************************************************
1115                                                         Command Buffer Management
1116  ********************************************************************************
1117  ********************************************************************************/
1118 
1119 /********************************************************************************
1120  * Allocate a command.
1121  */
1122 int
1123 mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp)
1124 {
1125     struct mly_command	*mc;
1126 
1127     debug_called(3);
1128 
1129     if ((mc = mly_dequeue_free(sc)) == NULL)
1130 	return(ENOMEM);
1131 
1132     *mcp = mc;
1133     return(0);
1134 }
1135 
1136 /********************************************************************************
1137  * Release a command back to the freelist.
1138  */
1139 void
1140 mly_release_command(struct mly_command *mc)
1141 {
1142     debug_called(3);
1143 
1144     /*
1145      * Fill in parts of the command that may cause confusion if
1146      * a consumer doesn't when we are later allocated.
1147      */
1148     mc->mc_data = NULL;
1149     mc->mc_flags = 0;
1150     mc->mc_complete = NULL;
1151     mc->mc_private = NULL;
1152 
1153     /*
1154      * By default, we set up to overwrite the command packet with
1155      * sense information.
1156      */
1157     mc->mc_packet->generic.sense_buffer_address = mc->mc_packetphys;
1158     mc->mc_packet->generic.maximum_sense_size = sizeof(union mly_command_packet);
1159 
1160     mly_enqueue_free(mc);
1161 }
1162 
1163 /********************************************************************************
1164  * Map helper for command allocation.
1165  */
1166 static void
1167 mly_alloc_commands_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1168 {
1169     struct mly_softc	*sc = (struct mly_softc *)arg
1170 
1171     debug_called(2);
1172 
1173     sc->mly_packetphys = segs[0].ds_addr;
1174 }
1175 
1176 /********************************************************************************
1177  * Allocate and initialise command and packet structures.
1178  */
1179 static int
1180 mly_alloc_commands(struct mly_softc *sc)
1181 {
1182     struct mly_command		*mc;
1183     int				i;
1184 
1185     /*
1186      * Allocate enough space for all the command packets in one chunk and
1187      * map them permanently into controller-visible space.
1188      */
1189     if (bus_dmamem_alloc(sc->mly_packet_dmat, (void **)&sc->mly_packet,
1190 			 BUS_DMA_NOWAIT, &sc->mly_packetmap)) {
1191 	return(ENOMEM);
1192     }
1193     bus_dmamap_load(sc->mly_packet_dmat, sc->mly_packetmap, sc->mly_packet,
1194 		    MLY_MAXCOMMANDS * sizeof(union mly_command_packet),
1195 		    mly_alloc_commands_map, sc, 0);
1196 
1197     for (i = 0; i < MLY_MAXCOMMANDS; i++) {
1198 	mc = &sc->mly_command[i];
1199 	bzero(mc, sizeof(*mc));
1200 	mc->mc_sc = sc;
1201 	mc->mc_slot = MLY_SLOT_START + i;
1202 	mc->mc_packet = sc->mly_packet + i;
1203 	mc->mc_packetphys = sc->mly_packetphys + (i * sizeof(union mly_command_packet));
1204 	if (!bus_dmamap_create(sc->mly_buffer_dmat, 0, &mc->mc_datamap))
1205 	    mly_release_command(mc);
1206     }
1207     return(0);
1208 }
1209 
1210 /********************************************************************************
1211  * Command-mapping helper function - populate this command's s/g table
1212  * with the s/g entries for its data.
1213  */
1214 static void
1215 mly_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1216 {
1217     struct mly_command		*mc = (struct mly_command *)arg;
1218     struct mly_softc		*sc = mc->mc_sc;
1219     struct mly_command_generic	*gen = &(mc->mc_packet->generic);
1220     struct mly_sg_entry		*sg;
1221     int				i, tabofs;
1222 
1223     debug_called(3);
1224 
1225     /* can we use the transfer structure directly? */
1226     if (nseg <= 2) {
1227 	sg = &gen->transfer.direct.sg[0];
1228 	gen->command_control.extended_sg_table = 0;
1229     } else {
1230 	tabofs = ((mc->mc_slot - MLY_SLOT_START) * MLY_MAXSGENTRIES);
1231 	sg = sc->mly_sg_table + tabofs;
1232 	gen->transfer.indirect.entries[0] = nseg;
1233 	gen->transfer.indirect.table_physaddr[0] = sc->mly_sg_busaddr + (tabofs * sizeof(struct mly_sg_entry));
1234 	gen->command_control.extended_sg_table = 1;
1235     }
1236 
1237     /* copy the s/g table */
1238     for (i = 0; i < nseg; i++) {
1239 	sg[i].physaddr = segs[i].ds_addr;
1240 	sg[i].length = segs[i].ds_len;
1241     }
1242 
1243 }
1244 
1245 #if 0
1246 /********************************************************************************
1247  * Command-mapping helper function - save the cdb's physical address.
1248  *
1249  * We don't support 'large' SCSI commands at this time, so this is unused.
1250  */
1251 static void
1252 mly_map_command_cdb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1253 {
1254     struct mly_command			*mc = (struct mly_command *)arg;
1255 
1256     debug_called(3);
1257 
1258     /* XXX can we safely assume that a CDB will never cross a page boundary? */
1259     if ((segs[0].ds_addr % PAGE_SIZE) >
1260 	((segs[0].ds_addr + mc->mc_packet->scsi_large.cdb_length) % PAGE_SIZE))
1261 	panic("cdb crosses page boundary");
1262 
1263     /* fix up fields in the command packet */
1264     mc->mc_packet->scsi_large.cdb_physaddr = segs[0].ds_addr;
1265 }
1266 #endif
1267 
1268 /********************************************************************************
1269  * Map a command into controller-visible space
1270  */
1271 static void
1272 mly_map_command(struct mly_command *mc)
1273 {
1274     struct mly_softc	*sc = mc->mc_sc;
1275 
1276     debug_called(2);
1277 
1278     /* don't map more than once */
1279     if (mc->mc_flags & MLY_CMD_MAPPED)
1280 	return;
1281 
1282     /* does the command have a data buffer? */
1283     if (mc->mc_data != NULL)
1284 	bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap, mc->mc_data, mc->mc_length,
1285 			mly_map_command_sg, mc, 0);
1286 
1287     if (mc->mc_flags & MLY_CMD_DATAIN)
1288 	bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREREAD);
1289     if (mc->mc_flags & MLY_CMD_DATAOUT)
1290 	bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREWRITE);
1291 
1292     mc->mc_flags |= MLY_CMD_MAPPED;
1293 }
1294 
1295 /********************************************************************************
1296  * Unmap a command from controller-visible space
1297  */
1298 static void
1299 mly_unmap_command(struct mly_command *mc)
1300 {
1301     struct mly_softc	*sc = mc->mc_sc;
1302 
1303     debug_called(2);
1304 
1305     if (!(mc->mc_flags & MLY_CMD_MAPPED))
1306 	return;
1307 
1308     if (mc->mc_flags & MLY_CMD_DATAIN)
1309 	bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_POSTREAD);
1310     if (mc->mc_flags & MLY_CMD_DATAOUT)
1311 	bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_POSTWRITE);
1312 
1313     /* does the command have a data buffer? */
1314     if (mc->mc_data != NULL)
1315 	bus_dmamap_unload(sc->mly_buffer_dmat, mc->mc_datamap);
1316 
1317     mc->mc_flags &= ~MLY_CMD_MAPPED;
1318 }
1319 
1320 /********************************************************************************
1321  ********************************************************************************
1322                                                                  Hardware Control
1323  ********************************************************************************
1324  ********************************************************************************/
1325 
1326 /********************************************************************************
1327  * Handshake with the firmware while the card is being initialised.
1328  */
1329 static int
1330 mly_fwhandshake(struct mly_softc *sc)
1331 {
1332     u_int8_t	error, param0, param1;
1333     int		spinup = 0;
1334 
1335     debug_called(1);
1336 
1337     /* set HM_STSACK and let the firmware initialise */
1338     MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_STSACK);
1339     DELAY(1000);	/* too short? */
1340 
1341     /* if HM_STSACK is still true, the controller is initialising */
1342     if (!MLY_IDBR_TRUE(sc, MLY_HM_STSACK))
1343 	return(0);
1344     mly_printf(sc, "controller initialisation started\n");
1345 
1346     /* spin waiting for initialisation to finish, or for a message to be delivered */
1347     while (MLY_IDBR_TRUE(sc, MLY_HM_STSACK)) {
1348 	/* check for a message */
1349 	if (MLY_ERROR_VALID(sc)) {
1350 	    error = MLY_GET_REG(sc, sc->mly_error_status) & ~MLY_MSG_EMPTY;
1351 	    param0 = MLY_GET_REG(sc, sc->mly_command_mailbox);
1352 	    param1 = MLY_GET_REG(sc, sc->mly_command_mailbox + 1);
1353 
1354 	    switch(error) {
1355 	    case MLY_MSG_SPINUP:
1356 		if (!spinup) {
1357 		    mly_printf(sc, "drive spinup in progress\n");
1358 		    spinup = 1;			/* only print this once (should print drive being spun?) */
1359 		}
1360 		break;
1361 	    case MLY_MSG_RACE_RECOVERY_FAIL:
1362 		mly_printf(sc, "mirror race recovery failed, one or more drives offline\n");
1363 		break;
1364 	    case MLY_MSG_RACE_IN_PROGRESS:
1365 		mly_printf(sc, "mirror race recovery in progress\n");
1366 		break;
1367 	    case MLY_MSG_RACE_ON_CRITICAL:
1368 		mly_printf(sc, "mirror race recovery on a critical drive\n");
1369 		break;
1370 	    case MLY_MSG_PARITY_ERROR:
1371 		mly_printf(sc, "FATAL MEMORY PARITY ERROR\n");
1372 		return(ENXIO);
1373 	    default:
1374 		mly_printf(sc, "unknown initialisation code 0x%x\n", error);
1375 	    }
1376 	}
1377     }
1378     return(0);
1379 }
1380 
1381 /********************************************************************************
1382  ********************************************************************************
1383                                                         Debugging and Diagnostics
1384  ********************************************************************************
1385  ********************************************************************************/
1386 
1387 /********************************************************************************
1388  * Print some information about the controller.
1389  */
1390 static void
1391 mly_describe_controller(struct mly_softc *sc)
1392 {
1393     struct mly_ioctl_getcontrollerinfo	*mi = sc->mly_controllerinfo;
1394 
1395     mly_printf(sc, "%16s, %d channel%s, firmware %d.%02d-%d-%02d (%02d%02d%02d%02d), %dMB RAM\n",
1396 	       mi->controller_name, mi->physical_channels_present, (mi->physical_channels_present) > 1 ? "s" : "",
1397 	       mi->fw_major, mi->fw_minor, mi->fw_turn, mi->fw_build,	/* XXX turn encoding? */
1398 	       mi->fw_century, mi->fw_year, mi->fw_month, mi->fw_day,
1399 	       mi->memory_size);
1400 
1401     if (bootverbose) {
1402 	mly_printf(sc, "%s %s (%x), %dMHz %d-bit %.16s\n",
1403 		   mly_describe_code(mly_table_oemname, mi->oem_information),
1404 		   mly_describe_code(mly_table_controllertype, mi->controller_type), mi->controller_type,
1405 		   mi->interface_speed, mi->interface_width, mi->interface_name);
1406 	mly_printf(sc, "%dMB %dMHz %d-bit %s%s%s, cache %dMB\n",
1407 		   mi->memory_size, mi->memory_speed, mi->memory_width,
1408 		   mly_describe_code(mly_table_memorytype, mi->memory_type),
1409 		   mi->memory_parity ? "+parity": "",mi->memory_ecc ? "+ECC": "",
1410 		   mi->cache_size);
1411 	mly_printf(sc, "CPU: %s @ %dMHZ\n",
1412 		   mly_describe_code(mly_table_cputype, mi->cpu[0].type), mi->cpu[0].speed);
1413 	if (mi->l2cache_size != 0)
1414 	    mly_printf(sc, "%dKB L2 cache\n", mi->l2cache_size);
1415 	if (mi->exmemory_size != 0)
1416 	    mly_printf(sc, "%dMB %dMHz %d-bit private %s%s%s\n",
1417 		       mi->exmemory_size, mi->exmemory_speed, mi->exmemory_width,
1418 		       mly_describe_code(mly_table_memorytype, mi->exmemory_type),
1419 		       mi->exmemory_parity ? "+parity": "",mi->exmemory_ecc ? "+ECC": "");
1420 	mly_printf(sc, "battery backup %s\n", mi->bbu_present ? "present" : "not installed");
1421 	mly_printf(sc, "maximum data transfer %d blocks, maximum sg entries/command %d\n",
1422 		   mi->maximum_block_count, mi->maximum_sg_entries);
1423 	mly_printf(sc, "logical devices present/critical/offline %d/%d/%d\n",
1424 		   mi->logical_devices_present, mi->logical_devices_critical, mi->logical_devices_offline);
1425 	mly_printf(sc, "physical devices present %d\n",
1426 		   mi->physical_devices_present);
1427 	mly_printf(sc, "physical disks present/offline %d/%d\n",
1428 		   mi->physical_disks_present, mi->physical_disks_offline);
1429 	mly_printf(sc, "%d physical channel%s, %d virtual channel%s of %d possible\n",
1430 		   mi->physical_channels_present, mi->physical_channels_present == 1 ? "" : "s",
1431 		   mi->virtual_channels_present, mi->virtual_channels_present == 1 ? "" : "s",
1432 		   mi->virtual_channels_possible);
1433 	mly_printf(sc, "%d parallel commands supported\n", mi->maximum_parallel_commands);
1434 	mly_printf(sc, "%dMB flash ROM, %d of %d maximum cycles\n",
1435 		   mi->flash_size, mi->flash_age, mi->flash_maximum_age);
1436     }
1437 }
1438 
1439 #ifdef MLY_DEBUG
1440 /********************************************************************************
1441  * Print some controller state
1442  */
1443 static void
1444 mly_printstate(struct mly_softc *sc)
1445 {
1446     mly_printf(sc, "IDBR %02x  ODBR %02x  ERROR %02x  (%x %x %x)\n",
1447 		  MLY_GET_REG(sc, sc->mly_idbr),
1448 		  MLY_GET_REG(sc, sc->mly_odbr),
1449 		  MLY_GET_REG(sc, sc->mly_error_status),
1450 		  sc->mly_idbr,
1451 		  sc->mly_odbr,
1452 		  sc->mly_error_status);
1453     mly_printf(sc, "IMASK %02x  ISTATUS %02x\n",
1454 		  MLY_GET_REG(sc, sc->mly_interrupt_mask),
1455 		  MLY_GET_REG(sc, sc->mly_interrupt_status));
1456     mly_printf(sc, "COMMAND %02x %02x %02x %02x %02x %02x %02x %02x\n",
1457 		  MLY_GET_REG(sc, sc->mly_command_mailbox),
1458 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 1),
1459 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 2),
1460 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 3),
1461 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 4),
1462 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 5),
1463 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 6),
1464 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 7));
1465     mly_printf(sc, "STATUS  %02x %02x %02x %02x %02x %02x %02x %02x\n",
1466 		  MLY_GET_REG(sc, sc->mly_status_mailbox),
1467 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 1),
1468 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 2),
1469 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 3),
1470 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 4),
1471 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 5),
1472 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 6),
1473 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 7));
1474     mly_printf(sc, "        %04x        %08x\n",
1475 		  MLY_GET_REG2(sc, sc->mly_status_mailbox),
1476 		  MLY_GET_REG4(sc, sc->mly_status_mailbox + 4));
1477 }
1478 
1479 struct mly_softc	*mly_softc0 = NULL;
1480 void
1481 mly_printstate0(void)
1482 {
1483     if (mly_softc0 != NULL)
1484 	mly_printstate(mly_softc0);
1485 }
1486 
1487 /********************************************************************************
1488  * Print a command
1489  */
1490 static void
1491 mly_print_command(struct mly_command *mc)
1492 {
1493     struct mly_softc	*sc = mc->mc_sc;
1494 
1495     mly_printf(sc, "COMMAND @ %p\n", mc);
1496     mly_printf(sc, "  slot      %d\n", mc->mc_slot);
1497     mly_printf(sc, "  status    0x%x\n", mc->mc_status);
1498     mly_printf(sc, "  sense len %d\n", mc->mc_sense);
1499     mly_printf(sc, "  resid     %d\n", mc->mc_resid);
1500     mly_printf(sc, "  packet    %p/0x%llx\n", mc->mc_packet, mc->mc_packetphys);
1501     if (mc->mc_packet != NULL)
1502 	mly_print_packet(mc);
1503     mly_printf(sc, "  data      %p/%d\n", mc->mc_data, mc->mc_length);
1504     mly_printf(sc, "  flags     %b\n", mc->mc_flags, "\20\1busy\2complete\3slotted\4mapped\5datain\6dataout\n");
1505     mly_printf(sc, "  complete  %p\n", mc->mc_complete);
1506     mly_printf(sc, "  private   %p\n", mc->mc_private);
1507 }
1508 
1509 /********************************************************************************
1510  * Print a command packet
1511  */
1512 static void
1513 mly_print_packet(struct mly_command *mc)
1514 {
1515     struct mly_softc			*sc = mc->mc_sc;
1516     struct mly_command_generic		*ge = (struct mly_command_generic *)mc->mc_packet;
1517     struct mly_command_scsi_small	*ss = (struct mly_command_scsi_small *)mc->mc_packet;
1518     struct mly_command_scsi_large	*sl = (struct mly_command_scsi_large *)mc->mc_packet;
1519     struct mly_command_ioctl		*io = (struct mly_command_ioctl *)mc->mc_packet;
1520     int					transfer;
1521 
1522     mly_printf(sc, "   command_id           %d\n", ge->command_id);
1523     mly_printf(sc, "   opcode               %d\n", ge->opcode);
1524     mly_printf(sc, "   command_control      fua %d  dpo %d  est %d  dd %s  nas %d ddis %d\n",
1525 		  ge->command_control.force_unit_access,
1526 		  ge->command_control.disable_page_out,
1527 		  ge->command_control.extended_sg_table,
1528 		  (ge->command_control.data_direction == MLY_CCB_WRITE) ? "WRITE" : "READ",
1529 		  ge->command_control.no_auto_sense,
1530 		  ge->command_control.disable_disconnect);
1531     mly_printf(sc, "   data_size            %d\n", ge->data_size);
1532     mly_printf(sc, "   sense_buffer_address 0x%llx\n", ge->sense_buffer_address);
1533     mly_printf(sc, "   lun                  %d\n", ge->addr.phys.lun);
1534     mly_printf(sc, "   target               %d\n", ge->addr.phys.target);
1535     mly_printf(sc, "   channel              %d\n", ge->addr.phys.channel);
1536     mly_printf(sc, "   logical device       %d\n", ge->addr.log.logdev);
1537     mly_printf(sc, "   controller           %d\n", ge->addr.phys.controller);
1538     mly_printf(sc, "   timeout              %d %s\n",
1539 		  ge->timeout.value,
1540 		  (ge->timeout.scale == MLY_TIMEOUT_SECONDS) ? "seconds" :
1541 		  ((ge->timeout.scale == MLY_TIMEOUT_MINUTES) ? "minutes" : "hours"));
1542     mly_printf(sc, "   maximum_sense_size   %d\n", ge->maximum_sense_size);
1543     switch(ge->opcode) {
1544     case MDACMD_SCSIPT:
1545     case MDACMD_SCSI:
1546 	mly_printf(sc, "   cdb length           %d\n", ss->cdb_length);
1547 	mly_printf(sc, "   cdb                  %*D\n", ss->cdb_length, ss->cdb, " ");
1548 	transfer = 1;
1549 	break;
1550     case MDACMD_SCSILC:
1551     case MDACMD_SCSILCPT:
1552 	mly_printf(sc, "   cdb length           %d\n", sl->cdb_length);
1553 	mly_printf(sc, "   cdb                  0x%llx\n", sl->cdb_physaddr);
1554 	transfer = 1;
1555 	break;
1556     case MDACMD_IOCTL:
1557 	mly_printf(sc, "   sub_ioctl            0x%x\n", io->sub_ioctl);
1558 	switch(io->sub_ioctl) {
1559 	case MDACIOCTL_SETMEMORYMAILBOX:
1560 	    mly_printf(sc, "   health_buffer_size   %d\n",
1561 			  io->param.setmemorymailbox.health_buffer_size);
1562 	    mly_printf(sc, "   health_buffer_phys   0x%llx\n",
1563 			  io->param.setmemorymailbox.health_buffer_physaddr);
1564 	    mly_printf(sc, "   command_mailbox      0x%llx\n",
1565 			  io->param.setmemorymailbox.command_mailbox_physaddr);
1566 	    mly_printf(sc, "   status_mailbox       0x%llx\n",
1567 			  io->param.setmemorymailbox.status_mailbox_physaddr);
1568 	    transfer = 0;
1569 	    break;
1570 
1571 	case MDACIOCTL_SETREALTIMECLOCK:
1572 	case MDACIOCTL_GETHEALTHSTATUS:
1573 	case MDACIOCTL_GETCONTROLLERINFO:
1574 	case MDACIOCTL_GETLOGDEVINFOVALID:
1575 	case MDACIOCTL_GETPHYSDEVINFOVALID:
1576 	case MDACIOCTL_GETPHYSDEVSTATISTICS:
1577 	case MDACIOCTL_GETLOGDEVSTATISTICS:
1578 	case MDACIOCTL_GETCONTROLLERSTATISTICS:
1579 	case MDACIOCTL_GETBDT_FOR_SYSDRIVE:
1580 	case MDACIOCTL_CREATENEWCONF:
1581 	case MDACIOCTL_ADDNEWCONF:
1582 	case MDACIOCTL_GETDEVCONFINFO:
1583 	case MDACIOCTL_GETFREESPACELIST:
1584 	case MDACIOCTL_MORE:
1585 	case MDACIOCTL_SETPHYSDEVPARAMETER:
1586 	case MDACIOCTL_GETPHYSDEVPARAMETER:
1587 	case MDACIOCTL_GETLOGDEVPARAMETER:
1588 	case MDACIOCTL_SETLOGDEVPARAMETER:
1589 	    mly_printf(sc, "   param                %10D\n", io->param.data.param, " ");
1590 	    transfer = 1;
1591 	    break;
1592 
1593 	case MDACIOCTL_GETEVENT:
1594 	    mly_printf(sc, "   event                %d\n",
1595 		       io->param.getevent.sequence_number_low + ((u_int32_t)io->addr.log.logdev << 16));
1596 	    transfer = 1;
1597 	    break;
1598 
1599 	case MDACIOCTL_SETRAIDDEVSTATE:
1600 	    mly_printf(sc, "   state                %d\n", io->param.setraiddevstate.state);
1601 	    transfer = 0;
1602 	    break;
1603 
1604 	case MDACIOCTL_XLATEPHYSDEVTORAIDDEV:
1605 	    mly_printf(sc, "   raid_device          %d\n", io->param.xlatephysdevtoraiddev.raid_device);
1606 	    mly_printf(sc, "   controller           %d\n", io->param.xlatephysdevtoraiddev.controller);
1607 	    mly_printf(sc, "   channel              %d\n", io->param.xlatephysdevtoraiddev.channel);
1608 	    mly_printf(sc, "   target               %d\n", io->param.xlatephysdevtoraiddev.target);
1609 	    mly_printf(sc, "   lun                  %d\n", io->param.xlatephysdevtoraiddev.lun);
1610 	    transfer = 0;
1611 	    break;
1612 
1613 	case MDACIOCTL_GETGROUPCONFINFO:
1614 	    mly_printf(sc, "   group                %d\n", io->param.getgroupconfinfo.group);
1615 	    transfer = 1;
1616 	    break;
1617 
1618 	case MDACIOCTL_GET_SUBSYSTEM_DATA:
1619 	case MDACIOCTL_SET_SUBSYSTEM_DATA:
1620 	case MDACIOCTL_STARTDISOCVERY:
1621 	case MDACIOCTL_INITPHYSDEVSTART:
1622 	case MDACIOCTL_INITPHYSDEVSTOP:
1623 	case MDACIOCTL_INITRAIDDEVSTART:
1624 	case MDACIOCTL_INITRAIDDEVSTOP:
1625 	case MDACIOCTL_REBUILDRAIDDEVSTART:
1626 	case MDACIOCTL_REBUILDRAIDDEVSTOP:
1627 	case MDACIOCTL_MAKECONSISTENTDATASTART:
1628 	case MDACIOCTL_MAKECONSISTENTDATASTOP:
1629 	case MDACIOCTL_CONSISTENCYCHECKSTART:
1630 	case MDACIOCTL_CONSISTENCYCHECKSTOP:
1631 	case MDACIOCTL_RESETDEVICE:
1632 	case MDACIOCTL_FLUSHDEVICEDATA:
1633 	case MDACIOCTL_PAUSEDEVICE:
1634 	case MDACIOCTL_UNPAUSEDEVICE:
1635 	case MDACIOCTL_LOCATEDEVICE:
1636 	case MDACIOCTL_SETMASTERSLAVEMODE:
1637 	case MDACIOCTL_DELETERAIDDEV:
1638 	case MDACIOCTL_REPLACEINTERNALDEV:
1639 	case MDACIOCTL_CLEARCONF:
1640 	case MDACIOCTL_GETCONTROLLERPARAMETER:
1641 	case MDACIOCTL_SETCONTRLLERPARAMETER:
1642 	case MDACIOCTL_CLEARCONFSUSPMODE:
1643 	case MDACIOCTL_STOREIMAGE:
1644 	case MDACIOCTL_READIMAGE:
1645 	case MDACIOCTL_FLASHIMAGES:
1646 	case MDACIOCTL_RENAMERAIDDEV:
1647 	default:			/* no idea what to print */
1648 	    transfer = 0;
1649 	    break;
1650 	}
1651 	break;
1652 
1653     case MDACMD_IOCTLCHECK:
1654     case MDACMD_MEMCOPY:
1655     default:
1656 	transfer = 0;
1657 	break;	/* print nothing */
1658     }
1659     if (transfer) {
1660 	if (ge->command_control.extended_sg_table) {
1661 	    mly_printf(sc, "   sg table             0x%llx/%d\n",
1662 			  ge->transfer.indirect.table_physaddr[0], ge->transfer.indirect.entries[0]);
1663 	} else {
1664 	    mly_printf(sc, "   0000                 0x%llx/%lld\n",
1665 			  ge->transfer.direct.sg[0].physaddr, ge->transfer.direct.sg[0].length);
1666 	    mly_printf(sc, "   0001                 0x%llx/%lld\n",
1667 			  ge->transfer.direct.sg[1].physaddr, ge->transfer.direct.sg[1].length);
1668 	}
1669     }
1670 }
1671 
1672 /********************************************************************************
1673  * Panic in a slightly informative fashion
1674  */
1675 static void
1676 mly_panic(struct mly_softc *sc, char *reason)
1677 {
1678     mly_printstate(sc);
1679     panic(reason);
1680 }
1681 #endif
1682 
1683 /********************************************************************************
1684  * Print queue statistics, callable from DDB.
1685  */
1686 void
1687 mly_print_controller(int controller)
1688 {
1689     struct mly_softc	*sc;
1690 
1691     if ((sc = devclass_get_softc(devclass_find("mly"), controller)) == NULL) {
1692 	printf("mly: controller %d invalid\n", controller);
1693     } else {
1694 	device_printf(sc->mly_dev, "queue    curr max\n");
1695 	device_printf(sc->mly_dev, "free     %04d/%04d\n",
1696 		      sc->mly_qstat[MLYQ_FREE].q_length, sc->mly_qstat[MLYQ_FREE].q_max);
1697 	device_printf(sc->mly_dev, "ready    %04d/%04d\n",
1698 		      sc->mly_qstat[MLYQ_READY].q_length, sc->mly_qstat[MLYQ_READY].q_max);
1699 	device_printf(sc->mly_dev, "busy     %04d/%04d\n",
1700 		      sc->mly_qstat[MLYQ_BUSY].q_length, sc->mly_qstat[MLYQ_BUSY].q_max);
1701 	device_printf(sc->mly_dev, "complete %04d/%04d\n",
1702 		      sc->mly_qstat[MLYQ_COMPLETE].q_length, sc->mly_qstat[MLYQ_COMPLETE].q_max);
1703     }
1704 }
1705 
1706 
1707 /********************************************************************************
1708  ********************************************************************************
1709                                                          Control device interface
1710  ********************************************************************************
1711  ********************************************************************************/
1712 
1713 /********************************************************************************
1714  * Accept an open operation on the control device.
1715  */
1716 static int
1717 mly_user_open(dev_t dev, int flags, int fmt, d_thread_t *td)
1718 {
1719     int			unit = minor(dev);
1720     struct mly_softc	*sc = devclass_get_softc(devclass_find("mly"), unit);
1721 
1722     sc->mly_state |= MLY_STATE_OPEN;
1723     return(0);
1724 }
1725 
1726 /********************************************************************************
1727  * Accept the last close on the control device.
1728  */
1729 static int
1730 mly_user_close(dev_t dev, int flags, int fmt, d_thread_t *td)
1731 {
1732     int			unit = minor(dev);
1733     struct mly_softc	*sc = devclass_get_softc(devclass_find("mly"), unit);
1734 
1735     sc->mly_state &= ~MLY_STATE_OPEN;
1736     return (0);
1737 }
1738 
1739 /********************************************************************************
1740  * Handle controller-specific control operations.
1741  */
1742 static int
1743 mly_user_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td)
1744 {
1745     struct mly_softc		*sc = (struct mly_softc *)dev->si_drv1;
1746     struct mly_user_command	*uc = (struct mly_user_command *)addr;
1747     struct mly_user_health	*uh = (struct mly_user_health *)addr;
1748 
1749     switch(cmd) {
1750     case MLYIO_COMMAND:
1751 	return(mly_user_command(sc, uc));
1752     case MLYIO_HEALTH:
1753 	return(mly_user_health(sc, uh));
1754     default:
1755 	return(ENOIOCTL);
1756     }
1757 }
1758 
1759 /********************************************************************************
1760  * Execute a command passed in from userspace.
1761  *
1762  * The control structure contains the actual command for the controller, as well
1763  * as the user-space data pointer and data size, and an optional sense buffer
1764  * size/pointer.  On completion, the data size is adjusted to the command
1765  * residual, and the sense buffer size to the size of the returned sense data.
1766  *
1767  */
1768 static int
1769 mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
1770 {
1771     struct mly_command			*mc;
1772     int					error, s;
1773 
1774     /* allocate a command */
1775     if (mly_alloc_command(sc, &mc)) {
1776 	error = ENOMEM;
1777 	goto out;		/* XXX Linux version will wait for a command */
1778     }
1779 
1780     /* handle data size/direction */
1781     mc->mc_length = (uc->DataTransferLength >= 0) ? uc->DataTransferLength : -uc->DataTransferLength;
1782     if (mc->mc_length > 0) {
1783 	if ((mc->mc_data = malloc(mc->mc_length, M_DEVBUF, M_NOWAIT)) == NULL) {
1784 	    error = ENOMEM;
1785 	    goto out;
1786 	}
1787     }
1788     if (uc->DataTransferLength > 0) {
1789 	mc->mc_flags |= MLY_CMD_DATAIN;
1790 	bzero(mc->mc_data, mc->mc_length);
1791     }
1792     if (uc->DataTransferLength < 0) {
1793 	mc->mc_flags |= MLY_CMD_DATAOUT;
1794 	if ((error = copyin(uc->DataTransferBuffer, mc->mc_data, mc->mc_length)) != 0)
1795 	    goto out;
1796     }
1797 
1798     /* copy the controller command */
1799     bcopy(&uc->CommandMailbox, mc->mc_packet, sizeof(uc->CommandMailbox));
1800 
1801     /* clear command completion handler so that we get woken up */
1802     mc->mc_complete = NULL;
1803 
1804     /* execute the command */
1805     s = splcam();
1806     mly_requeue_ready(mc);
1807     mly_startio(sc);
1808     while (!(mc->mc_flags & MLY_CMD_COMPLETE))
1809 	tsleep(mc, 0, "mlyioctl", 0);
1810     splx(s);
1811 
1812     /* return the data to userspace */
1813     if (uc->DataTransferLength > 0)
1814 	if ((error = copyout(mc->mc_data, uc->DataTransferBuffer, mc->mc_length)) != 0)
1815 	    goto out;
1816 
1817     /* return the sense buffer to userspace */
1818     if ((uc->RequestSenseLength > 0) && (mc->mc_sense > 0)) {
1819 	if ((error = copyout(mc->mc_packet, uc->RequestSenseBuffer,
1820 			     min(uc->RequestSenseLength, mc->mc_sense))) != 0)
1821 	    goto out;
1822     }
1823 
1824     /* return command results to userspace (caller will copy out) */
1825     uc->DataTransferLength = mc->mc_resid;
1826     uc->RequestSenseLength = min(uc->RequestSenseLength, mc->mc_sense);
1827     uc->CommandStatus = mc->mc_status;
1828     error = 0;
1829 
1830  out:
1831     if (mc->mc_data != NULL)
1832 	free(mc->mc_data, M_DEVBUF);
1833     if (mc != NULL)
1834 	mly_release_command(mc);
1835     return(error);
1836 }
1837 
1838 /********************************************************************************
1839  * Return health status to userspace.  If the health change index in the user
1840  * structure does not match that currently exported by the controller, we
1841  * return the current status immediately.  Otherwise, we block until either
1842  * interrupted or new status is delivered.
1843  */
1844 static int
1845 mly_user_health(struct mly_softc *sc, struct mly_user_health *uh)
1846 {
1847     struct mly_health_status		mh;
1848     int					error, s;
1849 
1850     /* fetch the current health status from userspace */
1851     if ((error = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh))) != 0)
1852 	return(error);
1853 
1854     /* spin waiting for a status update */
1855     s = splcam();
1856     error = EWOULDBLOCK;
1857     while ((error != 0) && (sc->mly_event_change == mh.change_counter))
1858 	error = tsleep(&sc->mly_event_change, PCATCH, "mlyhealth", 0);
1859     splx(s);
1860 
1861     /* copy the controller's health status buffer out (there is a race here if it changes again) */
1862     error = copyout(&sc->mly_mmbox->mmm_health.status, uh->HealthStatusBuffer,
1863 		    sizeof(uh->HealthStatusBuffer));
1864     return(error);
1865 }
1866