scsi: cciss: correct check map error.
authorDon Brace <don.brace@microsemi.com>
Thu, 23 Feb 2017 14:57:20 +0000 (08:57 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 23 Feb 2017 22:10:32 +0000 (17:10 -0500)
Remove device driver failed to check map error messages

Reported-by: Johnny Bieren <jbieren@redhat.com>
Tested-by: Johnny Bieren <jbieren@redhat.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/block/cciss.c

index 27d613795653bd39c38d49f68a983b325f57b470..8e1a4554951c0d4f9374bb63d0cddb83c2a210d0 100644 (file)
@@ -348,7 +348,7 @@ static void cciss_unmap_sg_chain_block(ctlr_info_t *h, CommandList_struct *c)
        pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
 }
 
-static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
+static int cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
        SGDescriptor_struct *chain_block, int len)
 {
        SGDescriptor_struct *chain_sg;
@@ -359,8 +359,16 @@ static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
        chain_sg->Len = len;
        temp64.val = pci_map_single(h->pdev, chain_block, len,
                                PCI_DMA_TODEVICE);
+       if (dma_mapping_error(&h->pdev->dev, temp64.val)) {
+               dev_warn(&h->pdev->dev,
+                       "%s: error mapping chain block for DMA\n",
+                       __func__);
+               return -1;
+       }
        chain_sg->Addr.lower = temp64.val32.lower;
        chain_sg->Addr.upper = temp64.val32.upper;
+
+       return 0;
 }
 
 #include "cciss_scsi.c"                /* For SCSI tape support */
@@ -3369,15 +3377,31 @@ static void do_cciss_request(struct request_queue *q)
                temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
                                                tmp_sg[i].offset,
                                                tmp_sg[i].length, dir);
+               if (dma_mapping_error(&h->pdev->dev, temp64.val)) {
+                       dev_warn(&h->pdev->dev,
+                               "%s: error mapping page for DMA\n", __func__);
+                       creq->errors = make_status_bytes(SAM_STAT_GOOD,
+                                                       0, DRIVER_OK,
+                                                       DID_SOFT_ERROR);
+                       cmd_free(h, c);
+                       return;
+               }
                curr_sg[sg_index].Addr.lower = temp64.val32.lower;
                curr_sg[sg_index].Addr.upper = temp64.val32.upper;
                curr_sg[sg_index].Ext = 0;  /* we are not chaining */
                ++sg_index;
        }
-       if (chained)
-               cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
+       if (chained) {
+               if (cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
                        (seg - (h->max_cmd_sgentries - 1)) *
-                               sizeof(SGDescriptor_struct));
+                               sizeof(SGDescriptor_struct))) {
+                       creq->errors = make_status_bytes(SAM_STAT_GOOD,
+                                                       0, DRIVER_OK,
+                                                       DID_SOFT_ERROR);
+                       cmd_free(h, c);
+                       return;
+               }
+       }
 
        /* track how many SG entries we are using */
        if (seg > h->maxSG)