generic.c 15.3 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
			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) {
224
			dev_err(&port->dev, "%s - error submitting urb: %d\n",
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
				__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;
}

249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
/**
 * 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;

	spin_lock_irqsave(&port->lock, flags);
264 265 266
	if (port->write_urb_busy || !kfifo_len(&port->write_fifo)) {
		spin_unlock_irqrestore(&port->lock, flags);
		return 0;
267
	}
268
	port->write_urb_busy = 1;
269 270 271
	spin_unlock_irqrestore(&port->lock, flags);

	data = port->write_urb->transfer_buffer;
272
	count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock);
273 274
	usb_serial_debug_data(debug, &port->dev, __func__, count, data);

275
	port->write_urb->transfer_buffer_length = count;
276 277 278 279

	/* send the data out the bulk port */
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	if (result) {
280
		dev_err(&port->dev, "%s - error submitting urb: %d\n",
281 282 283 284
						__func__, result);
		/* don't have to grab the lock here, as we will
		   retry if != 0 */
		port->write_urb_busy = 0;
285 286
		return result;
	}
287

288 289 290 291 292
	spin_lock_irqsave(&port->lock, flags);
	port->tx_bytes_flight += count;
	spin_unlock_irqrestore(&port->lock, flags);

	return count;
293 294 295 296 297 298 299 300 301 302 303 304 305
}

/**
 * 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 已提交
306 307
int usb_serial_generic_write(struct tty_struct *tty,
	struct usb_serial_port *port, const unsigned char *buf, int count)
L
Linus Torvalds 已提交
308 309 310 311
{
	struct usb_serial *serial = port->serial;
	int result;

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

314 315 316 317
	/* only do something if we have a bulk out endpoint */
	if (!port->bulk_out_size)
		return -ENODEV;

318
	if (!count)
A
Alan Cox 已提交
319
		return 0;
L
Linus Torvalds 已提交
320

321 322 323
	if (serial->type->max_in_flight_urbs)
		return usb_serial_multi_urb_write(tty, port,
						  buf, count);
L
Linus Torvalds 已提交
324

325
	count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
326
	result = usb_serial_generic_write_start(port);
L
Linus Torvalds 已提交
327

328 329
	if (result >= 0)
		result = count;
L
Linus Torvalds 已提交
330

331
	return result;
L
Linus Torvalds 已提交
332
}
333
EXPORT_SYMBOL_GPL(usb_serial_generic_write);
L
Linus Torvalds 已提交
334

A
Alan Cox 已提交
335
int usb_serial_generic_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
336
{
A
Alan Cox 已提交
337
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
338
	struct usb_serial *serial = port->serial;
339
	unsigned long flags;
L
Linus Torvalds 已提交
340 341
	int room = 0;

342
	dbg("%s - port %d", __func__, port->number);
343 344 345 346

	if (!port->bulk_out_size)
		return 0;

347 348 349
	spin_lock_irqsave(&port->lock, flags);
	if (serial->type->max_in_flight_urbs) {
		if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
350 351 352
			room = port->bulk_out_size *
				(serial->type->max_in_flight_urbs -
				 port->urbs_in_flight);
353
	} else {
354
		room = kfifo_avail(&port->write_fifo);
355
	}
356
	spin_unlock_irqrestore(&port->lock, flags);
L
Linus Torvalds 已提交
357

358
	dbg("%s - returns %d", __func__, room);
359
	return room;
L
Linus Torvalds 已提交
360 361
}

A
Alan Cox 已提交
362
int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
363
{
A
Alan Cox 已提交
364
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
365
	struct usb_serial *serial = port->serial;
366
	unsigned long flags;
367
	int chars;
L
Linus Torvalds 已提交
368

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

371 372 373
	if (!port->bulk_out_size)
		return 0;

374 375
	spin_lock_irqsave(&port->lock, flags);
	if (serial->type->max_in_flight_urbs)
376
		chars = port->tx_bytes_flight;
377
	else
378
		chars = kfifo_len(&port->write_fifo) + port->tx_bytes_flight;
379
	spin_unlock_irqrestore(&port->lock, flags);
L
Linus Torvalds 已提交
380

381
	dbg("%s - returns %d", __func__, chars);
A
Alan Cox 已提交
382
	return chars;
L
Linus Torvalds 已提交
383 384
}

385 386
int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
					gfp_t mem_flags)
L
Linus Torvalds 已提交
387 388 389
{
	int result;

390
	result = usb_submit_urb(port->read_urb, mem_flags);
391
	if (result && result != -EPERM) {
392
		dev_err(&port->dev, "%s - error submitting urb: %d\n",
A
Alan Cox 已提交
393
							__func__, result);
394
	}
395
	return result;
L
Linus Torvalds 已提交
396
}
397
EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urb);
398

399
void usb_serial_generic_process_read_urb(struct urb *urb)
400
{
401 402
	struct usb_serial_port *port = urb->context;
	struct tty_struct *tty;
403 404 405
	char *ch = (char *)urb->transfer_buffer;
	int i;

406
	tty = tty_port_tty_get(&port->port);
407
	if (!tty)
408
		return;
409

410 411 412
	/* 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 */
413
	if (!port->port.console || !port->sysrq)
414 415 416
		tty_insert_flip_string(tty, ch, urb->actual_length);
	else {
		for (i = 0; i < urb->actual_length; i++, ch++) {
A
Alan Cox 已提交
417
			if (!usb_serial_handle_sysrq_char(tty, port, *ch))
418 419
				tty_insert_flip_char(tty, *ch, TTY_NORMAL);
		}
420
	}
421
	tty_flip_buffer_push(tty);
A
Alan Cox 已提交
422
	tty_kref_put(tty);
423
}
424
EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb);
425

