Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.20-rc7 321 lines 8.9 kB view raw
1/* 2 * AirPrime CDMA Wireless Serial USB driver 3 * 4 * Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/tty.h> 14#include <linux/tty_flip.h> 15#include <linux/module.h> 16#include <linux/usb.h> 17#include <linux/usb/serial.h> 18 19static struct usb_device_id id_table [] = { 20 { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ 21 { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ 22 { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */ 23 { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */ 24 { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ 25 { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ 26 { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ 27 { }, 28}; 29MODULE_DEVICE_TABLE(usb, id_table); 30 31#define URB_TRANSFER_BUFFER_SIZE 4096 32#define NUM_READ_URBS 4 33#define NUM_WRITE_URBS 4 34#define NUM_BULK_EPS 3 35#define MAX_BULK_EPS 6 36 37/* if overridden by the user, then use their value for the size of the 38 * read and write urbs, and the number of endpoints */ 39static int buffer_size = URB_TRANSFER_BUFFER_SIZE; 40static int endpoints = NUM_BULK_EPS; 41static int debug; 42struct airprime_private { 43 spinlock_t lock; 44 int outstanding_urbs; 45 int throttled; 46 struct urb *read_urbp[NUM_READ_URBS]; 47}; 48 49static void airprime_read_bulk_callback(struct urb *urb) 50{ 51 struct usb_serial_port *port = urb->context; 52 unsigned char *data = urb->transfer_buffer; 53 struct tty_struct *tty; 54 int result; 55 56 dbg("%s - port %d", __FUNCTION__, port->number); 57 58 if (urb->status) { 59 dbg("%s - nonzero read bulk status received: %d", 60 __FUNCTION__, urb->status); 61 /* something happened, so free up the memory for this urb */ 62 if (urb->transfer_buffer) { 63 kfree (urb->transfer_buffer); 64 urb->transfer_buffer = NULL; 65 } 66 return; 67 } 68 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 69 70 tty = port->tty; 71 if (tty && urb->actual_length) { 72 tty_insert_flip_string (tty, data, urb->actual_length); 73 tty_flip_buffer_push (tty); 74 } 75 76 result = usb_submit_urb (urb, GFP_ATOMIC); 77 if (result) 78 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", 79 __FUNCTION__, result); 80 return; 81} 82 83static void airprime_write_bulk_callback(struct urb *urb) 84{ 85 struct usb_serial_port *port = urb->context; 86 struct airprime_private *priv = usb_get_serial_port_data(port); 87 unsigned long flags; 88 89 dbg("%s - port %d", __FUNCTION__, port->number); 90 91 /* free up the transfer buffer, as usb_free_urb() does not do this */ 92 kfree (urb->transfer_buffer); 93 94 if (urb->status) 95 dbg("%s - nonzero write bulk status received: %d", 96 __FUNCTION__, urb->status); 97 spin_lock_irqsave(&priv->lock, flags); 98 --priv->outstanding_urbs; 99 spin_unlock_irqrestore(&priv->lock, flags); 100 101 usb_serial_port_softint(port); 102} 103 104static int airprime_open(struct usb_serial_port *port, struct file *filp) 105{ 106 struct airprime_private *priv = usb_get_serial_port_data(port); 107 struct usb_serial *serial = port->serial; 108 struct urb *urb; 109 char *buffer = NULL; 110 int i; 111 int result = 0; 112 113 dbg("%s - port %d", __FUNCTION__, port->number); 114 115 /* initialize our private data structure if it isn't already created */ 116 if (!priv) { 117 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 118 if (!priv) { 119 result = -ENOMEM; 120 goto out; 121 } 122 spin_lock_init(&priv->lock); 123 usb_set_serial_port_data(port, priv); 124 } 125 126 for (i = 0; i < NUM_READ_URBS; ++i) { 127 buffer = kmalloc(buffer_size, GFP_KERNEL); 128 if (!buffer) { 129 dev_err(&port->dev, "%s - out of memory.\n", 130 __FUNCTION__); 131 result = -ENOMEM; 132 goto errout; 133 } 134 urb = usb_alloc_urb(0, GFP_KERNEL); 135 if (!urb) { 136 kfree(buffer); 137 dev_err(&port->dev, "%s - no more urbs?\n", 138 __FUNCTION__); 139 result = -ENOMEM; 140 goto errout; 141 } 142 usb_fill_bulk_urb(urb, serial->dev, 143 usb_rcvbulkpipe(serial->dev, 144 port->bulk_out_endpointAddress), 145 buffer, buffer_size, 146 airprime_read_bulk_callback, port); 147 result = usb_submit_urb(urb, GFP_KERNEL); 148 if (result) { 149 dev_err(&port->dev, 150 "%s - failed submitting read urb %d for port %d, error %d\n", 151 __FUNCTION__, i, port->number, result); 152 goto errout; 153 } 154 /* remember this urb so we can kill it when the port is closed */ 155 priv->read_urbp[i] = urb; 156 } 157 goto out; 158 159 errout: 160 /* some error happened, cancel any submitted urbs and clean up anything that 161 got allocated successfully */ 162 163 for ( ; i >= 0; --i) { 164 urb = priv->read_urbp[i]; 165 if (urb) { 166 /* This urb was submitted successfully. So we have to 167 cancel it. 168 Unlinking the urb will invoke read_bulk_callback() 169 with an error status, so its transfer buffer will 170 be freed there */ 171 if (usb_unlink_urb (urb) != -EINPROGRESS) { 172 /* comments in drivers/usb/core/urb.c say this 173 can only happen if the urb was never submitted, 174 or has completed already. 175 Either way we may have to free the transfer 176 buffer here. */ 177 if (urb->transfer_buffer) { 178 kfree (urb->transfer_buffer); 179 urb->transfer_buffer = NULL; 180 } 181 } 182 usb_free_urb (urb); 183 } 184 } 185 186 out: 187 return result; 188} 189 190static void airprime_close(struct usb_serial_port *port, struct file * filp) 191{ 192 struct airprime_private *priv = usb_get_serial_port_data(port); 193 int i; 194 195 dbg("%s - port %d", __FUNCTION__, port->number); 196 197 /* killing the urb will invoke read_bulk_callback() with an error status, 198 so the transfer buffer will be freed there */ 199 for (i = 0; i < NUM_READ_URBS; ++i) { 200 usb_kill_urb (priv->read_urbp[i]); 201 usb_free_urb (priv->read_urbp[i]); 202 } 203 204 /* free up private structure */ 205 kfree (priv); 206 usb_set_serial_port_data(port, NULL); 207} 208 209static int airprime_write(struct usb_serial_port *port, 210 const unsigned char *buf, int count) 211{ 212 struct airprime_private *priv = usb_get_serial_port_data(port); 213 struct usb_serial *serial = port->serial; 214 struct urb *urb; 215 unsigned char *buffer; 216 unsigned long flags; 217 int status; 218 dbg("%s - port %d", __FUNCTION__, port->number); 219 220 spin_lock_irqsave(&priv->lock, flags); 221 if (priv->outstanding_urbs > NUM_WRITE_URBS) { 222 spin_unlock_irqrestore(&priv->lock, flags); 223 dbg("%s - write limit hit\n", __FUNCTION__); 224 return 0; 225 } 226 spin_unlock_irqrestore(&priv->lock, flags); 227 buffer = kmalloc(count, GFP_ATOMIC); 228 if (!buffer) { 229 dev_err(&port->dev, "out of memory\n"); 230 return -ENOMEM; 231 } 232 urb = usb_alloc_urb(0, GFP_ATOMIC); 233 if (!urb) { 234 dev_err(&port->dev, "no more free urbs\n"); 235 kfree (buffer); 236 return -ENOMEM; 237 } 238 memcpy (buffer, buf, count); 239 240 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer); 241 242 usb_fill_bulk_urb(urb, serial->dev, 243 usb_sndbulkpipe(serial->dev, 244 port->bulk_out_endpointAddress), 245 buffer, count, 246 airprime_write_bulk_callback, port); 247 248 /* send it down the pipe */ 249 status = usb_submit_urb(urb, GFP_ATOMIC); 250 if (status) { 251 dev_err(&port->dev, 252 "%s - usb_submit_urb(write bulk) failed with status = %d\n", 253 __FUNCTION__, status); 254 count = status; 255 kfree (buffer); 256 } else { 257 spin_lock_irqsave(&priv->lock, flags); 258 ++priv->outstanding_urbs; 259 spin_unlock_irqrestore(&priv->lock, flags); 260 } 261 /* we are done with this urb, so let the host driver 262 * really free it when it is finished with it */ 263 usb_free_urb (urb); 264 return count; 265} 266 267static struct usb_driver airprime_driver = { 268 .name = "airprime", 269 .probe = usb_serial_probe, 270 .disconnect = usb_serial_disconnect, 271 .id_table = id_table, 272 .no_dynamic_id = 1, 273}; 274 275static struct usb_serial_driver airprime_device = { 276 .driver = { 277 .owner = THIS_MODULE, 278 .name = "airprime", 279 }, 280 .id_table = id_table, 281 .num_interrupt_in = NUM_DONT_CARE, 282 .num_bulk_in = NUM_DONT_CARE, 283 .num_bulk_out = NUM_DONT_CARE, 284 .open = airprime_open, 285 .close = airprime_close, 286 .write = airprime_write, 287}; 288 289static int __init airprime_init(void) 290{ 291 int retval; 292 293 airprime_device.num_ports = 294 (endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS; 295 retval = usb_serial_register(&airprime_device); 296 if (retval) 297 return retval; 298 retval = usb_register(&airprime_driver); 299 if (retval) 300 usb_serial_deregister(&airprime_device); 301 return retval; 302} 303 304static void __exit airprime_exit(void) 305{ 306 dbg("%s", __FUNCTION__); 307 308 usb_deregister(&airprime_driver); 309 usb_serial_deregister(&airprime_device); 310} 311 312module_init(airprime_init); 313module_exit(airprime_exit); 314MODULE_LICENSE("GPL"); 315 316module_param(debug, bool, S_IRUGO | S_IWUSR); 317MODULE_PARM_DESC(debug, "Debug enabled"); 318module_param(buffer_size, int, 0); 319MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)"); 320module_param(endpoints, int, 0); 321MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)");