aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss_scsi.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-02-26 17:01:53 -0500
committerJens Axboe <jens.axboe@oracle.com>2010-02-28 13:42:32 -0500
commit87c3a922a7ee8cfb9ab837f4ae38c993e9b30711 (patch)
tree84d896c43d9aacb6c575150ba4afca9a97b6c482 /drivers/block/cciss_scsi.c
parentbf8873781831c7799255e0932848401070185dd0 (diff)
cciss: Fix problem with scatter gather elements in the scsi half of the driver
cciss: Fix problem with scatter gather elements in the scsi half of the driver When support for more than 31 scatter gather elements was added to the block half of the driver, the SCSI half of the driver was not addressed, and the bump from 31 to 32 scatter gather elements in the command block itself (not chained) actually broke the SCSI half of the driver, so that any transfer requiring 32 scatter gather elements wouldn't work. This fix also increases the max transfer size and size of the scatter gather table to the limit supported by the controller Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block/cciss_scsi.c')
-rw-r--r--drivers/block/cciss_scsi.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 6dc15b669694..e1d0e2cfec72 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -84,7 +84,6 @@ static struct scsi_host_template cciss_driver_template = {
84 .queuecommand = cciss_scsi_queue_command, 84 .queuecommand = cciss_scsi_queue_command,
85 .can_queue = SCSI_CCISS_CAN_QUEUE, 85 .can_queue = SCSI_CCISS_CAN_QUEUE,
86 .this_id = 7, 86 .this_id = 7,
87 .sg_tablesize = MAXSGENTRIES,
88 .cmd_per_lun = 1, 87 .cmd_per_lun = 1,
89 .use_clustering = DISABLE_CLUSTERING, 88 .use_clustering = DISABLE_CLUSTERING,
90 /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */ 89 /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
@@ -94,13 +93,14 @@ static struct scsi_host_template cciss_driver_template = {
94 93
95#pragma pack(1) 94#pragma pack(1)
96 95
97#define SCSI_PAD_32 4 96#define SCSI_PAD_32 0
98#define SCSI_PAD_64 4 97#define SCSI_PAD_64 0
99 98
100struct cciss_scsi_cmd_stack_elem_t { 99struct cciss_scsi_cmd_stack_elem_t {
101 CommandList_struct cmd; 100 CommandList_struct cmd;
102 ErrorInfo_struct Err; 101 ErrorInfo_struct Err;
103 __u32 busaddr; 102 __u32 busaddr;
103 int cmdindex;
104 u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64]; 104 u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64];
105}; 105};
106 106
@@ -122,6 +122,7 @@ struct cciss_scsi_cmd_stack_t {
122struct cciss_scsi_adapter_data_t { 122struct cciss_scsi_adapter_data_t {
123 struct Scsi_Host *scsi_host; 123 struct Scsi_Host *scsi_host;
124 struct cciss_scsi_cmd_stack_t cmd_stack; 124 struct cciss_scsi_cmd_stack_t cmd_stack;
125 SGDescriptor_struct **cmd_sg_list;
125 int registered; 126 int registered;
126 spinlock_t lock; // to protect ccissscsi[ctlr]; 127 spinlock_t lock; // to protect ccissscsi[ctlr];
127}; 128};
@@ -156,6 +157,7 @@ scsi_cmd_alloc(ctlr_info_t *h)
156 memset(&c->Err, 0, sizeof(c->Err)); 157 memset(&c->Err, 0, sizeof(c->Err));
157 /* set physical addr of cmd and addr of scsi parameters */ 158 /* set physical addr of cmd and addr of scsi parameters */
158 c->cmd.busaddr = c->busaddr; 159 c->cmd.busaddr = c->busaddr;
160 c->cmd.cmdindex = c->cmdindex;
159 /* (__u32) (stk->cmd_pool_handle + 161 /* (__u32) (stk->cmd_pool_handle +
160 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */ 162 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */
161 163
@@ -201,6 +203,11 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
201 struct cciss_scsi_cmd_stack_t *stk; 203 struct cciss_scsi_cmd_stack_t *stk;
202 size_t size; 204 size_t size;
203 205
206 sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr],
207 hba[ctlr]->chainsize, CMD_STACK_SIZE);
208 if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0)
209 return -ENOMEM;
210
204 stk = &sa->cmd_stack; 211 stk = &sa->cmd_stack;
205 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; 212 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
206 213
@@ -211,14 +218,16 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
211 pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle); 218 pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
212 219
213 if (stk->pool == NULL) { 220 if (stk->pool == NULL) {
214 printk("stk->pool is null\n"); 221 cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
215 return -1; 222 sa->cmd_sg_list = NULL;
223 return -ENOMEM;
216 } 224 }
217 225
218 for (i=0; i<CMD_STACK_SIZE; i++) { 226 for (i=0; i<CMD_STACK_SIZE; i++) {
219 stk->elem[i] = &stk->pool[i]; 227 stk->elem[i] = &stk->pool[i];
220 stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle + 228 stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
221 (sizeof(struct cciss_scsi_cmd_stack_elem_t) * i)); 229 (sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
230 stk->elem[i]->cmdindex = i;
222 } 231 }
223 stk->top = CMD_STACK_SIZE-1; 232 stk->top = CMD_STACK_SIZE-1;
224 return 0; 233 return 0;
@@ -243,6 +252,7 @@ scsi_cmd_stack_free(int ctlr)
243 252
244 pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle); 253 pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
245 stk->pool = NULL; 254 stk->pool = NULL;
255 cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
246} 256}
247 257
248#if 0 258#if 0
@@ -726,6 +736,8 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
726 ctlr = hba[cp->ctlr]; 736 ctlr = hba[cp->ctlr];
727 737
728 scsi_dma_unmap(cmd); 738 scsi_dma_unmap(cmd);
739 if (cp->Header.SGTotal > ctlr->max_cmd_sgentries)
740 cciss_unmap_sg_chain_block(ctlr, cp);
729 741
730 cmd->result = (DID_OK << 16); /* host byte */ 742 cmd->result = (DID_OK << 16); /* host byte */
731 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ 743 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
@@ -848,6 +860,7 @@ cciss_scsi_detect(int ctlr)
848 sh->io_port = 0; // good enough? FIXME, 860 sh->io_port = 0; // good enough? FIXME,
849 sh->n_io_port = 0; // I don't think we use these two... 861 sh->n_io_port = 0; // I don't think we use these two...
850 sh->this_id = SELF_SCSI_ID; 862 sh->this_id = SELF_SCSI_ID;
863 sh->sg_tablesize = hba[ctlr]->maxsgentries;
851 864
852 ((struct cciss_scsi_adapter_data_t *) 865 ((struct cciss_scsi_adapter_data_t *)
853 hba[ctlr]->scsi_ctlr)->scsi_host = sh; 866 hba[ctlr]->scsi_ctlr)->scsi_host = sh;
@@ -1365,34 +1378,54 @@ cciss_scsi_proc_info(struct Scsi_Host *sh,
1365 dma mapping and fills in the scatter gather entries of the 1378 dma mapping and fills in the scatter gather entries of the
1366 cciss command, cp. */ 1379 cciss command, cp. */
1367 1380
1368static void 1381static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp,
1369cciss_scatter_gather(struct pci_dev *pdev, 1382 struct scsi_cmnd *cmd)
1370 CommandList_struct *cp,
1371 struct scsi_cmnd *cmd)
1372{ 1383{
1373 unsigned int len; 1384 unsigned int len;
1374 struct scatterlist *sg; 1385 struct scatterlist *sg;
1375 __u64 addr64; 1386 __u64 addr64;
1376 int use_sg, i; 1387 int request_nsgs, i, chained, sg_index;
1377 1388 struct cciss_scsi_adapter_data_t *sa = h->scsi_ctlr;
1378 BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); 1389 SGDescriptor_struct *curr_sg;
1379 1390
1380 use_sg = scsi_dma_map(cmd); 1391 BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
1381 if (use_sg) { /* not too many addrs? */ 1392
1382 scsi_for_each_sg(cmd, sg, use_sg, i) { 1393 chained = 0;
1394 sg_index = 0;
1395 curr_sg = cp->SG;
1396 request_nsgs = scsi_dma_map(cmd);
1397 if (request_nsgs) {
1398 scsi_for_each_sg(cmd, sg, request_nsgs, i) {
1399 if (sg_index + 1 == h->max_cmd_sgentries &&
1400 !chained && request_nsgs - i > 1) {
1401 chained = 1;
1402 sg_index = 0;
1403 curr_sg = sa->cmd_sg_list[cp->cmdindex];
1404 }
1383 addr64 = (__u64) sg_dma_address(sg); 1405 addr64 = (__u64) sg_dma_address(sg);
1384 len = sg_dma_len(sg); 1406 len = sg_dma_len(sg);
1385 cp->SG[i].Addr.lower = 1407 curr_sg[sg_index].Addr.lower =
1386 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); 1408 (__u32) (addr64 & 0x0FFFFFFFFULL);
1387 cp->SG[i].Addr.upper = 1409 curr_sg[sg_index].Addr.upper =
1388 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); 1410 (__u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
1389 cp->SG[i].Len = len; 1411 curr_sg[sg_index].Len = len;
1390 cp->SG[i].Ext = 0; // we are not chaining 1412 curr_sg[sg_index].Ext = 0;
1413 ++sg_index;
1391 } 1414 }
1415 if (chained)
1416 cciss_map_sg_chain_block(h, cp,
1417 sa->cmd_sg_list[cp->cmdindex],
1418 (request_nsgs - (h->max_cmd_sgentries - 1)) *
1419 sizeof(SGDescriptor_struct));
1392 } 1420 }
1393 1421 /* track how many SG entries we are using */
1394 cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ 1422 if (request_nsgs > h->maxSG)
1395 cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ 1423 h->maxSG = request_nsgs;
1424 cp->Header.SGTotal = (__u8) request_nsgs + chained;
1425 if (request_nsgs > h->max_cmd_sgentries)
1426 cp->Header.SGList = h->max_cmd_sgentries;
1427 else
1428 cp->Header.SGList = cp->Header.SGTotal;
1396 return; 1429 return;
1397} 1430}
1398 1431
@@ -1490,7 +1523,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
1490 BUG(); 1523 BUG();
1491 break; 1524 break;
1492 } 1525 }
1493 cciss_scatter_gather(c->pdev, cp, cmd); 1526 cciss_scatter_gather(c, cp, cmd);
1494 1527
1495 /* Put the request on the tail of the request queue */ 1528 /* Put the request on the tail of the request queue */
1496 1529