diff options
| author | Johan Hovold <jhovold@gmail.com> | 2010-05-15 11:53:45 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:48 -0400 |
| commit | 695aaae684e249f9f0e7f1ed4caafa0687dbfa5b (patch) | |
| tree | 9f6ef24b5c62300e3bee5181c2196f5b56633652 /drivers/usb | |
| parent | 56a1df46c19150db0a9b0f0c14e0b1d42e7f32d4 (diff) | |
USB: empeg: reimplement using generic framework
Kill custom read and write implementations (static 16*4k write-urb pool
shared among all ports in system).
Also remove old changelog entries in header (code is now gone, and
these entries can still be retrieved through git).
Compile-only tested.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/serial/empeg.c | 401 |
1 files changed, 13 insertions, 388 deletions
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 5f740a1eacab..504b5585ea45 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
| @@ -13,44 +13,6 @@ | |||
| 13 | * | 13 | * |
| 14 | * See Documentation/usb/usb-serial.txt for more information on using this | 14 | * See Documentation/usb/usb-serial.txt for more information on using this |
| 15 | * driver | 15 | * driver |
| 16 | * | ||
| 17 | * (07/16/2001) gb | ||
| 18 | * remove unused code in empeg_close() (thanks to Oliver Neukum for | ||
| 19 | * pointing this out) and rewrote empeg_set_termios(). | ||
| 20 | * | ||
| 21 | * (05/30/2001) gkh | ||
| 22 | * switched from using spinlock to a semaphore, which fixes lots of | ||
| 23 | * problems. | ||
| 24 | * | ||
| 25 | * (04/08/2001) gb | ||
| 26 | * Identify version on module load. | ||
| 27 | * | ||
| 28 | * (01/22/2001) gb | ||
| 29 | * Added write_room() and chars_in_buffer() support. | ||
| 30 | * | ||
| 31 | * (12/21/2000) gb | ||
| 32 | * Moved termio stuff inside the port->active check. | ||
| 33 | * Moved MOD_DEC_USE_COUNT to end of empeg_close(). | ||
| 34 | * | ||
| 35 | * (12/03/2000) gb | ||
| 36 | * Added tty->ldisc.set_termios(port, tty, NULL) to empeg_open(). | ||
| 37 | * This notifies the tty driver that the termios have changed. | ||
| 38 | * | ||
| 39 | * (11/13/2000) gb | ||
| 40 | * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to | ||
| 41 | * empeg_open() (It only needs to be set once - Doh!) | ||
| 42 | * | ||
| 43 | * (11/11/2000) gb | ||
| 44 | * Updated to work with id_table structure. | ||
| 45 | * | ||
| 46 | * (11/04/2000) gb | ||
| 47 | * Forked this from visor.c, and hacked it up to work with an | ||
| 48 | * Empeg ltd. empeg-car player. Constructive criticism welcomed. | ||
| 49 | * I would like to say, 'Thank You' to Greg Kroah-Hartman for the | ||
| 50 | * use of his code, and for his guidance, advice and patience. :) | ||
| 51 | * A 'Thank You' is in order for John Ripley of Empeg ltd for his | ||
| 52 | * advice, and patience too. | ||
| 53 | * | ||
| 54 | */ | 16 | */ |
| 55 | 17 | ||
| 56 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| @@ -71,7 +33,7 @@ static int debug; | |||
| 71 | /* | 33 | /* |
| 72 | * Version Information | 34 | * Version Information |
| 73 | */ | 35 | */ |
| 74 | #define DRIVER_VERSION "v1.2" | 36 | #define DRIVER_VERSION "v1.3" |
| 75 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>" | 37 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>" |
| 76 | #define DRIVER_DESC "USB Empeg Mark I/II Driver" | 38 | #define DRIVER_DESC "USB Empeg Mark I/II Driver" |
| 77 | 39 | ||
| @@ -79,19 +41,8 @@ static int debug; | |||
| 79 | #define EMPEG_PRODUCT_ID 0x0001 | 41 | #define EMPEG_PRODUCT_ID 0x0001 |
| 80 | 42 | ||
| 81 | /* function prototypes for an empeg-car player */ | 43 | /* function prototypes for an empeg-car player */ |
| 82 | static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port); | ||
| 83 | static void empeg_close(struct usb_serial_port *port); | ||
| 84 | static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 85 | const unsigned char *buf, | ||
| 86 | int count); | ||
| 87 | static int empeg_write_room(struct tty_struct *tty); | ||
| 88 | static int empeg_chars_in_buffer(struct tty_struct *tty); | ||
| 89 | static void empeg_throttle(struct tty_struct *tty); | ||
| 90 | static void empeg_unthrottle(struct tty_struct *tty); | ||
| 91 | static int empeg_startup(struct usb_serial *serial); | 44 | static int empeg_startup(struct usb_serial *serial); |
| 92 | static void empeg_init_termios(struct tty_struct *tty); | 45 | static void empeg_init_termios(struct tty_struct *tty); |
| 93 | static void empeg_write_bulk_callback(struct urb *urb); | ||
| 94 | static void empeg_read_bulk_callback(struct urb *urb); | ||
| 95 | 46 | ||
| 96 | static const struct usb_device_id id_table[] = { | 47 | static const struct usb_device_id id_table[] = { |
| 97 | { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, | 48 | { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, |
| @@ -105,7 +56,7 @@ static struct usb_driver empeg_driver = { | |||
| 105 | .probe = usb_serial_probe, | 56 | .probe = usb_serial_probe, |
| 106 | .disconnect = usb_serial_disconnect, | 57 | .disconnect = usb_serial_disconnect, |
| 107 | .id_table = id_table, | 58 | .id_table = id_table, |
| 108 | .no_dynamic_id = 1, | 59 | .no_dynamic_id = 1, |
| 109 | }; | 60 | }; |
| 110 | 61 | ||
| 111 | static struct usb_serial_driver empeg_device = { | 62 | static struct usb_serial_driver empeg_device = { |
| @@ -114,291 +65,16 @@ static struct usb_serial_driver empeg_device = { | |||
| 114 | .name = "empeg", | 65 | .name = "empeg", |
| 115 | }, | 66 | }, |
| 116 | .id_table = id_table, | 67 | .id_table = id_table, |
| 117 | .usb_driver = &empeg_driver, | 68 | .usb_driver = &empeg_driver, |
| 118 | .num_ports = 1, | 69 | .num_ports = 1, |
| 119 | .open = empeg_open, | 70 | .bulk_out_size = 256, |
| 120 | .close = empeg_close, | 71 | .throttle = usb_serial_generic_throttle, |
| 121 | .throttle = empeg_throttle, | 72 | .unthrottle = usb_serial_generic_unthrottle, |
| 122 | .unthrottle = empeg_unthrottle, | ||
| 123 | .attach = empeg_startup, | 73 | .attach = empeg_startup, |
| 124 | .init_termios = empeg_init_termios, | 74 | .init_termios = empeg_init_termios, |
| 125 | .write = empeg_write, | ||
| 126 | .write_room = empeg_write_room, | ||
| 127 | .chars_in_buffer = empeg_chars_in_buffer, | ||
| 128 | .write_bulk_callback = empeg_write_bulk_callback, | ||
| 129 | .read_bulk_callback = empeg_read_bulk_callback, | ||
| 130 | }; | 75 | }; |
| 131 | 76 | ||
| 132 | #define NUM_URBS 16 | 77 | static int empeg_startup(struct usb_serial *serial) |
| 133 | #define URB_TRANSFER_BUFFER_SIZE 4096 | ||
| 134 | |||
| 135 | static struct urb *write_urb_pool[NUM_URBS]; | ||
| 136 | static spinlock_t write_urb_pool_lock; | ||
| 137 | static int bytes_in; | ||
| 138 | static int bytes_out; | ||
| 139 | |||
| 140 | /****************************************************************************** | ||
| 141 | * Empeg specific driver functions | ||
| 142 | ******************************************************************************/ | ||
| 143 | static int empeg_open(struct tty_struct *tty,struct usb_serial_port *port) | ||
| 144 | { | ||
| 145 | struct usb_serial *serial = port->serial; | ||
| 146 | int result = 0; | ||
| 147 | |||
| 148 | dbg("%s - port %d", __func__, port->number); | ||
| 149 | |||
| 150 | bytes_in = 0; | ||
| 151 | bytes_out = 0; | ||
| 152 | |||
| 153 | /* Start reading from the device */ | ||
| 154 | usb_fill_bulk_urb( | ||
| 155 | port->read_urb, | ||
| 156 | serial->dev, | ||
| 157 | usb_rcvbulkpipe(serial->dev, | ||
| 158 | port->bulk_in_endpointAddress), | ||
| 159 | port->read_urb->transfer_buffer, | ||
| 160 | port->read_urb->transfer_buffer_length, | ||
| 161 | empeg_read_bulk_callback, | ||
| 162 | port); | ||
| 163 | |||
| 164 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
| 165 | |||
| 166 | if (result) | ||
| 167 | dev_err(&port->dev, | ||
| 168 | "%s - failed submitting read urb, error %d\n", | ||
| 169 | __func__, result); | ||
| 170 | |||
| 171 | return result; | ||
| 172 | } | ||
| 173 | |||
| 174 | |||
| 175 | static void empeg_close(struct usb_serial_port *port) | ||
| 176 | { | ||
| 177 | dbg("%s - port %d", __func__, port->number); | ||
| 178 | |||
| 179 | /* shutdown our bulk read */ | ||
| 180 | usb_kill_urb(port->read_urb); | ||
| 181 | /* Uncomment the following line if you want to see some statistics in your syslog */ | ||
| 182 | /* dev_info (&port->dev, "Bytes In = %d Bytes Out = %d\n", bytes_in, bytes_out); */ | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 187 | const unsigned char *buf, int count) | ||
| 188 | { | ||
| 189 | struct usb_serial *serial = port->serial; | ||
| 190 | struct urb *urb; | ||
| 191 | const unsigned char *current_position = buf; | ||
| 192 | unsigned long flags; | ||
| 193 | int status; | ||
| 194 | int i; | ||
| 195 | int bytes_sent = 0; | ||
| 196 | int transfer_size; | ||
| 197 | |||
| 198 | dbg("%s - port %d", __func__, port->number); | ||
| 199 | |||
| 200 | while (count > 0) { | ||
| 201 | /* try to find a free urb in our list of them */ | ||
| 202 | urb = NULL; | ||
| 203 | |||
| 204 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
| 205 | |||
| 206 | for (i = 0; i < NUM_URBS; ++i) { | ||
| 207 | if (write_urb_pool[i]->status != -EINPROGRESS) { | ||
| 208 | urb = write_urb_pool[i]; | ||
| 209 | break; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
| 214 | |||
| 215 | if (urb == NULL) { | ||
| 216 | dbg("%s - no more free urbs", __func__); | ||
| 217 | goto exit; | ||
| 218 | } | ||
| 219 | |||
| 220 | if (urb->transfer_buffer == NULL) { | ||
| 221 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); | ||
| 222 | if (urb->transfer_buffer == NULL) { | ||
| 223 | dev_err(&port->dev, | ||
| 224 | "%s no more kernel memory...\n", | ||
| 225 | __func__); | ||
| 226 | goto exit; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); | ||
| 231 | |||
| 232 | memcpy(urb->transfer_buffer, current_position, transfer_size); | ||
| 233 | |||
| 234 | usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer); | ||
| 235 | |||
| 236 | /* build up our urb */ | ||
| 237 | usb_fill_bulk_urb( | ||
| 238 | urb, | ||
| 239 | serial->dev, | ||
| 240 | usb_sndbulkpipe(serial->dev, | ||
| 241 | port->bulk_out_endpointAddress), | ||
| 242 | urb->transfer_buffer, | ||
| 243 | transfer_size, | ||
| 244 | empeg_write_bulk_callback, | ||
| 245 | port); | ||
| 246 | |||
| 247 | /* send it down the pipe */ | ||
| 248 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 249 | if (status) { | ||
| 250 | dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); | ||
| 251 | bytes_sent = status; | ||
| 252 | break; | ||
| 253 | } | ||
| 254 | |||
| 255 | current_position += transfer_size; | ||
| 256 | bytes_sent += transfer_size; | ||
| 257 | count -= transfer_size; | ||
| 258 | bytes_out += transfer_size; | ||
| 259 | |||
| 260 | } | ||
| 261 | exit: | ||
| 262 | return bytes_sent; | ||
| 263 | } | ||
| 264 | |||
| 265 | |||
| 266 | static int empeg_write_room(struct tty_struct *tty) | ||
| 267 | { | ||
| 268 | struct usb_serial_port *port = tty->driver_data; | ||
| 269 | unsigned long flags; | ||
| 270 | int i; | ||
| 271 | int room = 0; | ||
| 272 | |||
| 273 | dbg("%s - port %d", __func__, port->number); | ||
| 274 | |||
| 275 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
| 276 | /* tally up the number of bytes available */ | ||
| 277 | for (i = 0; i < NUM_URBS; ++i) { | ||
| 278 | if (write_urb_pool[i]->status != -EINPROGRESS) | ||
| 279 | room += URB_TRANSFER_BUFFER_SIZE; | ||
| 280 | } | ||
| 281 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
| 282 | dbg("%s - returns %d", __func__, room); | ||
| 283 | return room; | ||
| 284 | |||
| 285 | } | ||
| 286 | |||
| 287 | |||
| 288 | static int empeg_chars_in_buffer(struct tty_struct *tty) | ||
| 289 | { | ||
| 290 | struct usb_serial_port *port = tty->driver_data; | ||
| 291 | unsigned long flags; | ||
| 292 | int i; | ||
| 293 | int chars = 0; | ||
| 294 | |||
| 295 | dbg("%s - port %d", __func__, port->number); | ||
| 296 | |||
| 297 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
| 298 | |||
| 299 | /* tally up the number of bytes waiting */ | ||
| 300 | for (i = 0; i < NUM_URBS; ++i) { | ||
| 301 | if (write_urb_pool[i]->status == -EINPROGRESS) | ||
| 302 | chars += URB_TRANSFER_BUFFER_SIZE; | ||
| 303 | } | ||
| 304 | |||
| 305 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
| 306 | dbg("%s - returns %d", __func__, chars); | ||
| 307 | return chars; | ||
| 308 | } | ||
| 309 | |||
| 310 | |||
| 311 | static void empeg_write_bulk_callback(struct urb *urb) | ||
| 312 | { | ||
| 313 | struct usb_serial_port *port = urb->context; | ||
| 314 | int status = urb->status; | ||
| 315 | |||
| 316 | dbg("%s - port %d", __func__, port->number); | ||
| 317 | |||
| 318 | if (status) { | ||
| 319 | dbg("%s - nonzero write bulk status received: %d", | ||
| 320 | __func__, status); | ||
| 321 | return; | ||
| 322 | } | ||
| 323 | |||
| 324 | usb_serial_port_softint(port); | ||
| 325 | } | ||
| 326 | |||
| 327 | |||
| 328 | static void empeg_read_bulk_callback(struct urb *urb) | ||
| 329 | { | ||
| 330 | struct usb_serial_port *port = urb->context; | ||
| 331 | struct tty_struct *tty; | ||
| 332 | unsigned char *data = urb->transfer_buffer; | ||
| 333 | int result; | ||
| 334 | int status = urb->status; | ||
| 335 | |||
| 336 | dbg("%s - port %d", __func__, port->number); | ||
| 337 | |||
| 338 | if (status) { | ||
| 339 | dbg("%s - nonzero read bulk status received: %d", | ||
| 340 | __func__, status); | ||
| 341 | return; | ||
| 342 | } | ||
| 343 | |||
| 344 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
| 345 | urb->actual_length, data); | ||
| 346 | tty = tty_port_tty_get(&port->port); | ||
| 347 | |||
| 348 | if (urb->actual_length) { | ||
| 349 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
| 350 | tty_flip_buffer_push(tty); | ||
| 351 | bytes_in += urb->actual_length; | ||
| 352 | } | ||
| 353 | tty_kref_put(tty); | ||
| 354 | |||
| 355 | /* Continue trying to always read */ | ||
| 356 | usb_fill_bulk_urb( | ||
| 357 | port->read_urb, | ||
| 358 | port->serial->dev, | ||
| 359 | usb_rcvbulkpipe(port->serial->dev, | ||
| 360 | port->bulk_in_endpointAddress), | ||
| 361 | port->read_urb->transfer_buffer, | ||
| 362 | port->read_urb->transfer_buffer_length, | ||
| 363 | empeg_read_bulk_callback, | ||
| 364 | port); | ||
| 365 | |||
| 366 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
| 367 | |||
| 368 | if (result) | ||
| 369 | dev_err(&urb->dev->dev, | ||
| 370 | "%s - failed resubmitting read urb, error %d\n", | ||
| 371 | __func__, result); | ||
| 372 | |||
| 373 | return; | ||
| 374 | |||
| 375 | } | ||
| 376 | |||
| 377 | |||
| 378 | static void empeg_throttle(struct tty_struct *tty) | ||
| 379 | { | ||
| 380 | struct usb_serial_port *port = tty->driver_data; | ||
| 381 | dbg("%s - port %d", __func__, port->number); | ||
| 382 | usb_kill_urb(port->read_urb); | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | static void empeg_unthrottle(struct tty_struct *tty) | ||
| 387 | { | ||
| 388 | struct usb_serial_port *port = tty->driver_data; | ||
| 389 | int result; | ||
| 390 | dbg("%s - port %d", __func__, port->number); | ||
| 391 | |||
| 392 | port->read_urb->dev = port->serial->dev; | ||
| 393 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
| 394 | if (result) | ||
| 395 | dev_err(&port->dev, | ||
| 396 | "%s - failed submitting read urb, error %d\n", | ||
| 397 | __func__, result); | ||
| 398 | } | ||
| 399 | |||
| 400 | |||
| 401 | static int empeg_startup(struct usb_serial *serial) | ||
| 402 | { | 78 | { |
| 403 | int r; | 79 | int r; |
| 404 | 80 | ||
| @@ -414,10 +90,8 @@ static int empeg_startup(struct usb_serial *serial) | |||
| 414 | 90 | ||
| 415 | /* continue on with initialization */ | 91 | /* continue on with initialization */ |
| 416 | return r; | 92 | return r; |
| 417 | |||
| 418 | } | 93 | } |
| 419 | 94 | ||
| 420 | |||
| 421 | static void empeg_init_termios(struct tty_struct *tty) | 95 | static void empeg_init_termios(struct tty_struct *tty) |
| 422 | { | 96 | { |
| 423 | struct ktermios *termios = tty->termios; | 97 | struct ktermios *termios = tty->termios; |
| @@ -462,77 +136,28 @@ static void empeg_init_termios(struct tty_struct *tty) | |||
| 462 | tty_encode_baud_rate(tty, 115200, 115200); | 136 | tty_encode_baud_rate(tty, 115200, 115200); |
| 463 | } | 137 | } |
| 464 | 138 | ||
| 465 | |||
| 466 | static int __init empeg_init(void) | 139 | static int __init empeg_init(void) |
| 467 | { | 140 | { |
| 468 | struct urb *urb; | 141 | int retval; |
| 469 | int i, retval; | ||
| 470 | |||
| 471 | /* create our write urb pool and transfer buffers */ | ||
| 472 | spin_lock_init(&write_urb_pool_lock); | ||
| 473 | for (i = 0; i < NUM_URBS; ++i) { | ||
| 474 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 475 | write_urb_pool[i] = urb; | ||
| 476 | if (urb == NULL) { | ||
| 477 | printk(KERN_ERR "empeg: No more urbs???\n"); | ||
| 478 | continue; | ||
| 479 | } | ||
| 480 | |||
| 481 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, | ||
| 482 | GFP_KERNEL); | ||
| 483 | if (!urb->transfer_buffer) { | ||
| 484 | printk(KERN_ERR "empeg: %s - out of memory for urb " | ||
| 485 | "buffers.", __func__); | ||
| 486 | continue; | ||
| 487 | } | ||
| 488 | } | ||
| 489 | 142 | ||
| 490 | retval = usb_serial_register(&empeg_device); | 143 | retval = usb_serial_register(&empeg_device); |
| 491 | if (retval) | 144 | if (retval) |
| 492 | goto failed_usb_serial_register; | 145 | return retval; |
| 493 | retval = usb_register(&empeg_driver); | 146 | retval = usb_register(&empeg_driver); |
| 494 | if (retval) | 147 | if (retval) { |
| 495 | goto failed_usb_register; | 148 | usb_serial_deregister(&empeg_device); |
| 496 | 149 | return retval; | |
| 150 | } | ||
| 497 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 151 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" |
| 498 | DRIVER_DESC "\n"); | 152 | DRIVER_DESC "\n"); |
| 499 | 153 | ||
| 500 | return 0; | 154 | return 0; |
| 501 | failed_usb_register: | ||
| 502 | usb_serial_deregister(&empeg_device); | ||
| 503 | failed_usb_serial_register: | ||
| 504 | for (i = 0; i < NUM_URBS; ++i) { | ||
| 505 | if (write_urb_pool[i]) { | ||
| 506 | kfree(write_urb_pool[i]->transfer_buffer); | ||
| 507 | usb_free_urb(write_urb_pool[i]); | ||
| 508 | } | ||
| 509 | } | ||
| 510 | return retval; | ||
| 511 | } | 155 | } |
| 512 | 156 | ||
| 513 | |||
| 514 | static void __exit empeg_exit(void) | 157 | static void __exit empeg_exit(void) |
| 515 | { | 158 | { |
| 516 | int i; | ||
| 517 | unsigned long flags; | ||
| 518 | |||
| 519 | usb_deregister(&empeg_driver); | 159 | usb_deregister(&empeg_driver); |
| 520 | usb_serial_deregister(&empeg_device); | 160 | usb_serial_deregister(&empeg_device); |
| 521 | |||
| 522 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
| 523 | |||
| 524 | for (i = 0; i < NUM_URBS; ++i) { | ||
| 525 | if (write_urb_pool[i]) { | ||
| 526 | /* FIXME - uncomment the following usb_kill_urb call | ||
| 527 | * when the host controllers get fixed to set urb->dev | ||
| 528 | * = NULL after the urb is finished. Otherwise this | ||
| 529 | * call oopses. */ | ||
| 530 | /* usb_kill_urb(write_urb_pool[i]); */ | ||
| 531 | kfree(write_urb_pool[i]->transfer_buffer); | ||
| 532 | usb_free_urb(write_urb_pool[i]); | ||
| 533 | } | ||
| 534 | } | ||
| 535 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
| 536 | } | 161 | } |
| 537 | 162 | ||
| 538 | 163 | ||
