cdc-acm.c 48.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 * cdc-acm.c
 *
 * Copyright (c) 1999 Armin Fuerst	<fuerst@in.tum.de>
P
Pavel Machek 已提交
5
 * Copyright (c) 1999 Pavel Machek	<pavel@ucw.cz>
L
Linus Torvalds 已提交
6 7 8
 * Copyright (c) 1999 Johannes Erdfelt	<johannes@erdfelt.com>
 * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
 * Copyright (c) 2004 Oliver Neukum	<oliver@neukum.name>
9
 * Copyright (c) 2005 David Kubicek	<dave@awk.cz>
10
 * Copyright (c) 2011 Johan Hovold	<jhovold@gmail.com>
L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *
 * USB Abstract Control Model driver for USB modems and ISDN adapters
 *
 * Sponsored by SuSE
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#undef DEBUG
32
#undef VERBOSE_DEBUG
L
Linus Torvalds 已提交
33 34 35 36 37 38

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
39
#include <linux/serial.h>
L
Linus Torvalds 已提交
40 41 42
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
43
#include <linux/mutex.h>
A
Alan Cox 已提交
44
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
45
#include <linux/usb.h>
46
#include <linux/usb/cdc.h>
L
Linus Torvalds 已提交
47 48
#include <asm/byteorder.h>
#include <asm/unaligned.h>
49
#include <linux/list.h>
L
Linus Torvalds 已提交
50 51 52

#include "cdc-acm.h"

53

54
#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek, Johan Hovold"
L
Linus Torvalds 已提交
55 56 57 58 59 60
#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"

static struct usb_driver acm_driver;
static struct tty_driver *acm_tty_driver;
static struct acm *acm_table[ACM_TTY_MINORS];

61
static DEFINE_MUTEX(acm_table_lock);
L
Linus Torvalds 已提交
62

63 64 65
/*
 * acm_table accessors
 */
L
Linus Torvalds 已提交
66

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/*
 * Look up an ACM structure by index. If found and not disconnected, increment
 * its refcount and return it with its mutex held.
 */
static struct acm *acm_get_by_index(unsigned index)
{
	struct acm *acm;

	mutex_lock(&acm_table_lock);
	acm = acm_table[index];
	if (acm) {
		mutex_lock(&acm->mutex);
		if (acm->disconnected) {
			mutex_unlock(&acm->mutex);
			acm = NULL;
		} else {
			tty_port_get(&acm->port);
			mutex_unlock(&acm->mutex);
		}
	}
	mutex_unlock(&acm_table_lock);
	return acm;
}

/*
 * Try to find an available minor number and if found, associate it with 'acm'.
 */
static int acm_alloc_minor(struct acm *acm)
{
	int minor;

	mutex_lock(&acm_table_lock);
	for (minor = 0; minor < ACM_TTY_MINORS; minor++) {
		if (!acm_table[minor]) {
			acm_table[minor] = acm;
			break;
		}
	}
	mutex_unlock(&acm_table_lock);

	return minor;
}

/* Release the minor number associated with 'acm'.  */
static void acm_release_minor(struct acm *acm)
{
	mutex_lock(&acm_table_lock);
	acm_table[acm->minor] = NULL;
	mutex_unlock(&acm_table_lock);
}
A
Alan Cox 已提交
117

L
Linus Torvalds 已提交
118 119 120 121
/*
 * Functions for ACM control messages.
 */

122 123
static int acm_ctrl_msg(struct acm *acm, int request, int value,
							void *buf, int len)
L
Linus Torvalds 已提交
124 125 126 127 128
{
	int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
		request, USB_RT_ACM, value,
		acm->control->altsetting[0].desc.bInterfaceNumber,
		buf, len, 5000);
129 130 131
	dev_dbg(&acm->control->dev,
			"%s - rq 0x%02x, val %#x, len %#x, result %d\n",
			__func__, request, value, len, retval);
L
Linus Torvalds 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144
	return retval < 0 ? retval : 0;
}

/* devices aren't required to support these requests.
 * the cdc acm descriptor tells whether they do...
 */
#define acm_set_control(acm, control) \
	acm_ctrl_msg(acm, USB_CDC_REQ_SET_CONTROL_LINE_STATE, control, NULL, 0)
#define acm_set_line(acm, line) \
	acm_ctrl_msg(acm, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line))
#define acm_send_break(acm, ms) \
	acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0)

145 146 147 148 149 150 151 152 153 154
/*
 * Write buffer management.
 * All of these assume proper locks taken by the caller.
 */

static int acm_wb_alloc(struct acm *acm)
{
	int i, wbn;
	struct acm_wb *wb;

155
	wbn = 0;
156 157 158 159 160 161 162
	i = 0;
	for (;;) {
		wb = &acm->wb[wbn];
		if (!wb->use) {
			wb->use = 1;
			return wbn;
		}
163 164
		wbn = (wbn + 1) % ACM_NW;
		if (++i >= ACM_NW)
165 166 167 168 169 170 171
			return -1;
	}
}

static int acm_wb_is_avail(struct acm *acm)
{
	int i, n;
172
	unsigned long flags;
173

174
	n = ACM_NW;
175
	spin_lock_irqsave(&acm->write_lock, flags);
176
	for (i = 0; i < ACM_NW; i++)
177
		n -= acm->wb[i].use;
178
	spin_unlock_irqrestore(&acm->write_lock, flags);
179 180 181 182
	return n;
}

/*
183
 * Finish write. Caller must hold acm->write_lock
184
 */
185
static void acm_write_done(struct acm *acm, struct acm_wb *wb)
186
{
187
	wb->use = 0;
188
	acm->transmitting--;
189
	usb_autopm_put_interface_async(acm->control);
190 191 192 193
}

/*
 * Poke write.
194 195
 *
 * the caller is responsible for locking
196
 */
197 198 199 200 201 202 203 204 205 206 207 208

static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
{
	int rc;

	acm->transmitting++;

	wb->urb->transfer_buffer = wb->buf;
	wb->urb->transfer_dma = wb->dmah;
	wb->urb->transfer_buffer_length = wb->len;
	wb->urb->dev = acm->dev;

209 210
	rc = usb_submit_urb(wb->urb, GFP_ATOMIC);
	if (rc < 0) {
211 212 213
		dev_err(&acm->data->dev,
			"%s - usb_submit_urb(write bulk) failed: %d\n",
			__func__, rc);
214 215 216 217 218
		acm_write_done(acm, wb);
	}
	return rc;
}

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
/*
 * attributes exported through sysfs
 */
static ssize_t show_caps
(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct acm *acm = usb_get_intfdata(intf);

	return sprintf(buf, "%d", acm->ctrl_caps);
}
static DEVICE_ATTR(bmCapabilities, S_IRUGO, show_caps, NULL);

static ssize_t show_country_codes
(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct acm *acm = usb_get_intfdata(intf);

	memcpy(buf, acm->country_codes, acm->country_code_size);
	return acm->country_code_size;
}

static DEVICE_ATTR(wCountryCodes, S_IRUGO, show_country_codes, NULL);

static ssize_t show_country_rel_date
(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct acm *acm = usb_get_intfdata(intf);

	return sprintf(buf, "%d", acm->country_rel_date);
}
252

253
static DEVICE_ATTR(iCountryCodeRelDate, S_IRUGO, show_country_rel_date, NULL);
L
Linus Torvalds 已提交
254 255 256 257 258
/*
 * Interrupt handlers for various ACM device responses
 */

/* control interface reports status changes with "interrupt" transfers */
259
static void acm_ctrl_irq(struct urb *urb)
L
Linus Torvalds 已提交
260 261 262 263 264
{
	struct acm *acm = urb->context;
	struct usb_cdc_notification *dr = urb->transfer_buffer;
	unsigned char *data;
	int newctrl;
265 266
	int retval;
	int status = urb->status;
L
Linus Torvalds 已提交
267

268
	switch (status) {
L
Linus Torvalds 已提交
269 270 271 272 273 274 275
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
276 277 278
		dev_dbg(&acm->control->dev,
				"%s - urb shutting down with status: %d\n",
				__func__, status);
L
Linus Torvalds 已提交
279 280
		return;
	default:
281 282 283
		dev_dbg(&acm->control->dev,
				"%s - nonzero urb status received: %d\n",
				__func__, status);
L
Linus Torvalds 已提交
284 285 286
		goto exit;
	}

287 288
	usb_mark_last_busy(acm->dev);

L
Linus Torvalds 已提交
289 290
	data = (unsigned char *)(dr + 1);
	switch (dr->bNotificationType) {
291
	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
292 293
		dev_dbg(&acm->control->dev, "%s - network connection: %d\n",
							__func__, dr->wValue);
294
		break;
L
Linus Torvalds 已提交
295

296 297
	case USB_CDC_NOTIFY_SERIAL_STATE:
		newctrl = get_unaligned_le16(data);
L
Linus Torvalds 已提交
298

J
Jiri Slaby 已提交
299 300 301 302
		if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
			dev_dbg(&acm->control->dev, "%s - calling hangup\n",
					__func__);
			tty_port_tty_hangup(&acm->port, false);
303
		}
L
Linus Torvalds 已提交
304

305
		acm->ctrlin = newctrl;
L
Linus Torvalds 已提交
306

307 308 309 310
		dev_dbg(&acm->control->dev,
			"%s - input control lines: dcd%c dsr%c break%c "
			"ring%c framing%c parity%c overrun%c\n",
			__func__,
311 312 313 314 315 316 317
			acm->ctrlin & ACM_CTRL_DCD ? '+' : '-',
			acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
			acm->ctrlin & ACM_CTRL_BRK ? '+' : '-',
			acm->ctrlin & ACM_CTRL_RI  ? '+' : '-',
			acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',
			acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
			acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
L
Linus Torvalds 已提交
318 319
			break;

320
	default:
321 322 323 324
		dev_dbg(&acm->control->dev,
			"%s - unknown notification %d received: index %d "
			"len %d data0 %d data1 %d\n",
			__func__,
325 326 327
			dr->bNotificationType, dr->wIndex,
			dr->wLength, data[0], data[1]);
		break;
L
Linus Torvalds 已提交
328 329
	}
exit:
330
	retval = usb_submit_urb(urb, GFP_ATOMIC);
331
	if (retval)
332 333
		dev_err(&acm->control->dev, "%s - usb_submit_urb failed: %d\n",
							__func__, retval);
L
Linus Torvalds 已提交
334 335
}

336
static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
L
Linus Torvalds 已提交
337
{
338
	int res;
339

340 341
	if (!test_and_clear_bit(index, &acm->read_urbs_free))
		return 0;
L
Linus Torvalds 已提交
342

343 344 345 346 347 348 349 350 351 352 353
	dev_vdbg(&acm->data->dev, "%s - urb %d\n", __func__, index);

	res = usb_submit_urb(acm->read_urbs[index], mem_flags);
	if (res) {
		if (res != -EPERM) {
			dev_err(&acm->data->dev,
					"%s - usb_submit_urb failed: %d\n",
					__func__, res);
		}
		set_bit(index, &acm->read_urbs_free);
		return res;
354
	}
L
Linus Torvalds 已提交
355

356 357
	return 0;
}
L
Linus Torvalds 已提交
358

359 360 361 362
static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
{
	int res;
	int i;
363

364 365 366 367
	for (i = 0; i < acm->rx_buflimit; ++i) {
		res = acm_submit_read_urb(acm, i, mem_flags);
		if (res)
			return res;
368
	}
369 370

	return 0;
L
Linus Torvalds 已提交
371 372
}

373
static void acm_process_read_urb(struct acm *acm, struct urb *urb)
L
Linus Torvalds 已提交
374
{
375
	if (!urb->actual_length)
376
		return;
377

J
Jiri Slaby 已提交
378 379
	tty_insert_flip_string(&acm->port, urb->transfer_buffer,
			urb->actual_length);
J
Jiri Slaby 已提交
380
	tty_flip_buffer_push(&acm->port);
381
}
A
Alan Cox 已提交
382

383 384 385 386 387
static void acm_read_bulk_callback(struct urb *urb)
{
	struct acm_rb *rb = urb->context;
	struct acm *acm = rb->instance;
	unsigned long flags;
388

389 390 391
	dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__,
					rb->index, urb->actual_length);
	set_bit(rb->index, &acm->read_urbs_free);
392

393 394 395 396 397
	if (!acm->dev) {
		dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
		return;
	}
	usb_mark_last_busy(acm->dev);
398

399 400 401 402
	if (urb->status) {
		dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n",
							__func__, urb->status);
		return;
403
	}
404 405 406
	acm_process_read_urb(acm, urb);

	/* throttle device if requested by tty */
407
	spin_lock_irqsave(&acm->read_lock, flags);
408 409 410 411 412 413 414
	acm->throttled = acm->throttle_req;
	if (!acm->throttled && !acm->susp_count) {
		spin_unlock_irqrestore(&acm->read_lock, flags);
		acm_submit_read_urb(acm, rb->index, GFP_ATOMIC);
	} else {
		spin_unlock_irqrestore(&acm->read_lock, flags);
	}
L
Linus Torvalds 已提交
415 416 417
}

/* data interface wrote those outgoing bytes */
418
static void acm_write_bulk(struct urb *urb)
L
Linus Torvalds 已提交
419
{
420
	struct acm_wb *wb = urb->context;
421
	struct acm *acm = wb->instance;
422
	unsigned long flags;
L
Linus Torvalds 已提交
423

424 425
	if (urb->status	|| (urb->actual_length != urb->transfer_buffer_length))
		dev_vdbg(&acm->data->dev, "%s - len %d/%d, status %d\n",
426
			__func__,
427 428 429
			urb->actual_length,
			urb->transfer_buffer_length,
			urb->status);
L
Linus Torvalds 已提交
430

431
	spin_lock_irqsave(&acm->write_lock, flags);
432
	acm_write_done(acm, wb);
433
	spin_unlock_irqrestore(&acm->write_lock, flags);
434
	schedule_work(&acm->work);
L
Linus Torvalds 已提交
435 436
}

D
David Howells 已提交
437
static void acm_softint(struct work_struct *work)
L
Linus Torvalds 已提交
438
{
D
David Howells 已提交
439
	struct acm *acm = container_of(work, struct acm, work);
440

441 442
	dev_vdbg(&acm->data->dev, "%s\n", __func__);

J
Jiri Slaby 已提交
443
	tty_port_tty_wakeup(&acm->port);
L
Linus Torvalds 已提交
444 445 446 447 448 449
}

/*
 * TTY handlers
 */

450
static int acm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
L
Linus Torvalds 已提交
451 452
{
	struct acm *acm;
453
	int retval;
L
Linus Torvalds 已提交
454

455
	dev_dbg(tty->dev, "%s\n", __func__);
L
Linus Torvalds 已提交
456

457 458 459
	acm = acm_get_by_index(tty->index);
	if (!acm)
		return -ENODEV;
460

461
	retval = tty_standard_install(driver, tty);
462 463
	if (retval)
		goto error_init_termios;
A
Alan Cox 已提交
464

L
Linus Torvalds 已提交
465 466
	tty->driver_data = acm;

467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
	return 0;

error_init_termios:
	tty_port_put(&acm->port);
	return retval;
}

static int acm_tty_open(struct tty_struct *tty, struct file *filp)
{
	struct acm *acm = tty->driver_data;

	dev_dbg(tty->dev, "%s\n", __func__);

	return tty_port_open(&acm->port, tty, filp);
}

static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
{
	struct acm *acm = container_of(port, struct acm, port);
	int retval = -ENODEV;

	dev_dbg(&acm->control->dev, "%s\n", __func__);
O
Oliver Neukum 已提交
489 490

	mutex_lock(&acm->mutex);
491 492 493 494 495 496 497 498 499 500 501 502 503
	if (acm->disconnected)
		goto disconnected;

	retval = usb_autopm_get_interface(acm->control);
	if (retval)
		goto error_get_interface;

	/*
	 * FIXME: Why do we need this? Allocating 64K of physically contiguous
	 * memory is really nasty...
	 */
	set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
	acm->control->needs_remote_wakeup = 1;
O
Oliver Neukum 已提交
504

L
Linus Torvalds 已提交
505 506
	acm->ctrlurb->dev = acm->dev;
	if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
507 508
		dev_err(&acm->control->dev,
			"%s - usb_submit_urb(ctrl irq) failed\n", __func__);
509
		goto error_submit_urb;
L
Linus Torvalds 已提交
510 511
	}

512 513
	acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS;
	if (acm_set_control(acm, acm->ctrlout) < 0 &&
514
	    (acm->ctrl_caps & USB_CDC_CAP_LINE))
515
		goto error_set_control;
A
Alan Cox 已提交
516

517
	usb_autopm_put_interface(acm->control);
L
Linus Torvalds 已提交
518

519 520 521 522 523 524 525 526
	/*
	 * Unthrottle device in case the TTY was closed while throttled.
	 */
	spin_lock_irq(&acm->read_lock);
	acm->throttled = 0;
	acm->throttle_req = 0;
	spin_unlock_irq(&acm->read_lock);

527
	if (acm_submit_read_urbs(acm, GFP_KERNEL))
528
		goto error_submit_read_urbs;
529

O
Oliver Neukum 已提交
530
	mutex_unlock(&acm->mutex);
L
Linus Torvalds 已提交
531

532 533 534 535 536 537 538 539
	return 0;

error_submit_read_urbs:
	acm->ctrlout = 0;
	acm_set_control(acm, acm->ctrlout);
error_set_control:
	usb_kill_urb(acm->ctrlurb);
error_submit_urb:
540
	usb_autopm_put_interface(acm->control);
541 542 543 544
error_get_interface:
disconnected:
	mutex_unlock(&acm->mutex);
	return retval;
L
Linus Torvalds 已提交
545 546
}

547
static void acm_port_destruct(struct tty_port *port)
548
{
549 550 551
	struct acm *acm = container_of(port, struct acm, port);

	dev_dbg(&acm->control->dev, "%s\n", __func__);
552

553
	acm_release_minor(acm);
554
	usb_put_intf(acm->control);
555
	kfree(acm->country_codes);
556 557 558
	kfree(acm);
}

559
static void acm_port_shutdown(struct tty_port *port)
A
Alan Cox 已提交
560
{
561
	struct acm *acm = container_of(port, struct acm, port);
562 563
	int i;

564 565 566 567
	dev_dbg(&acm->control->dev, "%s\n", __func__);

	mutex_lock(&acm->mutex);
	if (!acm->disconnected) {
A
Alan Cox 已提交
568 569 570 571 572
		usb_autopm_get_interface(acm->control);
		acm_set_control(acm, acm->ctrlout = 0);
		usb_kill_urb(acm->ctrlurb);
		for (i = 0; i < ACM_NW; i++)
			usb_kill_urb(acm->wb[i].urb);
573
		for (i = 0; i < acm->rx_buflimit; i++)
574
			usb_kill_urb(acm->read_urbs[i]);
A
Alan Cox 已提交
575 576 577
		acm->control->needs_remote_wakeup = 0;
		usb_autopm_put_interface(acm->control);
	}
578 579 580 581 582 583 584 585
	mutex_unlock(&acm->mutex);
}

static void acm_tty_cleanup(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	dev_dbg(&acm->control->dev, "%s\n", __func__);
	tty_port_put(&acm->port);
A
Alan Cox 已提交
586 587 588 589 590
}

static void acm_tty_hangup(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
591
	dev_dbg(&acm->control->dev, "%s\n", __func__);
A
Alan Cox 已提交
592 593 594
	tty_port_hangup(&acm->port);
}

L
Linus Torvalds 已提交
595 596 597
static void acm_tty_close(struct tty_struct *tty, struct file *filp)
{
	struct acm *acm = tty->driver_data;
598 599
	dev_dbg(&acm->control->dev, "%s\n", __func__);
	tty_port_close(&acm->port, tty, filp);
L
Linus Torvalds 已提交
600 601
}

602 603
static int acm_tty_write(struct tty_struct *tty,
					const unsigned char *buf, int count)
L
Linus Torvalds 已提交
604 605 606
{
	struct acm *acm = tty->driver_data;
	int stat;
607 608 609 610
	unsigned long flags;
	int wbn;
	struct acm_wb *wb;

L
Linus Torvalds 已提交
611 612 613
	if (!count)
		return 0;

614
	dev_vdbg(&acm->data->dev, "%s - count %d\n", __func__, count);
615

616
	spin_lock_irqsave(&acm->write_lock, flags);
617 618
	wbn = acm_wb_alloc(acm);
	if (wbn < 0) {
619 620 621 622
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return 0;
	}
	wb = &acm->wb[wbn];
L
Linus Torvalds 已提交
623

624 625 626 627 628 629
	if (!acm->dev) {
		wb->use = 0;
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return -ENODEV;
	}

630
	count = (count > acm->writesize) ? acm->writesize : count;
631
	dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count);
632 633
	memcpy(wb->buf, buf, count);
	wb->len = count;
634 635 636 637 638 639 640 641 642 643 644 645 646

	usb_autopm_get_interface_async(acm->control);
	if (acm->susp_count) {
		if (!acm->delayed_wb)
			acm->delayed_wb = wb;
		else
			usb_autopm_put_interface_async(acm->control);
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return count;	/* A white lie */
	}
	usb_mark_last_busy(acm->dev);

	stat = acm_start_wb(acm, wb);
647
	spin_unlock_irqrestore(&acm->write_lock, flags);
L
Linus Torvalds 已提交
648

649
	if (stat < 0)
L
Linus Torvalds 已提交
650 651 652 653 654 655 656
		return stat;
	return count;
}

static int acm_tty_write_room(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
657 658 659 660
	/*
	 * Do not let the line discipline to know that we have a reserve,
	 * or it might get too enthusiastic.
	 */
661
	return acm_wb_is_avail(acm) ? acm->writesize : 0;
L
Linus Torvalds 已提交
662 663 664 665 666
}

static int acm_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
667 668 669 670 671
	/*
	 * if the device was unplugged then any remaining characters fell out
	 * of the connector ;)
	 */
	if (acm->disconnected)
A
Alan Cox 已提交
672
		return 0;
673 674 675
	/*
	 * This is inaccurate (overcounts), but it works.
	 */
676
	return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize;
L
Linus Torvalds 已提交
677 678 679 680 681
}

static void acm_tty_throttle(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
682 683 684 685

	spin_lock_irq(&acm->read_lock);
	acm->throttle_req = 1;
	spin_unlock_irq(&acm->read_lock);
L
Linus Torvalds 已提交
686 687 688 689 690
}

static void acm_tty_unthrottle(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
691 692 693 694 695 696 697 698 699 700
	unsigned int was_throttled;

	spin_lock_irq(&acm->read_lock);
	was_throttled = acm->throttled;
	acm->throttled = 0;
	acm->throttle_req = 0;
	spin_unlock_irq(&acm->read_lock);

	if (was_throttled)
		acm_submit_read_urbs(acm, GFP_KERNEL);
L
Linus Torvalds 已提交
701 702
}

A
Alan Cox 已提交
703
static int acm_tty_break_ctl(struct tty_struct *tty, int state)
L
Linus Torvalds 已提交
704 705
{
	struct acm *acm = tty->driver_data;
A
Alan Cox 已提交
706
	int retval;
707

A
Alan Cox 已提交
708 709
	retval = acm_send_break(acm, state ? 0xffff : 0);
	if (retval < 0)
710 711
		dev_dbg(&acm->control->dev, "%s - send break failed\n",
								__func__);
A
Alan Cox 已提交
712
	return retval;
L
Linus Torvalds 已提交
713 714
}

715
static int acm_tty_tiocmget(struct tty_struct *tty)
L
Linus Torvalds 已提交
716 717 718 719 720 721 722 723 724 725 726
{
	struct acm *acm = tty->driver_data;

	return (acm->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) |
	       (acm->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) |
	       (acm->ctrlin  & ACM_CTRL_DSR ? TIOCM_DSR : 0) |
	       (acm->ctrlin  & ACM_CTRL_RI  ? TIOCM_RI  : 0) |
	       (acm->ctrlin  & ACM_CTRL_DCD ? TIOCM_CD  : 0) |
	       TIOCM_CTS;
}

727
static int acm_tty_tiocmset(struct tty_struct *tty,
L
Linus Torvalds 已提交
728 729 730 731 732 733
			    unsigned int set, unsigned int clear)
{
	struct acm *acm = tty->driver_data;
	unsigned int newctrl;

	newctrl = acm->ctrlout;
734 735 736 737
	set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) |
					(set & TIOCM_RTS ? ACM_CTRL_RTS : 0);
	clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) |
					(clear & TIOCM_RTS ? ACM_CTRL_RTS : 0);
L
Linus Torvalds 已提交
738 739 740 741 742 743 744 745

	newctrl = (newctrl & ~clear) | set;

	if (acm->ctrlout == newctrl)
		return 0;
	return acm_set_control(acm, acm->ctrlout = newctrl);
}

746 747 748 749 750 751 752 753 754 755 756
static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
{
	struct serial_struct tmp;

	if (!info)
		return -EINVAL;

	memset(&tmp, 0, sizeof(tmp));
	tmp.flags = ASYNC_LOW_LATENCY;
	tmp.xmit_fifo_size = acm->writesize;
	tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
757 758 759 760
	tmp.close_delay	= acm->port.close_delay / 10;
	tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
				ASYNC_CLOSING_WAIT_NONE :
				acm->port.closing_wait / 10;
761 762 763 764 765 766 767

	if (copy_to_user(info, &tmp, sizeof(tmp)))
		return -EFAULT;
	else
		return 0;
}

768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
static int set_serial_info(struct acm *acm,
				struct serial_struct __user *newinfo)
{
	struct serial_struct new_serial;
	unsigned int closing_wait, close_delay;
	int retval = 0;

	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
		return -EFAULT;

	close_delay = new_serial.close_delay * 10;
	closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
			ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;

	mutex_lock(&acm->port.mutex);

	if (!capable(CAP_SYS_ADMIN)) {
		if ((close_delay != acm->port.close_delay) ||
		    (closing_wait != acm->port.closing_wait))
			retval = -EPERM;
		else
			retval = -EOPNOTSUPP;
	} else {
		acm->port.close_delay  = close_delay;
		acm->port.closing_wait = closing_wait;
	}

	mutex_unlock(&acm->port.mutex);
	return retval;
}

799
static int acm_tty_ioctl(struct tty_struct *tty,
800
					unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
801
{
802 803 804 805 806 807
	struct acm *acm = tty->driver_data;
	int rv = -ENOIOCTLCMD;

	switch (cmd) {
	case TIOCGSERIAL: /* gets serial port data */
		rv = get_serial_info(acm, (struct serial_struct __user *) arg);
808 809 810
		break;
	case TIOCSSERIAL:
		rv = set_serial_info(acm, (struct serial_struct __user *) arg);
811 812 813 814
		break;
	}

	return rv;
L
Linus Torvalds 已提交
815 816
}

817 818
static void acm_tty_set_termios(struct tty_struct *tty,
						struct ktermios *termios_old)
L
Linus Torvalds 已提交
819 820
{
	struct acm *acm = tty->driver_data;
821
	struct ktermios *termios = &tty->termios;
L
Linus Torvalds 已提交
822 823 824
	struct usb_cdc_line_coding newline;
	int newctrl = acm->ctrlout;

825
	newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
L
Linus Torvalds 已提交
826 827
	newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
	newline.bParityType = termios->c_cflag & PARENB ?
828 829
				(termios->c_cflag & PARODD ? 1 : 2) +
				(termios->c_cflag & CMSPAR ? 2 : 0) : 0;
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		newline.bDataBits = 5;
		break;
	case CS6:
		newline.bDataBits = 6;
		break;
	case CS7:
		newline.bDataBits = 7;
		break;
	case CS8:
	default:
		newline.bDataBits = 8;
		break;
	}
845
	/* FIXME: Needs to clear unsupported bits in the termios */
L
Linus Torvalds 已提交
846 847 848 849 850
	acm->clocal = ((termios->c_cflag & CLOCAL) != 0);

	if (!newline.dwDTERate) {
		newline.dwDTERate = acm->line.dwDTERate;
		newctrl &= ~ACM_CTRL_DTR;
851 852
	} else
		newctrl |=  ACM_CTRL_DTR;
L
Linus Torvalds 已提交
853 854 855 856 857 858

	if (newctrl != acm->ctrlout)
		acm_set_control(acm, acm->ctrlout = newctrl);

	if (memcmp(&acm->line, &newline, sizeof newline)) {
		memcpy(&acm->line, &newline, sizeof newline);
859 860 861
		dev_dbg(&acm->control->dev, "%s - set line: %d %d %d %d\n",
			__func__,
			le32_to_cpu(newline.dwDTERate),
L
Linus Torvalds 已提交
862 863 864 865 866 867
			newline.bCharFormat, newline.bParityType,
			newline.bDataBits);
		acm_set_line(acm, &acm->line);
	}
}

868 869 870 871 872 873
static const struct tty_port_operations acm_port_ops = {
	.shutdown = acm_port_shutdown,
	.activate = acm_port_activate,
	.destruct = acm_port_destruct,
};

L
Linus Torvalds 已提交
874 875 876 877
/*
 * USB probe and disconnect routines.
 */

878
/* Little helpers: write/read buffers free */
879 880 881 882
static void acm_write_buffers_free(struct acm *acm)
{
	int i;
	struct acm_wb *wb;
O
Oliver Neukum 已提交
883
	struct usb_device *usb_dev = interface_to_usbdev(acm->control);
884

885
	for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++)
886
		usb_free_coherent(usb_dev, acm->writesize, wb->buf, wb->dmah);
887 888
}

889 890 891
static void acm_read_buffers_free(struct acm *acm)
{
	struct usb_device *usb_dev = interface_to_usbdev(acm->control);
892
	int i;
893

894
	for (i = 0; i < acm->rx_buflimit; i++)
895
		usb_free_coherent(usb_dev, acm->readsize,
896
			  acm->read_buffers[i].base, acm->read_buffers[i].dma);
897 898
}

899 900 901 902 903 904
/* Little helper: write buffers allocate */
static int acm_write_buffers_alloc(struct acm *acm)
{
	int i;
	struct acm_wb *wb;

905
	for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
906
		wb->buf = usb_alloc_coherent(acm->dev, acm->writesize, GFP_KERNEL,
907 908 909 910 911
		    &wb->dmah);
		if (!wb->buf) {
			while (i != 0) {
				--i;
				--wb;
912
				usb_free_coherent(acm->dev, acm->writesize,
913 914 915 916 917 918 919 920
				    wb->buf, wb->dmah);
			}
			return -ENOMEM;
		}
	}
	return 0;
}

A
Alan Cox 已提交
921 922
static int acm_probe(struct usb_interface *intf,
		     const struct usb_device_id *id)
L
Linus Torvalds 已提交
923 924
{
	struct usb_cdc_union_desc *union_header = NULL;
925
	struct usb_cdc_country_functional_desc *cfd = NULL;
D
David Brownell 已提交
926
	unsigned char *buffer = intf->altsetting->extra;
L
Linus Torvalds 已提交
927 928 929
	int buflen = intf->altsetting->extralen;
	struct usb_interface *control_interface;
	struct usb_interface *data_interface;
930 931 932
	struct usb_endpoint_descriptor *epctrl = NULL;
	struct usb_endpoint_descriptor *epread = NULL;
	struct usb_endpoint_descriptor *epwrite = NULL;
L
Linus Torvalds 已提交
933 934 935
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct acm *acm;
	int minor;
936
	int ctrlsize, readsize;
L
Linus Torvalds 已提交
937 938 939 940
	u8 *buf;
	u8 ac_management_function = 0;
	u8 call_management_function = 0;
	int call_interface_num = -1;
941
	int data_interface_num = -1;
L
Linus Torvalds 已提交
942
	unsigned long quirks;
943
	int num_rx_buf;
944
	int i;
945
	int combined_interfaces = 0;
946 947
	struct device *tty_dev;
	int rv = -ENOMEM;
L
Linus Torvalds 已提交
948

949
	/* normal quirks */
L
Linus Torvalds 已提交
950
	quirks = (unsigned long)id->driver_info;
951 952 953 954

	if (quirks == IGNORE_DEVICE)
		return -ENODEV;

955 956 957
	num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;

	/* handle quirks deadly to normal probing*/
L
Linus Torvalds 已提交
958 959 960 961 962
	if (quirks == NO_UNION_NORMAL) {
		data_interface = usb_ifnum_to_if(usb_dev, 1);
		control_interface = usb_ifnum_to_if(usb_dev, 0);
		goto skip_normal_probe;
	}
963

L
Linus Torvalds 已提交
964 965
	/* normal probing*/
	if (!buffer) {
966
		dev_err(&intf->dev, "Weird descriptor references\n");
L
Linus Torvalds 已提交
967 968 969 970
		return -EINVAL;
	}

	if (!buflen) {
971 972
		if (intf->cur_altsetting->endpoint &&
				intf->cur_altsetting->endpoint->extralen &&
973 974 975
				intf->cur_altsetting->endpoint->extra) {
			dev_dbg(&intf->dev,
				"Seeking extra descriptors on endpoint\n");
L
Linus Torvalds 已提交
976 977 978
			buflen = intf->cur_altsetting->endpoint->extralen;
			buffer = intf->cur_altsetting->endpoint->extra;
		} else {
979 980
			dev_err(&intf->dev,
				"Zero length descriptor references\n");
L
Linus Torvalds 已提交
981 982 983 984 985
			return -EINVAL;
		}
	}

	while (buflen > 0) {
986
		if (buffer[1] != USB_DT_CS_INTERFACE) {
987
			dev_err(&intf->dev, "skipping garbage\n");
L
Linus Torvalds 已提交
988 989 990
			goto next_desc;
		}

991 992 993 994 995 996
		switch (buffer[2]) {
		case USB_CDC_UNION_TYPE: /* we've found it */
			if (union_header) {
				dev_err(&intf->dev, "More than one "
					"union descriptor, skipping ...\n");
				goto next_desc;
L
Linus Torvalds 已提交
997
			}
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
			union_header = (struct usb_cdc_union_desc *)buffer;
			break;
		case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/
			cfd = (struct usb_cdc_country_functional_desc *)buffer;
			break;
		case USB_CDC_HEADER_TYPE: /* maybe check version */
			break; /* for now we ignore it */
		case USB_CDC_ACM_TYPE:
			ac_management_function = buffer[3];
			break;
		case USB_CDC_CALL_MANAGEMENT_TYPE:
			call_management_function = buffer[3];
			call_interface_num = buffer[4];
1011
			if ((quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3)
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
				dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n");
			break;
		default:
			/* there are LOTS more CDC descriptors that
			 * could legitimately be found here.
			 */
			dev_dbg(&intf->dev, "Ignoring descriptor: "
					"type %02x, length %d\n",
					buffer[2], buffer[0]);
			break;
		}
L
Linus Torvalds 已提交
1023 1024 1025 1026 1027 1028 1029
next_desc:
		buflen -= buffer[0];
		buffer += buffer[0];
	}

	if (!union_header) {
		if (call_interface_num > 0) {
1030
			dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n");
1031 1032 1033 1034 1035
			/* quirks for Droids MuIn LCD */
			if (quirks & NO_DATA_INTERFACE)
				data_interface = usb_ifnum_to_if(usb_dev, 0);
			else
				data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
L
Linus Torvalds 已提交
1036 1037
			control_interface = intf;
		} else {
1038 1039 1040 1041 1042 1043 1044 1045 1046
			if (intf->cur_altsetting->desc.bNumEndpoints != 3) {
				dev_dbg(&intf->dev,"No union descriptor, giving up\n");
				return -ENODEV;
			} else {
				dev_warn(&intf->dev,"No union descriptor, testing for castrated device\n");
				combined_interfaces = 1;
				control_interface = data_interface = intf;
				goto look_for_collapsed_interface;
			}
L
Linus Torvalds 已提交
1047 1048 1049 1050 1051
		}
	} else {
		control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
		data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
		if (!control_interface || !data_interface) {
1052
			dev_dbg(&intf->dev, "no interfaces\n");
L
Linus Torvalds 已提交
1053 1054 1055
			return -ENODEV;
		}
	}
1056

L
Linus Torvalds 已提交
1057
	if (data_interface_num != call_interface_num)
1058
		dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n");
L
Linus Torvalds 已提交
1059

1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
	if (control_interface == data_interface) {
		/* some broken devices designed for windows work this way */
		dev_warn(&intf->dev,"Control and data interfaces are not separated!\n");
		combined_interfaces = 1;
		/* a popular other OS doesn't use it */
		quirks |= NO_CAP_LINE;
		if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) {
			dev_err(&intf->dev, "This needs exactly 3 endpoints\n");
			return -EINVAL;
		}
look_for_collapsed_interface:
		for (i = 0; i < 3; i++) {
			struct usb_endpoint_descriptor *ep;
			ep = &data_interface->cur_altsetting->endpoint[i].desc;

			if (usb_endpoint_is_int_in(ep))
				epctrl = ep;
			else if (usb_endpoint_is_bulk_out(ep))
				epwrite = ep;
			else if (usb_endpoint_is_bulk_in(ep))
				epread = ep;
			else
				return -EINVAL;
		}
		if (!epctrl || !epread || !epwrite)
			return -ENODEV;
		else
			goto made_compressed_probe;
	}

L
Linus Torvalds 已提交
1090 1091 1092
skip_normal_probe:

	/*workaround for switched interfaces */
1093 1094 1095 1096
	if (data_interface->cur_altsetting->desc.bInterfaceClass
						!= CDC_DATA_INTERFACE_TYPE) {
		if (control_interface->cur_altsetting->desc.bInterfaceClass
						== CDC_DATA_INTERFACE_TYPE) {
L
Linus Torvalds 已提交
1097
			struct usb_interface *t;
1098 1099
			dev_dbg(&intf->dev,
				"Your device has switched interfaces.\n");
L
Linus Torvalds 已提交
1100 1101 1102 1103 1104 1105 1106
			t = control_interface;
			control_interface = data_interface;
			data_interface = t;
		} else {
			return -EINVAL;
		}
	}
1107 1108

	/* Accept probe requests only for the control interface */
1109
	if (!combined_interfaces && intf != control_interface)
1110
		return -ENODEV;
1111

1112 1113
	if (!combined_interfaces && usb_interface_claimed(data_interface)) {
		/* valid in this context */
1114
		dev_dbg(&intf->dev, "The data interface isn't available\n");
L
Linus Torvalds 已提交
1115 1116 1117 1118
		return -EBUSY;
	}


1119 1120
	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 ||
	    control_interface->cur_altsetting->desc.bNumEndpoints == 0)
L
Linus Torvalds 已提交
1121 1122 1123 1124 1125 1126 1127 1128
		return -EINVAL;

	epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
	epread = &data_interface->cur_altsetting->endpoint[0].desc;
	epwrite = &data_interface->cur_altsetting->endpoint[1].desc;


	/* workaround for switched endpoints */
1129
	if (!usb_endpoint_dir_in(epread)) {
L
Linus Torvalds 已提交
1130 1131
		/* descriptors are swapped */
		struct usb_endpoint_descriptor *t;
1132 1133
		dev_dbg(&intf->dev,
			"The data interface has switched endpoints\n");
L
Linus Torvalds 已提交
1134 1135 1136 1137
		t = epread;
		epread = epwrite;
		epwrite = t;
	}
1138
made_compressed_probe:
1139
	dev_dbg(&intf->dev, "interfaces are valid\n");
L
Linus Torvalds 已提交
1140

1141 1142
	acm = kzalloc(sizeof(struct acm), GFP_KERNEL);
	if (acm == NULL) {
1143
		dev_err(&intf->dev, "out of memory (acm kzalloc)\n");
L
Linus Torvalds 已提交
1144 1145 1146
		goto alloc_fail;
	}

1147 1148 1149 1150 1151 1152 1153
	minor = acm_alloc_minor(acm);
	if (minor == ACM_TTY_MINORS) {
		dev_err(&intf->dev, "no more free acm devices\n");
		kfree(acm);
		return -ENODEV;
	}

1154 1155
	ctrlsize = usb_endpoint_maxp(epctrl);
	readsize = usb_endpoint_maxp(epread) *
1156
				(quirks == SINGLE_RX_URB ? 1 : 2);
1157
	acm->combined_interfaces = combined_interfaces;
1158
	acm->writesize = usb_endpoint_maxp(epwrite) * 20;
L
Linus Torvalds 已提交
1159 1160 1161 1162 1163
	acm->control = control_interface;
	acm->data = data_interface;
	acm->minor = minor;
	acm->dev = usb_dev;
	acm->ctrl_caps = ac_management_function;
1164 1165
	if (quirks & NO_CAP_LINE)
		acm->ctrl_caps &= ~USB_CDC_CAP_LINE;
L
Linus Torvalds 已提交
1166 1167
	acm->ctrlsize = ctrlsize;
	acm->readsize = readsize;
1168
	acm->rx_buflimit = num_rx_buf;
D
David Howells 已提交
1169
	INIT_WORK(&acm->work, acm_softint);
1170
	spin_lock_init(&acm->write_lock);
1171
	spin_lock_init(&acm->read_lock);
O
Oliver Neukum 已提交
1172
	mutex_init(&acm->mutex);
1173
	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
1174 1175 1176
	acm->is_int_ep = usb_endpoint_xfer_int(epread);
	if (acm->is_int_ep)
		acm->bInterval = epread->bInterval;
A
Alan Cox 已提交
1177 1178
	tty_port_init(&acm->port);
	acm->port.ops = &acm_port_ops;
L
Linus Torvalds 已提交
1179

1180
	buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
L
Linus Torvalds 已提交
1181
	if (!buf) {
1182
		dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n");
L
Linus Torvalds 已提交
1183 1184 1185 1186
		goto alloc_fail2;
	}
	acm->ctrl_buffer = buf;

1187
	if (acm_write_buffers_alloc(acm) < 0) {
1188
		dev_err(&intf->dev, "out of memory (write buffer alloc)\n");
L
Linus Torvalds 已提交
1189 1190 1191 1192 1193
		goto alloc_fail4;
	}

	acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
	if (!acm->ctrlurb) {
1194
		dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
L
Linus Torvalds 已提交
1195 1196
		goto alloc_fail5;
	}
1197
	for (i = 0; i < num_rx_buf; i++) {
1198 1199
		struct acm_rb *rb = &(acm->read_buffers[i]);
		struct urb *urb;
1200

1201 1202 1203 1204 1205 1206 1207
		rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL,
								&rb->dma);
		if (!rb->base) {
			dev_err(&intf->dev, "out of memory "
					"(read bufs usb_alloc_coherent)\n");
			goto alloc_fail6;
		}
1208 1209
		rb->index = i;
		rb->instance = acm;
1210

1211 1212
		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
1213
			dev_err(&intf->dev,
1214
				"out of memory (read urbs usb_alloc_urb)\n");
1215
			goto alloc_fail6;
1216
		}
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		urb->transfer_dma = rb->dma;
		if (acm->is_int_ep) {
			usb_fill_int_urb(urb, acm->dev,
					 acm->rx_endpoint,
					 rb->base,
					 acm->readsize,
					 acm_read_bulk_callback, rb,
					 acm->bInterval);
		} else {
			usb_fill_bulk_urb(urb, acm->dev,
					  acm->rx_endpoint,
					  rb->base,
					  acm->readsize,
					  acm_read_bulk_callback, rb);
		}
1233

1234 1235
		acm->read_urbs[i] = urb;
		__set_bit(i, &acm->read_urbs_free);
1236
	}
1237
	for (i = 0; i < ACM_NW; i++) {
1238 1239
		struct acm_wb *snd = &(acm->wb[i]);

1240 1241
		snd->urb = usb_alloc_urb(0, GFP_KERNEL);
		if (snd->urb == NULL) {
1242
			dev_err(&intf->dev,
1243
				"out of memory (write urbs usb_alloc_urb)\n");
1244
			goto alloc_fail7;
1245 1246
		}

1247 1248
		if (usb_endpoint_xfer_int(epwrite))
			usb_fill_int_urb(snd->urb, usb_dev,
1249
				usb_sndintpipe(usb_dev, epwrite->bEndpointAddress),
1250 1251 1252 1253 1254
				NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
		else
			usb_fill_bulk_urb(snd->urb, usb_dev,
				usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
				NULL, acm->writesize, acm_write_bulk, snd);
1255 1256
		snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		snd->instance = acm;
L
Linus Torvalds 已提交
1257 1258
	}

1259
	usb_set_intfdata(intf, acm);
1260 1261 1262

	i = device_create_file(&intf->dev, &dev_attr_bmCapabilities);
	if (i < 0)
1263
		goto alloc_fail7;
1264 1265 1266 1267 1268 1269

	if (cfd) { /* export the country data */
		acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL);
		if (!acm->country_codes)
			goto skip_countries;
		acm->country_code_size = cfd->bLength - 4;
1270 1271
		memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0,
							cfd->bLength - 4);
1272 1273 1274 1275 1276
		acm->country_rel_date = cfd->iCountryCodeRelDate;

		i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
		if (i < 0) {
			kfree(acm->country_codes);
1277 1278
			acm->country_codes = NULL;
			acm->country_code_size = 0;
1279 1280 1281
			goto skip_countries;
		}

1282 1283
		i = device_create_file(&intf->dev,
						&dev_attr_iCountryCodeRelDate);
1284
		if (i < 0) {
1285
			device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
1286
			kfree(acm->country_codes);
1287 1288
			acm->country_codes = NULL;
			acm->country_code_size = 0;
1289 1290 1291 1292 1293
			goto skip_countries;
		}
	}

skip_countries:
1294
	usb_fill_int_urb(acm->ctrlurb, usb_dev,
1295 1296 1297
			 usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
			 acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm,
			 /* works around buggy devices */
1298
			 epctrl->bInterval ? epctrl->bInterval : 16);
L
Linus Torvalds 已提交
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
	acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	acm->ctrlurb->transfer_dma = acm->ctrl_dma;

	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);

	acm_set_control(acm, acm->ctrlout);

	acm->line.dwDTERate = cpu_to_le32(9600);
	acm->line.bDataBits = 8;
	acm_set_line(acm, &acm->line);

	usb_driver_claim_interface(&acm_driver, data_interface, acm);
D
David Brownell 已提交
1311
	usb_set_intfdata(data_interface, acm);
L
Linus Torvalds 已提交
1312

1313
	usb_get_intf(control_interface);
1314
	tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
J
Jiri Slaby 已提交
1315
			&control_interface->dev);
1316 1317 1318 1319
	if (IS_ERR(tty_dev)) {
		rv = PTR_ERR(tty_dev);
		goto alloc_fail8;
	}
L
Linus Torvalds 已提交
1320

1321
	return 0;
1322 1323 1324 1325 1326 1327 1328 1329
alloc_fail8:
	if (acm->country_codes) {
		device_remove_file(&acm->control->dev,
				&dev_attr_wCountryCodes);
		device_remove_file(&acm->control->dev,
				&dev_attr_iCountryCodeRelDate);
	}
	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
1330
alloc_fail7:
1331
	usb_set_intfdata(intf, NULL);
1332 1333
	for (i = 0; i < ACM_NW; i++)
		usb_free_urb(acm->wb[i].urb);
1334
alloc_fail6:
1335
	for (i = 0; i < num_rx_buf; i++)
1336
		usb_free_urb(acm->read_urbs[i]);
1337
	acm_read_buffers_free(acm);
L
Linus Torvalds 已提交
1338 1339
	usb_free_urb(acm->ctrlurb);
alloc_fail5:
1340
	acm_write_buffers_free(acm);
L
Linus Torvalds 已提交
1341
alloc_fail4:
1342
	usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
L
Linus Torvalds 已提交
1343
alloc_fail2:
1344
	acm_release_minor(acm);
L
Linus Torvalds 已提交
1345 1346
	kfree(acm);
alloc_fail:
1347
	return rv;
L
Linus Torvalds 已提交
1348 1349
}

O
Oliver Neukum 已提交
1350 1351 1352
static void stop_data_traffic(struct acm *acm)
{
	int i;
1353 1354

	dev_dbg(&acm->control->dev, "%s\n", __func__);
O
Oliver Neukum 已提交
1355 1356

	usb_kill_urb(acm->ctrlurb);
1357
	for (i = 0; i < ACM_NW; i++)
1358
		usb_kill_urb(acm->wb[i].urb);
O
Oliver Neukum 已提交
1359
	for (i = 0; i < acm->rx_buflimit; i++)
1360
		usb_kill_urb(acm->read_urbs[i]);
O
Oliver Neukum 已提交
1361 1362 1363 1364

	cancel_work_sync(&acm->work);
}

L
Linus Torvalds 已提交
1365 1366
static void acm_disconnect(struct usb_interface *intf)
{
1367
	struct acm *acm = usb_get_intfdata(intf);
L
Linus Torvalds 已提交
1368
	struct usb_device *usb_dev = interface_to_usbdev(intf);
A
Alan Cox 已提交
1369
	struct tty_struct *tty;
1370 1371 1372
	int i;

	dev_dbg(&intf->dev, "%s\n", __func__);
L
Linus Torvalds 已提交
1373

D
David Brownell 已提交
1374 1375
	/* sibling interface is already cleaning up */
	if (!acm)
1376
		return;
D
David Brownell 已提交
1377

1378 1379
	mutex_lock(&acm->mutex);
	acm->disconnected = true;
1380
	if (acm->country_codes) {
1381 1382 1383 1384
		device_remove_file(&acm->control->dev,
				&dev_attr_wCountryCodes);
		device_remove_file(&acm->control->dev,
				&dev_attr_iCountryCodeRelDate);
1385
	}
1386
	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
1387 1388
	usb_set_intfdata(acm->control, NULL);
	usb_set_intfdata(acm->data, NULL);
1389 1390 1391 1392 1393 1394 1395
	mutex_unlock(&acm->mutex);

	tty = tty_port_tty_get(&acm->port);
	if (tty) {
		tty_vhangup(tty);
		tty_kref_put(tty);
	}
L
Linus Torvalds 已提交
1396

O
Oliver Neukum 已提交
1397
	stop_data_traffic(acm);
L
Linus Torvalds 已提交
1398

1399 1400
	tty_unregister_device(acm_tty_driver, acm->minor);

1401 1402 1403 1404 1405
	usb_free_urb(acm->ctrlurb);
	for (i = 0; i < ACM_NW; i++)
		usb_free_urb(acm->wb[i].urb);
	for (i = 0; i < acm->rx_buflimit; i++)
		usb_free_urb(acm->read_urbs[i]);
1406
	acm_write_buffers_free(acm);
1407
	usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
1408
	acm_read_buffers_free(acm);
L
Linus Torvalds 已提交
1409

1410 1411
	if (!acm->combined_interfaces)
		usb_driver_release_interface(&acm_driver, intf == acm->control ?
1412
					acm->data : acm->control);
L
Linus Torvalds 已提交
1413

1414
	tty_port_put(&acm->port);
L
Linus Torvalds 已提交
1415 1416
}

