[SCSI] fix 3ware raid emulated commands
The 3ware emulated commands all expect they are executing in the use_sg == 0 case, which isn't true either in the block layer rework or an SG_IO ioctl. Fix this by adding the correct kmapping of the first element in the sg list. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
f189c5cb8d
commit
c9d297c543
|
@ -1499,22 +1499,43 @@ static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
|
||||||
return 0;
|
return 0;
|
||||||
} /* End tw_scsiop_inquiry() */
|
} /* End tw_scsiop_inquiry() */
|
||||||
|
|
||||||
|
static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
|
||||||
|
void *data, unsigned int len)
|
||||||
|
{
|
||||||
|
struct scsi_cmnd *cmd = tw_dev->srb[request_id];
|
||||||
|
void *buf;
|
||||||
|
unsigned int transfer_len;
|
||||||
|
|
||||||
|
if (cmd->use_sg) {
|
||||||
|
struct scatterlist *sg =
|
||||||
|
(struct scatterlist *)cmd->request_buffer;
|
||||||
|
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
|
||||||
|
transfer_len = min(sg->length, len);
|
||||||
|
} else {
|
||||||
|
buf = cmd->request_buffer;
|
||||||
|
transfer_len = min(cmd->request_bufflen, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, data, transfer_len);
|
||||||
|
|
||||||
|
if (cmd->use_sg) {
|
||||||
|
struct scatterlist *sg;
|
||||||
|
|
||||||
|
sg = (struct scatterlist *)cmd->request_buffer;
|
||||||
|
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This function is called by the isr to complete an inquiry command */
|
/* This function is called by the isr to complete an inquiry command */
|
||||||
static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
|
static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||||
{
|
{
|
||||||
unsigned char *is_unit_present;
|
unsigned char *is_unit_present;
|
||||||
unsigned char *request_buffer;
|
unsigned char request_buffer[36];
|
||||||
TW_Param *param;
|
TW_Param *param;
|
||||||
|
|
||||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
|
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
|
||||||
|
|
||||||
/* Fill request buffer */
|
memset(request_buffer, 0, sizeof(request_buffer));
|
||||||
if (tw_dev->srb[request_id]->request_buffer == NULL) {
|
|
||||||
printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
request_buffer = tw_dev->srb[request_id]->request_buffer;
|
|
||||||
memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
|
|
||||||
request_buffer[0] = TYPE_DISK; /* Peripheral device type */
|
request_buffer[0] = TYPE_DISK; /* Peripheral device type */
|
||||||
request_buffer[1] = 0; /* Device type modifier */
|
request_buffer[1] = 0; /* Device type modifier */
|
||||||
request_buffer[2] = 0; /* No ansi/iso compliance */
|
request_buffer[2] = 0; /* No ansi/iso compliance */
|
||||||
|
@ -1522,6 +1543,8 @@ static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_i
|
||||||
memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
|
memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
|
||||||
sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
|
sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
|
||||||
memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
|
memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
|
||||||
|
tw_transfer_internal(tw_dev, request_id, request_buffer,
|
||||||
|
sizeof(request_buffer));
|
||||||
|
|
||||||
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
|
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
|
||||||
if (param == NULL) {
|
if (param == NULL) {
|
||||||
|
@ -1612,7 +1635,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
|
||||||
{
|
{
|
||||||
TW_Param *param;
|
TW_Param *param;
|
||||||
unsigned char *flags;
|
unsigned char *flags;
|
||||||
unsigned char *request_buffer;
|
unsigned char request_buffer[8];
|
||||||
|
|
||||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
|
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
|
||||||
|
|
||||||
|
@ -1622,8 +1645,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
flags = (char *)&(param->data[0]);
|
flags = (char *)&(param->data[0]);
|
||||||
request_buffer = tw_dev->srb[request_id]->buffer;
|
memset(request_buffer, 0, sizeof(request_buffer));
|
||||||
memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
|
|
||||||
|
|
||||||
request_buffer[0] = 0xf; /* mode data length */
|
request_buffer[0] = 0xf; /* mode data length */
|
||||||
request_buffer[1] = 0; /* default medium type */
|
request_buffer[1] = 0; /* default medium type */
|
||||||
|
@ -1635,6 +1657,8 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
|
||||||
request_buffer[6] = 0x4; /* WCE on */
|
request_buffer[6] = 0x4; /* WCE on */
|
||||||
else
|
else
|
||||||
request_buffer[6] = 0x0; /* WCE off */
|
request_buffer[6] = 0x0; /* WCE off */
|
||||||
|
tw_transfer_internal(tw_dev, request_id, request_buffer,
|
||||||
|
sizeof(request_buffer));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* End tw_scsiop_mode_sense_complete() */
|
} /* End tw_scsiop_mode_sense_complete() */
|
||||||
|
@ -1701,17 +1725,12 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
|
||||||
{
|
{
|
||||||
unsigned char *param_data;
|
unsigned char *param_data;
|
||||||
u32 capacity;
|
u32 capacity;
|
||||||
char *buff;
|
char buff[8];
|
||||||
TW_Param *param;
|
TW_Param *param;
|
||||||
|
|
||||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
|
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
|
||||||
|
|
||||||
buff = tw_dev->srb[request_id]->request_buffer;
|
memset(buff, 0, sizeof(buff));
|
||||||
if (buff == NULL) {
|
|
||||||
printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
|
|
||||||
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
|
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
|
||||||
if (param == NULL) {
|
if (param == NULL) {
|
||||||
printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
|
printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
|
||||||
|
@ -1739,6 +1758,8 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
|
||||||
buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
|
buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
|
||||||
buff[7] = TW_BLOCK_SIZE & 0xff;
|
buff[7] = TW_BLOCK_SIZE & 0xff;
|
||||||
|
|
||||||
|
tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* End tw_scsiop_read_capacity_complete() */
|
} /* End tw_scsiop_read_capacity_complete() */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue