|
@@ -1291,13 +1291,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
|
|
|
if (inq_buff == NULL)
|
|
|
goto mem_msg;
|
|
|
|
|
|
+ /* testing to see if 16-byte CDBs are already being used */
|
|
|
+ if (h->cciss_read == CCISS_READ_16) {
|
|
|
+ cciss_read_capacity_16(h->ctlr, drv_index, 1,
|
|
|
+ &total_size, &block_size);
|
|
|
+ goto geo_inq;
|
|
|
+ }
|
|
|
+
|
|
|
cciss_read_capacity(ctlr, drv_index, 1,
|
|
|
&total_size, &block_size);
|
|
|
|
|
|
- /* total size = last LBA + 1 */
|
|
|
- /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */
|
|
|
- /* so we assume this volume this must be >2TB in size */
|
|
|
- if (total_size == (__u32) 0) {
|
|
|
+ /* if read_capacity returns all F's this volume is >2TB in size */
|
|
|
+ /* so we switch to 16-byte CDB's for all read/write ops */
|
|
|
+ if (total_size == 0xFFFFFFFFULL) {
|
|
|
cciss_read_capacity_16(ctlr, drv_index, 1,
|
|
|
&total_size, &block_size);
|
|
|
h->cciss_read = CCISS_READ_16;
|
|
@@ -1306,6 +1312,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
|
|
|
h->cciss_read = CCISS_READ_10;
|
|
|
h->cciss_write = CCISS_WRITE_10;
|
|
|
}
|
|
|
+geo_inq:
|
|
|
cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
|
|
|
inq_buff, &h->drv[drv_index]);
|
|
|
|
|
@@ -1917,13 +1924,14 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
|
|
|
drv->raid_level = inq_buff->data_byte[8];
|
|
|
}
|
|
|
drv->block_size = block_size;
|
|
|
- drv->nr_blocks = total_size;
|
|
|
+ drv->nr_blocks = total_size + 1;
|
|
|
t = drv->heads * drv->sectors;
|
|
|
if (t > 1) {
|
|
|
- unsigned rem = sector_div(total_size, t);
|
|
|
+ sector_t real_size = total_size + 1;
|
|
|
+ unsigned long rem = sector_div(real_size, t);
|
|
|
if (rem)
|
|
|
- total_size++;
|
|
|
- drv->cylinders = total_size;
|
|
|
+ real_size++;
|
|
|
+ drv->cylinders = real_size;
|
|
|
}
|
|
|
} else { /* Get geometry failed */
|
|
|
printk(KERN_WARNING "cciss: reading geometry failed\n");
|
|
@@ -1953,16 +1961,16 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
|
|
|
ctlr, buf, sizeof(ReadCapdata_struct),
|
|
|
1, logvol, 0, NULL, TYPE_CMD);
|
|
|
if (return_code == IO_OK) {
|
|
|
- *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1;
|
|
|
+ *total_size = be32_to_cpu(*(__u32 *) buf->total_size);
|
|
|
*block_size = be32_to_cpu(*(__u32 *) buf->block_size);
|
|
|
} else { /* read capacity command failed */
|
|
|
printk(KERN_WARNING "cciss: read capacity failed\n");
|
|
|
*total_size = 0;
|
|
|
*block_size = BLOCK_SIZE;
|
|
|
}
|
|
|
- if (*total_size != (__u32) 0)
|
|
|
+ if (*total_size != 0)
|
|
|
printk(KERN_INFO " blocks= %llu block_size= %d\n",
|
|
|
- (unsigned long long)*total_size, *block_size);
|
|
|
+ (unsigned long long)*total_size+1, *block_size);
|
|
|
kfree(buf);
|
|
|
return;
|
|
|
}
|
|
@@ -1989,7 +1997,7 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size,
|
|
|
1, logvol, 0, NULL, TYPE_CMD);
|
|
|
}
|
|
|
if (return_code == IO_OK) {
|
|
|
- *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1;
|
|
|
+ *total_size = be64_to_cpu(*(__u64 *) buf->total_size);
|
|
|
*block_size = be32_to_cpu(*(__u32 *) buf->block_size);
|
|
|
} else { /* read capacity command failed */
|
|
|
printk(KERN_WARNING "cciss: read capacity failed\n");
|
|
@@ -1997,7 +2005,7 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size,
|
|
|
*block_size = BLOCK_SIZE;
|
|
|
}
|
|
|
printk(KERN_INFO " blocks= %llu block_size= %d\n",
|
|
|
- (unsigned long long)*total_size, *block_size);
|
|
|
+ (unsigned long long)*total_size+1, *block_size);
|
|
|
kfree(buf);
|
|
|
return;
|
|
|
}
|
|
@@ -3119,8 +3127,9 @@ static void cciss_getgeometry(int cntl_num)
|
|
|
}
|
|
|
cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size);
|
|
|
|
|
|
- /* total_size = last LBA + 1 */
|
|
|
- if(total_size == (__u32) 0) {
|
|
|
+ /* If read_capacity returns all F's the logical is >2TB */
|
|
|
+ /* so we switch to 16-byte CDBs for all read/write ops */
|
|
|
+ if(total_size == 0xFFFFFFFFULL) {
|
|
|
cciss_read_capacity_16(cntl_num, i, 0,
|
|
|
&total_size, &block_size);
|
|
|
hba[cntl_num]->cciss_read = CCISS_READ_16;
|