[dev][xdc] Move packet related code to library.

Will be used by the host side xdc server. Since the host side
will have libusb transfer buffers instead of usb requests,
xdc_update_packet_state takes in a void* buffer instead.

Change-Id: I6ddc6e692c9190f3dac3ec03982a50bc99ac0697
diff --git a/system/dev/usb/xhci/rules.mk b/system/dev/usb/xhci/rules.mk
index 9d723e4..c098d64 100644
--- a/system/dev/usb/xhci/rules.mk
+++ b/system/dev/usb/xhci/rules.mk
@@ -20,7 +20,10 @@
     $(LOCAL_DIR)/xhci-trb.c \
     $(LOCAL_DIR)/xhci-util.c \
 
-MODULE_STATIC_LIBS := system/ulib/ddk system/ulib/sync
+MODULE_STATIC_LIBS := \
+    system/ulib/ddk \
+    system/ulib/sync \
+    system/ulib/xdc-server-utils \
 
 MODULE_LIBS := system/ulib/driver system/ulib/zircon system/ulib/c
 
diff --git a/system/dev/usb/xhci/xdc.c b/system/dev/usb/xhci/xdc.c
index c2fb88f..7159f25 100644
--- a/system/dev/usb/xhci/xdc.c
+++ b/system/dev/usb/xhci/xdc.c
@@ -316,32 +316,6 @@
     }
 }
 
