From: "Stephen M. Cameron" <scameron@beardog.cce.hp.com>
To: James.Bottomley@HansenPartnership.com, akpm@linux-foundation.org
Cc: mikem@beardog.cce.hp.com, brace@beardog.cce.hp.com,
matthew.gates@hp.com, linux-scsi@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 17/30] hpsa: Fix p1210m LUN assignment.
Date: Thu, 04 Feb 2010 08:42:50 -0600 [thread overview]
Message-ID: <20100204144250.10406.92418.stgit@beardog.cce.hp.com> (raw)
In-Reply-To: <20100204144012.10406.14868.stgit@beardog.cce.hp.com>
From: Stephen M. Cameron <scameron@beardog.cce.hp.com>
hpsa: Fix p1210m LUN assignment. The p1210m responsds to SCSI report
LUNs, unlike traditional Smart Array controllers. This means that the
bus, target, and lun assignments done by the driver cannot be arbitrary,
but must match what SCSI REPORT LUNS returns.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
drivers/scsi/hpsa.c | 117 ++++++++++++++++++++++++++++++++++++++++++---------
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 46055e2..cc9e92a 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[])
return (scsi3addr[3] & 0xC0) == 0x40;
}
+static inline int is_scsi_rev_5(struct ctlr_info *h)
+{
+ if (!h->hba_inquiry_data)
+ return 0;
+ if ((h->hba_inquiry_data[2] & 0x07) == 5)
+ return 1;
+ return 0;
+}
+
static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
"UNKNOWN"
};
@@ -1525,22 +1534,44 @@ static void figure_bus_target_lun(struct ctlr_info *h,
if (is_logical_dev_addr_mode(lunaddrbytes)) {
/* logical device */
- lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
- if (is_msa2xxx(h, device)) {
- *bus = 1;
- *target = (lunid >> 16) & 0x3fff;
- *lun = lunid & 0x00ff;
- } else {
+ if (unlikely(is_scsi_rev_5(h))) {
+ /* p1210m, logical drives lun assignments
+ * match SCSI REPORT LUNS data.
+ */
+ lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
*bus = 0;
- *lun = 0;
- *target = lunid & 0x3fff;
+ *target = 0;
+ *lun = (lunid & 0x3fff) + 1;
+ } else {
+ /* not p1210m... */
+ lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+ if (is_msa2xxx(h, device)) {
+ /* msa2xxx way, put logicals on bus 1
+ * and match target/lun numbers box
+ * reports.
+ */
+ *bus = 1;
+ *target = (lunid >> 16) & 0x3fff;
+ *lun = lunid & 0x00ff;
+ } else {
+ /* Traditional smart array way. */
+ *bus = 0;
+ *lun = 0;
+ *target = lunid & 0x3fff;
+ }
}
} else {
/* physical device */
if (is_hba_lunid(lunaddrbytes))
- *bus = 3;
+ if (unlikely(is_scsi_rev_5(h))) {
+ *bus = 0; /* put p1210m ctlr at 0,0,0 */
+ *target = 0;
+ *lun = 0;
+ return;
+ } else
+ *bus = 3; /* traditional smartarray */
else
- *bus = 2;
+ *bus = 2; /* physical disk */
*target = -1;
*lun = -1; /* we will fill these in later. */
}
@@ -1580,6 +1611,9 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
if (is_hba_lunid(scsi3addr))
return 0; /* Don't add the RAID controller here. */
+ if (is_scsi_rev_5(h))
+ return 0; /* p1210m doesn't need to do this. */
+
#define MAX_MSA2XXX_ENCLOSURES 32
if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
@@ -1643,6 +1677,31 @@ static int hpsa_gather_lun_info(struct ctlr_info *h,
return 0;
}
+u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position, int i,
+ int nphysicals, int nlogicals, struct ReportLUNdata *physdev_list,
+ struct ReportLUNdata *logdev_list)
+{
+ /* Helper function, figure out where the LUN ID info is coming from
+ * given index i, lists of physical and logical devices, where in
+ * the list the raid controller is supposed to appear (first or last)
+ */
+
+ int logicals_start = nphysicals + (raid_ctlr_position == 0);
+ int last_device = nphysicals + nlogicals + (raid_ctlr_position == 0);
+
+ if (i == raid_ctlr_position)
+ return RAID_CTLR_LUNID;
+
+ if (i < logicals_start)
+ return &physdev_list->LUN[i - (raid_ctlr_position == 0)][0];
+
+ if (i < last_device)
+ return &logdev_list->LUN[i - nphysicals -
+ (raid_ctlr_position == 0)][0];
+ BUG();
+ return NULL;
+}
+
static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
{
/* the idea here is we could get notified
@@ -1666,6 +1725,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8;
int i, nmsa2xxx_enclosures, ndevs_to_allocate;
int bus, target, lun;
+ int raid_ctlr_position;
DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
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)
ndev_allocated++;
}
+ if (unlikely(is_scsi_rev_5(h)))
+ raid_ctlr_position = 0;
+ else
+ raid_ctlr_position = nphysicals + nlogicals;
+
/* adjust our table of devices */
nmsa2xxx_enclosures = 0;
for (i = 0; i < nphysicals + nlogicals + 1; i++) {
u8 *lunaddrbytes;
/* Figure out where the LUN ID info is coming from */
- if (i < nphysicals)
- lunaddrbytes = &physdev_list->LUN[i][0];
- else
- if (i < nphysicals + nlogicals)
- lunaddrbytes =
- &logdev_list->LUN[i-nphysicals][0];
- else /* jam in the RAID controller at the end */
- lunaddrbytes = RAID_CTLR_LUNID;
-
+ lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
+ i, nphysicals, nlogicals, physdev_list, logdev_list);
/* skip masked physical devices. */
- if (lunaddrbytes[3] & 0xC0 && i < nphysicals)
+ if (lunaddrbytes[3] & 0xC0 &&
+ i < nphysicals + (raid_ctlr_position == 0))
continue;
/* Get device type, vendor, model, device id */
@@ -3349,6 +3408,22 @@ err_out_free_res:
return err;
}
+static void __devinit hpsa_hba_inquiry(struct ctlr_info *h)
+{
+ int rc;
+
+#define HBA_INQUIRY_BYTE_COUNT 64
+ h->hba_inquiry_data = kmalloc(HBA_INQUIRY_BYTE_COUNT, GFP_KERNEL);
+ if (!h->hba_inquiry_data)
+ return;
+ rc = hpsa_scsi_do_inquiry(h, RAID_CTLR_LUNID, 0,
+ h->hba_inquiry_data, HBA_INQUIRY_BYTE_COUNT);
+ if (rc != 0) {
+ kfree(h->hba_inquiry_data);
+ h->hba_inquiry_data = NULL;
+ }
+}
+
static int __devinit hpsa_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -3458,6 +3533,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
h->access.set_intr_mask(h, HPSA_INTR_ON);
hpsa_put_ctlr_into_performant_mode(h);
+ hpsa_hba_inquiry(h);
hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
h->busy_initializing = 0;
return 1;
@@ -3550,6 +3626,7 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
h->reply_pool, h->reply_pool_dhandle);
kfree(h->cmd_pool_bits);
kfree(h->blockFetchTable);
+ kfree(h->hba_inquiry_data);
/*
* Deliberately omit pci_disable_device(): it does something nasty to
* Smart Array controllers that pci_enable_device does not undo
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 0ba1aa3..1ab0c1b 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -120,6 +120,7 @@ struct ctlr_info {
size_t reply_pool_size;
unsigned char reply_pool_wraparound;
u32 *blockFetchTable;
+ unsigned char *hba_inquiry_data;
};
#define HPSA_ABORT_MSG 0
#define HPSA_DEVICE_RESET_MSG 1
next prev parent reply other threads:[~2010-02-04 14:40 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-04 14:41 [PATCH 00/30] hpsa: Feb 2010 driver updates Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 01/30] hpsa: fix typo in comments Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 02/30] hpsa: Use kernel integer types, not userland ones Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 03/30] hpsa: avoid unwanted promotion from unsigned to signed for raid level index Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 04/30] hpsa: Use BUG_ON instead of an if statement Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 05/30] hpsa: make adjust_hpsa_scsi_table return void Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 06/30] hpsa: remove superfluous returns from void functions Stephen M. Cameron
2010-02-04 14:41 ` [PATCH 07/30] hpsa: return proper error codes not minus one Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 08/30] hpsa: use sizeof() not an inline constant in memset Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 09/30] hpsa: use kzalloc not kmalloc plus memset Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 10/30] hpsa: remove unwanted debug code Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 11/30] hpsa: eliminate unnecessary memcpys Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 12/30] hpsa: make tag macros into functions Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 13/30] hpsa: fix some debug printks to use dev_dbg instead Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 14/30] hpsa: interrupt pending function should return bool not unsigned long Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 15/30] hpsa: Allow multiple command completions per interrupt Stephen M. Cameron
2010-02-04 14:42 ` [PATCH 16/30] hpsa: add pci ids for storageworks 1210m, remove p400, p800, p700m Stephen M. Cameron
2010-02-04 14:42 ` Stephen M. Cameron [this message]
2010-02-04 14:42 ` [PATCH 18/30] hpsa: Return DID_RESET for commands which complete with status of UNSOLICITED ABORT Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 19/30] hpsa: Retry commands completing with a sense key of ABORTED_COMMAND Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 20/30] hpsa: Don't return DID_NO_CONNECT when a device is merely not ready Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 21/30] hpsa: Add an shost_to_hba helper function Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 22/30] hpsa: use scan_start and scan_finished entry points for scanning Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 23/30] hpsa: when resetting devices, print out which device Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 24/30] hpsa: print all the bytes of the CDB, not just the first one Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 25/30] hpsa: clarify obscure comment in adjust_hpsa_scsi_table Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 26/30] hpsa: Fix hpsa_find_scsi_entry so that it doesn't try to dereference NULL pointers Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 27/30] hpsa: fix bug in adjust_hpsa_scsi_table Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 28/30] hpsa: eliminate lock_kernel in compat_ioctl Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 29/30] hpsa: Reorder compat ioctl functions to eliminate some forward declarations Stephen M. Cameron
2010-02-04 14:43 ` [PATCH 30/30] hpsa: `update driver version to 2.0.1-3 Stephen M. Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100204144250.10406.92418.stgit@beardog.cce.hp.com \
--to=scameron@beardog.cce.hp.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=akpm@linux-foundation.org \
--cc=brace@beardog.cce.hp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=matthew.gates@hp.com \
--cc=mikem@beardog.cce.hp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox