From: Bernhard Urban Date: Wed, 23 Sep 2009 06:07:40 +0000 (+0200) Subject: first attempt to get interrupt transfers working. epic fail :( X-Git-Tag: demo0~8 X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=ppcskel.git;a=commitdiff_plain;h=f57c39027e4f153e0ce2f3ab847fb83da624e31d first attempt to get interrupt transfers working. epic fail :( {s,g}et_configuration still don't work (hence, so do {s,g}et_interface) --- diff --git a/usb/core/core.c b/usb/core/core.c index be99b29..f279a89 100644 --- a/usb/core/core.c +++ b/usb/core/core.c @@ -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; } diff --git a/usb/core/core.h b/usb/core/core.h index 4aeb042..64bddf4 100644 --- a/usb/core/core.h +++ b/usb/core/core.h @@ -167,6 +167,7 @@ struct usb_transfer_descriptor { u8 devaddress; u8 endpoint; u8 fullspeed; + u8 type; // TODO: zusammenfassen! u8 pid; diff --git a/usb/core/usb.c b/usb/core/usb.c index dd21166..b73a33d 100644 --- a/usb/core/usb.c +++ b/usb/core/usb.c @@ -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; } diff --git a/usb/core/usb.h b/usb/core/usb.h index 2e9c0a4..ecc5e3f 100644 --- a/usb/core/usb.h +++ b/usb/core/usb.h @@ -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 **********************/ diff --git a/usb/host/ohci.c b/usb/host/ohci.c index a1520d0..a7ef894 100644 --- a/usb/host/ohci.c +++ b/usb/host/ohci.c @@ -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;