mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
[SCSI] fix up request buffer reference in various scsi drivers
Various scsi drivers use scsi_cmnd.buffer and scsi_cmnd.bufflen in their queuecommand functions. Those fields are internal storage for the midlayer only and are used to restore the original payload after request_buffer and request_bufflen have been overwritten for EH. Using the buffer and bufflen fields means they do very broken things in error handling. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
e4a082c7c1
commit
5d5ff44fe6
@ -578,7 +578,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
|
|||||||
|
|
||||||
if (cmd->use_sg) {
|
if (cmd->use_sg) {
|
||||||
pci_unmap_sg(ctlr->pdev,
|
pci_unmap_sg(ctlr->pdev,
|
||||||
cmd->buffer, cmd->use_sg,
|
cmd->request_buffer, cmd->use_sg,
|
||||||
cmd->sc_data_direction);
|
cmd->sc_data_direction);
|
||||||
}
|
}
|
||||||
else if (cmd->request_bufflen) {
|
else if (cmd->request_bufflen) {
|
||||||
@ -1210,7 +1210,7 @@ cciss_scatter_gather(struct pci_dev *pdev,
|
|||||||
struct scsi_cmnd *cmd)
|
struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
unsigned int use_sg, nsegs=0, len;
|
unsigned int use_sg, nsegs=0, len;
|
||||||
struct scatterlist *scatter = (struct scatterlist *) cmd->buffer;
|
struct scatterlist *scatter = (struct scatterlist *) cmd->request_buffer;
|
||||||
__u64 addr64;
|
__u64 addr64;
|
||||||
|
|
||||||
/* is it just one virtual address? */
|
/* is it just one virtual address? */
|
||||||
@ -1232,7 +1232,7 @@ cciss_scatter_gather(struct pci_dev *pdev,
|
|||||||
} /* else, must be a list of virtual addresses.... */
|
} /* else, must be a list of virtual addresses.... */
|
||||||
else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */
|
else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */
|
||||||
|
|
||||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg,
|
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg,
|
||||||
cmd->sc_data_direction);
|
cmd->sc_data_direction);
|
||||||
|
|
||||||
for (nsegs=0; nsegs < use_sg; nsegs++) {
|
for (nsegs=0; nsegs < use_sg; nsegs++) {
|
||||||
|
@ -1388,7 +1388,7 @@ static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
|
|||||||
if (cmd->use_sg == 0)
|
if (cmd->use_sg == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
||||||
|
|
||||||
if (use_sg == 0) {
|
if (use_sg == 0) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
|
||||||
|
@ -1286,7 +1286,7 @@ static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
|
|||||||
if (cmd->use_sg == 0)
|
if (cmd->use_sg == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
||||||
|
|
||||||
if (use_sg == 0) {
|
if (use_sg == 0) {
|
||||||
printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
|
printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
|
||||||
|
@ -296,7 +296,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (cmd->use_sg) {
|
if (cmd->use_sg) {
|
||||||
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
|
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
|
||||||
cmd->SCp.buffers_residual = cmd->use_sg - 1;
|
cmd->SCp.buffers_residual = cmd->use_sg - 1;
|
||||||
cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
|
cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
|
||||||
cmd->SCp.buffer->offset;
|
cmd->SCp.buffer->offset;
|
||||||
|
@ -961,7 +961,7 @@ static void io_callback(void *context, struct fib * fibptr)
|
|||||||
|
|
||||||
if(scsicmd->use_sg)
|
if(scsicmd->use_sg)
|
||||||
pci_unmap_sg(dev->pdev,
|
pci_unmap_sg(dev->pdev,
|
||||||
(struct scatterlist *)scsicmd->buffer,
|
(struct scatterlist *)scsicmd->request_buffer,
|
||||||
scsicmd->use_sg,
|
scsicmd->use_sg,
|
||||||
scsicmd->sc_data_direction);
|
scsicmd->sc_data_direction);
|
||||||
else if(scsicmd->request_bufflen)
|
else if(scsicmd->request_bufflen)
|
||||||
@ -1919,7 +1919,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
|||||||
|
|
||||||
if(scsicmd->use_sg)
|
if(scsicmd->use_sg)
|
||||||
pci_unmap_sg(dev->pdev,
|
pci_unmap_sg(dev->pdev,
|
||||||
(struct scatterlist *)scsicmd->buffer,
|
(struct scatterlist *)scsicmd->request_buffer,
|
||||||
scsicmd->use_sg,
|
scsicmd->use_sg,
|
||||||
scsicmd->sc_data_direction);
|
scsicmd->sc_data_direction);
|
||||||
else if(scsicmd->request_bufflen)
|
else if(scsicmd->request_bufflen)
|
||||||
|
@ -473,7 +473,7 @@ go_42:
|
|||||||
*/
|
*/
|
||||||
if (workreq->use_sg) {
|
if (workreq->use_sg) {
|
||||||
pci_unmap_sg(dev->pdev,
|
pci_unmap_sg(dev->pdev,
|
||||||
(struct scatterlist *)workreq->buffer,
|
(struct scatterlist *)workreq->request_buffer,
|
||||||
workreq->use_sg,
|
workreq->use_sg,
|
||||||
workreq->sc_data_direction);
|
workreq->sc_data_direction);
|
||||||
} else if (workreq->request_bufflen &&
|
} else if (workreq->request_bufflen &&
|
||||||
|
@ -2542,7 +2542,7 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
|
|||||||
gdth_ha_str *ha;
|
gdth_ha_str *ha;
|
||||||
char *address;
|
char *address;
|
||||||
|
|
||||||
cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
|
cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen;
|
||||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||||
|
|
||||||
if (scp->use_sg) {
|
if (scp->use_sg) {
|
||||||
|
@ -370,7 +370,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (cmd->use_sg) {
|
if (cmd->use_sg) {
|
||||||
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
|
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
|
||||||
cmd->SCp.buffers_residual = cmd->use_sg - 1;
|
cmd->SCp.buffers_residual = cmd->use_sg - 1;
|
||||||
cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
|
cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
|
||||||
cmd->SCp.this_residual = cmd->SCp.buffer->length;
|
cmd->SCp.this_residual = cmd->SCp.buffer->length;
|
||||||
|
@ -4364,7 +4364,7 @@ ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
|
|||||||
|
|
||||||
METHOD_TRACE("ips_rdcap", 1);
|
METHOD_TRACE("ips_rdcap", 1);
|
||||||
|
|
||||||
if (scb->scsi_cmd->bufflen < 8)
|
if (scb->scsi_cmd->request_bufflen < 8)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
cap.lba =
|
cap.lba =
|
||||||
|
@ -2310,7 +2310,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
qc->nbytes = cmd->bufflen;
|
qc->nbytes = cmd->request_bufflen;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2500,7 +2500,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
|
|||||||
* TODO: find out if we need to do more here to
|
* TODO: find out if we need to do more here to
|
||||||
* cover scatter/gather case.
|
* cover scatter/gather case.
|
||||||
*/
|
*/
|
||||||
qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
|
qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
|
|||||||
* filter the internal and ioctl commands
|
* filter the internal and ioctl commands
|
||||||
*/
|
*/
|
||||||
if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) {
|
if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) {
|
||||||
return cmd->buffer;
|
return cmd->request_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4493,7 +4493,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
|
|||||||
scmd->device = sdev;
|
scmd->device = sdev;
|
||||||
|
|
||||||
scmd->device->host = adapter->host;
|
scmd->device->host = adapter->host;
|
||||||
scmd->buffer = (void *)scb;
|
scmd->request_buffer = (void *)scb;
|
||||||
scmd->cmnd[0] = MEGA_INTERNAL_CMD;
|
scmd->cmnd[0] = MEGA_INTERNAL_CMD;
|
||||||
|
|
||||||
scb->state |= SCB_ACTIVE;
|
scb->state |= SCB_ACTIVE;
|
||||||
|
@ -529,7 +529,7 @@ static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
|
|||||||
{
|
{
|
||||||
switch(cmd->__data_mapped) {
|
switch(cmd->__data_mapped) {
|
||||||
case 2:
|
case 2:
|
||||||
dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
|
dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
|
||||||
cmd->sc_data_direction);
|
cmd->sc_data_direction);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -564,7 +564,7 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
|
|||||||
if (cmd->use_sg == 0)
|
if (cmd->use_sg == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
|
use_sg = dma_map_sg(dev, cmd->request_buffer, cmd->use_sg,
|
||||||
cmd->sc_data_direction);
|
cmd->sc_data_direction);
|
||||||
cmd->__data_mapped = 2;
|
cmd->__data_mapped = 2;
|
||||||
cmd->__data_mapping = use_sg;
|
cmd->__data_mapping = use_sg;
|
||||||
@ -7697,7 +7697,7 @@ static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd)
|
|||||||
if (!use_sg)
|
if (!use_sg)
|
||||||
segment = ncr_scatter_no_sglist(np, cp, cmd);
|
segment = ncr_scatter_no_sglist(np, cp, cmd);
|
||||||
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
|
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
|
||||||
struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
|
struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer;
|
||||||
struct scr_tblmove *data;
|
struct scr_tblmove *data;
|
||||||
|
|
||||||
if (use_sg > MAX_SCATTER) {
|
if (use_sg > MAX_SCATTER) {
|
||||||
|
@ -1636,7 +1636,7 @@ static void nsp32_scsi_done(struct scsi_cmnd *SCpnt)
|
|||||||
|
|
||||||
if (SCpnt->use_sg) {
|
if (SCpnt->use_sg) {
|
||||||
pci_unmap_sg(data->Pci,
|
pci_unmap_sg(data->Pci,
|
||||||
(struct scatterlist *)SCpnt->buffer,
|
(struct scatterlist *)SCpnt->request_buffer,
|
||||||
SCpnt->use_sg, SCpnt->sc_data_direction);
|
SCpnt->use_sg, SCpnt->sc_data_direction);
|
||||||
} else {
|
} else {
|
||||||
pci_unmap_single(data->Pci,
|
pci_unmap_single(data->Pci,
|
||||||
|
@ -891,7 +891,7 @@ static struct block_device_operations sd_fops = {
|
|||||||
static void sd_rw_intr(struct scsi_cmnd * SCpnt)
|
static void sd_rw_intr(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
int result = SCpnt->result;
|
int result = SCpnt->result;
|
||||||
int this_count = SCpnt->bufflen;
|
int this_count = SCpnt->request_bufflen;
|
||||||
int good_bytes = (result == 0 ? this_count : 0);
|
int good_bytes = (result == 0 ? this_count : 0);
|
||||||
sector_t block_sectors = 1;
|
sector_t block_sectors = 1;
|
||||||
u64 first_err_block;
|
u64 first_err_block;
|
||||||
|
@ -217,7 +217,7 @@ int sr_media_change(struct cdrom_device_info *cdi, int slot)
|
|||||||
static void rw_intr(struct scsi_cmnd * SCpnt)
|
static void rw_intr(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
int result = SCpnt->result;
|
int result = SCpnt->result;
|
||||||
int this_count = SCpnt->bufflen;
|
int this_count = SCpnt->request_bufflen;
|
||||||
int good_bytes = (result == 0 ? this_count : 0);
|
int good_bytes = (result == 0 ? this_count : 0);
|
||||||
int block_sectors = 0;
|
int block_sectors = 0;
|
||||||
long error_sector;
|
long error_sector;
|
||||||
|
@ -156,7 +156,7 @@ static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
|
|||||||
|
|
||||||
switch(SYM_UCMD_PTR(cmd)->data_mapped) {
|
switch(SYM_UCMD_PTR(cmd)->data_mapped) {
|
||||||
case 2:
|
case 2:
|
||||||
pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
|
pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
pci_unmap_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
|
pci_unmap_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
|
||||||
@ -186,7 +186,7 @@ static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
|
|||||||
int use_sg;
|
int use_sg;
|
||||||
int dma_dir = cmd->sc_data_direction;
|
int dma_dir = cmd->sc_data_direction;
|
||||||
|
|
||||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
|
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
|
||||||
if (use_sg > 0) {
|
if (use_sg > 0) {
|
||||||
SYM_UCMD_PTR(cmd)->data_mapped = 2;
|
SYM_UCMD_PTR(cmd)->data_mapped = 2;
|
||||||
SYM_UCMD_PTR(cmd)->data_mapping = use_sg;
|
SYM_UCMD_PTR(cmd)->data_mapping = use_sg;
|
||||||
@ -376,7 +376,7 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
|
|||||||
if (!use_sg)
|
if (!use_sg)
|
||||||
segment = sym_scatter_no_sglist(np, cp, cmd);
|
segment = sym_scatter_no_sglist(np, cp, cmd);
|
||||||
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
|
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
|
||||||
struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
|
struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer;
|
||||||
struct sym_tcb *tp = &np->target[cp->target];
|
struct sym_tcb *tp = &np->target[cp->target];
|
||||||
struct sym_tblmove *data;
|
struct sym_tblmove *data;
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ static void mts_do_sg (struct urb* transfer, struct pt_regs *regs)
|
|||||||
mts_transfer_cleanup(transfer);
|
mts_transfer_cleanup(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
sg = context->srb->buffer;
|
sg = context->srb->request_buffer;
|
||||||
context->fragment++;
|
context->fragment++;
|
||||||
mts_int_submit_urb(transfer,
|
mts_int_submit_urb(transfer,
|
||||||
context->data_pipe,
|
context->data_pipe,
|
||||||
@ -549,19 +549,19 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc )
|
|||||||
desc->context.fragment = 0;
|
desc->context.fragment = 0;
|
||||||
|
|
||||||
if (!srb->use_sg) {
|
if (!srb->use_sg) {
|
||||||
if ( !srb->bufflen ){
|
if ( !srb->request_bufflen ){
|
||||||
desc->context.data = NULL;
|
desc->context.data = NULL;
|
||||||
desc->context.data_length = 0;
|
desc->context.data_length = 0;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
desc->context.data = srb->buffer;
|
desc->context.data = srb->request_buffer;
|
||||||
desc->context.data_length = srb->bufflen;
|
desc->context.data_length = srb->request_bufflen;
|
||||||
MTS_DEBUG("length = %d or %d\n",
|
MTS_DEBUG("length = %d or %d\n",
|
||||||
srb->request_bufflen, srb->bufflen);
|
srb->request_bufflen, srb->bufflen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MTS_DEBUG("Using scatter/gather\n");
|
MTS_DEBUG("Using scatter/gather\n");
|
||||||
sg = srb->buffer;
|
sg = srb->request_buffer;
|
||||||
desc->context.data = page_address(sg[0].page) + sg[0].offset;
|
desc->context.data = page_address(sg[0].page) + sg[0].offset;
|
||||||
desc->context.data_length = sg[0].length;
|
desc->context.data_length = sg[0].length;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user