blob: 00da3f6620a3c360c02bdbd48e2e053b33c938aa [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * g_serial.c -- USB gadget serial driver
3 *
4 * Copyright 2003 (C) Al Borchers (alborchers@steinerpoint.com)
5 *
6 * This code is based in part on the Gadget Zero driver, which
7 * is Copyright (C) 2003 by David Brownell, all rights reserved.
8 *
9 * This code also borrows from usbserial.c, which is
10 * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
11 * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
12 * Copyright (C) 2000 Al Borchers (alborchers@steinerpoint.com)
13 *
14 * This software is distributed under the terms of the GNU General
15 * Public License ("GPL") as published by the Free Software Foundation,
16 * either version 2 of that License or (at your option) any later version.
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 */
18
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/utsname.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/device.h>
22#include <linux/tty.h>
23#include <linux/tty_flip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
David Brownell5f848132006-12-16 15:34:53 -080025#include <linux/usb/ch9.h>
David Brownella8c28f22006-06-13 09:57:47 -070026#include <linux/usb/cdc.h>
David Brownell9454a572007-10-04 18:05:17 -070027#include <linux/usb/gadget.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
29#include "gadget_chips.h"
30
31
Linus Torvalds1da177e2005-04-16 15:20:36 -070032/* Defines */
33
Franck Bui-Huuca094f12006-06-14 10:47:18 +020034#define GS_VERSION_STR "v2.2"
35#define GS_VERSION_NUM 0x0202
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
37#define GS_LONG_NAME "Gadget Serial"
38#define GS_SHORT_NAME "g_serial"
39
40#define GS_MAJOR 127
41#define GS_MINOR_START 0
42
David Brownell9079e912008-05-07 16:00:36 -070043/* REVISIT only one port is supported for now;
44 * see gs_{send,recv}_packet() ... no multiplexing,
45 * and no support for multiple ACM devices.
46 */
47#define GS_NUM_PORTS 1
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49#define GS_NUM_CONFIGS 1
50#define GS_NO_CONFIG_ID 0
51#define GS_BULK_CONFIG_ID 1
52#define GS_ACM_CONFIG_ID 2
53
54#define GS_MAX_NUM_INTERFACES 2
55#define GS_BULK_INTERFACE_ID 0
56#define GS_CONTROL_INTERFACE_ID 0
57#define GS_DATA_INTERFACE_ID 1
58
59#define GS_MAX_DESC_LEN 256
60
61#define GS_DEFAULT_READ_Q_SIZE 32
62#define GS_DEFAULT_WRITE_Q_SIZE 32
63
64#define GS_DEFAULT_WRITE_BUF_SIZE 8192
65#define GS_TMP_BUF_SIZE 8192
66
67#define GS_CLOSE_TIMEOUT 15
68
69#define GS_DEFAULT_USE_ACM 0
70
David Brownell9079e912008-05-07 16:00:36 -070071/* 9600-8-N-1 ... matches init_termios.c_cflag and defaults
72 * expected by "usbser.sys" on MS-Windows.
73 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#define GS_DEFAULT_DTE_RATE 9600
75#define GS_DEFAULT_DATA_BITS 8
76#define GS_DEFAULT_PARITY USB_CDC_NO_PARITY
77#define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS
78
David Brownell51a0e852007-08-02 00:02:47 -070079/* maxpacket and other transfer characteristics vary by speed. */
80static inline struct usb_endpoint_descriptor *
81choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
82 struct usb_endpoint_descriptor *fs)
83{
84 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
85 return hs;
86 return fs;
87}
88
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
90/* debug settings */
David Brownell51a0e852007-08-02 00:02:47 -070091#ifdef DEBUG
Linus Torvalds1da177e2005-04-16 15:20:36 -070092static int debug = 1;
David Brownell51a0e852007-08-02 00:02:47 -070093#else
94#define debug 0
95#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97#define gs_debug(format, arg...) \
David Brownell00274922007-11-19 12:58:36 -080098 do { if (debug) pr_debug(format, ## arg); } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099#define gs_debug_level(level, format, arg...) \
David Brownell00274922007-11-19 12:58:36 -0800100 do { if (debug >= level) pr_debug(format, ## arg); } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103/* Thanks to NetChip Technologies for donating this product ID.
104 *
105 * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
106 * Instead: allocate your own, using normal USB-IF procedures.
107 */
108#define GS_VENDOR_ID 0x0525 /* NetChip */
109#define GS_PRODUCT_ID 0xa4a6 /* Linux-USB Serial Gadget */
110#define GS_CDC_PRODUCT_ID 0xa4a7 /* ... as CDC-ACM */
111
112#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
113#define GS_NOTIFY_MAXPACKET 8
114
115
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116/* circular buffer */
117struct gs_buf {
118 unsigned int buf_size;
119 char *buf_buf;
120 char *buf_get;
121 char *buf_put;
122};
123
124/* list of requests */
125struct gs_req_entry {
126 struct list_head re_entry;
127 struct usb_request *re_req;
128};
129
130/* the port structure holds info for each port, one for each minor number */
131struct gs_port {
David Brownell51a0e852007-08-02 00:02:47 -0700132 struct gs_dev *port_dev; /* pointer to device struct */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 struct tty_struct *port_tty; /* pointer to tty struct */
134 spinlock_t port_lock;
David Brownell51a0e852007-08-02 00:02:47 -0700135 int port_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 int port_open_count;
137 int port_in_use; /* open/close in progress */
138 wait_queue_head_t port_write_wait;/* waiting to write */
139 struct gs_buf *port_write_buf;
David Brownellf371e752008-04-18 17:37:49 -0700140 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */
141 u16 port_handshake_bits;
142#define RS232_RTS (1 << 1)
143#define RS232_DTE (1 << 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144};
145
146/* the device structure holds info for the USB device */
147struct gs_dev {
148 struct usb_gadget *dev_gadget; /* gadget device pointer */
149 spinlock_t dev_lock; /* lock for set/reset config */
150 int dev_config; /* configuration number */
151 struct usb_ep *dev_notify_ep; /* address of notify endpoint */
152 struct usb_ep *dev_in_ep; /* address of in endpoint */
153 struct usb_ep *dev_out_ep; /* address of out endpoint */
Steven Cole093cf722005-05-03 19:07:24 -0600154 struct usb_endpoint_descriptor /* descriptor of notify ep */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 *dev_notify_ep_desc;
156 struct usb_endpoint_descriptor /* descriptor of in endpoint */
157 *dev_in_ep_desc;
158 struct usb_endpoint_descriptor /* descriptor of out endpoint */
159 *dev_out_ep_desc;
160 struct usb_request *dev_ctrl_req; /* control request */
161 struct list_head dev_req_list; /* list of write requests */
162 int dev_sched_port; /* round robin port scheduled */
163 struct gs_port *dev_port[GS_NUM_PORTS]; /* the ports */
164};
165
166
167/* Functions */
168
David Brownell9079e912008-05-07 16:00:36 -0700169/* tty driver internals */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170static int gs_send(struct gs_dev *dev);
171static int gs_send_packet(struct gs_dev *dev, char *packet,
172 unsigned int size);
173static int gs_recv_packet(struct gs_dev *dev, char *packet,
174 unsigned int size);
175static void gs_read_complete(struct usb_ep *ep, struct usb_request *req);
176static void gs_write_complete(struct usb_ep *ep, struct usb_request *req);
177
David Brownell9079e912008-05-07 16:00:36 -0700178/* gadget driver internals */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179static int gs_set_config(struct gs_dev *dev, unsigned config);
180static void gs_reset_config(struct gs_dev *dev);
David Brownell51a0e852007-08-02 00:02:47 -0700181static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 u8 type, unsigned int index, int is_otg);
183
184static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
Al Viro55016f12005-10-21 03:21:58 -0400185 gfp_t kmalloc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
187
188static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
Al Viro55016f12005-10-21 03:21:58 -0400189 gfp_t kmalloc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
191
Al Viro55016f12005-10-21 03:21:58 -0400192static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193static void gs_free_ports(struct gs_dev *dev);
194
195/* circular buffer */
Al Viro55016f12005-10-21 03:21:58 -0400196static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197static void gs_buf_free(struct gs_buf *gb);
198static void gs_buf_clear(struct gs_buf *gb);
199static unsigned int gs_buf_data_avail(struct gs_buf *gb);
200static unsigned int gs_buf_space_avail(struct gs_buf *gb);
201static unsigned int gs_buf_put(struct gs_buf *gb, const char *buf,
202 unsigned int count);
203static unsigned int gs_buf_get(struct gs_buf *gb, char *buf,
204 unsigned int count);
205
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206
207/* Globals */
208
209static struct gs_dev *gs_device;
210
211static const char *EP_IN_NAME;
212static const char *EP_OUT_NAME;
213static const char *EP_NOTIFY_NAME;
214
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200215static struct mutex gs_open_close_lock[GS_NUM_PORTS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
David Brownell9079e912008-05-07 16:00:36 -0700218/*-------------------------------------------------------------------------*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
220/* USB descriptors */
221
222#define GS_MANUFACTURER_STR_ID 1
223#define GS_PRODUCT_STR_ID 2
224#define GS_SERIAL_STR_ID 3
225#define GS_BULK_CONFIG_STR_ID 4
226#define GS_ACM_CONFIG_STR_ID 5
227#define GS_CONTROL_STR_ID 6
228#define GS_DATA_STR_ID 7
229
230/* static strings, in UTF-8 */
231static char manufacturer[50];
232static struct usb_string gs_strings[] = {
233 { GS_MANUFACTURER_STR_ID, manufacturer },
234 { GS_PRODUCT_STR_ID, GS_LONG_NAME },
235 { GS_SERIAL_STR_ID, "0" },
236 { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" },
237 { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" },
238 { GS_CONTROL_STR_ID, "Gadget Serial Control" },
239 { GS_DATA_STR_ID, "Gadget Serial Data" },
240 { } /* end of list */
241};
242
243static struct usb_gadget_strings gs_string_table = {
244 .language = 0x0409, /* en-us */
245 .strings = gs_strings,
246};
247
248static struct usb_device_descriptor gs_device_desc = {
249 .bLength = USB_DT_DEVICE_SIZE,
250 .bDescriptorType = USB_DT_DEVICE,
251 .bcdUSB = __constant_cpu_to_le16(0x0200),
252 .bDeviceSubClass = 0,
253 .bDeviceProtocol = 0,
254 .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID),
255 .idProduct = __constant_cpu_to_le16(GS_PRODUCT_ID),
256 .iManufacturer = GS_MANUFACTURER_STR_ID,
257 .iProduct = GS_PRODUCT_STR_ID,
258 .iSerialNumber = GS_SERIAL_STR_ID,
259 .bNumConfigurations = GS_NUM_CONFIGS,
260};
261
262static struct usb_otg_descriptor gs_otg_descriptor = {
263 .bLength = sizeof(gs_otg_descriptor),
264 .bDescriptorType = USB_DT_OTG,
265 .bmAttributes = USB_OTG_SRP,
266};
267
268static struct usb_config_descriptor gs_bulk_config_desc = {
269 .bLength = USB_DT_CONFIG_SIZE,
270 .bDescriptorType = USB_DT_CONFIG,
271 /* .wTotalLength computed dynamically */
272 .bNumInterfaces = 1,
273 .bConfigurationValue = GS_BULK_CONFIG_ID,
274 .iConfiguration = GS_BULK_CONFIG_STR_ID,
275 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
276 .bMaxPower = 1,
277};
278
279static struct usb_config_descriptor gs_acm_config_desc = {
280 .bLength = USB_DT_CONFIG_SIZE,
281 .bDescriptorType = USB_DT_CONFIG,
282 /* .wTotalLength computed dynamically */
283 .bNumInterfaces = 2,
284 .bConfigurationValue = GS_ACM_CONFIG_ID,
285 .iConfiguration = GS_ACM_CONFIG_STR_ID,
286 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
287 .bMaxPower = 1,
288};
289
290static const struct usb_interface_descriptor gs_bulk_interface_desc = {
291 .bLength = USB_DT_INTERFACE_SIZE,
292 .bDescriptorType = USB_DT_INTERFACE,
293 .bInterfaceNumber = GS_BULK_INTERFACE_ID,
294 .bNumEndpoints = 2,
295 .bInterfaceClass = USB_CLASS_CDC_DATA,
296 .bInterfaceSubClass = 0,
297 .bInterfaceProtocol = 0,
298 .iInterface = GS_DATA_STR_ID,
299};
300
301static const struct usb_interface_descriptor gs_control_interface_desc = {
302 .bLength = USB_DT_INTERFACE_SIZE,
303 .bDescriptorType = USB_DT_INTERFACE,
304 .bInterfaceNumber = GS_CONTROL_INTERFACE_ID,
305 .bNumEndpoints = 1,
306 .bInterfaceClass = USB_CLASS_COMM,
307 .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
308 .bInterfaceProtocol = USB_CDC_ACM_PROTO_AT_V25TER,
309 .iInterface = GS_CONTROL_STR_ID,
310};
311
312static const struct usb_interface_descriptor gs_data_interface_desc = {
313 .bLength = USB_DT_INTERFACE_SIZE,
314 .bDescriptorType = USB_DT_INTERFACE,
315 .bInterfaceNumber = GS_DATA_INTERFACE_ID,
316 .bNumEndpoints = 2,
317 .bInterfaceClass = USB_CLASS_CDC_DATA,
318 .bInterfaceSubClass = 0,
319 .bInterfaceProtocol = 0,
320 .iInterface = GS_DATA_STR_ID,
321};
322
323static const struct usb_cdc_header_desc gs_header_desc = {
324 .bLength = sizeof(gs_header_desc),
325 .bDescriptorType = USB_DT_CS_INTERFACE,
326 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
327 .bcdCDC = __constant_cpu_to_le16(0x0110),
328};
329
330static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = {
David Brownell51a0e852007-08-02 00:02:47 -0700331 .bLength = sizeof(gs_call_mgmt_descriptor),
332 .bDescriptorType = USB_DT_CS_INTERFACE,
333 .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
334 .bmCapabilities = 0,
335 .bDataInterface = 1, /* index of data interface */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336};
337
338static struct usb_cdc_acm_descriptor gs_acm_descriptor = {
David Brownell51a0e852007-08-02 00:02:47 -0700339 .bLength = sizeof(gs_acm_descriptor),
340 .bDescriptorType = USB_DT_CS_INTERFACE,
341 .bDescriptorSubType = USB_CDC_ACM_TYPE,
David Brownellf371e752008-04-18 17:37:49 -0700342 .bmCapabilities = (1 << 1),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343};
344
345static const struct usb_cdc_union_desc gs_union_desc = {
346 .bLength = sizeof(gs_union_desc),
347 .bDescriptorType = USB_DT_CS_INTERFACE,
348 .bDescriptorSubType = USB_CDC_UNION_TYPE,
349 .bMasterInterface0 = 0, /* index of control interface */
350 .bSlaveInterface0 = 1, /* index of data interface */
351};
David Brownell51a0e852007-08-02 00:02:47 -0700352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = {
354 .bLength = USB_DT_ENDPOINT_SIZE,
355 .bDescriptorType = USB_DT_ENDPOINT,
356 .bEndpointAddress = USB_DIR_IN,
357 .bmAttributes = USB_ENDPOINT_XFER_INT,
358 .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
359 .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
360};
361
362static struct usb_endpoint_descriptor gs_fullspeed_in_desc = {
363 .bLength = USB_DT_ENDPOINT_SIZE,
364 .bDescriptorType = USB_DT_ENDPOINT,
365 .bEndpointAddress = USB_DIR_IN,
366 .bmAttributes = USB_ENDPOINT_XFER_BULK,
367};
368
369static struct usb_endpoint_descriptor gs_fullspeed_out_desc = {
370 .bLength = USB_DT_ENDPOINT_SIZE,
371 .bDescriptorType = USB_DT_ENDPOINT,
372 .bEndpointAddress = USB_DIR_OUT,
373 .bmAttributes = USB_ENDPOINT_XFER_BULK,
374};
375
376static const struct usb_descriptor_header *gs_bulk_fullspeed_function[] = {
377 (struct usb_descriptor_header *) &gs_otg_descriptor,
378 (struct usb_descriptor_header *) &gs_bulk_interface_desc,
379 (struct usb_descriptor_header *) &gs_fullspeed_in_desc,
380 (struct usb_descriptor_header *) &gs_fullspeed_out_desc,
381 NULL,
382};
383
384static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = {
385 (struct usb_descriptor_header *) &gs_otg_descriptor,
386 (struct usb_descriptor_header *) &gs_control_interface_desc,
387 (struct usb_descriptor_header *) &gs_header_desc,
388 (struct usb_descriptor_header *) &gs_call_mgmt_descriptor,
389 (struct usb_descriptor_header *) &gs_acm_descriptor,
390 (struct usb_descriptor_header *) &gs_union_desc,
391 (struct usb_descriptor_header *) &gs_fullspeed_notify_desc,
392 (struct usb_descriptor_header *) &gs_data_interface_desc,
393 (struct usb_descriptor_header *) &gs_fullspeed_in_desc,
394 (struct usb_descriptor_header *) &gs_fullspeed_out_desc,
395 NULL,
396};
397
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398static struct usb_endpoint_descriptor gs_highspeed_notify_desc = {
399 .bLength = USB_DT_ENDPOINT_SIZE,
400 .bDescriptorType = USB_DT_ENDPOINT,
401 .bEndpointAddress = USB_DIR_IN,
402 .bmAttributes = USB_ENDPOINT_XFER_INT,
403 .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
404 .bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
405};
406
407static struct usb_endpoint_descriptor gs_highspeed_in_desc = {
408 .bLength = USB_DT_ENDPOINT_SIZE,
409 .bDescriptorType = USB_DT_ENDPOINT,
410 .bmAttributes = USB_ENDPOINT_XFER_BULK,
411 .wMaxPacketSize = __constant_cpu_to_le16(512),
412};
413
414static struct usb_endpoint_descriptor gs_highspeed_out_desc = {
415 .bLength = USB_DT_ENDPOINT_SIZE,
416 .bDescriptorType = USB_DT_ENDPOINT,
417 .bmAttributes = USB_ENDPOINT_XFER_BULK,
418 .wMaxPacketSize = __constant_cpu_to_le16(512),
419};
420
421static struct usb_qualifier_descriptor gs_qualifier_desc = {
422 .bLength = sizeof(struct usb_qualifier_descriptor),
423 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
424 .bcdUSB = __constant_cpu_to_le16 (0x0200),
425 /* assumes ep0 uses the same value for both speeds ... */
426 .bNumConfigurations = GS_NUM_CONFIGS,
427};
428
429static const struct usb_descriptor_header *gs_bulk_highspeed_function[] = {
430 (struct usb_descriptor_header *) &gs_otg_descriptor,
431 (struct usb_descriptor_header *) &gs_bulk_interface_desc,
432 (struct usb_descriptor_header *) &gs_highspeed_in_desc,
433 (struct usb_descriptor_header *) &gs_highspeed_out_desc,
434 NULL,
435};
436
437static const struct usb_descriptor_header *gs_acm_highspeed_function[] = {
438 (struct usb_descriptor_header *) &gs_otg_descriptor,
439 (struct usb_descriptor_header *) &gs_control_interface_desc,
440 (struct usb_descriptor_header *) &gs_header_desc,
441 (struct usb_descriptor_header *) &gs_call_mgmt_descriptor,
442 (struct usb_descriptor_header *) &gs_acm_descriptor,
443 (struct usb_descriptor_header *) &gs_union_desc,
444 (struct usb_descriptor_header *) &gs_highspeed_notify_desc,
445 (struct usb_descriptor_header *) &gs_data_interface_desc,
446 (struct usb_descriptor_header *) &gs_highspeed_in_desc,
447 (struct usb_descriptor_header *) &gs_highspeed_out_desc,
448 NULL,
449};
450
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451
David Brownell9079e912008-05-07 16:00:36 -0700452/*-------------------------------------------------------------------------*/
453
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454/* Module */
455MODULE_DESCRIPTION(GS_LONG_NAME);
456MODULE_AUTHOR("Al Borchers");
457MODULE_LICENSE("GPL");
458
David Brownell51a0e852007-08-02 00:02:47 -0700459#ifdef DEBUG
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460module_param(debug, int, S_IRUGO|S_IWUSR);
461MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
462#endif
463
David Brownell9079e912008-05-07 16:00:36 -0700464static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465module_param(read_q_size, uint, S_IRUGO);
466MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32");
467
David Brownell9079e912008-05-07 16:00:36 -0700468static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469module_param(write_q_size, uint, S_IRUGO);
470MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32");
471
David Brownell9079e912008-05-07 16:00:36 -0700472static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473module_param(write_buf_size, uint, S_IRUGO);
474MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192");
475
David Brownell9079e912008-05-07 16:00:36 -0700476static unsigned int use_acm = GS_DEFAULT_USE_ACM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477module_param(use_acm, uint, S_IRUGO);
478MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no");
479
David Brownell9079e912008-05-07 16:00:36 -0700480/*-------------------------------------------------------------------------*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482/* TTY Driver */
483
484/*
485 * gs_open
486 */
487static int gs_open(struct tty_struct *tty, struct file *file)
488{
489 int port_num;
490 unsigned long flags;
491 struct gs_port *port;
492 struct gs_dev *dev;
493 struct gs_buf *buf;
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200494 struct mutex *mtx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 int ret;
496
497 port_num = tty->index;
498
499 gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file);
500
501 if (port_num < 0 || port_num >= GS_NUM_PORTS) {
David Brownell00274922007-11-19 12:58:36 -0800502 pr_err("gs_open: (%d,%p,%p) invalid port number\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 port_num, tty, file);
504 return -ENODEV;
505 }
506
507 dev = gs_device;
508
509 if (dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800510 pr_err("gs_open: (%d,%p,%p) NULL device pointer\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 port_num, tty, file);
512 return -ENODEV;
513 }
514
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200515 mtx = &gs_open_close_lock[port_num];
516 if (mutex_lock_interruptible(mtx)) {
David Brownell00274922007-11-19 12:58:36 -0800517 pr_err("gs_open: (%d,%p,%p) interrupted waiting for mutex\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 port_num, tty, file);
519 return -ERESTARTSYS;
520 }
521
522 spin_lock_irqsave(&dev->dev_lock, flags);
523
524 if (dev->dev_config == GS_NO_CONFIG_ID) {
David Brownell00274922007-11-19 12:58:36 -0800525 pr_err("gs_open: (%d,%p,%p) device is not connected\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 port_num, tty, file);
527 ret = -ENODEV;
528 goto exit_unlock_dev;
529 }
530
531 port = dev->dev_port[port_num];
532
533 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800534 pr_err("gs_open: (%d,%p,%p) NULL port pointer\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 port_num, tty, file);
536 ret = -ENODEV;
537 goto exit_unlock_dev;
538 }
539
540 spin_lock(&port->port_lock);
541 spin_unlock(&dev->dev_lock);
542
543 if (port->port_dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800544 pr_err("gs_open: (%d,%p,%p) port disconnected (1)\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 port_num, tty, file);
546 ret = -EIO;
547 goto exit_unlock_port;
548 }
549
550 if (port->port_open_count > 0) {
551 ++port->port_open_count;
552 gs_debug("gs_open: (%d,%p,%p) already open\n",
553 port_num, tty, file);
554 ret = 0;
555 goto exit_unlock_port;
556 }
557
558 tty->driver_data = NULL;
559
560 /* mark port as in use, we can drop port lock and sleep if necessary */
561 port->port_in_use = 1;
562
563 /* allocate write buffer on first open */
564 if (port->port_write_buf == NULL) {
565 spin_unlock_irqrestore(&port->port_lock, flags);
566 buf = gs_buf_alloc(write_buf_size, GFP_KERNEL);
567 spin_lock_irqsave(&port->port_lock, flags);
568
569 /* might have been disconnected while asleep, check */
570 if (port->port_dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800571 pr_err("gs_open: (%d,%p,%p) port disconnected (2)\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 port_num, tty, file);
573 port->port_in_use = 0;
574 ret = -EIO;
575 goto exit_unlock_port;
576 }
577
578 if ((port->port_write_buf=buf) == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800579 pr_err("gs_open: (%d,%p,%p) cannot allocate "
580 "port write buffer\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 port_num, tty, file);
582 port->port_in_use = 0;
583 ret = -ENOMEM;
584 goto exit_unlock_port;
585 }
586
587 }
588
589 /* wait for carrier detect (not implemented) */
590
591 /* might have been disconnected while asleep, check */
592 if (port->port_dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800593 pr_err("gs_open: (%d,%p,%p) port disconnected (3)\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 port_num, tty, file);
595 port->port_in_use = 0;
596 ret = -EIO;
597 goto exit_unlock_port;
598 }
599
600 tty->driver_data = port;
601 port->port_tty = tty;
602 port->port_open_count = 1;
603 port->port_in_use = 0;
604
605 gs_debug("gs_open: (%d,%p,%p) completed\n", port_num, tty, file);
606
607 ret = 0;
608
609exit_unlock_port:
610 spin_unlock_irqrestore(&port->port_lock, flags);
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200611 mutex_unlock(mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 return ret;
613
614exit_unlock_dev:
615 spin_unlock_irqrestore(&dev->dev_lock, flags);
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200616 mutex_unlock(mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 return ret;
618
619}
620
621/*
622 * gs_close
623 */
Franck Bui-Huu943e1b42006-06-14 10:29:21 +0200624
David Brownell9079e912008-05-07 16:00:36 -0700625static int gs_write_finished_event_safely(struct gs_port *p)
626{
627 int cond;
628
629 spin_lock_irq(&(p)->port_lock);
630 cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf);
631 spin_unlock_irq(&(p)->port_lock);
632 return cond;
633}
Franck Bui-Huu943e1b42006-06-14 10:29:21 +0200634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635static void gs_close(struct tty_struct *tty, struct file *file)
636{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 struct gs_port *port = tty->driver_data;
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200638 struct mutex *mtx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800641 pr_err("gs_close: NULL port pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 return;
643 }
644
645 gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file);
646
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200647 mtx = &gs_open_close_lock[port->port_num];
648 mutex_lock(mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
Franck Bui-Huuca094f12006-06-14 10:47:18 +0200650 spin_lock_irq(&port->port_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651
652 if (port->port_open_count == 0) {
David Brownell00274922007-11-19 12:58:36 -0800653 pr_err("gs_close: (%d,%p,%p) port is already closed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 port->port_num, tty, file);
655 goto exit;
656 }
657
658 if (port->port_open_count > 1) {
659 --port->port_open_count;
660 goto exit;
661 }
662
663 /* free disconnected port on final close */
664 if (port->port_dev == NULL) {
665 kfree(port);
666 goto exit;
667 }
668
669 /* mark port as closed but in use, we can drop port lock */
670 /* and sleep if necessary */
671 port->port_in_use = 1;
672 port->port_open_count = 0;
673
674 /* wait for write buffer to drain, or */
675 /* at most GS_CLOSE_TIMEOUT seconds */
676 if (gs_buf_data_avail(port->port_write_buf) > 0) {
Franck Bui-Huuca094f12006-06-14 10:47:18 +0200677 spin_unlock_irq(&port->port_lock);
Franck Bui-Huu943e1b42006-06-14 10:29:21 +0200678 wait_event_interruptible_timeout(port->port_write_wait,
David Brownell9079e912008-05-07 16:00:36 -0700679 gs_write_finished_event_safely(port),
Franck Bui-Huu943e1b42006-06-14 10:29:21 +0200680 GS_CLOSE_TIMEOUT * HZ);
Franck Bui-Huuca094f12006-06-14 10:47:18 +0200681 spin_lock_irq(&port->port_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 }
683
684 /* free disconnected port on final close */
685 /* (might have happened during the above sleep) */
686 if (port->port_dev == NULL) {
687 kfree(port);
688 goto exit;
689 }
690
691 gs_buf_clear(port->port_write_buf);
692
693 tty->driver_data = NULL;
694 port->port_tty = NULL;
695 port->port_in_use = 0;
696
697 gs_debug("gs_close: (%d,%p,%p) completed\n",
698 port->port_num, tty, file);
699
700exit:
Franck Bui-Huuca094f12006-06-14 10:47:18 +0200701 spin_unlock_irq(&port->port_lock);
Matthias Kaehlcke831c70f2007-07-13 21:25:25 +0200702 mutex_unlock(mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703}
704
705/*
706 * gs_write
707 */
708static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count)
709{
710 unsigned long flags;
711 struct gs_port *port = tty->driver_data;
712 int ret;
713
714 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800715 pr_err("gs_write: NULL port pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 return -EIO;
717 }
718
719 gs_debug("gs_write: (%d,%p) writing %d bytes\n", port->port_num, tty,
720 count);
721
722 if (count == 0)
723 return 0;
724
725 spin_lock_irqsave(&port->port_lock, flags);
726
727 if (port->port_dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800728 pr_err("gs_write: (%d,%p) port is not connected\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 port->port_num, tty);
730 ret = -EIO;
731 goto exit;
732 }
733
734 if (port->port_open_count == 0) {
David Brownell00274922007-11-19 12:58:36 -0800735 pr_err("gs_write: (%d,%p) port is closed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 port->port_num, tty);
737 ret = -EBADF;
738 goto exit;
739 }
740
741 count = gs_buf_put(port->port_write_buf, buf, count);
742
743 spin_unlock_irqrestore(&port->port_lock, flags);
744
745 gs_send(gs_device);
746
747 gs_debug("gs_write: (%d,%p) wrote %d bytes\n", port->port_num, tty,
748 count);
749
750 return count;
751
752exit:
753 spin_unlock_irqrestore(&port->port_lock, flags);
754 return ret;
755}
756
757/*
758 * gs_put_char
759 */
Alan Cox4cd55ab2008-04-30 00:54:01 -0700760static int gs_put_char(struct tty_struct *tty, unsigned char ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761{
762 unsigned long flags;
763 struct gs_port *port = tty->driver_data;
Alan Cox4cd55ab2008-04-30 00:54:01 -0700764 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765
766 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800767 pr_err("gs_put_char: NULL port pointer\n");
Alan Cox4cd55ab2008-04-30 00:54:01 -0700768 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 }
770
David Brownell51a0e852007-08-02 00:02:47 -0700771 gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n",
772 port->port_num, tty, ch, __builtin_return_address(0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773
774 spin_lock_irqsave(&port->port_lock, flags);
775
776 if (port->port_dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800777 pr_err("gs_put_char: (%d,%p) port is not connected\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 port->port_num, tty);
779 goto exit;
780 }
781
782 if (port->port_open_count == 0) {
David Brownell00274922007-11-19 12:58:36 -0800783 pr_err("gs_put_char: (%d,%p) port is closed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 port->port_num, tty);
785 goto exit;
786 }
787
Alan Cox4cd55ab2008-04-30 00:54:01 -0700788 ret = gs_buf_put(port->port_write_buf, &ch, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789
790exit:
791 spin_unlock_irqrestore(&port->port_lock, flags);
Alan Cox4cd55ab2008-04-30 00:54:01 -0700792 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793}
794
795/*
796 * gs_flush_chars
797 */
798static void gs_flush_chars(struct tty_struct *tty)
799{
800 unsigned long flags;
801 struct gs_port *port = tty->driver_data;
802
803 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800804 pr_err("gs_flush_chars: NULL port pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 return;
806 }
807
808 gs_debug("gs_flush_chars: (%d,%p)\n", port->port_num, tty);
809
810 spin_lock_irqsave(&port->port_lock, flags);
811
812 if (port->port_dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800813 pr_err("gs_flush_chars: (%d,%p) port is not connected\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 port->port_num, tty);
815 goto exit;
816 }
817
818 if (port->port_open_count == 0) {
David Brownell00274922007-11-19 12:58:36 -0800819 pr_err("gs_flush_chars: (%d,%p) port is closed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 port->port_num, tty);
821 goto exit;
822 }
823
824 spin_unlock_irqrestore(&port->port_lock, flags);
825
826 gs_send(gs_device);
827
828 return;
829
830exit:
831 spin_unlock_irqrestore(&port->port_lock, flags);
832}
833
834/*
835 * gs_write_room
836 */
837static int gs_write_room(struct tty_struct *tty)
838{
839
840 int room = 0;
841 unsigned long flags;
842 struct gs_port *port = tty->driver_data;
843
844
845 if (port == NULL)
846 return 0;
847
848 spin_lock_irqsave(&port->port_lock, flags);
849
850 if (port->port_dev != NULL && port->port_open_count > 0
851 && port->port_write_buf != NULL)
852 room = gs_buf_space_avail(port->port_write_buf);
853
854 spin_unlock_irqrestore(&port->port_lock, flags);
855
856 gs_debug("gs_write_room: (%d,%p) room=%d\n",
857 port->port_num, tty, room);
858
859 return room;
860}
861
862/*
863 * gs_chars_in_buffer
864 */
865static int gs_chars_in_buffer(struct tty_struct *tty)
866{
867 int chars = 0;
868 unsigned long flags;
869 struct gs_port *port = tty->driver_data;
870
871 if (port == NULL)
872 return 0;
873
874 spin_lock_irqsave(&port->port_lock, flags);
875
876 if (port->port_dev != NULL && port->port_open_count > 0
877 && port->port_write_buf != NULL)
878 chars = gs_buf_data_avail(port->port_write_buf);
879
880 spin_unlock_irqrestore(&port->port_lock, flags);
881
882 gs_debug("gs_chars_in_buffer: (%d,%p) chars=%d\n",
883 port->port_num, tty, chars);
884
885 return chars;
886}
887
888/*
889 * gs_throttle
890 */
891static void gs_throttle(struct tty_struct *tty)
892{
893}
894
895/*
896 * gs_unthrottle
897 */
898static void gs_unthrottle(struct tty_struct *tty)
899{
900}
901
902/*
903 * gs_break
904 */
905static void gs_break(struct tty_struct *tty, int break_state)
906{
907}
908
909/*
910 * gs_ioctl
911 */
912static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
913{
914 struct gs_port *port = tty->driver_data;
915
916 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800917 pr_err("gs_ioctl: NULL port pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 return -EIO;
919 }
920
921 gs_debug("gs_ioctl: (%d,%p,%p) cmd=0x%4.4x, arg=%lu\n",
922 port->port_num, tty, file, cmd, arg);
923
924 /* handle ioctls */
925
926 /* could not handle ioctl */
927 return -ENOIOCTLCMD;
928}
929
930/*
931 * gs_set_termios
932 */
Alan Cox606d0992006-12-08 02:38:45 -0800933static void gs_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934{
935}
936
David Brownell9079e912008-05-07 16:00:36 -0700937static const struct tty_operations gs_tty_ops = {
938 .open = gs_open,
939 .close = gs_close,
940 .write = gs_write,
941 .put_char = gs_put_char,
942 .flush_chars = gs_flush_chars,
943 .write_room = gs_write_room,
944 .ioctl = gs_ioctl,
945 .set_termios = gs_set_termios,
946 .throttle = gs_throttle,
947 .unthrottle = gs_unthrottle,
948 .break_ctl = gs_break,
949 .chars_in_buffer = gs_chars_in_buffer,
950};
951
952/*-------------------------------------------------------------------------*/
953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954/*
955* gs_send
956*
957* This function finds available write requests, calls
958* gs_send_packet to fill these packets with data, and
959* continues until either there are no more write requests
960* available or no more data to send. This function is
961* run whenever data arrives or write requests are available.
962*/
963static int gs_send(struct gs_dev *dev)
964{
965 int ret,len;
966 unsigned long flags;
967 struct usb_ep *ep;
968 struct usb_request *req;
969 struct gs_req_entry *req_entry;
970
971 if (dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -0800972 pr_err("gs_send: NULL device pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 return -ENODEV;
974 }
975
976 spin_lock_irqsave(&dev->dev_lock, flags);
977
978 ep = dev->dev_in_ep;
979
980 while(!list_empty(&dev->dev_req_list)) {
981
982 req_entry = list_entry(dev->dev_req_list.next,
983 struct gs_req_entry, re_entry);
984
985 req = req_entry->re_req;
986
987 len = gs_send_packet(dev, req->buf, ep->maxpacket);
988
989 if (len > 0) {
David Brownell51a0e852007-08-02 00:02:47 -0700990 gs_debug_level(3, "gs_send: len=%d, 0x%2.2x "
991 "0x%2.2x 0x%2.2x ...\n", len,
992 *((unsigned char *)req->buf),
993 *((unsigned char *)req->buf+1),
994 *((unsigned char *)req->buf+2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 list_del(&req_entry->re_entry);
996 req->length = len;
Eugeny S. Mints80f8af02006-09-02 03:59:19 -0700997 spin_unlock_irqrestore(&dev->dev_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
David Brownell00274922007-11-19 12:58:36 -0800999 pr_err(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 "gs_send: cannot queue read request, ret=%d\n",
1001 ret);
Eugeny S. Mints80f8af02006-09-02 03:59:19 -07001002 spin_lock_irqsave(&dev->dev_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 break;
1004 }
Eugeny S. Mints80f8af02006-09-02 03:59:19 -07001005 spin_lock_irqsave(&dev->dev_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 } else {
1007 break;
1008 }
1009
1010 }
1011
1012 spin_unlock_irqrestore(&dev->dev_lock, flags);
1013
1014 return 0;
1015}
1016
1017/*
1018 * gs_send_packet
1019 *
1020 * If there is data to send, a packet is built in the given
1021 * buffer and the size is returned. If there is no data to
1022 * send, 0 is returned. If there is any error a negative
1023 * error number is returned.
1024 *
1025 * Called during USB completion routine, on interrupt time.
1026 *
1027 * We assume that disconnect will not happen until all completion
1028 * routines have completed, so we can assume that the dev_port
1029 * array does not change during the lifetime of this function.
1030 */
1031static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size)
1032{
1033 unsigned int len;
1034 struct gs_port *port;
1035
1036 /* TEMPORARY -- only port 0 is supported right now */
1037 port = dev->dev_port[0];
1038
1039 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001040 pr_err("gs_send_packet: port=%d, NULL port pointer\n", 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 return -EIO;
1042 }
1043
1044 spin_lock(&port->port_lock);
1045
1046 len = gs_buf_data_avail(port->port_write_buf);
1047 if (len < size)
1048 size = len;
1049
1050 if (size == 0)
1051 goto exit;
1052
1053 size = gs_buf_get(port->port_write_buf, packet, size);
1054
1055 if (port->port_tty)
1056 wake_up_interruptible(&port->port_tty->write_wait);
1057
1058exit:
1059 spin_unlock(&port->port_lock);
1060 return size;
1061}
1062
1063/*
1064 * gs_recv_packet
1065 *
1066 * Called for each USB packet received. Reads the packet
1067 * header and stuffs the data in the appropriate tty buffer.
1068 * Returns 0 if successful, or a negative error number.
1069 *
1070 * Called during USB completion routine, on interrupt time.
1071 *
1072 * We assume that disconnect will not happen until all completion
1073 * routines have completed, so we can assume that the dev_port
1074 * array does not change during the lifetime of this function.
1075 */
1076static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size)
1077{
1078 unsigned int len;
1079 struct gs_port *port;
1080 int ret;
Alan Cox33f0f882006-01-09 20:54:13 -08001081 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
1083 /* TEMPORARY -- only port 0 is supported right now */
1084 port = dev->dev_port[0];
1085
1086 if (port == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001087 pr_err("gs_recv_packet: port=%d, NULL port pointer\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 port->port_num);
1089 return -EIO;
1090 }
1091
1092 spin_lock(&port->port_lock);
1093
1094 if (port->port_open_count == 0) {
David Brownell00274922007-11-19 12:58:36 -08001095 pr_err("gs_recv_packet: port=%d, port is closed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 port->port_num);
1097 ret = -EIO;
1098 goto exit;
1099 }
1100
Alan Cox33f0f882006-01-09 20:54:13 -08001101
1102 tty = port->port_tty;
1103
1104 if (tty == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001105 pr_err("gs_recv_packet: port=%d, NULL tty pointer\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 port->port_num);
1107 ret = -EIO;
1108 goto exit;
1109 }
1110
1111 if (port->port_tty->magic != TTY_MAGIC) {
David Brownell00274922007-11-19 12:58:36 -08001112 pr_err("gs_recv_packet: port=%d, bad tty magic\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 port->port_num);
1114 ret = -EIO;
1115 goto exit;
1116 }
1117
Alan Cox33f0f882006-01-09 20:54:13 -08001118 len = tty_buffer_request_room(tty, size);
1119 if (len > 0) {
1120 tty_insert_flip_string(tty, packet, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 tty_flip_buffer_push(port->port_tty);
1122 wake_up_interruptible(&port->port_tty->read_wait);
1123 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125exit:
1126 spin_unlock(&port->port_lock);
1127 return ret;
1128}
1129
1130/*
1131* gs_read_complete
1132*/
1133static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
1134{
1135 int ret;
1136 struct gs_dev *dev = ep->driver_data;
1137
1138 if (dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001139 pr_err("gs_read_complete: NULL device pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 return;
1141 }
1142
1143 switch(req->status) {
1144 case 0:
David Brownell51a0e852007-08-02 00:02:47 -07001145 /* normal completion */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 gs_recv_packet(dev, req->buf, req->actual);
1147requeue:
1148 req->length = ep->maxpacket;
1149 if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
David Brownell00274922007-11-19 12:58:36 -08001150 pr_err(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 "gs_read_complete: cannot queue read request, ret=%d\n",
1152 ret);
1153 }
1154 break;
1155
1156 case -ESHUTDOWN:
1157 /* disconnect */
1158 gs_debug("gs_read_complete: shutdown\n");
1159 gs_free_req(ep, req);
1160 break;
1161
1162 default:
1163 /* unexpected */
David Brownell00274922007-11-19 12:58:36 -08001164 pr_err(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 "gs_read_complete: unexpected status error, status=%d\n",
1166 req->status);
1167 goto requeue;
1168 break;
1169 }
1170}
1171
1172/*
1173* gs_write_complete
1174*/
1175static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
1176{
1177 struct gs_dev *dev = ep->driver_data;
1178 struct gs_req_entry *gs_req = req->context;
1179
1180 if (dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001181 pr_err("gs_write_complete: NULL device pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 return;
1183 }
1184
1185 switch(req->status) {
1186 case 0:
1187 /* normal completion */
1188requeue:
1189 if (gs_req == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001190 pr_err("gs_write_complete: NULL request pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 return;
1192 }
1193
1194 spin_lock(&dev->dev_lock);
1195 list_add(&gs_req->re_entry, &dev->dev_req_list);
1196 spin_unlock(&dev->dev_lock);
1197
1198 gs_send(dev);
1199
1200 break;
1201
1202 case -ESHUTDOWN:
1203 /* disconnect */
1204 gs_debug("gs_write_complete: shutdown\n");
1205 gs_free_req(ep, req);
1206 break;
1207
1208 default:
David Brownell00274922007-11-19 12:58:36 -08001209 pr_err(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 "gs_write_complete: unexpected status error, status=%d\n",
1211 req->status);
1212 goto requeue;
1213 break;
1214 }
1215}
1216
David Brownell9079e912008-05-07 16:00:36 -07001217/*-------------------------------------------------------------------------*/
1218
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219/* Gadget Driver */
1220
1221/*
David Brownell9079e912008-05-07 16:00:36 -07001222 * gs_unbind
1223 *
1224 * Called on module unload. Frees the control request and device
1225 * structure.
1226 */
1227static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
1228{
1229 struct gs_dev *dev = get_gadget_data(gadget);
1230
1231 gs_device = NULL;
1232
1233 /* read/write requests already freed, only control request remains */
1234 if (dev != NULL) {
1235 if (dev->dev_ctrl_req != NULL) {
1236 gs_free_req(gadget->ep0, dev->dev_ctrl_req);
1237 dev->dev_ctrl_req = NULL;
1238 }
1239 gs_free_ports(dev);
1240 if (dev->dev_notify_ep)
1241 usb_ep_disable(dev->dev_notify_ep);
1242 if (dev->dev_in_ep)
1243 usb_ep_disable(dev->dev_in_ep);
1244 if (dev->dev_out_ep)
1245 usb_ep_disable(dev->dev_out_ep);
1246 kfree(dev);
1247 set_gadget_data(gadget, NULL);
1248 }
1249
1250 pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
1251 GS_VERSION_STR);
1252}
1253
1254/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 * gs_bind
1256 *
1257 * Called on module load. Allocates and initializes the device
1258 * structure and a control request.
1259 */
David Brownell329af282006-02-18 12:31:05 -08001260static int __init gs_bind(struct usb_gadget *gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261{
1262 int ret;
1263 struct usb_ep *ep;
1264 struct gs_dev *dev;
David Brownell91e79c92005-07-13 15:18:30 -07001265 int gcnum;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266
David Brownell91e79c92005-07-13 15:18:30 -07001267 /* Some controllers can't support CDC ACM:
1268 * - sh doesn't support multiple interfaces or configs;
1269 * - sa1100 doesn't have a third interrupt endpoint
1270 */
1271 if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 use_acm = 0;
David Brownell91e79c92005-07-13 15:18:30 -07001273
1274 gcnum = usb_gadget_controller_number(gadget);
1275 if (gcnum >= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 gs_device_desc.bcdDevice =
David Brownell91e79c92005-07-13 15:18:30 -07001277 cpu_to_le16(GS_VERSION_NUM | gcnum);
1278 else {
David Brownell00274922007-11-19 12:58:36 -08001279 pr_warning("gs_bind: controller '%s' not recognized\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 gadget->name);
1281 /* unrecognized, but safe unless bulk is REALLY quirky */
1282 gs_device_desc.bcdDevice =
1283 __constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
1284 }
1285
1286 usb_ep_autoconfig_reset(gadget);
1287
1288 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc);
1289 if (!ep)
1290 goto autoconf_fail;
1291 EP_IN_NAME = ep->name;
1292 ep->driver_data = ep; /* claim the endpoint */
1293
1294 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc);
1295 if (!ep)
1296 goto autoconf_fail;
1297 EP_OUT_NAME = ep->name;
1298 ep->driver_data = ep; /* claim the endpoint */
1299
1300 if (use_acm) {
1301 ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
1302 if (!ep) {
David Brownell00274922007-11-19 12:58:36 -08001303 pr_err("gs_bind: cannot run ACM on %s\n", gadget->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 goto autoconf_fail;
1305 }
1306 gs_device_desc.idProduct = __constant_cpu_to_le16(
1307 GS_CDC_PRODUCT_ID),
1308 EP_NOTIFY_NAME = ep->name;
1309 ep->driver_data = ep; /* claim the endpoint */
1310 }
1311
1312 gs_device_desc.bDeviceClass = use_acm
1313 ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
1314 gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
1315
David Brownell51a0e852007-08-02 00:02:47 -07001316 if (gadget_is_dualspeed(gadget)) {
1317 gs_qualifier_desc.bDeviceClass = use_acm
1318 ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
1319 /* assume ep0 uses the same packet size for both speeds */
1320 gs_qualifier_desc.bMaxPacketSize0 =
1321 gs_device_desc.bMaxPacketSize0;
1322 /* assume endpoints are dual-speed */
1323 gs_highspeed_notify_desc.bEndpointAddress =
1324 gs_fullspeed_notify_desc.bEndpointAddress;
1325 gs_highspeed_in_desc.bEndpointAddress =
1326 gs_fullspeed_in_desc.bEndpointAddress;
1327 gs_highspeed_out_desc.bEndpointAddress =
1328 gs_fullspeed_out_desc.bEndpointAddress;
1329 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
1331 usb_gadget_set_selfpowered(gadget);
1332
David Brownell51a0e852007-08-02 00:02:47 -07001333 if (gadget_is_otg(gadget)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 gs_otg_descriptor.bmAttributes |= USB_OTG_HNP,
1335 gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
1336 gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
1337 }
1338
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07001339 gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 if (dev == NULL)
1341 return -ENOMEM;
1342
1343 snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
Serge E. Hallyn96b644b2006-10-02 02:18:13 -07001344 init_utsname()->sysname, init_utsname()->release,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 gadget->name);
1346
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 dev->dev_gadget = gadget;
1348 spin_lock_init(&dev->dev_lock);
1349 INIT_LIST_HEAD(&dev->dev_req_list);
1350 set_gadget_data(gadget, dev);
1351
1352 if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) {
David Brownell00274922007-11-19 12:58:36 -08001353 pr_err("gs_bind: cannot allocate ports\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 gs_unbind(gadget);
1355 return ret;
1356 }
1357
1358 /* preallocate control response and buffer */
1359 dev->dev_ctrl_req = gs_alloc_req(gadget->ep0, GS_MAX_DESC_LEN,
1360 GFP_KERNEL);
1361 if (dev->dev_ctrl_req == NULL) {
1362 gs_unbind(gadget);
1363 return -ENOMEM;
1364 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 gadget->ep0->driver_data = dev;
1366
David Brownell00274922007-11-19 12:58:36 -08001367 pr_info("gs_bind: %s %s bound\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 GS_LONG_NAME, GS_VERSION_STR);
1369
1370 return 0;
1371
1372autoconf_fail:
David Brownell00274922007-11-19 12:58:36 -08001373 pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 return -ENODEV;
1375}
1376
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377static int gs_setup_standard(struct usb_gadget *gadget,
1378 const struct usb_ctrlrequest *ctrl)
1379{
1380 int ret = -EOPNOTSUPP;
1381 struct gs_dev *dev = get_gadget_data(gadget);
1382 struct usb_request *req = dev->dev_ctrl_req;
David Brownell1bbc1692005-05-07 13:05:13 -07001383 u16 wIndex = le16_to_cpu(ctrl->wIndex);
1384 u16 wValue = le16_to_cpu(ctrl->wValue);
1385 u16 wLength = le16_to_cpu(ctrl->wLength);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386
1387 switch (ctrl->bRequest) {
1388 case USB_REQ_GET_DESCRIPTOR:
1389 if (ctrl->bRequestType != USB_DIR_IN)
1390 break;
1391
1392 switch (wValue >> 8) {
1393 case USB_DT_DEVICE:
1394 ret = min(wLength,
1395 (u16)sizeof(struct usb_device_descriptor));
1396 memcpy(req->buf, &gs_device_desc, ret);
1397 break;
1398
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 case USB_DT_DEVICE_QUALIFIER:
David Brownell51a0e852007-08-02 00:02:47 -07001400 if (!gadget_is_dualspeed(gadget))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 break;
1402 ret = min(wLength,
1403 (u16)sizeof(struct usb_qualifier_descriptor));
1404 memcpy(req->buf, &gs_qualifier_desc, ret);
1405 break;
1406
1407 case USB_DT_OTHER_SPEED_CONFIG:
David Brownell51a0e852007-08-02 00:02:47 -07001408 if (!gadget_is_dualspeed(gadget))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 break;
1410 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 case USB_DT_CONFIG:
David Brownell51a0e852007-08-02 00:02:47 -07001412 ret = gs_build_config_buf(req->buf, gadget,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 wValue >> 8, wValue & 0xff,
David Brownell51a0e852007-08-02 00:02:47 -07001414 gadget_is_otg(gadget));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 if (ret >= 0)
1416 ret = min(wLength, (u16)ret);
1417 break;
1418
1419 case USB_DT_STRING:
1420 /* wIndex == language code. */
1421 ret = usb_gadget_get_string(&gs_string_table,
1422 wValue & 0xff, req->buf);
1423 if (ret >= 0)
1424 ret = min(wLength, (u16)ret);
1425 break;
1426 }
1427 break;
1428
1429 case USB_REQ_SET_CONFIGURATION:
1430 if (ctrl->bRequestType != 0)
1431 break;
1432 spin_lock(&dev->dev_lock);
1433 ret = gs_set_config(dev, wValue);
1434 spin_unlock(&dev->dev_lock);
1435 break;
1436
1437 case USB_REQ_GET_CONFIGURATION:
1438 if (ctrl->bRequestType != USB_DIR_IN)
1439 break;
1440 *(u8 *)req->buf = dev->dev_config;
1441 ret = min(wLength, (u16)1);
1442 break;
1443
1444 case USB_REQ_SET_INTERFACE:
1445 if (ctrl->bRequestType != USB_RECIP_INTERFACE
1446 || !dev->dev_config
1447 || wIndex >= GS_MAX_NUM_INTERFACES)
1448 break;
1449 if (dev->dev_config == GS_BULK_CONFIG_ID
1450 && wIndex != GS_BULK_INTERFACE_ID)
1451 break;
1452 /* no alternate interface settings */
1453 if (wValue != 0)
1454 break;
1455 spin_lock(&dev->dev_lock);
1456 /* PXA hardware partially handles SET_INTERFACE;
1457 * we need to kluge around that interference. */
1458 if (gadget_is_pxa(gadget)) {
1459 ret = gs_set_config(dev, use_acm ?
1460 GS_ACM_CONFIG_ID : GS_BULK_CONFIG_ID);
1461 goto set_interface_done;
1462 }
1463 if (dev->dev_config != GS_BULK_CONFIG_ID
1464 && wIndex == GS_CONTROL_INTERFACE_ID) {
1465 if (dev->dev_notify_ep) {
1466 usb_ep_disable(dev->dev_notify_ep);
1467 usb_ep_enable(dev->dev_notify_ep, dev->dev_notify_ep_desc);
1468 }
1469 } else {
1470 usb_ep_disable(dev->dev_in_ep);
1471 usb_ep_disable(dev->dev_out_ep);
1472 usb_ep_enable(dev->dev_in_ep, dev->dev_in_ep_desc);
1473 usb_ep_enable(dev->dev_out_ep, dev->dev_out_ep_desc);
1474 }
1475 ret = 0;
1476set_interface_done:
1477 spin_unlock(&dev->dev_lock);
1478 break;
1479
1480 case USB_REQ_GET_INTERFACE:
1481 if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)
1482 || dev->dev_config == GS_NO_CONFIG_ID)
1483 break;
1484 if (wIndex >= GS_MAX_NUM_INTERFACES
1485 || (dev->dev_config == GS_BULK_CONFIG_ID
1486 && wIndex != GS_BULK_INTERFACE_ID)) {
1487 ret = -EDOM;
1488 break;
1489 }
1490 /* no alternate interface settings */
1491 *(u8 *)req->buf = 0;
1492 ret = min(wLength, (u16)1);
1493 break;
1494
1495 default:
David Brownell00274922007-11-19 12:58:36 -08001496 pr_err("gs_setup: unknown standard request, type=%02x, "
1497 "request=%02x, value=%04x, index=%04x, length=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 ctrl->bRequestType, ctrl->bRequest,
1499 wValue, wIndex, wLength);
1500 break;
1501 }
1502
1503 return ret;
1504}
1505
David Brownell9079e912008-05-07 16:00:36 -07001506static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
1507 struct usb_request *req)
1508{
1509 struct gs_dev *dev = ep->driver_data;
1510 struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
1511
1512 switch (req->status) {
1513 case 0:
1514 /* normal completion */
1515 if (req->actual != sizeof(port->port_line_coding))
1516 usb_ep_set_halt(ep);
1517 else if (port) {
1518 struct usb_cdc_line_coding *value = req->buf;
1519
1520 /* REVISIT: we currently just remember this data.
1521 * If we change that, (a) validate it first, then
1522 * (b) update whatever hardware needs updating.
1523 */
1524 spin_lock(&port->port_lock);
1525 port->port_line_coding = *value;
1526 spin_unlock(&port->port_lock);
1527 }
1528 break;
1529
1530 case -ESHUTDOWN:
1531 /* disconnect */
1532 gs_free_req(ep, req);
1533 break;
1534
1535 default:
1536 /* unexpected */
1537 break;
1538 }
1539 return;
1540}
1541
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542static int gs_setup_class(struct usb_gadget *gadget,
1543 const struct usb_ctrlrequest *ctrl)
1544{
1545 int ret = -EOPNOTSUPP;
1546 struct gs_dev *dev = get_gadget_data(gadget);
1547 struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
1548 struct usb_request *req = dev->dev_ctrl_req;
David Brownell1bbc1692005-05-07 13:05:13 -07001549 u16 wIndex = le16_to_cpu(ctrl->wIndex);
1550 u16 wValue = le16_to_cpu(ctrl->wValue);
1551 u16 wLength = le16_to_cpu(ctrl->wLength);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552
1553 switch (ctrl->bRequest) {
1554 case USB_CDC_REQ_SET_LINE_CODING:
David Brownellf371e752008-04-18 17:37:49 -07001555 if (wLength != sizeof(struct usb_cdc_line_coding))
1556 break;
1557 ret = wLength;
1558 req->complete = gs_setup_complete_set_line_coding;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 break;
1560
1561 case USB_CDC_REQ_GET_LINE_CODING:
David Brownellf371e752008-04-18 17:37:49 -07001562 ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 if (port) {
1564 spin_lock(&port->port_lock);
1565 memcpy(req->buf, &port->port_line_coding, ret);
1566 spin_unlock(&port->port_lock);
1567 }
1568 break;
1569
1570 case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
David Brownellf371e752008-04-18 17:37:49 -07001571 if (wLength != 0)
1572 break;
1573 ret = 0;
1574 if (port) {
1575 /* REVISIT: we currently just remember this data.
1576 * If we change that, update whatever hardware needs
1577 * updating.
1578 */
1579 spin_lock(&port->port_lock);
1580 port->port_handshake_bits = wValue;
1581 spin_unlock(&port->port_lock);
1582 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 break;
1584
1585 default:
David Brownellf371e752008-04-18 17:37:49 -07001586 /* NOTE: strictly speaking, we should accept AT-commands
1587 * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE.
1588 * But our call management descriptor says we don't handle
1589 * call management, so we should be able to get by without
1590 * handling those "required" commands (except by stalling).
1591 */
David Brownell00274922007-11-19 12:58:36 -08001592 pr_err("gs_setup: unknown class request, "
David Brownell49b4f902007-08-26 12:44:24 -07001593 "type=%02x, request=%02x, value=%04x, "
1594 "index=%04x, length=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 ctrl->bRequestType, ctrl->bRequest,
1596 wValue, wIndex, wLength);
1597 break;
1598 }
1599
1600 return ret;
1601}
1602
1603/*
1604 * gs_setup_complete
1605 */
1606static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req)
1607{
1608 if (req->status || req->actual != req->length) {
David Brownell00274922007-11-19 12:58:36 -08001609 pr_err("gs_setup_complete: status error, status=%d, "
1610 "actual=%d, length=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 req->status, req->actual, req->length);
1612 }
1613}
1614
1615/*
David Brownell9079e912008-05-07 16:00:36 -07001616 * gs_setup
1617 *
1618 * Implements all the control endpoint functionality that's not
1619 * handled in hardware or the hardware driver.
1620 *
1621 * Returns the size of the data sent to the host, or a negative
1622 * error number.
1623 */
1624static int gs_setup(struct usb_gadget *gadget,
1625 const struct usb_ctrlrequest *ctrl)
1626{
1627 int ret = -EOPNOTSUPP;
1628 struct gs_dev *dev = get_gadget_data(gadget);
1629 struct usb_request *req = dev->dev_ctrl_req;
1630 u16 wIndex = le16_to_cpu(ctrl->wIndex);
1631 u16 wValue = le16_to_cpu(ctrl->wValue);
1632 u16 wLength = le16_to_cpu(ctrl->wLength);
1633
1634 req->complete = gs_setup_complete;
1635
1636 switch (ctrl->bRequestType & USB_TYPE_MASK) {
1637 case USB_TYPE_STANDARD:
1638 ret = gs_setup_standard(gadget, ctrl);
1639 break;
1640
1641 case USB_TYPE_CLASS:
1642 ret = gs_setup_class(gadget, ctrl);
1643 break;
1644
1645 default:
1646 pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
1647 "value=%04x, index=%04x, length=%d\n",
1648 ctrl->bRequestType, ctrl->bRequest,
1649 wValue, wIndex, wLength);
1650 break;
1651 }
1652
1653 /* respond with data transfer before status phase? */
1654 if (ret >= 0) {
1655 req->length = ret;
1656 req->zero = ret < wLength
1657 && (ret % gadget->ep0->maxpacket) == 0;
1658 ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
1659 if (ret < 0) {
1660 pr_err("gs_setup: cannot queue response, ret=%d\n",
1661 ret);
1662 req->status = 0;
1663 gs_setup_complete(gadget->ep0, req);
1664 }
1665 }
1666
1667 /* device either stalls (ret < 0) or reports success */
1668 return ret;
1669}
1670
1671/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 * gs_disconnect
1673 *
1674 * Called when the device is disconnected. Frees the closed
1675 * ports and disconnects open ports. Open ports will be freed
1676 * on close. Then reallocates the ports for the next connection.
1677 */
1678static void gs_disconnect(struct usb_gadget *gadget)
1679{
1680 unsigned long flags;
1681 struct gs_dev *dev = get_gadget_data(gadget);
1682
1683 spin_lock_irqsave(&dev->dev_lock, flags);
1684
1685 gs_reset_config(dev);
1686
1687 /* free closed ports and disconnect open ports */
1688 /* (open ports will be freed when closed) */
1689 gs_free_ports(dev);
1690
1691 /* re-allocate ports for the next connection */
1692 if (gs_alloc_ports(dev, GFP_ATOMIC) != 0)
David Brownell00274922007-11-19 12:58:36 -08001693 pr_err("gs_disconnect: cannot re-allocate ports\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
1695 spin_unlock_irqrestore(&dev->dev_lock, flags);
1696
David Brownell00274922007-11-19 12:58:36 -08001697 pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698}
1699
David Brownell9079e912008-05-07 16:00:36 -07001700static struct usb_gadget_driver gs_gadget_driver = {
1701#ifdef CONFIG_USB_GADGET_DUALSPEED
1702 .speed = USB_SPEED_HIGH,
1703#else
1704 .speed = USB_SPEED_FULL,
1705#endif /* CONFIG_USB_GADGET_DUALSPEED */
1706 .function = GS_LONG_NAME,
1707 .bind = gs_bind,
1708 .unbind = gs_unbind,
1709 .setup = gs_setup,
1710 .disconnect = gs_disconnect,
1711 .driver = {
1712 .name = GS_SHORT_NAME,
1713 .owner = THIS_MODULE,
1714 },
1715};
1716
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717/*
1718 * gs_set_config
1719 *
1720 * Configures the device by enabling device specific
1721 * optimizations, setting up the endpoints, allocating
1722 * read and write requests and queuing read requests.
1723 *
1724 * The device lock must be held when calling this function.
1725 */
1726static int gs_set_config(struct gs_dev *dev, unsigned config)
1727{
1728 int i;
1729 int ret = 0;
1730 struct usb_gadget *gadget = dev->dev_gadget;
1731 struct usb_ep *ep;
1732 struct usb_endpoint_descriptor *ep_desc;
1733 struct usb_request *req;
1734 struct gs_req_entry *req_entry;
1735
1736 if (dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001737 pr_err("gs_set_config: NULL device pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 return 0;
1739 }
1740
1741 if (config == dev->dev_config)
1742 return 0;
1743
1744 gs_reset_config(dev);
1745
1746 switch (config) {
1747 case GS_NO_CONFIG_ID:
1748 return 0;
1749 case GS_BULK_CONFIG_ID:
1750 if (use_acm)
1751 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 break;
1753 case GS_ACM_CONFIG_ID:
1754 if (!use_acm)
1755 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 break;
1757 default:
1758 return -EINVAL;
1759 }
1760
1761 dev->dev_config = config;
1762
1763 gadget_for_each_ep(ep, gadget) {
1764
1765 if (EP_NOTIFY_NAME
1766 && strcmp(ep->name, EP_NOTIFY_NAME) == 0) {
David Brownell51a0e852007-08-02 00:02:47 -07001767 ep_desc = choose_ep_desc(gadget,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 &gs_highspeed_notify_desc,
1769 &gs_fullspeed_notify_desc);
1770 ret = usb_ep_enable(ep,ep_desc);
1771 if (ret == 0) {
1772 ep->driver_data = dev;
1773 dev->dev_notify_ep = ep;
1774 dev->dev_notify_ep_desc = ep_desc;
1775 } else {
David Brownell00274922007-11-19 12:58:36 -08001776 pr_err("gs_set_config: cannot enable NOTIFY "
1777 "endpoint %s, ret=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 ep->name, ret);
1779 goto exit_reset_config;
1780 }
1781 }
1782
1783 else if (strcmp(ep->name, EP_IN_NAME) == 0) {
David Brownell51a0e852007-08-02 00:02:47 -07001784 ep_desc = choose_ep_desc(gadget,
1785 &gs_highspeed_in_desc,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 &gs_fullspeed_in_desc);
1787 ret = usb_ep_enable(ep,ep_desc);
1788 if (ret == 0) {
1789 ep->driver_data = dev;
1790 dev->dev_in_ep = ep;
1791 dev->dev_in_ep_desc = ep_desc;
1792 } else {
David Brownell00274922007-11-19 12:58:36 -08001793 pr_err("gs_set_config: cannot enable IN "
1794 "endpoint %s, ret=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 ep->name, ret);
1796 goto exit_reset_config;
1797 }
1798 }
1799
1800 else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
David Brownell51a0e852007-08-02 00:02:47 -07001801 ep_desc = choose_ep_desc(gadget,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 &gs_highspeed_out_desc,
1803 &gs_fullspeed_out_desc);
1804 ret = usb_ep_enable(ep,ep_desc);
1805 if (ret == 0) {
1806 ep->driver_data = dev;
1807 dev->dev_out_ep = ep;
1808 dev->dev_out_ep_desc = ep_desc;
1809 } else {
David Brownell00274922007-11-19 12:58:36 -08001810 pr_err("gs_set_config: cannot enable OUT "
1811 "endpoint %s, ret=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 ep->name, ret);
1813 goto exit_reset_config;
1814 }
1815 }
1816
1817 }
1818
1819 if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL
1820 || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) {
David Brownell00274922007-11-19 12:58:36 -08001821 pr_err("gs_set_config: cannot find endpoints\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 ret = -ENODEV;
1823 goto exit_reset_config;
1824 }
1825
1826 /* allocate and queue read requests */
1827 ep = dev->dev_out_ep;
1828 for (i=0; i<read_q_size && ret == 0; i++) {
1829 if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) {
1830 req->complete = gs_read_complete;
1831 if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
David Brownell00274922007-11-19 12:58:36 -08001832 pr_err("gs_set_config: cannot queue read "
1833 "request, ret=%d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 }
1835 } else {
David Brownell00274922007-11-19 12:58:36 -08001836 pr_err("gs_set_config: cannot allocate "
1837 "read requests\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 ret = -ENOMEM;
1839 goto exit_reset_config;
1840 }
1841 }
1842
1843 /* allocate write requests, and put on free list */
1844 ep = dev->dev_in_ep;
1845 for (i=0; i<write_q_size; i++) {
1846 if ((req_entry=gs_alloc_req_entry(ep, ep->maxpacket, GFP_ATOMIC))) {
1847 req_entry->re_req->complete = gs_write_complete;
1848 list_add(&req_entry->re_entry, &dev->dev_req_list);
1849 } else {
David Brownell00274922007-11-19 12:58:36 -08001850 pr_err("gs_set_config: cannot allocate "
1851 "write requests\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 ret = -ENOMEM;
1853 goto exit_reset_config;
1854 }
1855 }
1856
David Brownellf371e752008-04-18 17:37:49 -07001857 /* REVISIT the ACM mode should be able to actually *issue* some
1858 * notifications, for at least serial state change events if
1859 * not also for network connection; say so in bmCapabilities.
1860 */
1861
David Brownell00274922007-11-19 12:58:36 -08001862 pr_info("gs_set_config: %s configured, %s speed %s config\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 GS_LONG_NAME,
1864 gadget->speed == USB_SPEED_HIGH ? "high" : "full",
1865 config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM");
1866
1867 return 0;
1868
1869exit_reset_config:
1870 gs_reset_config(dev);
1871 return ret;
1872}
1873
1874/*
1875 * gs_reset_config
1876 *
1877 * Mark the device as not configured, disable all endpoints,
1878 * which forces completion of pending I/O and frees queued
1879 * requests, and free the remaining write requests on the
1880 * free list.
1881 *
1882 * The device lock must be held when calling this function.
1883 */
1884static void gs_reset_config(struct gs_dev *dev)
1885{
1886 struct gs_req_entry *req_entry;
1887
1888 if (dev == NULL) {
David Brownell00274922007-11-19 12:58:36 -08001889 pr_err("gs_reset_config: NULL device pointer\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 return;
1891 }
1892
1893 if (dev->dev_config == GS_NO_CONFIG_ID)
1894 return;
1895
1896 dev->dev_config = GS_NO_CONFIG_ID;
1897
1898 /* free write requests on the free list */
1899 while(!list_empty(&dev->dev_req_list)) {
1900 req_entry = list_entry(dev->dev_req_list.next,
1901 struct gs_req_entry, re_entry);
1902 list_del(&req_entry->re_entry);
1903 gs_free_req_entry(dev->dev_in_ep, req_entry);
1904 }
1905
1906 /* disable endpoints, forcing completion of pending i/o; */
1907 /* completion handlers free their requests in this case */
1908 if (dev->dev_notify_ep) {
1909 usb_ep_disable(dev->dev_notify_ep);
1910 dev->dev_notify_ep = NULL;
1911 }
1912 if (dev->dev_in_ep) {
1913 usb_ep_disable(dev->dev_in_ep);
1914 dev->dev_in_ep = NULL;
1915 }
1916 if (dev->dev_out_ep) {
1917 usb_ep_disable(dev->dev_out_ep);
1918 dev->dev_out_ep = NULL;
1919 }
1920}
1921
1922/*
1923 * gs_build_config_buf
1924 *
1925 * Builds the config descriptors in the given buffer and returns the
1926 * length, or a negative error number.
1927 */
David Brownell51a0e852007-08-02 00:02:47 -07001928static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 u8 type, unsigned int index, int is_otg)
1930{
1931 int len;
David Brownell51a0e852007-08-02 00:02:47 -07001932 int high_speed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 const struct usb_config_descriptor *config_desc;
1934 const struct usb_descriptor_header **function;
1935
1936 if (index >= gs_device_desc.bNumConfigurations)
1937 return -EINVAL;
1938
1939 /* other speed switches high and full speed */
David Brownell51a0e852007-08-02 00:02:47 -07001940 if (gadget_is_dualspeed(g)) {
1941 high_speed = (g->speed == USB_SPEED_HIGH);
1942 if (type == USB_DT_OTHER_SPEED_CONFIG)
1943 high_speed = !high_speed;
1944 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945
1946 if (use_acm) {
1947 config_desc = &gs_acm_config_desc;
David Brownell51a0e852007-08-02 00:02:47 -07001948 function = high_speed
1949 ? gs_acm_highspeed_function
1950 : gs_acm_fullspeed_function;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 } else {
1952 config_desc = &gs_bulk_config_desc;
David Brownell51a0e852007-08-02 00:02:47 -07001953 function = high_speed
1954 ? gs_bulk_highspeed_function
1955 : gs_bulk_fullspeed_function;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 }
1957
1958 /* for now, don't advertise srp-only devices */
1959 if (!is_otg)
1960 function++;
1961
1962 len = usb_gadget_config_buf(config_desc, buf, GS_MAX_DESC_LEN, function);
1963 if (len < 0)
1964 return len;
1965
1966 ((struct usb_config_descriptor *)buf)->bDescriptorType = type;
1967
1968 return len;
1969}
1970
1971/*
1972 * gs_alloc_req
1973 *
1974 * Allocate a usb_request and its buffer. Returns a pointer to the
1975 * usb_request or NULL if there is an error.
1976 */
David Brownell1bbc1692005-05-07 13:05:13 -07001977static struct usb_request *
Al Viro55016f12005-10-21 03:21:58 -04001978gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979{
1980 struct usb_request *req;
1981
1982 if (ep == NULL)
1983 return NULL;
1984
1985 req = usb_ep_alloc_request(ep, kmalloc_flags);
1986
1987 if (req != NULL) {
1988 req->length = len;
1989 req->buf = kmalloc(len, kmalloc_flags);
1990 if (req->buf == NULL) {
1991 usb_ep_free_request(ep, req);
1992 return NULL;
1993 }
1994 }
1995
1996 return req;
1997}
1998
1999/*
2000 * gs_free_req
2001 *
2002 * Free a usb_request and its buffer.
2003 */
2004static void gs_free_req(struct usb_ep *ep, struct usb_request *req)
2005{
2006 if (ep != NULL && req != NULL) {
2007 kfree(req->buf);
2008 usb_ep_free_request(ep, req);
2009 }
2010}
2011
2012/*
2013 * gs_alloc_req_entry
2014 *
2015 * Allocates a request and its buffer, using the given
2016 * endpoint, buffer len, and kmalloc flags.
2017 */
David Brownell1bbc1692005-05-07 13:05:13 -07002018static struct gs_req_entry *
Al Viro55016f12005-10-21 03:21:58 -04002019gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020{
2021 struct gs_req_entry *req;
2022
2023 req = kmalloc(sizeof(struct gs_req_entry), kmalloc_flags);
2024 if (req == NULL)
2025 return NULL;
2026
2027 req->re_req = gs_alloc_req(ep, len, kmalloc_flags);
2028 if (req->re_req == NULL) {
2029 kfree(req);
2030 return NULL;
2031 }
2032
2033 req->re_req->context = req;
2034
2035 return req;
2036}
2037
2038/*
2039 * gs_free_req_entry
2040 *
2041 * Frees a request and its buffer.
2042 */
2043static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req)
2044{
2045 if (ep != NULL && req != NULL) {
2046 if (req->re_req != NULL)
2047 gs_free_req(ep, req->re_req);
2048 kfree(req);
2049 }
2050}
2051
2052/*
2053 * gs_alloc_ports
2054 *
2055 * Allocate all ports and set the gs_dev struct to point to them.
2056 * Return 0 if successful, or a negative error number.
2057 *
2058 * The device lock is normally held when calling this function.
2059 */
Al Viro55016f12005-10-21 03:21:58 -04002060static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061{
2062 int i;
2063 struct gs_port *port;
2064
2065 if (dev == NULL)
2066 return -EIO;
2067
2068 for (i=0; i<GS_NUM_PORTS; i++) {
Eric Sesterhenn7039f422006-02-27 13:34:10 -08002069 if ((port=kzalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 return -ENOMEM;
2071
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072 port->port_dev = dev;
2073 port->port_num = i;
2074 port->port_line_coding.dwDTERate = cpu_to_le32(GS_DEFAULT_DTE_RATE);
2075 port->port_line_coding.bCharFormat = GS_DEFAULT_CHAR_FORMAT;
2076 port->port_line_coding.bParityType = GS_DEFAULT_PARITY;
2077 port->port_line_coding.bDataBits = GS_DEFAULT_DATA_BITS;
2078 spin_lock_init(&port->port_lock);
2079 init_waitqueue_head(&port->port_write_wait);
2080
2081 dev->dev_port[i] = port;
2082 }
2083
2084 return 0;
2085}
2086
2087/*
2088 * gs_free_ports
2089 *
2090 * Free all closed ports. Open ports are disconnected by
2091 * freeing their write buffers, setting their device pointers
2092 * and the pointers to them in the device to NULL. These
2093 * ports will be freed when closed.
2094 *
2095 * The device lock is normally held when calling this function.
2096 */
2097static void gs_free_ports(struct gs_dev *dev)
2098{
2099 int i;
2100 unsigned long flags;
2101 struct gs_port *port;
2102
2103 if (dev == NULL)
2104 return;
2105
2106 for (i=0; i<GS_NUM_PORTS; i++) {
2107 if ((port=dev->dev_port[i]) != NULL) {
2108 dev->dev_port[i] = NULL;
2109
2110 spin_lock_irqsave(&port->port_lock, flags);
2111
2112 if (port->port_write_buf != NULL) {
2113 gs_buf_free(port->port_write_buf);
2114 port->port_write_buf = NULL;
2115 }
2116
2117 if (port->port_open_count > 0 || port->port_in_use) {
2118 port->port_dev = NULL;
2119 wake_up_interruptible(&port->port_write_wait);
2120 if (port->port_tty) {
Savin Zlobec42089782008-02-15 13:42:01 +01002121 tty_hangup(port->port_tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 }
2123 spin_unlock_irqrestore(&port->port_lock, flags);
2124 } else {
2125 spin_unlock_irqrestore(&port->port_lock, flags);
2126 kfree(port);
2127 }
2128
2129 }
2130 }
2131}
2132
David Brownell9079e912008-05-07 16:00:36 -07002133/*-------------------------------------------------------------------------*/
2134
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135/* Circular Buffer */
2136
2137/*
2138 * gs_buf_alloc
2139 *
2140 * Allocate a circular buffer and all associated memory.
2141 */
Al Viro55016f12005-10-21 03:21:58 -04002142static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143{
2144 struct gs_buf *gb;
2145
2146 if (size == 0)
2147 return NULL;
2148
Robert P. J. Day5cbded52006-12-13 00:35:56 -08002149 gb = kmalloc(sizeof(struct gs_buf), kmalloc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 if (gb == NULL)
2151 return NULL;
2152
2153 gb->buf_buf = kmalloc(size, kmalloc_flags);
2154 if (gb->buf_buf == NULL) {
2155 kfree(gb);
2156 return NULL;
2157 }
2158
2159 gb->buf_size = size;
2160 gb->buf_get = gb->buf_put = gb->buf_buf;
2161
2162 return gb;
2163}
2164
2165/*
2166 * gs_buf_free
2167 *
2168 * Free the buffer and all associated memory.
2169 */
David Brownellb29dbbd2007-05-25 20:40:31 -07002170static void gs_buf_free(struct gs_buf *gb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171{
Jesper Juhl1bc3c9e2005-04-18 17:39:34 -07002172 if (gb) {
2173 kfree(gb->buf_buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 kfree(gb);
2175 }
2176}
2177
2178/*
2179 * gs_buf_clear
2180 *
2181 * Clear out all data in the circular buffer.
2182 */
David Brownellb29dbbd2007-05-25 20:40:31 -07002183static void gs_buf_clear(struct gs_buf *gb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184{
2185 if (gb != NULL)
2186 gb->buf_get = gb->buf_put;
2187 /* equivalent to a get of all data available */
2188}
2189
2190/*
2191 * gs_buf_data_avail
2192 *
2193 * Return the number of bytes of data available in the circular
2194 * buffer.
2195 */
David Brownellb29dbbd2007-05-25 20:40:31 -07002196static unsigned int gs_buf_data_avail(struct gs_buf *gb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197{
2198 if (gb != NULL)
2199 return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size;
2200 else
2201 return 0;
2202}
2203
2204/*
2205 * gs_buf_space_avail
2206 *
2207 * Return the number of bytes of space available in the circular
2208 * buffer.
2209 */
David Brownellb29dbbd2007-05-25 20:40:31 -07002210static unsigned int gs_buf_space_avail(struct gs_buf *gb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211{
2212 if (gb != NULL)
2213 return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size;
2214 else
2215 return 0;
2216}
2217
2218/*
2219 * gs_buf_put
2220 *
2221 * Copy data data from a user buffer and put it into the circular buffer.
2222 * Restrict to the amount of space available.
2223 *
2224 * Return the number of bytes copied.
2225 */
David Brownellb29dbbd2007-05-25 20:40:31 -07002226static unsigned int
2227gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228{
2229 unsigned int len;
2230
2231 if (gb == NULL)
2232 return 0;
2233
2234 len = gs_buf_space_avail(gb);
2235 if (count > len)
2236 count = len;
2237
2238 if (count == 0)
2239 return 0;
2240
2241 len = gb->buf_buf + gb->buf_size - gb->buf_put;
2242 if (count > len) {
2243 memcpy(gb->buf_put, buf, len);
2244 memcpy(gb->buf_buf, buf+len, count - len);
2245 gb->buf_put = gb->buf_buf + count - len;
2246 } else {
2247 memcpy(gb->buf_put, buf, count);
2248 if (count < len)
2249 gb->buf_put += count;
2250 else /* count == len */
2251 gb->buf_put = gb->buf_buf;
2252 }
2253
2254 return count;
2255}
2256
2257/*
2258 * gs_buf_get
2259 *
2260 * Get data from the circular buffer and copy to the given buffer.
2261 * Restrict to the amount of data available.
2262 *
2263 * Return the number of bytes copied.
2264 */
David Brownellb29dbbd2007-05-25 20:40:31 -07002265static unsigned int
2266gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267{
2268 unsigned int len;
2269
2270 if (gb == NULL)
2271 return 0;
2272
2273 len = gs_buf_data_avail(gb);
2274 if (count > len)
2275 count = len;
2276
2277 if (count == 0)
2278 return 0;
2279
2280 len = gb->buf_buf + gb->buf_size - gb->buf_get;
2281 if (count > len) {
2282 memcpy(buf, gb->buf_get, len);
2283 memcpy(buf+len, gb->buf_buf, count - len);
2284 gb->buf_get = gb->buf_buf + count - len;
2285 } else {
2286 memcpy(buf, gb->buf_get, count);
2287 if (count < len)
2288 gb->buf_get += count;
2289 else /* count == len */
2290 gb->buf_get = gb->buf_buf;
2291 }
2292
2293 return count;
2294}
David Brownell9079e912008-05-07 16:00:36 -07002295
2296/*-------------------------------------------------------------------------*/
2297
2298static struct tty_driver *gs_tty_driver;
2299
2300/*
2301 * gs_module_init
2302 *
2303 * Register as a USB gadget driver and a tty driver.
2304 */
2305static int __init gs_module_init(void)
2306{
2307 int i;
2308 int retval;
2309
2310 retval = usb_gadget_register_driver(&gs_gadget_driver);
2311 if (retval) {
2312 pr_err("gs_module_init: cannot register gadget driver, "
2313 "ret=%d\n", retval);
2314 return retval;
2315 }
2316
2317 gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS);
2318 if (!gs_tty_driver)
2319 return -ENOMEM;
2320 gs_tty_driver->owner = THIS_MODULE;
2321 gs_tty_driver->driver_name = GS_SHORT_NAME;
2322 gs_tty_driver->name = "ttygs";
2323 gs_tty_driver->major = GS_MAJOR;
2324 gs_tty_driver->minor_start = GS_MINOR_START;
2325 gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
2326 gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
2327 gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
2328 gs_tty_driver->init_termios = tty_std_termios;
2329 /* must match GS_DEFAULT_DTE_RATE and friends */
2330 gs_tty_driver->init_termios.c_cflag =
2331 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2332 gs_tty_driver->init_termios.c_ispeed = GS_DEFAULT_DTE_RATE;
2333 gs_tty_driver->init_termios.c_ospeed = GS_DEFAULT_DTE_RATE;
2334 tty_set_operations(gs_tty_driver, &gs_tty_ops);
2335
2336 for (i = 0; i < GS_NUM_PORTS; i++)
2337 mutex_init(&gs_open_close_lock[i]);
2338
2339 retval = tty_register_driver(gs_tty_driver);
2340 if (retval) {
2341 usb_gadget_unregister_driver(&gs_gadget_driver);
2342 put_tty_driver(gs_tty_driver);
2343 pr_err("gs_module_init: cannot register tty driver, "
2344 "ret=%d\n", retval);
2345 return retval;
2346 }
2347
2348 pr_info("gs_module_init: %s %s loaded\n",
2349 GS_LONG_NAME, GS_VERSION_STR);
2350 return 0;
2351}
2352module_init(gs_module_init);
2353
2354/*
2355 * gs_module_exit
2356 *
2357 * Unregister as a tty driver and a USB gadget driver.
2358 */
2359static void __exit gs_module_exit(void)
2360{
2361 tty_unregister_driver(gs_tty_driver);
2362 put_tty_driver(gs_tty_driver);
2363 usb_gadget_unregister_driver(&gs_gadget_driver);
2364
2365 pr_info("gs_module_exit: %s %s unloaded\n",
2366 GS_LONG_NAME, GS_VERSION_STR);
2367}
2368module_exit(gs_module_exit);