generic.c 16.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * USB Serial Converter Generic functions
 *
 * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License version
 *	2 as published by the Free Software Foundation.
 *
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
15
#include <linux/sysrq.h>
L
Linus Torvalds 已提交
16 17 18 19 20
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb.h>
21
#include <linux/usb/serial.h>
A
Alan Cox 已提交
22
#include <linux/uaccess.h>
23
#include <linux/kfifo.h>
24
#include <linux/serial.h>
25

L
Linus Torvalds 已提交
26 27 28
static int debug;

#ifdef CONFIG_USB_SERIAL_GENERIC
29 30 31 32

static int generic_probe(struct usb_interface *interface,
			 const struct usb_device_id *id);

L
Linus Torvalds 已提交
33 34 35 36 37 38 39 40 41 42 43
static __u16 vendor  = 0x05f9;
static __u16 product = 0xffff;

module_param(vendor, ushort, 0);
MODULE_PARM_DESC(vendor, "User specified USB idVendor");

module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified USB idProduct");

static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */

44 45
/* we want to look at all devices, as the vendor/product id can change
 * depending on the command line argument */
46
static const struct usb_device_id generic_serial_ids[] = {
47 48 49 50 51 52 53 54 55 56 57 58
	{.driver_info = 42},
	{}
};

static struct usb_driver generic_driver = {
	.name =		"usbserial_generic",
	.probe =	generic_probe,
	.disconnect =	usb_serial_disconnect,
	.id_table =	generic_serial_ids,
	.no_dynamic_id =	1,
};

L
Linus Torvalds 已提交
59
/* All of the device info needed for the Generic Serial Converter */
60
struct usb_serial_driver usb_serial_generic_device = {
61 62
	.driver = {
		.owner =	THIS_MODULE,
63
		.name =		"generic",
64
	},
L
Linus Torvalds 已提交
65
	.id_table =		generic_device_ids,
66
	.usb_driver = 		&generic_driver,
L
Linus Torvalds 已提交
67
	.num_ports =		1,
68 69
	.disconnect =		usb_serial_generic_disconnect,
	.release =		usb_serial_generic_release,
70 71
	.throttle =		usb_serial_generic_throttle,
	.unthrottle =		usb_serial_generic_unthrottle,
72
	.resume =		usb_serial_generic_resume,
L
Linus Torvalds 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86
};

static int generic_probe(struct usb_interface *interface,
			       const struct usb_device_id *id)
{
	const struct usb_device_id *id_pattern;

	id_pattern = usb_match_id(interface, generic_device_ids);
	if (id_pattern != NULL)
		return usb_serial_probe(interface, id);
	return -ENODEV;
}
#endif

A
Alan Cox 已提交
87
int usb_serial_generic_register(int _debug)
L
Linus Torvalds 已提交
88 89 90 91 92 93 94
{
	int retval = 0;

	debug = _debug;
#ifdef CONFIG_USB_SERIAL_GENERIC
	generic_device_ids[0].idVendor = vendor;
	generic_device_ids[0].idProduct = product;
A
Alan Cox 已提交
95 96
	generic_device_ids[0].match_flags =
		USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
L
Linus Torvalds 已提交
97 98

	/* register our generic driver with ourselves */
A
Alan Cox 已提交
99
	retval = usb_serial_register(&usb_serial_generic_device);
L
Linus Torvalds 已提交
100 101 102 103 104 105 106 107 108 109
	if (retval)
		goto exit;
	retval = usb_register(&generic_driver);
	if (retval)
		usb_serial_deregister(&usb_serial_generic_device);
exit:
#endif
	return retval;
}

A
Alan Cox 已提交
110
void usb_serial_generic_deregister(void)
L
Linus Torvalds 已提交
111 112 113 114
{
#ifdef CONFIG_USB_SERIAL_GENERIC
	/* remove our generic driver */
	usb_deregister(&generic_driver);
A
Alan Cox 已提交
115
	usb_serial_deregister(&usb_serial_generic_device);
L
Linus Torvalds 已提交
116 117 118
#endif
}

119
int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
L
Linus Torvalds 已提交
120 121 122
{
	struct usb_serial *serial = port->serial;
	int result = 0;
123
	unsigned long flags;
L
Linus Torvalds 已提交
124

125
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
126

127 128 129 130 131 132 133
	/* clear the throttle flags */
	spin_lock_irqsave(&port->lock, flags);
	port->throttled = 0;
	port->throttle_req = 0;
	spin_unlock_irqrestore(&port->lock, flags);

	/* if we have a bulk endpoint, start reading from it */
134
	if (port->bulk_in_size) {
L
Linus Torvalds 已提交
135
		/* Start reading from the device */
A
Alan Cox 已提交
136 137 138
		usb_fill_bulk_urb(port->read_urb, serial->dev,
				   usb_rcvbulkpipe(serial->dev,
						port->bulk_in_endpointAddress),
L
Linus Torvalds 已提交
139 140 141 142 143 144 145 146
				   port->read_urb->transfer_buffer,
				   port->read_urb->transfer_buffer_length,
				   ((serial->type->read_bulk_callback) ?
				     serial->type->read_bulk_callback :
				     usb_serial_generic_read_bulk_callback),
				   port);
		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
		if (result)
A
Alan Cox 已提交
147 148 149
			dev_err(&port->dev,
			    "%s - failed resubmitting read urb, error %d\n",
							__func__, result);
L
Linus Torvalds 已提交
150 151 152 153
	}

	return result;
}
154
EXPORT_SYMBOL_GPL(usb_serial_generic_open);
L
Linus Torvalds 已提交
155

A
Alan Cox 已提交
156
static void generic_cleanup(struct usb_serial_port *port)
L
Linus Torvalds 已提交
157 158 159
{
	struct usb_serial *serial = port->serial;

160
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
161 162

	if (serial->dev) {
163 164
		/* shutdown any bulk transfers that might be going on */
		if (port->bulk_out_size)
L
Linus Torvalds 已提交
165
			usb_kill_urb(port->write_urb);
166
		if (port->bulk_in_size)
L
Linus Torvalds 已提交
167 168 169 170
			usb_kill_urb(port->read_urb);
	}
}

171
void usb_serial_generic_close(struct usb_serial_port *port)
L
Linus Torvalds 已提交
172
{
173
	dbg("%s - port %d", __func__, port->number);
A
Alan Cox 已提交
174
	generic_cleanup(port);
L
Linus Torvalds 已提交
175 176
}

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
static int usb_serial_multi_urb_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
{
	unsigned long flags;
	struct urb *urb;
	unsigned char *buffer;
	int status;
	int towrite;
	int bwrite = 0;

	dbg("%s - port %d", __func__, port->number);

	if (count == 0)
		dbg("%s - write request of 0 bytes", __func__);

	while (count > 0) {
		towrite = (count > port->bulk_out_size) ?
			port->bulk_out_size : count;
		spin_lock_irqsave(&port->lock, flags);
		if (port->urbs_in_flight >
		    port->serial->type->max_in_flight_urbs) {
			spin_unlock_irqrestore(&port->lock, flags);
199
			dbg("%s - write limit hit", __func__);
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
			return bwrite;
		}
		port->tx_bytes_flight += towrite;
		port->urbs_in_flight++;
		spin_unlock_irqrestore(&port->lock, flags);

		buffer = kmalloc(towrite, GFP_ATOMIC);
		if (!buffer) {
			dev_err(&port->dev,
			"%s ran out of kernel memory for urb ...\n", __func__);
			goto error_no_buffer;
		}

		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (!urb) {
			dev_err(&port->dev, "%s - no more free urbs\n",
				__func__);
			goto error_no_urb;
		}

		/* Copy data */
		memcpy(buffer, buf + bwrite, towrite);
		usb_serial_debug_data(debug, &port->dev, __func__,
				      towrite, buffer);
		/* fill the buffer and send it */
		usb_fill_bulk_urb(urb, port->serial->dev,
			usb_sndbulkpipe(port->serial->dev,
					port->bulk_out_endpointAddress),
			buffer, towrite,
			usb_serial_generic_write_bulk_callback, port);

		status = usb_submit_urb(urb, GFP_ATOMIC);
		if (status) {
			dev_err(&port->dev,
				"%s - failed submitting write urb, error %d\n",
				__func__, status);
			goto error;
		}

		/* This urb is the responsibility of the host driver now */
		usb_free_urb(urb);
		dbg("%s write: %d", __func__, towrite);
		count -= towrite;
		bwrite += towrite;
	}
	return bwrite;

error:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&port->lock, flags);
	port->urbs_in_flight--;
	port->tx_bytes_flight -= towrite;
	spin_unlock_irqrestore(&port->lock, flags);
	return bwrite;
}

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
/**
 * usb_serial_generic_write_start - kick off an URB write
 * @port:	Pointer to the &struct usb_serial_port data
 *
 * Returns the number of bytes queued on success. This will be zero if there
 * was nothing to send. Otherwise, it returns a negative errno value
 */
