[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cdi-devel] [PATCH] usb: struct usb_packet



Kevin Wolf schrieb:
Als ersten Schritt zu einem netteren Interface nimmt usb_do_packet jetzt
statt einer endlosen Kette von Parametern jetzt eine struct, die ein
Paket beschreibt.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 usb/include/usb.h |   27 ++++++++++--
 usb/main.c        |   85 +++++++++++++++++++++++++--------------
 usb/msd.c         |  114 +++++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 167 insertions(+), 59 deletions(-)

diff --git a/usb/include/usb.h b/usb/include/usb.h
index 2c435d8..cca698a 100644
--- a/usb/include/usb.h
+++ b/usb/include/usb.h
@@ -28,10 +28,11 @@
 #include "cdi/misc.h"
 #include "cdi/pci.h"
-
-#define PACKET_SETUP 0x2D
-#define PACKET_IN    0x69
-#define PACKET_OUT   0xE1
+enum usb_packet_type {
+    PACKET_SETUP = 0x2D,
+    PACKET_IN    = 0x69,
+    PACKET_OUT   = 0xE1,
+};
#define NO_DATA 0x01
 #define DEV_TO_HOST   0x80
@@ -270,6 +271,22 @@ struct msclass_data
     struct endpoint_desc *bulk_ep_out;
 };
+/** Beschreibt ein USB-Paket */
+struct usb_packet {
+    /// Der Typ des Pakets (PACKET_IN, PACKET_OUT, PACKET_SETUP)
+    enum usb_packet_type type;
+    /// Der gewuenschte Endpoint (0 bis 15)
+    int endpoint;
+    /// Die physische Adresse des zu verwendenden Datenpuffers
+    uintptr_t phys_data;
+    /// Die Laenge des Puffers
+    int length;
+    /// Gibt an, ob DATA0 (0) oder DATA1 (1) verwendet werden soll
+    int datatoggle;
+    /// Typ der Daten (zur Sicherheit, damit es kein doofes STALL gibt)
+    int type_of_data;
+};
+
#include "uhci.h" @@ -277,7 +294,7 @@ struct msclass_data
 #define HCI_STRUCT_SIZE sizeof(struct uhci)
-int do_packet(struct usb_device *device, int type, int endpoint, uintptr_t phys_data, int length, int datatoggle, int type_of_data);
+int usb_do_packet(struct usb_device *device, struct usb_packet* packet);
 void enumerate_hci(struct hci *);
 struct cdi_driver *init_uhcd(void);
 void init_msc_driver(void);
