diff options
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 61 |
1 files changed, 29 insertions, 32 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a9be85103d2..4f57085619b 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -81,6 +81,10 @@ | |||
81 | * removable Default false, boolean for removable media | 81 | * removable Default false, boolean for removable media |
82 | * luns=N Default N = number of filenames, number of | 82 | * luns=N Default N = number of filenames, number of |
83 | * LUNs to support | 83 | * LUNs to support |
84 | * stall Default determined according to the type of | ||
85 | * USB device controller (usually true), | ||
86 | * boolean to permit the driver to halt | ||
87 | * bulk endpoints | ||
84 | * transport=XXX Default BBB, transport name (CB, CBI, or BBB) | 88 | * transport=XXX Default BBB, transport name (CB, CBI, or BBB) |
85 | * protocol=YYY Default SCSI, protocol name (RBC, 8020 or | 89 | * protocol=YYY Default SCSI, protocol name (RBC, 8020 or |
86 | * ATAPI, QIC, UFI, 8070, or SCSI; | 90 | * ATAPI, QIC, UFI, 8070, or SCSI; |
@@ -91,14 +95,10 @@ | |||
91 | * buflen=N Default N=16384, buffer size used (will be | 95 | * buflen=N Default N=16384, buffer size used (will be |
92 | * rounded down to a multiple of | 96 | * rounded down to a multiple of |
93 | * PAGE_CACHE_SIZE) | 97 | * PAGE_CACHE_SIZE) |
94 | * stall Default determined according to the type of | ||
95 | * USB device controller (usually true), | ||
96 | * boolean to permit the driver to halt | ||
97 | * bulk endpoints | ||
98 | * | 98 | * |
99 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", | 99 | * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", |
100 | * "removable", and "luns" options are available; default values are used | 100 | * "removable", "luns", and "stall" options are available; default values |
101 | * for everything else. | 101 | * are used for everything else. |
102 | * | 102 | * |
103 | * The pathnames of the backing files and the ro settings are available in | 103 | * The pathnames of the backing files and the ro settings are available in |
104 | * the attribute files "file" and "ro" in the lun<n> subdirectory of the | 104 | * the attribute files "file" and "ro" in the lun<n> subdirectory of the |
@@ -342,14 +342,15 @@ static struct { | |||
342 | int num_ros; | 342 | int num_ros; |
343 | unsigned int nluns; | 343 | unsigned int nluns; |
344 | 344 | ||
345 | int removable; | ||
346 | int can_stall; | ||
347 | |||
345 | char *transport_parm; | 348 | char *transport_parm; |
346 | char *protocol_parm; | 349 | char *protocol_parm; |
347 | int removable; | ||
348 | unsigned short vendor; | 350 | unsigned short vendor; |
349 | unsigned short product; | 351 | unsigned short product; |
350 | unsigned short release; | 352 | unsigned short release; |
351 | unsigned int buflen; | 353 | unsigned int buflen; |
352 | int can_stall; | ||
353 | 354 | ||
354 | int transport_type; | 355 | int transport_type; |
355 | char *transport_name; | 356 | char *transport_name; |
@@ -360,11 +361,11 @@ static struct { | |||
360 | .transport_parm = "BBB", | 361 | .transport_parm = "BBB", |
361 | .protocol_parm = "SCSI", | 362 | .protocol_parm = "SCSI", |
362 | .removable = 0, | 363 | .removable = 0, |
364 | .can_stall = 1, | ||
363 | .vendor = DRIVER_VENDOR_ID, | 365 | .vendor = DRIVER_VENDOR_ID, |
364 | .product = DRIVER_PRODUCT_ID, | 366 | .product = DRIVER_PRODUCT_ID, |
365 | .release = 0xffff, // Use controller chip type | 367 | .release = 0xffff, // Use controller chip type |
366 | .buflen = 16384, | 368 | .buflen = 16384, |
367 | .can_stall = 1, | ||
368 | }; | 369 | }; |
369 | 370 | ||
370 | 371 | ||
@@ -380,6 +381,9 @@ MODULE_PARM_DESC(luns, "number of LUNs"); | |||
380 | module_param_named(removable, mod_data.removable, bool, S_IRUGO); | 381 | module_param_named(removable, mod_data.removable, bool, S_IRUGO); |
381 | MODULE_PARM_DESC(removable, "true to simulate removable media"); | 382 | MODULE_PARM_DESC(removable, "true to simulate removable media"); |
382 | 383 | ||
384 | module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); | ||
385 | MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); | ||
386 | |||
383 | 387 | ||
384 | /* In the non-TEST version, only the module parameters listed above | 388 | /* In the non-TEST version, only the module parameters listed above |
385 | * are available. */ | 389 | * are available. */ |
@@ -404,9 +408,6 @@ MODULE_PARM_DESC(release, "USB release number"); | |||
404 | module_param_named(buflen, mod_data.buflen, uint, S_IRUGO); | 408 | module_param_named(buflen, mod_data.buflen, uint, S_IRUGO); |
405 | MODULE_PARM_DESC(buflen, "I/O buffer size"); | 409 | MODULE_PARM_DESC(buflen, "I/O buffer size"); |
406 | 410 | ||
407 | module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); | ||
408 | MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); | ||
409 | |||
410 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ | 411 | #endif /* CONFIG_USB_FILE_STORAGE_TEST */ |
411 | 412 | ||
412 | 413 | ||
@@ -818,7 +819,7 @@ static void inline put_be32(u8 *buf, u32 val) | |||
818 | buf[0] = val >> 24; | 819 | buf[0] = val >> 24; |
819 | buf[1] = val >> 16; | 820 | buf[1] = val >> 16; |
820 | buf[2] = val >> 8; | 821 | buf[2] = val >> 8; |
821 | buf[3] = val; | 822 | buf[3] = val & 0xff; |
822 | } | 823 | } |
823 | 824 | ||
824 | 825 | ||
@@ -1276,8 +1277,8 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1276 | { | 1277 | { |
1277 | struct usb_request *req = fsg->ep0req; | 1278 | struct usb_request *req = fsg->ep0req; |
1278 | int value = -EOPNOTSUPP; | 1279 | int value = -EOPNOTSUPP; |
1279 | u16 w_index = ctrl->wIndex; | 1280 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
1280 | u16 w_length = ctrl->wLength; | 1281 | u16 w_length = le16_to_cpu(ctrl->wLength); |
1281 | 1282 | ||
1282 | if (!fsg->config) | 1283 | if (!fsg->config) |
1283 | return value; | 1284 | return value; |
@@ -1312,7 +1313,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1312 | } | 1313 | } |
1313 | VDBG(fsg, "get max LUN\n"); | 1314 | VDBG(fsg, "get max LUN\n"); |
1314 | *(u8 *) req->buf = fsg->nluns - 1; | 1315 | *(u8 *) req->buf = fsg->nluns - 1; |
1315 | value = min(w_length, (u16) 1); | 1316 | value = 1; |
1316 | break; | 1317 | break; |
1317 | } | 1318 | } |
1318 | } | 1319 | } |
@@ -1344,7 +1345,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1344 | "unknown class-specific control req " | 1345 | "unknown class-specific control req " |
1345 | "%02x.%02x v%04x i%04x l%u\n", | 1346 | "%02x.%02x v%04x i%04x l%u\n", |
1346 | ctrl->bRequestType, ctrl->bRequest, | 1347 | ctrl->bRequestType, ctrl->bRequest, |
1347 | ctrl->wValue, w_index, w_length); | 1348 | le16_to_cpu(ctrl->wValue), w_index, w_length); |
1348 | return value; | 1349 | return value; |
1349 | } | 1350 | } |
1350 | 1351 | ||
@@ -1358,9 +1359,8 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1358 | { | 1359 | { |
1359 | struct usb_request *req = fsg->ep0req; | 1360 | struct usb_request *req = fsg->ep0req; |
1360 | int value = -EOPNOTSUPP; | 1361 | int value = -EOPNOTSUPP; |
1361 | u16 w_index = ctrl->wIndex; | 1362 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
1362 | u16 w_value = ctrl->wValue; | 1363 | u16 w_value = le16_to_cpu(ctrl->wValue); |
1363 | u16 w_length = ctrl->wLength; | ||
1364 | 1364 | ||
1365 | /* Usually this just stores reply data in the pre-allocated ep0 buffer, | 1365 | /* Usually this just stores reply data in the pre-allocated ep0 buffer, |
1366 | * but config change events will also reconfigure hardware. */ | 1366 | * but config change events will also reconfigure hardware. */ |
@@ -1374,7 +1374,7 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1374 | 1374 | ||
1375 | case USB_DT_DEVICE: | 1375 | case USB_DT_DEVICE: |
1376 | VDBG(fsg, "get device descriptor\n"); | 1376 | VDBG(fsg, "get device descriptor\n"); |
1377 | value = min(w_length, (u16) sizeof device_desc); | 1377 | value = sizeof device_desc; |
1378 | memcpy(req->buf, &device_desc, value); | 1378 | memcpy(req->buf, &device_desc, value); |
1379 | break; | 1379 | break; |
1380 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1380 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
@@ -1382,7 +1382,7 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1382 | VDBG(fsg, "get device qualifier\n"); | 1382 | VDBG(fsg, "get device qualifier\n"); |
1383 | if (!fsg->gadget->is_dualspeed) | 1383 | if (!fsg->gadget->is_dualspeed) |
1384 | break; | 1384 | break; |
1385 | value = min(w_length, (u16) sizeof dev_qualifier); | 1385 | value = sizeof dev_qualifier; |
1386 | memcpy(req->buf, &dev_qualifier, value); | 1386 | memcpy(req->buf, &dev_qualifier, value); |
1387 | break; | 1387 | break; |
1388 | 1388 | ||
@@ -1401,8 +1401,6 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1401 | req->buf, | 1401 | req->buf, |
1402 | w_value >> 8, | 1402 | w_value >> 8, |
1403 | w_value & 0xff); | 1403 | w_value & 0xff); |
1404 | if (value >= 0) | ||
1405 | value = min(w_length, (u16) value); | ||
1406 | break; | 1404 | break; |
1407 | 1405 | ||
1408 | case USB_DT_STRING: | 1406 | case USB_DT_STRING: |
@@ -1411,8 +1409,6 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1411 | /* wIndex == language code */ | 1409 | /* wIndex == language code */ |
1412 | value = usb_gadget_get_string(&stringtab, | 1410 | value = usb_gadget_get_string(&stringtab, |
1413 | w_value & 0xff, req->buf); | 1411 | w_value & 0xff, req->buf); |
1414 | if (value >= 0) | ||
1415 | value = min(w_length, (u16) value); | ||
1416 | break; | 1412 | break; |
1417 | } | 1413 | } |
1418 | break; | 1414 | break; |
@@ -1438,7 +1434,7 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1438 | break; | 1434 | break; |
1439 | VDBG(fsg, "get configuration\n"); | 1435 | VDBG(fsg, "get configuration\n"); |
1440 | *(u8 *) req->buf = fsg->config; | 1436 | *(u8 *) req->buf = fsg->config; |
1441 | value = min(w_length, (u16) 1); | 1437 | value = 1; |
1442 | break; | 1438 | break; |
1443 | 1439 | ||
1444 | case USB_REQ_SET_INTERFACE: | 1440 | case USB_REQ_SET_INTERFACE: |
@@ -1466,14 +1462,14 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1466 | } | 1462 | } |
1467 | VDBG(fsg, "get interface\n"); | 1463 | VDBG(fsg, "get interface\n"); |
1468 | *(u8 *) req->buf = 0; | 1464 | *(u8 *) req->buf = 0; |
1469 | value = min(w_length, (u16) 1); | 1465 | value = 1; |
1470 | break; | 1466 | break; |
1471 | 1467 | ||
1472 | default: | 1468 | default: |
1473 | VDBG(fsg, | 1469 | VDBG(fsg, |
1474 | "unknown control req %02x.%02x v%04x i%04x l%u\n", | 1470 | "unknown control req %02x.%02x v%04x i%04x l%u\n", |
1475 | ctrl->bRequestType, ctrl->bRequest, | 1471 | ctrl->bRequestType, ctrl->bRequest, |
1476 | w_value, w_index, w_length); | 1472 | w_value, w_index, le16_to_cpu(ctrl->wLength)); |
1477 | } | 1473 | } |
1478 | 1474 | ||
1479 | return value; | 1475 | return value; |
@@ -1485,6 +1481,7 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
1485 | { | 1481 | { |
1486 | struct fsg_dev *fsg = get_gadget_data(gadget); | 1482 | struct fsg_dev *fsg = get_gadget_data(gadget); |
1487 | int rc; | 1483 | int rc; |
1484 | int w_length = le16_to_cpu(ctrl->wLength); | ||
1488 | 1485 | ||
1489 | ++fsg->ep0_req_tag; // Record arrival of a new request | 1486 | ++fsg->ep0_req_tag; // Record arrival of a new request |
1490 | fsg->ep0req->context = NULL; | 1487 | fsg->ep0req->context = NULL; |
@@ -1498,9 +1495,9 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
1498 | 1495 | ||
1499 | /* Respond with data/status or defer until later? */ | 1496 | /* Respond with data/status or defer until later? */ |
1500 | if (rc >= 0 && rc != DELAYED_STATUS) { | 1497 | if (rc >= 0 && rc != DELAYED_STATUS) { |
1498 | rc = min(rc, w_length); | ||
1501 | fsg->ep0req->length = rc; | 1499 | fsg->ep0req->length = rc; |
1502 | fsg->ep0req->zero = (rc < ctrl->wLength && | 1500 | fsg->ep0req->zero = rc < w_length; |
1503 | (rc % gadget->ep0->maxpacket) == 0); | ||
1504 | fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? | 1501 | fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? |
1505 | "ep0-in" : "ep0-out"); | 1502 | "ep0-in" : "ep0-out"); |
1506 | rc = ep0_queue(fsg); | 1503 | rc = ep0_queue(fsg); |
@@ -2660,7 +2657,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2660 | } | 2657 | } |
2661 | } | 2658 | } |
2662 | 2659 | ||
2663 | /* Check that the LUN values are oonsistent */ | 2660 | /* Check that the LUN values are consistent */ |
2664 | if (transport_is_bbb()) { | 2661 | if (transport_is_bbb()) { |
2665 | if (fsg->lun != lun) | 2662 | if (fsg->lun != lun) |
2666 | DBG(fsg, "using LUN %d from CBW, " | 2663 | DBG(fsg, "using LUN %d from CBW, " |