4 * Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de> 5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> 6 * Copyright (c) 1999 Johannes Erdfelt <jerdfelt@valinux.com> 7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> 9 * USB Abstract Control Model driver for USB modems and ISDN adapters 14 * v0.9 - thorough cleaning, URBification, almost a rewrite 15 * v0.10 - some more cleanups 16 * v0.11 - fixed flow control, read error doesn't stop reads 17 * v0.12 - added TIOCM ioctls, added break handling, made struct acm kmalloced 18 * v0.13 - added termios, added hangup 19 * v0.14 - sized down struct acm 20 * v0.15 - fixed flow control again - characters could be lost 21 * v0.16 - added code for modems with swapped data and control interfaces 22 * v0.17 - added new style probing 23 * v0.18 - fixed new style probing for devices with more configurations 27 * This program is free software; you can redistribute it and/or modify 28 * it under the terms of the GNU General Public License as published by 29 * the Free Software Foundation; either version 2 of the License, or 30 * (at your option) any later version. 32 * This program is distributed in the hope that it will be useful, 33 * but WITHOUT ANY WARRANTY; without even the implied warranty of 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 * GNU General Public License for more details. 37 * You should have received a copy of the GNU General Public License 38 * along with this program; if not, write to the Free Software 39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 42 #include <linux/kernel.h> 43 #include <linux/sched.h> 44 #include <linux/signal.h> 45 #include <linux/errno.h> 46 #include <linux/poll.h> 47 #include <linux/init.h> 48 #include <linux/malloc.h> 49 #include <linux/fcntl.h> 50 #include <linux/tty_driver.h> 51 #include <linux/tty_flip.h> 52 #include <linux/tty.h> 53 #include <linux/module.h> 55 #include <linux/usb.h> 58 * CMSPAR, some architectures can't have space and mark parity. 66 * Major and minor numbers. 69 #define ACM_TTY_MAJOR 166 70 #define ACM_TTY_MINORS 32 76 #define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) 78 #define ACM_REQ_COMMAND 0x00 79 #define ACM_REQ_RESPONSE 0x01 80 #define ACM_REQ_SET_FEATURE 0x02 81 #define ACM_REQ_GET_FEATURE 0x03 82 #define ACM_REQ_CLEAR_FEATURE 0x04 84 #define ACM_REQ_SET_LINE 0x20 85 #define ACM_REQ_GET_LINE 0x21 86 #define ACM_REQ_SET_CONTROL 0x22 87 #define ACM_REQ_SEND_BREAK 0x23 93 #define ACM_IRQ_NETWORK 0x00 94 #define ACM_IRQ_LINE_STATE 0x20 97 * Output control lines. 100 #define ACM_CTRL_DTR 0x01 101 #define ACM_CTRL_RTS 0x02 104 * Input control lines and line errors. 107 #define ACM_CTRL_DCD 0x01 108 #define ACM_CTRL_DSR 0x02 109 #define ACM_CTRL_BRK 0x04 110 #define ACM_CTRL_RI 0x08 112 #define ACM_CTRL_FRAMING 0x10 113 #define ACM_CTRL_PARITY 0x20 114 #define ACM_CTRL_OVERRUN 0x40 117 * Line speed and caracter encoding. 125 }__attribute__((packed
)); 128 * Internal driver structures. 132 struct usb_device
*dev
;/* the coresponding usb device */ 133 struct usb_interface
*iface
;/* the interfaces - +0 control +1 data */ 134 struct tty_struct
*tty
;/* the coresponding tty */ 135 struct urb ctrlurb
, readurb
, writeurb
;/* urbs */ 136 struct acm_line line
;/* line coding (bits, stop, parity) */ 137 struct tq_struct tqueue
;/* task queue for line discipline waking up */ 138 unsigned int ctrlin
;/* input control lines (DCD, DSR, RI, break, overruns) */ 139 unsigned int ctrlout
;/* output control lines (DTR, RTS) */ 140 unsigned int writesize
;/* max packet size for the output bulk endpoint */ 141 unsigned int used
;/* someone has this acm's device open */ 142 unsigned int minor
;/* acm minor number */ 143 unsigned char throttle
;/* throttled by tty layer */ 144 unsigned char clocal
;/* termios CLOCAL */ 147 static struct usb_driver acm_driver
; 148 static struct tty_driver acm_tty_driver
; 149 static struct acm
*acm_table
[ACM_TTY_MINORS
]; 151 #define ACM_READY(acm) (acm && acm->dev && acm->used) 154 * Functions for ACM control messages. 157 static intacm_ctrl_msg(struct acm
*acm
,int request
,int value
,void*buf
,int len
) 159 int retval
=usb_control_msg(acm
->dev
,usb_sndctrlpipe(acm
->dev
,0), 160 request
, USB_RT_ACM
, value
, acm
->iface
[0].altsetting
[0].bInterfaceNumber
, buf
, len
, HZ
*5); 161 dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", request
, value
, len
, retval
); 162 return retval
<0? retval
:0; 165 #define acm_set_control(acm, control) acm_ctrl_msg(acm, ACM_REQ_SET_CONTROL, control, NULL, 0) 166 #define acm_set_line(acm, line) acm_ctrl_msg(acm, ACM_REQ_SET_LINE, 0, line, sizeof(struct acm_line)) 167 #define acm_send_break(acm, ms) acm_ctrl_msg(acm, ACM_REQ_SEND_BREAK, ms, NULL, 0) 170 * Interrupt handler for various ACM control events 173 static voidacm_ctrl_irq(struct urb
*urb
) 175 struct acm
*acm
= urb
->context
; 176 devrequest
*dr
= urb
->transfer_buffer
; 177 unsigned char*data
= (unsigned char*)(dr
+1); 180 if(!ACM_READY(acm
))return; 183 dbg("nonzero ctrl irq status received: %d", urb
->status
); 187 switch(dr
->request
) { 189 case ACM_IRQ_NETWORK
: 191 dbg("%s network", data
[0] ?"connected to":"disconnected from"); 194 case ACM_IRQ_LINE_STATE
: 196 newctrl
=le16_to_cpup((__u16
*) data
); 199 /* Please someone tell me how to do this properly to kill pppd and not kill minicom */ 200 if(acm
->tty
&& !acm
->clocal
&& (acm
->ctrlin
& ~newctrl
& ACM_CTRL_DCD
)) { 201 dbg("calling hangup"); 202 tty_hangup(acm
->tty
); 206 acm
->ctrlin
= newctrl
; 208 dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c", 209 acm
->ctrlin
& ACM_CTRL_DCD
?'+':'-', acm
->ctrlin
& ACM_CTRL_DSR
?'+':'-', 210 acm
->ctrlin
& ACM_CTRL_BRK
?'+':'-', acm
->ctrlin
& ACM_CTRL_RI
?'+':'-', 211 acm
->ctrlin
& ACM_CTRL_FRAMING
?'+':'-', acm
->ctrlin
& ACM_CTRL_PARITY
?'+':'-', 212 acm
->ctrlin
& ACM_CTRL_OVERRUN
?'+':'-'); 217 dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d", 218 dr
->request
, dr
->index
, dr
->length
, data
[0], data
[1]); 223 static voidacm_read_bulk(struct urb
*urb
) 225 struct acm
*acm
= urb
->context
; 226 struct tty_struct
*tty
= acm
->tty
; 227 unsigned char*data
= urb
->transfer_buffer
; 230 if(!ACM_READY(acm
))return; 233 dbg("nonzero read bulk status received: %d", urb
->status
); 235 if(!urb
->status
& !acm
->throttle
) { 236 for(i
=0; i
< urb
->actual_length
&& !acm
->throttle
; i
++) 237 tty_insert_flip_char(tty
, data
[i
],0); 238 tty_flip_buffer_push(tty
); 242 memmove(data
, data
+ i
, urb
->actual_length
- i
); 243 urb
->actual_length
-= i
; 247 urb
->actual_length
=0; 250 if(usb_submit_urb(urb
)) 251 dbg("failed resubmitting read urb"); 254 static voidacm_write_bulk(struct urb
*urb
) 256 struct acm
*acm
= (struct acm
*)urb
->context
; 258 if(!ACM_READY(acm
))return; 261 dbg("nonzero write bulk status received: %d", urb
->status
); 263 queue_task(&acm
->tqueue
, &tq_immediate
); 264 mark_bh(IMMEDIATE_BH
); 267 static voidacm_softint(void*private) 269 struct acm
*acm
=private; 270 struct tty_struct
*tty
= acm
->tty
; 272 if(!ACM_READY(acm
))return; 274 if((tty
->flags
& (1<< TTY_DO_WRITE_WAKEUP
)) && tty
->ldisc
.write_wakeup
) 275 (tty
->ldisc
.write_wakeup
)(tty
); 277 wake_up_interruptible(&tty
->write_wait
); 284 static intacm_tty_open(struct tty_struct
*tty
,struct file
*filp
) 286 struct acm
*acm
= acm_table
[MINOR(tty
->device
)]; 288 if(!acm
|| !acm
->dev
)return-EINVAL
; 290 tty
->driver_data
= acm
; 295 if(acm
->used
++)return0; 297 acm
->ctrlurb
.dev
= acm
->dev
; 298 if(usb_submit_urb(&acm
->ctrlurb
)) 299 dbg("usb_submit_urb(ctrl irq) failed"); 301 acm
->readurb
.dev
= acm
->dev
; 302 if(usb_submit_urb(&acm
->readurb
)) 303 dbg("usb_submit_urb(read bulk) failed"); 305 acm_set_control(acm
, acm
->ctrlout
= ACM_CTRL_DTR
| ACM_CTRL_RTS
); 310 static voidacm_tty_close(struct tty_struct
*tty
,struct file
*filp
) 312 struct acm
*acm
= tty
->driver_data
; 314 if(!acm
|| !acm
->used
)return; 318 acm_set_control(acm
, acm
->ctrlout
=0); 319 usb_unlink_urb(&acm
->ctrlurb
); 320 usb_unlink_urb(&acm
->writeurb
); 321 usb_unlink_urb(&acm
->readurb
); 323 tty_unregister_devfs(&acm_tty_driver
, acm
->minor
); 324 acm_table
[acm
->minor
] = NULL
; 331 static intacm_tty_write(struct tty_struct
*tty
,int from_user
,const unsigned char*buf
,int count
) 333 struct acm
*acm
= tty
->driver_data
; 335 if(!ACM_READY(acm
))return-EINVAL
; 336 if(acm
->writeurb
.status
== -EINPROGRESS
)return0; 339 count
= (count
> acm
->writesize
) ? acm
->writesize
: count
; 342 copy_from_user(acm
->writeurb
.transfer_buffer
, buf
, count
); 344 memcpy(acm
->writeurb
.transfer_buffer
, buf
, count
); 346 acm
->writeurb
.transfer_buffer_length
= count
; 347 acm
->writeurb
.dev
= acm
->dev
; 349 if(usb_submit_urb(&acm
->writeurb
)) 350 dbg("usb_submit_urb(write bulk) failed"); 355 static intacm_tty_write_room(struct tty_struct
*tty
) 357 struct acm
*acm
= tty
->driver_data
; 358 if(!ACM_READY(acm
))return-EINVAL
; 359 return acm
->writeurb
.status
== -EINPROGRESS
?0: acm
->writesize
; 362 static intacm_tty_chars_in_buffer(struct tty_struct
*tty
) 364 struct acm
*acm
= tty
->driver_data
; 365 if(!ACM_READY(acm
))return-EINVAL
; 366 return acm
->writeurb
.status
== -EINPROGRESS
? acm
->writeurb
.transfer_buffer_length
:0; 369 static voidacm_tty_throttle(struct tty_struct
*tty
) 371 struct acm
*acm
= tty
->driver_data
; 372 if(!ACM_READY(acm
))return; 376 static voidacm_tty_unthrottle(struct tty_struct
*tty
) 378 struct acm
*acm
= tty
->driver_data
; 379 if(!ACM_READY(acm
))return; 381 if(acm
->readurb
.status
!= -EINPROGRESS
) 382 acm_read_bulk(&acm
->readurb
); 385 static voidacm_tty_break_ctl(struct tty_struct
*tty
,int state
) 387 struct acm
*acm
= tty
->driver_data
; 388 if(!ACM_READY(acm
))return; 389 if(acm_send_break(acm
, state
?0xffff:0)) 390 dbg("send break failed"); 393 static intacm_tty_ioctl(struct tty_struct
*tty
,struct file
*file
,unsigned int cmd
,unsigned long arg
) 395 struct acm
*acm
= tty
->driver_data
; 396 unsigned int retval
, mask
, newctrl
; 398 if(!ACM_READY(acm
))return-EINVAL
; 404 returnput_user((acm
->ctrlout
& ACM_CTRL_DTR
? TIOCM_DTR
:0) | 405 (acm
->ctrlout
& ACM_CTRL_RTS
? TIOCM_RTS
:0) | 406 (acm
->ctrlin
& ACM_CTRL_DSR
? TIOCM_DSR
:0) | 407 (acm
->ctrlin
& ACM_CTRL_RI
? TIOCM_RI
:0) | 408 (acm
->ctrlin
& ACM_CTRL_DCD
? TIOCM_CD
:0) | 409 TIOCM_CTS
, (unsigned long*) arg
); 415 if((retval
=get_user(mask
, (unsigned long*) arg
)))return retval
; 417 newctrl
= acm
->ctrlout
; 418 mask
= (mask
& TIOCM_DTR
? ACM_CTRL_DTR
:0) | (mask
& TIOCM_RTS
? ACM_CTRL_RTS
:0); 421 case TIOCMSET
: newctrl
= mask
;break; 422 case TIOCMBIS
: newctrl
|= mask
;break; 423 case TIOCMBIC
: newctrl
&= ~mask
;break; 426 if(acm
->ctrlout
== newctrl
)return0; 427 returnacm_set_control(acm
, acm
->ctrlout
= newctrl
); 433 static __u32 acm_tty_speed
[] = { 434 0,50,75,110,134,150,200,300,600, 435 1200,1800,2400,4800,9600,19200,38400, 436 57600,115200,230400,460800,500000,576000, 437 921600,1000000,1152000,1500000,2000000, 438 2500000,3000000,3500000,4000000 441 static __u8 acm_tty_size
[] = { 445 static voidacm_tty_set_termios(struct tty_struct
*tty
,struct termios
*termios_old
) 447 struct acm
*acm
= tty
->driver_data
; 448 struct termios
*termios
= tty
->termios
; 449 struct acm_line newline
; 450 int newctrl
= acm
->ctrlout
; 452 if(!ACM_READY(acm
))return; 454 newline
.speed
=cpu_to_le32p(acm_tty_speed
+ 455 (termios
->c_cflag
& CBAUD
& ~CBAUDEX
) + (termios
->c_cflag
& CBAUDEX
?15:0)); 456 newline
.stopbits
= termios
->c_cflag
& CSTOPB
?2:0; 457 newline
.parity
= termios
->c_cflag
& PARENB
? 458 (termios
->c_cflag
& PARODD
?1:2) + (termios
->c_cflag
& CMSPAR
?2:0) :0; 459 newline
.databits
= acm_tty_size
[(termios
->c_cflag
& CSIZE
) >>4]; 461 acm
->clocal
= termios
->c_cflag
& CLOCAL
; 464 newline
.speed
= acm
->line
.speed
; 465 newctrl
&= ~ACM_CTRL_DTR
; 466 }else newctrl
|= ACM_CTRL_DTR
; 468 if(newctrl
!= acm
->ctrlout
) 469 acm_set_control(acm
, acm
->ctrlout
= newctrl
); 471 if(memcmp(&acm
->line
, &newline
,sizeof(struct acm_line
))) { 472 memcpy(&acm
->line
, &newline
,sizeof(struct acm_line
)); 473 dbg("set line: %d %d %d %d", newline
.speed
, newline
.stopbits
, newline
.parity
, newline
.databits
); 474 acm_set_line(acm
, &acm
->line
); 479 * USB probe and disconnect routines. 482 static void*acm_probe(struct usb_device
*dev
,unsigned int ifnum
, 483 const struct usb_device_id
*id
) 486 struct usb_config_descriptor
*cfacm
; 487 struct usb_interface_descriptor
*ifcom
, *ifdata
; 488 struct usb_endpoint_descriptor
*epctrl
, *epread
, *epwrite
; 489 int readsize
, ctrlsize
, minor
, i
; 493 * Since 0 is treated as a wildcard by the USB pattern matching, 494 * we explicitly check bDeviceSubClass and bDeviceProtocol here. 497 if(dev
->descriptor
.bDeviceSubClass
!=0|| 498 dev
->descriptor
.bDeviceProtocol
!=0) 501 for(i
=0; i
< dev
->descriptor
.bNumConfigurations
; i
++) { 503 cfacm
= dev
->config
+ i
; 505 dbg("probing config %d", cfacm
->bConfigurationValue
); 507 if(cfacm
->bNumInterfaces
!=2|| 508 usb_interface_claimed(cfacm
->interface
+0) || 509 usb_interface_claimed(cfacm
->interface
+1)) 512 ifcom
= cfacm
->interface
[0].altsetting
+0; 513 ifdata
= cfacm
->interface
[1].altsetting
+0; 515 if(ifdata
->bInterfaceClass
!=10|| ifdata
->bNumEndpoints
<2) { 516 ifcom
= cfacm
->interface
[1].altsetting
+0; 517 ifdata
= cfacm
->interface
[0].altsetting
+0; 518 if(ifdata
->bInterfaceClass
!=10|| ifdata
->bNumEndpoints
<2) 522 if(ifcom
->bInterfaceClass
!=2|| ifcom
->bInterfaceSubClass
!=2|| 523 ifcom
->bInterfaceProtocol
!=1|| ifcom
->bNumEndpoints
<1) 526 epctrl
= ifcom
->endpoint
+0; 527 epread
= ifdata
->endpoint
+0; 528 epwrite
= ifdata
->endpoint
+1; 530 if((epctrl
->bEndpointAddress
&0x80) !=0x80|| (epctrl
->bmAttributes
&3) !=3|| 531 (epread
->bmAttributes
&3) !=2|| (epwrite
->bmAttributes
&3) !=2|| 532 ((epread
->bEndpointAddress
&0x80) ^ (epwrite
->bEndpointAddress
&0x80)) !=0x80) 535 if((epread
->bEndpointAddress
&0x80) !=0x80) { 536 epread
= ifdata
->endpoint
+1; 537 epwrite
= ifdata
->endpoint
+0; 540 usb_set_configuration(dev
, cfacm
->bConfigurationValue
); 542 for(minor
=0; minor
< ACM_TTY_MINORS
&& acm_table
[minor
]; minor
++); 543 if(acm_table
[minor
]) { 544 err("no more free acm devices"); 548 if(!(acm
=kmalloc(sizeof(struct acm
), GFP_KERNEL
))) { 549 err("out of memory"); 552 memset(acm
,0,sizeof(struct acm
)); 554 ctrlsize
= epctrl
->wMaxPacketSize
; 555 readsize
= epread
->wMaxPacketSize
; 556 acm
->writesize
= epwrite
->wMaxPacketSize
; 557 acm
->iface
= cfacm
->interface
; 561 acm
->tqueue
.routine
= acm_softint
; 562 acm
->tqueue
.data
= acm
; 564 if(!(buf
=kmalloc(ctrlsize
+ readsize
+ acm
->writesize
, GFP_KERNEL
))) { 565 err("out of memory"); 570 FILL_INT_URB(&acm
->ctrlurb
, dev
,usb_rcvintpipe(dev
, epctrl
->bEndpointAddress
), 571 buf
, ctrlsize
, acm_ctrl_irq
, acm
, epctrl
->bInterval
); 573 FILL_BULK_URB(&acm
->readurb
, dev
,usb_rcvbulkpipe(dev
, epread
->bEndpointAddress
), 574 buf
+= ctrlsize
, readsize
, acm_read_bulk
, acm
); 575 acm
->readurb
.transfer_flags
|= USB_NO_FSBR
; 577 FILL_BULK_URB(&acm
->writeurb
, dev
,usb_sndbulkpipe(dev
, epwrite
->bEndpointAddress
), 578 buf
+= readsize
, acm
->writesize
, acm_write_bulk
, acm
); 579 acm
->writeurb
.transfer_flags
|= USB_NO_FSBR
; 581 printk(KERN_INFO
"ttyACM%d: USB ACM device\n", minor
); 583 acm_set_control(acm
, acm
->ctrlout
); 585 acm
->line
.speed
=cpu_to_le32(9600); 586 acm
->line
.databits
=8; 587 acm_set_line(acm
, &acm
->line
); 589 usb_driver_claim_interface(&acm_driver
, acm
->iface
+0, acm
); 590 usb_driver_claim_interface(&acm_driver
, acm
->iface
+1, acm
); 592 tty_register_devfs(&acm_tty_driver
,0, minor
); 593 return acm_table
[minor
] = acm
; 599 static voidacm_disconnect(struct usb_device
*dev
,void*ptr
) 601 struct acm
*acm
= ptr
; 603 if(!acm
|| !acm
->dev
) { 604 dbg("disconnect on nonexisting interface"); 610 usb_unlink_urb(&acm
->ctrlurb
); 611 usb_unlink_urb(&acm
->readurb
); 612 usb_unlink_urb(&acm
->writeurb
); 614 kfree(acm
->ctrlurb
.transfer_buffer
); 616 usb_driver_release_interface(&acm_driver
, acm
->iface
+0); 617 usb_driver_release_interface(&acm_driver
, acm
->iface
+1); 620 tty_unregister_devfs(&acm_tty_driver
, acm
->minor
); 621 acm_table
[acm
->minor
] = NULL
; 627 tty_hangup(acm
->tty
); 631 * USB driver structure. 634 static struct usb_device_id acm_ids
[] = { 635 { bDeviceClass
:2, bDeviceSubClass
:0, bDeviceProtocol
:0}, 639 MODULE_DEVICE_TABLE(usb
, acm_ids
); 641 static struct usb_driver acm_driver
= { 644 disconnect
: acm_disconnect
, 649 * TTY driver structures. 652 static int acm_tty_refcount
; 654 static struct tty_struct
*acm_tty_table
[ACM_TTY_MINORS
]; 655 static struct termios
*acm_tty_termios
[ACM_TTY_MINORS
]; 656 static struct termios
*acm_tty_termios_locked
[ACM_TTY_MINORS
]; 658 static struct tty_driver acm_tty_driver
= { 659 magic
: TTY_DRIVER_MAGIC
, 662 major
: ACM_TTY_MAJOR
, 665 type
: TTY_DRIVER_TYPE_SERIAL
, 666 subtype
: SERIAL_TYPE_NORMAL
, 667 flags
: TTY_DRIVER_REAL_RAW
| TTY_DRIVER_NO_DEVFS
, 669 refcount
: &acm_tty_refcount
, 671 table
: acm_tty_table
, 672 termios
: acm_tty_termios
, 673 termios_locked
: acm_tty_termios_locked
, 676 close
: acm_tty_close
, 677 write
: acm_tty_write
, 678 write_room
: acm_tty_write_room
, 679 ioctl
: acm_tty_ioctl
, 680 throttle
: acm_tty_throttle
, 681 unthrottle
: acm_tty_unthrottle
, 682 chars_in_buffer
: acm_tty_chars_in_buffer
, 683 break_ctl
: acm_tty_break_ctl
, 684 set_termios
: acm_tty_set_termios
691 static int __init
acm_init(void) 693 acm_tty_driver
.init_termios
= tty_std_termios
; 694 acm_tty_driver
.init_termios
.c_cflag
= B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
; 696 if(tty_register_driver(&acm_tty_driver
)) 699 if(usb_register(&acm_driver
) <0) { 700 tty_unregister_driver(&acm_tty_driver
); 707 static void __exit
acm_exit(void) 709 usb_deregister(&acm_driver
); 710 tty_unregister_driver(&acm_tty_driver
); 713 module_init(acm_init
); 714 module_exit(acm_exit
); 716 MODULE_AUTHOR("Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"); 717 MODULE_DESCRIPTION("USB Abstract Control Model driver for USB modems and ISDN adapters");