do it more generic, but it fails :/
[ppcskel.git] / usb / core / core.c
index e3dffb24e4102e8f45259f139c58c5aa66d89af8..628e999602d555b4bb2fecf9635b9b8011845a4b 100644 (file)
@@ -40,6 +40,7 @@
 #include "../lib/list.h"
 #include "../../malloc.h"
 #include "../../bootmii_ppc.h" //printf
+#include "../../string.h" //memset
 
 /**
  * Initialize USB stack.
@@ -89,7 +90,7 @@ usb_device *usb_add_device()
 {
        usb_device *dev = (usb_device *) malloc(sizeof(usb_device));
        dev->address = 0;
-       dev->bMaxPacketSize0 = 8;                       /* send at first time only 8 bytes */
+       dev->bMaxPacketSize0 = 8;       /* send at first time only 8 bytes */
 
        dev->epSize[0] = 64;
        dev->epSize[1] = 64;
@@ -100,14 +101,31 @@ usb_device *usb_add_device()
        dev->epTogl[2] = 0;
 
        char buf[64];
-       u8 devdescr_size;
-       u8 address = usb_next_address();
+       memset(buf, 0, sizeof(buf));
 
        /* ask first 8 bytes of device descriptor with this special 
         * GET Descriptor Request, when device address = 0
         */
-       usb_control_msg(dev, 0x80, GET_DESCRIPTOR, 1, 0, 64, buf, 8, 0);
 
+       /*
+        * see page 253 in usb_20.pdf
+        * 
+        * bmRequestType = 0x80 = 10000000B
+        * bRequest = GET_DESCRIPTOR
+        * wValue = DEVICE (Descriptor Type)
+        * wIndex = 0
+        * wLength = 64 // in fact just 8 bytes
+        */
+       //usb_control_msg(dev, 0x80, GET_DESCRIPTOR, DEVICE << 8, 0, 64, buf, 8, 0);
+       // length == 8 => no STALL?! :O
+       usb_control_msg(dev, 0x80, GET_DESCRIPTOR, DEVICE << 8, 0, 64, buf, 8, 0);
+
+       printf("===========\nafter usb control msg:\n");
+       hexdump(buf, sizeof(buf));
+
+#if 0
+       u8 devdescr_size;
+       u8 address = usb_next_address();
        dev->bMaxPacketSize0 = (u8) buf[7] ? (u8) buf[7] : 1; //dirty?  /* setup real ep0 fifo size */
        devdescr_size = (u8) buf[0];    /* save real length of device descriptor */
 
@@ -155,6 +173,7 @@ usb_device *usb_add_device()
        list_add_tail(core.devices, tmp);
 
        usb_probe_driver();
+#endif
 
        return dev;
 }
@@ -240,14 +259,12 @@ u16 usb_submit_irp(usb_irp *irp)
        u8 runloop = 1;
        u16 restlength = irp->len;
        char *td_buf_ptr = irp->buffer;
+       char mybuf[64];
 
-       //u8 togl=irp->dev->epTogl[(irp->endpoint & 0x7F)];
        u8 togl = irp->dev->epTogl[(irp->endpoint & 0x7F)];
