|
@@ -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);
|
|
|
}
|