+ tUHCI_TD *td;
+
+ if( Length > 0x400 ) return NULL; // Controller allows up to 0x500, but USB doesn't
+
+ td = UHCI_int_AllocateTD(Cont);
+
+ td->Link = 1;
+ td->Control = (Length - 1) & 0x7FF;
+ td->Token = ((Length - 1) & 0x7FF) << 21;
+ td->Token |= (bTgl & 1) << 19;
+ td->Token |= (Addr & 0xF) << 15;
+ td->Token |= ((Addr/16) & 0xFF) << 8;
+ td->Token |= Type;
+
+ // TODO: Ensure 32-bit paddr
+ if( ((tVAddr)Data & PAGE_SIZE) + Length > PAGE_SIZE ) {
+ Log_Warning("UHCI", "TODO: Support non single page transfers");
+// td->BufferPointer =
+ return NULL;
+ }
+ else {
+ td->BufferPointer = MM_GetPhysAddr( (tVAddr)Data );
+ }
+
+ if( bIOC ) {
+// td->Control
+ }
+
+ UHCI_int_AppendTD(Cont, td);
+
+ return td;
+}
+
+void *UHCI_DataIN(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length)
+{
+ return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0x69, DataTgl, bIOC, Data, Length);
+}
+
+void *UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length)
+{
+ return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0xE1, DataTgl, bIOC, Data, Length);
+}
+
+void *UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length)
+{
+ return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0x2D, DataTgl, bIOC, Data, Length);