Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
authorJohn Hodge <[email protected]>
Wed, 9 May 2012 04:36:28 +0000 (12:36 +0800)
committerJohn Hodge <[email protected]>
Wed, 9 May 2012 04:36:28 +0000 (12:36 +0800)
15 files changed:
BuildConf/x86/default.mk
KernelLand/Kernel/arch/x86/irq.c
KernelLand/Kernel/arch/x86/mm_virt.c
KernelLand/Kernel/arch/x86/vm8086.c
KernelLand/Kernel/arch/x86_64/vm8086.c
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/threads.c
KernelLand/Modules/Display/BochsGA/bochsvbe.c
KernelLand/Modules/Display/VESA/main.c
KernelLand/Modules/Network/VIARhineII/Makefile [new file with mode: 0644]
KernelLand/Modules/Network/VIARhineII/rhine2.c [new file with mode: 0644]
KernelLand/Modules/USB/Core/usb_devinit.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/UHCI/uhci.c
KernelLand/Modules/USB/UHCI/uhci.h

index a4ce894..51bb9fc 100644 (file)
@@ -2,8 +2,10 @@
 MODULES += Storage/ATA
 MODULES += Storage/FDDv2
 MODULES += Network/NE2000 Network/RTL8139
+MODULES += Network/VIARhineII
 MODULES += Display/VESA
-MODULES += Display/BochsGA Display/VIAVideo
+MODULES += Display/BochsGA
+#MODULES += Display/VIAVideo
 MODULES += Input/PS2KbMouse
 MODULES += x86/ISADMA x86/VGAText
 
index 3d23636..eb89139 100644 (file)
@@ -62,7 +62,7 @@ int IRQ_AddHandler( int Num, void (*Callback)(int, void*), void *Ptr )
        for( i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ )
        {
                if( gIRQ_Handlers[Num][i] == NULL ) {
-                       Log_Log("IRQ", "Added IRQ%i Cb#%i %p", Num, i, Callback);
+//                     Log_Log("IRQ", "Added IRQ%i Cb#%i %p", Num, i, Callback);
                        gIRQ_Handlers[Num][i] = Callback;
                        gaIRQ_DataPointers[Num][i] = Ptr;
                        return 1;
index e96b627..51a3f62 100644 (file)
@@ -1075,6 +1075,9 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
        
        ENTER("iPages iMaxBits pPhysAddr", Pages, MaxBits, PhysAddr);
        
+       if(MaxBits == -1)
+               MaxBits = PHYS_BITS;
+       
        // Sanity Check
        if(MaxBits < 12 || !PhysAddr) {
                LEAVE('i', 0);
index 44c60df..397ec14 100644 (file)
@@ -1,6 +1,9 @@
 /*
- * Acess2 VM8086 Driver
+ * Acess2 Kernel (x86)
  * - By John Hodge (thePowersGang)
+ *
+ * vm8086.c
+ * - Virtual 8086 Mode Monitor
  */
 #define DEBUG  0
 #include <acess.h>
@@ -12,6 +15,8 @@
 // === CONSTANTS ===
 #define TRACE_EMU      0
 
+#define VM8086_USER_BASE       0x1000
+
 #define VM8086_MAGIC_CS        0xFFFF
 #define VM8086_MAGIC_IP        0x0010
 #define VM8086_STACK_SEG       0x9F00
@@ -33,13 +38,15 @@ enum eVM8086_Opcodes
 #define VM8086_BLOCKCOUNT      ((0x9F000-0x10000)/VM8086_BLOCKSIZE)
 
 // === TYPES ===
+struct sVM8086_InternalPages
+{
+       Uint32  Bitmap; // 32 sections = 128 byte blocks
+       tVAddr  VirtBase;
+       tPAddr  PhysAddr;
+};
 struct sVM8086_InternalData
 {
-       struct {
-               Uint32  Bitmap; // 32 sections = 128 byte blocks
-               tVAddr  VirtBase;
-               tPAddr  PhysAddr;
-       }       AllocatedPages[VM8086_PAGES_PER_INST];
+       struct sVM8086_InternalPages    AllocatedPages[VM8086_PAGES_PER_INST];
 };
 
 // === PROTOTYPES ===
@@ -92,15 +99,15 @@ int VM8086_Install(char **Arguments)
                        MM_Map( i * 0x1000, i * 0x1000 );
                }
                MM_Map( 0, 0 ); // IVT / BDA
-               // Map (but allow allocation) of 0x1000 - 0x9F000
-               // - So much hack, it isn't funny
-               // TODO: Remove this and replce with something less hacky
-               for(i=1;i<0x9F;i++) {
-                       MM_Map( i * 0x1000, i * 0x1000 );
-                       while(MM_GetRefCount(i*0x1000))
-                               MM_DerefPhys( i * 0x1000 );
+               if( MM_GetRefCount(0x00000) > 2 ) {
+                       Log_Notice("VM8086", "Ok, who's touched the IVT? (%i)",
+                               MM_GetRefCount(0x00000));
                }
                MM_Map( 0x9F000, 0x9F000 );     // Stack / EBDA
+               if( MM_GetRefCount(0x9F000) > 2 ) {
+                       Log_Notice("VM8086", "And who's been playing with my EBDA? (%i)",
+                               MM_GetRefCount(0x9F000));
+               }
                // System Stack / Stub
                if( MM_Allocate( 0x100000 ) == 0 ) {
                        Log_Error("VM8086", "Unable to allocate memory for stack/stub");
@@ -177,6 +184,7 @@ void VM8086_GPF(tRegs *Regs)
        if(Regs->eip == VM8086_MAGIC_IP && Regs->cs == VM8086_MAGIC_CS
        && Threads_GetPID() == gVM8086_WorkerPID)
        {
+                int    i;
                if( gpVM8086_State == (void*)-1 ) {
                        Log_Log("VM8086", "Worker thread ready and waiting");
                        gpVM8086_State = NULL;
@@ -190,7 +198,17 @@ void VM8086_GPF(tRegs *Regs)
                        gpVM8086_State->BP = Regs->ebp;
                        gpVM8086_State->SI = Regs->esi; gpVM8086_State->DI = Regs->edi;
                        gpVM8086_State->DS = Regs->ds;  gpVM8086_State->ES = Regs->es;
+
+                       LOG("gpVM8086_State = %p", gpVM8086_State);
+                       LOG("gpVM8086_State->Internal = %p", gpVM8086_State->Internal);
+                       for( i = 0; i < VM8086_PAGES_PER_INST; i ++ ) {
+                               if( !gpVM8086_State->Internal->AllocatedPages[i].VirtBase )
+                                       continue ;
+                               MM_Deallocate( VM8086_USER_BASE + i*PAGE_SIZE );
+                       }
+
                        gpVM8086_State = NULL;
+                               
                        // Wake the caller
                        Semaphore_Signal(&gVM8086_TaskComplete, 1);
                }
@@ -199,6 +217,14 @@ void VM8086_GPF(tRegs *Regs)
                __asm__ __volatile__ ("sti");
                Semaphore_Wait(&gVM8086_TasksToDo, 1);
                
+               for( i = 0; i < VM8086_PAGES_PER_INST; i ++ )
+               {
+                       if( !gpVM8086_State->Internal->AllocatedPages[i].VirtBase )
+                               continue ;
+                       MM_Map( VM8086_USER_BASE + i*PAGE_SIZE, gpVM8086_State->Internal->AllocatedPages[i].PhysAddr );
+               }
+
+               
                //Log_Log("VM8086", "We have a task (%p)", gpVM8086_State);
                Regs->esp -= 2; *(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_CS;
                Regs->esp -= 2; *(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_IP;
@@ -252,6 +278,7 @@ void VM8086_GPF(tRegs *Regs)
                id = *(Uint8*)( Regs->cs*16 +(Regs->eip&0xFFFF));
                Regs->eip ++;
                
+               Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eflags;
                Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->cs;
                Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eip;
                
@@ -390,6 +417,7 @@ tVM8086 *VM8086_Init(void)
 void VM8086_Free(tVM8086 *State)
 {
         int    i;
+       // TODO: Make sure the state isn't in use currently
        for( i = VM8086_PAGES_PER_INST; i --; )
                MM_UnmapHWPages( State->Internal->AllocatedPages[i].VirtBase, 1);
        free(State);
@@ -397,6 +425,7 @@ void VM8086_Free(tVM8086 *State)
 
 void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset)
 {
+       struct sVM8086_InternalPages    *pages = State->Internal->AllocatedPages;
         int    i, j, base = 0;
         int    nBlocks, rem;
        
@@ -407,16 +436,15 @@ void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset)
        
        for( i = 0; i < VM8086_PAGES_PER_INST; i++ )
        {
-               if( State->Internal->AllocatedPages[i].VirtBase == 0 )  continue;
-               
+               if( pages[i].VirtBase == 0 )    continue;
                
-               //Log_Debug("VM8086", "AllocatedPages[%i].Bitmap = 0b%b", i, State->Internal->AllocatedPages[i].Bitmap);
+               //Log_Debug("VM8086", "pages[%i].Bitmap = 0b%b", i, pages[i].Bitmap);
                
                rem = nBlocks;
                base = 0;
                // Scan the bitmap for a free block
                for( j = 0; j < 32; j++ ) {
-                       if( State->Internal->AllocatedPages[i].Bitmap & (1 << j) ) {
+                       if( pages[i].Bitmap & (1 << j) ) {
                                base = j+1;
                                rem = nBlocks;
                        }
@@ -425,12 +453,12 @@ void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset)
                        if(rem == 0)    // Goodie, there's a gap
                        {
                                for( j = 0; j < nBlocks; j++ )
-                                       State->Internal->AllocatedPages[i].Bitmap |= 1 << (base + j);
-                               *Segment = State->Internal->AllocatedPages[i].PhysAddr / 16 + base * 8;
+                                       pages[i].Bitmap |= 1 << (base + j);
+                               *Segment = (VM8086_USER_BASE + i * 0x1000) / 16 + base * 8;
                                *Offset = 0;
-                               LOG("Allocated at #%i,%04x", i, base*128);
+                               LOG("Allocated at #%i,%04x", i, base*8*16);
                                LOG(" - %x:%x", *Segment, *Offset);
-                               return (void*)( State->Internal->AllocatedPages[i].VirtBase + base * 128 );
+                               return (void*)( pages[i].VirtBase + base * 8 * 16 );
                        }
                }
        }
@@ -438,7 +466,7 @@ void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset)
        // No pages with free space?, allocate a new one
        for( i = 0; i < VM8086_PAGES_PER_INST; i++ )
        {
-               if( State->Internal->AllocatedPages[i].VirtBase == 0 )  break;
+               if( pages[i].VirtBase == 0 )    break;
        }
        // Darn, we can't allocate any more
        if( i == VM8086_PAGES_PER_INST ) {
@@ -446,22 +474,40 @@ void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset)
                return NULL;
        }
        
-       State->Internal->AllocatedPages[i].VirtBase = MM_AllocDMA(
-               1, 20, &State->Internal->AllocatedPages[i].PhysAddr);
-       State->Internal->AllocatedPages[i].Bitmap = 0;
+       pages[i].VirtBase = MM_AllocDMA(1, -1, &pages[i].PhysAddr);
+       if( pages[i].VirtBase == 0 ) {
+               Log_Warning("VM8086", "Unable to allocate data page");
+               return NULL;
+       }
+       pages[i].Bitmap = 0;
+       LOG("AllocatedPages[%i].VirtBase = %p", i, pages[i].VirtBase);
+       LOG("AllocatedPages[%i].PhysAddr = %P", i, pages[i].PhysAddr);
                
        for( j = 0; j < nBlocks; j++ )
-               State->Internal->AllocatedPages[i].Bitmap |= 1 << j;
-       LOG("AllocatedPages[%i].Bitmap = 0b%b", i, State->Internal->AllocatedPages[i].Bitmap);
-       *Segment = State->Internal->AllocatedPages[i].PhysAddr / 16;
+               pages[i].Bitmap |= 1 << j;
+       LOG("AllocatedPages[%i].Bitmap = 0b%b", i, pages[i].Bitmap);
+       *Segment = (VM8086_USER_BASE + i * 0x1000) / 16;
        *Offset = 0;
-       LOG(" - %x:%x", *Segment, *Offset);
-       return (void*) State->Internal->AllocatedPages[i].VirtBase;
+       LOG(" - %04x:%04x", *Segment, *Offset);
+       return (void*) pages[i].VirtBase;
 }
 
 void *VM8086_GetPointer(tVM8086 *State, Uint16 Segment, Uint16 Offset)
 {
-       return (void*)( KERNEL_BASE + Segment*16 + Offset );
+       Uint32  addr = Segment * 16 + Offset;
+       
+       if( VM8086_USER_BASE <= addr && addr < VM8086_USER_BASE + VM8086_PAGES_PER_INST*0x1000 )
+       {
+               int pg = (addr - VM8086_USER_BASE) / 0x1000;
+               if( State->Internal->AllocatedPages[pg].VirtBase == 0)
+                       return NULL;
+               else
+                       return (Uint8*)State->Internal->AllocatedPages[pg].VirtBase + (addr & 0xFFF);
+       }
+       else
+       {
+               return (void*)( KERNEL_BASE + addr );
+       }
 }
 
 void VM8086_Int(tVM8086 *State, Uint8 Interrupt)
index 4251570..994fcb2 100644 (file)
@@ -1,4 +1,9 @@
 /*
+ * Acess2 Kernel (x86-64/amd64)
+ * - By John Hodge (thePowersGang)
+ *
+ * vm8086.c
+ * - Real-mode emulation (Stub until emulator is included)
  */
 #include <acess.h>
 #include <vm8086.h>
index 1cc60be..7d30511 100644 (file)
@@ -230,7 +230,7 @@ void VT_SetResolution(int Width, int Height)
        if( Width != mode.width || Height != mode.height )
        {
                Log_Warning("VTerm",
-                       "Selected resolution (%ix%i is not supported) by the device, using (%ix%i)",
+                       "Selected resolution (%ix%i) is not supported by the device, using (%ix%i)",
                        giVT_RealWidth, giVT_RealHeight,
                        mode.width, mode.height
                        );
index e22994b..6099621 100644 (file)
@@ -73,6 +73,7 @@ tGID  Threads_GetGID(void);
  int   Threads_SetUID(Uint *Errno, tUID ID);
  int   Threads_SetGID(Uint *Errno, tUID ID);
 #endif
+void   Threads_int_DumpThread(tThread *thread);
 void   Threads_Dump(void);
 void   Threads_DumpActive(void);
 
@@ -210,7 +211,7 @@ int Threads_SetName(const char *NewName)
        if( IsHeap(oldname) )   free( oldname );        
        cur->ThreadName = strdup(NewName);
 
-       Log_Debug("Threads", "Thread renamed to '%s'", NewName);        
+//     Log_Debug("Threads", "Thread renamed to '%s'", NewName);        
 
        return 0;
 }
@@ -343,9 +344,16 @@ tThread *Threads_CloneTCB(Uint Flags)
                newproc->nThreads = 1;
                // Reference all handles in the VFS
                VFS_ReferenceUserHandles();
+
+               newproc->FirstThread = new;
+               new->ProcessNext = NULL;
        }
        else {
                new->Process->nThreads ++;
+               new->Process = cur->Process;
+               // TODO: Locking
+               new->ProcessNext = new->Process->FirstThread;
+               new->Process->FirstThread = new;
        }
        
        // Messages are not inherited
@@ -1049,6 +1057,36 @@ char **Threads_GetCWD(void)
 }
 // ---
 
+void Threads_int_DumpThread(tThread *thread)
+{
+       Log(" %p %i (%i) - %s (CPU %i) - %i (%s)",
+               thread, thread->TID, thread->Process->PID, thread->ThreadName, thread->CurCPU,
+               thread->Status, casTHREAD_STAT[thread->Status]
+               );
+       switch(thread->Status)
+       {
+       case THREAD_STAT_MUTEXSLEEP:
+               Log("  Mutex Pointer: %p", thread->WaitPointer);
+               break;
+       case THREAD_STAT_SEMAPHORESLEEP:
+               Log("  Semaphore Pointer: %p", thread->WaitPointer);
+               Log("  Semaphore Name: %s:%s", 
+                       ((tSemaphore*)thread->WaitPointer)->ModName,
+                       ((tSemaphore*)thread->WaitPointer)->Name
+                       );
+               break;
+       case THREAD_STAT_ZOMBIE:
+               Log("  Return Status: %i", thread->RetStatus);
+               break;
+       default:        break;
+       }
+       Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
+       Log("  KStack 0x%x", thread->KernelStack);
+       if( thread->bInstrTrace )
+               Log("  Tracing Enabled");
+       Proc_DumpThreadCPUState(thread);
+}
+
 /**
  * \fn void Threads_Dump(void)
  */
@@ -1071,16 +1109,10 @@ void Threads_DumpActive(void)
        #endif
                for(thread=list->Head;thread;thread=thread->Next)
                {
-                       Log(" %p %i (%i) - %s (CPU %i)",
-                               thread, thread->TID, thread->Process->PID, thread->ThreadName, thread->CurCPU);
+                       Threads_int_DumpThread(thread);
                        if(thread->Status != THREAD_STAT_ACTIVE)
                                Log("  ERROR State (%i) != THREAD_STAT_ACTIVE (%i)",
                                        thread->Status, THREAD_STAT_ACTIVE);
-                       Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
-                       Log("  KStack 0x%x", thread->KernelStack);
-                       if( thread->bInstrTrace )
-                               Log("  Tracing Enabled");
-                       Proc_DumpThreadCPUState(thread);
                }
        
        #if SCHEDULER_TYPE == SCHED_RR_PRI
@@ -1102,31 +1134,7 @@ void Threads_Dump(void)
        Log("All Threads:");
        for(thread=gAllThreads;thread;thread=thread->GlobalNext)
        {
-               Log(" %p %i (%i) - %s (CPU %i)",
-                       thread, thread->TID, thread->Process->PID, thread->ThreadName, thread->CurCPU);
-               Log("  State %i (%s)", thread->Status, casTHREAD_STAT[thread->Status]);
-               switch(thread->Status)
-               {
-               case THREAD_STAT_MUTEXSLEEP:
-                       Log("  Mutex Pointer: %p", thread->WaitPointer);
-                       break;
-               case THREAD_STAT_SEMAPHORESLEEP:
-                       Log("  Semaphore Pointer: %p", thread->WaitPointer);
-                       Log("  Semaphore Name: %s:%s", 
-                               ((tSemaphore*)thread->WaitPointer)->ModName,
-                               ((tSemaphore*)thread->WaitPointer)->Name
-                               );
-                       break;
-               case THREAD_STAT_ZOMBIE:
-                       Log("  Return Status: %i", thread->RetStatus);
-                       break;
-               default:        break;
-               }
-               Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
-               Log("  KStack 0x%x", thread->KernelStack);
-               if( thread->bInstrTrace )
-                       Log("  Tracing Enabled");
-               Proc_DumpThreadCPUState(thread);
+               Threads_int_DumpThread(thread);
        }
 }
 
index 4e0e600..70f0c91 100644 (file)
@@ -103,6 +103,10 @@ int BGA_Install(char **Arguments)
        // Check BGA Version\r
        version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
        LOG("version = 0x%x", version);\r
+       if( version == 0xFFFF ) {\r
+               // Floating bus, nothing there\r
+               return MODULE_ERR_NOTNEEDED;\r
+       }\r
        \r
        // NOTE: This driver was written for BGA versions >= 0xBOC2\r
        // NOTE: However, Qemu is braindead and doesn't return the actual version\r
index ddf0671..3f2f1c9 100644 (file)
@@ -112,6 +112,8 @@ int VBE_int_GetModeList(void)
        }\r
        \r
        modes = (Uint16 *) VM8086_GetPointer(gpVesa_BiosState, info->VideoModes.seg, info->VideoModes.ofs);\r
+       LOG("Virtual addres of mode list from %04x:%04x is %p",\r
+               info->VideoModes.seg, info->VideoModes.ofs, modes);\r
 //     VM8086_Deallocate( gpVesa_BiosState, info );\r
        \r
        // Count Modes\r
@@ -155,6 +157,7 @@ void VBE_int_FillMode_Int(int Index, tVesa_CallModeInfo *vbeinfo, tFarPtr *BufPt
                return ;\r
        }\r
 \r
+       #if 0\r
        #define S_LOG(s, fld, fmt)      LOG(" ."#fld" = "fmt, (s).fld)\r
        LOG("vbeinfo[0x%x] = {", mode->code);\r
        S_LOG(*vbeinfo, attributes, "0x%02x");\r
@@ -166,6 +169,7 @@ void VBE_int_FillMode_Int(int Index, tVesa_CallModeInfo *vbeinfo, tFarPtr *BufPt
        S_LOG(*vbeinfo, segmentB, "0x%04x");\r
        LOG(" .realFctPtr = %04x:%04x", vbeinfo->realFctPtr.seg, vbeinfo->realFctPtr.ofs);\r
        S_LOG(*vbeinfo, pitch, "0x%04x");\r
+\r
        // -- Extended\r
        S_LOG(*vbeinfo, Xres, "%i");\r
        S_LOG(*vbeinfo, Yres, "%i");\r
@@ -194,6 +198,7 @@ void VBE_int_FillMode_Int(int Index, tVesa_CallModeInfo *vbeinfo, tFarPtr *BufPt
        S_LOG(*vbeinfo, image_count_banked, "%i");\r
        S_LOG(*vbeinfo, image_count_lfb, "%i");\r
        LOG("}");\r
+       #endif\r
 \r
        mode->flags = FLAG_POPULATED;\r
        if( !(vbeinfo->attributes & 1) ) {\r
@@ -366,14 +371,14 @@ int Vesa_Int_SetMode(int mode)
 int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)\r
 {\r
         int    i;\r
-        int    best = -1, bestFactor = 1000;\r
-        int    factor, tmp;\r
+        int    best = -1, tmp;\r
+       unsigned int factor, bestFactor = -1;\r
        \r
        ENTER("idata->width idata->height idata->bpp", data->width, data->height, data->bpp);\r
 \r
        Vesa_int_FillModeList();\r
        \r
-       for(i=0;i<giVesaModeCount;i++)\r
+       for(i = 0; i < giVesaModeCount; i ++)\r
        {\r
                LOG("Mode %i (%ix%ix%i)", i, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);\r
        \r
@@ -392,7 +397,7 @@ int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)
                tmp = gVesa_Modes[i].width * gVesa_Modes[i].height;\r
                tmp -= data->width * data->height;\r
                tmp = tmp < 0 ? -tmp : tmp;\r
-               factor = tmp * 1000 / (data->width * data->height);\r
+               factor = (Uint64)tmp * 1000 / (data->width * data->height);\r
                \r
                if( data->bpp == 8 && gVesa_Modes[i].bpp != 8 ) continue;\r
                if( data->bpp == 16 && gVesa_Modes[i].bpp != 16 )       continue;\r
diff --git a/KernelLand/Modules/Network/VIARhineII/Makefile b/KernelLand/Modules/Network/VIARhineII/Makefile
new file mode 100644 (file)
index 0000000..580a57a
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = rhine2.o
+NAME = VIARhineII
+
+-include ../Makefile.tpl
diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2.c b/KernelLand/Modules/Network/VIARhineII/rhine2.c
new file mode 100644 (file)
index 0000000..d351a4d
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Acess2 VIA Rhine II Driver (VT6102)
+ * - By John Hodge (thePowersGang)
+ */
+#define        DEBUG   0
+#define VERSION        ((0<<8)|10)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <api_drv_network.h>
+#include <semaphore.h>
+
+// === CONSTANTS ===
+#define VENDOR_ID      0x1106
+#define DEVICE_ID      0x3065
+
+enum eRegs
+{
+       REG_PAR0, REG_PAR1,
+       REG_PAR2, REG_PAR3,
+       REG_PAR4, REG_PAR5,
+       REG_RCR,  REG_TCR,
+       REG_CR0,  REG_CR1,
+       REG_rsv0, REG_rsv1,
+       REG_ISR0, REG_ISR1,
+       REG_IMR0, REG_IMR1,
+};
+
+// === TYPES ===
+typedef struct sCard
+{
+       Uint16  IOBase;
+       Uint8   IRQ;
+       
+        int    NumWaitingPackets;
+       
+       char    Name[2];
+       tVFS_Node       Node;
+       Uint8   MacAddr[6];
+}      tCard;
+
+// === PROTOTYPES ===
+ int   Rhine2_Install(char **Options);
+char   *Rhine2_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *Rhine2_FindDir(tVFS_Node *Node, const char *Filename);
+ int   Rhine2_RootIOCtl(tVFS_Node *Node, int ID, void *Arg);
+Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+ int   Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Arg);
+void   Rhine2_IRQHandler(int Num);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, VIARhineII, Rhine2_Install, NULL, NULL);
+tVFS_NodeType  gRhine2_DirType = {
+       .ReadDir = Rhine2_ReadDir,
+       .FindDir = Rhine2_FindDir,
+       .IOCtl = Rhine2_RootIOCtl
+       };
+tDevFS_Driver  gRhine2_DriverInfo = {
+       NULL, "Rhine2",
+       {
+       .NumACLs = 1,
+       .ACLs = &gVFS_ACL_EveryoneRX,
+       .Flags = VFS_FFLAG_DIRECTORY,
+       .Type = &gRhine2_DirType
+       }
+};
+ int   giRhine2_CardCount;
+tCard  *gaRhine2_Cards;
+
+// === CODE ===
+/**
+ * \brief Installs the PCnet3 Driver
+ */
+int Rhine2_Install(char **Options)
+{
+        int    id = -1;
+        int    i = 0;
+//     Uint16  base;
+       tCard   *card;
+       
+       giRhine2_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID);
+       Log_Debug("PCnet3", "%i cards", giRhine2_CardCount);
+       
+       if( giRhine2_CardCount == 0 )   return MODULE_ERR_NOTNEEDED;
+       
+       gaRhine2_Cards = calloc( giRhine2_CardCount, sizeof(tCard) );
+       
+       while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, i)) != -1 )
+       {
+               card = &gaRhine2_Cards[i];
+               
+               LOG("BAR0 = 0x%08x", PCI_GetBAR(id, 0));
+               LOG("BAR1 = 0x%08x", PCI_GetBAR(id, 1));
+               LOG("BAR2 = 0x%08x", PCI_GetBAR(id, 2));
+               LOG("BAR3 = 0x%08x", PCI_GetBAR(id, 3));
+               LOG("BAR4 = 0x%08x", PCI_GetBAR(id, 4));
+               LOG("BAR5 = 0x%08x", PCI_GetBAR(id, 5));
+               
+//             card->IOBase = base;
+//             card->IRQ = PCI_GetIRQ( id );
+               
+               // Install IRQ Handler
+//             IRQ_AddHandler(card->IRQ, Rhine2_IRQHandler);
+               
+               
+               
+//             Log_Log("PCnet3", "Card %i 0x%04x, IRQ %i %02x:%02x:%02x:%02x:%02x:%02x",
+//                     i, card->IOBase, card->IRQ,
+//                     card->MacAddr[0], card->MacAddr[1], card->MacAddr[2],
+//                     card->MacAddr[3], card->MacAddr[4], card->MacAddr[5]
+//                     );
+               
+               i ++;
+       }
+       
+       gRhine2_DriverInfo.RootNode.Size = giRhine2_CardCount;
+       DevFS_AddDevice( &gRhine2_DriverInfo );
+       
+       return MODULE_ERR_OK;
+}
+
+// --- Root Functions ---
+char *Rhine2_ReadDir(tVFS_Node *Node, int Pos)
+{
+       if( Pos < 0 || Pos >= giRhine2_CardCount )      return NULL;
+       
+       return strdup( gaRhine2_Cards[Pos].Name );
+}
+
+tVFS_Node *Rhine2_FindDir(tVFS_Node *Node, const char *Filename)
+{
+       //TODO: It might be an idea to supprt >10 cards
+       if(Filename[0] == '\0' || Filename[1] != '\0')  return NULL;
+       if(Filename[0] < '0' || Filename[0] > '9')      return NULL;
+       return &gaRhine2_Cards[ Filename[0]-'0' ].Node;
+}
+
+const char *csaRhine2_RootIOCtls[] = {DRV_IOCTLNAMES, NULL};
+int Rhine2_RootIOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       ENTER("pNode iID pData", Node, ID, Data);
+       switch(ID)
+       {
+       BASE_IOCTLS(DRV_TYPE_NETWORK, "PCnet3", VERSION, csaRhine2_RootIOCtls);
+       }
+       LEAVE('i', 0);
+       return 0;
+}
+
+// --- File Functions ---
+Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       #if 0
+       tCard   *card = Node->ImplPtr;
+       Uint16  read_ofs, pkt_length;
+        int    new_read_ofs;
+
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+
+retry:
+       if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
+       {
+               LEAVE_RET('i', 0);
+       }
+       
+       Mutex_Acquire( &card->ReadMutex );
+       
+       read_ofs = inw( card->IOBase + CAPR );
+       LOG("raw read_ofs = %i", read_ofs);
+       read_ofs = (read_ofs + 0x10) & 0xFFFF;
+       LOG("read_ofs = %i", read_ofs);
+       
+       pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2];
+       
+       // Calculate new read offset
+       new_read_ofs = read_ofs + pkt_length + 4;
+       new_read_ofs = (new_read_ofs + 3) & ~3; // Align
+       if(new_read_ofs > card->ReceiveBufferLength) {
+               LOG("wrapping read_ofs");
+               new_read_ofs -= card->ReceiveBufferLength;
+       }
+       new_read_ofs -= 0x10;   // I dunno
+       LOG("new_read_ofs = %i", new_read_ofs);
+       
+       // Check for errors
+       if( *(Uint16*)&card->ReceiveBuffer[read_ofs] & 0x1E ) {
+               // Update CAPR
+               outw(card->IOBase + CAPR, new_read_ofs);
+               Mutex_Release( &card->ReadMutex );
+               goto retry;     // I feel evil
+       }
+       
+       // Get packet
+       if( Length > pkt_length )       Length = pkt_length;
+       memcpy(Buffer, &card->ReceiveBuffer[read_ofs+4], Length);
+       
+       // Update CAPR
+       outw(card->IOBase + CAPR, new_read_ofs);
+       
+       Mutex_Release( &card->ReadMutex );
+       
+       LEAVE('i', Length);
+       #endif
+       
+       return Length;
+}
+
+Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       #if 0
+        int    td;
+       Uint32  status;
+       tCard   *card = Node->ImplPtr;
+       
+       if( Length > 1500 )     return 0;       // MTU exceeded
+       
+       ENTER("pNode XLength pBuffer", Node, Length, Buffer);
+       
+       // TODO: Implement a semaphore for avaliable transmit buffers
+
+       // Find an avaliable descriptor
+       Mutex_Acquire(&card->CurTXProtector);
+       td = card->CurTXDescriptor;
+       card->CurTXDescriptor ++;
+       card->CurTXDescriptor %= 4;
+       Mutex_Release(&card->CurTXProtector);
+       // - Lock it
+       Mutex_Acquire( &card->TransmitInUse[td] );
+       
+       LOG("td = %i", td);
+       
+       // Transmit using descriptor `td`
+       LOG("card->PhysTransmitBuffers[td] = %P", card->PhysTransmitBuffers[td]);
+       outd(card->IOBase + TSAD0 + td*4, card->PhysTransmitBuffers[td]);
+       LOG("card->TransmitBuffers[td] = %p", card->TransmitBuffers[td]);
+       // Copy to buffer
+       memcpy(card->TransmitBuffers[td], Buffer, Length);
+       // Start
+       status = 0;
+       status |= Length & 0x1FFF;      // 0-12: Length
+       status |= 0 << 13;      // 13: OWN bit
+       status |= (0 & 0x3F) << 16;     // 16-21: Early TX threshold (zero atm, TODO: check)
+       LOG("status = 0x%08x", status);
+       outd(card->IOBase + TSD0 + td*4, status);
+       
+       LEAVE('i', (int)Length);
+       #endif
+       
+       return Length;
+}
+
+const char *csaRhine2_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL};
+int Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       tCard   *card = Node->ImplPtr;
+       ENTER("pNode iID pData", Node, ID, Data);
+       switch(ID)
+       {
+       BASE_IOCTLS(DRV_TYPE_NETWORK, "PCnet3", VERSION, csaRhine2_NodeIOCtls);
+       case NET_IOCTL_GETMAC:
+               if( !CheckMem(Data, 6) ) {
+                       LEAVE('i', -1);
+                       return -1;
+               }
+               memcpy( Data, card->MacAddr, 6 );
+               LEAVE('i', 1);
+               return 1;
+       }
+       LEAVE('i', 0);
+       return 0;
+}
+
+void Rhine2_IRQHandler(int Num)
+{
+       #if 0
+        int    i, j;
+       tCard   *card;
+       Uint16  status;
+
+       LOG("Num = %i", Num);
+       
+       for( i = 0; i < giRhine2_CardCount; i ++ )
+       {
+               card = &gaRhine2_Cards[i];
+               if( Num != card->IRQ )  break;
+               
+               status = inw(card->IOBase + ISR);
+               LOG("status = 0x%02x", status);
+               
+               // Transmit OK, a transmit descriptor is now free
+               if( status & FLAG_ISR_TOK )
+               {
+                       for( j = 0; j < 4; j ++ )
+                       {
+                               if( ind(card->IOBase + TSD0 + j*4) & 0x8000 ) { // TSD TOK
+                                       Mutex_Release( &card->TransmitInUse[j] );
+                                       // TODO: Update semaphore once implemented
+                               }
+                       }
+                       outw(card->IOBase + ISR, FLAG_ISR_TOK);
+               }
+               
+               // Recieve OK, inform read
+               if( status & FLAG_ISR_ROK )
+               {
+                        int    read_ofs, end_ofs;
+                        int    packet_count = 0;
+                        int    len;
+                       
+                       // Scan recieve buffer for packets
+                       end_ofs = inw(card->IOBase + CBA);
+                       read_ofs = card->SeenOfs;
+                       LOG("read_ofs = %i, end_ofs = %i", read_ofs, end_ofs);
+                       if( read_ofs > end_ofs )
+                       {
+                               while( read_ofs < card->ReceiveBufferLength )
+                               {
+                                       packet_count ++;
+                                       len = *(Uint16*)&card->ReceiveBuffer[read_ofs+2];
+                                       LOG("%i 0x%x Pkt Hdr: 0x%04x, len: 0x%04x",
+                                               packet_count, read_ofs,
+                                               *(Uint16*)&card->ReceiveBuffer[read_ofs],
+                                               len
+                                               );
+                                       if(len > 2000) {
+                                               Log_Warning("PCnet3", "IRQ: Packet in buffer exceeds sanity (%i>2000)", len);
+                                       }
+                                       read_ofs += len + 4;
+                                       read_ofs = (read_ofs + 3) & ~3; // Align
+                               }
+                               read_ofs -= card->ReceiveBufferLength;
+                               LOG("wrapped read_ofs");
+                       }
+                       while( read_ofs < end_ofs )
+                       {
+                               packet_count ++;
+                               LOG("%i 0x%x Pkt Hdr: 0x%04x, len: 0x%04x",
+                                       packet_count, read_ofs,
+                                       *(Uint16*)&card->ReceiveBuffer[read_ofs],
+                                       *(Uint16*)&card->ReceiveBuffer[read_ofs+2]
+                                       );
+                               read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4;
+                               read_ofs = (read_ofs + 3) & ~3; // Align
+                       }
+                       if( read_ofs != end_ofs ) {
+                               Log_Warning("PCnet3", "IRQ: read_ofs (%i) != end_ofs(%i)", read_ofs, end_ofs);
+                               read_ofs = end_ofs;
+                       }
+                       card->SeenOfs = read_ofs;
+                       
+                       LOG("packet_count = %i, read_ofs = 0x%x", packet_count, read_ofs);
+                       
+                       if( packet_count )
+                       {
+                               if( Semaphore_Signal( &card->ReadSemaphore, packet_count ) != packet_count ) {
+                                       // Oops?
+                               }
+                               VFS_MarkAvaliable( &card->Node, 1 );
+                       }
+                       
+                       outw(card->IOBase + ISR, FLAG_ISR_ROK);
+               }
+       }
+       #endif
+}
index 06efd21..3207669 100644 (file)
@@ -77,20 +77,26 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                if( desc.ManufacturerStr )
                {
                        char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ManufacturerStr);
