aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-02-26 17:01:27 -0500
committerJens Axboe <jens.axboe@oracle.com>2010-02-28 13:42:31 -0500
commitdccc9b563e455b91f7247b1ca6b0face40323538 (patch)
treea800d412764ee22d9a54000cb844a04a1a006933 /drivers/block/cciss.c
parent49fc5601ea3bf9625d699dc777f80f72e8126c0b (diff)
cciss: simplify scatter gather code
cciss: simplify scatter gather code. Instead of allocating an array of pointers to a structure containing an SGDescriptor structure, and two other elements that aren't really used, just allocate SGDescriptor structs. 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.c')
-rw-r--r--drivers/block/cciss.c43
1 files changed, 15 insertions, 28 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index eddb916d2908..adc517c1381c 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -257,7 +257,7 @@ static inline void removeQ(CommandList_struct *c)
257 hlist_del_init(&c->list); 257 hlist_del_init(&c->list);
258} 258}
259 259
260static void cciss_free_sg_chain_blocks(struct Cmd_sg_list **cmd_sg_list, 260static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list,
261 int nr_cmds) 261 int nr_cmds)
262{ 262{
263 int i; 263 int i;
@@ -265,20 +265,17 @@ static void cciss_free_sg_chain_blocks(struct Cmd_sg_list **cmd_sg_list,
265 if (!cmd_sg_list) 265 if (!cmd_sg_list)
266 return; 266 return;
267 for (i = 0; i < nr_cmds; i++) { 267 for (i = 0; i < nr_cmds; i++) {
268 if (cmd_sg_list[i]) { 268 kfree(cmd_sg_list[i]);
269 kfree(cmd_sg_list[i]->sgchain); 269 cmd_sg_list[i] = NULL;
270 kfree(cmd_sg_list[i]);
271 cmd_sg_list[i] = NULL;
272 }
273 } 270 }
274 kfree(cmd_sg_list); 271 kfree(cmd_sg_list);
275} 272}
276 273
277static struct Cmd_sg_list **cciss_allocate_sg_chain_blocks(ctlr_info_t *h, 274static SGDescriptor_struct **cciss_allocate_sg_chain_blocks(
278 int chainsize, int nr_cmds) 275 ctlr_info_t *h, int chainsize, int nr_cmds)
279{ 276{
280 int j; 277 int j;
281 struct Cmd_sg_list **cmd_sg_list; 278 SGDescriptor_struct **cmd_sg_list;
282 279
283 if (chainsize <= 0) 280 if (chainsize <= 0)
284 return NULL; 281 return NULL;
@@ -289,16 +286,10 @@ static struct Cmd_sg_list **cciss_allocate_sg_chain_blocks(ctlr_info_t *h,
289 286
290 /* Build up chain blocks for each command */ 287 /* Build up chain blocks for each command */
291 for (j = 0; j < nr_cmds; j++) { 288 for (j = 0; j < nr_cmds; j++) {
292 cmd_sg_list[j] = kmalloc(sizeof(*cmd_sg_list[j]), GFP_KERNEL);
293 if (!cmd_sg_list[j]) {
294 dev_err(&h->pdev->dev, "Cannot get memory "
295 "for chain block.\n");
296 goto clean;
297 }
298 /* Need a block of chainsized s/g elements. */ 289 /* Need a block of chainsized s/g elements. */
299 cmd_sg_list[j]->sgchain = kmalloc((chainsize * 290 cmd_sg_list[j] = kmalloc((chainsize *
300 sizeof(SGDescriptor_struct)), GFP_KERNEL); 291 sizeof(*cmd_sg_list[j])), GFP_KERNEL);
301 if (!cmd_sg_list[j]->sgchain) { 292 if (!cmd_sg_list[j]) {
302 dev_err(&h->pdev->dev, "Cannot get memory " 293 dev_err(&h->pdev->dev, "Cannot get memory "
303 "for s/g chains.\n"); 294 "for s/g chains.\n");
304 goto clean; 295 goto clean;
@@ -1731,7 +1722,7 @@ static void cciss_softirq_done(struct request *rq)
1731 pci_unmap_single(h->pdev, temp64.val, 1722 pci_unmap_single(h->pdev, temp64.val,
1732 cmd->SG[i].Len, ddir); 1723 cmd->SG[i].Len, ddir);
1733 /* Point to the next block */ 1724 /* Point to the next block */
1734 curr_sg = h->cmd_sg_list[cmd->cmdindex]->sgchain; 1725 curr_sg = h->cmd_sg_list[cmd->cmdindex];
1735 sg_index = 0; 1726 sg_index = 0;
1736 } 1727 }
1737 temp64.val32.lower = curr_sg[sg_index].Addr.lower; 1728 temp64.val32.lower = curr_sg[sg_index].Addr.lower;
@@ -3206,7 +3197,7 @@ static void do_cciss_request(struct request_queue *q)
3206 curr_sg[sg_index].Ext = CCISS_SG_CHAIN; 3197 curr_sg[sg_index].Ext = CCISS_SG_CHAIN;
3207 3198
3208 /* Point to next chain block. */ 3199 /* Point to next chain block. */
3209 curr_sg = h->cmd_sg_list[c->cmdindex]->sgchain; 3200 curr_sg = h->cmd_sg_list[c->cmdindex];
3210 sg_index = 0; 3201 sg_index = 0;
3211 chained = 1; 3202 chained = 1;
3212 } 3203 }
@@ -3223,6 +3214,7 @@ static void do_cciss_request(struct request_queue *q)
3223 3214
3224 if (chained) { 3215 if (chained) {
3225 int len; 3216 int len;
3217 dma_addr_t dma_addr;
3226 curr_sg = c->SG; 3218 curr_sg = c->SG;
3227 sg_index = h->max_cmd_sgentries - 1; 3219 sg_index = h->max_cmd_sgentries - 1;
3228 len = curr_sg[sg_index].Len; 3220 len = curr_sg[sg_index].Len;
@@ -3231,16 +3223,11 @@ static void do_cciss_request(struct request_queue *q)
3231 * block with address of next chain block. 3223 * block with address of next chain block.
3232 */ 3224 */
3233 temp64.val = pci_map_single(h->pdev, 3225 temp64.val = pci_map_single(h->pdev,
3234 h->cmd_sg_list[c->cmdindex]->sgchain, 3226 h->cmd_sg_list[c->cmdindex], len, dir);
3235 len, dir); 3227 dma_addr = temp64.val;
3236
3237 h->cmd_sg_list[c->cmdindex]->sg_chain_dma = temp64.val;
3238 curr_sg[sg_index].Addr.lower = temp64.val32.lower; 3228 curr_sg[sg_index].Addr.lower = temp64.val32.lower;
3239 curr_sg[sg_index].Addr.upper = temp64.val32.upper; 3229 curr_sg[sg_index].Addr.upper = temp64.val32.upper;
3240 3230 pci_dma_sync_single_for_device(h->pdev, dma_addr, len, dir);
3241 pci_dma_sync_single_for_device(h->pdev,
3242 h->cmd_sg_list[c->cmdindex]->sg_chain_dma,
3243 len, dir);
3244 } 3231 }
3245 3232
3246 /* track how many SG entries we are using */ 3233 /* track how many SG entries we are using */