blob: 878776888ee6b76d06bd9f3e998e44a120c75a73 [file] [log] [blame]
Pavankumar Kondetia51de952012-06-25 13:57:11 +05301/* Target based USB-Gadget Function
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -07002 *
3 * UAS protocol handling, target callbacks, configfs handling,
4 * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling.
5 *
6 * Author: Sebastian Andrzej Siewior <bigeasy at linutronix dot de>
7 * License: GPLv2 as published by FSF.
8 */
Pavankumar Kondetia51de952012-06-25 13:57:11 +05309
10#include <linux/init.h>
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070011#include <linux/module.h>
Pavankumar Kondetia51de952012-06-25 13:57:11 +053012
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070013#include <linux/usb/composite.h>
14#include <linux/usb/gadget.h>
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070015
16#include "usbstring.c"
17#include "epautoconf.c"
18#include "config.c"
19#include "composite.c"
20
Pavankumar Kondetia51de952012-06-25 13:57:11 +053021#include "f_tcm.c"
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070022
23#define UAS_VENDOR_ID 0x0525 /* NetChip */
24#define UAS_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */
25
Pavankumar Kondetia51de952012-06-25 13:57:11 +053026#define USB_G_STR_MANUFACTOR 1
27#define USB_G_STR_PRODUCT 2
28#define USB_G_STR_SERIAL 3
29#define USB_G_STR_CONFIG 4
30
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070031static struct usb_device_descriptor usbg_device_desc = {
32 .bLength = sizeof(usbg_device_desc),
33 .bDescriptorType = USB_DT_DEVICE,
34 .bcdUSB = cpu_to_le16(0x0200),
35 .bDeviceClass = USB_CLASS_PER_INTERFACE,
36 .idVendor = cpu_to_le16(UAS_VENDOR_ID),
37 .idProduct = cpu_to_le16(UAS_PRODUCT_ID),
38 .iManufacturer = USB_G_STR_MANUFACTOR,
39 .iProduct = USB_G_STR_PRODUCT,
40 .iSerialNumber = USB_G_STR_SERIAL,
41
42 .bNumConfigurations = 1,
43};
44
45static struct usb_string usbg_us_strings[] = {
46 { USB_G_STR_MANUFACTOR, "Target Manufactor"},
47 { USB_G_STR_PRODUCT, "Target Product"},
48 { USB_G_STR_SERIAL, "000000000001"},
49 { USB_G_STR_CONFIG, "default config"},
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070050 { },
51};
52
53static struct usb_gadget_strings usbg_stringtab = {
54 .language = 0x0409,
55 .strings = usbg_us_strings,
56};
57
58static struct usb_gadget_strings *usbg_strings[] = {
59 &usbg_stringtab,
60 NULL,
61};
62
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070063static struct usb_configuration usbg_config_driver = {
64 .label = "Linux Target",
65 .bConfigurationValue = 1,
66 .iConfiguration = USB_G_STR_CONFIG,
67 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
68};
69
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070070static int usbg_cfg_bind(struct usb_configuration *c)
71{
Pavankumar Kondetia51de952012-06-25 13:57:11 +053072 return tcm_bind_config(c);
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070073}
74
75static int usb_target_bind(struct usb_composite_dev *cdev)
76{
77 int ret;
78
79 ret = usb_add_config(cdev, &usbg_config_driver,
80 usbg_cfg_bind);
Pavankumar Kondetia51de952012-06-25 13:57:11 +053081 return ret;
82}
83
84static int guas_unbind(struct usb_composite_dev *cdev)
85{
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070086 return 0;
87}
88
89static struct usb_composite_driver usbg_driver = {
90 .name = "g_target",
91 .dev = &usbg_device_desc,
92 .strings = usbg_strings,
93 .max_speed = USB_SPEED_SUPER,
94 .unbind = guas_unbind,
95};
96
Pavankumar Kondetia51de952012-06-25 13:57:11 +053097static int usbg_attach_cb(bool connect)
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -070098{
Pavankumar Kondetia51de952012-06-25 13:57:11 +053099 int ret = 0;
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -0700100
Pavankumar Kondetia51de952012-06-25 13:57:11 +0530101 if (connect)
102 ret = usb_composite_probe(&usbg_driver, usb_target_bind);
103 else
104 usb_composite_unregister(&usbg_driver);
105
106 return ret;
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -0700107}
108
109static int __init usb_target_gadget_init(void)
110{
111 int ret;
112
Pavankumar Kondetia51de952012-06-25 13:57:11 +0530113 ret = f_tcm_init(&usbg_attach_cb);
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -0700114 return ret;
115}
116module_init(usb_target_gadget_init);
117
118static void __exit usb_target_gadget_exit(void)
119{
Pavankumar Kondetia51de952012-06-25 13:57:11 +0530120 f_tcm_exit();
Sebastian Andrzej Siewior464cafd2012-05-03 19:51:36 -0700121}
122module_exit(usb_target_gadget_exit);
123
124MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
125MODULE_DESCRIPTION("usb-gadget fabric");
126MODULE_LICENSE("GPL v2");