diff options
Diffstat (limited to 'drivers/scsi/3w-xxxx.c')
-rw-r--r-- | drivers/scsi/3w-xxxx.c | 57 |
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 | ||
1502 | static 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 */ |
1503 | static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id) | 1530 | static 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 | ||