X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FUSB%2FUHCI%2Fuhci.c;h=98a4b09692959e134dcd89d7af21eeb72d993db1;hb=538fe6ae58915a502057b5dc7bc43bedd87c5067;hp=636cd74c53b6d8021674e5d971396140a2161ada;hpb=dc8805bd19e086fd0752f976abb1bd0393b12c00;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/USB/UHCI/uhci.c b/KernelLand/Modules/USB/UHCI/uhci.c index 636cd74c..98a4b096 100644 --- a/KernelLand/Modules/USB/UHCI/uhci.c +++ b/KernelLand/Modules/USB/UHCI/uhci.c @@ -93,7 +93,14 @@ int UHCI_Initialise(char **Arguments) int ret; ENTER(""); - + + if( Arguments && *Arguments && strcmp(*Arguments, "0") == 0 ) + { + LOG("Disabled by argument"); + LEAVE('i', MODULE_ERR_NOTNEEDED); + return MODULE_ERR_NOTNEEDED; + } + // Initialise with no maximum value Semaphore_Init( &gUHCI_InterruptSempahore, 0, 0, "UHCI", "Interrupt Queue"); @@ -107,14 +114,15 @@ int UHCI_Initialise(char **Arguments) tPAddr tmp; gaUHCI_TDPool = (void *) MM_AllocDMA(1, 32, &tmp); memset(gaUHCI_TDPool, 0, PAGE_SIZE); + LOG("gaUHCI_TDPool = %p (%P)", gaUHCI_TDPool, tmp); } // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices + // Class:SubClass:Protocol = 0xC (Serial) : 0x3 (USB) : 0x00 (UHCI) while( (id = PCI_GetDeviceByClass(0x0C0300, 0xFFFFFF, id)) >= 0 && i < MAX_CONTROLLERS ) { tUHCI_Controller *cinfo = &gUHCI_Controllers[i]; Uint32 base_addr; - // NOTE: Check "protocol" from PCI? cinfo->PciId = id; base_addr = PCI_GetBAR(id, 4); @@ -184,6 +192,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host) LEAVE('i', -1); return -1; } + LOG("->FrameList = %p (%P)", Host->FrameList, Host->PhysFrameList); Host->TDQHPage = (void *) MM_AllocDMA(1, 32, &Host->PhysTDQHPage); if( !Host->TDQHPage ) { @@ -192,6 +201,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host) LEAVE('i', -1); return -1; } + LOG("->TDQHPage = %p (%P)", Host->TDQHPage, Host->PhysTDQHPage); // Fill frame list // - The numbers 0...31, but bit reversed (16 (0b1000) = 1 (0b00001) @@ -199,6 +209,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host) 0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30, 1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31 }; + // Fill all slots (but every 4th will be changed below for( int i = 0; i < 1024; i ++ ) { Uint32 addr = MM_GetPhysAddr( &Host->TDQHPage->ControlQH ); Host->FrameList[i] = addr | 2; @@ -214,7 +225,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host) Host->FrameList[768 + i*4] = addr | 2; } - // Build up interrupt binary tree + // Build up interrupt binary tree { tUHCI_QH *dest = Host->TDQHPage->InterruptQHs; Uint32 destphys = Host->PhysTDQHPage; @@ -222,7 +233,9 @@ int UHCI_int_InitHost(tUHCI_Controller *Host) // Set up next pointer to index to i/2 in the next step for( int _count = 64; _count > 1; _count /= 2 ) { + LOG("count=%i, dest=%p, destphys=%P", _count, dest, destphys); for( int i = 0; i < _count; i ++ ) { + LOG(" %i-%i: %P==%P", _count, i, MM_GetPhysAddr(dest+i), destphys+i*sizeof(tUHCI_QH)); dest[i].Next = destphys + (_count + i/2) * sizeof(tUHCI_QH) + 2; dest[i].Child = 1; } @@ -257,6 +270,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host) PCI_ConfigWrite( Host->PciId, 0xC0, 2, 0x2000 ); // Enable processing + LOG("Processing enabling"); _OutWord( Host, USBCMD, 0x0001 ); LEAVE('i', 0); @@ -301,16 +315,18 @@ void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD) TD->Control |= (TD->Token >> 21) & 0x7FF; // Stop controller + tPAddr tdaddr = MM_GetPhysAddr( TD ); + ASSERT(tdaddr); _OutWord( Cont, USBCMD, 0x0000 ); // Add TD->Link = 1; if( QH->Child & 1 ) { - QH->Child = MM_GetPhysAddr( TD ); + QH->Child = tdaddr; } else { // Depth first - QH->_LastItem->Link = MM_GetPhysAddr( TD ) | 4; + QH->_LastItem->Link = tdaddr | 4; } QH->_LastItem = TD; @@ -537,7 +553,7 @@ void *UHCI_int_InitEndpt(tUHCI_Controller *Cont, int Type, int Endpt, size_t Max epi->Type = Type; epi->Tgl = 0; - return (void*)(Endpt+1); + return (void*)(tVAddr)(Endpt+1); } @@ -574,7 +590,7 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, void *InData, size_t InLength ) { - ENTER("pPtr pEndpt ibOutbound", Ptr, Endpt, bOutbound); + ENTER("pPtr pEndpt bOutbound", Ptr, Endpt, bOutbound); tUHCI_Controller *Cont = Ptr; tUHCI_QH *qh = &Cont->TDQHPage->ControlQH; @@ -644,7 +660,14 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, // Update toggle value epi->Tgl = tgl; - + + // --- HACK!!! +// for( int i = 0; i < 1024; i ++ ) +// { +// LOG("- FrameList[%i] = %x", i, Cont->FrameList[i]); +// } + // --- /HACK + LEAVE('p', td); return td; } @@ -658,7 +681,7 @@ void *UHCI_SendBulk(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int bOu int dest, tgl; size_t mps; - ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Dest, Cb, CbData, bOutbound, Data, Length); + ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Endpt, Cb, CbData, bOutbound, Data, Length); if( Endpt == NULL ) { Log_Error("UHCI", "_SendBulk passed a NULL endpoint handle"); @@ -800,7 +823,8 @@ void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH) continue ; } - LOG("Removed %p from QH %p", td, QH); + LOG("Removed %p from QH %p", td, QH); + ASSERT(td->Link); if( !prev ) QH->Child = td->Link; @@ -968,26 +992,38 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr) // USB Error Interrupt if( status & 2 ) { - + Log_Notice("UHCI", "USB Error"); } // Resume Detect // - Fired if in suspend state and a USB device sends the RESUME signal if( status & 4 ) { - + Log_Notice("UHCI", "Resume Detect"); } // Host System Error if( status & 8 ) { - + Log_Notice("UHCI", "Host System Error"); } // Host Controller Process Error if( status & 0x10 ) { Log_Error("UHCI", "Host controller process error on controller %p", Ptr); + // Spam Tree + //for( int i = 0; i < 1024; i += 4 ) { + // LOG("%4i: %x", i, Host->FrameList[i]); + //} + + tPAddr phys = Host->TDQHPage->ControlQH.Child; + while( !(phys & 1) && MM_GetRefCount(phys & ~15)) + { + tUHCI_TD *td = UHCI_int_GetTDFromPhys(Host, phys); + LOG("%08P: %08x %08x %08x", phys, td->Control, td->Token, td->BufferPointer); + phys = td->Link; + } } _OutWord(Host, USBSTS, status);