diff options
-rw-r--r-- | drivers/usb/gadget/serial.c | 1073 | ||||
-rw-r--r-- | drivers/usb/gadget/u_serial.h | 5 |
2 files changed, 145 insertions, 933 deletions
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 64ce7e00e98a..b3699afff002 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) | 4 | * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) |
5 | * Copyright (C) 2008 by David Brownell | 5 | * Copyright (C) 2008 by David Brownell |
6 | * Copyright (C) 2008 by Nokia Corporation | ||
6 | * | 7 | * |
7 | * This software is distributed under the terms of the GNU General | 8 | * This software is distributed under the terms of the GNU General |
8 | * Public License ("GPL") as published by the Free Software Foundation, | 9 | * Public License ("GPL") as published by the Free Software Foundation, |
@@ -21,314 +22,79 @@ | |||
21 | 22 | ||
22 | /* Defines */ | 23 | /* Defines */ |
23 | 24 | ||
24 | #define GS_VERSION_STR "v2.3" | 25 | #define GS_VERSION_STR "v2.4" |
25 | #define GS_VERSION_NUM 0x2300 | 26 | #define GS_VERSION_NUM 0x2400 |
26 | 27 | ||
27 | #define GS_LONG_NAME "Gadget Serial" | 28 | #define GS_LONG_NAME "Gadget Serial" |
28 | #define GS_SHORT_NAME "g_serial" | ||
29 | |||
30 | #define GS_VERSION_NAME GS_LONG_NAME " " GS_VERSION_STR | 29 | #define GS_VERSION_NAME GS_LONG_NAME " " GS_VERSION_STR |
31 | 30 | ||
32 | 31 | /*-------------------------------------------------------------------------*/ | |
33 | /* REVISIT only one port is supported for now; | ||
34 | * see gs_{send,recv}_packet() ... no multiplexing, | ||
35 | * and no support for multiple ACM devices. | ||
36 | */ | ||
37 | #define GS_NUM_PORTS 1 | ||
38 | |||
39 | #define GS_NUM_CONFIGS 1 | ||
40 | #define GS_NO_CONFIG_ID 0 | ||
41 | #define GS_BULK_CONFIG_ID 1 | ||
42 | #define GS_ACM_CONFIG_ID 2 | ||
43 | |||
44 | #define GS_MAX_NUM_INTERFACES 2 | ||
45 | #define GS_BULK_INTERFACE_ID 0 | ||
46 | #define GS_CONTROL_INTERFACE_ID 0 | ||
47 | #define GS_DATA_INTERFACE_ID 1 | ||
48 | |||
49 | #define GS_MAX_DESC_LEN 256 | ||
50 | |||
51 | #define GS_DEFAULT_USE_ACM 0 | ||
52 | |||
53 | |||
54 | /* maxpacket and other transfer characteristics vary by speed. */ | ||
55 | static inline struct usb_endpoint_descriptor * | ||
56 | choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, | ||
57 | struct usb_endpoint_descriptor *fs) | ||
58 | { | ||
59 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
60 | return hs; | ||
61 | return fs; | ||
62 | } | ||
63 | |||
64 | 32 | ||
65 | /* Thanks to NetChip Technologies for donating this product ID. | 33 | /* Thanks to NetChip Technologies for donating this product ID. |
66 | * | 34 | * |
67 | * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! | 35 | * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! |
68 | * Instead: allocate your own, using normal USB-IF procedures. | 36 | * Instead: allocate your own, using normal USB-IF procedures. |
69 | */ | 37 | */ |
70 | #define GS_VENDOR_ID 0x0525 /* NetChip */ | 38 | #define GS_VENDOR_ID 0x0525 /* NetChip */ |
71 | #define GS_PRODUCT_ID 0xa4a6 /* Linux-USB Serial Gadget */ | 39 | #define GS_PRODUCT_ID 0xa4a6 /* Linux-USB Serial Gadget */ |
72 | #define GS_CDC_PRODUCT_ID 0xa4a7 /* ... as CDC-ACM */ | 40 | #define GS_CDC_PRODUCT_ID 0xa4a7 /* ... as CDC-ACM */ |
73 | 41 | ||
74 | #define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */ | 42 | /* string IDs are assigned dynamically */ |
75 | #define GS_NOTIFY_MAXPACKET 8 | ||
76 | 43 | ||
77 | /* the device structure holds info for the USB device */ | 44 | #define STRING_MANUFACTURER_IDX 0 |
78 | struct gs_dev { | 45 | #define STRING_PRODUCT_IDX 1 |
79 | struct usb_gadget *dev_gadget; /* gadget device pointer */ | 46 | #define STRING_DESCRIPTION_IDX 2 |
80 | spinlock_t dev_lock; /* lock for set/reset config */ | ||
81 | int dev_config; /* configuration number */ | ||
82 | struct usb_request *dev_ctrl_req; /* control request */ | ||
83 | 47 | ||
84 | struct gserial gser; /* serial/tty port */ | ||
85 | }; | ||
86 | |||
87 | |||
88 | /* Functions */ | ||
89 | |||
90 | /* gadget driver internals */ | ||
91 | static int gs_set_config(struct gs_dev *dev, unsigned config); | ||
92 | static void gs_reset_config(struct gs_dev *dev); | ||
93 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, | ||
94 | u8 type, unsigned int index, int is_otg); | ||
95 | |||
96 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, | ||
97 | gfp_t kmalloc_flags); | ||
98 | static void gs_free_req(struct usb_ep *ep, struct usb_request *req); | ||
99 | |||
100 | /*-------------------------------------------------------------------------*/ | ||
101 | |||
102 | /* USB descriptors */ | ||
103 | |||
104 | #define GS_MANUFACTURER_STR_ID 1 | ||
105 | #define GS_PRODUCT_STR_ID 2 | ||
106 | #define GS_SERIAL_STR_ID 3 | ||
107 | #define GS_BULK_CONFIG_STR_ID 4 | ||
108 | #define GS_ACM_CONFIG_STR_ID 5 | ||
109 | #define GS_CONTROL_STR_ID 6 | ||
110 | #define GS_DATA_STR_ID 7 | ||
111 | |||
112 | /* static strings, in UTF-8 */ | ||
113 | static char manufacturer[50]; | 48 | static char manufacturer[50]; |
114 | static struct usb_string gs_strings[] = { | 49 | |
115 | { GS_MANUFACTURER_STR_ID, manufacturer }, | 50 | static struct usb_string strings_dev[] = { |
116 | { GS_PRODUCT_STR_ID, GS_VERSION_NAME }, | 51 | [STRING_MANUFACTURER_IDX].s = manufacturer, |
117 | { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" }, | 52 | [STRING_PRODUCT_IDX].s = GS_VERSION_NAME, |
118 | { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" }, | 53 | [STRING_DESCRIPTION_IDX].s = NULL /* updated; f(use_acm) */, |
119 | { GS_CONTROL_STR_ID, "Gadget Serial Control" }, | ||
120 | { GS_DATA_STR_ID, "Gadget Serial Data" }, | ||
121 | { } /* end of list */ | 54 | { } /* end of list */ |
122 | }; | 55 | }; |
123 | 56 | ||
124 | static struct usb_gadget_strings gs_string_table = { | 57 | static struct usb_gadget_strings stringtab_dev = { |
125 | .language = 0x0409, /* en-us */ | 58 | .language = 0x0409, /* en-us */ |
126 | .strings = gs_strings, | 59 | .strings = strings_dev, |
127 | }; | 60 | }; |
128 | 61 | ||
129 | static struct usb_device_descriptor gs_device_desc = { | 62 | static struct usb_gadget_strings *dev_strings[] = { |
63 | &stringtab_dev, | ||
64 | NULL, | ||
65 | }; | ||
66 | |||
67 | static struct usb_device_descriptor device_desc = { | ||
130 | .bLength = USB_DT_DEVICE_SIZE, | 68 | .bLength = USB_DT_DEVICE_SIZE, |
131 | .bDescriptorType = USB_DT_DEVICE, | 69 | .bDescriptorType = USB_DT_DEVICE, |
132 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 70 | .bcdUSB = __constant_cpu_to_le16(0x0200), |
71 | /* .bDeviceClass = f(use_acm) */ | ||
133 | .bDeviceSubClass = 0, | 72 | .bDeviceSubClass = 0, |
134 | .bDeviceProtocol = 0, | 73 | .bDeviceProtocol = 0, |
74 | /* .bMaxPacketSize0 = f(hardware) */ | ||
135 | .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID), | 75 | .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID), |
136 | .idProduct = __constant_cpu_to_le16(GS_PRODUCT_ID), | 76 | /* .idProduct = f(use_acm) */ |
137 | .iManufacturer = GS_MANUFACTURER_STR_ID, | 77 | /* .bcdDevice = f(hardware) */ |
138 | .iProduct = GS_PRODUCT_STR_ID, | 78 | /* .iManufacturer = DYNAMIC */ |
139 | .bNumConfigurations = GS_NUM_CONFIGS, | 79 | /* .iProduct = DYNAMIC */ |
80 | .bNumConfigurations = 1, | ||
140 | }; | 81 | }; |
141 | 82 | ||
142 | static struct usb_otg_descriptor gs_otg_descriptor = { | 83 | static struct usb_otg_descriptor otg_descriptor = { |
143 | .bLength = sizeof(gs_otg_descriptor), | 84 | .bLength = sizeof otg_descriptor, |
144 | .bDescriptorType = USB_DT_OTG, | 85 | .bDescriptorType = USB_DT_OTG, |
145 | .bmAttributes = USB_OTG_SRP, | ||
146 | }; | ||
147 | 86 | ||
148 | static struct usb_config_descriptor gs_bulk_config_desc = { | 87 | /* REVISIT SRP-only hardware is possible, although |
149 | .bLength = USB_DT_CONFIG_SIZE, | 88 | * it would not be called "OTG" ... |
150 | .bDescriptorType = USB_DT_CONFIG, | 89 | */ |
151 | /* .wTotalLength computed dynamically */ | 90 | .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, |
152 | .bNumInterfaces = 1, | ||
153 | .bConfigurationValue = GS_BULK_CONFIG_ID, | ||
154 | .iConfiguration = GS_BULK_CONFIG_STR_ID, | ||
155 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
156 | .bMaxPower = 1, | ||
157 | }; | ||
158 | |||
159 | static struct usb_config_descriptor gs_acm_config_desc = { | ||
160 | .bLength = USB_DT_CONFIG_SIZE, | ||
161 | .bDescriptorType = USB_DT_CONFIG, | ||
162 | /* .wTotalLength computed dynamically */ | ||
163 | .bNumInterfaces = 2, | ||
164 | .bConfigurationValue = GS_ACM_CONFIG_ID, | ||
165 | .iConfiguration = GS_ACM_CONFIG_STR_ID, | ||
166 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
167 | .bMaxPower = 1, | ||
168 | }; | ||
169 | |||
170 | static const struct usb_interface_descriptor gs_bulk_interface_desc = { | ||
171 | .bLength = USB_DT_INTERFACE_SIZE, | ||
172 | .bDescriptorType = USB_DT_INTERFACE, | ||
173 | .bInterfaceNumber = GS_BULK_INTERFACE_ID, | ||
174 | .bNumEndpoints = 2, | ||
175 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
176 | .bInterfaceSubClass = 0, | ||
177 | .bInterfaceProtocol = 0, | ||
178 | .iInterface = GS_DATA_STR_ID, | ||
179 | }; | ||
180 | |||
181 | static const struct usb_interface_descriptor gs_control_interface_desc = { | ||
182 | .bLength = USB_DT_INTERFACE_SIZE, | ||
183 | .bDescriptorType = USB_DT_INTERFACE, | ||
184 | .bInterfaceNumber = GS_CONTROL_INTERFACE_ID, | ||
185 | .bNumEndpoints = 1, | ||
186 | .bInterfaceClass = USB_CLASS_COMM, | ||
187 | .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, | ||
188 | .bInterfaceProtocol = USB_CDC_ACM_PROTO_AT_V25TER, | ||
189 | .iInterface = GS_CONTROL_STR_ID, | ||
190 | }; | ||
191 | |||
192 | static const struct usb_interface_descriptor gs_data_interface_desc = { | ||
193 | .bLength = USB_DT_INTERFACE_SIZE, | ||
194 | .bDescriptorType = USB_DT_INTERFACE, | ||
195 | .bInterfaceNumber = GS_DATA_INTERFACE_ID, | ||
196 | .bNumEndpoints = 2, | ||
197 | .bInterfaceClass = USB_CLASS_CDC_DATA, | ||
198 | .bInterfaceSubClass = 0, | ||
199 | .bInterfaceProtocol = 0, | ||
200 | .iInterface = GS_DATA_STR_ID, | ||
201 | }; | ||
202 | |||
203 | static const struct usb_cdc_header_desc gs_header_desc = { | ||
204 | .bLength = sizeof(gs_header_desc), | ||
205 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
206 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | ||
207 | .bcdCDC = __constant_cpu_to_le16(0x0110), | ||
208 | }; | ||
209 | |||
210 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { | ||
211 | .bLength = sizeof(gs_call_mgmt_descriptor), | ||
212 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
213 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, | ||
214 | .bmCapabilities = 0, | ||
215 | .bDataInterface = 1, /* index of data interface */ | ||
216 | }; | ||
217 | |||
218 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { | ||
219 | .bLength = sizeof(gs_acm_descriptor), | ||
220 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
221 | .bDescriptorSubType = USB_CDC_ACM_TYPE, | ||
222 | .bmCapabilities = (1 << 1), | ||
223 | }; | ||
224 | |||
225 | static const struct usb_cdc_union_desc gs_union_desc = { | ||
226 | .bLength = sizeof(gs_union_desc), | ||
227 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
228 | .bDescriptorSubType = USB_CDC_UNION_TYPE, | ||
229 | .bMasterInterface0 = 0, /* index of control interface */ | ||
230 | .bSlaveInterface0 = 1, /* index of data interface */ | ||
231 | }; | ||
232 | |||
233 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { | ||
234 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
235 | .bDescriptorType = USB_DT_ENDPOINT, | ||
236 | .bEndpointAddress = USB_DIR_IN, | ||
237 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
238 | .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | ||
239 | .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, | ||
240 | }; | ||
241 | |||
242 | static struct usb_endpoint_descriptor gs_fullspeed_in_desc = { | ||
243 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
244 | .bDescriptorType = USB_DT_ENDPOINT, | ||
245 | .bEndpointAddress = USB_DIR_IN, | ||
246 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
247 | }; | ||
248 | |||
249 | static struct usb_endpoint_descriptor gs_fullspeed_out_desc = { | ||
250 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
251 | .bDescriptorType = USB_DT_ENDPOINT, | ||
252 | .bEndpointAddress = USB_DIR_OUT, | ||
253 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
254 | }; | ||
255 | |||
256 | static const struct usb_descriptor_header *gs_bulk_fullspeed_function[] = { | ||
257 | (struct usb_descriptor_header *) &gs_otg_descriptor, | ||
258 | (struct usb_descriptor_header *) &gs_bulk_interface_desc, | ||
259 | (struct usb_descriptor_header *) &gs_fullspeed_in_desc, | ||
260 | (struct usb_descriptor_header *) &gs_fullspeed_out_desc, | ||
261 | NULL, | ||
262 | }; | ||
263 | |||
264 | static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = { | ||
265 | (struct usb_descriptor_header *) &gs_otg_descriptor, | ||
266 | (struct usb_descriptor_header *) &gs_control_interface_desc, | ||
267 | (struct usb_descriptor_header *) &gs_header_desc, | ||
268 | (struct usb_descriptor_header *) &gs_call_mgmt_descriptor, | ||
269 | (struct usb_descriptor_header *) &gs_acm_descriptor, | ||
270 | (struct usb_descriptor_header *) &gs_union_desc, | ||
271 | (struct usb_descriptor_header *) &gs_fullspeed_notify_desc, | ||
272 | (struct usb_descriptor_header *) &gs_data_interface_desc, | ||
273 | (struct usb_descriptor_header *) &gs_fullspeed_in_desc, | ||
274 | (struct usb_descriptor_header *) &gs_fullspeed_out_desc, | ||
275 | NULL, | ||
276 | }; | ||
277 | |||
278 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { | ||
279 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
280 | .bDescriptorType = USB_DT_ENDPOINT, | ||
281 | .bEndpointAddress = USB_DIR_IN, | ||
282 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
283 | .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | ||
284 | .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, | ||
285 | }; | ||
286 | |||
287 | static struct usb_endpoint_descriptor gs_highspeed_in_desc = { | ||
288 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
289 | .bDescriptorType = USB_DT_ENDPOINT, | ||
290 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
291 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
292 | }; | ||
293 | |||
294 | static struct usb_endpoint_descriptor gs_highspeed_out_desc = { | ||
295 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
296 | .bDescriptorType = USB_DT_ENDPOINT, | ||
297 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
298 | .wMaxPacketSize = __constant_cpu_to_le16(512), | ||
299 | }; | ||
300 | |||
301 | static struct usb_qualifier_descriptor gs_qualifier_desc = { | ||
302 | .bLength = sizeof(struct usb_qualifier_descriptor), | ||
303 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
304 | .bcdUSB = __constant_cpu_to_le16 (0x0200), | ||
305 | /* assumes ep0 uses the same value for both speeds ... */ | ||
306 | .bNumConfigurations = GS_NUM_CONFIGS, | ||
307 | }; | ||
308 | |||
309 | static const struct usb_descriptor_header *gs_bulk_highspeed_function[] = { | ||
310 | (struct usb_descriptor_header *) &gs_otg_descriptor, | ||
311 | (struct usb_descriptor_header *) &gs_bulk_interface_desc, | ||
312 | (struct usb_descriptor_header *) &gs_highspeed_in_desc, | ||
313 | (struct usb_descriptor_header *) &gs_highspeed_out_desc, | ||
314 | NULL, | ||
315 | }; | 91 | }; |
316 | 92 | ||
317 | static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { | 93 | static const struct usb_descriptor_header *otg_desc[] = { |
318 | (struct usb_descriptor_header *) &gs_otg_descriptor, | 94 | (struct usb_descriptor_header *) &otg_descriptor, |
319 | (struct usb_descriptor_header *) &gs_control_interface_desc, | ||
320 | (struct usb_descriptor_header *) &gs_header_desc, | ||
321 | (struct usb_descriptor_header *) &gs_call_mgmt_descriptor, | ||
322 | (struct usb_descriptor_header *) &gs_acm_descriptor, | ||
323 | (struct usb_descriptor_header *) &gs_union_desc, | ||
324 | (struct usb_descriptor_header *) &gs_highspeed_notify_desc, | ||
325 | (struct usb_descriptor_header *) &gs_data_interface_desc, | ||
326 | (struct usb_descriptor_header *) &gs_highspeed_in_desc, | ||
327 | (struct usb_descriptor_header *) &gs_highspeed_out_desc, | ||
328 | NULL, | 95 | NULL, |
329 | }; | 96 | }; |
330 | 97 | ||
331 | |||
332 | /*-------------------------------------------------------------------------*/ | 98 | /*-------------------------------------------------------------------------*/ |
333 | 99 | ||
334 | /* Module */ | 100 | /* Module */ |
@@ -337,699 +103,150 @@ MODULE_AUTHOR("Al Borchers"); | |||
337 | MODULE_AUTHOR("David Brownell"); | 103 | MODULE_AUTHOR("David Brownell"); |
338 | MODULE_LICENSE("GPL"); | 104 | MODULE_LICENSE("GPL"); |
339 | 105 | ||
340 | static unsigned int use_acm = GS_DEFAULT_USE_ACM; | 106 | static int use_acm = true; |
341 | module_param(use_acm, uint, S_IRUGO); | 107 | module_param(use_acm, bool, 0); |
342 | MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no"); | 108 | MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes"); |
343 | 109 | ||
344 | /*-------------------------------------------------------------------------*/ | 110 | static unsigned n_ports = 1; |
111 | module_param(n_ports, uint, 0); | ||
112 | MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); | ||
345 | 113 | ||
346 | /* Gadget Driver */ | 114 | /*-------------------------------------------------------------------------*/ |
347 | 115 | ||
348 | /* | 116 | static int __init serial_bind_config(struct usb_configuration *c) |
349 | * gs_unbind | ||
350 | * | ||
351 | * Called on module unload. Frees the control request and device | ||
352 | * structure. | ||
353 | */ | ||
354 | static void __exit gs_unbind(struct usb_gadget *gadget) | ||
355 | { | 117 | { |
356 | struct gs_dev *dev = get_gadget_data(gadget); | 118 | unsigned i; |
119 | int status = 0; | ||
357 | 120 | ||
358 | /* read/write requests already freed, only control request remains */ | 121 | for (i = 0; i < n_ports && status == 0; i++) { |
359 | if (dev != NULL) { | 122 | if (use_acm) |
360 | if (dev->dev_ctrl_req != NULL) { | 123 | status = acm_bind_config(c, i); |
361 | gs_free_req(gadget->ep0, dev->dev_ctrl_req); | 124 | else |
362 | dev->dev_ctrl_req = NULL; | 125 | status = gser_bind_config(c, i); |
363 | } | ||
364 | gs_reset_config(dev); | ||
365 | kfree(dev); | ||
366 | set_gadget_data(gadget, NULL); | ||
367 | } | 126 | } |
368 | 127 | return status; | |
369 | pr_info("gs_unbind: %s unbound\n", GS_VERSION_NAME); | ||
370 | |||
371 | gserial_cleanup(); | ||
372 | } | 128 | } |
373 | 129 | ||
374 | /* | 130 | static struct usb_configuration serial_config_driver = { |
375 | * gs_bind | 131 | /* .label = f(use_acm) */ |
376 | * | 132 | .bind = serial_bind_config, |
377 | * Called on module load. Allocates and initializes the device | 133 | /* .bConfigurationValue = f(use_acm) */ |
378 | * structure and a control request. | 134 | /* .iConfiguration = DYNAMIC */ |
379 | */ | 135 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, |
380 | static int __init gs_bind(struct usb_gadget *gadget) | 136 | .bMaxPower = 1, /* 2 mA, minimal */ |
137 | }; | ||
138 | |||
139 | static int __init gs_bind(struct usb_composite_dev *cdev) | ||
381 | { | 140 | { |
382 | int ret; | 141 | int gcnum; |
383 | struct usb_ep *ep; | 142 | struct usb_gadget *gadget = cdev->gadget; |
384 | struct gs_dev *dev; | 143 | int status; |
385 | int gcnum; | ||
386 | 144 | ||
387 | ret = gserial_setup(gadget, GS_NUM_PORTS); | 145 | status = gserial_setup(cdev->gadget, n_ports); |
388 | if (ret < 0) | 146 | if (status < 0) |
389 | return ret; | 147 | return status; |
390 | 148 | ||
391 | /* Some controllers can't support CDC ACM: | 149 | /* Allocate string descriptor numbers ... note that string |
392 | * - sh doesn't support multiple interfaces or configs; | 150 | * contents can be overridden by the composite_dev glue. |
393 | * - sa1100 doesn't have a third interrupt endpoint | ||
394 | */ | 151 | */ |
395 | if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget)) | ||
396 | use_acm = 0; | ||
397 | |||
398 | gcnum = usb_gadget_controller_number(gadget); | ||
399 | if (gcnum >= 0) | ||
400 | gs_device_desc.bcdDevice = | ||
401 | cpu_to_le16(GS_VERSION_NUM | gcnum); | ||
402 | else { | ||
403 | pr_warning("gs_bind: controller '%s' not recognized\n", | ||
404 | gadget->name); | ||
405 | /* unrecognized, but safe unless bulk is REALLY quirky */ | ||
406 | gs_device_desc.bcdDevice = | ||
407 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); | ||
408 | } | ||
409 | |||
410 | dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); | ||
411 | if (dev == NULL) { | ||
412 | ret = -ENOMEM; | ||
413 | goto autoconf_fail; | ||
414 | } | ||
415 | |||
416 | usb_ep_autoconfig_reset(gadget); | ||
417 | ret = -ENXIO; | ||
418 | |||
419 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); | ||
420 | if (!ep) | ||
421 | goto autoconf_fail; | ||
422 | dev->gser.in = ep; | ||
423 | ep->driver_data = dev; /* claim the endpoint */ | ||
424 | |||
425 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); | ||
426 | if (!ep) | ||
427 | goto autoconf_fail; | ||
428 | dev->gser.out = ep; | ||
429 | ep->driver_data = dev; /* claim the endpoint */ | ||
430 | |||
431 | if (use_acm) { | ||
432 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); | ||
433 | if (!ep) { | ||
434 | pr_err("gs_bind: cannot run ACM on %s\n", gadget->name); | ||
435 | goto autoconf_fail; | ||
436 | } | ||
437 | gs_device_desc.idProduct = __constant_cpu_to_le16( | ||
438 | GS_CDC_PRODUCT_ID), | ||
439 | dev->gser.notify = ep; | ||
440 | ep->driver_data = dev; /* claim the endpoint */ | ||
441 | } | ||
442 | |||
443 | gs_device_desc.bDeviceClass = use_acm | ||
444 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | ||
445 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
446 | |||
447 | if (gadget_is_dualspeed(gadget)) { | ||
448 | gs_qualifier_desc.bDeviceClass = use_acm | ||
449 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | ||
450 | /* assume ep0 uses the same packet size for both speeds */ | ||
451 | gs_qualifier_desc.bMaxPacketSize0 = | ||
452 | gs_device_desc.bMaxPacketSize0; | ||
453 | /* assume endpoints are dual-speed */ | ||
454 | gs_highspeed_notify_desc.bEndpointAddress = | ||
455 | gs_fullspeed_notify_desc.bEndpointAddress; | ||
456 | gs_highspeed_in_desc.bEndpointAddress = | ||
457 | gs_fullspeed_in_desc.bEndpointAddress; | ||
458 | gs_highspeed_out_desc.bEndpointAddress = | ||
459 | gs_fullspeed_out_desc.bEndpointAddress; | ||
460 | } | ||
461 | |||
462 | usb_gadget_set_selfpowered(gadget); | ||
463 | |||
464 | if (gadget_is_otg(gadget)) { | ||
465 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, | ||
466 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
467 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
468 | } | ||
469 | 152 | ||
470 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | 153 | /* device description: manufacturer, product */ |
154 | snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", | ||
471 | init_utsname()->sysname, init_utsname()->release, | 155 | init_utsname()->sysname, init_utsname()->release, |
472 | gadget->name); | 156 | gadget->name); |
157 | status = usb_string_id(cdev); | ||
158 | if (status < 0) | ||
159 | goto fail; | ||
160 | strings_dev[STRING_MANUFACTURER_IDX].id = status; | ||
473 | 161 | ||
474 | dev->dev_gadget = gadget; | 162 | device_desc.iManufacturer = status; |
475 | spin_lock_init(&dev->dev_lock); | ||
476 | set_gadget_data(gadget, dev); | ||
477 | |||
478 | /* preallocate control response and buffer */ | ||
479 | dev->dev_ctrl_req = gs_alloc_req(gadget->ep0, GS_MAX_DESC_LEN, | ||
480 | GFP_KERNEL); | ||
481 | if (dev->dev_ctrl_req == NULL) { | ||
482 | ret = -ENOMEM; | ||
483 | goto autoconf_fail; | ||
484 | } | ||
485 | gadget->ep0->driver_data = dev; | ||
486 | |||
487 | pr_info("gs_bind: %s bound\n", GS_VERSION_NAME); | ||
488 | |||
489 | return 0; | ||
490 | |||
491 | autoconf_fail: | ||
492 | kfree(dev); | ||
493 | gserial_cleanup(); | ||
494 | pr_err("gs_bind: to %s, err %d\n", gadget->name, ret); | ||
495 | return ret; | ||
496 | } | ||
497 | |||
498 | static int gs_setup_standard(struct usb_gadget *gadget, | ||
499 | const struct usb_ctrlrequest *ctrl) | ||
500 | { | ||
501 | int ret = -EOPNOTSUPP; | ||
502 | struct gs_dev *dev = get_gadget_data(gadget); | ||
503 | struct usb_request *req = dev->dev_ctrl_req; | ||
504 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | ||
505 | u16 wValue = le16_to_cpu(ctrl->wValue); | ||
506 | u16 wLength = le16_to_cpu(ctrl->wLength); | ||
507 | |||
508 | switch (ctrl->bRequest) { | ||
509 | case USB_REQ_GET_DESCRIPTOR: | ||
510 | if (ctrl->bRequestType != USB_DIR_IN) | ||
511 | break; | ||
512 | |||
513 | switch (wValue >> 8) { | ||
514 | case USB_DT_DEVICE: | ||
515 | ret = min(wLength, | ||
516 | (u16)sizeof(struct usb_device_descriptor)); | ||
517 | memcpy(req->buf, &gs_device_desc, ret); | ||
518 | break; | ||
519 | |||
520 | case USB_DT_DEVICE_QUALIFIER: | ||
521 | if (!gadget_is_dualspeed(gadget)) | ||
522 | break; | ||
523 | ret = min(wLength, | ||
524 | (u16)sizeof(struct usb_qualifier_descriptor)); | ||
525 | memcpy(req->buf, &gs_qualifier_desc, ret); | ||
526 | break; | ||
527 | |||
528 | case USB_DT_OTHER_SPEED_CONFIG: | ||
529 | if (!gadget_is_dualspeed(gadget)) | ||
530 | break; | ||
531 | /* fall through */ | ||
532 | case USB_DT_CONFIG: | ||
533 | ret = gs_build_config_buf(req->buf, gadget, | ||
534 | wValue >> 8, wValue & 0xff, | ||
535 | gadget_is_otg(gadget)); | ||
536 | if (ret >= 0) | ||
537 | ret = min(wLength, (u16)ret); | ||
538 | break; | ||
539 | |||
540 | case USB_DT_STRING: | ||
541 | /* wIndex == language code. */ | ||
542 | ret = usb_gadget_get_string(&gs_string_table, | ||
543 | wValue & 0xff, req->buf); | ||
544 | if (ret >= 0) | ||
545 | ret = min(wLength, (u16)ret); | ||
546 | break; | ||
547 | } | ||
548 | break; | ||
549 | 163 | ||
550 | case USB_REQ_SET_CONFIGURATION: | 164 | status = usb_string_id(cdev); |
551 | if (ctrl->bRequestType != 0) | 165 | if (status < 0) |
552 | break; | 166 | goto fail; |
553 | spin_lock(&dev->dev_lock); | 167 | strings_dev[STRING_PRODUCT_IDX].id = status; |
554 | ret = gs_set_config(dev, wValue); | ||
555 | spin_unlock(&dev->dev_lock); | ||
556 | break; | ||
557 | 168 | ||
558 | case USB_REQ_GET_CONFIGURATION: | 169 | device_desc.iProduct = status; |
559 | if (ctrl->bRequestType != USB_DIR_IN) | ||
560 | break; | ||
561 | *(u8 *)req->buf = dev->dev_config; | ||
562 | ret = min(wLength, (u16)1); | ||
563 | break; | ||
564 | 170 | ||
565 | case USB_REQ_SET_INTERFACE: | 171 | /* config description */ |
566 | if (ctrl->bRequestType != USB_RECIP_INTERFACE | 172 | status = usb_string_id(cdev); |
567 | || !dev->dev_config | 173 | if (status < 0) |
568 | || wIndex >= GS_MAX_NUM_INTERFACES) | 174 | goto fail; |
569 | break; | 175 | strings_dev[STRING_DESCRIPTION_IDX].id = status; |
570 | if (dev->dev_config == GS_BULK_CONFIG_ID | ||
571 | && wIndex != GS_BULK_INTERFACE_ID) | ||
572 | break; | ||
573 | /* no alternate interface settings */ | ||
574 | if (wValue != 0) | ||
575 | break; | ||
576 | spin_lock(&dev->dev_lock); | ||
577 | /* PXA hardware partially handles SET_INTERFACE; | ||
578 | * we need to kluge around that interference. */ | ||
579 | if (gadget_is_pxa(gadget)) { | ||
580 | ret = gs_set_config(dev, use_acm ? | ||
581 | GS_ACM_CONFIG_ID : GS_BULK_CONFIG_ID); | ||
582 | goto set_interface_done; | ||
583 | } | ||
584 | if (dev->dev_config != GS_BULK_CONFIG_ID | ||
585 | && wIndex == GS_CONTROL_INTERFACE_ID) { | ||
586 | if (dev->gser.notify) { | ||
587 | usb_ep_disable(dev->gser.notify); | ||
588 | usb_ep_enable(dev->gser.notify, | ||
589 | dev->gser.notify_desc); | ||
590 | } | ||
591 | } else { | ||
592 | gserial_connect(&dev->gser, 0); | ||
593 | gserial_disconnect(&dev->gser); | ||
594 | } | ||
595 | ret = 0; | ||
596 | set_interface_done: | ||
597 | spin_unlock(&dev->dev_lock); | ||
598 | break; | ||
599 | 176 | ||
600 | case USB_REQ_GET_INTERFACE: | 177 | serial_config_driver.iConfiguration = status; |
601 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE) | ||
602 | || dev->dev_config == GS_NO_CONFIG_ID) | ||
603 | break; | ||
604 | if (wIndex >= GS_MAX_NUM_INTERFACES | ||
605 | || (dev->dev_config == GS_BULK_CONFIG_ID | ||
606 | && wIndex != GS_BULK_INTERFACE_ID)) { | ||
607 | ret = -EDOM; | ||
608 | break; | ||
609 | } | ||
610 | /* no alternate interface settings */ | ||
611 | *(u8 *)req->buf = 0; | ||
612 | ret = min(wLength, (u16)1); | ||
613 | break; | ||
614 | 178 | ||
615 | default: | 179 | /* set up other descriptors */ |
616 | pr_err("gs_setup: unknown standard request, type=%02x, " | 180 | gcnum = usb_gadget_controller_number(gadget); |
617 | "request=%02x, value=%04x, index=%04x, length=%d\n", | 181 | if (gcnum >= 0) |
618 | ctrl->bRequestType, ctrl->bRequest, | 182 | device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum); |
619 | wValue, wIndex, wLength); | 183 | else { |
620 | break; | 184 | /* this is so simple (for now, no altsettings) that it |
621 | } | 185 | * SHOULD NOT have problems with bulk-capable hardware. |
622 | 186 | * so warn about unrcognized controllers -- don't panic. | |
623 | return ret; | 187 | * |
624 | } | 188 | * things like configuration and altsetting numbering |
625 | 189 | * can need hardware-specific attention though. | |
626 | static void gs_setup_complete_set_line_coding(struct usb_ep *ep, | ||
627 | struct usb_request *req) | ||
628 | { | ||
629 | struct gs_dev *dev = ep->driver_data; | ||
630 | |||
631 | switch (req->status) { | ||
632 | case 0: | ||
633 | /* normal completion */ | ||
634 | if (req->actual != sizeof(dev->gser.port_line_coding)) | ||
635 | usb_ep_set_halt(ep); | ||
636 | else { | ||
637 | struct usb_cdc_line_coding *value = req->buf; | ||
638 | |||
639 | /* REVISIT: we currently just remember this data. | ||
640 | * If we change that, (a) validate it first, then | ||
641 | * (b) update whatever hardware needs updating. | ||
642 | */ | ||
643 | spin_lock(&dev->dev_lock); | ||
644 | dev->gser.port_line_coding = *value; | ||
645 | spin_unlock(&dev->dev_lock); | ||
646 | } | ||
647 | break; | ||
648 | |||
649 | case -ESHUTDOWN: | ||
650 | /* disconnect */ | ||
651 | gs_free_req(ep, req); | ||
652 | break; | ||
653 | |||
654 | default: | ||
655 | /* unexpected */ | ||
656 | break; | ||
657 | } | ||
658 | return; | ||
659 | } | ||
660 | |||
661 | static int gs_setup_class(struct usb_gadget *gadget, | ||
662 | const struct usb_ctrlrequest *ctrl) | ||
663 | { | ||
664 | int ret = -EOPNOTSUPP; | ||
665 | struct gs_dev *dev = get_gadget_data(gadget); | ||
666 | struct usb_request *req = dev->dev_ctrl_req; | ||
667 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | ||
668 | u16 wValue = le16_to_cpu(ctrl->wValue); | ||
669 | u16 wLength = le16_to_cpu(ctrl->wLength); | ||
670 | |||
671 | switch (ctrl->bRequest) { | ||
672 | case USB_CDC_REQ_SET_LINE_CODING: | ||
673 | if (wLength != sizeof(struct usb_cdc_line_coding)) | ||
674 | break; | ||
675 | ret = wLength; | ||
676 | req->complete = gs_setup_complete_set_line_coding; | ||
677 | break; | ||
678 | |||
679 | case USB_CDC_REQ_GET_LINE_CODING: | ||
680 | ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding)); | ||
681 | spin_lock(&dev->dev_lock); | ||
682 | memcpy(req->buf, &dev->gser.port_line_coding, ret); | ||
683 | spin_unlock(&dev->dev_lock); | ||
684 | break; | ||
685 | |||
686 | case USB_CDC_REQ_SET_CONTROL_LINE_STATE: | ||
687 | if (wLength != 0) | ||
688 | break; | ||
689 | ret = 0; | ||
690 | /* REVISIT: we currently just remember this data. | ||
691 | * If we change that, update whatever hardware needs | ||
692 | * updating. | ||
693 | */ | ||
694 | spin_lock(&dev->dev_lock); | ||
695 | dev->gser.port_handshake_bits = wValue; | ||
696 | spin_unlock(&dev->dev_lock); | ||
697 | break; | ||
698 | |||
699 | default: | ||
700 | /* NOTE: strictly speaking, we should accept AT-commands | ||
701 | * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE. | ||
702 | * But our call management descriptor says we don't handle | ||
703 | * call management, so we should be able to get by without | ||
704 | * handling those "required" commands (except by stalling). | ||
705 | */ | 190 | */ |
706 | pr_err("gs_setup: unknown class request, " | 191 | pr_warning("gs_bind: controller '%s' not recognized\n", |
707 | "type=%02x, request=%02x, value=%04x, " | 192 | gadget->name); |
708 | "index=%04x, length=%d\n", | 193 | device_desc.bcdDevice = |
709 | ctrl->bRequestType, ctrl->bRequest, | 194 | __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099); |
710 | wValue, wIndex, wLength); | ||
711 | break; | ||
712 | } | ||
713 | |||
714 | return ret; | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | * gs_setup_complete | ||
719 | */ | ||
720 | static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) | ||
721 | { | ||
722 | if (req->status || req->actual != req->length) { | ||
723 | pr_err("gs_setup_complete: status error, status=%d, " | ||
724 | "actual=%d, length=%d\n", | ||
725 | req->status, req->actual, req->length); | ||
726 | } | ||
727 | } | ||
728 | |||
729 | /* | ||
730 | * gs_setup | ||
731 | * | ||
732 | * Implements all the control endpoint functionality that's not | ||
733 | * handled in hardware or the hardware driver. | ||
734 | * | ||
735 | * Returns the size of the data sent to the host, or a negative | ||
736 | * error number. | ||
737 | */ | ||
738 | static int gs_setup(struct usb_gadget *gadget, | ||
739 | const struct usb_ctrlrequest *ctrl) | ||
740 | { | ||
741 | int ret = -EOPNOTSUPP; | ||
742 | struct gs_dev *dev = get_gadget_data(gadget); | ||
743 | struct usb_request *req = dev->dev_ctrl_req; | ||
744 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | ||
745 | u16 wValue = le16_to_cpu(ctrl->wValue); | ||
746 | u16 wLength = le16_to_cpu(ctrl->wLength); | ||
747 | |||
748 | req->complete = gs_setup_complete; | ||
749 | |||
750 | switch (ctrl->bRequestType & USB_TYPE_MASK) { | ||
751 | case USB_TYPE_STANDARD: | ||
752 | ret = gs_setup_standard(gadget, ctrl); | ||
753 | break; | ||
754 | |||
755 | case USB_TYPE_CLASS: | ||
756 | ret = gs_setup_class(gadget, ctrl); | ||
757 | break; | ||
758 | |||
759 | default: | ||
760 | pr_err("gs_setup: unknown request, type=%02x, request=%02x, " | ||
761 | "value=%04x, index=%04x, length=%d\n", | ||
762 | ctrl->bRequestType, ctrl->bRequest, | ||
763 | wValue, wIndex, wLength); | ||
764 | break; | ||
765 | } | 195 | } |
766 | 196 | ||
767 | /* respond with data transfer before status phase? */ | 197 | if (gadget_is_otg(cdev->gadget)) { |
768 | if (ret >= 0) { | 198 | serial_config_driver.descriptors = otg_desc; |
769 | req->length = ret; | 199 | serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
770 | req->zero = ret < wLength | ||
771 | && (ret % gadget->ep0->maxpacket) == 0; | ||
772 | ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | ||
773 | if (ret < 0) { | ||
774 | pr_err("gs_setup: cannot queue response, ret=%d\n", | ||
775 | ret); | ||
776 | req->status = 0; | ||
777 | gs_setup_complete(gadget->ep0, req); | ||
778 | } | ||
779 | } | 200 | } |
780 | 201 | ||
781 | /* device either stalls (ret < 0) or reports success */ | 202 | /* register our configuration */ |
782 | return ret; | 203 | status = usb_add_config(cdev, &serial_config_driver); |
783 | } | 204 | if (status < 0) |
205 | goto fail; | ||
784 | 206 | ||
785 | /* | 207 | INFO(cdev, "%s\n", GS_VERSION_NAME); |
786 | * gs_disconnect | ||
787 | * | ||
788 | * Called when the device is disconnected. Frees the closed | ||
789 | * ports and disconnects open ports. Open ports will be freed | ||
790 | * on close. Then reallocates the ports for the next connection. | ||
791 | */ | ||
792 | static void gs_disconnect(struct usb_gadget *gadget) | ||
793 | { | ||
794 | unsigned long flags; | ||
795 | struct gs_dev *dev = get_gadget_data(gadget); | ||
796 | 208 | ||
797 | spin_lock_irqsave(&dev->dev_lock, flags); | 209 | return 0; |
798 | gs_reset_config(dev); | ||
799 | spin_unlock_irqrestore(&dev->dev_lock, flags); | ||
800 | 210 | ||
801 | pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME); | 211 | fail: |
212 | gserial_cleanup(); | ||
213 | return status; | ||
802 | } | 214 | } |
803 | 215 | ||
804 | static struct usb_gadget_driver gs_gadget_driver = { | 216 | static struct usb_composite_driver gserial_driver = { |
805 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 217 | .name = "g_serial", |
806 | .speed = USB_SPEED_HIGH, | 218 | .dev = &device_desc, |
807 | #else | 219 | .strings = dev_strings, |
808 | .speed = USB_SPEED_FULL, | 220 | .bind = gs_bind, |
809 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
810 | .function = GS_LONG_NAME, | ||
811 | .bind = gs_bind, | ||
812 | .unbind = gs_unbind, | ||
813 | .setup = gs_setup, | ||
814 | .disconnect = gs_disconnect, | ||
815 | .driver = { | ||
816 | .name = GS_SHORT_NAME, | ||
817 | .owner = THIS_MODULE, | ||
818 | }, | ||
819 | }; | 221 | }; |
820 | 222 | ||
821 | /* | 223 | static int __init init(void) |
822 | * gs_set_config | ||
823 | * | ||
824 | * Configures the device by enabling device specific | ||
825 | * optimizations, setting up the endpoints, allocating | ||
826 | * read and write requests and queuing read requests. | ||
827 | * | ||
828 | * The device lock must be held when calling this function. | ||
829 | */ | ||
830 | static int gs_set_config(struct gs_dev *dev, unsigned config) | ||
831 | { | 224 | { |
832 | int ret = 0; | 225 | /* We *could* export two configs; that'd be much cleaner... |
833 | struct usb_gadget *gadget = dev->dev_gadget; | 226 | * but neither of these product IDs was defined that way. |
834 | |||
835 | if (config == dev->dev_config) | ||
836 | return 0; | ||
837 | |||
838 | gs_reset_config(dev); | ||
839 | |||
840 | switch (config) { | ||
841 | case GS_NO_CONFIG_ID: | ||
842 | return 0; | ||
843 | case GS_BULK_CONFIG_ID: | ||
844 | if (use_acm) | ||
845 | return -EINVAL; | ||
846 | break; | ||
847 | case GS_ACM_CONFIG_ID: | ||
848 | if (!use_acm) | ||
849 | return -EINVAL; | ||
850 | break; | ||
851 | default: | ||
852 | return -EINVAL; | ||
853 | } | ||
854 | |||
855 | dev->gser.in_desc = choose_ep_desc(gadget, | ||
856 | &gs_highspeed_in_desc, | ||
857 | &gs_fullspeed_in_desc); | ||
858 | dev->gser.out_desc = choose_ep_desc(gadget, | ||
859 | &gs_highspeed_out_desc, | ||
860 | &gs_fullspeed_out_desc); | ||
861 | dev->gser.notify_desc = dev->gser.notify | ||
862 | ? choose_ep_desc(gadget, | ||
863 | &gs_highspeed_notify_desc, | ||
864 | &gs_fullspeed_notify_desc) | ||
865 | : NULL; | ||
866 | |||
867 | /* only support one "serial" port for now */ | ||
868 | if (dev->gser.notify) { | ||
869 | ret = usb_ep_enable(dev->gser.notify, dev->gser.notify_desc); | ||
870 | if (ret < 0) | ||
871 | return ret; | ||
872 | dev->gser.notify->driver_data = dev; | ||
873 | } | ||
874 | |||
875 | ret = gserial_connect(&dev->gser, 0); | ||
876 | if (ret < 0) { | ||
877 | if (dev->gser.notify) { | ||
878 | usb_ep_disable(dev->gser.notify); | ||
879 | dev->gser.notify->driver_data = NULL; | ||
880 | } | ||
881 | return ret; | ||
882 | } | ||
883 | |||
884 | dev->dev_config = config; | ||
885 | |||
886 | /* REVISIT the ACM mode should be able to actually *issue* some | ||
887 | * notifications, for at least serial state change events if | ||
888 | * not also for network connection; say so in bmCapabilities. | ||
889 | */ | 227 | */ |
890 | |||
891 | pr_info("gs_set_config: %s configured, %s speed %s config\n", | ||
892 | GS_LONG_NAME, | ||
893 | gadget->speed == USB_SPEED_HIGH ? "high" : "full", | ||
894 | config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM"); | ||
895 | |||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | /* | ||
900 | * gs_reset_config | ||
901 | * | ||
902 | * Mark the device as not configured, disable all endpoints, | ||
903 | * which forces completion of pending I/O and frees queued | ||
904 | * requests, and free the remaining write requests on the | ||
905 | * free list. | ||
906 | * | ||
907 | * The device lock must be held when calling this function. | ||
908 | */ | ||
909 | static void gs_reset_config(struct gs_dev *dev) | ||
910 | { | ||
911 | if (dev->dev_config == GS_NO_CONFIG_ID) | ||
912 | return; | ||
913 | |||
914 | dev->dev_config = GS_NO_CONFIG_ID; | ||
915 | |||
916 | gserial_disconnect(&dev->gser); | ||
917 | if (dev->gser.notify) { | ||
918 | usb_ep_disable(dev->gser.notify); | ||
919 | dev->gser.notify->driver_data = NULL; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | /* | ||
924 | * gs_build_config_buf | ||
925 | * | ||
926 | * Builds the config descriptors in the given buffer and returns the | ||
927 | * length, or a negative error number. | ||
928 | */ | ||
929 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, | ||
930 | u8 type, unsigned int index, int is_otg) | ||
931 | { | ||
932 | int len; | ||
933 | int high_speed = 0; | ||
934 | const struct usb_config_descriptor *config_desc; | ||
935 | const struct usb_descriptor_header **function; | ||
936 | |||
937 | if (index >= gs_device_desc.bNumConfigurations) | ||
938 | return -EINVAL; | ||
939 | |||
940 | /* other speed switches high and full speed */ | ||
941 | if (gadget_is_dualspeed(g)) { | ||
942 | high_speed = (g->speed == USB_SPEED_HIGH); | ||
943 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
944 | high_speed = !high_speed; | ||
945 | } | ||
946 | |||
947 | if (use_acm) { | 228 | if (use_acm) { |
948 | config_desc = &gs_acm_config_desc; | 229 | serial_config_driver.label = "CDC ACM config"; |
949 | function = high_speed | 230 | serial_config_driver.bConfigurationValue = 2; |
950 | ? gs_acm_highspeed_function | 231 | device_desc.bDeviceClass = USB_CLASS_COMM; |
951 | : gs_acm_fullspeed_function; | 232 | device_desc.idProduct = |
233 | __constant_cpu_to_le16(GS_CDC_PRODUCT_ID); | ||
952 | } else { | 234 | } else { |
953 | config_desc = &gs_bulk_config_desc; | 235 | serial_config_driver.label = "Generic Serial config"; |
954 | function = high_speed | 236 | serial_config_driver.bConfigurationValue = 1; |
955 | ? gs_bulk_highspeed_function | 237 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
956 | : gs_bulk_fullspeed_function; | 238 | device_desc.idProduct = |
957 | } | 239 | __constant_cpu_to_le16(GS_PRODUCT_ID); |
958 | |||
959 | /* for now, don't advertise srp-only devices */ | ||
960 | if (!is_otg) | ||
961 | function++; | ||
962 | |||
963 | len = usb_gadget_config_buf(config_desc, buf, GS_MAX_DESC_LEN, function); | ||
964 | if (len < 0) | ||
965 | return len; | ||
966 | |||
967 | ((struct usb_config_descriptor *)buf)->bDescriptorType = type; | ||
968 | |||
969 | return len; | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * gs_alloc_req | ||
974 | * | ||
975 | * Allocate a usb_request and its buffer. Returns a pointer to the | ||
976 | * usb_request or NULL if there is an error. | ||
977 | */ | ||
978 | static struct usb_request * | ||
979 | gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags) | ||
980 | { | ||
981 | struct usb_request *req; | ||
982 | |||
983 | if (ep == NULL) | ||
984 | return NULL; | ||
985 | |||
986 | req = usb_ep_alloc_request(ep, kmalloc_flags); | ||
987 | |||
988 | if (req != NULL) { | ||
989 | req->length = len; | ||
990 | req->buf = kmalloc(len, kmalloc_flags); | ||
991 | if (req->buf == NULL) { | ||
992 | usb_ep_free_request(ep, req); | ||
993 | return NULL; | ||
994 | } | ||
995 | } | ||
996 | |||
997 | return req; | ||
998 | } | ||
999 | |||
1000 | /* | ||
1001 | * gs_free_req | ||
1002 | * | ||
1003 | * Free a usb_request and its buffer. | ||
1004 | */ | ||
1005 | static void gs_free_req(struct usb_ep *ep, struct usb_request *req) | ||
1006 | { | ||
1007 | if (ep != NULL && req != NULL) { | ||
1008 | kfree(req->buf); | ||
1009 | usb_ep_free_request(ep, req); | ||
1010 | } | 240 | } |
1011 | } | 241 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; |
1012 | |||
1013 | /*-------------------------------------------------------------------------*/ | ||
1014 | 242 | ||
1015 | /* | 243 | return usb_composite_register(&gserial_driver); |
1016 | * gs_module_init | ||
1017 | * | ||
1018 | * Register as a USB gadget driver and a tty driver. | ||
1019 | */ | ||
1020 | static int __init gs_module_init(void) | ||
1021 | { | ||
1022 | return usb_gadget_register_driver(&gs_gadget_driver); | ||
1023 | } | 244 | } |
1024 | module_init(gs_module_init); | 245 | module_init(init); |
1025 | 246 | ||
1026 | /* | 247 | static void __exit cleanup(void) |
1027 | * gs_module_exit | ||
1028 | * | ||
1029 | * Unregister as a tty driver and a USB gadget driver. | ||
1030 | */ | ||
1031 | static void __exit gs_module_exit(void) | ||
1032 | { | 248 | { |
1033 | usb_gadget_unregister_driver(&gs_gadget_driver); | 249 | usb_composite_unregister(&gserial_driver); |
250 | gserial_cleanup(); | ||
1034 | } | 251 | } |
1035 | module_exit(gs_module_exit); | 252 | module_exit(cleanup); |
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h index f9ce3005d751..7b561138f90e 100644 --- a/drivers/usb/gadget/u_serial.h +++ b/drivers/usb/gadget/u_serial.h | |||
@@ -41,11 +41,6 @@ struct gserial { | |||
41 | 41 | ||
42 | /* REVISIT avoid this CDC-ACM support harder ... */ | 42 | /* REVISIT avoid this CDC-ACM support harder ... */ |
43 | struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */ | 43 | struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */ |
44 | |||
45 | /* FIXME remove these when we switch to acm_bind_config... */ | ||
46 | struct usb_ep *notify; | ||
47 | struct usb_endpoint_descriptor *notify_desc; | ||
48 | u16 port_handshake_bits; | ||
49 | }; | 44 | }; |
50 | 45 | ||
51 | /* port setup/teardown is handled by gadget driver */ | 46 | /* port setup/teardown is handled by gadget driver */ |