aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_ioctl.c46
-rw-r--r--drivers/scsi/scsi_lib.c94
-rw-r--r--drivers/scsi/sd.c5
-rw-r--r--drivers/scsi/sr.c2
4 files changed, 53 insertions, 94 deletions
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index f5bf5c07be91..5f399c9c68ee 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -88,25 +88,21 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
88static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, 88static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
89 int timeout, int retries) 89 int timeout, int retries)
90{ 90{
91 struct scsi_request *sreq;
92 int result; 91 int result;
93 struct scsi_sense_hdr sshdr; 92 struct scsi_sense_hdr sshdr;
93 char sense[SCSI_SENSE_BUFFERSIZE];
94 94
95 SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd)); 95 SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
96 96
97 sreq = scsi_allocate_request(sdev, GFP_KERNEL);
98 if (!sreq) {
99 printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
100 return -ENOMEM;
101 }
102 97
103 sreq->sr_data_direction = DMA_NONE; 98 memset(sense, 0, sizeof(*sense));
104 scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries); 99 result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
100 sense, timeout, retries);
105 101
106 SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", sreq->sr_result)); 102 SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", result));
107 103
108 if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && 104 if ((driver_byte(result) & DRIVER_SENSE) &&
109 (scsi_request_normalize_sense(sreq, &sshdr))) { 105 (scsi_normalize_sense(sense, sizeof(*sense), &sshdr))) {
110 switch (sshdr.sense_key) { 106 switch (sshdr.sense_key) {
111 case ILLEGAL_REQUEST: 107 case ILLEGAL_REQUEST:
112 if (cmd[0] == ALLOW_MEDIUM_REMOVAL) 108 if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
@@ -125,7 +121,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
125 case UNIT_ATTENTION: 121 case UNIT_ATTENTION:
126 if (sdev->removable) { 122 if (sdev->removable) {
127 sdev->changed = 1; 123 sdev->changed = 1;
128 sreq->sr_result = 0; /* This is no longer considered an error */ 124 result = 0; /* This is no longer considered an error */
129 break; 125 break;
130 } 126 }
131 default: /* Fall through for non-removable media */ 127 default: /* Fall through for non-removable media */
@@ -135,15 +131,13 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
135 sdev->channel, 131 sdev->channel,
136 sdev->id, 132 sdev->id,
137 sdev->lun, 133 sdev->lun,
138 sreq->sr_result); 134 result);
139 scsi_print_req_sense(" ", sreq); 135 __scsi_print_sense(" ", sense, sizeof(*sense));
140 break; 136 break;
141 } 137 }
142 } 138 }
143 139
144 result = sreq->sr_result;
145 SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n")); 140 SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
146 scsi_release_request(sreq);
147 return result; 141 return result;
148} 142}
149 143
@@ -208,8 +202,8 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
208{ 202{
209 char *buf; 203 char *buf;
210 unsigned char cmd[MAX_COMMAND_SIZE]; 204 unsigned char cmd[MAX_COMMAND_SIZE];
205 unsigned char sense[SCSI_SENSE_BUFFERSIZE];
211 char __user *cmd_in; 206 char __user *cmd_in;
212 struct scsi_request *sreq;
213 unsigned char opcode; 207 unsigned char opcode;
214 unsigned int inlen, outlen, cmdlen; 208 unsigned int inlen, outlen, cmdlen;
215 unsigned int needed, buf_needed; 209 unsigned int needed, buf_needed;
@@ -321,31 +315,23 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
321 break; 315 break;
322 } 316 }
323 317
324 sreq = scsi_allocate_request(sdev, GFP_KERNEL); 318 result = scsi_execute_req(sdev, cmd, data_direction, buf, needed,
325 if (!sreq) { 319 sense, timeout, retries);
326 result = -EINTR; 320
327 goto error;
328 }
329
330 sreq->sr_data_direction = data_direction;
331 scsi_wait_req(sreq, cmd, buf, needed, timeout, retries);
332
333 /* 321 /*
334 * If there was an error condition, pass the info back to the user. 322 * If there was an error condition, pass the info back to the user.
335 */ 323 */
336 result = sreq->sr_result;
337 if (result) { 324 if (result) {
338 int sb_len = sizeof(sreq->sr_sense_buffer); 325 int sb_len = sizeof(*sense);
339 326
340 sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len; 327 sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;
341 if (copy_to_user(cmd_in, sreq->sr_sense_buffer, sb_len)) 328 if (copy_to_user(cmd_in, sense, sb_len))
342 result = -EFAULT; 329 result = -EFAULT;
343 } else { 330 } else {
344 if (copy_to_user(cmd_in, buf, outlen)) 331 if (copy_to_user(cmd_in, buf, outlen))
345 result = -EFAULT; 332 result = -EFAULT;
346 } 333 }
347 334
348 scsi_release_request(sreq);
349error: 335error:
350 kfree(buf); 336 kfree(buf);
351 return result; 337 return result;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 278e0c99b2ae..3f3accd6cd46 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1615,7 +1615,7 @@ void scsi_exit_queue(void)
1615/** 1615/**
1616 * __scsi_mode_sense - issue a mode sense, falling back from 10 to 1616 * __scsi_mode_sense - issue a mode sense, falling back from 10 to
1617 * six bytes if necessary. 1617 * six bytes if necessary.
1618 * @sreq: SCSI request to fill in with the MODE_SENSE 1618 * @sdev: SCSI device to be queried
1619 * @dbd: set if mode sense will allow block descriptors to be returned 1619 * @dbd: set if mode sense will allow block descriptors to be returned
1620 * @modepage: mode page being requested 1620 * @modepage: mode page being requested
1621 * @buffer: request buffer (may not be smaller than eight bytes) 1621 * @buffer: request buffer (may not be smaller than eight bytes)
@@ -1623,26 +1623,38 @@ void scsi_exit_queue(void)
1623 * @timeout: command timeout 1623 * @timeout: command timeout
1624 * @retries: number of retries before failing 1624 * @retries: number of retries before failing
1625 * @data: returns a structure abstracting the mode header data 1625 * @data: returns a structure abstracting the mode header data
1626 * @sense: place to put sense data (or NULL if no sense to be collected).
1627 * must be SCSI_SENSE_BUFFERSIZE big.
1626 * 1628 *
1627 * Returns zero if unsuccessful, or the header offset (either 4 1629 * Returns zero if unsuccessful, or the header offset (either 4
1628 * or 8 depending on whether a six or ten byte command was 1630 * or 8 depending on whether a six or ten byte command was
1629 * issued) if successful. 1631 * issued) if successful.
1630 **/ 1632 **/
1631int 1633int
1632__scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage, 1634scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
1633 unsigned char *buffer, int len, int timeout, int retries, 1635 unsigned char *buffer, int len, int timeout, int retries,
1634 struct scsi_mode_data *data) { 1636 struct scsi_mode_data *data, char *sense) {
1635 unsigned char cmd[12]; 1637 unsigned char cmd[12];
1636 int use_10_for_ms; 1638 int use_10_for_ms;
1637 int header_length; 1639 int header_length;
1640 int result;
1641 char *sense_buffer = NULL;
1638 1642
1639 memset(data, 0, sizeof(*data)); 1643 memset(data, 0, sizeof(*data));
1640 memset(&cmd[0], 0, 12); 1644 memset(&cmd[0], 0, 12);
1641 cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */ 1645 cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
1642 cmd[2] = modepage; 1646 cmd[2] = modepage;
1643 1647
1648 if (!sense) {
1649 sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
1650 if (!sense_buffer) {
1651 dev_printk(KERN_ERR, &sdev->sdev_gendev, "failed to allocate sense buffer\n");
1652 return 0;
1653 }
1654 sense = sense_buffer;
1655 }
1644 retry: 1656 retry:
1645 use_10_for_ms = sreq->sr_device->use_10_for_ms; 1657 use_10_for_ms = sdev->use_10_for_ms;
1646 1658
1647 if (use_10_for_ms) { 1659 if (use_10_for_ms) {
1648 if (len < 8) 1660 if (len < 8)
@@ -1660,36 +1672,35 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
1660 header_length = 4; 1672 header_length = 4;
1661 } 1673 }
1662 1674
1663 sreq->sr_cmd_len = 0; 1675 memset(sense, 0, SCSI_SENSE_BUFFERSIZE);
1664 memset(sreq->sr_sense_buffer, 0, sizeof(sreq->sr_sense_buffer));
1665 sreq->sr_data_direction = DMA_FROM_DEVICE;
1666 1676
1667 memset(buffer, 0, len); 1677 memset(buffer, 0, len);
1668 1678
1669 scsi_wait_req(sreq, cmd, buffer, len, timeout, retries); 1679 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
1680 sense, timeout, retries);
1670 1681
1671 /* This code looks awful: what it's doing is making sure an 1682 /* This code looks awful: what it's doing is making sure an
1672 * ILLEGAL REQUEST sense return identifies the actual command 1683 * ILLEGAL REQUEST sense return identifies the actual command
1673 * byte as the problem. MODE_SENSE commands can return 1684 * byte as the problem. MODE_SENSE commands can return
1674 * ILLEGAL REQUEST if the code page isn't supported */ 1685 * ILLEGAL REQUEST if the code page isn't supported */
1675 1686
1676 if (use_10_for_ms && !scsi_status_is_good(sreq->sr_result) && 1687 if (use_10_for_ms && !scsi_status_is_good(result) &&
1677 (driver_byte(sreq->sr_result) & DRIVER_SENSE)) { 1688 (driver_byte(result) & DRIVER_SENSE)) {
1678 struct scsi_sense_hdr sshdr; 1689 struct scsi_sense_hdr sshdr;
1679 1690
1680 if (scsi_request_normalize_sense(sreq, &sshdr)) { 1691 if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) {
1681 if ((sshdr.sense_key == ILLEGAL_REQUEST) && 1692 if ((sshdr.sense_key == ILLEGAL_REQUEST) &&
1682 (sshdr.asc == 0x20) && (sshdr.ascq == 0)) { 1693 (sshdr.asc == 0x20) && (sshdr.ascq == 0)) {
1683 /* 1694 /*
1684 * Invalid command operation code 1695 * Invalid command operation code
1685 */ 1696 */
1686 sreq->sr_device->use_10_for_ms = 0; 1697 sdev->use_10_for_ms = 0;
1687 goto retry; 1698 goto retry;
1688 } 1699 }
1689 } 1700 }
1690 } 1701 }
1691 1702
1692 if(scsi_status_is_good(sreq->sr_result)) { 1703 if(scsi_status_is_good(result)) {
1693 data->header_length = header_length; 1704 data->header_length = header_length;
1694 if(use_10_for_ms) { 1705 if(use_10_for_ms) {
1695 data->length = buffer[0]*256 + buffer[1] + 2; 1706 data->length = buffer[0]*256 + buffer[1] + 2;
@@ -1706,73 +1717,34 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
1706 } 1717 }
1707 } 1718 }
1708 1719
1709 return sreq->sr_result; 1720 kfree(sense_buffer);
1710} 1721 return result;
1711EXPORT_SYMBOL(__scsi_mode_sense);
1712
1713/**
1714 * scsi_mode_sense - issue a mode sense, falling back from 10 to
1715 * six bytes if necessary.
1716 * @sdev: scsi device to send command to.
1717 * @dbd: set if mode sense will disable block descriptors in the return
1718 * @modepage: mode page being requested
1719 * @buffer: request buffer (may not be smaller than eight bytes)
1720 * @len: length of request buffer.
1721 * @timeout: command timeout
1722 * @retries: number of retries before failing
1723 *
1724 * Returns zero if unsuccessful, or the header offset (either 4
1725 * or 8 depending on whether a six or ten byte command was
1726 * issued) if successful.
1727 **/
1728int
1729scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
1730 unsigned char *buffer, int len, int timeout, int retries,
1731 struct scsi_mode_data *data)
1732{
1733 struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
1734 int ret;
1735
1736 if (!sreq)
1737 return -1;
1738
1739 ret = __scsi_mode_sense(sreq, dbd, modepage, buffer, len,
1740 timeout, retries, data);
1741
1742 scsi_release_request(sreq);
1743
1744 return ret;
1745} 1722}
1746EXPORT_SYMBOL(scsi_mode_sense); 1723EXPORT_SYMBOL(scsi_mode_sense);
1747 1724
1748int 1725int
1749scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries) 1726scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
1750{ 1727{
1751 struct scsi_request *sreq;
1752 char cmd[] = { 1728 char cmd[] = {
1753 TEST_UNIT_READY, 0, 0, 0, 0, 0, 1729 TEST_UNIT_READY, 0, 0, 0, 0, 0,
1754 }; 1730 };
1731 char sense[SCSI_SENSE_BUFFERSIZE];
1755 int result; 1732 int result;
1756 1733
1757 sreq = scsi_allocate_request(sdev, GFP_KERNEL); 1734 result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sense,
1758 if (!sreq) 1735 timeout, retries);
1759 return -ENOMEM;
1760
1761 sreq->sr_data_direction = DMA_NONE;
1762 scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
1763 1736
1764 if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && sdev->removable) { 1737 if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) {
1765 struct scsi_sense_hdr sshdr; 1738 struct scsi_sense_hdr sshdr;
1766 1739
1767 if ((scsi_request_normalize_sense(sreq, &sshdr)) && 1740 if ((scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE,
1741 &sshdr)) &&
1768 ((sshdr.sense_key == UNIT_ATTENTION) || 1742 ((sshdr.sense_key == UNIT_ATTENTION) ||
1769 (sshdr.sense_key == NOT_READY))) { 1743 (sshdr.sense_key == NOT_READY))) {
1770 sdev->changed = 1; 1744 sdev->changed = 1;
1771 sreq->sr_result = 0; 1745 result = 0;
1772 } 1746 }
1773 } 1747 }
1774 result = sreq->sr_result;
1775 scsi_release_request(sreq);
1776 return result; 1748 return result;
1777} 1749}
1778EXPORT_SYMBOL(scsi_test_unit_ready); 1750EXPORT_SYMBOL(scsi_test_unit_ready);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 0410e1bf109a..15c2039059c9 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1299,8 +1299,9 @@ static inline int
1299sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage, 1299sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
1300 unsigned char *buffer, int len, struct scsi_mode_data *data) 1300 unsigned char *buffer, int len, struct scsi_mode_data *data)
1301{ 1301{
1302 return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len, 1302 return scsi_mode_sense(SRpnt->sr_device, dbd, modepage, buffer, len,
1303 SD_TIMEOUT, SD_MAX_RETRIES, data); 1303 SD_TIMEOUT, SD_MAX_RETRIES, data,
1304 SRpnt->sr_sense_buffer);
1304} 1305}
1305 1306
1306/* 1307/*
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 2f259f249522..8cbe6e004187 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -817,7 +817,7 @@ static void get_capabilities(struct scsi_cd *cd)
817 817
818 /* ask for mode page 0x2a */ 818 /* ask for mode page 0x2a */
819 rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, 819 rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
820 SR_TIMEOUT, 3, &data); 820 SR_TIMEOUT, 3, &data, NULL);
821 821
822 if (!scsi_status_is_good(rc)) { 822 if (!scsi_status_is_good(rc)) {
823 /* failed, drive doesn't have capabilities mode page */ 823 /* failed, drive doesn't have capabilities mode page */