-       //u8 togl=0;
 
        switch (irp->type) {
        case USB_CTRL:
-
                /* alle requests mit dem gleichen algorithmus zerteilen
                 * das einzige ist der spezielle get_Device_descriptor request
                 * bei dem eine laenge von 64 angegeben ist.
@@ -255,47 +272,51 @@ u16 usb_submit_irp(usb_irp *irp)
                 * dann reichen die ersten 8 byte.
                 */
 
-                       /***************** Setup Stage ***********************/
+               /***************** Setup Stage ***********************/
                td = usb_create_transfer_descriptor(irp);
                td->pid = USB_PID_SETUP;
                td->buffer = irp->buffer;
-               td->actlen = 8;                                                 /* control message are always 8 bytes */
+
+               /* control message are always 8 bytes */
+               td->actlen = 8;
+               memcpy(mybuf, td->buffer, td->actlen);
 
                togl = 0;
-               td->togl = togl;                                                /* start with data0 */
-               if (togl == 0)
-                       togl = 1;
-               else
-                       togl = 0;
-                       /**** send token ****/
+               /* start with data0 */
+               td->togl = togl;
+               togl = togl ? 0 : 1;
+
+               /**** send token ****/
                hcdi_enqueue(td);
 
-                       /***************** Data Stage ***********************/
-                       /**
-                        * You can see at bit 7 of bmRequestType if this stage is used,
-                        * default requests are always 8 byte greate, from
-                        * host to device. Stage 3 is only neccessary if the request
-                        * expected datas from the device.
-                        * bit7 - 1 = from device to host -> yes we need data stage
-                        * bit7 - 0 = from host to device -> no send zero packet
-                        *
-                        * nach einem setup token kann nur ein IN token in stage 3 folgen
-                        * nie aber ein OUT. Ein Zero OUT wird nur als Bestaetigung benoetigt.
-                        *
-                        *
-                        * bit7 = 1
-                        *      Device to Host
-                        *      - es kommen noch Daten mit PID_IN an
-                        *      - host beendet mit PID_OUT DATA1 Zero
-                        * bit7 - 0
-                        *      Host zu Device (wie set address)
-                        *      - device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
-                        */
-               usb_device_request *setup = (usb_device_request *) irp->buffer;
+               /***************** Data Stage ***********************/
+               /**
+                * You can see at bit 7 of bmRequestType if this stage is used,
+                * default requests are always 8 byte greate, from
+                * host to device. Stage 3 is only neccessary if the request
+                * expected datas from the device.
+                * bit7 - 1 = from device to host -> yes we need data stage
+                * bit7 - 0 = from host to device -> no send zero packet
+                *
+                * nach einem setup token kann nur ein IN token in stage 3 folgen
+                * nie aber ein OUT. Ein Zero OUT wird nur als Bestaetigung benoetigt.
+                *
+                *
+                * bit7 = 1
+                *      Device to Host
+                *      - es kommen noch Daten mit PID_IN an
+                *      - host beendet mit PID_OUT DATA1 Zero
+                * bit7 - 0
+                *      Host zu Device (wie set address)
+                *      - device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
+                */
+               memcpy(mybuf, irp->buffer, td->actlen);
+               usb_device_request *setup = (usb_device_request *) mybuf;
                u8 bmRequestType = setup->bmRequestType;
+               free(td);
 
-               if (bmRequestType & 0x80) { /* check bit 7 of bmRequestType */
-
+               /* check bit 7 of bmRequestType */
+               if (bmRequestType & 0x80) { 
                        /* schleife die die tds generiert */
                        while (runloop) {
                                td = usb_create_transfer_descriptor(irp);
@@ -312,52 +333,50 @@ u16 usb_submit_irp(usb_irp *irp)
 
                                td->pid = USB_PID_IN;
                                td->togl = togl;
-                               if (togl == 0)
-                                       togl = 1;
-                               else
-                                       togl = 0;
+                               togl = togl ? 0 : 1;
 
                                /* wenn device descriptor von adresse 0 angefragt wird werden nur
                                 * die ersten 8 byte abgefragt
                                 */
-                               if (setup->bRequest == GET_DESCRIPTOR && (setup->wValue >> 8) == 1
+                               if (setup->bRequest == GET_DESCRIPTOR && (setup->wValue & 0xff) == 1
                                                && td->devaddress == 0) {
-                                       runloop = 0;                                    /* stop loop */
+                                       /* stop loop */
+                                       runloop = 0;
                                }
 
-                                       /**** send token ****/
+                               /**** send token ****/
                                hcdi_enqueue(td);
 
                                /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */
                                restlength = restlength - irp->epsize;
+                               free(td);
                        }
                }
 
 
-                       /***************** Status Stage ***********************/
+               /***************** Status Stage ***********************/
                /* Zero packet for end */
                td = usb_create_transfer_descriptor(irp);
                td->togl = 1;                                                           /* zero data packet = always DATA1 packet */
                td->actlen = 0;
                td->buffer = NULL;
 
-                       /**
-                        * bit7 = 1, host beendet mit PID_OUT DATA1 Zero
-                        * bit7 = 0, device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
-                        */
-               if (bmRequestType & 0x80) { /* check bit 7 of bmRequestType */
+               /**
+                * bit7 = 1, host beendet mit PID_OUT DATA1 Zero
+                * bit7 = 0, device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
+                */
+               /* check bit 7 of bmRequestType */
+               if (bmRequestType & 0x80) {
                        td->pid = USB_PID_OUT;
                } else {
                        td->pid = USB_PID_IN;
                }
-                       /**** send token ****/
+               /**** send token ****/
                hcdi_enqueue(td);
                free(td);
-
-
                break;
-       case USB_BULK:
 
+       case USB_BULK:
                core.stdout("bulk\r\n");
                //u8 runloop=1;
                //u16 restlength = irp->len;
@@ -406,6 +425,7 @@ u16 usb_submit_irp(usb_irp *irp)
 
                break;
        }
+       hcdi_fire();
 
        return 1;
 }
@@ -424,6 +444,7 @@ usb_transfer_descriptor *usb_create_transfer_descriptor(usb_irp * irp)
        td->endpoint = irp->endpoint;
        td->iso = 0;
        td->state = USB_TRANSFER_DESCR_NONE;
+       td->maxp = irp->epsize;
 
        return td;
 }