diff options
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a43dc908ac59..c83d3b6c68f2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -221,7 +221,6 @@ | |||
221 | #undef VERBOSE | 221 | #undef VERBOSE |
222 | #undef DUMP_MSGS | 222 | #undef DUMP_MSGS |
223 | 223 | ||
224 | #include <linux/config.h> | ||
225 | 224 | ||
226 | #include <asm/system.h> | 225 | #include <asm/system.h> |
227 | #include <asm/uaccess.h> | 226 | #include <asm/uaccess.h> |
@@ -568,6 +567,7 @@ struct lun { | |||
568 | unsigned int ro : 1; | 567 | unsigned int ro : 1; |
569 | unsigned int prevent_medium_removal : 1; | 568 | unsigned int prevent_medium_removal : 1; |
570 | unsigned int registered : 1; | 569 | unsigned int registered : 1; |
570 | unsigned int info_valid : 1; | ||
571 | 571 | ||
572 | u32 sense_data; | 572 | u32 sense_data; |
573 | u32 sense_data_info; | 573 | u32 sense_data_info; |
@@ -1657,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg) | |||
1657 | curlun->sense_data = | 1657 | curlun->sense_data = |
1658 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1658 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
1659 | curlun->sense_data_info = file_offset >> 9; | 1659 | curlun->sense_data_info = file_offset >> 9; |
1660 | curlun->info_valid = 1; | ||
1660 | bh->inreq->length = 0; | 1661 | bh->inreq->length = 0; |
1661 | bh->state = BUF_STATE_FULL; | 1662 | bh->state = BUF_STATE_FULL; |
1662 | break; | 1663 | break; |
@@ -1692,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg) | |||
1692 | if (nread < amount) { | 1693 | if (nread < amount) { |
1693 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1694 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
1694 | curlun->sense_data_info = file_offset >> 9; | 1695 | curlun->sense_data_info = file_offset >> 9; |
1696 | curlun->info_valid = 1; | ||
1695 | break; | 1697 | break; |
1696 | } | 1698 | } |
1697 | 1699 | ||
@@ -1786,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1786 | curlun->sense_data = | 1788 | curlun->sense_data = |
1787 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1789 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
1788 | curlun->sense_data_info = usb_offset >> 9; | 1790 | curlun->sense_data_info = usb_offset >> 9; |
1791 | curlun->info_valid = 1; | ||
1789 | continue; | 1792 | continue; |
1790 | } | 1793 | } |
1791 | amount -= (amount & 511); | 1794 | amount -= (amount & 511); |
@@ -1828,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1828 | if (bh->outreq->status != 0) { | 1831 | if (bh->outreq->status != 0) { |
1829 | curlun->sense_data = SS_COMMUNICATION_FAILURE; | 1832 | curlun->sense_data = SS_COMMUNICATION_FAILURE; |
1830 | curlun->sense_data_info = file_offset >> 9; | 1833 | curlun->sense_data_info = file_offset >> 9; |
1834 | curlun->info_valid = 1; | ||
1831 | break; | 1835 | break; |
1832 | } | 1836 | } |
1833 | 1837 | ||
@@ -1869,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1869 | if (nwritten < amount) { | 1873 | if (nwritten < amount) { |
1870 | curlun->sense_data = SS_WRITE_ERROR; | 1874 | curlun->sense_data = SS_WRITE_ERROR; |
1871 | curlun->sense_data_info = file_offset >> 9; | 1875 | curlun->sense_data_info = file_offset >> 9; |
1876 | curlun->info_valid = 1; | ||
1872 | break; | 1877 | break; |
1873 | } | 1878 | } |
1874 | 1879 | ||
@@ -2011,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg) | |||
2011 | curlun->sense_data = | 2016 | curlun->sense_data = |
2012 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 2017 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
2013 | curlun->sense_data_info = file_offset >> 9; | 2018 | curlun->sense_data_info = file_offset >> 9; |
2019 | curlun->info_valid = 1; | ||
2014 | break; | 2020 | break; |
2015 | } | 2021 | } |
2016 | 2022 | ||
@@ -2037,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg) | |||
2037 | if (nread == 0) { | 2043 | if (nread == 0) { |
2038 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 2044 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
2039 | curlun->sense_data_info = file_offset >> 9; | 2045 | curlun->sense_data_info = file_offset >> 9; |
2046 | curlun->info_valid = 1; | ||
2040 | break; | 2047 | break; |
2041 | } | 2048 | } |
2042 | file_offset += nread; | 2049 | file_offset += nread; |
@@ -2080,6 +2087,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2080 | struct lun *curlun = fsg->curlun; | 2087 | struct lun *curlun = fsg->curlun; |
2081 | u8 *buf = (u8 *) bh->buf; | 2088 | u8 *buf = (u8 *) bh->buf; |
2082 | u32 sd, sdinfo; | 2089 | u32 sd, sdinfo; |
2090 | int valid; | ||
2083 | 2091 | ||
2084 | /* | 2092 | /* |
2085 | * From the SCSI-2 spec., section 7.9 (Unit attention condition): | 2093 | * From the SCSI-2 spec., section 7.9 (Unit attention condition): |
@@ -2107,15 +2115,18 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2107 | fsg->bad_lun_okay = 1; | 2115 | fsg->bad_lun_okay = 1; |
2108 | sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; | 2116 | sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; |
2109 | sdinfo = 0; | 2117 | sdinfo = 0; |
2118 | valid = 0; | ||
2110 | } else { | 2119 | } else { |
2111 | sd = curlun->sense_data; | 2120 | sd = curlun->sense_data; |
2112 | sdinfo = curlun->sense_data_info; | 2121 | sdinfo = curlun->sense_data_info; |
2122 | valid = curlun->info_valid << 7; | ||
2113 | curlun->sense_data = SS_NO_SENSE; | 2123 | curlun->sense_data = SS_NO_SENSE; |
2114 | curlun->sense_data_info = 0; | 2124 | curlun->sense_data_info = 0; |
2125 | curlun->info_valid = 0; | ||
2115 | } | 2126 | } |
2116 | 2127 | ||
2117 | memset(buf, 0, 18); | 2128 | memset(buf, 0, 18); |
2118 | buf[0] = 0x80 | 0x70; // Valid, current error | 2129 | buf[0] = valid | 0x70; // Valid, current error |
2119 | buf[2] = SK(sd); | 2130 | buf[2] = SK(sd); |
2120 | put_be32(&buf[3], sdinfo); // Sense information | 2131 | put_be32(&buf[3], sdinfo); // Sense information |
2121 | buf[7] = 18 - 8; // Additional sense length | 2132 | buf[7] = 18 - 8; // Additional sense length |
@@ -2704,6 +2715,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2704 | if (fsg->cmnd[0] != SC_REQUEST_SENSE) { | 2715 | if (fsg->cmnd[0] != SC_REQUEST_SENSE) { |
2705 | curlun->sense_data = SS_NO_SENSE; | 2716 | curlun->sense_data = SS_NO_SENSE; |
2706 | curlun->sense_data_info = 0; | 2717 | curlun->sense_data_info = 0; |
2718 | curlun->info_valid = 0; | ||
2707 | } | 2719 | } |
2708 | } else { | 2720 | } else { |
2709 | fsg->curlun = curlun = NULL; | 2721 | fsg->curlun = curlun = NULL; |
@@ -3333,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg) | |||
3333 | curlun->sense_data = curlun->unit_attention_data = | 3345 | curlun->sense_data = curlun->unit_attention_data = |
3334 | SS_NO_SENSE; | 3346 | SS_NO_SENSE; |
3335 | curlun->sense_data_info = 0; | 3347 | curlun->sense_data_info = 0; |
3348 | curlun->info_valid = 0; | ||
3336 | } | 3349 | } |
3337 | fsg->state = FSG_STATE_IDLE; | 3350 | fsg->state = FSG_STATE_IDLE; |
3338 | } | 3351 | } |
@@ -3692,7 +3705,7 @@ static void lun_release(struct device *dev) | |||
3692 | kref_put(&fsg->ref, fsg_release); | 3705 | kref_put(&fsg->ref, fsg_release); |
3693 | } | 3706 | } |
3694 | 3707 | ||
3695 | static void __exit fsg_unbind(struct usb_gadget *gadget) | 3708 | static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) |
3696 | { | 3709 | { |
3697 | struct fsg_dev *fsg = get_gadget_data(gadget); | 3710 | struct fsg_dev *fsg = get_gadget_data(gadget); |
3698 | int i; | 3711 | int i; |
@@ -3874,21 +3887,26 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3874 | for (i = 0; i < fsg->nluns; ++i) { | 3887 | for (i = 0; i < fsg->nluns; ++i) { |
3875 | curlun = &fsg->luns[i]; | 3888 | curlun = &fsg->luns[i]; |
3876 | curlun->ro = mod_data.ro[i]; | 3889 | curlun->ro = mod_data.ro[i]; |
3890 | curlun->dev.release = lun_release; | ||
3877 | curlun->dev.parent = &gadget->dev; | 3891 | curlun->dev.parent = &gadget->dev; |
3878 | curlun->dev.driver = &fsg_driver.driver; | 3892 | curlun->dev.driver = &fsg_driver.driver; |
3879 | dev_set_drvdata(&curlun->dev, fsg); | 3893 | dev_set_drvdata(&curlun->dev, fsg); |
3880 | snprintf(curlun->dev.bus_id, BUS_ID_SIZE, | 3894 | snprintf(curlun->dev.bus_id, BUS_ID_SIZE, |
3881 | "%s-lun%d", gadget->dev.bus_id, i); | 3895 | "%s-lun%d", gadget->dev.bus_id, i); |
3882 | 3896 | ||
3883 | if ((rc = device_register(&curlun->dev)) != 0) | 3897 | if ((rc = device_register(&curlun->dev)) != 0) { |
3884 | INFO(fsg, "failed to register LUN%d: %d\n", i, rc); | 3898 | INFO(fsg, "failed to register LUN%d: %d\n", i, rc); |
3885 | else { | 3899 | goto out; |
3886 | curlun->registered = 1; | 3900 | } |
3887 | curlun->dev.release = lun_release; | 3901 | if ((rc = device_create_file(&curlun->dev, |
3888 | device_create_file(&curlun->dev, &dev_attr_ro); | 3902 | &dev_attr_ro)) != 0 || |
3889 | device_create_file(&curlun->dev, &dev_attr_file); | 3903 | (rc = device_create_file(&curlun->dev, |
3890 | kref_get(&fsg->ref); | 3904 | &dev_attr_file)) != 0) { |
3905 | device_unregister(&curlun->dev); | ||
3906 | goto out; | ||
3891 | } | 3907 | } |
3908 | curlun->registered = 1; | ||
3909 | kref_get(&fsg->ref); | ||
3892 | 3910 | ||
3893 | if (mod_data.file[i] && *mod_data.file[i]) { | 3911 | if (mod_data.file[i] && *mod_data.file[i]) { |
3894 | if ((rc = open_backing_file(curlun, | 3912 | if ((rc = open_backing_file(curlun, |