aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/file_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r--drivers/usb/gadget/file_storage.c38
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
3695static void __exit fsg_unbind(struct usb_gadget *gadget) 3708static 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,