File:  [DragonFly] / src / sys / dev / raid / ciss / ciss.c
Revision 1.7: download - view: text, annotated - select for diffs
Thu May 13 23:49:18 2004 UTC (10 years, 7 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) 2001 Michael Smith
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  *
   14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24:  * SUCH DAMAGE.
   25:  *
   26:  *	$FreeBSD: src/sys/dev/ciss/ciss.c,v 1.2.2.6 2003/02/18 22:27:41 ps Exp $
   27:  *	$DragonFly: src/sys/dev/raid/ciss/ciss.c,v 1.7 2004/05/13 23:49:18 dillon Exp $
   28:  */
   29: 
   30: /*
   31:  * Common Interface for SCSI-3 Support driver.
   32:  *
   33:  * CISS claims to provide a common interface between a generic SCSI
   34:  * transport and an intelligent host adapter.
   35:  *
   36:  * This driver supports CISS as defined in the document "CISS Command
   37:  * Interface for SCSI-3 Support Open Specification", Version 1.04,
   38:  * Valence Number 1, dated 20001127, produced by Compaq Computer
   39:  * Corporation.  This document appears to be a hastily and somewhat
   40:  * arbitrarlily cut-down version of a larger (and probably even more
   41:  * chaotic and inconsistent) Compaq internal document.  Various
   42:  * details were also gleaned from Compaq's "cciss" driver for Linux.
   43:  *
   44:  * We provide a shim layer between the CISS interface and CAM,
   45:  * offloading most of the queueing and being-a-disk chores onto CAM.
   46:  * Entry to the driver is via the PCI bus attachment (ciss_probe,
   47:  * ciss_attach, etc) and via the CAM interface (ciss_cam_action,
   48:  * ciss_cam_poll).  The Compaq CISS adapters are, however, poor SCSI
   49:  * citizens and we have to fake up some responses to get reasonable
   50:  * behaviour out of them.  In addition, the CISS command set is by no
   51:  * means adequate to support the functionality of a RAID controller,
   52:  * and thus the supported Compaq adapters utilise portions of the
   53:  * control protocol from earlier Compaq adapter families.
   54:  *
   55:  * Note that we only support the "simple" transport layer over PCI.
   56:  * This interface (ab)uses the I2O register set (specifically the post
   57:  * queues) to exchange commands with the adapter.  Other interfaces
   58:  * are available, but we aren't supposed to know about them, and it is
   59:  * dubious whether they would provide major performance improvements
   60:  * except under extreme load.
   61:  * 
   62:  * Currently the only supported CISS adapters are the Compaq Smart
   63:  * Array 5* series (5300, 5i, 532).  Even with only three adapters,
   64:  * Compaq still manage to have interface variations.
   65:  *
   66:  *
   67:  * Thanks must go to Fred Harris and Darryl DeVinney at Compaq, as
   68:  * well as Paul Saab at Yahoo! for their assistance in making this
   69:  * driver happen.
   70:  */
   71: 
   72: #include <sys/param.h>
   73: #include <sys/systm.h>
   74: #include <sys/malloc.h>
   75: #include <sys/kernel.h>
   76: #include <sys/bus.h>
   77: #include <sys/conf.h>
   78: #include <sys/devicestat.h>
   79: #include <sys/stat.h>
   80: 
   81: #include <bus/cam/cam.h>
   82: #include <bus/cam/cam_ccb.h>
   83: #include <bus/cam/cam_periph.h>
   84: #include <bus/cam/cam_sim.h>
   85: #include <bus/cam/cam_xpt_sim.h>
   86: #include <bus/cam/scsi/scsi_all.h>
   87: #include <bus/cam/scsi/scsi_message.h>
   88: 
   89: #include <machine/clock.h>
   90: #include <machine/bus_memio.h>
   91: #include <machine/bus.h>
   92: #include <machine/endian.h>
   93: #include <machine/resource.h>
   94: #include <sys/rman.h>
   95: 
   96: #include <bus/pci/pcireg.h>
   97: #include <bus/pci/pcivar.h>
   98: 
   99: #include "cissreg.h"
  100: #include "cissvar.h"
  101: #include "cissio.h"
  102: 
  103: MALLOC_DEFINE(CISS_MALLOC_CLASS, "ciss_data", "ciss internal data buffers");
  104: 
  105: /* pci interface */
  106: static int	ciss_lookup(device_t dev);
  107: static int	ciss_probe(device_t dev);
  108: static int	ciss_attach(device_t dev);
  109: static int	ciss_detach(device_t dev);
  110: static int	ciss_shutdown(device_t dev);
  111: 
  112: /* (de)initialisation functions, control wrappers */
  113: static int	ciss_init_pci(struct ciss_softc *sc);
  114: static int	ciss_wait_adapter(struct ciss_softc *sc);
  115: static int	ciss_flush_adapter(struct ciss_softc *sc);
  116: static int	ciss_init_requests(struct ciss_softc *sc);
  117: static void	ciss_command_map_helper(void *arg, bus_dma_segment_t *segs,
  118: 					int nseg, int error);
  119: static int	ciss_identify_adapter(struct ciss_softc *sc);
  120: static int	ciss_init_logical(struct ciss_softc *sc);
  121: static int	ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld);
  122: static int	ciss_get_ldrive_status(struct ciss_softc *sc,  struct ciss_ldrive *ld);
  123: static int	ciss_update_config(struct ciss_softc *sc);
  124: static int	ciss_accept_media(struct ciss_softc *sc, int ldrive, int async);
  125: static void	ciss_accept_media_complete(struct ciss_request *cr);
  126: static void	ciss_free(struct ciss_softc *sc);
  127: 
  128: /* request submission/completion */
  129: static int	ciss_start(struct ciss_request *cr);
  130: static void	ciss_done(struct ciss_softc *sc);
  131: static void	ciss_intr(void *arg);
  132: static void	ciss_complete(struct ciss_softc *sc);
  133: static int	ciss_report_request(struct ciss_request *cr, int *command_status,
  134: 				    int *scsi_status);
  135: static int	ciss_synch_request(struct ciss_request *cr, int timeout);
  136: static int	ciss_poll_request(struct ciss_request *cr, int timeout);
  137: static int	ciss_wait_request(struct ciss_request *cr, int timeout);
  138: #if 0
  139: static int	ciss_abort_request(struct ciss_request *cr);
  140: #endif
  141: 
  142: /* request queueing */
  143: static int	ciss_get_request(struct ciss_softc *sc, struct ciss_request **crp);
  144: static void	ciss_preen_command(struct ciss_request *cr);
  145: static void 	ciss_release_request(struct ciss_request *cr);
  146: 
  147: /* request helpers */
  148: static int	ciss_get_bmic_request(struct ciss_softc *sc, struct ciss_request **crp,
  149: 				      int opcode, void **bufp, size_t bufsize);
  150: static int	ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc);
  151: 
  152: /* DMA map/unmap */
  153: static int	ciss_map_request(struct ciss_request *cr);
  154: static void	ciss_request_map_helper(void *arg, bus_dma_segment_t *segs,
  155: 					int nseg, int error);
  156: static void	ciss_unmap_request(struct ciss_request *cr);
  157: 
  158: /* CAM interface */
  159: static int	ciss_cam_init(struct ciss_softc *sc);
  160: static void	ciss_cam_rescan_target(struct ciss_softc *sc, int target);
  161: static void	ciss_cam_rescan_all(struct ciss_softc *sc);
  162: static void	ciss_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb);
  163: static void	ciss_cam_action(struct cam_sim *sim, union ccb *ccb);
  164: static int	ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio);
  165: static int	ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio);
  166: static void	ciss_cam_poll(struct cam_sim *sim);
  167: static void	ciss_cam_complete(struct ciss_request *cr);
  168: static void	ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio);
  169: static struct cam_periph *ciss_find_periph(struct ciss_softc *sc, int target);
  170: static int	ciss_name_device(struct ciss_softc *sc, int target);
  171: 
  172: /* periodic status monitoring */
  173: static void	ciss_periodic(void *arg);
  174: static void	ciss_notify_event(struct ciss_softc *sc);
  175: static void	ciss_notify_complete(struct ciss_request *cr);
  176: static int	ciss_notify_abort(struct ciss_softc *sc);
  177: static int	ciss_notify_abort_bmic(struct ciss_softc *sc);
  178: static void	ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn);
  179: static void	ciss_notify_physical(struct ciss_softc *sc, struct ciss_notify *cn);
  180: 
  181: /* debugging output */
  182: static void	ciss_print_request(struct ciss_request *cr);
  183: static void	ciss_print_ldrive(struct ciss_softc *sc, struct ciss_ldrive *ld);
  184: static const char *ciss_name_ldrive_status(int status);
  185: static int	ciss_decode_ldrive_status(int status);
  186: static const char *ciss_name_ldrive_org(int org);
  187: static const char *ciss_name_command_status(int status);
  188: 
  189: /*
  190:  * PCI bus interface.
  191:  */
  192: static device_method_t ciss_methods[] = {
  193:     /* Device interface */
  194:     DEVMETHOD(device_probe,	ciss_probe),
  195:     DEVMETHOD(device_attach,	ciss_attach),
  196:     DEVMETHOD(device_detach,	ciss_detach),
  197:     DEVMETHOD(device_shutdown,	ciss_shutdown),
  198:     { 0, 0 }
  199: };
  200: 
  201: static driver_t ciss_pci_driver = {
  202:     "ciss",
  203:     ciss_methods,
  204:     sizeof(struct ciss_softc)
  205: };
  206: 
  207: static devclass_t	ciss_devclass;
  208: 
  209: DECLARE_DUMMY_MODULE(ciss);
  210: DRIVER_MODULE(ciss, pci, ciss_pci_driver, ciss_devclass, 0, 0);
  211: 
  212: /*
  213:  * Control device interface.
  214:  */
  215: static d_open_t		ciss_open;
  216: static d_close_t	ciss_close;
  217: static d_ioctl_t	ciss_ioctl;
  218: 
  219: #define CISS_CDEV_MAJOR  166
  220: 
  221: static struct cdevsw ciss_cdevsw = {
  222:     /* name */		"ciss",
  223:     /* cmaj */		CISS_CDEV_MAJOR,
  224:     /* flags */		0, 
  225:     /* port */		NULL,
  226:     /* clone */		NULL,
  227:     ciss_open, ciss_close, noread, nowrite, ciss_ioctl,
  228:     nopoll, nommap, nostrategy,
  229:     nodump, nopsize, nokqfilter
  230: };
  231: 
  232: /************************************************************************
  233:  * CISS adapters amazingly don't have a defined programming interface
  234:  * value.  (One could say some very despairing things about PCI and
  235:  * people just not getting the general idea.)  So we are forced to
  236:  * stick with matching against subvendor/subdevice, and thus have to
  237:  * be updated for every new CISS adapter that appears.
  238:  */
  239: #define CISS_BOARD_SA5	(1<<0)
  240: #define CISS_BOARD_SA5B	(1<<1)
  241: 
  242: static struct
  243: {
  244:     u_int16_t	subvendor;
  245:     u_int16_t	subdevice;
  246:     int		flags;
  247:     char	*desc;
  248: } ciss_vendor_data[] = {
  249:     { 0x0e11, 0x4070, CISS_BOARD_SA5,	"Compaq Smart Array 5300" },
  250:     { 0x0e11, 0x4080, CISS_BOARD_SA5B,	"Compaq Smart Array 5i" },
  251:     { 0x0e11, 0x4082, CISS_BOARD_SA5B,	"Compaq Smart Array 532" },
  252:     { 0x0e11, 0x4083, CISS_BOARD_SA5B,	"HP Smart Array 5312" },
  253:     { 0x0e11, 0x409A, CISS_BOARD_SA5B,	"HP Smart Array 641" },
  254:     { 0x0e11, 0x409B, CISS_BOARD_SA5B,	"HP Smart Array 642" },
  255:     { 0x0e11, 0x409C, CISS_BOARD_SA5B,	"HP Smart Array 6400" },
  256:     { 0, 0, 0, NULL }
  257: };
  258: 
  259: /************************************************************************
  260:  * Find a match for the device in our list of known adapters.
  261:  */
  262: static int
  263: ciss_lookup(device_t dev)
  264: {
  265:     int 	i;
  266:     
  267:     for (i = 0; ciss_vendor_data[i].desc != NULL; i++)
  268: 	if ((pci_get_subvendor(dev) == ciss_vendor_data[i].subvendor) &&
  269: 	    (pci_get_subdevice(dev) == ciss_vendor_data[i].subdevice)) {
  270: 	    return(i);
  271: 	}
  272:     return(-1);
  273: }
  274: 
  275: /************************************************************************
  276:  * Match a known CISS adapter.
  277:  */
  278: static int
  279: ciss_probe(device_t dev)
  280: {
  281:     int		i;
  282:     
  283:     i = ciss_lookup(dev);
  284:     if (i != -1) {
  285: 	device_set_desc(dev, ciss_vendor_data[i].desc);
  286: 	return(-10);
  287:     }
  288:     return(ENOENT);
  289: }	
  290: 
  291: /************************************************************************
  292:  * Attach the driver to this adapter.
  293:  */
  294: static int
  295: ciss_attach(device_t dev)
  296: {
  297:     struct ciss_softc	*sc;
  298:     int			i, error;
  299: 
  300:     debug_called(1);
  301: 
  302: #ifdef CISS_DEBUG
  303:     /* print structure/union sizes */
  304:     debug_struct(ciss_command);
  305:     debug_struct(ciss_header);
  306:     debug_union(ciss_device_address);
  307:     debug_struct(ciss_cdb);
  308:     debug_struct(ciss_report_cdb);
  309:     debug_struct(ciss_notify_cdb);
  310:     debug_struct(ciss_notify);
  311:     debug_struct(ciss_message_cdb);
  312:     debug_struct(ciss_error_info_pointer);
  313:     debug_struct(ciss_error_info);
  314:     debug_struct(ciss_sg_entry);
  315:     debug_struct(ciss_config_table);
  316:     debug_struct(ciss_bmic_cdb);
  317:     debug_struct(ciss_bmic_id_ldrive);
  318:     debug_struct(ciss_bmic_id_lstatus);
  319:     debug_struct(ciss_bmic_id_table);
  320:     debug_struct(ciss_bmic_id_pdrive);
  321:     debug_struct(ciss_bmic_blink_pdrive);
  322:     debug_struct(ciss_bmic_flush_cache);
  323:     debug_const(CISS_MAX_REQUESTS);
  324:     debug_const(CISS_MAX_LOGICAL);
  325:     debug_const(CISS_INTERRUPT_COALESCE_DELAY);
  326:     debug_const(CISS_INTERRUPT_COALESCE_COUNT);
  327:     debug_const(CISS_COMMAND_ALLOC_SIZE);
  328:     debug_const(CISS_COMMAND_SG_LENGTH);
  329: 
  330:     debug_type(cciss_pci_info_struct);
  331:     debug_type(cciss_coalint_struct);
  332:     debug_type(cciss_coalint_struct);
  333:     debug_type(NodeName_type);
  334:     debug_type(NodeName_type);
  335:     debug_type(Heartbeat_type);
  336:     debug_type(BusTypes_type);
  337:     debug_type(FirmwareVer_type);
  338:     debug_type(DriverVer_type);
  339:     debug_type(IOCTL_Command_struct);
  340: #endif
  341: 
  342:     sc = device_get_softc(dev);
  343:     sc->ciss_dev = dev;
  344: 
  345:     /*
  346:      * Work out adapter type.
  347:      */
  348:     i = ciss_lookup(dev);
  349:     if (ciss_vendor_data[i].flags & CISS_BOARD_SA5) {
  350: 	sc->ciss_interrupt_mask = CISS_TL_SIMPLE_INTR_OPQ_SA5;
  351:     } else if (ciss_vendor_data[i].flags & CISS_BOARD_SA5B) {
  352: 	sc->ciss_interrupt_mask = CISS_TL_SIMPLE_INTR_OPQ_SA5B;
  353:     } else {
  354: 	/* really an error on our part */
  355: 	ciss_printf(sc, "unable to determine hardware type\n");
  356: 	error = ENXIO;
  357: 	goto out;
  358:     }
  359: 	
  360:     /*
  361:      * Do PCI-specific init.
  362:      */
  363:     if ((error = ciss_init_pci(sc)) != 0)
  364: 	goto out;
  365: 
  366:     /*
  367:      * Initialise driver queues.
  368:      */
  369:     ciss_initq_free(sc);
  370:     ciss_initq_busy(sc);
  371:     ciss_initq_complete(sc);
  372: 
  373:     /*
  374:      * Initialise command/request pool.
  375:      */
  376:     if ((error = ciss_init_requests(sc)) != 0)
  377: 	goto out;
  378: 
  379:     /*
  380:      * Get adapter information.
  381:      */
  382:     if ((error = ciss_identify_adapter(sc)) != 0)
  383: 	goto out;
  384:     
  385:     /*
  386:      * Build our private table of logical devices.
  387:      */
  388:     if ((error = ciss_init_logical(sc)) != 0)
  389: 	goto out;
  390: 
  391:     /*
  392:      * Enable interrupts so that the CAM scan can complete.
  393:      */
  394:     CISS_TL_SIMPLE_ENABLE_INTERRUPTS(sc);
  395: 
  396:     /*
  397:      * Initialise the CAM interface.
  398:      */
  399:     if ((error = ciss_cam_init(sc)) != 0)
  400: 	goto out;
  401: 
  402:     /*
  403:      * Start the heartbeat routine and event chain.
  404:      */
  405:     ciss_periodic(sc);
  406: 
  407:    /*
  408:      * Create the control device.
  409:      */
  410:     sc->ciss_dev_t = make_dev(&ciss_cdevsw, device_get_unit(sc->ciss_dev),
  411: 			      UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
  412: 			      "ciss%d", device_get_unit(sc->ciss_dev));
  413:     sc->ciss_dev_t->si_drv1 = sc;
  414: 
  415:     /*
  416:      * The adapter is running; synchronous commands can now sleep
  417:      * waiting for an interrupt to signal completion.
  418:      */
  419:     sc->ciss_flags |= CISS_FLAG_RUNNING;
  420: 
  421:     error = 0;
  422:  out:
  423:     if (error != 0)
  424: 	ciss_free(sc);
  425:     return(error);
  426: }
  427: 
  428: /************************************************************************
  429:  * Detach the driver from this adapter.
  430:  */
  431: static int
  432: ciss_detach(device_t dev)
  433: {
  434:     struct ciss_softc	*sc = device_get_softc(dev);
  435: 
  436:     debug_called(1);
  437:     
  438:     /* flush adapter cache */
  439:     ciss_flush_adapter(sc);
  440: 
  441:     /* release all resources */
  442:     ciss_free(sc);
  443: 
  444:     return(0);
  445:     
  446: }
  447: 
  448: /************************************************************************
  449:  * Prepare adapter for system shutdown.
  450:  */
  451: static int
  452: ciss_shutdown(device_t dev)
  453: {
  454:     struct ciss_softc	*sc = device_get_softc(dev);
  455: 
  456:     debug_called(1);
  457: 
  458:     /* flush adapter cache */
  459:     ciss_flush_adapter(sc);
  460: 
  461:     return(0);
  462: }
  463: 
  464: /************************************************************************
  465:  * Perform PCI-specific attachment actions.
  466:  */
  467: static int
  468: ciss_init_pci(struct ciss_softc *sc)
  469: {
  470:     uintptr_t		cbase, csize, cofs;
  471:     int			error;
  472: 
  473:     debug_called(1);
  474: 
  475:     /*
  476:      * Allocate register window first (we need this to find the config
  477:      * struct).
  478:      */
  479:     error = ENXIO;
  480:     sc->ciss_regs_rid = CISS_TL_SIMPLE_BAR_REGS;
  481:     if ((sc->ciss_regs_resource =
  482: 	 bus_alloc_resource(sc->ciss_dev, SYS_RES_MEMORY, &sc->ciss_regs_rid,
  483: 			    0, ~0, 1, RF_ACTIVE)) == NULL) {
  484: 	ciss_printf(sc, "can't allocate register window\n");
  485: 	return(ENXIO);
  486:     }
  487:     sc->ciss_regs_bhandle = rman_get_bushandle(sc->ciss_regs_resource);
  488:     sc->ciss_regs_btag = rman_get_bustag(sc->ciss_regs_resource);
  489:     
  490:     /*
  491:      * Find the BAR holding the config structure.  If it's not the one
  492:      * we already mapped for registers, map it too.
  493:      */
  494:     sc->ciss_cfg_rid = CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_CFG_BAR) & 0xffff;
  495:     if (sc->ciss_cfg_rid != sc->ciss_regs_rid) {
  496: 	if ((sc->ciss_cfg_resource =
  497: 	     bus_alloc_resource(sc->ciss_dev, SYS_RES_MEMORY, &sc->ciss_cfg_rid,
  498: 				0, ~0, 1, RF_ACTIVE)) == NULL) {
  499: 	    ciss_printf(sc, "can't allocate config window\n");
  500: 	    return(ENXIO);
  501: 	}
  502: 	cbase = (uintptr_t)rman_get_virtual(sc->ciss_cfg_resource);
  503: 	csize = rman_get_end(sc->ciss_cfg_resource) -
  504: 	    rman_get_start(sc->ciss_cfg_resource) + 1;
  505:     } else {
  506: 	cbase = (uintptr_t)rman_get_virtual(sc->ciss_regs_resource);
  507: 	csize = rman_get_end(sc->ciss_regs_resource) -
  508: 	    rman_get_start(sc->ciss_regs_resource) + 1;
  509:     }
  510:     cofs = CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_CFG_OFF);
  511:     
  512:     /*
  513:      * Use the base/size/offset values we just calculated to
  514:      * sanity-check the config structure.  If it's OK, point to it.
  515:      */
  516:     if ((cofs + sizeof(struct ciss_config_table)) > csize) {
  517: 	ciss_printf(sc, "config table outside window\n");
  518: 	return(ENXIO);
  519:     }
  520:     sc->ciss_cfg = (struct ciss_config_table *)(cbase + cofs);
  521:     debug(1, "config struct at %p", sc->ciss_cfg);
  522:     
  523:     /*
  524:      * Validate the config structure.  If we supported other transport
  525:      * methods, we could select amongst them at this point in time.
  526:      */
  527:     if (strncmp(sc->ciss_cfg->signature, "CISS", 4)) {
  528: 	ciss_printf(sc, "config signature mismatch (got '%c%c%c%c')\n",
  529: 		    sc->ciss_cfg->signature[0], sc->ciss_cfg->signature[1],
  530: 		    sc->ciss_cfg->signature[2], sc->ciss_cfg->signature[3]);
  531: 	return(ENXIO);
  532:     }
  533:     if ((sc->ciss_cfg->valence < CISS_MIN_VALENCE) ||
  534: 	(sc->ciss_cfg->valence > CISS_MAX_VALENCE)) {
  535: 	ciss_printf(sc, "adapter interface specification (%d) unsupported\n", 
  536: 		    sc->ciss_cfg->valence);
  537: 	return(ENXIO);
  538:     }
  539: 
  540:     /*
  541:      * Put the board into simple mode, and tell it we're using the low
  542:      * 4GB of RAM.  Set the default interrupt coalescing options.
  543:      */
  544:     if (!(sc->ciss_cfg->supported_methods & CISS_TRANSPORT_METHOD_SIMPLE)) {
  545: 	ciss_printf(sc, "adapter does not support 'simple' transport layer\n");
  546: 	return(ENXIO);
  547:     }
  548:     sc->ciss_cfg->requested_method = CISS_TRANSPORT_METHOD_SIMPLE;
  549:     sc->ciss_cfg->command_physlimit = 0;
  550:     sc->ciss_cfg->interrupt_coalesce_delay = CISS_INTERRUPT_COALESCE_DELAY;
  551:     sc->ciss_cfg->interrupt_coalesce_count = CISS_INTERRUPT_COALESCE_COUNT;
  552: 
  553:     if (ciss_update_config(sc)) {
  554: 	ciss_printf(sc, "adapter refuses to accept config update (IDBR 0x%x)\n",
  555: 		    CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IDBR));
  556: 	return(ENXIO);
  557:     }
  558:     if (!(sc->ciss_cfg->active_method != CISS_TRANSPORT_METHOD_SIMPLE)) {
  559: 	ciss_printf(sc,
  560: 		    "adapter refuses to go into 'simple' transport mode (0x%x, 0x%x)\n",
  561: 		    sc->ciss_cfg->supported_methods, sc->ciss_cfg->active_method);
  562: 	return(ENXIO);
  563:     }
  564: 
  565:     /*
  566:      * Wait for the adapter to come ready.
  567:      */
  568:     if ((error = ciss_wait_adapter(sc)) != 0)
  569: 	return(error);
  570: 
  571:     /*
  572:      * Turn off interrupts before we go routing anything.
  573:      */
  574:     CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc);
  575:     
  576:     /*
  577:      * Allocate and set up our interrupt.
  578:      */
  579:     sc->ciss_irq_rid = 0;
  580:     if ((sc->ciss_irq_resource =
  581: 	 bus_alloc_resource(sc->ciss_dev, SYS_RES_IRQ, &sc->ciss_irq_rid, 0, ~0, 1, 
  582: 			    RF_ACTIVE | RF_SHAREABLE)) == NULL) {
  583: 	ciss_printf(sc, "can't allocate interrupt\n");
  584: 	return(ENXIO);
  585:     }
  586:     if (bus_setup_intr(sc->ciss_dev, sc->ciss_irq_resource, INTR_TYPE_CAM, ciss_intr, sc,
  587: 		       &sc->ciss_intr)) {
  588: 	ciss_printf(sc, "can't set up interrupt\n");
  589: 	return(ENXIO);
  590:     }
  591: 
  592:     /*
  593:      * Allocate the parent bus DMA tag appropriate for our PCI
  594:      * interface.
  595:      * 
  596:      * Note that "simple" adapters can only address within a 32-bit
  597:      * span.
  598:      */
  599:     if (bus_dma_tag_create(NULL, 			/* parent */
  600: 			   1, 0, 			/* alignment, boundary */
  601: 			   BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
  602: 			   BUS_SPACE_MAXADDR, 		/* highaddr */
  603: 			   NULL, NULL, 			/* filter, filterarg */
  604: 			   MAXBSIZE, CISS_COMMAND_SG_LENGTH,	/* maxsize, nsegments */
  605: 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
  606: 			   BUS_DMA_ALLOCNOW,		/* flags */
  607: 			   &sc->ciss_parent_dmat)) {
  608: 	ciss_printf(sc, "can't allocate parent DMA tag\n");
  609: 	return(ENOMEM);
  610:     }
  611: 
  612:     /*
  613:      * Create DMA tag for mapping buffers into adapter-addressable
  614:      * space.
  615:      */
  616:     if (bus_dma_tag_create(sc->ciss_parent_dmat, 	/* parent */
  617: 			   1, 0, 			/* alignment, boundary */
  618: 			   BUS_SPACE_MAXADDR,		/* lowaddr */
  619: 			   BUS_SPACE_MAXADDR, 		/* highaddr */
  620: 			   NULL, NULL, 			/* filter, filterarg */
  621: 			   MAXBSIZE, CISS_COMMAND_SG_LENGTH,	/* maxsize, nsegments */
  622: 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
  623: 			   0,				/* flags */
  624: 			   &sc->ciss_buffer_dmat)) {
  625: 	ciss_printf(sc, "can't allocate buffer DMA tag\n");
  626: 	return(ENOMEM);
  627:     }
  628:     return(0);
  629: }
  630: 
  631: /************************************************************************
  632:  * Wait for the adapter to come ready.
  633:  */
  634: static int
  635: ciss_wait_adapter(struct ciss_softc *sc)
  636: {
  637:     int		i;
  638: 
  639:     debug_called(1);
  640:     
  641:     /*
  642:      * Wait for the adapter to come ready.
  643:      */
  644:     if (!(sc->ciss_cfg->active_method & CISS_TRANSPORT_METHOD_READY)) {
  645: 	ciss_printf(sc, "waiting for adapter to come ready...\n");
  646: 	for (i = 0; !(sc->ciss_cfg->active_method & CISS_TRANSPORT_METHOD_READY); i++) {
  647: 	    DELAY(1000000);	/* one second */
  648: 	    if (i > 30) {
  649: 		ciss_printf(sc, "timed out waiting for adapter to come ready\n");
  650: 		return(EIO);
  651: 	    }
  652: 	}
  653:     }
  654:     return(0);
  655: }
  656: 
  657: /************************************************************************
  658:  * Flush the adapter cache.
  659:  */
  660: static int
  661: ciss_flush_adapter(struct ciss_softc *sc)
  662: {
  663:     struct ciss_request			*cr;
  664:     struct ciss_bmic_flush_cache	*cbfc;
  665:     int					error, command_status;
  666: 
  667:     debug_called(1);
  668: 
  669:     cr = NULL;
  670:     cbfc = NULL;
  671: 
  672:     /*
  673:      * Build a BMIC request to flush the cache.  We don't disable
  674:      * it, as we may be going to do more I/O (eg. we are emulating
  675:      * the Synchronise Cache command).
  676:      */
  677:     if ((cbfc = malloc(sizeof(*cbfc), CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) {
  678: 	error = ENOMEM;
  679: 	goto out;
  680:     }
  681:     if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_FLUSH_CACHE,
  682: 				       (void **)&cbfc, sizeof(*cbfc))) != 0)
  683: 	goto out;
  684: 
  685:     /*
  686:      * Submit the request and wait for it to complete.
  687:      */
  688:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
  689: 	ciss_printf(sc, "error sending BMIC FLUSH_CACHE command (%d)\n", error);
  690: 	goto out;
  691:     }
  692:     
  693:     /*
  694:      * Check response.
  695:      */
  696:     ciss_report_request(cr, &command_status, NULL);
  697:     switch(command_status) {
  698:     case CISS_CMD_STATUS_SUCCESS:
  699: 	break;
  700:     default:
  701: 	ciss_printf(sc, "error flushing cache (%s)\n",  
  702: 		    ciss_name_command_status(command_status));
  703: 	error = EIO;
  704: 	goto out;
  705:     }
  706: 
  707: out:
  708:     if (cbfc != NULL)
  709: 	free(cbfc, CISS_MALLOC_CLASS);
  710:     if (cr != NULL)
  711: 	ciss_release_request(cr);
  712:     return(error);
  713: }
  714: 
  715: /************************************************************************
  716:  * Allocate memory for the adapter command structures, initialise
  717:  * the request structures.
  718:  *
  719:  * Note that the entire set of commands are allocated in a single
  720:  * contiguous slab.
  721:  */
  722: static int
  723: ciss_init_requests(struct ciss_softc *sc)
  724: {
  725:     struct ciss_request	*cr;
  726:     int			i;
  727: 
  728:     debug_called(1);
  729:     
  730:     /*
  731:      * Calculate the number of request structures/commands we are
  732:      * going to provide for this adapter.
  733:      */
  734:     sc->ciss_max_requests = min(CISS_MAX_REQUESTS, sc->ciss_cfg->max_outstanding_commands);
  735:     
  736:     if (1/*bootverbose*/)
  737: 	ciss_printf(sc, "using %d of %d available commands\n",
  738: 		    sc->ciss_max_requests, sc->ciss_cfg->max_outstanding_commands);
  739: 
  740:     /*
  741:      * Create the DMA tag for commands.
  742:      */
  743:     if (bus_dma_tag_create(sc->ciss_parent_dmat,	/* parent */
  744: 			   1, 0, 			/* alignment, boundary */
  745: 			   BUS_SPACE_MAXADDR,		/* lowaddr */
  746: 			   BUS_SPACE_MAXADDR, 		/* highaddr */
  747: 			   NULL, NULL, 			/* filter, filterarg */
  748: 			   CISS_COMMAND_ALLOC_SIZE * 
  749: 			   sc->ciss_max_requests, 1,	/* maxsize, nsegments */
  750: 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
  751: 			   0,				/* flags */
  752: 			   &sc->ciss_command_dmat)) {
  753: 	ciss_printf(sc, "can't allocate command DMA tag\n");
  754: 	return(ENOMEM);
  755:     }
  756:     /*
  757:      * Allocate memory and make it available for DMA.
  758:      */
  759:     if (bus_dmamem_alloc(sc->ciss_command_dmat, (void **)&sc->ciss_command, 
  760: 			 BUS_DMA_NOWAIT, &sc->ciss_command_map)) {
  761: 	ciss_printf(sc, "can't allocate command memory\n");
  762: 	return(ENOMEM);
  763:     }
  764:     bus_dmamap_load(sc->ciss_command_dmat, sc->ciss_command_map, sc->ciss_command, 
  765: 		    sizeof(struct ciss_command) * sc->ciss_max_requests,
  766: 		    ciss_command_map_helper, sc, 0);
  767:     bzero(sc->ciss_command, CISS_COMMAND_ALLOC_SIZE * sc->ciss_max_requests);
  768: 
  769:     /*
  770:      * Set up the request and command structures, push requests onto
  771:      * the free queue.
  772:      */
  773:     for (i = 1; i < sc->ciss_max_requests; i++) {
  774: 	cr = &sc->ciss_request[i];
  775: 	cr->cr_sc = sc;
  776: 	cr->cr_tag = i;
  777: 	ciss_enqueue_free(cr);
  778:     }
  779:     return(0);
  780: }
  781: 
  782: static void
  783: ciss_command_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
  784: {
  785:     struct ciss_softc	*sc = (struct ciss_softc *)arg;
  786: 
  787:     sc->ciss_command_phys = segs->ds_addr;
  788: }
  789: 
  790: /************************************************************************
  791:  * Identify the adapter, print some information about it.
  792:  */
  793: static int
  794: ciss_identify_adapter(struct ciss_softc *sc)
  795: {
  796:     struct ciss_request	*cr;
  797:     int			error, command_status;
  798: 
  799:     debug_called(1);
  800: 
  801:     cr = NULL;
  802: 
  803:     /*
  804:      * Get a request, allocate storage for the adapter data.
  805:      */
  806:     if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ID_CTLR,
  807: 				       (void **)&sc->ciss_id,
  808: 				       sizeof(*sc->ciss_id))) != 0)
  809: 	goto out;
  810: 
  811:     /*
  812:      * Submit the request and wait for it to complete.
  813:      */
  814:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
  815: 	ciss_printf(sc, "error sending BMIC ID_CTLR command (%d)\n", error);
  816: 	goto out;
  817:     }
  818:     
  819:     /*
  820:      * Check response.
  821:      */
  822:     ciss_report_request(cr, &command_status, NULL);
  823:     switch(command_status) {
  824:     case CISS_CMD_STATUS_SUCCESS:		/* buffer right size */
  825: 	break;
  826:     case CISS_CMD_STATUS_DATA_UNDERRUN:
  827:     case CISS_CMD_STATUS_DATA_OVERRUN:
  828: 	ciss_printf(sc, "data over/underrun reading adapter information\n");
  829:     default:
  830: 	ciss_printf(sc, "error reading adapter information (%s)\n",
  831: 		    ciss_name_command_status(command_status));
  832: 	error = EIO;
  833: 	goto out;
  834:     }
  835: 
  836:     /* sanity-check reply */
  837:     if (!sc->ciss_id->big_map_supported) {
  838: 	ciss_printf(sc, "adapter does not support BIG_MAP\n");
  839: 	error = ENXIO;
  840: 	goto out;
  841:     }
  842: 
  843: #if 0
  844:     /* XXX later revisions may not need this */
  845:     sc->ciss_flags |= CISS_FLAG_FAKE_SYNCH;
  846: #endif
  847: 
  848:     /* XXX only really required for old 5300 adapters? */
  849:     sc->ciss_flags |= CISS_FLAG_BMIC_ABORT;
  850:     
  851:     /* print information */
  852:     if (1/*bootverbose*/) {
  853: 	ciss_printf(sc, "  %d logical drive%s configured\n",
  854: 		    sc->ciss_id->configured_logical_drives,
  855: 		    (sc->ciss_id->configured_logical_drives == 1) ? "" : "s");
  856: 	ciss_printf(sc, "  firmware %4.4s\n", sc->ciss_id->running_firmware_revision);
  857: 	ciss_printf(sc, "  %d SCSI channels\n", sc->ciss_id->scsi_bus_count);
  858: 
  859: 	ciss_printf(sc, "  signature '%.4s'\n", sc->ciss_cfg->signature);
  860: 	ciss_printf(sc, "  valence %d\n", sc->ciss_cfg->valence);
  861: 	ciss_printf(sc, "  supported I/O methods 0x%b\n",
  862: 		    sc->ciss_cfg->supported_methods, 
  863: 		    "\20\1READY\2simple\3performant\4MEMQ\n");
  864: 	ciss_printf(sc, "  active I/O method 0x%b\n",
  865: 		    sc->ciss_cfg->active_method, "\20\2simple\3performant\4MEMQ\n");
  866: 	ciss_printf(sc, "  4G page base 0x%08x\n",
  867: 		    sc->ciss_cfg->command_physlimit);
  868: 	ciss_printf(sc, "  interrupt coalesce delay %dus\n",
  869: 		    sc->ciss_cfg->interrupt_coalesce_delay);
  870: 	ciss_printf(sc, "  interrupt coalesce count %d\n",
  871: 		    sc->ciss_cfg->interrupt_coalesce_count);
  872: 	ciss_printf(sc, "  max outstanding commands %d\n",
  873: 		    sc->ciss_cfg->max_outstanding_commands);
  874: 	ciss_printf(sc, "  bus types 0x%b\n", sc->ciss_cfg->bus_types, 
  875: 		    "\20\1ultra2\2ultra3\10fibre1\11fibre2\n");
  876: 	ciss_printf(sc, "  server name '%.16s'\n", sc->ciss_cfg->server_name);
  877: 	ciss_printf(sc, "  heartbeat 0x%x\n", sc->ciss_cfg->heartbeat);
  878:     }
  879: 
  880: out:
  881:     if (error) {
  882: 	if (sc->ciss_id != NULL) {
  883: 	    free(sc->ciss_id, CISS_MALLOC_CLASS);
  884: 	    sc->ciss_id = NULL;
  885: 	}
  886:     }	
  887:     if (cr != NULL)
  888: 	ciss_release_request(cr);
  889:     return(error);
  890: }
  891: 
  892: /************************************************************************
  893:  * Find logical drives on the adapter.
  894:  */
  895: static int
  896: ciss_init_logical(struct ciss_softc *sc)
  897: {
  898:     struct ciss_request		*cr;
  899:     struct ciss_command		*cc;
  900:     struct ciss_report_cdb	*crc;
  901:     struct ciss_lun_report	*cll;
  902:     int				error, i;
  903:     size_t			report_size;
  904:     int				ndrives;
  905:     int				command_status;
  906: 
  907:     debug_called(1);
  908: 
  909:     cr = NULL;
  910:     cll = NULL;
  911: 
  912:     /*
  913:      * Get a request, allocate storage for the address list.
  914:      */
  915:     if ((error = ciss_get_request(sc, &cr)) != 0)
  916: 	goto out;
  917:     report_size = sizeof(*cll) + CISS_MAX_LOGICAL * sizeof(union ciss_device_address);
  918:     if ((cll = malloc(report_size, CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) {
  919: 	ciss_printf(sc, "can't allocate memory for logical drive list\n");
  920: 	error = ENOMEM;
  921: 	goto out;
  922:     }
  923: 
  924:     /*
  925:      * Build the Report Logical LUNs command.
  926:      */
  927:     cc = CISS_FIND_COMMAND(cr);
  928:     cr->cr_data = cll;
  929:     cr->cr_length = report_size;
  930:     cr->cr_flags = CISS_REQ_DATAIN;
  931:     
  932:     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
  933:     cc->header.address.physical.bus = 0;
  934:     cc->header.address.physical.target = 0;
  935:     cc->cdb.cdb_length = sizeof(*crc);
  936:     cc->cdb.type = CISS_CDB_TYPE_COMMAND;
  937:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
  938:     cc->cdb.direction = CISS_CDB_DIRECTION_READ;
  939:     cc->cdb.timeout = 30;	/* XXX better suggestions? */
  940: 
  941:     crc = (struct ciss_report_cdb *)&(cc->cdb.cdb[0]);
  942:     bzero(crc, sizeof(*crc));
  943:     crc->opcode = CISS_OPCODE_REPORT_LOGICAL_LUNS;
  944:     crc->length = htonl(report_size);			/* big-endian field */
  945:     cll->list_size = htonl(report_size - sizeof(*cll));	/* big-endian field */
  946:     
  947:     /*
  948:      * Submit the request and wait for it to complete.  (timeout
  949:      * here should be much greater than above)
  950:      */
  951:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
  952: 	ciss_printf(sc, "error sending Report Logical LUNs command (%d)\n", error);
  953: 	goto out;
  954:     }
  955: 
  956:     /*
  957:      * Check response.  Note that data over/underrun is OK.
  958:      */
  959:     ciss_report_request(cr, &command_status, NULL);
  960:     switch(command_status) {
  961:     case CISS_CMD_STATUS_SUCCESS:	/* buffer right size */
  962:     case CISS_CMD_STATUS_DATA_UNDERRUN:	/* buffer too large, not bad */
  963: 	break;
  964:     case CISS_CMD_STATUS_DATA_OVERRUN:
  965: 	ciss_printf(sc, "WARNING: more logical drives than driver limit (%d), adjust CISS_MAX_LOGICAL\n",
  966: 		    CISS_MAX_LOGICAL);
  967: 	break;
  968:     default:
  969: 	ciss_printf(sc, "error detecting logical drive configuration (%s)\n",
  970: 		    ciss_name_command_status(command_status));
  971: 	error = EIO;
  972: 	goto out;
  973:     }
  974:     ciss_release_request(cr);
  975:     cr = NULL;
  976: 
  977:     /* sanity-check reply */
  978:     ndrives = (ntohl(cll->list_size) / sizeof(union ciss_device_address));
  979:     if ((ndrives < 0) || (ndrives > CISS_MAX_LOGICAL)) {
  980: 	ciss_printf(sc, "adapter claims to report absurd number of logical drives (%d > %d)\n",
  981: 		    ndrives, CISS_MAX_LOGICAL);
  982: 	return(ENXIO);
  983:     }
  984: 
  985:     /*
  986:      * Save logical drive information.
  987:      */
  988:     if (1/*bootverbose*/)
  989: 	ciss_printf(sc, "%d logical drive%s\n", ndrives, (ndrives > 1) ? "s" : "");
  990:     if (ndrives != sc->ciss_id->configured_logical_drives)
  991: 	ciss_printf(sc, "logical drive map claims %d drives, but adapter claims %d\n",
  992: 		    ndrives, sc->ciss_id->configured_logical_drives);
  993:     for (i = 0; i < CISS_MAX_LOGICAL; i++) {
  994: 	if (i < ndrives) {
  995: 	    sc->ciss_logical[i].cl_address = cll->lun[i];	/* XXX endianness? */
  996: 	    if (ciss_identify_logical(sc, &sc->ciss_logical[i]) != 0)
  997: 		continue;
  998: 	    /*
  999: 	     * If the drive has had media exchanged, we should bring it online.
 1000: 	     */
 1001: 	    if (sc->ciss_logical[i].cl_lstatus->media_exchanged)
 1002: 		ciss_accept_media(sc, i, 0);
 1003: 
 1004: 	} else {
 1005: 	    sc->ciss_logical[i].cl_status = CISS_LD_NONEXISTENT;
 1006: 	}
 1007:     }
 1008:     error = 0;
 1009:     
 1010:  out:
 1011:     /*
 1012:      * Note that if the error is a timeout, we are taking a slight
 1013:      * risk here and assuming that the adapter will not respond at a
 1014:      * later time, scribbling over host memory.
 1015:      */
 1016:     if (cr != NULL)
 1017: 	ciss_release_request(cr);
 1018:     if (cll != NULL)
 1019: 	free(cll, CISS_MALLOC_CLASS);
 1020:     return(error);
 1021: }
 1022: 
 1023: static int
 1024: ciss_inquiry_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
 1025: {
 1026:     struct ciss_request			*cr;
 1027:     struct ciss_command			*cc;
 1028:     struct scsi_inquiry			*inq;
 1029:     int					error;
 1030:     int					command_status;
 1031:     int					lun;
 1032: 
 1033:     cr = NULL;
 1034:     lun = ld->cl_address.logical.lun;
 1035: 
 1036:     bzero(&ld->cl_geometry, sizeof(ld->cl_geometry));
 1037: 
 1038:     if ((error = ciss_get_request(sc, &cr)) != 0)
 1039: 	goto out;
 1040: 
 1041:     cc = CISS_FIND_COMMAND(cr);
 1042:     cr->cr_data = &ld->cl_geometry;
 1043:     cr->cr_length = sizeof(ld->cl_geometry);
 1044:     cr->cr_flags = CISS_REQ_DATAIN;
 1045: 
 1046:     cc->header.address.logical.mode = CISS_HDR_ADDRESS_MODE_LOGICAL;
 1047:     cc->header.address.logical.lun  = lun;
 1048:     cc->cdb.cdb_length = 6;
 1049:     cc->cdb.type = CISS_CDB_TYPE_COMMAND;
 1050:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
 1051:     cc->cdb.direction = CISS_CDB_DIRECTION_READ;
 1052:     cc->cdb.timeout = 30;
 1053: 
 1054:     inq = (struct scsi_inquiry *)&(cc->cdb.cdb[0]);
 1055:     inq->opcode = INQUIRY;
 1056:     inq->byte2 = SI_EVPD;
 1057:     inq->page_code = CISS_VPD_LOGICAL_DRIVE_GEOMETRY;
 1058:     inq->length = sizeof(ld->cl_geometry);
 1059: 
 1060:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
 1061: 	ciss_printf(sc, "error getting geometry (%d)\n", error);
 1062: 	goto out;
 1063:     }
 1064: 
 1065:     ciss_report_request(cr, &command_status, NULL);
 1066:     switch(command_status) {
 1067:     case CISS_CMD_STATUS_SUCCESS:
 1068:     case CISS_CMD_STATUS_DATA_UNDERRUN:
 1069: 	break;
 1070:     case CISS_CMD_STATUS_DATA_OVERRUN:
 1071: 	ciss_printf(sc, "WARNING: Data overrun\n");
 1072: 	break;
 1073:     default:
 1074: 	ciss_printf(sc, "Error detecting logical drive geometry (%s)\n",
 1075: 		    ciss_name_command_status(command_status));
 1076: 	break;
 1077:     }
 1078: 
 1079: out:
 1080:     if (cr != NULL)
 1081: 	ciss_release_request(cr);
 1082:     return(error);
 1083: }
 1084: /************************************************************************
 1085:  * Identify a logical drive, initialise state related to it.
 1086:  */
 1087: static int
 1088: ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld)
 1089: {
 1090:     struct ciss_request		*cr;
 1091:     struct ciss_command		*cc;
 1092:     struct ciss_bmic_cdb	*cbc;
 1093:     int				error, command_status;
 1094: 
 1095:     debug_called(1);
 1096: 
 1097:     cr = NULL;
 1098: 
 1099:     /*
 1100:      * Build a BMIC request to fetch the drive ID.
 1101:      */
 1102:     if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ID_LDRIVE,
 1103: 				       (void **)&ld->cl_ldrive, 
 1104: 				       sizeof(*ld->cl_ldrive))) != 0)
 1105: 	goto out;
 1106:     cc = CISS_FIND_COMMAND(cr);
 1107:     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
 1108:     cbc->log_drive = ld->cl_address.logical.lun;
 1109: 
 1110:     /*
 1111:      * Submit the request and wait for it to complete.
 1112:      */
 1113:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
 1114: 	ciss_printf(sc, "error sending BMIC LDRIVE command (%d)\n", error);
 1115: 	goto out;
 1116:     }
 1117:     
 1118:     /*
 1119:      * Check response.
 1120:      */
 1121:     ciss_report_request(cr, &command_status, NULL);
 1122:     switch(command_status) {
 1123:     case CISS_CMD_STATUS_SUCCESS:		/* buffer right size */
 1124: 	break;
 1125:     case CISS_CMD_STATUS_DATA_UNDERRUN:
 1126:     case CISS_CMD_STATUS_DATA_OVERRUN:
 1127: 	ciss_printf(sc, "data over/underrun reading logical drive ID\n");
 1128:     default:
 1129: 	ciss_printf(sc, "error reading logical drive ID (%s)\n",
 1130: 		    ciss_name_command_status(command_status));
 1131: 	error = EIO;
 1132: 	goto out;
 1133:     }
 1134:     ciss_release_request(cr);
 1135:     cr = NULL;
 1136: 
 1137:     /*
 1138:      * Build a CISS BMIC command to get the logical drive status.
 1139:      */
 1140:     if ((error = ciss_get_ldrive_status(sc, ld)) != 0)
 1141: 	goto out;
 1142: 
 1143:     /*
 1144:      * Get the logical drive geometry.
 1145:      */
 1146:     if ((error = ciss_inquiry_logical(sc, ld)) != 0)
 1147: 	goto out;
 1148: 
 1149:     /*
 1150:      * Print the drive's basic characteristics.
 1151:      */
 1152:     if (1/*bootverbose*/) {
 1153: 	ciss_printf(sc, "logical drive %d: %s, %dMB ",
 1154: 		    cbc->log_drive, ciss_name_ldrive_org(ld->cl_ldrive->fault_tolerance),
 1155: 		    ((ld->cl_ldrive->blocks_available / (1024 * 1024)) *
 1156: 		     ld->cl_ldrive->block_size));
 1157: 
 1158: 	ciss_print_ldrive(sc, ld);
 1159:     }
 1160: out:
 1161:     if (error != 0) {
 1162: 	/* make the drive not-exist */
 1163: 	ld->cl_status = CISS_LD_NONEXISTENT;
 1164: 	if (ld->cl_ldrive != NULL) {
 1165: 	    free(ld->cl_ldrive, CISS_MALLOC_CLASS);
 1166: 	    ld->cl_ldrive = NULL;
 1167: 	}
 1168: 	if (ld->cl_lstatus != NULL) {
 1169: 	    free(ld->cl_lstatus, CISS_MALLOC_CLASS);
 1170: 	    ld->cl_lstatus = NULL;
 1171: 	}
 1172:     }
 1173:     if (cr != NULL)
 1174: 	ciss_release_request(cr);
 1175: 	
 1176:     return(error);
 1177: }
 1178: 
 1179: /************************************************************************
 1180:  * Get status for a logical drive.
 1181:  *
 1182:  * XXX should we also do this in response to Test Unit Ready?
 1183:  */
 1184: static int
 1185: ciss_get_ldrive_status(struct ciss_softc *sc,  struct ciss_ldrive *ld)
 1186: {
 1187:     struct ciss_request		*cr;
 1188:     struct ciss_command		*cc;
 1189:     struct ciss_bmic_cdb	*cbc;
 1190:     int				error, command_status;
 1191: 
 1192:     /*
 1193:      * Build a CISS BMIC command to get the logical drive status.
 1194:      */
 1195:     if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ID_LSTATUS,
 1196: 				       (void **)&ld->cl_lstatus, 
 1197: 				       sizeof(*ld->cl_lstatus))) != 0)
 1198: 	goto out;
 1199:     cc = CISS_FIND_COMMAND(cr);
 1200:     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
 1201:     cbc->log_drive = ld->cl_address.logical.lun;
 1202: 
 1203:     /*
 1204:      * Submit the request and wait for it to complete.
 1205:      */
 1206:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
 1207: 	ciss_printf(sc, "error sending BMIC LSTATUS command (%d)\n", error);
 1208: 	goto out;
 1209:     }
 1210:     
 1211:     /*
 1212:      * Check response.
 1213:      */
 1214:     ciss_report_request(cr, &command_status, NULL);
 1215:     switch(command_status) {
 1216:     case CISS_CMD_STATUS_SUCCESS:		/* buffer right size */
 1217: 	break;
 1218:     case CISS_CMD_STATUS_DATA_UNDERRUN:
 1219:     case CISS_CMD_STATUS_DATA_OVERRUN:
 1220: 	ciss_printf(sc, "data over/underrun reading logical drive status\n");
 1221:     default:
 1222: 	ciss_printf(sc, "error reading logical drive status (%s)\n",
 1223: 		    ciss_name_command_status(command_status));
 1224: 	error = EIO;
 1225: 	goto out;
 1226:     }
 1227: 
 1228:     /*
 1229:      * Set the drive's summary status based on the returned status.
 1230:      *
 1231:      * XXX testing shows that a failed JBOD drive comes back at next 
 1232:      * boot in "queued for expansion" mode.  WTF?
 1233:      */
 1234:     ld->cl_status = ciss_decode_ldrive_status(ld->cl_lstatus->status);
 1235: 
 1236: out:
 1237:     if (cr != NULL)
 1238: 	ciss_release_request(cr);
 1239:     return(error);
 1240: }
 1241: 
 1242: /************************************************************************
 1243:  * Notify the adapter of a config update.
 1244:  */
 1245: static int
 1246: ciss_update_config(struct ciss_softc *sc)
 1247: {
 1248:     int		i;
 1249: 
 1250:     debug_called(1);
 1251: 
 1252:     CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IDBR, CISS_TL_SIMPLE_IDBR_CFG_TABLE);
 1253:     for (i = 0; i < 1000; i++) {
 1254: 	if (!(CISS_TL_SIMPLE_READ(sc, CISS_TL_SIMPLE_IDBR) &
 1255: 	      CISS_TL_SIMPLE_IDBR_CFG_TABLE)) {
 1256: 	    return(0);
 1257: 	}
 1258: 	DELAY(1000);
 1259:     }
 1260:     return(1);
 1261: }
 1262: 
 1263: /************************************************************************
 1264:  * Accept new media into a logical drive.
 1265:  *
 1266:  * XXX The drive has previously been offline; it would be good if we
 1267:  *     could make sure it's not open right now.
 1268:  */
 1269: static int
 1270: ciss_accept_media(struct ciss_softc *sc, int ldrive, int async)
 1271: {
 1272:     struct ciss_request		*cr;
 1273:     struct ciss_command		*cc;
 1274:     struct ciss_bmic_cdb	*cbc;
 1275:     int				error;
 1276: 
 1277:     debug(0, "bringing logical drive %d back online %ssynchronously", 
 1278: 	  ldrive, async ? "a" : "");
 1279: 
 1280:     /*
 1281:      * Build a CISS BMIC command to bring the drive back online.
 1282:      */
 1283:     if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_ACCEPT_MEDIA,
 1284: 				       NULL, 0)) != 0)
 1285: 	goto out;
 1286:     cc = CISS_FIND_COMMAND(cr);
 1287:     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
 1288:     cbc->log_drive = ldrive;
 1289: 
 1290:     /*
 1291:      * Dispatch the request asynchronously if we can't sleep waiting
 1292:      * for it to complete.
 1293:      */
 1294:     if (async) {
 1295: 	cr->cr_complete = ciss_accept_media_complete;
 1296: 	if ((error = ciss_start(cr)) != 0)
 1297: 	    goto out;
 1298: 	return(0);
 1299:     } else {
 1300: 	/*
 1301: 	 * Submit the request and wait for it to complete.
 1302: 	 */
 1303: 	if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
 1304: 	    ciss_printf(sc, "error sending BMIC LSTATUS command (%d)\n", error);
 1305: 	    goto out;
 1306: 	}
 1307:     }
 1308: 
 1309:     /*
 1310:      * Call the completion callback manually.
 1311:      */
 1312:     ciss_accept_media_complete(cr);
 1313:     return(0);
 1314:     
 1315: out:
 1316:     if (cr != NULL)
 1317: 	ciss_release_request(cr);
 1318:     return(error);
 1319: }
 1320: 
 1321: static void
 1322: ciss_accept_media_complete(struct ciss_request *cr)
 1323: {
 1324:     int				command_status;
 1325:     
 1326:     /*
 1327:      * Check response.
 1328:      */
 1329:     ciss_report_request(cr, &command_status, NULL);
 1330:     switch(command_status) {
 1331:     case CISS_CMD_STATUS_SUCCESS:		/* all OK */
 1332: 	/* we should get a logical drive status changed event here */
 1333: 	break;
 1334:     default:
 1335: 	ciss_printf(cr->cr_sc, "error accepting media into failed logical drive (%s)\n",
 1336: 		    ciss_name_command_status(command_status));
 1337: 	break;
 1338:     }
 1339:     ciss_release_request(cr);
 1340: }
 1341: 
 1342: /************************************************************************
 1343:  * Release adapter resources.
 1344:  */
 1345: static void
 1346: ciss_free(struct ciss_softc *sc)
 1347: {
 1348:     debug_called(1);
 1349: 
 1350:     /* we're going away */
 1351:     sc->ciss_flags |= CISS_FLAG_ABORTING;
 1352: 
 1353:     /* terminate the periodic heartbeat routine */
 1354:     untimeout(ciss_periodic, sc, sc->ciss_periodic);
 1355: 
 1356:     /* cancel the Event Notify chain */
 1357:     ciss_notify_abort(sc);
 1358:     
 1359:     /* free the controller data */
 1360:     if (sc->ciss_id != NULL)
 1361: 	free(sc->ciss_id, CISS_MALLOC_CLASS);
 1362: 
 1363:     /* release I/O resources */
 1364:     if (sc->ciss_regs_resource != NULL)
 1365: 	bus_release_resource(sc->ciss_dev, SYS_RES_MEMORY,
 1366: 			     sc->ciss_regs_rid, sc->ciss_regs_resource);
 1367:     if (sc->ciss_cfg_resource != NULL)
 1368: 	bus_release_resource(sc->ciss_dev, SYS_RES_MEMORY,
 1369: 			     sc->ciss_cfg_rid, sc->ciss_cfg_resource);
 1370:     if (sc->ciss_intr != NULL)
 1371: 	bus_teardown_intr(sc->ciss_dev, sc->ciss_irq_resource, sc->ciss_intr);
 1372:     if (sc->ciss_irq_resource != NULL)
 1373: 	bus_release_resource(sc->ciss_dev, SYS_RES_IRQ,
 1374: 			     sc->ciss_irq_rid, sc->ciss_irq_resource);
 1375: 
 1376:     /* destroy DMA tags */
 1377:     if (sc->ciss_parent_dmat)
 1378: 	bus_dma_tag_destroy(sc->ciss_parent_dmat);
 1379:     if (sc->ciss_buffer_dmat)
 1380: 	bus_dma_tag_destroy(sc->ciss_buffer_dmat);
 1381: 
 1382:     /* destroy command memory and DMA tag */
 1383:     if (sc->ciss_command != NULL) {
 1384: 	bus_dmamap_unload(sc->ciss_command_dmat, sc->ciss_command_map);
 1385: 	bus_dmamem_free(sc->ciss_command_dmat, sc->ciss_command, sc->ciss_command_map);
 1386:     }
 1387:     if (sc->ciss_buffer_dmat)
 1388: 	bus_dma_tag_destroy(sc->ciss_command_dmat);
 1389: 
 1390:     /* disconnect from CAM */
 1391:     if (sc->ciss_cam_sim) {
 1392: 	xpt_bus_deregister(cam_sim_path(sc->ciss_cam_sim));
 1393: 	cam_sim_free(sc->ciss_cam_sim);
 1394:     }
 1395:     if (sc->ciss_cam_devq)
 1396: 	cam_simq_release(sc->ciss_cam_devq);
 1397:     /* XXX what about ciss_cam_path? */
 1398: }
 1399: 
 1400: /************************************************************************
 1401:  * Give a command to the adapter.
 1402:  *
 1403:  * Note that this uses the simple transport layer directly.  If we
 1404:  * want to add support for other layers, we'll need a switch of some
 1405:  * sort.
 1406:  *
 1407:  * Note that the simple transport layer has no way of refusing a
 1408:  * command; we only have as many request structures as the adapter
 1409:  * supports commands, so we don't have to check (this presumes that
 1410:  * the adapter can handle commands as fast as we throw them at it).
 1411:  */
 1412: static int
 1413: ciss_start(struct ciss_request *cr)
 1414: {
 1415:     struct ciss_command	*cc;	/* XXX debugging only */
 1416:     int			error;
 1417: 
 1418:     cc = CISS_FIND_COMMAND(cr);
 1419:     debug(2, "post command %d tag %d ", cr->cr_tag, cc->header.host_tag);
 1420: 
 1421:     /*
 1422:      * Map the request's data.
 1423:      */
 1424:     if ((error = ciss_map_request(cr)))
 1425: 	return(error);
 1426: 
 1427: #if 0
 1428:     ciss_print_request(cr);
 1429: #endif
 1430: 
 1431:     /*
 1432:      * Post the command to the adapter.
 1433:      */
 1434:     ciss_enqueue_busy(cr);
 1435:     CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr));
 1436: 
 1437:     return(0);
 1438: }
 1439: 
 1440: /************************************************************************
 1441:  * Fetch completed request(s) from the adapter, queue them for
 1442:  * completion handling.
 1443:  *
 1444:  * Note that this uses the simple transport layer directly.  If we
 1445:  * want to add support for other layers, we'll need a switch of some
 1446:  * sort.
 1447:  *
 1448:  * Note that the simple transport mechanism does not require any
 1449:  * reentrancy protection; the OPQ read is atomic.  If there is a
 1450:  * chance of a race with something else that might move the request
 1451:  * off the busy list, then we will have to lock against that
 1452:  * (eg. timeouts, etc.)
 1453:  */
 1454: static void
 1455: ciss_done(struct ciss_softc *sc)
 1456: {
 1457:     struct ciss_request	*cr;
 1458:     struct ciss_command	*cc;
 1459:     u_int32_t		tag, index;
 1460:     int			complete;
 1461:     
 1462:     debug_called(3);
 1463: 
 1464:     /*
 1465:      * Loop quickly taking requests from the adapter and moving them
 1466:      * from the busy queue to the completed queue.
 1467:      */
 1468:     complete = 0;
 1469:     for (;;) {
 1470: 
 1471: 	/* see if the OPQ contains anything */
 1472: 	if (!CISS_TL_SIMPLE_OPQ_INTERRUPT(sc))
 1473: 	    break;
 1474: 
 1475: 	tag = CISS_TL_SIMPLE_FETCH_CMD(sc);
 1476: 	if (tag == CISS_TL_SIMPLE_OPQ_EMPTY)
 1477: 	    break;
 1478: 	index = tag >> 2;
 1479: 	debug(2, "completed command %d%s", index, 
 1480: 	      (tag & CISS_HDR_HOST_TAG_ERROR) ? " with error" : "");
 1481: 	if (index >= sc->ciss_max_requests) {
 1482: 	    ciss_printf(sc, "completed invalid request %d (0x%x)\n", index, tag);
 1483: 	    continue;
 1484: 	}
 1485: 	cr = &(sc->ciss_request[index]);
 1486: 	cc = CISS_FIND_COMMAND(cr);
 1487: 	cc->header.host_tag = tag;	/* not updated by adapter */
 1488: 	if (ciss_remove_busy(cr)) {
 1489: 	    /* assume this is garbage out of the adapter */
 1490: 	    ciss_printf(sc, "completed nonbusy request %d\n", index);
 1491: 	} else {
 1492: 	    ciss_enqueue_complete(cr);
 1493: 	}
 1494: 	complete = 1;
 1495:     }
 1496:     
 1497:     /*
 1498:      * Invoke completion processing.  If we can defer this out of
 1499:      * interrupt context, that'd be good.
 1500:      */
 1501:     if (complete)
 1502: 	ciss_complete(sc);
 1503: }
 1504: 
 1505: /************************************************************************
 1506:  * Take an interrupt from the adapter.
 1507:  */
 1508: static void
 1509: ciss_intr(void *arg)
 1510: {
 1511:     struct ciss_softc	*sc = (struct ciss_softc *)arg;
 1512: 
 1513:     /*
 1514:      * The only interrupt we recognise indicates that there are
 1515:      * entries in the outbound post queue.
 1516:      */
 1517:     ciss_done(sc);
 1518: }
 1519: 
 1520: /************************************************************************
 1521:  * Process completed requests.
 1522:  *
 1523:  * Requests can be completed in three fashions:
 1524:  *
 1525:  * - by invoking a callback function (cr_complete is non-null)
 1526:  * - by waking up a sleeper (cr_flags has CISS_REQ_SLEEP set)
 1527:  * - by clearing the CISS_REQ_POLL flag in interrupt/timeout context
 1528:  */
 1529: static void
 1530: ciss_complete(struct ciss_softc *sc)
 1531: {
 1532:     struct ciss_request	*cr;
 1533: 
 1534:     debug_called(2);
 1535: 
 1536:     /*
 1537:      * Loop taking requests off the completed queue and performing
 1538:      * completion processing on them.
 1539:      */
 1540:     for (;;) {
 1541: 	if ((cr = ciss_dequeue_complete(sc)) == NULL)
 1542: 	    break;
 1543: 	ciss_unmap_request(cr);
 1544: 	
 1545: 	/*
 1546: 	 * If the request has a callback, invoke it.
 1547: 	 */
 1548: 	if (cr->cr_complete != NULL) {
 1549: 	    cr->cr_complete(cr);
 1550: 	    continue;
 1551: 	}
 1552: 	
 1553: 	/*
 1554: 	 * If someone is sleeping on this request, wake them up.
 1555: 	 */
 1556: 	if (cr->cr_flags & CISS_REQ_SLEEP) {
 1557: 	    cr->cr_flags &= ~CISS_REQ_SLEEP;
 1558: 	    wakeup(cr);
 1559: 	    continue;
 1560: 	}
 1561: 
 1562: 	/*
 1563: 	 * If someone is polling this request for completion, signal.
 1564: 	 */
 1565: 	if (cr->cr_flags & CISS_REQ_POLL) {
 1566: 	    cr->cr_flags &= ~CISS_REQ_POLL;
 1567: 	    continue;
 1568: 	}
 1569: 	
 1570: 	/*
 1571: 	 * Give up and throw the request back on the free queue.  This
 1572: 	 * should never happen; resources will probably be lost.
 1573: 	 */
 1574: 	ciss_printf(sc, "WARNING: completed command with no submitter\n");
 1575: 	ciss_enqueue_free(cr);
 1576:     }
 1577: }
 1578: 
 1579: /************************************************************************
 1580:  * Report on the completion status of a request, and pass back SCSI
 1581:  * and command status values.
 1582:  */
 1583: static int
 1584: ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_status)
 1585: {
 1586:     struct ciss_command		*cc;
 1587:     struct ciss_error_info	*ce;
 1588: 
 1589:     debug_called(2);
 1590: 
 1591:     cc = CISS_FIND_COMMAND(cr);
 1592:     ce = (struct ciss_error_info *)&(cc->sg[0]);
 1593: 
 1594:     /*
 1595:      * We don't consider data under/overrun an error for the Report
 1596:      * Logical/Physical LUNs commands.
 1597:      */
 1598:     if ((cc->header.host_tag & CISS_HDR_HOST_TAG_ERROR) &&
 1599: 	((cc->cdb.cdb[0] == CISS_OPCODE_REPORT_LOGICAL_LUNS) ||
 1600: 	 (cc->cdb.cdb[0] == CISS_OPCODE_REPORT_PHYSICAL_LUNS))) {
 1601: 	cc->header.host_tag &= ~CISS_HDR_HOST_TAG_ERROR;
 1602: 	debug(2, "ignoring irrelevant under/overrun error");
 1603:     }
 1604:     
 1605:     /*
 1606:      * Check the command's error bit, if clear, there's no status and
 1607:      * everything is OK.
 1608:      */
 1609:     if (!(cc->header.host_tag & CISS_HDR_HOST_TAG_ERROR)) {
 1610: 	if (scsi_status != NULL)
 1611: 	    *scsi_status = SCSI_STATUS_OK;
 1612: 	if (command_status != NULL)
 1613: 	    *command_status = CISS_CMD_STATUS_SUCCESS;
 1614: 	return(0);
 1615:     } else {
 1616: 	if (command_status != NULL)
 1617: 	    *command_status = ce->command_status;
 1618: 	if (scsi_status != NULL) {
 1619: 	    if (ce->command_status == CISS_CMD_STATUS_TARGET_STATUS) {
 1620: 		*scsi_status = ce->scsi_status;
 1621: 	    } else {
 1622: 		*scsi_status = -1;
 1623: 	    }
 1624: 	}
 1625: 	if (bootverbose)
 1626: 	    ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x\n",
 1627: 			ce->command_status, ciss_name_command_status(ce->command_status),
 1628: 			ce->scsi_status);
 1629: 	if (ce->command_status == CISS_CMD_STATUS_INVALID_COMMAND) {
 1630: 	    ciss_printf(cr->cr_sc, "invalid command, offense size %d at %d, value 0x%x\n",
 1631: 			ce->additional_error_info.invalid_command.offense_size,
 1632: 			ce->additional_error_info.invalid_command.offense_offset,
 1633: 			ce->additional_error_info.invalid_command.offense_value);
 1634: 	}
 1635:     }
 1636:     return(1);
 1637: }
 1638: 
 1639: /************************************************************************
 1640:  * Issue a request and don't return until it's completed.
 1641:  *
 1642:  * Depending on adapter status, we may poll or sleep waiting for
 1643:  * completion.
 1644:  */
 1645: static int
 1646: ciss_synch_request(struct ciss_request *cr, int timeout)
 1647: {
 1648:     if (cr->cr_sc->ciss_flags & CISS_FLAG_RUNNING) {
 1649: 	return(ciss_wait_request(cr, timeout));
 1650:     } else {
 1651: 	return(ciss_poll_request(cr, timeout));
 1652:     }
 1653: }
 1654: 
 1655: /************************************************************************
 1656:  * Issue a request and poll for completion.
 1657:  *
 1658:  * Timeout in milliseconds.
 1659:  */
 1660: static int
 1661: ciss_poll_request(struct ciss_request *cr, int timeout)
 1662: {
 1663:     int		error;
 1664:     
 1665:     debug_called(2);
 1666: 
 1667:     cr->cr_flags |= CISS_REQ_POLL;
 1668:     if ((error = ciss_start(cr)) != 0)
 1669: 	return(error);
 1670: 
 1671:     do {
 1672: 	ciss_done(cr->cr_sc);
 1673: 	if (!(cr->cr_flags & CISS_REQ_POLL))
 1674: 	    return(0);
 1675: 	DELAY(1000);
 1676:     } while (timeout-- >= 0);
 1677:     return(EWOULDBLOCK);
 1678: }
 1679: 
 1680: /************************************************************************
 1681:  * Issue a request and sleep waiting for completion.
 1682:  *
 1683:  * Timeout in milliseconds.  Note that a spurious wakeup will reset
 1684:  * the timeout.
 1685:  */
 1686: static int
 1687: ciss_wait_request(struct ciss_request *cr, int timeout)
 1688: {
 1689:     int		s, error;
 1690: 
 1691:     debug_called(2);
 1692: 
 1693:     cr->cr_flags |= CISS_REQ_SLEEP;
 1694:     if ((error = ciss_start(cr)) != 0)
 1695: 	return(error);
 1696: 
 1697:     s = splcam();
 1698:     while (cr->cr_flags & CISS_REQ_SLEEP) {
 1699: 	error = tsleep(cr, PCATCH, "cissREQ", (timeout * hz) / 1000);
 1700: 	/* 
 1701: 	 * On wakeup or interruption due to restartable activity, go
 1702: 	 * back and check to see if we're done.
 1703: 	 */
 1704: 	if ((error == 0) || (error == ERESTART)) {
 1705: 	    error = 0;
 1706: 	    continue;
 1707: 	}
 1708: 	/*
 1709: 	 * Timeout, interrupted system call, etc.
 1710: 	 */
 1711: 	break;
 1712:     }
 1713:     splx(s);
 1714:     return(error);
 1715: }
 1716: 
 1717: #if 0
 1718: /************************************************************************
 1719:  * Abort a request.  Note that a potential exists here to race the
 1720:  * request being completed; the caller must deal with this.
 1721:  */
 1722: static int
 1723: ciss_abort_request(struct ciss_request *ar)
 1724: {
 1725:     struct ciss_request		*cr;
 1726:     struct ciss_command		*cc;
 1727:     struct ciss_message_cdb	*cmc;
 1728:     int				error;
 1729: 
 1730:     debug_called(1);
 1731: 
 1732:     /* get a request */
 1733:     if ((error = ciss_get_request(ar->cr_sc, &cr)) != 0)
 1734: 	return(error);
 1735: 
 1736:     /* build the abort command */	
 1737:     cc = CISS_FIND_COMMAND(cr);
 1738:     cc->header.address.mode.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;	/* addressing? */
 1739:     cc->header.address.physical.target = 0;
 1740:     cc->header.address.physical.bus = 0;
 1741:     cc->cdb.cdb_length = sizeof(*cmc);
 1742:     cc->cdb.type = CISS_CDB_TYPE_MESSAGE;
 1743:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
 1744:     cc->cdb.direction = CISS_CDB_DIRECTION_NONE;
 1745:     cc->cdb.timeout = 30;
 1746: 
 1747:     cmc = (struct ciss_message_cdb *)&(cc->cdb.cdb[0]);
 1748:     cmc->opcode = CISS_OPCODE_MESSAGE_ABORT;
 1749:     cmc->type = CISS_MESSAGE_ABORT_TASK;
 1750:     cmc->abort_tag = ar->cr_tag;	/* endianness?? */
 1751: 
 1752:     /*
 1753:      * Send the request and wait for a response.  If we believe we
 1754:      * aborted the request OK, clear the flag that indicates it's
 1755:      * running.
 1756:      */
 1757:     error = ciss_synch_request(cr, 35 * 1000);
 1758:     if (!error)
 1759: 	error = ciss_report_request(cr, NULL, NULL);
 1760:     ciss_release_request(cr);
 1761: 
 1762:     return(error);
 1763: }
 1764: #endif
 1765: 
 1766: 
 1767: /************************************************************************
 1768:  * Fetch and initialise a request
 1769:  */
 1770: static int
 1771: ciss_get_request(struct ciss_softc *sc, struct ciss_request **crp)
 1772: {
 1773:     struct ciss_request *cr;
 1774: 
 1775:     debug_called(2);
 1776: 
 1777:     /*
 1778:      * Get a request and clean it up.
 1779:      */
 1780:     if ((cr = ciss_dequeue_free(sc)) == NULL)
 1781: 	return(ENOMEM);
 1782: 
 1783:     cr->cr_data = NULL;
 1784:     cr->cr_flags = 0;
 1785:     cr->cr_complete = NULL;
 1786:     
 1787:     ciss_preen_command(cr);
 1788:     *crp = cr;
 1789:     return(0);
 1790: }
 1791: 
 1792: static void
 1793: ciss_preen_command(struct ciss_request *cr)
 1794: {
 1795:     struct ciss_command	*cc;
 1796:     u_int32_t		cmdphys;
 1797: 
 1798:     /*
 1799:      * Clean up the command structure.
 1800:      *
 1801:      * Note that we set up the error_info structure here, since the
 1802:      * length can be overwritten by any command.
 1803:      */
 1804:     cc = CISS_FIND_COMMAND(cr);
 1805:     cc->header.sg_in_list = 0;		/* kinda inefficient this way */
 1806:     cc->header.sg_total = 0;
 1807:     cc->header.host_tag = cr->cr_tag << 2;
 1808:     cc->header.host_tag_zeroes = 0;
 1809:     cmdphys = CISS_FIND_COMMANDPHYS(cr);
 1810:     cc->error_info.error_info_address = cmdphys + sizeof(struct ciss_command);
 1811:     cc->error_info.error_info_length = CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command);
 1812:     
 1813: }
 1814: 
 1815: /************************************************************************
 1816:  * Release a request to the free list.
 1817:  */
 1818: static void
 1819: ciss_release_request(struct ciss_request *cr)
 1820: {
 1821:     struct ciss_softc	*sc;
 1822: 
 1823:     debug_called(2);
 1824: 
 1825:     sc = cr->cr_sc;
 1826:     
 1827:     /* release the request to the free queue */
 1828:     ciss_requeue_free(cr);
 1829: }
 1830: 
 1831: /************************************************************************
 1832:  * Allocate a request that will be used to send a BMIC command.  Do some
 1833:  * of the common setup here to avoid duplicating it everywhere else.
 1834:  */
 1835: static int
 1836: ciss_get_bmic_request(struct ciss_softc *sc, struct ciss_request **crp,
 1837: 		      int opcode, void **bufp, size_t bufsize)
 1838: {
 1839:     struct ciss_request		*cr;
 1840:     struct ciss_command		*cc;
 1841:     struct ciss_bmic_cdb	*cbc;
 1842:     void			*buf;
 1843:     int				error;
 1844:     int				dataout;
 1845: 
 1846:     debug_called(2);
 1847: 
 1848:     cr = NULL;
 1849:     buf = NULL;	
 1850: 
 1851:     /*
 1852:      * Get a request.
 1853:      */
 1854:     if ((error = ciss_get_request(sc, &cr)) != 0)
 1855: 	goto out;
 1856: 
 1857:     /*
 1858:      * Allocate data storage if requested, determine the data direction.
 1859:      */
 1860:     dataout = 0;
 1861:     if ((bufsize > 0) && (bufp != NULL)) {
 1862: 	if (*bufp == NULL) {
 1863: 	    if ((buf = malloc(bufsize, CISS_MALLOC_CLASS, M_NOWAIT | M_ZERO)) == NULL) {
 1864: 		error = ENOMEM;
 1865: 		goto out;
 1866: 	    }
 1867: 	} else {
 1868: 	    buf = *bufp;
 1869: 	    dataout = 1;	/* we are given a buffer, so we are writing */
 1870: 	}
 1871:     }
 1872: 
 1873:     /*
 1874:      * Build a CISS BMIC command to get the logical drive ID.
 1875:      */
 1876:     cr->cr_data = buf;
 1877:     cr->cr_length = bufsize;
 1878:     if (!dataout)
 1879: 	cr->cr_flags = CISS_REQ_DATAIN;
 1880:     
 1881:     cc = CISS_FIND_COMMAND(cr);
 1882:     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
 1883:     cc->header.address.physical.bus = 0;
 1884:     cc->header.address.physical.target = 0;
 1885:     cc->cdb.cdb_length = sizeof(*cbc);
 1886:     cc->cdb.type = CISS_CDB_TYPE_COMMAND;
 1887:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
 1888:     cc->cdb.direction = dataout ? CISS_CDB_DIRECTION_WRITE : CISS_CDB_DIRECTION_READ;
 1889:     cc->cdb.timeout = 0;
 1890: 
 1891:     cbc = (struct ciss_bmic_cdb *)&(cc->cdb.cdb[0]);
 1892:     bzero(cbc, sizeof(*cbc));
 1893:     cbc->opcode = dataout ? CISS_ARRAY_CONTROLLER_WRITE : CISS_ARRAY_CONTROLLER_READ;
 1894:     cbc->bmic_opcode = opcode;
 1895:     cbc->size = htons((u_int16_t)bufsize);
 1896: 
 1897: out:
 1898:     if (error) {
 1899: 	if (cr != NULL)
 1900: 	    ciss_release_request(cr);
 1901: 	if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL))
 1902: 	    free(buf, CISS_MALLOC_CLASS);
 1903:     } else {
 1904: 	*crp = cr;
 1905: 	if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL))
 1906: 	    *bufp = buf;
 1907:     }
 1908:     return(error);
 1909: }
 1910: 
 1911: /************************************************************************
 1912:  * Handle a command passed in from userspace.
 1913:  */
 1914: static int
 1915: ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
 1916: {
 1917:     struct ciss_request		*cr;
 1918:     struct ciss_command		*cc;
 1919:     struct ciss_error_info	*ce;
 1920:     int				error;
 1921: 
 1922:     debug_called(1);
 1923: 
 1924:     cr = NULL;
 1925: 
 1926:     /*
 1927:      * Get a request.
 1928:      */
 1929:     if ((error = ciss_get_request(sc, &cr)) != 0)
 1930: 	goto out;
 1931:     cc = CISS_FIND_COMMAND(cr);
 1932: 
 1933:     /*
 1934:      * Allocate an in-kernel databuffer if required, copy in user data.
 1935:      */
 1936:     cr->cr_length = ioc->buf_size;
 1937:     if (ioc->buf_size > 0) {
 1938: 	if ((cr->cr_data = malloc(ioc->buf_size, CISS_MALLOC_CLASS, M_WAITOK)) == NULL) {
 1939: 	    error = ENOMEM;
 1940: 	    goto out;
 1941: 	}
 1942: 	if ((error = copyin(ioc->buf, cr->cr_data, ioc->buf_size))) {
 1943: 	    debug(0, "copyin: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
 1944: 	    goto out;
 1945: 	}
 1946:     }
 1947: 
 1948:     /*
 1949:      * Build the request based on the user command.
 1950:      */
 1951:     bcopy(&ioc->LUN_info, &cc->header.address, sizeof(cc->header.address));
 1952:     bcopy(&ioc->Request, &cc->cdb, sizeof(cc->cdb));
 1953: 
 1954:     /* XXX anything else to populate here? */
 1955: 
 1956:     /*
 1957:      * Run the command.
 1958:      */
 1959:     if ((error = ciss_synch_request(cr, 60 * 1000))) {
 1960: 	debug(0, "request failed - %d", error);
 1961: 	goto out;
 1962:     }
 1963: 
 1964:     /*
 1965:      * Copy the results back to the user.
 1966:      */
 1967:     ce = (struct ciss_error_info *)&(cc->sg[0]);
 1968:     bcopy(ce, &ioc->error_info, sizeof(*ce));
 1969:     if ((ioc->buf_size > 0) &&
 1970: 	(error = copyout(cr->cr_data, ioc->buf, ioc->buf_size))) {
 1971: 	debug(0, "copyout: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
 1972: 	goto out;
 1973:     }
 1974: 
 1975:     /* done OK */
 1976:     error = 0;
 1977: 
 1978: out:
 1979:     if ((cr != NULL) && (cr->cr_data != NULL))
 1980: 	free(cr->cr_data, CISS_MALLOC_CLASS);
 1981:     if (cr != NULL)
 1982: 	ciss_release_request(cr);
 1983:     return(error);
 1984: }
 1985: 
 1986: /************************************************************************
 1987:  * Map a request into bus-visible space, initialise the scatter/gather
 1988:  * list.
 1989:  */
 1990: static int
 1991: ciss_map_request(struct ciss_request *cr)
 1992: {
 1993:     struct ciss_softc	*sc;
 1994: 
 1995:     debug_called(2);
 1996:     
 1997:     sc = cr->cr_sc;
 1998: 
 1999:     /* check that mapping is necessary */
 2000:     if ((cr->cr_flags & CISS_REQ_MAPPED) || (cr->cr_data == NULL))
 2001: 	return(0);
 2002:     
 2003:     bus_dmamap_load(sc->ciss_buffer_dmat, cr->cr_datamap, cr->cr_data, cr->cr_length,
 2004: 		    ciss_request_map_helper, CISS_FIND_COMMAND(cr), 0);
 2005: 	
 2006:     if (cr->cr_flags & CISS_REQ_DATAIN)
 2007: 	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREREAD);
 2008:     if (cr->cr_flags & CISS_REQ_DATAOUT)
 2009: 	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREWRITE);
 2010: 
 2011:     cr->cr_flags |= CISS_REQ_MAPPED;
 2012:     return(0);
 2013: }
 2014: 
 2015: static void
 2016: ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 2017: {
 2018:     struct ciss_command	*cc;
 2019:     int			i;
 2020: 
 2021:     debug_called(2);
 2022:     
 2023:     cc = (struct ciss_command *)arg;
 2024:     for (i = 0; i < nseg; i++) {
 2025: 	cc->sg[i].address = segs[i].ds_addr;
 2026: 	cc->sg[i].length = segs[i].ds_len;
 2027: 	cc->sg[i].extension = 0;
 2028:     }
 2029:     /* we leave the s/g table entirely within the command */
 2030:     cc->header.sg_in_list = nseg;
 2031:     cc->header.sg_total = nseg;
 2032: }
 2033: 
 2034: /************************************************************************
 2035:  * Unmap a request from bus-visible space.
 2036:  */
 2037: static void
 2038: ciss_unmap_request(struct ciss_request *cr)
 2039: {
 2040:     struct ciss_softc	*sc;
 2041: 
 2042:     debug_called(2);
 2043:     
 2044:     sc = cr->cr_sc;
 2045: 
 2046:     /* check that unmapping is necessary */
 2047:     if (!(cr->cr_flags & CISS_REQ_MAPPED) || (cr->cr_data == NULL))
 2048: 	return;
 2049: 
 2050:     if (cr->cr_flags & CISS_REQ_DATAIN)
 2051: 	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_POSTREAD);
 2052:     if (cr->cr_flags & CISS_REQ_DATAOUT)
 2053: 	bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_POSTWRITE);
 2054: 
 2055:     bus_dmamap_unload(sc->ciss_buffer_dmat, cr->cr_datamap);
 2056:     cr->cr_flags &= ~CISS_REQ_MAPPED;
 2057: }
 2058: 
 2059: /************************************************************************
 2060:  * Attach the driver to CAM.
 2061:  *
 2062:  * We put all the logical drives on a single SCSI bus.
 2063:  */
 2064: static int
 2065: ciss_cam_init(struct ciss_softc *sc)
 2066: {
 2067: 
 2068:     debug_called(1);
 2069: 
 2070:     /*
 2071:      * Allocate a devq.  We can reuse this for the masked physical
 2072:      * devices if we decide to export these as well.
 2073:      */
 2074:     if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests)) == NULL) {
 2075: 	ciss_printf(sc, "can't allocate CAM SIM queue\n");
 2076: 	return(ENOMEM);
 2077:     }
 2078: 
 2079:     /*
 2080:      * Create a SIM.
 2081:      */
 2082:     if ((sc->ciss_cam_sim = cam_sim_alloc(ciss_cam_action, ciss_cam_poll, "ciss", sc,
 2083: 					  device_get_unit(sc->ciss_dev),
 2084: 					  sc->ciss_max_requests - 2,
 2085: 					  1,
 2086: 					  sc->ciss_cam_devq)) == NULL) {
 2087: 	ciss_printf(sc, "can't allocate CAM SIM\n");
 2088: 	return(ENOMEM);
 2089:     }
 2090: 
 2091:     /*
 2092:      * Register bus 0 (the 'logical drives' bus) with this SIM.
 2093:      */
 2094:     if (xpt_bus_register(sc->ciss_cam_sim, 0) != 0) {
 2095: 	ciss_printf(sc, "can't register SCSI bus 0\n");
 2096: 	return(ENXIO);
 2097:     }
 2098: 
 2099:     /*
 2100:      * Initiate a rescan of the bus.
 2101:      */
 2102:     ciss_cam_rescan_all(sc);
 2103:     
 2104:     return(0);
 2105: }
 2106: 
 2107: /************************************************************************
 2108:  * Initiate a rescan of the 'logical devices' SIM
 2109:  */ 
 2110: static void
 2111: ciss_cam_rescan_target(struct ciss_softc *sc, int target)
 2112: {
 2113:     union ccb	*ccb;
 2114: 
 2115:     debug_called(1);
 2116: 
 2117:     if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) {
 2118: 	ciss_printf(sc, "rescan failed (can't allocate CCB)\n");
 2119: 	return;
 2120:     }
 2121:     
 2122:     if (xpt_create_path(&sc->ciss_cam_path, xpt_periph, cam_sim_path(sc->ciss_cam_sim), target, 0)
 2123: 	!= CAM_REQ_CMP) {
 2124: 	ciss_printf(sc, "rescan failed (can't create path)\n");
 2125: 	return;
 2126:     }
 2127:     
 2128:     xpt_setup_ccb(&ccb->ccb_h, sc->ciss_cam_path, 5/*priority (low)*/);
 2129:     ccb->ccb_h.func_code = XPT_SCAN_BUS;
 2130:     ccb->ccb_h.cbfcnp = ciss_cam_rescan_callback;
 2131:     ccb->crcn.flags = CAM_FLAG_NONE;
 2132:     xpt_action(ccb);
 2133:  
 2134:     /* scan is now in progress */
 2135: }
 2136: 
 2137: static void
 2138: ciss_cam_rescan_all(struct ciss_softc *sc)
 2139: {
 2140:     return(ciss_cam_rescan_target(sc, 0));
 2141: }
 2142: 
 2143: static void
 2144: ciss_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
 2145: {
 2146:     xpt_free_path(ccb->ccb_h.path);
 2147:     free(ccb, M_TEMP);
 2148: }
 2149: 
 2150: /************************************************************************
 2151:  * Handle requests coming from CAM
 2152:  */
 2153: static void
 2154: ciss_cam_action(struct cam_sim *sim, union ccb *ccb)
 2155: {
 2156:     struct ciss_softc	*sc;
 2157:     struct ccb_scsiio	*csio;
 2158:     int			target;
 2159: 
 2160:     sc = cam_sim_softc(sim);
 2161:     csio = (struct ccb_scsiio *)&ccb->csio;
 2162:     target = csio->ccb_h.target_id;
 2163: 
 2164:     switch (ccb->ccb_h.func_code) {
 2165: 
 2166: 	/* perform SCSI I/O */
 2167:     case XPT_SCSI_IO:
 2168: 	if (!ciss_cam_action_io(sim, csio))
 2169: 	    return;
 2170: 	break;
 2171: 
 2172: 	/* perform geometry calculations */
 2173:     case XPT_CALC_GEOMETRY:
 2174:     {
 2175: 	struct ccb_calc_geometry	*ccg = &ccb->ccg;
 2176: 	struct ciss_ldrive		*ld = &sc->ciss_logical[target];
 2177: 
 2178: 	debug(1, "XPT_CALC_GEOMETRY %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
 2179: 
 2180: 	/*
 2181: 	 * Use the cached geometry settings unless the fault tolerance
 2182: 	 * is invalid.
 2183: 	 */
 2184: 	if (ld->cl_geometry.fault_tolerance == 0xFF) {
 2185: 	    u_int32_t			secs_per_cylinder;
 2186: 
 2187: 	    ccg->heads = 255;
 2188: 	    ccg->secs_per_track = 32;
 2189: 	    secs_per_cylinder = ccg->heads * ccg->secs_per_track;
 2190: 	    ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 2191: 	} else {
 2192: 	    ccg->heads = ld->cl_geometry.heads;
 2193: 	    ccg->secs_per_track = ld->cl_geometry.sectors;
 2194: 	    ccg->cylinders = ntohs(ld->cl_geometry.cylinders);
 2195: 	}
 2196: 	ccb->ccb_h.status = CAM_REQ_CMP;
 2197:         break;
 2198:     }
 2199: 
 2200: 	/* handle path attribute inquiry */
 2201:     case XPT_PATH_INQ:
 2202:     {
 2203: 	struct ccb_pathinq	*cpi = &ccb->cpi;
 2204: 
 2205: 	debug(1, "XPT_PATH_INQ %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
 2206: 
 2207: 	cpi->version_num = 1;
 2208: 	cpi->hba_inquiry = PI_TAG_ABLE;	/* XXX is this correct? */
 2209: 	cpi->target_sprt = 0;
 2210: 	cpi->hba_misc = 0;
 2211: 	cpi->max_target = CISS_MAX_LOGICAL;
 2212: 	cpi->max_lun = 0;		/* 'logical drive' channel only */
 2213: 	cpi->initiator_id = CISS_MAX_LOGICAL;
 2214: 	strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 2215:         strncpy(cpi->hba_vid, "msmith@freebsd.org", HBA_IDLEN);
 2216:         strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 2217:         cpi->unit_number = cam_sim_unit(sim);
 2218:         cpi->bus_id = cam_sim_bus(sim);
 2219: 	cpi->base_transfer_speed = 132 * 1024;	/* XXX what to set this to? */
 2220: 	ccb->ccb_h.status = CAM_REQ_CMP;
 2221: 	break;
 2222:     }
 2223: 
 2224:     case XPT_GET_TRAN_SETTINGS:
 2225:     {
 2226: 	struct ccb_trans_settings	*cts = &ccb->cts;
 2227: 	int				bus, target;
 2228: 
 2229: 	bus = cam_sim_bus(sim);
 2230: 	target = cts->ccb_h.target_id;
 2231: 
 2232: 	debug(1, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target);
 2233: 	cts->valid = 0;
 2234: 
 2235: 	/* disconnect always OK */
 2236: 	cts->flags |= CCB_TRANS_DISC_ENB;
 2237: 	cts->valid |= CCB_TRANS_DISC_VALID;
 2238: 
 2239: 	cts->ccb_h.status = CAM_REQ_CMP;
 2240: 	break;
 2241:     }
 2242: 
 2243:     default:		/* we can't do this */
 2244: 	debug(1, "unspported func_code = 0x%x", ccb->ccb_h.func_code);
 2245: 	ccb->ccb_h.status = CAM_REQ_INVALID;
 2246: 	break;
 2247:     }
 2248: 
 2249:     xpt_done(ccb);
 2250: }
 2251: 
 2252: /************************************************************************
 2253:  * Handle a CAM SCSI I/O request.
 2254:  */
 2255: static int
 2256: ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
 2257: {
 2258:     struct ciss_softc	*sc;
 2259:     int			bus, target;
 2260:     struct ciss_request	*cr;
 2261:     struct ciss_command	*cc;
 2262:     int			error;
 2263: 
 2264:     sc = cam_sim_softc(sim);
 2265:     bus = cam_sim_bus(sim);
 2266:     target = csio->ccb_h.target_id;
 2267: 
 2268:     debug(2, "XPT_SCSI_IO %d:%d:%d", bus, target, csio->ccb_h.target_lun);
 2269: 
 2270:     /* check for I/O attempt to nonexistent device */
 2271:     if ((bus != 0) ||
 2272: 	(target > CISS_MAX_LOGICAL) ||
 2273: 	(sc->ciss_logical[target].cl_status == CISS_LD_NONEXISTENT)) {
 2274: 	debug(3, "  device does not exist");
 2275: 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2276:     }
 2277: 
 2278:     /* firmware does not support commands > 10 bytes */
 2279:     if (csio->cdb_len > 12/*CISS_CDB_BUFFER_SIZE*/) {
 2280: 	debug(3, "  command too large (%d > %d)", csio->cdb_len, CISS_CDB_BUFFER_SIZE);
 2281: 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2282:     }
 2283: 
 2284:     /* check that the CDB pointer is not to a physical address */
 2285:     if ((csio->ccb_h.flags & CAM_CDB_POINTER) && (csio->ccb_h.flags & CAM_CDB_PHYS)) {
 2286: 	debug(3, "  CDB pointer is to physical address");
 2287: 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2288:     }
 2289: 
 2290:     /* if there is data transfer, it must be to/from a virtual address */
 2291:     if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 2292: 	if (csio->ccb_h.flags & CAM_DATA_PHYS) {		/* we can't map it */
 2293: 	    debug(3, "  data pointer is to physical address");
 2294: 	    csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2295: 	}
 2296: 	if (csio->ccb_h.flags & CAM_SCATTER_VALID) {	/* we want to do the s/g setup */
 2297: 	    debug(3, "  data has premature s/g setup");
 2298: 	    csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2299: 	}
 2300:     }
 2301: 
 2302:     /* abandon aborted ccbs or those that have failed validation */
 2303:     if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
 2304: 	debug(3, "abandoning CCB due to abort/validation failure");
 2305: 	return(EINVAL);
 2306:     }
 2307: 
 2308:     /* handle emulation of some SCSI commands ourself */
 2309:     if (ciss_cam_emulate(sc, csio))
 2310: 	return(0);
 2311: 
 2312:     /*
 2313:      * Get a request to manage this command.  If we can't, return the
 2314:      * ccb, freeze the queue and flag so that we unfreeze it when a
 2315:      * request completes.
 2316:      */
 2317:     if ((error = ciss_get_request(sc, &cr)) != 0) {
 2318: 	xpt_freeze_simq(sc->ciss_cam_sim, 1);
 2319: 	csio->ccb_h.status |= CAM_REQUEUE_REQ;
 2320: 	return(error);
 2321:     }
 2322: 
 2323:     /*
 2324:      * Build the command.
 2325:      */
 2326:     cc = CISS_FIND_COMMAND(cr);
 2327:     cr->cr_data = csio->data_ptr;
 2328:     cr->cr_length = csio->dxfer_len;
 2329:     cr->cr_complete = ciss_cam_complete;
 2330:     cr->cr_private = csio;
 2331: 	
 2332:     cc->header.address.logical.mode = CISS_HDR_ADDRESS_MODE_LOGICAL;
 2333:     cc->header.address.logical.lun = target;
 2334:     cc->cdb.cdb_length = csio->cdb_len;
 2335:     cc->cdb.type = CISS_CDB_TYPE_COMMAND;
 2336:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;	/* XXX ordered tags? */
 2337:     if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
 2338: 	cr->cr_flags = CISS_REQ_DATAOUT;
 2339: 	cc->cdb.direction = CISS_CDB_DIRECTION_WRITE;
 2340:     } else if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 2341: 	cr->cr_flags = CISS_REQ_DATAIN;
 2342: 	cc->cdb.direction = CISS_CDB_DIRECTION_READ;
 2343:     } else {
 2344: 	cr->cr_flags = 0;
 2345: 	cc->cdb.direction = CISS_CDB_DIRECTION_NONE;
 2346:     }
 2347:     cc->cdb.timeout = (csio->ccb_h.timeout / 1000) + 1;
 2348:     if (csio->ccb_h.flags & CAM_CDB_POINTER) {
 2349: 	bcopy(csio->cdb_io.cdb_ptr, &cc->cdb.cdb[0], csio->cdb_len);
 2350:     } else {
 2351: 	bcopy(csio->cdb_io.cdb_bytes, &cc->cdb.cdb[0], csio->cdb_len);
 2352:     }
 2353: 
 2354:     /*
 2355:      * Submit the request to the adapter.
 2356:      *
 2357:      * Note that this may fail if we're unable to map the request (and
 2358:      * if we ever learn a transport layer other than simple, may fail
 2359:      * if the adapter rejects the command).
 2360:      */
 2361:     if ((error = ciss_start(cr)) != 0) {
 2362: 	xpt_freeze_simq(sc->ciss_cam_sim, 1);
 2363: 	csio->ccb_h.status |= CAM_REQUEUE_REQ;
 2364: 	ciss_release_request(cr);
 2365: 	return(error);
 2366:     }
 2367: 	
 2368:     return(0);
 2369: }
 2370: 
 2371: /************************************************************************
 2372:  * Emulate SCSI commands the adapter doesn't handle as we might like.
 2373:  */
 2374: static int
 2375: ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio)
 2376: {
 2377:     int		target;
 2378:     u_int8_t	opcode;
 2379:     
 2380:     
 2381:     target = csio->ccb_h.target_id;
 2382:     opcode = (csio->ccb_h.flags & CAM_CDB_POINTER) ? 
 2383: 	*(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0];
 2384: 
 2385:     /*
 2386:      * Handle requests for volumes that don't exist.  A selection timeout
 2387:      * is slightly better than an illegal request.  Other errors might be 
 2388:      * better.
 2389:      */
 2390:     if (sc->ciss_logical[target].cl_status == CISS_LD_NONEXISTENT) {
 2391: 	csio->ccb_h.status = CAM_SEL_TIMEOUT;
 2392: 	xpt_done((union ccb *)csio);
 2393: 	return(1);
 2394:     }
 2395: 
 2396:     /*
 2397:      * Handle requests for volumes that exist but are offline.
 2398:      *
 2399:      * I/O operations should fail, everything else should work.
 2400:      */
 2401:     if (sc->ciss_logical[target].cl_status == CISS_LD_OFFLINE) {
 2402: 	switch(opcode) {
 2403: 	case READ_6:
 2404: 	case READ_10:
 2405: 	case READ_12:
 2406: 	case WRITE_6:
 2407: 	case WRITE_10:
 2408: 	case WRITE_12:
 2409: 	    csio->ccb_h.status = CAM_SEL_TIMEOUT;
 2410: 	    xpt_done((union ccb *)csio);
 2411: 	    return(1);
 2412: 	}
 2413:     }
 2414: 	    
 2415: 
 2416:     /* if we have to fake Synchronise Cache */
 2417:     if (sc->ciss_flags & CISS_FLAG_FAKE_SYNCH) {
 2418: 	
 2419: 	/*
 2420: 	 * If this is a Synchronise Cache command, typically issued when
 2421: 	 * a device is closed, flush the adapter and complete now.
 2422: 	 */
 2423: 	if (((csio->ccb_h.flags & CAM_CDB_POINTER) ? 
 2424: 	     *(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0]) == SYNCHRONIZE_CACHE) {
 2425: 	    ciss_flush_adapter(sc);
 2426: 	    csio->ccb_h.status = CAM_REQ_CMP;
 2427: 	    xpt_done((union ccb *)csio);
 2428: 	    return(1);
 2429: 	}
 2430:     }
 2431: 
 2432:     return(0);
 2433: }
 2434: 
 2435: /************************************************************************
 2436:  * Check for possibly-completed commands.
 2437:  */
 2438: static void
 2439: ciss_cam_poll(struct cam_sim *sim)
 2440: {
 2441:     struct ciss_softc	*sc = cam_sim_softc(sim);
 2442: 
 2443:     debug_called(2);
 2444: 
 2445:     ciss_done(sc);
 2446: }
 2447: 
 2448: /************************************************************************
 2449:  * Handle completion of a command - pass results back through the CCB
 2450:  */
 2451: static void
 2452: ciss_cam_complete(struct ciss_request *cr)
 2453: {
 2454:     struct ciss_softc		*sc;
 2455:     struct ciss_command		*cc;
 2456:     struct ciss_error_info	*ce;
 2457:     struct ccb_scsiio		*csio;
 2458:     int				scsi_status;
 2459:     int				command_status;
 2460: 
 2461:     debug_called(2);
 2462: 
 2463:     sc = cr->cr_sc;
 2464:     cc = CISS_FIND_COMMAND(cr);
 2465:     ce = (struct ciss_error_info *)&(cc->sg[0]);
 2466:     csio = (struct ccb_scsiio *)cr->cr_private;
 2467: 
 2468:     /*
 2469:      * Extract status values from request.
 2470:      */
 2471:     ciss_report_request(cr, &command_status, &scsi_status);
 2472:     csio->scsi_status = scsi_status;
 2473:     
 2474:     /*
 2475:      * Handle specific SCSI status values.
 2476:      */
 2477:     switch(scsi_status) {
 2478: 	/* no status due to adapter error */
 2479:     case -1:				
 2480: 	debug(0, "adapter error");
 2481: 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2482: 	break;
 2483: 	
 2484: 	/* no status due to command completed OK */
 2485:     case SCSI_STATUS_OK:		/* CISS_SCSI_STATUS_GOOD */
 2486: 	debug(2, "SCSI_STATUS_OK");
 2487: 	csio->ccb_h.status = CAM_REQ_CMP;
 2488: 	break;
 2489: 
 2490: 	/* check condition, sense data included */
 2491:     case SCSI_STATUS_CHECK_COND:	/* CISS_SCSI_STATUS_CHECK_CONDITION */
 2492: 	debug(0, "SCSI_STATUS_CHECK_COND  sense size %d  resid %d",
 2493: 	      ce->sense_length, ce->residual_count);
 2494: 	bzero(&csio->sense_data, SSD_FULL_SIZE);
 2495: 	bcopy(&ce->sense_info[0], &csio->sense_data, ce->sense_length);
 2496: 	csio->sense_len = ce->sense_length;
 2497: 	csio->resid = ce->residual_count;	
 2498: 	csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
 2499: #ifdef CISS_DEBUG
 2500: 	{
 2501: 	    struct scsi_sense_data	*sns = (struct scsi_sense_data *)&ce->sense_info[0];
 2502: 	    debug(0, "sense key %x", sns->flags & SSD_KEY);
 2503: 	}
 2504: #endif	    
 2505: 	break;
 2506: 
 2507:     case SCSI_STATUS_BUSY:		/* CISS_SCSI_STATUS_BUSY */
 2508: 	debug(0, "SCSI_STATUS_BUSY");
 2509: 	csio->ccb_h.status = CAM_SCSI_BUSY;
 2510: 	break;
 2511: 
 2512:     default:
 2513: 	debug(0, "unknown status 0x%x", csio->scsi_status);
 2514: 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
 2515: 	break;
 2516:     }
 2517: 
 2518:     /* handle post-command fixup */
 2519:     ciss_cam_complete_fixup(sc, csio);
 2520: 
 2521:     /* tell CAM we're ready for more commands */
 2522:     csio->ccb_h.status |= CAM_RELEASE_SIMQ;
 2523: 
 2524:     xpt_done((union ccb *)csio);
 2525:     ciss_release_request(cr);
 2526: }
 2527: 
 2528: /********************************************************************************
 2529:  * Fix up the result of some commands here.
 2530:  */
 2531: static void
 2532: ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio)
 2533: {
 2534:     struct scsi_inquiry_data	*inq;
 2535:     struct ciss_ldrive		*cl;
 2536:     int				target;
 2537: 
 2538:     if (((csio->ccb_h.flags & CAM_CDB_POINTER) ? 
 2539: 	 *(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0]) == INQUIRY) {
 2540: 
 2541: 	inq = (struct scsi_inquiry_data *)csio->data_ptr;
 2542: 	target = csio->ccb_h.target_id;
 2543: 	cl = &sc->ciss_logical[target];
 2544: 	
 2545: 	padstr(inq->vendor, "COMPAQ", 8);
 2546: 	padstr(inq->product, ciss_name_ldrive_org(cl->cl_ldrive->fault_tolerance), 8);
 2547: 	padstr(inq->revision, ciss_name_ldrive_status(cl->cl_lstatus->status), 16);
 2548:     }
 2549: }
 2550: 
 2551: 
 2552: /********************************************************************************
 2553:  * Find a peripheral attached at (target)
 2554:  */
 2555: static struct cam_periph *
 2556: ciss_find_periph(struct ciss_softc *sc, int target)
 2557: {
 2558:     struct cam_periph	*periph;
 2559:     struct cam_path	*path;
 2560:     int			status;
 2561: 
 2562:     status = xpt_create_path(&path, NULL, cam_sim_path(sc->ciss_cam_sim), target, 0);
 2563:     if (status == CAM_REQ_CMP) {
 2564: 	periph = cam_periph_find(path, NULL);
 2565: 	xpt_free_path(path);
 2566:     } else {
 2567: 	periph = NULL;
 2568:     }
 2569:     return(periph);
 2570: }
 2571: 
 2572: /********************************************************************************
 2573:  * Name the device at (target)
 2574:  *
 2575:  * XXX is this strictly correct?
 2576:  */
 2577: int
 2578: ciss_name_device(struct ciss_softc *sc, int target)
 2579: {
 2580:     struct cam_periph	*periph;
 2581: 
 2582:     if ((periph = ciss_find_periph(sc, target)) != NULL) {
 2583: 	sprintf(sc->ciss_logical[target].cl_name, "%s%d", periph->periph_name, periph->unit_number);
 2584: 	return(0);
 2585:     }
 2586:     sc->ciss_logical[target].cl_name[0] = 0;
 2587:     return(ENOENT);
 2588: }
 2589: 
 2590: /************************************************************************
 2591:  * Periodic status monitoring.
 2592:  */
 2593: static void
 2594: ciss_periodic(void *arg)
 2595: {
 2596:     struct ciss_softc	*sc;
 2597: 
 2598:     debug_called(1);
 2599:     
 2600:     sc = (struct ciss_softc *)arg;
 2601: 
 2602:     /*
 2603:      * Check the adapter heartbeat.
 2604:      */
 2605:     if (sc->ciss_cfg->heartbeat == sc->ciss_heartbeat) {
 2606: 	sc->ciss_heart_attack++;
 2607: 	debug(0, "adapter heart attack in progress 0x%x/%d", 
 2608: 	      sc->ciss_heartbeat, sc->ciss_heart_attack);
 2609: 	if (sc->ciss_heart_attack == 3) {
 2610: 	    ciss_printf(sc, "ADAPTER HEARTBEAT FAILED\n");
 2611: 	    /* XXX should reset adapter here */
 2612: 	}
 2613:     } else {
 2614: 	sc->ciss_heartbeat = sc->ciss_cfg->heartbeat;
 2615: 	sc->ciss_heart_attack = 0;
 2616: 	debug(3, "new heartbeat 0x%x", sc->ciss_heartbeat);
 2617:     }
 2618:     
 2619:     /*
 2620:      * If the notify event request has died for some reason, or has
 2621:      * not started yet, restart it.
 2622:      */
 2623:     if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK)) {
 2624: 	debug(0, "(re)starting Event Notify chain");
 2625: 	ciss_notify_event(sc);
 2626:     }
 2627: 
 2628:     /*
 2629:      * Reschedule.
 2630:      */
 2631:     if (!(sc->ciss_flags & CISS_FLAG_ABORTING))
 2632: 	sc->ciss_periodic = timeout(ciss_periodic, sc, CISS_HEARTBEAT_RATE * hz);
 2633: }
 2634: 
 2635: /************************************************************************
 2636:  * Request a notification response from the adapter.
 2637:  *
 2638:  * If (cr) is NULL, this is the first request of the adapter, so
 2639:  * reset the adapter's message pointer and start with the oldest
 2640:  * message available.
 2641:  */
 2642: static void
 2643: ciss_notify_event(struct ciss_softc *sc)
 2644: {
 2645:     struct ciss_request		*cr;
 2646:     struct ciss_command		*cc;
 2647:     struct ciss_notify_cdb	*cnc;
 2648:     int				error;
 2649: 
 2650:     debug_called(1);
 2651: 
 2652:     cr = sc->ciss_periodic_notify;
 2653:     
 2654:     /* get a request if we don't already have one */
 2655:     if (cr == NULL) {
 2656: 	if ((error = ciss_get_request(sc, &cr)) != 0) {
 2657: 	    debug(0, "can't get notify event request");
 2658: 	    goto out;
 2659: 	}
 2660: 	sc->ciss_periodic_notify = cr;
 2661: 	cr->cr_complete = ciss_notify_complete;
 2662: 	debug(1, "acquired request %d", cr->cr_tag);
 2663:     }
 2664:     
 2665:     /* 
 2666:      * Get a databuffer if we don't already have one, note that the
 2667:      * adapter command wants a larger buffer than the actual
 2668:      * structure.
 2669:      */
 2670:     if (cr->cr_data == NULL) {
 2671: 	if ((cr->cr_data = malloc(CISS_NOTIFY_DATA_SIZE, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
 2672: 	    debug(0, "can't get notify event request buffer");
 2673: 	    error = ENOMEM;
 2674: 	    goto out;
 2675: 	}
 2676: 	cr->cr_length = CISS_NOTIFY_DATA_SIZE;
 2677:     }
 2678: 
 2679:     /* re-setup the request's command (since we never release it) XXX overkill*/
 2680:     ciss_preen_command(cr);
 2681: 
 2682:     /* (re)build the notify event command */
 2683:     cc = CISS_FIND_COMMAND(cr);
 2684:     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
 2685:     cc->header.address.physical.bus = 0;
 2686:     cc->header.address.physical.target = 0;
 2687: 
 2688:     cc->cdb.cdb_length = sizeof(*cnc);
 2689:     cc->cdb.type = CISS_CDB_TYPE_COMMAND;
 2690:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
 2691:     cc->cdb.direction = CISS_CDB_DIRECTION_READ;
 2692:     cc->cdb.timeout = 0;	/* no timeout, we hope */
 2693:     
 2694:     cnc = (struct ciss_notify_cdb *)&(cc->cdb.cdb[0]);
 2695:     bzero(cr->cr_data, CISS_NOTIFY_DATA_SIZE);
 2696:     cnc->opcode = CISS_OPCODE_READ;
 2697:     cnc->command = CISS_COMMAND_NOTIFY_ON_EVENT;
 2698:     cnc->timeout = 0;		/* no timeout, we hope */
 2699:     cnc->synchronous = 0;
 2700:     cnc->ordered = 0;
 2701:     cnc->seek_to_oldest = 0;
 2702:     cnc->new_only = 0;
 2703:     cnc->length = htonl(CISS_NOTIFY_DATA_SIZE);
 2704: 
 2705:     /* submit the request */
 2706:     error = ciss_start(cr);
 2707: 
 2708:  out:
 2709:     if (error) {
 2710: 	if (cr != NULL) {
 2711: 	    if (cr->cr_data != NULL)
 2712: 		free(cr->cr_data, CISS_MALLOC_CLASS);
 2713: 	    ciss_release_request(cr);
 2714: 	}
 2715: 	sc->ciss_periodic_notify = NULL;
 2716: 	debug(0, "can't submit notify event request");
 2717: 	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
 2718:     } else {
 2719: 	debug(1, "notify event submitted");
 2720: 	sc->ciss_flags |= CISS_FLAG_NOTIFY_OK;
 2721:     }
 2722: }
 2723: 
 2724: static void
 2725: ciss_notify_complete(struct ciss_request *cr)
 2726: {
 2727:     struct ciss_command	*cc;
 2728:     struct ciss_notify	*cn;
 2729:     struct ciss_softc	*sc;
 2730:     int			scsi_status;
 2731:     int			command_status;
 2732: 
 2733:     debug_called(1);
 2734:     
 2735:     cc = CISS_FIND_COMMAND(cr);
 2736:     cn = (struct ciss_notify *)cr->cr_data;
 2737:     sc = cr->cr_sc;
 2738:     
 2739:     /*
 2740:      * Report request results, decode status.
 2741:      */
 2742:     ciss_report_request(cr, &command_status, &scsi_status);
 2743: 
 2744:     /*
 2745:      * Abort the chain on a fatal error.
 2746:      *
 2747:      * XXX which of these are actually errors?
 2748:      */
 2749:     if ((command_status != CISS_CMD_STATUS_SUCCESS) &&
 2750: 	(command_status != CISS_CMD_STATUS_TARGET_STATUS) &&
 2751: 	(command_status != CISS_CMD_STATUS_TIMEOUT)) {	/* XXX timeout? */
 2752: 	ciss_printf(sc, "fatal error in Notify Event request (%s)\n",
 2753: 		    ciss_name_command_status(command_status));
 2754: 	ciss_release_request(cr);
 2755: 	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
 2756: 	return;
 2757:     }
 2758: 
 2759:     /* 
 2760:      * If the adapter gave us a text message, print it.
 2761:      */
 2762:     if (cn->message[0] != 0)
 2763: 	ciss_printf(sc, "*** %.80s\n", cn->message);
 2764: 
 2765:     debug(0, "notify event class %d subclass %d detail %d",
 2766: 		cn->class, cn->subclass, cn->detail);
 2767: 
 2768:     /*
 2769:      * If there's room, save the event for a user-level tool.
 2770:      */
 2771:     if (((sc->ciss_notify_head + 1) % CISS_MAX_EVENTS) != sc->ciss_notify_tail) {
 2772: 	sc->ciss_notify[sc->ciss_notify_head] = *cn;
 2773: 	sc->ciss_notify_head = (sc->ciss_notify_head + 1) % CISS_MAX_EVENTS;
 2774:     }
 2775: 
 2776:     /*
 2777:      * Some events are directly of interest to us.
 2778:      */
 2779:     switch (cn->class) {
 2780:     case CISS_NOTIFY_LOGICAL:
 2781: 	ciss_notify_logical(sc, cn);
 2782: 	break;
 2783:     case CISS_NOTIFY_PHYSICAL:
 2784: 	ciss_notify_physical(sc, cn);
 2785: 	break;
 2786:     }
 2787: 
 2788:     /*
 2789:      * If the response indicates that the notifier has been aborted,
 2790:      * release the notifier command.
 2791:      */
 2792:     if ((cn->class == CISS_NOTIFY_NOTIFIER) &&
 2793: 	(cn->subclass == CISS_NOTIFY_NOTIFIER_STATUS) &&
 2794: 	(cn->detail == 1)) {
 2795: 	debug(0, "notifier exiting");
 2796: 	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
 2797: 	ciss_release_request(cr);
 2798: 	sc->ciss_periodic_notify = NULL;
 2799: 	wakeup(&sc->ciss_periodic_notify);
 2800:     }
 2801: 	
 2802:     /*
 2803:      * Send a new notify event command, if we're not aborting.
 2804:      */
 2805:     if (!(sc->ciss_flags & CISS_FLAG_ABORTING)) {
 2806: 	ciss_notify_event(sc);
 2807:     }
 2808: }
 2809: 
 2810: /************************************************************************
 2811:  * Abort the Notify Event chain.
 2812:  *
 2813:  * Note that we can't just abort the command in progress; we have to
 2814:  * explicitly issue an Abort Notify Event command in order for the
 2815:  * adapter to clean up correctly.
 2816:  *
 2817:  * If we are called with CISS_FLAG_ABORTING set in the adapter softc,
 2818:  * the chain will not restart itself.
 2819:  */
 2820: static int
 2821: ciss_notify_abort(struct ciss_softc *sc)
 2822: {
 2823:     struct ciss_request		*cr;
 2824:     struct ciss_command		*cc;
 2825:     struct ciss_notify_cdb	*cnc;
 2826:     int				error, s, command_status, scsi_status;
 2827: 
 2828:     debug_called(1);
 2829: 
 2830:     cr = NULL;
 2831:     error = 0;
 2832:     
 2833:     /* verify that there's an outstanding command */
 2834:     if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK))
 2835: 	goto out;
 2836:     
 2837:     /* get a command to issue the abort with */
 2838:     if ((error = ciss_get_request(sc, &cr)))
 2839: 	goto out;
 2840: 
 2841:     /* get a buffer for the result */
 2842:     if ((cr->cr_data = malloc(CISS_NOTIFY_DATA_SIZE, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
 2843: 	debug(0, "can't get notify event request buffer");
 2844: 	error = ENOMEM;
 2845: 	goto out;
 2846:     }
 2847:     cr->cr_length = CISS_NOTIFY_DATA_SIZE;
 2848:     
 2849:     /* build the CDB */
 2850:     cc = CISS_FIND_COMMAND(cr);
 2851:     cc->header.address.physical.mode = CISS_HDR_ADDRESS_MODE_PERIPHERAL;
 2852:     cc->header.address.physical.bus = 0;
 2853:     cc->header.address.physical.target = 0;
 2854:     cc->cdb.cdb_length = sizeof(*cnc);
 2855:     cc->cdb.type = CISS_CDB_TYPE_COMMAND;
 2856:     cc->cdb.attribute = CISS_CDB_ATTRIBUTE_SIMPLE;
 2857:     cc->cdb.direction = CISS_CDB_DIRECTION_READ;
 2858:     cc->cdb.timeout = 0;	/* no timeout, we hope */
 2859:     
 2860:     cnc = (struct ciss_notify_cdb *)&(cc->cdb.cdb[0]);
 2861:     bzero(cnc, sizeof(*cnc));
 2862:     cnc->opcode = CISS_OPCODE_WRITE;
 2863:     cnc->command = CISS_COMMAND_ABORT_NOTIFY;
 2864:     cnc->length = htonl(CISS_NOTIFY_DATA_SIZE);
 2865: 
 2866:     ciss_print_request(cr);
 2867:     
 2868:     /*
 2869:      * Submit the request and wait for it to complete.
 2870:      */
 2871:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
 2872: 	ciss_printf(sc, "Abort Notify Event command failed (%d)\n", error);
 2873: 	goto out;
 2874:     }
 2875: 
 2876:     /*
 2877:      * Check response.
 2878:      */
 2879:     ciss_report_request(cr, &command_status, &scsi_status);
 2880:     switch(command_status) {
 2881:     case CISS_CMD_STATUS_SUCCESS:
 2882: 	break;
 2883:     case CISS_CMD_STATUS_INVALID_COMMAND:
 2884: 	/*
 2885: 	 * Some older adapters don't support the CISS version of this
 2886: 	 * command.  Fall back to using the BMIC version.
 2887: 	 */
 2888: 	error = ciss_notify_abort_bmic(sc);
 2889: 	if (error != 0)
 2890: 	    goto out;
 2891: 	break;
 2892: 	
 2893:     case CISS_CMD_STATUS_TARGET_STATUS:
 2894: 	/*
 2895: 	 * This can happen if the adapter thinks there wasn't an outstanding
 2896: 	 * Notify Event command but we did.  We clean up here.
 2897: 	 */
 2898: 	if (scsi_status == CISS_SCSI_STATUS_CHECK_CONDITION) {
 2899: 	    if (sc->ciss_periodic_notify != NULL)
 2900: 		ciss_release_request(sc->ciss_periodic_notify);
 2901: 	    error = 0;
 2902: 	    goto out;
 2903: 	}
 2904: 	/* FALLTHROUGH */
 2905: 	    
 2906:     default:
 2907: 	ciss_printf(sc, "Abort Notify Event command failed (%s)\n",
 2908: 		    ciss_name_command_status(command_status));
 2909: 	error = EIO;
 2910: 	goto out;
 2911:     }
 2912:     
 2913:     /*
 2914:      * Sleep waiting for the notifier command to complete.  Note
 2915:      * that if it doesn't, we may end up in a bad situation, since
 2916:      * the adapter may deliver it later.  Also note that the adapter
 2917:      * requires the Notify Event command to be cancelled in order to
 2918:      * maintain internal bookkeeping.
 2919:      */
 2920:     s = splcam();
 2921:     while (sc->ciss_periodic_notify != NULL) {
 2922: 	error = tsleep(&sc->ciss_periodic_notify, 0, "cissNEA", hz * 5);
 2923: 	if (error == EWOULDBLOCK) {
 2924: 	    ciss_printf(sc, "Notify Event command failed to abort, adapter may wedge.\n");
 2925: 	    break;
 2926: 	}
 2927:     }
 2928:     splx(s);
 2929: 
 2930:  out:
 2931:     /* release the cancel request */
 2932:     if (cr != NULL) {
 2933: 	if (cr->cr_data != NULL)
 2934: 	    free(cr->cr_data, CISS_MALLOC_CLASS);
 2935: 	ciss_release_request(cr);
 2936:     }
 2937:     if (error == 0)
 2938: 	sc->ciss_flags &= ~CISS_FLAG_NOTIFY_OK;
 2939:     return(error);
 2940: }
 2941: 
 2942: /************************************************************************
 2943:  * Abort the Notify Event chain using a BMIC command.
 2944:  */
 2945: static int
 2946: ciss_notify_abort_bmic(struct ciss_softc *sc)
 2947: {
 2948:     struct ciss_request			*cr;
 2949:     int					error, command_status;
 2950: 
 2951:     debug_called(1);
 2952: 
 2953:     cr = NULL;
 2954:     error = 0;
 2955: 
 2956:     /* verify that there's an outstanding command */
 2957:     if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK))
 2958: 	goto out;
 2959:     
 2960:     /*
 2961:      * Build a BMIC command to cancel the Notify on Event command.
 2962:      *
 2963:      * Note that we are sending a CISS opcode here.  Odd.
 2964:      */
 2965:     if ((error = ciss_get_bmic_request(sc, &cr, CISS_COMMAND_ABORT_NOTIFY,
 2966: 				       NULL, 0)) != 0)
 2967: 	goto out;
 2968: 
 2969:     /*
 2970:      * Submit the request and wait for it to complete.
 2971:      */
 2972:     if ((error = ciss_synch_request(cr, 60 * 1000)) != 0) {
 2973: 	ciss_printf(sc, "error sending BMIC Cancel Notify on Event command (%d)\n", error);
 2974: 	goto out;
 2975:     }
 2976:     
 2977:     /*
 2978:      * Check response.
 2979:      */
 2980:     ciss_report_request(cr, &command_status, NULL);
 2981:     switch(command_status) {
 2982:     case CISS_CMD_STATUS_SUCCESS:
 2983: 	break;
 2984:     default:
 2985: 	ciss_printf(sc, "error cancelling Notify on Event (%s)\n",  
 2986: 		    ciss_name_command_status(command_status));
 2987: 	error = EIO;
 2988: 	goto out;
 2989:     }
 2990: 
 2991: out:
 2992:     if (cr != NULL)
 2993: 	ciss_release_request(cr);
 2994:     return(error);
 2995: }
 2996: 
 2997: /************************************************************************
 2998:  * Handle a notify event relating to the status of a logical drive.
 2999:  *
 3000:  * XXX need to be able to defer some of these to properly handle
 3001:  *     calling the "ID Physical drive" command, unless the 'extended'
 3002:  *     drive IDs are always in BIG_MAP format.
 3003:  */
 3004: static void
 3005: ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn)
 3006: {
 3007:     struct ciss_ldrive	*ld;
 3008:     int			ostatus;
 3009: 
 3010:     debug_called(2);
 3011: 
 3012:     ld = &sc->ciss_logical[cn->data.logical_status.logical_drive];
 3013: 
 3014:     switch (cn->subclass) {
 3015:     case CISS_NOTIFY_LOGICAL_STATUS:
 3016: 	switch (cn->detail) {
 3017: 	case 0:
 3018: 	    ciss_name_device(sc, cn->data.logical_status.logical_drive);
 3019: 	    ciss_printf(sc, "logical drive %d (%s) changed status %s->%s, spare status 0x%b\n",
 3020: 			cn->data.logical_status.logical_drive, ld->cl_name,
 3021: 			ciss_name_ldrive_status(cn->data.logical_status.previous_state),
 3022: 			ciss_name_ldrive_status(cn->data.logical_status.new_state),
 3023: 			cn->data.logical_status.spare_state,
 3024: 			"\20\1configured\2rebuilding\3failed\4in use\5available\n");
 3025: 
 3026: 	    /*
 3027: 	     * Update our idea of the drive's status.
 3028: 	     */
 3029: 	    ostatus = ciss_decode_ldrive_status(cn->data.logical_status.previous_state);
 3030: 	    ld->cl_status = ciss_decode_ldrive_status(cn->data.logical_status.new_state);
 3031: 	    if (ld->cl_lstatus != NULL)
 3032: 		ld->cl_lstatus->status = cn->data.logical_status.new_state;
 3033: 
 3034: #if 0
 3035: 	    /*
 3036: 	     * Have CAM rescan the drive if its status has changed.
 3037: 	     */
 3038: 	    if (ostatus != ld->cl_status)
 3039: 		ciss_cam_rescan_target(sc, cn->data.logical_status.logical_drive);
 3040: #endif
 3041: 
 3042: 	    break;
 3043: 
 3044: 	case 1:	/* logical drive has recognised new media, needs Accept Media Exchange */
 3045: 	    ciss_name_device(sc, cn->data.logical_status.logical_drive);
 3046: 	    ciss_printf(sc, "logical drive %d (%s) media exchanged, ready to go online\n",
 3047: 			cn->data.logical_status.logical_drive, ld->cl_name);
 3048: 	    ciss_accept_media(sc, cn->data.logical_status.logical_drive, 1);
 3049: 	    break;
 3050: 
 3051: 	case 2:
 3052: 	case 3:
 3053: 	    ciss_printf(sc, "rebuild of logical drive %d (%s) failed due to %s error\n",
 3054: 			cn->data.rebuild_aborted.logical_drive,
 3055: 			sc->ciss_logical[cn->data.rebuild_aborted.logical_drive].cl_name,
 3056: 			(cn->detail == 2) ? "read" : "write");
 3057: 	    break;
 3058: 	}
 3059: 	break;
 3060: 
 3061:     case CISS_NOTIFY_LOGICAL_ERROR:
 3062: 	if (cn->detail == 0) {
 3063: 	    ciss_printf(sc, "FATAL I/O ERROR on logical drive %d (%s), SCSI port %d ID %d\n",
 3064: 			cn->data.io_error.logical_drive,
 3065: 			sc->ciss_logical[cn->data.io_error.logical_drive].cl_name,
 3066: 			cn->data.io_error.failure_bus,
 3067: 			cn->data.io_error.failure_drive);
 3068: 	    /* XXX should we take the drive down at this point, or will we be told? */
 3069: 	}
 3070: 	break;
 3071: 
 3072:     case CISS_NOTIFY_LOGICAL_SURFACE:
 3073: 	if (cn->detail == 0)
 3074: 	    ciss_printf(sc, "logical drive %d (%s) completed consistency initialisation\n",
 3075: 			cn->data.consistency_completed.logical_drive,
 3076: 			sc->ciss_logical[cn->data.consistency_completed.logical_drive].cl_name);
 3077: 	break;
 3078:     }
 3079: }
 3080: 
 3081: /************************************************************************
 3082:  * Handle a notify event relating to the status of a physical drive.
 3083:  */
 3084: static void
 3085: ciss_notify_physical(struct ciss_softc *sc, struct ciss_notify *cn)
 3086: {
 3087:     
 3088: }
 3089: 
 3090: /************************************************************************
 3091:  * Print a request.
 3092:  */
 3093: static void
 3094: ciss_print_request(struct ciss_request *cr)
 3095: {
 3096:     struct ciss_softc	*sc;
 3097:     struct ciss_command	*cc;
 3098:     int			i;
 3099: 
 3100:     sc = cr->cr_sc;
 3101:     cc = CISS_FIND_COMMAND(cr);
 3102:     
 3103:     ciss_printf(sc, "REQUEST @ %p\n", cr);
 3104:     ciss_printf(sc, "  data %p/%d  tag %d  flags %b\n",
 3105: 	      cr->cr_data, cr->cr_length, cr->cr_tag, cr->cr_flags,
 3106: 	      "\20\1mapped\2sleep\3poll\4dataout\5datain\n");
 3107:     ciss_printf(sc, "  sg list/total %d/%d  host tag 0x%x\n",
 3108: 		cc->header.sg_in_list, cc->header.sg_total, cc->header.host_tag);
 3109:     switch(cc->header.address.mode.mode) {
 3110:     case CISS_HDR_ADDRESS_MODE_PERIPHERAL:
 3111:     case CISS_HDR_ADDRESS_MODE_MASK_PERIPHERAL:
 3112: 	ciss_printf(sc, "  physical bus %d target %d\n",
 3113: 		    cc->header.address.physical.bus, cc->header.address.physical.target);
 3114: 	break;
 3115:     case CISS_HDR_ADDRESS_MODE_LOGICAL:
 3116: 	ciss_printf(sc, "  logical unit %d\n", cc->header.address.logical.lun);
 3117: 	break;
 3118:     }
 3119:     ciss_printf(sc, "  %s cdb length %d type %s attribute %s\n", 
 3120: 		(cc->cdb.direction == CISS_CDB_DIRECTION_NONE) ? "no-I/O" :
 3121: 		(cc->cdb.direction == CISS_CDB_DIRECTION_READ) ? "READ" :
 3122: 		(cc->cdb.direction == CISS_CDB_DIRECTION_WRITE) ? "WRITE" : "??",
 3123: 		cc->cdb.cdb_length,
 3124: 		(cc->cdb.type == CISS_CDB_TYPE_COMMAND) ? "command" :
 3125: 		(cc->cdb.type == CISS_CDB_TYPE_MESSAGE) ? "message" : "??",
 3126: 		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_UNTAGGED) ? "untagged" :
 3127: 		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_SIMPLE) ? "simple" :
 3128: 		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_HEAD_OF_QUEUE) ? "head-of-queue" :
 3129: 		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_ORDERED) ? "ordered" :
 3130: 		(cc->cdb.attribute == CISS_CDB_ATTRIBUTE_AUTO_CONTINGENT) ? "auto-contingent" : "??");
 3131:     ciss_printf(sc, "  %*D\n", cc->cdb.cdb_length, &cc->cdb.cdb[0], " ");
 3132: 
 3133:     if (cc->header.host_tag & CISS_HDR_HOST_TAG_ERROR) {
 3134: 	/* XXX print error info */
 3135:     } else {
 3136: 	/* since we don't use chained s/g, don't support it here */
 3137: 	for (i = 0; i < cc->header.sg_in_list; i++) {
 3138: 	    if ((i % 4) == 0)
 3139: 		ciss_printf(sc, "   ");
 3140: 	    printf("0x%08x/%d ", (u_int32_t)cc->sg[i].address, cc->sg[i].length);
 3141: 	    if ((((i + 1) % 4) == 0) || (i == (cc->header.sg_in_list - 1)))
 3142: 		printf("\n");
 3143: 	}
 3144:     }
 3145: }
 3146: 
 3147: /************************************************************************
 3148:  * Print information about the status of a logical drive.
 3149:  */
 3150: static void
 3151: ciss_print_ldrive(struct ciss_softc *sc, struct ciss_ldrive *ld)
 3152: {
 3153:     int		bus, target, i;
 3154: 
 3155:     if (ld->cl_lstatus == NULL) {
 3156: 	printf("does not exist\n");
 3157: 	return;
 3158:     }
 3159: 
 3160:     /* print drive status */
 3161:     switch(ld->cl_lstatus->status) {
 3162:     case CISS_LSTATUS_OK:
 3163: 	printf("online\n");
 3164: 	break;
 3165:     case CISS_LSTATUS_INTERIM_RECOVERY:
 3166: 	printf("in interim recovery mode\n");
 3167: 	break;
 3168:     case CISS_LSTATUS_READY_RECOVERY:
 3169: 	printf("ready to begin recovery\n");
 3170: 	break;
 3171:     case CISS_LSTATUS_RECOVERING:
 3172: 	bus = CISS_BIG_MAP_BUS(sc, ld->cl_lstatus->drive_rebuilding);
 3173: 	target = CISS_BIG_MAP_BUS(sc, ld->cl_lstatus->drive_rebuilding);
 3174: 	printf("being recovered, working on physical drive %d.%d, %u blocks remaining\n",
 3175: 	       bus, target, ld->cl_lstatus->blocks_to_recover);
 3176: 	break;
 3177:     case CISS_LSTATUS_EXPANDING:
 3178: 	printf("being expanded, %u blocks remaining\n",
 3179: 	       ld->cl_lstatus->blocks_to_recover);
 3180: 	break;
 3181:     case CISS_LSTATUS_QUEUED_FOR_EXPANSION:
 3182: 	printf("queued for expansion\n");
 3183: 	break;
 3184:     case CISS_LSTATUS_FAILED:
 3185: 	printf("queued for expansion\n");
 3186: 	break;
 3187:     case CISS_LSTATUS_WRONG_PDRIVE:
 3188: 	printf("wrong physical drive inserted\n");
 3189: 	break;
 3190:     case CISS_LSTATUS_MISSING_PDRIVE:
 3191: 	printf("missing a needed physical drive\n");
 3192: 	break;
 3193:     case CISS_LSTATUS_BECOMING_READY:
 3194: 	printf("becoming ready\n");
 3195: 	break;
 3196:     }
 3197: 
 3198:     /* print failed physical drives */
 3199:     for (i = 0; i < CISS_BIG_MAP_ENTRIES / 8; i++) {
 3200: 	bus = CISS_BIG_MAP_BUS(sc, ld->cl_lstatus->drive_failure_map[i]);
 3201: 	target = CISS_BIG_MAP_TARGET(sc, ld->cl_lstatus->drive_failure_map[i]);
 3202: 	if (bus == -1)
 3203: 	    continue;
 3204: 	ciss_printf(sc, "physical drive %d:%d (%x) failed\n", bus, target, 
 3205: 		    ld->cl_lstatus->drive_failure_map[i]);
 3206:     }
 3207: }
 3208: 
 3209: #ifdef CISS_DEBUG
 3210: /************************************************************************
 3211:  * Print information about the controller/driver.
 3212:  */
 3213: static void
 3214: ciss_print_adapter(struct ciss_softc *sc)
 3215: {
 3216:     int		i;
 3217: 
 3218:     ciss_printf(sc, "ADAPTER:\n");
 3219:     for (i = 0; i < CISSQ_COUNT; i++) {
 3220: 	ciss_printf(sc, "%s     %d/%d\n",
 3221: 	    i == 0 ? "free" :
 3222: 	    i == 1 ? "busy" : "complete",
 3223: 	    sc->ciss_qstat[i].q_length,
 3224: 	    sc->ciss_qstat[i].q_max);
 3225:     }
 3226:     ciss_printf(sc, "max_requests %d\n", sc->ciss_max_requests);
 3227:     ciss_printf(sc, "notify_head/tail %d/%d\n",
 3228: 	sc->ciss_notify_head, sc->ciss_notify_tail);
 3229:     ciss_printf(sc, "flags %b\n", sc->ciss_flags,
 3230: 	"\20\1notify_ok\2control_open\3aborting\4running\21fake_synch\22bmic_abort\n");
 3231: 
 3232:     for (i = 0; i < CISS_MAX_LOGICAL; i++) {
 3233: 	ciss_printf(sc, "LOGICAL DRIVE %d:  ", i);
 3234: 	ciss_print_ldrive(sc, sc->ciss_logical + i);
 3235:     }
 3236: 
 3237:     for (i = 1; i < sc->ciss_max_requests; i++)
 3238: 	ciss_print_request(sc->ciss_request + i);
 3239: 
 3240: }
 3241: 
 3242: /* DDB hook */
 3243: void
 3244: ciss_print0(void)
 3245: {
 3246:     struct ciss_softc	*sc;
 3247:     
 3248:     sc = devclass_get_softc(devclass_find("ciss"), 0);
 3249:     if (sc == NULL) {
 3250: 	printf("no ciss controllers\n");
 3251:     } else {
 3252: 	ciss_print_adapter(sc);
 3253:     }
 3254: }
 3255: #endif
 3256: 
 3257: /************************************************************************
 3258:  * Return a name for a logical drive status value.
 3259:  */
 3260: static const char *
 3261: ciss_name_ldrive_status(int status)
 3262: {
 3263:     switch (status) {
 3264:     case CISS_LSTATUS_OK:
 3265: 	return("OK");
 3266:     case CISS_LSTATUS_FAILED:
 3267: 	return("failed");
 3268:     case CISS_LSTATUS_NOT_CONFIGURED:
 3269: 	return("not configured");
 3270:     case CISS_LSTATUS_INTERIM_RECOVERY:
 3271: 	return("interim recovery");
 3272:     case CISS_LSTATUS_READY_RECOVERY:
 3273: 	return("ready for recovery");
 3274:     case CISS_LSTATUS_RECOVERING:
 3275: 	return("recovering");
 3276:     case CISS_LSTATUS_WRONG_PDRIVE:
 3277: 	return("wrong physical drive inserted");
 3278:     case CISS_LSTATUS_MISSING_PDRIVE:
 3279: 	return("missing physical drive");
 3280:     case CISS_LSTATUS_EXPANDING:
 3281: 	return("expanding");
 3282:     case CISS_LSTATUS_BECOMING_READY:
 3283: 	return("becoming ready");
 3284:     case CISS_LSTATUS_QUEUED_FOR_EXPANSION:
 3285: 	return("queued for expansion");
 3286:     }
 3287:     return("unknown status");
 3288: }
 3289: 
 3290: /************************************************************************
 3291:  * Return an online/offline/nonexistent value for a logical drive
 3292:  * status value.
 3293:  */
 3294: static int
 3295: ciss_decode_ldrive_status(int status)
 3296: {
 3297:     switch(status) {
 3298:     case CISS_LSTATUS_NOT_CONFIGURED:
 3299: 	return(CISS_LD_NONEXISTENT);
 3300: 
 3301:     case CISS_LSTATUS_OK:
 3302:     case CISS_LSTATUS_INTERIM_RECOVERY:
 3303:     case CISS_LSTATUS_READY_RECOVERY:
 3304:     case CISS_LSTATUS_RECOVERING:
 3305:     case CISS_LSTATUS_EXPANDING:
 3306:     case CISS_LSTATUS_QUEUED_FOR_EXPANSION:
 3307: 	return(CISS_LD_ONLINE);
 3308: 
 3309:     case CISS_LSTATUS_FAILED:
 3310:     case CISS_LSTATUS_WRONG_PDRIVE:
 3311:     case CISS_LSTATUS_MISSING_PDRIVE:
 3312:     case CISS_LSTATUS_BECOMING_READY:
 3313:     default:
 3314: 	return(CISS_LD_OFFLINE);
 3315:     }
 3316: }
 3317: 
 3318: 
 3319: /************************************************************************
 3320:  * Return a name for a logical drive's organisation.
 3321:  */
 3322: static const char *
 3323: ciss_name_ldrive_org(int org)
 3324: {
 3325:     switch(org) {
 3326:     case CISS_LDRIVE_RAID0:
 3327: 	return("RAID 0");
 3328:     case CISS_LDRIVE_RAID1:
 3329: 	return("RAID 1");
 3330:     case CISS_LDRIVE_RAID4:
 3331: 	return("RAID 4");
 3332:     case CISS_LDRIVE_RAID5:
 3333: 	return("RAID 5");
 3334:     }
 3335:     return("unkown");
 3336: }
 3337: 
 3338: /************************************************************************
 3339:  * Return a name for a command status value.
 3340:  */
 3341: static const char *
 3342: ciss_name_command_status(int status)
 3343: {
 3344:     switch(status) {
 3345:     case CISS_CMD_STATUS_SUCCESS:
 3346: 	return("success");
 3347:     case CISS_CMD_STATUS_TARGET_STATUS:
 3348: 	return("target status");
 3349:     case CISS_CMD_STATUS_DATA_UNDERRUN:
 3350: 	return("data underrun");
 3351:     case CISS_CMD_STATUS_DATA_OVERRUN:
 3352: 	return("data overrun");
 3353:     case CISS_CMD_STATUS_INVALID_COMMAND:
 3354: 	return("invalid command");
 3355:     case CISS_CMD_STATUS_PROTOCOL_ERROR:
 3356: 	return("protocol error");
 3357:     case CISS_CMD_STATUS_HARDWARE_ERROR:
 3358: 	return("hardware error");
 3359:     case CISS_CMD_STATUS_CONNECTION_LOST:
 3360: 	return("connection lost");
 3361:     case CISS_CMD_STATUS_ABORTED:
 3362: 	return("aborted");
 3363:     case CISS_CMD_STATUS_ABORT_FAILED:
 3364: 	return("abort failed");
 3365:     case CISS_CMD_STATUS_UNSOLICITED_ABORT:
 3366: 	return("unsolicited abort");
 3367:     case CISS_CMD_STATUS_TIMEOUT:
 3368: 	return("timeout");
 3369:     case CISS_CMD_STATUS_UNABORTABLE:
 3370: 	return("unabortable");
 3371:     }
 3372:     return("unknown status");
 3373: }
 3374: 
 3375: /************************************************************************
 3376:  * Handle an open on the control device.
 3377:  */
 3378: static int
 3379: ciss_open(dev_t dev, int flags, int fmt, d_thread_t *p)
 3380: {
 3381:     struct ciss_softc	*sc;
 3382: 
 3383:     debug_called(1);
 3384:     
 3385:     sc = (struct ciss_softc *)dev->si_drv1;
 3386: 
 3387:     /* we might want to veto if someone already has us open */
 3388: 	
 3389:     sc->ciss_flags |= CISS_FLAG_CONTROL_OPEN;
 3390:     return(0);
 3391: }
 3392: 
 3393: /************************************************************************
 3394:  * Handle the last close on the control device.
 3395:  */
 3396: static int
 3397: ciss_close(dev_t dev, int flags, int fmt, d_thread_t *p)
 3398: {
 3399:     struct ciss_softc	*sc;
 3400: 
 3401:     debug_called(1);
 3402:     
 3403:     sc = (struct ciss_softc *)dev->si_drv1;
 3404:     
 3405:     sc->ciss_flags &= ~CISS_FLAG_CONTROL_OPEN;
 3406:     return (0);
 3407: }
 3408: 
 3409: /********************************************************************************
 3410:  * Handle adapter-specific control operations.
 3411:  *
 3412:  * Note that the API here is compatible with the Linux driver, in order to
 3413:  * simplify the porting of Compaq's userland tools.
 3414:  */
 3415: static int
 3416: ciss_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *p)
 3417: {
 3418:     struct ciss_softc		*sc;
 3419:     int				error;
 3420: 
 3421:     debug_called(1);
 3422: 
 3423:     sc = (struct ciss_softc *)dev->si_drv1;
 3424:     error = 0;
 3425: 
 3426:     switch(cmd) {
 3427:     case CCISS_GETPCIINFO:
 3428:     {
 3429: 	cciss_pci_info_struct	*pis = (cciss_pci_info_struct *)addr;
 3430: 
 3431: 	pis->bus = pci_get_bus(sc->ciss_dev);
 3432: 	pis->dev_fn = pci_get_slot(sc->ciss_dev);
 3433: 	pis->board_id = pci_get_devid(sc->ciss_dev);
 3434: 
 3435: 	break;
 3436:     }
 3437:     
 3438:     case CCISS_GETINTINFO:
 3439:     {
 3440: 	cciss_coalint_struct	*cis = (cciss_coalint_struct *)addr;
 3441: 
 3442: 	cis->delay = sc->ciss_cfg->interrupt_coalesce_delay;
 3443: 	cis->count = sc->ciss_cfg->interrupt_coalesce_count;
 3444: 
 3445: 	break;
 3446:     }
 3447: 
 3448:     case CCISS_SETINTINFO:
 3449:     {
 3450: 	cciss_coalint_struct	*cis = (cciss_coalint_struct *)addr;
 3451: 
 3452: 	if ((cis->delay == 0) && (cis->count == 0)) {
 3453: 	    error = EINVAL;
 3454: 	    break;
 3455: 	}
 3456: 
 3457: 	/*
 3458: 	 * XXX apparently this is only safe if the controller is idle,
 3459: 	 *     we should suspend it before doing this.
 3460: 	 */
 3461: 	sc->ciss_cfg->interrupt_coalesce_delay = cis->delay;
 3462: 	sc->ciss_cfg->interrupt_coalesce_count = cis->count;
 3463: 
 3464: 	if (ciss_update_config(sc))
 3465: 	    error = EIO;
 3466: 
 3467: 	/* XXX resume the controller here */
 3468: 	break;
 3469:     }
 3470: 
 3471:     case CCISS_GETNODENAME:
 3472: 	bcopy(sc->ciss_cfg->server_name, (NodeName_type *)addr,
 3473: 	      sizeof(NodeName_type));
 3474: 	break;
 3475: 
 3476:     case CCISS_SETNODENAME:
 3477: 	bcopy((NodeName_type *)addr, sc->ciss_cfg->server_name,
 3478: 	      sizeof(NodeName_type));
 3479: 	if (ciss_update_config(sc))
 3480: 	    error = EIO;
 3481: 	break;
 3482: 	
 3483:     case CCISS_GETHEARTBEAT:
 3484: 	*(Heartbeat_type *)addr = sc->ciss_cfg->heartbeat;
 3485: 	break;
 3486: 
 3487:     case CCISS_GETBUSTYPES:
 3488: 	*(BusTypes_type *)addr = sc->ciss_cfg->bus_types;
 3489: 	break;
 3490: 
 3491:     case CCISS_GETFIRMVER:
 3492: 	bcopy(sc->ciss_id->running_firmware_revision, (FirmwareVer_type *)addr,
 3493: 	      sizeof(FirmwareVer_type));
 3494: 	break;
 3495: 
 3496:     case CCISS_GETDRIVERVER:
 3497: 	*(DriverVer_type *)addr = CISS_DRIVER_VERSION;
 3498: 	break;
 3499: 
 3500:     case CCISS_REVALIDVOLS:
 3501: 	/*
 3502: 	 * This is a bit ugly; to do it "right" we really need
 3503: 	 * to find any disks that have changed, kick CAM off them,
 3504: 	 * then rescan only these disks.  It'd be nice if they
 3505: 	 * a) told us which disk(s) they were going to play with,
 3506: 	 * and b) which ones had arrived. 8(
 3507: 	 */
 3508: 	break;
 3509: 
 3510:     case CCISS_PASSTHRU:
 3511: 	error = ciss_user_command(sc, (IOCTL_Command_struct *)addr);
 3512: 	break;
 3513: 
 3514:     default:
 3515: 	debug(0, "unknown ioctl 0x%lx", cmd);
 3516: 
 3517: 	debug(1, "CCISS_GETPCIINFO:   0x%lx", CCISS_GETPCIINFO);
 3518: 	debug(1, "CCISS_GETINTINFO:   0x%lx", CCISS_GETINTINFO);
 3519: 	debug(1, "CCISS_SETINTINFO:   0x%lx", CCISS_SETINTINFO);
 3520: 	debug(1, "CCISS_GETNODENAME:  0x%lx", CCISS_GETNODENAME);
 3521: 	debug(1, "CCISS_SETNODENAME:  0x%lx", CCISS_SETNODENAME);
 3522: 	debug(1, "CCISS_GETHEARTBEAT: 0x%lx", CCISS_GETHEARTBEAT);
 3523: 	debug(1, "CCISS_GETBUSTYPES:  0x%lx", CCISS_GETBUSTYPES);
 3524: 	debug(1, "CCISS_GETFIRMVER:   0x%lx", CCISS_GETFIRMVER);
 3525: 	debug(1, "CCISS_GETDRIVERVER: 0x%lx", CCISS_GETDRIVERVER);
 3526: 	debug(1, "CCISS_REVALIDVOLS:  0x%lx", CCISS_REVALIDVOLS);
 3527: 	debug(1, "CCISS_PASSTHRU:     0x%lx", CCISS_PASSTHRU);
 3528: 
 3529: 	error = ENOIOCTL;
 3530: 	break;
 3531:     }
 3532: 
 3533:     return(error);
 3534: }