1417
#ifdef CONFIG_PM
O
Oliver Neukum 已提交
1418 1419 1420
static int acm_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct acm *acm = usb_get_intfdata(intf);
1421 1422
	int cnt;

1423
	if (PMSG_IS_AUTO(message)) {
1424 1425
		int b;

1426 1427 1428
		spin_lock_irq(&acm->write_lock);
		b = acm->transmitting;
		spin_unlock_irq(&acm->write_lock);
1429 1430 1431 1432 1433 1434 1435 1436 1437
		if (b)
			return -EBUSY;
	}

	spin_lock_irq(&acm->read_lock);
	spin_lock(&acm->write_lock);
	cnt = acm->susp_count++;
	spin_unlock(&acm->write_lock);
	spin_unlock_irq(&acm->read_lock);
O
Oliver Neukum 已提交
1438

1439
	if (cnt)
O
Oliver Neukum 已提交
1440 1441
		return 0;

1442
	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
O
Oliver Neukum 已提交
1443 1444 1445 1446 1447 1448 1449 1450
		stop_data_traffic(acm);

	return 0;
}

static int acm_resume(struct usb_interface *intf)
{
	struct acm *acm = usb_get_intfdata(intf);
1451
	struct acm_wb *wb;
O
Oliver Neukum 已提交
1452
	int rv = 0;
1453
	int cnt;
O
Oliver Neukum 已提交
1454

1455 1456 1457 1458 1459 1460
	spin_lock_irq(&acm->read_lock);
	acm->susp_count -= 1;
	cnt = acm->susp_count;
	spin_unlock_irq(&acm->read_lock);

	if (cnt)
O
Oliver Neukum 已提交
1461 1462
		return 0;

1463
	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
O
Oliver Neukum 已提交
1464
		rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
1465 1466 1467 1468 1469 1470

		spin_lock_irq(&acm->write_lock);
		if (acm->delayed_wb) {
			wb = acm->delayed_wb;
			acm->delayed_wb = NULL;
			spin_unlock_irq(&acm->write_lock);
1471
			acm_start_wb(acm, wb);
1472 1473 1474 1475 1476 1477 1478 1479
		} else {
			spin_unlock_irq(&acm->write_lock);
		}

		/*
		 * delayed error checking because we must
		 * do the write path at all cost
		 */
O
Oliver Neukum 已提交
1480
		if (rv < 0)
1481
			goto err_out;
O
Oliver Neukum 已提交
1482

1483
		rv = acm_submit_read_urbs(acm, GFP_NOIO);
O
Oliver Neukum 已提交
1484 1485 1486 1487 1488
	}

err_out:
	return rv;
}
1489

1490 1491 1492 1493
static int acm_reset_resume(struct usb_interface *intf)
{
	struct acm *acm = usb_get_intfdata(intf);

J
Jiri Slaby 已提交
1494 1495
	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
		tty_port_tty_hangup(&acm->port, false);
1496

1497 1498 1499
	return acm_resume(intf);
}

1500
#endif /* CONFIG_PM */
1501 1502 1503 1504 1505 1506

#define NOKIA_PCSUITE_ACM_INFO(x) \
		USB_DEVICE_AND_INTERFACE_INFO(0x0421, x, \
		USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
		USB_CDC_ACM_PROTO_VENDOR)

1507 1508 1509 1510 1511
#define SAMSUNG_PCSUITE_ACM_INFO(x) \
		USB_DEVICE_AND_INTERFACE_INFO(0x04e7, x, \
		USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
		USB_CDC_ACM_PROTO_VENDOR)

L
Linus Torvalds 已提交
1512 1513 1514 1515
/*
 * USB driver structure.
 */