-// Updates the packet state with the completed usb request.
-// If out_new_packet is not NULL, it will be populated with whether this request starts
-// a new xdc packet and hence contains a header.
-//
-// Returns ZX_OK if successful, or an error if the request was malformed.
-static zx_status_t xdc_update_packet_state(xdc_packet_state_t* packet_state, usb_request_t* req,
-                                           bool* out_new_packet) {
-    // If we've received all the bytes for a packet, this usb request must be the start
-    // of a new xdc packet, and contain the xdc packet header.
-    bool new_packet = packet_state->bytes_received >= packet_state->header.total_length;
-    if (new_packet) {
-        if (req->response.actual < sizeof(xdc_packet_header_t)) {
-            zxlogf(ERROR, "malformed header, only received %zu bytes\n", req->response.actual);
-            return ZX_ERR_BAD_STATE;
-        }
-        usb_request_copyfrom(req, &packet_state->header,
-                             sizeof(xdc_packet_header_t), 0 /* offset */);
-        packet_state->bytes_received = 0;
-    }
-    packet_state->bytes_received += req->response.actual;
-    if (out_new_packet) {
-        *out_new_packet = new_packet;
-    }
-    return ZX_OK;
-}
-
 static void xdc_update_instance_read_signal_locked(xdc_instance_t* inst)
                                                    __TA_REQUIRES(inst->lock) {
     if (list_length(&inst->completed_reads) > 0) {
@@ -382,8 +356,16 @@
            (req = list_peek_head_type(&inst->completed_reads, usb_request_t, node)) != NULL) {
         if (inst->cur_req_read_offset == 0) {
             bool is_new_packet;
-            zx_status_t status = xdc_update_packet_state(&inst->cur_read_packet,
-                                                         req, &is_new_packet);
+            void* data;
+            zx_status_t status = usb_request_mmap(req, &data);
+             if (status != ZX_OK) {
+                 zxlogf(ERROR, "usb_request_mmap failed, err: %d\n", status);
+                 mtx_unlock(&inst->lock);
+                 return ZX_ERR_BAD_STATE;
+            }
+
+            status = xdc_update_packet_state(&inst->cur_read_packet,
+                                             data, req->response.actual, &is_new_packet);
             if (status != ZX_OK) {
                 mtx_unlock(&inst->lock);
                 return ZX_ERR_BAD_STATE;
@@ -721,7 +703,14 @@
         goto out;
     }
 
-    zx_status_t status = xdc_update_packet_state(&xdc->cur_read_packet, req, NULL);
+    void* data;
+    zx_status_t status = usb_request_mmap(req, &data);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "usb_request_mmap failed, err: %d\n", status);
+        xdc_queue_read_locked(xdc, req);
+        goto out;
+    }
+    status = xdc_update_packet_state(&xdc->cur_read_packet, data, req->response.actual, NULL);
     if (status != ZX_OK) {
         xdc_queue_read_locked(xdc, req);
         goto out;
diff --git a/system/dev/usb/xhci/xdc.h b/system/dev/usb/xhci/xdc.h
index 75da39a..04b2df6 100644
--- a/system/dev/usb/xhci/xdc.h
+++ b/system/dev/usb/xhci/xdc.h
@@ -6,6 +6,7 @@
 
 #include <ddk/device.h>
 #include <ddk/usb-request.h>
+#include <xdc-server-utils/packet.h>
 
 #include "xdc-hw.h"
 #include "xhci-transfer-common.h"
@@ -61,18 +62,6 @@
     xdc_str_desc_t serial_num_desc;
 } xdc_str_descs_t;
 
-typedef struct {
-    uint32_t stream_id;
-    size_t total_length;
-} xdc_packet_header_t;
-
-typedef struct {
-    xdc_packet_header_t header;
-    // Number of bytes received for this packet so far.
-    // Once this equals header.total_length, the packet has been fully received.
-    size_t bytes_received;
-} xdc_packet_state_t;
-
 // This is used by the xdc_poll thread to monitors changes in the debug capability register state,
 // and handle completed requests.
 // TODO(jocelyndang): move this and all poll thread related functions into a single file.
diff --git a/system/ulib/xdc-server-utils/include/xdc-server-utils/packet.h b/system/ulib/xdc-server-utils/include/xdc-server-utils/packet.h
new file mode 100644
index 0000000..b35a139
--- /dev/null
+++ b/system/ulib/xdc-server-utils/include/xdc-server-utils/packet.h
@@ -0,0 +1,27 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <zircon/types.h>
+
+typedef struct {
+    uint32_t stream_id;
+    size_t total_length;
+} xdc_packet_header_t;
+
+typedef struct {
+    xdc_packet_header_t header;
+    // Number of bytes received for this packet so far.
+    // Once this equals header.total_length, the packet has been fully received.
+    size_t bytes_received;
+} xdc_packet_state_t;
+
+// Updates the packet state with the read data buffer.
+// If out_new_packet is not NULL, it will be populated with whether this
+// data buffer starts a new xdc packet and hence contains a header.
+//
+// Returns ZX_OK if successful, or an error if the data buffer was malformed.
+zx_status_t xdc_update_packet_state(xdc_packet_state_t* packet_state,
+                                    void* data, size_t data_len, bool* out_new_packet);
diff --git a/system/ulib/xdc-server-utils/packet.c b/system/ulib/xdc-server-utils/packet.c
new file mode 100644
index 0000000..7927ebc
--- /dev/null
+++ b/system/ulib/xdc-server-utils/packet.c
@@ -0,0 +1,27 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdio.h>
+#include <string.h>
+#include <xdc-server-utils/packet.h>
+
+zx_status_t xdc_update_packet_state(xdc_packet_state_t* packet_state,
+                                    void* data, size_t data_len, bool* out_new_packet) {
+    // If we've received all the bytes for a packet, this data buffer must be the start
+    // of a new xdc packet, and contain the xdc packet header.
+    bool new_packet = packet_state->bytes_received >= packet_state->header.total_length;
+    if (new_packet) {
+        if (data_len < sizeof(xdc_packet_header_t)) {
+            fprintf(stderr, "malformed header, only received %zu bytes\n", data_len);
+            return ZX_ERR_BAD_STATE;
+        }
+        memcpy(&packet_state->header, data, sizeof(xdc_packet_header_t));
+        packet_state->bytes_received = 0;
+    }
+    packet_state->bytes_received += data_len;
+    if (out_new_packet) {
+        *out_new_packet = new_packet;
+    }
+    return ZX_OK;
+}
diff --git a/system/ulib/xdc-server-utils/rules.mk b/system/ulib/xdc-server-utils/rules.mk
new file mode 100644
index 0000000..e9deab4
--- /dev/null
+++ b/system/ulib/xdc-server-utils/rules.mk
@@ -0,0 +1,29 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+# Userspace library.
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_TYPE := userlib
+
+MODULE_SRCS += \
+    $(LOCAL_DIR)/packet.c \
+
+MODULE_LIBS := system/ulib/c
+
+include make/module.mk
+
+# Host library.
+
+MODULE := $(LOCAL_DIR).hostlib
+
+MODULE_TYPE := hostlib
+
+MODULE_SRCS += \
+    $(LOCAL_DIR)/packet.c \
+
+include make/module.mk