aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorMike Miller (OS Dev) <mikem@beardog.cca.cpqcorp.net>2006-10-01 02:27:23 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:20 -0400
commit00988a3514bbc0cce781c067cf52559741d88b80 (patch)
treee0a844ecd9351c67dd9e73e8e6aafd064fa43137 /drivers/block
parent82b0547cfae1fb2ee26cad588f6d49a347d24740 (diff)
[PATCH] cciss: support for >2TB logical volumes
Add support for logical volumes >2TB. All SAS/SATA controllers support large volumes. Signed-off-by: Mike Miller <mike.miller@hp.com> Cc: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/cciss.c229
-rw-r--r--drivers/block/cciss.h3
-rw-r--r--drivers/block/cciss_cmd.h33
3 files changed, 192 insertions, 73 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index c211065ad829..e707f39e990c 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -144,13 +144,13 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
144static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, 144static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
145 int clear_all); 145 int clear_all);
146 146
147static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, 147static void cciss_read_capacity(int ctlr, int logvol, int withirq,
148 int withirq, unsigned int *total_size, 148 sector_t *total_size, unsigned int *block_size);
149 unsigned int *block_size); 149static void cciss_read_capacity_16(int ctlr, int logvol, int withirq,
150static void cciss_geometry_inquiry(int ctlr, int logvol, int withirq, 150 sector_t *total_size, unsigned int *block_size);
151 unsigned int total_size, 151static void cciss_geometry_inquiry(int ctlr, int logvol,
152 unsigned int block_size, 152 int withirq, sector_t total_size,
153 InquiryData_struct *inq_buff, 153 unsigned int block_size, InquiryData_struct *inq_buff,
154 drive_info_struct *drv); 154 drive_info_struct *drv);
155static void cciss_getgeometry(int cntl_num); 155static void cciss_getgeometry(int cntl_num);
156static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, 156static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *,
@@ -1325,10 +1325,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
1325{ 1325{
1326 ctlr_info_t *h = hba[ctlr]; 1326 ctlr_info_t *h = hba[ctlr];
1327 struct gendisk *disk; 1327 struct gendisk *disk;
1328 ReadCapdata_struct *size_buff = NULL;
1329 InquiryData_struct *inq_buff = NULL; 1328 InquiryData_struct *inq_buff = NULL;
1330 unsigned int block_size; 1329 unsigned int block_size;
1331 unsigned int total_size; 1330 sector_t total_size;
1332 unsigned long flags = 0; 1331 unsigned long flags = 0;
1333 int ret = 0; 1332 int ret = 0;
1334 1333
@@ -1347,15 +1346,25 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
1347 return; 1346 return;
1348 1347
1349 /* Get information about the disk and modify the driver structure */ 1348 /* Get information about the disk and modify the driver structure */
1350 size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
1351 if (size_buff == NULL)
1352 goto mem_msg;
1353 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); 1349 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
1354 if (inq_buff == NULL) 1350 if (inq_buff == NULL)
1355 goto mem_msg; 1351 goto mem_msg;
1356 1352
1357 cciss_read_capacity(ctlr, drv_index, size_buff, 1, 1353 cciss_read_capacity(ctlr, drv_index, 1,
1358 &total_size, &block_size); 1354 &total_size, &block_size);
1355
1356 /* total size = last LBA + 1 */
1357 /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */
1358 /* so we assume this volume this must be >2TB in size */
1359 if (total_size == (__u32) 0) {
1360 cciss_read_capacity_16(ctlr, drv_index, 1,
1361 &total_size, &block_size);
1362 h->cciss_read = CCISS_READ_16;
1363 h->cciss_write = CCISS_WRITE_16;
1364 } else {
1365 h->cciss_read = CCISS_READ_10;
1366 h->cciss_write = CCISS_WRITE_10;
1367 }
1359 cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, 1368 cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
1360 inq_buff, &h->drv[drv_index]); 1369 inq_buff, &h->drv[drv_index]);
1361 1370
@@ -1391,7 +1400,6 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
1391 } 1400 }
1392 1401
1393 freeret: 1402 freeret:
1394 kfree(size_buff);
1395 kfree(inq_buff); 1403 kfree(inq_buff);
1396 return; 1404 return;
1397 mem_msg: 1405 mem_msg:
@@ -1716,6 +1724,22 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
1716 c->Request.Timeout = 0; 1724 c->Request.Timeout = 0;
1717 c->Request.CDB[0] = cmd; 1725 c->Request.CDB[0] = cmd;
1718 break; 1726 break;
1727 case CCISS_READ_CAPACITY_16:
1728 c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID;
1729 c->Header.LUN.LogDev.Mode = 1;
1730 c->Request.CDBLen = 16;
1731 c->Request.Type.Attribute = ATTR_SIMPLE;
1732 c->Request.Type.Direction = XFER_READ;
1733 c->Request.Timeout = 0;
1734 c->Request.CDB[0] = cmd;
1735 c->Request.CDB[1] = 0x10;
1736 c->Request.CDB[10] = (size >> 24) & 0xFF;
1737 c->Request.CDB[11] = (size >> 16) & 0xFF;
1738 c->Request.CDB[12] = (size >> 8) & 0xFF;
1739 c->Request.CDB[13] = size & 0xFF;
1740 c->Request.Timeout = 0;
1741 c->Request.CDB[0] = cmd;
1742 break;
1719 case CCISS_CACHE_FLUSH: 1743 case CCISS_CACHE_FLUSH:
1720 c->Request.CDBLen = 12; 1744 c->Request.CDBLen = 12;
1721 c->Request.Type.Attribute = ATTR_SIMPLE; 1745 c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -1749,6 +1773,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
1749 memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); 1773 memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
1750 c->Request.CDB[0] = cmd; /* reset */ 1774 c->Request.CDB[0] = cmd; /* reset */
1751 c->Request.CDB[1] = 0x04; /* reset a LUN */ 1775 c->Request.CDB[1] = 0x04; /* reset a LUN */
1776 break;
1752 case 3: /* No-Op message */ 1777 case 3: /* No-Op message */
1753 c->Request.CDBLen = 1; 1778 c->Request.CDBLen = 1;
1754 c->Request.Type.Attribute = ATTR_SIMPLE; 1779 c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -1892,12 +1917,15 @@ static int sendcmd_withirq(__u8 cmd,
1892} 1917}
1893 1918
1894static void cciss_geometry_inquiry(int ctlr, int logvol, 1919static void cciss_geometry_inquiry(int ctlr, int logvol,
1895 int withirq, unsigned int total_size, 1920 int withirq, sector_t total_size,
1896 unsigned int block_size, 1921 unsigned int block_size,
1897 InquiryData_struct *inq_buff, 1922 InquiryData_struct *inq_buff,
1898 drive_info_struct *drv) 1923 drive_info_struct *drv)
1899{ 1924{
1900 int return_code; 1925 int return_code;
1926 unsigned long t;
1927 unsigned long rem;
1928
1901 memset(inq_buff, 0, sizeof(InquiryData_struct)); 1929 memset(inq_buff, 0, sizeof(InquiryData_struct));
1902 if (withirq) 1930 if (withirq)
1903 return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, 1931 return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
@@ -1916,10 +1944,10 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
1916 drv->nr_blocks = total_size; 1944 drv->nr_blocks = total_size;
1917 drv->heads = 255; 1945 drv->heads = 255;
1918 drv->sectors = 32; // Sectors per track 1946 drv->sectors = 32; // Sectors per track
1919 drv->cylinders = total_size / 255 / 32; 1947 t = drv->heads * drv->sectors;
1948 drv->cylinders = total_size;
1949 rem = do_div(drv->cylinders, t);
1920 } else { 1950 } else {
1921 unsigned int t;
1922
1923 drv->block_size = block_size; 1951 drv->block_size = block_size;
1924 drv->nr_blocks = total_size; 1952 drv->nr_blocks = total_size;
1925 drv->heads = inq_buff->data_byte[6]; 1953 drv->heads = inq_buff->data_byte[6];
@@ -1929,7 +1957,8 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
1929 drv->raid_level = inq_buff->data_byte[8]; 1957 drv->raid_level = inq_buff->data_byte[8];
1930 t = drv->heads * drv->sectors; 1958 t = drv->heads * drv->sectors;
1931 if (t > 1) { 1959 if (t > 1) {
1932 drv->cylinders = total_size / t; 1960 drv->cylinders = total_size;
1961 rem = do_div(drv->cylinders, t);
1933 } 1962 }
1934 } 1963 }
1935 } else { /* Get geometry failed */ 1964 } else { /* Get geometry failed */
@@ -1940,31 +1969,72 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
1940} 1969}
1941 1970
1942static void 1971static void
1943cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, 1972cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
1944 int withirq, unsigned int *total_size,
1945 unsigned int *block_size) 1973 unsigned int *block_size)
1946{ 1974{
1975 ReadCapdata_struct *buf;
1947 int return_code; 1976 int return_code;
1948 memset(buf, 0, sizeof(*buf)); 1977 buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
1978 if (buf == NULL) {
1979 printk(KERN_WARNING "cciss: out of memory\n");
1980 return;
1981 }
1982 memset(buf, 0, sizeof(ReadCapdata_struct));
1949 if (withirq) 1983 if (withirq)
1950 return_code = sendcmd_withirq(CCISS_READ_CAPACITY, 1984 return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
1951 ctlr, buf, sizeof(*buf), 1, 1985 ctlr, buf, sizeof(ReadCapdata_struct),
1952 logvol, 0, TYPE_CMD); 1986 1, logvol, 0, TYPE_CMD);
1953 else 1987 else
1954 return_code = sendcmd(CCISS_READ_CAPACITY, 1988 return_code = sendcmd(CCISS_READ_CAPACITY,
1955 ctlr, buf, sizeof(*buf), 1, logvol, 0, 1989 ctlr, buf, sizeof(ReadCapdata_struct),
1956 NULL, TYPE_CMD); 1990 1, logvol, 0, NULL, TYPE_CMD);
1957 if (return_code == IO_OK) { 1991 if (return_code == IO_OK) {
1958 *total_size = 1992 *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1;
1959 be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1; 1993 *block_size = be32_to_cpu(*(__u32 *) buf->block_size);
1960 *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0]));
1961 } else { /* read capacity command failed */ 1994 } else { /* read capacity command failed */
1962 printk(KERN_WARNING "cciss: read capacity failed\n"); 1995 printk(KERN_WARNING "cciss: read capacity failed\n");
1963 *total_size = 0; 1996 *total_size = 0;
1964 *block_size = BLOCK_SIZE; 1997 *block_size = BLOCK_SIZE;
1965 } 1998 }
1966 printk(KERN_INFO " blocks= %u block_size= %d\n", 1999 if (*total_size != (__u32) 0)
2000 printk(KERN_INFO " blocks= %lld block_size= %d\n",
2001 *total_size, *block_size);
2002 kfree(buf);
2003 return;
2004}
2005
2006static void
2007cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size)
2008{
2009 ReadCapdata_struct_16 *buf;
2010 int return_code;
2011 buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL);
2012 if (buf == NULL) {
2013 printk(KERN_WARNING "cciss: out of memory\n");
2014 return;
2015 }
2016 memset(buf, 0, sizeof(ReadCapdata_struct_16));
2017 if (withirq) {
2018 return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
2019 ctlr, buf, sizeof(ReadCapdata_struct_16),
2020 1, logvol, 0, TYPE_CMD);
2021 }
2022 else {
2023 return_code = sendcmd(CCISS_READ_CAPACITY_16,
2024 ctlr, buf, sizeof(ReadCapdata_struct_16),
2025 1, logvol, 0, NULL, TYPE_CMD);
2026 }
2027 if (return_code == IO_OK) {
2028 *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1;
2029 *block_size = be32_to_cpu(*(__u32 *) buf->block_size);
2030 } else { /* read capacity command failed */
2031 printk(KERN_WARNING "cciss: read capacity failed\n");
2032 *total_size = 0;
2033 *block_size = BLOCK_SIZE;
2034 }
2035 printk(KERN_INFO " blocks= %lld block_size= %d\n",
1967 *total_size, *block_size); 2036 *total_size, *block_size);
2037 kfree(buf);
1968 return; 2038 return;
1969} 2039}
1970 2040
@@ -1975,8 +2045,7 @@ static int cciss_revalidate(struct gendisk *disk)
1975 int logvol; 2045 int logvol;
1976 int FOUND = 0; 2046 int FOUND = 0;
1977 unsigned int block_size; 2047 unsigned int block_size;
1978 unsigned int total_size; 2048 sector_t total_size;
1979 ReadCapdata_struct *size_buff = NULL;
1980 InquiryData_struct *inq_buff = NULL; 2049 InquiryData_struct *inq_buff = NULL;
1981 2050
1982 for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { 2051 for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
@@ -1989,27 +2058,24 @@ static int cciss_revalidate(struct gendisk *disk)
1989 if (!FOUND) 2058 if (!FOUND)
1990 return 1; 2059 return 1;
1991 2060
1992 size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
1993 if (size_buff == NULL) {
1994 printk(KERN_WARNING "cciss: out of memory\n");
1995 return 1;
1996 }
1997 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); 2061 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
1998 if (inq_buff == NULL) { 2062 if (inq_buff == NULL) {
1999 printk(KERN_WARNING "cciss: out of memory\n"); 2063 printk(KERN_WARNING "cciss: out of memory\n");
2000 kfree(size_buff);
2001 return 1; 2064 return 1;
2002 } 2065 }
2003 2066 if (h->cciss_read == CCISS_READ_10) {
2004 cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, 2067 cciss_read_capacity(h->ctlr, logvol, 1,
2005 &block_size); 2068 &total_size, &block_size);
2069 } else {
2070 cciss_read_capacity_16(h->ctlr, logvol, 1,
2071 &total_size, &block_size);
2072 }
2006 cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, 2073 cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size,
2007 inq_buff, drv); 2074 inq_buff, drv);
2008 2075
2009 blk_queue_hardsect_size(drv->queue, drv->block_size); 2076 blk_queue_hardsect_size(drv->queue, drv->block_size);
2010 set_capacity(disk, drv->nr_blocks); 2077 set_capacity(disk, drv->nr_blocks);
2011 2078
2012 kfree(size_buff);
2013 kfree(inq_buff); 2079 kfree(inq_buff);
2014 return 0; 2080 return 0;
2015} 2081}
@@ -2418,7 +2484,8 @@ static void do_cciss_request(request_queue_t *q)
2418{ 2484{
2419 ctlr_info_t *h = q->queuedata; 2485 ctlr_info_t *h = q->queuedata;
2420 CommandList_struct *c; 2486 CommandList_struct *c;
2421 int start_blk, seg; 2487 sector_t start_blk;
2488 int seg;
2422 struct request *creq; 2489 struct request *creq;
2423 u64bit temp64; 2490 u64bit temp64;
2424 struct scatterlist tmp_sg[MAXSGENTRIES]; 2491 struct scatterlist tmp_sg[MAXSGENTRIES];
@@ -2462,10 +2529,10 @@ static void do_cciss_request(request_queue_t *q)
2462 c->Request.Type.Type = TYPE_CMD; // It is a command. 2529 c->Request.Type.Type = TYPE_CMD; // It is a command.
2463 c->Request.Type.Attribute = ATTR_SIMPLE; 2530 c->Request.Type.Attribute = ATTR_SIMPLE;
2464 c->Request.Type.Direction = 2531 c->Request.Type.Direction =
2465 (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; 2532 (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
2466 c->Request.Timeout = 0; // Don't time out 2533 c->Request.Timeout = 0; // Don't time out
2467 c->Request.CDB[0] = 2534 c->Request.CDB[0] =
2468 (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; 2535 (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
2469 start_blk = creq->sector; 2536 start_blk = creq->sector;
2470#ifdef CCISS_DEBUG 2537#ifdef CCISS_DEBUG
2471 printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector, 2538 printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector,
@@ -2499,15 +2566,33 @@ static void do_cciss_request(request_queue_t *q)
2499#endif /* CCISS_DEBUG */ 2566#endif /* CCISS_DEBUG */
2500 2567
2501 c->Header.SGList = c->Header.SGTotal = seg; 2568 c->Header.SGList = c->Header.SGTotal = seg;
2502 c->Request.CDB[1] = 0; 2569 if(h->cciss_read == CCISS_READ_10) {
2503 c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB 2570 c->Request.CDB[1] = 0;
2504 c->Request.CDB[3] = (start_blk >> 16) & 0xff; 2571 c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
2505 c->Request.CDB[4] = (start_blk >> 8) & 0xff; 2572 c->Request.CDB[3] = (start_blk >> 16) & 0xff;
2506 c->Request.CDB[5] = start_blk & 0xff; 2573 c->Request.CDB[4] = (start_blk >> 8) & 0xff;
2507 c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB 2574 c->Request.CDB[5] = start_blk & 0xff;
2508 c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; 2575 c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
2509 c->Request.CDB[8] = creq->nr_sectors & 0xff; 2576 c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
2510 c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; 2577 c->Request.CDB[8] = creq->nr_sectors & 0xff;
2578 c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
2579 } else {
2580 c->Request.CDBLen = 16;
2581 c->Request.CDB[1]= 0;
2582 c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
2583 c->Request.CDB[3]= (start_blk >> 48) & 0xff;
2584 c->Request.CDB[4]= (start_blk >> 40) & 0xff;
2585 c->Request.CDB[5]= (start_blk >> 32) & 0xff;
2586 c->Request.CDB[6]= (start_blk >> 24) & 0xff;
2587 c->Request.CDB[7]= (start_blk >> 16) & 0xff;
2588 c->Request.CDB[8]= (start_blk >> 8) & 0xff;
2589 c->Request.CDB[9]= start_blk & 0xff;
2590 c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
2591 c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
2592 c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
2593 c->Request.CDB[13]= creq->nr_sectors & 0xff;
2594 c->Request.CDB[14] = c->Request.CDB[15] = 0;
2595 }
2511 2596
2512 spin_lock_irq(q->queue_lock); 2597 spin_lock_irq(q->queue_lock);
2513 2598
@@ -2517,9 +2602,9 @@ static void do_cciss_request(request_queue_t *q)
2517 h->maxQsinceinit = h->Qdepth; 2602 h->maxQsinceinit = h->Qdepth;
2518 2603
2519 goto queue; 2604 goto queue;
2520 full: 2605full:
2521 blk_stop_queue(q); 2606 blk_stop_queue(q);
2522 startio: 2607startio:
2523 /* We will already have the driver lock here so not need 2608 /* We will already have the driver lock here so not need
2524 * to lock it. 2609 * to lock it.
2525 */ 2610 */
@@ -2947,31 +3032,23 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
2947static void cciss_getgeometry(int cntl_num) 3032static void cciss_getgeometry(int cntl_num)
2948{ 3033{
2949 ReportLunData_struct *ld_buff; 3034 ReportLunData_struct *ld_buff;
2950 ReadCapdata_struct *size_buff;
2951 InquiryData_struct *inq_buff; 3035 InquiryData_struct *inq_buff;
2952 int return_code; 3036 int return_code;
2953 int i; 3037 int i;
2954 int listlength = 0; 3038 int listlength = 0;
2955 __u32 lunid = 0; 3039 __u32 lunid = 0;
2956 int block_size; 3040 int block_size;
2957 int total_size; 3041 sector_t total_size;
2958 3042
2959 ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); 3043 ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
2960 if (ld_buff == NULL) { 3044 if (ld_buff == NULL) {
2961 printk(KERN_ERR "cciss: out of memory\n"); 3045 printk(KERN_ERR "cciss: out of memory\n");
2962 return; 3046 return;
2963 } 3047 }
2964 size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
2965 if (size_buff == NULL) {
2966 printk(KERN_ERR "cciss: out of memory\n");
2967 kfree(ld_buff);
2968 return;
2969 }
2970 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); 3048 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
2971 if (inq_buff == NULL) { 3049 if (inq_buff == NULL) {
2972 printk(KERN_ERR "cciss: out of memory\n"); 3050 printk(KERN_ERR "cciss: out of memory\n");
2973 kfree(ld_buff); 3051 kfree(ld_buff);
2974 kfree(size_buff);
2975 return; 3052 return;
2976 } 3053 }
2977 /* Get the firmware version */ 3054 /* Get the firmware version */
@@ -3026,7 +3103,6 @@ static void cciss_getgeometry(int cntl_num)
3026#endif /* CCISS_DEBUG */ 3103#endif /* CCISS_DEBUG */
3027 3104
3028 hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; 3105 hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1;
3029// for(i=0; i< hba[cntl_num]->num_luns; i++)
3030 for (i = 0; i < CISS_MAX_LUN; i++) { 3106 for (i = 0; i < CISS_MAX_LUN; i++) {
3031 if (i < hba[cntl_num]->num_luns) { 3107 if (i < hba[cntl_num]->num_luns) {
3032 lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) 3108 lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
@@ -3045,8 +3121,26 @@ static void cciss_getgeometry(int cntl_num)
3045 ld_buff->LUN[i][2], ld_buff->LUN[i][3], 3121 ld_buff->LUN[i][2], ld_buff->LUN[i][3],
3046 hba[cntl_num]->drv[i].LunID); 3122 hba[cntl_num]->drv[i].LunID);
3047#endif /* CCISS_DEBUG */ 3123#endif /* CCISS_DEBUG */
3048 cciss_read_capacity(cntl_num, i, size_buff, 0, 3124
3125 /* testing to see if 16-byte CDBs are already being used */
3126 if(hba[cntl_num]->cciss_read == CCISS_READ_16) {
3127 cciss_read_capacity_16(cntl_num, i, 0,
3049 &total_size, &block_size); 3128 &total_size, &block_size);
3129 goto geo_inq;
3130 }
3131 cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size);
3132
3133 /* total_size = last LBA + 1 */
3134 if(total_size == (__u32) 0) {
3135 cciss_read_capacity_16(cntl_num, i, 0,
3136 &total_size, &block_size);
3137 hba[cntl_num]->cciss_read = CCISS_READ_16;
3138 hba[cntl_num]->cciss_write = CCISS_WRITE_16;
3139 } else {
3140 hba[cntl_num]->cciss_read = CCISS_READ_10;
3141 hba[cntl_num]->cciss_write = CCISS_WRITE_10;
3142 }
3143geo_inq:
3050 cciss_geometry_inquiry(cntl_num, i, 0, total_size, 3144 cciss_geometry_inquiry(cntl_num, i, 0, total_size,
3051 block_size, inq_buff, 3145 block_size, inq_buff,
3052 &hba[cntl_num]->drv[i]); 3146 &hba[cntl_num]->drv[i]);
@@ -3056,7 +3150,6 @@ static void cciss_getgeometry(int cntl_num)
3056 } 3150 }
3057 } 3151 }
3058 kfree(ld_buff); 3152 kfree(ld_buff);
3059 kfree(size_buff);
3060 kfree(inq_buff); 3153 kfree(inq_buff);
3061} 3154}
3062 3155
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 868e0d862b0d..562235c1445a 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -76,6 +76,9 @@ struct ctlr_info
76 unsigned int intr[4]; 76 unsigned int intr[4];
77 unsigned int msix_vector; 77 unsigned int msix_vector;
78 unsigned int msi_vector; 78 unsigned int msi_vector;
79 BYTE cciss_read;
80 BYTE cciss_write;
81 BYTE cciss_read_capacity;
79 82
80 // information about each logical volume 83 // information about each logical volume
81 drive_info_struct drv[CISS_MAX_LUN]; 84 drive_info_struct drv[CISS_MAX_LUN];
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index 53fea549ba8b..4af7c4c0c7af 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -118,11 +118,34 @@ typedef struct _ReadCapdata_struct
118 BYTE block_size[4]; // Size of blocks in bytes 118 BYTE block_size[4]; // Size of blocks in bytes
119} ReadCapdata_struct; 119} ReadCapdata_struct;
120 120
121// 12 byte commands not implemented in firmware yet. 121#define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */
122// #define CCISS_READ 0xa8 // Read(12) 122
123// #define CCISS_WRITE 0xaa // Write(12) 123/* service action to differentiate a 16 byte read capacity from
124 #define CCISS_READ 0x28 // Read(10) 124 other commands that use the 0x9e SCSI op code */
125 #define CCISS_WRITE 0x2a // Write(10) 125
126#define CCISS_READ_CAPACITY_16_SERVICE_ACT 0x10
127
128typedef struct _ReadCapdata_struct_16
129{
130 BYTE total_size[8]; /* Total size in blocks */
131 BYTE block_size[4]; /* Size of blocks in bytes */
132 BYTE prot_en:1; /* protection enable bit */
133 BYTE rto_en:1; /* reference tag own enable bit */
134 BYTE reserved:6; /* reserved bits */
135 BYTE reserved2[18]; /* reserved bytes per spec */
136} ReadCapdata_struct_16;
137
138/* Define the supported read/write commands for cciss based controllers */
139
140#define CCISS_READ_10 0x28 /* Read(10) */
141#define CCISS_WRITE_10 0x2a /* Write(10) */
142#define CCISS_READ_16 0x88 /* Read(16) */
143#define CCISS_WRITE_16 0x8a /* Write(16) */
144
145/* Define the CDB lengths supported by cciss based controllers */
146
147#define CDB_LEN10 10
148#define CDB_LEN16 16
126 149
127// BMIC commands 150// BMIC commands
128#define BMIC_READ 0x26 151#define BMIC_READ 0x26