generic.c 15.4 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
{
	int result = 0;
122
	unsigned long flags;
L
Linus Torvalds 已提交
123

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

126 127 128 129 130 131 132
	/* 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 */
133 134
	if (port->bulk_in_size)
		result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL);
L
Linus Torvalds 已提交
135 136 137

	return result;
}
138
EXPORT_SYMBOL_GPL(usb_serial_generic_open);
L
Linus Torvalds 已提交
139

A
Alan Cox 已提交
140
static void generic_cleanup(struct usb_serial_port *port)
L
Linus Torvalds 已提交
141 142
{
	struct usb_serial *serial = port->serial;
J
Johan Hovold 已提交
143
	unsigned long flags;
L
Linus Torvalds 已提交
144

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

	if (serial->dev) {
148
		/* shutdown any bulk transfers that might be going on */
J
Johan Hovold 已提交
149
		if (port->bulk_out_size) {
L
Linus Torvalds 已提交
150
			usb_kill_urb(port->write_urb);
J
Johan Hovold 已提交
151 152 153 154 155

			spin_lock_irqsave(&port->lock, flags);
			kfifo_reset_out(&port->write_fifo);
			spin_unlock_irqrestore(&port->lock, flags);
		}
156
		if (port->bulk_in_size)
L
Linus Torvalds 已提交
157 158 159 160
			usb_kill_urb(port->read_urb);
	}
}

161
void usb_serial_generic_close(struct usb_serial_port *port)
L
Linus Torvalds 已提交
162
{
163
	dbg("%s - port %d", __func__, port->number);
A
Alan Cox 已提交
164
	generic_cleanup(port);
L
Linus Torvalds 已提交
165
}
166
EXPORT_SYMBOL_GPL(usb_serial_generic_close);
L
Linus Torvalds 已提交
167

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
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);
190
			dbg("%s - write limit hit", __func__);
191 192 193 194 195 196 197 198 199 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
			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;
}

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
/**
 * 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)
{
	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 {
271
		start_io = (kfifo_len(&port->write_fifo) != 0);
272 273 274 275 276 277 278 279
		port->write_urb_busy = start_io;
	}
	spin_unlock_irqrestore(&port->lock, flags);

	if (!start_io)
		return 0;

	data = port->write_urb->transfer_buffer;
280
	count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock);
281 282
	usb_serial_debug_data(debug, &port->dev, __func__, count, data);

283
	port->write_urb->transfer_buffer_length = count;
284 285 286 287 288 289 290 291 292 293

	/* 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;
294 295
		return result;
	}
296

297 298 299 300 301
	spin_lock_irqsave(&port->lock, flags);
	port->tx_bytes_flight += count;
	spin_unlock_irqrestore(&port->lock, flags);

	return count;
302 303 304 305 306 307 308 309 310 311 312 313 314
}

/**
 * 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 已提交
315 316
int usb_serial_generic_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
L
Linus Torvalds 已提交
317 318 319 320
{
	struct usb_serial *serial = port->serial;
	int result;

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

323 324 325 326
	/* only do something if we have a bulk out endpoint */
	if (!port->bulk_out_size)
		return -ENODEV;

L
Linus Torvalds 已提交
327
	if (count == 0) {
328
		dbg("%s - write request of 0 bytes", __func__);
A
Alan Cox 已提交
329
		return 0;
L
Linus Torvalds 已提交
330 331
	}

332 333 334
	if (serial->type->max_in_flight_urbs)
		return usb_serial_multi_urb_write(tty, port,
						  buf, count);
L
Linus Torvalds 已提交
335

336
	count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
337
	result = usb_serial_generic_write_start(port);
L
Linus Torvalds 已提交
338

339 340
	if (result >= 0)
		result = count;
L
Linus Torvalds 已提交
341

342
	return result;
L
Linus Torvalds 已提交
343
}
344
EXPORT_SYMBOL_GPL(usb_serial_generic_write);
L
Linus Torvalds 已提交
345

A
Alan Cox 已提交
346
int usb_serial_generic_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
347
{
A
Alan Cox 已提交
348
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
349
	struct usb_serial *serial = port->serial;
350
	unsigned long flags;
L
Linus Torvalds 已提交
351 352
	int room = 0;

353
	dbg("%s - port %d", __func__, port->number);
354 355 356 357

	if (!port->bulk_out_size)
		return 0;

358 359 360
	spin_lock_irqsave(&port->lock, flags);
	if (serial->type->max_in_flight_urbs) {
		if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
361 362 363
			room = port->bulk_out_size *
				(serial->type->max_in_flight_urbs -
				 port->urbs_in_flight);
364
	} else {
365
		room = kfifo_avail(&port->write_fifo);
366
	}
367
	spin_unlock_irqrestore(&port->lock, flags);
L
Linus Torvalds 已提交
368

369
	dbg("%s - returns %d", __func__, room);
370
	return room;
L
Linus Torvalds 已提交
371 372
}

A
Alan Cox 已提交
373
int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
374
{
A
Alan Cox 已提交
375
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
376
	struct usb_serial *serial = port->serial;
377
	unsigned long flags;
378
	int chars;
L
Linus Torvalds 已提交
379

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

382 383 384
	if (!port->bulk_out_size)
		return 0;

385 386
	spin_lock_irqsave(&port->lock, flags);
	if (serial->type->max_in_flight_urbs)
387
		chars = port->tx_bytes_flight;
388
	else
389
		chars = kfifo_len(&port->write_fifo) + port->tx_bytes_flight;
390
	spin_unlock_irqrestore(&port->lock, flags);
L
Linus Torvalds 已提交
391

392
	dbg("%s - returns %d", __func__, chars);
A
Alan Cox 已提交
393
	return chars;
L
Linus Torvalds 已提交
394 395
}

396 397
int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
					gfp_t mem_flags)
L
Linus Torvalds 已提交
398 399 400
{
	int result;

401
	result = usb_submit_urb(port->read_urb, mem_flags);
402
	if (result && result != -EPERM) {
A
Alan Cox 已提交
403
		dev_err(&port->dev,
404
			"%s - failed submitting read urb, error %d\n",
A
Alan Cox 已提交
405
							__func__, result);
406
	}
407
	return result;
L
Linus Torvalds 已提交
408
}
409
EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urb);
410

411
void usb_serial_generic_process_read_urb(struct urb *urb)
412
{
413 414
	struct usb_serial_port *port = urb->context;
	struct tty_struct *tty;
415 416 417
	char *ch = (char *)urb->transfer_buffer;
	int i;

418
	tty = tty_port_tty_get(&port->port);
419
	if (!tty)
420
		return;
421

422 423 424
	/* 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 */
425
	if (!port->port.console || !port->sysrq)
426 427 428
		tty_insert_flip_string(tty, ch, urb->actual_length);
	else {
		for (i = 0; i < urb->actual_length; i++, ch++) {
A
Alan Cox 已提交
429
			if (!usb_serial_handle_sysrq_char(tty, port, *ch))
430 431
				tty_insert_flip_char(tty, *ch, TTY_NORMAL);
		}
432
	}
433
	tty_flip_buffer_push(tty);
A
Alan Cox 已提交
434
	tty_kref_put(tty);
435
}
436
EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb);
437

A
Alan Cox 已提交
438
void usb_serial_generic_read_bulk_callback(struct urb *urb)
439
{
440
	struct usb_serial_port *port = urb->context;
441
	unsigned char *data = urb->transfer_buffer;
442
	int status = urb->status;
443
	unsigned long flags;
444

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

447 448
	if (unlikely(status != 0)) {
		dbg("%s - nonzero read bulk status received: %d",
449
		    __func__, status);
450 451 452
		return;
	}

A
Alan Cox 已提交
453 454
	usb_serial_debug_data(debug, &port->dev, __func__,
						urb->actual_length, data);
455
	port->serial->type->process_read_urb(urb);
456 457

	/* Throttle the device if requested by tty */
458
	spin_lock_irqsave(&port->lock, flags);
A
Alan Cox 已提交
459 460
	port->throttled = port->throttle_req;
	if (!port->throttled) {
461
		spin_unlock_irqrestore(&port->lock, flags);
462
		usb_serial_generic_submit_read_urb(port, GFP_ATOMIC);
A
Alan Cox 已提交
463
	} else
464
		spin_unlock_irqrestore(&port->lock, flags);
465
}
466
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
L
Linus Torvalds 已提交
467

A
Alan Cox 已提交
468
void usb_serial_generic_write_bulk_callback(struct urb *urb)
L
Linus Torvalds 已提交
469
{
470
	unsigned long flags;
471
	struct usb_serial_port *port = urb->context;
472
	int status = urb->status;
L
Linus Torvalds 已提交
473

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

476
	if (port->serial->type->max_in_flight_urbs) {
477 478
		kfree(urb->transfer_buffer);

479 480 481 482 483 484 485
		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 {
486 487
		spin_lock_irqsave(&port->lock, flags);
		port->tx_bytes_flight -= urb->transfer_buffer_length;
488
		port->write_urb_busy = 0;
489
		spin_unlock_irqrestore(&port->lock, flags);
490

491 492
		if (status) {
			spin_lock_irqsave(&port->lock, flags);
493
			kfifo_reset_out(&port->write_fifo);
494 495
			spin_unlock_irqrestore(&port->lock, flags);
		} else {
496
			usb_serial_generic_write_start(port);
497
		}
L
Linus Torvalds 已提交
498
	}
499

500 501 502
	if (status)
		dbg("%s - non-zero urb status: %d", __func__, status);

503
	usb_serial_port_softint(port);
L
Linus Torvalds 已提交
504
}
505
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
L
Linus Torvalds 已提交
506

A
Alan Cox 已提交
507
void usb_serial_generic_throttle(struct tty_struct *tty)
508
{
A
Alan Cox 已提交
509
	struct usb_serial_port *port = tty->driver_data;
510 511
	unsigned long flags;

512
	dbg("%s - port %d", __func__, port->number);
513 514 515 516 517 518 519 520

	/* 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 已提交
521
void usb_serial_generic_unthrottle(struct tty_struct *tty)
522
{
A
Alan Cox 已提交
523
	struct usb_serial_port *port = tty->driver_data;
524 525
	int was_throttled;

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

	/* Clear the throttle flags */
529
	spin_lock_irq(&port->lock);
530 531
	was_throttled = port->throttled;
	port->throttled = port->throttle_req = 0;
532
	spin_unlock_irq(&port->lock);
533

534 535
	if (was_throttled)
		usb_serial_generic_submit_read_urb(port, GFP_KERNEL);
536 537
}

538
#ifdef CONFIG_MAGIC_SYSRQ
A
Alan Cox 已提交
539 540
int usb_serial_handle_sysrq_char(struct tty_struct *tty,
			struct usb_serial_port *port, unsigned int ch)
541
{
542
	if (port->sysrq && port->port.console) {
543
		if (ch && time_before(jiffies, port->sysrq)) {
A
Alan Cox 已提交
544
			handle_sysrq(ch, tty);
545 546 547 548 549 550 551
			port->sysrq = 0;
			return 1;
		}
		port->sysrq = 0;
	}
	return 0;
}
552 553 554 555 556 557 558
#else
int usb_serial_handle_sysrq_char(struct tty_struct *tty,
			struct usb_serial_port *port, unsigned int ch)
{
	return 0;
}
#endif
559 560 561 562 563 564 565 566 567 568 569 570 571
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);

572 573 574 575 576 577 578
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];
579
		if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
			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);

599
void usb_serial_generic_disconnect(struct usb_serial *serial)
L
Linus Torvalds 已提交
600 601 602
{
	int i;

603
	dbg("%s", __func__);
L
Linus Torvalds 已提交
604 605

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

610 611 612 613
void usb_serial_generic_release(struct usb_serial *serial)
{
	dbg("%s", __func__);
}