intterupt transfers done right now. however, the keyboard driver behave
authorBernhard Urban <lewurm@gmx.net>
Sat, 26 Sep 2009 06:40:27 +0000 (08:40 +0200)
committerBernhard Urban <lewurm@gmx.net>
Sat, 26 Sep 2009 06:40:27 +0000 (08:40 +0200)
still buggy.

bulk transfers also added, but UNTESTED!

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

diff --git a/main.c b/main.c
index 6c30ab6cbdee73d17f98ecfe64b38f49cc25cb23..133d998531a4271cbb0e707f33c115b66385adfe 100644 (file)
--- a/main.c
+++ b/main.c
@@ -123,7 +123,7 @@ int main(void)
        usb_init(OHCI0_REG_BASE);
 
        /* internal ohci */
-       usb_init(OHCI1_REG_BASE);
+       //usb_init(OHCI1_REG_BASE);
 
        /* load HID keyboard driver */
        usb_hidkb_init();
@@ -134,6 +134,8 @@ int main(void)
        }
        while(!usb_hidkb_inuse());
 
+       print_str("hello keyboard :)", 17);
+
 #define FONT_WIDTH  13
 #define FONT_HEIGHT 15
 #define STDOUT_BORDER_LEFT 20
index 0b38e77d6c34ec6136a360041ba6d087ceee49f7..54cfb9792a34649dc166490337fad1cd16f86210 100644 (file)
@@ -121,7 +121,7 @@ struct usb_device *usb_add_device(u8 lowspeed, u32 reg)
                return (void*) -1;
        }
 
-#define WTF
+//#define WTF
 #ifdef WTF
        volatile u8 wzf = 11;
        if(0 == wzf) {
index bb0a3c0acfb5957195bc1ad6e6494251156e8c99..f243bcad9f56c7f6040eccc5c599cbb3fc4b4424 100644 (file)
@@ -155,12 +155,33 @@ void hcdi_fire(u32 reg)
        if(edhead == 0)
                return;
 
+       u8 itmp;
+       switch(edhead->type) {
+               case USB_CTRL:
 #ifdef _USE_C_Q
-       /* quirk... 11ms seems to be a minimum :O */
-       udelay(11000);
-#endif
+                       /* quirk... 11ms seems to be a minimum :O */
+                       udelay(11000);
+#endif
+                       write32(reg+OHCI_HC_CTRL_HEAD_ED, virt_to_phys(edhead));
+               break;
+
+               case USB_INTR:
+                       //udelay(11000);
+                       set_target_hcca(reg);
+                       sync_before_read(hcca, sizeof(struct ohci_hcca));
+                       for(itmp = 0; itmp < NUM_INITS; itmp++) {
+                               hcca->int_table[itmp] = LE(virt_to_phys(edhead));
+                       }
+                       sync_after_write(hcca, sizeof(struct ohci_hcca));
+               break;
 
-       write32(reg+OHCI_HC_CTRL_HEAD_ED, virt_to_phys(edhead));
+               case USB_BULK:
+                       write32(reg+OHCI_HC_BULK_HEAD_ED, virt_to_phys(edhead));
+               break;
+
+               case USB_ISOC:
+               break;
+       }
 
        /* sync it all */
        sync_after_write(edhead, sizeof(struct endpoint_descriptor));
@@ -184,9 +205,28 @@ void hcdi_fire(u32 reg)
                x = phys_to_virt(LE(x->nexttd));
        }
 
-       /* trigger control list */
-       set32(reg+OHCI_HC_CONTROL, OHCI_CTRL_CLE);
-       write32(reg+OHCI_HC_COMMAND_STATUS, OHCI_CLF);
+       /* start transfer */
+       switch(edhead->type) {
+               case USB_CTRL:
+                       /* trigger control list */
+                       set32(reg+OHCI_HC_CONTROL, OHCI_CTRL_CLE);
+                       write32(reg+OHCI_HC_COMMAND_STATUS, OHCI_CLF);
+                       break;
+
+               case USB_INTR:
+                       /* trigger periodic list */
+                       set32(reg+OHCI_HC_CONTROL, OHCI_CTRL_PLE);
+                       break;
+
+               case USB_BULK:
+                       /* trigger bulk list */
+                       set32(reg+OHCI_HC_CONTROL, OHCI_CTRL_BLE);
+                       write32(reg+OHCI_HC_COMMAND_STATUS, OHCI_BLF);
+                       break;
+
+               case USB_ISOC:
+                       break;
+       }
 
        struct general_td *n=0, *prev = 0, *next = 0;
        /* poll until edhead->headp is null */
@@ -282,12 +322,33 @@ void hcdi_fire(u32 reg)
                free(prev);
        }
 
+out:
        set_target_hcca(reg);
-       hcca->done_head = 0;
-       sync_after_write(hcca, sizeof(*hcca));
+       sync_before_read(hcca, sizeof(struct ohci_hcca));
 
-out:
-       write32(reg+OHCI_HC_CONTROL, read32(reg+OHCI_HC_CONTROL)&~OHCI_CTRL_CLE);
+       u8 jtmp;
+       switch(edhead->type) {
+               case USB_CTRL:
+                       write32(reg+OHCI_HC_CONTROL, read32(reg+OHCI_HC_CONTROL)&~OHCI_CTRL_CLE);
+                       break;
+
+               case USB_INTR:
+                       write32(reg+OHCI_HC_CONTROL, read32(reg+OHCI_HC_CONTROL)&~OHCI_CTRL_PLE);
+                       for(jtmp = 0; jtmp < NUM_INITS; jtmp++) {
+                               hcca->int_table[jtmp] = 0;
+                       }
+                       break;
+
+               case USB_BULK:
+                       write32(reg+OHCI_HC_CONTROL, read32(reg+OHCI_HC_CONTROL)&~OHCI_CTRL_BLE);
+                       break;
+
+               case USB_ISOC:
+                       break;
+       }
+
+       hcca->done_head = 0;
+       sync_after_write(hcca, sizeof(struct ohci_hcca));
 
        edhead = 0;
 
@@ -317,6 +378,7 @@ u8 hcdi_enqueue(const struct usb_transfer_descriptor *td, u32 reg) {
                                OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(td->endpoint) |
                                OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(td->maxp));
                edhead->tdcount = 0;
+               edhead->type = td->type;
        }
 
        struct general_td *tdhw = allocate_general_td();
index 845cc63511ba7cf38f914869d4238c3884c243d7..a857ba0f33bfb654cb90769ef34c3149c8f148b4 100644 (file)
@@ -127,6 +127,7 @@ struct endpoint_descriptor {
 
        /* required by software */
        u32 tdcount;
+       u8 type;
 } ALIGNED(16);
 
 #define        OHCI_ENDPOINT_ADDRESS_MASK                              0x0000007f