summaryrefslogtreecommitdiff
path: root/drivers/usb/wusbcore/wa-xfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/wusbcore/wa-xfer.c')
-rw-r--r--drivers/usb/wusbcore/wa-xfer.c83
1 files changed, 49 insertions, 34 deletions
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
index cf7c95ceebe0..52c7259705e6 100644
--- a/drivers/usb/wusbcore/wa-xfer.c
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -2741,41 +2741,15 @@ out:
}
/*
- * Transfer complete notification
- *
- * Called from the notif.c code. We get a notification on EP2 saying
- * that some endpoint has some transfer result data available. We are
- * about to read it.
- *
- * To speed up things, we always have a URB reading the DTI URB; we
- * don't really set it up and start it until the first xfer complete
- * notification arrives, which is what we do here.
- *
- * Follow up in wa_dti_cb(), as that's where the whole state
- * machine starts.
- *
- * So here we just initialize the DTI URB for reading transfer result
- * notifications and also the buffer-in URB, for reading buffers. Then
- * we just submit the DTI URB.
- *
- * @wa shall be referenced
+ * Initialize the DTI URB for reading transfer result notifications and also
+ * the buffer-in URB, for reading buffers. Then we just submit the DTI URB.
*/
-void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
+int wa_dti_start(struct wahc *wa)
{
- int result;
- struct device *dev = &wa->usb_iface->dev;
- struct wa_notif_xfer *notif_xfer;
const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;
+ struct device *dev = &wa->usb_iface->dev;
+ int result = -ENOMEM;
- notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr);
- BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER);
-
- if ((0x80 | notif_xfer->bEndpoint) != dti_epd->bEndpointAddress) {
- /* FIXME: hardcoded limitation, adapt */
- dev_err(dev, "BUG: DTI ep is %u, not %u (hack me)\n",
- notif_xfer->bEndpoint, dti_epd->bEndpointAddress);
- goto error;
- }
if (wa->dti_urb != NULL) /* DTI URB already started */
goto out;
@@ -2786,7 +2760,7 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
}
usb_fill_bulk_urb(
wa->dti_urb, wa->usb_dev,
- usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
+ usb_rcvbulkpipe(wa->usb_dev, 0x80 | dti_epd->bEndpointAddress),
wa->dti_buf, wa->dti_buf_size,
wa_dti_cb, wa);
@@ -2797,7 +2771,7 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
}
usb_fill_bulk_urb(
wa->buf_in_urb, wa->usb_dev,
- usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
+ usb_rcvbulkpipe(wa->usb_dev, 0x80 | dti_epd->bEndpointAddress),
NULL, 0, wa_buf_in_cb, wa);
result = usb_submit_urb(wa->dti_urb, GFP_KERNEL);
if (result < 0) {
@@ -2806,7 +2780,7 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
goto error_dti_urb_submit;
}
out:
- return;
+ return 0;
error_dti_urb_submit:
usb_put_urb(wa->buf_in_urb);
@@ -2815,6 +2789,47 @@ error_buf_in_urb_alloc:
usb_put_urb(wa->dti_urb);
wa->dti_urb = NULL;
error_dti_urb_alloc:
+ return result;
+}
+EXPORT_SYMBOL_GPL(wa_dti_start);
+/*
+ * Transfer complete notification
+ *
+ * Called from the notif.c code. We get a notification on EP2 saying
+ * that some endpoint has some transfer result data available. We are
+ * about to read it.
+ *
+ * To speed up things, we always have a URB reading the DTI URB; we
+ * don't really set it up and start it until the first xfer complete
+ * notification arrives, which is what we do here.
+ *
+ * Follow up in wa_dti_cb(), as that's where the whole state
+ * machine starts.
+ *
+ * @wa shall be referenced
+ */
+void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
+{
+ struct device *dev = &wa->usb_iface->dev;
+ struct wa_notif_xfer *notif_xfer;
+ const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;
+
+ notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr);
+ BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER);
+
+ if ((0x80 | notif_xfer->bEndpoint) != dti_epd->bEndpointAddress) {
+ /* FIXME: hardcoded limitation, adapt */
+ dev_err(dev, "BUG: DTI ep is %u, not %u (hack me)\n",
+ notif_xfer->bEndpoint, dti_epd->bEndpointAddress);
+ goto error;
+ }
+
+ /* attempt to start the DTI ep processing. */
+ if (wa_dti_start(wa) < 0)
+ goto error;
+
+ return;
+
error:
wa_reset_all(wa);
}