diff options
author | Michal Nazarewicz <m.nazarewicz@samsung.com> | 2009-11-09 08:15:20 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 14:55:22 -0500 |
commit | d23b0f08d18fc42f26f6a0776c6d827eb35143a9 (patch) | |
tree | e6557975165865e43984045279e262d62b939dde | |
parent | 6648f29d3be2972a74ef8e29aa5d425ab4f1fc48 (diff) |
USB: g_mass_storage: Mass Storage Function created
The f_mass_storage.c has been changed into a composite function.
mass_storage.c file has been introduced which defines a
g_mass_storage gadget based on composite framework.
Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/Kconfig | 18 | ||||
-rw-r--r-- | drivers/usb/gadget/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 644 | ||||
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/mass_storage.c | 233 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 22 |
6 files changed, 426 insertions, 500 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index a18e3c5dd82e..3bb250fd5321 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -732,6 +732,24 @@ config USB_FILE_STORAGE_TEST | |||
732 | behavior of USB Mass Storage hosts. Not needed for | 732 | behavior of USB Mass Storage hosts. Not needed for |
733 | normal operation. | 733 | normal operation. |
734 | 734 | ||
735 | config USB_MASS_STORAGE | ||
736 | tristate "Mass Storage Gadget" | ||
737 | depends on BLOCK | ||
738 | help | ||
739 | The Mass Storage Gadget acts as a USB Mass Storage disk drive. | ||
740 | As its storage repository it can use a regular file or a block | ||
741 | device (in much the same way as the "loop" device driver), | ||
742 | specified as a module parameter or sysfs option. | ||
743 | |||
744 | This is heavily based on File-backed Storage Gadget and in most | ||
745 | cases you will want to use FSG instead. This gadget is mostly | ||
746 | here to test the functionality of the Mass Storage Function | ||
747 | which may be used with composite framework. | ||
748 | |||
749 | Say "y" to link the driver statically, or "m" to build | ||
750 | a dynamically linked module called "g_file_storage". If unsure, | ||
751 | consider File-backed Storage Gadget. | ||
752 | |||
735 | config USB_G_SERIAL | 753 | config USB_G_SERIAL |
736 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | 754 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" |
737 | help | 755 | help |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 9d7b87c52e9f..025ba2ed7907 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -39,6 +39,7 @@ g_serial-objs := serial.o | |||
39 | g_midi-objs := gmidi.o | 39 | g_midi-objs := gmidi.o |
40 | gadgetfs-objs := inode.o | 40 | gadgetfs-objs := inode.o |
41 | g_file_storage-objs := file_storage.o | 41 | g_file_storage-objs := file_storage.o |
42 | g_mass_storage-objs := mass_storage.o | ||
42 | g_printer-objs := printer.o | 43 | g_printer-objs := printer.o |
43 | g_cdc-objs := cdc2.o | 44 | g_cdc-objs := cdc2.o |
44 | 45 | ||
@@ -47,6 +48,7 @@ obj-$(CONFIG_USB_AUDIO) += g_audio.o | |||
47 | obj-$(CONFIG_USB_ETH) += g_ether.o | 48 | obj-$(CONFIG_USB_ETH) += g_ether.o |
48 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o | 49 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o |
49 | obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o | 50 | obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o |
51 | obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o | ||
50 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o | 52 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o |
51 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | 53 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o |
52 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | 54 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5a0f5708c094..5fc01c04af05 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -233,47 +233,23 @@ | |||
233 | 233 | ||
234 | 234 | ||
235 | 235 | ||
236 | /* | ||
237 | * Kbuild is not very cooperative with respect to linking separately | ||
238 | * compiled library objects into one module. So for now we won't use | ||
239 | * separate compilation ... ensuring init/exit sections work to shrink | ||
240 | * the runtime footprint, and giving us at least some parts of what | ||
241 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
242 | */ | ||
243 | #include "usbstring.c" | ||
244 | #include "config.c" | ||
245 | #include "epautoconf.c" | ||
246 | |||
247 | /*-------------------------------------------------------------------------*/ | 236 | /*-------------------------------------------------------------------------*/ |
248 | 237 | ||
249 | #define DRIVER_DESC "File-backed Storage Gadget" | 238 | #define FSG_DRIVER_DESC "Mass Storage Function" |
250 | #define DRIVER_NAME "g_file_storage" | 239 | #define FSG_DRIVER_VERSION "20 November 2008" |
251 | #define DRIVER_VERSION "20 November 2008" | ||
252 | 240 | ||
253 | static char fsg_string_manufacturer[64]; | ||
254 | static const char fsg_string_product[] = DRIVER_DESC; | ||
255 | static char fsg_string_serial[13]; | ||
256 | static const char fsg_string_config[] = "Self-powered"; | ||
257 | static const char fsg_string_interface[] = "Mass Storage"; | 241 | static const char fsg_string_interface[] = "Mass Storage"; |
258 | 242 | ||
259 | 243 | ||
260 | #define FSG_NO_INTR_EP 1 | 244 | #define FSG_NO_INTR_EP 1 |
261 | #define FSG_BUFFHD_STATIC_BUFFER 1 | 245 | #define FSG_BUFFHD_STATIC_BUFFER 1 |
246 | #define FSG_NO_DEVICE_STRINGS 1 | ||
247 | #define FSG_NO_OTG 1 | ||
248 | #define FSG_NO_INTR_EP 1 | ||
262 | 249 | ||
263 | #include "storage_common.c" | 250 | #include "storage_common.c" |
264 | 251 | ||
265 | 252 | ||
266 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
267 | MODULE_AUTHOR("Alan Stern"); | ||
268 | MODULE_LICENSE("Dual BSD/GPL"); | ||
269 | |||
270 | /* | ||
271 | * This driver assumes self-powered hardware and has no way for users to | ||
272 | * trigger remote wakeup. It uses autoconfiguration to select endpoints | ||
273 | * and endpoint addresses. | ||
274 | */ | ||
275 | |||
276 | |||
277 | /*-------------------------------------------------------------------------*/ | 253 | /*-------------------------------------------------------------------------*/ |
278 | 254 | ||
279 | 255 | ||
@@ -295,6 +271,7 @@ static struct { | |||
295 | .removable = 0, | 271 | .removable = 0, |
296 | .can_stall = 1, | 272 | .can_stall = 1, |
297 | .cdrom = 0, | 273 | .cdrom = 0, |
274 | .release = 0xffff, | ||
298 | }; | 275 | }; |
299 | 276 | ||
300 | 277 | ||
@@ -347,14 +324,18 @@ struct fsg_common { | |||
347 | 324 | ||
348 | 325 | ||
349 | struct fsg_dev { | 326 | struct fsg_dev { |
327 | struct usb_function function; | ||
328 | struct usb_composite_dev*cdev; | ||
329 | struct usb_gadget *gadget; /* Copy of cdev->gadget */ | ||
350 | struct fsg_common *common; | 330 | struct fsg_common *common; |
351 | 331 | ||
332 | u16 interface_number; | ||
333 | |||
352 | /* lock protects: state, all the req_busy's */ | 334 | /* lock protects: state, all the req_busy's */ |
353 | spinlock_t lock; | 335 | spinlock_t lock; |
354 | struct usb_gadget *gadget; | ||
355 | 336 | ||
356 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | 337 | struct usb_ep *ep0; /* Copy of gadget->ep0 */ |
357 | struct usb_request *ep0req; // For control responses | 338 | struct usb_request *ep0req; /* Copy of cdev->req */ |
358 | unsigned int ep0_req_tag; | 339 | unsigned int ep0_req_tag; |
359 | const char *ep0req_name; | 340 | const char *ep0req_name; |
360 | 341 | ||
@@ -390,6 +371,13 @@ struct fsg_dev { | |||
390 | u32 usb_amount_left; | 371 | u32 usb_amount_left; |
391 | }; | 372 | }; |
392 | 373 | ||
374 | |||
375 | static inline struct fsg_dev *fsg_from_func(struct usb_function *f) | ||
376 | { | ||
377 | return container_of(f, struct fsg_dev, function); | ||
378 | } | ||
379 | |||
380 | |||
393 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 381 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
394 | 382 | ||
395 | static int exception_in_progress(struct fsg_dev *fsg) | 383 | static int exception_in_progress(struct fsg_dev *fsg) |
@@ -410,10 +398,6 @@ static void set_bulk_out_req_length(struct fsg_dev *fsg, | |||
410 | bh->outreq->length = length; | 398 | bh->outreq->length = length; |
411 | } | 399 | } |
412 | 400 | ||
413 | static struct fsg_dev *the_fsg; | ||
414 | static struct usb_gadget_driver fsg_driver; | ||
415 | |||
416 | |||
417 | /*-------------------------------------------------------------------------*/ | 401 | /*-------------------------------------------------------------------------*/ |
418 | 402 | ||
419 | static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | 403 | static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) |
@@ -433,95 +417,6 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | |||
433 | 417 | ||
434 | /*-------------------------------------------------------------------------*/ | 418 | /*-------------------------------------------------------------------------*/ |
435 | 419 | ||
436 | /* | ||
437 | * DESCRIPTORS ... most are static, but strings and (full) configuration | ||
438 | * descriptors are built on demand. Also the (static) config and interface | ||
439 | * descriptors are adjusted during fsg_bind(). | ||
440 | */ | ||
441 | |||
442 | /* There is only one configuration. */ | ||
443 | #define CONFIG_VALUE 1 | ||
444 | |||
445 | static struct usb_device_descriptor | ||
446 | device_desc = { | ||
447 | .bLength = sizeof device_desc, | ||
448 | .bDescriptorType = USB_DT_DEVICE, | ||
449 | |||
450 | .bcdUSB = cpu_to_le16(0x0200), | ||
451 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
452 | |||
453 | /* The next three values can be overridden by module parameters */ | ||
454 | .idVendor = cpu_to_le16(FSG_VENDOR_ID), | ||
455 | .idProduct = cpu_to_le16(FSG_PRODUCT_ID), | ||
456 | .bcdDevice = cpu_to_le16(0xffff), | ||
457 | |||
458 | .iManufacturer = FSG_STRING_MANUFACTURER, | ||
459 | .iProduct = FSG_STRING_PRODUCT, | ||
460 | .iSerialNumber = FSG_STRING_SERIAL, | ||
461 | .bNumConfigurations = 1, | ||
462 | }; | ||
463 | |||
464 | static struct usb_config_descriptor | ||
465 | config_desc = { | ||
466 | .bLength = sizeof config_desc, | ||
467 | .bDescriptorType = USB_DT_CONFIG, | ||
468 | |||
469 | /* wTotalLength computed by usb_gadget_config_buf() */ | ||
470 | .bNumInterfaces = 1, | ||
471 | .bConfigurationValue = CONFIG_VALUE, | ||
472 | .iConfiguration = FSG_STRING_CONFIG, | ||
473 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
474 | .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, | ||
475 | }; | ||
476 | |||
477 | |||
478 | static struct usb_qualifier_descriptor | ||
479 | dev_qualifier = { | ||
480 | .bLength = sizeof dev_qualifier, | ||
481 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
482 | |||
483 | .bcdUSB = cpu_to_le16(0x0200), | ||
484 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
485 | |||
486 | .bNumConfigurations = 1, | ||
487 | }; | ||
488 | |||
489 | |||
490 | |||
491 | /* | ||
492 | * Config descriptors must agree with the code that sets configurations | ||
493 | * and with code managing interfaces and their altsettings. They must | ||
494 | * also handle different speeds and other-speed requests. | ||
495 | */ | ||
496 | static int populate_config_buf(struct usb_gadget *gadget, | ||
497 | u8 *buf, u8 type, unsigned index) | ||
498 | { | ||
499 | enum usb_device_speed speed = gadget->speed; | ||
500 | int len; | ||
501 | const struct usb_descriptor_header **function; | ||
502 | |||
503 | if (index > 0) | ||
504 | return -EINVAL; | ||
505 | |||
506 | if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) | ||
507 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; | ||
508 | if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH) | ||
509 | function = fsg_hs_function; | ||
510 | else | ||
511 | function = fsg_fs_function; | ||
512 | |||
513 | /* for now, don't advertise srp-only devices */ | ||
514 | if (!gadget_is_otg(gadget)) | ||
515 | function++; | ||
516 | |||
517 | len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); | ||
518 | ((struct usb_config_descriptor *) buf)->bDescriptorType = type; | ||
519 | return len; | ||
520 | } | ||
521 | |||
522 | |||
523 | /*-------------------------------------------------------------------------*/ | ||
524 | |||
525 | /* These routines may be called in process context or in_irq */ | 420 | /* These routines may be called in process context or in_irq */ |
526 | 421 | ||
527 | /* Caller must hold fsg->lock */ | 422 | /* Caller must hold fsg->lock */ |
@@ -555,25 +450,12 @@ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) | |||
555 | 450 | ||
556 | /*-------------------------------------------------------------------------*/ | 451 | /*-------------------------------------------------------------------------*/ |
557 | 452 | ||
558 | /* The disconnect callback and ep0 routines. These always run in_irq, | ||
559 | * except that ep0_queue() is called in the main thread to acknowledge | ||
560 | * completion of various requests: set config, set interface, and | ||
561 | * Bulk-only device reset. */ | ||
562 | |||
563 | static void fsg_disconnect(struct usb_gadget *gadget) | ||
564 | { | ||
565 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
566 | |||
567 | DBG(fsg, "disconnect or port reset\n"); | ||
568 | raise_exception(fsg, FSG_STATE_DISCONNECT); | ||
569 | } | ||
570 | |||
571 | |||
572 | static int ep0_queue(struct fsg_dev *fsg) | 453 | static int ep0_queue(struct fsg_dev *fsg) |
573 | { | 454 | { |
574 | int rc; | 455 | int rc; |
575 | 456 | ||
576 | rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC); | 457 | rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC); |
458 | fsg->ep0->driver_data = fsg; | ||
577 | if (rc != 0 && rc != -ESHUTDOWN) { | 459 | if (rc != 0 && rc != -ESHUTDOWN) { |
578 | 460 | ||
579 | /* We can't do much more than wait for a reset */ | 461 | /* We can't do much more than wait for a reset */ |
@@ -583,23 +465,6 @@ static int ep0_queue(struct fsg_dev *fsg) | |||
583 | return rc; | 465 | return rc; |
584 | } | 466 | } |
585 | 467 | ||
586 | static void ep0_complete(struct usb_ep *ep, struct usb_request *req) | ||
587 | { | ||
588 | struct fsg_dev *fsg = ep->driver_data; | ||
589 | |||
590 | if (req->actual > 0) | ||
591 | dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); | ||
592 | if (req->status || req->actual != req->length) | ||
593 | DBG(fsg, "%s --> %d, %u/%u\n", __func__, | ||
594 | req->status, req->actual, req->length); | ||
595 | if (req->status == -ECONNRESET) // Request was cancelled | ||
596 | usb_ep_fifo_flush(ep); | ||
597 | |||
598 | if (req->status == 0 && req->context) | ||
599 | ((fsg_routine_t) (req->context))(fsg); | ||
600 | } | ||
601 | |||
602 | |||
603 | /*-------------------------------------------------------------------------*/ | 468 | /*-------------------------------------------------------------------------*/ |
604 | 469 | ||
605 | /* Bulk and interrupt endpoint completion handlers. | 470 | /* Bulk and interrupt endpoint completion handlers. |
@@ -652,9 +517,10 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
652 | 517 | ||
653 | /* Ep0 class-specific handlers. These always run in_irq. */ | 518 | /* Ep0 class-specific handlers. These always run in_irq. */ |
654 | 519 | ||
655 | static int class_setup_req(struct fsg_dev *fsg, | 520 | static int fsg_setup(struct usb_function *f, |
656 | const struct usb_ctrlrequest *ctrl) | 521 | const struct usb_ctrlrequest *ctrl) |
657 | { | 522 | { |
523 | struct fsg_dev *fsg = fsg_from_func(f); | ||
658 | struct usb_request *req = fsg->ep0req; | 524 | struct usb_request *req = fsg->ep0req; |
659 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 525 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
660 | u16 w_value = le16_to_cpu(ctrl->wValue); | 526 | u16 w_value = le16_to_cpu(ctrl->wValue); |
@@ -669,7 +535,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
669 | if (ctrl->bRequestType != | 535 | if (ctrl->bRequestType != |
670 | (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 536 | (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
671 | break; | 537 | break; |
672 | if (w_index != 0 || w_value != 0) | 538 | if (w_index != fsg->interface_number || w_value != 0) |
673 | return -EDOM; | 539 | return -EDOM; |
674 | 540 | ||
675 | /* Raise an exception to stop the current operation | 541 | /* Raise an exception to stop the current operation |
@@ -682,7 +548,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
682 | if (ctrl->bRequestType != | 548 | if (ctrl->bRequestType != |
683 | (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 549 | (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
684 | break; | 550 | break; |
685 | if (w_index != 0 || w_value != 0) | 551 | if (w_index != fsg->interface_number || w_value != 0) |
686 | return -EDOM; | 552 | return -EDOM; |
687 | VDBG(fsg, "get max LUN\n"); | 553 | VDBG(fsg, "get max LUN\n"); |
688 | *(u8 *) req->buf = fsg->common->nluns - 1; | 554 | *(u8 *) req->buf = fsg->common->nluns - 1; |
@@ -700,160 +566,6 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
700 | 566 | ||
701 | /*-------------------------------------------------------------------------*/ | 567 | /*-------------------------------------------------------------------------*/ |
702 | 568 | ||
703 | /* Ep0 standard request handlers. These always run in_irq. */ | ||
704 | |||
705 | static int standard_setup_req(struct fsg_dev *fsg, | ||
706 | const struct usb_ctrlrequest *ctrl) | ||
707 | { | ||
708 | struct usb_request *req = fsg->ep0req; | ||
709 | int value = -EOPNOTSUPP; | ||
710 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
711 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
712 | |||
713 | /* Usually this just stores reply data in the pre-allocated ep0 buffer, | ||
714 | * but config change events will also reconfigure hardware. */ | ||
715 | switch (ctrl->bRequest) { | ||
716 | |||
717 | case USB_REQ_GET_DESCRIPTOR: | ||
718 | if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | | ||
719 | USB_RECIP_DEVICE)) | ||
720 | break; | ||
721 | switch (w_value >> 8) { | ||
722 | |||
723 | case USB_DT_DEVICE: | ||
724 | VDBG(fsg, "get device descriptor\n"); | ||
725 | value = sizeof device_desc; | ||
726 | memcpy(req->buf, &device_desc, value); | ||
727 | break; | ||
728 | case USB_DT_DEVICE_QUALIFIER: | ||
729 | VDBG(fsg, "get device qualifier\n"); | ||
730 | if (!gadget_is_dualspeed(fsg->gadget)) | ||
731 | break; | ||
732 | value = sizeof dev_qualifier; | ||
733 | memcpy(req->buf, &dev_qualifier, value); | ||
734 | break; | ||
735 | |||
736 | case USB_DT_OTHER_SPEED_CONFIG: | ||
737 | VDBG(fsg, "get other-speed config descriptor\n"); | ||
738 | if (!gadget_is_dualspeed(fsg->gadget)) | ||
739 | break; | ||
740 | goto get_config; | ||
741 | case USB_DT_CONFIG: | ||
742 | VDBG(fsg, "get configuration descriptor\n"); | ||
743 | get_config: | ||
744 | value = populate_config_buf(fsg->gadget, | ||
745 | req->buf, | ||
746 | w_value >> 8, | ||
747 | w_value & 0xff); | ||
748 | break; | ||
749 | |||
750 | case USB_DT_STRING: | ||
751 | VDBG(fsg, "get string descriptor\n"); | ||
752 | |||
753 | /* wIndex == language code */ | ||
754 | value = usb_gadget_get_string(&fsg_stringtab, | ||
755 | w_value & 0xff, req->buf); | ||
756 | break; | ||
757 | } | ||
758 | break; | ||
759 | |||
760 | /* One config, two speeds */ | ||
761 | case USB_REQ_SET_CONFIGURATION: | ||
762 | if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | | ||
763 | USB_RECIP_DEVICE)) | ||
764 | break; | ||
765 | VDBG(fsg, "set configuration\n"); | ||
766 | if (w_value == CONFIG_VALUE || w_value == 0) { | ||
767 | fsg->new_config = w_value; | ||
768 | |||
769 | /* Raise an exception to wipe out previous transaction | ||
770 | * state (queued bufs, etc) and set the new config. */ | ||
771 | raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); | ||
772 | value = DELAYED_STATUS; | ||
773 | } | ||
774 | break; | ||
775 | case USB_REQ_GET_CONFIGURATION: | ||
776 | if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | | ||
777 | USB_RECIP_DEVICE)) | ||
778 | break; | ||
779 | VDBG(fsg, "get configuration\n"); | ||
780 | *(u8 *) req->buf = fsg->config; | ||
781 | value = 1; | ||
782 | break; | ||
783 | |||
784 | case USB_REQ_SET_INTERFACE: | ||
785 | if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD | | ||
786 | USB_RECIP_INTERFACE)) | ||
787 | break; | ||
788 | if (fsg->config && w_index == 0) { | ||
789 | |||
790 | /* Raise an exception to wipe out previous transaction | ||
791 | * state (queued bufs, etc) and install the new | ||
792 | * interface altsetting. */ | ||
793 | raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE); | ||
794 | value = DELAYED_STATUS; | ||
795 | } | ||
796 | break; | ||
797 | case USB_REQ_GET_INTERFACE: | ||
798 | if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | | ||
799 | USB_RECIP_INTERFACE)) | ||
800 | break; | ||
801 | if (!fsg->config) | ||
802 | break; | ||
803 | if (w_index != 0) { | ||
804 | value = -EDOM; | ||
805 | break; | ||
806 | } | ||
807 | VDBG(fsg, "get interface\n"); | ||
808 | *(u8 *) req->buf = 0; | ||
809 | value = 1; | ||
810 | break; | ||
811 | |||
812 | default: | ||
813 | VDBG(fsg, | ||
814 | "unknown control req %02x.%02x v%04x i%04x l%u\n", | ||
815 | ctrl->bRequestType, ctrl->bRequest, | ||
816 | w_value, w_index, le16_to_cpu(ctrl->wLength)); | ||
817 | } | ||
818 | |||
819 | return value; | ||
820 | } | ||
821 | |||
822 | |||
823 | static int fsg_setup(struct usb_gadget *gadget, | ||
824 | const struct usb_ctrlrequest *ctrl) | ||
825 | { | ||
826 | struct fsg_dev *fsg = get_gadget_data(gadget); | ||
827 | int rc; | ||
828 | int w_length = le16_to_cpu(ctrl->wLength); | ||
829 | |||
830 | ++fsg->ep0_req_tag; // Record arrival of a new request | ||
831 | fsg->ep0req->context = NULL; | ||
832 | fsg->ep0req->length = 0; | ||
833 | dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); | ||
834 | |||
835 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) | ||
836 | rc = class_setup_req(fsg, ctrl); | ||
837 | else | ||
838 | rc = standard_setup_req(fsg, ctrl); | ||
839 | |||
840 | /* Respond with data/status or defer until later? */ | ||
841 | if (rc >= 0 && rc != DELAYED_STATUS) { | ||
842 | rc = min(rc, w_length); | ||
843 | fsg->ep0req->length = rc; | ||
844 | fsg->ep0req->zero = rc < w_length; | ||
845 | fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? | ||
846 | "ep0-in" : "ep0-out"); | ||
847 | rc = ep0_queue(fsg); | ||
848 | } | ||
849 | |||
850 | /* Device either stalls (rc < 0) or reports success */ | ||
851 | return rc; | ||
852 | } | ||
853 | |||
854 | |||
855 | /*-------------------------------------------------------------------------*/ | ||
856 | |||
857 | /* All the following routines run in process context */ | 569 | /* All the following routines run in process context */ |
858 | 570 | ||
859 | 571 | ||
@@ -2518,24 +2230,33 @@ static int do_set_config(struct fsg_dev *fsg, u8 new_config) | |||
2518 | /* Enable the interface */ | 2230 | /* Enable the interface */ |
2519 | if (new_config != 0) { | 2231 | if (new_config != 0) { |
2520 | fsg->config = new_config; | 2232 | fsg->config = new_config; |
2521 | if ((rc = do_set_interface(fsg, 0)) != 0) | 2233 | rc = do_set_interface(fsg, 0); |
2522 | fsg->config = 0; // Reset on errors | 2234 | if (rc != 0) |
2523 | else { | 2235 | fsg->config = 0; /* Reset on errors */ |
2524 | char *speed; | ||
2525 | |||
2526 | switch (fsg->gadget->speed) { | ||
2527 | case USB_SPEED_LOW: speed = "low"; break; | ||
2528 | case USB_SPEED_FULL: speed = "full"; break; | ||
2529 | case USB_SPEED_HIGH: speed = "high"; break; | ||
2530 | default: speed = "?"; break; | ||
2531 | } | ||
2532 | INFO(fsg, "%s speed config #%d\n", speed, fsg->config); | ||
2533 | } | ||
2534 | } | 2236 | } |
2535 | return rc; | 2237 | return rc; |
2536 | } | 2238 | } |
2537 | 2239 | ||
2538 | 2240 | ||
2241 | /****************************** ALT CONFIGS ******************************/ | ||
2242 | |||
2243 | |||
2244 | static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | ||
2245 | { | ||
2246 | struct fsg_dev *fsg = fsg_from_func(f); | ||
2247 | fsg->new_config = 1; | ||
2248 | raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); | ||
2249 | return 0; | ||
2250 | } | ||
2251 | |||
2252 | static void fsg_disable(struct usb_function *f) | ||
2253 | { | ||
2254 | struct fsg_dev *fsg = fsg_from_func(f); | ||
2255 | fsg->new_config = 0; | ||
2256 | raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); | ||
2257 | } | ||
2258 | |||
2259 | |||
2539 | /*-------------------------------------------------------------------------*/ | 2260 | /*-------------------------------------------------------------------------*/ |
2540 | 2261 | ||
2541 | static void handle_exception(struct fsg_dev *fsg) | 2262 | static void handle_exception(struct fsg_dev *fsg) |
@@ -2623,9 +2344,6 @@ static void handle_exception(struct fsg_dev *fsg) | |||
2623 | 2344 | ||
2624 | /* Carry out any extra actions required for the exception */ | 2345 | /* Carry out any extra actions required for the exception */ |
2625 | switch (old_state) { | 2346 | switch (old_state) { |
2626 | default: | ||
2627 | break; | ||
2628 | |||
2629 | case FSG_STATE_ABORT_BULK_OUT: | 2347 | case FSG_STATE_ABORT_BULK_OUT: |
2630 | send_status(fsg); | 2348 | send_status(fsg); |
2631 | spin_lock_irq(&fsg->lock); | 2349 | spin_lock_irq(&fsg->lock); |
@@ -2651,16 +2369,6 @@ static void handle_exception(struct fsg_dev *fsg) | |||
2651 | // fsg->common->luns[i].unit_attention_data = SS_RESET_OCCURRED; | 2369 | // fsg->common->luns[i].unit_attention_data = SS_RESET_OCCURRED; |
2652 | break; | 2370 | break; |
2653 | 2371 | ||
2654 | case FSG_STATE_INTERFACE_CHANGE: | ||
2655 | rc = do_set_interface(fsg, 0); | ||
2656 | if (fsg->ep0_req_tag != exception_req_tag) | ||
2657 | break; | ||
2658 | if (rc != 0) // STALL on errors | ||
2659 | fsg_set_halt(fsg, fsg->ep0); | ||
2660 | else // Complete the status stage | ||
2661 | ep0_queue(fsg); | ||
2662 | break; | ||
2663 | |||
2664 | case FSG_STATE_CONFIG_CHANGE: | 2372 | case FSG_STATE_CONFIG_CHANGE: |
2665 | rc = do_set_config(fsg, new_config); | 2373 | rc = do_set_config(fsg, new_config); |
2666 | if (fsg->ep0_req_tag != exception_req_tag) | 2374 | if (fsg->ep0_req_tag != exception_req_tag) |
@@ -2671,12 +2379,6 @@ static void handle_exception(struct fsg_dev *fsg) | |||
2671 | ep0_queue(fsg); | 2379 | ep0_queue(fsg); |
2672 | break; | 2380 | break; |
2673 | 2381 | ||
2674 | case FSG_STATE_DISCONNECT: | ||
2675 | for (i = 0; i < fsg->common->nluns; ++i) | ||
2676 | fsg_lun_fsync_sub(&fsg->common->luns[i]); | ||
2677 | do_set_config(fsg, 0); // Unconfigured state | ||
2678 | break; | ||
2679 | |||
2680 | case FSG_STATE_EXIT: | 2382 | case FSG_STATE_EXIT: |
2681 | case FSG_STATE_TERMINATED: | 2383 | case FSG_STATE_TERMINATED: |
2682 | do_set_config(fsg, 0); // Free resources | 2384 | do_set_config(fsg, 0); // Free resources |
@@ -2684,6 +2386,14 @@ static void handle_exception(struct fsg_dev *fsg) | |||
2684 | fsg->state = FSG_STATE_TERMINATED; // Stop the thread | 2386 | fsg->state = FSG_STATE_TERMINATED; // Stop the thread |
2685 | spin_unlock_irq(&fsg->lock); | 2387 | spin_unlock_irq(&fsg->lock); |
2686 | break; | 2388 | break; |
2389 | |||
2390 | case FSG_STATE_INTERFACE_CHANGE: | ||
2391 | case FSG_STATE_DISCONNECT: | ||
2392 | case FSG_STATE_COMMAND_PHASE: | ||
2393 | case FSG_STATE_DATA_PHASE: | ||
2394 | case FSG_STATE_STATUS_PHASE: | ||
2395 | case FSG_STATE_IDLE: | ||
2396 | break; | ||
2687 | } | 2397 | } |
2688 | } | 2398 | } |
2689 | 2399 | ||
@@ -2744,16 +2454,17 @@ static int fsg_main_thread(void *fsg_) | |||
2744 | if (!exception_in_progress(fsg)) | 2454 | if (!exception_in_progress(fsg)) |
2745 | fsg->state = FSG_STATE_IDLE; | 2455 | fsg->state = FSG_STATE_IDLE; |
2746 | spin_unlock_irq(&fsg->lock); | 2456 | spin_unlock_irq(&fsg->lock); |
2747 | } | 2457 | } |
2748 | 2458 | ||
2749 | spin_lock_irq(&fsg->lock); | 2459 | spin_lock_irq(&fsg->lock); |
2750 | fsg->thread_task = NULL; | 2460 | fsg->thread_task = NULL; |
2751 | spin_unlock_irq(&fsg->lock); | 2461 | spin_unlock_irq(&fsg->lock); |
2752 | 2462 | ||
2463 | /* XXX */ | ||
2753 | /* If we are exiting because of a signal, unregister the | 2464 | /* If we are exiting because of a signal, unregister the |
2754 | * gadget driver. */ | 2465 | * gadget driver. */ |
2755 | if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) | 2466 | /* if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) */ |
2756 | usb_gadget_unregister_driver(&fsg_driver); | 2467 | /* usb_gadget_unregister_driver(&fsg_driver); */ |
2757 | 2468 | ||
2758 | /* Let the unbind and cleanup routines know the thread has exited */ | 2469 | /* Let the unbind and cleanup routines know the thread has exited */ |
2759 | complete_and_exit(&fsg->thread_notifier, 0); | 2470 | complete_and_exit(&fsg->thread_notifier, 0); |
@@ -2762,10 +2473,9 @@ static int fsg_main_thread(void *fsg_) | |||
2762 | 2473 | ||
2763 | /*************************** DEVICE ATTRIBUTES ***************************/ | 2474 | /*************************** DEVICE ATTRIBUTES ***************************/ |
2764 | 2475 | ||
2765 | 2476 | /* Write permission is checked per LUN in store_*() functions. */ | |
2766 | /* The write permissions and store_xxx pointers are set in fsg_bind() */ | 2477 | static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro); |
2767 | static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); | 2478 | static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file); |
2768 | static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); | ||
2769 | 2479 | ||
2770 | 2480 | ||
2771 | /****************************** FSG COMMON ******************************/ | 2481 | /****************************** FSG COMMON ******************************/ |
@@ -2789,11 +2499,13 @@ static inline void fsg_common_put(struct fsg_common *common) | |||
2789 | 2499 | ||
2790 | 2500 | ||
2791 | static struct fsg_common *fsg_common_init(struct fsg_common *common, | 2501 | static struct fsg_common *fsg_common_init(struct fsg_common *common, |
2792 | struct usb_gadget *gadget) | 2502 | struct usb_composite_dev *cdev) |
2793 | { | 2503 | { |
2504 | struct usb_gadget *gadget = cdev->gadget; | ||
2794 | struct fsg_buffhd *bh; | 2505 | struct fsg_buffhd *bh; |
2795 | struct fsg_lun *curlun; | 2506 | struct fsg_lun *curlun; |
2796 | int nluns, i, rc; | 2507 | int nluns, i, rc; |
2508 | char *pathbuf; | ||
2797 | 2509 | ||
2798 | /* Find out how many LUNs there should be */ | 2510 | /* Find out how many LUNs there should be */ |
2799 | nluns = mod_data.nluns; | 2511 | nluns = mod_data.nluns; |
@@ -2833,7 +2545,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2833 | curlun->removable = mod_data.removable; | 2545 | curlun->removable = mod_data.removable; |
2834 | curlun->dev.release = fsg_lun_release; | 2546 | curlun->dev.release = fsg_lun_release; |
2835 | curlun->dev.parent = &gadget->dev; | 2547 | curlun->dev.parent = &gadget->dev; |
2836 | curlun->dev.driver = &fsg_driver.driver; | 2548 | /* curlun->dev.driver = &fsg_driver.driver; XXX */ |
2837 | dev_set_drvdata(&curlun->dev, &common->filesem); | 2549 | dev_set_drvdata(&curlun->dev, &common->filesem); |
2838 | dev_set_name(&curlun->dev,"%s-lun%d", | 2550 | dev_set_name(&curlun->dev,"%s-lun%d", |
2839 | dev_name(&gadget->dev), i); | 2551 | dev_name(&gadget->dev), i); |
@@ -2906,6 +2618,33 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2906 | 2618 | ||
2907 | 2619 | ||
2908 | kref_init(&common->ref); | 2620 | kref_init(&common->ref); |
2621 | |||
2622 | /* Information */ | ||
2623 | INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); | ||
2624 | INFO(common, "Number of LUNs=%d\n", common->nluns); | ||
2625 | |||
2626 | pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); | ||
2627 | for (i = 0, nluns = common->nluns, curlun = common->luns; | ||
2628 | i < nluns; | ||
2629 | ++curlun, ++i) { | ||
2630 | char *p = "(no medium)"; | ||
2631 | if (fsg_lun_is_open(curlun)) { | ||
2632 | p = "(error)"; | ||
2633 | if (pathbuf) { | ||
2634 | p = d_path(&curlun->filp->f_path, | ||
2635 | pathbuf, PATH_MAX); | ||
2636 | if (IS_ERR(p)) | ||
2637 | p = "(error)"; | ||
2638 | } | ||
2639 | } | ||
2640 | LINFO(curlun, "LUN: %s%s%sfile: %s\n", | ||
2641 | curlun->removable ? "removable " : "", | ||
2642 | curlun->ro ? "read only " : "", | ||
2643 | curlun->cdrom ? "CD-ROM " : "", | ||
2644 | p); | ||
2645 | } | ||
2646 | kfree(pathbuf); | ||
2647 | |||
2909 | return common; | 2648 | return common; |
2910 | 2649 | ||
2911 | 2650 | ||
@@ -2944,10 +2683,9 @@ static void fsg_common_release(struct kref *ref) | |||
2944 | /*-------------------------------------------------------------------------*/ | 2683 | /*-------------------------------------------------------------------------*/ |
2945 | 2684 | ||
2946 | 2685 | ||
2947 | static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) | 2686 | static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) |
2948 | { | 2687 | { |
2949 | struct fsg_dev *fsg = get_gadget_data(gadget); | 2688 | struct fsg_dev *fsg = fsg_from_func(f); |
2950 | struct usb_request *req = fsg->ep0req; | ||
2951 | 2689 | ||
2952 | DBG(fsg, "unbind\n"); | 2690 | DBG(fsg, "unbind\n"); |
2953 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 2691 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
@@ -2961,59 +2699,31 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) | |||
2961 | complete(&fsg->thread_notifier); | 2699 | complete(&fsg->thread_notifier); |
2962 | } | 2700 | } |
2963 | 2701 | ||
2964 | /* Free the request and buffer for endpoint 0 */ | ||
2965 | if (req) { | ||
2966 | kfree(req->buf); | ||
2967 | usb_ep_free_request(fsg->ep0, req); | ||
2968 | } | ||
2969 | |||
2970 | fsg_common_put(fsg->common); | 2702 | fsg_common_put(fsg->common); |
2971 | kfree(fsg); | 2703 | kfree(fsg); |
2972 | set_gadget_data(gadget, NULL); | ||
2973 | } | 2704 | } |
2974 | 2705 | ||
2975 | 2706 | ||
2976 | static int __init fsg_bind(struct usb_gadget *gadget) | 2707 | static int fsg_bind(struct usb_configuration *c, struct usb_function *f) |
2977 | { | 2708 | { |
2978 | struct fsg_dev *fsg; | 2709 | struct fsg_dev *fsg = fsg_from_func(f); |
2710 | struct usb_gadget *gadget = c->cdev->gadget; | ||
2979 | int rc; | 2711 | int rc; |
2980 | int i; | 2712 | int i; |
2981 | struct fsg_lun *curlun; | ||
2982 | struct usb_ep *ep; | 2713 | struct usb_ep *ep; |
2983 | struct usb_request *req; | ||
2984 | char *pathbuf, *p; | ||
2985 | 2714 | ||
2986 | /* Allocate */ | ||
2987 | fsg = kzalloc(sizeof *fsg, GFP_KERNEL); | ||
2988 | if (!fsg) | ||
2989 | return -ENOMEM; | ||
2990 | |||
2991 | /* Initialise common */ | ||
2992 | fsg->common = fsg_common_init(0, gadget); | ||
2993 | if (IS_ERR(fsg->common)) | ||
2994 | return PTR_ERR(fsg->common); | ||
2995 | |||
2996 | /* Basic parameters */ | ||
2997 | fsg->gadget = gadget; | 2715 | fsg->gadget = gadget; |
2998 | set_gadget_data(gadget, fsg); | ||
2999 | fsg->ep0 = gadget->ep0; | 2716 | fsg->ep0 = gadget->ep0; |
3000 | fsg->ep0->driver_data = fsg; | 2717 | fsg->ep0req = c->cdev->req; |
3001 | 2718 | ||
3002 | spin_lock_init(&fsg->lock); | 2719 | /* New interface */ |
3003 | init_completion(&fsg->thread_notifier); | 2720 | i = usb_interface_id(c, f); |
3004 | 2721 | if (i < 0) | |
3005 | /* Enable the store_xxx attributes */ | 2722 | return i; |
3006 | if (mod_data.removable) { | 2723 | fsg_intf_desc.bInterfaceNumber = i; |
3007 | dev_attr_file.attr.mode = 0644; | 2724 | fsg->interface_number = i; |
3008 | dev_attr_file.store = fsg_store_file; | ||
3009 | if (!mod_data.cdrom) { | ||
3010 | dev_attr_ro.attr.mode = 0644; | ||
3011 | dev_attr_ro.store = fsg_store_ro; | ||
3012 | } | ||
3013 | } | ||
3014 | 2725 | ||
3015 | /* Find all the endpoints we will use */ | 2726 | /* Find all the endpoints we will use */ |
3016 | usb_ep_autoconfig_reset(gadget); | ||
3017 | ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); | 2727 | ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); |
3018 | if (!ep) | 2728 | if (!ep) |
3019 | goto autoconf_fail; | 2729 | goto autoconf_fail; |
@@ -3026,53 +2736,26 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3026 | ep->driver_data = fsg; // claim the endpoint | 2736 | ep->driver_data = fsg; // claim the endpoint |
3027 | fsg->bulk_out = ep; | 2737 | fsg->bulk_out = ep; |
3028 | 2738 | ||
3029 | /* Fix up the descriptors */ | ||
3030 | device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; | ||
3031 | device_desc.bcdDevice = cpu_to_le16(mod_data.release); | ||
3032 | |||
3033 | if (gadget_is_dualspeed(gadget)) { | 2739 | if (gadget_is_dualspeed(gadget)) { |
3034 | /* Assume ep0 uses the same maxpacket value for both speeds */ | ||
3035 | dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; | ||
3036 | |||
3037 | /* Assume endpoint addresses are the same for both speeds */ | 2740 | /* Assume endpoint addresses are the same for both speeds */ |
3038 | fsg_hs_bulk_in_desc.bEndpointAddress = | 2741 | fsg_hs_bulk_in_desc.bEndpointAddress = |
3039 | fsg_fs_bulk_in_desc.bEndpointAddress; | 2742 | fsg_fs_bulk_in_desc.bEndpointAddress; |
3040 | fsg_hs_bulk_out_desc.bEndpointAddress = | 2743 | fsg_hs_bulk_out_desc.bEndpointAddress = |
3041 | fsg_fs_bulk_out_desc.bEndpointAddress; | 2744 | fsg_fs_bulk_out_desc.bEndpointAddress; |
2745 | f->hs_descriptors = fsg_hs_function; | ||
3042 | } | 2746 | } |
3043 | 2747 | ||
3044 | if (gadget_is_otg(gadget)) | ||
3045 | fsg_otg_desc.bmAttributes |= USB_OTG_HNP; | ||
3046 | |||
3047 | rc = -ENOMEM; | ||
3048 | |||
3049 | /* Allocate the request and buffer for endpoint 0 */ | ||
3050 | fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); | ||
3051 | if (!req) | ||
3052 | goto out; | ||
3053 | req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL); | ||
3054 | if (!req->buf) | ||
3055 | goto out; | ||
3056 | req->complete = ep0_complete; | ||
3057 | |||
3058 | /* This should reflect the actual gadget power source */ | ||
3059 | usb_gadget_set_selfpowered(gadget); | ||
3060 | |||
3061 | snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer, | ||
3062 | "%s %s with %s", | ||
3063 | init_utsname()->sysname, init_utsname()->release, | ||
3064 | gadget->name); | ||
3065 | |||
3066 | /* On a real device, serial[] would be loaded from permanent | ||
3067 | * storage. We just encode it from the driver version string. */ | ||
3068 | for (i = 0; i < sizeof fsg_string_serial - 2; i += 2) { | ||
3069 | unsigned char c = DRIVER_VERSION[i / 2]; | ||
3070 | 2748 | ||
3071 | if (!c) | 2749 | /* maybe allocate device-global string IDs, and patch descriptors */ |
3072 | break; | 2750 | if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { |
3073 | sprintf(&fsg_string_serial[i], "%02X", c); | 2751 | i = usb_string_id(c->cdev); |
2752 | if (i < 0) | ||
2753 | return i; | ||
2754 | fsg_strings[FSG_STRING_INTERFACE].id = i; | ||
2755 | fsg_intf_desc.iInterface = i; | ||
3074 | } | 2756 | } |
3075 | 2757 | ||
2758 | |||
3076 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, | 2759 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, |
3077 | "file-storage-gadget"); | 2760 | "file-storage-gadget"); |
3078 | if (IS_ERR(fsg->thread_task)) { | 2761 | if (IS_ERR(fsg->thread_task)) { |
@@ -3080,37 +2763,12 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3080 | goto out; | 2763 | goto out; |
3081 | } | 2764 | } |
3082 | 2765 | ||
3083 | INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); | ||
3084 | INFO(fsg, "Number of LUNs=%d\n", fsg->common->nluns); | ||
3085 | |||
3086 | pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); | ||
3087 | for (i = 0; i < fsg->common->nluns; ++i) { | ||
3088 | curlun = &fsg->common->luns[i]; | ||
3089 | if (fsg_lun_is_open(curlun)) { | ||
3090 | p = NULL; | ||
3091 | if (pathbuf) { | ||
3092 | p = d_path(&curlun->filp->f_path, | ||
3093 | pathbuf, PATH_MAX); | ||
3094 | if (IS_ERR(p)) | ||
3095 | p = NULL; | ||
3096 | } | ||
3097 | LINFO(curlun, "ro=%d, file: %s\n", | ||
3098 | curlun->ro, (p ? p : "(error)")); | ||
3099 | } | ||
3100 | } | ||
3101 | kfree(pathbuf); | ||
3102 | |||
3103 | DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", | ||
3104 | mod_data.removable, mod_data.can_stall, | ||
3105 | mod_data.cdrom, FSG_BUFLEN); | ||
3106 | DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); | 2766 | DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); |
3107 | 2767 | ||
3108 | set_bit(REGISTERED, &fsg->atomic_bitflags); | 2768 | set_bit(REGISTERED, &fsg->atomic_bitflags); |
3109 | 2769 | ||
3110 | /* Tell the thread to start working */ | 2770 | /* Tell the thread to start working */ |
3111 | wake_up_process(fsg->thread_task); | 2771 | wake_up_process(fsg->thread_task); |
3112 | |||
3113 | the_fsg = fsg; | ||
3114 | return 0; | 2772 | return 0; |
3115 | 2773 | ||
3116 | autoconf_fail: | 2774 | autoconf_fail: |
@@ -3119,48 +2777,56 @@ autoconf_fail: | |||
3119 | 2777 | ||
3120 | out: | 2778 | out: |
3121 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead | 2779 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead |
3122 | fsg_unbind(gadget); | 2780 | fsg_unbind(c, f); |
3123 | complete(&fsg->thread_notifier); | 2781 | complete(&fsg->thread_notifier); |
3124 | return rc; | 2782 | return rc; |
3125 | } | 2783 | } |
3126 | 2784 | ||
3127 | 2785 | ||
3128 | /*-------------------------------------------------------------------------*/ | 2786 | /****************************** ADD FUNCTION ******************************/ |
3129 | 2787 | ||
3130 | static struct usb_gadget_driver fsg_driver = { | 2788 | static struct usb_gadget_strings *fsg_strings_array[] = { |
3131 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 2789 | &fsg_stringtab, |
3132 | .speed = USB_SPEED_HIGH, | 2790 | NULL, |
3133 | #else | ||
3134 | .speed = USB_SPEED_FULL, | ||
3135 | #endif | ||
3136 | .function = (char *) fsg_string_product, | ||
3137 | .bind = fsg_bind, | ||
3138 | .unbind = fsg_unbind, | ||
3139 | .disconnect = fsg_disconnect, | ||
3140 | .setup = fsg_setup, | ||
3141 | |||
3142 | .driver = { | ||
3143 | .name = DRIVER_NAME, | ||
3144 | .owner = THIS_MODULE, | ||
3145 | // .release = ... | ||
3146 | // .suspend = ... | ||
3147 | // .resume = ... | ||
3148 | }, | ||
3149 | }; | 2791 | }; |
3150 | 2792 | ||
3151 | 2793 | static int fsg_add(struct usb_composite_dev *cdev, | |
3152 | static int __init fsg_init(void) | 2794 | struct usb_configuration *c, |
2795 | struct fsg_common *common) | ||
3153 | { | 2796 | { |
3154 | return usb_gadget_register_driver(&fsg_driver); | 2797 | struct fsg_dev *fsg; |
3155 | } | 2798 | int rc; |
3156 | module_init(fsg_init); | 2799 | |
2800 | fsg = kzalloc(sizeof *fsg, GFP_KERNEL); | ||
2801 | if (unlikely(!fsg)) | ||
2802 | return -ENOMEM; | ||
3157 | 2803 | ||
2804 | spin_lock_init(&fsg->lock); | ||
2805 | init_completion(&fsg->thread_notifier); | ||
3158 | 2806 | ||
3159 | static void __exit fsg_cleanup(void) | 2807 | fsg->cdev = cdev; |
3160 | { | 2808 | fsg->function.name = FSG_DRIVER_DESC; |
3161 | /* Unregister the driver iff the thread hasn't already done so */ | 2809 | fsg->function.strings = fsg_strings_array; |
3162 | if (the_fsg && | 2810 | fsg->function.descriptors = fsg_fs_function; |
3163 | test_and_clear_bit(REGISTERED, &the_fsg->atomic_bitflags)) | 2811 | fsg->function.bind = fsg_bind; |
3164 | usb_gadget_unregister_driver(&fsg_driver); | 2812 | fsg->function.unbind = fsg_unbind; |
2813 | fsg->function.setup = fsg_setup; | ||
2814 | fsg->function.set_alt = fsg_set_alt; | ||
2815 | fsg->function.disable = fsg_disable; | ||
2816 | |||
2817 | fsg->common = common; | ||
2818 | /* Our caller holds a reference to common structure so we | ||
2819 | * don't have to be worry about it being freed until we return | ||
2820 | * from this function. So instead of incrementing counter now | ||
2821 | * and decrement in error recovery we increment it only when | ||
2822 | * call to usb_add_function() was successful. */ | ||
2823 | |||
2824 | rc = usb_add_function(c, &fsg->function); | ||
2825 | |||
2826 | if (likely(rc == 0)) | ||
2827 | fsg_common_get(fsg->common); | ||
2828 | else | ||
2829 | kfree(fsg); | ||
2830 | |||
2831 | return rc; | ||
3165 | } | 2832 | } |
3166 | module_exit(fsg_cleanup); | ||
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 7998402b1840..fca3407e48f2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -594,10 +594,9 @@ static int populate_config_buf(struct usb_gadget *gadget, | |||
594 | 594 | ||
595 | if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) | 595 | if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) |
596 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; | 596 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; |
597 | if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH) | 597 | function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH |
598 | function = fsg_hs_function; | 598 | ? (const struct usb_descriptor_header **)fsg_hs_function |
599 | else | 599 | : (const struct usb_descriptor_header **)fsg_fs_function; |
600 | function = fsg_fs_function; | ||
601 | 600 | ||
602 | /* for now, don't advertise srp-only devices */ | 601 | /* for now, don't advertise srp-only devices */ |
603 | if (!gadget_is_otg(gadget)) | 602 | if (!gadget_is_otg(gadget)) |
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c new file mode 100644 index 000000000000..27339f04bc1b --- /dev/null +++ b/drivers/usb/gadget/mass_storage.c | |||
@@ -0,0 +1,233 @@ | |||
1 | /* | ||
2 | * mass_storage.c -- File-backed USB Storage Gadget, for USB development | ||
3 | * | ||
4 | * Copyright (C) 2003-2008 Alan Stern | ||
5 | * | ||
6 | * Copyright (C) 2009 Samsung Electronics | ||
7 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | |||
25 | /* | ||
26 | * The Mass Storage Gadget acts as a USB Mass Storage device, | ||
27 | * appearing to the host as a disk drive or as a CD-ROM drive. In | ||
28 | * addition to providing an example of a genuinely useful gadget | ||
29 | * driver for a USB device, it also illustrates a technique of | ||
30 | * double-buffering for increased throughput. Last but not least, it | ||
31 | * gives an easy way to probe the behavior of the Mass Storage drivers | ||
32 | * in a USB host. | ||
33 | * | ||
34 | * Since this file serves only administrative purposes and all the | ||
35 | * business logic is implemented in f_mass_storage.* file. Read | ||
36 | * comments in this file for more detailed description. | ||
37 | */ | ||
38 | |||
39 | |||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/utsname.h> | ||
42 | #include <linux/usb/ch9.h> | ||
43 | |||
44 | |||
45 | /*-------------------------------------------------------------------------*/ | ||
46 | |||
47 | #define DRIVER_DESC "Mass Storage Gadget" | ||
48 | #define DRIVER_VERSION "2009/07/21" | ||
49 | |||
50 | /*-------------------------------------------------------------------------*/ | ||
51 | |||
52 | /* | ||
53 | * kbuild is not very cooperative with respect to linking separately | ||
54 | * compiled library objects into one module. So for now we won't use | ||
55 | * separate compilation ... ensuring init/exit sections work to shrink | ||
56 | * the runtime footprint, and giving us at least some parts of what | ||
57 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
58 | */ | ||
59 | |||
60 | #include "composite.c" | ||
61 | #include "usbstring.c" | ||
62 | #include "config.c" | ||
63 | #include "epautoconf.c" | ||
64 | #include "f_mass_storage.c" | ||
65 | |||
66 | /*-------------------------------------------------------------------------*/ | ||
67 | |||
68 | static struct usb_device_descriptor msg_device_desc = { | ||
69 | .bLength = sizeof msg_device_desc, | ||
70 | .bDescriptorType = USB_DT_DEVICE, | ||
71 | |||
72 | .bcdUSB = cpu_to_le16(0x0200), | ||
73 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
74 | |||
75 | /* Vendor and product id can be overridden by module parameters. */ | ||
76 | .idVendor = cpu_to_le16(FSG_VENDOR_ID), | ||
77 | .idProduct = cpu_to_le16(FSG_PRODUCT_ID), | ||
78 | /* .bcdDevice = f(hardware) */ | ||
79 | /* .iManufacturer = DYNAMIC */ | ||
80 | /* .iProduct = DYNAMIC */ | ||
81 | /* NO SERIAL NUMBER */ | ||
82 | .bNumConfigurations = 1, | ||
83 | }; | ||
84 | |||
85 | static struct usb_otg_descriptor otg_descriptor = { | ||
86 | .bLength = sizeof otg_descriptor, | ||
87 | .bDescriptorType = USB_DT_OTG, | ||
88 | |||
89 | /* REVISIT SRP-only hardware is possible, although | ||
90 | * it would not be called "OTG" ... | ||
91 | */ | ||
92 | .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, | ||
93 | }; | ||
94 | |||
95 | static const struct usb_descriptor_header *otg_desc[] = { | ||
96 | (struct usb_descriptor_header *) &otg_descriptor, | ||
97 | NULL, | ||
98 | }; | ||
99 | |||
100 | |||
101 | /* string IDs are assigned dynamically */ | ||
102 | |||
103 | #define STRING_MANUFACTURER_IDX 0 | ||
104 | #define STRING_PRODUCT_IDX 1 | ||
105 | #define STRING_CONFIGURATION_IDX 2 | ||
106 | |||
107 | static char manufacturer[50]; | ||
108 | |||
109 | static struct usb_string strings_dev[] = { | ||
110 | [STRING_MANUFACTURER_IDX].s = manufacturer, | ||
111 | [STRING_PRODUCT_IDX].s = DRIVER_DESC, | ||
112 | [STRING_CONFIGURATION_IDX].s = "Self Powered", | ||
113 | { } /* end of list */ | ||
114 | }; | ||
115 | |||
116 | static struct usb_gadget_strings stringtab_dev = { | ||
117 | .language = 0x0409, /* en-us */ | ||
118 | .strings = strings_dev, | ||
119 | }; | ||
120 | |||
121 | static struct usb_gadget_strings *dev_strings[] = { | ||
122 | &stringtab_dev, | ||
123 | NULL, | ||
124 | }; | ||
125 | |||
126 | |||
127 | |||
128 | /****************************** Configurations ******************************/ | ||
129 | |||
130 | static int __init msg_do_config(struct usb_configuration *c) | ||
131 | { | ||
132 | struct fsg_common *common; | ||
133 | int ret; | ||
134 | |||
135 | if (gadget_is_otg(c->cdev->gadget)) { | ||
136 | c->descriptors = otg_desc; | ||
137 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
138 | } | ||
139 | |||
140 | common = fsg_common_init(0, c->cdev); | ||
141 | if (IS_ERR(common)) | ||
142 | return PTR_ERR(common); | ||
143 | |||
144 | ret = fsg_add(c->cdev, c, common); | ||
145 | fsg_common_put(common); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | static struct usb_configuration msg_config_driver = { | ||
150 | .label = "Linux File-Backed Storage", | ||
151 | .bind = msg_do_config, | ||
152 | .bConfigurationValue = 1, | ||
153 | /* .iConfiguration = DYNAMIC */ | ||
154 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
155 | }; | ||
156 | |||
157 | |||
158 | |||
159 | /****************************** Gadget Bind ******************************/ | ||
160 | |||
161 | |||
162 | static int __init msg_bind(struct usb_composite_dev *cdev) | ||
163 | { | ||
164 | struct usb_gadget *gadget = cdev->gadget; | ||
165 | int status; | ||
166 | |||
167 | /* Allocate string descriptor numbers ... note that string | ||
168 | * contents can be overridden by the composite_dev glue. | ||
169 | */ | ||
170 | |||
171 | /* device descriptor strings: manufacturer, product */ | ||
172 | snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", | ||
173 | init_utsname()->sysname, init_utsname()->release, | ||
174 | gadget->name); | ||
175 | status = usb_string_id(cdev); | ||
176 | if (status < 0) | ||
177 | return status; | ||
178 | strings_dev[STRING_MANUFACTURER_IDX].id = status; | ||
179 | msg_device_desc.iManufacturer = status; | ||
180 | |||
181 | status = usb_string_id(cdev); | ||
182 | if (status < 0) | ||
183 | return status; | ||
184 | strings_dev[STRING_PRODUCT_IDX].id = status; | ||
185 | msg_device_desc.iProduct = status; | ||
186 | |||
187 | status = usb_string_id(cdev); | ||
188 | if (status < 0) | ||
189 | return status; | ||
190 | strings_dev[STRING_CONFIGURATION_IDX].id = status; | ||
191 | msg_config_driver.iConfiguration = status; | ||
192 | |||
193 | /* register our second configuration */ | ||
194 | status = usb_add_config(cdev, &msg_config_driver); | ||
195 | if (status < 0) | ||
196 | return status; | ||
197 | |||
198 | dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int __exit msg_unbind(struct usb_composite_dev *cdev) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | |||
208 | /****************************** Some noise ******************************/ | ||
209 | |||
210 | |||
211 | static struct usb_composite_driver msg_driver = { | ||
212 | .name = "g_mass_storage", | ||
213 | .dev = &msg_device_desc, | ||
214 | .strings = dev_strings, | ||
215 | .bind = msg_bind, | ||
216 | .unbind = __exit_p(msg_unbind), | ||
217 | }; | ||
218 | |||
219 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
220 | MODULE_AUTHOR("Michal Nazarewicz"); | ||
221 | MODULE_LICENSE("GPL"); | ||
222 | |||
223 | static int __init msg_init(void) | ||
224 | { | ||
225 | return usb_composite_register(&msg_driver); | ||
226 | } | ||
227 | module_init(msg_init); | ||
228 | |||
229 | static void __exit msg_cleanup(void) | ||
230 | { | ||
231 | usb_composite_unregister(&msg_driver); | ||
232 | } | ||
233 | module_exit(msg_cleanup); | ||
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 60bc696778c9..7e81a2d898f0 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -84,11 +84,19 @@ | |||
84 | #define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args) | 84 | #define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args) |
85 | #define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args) | 85 | #define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args) |
86 | 86 | ||
87 | #define DBG(d, fmt, args...) dev_dbg (&(d)->gadget->dev, fmt, ## args) | 87 | /* Keep those macros in sync with thos in |
88 | #define VDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev, fmt, ## args) | 88 | * include/linux/ubs/composite.h or else GCC will complain. If they |
89 | #define ERROR(d, fmt, args...) dev_err (&(d)->gadget->dev, fmt, ## args) | 89 | * are identical (the same names of arguments, white spaces in the |
90 | #define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev, fmt, ## args) | 90 | * same places) GCC will allow redefinition otherwise (even if some |
91 | #define INFO(d, fmt, args...) dev_info(&(d)->gadget->dev, fmt, ## args) | 91 | * white space is removed or added) warning will be issued. No |
92 | * checking if those symbols is defined is performed because warning | ||
93 | * is desired when those macros were defined by someone else to mean | ||
94 | * something else. */ | ||
95 | #define DBG(d, fmt, args...) dev_dbg(&(d)->gadget->dev , fmt , ## args) | ||
96 | #define VDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev , fmt , ## args) | ||
97 | #define ERROR(d, fmt, args...) dev_err(&(d)->gadget->dev , fmt , ## args) | ||
98 | #define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev , fmt , ## args) | ||
99 | #define INFO(d, fmt, args...) dev_info(&(d)->gadget->dev , fmt , ## args) | ||
92 | 100 | ||
93 | 101 | ||
94 | 102 | ||
@@ -429,7 +437,7 @@ fsg_fs_intr_in_desc = { | |||
429 | 437 | ||
430 | #endif | 438 | #endif |
431 | 439 | ||
432 | static const struct usb_descriptor_header *fsg_fs_function[] = { | 440 | static struct usb_descriptor_header *fsg_fs_function[] = { |
433 | #ifndef FSG_NO_OTG | 441 | #ifndef FSG_NO_OTG |
434 | (struct usb_descriptor_header *) &fsg_otg_desc, | 442 | (struct usb_descriptor_header *) &fsg_otg_desc, |
435 | #endif | 443 | #endif |
@@ -493,7 +501,7 @@ fsg_hs_intr_in_desc = { | |||
493 | 501 | ||
494 | #endif | 502 | #endif |
495 | 503 | ||
496 | static const struct usb_descriptor_header *fsg_hs_function[] = { | 504 | static struct usb_descriptor_header *fsg_hs_function[] = { |
497 | #ifndef FSG_NO_OTG | 505 | #ifndef FSG_NO_OTG |
498 | (struct usb_descriptor_header *) &fsg_otg_desc, | 506 | (struct usb_descriptor_header *) &fsg_otg_desc, |
499 | #endif | 507 | #endif |