static int usb_serial_generic_write_start(struct usb_serial_port *port)
{
	struct usb_serial *serial = port->serial;
	unsigned char *data;
	int result;
	int count;
	unsigned long flags;
	bool start_io;

	/* Atomically determine whether we can and need to start a USB
	 * operation. */
	spin_lock_irqsave(&port->lock, flags);
	if (port->write_urb_busy)
		start_io = false;
	else {
281
		start_io = (kfifo_len(&port->write_fifo) != 0);
282 283 284 285 286 287 288 289
		port->write_urb_busy = start_io;
	}
	spin_unlock_irqrestore(&port->lock, flags);

	if (!start_io)
		return 0;

	data = port->write_urb->transfer_buffer;
290
	count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock);
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
	usb_serial_debug_data(debug, &port->dev, __func__, count, data);

	/* set up our urb */
	usb_fill_bulk_urb(port->write_urb, serial->dev,
			   usb_sndbulkpipe(serial->dev,
				port->bulk_out_endpointAddress),
			   port->write_urb->transfer_buffer, count,
			   ((serial->type->write_bulk_callback) ?
			     serial->type->write_bulk_callback :
			     usb_serial_generic_write_bulk_callback),
			   port);

	/* send the data out the bulk port */
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	if (result) {
		dev_err(&port->dev,
			"%s - failed submitting write urb, error %d\n",
						__func__, result);
		/* don't have to grab the lock here, as we will
		   retry if != 0 */
		port->write_urb_busy = 0;
312 313
		return result;
	}
314

315 316 317 318 319
	spin_lock_irqsave(&port->lock, flags);
	port->tx_bytes_flight += count;
	spin_unlock_irqrestore(&port->lock, flags);

	return count;
320 321 322 323 324 325 326 327 328 329 330 331 332
}

/**
 * usb_serial_generic_write - generic write function for serial USB devices
 * @tty:	Pointer to &struct tty_struct for the device
 * @port:	Pointer to the &usb_serial_port structure for the device
 * @buf:	Pointer to the data to write
 * @count:	Number of bytes to write
 *
 * Returns the number of characters actually written, which may be anything
 * from zero to @count. If an error occurs, it returns the negative errno
 * value.
 */
