diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2013-02-20 21:24:46 +0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-02-24 13:35:18 +0400 |
commit | e2bea6df3261dac1ae400452ddab07babb4fc5f3 (patch) | |
tree | 9a8e13d18658b3541510608ae1575b4156a00977 /drivers/scsi/hpsa.c | |
parent | a2dac136c40fe07861f8146434917031a8c301b1 (diff) | |
download | linux-e2bea6df3261dac1ae400452ddab07babb4fc5f3.tar.xz |
[SCSI] hpsa: check for dma_mapping_error in hpsa_map_sg_chain_block
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 137ed3335415..38c8aa5e85b4 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1131,7 +1131,7 @@ clean: return -ENOMEM; } -static void hpsa_map_sg_chain_block(struct ctlr_info *h, +static int hpsa_map_sg_chain_block(struct ctlr_info *h, struct CommandList *c) { struct SGDescriptor *chain_sg, *chain_block; @@ -1144,8 +1144,15 @@ static void hpsa_map_sg_chain_block(struct ctlr_info *h, (c->Header.SGTotal - h->max_cmd_sg_entries); temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len, PCI_DMA_TODEVICE); + if (dma_mapping_error(&h->pdev->dev, temp64)) { + /* prevent subsequent unmapping */ + chain_sg->Addr.lower = 0; + chain_sg->Addr.upper = 0; + return -1; + } chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL); chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL); + return 0; } static void hpsa_unmap_sg_chain_block(struct ctlr_info *h, @@ -2123,7 +2130,10 @@ static int hpsa_scatter_gather(struct ctlr_info *h, if (chained) { cp->Header.SGList = h->max_cmd_sg_entries; cp->Header.SGTotal = (u16) (use_sg + 1); - hpsa_map_sg_chain_block(h, cp); + if (hpsa_map_sg_chain_block(h, cp)) { + scsi_dma_unmap(cmd); + return -1; + } return 0; } |