diff options
32 files changed, 532 insertions, 348 deletions
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 69b7f8e77596..689cd27ac890 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
| @@ -1025,6 +1025,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1025 | { | 1025 | { |
| 1026 | struct urb *urb = &sc->work_urb; | 1026 | struct urb *urb = &sc->work_urb; |
| 1027 | struct bulk_cs_wrap *bcs; | 1027 | struct bulk_cs_wrap *bcs; |
| 1028 | int endp; | ||
| 1028 | int len; | 1029 | int len; |
| 1029 | int rc; | 1030 | int rc; |
| 1030 | 1031 | ||
| @@ -1033,6 +1034,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1033 | return; | 1034 | return; |
| 1034 | } | 1035 | } |
| 1035 | 1036 | ||
| 1037 | endp = usb_pipeendpoint(sc->last_pipe); | ||
| 1038 | if (usb_pipein(sc->last_pipe)) | ||
| 1039 | endp |= USB_DIR_IN; | ||
| 1040 | |||
| 1036 | if (cmd->state == UB_CMDST_CLEAR) { | 1041 | if (cmd->state == UB_CMDST_CLEAR) { |
| 1037 | if (urb->status == -EPIPE) { | 1042 | if (urb->status == -EPIPE) { |
| 1038 | /* | 1043 | /* |
| @@ -1048,9 +1053,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1048 | * We ignore the result for the halt clear. | 1053 | * We ignore the result for the halt clear. |
| 1049 | */ | 1054 | */ |
| 1050 | 1055 | ||
| 1051 | /* reset the endpoint toggle */ | 1056 | usb_reset_endpoint(sc->dev, endp); |
| 1052 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
| 1053 | usb_pipeout(sc->last_pipe), 0); | ||
| 1054 | 1057 | ||
| 1055 | ub_state_sense(sc, cmd); | 1058 | ub_state_sense(sc, cmd); |
| 1056 | 1059 | ||
| @@ -1065,9 +1068,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1065 | * We ignore the result for the halt clear. | 1068 | * We ignore the result for the halt clear. |
| 1066 | */ | 1069 | */ |
| 1067 | 1070 | ||
| 1068 | /* reset the endpoint toggle */ | 1071 | usb_reset_endpoint(sc->dev, endp); |
| 1069 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
| 1070 | usb_pipeout(sc->last_pipe), 0); | ||
| 1071 | 1072 | ||
| 1072 | ub_state_stat(sc, cmd); | 1073 | ub_state_stat(sc, cmd); |
| 1073 | 1074 | ||
| @@ -1082,9 +1083,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1082 | * We ignore the result for the halt clear. | 1083 | * We ignore the result for the halt clear. |
| 1083 | */ | 1084 | */ |
| 1084 | 1085 | ||
| 1085 | /* reset the endpoint toggle */ | 1086 | usb_reset_endpoint(sc->dev, endp); |
| 1086 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
| 1087 | usb_pipeout(sc->last_pipe), 0); | ||
| 1088 | 1087 | ||
| 1089 | ub_state_stat_counted(sc, cmd); | 1088 | ub_state_stat_counted(sc, cmd); |
| 1090 | 1089 | ||
| @@ -2119,8 +2118,7 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) | |||
| 2119 | del_timer_sync(&timer); | 2118 | del_timer_sync(&timer); |
| 2120 | usb_kill_urb(&sc->work_urb); | 2119 | usb_kill_urb(&sc->work_urb); |
| 2121 | 2120 | ||
| 2122 | /* reset the endpoint toggle */ | 2121 | usb_reset_endpoint(sc->dev, endp); |
| 2123 | usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0); | ||
| 2124 | 2122 | ||
| 2125 | return 0; | 2123 | return 0; |
| 2126 | } | 2124 | } |
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index ec3c0e507669..2b3a055059ea 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c | |||
| @@ -149,14 +149,7 @@ static void usb_ctrl_complete(struct urb *urb) | |||
| 149 | if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { | 149 | if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { |
| 150 | /* Special case handling for pipe reset */ | 150 | /* Special case handling for pipe reset */ |
| 151 | le16_to_cpus(&ctrl_msg->dr.wIndex); | 151 | le16_to_cpus(&ctrl_msg->dr.wIndex); |
| 152 | 152 | usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex); | |
| 153 | /* toggle is reset on clear */ | ||
| 154 | usb_settoggle(adapter->usb_dev, | ||
| 155 | ctrl_msg->dr.wIndex & ~USB_DIR_IN, | ||
| 156 | (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0, | ||
| 157 | 0); | ||
| 158 | |||
| 159 | |||
| 160 | } | 153 | } |
| 161 | 154 | ||
| 162 | if (ctrl_msg->complete) | 155 | if (ctrl_msg->complete) |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index d9d974a8f52a..add3395d3248 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
| @@ -1461,7 +1461,6 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) | |||
| 1461 | return ret; | 1461 | return ret; |
| 1462 | } | 1462 | } |
| 1463 | 1463 | ||
| 1464 | usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0); | ||
| 1465 | usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); | 1464 | usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); |
| 1466 | 1465 | ||
| 1467 | pipe = usb_sndctrlpipe(hdw->usb_dev, 0); | 1466 | pipe = usb_sndctrlpipe(hdw->usb_dev, 0); |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 3771d6e6d0cc..34e6108e1d42 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
| @@ -652,7 +652,7 @@ next_desc: | |||
| 652 | 652 | ||
| 653 | iface = &intf->altsetting[0]; | 653 | iface = &intf->altsetting[0]; |
| 654 | ep = &iface->endpoint[0].desc; | 654 | ep = &iface->endpoint[0].desc; |
| 655 | if (!usb_endpoint_is_int_in(ep)) { | 655 | if (!ep || !usb_endpoint_is_int_in(ep)) { |
| 656 | rv = -EINVAL; | 656 | rv = -EINVAL; |
| 657 | goto err; | 657 | goto err; |
| 658 | } | 658 | } |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index df3c539f652a..308609039c73 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -841,7 +841,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg) | |||
| 841 | ret = checkintf(ps, ret); | 841 | ret = checkintf(ps, ret); |
| 842 | if (ret) | 842 | if (ret) |
| 843 | return ret; | 843 | return ret; |
| 844 | usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); | 844 | usb_reset_endpoint(ps->dev, ep); |
| 845 | return 0; | 845 | return 0; |
| 846 | } | 846 | } |
| 847 | 847 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 81fa8506825d..42b93da1085d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -1539,6 +1539,32 @@ void usb_hcd_disable_endpoint(struct usb_device *udev, | |||
| 1539 | hcd->driver->endpoint_disable(hcd, ep); | 1539 | hcd->driver->endpoint_disable(hcd, ep); |
| 1540 | } | 1540 | } |
| 1541 | 1541 | ||
| 1542 | /** | ||
| 1543 | * usb_hcd_reset_endpoint - reset host endpoint state | ||
| 1544 | * @udev: USB device. | ||
| 1545 | * @ep: the endpoint to reset. | ||
| 1546 | * | ||
| 1547 | * Resets any host endpoint state such as the toggle bit, sequence | ||
| 1548 | * number and current window. | ||
| 1549 | */ | ||
| 1550 | void usb_hcd_reset_endpoint(struct usb_device *udev, | ||
| 1551 | struct usb_host_endpoint *ep) | ||
| 1552 | { | ||
| 1553 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
| 1554 | |||
| 1555 | if (hcd->driver->endpoint_reset) | ||
| 1556 | hcd->driver->endpoint_reset(hcd, ep); | ||
| 1557 | else { | ||
| 1558 | int epnum = usb_endpoint_num(&ep->desc); | ||
| 1559 | int is_out = usb_endpoint_dir_out(&ep->desc); | ||
| 1560 | int is_control = usb_endpoint_xfer_control(&ep->desc); | ||
| 1561 | |||
| 1562 | usb_settoggle(udev, epnum, is_out, 0); | ||
| 1563 | if (is_control) | ||
| 1564 | usb_settoggle(udev, epnum, !is_out, 0); | ||
| 1565 | } | ||
| 1566 | } | ||
| 1567 | |||
| 1542 | /* Protect against drivers that try to unlink URBs after the device | 1568 | /* Protect against drivers that try to unlink URBs after the device |
| 1543 | * is gone, by waiting until all unlinks for @udev are finished. | 1569 | * is gone, by waiting until all unlinks for @udev are finished. |
| 1544 | * Since we don't currently track URBs by device, simply wait until | 1570 | * Since we don't currently track URBs by device, simply wait until |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index f750eb1ab595..e7d4479de41c 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
| @@ -206,6 +206,11 @@ struct hc_driver { | |||
| 206 | void (*endpoint_disable)(struct usb_hcd *hcd, | 206 | void (*endpoint_disable)(struct usb_hcd *hcd, |
| 207 | struct usb_host_endpoint *ep); | 207 | struct usb_host_endpoint *ep); |
| 208 | 208 | ||
| 209 | /* (optional) reset any endpoint state such as sequence number | ||
| 210 | and current window */ | ||
| 211 | void (*endpoint_reset)(struct usb_hcd *hcd, | ||
| 212 | struct usb_host_endpoint *ep); | ||
| 213 | |||
| 209 | /* root hub support */ | 214 | /* root hub support */ |
| 210 | int (*hub_status_data) (struct usb_hcd *hcd, char *buf); | 215 | int (*hub_status_data) (struct usb_hcd *hcd, char *buf); |
| 211 | int (*hub_control) (struct usb_hcd *hcd, | 216 | int (*hub_control) (struct usb_hcd *hcd, |
| @@ -234,6 +239,8 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev, | |||
| 234 | struct usb_host_endpoint *ep); | 239 | struct usb_host_endpoint *ep); |
| 235 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, | 240 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, |
| 236 | struct usb_host_endpoint *ep); | 241 | struct usb_host_endpoint *ep); |
| 242 | extern void usb_hcd_reset_endpoint(struct usb_device *udev, | ||
| 243 | struct usb_host_endpoint *ep); | ||
| 237 | extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); | 244 | extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); |
| 238 | extern int usb_hcd_get_frame_number(struct usb_device *udev); | 245 | extern int usb_hcd_get_frame_number(struct usb_device *udev); |
| 239 | 246 | ||
| @@ -279,6 +286,13 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd); | |||
| 279 | extern void usb_hc_died(struct usb_hcd *hcd); | 286 | extern void usb_hc_died(struct usb_hcd *hcd); |
| 280 | extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); | 287 | extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); |
| 281 | 288 | ||
| 289 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ | ||
| 290 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) | ||
| 291 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) | ||
| 292 | #define usb_settoggle(dev, ep, out, bit) \ | ||
| 293 | ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ | ||
| 294 | ((bit) << (ep))) | ||
| 295 | |||
| 282 | /* -------------------------------------------------------------------------- */ | 296 | /* -------------------------------------------------------------------------- */ |
| 283 | 297 | ||
| 284 | /* Enumeration is only for the hub driver, or HCD virtual root hubs */ | 298 | /* Enumeration is only for the hub driver, or HCD virtual root hubs */ |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 30a0690f3683..b62628377654 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -1002,8 +1002,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe) | |||
| 1002 | * the copy in usb-storage, for as long as we need two copies. | 1002 | * the copy in usb-storage, for as long as we need two copies. |
| 1003 | */ | 1003 | */ |
| 1004 | 1004 | ||
| 1005 | /* toggle was reset by the clear */ | 1005 | usb_reset_endpoint(dev, endp); |
| 1006 | usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); | ||
| 1007 | 1006 | ||
| 1008 | return 0; | 1007 | return 0; |
| 1009 | } | 1008 | } |
| @@ -1076,6 +1075,30 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, | |||
| 1076 | } | 1075 | } |
| 1077 | 1076 | ||
| 1078 | /** | 1077 | /** |
| 1078 | * usb_reset_endpoint - Reset an endpoint's state. | ||
| 1079 | * @dev: the device whose endpoint is to be reset | ||
| 1080 | * @epaddr: the endpoint's address. Endpoint number for output, | ||
| 1081 | * endpoint number + USB_DIR_IN for input | ||
| 1082 | * | ||
| 1083 | * Resets any host-side endpoint state such as the toggle bit, | ||
| 1084 | * sequence number or current window. | ||
| 1085 | */ | ||
| 1086 | void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr) | ||
| 1087 | { | ||
| 1088 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | ||
| 1089 | struct usb_host_endpoint *ep; | ||
| 1090 | |||
| 1091 | if (usb_endpoint_out(epaddr)) | ||
| 1092 | ep = dev->ep_out[epnum]; | ||
| 1093 | else | ||
| 1094 | ep = dev->ep_in[epnum]; | ||
| 1095 | if (ep) | ||
| 1096 | usb_hcd_reset_endpoint(dev, ep); | ||
| 1097 | } | ||
| 1098 | EXPORT_SYMBOL_GPL(usb_reset_endpoint); | ||
| 1099 | |||
| 1100 | |||
| 1101 | /** | ||
| 1079 | * usb_disable_interface -- Disable all endpoints for an interface | 1102 | * usb_disable_interface -- Disable all endpoints for an interface |
| 1080 | * @dev: the device whose interface is being disabled | 1103 | * @dev: the device whose interface is being disabled |
| 1081 | * @intf: pointer to the interface descriptor | 1104 | * @intf: pointer to the interface descriptor |
| @@ -1117,7 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
| 1117 | usb_disable_endpoint(dev, i, true); | 1140 | usb_disable_endpoint(dev, i, true); |
| 1118 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); | 1141 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
| 1119 | } | 1142 | } |
| 1120 | dev->toggle[0] = dev->toggle[1] = 0; | ||
| 1121 | 1143 | ||
| 1122 | /* getting rid of interfaces will disconnect | 1144 | /* getting rid of interfaces will disconnect |
| 1123 | * any drivers bound to them (a key side effect) | 1145 | * any drivers bound to them (a key side effect) |
| @@ -1154,28 +1176,24 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
| 1154 | * usb_enable_endpoint - Enable an endpoint for USB communications | 1176 | * usb_enable_endpoint - Enable an endpoint for USB communications |
| 1155 | * @dev: the device whose interface is being enabled | 1177 | * @dev: the device whose interface is being enabled |
| 1156 | * @ep: the endpoint | 1178 | * @ep: the endpoint |
| 1157 | * @reset_toggle: flag to set the endpoint's toggle back to 0 | 1179 | * @reset_ep: flag to reset the endpoint state |
| 1158 | * | 1180 | * |
| 1159 | * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers. | 1181 | * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers. |
| 1160 | * For control endpoints, both the input and output sides are handled. | 1182 | * For control endpoints, both the input and output sides are handled. |
| 1161 | */ | 1183 | */ |
| 1162 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, | 1184 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, |
| 1163 | bool reset_toggle) | 1185 | bool reset_ep) |
| 1164 | { | 1186 | { |
| 1165 | int epnum = usb_endpoint_num(&ep->desc); | 1187 | int epnum = usb_endpoint_num(&ep->desc); |
| 1166 | int is_out = usb_endpoint_dir_out(&ep->desc); | 1188 | int is_out = usb_endpoint_dir_out(&ep->desc); |
| 1167 | int is_control = usb_endpoint_xfer_control(&ep->desc); | 1189 | int is_control = usb_endpoint_xfer_control(&ep->desc); |
| 1168 | 1190 | ||
| 1169 | if (is_out || is_control) { | 1191 | if (reset_ep) |
| 1170 | if (reset_toggle) | 1192 | usb_hcd_reset_endpoint(dev, ep); |
| 1171 | usb_settoggle(dev, epnum, 1, 0); | 1193 | if (is_out || is_control) |
| 1172 | dev->ep_out[epnum] = ep; | 1194 | dev->ep_out[epnum] = ep; |
| 1173 | } | 1195 | if (!is_out || is_control) |
| 1174 | if (!is_out || is_control) { | ||
| 1175 | if (reset_toggle) | ||
| 1176 | usb_settoggle(dev, epnum, 0, 0); | ||
| 1177 | dev->ep_in[epnum] = ep; | 1196 | dev->ep_in[epnum] = ep; |
| 1178 | } | ||
| 1179 | ep->enabled = 1; | 1197 | ep->enabled = 1; |
| 1180 | } | 1198 | } |
| 1181 | 1199 | ||
| @@ -1183,18 +1201,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, | |||
| 1183 | * usb_enable_interface - Enable all the endpoints for an interface | 1201 | * usb_enable_interface - Enable all the endpoints for an interface |
| 1184 | * @dev: the device whose interface is being enabled | 1202 | * @dev: the device whose interface is being enabled |
| 1185 | * @intf: pointer to the interface descriptor | 1203 | * @intf: pointer to the interface descriptor |
| 1186 | * @reset_toggles: flag to set the endpoints' toggles back to 0 | 1204 | * @reset_eps: flag to reset the endpoints' state |
| 1187 | * | 1205 | * |
| 1188 | * Enables all the endpoints for the interface's current altsetting. | 1206 | * Enables all the endpoints for the interface's current altsetting. |
| 1189 | */ | 1207 | */ |
| 1190 | void usb_enable_interface(struct usb_device *dev, | 1208 | void usb_enable_interface(struct usb_device *dev, |
| 1191 | struct usb_interface *intf, bool reset_toggles) | 1209 | struct usb_interface *intf, bool reset_eps) |
| 1192 | { | 1210 | { |
| 1193 | struct usb_host_interface *alt = intf->cur_altsetting; | 1211 | struct usb_host_interface *alt = intf->cur_altsetting; |
| 1194 | int i; | 1212 | int i; |
| 1195 | 1213 | ||
| 1196 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) | 1214 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) |
| 1197 | usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles); | 1215 | usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps); |
| 1198 | } | 1216 | } |
| 1199 | 1217 | ||
| 1200 | /** | 1218 | /** |
| @@ -1335,7 +1353,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface); | |||
| 1335 | * This issues a standard SET_CONFIGURATION request to the device using | 1353 | * This issues a standard SET_CONFIGURATION request to the device using |
| 1336 | * the current configuration. The effect is to reset most USB-related | 1354 | * the current configuration. The effect is to reset most USB-related |
| 1337 | * state in the device, including interface altsettings (reset to zero), | 1355 | * state in the device, including interface altsettings (reset to zero), |
| 1338 | * endpoint halts (cleared), and data toggle (only for bulk and interrupt | 1356 | * endpoint halts (cleared), and endpoint state (only for bulk and interrupt |
| 1339 | * endpoints). Other usbcore state is unchanged, including bindings of | 1357 | * endpoints). Other usbcore state is unchanged, including bindings of |
| 1340 | * usb device drivers to interfaces. | 1358 | * usb device drivers to interfaces. |
| 1341 | * | 1359 | * |
| @@ -1343,7 +1361,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface); | |||
| 1343 | * (multi-interface) devices. Instead, the driver for each interface may | 1361 | * (multi-interface) devices. Instead, the driver for each interface may |
| 1344 | * use usb_set_interface() on the interfaces it claims. Be careful though; | 1362 | * use usb_set_interface() on the interfaces it claims. Be careful though; |
| 1345 | * some devices don't support the SET_INTERFACE request, and others won't | 1363 | * some devices don't support the SET_INTERFACE request, and others won't |
| 1346 | * reset all the interface state (notably data toggles). Resetting the whole | 1364 | * reset all the interface state (notably endpoint state). Resetting the whole |
| 1347 | * configuration would affect other drivers' interfaces. | 1365 | * configuration would affect other drivers' interfaces. |
| 1348 | * | 1366 | * |
| 1349 | * The caller must own the device lock. | 1367 | * The caller must own the device lock. |
| @@ -1376,8 +1394,6 @@ int usb_reset_configuration(struct usb_device *dev) | |||
| 1376 | if (retval < 0) | 1394 | if (retval < 0) |
| 1377 | return retval; | 1395 | return retval; |
| 1378 | 1396 | ||
| 1379 | dev->toggle[0] = dev->toggle[1] = 0; | ||
| 1380 | |||
| 1381 | /* re-init hc/hcd interface/endpoint state */ | 1397 | /* re-init hc/hcd interface/endpoint state */ |
| 1382 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | 1398 | for (i = 0; i < config->desc.bNumInterfaces; i++) { |
| 1383 | struct usb_interface *intf = config->interface[i]; | 1399 | struct usb_interface *intf = config->interface[i]; |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index dcfc072630c1..7eee400d3e32 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
| 362 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; | 362 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; |
| 363 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; | 363 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; |
| 364 | /* ep0 maxpacket comes later, from device descriptor */ | 364 | /* ep0 maxpacket comes later, from device descriptor */ |
| 365 | usb_enable_endpoint(dev, &dev->ep0, true); | 365 | usb_enable_endpoint(dev, &dev->ep0, false); |
| 366 | dev->can_submit = 1; | 366 | dev->can_submit = 1; |
| 367 | 367 | ||
| 368 | /* Save readable and stable topology id, distinguishing devices | 368 | /* Save readable and stable topology id, distinguishing devices |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 96d65ca06ecd..4007770f7ed2 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) | |||
| 175 | strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); | 175 | strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static u32 eth_get_link(struct net_device *net) | ||
| 179 | { | ||
| 180 | struct eth_dev *dev = netdev_priv(net); | ||
| 181 | return dev->gadget->speed != USB_SPEED_UNKNOWN; | ||
| 182 | } | ||
| 183 | |||
| 184 | /* REVISIT can also support: | 178 | /* REVISIT can also support: |
| 185 | * - WOL (by tracking suspends and issuing remote wakeup) | 179 | * - WOL (by tracking suspends and issuing remote wakeup) |
| 186 | * - msglevel (implies updated messaging) | 180 | * - msglevel (implies updated messaging) |
| @@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net) | |||
| 189 | 183 | ||
| 190 | static struct ethtool_ops ops = { | 184 | static struct ethtool_ops ops = { |
| 191 | .get_drvinfo = eth_get_drvinfo, | 185 | .get_drvinfo = eth_get_drvinfo, |
| 192 | .get_link = eth_get_link | 186 | .get_link = ethtool_op_get_link, |
| 193 | }; | 187 | }; |
| 194 | 188 | ||
| 195 | static void defer_kevent(struct eth_dev *dev, int flag) | 189 | static void defer_kevent(struct eth_dev *dev, int flag) |
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 958751ccea43..c2050785a819 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 | /* |
| @@ -254,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags) | |||
| 254 | 255 | ||
| 255 | spin_lock_irqsave(&whc->lock, flags); | 256 | spin_lock_irqsave(&whc->lock, flags); |
| 256 | 257 | ||
| 258 | err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
| 259 | if (err < 0) { | ||
| 260 | spin_unlock_irqrestore(&whc->lock, flags); | ||
| 261 | return err; | ||
| 262 | } | ||
| 263 | |||
| 257 | qset = get_qset(whc, urb, GFP_ATOMIC); | 264 | qset = get_qset(whc, urb, GFP_ATOMIC); |
| 258 | if (qset == NULL) | 265 | if (qset == NULL) |
| 259 | err = -ENOMEM; | 266 | err = -ENOMEM; |
| 260 | else | 267 | else |
| 261 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); | 268 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); |
| 262 | if (!err) { | 269 | if (!err) { |
| 263 | usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
| 264 | if (!qset->in_sw_list) | 270 | if (!qset->in_sw_list) |
| 265 | asl_qset_insert_begin(whc, qset); | 271 | asl_qset_insert_begin(whc, qset); |
| 266 | } | 272 | } else |
| 273 | usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); | ||
| 267 | 274 | ||
| 268 | spin_unlock_irqrestore(&whc->lock, flags); | 275 | spin_unlock_irqrestore(&whc->lock, flags); |
| 269 | 276 | ||
| 270 | if (!err) | 277 | if (!err) |
| 271 | queue_work(whc->workqueue, &whc->async_work); | 278 | queue_work(whc->workqueue, &whc->async_work); |
| 272 | 279 | ||
| 273 | return 0; | 280 | return err; |
| 274 | } | 281 | } |
| 275 | 282 | ||
| 276 | /** | 283 | /** |
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..ff4ef9e910d9 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 | /* |
| @@ -282,23 +283,29 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags) | |||
| 282 | 283 | ||
| 283 | spin_lock_irqsave(&whc->lock, flags); | 284 | spin_lock_irqsave(&whc->lock, flags); |
| 284 | 285 | ||
| 286 | err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
| 287 | if (err < 0) { | ||
| 288 | spin_unlock_irqrestore(&whc->lock, flags); | ||
| 289 | return err; | ||
| 290 | } | ||
| 291 | |||
| 285 | qset = get_qset(whc, urb, GFP_ATOMIC); | 292 | qset = get_qset(whc, urb, GFP_ATOMIC); |
| 286 | if (qset == NULL) | 293 | if (qset == NULL) |
| 287 | err = -ENOMEM; | 294 | err = -ENOMEM; |
| 288 | else | 295 | else |
| 289 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); | 296 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); |
| 290 | if (!err) { | 297 | if (!err) { |
| 291 | usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
| 292 | if (!qset->in_sw_list) | 298 | if (!qset->in_sw_list) |
| 293 | qset_insert_in_sw_list(whc, qset); | 299 | qset_insert_in_sw_list(whc, qset); |
| 294 | } | 300 | } else |
| 301 | usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); | ||
| 295 | 302 | ||
| 296 | spin_unlock_irqrestore(&whc->lock, flags); | 303 | spin_unlock_irqrestore(&whc->lock, flags); |
| 297 | 304 | ||
| 298 | if (!err) | 305 | if (!err) |
| 299 | queue_work(whc->workqueue, &whc->periodic_work); | 306 | queue_work(whc->workqueue, &whc->periodic_work); |
| 300 | 307 | ||
| 301 | return 0; | 308 | return err; |
| 302 | } | 309 | } |
| 303 | 310 | ||
| 304 | /** | 311 | /** |
| @@ -353,7 +360,6 @@ void pzl_qset_delete(struct whc *whc, struct whc_qset *qset) | |||
| 353 | qset_delete(whc, qset); | 360 | qset_delete(whc, qset); |
| 354 | } | 361 | } |
| 355 | 362 | ||
| 356 | |||
| 357 | /** | 363 | /** |
| 358 | * pzl_init - initialize the periodic zone list | 364 | * pzl_init - initialize the periodic zone list |
| 359 | * @whc: the WHCI host controller | 365 | * @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 |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 569ef0fed0f6..1976e9b41800 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
| @@ -579,6 +579,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) | |||
| 579 | * trigger the "send a ZLP?" confusion. | 579 | * trigger the "send a ZLP?" confusion. |
| 580 | */ | 580 | */ |
| 581 | rndis = (maxpacket & 0x3f) == 0 | 581 | rndis = (maxpacket & 0x3f) == 0 |
| 582 | && length > maxpacket | ||
| 582 | && length < 0xffff | 583 | && length < 0xffff |
| 583 | && (length % maxpacket) != 0; | 584 | && (length % maxpacket) != 0; |
| 584 | 585 | ||
| @@ -1228,27 +1229,7 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx) | |||
| 1228 | 1229 | ||
| 1229 | hw_ep = tx_ch->hw_ep; | 1230 | hw_ep = tx_ch->hw_ep; |
| 1230 | 1231 | ||
| 1231 | /* Peripheral role never repurposes the | 1232 | musb_dma_completion(musb, index + 1, 1); |
| 1232 | * endpoint, so immediate completion is | ||
| 1233 | * safe. Host role waits for the fifo | ||
| 1234 | * to empty (TXPKTRDY irq) before going | ||
| 1235 | * to the next queued bulk transfer. | ||
| 1236 | */ | ||
| 1237 | if (is_host_active(cppi->musb)) { | ||
| 1238 | #if 0 | ||
| 1239 | /* WORKAROUND because we may | ||
| 1240 | * not always get TXKPTRDY ... | ||
| 1241 | */ | ||
| 1242 | int csr; | ||
| 1243 | |||
| 1244 | csr = musb_readw(hw_ep->regs, | ||
| 1245 | MUSB_TXCSR); | ||
| 1246 | if (csr & MUSB_TXCSR_TXPKTRDY) | ||
| 1247 | #endif | ||
| 1248 | completed = false; | ||
| 1249 | } | ||
| 1250 | if (completed) | ||
| 1251 | musb_dma_completion(musb, index + 1, 1); | ||
| 1252 | 1233 | ||
| 1253 | } else { | 1234 | } else { |
| 1254 | /* Bigger transfer than we could fit in | 1235 | /* Bigger transfer than we could fit in |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 338cd1611ab3..0112353ec97d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -2170,26 +2170,22 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message) | |||
| 2170 | return 0; | 2170 | return 0; |
| 2171 | } | 2171 | } |
| 2172 | 2172 | ||
| 2173 | static int musb_resume(struct platform_device *pdev) | 2173 | static int musb_resume_early(struct platform_device *pdev) |
| 2174 | { | 2174 | { |
| 2175 | unsigned long flags; | ||
| 2176 | struct musb *musb = dev_to_musb(&pdev->dev); | 2175 | struct musb *musb = dev_to_musb(&pdev->dev); |
| 2177 | 2176 | ||
| 2178 | if (!musb->clock) | 2177 | if (!musb->clock) |
| 2179 | return 0; | 2178 | return 0; |
| 2180 | 2179 | ||
| 2181 | spin_lock_irqsave(&musb->lock, flags); | ||
| 2182 | |||
| 2183 | if (musb->set_clock) | 2180 | if (musb->set_clock) |
| 2184 | musb->set_clock(musb->clock, 1); | 2181 | musb->set_clock(musb->clock, 1); |
| 2185 | else | 2182 | else |
| 2186 | clk_enable(musb->clock); | 2183 | clk_enable(musb->clock); |
| 2187 | 2184 | ||
| 2188 | /* for static cmos like DaVinci, register values were preserved | 2185 | /* for static cmos like DaVinci, register values were preserved |
| 2189 | * unless for some reason the whole soc powered down and we're | 2186 | * unless for some reason the whole soc powered down or the USB |
| 2190 | * not treating that as a whole-system restart (e.g. swsusp) | 2187 | * module got reset through the PSC (vs just being disabled). |
| 2191 | */ | 2188 | */ |
| 2192 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 2193 | return 0; | 2189 | return 0; |
| 2194 | } | 2190 | } |
| 2195 | 2191 | ||
| @@ -2207,7 +2203,7 @@ static struct platform_driver musb_driver = { | |||
| 2207 | .remove = __devexit_p(musb_remove), | 2203 | .remove = __devexit_p(musb_remove), |
| 2208 | .shutdown = musb_shutdown, | 2204 | .shutdown = musb_shutdown, |
| 2209 | .suspend = musb_suspend, | 2205 | .suspend = musb_suspend, |
| 2210 | .resume = musb_resume, | 2206 | .resume_early = musb_resume_early, |
| 2211 | }; | 2207 | }; |
| 2212 | 2208 | ||
| 2213 | /*-------------------------------------------------------------------------*/ | 2209 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c7ebd0867fcc..f79440cdfe7e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -165,9 +165,15 @@ static void nuke(struct musb_ep *ep, const int status) | |||
| 165 | if (is_dma_capable() && ep->dma) { | 165 | if (is_dma_capable() && ep->dma) { |
| 166 | struct dma_controller *c = ep->musb->dma_controller; | 166 | struct dma_controller *c = ep->musb->dma_controller; |
| 167 | int value; | 167 | int value; |
| 168 | |||
| 168 | if (ep->is_in) { | 169 | if (ep->is_in) { |
| 170 | /* | ||
| 171 | * The programming guide says that we must not clear | ||
| 172 | * the DMAMODE bit before DMAENAB, so we only | ||
| 173 | * clear it in the second write... | ||
| 174 | */ | ||
| 169 | musb_writew(epio, MUSB_TXCSR, | 175 | musb_writew(epio, MUSB_TXCSR, |
| 170 | 0 | MUSB_TXCSR_FLUSHFIFO); | 176 | MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO); |
| 171 | musb_writew(epio, MUSB_TXCSR, | 177 | musb_writew(epio, MUSB_TXCSR, |
| 172 | 0 | MUSB_TXCSR_FLUSHFIFO); | 178 | 0 | MUSB_TXCSR_FLUSHFIFO); |
| 173 | } else { | 179 | } else { |
| @@ -230,7 +236,7 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep) | |||
| 230 | | IN token(s) are recd from Host. | 236 | | IN token(s) are recd from Host. |
| 231 | | -> DMA interrupt on completion | 237 | | -> DMA interrupt on completion |
| 232 | | calls TxAvail. | 238 | | calls TxAvail. |
| 233 | | -> stop DMA, ~DmaEenab, | 239 | | -> stop DMA, ~DMAENAB, |
| 234 | | -> set TxPktRdy for last short pkt or zlp | 240 | | -> set TxPktRdy for last short pkt or zlp |
| 235 | | -> Complete Request | 241 | | -> Complete Request |
| 236 | | -> Continue next request (call txstate) | 242 | | -> Continue next request (call txstate) |
| @@ -315,9 +321,17 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
| 315 | request->dma, request_size); | 321 | request->dma, request_size); |
| 316 | if (use_dma) { | 322 | if (use_dma) { |
| 317 | if (musb_ep->dma->desired_mode == 0) { | 323 | if (musb_ep->dma->desired_mode == 0) { |
| 318 | /* ASSERT: DMAENAB is clear */ | 324 | /* |
| 319 | csr &= ~(MUSB_TXCSR_AUTOSET | | 325 | * We must not clear the DMAMODE bit |
| 320 | MUSB_TXCSR_DMAMODE); | 326 | * before the DMAENAB bit -- and the |
| 327 | * latter doesn't always get cleared | ||
| 328 | * before we get here... | ||
| 329 | */ | ||
| 330 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
| 331 | | MUSB_TXCSR_DMAENAB); | ||
| 332 | musb_writew(epio, MUSB_TXCSR, csr | ||
| 333 | | MUSB_TXCSR_P_WZC_BITS); | ||
| 334 | csr &= ~MUSB_TXCSR_DMAMODE; | ||
| 321 | csr |= (MUSB_TXCSR_DMAENAB | | 335 | csr |= (MUSB_TXCSR_DMAENAB | |
| 322 | MUSB_TXCSR_MODE); | 336 | MUSB_TXCSR_MODE); |
| 323 | /* against programming guide */ | 337 | /* against programming guide */ |
| @@ -334,10 +348,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
| 334 | 348 | ||
| 335 | #elif defined(CONFIG_USB_TI_CPPI_DMA) | 349 | #elif defined(CONFIG_USB_TI_CPPI_DMA) |
| 336 | /* program endpoint CSR first, then setup DMA */ | 350 | /* program endpoint CSR first, then setup DMA */ |
| 337 | csr &= ~(MUSB_TXCSR_AUTOSET | 351 | csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); |
| 338 | | MUSB_TXCSR_DMAMODE | ||
| 339 | | MUSB_TXCSR_P_UNDERRUN | ||
| 340 | | MUSB_TXCSR_TXPKTRDY); | ||
| 341 | csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB; | 352 | csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB; |
| 342 | musb_writew(epio, MUSB_TXCSR, | 353 | musb_writew(epio, MUSB_TXCSR, |
| 343 | (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) | 354 | (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) |
| @@ -364,8 +375,8 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
| 364 | if (!use_dma) { | 375 | if (!use_dma) { |
| 365 | c->channel_release(musb_ep->dma); | 376 | c->channel_release(musb_ep->dma); |
| 366 | musb_ep->dma = NULL; | 377 | musb_ep->dma = NULL; |
| 367 | /* ASSERT: DMAENAB clear */ | 378 | csr &= ~MUSB_TXCSR_DMAENAB; |
| 368 | csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE); | 379 | musb_writew(epio, MUSB_TXCSR, csr); |
| 369 | /* invariant: prequest->buf is non-null */ | 380 | /* invariant: prequest->buf is non-null */ |
| 370 | } | 381 | } |
| 371 | #elif defined(CONFIG_USB_TUSB_OMAP_DMA) | 382 | #elif defined(CONFIG_USB_TUSB_OMAP_DMA) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 499c431a6d62..db1b57415ec7 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * Copyright 2005 Mentor Graphics Corporation | 4 | * Copyright 2005 Mentor Graphics Corporation |
| 5 | * Copyright (C) 2005-2006 by Texas Instruments | 5 | * Copyright (C) 2005-2006 by Texas Instruments |
| 6 | * Copyright (C) 2006-2007 Nokia Corporation | 6 | * Copyright (C) 2006-2007 Nokia Corporation |
| 7 | * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com> | ||
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
| @@ -96,8 +97,8 @@ | |||
| 96 | 97 | ||
| 97 | 98 | ||
| 98 | static void musb_ep_program(struct musb *musb, u8 epnum, | 99 | static void musb_ep_program(struct musb *musb, u8 epnum, |
| 99 | struct urb *urb, unsigned int nOut, | 100 | struct urb *urb, int is_out, |
| 100 | u8 *buf, u32 len); | 101 | u8 *buf, u32 offset, u32 len); |
| 101 | 102 | ||
| 102 | /* | 103 | /* |
| 103 | * Clear TX fifo. Needed to avoid BABBLE errors. | 104 | * Clear TX fifo. Needed to avoid BABBLE errors. |
| @@ -125,6 +126,29 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) | |||
| 125 | } | 126 | } |
| 126 | } | 127 | } |
| 127 | 128 | ||
| 129 | static void musb_h_ep0_flush_fifo(struct musb_hw_ep *ep) | ||
| 130 | { | ||
| 131 | void __iomem *epio = ep->regs; | ||
| 132 | u16 csr; | ||
| 133 | int retries = 5; | ||
| 134 | |||
| 135 | /* scrub any data left in the fifo */ | ||
| 136 | do { | ||
| 137 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 138 | if (!(csr & (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_RXPKTRDY))) | ||
| 139 | break; | ||
| 140 | musb_writew(epio, MUSB_TXCSR, MUSB_CSR0_FLUSHFIFO); | ||
| 141 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 142 | udelay(10); | ||
| 143 | } while (--retries); | ||
| 144 | |||
| 145 | WARN(!retries, "Could not flush host TX%d fifo: csr: %04x\n", | ||
| 146 | ep->epnum, csr); | ||
| 147 | |||
| 148 | /* and reset for the next transfer */ | ||
| 149 | musb_writew(epio, MUSB_TXCSR, 0); | ||
| 150 | } | ||
| 151 | |||
| 128 | /* | 152 | /* |
| 129 | * Start transmit. Caller is responsible for locking shared resources. | 153 | * Start transmit. Caller is responsible for locking shared resources. |
| 130 | * musb must be locked. | 154 | * musb must be locked. |
| @@ -145,13 +169,15 @@ static inline void musb_h_tx_start(struct musb_hw_ep *ep) | |||
| 145 | 169 | ||
| 146 | } | 170 | } |
| 147 | 171 | ||
| 148 | static inline void cppi_host_txdma_start(struct musb_hw_ep *ep) | 172 | static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep) |
| 149 | { | 173 | { |
| 150 | u16 txcsr; | 174 | u16 txcsr; |
| 151 | 175 | ||
| 152 | /* NOTE: no locks here; caller should lock and select EP */ | 176 | /* NOTE: no locks here; caller should lock and select EP */ |
| 153 | txcsr = musb_readw(ep->regs, MUSB_TXCSR); | 177 | txcsr = musb_readw(ep->regs, MUSB_TXCSR); |
| 154 | txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; | 178 | txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; |
| 179 | if (is_cppi_enabled()) | ||
| 180 | txcsr |= MUSB_TXCSR_DMAMODE; | ||
| 155 | musb_writew(ep->regs, MUSB_TXCSR, txcsr); | 181 | musb_writew(ep->regs, MUSB_TXCSR, txcsr); |
| 156 | } | 182 | } |
| 157 | 183 | ||
| @@ -166,9 +192,10 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
| 166 | { | 192 | { |
| 167 | u16 frame; | 193 | u16 frame; |
| 168 | u32 len; | 194 | u32 len; |
| 169 | void *buf; | ||
| 170 | void __iomem *mbase = musb->mregs; | 195 | void __iomem *mbase = musb->mregs; |
| 171 | struct urb *urb = next_urb(qh); | 196 | struct urb *urb = next_urb(qh); |
| 197 | void *buf = urb->transfer_buffer; | ||
| 198 | u32 offset = 0; | ||
| 172 | struct musb_hw_ep *hw_ep = qh->hw_ep; | 199 | struct musb_hw_ep *hw_ep = qh->hw_ep; |
| 173 | unsigned pipe = urb->pipe; | 200 | unsigned pipe = urb->pipe; |
| 174 | u8 address = usb_pipedevice(pipe); | 201 | u8 address = usb_pipedevice(pipe); |
| @@ -191,7 +218,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
| 191 | case USB_ENDPOINT_XFER_ISOC: | 218 | case USB_ENDPOINT_XFER_ISOC: |
| 192 | qh->iso_idx = 0; | 219 | qh->iso_idx = 0; |
| 193 | qh->frame = 0; | 220 | qh->frame = 0; |
| 194 | buf = urb->transfer_buffer + urb->iso_frame_desc[0].offset; | 221 | offset = urb->iso_frame_desc[0].offset; |
| 195 | len = urb->iso_frame_desc[0].length; | 222 | len = urb->iso_frame_desc[0].length; |
| 196 | break; | 223 | break; |
| 197 | default: /* bulk, interrupt */ | 224 | default: /* bulk, interrupt */ |
| @@ -209,14 +236,14 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
| 209 | case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; | 236 | case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; |
| 210 | default: s = "-intr"; break; | 237 | default: s = "-intr"; break; |
| 211 | }; s; }), | 238 | }; s; }), |
| 212 | epnum, buf, len); | 239 | epnum, buf + offset, len); |
| 213 | 240 | ||
| 214 | /* Configure endpoint */ | 241 | /* Configure endpoint */ |
| 215 | if (is_in || hw_ep->is_shared_fifo) | 242 | if (is_in || hw_ep->is_shared_fifo) |
| 216 | hw_ep->in_qh = qh; | 243 | hw_ep->in_qh = qh; |
| 217 | else | 244 | else |
| 218 | hw_ep->out_qh = qh; | 245 | hw_ep->out_qh = qh; |
| 219 | musb_ep_program(musb, epnum, urb, !is_in, buf, len); | 246 | musb_ep_program(musb, epnum, urb, !is_in, buf, offset, len); |
| 220 | 247 | ||
| 221 | /* transmit may have more work: start it when it is time */ | 248 | /* transmit may have more work: start it when it is time */ |
| 222 | if (is_in) | 249 | if (is_in) |
| @@ -227,7 +254,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
| 227 | case USB_ENDPOINT_XFER_ISOC: | 254 | case USB_ENDPOINT_XFER_ISOC: |
| 228 | case USB_ENDPOINT_XFER_INT: | 255 | case USB_ENDPOINT_XFER_INT: |
| 229 | DBG(3, "check whether there's still time for periodic Tx\n"); | 256 | DBG(3, "check whether there's still time for periodic Tx\n"); |
| 230 | qh->iso_idx = 0; | ||
| 231 | frame = musb_readw(mbase, MUSB_FRAME); | 257 | frame = musb_readw(mbase, MUSB_FRAME); |
| 232 | /* FIXME this doesn't implement that scheduling policy ... | 258 | /* FIXME this doesn't implement that scheduling policy ... |
| 233 | * or handle framecounter wrapping | 259 | * or handle framecounter wrapping |
| @@ -256,7 +282,7 @@ start: | |||
| 256 | if (!hw_ep->tx_channel) | 282 | if (!hw_ep->tx_channel) |
| 257 | musb_h_tx_start(hw_ep); | 283 | musb_h_tx_start(hw_ep); |
| 258 | else if (is_cppi_enabled() || tusb_dma_omap()) | 284 | else if (is_cppi_enabled() || tusb_dma_omap()) |
| 259 | cppi_host_txdma_start(hw_ep); | 285 | musb_h_tx_dma_start(hw_ep); |
| 260 | } | 286 | } |
| 261 | } | 287 | } |
| 262 | 288 | ||
| @@ -567,10 +593,17 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
| 567 | csr = musb_readw(ep->regs, MUSB_TXCSR); | 593 | csr = musb_readw(ep->regs, MUSB_TXCSR); |
| 568 | if (csr & MUSB_TXCSR_MODE) { | 594 | if (csr & MUSB_TXCSR_MODE) { |
| 569 | musb_h_tx_flush_fifo(ep); | 595 | musb_h_tx_flush_fifo(ep); |
| 596 | csr = musb_readw(ep->regs, MUSB_TXCSR); | ||
| 570 | musb_writew(ep->regs, MUSB_TXCSR, | 597 | musb_writew(ep->regs, MUSB_TXCSR, |
| 571 | MUSB_TXCSR_FRCDATATOG); | 598 | csr | MUSB_TXCSR_FRCDATATOG); |
| 572 | } | 599 | } |
| 573 | /* clear mode (and everything else) to enable Rx */ | 600 | |
| 601 | /* | ||
| 602 | * Clear the MODE bit (and everything else) to enable Rx. | ||
| 603 | * NOTE: we mustn't clear the DMAMODE bit before DMAENAB. | ||
| 604 | */ | ||
| 605 | if (csr & MUSB_TXCSR_DMAMODE) | ||
| 606 | musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE); | ||
| 574 | musb_writew(ep->regs, MUSB_TXCSR, 0); | 607 | musb_writew(ep->regs, MUSB_TXCSR, 0); |
| 575 | 608 | ||
| 576 | /* scrub all previous state, clearing toggle */ | 609 | /* scrub all previous state, clearing toggle */ |
| @@ -601,14 +634,68 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
| 601 | ep->rx_reinit = 0; | 634 | ep->rx_reinit = 0; |
| 602 | } | 635 | } |
| 603 | 636 | ||
| 637 | static bool musb_tx_dma_program(struct dma_controller *dma, | ||
| 638 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, | ||
| 639 | struct urb *urb, u32 offset, u32 length) | ||
| 640 | { | ||
| 641 | struct dma_channel *channel = hw_ep->tx_channel; | ||
| 642 | void __iomem *epio = hw_ep->regs; | ||
| 643 | u16 pkt_size = qh->maxpacket; | ||
| 644 | u16 csr; | ||
| 645 | u8 mode; | ||
| 646 | |||
| 647 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
| 648 | if (length > channel->max_len) | ||
| 649 | length = channel->max_len; | ||
| 650 | |||
| 651 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 652 | if (length > pkt_size) { | ||
| 653 | mode = 1; | ||
| 654 | csr |= MUSB_TXCSR_AUTOSET | ||
| 655 | | MUSB_TXCSR_DMAMODE | ||
| 656 | | MUSB_TXCSR_DMAENAB; | ||
| 657 | } else { | ||
| 658 | mode = 0; | ||
| 659 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE); | ||
| 660 | csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */ | ||
| 661 | } | ||
| 662 | channel->desired_mode = mode; | ||
| 663 | musb_writew(epio, MUSB_TXCSR, csr); | ||
| 664 | #else | ||
| 665 | if (!is_cppi_enabled() && !tusb_dma_omap()) | ||
| 666 | return false; | ||
| 667 | |||
| 668 | channel->actual_len = 0; | ||
| 669 | |||
| 670 | /* | ||
| 671 | * TX uses "RNDIS" mode automatically but needs help | ||
| 672 | * to identify the zero-length-final-packet case. | ||
| 673 | */ | ||
| 674 | mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; | ||
| 675 | #endif | ||
| 676 | |||
| 677 | qh->segsize = length; | ||
| 678 | |||
| 679 | if (!dma->channel_program(channel, pkt_size, mode, | ||
| 680 | urb->transfer_dma + offset, length)) { | ||
| 681 | dma->channel_release(channel); | ||
| 682 | hw_ep->tx_channel = NULL; | ||
| 683 | |||
| 684 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 685 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB); | ||
| 686 | musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_H_WZC_BITS); | ||
| 687 | return false; | ||
| 688 | } | ||
| 689 | return true; | ||
| 690 | } | ||
| 604 | 691 | ||
| 605 | /* | 692 | /* |
| 606 | * Program an HDRC endpoint as per the given URB | 693 | * Program an HDRC endpoint as per the given URB |
| 607 | * Context: irqs blocked, controller lock held | 694 | * Context: irqs blocked, controller lock held |
| 608 | */ | 695 | */ |
| 609 | static void musb_ep_program(struct musb *musb, u8 epnum, | 696 | static void musb_ep_program(struct musb *musb, u8 epnum, |
| 610 | struct urb *urb, unsigned int is_out, | 697 | struct urb *urb, int is_out, |
| 611 | u8 *buf, u32 len) | 698 | u8 *buf, u32 offset, u32 len) |
| 612 | { | 699 | { |
| 613 | struct dma_controller *dma_controller; | 700 | struct dma_controller *dma_controller; |
| 614 | struct dma_channel *dma_channel; | 701 | struct dma_channel *dma_channel; |
| @@ -667,12 +754,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
| 667 | 754 | ||
| 668 | /* general endpoint setup */ | 755 | /* general endpoint setup */ |
| 669 | if (epnum) { | 756 | if (epnum) { |
| 670 | /* ASSERT: TXCSR_DMAENAB was already cleared */ | ||
| 671 | |||
| 672 | /* flush all old state, set default */ | 757 | /* flush all old state, set default */ |
| 673 | musb_h_tx_flush_fifo(hw_ep); | 758 | musb_h_tx_flush_fifo(hw_ep); |
| 759 | |||
| 760 | /* | ||
| 761 | * We must not clear the DMAMODE bit before or in | ||
| 762 | * the same cycle with the DMAENAB bit, so we clear | ||
| 763 | * the latter first... | ||
| 764 | */ | ||
| 674 | csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT | 765 | csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT |
| 675 | | MUSB_TXCSR_DMAMODE | 766 | | MUSB_TXCSR_AUTOSET |
| 767 | | MUSB_TXCSR_DMAENAB | ||
| 676 | | MUSB_TXCSR_FRCDATATOG | 768 | | MUSB_TXCSR_FRCDATATOG |
| 677 | | MUSB_TXCSR_H_RXSTALL | 769 | | MUSB_TXCSR_H_RXSTALL |
| 678 | | MUSB_TXCSR_H_ERROR | 770 | | MUSB_TXCSR_H_ERROR |
| @@ -680,24 +772,20 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
| 680 | ); | 772 | ); |
| 681 | csr |= MUSB_TXCSR_MODE; | 773 | csr |= MUSB_TXCSR_MODE; |
| 682 | 774 | ||
| 683 | if (usb_gettoggle(urb->dev, | 775 | if (usb_gettoggle(urb->dev, qh->epnum, 1)) |
| 684 | qh->epnum, 1)) | ||
| 685 | csr |= MUSB_TXCSR_H_WR_DATATOGGLE | 776 | csr |= MUSB_TXCSR_H_WR_DATATOGGLE |
| 686 | | MUSB_TXCSR_H_DATATOGGLE; | 777 | | MUSB_TXCSR_H_DATATOGGLE; |
| 687 | else | 778 | else |
| 688 | csr |= MUSB_TXCSR_CLRDATATOG; | 779 | csr |= MUSB_TXCSR_CLRDATATOG; |
| 689 | 780 | ||
| 690 | /* twice in case of double packet buffering */ | ||
| 691 | musb_writew(epio, MUSB_TXCSR, csr); | 781 | musb_writew(epio, MUSB_TXCSR, csr); |
| 692 | /* REVISIT may need to clear FLUSHFIFO ... */ | 782 | /* REVISIT may need to clear FLUSHFIFO ... */ |
| 783 | csr &= ~MUSB_TXCSR_DMAMODE; | ||
| 693 | musb_writew(epio, MUSB_TXCSR, csr); | 784 | musb_writew(epio, MUSB_TXCSR, csr); |
| 694 | csr = musb_readw(epio, MUSB_TXCSR); | 785 | csr = musb_readw(epio, MUSB_TXCSR); |
| 695 | } else { | 786 | } else { |
| 696 | /* endpoint 0: just flush */ | 787 | /* endpoint 0: just flush */ |
| 697 | musb_writew(epio, MUSB_CSR0, | 788 | musb_h_ep0_flush_fifo(hw_ep); |
| 698 | csr | MUSB_CSR0_FLUSHFIFO); | ||
| 699 | musb_writew(epio, MUSB_CSR0, | ||
| 700 | csr | MUSB_CSR0_FLUSHFIFO); | ||
| 701 | } | 789 | } |
| 702 | 790 | ||
| 703 | /* target addr and (for multipoint) hub addr/port */ | 791 | /* target addr and (for multipoint) hub addr/port */ |
| @@ -734,113 +822,14 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
| 734 | else | 822 | else |
| 735 | load_count = min((u32) packet_sz, len); | 823 | load_count = min((u32) packet_sz, len); |
| 736 | 824 | ||
| 737 | #ifdef CONFIG_USB_INVENTRA_DMA | 825 | if (dma_channel && musb_tx_dma_program(dma_controller, |
| 738 | if (dma_channel) { | 826 | hw_ep, qh, urb, offset, len)) |
| 739 | 827 | load_count = 0; | |
| 740 | /* clear previous state */ | ||
| 741 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 742 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
| 743 | | MUSB_TXCSR_DMAMODE | ||
| 744 | | MUSB_TXCSR_DMAENAB); | ||
| 745 | csr |= MUSB_TXCSR_MODE; | ||
| 746 | musb_writew(epio, MUSB_TXCSR, | ||
| 747 | csr | MUSB_TXCSR_MODE); | ||
| 748 | |||
| 749 | qh->segsize = min(len, dma_channel->max_len); | ||
| 750 | |||
| 751 | if (qh->segsize <= packet_sz) | ||
| 752 | dma_channel->desired_mode = 0; | ||
| 753 | else | ||
| 754 | dma_channel->desired_mode = 1; | ||
| 755 | |||
| 756 | |||
| 757 | if (dma_channel->desired_mode == 0) { | ||
| 758 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
| 759 | | MUSB_TXCSR_DMAMODE); | ||
| 760 | csr |= (MUSB_TXCSR_DMAENAB); | ||
| 761 | /* against programming guide */ | ||
| 762 | } else | ||
| 763 | csr |= (MUSB_TXCSR_AUTOSET | ||
| 764 | | MUSB_TXCSR_DMAENAB | ||
| 765 | | MUSB_TXCSR_DMAMODE); | ||
| 766 | |||
| 767 | musb_writew(epio, MUSB_TXCSR, csr); | ||
| 768 | |||
| 769 | dma_ok = dma_controller->channel_program( | ||
| 770 | dma_channel, packet_sz, | ||
| 771 | dma_channel->desired_mode, | ||
| 772 | urb->transfer_dma, | ||
| 773 | qh->segsize); | ||
| 774 | if (dma_ok) { | ||
| 775 | load_count = 0; | ||
| 776 | } else { | ||
| 777 | dma_controller->channel_release(dma_channel); | ||
| 778 | if (is_out) | ||
| 779 | hw_ep->tx_channel = NULL; | ||
| 780 | else | ||
| 781 | hw_ep->rx_channel = NULL; | ||
| 782 | dma_channel = NULL; | ||
| 783 | } | ||
| 784 | } | ||
| 785 | #endif | ||
| 786 | |||
| 787 | /* candidate for DMA */ | ||
| 788 | if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { | ||
| 789 | |||
| 790 | /* program endpoint CSRs first, then setup DMA. | ||
| 791 | * assume CPPI setup succeeds. | ||
| 792 | * defer enabling dma. | ||
| 793 | */ | ||
| 794 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 795 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
| 796 | | MUSB_TXCSR_DMAMODE | ||
| 797 | | MUSB_TXCSR_DMAENAB); | ||
| 798 | csr |= MUSB_TXCSR_MODE; | ||
| 799 | musb_writew(epio, MUSB_TXCSR, | ||
| 800 | csr | MUSB_TXCSR_MODE); | ||
| 801 | |||
| 802 | dma_channel->actual_len = 0L; | ||
| 803 | qh->segsize = len; | ||
| 804 | |||
| 805 | /* TX uses "rndis" mode automatically, but needs help | ||
| 806 | * to identify the zero-length-final-packet case. | ||
| 807 | */ | ||
| 808 | dma_ok = dma_controller->channel_program( | ||
| 809 | dma_channel, packet_sz, | ||
| 810 | (urb->transfer_flags | ||
| 811 | & URB_ZERO_PACKET) | ||
| 812 | == URB_ZERO_PACKET, | ||
| 813 | urb->transfer_dma, | ||
| 814 | qh->segsize); | ||
| 815 | if (dma_ok) { | ||
| 816 | load_count = 0; | ||
| 817 | } else { | ||
| 818 | dma_controller->channel_release(dma_channel); | ||
| 819 | hw_ep->tx_channel = NULL; | ||
| 820 | dma_channel = NULL; | ||
| 821 | |||
| 822 | /* REVISIT there's an error path here that | ||
| 823 | * needs handling: can't do dma, but | ||
| 824 | * there's no pio buffer address... | ||
| 825 | */ | ||
| 826 | } | ||
| 827 | } | ||
| 828 | 828 | ||
| 829 | if (load_count) { | 829 | if (load_count) { |
| 830 | /* ASSERT: TXCSR_DMAENAB was already cleared */ | ||
| 831 | |||
| 832 | /* PIO to load FIFO */ | 830 | /* PIO to load FIFO */ |
| 833 | qh->segsize = load_count; | 831 | qh->segsize = load_count; |
| 834 | musb_write_fifo(hw_ep, load_count, buf); | 832 | musb_write_fifo(hw_ep, load_count, buf); |
| 835 | csr = musb_readw(epio, MUSB_TXCSR); | ||
| 836 | csr &= ~(MUSB_TXCSR_DMAENAB | ||
| 837 | | MUSB_TXCSR_DMAMODE | ||
| 838 | | MUSB_TXCSR_AUTOSET); | ||
| 839 | /* write CSR */ | ||
| 840 | csr |= MUSB_TXCSR_MODE; | ||
| 841 | |||
| 842 | if (epnum) | ||
| 843 | musb_writew(epio, MUSB_TXCSR, csr); | ||
| 844 | } | 833 | } |
| 845 | 834 | ||
| 846 | /* re-enable interrupt */ | 835 | /* re-enable interrupt */ |
| @@ -895,7 +884,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
| 895 | dma_channel, packet_sz, | 884 | dma_channel, packet_sz, |
| 896 | !(urb->transfer_flags | 885 | !(urb->transfer_flags |
| 897 | & URB_SHORT_NOT_OK), | 886 | & URB_SHORT_NOT_OK), |
| 898 | urb->transfer_dma, | 887 | urb->transfer_dma + offset, |
| 899 | qh->segsize); | 888 | qh->segsize); |
| 900 | if (!dma_ok) { | 889 | if (!dma_ok) { |
| 901 | dma_controller->channel_release( | 890 | dma_controller->channel_release( |
| @@ -1063,11 +1052,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
| 1063 | csr &= ~MUSB_CSR0_H_NAKTIMEOUT; | 1052 | csr &= ~MUSB_CSR0_H_NAKTIMEOUT; |
| 1064 | musb_writew(epio, MUSB_CSR0, csr); | 1053 | musb_writew(epio, MUSB_CSR0, csr); |
| 1065 | } else { | 1054 | } else { |
| 1066 | csr |= MUSB_CSR0_FLUSHFIFO; | 1055 | musb_h_ep0_flush_fifo(hw_ep); |
| 1067 | musb_writew(epio, MUSB_CSR0, csr); | ||
| 1068 | musb_writew(epio, MUSB_CSR0, csr); | ||
| 1069 | csr &= ~MUSB_CSR0_H_NAKTIMEOUT; | ||
| 1070 | musb_writew(epio, MUSB_CSR0, csr); | ||
| 1071 | } | 1056 | } |
| 1072 | 1057 | ||
| 1073 | musb_writeb(epio, MUSB_NAKLIMIT0, 0); | 1058 | musb_writeb(epio, MUSB_NAKLIMIT0, 0); |
| @@ -1081,10 +1066,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
| 1081 | * SHOULD NEVER HAPPEN! */ | 1066 | * SHOULD NEVER HAPPEN! */ |
| 1082 | ERR("no URB for end 0\n"); | 1067 | ERR("no URB for end 0\n"); |
| 1083 | 1068 | ||
| 1084 | musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); | 1069 | musb_h_ep0_flush_fifo(hw_ep); |
| 1085 | musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); | ||
| 1086 | musb_writew(epio, MUSB_CSR0, 0); | ||
| 1087 | |||
| 1088 | goto done; | 1070 | goto done; |
| 1089 | } | 1071 | } |
| 1090 | 1072 | ||
| @@ -1145,8 +1127,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1145 | int pipe; | 1127 | int pipe; |
| 1146 | bool done = false; | 1128 | bool done = false; |
| 1147 | u16 tx_csr; | 1129 | u16 tx_csr; |
| 1148 | size_t wLength = 0; | 1130 | size_t length = 0; |
| 1149 | u8 *buf = NULL; | 1131 | size_t offset = 0; |
| 1150 | struct urb *urb; | 1132 | struct urb *urb; |
| 1151 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; | 1133 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; |
| 1152 | void __iomem *epio = hw_ep->regs; | 1134 | void __iomem *epio = hw_ep->regs; |
| @@ -1164,7 +1146,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1164 | /* with CPPI, DMA sometimes triggers "extra" irqs */ | 1146 | /* with CPPI, DMA sometimes triggers "extra" irqs */ |
| 1165 | if (!urb) { | 1147 | if (!urb) { |
| 1166 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); | 1148 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); |
| 1167 | goto finish; | 1149 | return; |
| 1168 | } | 1150 | } |
| 1169 | 1151 | ||
| 1170 | pipe = urb->pipe; | 1152 | pipe = urb->pipe; |
| @@ -1201,7 +1183,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1201 | musb_writew(epio, MUSB_TXCSR, | 1183 | musb_writew(epio, MUSB_TXCSR, |
| 1202 | MUSB_TXCSR_H_WZC_BITS | 1184 | MUSB_TXCSR_H_WZC_BITS |
| 1203 | | MUSB_TXCSR_TXPKTRDY); | 1185 | | MUSB_TXCSR_TXPKTRDY); |
| 1204 | goto finish; | 1186 | return; |
| 1205 | } | 1187 | } |
| 1206 | 1188 | ||
| 1207 | if (status) { | 1189 | if (status) { |
| @@ -1233,29 +1215,89 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1233 | /* second cppi case */ | 1215 | /* second cppi case */ |
| 1234 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1216 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
| 1235 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); | 1217 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); |
| 1236 | goto finish; | 1218 | return; |
| 1219 | } | ||
| 1220 | |||
| 1221 | if (is_dma_capable() && dma && !status) { | ||
| 1222 | /* | ||
| 1223 | * DMA has completed. But if we're using DMA mode 1 (multi | ||
| 1224 | * packet DMA), we need a terminal TXPKTRDY interrupt before | ||
| 1225 | * we can consider this transfer completed, lest we trash | ||
| 1226 | * its last packet when writing the next URB's data. So we | ||
| 1227 | * switch back to mode 0 to get that interrupt; we'll come | ||
| 1228 | * back here once it happens. | ||
| 1229 | */ | ||
| 1230 | if (tx_csr & MUSB_TXCSR_DMAMODE) { | ||
| 1231 | /* | ||
| 1232 | * We shouldn't clear DMAMODE with DMAENAB set; so | ||
| 1233 | * clear them in a safe order. That should be OK | ||
| 1234 | * once TXPKTRDY has been set (and I've never seen | ||
| 1235 | * it being 0 at this moment -- DMA interrupt latency | ||
| 1236 | * is significant) but if it hasn't been then we have | ||
| 1237 | * no choice but to stop being polite and ignore the | ||
| 1238 | * programmer's guide... :-) | ||
| 1239 | * | ||
| 1240 | * Note that we must write TXCSR with TXPKTRDY cleared | ||
| 1241 | * in order not to re-trigger the packet send (this bit | ||
| 1242 | * can't be cleared by CPU), and there's another caveat: | ||
| 1243 | * TXPKTRDY may be set shortly and then cleared in the | ||
| 1244 | * double-buffered FIFO mode, so we do an extra TXCSR | ||
| 1245 | * read for debouncing... | ||
| 1246 | */ | ||
| 1247 | tx_csr &= musb_readw(epio, MUSB_TXCSR); | ||
| 1248 | if (tx_csr & MUSB_TXCSR_TXPKTRDY) { | ||
| 1249 | tx_csr &= ~(MUSB_TXCSR_DMAENAB | | ||
| 1250 | MUSB_TXCSR_TXPKTRDY); | ||
| 1251 | musb_writew(epio, MUSB_TXCSR, | ||
| 1252 | tx_csr | MUSB_TXCSR_H_WZC_BITS); | ||
| 1253 | } | ||
| 1254 | tx_csr &= ~(MUSB_TXCSR_DMAMODE | | ||
| 1255 | MUSB_TXCSR_TXPKTRDY); | ||
| 1256 | musb_writew(epio, MUSB_TXCSR, | ||
| 1257 | tx_csr | MUSB_TXCSR_H_WZC_BITS); | ||
| 1258 | |||
| 1259 | /* | ||
| 1260 | * There is no guarantee that we'll get an interrupt | ||
| 1261 | * after clearing DMAMODE as we might have done this | ||
| 1262 | * too late (after TXPKTRDY was cleared by controller). | ||
| 1263 | * Re-read TXCSR as we have spoiled its previous value. | ||
| 1264 | */ | ||
| 1265 | tx_csr = musb_readw(epio, MUSB_TXCSR); | ||
| 1266 | } | ||
| 1237 | 1267 | ||
| 1268 | /* | ||
| 1269 | * We may get here from a DMA completion or TXPKTRDY interrupt. | ||
| 1270 | * In any case, we must check the FIFO status here and bail out | ||
| 1271 | * only if the FIFO still has data -- that should prevent the | ||
| 1272 | * "missed" TXPKTRDY interrupts and deal with double-buffered | ||
| 1273 | * FIFO mode too... | ||
| 1274 | */ | ||
| 1275 | if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) { | ||
| 1276 | DBG(2, "DMA complete but packet still in FIFO, " | ||
| 1277 | "CSR %04x\n", tx_csr); | ||
| 1278 | return; | ||
| 1279 | } | ||
| 1238 | } | 1280 | } |
| 1239 | 1281 | ||
| 1240 | /* REVISIT this looks wrong... */ | ||
| 1241 | if (!status || dma || usb_pipeisoc(pipe)) { | 1282 | if (!status || dma || usb_pipeisoc(pipe)) { |
| 1242 | if (dma) | 1283 | if (dma) |
| 1243 | wLength = dma->actual_len; | 1284 | length = dma->actual_len; |
| 1244 | else | 1285 | else |
| 1245 | wLength = qh->segsize; | 1286 | length = qh->segsize; |
| 1246 | qh->offset += wLength; | 1287 | qh->offset += length; |
| 1247 | 1288 | ||
| 1248 | if (usb_pipeisoc(pipe)) { | 1289 | if (usb_pipeisoc(pipe)) { |
| 1249 | struct usb_iso_packet_descriptor *d; | 1290 | struct usb_iso_packet_descriptor *d; |
| 1250 | 1291 | ||
| 1251 | d = urb->iso_frame_desc + qh->iso_idx; | 1292 | d = urb->iso_frame_desc + qh->iso_idx; |
| 1252 | d->actual_length = qh->segsize; | 1293 | d->actual_length = length; |
| 1294 | d->status = status; | ||
| 1253 | if (++qh->iso_idx >= urb->number_of_packets) { | 1295 | if (++qh->iso_idx >= urb->number_of_packets) { |
| 1254 | done = true; | 1296 | done = true; |
| 1255 | } else { | 1297 | } else { |
| 1256 | d++; | 1298 | d++; |
| 1257 | buf = urb->transfer_buffer + d->offset; | 1299 | offset = d->offset; |
| 1258 | wLength = d->length; | 1300 | length = d->length; |
| 1259 | } | 1301 | } |
| 1260 | } else if (dma) { | 1302 | } else if (dma) { |
| 1261 | done = true; | 1303 | done = true; |
| @@ -1268,10 +1310,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1268 | & URB_ZERO_PACKET)) | 1310 | & URB_ZERO_PACKET)) |
| 1269 | done = true; | 1311 | done = true; |
| 1270 | if (!done) { | 1312 | if (!done) { |
| 1271 | buf = urb->transfer_buffer | 1313 | offset = qh->offset; |
| 1272 | + qh->offset; | 1314 | length = urb->transfer_buffer_length - offset; |
| 1273 | wLength = urb->transfer_buffer_length | ||
| 1274 | - qh->offset; | ||
| 1275 | } | 1315 | } |
| 1276 | } | 1316 | } |
| 1277 | } | 1317 | } |
| @@ -1290,28 +1330,31 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1290 | urb->status = status; | 1330 | urb->status = status; |
| 1291 | urb->actual_length = qh->offset; | 1331 | urb->actual_length = qh->offset; |
| 1292 | musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); | 1332 | musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); |
| 1333 | return; | ||
| 1334 | } else if (usb_pipeisoc(pipe) && dma) { | ||
| 1335 | if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, | ||
| 1336 | offset, length)) | ||
| 1337 | return; | ||
| 1338 | } else if (tx_csr & MUSB_TXCSR_DMAENAB) { | ||
| 1339 | DBG(1, "not complete, but DMA enabled?\n"); | ||
| 1340 | return; | ||
| 1341 | } | ||
| 1293 | 1342 | ||
| 1294 | } else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) { | 1343 | /* |
| 1295 | /* WARN_ON(!buf); */ | 1344 | * PIO: start next packet in this URB. |
| 1296 | 1345 | * | |
| 1297 | /* REVISIT: some docs say that when hw_ep->tx_double_buffered, | 1346 | * REVISIT: some docs say that when hw_ep->tx_double_buffered, |
| 1298 | * (and presumably, fifo is not half-full) we should write TWO | 1347 | * (and presumably, FIFO is not half-full) we should write *two* |
| 1299 | * packets before updating TXCSR ... other docs disagree ... | 1348 | * packets before updating TXCSR; other docs disagree... |
| 1300 | */ | 1349 | */ |
| 1301 | /* PIO: start next packet in this URB */ | 1350 | if (length > qh->maxpacket) |
| 1302 | if (wLength > qh->maxpacket) | 1351 | length = qh->maxpacket; |
| 1303 | wLength = qh->maxpacket; | 1352 | musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset); |
| 1304 | musb_write_fifo(hw_ep, wLength, buf); | 1353 | qh->segsize = length; |
| 1305 | qh->segsize = wLength; | ||
| 1306 | |||
| 1307 | musb_ep_select(mbase, epnum); | ||
| 1308 | musb_writew(epio, MUSB_TXCSR, | ||
| 1309 | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); | ||
| 1310 | } else | ||
| 1311 | DBG(1, "not complete, but dma enabled?\n"); | ||
| 1312 | 1354 | ||
| 1313 | finish: | 1355 | musb_ep_select(mbase, epnum); |
| 1314 | return; | 1356 | musb_writew(epio, MUSB_TXCSR, |
| 1357 | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); | ||
| 1315 | } | 1358 | } |
| 1316 | 1359 | ||
| 1317 | 1360 | ||
| @@ -1841,7 +1884,7 @@ static int musb_urb_enqueue( | |||
| 1841 | unsigned long flags; | 1884 | unsigned long flags; |
| 1842 | struct musb *musb = hcd_to_musb(hcd); | 1885 | struct musb *musb = hcd_to_musb(hcd); |
| 1843 | struct usb_host_endpoint *hep = urb->ep; | 1886 | struct usb_host_endpoint *hep = urb->ep; |
| 1844 | struct musb_qh *qh = hep->hcpriv; | 1887 | struct musb_qh *qh; |
| 1845 | struct usb_endpoint_descriptor *epd = &hep->desc; | 1888 | struct usb_endpoint_descriptor *epd = &hep->desc; |
| 1846 | int ret; | 1889 | int ret; |
| 1847 | unsigned type_reg; | 1890 | unsigned type_reg; |
| @@ -1853,22 +1896,21 @@ static int musb_urb_enqueue( | |||
| 1853 | 1896 | ||
| 1854 | spin_lock_irqsave(&musb->lock, flags); | 1897 | spin_lock_irqsave(&musb->lock, flags); |
| 1855 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 1898 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
| 1899 | qh = ret ? NULL : hep->hcpriv; | ||
| 1900 | if (qh) | ||
| 1901 | urb->hcpriv = qh; | ||
| 1856 | spin_unlock_irqrestore(&musb->lock, flags); | 1902 | spin_unlock_irqrestore(&musb->lock, flags); |
| 1857 | if (ret) | ||
| 1858 | return ret; | ||
| 1859 | 1903 | ||
| 1860 | /* DMA mapping was already done, if needed, and this urb is on | 1904 | /* DMA mapping was already done, if needed, and this urb is on |
| 1861 | * hep->urb_list ... so there's little to do unless hep wasn't | 1905 | * hep->urb_list now ... so we're done, unless hep wasn't yet |
| 1862 | * yet scheduled onto a live qh. | 1906 | * scheduled onto a live qh. |
| 1863 | * | 1907 | * |
| 1864 | * REVISIT best to keep hep->hcpriv valid until the endpoint gets | 1908 | * REVISIT best to keep hep->hcpriv valid until the endpoint gets |
| 1865 | * disabled, testing for empty qh->ring and avoiding qh setup costs | 1909 | * disabled, testing for empty qh->ring and avoiding qh setup costs |
| 1866 | * except for the first urb queued after a config change. | 1910 | * except for the first urb queued after a config change. |
| 1867 | */ | 1911 | */ |
| 1868 | if (qh) { | 1912 | if (qh || ret) |
| 1869 | urb->hcpriv = qh; | 1913 | return ret; |
| 1870 | return 0; | ||
| 1871 | } | ||
| 1872 | 1914 | ||
| 1873 | /* Allocate and initialize qh, minimizing the work done each time | 1915 | /* Allocate and initialize qh, minimizing the work done each time |
| 1874 | * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. | 1916 | * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. |
| @@ -2044,7 +2086,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) | |||
| 2044 | * endpoint's irq status here to avoid bogus irqs. | 2086 | * endpoint's irq status here to avoid bogus irqs. |
| 2045 | * clearing that status is platform-specific... | 2087 | * clearing that status is platform-specific... |
| 2046 | */ | 2088 | */ |
| 2047 | } else { | 2089 | } else if (ep->epnum) { |
| 2048 | musb_h_tx_flush_fifo(ep); | 2090 | musb_h_tx_flush_fifo(ep); |
| 2049 | csr = musb_readw(epio, MUSB_TXCSR); | 2091 | csr = musb_readw(epio, MUSB_TXCSR); |
| 2050 | csr &= ~(MUSB_TXCSR_AUTOSET | 2092 | csr &= ~(MUSB_TXCSR_AUTOSET |
| @@ -2058,6 +2100,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) | |||
| 2058 | musb_writew(epio, MUSB_TXCSR, csr); | 2100 | musb_writew(epio, MUSB_TXCSR, csr); |
| 2059 | /* flush cpu writebuffer */ | 2101 | /* flush cpu writebuffer */ |
| 2060 | csr = musb_readw(epio, MUSB_TXCSR); | 2102 | csr = musb_readw(epio, MUSB_TXCSR); |
| 2103 | } else { | ||
| 2104 | musb_h_ep0_flush_fifo(ep); | ||
| 2061 | } | 2105 | } |
| 2062 | if (status == 0) | 2106 | if (status == 0) |
| 2063 | musb_advance_schedule(ep->musb, urb, ep, is_in); | 2107 | musb_advance_schedule(ep->musb, urb, ep, is_in); |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 8662e9e159c3..5e83f96d6b77 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
| @@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel) | |||
| 195 | void __iomem *mbase = musb_channel->controller->base; | 195 | void __iomem *mbase = musb_channel->controller->base; |
| 196 | 196 | ||
| 197 | u8 bchannel = musb_channel->idx; | 197 | u8 bchannel = musb_channel->idx; |
| 198 | int offset; | ||
| 198 | u16 csr; | 199 | u16 csr; |
| 199 | 200 | ||
| 200 | if (channel->status == MUSB_DMA_STATUS_BUSY) { | 201 | if (channel->status == MUSB_DMA_STATUS_BUSY) { |
| 201 | if (musb_channel->transmit) { | 202 | if (musb_channel->transmit) { |
| 202 | 203 | offset = MUSB_EP_OFFSET(musb_channel->epnum, | |
| 203 | csr = musb_readw(mbase, | 204 | MUSB_TXCSR); |
| 204 | MUSB_EP_OFFSET(musb_channel->epnum, | 205 | |
| 205 | MUSB_TXCSR)); | 206 | /* |
| 206 | csr &= ~(MUSB_TXCSR_AUTOSET | | 207 | * The programming guide says that we must clear |
| 207 | MUSB_TXCSR_DMAENAB | | 208 | * the DMAENAB bit before the DMAMODE bit... |
| 208 | MUSB_TXCSR_DMAMODE); | 209 | */ |
| 209 | musb_writew(mbase, | 210 | csr = musb_readw(mbase, offset); |
| 210 | MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR), | 211 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB); |
| 211 | csr); | 212 | musb_writew(mbase, offset, csr); |
| 213 | csr &= ~MUSB_TXCSR_DMAMODE; | ||
| 214 | musb_writew(mbase, offset, csr); | ||
| 212 | } else { | 215 | } else { |
| 213 | csr = musb_readw(mbase, | 216 | offset = MUSB_EP_OFFSET(musb_channel->epnum, |
| 214 | MUSB_EP_OFFSET(musb_channel->epnum, | 217 | MUSB_RXCSR); |
| 215 | MUSB_RXCSR)); | 218 | |
| 219 | csr = musb_readw(mbase, offset); | ||
| 216 | csr &= ~(MUSB_RXCSR_AUTOCLEAR | | 220 | csr &= ~(MUSB_RXCSR_AUTOCLEAR | |
| 217 | MUSB_RXCSR_DMAENAB | | 221 | MUSB_RXCSR_DMAENAB | |
| 218 | MUSB_RXCSR_DMAMODE); | 222 | MUSB_RXCSR_DMAMODE); |
| 219 | musb_writew(mbase, | 223 | musb_writew(mbase, offset, csr); |
| 220 | MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR), | ||
| 221 | csr); | ||
| 222 | } | 224 | } |
| 223 | 225 | ||
| 224 | musb_writew(mbase, | 226 | musb_writew(mbase, |
| @@ -296,20 +298,28 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
| 296 | && ((channel->desired_mode == 0) | 298 | && ((channel->desired_mode == 0) |
| 297 | || (channel->actual_len & | 299 | || (channel->actual_len & |
| 298 | (musb_channel->max_packet_sz - 1))) | 300 | (musb_channel->max_packet_sz - 1))) |
| 299 | ) { | 301 | ) { |
| 302 | u8 epnum = musb_channel->epnum; | ||
| 303 | int offset = MUSB_EP_OFFSET(epnum, | ||
| 304 | MUSB_TXCSR); | ||
| 305 | u16 txcsr; | ||
| 306 | |||
| 307 | /* | ||
| 308 | * The programming guide says that we | ||
| 309 | * must clear DMAENAB before DMAMODE. | ||
| 310 | */ | ||
| 311 | musb_ep_select(mbase, epnum); | ||
| 312 | txcsr = musb_readw(mbase, offset); | ||
| 313 | txcsr &= ~(MUSB_TXCSR_DMAENAB | ||
| 314 | | MUSB_TXCSR_AUTOSET); | ||
| 315 | musb_writew(mbase, offset, txcsr); | ||
| 300 | /* Send out the packet */ | 316 | /* Send out the packet */ |
| 301 | musb_ep_select(mbase, | 317 | txcsr &= ~MUSB_TXCSR_DMAMODE; |
| 302 | musb_channel->epnum); | 318 | txcsr |= MUSB_TXCSR_TXPKTRDY; |
| 303 | musb_writew(mbase, MUSB_EP_OFFSET( | 319 | musb_writew(mbase, offset, txcsr); |
| 304 | musb_channel->epnum, | ||
| 305 | MUSB_TXCSR), | ||
| 306 | MUSB_TXCSR_TXPKTRDY); | ||
| 307 | } else { | ||
| 308 | musb_dma_completion( | ||
| 309 | musb, | ||
| 310 | musb_channel->epnum, | ||
| 311 | musb_channel->transmit); | ||
| 312 | } | 320 | } |
| 321 | musb_dma_completion(musb, musb_channel->epnum, | ||
| 322 | musb_channel->transmit); | ||
| 313 | } | 323 | } |
| 314 | } | 324 | } |
| 315 | } | 325 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dcc87aaa8628..8100f1d25904 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -668,6 +668,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 668 | { USB_DEVICE(DE_VID, WHT_PID) }, | 668 | { USB_DEVICE(DE_VID, WHT_PID) }, |
| 669 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), | 669 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), |
| 670 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 670 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 671 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | ||
| 671 | { }, /* Optional parameter entry */ | 672 | { }, /* Optional parameter entry */ |
| 672 | { } /* Terminating entry */ | 673 | { } /* Terminating entry */ |
| 673 | }; | 674 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index daaf63db0b50..c09f658a448b 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -913,6 +913,13 @@ | |||
| 913 | #define ADI_GNICE_PID 0xF000 | 913 | #define ADI_GNICE_PID 0xF000 |
| 914 | 914 | ||
| 915 | /* | 915 | /* |
| 916 | * JETI SPECTROMETER SPECBOS 1201 | ||
| 917 | * http://www.jeti.com/products/sys/scb/scb1201.php | ||
| 918 | */ | ||
| 919 | #define JETI_VID 0x0c6c | ||
| 920 | #define JETI_SPC1201_PID 0x04b2 | ||
| 921 | |||
| 922 | /* | ||
| 916 | * BmRequestType: 1100 0000b | 923 | * BmRequestType: 1100 0000b |
| 917 | * bRequest: FTDI_E2_READ | 924 | * bRequest: FTDI_E2_READ |
| 918 | * wValue: 0 | 925 | * wValue: 0 |
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c index 2e8e05462ef7..b66b71ccd12b 100644 --- a/drivers/usb/serial/moto_modem.c +++ b/drivers/usb/serial/moto_modem.c | |||
| @@ -25,6 +25,7 @@ static struct usb_device_id id_table [] = { | |||
| 25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ | 25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ |
| 26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ | 26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ |
| 27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ | 27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ |
| 28 | { USB_DEVICE(0x22b8, 0x2c64) }, /* Motorola V950 phone */ | ||
| 28 | { }, | 29 | { }, |
| 29 | }; | 30 | }; |
| 30 | MODULE_DEVICE_TABLE(usb, id_table); | 31 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d560c0b54e6e..47bd070f24b7 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -300,6 +300,10 @@ static int option_resume(struct usb_serial *serial); | |||
| 300 | #define BENQ_VENDOR_ID 0x04a5 | 300 | #define BENQ_VENDOR_ID 0x04a5 |
| 301 | #define BENQ_PRODUCT_H10 0x4068 | 301 | #define BENQ_PRODUCT_H10 0x4068 |
| 302 | 302 | ||
| 303 | #define DLINK_VENDOR_ID 0x1186 | ||
| 304 | #define DLINK_PRODUCT_DWM_652 0x3e04 | ||
| 305 | |||
| 306 | |||
| 303 | static struct usb_device_id option_ids[] = { | 307 | static struct usb_device_id option_ids[] = { |
| 304 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 308 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 305 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 309 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -516,6 +520,7 @@ static struct usb_device_id option_ids[] = { | |||
| 516 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, | 520 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, |
| 517 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 521 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, |
| 518 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 522 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
| 523 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | ||
| 519 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | 524 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ |
| 520 | { } /* Terminating entry */ | 525 | { } /* Terminating entry */ |
| 521 | }; | 526 | }; |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index e6d6b0c17fd9..7528b8d57f1c 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
| @@ -26,6 +26,27 @@ static struct usb_device_id id_table[] = { | |||
| 26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
| 27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
| 28 | {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ | 28 | {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ |
| 29 | {USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | ||
| 30 | {USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ | ||
| 31 | {USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | ||
| 32 | {USB_DEVICE(0x413c, 0x8171)}, /* Dell Gobi QDL device */ | ||
| 33 | {USB_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | ||
| 34 | {USB_DEVICE(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ | ||
| 35 | {USB_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ | ||
| 36 | {USB_DEVICE(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ | ||
| 37 | {USB_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ | ||
| 38 | {USB_DEVICE(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */ | ||
| 39 | {USB_DEVICE(0x1557, 0x0a80)}, /* OQO Gobi QDL device */ | ||
| 40 | {USB_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ | ||
| 41 | {USB_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ | ||
| 42 | {USB_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ | ||
| 43 | {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ | ||
| 44 | {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ | ||
| 45 | {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ | ||
| 46 | {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ | ||
| 47 | {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ | ||
| 48 | {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ | ||
| 49 | {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ | ||
| 29 | { } /* Terminating entry */ | 50 | { } /* Terminating entry */ |
| 30 | }; | 51 | }; |
| 31 | MODULE_DEVICE_TABLE(usb, id_table); | 52 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 5be54c019662..ef7e5a8ceab5 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
| @@ -17,7 +17,8 @@ usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | |||
| 17 | ifeq ($(CONFIG_USB_LIBUSUAL),) | 17 | ifeq ($(CONFIG_USB_LIBUSUAL),) |
| 18 | usb-storage-objs += usual-tables.o | 18 | usb-storage-objs += usual-tables.o |
| 19 | else | 19 | else |
| 20 | obj-$(CONFIG_USB) += libusual.o usual-tables.o | 20 | obj-$(CONFIG_USB) += usb-libusual.o |
| 21 | usb-libusual-objs := libusual.o usual-tables.o | ||
| 21 | endif | 22 | endif |
| 22 | 23 | ||
| 23 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o | 24 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o |
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 49aedb36dc19..fcb320217218 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
| @@ -247,10 +247,8 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) | |||
| 247 | USB_ENDPOINT_HALT, endp, | 247 | USB_ENDPOINT_HALT, endp, |
| 248 | NULL, 0, 3*HZ); | 248 | NULL, 0, 3*HZ); |
| 249 | 249 | ||
| 250 | /* reset the endpoint toggle */ | ||
| 251 | if (result >= 0) | 250 | if (result >= 0) |
| 252 | usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), | 251 | usb_reset_endpoint(us->pusb_dev, endp); |
| 253 | usb_pipeout(pipe), 0); | ||
| 254 | 252 | ||
| 255 | US_DEBUGP("%s: result = %d\n", __func__, result); | 253 | US_DEBUGP("%s: result = %d\n", __func__, result); |
| 256 | return result; | 254 | return result; |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1c1f643e8a78..96db479d1165 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -975,12 +975,14 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, | |||
| 975 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 975 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 976 | US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), | 976 | US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), |
| 977 | 977 | ||
| 978 | /* Reported by Rauch Wolke <rauchwolke@gmx.net> */ | 978 | /* Reported by Rauch Wolke <rauchwolke@gmx.net> |
| 979 | * and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882) | ||
| 980 | */ | ||
| 979 | UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, | 981 | UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, |
| 980 | "Simple Tech/Datafab", | 982 | "Simple Tech/Datafab", |
| 981 | "CF+SM Reader", | 983 | "CF+SM Reader", |
| 982 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 984 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 983 | US_FL_IGNORE_RESIDUE ), | 985 | US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ), |
| 984 | 986 | ||
| 985 | /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant | 987 | /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant |
| 986 | * to the USB storage specification in two ways: | 988 | * to the USB storage specification in two ways: |
| @@ -1376,6 +1378,14 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, | |||
| 1376 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1378 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 1377 | 0), | 1379 | 0), |
| 1378 | 1380 | ||
| 1381 | /* Reported by Pascal Terjan <pterjan@mandriva.com> | ||
| 1382 | * Ignore driver CD mode and force into modem mode by default. | ||
| 1383 | */ | ||
| 1384 | UNUSUAL_DEV( 0x1186, 0x3e04, 0x0000, 0x0000, | ||
| 1385 | "D-Link", | ||
| 1386 | "USB Mass Storage", | ||
| 1387 | US_SC_DEVICE, US_PR_DEVICE, option_ms_init, 0), | ||
| 1388 | |||
| 1379 | /* Reported by Kevin Lloyd <linux@sierrawireless.com> | 1389 | /* Reported by Kevin Lloyd <linux@sierrawireless.com> |
| 1380 | * Entry is needed for the initializer function override, | 1390 | * Entry is needed for the initializer function override, |
| 1381 | * which instructs the device to load as a modem | 1391 | * which instructs the device to load as a modem |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 386eaa22d215..4ac4300a3f9a 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
| @@ -267,6 +267,8 @@ static void wusbhc_devconnect_acked_work(struct work_struct *work) | |||
| 267 | mutex_lock(&wusbhc->mutex); | 267 | mutex_lock(&wusbhc->mutex); |
| 268 | wusbhc_devconnect_acked(wusbhc, wusb_dev); | 268 | wusbhc_devconnect_acked(wusbhc, wusb_dev); |
| 269 | mutex_unlock(&wusbhc->mutex); | 269 | mutex_unlock(&wusbhc->mutex); |
| 270 | |||
| 271 | wusb_dev_put(wusb_dev); | ||
| 270 | } | 272 | } |
| 271 | 273 | ||
| 272 | /* | 274 | /* |
| @@ -396,7 +398,8 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
| 396 | 398 | ||
| 397 | /* After a device disconnects, change the GTK (see [WUSB] | 399 | /* After a device disconnects, change the GTK (see [WUSB] |
| 398 | * section 6.2.11.2). */ | 400 | * section 6.2.11.2). */ |
| 399 | wusbhc_gtk_rekey(wusbhc); | 401 | if (wusbhc->active) |
| 402 | wusbhc_gtk_rekey(wusbhc); | ||
| 400 | 403 | ||
| 401 | /* The Wireless USB part has forgotten about the device already; now | 404 | /* The Wireless USB part has forgotten about the device already; now |
| 402 | * khubd's timer will pick up the disconnection and remove the USB | 405 | * khubd's timer will pick up the disconnection and remove the USB |
| @@ -1084,15 +1087,21 @@ error_mmcie_set: | |||
| 1084 | * wusbhc_devconnect_stop - stop managing connected devices | 1087 | * wusbhc_devconnect_stop - stop managing connected devices |
| 1085 | * @wusbhc: the WUSB HC | 1088 | * @wusbhc: the WUSB HC |
| 1086 | * | 1089 | * |
| 1087 | * Removes the Host Info IE and stops the keep alives. | 1090 | * Disconnects any devices still connected, stops the keep alives and |
| 1088 | * | 1091 | * removes the Host Info IE. |
| 1089 | * FIXME: should this disconnect all devices? | ||
| 1090 | */ | 1092 | */ |
| 1091 | void wusbhc_devconnect_stop(struct wusbhc *wusbhc) | 1093 | void wusbhc_devconnect_stop(struct wusbhc *wusbhc) |
| 1092 | { | 1094 | { |
| 1093 | cancel_delayed_work_sync(&wusbhc->keep_alive_timer); | 1095 | int i; |
| 1094 | WARN_ON(!list_empty(&wusbhc->cack_list)); | ||
| 1095 | 1096 | ||
| 1097 | mutex_lock(&wusbhc->mutex); | ||
| 1098 | for (i = 0; i < wusbhc->ports_max; i++) { | ||
| 1099 | if (wusbhc->port[i].wusb_dev) | ||
| 1100 | __wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]); | ||
| 1101 | } | ||
| 1102 | mutex_unlock(&wusbhc->mutex); | ||
| 1103 | |||
| 1104 | cancel_delayed_work_sync(&wusbhc->keep_alive_timer); | ||
| 1096 | wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr); | 1105 | wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr); |
| 1097 | kfree(wusbhc->wuie_host_info); | 1106 | kfree(wusbhc->wuie_host_info); |
| 1098 | wusbhc->wuie_host_info = NULL; | 1107 | wusbhc->wuie_host_info = NULL; |
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index 07c63a31c799..ee6256f23636 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c | |||
| @@ -88,33 +88,31 @@ static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show, | |||
| 88 | wusb_trust_timeout_store); | 88 | wusb_trust_timeout_store); |
| 89 | 89 | ||
| 90 | /* | 90 | /* |
| 91 | * Show & store the current WUSB CHID | 91 | * Show the current WUSB CHID. |
| 92 | */ | 92 | */ |
| 93 | static ssize_t wusb_chid_show(struct device *dev, | 93 | static ssize_t wusb_chid_show(struct device *dev, |
| 94 | struct device_attribute *attr, char *buf) | 94 | struct device_attribute *attr, char *buf) |
| 95 | { | 95 | { |
| 96 | struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); | 96 | struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); |
| 97 | const struct wusb_ckhdid *chid; | ||
| 97 | ssize_t result = 0; | 98 | ssize_t result = 0; |
| 98 | 99 | ||
| 99 | if (wusbhc->wuie_host_info != NULL) | 100 | if (wusbhc->wuie_host_info != NULL) |
| 100 | result += ckhdid_printf(buf, PAGE_SIZE, | 101 | chid = &wusbhc->wuie_host_info->CHID; |
| 101 | &wusbhc->wuie_host_info->CHID); | 102 | else |
| 103 | chid = &wusb_ckhdid_zero; | ||
| 104 | |||
| 105 | result += ckhdid_printf(buf, PAGE_SIZE, chid); | ||
| 106 | result += sprintf(buf + result, "\n"); | ||
| 107 | |||
| 102 | return result; | 108 | return result; |
| 103 | } | 109 | } |
| 104 | 110 | ||
| 105 | /* | 111 | /* |
| 106 | * Store a new CHID | 112 | * Store a new CHID. |
| 107 | * | ||
| 108 | * This will (FIXME) trigger many changes. | ||
| 109 | * | ||
| 110 | * - Send an all zeros CHID and it will stop the controller | ||
| 111 | * - Send a non-zero CHID and it will start it | ||
| 112 | * (unless it was started, it will just change the CHID, | ||
| 113 | * diconnecting all devices first). | ||
| 114 | * | 113 | * |
| 115 | * So first we scan the MMC we are sent and then we act on it. We | 114 | * - Write an all zeros CHID and it will stop the controller |
| 116 | * read it in the same format as we print it, an ASCII string of 16 | 115 | * - Write a non-zero CHID and it will start it. |
| 117 | * hex bytes. | ||
| 118 | * | 116 | * |
| 119 | * See wusbhc_chid_set() for more info. | 117 | * See wusbhc_chid_set() for more info. |
| 120 | */ | 118 | */ |
| @@ -339,13 +337,15 @@ void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status) | |||
| 339 | { | 337 | { |
| 340 | struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); | 338 | struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); |
| 341 | 339 | ||
| 342 | if (status == 0) { | 340 | if (status == 0 && wusb_dev) { |
| 343 | wusb_dev->entry_ts = jiffies; | 341 | wusb_dev->entry_ts = jiffies; |
| 344 | 342 | ||
| 345 | /* wusbhc_devconnect_acked() can't be called from from | 343 | /* wusbhc_devconnect_acked() can't be called from |
| 346 | atomic context so defer it to a work queue. */ | 344 | atomic context so defer it to a work queue. */ |
| 347 | if (!list_empty(&wusb_dev->cack_node)) | 345 | if (!list_empty(&wusb_dev->cack_node)) |
| 348 | queue_work(wusbd, &wusb_dev->devconnect_acked_work); | 346 | queue_work(wusbd, &wusb_dev->devconnect_acked_work); |
| 347 | else | ||
| 348 | wusb_dev_put(wusb_dev); | ||
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status); | 351 | usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status); |
diff --git a/include/linux/usb.h b/include/linux/usb.h index c6b2ab41b908..3aa2cd1f8d08 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
| @@ -1387,6 +1387,7 @@ extern int usb_string(struct usb_device *dev, int index, | |||
| 1387 | extern int usb_clear_halt(struct usb_device *dev, int pipe); | 1387 | extern int usb_clear_halt(struct usb_device *dev, int pipe); |
| 1388 | extern int usb_reset_configuration(struct usb_device *dev); | 1388 | extern int usb_reset_configuration(struct usb_device *dev); |
| 1389 | extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); | 1389 | extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); |
| 1390 | extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr); | ||
| 1390 | 1391 | ||
| 1391 | /* this request isn't really synchronous, but it belongs with the others */ | 1392 | /* this request isn't really synchronous, but it belongs with the others */ |
| 1392 | extern int usb_driver_set_configuration(struct usb_device *udev, int config); | 1393 | extern int usb_driver_set_configuration(struct usb_device *udev, int config); |
| @@ -1491,14 +1492,6 @@ void usb_sg_wait(struct usb_sg_request *io); | |||
| 1491 | #define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL) | 1492 | #define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL) |
| 1492 | #define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK) | 1493 | #define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK) |
| 1493 | 1494 | ||
| 1494 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ | ||
| 1495 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) | ||
| 1496 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) | ||
| 1497 | #define usb_settoggle(dev, ep, out, bit) \ | ||
| 1498 | ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ | ||
| 1499 | ((bit) << (ep))) | ||
| 1500 | |||
| 1501 | |||
| 1502 | static inline unsigned int __create_pipe(struct usb_device *dev, | 1495 | static inline unsigned int __create_pipe(struct usb_device *dev, |
| 1503 | unsigned int endpoint) | 1496 | unsigned int endpoint) |
| 1504 | { | 1497 | { |