-                       LOG("ManufacturerStr = '%s'", tmp);
-                       free(tmp);
+                       if( tmp ) {
+                               LOG("ManufacturerStr = '%s'", tmp);
+                               free(tmp);
+                       }
                }
                if( desc.ProductStr )
                {
                        char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ProductStr);
-                       LOG("ProductStr = '%s'", tmp);
-                       free(tmp);
+                       if( tmp ) {
+                               LOG("ProductStr = '%s'", tmp);
+                               free(tmp);
+                       }
                }
                if( desc.SerialNumberStr )
                {
                        char    *tmp = USB_int_GetDeviceString(dev, 0, desc.SerialNumberStr);
-                       LOG("SerialNumbertStr = '%s'", tmp);
-                       free(tmp);
+                       if( tmp ) {
+                               LOG("SerialNumbertStr = '%s'", tmp);
+                               free(tmp);
+                       }
                }
                #endif
        }
index 8eab009..6b38e65 100644 (file)
@@ -152,7 +152,9 @@ char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index)
 
        if(Index == 0)  return strdup("");
        
+       str.Length = 0;
        USB_int_ReadDescriptor(Dev, Endpoint, 3, Index, sizeof(str), &str);
+       if(str.Length == 0)     return NULL;
        if(str.Length < 2) {
                Log_Error("USB", "String %p:%i:%i:%i descriptor is undersized (%i)",
                        Dev->Host, Dev->Address, Endpoint, Index, str.Length);
index 95faca2..dd07210 100644 (file)
@@ -16,7 +16,7 @@
 #include <semaphore.h>
 
 // === CONSTANTS ===
-#define        MAX_CONTROLLERS 4
+#define        MAX_CONTROLLERS 8
 //#define NUM_TDs      1024
 #define NUM_TDs        (PAGE_SIZE/sizeof(tUHCI_TD))
 #define MAX_PACKET_SIZE        0x400
@@ -97,6 +97,7 @@ int UHCI_Initialise(char **Arguments)
        {
                tPAddr  tmp;    
                gaUHCI_TDPool = (void *) MM_AllocDMA(1, 32, &tmp);
+               memset(gaUHCI_TDPool, 0, PAGE_SIZE);
        }
 
        // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices
@@ -265,7 +266,7 @@ tUHCI_TD *UHCI_int_AllocateTD(tUHCI_Controller *Cont)
                if(gaUHCI_TDPool[i]._info.bActive == 0)
                {
                        gaUHCI_TDPool[i].Link = 1;
-                       gaUHCI_TDPool[i].Control = (1 << 23);
+                       gaUHCI_TDPool[i].Control = TD_CTL_ACTIVE;
                        gaUHCI_TDPool[i]._info.bActive = 1;
                        gaUHCI_TDPool[i]._info.QueueIndex = 128;
                        Mutex_Release( &lock );
@@ -283,8 +284,9 @@ void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD)
        Mutex_Acquire(&lock);
        
        // Ensure that there is an interrupt for each used frame
-       TD->Control |= (1 << 24);
+       TD->Control |= TD_CTL_IOC;
        TD->_info.QueueIndex = ((tVAddr)QH - (tVAddr)Cont->TDQHPage->InterruptQHs) / sizeof(tUHCI_QH);
+       LOG("TD(%p)->QueueIndex = %i", TD, TD->_info.QueueIndex);
        // Update length
        TD->Control &= ~0x7FF;
        TD->Control |= (TD->Token >> 21) & 0x7FF;
@@ -341,8 +343,14 @@ tUHCI_TD *UHCI_int_CreateTD(
                td, Length, Type, Addr);
 
        td->Control = (Length - 1) & 0x7FF;
-       td->Control |= (1 << 23);       // Active set
+       td->Control |= TD_CTL_ACTIVE;   // Active set
        td->Control |= (3 << 27);       // 3 retries
+       // High speed device (must be explicitly enabled
+       if( Addr & 0x8000 )
+               ;
+       else
+               td->Control |= 1 << 26;
+               
        td->Token  = ((Length - 1) & 0x7FF) << 21;
        td->Token |= (bTgl & 1) << 19;
        td->Token |= (Addr & 0xF) << 15;
@@ -374,7 +382,7 @@ tUHCI_TD *UHCI_int_CreateTD(
                        tVAddr  ptr = MM_MapTemp(td->BufferPointer);
                        memcpy( (void*)ptr, Data, Length );
                        MM_FreeTemp(ptr);
-                       td->Control |= (1 << 24);
+                       td->Control |= TD_CTL_IOC;
                }
                td->_info.bFreePointer = 1;
        }
@@ -396,7 +404,7 @@ tUHCI_TD *UHCI_int_CreateTD(
        
        if( info ) {
                LOG("info = %p", info);
-               td->Control |= (1 << 24);
+               td->Control |= TD_CTL_IOC;
                td->_info.ExtraInfo = info;
        }
 
@@ -680,12 +688,14 @@ void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH)
 {
        tUHCI_TD        *td, *prev = NULL;
        Uint32  cur_td;
+        int    nCleaned = 0;
 
        // Disable controller
        _OutWord( Cont, USBCMD, 0x0000 );
        
        // Scan QH list
        cur_td = QH->Child;
+       LOG("cur_td = 0x%08x", cur_td);
        while( !(cur_td & 1) )
        {
                td = UHCI_int_GetTDFromPhys(Cont, cur_td);
@@ -696,8 +706,10 @@ void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH)
                }
                
                // Active? Ok.
-               if( td->Control & (1 << 23) ) {
+               if( td->Control & TD_CTL_ACTIVE ) {
+                       LOG("%p still active", td);
                        prev = td;
+                       cur_td = td->Link;
                        continue ;
                }
 
@@ -708,6 +720,11 @@ void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH)
                else
                        prev->Link = td->Link;
                cur_td = td->Link;
+               nCleaned ++;
+       }
+
+       if( nCleaned == 0 ) {
+               LOG("Nothing cleaned... what the?");
        }
 
        // re-enable controller
@@ -772,6 +789,8 @@ void UHCI_int_InterruptThread(void *Pointer)
        Threads_SetName("UHCI Interrupt Handler");
        for( ;; )
        {
+                int    nSeen = 0;
+               
                LOG("zzzzz....");
                // 0 = Take all
                Semaphore_Wait(&gUHCI_InterruptSempahore, 0);
@@ -786,7 +805,9 @@ void UHCI_int_InterruptThread(void *Pointer)
                        // Skip completely inactive TDs
                        if( td->_info.bActive == 0 )    continue ;
                        // Skip ones that are still in use
-                       if( td->Control & (1 << 23) )   continue ;
+                       if( td->Control & TD_CTL_ACTIVE )       continue ;
+
+                       nSeen ++;
 
                        // If no callback/alt buffer, mark as free and move on
                        if( td->_info.ExtraInfo )
@@ -797,17 +818,19 @@ void UHCI_int_InterruptThread(void *Pointer)
                        // Error check
                        if( td->Control & 0x00FF0000 ) {
                                LOG("td->control(Status) = %s%s%s%s%s%s%s%s",
-                                       td->Control & (1 << 23) ? "Active " : "",
-                                       td->Control & (1 << 22) ? "Stalled " : "",
-                                       td->Control & (1 << 21) ? "Data Buffer Error " : "",
-                                       td->Control & (1 << 20) ? "Babble " : "",
-                                       td->Control & (1 << 19) ? "NAK " : "",
-                                       td->Control & (1 << 18) ? "CRC Error, " : "",
-                                       td->Control & (1 << 17) ? "Bitstuff Error, " : "",
-                                       td->Control & (1 << 16) ? "Reserved " : ""
+                                       td->Control & TD_CTL_ACTIVE     ? "Active, " : "",
+                                       td->Control & TD_CTL_STALLED    ? "Stalled, " : "",
+                                       td->Control & TD_CTL_DATABUFERR ? "Data Buffer Error, " : "",
+                                       td->Control & TD_CTL_BABBLE     ? "Babble, " : "",
+                                       td->Control & TD_CTL_NAK        ? "NAK, " : "",
+                                       td->Control & TD_CTL_CRCERR     ? "CRC Error, " : "",
+                                       td->Control & TD_CTL_BITSTUFF   ? "Bitstuff Error, " : "",
+                                       td->Control & TD_CTL_RESERVED   ? "Reserved " : ""
                                        );
+                               LOG("From queue %i", td->_info.QueueIndex);
                                // Clean up QH (removing all inactive entries)
                                UHCI_int_CleanQH(Cont, Cont->TDQHPage->InterruptQHs + td->_info.QueueIndex);
+                               td->Control = 0;
                        }
        
                        // Handle rescheduling of interrupt TDs
@@ -815,7 +838,7 @@ void UHCI_int_InterruptThread(void *Pointer)
                        {
                                LOG("Re-schedule interrupt %p (offset %i)", td, td->_info.QueueIndex);
                                // TODO: Flip toggle?
-                               td->Control |= (1 << 23);
+                               td->Control |= TD_CTL_ACTIVE;
                                // Add back into controller's interrupt list
                                UHCI_int_AppendTD(
                                        Cont,
@@ -833,6 +856,10 @@ void UHCI_int_InterruptThread(void *Pointer)
                        LOG("Cleaned %p (->Control = %x)", td, td->Control);
                        td->_info.bActive = 0;
                }
+
+               if( nSeen == 0 ) {
+                       LOG("Why did you wake me?");
+               }
        }
 }
 
