diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2010-02-26 17:01:27 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-02-28 13:42:31 -0500 |
commit | dccc9b563e455b91f7247b1ca6b0face40323538 (patch) | |
tree | a800d412764ee22d9a54000cb844a04a1a006933 /drivers/block | |
parent | 49fc5601ea3bf9625d699dc777f80f72e8126c0b (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')
-rw-r--r-- | drivers/block/cciss.c | 43 | ||||
-rw-r--r-- | drivers/block/cciss.h | 8 |
2 files changed, 16 insertions, 35 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 | ||
260 | static void cciss_free_sg_chain_blocks(struct Cmd_sg_list **cmd_sg_list, | 260 | static 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 | ||
277 | static struct Cmd_sg_list **cciss_allocate_sg_chain_blocks(ctlr_info_t *h, | 274 | static 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 */ |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 2b07bdacbd12..ac454fdd4d30 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -55,12 +55,6 @@ typedef struct _drive_info_struct | |||
55 | char device_initialized; /* indicates whether dev is initialized */ | 55 | char device_initialized; /* indicates whether dev is initialized */ |
56 | } drive_info_struct; | 56 | } drive_info_struct; |
57 | 57 | ||
58 | struct Cmd_sg_list { | ||
59 | SGDescriptor_struct *sgchain; | ||
60 | dma_addr_t sg_chain_dma; | ||
61 | int chain_block_size; | ||
62 | }; | ||
63 | |||
64 | struct ctlr_info | 58 | struct ctlr_info |
65 | { | 59 | { |
66 | int ctlr; | 60 | int ctlr; |
@@ -89,7 +83,7 @@ struct ctlr_info | |||
89 | int maxsgentries; | 83 | int maxsgentries; |
90 | int chainsize; | 84 | int chainsize; |
91 | int max_cmd_sgentries; | 85 | int max_cmd_sgentries; |
92 | struct Cmd_sg_list **cmd_sg_list; | 86 | SGDescriptor_struct **cmd_sg_list; |
93 | 87 | ||
94 | # define DOORBELL_INT 0 | 88 | # define DOORBELL_INT 0 |
95 | # define PERF_MODE_INT 1 | 89 | # define PERF_MODE_INT 1 |