diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/intel/io/aac/aac.c | 409 | ||||
-rw-r--r-- | usr/src/uts/intel/io/aac/aac.h | 19 | ||||
-rw-r--r-- | usr/src/uts/intel/io/aac/aac_regs.h | 109 |
3 files changed, 377 insertions, 160 deletions
diff --git a/usr/src/uts/intel/io/aac/aac.c b/usr/src/uts/intel/io/aac/aac.c index 4871874ee5..a68584d66b 100644 --- a/usr/src/uts/intel/io/aac/aac.c +++ b/usr/src/uts/intel/io/aac/aac.c @@ -105,7 +105,11 @@ _NOTE(CONSTCOND) } while (0) ((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 @@ _NOTE(CONSTCOND) } while (0) #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 @@ static struct aac_interface aac_rkt_interface = { 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_card_type(struct aac_softstate *); 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 struct aac_fib *aac_grab_sync_fib(struct aac_softstate *, 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_start_waiting_io(struct aac_softstate *); 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 modlinkage aac_modlinkage = { 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[] = { - {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, + {0x1028, 0x1, 0x1028, 0x1, AAC_HWIF_I960RX, AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"}, - {0x1028, 0xa, 0x1028, 0x106, AAC_HWIF_I960RX, + {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, 0x2, 0x1028, 0xd1, AAC_HWIF_I960RX, + {0x1028, 0xa, 0x1028, 0x106, 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, + {0x1028, 0xa, 0x1028, 0x11b, AAC_HWIF_I960RX, AAC_FLAGS_PERC, AAC_TYPE_SCSI, "Dell", "PERC 3/Di"}, - {0x1028, 0x1, 0x1028, 0x1, AAC_HWIF_I960RX, + {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, 0x287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB | AAC_FLAGS_256FIBS, AAC_TYPE_SCSI, "Adaptec", "2200S"}, @@ -358,8 +378,8 @@ static struct aac_card_type aac_cards[] = { 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 @@ static struct aac_card_type aac_cards[] = { 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 struct { 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 @@ static ddi_dma_attr_t aac_buf_dma_attr = { 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 @@ aac_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) AACDB_PRINT((CE_WARN, "Cannot alloc soft state")); goto error; } - attach_state |= AAC_ATTACH_SOFTSTATE_ALLOCED; softs = ddi_get_soft_state(aac_softstatep, instance); - softs->devinfo_p = dip; + attach_state |= AAC_ATTACH_SOFTSTATE_ALLOCED; + 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 @@ aac_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 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 @@ aac_softintr(caddr_t arg) /* * 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 @@ aac_intr_norm(struct aac_softstate *softs, struct aac_cmd *acp) 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 @@ aac_check_card_type(struct aac_softstate *softs) 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_check_card_type(struct aac_softstate *softs) 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 @@ aac_check_firmware(struct aac_softstate *softs) /* * 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 @@ aac_common_attach(struct aac_softstate *softs) 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 @@ aac_setup_comm_space(struct aac_softstate *softs) 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 @@ aac_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt) 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 @@ aac_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt) 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 @@ aac_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt) 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; diff --git a/usr/src/uts/intel/io/aac/aac.h b/usr/src/uts/intel/io/aac/aac.h index 83da9a94b4..7b455c3739 100644 --- a/usr/src/uts/intel/io/aac/aac.h +++ b/usr/src/uts/intel/io/aac/aac.h @@ -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 @@ _NOTE(CONSTCOND) } while (0) #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 @@ struct aac_card_type { 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_slot { 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 { 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_softstate { 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 */ diff --git a/usr/src/uts/intel/io/aac/aac_regs.h b/usr/src/uts/intel/io/aac/aac_regs.h index a04e6ddc13..65d3a59959 100644 --- a/usr/src/uts/intel/io/aac/aac_regs.h +++ b/usr/src/uts/intel/io/aac/aac_regs.h @@ -229,8 +229,9 @@ struct aac_fib { #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 @@ struct FsaRev { 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 @@ struct aac_adapter_info { 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 @@ struct aac_mntinforesp { #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 @@ typedef enum { 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 { |