Commit 39ccf9a6 authored by Stephen M. Cameron's avatar Stephen M. Cameron Committed by Jens Axboe

cciss: Preserve all 8 bytes of LUN ID for logical drives.

Preserve all 8 bytes of the LunID field returned
by CCISS_REPORT_LOGICAL instead of only saving 4 bytes.
This fixes a bug with logical volume addressing encountered on
an MSA2012.
Signed-off-by: default avatarStephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 983333cb
...@@ -846,7 +846,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) ...@@ -846,7 +846,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
if (MINOR(bdev->bd_dev) & 0x0f) { if (MINOR(bdev->bd_dev) & 0x0f) {
return -ENXIO; return -ENXIO;
/* if it is, make sure we have a LUN ID */ /* if it is, make sure we have a LUN ID */
} else if (drv->LunID == 0) { } else if (memcmp(drv->LunID, CTLR_LUNID,
sizeof(drv->LunID))) {
return -ENXIO; return -ENXIO;
} }
} }
...@@ -1216,7 +1217,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1216,7 +1217,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
case CCISS_GETLUNINFO:{ case CCISS_GETLUNINFO:{
LogvolInfo_struct luninfo; LogvolInfo_struct luninfo;
luninfo.LunID = drv->LunID; memcpy(&luninfo.LunID, drv->LunID,
sizeof(luninfo.LunID));
luninfo.num_opens = drv->usage_count; luninfo.num_opens = drv->usage_count;
luninfo.num_parts = 0; luninfo.num_parts = 0;
if (copy_to_user(argp, &luninfo, if (copy_to_user(argp, &luninfo,
...@@ -1611,13 +1613,11 @@ static void cciss_softirq_done(struct request *rq) ...@@ -1611,13 +1613,11 @@ static void cciss_softirq_done(struct request *rq)
spin_unlock_irqrestore(&h->lock, flags); spin_unlock_irqrestore(&h->lock, flags);
} }
static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[], static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
uint32_t log_unit) unsigned char scsi3addr[], uint32_t log_unit)
{ {
log_unit = h->drv[log_unit].LunID & 0x03fff; memcpy(scsi3addr, h->drv[log_unit].LunID,
memset(&scsi3addr[4], 0, 4); sizeof(h->drv[log_unit].LunID));
memcpy(&scsi3addr[0], &log_unit, 4);
scsi3addr[3] |= 0x40;
} }
/* This function gets the SCSI vendor, model, and revision of a logical drive /* This function gets the SCSI vendor, model, and revision of a logical drive
...@@ -1924,7 +1924,8 @@ static void cciss_free_gendisk(ctlr_info_t *h, int drv_index) ...@@ -1924,7 +1924,8 @@ static void cciss_free_gendisk(ctlr_info_t *h, int drv_index)
* a means to talk to the controller in case no logical * a means to talk to the controller in case no logical
* drives have yet been configured. * drives have yet been configured.
*/ */
static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[],
int controller_node)
{ {
int drv_index; int drv_index;
...@@ -1943,7 +1944,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) ...@@ -1943,7 +1944,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
return -1; return -1;
} }
} }
h->drv[drv_index].LunID = lunid; memcpy(h->drv[drv_index].LunID, lunid,
sizeof(h->drv[drv_index].LunID));
if (h->drv[drv_index].dev == NULL) { if (h->drv[drv_index].dev == NULL) {
if (cciss_create_ld_sysfs_entry(h, drv_index)) if (cciss_create_ld_sysfs_entry(h, drv_index))
goto err_free_disk; goto err_free_disk;
...@@ -1973,7 +1975,7 @@ static void cciss_add_controller_node(ctlr_info_t *h) ...@@ -1973,7 +1975,7 @@ static void cciss_add_controller_node(ctlr_info_t *h)
if (h->gendisk[0] != NULL) /* already did this? Then bail. */ if (h->gendisk[0] != NULL) /* already did this? Then bail. */
return; return;
drv_index = cciss_add_gendisk(h, 0, 1); drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1);
if (drv_index == -1) if (drv_index == -1)
goto error; goto error;
h->drv[drv_index].block_size = 512; h->drv[drv_index].block_size = 512;
...@@ -2012,7 +2014,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, ...@@ -2012,7 +2014,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
int i; int i;
int drv_found; int drv_found;
int drv_index = 0; int drv_index = 0;
__u32 lunid = 0; unsigned char lunid[8] = CTLR_LUNID;
unsigned long flags; unsigned long flags;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
...@@ -2069,9 +2071,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, ...@@ -2069,9 +2071,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
continue; continue;
for (j = 0; j < num_luns; j++) { for (j = 0; j < num_luns; j++) {
memcpy(&lunid, &ld_buff->LUN[j][0], 4); memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid));
lunid = le32_to_cpu(lunid); if (memcmp(h->drv[i].LunID, lunid,
if (h->drv[i].LunID == lunid) { sizeof(lunid)) == 0) {
drv_found = 1; drv_found = 1;
break; break;
} }
...@@ -2096,9 +2098,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, ...@@ -2096,9 +2098,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
drv_found = 0; drv_found = 0;
memcpy(&lunid, &ld_buff->LUN[i][0], 4); memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid));
lunid = le32_to_cpu(lunid);
/* Find if the LUN is already in the drive array /* Find if the LUN is already in the drive array
* of the driver. If so then update its info * of the driver. If so then update its info
* if not in use. If it does not exist then find * if not in use. If it does not exist then find
...@@ -2106,7 +2106,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, ...@@ -2106,7 +2106,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time,
*/ */
for (j = 0; j <= h->highest_lun; j++) { for (j = 0; j <= h->highest_lun; j++) {
if (h->drv[j].raid_level != -1 && if (h->drv[j].raid_level != -1 &&
h->drv[j].LunID == lunid) { memcmp(h->drv[j].LunID, lunid,
sizeof(h->drv[j].LunID)) == 0) {
drv_index = j; drv_index = j;
drv_found = 1; drv_found = 1;
break; break;
...@@ -2254,8 +2255,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, ...@@ -2254,8 +2255,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
} }
h->highest_lun = newhighest; h->highest_lun = newhighest;
} }
memset(drv->LunID, 0, sizeof(drv->LunID));
drv->LunID = 0;
} }
return 0; return 0;
} }
...@@ -2686,7 +2686,8 @@ static int cciss_revalidate(struct gendisk *disk) ...@@ -2686,7 +2686,8 @@ static int cciss_revalidate(struct gendisk *disk)
InquiryData_struct *inq_buff = NULL; InquiryData_struct *inq_buff = NULL;
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
if (h->drv[logvol].LunID == drv->LunID) { if (memcmp(h->drv[logvol].LunID, drv->LunID,
sizeof(drv->LunID)) == 0) {
FOUND = 1; FOUND = 1;
break; break;
} }
...@@ -3171,8 +3172,7 @@ static void do_cciss_request(struct request_queue *q) ...@@ -3171,8 +3172,7 @@ static void do_cciss_request(struct request_queue *q)
/* The first 2 bits are reserved for controller error reporting. */ /* The first 2 bits are reserved for controller error reporting. */
c->Header.Tag.lower = (c->cmdindex << 3); c->Header.Tag.lower = (c->cmdindex << 3);
c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
c->Header.LUN.LogDev.VolId = drv->LunID; memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
c->Header.LUN.LogDev.Mode = 1;
c->Request.CDBLen = 10; // 12 byte commands not in FW yet; c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
c->Request.Type.Type = TYPE_CMD; // It is a command. c->Request.Type.Type = TYPE_CMD; // It is a command.
c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Attribute = ATTR_SIMPLE;
......
...@@ -30,7 +30,7 @@ struct access_method { ...@@ -30,7 +30,7 @@ struct access_method {
}; };
typedef struct _drive_info_struct typedef struct _drive_info_struct
{ {
__u32 LunID; unsigned char LunID[8];
int usage_count; int usage_count;
struct request_queue *queue; struct request_queue *queue;
sector_t nr_blocks; sector_t nr_blocks;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment