diff options
Diffstat (limited to 'drivers/usb/wusbcore/wa-hc.h')
| -rw-r--r-- | drivers/usb/wusbcore/wa-hc.h | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h index e614f02f0cf..f2a8d29e17b 100644 --- a/drivers/usb/wusbcore/wa-hc.h +++ b/drivers/usb/wusbcore/wa-hc.h @@ -36,7 +36,7 @@ * * hcd glue with the USB API Host Controller Interface API. * - * nep Notification EndPoint managent: collect notifications + * nep Notification EndPoint management: collect notifications * and queue them with the workqueue daemon. * * Handle notifications as coming from the NEP. Sends them @@ -125,7 +125,8 @@ struct wa_rpipe { enum wa_dti_state { WA_DTI_TRANSFER_RESULT_PENDING, - WA_DTI_ISOC_PACKET_STATUS_PENDING + WA_DTI_ISOC_PACKET_STATUS_PENDING, + WA_DTI_BUF_IN_DATA_PENDING }; enum wa_quirks { @@ -134,8 +135,20 @@ enum wa_quirks { * requests to be concatenated and not sent as separate packets. */ WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC = 0x01, + /* + * The Alereon HWA can be instructed to not send transfer notifications + * as an optimization. + */ + WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS = 0x02, }; +enum wa_vendor_specific_requests { + WA_REQ_ALEREON_DISABLE_XFER_NOTIFICATIONS = 0x4C, + WA_REQ_ALEREON_FEATURE_SET = 0x01, + WA_REQ_ALEREON_FEATURE_CLEAR = 0x00, +}; + +#define WA_MAX_BUF_IN_URBS 4 /** * Instance of a HWA Host Controller * @@ -144,7 +157,7 @@ enum wa_quirks { * * @wa_descr Can be accessed without locking because it is in * the same area where the device descriptors were - * read, so it is guaranteed to exist umodified while + * read, so it is guaranteed to exist unmodified while * the device exists. * * Endianess has been converted to CPU's. @@ -167,8 +180,8 @@ enum wa_quirks { * submitted from an atomic context). * * FIXME: this needs to be layered up: a wusbhc layer (for sharing - * comonalities with WHCI), a wa layer (for sharing - * comonalities with DWA-RC). + * commonalities with WHCI), a wa layer (for sharing + * commonalities with DWA-RC). */ struct wahc { struct usb_device *usb_dev; @@ -197,21 +210,23 @@ struct wahc { struct mutex rpipe_mutex; /* assigning resources to endpoints */ /* - * dti_state is used to track the state of the dti_urb. When dti_state + * dti_state is used to track the state of the dti_urb. When dti_state * is WA_DTI_ISOC_PACKET_STATUS_PENDING, dti_isoc_xfer_in_progress and - * dti_isoc_xfer_seg identify which xfer the incoming isoc packet status - * refers to. + * dti_isoc_xfer_seg identify which xfer the incoming isoc packet + * status refers to. */ enum wa_dti_state dti_state; u32 dti_isoc_xfer_in_progress; u8 dti_isoc_xfer_seg; struct urb *dti_urb; /* URB for reading xfer results */ - struct urb *buf_in_urb; /* URB for reading data in */ + /* URBs for reading data in */ + struct urb buf_in_urbs[WA_MAX_BUF_IN_URBS]; + int active_buf_in_urbs; /* number of buf_in_urbs active. */ struct edc dti_edc; /* DTI error density counter */ void *dti_buf; size_t dti_buf_size; - unsigned long dto_in_use; /* protect dto endoint serialization. */ + unsigned long dto_in_use; /* protect dto endoint serialization */ s32 status; /* For reading status */ @@ -234,6 +249,7 @@ struct wahc { extern int wa_create(struct wahc *wa, struct usb_interface *iface, kernel_ulong_t); extern void __wa_destroy(struct wahc *wa); +extern int wa_dti_start(struct wahc *wa); void wa_reset_all(struct wahc *wa); @@ -275,6 +291,8 @@ static inline void wa_rpipe_init(struct wahc *wa) static inline void wa_init(struct wahc *wa) { + int index; + edc_init(&wa->nep_edc); atomic_set(&wa->notifs_queued, 0); wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; @@ -288,6 +306,10 @@ static inline void wa_init(struct wahc *wa) INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run); wa->dto_in_use = 0; atomic_set(&wa->xfer_id_count, 1); + /* init the buf in URBs */ + for (index = 0; index < WA_MAX_BUF_IN_URBS; ++index) + usb_init_urb(&(wa->buf_in_urbs[index])); + wa->active_buf_in_urbs = 0; } /** @@ -332,7 +354,7 @@ static inline int rpipe_avail_inc(struct wa_rpipe *rpipe) /* Transferring data */ extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *, struct urb *, gfp_t); -extern int wa_urb_dequeue(struct wahc *, struct urb *); +extern int wa_urb_dequeue(struct wahc *, struct urb *, int); extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *); @@ -345,7 +367,7 @@ extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *); * it...no RC specific function is called...unless I miss * something. * - * FIXME: has to go away in favour of an 'struct' hcd based sollution + * FIXME: has to go away in favour of a 'struct' hcd based solution */ static inline struct wahc *wa_get(struct wahc *wa) { @@ -366,7 +388,7 @@ static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature) USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, feature, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, - NULL, 0, 1000 /* FIXME: arbitrary */); + NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -400,8 +422,7 @@ s32 __wa_get_status(struct wahc *wa) USB_REQ_GET_STATUS, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, - &wa->status, sizeof(wa->status), - 1000 /* FIXME: arbitrary */); + &wa->status, sizeof(wa->status), USB_CTRL_GET_TIMEOUT); if (result >= 0) result = wa->status; return result; |
