From f9a735208a21ec20ae9cc75352307a78199582db Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Sat, 28 Sep 2013 15:55:57 +0200
Subject: [PATCH] WIP ciss(4): Bring in some FreeBSD fixes.

---
 share/man/man4/ciss.4       |  39 ++++++++----
 sys/dev/raid/ciss/Makefile  |   2 +-
 sys/dev/raid/ciss/ciss.c    | 142 +++++++++++++++++++++++++++++++++-----------
 sys/dev/raid/ciss/cissio.h  |   2 +-
 sys/dev/raid/ciss/cissreg.h |  11 +++-
 sys/dev/raid/ciss/cissvar.h |   5 +-
 6 files changed, 151 insertions(+), 50 deletions(-)

diff --git a/share/man/man4/ciss.4 b/share/man/man4/ciss.4
index a5405b4..240b5b1 100644
--- a/share/man/man4/ciss.4
+++ b/share/man/man4/ciss.4
@@ -1,8 +1,8 @@
-.\" $FreeBSD: src/share/man/man4/ciss.4,v 1.19 2012/01/26 17:04:17 sbruno Exp $
+.\" $FreeBSD: head/share/man/man4/ciss.4 253980 2013-08-06 03:17:01Z sbruno $
 .\" Written by Tom Rhodes
 .\" This file is in the public domain.
 .\"
-.Dd July 29, 2012
+.Dd September 28, 2013
 .Dt CISS 4
 .Os
 .Sh NAME
@@ -62,14 +62,11 @@ control protocol from earlier Compaq adapter families.
 .Pp
 Currently
 .Nm
-only supports the
+supports the
 .Dq simple
-transport layer over PCI.
-This interface (ab)uses the I2O register set (specifically the post
-queues) to exchange commands with the adapter.
-Other interfaces are available, but we are not supposed to know about them,
-and it is dubious whether they would provide major performance improvements
-except under extreme load.
+and
+.Dq performant
+transport layer.
 .Pp
 Non-disk devices (such as internal DATs and devices
 attached to the external SCSI bus) are supported as normal CAM devices
@@ -81,8 +78,8 @@ tunable to non-zero at boot time.
 Direct Access devices (such as disk drives) are only exposed as
 .Xr pass 4
 devices.
-Hot-insertion and removal of devices is supported but a bus
-rescan might be necessary.
+Hot-insertion and removal of devices is supported and notification messages
+will be reported to the console and logs.
 .Pp
 The problem which adapter freezes with the message
 .Dq ADAPTER HEARTBEAT FAILED
@@ -118,7 +115,7 @@ driver include:
 .Pp
 .Bl -bullet -compact
 .It
-Compaq Smart Array 5300
+Compaq Smart Array 5300 (simple mode only)
 .It
 Compaq Smart Array 532
 .It
@@ -146,6 +143,8 @@ HP Smart Array P220i
 .It
 HP Smart Array P222
 .It
+HP Smart Array P230i
+.It
 HP Smart Array P400
 .It
 HP Smart Array P400i
@@ -162,14 +161,30 @@ HP Smart Array P420i
 .It
 HP Smart Array P421
 .It
+HP Smart Array P430
+.It
+HP Smart Array P430i
+.It
+HP Smart Array P431
+.It
+HP Smart Array P530
+.It
+HP Smart Array P531
+.It
 HP Smart Array P600
 .It
 HP Smart Array P721m
 .It
+HP Smart Array P731m
+.It
 HP Smart Array P800
 .It
 HP Smart Array P812
 .It
+HP Smart Array P830
+.It
+HP Smart Array P830i
+.It
 HP Modular Smart Array 20 (MSA20)
 .It
 HP Modular Smart Array 500 (MSA500)
diff --git a/sys/dev/raid/ciss/Makefile b/sys/dev/raid/ciss/Makefile
index 376206e..3cb1e4f 100644
--- a/sys/dev/raid/ciss/Makefile
+++ b/sys/dev/raid/ciss/Makefile
@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/modules/ciss/Makefile,v 1.2 2002/10/27 12:09:51 mux Exp $
+# $FreeBSD: head/sys/modules/ciss/Makefile 106038 2002-10-27 12:09:51Z mux $
 
 KMOD		=  ciss
 SRCS		=  ciss.c
diff --git a/sys/dev/raid/ciss/ciss.c b/sys/dev/raid/ciss/ciss.c
index a0928e6..2c44eac 100644
--- a/sys/dev/raid/ciss/ciss.c
+++ b/sys/dev/raid/ciss/ciss.c
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/ciss/ciss.c,v 1.113 2012/03/12 08:03:51 scottl Exp $
+ *	$FreeBSD: head/sys/dev/ciss/ciss.c 253980 2013-08-06 03:17:01Z sbruno $
  */
 
 /*
@@ -282,6 +282,7 @@ TUNABLE_INT("hw.ciss.force_interrupt", &ciss_force_interrupt);
 #define CISS_BOARD_SA5		1
 #define CISS_BOARD_SA5B		2
 #define CISS_BOARD_NOMSI	(1<<4)
+#define CISS_BOARD_SIMPLE	(1<<5)
 
 static struct
 {
@@ -290,7 +291,8 @@ static struct
     int		flags;
     char	*desc;
 } ciss_vendor_data[] = {
-    { 0x0e11, 0x4070, CISS_BOARD_SA5|CISS_BOARD_NOMSI,	"Compaq Smart Array 5300" },
+    { 0x0e11, 0x4070, CISS_BOARD_SA5|CISS_BOARD_NOMSI|CISS_BOARD_SIMPLE,
+                                                        "Compaq Smart Array 5300" },
     { 0x0e11, 0x4080, CISS_BOARD_SA5B|CISS_BOARD_NOMSI,	"Compaq Smart Array 5i" },
     { 0x0e11, 0x4082, CISS_BOARD_SA5B|CISS_BOARD_NOMSI,	"Compaq Smart Array 532" },
     { 0x0e11, 0x4083, CISS_BOARD_SA5B|CISS_BOARD_NOMSI,	"HP Smart Array 5312" },
@@ -336,6 +338,15 @@ static struct
     { 0x103C, 0x3354, CISS_BOARD_SA5,   "HP Smart Array P420i" },
     { 0x103C, 0x3355, CISS_BOARD_SA5,   "HP Smart Array P220i" },
     { 0x103C, 0x3356, CISS_BOARD_SA5,   "HP Smart Array P721m" },
+    { 0x103C, 0x1920, CISS_BOARD_SA5,   "HP Smart Array P430i" },
+    { 0x103C, 0x1921, CISS_BOARD_SA5,   "HP Smart Array P830i" },
+    { 0x103C, 0x1922, CISS_BOARD_SA5,   "HP Smart Array P430" },
+    { 0x103C, 0x1923, CISS_BOARD_SA5,   "HP Smart Array P431" },
+    { 0x103C, 0x1924, CISS_BOARD_SA5,   "HP Smart Array P830" },
+    { 0x103C, 0x1926, CISS_BOARD_SA5,   "HP Smart Array P731m" },
+    { 0x103C, 0x1928, CISS_BOARD_SA5,   "HP Smart Array P230i" },
+    { 0x103C, 0x1929, CISS_BOARD_SA5,   "HP Smart Array P530" },
+    { 0x103C, 0x192A, CISS_BOARD_SA5,   "HP Smart Array P531" },
     { 0, 0, 0, NULL }
 };
 
@@ -529,7 +540,7 @@ ciss_detach(device_t dev)
     /* flush adapter cache */
     ciss_flush_adapter(sc);
 
-    /* release all resources.  The mutex is released and freed here too. */
+    /* release all resources.  The lock is released and freed here too. */
     ciss_free(sc);
 
     return(0);
@@ -687,7 +698,14 @@ ciss_init_pci(struct ciss_softc *sc)
 	supported_methods = CISS_TRANSPORT_METHOD_PERF;
 	break;
     default:
-	supported_methods = sc->ciss_cfg->supported_methods;
+	/*
+	 * Override the capabilities of the BOARD and specify SIMPLE
+	 * MODE
+	 */
+	if (ciss_vendor_data[i].flags & CISS_BOARD_SIMPLE)
+		supported_methods = CISS_TRANSPORT_METHOD_SIMPLE;
+	else
+		supported_methods = sc->ciss_cfg->supported_methods;
 	break;
     }
 
@@ -1209,13 +1227,21 @@ ciss_identify_adapter(struct ciss_softc *sc)
     /* XXX only really required for old 5300 adapters? */
     sc->ciss_flags |= CISS_FLAG_BMIC_ABORT;
 
+    /*
+     * Earlier controller specs do not contain these config
+     * entries, so assume that a 0 means its old and assign
+     * these values to the defaults that were established
+     * when this driver was developed for them
+     */
+    if (sc->ciss_cfg->max_logical_supported == 0)
+	sc->ciss_cfg->max_logical_supported = CISS_MAX_LOGICAL;
+    if (sc->ciss_cfg->max_physical_supported == 0)
+	sc->ciss_cfg->max_physical_supported = CISS_MAX_PHYSICAL;
     /* print information */
     if (bootverbose) {
-#if 0	/* XXX proxy volumes??? */
 	ciss_printf(sc, "  %d logical drive%s configured\n",
 		    sc->ciss_id->configured_logical_drives,
 		    (sc->ciss_id->configured_logical_drives == 1) ? "" : "s");
-#endif
 	ciss_printf(sc, "  firmware %4.4s\n", sc->ciss_id->running_firmware_revision);
 	ciss_printf(sc, "  %d SCSI channels\n", sc->ciss_id->scsi_bus_count);
 
@@ -1238,6 +1264,9 @@ ciss_identify_adapter(struct ciss_softc *sc)
 		    "\20\1ultra2\2ultra3\10fibre1\11fibre2\n");
 	ciss_printf(sc, "  server name '%.16s'\n", sc->ciss_cfg->server_name);
 	ciss_printf(sc, "  heartbeat 0x%x\n", sc->ciss_cfg->heartbeat);
+	ciss_printf(sc, "  max logical logical volumes: %d\n", sc->ciss_cfg->max_logical_supported);
+	ciss_printf(sc, "  max physical disks supported: %d\n", sc->ciss_cfg->max_physical_supported);
+	ciss_printf(sc, "  max physical disks per logical volume: %d\n", sc->ciss_cfg->max_physical_per_logical);
     }
 
 out:
@@ -1321,7 +1350,7 @@ ciss_report_luns(struct ciss_softc *sc, int opcode, int nunits)
 	break;
     case CISS_CMD_STATUS_DATA_OVERRUN:
 	ciss_printf(sc, "WARNING: more units than driver limit (%d)\n",
-		    CISS_MAX_LOGICAL);
+		    sc->ciss_cfg->max_logical_supported);
 	break;
     default:
 	ciss_printf(sc, "error detecting logical drive configuration (%s)\n",
@@ -1355,7 +1384,7 @@ ciss_init_logical(struct ciss_softc *sc)
     debug_called(1);
 
     cll = ciss_report_luns(sc, CISS_OPCODE_REPORT_LOGICAL_LUNS,
-			   CISS_MAX_LOGICAL);
+			   sc->ciss_cfg->max_logical_supported);
     if (cll == NULL) {
 	error = ENXIO;
 	goto out;
@@ -1363,9 +1392,9 @@ ciss_init_logical(struct ciss_softc *sc)
 
     /* sanity-check reply */
     ndrives = (ntohl(cll->list_size) / sizeof(union ciss_device_address));
-    if ((ndrives < 0) || (ndrives > CISS_MAX_LOGICAL)) {
+    if ((ndrives < 0) || (ndrives > sc->ciss_cfg->max_logical_supported)) {
 	ciss_printf(sc, "adapter claims to report absurd number of logical drives (%d > %d)\n",
-		    ndrives, CISS_MAX_LOGICAL);
+		ndrives, sc->ciss_cfg->max_logical_supported);
 	error = ENXIO;
 	goto out;
     }
@@ -1384,15 +1413,16 @@ ciss_init_logical(struct ciss_softc *sc)
 
     for (i = 0; i <= sc->ciss_max_logical_bus; i++) {
 	sc->ciss_logical[i] =
-	    kmalloc(CISS_MAX_LOGICAL * sizeof(struct ciss_ldrive),
+	    kmalloc(sc->ciss_cfg->max_logical_supported *
+		    sizeof(struct ciss_ldrive),
 		    CISS_MALLOC_CLASS, M_INTWAIT | M_ZERO);
 
-	for (j = 0; j < CISS_MAX_LOGICAL; j++)
+	for (j = 0; j < sc->ciss_cfg->max_logical_supported; j++)
 	    sc->ciss_logical[i][j].cl_status = CISS_LD_NONEXISTENT;
     }
 
 
-    for (i = 0; i < CISS_MAX_LOGICAL; i++) {
+    for (i = 0; i < sc->ciss_cfg->max_logical_supported; i++) {
 	if (i < ndrives) {
 	    struct ciss_ldrive	*ld;
 	    int			bus, target;
@@ -1433,7 +1463,7 @@ ciss_init_physical(struct ciss_softc *sc)
     bus = 0;
 
     cll = ciss_report_luns(sc, CISS_OPCODE_REPORT_PHYSICAL_LUNS,
-			   CISS_MAX_PHYSICAL);
+			   sc->ciss_cfg->max_physical_supported);
     if (cll == NULL) {
 	error = ENXIO;
 	goto out;
@@ -1964,7 +1994,7 @@ ciss_free(struct ciss_softc *sc)
 	bus_dma_tag_destroy(sc->ciss_parent_dmat);
     if (sc->ciss_logical) {
 	for (i = 0; i <= sc->ciss_max_logical_bus; i++) {
-	    for (j = 0; j < CISS_MAX_LOGICAL; j++) {
+	    for (j = 0; j < sc->ciss_cfg->max_logical_supported; j++) {
 		if (sc->ciss_logical[i][j].cl_ldrive)
 		    kfree(sc->ciss_logical[i][j].cl_ldrive, CISS_MALLOC_CLASS);
 		if (sc->ciss_logical[i][j].cl_lstatus)
@@ -2452,6 +2482,7 @@ ciss_preen_command(struct ciss_request *cr)
     cc->header.sg_total = 0;
     cc->header.host_tag = cr->cr_tag << 2;
     cc->header.host_tag_zeroes = 0;
+    bzero(&(cc->sg[0]), CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command));
     cmdphys = cr->cr_ccphys;
     cc->error_info.error_info_address = cmdphys + sizeof(struct ciss_command);
     cc->error_info.error_info_length = CISS_COMMAND_ALLOC_SIZE - sizeof(struct ciss_command);
@@ -2960,6 +2991,7 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb)
     case XPT_PATH_INQ:
     {
 	struct ccb_pathinq	*cpi = &ccb->cpi;
+	int			sg_length;
 
 	debug(1, "XPT_PATH_INQ %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
 
@@ -2967,9 +2999,9 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb)
 	cpi->hba_inquiry = PI_TAG_ABLE;	/* XXX is this correct? */
 	cpi->target_sprt = 0;
 	cpi->hba_misc = 0;
-	cpi->max_target = CISS_MAX_LOGICAL;
+	cpi->max_target = sc->ciss_cfg->max_logical_supported;
 	cpi->max_lun = 0;		/* 'logical drive' channel only */
-	cpi->initiator_id = CISS_MAX_LOGICAL;
+	cpi->initiator_id = sc->ciss_cfg->max_logical_supported;
 	strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
         strncpy(cpi->hba_vid, "msmith@freebsd.org", HBA_IDLEN);
         strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
@@ -2980,9 +3012,22 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb)
 	cpi->transport_version = 2;
 	cpi->protocol = PROTO_SCSI;
 	cpi->protocol_version = SCSI_REV_2;
-#if 0 /* XXX swildner */
-	cpi->maxio = (CISS_MAX_SG_ELEMENTS - 1) * PAGE_SIZE;
-#endif
+	if (sc->ciss_cfg->max_sg_length == 0) {
+		sg_length = 17;
+	} else {
+	/* XXX Fix for ZMR cards that advertise max_sg_length == 32
+	 * Confusing bit here. max_sg_length is usually a power of 2. We always
+	 * need to subtract 1 to account for partial pages. Then we need to
+	 * align on a valid PAGE_SIZE so we round down to the nearest power of 2.
+	 * Add 1 so we can then subtract it out in the assignment to maxio.
+	 * The reason for all these shenanigans is to create a maxio value that
+	 * creates IO operations to volumes that yield consistent operations
+	 * with good performance.
+	 */
+		sg_length = sc->ciss_cfg->max_sg_length - 1;
+		sg_length = (1 << (fls(sg_length) - 1)) + 1;
+	}
+	cpi->maxio = (min(CISS_MAX_SG_ELEMENTS, sg_length) - 1) * PAGE_SIZE;
 	ccb->ccb_h.status = CAM_REQ_CMP;
 	break;
     }
@@ -3152,9 +3197,12 @@ static int
 ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio)
 {
     int		bus, target;
+    u_int8_t	opcode;
 
     target = csio->ccb_h.target_id;
     bus = cam_sim_bus(xpt_path_sim(csio->ccb_h.path));
+    opcode = (csio->ccb_h.flags & CAM_CDB_POINTER) ?
+	*(u_int8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes[0];
 
     if (CISS_IS_PHYSICAL(bus)) {
 	if (sc->ciss_physical[CISS_CAM_TO_PBUS(bus)][target].cp_online != 1) {
@@ -3191,6 +3239,19 @@ ciss_cam_emulate(struct ciss_softc *sc, struct ccb_scsiio *csio)
 	}
     }
 
+    /*
+     * A CISS target can only ever have one lun per target. REPORT_LUNS requires
+     * at least one LUN field to be pre created for us, so snag it and fill in
+     * the least significant byte indicating 1 LUN here.  Emulate the command
+     * return to shut up warning on console of a CDB error.  swb
+     */
+    if (opcode == REPORT_LUNS && csio->dxfer_len > 0) {
+       csio->data_ptr[3] = 8;
+       csio->ccb_h.status |= CAM_REQ_CMP;
+       xpt_done((union ccb *)csio);
+       return(1);
+    }
+
     return(0);
 }
 
@@ -3334,9 +3395,14 @@ ciss_cam_complete_fixup(struct ciss_softc *sc, struct ccb_scsiio *csio)
 
 	cl = &sc->ciss_logical[bus][target];
 
-	padstr(inq->vendor, "COMPAQ", 8);
-	padstr(inq->product, ciss_name_ldrive_org(cl->cl_ldrive->fault_tolerance), 8);
-	padstr(inq->revision, ciss_name_ldrive_status(cl->cl_lstatus->status), 16);
+	padstr(inq->vendor, "HP",
+	       SID_VENDOR_SIZE);
+	padstr(inq->product,
+	       ciss_name_ldrive_org(cl->cl_ldrive->fault_tolerance),
+	       SID_PRODUCT_SIZE);
+	padstr(inq->revision,
+	       ciss_name_ldrive_status(cl->cl_lstatus->status),
+	       SID_REVISION_SIZE);
     }
 }
 
@@ -3873,7 +3939,7 @@ ciss_notify_rescan_logical(struct ciss_softc *sc)
      * drive address.
      */
     cll = ciss_report_luns(sc, CISS_OPCODE_REPORT_LOGICAL_LUNS,
-                           CISS_MAX_LOGICAL);
+                           sc->ciss_cfg->max_logical_supported);
     if (cll == NULL)
         return;
 
@@ -3884,7 +3950,7 @@ ciss_notify_rescan_logical(struct ciss_softc *sc)
      * firmware.
      */
     for (i = 0; i < sc->ciss_max_logical_bus; i++) {
-	for (j = 0; j < CISS_MAX_LOGICAL; j++) {
+	for (j = 0; j < sc->ciss_cfg->max_logical_supported; j++) {
 	    ld = &sc->ciss_logical[i][j];
 
 	    if (ld->cl_update == 0)
@@ -3938,7 +4004,8 @@ static void
 ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn)
 {
     struct ciss_ldrive	*ld;
-    int			ostatus, bus, target;
+    int			bus, target;
+    int			rescan_ld;
 
     debug_called(2);
 
@@ -3961,7 +4028,6 @@ ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn)
 	    /*
 	     * Update our idea of the drive's status.
 	     */
-	    ostatus = ciss_decode_ldrive_status(cn->data.logical_status.previous_state);
 	    ld->cl_status = ciss_decode_ldrive_status(cn->data.logical_status.new_state);
 	    if (ld->cl_lstatus != NULL)
 		ld->cl_lstatus->status = cn->data.logical_status.new_state;
@@ -3969,7 +4035,9 @@ ciss_notify_logical(struct ciss_softc *sc, struct ciss_notify *cn)
 	    /*
 	     * Have CAM rescan the drive if its status has changed.
 	     */
-	    if (ostatus != ld->cl_status) {
+            rescan_ld = (cn->data.logical_status.previous_state !=
+                         cn->data.logical_status.new_state) ? 1 : 0;
+	    if (rescan_ld) {
 		ld->cl_update = 1;
 		ciss_notify_rescan_logical(sc);
 	    }
@@ -4053,7 +4121,7 @@ ciss_notify_hotplug(struct ciss_softc *sc, struct ciss_notify *cn)
 	     * Rescan the physical lun list for new items
 	     */
 	    cll = ciss_report_luns(sc, CISS_OPCODE_REPORT_PHYSICAL_LUNS,
-				   CISS_MAX_PHYSICAL);
+				   sc->ciss_cfg->max_physical_supported);
 	    if (cll == NULL) {
 		ciss_printf(sc, "Warning, cannot get physical lun list\n");
 		break;
@@ -4296,7 +4364,7 @@ ciss_print_adapter(struct ciss_softc *sc)
 	"\20\1notify_ok\2control_open\3aborting\4running\21fake_synch\22bmic_abort\n");
 
     for (i = 0; i < sc->ciss_max_logical_bus; i++) {
-	for (j = 0; j < CISS_MAX_LOGICAL; j++) {
+	for (j = 0; j < sc->ciss_cfg->max_logical_supported; j++) {
 	    ciss_printf(sc, "LOGICAL DRIVE %d:  ", i);
 	    ciss_print_ldrive(sc, &sc->ciss_logical[i][j]);
 	}
@@ -4312,11 +4380,17 @@ ciss_print_adapter(struct ciss_softc *sc)
 DB_COMMAND(ciss_prt, db_ciss_prt)
 {
     struct ciss_softc	*sc;
+    devclass_t dc;
+    int maxciss, i;
 
-    sc = devclass_get_softc(devclass_find("ciss"), 0);
-    if (sc == NULL) {
-	kprintf("no ciss controllers\n");
-    } else {
+    dc = devclass_find("ciss");
+    if ( dc == NULL ) {
+        kprintf("%s: can't find devclass!\n", __func__);
+        return;
+    }
+    maxciss = devclass_get_maxunit(dc);
+    for (i = 0; i < maxciss; i++) {
+        sc = devclass_get_softc(dc, i);
 	ciss_print_adapter(sc);
     }
 }
diff --git a/sys/dev/raid/ciss/cissio.h b/sys/dev/raid/ciss/cissio.h
index 6fd4439..7a91b78 100644
--- a/sys/dev/raid/ciss/cissio.h
+++ b/sys/dev/raid/ciss/cissio.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/ciss/cissio.h,v 1.6 2008/07/11 21:20:51 scottl Exp $
+ *	$FreeBSD: head/sys/dev/ciss/cissio.h 180454 2008-07-11 21:20:51Z scottl $
  */
 
 /*
diff --git a/sys/dev/raid/ciss/cissreg.h b/sys/dev/raid/ciss/cissreg.h
index 6db29bf..22c0387 100644
--- a/sys/dev/raid/ciss/cissreg.h
+++ b/sys/dev/raid/ciss/cissreg.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/ciss/cissreg.h,v 1.21 2009/09/16 23:27:14 scottl Exp $
+ *	$FreeBSD: head/sys/dev/ciss/cissreg.h 245459 2013-01-15 14:35:35Z sbruno $
  */
 
 /*
@@ -425,6 +425,15 @@ struct ciss_config_table
 #define CISS_DRIVER_DAUGHTER_ATTACHED		(1<<8)
 #define CISS_DRIVER_SCSI_PREFETCH		(1<<9)
     u_int32_t	max_sg_length;		/* 31 in older firmware */
+/*
+ * these fields appear in OpenCISS Spec 1.06
+ * http://cciss.sourceforge.net/#docs
+ */
+    u_int32_t	max_logical_supported;
+    u_int32_t	max_physical_supported;
+    u_int32_t	max_physical_per_logical;
+    u_int32_t	max_perfomant_mode_cmds;
+    u_int32_t	max_block_fetch_count;
 } __packed;
 
 /*
diff --git a/sys/dev/raid/ciss/cissvar.h b/sys/dev/raid/ciss/cissvar.h
index 6a873ab..70242e7 100644
--- a/sys/dev/raid/ciss/cissvar.h
+++ b/sys/dev/raid/ciss/cissvar.h
@@ -45,8 +45,11 @@ typedef STAILQ_HEAD(, ciss_request)	cr_qhead_t;
 
 /*
  * Maximum number of logical drives we support.
+ * If the controller does not indicate a maximum
+ * value.  This is a compatibiliy value to support
+ * older ciss controllers (e.g. model 6i)
  */
-#define CISS_MAX_LOGICAL	15
+#define CISS_MAX_LOGICAL	16
 
 /*
  * Maximum number of physical devices we support.
-- 
1.8.3.4

