[SCSI] hpsa: fix problem that OBDR devices are not detected
The test to detect OBDR ("One Button Disaster Recovery") cd-rom devices was comparing against uninitialized data. Fixed by moving the test for the device to where the inquiry data is collected, and uninitialized variable altogether as it wasn't really being used. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Cc: stable@kernel.org Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
98e2a5a3a1
commit
0b0e1d6cbc
1 changed files with 27 additions and 20 deletions
|
@ -1548,10 +1548,17 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hpsa_update_device_info(struct ctlr_info *h,
|
static int hpsa_update_device_info(struct ctlr_info *h,
|
||||||
unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
|
unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
|
||||||
|
unsigned char *is_OBDR_device)
|
||||||
{
|
{
|
||||||
#define OBDR_TAPE_INQ_SIZE 49
|
|
||||||
|
#define OBDR_SIG_OFFSET 43
|
||||||
|
#define OBDR_TAPE_SIG "$DR-10"
|
||||||
|
#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1)
|
||||||
|
#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN)
|
||||||
|
|
||||||
unsigned char *inq_buff;
|
unsigned char *inq_buff;
|
||||||
|
unsigned char *obdr_sig;
|
||||||
|
|
||||||
inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
|
inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
|
||||||
if (!inq_buff)
|
if (!inq_buff)
|
||||||
|
@ -1583,6 +1590,16 @@ static int hpsa_update_device_info(struct ctlr_info *h,
|
||||||
else
|
else
|
||||||
this_device->raid_level = RAID_UNKNOWN;
|
this_device->raid_level = RAID_UNKNOWN;
|
||||||
|
|
||||||
|
if (is_OBDR_device) {
|
||||||
|
/* See if this is a One-Button-Disaster-Recovery device
|
||||||
|
* by looking for "$DR-10" at offset 43 in inquiry data.
|
||||||
|
*/
|
||||||
|
obdr_sig = &inq_buff[OBDR_SIG_OFFSET];
|
||||||
|
*is_OBDR_device = (this_device->devtype == TYPE_ROM &&
|
||||||
|
strncmp(obdr_sig, OBDR_TAPE_SIG,
|
||||||
|
OBDR_SIG_LEN) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
kfree(inq_buff);
|
kfree(inq_buff);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1716,7 +1733,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hpsa_update_device_info(h, scsi3addr, this_device))
|
if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
(*nmsa2xxx_enclosures)++;
|
(*nmsa2xxx_enclosures)++;
|
||||||
hpsa_set_bus_target_lun(this_device, bus, target, 0);
|
hpsa_set_bus_target_lun(this_device, bus, target, 0);
|
||||||
|
@ -1808,7 +1825,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
*/
|
*/
|
||||||
struct ReportLUNdata *physdev_list = NULL;
|
struct ReportLUNdata *physdev_list = NULL;
|
||||||
struct ReportLUNdata *logdev_list = NULL;
|
struct ReportLUNdata *logdev_list = NULL;
|
||||||
unsigned char *inq_buff = NULL;
|
|
||||||
u32 nphysicals = 0;
|
u32 nphysicals = 0;
|
||||||
u32 nlogicals = 0;
|
u32 nlogicals = 0;
|
||||||
u32 ndev_allocated = 0;
|
u32 ndev_allocated = 0;
|
||||||
|
@ -1824,11 +1840,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
|
physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
|
||||||
logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
|
logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
|
||||||
inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
|
|
||||||
tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
|
tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
|
||||||
|
|
||||||
if (!currentsd || !physdev_list || !logdev_list ||
|
if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) {
|
||||||
!inq_buff || !tmpdevice) {
|
|
||||||
dev_err(&h->pdev->dev, "out of memory\n");
|
dev_err(&h->pdev->dev, "out of memory\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1863,7 +1877,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
/* adjust our table of devices */
|
/* adjust our table of devices */
|
||||||
nmsa2xxx_enclosures = 0;
|
nmsa2xxx_enclosures = 0;
|
||||||
for (i = 0; i < nphysicals + nlogicals + 1; i++) {
|
for (i = 0; i < nphysicals + nlogicals + 1; i++) {
|
||||||
u8 *lunaddrbytes;
|
u8 *lunaddrbytes, is_OBDR = 0;
|
||||||
|
|
||||||
/* Figure out where the LUN ID info is coming from */
|
/* Figure out where the LUN ID info is coming from */
|
||||||
lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
|
lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
|
||||||
|
@ -1874,7 +1888,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Get device type, vendor, model, device id */
|
/* Get device type, vendor, model, device id */
|
||||||
if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice))
|
if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
|
||||||
|
&is_OBDR))
|
||||||
continue; /* skip it if we can't talk to it. */
|
continue; /* skip it if we can't talk to it. */
|
||||||
figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
|
figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
|
||||||
tmpdevice);
|
tmpdevice);
|
||||||
|
@ -1898,7 +1913,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
hpsa_set_bus_target_lun(this_device, bus, target, lun);
|
hpsa_set_bus_target_lun(this_device, bus, target, lun);
|
||||||
|
|
||||||
switch (this_device->devtype) {
|
switch (this_device->devtype) {
|
||||||
case TYPE_ROM: {
|
case TYPE_ROM:
|
||||||
/* We don't *really* support actual CD-ROM devices,
|
/* We don't *really* support actual CD-ROM devices,
|
||||||
* just "One Button Disaster Recovery" tape drive
|
* just "One Button Disaster Recovery" tape drive
|
||||||
* which temporarily pretends to be a CD-ROM drive.
|
* which temporarily pretends to be a CD-ROM drive.
|
||||||
|
@ -1906,15 +1921,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
* device by checking for "$DR-10" in bytes 43-48 of
|
* device by checking for "$DR-10" in bytes 43-48 of
|
||||||
* the inquiry data.
|
* the inquiry data.
|
||||||
*/
|
*/
|
||||||
char obdr_sig[7];
|
if (is_OBDR)
|
||||||
#define OBDR_TAPE_SIG "$DR-10"
|
ncurrent++;
|
||||||
strncpy(obdr_sig, &inq_buff[43], 6);
|
|
||||||
obdr_sig[6] = '\0';
|
|
||||||
if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
|
|
||||||
/* Not OBDR device, ignore it. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ncurrent++;
|
|
||||||
break;
|
break;
|
||||||
case TYPE_DISK:
|
case TYPE_DISK:
|
||||||
if (i < nphysicals)
|
if (i < nphysicals)
|
||||||
|
@ -1947,7 +1955,6 @@ out:
|
||||||
for (i = 0; i < ndev_allocated; i++)
|
for (i = 0; i < ndev_allocated; i++)
|
||||||
kfree(currentsd[i]);
|
kfree(currentsd[i]);
|
||||||
kfree(currentsd);
|
kfree(currentsd);
|
||||||
kfree(inq_buff);
|
|
||||||
kfree(physdev_list);
|
kfree(physdev_list);
|
||||||
kfree(logdev_list);
|
kfree(logdev_list);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue