Modules/EHCI - Bulk/Control transfers working
[tpg/acess2.git] / KernelLand / Modules / USB / UHCI / uhci.c
index 636cd74..98a4b09 100644 (file)
@@ -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);

UCC git Repository :: git.ucc.asn.au