A
Alan Cox 已提交
333 334
int usb_serial_generic_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
L
Linus Torvalds 已提交
335 336 337 338
{
	struct usb_serial *serial = port->serial;
	int result;

339
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
340

341 342 343 344
	/* only do something if we have a bulk out endpoint */
	if (!port->bulk_out_size)
		return -ENODEV;

L
Linus Torvalds 已提交
345
	if (count == 0) {
346
		dbg("%s - write request of 0 bytes", __func__);
A
Alan Cox 已提交
347
		return 0;
L
Linus Torvalds 已提交
348 349
	}

350 351 352
	if (serial->type->max_in_flight_urbs)
		return usb_serial_multi_urb_write(tty, port,
						  buf, count);
L
Linus Torvalds 已提交
353

354
	count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
355
	result = usb_serial_generic_write_start(port);
L
Linus Torvalds 已提交
356

357 358
	if (result >= 0)
		result = count;
L
Linus Torvalds 已提交
359

360
	return result;
L
Linus Torvalds 已提交
361
}
362
EXPORT_SYMBOL_GPL(usb_serial_generic_write);
L
Linus Torvalds 已提交
363

A
Alan Cox 已提交
364
int usb_serial_generic_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
365
{
A
Alan Cox 已提交
366
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
367
	struct usb_serial *serial = port->serial;
368
	unsigned long flags;
L
Linus Torvalds 已提交
369 370
	int room = 0;

371
	dbg("%s - port %d", __func__, port->number);
372 373 374 375

	if (!port->bulk_out_size)
		return 0;

376 377 378
	spin_lock_irqsave(&port->lock, flags);
	if (serial->type->max_in_flight_urbs) {
		if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
379 380 381
			room = port->bulk_out_size *
				(serial->type->max_in_flight_urbs -
				 port->urbs_in_flight);
382
	} else {
383
		room = kfifo_avail(&port->write_fifo);
384
	}
385
	spin_unlock_irqrestore(&port->lock, flags);
L
Linus Torvalds 已提交
386

387
	dbg("%s - returns %d", __func__, room);
388
	return room;
L
Linus Torvalds 已提交
389 390
}

A
Alan Cox 已提交
391
int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
392
{
A
Alan Cox 已提交
393
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
394
	struct usb_serial *serial = port->serial;
395
	unsigned long flags;
396
	int chars;
L
Linus Torvalds 已提交
397

398
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
399

400 401 402
	if (!port->bulk_out_size)
		return 0;

403 404
	spin_lock_irqsave(&port->lock, flags);
	if (serial->type->max_in_flight_urbs)
405
		chars = port->tx_bytes_flight;
406
	else
407
		chars = kfifo_len(&port->write_fifo) + port->tx_bytes_flight;
408
	spin_unlock_irqrestore(&port->lock, flags);
L
Linus Torvalds 已提交
409

410
	dbg("%s - returns %d", __func__, chars);
A
Alan Cox 已提交
411
	return chars;
L
Linus Torvalds 已提交
412 413
}

414

415 416
void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,
			gfp_t mem_flags)
L
Linus Torvalds 已提交
417
{
418
	struct urb *urb = port->read_urb;
419
	struct usb_serial *serial = port->serial;
L
Linus Torvalds 已提交
420 421
	int result;

422
	/* Continue reading from device */
A
Alan Cox 已提交
423 424 425
	usb_fill_bulk_urb(urb, serial->dev,
			   usb_rcvbulkpipe(serial->dev,
					port->bulk_in_endpointAddress),
426 427
			   urb->transfer_buffer,
			   urb->transfer_buffer_length,
A
Alan Cox 已提交
428 429
			   ((serial->type->read_bulk_callback) ?
			     serial->type->read_bulk_callback :
L
Linus Torvalds 已提交
430
			     usb_serial_generic_read_bulk_callback), port);
431

432
	result = usb_submit_urb(urb, mem_flags);
433
	if (result && result != -EPERM) {
A
Alan Cox 已提交
434 435 436
		dev_err(&port->dev,
			"%s - failed resubmitting read urb, error %d\n",
							__func__, result);
437
	}
L
Linus Torvalds 已提交
438
}
439
EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb);
440

