X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=usb%2Fcore%2Fcore.c;h=d50c22ba4b057082a29671ac6cbfd9e851a9b007;hb=a553702c41879a83bb8931372d06e377fe88181d;hp=fe1ae9e7d65b0d31acb280d87284bca3ff5623ce;hpb=d2d9dbe02102801e2f52380fb5bd11d8cbcf786c;p=ppcskel.git diff --git a/usb/core/core.c b/usb/core/core.c index fe1ae9e..d50c22b 100644 --- a/usb/core/core.c +++ b/usb/core/core.c @@ -45,12 +45,12 @@ /** * Initialize USB stack. */ -void usb_init() +void usb_init(u32 reg) { core.drivers = list_create(); core.devices = list_create(); core.nextaddress = 1; - hcdi_init(); + hcdi_init(reg); } /** @@ -71,10 +71,10 @@ u8 usb_next_address() void usb_periodic() { // call ever registered driver - usb_driver *drv; - element *iterator = core.drivers->head; + struct usb_driver *drv; + struct element *iterator = core.drivers->head; while (iterator != NULL) { - drv = (usb_driver *) iterator->data; + drv = (struct usb_driver *) iterator->data; drv->check(); iterator = iterator->next; } @@ -86,11 +86,17 @@ void usb_periodic() * for the core. usb_add_device expected that * the device answers to address zero. */ -usb_device *usb_add_device() +struct usb_device *usb_add_device(u8 lowspeed, u32 reg) { - usb_device *dev = (usb_device *) malloc(sizeof(usb_device)); + struct usb_device *dev = (struct usb_device *) malloc(sizeof(struct usb_device)); + dev->conf = (struct usb_conf *) malloc(sizeof(struct usb_conf)); dev->address = 0; - dev->bMaxPacketSize0 = 8; /* send at first time only 8 bytes */ + dev->fullspeed = lowspeed ? 0 : 1; + /* send at first time only 8 bytes for lowspeed devices + * 64 bytes for fullspeed + */ + dev->bMaxPacketSize0 = lowspeed ? 8 : 64; + dev->ohci = reg; dev->epSize[0] = 64; dev->epSize[1] = 64; @@ -100,73 +106,127 @@ usb_device *usb_add_device() dev->epTogl[1] = 0; dev->epTogl[2] = 0; - char buf[64]; - memset(buf, 0, sizeof(buf)); - - /* ask first 8 bytes of device descriptor with this special - * GET Descriptor Request, when device address = 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)); + s8 ret; + ret = usb_get_desc_dev_simple(dev); + if(ret < 0) { + return (void*) -1; + } -#if 0 - u8 devdescr_size; +//#define WTF +#ifdef WTF + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADING WTF :O lolololololo \n"); + printf("loolololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDNG WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDINGWTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :Ololololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O llololololo \n"); + printf("lololololool PADDING WTF :O loololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O loloooloo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololoolo \n"); + printf("lololololool PADDING WTF :O lololooolo \n"); + printf("lololololool PADDING WTF :O loloolololo \n"); + printf("lololol PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lolololool PADDING WTF :O lololoololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lolololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lollllool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O loloolololo \n"); + printf("lololololool PADDING WTF lololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); + printf("lololololool PADDING WTF :O lolololololo \n"); +#endif 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 */ - - /* define new adress */ - usb_control_msg(dev, 0x00, SET_ADDRESS, address << 8, 0, 0, buf, 8, 0); + ret = usb_set_address(dev, address); dev->address = address; + printf("set address to %d\n", dev->address); + + /* get device descriptor&co */ + ret = usb_get_desc_dev(dev); + if(ret < 0) + return (void*) -1; + + /* print device info */ + lsusb(dev); + + //HID only! +#define GET_PROTOCOL 0x03 +#define SET_PROTOCOL 0x0b +#define GETit 0xa1 +#define SETit 0x21 + + + u8 buf[255]; +#if 1 + /* select configuration */ + wait_ms(500); + ret = usb_set_configuration(dev, 1); + printf("=============\nusb_set_configuration(ret: %d): %d\n", ret, dev->conf->bConfigurationValue); + wait_ms(500); + printf("=============\nusb_get_configuration: %d (should be 1 here)\n", usb_get_configuration(dev)); +#endif - /* get complete device descriptor */ - usb_control_msg(dev, 0x80, GET_DESCRIPTOR, 1, 0, devdescr_size, buf, 8, - 0); - - /* save only really neccessary values for this small usbstack */ - dev->bDeviceClass = (u8) buf[4]; - dev->bDeviceSubClass = (u8) buf[5]; - dev->bDeviceProtocoll = (u8) buf[6]; - dev->idVendor = (u16) (buf[9] << 8) | (buf[8]); - dev->idProduct = (u16) (buf[11] << 8) | (buf[10]); - dev->bcdDevice = (u16) (buf[13] << 8) | (buf[12]); - - printf( "bDeviceClass 0x%02X\n" - "bDeviceSubClass 0x%02X\n" - "bDeviceProtocoll 0x%02X\n" - "idVendor 0x%04X\n" - "idProduct 0x%04X\n" - "bcdDevice 0x%04X\n", dev->bDeviceClass, - dev->bDeviceSubClass, dev->bDeviceProtocoll, - dev->idVendor, dev->idProduct, dev->bcdDevice); - /* for lewurms keyboard it should be: - * bDeviceClass 0 - * bDeviceSubClass 0 - * bDeviceClass 0 - * idVendor 0x049f - * idProduct 0x000e - * bcdDevice 1.00 - */ +#if 0 + memset(buf, 0, 0xff); + usb_control_msg(dev, 0x81, GET_DESCRIPTOR, 0x2200, 0x0, 0x41, buf, 0); + printf("wtf request\n"); + hexdump((void*)buf, 0x41); +#endif +#if 0 + /* set protocol */ + /* see p48 in HID spec */ + memset(buf, 0, 8); + usb_control_msg(dev, SETit, SET_PROTOCOL, 0, 0, 0, buf, 0); + printf("=============\nhid_set_protocol %d\n", 0); + hexdump((void*)buf, 8); +#endif +#if 0 + memset(buf, 0, 8); + usb_control_msg(dev, GETit, GET_PROTOCOL, 0, 0, 4, buf, 0); + printf("=============\nusb_get_interface: %d\n", buf[0]); + hexdump((void*)buf, 8); +#endif - // string descriptoren werden nicht im arbeitsspeicher gehalten -> on demand mit - // entprechenden funktionen - // hier muss man noch mehr abholen, konfigurationene, interfaces und endpunkte +#if 0 + /* 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); + } +#endif +#if 0 /* add device to device list */ element *tmp = (element *) malloc(sizeof(element)); tmp->data = (void *) dev; @@ -178,11 +238,75 @@ usb_device *usb_add_device() return dev; } +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%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); + printf("iManufacturer(0x%02X): \"%s\"\n", dev->iManufacturer, dev->iManufacturer ? usb_get_string_simple(dev, dev->iManufacturer) : "no String"); + printf("iProduct(0x%02X): \"%s\"\n", dev->iProduct, dev->iProduct ? usb_get_string_simple(dev, dev->iProduct) : "no String"); + printf("iSerialNumber(0x%02X): \"%s\"\n", dev->iSerialNumber, dev->iSerialNumber ? usb_get_string_simple(dev, dev->iSerialNumber) : "no String"); + printf("bNumConfigurations 0x%02X\n", dev->bNumConfigurations); + + u8 c, i, e; + struct usb_conf *conf = dev->conf; + for(c=0; c <= dev->bNumConfigurations; c++) { + printf(" === Configuration Descriptor %d ===\n", c+1); + printf(" bLength 0x%02X\n", conf->bLength); + printf(" bDescriptorType 0x%02X\n", conf->bDescriptorType); + printf(" wTotalLength 0x%04X\n", conf->wTotalLength); + printf(" bNumInterfaces 0x%02X\n", conf->bNumInterfaces); + printf(" bConfigurationValue 0x%02X\n", conf->bConfigurationValue); + printf(" iConfiguration (0x%02X): \"%s\"\n", conf->iConfiguration, conf->iConfiguration ? usb_get_string_simple(dev, conf->iConfiguration) : "no String"); + printf(" bmAttributes 0x%02X\n", conf->bmAttributes); + printf(" bMaxPower 0x%02X\n", conf->bMaxPower); + + struct usb_intf *ifs = conf->intf; + for(i=1; i <= conf->bNumInterfaces; i++) { + printf(" === Interface Descriptor %d ===\n", i); + printf(" bLength 0x%02X\n", ifs->bLength); + printf(" bDescriptorType 0x%02X\n", ifs->bDescriptorType); + printf(" bInterfaceNumber 0x%02X\n", ifs->bInterfaceNumber); + printf(" bAlternateSetting 0x%02X\n", ifs->bAlternateSetting); + printf(" bNumEndpoints 0x%02X\n", ifs->bNumEndpoints); + printf(" bInterfaceClass 0x%02X\n", ifs->bInterfaceClass); + printf(" bInterfaceSubClass 0x%02X\n", ifs->bInterfaceSubClass); + printf(" bInterfaceProtocol 0x%02X\n", ifs->bInterfaceProtocol); + printf(" iInterface (0x%02X): \"%s\"\n", ifs->iInterface, ifs->iInterface ? usb_get_string_simple(dev, ifs->iInterface) : "no String"); + + struct usb_endp *ed = ifs->endp; + for(e=1; e <= ifs->bNumEndpoints; e++) { + printf(" === Endpoint Descriptor %d ===\n", e); + printf(" bLength 0x%02X\n", ed->bLength); + printf(" bDescriptorType 0x%02X\n", ed->bDescriptorType); + printf(" bEndpointAddress 0x%02X\n", ed->bEndpointAddress); + printf(" bmAttributes 0x%02X\n", ed->bmAttributes); + printf(" wMaxPacketSize 0x%02X\n", ed->wMaxPacketSize); + printf(" bInterval 0x%02X\n", ed->bInterval); + + ed = ed->next; + } //endpoint + + ifs = ifs->next; + } //interface + + conf = conf->next; + } //configuration +} + /** * Find currently detached device and remove * data structures */ -u8 usb_remove_device(usb_device * dev) +u8 usb_remove_device(struct usb_device * dev) { // FIXME!!!! dieser quatsch ist nur temporaer free(core.devices->head); @@ -194,10 +318,10 @@ u8 usb_remove_device(usb_device * dev) /** * Register new driver at usb stack. */ -u8 usb_register_driver(usb_driver * dev) +u8 usb_register_driver(struct usb_driver * dev) { /* add driver to driver list */ - element *tmp = (element *) malloc(sizeof(element)); + struct element *tmp = (struct element *) malloc(sizeof(struct element)); tmp->data = (void *) dev; tmp->next = NULL; list_add_tail(core.drivers, tmp); @@ -221,10 +345,10 @@ u8 usb_register_driver(usb_driver * dev) void usb_probe_driver() { // call ever registered driver - usb_driver *drv; - element *iterator = core.drivers->head; + struct usb_driver *drv; + struct element *iterator = core.drivers->head; while (iterator != NULL) { - drv = (usb_driver *) iterator->data; + drv = (struct usb_driver *) iterator->data; drv->probe(); iterator = iterator->next; } @@ -233,7 +357,7 @@ void usb_probe_driver() /** * Not implemented. */ -usb_irp *usb_get_irp() +struct usb_irp *usb_get_irp() { return 0; } @@ -241,7 +365,7 @@ usb_irp *usb_get_irp() /** * Not implemented. */ -u8 usb_remove_irp(usb_irp * irp) +u8 usb_remove_irp(struct usb_irp *irp) { return 1; @@ -253,13 +377,13 @@ u8 usb_remove_irp(usb_irp * irp) * In the usbstack they are transported with the * usb_transfer_descriptor data structure. */ -u16 usb_submit_irp(usb_irp *irp) +u16 usb_submit_irp(struct usb_irp *irp) { - usb_transfer_descriptor *td; + struct usb_transfer_descriptor *td; u8 runloop = 1; u16 restlength = irp->len; - char *td_buf_ptr = irp->buffer; - char mybuf[64]; + u8 *td_buf_ptr = irp->buffer; + u8 mybuf[64]; u8 togl = irp->dev->epTogl[(irp->endpoint & 0x7F)]; @@ -279,7 +403,6 @@ u16 usb_submit_irp(usb_irp *irp) /* control message are always 8 bytes */ td->actlen = 8; - memcpy(mybuf, td->buffer, td->actlen); togl = 0; /* start with data0 */ @@ -287,7 +410,7 @@ u16 usb_submit_irp(usb_irp *irp) togl = togl ? 0 : 1; /**** send token ****/ - hcdi_enqueue(td); + hcdi_enqueue(td, irp->dev->ohci); /***************** Data Stage ***********************/ /** @@ -318,18 +441,18 @@ u16 usb_submit_irp(usb_irp *irp) /* check bit 7 of bmRequestType */ if (bmRequestType & 0x80) { /* schleife die die tds generiert */ - while (runloop) { + while (runloop && (restlength > 0)) { td = usb_create_transfer_descriptor(irp); td->actlen = irp->epsize; /* stop loop if all bytes are send */ - if (restlength <= irp->epsize) { + if (restlength < irp->epsize) { runloop = 0; td->actlen = restlength; } td->buffer = td_buf_ptr; /* move pointer for next packet */ - td_buf_ptr = td_buf_ptr + irp->epsize; + td_buf_ptr += irp->epsize; td->pid = USB_PID_IN; td->togl = togl; @@ -345,7 +468,7 @@ u16 usb_submit_irp(usb_irp *irp) } /**** send token ****/ - hcdi_enqueue(td); + hcdi_enqueue(td, irp->dev->ohci); /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */ restlength = restlength - irp->epsize; @@ -372,19 +495,17 @@ u16 usb_submit_irp(usb_irp *irp) td->pid = USB_PID_IN; } /**** send token ****/ - hcdi_enqueue(td); + hcdi_enqueue(td, irp->dev->ohci); free(td); 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 */ @@ -409,12 +530,9 @@ u16 usb_submit_irp(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); + hcdi_enqueue(td, irp->dev->ohci); free(td); } /* next togl */ @@ -424,7 +542,43 @@ u16 usb_submit_irp(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); return 1; } @@ -434,16 +588,18 @@ u16 usb_submit_irp(usb_irp *irp) /** * Create a transfer descriptor with an parent irp. */ -usb_transfer_descriptor *usb_create_transfer_descriptor(usb_irp * irp) +struct usb_transfer_descriptor *usb_create_transfer_descriptor(struct usb_irp * irp) { - usb_transfer_descriptor *td = - (usb_transfer_descriptor *) malloc(sizeof(usb_transfer_descriptor)); + struct usb_transfer_descriptor *td = + (struct usb_transfer_descriptor *) malloc(sizeof(struct usb_transfer_descriptor)); td->devaddress = irp->dev->address; td->endpoint = irp->endpoint; td->iso = 0; td->state = USB_TRANSFER_DESCR_NONE; td->maxp = irp->epsize; + td->fullspeed = irp->dev->fullspeed; + td->type = irp->type; return td; }