2 * USB Abstract Control Model based on Brad Keryan's USB busmouse driver
4 * Armin Fuerst 5/8/1999
6 * version 0.7: Added usb flow control. Fixed bug in uhci.c (what idiot
7 * wrote this code? ...Oops that was me). Fixed module cleanup. Did some
8 * testing at 3Com => zmodem uload+download works, pppd had trouble but
9 * seems to work now. Changed Menuconfig texts "Communications Device
10 * Class (ACM)" might be a bit more intuitive. Ported to 2.3.13-1 prepatch.
13 * version 0.6: Modularized driver, added disconnect code, improved
14 * assignment of device to tty minor number.
17 * version 0.5: Driver now generates a tty instead of a simple character
18 * device. Moved async bulk transfer to 2.3.10 kernel version. fixed a bug
19 * in uhci_td_allocate. Commenetd out getstringtable which causes crash.
22 * version 0.4: Small fixes in the FIFO, cleanup. Updated Bulk transfer in
23 * uhci.c. Should have the correct interface now.
26 * version 0.3: Major changes. Changed Bulk transfer to interrupt based
27 * transfer. Using FIFO Buffers now. Consistent handling of open/close
28 * file state and detected/nondetected device. File operations behave
29 * according to this. Driver is able to send+receive now! Heureka!
32 * version 0.2: Improved Bulk transfer. TX led now flashes every time data is
33 * sent. Send Encapsulated Data is not needed, nor does it do anything.
34 * Why's that ?!? Thanks to Thomas Sailer for his close look at the bulk code.
35 * He told me about some importand bugs. (5/21/99)
37 * version 0.1: Bulk transfer for uhci seems to work now, no dangling tds any
38 * more. TX led of the ISDN TA flashed the first time. Does this mean it works?
39 * The interrupt of the ctrl endpoint crashes the kernel => no read possible
42 * version 0.0: Driver sets up configuration, sets up data pipes, opens misc
43 * device. No actual data transfer is done, since we don't have bulk transfer,
44 * yet. Purely skeleton for now. (5/8/99)
47 #include <linux/kernel.h>
48 #include <linux/sched.h>
49 #include <linux/signal.h>
50 #include <linux/errno.h>
51 #include <linux/poll.h>
52 #include <linux/init.h>
53 #include <linux/malloc.h>
54 #include <linux/fcntl.h>
55 #include <linux/tty_driver.h>
56 #include <linux/tty_flip.h>
57 #include <linux/tty.h>
58 #include <linux/module.h>
59 #include <linux/spinlock.h>
66 #define info(message); printk(message);
67 //#define info(message);
69 #define CTRL_STAT_DTR 1
70 #define CTRL_STAT_RTS 2
72 static int acm_refcount
;
74 static struct tty_driver acm_tty_driver
;
75 static struct tty_struct
*acm_tty
[NR_PORTS
];
76 static struct termios
*acm_termios
[NR_PORTS
];
77 static struct termios
*acm_termios_locked
[NR_PORTS
];
78 static struct acm_state acm_state_table
[NR_PORTS
];
81 struct usb_device
*dev
; //the coresponding usb device
82 struct tty_struct
*tty
; //the coresponding tty
83 char present
; //a device for this struct was detected => this tty is used
84 char active
; //someone has this acm's device open
85 unsigned int ctrlstate
; //Status of the serial control lines (handshake,...)
86 unsigned int linecoding
; //Status of the line coding (Bits, Stop, Parity)
87 int writesize
, readsize
; //size of the usb buffers
88 char *writebuffer
, *readbuffer
; //the usb buffers
89 void *readtransfer
, *writetransfer
;
90 void *ctrltransfer
; //ptr to HC internal transfer struct
91 char writing
, reading
; //flag if transfer is running
92 unsigned int readendp
,writeendp
,ctrlendp
; //endpoints and
93 unsigned int readpipe
,writepipe
,ctrlpipe
; //pipes (are one of these obsolete?)
94 unsigned ctrlinterval
; //interval to poll from device
98 //functions for various ACM requests
100 void Set_Control_Line_Status (unsigned int status
,struct acm_state
*acm
)
104 info("Set_control_Line_Status\n");
106 dr
.requesttype
= 0x22;
111 acm
->dev
->bus
->op
->control_msg(acm
->dev
, usb_sndctrlpipe(acm
->dev
,0), &dr
, NULL
, 0);
113 acm
->ctrlstate
=status
;
116 void Set_Line_Coding (unsigned int coding
,struct acm_state
*acm
)
120 info("Set_Line_Coding\n");
122 dr
.requesttype
= 0x22;
127 acm
->dev
->bus
->op
->control_msg(acm
->dev
, usb_sndctrlpipe(acm
->dev
,0), &dr
, NULL
, 0);
129 acm
->linecoding
=coding
;
132 //Interrupt handler for various usb events
133 static int acm_irq(int state
, void *__buffer
, int count
, void *dev_id
)
137 struct acm_state
*acm
= (struct acm_state
*) dev_id
;
140 info("ACM_USB_IRQ\n");
143 info("NO ACM DEVICE REGISTERED\n");
147 info ("ACM DEVICE NOT OPEN\n");
156 printk("reqtype: %02X\n",dr
->requesttype
);
157 printk("request: %02X\n",dr
->request
);
158 printk("wValue: %02X\n",dr
->value
);
159 printk("wIndex: %02X\n",dr
->index
);
160 printk("wLength: %02X\n",dr
->length
);
163 switch(dr
->request
) {
166 printk("Network connection: ");
167 if (dr
->request
==0) info("disconnected\n");
168 if (dr
->request
==1) info("connected\n");
173 printk("Response available\n");
176 //Set serial line state
178 printk("Set serial control line state\n");
179 if ((dr
->index
==1)&&(dr
->length
==2)) {
180 acm
->ctrlstate
=* ((unsigned short int *)data
);
181 printk("Serstate: %02X\n",acm
->ctrlstate
);
191 static int acm_read_irq(int state
, void *__buffer
, int count
, void *dev_id
)
193 struct acm_state
*acm
= (struct acm_state
*) dev_id
;
194 struct tty_struct
*tty
= acm
->tty
;
195 unsigned char* data
=__buffer
;
198 info("ACM_READ_IRQ\n");
201 info("NO ACM DEVICE REGISTERED\n");
207 info ("ACM DEVICE NOT OPEN\n");
212 // printk("%d %s\n",count,data);
213 for (i
=0;i
<count
;i
++) {
214 tty_insert_flip_char(tty
,data
[i
],0);
216 tty_flip_buffer_push(tty
);
223 static int acm_write_irq(int state
, void *__buffer
, int count
, void *dev_id
)
225 struct acm_state
*acm
= (struct acm_state
*) dev_id
;
226 struct tty_struct
*tty
= acm
->tty
;
228 info("ACM_WRITE_IRQ\n");
231 info("NO ACM DEVICE REGISTERED\n");
236 info ("ACM DEVICE NOT OPEN\n");
241 usb_terminate_bulk(acm
->dev
, acm
->writetransfer
);
243 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) && tty
->ldisc
.write_wakeup
)
244 (tty
->ldisc
.write_wakeup
)(tty
);
245 wake_up_interruptible(&tty
->write_wait
);
253 static int rs_open(struct tty_struct
*tty
, struct file
* filp
)
255 struct acm_state
*acm
;
258 info("USB_FILE_OPEN\n");
260 tty
->driver_data
=acm
=&acm_state_table
[MINOR(tty
->device
)-tty
->driver
.minor_start
];
264 info("NO ACM DEVICE REGISTERED\n");
269 info ("ACM DEVICE ALREADY OPEN\n");
274 /*Start reading from the device*/
275 acm
->ctrltransfer
=usb_request_irq(acm
->dev
,acm
->ctrlpipe
, acm_irq
, acm
->ctrlinterval
, acm
);
278 acm
->readtransfer
=usb_request_bulk(acm
->dev
,acm
->readpipe
, acm_read_irq
, acm
->readbuffer
, acm
->readsize
, acm
);
280 Set_Control_Line_Status (CTRL_STAT_DTR
| CTRL_STAT_RTS
, acm
);
285 static void rs_close(struct tty_struct
*tty
, struct file
* filp
)
287 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
291 info("NO ACM DEVICE REGISTERED\n");
296 info ("ACM DEVICE NOT OPEN\n");
300 Set_Control_Line_Status (0, acm
);
303 usb_terminate_bulk(acm
->dev
, acm
->writetransfer
);
307 usb_terminate_bulk(acm
->dev
, acm
->readtransfer
);
310 // usb_release_irq(acm->dev,acm->ctrltransfer);
315 static int rs_write(struct tty_struct
* tty
, int from_user
,
316 const unsigned char *buf
, int count
)
318 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
324 info("NO ACM DEVICE REGISTERED\n");
329 info ("ACM DEVICE NOT OPEN\n");
334 info ("already writing\n");
338 written
=(count
>acm
->writesize
) ? acm
->writesize
: count
;
341 //info("fromuser\n");
342 copy_from_user(acm
->writebuffer
,buf
,written
);
345 //info("notfromuser\n");
346 memcpy(acm
->writebuffer
,buf
,written
);
351 acm
->writetransfer
=usb_request_bulk(acm
->dev
,acm
->writepipe
, acm_write_irq
, acm
->writebuffer
, written
, acm
);
356 static void rs_put_char(struct tty_struct
*tty
, unsigned char ch
)
358 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
360 info("rs_put_char\n");
363 info("NO ACM DEVICE REGISTERED\n");
368 info ("ACM DEVICE NOT OPEN\n");
371 // printk("%c\n",ch);
374 static int rs_write_room(struct tty_struct
*tty
)
376 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
378 info("rs_write_room\n");
381 info("NO ACM DEVICE REGISTERED\n");
386 info ("ACM DEVICE NOT OPEN\n");
393 return acm
->writesize
;
396 static int rs_chars_in_buffer(struct tty_struct
*tty
)
398 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
400 info("rs_chars_in_buffer\n");
403 info("NO ACM DEVICE REGISTERED\n");
408 info ("ACM DEVICE NOT OPEN\n");
413 return acm
->writesize
;
418 static void rs_throttle(struct tty_struct
* tty
)
420 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
422 info("rs_throttle\n");
425 info("NO ACM DEVICE REGISTERED\n");
430 info ("ACM DEVICE NOT OPEN\n");
436 rs_send_xchar(tty, STOP_CHAR(tty));
439 if (tty
->termios
->c_cflag
& CRTSCTS
)
440 Set_Control_Line_Status (acm
->ctrlstate
& ~CTRL_STAT_RTS
, acm
);
443 static void rs_unthrottle(struct tty_struct
* tty
)
445 struct acm_state
*acm
= (struct acm_state
*) tty
->driver_data
;
447 info("rs_unthrottle\n");
450 info("NO ACM DEVICE REGISTERED\n");
455 info ("ACM DEVICE NOT OPEN\n");
461 rs_send_xchar(tty, STOP_CHAR(tty));
464 if (tty
->termios
->c_cflag
& CRTSCTS
)
465 Set_Control_Line_Status (acm
->ctrlstate
| CTRL_STAT_RTS
, acm
);
468 static int get_free_acm(void)
472 for (i
=0;i
<NR_PORTS
;i
++) {
473 if (!acm_state_table
[i
].present
)
479 static int acm_probe(struct usb_device
*dev
)
481 struct acm_state
*acm
;
482 struct usb_interface_descriptor
*interface
;
483 struct usb_endpoint_descriptor
*endpoint
;
489 if (0>(acmno
=get_free_acm())) {
490 info("Too many acm devices connected\n");
493 acm
= &acm_state_table
[acmno
];
496 if (dev
->descriptor
.bDeviceClass
!= 2 ||
497 dev
->descriptor
.bDeviceSubClass
!= 0 ||
498 dev
->descriptor
.bDeviceProtocol
!= 0)
501 #define IFCLASS(if) ((if->bInterfaceClass << 24) | (if->bInterfaceSubClass << 16) | (if->bInterfaceProtocol << 8) | (if->bNumEndpoints))
503 /* Now scan all configs for a ACM configuration*/
504 for (cfgnum
=0;cfgnum
<dev
->descriptor
.bNumConfigurations
;cfgnum
++) {
505 /* The first one should be Communications interface? */
506 interface
= &dev
->config
[cfgnum
].interface
[0].altsetting
[0];
507 if (IFCLASS(interface
) != 0x02020101)
510 /*Which uses an interrupt input */
511 endpoint
= &interface
->endpoint
[0];
512 if ((endpoint
->bEndpointAddress
& 0x80) != 0x80 ||
513 (endpoint
->bmAttributes
& 3) != 3)
516 /* The second one should be a Data interface? */
517 interface
= &dev
->config
[cfgnum
].interface
[1].altsetting
[0];
518 if (interface
->bInterfaceClass
!= 10 ||
519 interface
->bNumEndpoints
!= 2)
522 if ((endpoint
->bEndpointAddress
& 0x80) == 0x80)
525 /*With a bulk input */
526 endpoint
= &interface
->endpoint
[0^swapped
];
527 if ((endpoint
->bEndpointAddress
& 0x80) != 0x80 ||
528 (endpoint
->bmAttributes
& 3) != 2)
531 /*And a bulk output */
532 endpoint
= &interface
->endpoint
[1^swapped
];
533 if ((endpoint
->bEndpointAddress
& 0x80) == 0x80 ||
534 (endpoint
->bmAttributes
& 3) != 2)
537 printk("USB ACM %d found\n",acmno
);
538 usb_set_configuration(dev
, dev
->config
[cfgnum
].bConfigurationValue
);
543 acm
->readendp
=dev
->config
[cfgnum
].interface
[1].altsetting
[0].endpoint
[0^swapped
].bEndpointAddress
;
544 acm
->readpipe
=usb_rcvbulkpipe(dev
,acm
->readendp
);
545 acm
->readbuffer
=kmalloc(acm
->readsize
=dev
->config
[cfgnum
].interface
[1].altsetting
[0].endpoint
[0^swapped
].wMaxPacketSize
,GFP_KERNEL
);
547 if (!acm
->readbuffer
) {
548 printk("ACM: Couldn't allocate readbuffer\n");
552 acm
->writeendp
=dev
->config
[cfgnum
].interface
[1].altsetting
[0].endpoint
[1^swapped
].bEndpointAddress
;
553 acm
->writepipe
=usb_sndbulkpipe(dev
,acm
->writeendp
);
554 acm
->writebuffer
=kmalloc(acm
->writesize
=dev
->config
[cfgnum
].interface
[1].altsetting
[0].endpoint
[1^swapped
].wMaxPacketSize
, GFP_KERNEL
);
556 if (!acm
->writebuffer
) {
557 printk("ACM: Couldn't allocate writebuffer\n");
558 kfree(acm
->readbuffer
);
562 acm
->ctrlendp
=dev
->config
[cfgnum
].interface
[0].altsetting
[0].endpoint
[0].bEndpointAddress
;
563 acm
->ctrlpipe
=usb_rcvctrlpipe(acm
->dev
,acm
->ctrlendp
);
564 acm
->ctrlinterval
=dev
->config
[cfgnum
].interface
[0].altsetting
[0].endpoint
[0].bInterval
;
573 static void acm_disconnect(struct usb_device
*dev
)
575 struct acm_state
*acm
= (struct acm_state
*) dev
->private;
577 info("acm_disconnect\n");
580 printk("device not present\n");
584 printk("disconnecting\n");
587 usb_terminate_bulk(acm
->dev
, acm
->writetransfer
);
591 usb_terminate_bulk(acm
->dev
, acm
->readtransfer
);
594 // usb_release_irq(acm->dev,acm->ctrltransfer);
595 //BUG: What to do if a device is open?? Notify process or not allow cleanup?
598 kfree(acm
->writebuffer
);
599 kfree(acm
->readbuffer
);
605 static struct usb_driver acm_driver
= {
612 int usb_acm_init(void)
616 info("usb_acm_init\n");
618 //INITIALIZE GLOBAL DATA STRUCTURES
619 for (cnt
=0;cnt
<NR_PORTS
;cnt
++) {
620 memset(&acm_state_table
[cnt
], 0, sizeof(struct acm_state
));
623 //REGISTER TTY DRIVER
624 memset(&acm_tty_driver
, 0, sizeof(struct tty_driver
));
625 acm_tty_driver
.magic
= TTY_DRIVER_MAGIC
;
626 acm_tty_driver
.driver_name
= "usb";
627 acm_tty_driver
.name
= "ttyACM";
628 acm_tty_driver
.major
= ACM_MAJOR
;
629 acm_tty_driver
.minor_start
= 0;
630 acm_tty_driver
.num
= NR_PORTS
;
631 acm_tty_driver
.type
= TTY_DRIVER_TYPE_SERIAL
;
632 acm_tty_driver
.subtype
= SERIAL_TYPE_NORMAL
;
633 acm_tty_driver
.init_termios
= tty_std_termios
;
634 acm_tty_driver
.init_termios
.c_cflag
= B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
635 acm_tty_driver
.flags
= TTY_DRIVER_REAL_RAW
;
636 acm_tty_driver
.refcount
= &acm_refcount
;
637 acm_tty_driver
.table
= acm_tty
;
638 acm_tty_driver
.termios
= acm_termios
;
639 acm_tty_driver
.termios_locked
= acm_termios_locked
;
641 acm_tty_driver
.open
= rs_open
;
642 acm_tty_driver
.close
= rs_close
;
643 acm_tty_driver
.write
= rs_write
;
644 acm_tty_driver
.put_char
= rs_put_char
; //FUCKIN BUG IN DOKU!!!
645 acm_tty_driver
.flush_chars
= NULL
; //rs_flush_chars;
646 acm_tty_driver
.write_room
= rs_write_room
; //ANBOTHER FUCKIN BUG!!
647 acm_tty_driver
.ioctl
= NULL
; //rs_ioctl;
648 acm_tty_driver
.set_termios
= NULL
; //rs_set_termios;
649 acm_tty_driver
.set_ldisc
= NULL
;
650 acm_tty_driver
.throttle
= rs_throttle
;
651 acm_tty_driver
.unthrottle
= rs_unthrottle
;
652 acm_tty_driver
.stop
= NULL
; //rs_stop;
653 acm_tty_driver
.start
= NULL
; //rs_start;
654 acm_tty_driver
.hangup
= NULL
; //rs_hangup;
655 acm_tty_driver
.break_ctl
= NULL
; //rs_break;
656 acm_tty_driver
.wait_until_sent
= NULL
; //rs_wait_until_sent;
657 acm_tty_driver
.send_xchar
= NULL
; //rs_send_xchar;
658 acm_tty_driver
.read_proc
= NULL
; //rs_read_proc;
659 acm_tty_driver
.chars_in_buffer
= rs_chars_in_buffer
;
660 acm_tty_driver
.flush_buffer
= NULL
; //rs_flush_buffer;
661 if (tty_register_driver(&acm_tty_driver
)) {
662 printk( "acm: failed to register tty driver\n" );
666 //REGISTER USB DRIVER
667 usb_register(&acm_driver
);
669 printk(KERN_INFO
"USB ACM registered.\n");
673 void usb_acm_cleanup(void)
676 struct acm_state
*acm
;
678 info("usb_acm_cleanup\n");
680 for (i
=0;i
<NR_PORTS
;i
++) {
681 acm
=&acm_state_table
[i
];
683 printk("disconnecting %d\n",i
);
684 acm_disconnect(acm
->dev
);
687 tty_unregister_driver(&acm_tty_driver
);
689 usb_deregister(&acm_driver
);
694 int init_module(void)
696 return usb_acm_init();
699 void cleanup_module(void)