From 7476b06865d3038877c940176a661c10dfb28377 Mon Sep 17 00:00:00 2001 From: "crediar@rypp.net" Date: Sat, 23 Jun 2012 22:07:03 +0000 Subject: [PATCH] USB/EHCI: *Improved the USB/EHCI code, it now retries if an USB device fails to initialise. *Fixed some memory leaks *Added prefixes to some debug texts *Removed some debug texts git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@4 be6c1b03-d731-4111-a574-e37d80d43941 --- alloc.c | 6 +-- diskio.c | 45 ++++++++++-------- ehci.c | 127 ++++++++++++++++++++++++++------------------------- usb.c | 31 +++++++++---- usbstorage.c | 32 ++++++++----- 5 files changed, 138 insertions(+), 103 deletions(-) diff --git a/alloc.c b/alloc.c index c2e1c45..4d47ed2 100644 --- a/alloc.c +++ b/alloc.c @@ -21,7 +21,7 @@ void HeapInit( u8 *Offset ) while( HeapInfoEntries[0].Offset != 0 ) { EXIControl(1); - dbgprintf("Failed to clear memory!:%08X", HeapInfoEntries[0].Offset ); + dbgprintf("Alloc:Failed to clear memory!:%08X", HeapInfoEntries[0].Offset ); Shutdown(); } @@ -59,7 +59,7 @@ void *malloc( u32 _size ) while(1); } - dbgprintf("Using entry:%d to alloc %u(%u) bytes...\n", entry, size, _size ); + //dbgprintf("Alloc:Using entry:%d to alloc %u(%u) bytes...\n", entry, size, _size ); //Now we search a used entry u32 used_entry = 0xdeadbeef; @@ -177,7 +177,7 @@ find_space: if( used_entry != 0xdeadbeef ) goto find_space; - dbgprintf("failed to alloc %d bytes\n", size ); + dbgprintf("Alloc:failed to alloc %d bytes\n", size ); return NULL; } diff --git a/diskio.c b/diskio.c index 020f781..baa5688 100644 --- a/diskio.c +++ b/diskio.c @@ -6,29 +6,38 @@ extern u32 IsInit; DSTATUS disk_initialize( BYTE drv ) { - udelay( 50000 ); - - tiny_ehci_init(); - - int ret = -ENODEV; - - do { - - udelay( 4000 ); - ret = ehci_discover(); - - } while( ret == -ENODEV ); - - dbgprintf("ehci_discover():%d\n", ret ); - - s32 r = USBStorage_Init(); - + s32 r, s_cnt; u32 s_size; - u32 s_cnt = USBStorage_Get_Capacity(&s_size); + + while( 1 ) + { + udelay( 50000 ); + + tiny_ehci_init(); + + int ret = -ENODEV; + + do { + + udelay( 4000 ); + ret = ehci_discover(); + + } while( ret == -ENODEV ); + + dbgprintf("ehci_discover():%d\n", ret ); + + r = USBStorage_Init(); + if( r == 0 ) + break; + } + + s_cnt = USBStorage_Get_Capacity( &s_size ); + dbgprintf( "DIP: Drive size: %dMB SectorSize:%d\n", s_cnt / 1024 * s_size / 1024, s_size); return r; + } DSTATUS disk_status( BYTE drv ) diff --git a/ehci.c b/ehci.c index 47d40ca..08ae6df 100644 --- a/ehci.c +++ b/ehci.c @@ -41,29 +41,29 @@ extern int verbose; static void dbg_qtd (const char *label, struct ehci_qtd *qtd) { - ehci_dbg( "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd, - hc32_to_cpup( &qtd->hw_next), - hc32_to_cpup( &qtd->hw_alt_next), - hc32_to_cpup( &qtd->hw_token), - hc32_to_cpup( &qtd->hw_buf [0])); - if (qtd->hw_buf [1]) - ehci_dbg( " p1=%08x p2=%08x p3=%08x p4=%08x\n", - hc32_to_cpup( &qtd->hw_buf[1]), - hc32_to_cpup( &qtd->hw_buf[2]), - hc32_to_cpup( &qtd->hw_buf[3]), - hc32_to_cpup( &qtd->hw_buf[4])); + //ehci_dbg( "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd, + // hc32_to_cpup( &qtd->hw_next), + // hc32_to_cpup( &qtd->hw_alt_next), + // hc32_to_cpup( &qtd->hw_token), + // hc32_to_cpup( &qtd->hw_buf [0])); + //if (qtd->hw_buf [1]) + // ehci_dbg( " p1=%08x p2=%08x p3=%08x p4=%08x\n", + // hc32_to_cpup( &qtd->hw_buf[1]), + // hc32_to_cpup( &qtd->hw_buf[2]), + // hc32_to_cpup( &qtd->hw_buf[3]), + // hc32_to_cpup( &qtd->hw_buf[4])); } static void dbg_qh (const char *label, struct ehci_qh *qh) { - ehci_dbg ( "%s qh %p n%08x info %x %x qtd %x\n", label, - qh, - hc32_to_cpu(qh->hw_next), - hc32_to_cpu(qh->hw_info1), - hc32_to_cpu(qh->hw_info2), - hc32_to_cpu(qh->hw_current)); - dbg_qtd ("overlay", (struct ehci_qtd *) &qh->hw_qtd_next); + //ehci_dbg ( "%s qh %p n%08x info %x %x qtd %x\n", label, + // qh, + // hc32_to_cpu(qh->hw_next), + // hc32_to_cpu(qh->hw_info1), + // hc32_to_cpu(qh->hw_info2), + // hc32_to_cpu(qh->hw_current)); + //dbg_qtd ("overlay", (struct ehci_qtd *) &qh->hw_qtd_next); } static void @@ -113,37 +113,37 @@ dbg_status (void) void debug_qtds(void) { - struct ehci_qh *qh = ehci->async; - struct ehci_qtd *qtd; - dbg_qh ("qh",qh); - dbg_command (); - dbg_status (); - for(qtd = qh->qtd_head; qtd; qtd = qtd->next) - { - ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd)); - dbg_qtd("qtd",qtd); - ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd)); - } + //struct ehci_qh *qh = ehci->async; + //struct ehci_qtd *qtd; + //dbg_qh ("qh",qh); + //dbg_command (); + //dbg_status (); + //for(qtd = qh->qtd_head; qtd; qtd = qtd->next) + //{ + // ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd)); + // dbg_qtd("qtd",qtd); + // ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd)); + //} } void dump_qh(struct ehci_qh *qh) { - struct ehci_qtd *qtd; - dbg_command (); - dbg_status (); - ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh)); - dbg_qh("qh",qh); - print_hex_dump_bytes("qh:",DUMP_PREFIX_OFFSET,(void*)qh,12*4); - for(qtd = qh->qtd_head; qtd; qtd = qtd->next){ - u32 *buf; - ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd)); - dbg_qtd("qtd",qtd); - print_hex_dump_bytes("qtd:",DUMP_PREFIX_OFFSET,(void*)qtd,8*4); - buf = (u32*)hc32_to_cpu(qtd->hw_buf[0]); - if(buf) - print_hex_dump_bytes("qtd buf:",DUMP_PREFIX_OFFSET,(void*)(buf),8*4); + //struct ehci_qtd *qtd; + //dbg_command (); + //dbg_status (); + //ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh)); + //dbg_qh("qh",qh); + //print_hex_dump_bytes("qh:",DUMP_PREFIX_OFFSET,(void*)qh,12*4); + //for(qtd = qh->qtd_head; qtd; qtd = qtd->next){ + // u32 *buf; + // ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd)); + // dbg_qtd("qtd",qtd); + // print_hex_dump_bytes("qtd:",DUMP_PREFIX_OFFSET,(void*)qtd,8*4); + // buf = (u32*)hc32_to_cpu(qtd->hw_buf[0]); + // if(buf) + // print_hex_dump_bytes("qtd buf:",DUMP_PREFIX_OFFSET,(void*)(buf),8*4); - } + //} } /*-------------------------------------------------------------------------*/ @@ -176,11 +176,11 @@ static int handshake (void __iomem *ptr, result &= mask; if (result == done) return 0; - udelay (1); + udelay(1); usec--; } while (usec > 0); - ehci_dbg("\nhandshake timeout!!\n\n"); + ehci_dbg("\nEHCI:handshake timeout!!\n\n"); dump_qh(ehci->async); dump_qh(ehci->asyncqh); //BUG(); @@ -191,8 +191,8 @@ static int handshake (void __iomem *ptr, /* one-time init, only for memory state */ static int ehci_init(void) { - int retval; - if ((retval = ehci_mem_init()) < 0) + int retval; + if( (retval = ehci_mem_init()) < 0 ) return retval; /* * dedicate a qh for the async ring head, since we couldn't unlink @@ -206,7 +206,12 @@ static int ehci_init(void) ehci->async->hw_token = cpu_to_hc32( QTD_STS_HALT); ehci->async->hw_qtd_next = EHCI_LIST_END(); ehci->async->hw_alt_next = EHCI_LIST_END();//QTD_NEXT( ehci->async->dummy->qtd_dma); + + if( ehci->ctrl_buffer != NULL ) + USB_Free( ehci->ctrl_buffer ); + ehci->ctrl_buffer = USB_Alloc(sizeof(usbctrlrequest)); + ehci->command = 0; ehci_writel( 0x00800002, &ehci->regs->command); ehci_writel( ehci->periodic_dma, &ehci->regs->frame_list); @@ -281,7 +286,7 @@ static void qh_end_transfer (void) if (!(qtd->length ==0 && ((token & 0xff)==QTD_STS_HALT)) && (token & QTD_STS_HALT)) { - ehci_dbg("\nqtd error!:"); + ehci_dbg("EHCI:qtd error!:"); if (token & QTD_STS_BABBLE) { /* FIXME "must" disable babbling device's port too */ @@ -562,7 +567,7 @@ int ehci_do_urb ( struct ehci_device *dev, struct ehci_urb *urb) { return urb->actual_length; } - ehci_dbg ( "un successfull urb %d!!\n", retval); + ehci_dbg ( "EHCI:unsuccessfull urb %d!!\n", retval); return retval; } @@ -592,7 +597,7 @@ s32 ehci_control_message(struct ehci_device *dev,u8 bmRequestType,u8 bmRequest,u { urb.transfer_buffer = USB_Alloc( wLength ); - dbgprintf("memcpy(%p,%p,%u)\n", urb.transfer_buffer, buf, wLength ); + //dbgprintf("memcpy(%p,%p,%u)\n", urb.transfer_buffer, buf, wLength ); memcpy( urb.transfer_buffer, buf, wLength ); ret = ehci_do_urb( dev, &urb ); @@ -667,12 +672,12 @@ int ehci_reset_port(int port) return -ENODEV;// no USB2 device connected } - ehci_dbg ( "port %d has usb2 device connected! reset it...\n", port); + ehci_dbg ( "EHCI:port %d has usb2 device connected! reset it...\n", port); ehci_writel( 0x1803,status_reg); while ((ehci_readl(status_reg) & 0x1801) != 0x1801) { - ehci_dbg ( "Waiting for port %d to settle...(%04x)\n", port, ehci_readl(status_reg)); + ehci_dbg ( "EHCI:Waiting for port %d to settle...(%04x)\n", port, ehci_readl(status_reg)); ehci_writel( 0x1803,status_reg); msleep(500); } @@ -685,30 +690,30 @@ int ehci_reset_port(int port) if (retval != 0) { - ehci_dbg ( "port %d reset error %d\n", port, retval); + ehci_dbg ( "EHCI:port %d reset error %d\n", port, retval); return retval; } - ehci_dbg ( "port %d reseted status:%04x...\n", port,ehci_readl(status_reg)); + ehci_dbg ( "EHCI:port %d reseted status:%04x...\n", port,ehci_readl(status_reg)); msleep(50); // now the device has the default device id retval = ehci_control_message( dev, USB_CTRLTYPE_DIR_DEVICE2HOST, USB_REQ_GETDESCRIPTOR, USB_DT_DEVICE<<8, 0, sizeof(dev->desc), &dev->desc ); if (retval < 0) { - ehci_dbg("unable to get device desc...\n"); + ehci_dbg("EHCI:unable to get device desc...\n"); return retval; } retval = ehci_control_message( dev, USB_CTRLTYPE_DIR_HOST2DEVICE, USB_REQ_SETADDRESS,port+1,0,0,0); if (retval < 0) { - ehci_dbg("unable to set device addr...\n"); + ehci_dbg("EHCI:unable to set device addr...\n"); return retval; } dev->toggles = 0; dev->id = port+1; - ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); + ehci_dbg ( "EHCI:device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); return retval; } int ehci_reset_device(struct ehci_device *dev) @@ -779,7 +784,7 @@ int ehci_close_device(struct ehci_device *dev) for(i=0;inum_port;i++) { struct ehci_device *dev = &ehci->devices[i]; - ehci_dbg ( "device %d:fd:%d %X %X...\n", dev->id,dev->fd,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); + ehci_dbg ( "EHCI:device %d:fd:%d %X %X...\n", dev->id,dev->fd,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); if(dev->fd == fd){ return dev; } @@ -795,7 +800,7 @@ int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf) { struct ehci_device *dev = &ehci->devices[i]; if(dev->id != 0){ - ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); + ehci_dbg ( "EHCI:device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); buf[j*4] = 0; buf[j*4+1] = 0; buf[j*4+2] = le16_to_cpu(dev->desc.idVendor); @@ -803,7 +808,7 @@ int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf) j++; } } - ehci_dbg("found %d devices\n",j); + ehci_dbg("EHCI:found %d devices\n",j); *num = j; return 0; } diff --git a/usb.c b/usb.c index 56df6cd..aad58bc 100644 --- a/usb.c +++ b/usb.c @@ -32,7 +32,7 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd) retval = __usb_getdesc(fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE); if(retval < 0) { - dbgprintf("__usb_getdesc():%d failed\n", retval ); + dbgprintf("USB:__usb_getdesc():%d failed\n", retval ); goto free_and_error; } @@ -50,7 +50,7 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd) //udd->configurations = USB_Alloc(udd->bNumConfigurations* sizeof(*udd->configurations)); if( _ptr == 0) { - dbgprintf("USB_Alloc():failed:%u\n", __LINE__ ); + dbgprintf("USB:USB_Alloc():failed:%u\n", __LINE__ ); retval = -ENOMEM; goto free_and_error; } @@ -99,12 +99,14 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd) //if(ucd->interfaces == NULL) // goto free_and_error; - _ptr = (u32)USB_Alloc(ucd->bNumInterfaces* sizeof(*ucd->interfaces)); - if( _ptr == 0 ) + + + u32 _ptrB = (u32)USB_Alloc(ucd->bNumInterfaces* sizeof(*ucd->interfaces)); + if( _ptrB == 0 ) goto free_and_error; - _ucd[2] = ( ucd->bMaxPower << 24 ) | (_ptr>>8); - _ucd[3] = ((_ptr & 0xFF) << 24) | (_ucd[3]&0xFFFFFF); + _ucd[2] = ( ucd->bMaxPower << 24 ) | (_ptrB>>8); + _ucd[3] = ((_ptrB & 0xFF) << 24) | (_ucd[3]&0xFFFFFF); //dbgprintf("ucd->interfaces:%p\n", ucd->interfaces ); memset( ucd->interfaces, 0, ucd->bNumInterfaces * sizeof(*ucd->interfaces) ); @@ -120,10 +122,10 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd) // goto free_and_error; u32 *_uid = (u32*)uid; - _ptr = (u32)USB_Alloc(uid->bNumEndpoints* sizeof(*uid->endpoints)); + u32 _ptrC = (u32)USB_Alloc(uid->bNumEndpoints* sizeof(*uid->endpoints)); - _uid[2] = (uid->iInterface<<24) | (_ptr >> 8); - _uid[3] = (_ptr<<24) | (_uid[3]&0xFFFFFF); + _uid[2] = (uid->iInterface<<24) | (_ptrC >> 8); + _uid[3] = (_ptrC<<24) | (_uid[3]&0xFFFFFF); memset( uid->endpoints, 0, uid->bNumEndpoints * sizeof(*uid->endpoints) ); @@ -137,18 +139,27 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd) u32 *_ued = (u32*)ued; _ued[1] = (cpu_to_le16(ued->wMaxPacketSize) << 16 ) | (_ued[1] & 0xFFFF); } - } + USB_Free((void*)_ptrC); + } + + USB_Free((void*)_ptrB); + USB_Free( buffer); buffer = (u8*)NULL; } retval = 0; free_and_error: + if( _ptr != 0 ) + USB_Free((void*)_ptr); + if(buffer != NULL) USB_Free(buffer); + if(retval < 0) USB_FreeDescriptors(udd); + return retval; } diff --git a/usbstorage.c b/usbstorage.c index 9e0876b..2952d3a 100644 --- a/usbstorage.c +++ b/usbstorage.c @@ -453,7 +453,9 @@ found: else retval = USBSTORAGE_OK; free_and_return: - if(max_lun!=NULL) USB_Free(max_lun); + if(max_lun!=NULL) + USB_Free(max_lun); + if(retval < 0) { if(dev->buffer != NULL) @@ -643,14 +645,14 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) int ret = USBStorage_Open(&__usbfd, fd); if( ret < 0) { - dbgprintf("Could not open USB device:%d\n",ret); + dbgprintf("USB:Could not open device:%d\n",ret); return -EINVAL; } maxLun = USBStorage_GetMaxLUN(&__usbfd); if(maxLun == USBSTORAGE_ETIMEDOUT) { - dbgprintf("USB device timed out\n"); + dbgprintf("USB:Device timed out\n"); return -EINVAL; } @@ -674,25 +676,33 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) return 0; } - dbgprintf("USB device failed to mount\n"); + dbgprintf("USB:Device failed to mount\n"); return -EINVAL; } static int ums_init_done = 0; s32 USBStorage_Init(void) { + s32 res = -ENODEV; + int i; //debug_printf("usbstorage init %d\n", ums_init_done); if(ums_init_done) return 0; - ums_init_done = 1; - for(i = 0;inum_port; i++){ - struct ehci_device *dev = &ehci->devices[i]; - if(dev->id != 0){ - USBStorage_Try_Device(dev); - } + + + + for(i = 0;inum_port; i++) + { + struct ehci_device *dev = &ehci->devices[i]; + if(dev->id != 0) + { + res = USBStorage_Try_Device(dev); + if( res == 0 ) + ums_init_done = 1; + } } - return 0; + return res; } s32 USBStorage_Get_Capacity(u32*sector_size)