A
Alan Cox 已提交
426
void usb_serial_generic_read_bulk_callback(struct urb *urb)
427
{
428
	struct usb_serial_port *port = urb->context;
429
	unsigned char *data = urb->transfer_buffer;
430
	int status = urb->status;
431
	unsigned long flags;
432

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

435 436
	if (unlikely(status != 0)) {
		dbg("%s - nonzero read bulk status received: %d",
437
		    __func__, status);
438 439 440
		return;
	}

A
Alan Cox 已提交
441 442
	usb_serial_debug_data(debug, &port->dev, __func__,
						urb->actual_length, data);
443
	port->serial->type->process_read_urb(urb);
444 445

	/* Throttle the device if requested by tty */
446
	spin_lock_irqsave(&port->lock, flags);
A
Alan Cox 已提交
447 448
	port->throttled = port->throttle_req;
	if (!port->throttled) {
449
		spin_unlock_irqrestore(&port->lock, flags);
450
		usb_serial_generic_submit_read_urb(port, GFP_ATOMIC);
A
Alan Cox 已提交
451
	} else
452
		spin_unlock_irqrestore(&port->lock, flags);
453
}
454
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
L
Linus Torvalds 已提交
455

A
Alan Cox 已提交
456
void usb_serial_generic_write_bulk_callback(struct urb *urb)
L
Linus Torvalds 已提交
457
{
458
	unsigned long flags;
459
	struct usb_serial_port *port = urb->context;
460
	int status = urb->status;
L
Linus Torvalds 已提交
461

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

464
	if (port->serial->type->max_in_flight_urbs) {
465 466
		kfree(urb->transfer_buffer);

467 468 469 470 471 472 473
		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 {
474 475
		spin_lock_irqsave(&port->lock, flags);
		port->tx_bytes_flight -= urb->transfer_buffer_length;
476
		port->write_urb_busy = 0;
477
		spin_unlock_irqrestore(&port->lock, flags);
478

479 480
		if (status) {
			spin_lock_irqsave(&port->lock, flags);
481
			kfifo_reset_out(&port->write_fifo);
482 483
			spin_unlock_irqrestore(&port->lock, flags);
		} else {
484
			usb_serial_generic_write_start(port);
485
		}
L
Linus Torvalds 已提交
486
	}
487

488 489 490
	if (status)
		dbg("%s - non-zero urb status: %d", __func__, status);

491
	usb_serial_port_softint(port);
L
Linus Torvalds 已提交
492
}
493
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
L
Linus Torvalds 已提交
494

A
Alan Cox 已提交
495
void usb_serial_generic_throttle(struct tty_struct *tty)
496
{
A
Alan Cox 已提交
497
	struct usb_serial_port *port = tty->driver_data;
498 499
	unsigned long flags;

500
	dbg("%s - port %d", __func__, port->number);
501 502 503 504 505 506 507

	/* 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);
}
508
EXPORT_SYMBOL_GPL(usb_serial_generic_throttle);
509

A
Alan Cox 已提交
510
void usb_serial_generic_unthrottle(struct tty_struct *tty)
511
{
A
Alan Cox 已提交
512
	struct usb_serial_port *port = tty->driver_data;
513 514
	int was_throttled;

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

	/* Clear the throttle flags */
518
	spin_lock_irq(&port->lock);
519 520
	was_throttled = port->throttled;
	port->throttled = port->throttle_req = 0;
521
	spin_unlock_irq(&port->lock);
522

523 524
	if (was_throttled)
		usb_serial_generic_submit_read_urb(port, GFP_KERNEL);
525
}
526
EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle);
527

528
#ifdef CONFIG_MAGIC_SYSRQ
A
Alan Cox 已提交
529 530
int usb_serial_handle_sysrq_char(struct tty_struct *tty,
			struct usb_serial_port *port, unsigned int ch)
531
{
532
	if (port->sysrq && port->port.console) {
533
		if (ch && time_before(jiffies, port->sysrq)) {
A
Alan Cox 已提交
534
			handle_sysrq(ch, tty);
535 536 537 538 539 540 541
			port->sysrq = 0;
			return 1;
		}
		port->sysrq = 0;
	}
	return 0;
}
542 543 544 545 546 547 548
#else
int usb_serial_handle_sysrq_char(struct tty_struct *tty,
			struct usb_serial_port *port, unsigned int ch)
{
	return 0;
}
#endif
549 550 551 552 553 554 555 556 557 558 559 560 561
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);

562 563 564 565 566 567 568
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];
569
		if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
			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);

589
void usb_serial_generic_disconnect(struct usb_serial *serial)
L
Linus Torvalds 已提交
590 591 592
{
	int i;

593
	dbg("%s", __func__);
L
Linus Torvalds 已提交
594 595

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

600 601 602 603
void usb_serial_generic_release(struct usb_serial *serial)
{
	dbg("%s", __func__);
}