changeset 4134:033ee69fd3c3

6541796 Solaris 10 Update4 build3/ NV_60 installation broken on Intel Blade server (wolf) 6547699 SCMD_DOORLOCK handling code should not refer to lun
author pl196000
date Mon, 30 Apr 2007 05:27:41 -0700
parents 7137952457a5
children 69588295f961
files usr/src/uts/intel/io/aac/aac.c usr/src/uts/intel/io/aac/aac.h usr/src/uts/intel/io/aac/aac_regs.h
diffstat 3 files changed, 381 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/intel/io/aac/aac.c	Sun Apr 29 21:15:25 2007 -0700
+++ b/usr/src/uts/intel/io/aac/aac.c	Mon Apr 30 05:27:41 2007 -0700
@@ -105,7 +105,11 @@
 	((uint64_t)(mir)->MntObj.CapacityHigh << 32) : \
 	(uint64_t)(mir)->MntObj.Capacity)
 
-#define	BUF_IS_READ(bp) ((bp)->b_flags & B_READ)
+/* The last entry of aac_cards[] is for unknown cards */
+#define	AAC_UNKNOWN_CARD \
+	(sizeof (aac_cards) / sizeof (struct aac_card_type) - 1)
+#define	CARD_IS_UNKNOWN(i)	(i == AAC_UNKNOWN_CARD)
+#define	BUF_IS_READ(bp)		((bp)->b_flags & B_READ)
 #define	AAC_IS_Q_EMPTY(q) (((q)->q_head == NULL) ? 1 : 0)
 
 #define	PCI_MEM_GET32(softs, off) ddi_get32((softs)->pci_mem_handle, \
@@ -140,6 +144,9 @@
 #define	AAC_IOCMD_ALL		(AAC_IOCMD_SYNC | AAC_IOCMD_ASYNC | \
 				AAC_IOCMD_OUTSTANDING)
 
+/*
+ * Hardware access functions
+ */
 static int aac_rx_get_fwstatus(struct aac_softstate *);
 static int aac_rx_get_mailbox(struct aac_softstate *, int);
 static void aac_rx_set_mailbox(struct aac_softstate *, uint32_t,
@@ -160,8 +167,6 @@
 	aac_rkt_set_mailbox
 };
 
-static int aac_send_command(struct aac_softstate *, struct aac_slot *);
-
 /*
  * SCSA function prototypes
  */
@@ -184,14 +189,17 @@
 static int aac_check_firmware(struct aac_softstate *);
 static int aac_common_attach(struct aac_softstate *);
 static void aac_common_detach(struct aac_softstate *);
-int aac_sync_mbcommand(struct aac_softstate *, uint32_t, uint32_t,
-	uint32_t, uint32_t, uint32_t, uint32_t *);
 static int aac_get_container(struct aac_softstate *);
 static int aac_alloc_comm_space(struct aac_softstate *);
 static int aac_setup_comm_space(struct aac_softstate *);
 static void aac_free_comm_space(struct aac_softstate *);
 static int aac_hba_setup(struct aac_softstate *);
 
+/*
+ * Sync FIB operation functions
+ */
+int aac_sync_mbcommand(struct aac_softstate *, uint32_t, uint32_t,
+	uint32_t, uint32_t, uint32_t, uint32_t *);
 static int aac_sync_fib(struct aac_softstate *, uint32_t, struct aac_fib *,
 	uint16_t);
 static struct aac_fib *aac_grab_sync_fib(struct aac_softstate *,
@@ -199,7 +207,7 @@
 static void aac_release_sync_fib(struct aac_softstate *);
 
 /*
- * hardware queue operation funcitons
+ * Waiting/complete queue operation funcitons
  */
 static void aac_cmd_enqueue(struct aac_cmd_queue *, struct aac_cmd *);
 static struct aac_cmd *aac_cmd_dequeue(struct aac_cmd_queue *);
@@ -232,22 +240,23 @@
 static void aac_drain_comp_q(struct aac_softstate *);
 static int aac_do_poll_io(struct aac_softstate *, struct aac_cmd *);
 int aac_do_async_io(struct aac_softstate *, struct aac_cmd *);
+static int aac_send_command(struct aac_softstate *, struct aac_slot *);
 static void aac_dma_sync(ddi_dma_handle_t, off_t, size_t, uint_t);
 static int aac_shutdown(struct aac_softstate *);
 static int aac_reset_adapter(struct aac_softstate *);
 
 /*
- * Timeout handling thread function
+ * Adapter Initiated FIB handling function
  */
 static int aac_handle_aif(struct aac_softstate *, struct aac_fib *);
 
 /*
  * Timeout handling thread function
  */
-static void aac_daemon(void*);
+static void aac_daemon(void *);
 
 /*
- * IOCTL related functions
+ * IOCTL interface related functions
  */
 static int aac_open(dev_t *, int, int, cred_t *);
 static int aac_close(dev_t, int, int, cred_t *);
@@ -304,41 +313,52 @@
 static struct aac_softstate  *aac_softstatep;
 
 /*
- * Suppoted card list
+ * Supported card list
+ * ordered in vendor id, subvendor id, subdevice id, and device id
  */
 static struct aac_card_type aac_cards[] = {
+	{0x1028, 0x1, 0x1028, 0x1, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0x2, 0x1028, 0x2, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0x3, 0x1028, 0x3, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Si"},
+	{0x1028, 0x8, 0x1028, 0xcf, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0x4, 0x1028, 0xd0, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Si"},
+	{0x1028, 0x2, 0x1028, 0xd1, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0x2, 0x1028, 0xd9, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0xa, 0x1028, 0x106, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0xa, 0x1028, 0x11b, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x1028, 0xa, 0x1028, 0x121, AAC_HWIF_I960RX,
+		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
+	{0x9005, 0x285, 0x1028, 0x287, AAC_HWIF_I960RX,
+		AAC_FLAGS_NO4GB | AAC_FLAGS_256FIBS, AAC_TYPE_SCSI,
+		"Dell", "PERC 320/DC"},
+	{0x9005, 0x285, 0x1028, 0x291, AAC_HWIF_I960RX,
+		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Dell", "CERC SR2"},
+
+	{0x9005, 0x285, 0x1014, 0x2f2, AAC_HWIF_I960RX,
+		0, AAC_TYPE_SCSI, "IBM", "ServeRAID 8i"},
+	{0x9005, 0x285, 0x1014, 0x34d, AAC_HWIF_I960RX,
+		0, AAC_TYPE_SAS, "IBM", "ServeRAID 8s"},
+	{0x9005, 0x286, 0x1014, 0x9580, AAC_HWIF_RKT,
+		0, AAC_TYPE_SAS, "IBM", "ServeRAID 8k"},
+
+	{0x9005, 0x285, 0x103c, 0x3227, AAC_HWIF_I960RX,
+		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Adaptec", "2610SA"},
+
 	{0x9005, 0x285, 0x9005, 0x285, AAC_HWIF_I960RX,
 		AAC_FLAGS_NO4GB | AAC_FLAGS_256FIBS, AAC_TYPE_SCSI,
 		"Adaptec", "2200S"},
 	{0x9005, 0x285, 0x9005, 0x286, AAC_HWIF_I960RX,
 		AAC_FLAGS_NO4GB | AAC_FLAGS_256FIBS, AAC_TYPE_SCSI,
 		"Adaptec", "2120S"},
-	{0x9005, 0x285, 0x9005, 0x290, AAC_HWIF_I960RX,
-		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Adaptec", "2410SA"},
-	{0x9005, 0x285, 0x1028, 0x287, AAC_HWIF_I960RX,
-		AAC_FLAGS_NO4GB | AAC_FLAGS_256FIBS, AAC_TYPE_SCSI,
-		"Dell", "PERC 320/DC"},
-	{0x1028, 0xa, 0x1028, 0x121, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0xa, 0x1028, 0x11b, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0xa, 0x1028, 0x106, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0x8, 0x1028, 0xcf, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0x2, 0x1028, 0xd9, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0x2, 0x1028, 0xd1, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0x4, 0x1028, 0xd0, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Si"},
-	{0x1028, 0x3, 0x1028, 0x3, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Si"},
-	{0x1028, 0x2, 0x1028, 0x2, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-	{0x1028, 0x1, 0x1028, 0x1, AAC_HWIF_I960RX,
-		AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"},
-
 	{0x9005, 0x285, 0x9005, 0x287, AAC_HWIF_I960RX,
 		AAC_FLAGS_NO4GB | AAC_FLAGS_256FIBS, AAC_TYPE_SCSI,
 		"Adaptec", "2200S"},
@@ -358,8 +378,8 @@
 		0, AAC_TYPE_SATA, "Adaptec", "2020SA"},
 	{0x9005, 0x285, 0x9005, 0x28f, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SATA, "Adaptec", "2025SA"},
-	{0x9005, 0x285, 0x9005, 0x291, AAC_HWIF_I960RX,
-		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Dell", "CERC SR2"},
+	{0x9005, 0x285, 0x9005, 0x290, AAC_HWIF_I960RX,
+		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Adaptec", "2410SA"},
 	{0x9005, 0x285, 0x9005, 0x292, AAC_HWIF_I960RX,
 		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Adaptec", "2810SA"},
 	{0x9005, 0x285, 0x9005, 0x293, AAC_HWIF_I960RX,
@@ -390,54 +410,27 @@
 		0, AAC_TYPE_SATA, "ICP", "9047MA"},
 	{0x9005, 0x286, 0x9005, 0x2a1, AAC_HWIF_RKT,
 		0, AAC_TYPE_SATA, "ICP", "9087MA"},
-	{0x9005, 0x286, 0x9005, 0x2a2, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 3800"},
-	{0x9005, 0x286, 0x9005, 0x2a7, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 3805"},
-	{0x9005, 0x286, 0x9005, 0x2a8, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 3400"},
-	{0x9005, 0x286, 0x9005, 0x2a9, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "ICP", "5085AU"},
-	{0x9005, 0x286, 0x9005, 0x2aa, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "ICP", "5045AU"},
-	{0x9005, 0x286, 0x9005, 0x2a3, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "ICP", "5445AU"},
 	{0x9005, 0x285, 0x9005, 0x2a4, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SAS, "ICP", "9085LI"},
 	{0x9005, 0x285, 0x9005, 0x2a5, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SAS, "ICP", "5085BR"},
 	{0x9005, 0x286, 0x9005, 0x2a6, AAC_HWIF_RKT,
 		0, AAC_TYPE_SATA, "ICP", "9067MA"},
-	{0x9005, 0x286, 0x9005, 0x2ac, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 1800"},
-	{0x9005, 0x286, 0x9005, 0x2b3, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 2400"},
-	{0x9005, 0x286, 0x9005, 0x2b4, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "ICP", "5045AL"},
 	{0x9005, 0x285, 0x9005, 0x2b5, AAC_HWIF_I960RX,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 5800"},
+		0, AAC_TYPE_SAS, "Adaptec", "RAID 5445"},
 	{0x9005, 0x285, 0x9005, 0x2b6, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SAS, "Adaptec", "RAID 5805"},
 	{0x9005, 0x285, 0x9005, 0x2b7, AAC_HWIF_I960RX,
-		0, AAC_TYPE_SAS, "Adaptec", "RAID 5808"},
+		0, AAC_TYPE_SAS, "Adaptec", "RAID 5085"},
 	{0x9005, 0x285, 0x9005, 0x2b8, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SAS, "ICP", "RAID ICP5445SL"},
 	{0x9005, 0x285, 0x9005, 0x2b9, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SAS, "ICP", "RAID ICP5085SL"},
 	{0x9005, 0x285, 0x9005, 0x2ba, AAC_HWIF_I960RX,
 		0, AAC_TYPE_SAS, "ICP", "RAID ICP5805SL"},
-	{0x9005, 0x285, 0x1014, 0x2f2, AAC_HWIF_I960RX,
-		0, AAC_TYPE_SCSI, "IBM", "ServeRAID 8i"},
-	{0x9005, 0x285, 0x103c, 0x3227, AAC_HWIF_I960RX,
-		AAC_FLAGS_NO4GB, AAC_TYPE_SATA, "Adaptec", "2610SA"},
-	{0x9005, 0x286, 0x1014, 0x9580, AAC_HWIF_RKT,
-		0, AAC_TYPE_SAS, "IBM", "ServeRAID 8k"},
-	{0x9005, 0x285, 0x1014, 0x034d, AAC_HWIF_I960RX,
-		0, AAC_TYPE_SAS, "IBM", "ServeRAID 8s"},
 
 	{0, 0, 0, 0, AAC_HWIF_UNKNOWN,
 		0, AAC_TYPE_UNKNOWN, "Unknown", "AAC card"},
-	{0, 0, 0, 0, AAC_HWIF_UNKNOWN, 0, AAC_TYPE_UNKNOWN, NULL, NULL}
 };
 
 ddi_device_acc_attr_t aac_acc_attr = {
@@ -466,7 +459,7 @@
 static ddi_dma_attr_t aac_buf_dma_attr = {
 		DMA_ATTR_V0,
 		0x2000ull,	/* lowest usable address */
-				/* (2200 and 2120 cannot dma below 8192 */
+				/* (2200 and 2120 cannot do DMA below 8192) */
 		0xffffffffull,	/* high DMA address range */
 		0x0000ffffull,	/* DMA counter register */
 		AAC_DMA_ALIGN,	/* DMA address alignment */
@@ -475,14 +468,14 @@
 		0xffffffffull,	/* max DMA xfer size */
 		0xffffffffull,	/* segment boundary */
 		AAC_NSEG,	/* s/g list length */
-		512,		/* granularity of device */
+		AAC_BLK_SIZE,	/* granularity of device */
 		0,		/* DMA transfer flags */
 };
 
 static ddi_dma_attr_t aac_addr_dma_attr = {
 		DMA_ATTR_V0,
 		0x2000ull,	/* lowest usable address */
-				/* (2200 and 2120 cannot dma below 8192 */
+				/* (2200 and 2120 cannot do DMA below 8192) */
 		0x7fffffffull,	/* high DMA address range */
 		0x0000ffffull,	/* DMA counter register */
 		AAC_DMA_ALIGN,	/* DMA address alignment */
@@ -580,34 +573,19 @@
 		AACDB_PRINT((CE_WARN, "Cannot alloc soft state"));
 		goto error;
 	}
+	softs = ddi_get_soft_state(aac_softstatep, instance);
 	attach_state |= AAC_ATTACH_SOFTSTATE_ALLOCED;
-	softs = ddi_get_soft_state(aac_softstatep, instance);
+
 	softs->devinfo_p = dip;
-
 	softs->buf_dma_attr = aac_buf_dma_attr;
 	softs->addr_dma_attr = aac_addr_dma_attr;
+	softs->card = AAC_UNKNOWN_CARD;
 
 	/* Check the card type */
-	if ((softs->card = aac_check_card_type(softs)) == AACERR) {
+	if (aac_check_card_type(softs) == AACERR) {
 		AACDB_PRINT((CE_WARN, "Card not supported"));
 		goto error;
 	}
-
-	/* Set hardware dependent interface */
-	switch (aac_cards[softs->card].hwif) {
-	case AAC_HWIF_I960RX:
-		softs->aac_if = aac_rx_interface;
-		softs->map_size_min = AAC_MAP_SIZE_MIN_RX;
-		break;
-	case AAC_HWIF_RKT:
-		softs->aac_if = aac_rkt_interface;
-		softs->map_size_min = AAC_MAP_SIZE_MIN_RKT;
-		break;
-	default:
-		goto error;
-	}
-	/* Set up quirks */
-	softs->flags = aac_cards[softs->card].quirks;
 	/* We have found the right card and everything is OK */
 	attach_state |= AAC_ATTACH_CARD_DETECTED;
 
@@ -814,7 +792,8 @@
 	rw_destroy(&softs->errlock);
 
 	ddi_regs_map_free(&softs->pci_mem_handle);
-	softs->card = AACERR;
+	softs->hwif = AAC_HWIF_UNKNOWN;
+	softs->card = AAC_UNKNOWN_CARD;
 	ddi_soft_state_free(aac_softstatep, instance);
 
 	return (DDI_SUCCESS);
@@ -883,7 +862,7 @@
 /*
  * Setup auto sense data for pkt
  */
-void
+static void
 aac_set_arq_data(struct scsi_pkt *pkt, uchar_t key,
 	uchar_t add_code, uchar_t qual_code, uint64_t info)
 {
@@ -1238,16 +1217,15 @@
 static int
 aac_check_card_type(struct aac_softstate *softs)
 {
+	ddi_acc_handle_t pci_config_handle;
 	uint16_t vendid, subvendid, devid, subsysid;
-	uint32_t mem_base;
-	int card_type_index;
+	int card_index;
 	uint32_t pci_cmd;
-	int card_found;
-	dev_info_t *dip = softs->devinfo_p;
-	ddi_acc_handle_t pci_config_handle;
+	uint32_t mem_base;
 
 	/* Map pci configuration space */
-	if ((pci_config_setup(dip, &pci_config_handle)) != DDI_SUCCESS) {
+	if ((pci_config_setup(softs->devinfo_p, &pci_config_handle))
+		!= DDI_SUCCESS) {
 		AACDB_PRINT((CE_WARN, "Cannot setup pci config space"));
 		return (AACERR);
 	}
@@ -1256,55 +1234,99 @@
 	devid = pci_config_get16(pci_config_handle, PCI_CONF_DEVID);
 	subvendid = pci_config_get16(pci_config_handle, PCI_CONF_SUBVENID);
 	subsysid = pci_config_get16(pci_config_handle, PCI_CONF_SUBSYSID);
-	mem_base = pci_config_get32(pci_config_handle, PCI_CONF_BASE0);
-	card_type_index = 0;
-	card_found = 0;
-	while (aac_cards[card_type_index].desc != NULL) {
-		if ((aac_cards[card_type_index].vendor == vendid) &&
-			(aac_cards[card_type_index].device == devid) &&
-			(aac_cards[card_type_index].subvendor == subvendid) &&
-			(aac_cards[card_type_index].subsys == subsysid)) {
-			card_found = 1;
+	card_index = 0;
+	while (!CARD_IS_UNKNOWN(card_index)) {
+		if ((aac_cards[card_index].vendor == vendid) &&
+			(aac_cards[card_index].device == devid) &&
+			(aac_cards[card_index].subvendor == subvendid) &&
+			(aac_cards[card_index].subsys == subsysid)) {
 			/*
 			 * SATA RAID adapter's DMA capability is worse
 			 * than SCSI RAID adapter.  So we need to change
 			 * dma_attr_count_max from 0xffff to 0xfff to meet
 			 * the requirement.
 			 */
-			if (aac_cards[card_type_index].type == AAC_TYPE_SATA)
+			if (aac_cards[card_index].type == AAC_TYPE_SATA)
 				softs->buf_dma_attr.dma_attr_count_max =
 					0xfffull;
 			break;
 		}
-		card_type_index++;
+		card_index++;
 	}
 
-	/* Make sure we can talk to this card */
-	if (card_found) {
-		/* supported aac card */
-		pci_cmd = pci_config_get16(pci_config_handle, PCI_CONF_COMM);
-		if ((pci_cmd & PCI_COMM_ME) == 0) {
-			/* force the busmaster enable bit on */
-			pci_cmd |= PCI_COMM_ME;
-			pci_config_put16(pci_config_handle, PCI_CONF_COMM,
-				pci_cmd);
-			pci_cmd = pci_config_get16(pci_config_handle,
-				PCI_CONF_COMM);
-			if ((pci_cmd & PCI_COMM_ME) == 0) {
-				cmn_err(CE_CONT,
-					"?Cannot enable busmaster bit");
-				goto error;
-			}
+	softs->card = card_index;
+	softs->hwif = aac_cards[card_index].hwif;
+
+	/*
+	 * Unknown aac card
+	 * do a generic match based on the VendorID and DeviceID to
+	 * support the new cards in the aac family
+	 */
+	if (CARD_IS_UNKNOWN(card_index)) {
+		if (vendid != 0x9005) {
+			AACDB_PRINT((CE_WARN,
+				"Unknown vendor 0x%x", vendid));
+			goto error;
 		}
-		if ((pci_cmd & PCI_COMM_MAE) == 0) {
-			AACDB_PRINT((CE_WARN, "Memory window not available"));
+		switch (devid) {
+		case 0x285:
+			softs->hwif = AAC_HWIF_I960RX;
+			break;
+		case 0x286:
+			softs->hwif = AAC_HWIF_RKT;
+			break;
+		default:
+			AACDB_PRINT((CE_WARN,
+				"Unknown device \"pci9005,%x\"", devid));
 			goto error;
 		}
-	} else
-		/* Unknown aac card */
-		card_type_index--;
+	}
+
+	/* Set hardware dependent interface */
+	switch (softs->hwif) {
+	case AAC_HWIF_I960RX:
+		softs->aac_if = aac_rx_interface;
+		softs->map_size_min = AAC_MAP_SIZE_MIN_RX;
+		break;
+	case AAC_HWIF_RKT:
+		softs->aac_if = aac_rkt_interface;
+		softs->map_size_min = AAC_MAP_SIZE_MIN_RKT;
+		break;
+	default:
+		AACDB_PRINT((CE_WARN,
+			"Unknown hardware interface %d", softs->hwif));
+		goto error;
+	}
+
+	/* Set card names */
+	(void *)strncpy(softs->vendor_name, aac_cards[card_index].vid,
+		AAC_VENDOR_LEN);
+	(void *)strncpy(softs->product_name, aac_cards[card_index].desc,
+		AAC_PRODUCT_LEN);
+
+	/* Set up quirks */
+	softs->flags = aac_cards[card_index].quirks;
+
+	/* Force the busmaster enable bit on */
+	pci_cmd = pci_config_get16(pci_config_handle, PCI_CONF_COMM);
+	if ((pci_cmd & PCI_COMM_ME) == 0) {
+		pci_cmd |= PCI_COMM_ME;
+		pci_config_put16(pci_config_handle, PCI_CONF_COMM,
+			pci_cmd);
+		pci_cmd = pci_config_get16(pci_config_handle,
+			PCI_CONF_COMM);
+		if ((pci_cmd & PCI_COMM_ME) == 0) {
+			cmn_err(CE_CONT,
+				"?Cannot enable busmaster bit");
+			goto error;
+		}
+	}
+
+	/* Set memory base to map */
+	mem_base = pci_config_get32(pci_config_handle, PCI_CONF_BASE0);
 
 	pci_config_teardown(&pci_config_handle);
+
 	cmn_err(CE_NOTE,
 		"!aac driver %d.%02d.%02d-%d, found card: " \
 		"%s %s(pci0x%x.%x.%x.%x) at 0x%x",
@@ -1312,11 +1334,10 @@
 		AAC_DRIVER_MINOR_VERSION,
 		AAC_DRIVER_BUGFIX_LEVEL,
 		AAC_DRIVER_BUILD,
-		aac_cards[card_type_index].vid,
-		aac_cards[card_type_index].desc,
+		softs->vendor_name, softs->product_name,
 		vendid, devid, subvendid, subsysid,
 		mem_base);
-	return (card_type_index); /* card type detected */
+	return (AACOK); /* card type detected */
 
 error:
 	pci_config_teardown(&pci_config_handle);
@@ -1473,6 +1494,56 @@
 /*
  * The following function comes from Adaptec:
  *
+ * Query adapter information and supplement adapter information
+ */
+static int
+aac_get_adapter_info(struct aac_softstate *softs,
+	struct aac_adapter_info *ainfr,
+	struct aac_supplement_adapter_info *sinfr)
+{
+	struct aac_fib *fib;
+	struct aac_adapter_info *ainfp;
+	struct aac_supplement_adapter_info *sinfp;
+
+	fib = aac_grab_sync_fib(softs, SLEEP_FUNC);
+	fib->data[0] = 0;
+	if (aac_sync_fib(softs, RequestAdapterInfo, fib,
+		sizeof (struct aac_fib_header)) != AACOK) {
+		AACDB_PRINT((CE_WARN, "RequestAdapterInfo failed"));
+		aac_release_sync_fib(softs);
+		return (AACERR);
+	}
+	ainfp = (struct aac_adapter_info *)fib->data;
+	if (ainfr) {
+		*ainfr = *ainfp;
+	}
+	if (sinfr) {
+		if (!(softs->support_opt &
+			AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO)) {
+			AACDB_PRINT((CE_WARN,
+				"SupplementAdapterInfo not supported"));
+			aac_release_sync_fib(softs);
+			return (AACERR);
+		}
+		fib->data[0] = 0;
+		if (aac_sync_fib(softs, RequestSupplementAdapterInfo, fib,
+			sizeof (struct aac_fib_header)) != AACOK) {
+			AACDB_PRINT((CE_WARN,
+				"RequestSupplementAdapterInfo failed"));
+			aac_release_sync_fib(softs);
+			return (AACERR);
+		}
+		sinfp = (struct aac_supplement_adapter_info *)fib->data;
+		*sinfr = *sinfp;
+	}
+
+	aac_release_sync_fib(softs);
+	return (AACOK);
+}
+
+/*
+ * The following function comes from Adaptec:
+ *
  * Routine to be called during initialization of communications with
  * the adapter to handle possible adapter configuration issues. When
  * the adapter first boots up, it examines attached drives, etc, and
@@ -1639,6 +1710,56 @@
 		goto error;
 	AACDB_PRINT((CE_NOTE, "%d fibs allocated", softs->total_fibs));
 
+	/* Get adapter names */
+	if (CARD_IS_UNKNOWN(softs->card)) {
+		struct aac_supplement_adapter_info sinf;
+
+		if (aac_get_adapter_info(softs, NULL, &sinf) != AACOK) {
+			cmn_err(CE_CONT, "?Query adapter information failed");
+		} else {
+			char *p, *p0, *p1;
+
+			/*
+			 * Now find the controller name in supp_adapter_info->
+			 * AdapterTypeText. Use the first word as the vendor
+			 * and the other words as the product name.
+			 */
+			AACDB_PRINT((CE_NOTE, "sinf.AdapterTypeText = "
+				"\"%s\"", sinf.AdapterTypeText));
+			p = sinf.AdapterTypeText;
+			p0 = p1 = NULL;
+			/* Skip heading spaces */
+			while (*p && (*p == ' ' || *p == '\t'))
+				p++;
+			p0 = p;
+			while (*p && (*p != ' ' && *p != '\t'))
+				p++;
+			/* Remove middle spaces */
+			while (*p && (*p == ' ' || *p == '\t'))
+				*p++ = 0;
+			p1 = p;
+			/* Remove trailing spaces */
+			p = p1 + strlen(p1) - 1;
+			while (p > p1 && (*p == ' ' || *p == '\t'))
+				*p-- = 0;
+			if (*p0 && *p1) {
+				(void *)strncpy(softs->vendor_name, p0,
+					AAC_VENDOR_LEN);
+				(void *)strncpy(softs->product_name, p1,
+					AAC_PRODUCT_LEN);
+			} else {
+				cmn_err(CE_WARN,
+					"?adapter name mis-formatted\n");
+				if (*p0)
+					(void *)strncpy(softs->product_name,
+						p0, AAC_PRODUCT_LEN);
+			}
+			AACDB_PRINT((CE_NOTE,
+				"adapter: vendor = \"%s\", product = \"%s\"",
+				softs->vendor_name, softs->product_name));
+		}
+	}
+
 	/* Perform acceptance of adapter-detected config changes if possible */
 	if (aac_handle_adapter_config_issues(softs) != AACMPE_OK) {
 		cmn_err(CE_CONT, "?Handle adapter config issues failed");
@@ -2430,21 +2551,17 @@
 static uchar_t *
 aac_vendor_id(struct aac_softstate *softs, uchar_t *buf)
 {
-	struct aac_card_type *cardp = &aac_cards[softs->card];
-
-	(void) memset(buf, ' ', 8);
-	bcopy(cardp->vid, buf, strlen(cardp->vid));
-	return (buf + 8);
+	(void) memset(buf, ' ', AAC_VENDOR_LEN);
+	bcopy(softs->vendor_name, buf, strlen(softs->vendor_name));
+	return (buf + AAC_VENDOR_LEN);
 }
 
 static uchar_t *
 aac_product_id(struct aac_softstate *softs, uchar_t *buf)
 {
-	struct aac_card_type *cardp = &aac_cards[softs->card];
-
-	(void) memset(buf, ' ', 16);
-	bcopy(cardp->desc, buf, strlen(cardp->desc));
-	return (buf + 16);
+	(void) memset(buf, ' ', AAC_PRODUCT_LEN);
+	bcopy(softs->product_name, buf, strlen(softs->product_name));
+	return (buf + AAC_PRODUCT_LEN);
 }
 
 /*
@@ -3085,11 +3202,9 @@
 			cap.lbasize = BE_32(AAC_SECTOR_SIZE);
 
 			aac_free_dmamap(ac);
-			if (bp->b_flags & (B_PHYS|B_PAGEIO)) {
+			if (bp->b_flags & (B_PHYS|B_PAGEIO))
 				bp_mapin(bp);
-				bcopy(&cap, bp->b_un.b_addr, 8);
-			} else
-				bcopy(&cap, bp->b_un.b_addr, 8);
+			bcopy(&cap, bp->b_un.b_addr, 8);
 			pkt->pkt_state |= STATE_XFERRED_DATA;
 		}
 		aac_soft_callback(softs, ac, CMD_CMPLT);
@@ -3112,11 +3227,9 @@
 			cap16.sc_lbasize = BE_32(AAC_SECTOR_SIZE);
 
 			aac_free_dmamap(ac);
-			if (bp->b_flags & (B_PHYS | B_PAGEIO)) {
+			if (bp->b_flags & (B_PHYS | B_PAGEIO))
 				bp_mapin(bp);
-				bcopy(&cap16, bp->b_un.b_addr, cap_len);
-			} else
-				bcopy(&cap16, bp->b_un.b_addr, cap_len);
+			bcopy(&cap16, bp->b_un.b_addr, cap_len);
 			pkt->pkt_state |= STATE_XFERRED_DATA;
 		}
 		aac_soft_callback(softs, ac, CMD_CMPLT);
@@ -3253,9 +3366,9 @@
 		ac->flags |= AAC_CMD_SOFT_INTR;
 		aac_free_dmamap(ac);
 		if (pkt->pkt_cdbp[4] & 0x01)
-			softs->container[target*16+lun].locked = 1;
+			softs->container[target].locked = 1;
 		else
-			softs->container[target*16+lun].locked = 0;
+			softs->container[target].locked = 0;
 		aac_soft_callback(softs, ac, CMD_CMPLT);
 		ret_val = TRAN_ACCEPT;
 		break;
--- a/usr/src/uts/intel/io/aac/aac.h	Sun Apr 29 21:15:25 2007 -0700
+++ b/usr/src/uts/intel/io/aac/aac.h	Mon Apr 30 05:27:41 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -80,7 +80,7 @@
 
 #define	AAC_DRIVER_MAJOR_VERSION	2
 #define	AAC_DRIVER_MINOR_VERSION	1
-#define	AAC_DRIVER_BUGFIX_LEVEL		12
+#define	AAC_DRIVER_BUGFIX_LEVEL		13
 #define	AAC_DRIVER_TYPE			AAC_TYPE_RELEASE
 
 #define	STR(s)				# s
@@ -151,6 +151,7 @@
 	char *desc;		/* ASCII data for INQUIRY command product id */
 };
 
+/* Array description */
 struct aac_container {
 	uint16_t valid;
 	uint32_t cid;		/* container id */
@@ -222,9 +223,9 @@
 struct aac_softstate;
 struct aac_interface {
 	int (*aif_get_fwstatus)(struct aac_softstate *);
-	int (*aif_get_mailbox)(struct aac_softstate *, int mb);
-	void (*aif_set_mailbox)(struct aac_softstate *, uint32_t command,
-		uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3);
+	int (*aif_get_mailbox)(struct aac_softstate *, int);
+	void (*aif_set_mailbox)(struct aac_softstate *, uint32_t,
+		uint32_t, uint32_t, uint32_t, uint32_t);
 };
 
 struct aac_fib_context {
@@ -234,8 +235,14 @@
 	struct aac_fib_context *next, *prev;
 };
 
+#define	AAC_VENDOR_LEN		8
+#define	AAC_PRODUCT_LEN		16
+
 struct aac_softstate {
 	int card;		/* index to aac_cards */
+	uint16_t hwif;		/* card chip type: i960 or Rocket */
+	char vendor_name[AAC_VENDOR_LEN + 1];
+	char product_name[AAC_PRODUCT_LEN + 1];
 	uint32_t support_opt;	/* firmware features */
 	uint32_t atu_size;	/* actual size of PCI mem space */
 	uint32_t map_size;	/* mapped PCI mem space size */
@@ -280,7 +287,7 @@
 	struct aac_cmd_queue q_wait;		/* for async FIB requests */
 	struct aac_cmd_queue q_comp;		/* for completed io requests */
 
-	/* aac I/O slots and FIBs */
+	/* I/O slots and FIBs */
 	int total_slots;		/* total slots allocated */
 	int total_fibs;			/* total FIBs allocated */
 	struct aac_slot *io_slot;	/* static list for allocated slots */
--- a/usr/src/uts/intel/io/aac/aac_regs.h	Sun Apr 29 21:15:25 2007 -0700
+++ b/usr/src/uts/intel/io/aac/aac_regs.h	Mon Apr 30 05:27:41 2007 -0700
@@ -229,8 +229,9 @@
 #define	OnLineDiagnostic		800
 #define	FduAdapterTest			801
 
-
-/* Structures used to respond to a RequestAdapterInfo FIB */
+/*
+ * Revision number handling
+ */
 struct FsaRev {
 	union {
 		struct {
@@ -244,6 +245,9 @@
 	uint32_t buildNumber;
 };
 
+/*
+ * Structures used to respond to a RequestAdapterInfo FIB
+ */
 struct aac_adapter_info {
 	uint32_t	PlatformBase;	/* adapter type */
 	uint32_t	CpuArchitecture; /* adapter CPU type */
@@ -264,6 +268,59 @@
 	uint32_t	OemVariant;
 };
 
+/*
+ * The following definitions on Supplement Adapter Information
+ * come from Adaptec:
+ */
+struct vpd_info {
+	uint8_t		AssemblyPn[8];
+	uint8_t		FruPn[8];
+	uint8_t		BatteryFruPn[8];
+	uint8_t		EcVersionString[8];
+	uint8_t		Tsid[12];
+};
+
+#define	MFG_PCBA_SERIAL_NUMBER_WIDTH	12
+#define	MFG_WWN_WIDTH			8
+
+struct aac_supplement_adapter_info {
+	/* The assigned Adapter Type Text, extra byte for null termination */
+	int8_t		AdapterTypeText[17+1];
+	/* Pad for the text above */
+	int8_t		Pad[2];
+	/* Size in bytes of the memory that is flashed */
+	uint32_t	FlashMemoryByteSize;
+	/* The assigned IMAGEID_xxx for this adapter */
+	uint32_t	FlashImageId;
+	/*
+	 * The maximum number of Phys available on a SATA/SAS
+	 * Controller, 0 otherwise
+	 */
+	uint32_t	MaxNumberPorts;
+	/* Version of expansion area */
+	uint32_t	Version;
+	uint32_t	FeatureBits;
+	uint8_t		SlotNumber;
+	uint8_t		ReservedPad0[3];
+	uint8_t		BuildDate[12];
+	/* The current number of Ports on a SAS controller, 0 otherwise */
+	uint32_t	CurrentNumberPorts;
+
+	struct vpd_info VpdInfo;
+
+	/* Firmware Revision (Vmaj.min-dash.) */
+	struct FsaRev	FlashFirmwareRevision;
+	uint32_t	RaidTypeMorphOptions;
+	/* Firmware's boot code Revision (Vmaj.min-dash.) */
+	struct FsaRev	FlashFirmwareBootRevision;
+	/* PCBA serial no. from th MFG sector */
+	uint8_t		MfgPcbaSerialNo[MFG_PCBA_SERIAL_NUMBER_WIDTH];
+	/* WWN from the MFG sector */
+	uint8_t		MfgWWNName[MFG_WWN_WIDTH];
+	/* Growth Area for future expansion ((7*4) - 12 - 8)/4 = 2 words */
+	uint32_t	ReservedGrowth[2];
+};
+
 /* Container creation data */
 struct aac_container_creation {
 	uint8_t		ViaBuildNumber;
@@ -316,8 +373,28 @@
 #define	CNT_SIZE			5
 
 /* Container types */
-#define	CT_NONE				0
-#define	CT_PASSTHRU			8
+typedef enum {
+	CT_NONE = 0,
+	CT_VOLUME,
+	CT_MIRROR,
+	CT_STRIPE,
+	CT_RAID5,
+	CT_SSRW,
+	CT_SSRO,
+	CT_MORPH,
+	CT_PASSTHRU,
+	CT_RAID4,
+	CT_RAID10,		/* stripe of mirror */
+	CT_RAID00,		/* stripe of stripe */
+	CT_VOLUME_OF_MIRRORS,	/* volume of mirror */
+	CT_PSEUDO_RAID3,	/* really raid4 */
+	CT_RAID50,		/* stripe of raid5 */
+	CT_RAID5D,		/* raid5 distributed hot-sparing */
+	CT_RAID5D0,
+	CT_RAID1E,		/* extended raid1 mirroring */
+	CT_RAID6,
+	CT_RAID60
+} AAC_FSAVolType;
 
 /*
  * Container Configuration Sub-Commands
@@ -655,8 +732,28 @@
 	MAX_VMCOMMAND_NUM	/* used for sizing stats array - leave last */
 } AAC_VmCommand;
 
-/* Host-addressable object types */
-#define	FT_FILESYS		8
+/*
+ * Host-addressable object types
+ */
+typedef enum {
+	FT_REG = 1,	/* regular file */
+	FT_DIR,		/* directory */
+	FT_BLK,		/* "block" device - reserved */
+	FT_CHR,		/* "character special" device - reserved */
+	FT_LNK,		/* symbolic link */
+	FT_SOCK,	/* socket */
+	FT_FIFO,	/* fifo */
+	FT_FILESYS,	/* ADAPTEC's "FSA"(tm) filesystem */
+	FT_DRIVE,	/* physical disk - addressable in scsi by b/t/l */
+	FT_SLICE,	/* virtual disk - raw volume - slice */
+	FT_PARTITION,	/* FSA partition - carved out of a slice - building */
+			/* block for containers */
+	FT_VOLUME,	/* Container - Volume Set */
+	FT_STRIPE,	/* Container - Stripe Set */
+	FT_MIRROR,	/* Container - Mirror Set */
+	FT_RAID5,	/* Container - Raid 5 Set */
+	FT_DATABASE	/* Storage object with "foreign" content manager */
+} AAC_FType;
 
 /* Host-side scatter/gather list for 32-bit, 64-bit, raw commands */
 struct aac_sg_entry {