diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2009-09-17 14:48:00 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-10-01 15:15:43 -0400 |
commit | 39ccf9a645dbca7f9866317380912327570787c0 (patch) | |
tree | 6b6a8217c4e2997694738b91b410fe37573688a9 | |
parent | 983333cb0c445c56808502461bbb34876c63eb2b (diff) |
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: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | drivers/block/cciss.c | 48 | ||||
-rw-r--r-- | drivers/block/cciss.h | 2 |
2 files changed, 25 insertions, 25 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 67c4899ce9ea..d6ea93767970 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -846,7 +846,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) | |||
846 | if (MINOR(bdev->bd_dev) & 0x0f) { | 846 | if (MINOR(bdev->bd_dev) & 0x0f) { |
847 | return -ENXIO; | 847 | return -ENXIO; |
848 | /* if it is, make sure we have a LUN ID */ | 848 | /* if it is, make sure we have a LUN ID */ |
849 | } else if (drv->LunID == 0) { | 849 | } else if (memcmp(drv->LunID, CTLR_LUNID, |
850 | sizeof(drv->LunID))) { | ||
850 | return -ENXIO; | 851 | return -ENXIO; |
851 | } | 852 | } |
852 | } | 853 | } |
@@ -1216,7 +1217,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1216 | case CCISS_GETLUNINFO:{ | 1217 | case CCISS_GETLUNINFO:{ |
1217 | LogvolInfo_struct luninfo; | 1218 | LogvolInfo_struct luninfo; |
1218 | 1219 | ||
1219 | luninfo.LunID = drv->LunID; | 1220 | memcpy(&luninfo.LunID, drv->LunID, |
1221 | sizeof(luninfo.LunID)); | ||
1220 | luninfo.num_opens = drv->usage_count; | 1222 | luninfo.num_opens = drv->usage_count; |
1221 | luninfo.num_parts = 0; | 1223 | luninfo.num_parts = 0; |
1222 | if (copy_to_user(argp, &luninfo, | 1224 | if (copy_to_user(argp, &luninfo, |
@@ -1611,13 +1613,11 @@ static void cciss_softirq_done(struct request *rq) | |||
1611 | spin_unlock_irqrestore(&h->lock, flags); | 1613 | spin_unlock_irqrestore(&h->lock, flags); |
1612 | } | 1614 | } |
1613 | 1615 | ||
1614 | static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[], | 1616 | static inline void log_unit_to_scsi3addr(ctlr_info_t *h, |
1615 | uint32_t log_unit) | 1617 | unsigned char scsi3addr[], uint32_t log_unit) |
1616 | { | 1618 | { |
1617 | log_unit = h->drv[log_unit].LunID & 0x03fff; | 1619 | memcpy(scsi3addr, h->drv[log_unit].LunID, |
1618 | memset(&scsi3addr[4], 0, 4); | 1620 | sizeof(h->drv[log_unit].LunID)); |
1619 | memcpy(&scsi3addr[0], &log_unit, 4); | ||
1620 | scsi3addr[3] |= 0x40; | ||
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | /* This function gets the SCSI vendor, model, and revision of a logical drive | 1623 | /* 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 | * a means to talk to the controller in case no logical | 1924 | * a means to talk to the controller in case no logical |
1925 | * drives have yet been configured. | 1925 | * drives have yet been configured. |
1926 | */ | 1926 | */ |
1927 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | 1927 | static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], |
1928 | int controller_node) | ||
1928 | { | 1929 | { |
1929 | int drv_index; | 1930 | int drv_index; |
1930 | 1931 | ||
@@ -1943,7 +1944,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | |||
1943 | return -1; | 1944 | return -1; |
1944 | } | 1945 | } |
1945 | } | 1946 | } |
1946 | h->drv[drv_index].LunID = lunid; | 1947 | memcpy(h->drv[drv_index].LunID, lunid, |
1948 | sizeof(h->drv[drv_index].LunID)); | ||
1947 | if (h->drv[drv_index].dev == NULL) { | 1949 | if (h->drv[drv_index].dev == NULL) { |
1948 | if (cciss_create_ld_sysfs_entry(h, drv_index)) | 1950 | if (cciss_create_ld_sysfs_entry(h, drv_index)) |
1949 | goto err_free_disk; | 1951 | goto err_free_disk; |
@@ -1973,7 +1975,7 @@ static void cciss_add_controller_node(ctlr_info_t *h) | |||
1973 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | 1975 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ |
1974 | return; | 1976 | return; |
1975 | 1977 | ||
1976 | drv_index = cciss_add_gendisk(h, 0, 1); | 1978 | drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1); |
1977 | if (drv_index == -1) | 1979 | if (drv_index == -1) |
1978 | goto error; | 1980 | goto error; |
1979 | h->drv[drv_index].block_size = 512; | 1981 | h->drv[drv_index].block_size = 512; |
@@ -2012,7 +2014,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2012 | int i; | 2014 | int i; |
2013 | int drv_found; | 2015 | int drv_found; |
2014 | int drv_index = 0; | 2016 | int drv_index = 0; |
2015 | __u32 lunid = 0; | 2017 | unsigned char lunid[8] = CTLR_LUNID; |
2016 | unsigned long flags; | 2018 | unsigned long flags; |
2017 | 2019 | ||
2018 | if (!capable(CAP_SYS_RAWIO)) | 2020 | if (!capable(CAP_SYS_RAWIO)) |
@@ -2069,9 +2071,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2069 | continue; | 2071 | continue; |
2070 | 2072 | ||
2071 | for (j = 0; j < num_luns; j++) { | 2073 | for (j = 0; j < num_luns; j++) { |
2072 | memcpy(&lunid, &ld_buff->LUN[j][0], 4); | 2074 | memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid)); |
2073 | lunid = le32_to_cpu(lunid); | 2075 | if (memcmp(h->drv[i].LunID, lunid, |
2074 | if (h->drv[i].LunID == lunid) { | 2076 | sizeof(lunid)) == 0) { |
2075 | drv_found = 1; | 2077 | drv_found = 1; |
2076 | break; | 2078 | break; |
2077 | } | 2079 | } |
@@ -2096,9 +2098,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2096 | 2098 | ||
2097 | drv_found = 0; | 2099 | drv_found = 0; |
2098 | 2100 | ||
2099 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); | 2101 | memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid)); |
2100 | lunid = le32_to_cpu(lunid); | ||
2101 | |||
2102 | /* Find if the LUN is already in the drive array | 2102 | /* Find if the LUN is already in the drive array |
2103 | * of the driver. If so then update its info | 2103 | * of the driver. If so then update its info |
2104 | * if not in use. If it does not exist then find | 2104 | * 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 | */ | 2106 | */ |
2107 | for (j = 0; j <= h->highest_lun; j++) { | 2107 | for (j = 0; j <= h->highest_lun; j++) { |
2108 | if (h->drv[j].raid_level != -1 && | 2108 | if (h->drv[j].raid_level != -1 && |
2109 | h->drv[j].LunID == lunid) { | 2109 | memcmp(h->drv[j].LunID, lunid, |
2110 | sizeof(h->drv[j].LunID)) == 0) { | ||
2110 | drv_index = j; | 2111 | drv_index = j; |
2111 | drv_found = 1; | 2112 | drv_found = 1; |
2112 | break; | 2113 | break; |
@@ -2254,8 +2255,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, | |||
2254 | } | 2255 | } |
2255 | h->highest_lun = newhighest; | 2256 | h->highest_lun = newhighest; |
2256 | } | 2257 | } |
2257 | 2258 | memset(drv->LunID, 0, sizeof(drv->LunID)); | |
2258 | drv->LunID = 0; | ||
2259 | } | 2259 | } |
2260 | return 0; | 2260 | return 0; |
2261 | } | 2261 | } |
@@ -2686,7 +2686,8 @@ static int cciss_revalidate(struct gendisk *disk) | |||
2686 | InquiryData_struct *inq_buff = NULL; | 2686 | InquiryData_struct *inq_buff = NULL; |
2687 | 2687 | ||
2688 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2688 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { |
2689 | if (h->drv[logvol].LunID == drv->LunID) { | 2689 | if (memcmp(h->drv[logvol].LunID, drv->LunID, |
2690 | sizeof(drv->LunID)) == 0) { | ||
2690 | FOUND = 1; | 2691 | FOUND = 1; |
2691 | break; | 2692 | break; |
2692 | } | 2693 | } |
@@ -3171,8 +3172,7 @@ static void do_cciss_request(struct request_queue *q) | |||
3171 | /* The first 2 bits are reserved for controller error reporting. */ | 3172 | /* The first 2 bits are reserved for controller error reporting. */ |
3172 | c->Header.Tag.lower = (c->cmdindex << 3); | 3173 | c->Header.Tag.lower = (c->cmdindex << 3); |
3173 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ | 3174 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ |
3174 | c->Header.LUN.LogDev.VolId = drv->LunID; | 3175 | memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); |
3175 | c->Header.LUN.LogDev.Mode = 1; | ||
3176 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; | 3176 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; |
3177 | c->Request.Type.Type = TYPE_CMD; // It is a command. | 3177 | c->Request.Type.Type = TYPE_CMD; // It is a command. |
3178 | c->Request.Type.Attribute = ATTR_SIMPLE; | 3178 | c->Request.Type.Attribute = ATTR_SIMPLE; |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 96793425688e..5188f713d1b0 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -30,7 +30,7 @@ struct access_method { | |||
30 | }; | 30 | }; |
31 | typedef struct _drive_info_struct | 31 | typedef struct _drive_info_struct |
32 | { | 32 | { |
33 | __u32 LunID; | 33 | unsigned char LunID[8]; |
34 | int usage_count; | 34 | int usage_count; |
35 | struct request_queue *queue; | 35 | struct request_queue *queue; |
36 | sector_t nr_blocks; | 36 | sector_t nr_blocks; |