first attempt to get interrupt transfers working. epic fail :(
authorBernhard Urban <lewurm@gmx.net>
Wed, 23 Sep 2009 06:07:40 +0000 (08:07 +0200)
committerBernhard Urban <lewurm@gmx.net>
Wed, 23 Sep 2009 06:07:40 +0000 (08:07 +0200)
{s,g}et_configuration still don't work (hence, so do {s,g}et_interface)

usb/core/core.c
usb/core/core.h
usb/core/usb.c
usb/core/usb.h
usb/host/ohci.c

index be99b29533099ea5e86a130b5e5c43c2704a2315..f279a891b53517f14c4d3703ba97bf04aa0b1626 100644 (file)
@@ -160,23 +160,47 @@ struct usb_device *usb_add_device(u8 lowspeed, u32 reg)
        /* print device info */
        lsusb(dev);
 
+
+#if 1
        /* select configuration */
-       ret = usb_set_configuration(dev, dev->conf->bConfigurationValue);
+       ret = usb_set_configuration(dev, 1);
        printf("=============\nusb_set_configuration(ret: %d): %d\n", ret, dev->conf->bConfigurationValue);
-       printf("=============\nusb_get_configuration: %d\n", usb_get_configuration(dev));
+       printf("=============\nusb_get_configuration: %d (should be 1 here)\n", usb_get_configuration(dev));
+#endif
+
 
-#if 0
        u8 buf[8];
+#if 1
+       /* select interface */
        memset(buf, 0, 8);
-       usb_control_msg(dev, 0x00, SET_INTERFACE, 0, dev->conf->intf->bInterfaceNumber, 0, buf, 0);
-       printf("=============\nusb_set_interface: %d\n", dev->conf->intf->bInterfaceNumber);
+       printf("interfacenumber: %d\n", dev->conf->intf->bInterfaceNumber);
+       usb_control_msg(dev, 0x01, SET_INTERFACE, 0, 0, 0, buf, 0);
+       printf("=============\nusb_set_interface: %d\n", 0);
        hexdump((void*)buf, 8);
-
+#if 0
        memset(buf, 0, 8);
-       usb_control_msg(dev, 0x81, GET_INTERFACE, 0, dev->conf->intf->bInterfaceNumber, 8, buf, 0);
+       usb_control_msg(dev, 0x81, GET_INTERFACE, 0, 0, 4, buf, 0);
        printf("=============\nusb_get_interface: %d\n", buf[0]);
        hexdump((void*)buf, 8);
 #endif
+#endif
+
+       /* I just don't know why on some devices 
+        * {s,g}et_{configuration,interface} won't work.
+        * may the setter works and getter are poorly implemented?
+        * however, I try here some interrupt inputs, assuming 
+        * the setters are fine*/
+
+       memset(buf, 0, 8);
+       s8 epnum = dev->conf->intf->endp->bEndpointAddress & 0xf;
+       printf("epnum: 0x%04X\n", epnum);
+       u8 muh = 10;
+       while(muh--) {
+               (void) usb_interrupt_read(dev, epnum, buf, 8, 0);
+               printf("============\nusb_interrupt_read:\n");
+               hexdump((void*)buf, 8);
+               udelay(2000000);
+       }
 
 #if 0
        /* add device to device list */
@@ -195,10 +219,11 @@ void lsusb(struct usb_device *dev)
        printf("=== Device Descriptor === \n");
        printf("bLength 0x%02X\n", dev->bLength);
        printf("bDescriptorType 0x%02X\n", dev->bDeviceClass);
-       printf("bcdUSB 0x%02X\n", dev->bcdUSB);
+       printf("bcdUSB 0x%04X\n", dev->bcdUSB);
        printf("bDeviceClass 0x%02X\n", dev->bDeviceClass);
        printf("bDeviceSubClass 0x%02X\n", dev->bDeviceSubClass);
        printf("bDeviceProtocoll 0x%02X\n", dev->bDeviceProtocoll);
+       printf("bMaxPacketSize 0x%02X\n", dev->bMaxPacketSize0);
        printf("idVendor 0x%04X\n", dev->idVendor);
        printf("idProduct 0x%04X\n", dev->idProduct);
        printf("bcdDevice 0x%04X\n", dev->bcdDevice);
@@ -451,14 +476,12 @@ u16 usb_submit_irp(struct usb_irp *irp)
                break;
 
        case USB_BULK:
-               core.stdout("bulk\r\n");
                //u8 runloop=1;
                //u16 restlength = irp->len;
                //char * td_buf_ptr=irp->buffer;
 
                /* schleife die die tds generiert */
                while (runloop) {
-
                        td = usb_create_transfer_descriptor(irp);
                        td->endpoint = td->endpoint & 0x7F;                             /* clear direction bit */
 
@@ -483,10 +506,7 @@ u16 usb_submit_irp(struct usb_irp *irp)
                        td_buf_ptr = td_buf_ptr + irp->epsize;
 
                        td->togl = togl;
-                       if (togl == 0)
-                               togl = 1;
-                       else
-                               togl = 0;
+                       togl = togl ? 0 : 1;
                                /**** send token ****/
                        hcdi_enqueue(td, irp->dev->ohci);
                        free(td);
@@ -498,6 +518,41 @@ u16 usb_submit_irp(struct usb_irp *irp)
                irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
 
                break;
+       
+       case USB_INTR:
+               //u8 runloop=1;
+               //u16 restlength = irp->len;
+               //char * td_buf_ptr=irp->buffer;
+
+               /* schleife die die tds generiert */
+               while (runloop && (restlength > 0)) {
+                       td = usb_create_transfer_descriptor(irp);
+                       /* max packet size for given endpoint */
+                       td->actlen = irp->epsize;
+
+                       td->pid = USB_PID_IN;
+                       /* TODO: USB_PID_OUT */
+
+                       /* stop loop if all bytes are send */
+                       if (restlength < irp->epsize) {
+                               runloop = 0;
+                               td->actlen = restlength;
+                       }
+
+                       td->buffer = td_buf_ptr;
+                       /* move pointer for next packet */
+                       td_buf_ptr += irp->epsize;
+
+                       td->togl = togl;
+                       togl = togl ? 0 : 1;
+                               
+                               /**** send token ****/
+                       hcdi_enqueue(td, irp->dev->ohci);
+                       restlength = restlength - irp->epsize;
+                       free(td);
+               }
+               break;
+               irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
        }
        hcdi_fire(irp->dev->ohci);
 
@@ -520,6 +575,7 @@ struct usb_transfer_descriptor *usb_create_transfer_descriptor(struct usb_irp *
        td->state = USB_TRANSFER_DESCR_NONE;
        td->maxp = irp->epsize;
        td->fullspeed = irp->dev->fullspeed;
+       td->type = irp->type;
 
        return td;
 }
index 4aeb042884394689fc42e9e15185f9d842cb469a..64bddf481e049deb92f3bf77712f0a9be17d6a26 100644 (file)
@@ -167,6 +167,7 @@ struct usb_transfer_descriptor {
        u8 devaddress;
        u8 endpoint;
        u8 fullspeed;
+       u8 type;
        
        // TODO: zusammenfassen!
        u8 pid;
index dd21166b838c7328543129e481c8186fbe9b6898..b73a33d134c6df92618ee6b7c37bb3269d20d8e4 100644 (file)
@@ -101,7 +101,6 @@ s8 usb_reset(struct usb_device *dev)
 
 
 /******************* Control Transfer **********************/
-
 /**
  * Create a control transfer.
  */
@@ -293,6 +292,7 @@ s8 usb_set_address(struct usb_device *dev, u8 address)
 {
        cleargbuf();
        usb_control_msg(dev, 0x00, SET_ADDRESS, address, 0, 0, gbuf, 0);
+       wait_ms(210);
        return 0;
 }
 
@@ -302,7 +302,7 @@ u8 usb_get_configuration(struct usb_device *dev)
        cleargbuf();
        usb_control_msg(dev, 0x80, GET_CONFIGURATION, 0, 0, 4, gbuf, 0);
        printf("=============\nafter usb_get_configuration:\n");
-       hexdump((void*) gbuf, 1);
+       hexdump((void*) gbuf, 8);
        return gbuf[0];
 }
 
@@ -310,6 +310,7 @@ s8 usb_set_configuration(struct usb_device *dev, u8 configuration)
 {
        cleargbuf();
        usb_control_msg(dev, 0x00, SET_CONFIGURATION, configuration, 0, 0, gbuf, 0);
+       wait_ms(50);
        return 0;
 }
 
@@ -322,7 +323,6 @@ s8 usb_set_altinterface(struct usb_device *dev, u8 alternate)
 
 
 /******************* Bulk Transfer **********************/
-
 /**
  * Write to an a bulk endpoint.
  */
@@ -376,7 +376,6 @@ s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
  */
 s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
 {
-
        return 0;
 }
 
@@ -385,6 +384,19 @@ s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeo
  */
 s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
 {
+       struct usb_irp *irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
+       irp->dev = dev;
+       irp->endpoint = ep | 0x80; //from device to host
+       irp->epsize = dev->epSize[ep]; // ermitteln
+       irp->type = USB_INTR;
+
+       irp->buffer = buf;
+       irp->len = size;
+       irp->timeout = timeout;
+
+       printf("interupt_read\n");
+       usb_submit_irp(irp);
+       free(irp);
 
        return 0;
 }
index 2e9c0a421f07789656ecf311fcd39f8154731ac3..ecc5e3f9d294e55b0f449c1f30a6593321cbac6a 100644 (file)
@@ -81,8 +81,8 @@ s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
 
 
 /******************* Interrupt Transfer **********************/
-s8 usb_u8errupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
-s8 usb_u8errupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
+s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
+s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout);
 
 
 /******************* Isochron Transfer **********************/
