diff options
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 104 |
1 files changed, 85 insertions, 19 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index b49d86e3e45b..a857b7ac238c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -56,7 +56,7 @@ | |||
56 | * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), | 56 | * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), |
57 | * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by | 57 | * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by |
58 | * the optional "protocol" module parameter. In addition, the default | 58 | * the optional "protocol" module parameter. In addition, the default |
59 | * Vendor ID, Product ID, and release number can be overridden. | 59 | * Vendor ID, Product ID, release number and serial number can be overridden. |
60 | * | 60 | * |
61 | * There is support for multiple logical units (LUNs), each of which has | 61 | * There is support for multiple logical units (LUNs), each of which has |
62 | * its own backing file. The number of LUNs can be set using the optional | 62 | * its own backing file. The number of LUNs can be set using the optional |
@@ -93,6 +93,8 @@ | |||
93 | * removable Default false, boolean for removable media | 93 | * removable Default false, boolean for removable media |
94 | * luns=N Default N = number of filenames, number of | 94 | * luns=N Default N = number of filenames, number of |
95 | * LUNs to support | 95 | * LUNs to support |
96 | * nofua=b[,b...] Default false, booleans for ignore FUA flag | ||
97 | * in SCSI WRITE(10,12) commands | ||
96 | * stall Default determined according to the type of | 98 | * stall Default determined according to the type of |
97 | * USB device controller (usually true), | 99 | * USB device controller (usually true), |
98 | * boolean to permit the driver to halt | 100 | * boolean to permit the driver to halt |
@@ -106,17 +108,18 @@ | |||
106 | * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID | 108 | * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID |
107 | * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID | 109 | * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID |
108 | * release=0xRRRR Override the USB release number (bcdDevice) | 110 | * release=0xRRRR Override the USB release number (bcdDevice) |
111 | * serial=HHHH... Override serial number (string of hex chars) | ||
109 | * buflen=N Default N=16384, buffer size used (will be | 112 | * buflen=N Default N=16384, buffer size used (will be |
110 | * rounded down to a multiple of | 113 | * rounded down to a multiple of |
111 | * PAGE_CACHE_SIZE) | 114 | * PAGE_CACHE_SIZE) |
112 | * | 115 | * |
113 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", | 116 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", |
114 | * "removable", "luns", "stall", and "cdrom" options are available; default | 117 | * "removable", "luns", "nofua", "stall", and "cdrom" options are available; |
115 | * values are used for everything else. | 118 | * default values are used for everything else. |
116 | * | 119 | * |
117 | * The pathnames of the backing files and the ro settings are available in | 120 | * The pathnames of the backing files and the ro settings are available in |
118 | * the attribute files "file" and "ro" in the lun<n> subdirectory of the | 121 | * the attribute files "file", "nofua", and "ro" in the lun<n> subdirectory of |
119 | * gadget's sysfs directory. If the "removable" option is set, writing to | 122 | * the gadget's sysfs directory. If the "removable" option is set, writing to |
120 | * these files will simulate ejecting/loading the medium (writing an empty | 123 | * these files will simulate ejecting/loading the medium (writing an empty |
121 | * line means eject) and adjusting a write-enable tab. Changes to the ro | 124 | * line means eject) and adjusting a write-enable tab. Changes to the ro |
122 | * setting are not allowed when the medium is loaded or if CD-ROM emulation | 125 | * setting are not allowed when the medium is loaded or if CD-ROM emulation |
@@ -270,6 +273,8 @@ | |||
270 | 273 | ||
271 | #define DRIVER_DESC "File-backed Storage Gadget" | 274 | #define DRIVER_DESC "File-backed Storage Gadget" |
272 | #define DRIVER_NAME "g_file_storage" | 275 | #define DRIVER_NAME "g_file_storage" |
276 | /* DRIVER_VERSION must be at least 6 characters long, as it is used | ||
277 | * to generate a fallback serial number. */ | ||
273 | #define DRIVER_VERSION "20 November 2008" | 278 | #define DRIVER_VERSION "20 November 2008" |
274 | 279 | ||
275 | static char fsg_string_manufacturer[64]; | 280 | static char fsg_string_manufacturer[64]; |
@@ -301,8 +306,10 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
301 | static struct { | 306 | static struct { |
302 | char *file[FSG_MAX_LUNS]; | 307 | char *file[FSG_MAX_LUNS]; |
303 | int ro[FSG_MAX_LUNS]; | 308 | int ro[FSG_MAX_LUNS]; |
309 | int nofua[FSG_MAX_LUNS]; | ||
304 | unsigned int num_filenames; | 310 | unsigned int num_filenames; |
305 | unsigned int num_ros; | 311 | unsigned int num_ros; |
312 | unsigned int num_nofuas; | ||
306 | unsigned int nluns; | 313 | unsigned int nluns; |
307 | 314 | ||
308 | int removable; | 315 | int removable; |
@@ -314,6 +321,7 @@ static struct { | |||
314 | unsigned short vendor; | 321 | unsigned short vendor; |
315 | unsigned short product; | 322 | unsigned short product; |
316 | unsigned short release; | 323 | unsigned short release; |
324 | char *serial; | ||
317 | unsigned int buflen; | 325 | unsigned int buflen; |
318 | 326 | ||
319 | int transport_type; | 327 | int transport_type; |
@@ -341,6 +349,10 @@ MODULE_PARM_DESC(file, "names of backing files or devices"); | |||
341 | module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); | 349 | module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); |
342 | MODULE_PARM_DESC(ro, "true to force read-only"); | 350 | MODULE_PARM_DESC(ro, "true to force read-only"); |
343 | 351 | ||
352 | module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas, | ||
353 | S_IRUGO); | ||
354 | MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit"); | ||
355 | |||
344 | module_param_named(luns, mod_data.nluns, uint, S_IRUGO); | 356 | module_param_named(luns, mod_data.nluns, uint, S_IRUGO); |
345 | MODULE_PARM_DESC(luns, "number of LUNs"); | 357 | MODULE_PARM_DESC(luns, "number of LUNs"); |
346 | 358 | ||
@@ -353,6 +365,8 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); | |||
353 | module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); | 365 | module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); |
354 | MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); | 366 | MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); |
355 | 367 | ||
368 | module_param_named(serial, mod_data.serial, charp, S_IRUGO); | ||
369 | MODULE_PARM_DESC(serial, "USB serial number"); | ||
356 | 370 | ||
357 | /* In the non-TEST version, only the module parameters listed above | 371 | /* In the non-TEST version, only the module parameters listed above |
358 | * are available. */ | 372 | * are available. */ |
@@ -1272,7 +1286,8 @@ static int do_write(struct fsg_dev *fsg) | |||
1272 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 1286 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
1273 | return -EINVAL; | 1287 | return -EINVAL; |
1274 | } | 1288 | } |
1275 | if (fsg->cmnd[1] & 0x08) { // FUA | 1289 | /* FUA */ |
1290 | if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) { | ||
1276 | spin_lock(&curlun->filp->f_lock); | 1291 | spin_lock(&curlun->filp->f_lock); |
1277 | curlun->filp->f_flags |= O_DSYNC; | 1292 | curlun->filp->f_flags |= O_DSYNC; |
1278 | spin_unlock(&curlun->filp->f_lock); | 1293 | spin_unlock(&curlun->filp->f_lock); |
@@ -3126,6 +3141,7 @@ static int fsg_main_thread(void *fsg_) | |||
3126 | 3141 | ||
3127 | /* The write permissions and store_xxx pointers are set in fsg_bind() */ | 3142 | /* The write permissions and store_xxx pointers are set in fsg_bind() */ |
3128 | static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); | 3143 | static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); |
3144 | static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL); | ||
3129 | static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); | 3145 | static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); |
3130 | 3146 | ||
3131 | 3147 | ||
@@ -3197,6 +3213,7 @@ static int __init check_parameters(struct fsg_dev *fsg) | |||
3197 | { | 3213 | { |
3198 | int prot; | 3214 | int prot; |
3199 | int gcnum; | 3215 | int gcnum; |
3216 | int i; | ||
3200 | 3217 | ||
3201 | /* Store the default values */ | 3218 | /* Store the default values */ |
3202 | mod_data.transport_type = USB_PR_BULK; | 3219 | mod_data.transport_type = USB_PR_BULK; |
@@ -3272,13 +3289,65 @@ static int __init check_parameters(struct fsg_dev *fsg) | |||
3272 | ERROR(fsg, "invalid buflen\n"); | 3289 | ERROR(fsg, "invalid buflen\n"); |
3273 | return -ETOOSMALL; | 3290 | return -ETOOSMALL; |
3274 | } | 3291 | } |
3292 | |||
3275 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | 3293 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ |
3276 | 3294 | ||
3295 | /* Serial string handling. | ||
3296 | * On a real device, the serial string would be loaded | ||
3297 | * from permanent storage. */ | ||
3298 | if (mod_data.serial) { | ||
3299 | const char *ch; | ||
3300 | unsigned len = 0; | ||
3301 | |||
3302 | /* Sanity check : | ||
3303 | * The CB[I] specification limits the serial string to | ||
3304 | * 12 uppercase hexadecimal characters. | ||
3305 | * BBB need at least 12 uppercase hexadecimal characters, | ||
3306 | * with a maximum of 126. */ | ||
3307 | for (ch = mod_data.serial; *ch; ++ch) { | ||
3308 | ++len; | ||
3309 | if ((*ch < '0' || *ch > '9') && | ||
3310 | (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */ | ||
3311 | WARNING(fsg, | ||
3312 | "Invalid serial string character: %c; " | ||
3313 | "Failing back to default\n", | ||
3314 | *ch); | ||
3315 | goto fill_serial; | ||
3316 | } | ||
3317 | } | ||
3318 | if (len > 126 || | ||
3319 | (mod_data.transport_type == USB_PR_BULK && len < 12) || | ||
3320 | (mod_data.transport_type != USB_PR_BULK && len > 12)) { | ||
3321 | WARNING(fsg, | ||
3322 | "Invalid serial string length; " | ||
3323 | "Failing back to default\n"); | ||
3324 | goto fill_serial; | ||
3325 | } | ||
3326 | fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial; | ||
3327 | } else { | ||
3328 | WARNING(fsg, | ||
3329 | "Userspace failed to provide serial number; " | ||
3330 | "Failing back to default\n"); | ||
3331 | fill_serial: | ||
3332 | /* Serial number not specified or invalid, make our own. | ||
3333 | * We just encode it from the driver version string, | ||
3334 | * 12 characters to comply with both CB[I] and BBB spec. | ||
3335 | * Warning : Two devices running the same kernel will have | ||
3336 | * the same fallback serial number. */ | ||
3337 | for (i = 0; i < 12; i += 2) { | ||
3338 | unsigned char c = DRIVER_VERSION[i / 2]; | ||
3339 | |||
3340 | if (!c) | ||
3341 | break; | ||
3342 | sprintf(&fsg_string_serial[i], "%02X", c); | ||
3343 | } | ||
3344 | } | ||
3345 | |||
3277 | return 0; | 3346 | return 0; |
3278 | } | 3347 | } |
3279 | 3348 | ||
3280 | 3349 | ||
3281 | static int __init fsg_bind(struct usb_gadget *gadget) | 3350 | static int __ref fsg_bind(struct usb_gadget *gadget) |
3282 | { | 3351 | { |
3283 | struct fsg_dev *fsg = the_fsg; | 3352 | struct fsg_dev *fsg = the_fsg; |
3284 | int rc; | 3353 | int rc; |
@@ -3305,6 +3374,10 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3305 | } | 3374 | } |
3306 | } | 3375 | } |
3307 | 3376 | ||
3377 | /* Only for removable media? */ | ||
3378 | dev_attr_nofua.attr.mode = 0644; | ||
3379 | dev_attr_nofua.store = fsg_store_nofua; | ||
3380 | |||
3308 | /* Find out how many LUNs there should be */ | 3381 | /* Find out how many LUNs there should be */ |
3309 | i = mod_data.nluns; | 3382 | i = mod_data.nluns; |
3310 | if (i == 0) | 3383 | if (i == 0) |
@@ -3330,6 +3403,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3330 | curlun->ro = mod_data.cdrom || mod_data.ro[i]; | 3403 | curlun->ro = mod_data.cdrom || mod_data.ro[i]; |
3331 | curlun->initially_ro = curlun->ro; | 3404 | curlun->initially_ro = curlun->ro; |
3332 | curlun->removable = mod_data.removable; | 3405 | curlun->removable = mod_data.removable; |
3406 | curlun->nofua = mod_data.nofua[i]; | ||
3333 | curlun->dev.release = lun_release; | 3407 | curlun->dev.release = lun_release; |
3334 | curlun->dev.parent = &gadget->dev; | 3408 | curlun->dev.parent = &gadget->dev; |
3335 | curlun->dev.driver = &fsg_driver.driver; | 3409 | curlun->dev.driver = &fsg_driver.driver; |
@@ -3344,6 +3418,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3344 | if ((rc = device_create_file(&curlun->dev, | 3418 | if ((rc = device_create_file(&curlun->dev, |
3345 | &dev_attr_ro)) != 0 || | 3419 | &dev_attr_ro)) != 0 || |
3346 | (rc = device_create_file(&curlun->dev, | 3420 | (rc = device_create_file(&curlun->dev, |
3421 | &dev_attr_nofua)) != 0 || | ||
3422 | (rc = device_create_file(&curlun->dev, | ||
3347 | &dev_attr_file)) != 0) { | 3423 | &dev_attr_file)) != 0) { |
3348 | device_unregister(&curlun->dev); | 3424 | device_unregister(&curlun->dev); |
3349 | goto out; | 3425 | goto out; |
@@ -3447,16 +3523,6 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3447 | init_utsname()->sysname, init_utsname()->release, | 3523 | init_utsname()->sysname, init_utsname()->release, |
3448 | gadget->name); | 3524 | gadget->name); |
3449 | 3525 | ||
3450 | /* On a real device, serial[] would be loaded from permanent | ||
3451 | * storage. We just encode it from the driver version string. */ | ||
3452 | for (i = 0; i < sizeof fsg_string_serial - 2; i += 2) { | ||
3453 | unsigned char c = DRIVER_VERSION[i / 2]; | ||
3454 | |||
3455 | if (!c) | ||
3456 | break; | ||
3457 | sprintf(&fsg_string_serial[i], "%02X", c); | ||
3458 | } | ||
3459 | |||
3460 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, | 3526 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, |
3461 | "file-storage-gadget"); | 3527 | "file-storage-gadget"); |
3462 | if (IS_ERR(fsg->thread_task)) { | 3528 | if (IS_ERR(fsg->thread_task)) { |
@@ -3478,8 +3544,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3478 | if (IS_ERR(p)) | 3544 | if (IS_ERR(p)) |
3479 | p = NULL; | 3545 | p = NULL; |
3480 | } | 3546 | } |
3481 | LINFO(curlun, "ro=%d, file: %s\n", | 3547 | LINFO(curlun, "ro=%d, nofua=%d, file: %s\n", |
3482 | curlun->ro, (p ? p : "(error)")); | 3548 | curlun->ro, curlun->nofua, (p ? p : "(error)")); |
3483 | } | 3549 | } |
3484 | } | 3550 | } |
3485 | kfree(pathbuf); | 3551 | kfree(pathbuf); |