diff options
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ec61bdb833ac..b200b736b000 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -676,6 +676,16 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno, | |||
676 | BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); | 676 | BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); |
677 | removed[*nremoved] = h->dev[entry]; | 677 | removed[*nremoved] = h->dev[entry]; |
678 | (*nremoved)++; | 678 | (*nremoved)++; |
679 | |||
680 | /* | ||
681 | * New physical devices won't have target/lun assigned yet | ||
682 | * so we need to preserve the values in the slot we are replacing. | ||
683 | */ | ||
684 | if (new_entry->target == -1) { | ||
685 | new_entry->target = h->dev[entry]->target; | ||
686 | new_entry->lun = h->dev[entry]->lun; | ||
687 | } | ||
688 | |||
679 | h->dev[entry] = new_entry; | 689 | h->dev[entry] = new_entry; |
680 | added[*nadded] = new_entry; | 690 | added[*nadded] = new_entry; |
681 | (*nadded)++; | 691 | (*nadded)++; |
@@ -1548,10 +1558,17 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device, | |||
1548 | } | 1558 | } |
1549 | 1559 | ||
1550 | static int hpsa_update_device_info(struct ctlr_info *h, | 1560 | static int hpsa_update_device_info(struct ctlr_info *h, |
1551 | unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device) | 1561 | unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device, |
1562 | unsigned char *is_OBDR_device) | ||
1552 | { | 1563 | { |
1553 | #define OBDR_TAPE_INQ_SIZE 49 | 1564 | |
1565 | #define OBDR_SIG_OFFSET 43 | ||
1566 | #define OBDR_TAPE_SIG "$DR-10" | ||
1567 | #define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1) | ||
1568 | #define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN) | ||
1569 | |||
1554 | unsigned char *inq_buff; | 1570 | unsigned char *inq_buff; |
1571 | unsigned char *obdr_sig; | ||
1555 | 1572 | ||
1556 | inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); | 1573 | inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); |
1557 | if (!inq_buff) | 1574 | if (!inq_buff) |
@@ -1583,6 +1600,16 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
1583 | else | 1600 | else |
1584 | this_device->raid_level = RAID_UNKNOWN; | 1601 | this_device->raid_level = RAID_UNKNOWN; |
1585 | 1602 | ||
1603 | if (is_OBDR_device) { | ||
1604 | /* See if this is a One-Button-Disaster-Recovery device | ||
1605 | * by looking for "$DR-10" at offset 43 in inquiry data. | ||
1606 | */ | ||
1607 | obdr_sig = &inq_buff[OBDR_SIG_OFFSET]; | ||
1608 | *is_OBDR_device = (this_device->devtype == TYPE_ROM && | ||
1609 | strncmp(obdr_sig, OBDR_TAPE_SIG, | ||
1610 | OBDR_SIG_LEN) == 0); | ||
1611 | } | ||
1612 | |||
1586 | kfree(inq_buff); | 1613 | kfree(inq_buff); |
1587 | return 0; | 1614 | return 0; |
1588 | 1615 | ||
@@ -1716,7 +1743,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h, | |||
1716 | return 0; | 1743 | return 0; |
1717 | } | 1744 | } |
1718 | 1745 | ||
1719 | if (hpsa_update_device_info(h, scsi3addr, this_device)) | 1746 | if (hpsa_update_device_info(h, scsi3addr, this_device, NULL)) |
1720 | return 0; | 1747 | return 0; |
1721 | (*nmsa2xxx_enclosures)++; | 1748 | (*nmsa2xxx_enclosures)++; |
1722 | hpsa_set_bus_target_lun(this_device, bus, target, 0); | 1749 | hpsa_set_bus_target_lun(this_device, bus, target, 0); |
@@ -1808,7 +1835,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1808 | */ | 1835 | */ |
1809 | struct ReportLUNdata *physdev_list = NULL; | 1836 | struct ReportLUNdata *physdev_list = NULL; |
1810 | struct ReportLUNdata *logdev_list = NULL; | 1837 | struct ReportLUNdata *logdev_list = NULL; |
1811 | unsigned char *inq_buff = NULL; | ||
1812 | u32 nphysicals = 0; | 1838 | u32 nphysicals = 0; |
1813 | u32 nlogicals = 0; | 1839 | u32 nlogicals = 0; |
1814 | u32 ndev_allocated = 0; | 1840 | u32 ndev_allocated = 0; |
@@ -1824,11 +1850,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1824 | GFP_KERNEL); | 1850 | GFP_KERNEL); |
1825 | physdev_list = kzalloc(reportlunsize, GFP_KERNEL); | 1851 | physdev_list = kzalloc(reportlunsize, GFP_KERNEL); |
1826 | logdev_list = kzalloc(reportlunsize, GFP_KERNEL); | 1852 | logdev_list = kzalloc(reportlunsize, GFP_KERNEL); |
1827 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); | ||
1828 | tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); | 1853 | tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); |
1829 | 1854 | ||
1830 | if (!currentsd || !physdev_list || !logdev_list || | 1855 | if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) { |
1831 | !inq_buff || !tmpdevice) { | ||
1832 | dev_err(&h->pdev->dev, "out of memory\n"); | 1856 | dev_err(&h->pdev->dev, "out of memory\n"); |
1833 | goto out; | 1857 | goto out; |
1834 | } | 1858 | } |
@@ -1863,7 +1887,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1863 | /* adjust our table of devices */ | 1887 | /* adjust our table of devices */ |
1864 | nmsa2xxx_enclosures = 0; | 1888 | nmsa2xxx_enclosures = 0; |
1865 | for (i = 0; i < nphysicals + nlogicals + 1; i++) { | 1889 | for (i = 0; i < nphysicals + nlogicals + 1; i++) { |
1866 | u8 *lunaddrbytes; | 1890 | u8 *lunaddrbytes, is_OBDR = 0; |
1867 | 1891 | ||
1868 | /* Figure out where the LUN ID info is coming from */ | 1892 | /* Figure out where the LUN ID info is coming from */ |
1869 | lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, | 1893 | lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, |
@@ -1874,7 +1898,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1874 | continue; | 1898 | continue; |
1875 | 1899 | ||
1876 | /* Get device type, vendor, model, device id */ | 1900 | /* Get device type, vendor, model, device id */ |
1877 | if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice)) | 1901 | if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice, |
1902 | &is_OBDR)) | ||
1878 | continue; /* skip it if we can't talk to it. */ | 1903 | continue; /* skip it if we can't talk to it. */ |
1879 | figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, | 1904 | figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, |
1880 | tmpdevice); | 1905 | tmpdevice); |
@@ -1898,7 +1923,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1898 | hpsa_set_bus_target_lun(this_device, bus, target, lun); | 1923 | hpsa_set_bus_target_lun(this_device, bus, target, lun); |
1899 | 1924 | ||
1900 | switch (this_device->devtype) { | 1925 | switch (this_device->devtype) { |
1901 | case TYPE_ROM: { | 1926 | case TYPE_ROM: |
1902 | /* We don't *really* support actual CD-ROM devices, | 1927 | /* We don't *really* support actual CD-ROM devices, |
1903 | * just "One Button Disaster Recovery" tape drive | 1928 | * just "One Button Disaster Recovery" tape drive |
1904 | * which temporarily pretends to be a CD-ROM drive. | 1929 | * which temporarily pretends to be a CD-ROM drive. |
@@ -1906,15 +1931,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1906 | * device by checking for "$DR-10" in bytes 43-48 of | 1931 | * device by checking for "$DR-10" in bytes 43-48 of |
1907 | * the inquiry data. | 1932 | * the inquiry data. |
1908 | */ | 1933 | */ |
1909 | char obdr_sig[7]; | 1934 | if (is_OBDR) |
1910 | #define OBDR_TAPE_SIG "$DR-10" | 1935 | ncurrent++; |
1911 | strncpy(obdr_sig, &inq_buff[43], 6); | ||
1912 | obdr_sig[6] = '\0'; | ||
1913 | if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) | ||
1914 | /* Not OBDR device, ignore it. */ | ||
1915 | break; | ||
1916 | } | ||
1917 | ncurrent++; | ||
1918 | break; | 1936 | break; |
1919 | case TYPE_DISK: | 1937 | case TYPE_DISK: |
1920 | if (i < nphysicals) | 1938 | if (i < nphysicals) |
@@ -1947,7 +1965,6 @@ out: | |||
1947 | for (i = 0; i < ndev_allocated; i++) | 1965 | for (i = 0; i < ndev_allocated; i++) |
1948 | kfree(currentsd[i]); | 1966 | kfree(currentsd[i]); |
1949 | kfree(currentsd); | 1967 | kfree(currentsd); |
1950 | kfree(inq_buff); | ||
1951 | kfree(physdev_list); | 1968 | kfree(physdev_list); |
1952 | kfree(logdev_list); | 1969 | kfree(logdev_list); |
1953 | } | 1970 | } |