aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/3w-xxxx.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2005-06-28 10:18:21 -0400
committerJames Bottomley <jejb@titanic.(none)>2005-08-28 12:34:11 -0400
commitc9d297c543f379a27a34082070ed03a8ef846fc2 (patch)
tree4dcc96b31a31a6e7fbc82de31346f395fe78cb0b /drivers/scsi/3w-xxxx.c
parentf189c5cb8ddde0c01838f2b3bc7650e86c097a14 (diff)
[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>
Diffstat (limited to 'drivers/scsi/3w-xxxx.c')
-rw-r--r--drivers/scsi/3w-xxxx.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 973c51fb0fe2..ae9e0203e9de 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1499,22 +1499,43 @@ static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1499 return 0; 1499 return 0;
1500} /* End tw_scsiop_inquiry() */ 1500} /* End tw_scsiop_inquiry() */
1501 1501
1502static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1503 void *data, unsigned int len)
1504{
1505 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1506 void *buf;
1507 unsigned int transfer_len;
1508
1509 if (cmd->use_sg) {
1510 struct scatterlist *sg =
1511 (struct scatterlist *)cmd->request_buffer;
1512 buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
1513 transfer_len = min(sg->length, len);
1514 } else {
1515 buf = cmd->request_buffer;
1516 transfer_len = min(cmd->request_bufflen, len);
1517 }
1518
1519 memcpy(buf, data, transfer_len);
1520
1521 if (cmd->use_sg) {
1522 struct scatterlist *sg;
1523
1524 sg = (struct scatterlist *)cmd->request_buffer;
1525 kunmap_atomic(buf - sg->offset, KM_IRQ0);
1526 }
1527}
1528
1502/* This function is called by the isr to complete an inquiry command */ 1529/* This function is called by the isr to complete an inquiry command */
1503static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id) 1530static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1504{ 1531{
1505 unsigned char *is_unit_present; 1532 unsigned char *is_unit_present;
1506 unsigned char *request_buffer; 1533 unsigned char request_buffer[36];
1507 TW_Param *param; 1534 TW_Param *param;
1508 1535
1509 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n"); 1536 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1510 1537
1511 /* Fill request buffer */ 1538 memset(request_buffer, 0, sizeof(request_buffer));
1512 if (tw_dev->srb[request_id]->request_buffer == NULL) {
1513 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
1514 return 1;
1515 }
1516 request_buffer = tw_dev->srb[request_id]->request_buffer;
1517 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
1518 request_buffer[0] = TYPE_DISK; /* Peripheral device type */ 1539 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
1519 request_buffer[1] = 0; /* Device type modifier */ 1540 request_buffer[1] = 0; /* Device type modifier */
1520 request_buffer[2] = 0; /* No ansi/iso compliance */ 1541 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
1522 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */ 1543 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
1523 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id); 1544 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1524 memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3); 1545 memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1546 tw_transfer_internal(tw_dev, request_id, request_buffer,
1547 sizeof(request_buffer));
1525 1548
1526 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; 1549 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1527 if (param == NULL) { 1550 if (param == NULL) {
@@ -1612,7 +1635,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
1612{ 1635{
1613 TW_Param *param; 1636 TW_Param *param;
1614 unsigned char *flags; 1637 unsigned char *flags;
1615 unsigned char *request_buffer; 1638 unsigned char request_buffer[8];
1616 1639
1617 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n"); 1640 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1618 1641
@@ -1622,8 +1645,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
1622 return 1; 1645 return 1;
1623 } 1646 }
1624 flags = (char *)&(param->data[0]); 1647 flags = (char *)&(param->data[0]);
1625 request_buffer = tw_dev->srb[request_id]->buffer; 1648 memset(request_buffer, 0, sizeof(request_buffer));
1626 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
1627 1649
1628 request_buffer[0] = 0xf; /* mode data length */ 1650 request_buffer[0] = 0xf; /* mode data length */
1629 request_buffer[1] = 0; /* default medium type */ 1651 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
1635 request_buffer[6] = 0x4; /* WCE on */ 1657 request_buffer[6] = 0x4; /* WCE on */
1636 else 1658 else
1637 request_buffer[6] = 0x0; /* WCE off */ 1659 request_buffer[6] = 0x0; /* WCE off */
1660 tw_transfer_internal(tw_dev, request_id, request_buffer,
1661 sizeof(request_buffer));
1638 1662
1639 return 0; 1663 return 0;
1640} /* End tw_scsiop_mode_sense_complete() */ 1664} /* End tw_scsiop_mode_sense_complete() */
@@ -1701,17 +1725,12 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
1701{ 1725{
1702 unsigned char *param_data; 1726 unsigned char *param_data;
1703 u32 capacity; 1727 u32 capacity;
1704 char *buff; 1728 char buff[8];
1705 TW_Param *param; 1729 TW_Param *param;
1706 1730
1707 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n"); 1731 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1708 1732
1709 buff = tw_dev->srb[request_id]->request_buffer; 1733 memset(buff, 0, sizeof(buff));
1710 if (buff == NULL) {
1711 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
1712 return 1;
1713 }
1714 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
1715 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; 1734 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1716 if (param == NULL) { 1735 if (param == NULL) {
1717 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n"); 1736 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
1739 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff; 1758 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1740 buff[7] = TW_BLOCK_SIZE & 0xff; 1759 buff[7] = TW_BLOCK_SIZE & 0xff;
1741 1760
1761 tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1762
1742 return 0; 1763 return 0;
1743} /* End tw_scsiop_read_capacity_complete() */ 1764} /* End tw_scsiop_read_capacity_complete() */
1744 1765