441
/* Push data to tty layer and resubmit the bulk read URB */
A
Alan Cox 已提交
442
static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
443 444
{
	struct urb *urb = port->read_urb;
A
Alan Cox 已提交
445
	struct tty_struct *tty = tty_port_tty_get(&port->port);
446 447 448 449 450
	char *ch = (char *)urb->transfer_buffer;
	int i;

	if (!tty)
		goto done;
451

452 453 454
	/* The per character mucking around with sysrq path it too slow for
	   stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases
	   where the USB serial is not a console anyway */
455
	if (!port->port.console || !port->sysrq)
456 457 458 459
		tty_insert_flip_string(tty, ch, urb->actual_length);
	else {
		/* Push data to tty */
		for (i = 0; i < urb->actual_length; i++, ch++) {
A
Alan Cox 已提交
460
			if (!usb_serial_handle_sysrq_char(tty, port, *ch))
461 462
				tty_insert_flip_char(tty, *ch, TTY_NORMAL);
		}
463
	}
464
	tty_flip_buffer_push(tty);
A
Alan Cox 已提交
465
	tty_kref_put(tty);
466 467
done:
	usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC);
468 469
}

A
Alan Cox 已提交
470
void usb_serial_generic_read_bulk_callback(struct urb *urb)
471
{
472
	struct usb_serial_port *port = urb->context;
473
	unsigned char *data = urb->transfer_buffer;
474
	int status = urb->status;
475
	unsigned long flags;
476

477
	dbg("%s - port %d", __func__, port->number);
478

479 480
	if (unlikely(status != 0)) {
		dbg("%s - nonzero read bulk status received: %d",
481
		    __func__, status);
482 483 484
		return;
	}

A
Alan Cox 已提交
485 486
	usb_serial_debug_data(debug, &port->dev, __func__,
						urb->actual_length, data);
487 488

	/* Throttle the device if requested by tty */
489
	spin_lock_irqsave(&port->lock, flags);
A
Alan Cox 已提交
490 491
	port->throttled = port->throttle_req;
	if (!port->throttled) {
492
		spin_unlock_irqrestore(&port->lock, flags);
493
		flush_and_resubmit_read_urb(port);
A
Alan Cox 已提交
494
	} else
495
		spin_unlock_irqrestore(&port->lock, flags);
496
}
497
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
L
Linus Torvalds 已提交
498

A
Alan Cox 已提交
499
void usb_serial_generic_write_bulk_callback(struct urb *urb)
L
Linus Torvalds 已提交
500
{
501
	unsigned long flags;
502
	struct usb_serial_port *port = urb->context;
503
	int status = urb->status;
L
Linus Torvalds 已提交
504

505
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
506

507
	if (port->serial->type->max_in_flight_urbs) {
508 509
		kfree(urb->transfer_buffer);

510 511 512 513 514 515 516
		spin_lock_irqsave(&port->lock, flags);
		--port->urbs_in_flight;
		port->tx_bytes_flight -= urb->transfer_buffer_length;
		if (port->urbs_in_flight < 0)
			port->urbs_in_flight = 0;
		spin_unlock_irqrestore(&port->lock, flags);
	} else {
517 518
		spin_lock_irqsave(&port->lock, flags);
		port->tx_bytes_flight -= urb->transfer_buffer_length;
519
		port->write_urb_busy = 0;
520
		spin_unlock_irqrestore(&port->lock, flags);
521

522 523
		if (status) {
			spin_lock_irqsave(&port->lock, flags);
524
			kfifo_reset_out(&port->write_fifo);
525 526
			spin_unlock_irqrestore(&port->lock, flags);
		} else {
527
			usb_serial_generic_write_start(port);
528
		}
L
Linus Torvalds 已提交
529
	}
530

531 532 533
	if (status)
		dbg("%s - non-zero urb status: %d", __func__, status);

534
	usb_serial_port_softint(port);
L
Linus Torvalds 已提交
535
}
536
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
L
Linus Torvalds 已提交
537

A
Alan Cox 已提交
538
void usb_serial_generic_throttle(struct tty_struct *tty)
539
{
A
Alan Cox 已提交
540
	struct usb_serial_port *port = tty->driver_data;
541 542
	unsigned long flags;

543
	dbg("%s - port %d", __func__, port->number);
544 545 546 547 548 549 550 551

	/* Set the throttle request flag. It will be picked up
	 * by usb_serial_generic_read_bulk_callback(). */
	spin_lock_irqsave(&port->lock, flags);
	port->throttle_req = 1;
	spin_unlock_irqrestore(&port->lock, flags);
}

A
Alan Cox 已提交
552
void usb_serial_generic_unthrottle(struct tty_struct *tty)
553
{
A
Alan Cox 已提交
554
	struct usb_serial_port *port = tty->driver_data;
555 556 557
	int was_throttled;
	unsigned long flags;

558
	dbg("%s - port %d", __func__, port->number);
559 560 561 562 563 564 565 566

	/* Clear the throttle flags */
	spin_lock_irqsave(&port->lock, flags);
	was_throttled = port->throttled;
	port->throttled = port->throttle_req = 0;
	spin_unlock_irqrestore(&port->lock, flags);

	if (was_throttled) {
567
		/* Resume reading from device */
568
		flush_and_resubmit_read_urb(port);
569 570 571
	}
}

572
#ifdef CONFIG_MAGIC_SYSRQ
A
Alan Cox 已提交
573 574
int usb_serial_handle_sysrq_char(struct tty_struct *tty,
			struct usb_serial_port *port, unsigned int ch)
575
{
576
	if (port->sysrq && port->port.console) {
577
		if (ch && time_before(jiffies, port->sysrq)) {
A
Alan Cox 已提交
578
			handle_sysrq(ch, tty);
579 580 581 582 583 584 585
			port->sysrq = 0;
			return 1;
		}
		port->sysrq = 0;
	}
	return 0;
}
586 587 588 589 590 591 592
#else
int usb_serial_handle_sysrq_char(struct tty_struct *tty,
			struct usb_serial_port *port, unsigned int ch)
{
	return 0;
}
#endif
593 594 595 596 597 598 599 600 601 602 603 604 605
EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char);

int usb_serial_handle_break(struct usb_serial_port *port)
{
	if (!port->sysrq) {
		port->sysrq = jiffies + HZ*5;
		return 1;
	}
	port->sysrq = 0;
	return 0;
}
EXPORT_SYMBOL_GPL(usb_serial_handle_break);

606 607 608 609 610 611 612
int usb_serial_generic_resume(struct usb_serial *serial)
{
	struct usb_serial_port *port;
	int i, c = 0, r;

	for (i = 0; i < serial->num_ports; i++) {
		port = serial->port[i];
613
		if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
			continue;

		if (port->read_urb) {
			r = usb_submit_urb(port->read_urb, GFP_NOIO);
			if (r < 0)
				c++;
		}

		if (port->write_urb) {
			r = usb_serial_generic_write_start(port);
			if (r < 0)
				c++;
		}
	}

	return c ? -EIO : 0;
}
EXPORT_SYMBOL_GPL(usb_serial_generic_resume);

633
void usb_serial_generic_disconnect(struct usb_serial *serial)
L
Linus Torvalds 已提交
634 635 636
{
	int i;

637
	dbg("%s", __func__);
L
Linus Torvalds 已提交
638 639

	/* stop reads and writes on all ports */
A
Alan Cox 已提交
640
	for (i = 0; i < serial->num_ports; ++i)
L
Linus Torvalds 已提交
641 642 643
		generic_cleanup(serial->port[i]);
}

644 645 646 647
void usb_serial_generic_release(struct usb_serial *serial)
{
	dbg("%s", __func__);
}