aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/BusLogic.c
diff options
context:
space:
mode:
authorKhalid Aziz <khalid.aziz@oracle.com>2013-09-13 15:44:06 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-10-25 04:57:57 -0400
commiteeceec904031f859d3f348ab38fe4329c91f7550 (patch)
tree45ea2e141b3b5074bb0e25adb57b4fd9038805b6 /drivers/scsi/BusLogic.c
parent5ae303443094ab49fca41cf331d5af189995bead (diff)
[SCSI] buslogic: Added check for DMA mapping errors
Added check for DMA mapping errors for request sense data buffer. Checking for mapping error can avoid potential wild writes. This patch was prompted by the warning from dma_unmap when kernel is compiled with CONFIG_DMA_API_DEBUG. Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com> Tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/BusLogic.c')
-rw-r--r--drivers/scsi/BusLogic.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 757eb0716d45..972f8176665f 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -26,8 +26,8 @@
26 26
27*/ 27*/
28 28
29#define blogic_drvr_version "2.1.16" 29#define blogic_drvr_version "2.1.17"
30#define blogic_drvr_date "18 July 2002" 30#define blogic_drvr_date "12 September 2013"
31 31
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/init.h> 33#include <linux/init.h>
@@ -311,12 +311,14 @@ static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
311 caller. 311 caller.
312*/ 312*/
313 313
314static void blogic_dealloc_ccb(struct blogic_ccb *ccb) 314static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
315{ 315{
316 struct blogic_adapter *adapter = ccb->adapter; 316 struct blogic_adapter *adapter = ccb->adapter;
317 317
318 scsi_dma_unmap(ccb->command); 318 if (ccb->command != NULL)
319 pci_unmap_single(adapter->pci_device, ccb->sensedata, 319 scsi_dma_unmap(ccb->command);
320 if (dma_unmap)
321 pci_unmap_single(adapter->pci_device, ccb->sensedata,
320 ccb->sense_datalen, PCI_DMA_FROMDEVICE); 322 ccb->sense_datalen, PCI_DMA_FROMDEVICE);
321 323
322 ccb->command = NULL; 324 ccb->command = NULL;
@@ -2762,8 +2764,8 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
2762 /* 2764 /*
2763 Place CCB back on the Host Adapter's free list. 2765 Place CCB back on the Host Adapter's free list.
2764 */ 2766 */
2765 blogic_dealloc_ccb(ccb); 2767 blogic_dealloc_ccb(ccb, 1);
2766#if 0 /* this needs to be redone different for new EH */ 2768#if 0 /* this needs to be redone different for new EH */
2767 /* 2769 /*
2768 Bus Device Reset CCBs have the command field 2770 Bus Device Reset CCBs have the command field
2769 non-NULL only when a Bus Device Reset was requested 2771 non-NULL only when a Bus Device Reset was requested
@@ -2791,7 +2793,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
2791 if (ccb->status == BLOGIC_CCB_RESET && 2793 if (ccb->status == BLOGIC_CCB_RESET &&
2792 ccb->tgt_id == tgt_id) { 2794 ccb->tgt_id == tgt_id) {
2793 command = ccb->command; 2795 command = ccb->command;
2794 blogic_dealloc_ccb(ccb); 2796 blogic_dealloc_ccb(ccb, 1);
2795 adapter->active_cmds[tgt_id]--; 2797 adapter->active_cmds[tgt_id]--;
2796 command->result = DID_RESET << 16; 2798 command->result = DID_RESET << 16;
2797 command->scsi_done(command); 2799 command->scsi_done(command);
@@ -2862,7 +2864,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
2862 /* 2864 /*
2863 Place CCB back on the Host Adapter's free list. 2865 Place CCB back on the Host Adapter's free list.
2864 */ 2866 */
2865 blogic_dealloc_ccb(ccb); 2867 blogic_dealloc_ccb(ccb, 1);
2866 /* 2868 /*
2867 Call the SCSI Command Completion Routine. 2869 Call the SCSI Command Completion Routine.
2868 */ 2870 */
@@ -3034,6 +3036,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
3034 int buflen = scsi_bufflen(command); 3036 int buflen = scsi_bufflen(command);
3035 int count; 3037 int count;
3036 struct blogic_ccb *ccb; 3038 struct blogic_ccb *ccb;
3039 dma_addr_t sense_buf;
3037 3040
3038 /* 3041 /*
3039 SCSI REQUEST_SENSE commands will be executed automatically by the 3042 SCSI REQUEST_SENSE commands will be executed automatically by the
@@ -3179,10 +3182,17 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
3179 } 3182 }
3180 memcpy(ccb->cdb, cdb, cdblen); 3183 memcpy(ccb->cdb, cdb, cdblen);
3181 ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE; 3184 ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
3182 ccb->sensedata = pci_map_single(adapter->pci_device, 3185 ccb->command = command;
3186 sense_buf = pci_map_single(adapter->pci_device,
3183 command->sense_buffer, ccb->sense_datalen, 3187 command->sense_buffer, ccb->sense_datalen,
3184 PCI_DMA_FROMDEVICE); 3188 PCI_DMA_FROMDEVICE);
3185 ccb->command = command; 3189 if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
3190 blogic_err("DMA mapping for sense data buffer failed\n",
3191 adapter);
3192 blogic_dealloc_ccb(ccb, 0);
3193 return SCSI_MLQUEUE_HOST_BUSY;
3194 }
3195 ccb->sensedata = sense_buf;
3186 command->scsi_done = comp_cb; 3196 command->scsi_done = comp_cb;
3187 if (blogic_multimaster_type(adapter)) { 3197 if (blogic_multimaster_type(adapter)) {
3188 /* 3198 /*
@@ -3203,7 +3213,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
3203 if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, 3213 if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
3204 ccb)) { 3214 ccb)) {
3205 blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter); 3215 blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter);
3206 blogic_dealloc_ccb(ccb); 3216 blogic_dealloc_ccb(ccb, 1);
3207 command->result = DID_ERROR << 16; 3217 command->result = DID_ERROR << 16;
3208 command->scsi_done(command); 3218 command->scsi_done(command);
3209 } 3219 }
@@ -3337,7 +3347,7 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
3337 3347
3338 for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all) 3348 for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3339 if (ccb->status == BLOGIC_CCB_ACTIVE) 3349 if (ccb->status == BLOGIC_CCB_ACTIVE)
3340 blogic_dealloc_ccb(ccb); 3350 blogic_dealloc_ccb(ccb, 1);
3341 /* 3351 /*
3342 * Wait a few seconds between the Host Adapter Hard Reset which 3352 * Wait a few seconds between the Host Adapter Hard Reset which
3343 * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some 3353 * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some