Import 2.3.18pre1
[davej-history.git] / drivers / usb / acm.c
blob48fea89d49286b086cb1208060a25fbec5276aa3
1 /*
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.
11 * (2/8/99)
13 * version 0.6: Modularized driver, added disconnect code, improved
14 * assignment of device to tty minor number.
15 * (21/7/99)
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.
20 * (13/7/99)
22 * version 0.4: Small fixes in the FIFO, cleanup. Updated Bulk transfer in
23 * uhci.c. Should have the correct interface now.
24 * (6/6/99)
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!
30 * (27/5/99)
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
40 * (5/19/99)
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>
61 #include "usb.h"
63 #define NR_PORTS 3
64 #define ACM_MAJOR 166
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];
80 struct acm_state {
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)
102 devrequest dr;
104 info("Set_control_Line_Status\n");
106 dr.requesttype = 0x22;
107 dr.request = 0x22;
108 dr.value = status;
109 dr.index = 0;
110 dr.length = 0;
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)
118 devrequest dr;
120 info("Set_Line_Coding\n");
122 dr.requesttype = 0x22;
123 dr.request = 0x30;
124 dr.value = coding;
125 dr.index = 0;
126 dr.length = 0;
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)
136 unsigned char *data;
137 struct acm_state *acm = (struct acm_state *) dev_id;
138 devrequest *dr;
140 info("ACM_USB_IRQ\n");
142 if (!acm->present) {
143 info("NO ACM DEVICE REGISTERED\n");
144 return 0;
146 if (!acm->active) {
147 info ("ACM DEVICE NOT OPEN\n");
148 return 1;
151 dr=__buffer;
152 data=__buffer;
153 data+=sizeof(dr);
155 #if 1
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);
161 #endif
163 switch(dr->request) {
164 //Network connection
165 case 0x00:
166 printk("Network connection: ");
167 if (dr->request==0) info("disconnected\n");
168 if (dr->request==1) info("connected\n");
169 break;
171 //Response available
172 case 0x01:
173 printk("Response available\n");
174 break;
176 //Set serial line state
177 case 0x20:
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);
183 break;
186 //info("Done\n");
187 //Continue transfer
188 return 1;
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;
196 int i;
198 info("ACM_READ_IRQ\n");
200 if (!acm->present) {
201 info("NO ACM DEVICE REGISTERED\n");
202 //Stop transfer
203 return 0;
206 if (!acm->active) {
207 info ("ACM DEVICE NOT OPEN\n");
208 //Stop transfer
209 return 0;
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);
218 //info("Done\n");
219 //Continue transfer
220 return 1;
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");
230 if (!acm->present) {
231 info("NO ACM DEVICE REGISTERED\n");
232 //Stop transfer
233 return 0;
235 if (!acm->active) {
236 info ("ACM DEVICE NOT OPEN\n");
237 //Stop transfer
238 return 0;
241 usb_terminate_bulk(acm->dev, acm->writetransfer);
242 acm->writing=0;
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);
247 //info("Done\n");
248 //Stop transfer
249 return 0;
252 /*TTY STUFF*/
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];
261 acm->tty=tty;
263 if (!acm->present) {
264 info("NO ACM DEVICE REGISTERED\n");
265 return -EINVAL;
268 if (acm->active) {
269 info ("ACM DEVICE ALREADY OPEN\n");
270 return -EINVAL;
272 acm->active=1;
274 /*Start reading from the device*/
275 acm->ctrltransfer=usb_request_irq(acm->dev,acm->ctrlpipe, acm_irq, acm->ctrlinterval, acm);
277 acm->reading=1;
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);
282 return 0;
285 static void rs_close(struct tty_struct *tty, struct file * filp)
287 struct acm_state *acm = (struct acm_state *) tty->driver_data;
288 info("rs_close\n");
290 if (!acm->present) {
291 info("NO ACM DEVICE REGISTERED\n");
292 return;
295 if (!acm->active) {
296 info ("ACM DEVICE NOT OPEN\n");
297 return;
300 Set_Control_Line_Status (0, acm);
302 if (acm->writing){
303 usb_terminate_bulk(acm->dev, acm->writetransfer);
304 acm->writing=0;
306 if (acm->reading){
307 usb_terminate_bulk(acm->dev, acm->readtransfer);
308 acm->reading=0;
310 // usb_release_irq(acm->dev,acm->ctrltransfer);
312 acm->active=0;
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;
319 int written;
321 info("rs_write\n");
323 if (!acm->present) {
324 info("NO ACM DEVICE REGISTERED\n");
325 return -EINVAL;
328 if (!acm->active) {
329 info ("ACM DEVICE NOT OPEN\n");
330 return -EINVAL;
333 if (acm->writing) {
334 info ("already writing\n");
335 return 0;
338 written=(count>acm->writesize) ? acm->writesize : count;
340 if (from_user) {
341 //info("fromuser\n");
342 copy_from_user(acm->writebuffer,buf,written);
344 else {
345 //info("notfromuser\n");
346 memcpy(acm->writebuffer,buf,written);
349 //start the transfer
350 acm->writing=1;
351 acm->writetransfer=usb_request_bulk(acm->dev,acm->writepipe, acm_write_irq, acm->writebuffer, written, acm);
353 return written;
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");
362 if (!acm->present) {
363 info("NO ACM DEVICE REGISTERED\n");
364 return;
367 if (!acm->active) {
368 info ("ACM DEVICE NOT OPEN\n");
369 return;
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");
380 if (!acm->present) {
381 info("NO ACM DEVICE REGISTERED\n");
382 return -EINVAL;
385 if (!acm->active) {
386 info ("ACM DEVICE NOT OPEN\n");
387 return -EINVAL;
390 if (acm->writing) {
391 return 0;
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");
402 if (!acm->present) {
403 info("NO ACM DEVICE REGISTERED\n");
404 return -EINVAL;
407 if (!acm->active) {
408 info ("ACM DEVICE NOT OPEN\n");
409 return -EINVAL;
412 if (acm->writing) {
413 return acm->writesize;
415 return 0;
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");
424 if (!acm->present) {
425 info("NO ACM DEVICE REGISTERED\n");
426 return;
429 if (!acm->active) {
430 info ("ACM DEVICE NOT OPEN\n");
431 return;
435 if (I_IXOFF(tty))
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");
449 if (!acm->present) {
450 info("NO ACM DEVICE REGISTERED\n");
451 return;
454 if (!acm->active) {
455 info ("ACM DEVICE NOT OPEN\n");
456 return;
460 if (I_IXOFF(tty))
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)
470 int i;
472 for (i=0;i<NR_PORTS;i++) {
473 if (!acm_state_table[i].present)
474 return i;
476 return -1;
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;
484 int cfgnum,acmno;
485 int swapped=0;
487 info("acm_probe\n");
489 if (0>(acmno=get_free_acm())) {
490 info("Too many acm devices connected\n");
491 return -1;
493 acm = &acm_state_table[acmno];
495 /* Only use CDC */
496 if (dev->descriptor.bDeviceClass != 2 ||
497 dev->descriptor.bDeviceSubClass != 0 ||
498 dev->descriptor.bDeviceProtocol != 0)
499 return -1;
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)
508 continue;
510 /*Which uses an interrupt input */
511 endpoint = &interface->endpoint[0];
512 if ((endpoint->bEndpointAddress & 0x80) != 0x80 ||
513 (endpoint->bmAttributes & 3) != 3)
514 continue;
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)
520 continue;
522 if ((endpoint->bEndpointAddress & 0x80) == 0x80)
523 swapped = 1;
525 /*With a bulk input */
526 endpoint = &interface->endpoint[0^swapped];
527 if ((endpoint->bEndpointAddress & 0x80) != 0x80 ||
528 (endpoint->bmAttributes & 3) != 2)
529 continue;
531 /*And a bulk output */
532 endpoint = &interface->endpoint[1^swapped];
533 if ((endpoint->bEndpointAddress & 0x80) == 0x80 ||
534 (endpoint->bmAttributes & 3) != 2)
535 continue;
537 printk("USB ACM %d found\n",acmno);
538 usb_set_configuration(dev, dev->config[cfgnum].bConfigurationValue);
540 acm->dev=dev;
541 dev->private=acm;
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);
546 acm->reading=0;
547 if (!acm->readbuffer) {
548 printk("ACM: Couldn't allocate readbuffer\n");
549 return -1;
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);
555 acm->writing=0;
556 if (!acm->writebuffer) {
557 printk("ACM: Couldn't allocate writebuffer\n");
558 kfree(acm->readbuffer);
559 return -1;
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;
566 acm->present=1;
567 MOD_INC_USE_COUNT;
568 return 0;
570 return -1;
573 static void acm_disconnect(struct usb_device *dev)
575 struct acm_state *acm = (struct acm_state *) dev->private;
577 info("acm_disconnect\n");
579 if (!acm->present) {
580 printk("device not present\n");
581 return;
584 printk("disconnecting\n");
586 if (acm->writing){
587 usb_terminate_bulk(acm->dev, acm->writetransfer);
588 acm->writing=0;
590 if (acm->reading){
591 usb_terminate_bulk(acm->dev, acm->readtransfer);
592 acm->reading=0;
594 // usb_release_irq(acm->dev,acm->ctrltransfer);
595 //BUG: What to do if a device is open?? Notify process or not allow cleanup?
596 acm->active=0;
597 acm->present=0;
598 kfree(acm->writebuffer);
599 kfree(acm->readbuffer);
601 MOD_DEC_USE_COUNT;
604 /*USB DRIVER STUFF*/
605 static struct usb_driver acm_driver = {
606 "acm",
607 acm_probe,
608 acm_disconnect,
609 { NULL, NULL }
612 int usb_acm_init(void)
614 int cnt;
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" );
663 return -EPERM;
666 //REGISTER USB DRIVER
667 usb_register(&acm_driver);
669 printk(KERN_INFO "USB ACM registered.\n");
670 return 0;
673 void usb_acm_cleanup(void)
675 int i;
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];
682 if (acm->present) {
683 printk("disconnecting %d\n",i);
684 acm_disconnect(acm->dev);
687 tty_unregister_driver(&acm_tty_driver);
689 usb_deregister(&acm_driver);
693 #ifdef MODULE
694 int init_module(void)
696 return usb_acm_init();
699 void cleanup_module(void)
701 usb_acm_cleanup();
703 #endif