index a1520d02d61481ba7ad251378924c46c9ebf1d9e..a7ef894147e48028dc06bbff225dc0e1b0270bba 100644 (file)
@@ -116,11 +116,7 @@ static void general_td_fill(struct general_td *dest, const struct usb_transfer_d
                        dest->flags |= LE(OHCI_TD_DIRECTION_PID_OUT);
                        dest->flags |= LE(OHCI_TD_BUFFER_ROUNDING);
 
-                       /*
-                        * TODO: just temporary solution! (consider it with len?)
-                        * there can be also regular PID_OUT pakets
-                        */
-                       dest->flags |= LE(OHCI_TD_TOGGLE_1);
+                       dest->flags |= src->togl ? LE(OHCI_TD_TOGGLE_1) : LE(OHCI_TD_TOGGLE_0);
                        break;
                case USB_PID_IN:
 #ifdef _DU_OHCI_Q
@@ -133,12 +129,7 @@ static void general_td_fill(struct general_td *dest, const struct usb_transfer_d
                                printf("round buffer!\n");
 #endif
                        }
-                       /*
-                        * let the endpoint do the togglestuff!
-                        * TODO: just temporary solution!
-                        * there can be also inregular PID_IN pakets (@Status Stage)
-                        */
-                       dest->flags |= LE(OHCI_TD_TOGGLE_CARRY);
+                       dest->flags |= src->togl ? LE(OHCI_TD_TOGGLE_1) : LE(OHCI_TD_TOGGLE_0);
                        break;
        }
        dest->flags |= LE(OHCI_TD_SET_DELAY_INTERRUPT(7));
@@ -200,10 +191,10 @@ void hcdi_fire(u32 reg)
        /* poll until edhead->headp is null */
        do {
                sync_before_read(edhead, sizeof(struct endpoint_descriptor));
-#ifdef _DU_OHCI_F
+//#ifdef _DU_OHCI_F
                printf("edhead->headp: 0x%08X\n", LE(edhead->headp));
+//#endif
                udelay(10000);
-#endif
 
                /* if halted, debug output plz. will break the transfer */
                if((LE(edhead->headp) & OHCI_ENDPOINT_HALTED)) {
@@ -243,7 +234,7 @@ void hcdi_fire(u32 reg)
                        dbg_td_flag(LE(prev->flags));
                        printf("halted end!\n");
 #endif
-                       return;
+                       goto out;
                }
                prev = (struct general_td*) (LE(edhead->headp)&~0xf);
        } while(LE(edhead->headp)&~0xf);
@@ -299,6 +290,7 @@ void hcdi_fire(u32 reg)
                sync_after_write(&hcca_oh1, sizeof(hcca_oh1));
        }
 
+out:
        write32(reg+OHCI_HC_CONTROL, read32(reg+OHCI_HC_CONTROL)&~OHCI_CTRL_CLE);
 
        edhead = 0;