diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-14 23:09:14 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-14 23:09:14 (GMT) |
commit | bcd438be3b66110dfe70f655cadb2b20e201f076 (patch) | |
tree | 0c631cbcc730c4da0ebf74c68d025d6474114ca0 /drivers/scsi/hpsa.c | |
parent | 53d872e99520bbc7d83c34a416144e591ef69584 (diff) | |
parent | 610602f369b4c810c9df05e431abd38f38cb8e0d (diff) | |
download | linux-fsl-qoriq-bcd438be3b66110dfe70f655cadb2b20e201f076.tar.xz |
Merge git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6
* git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6: (25 commits)
[SCSI] bnx2i: Fixed the endian on TTT for NOP out transmission
[SCSI] libfc: fix referencing to fc_fcp_pkt from the frame pointer via fr_fsp()
[SCSI] libfc: block SCSI eh thread for blocked rports
[SCSI] libfc: fix fc_eh_host_reset
[SCSI] fcoe: Fix deadlock between fip's recv_work and rtnl
[SCSI] qla2xxx: Update version number to 8.03.07.07-k.
[SCSI] qla2xxx: Set the task attributes after memsetting fcp cmnd.
[SCSI] qla2xxx: Correct inadvertent loop state transitions during port-update handling.
[SCSI] qla2xxx: Save and restore irq in the response queue interrupt handler.
[SCSI] qla2xxx: Double check for command completion if abort mailbox command fails.
[SCSI] qla2xxx: Acquire hardware lock while manipulating dsd list.
[SCSI] qla2xxx: Fix qla24xx revision check while enabling interrupts.
[SCSI] qla2xxx: T10 DIF - Fix incorrect error reporting.
[SCSI] qla2xxx: T10 DIF - Handle uninitalized sectors.
[SCSI] hpsa: fix physical device lun and target numbering problem
[SCSI] hpsa: fix problem that OBDR devices are not detected
[SCSI] isci: add version number
[SCSI] isci: fix event-get pointer increment
[SCSI] isci: dynamic interrupt coalescing
[SCSI] isci: Leave requests alone if already terminating.
...
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 ec61bdb..b200b73 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, BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); removed[*nremoved] = h->dev[entry]; (*nremoved)++; + + /* + * New physical devices won't have target/lun assigned yet + * so we need to preserve the values in the slot we are replacing. + */ + if (new_entry->target == -1) { + new_entry->target = h->dev[entry]->target; + new_entry->lun = h->dev[entry]->lun; + } + h->dev[entry] = new_entry; added[*nadded] = new_entry; (*nadded)++; @@ -1548,10 +1558,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, - 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 *obdr_sig; inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); if (!inq_buff) @@ -1583,6 +1600,16 @@ static int hpsa_update_device_info(struct ctlr_info *h, else 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); return 0; @@ -1716,7 +1743,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h, return 0; } - if (hpsa_update_device_info(h, scsi3addr, this_device)) + if (hpsa_update_device_info(h, scsi3addr, this_device, NULL)) return 0; (*nmsa2xxx_enclosures)++; 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) */ struct ReportLUNdata *physdev_list = NULL; struct ReportLUNdata *logdev_list = NULL; - unsigned char *inq_buff = NULL; u32 nphysicals = 0; u32 nlogicals = 0; u32 ndev_allocated = 0; @@ -1824,11 +1850,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) GFP_KERNEL); physdev_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); - if (!currentsd || !physdev_list || !logdev_list || - !inq_buff || !tmpdevice) { + if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) { dev_err(&h->pdev->dev, "out of memory\n"); goto out; } @@ -1863,7 +1887,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) /* adjust our table of devices */ nmsa2xxx_enclosures = 0; 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 */ lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, @@ -1874,7 +1898,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) continue; /* 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. */ figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, tmpdevice); @@ -1898,7 +1923,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) hpsa_set_bus_target_lun(this_device, bus, target, lun); switch (this_device->devtype) { - case TYPE_ROM: { + case TYPE_ROM: /* We don't *really* support actual CD-ROM devices, * just "One Button Disaster Recovery" tape drive * 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) * device by checking for "$DR-10" in bytes 43-48 of * the inquiry data. */ - char obdr_sig[7]; -#define OBDR_TAPE_SIG "$DR-10" - 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++; + if (is_OBDR) + ncurrent++; break; case TYPE_DISK: if (i < nphysicals) @@ -1947,7 +1965,6 @@ out: for (i = 0; i < ndev_allocated; i++) kfree(currentsd[i]); kfree(currentsd); - kfree(inq_buff); kfree(physdev_list); kfree(logdev_list); } |