1516
static const struct usb_device_id acm_ids[] = {
L
Linus Torvalds 已提交
1517
	/* quirky and broken devices */
1518 1519
	{ USB_DEVICE(0x17ef, 0x7000), /* Lenovo USB modem */
	.driver_info = NO_UNION_NORMAL, },/* has no union descriptor */
L
Linus Torvalds 已提交
1520 1521 1522
	{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1523 1524 1525
	{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
A
Andrew Lunn 已提交
1526 1527 1528
	{ USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1529 1530 1531
	{ USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1532 1533 1534
	{ USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
A
Alan Cox 已提交
1535 1536 1537
	{ USB_DEVICE(0x0ace, 0x1602), /* ZyDAS 56K USB MODEM */
	.driver_info = SINGLE_RX_URB,
	},
1538 1539 1540
	{ USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
	.driver_info = SINGLE_RX_URB, /* firmware bug */
	},
1541 1542 1543
	{ USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
	.driver_info = SINGLE_RX_URB, /* firmware bug */
	},
O
Oliver Neukum 已提交
1544 1545 1546
	{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1547 1548 1549
	{ USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1550 1551 1552
	{ USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1553 1554 1555
	{ USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1556 1557 1558
	{ USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
1559 1560
	{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
	},
1561 1562 1563 1564 1565 1566 1567 1568 1569 1570
	/* Motorola H24 HSPA module: */
	{ USB_DEVICE(0x22b8, 0x2d91) }, /* modem                                */
	{ USB_DEVICE(0x22b8, 0x2d92) }, /* modem           + diagnostics        */
	{ USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port                      */
	{ USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics        */
	{ USB_DEVICE(0x22b8, 0x2d96) }, /* modem                         + NMEA */
	{ USB_DEVICE(0x22b8, 0x2d97) }, /* modem           + diagnostics + NMEA */
	{ USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port               + NMEA */
	{ USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */

1571 1572 1573 1574 1575 1576 1577
	{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
	.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
					   data interface instead of
					   communications interface.
					   Maybe we should define a new
					   quirk for this. */
	},
1578 1579 1580
	{ USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */
	.driver_info = NO_UNION_NORMAL,
	},
1581 1582 1583
	{ USB_DEVICE(0x05f9, 0x4002), /* PSC Scanning, Magellan 800i */
	.driver_info = NO_UNION_NORMAL,
	},
1584 1585 1586
	{ USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
	},
1587 1588 1589
	{ USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
	},
O
Oliver Neukum 已提交
1590

1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638
	/* Nokia S60 phones expose two ACM channels. The first is
	 * a modem and is picked up by the standard AT-command
	 * information below. The second is 'vendor-specific' but
	 * is treated as a serial device at the S60 end, so we want
	 * to expose it on Linux too. */
	{ NOKIA_PCSUITE_ACM_INFO(0x042D), }, /* Nokia 3250 */
	{ NOKIA_PCSUITE_ACM_INFO(0x04D8), }, /* Nokia 5500 Sport */
	{ NOKIA_PCSUITE_ACM_INFO(0x04C9), }, /* Nokia E50 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0419), }, /* Nokia E60 */
	{ NOKIA_PCSUITE_ACM_INFO(0x044D), }, /* Nokia E61 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0001), }, /* Nokia E61i */
	{ NOKIA_PCSUITE_ACM_INFO(0x0475), }, /* Nokia E62 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0508), }, /* Nokia E65 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0418), }, /* Nokia E70 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0425), }, /* Nokia N71 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0486), }, /* Nokia N73 */
	{ NOKIA_PCSUITE_ACM_INFO(0x04DF), }, /* Nokia N75 */
	{ NOKIA_PCSUITE_ACM_INFO(0x000e), }, /* Nokia N77 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0445), }, /* Nokia N80 */
	{ NOKIA_PCSUITE_ACM_INFO(0x042F), }, /* Nokia N91 & N91 8GB */
	{ NOKIA_PCSUITE_ACM_INFO(0x048E), }, /* Nokia N92 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0420), }, /* Nokia N93 */
	{ NOKIA_PCSUITE_ACM_INFO(0x04E6), }, /* Nokia N93i  */
	{ NOKIA_PCSUITE_ACM_INFO(0x04B2), }, /* Nokia 5700 XpressMusic */
	{ NOKIA_PCSUITE_ACM_INFO(0x0134), }, /* Nokia 6110 Navigator (China) */
	{ NOKIA_PCSUITE_ACM_INFO(0x046E), }, /* Nokia 6110 Navigator */
	{ NOKIA_PCSUITE_ACM_INFO(0x002f), }, /* Nokia 6120 classic &  */
	{ NOKIA_PCSUITE_ACM_INFO(0x0088), }, /* Nokia 6121 classic */
	{ NOKIA_PCSUITE_ACM_INFO(0x00fc), }, /* Nokia 6124 classic */
	{ NOKIA_PCSUITE_ACM_INFO(0x0042), }, /* Nokia E51 */
	{ NOKIA_PCSUITE_ACM_INFO(0x00b0), }, /* Nokia E66 */
	{ NOKIA_PCSUITE_ACM_INFO(0x00ab), }, /* Nokia E71 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0481), }, /* Nokia N76 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0007), }, /* Nokia N81 & N81 8GB */
	{ NOKIA_PCSUITE_ACM_INFO(0x0071), }, /* Nokia N82 */
	{ NOKIA_PCSUITE_ACM_INFO(0x04F0), }, /* Nokia N95 & N95-3 NAM */
	{ NOKIA_PCSUITE_ACM_INFO(0x0070), }, /* Nokia N95 8GB  */
	{ NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
	{ NOKIA_PCSUITE_ACM_INFO(0x0099), }, /* Nokia 6210 Navigator, RM-367 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0128), }, /* Nokia 6210 Navigator, RM-419 */
	{ NOKIA_PCSUITE_ACM_INFO(0x008f), }, /* Nokia 6220 Classic */
	{ NOKIA_PCSUITE_ACM_INFO(0x00a0), }, /* Nokia 6650 */
	{ NOKIA_PCSUITE_ACM_INFO(0x007b), }, /* Nokia N78 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0094), }, /* Nokia N85 */
	{ NOKIA_PCSUITE_ACM_INFO(0x003a), }, /* Nokia N96 & N96-3  */
	{ NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
	{ NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */
	{ NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */
1639
	{ NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */
1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
	{ NOKIA_PCSUITE_ACM_INFO(0x0178), }, /* Nokia E63 */
	{ NOKIA_PCSUITE_ACM_INFO(0x010e), }, /* Nokia E75 */
	{ NOKIA_PCSUITE_ACM_INFO(0x02d9), }, /* Nokia 6760 Slide */
	{ NOKIA_PCSUITE_ACM_INFO(0x01d0), }, /* Nokia E52 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0223), }, /* Nokia E72 */
	{ NOKIA_PCSUITE_ACM_INFO(0x0275), }, /* Nokia X6 */
	{ NOKIA_PCSUITE_ACM_INFO(0x026c), }, /* Nokia N97 Mini */
	{ NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */
	{ NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */
	{ NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */
1650
	{ NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */
1651 1652
	{ NOKIA_PCSUITE_ACM_INFO(0x0335), }, /* Nokia E7 */
	{ NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */
1653
	{ SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
1654

D
Denis Pershin 已提交
1655 1656 1657
	/* Support for Owen devices */
	{ USB_DEVICE(0x03eb, 0x0030), }, /* Owen SI30 */

1658 1659
	/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */

1660
	/* Support Lego NXT using pbLua firmware */
1661 1662
	{ USB_DEVICE(0x0694, 0xff00),
	.driver_info = NOT_A_MODEM,
1663
	},
1664

1665 1666 1667 1668 1669
	/* Support for Droids MuIn LCD */
	{ USB_DEVICE(0x04d8, 0x000b),
	.driver_info = NO_DATA_INTERFACE,
	},

1670 1671 1672 1673 1674 1675 1676 1677 1678
#if IS_ENABLED(CONFIG_INPUT_IMS_PCU)
	{ USB_DEVICE(0x04d8, 0x0082),	/* Application mode */
	.driver_info = IGNORE_DEVICE,
	},
	{ USB_DEVICE(0x04d8, 0x0083),	/* Bootloader mode */
	.driver_info = IGNORE_DEVICE,
	},
#endif

1679 1680 1681 1682
	/* control interfaces without any protocol set */
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
		USB_CDC_PROTO_NONE) },

L
Linus Torvalds 已提交
1683 1684 1685 1686 1687 1688 1689 1690 1691 1692
	/* control interfaces with various AT-command sets */
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
		USB_CDC_ACM_PROTO_AT_V25TER) },
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
		USB_CDC_ACM_PROTO_AT_PCCA101) },
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
		USB_CDC_ACM_PROTO_AT_PCCA101_WAKE) },
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
		USB_CDC_ACM_PROTO_AT_GSM) },
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1693
		USB_CDC_ACM_PROTO_AT_3G) },
L
Linus Torvalds 已提交
1694 1695 1696 1697 1698 1699
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
		USB_CDC_ACM_PROTO_AT_CDMA) },

	{ }
};

1700
MODULE_DEVICE_TABLE(usb, acm_ids);
L
Linus Torvalds 已提交
1701 1702 1703 1704 1705

static struct usb_driver acm_driver = {
	.name =		"cdc_acm",
	.probe =	acm_probe,
	.disconnect =	acm_disconnect,
1706
#ifdef CONFIG_PM
O
Oliver Neukum 已提交
1707 1708
	.suspend =	acm_suspend,
	.resume =	acm_resume,
1709
	.reset_resume =	acm_reset_resume,
1710
#endif
L
Linus Torvalds 已提交
1711
	.id_table =	acm_ids,
1712
#ifdef CONFIG_PM
O
Oliver Neukum 已提交
1713
	.supports_autosuspend = 1,
1714
#endif
1715
	.disable_hub_initiated_lpm = 1,
L
Linus Torvalds 已提交
1716 1717 1718 1719 1720 1721
};

/*
 * TTY driver structures.
 */

J
Jeff Dike 已提交
1722
static const struct tty_operations acm_ops = {
1723
	.install =		acm_tty_install,
L
Linus Torvalds 已提交
1724 1725
	.open =			acm_tty_open,
	.close =		acm_tty_close,
1726
	.cleanup =		acm_tty_cleanup,
A
Alan Cox 已提交
1727
	.hangup =		acm_tty_hangup,
L
Linus Torvalds 已提交
1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
	.write =		acm_tty_write,
	.write_room =		acm_tty_write_room,
	.ioctl =		acm_tty_ioctl,
	.throttle =		acm_tty_throttle,
	.unthrottle =		acm_tty_unthrottle,
	.chars_in_buffer =	acm_tty_chars_in_buffer,
	.break_ctl =		acm_tty_break_ctl,
	.set_termios =		acm_tty_set_termios,
	.tiocmget =		acm_tty_tiocmget,
	.tiocmset =		acm_tty_tiocmset,
};

/*
 * Init / exit.
 */

static int __init acm_init(void)
{
	int retval;
	acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS);
	if (!acm_tty_driver)
		return -ENOMEM;
	acm_tty_driver->driver_name = "acm",
	acm_tty_driver->name = "ttyACM",
	acm_tty_driver->major = ACM_TTY_MAJOR,
	acm_tty_driver->minor_start = 0,
	acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
	acm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
1756
	acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
L
Linus Torvalds 已提交
1757
	acm_tty_driver->init_termios = tty_std_termios;
1758 1759
	acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD |
								HUPCL | CLOCAL;
L
Linus Torvalds 已提交
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
	tty_set_operations(acm_tty_driver, &acm_ops);

	retval = tty_register_driver(acm_tty_driver);
	if (retval) {
		put_tty_driver(acm_tty_driver);
		return retval;
	}

	retval = usb_register(&acm_driver);
	if (retval) {
		tty_unregister_driver(acm_tty_driver);
		put_tty_driver(acm_tty_driver);
		return retval;
	}

1775
	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
L
Linus Torvalds 已提交
1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789

	return 0;
}

static void __exit acm_exit(void)
{
	usb_deregister(&acm_driver);
	tty_unregister_driver(acm_tty_driver);
	put_tty_driver(acm_tty_driver);
}

module_init(acm_init);
module_exit(acm_exit);

1790 1791
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
L
Linus Torvalds 已提交
1792
MODULE_LICENSE("GPL");
1793
MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR);