File:  [DragonFly] / src / sys / dev / raid / mly / mly.c
Revision 1.8: download - view: text, annotated - select for diffs
Thu May 13 23:49:19 2004 UTC (10 years, 5 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
device switch 1/many: Remove d_autoq, add d_clone (where d_autoq was).

d_autoq was used to allow the device port dispatch to mix old-style synchronous
calls with new style messaging calls within a particular device.  It was never
used for that purpose.

d_clone will be more fully implemented as work continues.  We are going to
install d_port in the dev_t (struct specinfo) structure itself and d_clone
will be needed to allow devices to 'revector' the port on a minor-number
by minor-number basis, in particular allowing minor numbers to be directly
dispatched to distinct threads.  This is something we will be needing later
on.

    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.8 2004/05/13 23:49:19 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:     /* clone */	NULL,
  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 defined(__FreeBSD__) && __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 defined(__FreeBSD__) && __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: }