diff --git a/usb/main.c b/usb/main.c
index c06f15d..92a7096 100644
--- a/usb/main.c
+++ b/usb/main.c
@@ -97,44 +97,41 @@ static const int next_data_type[9] = {
 * Verarbeitet ein USB-Paket.
 *
 * @param device Das USB-Gerät
-* @param type Der Typ des Pakets (PACKET_IN, PACKET_OUT, PACKET_SETUP)
-* @param endpoint Der gewünschte Endpoint (0 bis 15)
-* @param phys_data Die physische Adresse des zu verwendenden Datenpuffers
-* @param length Die Länge des Puffers
-* @param datatoggle Gibt an, ob DATA0 (0) oder DATA1 (1) verwendet werden soll
-* @param type_of_data Typ der Daten (zur Sicherheit, damit es kein doofes STALL gibt)
 */
-int do_packet(struct usb_device *device, int type, int endpoint, uintptr_t phys_data, int length, int datatoggle, int type_of_data)
+int usb_do_packet(struct usb_device *device, struct usb_packet* packet)
 {
     int error;
     int tod_short;
- if (!(device->expects & type_of_data)) {
-        dprintf("Expected 0x%04X, got 0x%04X...?\n", device->expects, type_of_data);
+    if (!(device->expects & packet->type_of_data)) {
+        dprintf("Expected 0x%04X, got 0x%04X...?\n", device->expects,
+            packet->type_of_data);
+        // FIXME Das ist keine elegante Loesung des Problems
         for (;;);
     }
-    type_of_data >>= 1;
-    for (tod_short = 0; type_of_data; tod_short++) {
-        type_of_data >>= 1;
+    packet->type_of_data >>= 1;
+    for (tod_short = 0; packet->type_of_data; tod_short++) {
+        packet->type_of_data >>= 1;
     }
     //dprintf("TOD: %s\n", tod_name[tod_short]);
     device->expects = next_data_type[tod_short];
-    endpoint &= 0x07;
-    type &= 0xFF;
+    packet->endpoint &= 0x07;
+    packet->type &= 0xFF;
     if (device->stalled) //TODO: Irgendwie entstallen, evtl.? oO
     {
         dprintf("Zugriff auf stalled-Gerät verweigert.\n");
         return USB_STALLED;
     }
     error = device->hci->do_packet(device->hci,
-                                   (device->hci->get_frame(device->hci) + 3) & 0x3FF,
-                                   type, device->id, endpoint,
-                                   device->low_speed, phys_data, length,
-                                   datatoggle);
+        (device->hci->get_frame(device->hci) + 3) & 0x3FF,
+        packet->type, device->id, packet->endpoint,
+        device->low_speed, packet->phys_data, packet->length,
+        packet->datatoggle);
     if (error == USB_STALLED)
     {
-        printf("[usb] ENDPOINT %i DES GERÄTS %i STALLED!\n", endpoint, device->id);
+        printf("[usb] ENDPOINT %i DES GERÄTS %i STALLED!\n",
+            packet->endpoint, device->id);
         device->stalled = 1;
     }
     return error;
@@ -164,10 +161,21 @@ static void *do_control(struct usb_device *device, int direction, void *buffer,
     setup->value = value;
     setup->index = index;
     setup->length = length;
-    if (do_packet(device, PACKET_SETUP, 0, psetup, sizeof(struct setup_packet),
-                  0, USB_TOD_SETUP) != USB_NO_ERROR) {
+
+    struct usb_packet setup_packet = {
+        .type           = PACKET_SETUP,
+        .endpoint       = 0,
+        .phys_data      = psetup,
+        .length         = sizeof(*setup),
+        .datatoggle     = 0,
+        .type_of_data   = USB_TOD_SETUP,
+    };
+
+
+    if (usb_do_packet(device, &setup_packet)) {
         return NULL;
     }
+
     cdi_sleep_ms(20);
     if (no_data)
     {
@@ -176,22 +184,39 @@ static void *do_control(struct usb_device *device, int direction, void *buffer,
     }
     else
     {
-        if (direction == DEV_TO_HOST) {
-            rval = do_packet(device, PACKET_IN, 0, pbuf, length, 1,
-                             USB_TOD_SETUP_DATA_IN);
-        } else {
-            rval = do_packet(device, PACKET_OUT, 0, pbuf, length, 1,
-                             USB_TOD_SETUP_DATA_OUT);
-        }
+        struct usb_packet data_packet = {
+            .type           = PACKET_IN,
Das Feld "type" ist ebenso wie das Feld "type_of_data" von der Variable "direction" abhängig. Hier gehört also Folgendes hin:
.type           = (direction == DEV_TO_HOST ?
                 PACKET_IN : PACKET_OUT),
+            .endpoint       = 0,
+            .phys_data      = pbuf,
+            .length         = length,
+            .datatoggle     = 1,
+            .type_of_data   = (direction == DEV_TO_HOST ?
+                              USB_TOD_SETUP_DATA_IN : USB_TOD_SETUP_DATA_OUT),
+        };
+
+        rval = usb_do_packet(device, &data_packet);
     }
+
     if (rval == USB_NO_ERROR)
     {
+        struct usb_packet ack_packet = {
+            .endpoint       = 0,
+            .phys_data      = 0,
+            .length         = 0,
+            .datatoggle     = 1,
+        };
+
         cdi_sleep_ms(20);
+
         if (no_data || (direction == HOST_TO_DEV)) {
-            rval = do_packet(device, PACKET_IN, 0, 0, 0, 1, USB_TOD_SETUP_ACK_IN);
+            ack_packet.type         = PACKET_IN;
+            ack_packet.type_of_data = USB_TOD_SETUP_ACK_IN;
         } else {
-            rval = do_packet(device, PACKET_OUT, 0, 0, 0, 1, USB_TOD_SETUP_ACK_OUT);
+            ack_packet.type         = PACKET_OUT;
+            ack_packet.type_of_data = USB_TOD_SETUP_ACK_OUT;
         }
+
+        rval = usb_do_packet(device, &ack_packet);
     }
     return (rval == USB_NO_ERROR) ? rbuf : NULL;
 }
diff --git a/usb/msd.c b/usb/msd.c
index 11fbd6a..0f9b79e 100644
--- a/usb/msd.c
+++ b/usb/msd.c
@@ -187,7 +187,7 @@ void register_msd(struct usb_device *usbdev)
         strgdev->block_count = bc;
         size = bs;
         size *= bc;
-        dprintf("%s: %i * %i B (ca. %i MB).\n", strgdev->dev.name, bc, bs, size >> 20);
+        dprintf("%s: %i * %i B (ca. %lld MB).\n", strgdev->dev.name, bc, bs, size >> 20);
     }
     cdi_storage_device_init(strgdev);
     cdi_list_push(cdi_driver.drv.devices, strgdev);
@@ -210,6 +210,36 @@ static void deinit_msd(struct cdi_device *cdi_msd)
     //TODO: Und gerade hier...
 }
+static int write_cmd(struct usb_device* usbdev, uintptr_t src)
+{
+    struct msclass_data *msc = (struct msclass_data*) usbdev->classd;
+    struct usb_packet cmd_packet = {
+        .type           = PACKET_OUT,
+        .endpoint       = msc->bulk_ep_out->endpoint_address,
+        .phys_data      = src,
+        .length         = 0x1F,
+        .datatoggle     = 0,
+        .type_of_data   = USB_TOD_COMMAND,
+    };
+
+    return usb_do_packet(usbdev, &cmd_packet);
+}
+
+static int read_status(struct usb_device* usbdev, uintptr_t dest)
+{
+    struct msclass_data *msc = (struct msclass_data*) usbdev->classd;
+    struct usb_packet status_packet = {
+        .type           = PACKET_IN,
+        .endpoint       = msc->bulk_ep_in->endpoint_address,
+        .phys_data      = dest,
+        .length         = 0x0D,
+        .datatoggle     = 0,
+        .type_of_data   = USB_TOD_STATUS,
+    };
+
+    return usb_do_packet(usbdev, &status_packet);
+}
+
 static int msd_get_capacity(struct usb_device *usbdev, uint32_t *block_size, uint32_t *block_count)
 {
     struct msclass_data *msc;
@@ -244,29 +274,43 @@ static int msd_get_capacity(struct usb_device *usbdev, uint32_t *block_size, uin
     cbw->cbw_cb_length = 12;
     cbw->cbw_cb[0] = MSC_CMD_CAPACITY;
     cbw->cbw_cb[1] = 0; //LUN: 0
-    if (do_packet(usbdev, PACKET_OUT, msc->bulk_ep_out->endpoint_address, pcbw,
-                  0x1F, 0, USB_TOD_COMMAND) != USB_NO_ERROR) {
+
+    if (write_cmd(usbdev, pcbw) != USB_NO_ERROR) {
         return 0;
     }
+
     cdi_sleep_ms(20);
-    if (do_packet(usbdev, PACKET_IN, msc->bulk_ep_in->endpoint_address, pcap,
-                  sizeof(struct msd_capacity), 0, USB_TOD_DATA_IN)
-           != USB_NO_ERROR) {
+
+    struct usb_packet in_packet = {
+        .type           = PACKET_IN,
+        .endpoint       = msc->bulk_ep_in->endpoint_address,
+        .phys_data      = pcap,
+        .length         = sizeof(*cap),
+        .datatoggle     = 0,
+        .type_of_data   = USB_TOD_DATA_IN,
+    };
+
+    if (usb_do_packet(usbdev, &in_packet) != USB_NO_ERROR) {
         return 0;
     }
+
     cdi_sleep_ms(5);
-    if (do_packet(usbdev, PACKET_IN, msc->bulk_ep_in->endpoint_address, pcsw,
-                  0x0D, 0, USB_TOD_STATUS) != USB_NO_ERROR) {
+
+    if (read_status(usbdev, pcsw) != USB_NO_ERROR) {
         return 0;
     }
+
     cdi_sleep_ms(5);
+
     if ((csw->csw_signature != CSW_SIGNATURE) ||
          (csw->csw_tag      !=  expected_tag) ||
           csw->csw_status) {
         return 0;
     }
+
     *block_size = BE2CPU(cap->block_length);
     *block_count = BE2CPU(cap->last_lba) + 1;
+
     return 1;
 }
@@ -295,21 +339,23 @@ static int msd_ready(struct usb_device *usbdev)
    cbw->cbw_flags = 0x80; //IN
    cbw->cbw_lun = 0; //Was weiß ich, wie viele LUNs datt Dingens hat?
    cbw->cbw_cb_length = 12; //Alles null, also "Test unit ready"
-   if (do_packet(usbdev, PACKET_OUT, msc->bulk_ep_out->endpoint_address, pcbw,
-                 0x1F, 0, USB_TOD_COMMAND) != USB_NO_ERROR) {
+
+   if (write_cmd(usbdev, pcbw) != USB_NO_ERROR) {
        return 0;
    }
+
    cdi_sleep_ms(7);
-   if (do_packet(usbdev, PACKET_IN, msc->bulk_ep_in->endpoint_address, pcsw,
-                 0x0D, 0, USB_TOD_STATUS) != USB_NO_ERROR) {
+   if (read_status(usbdev, pcsw) != USB_NO_ERROR) {
        return 0;
    }
+
    cdi_sleep_ms(4);
    if ((csw->csw_signature != CSW_SIGNATURE) ||
        (csw->csw_tag       !=  expected_tag) ||
         csw->csw_status) {
       return 0;
    }
+
    return 1;
 }
 #endif
@@ -409,23 +455,33 @@ static uint32_t msd_read(struct usb_device *usbdev, uint32_t lba, uint16_t secto
     cbw->cbw_cb[5] =  lba & 0x000000FF;
     cbw->cbw_cb[7] = (sectors & 0x0000FF00) >> 8;
     cbw->cbw_cb[8] =  sectors & 0x000000FF;
-    error = do_packet(usbdev, PACKET_OUT, msc->bulk_ep_out->endpoint_address,
-                      pcbw, 0x1F, 0, USB_TOD_COMMAND);
+
+    error = write_cmd(usbdev, pcbw);
     if (error != USB_NO_ERROR) {
         return error;
     }
     cdi_sleep_ms(20);
-    error = do_packet(usbdev, PACKET_IN, msc->bulk_ep_in->endpoint_address,
-                      phys_buffer, length, 0, USB_TOD_DATA_IN);
+
+    struct usb_packet in_packet = {
+        .type           = PACKET_IN,
+        .endpoint       = msc->bulk_ep_in->endpoint_address,
+        .phys_data      = phys_buffer,
+        .length         = length,
+        .datatoggle     = 0,
+        .type_of_data   = USB_TOD_DATA_IN,
+    };
+
+    error = usb_do_packet(usbdev, &in_packet);
     if (error != USB_NO_ERROR) {
         return error;
     }
     cdi_sleep_ms(5);
-    error = do_packet(usbdev, PACKET_IN, msc->bulk_ep_in->endpoint_address,
-                      pcsw, 0x0D, 0, USB_TOD_STATUS);
+
+    error = read_status(usbdev, pcsw);
     if (error != USB_NO_ERROR) {
         return error;
     }
+
     cdi_sleep_ms(4);
     if ((csw->csw_signature != CSW_SIGNATURE) ||
         (csw->csw_tag       !=  expected_tag) ||
@@ -522,23 +578,33 @@ static uint32_t msd_write(struct usb_device *usbdev, uint32_t lba, uint16_t sect
     cbw->cbw_cb[5] =  lba & 0x000000FF;
     cbw->cbw_cb[7] = (sectors & 0x0000FF00) >> 8;
     cbw->cbw_cb[8] =  sectors & 0x000000FF;
-    error = do_packet(usbdev, PACKET_OUT, msc->bulk_ep_out->endpoint_address,
-                      pcbw, 0x1F, 0, USB_TOD_COMMAND);
+
+    error = write_cmd(usbdev, pcbw);
     if (error != USB_NO_ERROR) {
         return error;
     }
     cdi_sleep_ms(20);
-    error = do_packet(usbdev, PACKET_OUT, msc->bulk_ep_out->endpoint_address,
-                      phys_buffer, length, 0, USB_TOD_DATA_OUT);
+
+    struct usb_packet out_packet = {
+        .type           = PACKET_OUT,
+        .endpoint       = msc->bulk_ep_out->endpoint_address,
+        .phys_data      = phys_buffer,
+        .length         = length,
+        .datatoggle     = 0,
+        .type_of_data   = USB_TOD_DATA_OUT,
+    };
+
+    error = usb_do_packet(usbdev, &out_packet);
     if (error != USB_NO_ERROR) {
         return error;
     }
+
     cdi_sleep_ms(5);
-    error = do_packet(usbdev, PACKET_IN, msc->bulk_ep_in->endpoint_address,
-                      pcsw, 0x0D, 0, USB_TOD_STATUS);
+    error = read_status(usbdev, pcsw);
     if (error != USB_NO_ERROR) {
         return error;
     }
+
     cdi_sleep_ms(4);
     if ((csw->csw_signature != CSW_SIGNATURE) ||
         (csw->csw_tag       !=  expected_tag) ||
------------------------------------------------------------------------

_______________________________________________
cdi-devel mailing list
cdi-devel@xxxxxxxxxx
http://list.tyndur.org/cgi-bin/mailman/listinfo/cdi-devel