X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fclass%2Fcdc-acm.h;h=fd2aaccdcbac7a4d04cc65f74743ea92541299fe;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=9009114e311bebc1c50fc7e5946ac428dbf08862;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 9009114e3..fd2aaccdc 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -51,17 +51,61 @@ * Internal driver structures. */ +/* + * The only reason to have several buffers is to accomodate assumptions + * in line disciplines. They ask for empty space amount, receive our URB size, + * and proceed to issue several 1-character writes, assuming they will fit. + * The very first write takes a complete URB. Fortunately, this only happens + * when processing onlcr, so we only need 2 buffers. + */ +#define ACM_NWB 2 +#define ACM_NRU 16 +#define ACM_NRB 16 + +struct acm_wb { + unsigned char *buf; + dma_addr_t dmah; + int len; + int use; +}; + +struct acm_rb { + struct list_head list; + int size; + unsigned char *base; + dma_addr_t dma; +}; + +struct acm_ru { + struct list_head list; + struct acm_rb *buffer; + struct urb *urb; + struct acm *instance; +}; + struct acm { struct usb_device *dev; /* the corresponding usb device */ struct usb_interface *control; /* control interface */ struct usb_interface *data; /* data interface */ struct tty_struct *tty; /* the corresponding tty */ - struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ - u8 *ctrl_buffer, *read_buffer, *write_buffer; /* buffers of urbs */ - dma_addr_t ctrl_dma, read_dma, write_dma; /* dma handles of buffers */ + struct urb *ctrlurb, *writeurb; /* urbs */ + u8 *ctrl_buffer; /* buffers of urbs */ + dma_addr_t ctrl_dma; /* dma handles of buffers */ + struct acm_wb wb[ACM_NWB]; + struct acm_ru ru[ACM_NRU]; + struct acm_rb rb[ACM_NRB]; + int rx_endpoint; + spinlock_t read_lock; + struct list_head spare_read_urbs; + struct list_head spare_read_bufs; + struct list_head filled_read_bufs; + int write_current; /* current write buffer */ + int write_used; /* number of non-empty write buffers */ + int write_ready; /* write urb is not running */ + spinlock_t write_lock; struct usb_cdc_line_coding line; /* bits, stop, parity */ struct work_struct work; /* work queue entry for line discipline waking up */ - struct tasklet_struct bh; /* rx processing */ + struct tasklet_struct urb_task; /* rx processing */ spinlock_t throttle_lock; /* synchronize throtteling and read callback */ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ unsigned int ctrlout; /* output control lines (DTR, RTS) */ @@ -71,8 +115,6 @@ struct acm { unsigned int minor; /* acm minor number */ unsigned char throttle; /* throttled by tty layer */ unsigned char clocal; /* termios CLOCAL */ - unsigned char ready_for_write; /* write urb can be used */ - unsigned char resubmit_to_unthrottle; /* throtteling has disabled the read urb */ unsigned int ctrl_caps; /* control capabilities from the class specific header */ };