Skip to content

Commit

Permalink
[SCSI] buslogic: Added check for DMA mapping errors
Browse files Browse the repository at this point in the history
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 <[email protected]>
Tested-by: Tetsuo Handa <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
  • Loading branch information
hikerockies authored and James Bottomley committed Oct 25, 2013
1 parent 5ae3034 commit eeceec9
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions drivers/scsi/BusLogic.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
*/

#define blogic_drvr_version "2.1.16"
#define blogic_drvr_date "18 July 2002"
#define blogic_drvr_version "2.1.17"
#define blogic_drvr_date "12 September 2013"

#include <linux/module.h>
#include <linux/init.h>
Expand Down Expand Up @@ -311,12 +311,14 @@ static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
caller.
*/

static void blogic_dealloc_ccb(struct blogic_ccb *ccb)
static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
{
struct blogic_adapter *adapter = ccb->adapter;

scsi_dma_unmap(ccb->command);
pci_unmap_single(adapter->pci_device, ccb->sensedata,
if (ccb->command != NULL)
scsi_dma_unmap(ccb->command);
if (dma_unmap)
pci_unmap_single(adapter->pci_device, ccb->sensedata,
ccb->sense_datalen, PCI_DMA_FROMDEVICE);

ccb->command = NULL;
Expand Down Expand Up @@ -2762,8 +2764,8 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
/*
Place CCB back on the Host Adapter's free list.
*/
blogic_dealloc_ccb(ccb);
#if 0 /* this needs to be redone different for new EH */
blogic_dealloc_ccb(ccb, 1);
#if 0 /* this needs to be redone different for new EH */
/*
Bus Device Reset CCBs have the command field
non-NULL only when a Bus Device Reset was requested
Expand Down Expand Up @@ -2791,7 +2793,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
if (ccb->status == BLOGIC_CCB_RESET &&
ccb->tgt_id == tgt_id) {
command = ccb->command;
blogic_dealloc_ccb(ccb);
blogic_dealloc_ccb(ccb, 1);
adapter->active_cmds[tgt_id]--;
command->result = DID_RESET << 16;
command->scsi_done(command);
Expand Down Expand Up @@ -2862,7 +2864,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
/*
Place CCB back on the Host Adapter's free list.
*/
blogic_dealloc_ccb(ccb);
blogic_dealloc_ccb(ccb, 1);
/*
Call the SCSI Command Completion Routine.
*/
Expand Down Expand Up @@ -3034,6 +3036,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
int buflen = scsi_bufflen(command);
int count;
struct blogic_ccb *ccb;
dma_addr_t sense_buf;

/*
SCSI REQUEST_SENSE commands will be executed automatically by the
Expand Down Expand Up @@ -3179,10 +3182,17 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
}
memcpy(ccb->cdb, cdb, cdblen);
ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
ccb->sensedata = pci_map_single(adapter->pci_device,
ccb->command = command;
sense_buf = pci_map_single(adapter->pci_device,
command->sense_buffer, ccb->sense_datalen,
PCI_DMA_FROMDEVICE);
ccb->command = command;
if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
blogic_err("DMA mapping for sense data buffer failed\n",
adapter);
blogic_dealloc_ccb(ccb, 0);
return SCSI_MLQUEUE_HOST_BUSY;
}
ccb->sensedata = sense_buf;
command->scsi_done = comp_cb;
if (blogic_multimaster_type(adapter)) {
/*
Expand All @@ -3203,7 +3213,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
ccb)) {
blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter);
blogic_dealloc_ccb(ccb);
blogic_dealloc_ccb(ccb, 1);
command->result = DID_ERROR << 16;
command->scsi_done(command);
}
Expand Down Expand Up @@ -3337,7 +3347,7 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)

for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
if (ccb->status == BLOGIC_CCB_ACTIVE)
blogic_dealloc_ccb(ccb);
blogic_dealloc_ccb(ccb, 1);
/*
* Wait a few seconds between the Host Adapter Hard Reset which
* initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
Expand Down

0 comments on commit eeceec9

Please sign in to comment.