This fixes/improves the ehci driver on bare metal. The current logic in ehci_send_bulk(..) looks wired... but he.. this patch is RFC :)
Before patch:
Option rom sizing returned 0 0 \0f7a6000/ End thread \0f7a4000/ End thread \0f7a3000/ End thread |0f7a2000| ata_reset exit status=50 |0f7a2000| send_cmd : read error (status=51 err=04) |0f7a2000| ata0-0: SFCF4096H3BK2SA-I-Q1-233-SMA ATA-5 Hard-Disk (3919 MiBytes) |0f7a2000| Registering bootable: ata0-0: SFCF4096H3BK2SA-I-Q1-233-SMA ATA-5 Hard-Disk (3919 MiBytes) (type:2 prio:103 data:fdb10) |0f7a2000| ata_detect resetresult=604f \0f7a2000/ End thread |0f7a5000| set_address 0x0f7a8d10 |0f7a5000| ehci_control 0x0f7a8950 (dir=0 cmd=8 data=0) |0f7a5000| config_usb: 0x0f7a8950 |0f7a5000| ehci_control 0x0f7a8950 (dir=128 cmd=8 data=8) |0f7a5000| device rev=0200 cls=00 sub=00 proto=00 size=40 |0f7a5000| ehci_control 0x0f7a8950 (dir=128 cmd=8 data=9) |0f7a5000| ehci_control 0x0f7a8950 (dir=128 cmd=8 data=39) |0f7a5000| ehci_control 0x0f7a8950 (dir=0 cmd=8 data=0) |0f7a5000| ehci_control 0x0f7a8950 (dir=128 cmd=8 data=1) |0f7a5000| WARNING - Timeout at ehci_wait_td:544! |0f7a5000| ehci pipe=0x000ef700 cur=00000000 tok=00000000 next=f7a5c80 td=0x0f7a5c80 status=d0d80 |0f7a5000| USB transmission failed |0f7a5000| Unable to configure USB MSC drive. |0f7a5000| Unable to configure USB MSC device. \0f7a5000/ End thread \0f7a7000/ End thread All threads complete. Mapping hd drive 0x000fdb10 to 0 drive 0x000fdb10: PCHS=7964/16/63 translation=large LCHS=995/128/63 s=8027712 finalize PMM malloc finalize Space available for UMB: 000c0000-000ef000
usb transfer log: http://dpaste.com/869037/
After patch:
\0f7a6000/ End thread \0f7a4000/ End thread \0f7a3000/ End thread |0f7a2000| ata_reset exit status=50 |0f7a2000| send_cmd : read error (status=51 err=04) |0f7a2000| ata0-0: SFCF4096H3BK2SA-I-Q1-233-SMA ATA-5 Hard-Disk (3919 MiBytes) |0f7a2000| Registering bootable: ata0-0: SFCF4096H3BK2SA-I-Q1-233-SMA ATA-5 Hard-Disk (3919 MiBytes) (type:2 prio:103 data:fdb10) |0f7a2000| ata_detect resetresult=604f \0f7a2000/ End thread |0f7a5000| set_address 0x0f7a8ce0 |0f7a5000| ehci_control 0x0f7a88d0 (dir=0 cmd=8 data=0) |0f7a5000| config_usb: 0x0f7a88d0 |0f7a5000| ehci_control 0x0f7a88d0 (dir=128 cmd=8 data=8) |0f7a5000| device rev=0200 cls=00 sub=00 proto=00 size=40 |0f7a5000| ehci_control 0x0f7a88d0 (dir=128 cmd=8 data=9) |0f7a5000| ehci_control 0x0f7a88d0 (dir=128 cmd=8 data=39) |0f7a5000| ehci_control 0x0f7a88d0 (dir=0 cmd=8 data=0) |0f7a5000| ehci_control 0x0f7a88d0 (dir=128 cmd=8 data=1) |0f7a5000| USB MSC vendor='' product='STD USB 1GB' rev='0.00' type=0 removable=1 |0f7a5000| scsi_is_ready (drive=0x000fdae0) |0f7a5000| USB MSC blksize=512 sectors=2005575 |0f7a5000| Registering bootable: USB MSC Drive STD USB 1GB 0.00 (type:2 prio:103 data:fdae0) \0f7a5000/ End thread \0f7a7000/ End thread All threads complete. Mapping hd drive 0x000fdb10 to 0 drive 0x000fdb10: PCHS=7964/16/63 translation=large LCHS=995/128/63 s=8027712 Mapping hd drive 0x000fdae0 to 1 drive 0x000fdae0: PCHS=0/0/0 translation=lba LCHS=994/32/63 s=2005575 finalize PMM malloc finalize
ubs transfer log: http://dpaste.com/869023/
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- src/usb-ehci.c | 15 ++++++++++++++- src/usb.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/usb-ehci.c b/src/usb-ehci.c index 2676615..3eefd85 100644 --- a/src/usb-ehci.c +++ b/src/usb-ehci.c @@ -410,6 +410,8 @@ ehci_desc2pipe(struct ehci_pipe *pipe, struct usbdevice_s *usbdev | QH_TOGGLECONTROL); else if (eptype == USB_ENDPOINT_XFER_INT) pipe->qh.info2 |= (0x01 << QH_SMASK_SHIFT) | (0x1c << QH_CMASK_SHIFT); + else if (eptype == USB_ENDPOINT_XFER_BULK) + pipe->qh.info1 |= QH_TOGGLECONTROL; }
static struct usb_pipe * @@ -661,12 +663,15 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
u16 maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); int tdpos = 0; + struct ehci_qtd *last = &tds[0]; + while (datasize) { struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS]; +/* int ret = ehci_wait_td(pipe, td, 5000); if (ret) return -1; - +*/ struct ehci_qtd *nexttd_fl = MAKE_FLATPTR(GET_SEG(SS) , &tds[tdpos % STACKQTDS]);
@@ -680,6 +685,11 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) data += transfer; datasize -= transfer; } + + /* update based on endpoint toggle */ + tds[0].token |= (pipe->pipe.toogle?QTD_TOGGLE:0); + pipe->qh.token|= (pipe->pipe.toogle?QTD_TOGGLE:0); + int i; for (i=0; i<STACKQTDS; i++) { struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS]; @@ -688,6 +698,9 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) return -1; }
+ /* update endpoint toggle based on device */ + pipe->pipe.toogle = (last->token & QTD_TOGGLE) >> 31; + return 0; }
diff --git a/src/usb.h b/src/usb.h index a43e829..d272306 100644 --- a/src/usb.h +++ b/src/usb.h @@ -14,6 +14,7 @@ struct usb_pipe { u8 ep; u8 devaddr; u8 speed; + u8 toogle; u16 maxpacket; u8 eptype; };