diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-09-26 14:51:48 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-28 18:36:47 -0400 |
commit | 6174d0fd35f486f59b743630bdf088a9f9792d4d (patch) | |
tree | dff7959fbb7d36b96301a85c5e651912c6cf02b7 | |
parent | e0318ebff4d96131bb3524308b845f642e64df81 (diff) |
USB: g_file_storage: Set sense info Valid bit only when needed
Strictly speaking, the Valid bit in SCSI sense data is supposed to
be set only when the Information field contains a valid number. This
patch (as793) turns off the Valid bit when the Information field
hasn't been set.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index d472c9c29904..c83d3b6c68f2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -567,6 +567,7 @@ struct lun { | |||
567 | unsigned int ro : 1; | 567 | unsigned int ro : 1; |
568 | unsigned int prevent_medium_removal : 1; | 568 | unsigned int prevent_medium_removal : 1; |
569 | unsigned int registered : 1; | 569 | unsigned int registered : 1; |
570 | unsigned int info_valid : 1; | ||
570 | 571 | ||
571 | u32 sense_data; | 572 | u32 sense_data; |
572 | u32 sense_data_info; | 573 | u32 sense_data_info; |
@@ -1656,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg) | |||
1656 | curlun->sense_data = | 1657 | curlun->sense_data = |
1657 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1658 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
1658 | curlun->sense_data_info = file_offset >> 9; | 1659 | curlun->sense_data_info = file_offset >> 9; |
1660 | curlun->info_valid = 1; | ||
1659 | bh->inreq->length = 0; | 1661 | bh->inreq->length = 0; |
1660 | bh->state = BUF_STATE_FULL; | 1662 | bh->state = BUF_STATE_FULL; |
1661 | break; | 1663 | break; |
@@ -1691,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg) | |||
1691 | if (nread < amount) { | 1693 | if (nread < amount) { |
1692 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1694 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
1693 | curlun->sense_data_info = file_offset >> 9; | 1695 | curlun->sense_data_info = file_offset >> 9; |
1696 | curlun->info_valid = 1; | ||
1694 | break; | 1697 | break; |
1695 | } | 1698 | } |
1696 | 1699 | ||
@@ -1785,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1785 | curlun->sense_data = | 1788 | curlun->sense_data = |
1786 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1789 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
1787 | curlun->sense_data_info = usb_offset >> 9; | 1790 | curlun->sense_data_info = usb_offset >> 9; |
1791 | curlun->info_valid = 1; | ||
1788 | continue; | 1792 | continue; |
1789 | } | 1793 | } |
1790 | amount -= (amount & 511); | 1794 | amount -= (amount & 511); |
@@ -1827,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1827 | if (bh->outreq->status != 0) { | 1831 | if (bh->outreq->status != 0) { |
1828 | curlun->sense_data = SS_COMMUNICATION_FAILURE; | 1832 | curlun->sense_data = SS_COMMUNICATION_FAILURE; |
1829 | curlun->sense_data_info = file_offset >> 9; | 1833 | curlun->sense_data_info = file_offset >> 9; |
1834 | curlun->info_valid = 1; | ||
1830 | break; | 1835 | break; |
1831 | } | 1836 | } |
1832 | 1837 | ||
@@ -1868,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1868 | if (nwritten < amount) { | 1873 | if (nwritten < amount) { |
1869 | curlun->sense_data = SS_WRITE_ERROR; | 1874 | curlun->sense_data = SS_WRITE_ERROR; |
1870 | curlun->sense_data_info = file_offset >> 9; | 1875 | curlun->sense_data_info = file_offset >> 9; |
1876 | curlun->info_valid = 1; | ||
1871 | break; | 1877 | break; |
1872 | } | 1878 | } |
1873 | 1879 | ||
@@ -2010,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg) | |||
2010 | curlun->sense_data = | 2016 | curlun->sense_data = |
2011 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 2017 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
2012 | curlun->sense_data_info = file_offset >> 9; | 2018 | curlun->sense_data_info = file_offset >> 9; |
2019 | curlun->info_valid = 1; | ||
2013 | break; | 2020 | break; |
2014 | } | 2021 | } |
2015 | 2022 | ||
@@ -2036,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg) | |||
2036 | if (nread == 0) { | 2043 | if (nread == 0) { |
2037 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 2044 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
2038 | curlun->sense_data_info = file_offset >> 9; | 2045 | curlun->sense_data_info = file_offset >> 9; |
2046 | curlun->info_valid = 1; | ||
2039 | break; | 2047 | break; |
2040 | } | 2048 | } |
2041 | file_offset += nread; | 2049 | file_offset += nread; |
@@ -2079,6 +2087,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2079 | struct lun *curlun = fsg->curlun; | 2087 | struct lun *curlun = fsg->curlun; |
2080 | u8 *buf = (u8 *) bh->buf; | 2088 | u8 *buf = (u8 *) bh->buf; |
2081 | u32 sd, sdinfo; | 2089 | u32 sd, sdinfo; |
2090 | int valid; | ||
2082 | 2091 | ||
2083 | /* | 2092 | /* |
2084 | * From the SCSI-2 spec., section 7.9 (Unit attention condition): | 2093 | * From the SCSI-2 spec., section 7.9 (Unit attention condition): |
@@ -2106,15 +2115,18 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2106 | fsg->bad_lun_okay = 1; | 2115 | fsg->bad_lun_okay = 1; |
2107 | sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; | 2116 | sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; |
2108 | sdinfo = 0; | 2117 | sdinfo = 0; |
2118 | valid = 0; | ||
2109 | } else { | 2119 | } else { |
2110 | sd = curlun->sense_data; | 2120 | sd = curlun->sense_data; |
2111 | sdinfo = curlun->sense_data_info; | 2121 | sdinfo = curlun->sense_data_info; |
2122 | valid = curlun->info_valid << 7; | ||
2112 | curlun->sense_data = SS_NO_SENSE; | 2123 | curlun->sense_data = SS_NO_SENSE; |
2113 | curlun->sense_data_info = 0; | 2124 | curlun->sense_data_info = 0; |
2125 | curlun->info_valid = 0; | ||
2114 | } | 2126 | } |
2115 | 2127 | ||
2116 | memset(buf, 0, 18); | 2128 | memset(buf, 0, 18); |
2117 | buf[0] = 0x80 | 0x70; // Valid, current error | 2129 | buf[0] = valid | 0x70; // Valid, current error |
2118 | buf[2] = SK(sd); | 2130 | buf[2] = SK(sd); |
2119 | put_be32(&buf[3], sdinfo); // Sense information | 2131 | put_be32(&buf[3], sdinfo); // Sense information |
2120 | buf[7] = 18 - 8; // Additional sense length | 2132 | buf[7] = 18 - 8; // Additional sense length |
@@ -2703,6 +2715,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2703 | if (fsg->cmnd[0] != SC_REQUEST_SENSE) { | 2715 | if (fsg->cmnd[0] != SC_REQUEST_SENSE) { |
2704 | curlun->sense_data = SS_NO_SENSE; | 2716 | curlun->sense_data = SS_NO_SENSE; |
2705 | curlun->sense_data_info = 0; | 2717 | curlun->sense_data_info = 0; |
2718 | curlun->info_valid = 0; | ||
2706 | } | 2719 | } |
2707 | } else { | 2720 | } else { |
2708 | fsg->curlun = curlun = NULL; | 2721 | fsg->curlun = curlun = NULL; |
@@ -3332,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg) | |||
3332 | curlun->sense_data = curlun->unit_attention_data = | 3345 | curlun->sense_data = curlun->unit_attention_data = |
3333 | SS_NO_SENSE; | 3346 | SS_NO_SENSE; |
3334 | curlun->sense_data_info = 0; | 3347 | curlun->sense_data_info = 0; |
3348 | curlun->info_valid = 0; | ||
3335 | } | 3349 | } |
3336 | fsg->state = FSG_STATE_IDLE; | 3350 | fsg->state = FSG_STATE_IDLE; |
3337 | } | 3351 | } |