diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2013-02-20 12:24:41 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-02-24 04:34:21 -0500 |
commit | a2dac136c40fe07861f8146434917031a8c301b1 (patch) | |
tree | fdffcb848d9eae32aa11723c6fe268464f0997bb /drivers/scsi | |
parent | eceaae187d3bd457b3dba29c4f23bccda374db63 (diff) |
[SCSI] hpsa: Check for dma_mapping_error for all code paths using fill_cmd
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/hpsa.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3b4d195b4978..137ed3335415 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -165,7 +165,7 @@ static void cmd_free(struct ctlr_info *h, struct CommandList *c); | |||
165 | static void cmd_special_free(struct ctlr_info *h, struct CommandList *c); | 165 | static void cmd_special_free(struct ctlr_info *h, struct CommandList *c); |
166 | static struct CommandList *cmd_alloc(struct ctlr_info *h); | 166 | static struct CommandList *cmd_alloc(struct ctlr_info *h); |
167 | static struct CommandList *cmd_special_alloc(struct ctlr_info *h); | 167 | static struct CommandList *cmd_special_alloc(struct ctlr_info *h); |
168 | static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, | 168 | static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, |
169 | void *buff, size_t size, u8 page_code, unsigned char *scsi3addr, | 169 | void *buff, size_t size, u8 page_code, unsigned char *scsi3addr, |
170 | int cmd_type); | 170 | int cmd_type); |
171 | 171 | ||
@@ -1390,7 +1390,7 @@ static void hpsa_pci_unmap(struct pci_dev *pdev, | |||
1390 | } | 1390 | } |
1391 | } | 1391 | } |
1392 | 1392 | ||
1393 | static void hpsa_map_one(struct pci_dev *pdev, | 1393 | static int hpsa_map_one(struct pci_dev *pdev, |
1394 | struct CommandList *cp, | 1394 | struct CommandList *cp, |
1395 | unsigned char *buf, | 1395 | unsigned char *buf, |
1396 | size_t buflen, | 1396 | size_t buflen, |
@@ -1401,14 +1401,15 @@ static void hpsa_map_one(struct pci_dev *pdev, | |||
1401 | if (buflen == 0 || data_direction == PCI_DMA_NONE) { | 1401 | if (buflen == 0 || data_direction == PCI_DMA_NONE) { |
1402 | cp->Header.SGList = 0; | 1402 | cp->Header.SGList = 0; |
1403 | cp->Header.SGTotal = 0; | 1403 | cp->Header.SGTotal = 0; |
1404 | return; | 1404 | return 0; |
1405 | } | 1405 | } |
1406 | 1406 | ||
1407 | addr64 = (u64) pci_map_single(pdev, buf, buflen, data_direction); | 1407 | addr64 = (u64) pci_map_single(pdev, buf, buflen, data_direction); |
1408 | if (dma_mapping_error(&pdev->dev, addr64)) { | 1408 | if (dma_mapping_error(&pdev->dev, addr64)) { |
1409 | /* Prevent subsequent unmap of something never mapped */ | ||
1409 | cp->Header.SGList = 0; | 1410 | cp->Header.SGList = 0; |
1410 | cp->Header.SGTotal = 0; | 1411 | cp->Header.SGTotal = 0; |
1411 | return; | 1412 | return -1; |
1412 | } | 1413 | } |
1413 | cp->SG[0].Addr.lower = | 1414 | cp->SG[0].Addr.lower = |
1414 | (u32) (addr64 & (u64) 0x00000000FFFFFFFF); | 1415 | (u32) (addr64 & (u64) 0x00000000FFFFFFFF); |
@@ -1417,6 +1418,7 @@ static void hpsa_map_one(struct pci_dev *pdev, | |||
1417 | cp->SG[0].Len = buflen; | 1418 | cp->SG[0].Len = buflen; |
1418 | cp->Header.SGList = (u8) 1; /* no. SGs contig in this cmd */ | 1419 | cp->Header.SGList = (u8) 1; /* no. SGs contig in this cmd */ |
1419 | cp->Header.SGTotal = (u16) 1; /* total sgs in this cmd list */ | 1420 | cp->Header.SGTotal = (u16) 1; /* total sgs in this cmd list */ |
1421 | return 0; | ||
1420 | } | 1422 | } |
1421 | 1423 | ||
1422 | static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h, | 1424 | static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h, |
@@ -1545,13 +1547,18 @@ static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr, | |||
1545 | return -ENOMEM; | 1547 | return -ENOMEM; |
1546 | } | 1548 | } |
1547 | 1549 | ||
1548 | fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize, page, scsi3addr, TYPE_CMD); | 1550 | if (fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize, |
1551 | page, scsi3addr, TYPE_CMD)) { | ||
1552 | rc = -1; | ||
1553 | goto out; | ||
1554 | } | ||
1549 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); | 1555 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); |
1550 | ei = c->err_info; | 1556 | ei = c->err_info; |
1551 | if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { | 1557 | if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { |
1552 | hpsa_scsi_interpret_error(c); | 1558 | hpsa_scsi_interpret_error(c); |
1553 | rc = -1; | 1559 | rc = -1; |
1554 | } | 1560 | } |
1561 | out: | ||
1555 | cmd_special_free(h, c); | 1562 | cmd_special_free(h, c); |
1556 | return rc; | 1563 | return rc; |
1557 | } | 1564 | } |
@@ -1569,7 +1576,9 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr) | |||
1569 | return -ENOMEM; | 1576 | return -ENOMEM; |
1570 | } | 1577 | } |
1571 | 1578 | ||
1572 | fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); | 1579 | /* fill_cmd can't fail here, no data buffer to map. */ |
1580 | (void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, | ||
1581 | NULL, 0, 0, scsi3addr, TYPE_MSG); | ||
1573 | hpsa_scsi_do_simple_cmd_core(h, c); | 1582 | hpsa_scsi_do_simple_cmd_core(h, c); |
1574 | /* no unmap needed here because no data xfer. */ | 1583 | /* no unmap needed here because no data xfer. */ |
1575 | 1584 | ||
@@ -1636,8 +1645,11 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical, | |||
1636 | } | 1645 | } |
1637 | /* address the controller */ | 1646 | /* address the controller */ |
1638 | memset(scsi3addr, 0, sizeof(scsi3addr)); | 1647 | memset(scsi3addr, 0, sizeof(scsi3addr)); |
1639 | fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h, | 1648 | if (fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h, |
1640 | buf, bufsize, 0, scsi3addr, TYPE_CMD); | 1649 | buf, bufsize, 0, scsi3addr, TYPE_CMD)) { |
1650 | rc = -1; | ||
1651 | goto out; | ||
1652 | } | ||
1641 | if (extended_response) | 1653 | if (extended_response) |
1642 | c->Request.CDB[1] = extended_response; | 1654 | c->Request.CDB[1] = extended_response; |
1643 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); | 1655 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); |
@@ -1647,6 +1659,7 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical, | |||
1647 | hpsa_scsi_interpret_error(c); | 1659 | hpsa_scsi_interpret_error(c); |
1648 | rc = -1; | 1660 | rc = -1; |
1649 | } | 1661 | } |
1662 | out: | ||
1650 | cmd_special_free(h, c); | 1663 | cmd_special_free(h, c); |
1651 | return rc; | 1664 | return rc; |
1652 | } | 1665 | } |
@@ -2358,8 +2371,9 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h, | |||
2358 | if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS) | 2371 | if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS) |
2359 | waittime = waittime * 2; | 2372 | waittime = waittime * 2; |
2360 | 2373 | ||
2361 | /* Send the Test Unit Ready */ | 2374 | /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */ |
2362 | fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, lunaddr, TYPE_CMD); | 2375 | (void) fill_cmd(c, TEST_UNIT_READY, h, |
2376 | NULL, 0, 0, lunaddr, TYPE_CMD); | ||
2363 | hpsa_scsi_do_simple_cmd_core(h, c); | 2377 | hpsa_scsi_do_simple_cmd_core(h, c); |
2364 | /* no unmap needed here because no data xfer. */ | 2378 | /* no unmap needed here because no data xfer. */ |
2365 | 2379 | ||
@@ -2444,7 +2458,9 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr, | |||
2444 | return -ENOMEM; | 2458 | return -ENOMEM; |
2445 | } | 2459 | } |
2446 | 2460 | ||
2447 | fill_cmd(c, HPSA_ABORT_MSG, h, abort, 0, 0, scsi3addr, TYPE_MSG); | 2461 | /* fill_cmd can't fail here, no buffer to map */ |
2462 | (void) fill_cmd(c, HPSA_ABORT_MSG, h, abort, | ||
2463 | 0, 0, scsi3addr, TYPE_MSG); | ||
2448 | if (swizzle) | 2464 | if (swizzle) |
2449 | swizzle_abort_tag(&c->Request.CDB[4]); | 2465 | swizzle_abort_tag(&c->Request.CDB[4]); |
2450 | hpsa_scsi_do_simple_cmd_core(h, c); | 2466 | hpsa_scsi_do_simple_cmd_core(h, c); |
@@ -3195,7 +3211,8 @@ static int hpsa_send_host_reset(struct ctlr_info *h, unsigned char *scsi3addr, | |||
3195 | c = cmd_alloc(h); | 3211 | c = cmd_alloc(h); |
3196 | if (!c) | 3212 | if (!c) |
3197 | return -ENOMEM; | 3213 | return -ENOMEM; |
3198 | fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, | 3214 | /* fill_cmd can't fail here, no data buffer to map */ |
3215 | (void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, | ||
3199 | RAID_CTLR_LUNID, TYPE_MSG); | 3216 | RAID_CTLR_LUNID, TYPE_MSG); |
3200 | c->Request.CDB[1] = reset_type; /* fill_cmd defaults to target reset */ | 3217 | c->Request.CDB[1] = reset_type; /* fill_cmd defaults to target reset */ |
3201 | c->waiting = NULL; | 3218 | c->waiting = NULL; |
@@ -3207,7 +3224,7 @@ static int hpsa_send_host_reset(struct ctlr_info *h, unsigned char *scsi3addr, | |||
3207 | return 0; | 3224 | return 0; |
3208 | } | 3225 | } |
3209 | 3226 | ||
3210 | static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, | 3227 | static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, |
3211 | void *buff, size_t size, u8 page_code, unsigned char *scsi3addr, | 3228 | void *buff, size_t size, u8 page_code, unsigned char *scsi3addr, |
3212 | int cmd_type) | 3229 | int cmd_type) |
3213 | { | 3230 | { |
@@ -3276,7 +3293,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, | |||
3276 | default: | 3293 | default: |
3277 | dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); | 3294 | dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); |
3278 | BUG(); | 3295 | BUG(); |
3279 | return; | 3296 | return -1; |
3280 | } | 3297 | } |
3281 | } else if (cmd_type == TYPE_MSG) { | 3298 | } else if (cmd_type == TYPE_MSG) { |
3282 | switch (cmd) { | 3299 | switch (cmd) { |
@@ -3348,10 +3365,9 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, | |||
3348 | default: | 3365 | default: |
3349 | pci_dir = PCI_DMA_BIDIRECTIONAL; | 3366 | pci_dir = PCI_DMA_BIDIRECTIONAL; |
3350 | } | 3367 | } |
3351 | 3368 | if (hpsa_map_one(h->pdev, c, buff, size, pci_dir)) | |
3352 | hpsa_map_one(h->pdev, c, buff, size, pci_dir); | 3369 | return -1; |
3353 | 3370 | return 0; | |
3354 | return; | ||
3355 | } | 3371 | } |
3356 | 3372 | ||
3357 | /* | 3373 | /* |
@@ -4887,10 +4903,13 @@ static void hpsa_flush_cache(struct ctlr_info *h) | |||
4887 | dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); | 4903 | dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); |
4888 | goto out_of_memory; | 4904 | goto out_of_memory; |
4889 | } | 4905 | } |
4890 | fill_cmd(c, HPSA_CACHE_FLUSH, h, flush_buf, 4, 0, | 4906 | if (fill_cmd(c, HPSA_CACHE_FLUSH, h, flush_buf, 4, 0, |
4891 | RAID_CTLR_LUNID, TYPE_CMD); | 4907 | RAID_CTLR_LUNID, TYPE_CMD)) { |
4908 | goto out; | ||
4909 | } | ||
4892 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_TODEVICE); | 4910 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_TODEVICE); |
4893 | if (c->err_info->CommandStatus != 0) | 4911 | if (c->err_info->CommandStatus != 0) |
4912 | out: | ||
4894 | dev_warn(&h->pdev->dev, | 4913 | dev_warn(&h->pdev->dev, |
4895 | "error flushing cache on controller\n"); | 4914 | "error flushing cache on controller\n"); |
4896 | cmd_special_free(h, c); | 4915 | cmd_special_free(h, c); |