aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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