@@ -842,6 +869,7 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
 //      int    frame = (_InWord(Host, FRNUM) - 1) & 0x3FF;
        Uint16  status = _InWord(Host, USBSTS);
        
+       LOG("%p: status = 0x%04x", Ptr, status);
        // Interrupt-on-completion
        if( status & 1 )
        {
@@ -849,7 +877,6 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
                Semaphore_Signal(&gUHCI_InterruptSempahore, 1);
        }
 
-       LOG("status = 0x%04x", status);
        _OutWord(Host, USBSTS, status);
 }
 
index 159bbab..6eff0eb 100644 (file)
@@ -24,6 +24,17 @@ struct sUHCI_ExtraTDInfo
        void    *CallbackPtr;
 };
 
+#define TD_CTL_IOC     (1 << 24)
+
+#define TD_CTL_ACTIVE  (1 << 23)
+#define TD_CTL_STALLED (1 << 22)
+#define TD_CTL_DATABUFERR      (1 << 21)
+#define TD_CTL_BABBLE  (1 << 20)
+#define TD_CTL_NAK     (1 << 19)
+#define TD_CTL_CRCERR  (1 << 18)
+#define TD_CTL_BITSTUFF        (1 << 17)
+#define TD_CTL_RESERVED        (1 << 16)
+
 struct sUHCI_TD
 {
        /**

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