aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 42edf29223a..bdea26b56dc 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -293,8 +293,8 @@ EXPORT_SYMBOL(scsi_wait_req);
293 * @retries: number of times to retry request 293 * @retries: number of times to retry request
294 * @flags: or into request flags; 294 * @flags: or into request flags;
295 * 295 *
296 * scsi_execute_req returns the req->errors value which is the 296 * returns the req->errors value which is the the scsi_cmnd result
297 * the scsi_cmnd result field. 297 * field.
298 **/ 298 **/
299int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, 299int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
300 int data_direction, void *buffer, unsigned bufflen, 300 int data_direction, void *buffer, unsigned bufflen,
@@ -328,9 +328,31 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
328 328
329 return ret; 329 return ret;
330} 330}
331
332EXPORT_SYMBOL(scsi_execute); 331EXPORT_SYMBOL(scsi_execute);
333 332
333
334int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
335 int data_direction, void *buffer, unsigned bufflen,
336 struct scsi_sense_hdr *sshdr, int timeout, int retries)
337{
338 char *sense = NULL;
339
340 if (sshdr) {
341 sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
342 if (!sense)
343 return DRIVER_ERROR << 24;
344 memset(sense, 0, sizeof(*sense));
345 }
346 int result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
347 sense, timeout, retries, 0);
348 if (sshdr)
349 scsi_normalize_sense(sense, sizeof(*sense), sshdr);
350
351 kfree(sense);
352 return result;
353}
354EXPORT_SYMBOL(scsi_execute_req);
355
334/* 356/*
335 * Function: scsi_init_cmd_errh() 357 * Function: scsi_init_cmd_errh()
336 * 358 *
@@ -1614,7 +1636,7 @@ void scsi_exit_queue(void)
1614 } 1636 }
1615} 1637}
1616/** 1638/**
1617 * __scsi_mode_sense - issue a mode sense, falling back from 10 to 1639 * scsi_mode_sense - issue a mode sense, falling back from 10 to
1618 * six bytes if necessary. 1640 * six bytes if necessary.
1619 * @sdev: SCSI device to be queried 1641 * @sdev: SCSI device to be queried
1620 * @dbd: set if mode sense will allow block descriptors to be returned 1642 * @dbd: set if mode sense will allow block descriptors to be returned
@@ -1634,26 +1656,22 @@ void scsi_exit_queue(void)
1634int 1656int
1635scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, 1657scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
1636 unsigned char *buffer, int len, int timeout, int retries, 1658 unsigned char *buffer, int len, int timeout, int retries,
1637 struct scsi_mode_data *data, char *sense) { 1659 struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) {
1638 unsigned char cmd[12]; 1660 unsigned char cmd[12];
1639 int use_10_for_ms; 1661 int use_10_for_ms;
1640 int header_length; 1662 int header_length;
1641 int result; 1663 int result;
1642 char *sense_buffer = NULL; 1664 struct scsi_sense_hdr my_sshdr;
1643 1665
1644 memset(data, 0, sizeof(*data)); 1666 memset(data, 0, sizeof(*data));
1645 memset(&cmd[0], 0, 12); 1667 memset(&cmd[0], 0, 12);
1646 cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */ 1668 cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */
1647 cmd[2] = modepage; 1669 cmd[2] = modepage;
1648 1670
1649 if (!sense) { 1671 /* caller might not be interested in sense, but we need it */
1650 sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); 1672 if (!sshdr)
1651 if (!sense_buffer) { 1673 sshdr = &my_sshdr;
1652 dev_printk(KERN_ERR, &sdev->sdev_gendev, "failed to allocate sense buffer\n"); 1674
1653 return 0;
1654 }
1655 sense = sense_buffer;
1656 }
1657 retry: 1675 retry:
1658 use_10_for_ms = sdev->use_10_for_ms; 1676 use_10_for_ms = sdev->use_10_for_ms;
1659 1677
@@ -1673,12 +1691,10 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
1673 header_length = 4; 1691 header_length = 4;
1674 } 1692 }
1675 1693
1676 memset(sense, 0, SCSI_SENSE_BUFFERSIZE);
1677
1678 memset(buffer, 0, len); 1694 memset(buffer, 0, len);
1679 1695
1680 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, 1696 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
1681 sense, timeout, retries); 1697 sshdr, timeout, retries);
1682 1698
1683 /* This code looks awful: what it's doing is making sure an 1699 /* This code looks awful: what it's doing is making sure an
1684 * ILLEGAL REQUEST sense return identifies the actual command 1700 * ILLEGAL REQUEST sense return identifies the actual command
@@ -1687,11 +1703,9 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
1687 1703
1688 if (use_10_for_ms && !scsi_status_is_good(result) && 1704 if (use_10_for_ms && !scsi_status_is_good(result) &&
1689 (driver_byte(result) & DRIVER_SENSE)) { 1705 (driver_byte(result) & DRIVER_SENSE)) {
1690 struct scsi_sense_hdr sshdr; 1706 if (scsi_sense_valid(sshdr)) {
1691 1707 if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
1692 if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { 1708 (sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
1693 if ((sshdr.sense_key == ILLEGAL_REQUEST) &&
1694 (sshdr.asc == 0x20) && (sshdr.ascq == 0)) {
1695 /* 1709 /*
1696 * Invalid command operation code 1710 * Invalid command operation code
1697 */ 1711 */
@@ -1718,7 +1732,6 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
1718 } 1732 }
1719 } 1733 }
1720 1734
1721 kfree(sense_buffer);
1722 return result; 1735 return result;
1723} 1736}
1724EXPORT_SYMBOL(scsi_mode_sense); 1737EXPORT_SYMBOL(scsi_mode_sense);
@@ -1729,17 +1742,15 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
1729 char cmd[] = { 1742 char cmd[] = {
1730 TEST_UNIT_READY, 0, 0, 0, 0, 0, 1743 TEST_UNIT_READY, 0, 0, 0, 0, 0,
1731 }; 1744 };
1732 char sense[SCSI_SENSE_BUFFERSIZE]; 1745 struct scsi_sense_hdr sshdr;
1733 int result; 1746 int result;
1734 1747
1735 result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sense, 1748 result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, &sshdr,
1736 timeout, retries); 1749 timeout, retries);
1737 1750
1738 if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) { 1751 if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) {
1739 struct scsi_sense_hdr sshdr;
1740 1752
1741 if ((scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, 1753 if ((scsi_sense_valid(&sshdr)) &&
1742 &sshdr)) &&
1743 ((sshdr.sense_key == UNIT_ATTENTION) || 1754 ((sshdr.sense_key == UNIT_ATTENTION) ||
1744 (sshdr.sense_key == NOT_READY))) { 1755 (sshdr.sense_key == NOT_READY))) {
1745 sdev->changed = 1; 1756 sdev->changed = 1;