| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 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. | 
|  | 17 | * | 
|  | 18 | */ | 
|  | 19 |  | 
|  | 20 | #include <linux/config.h> | 
|  | 21 | #include <linux/module.h> | 
|  | 22 | #include <linux/kernel.h> | 
|  | 23 | #include <linux/delay.h> | 
|  | 24 | #include <linux/ioport.h> | 
|  | 25 | #include <linux/sched.h> | 
|  | 26 | #include <linux/slab.h> | 
|  | 27 | #include <linux/smp_lock.h> | 
|  | 28 | #include <linux/errno.h> | 
|  | 29 | #include <linux/init.h> | 
|  | 30 | #include <linux/timer.h> | 
|  | 31 | #include <linux/list.h> | 
|  | 32 | #include <linux/interrupt.h> | 
|  | 33 | #include <linux/utsname.h> | 
|  | 34 | #include <linux/wait.h> | 
|  | 35 | #include <linux/proc_fs.h> | 
|  | 36 | #include <linux/device.h> | 
|  | 37 | #include <linux/tty.h> | 
|  | 38 | #include <linux/tty_flip.h> | 
|  | 39 |  | 
|  | 40 | #include <asm/byteorder.h> | 
|  | 41 | #include <asm/io.h> | 
|  | 42 | #include <asm/irq.h> | 
|  | 43 | #include <asm/system.h> | 
|  | 44 | #include <asm/unaligned.h> | 
|  | 45 | #include <asm/uaccess.h> | 
|  | 46 |  | 
|  | 47 | #include <linux/usb_ch9.h> | 
|  | 48 | #include <linux/usb_cdc.h> | 
|  | 49 | #include <linux/usb_gadget.h> | 
|  | 50 |  | 
|  | 51 | #include "gadget_chips.h" | 
|  | 52 |  | 
|  | 53 |  | 
|  | 54 | /* Wait Cond */ | 
|  | 55 |  | 
|  | 56 | #define __wait_cond_interruptible(wq, condition, lock, flags, ret)	\ | 
|  | 57 | do {									\ | 
|  | 58 | wait_queue_t __wait;						\ | 
|  | 59 | init_waitqueue_entry(&__wait, current);				\ | 
|  | 60 | \ | 
|  | 61 | add_wait_queue(&wq, &__wait);					\ | 
|  | 62 | for (;;) {							\ | 
|  | 63 | set_current_state(TASK_INTERRUPTIBLE);			\ | 
|  | 64 | if (condition)						\ | 
|  | 65 | break;						\ | 
|  | 66 | if (!signal_pending(current)) {				\ | 
|  | 67 | spin_unlock_irqrestore(lock, flags);		\ | 
|  | 68 | schedule();					\ | 
|  | 69 | spin_lock_irqsave(lock, flags);			\ | 
|  | 70 | continue;					\ | 
|  | 71 | }							\ | 
|  | 72 | ret = -ERESTARTSYS;					\ | 
|  | 73 | break;							\ | 
|  | 74 | }								\ | 
|  | 75 | current->state = TASK_RUNNING;					\ | 
|  | 76 | remove_wait_queue(&wq, &__wait);				\ | 
|  | 77 | } while (0) | 
|  | 78 |  | 
|  | 79 | #define wait_cond_interruptible(wq, condition, lock, flags)		\ | 
|  | 80 | ({									\ | 
|  | 81 | int __ret = 0;							\ | 
|  | 82 | if (!(condition))						\ | 
|  | 83 | __wait_cond_interruptible(wq, condition, lock, flags,	\ | 
|  | 84 | __ret);			\ | 
|  | 85 | __ret;								\ | 
|  | 86 | }) | 
|  | 87 |  | 
|  | 88 | #define __wait_cond_interruptible_timeout(wq, condition, lock, flags, 	\ | 
|  | 89 | timeout, ret)		\ | 
|  | 90 | do {									\ | 
|  | 91 | signed long __timeout = timeout;				\ | 
|  | 92 | wait_queue_t __wait;						\ | 
|  | 93 | init_waitqueue_entry(&__wait, current);				\ | 
|  | 94 | \ | 
|  | 95 | add_wait_queue(&wq, &__wait);					\ | 
|  | 96 | for (;;) {							\ | 
|  | 97 | set_current_state(TASK_INTERRUPTIBLE);			\ | 
|  | 98 | if (__timeout == 0)					\ | 
|  | 99 | break;						\ | 
|  | 100 | if (condition)						\ | 
|  | 101 | break;						\ | 
|  | 102 | if (!signal_pending(current)) {				\ | 
|  | 103 | spin_unlock_irqrestore(lock, flags);		\ | 
|  | 104 | __timeout = schedule_timeout(__timeout);	\ | 
|  | 105 | spin_lock_irqsave(lock, flags);			\ | 
|  | 106 | continue;					\ | 
|  | 107 | }							\ | 
|  | 108 | ret = -ERESTARTSYS;					\ | 
|  | 109 | break;							\ | 
|  | 110 | }								\ | 
|  | 111 | current->state = TASK_RUNNING;					\ | 
|  | 112 | remove_wait_queue(&wq, &__wait);				\ | 
|  | 113 | } while (0) | 
|  | 114 |  | 
|  | 115 | #define wait_cond_interruptible_timeout(wq, condition, lock, flags,	\ | 
|  | 116 | timeout)		\ | 
|  | 117 | ({									\ | 
|  | 118 | int __ret = 0;							\ | 
|  | 119 | if (!(condition))						\ | 
|  | 120 | __wait_cond_interruptible_timeout(wq, condition, lock,	\ | 
|  | 121 | flags, timeout, __ret);	\ | 
|  | 122 | __ret;								\ | 
|  | 123 | }) | 
|  | 124 |  | 
|  | 125 |  | 
|  | 126 | /* Defines */ | 
|  | 127 |  | 
|  | 128 | #define GS_VERSION_STR			"v2.0" | 
|  | 129 | #define GS_VERSION_NUM			0x0200 | 
|  | 130 |  | 
|  | 131 | #define GS_LONG_NAME			"Gadget Serial" | 
|  | 132 | #define GS_SHORT_NAME			"g_serial" | 
|  | 133 |  | 
|  | 134 | #define GS_MAJOR			127 | 
|  | 135 | #define GS_MINOR_START			0 | 
|  | 136 |  | 
|  | 137 | #define GS_NUM_PORTS			16 | 
|  | 138 |  | 
|  | 139 | #define GS_NUM_CONFIGS			1 | 
|  | 140 | #define GS_NO_CONFIG_ID			0 | 
|  | 141 | #define GS_BULK_CONFIG_ID		1 | 
|  | 142 | #define GS_ACM_CONFIG_ID		2 | 
|  | 143 |  | 
|  | 144 | #define GS_MAX_NUM_INTERFACES		2 | 
|  | 145 | #define GS_BULK_INTERFACE_ID		0 | 
|  | 146 | #define GS_CONTROL_INTERFACE_ID		0 | 
|  | 147 | #define GS_DATA_INTERFACE_ID		1 | 
|  | 148 |  | 
|  | 149 | #define GS_MAX_DESC_LEN			256 | 
|  | 150 |  | 
|  | 151 | #define GS_DEFAULT_READ_Q_SIZE		32 | 
|  | 152 | #define GS_DEFAULT_WRITE_Q_SIZE		32 | 
|  | 153 |  | 
|  | 154 | #define GS_DEFAULT_WRITE_BUF_SIZE	8192 | 
|  | 155 | #define GS_TMP_BUF_SIZE			8192 | 
|  | 156 |  | 
|  | 157 | #define GS_CLOSE_TIMEOUT		15 | 
|  | 158 |  | 
|  | 159 | #define GS_DEFAULT_USE_ACM		0 | 
|  | 160 |  | 
|  | 161 | #define GS_DEFAULT_DTE_RATE		9600 | 
|  | 162 | #define GS_DEFAULT_DATA_BITS		8 | 
|  | 163 | #define GS_DEFAULT_PARITY		USB_CDC_NO_PARITY | 
|  | 164 | #define GS_DEFAULT_CHAR_FORMAT		USB_CDC_1_STOP_BITS | 
|  | 165 |  | 
|  | 166 | /* select highspeed/fullspeed, hiding highspeed if not configured */ | 
|  | 167 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 
|  | 168 | #define GS_SPEED_SELECT(is_hs,hs,fs) ((is_hs) ? (hs) : (fs)) | 
|  | 169 | #else | 
|  | 170 | #define GS_SPEED_SELECT(is_hs,hs,fs) (fs) | 
|  | 171 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 
|  | 172 |  | 
|  | 173 | /* debug settings */ | 
|  | 174 | #ifdef GS_DEBUG | 
|  | 175 | static int debug = 1; | 
|  | 176 |  | 
|  | 177 | #define gs_debug(format, arg...) \ | 
|  | 178 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) | 
|  | 179 | #define gs_debug_level(level, format, arg...) \ | 
|  | 180 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) | 
|  | 181 |  | 
|  | 182 | #else | 
|  | 183 |  | 
|  | 184 | #define gs_debug(format, arg...) \ | 
|  | 185 | do { } while(0) | 
|  | 186 | #define gs_debug_level(level, format, arg...) \ | 
|  | 187 | do { } while(0) | 
|  | 188 |  | 
|  | 189 | #endif /* GS_DEBUG */ | 
|  | 190 |  | 
|  | 191 | /* Thanks to NetChip Technologies for donating this product ID. | 
|  | 192 | * | 
|  | 193 | * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!! | 
|  | 194 | * Instead:  allocate your own, using normal USB-IF procedures. | 
|  | 195 | */ | 
|  | 196 | #define GS_VENDOR_ID			0x0525	/* NetChip */ | 
|  | 197 | #define GS_PRODUCT_ID			0xa4a6	/* Linux-USB Serial Gadget */ | 
|  | 198 | #define GS_CDC_PRODUCT_ID		0xa4a7	/* ... as CDC-ACM */ | 
|  | 199 |  | 
|  | 200 | #define GS_LOG2_NOTIFY_INTERVAL		5	/* 1 << 5 == 32 msec */ | 
|  | 201 | #define GS_NOTIFY_MAXPACKET		8 | 
|  | 202 |  | 
|  | 203 |  | 
|  | 204 | /* Structures */ | 
|  | 205 |  | 
|  | 206 | struct gs_dev; | 
|  | 207 |  | 
|  | 208 | /* circular buffer */ | 
|  | 209 | struct gs_buf { | 
|  | 210 | unsigned int		buf_size; | 
|  | 211 | char			*buf_buf; | 
|  | 212 | char			*buf_get; | 
|  | 213 | char			*buf_put; | 
|  | 214 | }; | 
|  | 215 |  | 
|  | 216 | /* list of requests */ | 
|  | 217 | struct gs_req_entry { | 
|  | 218 | struct list_head	re_entry; | 
|  | 219 | struct usb_request	*re_req; | 
|  | 220 | }; | 
|  | 221 |  | 
|  | 222 | /* the port structure holds info for each port, one for each minor number */ | 
|  | 223 | struct gs_port { | 
|  | 224 | struct gs_dev 		*port_dev;	/* pointer to device struct */ | 
|  | 225 | struct tty_struct	*port_tty;	/* pointer to tty struct */ | 
|  | 226 | spinlock_t		port_lock; | 
|  | 227 | int 			port_num; | 
|  | 228 | int			port_open_count; | 
|  | 229 | int			port_in_use;	/* open/close in progress */ | 
|  | 230 | wait_queue_head_t	port_write_wait;/* waiting to write */ | 
|  | 231 | struct gs_buf		*port_write_buf; | 
|  | 232 | struct usb_cdc_line_coding	port_line_coding; | 
|  | 233 | }; | 
|  | 234 |  | 
|  | 235 | /* the device structure holds info for the USB device */ | 
|  | 236 | struct gs_dev { | 
|  | 237 | struct usb_gadget	*dev_gadget;	/* gadget device pointer */ | 
|  | 238 | spinlock_t		dev_lock;	/* lock for set/reset config */ | 
|  | 239 | int			dev_config;	/* configuration number */ | 
|  | 240 | struct usb_ep		*dev_notify_ep;	/* address of notify endpoint */ | 
|  | 241 | struct usb_ep		*dev_in_ep;	/* address of in endpoint */ | 
|  | 242 | struct usb_ep		*dev_out_ep;	/* address of out endpoint */ | 
| Steven Cole | 093cf72 | 2005-05-03 19:07:24 -0600 | [diff] [blame] | 243 | struct usb_endpoint_descriptor		/* descriptor of notify ep */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 244 | *dev_notify_ep_desc; | 
|  | 245 | struct usb_endpoint_descriptor		/* descriptor of in endpoint */ | 
|  | 246 | *dev_in_ep_desc; | 
|  | 247 | struct usb_endpoint_descriptor		/* descriptor of out endpoint */ | 
|  | 248 | *dev_out_ep_desc; | 
|  | 249 | struct usb_request	*dev_ctrl_req;	/* control request */ | 
|  | 250 | struct list_head	dev_req_list;	/* list of write requests */ | 
|  | 251 | int			dev_sched_port;	/* round robin port scheduled */ | 
|  | 252 | struct gs_port		*dev_port[GS_NUM_PORTS]; /* the ports */ | 
|  | 253 | }; | 
|  | 254 |  | 
|  | 255 |  | 
|  | 256 | /* Functions */ | 
|  | 257 |  | 
|  | 258 | /* module */ | 
|  | 259 | static int __init gs_module_init(void); | 
|  | 260 | static void __exit gs_module_exit(void); | 
|  | 261 |  | 
|  | 262 | /* tty driver */ | 
|  | 263 | static int gs_open(struct tty_struct *tty, struct file *file); | 
|  | 264 | static void gs_close(struct tty_struct *tty, struct file *file); | 
|  | 265 | static int gs_write(struct tty_struct *tty, | 
|  | 266 | const unsigned char *buf, int count); | 
|  | 267 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); | 
|  | 268 | static void gs_flush_chars(struct tty_struct *tty); | 
|  | 269 | static int gs_write_room(struct tty_struct *tty); | 
|  | 270 | static int gs_chars_in_buffer(struct tty_struct *tty); | 
|  | 271 | static void gs_throttle(struct tty_struct * tty); | 
|  | 272 | static void gs_unthrottle(struct tty_struct * tty); | 
|  | 273 | static void gs_break(struct tty_struct *tty, int break_state); | 
|  | 274 | static int  gs_ioctl(struct tty_struct *tty, struct file *file, | 
|  | 275 | unsigned int cmd, unsigned long arg); | 
|  | 276 | static void gs_set_termios(struct tty_struct *tty, struct termios *old); | 
|  | 277 |  | 
|  | 278 | static int gs_send(struct gs_dev *dev); | 
|  | 279 | static int gs_send_packet(struct gs_dev *dev, char *packet, | 
|  | 280 | unsigned int size); | 
|  | 281 | static int gs_recv_packet(struct gs_dev *dev, char *packet, | 
|  | 282 | unsigned int size); | 
|  | 283 | static void gs_read_complete(struct usb_ep *ep, struct usb_request *req); | 
|  | 284 | static void gs_write_complete(struct usb_ep *ep, struct usb_request *req); | 
|  | 285 |  | 
|  | 286 | /* gadget driver */ | 
|  | 287 | static int gs_bind(struct usb_gadget *gadget); | 
|  | 288 | static void gs_unbind(struct usb_gadget *gadget); | 
|  | 289 | static int gs_setup(struct usb_gadget *gadget, | 
|  | 290 | const struct usb_ctrlrequest *ctrl); | 
|  | 291 | static int gs_setup_standard(struct usb_gadget *gadget, | 
|  | 292 | const struct usb_ctrlrequest *ctrl); | 
|  | 293 | static int gs_setup_class(struct usb_gadget *gadget, | 
|  | 294 | const struct usb_ctrlrequest *ctrl); | 
|  | 295 | static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); | 
|  | 296 | static void gs_disconnect(struct usb_gadget *gadget); | 
|  | 297 | static int gs_set_config(struct gs_dev *dev, unsigned config); | 
|  | 298 | static void gs_reset_config(struct gs_dev *dev); | 
|  | 299 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 
|  | 300 | u8 type, unsigned int index, int is_otg); | 
|  | 301 |  | 
|  | 302 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 303 | unsigned kmalloc_flags); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 304 | static void gs_free_req(struct usb_ep *ep, struct usb_request *req); | 
|  | 305 |  | 
|  | 306 | static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len, | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 307 | unsigned kmalloc_flags); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 308 | static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req); | 
|  | 309 |  | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 310 | static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 311 | static void gs_free_ports(struct gs_dev *dev); | 
|  | 312 |  | 
|  | 313 | /* circular buffer */ | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 314 | static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 315 | static void gs_buf_free(struct gs_buf *gb); | 
|  | 316 | static void gs_buf_clear(struct gs_buf *gb); | 
|  | 317 | static unsigned int gs_buf_data_avail(struct gs_buf *gb); | 
|  | 318 | static unsigned int gs_buf_space_avail(struct gs_buf *gb); | 
|  | 319 | static unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, | 
|  | 320 | unsigned int count); | 
|  | 321 | static unsigned int gs_buf_get(struct gs_buf *gb, char *buf, | 
|  | 322 | unsigned int count); | 
|  | 323 |  | 
|  | 324 | /* external functions */ | 
|  | 325 | extern int net2280_set_fifo_mode(struct usb_gadget *gadget, int mode); | 
|  | 326 |  | 
|  | 327 |  | 
|  | 328 | /* Globals */ | 
|  | 329 |  | 
|  | 330 | static struct gs_dev *gs_device; | 
|  | 331 |  | 
|  | 332 | static const char *EP_IN_NAME; | 
|  | 333 | static const char *EP_OUT_NAME; | 
|  | 334 | static const char *EP_NOTIFY_NAME; | 
|  | 335 |  | 
|  | 336 | static struct semaphore	gs_open_close_sem[GS_NUM_PORTS]; | 
|  | 337 |  | 
|  | 338 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; | 
|  | 339 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; | 
|  | 340 |  | 
|  | 341 | static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE; | 
|  | 342 |  | 
|  | 343 | static unsigned int use_acm = GS_DEFAULT_USE_ACM; | 
|  | 344 |  | 
|  | 345 |  | 
|  | 346 | /* tty driver struct */ | 
|  | 347 | static struct tty_operations gs_tty_ops = { | 
|  | 348 | .open =			gs_open, | 
|  | 349 | .close =		gs_close, | 
|  | 350 | .write =		gs_write, | 
|  | 351 | .put_char =		gs_put_char, | 
|  | 352 | .flush_chars =		gs_flush_chars, | 
|  | 353 | .write_room =		gs_write_room, | 
|  | 354 | .ioctl =		gs_ioctl, | 
|  | 355 | .set_termios =		gs_set_termios, | 
|  | 356 | .throttle =		gs_throttle, | 
|  | 357 | .unthrottle =		gs_unthrottle, | 
|  | 358 | .break_ctl =		gs_break, | 
|  | 359 | .chars_in_buffer =	gs_chars_in_buffer, | 
|  | 360 | }; | 
|  | 361 | static struct tty_driver *gs_tty_driver; | 
|  | 362 |  | 
|  | 363 | /* gadget driver struct */ | 
|  | 364 | static struct usb_gadget_driver gs_gadget_driver = { | 
|  | 365 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 
|  | 366 | .speed =		USB_SPEED_HIGH, | 
|  | 367 | #else | 
|  | 368 | .speed =		USB_SPEED_FULL, | 
|  | 369 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 
|  | 370 | .function =		GS_LONG_NAME, | 
|  | 371 | .bind =			gs_bind, | 
|  | 372 | .unbind =		gs_unbind, | 
|  | 373 | .setup =		gs_setup, | 
|  | 374 | .disconnect =		gs_disconnect, | 
|  | 375 | .driver = { | 
|  | 376 | .name =		GS_SHORT_NAME, | 
|  | 377 | /* .shutdown = ... */ | 
|  | 378 | /* .suspend = ...  */ | 
|  | 379 | /* .resume = ...   */ | 
|  | 380 | }, | 
|  | 381 | }; | 
|  | 382 |  | 
|  | 383 |  | 
|  | 384 | /* USB descriptors */ | 
|  | 385 |  | 
|  | 386 | #define GS_MANUFACTURER_STR_ID	1 | 
|  | 387 | #define GS_PRODUCT_STR_ID	2 | 
|  | 388 | #define GS_SERIAL_STR_ID	3 | 
|  | 389 | #define GS_BULK_CONFIG_STR_ID	4 | 
|  | 390 | #define GS_ACM_CONFIG_STR_ID	5 | 
|  | 391 | #define GS_CONTROL_STR_ID	6 | 
|  | 392 | #define GS_DATA_STR_ID		7 | 
|  | 393 |  | 
|  | 394 | /* static strings, in UTF-8 */ | 
|  | 395 | static char manufacturer[50]; | 
|  | 396 | static struct usb_string gs_strings[] = { | 
|  | 397 | { GS_MANUFACTURER_STR_ID, manufacturer }, | 
|  | 398 | { GS_PRODUCT_STR_ID, GS_LONG_NAME }, | 
|  | 399 | { GS_SERIAL_STR_ID, "0" }, | 
|  | 400 | { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" }, | 
|  | 401 | { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" }, | 
|  | 402 | { GS_CONTROL_STR_ID, "Gadget Serial Control" }, | 
|  | 403 | { GS_DATA_STR_ID, "Gadget Serial Data" }, | 
|  | 404 | {  } /* end of list */ | 
|  | 405 | }; | 
|  | 406 |  | 
|  | 407 | static struct usb_gadget_strings gs_string_table = { | 
|  | 408 | .language =		0x0409,	/* en-us */ | 
|  | 409 | .strings =		gs_strings, | 
|  | 410 | }; | 
|  | 411 |  | 
|  | 412 | static struct usb_device_descriptor gs_device_desc = { | 
|  | 413 | .bLength =		USB_DT_DEVICE_SIZE, | 
|  | 414 | .bDescriptorType =	USB_DT_DEVICE, | 
|  | 415 | .bcdUSB =		__constant_cpu_to_le16(0x0200), | 
|  | 416 | .bDeviceSubClass =	0, | 
|  | 417 | .bDeviceProtocol =	0, | 
|  | 418 | .idVendor =		__constant_cpu_to_le16(GS_VENDOR_ID), | 
|  | 419 | .idProduct =		__constant_cpu_to_le16(GS_PRODUCT_ID), | 
|  | 420 | .iManufacturer =	GS_MANUFACTURER_STR_ID, | 
|  | 421 | .iProduct =		GS_PRODUCT_STR_ID, | 
|  | 422 | .iSerialNumber =	GS_SERIAL_STR_ID, | 
|  | 423 | .bNumConfigurations =	GS_NUM_CONFIGS, | 
|  | 424 | }; | 
|  | 425 |  | 
|  | 426 | static struct usb_otg_descriptor gs_otg_descriptor = { | 
|  | 427 | .bLength =		sizeof(gs_otg_descriptor), | 
|  | 428 | .bDescriptorType =	USB_DT_OTG, | 
|  | 429 | .bmAttributes =		USB_OTG_SRP, | 
|  | 430 | }; | 
|  | 431 |  | 
|  | 432 | static struct usb_config_descriptor gs_bulk_config_desc = { | 
|  | 433 | .bLength =		USB_DT_CONFIG_SIZE, | 
|  | 434 | .bDescriptorType =	USB_DT_CONFIG, | 
|  | 435 | /* .wTotalLength computed dynamically */ | 
|  | 436 | .bNumInterfaces =	1, | 
|  | 437 | .bConfigurationValue =	GS_BULK_CONFIG_ID, | 
|  | 438 | .iConfiguration =	GS_BULK_CONFIG_STR_ID, | 
|  | 439 | .bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 
|  | 440 | .bMaxPower =		1, | 
|  | 441 | }; | 
|  | 442 |  | 
|  | 443 | static struct usb_config_descriptor gs_acm_config_desc = { | 
|  | 444 | .bLength =		USB_DT_CONFIG_SIZE, | 
|  | 445 | .bDescriptorType =	USB_DT_CONFIG, | 
|  | 446 | /* .wTotalLength computed dynamically */ | 
|  | 447 | .bNumInterfaces =	2, | 
|  | 448 | .bConfigurationValue =	GS_ACM_CONFIG_ID, | 
|  | 449 | .iConfiguration =	GS_ACM_CONFIG_STR_ID, | 
|  | 450 | .bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 
|  | 451 | .bMaxPower =		1, | 
|  | 452 | }; | 
|  | 453 |  | 
|  | 454 | static const struct usb_interface_descriptor gs_bulk_interface_desc = { | 
|  | 455 | .bLength =		USB_DT_INTERFACE_SIZE, | 
|  | 456 | .bDescriptorType =	USB_DT_INTERFACE, | 
|  | 457 | .bInterfaceNumber =	GS_BULK_INTERFACE_ID, | 
|  | 458 | .bNumEndpoints =	2, | 
|  | 459 | .bInterfaceClass =	USB_CLASS_CDC_DATA, | 
|  | 460 | .bInterfaceSubClass =	0, | 
|  | 461 | .bInterfaceProtocol =	0, | 
|  | 462 | .iInterface =		GS_DATA_STR_ID, | 
|  | 463 | }; | 
|  | 464 |  | 
|  | 465 | static const struct usb_interface_descriptor gs_control_interface_desc = { | 
|  | 466 | .bLength =		USB_DT_INTERFACE_SIZE, | 
|  | 467 | .bDescriptorType =	USB_DT_INTERFACE, | 
|  | 468 | .bInterfaceNumber =	GS_CONTROL_INTERFACE_ID, | 
|  | 469 | .bNumEndpoints =	1, | 
|  | 470 | .bInterfaceClass =	USB_CLASS_COMM, | 
|  | 471 | .bInterfaceSubClass =	USB_CDC_SUBCLASS_ACM, | 
|  | 472 | .bInterfaceProtocol =	USB_CDC_ACM_PROTO_AT_V25TER, | 
|  | 473 | .iInterface =		GS_CONTROL_STR_ID, | 
|  | 474 | }; | 
|  | 475 |  | 
|  | 476 | static const struct usb_interface_descriptor gs_data_interface_desc = { | 
|  | 477 | .bLength =		USB_DT_INTERFACE_SIZE, | 
|  | 478 | .bDescriptorType =	USB_DT_INTERFACE, | 
|  | 479 | .bInterfaceNumber =	GS_DATA_INTERFACE_ID, | 
|  | 480 | .bNumEndpoints =	2, | 
|  | 481 | .bInterfaceClass =	USB_CLASS_CDC_DATA, | 
|  | 482 | .bInterfaceSubClass =	0, | 
|  | 483 | .bInterfaceProtocol =	0, | 
|  | 484 | .iInterface =		GS_DATA_STR_ID, | 
|  | 485 | }; | 
|  | 486 |  | 
|  | 487 | static const struct usb_cdc_header_desc gs_header_desc = { | 
|  | 488 | .bLength =		sizeof(gs_header_desc), | 
|  | 489 | .bDescriptorType =	USB_DT_CS_INTERFACE, | 
|  | 490 | .bDescriptorSubType =	USB_CDC_HEADER_TYPE, | 
|  | 491 | .bcdCDC =		__constant_cpu_to_le16(0x0110), | 
|  | 492 | }; | 
|  | 493 |  | 
|  | 494 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { | 
|  | 495 | .bLength =  		sizeof(gs_call_mgmt_descriptor), | 
|  | 496 | .bDescriptorType = 	USB_DT_CS_INTERFACE, | 
|  | 497 | .bDescriptorSubType = 	USB_CDC_CALL_MANAGEMENT_TYPE, | 
|  | 498 | .bmCapabilities = 	0, | 
|  | 499 | .bDataInterface = 	1,	/* index of data interface */ | 
|  | 500 | }; | 
|  | 501 |  | 
|  | 502 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { | 
|  | 503 | .bLength =  		sizeof(gs_acm_descriptor), | 
|  | 504 | .bDescriptorType = 	USB_DT_CS_INTERFACE, | 
|  | 505 | .bDescriptorSubType = 	USB_CDC_ACM_TYPE, | 
|  | 506 | .bmCapabilities = 	0, | 
|  | 507 | }; | 
|  | 508 |  | 
|  | 509 | static const struct usb_cdc_union_desc gs_union_desc = { | 
|  | 510 | .bLength =		sizeof(gs_union_desc), | 
|  | 511 | .bDescriptorType =	USB_DT_CS_INTERFACE, | 
|  | 512 | .bDescriptorSubType =	USB_CDC_UNION_TYPE, | 
|  | 513 | .bMasterInterface0 =	0,	/* index of control interface */ | 
|  | 514 | .bSlaveInterface0 =	1,	/* index of data interface */ | 
|  | 515 | }; | 
|  | 516 |  | 
|  | 517 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { | 
|  | 518 | .bLength =		USB_DT_ENDPOINT_SIZE, | 
|  | 519 | .bDescriptorType =	USB_DT_ENDPOINT, | 
|  | 520 | .bEndpointAddress =	USB_DIR_IN, | 
|  | 521 | .bmAttributes =		USB_ENDPOINT_XFER_INT, | 
|  | 522 | .wMaxPacketSize =	__constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | 
|  | 523 | .bInterval =		1 << GS_LOG2_NOTIFY_INTERVAL, | 
|  | 524 | }; | 
|  | 525 |  | 
|  | 526 | static struct usb_endpoint_descriptor gs_fullspeed_in_desc = { | 
|  | 527 | .bLength =		USB_DT_ENDPOINT_SIZE, | 
|  | 528 | .bDescriptorType =	USB_DT_ENDPOINT, | 
|  | 529 | .bEndpointAddress =	USB_DIR_IN, | 
|  | 530 | .bmAttributes =		USB_ENDPOINT_XFER_BULK, | 
|  | 531 | }; | 
|  | 532 |  | 
|  | 533 | static struct usb_endpoint_descriptor gs_fullspeed_out_desc = { | 
|  | 534 | .bLength =		USB_DT_ENDPOINT_SIZE, | 
|  | 535 | .bDescriptorType =	USB_DT_ENDPOINT, | 
|  | 536 | .bEndpointAddress =	USB_DIR_OUT, | 
|  | 537 | .bmAttributes =		USB_ENDPOINT_XFER_BULK, | 
|  | 538 | }; | 
|  | 539 |  | 
|  | 540 | static const struct usb_descriptor_header *gs_bulk_fullspeed_function[] = { | 
|  | 541 | (struct usb_descriptor_header *) &gs_otg_descriptor, | 
|  | 542 | (struct usb_descriptor_header *) &gs_bulk_interface_desc, | 
|  | 543 | (struct usb_descriptor_header *) &gs_fullspeed_in_desc, | 
|  | 544 | (struct usb_descriptor_header *) &gs_fullspeed_out_desc, | 
|  | 545 | NULL, | 
|  | 546 | }; | 
|  | 547 |  | 
|  | 548 | static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = { | 
|  | 549 | (struct usb_descriptor_header *) &gs_otg_descriptor, | 
|  | 550 | (struct usb_descriptor_header *) &gs_control_interface_desc, | 
|  | 551 | (struct usb_descriptor_header *) &gs_header_desc, | 
|  | 552 | (struct usb_descriptor_header *) &gs_call_mgmt_descriptor, | 
|  | 553 | (struct usb_descriptor_header *) &gs_acm_descriptor, | 
|  | 554 | (struct usb_descriptor_header *) &gs_union_desc, | 
|  | 555 | (struct usb_descriptor_header *) &gs_fullspeed_notify_desc, | 
|  | 556 | (struct usb_descriptor_header *) &gs_data_interface_desc, | 
|  | 557 | (struct usb_descriptor_header *) &gs_fullspeed_in_desc, | 
|  | 558 | (struct usb_descriptor_header *) &gs_fullspeed_out_desc, | 
|  | 559 | NULL, | 
|  | 560 | }; | 
|  | 561 |  | 
|  | 562 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 
|  | 563 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { | 
|  | 564 | .bLength =		USB_DT_ENDPOINT_SIZE, | 
|  | 565 | .bDescriptorType =	USB_DT_ENDPOINT, | 
|  | 566 | .bEndpointAddress =	USB_DIR_IN, | 
|  | 567 | .bmAttributes =		USB_ENDPOINT_XFER_INT, | 
|  | 568 | .wMaxPacketSize =	__constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | 
|  | 569 | .bInterval =		GS_LOG2_NOTIFY_INTERVAL+4, | 
|  | 570 | }; | 
|  | 571 |  | 
|  | 572 | static struct usb_endpoint_descriptor gs_highspeed_in_desc = { | 
|  | 573 | .bLength =		USB_DT_ENDPOINT_SIZE, | 
|  | 574 | .bDescriptorType =	USB_DT_ENDPOINT, | 
|  | 575 | .bmAttributes =		USB_ENDPOINT_XFER_BULK, | 
|  | 576 | .wMaxPacketSize =	__constant_cpu_to_le16(512), | 
|  | 577 | }; | 
|  | 578 |  | 
|  | 579 | static struct usb_endpoint_descriptor gs_highspeed_out_desc = { | 
|  | 580 | .bLength =		USB_DT_ENDPOINT_SIZE, | 
|  | 581 | .bDescriptorType =	USB_DT_ENDPOINT, | 
|  | 582 | .bmAttributes =		USB_ENDPOINT_XFER_BULK, | 
|  | 583 | .wMaxPacketSize =	__constant_cpu_to_le16(512), | 
|  | 584 | }; | 
|  | 585 |  | 
|  | 586 | static struct usb_qualifier_descriptor gs_qualifier_desc = { | 
|  | 587 | .bLength =		sizeof(struct usb_qualifier_descriptor), | 
|  | 588 | .bDescriptorType =	USB_DT_DEVICE_QUALIFIER, | 
|  | 589 | .bcdUSB =		__constant_cpu_to_le16 (0x0200), | 
|  | 590 | /* assumes ep0 uses the same value for both speeds ... */ | 
|  | 591 | .bNumConfigurations =	GS_NUM_CONFIGS, | 
|  | 592 | }; | 
|  | 593 |  | 
|  | 594 | static const struct usb_descriptor_header *gs_bulk_highspeed_function[] = { | 
|  | 595 | (struct usb_descriptor_header *) &gs_otg_descriptor, | 
|  | 596 | (struct usb_descriptor_header *) &gs_bulk_interface_desc, | 
|  | 597 | (struct usb_descriptor_header *) &gs_highspeed_in_desc, | 
|  | 598 | (struct usb_descriptor_header *) &gs_highspeed_out_desc, | 
|  | 599 | NULL, | 
|  | 600 | }; | 
|  | 601 |  | 
|  | 602 | static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { | 
|  | 603 | (struct usb_descriptor_header *) &gs_otg_descriptor, | 
|  | 604 | (struct usb_descriptor_header *) &gs_control_interface_desc, | 
|  | 605 | (struct usb_descriptor_header *) &gs_header_desc, | 
|  | 606 | (struct usb_descriptor_header *) &gs_call_mgmt_descriptor, | 
|  | 607 | (struct usb_descriptor_header *) &gs_acm_descriptor, | 
|  | 608 | (struct usb_descriptor_header *) &gs_union_desc, | 
|  | 609 | (struct usb_descriptor_header *) &gs_highspeed_notify_desc, | 
|  | 610 | (struct usb_descriptor_header *) &gs_data_interface_desc, | 
|  | 611 | (struct usb_descriptor_header *) &gs_highspeed_in_desc, | 
|  | 612 | (struct usb_descriptor_header *) &gs_highspeed_out_desc, | 
|  | 613 | NULL, | 
|  | 614 | }; | 
|  | 615 |  | 
|  | 616 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 
|  | 617 |  | 
|  | 618 |  | 
|  | 619 | /* Module */ | 
|  | 620 | MODULE_DESCRIPTION(GS_LONG_NAME); | 
|  | 621 | MODULE_AUTHOR("Al Borchers"); | 
|  | 622 | MODULE_LICENSE("GPL"); | 
|  | 623 |  | 
|  | 624 | #ifdef GS_DEBUG | 
|  | 625 | module_param(debug, int, S_IRUGO|S_IWUSR); | 
|  | 626 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); | 
|  | 627 | #endif | 
|  | 628 |  | 
|  | 629 | module_param(read_q_size, uint, S_IRUGO); | 
|  | 630 | MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32"); | 
|  | 631 |  | 
|  | 632 | module_param(write_q_size, uint, S_IRUGO); | 
|  | 633 | MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32"); | 
|  | 634 |  | 
|  | 635 | module_param(write_buf_size, uint, S_IRUGO); | 
|  | 636 | MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192"); | 
|  | 637 |  | 
|  | 638 | module_param(use_acm, uint, S_IRUGO); | 
|  | 639 | MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no"); | 
|  | 640 |  | 
|  | 641 | module_init(gs_module_init); | 
|  | 642 | module_exit(gs_module_exit); | 
|  | 643 |  | 
|  | 644 | /* | 
|  | 645 | *  gs_module_init | 
|  | 646 | * | 
|  | 647 | *  Register as a USB gadget driver and a tty driver. | 
|  | 648 | */ | 
|  | 649 | static int __init gs_module_init(void) | 
|  | 650 | { | 
|  | 651 | int i; | 
|  | 652 | int retval; | 
|  | 653 |  | 
|  | 654 | retval = usb_gadget_register_driver(&gs_gadget_driver); | 
|  | 655 | if (retval) { | 
|  | 656 | printk(KERN_ERR "gs_module_init: cannot register gadget driver, ret=%d\n", retval); | 
|  | 657 | return retval; | 
|  | 658 | } | 
|  | 659 |  | 
|  | 660 | gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS); | 
|  | 661 | if (!gs_tty_driver) | 
|  | 662 | return -ENOMEM; | 
|  | 663 | gs_tty_driver->owner = THIS_MODULE; | 
|  | 664 | gs_tty_driver->driver_name = GS_SHORT_NAME; | 
|  | 665 | gs_tty_driver->name = "ttygs"; | 
|  | 666 | gs_tty_driver->devfs_name = "usb/ttygs/"; | 
|  | 667 | gs_tty_driver->major = GS_MAJOR; | 
|  | 668 | gs_tty_driver->minor_start = GS_MINOR_START; | 
|  | 669 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | 
|  | 670 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 
|  | 671 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 
|  | 672 | gs_tty_driver->init_termios = tty_std_termios; | 
|  | 673 | gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 
|  | 674 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | 
|  | 675 |  | 
|  | 676 | for (i=0; i < GS_NUM_PORTS; i++) | 
|  | 677 | sema_init(&gs_open_close_sem[i], 1); | 
|  | 678 |  | 
|  | 679 | retval = tty_register_driver(gs_tty_driver); | 
|  | 680 | if (retval) { | 
|  | 681 | usb_gadget_unregister_driver(&gs_gadget_driver); | 
|  | 682 | put_tty_driver(gs_tty_driver); | 
|  | 683 | printk(KERN_ERR "gs_module_init: cannot register tty driver, ret=%d\n", retval); | 
|  | 684 | return retval; | 
|  | 685 | } | 
|  | 686 |  | 
|  | 687 | printk(KERN_INFO "gs_module_init: %s %s loaded\n", GS_LONG_NAME, GS_VERSION_STR); | 
|  | 688 | return 0; | 
|  | 689 | } | 
|  | 690 |  | 
|  | 691 | /* | 
|  | 692 | * gs_module_exit | 
|  | 693 | * | 
|  | 694 | * Unregister as a tty driver and a USB gadget driver. | 
|  | 695 | */ | 
|  | 696 | static void __exit gs_module_exit(void) | 
|  | 697 | { | 
|  | 698 | tty_unregister_driver(gs_tty_driver); | 
|  | 699 | put_tty_driver(gs_tty_driver); | 
|  | 700 | usb_gadget_unregister_driver(&gs_gadget_driver); | 
|  | 701 |  | 
|  | 702 | printk(KERN_INFO "gs_module_exit: %s %s unloaded\n", GS_LONG_NAME, GS_VERSION_STR); | 
|  | 703 | } | 
|  | 704 |  | 
|  | 705 | /* TTY Driver */ | 
|  | 706 |  | 
|  | 707 | /* | 
|  | 708 | * gs_open | 
|  | 709 | */ | 
|  | 710 | static int gs_open(struct tty_struct *tty, struct file *file) | 
|  | 711 | { | 
|  | 712 | int port_num; | 
|  | 713 | unsigned long flags; | 
|  | 714 | struct gs_port *port; | 
|  | 715 | struct gs_dev *dev; | 
|  | 716 | struct gs_buf *buf; | 
|  | 717 | struct semaphore *sem; | 
|  | 718 | int ret; | 
|  | 719 |  | 
|  | 720 | port_num = tty->index; | 
|  | 721 |  | 
|  | 722 | gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file); | 
|  | 723 |  | 
|  | 724 | if (port_num < 0 || port_num >= GS_NUM_PORTS) { | 
|  | 725 | printk(KERN_ERR "gs_open: (%d,%p,%p) invalid port number\n", | 
|  | 726 | port_num, tty, file); | 
|  | 727 | return -ENODEV; | 
|  | 728 | } | 
|  | 729 |  | 
|  | 730 | dev = gs_device; | 
|  | 731 |  | 
|  | 732 | if (dev == NULL) { | 
|  | 733 | printk(KERN_ERR "gs_open: (%d,%p,%p) NULL device pointer\n", | 
|  | 734 | port_num, tty, file); | 
|  | 735 | return -ENODEV; | 
|  | 736 | } | 
|  | 737 |  | 
|  | 738 | sem = &gs_open_close_sem[port_num]; | 
|  | 739 | if (down_interruptible(sem)) { | 
|  | 740 | printk(KERN_ERR | 
|  | 741 | "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n", | 
|  | 742 | port_num, tty, file); | 
|  | 743 | return -ERESTARTSYS; | 
|  | 744 | } | 
|  | 745 |  | 
|  | 746 | spin_lock_irqsave(&dev->dev_lock, flags); | 
|  | 747 |  | 
|  | 748 | if (dev->dev_config == GS_NO_CONFIG_ID) { | 
|  | 749 | printk(KERN_ERR | 
|  | 750 | "gs_open: (%d,%p,%p) device is not connected\n", | 
|  | 751 | port_num, tty, file); | 
|  | 752 | ret = -ENODEV; | 
|  | 753 | goto exit_unlock_dev; | 
|  | 754 | } | 
|  | 755 |  | 
|  | 756 | port = dev->dev_port[port_num]; | 
|  | 757 |  | 
|  | 758 | if (port == NULL) { | 
|  | 759 | printk(KERN_ERR "gs_open: (%d,%p,%p) NULL port pointer\n", | 
|  | 760 | port_num, tty, file); | 
|  | 761 | ret = -ENODEV; | 
|  | 762 | goto exit_unlock_dev; | 
|  | 763 | } | 
|  | 764 |  | 
|  | 765 | spin_lock(&port->port_lock); | 
|  | 766 | spin_unlock(&dev->dev_lock); | 
|  | 767 |  | 
|  | 768 | if (port->port_dev == NULL) { | 
|  | 769 | printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (1)\n", | 
|  | 770 | port_num, tty, file); | 
|  | 771 | ret = -EIO; | 
|  | 772 | goto exit_unlock_port; | 
|  | 773 | } | 
|  | 774 |  | 
|  | 775 | if (port->port_open_count > 0) { | 
|  | 776 | ++port->port_open_count; | 
|  | 777 | gs_debug("gs_open: (%d,%p,%p) already open\n", | 
|  | 778 | port_num, tty, file); | 
|  | 779 | ret = 0; | 
|  | 780 | goto exit_unlock_port; | 
|  | 781 | } | 
|  | 782 |  | 
|  | 783 | tty->driver_data = NULL; | 
|  | 784 |  | 
|  | 785 | /* mark port as in use, we can drop port lock and sleep if necessary */ | 
|  | 786 | port->port_in_use = 1; | 
|  | 787 |  | 
|  | 788 | /* allocate write buffer on first open */ | 
|  | 789 | if (port->port_write_buf == NULL) { | 
|  | 790 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 791 | buf = gs_buf_alloc(write_buf_size, GFP_KERNEL); | 
|  | 792 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 793 |  | 
|  | 794 | /* might have been disconnected while asleep, check */ | 
|  | 795 | if (port->port_dev == NULL) { | 
|  | 796 | printk(KERN_ERR | 
|  | 797 | "gs_open: (%d,%p,%p) port disconnected (2)\n", | 
|  | 798 | port_num, tty, file); | 
|  | 799 | port->port_in_use = 0; | 
|  | 800 | ret = -EIO; | 
|  | 801 | goto exit_unlock_port; | 
|  | 802 | } | 
|  | 803 |  | 
|  | 804 | if ((port->port_write_buf=buf) == NULL) { | 
|  | 805 | printk(KERN_ERR "gs_open: (%d,%p,%p) cannot allocate port write buffer\n", | 
|  | 806 | port_num, tty, file); | 
|  | 807 | port->port_in_use = 0; | 
|  | 808 | ret = -ENOMEM; | 
|  | 809 | goto exit_unlock_port; | 
|  | 810 | } | 
|  | 811 |  | 
|  | 812 | } | 
|  | 813 |  | 
|  | 814 | /* wait for carrier detect (not implemented) */ | 
|  | 815 |  | 
|  | 816 | /* might have been disconnected while asleep, check */ | 
|  | 817 | if (port->port_dev == NULL) { | 
|  | 818 | printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (3)\n", | 
|  | 819 | port_num, tty, file); | 
|  | 820 | port->port_in_use = 0; | 
|  | 821 | ret = -EIO; | 
|  | 822 | goto exit_unlock_port; | 
|  | 823 | } | 
|  | 824 |  | 
|  | 825 | tty->driver_data = port; | 
|  | 826 | port->port_tty = tty; | 
|  | 827 | port->port_open_count = 1; | 
|  | 828 | port->port_in_use = 0; | 
|  | 829 |  | 
|  | 830 | gs_debug("gs_open: (%d,%p,%p) completed\n", port_num, tty, file); | 
|  | 831 |  | 
|  | 832 | ret = 0; | 
|  | 833 |  | 
|  | 834 | exit_unlock_port: | 
|  | 835 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 836 | up(sem); | 
|  | 837 | return ret; | 
|  | 838 |  | 
|  | 839 | exit_unlock_dev: | 
|  | 840 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 
|  | 841 | up(sem); | 
|  | 842 | return ret; | 
|  | 843 |  | 
|  | 844 | } | 
|  | 845 |  | 
|  | 846 | /* | 
|  | 847 | * gs_close | 
|  | 848 | */ | 
|  | 849 | static void gs_close(struct tty_struct *tty, struct file *file) | 
|  | 850 | { | 
|  | 851 | unsigned long flags; | 
|  | 852 | struct gs_port *port = tty->driver_data; | 
|  | 853 | struct semaphore *sem; | 
|  | 854 |  | 
|  | 855 | if (port == NULL) { | 
|  | 856 | printk(KERN_ERR "gs_close: NULL port pointer\n"); | 
|  | 857 | return; | 
|  | 858 | } | 
|  | 859 |  | 
|  | 860 | gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); | 
|  | 861 |  | 
|  | 862 | sem = &gs_open_close_sem[port->port_num]; | 
|  | 863 | down(sem); | 
|  | 864 |  | 
|  | 865 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 866 |  | 
|  | 867 | if (port->port_open_count == 0) { | 
|  | 868 | printk(KERN_ERR | 
|  | 869 | "gs_close: (%d,%p,%p) port is already closed\n", | 
|  | 870 | port->port_num, tty, file); | 
|  | 871 | goto exit; | 
|  | 872 | } | 
|  | 873 |  | 
|  | 874 | if (port->port_open_count > 1) { | 
|  | 875 | --port->port_open_count; | 
|  | 876 | goto exit; | 
|  | 877 | } | 
|  | 878 |  | 
|  | 879 | /* free disconnected port on final close */ | 
|  | 880 | if (port->port_dev == NULL) { | 
|  | 881 | kfree(port); | 
|  | 882 | goto exit; | 
|  | 883 | } | 
|  | 884 |  | 
|  | 885 | /* mark port as closed but in use, we can drop port lock */ | 
|  | 886 | /* and sleep if necessary */ | 
|  | 887 | port->port_in_use = 1; | 
|  | 888 | port->port_open_count = 0; | 
|  | 889 |  | 
|  | 890 | /* wait for write buffer to drain, or */ | 
|  | 891 | /* at most GS_CLOSE_TIMEOUT seconds */ | 
|  | 892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 
|  | 893 | wait_cond_interruptible_timeout(port->port_write_wait, | 
|  | 894 | port->port_dev == NULL | 
|  | 895 | || gs_buf_data_avail(port->port_write_buf) == 0, | 
|  | 896 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); | 
|  | 897 | } | 
|  | 898 |  | 
|  | 899 | /* free disconnected port on final close */ | 
|  | 900 | /* (might have happened during the above sleep) */ | 
|  | 901 | if (port->port_dev == NULL) { | 
|  | 902 | kfree(port); | 
|  | 903 | goto exit; | 
|  | 904 | } | 
|  | 905 |  | 
|  | 906 | gs_buf_clear(port->port_write_buf); | 
|  | 907 |  | 
|  | 908 | tty->driver_data = NULL; | 
|  | 909 | port->port_tty = NULL; | 
|  | 910 | port->port_in_use = 0; | 
|  | 911 |  | 
|  | 912 | gs_debug("gs_close: (%d,%p,%p) completed\n", | 
|  | 913 | port->port_num, tty, file); | 
|  | 914 |  | 
|  | 915 | exit: | 
|  | 916 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 917 | up(sem); | 
|  | 918 | } | 
|  | 919 |  | 
|  | 920 | /* | 
|  | 921 | * gs_write | 
|  | 922 | */ | 
|  | 923 | static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) | 
|  | 924 | { | 
|  | 925 | unsigned long flags; | 
|  | 926 | struct gs_port *port = tty->driver_data; | 
|  | 927 | int ret; | 
|  | 928 |  | 
|  | 929 | if (port == NULL) { | 
|  | 930 | printk(KERN_ERR "gs_write: NULL port pointer\n"); | 
|  | 931 | return -EIO; | 
|  | 932 | } | 
|  | 933 |  | 
|  | 934 | gs_debug("gs_write: (%d,%p) writing %d bytes\n", port->port_num, tty, | 
|  | 935 | count); | 
|  | 936 |  | 
|  | 937 | if (count == 0) | 
|  | 938 | return 0; | 
|  | 939 |  | 
|  | 940 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 941 |  | 
|  | 942 | if (port->port_dev == NULL) { | 
|  | 943 | printk(KERN_ERR "gs_write: (%d,%p) port is not connected\n", | 
|  | 944 | port->port_num, tty); | 
|  | 945 | ret = -EIO; | 
|  | 946 | goto exit; | 
|  | 947 | } | 
|  | 948 |  | 
|  | 949 | if (port->port_open_count == 0) { | 
|  | 950 | printk(KERN_ERR "gs_write: (%d,%p) port is closed\n", | 
|  | 951 | port->port_num, tty); | 
|  | 952 | ret = -EBADF; | 
|  | 953 | goto exit; | 
|  | 954 | } | 
|  | 955 |  | 
|  | 956 | count = gs_buf_put(port->port_write_buf, buf, count); | 
|  | 957 |  | 
|  | 958 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 959 |  | 
|  | 960 | gs_send(gs_device); | 
|  | 961 |  | 
|  | 962 | gs_debug("gs_write: (%d,%p) wrote %d bytes\n", port->port_num, tty, | 
|  | 963 | count); | 
|  | 964 |  | 
|  | 965 | return count; | 
|  | 966 |  | 
|  | 967 | exit: | 
|  | 968 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 969 | return ret; | 
|  | 970 | } | 
|  | 971 |  | 
|  | 972 | /* | 
|  | 973 | * gs_put_char | 
|  | 974 | */ | 
|  | 975 | static void gs_put_char(struct tty_struct *tty, unsigned char ch) | 
|  | 976 | { | 
|  | 977 | unsigned long flags; | 
|  | 978 | struct gs_port *port = tty->driver_data; | 
|  | 979 |  | 
|  | 980 | if (port == NULL) { | 
|  | 981 | printk(KERN_ERR "gs_put_char: NULL port pointer\n"); | 
|  | 982 | return; | 
|  | 983 | } | 
|  | 984 |  | 
|  | 985 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); | 
|  | 986 |  | 
|  | 987 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 988 |  | 
|  | 989 | if (port->port_dev == NULL) { | 
|  | 990 | printk(KERN_ERR "gs_put_char: (%d,%p) port is not connected\n", | 
|  | 991 | port->port_num, tty); | 
|  | 992 | goto exit; | 
|  | 993 | } | 
|  | 994 |  | 
|  | 995 | if (port->port_open_count == 0) { | 
|  | 996 | printk(KERN_ERR "gs_put_char: (%d,%p) port is closed\n", | 
|  | 997 | port->port_num, tty); | 
|  | 998 | goto exit; | 
|  | 999 | } | 
|  | 1000 |  | 
|  | 1001 | gs_buf_put(port->port_write_buf, &ch, 1); | 
|  | 1002 |  | 
|  | 1003 | exit: | 
|  | 1004 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 1005 | } | 
|  | 1006 |  | 
|  | 1007 | /* | 
|  | 1008 | * gs_flush_chars | 
|  | 1009 | */ | 
|  | 1010 | static void gs_flush_chars(struct tty_struct *tty) | 
|  | 1011 | { | 
|  | 1012 | unsigned long flags; | 
|  | 1013 | struct gs_port *port = tty->driver_data; | 
|  | 1014 |  | 
|  | 1015 | if (port == NULL) { | 
|  | 1016 | printk(KERN_ERR "gs_flush_chars: NULL port pointer\n"); | 
|  | 1017 | return; | 
|  | 1018 | } | 
|  | 1019 |  | 
|  | 1020 | gs_debug("gs_flush_chars: (%d,%p)\n", port->port_num, tty); | 
|  | 1021 |  | 
|  | 1022 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 1023 |  | 
|  | 1024 | if (port->port_dev == NULL) { | 
|  | 1025 | printk(KERN_ERR | 
|  | 1026 | "gs_flush_chars: (%d,%p) port is not connected\n", | 
|  | 1027 | port->port_num, tty); | 
|  | 1028 | goto exit; | 
|  | 1029 | } | 
|  | 1030 |  | 
|  | 1031 | if (port->port_open_count == 0) { | 
|  | 1032 | printk(KERN_ERR "gs_flush_chars: (%d,%p) port is closed\n", | 
|  | 1033 | port->port_num, tty); | 
|  | 1034 | goto exit; | 
|  | 1035 | } | 
|  | 1036 |  | 
|  | 1037 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 1038 |  | 
|  | 1039 | gs_send(gs_device); | 
|  | 1040 |  | 
|  | 1041 | return; | 
|  | 1042 |  | 
|  | 1043 | exit: | 
|  | 1044 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 1045 | } | 
|  | 1046 |  | 
|  | 1047 | /* | 
|  | 1048 | * gs_write_room | 
|  | 1049 | */ | 
|  | 1050 | static int gs_write_room(struct tty_struct *tty) | 
|  | 1051 | { | 
|  | 1052 |  | 
|  | 1053 | int room = 0; | 
|  | 1054 | unsigned long flags; | 
|  | 1055 | struct gs_port *port = tty->driver_data; | 
|  | 1056 |  | 
|  | 1057 |  | 
|  | 1058 | if (port == NULL) | 
|  | 1059 | return 0; | 
|  | 1060 |  | 
|  | 1061 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 1062 |  | 
|  | 1063 | if (port->port_dev != NULL && port->port_open_count > 0 | 
|  | 1064 | && port->port_write_buf != NULL) | 
|  | 1065 | room = gs_buf_space_avail(port->port_write_buf); | 
|  | 1066 |  | 
|  | 1067 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 1068 |  | 
|  | 1069 | gs_debug("gs_write_room: (%d,%p) room=%d\n", | 
|  | 1070 | port->port_num, tty, room); | 
|  | 1071 |  | 
|  | 1072 | return room; | 
|  | 1073 | } | 
|  | 1074 |  | 
|  | 1075 | /* | 
|  | 1076 | * gs_chars_in_buffer | 
|  | 1077 | */ | 
|  | 1078 | static int gs_chars_in_buffer(struct tty_struct *tty) | 
|  | 1079 | { | 
|  | 1080 | int chars = 0; | 
|  | 1081 | unsigned long flags; | 
|  | 1082 | struct gs_port *port = tty->driver_data; | 
|  | 1083 |  | 
|  | 1084 | if (port == NULL) | 
|  | 1085 | return 0; | 
|  | 1086 |  | 
|  | 1087 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 1088 |  | 
|  | 1089 | if (port->port_dev != NULL && port->port_open_count > 0 | 
|  | 1090 | && port->port_write_buf != NULL) | 
|  | 1091 | chars = gs_buf_data_avail(port->port_write_buf); | 
|  | 1092 |  | 
|  | 1093 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 1094 |  | 
|  | 1095 | gs_debug("gs_chars_in_buffer: (%d,%p) chars=%d\n", | 
|  | 1096 | port->port_num, tty, chars); | 
|  | 1097 |  | 
|  | 1098 | return chars; | 
|  | 1099 | } | 
|  | 1100 |  | 
|  | 1101 | /* | 
|  | 1102 | * gs_throttle | 
|  | 1103 | */ | 
|  | 1104 | static void gs_throttle(struct tty_struct *tty) | 
|  | 1105 | { | 
|  | 1106 | } | 
|  | 1107 |  | 
|  | 1108 | /* | 
|  | 1109 | * gs_unthrottle | 
|  | 1110 | */ | 
|  | 1111 | static void gs_unthrottle(struct tty_struct *tty) | 
|  | 1112 | { | 
|  | 1113 | } | 
|  | 1114 |  | 
|  | 1115 | /* | 
|  | 1116 | * gs_break | 
|  | 1117 | */ | 
|  | 1118 | static void gs_break(struct tty_struct *tty, int break_state) | 
|  | 1119 | { | 
|  | 1120 | } | 
|  | 1121 |  | 
|  | 1122 | /* | 
|  | 1123 | * gs_ioctl | 
|  | 1124 | */ | 
|  | 1125 | static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) | 
|  | 1126 | { | 
|  | 1127 | struct gs_port *port = tty->driver_data; | 
|  | 1128 |  | 
|  | 1129 | if (port == NULL) { | 
|  | 1130 | printk(KERN_ERR "gs_ioctl: NULL port pointer\n"); | 
|  | 1131 | return -EIO; | 
|  | 1132 | } | 
|  | 1133 |  | 
|  | 1134 | gs_debug("gs_ioctl: (%d,%p,%p) cmd=0x%4.4x, arg=%lu\n", | 
|  | 1135 | port->port_num, tty, file, cmd, arg); | 
|  | 1136 |  | 
|  | 1137 | /* handle ioctls */ | 
|  | 1138 |  | 
|  | 1139 | /* could not handle ioctl */ | 
|  | 1140 | return -ENOIOCTLCMD; | 
|  | 1141 | } | 
|  | 1142 |  | 
|  | 1143 | /* | 
|  | 1144 | * gs_set_termios | 
|  | 1145 | */ | 
|  | 1146 | static void gs_set_termios(struct tty_struct *tty, struct termios *old) | 
|  | 1147 | { | 
|  | 1148 | } | 
|  | 1149 |  | 
|  | 1150 | /* | 
|  | 1151 | * gs_send | 
|  | 1152 | * | 
|  | 1153 | * This function finds available write requests, calls | 
|  | 1154 | * gs_send_packet to fill these packets with data, and | 
|  | 1155 | * continues until either there are no more write requests | 
|  | 1156 | * available or no more data to send.  This function is | 
|  | 1157 | * run whenever data arrives or write requests are available. | 
|  | 1158 | */ | 
|  | 1159 | static int gs_send(struct gs_dev *dev) | 
|  | 1160 | { | 
|  | 1161 | int ret,len; | 
|  | 1162 | unsigned long flags; | 
|  | 1163 | struct usb_ep *ep; | 
|  | 1164 | struct usb_request *req; | 
|  | 1165 | struct gs_req_entry *req_entry; | 
|  | 1166 |  | 
|  | 1167 | if (dev == NULL) { | 
|  | 1168 | printk(KERN_ERR "gs_send: NULL device pointer\n"); | 
|  | 1169 | return -ENODEV; | 
|  | 1170 | } | 
|  | 1171 |  | 
|  | 1172 | spin_lock_irqsave(&dev->dev_lock, flags); | 
|  | 1173 |  | 
|  | 1174 | ep = dev->dev_in_ep; | 
|  | 1175 |  | 
|  | 1176 | while(!list_empty(&dev->dev_req_list)) { | 
|  | 1177 |  | 
|  | 1178 | req_entry = list_entry(dev->dev_req_list.next, | 
|  | 1179 | struct gs_req_entry, re_entry); | 
|  | 1180 |  | 
|  | 1181 | req = req_entry->re_req; | 
|  | 1182 |  | 
|  | 1183 | len = gs_send_packet(dev, req->buf, ep->maxpacket); | 
|  | 1184 |  | 
|  | 1185 | if (len > 0) { | 
|  | 1186 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); | 
|  | 1187 | list_del(&req_entry->re_entry); | 
|  | 1188 | req->length = len; | 
|  | 1189 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 
|  | 1190 | printk(KERN_ERR | 
|  | 1191 | "gs_send: cannot queue read request, ret=%d\n", | 
|  | 1192 | ret); | 
|  | 1193 | break; | 
|  | 1194 | } | 
|  | 1195 | } else { | 
|  | 1196 | break; | 
|  | 1197 | } | 
|  | 1198 |  | 
|  | 1199 | } | 
|  | 1200 |  | 
|  | 1201 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 
|  | 1202 |  | 
|  | 1203 | return 0; | 
|  | 1204 | } | 
|  | 1205 |  | 
|  | 1206 | /* | 
|  | 1207 | * gs_send_packet | 
|  | 1208 | * | 
|  | 1209 | * If there is data to send, a packet is built in the given | 
|  | 1210 | * buffer and the size is returned.  If there is no data to | 
|  | 1211 | * send, 0 is returned.  If there is any error a negative | 
|  | 1212 | * error number is returned. | 
|  | 1213 | * | 
|  | 1214 | * Called during USB completion routine, on interrupt time. | 
|  | 1215 | * | 
|  | 1216 | * We assume that disconnect will not happen until all completion | 
|  | 1217 | * routines have completed, so we can assume that the dev_port | 
|  | 1218 | * array does not change during the lifetime of this function. | 
|  | 1219 | */ | 
|  | 1220 | static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size) | 
|  | 1221 | { | 
|  | 1222 | unsigned int len; | 
|  | 1223 | struct gs_port *port; | 
|  | 1224 |  | 
|  | 1225 | /* TEMPORARY -- only port 0 is supported right now */ | 
|  | 1226 | port = dev->dev_port[0]; | 
|  | 1227 |  | 
|  | 1228 | if (port == NULL) { | 
|  | 1229 | printk(KERN_ERR | 
|  | 1230 | "gs_send_packet: port=%d, NULL port pointer\n", | 
|  | 1231 | 0); | 
|  | 1232 | return -EIO; | 
|  | 1233 | } | 
|  | 1234 |  | 
|  | 1235 | spin_lock(&port->port_lock); | 
|  | 1236 |  | 
|  | 1237 | len = gs_buf_data_avail(port->port_write_buf); | 
|  | 1238 | if (len < size) | 
|  | 1239 | size = len; | 
|  | 1240 |  | 
|  | 1241 | if (size == 0) | 
|  | 1242 | goto exit; | 
|  | 1243 |  | 
|  | 1244 | size = gs_buf_get(port->port_write_buf, packet, size); | 
|  | 1245 |  | 
|  | 1246 | if (port->port_tty) | 
|  | 1247 | wake_up_interruptible(&port->port_tty->write_wait); | 
|  | 1248 |  | 
|  | 1249 | exit: | 
|  | 1250 | spin_unlock(&port->port_lock); | 
|  | 1251 | return size; | 
|  | 1252 | } | 
|  | 1253 |  | 
|  | 1254 | /* | 
|  | 1255 | * gs_recv_packet | 
|  | 1256 | * | 
|  | 1257 | * Called for each USB packet received.  Reads the packet | 
|  | 1258 | * header and stuffs the data in the appropriate tty buffer. | 
|  | 1259 | * Returns 0 if successful, or a negative error number. | 
|  | 1260 | * | 
|  | 1261 | * Called during USB completion routine, on interrupt time. | 
|  | 1262 | * | 
|  | 1263 | * We assume that disconnect will not happen until all completion | 
|  | 1264 | * routines have completed, so we can assume that the dev_port | 
|  | 1265 | * array does not change during the lifetime of this function. | 
|  | 1266 | */ | 
|  | 1267 | static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | 
|  | 1268 | { | 
|  | 1269 | unsigned int len; | 
|  | 1270 | struct gs_port *port; | 
|  | 1271 | int ret; | 
|  | 1272 |  | 
|  | 1273 | /* TEMPORARY -- only port 0 is supported right now */ | 
|  | 1274 | port = dev->dev_port[0]; | 
|  | 1275 |  | 
|  | 1276 | if (port == NULL) { | 
|  | 1277 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL port pointer\n", | 
|  | 1278 | port->port_num); | 
|  | 1279 | return -EIO; | 
|  | 1280 | } | 
|  | 1281 |  | 
|  | 1282 | spin_lock(&port->port_lock); | 
|  | 1283 |  | 
|  | 1284 | if (port->port_open_count == 0) { | 
|  | 1285 | printk(KERN_ERR "gs_recv_packet: port=%d, port is closed\n", | 
|  | 1286 | port->port_num); | 
|  | 1287 | ret = -EIO; | 
|  | 1288 | goto exit; | 
|  | 1289 | } | 
|  | 1290 |  | 
|  | 1291 | if (port->port_tty == NULL) { | 
|  | 1292 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", | 
|  | 1293 | port->port_num); | 
|  | 1294 | ret = -EIO; | 
|  | 1295 | goto exit; | 
|  | 1296 | } | 
|  | 1297 |  | 
|  | 1298 | if (port->port_tty->magic != TTY_MAGIC) { | 
|  | 1299 | printk(KERN_ERR "gs_recv_packet: port=%d, bad tty magic\n", | 
|  | 1300 | port->port_num); | 
|  | 1301 | ret = -EIO; | 
|  | 1302 | goto exit; | 
|  | 1303 | } | 
|  | 1304 |  | 
|  | 1305 | len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count); | 
|  | 1306 | if (len < size) | 
|  | 1307 | size = len; | 
|  | 1308 |  | 
|  | 1309 | if (size > 0) { | 
|  | 1310 | memcpy(port->port_tty->flip.char_buf_ptr, packet, size); | 
|  | 1311 | port->port_tty->flip.char_buf_ptr += size; | 
|  | 1312 | port->port_tty->flip.count += size; | 
|  | 1313 | tty_flip_buffer_push(port->port_tty); | 
|  | 1314 | wake_up_interruptible(&port->port_tty->read_wait); | 
|  | 1315 | } | 
|  | 1316 |  | 
|  | 1317 | ret = 0; | 
|  | 1318 |  | 
|  | 1319 | exit: | 
|  | 1320 | spin_unlock(&port->port_lock); | 
|  | 1321 | return ret; | 
|  | 1322 | } | 
|  | 1323 |  | 
|  | 1324 | /* | 
|  | 1325 | * gs_read_complete | 
|  | 1326 | */ | 
|  | 1327 | static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) | 
|  | 1328 | { | 
|  | 1329 | int ret; | 
|  | 1330 | struct gs_dev *dev = ep->driver_data; | 
|  | 1331 |  | 
|  | 1332 | if (dev == NULL) { | 
|  | 1333 | printk(KERN_ERR "gs_read_complete: NULL device pointer\n"); | 
|  | 1334 | return; | 
|  | 1335 | } | 
|  | 1336 |  | 
|  | 1337 | switch(req->status) { | 
|  | 1338 | case 0: | 
|  | 1339 | /* normal completion */ | 
|  | 1340 | gs_recv_packet(dev, req->buf, req->actual); | 
|  | 1341 | requeue: | 
|  | 1342 | req->length = ep->maxpacket; | 
|  | 1343 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 
|  | 1344 | printk(KERN_ERR | 
|  | 1345 | "gs_read_complete: cannot queue read request, ret=%d\n", | 
|  | 1346 | ret); | 
|  | 1347 | } | 
|  | 1348 | break; | 
|  | 1349 |  | 
|  | 1350 | case -ESHUTDOWN: | 
|  | 1351 | /* disconnect */ | 
|  | 1352 | gs_debug("gs_read_complete: shutdown\n"); | 
|  | 1353 | gs_free_req(ep, req); | 
|  | 1354 | break; | 
|  | 1355 |  | 
|  | 1356 | default: | 
|  | 1357 | /* unexpected */ | 
|  | 1358 | printk(KERN_ERR | 
|  | 1359 | "gs_read_complete: unexpected status error, status=%d\n", | 
|  | 1360 | req->status); | 
|  | 1361 | goto requeue; | 
|  | 1362 | break; | 
|  | 1363 | } | 
|  | 1364 | } | 
|  | 1365 |  | 
|  | 1366 | /* | 
|  | 1367 | * gs_write_complete | 
|  | 1368 | */ | 
|  | 1369 | static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) | 
|  | 1370 | { | 
|  | 1371 | struct gs_dev *dev = ep->driver_data; | 
|  | 1372 | struct gs_req_entry *gs_req = req->context; | 
|  | 1373 |  | 
|  | 1374 | if (dev == NULL) { | 
|  | 1375 | printk(KERN_ERR "gs_write_complete: NULL device pointer\n"); | 
|  | 1376 | return; | 
|  | 1377 | } | 
|  | 1378 |  | 
|  | 1379 | switch(req->status) { | 
|  | 1380 | case 0: | 
|  | 1381 | /* normal completion */ | 
|  | 1382 | requeue: | 
|  | 1383 | if (gs_req == NULL) { | 
|  | 1384 | printk(KERN_ERR | 
|  | 1385 | "gs_write_complete: NULL request pointer\n"); | 
|  | 1386 | return; | 
|  | 1387 | } | 
|  | 1388 |  | 
|  | 1389 | spin_lock(&dev->dev_lock); | 
|  | 1390 | list_add(&gs_req->re_entry, &dev->dev_req_list); | 
|  | 1391 | spin_unlock(&dev->dev_lock); | 
|  | 1392 |  | 
|  | 1393 | gs_send(dev); | 
|  | 1394 |  | 
|  | 1395 | break; | 
|  | 1396 |  | 
|  | 1397 | case -ESHUTDOWN: | 
|  | 1398 | /* disconnect */ | 
|  | 1399 | gs_debug("gs_write_complete: shutdown\n"); | 
|  | 1400 | gs_free_req(ep, req); | 
|  | 1401 | break; | 
|  | 1402 |  | 
|  | 1403 | default: | 
|  | 1404 | printk(KERN_ERR | 
|  | 1405 | "gs_write_complete: unexpected status error, status=%d\n", | 
|  | 1406 | req->status); | 
|  | 1407 | goto requeue; | 
|  | 1408 | break; | 
|  | 1409 | } | 
|  | 1410 | } | 
|  | 1411 |  | 
|  | 1412 | /* Gadget Driver */ | 
|  | 1413 |  | 
|  | 1414 | /* | 
|  | 1415 | * gs_bind | 
|  | 1416 | * | 
|  | 1417 | * Called on module load.  Allocates and initializes the device | 
|  | 1418 | * structure and a control request. | 
|  | 1419 | */ | 
|  | 1420 | static int gs_bind(struct usb_gadget *gadget) | 
|  | 1421 | { | 
|  | 1422 | int ret; | 
|  | 1423 | struct usb_ep *ep; | 
|  | 1424 | struct gs_dev *dev; | 
|  | 1425 |  | 
|  | 1426 | /* device specific */ | 
|  | 1427 | if (gadget_is_net2280(gadget)) { | 
|  | 1428 | gs_device_desc.bcdDevice = | 
|  | 1429 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0001); | 
|  | 1430 | } else if (gadget_is_pxa(gadget)) { | 
|  | 1431 | gs_device_desc.bcdDevice = | 
|  | 1432 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0002); | 
|  | 1433 | } else if (gadget_is_sh(gadget)) { | 
|  | 1434 | gs_device_desc.bcdDevice = | 
|  | 1435 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0003); | 
|  | 1436 | /* sh doesn't support multiple interfaces or configs */ | 
|  | 1437 | use_acm = 0; | 
|  | 1438 | } else if (gadget_is_sa1100(gadget)) { | 
|  | 1439 | gs_device_desc.bcdDevice = | 
|  | 1440 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0004); | 
|  | 1441 | /* sa1100 doesn't support necessary endpoints */ | 
|  | 1442 | use_acm = 0; | 
|  | 1443 | } else if (gadget_is_goku(gadget)) { | 
|  | 1444 | gs_device_desc.bcdDevice = | 
|  | 1445 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0005); | 
|  | 1446 | } else if (gadget_is_mq11xx(gadget)) { | 
|  | 1447 | gs_device_desc.bcdDevice = | 
|  | 1448 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0006); | 
|  | 1449 | } else if (gadget_is_omap(gadget)) { | 
|  | 1450 | gs_device_desc.bcdDevice = | 
|  | 1451 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0007); | 
|  | 1452 | } else if (gadget_is_lh7a40x(gadget)) { | 
|  | 1453 | gs_device_desc.bcdDevice = | 
|  | 1454 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0008); | 
|  | 1455 | } else if (gadget_is_n9604(gadget)) { | 
|  | 1456 | gs_device_desc.bcdDevice = | 
|  | 1457 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0009); | 
|  | 1458 | } else if (gadget_is_pxa27x(gadget)) { | 
|  | 1459 | gs_device_desc.bcdDevice = | 
|  | 1460 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0011); | 
|  | 1461 | } else if (gadget_is_s3c2410(gadget)) { | 
|  | 1462 | gs_device_desc.bcdDevice = | 
|  | 1463 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0012); | 
|  | 1464 | } else if (gadget_is_at91(gadget)) { | 
|  | 1465 | gs_device_desc.bcdDevice = | 
|  | 1466 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0013); | 
|  | 1467 | } else { | 
|  | 1468 | printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n", | 
|  | 1469 | gadget->name); | 
|  | 1470 | /* unrecognized, but safe unless bulk is REALLY quirky */ | 
|  | 1471 | gs_device_desc.bcdDevice = | 
|  | 1472 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); | 
|  | 1473 | } | 
|  | 1474 |  | 
|  | 1475 | usb_ep_autoconfig_reset(gadget); | 
|  | 1476 |  | 
|  | 1477 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); | 
|  | 1478 | if (!ep) | 
|  | 1479 | goto autoconf_fail; | 
|  | 1480 | EP_IN_NAME = ep->name; | 
|  | 1481 | ep->driver_data = ep;	/* claim the endpoint */ | 
|  | 1482 |  | 
|  | 1483 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); | 
|  | 1484 | if (!ep) | 
|  | 1485 | goto autoconf_fail; | 
|  | 1486 | EP_OUT_NAME = ep->name; | 
|  | 1487 | ep->driver_data = ep;	/* claim the endpoint */ | 
|  | 1488 |  | 
|  | 1489 | if (use_acm) { | 
|  | 1490 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); | 
|  | 1491 | if (!ep) { | 
|  | 1492 | printk(KERN_ERR "gs_bind: cannot run ACM on %s\n", gadget->name); | 
|  | 1493 | goto autoconf_fail; | 
|  | 1494 | } | 
|  | 1495 | gs_device_desc.idProduct = __constant_cpu_to_le16( | 
|  | 1496 | GS_CDC_PRODUCT_ID), | 
|  | 1497 | EP_NOTIFY_NAME = ep->name; | 
|  | 1498 | ep->driver_data = ep;	/* claim the endpoint */ | 
|  | 1499 | } | 
|  | 1500 |  | 
|  | 1501 | gs_device_desc.bDeviceClass = use_acm | 
|  | 1502 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 
|  | 1503 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 
|  | 1504 |  | 
|  | 1505 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 
|  | 1506 | gs_qualifier_desc.bDeviceClass = use_acm | 
|  | 1507 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 
|  | 1508 | /* assume ep0 uses the same packet size for both speeds */ | 
|  | 1509 | gs_qualifier_desc.bMaxPacketSize0 = gs_device_desc.bMaxPacketSize0; | 
|  | 1510 | /* assume endpoints are dual-speed */ | 
|  | 1511 | gs_highspeed_notify_desc.bEndpointAddress = | 
|  | 1512 | gs_fullspeed_notify_desc.bEndpointAddress; | 
|  | 1513 | gs_highspeed_in_desc.bEndpointAddress = | 
|  | 1514 | gs_fullspeed_in_desc.bEndpointAddress; | 
|  | 1515 | gs_highspeed_out_desc.bEndpointAddress = | 
|  | 1516 | gs_fullspeed_out_desc.bEndpointAddress; | 
|  | 1517 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 
|  | 1518 |  | 
|  | 1519 | usb_gadget_set_selfpowered(gadget); | 
|  | 1520 |  | 
|  | 1521 | if (gadget->is_otg) { | 
|  | 1522 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, | 
|  | 1523 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 
|  | 1524 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 
|  | 1525 | } | 
|  | 1526 |  | 
|  | 1527 | gs_device = dev = kmalloc(sizeof(struct gs_dev), GFP_KERNEL); | 
|  | 1528 | if (dev == NULL) | 
|  | 1529 | return -ENOMEM; | 
|  | 1530 |  | 
|  | 1531 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | 
|  | 1532 | system_utsname.sysname, system_utsname.release, | 
|  | 1533 | gadget->name); | 
|  | 1534 |  | 
|  | 1535 | memset(dev, 0, sizeof(struct gs_dev)); | 
|  | 1536 | dev->dev_gadget = gadget; | 
|  | 1537 | spin_lock_init(&dev->dev_lock); | 
|  | 1538 | INIT_LIST_HEAD(&dev->dev_req_list); | 
|  | 1539 | set_gadget_data(gadget, dev); | 
|  | 1540 |  | 
|  | 1541 | if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) { | 
|  | 1542 | printk(KERN_ERR "gs_bind: cannot allocate ports\n"); | 
|  | 1543 | gs_unbind(gadget); | 
|  | 1544 | return ret; | 
|  | 1545 | } | 
|  | 1546 |  | 
|  | 1547 | /* preallocate control response and buffer */ | 
|  | 1548 | dev->dev_ctrl_req = gs_alloc_req(gadget->ep0, GS_MAX_DESC_LEN, | 
|  | 1549 | GFP_KERNEL); | 
|  | 1550 | if (dev->dev_ctrl_req == NULL) { | 
|  | 1551 | gs_unbind(gadget); | 
|  | 1552 | return -ENOMEM; | 
|  | 1553 | } | 
|  | 1554 | dev->dev_ctrl_req->complete = gs_setup_complete; | 
|  | 1555 |  | 
|  | 1556 | gadget->ep0->driver_data = dev; | 
|  | 1557 |  | 
|  | 1558 | printk(KERN_INFO "gs_bind: %s %s bound\n", | 
|  | 1559 | GS_LONG_NAME, GS_VERSION_STR); | 
|  | 1560 |  | 
|  | 1561 | return 0; | 
|  | 1562 |  | 
|  | 1563 | autoconf_fail: | 
|  | 1564 | printk(KERN_ERR "gs_bind: cannot autoconfigure on %s\n", gadget->name); | 
|  | 1565 | return -ENODEV; | 
|  | 1566 | } | 
|  | 1567 |  | 
|  | 1568 | /* | 
|  | 1569 | * gs_unbind | 
|  | 1570 | * | 
|  | 1571 | * Called on module unload.  Frees the control request and device | 
|  | 1572 | * structure. | 
|  | 1573 | */ | 
|  | 1574 | static void gs_unbind(struct usb_gadget *gadget) | 
|  | 1575 | { | 
|  | 1576 | struct gs_dev *dev = get_gadget_data(gadget); | 
|  | 1577 |  | 
|  | 1578 | gs_device = NULL; | 
|  | 1579 |  | 
|  | 1580 | /* read/write requests already freed, only control request remains */ | 
|  | 1581 | if (dev != NULL) { | 
|  | 1582 | if (dev->dev_ctrl_req != NULL) { | 
|  | 1583 | gs_free_req(gadget->ep0, dev->dev_ctrl_req); | 
|  | 1584 | dev->dev_ctrl_req = NULL; | 
|  | 1585 | } | 
|  | 1586 | gs_free_ports(dev); | 
|  | 1587 | kfree(dev); | 
|  | 1588 | set_gadget_data(gadget, NULL); | 
|  | 1589 | } | 
|  | 1590 |  | 
|  | 1591 | printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME, | 
|  | 1592 | GS_VERSION_STR); | 
|  | 1593 | } | 
|  | 1594 |  | 
|  | 1595 | /* | 
|  | 1596 | * gs_setup | 
|  | 1597 | * | 
|  | 1598 | * Implements all the control endpoint functionality that's not | 
|  | 1599 | * handled in hardware or the hardware driver. | 
|  | 1600 | * | 
|  | 1601 | * Returns the size of the data sent to the host, or a negative | 
|  | 1602 | * error number. | 
|  | 1603 | */ | 
|  | 1604 | static int gs_setup(struct usb_gadget *gadget, | 
|  | 1605 | const struct usb_ctrlrequest *ctrl) | 
|  | 1606 | { | 
|  | 1607 | int ret = -EOPNOTSUPP; | 
|  | 1608 | struct gs_dev *dev = get_gadget_data(gadget); | 
|  | 1609 | struct usb_request *req = dev->dev_ctrl_req; | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 1610 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | 
|  | 1611 | u16 wValue = le16_to_cpu(ctrl->wValue); | 
|  | 1612 | u16 wLength = le16_to_cpu(ctrl->wLength); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1613 |  | 
|  | 1614 | switch (ctrl->bRequestType & USB_TYPE_MASK) { | 
|  | 1615 | case USB_TYPE_STANDARD: | 
|  | 1616 | ret = gs_setup_standard(gadget,ctrl); | 
|  | 1617 | break; | 
|  | 1618 |  | 
|  | 1619 | case USB_TYPE_CLASS: | 
|  | 1620 | ret = gs_setup_class(gadget,ctrl); | 
|  | 1621 | break; | 
|  | 1622 |  | 
|  | 1623 | default: | 
|  | 1624 | printk(KERN_ERR "gs_setup: unknown request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", | 
|  | 1625 | ctrl->bRequestType, ctrl->bRequest, | 
|  | 1626 | wValue, wIndex, wLength); | 
|  | 1627 | break; | 
|  | 1628 | } | 
|  | 1629 |  | 
|  | 1630 | /* respond with data transfer before status phase? */ | 
|  | 1631 | if (ret >= 0) { | 
|  | 1632 | req->length = ret; | 
|  | 1633 | req->zero = ret < wLength | 
|  | 1634 | && (ret % gadget->ep0->maxpacket) == 0; | 
|  | 1635 | ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | 
|  | 1636 | if (ret < 0) { | 
|  | 1637 | printk(KERN_ERR "gs_setup: cannot queue response, ret=%d\n", | 
|  | 1638 | ret); | 
|  | 1639 | req->status = 0; | 
|  | 1640 | gs_setup_complete(gadget->ep0, req); | 
|  | 1641 | } | 
|  | 1642 | } | 
|  | 1643 |  | 
|  | 1644 | /* device either stalls (ret < 0) or reports success */ | 
|  | 1645 | return ret; | 
|  | 1646 | } | 
|  | 1647 |  | 
|  | 1648 | static int gs_setup_standard(struct usb_gadget *gadget, | 
|  | 1649 | const struct usb_ctrlrequest *ctrl) | 
|  | 1650 | { | 
|  | 1651 | int ret = -EOPNOTSUPP; | 
|  | 1652 | struct gs_dev *dev = get_gadget_data(gadget); | 
|  | 1653 | struct usb_request *req = dev->dev_ctrl_req; | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 1654 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | 
|  | 1655 | u16 wValue = le16_to_cpu(ctrl->wValue); | 
|  | 1656 | u16 wLength = le16_to_cpu(ctrl->wLength); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1657 |  | 
|  | 1658 | switch (ctrl->bRequest) { | 
|  | 1659 | case USB_REQ_GET_DESCRIPTOR: | 
|  | 1660 | if (ctrl->bRequestType != USB_DIR_IN) | 
|  | 1661 | break; | 
|  | 1662 |  | 
|  | 1663 | switch (wValue >> 8) { | 
|  | 1664 | case USB_DT_DEVICE: | 
|  | 1665 | ret = min(wLength, | 
|  | 1666 | (u16)sizeof(struct usb_device_descriptor)); | 
|  | 1667 | memcpy(req->buf, &gs_device_desc, ret); | 
|  | 1668 | break; | 
|  | 1669 |  | 
|  | 1670 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 
|  | 1671 | case USB_DT_DEVICE_QUALIFIER: | 
|  | 1672 | if (!gadget->is_dualspeed) | 
|  | 1673 | break; | 
|  | 1674 | ret = min(wLength, | 
|  | 1675 | (u16)sizeof(struct usb_qualifier_descriptor)); | 
|  | 1676 | memcpy(req->buf, &gs_qualifier_desc, ret); | 
|  | 1677 | break; | 
|  | 1678 |  | 
|  | 1679 | case USB_DT_OTHER_SPEED_CONFIG: | 
|  | 1680 | if (!gadget->is_dualspeed) | 
|  | 1681 | break; | 
|  | 1682 | /* fall through */ | 
|  | 1683 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 
|  | 1684 | case USB_DT_CONFIG: | 
|  | 1685 | ret = gs_build_config_buf(req->buf, gadget->speed, | 
|  | 1686 | wValue >> 8, wValue & 0xff, | 
|  | 1687 | gadget->is_otg); | 
|  | 1688 | if (ret >= 0) | 
|  | 1689 | ret = min(wLength, (u16)ret); | 
|  | 1690 | break; | 
|  | 1691 |  | 
|  | 1692 | case USB_DT_STRING: | 
|  | 1693 | /* wIndex == language code. */ | 
|  | 1694 | ret = usb_gadget_get_string(&gs_string_table, | 
|  | 1695 | wValue & 0xff, req->buf); | 
|  | 1696 | if (ret >= 0) | 
|  | 1697 | ret = min(wLength, (u16)ret); | 
|  | 1698 | break; | 
|  | 1699 | } | 
|  | 1700 | break; | 
|  | 1701 |  | 
|  | 1702 | case USB_REQ_SET_CONFIGURATION: | 
|  | 1703 | if (ctrl->bRequestType != 0) | 
|  | 1704 | break; | 
|  | 1705 | spin_lock(&dev->dev_lock); | 
|  | 1706 | ret = gs_set_config(dev, wValue); | 
|  | 1707 | spin_unlock(&dev->dev_lock); | 
|  | 1708 | break; | 
|  | 1709 |  | 
|  | 1710 | case USB_REQ_GET_CONFIGURATION: | 
|  | 1711 | if (ctrl->bRequestType != USB_DIR_IN) | 
|  | 1712 | break; | 
|  | 1713 | *(u8 *)req->buf = dev->dev_config; | 
|  | 1714 | ret = min(wLength, (u16)1); | 
|  | 1715 | break; | 
|  | 1716 |  | 
|  | 1717 | case USB_REQ_SET_INTERFACE: | 
|  | 1718 | if (ctrl->bRequestType != USB_RECIP_INTERFACE | 
|  | 1719 | || !dev->dev_config | 
|  | 1720 | || wIndex >= GS_MAX_NUM_INTERFACES) | 
|  | 1721 | break; | 
|  | 1722 | if (dev->dev_config == GS_BULK_CONFIG_ID | 
|  | 1723 | && wIndex != GS_BULK_INTERFACE_ID) | 
|  | 1724 | break; | 
|  | 1725 | /* no alternate interface settings */ | 
|  | 1726 | if (wValue != 0) | 
|  | 1727 | break; | 
|  | 1728 | spin_lock(&dev->dev_lock); | 
|  | 1729 | /* PXA hardware partially handles SET_INTERFACE; | 
|  | 1730 | * we need to kluge around that interference.  */ | 
|  | 1731 | if (gadget_is_pxa(gadget)) { | 
|  | 1732 | ret = gs_set_config(dev, use_acm ? | 
|  | 1733 | GS_ACM_CONFIG_ID : GS_BULK_CONFIG_ID); | 
|  | 1734 | goto set_interface_done; | 
|  | 1735 | } | 
|  | 1736 | if (dev->dev_config != GS_BULK_CONFIG_ID | 
|  | 1737 | && wIndex == GS_CONTROL_INTERFACE_ID) { | 
|  | 1738 | if (dev->dev_notify_ep) { | 
|  | 1739 | usb_ep_disable(dev->dev_notify_ep); | 
|  | 1740 | usb_ep_enable(dev->dev_notify_ep, dev->dev_notify_ep_desc); | 
|  | 1741 | } | 
|  | 1742 | } else { | 
|  | 1743 | usb_ep_disable(dev->dev_in_ep); | 
|  | 1744 | usb_ep_disable(dev->dev_out_ep); | 
|  | 1745 | usb_ep_enable(dev->dev_in_ep, dev->dev_in_ep_desc); | 
|  | 1746 | usb_ep_enable(dev->dev_out_ep, dev->dev_out_ep_desc); | 
|  | 1747 | } | 
|  | 1748 | ret = 0; | 
|  | 1749 | set_interface_done: | 
|  | 1750 | spin_unlock(&dev->dev_lock); | 
|  | 1751 | break; | 
|  | 1752 |  | 
|  | 1753 | case USB_REQ_GET_INTERFACE: | 
|  | 1754 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE) | 
|  | 1755 | || dev->dev_config == GS_NO_CONFIG_ID) | 
|  | 1756 | break; | 
|  | 1757 | if (wIndex >= GS_MAX_NUM_INTERFACES | 
|  | 1758 | || (dev->dev_config == GS_BULK_CONFIG_ID | 
|  | 1759 | && wIndex != GS_BULK_INTERFACE_ID)) { | 
|  | 1760 | ret = -EDOM; | 
|  | 1761 | break; | 
|  | 1762 | } | 
|  | 1763 | /* no alternate interface settings */ | 
|  | 1764 | *(u8 *)req->buf = 0; | 
|  | 1765 | ret = min(wLength, (u16)1); | 
|  | 1766 | break; | 
|  | 1767 |  | 
|  | 1768 | default: | 
|  | 1769 | printk(KERN_ERR "gs_setup: unknown standard request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", | 
|  | 1770 | ctrl->bRequestType, ctrl->bRequest, | 
|  | 1771 | wValue, wIndex, wLength); | 
|  | 1772 | break; | 
|  | 1773 | } | 
|  | 1774 |  | 
|  | 1775 | return ret; | 
|  | 1776 | } | 
|  | 1777 |  | 
|  | 1778 | static int gs_setup_class(struct usb_gadget *gadget, | 
|  | 1779 | const struct usb_ctrlrequest *ctrl) | 
|  | 1780 | { | 
|  | 1781 | int ret = -EOPNOTSUPP; | 
|  | 1782 | struct gs_dev *dev = get_gadget_data(gadget); | 
|  | 1783 | struct gs_port *port = dev->dev_port[0];	/* ACM only has one port */ | 
|  | 1784 | struct usb_request *req = dev->dev_ctrl_req; | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 1785 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | 
|  | 1786 | u16 wValue = le16_to_cpu(ctrl->wValue); | 
|  | 1787 | u16 wLength = le16_to_cpu(ctrl->wLength); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1788 |  | 
|  | 1789 | switch (ctrl->bRequest) { | 
|  | 1790 | case USB_CDC_REQ_SET_LINE_CODING: | 
|  | 1791 | ret = min(wLength, | 
|  | 1792 | (u16)sizeof(struct usb_cdc_line_coding)); | 
|  | 1793 | if (port) { | 
|  | 1794 | spin_lock(&port->port_lock); | 
|  | 1795 | memcpy(&port->port_line_coding, req->buf, ret); | 
|  | 1796 | spin_unlock(&port->port_lock); | 
|  | 1797 | } | 
|  | 1798 | break; | 
|  | 1799 |  | 
|  | 1800 | case USB_CDC_REQ_GET_LINE_CODING: | 
|  | 1801 | port = dev->dev_port[0];	/* ACM only has one port */ | 
|  | 1802 | ret = min(wLength, | 
|  | 1803 | (u16)sizeof(struct usb_cdc_line_coding)); | 
|  | 1804 | if (port) { | 
|  | 1805 | spin_lock(&port->port_lock); | 
|  | 1806 | memcpy(req->buf, &port->port_line_coding, ret); | 
|  | 1807 | spin_unlock(&port->port_lock); | 
|  | 1808 | } | 
|  | 1809 | break; | 
|  | 1810 |  | 
|  | 1811 | case USB_CDC_REQ_SET_CONTROL_LINE_STATE: | 
|  | 1812 | ret = 0; | 
|  | 1813 | break; | 
|  | 1814 |  | 
|  | 1815 | default: | 
|  | 1816 | printk(KERN_ERR "gs_setup: unknown class request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", | 
|  | 1817 | ctrl->bRequestType, ctrl->bRequest, | 
|  | 1818 | wValue, wIndex, wLength); | 
|  | 1819 | break; | 
|  | 1820 | } | 
|  | 1821 |  | 
|  | 1822 | return ret; | 
|  | 1823 | } | 
|  | 1824 |  | 
|  | 1825 | /* | 
|  | 1826 | * gs_setup_complete | 
|  | 1827 | */ | 
|  | 1828 | static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) | 
|  | 1829 | { | 
|  | 1830 | if (req->status || req->actual != req->length) { | 
|  | 1831 | printk(KERN_ERR "gs_setup_complete: status error, status=%d, actual=%d, length=%d\n", | 
|  | 1832 | req->status, req->actual, req->length); | 
|  | 1833 | } | 
|  | 1834 | } | 
|  | 1835 |  | 
|  | 1836 | /* | 
|  | 1837 | * gs_disconnect | 
|  | 1838 | * | 
|  | 1839 | * Called when the device is disconnected.  Frees the closed | 
|  | 1840 | * ports and disconnects open ports.  Open ports will be freed | 
|  | 1841 | * on close.  Then reallocates the ports for the next connection. | 
|  | 1842 | */ | 
|  | 1843 | static void gs_disconnect(struct usb_gadget *gadget) | 
|  | 1844 | { | 
|  | 1845 | unsigned long flags; | 
|  | 1846 | struct gs_dev *dev = get_gadget_data(gadget); | 
|  | 1847 |  | 
|  | 1848 | spin_lock_irqsave(&dev->dev_lock, flags); | 
|  | 1849 |  | 
|  | 1850 | gs_reset_config(dev); | 
|  | 1851 |  | 
|  | 1852 | /* free closed ports and disconnect open ports */ | 
|  | 1853 | /* (open ports will be freed when closed) */ | 
|  | 1854 | gs_free_ports(dev); | 
|  | 1855 |  | 
|  | 1856 | /* re-allocate ports for the next connection */ | 
|  | 1857 | if (gs_alloc_ports(dev, GFP_ATOMIC) != 0) | 
|  | 1858 | printk(KERN_ERR "gs_disconnect: cannot re-allocate ports\n"); | 
|  | 1859 |  | 
|  | 1860 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 
|  | 1861 |  | 
|  | 1862 | printk(KERN_INFO "gs_disconnect: %s disconnected\n", GS_LONG_NAME); | 
|  | 1863 | } | 
|  | 1864 |  | 
|  | 1865 | /* | 
|  | 1866 | * gs_set_config | 
|  | 1867 | * | 
|  | 1868 | * Configures the device by enabling device specific | 
|  | 1869 | * optimizations, setting up the endpoints, allocating | 
|  | 1870 | * read and write requests and queuing read requests. | 
|  | 1871 | * | 
|  | 1872 | * The device lock must be held when calling this function. | 
|  | 1873 | */ | 
|  | 1874 | static int gs_set_config(struct gs_dev *dev, unsigned config) | 
|  | 1875 | { | 
|  | 1876 | int i; | 
|  | 1877 | int ret = 0; | 
|  | 1878 | struct usb_gadget *gadget = dev->dev_gadget; | 
|  | 1879 | struct usb_ep *ep; | 
|  | 1880 | struct usb_endpoint_descriptor *ep_desc; | 
|  | 1881 | struct usb_request *req; | 
|  | 1882 | struct gs_req_entry *req_entry; | 
|  | 1883 |  | 
|  | 1884 | if (dev == NULL) { | 
|  | 1885 | printk(KERN_ERR "gs_set_config: NULL device pointer\n"); | 
|  | 1886 | return 0; | 
|  | 1887 | } | 
|  | 1888 |  | 
|  | 1889 | if (config == dev->dev_config) | 
|  | 1890 | return 0; | 
|  | 1891 |  | 
|  | 1892 | gs_reset_config(dev); | 
|  | 1893 |  | 
|  | 1894 | switch (config) { | 
|  | 1895 | case GS_NO_CONFIG_ID: | 
|  | 1896 | return 0; | 
|  | 1897 | case GS_BULK_CONFIG_ID: | 
|  | 1898 | if (use_acm) | 
|  | 1899 | return -EINVAL; | 
|  | 1900 | /* device specific optimizations */ | 
|  | 1901 | if (gadget_is_net2280(gadget)) | 
|  | 1902 | net2280_set_fifo_mode(gadget, 1); | 
|  | 1903 | break; | 
|  | 1904 | case GS_ACM_CONFIG_ID: | 
|  | 1905 | if (!use_acm) | 
|  | 1906 | return -EINVAL; | 
|  | 1907 | /* device specific optimizations */ | 
|  | 1908 | if (gadget_is_net2280(gadget)) | 
|  | 1909 | net2280_set_fifo_mode(gadget, 1); | 
|  | 1910 | break; | 
|  | 1911 | default: | 
|  | 1912 | return -EINVAL; | 
|  | 1913 | } | 
|  | 1914 |  | 
|  | 1915 | dev->dev_config = config; | 
|  | 1916 |  | 
|  | 1917 | gadget_for_each_ep(ep, gadget) { | 
|  | 1918 |  | 
|  | 1919 | if (EP_NOTIFY_NAME | 
|  | 1920 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { | 
|  | 1921 | ep_desc = GS_SPEED_SELECT( | 
|  | 1922 | gadget->speed == USB_SPEED_HIGH, | 
|  | 1923 | &gs_highspeed_notify_desc, | 
|  | 1924 | &gs_fullspeed_notify_desc); | 
|  | 1925 | ret = usb_ep_enable(ep,ep_desc); | 
|  | 1926 | if (ret == 0) { | 
|  | 1927 | ep->driver_data = dev; | 
|  | 1928 | dev->dev_notify_ep = ep; | 
|  | 1929 | dev->dev_notify_ep_desc = ep_desc; | 
|  | 1930 | } else { | 
|  | 1931 | printk(KERN_ERR "gs_set_config: cannot enable notify endpoint %s, ret=%d\n", | 
|  | 1932 | ep->name, ret); | 
|  | 1933 | goto exit_reset_config; | 
|  | 1934 | } | 
|  | 1935 | } | 
|  | 1936 |  | 
|  | 1937 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { | 
|  | 1938 | ep_desc = GS_SPEED_SELECT( | 
|  | 1939 | gadget->speed == USB_SPEED_HIGH, | 
|  | 1940 | &gs_highspeed_in_desc, | 
|  | 1941 | &gs_fullspeed_in_desc); | 
|  | 1942 | ret = usb_ep_enable(ep,ep_desc); | 
|  | 1943 | if (ret == 0) { | 
|  | 1944 | ep->driver_data = dev; | 
|  | 1945 | dev->dev_in_ep = ep; | 
|  | 1946 | dev->dev_in_ep_desc = ep_desc; | 
|  | 1947 | } else { | 
|  | 1948 | printk(KERN_ERR "gs_set_config: cannot enable in endpoint %s, ret=%d\n", | 
|  | 1949 | ep->name, ret); | 
|  | 1950 | goto exit_reset_config; | 
|  | 1951 | } | 
|  | 1952 | } | 
|  | 1953 |  | 
|  | 1954 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { | 
|  | 1955 | ep_desc = GS_SPEED_SELECT( | 
|  | 1956 | gadget->speed == USB_SPEED_HIGH, | 
|  | 1957 | &gs_highspeed_out_desc, | 
|  | 1958 | &gs_fullspeed_out_desc); | 
|  | 1959 | ret = usb_ep_enable(ep,ep_desc); | 
|  | 1960 | if (ret == 0) { | 
|  | 1961 | ep->driver_data = dev; | 
|  | 1962 | dev->dev_out_ep = ep; | 
|  | 1963 | dev->dev_out_ep_desc = ep_desc; | 
|  | 1964 | } else { | 
|  | 1965 | printk(KERN_ERR "gs_set_config: cannot enable out endpoint %s, ret=%d\n", | 
|  | 1966 | ep->name, ret); | 
|  | 1967 | goto exit_reset_config; | 
|  | 1968 | } | 
|  | 1969 | } | 
|  | 1970 |  | 
|  | 1971 | } | 
|  | 1972 |  | 
|  | 1973 | if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL | 
|  | 1974 | || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { | 
|  | 1975 | printk(KERN_ERR "gs_set_config: cannot find endpoints\n"); | 
|  | 1976 | ret = -ENODEV; | 
|  | 1977 | goto exit_reset_config; | 
|  | 1978 | } | 
|  | 1979 |  | 
|  | 1980 | /* allocate and queue read requests */ | 
|  | 1981 | ep = dev->dev_out_ep; | 
|  | 1982 | for (i=0; i<read_q_size && ret == 0; i++) { | 
|  | 1983 | if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) { | 
|  | 1984 | req->complete = gs_read_complete; | 
|  | 1985 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 
|  | 1986 | printk(KERN_ERR "gs_set_config: cannot queue read request, ret=%d\n", | 
|  | 1987 | ret); | 
|  | 1988 | } | 
|  | 1989 | } else { | 
|  | 1990 | printk(KERN_ERR "gs_set_config: cannot allocate read requests\n"); | 
|  | 1991 | ret = -ENOMEM; | 
|  | 1992 | goto exit_reset_config; | 
|  | 1993 | } | 
|  | 1994 | } | 
|  | 1995 |  | 
|  | 1996 | /* allocate write requests, and put on free list */ | 
|  | 1997 | ep = dev->dev_in_ep; | 
|  | 1998 | for (i=0; i<write_q_size; i++) { | 
|  | 1999 | if ((req_entry=gs_alloc_req_entry(ep, ep->maxpacket, GFP_ATOMIC))) { | 
|  | 2000 | req_entry->re_req->complete = gs_write_complete; | 
|  | 2001 | list_add(&req_entry->re_entry, &dev->dev_req_list); | 
|  | 2002 | } else { | 
|  | 2003 | printk(KERN_ERR "gs_set_config: cannot allocate write requests\n"); | 
|  | 2004 | ret = -ENOMEM; | 
|  | 2005 | goto exit_reset_config; | 
|  | 2006 | } | 
|  | 2007 | } | 
|  | 2008 |  | 
|  | 2009 | printk(KERN_INFO "gs_set_config: %s configured, %s speed %s config\n", | 
|  | 2010 | GS_LONG_NAME, | 
|  | 2011 | gadget->speed == USB_SPEED_HIGH ? "high" : "full", | 
|  | 2012 | config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM"); | 
|  | 2013 |  | 
|  | 2014 | return 0; | 
|  | 2015 |  | 
|  | 2016 | exit_reset_config: | 
|  | 2017 | gs_reset_config(dev); | 
|  | 2018 | return ret; | 
|  | 2019 | } | 
|  | 2020 |  | 
|  | 2021 | /* | 
|  | 2022 | * gs_reset_config | 
|  | 2023 | * | 
|  | 2024 | * Mark the device as not configured, disable all endpoints, | 
|  | 2025 | * which forces completion of pending I/O and frees queued | 
|  | 2026 | * requests, and free the remaining write requests on the | 
|  | 2027 | * free list. | 
|  | 2028 | * | 
|  | 2029 | * The device lock must be held when calling this function. | 
|  | 2030 | */ | 
|  | 2031 | static void gs_reset_config(struct gs_dev *dev) | 
|  | 2032 | { | 
|  | 2033 | struct gs_req_entry *req_entry; | 
|  | 2034 |  | 
|  | 2035 | if (dev == NULL) { | 
|  | 2036 | printk(KERN_ERR "gs_reset_config: NULL device pointer\n"); | 
|  | 2037 | return; | 
|  | 2038 | } | 
|  | 2039 |  | 
|  | 2040 | if (dev->dev_config == GS_NO_CONFIG_ID) | 
|  | 2041 | return; | 
|  | 2042 |  | 
|  | 2043 | dev->dev_config = GS_NO_CONFIG_ID; | 
|  | 2044 |  | 
|  | 2045 | /* free write requests on the free list */ | 
|  | 2046 | while(!list_empty(&dev->dev_req_list)) { | 
|  | 2047 | req_entry = list_entry(dev->dev_req_list.next, | 
|  | 2048 | struct gs_req_entry, re_entry); | 
|  | 2049 | list_del(&req_entry->re_entry); | 
|  | 2050 | gs_free_req_entry(dev->dev_in_ep, req_entry); | 
|  | 2051 | } | 
|  | 2052 |  | 
|  | 2053 | /* disable endpoints, forcing completion of pending i/o; */ | 
|  | 2054 | /* completion handlers free their requests in this case */ | 
|  | 2055 | if (dev->dev_notify_ep) { | 
|  | 2056 | usb_ep_disable(dev->dev_notify_ep); | 
|  | 2057 | dev->dev_notify_ep = NULL; | 
|  | 2058 | } | 
|  | 2059 | if (dev->dev_in_ep) { | 
|  | 2060 | usb_ep_disable(dev->dev_in_ep); | 
|  | 2061 | dev->dev_in_ep = NULL; | 
|  | 2062 | } | 
|  | 2063 | if (dev->dev_out_ep) { | 
|  | 2064 | usb_ep_disable(dev->dev_out_ep); | 
|  | 2065 | dev->dev_out_ep = NULL; | 
|  | 2066 | } | 
|  | 2067 | } | 
|  | 2068 |  | 
|  | 2069 | /* | 
|  | 2070 | * gs_build_config_buf | 
|  | 2071 | * | 
|  | 2072 | * Builds the config descriptors in the given buffer and returns the | 
|  | 2073 | * length, or a negative error number. | 
|  | 2074 | */ | 
|  | 2075 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 
|  | 2076 | u8 type, unsigned int index, int is_otg) | 
|  | 2077 | { | 
|  | 2078 | int len; | 
|  | 2079 | int high_speed; | 
|  | 2080 | const struct usb_config_descriptor *config_desc; | 
|  | 2081 | const struct usb_descriptor_header **function; | 
|  | 2082 |  | 
|  | 2083 | if (index >= gs_device_desc.bNumConfigurations) | 
|  | 2084 | return -EINVAL; | 
|  | 2085 |  | 
|  | 2086 | /* other speed switches high and full speed */ | 
|  | 2087 | high_speed = (speed == USB_SPEED_HIGH); | 
|  | 2088 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 
|  | 2089 | high_speed = !high_speed; | 
|  | 2090 |  | 
|  | 2091 | if (use_acm) { | 
|  | 2092 | config_desc = &gs_acm_config_desc; | 
|  | 2093 | function = GS_SPEED_SELECT(high_speed, | 
|  | 2094 | gs_acm_highspeed_function, | 
|  | 2095 | gs_acm_fullspeed_function); | 
|  | 2096 | } else { | 
|  | 2097 | config_desc = &gs_bulk_config_desc; | 
|  | 2098 | function = GS_SPEED_SELECT(high_speed, | 
|  | 2099 | gs_bulk_highspeed_function, | 
|  | 2100 | gs_bulk_fullspeed_function); | 
|  | 2101 | } | 
|  | 2102 |  | 
|  | 2103 | /* for now, don't advertise srp-only devices */ | 
|  | 2104 | if (!is_otg) | 
|  | 2105 | function++; | 
|  | 2106 |  | 
|  | 2107 | len = usb_gadget_config_buf(config_desc, buf, GS_MAX_DESC_LEN, function); | 
|  | 2108 | if (len < 0) | 
|  | 2109 | return len; | 
|  | 2110 |  | 
|  | 2111 | ((struct usb_config_descriptor *)buf)->bDescriptorType = type; | 
|  | 2112 |  | 
|  | 2113 | return len; | 
|  | 2114 | } | 
|  | 2115 |  | 
|  | 2116 | /* | 
|  | 2117 | * gs_alloc_req | 
|  | 2118 | * | 
|  | 2119 | * Allocate a usb_request and its buffer.  Returns a pointer to the | 
|  | 2120 | * usb_request or NULL if there is an error. | 
|  | 2121 | */ | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 2122 | static struct usb_request * | 
|  | 2123 | gs_alloc_req(struct usb_ep *ep, unsigned int len, unsigned kmalloc_flags) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2124 | { | 
|  | 2125 | struct usb_request *req; | 
|  | 2126 |  | 
|  | 2127 | if (ep == NULL) | 
|  | 2128 | return NULL; | 
|  | 2129 |  | 
|  | 2130 | req = usb_ep_alloc_request(ep, kmalloc_flags); | 
|  | 2131 |  | 
|  | 2132 | if (req != NULL) { | 
|  | 2133 | req->length = len; | 
|  | 2134 | req->buf = kmalloc(len, kmalloc_flags); | 
|  | 2135 | if (req->buf == NULL) { | 
|  | 2136 | usb_ep_free_request(ep, req); | 
|  | 2137 | return NULL; | 
|  | 2138 | } | 
|  | 2139 | } | 
|  | 2140 |  | 
|  | 2141 | return req; | 
|  | 2142 | } | 
|  | 2143 |  | 
|  | 2144 | /* | 
|  | 2145 | * gs_free_req | 
|  | 2146 | * | 
|  | 2147 | * Free a usb_request and its buffer. | 
|  | 2148 | */ | 
|  | 2149 | static void gs_free_req(struct usb_ep *ep, struct usb_request *req) | 
|  | 2150 | { | 
|  | 2151 | if (ep != NULL && req != NULL) { | 
|  | 2152 | kfree(req->buf); | 
|  | 2153 | usb_ep_free_request(ep, req); | 
|  | 2154 | } | 
|  | 2155 | } | 
|  | 2156 |  | 
|  | 2157 | /* | 
|  | 2158 | * gs_alloc_req_entry | 
|  | 2159 | * | 
|  | 2160 | * Allocates a request and its buffer, using the given | 
|  | 2161 | * endpoint, buffer len, and kmalloc flags. | 
|  | 2162 | */ | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 2163 | static struct gs_req_entry * | 
|  | 2164 | gs_alloc_req_entry(struct usb_ep *ep, unsigned len, unsigned kmalloc_flags) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2165 | { | 
|  | 2166 | struct gs_req_entry	*req; | 
|  | 2167 |  | 
|  | 2168 | req = kmalloc(sizeof(struct gs_req_entry), kmalloc_flags); | 
|  | 2169 | if (req == NULL) | 
|  | 2170 | return NULL; | 
|  | 2171 |  | 
|  | 2172 | req->re_req = gs_alloc_req(ep, len, kmalloc_flags); | 
|  | 2173 | if (req->re_req == NULL) { | 
|  | 2174 | kfree(req); | 
|  | 2175 | return NULL; | 
|  | 2176 | } | 
|  | 2177 |  | 
|  | 2178 | req->re_req->context = req; | 
|  | 2179 |  | 
|  | 2180 | return req; | 
|  | 2181 | } | 
|  | 2182 |  | 
|  | 2183 | /* | 
|  | 2184 | * gs_free_req_entry | 
|  | 2185 | * | 
|  | 2186 | * Frees a request and its buffer. | 
|  | 2187 | */ | 
|  | 2188 | static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req) | 
|  | 2189 | { | 
|  | 2190 | if (ep != NULL && req != NULL) { | 
|  | 2191 | if (req->re_req != NULL) | 
|  | 2192 | gs_free_req(ep, req->re_req); | 
|  | 2193 | kfree(req); | 
|  | 2194 | } | 
|  | 2195 | } | 
|  | 2196 |  | 
|  | 2197 | /* | 
|  | 2198 | * gs_alloc_ports | 
|  | 2199 | * | 
|  | 2200 | * Allocate all ports and set the gs_dev struct to point to them. | 
|  | 2201 | * Return 0 if successful, or a negative error number. | 
|  | 2202 | * | 
|  | 2203 | * The device lock is normally held when calling this function. | 
|  | 2204 | */ | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 2205 | static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2206 | { | 
|  | 2207 | int i; | 
|  | 2208 | struct gs_port *port; | 
|  | 2209 |  | 
|  | 2210 | if (dev == NULL) | 
|  | 2211 | return -EIO; | 
|  | 2212 |  | 
|  | 2213 | for (i=0; i<GS_NUM_PORTS; i++) { | 
|  | 2214 | if ((port=(struct gs_port *)kmalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL) | 
|  | 2215 | return -ENOMEM; | 
|  | 2216 |  | 
|  | 2217 | memset(port, 0, sizeof(struct gs_port)); | 
|  | 2218 | port->port_dev = dev; | 
|  | 2219 | port->port_num = i; | 
|  | 2220 | port->port_line_coding.dwDTERate = cpu_to_le32(GS_DEFAULT_DTE_RATE); | 
|  | 2221 | port->port_line_coding.bCharFormat = GS_DEFAULT_CHAR_FORMAT; | 
|  | 2222 | port->port_line_coding.bParityType = GS_DEFAULT_PARITY; | 
|  | 2223 | port->port_line_coding.bDataBits = GS_DEFAULT_DATA_BITS; | 
|  | 2224 | spin_lock_init(&port->port_lock); | 
|  | 2225 | init_waitqueue_head(&port->port_write_wait); | 
|  | 2226 |  | 
|  | 2227 | dev->dev_port[i] = port; | 
|  | 2228 | } | 
|  | 2229 |  | 
|  | 2230 | return 0; | 
|  | 2231 | } | 
|  | 2232 |  | 
|  | 2233 | /* | 
|  | 2234 | * gs_free_ports | 
|  | 2235 | * | 
|  | 2236 | * Free all closed ports.  Open ports are disconnected by | 
|  | 2237 | * freeing their write buffers, setting their device pointers | 
|  | 2238 | * and the pointers to them in the device to NULL.  These | 
|  | 2239 | * ports will be freed when closed. | 
|  | 2240 | * | 
|  | 2241 | * The device lock is normally held when calling this function. | 
|  | 2242 | */ | 
|  | 2243 | static void gs_free_ports(struct gs_dev *dev) | 
|  | 2244 | { | 
|  | 2245 | int i; | 
|  | 2246 | unsigned long flags; | 
|  | 2247 | struct gs_port *port; | 
|  | 2248 |  | 
|  | 2249 | if (dev == NULL) | 
|  | 2250 | return; | 
|  | 2251 |  | 
|  | 2252 | for (i=0; i<GS_NUM_PORTS; i++) { | 
|  | 2253 | if ((port=dev->dev_port[i]) != NULL) { | 
|  | 2254 | dev->dev_port[i] = NULL; | 
|  | 2255 |  | 
|  | 2256 | spin_lock_irqsave(&port->port_lock, flags); | 
|  | 2257 |  | 
|  | 2258 | if (port->port_write_buf != NULL) { | 
|  | 2259 | gs_buf_free(port->port_write_buf); | 
|  | 2260 | port->port_write_buf = NULL; | 
|  | 2261 | } | 
|  | 2262 |  | 
|  | 2263 | if (port->port_open_count > 0 || port->port_in_use) { | 
|  | 2264 | port->port_dev = NULL; | 
|  | 2265 | wake_up_interruptible(&port->port_write_wait); | 
|  | 2266 | if (port->port_tty) { | 
|  | 2267 | wake_up_interruptible(&port->port_tty->read_wait); | 
|  | 2268 | wake_up_interruptible(&port->port_tty->write_wait); | 
|  | 2269 | } | 
|  | 2270 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 2271 | } else { | 
|  | 2272 | spin_unlock_irqrestore(&port->port_lock, flags); | 
|  | 2273 | kfree(port); | 
|  | 2274 | } | 
|  | 2275 |  | 
|  | 2276 | } | 
|  | 2277 | } | 
|  | 2278 | } | 
|  | 2279 |  | 
|  | 2280 | /* Circular Buffer */ | 
|  | 2281 |  | 
|  | 2282 | /* | 
|  | 2283 | * gs_buf_alloc | 
|  | 2284 | * | 
|  | 2285 | * Allocate a circular buffer and all associated memory. | 
|  | 2286 | */ | 
| David Brownell | 1bbc169 | 2005-05-07 13:05:13 -0700 | [diff] [blame] | 2287 | static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2288 | { | 
|  | 2289 | struct gs_buf *gb; | 
|  | 2290 |  | 
|  | 2291 | if (size == 0) | 
|  | 2292 | return NULL; | 
|  | 2293 |  | 
|  | 2294 | gb = (struct gs_buf *)kmalloc(sizeof(struct gs_buf), kmalloc_flags); | 
|  | 2295 | if (gb == NULL) | 
|  | 2296 | return NULL; | 
|  | 2297 |  | 
|  | 2298 | gb->buf_buf = kmalloc(size, kmalloc_flags); | 
|  | 2299 | if (gb->buf_buf == NULL) { | 
|  | 2300 | kfree(gb); | 
|  | 2301 | return NULL; | 
|  | 2302 | } | 
|  | 2303 |  | 
|  | 2304 | gb->buf_size = size; | 
|  | 2305 | gb->buf_get = gb->buf_put = gb->buf_buf; | 
|  | 2306 |  | 
|  | 2307 | return gb; | 
|  | 2308 | } | 
|  | 2309 |  | 
|  | 2310 | /* | 
|  | 2311 | * gs_buf_free | 
|  | 2312 | * | 
|  | 2313 | * Free the buffer and all associated memory. | 
|  | 2314 | */ | 
|  | 2315 | void gs_buf_free(struct gs_buf *gb) | 
|  | 2316 | { | 
| Jesper Juhl | 1bc3c9e | 2005-04-18 17:39:34 -0700 | [diff] [blame] | 2317 | if (gb) { | 
|  | 2318 | kfree(gb->buf_buf); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2319 | kfree(gb); | 
|  | 2320 | } | 
|  | 2321 | } | 
|  | 2322 |  | 
|  | 2323 | /* | 
|  | 2324 | * gs_buf_clear | 
|  | 2325 | * | 
|  | 2326 | * Clear out all data in the circular buffer. | 
|  | 2327 | */ | 
|  | 2328 | void gs_buf_clear(struct gs_buf *gb) | 
|  | 2329 | { | 
|  | 2330 | if (gb != NULL) | 
|  | 2331 | gb->buf_get = gb->buf_put; | 
|  | 2332 | /* equivalent to a get of all data available */ | 
|  | 2333 | } | 
|  | 2334 |  | 
|  | 2335 | /* | 
|  | 2336 | * gs_buf_data_avail | 
|  | 2337 | * | 
|  | 2338 | * Return the number of bytes of data available in the circular | 
|  | 2339 | * buffer. | 
|  | 2340 | */ | 
|  | 2341 | unsigned int gs_buf_data_avail(struct gs_buf *gb) | 
|  | 2342 | { | 
|  | 2343 | if (gb != NULL) | 
|  | 2344 | return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size; | 
|  | 2345 | else | 
|  | 2346 | return 0; | 
|  | 2347 | } | 
|  | 2348 |  | 
|  | 2349 | /* | 
|  | 2350 | * gs_buf_space_avail | 
|  | 2351 | * | 
|  | 2352 | * Return the number of bytes of space available in the circular | 
|  | 2353 | * buffer. | 
|  | 2354 | */ | 
|  | 2355 | unsigned int gs_buf_space_avail(struct gs_buf *gb) | 
|  | 2356 | { | 
|  | 2357 | if (gb != NULL) | 
|  | 2358 | return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size; | 
|  | 2359 | else | 
|  | 2360 | return 0; | 
|  | 2361 | } | 
|  | 2362 |  | 
|  | 2363 | /* | 
|  | 2364 | * gs_buf_put | 
|  | 2365 | * | 
|  | 2366 | * Copy data data from a user buffer and put it into the circular buffer. | 
|  | 2367 | * Restrict to the amount of space available. | 
|  | 2368 | * | 
|  | 2369 | * Return the number of bytes copied. | 
|  | 2370 | */ | 
|  | 2371 | unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count) | 
|  | 2372 | { | 
|  | 2373 | unsigned int len; | 
|  | 2374 |  | 
|  | 2375 | if (gb == NULL) | 
|  | 2376 | return 0; | 
|  | 2377 |  | 
|  | 2378 | len  = gs_buf_space_avail(gb); | 
|  | 2379 | if (count > len) | 
|  | 2380 | count = len; | 
|  | 2381 |  | 
|  | 2382 | if (count == 0) | 
|  | 2383 | return 0; | 
|  | 2384 |  | 
|  | 2385 | len = gb->buf_buf + gb->buf_size - gb->buf_put; | 
|  | 2386 | if (count > len) { | 
|  | 2387 | memcpy(gb->buf_put, buf, len); | 
|  | 2388 | memcpy(gb->buf_buf, buf+len, count - len); | 
|  | 2389 | gb->buf_put = gb->buf_buf + count - len; | 
|  | 2390 | } else { | 
|  | 2391 | memcpy(gb->buf_put, buf, count); | 
|  | 2392 | if (count < len) | 
|  | 2393 | gb->buf_put += count; | 
|  | 2394 | else /* count == len */ | 
|  | 2395 | gb->buf_put = gb->buf_buf; | 
|  | 2396 | } | 
|  | 2397 |  | 
|  | 2398 | return count; | 
|  | 2399 | } | 
|  | 2400 |  | 
|  | 2401 | /* | 
|  | 2402 | * gs_buf_get | 
|  | 2403 | * | 
|  | 2404 | * Get data from the circular buffer and copy to the given buffer. | 
|  | 2405 | * Restrict to the amount of data available. | 
|  | 2406 | * | 
|  | 2407 | * Return the number of bytes copied. | 
|  | 2408 | */ | 
|  | 2409 | unsigned int gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count) | 
|  | 2410 | { | 
|  | 2411 | unsigned int len; | 
|  | 2412 |  | 
|  | 2413 | if (gb == NULL) | 
|  | 2414 | return 0; | 
|  | 2415 |  | 
|  | 2416 | len = gs_buf_data_avail(gb); | 
|  | 2417 | if (count > len) | 
|  | 2418 | count = len; | 
|  | 2419 |  | 
|  | 2420 | if (count == 0) | 
|  | 2421 | return 0; | 
|  | 2422 |  | 
|  | 2423 | len = gb->buf_buf + gb->buf_size - gb->buf_get; | 
|  | 2424 | if (count > len) { | 
|  | 2425 | memcpy(buf, gb->buf_get, len); | 
|  | 2426 | memcpy(buf+len, gb->buf_buf, count - len); | 
|  | 2427 | gb->buf_get = gb->buf_buf + count - len; | 
|  | 2428 | } else { | 
|  | 2429 | memcpy(buf, gb->buf_get, count); | 
|  | 2430 | if (count < len) | 
|  | 2431 | gb->buf_get += count; | 
|  | 2432 | else /* count == len */ | 
|  | 2433 | gb->buf_get = gb->buf_buf; | 
|  | 2434 | } | 
|  | 2435 |  | 
|  | 2436 | return count; | 
|  | 2437 | } |