diff options
| -rw-r--r-- | drivers/usb/host/whci/asl.c | 3 | ||||
| -rw-r--r-- | drivers/usb/host/whci/hcd.c | 23 | ||||
| -rw-r--r-- | drivers/usb/host/whci/pzl.c | 4 | ||||
| -rw-r--r-- | drivers/usb/host/whci/qset.c | 24 | ||||
| -rw-r--r-- | drivers/usb/host/whci/whcd.h | 1 | ||||
| -rw-r--r-- | drivers/usb/host/whci/whci-hc.h | 1 |
6 files changed, 50 insertions, 6 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 958751ccea43..be753f664993 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c | |||
| @@ -122,7 +122,8 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset) | |||
| 122 | process_inactive_qtd(whc, qset, td); | 122 | process_inactive_qtd(whc, qset, td); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | update |= qset_add_qtds(whc, qset); | 125 | if (!qset->remove) |
| 126 | update |= qset_add_qtds(whc, qset); | ||
| 126 | 127 | ||
| 127 | done: | 128 | done: |
| 128 | /* | 129 | /* |
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index 1569afd6245b..e019a5058ab8 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c | |||
| @@ -186,6 +186,28 @@ static void whc_endpoint_disable(struct usb_hcd *usb_hcd, | |||
| 186 | } | 186 | } |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | static void whc_endpoint_reset(struct usb_hcd *usb_hcd, | ||
| 190 | struct usb_host_endpoint *ep) | ||
| 191 | { | ||
| 192 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | ||
| 193 | struct whc *whc = wusbhc_to_whc(wusbhc); | ||
| 194 | struct whc_qset *qset; | ||
| 195 | |||
| 196 | qset = ep->hcpriv; | ||
| 197 | if (qset) { | ||
| 198 | qset->remove = 1; | ||
| 199 | |||
| 200 | if (usb_endpoint_xfer_bulk(&ep->desc) | ||
| 201 | || usb_endpoint_xfer_control(&ep->desc)) | ||
| 202 | queue_work(whc->workqueue, &whc->async_work); | ||
| 203 | else | ||
| 204 | queue_work(whc->workqueue, &whc->periodic_work); | ||
| 205 | |||
| 206 | qset_reset(whc, qset); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | |||
| 189 | static struct hc_driver whc_hc_driver = { | 211 | static struct hc_driver whc_hc_driver = { |
| 190 | .description = "whci-hcd", | 212 | .description = "whci-hcd", |
| 191 | .product_desc = "Wireless host controller", | 213 | .product_desc = "Wireless host controller", |
| @@ -200,6 +222,7 @@ static struct hc_driver whc_hc_driver = { | |||
| 200 | .urb_enqueue = whc_urb_enqueue, | 222 | .urb_enqueue = whc_urb_enqueue, |
| 201 | .urb_dequeue = whc_urb_dequeue, | 223 | .urb_dequeue = whc_urb_dequeue, |
| 202 | .endpoint_disable = whc_endpoint_disable, | 224 | .endpoint_disable = whc_endpoint_disable, |
| 225 | .endpoint_reset = whc_endpoint_reset, | ||
| 203 | 226 | ||
| 204 | .hub_status_data = wusbhc_rh_status_data, | 227 | .hub_status_data = wusbhc_rh_status_data, |
| 205 | .hub_control = wusbhc_rh_control, | 228 | .hub_control = wusbhc_rh_control, |
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index df8b85f07092..0c40022a6b2f 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c | |||
| @@ -128,7 +128,8 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset) | |||
| 128 | process_inactive_qtd(whc, qset, td); | 128 | process_inactive_qtd(whc, qset, td); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | update |= qset_add_qtds(whc, qset); | 131 | if (!qset->remove) |
| 132 | update |= qset_add_qtds(whc, qset); | ||
| 132 | 133 | ||
| 133 | done: | 134 | done: |
| 134 | /* | 135 | /* |
| @@ -353,7 +354,6 @@ void pzl_qset_delete(struct whc *whc, struct whc_qset *qset) | |||
| 353 | qset_delete(whc, qset); | 354 | qset_delete(whc, qset); |
| 354 | } | 355 | } |
| 355 | 356 | ||
| 356 | |||
| 357 | /** | 357 | /** |
| 358 | * pzl_init - initialize the periodic zone list | 358 | * pzl_init - initialize the periodic zone list |
| 359 | * @whc: the WHCI host controller | 359 | * @whc: the WHCI host controller |
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 7be74314ee12..640b38fbd051 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c | |||
| @@ -89,11 +89,16 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb) | |||
| 89 | QH_INFO3_TX_RATE_53_3 | 89 | QH_INFO3_TX_RATE_53_3 |
| 90 | | QH_INFO3_TX_PWR(0) /* 0 == max power */ | 90 | | QH_INFO3_TX_PWR(0) /* 0 == max power */ |
| 91 | ); | 91 | ); |
| 92 | |||
| 93 | qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1); | ||
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | /** | 96 | /** |
| 95 | * qset_clear - clear fields in a qset so it may be reinserted into a | 97 | * qset_clear - clear fields in a qset so it may be reinserted into a |
| 96 | * schedule | 98 | * schedule. |
| 99 | * | ||
| 100 | * The sequence number and current window are not cleared (see | ||
| 101 | * qset_reset()). | ||
| 97 | */ | 102 | */ |
| 98 | void qset_clear(struct whc *whc, struct whc_qset *qset) | 103 | void qset_clear(struct whc *whc, struct whc_qset *qset) |
| 99 | { | 104 | { |
| @@ -101,9 +106,8 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) | |||
| 101 | qset->remove = 0; | 106 | qset->remove = 0; |
| 102 | 107 | ||
| 103 | qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); | 108 | qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); |
| 104 | qset->qh.status = cpu_to_le16(QH_STATUS_ICUR(qset->td_start)); | 109 | qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; |
| 105 | qset->qh.err_count = 0; | 110 | qset->qh.err_count = 0; |
| 106 | qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1); | ||
| 107 | qset->qh.scratch[0] = 0; | 111 | qset->qh.scratch[0] = 0; |
| 108 | qset->qh.scratch[1] = 0; | 112 | qset->qh.scratch[1] = 0; |
| 109 | qset->qh.scratch[2] = 0; | 113 | qset->qh.scratch[2] = 0; |
| @@ -114,6 +118,20 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) | |||
| 114 | } | 118 | } |
| 115 | 119 | ||
| 116 | /** | 120 | /** |
| 121 | * qset_reset - reset endpoint state in a qset. | ||
| 122 | * | ||
| 123 | * Clears the sequence number and current window. This qset must not | ||
| 124 | * be in the ASL or PZL. | ||
| 125 | */ | ||
| 126 | void qset_reset(struct whc *whc, struct whc_qset *qset) | ||
| 127 | { | ||
| 128 | wait_for_completion(&qset->remove_complete); | ||
| 129 | |||
| 130 | qset->qh.status &= ~QH_STATUS_SEQ_MASK; | ||
| 131 | qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1); | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 117 | * get_qset - get the qset for an async endpoint | 135 | * get_qset - get the qset for an async endpoint |
| 118 | * | 136 | * |
| 119 | * A new qset is created if one does not already exist. | 137 | * A new qset is created if one does not already exist. |
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index d3543a181dc9..24e94d983c5e 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h | |||
| @@ -184,6 +184,7 @@ void qset_free(struct whc *whc, struct whc_qset *qset); | |||
| 184 | struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags); | 184 | struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags); |
| 185 | void qset_delete(struct whc *whc, struct whc_qset *qset); | 185 | void qset_delete(struct whc *whc, struct whc_qset *qset); |
| 186 | void qset_clear(struct whc *whc, struct whc_qset *qset); | 186 | void qset_clear(struct whc *whc, struct whc_qset *qset); |
| 187 | void qset_reset(struct whc *whc, struct whc_qset *qset); | ||
| 187 | int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb, | 188 | int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb, |
| 188 | gfp_t mem_flags); | 189 | gfp_t mem_flags); |
| 189 | void qset_free_std(struct whc *whc, struct whc_std *std); | 190 | void qset_free_std(struct whc *whc, struct whc_std *std); |
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h index 51df7e313b38..794dba0d0f0a 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/usb/host/whci/whci-hc.h | |||
| @@ -185,6 +185,7 @@ struct whc_qhead { | |||
| 185 | #define QH_STATUS_FLOW_CTRL (1 << 15) | 185 | #define QH_STATUS_FLOW_CTRL (1 << 15) |
| 186 | #define QH_STATUS_ICUR(i) ((i) << 5) | 186 | #define QH_STATUS_ICUR(i) ((i) << 5) |
| 187 | #define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7) | 187 | #define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7) |
| 188 | #define QH_STATUS_SEQ_MASK 0x1f | ||
| 188 | 189 | ||
| 189 | /** | 190 | /** |
| 190 | * usb_pipe_to_qh_type - USB core pipe type to QH transfer type | 191 | * usb_pipe_to_qh_type - USB core pipe type to QH transfer type |
