diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/hpsa.c | 117 | ||||
-rw-r--r-- | drivers/scsi/hpsa.h | 1 |
2 files changed, 98 insertions, 20 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 46055e2490f1..cc9e92a3be22 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -458,6 +458,15 @@ static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) | |||
458 | return (scsi3addr[3] & 0xC0) == 0x40; | 458 | return (scsi3addr[3] & 0xC0) == 0x40; |
459 | } | 459 | } |
460 | 460 | ||
461 | static inline int is_scsi_rev_5(struct ctlr_info *h) | ||
462 | { | ||
463 | if (!h->hba_inquiry_data) | ||
464 | return 0; | ||
465 | if ((h->hba_inquiry_data[2] & 0x07) == 5) | ||
466 | return 1; | ||
467 | return 0; | ||
468 | } | ||
469 | |||
461 | static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", | 470 | static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", |
462 | "UNKNOWN" | 471 | "UNKNOWN" |
463 | }; | 472 | }; |
@@ -1525,22 +1534,44 @@ static void figure_bus_target_lun(struct ctlr_info *h, | |||
1525 | 1534 | ||
1526 | if (is_logical_dev_addr_mode(lunaddrbytes)) { | 1535 | if (is_logical_dev_addr_mode(lunaddrbytes)) { |
1527 | /* logical device */ | 1536 | /* logical device */ |
1528 | lunid = le32_to_cpu(*((__le32 *) lunaddrbytes)); | 1537 | if (unlikely(is_scsi_rev_5(h))) { |
1529 | if (is_msa2xxx(h, device)) { | 1538 | /* p1210m, logical drives lun assignments |
1530 | *bus = 1; | 1539 | * match SCSI REPORT LUNS data. |
1531 | *target = (lunid >> 16) & 0x3fff; | 1540 | */ |
1532 | *lun = lunid & 0x00ff; | 1541 | lunid = le32_to_cpu(*((__le32 *) lunaddrbytes)); |
1533 | } else { | ||
1534 | *bus = 0; | 1542 | *bus = 0; |
1535 | *lun = 0; | 1543 | *target = 0; |
1536 | *target = lunid & 0x3fff; | 1544 | *lun = (lunid & 0x3fff) + 1; |
1545 | } else { | ||
1546 | /* not p1210m... */ | ||
1547 | lunid = le32_to_cpu(*((__le32 *) lunaddrbytes)); | ||
1548 | if (is_msa2xxx(h, device)) { | ||
1549 | /* msa2xxx way, put logicals on bus 1 | ||
1550 | * and match target/lun numbers box | ||
1551 | * reports. | ||
1552 | */ | ||
1553 | *bus = 1; | ||
1554 | *target = (lunid >> 16) & 0x3fff; | ||
1555 | *lun = lunid & 0x00ff; | ||
1556 | } else { | ||
1557 | /* Traditional smart array way. */ | ||
1558 | *bus = 0; | ||
1559 | *lun = 0; | ||
1560 | *target = lunid & 0x3fff; | ||
1561 | } | ||
1537 | } | 1562 | } |
1538 | } else { | 1563 | } else { |
1539 | /* physical device */ | 1564 | /* physical device */ |
1540 | if (is_hba_lunid(lunaddrbytes)) | 1565 | if (is_hba_lunid(lunaddrbytes)) |
1541 | *bus = 3; | 1566 | if (unlikely(is_scsi_rev_5(h))) { |
1567 | *bus = 0; /* put p1210m ctlr at 0,0,0 */ | ||
1568 | *target = 0; | ||
1569 | *lun = 0; | ||
1570 | return; | ||
1571 | } else | ||
1572 | *bus = 3; /* traditional smartarray */ | ||
1542 | else | 1573 | else |
1543 | *bus = 2; | 1574 | *bus = 2; /* physical disk */ |
1544 | *target = -1; | 1575 | *target = -1; |
1545 | *lun = -1; /* we will fill these in later. */ | 1576 | *lun = -1; /* we will fill these in later. */ |
1546 | } | 1577 | } |
@@ -1580,6 +1611,9 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h, | |||
1580 | if (is_hba_lunid(scsi3addr)) | 1611 | if (is_hba_lunid(scsi3addr)) |
1581 | return 0; /* Don't add the RAID controller here. */ | 1612 | return 0; /* Don't add the RAID controller here. */ |
1582 | 1613 | ||
1614 | if (is_scsi_rev_5(h)) | ||
1615 | return 0; /* p1210m doesn't need to do this. */ | ||
1616 | |||
1583 | #define MAX_MSA2XXX_ENCLOSURES 32 | 1617 | #define MAX_MSA2XXX_ENCLOSURES 32 |
1584 | if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) { | 1618 | if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) { |
1585 | dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX " | 1619 | dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX " |
@@ -1643,6 +1677,31 @@ static int hpsa_gather_lun_info(struct ctlr_info *h, | |||
1643 | return 0; | 1677 | return 0; |
1644 | } | 1678 | } |
1645 | 1679 | ||
1680 | u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position, int i, | ||
1681 | int nphysicals, int nlogicals, struct ReportLUNdata *physdev_list, | ||
1682 | struct ReportLUNdata *logdev_list) | ||
1683 | { | ||
1684 | /* Helper function, figure out where the LUN ID info is coming from | ||
1685 | * given index i, lists of physical and logical devices, where in | ||
1686 | * the list the raid controller is supposed to appear (first or last) | ||
1687 | */ | ||
1688 | |||
1689 | int logicals_start = nphysicals + (raid_ctlr_position == 0); | ||
1690 | int last_device = nphysicals + nlogicals + (raid_ctlr_position == 0); | ||
1691 | |||
1692 | if (i == raid_ctlr_position) | ||
1693 | return RAID_CTLR_LUNID; | ||
1694 | |||
1695 | if (i < logicals_start) | ||
1696 | return &physdev_list->LUN[i - (raid_ctlr_position == 0)][0]; | ||
1697 | |||
1698 | if (i < last_device) | ||
1699 | return &logdev_list->LUN[i - nphysicals - | ||
1700 | (raid_ctlr_position == 0)][0]; | ||
1701 | BUG(); | ||
1702 | return NULL; | ||
1703 | } | ||
1704 | |||
1646 | static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | 1705 | static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) |
1647 | { | 1706 | { |
1648 | /* the idea here is we could get notified | 1707 | /* the idea here is we could get notified |
@@ -1666,6 +1725,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1666 | int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8; | 1725 | int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8; |
1667 | int i, nmsa2xxx_enclosures, ndevs_to_allocate; | 1726 | int i, nmsa2xxx_enclosures, ndevs_to_allocate; |
1668 | int bus, target, lun; | 1727 | int bus, target, lun; |
1728 | int raid_ctlr_position; | ||
1669 | DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR); | 1729 | DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR); |
1670 | 1730 | ||
1671 | currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA, | 1731 | currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA, |
@@ -1703,23 +1763,22 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1703 | ndev_allocated++; | 1763 | ndev_allocated++; |
1704 | } | 1764 | } |
1705 | 1765 | ||
1766 | if (unlikely(is_scsi_rev_5(h))) | ||
1767 | raid_ctlr_position = 0; | ||
1768 | else | ||
1769 | raid_ctlr_position = nphysicals + nlogicals; | ||
1770 | |||
1706 | /* adjust our table of devices */ | 1771 | /* adjust our table of devices */ |
1707 | nmsa2xxx_enclosures = 0; | 1772 | nmsa2xxx_enclosures = 0; |
1708 | for (i = 0; i < nphysicals + nlogicals + 1; i++) { | 1773 | for (i = 0; i < nphysicals + nlogicals + 1; i++) { |
1709 | u8 *lunaddrbytes; | 1774 | u8 *lunaddrbytes; |
1710 | 1775 | ||
1711 | /* Figure out where the LUN ID info is coming from */ | 1776 | /* Figure out where the LUN ID info is coming from */ |
1712 | if (i < nphysicals) | 1777 | lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, |
1713 | lunaddrbytes = &physdev_list->LUN[i][0]; | 1778 | i, nphysicals, nlogicals, physdev_list, logdev_list); |
1714 | else | ||
1715 | if (i < nphysicals + nlogicals) | ||
1716 | lunaddrbytes = | ||
1717 | &logdev_list->LUN[i-nphysicals][0]; | ||
1718 | else /* jam in the RAID controller at the end */ | ||
1719 | lunaddrbytes = RAID_CTLR_LUNID; | ||
1720 | |||
1721 | /* skip masked physical devices. */ | 1779 | /* skip masked physical devices. */ |
1722 | if (lunaddrbytes[3] & 0xC0 && i < nphysicals) | 1780 | if (lunaddrbytes[3] & 0xC0 && |
1781 | i < nphysicals + (raid_ctlr_position == 0)) | ||
1723 | continue; | 1782 | continue; |
1724 | 1783 | ||
1725 | /* Get device type, vendor, model, device id */ | 1784 | /* Get device type, vendor, model, device id */ |
@@ -3349,6 +3408,22 @@ err_out_free_res: | |||
3349 | return err; | 3408 | return err; |
3350 | } | 3409 | } |
3351 | 3410 | ||
3411 | static void __devinit hpsa_hba_inquiry(struct ctlr_info *h) | ||
3412 | { | ||
3413 | int rc; | ||
3414 | |||
3415 | #define HBA_INQUIRY_BYTE_COUNT 64 | ||
3416 | h->hba_inquiry_data = kmalloc(HBA_INQUIRY_BYTE_COUNT, GFP_KERNEL); | ||
3417 | if (!h->hba_inquiry_data) | ||
3418 | return; | ||
3419 | rc = hpsa_scsi_do_inquiry(h, RAID_CTLR_LUNID, 0, | ||
3420 | h->hba_inquiry_data, HBA_INQUIRY_BYTE_COUNT); | ||
3421 | if (rc != 0) { | ||
3422 | kfree(h->hba_inquiry_data); | ||
3423 | h->hba_inquiry_data = NULL; | ||
3424 | } | ||
3425 | } | ||
3426 | |||
3352 | static int __devinit hpsa_init_one(struct pci_dev *pdev, | 3427 | static int __devinit hpsa_init_one(struct pci_dev *pdev, |
3353 | const struct pci_device_id *ent) | 3428 | const struct pci_device_id *ent) |
3354 | { | 3429 | { |
@@ -3458,6 +3533,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
3458 | h->access.set_intr_mask(h, HPSA_INTR_ON); | 3533 | h->access.set_intr_mask(h, HPSA_INTR_ON); |
3459 | 3534 | ||
3460 | hpsa_put_ctlr_into_performant_mode(h); | 3535 | hpsa_put_ctlr_into_performant_mode(h); |
3536 | hpsa_hba_inquiry(h); | ||
3461 | hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ | 3537 | hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ |
3462 | h->busy_initializing = 0; | 3538 | h->busy_initializing = 0; |
3463 | return 1; | 3539 | return 1; |
@@ -3550,6 +3626,7 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) | |||
3550 | h->reply_pool, h->reply_pool_dhandle); | 3626 | h->reply_pool, h->reply_pool_dhandle); |
3551 | kfree(h->cmd_pool_bits); | 3627 | kfree(h->cmd_pool_bits); |
3552 | kfree(h->blockFetchTable); | 3628 | kfree(h->blockFetchTable); |
3629 | kfree(h->hba_inquiry_data); | ||
3553 | /* | 3630 | /* |
3554 | * Deliberately omit pci_disable_device(): it does something nasty to | 3631 | * Deliberately omit pci_disable_device(): it does something nasty to |
3555 | * Smart Array controllers that pci_enable_device does not undo | 3632 | * Smart Array controllers that pci_enable_device does not undo |
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 0ba1aa3f4d4d..1ab0c1bbd27e 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h | |||
@@ -120,6 +120,7 @@ struct ctlr_info { | |||
120 | size_t reply_pool_size; | 120 | size_t reply_pool_size; |
121 | unsigned char reply_pool_wraparound; | 121 | unsigned char reply_pool_wraparound; |
122 | u32 *blockFetchTable; | 122 | u32 *blockFetchTable; |
123 | unsigned char *hba_inquiry_data; | ||
123 | }; | 124 | }; |
124 | #define HPSA_ABORT_MSG 0 | 125 | #define HPSA_ABORT_MSG 0 |
125 | #define HPSA_DEVICE_RESET_MSG 1 | 126 | #define HPSA_DEVICE_RESET_MSG 1 |