[xdc] Use internal complete_cb.

With usb request having private regions for each layer in the stack,
the complete callback and their contexts should not be part of the public
part of the usb-request. This changeset makes xdc use its internal
contex to save and retreive the complete_cb.

Test: zircon build

Change-Id: Ie8506968ccc73701a2bbd35b5498a513efaa8c38
diff --git a/system/dev/usb/xhci/xdc-transfer.cpp b/system/dev/usb/xhci/xdc-transfer.cpp
index e782949..7382f4e 100644
--- a/system/dev/usb/xhci/xdc-transfer.cpp
+++ b/system/dev/usb/xhci/xdc-transfer.cpp
@@ -117,8 +117,11 @@
         }
     }
 
-    zx_status_t status = xdc_req_list_add_tail(&ep->queued_reqs, req, sizeof(usb_request_t));
-    ZX_DEBUG_ASSERT(status == ZX_OK);
+    xdc_req_internal_t* req_int = USB_REQ_TO_XDC_INTERNAL(req, sizeof(usb_request_t));
+    req_int->complete_cb = in ? xdc_read_complete : xdc_write_complete;
+    req_int->cookie = xdc;
+
+    list_add_tail(&ep->queued_reqs, &req_int->node);
 
     // We can still queue requests for later while waiting for the xdc device to be configured,
     // or while the endpoint is halted. Before scheduling the TRBs however, we should wait
diff --git a/system/dev/usb/xhci/xdc.cpp b/system/dev/usb/xhci/xdc.cpp
index 1943807..077cd0e 100644
--- a/system/dev/usb/xhci/xdc.cpp
+++ b/system/dev/usb/xhci/xdc.cpp
@@ -650,11 +650,18 @@
         ep->state = XDC_EP_STATE_DEAD;
 
         usb_request_t* req;
-        while ((req = xdc_req_list_remove_tail(&ep->pending_reqs, usb_req_size)) != nullptr) {
-            usb_request_complete(req, ZX_ERR_IO_NOT_PRESENT, 0, req->complete_cb, req->cookie);
+        xdc_req_internal_t* req_int;
+        while ((req_int = list_remove_tail_type(&ep->pending_reqs, xdc_req_internal_t, node))
+                                                                                  != nullptr) {
+            req = XDC_INTERNAL_TO_USB_REQ(req_int, usb_req_size);
+            usb_request_complete(req, ZX_ERR_IO_NOT_PRESENT, 0, req_int->complete_cb,
+                                 req_int->cookie);
         }
-        while ((req = xdc_req_list_remove_tail(&ep->queued_reqs, usb_req_size)) != nullptr) {
-            usb_request_complete(req, ZX_ERR_IO_NOT_PRESENT, 0, req->complete_cb, req->cookie);
+        while ((req_int = list_remove_tail_type(&ep->queued_reqs, xdc_req_internal_t, node))
+                                                                                  != nullptr) {
+            req = XDC_INTERNAL_TO_USB_REQ(req_int, usb_req_size);
+            usb_request_complete(req, ZX_ERR_IO_NOT_PRESENT, 0, req_int->complete_cb,
+                                 req_int->cookie);
         }
     }
 
@@ -740,7 +747,7 @@
     mtx_unlock(&xdc->instance_list_lock);
 }
 
-static void xdc_write_complete(usb_request_t* req, void* cookie) {
+void xdc_write_complete(usb_request_t* req, void* cookie) {
     auto* xdc = static_cast<xdc_t*>(cookie);
 
     zx_status_t status = req->response.status;
@@ -781,8 +788,6 @@
         if (status != ZX_OK) {
             goto out;
         }
-        req->complete_cb = xdc_write_complete;
-        req->cookie = xdc;
     }
 
     usb_request_copy_to(req, &header, header_len, 0);
@@ -864,7 +869,7 @@
     }
 }
 
-static void xdc_read_complete(usb_request_t* req, void* cookie) {
+void xdc_read_complete(usb_request_t* req, void* cookie) {
     auto* xdc = static_cast<xdc_t*>(cookie);
 
     mtx_lock(&xdc->read_lock);
@@ -1215,11 +1220,13 @@
 
             // Call complete callbacks out of the lock.
             // TODO(jocelyndang): might want a separate thread for this.
+            xdc_req_internal_t* req_int;
             usb_request_t* req;
-            while ((req = xdc_req_list_remove_head(&poll_state.completed_reqs,
-                                                    sizeof(usb_request_t))) != nullptr) {
+            while ((req_int = list_remove_head_type(&poll_state.completed_reqs,
+                                                    xdc_req_internal_t, node)) != nullptr) {
+                req = XDC_INTERNAL_TO_USB_REQ(req_int, usb_req_size);
                 usb_request_complete(req, req->response.status, req->response.actual,
-                                     req->complete_cb, req->cookie);
+                                     req_int->complete_cb, req_int->cookie);
             }
         }
     }
@@ -1263,8 +1270,6 @@
             zxlogf(ERROR, "xdc failed to alloc write usb requests, err: %d\n", status);
             return status;
         }
-        req->complete_cb = xdc_write_complete;
-        req->cookie = xdc;
         ZX_DEBUG_ASSERT(usb_request_pool_add(&xdc->free_write_reqs, req) == ZX_OK);
     }
     for (int i = 0; i < MAX_REQS; i++) {
@@ -1274,8 +1279,6 @@
             zxlogf(ERROR, "xdc failed to alloc read usb requests, err: %d\n", status);
             return status;
         }
-        req->complete_cb = xdc_read_complete;
-        req->cookie = xdc;
         status = xdc_req_list_add_head(&xdc->free_read_reqs, req, usb_req_size);
         ZX_DEBUG_ASSERT(status == ZX_OK);
     }
diff --git a/system/dev/usb/xhci/xdc.h b/system/dev/usb/xhci/xdc.h
index f784b0d..9879994 100644
--- a/system/dev/usb/xhci/xdc.h
+++ b/system/dev/usb/xhci/xdc.h
@@ -156,3 +156,5 @@
 
 void xdc_endpoint_set_halt_locked(xdc_t* xdc, xdc_poll_state_t* poll_state, xdc_endpoint_t* ep)
                                   __TA_REQUIRES(xdc->lock);
+void xdc_write_complete(usb_request_t* req, void* cookie);
+void xdc_read_complete(usb_request_t* req, void* cookie);