Merge 15329:15546 from trunk

svn path=/branches/xmlbuildsystem/; revision=15547
This commit is contained in:
Casper Hornstrup 2005-05-27 19:29:24 +00:00
commit 062423314c
378 changed files with 32303 additions and 30029 deletions

View file

@ -1,4 +1,4 @@
/* $Id$
/*
*
* ReactOS ps - process list console viewer
*
@ -26,6 +26,67 @@
/* NOTE: W32API ddk/ntapi.h header has wrong definition of SYSTEM_PROCESSES. */
#include <ntos/types.h>
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
ULONG WaitReason;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG PageDirectoryFrame;
/*
* This part corresponds to VM_COUNTERS_EX.
* NOTE: *NOT* THE SAME AS VM_COUNTERS!
*/
ULONG PeakVirtualSize;
ULONG VirtualSize;
ULONG PageFaultCount;
ULONG PeakWorkingSetSize;
ULONG WorkingSetSize;
ULONG QuotaPeakPagedPoolUsage;
ULONG QuotaPagedPoolUsage;
ULONG QuotaPeakNonPagedPoolUsage;
ULONG QuotaNonPagedPoolUsage;
ULONG PagefileUsage;
ULONG PeakPagefileUsage;
ULONG PrivateUsage;
/* This part corresponds to IO_COUNTERS */
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREADS Threads [1];
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
// x00000000 00000000 000:00:00 000:00:00 ()
static char* title = "P PID PPID KTime UTime NAME\n";
@ -36,7 +97,7 @@ static char* title2 = "w PID Hwnd WndStile TID WndName\n";
struct status {
DWORD state;
char desc[10];
} thread_stat[8 + 1] = {
} thread_stat[8 + 1] = {
{0, "Init "},
{1, "Ready "},
{2, "Running "},
@ -50,39 +111,45 @@ struct status {
struct waitres {
DWORD state;
char desc[11];
} waitreason[28 + 1] = {
{0, "Executive "},
{1, "FreePage "},
{2, "PageIn "},
{3, "PoolAlloc "},
{4, "DelayExec "},
{5, "Suspended "},
{6, "UserReq "},
{7, "WrExecutive"},
{8, "WrFreePage "},
{9, "WrPageIn "},
{10,"WrPoolAlloc"},
{11,"WrDelayExec"},
{12,"WrSuspended"},
{13,"WrUserReq "},
{14,"WrEventPair"},
{15,"WrQueue "},
{16,"WrLpcRec "},
{17,"WrLpcReply "},
{18,"WrVirtualMm"},
{19,"WrPageOut "},
{20,"WrRendez "},
{21,"Spare1 "},
{22,"Spare2 "},
{23,"Spare3 "},
{24,"Spare4 "},
{25,"Spare5 "},
{26,"Spare6 "},
{27,"WrKernel "},
{-1," ? "}
char desc[17];
} waitreason[35 + 1] = {
{0, "Executive "},
{1, "FreePage "},
{2, "PageIn "},
{3, "PoolAllocation "},
{4, "DelayExecution "},
{5, "Suspended "},
{6, "UserRequest "},
{7, "WrExecutive "},
{8, "WrFreePage "},
{9, "WrPageIn "},
{10,"WrPoolAllocation "},
{11,"WrDelayExecution "},
{12,"WrSuspended "},
{13,"WrUserRequest "},
{14,"WrEventPair "},
{15,"WrQueue "},
{16,"WrLpcReceive "},
{17,"WrLpcReply "},
{18,"WrVirtualMemory "},
{19,"WrPageOut "},
{20,"WrRendezvous "},
{21,"Spare2 "},
{22,"WrGuardedMutex "},
{23,"Spare4 "},
{24,"Spare5 "},
{25,"Spare6 "},
{26,"WrKernel "},
{27,"WrResource "},
{28,"WrPushLock "},
{29,"WrMutex "},
{30,"WrQuantumEnd "},
{31,"WrDispatchInt "},
{32,"WrPreempted "},
{33,"WrYieldExecution "},
{34,"MaximumWaitReason"},
{-1," ? "}
};
BOOL CALLBACK
EnumThreadProc(HWND hwnd, LPARAM lp)
{
@ -90,9 +157,9 @@ EnumThreadProc(HWND hwnd, LPARAM lp)
LONG style;
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
char buf[256];
GetWindowText(hwnd, (LPTSTR)lp, 30);
if(hwnd != 0)
{
style = GetWindowLong(hwnd, GWL_STYLE);
@ -110,13 +177,13 @@ int main()
DWORD r;
ANSI_STRING astring;
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
PSYSTEM_PROCESS_INFORMATION SystemProcesses = NULL;
PSYSTEM_PROCESS_INFORMATION CurrentProcess;
PSYSTEM_PROCESSES SystemProcesses = NULL;
PSYSTEM_PROCESSES CurrentProcess;
ULONG BufferSize, ReturnSize;
NTSTATUS Status;
char buf[256];
char buf1[256];
WriteFile(stdout, title, lstrlen(title), &r, NULL);
WriteFile(stdout, title1, lstrlen(title1), &r, NULL);
WriteFile(stdout, title2, lstrlen(title2), &r, NULL);
@ -153,7 +220,7 @@ int main()
hour = (ptime.QuadPart / (10000000LL * 3600LL));
minute = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
seconds = (ptime.QuadPart / 10000000LL) % 60LL;
ptime.QuadPart = CurrentProcess->UserTime.QuadPart;
hour1 = (ptime.QuadPart / (10000000LL * 3600LL));
minute1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
@ -166,7 +233,7 @@ int main()
hour, minute, seconds, hour1, minute1, seconds1,
astring.Buffer);
WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
RtlFreeAnsiString(&astring);
for (ti = 0; ti < CurrentProcess->NumberOfThreads; ti++)
@ -175,37 +242,37 @@ int main()
struct waitres *waitt;
char szWindowName[30] = {" "};
ptime = CurrentProcess->TH[ti].KernelTime;
ptime = CurrentProcess->Threads[ti].KernelTime;
thour = (ptime.QuadPart / (10000000LL * 3600LL));
tmin = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
tsec = (ptime.QuadPart / 10000000LL) % 60LL;
ptime = CurrentProcess->TH[ti].UserTime;
ptime = CurrentProcess->Threads[ti].UserTime;
thour1 = (ptime.QuadPart / (10000000LL * 3600LL));
tmin1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
tsec1 = (ptime.QuadPart / 10000000LL) % 60LL;
statt = thread_stat;
while (statt->state != CurrentProcess->TH[ti].ThreadState && statt->state >= 0)
while (statt->state != CurrentProcess->Threads[ti].ThreadState && statt->state >= 0)
statt++;
waitt = waitreason;
while (waitt->state != CurrentProcess->TH[ti].WaitReason && waitt->state >= 0)
while (waitt->state != CurrentProcess->Threads[ti].WaitReason && waitt->state >= 0)
waitt++;
wsprintf (buf1,
wsprintf (buf1,
"t% %8d %3d:%02d:%02d %3d:%02d:%02d %s %s\n",
CurrentProcess->TH[ti].ClientId.UniqueThread,
CurrentProcess->Threads[ti].ClientId.UniqueThread,
thour, tmin, tsec, thour1, tmin1, tsec1,
statt->desc , waitt->desc);
WriteFile(stdout, buf1, lstrlen(buf1), &r, NULL);
EnumThreadWindows((DWORD)CurrentProcess->TH[ti].ClientId.UniqueThread,
EnumThreadWindows((DWORD)CurrentProcess->Threads[ti].ClientId.UniqueThread,
(ENUMWINDOWSPROC) EnumThreadProc,
(LPARAM)(LPTSTR) szWindowName );
}
CurrentProcess = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)CurrentProcess +
CurrentProcess = (PSYSTEM_PROCESSES)((ULONG_PTR)CurrentProcess +
CurrentProcess->NextEntryOffset);
}
}
return (0);
}

View file

@ -1715,7 +1715,7 @@ DetectKeyboardPeripheral(FRLDRHKEY ControllerKey)
/* Set 'Identifier' value */
strcpy(Buffer,
"PCAT_ENHANCED");
Error = RegSetValue(ControllerKey,
Error = RegSetValue(PeripheralKey,
"Identifier",
REG_SZ,
Buffer,

View file

@ -205,9 +205,27 @@ BOOL i386DiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLON
{
// Partition requested was zero which means the boot partition
if (! DiskGetActivePartitionEntry(i386BootDrive, &PartitionTableEntry))
{
/* Try partition-less disk */
*StartSector = 0;
*SectorCount = 0;
}
/* Check for valid partition */
else if (PartitionTableEntry.SystemIndicator == PARTITION_ENTRY_UNUSED)
{
return FALSE;
}
else
{
*StartSector = PartitionTableEntry.SectorCountBeforePartition;
*SectorCount = PartitionTableEntry.PartitionSectorCount;
}
}
else if (0xff == i386BootPartition)
{
/* Partition-less disk */
*StartSector = 0;
*SectorCount = 0;
}
else
{
@ -216,25 +234,26 @@ BOOL i386DiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLON
{
return FALSE;
}
}
// Check for valid partition
if (PartitionTableEntry.SystemIndicator == PARTITION_ENTRY_UNUSED)
{
return FALSE;
/* Check for valid partition */
else if (PartitionTableEntry.SystemIndicator == PARTITION_ENTRY_UNUSED)
{
return FALSE;
}
else
{
*StartSector = PartitionTableEntry.SectorCountBeforePartition;
*SectorCount = PartitionTableEntry.PartitionSectorCount;
}
}
// Try to recognize the file system
if (!FsRecognizeVolume(i386BootDrive, PartitionTableEntry.SectorCountBeforePartition, &VolumeType))
if (!FsRecognizeVolume(i386BootDrive, *StartSector, &VolumeType))
{
return FALSE;
}
*DriveNumber = i386BootDrive;
*StartSector = PartitionTableEntry.SectorCountBeforePartition;
*SectorCount = PartitionTableEntry.PartitionSectorCount;
//switch (PartitionTableEntry.SystemIndicator)
switch (VolumeType)
{
case PARTITION_FAT_12:

View file

@ -63,12 +63,12 @@ BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY Parti
// Make sure there was only one bootable partition
if (BootablePartitionCount == 0)
{
DiskError("No bootable (active) partitions found.", 0);
DbgPrint((DPRINT_DISK, "No bootable (active) partitions found.\n"));
return FALSE;
}
else if (BootablePartitionCount != 1)
{
DiskError("Too many bootable (active) partitions found.", 0);
DbgPrint((DPRINT_DISK, "Too many bootable (active) partitions found.\n"));
return FALSE;
}

View file

@ -35,7 +35,7 @@ VOID BootMain(char *CmdLine)
DebugInit();
DbgPrint((DPRINT_WARNING, "BootMain() called. BootDrive = 0x%x BootPartition = %d\n", BootDrive, BootPartition));
DbgPrint((DPRINT_WARNING, "BootMain() called.\n"));
if (!MmInitializeMemoryManager())
{

View file

@ -36,10 +36,30 @@ VOID DecrementAllocationCount(VOID);
VOID MemAllocTest(VOID);
#endif // DEBUG
/*
* Hack alert
* Normally, we allocate whole pages. This is ofcourse wastefull for small
* allocations (a few bytes). So, for small allocations (smaller than a page)
* we sub-allocate. When the first small allocation is done, a page is
* requested. We keep a pointer to that page in SubAllocationPage. The alloc
* is satisfied by returning a pointer to the beginning of the page. We also
* keep track of how many bytes are still available in the page in SubAllocationRest.
* When the next small request comes in, we try to allocate it just after the
* memory previously allocated. If it won't fit, we allocate a new page and
* the whole process starts again.
* Note that suballocations are done back-to-back, there's no bookkeeping at all.
* That also means that we cannot really free suballocations. So, when a free is
* done and it is determined that this might be a free of a sub-allocation, we
* just no-op the free.
* Perhaps we should use the heap routines from ntdll here.
*/
static PVOID SubAllocationPage = NULL;
static unsigned SubAllocationRest = 0;
PVOID MmAllocateMemory(ULONG MemorySize)
{
ULONG PagesNeeded;
ULONG FirstFreePageFromEnd;
ULONG PagesNeeded;
ULONG FirstFreePageFromEnd;
PVOID MemPointer;
if (MemorySize == 0)
@ -49,6 +69,14 @@ PVOID MmAllocateMemory(ULONG MemorySize)
return NULL;
}
MemorySize = ROUND_UP(MemorySize, 4);
if (MemorySize <= SubAllocationRest)
{
MemPointer = SubAllocationPage + MM_PAGE_SIZE - SubAllocationRest;
SubAllocationRest -= MemorySize;
return MemPointer;
}
// Find out how many blocks it will take to
// satisfy this allocation
PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
@ -76,6 +104,13 @@ PVOID MmAllocateMemory(ULONG MemorySize)
FreePagesInLookupTable -= PagesNeeded;
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
if (MemorySize < MM_PAGE_SIZE)
{
SubAllocationPage = MemPointer;
SubAllocationRest = MM_PAGE_SIZE - MemorySize;
}
#ifdef DEBUG
IncrementAllocationCount();
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, FirstFreePageFromEnd, AllocationCount));
@ -235,6 +270,13 @@ VOID MmFreeMemory(PVOID MemoryPointer)
#endif
/* If this allocation is only a single page, it could be a sub-allocated page.
* Just don't free it */
if (1 == PageCount)
{
return;
}
// Loop through our array and mark all the
// blocks as free
for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)

View file

@ -756,6 +756,16 @@ LoadAndBootReactOS(PCHAR OperatingSystemName)
if (!FrLdrLoadDriver(szHalName, 10))
return;
#if 0
/* Load bootvid */
strcpy(value, "INBV.DLL");
strcpy(szHalName, szBootPath);
strcat(szHalName, "SYSTEM32\\");
strcat(szHalName, value);
if (!FrLdrLoadDriver(szHalName, 10))
return;
#endif
/*
* Load the System hive from disk
*/

View file

@ -34,7 +34,7 @@
#include "registry.h"
//#define USE_UI
#define USE_UI
static BOOL
@ -88,7 +88,7 @@ LoadKernel(PCHAR szSourcePath, PCHAR szFileName)
* Update the status bar with the current file
*/
#ifdef USE_UI
sprintf(szBuffer, "Reading %s", szShortName);
sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
UiDrawStatusText(szBuffer);
#else
printf("Reading %s\n", szShortName);
@ -155,7 +155,7 @@ LoadDriver(PCHAR szSourcePath, PCHAR szFileName)
* Update the status bar with the current file
*/
#ifdef USE_UI
sprintf(szBuffer, "Reading %s", szShortName);
sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
UiDrawStatusText(szBuffer);
#else
printf("Reading %s\n", szShortName);
@ -220,7 +220,7 @@ LoadNlsFile(PCHAR szSourcePath, PCHAR szFileName, PCHAR szModuleName)
* Update the status bar with the current file
*/
#ifdef USE_UI
sprintf(szBuffer, "Reading %s", szShortName);
sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
UiDrawStatusText(szBuffer);
#else
printf("Reading %s\n", szShortName);
@ -232,6 +232,7 @@ LoadNlsFile(PCHAR szSourcePath, PCHAR szFileName, PCHAR szModuleName)
return(TRUE);
}
BOOL SetupUiInitialize(VOID);
VOID RunLoader(VOID)
{
@ -294,7 +295,7 @@ VOID RunLoader(VOID)
#endif
#ifdef USE_UI
UiInitialize();
SetupUiInitialize();
UiDrawStatusText("");
#endif

View file

@ -27,6 +27,7 @@
#include <inifile.h>
#include <version.h>
#include <video.h>
#include <reactos/buildno.h>
ULONG UiScreenWidth = 80; // Screen Width
ULONG UiScreenHeight = 25; // Screen Height
@ -196,6 +197,39 @@ BOOL UiInitialize(BOOLEAN ShowGui)
UserInterfaceUp = TRUE;
DbgPrint((DPRINT_UI, "UiInitialize() returning TRUE.\n"));
return TRUE;
}
BOOL SetupUiInitialize(VOID)
{
CHAR DisplayModeText[260];
ULONG Depth;
DisplayModeText[0] = '\0';
UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
TuiInitialize();
// Draw the backdrop and fade it in if special effects are enabled
TuiFillArea(0,
0,
UiScreenWidth - 1,
UiScreenHeight - 2,
0,
ATTR(UiBackdropFgColor, UiBackdropBgColor));
UiStatusBarBgColor = 7;
UserInterfaceUp = TRUE;
TuiDrawText(4, 1, "ReactOS " KERNEL_VERSION_STR " Setup", ATTR(COLOR_GRAY, UiBackdropBgColor));
TuiDrawText(3, 2, "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD", ATTR(COLOR_GRAY, UiBackdropBgColor));
DbgPrint((DPRINT_UI, "UiInitialize() returning TRUE.\n"));
return TRUE;

View file

@ -46,6 +46,9 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E975-E325-11CE-BFC1-08002BE103
HKLM,"SYSTEM\CurrentControlSet\Control\ComputerName",,0x00000012
HKLM,"SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName","ComputerName",0x00000002,"COMPUTERNAME"
; Device classes key
HKLM,"SYSTEM\CurrentControlSet\Control\DeviceClasses",,0x00000012
; Hardware profile settings
HKLM,"SYSTEM\CurrentControlSet\Control\IDConfigDB",,0x00000012
HKLM,"SYSTEM\CurrentControlSet\Control\IDConfigDB","CurrentConfig",0x00010001,0x00000000
@ -529,7 +532,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Class2","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\DebugOut","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\DebugOut","Group",0x00000000,"Debug"
HKLM,"SYSTEM\CurrentControlSet\Services\DebugOut","ImagePath",0x00020000,"system32\drivers\debugout.sys"
HKLM,"SYSTEM\CurrentControlSet\Services\DebugOut","Start",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\DebugOut","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\DebugOut","Type",0x00010001,0x00000001
; Disk class driver
@ -675,7 +678,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ErrorControl",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Group",0x00000000,"NDIS"
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ImagePath",0x00020000,"system32\drivers\ne2000.sys"
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Start",0x00010001,0x00000003
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Route",0x00000000,"Ne20001"
@ -687,8 +690,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE103
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001\Linkage","Export",0x00000000,"\Device\Ne20001"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001\Linkage","RootDevice",0x00000000,"Ne20001"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001\Linkage","UpperBind",0x00000000,"Tcpip"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001","Port",0x00000000,"280"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001","Irq",0x00000000,"9"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001","Port",0x00000000,"c100"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001","Irq",0x00000000,"B"
HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0001","NetworkAddress",0x00000000,"001122334455"
HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","DefaultGateway",0x00010000,"0.0.0.0"
HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","IPAddress",0x00010000,"0.0.0.0"
@ -926,6 +929,12 @@ HKLM,"SYSTEM\CurrentControlSet\Services\VBE","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\VBE","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\VBE\Device0","InstalledDisplayDrivers",0x00010000,"framebuf"
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\VBE\Device0","DefaultSettings.VRefresh",0x00010001,1
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\VBE\Device0","DefaultSettings.BitsPerPel",0x00010001,8
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\VBE\Device0","DefaultSettings.XResolution",0x00010001,640
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\VBE\Device0","DefaultSettings.YResolution",0x00010001,480
; VGA miniport driver
HKLM,"SYSTEM\CurrentControlSet\Services\Vga","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Group",0x00000000,"Video Save"
@ -934,6 +943,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Vga\Device0","InstalledDisplayDrivers",0x00010000,"vgaddi"
; VMware SVGA driver
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Group",0x00000000,"Video"

View file

@ -16,7 +16,7 @@ Signature = "$ReactOS$"
1 = system32
2 = system32\drivers
3 = media\fonts
4 = .
4 =
5 = system32\drivers\etc
6 = inf

View file

@ -162,7 +162,7 @@ DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
DbgPrint("Advanced Configuration and Power Interface Bus Driver\n");
DPRINT("Advanced Configuration and Power Interface Bus Driver\n");
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) ACPIDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH) ACPIPnpControl;

View file

@ -119,12 +119,16 @@ AcpiCreateInstanceIDString(PUNICODE_STRING InstanceID,
static BOOLEAN
AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList,
PULONG ResourceListSize,
PIO_RESOURCE_REQUIREMENTS_LIST* pRequirementsList,
PULONG RequirementsListSize,
RESOURCE* resources)
{
BOOLEAN Done;
ULONG NumberOfResources = 0;
PCM_RESOURCE_LIST ResourceList;
PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
PIO_RESOURCE_DESCRIPTOR RequirementDescriptor;
RESOURCE* resource;
ULONG i;
KIRQL Dirql;
@ -176,6 +180,24 @@ AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList,
ResourceList->List[0].PartialResourceList.Count = NumberOfResources;
ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
*RequirementsListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + sizeof(IO_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1);
RequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePool(PagedPool, *RequirementsListSize);
*pRequirementsList = RequirementsList;
if (!RequirementsList)
{
ExFreePool(ResourceList);
return FALSE;
}
RequirementsList->ListSize = *RequirementsListSize;
RequirementsList->InterfaceType = ResourceList->List[0].InterfaceType;
RequirementsList->BusNumber = ResourceList->List[0].BusNumber;
RequirementsList->SlotNumber = 0; /* Not used by WDM drivers */
RequirementsList->AlternativeLists = 1;
RequirementsList->List[0].Version = 1;
RequirementsList->List[0].Revision = 1;
RequirementsList->List[0].Count = NumberOfResources;
RequirementDescriptor = RequirementsList->List[0].Descriptors;
/* Fill resources list structure */
Done = FALSE;
resource = resources;
@ -199,7 +221,16 @@ AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList,
&Dirql,
&ResourceDescriptor->u.Interrupt.Affinity);
ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
RequirementDescriptor->Option = 0; /* Required */
RequirementDescriptor->Type = ResourceDescriptor->Type;
RequirementDescriptor->ShareDisposition = ResourceDescriptor->ShareDisposition;
RequirementDescriptor->Flags = ResourceDescriptor->Flags;
RequirementDescriptor->u.Interrupt.MinimumVector = RequirementDescriptor->u.Interrupt.MaximumVector
= irq_data->interrupts[i];
ResourceDescriptor++;
RequirementDescriptor++;
}
break;
}
@ -225,7 +256,16 @@ AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList,
case TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break;
}
ResourceDescriptor->u.Dma.Channel = dma_data->channels[i];
RequirementDescriptor->Option = 0; /* Required */
RequirementDescriptor->Type = ResourceDescriptor->Type;
RequirementDescriptor->ShareDisposition = ResourceDescriptor->ShareDisposition;
RequirementDescriptor->Flags = ResourceDescriptor->Flags;
RequirementDescriptor->u.Dma.MinimumChannel = RequirementDescriptor->u.Dma.MaximumChannel
= ResourceDescriptor->u.Dma.Channel;
ResourceDescriptor++;
RequirementDescriptor++;
}
break;
}
@ -242,7 +282,18 @@ AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList,
ResourceDescriptor->u.Port.Start.u.HighPart = 0;
ResourceDescriptor->u.Port.Start.u.LowPart = io_data->min_base_address;
ResourceDescriptor->u.Port.Length = io_data->range_length;
RequirementDescriptor->Option = 0; /* Required */
RequirementDescriptor->Type = ResourceDescriptor->Type;
RequirementDescriptor->ShareDisposition = ResourceDescriptor->ShareDisposition;
RequirementDescriptor->Flags = ResourceDescriptor->Flags;
RequirementDescriptor->u.Port.Length = ResourceDescriptor->u.Port.Length;
RequirementDescriptor->u.Port.Alignment = 1; /* Start address is specified, so it doesn't matter */
RequirementDescriptor->u.Port.MinimumAddress = RequirementDescriptor->u.Port.MaximumAddress
= ResourceDescriptor->u.Port.Start;
ResourceDescriptor++;
RequirementDescriptor++;
break;
}
case end_tag:
@ -366,6 +417,8 @@ FdoQueryBusRelations(
}
if (!AcpiCreateResourceList(&PdoDeviceExtension->ResourceList,
&PdoDeviceExtension->ResourceListSize,
&PdoDeviceExtension->ResourceRequirementsList,
&PdoDeviceExtension->ResourceRequirementsListSize,
(RESOURCE*)Buffer.pointer))
{
ASSERT(FALSE);
@ -573,7 +626,9 @@ FdoStartDevice(
}
}
#ifndef NDEBUG
ACPIPrintInfo(DeviceExtension);
#endif
/* Initialize ACPI bus manager */
AcpiStatus = bm_initialize();

View file

@ -50,6 +50,9 @@ typedef struct _PDO_DEVICE_EXTENSION
// Resource list
PCM_RESOURCE_LIST ResourceList;
ULONG ResourceListSize;
// Requirement list
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
ULONG ResourceRequirementsListSize;
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;

View file

@ -98,7 +98,7 @@ acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args)
static char Buffer[512];
LONG Size = vsprintf(Buffer, fmt, args);
DbgPrint("%s", Buffer);
DPRINT("%s", Buffer);
return Size;
}

View file

@ -107,6 +107,35 @@ PdoQueryId(
}
static NTSTATUS
PdoQueryResourceRequirements(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (DeviceExtension->ResourceRequirementsListSize == 0)
{
return Irp->IoStatus.Status;
}
ResourceRequirementsList = ExAllocatePool(PagedPool, DeviceExtension->ResourceRequirementsListSize);
if (!ResourceRequirementsList)
{
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(ResourceRequirementsList, DeviceExtension->ResourceRequirementsList, DeviceExtension->ResourceRequirementsListSize);
Irp->IoStatus.Information = (ULONG_PTR)ResourceRequirementsList;
return STATUS_SUCCESS;
}
static NTSTATUS
PdoQueryResources(
IN PDEVICE_OBJECT DeviceObject,
@ -227,6 +256,9 @@ PdoPnpControl(
break;
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
Status = PdoQueryResourceRequirements(DeviceObject,
Irp,
IrpSp);
break;
case IRP_MN_QUERY_RESOURCES:

View file

@ -172,7 +172,7 @@ DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
DbgPrint("Peripheral Component Interconnect Bus Driver\n");
DPRINT("Peripheral Component Interconnect Bus Driver\n");
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = PciPnpControl;

View file

@ -409,6 +409,8 @@ PdoQueryResourceRequirements(
ResourceList->ListSize = ListSize;
ResourceList->InterfaceType = PCIBus;
ResourceList->BusNumber = DeviceExtension->BusNumber,
ResourceList->SlotNumber = DeviceExtension->SlotNumber.u.AsULONG,
ResourceList->AlternativeLists = 1;
ResourceList->List[0].Version = 1;
@ -433,7 +435,7 @@ PdoQueryResourceRequirements(
if (Length == 0)
{
DPRINT("Unused address register\n");
break;
continue;
}
/* Set preferred descriptor */
@ -497,6 +499,7 @@ PdoQueryResourceRequirements(
if (PciConfig.u.type0.InterruptPin != 0)
{
Descriptor->Option = 0; /* Required */
Descriptor->Type = CmResourceTypeInterrupt;
Descriptor->ShareDisposition = CmResourceShareShared;
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
@ -522,7 +525,7 @@ PdoQueryResourceRequirements(
if (Length == 0)
{
DPRINT("Unused address register\n");
break;
continue;
}
/* Set preferred descriptor */
@ -722,7 +725,7 @@ PdoQueryResources(
if (Length == 0)
{
DPRINT("Unused address register\n");
break;
continue;
}
if (Flags & PCI_ADDRESS_IO_SPACE)
@ -776,7 +779,7 @@ PdoQueryResources(
if (Length == 0)
{
DPRINT("Unused address register\n");
break;
continue;
}
if (Flags & PCI_ADDRESS_IO_SPACE)

View file

@ -83,12 +83,13 @@ DetectLegacyDevice(
{
ULONG ResourceListSize;
PCM_RESOURCE_LIST ResourceList;
PCM_RESOURCE_LIST ResourceListTranslated;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptorTranslated;
BOOLEAN ConflictDetected;
UART_TYPE UartType;
PDEVICE_OBJECT Pdo = NULL;
PDEVICE_OBJECT Fdo;
KIRQL Dirql;
NTSTATUS Status;
/* Create resource list */
@ -96,29 +97,60 @@ DetectLegacyDevice(
ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
if (!ResourceList)
return STATUS_INSUFFICIENT_RESOURCES;
ResourceList->Count = 1;
ResourceList->List[0].InterfaceType = InterfaceTypeUndefined;
ResourceList->List[0].BusNumber = -1; /* unknown */
ResourceList->List[0].PartialResourceList.Version = 1;
ResourceList->List[0].PartialResourceList.Revision = 1;
ResourceList->List[0].PartialResourceList.Count = 2;
ResourceListTranslated = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
if (!ResourceListTranslated)
{
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Resource header */
ResourceList->Count = ResourceListTranslated->Count
= 1;
ResourceList->List[0].InterfaceType = ResourceListTranslated->List[0].InterfaceType
= InterfaceTypeUndefined;
ResourceList->List[0].BusNumber = ResourceListTranslated->List[0].BusNumber
= -1; /* unknown */
ResourceList->List[0].PartialResourceList.Version = ResourceListTranslated->List[0].PartialResourceList.Version
= 1;
ResourceList->List[0].PartialResourceList.Revision = ResourceListTranslated->List[0].PartialResourceList.Revision
= 1;
ResourceList->List[0].PartialResourceList.Count = ResourceListTranslated->List[0].PartialResourceList.Count
= 2;
/* I/O port */
ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
ResourceDescriptor->Type = CmResourceTypePort;
ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
ResourceDescriptor->u.Port.Start.u.HighPart = 0;
ResourceDescriptor->u.Port.Start.u.LowPart = ComPortBase;
ResourceDescriptor->u.Port.Length = 8;
ResourceDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[0];
ResourceDescriptor->Type = ResourceDescriptorTranslated->Type
= CmResourceTypePort;
ResourceDescriptor->ShareDisposition = ResourceDescriptorTranslated->ShareDisposition
= CmResourceShareDriverExclusive;
ResourceDescriptor->Flags = ResourceDescriptorTranslated->Flags
= CM_RESOURCE_PORT_IO;
ResourceDescriptor->u.Port.Start.u.HighPart = ResourceDescriptorTranslated->u.Port.Start.u.HighPart
= 0;
ResourceDescriptor->u.Port.Start.u.LowPart = ResourceDescriptorTranslated->u.Port.Start.u.LowPart
= ComPortBase;
ResourceDescriptor->u.Port.Length = ResourceDescriptorTranslated->u.Port.Length
= 8;
ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];
ResourceDescriptor->Type = CmResourceTypeInterrupt;
ResourceDescriptor->ShareDisposition = CmResourceShareShared;
ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(
Internal, 0, 0, Irq,
&Dirql,
ResourceDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[1];
ResourceDescriptor->Type = ResourceDescriptorTranslated->Type
= CmResourceTypeInterrupt;
ResourceDescriptor->ShareDisposition = ResourceDescriptorTranslated->ShareDisposition
= CmResourceShareShared;
ResourceDescriptor->Flags = ResourceDescriptorTranslated->Flags
= CM_RESOURCE_INTERRUPT_LATCHED;
ResourceDescriptor->u.Interrupt.Level = Irq;
ResourceDescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
ResourceList->List[0].InterfaceType,
ResourceList->List[0].BusNumber,
ResourceDescriptor->u.Interrupt.Level,
ResourceDescriptor->u.Interrupt.Vector,
(PKIRQL)&ResourceDescriptorTranslated->u.Interrupt.Level,
&ResourceDescriptor->u.Interrupt.Affinity);
ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
ResourceDescriptorTranslated->u.Interrupt.Affinity = ResourceDescriptor->u.Interrupt.Affinity;
/* Report resource list */
Status = IoReportResourceForDetection(
@ -129,11 +161,13 @@ DetectLegacyDevice(
{
DPRINT("Serial: conflict detected for serial port at 0x%lx (Irq %lu)\n", ComPortBase, Irq);
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
return STATUS_DEVICE_NOT_CONNECTED;
}
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
return Status;
}
@ -154,7 +188,7 @@ DetectLegacyDevice(
Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);
if (NT_SUCCESS(Status))
{
Status = SerialPnpStartDevice(Fdo, ResourceList);
Status = SerialPnpStartDevice(Fdo, ResourceList, ResourceListTranslated);
}
}
}
@ -168,6 +202,7 @@ DetectLegacyDevice(
Status = STATUS_DEVICE_NOT_CONNECTED;
}
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
return Status;
}

View file

@ -126,7 +126,8 @@ SerialAddDevice(
NTSTATUS STDCALL
SerialPnpStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PCM_RESOURCE_LIST ResourceList)
IN PCM_RESOURCE_LIST ResourceList,
IN PCM_RESOURCE_LIST ResourceListTranslated)
{
PSERIAL_DEVICE_EXTENSION DeviceExtension;
WCHAR DeviceNameBuffer[32];
@ -174,8 +175,8 @@ SerialPnpStartDevice(
case CmResourceTypeInterrupt:
if (Dirql != 0)
return STATUS_UNSUCCESSFUL;
Dirql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
Vector = PartialDescriptor->u.Interrupt.Vector;
Dirql = (KIRQL)ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Level;
Vector = ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Vector;
Affinity = PartialDescriptor->u.Interrupt.Affinity;
if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
InterruptMode = Latched;
@ -338,16 +339,9 @@ SerialPnp(
BOOLEAN ConflictDetected;
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
/* FIXME: first HACK: PnP manager can send multiple
* IRP_MN_START_DEVICE for one device
*/
if (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState != dsStopped)
{
DPRINT1("Serial: device already started. Ignoring this irp!\n");
Status = STATUS_SUCCESS;
break;
}
/* FIXME: second HACK: verify that we have some allocated resources.
ASSERT(((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState == dsStopped);
/* FIXME: HACK: verify that we have some allocated resources.
* It seems not to be always the case on some hardware
*/
if (Stack->Parameters.StartDevice.AllocatedResources == NULL)
@ -357,7 +351,7 @@ SerialPnp(
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
/* FIXME: third HACK: verify that we don't have resource conflict,
/* FIXME: HACK: verify that we don't have resource conflict,
* because PnP manager doesn't do it automatically
*/
Status = IoReportResourceForDetection(
@ -377,7 +371,8 @@ SerialPnp(
if (NT_SUCCESS(Status))
Status = SerialPnpStartDevice(
DeviceObject,
Stack->Parameters.StartDevice.AllocatedResources);
Stack->Parameters.StartDevice.AllocatedResources,
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
break;
}
case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */

View file

@ -327,7 +327,8 @@ SerialAddDevice(
NTSTATUS STDCALL
SerialPnpStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PCM_RESOURCE_LIST ResourceList);
IN PCM_RESOURCE_LIST ResourceList,
IN PCM_RESOURCE_LIST ResourceListTranslated);
NTSTATUS STDCALL
SerialPnp(

View file

@ -96,7 +96,7 @@ NpfsSignalAndRemoveListeningServerInstance(PNPFS_PIPE Pipe,
RemoveEntryList(&Waiter->Entry);
Irp = CONTAINING_RECORD(Waiter, IRP, Tail.Overlay.DriverContext);
Irp->IoStatus.Status = STATUS_PIPE_CONNECTED;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;

View file

@ -86,7 +86,7 @@ typedef struct _I8042_SETTINGS
DWORD OverrideKeyboardType;
DWORD OverrideKeyboardSubtype;
DWORD MouseResendStallTime;
DWORD MouseSynchIn100ns;
DWORD MouseSynchIn100ns; /* done */
DWORD MouseResolution; /* done */
DWORD NumberOfButtons;
DWORD EnableWheelDetection;
@ -169,6 +169,7 @@ typedef struct _DEVICE_EXTENSION
MOUSE_INPUT_DATA *MouseBuffer;
ULONG MouseInBuffer;
USHORT MouseButtonState;
ULARGE_INTEGER MousePacketStartTime;
UCHAR MouseLogiBuffer[3];
UCHAR MouseLogitechID;

View file

@ -113,7 +113,7 @@ BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt,
} while (Iterations < DevExt->Settings.PollStatusIterations);
if (STATUS_SUCCESS != Status) {
DPRINT1("Spurious I8042 interrupt\n");
DPRINT("Spurious I8042 interrupt\n");
return FALSE;
}

View file

@ -45,6 +45,39 @@ NTSTATUS STDCALL I8042SynchWritePortMouse(PVOID Context,
WaitForAck);
}
/* Test if packets are taking too long to come in. If they do, we
* might have gotten out of sync and should just drop what we have.
*
* If we want to be totally right, we'd also have to keep a count of
* errors, and totally reset the mouse after too much of them (can
* happen if the user is using a KVM switch and an OS on another port
* resets the mouse, or if the user hotplugs the mouse, or if we're just
* generally unlucky). Also note the input parsing routine where we
* drop invalid input packets.
*/
static VOID STDCALL I8042MouseInputTestTimeout(PDEVICE_EXTENSION DevExt)
{
ULARGE_INTEGER Now;
if (DevExt->MouseState == MouseExpectingACK ||
DevExt->MouseState == MouseResetting)
return;
Now.QuadPart = KeQueryInterruptTime();
if (DevExt->MouseState != MouseIdle) {
/* Check if the last byte came too long ago */
if (Now.QuadPart - DevExt->MousePacketStartTime.QuadPart >
DevExt->Settings.MouseSynchIn100ns) {
DPRINT1("Mouse input packet timeout\n");
DevExt->MouseState = MouseIdle;
}
}
if (DevExt->MouseState == MouseIdle)
DevExt->MousePacketStartTime.QuadPart = Now.QuadPart;
}
/*
* Call the customization hook. The Ret2 parameter is about wether
* we should go on with the interrupt. The return value is what
@ -301,7 +334,7 @@ BOOLEAN STDCALL I8042MouseResetIsr(PDEVICE_EXTENSION DevExt,
case ExpectingFinalResolutionACK:
I8042IsrWritePortMouse(DevExt,
DevExt->Settings.MouseResolution & 0xff);
DPRINT1("%x\n", DevExt->Settings.MouseResolution);
DPRINT("%x\n", DevExt->Settings.MouseResolution);
DevExt->MouseResetState = ExpectingFinalResolutionValueACK;
return TRUE;
case ExpectingFinalResolutionValueACK:
@ -517,6 +550,8 @@ BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt,
return TRUE;
}
I8042MouseInputTestTimeout(DevExt);
if (I8042MouseResetIsr(DevExt, PortStatus, &Output)) {
DPRINT("Handled by ResetIsr or hooked Isr\n");
if (NoChange != DevExt->MouseTimeoutState) {

View file

@ -141,7 +141,7 @@ AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
}
/* MmUnlockPages( Mdl ); */
IoFreeMdl( Mdl );
/* IoFreeMdl( Mdl ); */
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}

View file

@ -10,6 +10,7 @@
#include <ndissys.h>
struct _ADAPTER_BINDING;
typedef struct _HARDWARE_ADDRESS {
union {
@ -77,9 +78,9 @@ typedef struct _LOGICAL_ADAPTER
KDPC MiniportDpc; /* DPC routine for adapter */
BOOLEAN MiniportBusy; /* A MiniportXxx routine is executing */
ULONG WorkQueueLevel; /* Number of used work item buffers */
NDIS_MINIPORT_WORK_ITEM WorkQueue[NDIS_MINIPORT_WORK_QUEUE_SIZE];
PNDIS_MINIPORT_WORK_ITEM WorkQueueHead; /* Head of work queue */
PNDIS_MINIPORT_WORK_ITEM WorkQueueTail; /* Tail of work queue */
INTERNAL_NDIS_MINIPORT_WORK_ITEM WorkQueue[NDIS_MINIPORT_WORK_QUEUE_SIZE];
PINTERNAL_NDIS_MINIPORT_WORK_ITEM WorkQueueHead; /* Head of work queue */
PINTERNAL_NDIS_MINIPORT_WORK_ITEM WorkQueueTail; /* Tail of work queue */
LIST_ENTRY ListEntry; /* Entry on global list */
LIST_ENTRY MiniportListEntry; /* Entry on miniport driver list */
LIST_ENTRY ProtocolListHead; /* List of bound protocols */
@ -145,7 +146,7 @@ MiniQueryInformation(
NDIS_STATUS
FASTCALL
MiniQueueWorkItem(
PLOGICAL_ADAPTER Adapter,
struct _ADAPTER_BINDING *AdapterBinding,
NDIS_WORK_ITEM_TYPE WorkItemType,
PVOID WorkItemContext);
@ -153,12 +154,13 @@ NDIS_STATUS
FASTCALL
MiniDequeueWorkItem(
PLOGICAL_ADAPTER Adapter,
struct _ADAPTER_BINDING **AdapterBinding,
NDIS_WORK_ITEM_TYPE *WorkItemType,
PVOID *WorkItemContext);
NDIS_STATUS
MiniDoRequest(
PLOGICAL_ADAPTER Adapter,
struct _ADAPTER_BINDING *AdapterBinding,
PNDIS_REQUEST NdisRequest);
BOOLEAN

View file

@ -27,6 +27,14 @@ typedef struct _ATM_ADDRESS *PATM_ADDRESS;
#include <ddk/ntapi.h>
#endif /* _MSC_VER */
struct _ADAPTER_BINDING;
typedef struct _INTERNAL_NDIS_MINIPORT_WORK_ITEM {
SINGLE_LIST_ENTRY Link;
struct _ADAPTER_BINDING *AdapterBinding;
NDIS_MINIPORT_WORK_ITEM RealWorkItem;
} INTERNAL_NDIS_MINIPORT_WORK_ITEM, *PINTERNAL_NDIS_MINIPORT_WORK_ITEM;
#include "miniport.h"
#include "protocol.h"

View file

@ -327,6 +327,23 @@ MiniResetComplete(
}
VOID STDCALL
MiniRequestComplete(
IN PADAPTER_BINDING AdapterBinding,
IN PNDIS_REQUEST Request,
IN NDIS_STATUS Status)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
if( AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler ) {
(*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
AdapterBinding->NdisOpenBlock.NdisCommonOpenBlock.ProtocolBindingContext,
Request,
Status);
}
}
VOID STDCALL
MiniSendComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
@ -615,7 +632,7 @@ MiniQueryInformation(
NDIS_STATUS
FASTCALL
MiniQueueWorkItem(
PLOGICAL_ADAPTER Adapter,
PADAPTER_BINDING AdapterBinding,
NDIS_WORK_ITEM_TYPE WorkItemType,
PVOID WorkItemContext)
/*
@ -630,49 +647,51 @@ MiniQueueWorkItem(
* Status of operation
*/
{
PNDIS_MINIPORT_WORK_ITEM Item;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
ASSERT(Adapter);
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
PINTERNAL_NDIS_MINIPORT_WORK_ITEM Item;
PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
ASSERT(Adapter);
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
#if 0
if (Adapter->WorkQueueLevel < NDIS_MINIPORT_WORK_QUEUE_SIZE - 1)
if (Adapter->WorkQueueLevel < NDIS_MINIPORT_WORK_QUEUE_SIZE - 1)
{
Item = &Adapter->WorkQueue[Adapter->WorkQueueLevel];
Adapter->WorkQueueLevel++;
Item = &Adapter->WorkQueue[Adapter->WorkQueueLevel];
Adapter->WorkQueueLevel++;
}
else
else
#endif
{
Item = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM));
if (Item == NULL)
Item = ExAllocatePool(NonPagedPool, sizeof(INTERNAL_NDIS_MINIPORT_WORK_ITEM));
if (Item == NULL)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
}
}
Item->WorkItemType = WorkItemType;
Item->WorkItemContext = WorkItemContext;
/* safe due to adapter lock held */
Item->Link.Next = NULL;
if (!Adapter->WorkQueueHead)
Item->AdapterBinding = AdapterBinding;
Item->RealWorkItem.WorkItemType = WorkItemType;
Item->RealWorkItem.WorkItemContext = WorkItemContext;
/* safe due to adapter lock held */
Item->Link.Next = NULL;
if (!Adapter->WorkQueueHead)
{
Adapter->WorkQueueHead = Item;
Adapter->WorkQueueTail = Item;
Adapter->WorkQueueHead = Item;
Adapter->WorkQueueTail = Item;
}
else
else
{
Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item;
Adapter->WorkQueueTail = Item;
Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item;
Adapter->WorkQueueTail = Item;
}
KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
return NDIS_STATUS_SUCCESS;
KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
return NDIS_STATUS_SUCCESS;
}
@ -680,12 +699,14 @@ NDIS_STATUS
FASTCALL
MiniDequeueWorkItem(
PLOGICAL_ADAPTER Adapter,
PADAPTER_BINDING *AdapterBinding,
NDIS_WORK_ITEM_TYPE *WorkItemType,
PVOID *WorkItemContext)
/*
* FUNCTION: Dequeues a work item from the work queue of a logical adapter
* ARGUMENTS:
* Adapter = Pointer to the logical adapter object to dequeue work item from
* AdapterBinding = Address of buffer for adapter binding for this request
* WorkItemType = Address of buffer for work item type
* WorkItemContext = Address of buffer for pointer to context information
* NOTES:
@ -694,52 +715,55 @@ MiniDequeueWorkItem(
* Status of operation
*/
{
PNDIS_MINIPORT_WORK_ITEM Item;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
Item = Adapter->WorkQueueHead;
if (Item)
PINTERNAL_NDIS_MINIPORT_WORK_ITEM Item;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
Item = Adapter->WorkQueueHead;
if (Item)
{
/* safe due to adapter lock held */
Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)Item->Link.Next;
if (Item == Adapter->WorkQueueTail)
Adapter->WorkQueueTail = NULL;
*WorkItemType = Item->WorkItemType;
*WorkItemContext = Item->WorkItemContext;
ExFreePool(Item);
return NDIS_STATUS_SUCCESS;
/* safe due to adapter lock held */
Adapter->WorkQueueHead = (PINTERNAL_NDIS_MINIPORT_WORK_ITEM)Item->Link.Next;
if (Item == Adapter->WorkQueueTail)
Adapter->WorkQueueTail = NULL;
*AdapterBinding = Item->AdapterBinding;
*WorkItemType = Item->RealWorkItem.WorkItemType;
*WorkItemContext = Item->RealWorkItem.WorkItemContext;
ExFreePool(Item);
return NDIS_STATUS_SUCCESS;
}
return NDIS_STATUS_FAILURE;
return NDIS_STATUS_FAILURE;
}
NDIS_STATUS
MiniDoRequest(
PLOGICAL_ADAPTER Adapter,
PADAPTER_BINDING AdapterBinding,
PNDIS_REQUEST NdisRequest)
/*
* FUNCTION: Sends a request to a miniport
* ARGUMENTS:
* Adapter = Pointer to logical adapter object
* NdisRequest = Pointer to NDIS request structure describing request
* AdapterBinding = Pointer to binding used in the request
* NdisRequest = Pointer to NDIS request structure describing request
* RETURNS:
* Status of operation
*/
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
Adapter->NdisMiniportBlock.MediaRequest = NdisRequest;
switch (NdisRequest->RequestType)
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
Adapter->NdisMiniportBlock.MediaRequest = NdisRequest;
switch (NdisRequest->RequestType)
{
case NdisRequestQueryInformation:
case NdisRequestQueryInformation:
return (*Adapter->Miniport->Chars.QueryInformationHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext,
NdisRequest->DATA.QUERY_INFORMATION.Oid,
@ -748,8 +772,8 @@ MiniDoRequest(
(PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
(PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);
break;
case NdisRequestSetInformation:
case NdisRequestSetInformation:
return (*Adapter->Miniport->Chars.SetInformationHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext,
NdisRequest->DATA.SET_INFORMATION.Oid,
@ -758,8 +782,8 @@ MiniDoRequest(
(PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesRead,
(PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesNeeded);
break;
default:
default:
return NDIS_STATUS_FAILURE;
}
}
@ -800,11 +824,14 @@ VOID STDCALL MiniportDpc(
NDIS_STATUS NdisStatus;
PVOID WorkItemContext;
NDIS_WORK_ITEM_TYPE WorkItemType;
PADAPTER_BINDING AdapterBinding;
PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(DeferredContext);
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
NdisStatus = MiniDequeueWorkItem(Adapter, &WorkItemType, &WorkItemContext);
NdisStatus =
MiniDequeueWorkItem
(Adapter, &AdapterBinding, &WorkItemType, &WorkItemContext);
if (NdisStatus == NDIS_STATUS_SUCCESS)
{
@ -873,7 +900,7 @@ VOID STDCALL MiniportDpc(
break;
case NdisWorkItemRequest:
NdisStatus = MiniDoRequest(Adapter, (PNDIS_REQUEST)WorkItemContext);
NdisStatus = MiniDoRequest(AdapterBinding, (PNDIS_REQUEST)WorkItemContext);
if (NdisStatus == NDIS_STATUS_PENDING)
break;
@ -882,10 +909,12 @@ VOID STDCALL MiniportDpc(
{
case NdisRequestQueryInformation:
NdisMQueryInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
MiniRequestComplete( AdapterBinding, (PNDIS_REQUEST)WorkItemContext, NdisStatus );
break;
case NdisRequestSetInformation:
NdisMSetInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
MiniRequestComplete( AdapterBinding, (PNDIS_REQUEST)WorkItemContext, NdisStatus );
break;
default:

View file

@ -158,7 +158,7 @@ ProRequest(
/* MiniQueueWorkItem must be called at IRQL >= DISPATCH_LEVEL */
if (QueueWorkItem)
{
MiniQueueWorkItem(Adapter, NdisWorkItemRequest, (PVOID)NdisRequest);
MiniQueueWorkItem(AdapterBinding, NdisWorkItemRequest, (PVOID)NdisRequest);
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
return NDIS_STATUS_PENDING;
}
@ -169,7 +169,7 @@ ProRequest(
/* TODO (?): move the irql raise into MiniDoRequest */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
{
NdisStatus = MiniDoRequest(Adapter, NdisRequest);
NdisStatus = MiniDoRequest(AdapterBinding, NdisRequest);
NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
@ -278,7 +278,7 @@ ProSend(
if (QueueWorkItem)
{
MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, (PVOID)Packet);
MiniQueueWorkItem(AdapterBinding, NdisWorkItemSendLoopback, (PVOID)Packet);
return NDIS_STATUS_PENDING;
}
@ -315,7 +315,7 @@ ProSend(
/* This is a normal send packet, not a loopback packet. */
if (QueueWorkItem)
{
MiniQueueWorkItem(Adapter, NdisWorkItemSend, (PVOID)Packet);
MiniQueueWorkItem(AdapterBinding, NdisWorkItemSend, (PVOID)Packet);
NDIS_DbgPrint(MAX_TRACE, ("Queued a work item and returning\n"));
return NDIS_STATUS_PENDING;
}

View file

@ -9,7 +9,7 @@
*/
#include "precomp.h"
//#define NDEBUG
#define NDEBUG
#ifndef NDEBUG
DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER);

View file

@ -391,17 +391,10 @@ static VOID
CdromClassCreateMediaChangeEvent(IN PDEVICE_EXTENSION DeviceExtension,
IN ULONG DeviceNumber)
{
WCHAR NameBuffer[MAX_PATH];
UNICODE_STRING Name;
swprintf (NameBuffer,
L"\\Device\\MediaChangeEvent%lu",
DeviceNumber);
RtlInitUnicodeString (&Name,
NameBuffer);
DeviceExtension->MediaChangeEvent =
IoCreateSynchronizationEvent (&Name,
IoCreateSynchronizationEvent (NULL,
&DeviceExtension->MediaChangeEventHandle);
KeClearEvent (DeviceExtension->MediaChangeEvent);

View file

@ -315,17 +315,8 @@ static VOID
DiskClassCreateMediaChangeEvent(IN PDEVICE_EXTENSION DeviceExtension,
IN ULONG DeviceNumber)
{
WCHAR NameBuffer[MAX_PATH];
UNICODE_STRING Name;
swprintf (NameBuffer,
L"\\Device\\MediaChangeEvent%lu",
DeviceNumber);
RtlInitUnicodeString (&Name,
NameBuffer);
DeviceExtension->MediaChangeEvent =
IoCreateSynchronizationEvent (&Name,
IoCreateSynchronizationEvent (NULL,
&DeviceExtension->MediaChangeEventHandle);
KeClearEvent (DeviceExtension->MediaChangeEvent);

View file

@ -1,50 +1,50 @@
#
# ReactOS USB Drivers
#
PATH_TO_TOP = ../..
include $(PATH_TO_TOP)/rules.mak
DRIVERS = usbport miniport/usbuhci miniport/usbehci miniport/usbohci usbhub usbd
all: $(DRIVERS)
depends:
implib: $(DRIVERS:%=%_implib)
clean: $(DRIVERS:%=%_clean)
install: $(DRIVERS:%=%_install)
bootcd: $(DRIVERS:%=%_bootcd)
.PHONY: all depends implib clean install bootcd
#
# USB DRIVERS
#
$(DRIVERS): %:
$(MAKE) -C $*
$(DRIVERS:%=%_implib): %_implib:
$(MAKE) -C $* implib
$(DRIVERS:%=%_clean): %_clean:
$(MAKE) -C $* clean
$(DRIVERS:%=%_install): %_install:
$(MAKE) -C $* install
$(DRIVERS:%=%_bootcd): %_bootcd:
$(MAKE) -C $* bootcd
.PHONY: $(DRIVERS) $(DRIVERS:%=%_implib) $(DRIVERS:%=%_clean) $(DRIVERS:%=%_install) $(DRIVERS:%=%_bootcd)
etags:
find . -name "*.[ch]" -print | etags --language=c -
# EOF
#
# ReactOS USB Drivers
#
PATH_TO_TOP = ../..
include $(PATH_TO_TOP)/rules.mak
DRIVERS = usbport miniport/usbuhci miniport/usbehci miniport/usbohci usbhub usbd cromwell
all: $(DRIVERS)
depends:
implib: $(DRIVERS:%=%_implib)
clean: $(DRIVERS:%=%_clean)
install: $(DRIVERS:%=%_install)
bootcd: $(DRIVERS:%=%_bootcd)
.PHONY: all depends implib clean install bootcd
#
# USB DRIVERS
#
$(DRIVERS): %:
$(MAKE) -C $*
$(DRIVERS:%=%_implib): %_implib:
$(MAKE) -C $* implib
$(DRIVERS:%=%_clean): %_clean:
$(MAKE) -C $* clean
$(DRIVERS:%=%_install): %_install:
$(MAKE) -C $* install
$(DRIVERS:%=%_bootcd): %_bootcd:
$(MAKE) -C $* bootcd
.PHONY: $(DRIVERS) $(DRIVERS:%=%_implib) $(DRIVERS:%=%_clean) $(DRIVERS:%=%_install) $(DRIVERS:%=%_bootcd)
etags:
find . -name "*.[ch]" -print | etags --language=c -
# EOF

View file

@ -1,50 +1,50 @@
#
# ReactOS USB-Cromwell Drivers
#
PATH_TO_TOP = ../../..
include $(PATH_TO_TOP)/rules.mak
DRIVERS = core host uhci
all: $(DRIVERS)
depends:
implib: $(DRIVERS:%=%_implib)
clean: $(DRIVERS:%=%_clean)
install: $(DRIVERS:%=%_install)
bootcd: $(DRIVERS:%=%_bootcd)
.PHONY: all depends implib clean install bootcd
#
# USB DRIVERS
#
$(DRIVERS): %:
$(MAKE) -C $*
$(DRIVERS:%=%_implib): %_implib:
$(MAKE) -C $* implib
$(DRIVERS:%=%_clean): %_clean:
$(MAKE) -C $* clean
$(DRIVERS:%=%_install): %_install:
$(MAKE) -C $* install
$(DRIVERS:%=%_bootcd): %_bootcd:
$(MAKE) -C $* bootcd
.PHONY: $(DRIVERS) $(DRIVERS:%=%_implib) $(DRIVERS:%=%_clean) $(DRIVERS:%=%_install) $(DRIVERS:%=%_bootcd)
etags:
find . -name "*.[ch]" -print | etags --language=c -
# EOF
#
# ReactOS USB-Cromwell Drivers
#
PATH_TO_TOP = ../../..
include $(PATH_TO_TOP)/rules.mak
DRIVERS = core host uhci
all: $(DRIVERS)
depends:
implib: $(DRIVERS:%=%_implib)
clean: $(DRIVERS:%=%_clean)
install: $(DRIVERS:%=%_install)
bootcd: $(DRIVERS:%=%_bootcd)
.PHONY: all depends implib clean install bootcd
#
# USB DRIVERS
#
$(DRIVERS): %:
$(MAKE) -C $*
$(DRIVERS:%=%_implib): %_implib:
$(MAKE) -C $* implib
$(DRIVERS:%=%_clean): %_clean:
$(MAKE) -C $* clean
$(DRIVERS:%=%_install): %_install:
$(MAKE) -C $* install
$(DRIVERS:%=%_bootcd): %_bootcd:
$(MAKE) -C $* bootcd
.PHONY: $(DRIVERS) $(DRIVERS:%=%_implib) $(DRIVERS:%=%_clean) $(DRIVERS:%=%_install) $(DRIVERS:%=%_bootcd)
etags:
find . -name "*.[ch]" -print | etags --language=c -
# EOF

View file

@ -1,42 +1,42 @@
/*
* buffer_simple.c -- replacement for usb/core/buffer.c
*
* (c) Georg Acher, georg@acher.org
*
*/
#include "../usb_wrapper.h"
#define __KERNEL__
#define CONFIG_PCI
#include "hcd.h"
/*------------------------------------------------------------------------*/
int hcd_buffer_create (struct usb_hcd *hcd)
{
return 0;
}
/*------------------------------------------------------------------------*/
void hcd_buffer_destroy (struct usb_hcd *hcd)
{
}
/*------------------------------------------------------------------------*/
void *hcd_buffer_alloc (
struct usb_bus *bus,
size_t size,
int mem_flags,
dma_addr_t *dma
)
{
return kmalloc(size,0);
}
/*------------------------------------------------------------------------*/
void hcd_buffer_free (
struct usb_bus *bus,
size_t size,
void *addr,
dma_addr_t dma
)
{
kfree(addr);
}
/*
* buffer_simple.c -- replacement for usb/core/buffer.c
*
* (c) Georg Acher, georg@acher.org
*
*/
#include "../usb_wrapper.h"
#define __KERNEL__
#define CONFIG_PCI
#include "hcd.h"
/*------------------------------------------------------------------------*/
int hcd_buffer_create (struct usb_hcd *hcd)
{
return 0;
}
/*------------------------------------------------------------------------*/
void hcd_buffer_destroy (struct usb_hcd *hcd)
{
}
/*------------------------------------------------------------------------*/
void *hcd_buffer_alloc (
struct usb_bus *bus,
size_t size,
int mem_flags,
dma_addr_t *dma
)
{
return kmalloc(size,0);
}
/*------------------------------------------------------------------------*/
void hcd_buffer_free (
struct usb_bus *bus,
size_t size,
void *addr,
dma_addr_t dma
)
{
kfree(addr);
}

File diff suppressed because it is too large Load diff

View file

@ -1,369 +1,370 @@
/*
* (C) Copyright David Brownell 2000-2002
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if 0
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/usb.h>
#include "hcd.h"
#else
#define DEBUG
#include "../usb_wrapper.h"
#include "hcd.h"
#endif
/* PCI-based HCs are normal, but custom bus glue should be ok */
/*-------------------------------------------------------------------------*/
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
/**
* usb_hcd_pci_probe - initialize PCI-based HCDs
* @dev: USB Host Controller being probed
* @id: pci hotplug id connecting controller to HCD framework
* Context: !in_interrupt()
*
* Allocates basic PCI resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*
* Store this function in the HCD's struct pci_driver as probe().
*/
int STDCALL usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
struct hc_driver *driver;
PHYSICAL_ADDRESS resource;
unsigned long len;
void *base;
struct usb_hcd *hcd;
int retval, region;
char buf [8];
//char *bufp = buf;
printk("usbcore: usb_hcd_pci_probe() called\n");
if (usb_disabled())
return -ENODEV;
if (!id || !(driver = (struct hc_driver *) id->driver_data))
return -EINVAL;
if (pci_enable_device (dev) < 0)
return -ENODEV;
if (!dev->irq) {
err ("Found HC with no IRQ. Check BIOS/PCI %s setup!",
dev->slot_name);
return -ENODEV;
}
if (driver->flags & HCD_MEMORY) { // EHCI, OHCI
region = 0;
resource = pci_resource_start (dev, 0);
len = pci_resource_len (dev, 0);
if (!request_mem_region (resource, len, driver->description)) {
dbg ("controller already in use");
return -EBUSY;
}
base = ioremap_nocache (resource, len);
if (base == NULL) {
dbg ("error mapping memory");
retval = -EFAULT;
clean_1:
release_mem_region (resource, len);
err ("init %s fail, %d", dev->slot_name, retval);
return retval;
}
} else { // UHCI
//resource = 0;
len = 0;
for (region = 0; region < PCI_ROM_RESOURCE; region++) {
if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
continue;
resource = pci_resource_start (dev, region);
len = pci_resource_len (dev, region);
if (request_region (resource, len,
driver->description))
break;
}
if (region == PCI_ROM_RESOURCE) {
dbg ("no i/o regions available");
return -EBUSY;
}
base = NULL; //(void *) resource; // this isn't possible
}
// driver->start(), later on, will transfer device from
// control by SMM/BIOS to control by Linux (if needed)
pci_set_master (dev);
hcd = driver->hcd_alloc ();
if (hcd == NULL){
dbg ("hcd alloc fail");
retval = -ENOMEM;
clean_2:
if (driver->flags & HCD_MEMORY) {
iounmap (base);
goto clean_1;
} else {
release_region (resource, len);
err ("init %s fail, %d", dev->slot_name, retval);
return retval;
}
}
pci_set_drvdata (dev, hcd);
hcd->driver = driver;
hcd->description = driver->description;
hcd->pdev = dev;
hcd->self.bus_name = dev->slot_name;
hcd->product_desc = dev->dev.name;
hcd->self.controller = &dev->dev;
hcd->controller = hcd->self.controller;
if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
driver->hcd_free (hcd);
goto clean_2;
}
dev_info (hcd->controller, "%s\n", hcd->product_desc);
#ifndef __sparc__
sprintf (buf, "%d", dev->irq);
#else
bufp = __irq_itoa(dev->irq);
#endif
if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
!= 0) {
dev_err (hcd->controller,
"request interrupt %s failed\n", buf);
retval = -EBUSY;
goto clean_3;
}
hcd->irq = dev->irq;
hcd->regs = base;
hcd->region = region;
dev_info (hcd->controller, "irq %s, %s %p\n", buf,
(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
base);
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.hcpriv = (void *) hcd;
INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
usb_hcd_pci_remove (dev);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_probe);
/* may be called without controller electrically present */
/* may be called with controller, bus, and devices active */
/**
* usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
* @dev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_pci_probe(), first invoking
* the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
*
* Store this function in the HCD's struct pci_driver as remove().
*/
void STDCALL usb_hcd_pci_remove (struct pci_dev *dev)
{
struct usb_hcd *hcd;
struct usb_device *hub;
hcd = pci_get_drvdata(dev);
if (!hcd)
return;
dev_info (hcd->controller, "remove, state %x\n", hcd->state);
if (in_interrupt ())
BUG ();
hub = hcd->self.root_hub;
hcd->state = USB_STATE_QUIESCING;
dev_dbg (hcd->controller, "roothub graceful disconnect\n");
usb_disconnect (&hub);
hcd->driver->stop (hcd);
hcd_buffer_destroy (hcd);
hcd->state = USB_STATE_HALT;
pci_set_drvdata (dev, 0);
free_irq (hcd->irq, hcd);
if (hcd->driver->flags & HCD_MEMORY) {
iounmap (hcd->regs);
release_mem_region (pci_resource_start (dev, 0),
pci_resource_len (dev, 0));
} else {
release_region (pci_resource_start (dev, hcd->region),
pci_resource_len (dev, hcd->region));
}
usb_deregister_bus (&hcd->self);
if (atomic_read (&hcd->self.refcnt) != 1) {
dev_warn (hcd->controller,
"dangling refs (%d) to bus %d!\n",
atomic_read (&hcd->self.refcnt) - 1,
hcd->self.busnum);
}
hcd->driver->hcd_free (hcd);
}
EXPORT_SYMBOL (usb_hcd_pci_remove);
#ifdef CONFIG_PM
/*
* Some "sleep" power levels imply updating struct usb_driver
* to include a callback asking hcds to do their bit by checking
* if all the drivers can suspend. Gets involved with remote wakeup.
*
* If there are pending urbs, then HCs will need to access memory,
* causing extra power drain. New sleep()/wakeup() PM calls might
* be needed, beyond PCI suspend()/resume(). The root hub timer
* still be accessing memory though ...
*
* FIXME: USB should have some power budgeting support working with
* all kinds of hubs.
*
* FIXME: This assumes only D0->D3 suspend and D3->D0 resume.
* D1 and D2 states should do something, yes?
*
* FIXME: Should provide generic enable_wake(), calling pci_enable_wake()
* for all supported states, so that USB remote wakeup can work for any
* devices that support it (and are connected via powered hubs).
*
* FIXME: resume doesn't seem to work right any more...
*/
// 2.4 kernels have issued concurrent resumes (w/APM)
// we defend against that error; PCI doesn't yet.
/**
* usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
* @dev: USB Host Controller being suspended
*
* Store this function in the HCD's struct pci_driver as suspend().
*/
int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
dev_info (hcd->controller, "suspend to state %d\n", state);
pci_save_state (dev, hcd->pci_state);
// FIXME for all connected devices, leaf-to-root:
// driver->suspend()
// proposed "new 2.5 driver model" will automate that
/* driver may want to disable DMA etc */
retval = hcd->driver->suspend (hcd, state);
hcd->state = USB_STATE_SUSPENDED;
pci_set_power_state (dev, state);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_suspend);
/**
* usb_hcd_pci_resume - power management resume of a PCI-based HCD
* @dev: USB Host Controller being resumed
*
* Store this function in the HCD's struct pci_driver as resume().
*/
int usb_hcd_pci_resume (struct pci_dev *dev)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
dev_info (hcd->controller, "resume\n");
/* guard against multiple resumes (APM bug?) */
atomic_inc (&hcd->resume_count);
if (atomic_read (&hcd->resume_count) != 1) {
dev_err (hcd->controller, "concurrent PCI resumes\n");
retval = 0;
goto done;
}
retval = -EBUSY;
if (hcd->state != USB_STATE_SUSPENDED) {
dev_dbg (hcd->controller, "can't resume, not suspended!\n");
goto done;
}
hcd->state = USB_STATE_RESUMING;
pci_set_power_state (dev, 0);
pci_restore_state (dev, hcd->pci_state);
retval = hcd->driver->resume (hcd);
if (!HCD_IS_RUNNING (hcd->state)) {
dev_dbg (hcd->controller, "resume fail, retval %d\n", retval);
usb_hc_died (hcd);
// FIXME: recover, reset etc.
} else {
// FIXME for all connected devices, root-to-leaf:
// driver->resume ();
// proposed "new 2.5 driver model" will automate that
}
done:
atomic_dec (&hcd->resume_count);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_resume);
#endif /* CONFIG_PM */
/*
* (C) Copyright David Brownell 2000-2002
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if 0
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/usb.h>
#include "hcd.h"
#else
#define DEBUG
#include "../usb_wrapper.h"
#include "hcd.h"
#endif
/* PCI-based HCs are normal, but custom bus glue should be ok */
/*-------------------------------------------------------------------------*/
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
/**
* usb_hcd_pci_probe - initialize PCI-based HCDs
* @dev: USB Host Controller being probed
* @id: pci hotplug id connecting controller to HCD framework
* Context: !in_interrupt()
*
* Allocates basic PCI resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*
* Store this function in the HCD's struct pci_driver as probe().
*/
int STDCALL
usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
struct hc_driver *driver;
PHYSICAL_ADDRESS resource;
unsigned long len;
void *base;
struct usb_hcd *hcd;
int retval, region;
char buf [8];
//char *bufp = buf;
printk("usbcore: usb_hcd_pci_probe() called\n");
if (usb_disabled())
return -ENODEV;
if (!id || !(driver = (struct hc_driver *) id->driver_data))
return -EINVAL;
if (pci_enable_device (dev) < 0)
return -ENODEV;
if (!dev->irq) {
err ("Found HC with no IRQ. Check BIOS/PCI %s setup!",
dev->slot_name);
return -ENODEV;
}
if (driver->flags & HCD_MEMORY) { // EHCI, OHCI
region = 0;
resource = pci_resource_start (dev, 0);
len = pci_resource_len (dev, 0);
if (!request_mem_region (resource, len, driver->description)) {
dbg ("controller already in use");
return -EBUSY;
}
base = ioremap_nocache (resource, len);
if (base == NULL) {
dbg ("error mapping memory");
retval = -EFAULT;
clean_1:
release_mem_region (resource, len);
err ("init %s fail, %d", dev->slot_name, retval);
return retval;
}
} else { // UHCI
//resource = 0;
len = 0;
for (region = 0; region < PCI_ROM_RESOURCE; region++) {
if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
continue;
resource = pci_resource_start (dev, region);
len = pci_resource_len (dev, region);
if (request_region (resource, len,
driver->description))
break;
}
if (region == PCI_ROM_RESOURCE) {
dbg ("no i/o regions available");
return -EBUSY;
}
base = (void *) (ULONG_PTR)resource.u.LowPart;
}
// driver->start(), later on, will transfer device from
// control by SMM/BIOS to control by Linux (if needed)
pci_set_master (dev);
hcd = driver->hcd_alloc ();
if (hcd == NULL){
dbg ("hcd alloc fail");
retval = -ENOMEM;
clean_2:
if (driver->flags & HCD_MEMORY) {
iounmap (base);
goto clean_1;
} else {
release_region (resource, len);
err ("init %s fail, %d", dev->slot_name, retval);
return retval;
}
}
pci_set_drvdata (dev, hcd);
hcd->driver = driver;
hcd->description = driver->description;
hcd->pdev = dev;
hcd->self.bus_name = dev->slot_name;
hcd->product_desc = dev->dev.name;
hcd->self.controller = &dev->dev;
hcd->controller = hcd->self.controller;
if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
driver->hcd_free (hcd);
goto clean_2;
}
dev_info (hcd->controller, "%s\n", hcd->product_desc);
#ifndef __sparc__
sprintf (buf, "%d", dev->irq);
#else
bufp = __irq_itoa(dev->irq);
#endif
if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
!= 0) {
dev_err (hcd->controller,
"request interrupt %s failed\n", buf);
retval = -EBUSY;
goto clean_3;
}
hcd->irq = dev->irq;
hcd->regs = base;
hcd->region = region;
dev_info (hcd->controller, "irq %s, %s %p\n", buf,
(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
base);
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.hcpriv = (void *) hcd;
INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
usb_hcd_pci_remove (dev);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_probe);
/* may be called without controller electrically present */
/* may be called with controller, bus, and devices active */
/**
* usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
* @dev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_pci_probe(), first invoking
* the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
*
* Store this function in the HCD's struct pci_driver as remove().
*/
void STDCALL usb_hcd_pci_remove (struct pci_dev *dev)
{
struct usb_hcd *hcd;
struct usb_device *hub;
hcd = pci_get_drvdata(dev);
if (!hcd)
return;
dev_info (hcd->controller, "remove, state %x\n", hcd->state);
if (in_interrupt ())
BUG ();
hub = hcd->self.root_hub;
hcd->state = USB_STATE_QUIESCING;
dev_dbg (hcd->controller, "roothub graceful disconnect\n");
usb_disconnect (&hub);
hcd->driver->stop (hcd);
hcd_buffer_destroy (hcd);
hcd->state = USB_STATE_HALT;
pci_set_drvdata (dev, 0);
free_irq (hcd->irq, hcd);
if (hcd->driver->flags & HCD_MEMORY) {
iounmap (hcd->regs);
release_mem_region (pci_resource_start (dev, 0),
pci_resource_len (dev, 0));
} else {
release_region (pci_resource_start (dev, hcd->region),
pci_resource_len (dev, hcd->region));
}
usb_deregister_bus (&hcd->self);
if (atomic_read (&hcd->self.refcnt) != 1) {
dev_warn (hcd->controller,
"dangling refs (%d) to bus %d!\n",
atomic_read (&hcd->self.refcnt) - 1,
hcd->self.busnum);
}
hcd->driver->hcd_free (hcd);
}
EXPORT_SYMBOL (usb_hcd_pci_remove);
#ifdef CONFIG_PM
/*
* Some "sleep" power levels imply updating struct usb_driver
* to include a callback asking hcds to do their bit by checking
* if all the drivers can suspend. Gets involved with remote wakeup.
*
* If there are pending urbs, then HCs will need to access memory,
* causing extra power drain. New sleep()/wakeup() PM calls might
* be needed, beyond PCI suspend()/resume(). The root hub timer
* still be accessing memory though ...
*
* FIXME: USB should have some power budgeting support working with
* all kinds of hubs.
*
* FIXME: This assumes only D0->D3 suspend and D3->D0 resume.
* D1 and D2 states should do something, yes?
*
* FIXME: Should provide generic enable_wake(), calling pci_enable_wake()
* for all supported states, so that USB remote wakeup can work for any
* devices that support it (and are connected via powered hubs).
*
* FIXME: resume doesn't seem to work right any more...
*/
// 2.4 kernels have issued concurrent resumes (w/APM)
// we defend against that error; PCI doesn't yet.
/**
* usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
* @dev: USB Host Controller being suspended
*
* Store this function in the HCD's struct pci_driver as suspend().
*/
int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
dev_info (hcd->controller, "suspend to state %d\n", state);
pci_save_state (dev, hcd->pci_state);
// FIXME for all connected devices, leaf-to-root:
// driver->suspend()
// proposed "new 2.5 driver model" will automate that
/* driver may want to disable DMA etc */
retval = hcd->driver->suspend (hcd, state);
hcd->state = USB_STATE_SUSPENDED;
pci_set_power_state (dev, state);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_suspend);
/**
* usb_hcd_pci_resume - power management resume of a PCI-based HCD
* @dev: USB Host Controller being resumed
*
* Store this function in the HCD's struct pci_driver as resume().
*/
int usb_hcd_pci_resume (struct pci_dev *dev)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
dev_info (hcd->controller, "resume\n");
/* guard against multiple resumes (APM bug?) */
atomic_inc (&hcd->resume_count);
if (atomic_read (&hcd->resume_count) != 1) {
dev_err (hcd->controller, "concurrent PCI resumes\n");
retval = 0;
goto done;
}
retval = -EBUSY;
if (hcd->state != USB_STATE_SUSPENDED) {
dev_dbg (hcd->controller, "can't resume, not suspended!\n");
goto done;
}
hcd->state = USB_STATE_RESUMING;
pci_set_power_state (dev, 0);
pci_restore_state (dev, hcd->pci_state);
retval = hcd->driver->resume (hcd);
if (!HCD_IS_RUNNING (hcd->state)) {
dev_dbg (hcd->controller, "resume fail, retval %d\n", retval);
usb_hc_died (hcd);
// FIXME: recover, reset etc.
} else {
// FIXME for all connected devices, root-to-leaf:
// driver->resume ();
// proposed "new 2.5 driver model" will automate that
}
done:
atomic_dec (&hcd->resume_count);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_resume);
#endif /* CONFIG_PM */

File diff suppressed because it is too large Load diff

View file

@ -1,481 +1,481 @@
/*
* Copyright (c) 2001-2002 by David Brownell
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __KERNEL__
/* This file contains declarations of usbcore internals that are mostly
* used or exposed by Host Controller Drivers.
*/
/*
* USB Packet IDs (PIDs)
*/
#define USB_PID_UNDEF_0 0xf0
#define USB_PID_OUT 0xe1
#define USB_PID_ACK 0xd2
#define USB_PID_DATA0 0xc3
#define USB_PID_PING 0xb4 /* USB 2.0 */
#define USB_PID_SOF 0xa5
#define USB_PID_NYET 0x96 /* USB 2.0 */
#define USB_PID_DATA2 0x87 /* USB 2.0 */
#define USB_PID_SPLIT 0x78 /* USB 2.0 */
#define USB_PID_IN 0x69
#define USB_PID_NAK 0x5a
#define USB_PID_DATA1 0x4b
#define USB_PID_PREAMBLE 0x3c /* Token mode */
#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
#define USB_PID_SETUP 0x2d
#define USB_PID_STALL 0x1e
#define USB_PID_MDATA 0x0f /* USB 2.0 */
/*-------------------------------------------------------------------------*/
/*
* USB Host Controller Driver (usb_hcd) framework
*
* Since "struct usb_bus" is so thin, you can't share much code in it.
* This framework is a layer over that, and should be more sharable.
*/
/*-------------------------------------------------------------------------*/
struct usb_hcd { /* usb_bus.hcpriv points to this */
/*
* housekeeping
*/
struct usb_bus self; /* hcd is-a bus */
const char *product_desc; /* product/vendor string */
const char *description; /* "ehci-hcd" etc */
struct timer_list rh_timer; /* drives root hub */
struct list_head dev_list; /* devices on this bus */
struct work_struct work;
/*
* hardware info/state
*/
struct hc_driver *driver; /* hw-specific hooks */
int irq; /* irq allocated */
void *regs; /* device memory/io */
struct device *controller; /* handle to hardware */
/* a few non-PCI controllers exist, mostly for OHCI */
struct pci_dev *pdev; /* pci is typical */
#ifdef CONFIG_PCI
int region; /* pci region for regs */
u32 pci_state [16]; /* for PM state save */
atomic_t resume_count; /* multiple resumes issue */
#endif
#define HCD_BUFFER_POOLS 4
struct pci_pool *pool [HCD_BUFFER_POOLS];
int state;
# define __ACTIVE 0x01
# define __SLEEPY 0x02
# define __SUSPEND 0x04
# define __TRANSIENT 0x80
# define USB_STATE_HALT 0
# define USB_STATE_RUNNING (__ACTIVE)
# define USB_STATE_READY (__ACTIVE|__SLEEPY)
# define USB_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
# define USB_STATE_RESUMING (__SUSPEND|__TRANSIENT)
# define USB_STATE_SUSPENDED (__SUSPEND)
#define HCD_IS_RUNNING(state) ((state) & __ACTIVE)
#define HCD_IS_SUSPENDED(state) ((state) & __SUSPEND)
/* more shared queuing code would be good; it should support
* smarter scheduling, handle transaction translators, etc;
* input size of periodic table to an interrupt scheduler.
* (ohci 32, uhci 1024, ehci 256/512/1024).
*/
};
/* 2.4 does this a bit differently ... */
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{
return &hcd->self;
}
struct hcd_dev { /* usb_device.hcpriv points to this */
struct list_head dev_list; /* on this hcd */
struct list_head urb_list; /* pending on this dev */
/* per-configuration HC/HCD state, such as QH or ED */
void *ep[32];
};
// urb.hcpriv is really hardware-specific
struct hcd_timeout { /* timeouts we allocate */
struct list_head timeout_list;
struct timer_list timer;
};
/*-------------------------------------------------------------------------*/
/*
* FIXME usb_operations should vanish or become hc_driver,
* when usb_bus and usb_hcd become the same thing.
*/
struct usb_operations {
int (*allocate)(struct usb_device *);
int (*deallocate)(struct usb_device *);
int (*get_frame_number) (struct usb_device *usb_dev);
int (*submit_urb) (struct urb *urb, int mem_flags);
int (*unlink_urb) (struct urb *urb);
/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
int mem_flags,
dma_addr_t *dma);
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
void (*disable)(struct usb_device *udev, int bEndpointAddress);
};
/* each driver provides one of these, and hardware init support */
struct pt_regs;
// new struct from 2.6
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
/* irq handler */
irqreturn_t (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
/* called to init HCD and root hub */
int (*reset) (struct usb_hcd *hcd);
int (*start) (struct usb_hcd *hcd);
/* called after all devices were suspended */
int (*suspend) (struct usb_hcd *hcd, u32 state);
/* called before any devices get resumed */
int (*resume) (struct usb_hcd *hcd);
/* cleanly make HCD stop writing memory and doing I/O */
void (*stop) (struct usb_hcd *hcd);
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
int mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
struct hcd_dev *dev, int bEndpointAddress);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
};
// old version, "just in case"
#if 0
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
/* irq handler */
void (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
/* called to init HCD and root hub */
int (*start) (struct usb_hcd *hcd);
/* called after all devices were suspended */
int (*suspend) (struct usb_hcd *hcd, u32 state);
/* called before any devices get resumed */
int (*resume) (struct usb_hcd *hcd);
/* cleanly make HCD stop writing memory and doing I/O */
void (*stop) (struct usb_hcd *hcd);
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
int mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
struct hcd_dev *dev, int bEndpointAddress);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
};
#endif
extern void STDCALL usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
extern void STDCALL usb_bus_init (struct usb_bus *bus);
extern void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb);
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
extern int STDCALL usb_hcd_pci_probe (struct pci_dev *dev,
const struct pci_device_id *id);
extern void STDCALL usb_hcd_pci_remove (struct pci_dev *dev);
#ifdef CONFIG_PM
// FIXME: see Documentation/power/pci.txt (2.4.6 and later?)
// extern int usb_hcd_pci_save_state (struct pci_dev *dev, u32 state);
extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state);
extern int usb_hcd_pci_resume (struct pci_dev *dev);
// extern int usb_hcd_pci_enable_wake (struct pci_dev *dev, u32 state, int flg);
#endif /* CONFIG_PM */
#endif /* CONFIG_PCI */
/* pci-ish (pdev null is ok) buffer alloc/mapping support */
int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);
void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
int mem_flags, dma_addr_t *dma);
void hcd_buffer_free (struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
/* generic bus glue, needed for host controllers that don't use PCI */
extern struct usb_operations usb_hcd_operations;
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void STDCALL usb_hc_died (struct usb_hcd *hcd);
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
extern int usb_new_device(struct usb_device *dev, struct device *parent);
extern void STDCALL usb_connect(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);
/* exported to hub driver ONLY to support usb_reset_device () */
extern int usb_get_configuration(struct usb_device *dev);
extern void usb_set_maxpacket(struct usb_device *dev);
extern void usb_destroy_configuration(struct usb_device *dev);
extern int usb_set_address(struct usb_device *dev);
/* use these only before the device's address has been set */
#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30))
#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | USB_DIR_IN)
/*-------------------------------------------------------------------------*/
/*
* HCD Root Hub support
*/
#include "hub.h"
/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
#define DeviceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define DeviceOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define InterfaceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
/* table 9.6 standard features */
#define DEVICE_REMOTE_WAKEUP 1
#define ENDPOINT_HALT 0
/* class requests from the USB 2.0 hub spec, table 11-15 */
/* GetBusState and SetHubDescriptor are optional, omitted */
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
/*-------------------------------------------------------------------------*/
/*
* Generic bandwidth allocation constants/support
*/
#define FRAME_TIME_USECS 1000L
#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
/* Trying not to use worst-case bit-stuffing
of (7/6 * 8 * bytecount) = 9.33 * bytecount */
/* bytecount = data payload byte count */
#define NS_TO_US(ns) ((ns + 500L) / 1000L)
/* convert & round nanoseconds to microseconds */
extern void STDCALL usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
int bustime, int isoc);
extern void STDCALL usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
int isoc);
/*
* Full/low speed bandwidth allocation constants/support.
*/
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
/* 4 full-speed bit times (est.) */
#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
extern int STDCALL usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
/*
* Ceiling microseconds (typical) for that many bytes at high speed
* ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
* to preallocate bandwidth)
*/
#define USB2_HOST_DELAY 5 /* nsec, guess */
#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+ USB2_HOST_DELAY)
#define HS_USECS_ISO(bytes) NS_TO_US ( ((long)(38 * 8 * 2.083)) \
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+ USB2_HOST_DELAY)
extern long STDCALL usb_calc_bus_time (int speed, int is_input,
int isoc, int bytecount);
/*-------------------------------------------------------------------------*/
extern struct usb_bus STDCALL *usb_alloc_bus (struct usb_operations *);
extern void STDCALL usb_free_bus (struct usb_bus *);
extern void STDCALL usb_register_bus (struct usb_bus *);
extern void STDCALL usb_deregister_bus (struct usb_bus *);
extern int STDCALL usb_register_root_hub (struct usb_device *usb_dev,
struct device *parent_dev);
/* for portability to 2.4, hcds should call this */
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_register_root_hub (
hcd_to_bus (hcd)->root_hub, hcd->controller);
}
/*-------------------------------------------------------------------------*/
/* exported only within usbcore */
extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock;
extern void usb_bus_get (struct usb_bus *bus);
extern void usb_bus_put (struct usb_bus *bus);
extern int usb_find_interface_driver (struct usb_device *dev,
struct usb_interface *interface);
#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep)))
#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
/*
* USB device fs stuff
*/
#ifdef CONFIG_USB_DEVICEFS
/*
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
*/
extern void usbfs_add_bus(struct usb_bus *bus);
extern void usbfs_remove_bus(struct usb_bus *bus);
extern void usbfs_add_device(struct usb_device *dev);
extern void usbfs_remove_device(struct usb_device *dev);
extern void usbfs_update_special (void);
extern int usbfs_init(void);
extern void usbfs_cleanup(void);
#else /* CONFIG_USB_DEVICEFS */
static inline void usbfs_add_bus(struct usb_bus *bus) {}
static inline void usbfs_remove_bus(struct usb_bus *bus) {}
static inline void usbfs_add_device(struct usb_device *dev) {}
static inline void usbfs_remove_device(struct usb_device *dev) {}
static inline void usbfs_update_special (void) {}
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }
#endif /* CONFIG_USB_DEVICEFS */
/*-------------------------------------------------------------------------*/
/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
// bleech -- resurfaced in 2.4.11 or 2.4.12
#define bitmap DeviceRemovable
/*-------------------------------------------------------------------------*/
/* random stuff */
#define RUN_CONTEXT (in_irq () ? "in_irq" \
: (in_interrupt () ? "in_interrupt" : "can sleep"))
#endif /* __KERNEL__ */
/*
* Copyright (c) 2001-2002 by David Brownell
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __KERNEL__
/* This file contains declarations of usbcore internals that are mostly
* used or exposed by Host Controller Drivers.
*/
/*
* USB Packet IDs (PIDs)
*/
#define USB_PID_UNDEF_0 0xf0
#define USB_PID_OUT 0xe1
#define USB_PID_ACK 0xd2
#define USB_PID_DATA0 0xc3
#define USB_PID_PING 0xb4 /* USB 2.0 */
#define USB_PID_SOF 0xa5
#define USB_PID_NYET 0x96 /* USB 2.0 */
#define USB_PID_DATA2 0x87 /* USB 2.0 */
#define USB_PID_SPLIT 0x78 /* USB 2.0 */
#define USB_PID_IN 0x69
#define USB_PID_NAK 0x5a
#define USB_PID_DATA1 0x4b
#define USB_PID_PREAMBLE 0x3c /* Token mode */
#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
#define USB_PID_SETUP 0x2d
#define USB_PID_STALL 0x1e
#define USB_PID_MDATA 0x0f /* USB 2.0 */
/*-------------------------------------------------------------------------*/
/*
* USB Host Controller Driver (usb_hcd) framework
*
* Since "struct usb_bus" is so thin, you can't share much code in it.
* This framework is a layer over that, and should be more sharable.
*/
/*-------------------------------------------------------------------------*/
struct usb_hcd { /* usb_bus.hcpriv points to this */
/*
* housekeeping
*/
struct usb_bus self; /* hcd is-a bus */
const char *product_desc; /* product/vendor string */
const char *description; /* "ehci-hcd" etc */
struct timer_list rh_timer; /* drives root hub */
struct list_head dev_list; /* devices on this bus */
struct work_struct work;
/*
* hardware info/state
*/
struct hc_driver *driver; /* hw-specific hooks */
int irq; /* irq allocated */
void *regs; /* device memory/io */
struct device *controller; /* handle to hardware */
/* a few non-PCI controllers exist, mostly for OHCI */
struct pci_dev *pdev; /* pci is typical */
#ifdef CONFIG_PCI
int region; /* pci region for regs */
u32 pci_state [16]; /* for PM state save */
atomic_t resume_count; /* multiple resumes issue */
#endif
#define HCD_BUFFER_POOLS 4
struct pci_pool *pool [HCD_BUFFER_POOLS];
int state;
# define __ACTIVE 0x01
# define __SLEEPY 0x02
# define __SUSPEND 0x04
# define __TRANSIENT 0x80
# define USB_STATE_HALT 0
# define USB_STATE_RUNNING (__ACTIVE)
# define USB_STATE_READY (__ACTIVE|__SLEEPY)
# define USB_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
# define USB_STATE_RESUMING (__SUSPEND|__TRANSIENT)
# define USB_STATE_SUSPENDED (__SUSPEND)
#define HCD_IS_RUNNING(state) ((state) & __ACTIVE)
#define HCD_IS_SUSPENDED(state) ((state) & __SUSPEND)
/* more shared queuing code would be good; it should support
* smarter scheduling, handle transaction translators, etc;
* input size of periodic table to an interrupt scheduler.
* (ohci 32, uhci 1024, ehci 256/512/1024).
*/
};
/* 2.4 does this a bit differently ... */
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{
return &hcd->self;
}
struct hcd_dev { /* usb_device.hcpriv points to this */
struct list_head dev_list; /* on this hcd */
struct list_head urb_list; /* pending on this dev */
/* per-configuration HC/HCD state, such as QH or ED */
void *ep[32];
};
// urb.hcpriv is really hardware-specific
struct hcd_timeout { /* timeouts we allocate */
struct list_head timeout_list;
struct timer_list timer;
};
/*-------------------------------------------------------------------------*/
/*
* FIXME usb_operations should vanish or become hc_driver,
* when usb_bus and usb_hcd become the same thing.
*/
struct usb_operations {
int (*allocate)(struct usb_device *);
int (*deallocate)(struct usb_device *);
int (*get_frame_number) (struct usb_device *usb_dev);
int (*submit_urb) (struct urb *urb, int mem_flags);
int (*unlink_urb) (struct urb *urb);
/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
int mem_flags,
dma_addr_t *dma);
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
void (*disable)(struct usb_device *udev, int bEndpointAddress);
};
/* each driver provides one of these, and hardware init support */
struct pt_regs;
// new struct from 2.6
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
/* irq handler */
irqreturn_t (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
/* called to init HCD and root hub */
int (*reset) (struct usb_hcd *hcd);
int (*start) (struct usb_hcd *hcd);
/* called after all devices were suspended */
int (*suspend) (struct usb_hcd *hcd, u32 state);
/* called before any devices get resumed */
int (*resume) (struct usb_hcd *hcd);
/* cleanly make HCD stop writing memory and doing I/O */
void (*stop) (struct usb_hcd *hcd);
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
int mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
struct hcd_dev *dev, int bEndpointAddress);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
};
// old version, "just in case"
#if 0
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
/* irq handler */
int (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
/* called to init HCD and root hub */
int (*start) (struct usb_hcd *hcd);
/* called after all devices were suspended */
int (*suspend) (struct usb_hcd *hcd, u32 state);
/* called before any devices get resumed */
int (*resume) (struct usb_hcd *hcd);
/* cleanly make HCD stop writing memory and doing I/O */
void (*stop) (struct usb_hcd *hcd);
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
int mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
struct hcd_dev *dev, int bEndpointAddress);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
};
#endif
extern void STDCALL usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
extern void STDCALL usb_bus_init (struct usb_bus *bus);
extern void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb);
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
extern int STDCALL usb_hcd_pci_probe (struct pci_dev *dev,
const struct pci_device_id *id);
extern void STDCALL usb_hcd_pci_remove (struct pci_dev *dev);
#ifdef CONFIG_PM
// FIXME: see Documentation/power/pci.txt (2.4.6 and later?)
// extern int usb_hcd_pci_save_state (struct pci_dev *dev, u32 state);
extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state);
extern int usb_hcd_pci_resume (struct pci_dev *dev);
// extern int usb_hcd_pci_enable_wake (struct pci_dev *dev, u32 state, int flg);
#endif /* CONFIG_PM */
#endif /* CONFIG_PCI */
/* pci-ish (pdev null is ok) buffer alloc/mapping support */
int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);
void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
int mem_flags, dma_addr_t *dma);
void hcd_buffer_free (struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
/* generic bus glue, needed for host controllers that don't use PCI */
extern struct usb_operations usb_hcd_operations;
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void STDCALL usb_hc_died (struct usb_hcd *hcd);
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
extern int usb_new_device(struct usb_device *dev, struct device *parent);
extern void STDCALL usb_connect(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);
/* exported to hub driver ONLY to support usb_reset_device () */
extern int usb_get_configuration(struct usb_device *dev);
extern void usb_set_maxpacket(struct usb_device *dev);
extern void usb_destroy_configuration(struct usb_device *dev);
extern int usb_set_address(struct usb_device *dev);
/* use these only before the device's address has been set */
#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30))
#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | USB_DIR_IN)
/*-------------------------------------------------------------------------*/
/*
* HCD Root Hub support
*/
#include "hub.h"
/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
#define DeviceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define DeviceOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define InterfaceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
/* table 9.6 standard features */
#define DEVICE_REMOTE_WAKEUP 1
#define ENDPOINT_HALT 0
/* class requests from the USB 2.0 hub spec, table 11-15 */
/* GetBusState and SetHubDescriptor are optional, omitted */
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
/*-------------------------------------------------------------------------*/
/*
* Generic bandwidth allocation constants/support
*/
#define FRAME_TIME_USECS 1000L
#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
/* Trying not to use worst-case bit-stuffing
of (7/6 * 8 * bytecount) = 9.33 * bytecount */
/* bytecount = data payload byte count */
#define NS_TO_US(ns) ((ns + 500L) / 1000L)
/* convert & round nanoseconds to microseconds */
extern void STDCALL usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
int bustime, int isoc);
extern void STDCALL usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
int isoc);
/*
* Full/low speed bandwidth allocation constants/support.
*/
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
/* 4 full-speed bit times (est.) */
#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
extern int STDCALL usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
/*
* Ceiling microseconds (typical) for that many bytes at high speed
* ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
* to preallocate bandwidth)
*/
#define USB2_HOST_DELAY 5 /* nsec, guess */
#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+ USB2_HOST_DELAY)
#define HS_USECS_ISO(bytes) NS_TO_US ( ((long)(38 * 8 * 2.083)) \
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+ USB2_HOST_DELAY)
extern long STDCALL usb_calc_bus_time (int speed, int is_input,
int isoc, int bytecount);
/*-------------------------------------------------------------------------*/
extern struct usb_bus STDCALL *usb_alloc_bus (struct usb_operations *);
extern void STDCALL usb_free_bus (struct usb_bus *);
extern void STDCALL usb_register_bus (struct usb_bus *);
extern void STDCALL usb_deregister_bus (struct usb_bus *);
extern int STDCALL usb_register_root_hub (struct usb_device *usb_dev,
struct device *parent_dev);
/* for portability to 2.4, hcds should call this */
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_register_root_hub (
hcd_to_bus (hcd)->root_hub, hcd->controller);
}
/*-------------------------------------------------------------------------*/
/* exported only within usbcore */
extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock;
extern void usb_bus_get (struct usb_bus *bus);
extern void usb_bus_put (struct usb_bus *bus);
extern int usb_find_interface_driver (struct usb_device *dev,
struct usb_interface *interface);
#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep)))
#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
/*
* USB device fs stuff
*/
#ifdef CONFIG_USB_DEVICEFS
/*
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
*/
extern void usbfs_add_bus(struct usb_bus *bus);
extern void usbfs_remove_bus(struct usb_bus *bus);
extern void usbfs_add_device(struct usb_device *dev);
extern void usbfs_remove_device(struct usb_device *dev);
extern void usbfs_update_special (void);
extern int usbfs_init(void);
extern void usbfs_cleanup(void);
#else /* CONFIG_USB_DEVICEFS */
static inline void usbfs_add_bus(struct usb_bus *bus) {}
static inline void usbfs_remove_bus(struct usb_bus *bus) {}
static inline void usbfs_add_device(struct usb_device *dev) {}
static inline void usbfs_remove_device(struct usb_device *dev) {}
static inline void usbfs_update_special (void) {}
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }
#endif /* CONFIG_USB_DEVICEFS */
/*-------------------------------------------------------------------------*/
/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
// bleech -- resurfaced in 2.4.11 or 2.4.12
#define bitmap DeviceRemovable
/*-------------------------------------------------------------------------*/
/* random stuff */
#define RUN_CONTEXT (in_irq () ? "in_irq" \
: (in_interrupt () ? "in_interrupt" : "can sleep"))
#endif /* __KERNEL__ */

File diff suppressed because it is too large Load diff

View file

@ -1,195 +1,195 @@
#ifndef __LINUX_HUB_H
#define __LINUX_HUB_H
/*
* Hub protocol and driver data structures.
*
* Some of these are known to the "virtual root hub" code
* in host controller drivers.
*/
#if 0
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/compiler.h> /* likely()/unlikely() */
#endif
/*
* Hub request types
*/
#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
/*
* Hub class requests
* See USB 2.0 spec Table 11-16
*/
#define HUB_CLEAR_TT_BUFFER 8
#define HUB_RESET_TT 9
#define HUB_GET_TT_STATE 10
#define HUB_STOP_TT 11
/*
* Hub Class feature numbers
* See USB 2.0 spec Table 11-17
*/
#define C_HUB_LOCAL_POWER 0
#define C_HUB_OVER_CURRENT 1
/*
* Port feature numbers
* See USB 2.0 spec Table 11-17
*/
#define USB_PORT_FEAT_CONNECTION 0
#define USB_PORT_FEAT_ENABLE 1
#define USB_PORT_FEAT_SUSPEND 2
#define USB_PORT_FEAT_OVER_CURRENT 3
#define USB_PORT_FEAT_RESET 4
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
#define USB_PORT_FEAT_HIGHSPEED 10
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
#define USB_PORT_FEAT_C_OVER_CURRENT 19
#define USB_PORT_FEAT_C_RESET 20
#define USB_PORT_FEAT_TEST 21
#define USB_PORT_FEAT_INDICATOR 22
/*
* Hub Status and Hub Change results
* See USB 2.0 spec Table 11-19 and Table 11-20
*/
struct usb_port_status {
__u16 wPortStatus;
__u16 wPortChange;
} __attribute__ ((packed));
/*
* wPortStatus bit field
* See USB 2.0 spec Table 11-21
*/
#define USB_PORT_STAT_CONNECTION 0x0001
#define USB_PORT_STAT_ENABLE 0x0002
#define USB_PORT_STAT_SUSPEND 0x0004
#define USB_PORT_STAT_OVERCURRENT 0x0008
#define USB_PORT_STAT_RESET 0x0010
/* bits 5 to 7 are reserved */
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
#define USB_PORT_STAT_HIGH_SPEED 0x0400
#define USB_PORT_STAT_TEST 0x0800
#define USB_PORT_STAT_INDICATOR 0x1000
/* bits 13 to 15 are reserved */
/*
* wPortChange bit field
* See USB 2.0 spec Table 11-22
* Bits 0 to 4 shown, bits 5 to 15 are reserved
*/
#define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
#define USB_PORT_STAT_C_SUSPEND 0x0004
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
#define USB_PORT_STAT_C_RESET 0x0010
/*
* wHubCharacteristics (masks)
* See USB 2.0 spec Table 11-13, offset 3
*/
#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
#define HUB_CHAR_PORTIND 0x0080 /* D7 */
struct usb_hub_status {
__u16 wHubStatus;
__u16 wHubChange;
} __attribute__ ((packed));
/*
* Hub Status & Hub Change bit masks
* See USB 2.0 spec Table 11-19 and Table 11-20
* Bits 0 and 1 for wHubStatus and wHubChange
* Bits 2 to 15 are reserved for both
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
/*
* Hub descriptor
* See USB 2.0 spec Table 11-13
*/
#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
#define USB_DT_HUB_NONVAR_SIZE 7
struct usb_hub_descriptor {
__u8 bDescLength;
__u8 bDescriptorType;
__u8 bNbrPorts;
__u16 wHubCharacteristics;
__u8 bPwrOn2PwrGood;
__u8 bHubContrCurrent;
/* add 1 bit for hub status change; round to bytes */
__u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
__u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
} __attribute__ ((packed));
struct usb_device;
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct usb_tt {
struct usb_device *hub; /* upstream highspeed hub */
int multi; /* true means one TT per port */
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
spinlock_t lock;
struct list_head clear_list; /* of usb_tt_clear */
struct work_struct kevent;
};
struct usb_tt_clear {
struct list_head clear_list;
unsigned tt;
u16 devinfo;
};
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
struct usb_interface *intf; /* the "real" device */
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */
char (*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */
int nerrors; /* track consecutive errors */
struct list_head hub_list; /* all hubs */
struct list_head event_list; /* hubs w/data or errs ready */
struct usb_hub_descriptor *descriptor; /* class descriptor */
struct semaphore khubd_sem;
struct usb_tt tt; /* Transaction Translator */
};
#endif /* __LINUX_HUB_H */
#ifndef __LINUX_HUB_H
#define __LINUX_HUB_H
/*
* Hub protocol and driver data structures.
*
* Some of these are known to the "virtual root hub" code
* in host controller drivers.
*/
#if 0
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/compiler.h> /* likely()/unlikely() */
#endif
/*
* Hub request types
*/
#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
/*
* Hub class requests
* See USB 2.0 spec Table 11-16
*/
#define HUB_CLEAR_TT_BUFFER 8
#define HUB_RESET_TT 9
#define HUB_GET_TT_STATE 10
#define HUB_STOP_TT 11
/*
* Hub Class feature numbers
* See USB 2.0 spec Table 11-17
*/
#define C_HUB_LOCAL_POWER 0
#define C_HUB_OVER_CURRENT 1
/*
* Port feature numbers
* See USB 2.0 spec Table 11-17
*/
#define USB_PORT_FEAT_CONNECTION 0
#define USB_PORT_FEAT_ENABLE 1
#define USB_PORT_FEAT_SUSPEND 2
#define USB_PORT_FEAT_OVER_CURRENT 3
#define USB_PORT_FEAT_RESET 4
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
#define USB_PORT_FEAT_HIGHSPEED 10
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
#define USB_PORT_FEAT_C_OVER_CURRENT 19
#define USB_PORT_FEAT_C_RESET 20
#define USB_PORT_FEAT_TEST 21
#define USB_PORT_FEAT_INDICATOR 22
/*
* Hub Status and Hub Change results
* See USB 2.0 spec Table 11-19 and Table 11-20
*/
struct usb_port_status {
__u16 wPortStatus;
__u16 wPortChange;
} __attribute__ ((packed));
/*
* wPortStatus bit field
* See USB 2.0 spec Table 11-21
*/
#define USB_PORT_STAT_CONNECTION 0x0001
#define USB_PORT_STAT_ENABLE 0x0002
#define USB_PORT_STAT_SUSPEND 0x0004
#define USB_PORT_STAT_OVERCURRENT 0x0008
#define USB_PORT_STAT_RESET 0x0010
/* bits 5 to 7 are reserved */
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
#define USB_PORT_STAT_HIGH_SPEED 0x0400
#define USB_PORT_STAT_TEST 0x0800
#define USB_PORT_STAT_INDICATOR 0x1000
/* bits 13 to 15 are reserved */
/*
* wPortChange bit field
* See USB 2.0 spec Table 11-22
* Bits 0 to 4 shown, bits 5 to 15 are reserved
*/
#define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
#define USB_PORT_STAT_C_SUSPEND 0x0004
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
#define USB_PORT_STAT_C_RESET 0x0010
/*
* wHubCharacteristics (masks)
* See USB 2.0 spec Table 11-13, offset 3
*/
#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
#define HUB_CHAR_PORTIND 0x0080 /* D7 */
struct usb_hub_status {
__u16 wHubStatus;
__u16 wHubChange;
} __attribute__ ((packed));
/*
* Hub Status & Hub Change bit masks
* See USB 2.0 spec Table 11-19 and Table 11-20
* Bits 0 and 1 for wHubStatus and wHubChange
* Bits 2 to 15 are reserved for both
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
/*
* Hub descriptor
* See USB 2.0 spec Table 11-13
*/
#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
#define USB_DT_HUB_NONVAR_SIZE 7
struct usb_hub_descriptor {
__u8 bDescLength;
__u8 bDescriptorType;
__u8 bNbrPorts;
__u16 wHubCharacteristics;
__u8 bPwrOn2PwrGood;
__u8 bHubContrCurrent;
/* add 1 bit for hub status change; round to bytes */
__u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
__u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
} __attribute__ ((packed));
struct usb_device;
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct usb_tt {
struct usb_device *hub; /* upstream highspeed hub */
int multi; /* true means one TT per port */
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
spinlock_t lock;
struct list_head clear_list; /* of usb_tt_clear */
struct work_struct kevent;
};
struct usb_tt_clear {
struct list_head clear_list;
unsigned tt;
u16 devinfo;
};
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
struct usb_interface *intf; /* the "real" device */
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */
char (*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */
int nerrors; /* track consecutive errors */
struct list_head hub_list; /* all hubs */
struct list_head event_list; /* hubs w/data or errs ready */
struct usb_hub_descriptor *descriptor; /* class descriptor */
struct semaphore khubd_sem;
struct usb_tt tt; /* Transaction Translator */
};
#endif /* __LINUX_HUB_H */

View file

@ -1,22 +1,25 @@
PATH_TO_TOP = ../../../..
TARGET_TYPE = export_driver
TARGET_NAME = usbcore
TARGET_DDKLIBS = ntoskrnl.a
TARGET_CFLAGS = -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -DDEBUG_MODE
TARGET_OBJECTS = \
message.o hcd.o hcd-pci.o hub.o usb.o config.o urb.o \
buffer_simple.o usb-debug.o ../sys/ros_wrapper.o \
../sys/linuxwrapper.o usbcore.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# Automatic dependency tracking
DEP_OBJECTS := $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/tools/depend.mk
PATH_TO_TOP = ../../../..
TARGET_TYPE = export_driver
TARGET_NAME = usbcore
TARGET_DDKLIBS = ntoskrnl.a
TARGET_CFLAGS = -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -DDEBUG_MODE
TARGET_OBJECTS = \
message.o hcd.o hcd-pci.o hub.o usb.o config.o urb.o \
buffer_simple.o usb-debug.o ../sys/ros_wrapper.o \
../sys/linuxwrapper.o usbcore.o
TARGET_LIBS = \
$(PATH_TO_TOP)/dk/nkm/lib/libusbcore.a
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# Automatic dependency tracking
DEP_OBJECTS := $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/tools/depend.mk

View file

@ -1,6 +1,6 @@
O_TARGET := message.o hcd.o hcd-pci.o hub.o usb.o config.o urb.o buffer_simple.o urb.o usb-debug.o
#O_TARGET := urb.o
include $(TOPDIR)/Rules.make
O_TARGET := message.o hcd.o hcd-pci.o hub.o usb.o config.o urb.o buffer_simple.o urb.o usb-debug.o
#O_TARGET := urb.o
include $(TOPDIR)/Rules.make

File diff suppressed because it is too large Load diff

View file

@ -1,398 +1,398 @@
#include "../usb_wrapper.h"
#include "hcd.h"
/**
* usb_init_urb - initializes a urb so that it can be used by a USB driver
* @urb: pointer to the urb to initialize
*
* Initializes a urb so that the USB subsystem can use it properly.
*
* If a urb is created with a call to usb_alloc_urb() it is not
* necessary to call this function. Only use this if you allocate the
* space for a struct urb on your own. If you call this function, be
* careful when freeing the memory for your urb that it is no longer in
* use by the USB core.
*
* Only use this function if you _really_ understand what you are doing.
*/
void STDCALL usb_init_urb(struct urb *urb)
{
if (urb) {
memset(urb, 0, sizeof(*urb));
urb->count = (atomic_t)ATOMIC_INIT(1);
spin_lock_init(&urb->lock);
}
}
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
* @iso_packets: number of iso packets for this urb
* @mem_flags: the type of memory to allocate, see kmalloc() for a list of
* valid options for this.
*
* Creates an urb for the USB driver to use, initializes a few internal
* structures, incrementes the usage counter, and returns a pointer to it.
*
* If no memory is available, NULL is returned.
*
* If the driver want to use this urb for interrupt, control, or bulk
* endpoints, pass '0' as the number of iso packets.
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
struct urb STDCALL *usb_alloc_urb(int iso_packets, int mem_flags)
{
struct urb *urb;
urb = (struct urb *)kmalloc(sizeof(struct urb) +
iso_packets * sizeof(struct usb_iso_packet_descriptor),
mem_flags);
if (!urb) {
err("alloc_urb: kmalloc failed");
return NULL;
}
usb_init_urb(urb);
return urb;
}
/**
* usb_free_urb - frees the memory used by a urb when all users of it are finished
* @urb: pointer to the urb to free
*
* Must be called when a user of a urb is finished with it. When the last user
* of the urb calls this function, the memory of the urb is freed.
*
* Note: The transfer buffer associated with the urb is not freed, that must be
* done elsewhere.
*/
void STDCALL usb_free_urb(struct urb *urb)
{
if (urb)
if (atomic_dec_and_test(&urb->count))
{
kfree(urb);
}
}
/**
* usb_get_urb - increments the reference count of the urb
* @urb: pointer to the urb to modify
*
* This must be called whenever a urb is transferred from a device driver to a
* host controller driver. This allows proper reference counting to happen
* for urbs.
*
* A pointer to the urb with the incremented reference counter is returned.
*/
struct urb STDCALL * usb_get_urb(struct urb *urb)
{
if (urb) {
atomic_inc(&urb->count);
return urb;
} else
return NULL;
}
/*-------------------------------------------------------------------*/
/**
* usb_submit_urb - issue an asynchronous transfer request for an endpoint
* @urb: pointer to the urb describing the request
* @mem_flags: the type of memory to allocate, see kmalloc() for a list
* of valid options for this.
*
* This submits a transfer request, and transfers control of the URB
* describing that request to the USB subsystem. Request completion will
* be indicated later, asynchronously, by calling the completion handler.
* The three types of completion are success, error, and unlink
* (also called "request cancellation").
* URBs may be submitted in interrupt context.
*
* The caller must have correctly initialized the URB before submitting
* it. Functions such as usb_fill_bulk_urb() and usb_fill_control_urb() are
* available to ensure that most fields are correctly initialized, for
* the particular kind of transfer, although they will not initialize
* any transfer flags.
*
* Successful submissions return 0; otherwise this routine returns a
* negative error number. If the submission is successful, the complete()
* callback from the urb will be called exactly once, when the USB core and
* host controller driver are finished with the urb. When the completion
* function is called, control of the URB is returned to the device
* driver which issued the request. The completion handler may then
* immediately free or reuse that URB.
*
* For control endpoints, the synchronous usb_control_msg() call is
* often used (in non-interrupt context) instead of this call.
* That is often used through convenience wrappers, for the requests
* that are standardized in the USB 2.0 specification. For bulk
* endpoints, a synchronous usb_bulk_msg() call is available.
*
* Request Queuing:
*
* URBs may be submitted to endpoints before previous ones complete, to
* minimize the impact of interrupt latencies and system overhead on data
* throughput. This is required for continuous isochronous data streams,
* and may also be required for some kinds of interrupt transfers. Such
* queueing also maximizes bandwidth utilization by letting USB controllers
* start work on later requests before driver software has finished the
* completion processing for earlier requests.
*
* Bulk and Isochronous URBs may always be queued. At this writing, all
* mainstream host controller drivers support queueing for control and
* interrupt transfer requests.
*
* Reserved Bandwidth Transfers:
*
* Periodic transfers (interrupt or isochronous) are performed repeatedly,
* using the interval specified in the urb. Submitting the first urb to
* the endpoint reserves the bandwidth necessary to make those transfers.
* If the USB subsystem can't allocate sufficient bandwidth to perform
* the periodic request, submitting such a periodic request should fail.
*
* Device drivers must explicitly request that repetition, by ensuring that
* some URB is always on the endpoint's queue (except possibly for short
* periods during completion callacks). When there is no longer an urb
* queued, the endpoint's bandwidth reservation is canceled. This means
* drivers can use their completion handlers to ensure they keep bandwidth
* they need, by reinitializing and resubmitting the just-completed urb
* until the driver longer needs that periodic bandwidth.
*
* Memory Flags:
*
* The general rules for how to decide which mem_flags to use
* are the same as for kmalloc. There are four
* different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and
* GFP_ATOMIC.
*
* GFP_NOFS is not ever used, as it has not been implemented yet.
*
* GFP_ATOMIC is used when
* (a) you are inside a completion handler, an interrupt, bottom half,
* tasklet or timer, or
* (b) you are holding a spinlock or rwlock (does not apply to
* semaphores), or
* (c) current->state != TASK_RUNNING, this is the case only after
* you've changed it.
*
* GFP_NOIO is used in the block io path and error handling of storage
* devices.
*
* All other situations use GFP_KERNEL.
*
* Some more specific rules for mem_flags can be inferred, such as
* (1) start_xmit, timeout, and receive methods of network drivers must
* use GFP_ATOMIC (they are called with a spinlock held);
* (2) queuecommand methods of scsi drivers must use GFP_ATOMIC (also
* called with a spinlock held);
* (3) If you use a kernel thread with a network driver you must use
* GFP_NOIO, unless (b) or (c) apply;
* (4) after you have done a down() you can use GFP_KERNEL, unless (b) or (c)
* apply or your are in a storage driver's block io path;
* (5) USB probe and disconnect can use GFP_KERNEL unless (b) or (c) apply; and
* (6) changing firmware on a running storage or net device uses
* GFP_NOIO, unless b) or c) apply
*
*/
int STDCALL usb_submit_urb(struct urb *urb, int mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
struct usb_operations *op;
int is_out;
// printk("sub dev %p bus %p num %i op %p sub %p\n",
// urb->dev, urb->dev->bus,urb->dev->devnum,urb->dev->bus->op, urb->dev->bus->op->submit_urb);
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
if (!(dev = urb->dev) ||
(dev->state < USB_STATE_DEFAULT) ||
(!dev->bus) || (dev->devnum <= 0))
return -ENODEV;
if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV;
urb->status = -EINPROGRESS;
urb->actual_length = 0;
urb->bandwidth = 0;
/* Lots of sanity checks, so HCDs can rely on clean data
* and don't need to duplicate tests
*/
pipe = urb->pipe;
temp = usb_pipetype (pipe);
is_out = usb_pipeout (pipe);
if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED)
return -ENODEV;
/* (actually HCDs may need to duplicate this, endpoint might yet
* stall due to queued bulk/intr transactions that complete after
* we check)
*/
if (usb_endpoint_halted (dev, usb_pipeendpoint (pipe), is_out))
return -EPIPE;
/* FIXME there should be a sharable lock protecting us against
* config/altsetting changes and disconnects, kicking in here.
* (here == before maxpacket, and eventually endpoint type,
* checks get made.)
*/
max = usb_maxpacket (dev, pipe, is_out);
if (max <= 0) {
dbg ("%s: bogus endpoint %d-%s on usb-%s-%s (bad maxpacket %d)",
__FUNCTION__,
usb_pipeendpoint (pipe), is_out ? "OUT" : "IN",
dev->bus->bus_name, dev->devpath,
max);
return -EMSGSIZE;
}
/* periodic transfers limit size per frame/uframe,
* but drivers only control those sizes for ISO.
* while we're checking, initialize return status.
*/
if (temp == PIPE_ISOCHRONOUS) {
int n, len;
/* "high bandwidth" mode, 1-3 packets/uframe? */
if (dev->speed == USB_SPEED_HIGH) {
int mult = 1 + ((max >> 11) & 0x03);
max &= 0x03ff;
max *= mult;
}
if (urb->number_of_packets <= 0)
return -EINVAL;
for (n = 0; n < urb->number_of_packets; n++) {
len = urb->iso_frame_desc [n].length;
if (len < 0 || len > max)
return -EMSGSIZE;
urb->iso_frame_desc [n].status = -EXDEV;
urb->iso_frame_desc [n].actual_length = 0;
}
}
/* the I/O buffer must be mapped/unmapped, except when length=0 */
if (urb->transfer_buffer_length < 0)
return -EMSGSIZE;
#ifdef DEBUG
/* stuff that drivers shouldn't do, but which shouldn't
* cause problems in HCDs if they get it wrong.
*/
{
unsigned int orig_flags = urb->transfer_flags;
unsigned int allowed;
/* enforce simple/standard policy */
allowed = URB_ASYNC_UNLINK; // affects later unlinks
allowed |= URB_NO_DMA_MAP;
allowed |= URB_NO_INTERRUPT;
switch (temp) {
case PIPE_BULK:
if (is_out)
allowed |= URB_ZERO_PACKET;
/* FALLTHROUGH */
case PIPE_CONTROL:
allowed |= URB_NO_FSBR; /* only affects UHCI */
/* FALLTHROUGH */
default: /* all non-iso endpoints */
if (!is_out)
allowed |= URB_SHORT_NOT_OK;
break;
case PIPE_ISOCHRONOUS:
allowed |= URB_ISO_ASAP;
break;
}
urb->transfer_flags &= allowed;
/* fail if submitter gave bogus flags */
if (urb->transfer_flags != orig_flags) {
err ("BOGUS urb flags, %x --> %x",
orig_flags, urb->transfer_flags);
return -EINVAL;
}
}
#endif
/*
* Force periodic transfer intervals to be legal values that are
* a power of two (so HCDs don't need to).
*
* FIXME want bus->{intr,iso}_sched_horizon values here. Each HC
* supports different values... this uses EHCI/UHCI defaults (and
* EHCI can use smaller non-default values).
*/
switch (temp) {
case PIPE_ISOCHRONOUS:
case PIPE_INTERRUPT:
/* too small? */
if (urb->interval <= 0)
return -EINVAL;
/* too big? */
switch (dev->speed) {
case USB_SPEED_HIGH: /* units are microframes */
// NOTE usb handles 2^15
if (urb->interval > (1024 * 8))
urb->interval = 1024 * 8;
temp = 1024 * 8;
break;
case USB_SPEED_FULL: /* units are frames/msec */
case USB_SPEED_LOW:
if (temp == PIPE_INTERRUPT) {
if (urb->interval > 255)
return -EINVAL;
// NOTE ohci only handles up to 32
temp = 128;
} else {
if (urb->interval > 1024)
urb->interval = 1024;
// NOTE usb and ohci handle up to 2^15
temp = 1024;
}
break;
default:
return -EINVAL;
}
/* power of two? */
while (temp > urb->interval)
temp >>= 1;
urb->interval = temp;
}
return op->submit_urb (urb, mem_flags);
}
/*-------------------------------------------------------------------*/
/**
* usb_unlink_urb - abort/cancel a transfer request for an endpoint
* @urb: pointer to urb describing a previously submitted request
*
* This routine cancels an in-progress request. The requests's
* completion handler will be called with a status code indicating
* that the request has been canceled, and that control of the URB
* has been returned to that device driver.
*
* When the URB_ASYNC_UNLINK transfer flag for the URB is clear, this
* request is synchronous. Success is indicated by returning zero,
* at which time the urb will have been unlinked,
* and the completion function will see status -ENOENT. Failure is
* indicated by any other return value. This mode may not be used
* when unlinking an urb from an interrupt context, such as a bottom
* half or a completion handler,
*
* When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
* request is asynchronous. Success is indicated by returning -EINPROGRESS,
* at which time the urb will normally not have been unlinked,
* and the completion function will see status -ECONNRESET. Failure is
* indicated by any other return value.
*/
int STDCALL usb_unlink_urb(struct urb *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb);
else
return -ENODEV;
}
#include "../usb_wrapper.h"
#include "hcd.h"
/**
* usb_init_urb - initializes a urb so that it can be used by a USB driver
* @urb: pointer to the urb to initialize
*
* Initializes a urb so that the USB subsystem can use it properly.
*
* If a urb is created with a call to usb_alloc_urb() it is not
* necessary to call this function. Only use this if you allocate the
* space for a struct urb on your own. If you call this function, be
* careful when freeing the memory for your urb that it is no longer in
* use by the USB core.
*
* Only use this function if you _really_ understand what you are doing.
*/
void STDCALL usb_init_urb(struct urb *urb)
{
if (urb) {
memset(urb, 0, sizeof(*urb));
urb->count = (atomic_t)ATOMIC_INIT(1);
spin_lock_init(&urb->lock);
}
}
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
* @iso_packets: number of iso packets for this urb
* @mem_flags: the type of memory to allocate, see kmalloc() for a list of
* valid options for this.
*
* Creates an urb for the USB driver to use, initializes a few internal
* structures, incrementes the usage counter, and returns a pointer to it.
*
* If no memory is available, NULL is returned.
*
* If the driver want to use this urb for interrupt, control, or bulk
* endpoints, pass '0' as the number of iso packets.
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
struct urb STDCALL *usb_alloc_urb(int iso_packets, int mem_flags)
{
struct urb *urb;
urb = (struct urb *)kmalloc(sizeof(struct urb) +
iso_packets * sizeof(struct usb_iso_packet_descriptor),
mem_flags);
if (!urb) {
err("alloc_urb: kmalloc failed");
return NULL;
}
usb_init_urb(urb);
return urb;
}
/**
* usb_free_urb - frees the memory used by a urb when all users of it are finished
* @urb: pointer to the urb to free
*
* Must be called when a user of a urb is finished with it. When the last user
* of the urb calls this function, the memory of the urb is freed.
*
* Note: The transfer buffer associated with the urb is not freed, that must be
* done elsewhere.
*/
void STDCALL usb_free_urb(struct urb *urb)
{
if (urb)
if (atomic_dec_and_test(&urb->count))
{
kfree(urb);
}
}
/**
* usb_get_urb - increments the reference count of the urb
* @urb: pointer to the urb to modify
*
* This must be called whenever a urb is transferred from a device driver to a
* host controller driver. This allows proper reference counting to happen
* for urbs.
*
* A pointer to the urb with the incremented reference counter is returned.
*/
struct urb STDCALL * usb_get_urb(struct urb *urb)
{
if (urb) {
atomic_inc(&urb->count);
return urb;
} else
return NULL;
}
/*-------------------------------------------------------------------*/
/**
* usb_submit_urb - issue an asynchronous transfer request for an endpoint
* @urb: pointer to the urb describing the request
* @mem_flags: the type of memory to allocate, see kmalloc() for a list
* of valid options for this.
*
* This submits a transfer request, and transfers control of the URB
* describing that request to the USB subsystem. Request completion will
* be indicated later, asynchronously, by calling the completion handler.
* The three types of completion are success, error, and unlink
* (also called "request cancellation").
* URBs may be submitted in interrupt context.
*
* The caller must have correctly initialized the URB before submitting
* it. Functions such as usb_fill_bulk_urb() and usb_fill_control_urb() are
* available to ensure that most fields are correctly initialized, for
* the particular kind of transfer, although they will not initialize
* any transfer flags.
*
* Successful submissions return 0; otherwise this routine returns a
* negative error number. If the submission is successful, the complete()
* callback from the urb will be called exactly once, when the USB core and
* host controller driver are finished with the urb. When the completion
* function is called, control of the URB is returned to the device
* driver which issued the request. The completion handler may then
* immediately free or reuse that URB.
*
* For control endpoints, the synchronous usb_control_msg() call is
* often used (in non-interrupt context) instead of this call.
* That is often used through convenience wrappers, for the requests
* that are standardized in the USB 2.0 specification. For bulk
* endpoints, a synchronous usb_bulk_msg() call is available.
*
* Request Queuing:
*
* URBs may be submitted to endpoints before previous ones complete, to
* minimize the impact of interrupt latencies and system overhead on data
* throughput. This is required for continuous isochronous data streams,
* and may also be required for some kinds of interrupt transfers. Such
* queueing also maximizes bandwidth utilization by letting USB controllers
* start work on later requests before driver software has finished the
* completion processing for earlier requests.
*
* Bulk and Isochronous URBs may always be queued. At this writing, all
* mainstream host controller drivers support queueing for control and
* interrupt transfer requests.
*
* Reserved Bandwidth Transfers:
*
* Periodic transfers (interrupt or isochronous) are performed repeatedly,
* using the interval specified in the urb. Submitting the first urb to
* the endpoint reserves the bandwidth necessary to make those transfers.
* If the USB subsystem can't allocate sufficient bandwidth to perform
* the periodic request, submitting such a periodic request should fail.
*
* Device drivers must explicitly request that repetition, by ensuring that
* some URB is always on the endpoint's queue (except possibly for short
* periods during completion callacks). When there is no longer an urb
* queued, the endpoint's bandwidth reservation is canceled. This means
* drivers can use their completion handlers to ensure they keep bandwidth
* they need, by reinitializing and resubmitting the just-completed urb
* until the driver longer needs that periodic bandwidth.
*
* Memory Flags:
*
* The general rules for how to decide which mem_flags to use
* are the same as for kmalloc. There are four
* different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and
* GFP_ATOMIC.
*
* GFP_NOFS is not ever used, as it has not been implemented yet.
*
* GFP_ATOMIC is used when
* (a) you are inside a completion handler, an interrupt, bottom half,
* tasklet or timer, or
* (b) you are holding a spinlock or rwlock (does not apply to
* semaphores), or
* (c) current->state != TASK_RUNNING, this is the case only after
* you've changed it.
*
* GFP_NOIO is used in the block io path and error handling of storage
* devices.
*
* All other situations use GFP_KERNEL.
*
* Some more specific rules for mem_flags can be inferred, such as
* (1) start_xmit, timeout, and receive methods of network drivers must
* use GFP_ATOMIC (they are called with a spinlock held);
* (2) queuecommand methods of scsi drivers must use GFP_ATOMIC (also
* called with a spinlock held);
* (3) If you use a kernel thread with a network driver you must use
* GFP_NOIO, unless (b) or (c) apply;
* (4) after you have done a down() you can use GFP_KERNEL, unless (b) or (c)
* apply or your are in a storage driver's block io path;
* (5) USB probe and disconnect can use GFP_KERNEL unless (b) or (c) apply; and
* (6) changing firmware on a running storage or net device uses
* GFP_NOIO, unless b) or c) apply
*
*/
int STDCALL usb_submit_urb(struct urb *urb, int mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
struct usb_operations *op;
int is_out;
// printk("sub dev %p bus %p num %i op %p sub %p\n",
// urb->dev, urb->dev->bus,urb->dev->devnum,urb->dev->bus->op, urb->dev->bus->op->submit_urb);
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
if (!(dev = urb->dev) ||
(dev->state < USB_STATE_DEFAULT) ||
(!dev->bus) || (dev->devnum <= 0))
return -ENODEV;
if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV;
urb->status = -EINPROGRESS;
urb->actual_length = 0;
urb->bandwidth = 0;
/* Lots of sanity checks, so HCDs can rely on clean data
* and don't need to duplicate tests
*/
pipe = urb->pipe;
temp = usb_pipetype (pipe);
is_out = usb_pipeout (pipe);
if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED)
return -ENODEV;
/* (actually HCDs may need to duplicate this, endpoint might yet
* stall due to queued bulk/intr transactions that complete after
* we check)
*/
if (usb_endpoint_halted (dev, usb_pipeendpoint (pipe), is_out))
return -EPIPE;
/* FIXME there should be a sharable lock protecting us against
* config/altsetting changes and disconnects, kicking in here.
* (here == before maxpacket, and eventually endpoint type,
* checks get made.)
*/
max = usb_maxpacket (dev, pipe, is_out);
if (max <= 0) {
dbg ("%s: bogus endpoint %d-%s on usb-%s-%s (bad maxpacket %d)",
__FUNCTION__,
usb_pipeendpoint (pipe), is_out ? "OUT" : "IN",
dev->bus->bus_name, dev->devpath,
max);
return -EMSGSIZE;
}
/* periodic transfers limit size per frame/uframe,
* but drivers only control those sizes for ISO.
* while we're checking, initialize return status.
*/
if (temp == PIPE_ISOCHRONOUS) {
int n, len;
/* "high bandwidth" mode, 1-3 packets/uframe? */
if (dev->speed == USB_SPEED_HIGH) {
int mult = 1 + ((max >> 11) & 0x03);
max &= 0x03ff;
max *= mult;
}
if (urb->number_of_packets <= 0)
return -EINVAL;
for (n = 0; n < urb->number_of_packets; n++) {
len = urb->iso_frame_desc [n].length;
if (len < 0 || len > max)
return -EMSGSIZE;
urb->iso_frame_desc [n].status = -EXDEV;
urb->iso_frame_desc [n].actual_length = 0;
}
}
/* the I/O buffer must be mapped/unmapped, except when length=0 */
if (urb->transfer_buffer_length < 0)
return -EMSGSIZE;
#ifdef DEBUG
/* stuff that drivers shouldn't do, but which shouldn't
* cause problems in HCDs if they get it wrong.
*/
{
unsigned int orig_flags = urb->transfer_flags;
unsigned int allowed;
/* enforce simple/standard policy */
allowed = URB_ASYNC_UNLINK; // affects later unlinks
allowed |= URB_NO_DMA_MAP;
allowed |= URB_NO_INTERRUPT;
switch (temp) {
case PIPE_BULK:
if (is_out)
allowed |= URB_ZERO_PACKET;
/* FALLTHROUGH */
case PIPE_CONTROL:
allowed |= URB_NO_FSBR; /* only affects UHCI */
/* FALLTHROUGH */
default: /* all non-iso endpoints */
if (!is_out)
allowed |= URB_SHORT_NOT_OK;
break;
case PIPE_ISOCHRONOUS:
allowed |= URB_ISO_ASAP;
break;
}
urb->transfer_flags &= allowed;
/* fail if submitter gave bogus flags */
if (urb->transfer_flags != orig_flags) {
err ("BOGUS urb flags, %x --> %x",
orig_flags, urb->transfer_flags);
return -EINVAL;
}
}
#endif
/*
* Force periodic transfer intervals to be legal values that are
* a power of two (so HCDs don't need to).
*
* FIXME want bus->{intr,iso}_sched_horizon values here. Each HC
* supports different values... this uses EHCI/UHCI defaults (and
* EHCI can use smaller non-default values).
*/
switch (temp) {
case PIPE_ISOCHRONOUS:
case PIPE_INTERRUPT:
/* too small? */
if (urb->interval <= 0)
return -EINVAL;
/* too big? */
switch (dev->speed) {
case USB_SPEED_HIGH: /* units are microframes */
// NOTE usb handles 2^15
if (urb->interval > (1024 * 8))
urb->interval = 1024 * 8;
temp = 1024 * 8;
break;
case USB_SPEED_FULL: /* units are frames/msec */
case USB_SPEED_LOW:
if (temp == PIPE_INTERRUPT) {
if (urb->interval > 255)
return -EINVAL;
// NOTE ohci only handles up to 32
temp = 128;
} else {
if (urb->interval > 1024)
urb->interval = 1024;
// NOTE usb and ohci handle up to 2^15
temp = 1024;
}
break;
default:
return -EINVAL;
}
/* power of two? */
while (temp > urb->interval)
temp >>= 1;
urb->interval = temp;
}
return op->submit_urb (urb, mem_flags);
}
/*-------------------------------------------------------------------*/
/**
* usb_unlink_urb - abort/cancel a transfer request for an endpoint
* @urb: pointer to urb describing a previously submitted request
*
* This routine cancels an in-progress request. The requests's
* completion handler will be called with a status code indicating
* that the request has been canceled, and that control of the URB
* has been returned to that device driver.
*
* When the URB_ASYNC_UNLINK transfer flag for the URB is clear, this
* request is synchronous. Success is indicated by returning zero,
* at which time the urb will have been unlinked,
* and the completion function will see status -ENOENT. Failure is
* indicated by any other return value. This mode may not be used
* when unlinking an urb from an interrupt context, such as a bottom
* half or a completion handler,
*
* When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
* request is asynchronous. Success is indicated by returning -EINPROGRESS,
* at which time the urb will normally not have been unlinked,
* and the completion function will see status -ECONNRESET. Failure is
* indicated by any other return value.
*/
int STDCALL usb_unlink_urb(struct urb *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb);
else
return -ENODEV;
}

View file

@ -1,206 +1,206 @@
/*
* debug.c - USB debug helper routines.
*
* I just want these out of the way where they aren't in your
* face, but so that you can still use them..
*/
#define CONFIG_USB_DEBUG
#if 0
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#else
#include "../usb_wrapper.h"
#endif
static void usb_show_endpoint(struct usb_host_endpoint *endpoint)
{
usb_show_endpoint_descriptor(&endpoint->desc);
}
static void usb_show_interface(struct usb_host_interface *altsetting)
{
int i;
usb_show_interface_descriptor(&altsetting->desc);
for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
usb_show_endpoint(altsetting->endpoint + i);
}
static void usb_show_config(struct usb_host_config *config)
{
int i, j;
struct usb_interface *ifp;
usb_show_config_descriptor(&config->desc);
for (i = 0; i < config->desc.bNumInterfaces; i++) {
ifp = config->interface + i;
if (!ifp)
break;
printk("\n Interface: %d\n", i);
for (j = 0; j < ifp->num_altsetting; j++)
usb_show_interface(ifp->altsetting + j);
}
}
void usb_show_device(struct usb_device *dev)
{
int i;
usb_show_device_descriptor(&dev->descriptor);
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
usb_show_config(dev->config + i);
}
/*
* Parse and show the different USB descriptors.
*/
void usb_show_device_descriptor(struct usb_device_descriptor *desc)
{
if (!desc)
{
printk("Invalid USB device descriptor (NULL POINTER)\n");
return;
}
printk(" Length = %2d%s\n", desc->bLength,
desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");
printk(" DescriptorType = %02x\n", desc->bDescriptorType);
printk(" USB version = %x.%02x\n",
desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
printk(" Vendor:Product = %04x:%04x\n",
desc->idVendor, desc->idProduct);
printk(" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
printk(" NumConfigurations = %d\n", desc->bNumConfigurations);
printk(" Device version = %x.%02x\n",
desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
printk(" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
switch (desc->bDeviceClass) {
case 0:
printk(" Per-interface classes\n");
break;
case USB_CLASS_AUDIO:
printk(" Audio device class\n");
break;
case USB_CLASS_COMM:
printk(" Communications class\n");
break;
case USB_CLASS_HID:
printk(" Human Interface Devices class\n");
break;
case USB_CLASS_PRINTER:
printk(" Printer device class\n");
break;
case USB_CLASS_MASS_STORAGE:
printk(" Mass Storage device class\n");
break;
case USB_CLASS_HUB:
printk(" Hub device class\n");
break;
case USB_CLASS_VENDOR_SPEC:
printk(" Vendor class\n");
break;
default:
printk(" Unknown class\n");
}
}
void usb_show_config_descriptor(struct usb_config_descriptor *desc)
{
printk("Configuration:\n");
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_CONFIG_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" wTotalLength = %04x\n", desc->wTotalLength);
printk(" bNumInterfaces = %02x\n", desc->bNumInterfaces);
printk(" bConfigurationValue = %02x\n", desc->bConfigurationValue);
printk(" iConfiguration = %02x\n", desc->iConfiguration);
printk(" bmAttributes = %02x\n", desc->bmAttributes);
printk(" bMaxPower = %4dmA\n", desc->bMaxPower * 2);
}
void usb_show_interface_descriptor(struct usb_interface_descriptor *desc)
{
printk(" Alternate Setting: %2d\n", desc->bAlternateSetting);
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bInterfaceNumber = %02x\n", desc->bInterfaceNumber);
printk(" bAlternateSetting = %02x\n", desc->bAlternateSetting);
printk(" bNumEndpoints = %02x\n", desc->bNumEndpoints);
printk(" bInterface Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol);
printk(" iInterface = %02x\n", desc->iInterface);
}
void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *desc)
{
char *LengthCommentString = (desc->bLength ==
USB_DT_ENDPOINT_AUDIO_SIZE) ? " (Audio)" : (desc->bLength ==
USB_DT_ENDPOINT_SIZE) ? "" : " (!!!)";
char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };
printk(" Endpoint:\n");
printk(" bLength = %4d%s\n",
desc->bLength, LengthCommentString);
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bEndpointAddress = %02x (%s)\n", desc->bEndpointAddress,
(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL ? "i/o" :
(desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? "in" : "out");
printk(" bmAttributes = %02x (%s)\n", desc->bmAttributes,
EndpointType[USB_ENDPOINT_XFERTYPE_MASK & desc->bmAttributes]);
printk(" wMaxPacketSize = %04x\n", desc->wMaxPacketSize);
printk(" bInterval = %02x\n", desc->bInterval);
/* Audio extensions to the endpoint descriptor */
if (desc->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) {
printk(" bRefresh = %02x\n", desc->bRefresh);
printk(" bSynchAddress = %02x\n", desc->bSynchAddress);
}
}
void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
if (!index)
return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
kfree(buf);
}
void usb_dump_urb (struct urb *urb)
{
printk ("urb :%p\n", urb);
printk ("dev :%p\n", urb->dev);
printk ("pipe :%08X\n", urb->pipe);
printk ("status :%d\n", urb->status);
printk ("transfer_flags :%08X\n", urb->transfer_flags);
printk ("transfer_buffer :%p\n", urb->transfer_buffer);
printk ("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
printk ("actual_length :%d\n", urb->actual_length);
printk ("setup_packet :%p\n", urb->setup_packet);
printk ("start_frame :%d\n", urb->start_frame);
printk ("number_of_packets :%d\n", urb->number_of_packets);
printk ("interval :%d\n", urb->interval);
printk ("error_count :%d\n", urb->error_count);
printk ("context :%p\n", urb->context);
printk ("complete :%p\n", urb->complete);
}
/*
* debug.c - USB debug helper routines.
*
* I just want these out of the way where they aren't in your
* face, but so that you can still use them..
*/
#define CONFIG_USB_DEBUG
#if 0
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#else
#include "../usb_wrapper.h"
#endif
static void usb_show_endpoint(struct usb_host_endpoint *endpoint)
{
usb_show_endpoint_descriptor(&endpoint->desc);
}
static void usb_show_interface(struct usb_host_interface *altsetting)
{
int i;
usb_show_interface_descriptor(&altsetting->desc);
for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
usb_show_endpoint(altsetting->endpoint + i);
}
static void usb_show_config(struct usb_host_config *config)
{
int i, j;
struct usb_interface *ifp;
usb_show_config_descriptor(&config->desc);
for (i = 0; i < config->desc.bNumInterfaces; i++) {
ifp = config->interface + i;
if (!ifp)
break;
printk("\n Interface: %d\n", i);
for (j = 0; j < ifp->num_altsetting; j++)
usb_show_interface(ifp->altsetting + j);
}
}
void usb_show_device(struct usb_device *dev)
{
int i;
usb_show_device_descriptor(&dev->descriptor);
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
usb_show_config(dev->config + i);
}
/*
* Parse and show the different USB descriptors.
*/
void usb_show_device_descriptor(struct usb_device_descriptor *desc)
{
if (!desc)
{
printk("Invalid USB device descriptor (NULL POINTER)\n");
return;
}
printk(" Length = %2d%s\n", desc->bLength,
desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");
printk(" DescriptorType = %02x\n", desc->bDescriptorType);
printk(" USB version = %x.%02x\n",
desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
printk(" Vendor:Product = %04x:%04x\n",
desc->idVendor, desc->idProduct);
printk(" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
printk(" NumConfigurations = %d\n", desc->bNumConfigurations);
printk(" Device version = %x.%02x\n",
desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
printk(" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
switch (desc->bDeviceClass) {
case 0:
printk(" Per-interface classes\n");
break;
case USB_CLASS_AUDIO:
printk(" Audio device class\n");
break;
case USB_CLASS_COMM:
printk(" Communications class\n");
break;
case USB_CLASS_HID:
printk(" Human Interface Devices class\n");
break;
case USB_CLASS_PRINTER:
printk(" Printer device class\n");
break;
case USB_CLASS_MASS_STORAGE:
printk(" Mass Storage device class\n");
break;
case USB_CLASS_HUB:
printk(" Hub device class\n");
break;
case USB_CLASS_VENDOR_SPEC:
printk(" Vendor class\n");
break;
default:
printk(" Unknown class\n");
}
}
void usb_show_config_descriptor(struct usb_config_descriptor *desc)
{
printk("Configuration:\n");
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_CONFIG_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" wTotalLength = %04x\n", desc->wTotalLength);
printk(" bNumInterfaces = %02x\n", desc->bNumInterfaces);
printk(" bConfigurationValue = %02x\n", desc->bConfigurationValue);
printk(" iConfiguration = %02x\n", desc->iConfiguration);
printk(" bmAttributes = %02x\n", desc->bmAttributes);
printk(" bMaxPower = %4dmA\n", desc->bMaxPower * 2);
}
void usb_show_interface_descriptor(struct usb_interface_descriptor *desc)
{
printk(" Alternate Setting: %2d\n", desc->bAlternateSetting);
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bInterfaceNumber = %02x\n", desc->bInterfaceNumber);
printk(" bAlternateSetting = %02x\n", desc->bAlternateSetting);
printk(" bNumEndpoints = %02x\n", desc->bNumEndpoints);
printk(" bInterface Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol);
printk(" iInterface = %02x\n", desc->iInterface);
}
void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *desc)
{
char *LengthCommentString = (desc->bLength ==
USB_DT_ENDPOINT_AUDIO_SIZE) ? " (Audio)" : (desc->bLength ==
USB_DT_ENDPOINT_SIZE) ? "" : " (!!!)";
char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };
printk(" Endpoint:\n");
printk(" bLength = %4d%s\n",
desc->bLength, LengthCommentString);
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bEndpointAddress = %02x (%s)\n", desc->bEndpointAddress,
(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL ? "i/o" :
(desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? "in" : "out");
printk(" bmAttributes = %02x (%s)\n", desc->bmAttributes,
EndpointType[USB_ENDPOINT_XFERTYPE_MASK & desc->bmAttributes]);
printk(" wMaxPacketSize = %04x\n", desc->wMaxPacketSize);
printk(" bInterval = %02x\n", desc->bInterval);
/* Audio extensions to the endpoint descriptor */
if (desc->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) {
printk(" bRefresh = %02x\n", desc->bRefresh);
printk(" bSynchAddress = %02x\n", desc->bSynchAddress);
}
}
void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
if (!index)
return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
kfree(buf);
}
void usb_dump_urb (struct urb *urb)
{
printk ("urb :%p\n", urb);
printk ("dev :%p\n", urb->dev);
printk ("pipe :%08X\n", urb->pipe);
printk ("status :%d\n", urb->status);
printk ("transfer_flags :%08X\n", urb->transfer_flags);
printk ("transfer_buffer :%p\n", urb->transfer_buffer);
printk ("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
printk ("actual_length :%d\n", urb->actual_length);
printk ("setup_packet :%p\n", urb->setup_packet);
printk ("start_frame :%d\n", urb->start_frame);
printk ("number_of_packets :%d\n", urb->number_of_packets);
printk ("interval :%d\n", urb->interval);
printk ("error_count :%d\n", urb->error_count);
printk ("context :%p\n", urb->context);
printk ("complete :%p\n", urb->complete);
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* Functions local to drivers/usb/core/ */
extern void usb_create_driverfs_dev_files (struct usb_device *dev);
extern void usb_create_driverfs_intf_files (struct usb_interface *intf);
/* Functions local to drivers/usb/core/ */
extern void usb_create_driverfs_dev_files (struct usb_device *dev);
extern void usb_create_driverfs_intf_files (struct usb_interface *intf);

View file

@ -1,63 +1,67 @@
/*
ReactOS specific functions for usbcore module
by Aleksey Bragin (aleksey@reactos.com)
*/
#include <ddk/ntddk.h>
#include <debug.h>
NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
DbgPrint("usbcore: AddDevice called\n");
/* we need to do kind of this stuff here (as usual)
PDEVICE_OBJECT fdo;
IoCreateDevice(..., &fdo);
pdx->LowerDeviceObject =
IoAttachDeviceToDeviceStack(fdo, pdo);*/
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
// nothing to do here yet
}
// Dispatch PNP
NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp)
{
ULONG fcn;
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation(Irp);
fcn = stack->MinorFunction;
DbgPrint("IRP_MJ_PNP, fcn=%d\n", fcn);
if (fcn == IRP_MN_REMOVE_DEVICE)
{
IoDeleteDevice(fdo);
}
return STATUS_SUCCESS;
}
NTSTATUS DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DbgPrint("IRP_MJ_POWER dispatch\n");
return STATUS_SUCCESS;
}
/*
* Standard DriverEntry method.
*/
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}
/*
ReactOS specific functions for usbcore module
by Aleksey Bragin (aleksey@reactos.com)
*/
#include <ddk/ntddk.h>
#include <debug.h>
NTSTATUS STDCALL
AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
DbgPrint("usbcore: AddDevice called\n");
/* we need to do kind of this stuff here (as usual)
PDEVICE_OBJECT fdo;
IoCreateDevice(..., &fdo);
pdx->LowerDeviceObject =
IoAttachDeviceToDeviceStack(fdo, pdo);*/
return STATUS_SUCCESS;
}
VOID STDCALL
DriverUnload(PDRIVER_OBJECT DriverObject)
{
// nothing to do here yet
}
// Dispatch PNP
NTSTATUS STDCALL
DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp)
{
ULONG fcn;
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation(Irp);
fcn = stack->MinorFunction;
DbgPrint("IRP_MJ_PNP, fcn=%d\n", fcn);
if (fcn == IRP_MN_REMOVE_DEVICE)
{
IoDeleteDevice(fdo);
}
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DbgPrint("IRP_MJ_POWER dispatch\n");
return STATUS_SUCCESS;
}
/*
* Standard DriverEntry method.
*/
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}

View file

@ -1,32 +1,32 @@
;
; Exports definition file for usbcore.sys
;
EXPORTS
usb_init@0
usb_exit@0
usb_init_urb@4
usb_alloc_urb@8
usb_free_urb@4
usb_get_urb@4
usb_get_dev@4
usb_submit_urb@8
usb_unlink_urb@4
usb_bus_init@4
usb_alloc_bus@4
usb_free_bus@4
usb_register_bus@4
usb_deregister_bus@4
usb_register_root_hub@8
usb_calc_bus_time@16
usb_check_bandwidth@8
usb_claim_bandwidth@16
usb_release_bandwidth@12
usb_hcd_giveback_urb@12
;usb_hcd_irq@12
usb_hc_died@4
usb_alloc_dev@8
usb_connect@4
usb_put_dev@4
usb_disabled@0
usb_hcd_pci_probe@8
;
; Exports definition file for usbcore.sys
;
EXPORTS
usb_init@0
usb_exit@0
usb_init_urb@4
usb_alloc_urb@8
usb_free_urb@4
usb_get_urb@4
usb_get_dev@4
usb_submit_urb@8
usb_unlink_urb@4
usb_bus_init@4
usb_alloc_bus@4
usb_free_bus@4
usb_register_bus@4
usb_deregister_bus@4
usb_register_root_hub@8
usb_calc_bus_time@16
usb_check_bandwidth@8
usb_claim_bandwidth@16
usb_release_bandwidth@12
usb_hcd_giveback_urb@12
;usb_hcd_irq@12
usb_hc_died@4
usb_alloc_dev@8
usb_connect@4
usb_put_dev@4
usb_disabled@0
usb_hcd_pci_probe@8
usb_hcd_pci_remove@4

View file

@ -1,5 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB Core Device Driver\0"
#define REACTOS_STR_INTERNAL_NAME "usbcore\0"
#define REACTOS_STR_ORIGINAL_FILENAME "usbcore.sys\0"
#include <reactos/version.rc>
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB Core Device Driver\0"
#define REACTOS_STR_INTERNAL_NAME "usbcore\0"
#define REACTOS_STR_ORIGINAL_FILENAME "usbcore.sys\0"
#include <reactos/version.rc>

View file

@ -1,20 +1,20 @@
PATH_TO_TOP = ../../../..
TARGET_TYPE = export_driver
TARGET_NAME = ohci
TARGET_DDKLIBS = ntoskrnl.a usbcore.a
TARGET_CFLAGS = -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -DDEBUG_MODE
TARGET_OBJECTS = \
ohci-hcd.o ohci_main.o ../sys/ros_wrapper.o ../sys/linuxwrapper.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# Automatic dependency tracking
DEP_OBJECTS := $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/tools/depend.mk
PATH_TO_TOP = ../../../..
TARGET_TYPE = export_driver
TARGET_NAME = ohci
TARGET_DDKLIBS = ntoskrnl.a usbcore.a
TARGET_CFLAGS = -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -DDEBUG_MODE
TARGET_OBJECTS = \
ohci-hcd.o ohci_main.o ../sys/ros_wrapper.o ../sys/linuxwrapper.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# Automatic dependency tracking
DEP_OBJECTS := $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/tools/depend.mk

View file

@ -1,3 +1,3 @@
O_TARGET := ohci-hcd.o
include $(TOPDIR)/Rules.make
O_TARGET := ohci-hcd.o
include $(TOPDIR)/Rules.make

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,271 +1,271 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under GPL
*/
/*-------------------------------------------------------------------------*/
/*
* OHCI Root Hub ... the nonsharable stuff
*
* Registers don't need cpu_to_le32, that happens transparently
*/
/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
* The erratum (#4) description is incorrect. AMD's workaround waits
* till some bits (mostly reserved) are clear; ok for all revs.
*/
#define read_roothub(hc, register, mask) ({ \
u32 temp = readl (&hc->regs->roothub.register); \
if (temp == -1) \
disable (hc); \
else if (hc->flags & OHCI_QUIRK_AMD756) \
while (temp & mask) \
temp = readl (&hc->regs->roothub.register); \
temp; })
static u32 roothub_a (struct ohci_hcd *hc)
{ return read_roothub (hc, a, 0xfc0fe000); }
static inline u32 roothub_b (struct ohci_hcd *hc)
{ return readl (&hc->regs->roothub.b); }
static inline u32 roothub_status (struct ohci_hcd *hc)
{ return readl (&hc->regs->roothub.status); }
static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
/*-------------------------------------------------------------------------*/
#define dbg_port(hc,label,num,value) \
ohci_dbg (hc, \
"%s roothub.portstatus [%d] " \
"= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
label, num, temp, \
(temp & RH_PS_PRSC) ? " PRSC" : "", \
(temp & RH_PS_OCIC) ? " OCIC" : "", \
(temp & RH_PS_PSSC) ? " PSSC" : "", \
(temp & RH_PS_PESC) ? " PESC" : "", \
(temp & RH_PS_CSC) ? " CSC" : "", \
\
(temp & RH_PS_LSDA) ? " LSDA" : "", \
(temp & RH_PS_PPS) ? " PPS" : "", \
(temp & RH_PS_PRS) ? " PRS" : "", \
(temp & RH_PS_POCI) ? " POCI" : "", \
(temp & RH_PS_PSS) ? " PSS" : "", \
\
(temp & RH_PS_PES) ? " PES" : "", \
(temp & RH_PS_CCS) ? " CCS" : "" \
);
/*-------------------------------------------------------------------------*/
/* build "status change" packet (one or two bytes) from HC registers */
static int
ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports, i, changed = 0, length = 1;
ports = roothub_a (ohci) & RH_A_NDP;
if (ports > MAX_ROOT_PORTS) {
if (ohci->disabled)
return -ESHUTDOWN;
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
return 0;
}
/* init status */
if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
buf [0] = changed = 1;
else
buf [0] = 0;
if (ports > 7) {
buf [1] = 0;
length++;
}
/* look at each port */
for (i = 0; i < ports; i++) {
u32 status = roothub_portstatus (ohci, i);
status &= RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
| RH_PS_OCIC | RH_PS_PRSC;
if (status) {
changed = 1;
if (i < 7)
buf [0] |= 1 << (i + 1);
else
buf [1] |= 1 << (i - 7);
}
}
return changed ? length : 0;
}
/*-------------------------------------------------------------------------*/
static void
ohci_hub_descriptor (
struct ohci_hcd *ohci,
struct usb_hub_descriptor *desc
) {
u32 rh = roothub_a (ohci);
int ports = rh & RH_A_NDP;
u16 temp;
desc->bDescriptorType = 0x29;
desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
desc->bHubContrCurrent = 0;
desc->bNbrPorts = ports;
temp = 1 + (ports / 8);
desc->bDescLength = 7 + 2 * temp;
temp = 0;
if (rh & RH_A_PSM) /* per-port power switching? */
temp |= 0x0001;
if (rh & RH_A_NOCP) /* no overcurrent reporting? */
temp |= 0x0010;
else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */
temp |= 0x0008;
desc->wHubCharacteristics = cpu_to_le16 (temp);
/* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
rh = roothub_b (ohci);
desc->bitmap [0] = rh & RH_B_DR;
if (ports > 7) {
desc->bitmap [1] = (rh & RH_B_DR) >> 8;
desc->bitmap [2] = desc->bitmap [3] = 0xff;
} else
desc->bitmap [1] = 0xff;
}
/*-------------------------------------------------------------------------*/
static int ohci_hub_control (
struct usb_hcd *hcd,
u16 typeReq,
u16 wValue,
u16 wIndex,
char *buf,
u16 wLength
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports = hcd_to_bus (hcd)->root_hub->maxchild;
u32 temp;
int retval = 0;
switch (typeReq) {
case ClearHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
writel (RH_HS_OCIC, &ohci->regs->roothub.status);
case C_HUB_LOCAL_POWER:
break;
default:
goto error;
}
break;
case ClearPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
temp = RH_PS_CCS;
break;
case USB_PORT_FEAT_C_ENABLE:
temp = RH_PS_PESC;
break;
case USB_PORT_FEAT_SUSPEND:
temp = RH_PS_POCI;
break;
case USB_PORT_FEAT_C_SUSPEND:
temp = RH_PS_PSSC;
break;
case USB_PORT_FEAT_POWER:
temp = RH_PS_LSDA;
break;
case USB_PORT_FEAT_C_CONNECTION:
temp = RH_PS_CSC;
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
temp = RH_PS_OCIC;
break;
case USB_PORT_FEAT_C_RESET:
temp = RH_PS_PRSC;
break;
default:
goto error;
}
writel (temp, &ohci->regs->roothub.portstatus [wIndex]);
// readl (&ohci->regs->roothub.portstatus [wIndex]);
break;
case GetHubDescriptor:
ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
break;
case GetHubStatus:
temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
*(u32 *) buf = cpu_to_le32 (temp);
break;
case GetPortStatus:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
temp = roothub_portstatus (ohci, wIndex);
*(u32 *) buf = cpu_to_le32 (temp);
#ifndef OHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */
#endif
dbg_port (ohci, "GetStatus", wIndex + 1, temp);
break;
case SetHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
// FIXME: this can be cleared, yes?
case C_HUB_LOCAL_POWER:
break;
default:
goto error;
}
break;
case SetPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
writel (RH_PS_PSS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_POWER:
writel (RH_PS_PPS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_RESET:
temp = readl (&ohci->regs->roothub.portstatus [wIndex]);
if (temp & RH_PS_CCS)
writel (RH_PS_PRS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
default:
goto error;
}
break;
default:
error:
/* "protocol stall" on error */
retval = -EPIPE;
}
return retval;
}
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under GPL
*/
/*-------------------------------------------------------------------------*/
/*
* OHCI Root Hub ... the nonsharable stuff
*
* Registers don't need cpu_to_le32, that happens transparently
*/
/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
* The erratum (#4) description is incorrect. AMD's workaround waits
* till some bits (mostly reserved) are clear; ok for all revs.
*/
#define read_roothub(hc, register, mask) ({ \
u32 temp = readl (&hc->regs->roothub.register); \
if (temp == -1) \
disable (hc); \
else if (hc->flags & OHCI_QUIRK_AMD756) \
while (temp & mask) \
temp = readl (&hc->regs->roothub.register); \
temp; })
static u32 roothub_a (struct ohci_hcd *hc)
{ return read_roothub (hc, a, 0xfc0fe000); }
static inline u32 roothub_b (struct ohci_hcd *hc)
{ return readl (&hc->regs->roothub.b); }
static inline u32 roothub_status (struct ohci_hcd *hc)
{ return readl (&hc->regs->roothub.status); }
static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
/*-------------------------------------------------------------------------*/
#define dbg_port(hc,label,num,value) \
ohci_dbg (hc, \
"%s roothub.portstatus [%d] " \
"= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
label, num, temp, \
(temp & RH_PS_PRSC) ? " PRSC" : "", \
(temp & RH_PS_OCIC) ? " OCIC" : "", \
(temp & RH_PS_PSSC) ? " PSSC" : "", \
(temp & RH_PS_PESC) ? " PESC" : "", \
(temp & RH_PS_CSC) ? " CSC" : "", \
\
(temp & RH_PS_LSDA) ? " LSDA" : "", \
(temp & RH_PS_PPS) ? " PPS" : "", \
(temp & RH_PS_PRS) ? " PRS" : "", \
(temp & RH_PS_POCI) ? " POCI" : "", \
(temp & RH_PS_PSS) ? " PSS" : "", \
\
(temp & RH_PS_PES) ? " PES" : "", \
(temp & RH_PS_CCS) ? " CCS" : "" \
);
/*-------------------------------------------------------------------------*/
/* build "status change" packet (one or two bytes) from HC registers */
static int
ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports, i, changed = 0, length = 1;
ports = roothub_a (ohci) & RH_A_NDP;
if (ports > MAX_ROOT_PORTS) {
if (ohci->disabled)
return -ESHUTDOWN;
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
return 0;
}
/* init status */
if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
buf [0] = changed = 1;
else
buf [0] = 0;
if (ports > 7) {
buf [1] = 0;
length++;
}
/* look at each port */
for (i = 0; i < ports; i++) {
u32 status = roothub_portstatus (ohci, i);
status &= RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
| RH_PS_OCIC | RH_PS_PRSC;
if (status) {
changed = 1;
if (i < 7)
buf [0] |= 1 << (i + 1);
else
buf [1] |= 1 << (i - 7);
}
}
return changed ? length : 0;
}
/*-------------------------------------------------------------------------*/
static void
ohci_hub_descriptor (
struct ohci_hcd *ohci,
struct usb_hub_descriptor *desc
) {
u32 rh = roothub_a (ohci);
int ports = rh & RH_A_NDP;
u16 temp;
desc->bDescriptorType = 0x29;
desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
desc->bHubContrCurrent = 0;
desc->bNbrPorts = ports;
temp = 1 + (ports / 8);
desc->bDescLength = 7 + 2 * temp;
temp = 0;
if (rh & RH_A_PSM) /* per-port power switching? */
temp |= 0x0001;
if (rh & RH_A_NOCP) /* no overcurrent reporting? */
temp |= 0x0010;
else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */
temp |= 0x0008;
desc->wHubCharacteristics = cpu_to_le16 (temp);
/* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
rh = roothub_b (ohci);
desc->bitmap [0] = rh & RH_B_DR;
if (ports > 7) {
desc->bitmap [1] = (rh & RH_B_DR) >> 8;
desc->bitmap [2] = desc->bitmap [3] = 0xff;
} else
desc->bitmap [1] = 0xff;
}
/*-------------------------------------------------------------------------*/
static int ohci_hub_control (
struct usb_hcd *hcd,
u16 typeReq,
u16 wValue,
u16 wIndex,
char *buf,
u16 wLength
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports = hcd_to_bus (hcd)->root_hub->maxchild;
u32 temp;
int retval = 0;
switch (typeReq) {
case ClearHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
writel (RH_HS_OCIC, &ohci->regs->roothub.status);
case C_HUB_LOCAL_POWER:
break;
default:
goto error;
}
break;
case ClearPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
temp = RH_PS_CCS;
break;
case USB_PORT_FEAT_C_ENABLE:
temp = RH_PS_PESC;
break;
case USB_PORT_FEAT_SUSPEND:
temp = RH_PS_POCI;
break;
case USB_PORT_FEAT_C_SUSPEND:
temp = RH_PS_PSSC;
break;
case USB_PORT_FEAT_POWER:
temp = RH_PS_LSDA;
break;
case USB_PORT_FEAT_C_CONNECTION:
temp = RH_PS_CSC;
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
temp = RH_PS_OCIC;
break;
case USB_PORT_FEAT_C_RESET:
temp = RH_PS_PRSC;
break;
default:
goto error;
}
writel (temp, &ohci->regs->roothub.portstatus [wIndex]);
// readl (&ohci->regs->roothub.portstatus [wIndex]);
break;
case GetHubDescriptor:
ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
break;
case GetHubStatus:
temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
*(u32 *) buf = cpu_to_le32 (temp);
break;
case GetPortStatus:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
temp = roothub_portstatus (ohci, wIndex);
*(u32 *) buf = cpu_to_le32 (temp);
#ifndef OHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */
#endif
dbg_port (ohci, "GetStatus", wIndex + 1, temp);
break;
case SetHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
// FIXME: this can be cleared, yes?
case C_HUB_LOCAL_POWER:
break;
default:
goto error;
}
break;
case SetPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
writel (RH_PS_PSS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_POWER:
writel (RH_PS_PPS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_RESET:
temp = readl (&ohci->regs->roothub.portstatus [wIndex]);
if (temp & RH_PS_CCS)
writel (RH_PS_PRS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
default:
goto error;
}
break;
default:
error:
/* "protocol stall" on error */
retval = -EPIPE;
}
return retval;
}

View file

@ -1,146 +1,146 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*-------------------------------------------------------------------------*/
/*
* There's basically three types of memory:
* - data used only by the HCD ... kmalloc is fine
* - async and periodic schedules, shared by HC and HCD ... these
* need to use pci_pool or pci_alloc_consistent
* - driver buffers, read/written by HC ... the hcd glue or the
* device driver provides us with dma addresses
*
* There's also PCI "register" data, which is memory mapped.
* No memory seen by this driver is pagable.
*/
/*-------------------------------------------------------------------------*/
static struct usb_hcd *ohci_hcd_alloc (void)
{
struct ohci_hcd *ohci;
ohci = (struct ohci_hcd *) kmalloc (sizeof *ohci, GFP_KERNEL);
if (ohci != 0) {
memset (ohci, 0, sizeof (struct ohci_hcd));
return &ohci->hcd;
}
return 0;
}
static void ohci_hcd_free (struct usb_hcd *hcd)
{
kfree (hcd_to_ohci (hcd));
}
/*-------------------------------------------------------------------------*/
static int ohci_mem_init (struct ohci_hcd *ohci)
{
ohci->td_cache = pci_pool_create ("ohci_td", ohci->hcd.pdev,
sizeof (struct td),
32 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->td_cache)
return -ENOMEM;
ohci->ed_cache = pci_pool_create ("ohci_ed", ohci->hcd.pdev,
sizeof (struct ed),
16 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->ed_cache) {
pci_pool_destroy (ohci->td_cache);
return -ENOMEM;
}
return 0;
}
static void ohci_mem_cleanup (struct ohci_hcd *ohci)
{
if (ohci->td_cache) {
pci_pool_destroy (ohci->td_cache);
ohci->td_cache = 0;
}
if (ohci->ed_cache) {
pci_pool_destroy (ohci->ed_cache);
ohci->ed_cache = 0;
}
}
/*-------------------------------------------------------------------------*/
/* ohci "done list" processing needs this mapping */
static inline struct td *
dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
{
struct td *td;
td_dma &= TD_MASK;
td = hc->td_hash [TD_HASH_FUNC(td_dma)];
while (td && td->td_dma != td_dma)
td = td->td_hash;
return td;
}
/* TDs ... */
static struct td *
td_alloc (struct ohci_hcd *hc, int mem_flags)
{
dma_addr_t dma;
struct td *td;
td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
if (td) {
/* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma);
td->td_dma = dma;
/* hashed in td_fill */
}
return td;
}
static void
td_free (struct ohci_hcd *hc, struct td *td)
{
struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)];
while (*prev && *prev != td)
prev = &(*prev)->td_hash;
if (*prev)
*prev = td->td_hash;
else if ((td->hwINFO & TD_DONE) != 0)
ohci_dbg (hc, "no hash for td %p\n", td);
pci_pool_free (hc->td_cache, td, td->td_dma);
}
/*-------------------------------------------------------------------------*/
/* EDs ... */
static struct ed *
ed_alloc (struct ohci_hcd *hc, int mem_flags)
{
dma_addr_t dma;
struct ed *ed;
ed = pci_pool_alloc (hc->ed_cache, mem_flags, &dma);
if (ed) {
memset (ed, 0, sizeof (*ed));
INIT_LIST_HEAD (&ed->td_list);
ed->dma = dma;
}
return ed;
}
static void
ed_free (struct ohci_hcd *hc, struct ed *ed)
{
pci_pool_free (hc->ed_cache, ed, ed->dma);
}
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*-------------------------------------------------------------------------*/
/*
* There's basically three types of memory:
* - data used only by the HCD ... kmalloc is fine
* - async and periodic schedules, shared by HC and HCD ... these
* need to use pci_pool or pci_alloc_consistent
* - driver buffers, read/written by HC ... the hcd glue or the
* device driver provides us with dma addresses
*
* There's also PCI "register" data, which is memory mapped.
* No memory seen by this driver is pagable.
*/
/*-------------------------------------------------------------------------*/
static struct usb_hcd *ohci_hcd_alloc (void)
{
struct ohci_hcd *ohci;
ohci = (struct ohci_hcd *) kmalloc (sizeof *ohci, GFP_KERNEL);
if (ohci != 0) {
memset (ohci, 0, sizeof (struct ohci_hcd));
return &ohci->hcd;
}
return 0;
}
static void ohci_hcd_free (struct usb_hcd *hcd)
{
kfree (hcd_to_ohci (hcd));
}
/*-------------------------------------------------------------------------*/
static int ohci_mem_init (struct ohci_hcd *ohci)
{
ohci->td_cache = pci_pool_create ("ohci_td", ohci->hcd.pdev,
sizeof (struct td),
32 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->td_cache)
return -ENOMEM;
ohci->ed_cache = pci_pool_create ("ohci_ed", ohci->hcd.pdev,
sizeof (struct ed),
16 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->ed_cache) {
pci_pool_destroy (ohci->td_cache);
return -ENOMEM;
}
return 0;
}
static void ohci_mem_cleanup (struct ohci_hcd *ohci)
{
if (ohci->td_cache) {
pci_pool_destroy (ohci->td_cache);
ohci->td_cache = 0;
}
if (ohci->ed_cache) {
pci_pool_destroy (ohci->ed_cache);
ohci->ed_cache = 0;
}
}
/*-------------------------------------------------------------------------*/
/* ohci "done list" processing needs this mapping */
static inline struct td *
dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
{
struct td *td;
td_dma &= TD_MASK;
td = hc->td_hash [TD_HASH_FUNC(td_dma)];
while (td && td->td_dma != td_dma)
td = td->td_hash;
return td;
}
/* TDs ... */
static struct td *
td_alloc (struct ohci_hcd *hc, int mem_flags)
{
dma_addr_t dma;
struct td *td;
td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
if (td) {
/* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma);
td->td_dma = dma;
/* hashed in td_fill */
}
return td;
}
static void
td_free (struct ohci_hcd *hc, struct td *td)
{
struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)];
while (*prev && *prev != td)
prev = &(*prev)->td_hash;
if (*prev)
*prev = td->td_hash;
else if ((td->hwINFO & TD_DONE) != 0)
ohci_dbg (hc, "no hash for td %p\n", td);
pci_pool_free (hc->td_cache, td, td->td_dma);
}
/*-------------------------------------------------------------------------*/
/* EDs ... */
static struct ed *
ed_alloc (struct ohci_hcd *hc, int mem_flags)
{
dma_addr_t dma;
struct ed *ed;
ed = pci_pool_alloc (hc->ed_cache, mem_flags, &dma);
if (ed) {
memset (ed, 0, sizeof (*ed));
INIT_LIST_HEAD (&ed->td_list);
ed->dma = dma;
}
return ed;
}
static void
ed_free (struct ohci_hcd *hc, struct ed *ed)
{
pci_pool_free (hc->ed_cache, ed, ed->dma);
}

View file

@ -1,412 +1,412 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* [ Initialisation is based on Linus' ]
* [ uhci code and gregs ohci fragments ]
* [ (C) Copyright 1999 Linus Torvalds ]
* [ (C) Copyright 1999 Gregory P. Smith]
*
* PCI Bus Glue
*
* This file is licenced under the GPL.
*/
#ifdef CONFIG_PMAC_PBOOK
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/pci-bridge.h>
#include <asm/prom.h>
#ifndef CONFIG_PM
# define CONFIG_PM
#endif
#endif
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
#include "../linux/pci_ids.h"
/*-------------------------------------------------------------------------*/
static int __devinit
ohci_pci_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ret;
DPRINT("ohci_pci_start()\n");
if (hcd->pdev) {
ohci->hcca = pci_alloc_consistent (hcd->pdev,
sizeof *ohci->hcca, &ohci->hcca_dma);
if (!ohci->hcca)
return -ENOMEM;
/* AMD 756, for most chips (early revs), corrupts register
* values on read ... so enable the vendor workaround.
*/
if (hcd->pdev->vendor == PCI_VENDOR_ID_AMD
&& hcd->pdev->device == 0x740c) {
ohci->flags = OHCI_QUIRK_AMD756;
ohci_info (ohci, "AMD756 erratum 4 workaround\n");
}
/* FIXME for some of the early AMD 760 southbridges, OHCI
* won't work at all. blacklist them.
*/
/* Apple's OHCI driver has a lot of bizarre workarounds
* for this chip. Evidently control and bulk lists
* can get confused. (B&W G3 models, and ...)
*/
else if (hcd->pdev->vendor == PCI_VENDOR_ID_OPTI
&& hcd->pdev->device == 0xc861) {
ohci_info (ohci,
"WARNING: OPTi workarounds unavailable\n");
}
/* Check for NSC87560. We have to look at the bridge (fn1) to
* identify the USB (fn2). This quirk might apply to more or
* even all NSC stuff.
*/
else if (hcd->pdev->vendor == PCI_VENDOR_ID_NS) {
struct pci_dev *b, *hc;
hc = hcd->pdev;
b = pci_find_slot (hc->bus->number,
PCI_DEVFN (PCI_SLOT (hc->devfn), 1));
if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
&& b->vendor == PCI_VENDOR_ID_NS) {
ohci->flags |= OHCI_QUIRK_SUPERIO;
ohci_info (ohci, "Using NSC SuperIO setup\n");
}
}
}
memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
if ((ret = ohci_mem_init (ohci)) < 0) {
ohci_stop (hcd);
return ret;
}
ohci->regs = hcd->regs;
DPRINT("Controller memory init done\n");
if (hc_reset (ohci) < 0) {
ohci_stop (hcd);
return -ENODEV;
}
DPRINT("Controller reset done\n");
if (hc_start (ohci) < 0) {
ohci_err (ohci, "can't start\n");
ohci_stop (hcd);
return -EBUSY;
}
DPRINT("Controller start done\n");
#ifdef DEBUG
ohci_dump (ohci, 1);
#endif
return 0;
}
#ifdef CONFIG_PM
static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
u16 cmd;
if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
ohci_dbg (ohci, "can't suspend (state is %s)\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
return -EIO;
}
/* act as if usb suspend can always be used */
ohci_dbg (ohci, "suspend to %d\n", state);
ohci->sleeping = 1;
/* First stop processing */
spin_lock_irqsave (&ohci->lock, flags);
ohci->hc_control &=
~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
writel (ohci->hc_control, &ohci->regs->control);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
(void) readl (&ohci->regs->intrstatus);
spin_unlock_irqrestore (&ohci->lock, flags);
/* Wait a frame or two */
mdelay (1);
if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
mdelay (1);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
disable_irq (hcd->pdev->irq);
/* else, 2.4 assumes shared irqs -- don't disable */
#endif
/* Enable remote wakeup */
writel (readl (&ohci->regs->intrenable) | OHCI_INTR_RD,
&ohci->regs->intrenable);
/* Suspend chip and let things settle down a bit */
ohci->hc_control = OHCI_USB_SUSPEND;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (500); /* No schedule here ! */
switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
case OHCI_USB_RESET:
ohci_dbg (ohci, "suspend->reset ?\n");
break;
case OHCI_USB_RESUME:
ohci_dbg (ohci, "suspend->resume ?\n");
break;
case OHCI_USB_OPER:
ohci_dbg (ohci, "suspend->operational ?\n");
break;
case OHCI_USB_SUSPEND:
ohci_dbg (ohci, "suspended\n");
break;
}
/* In some rare situations, Apple's OHCI have happily trashed
* memory during sleep. We disable its bus master bit during
* suspend
*/
pci_read_config_word (hcd->pdev, PCI_COMMAND, &cmd);
cmd &= ~PCI_COMMAND_MASTER;
pci_write_config_word (hcd->pdev, PCI_COMMAND, cmd);
#ifdef CONFIG_PMAC_PBOOK
{
struct device_node *of_node;
/* Disable USB PAD & cell clock */
of_node = pci_device_to_OF_node (hcd->pdev);
if (of_node)
pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
}
#endif
return 0;
}
static int ohci_pci_resume (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int temp;
int retval = 0;
unsigned long flags;
#ifdef CONFIG_PMAC_PBOOK
{
struct device_node *of_node;
/* Re-enable USB PAD & cell clock */
of_node = pci_device_to_OF_node (hcd->pdev);
if (of_node)
pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
}
#endif
/* did we suspend, or were we powered off? */
ohci->hc_control = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
#ifdef DEBUG
/* the registers may look crazy here */
ohci_dump_status (ohci, 0, 0);
#endif
/* Re-enable bus mastering */
pci_set_master (ohci->hcd.pdev);
switch (temp) {
case OHCI_USB_RESET: // lost power
ohci_info (ohci, "USB restart\n");
retval = hc_restart (ohci);
break;
case OHCI_USB_SUSPEND: // host wakeup
case OHCI_USB_RESUME: // remote wakeup
ohci_info (ohci, "USB continue from %s wakeup\n",
(temp == OHCI_USB_SUSPEND)
? "host" : "remote");
ohci->hc_control = OHCI_USB_RESUME;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (20); /* no schedule here ! */
/* Some controllers (lucent) need a longer delay here */
mdelay (15);
temp = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
ohci->disabled = 1;
retval = -EIO;
break;
}
/* Some chips likes being resumed first */
writel (OHCI_USB_OPER, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (3);
/* Then re-enable operations */
spin_lock_irqsave (&ohci->lock, flags);
ohci->disabled = 0;
ohci->sleeping = 0;
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
if (!ohci->ed_rm_list) {
if (ohci->ed_controltail)
ohci->hc_control |= OHCI_CTRL_CLE;
if (ohci->ed_bulktail)
ohci->hc_control |= OHCI_CTRL_BLE;
}
hcd->state = USB_STATE_READY;
writel (ohci->hc_control, &ohci->regs->control);
/* trigger a start-frame interrupt (why?) */
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
/* Check for a pending done list */
writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
(void) readl (&ohci->regs->intrdisable);
spin_unlock_irqrestore (&ohci->lock, flags);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
enable_irq (hcd->pdev->irq);
#endif
if (ohci->hcca->done_head)
dl_done_list (ohci, dl_reverse_done_list (ohci), NULL);
writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
/* assume there are TDs on the bulk and control lists */
writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
// ohci_dump_status (ohci);
ohci_dbg (ohci, "sleeping = %d, disabled = %d\n",
ohci->sleeping, ohci->disabled);
break;
default:
ohci_warn (ohci, "odd PCI resume\n");
}
return retval;
}
#endif /* CONFIG_PM */
/*-------------------------------------------------------------------------*/
static const struct hc_driver ohci_pci_hc_driver = {
.description = hcd_name,
/*
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_MEMORY | HCD_USB11,
/*
* basic lifecycle operations
*/
.start = ohci_pci_start,
#ifdef CONFIG_PM
.suspend = ohci_pci_suspend,
.resume = ohci_pci_resume,
#endif
.stop = ohci_stop,
/*
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ohci_urb_enqueue,
.urb_dequeue = ohci_urb_dequeue,
.endpoint_disable = ohci_endpoint_disable,
/*
* scheduling support
*/
.get_frame_number = ohci_get_frame,
/*
* root hub support
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
};
/*-------------------------------------------------------------------------*/
const struct pci_device_id __devinitdata pci_ids [] = { {
/* handle any USB OHCI controller */
.class = (PCI_CLASS_SERIAL_USB << 8) | 0x10,
.class_mask = ~0,
.driver_data = (unsigned long) &ohci_pci_hc_driver,
/* no matter who makes it */
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, { /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE (pci, pci_ids);
/* pci driver glue; this is a "new style" PCI driver module */
struct pci_driver ohci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
.resume = usb_hcd_pci_resume,
#endif
};
int ohci_hcd_pci_init (void)
{
printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
if (usb_disabled())
return -ENODEV;
// causes page fault in reactos
//printk (KERN_DEBUG "%s: block sizes: ed %Zd td %Zd\n", hcd_name,
// sizeof (struct ed), sizeof (struct td));
return pci_module_init (&ohci_pci_driver);
}
/*module_init (ohci_hcd_pci_init);*/
/*-------------------------------------------------------------------------*/
void ohci_hcd_pci_cleanup (void)
{
pci_unregister_driver (&ohci_pci_driver);
}
/*module_exit (ohci_hcd_pci_cleanup);*/
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* [ Initialisation is based on Linus' ]
* [ uhci code and gregs ohci fragments ]
* [ (C) Copyright 1999 Linus Torvalds ]
* [ (C) Copyright 1999 Gregory P. Smith]
*
* PCI Bus Glue
*
* This file is licenced under the GPL.
*/
#ifdef CONFIG_PMAC_PBOOK
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/pci-bridge.h>
#include <asm/prom.h>
#ifndef CONFIG_PM
# define CONFIG_PM
#endif
#endif
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
#include "../linux/pci_ids.h"
/*-------------------------------------------------------------------------*/
static int __devinit
ohci_pci_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ret;
DPRINT("ohci_pci_start()\n");
if (hcd->pdev) {
ohci->hcca = pci_alloc_consistent (hcd->pdev,
sizeof *ohci->hcca, &ohci->hcca_dma);
if (!ohci->hcca)
return -ENOMEM;
/* AMD 756, for most chips (early revs), corrupts register
* values on read ... so enable the vendor workaround.
*/
if (hcd->pdev->vendor == PCI_VENDOR_ID_AMD
&& hcd->pdev->device == 0x740c) {
ohci->flags = OHCI_QUIRK_AMD756;
ohci_info (ohci, "AMD756 erratum 4 workaround\n");
}
/* FIXME for some of the early AMD 760 southbridges, OHCI
* won't work at all. blacklist them.
*/
/* Apple's OHCI driver has a lot of bizarre workarounds
* for this chip. Evidently control and bulk lists
* can get confused. (B&W G3 models, and ...)
*/
else if (hcd->pdev->vendor == PCI_VENDOR_ID_OPTI
&& hcd->pdev->device == 0xc861) {
ohci_info (ohci,
"WARNING: OPTi workarounds unavailable\n");
}
/* Check for NSC87560. We have to look at the bridge (fn1) to
* identify the USB (fn2). This quirk might apply to more or
* even all NSC stuff.
*/
else if (hcd->pdev->vendor == PCI_VENDOR_ID_NS) {
struct pci_dev *b, *hc;
hc = hcd->pdev;
b = pci_find_slot (hc->bus->number,
PCI_DEVFN (PCI_SLOT (hc->devfn), 1));
if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
&& b->vendor == PCI_VENDOR_ID_NS) {
ohci->flags |= OHCI_QUIRK_SUPERIO;
ohci_info (ohci, "Using NSC SuperIO setup\n");
}
}
}
memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
if ((ret = ohci_mem_init (ohci)) < 0) {
ohci_stop (hcd);
return ret;
}
ohci->regs = hcd->regs;
DPRINT("Controller memory init done\n");
if (hc_reset (ohci) < 0) {
ohci_stop (hcd);
return -ENODEV;
}
DPRINT("Controller reset done\n");
if (hc_start (ohci) < 0) {
ohci_err (ohci, "can't start\n");
ohci_stop (hcd);
return -EBUSY;
}
DPRINT("Controller start done\n");
#ifdef DEBUG
ohci_dump (ohci, 1);
#endif
return 0;
}
#ifdef CONFIG_PM
static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
u16 cmd;
if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
ohci_dbg (ohci, "can't suspend (state is %s)\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
return -EIO;
}
/* act as if usb suspend can always be used */
ohci_dbg (ohci, "suspend to %d\n", state);
ohci->sleeping = 1;
/* First stop processing */
spin_lock_irqsave (&ohci->lock, flags);
ohci->hc_control &=
~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
writel (ohci->hc_control, &ohci->regs->control);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
(void) readl (&ohci->regs->intrstatus);
spin_unlock_irqrestore (&ohci->lock, flags);
/* Wait a frame or two */
mdelay (1);
if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
mdelay (1);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
disable_irq (hcd->pdev->irq);
/* else, 2.4 assumes shared irqs -- don't disable */
#endif
/* Enable remote wakeup */
writel (readl (&ohci->regs->intrenable) | OHCI_INTR_RD,
&ohci->regs->intrenable);
/* Suspend chip and let things settle down a bit */
ohci->hc_control = OHCI_USB_SUSPEND;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (500); /* No schedule here ! */
switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
case OHCI_USB_RESET:
ohci_dbg (ohci, "suspend->reset ?\n");
break;
case OHCI_USB_RESUME:
ohci_dbg (ohci, "suspend->resume ?\n");
break;
case OHCI_USB_OPER:
ohci_dbg (ohci, "suspend->operational ?\n");
break;
case OHCI_USB_SUSPEND:
ohci_dbg (ohci, "suspended\n");
break;
}
/* In some rare situations, Apple's OHCI have happily trashed
* memory during sleep. We disable its bus master bit during
* suspend
*/
pci_read_config_word (hcd->pdev, PCI_COMMAND, &cmd);
cmd &= ~PCI_COMMAND_MASTER;
pci_write_config_word (hcd->pdev, PCI_COMMAND, cmd);
#ifdef CONFIG_PMAC_PBOOK
{
struct device_node *of_node;
/* Disable USB PAD & cell clock */
of_node = pci_device_to_OF_node (hcd->pdev);
if (of_node)
pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
}
#endif
return 0;
}
static int ohci_pci_resume (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int temp;
int retval = 0;
unsigned long flags;
#ifdef CONFIG_PMAC_PBOOK
{
struct device_node *of_node;
/* Re-enable USB PAD & cell clock */
of_node = pci_device_to_OF_node (hcd->pdev);
if (of_node)
pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
}
#endif
/* did we suspend, or were we powered off? */
ohci->hc_control = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
#ifdef DEBUG
/* the registers may look crazy here */
ohci_dump_status (ohci, 0, 0);
#endif
/* Re-enable bus mastering */
pci_set_master (ohci->hcd.pdev);
switch (temp) {
case OHCI_USB_RESET: // lost power
ohci_info (ohci, "USB restart\n");
retval = hc_restart (ohci);
break;
case OHCI_USB_SUSPEND: // host wakeup
case OHCI_USB_RESUME: // remote wakeup
ohci_info (ohci, "USB continue from %s wakeup\n",
(temp == OHCI_USB_SUSPEND)
? "host" : "remote");
ohci->hc_control = OHCI_USB_RESUME;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (20); /* no schedule here ! */
/* Some controllers (lucent) need a longer delay here */
mdelay (15);
temp = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
ohci->disabled = 1;
retval = -EIO;
break;
}
/* Some chips likes being resumed first */
writel (OHCI_USB_OPER, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (3);
/* Then re-enable operations */
spin_lock_irqsave (&ohci->lock, flags);
ohci->disabled = 0;
ohci->sleeping = 0;
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
if (!ohci->ed_rm_list) {
if (ohci->ed_controltail)
ohci->hc_control |= OHCI_CTRL_CLE;
if (ohci->ed_bulktail)
ohci->hc_control |= OHCI_CTRL_BLE;
}
hcd->state = USB_STATE_READY;
writel (ohci->hc_control, &ohci->regs->control);
/* trigger a start-frame interrupt (why?) */
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
/* Check for a pending done list */
writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
(void) readl (&ohci->regs->intrdisable);
spin_unlock_irqrestore (&ohci->lock, flags);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
enable_irq (hcd->pdev->irq);
#endif
if (ohci->hcca->done_head)
dl_done_list (ohci, dl_reverse_done_list (ohci), NULL);
writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
/* assume there are TDs on the bulk and control lists */
writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
// ohci_dump_status (ohci);
ohci_dbg (ohci, "sleeping = %d, disabled = %d\n",
ohci->sleeping, ohci->disabled);
break;
default:
ohci_warn (ohci, "odd PCI resume\n");
}
return retval;
}
#endif /* CONFIG_PM */
/*-------------------------------------------------------------------------*/
static const struct hc_driver ohci_pci_hc_driver = {
.description = hcd_name,
/*
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_MEMORY | HCD_USB11,
/*
* basic lifecycle operations
*/
.start = ohci_pci_start,
#ifdef CONFIG_PM
.suspend = ohci_pci_suspend,
.resume = ohci_pci_resume,
#endif
.stop = ohci_stop,
/*
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ohci_urb_enqueue,
.urb_dequeue = ohci_urb_dequeue,
.endpoint_disable = ohci_endpoint_disable,
/*
* scheduling support
*/
.get_frame_number = ohci_get_frame,
/*
* root hub support
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
};
/*-------------------------------------------------------------------------*/
const struct pci_device_id __devinitdata pci_ids [] = { {
/* handle any USB OHCI controller */
.class = (PCI_CLASS_SERIAL_USB << 8) | 0x10,
.class_mask = ~0,
.driver_data = (unsigned long) &ohci_pci_hc_driver,
/* no matter who makes it */
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, { /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE (pci, pci_ids);
/* pci driver glue; this is a "new style" PCI driver module */
struct pci_driver ohci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
.resume = usb_hcd_pci_resume,
#endif
};
int ohci_hcd_pci_init (void)
{
printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
if (usb_disabled())
return -ENODEV;
// causes page fault in reactos
//printk (KERN_DEBUG "%s: block sizes: ed %Zd td %Zd\n", hcd_name,
// sizeof (struct ed), sizeof (struct td));
return pci_module_init (&ohci_pci_driver);
}
/*module_init (ohci_hcd_pci_init);*/
/*-------------------------------------------------------------------------*/
void ohci_hcd_pci_cleanup (void)
{
pci_unregister_driver (&ohci_pci_driver);
}
/*module_exit (ohci_hcd_pci_cleanup);*/

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
LIBRARY ohci.sys
EXPORTS
LIBRARY ohci.sys
EXPORTS

View file

@ -1,418 +1,418 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*
* OHCI Endpoint Descriptor (ED) ... holds TD queue
* See OHCI spec, section 4.2
*
* This is a "Queue Head" for those transfers, which is why
* both EHCI and UHCI call similar structures a "QH".
*/
struct ed {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* endpoint config bitmap */
/* info bits defined by hcd */
#define ED_DEQUEUE __constant_cpu_to_le32(1 << 27)
/* info bits defined by the hardware */
#define ED_ISO __constant_cpu_to_le32(1 << 15)
#define ED_SKIP __constant_cpu_to_le32(1 << 14)
#define ED_LOWSPEED __constant_cpu_to_le32(1 << 13)
#define ED_OUT __constant_cpu_to_le32(0x01 << 11)
#define ED_IN __constant_cpu_to_le32(0x02 << 11)
__u32 hwTailP; /* tail of TD list */
__u32 hwHeadP; /* head of TD list (hc r/w) */
#define ED_C __constant_cpu_to_le32(0x02) /* toggle carry */
#define ED_H __constant_cpu_to_le32(0x01) /* halted */
__u32 hwNextED; /* next ED in list */
/* rest are purely for the driver's use */
dma_addr_t dma; /* addr of ED */
struct td *dummy; /* next TD to activate */
/* host's view of schedule */
struct ed *ed_next; /* on schedule or rm_list */
struct ed *ed_prev; /* for non-interrupt EDs */
struct list_head td_list; /* "shadow list" of our TDs */
/* create --> IDLE --> OPER --> ... --> IDLE --> destroy
* usually: OPER --> UNLINK --> (IDLE | OPER) --> ...
* some special cases : OPER --> IDLE ...
*/
u8 state; /* ED_{IDLE,UNLINK,OPER} */
#define ED_IDLE 0x00 /* NOT linked to HC */
#define ED_UNLINK 0x01 /* being unlinked from hc */
#define ED_OPER 0x02 /* IS linked to hc */
u8 type; /* PIPE_{BULK,...} */
/* periodic scheduling params (for intr and iso) */
u8 branch;
u16 interval;
u16 load;
u16 last_iso; /* iso only */
/* HC may see EDs on rm_list until next frame (frame_no == tick) */
u16 tick;
} __attribute__ ((aligned(16)));
#define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */
/*
* OHCI Transfer Descriptor (TD) ... one per transfer segment
* See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt)
* and 4.3.2 (iso)
*/
struct td {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* transfer info bitmask */
/* hwINFO bits for both general and iso tds: */
#define TD_CC 0xf0000000 /* condition code */
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
//#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
#define TD_DI 0x00E00000 /* frames before interrupt */
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
/* these two bits are available for definition/use by HCDs in both
* general and iso tds ... others are available for only one type
*/
#define TD_DONE 0x00020000 /* retired to donelist */
#define TD_ISO 0x00010000 /* copy of ED_ISO */
/* hwINFO bits for general tds: */
#define TD_EC 0x0C000000 /* error count */
#define TD_T 0x03000000 /* data toggle state */
#define TD_T_DATA0 0x02000000 /* DATA0 */
#define TD_T_DATA1 0x03000000 /* DATA1 */
#define TD_T_TOGGLE 0x00000000 /* uses ED_C */
#define TD_DP 0x00180000 /* direction/pid */
#define TD_DP_SETUP 0x00000000 /* SETUP pid */
#define TD_DP_IN 0x00100000 /* IN pid */
#define TD_DP_OUT 0x00080000 /* OUT pid */
/* 0x00180000 rsvd */
#define TD_R 0x00040000 /* round: short packets OK? */
/* (no hwINFO #defines yet for iso tds) */
__u32 hwCBP; /* Current Buffer Pointer (or 0) */
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
/* PSW is only for ISO */
#define MAXPSW 1 /* hardware allows 8 */
__u16 hwPSW [MAXPSW];
/* rest are purely for the driver's use */
__u8 index;
struct ed *ed;
struct td *td_hash; /* dma-->td hashtable */
struct td *next_dl_td;
struct urb *urb;
dma_addr_t td_dma; /* addr of this TD */
dma_addr_t data_dma; /* addr of data it points to */
struct list_head td_list; /* "shadow list", TDs on same ED */
} __attribute__ ((aligned(32))); /* c/b/i need 16; only iso needs 32 */
#define TD_MASK ((u32)~0x1f) /* strip hw status in low addr bits */
/*
* Hardware transfer status codes -- CC from td->hwINFO or td->hwPSW
*/
#define TD_CC_NOERROR 0x00
#define TD_CC_CRC 0x01
#define TD_CC_BITSTUFFING 0x02
#define TD_CC_DATATOGGLEM 0x03
#define TD_CC_STALL 0x04
#define TD_DEVNOTRESP 0x05
#define TD_PIDCHECKFAIL 0x06
#define TD_UNEXPECTEDPID 0x07
#define TD_DATAOVERRUN 0x08
#define TD_DATAUNDERRUN 0x09
/* 0x0A, 0x0B reserved for hardware */
#define TD_BUFFEROVERRUN 0x0C
#define TD_BUFFERUNDERRUN 0x0D
/* 0x0E, 0x0F reserved for HCD */
#define TD_NOTACCESSED 0x0F
/* map OHCI TD status codes (CC) to errno values */
static const int cc_to_error [16] = {
/* No Error */ 0,
/* CRC Error */ -EILSEQ,
/* Bit Stuff */ -EPROTO,
/* Data Togg */ -EILSEQ,
/* Stall */ -EPIPE,
/* DevNotResp */ -ETIMEDOUT,
/* PIDCheck */ -EPROTO,
/* UnExpPID */ -EPROTO,
/* DataOver */ -EOVERFLOW,
/* DataUnder */ -EREMOTEIO,
/* (for hw) */ -EIO,
/* (for hw) */ -EIO,
/* BufferOver */ -ECOMM,
/* BuffUnder */ -ENOSR,
/* (for HCD) */ -EALREADY,
/* (for HCD) */ -EALREADY
};
/*
* The HCCA (Host Controller Communications Area) is a 256 byte
* structure defined section 4.4.1 of the OHCI spec. The HC is
* told the base address of it. It must be 256-byte aligned.
*/
struct ohci_hcca {
#define NUM_INTS 32
__u32 int_table [NUM_INTS]; /* periodic schedule */
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc [116];
u8 what [4]; /* spec only identifies 252 bytes :) */
} __attribute__ ((aligned(256)));
/*
* This is the structure of the OHCI controller's memory mapped I/O region.
* You must use readl() and writel() (in <asm/io.h>) to access these fields!!
* Layout is in section 7 (and appendix B) of the spec.
*/
struct ohci_regs {
/* control and status registers (section 7.1) */
__u32 revision;
__u32 control;
__u32 cmdstatus;
__u32 intrstatus;
__u32 intrenable;
__u32 intrdisable;
/* memory pointers (section 7.2) */
__u32 hcca;
__u32 ed_periodcurrent;
__u32 ed_controlhead;
__u32 ed_controlcurrent;
__u32 ed_bulkhead;
__u32 ed_bulkcurrent;
__u32 donehead;
/* frame counters (section 7.3) */
__u32 fminterval;
__u32 fmremaining;
__u32 fmnumber;
__u32 periodicstart;
__u32 lsthresh;
/* Root hub ports (section 7.4) */
struct ohci_roothub_regs {
__u32 a;
__u32 b;
__u32 status;
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */
__u32 portstatus [MAX_ROOT_PORTS];
} roothub;
/* and optional "legacy support" registers (appendix B) at 0x0100 */
} __attribute__ ((aligned(32)));
/* OHCI CONTROL AND STATUS REGISTER MASKS */
/*
* HcControl (control) register masks
*/
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
/* pre-shifted values for HCFS */
#define OHCI_USB_RESET (0 << 6)
#define OHCI_USB_RESUME (1 << 6)
#define OHCI_USB_OPER (2 << 6)
#define OHCI_USB_SUSPEND (3 << 6)
// HCFS itself
static char *hcfs2string (int state)
{
switch (state) {
case OHCI_USB_RESET: return "reset";
case OHCI_USB_RESUME: return "resume";
case OHCI_USB_OPER: return "operational";
case OHCI_USB_SUSPEND: return "suspend";
}
return "?";
}
/*
* HcCommandStatus (cmdstatus) register masks
*/
#define OHCI_HCR (1 << 0) /* host controller reset */
#define OHCI_CLF (1 << 1) /* control list filled */
#define OHCI_BLF (1 << 2) /* bulk list filled */
#define OHCI_OCR (1 << 3) /* ownership change request */
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
/*
* masks used with interrupt registers:
* HcInterruptStatus (intrstatus)
* HcInterruptEnable (intrenable)
* HcInterruptDisable (intrdisable)
*/
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
#define OHCI_INTR_SF (1 << 2) /* start frame */
#define OHCI_INTR_RD (1 << 3) /* resume detect */
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
#define OHCI_INTR_OC (1 << 30) /* ownership change */
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
/* OHCI ROOT HUB REGISTER MASKS */
/* roothub.portstatus [i] bits */
#define RH_PS_CCS 0x00000001 /* current connect status */
#define RH_PS_PES 0x00000002 /* port enable status*/
#define RH_PS_PSS 0x00000004 /* port suspend status */
#define RH_PS_POCI 0x00000008 /* port over current indicator */
#define RH_PS_PRS 0x00000010 /* port reset status */
#define RH_PS_PPS 0x00000100 /* port power status */
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
#define RH_PS_CSC 0x00010000 /* connect status change */
#define RH_PS_PESC 0x00020000 /* port enable status change */
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
#define RH_PS_PRSC 0x00100000 /* port reset status change */
/* roothub.status bits */
#define RH_HS_LPS 0x00000001 /* local power status */
#define RH_HS_OCI 0x00000002 /* over current indicator */
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
#define RH_HS_LPSC 0x00010000 /* local power status change */
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
/* roothub.b masks */
#define RH_B_DR 0x0000ffff /* device removable flags */
#define RH_B_PPCM 0xffff0000 /* port power control mask */
/* roothub.a masks */
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
#define RH_A_PSM (1 << 8) /* power switching mode */
#define RH_A_NPS (1 << 9) /* no power switching */
#define RH_A_DT (1 << 10) /* device type (mbz) */
#define RH_A_OCPM (1 << 11) /* over current protection mode */
#define RH_A_NOCP (1 << 12) /* no over current protection */
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
/* hcd-private per-urb state */
typedef struct urb_priv {
struct ed *ed;
__u16 length; // # tds in this request
__u16 td_cnt; // tds already serviced
int state;
struct td *td [0]; // all TDs in this request
} urb_priv_t;
#define URB_DEL 1
#define TD_HASH_SIZE 64 /* power'o'two */
// sizeof (struct td) ~= 64 == 2^6 ...
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
/*
* This is the full ohci controller description
*
* Note how the "proper" USB information is just
* a subset of what the full implementation needs. (Linus)
*/
struct ohci_hcd {
spinlock_t lock;
/*
* I/O memory used to communicate with the HC (dma-consistent)
*/
struct ohci_regs *regs;
/*
* main memory used to communicate with the HC (dma-consistent).
* hcd adds to schedule for a live hc any time, but removals finish
* only at the start of the next frame.
*/
struct ohci_hcca *hcca;
dma_addr_t hcca_dma;
struct ed *ed_rm_list; /* to be removed */
struct ed *ed_bulktail; /* last in bulk list */
struct ed *ed_controltail; /* last in ctrl list */
struct ed *periodic [NUM_INTS]; /* shadow int_table */
/*
* memory management for queue data structures
*/
struct pci_pool *td_cache;
struct pci_pool *ed_cache;
struct td *td_hash [TD_HASH_SIZE];
/*
* driver state
*/
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
unsigned long flags; /* for HC bugs */
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */
// there are also chip quirks/bugs in init logic
/*
* framework state
*/
struct usb_hcd hcd;
};
#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
/*-------------------------------------------------------------------------*/
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
#define ohci_dbg(ohci, fmt, args...) \
dev_dbg ((ohci)->hcd.controller , fmt , ## args )
#define ohci_err(ohci, fmt, args...) \
dev_err ((ohci)->hcd.controller , fmt , ## args )
#define ohci_info(ohci, fmt, args...) \
dev_info ((ohci)->hcd.controller , fmt , ## args )
#define ohci_warn(ohci, fmt, args...) \
dev_warn ((ohci)->hcd.controller , fmt , ## args )
#ifdef OHCI_VERBOSE_DEBUG
# define ohci_vdbg ohci_dbg
#else
# define ohci_vdbg(ohci, fmt, args...) do { } while (0)
#endif
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*
* OHCI Endpoint Descriptor (ED) ... holds TD queue
* See OHCI spec, section 4.2
*
* This is a "Queue Head" for those transfers, which is why
* both EHCI and UHCI call similar structures a "QH".
*/
struct ed {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* endpoint config bitmap */
/* info bits defined by hcd */
#define ED_DEQUEUE __constant_cpu_to_le32(1 << 27)
/* info bits defined by the hardware */
#define ED_ISO __constant_cpu_to_le32(1 << 15)
#define ED_SKIP __constant_cpu_to_le32(1 << 14)
#define ED_LOWSPEED __constant_cpu_to_le32(1 << 13)
#define ED_OUT __constant_cpu_to_le32(0x01 << 11)
#define ED_IN __constant_cpu_to_le32(0x02 << 11)
__u32 hwTailP; /* tail of TD list */
__u32 hwHeadP; /* head of TD list (hc r/w) */
#define ED_C __constant_cpu_to_le32(0x02) /* toggle carry */
#define ED_H __constant_cpu_to_le32(0x01) /* halted */
__u32 hwNextED; /* next ED in list */
/* rest are purely for the driver's use */
dma_addr_t dma; /* addr of ED */
struct td *dummy; /* next TD to activate */
/* host's view of schedule */
struct ed *ed_next; /* on schedule or rm_list */
struct ed *ed_prev; /* for non-interrupt EDs */
struct list_head td_list; /* "shadow list" of our TDs */
/* create --> IDLE --> OPER --> ... --> IDLE --> destroy
* usually: OPER --> UNLINK --> (IDLE | OPER) --> ...
* some special cases : OPER --> IDLE ...
*/
u8 state; /* ED_{IDLE,UNLINK,OPER} */
#define ED_IDLE 0x00 /* NOT linked to HC */
#define ED_UNLINK 0x01 /* being unlinked from hc */
#define ED_OPER 0x02 /* IS linked to hc */
u8 type; /* PIPE_{BULK,...} */
/* periodic scheduling params (for intr and iso) */
u8 branch;
u16 interval;
u16 load;
u16 last_iso; /* iso only */
/* HC may see EDs on rm_list until next frame (frame_no == tick) */
u16 tick;
} __attribute__ ((aligned(16)));
#define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */
/*
* OHCI Transfer Descriptor (TD) ... one per transfer segment
* See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt)
* and 4.3.2 (iso)
*/
struct td {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* transfer info bitmask */
/* hwINFO bits for both general and iso tds: */
#define TD_CC 0xf0000000 /* condition code */
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
//#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
#define TD_DI 0x00E00000 /* frames before interrupt */
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
/* these two bits are available for definition/use by HCDs in both
* general and iso tds ... others are available for only one type
*/
#define TD_DONE 0x00020000 /* retired to donelist */
#define TD_ISO 0x00010000 /* copy of ED_ISO */
/* hwINFO bits for general tds: */
#define TD_EC 0x0C000000 /* error count */
#define TD_T 0x03000000 /* data toggle state */
#define TD_T_DATA0 0x02000000 /* DATA0 */
#define TD_T_DATA1 0x03000000 /* DATA1 */
#define TD_T_TOGGLE 0x00000000 /* uses ED_C */
#define TD_DP 0x00180000 /* direction/pid */
#define TD_DP_SETUP 0x00000000 /* SETUP pid */
#define TD_DP_IN 0x00100000 /* IN pid */
#define TD_DP_OUT 0x00080000 /* OUT pid */
/* 0x00180000 rsvd */
#define TD_R 0x00040000 /* round: short packets OK? */
/* (no hwINFO #defines yet for iso tds) */
__u32 hwCBP; /* Current Buffer Pointer (or 0) */
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
/* PSW is only for ISO */
#define MAXPSW 1 /* hardware allows 8 */
__u16 hwPSW [MAXPSW];
/* rest are purely for the driver's use */
__u8 index;
struct ed *ed;
struct td *td_hash; /* dma-->td hashtable */
struct td *next_dl_td;
struct urb *urb;
dma_addr_t td_dma; /* addr of this TD */
dma_addr_t data_dma; /* addr of data it points to */
struct list_head td_list; /* "shadow list", TDs on same ED */
} __attribute__ ((aligned(32))); /* c/b/i need 16; only iso needs 32 */
#define TD_MASK ((u32)~0x1f) /* strip hw status in low addr bits */
/*
* Hardware transfer status codes -- CC from td->hwINFO or td->hwPSW
*/
#define TD_CC_NOERROR 0x00
#define TD_CC_CRC 0x01
#define TD_CC_BITSTUFFING 0x02
#define TD_CC_DATATOGGLEM 0x03
#define TD_CC_STALL 0x04
#define TD_DEVNOTRESP 0x05
#define TD_PIDCHECKFAIL 0x06
#define TD_UNEXPECTEDPID 0x07
#define TD_DATAOVERRUN 0x08
#define TD_DATAUNDERRUN 0x09
/* 0x0A, 0x0B reserved for hardware */
#define TD_BUFFEROVERRUN 0x0C
#define TD_BUFFERUNDERRUN 0x0D
/* 0x0E, 0x0F reserved for HCD */
#define TD_NOTACCESSED 0x0F
/* map OHCI TD status codes (CC) to errno values */
static const int cc_to_error [16] = {
/* No Error */ 0,
/* CRC Error */ -EILSEQ,
/* Bit Stuff */ -EPROTO,
/* Data Togg */ -EILSEQ,
/* Stall */ -EPIPE,
/* DevNotResp */ -ETIMEDOUT,
/* PIDCheck */ -EPROTO,
/* UnExpPID */ -EPROTO,
/* DataOver */ -EOVERFLOW,
/* DataUnder */ -EREMOTEIO,
/* (for hw) */ -EIO,
/* (for hw) */ -EIO,
/* BufferOver */ -ECOMM,
/* BuffUnder */ -ENOSR,
/* (for HCD) */ -EALREADY,
/* (for HCD) */ -EALREADY
};
/*
* The HCCA (Host Controller Communications Area) is a 256 byte
* structure defined section 4.4.1 of the OHCI spec. The HC is
* told the base address of it. It must be 256-byte aligned.
*/
struct ohci_hcca {
#define NUM_INTS 32
__u32 int_table [NUM_INTS]; /* periodic schedule */
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc [116];
u8 what [4]; /* spec only identifies 252 bytes :) */
} __attribute__ ((aligned(256)));
/*
* This is the structure of the OHCI controller's memory mapped I/O region.
* You must use readl() and writel() (in <asm/io.h>) to access these fields!!
* Layout is in section 7 (and appendix B) of the spec.
*/
struct ohci_regs {
/* control and status registers (section 7.1) */
__u32 revision;
__u32 control;
__u32 cmdstatus;
__u32 intrstatus;
__u32 intrenable;
__u32 intrdisable;
/* memory pointers (section 7.2) */
__u32 hcca;
__u32 ed_periodcurrent;
__u32 ed_controlhead;
__u32 ed_controlcurrent;
__u32 ed_bulkhead;
__u32 ed_bulkcurrent;
__u32 donehead;
/* frame counters (section 7.3) */
__u32 fminterval;
__u32 fmremaining;
__u32 fmnumber;
__u32 periodicstart;
__u32 lsthresh;
/* Root hub ports (section 7.4) */
struct ohci_roothub_regs {
__u32 a;
__u32 b;
__u32 status;
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */
__u32 portstatus [MAX_ROOT_PORTS];
} roothub;
/* and optional "legacy support" registers (appendix B) at 0x0100 */
} __attribute__ ((aligned(32)));
/* OHCI CONTROL AND STATUS REGISTER MASKS */
/*
* HcControl (control) register masks
*/
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
/* pre-shifted values for HCFS */
#define OHCI_USB_RESET (0 << 6)
#define OHCI_USB_RESUME (1 << 6)
#define OHCI_USB_OPER (2 << 6)
#define OHCI_USB_SUSPEND (3 << 6)
// HCFS itself
static char *hcfs2string (int state)
{
switch (state) {
case OHCI_USB_RESET: return "reset";
case OHCI_USB_RESUME: return "resume";
case OHCI_USB_OPER: return "operational";
case OHCI_USB_SUSPEND: return "suspend";
}
return "?";
}
/*
* HcCommandStatus (cmdstatus) register masks
*/
#define OHCI_HCR (1 << 0) /* host controller reset */
#define OHCI_CLF (1 << 1) /* control list filled */
#define OHCI_BLF (1 << 2) /* bulk list filled */
#define OHCI_OCR (1 << 3) /* ownership change request */
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
/*
* masks used with interrupt registers:
* HcInterruptStatus (intrstatus)
* HcInterruptEnable (intrenable)
* HcInterruptDisable (intrdisable)
*/
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
#define OHCI_INTR_SF (1 << 2) /* start frame */
#define OHCI_INTR_RD (1 << 3) /* resume detect */
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
#define OHCI_INTR_OC (1 << 30) /* ownership change */
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
/* OHCI ROOT HUB REGISTER MASKS */
/* roothub.portstatus [i] bits */
#define RH_PS_CCS 0x00000001 /* current connect status */
#define RH_PS_PES 0x00000002 /* port enable status*/
#define RH_PS_PSS 0x00000004 /* port suspend status */
#define RH_PS_POCI 0x00000008 /* port over current indicator */
#define RH_PS_PRS 0x00000010 /* port reset status */
#define RH_PS_PPS 0x00000100 /* port power status */
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
#define RH_PS_CSC 0x00010000 /* connect status change */
#define RH_PS_PESC 0x00020000 /* port enable status change */
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
#define RH_PS_PRSC 0x00100000 /* port reset status change */
/* roothub.status bits */
#define RH_HS_LPS 0x00000001 /* local power status */
#define RH_HS_OCI 0x00000002 /* over current indicator */
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
#define RH_HS_LPSC 0x00010000 /* local power status change */
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
/* roothub.b masks */
#define RH_B_DR 0x0000ffff /* device removable flags */
#define RH_B_PPCM 0xffff0000 /* port power control mask */
/* roothub.a masks */
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
#define RH_A_PSM (1 << 8) /* power switching mode */
#define RH_A_NPS (1 << 9) /* no power switching */
#define RH_A_DT (1 << 10) /* device type (mbz) */
#define RH_A_OCPM (1 << 11) /* over current protection mode */
#define RH_A_NOCP (1 << 12) /* no over current protection */
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
/* hcd-private per-urb state */
typedef struct urb_priv {
struct ed *ed;
__u16 length; // # tds in this request
__u16 td_cnt; // tds already serviced
int state;
struct td *td [0]; // all TDs in this request
} urb_priv_t;
#define URB_DEL 1
#define TD_HASH_SIZE 64 /* power'o'two */
// sizeof (struct td) ~= 64 == 2^6 ...
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
/*
* This is the full ohci controller description
*
* Note how the "proper" USB information is just
* a subset of what the full implementation needs. (Linus)
*/
struct ohci_hcd {
spinlock_t lock;
/*
* I/O memory used to communicate with the HC (dma-consistent)
*/
struct ohci_regs *regs;
/*
* main memory used to communicate with the HC (dma-consistent).
* hcd adds to schedule for a live hc any time, but removals finish
* only at the start of the next frame.
*/
struct ohci_hcca *hcca;
dma_addr_t hcca_dma;
struct ed *ed_rm_list; /* to be removed */
struct ed *ed_bulktail; /* last in bulk list */
struct ed *ed_controltail; /* last in ctrl list */
struct ed *periodic [NUM_INTS]; /* shadow int_table */
/*
* memory management for queue data structures
*/
struct pci_pool *td_cache;
struct pci_pool *ed_cache;
struct td *td_hash [TD_HASH_SIZE];
/*
* driver state
*/
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
unsigned long flags; /* for HC bugs */
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */
// there are also chip quirks/bugs in init logic
/*
* framework state
*/
struct usb_hcd hcd;
};
#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
/*-------------------------------------------------------------------------*/
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
#define ohci_dbg(ohci, fmt, args...) \
dev_dbg ((ohci)->hcd.controller , fmt , ## args )
#define ohci_err(ohci, fmt, args...) \
dev_err ((ohci)->hcd.controller , fmt , ## args )
#define ohci_info(ohci, fmt, args...) \
dev_info ((ohci)->hcd.controller , fmt , ## args )
#define ohci_warn(ohci, fmt, args...) \
dev_warn ((ohci)->hcd.controller , fmt , ## args )
#ifdef OHCI_VERBOSE_DEBUG
# define ohci_vdbg ohci_dbg
#else
# define ohci_vdbg(ohci, fmt, args...) do { } while (0)
#endif

View file

@ -1,5 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB OHCI Device Driver\0"
#define REACTOS_STR_INTERNAL_NAME "ohci\0"
#define REACTOS_STR_ORIGINAL_FILENAME "ohci.sys\0"
#include <reactos/version.rc>
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB OHCI Device Driver\0"
#define REACTOS_STR_INTERNAL_NAME "ohci\0"
#define REACTOS_STR_ORIGINAL_FILENAME "ohci.sys\0"
#include <reactos/version.rc>

View file

@ -1,5 +1,5 @@
/*
* Configs for OHCI
*/
#define CONFIG_PCI
/*
* Configs for OHCI
*/
#define CONFIG_PCI

View file

@ -1,309 +1,309 @@
/*
ReactOS specific functions for OHCI module
by Aleksey Bragin (aleksey@reactos.com)
Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
*/
#include <ddk/ntddk.h>
#include <debug.h>
#include "../linux/linux_wrapper.h"
#include "ohci_main.h"
// declare basic init funcs
void init_wrapper(struct pci_dev *probe_dev);
int ohci_hcd_pci_init (void);
void ohci_hcd_pci_cleanup (void);
int STDCALL usb_init(void);
void STDCALL usb_exit(void);
extern struct pci_driver ohci_pci_driver;
extern const struct pci_device_id pci_ids[];
// This should be removed, but for testing purposes it's here
struct pci_dev *dev;
//struct pci_device_id *dev_id;
#define USB_OHCI_TAG TAG('u','s','b','o')
NTSTATUS STDCALL AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
PDEVICE_OBJECT fdo;
NTSTATUS Status;
WCHAR DeviceBuffer[20];
UNICODE_STRING DeviceName;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
ULONG Size, DeviceNumber;
DPRINT1("ohci: AddDevice called\n");
// Allocate driver extension now
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
if (DriverExtension == NULL)
{
Status = IoAllocateDriverObjectExtension(
DriverObject,
DriverObject,
sizeof(OHCI_DRIVER_EXTENSION),
(PVOID *)&DriverExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("Allocating DriverObjectExtension failed.\n");
return Status;
}
}
// Create a unicode device name
DeviceNumber = 0; //TODO: Allocate new device number every time
swprintf(DeviceBuffer, L"\\Device\\USBFDO-%lu", DeviceNumber);
RtlInitUnicodeString(&DeviceName, DeviceBuffer);
Status = IoCreateDevice(DriverObject,
sizeof(OHCI_DEVICE_EXTENSION)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
&DeviceName,
FILE_DEVICE_CONTROLLER,
0,
FALSE,
&fdo);
if (!NT_SUCCESS(Status))
{
DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
return Status;
}
// zerofill device extension
DeviceExtension = (POHCI_DEVICE_EXTENSION)pdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
// Initialize device extension
DeviceExtension->DeviceNumber = DeviceNumber;
DeviceExtension->PhysicalDeviceObject = pdo;
DeviceExtension->FunctionalDeviceObject = fdo;
DeviceExtension->DriverExtension = DriverExtension;
/* Get bus number from the upper level bus driver. */
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(
pdo,
DevicePropertyBusNumber,
Size,
&DeviceExtension->SystemIoBusNumber,
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
return Status;
}
DPRINT("Done AddDevice\n");
return STATUS_SUCCESS;
}
VOID STDCALL DriverUnload(PDRIVER_OBJECT DriverObject)
{
DPRINT1("DriverUnload()\n");
// Exit usb device
usb_exit();
// Remove device (ohci_pci_driver.remove)
ohci_pci_driver.remove(dev);
ExFreePool(dev->slot_name);
ExFreePool(dev);
// Perform some cleanup
ohci_hcd_pci_cleanup();
}
NTSTATUS InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Fill generic linux structs
dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_OHCI_TAG);
init_wrapper(dev);
dev->irq = DeviceExtension->InterruptLevel;
dev->dev_ext = (PVOID)DeviceExtension;
dev->slot_name = ExAllocatePoolWithTag(NonPagedPool, 128, USB_OHCI_TAG); // 128 max len for slot name
strcpy(dev->dev.name, "OpenHCI PCI-USB Controller");
strcpy(dev->slot_name, "OHCD PCI Slot");
// Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL
Status = ohci_hcd_pci_init();
//FIXME: Check status returned value
// Init core usb
usb_init();
// Probe device with real id now
ohci_pci_driver.probe(dev, pci_ids);
DPRINT("InitLinuxWrapper() done\n");
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PDRIVER_OBJECT DriverObject;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
/*
* Get the initialization data we saved in VideoPortInitialize.
*/
DriverObject = DeviceObject->DriverObject;
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/*
* Store some resources in the DeviceExtension.
*/
AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
if (AllocatedResources != NULL)
{
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
ULONG ResourceCount;
ULONG ResourceListSize;
/* Save the resource list */
ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
ResourceListSize =
FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
PartialDescriptors[ResourceCount]);
DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
if (DeviceExtension->AllocatedResources == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(DeviceExtension->AllocatedResources,
AllocatedResources,
ResourceListSize);
/* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
for (FullList = AllocatedResources->List;
FullList < AllocatedResources->List + AllocatedResources->Count;
FullList++)
{
/* FIXME: Is this ASSERT ok for resources from the PNP manager? */
/*ASSERT(FullList->InterfaceType == PCIBus &&
FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
1 == FullList->PartialResourceList.Version &&
1 == FullList->PartialResourceList.Revision);*/
for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
Descriptor++)
{
if (Descriptor->Type == CmResourceTypeInterrupt)
{
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
}
else if (Descriptor->Type == CmResourceTypeMemory)
{
DeviceExtension->BaseAddress = Descriptor->u.Memory.Start;
DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
}
}
}
}
DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
DeviceExtension->InterruptLevel,
DeviceExtension->InterruptVector);
/*
* Init wrapper with this object
*/
return InitLinuxWrapper(DeviceObject);
}
// Dispatch PNP
NTSTATUS STDCALL DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = OHCD_PnPStartDevice(DeviceObject, Irp);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_STOP_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoDeleteDevice(DeviceObject); // just delete device for now
break;
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
default:
return STATUS_NOT_IMPLEMENTED;
break;
}
return Status;
}
NTSTATUS STDCALL DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DbgPrint("IRP_MJ_POWER dispatch\n");
return STATUS_SUCCESS;
}
/*
* Standard DriverEntry method.
*/
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}
/*
ReactOS specific functions for OHCI module
by Aleksey Bragin (aleksey@reactos.com)
Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
*/
#include <ddk/ntddk.h>
#include <debug.h>
#include "../linux/linux_wrapper.h"
#include "ohci_main.h"
// declare basic init funcs
void init_wrapper(struct pci_dev *probe_dev);
int ohci_hcd_pci_init (void);
void ohci_hcd_pci_cleanup (void);
int STDCALL usb_init(void);
void STDCALL usb_exit(void);
extern struct pci_driver ohci_pci_driver;
extern const struct pci_device_id pci_ids[];
// This should be removed, but for testing purposes it's here
struct pci_dev *dev;
//struct pci_device_id *dev_id;
#define USB_OHCI_TAG TAG('u','s','b','o')
NTSTATUS STDCALL AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
PDEVICE_OBJECT fdo;
NTSTATUS Status;
WCHAR DeviceBuffer[20];
UNICODE_STRING DeviceName;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
ULONG Size, DeviceNumber;
DPRINT1("ohci: AddDevice called\n");
// Allocate driver extension now
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
if (DriverExtension == NULL)
{
Status = IoAllocateDriverObjectExtension(
DriverObject,
DriverObject,
sizeof(OHCI_DRIVER_EXTENSION),
(PVOID *)&DriverExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("Allocating DriverObjectExtension failed.\n");
return Status;
}
}
// Create a unicode device name
DeviceNumber = 0; //TODO: Allocate new device number every time
swprintf(DeviceBuffer, L"\\Device\\USBFDO-%lu", DeviceNumber);
RtlInitUnicodeString(&DeviceName, DeviceBuffer);
Status = IoCreateDevice(DriverObject,
sizeof(OHCI_DEVICE_EXTENSION)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
&DeviceName,
FILE_DEVICE_CONTROLLER,
0,
FALSE,
&fdo);
if (!NT_SUCCESS(Status))
{
DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
return Status;
}
// zerofill device extension
DeviceExtension = (POHCI_DEVICE_EXTENSION)pdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
// Initialize device extension
DeviceExtension->DeviceNumber = DeviceNumber;
DeviceExtension->PhysicalDeviceObject = pdo;
DeviceExtension->FunctionalDeviceObject = fdo;
DeviceExtension->DriverExtension = DriverExtension;
/* Get bus number from the upper level bus driver. */
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(
pdo,
DevicePropertyBusNumber,
Size,
&DeviceExtension->SystemIoBusNumber,
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
return Status;
}
DPRINT("Done AddDevice\n");
return STATUS_SUCCESS;
}
VOID STDCALL DriverUnload(PDRIVER_OBJECT DriverObject)
{
DPRINT1("DriverUnload()\n");
// Exit usb device
usb_exit();
// Remove device (ohci_pci_driver.remove)
ohci_pci_driver.remove(dev);
ExFreePool(dev->slot_name);
ExFreePool(dev);
// Perform some cleanup
ohci_hcd_pci_cleanup();
}
NTSTATUS InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Fill generic linux structs
dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_OHCI_TAG);
init_wrapper(dev);
dev->irq = DeviceExtension->InterruptLevel;
dev->dev_ext = (PVOID)DeviceExtension;
dev->slot_name = ExAllocatePoolWithTag(NonPagedPool, 128, USB_OHCI_TAG); // 128 max len for slot name
strcpy(dev->dev.name, "OpenHCI PCI-USB Controller");
strcpy(dev->slot_name, "OHCD PCI Slot");
// Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL
Status = ohci_hcd_pci_init();
//FIXME: Check status returned value
// Init core usb
usb_init();
// Probe device with real id now
ohci_pci_driver.probe(dev, pci_ids);
DPRINT("InitLinuxWrapper() done\n");
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PDRIVER_OBJECT DriverObject;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
/*
* Get the initialization data we saved in VideoPortInitialize.
*/
DriverObject = DeviceObject->DriverObject;
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/*
* Store some resources in the DeviceExtension.
*/
AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
if (AllocatedResources != NULL)
{
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
ULONG ResourceCount;
ULONG ResourceListSize;
/* Save the resource list */
ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
ResourceListSize =
FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
PartialDescriptors[ResourceCount]);
DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
if (DeviceExtension->AllocatedResources == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(DeviceExtension->AllocatedResources,
AllocatedResources,
ResourceListSize);
/* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
for (FullList = AllocatedResources->List;
FullList < AllocatedResources->List + AllocatedResources->Count;
FullList++)
{
/* FIXME: Is this ASSERT ok for resources from the PNP manager? */
/*ASSERT(FullList->InterfaceType == PCIBus &&
FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
1 == FullList->PartialResourceList.Version &&
1 == FullList->PartialResourceList.Revision);*/
for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
Descriptor++)
{
if (Descriptor->Type == CmResourceTypeInterrupt)
{
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
}
else if (Descriptor->Type == CmResourceTypeMemory)
{
DeviceExtension->BaseAddress = Descriptor->u.Memory.Start;
DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
}
}
}
}
DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
DeviceExtension->InterruptLevel,
DeviceExtension->InterruptVector);
/*
* Init wrapper with this object
*/
return InitLinuxWrapper(DeviceObject);
}
// Dispatch PNP
NTSTATUS STDCALL DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = OHCD_PnPStartDevice(DeviceObject, Irp);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_STOP_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoDeleteDevice(DeviceObject); // just delete device for now
break;
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
default:
return STATUS_NOT_IMPLEMENTED;
break;
}
return Status;
}
NTSTATUS STDCALL DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DbgPrint("IRP_MJ_POWER dispatch\n");
return STATUS_SUCCESS;
}
/*
* Standard DriverEntry method.
*/
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}

View file

@ -1,46 +1,47 @@
/*
* OHCI WDM/PNP driver
*
* Copyright (C) 2005 ReactOS Team
*
* Author: Aleksey Bragin (aleksey@reactos.com)
*
*/
#ifndef OHCI_MAIN_H
#define OHCI_MAIN_H
typedef struct _OHCI_DRIVER_EXTENSION
{
//OHCI_HW_INITIALIZATION_DATA InitializationData;
PVOID HwContext;
//UNICODE_STRING RegistryPath;
} OHCI_DRIVER_EXTENSION, *POHCI_DRIVER_EXTENSION;
typedef struct _OHCI_DEVICE_EXTENSTION
{
ULONG DeviceNumber;
PDEVICE_OBJECT PhysicalDeviceObject;
PDEVICE_OBJECT FunctionalDeviceObject;
PDEVICE_OBJECT NextDeviceObject;
//UNICODE_STRING RegistryPath;
PKINTERRUPT InterruptObject;
KSPIN_LOCK InterruptSpinLock;
PCM_RESOURCE_LIST AllocatedResources;
ULONG InterruptVector;
ULONG InterruptLevel;
PHYSICAL_ADDRESS BaseAddress;
ULONG BaseAddrLength;
ULONG AdapterInterfaceType;
ULONG SystemIoBusNumber;
ULONG SystemIoSlotNumber;
LIST_ENTRY AddressMappingListHead;
//KDPC DpcObject;
OHCI_DRIVER_EXTENSION *DriverExtension;
ULONG DeviceOpened;
//KMUTEX DeviceLock;
//CHAR MiniPortDeviceExtension[1];
} OHCI_DEVICE_EXTENSION, *POHCI_DEVICE_EXTENSION;
#endif
/*
* OHCI WDM/PNP driver
*
* Copyright (C) 2005 ReactOS Team
*
* Author: Aleksey Bragin (aleksey@reactos.com)
*
*/
#ifndef OHCI_MAIN_H
#define OHCI_MAIN_H
typedef struct _OHCI_DRIVER_EXTENSION
{
//OHCI_HW_INITIALIZATION_DATA InitializationData;
PVOID HwContext;
//UNICODE_STRING RegistryPath;
} OHCI_DRIVER_EXTENSION, *POHCI_DRIVER_EXTENSION;
typedef struct _OHCI_DEVICE_EXTENSTION
{
ULONG DeviceNumber;
PDEVICE_OBJECT PhysicalDeviceObject;
PDEVICE_OBJECT FunctionalDeviceObject;
PDEVICE_OBJECT NextDeviceObject;
//UNICODE_STRING RegistryPath;
PKINTERRUPT InterruptObject;
KSPIN_LOCK InterruptSpinLock;
PCM_RESOURCE_LIST AllocatedResources;
ULONG InterruptVector;
ULONG InterruptLevel;
PHYSICAL_ADDRESS BaseAddress;
ULONG BaseAddrLength;
ULONG Flags;
ULONG AdapterInterfaceType;
ULONG SystemIoBusNumber;
ULONG SystemIoSlotNumber;
LIST_ENTRY AddressMappingListHead;
//KDPC DpcObject;
OHCI_DRIVER_EXTENSION *DriverExtension;
ULONG DeviceOpened;
//KMUTEX DeviceLock;
//CHAR MiniPortDeviceExtension[1];
} OHCI_DEVICE_EXTENSION, *POHCI_DEVICE_EXTENSION;
#endif

View file

@ -1,384 +1,384 @@
#ifndef _I386_BITOPS_H
#define _I386_BITOPS_H
/*
* Copyright 1992, Linus Torvalds.
*/
//#include <linux/config.h>
/*
* These have to be done with inline assembly: that way the bit-setting
* is guaranteed to be atomic. All bit operations return 0 if the bit
* was cleared before the operation and != 0 if it was not.
*
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
#ifdef CONFIG_SMP
#define LOCK_PREFIX "lock ; "
#else
#define LOCK_PREFIX ""
#endif
#define ADDR (*(volatile long *) addr)
/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered. See __set_bit()
* if you do not require the atomic guarantees.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static __inline__ void set_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* __set_bit - Set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike set_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void __set_bit(int nr, volatile void * addr)
{
__asm__(
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered. However, it does
* not contain a memory barrier, so if it is used for locking purposes,
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
static __inline__ void clear_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
/**
* __change_bit - Toggle a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike change_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void __change_bit(int nr, volatile void * addr)
{
__asm__ __volatile__(
"btcl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static __inline__ void change_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
/**
* __test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__(
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
/**
* __test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__(
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
/* WARNING: non atomic and it can be reordered! */
static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
/**
* test_and_change_bit - Change a bit and return its new value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
#if 0 /* Fool kernel-doc since it doesn't do macros yet */
/**
* test_bit - Determine whether a bit is set
* @nr: bit number to test
* @addr: Address to start counting from
*/
static int test_bit(int nr, const volatile void * addr);
#endif
static __inline__ int constant_test_bit(int nr, const volatile void * addr)
{
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
}
static __inline__ int variable_test_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(
"btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
:"m" (ADDR),"Ir" (nr));
return oldbit;
}
#define test_bit(nr,addr) \
(__builtin_constant_p(nr) ? \
constant_test_bit((nr),(addr)) : \
variable_test_bit((nr),(addr)))
/**
* find_first_zero_bit - find the first zero bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit-number of the first zero bit, not the number of the byte
* containing a bit.
*/
static __inline__ int find_first_zero_bit(void * addr, unsigned size)
{
int d0, d1, d2;
int res;
if (!size)
return 0;
/* This looks at memory. Mark it volatile to tell gcc not to move it around */
__asm__ __volatile__(
"movl $-1,%%eax\n\t"
"xorl %%edx,%%edx\n\t"
"repe; scasl\n\t"
"je 1f\n\t"
"xorl -4(%%edi),%%eax\n\t"
"subl $4,%%edi\n\t"
"bsfl %%eax,%%edx\n"
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
/**
* find_next_zero_bit - find the first zero bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
int set = 0, bit = offset & 31, res;
if (bit) {
/*
* Look for zero in first byte
*/
__asm__("bsfl %1,%0\n\t"
"jne 1f\n\t"
"movl $32, %0\n"
"1:"
: "=r" (set)
: "r" (~(*p >> bit)));
if (set < (32 - bit))
return set + offset;
set = 32 - bit;
p++;
}
/*
* No zero yet, search remaining full bytes for a zero
*/
res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
return (offset + set + res);
}
/**
* ffz - find first zero in word.
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
static __inline__ unsigned long ffz(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
:"r" (~word));
return word;
}
#ifdef __KERNEL__
/**
* ffs - find first bit set
* @x: the word to search
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static __inline__ int ffs(int x)
{
int r;
__asm__("bsfl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r+1;
}
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
* The Hamming Weight of a number is the total number of bits set in it.
*/
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#ifdef __KERNEL__
#define ext2_set_bit __test_and_set_bit
#define ext2_clear_bit __test_and_clear_bit
#define ext2_test_bit test_bit
#define ext2_find_first_zero_bit find_first_zero_bit
#define ext2_find_next_zero_bit find_next_zero_bit
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr)
#define minix_set_bit(nr,addr) __set_bit(nr,addr)
#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
#endif /* __KERNEL__ */
#endif /* _I386_BITOPS_H */
#ifndef _I386_BITOPS_H
#define _I386_BITOPS_H
/*
* Copyright 1992, Linus Torvalds.
*/
//#include <linux/config.h>
/*
* These have to be done with inline assembly: that way the bit-setting
* is guaranteed to be atomic. All bit operations return 0 if the bit
* was cleared before the operation and != 0 if it was not.
*
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
#ifdef CONFIG_SMP
#define LOCK_PREFIX "lock ; "
#else
#define LOCK_PREFIX ""
#endif
#define ADDR (*(volatile long *) addr)
/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered. See __set_bit()
* if you do not require the atomic guarantees.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static __inline__ void set_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* __set_bit - Set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike set_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void __set_bit(int nr, volatile void * addr)
{
__asm__(
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered. However, it does
* not contain a memory barrier, so if it is used for locking purposes,
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
static __inline__ void clear_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
/**
* __change_bit - Toggle a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike change_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void __change_bit(int nr, volatile void * addr)
{
__asm__ __volatile__(
"btcl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static __inline__ void change_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
/**
* __test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__(
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
/**
* __test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__(
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
/* WARNING: non atomic and it can be reordered! */
static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
/**
* test_and_change_bit - Change a bit and return its new value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr) : "memory");
return oldbit;
}
#if 0 /* Fool kernel-doc since it doesn't do macros yet */
/**
* test_bit - Determine whether a bit is set
* @nr: bit number to test
* @addr: Address to start counting from
*/
static int test_bit(int nr, const volatile void * addr);
#endif
static __inline__ int constant_test_bit(int nr, const volatile void * addr)
{
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
}
static __inline__ int variable_test_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(
"btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
:"m" (ADDR),"Ir" (nr));
return oldbit;
}
#define test_bit(nr,addr) \
(__builtin_constant_p(nr) ? \
constant_test_bit((nr),(addr)) : \
variable_test_bit((nr),(addr)))
/**
* find_first_zero_bit - find the first zero bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit-number of the first zero bit, not the number of the byte
* containing a bit.
*/
static __inline__ int find_first_zero_bit(void * addr, unsigned size)
{
int d0, d1, d2;
int res;
if (!size)
return 0;
/* This looks at memory. Mark it volatile to tell gcc not to move it around */
__asm__ __volatile__(
"movl $-1,%%eax\n\t"
"xorl %%edx,%%edx\n\t"
"repe; scasl\n\t"
"je 1f\n\t"
"xorl -4(%%edi),%%eax\n\t"
"subl $4,%%edi\n\t"
"bsfl %%eax,%%edx\n"
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
/**
* find_next_zero_bit - find the first zero bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
int set = 0, bit = offset & 31, res;
if (bit) {
/*
* Look for zero in first byte
*/
__asm__("bsfl %1,%0\n\t"
"jne 1f\n\t"
"movl $32, %0\n"
"1:"
: "=r" (set)
: "r" (~(*p >> bit)));
if (set < (32 - bit))
return set + offset;
set = 32 - bit;
p++;
}
/*
* No zero yet, search remaining full bytes for a zero
*/
res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
return (offset + set + res);
}
/**
* ffz - find first zero in word.
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
static __inline__ unsigned long ffz(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
:"r" (~word));
return word;
}
#ifdef __KERNEL__
/**
* ffs - find first bit set
* @x: the word to search
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static __inline__ int ffs(int x)
{
int r;
__asm__("bsfl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r+1;
}
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
* The Hamming Weight of a number is the total number of bits set in it.
*/
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#ifdef __KERNEL__
#define ext2_set_bit __test_and_set_bit
#define ext2_clear_bit __test_and_clear_bit
#define ext2_test_bit test_bit
#define ext2_find_first_zero_bit find_first_zero_bit
#define ext2_find_next_zero_bit find_next_zero_bit
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr)
#define minix_set_bit(nr,addr) __set_bit(nr,addr)
#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
#endif /* __KERNEL__ */
#endif /* _I386_BITOPS_H */

View file

@ -1,72 +1,72 @@
#ifndef _LINUX_BITOPS_H
#define _LINUX_BITOPS_H
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static inline int generic_ffs(int x)
{
int r = 1;
if (!x)
return 0;
if (!(x & 0xffff)) {
x >>= 16;
r += 16;
}
if (!(x & 0xff)) {
x >>= 8;
r += 8;
}
if (!(x & 0xf)) {
x >>= 4;
r += 4;
}
if (!(x & 3)) {
x >>= 2;
r += 2;
}
if (!(x & 1)) {
x >>= 1;
r += 1;
}
return r;
}
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
static inline unsigned int generic_hweight32(unsigned int w)
{
unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
}
static inline unsigned int generic_hweight16(unsigned int w)
{
unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
res = (res & 0x3333) + ((res >> 2) & 0x3333);
res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
return (res & 0x00FF) + ((res >> 8) & 0x00FF);
}
static inline unsigned int generic_hweight8(unsigned int w)
{
unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
res = (res & 0x33) + ((res >> 2) & 0x33);
return (res & 0x0F) + ((res >> 4) & 0x0F);
}
#include "asm/bitops.h"
#endif
#ifndef _LINUX_BITOPS_H
#define _LINUX_BITOPS_H
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static inline int generic_ffs(int x)
{
int r = 1;
if (!x)
return 0;
if (!(x & 0xffff)) {
x >>= 16;
r += 16;
}
if (!(x & 0xff)) {
x >>= 8;
r += 8;
}
if (!(x & 0xf)) {
x >>= 4;
r += 4;
}
if (!(x & 3)) {
x >>= 2;
r += 2;
}
if (!(x & 1)) {
x >>= 1;
r += 1;
}
return r;
}
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
static inline unsigned int generic_hweight32(unsigned int w)
{
unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
}
static inline unsigned int generic_hweight16(unsigned int w)
{
unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
res = (res & 0x3333) + ((res >> 2) & 0x3333);
res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
return (res & 0x00FF) + ((res >> 8) & 0x00FF);
}
static inline unsigned int generic_hweight8(unsigned int w)
{
unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
res = (res & 0x33) + ((res >> 2) & 0x33);
return (res & 0x0F) + ((res >> 4) & 0x0F);
}
#include "asm/bitops.h"
#endif

View file

@ -1,337 +1,337 @@
#ifndef _Boot_H_
#define _Boot_H_
#include "config.h"
/***************************************************************************
Includes used by XBox boot code
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/////////////////////////////////
// configuration
#include "consts.h"
#include "stdint.h"
#include "cromwell_types.h"
unsigned int cromwell_config;
unsigned int cromwell_retryload;
unsigned int cromwell_loadbank;
unsigned int cromwell_Biostype;
unsigned int xbox_ram;
#define XROMWELL 0
#define CROMWELL 1
#define ICON_WIDTH 64
#define ICON_HEIGHT 64
/*
static double min (double a, double b)
{
if (a < b) return a; else return b;
}
static inline double max (double a, double b)
{
if (a > b) return a; else return b;
}
*/
//#include "iso_fs.h"
//#include "BootVideo.h"
//#define ASSERT(exp) { if(!(exp)) { bprintf("Assert failed file " __FILE__ " line %d\n", __LINE__); } }
#if 0
extern volatile CURRENT_VIDEO_MODE_DETAILS vmode;
unsigned int video_encoder;
volatile u32 VIDEO_CURSOR_POSX;
volatile u32 VIDEO_CURSOR_POSY;
volatile u32 VIDEO_ATTR;
volatile u32 VIDEO_LUMASCALING;
volatile u32 VIDEO_RSCALING;
volatile u32 VIDEO_BSCALING;
volatile u32 BIOS_TICK_COUNT;
volatile u32 VIDEO_VSYNC_POSITION;
volatile u32 VIDEO_VSYNC_DIR;
volatile u32 DVD_TRAY_STATE;
u8 VIDEO_AV_MODE ;
#define DVD_CLOSED 0
#define DVD_CLOSING 1
#define DVD_OPEN 2
#define DVD_OPENING 3
/////////////////////////////////
// Superfunky i386 internal structures
typedef struct gdt_t {
unsigned short m_wSize __attribute__ ((packed));
unsigned long m_dwBase32 __attribute__ ((packed));
unsigned short m_wDummy __attribute__ ((packed));
} ts_descriptor_pointer;
typedef struct { // inside an 8-byte protected mode interrupt vector
u16 m_wHandlerHighAddressLow16;
u16 m_wSelector;
u16 m_wType;
u16 m_wHandlerLinearAddressHigh16;
} ts_pm_interrupt;
typedef enum {
EDT_UNKNOWN= 0,
EDT_XBOXFS
} enumDriveType;
typedef struct tsHarddiskInfo { // this is the retained knowledge about an IDE device after init
unsigned short m_fwPortBase;
unsigned short m_wCountHeads;
unsigned short m_wCountCylinders;
unsigned short m_wCountSectorsPerTrack;
unsigned long m_dwCountSectorsTotal; /* total */
unsigned char m_bLbaMode; /* am i lba (0x40) or chs (0x00) */
unsigned char m_szIdentityModelNumber[40];
unsigned char term_space_1[2];
unsigned char m_szSerial[20];
unsigned char term_space_2[2];
char m_szFirmware[8];
unsigned char term_space_3[2];
unsigned char m_fDriveExists;
unsigned char m_fAtapi; // true if a CDROM, etc
enumDriveType m_enumDriveType;
unsigned char m_bCableConductors; // valid for device 0 if present
unsigned short m_wAtaRevisionSupported;
unsigned char s_length;
unsigned char m_length;
unsigned char m_fHasMbr;
unsigned short m_securitySettings; //This contains the contents of the ATA security regs
} tsHarddiskInfo;
/////////////////////////////////
// LED-flashing codes
// or these together as argument to I2cSetFrontpanelLed
enum {
I2C_LED_RED0 = 0x80,
I2C_LED_RED1 = 0x40,
I2C_LED_RED2 = 0x20,
I2C_LED_RED3 = 0x10,
I2C_LED_GREEN0 = 0x08,
I2C_LED_GREEN1 = 0x04,
I2C_LED_GREEN2 = 0x02,
I2C_LED_GREEN3 = 0x01
};
///////////////////////////////
/* BIOS-wide error codes all have b31 set */
enum {
ERR_SUCCESS = 0, // completed without error
ERR_I2C_ERROR_TIMEOUT = 0x80000001, // I2C action failed because it did not complete in a reasonable time
ERR_I2C_ERROR_BUS = 0x80000002, // I2C action failed due to non retryable bus error
ERR_BOOT_PIC_ALG_BROKEN = 0x80000101 // PIC algorithm did not pass its self-test
};
/////////////////////////////////
// some Boot API prototypes
//////// BootPerformPicChallengeResponseAction.c
/* ---------------------------- IO primitives -----------------------------------------------------------
*/
static __inline void IoOutputByte(u16 wAds, u8 bValue) {
// __asm__ (" out %%al,%%dx" : : "edx" (dwAds), "al" (bValue) );
__asm__ __volatile__ ("outb %b0,%w1": :"a" (bValue), "Nd" (wAds));
}
static __inline void IoOutputWord(u16 wAds, u16 wValue) {
// __asm__ (" out %%ax,%%dx " : : "edx" (dwAds), "ax" (wValue) );
__asm__ __volatile__ ("outw %0,%w1": :"a" (wValue), "Nd" (wAds));
}
static __inline void IoOutputDword(u16 wAds, u32 dwValue) {
// __asm__ (" out %%eax,%%dx " : : "edx" (dwAds), "ax" (wValue) );
__asm__ __volatile__ ("outl %0,%w1": :"a" (dwValue), "Nd" (wAds));
}
static __inline u8 IoInputByte(u16 wAds) {
unsigned char _v;
__asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline u16 IoInputWord(u16 wAds) {
u16 _v;
__asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline u32 IoInputDword(u16 wAds) {
u32 _v;
__asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))
#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))
void BootPciInterruptEnable(void);
// boot process
int BootPerformPicChallengeResponseAction(void);
// LED control (see associated enum above)
int I2cSetFrontpanelLed(u8 b);
#define bprintf(...)
#if PRINT_TRACE
#define TRACE bprintf(__FILE__ " :%d\n\r",__LINE__);
#else
#define TRACE
#endif
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *m_plistentryNext;
struct _LIST_ENTRY *m_plistentryPrevious;
} LIST_ENTRY;
void ListEntryInsertAfterCurrent(LIST_ENTRY *plistentryCurrent, LIST_ENTRY *plistentryNew);
void ListEntryRemove(LIST_ENTRY *plistentryCurrent);
////////// BootPerformXCodeActions.c
int BootPerformXCodeActions(void);
#include "BootEEPROM.h"
#include "BootParser.h"
////////// BootStartBios.c
void StartBios(CONFIGENTRY *config,int nActivePartition, int nFATXPresent,int bootfrom);
int BootMenu(CONFIGENTRY *config,int nDrive,int nActivePartition, int nFATXPresent);
////////// BootResetActions.c
void ClearIDT (void);
void BootResetAction(void);
void BootCpuCache(bool fEnable) ;
int printk(const char *szFormat, ...);
void BiosCmosWrite(u8 bAds, u8 bData);
u8 BiosCmosRead(u8 bAds);
///////// BootPciPeripheralInitialization.c
void BootPciPeripheralInitialization(void);
void BootAGPBUSInitialization(void);
void BootDetectMemorySize(void);
extern void ReadPCIByte(unsigned int bus, unsigned int dev, unsigned intfunc, unsigned int reg_off, unsigned char *pbyteval);
extern void WritePCIByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char byteval);
extern void ReadPCIDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int *pdwordval);
extern void WritePCIDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dwordval);
extern void ReadPCIBlock(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char *buf, unsigned int nbytes);
extern void WritePCIBlock(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char *buf, unsigned int nbytes);
void PciWriteByte (unsigned int bus, unsigned int dev, unsigned int func,
unsigned int reg_off, unsigned char byteval);
u8 PciReadByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off);
u32 PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, u32 dw);
u32 PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off);
///////// BootPerformPicChallengeResponseAction.c
int I2CTransmitWord(u8 bPicAddressI2cFormat, u16 wDataToWrite);
int I2CTransmitByteGetReturn(u8 bPicAddressI2cFormat, u8 bDataToWrite);
bool I2CGetTemperature(int *, int *);
void I2CModifyBits(u8 bAds, u8 bReg, u8 bData, u8 bMask);
///////// BootIde.c
extern tsHarddiskInfo tsaHarddiskInfo[]; // static struct stores data about attached drives
int BootIdeInit(void);
int BootIdeReadSector(int nDriveIndex, void * pbBuffer, unsigned int block, int byte_offset, int n_bytes);
int BootIdeBootSectorHddOrElTorito(int nDriveIndex, u8 * pbaResult);
int BootIdeAtapiAdditionalSenseCode(int nDrive, u8 * pba, int nLengthMaxReturn);
int BootIdeSetTransferMode(int nIndexDrive, int nMode);
int BootIdeWaitNotBusy(unsigned uIoBase);
bool BootIdeAtapiReportFriendlyError(int nDriveIndex, char * szErrorReturn, int nMaxLengthError);
void BootIdeAtapiPrintkFriendlyError(int nDriveIndex);
///////// BootUSB.c
void BootStopUSB(void);
void BootStartUSB(void);
void USBGetEvents(void);
#include "xpad.h"
extern struct xpad_data XPAD_current[4];
extern struct xpad_data XPAD_last[4];
extern void wait_ms(u32 ticks);
extern void wait_us(u32 ticks);
extern void wait_smalldelay(void);
void * memcpy(void *dest, const void *src, size_t size);
void * memset(void *dest, int data, size_t size);
int memcmp(const void *buffer1, const void *buffer2, size_t num);
int _strncmp(const char *sz1, const char *sz2, int nMax);
char * strcpy(char *sz, const char *szc);
char * _strncpy (char * dest, const char * src, size_t n);
void chrreplace(char *string, char search, char ch);
#define printf printk
#define sleep wait_ms
int tolower(int ch);
int isspace (int c);
void MemoryManagementInitialization(void * pvStartAddress, u32 dwTotalMemoryAllocLength);
void * malloc(size_t size);
void free(void *);
extern volatile int nCountI2cinterrupts, nCountUnusedInterrupts, nCountUnusedInterruptsPic2, nCountInterruptsSmc, nCountInterruptsIde;
extern volatile bool fSeenPowerdown;
typedef enum {
ETS_OPEN_OR_OPENING=0,
ETS_CLOSING,
ETS_CLOSED
} TRAY_STATE;
extern volatile TRAY_STATE traystate;
extern void BootInterruptsWriteIdt(void);
#endif
int copy_swap_trim(unsigned char *dst, unsigned char *src, int len);
void HMAC_SHA1( unsigned char *result,
unsigned char *key, int key_length,
unsigned char *text1, int text1_length,
unsigned char *text2, int text2_length );
char *strrchr0(char *string, char ch);
#endif // _Boot_H_
#ifndef _Boot_H_
#define _Boot_H_
#include "config.h"
/***************************************************************************
Includes used by XBox boot code
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/////////////////////////////////
// configuration
#include "consts.h"
#include "stdint.h"
#include "cromwell_types.h"
unsigned int cromwell_config;
unsigned int cromwell_retryload;
unsigned int cromwell_loadbank;
unsigned int cromwell_Biostype;
unsigned int xbox_ram;
#define XROMWELL 0
#define CROMWELL 1
#define ICON_WIDTH 64
#define ICON_HEIGHT 64
/*
static double min (double a, double b)
{
if (a < b) return a; else return b;
}
static inline double max (double a, double b)
{
if (a > b) return a; else return b;
}
*/
//#include "iso_fs.h"
//#include "BootVideo.h"
//#define ASSERT(exp) { if(!(exp)) { bprintf("Assert failed file " __FILE__ " line %d\n", __LINE__); } }
#if 0
extern volatile CURRENT_VIDEO_MODE_DETAILS vmode;
unsigned int video_encoder;
volatile u32 VIDEO_CURSOR_POSX;
volatile u32 VIDEO_CURSOR_POSY;
volatile u32 VIDEO_ATTR;
volatile u32 VIDEO_LUMASCALING;
volatile u32 VIDEO_RSCALING;
volatile u32 VIDEO_BSCALING;
volatile u32 BIOS_TICK_COUNT;
volatile u32 VIDEO_VSYNC_POSITION;
volatile u32 VIDEO_VSYNC_DIR;
volatile u32 DVD_TRAY_STATE;
u8 VIDEO_AV_MODE ;
#define DVD_CLOSED 0
#define DVD_CLOSING 1
#define DVD_OPEN 2
#define DVD_OPENING 3
/////////////////////////////////
// Superfunky i386 internal structures
typedef struct gdt_t {
unsigned short m_wSize __attribute__ ((packed));
unsigned long m_dwBase32 __attribute__ ((packed));
unsigned short m_wDummy __attribute__ ((packed));
} ts_descriptor_pointer;
typedef struct { // inside an 8-byte protected mode interrupt vector
u16 m_wHandlerHighAddressLow16;
u16 m_wSelector;
u16 m_wType;
u16 m_wHandlerLinearAddressHigh16;
} ts_pm_interrupt;
typedef enum {
EDT_UNKNOWN= 0,
EDT_XBOXFS
} enumDriveType;
typedef struct tsHarddiskInfo { // this is the retained knowledge about an IDE device after init
unsigned short m_fwPortBase;
unsigned short m_wCountHeads;
unsigned short m_wCountCylinders;
unsigned short m_wCountSectorsPerTrack;
unsigned long m_dwCountSectorsTotal; /* total */
unsigned char m_bLbaMode; /* am i lba (0x40) or chs (0x00) */
unsigned char m_szIdentityModelNumber[40];
unsigned char term_space_1[2];
unsigned char m_szSerial[20];
unsigned char term_space_2[2];
char m_szFirmware[8];
unsigned char term_space_3[2];
unsigned char m_fDriveExists;
unsigned char m_fAtapi; // true if a CDROM, etc
enumDriveType m_enumDriveType;
unsigned char m_bCableConductors; // valid for device 0 if present
unsigned short m_wAtaRevisionSupported;
unsigned char s_length;
unsigned char m_length;
unsigned char m_fHasMbr;
unsigned short m_securitySettings; //This contains the contents of the ATA security regs
} tsHarddiskInfo;
/////////////////////////////////
// LED-flashing codes
// or these together as argument to I2cSetFrontpanelLed
enum {
I2C_LED_RED0 = 0x80,
I2C_LED_RED1 = 0x40,
I2C_LED_RED2 = 0x20,
I2C_LED_RED3 = 0x10,
I2C_LED_GREEN0 = 0x08,
I2C_LED_GREEN1 = 0x04,
I2C_LED_GREEN2 = 0x02,
I2C_LED_GREEN3 = 0x01
};
///////////////////////////////
/* BIOS-wide error codes all have b31 set */
enum {
ERR_SUCCESS = 0, // completed without error
ERR_I2C_ERROR_TIMEOUT = 0x80000001, // I2C action failed because it did not complete in a reasonable time
ERR_I2C_ERROR_BUS = 0x80000002, // I2C action failed due to non retryable bus error
ERR_BOOT_PIC_ALG_BROKEN = 0x80000101 // PIC algorithm did not pass its self-test
};
/////////////////////////////////
// some Boot API prototypes
//////// BootPerformPicChallengeResponseAction.c
/* ---------------------------- IO primitives -----------------------------------------------------------
*/
static __inline void IoOutputByte(u16 wAds, u8 bValue) {
// __asm__ (" out %%al,%%dx" : : "edx" (dwAds), "al" (bValue) );
__asm__ __volatile__ ("outb %b0,%w1": :"a" (bValue), "Nd" (wAds));
}
static __inline void IoOutputWord(u16 wAds, u16 wValue) {
// __asm__ (" out %%ax,%%dx " : : "edx" (dwAds), "ax" (wValue) );
__asm__ __volatile__ ("outw %0,%w1": :"a" (wValue), "Nd" (wAds));
}
static __inline void IoOutputDword(u16 wAds, u32 dwValue) {
// __asm__ (" out %%eax,%%dx " : : "edx" (dwAds), "ax" (wValue) );
__asm__ __volatile__ ("outl %0,%w1": :"a" (dwValue), "Nd" (wAds));
}
static __inline u8 IoInputByte(u16 wAds) {
unsigned char _v;
__asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline u16 IoInputWord(u16 wAds) {
u16 _v;
__asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline u32 IoInputDword(u16 wAds) {
u32 _v;
__asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))
#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))
void BootPciInterruptEnable(void);
// boot process
int BootPerformPicChallengeResponseAction(void);
// LED control (see associated enum above)
int I2cSetFrontpanelLed(u8 b);
#define bprintf(...)
#if PRINT_TRACE
#define TRACE bprintf(__FILE__ " :%d\n\r",__LINE__);
#else
#define TRACE
#endif
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *m_plistentryNext;
struct _LIST_ENTRY *m_plistentryPrevious;
} LIST_ENTRY;
void ListEntryInsertAfterCurrent(LIST_ENTRY *plistentryCurrent, LIST_ENTRY *plistentryNew);
void ListEntryRemove(LIST_ENTRY *plistentryCurrent);
////////// BootPerformXCodeActions.c
int BootPerformXCodeActions(void);
#include "BootEEPROM.h"
#include "BootParser.h"
////////// BootStartBios.c
void StartBios(CONFIGENTRY *config,int nActivePartition, int nFATXPresent,int bootfrom);
int BootMenu(CONFIGENTRY *config,int nDrive,int nActivePartition, int nFATXPresent);
////////// BootResetActions.c
void ClearIDT (void);
void BootResetAction(void);
void BootCpuCache(bool fEnable) ;
int printk(const char *szFormat, ...);
void BiosCmosWrite(u8 bAds, u8 bData);
u8 BiosCmosRead(u8 bAds);
///////// BootPciPeripheralInitialization.c
void BootPciPeripheralInitialization(void);
void BootAGPBUSInitialization(void);
void BootDetectMemorySize(void);
extern void ReadPCIByte(unsigned int bus, unsigned int dev, unsigned intfunc, unsigned int reg_off, unsigned char *pbyteval);
extern void WritePCIByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char byteval);
extern void ReadPCIDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int *pdwordval);
extern void WritePCIDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dwordval);
extern void ReadPCIBlock(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char *buf, unsigned int nbytes);
extern void WritePCIBlock(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char *buf, unsigned int nbytes);
void PciWriteByte (unsigned int bus, unsigned int dev, unsigned int func,
unsigned int reg_off, unsigned char byteval);
u8 PciReadByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off);
u32 PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, u32 dw);
u32 PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off);
///////// BootPerformPicChallengeResponseAction.c
int I2CTransmitWord(u8 bPicAddressI2cFormat, u16 wDataToWrite);
int I2CTransmitByteGetReturn(u8 bPicAddressI2cFormat, u8 bDataToWrite);
bool I2CGetTemperature(int *, int *);
void I2CModifyBits(u8 bAds, u8 bReg, u8 bData, u8 bMask);
///////// BootIde.c
extern tsHarddiskInfo tsaHarddiskInfo[]; // static struct stores data about attached drives
int BootIdeInit(void);
int BootIdeReadSector(int nDriveIndex, void * pbBuffer, unsigned int block, int byte_offset, int n_bytes);
int BootIdeBootSectorHddOrElTorito(int nDriveIndex, u8 * pbaResult);
int BootIdeAtapiAdditionalSenseCode(int nDrive, u8 * pba, int nLengthMaxReturn);
int BootIdeSetTransferMode(int nIndexDrive, int nMode);
int BootIdeWaitNotBusy(unsigned uIoBase);
bool BootIdeAtapiReportFriendlyError(int nDriveIndex, char * szErrorReturn, int nMaxLengthError);
void BootIdeAtapiPrintkFriendlyError(int nDriveIndex);
///////// BootUSB.c
void BootStopUSB(void);
void BootStartUSB(void);
void USBGetEvents(void);
#include "xpad.h"
extern struct xpad_data XPAD_current[4];
extern struct xpad_data XPAD_last[4];
extern void wait_ms(u32 ticks);
extern void wait_us(u32 ticks);
extern void wait_smalldelay(void);
void * memcpy(void *dest, const void *src, size_t size);
void * memset(void *dest, int data, size_t size);
int memcmp(const void *buffer1, const void *buffer2, size_t num);
int _strncmp(const char *sz1, const char *sz2, int nMax);
char * strcpy(char *sz, const char *szc);
char * _strncpy (char * dest, const char * src, size_t n);
void chrreplace(char *string, char search, char ch);
#define printf printk
#define sleep wait_ms
int tolower(int ch);
int isspace (int c);
void MemoryManagementInitialization(void * pvStartAddress, u32 dwTotalMemoryAllocLength);
void * malloc(size_t size);
void free(void *);
extern volatile int nCountI2cinterrupts, nCountUnusedInterrupts, nCountUnusedInterruptsPic2, nCountInterruptsSmc, nCountInterruptsIde;
extern volatile bool fSeenPowerdown;
typedef enum {
ETS_OPEN_OR_OPENING=0,
ETS_CLOSING,
ETS_CLOSED
} TRAY_STATE;
extern volatile TRAY_STATE traystate;
extern void BootInterruptsWriteIdt(void);
#endif
int copy_swap_trim(unsigned char *dst, unsigned char *src, int len);
void HMAC_SHA1( unsigned char *result,
unsigned char *key, int key_length,
unsigned char *text1, int text1_length,
unsigned char *text2, int text2_length );
char *strrchr0(char *string, char ch);
#endif // _Boot_H_

View file

@ -1,70 +1,70 @@
#ifndef _Consts_H_
#define _Consts_H_
/*
*
* includes for startup code in a form usable by the .S files
*
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#define PCI_CFG_ADDR 0x0CF8
#define PCI_CFG_DATA 0x0CFC
#define I2C_IO_BASE 0xc000
#define BUS_0 0
#define BUS_1 1
#define DEV_0 0
#define DEV_1 1
#define DEV_2 2
#define DEV_3 3
#define DEV_4 4
#define DEV_5 5
#define DEV_6 6
#define DEV_7 7
#define DEV_8 8
#define DEV_9 9
#define DEV_a 0xa
#define DEV_b 0xb
#define DEV_c 0xc
#define DEV_d 0xd
#define DEV_e 0xe
#define DEV_f 0xf
#define DEV_10 0x10
#define DEV_11 0x11
#define DEV_12 0x12
#define DEV_13 0x13
#define DEV_14 0x14
#define DEV_15 0x15
#define DEV_16 0x16
#define DEV_17 0x17
#define DEV_18 0x18
#define DEV_19 0x19
#define DEV_1a 0x1a
#define DEV_1b 0x1b
#define DEV_1c 0x1c
#define DEV_1d 0x1d
#define DEV_1e 0x1e
#define DEV_1f 0x1f
#define FUNC_0 0
/*
#define boot_post_macro(value) \
movb $(value), %al ;\
outb %al, $0x80
*/
#endif // _Consts_H_
#ifndef _Consts_H_
#define _Consts_H_
/*
*
* includes for startup code in a form usable by the .S files
*
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#define PCI_CFG_ADDR 0x0CF8
#define PCI_CFG_DATA 0x0CFC
#define I2C_IO_BASE 0xc000
#define BUS_0 0
#define BUS_1 1
#define DEV_0 0
#define DEV_1 1
#define DEV_2 2
#define DEV_3 3
#define DEV_4 4
#define DEV_5 5
#define DEV_6 6
#define DEV_7 7
#define DEV_8 8
#define DEV_9 9
#define DEV_a 0xa
#define DEV_b 0xb
#define DEV_c 0xc
#define DEV_d 0xd
#define DEV_e 0xe
#define DEV_f 0xf
#define DEV_10 0x10
#define DEV_11 0x11
#define DEV_12 0x12
#define DEV_13 0x13
#define DEV_14 0x14
#define DEV_15 0x15
#define DEV_16 0x16
#define DEV_17 0x17
#define DEV_18 0x18
#define DEV_19 0x19
#define DEV_1a 0x1a
#define DEV_1b 0x1b
#define DEV_1c 0x1c
#define DEV_1d 0x1d
#define DEV_1e 0x1e
#define DEV_1f 0x1f
#define FUNC_0 0
/*
#define boot_post_macro(value) \
movb $(value), %al ;\
outb %al, $0x80
*/
#endif // _Consts_H_

View file

@ -1,27 +1,27 @@
#ifndef cromwell_types_h
#define cromwell_types_h
/////////////////////////////////
// some typedefs to make for easy sizing
//typedef unsigned long ULONG;
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#ifndef bool_already_defined_
typedef int bool;
#endif
typedef unsigned long RGBA; // LSB=R -> MSB = A
//typedef long long __int64;
#define guint int
#define guint8 unsigned char
#define true 1
#define false 0
#ifndef NULL
#define NULL ((void *)0)
#endif
#endif /* #ifndef cromwell_types_h */
#ifndef cromwell_types_h
#define cromwell_types_h
/////////////////////////////////
// some typedefs to make for easy sizing
//typedef unsigned long ULONG;
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#ifndef bool_already_defined_
typedef int bool;
#endif
typedef unsigned long RGBA; // LSB=R -> MSB = A
//typedef long long __int64;
#define guint int
#define guint8 unsigned char
#define true 1
#define false 0
#ifndef NULL
#define NULL ((void *)0)
#endif
#endif /* #ifndef cromwell_types_h */

View file

@ -1,132 +1,132 @@
#ifndef _I386_ERRNO_H
#define _I386_ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#endif
#ifndef _I386_ERRNO_H
#define _I386_ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,224 +1,224 @@
#ifndef _BOOT_LIST_H
#define _BOOT_LIST_H
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (void *) 0;
entry->prev = (void *) 0;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(struct list_head *head)
{
return head->next == head;
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member) \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#endif
#ifndef _BOOT_LIST_H
#define _BOOT_LIST_H
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (void *) 0;
entry->prev = (void *) 0;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(struct list_head *head)
{
return head->next == head;
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member) \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#endif

View file

@ -1,158 +1,162 @@
// PCI -> HAL interface
// this file is part of linux_wrapper.h
//FIXME: Move this file, make its definitions more general
#include "../host/ohci_main.h"
/*
Initialize device before it's used by a driver. Ask low-level code to enable I/O and memory.
Wake up the device if it was suspended. Beware, this function can fail.
*/
static int __inline__ pci_enable_device(struct pci_dev *dev)
{
DPRINT1("pci_enable_device() called...\n");
return 0;
}
// Get physical address where resource x resides
static PHYSICAL_ADDRESS __inline__ pci_resource_start (struct pci_dev *dev, int x)
{
POHCI_DEVICE_EXTENSION dev_ext = (POHCI_DEVICE_EXTENSION)dev->dev_ext;
DPRINT1("pci_resource_start() called, x=0x%x\n", x);
//FIXME: Take x into account
return dev_ext->BaseAddress;
//return dev->base[x];
}
// ???
static unsigned long __inline__ pci_resource_len (struct pci_dev *dev, int x)
{
POHCI_DEVICE_EXTENSION ext = (POHCI_DEVICE_EXTENSION)dev->dev_ext;
DPRINT1("pci_resource_len() called, x=0x%x\n", x);
//FIXME: Take x into account
return ext->BaseAddrLength;
}
// ???
static int __inline__ pci_resource_flags(struct pci_dev *dev, int x)
{
DPRINT1("pci_resource_flags() called, x=0x%x\n");
return dev->flags[x];
}
/*
Enables bus-mastering for device dev
*/
static int __inline__ pci_set_master(struct pci_dev *dev) {return 0;}
// Store pointer to data for this device
static int __inline__ pci_set_drvdata(struct pci_dev *dev, void* d)
{
DPRINT1("pci_set_drvdata() called...\n");
dev->data=(void*)d;
return 0;
}
// Get pointer to previously saved data
static void __inline__ *pci_get_drvdata(struct pci_dev *dev)
{
DPRINT1("pci_get_drvdata() called...\n");
return dev->data;
}
/*
===========================================================================
I/O mem related stuff below
*/
/*
Allocate I/O memory region.
Parameters:
start begin of region
n length of region
name name of requester
*/
static int __inline__ request_region(PHYSICAL_ADDRESS addr, unsigned long len, const char * d)
{
DPRINT1("request_region(): addr=0x%x, len=0x%x\n", addr, len);
return 0;
}
/*
Unmap I/O memory from kernel address space.
Parameters:
addr virtual start address
*/
static int __inline__ iounmap(void* p)
{
DPRINT1("iounmap(): p=0x%x. FIXME - how to obtain len of mapped region?\n", p);
//MmUnnapIoSpace(p);
return 0;
}
/*
Release I/O port region.
Parameters:
start begin of region
n length of region
*/
static int __inline__ release_region(PHYSICAL_ADDRESS addr, unsigned long len)
{
DPRINT1("release_region(): addr=0x%x, len=0x%x\n", addr, len);
return 0;
}
/*
Allocate I/O memory region.
Parameters:
start begin of region
n length of region
name name of requester
*/
static int __inline__ request_mem_region(PHYSICAL_ADDRESS addr, unsigned long len, const char * d)
{
DPRINT1("request_mem_region(): addr=0x%x, len=0x%x\n", addr, len);
return 1;
}
/*
Remap I/O memory into kernel address space (no cache).
Parameters:
phys_addr begin of physical address range
size size of physical address range
Returns:
virtual start address of mapped range
*/
static void __inline__ *ioremap_nocache(PHYSICAL_ADDRESS addr, unsigned long len)
{
// MmMapIoSpace with NoCache param
DPRINT1("ioremap_nocache(): addr=0x%x, len=0x%x\n", addr, len);
return MmMapIoSpace(addr, len, MmNonCached);
}
/*
Release I/O memory region.
Parameters:
start begin of region
n length of region
*/
static int __inline__ release_mem_region(PHYSICAL_ADDRESS addr, unsigned long len)
{
DPRINT1("release_mem_region(): addr=0x%x, len=0x%x\n", addr, len);
return 0;
}
// PCI -> HAL interface
// this file is part of linux_wrapper.h
//FIXME: Move this file, make its definitions more general
#include "../host/ohci_main.h"
/*
Initialize device before it's used by a driver. Ask low-level code to enable I/O and memory.
Wake up the device if it was suspended. Beware, this function can fail.
*/
static int __inline__ pci_enable_device(struct pci_dev *dev)
{
DPRINT1("pci_enable_device() called...\n");
return 0;
}
// Get physical address where resource x resides
static PHYSICAL_ADDRESS __inline__ pci_resource_start (struct pci_dev *dev, int x)
{
POHCI_DEVICE_EXTENSION dev_ext = (POHCI_DEVICE_EXTENSION)dev->dev_ext;
DPRINT1("pci_resource_start() called, x=0x%x\n", x);
//FIXME: Take x into account
return dev_ext->BaseAddress;
//return dev->base[x];
}
// ???
static unsigned long __inline__ pci_resource_len (struct pci_dev *dev, int x)
{
POHCI_DEVICE_EXTENSION ext = (POHCI_DEVICE_EXTENSION)dev->dev_ext;
DPRINT1("pci_resource_len() called, x=0x%x\n", x);
//FIXME: Take x into account
return ext->BaseAddrLength;
}
// ???
static int __inline__ pci_resource_flags(struct pci_dev *dev, int x)
{
POHCI_DEVICE_EXTENSION ext = (POHCI_DEVICE_EXTENSION)dev->dev_ext;
DPRINT1("pci_resource_flags() called, x=0x%x\n", x);
//FIXME: Take x into account
return ext->Flags;
}
/*
Enables bus-mastering for device dev
*/
static int __inline__ pci_set_master(struct pci_dev *dev) {return 0;}
// Store pointer to data for this device
static int __inline__ pci_set_drvdata(struct pci_dev *dev, void* d)
{
DPRINT1("pci_set_drvdata() called...\n");
dev->data=(void*)d;
return 0;
}
// Get pointer to previously saved data
static void __inline__ *pci_get_drvdata(struct pci_dev *dev)
{
DPRINT1("pci_get_drvdata() called...\n");
return dev->data;
}
/*
===========================================================================
I/O mem related stuff below
*/
/*
Allocate I/O memory region.
Parameters:
start begin of region
n length of region
name name of requester
*/
static int __inline__ request_region(PHYSICAL_ADDRESS addr, unsigned long len, const char * d)
{
DPRINT1("request_region(): addr=0x%lx, len=0x%lx\n", addr.u.LowPart, len);
return ~0;
}
/*
Unmap I/O memory from kernel address space.
Parameters:
addr virtual start address
*/
static int __inline__ iounmap(void* p)
{
DPRINT1("iounmap(): p=0x%x. FIXME - how to obtain len of mapped region?\n", p);
//MmUnnapIoSpace(p);
return 0;
}
/*
Release I/O port region.
Parameters:
start begin of region
n length of region
*/
static int __inline__ release_region(PHYSICAL_ADDRESS addr, unsigned long len)
{
DPRINT1("release_region(): addr=0x%lx, len=0x%lx\n", addr.u.LowPart, len);
return 0;
}
/*
Allocate I/O memory region.
Parameters:
start begin of region
n length of region
name name of requester
*/
static int __inline__ request_mem_region(PHYSICAL_ADDRESS addr, unsigned long len, const char * d)
{
DPRINT1("request_mem_region(): addr=0x%lx, len=0x%lx\n", addr.u.LowPart, len);
return 1;
}
/*
Remap I/O memory into kernel address space (no cache).
Parameters:
phys_addr begin of physical address range
size size of physical address range
Returns:
virtual start address of mapped range
*/
static void __inline__ *ioremap_nocache(PHYSICAL_ADDRESS addr, unsigned long len)
{
// MmMapIoSpace with NoCache param
DPRINT1("ioremap_nocache(): addr=0x%lx, len=0x%lx\n", addr.u.LowPart, len);
return MmMapIoSpace(addr, len, MmNonCached);
}
/*
Release I/O memory region.
Parameters:
start begin of region
n length of region
*/
static int __inline__ release_mem_region(PHYSICAL_ADDRESS addr, unsigned long len)
{
DPRINT1("release_mem_region(): addr=0x%lx, len=0x%lx\n", addr.u.LowPart, len);
return 0;
}

View file

@ -1,16 +1,16 @@
#ifndef PCI_IDS__H
#define PCI_IDS__H
#define PCI_VENDOR_ID_NS 0x100b
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_VENDOR_ID_OPTI 0x1045
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_NS_87560_LIO 0x000e
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_CLASS_SERIAL_USB (PCI_CLASS_SERIAL_BUS_CTLR << 8 + PCI_SUBCLASS_SB_USB)
#endif
#ifndef PCI_IDS__H
#define PCI_IDS__H
#define PCI_VENDOR_ID_NS 0x100b
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_VENDOR_ID_OPTI 0x1045
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_NS_87560_LIO 0x000e
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_CLASS_SERIAL_USB ((PCI_CLASS_SERIAL_BUS_CTLR << 8) + PCI_SUBCLASS_SB_USB)
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,315 +1,315 @@
/*
* This file holds USB constants and structures that are needed for USB
* device APIs. These are used by the USB device model, which is defined
* in chapter 9 of the USB 2.0 specification. Linux has several APIs in C
* that need these:
*
* - the master/host side Linux-USB kernel driver API;
* - the "usbfs" user space API; and
* - (eventually) a Linux "gadget" slave/device side driver API.
*
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
* act either as a USB master/host or as a USB slave/device. That means
* the master and slave side APIs will benefit from working well together.
*/
#ifndef __LINUX_USB_CH9_H
#define __LINUX_USB_CH9_H
#if 0
#include <asm/types.h> /* __u8 etc */
#endif
/*-------------------------------------------------------------------------*/
/* CONTROL REQUEST SUPPORT */
/*
* USB directions
*
* This bit flag is used in endpoint descriptors' bEndpointAddress field.
* It's also one of three fields in control requests bRequestType.
*/
#define USB_DIR_OUT 0 /* to device */
#define USB_DIR_IN 0x80 /* to host */
/*
* USB types, the second of three bRequestType fields
*/
#define USB_TYPE_MASK (0x03 << 5)
#define USB_TYPE_STANDARD (0x00 << 5)
#define USB_TYPE_CLASS (0x01 << 5)
#define USB_TYPE_VENDOR (0x02 << 5)
#define USB_TYPE_RESERVED (0x03 << 5)
/*
* USB recipients, the third of three bRequestType fields
*/
#define USB_RECIP_MASK 0x1f
#define USB_RECIP_DEVICE 0x00
#define USB_RECIP_INTERFACE 0x01
#define USB_RECIP_ENDPOINT 0x02
#define USB_RECIP_OTHER 0x03
/*
* Standard requests, for the bRequest field of a SETUP packet.
*
* These are qualified by the bRequestType field, so that for example
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
* by a GET_STATUS request.
*/
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
/**
* struct usb_ctrlrequest - SETUP data for a USB device control request
* @bRequestType: matches the USB bmRequestType field
* @bRequest: matches the USB bRequest field
* @wValue: matches the USB wValue field (le16 byte order)
* @wIndex: matches the USB wIndex field (le16 byte order)
* @wLength: matches the USB wLength field (le16 byte order)
*
* This structure is used to send control requests to a USB device. It matches
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
* USB spec for a fuller description of the different fields, and what they are
* used for.
*
* Note that the driver for any interface can issue control requests.
* For most devices, interfaces don't coordinate with each other, so
* such requests may be made at any time.
*/
struct usb_ctrlrequest {
__u8 bRequestType;
__u8 bRequest;
__u16 wValue;
__u16 wIndex;
__u16 wLength;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/*
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
* (rarely) accepted by SET_DESCRIPTOR.
*
* Note that all multi-byte values here are encoded in little endian
* byte order "on the wire". But when exposed through Linux-USB APIs,
* they've been converted to cpu byte order.
*/
/*
* Descriptor types ... USB 2.0 spec table 9.5
*/
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_DEVICE_QUALIFIER 0x06
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_INTERFACE_POWER 0x08
/* All standard descriptors have these 2 fields at the beginning */
struct usb_descriptor_header {
__u8 bLength;
__u8 bDescriptorType;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
#define USB_DT_DEVICE_SIZE 18
/*
* Device and/or Interface Class codes
* as found in bDeviceClass or bInterfaceClass
* and defined by www.usb.org documents
*/
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
#define USB_CLASS_AUDIO 1
#define USB_CLASS_COMM 2
#define USB_CLASS_HID 3
#define USB_CLASS_PHYSICAL 5
#define USB_CLASS_STILL_IMAGE 6
#define USB_CLASS_PRINTER 7
#define USB_CLASS_MASS_STORAGE 8
#define USB_CLASS_HUB 9
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff
/*-------------------------------------------------------------------------*/
/* USB_DT_CONFIG: Configuration descriptor information.
*
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
* descriptor type is different. Highspeed-capable devices can look
* different depending on what speed they're currently running. Only
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
* descriptors.
*/
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
#define USB_DT_CONFIG_SIZE 9
/* from config descriptor bmAttributes */
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
/*-------------------------------------------------------------------------*/
/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 wData[1]; /* UTF-16LE encoded */
} __attribute__ ((packed));
/* note that "string" zero is special, it holds language codes that
* the device supports, not Unicode characters.
*/
/*-------------------------------------------------------------------------*/
/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
#define USB_DT_INTERFACE_SIZE 9
/*-------------------------------------------------------------------------*/
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__u16 wMaxPacketSize;
__u8 bInterval;
// NOTE: these two are _only_ in audio endpoints.
// use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof.
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
/*
* Endpoints
*/
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
#define USB_ENDPOINT_DIR_MASK 0x80
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
#define USB_ENDPOINT_XFER_INT 3
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
struct usb_qualifier_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__u8 bNumConfigurations;
__u8 bRESERVED;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB 2.0 defines three speeds, here's how Linux identifies them */
enum usb_device_speed {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH /* usb 2.0 */
};
enum usb_device_state {
/* NOTATTACHED isn't in the USB spec, and this state acts
* the same as ATTACHED ... but it's clearer this way.
*/
USB_STATE_NOTATTACHED = 0,
/* the chapter 9 device states */
USB_STATE_ATTACHED,
USB_STATE_POWERED,
USB_STATE_DEFAULT, /* limited function */
USB_STATE_ADDRESS,
USB_STATE_CONFIGURED, /* most functions */
USB_STATE_SUSPENDED
/* NOTE: there are actually four different SUSPENDED
* states, returning to POWERED, DEFAULT, ADDRESS, or
* CONFIGURED respectively when SOF tokens flow again.
*/
};
#endif /* __LINUX_USB_CH9_H */
/*
* This file holds USB constants and structures that are needed for USB
* device APIs. These are used by the USB device model, which is defined
* in chapter 9 of the USB 2.0 specification. Linux has several APIs in C
* that need these:
*
* - the master/host side Linux-USB kernel driver API;
* - the "usbfs" user space API; and
* - (eventually) a Linux "gadget" slave/device side driver API.
*
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
* act either as a USB master/host or as a USB slave/device. That means
* the master and slave side APIs will benefit from working well together.
*/
#ifndef __LINUX_USB_CH9_H
#define __LINUX_USB_CH9_H
#if 0
#include <asm/types.h> /* __u8 etc */
#endif
/*-------------------------------------------------------------------------*/
/* CONTROL REQUEST SUPPORT */
/*
* USB directions
*
* This bit flag is used in endpoint descriptors' bEndpointAddress field.
* It's also one of three fields in control requests bRequestType.
*/
#define USB_DIR_OUT 0 /* to device */
#define USB_DIR_IN 0x80 /* to host */
/*
* USB types, the second of three bRequestType fields
*/
#define USB_TYPE_MASK (0x03 << 5)
#define USB_TYPE_STANDARD (0x00 << 5)
#define USB_TYPE_CLASS (0x01 << 5)
#define USB_TYPE_VENDOR (0x02 << 5)
#define USB_TYPE_RESERVED (0x03 << 5)
/*
* USB recipients, the third of three bRequestType fields
*/
#define USB_RECIP_MASK 0x1f
#define USB_RECIP_DEVICE 0x00
#define USB_RECIP_INTERFACE 0x01
#define USB_RECIP_ENDPOINT 0x02
#define USB_RECIP_OTHER 0x03
/*
* Standard requests, for the bRequest field of a SETUP packet.
*
* These are qualified by the bRequestType field, so that for example
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
* by a GET_STATUS request.
*/
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
/**
* struct usb_ctrlrequest - SETUP data for a USB device control request
* @bRequestType: matches the USB bmRequestType field
* @bRequest: matches the USB bRequest field
* @wValue: matches the USB wValue field (le16 byte order)
* @wIndex: matches the USB wIndex field (le16 byte order)
* @wLength: matches the USB wLength field (le16 byte order)
*
* This structure is used to send control requests to a USB device. It matches
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
* USB spec for a fuller description of the different fields, and what they are
* used for.
*
* Note that the driver for any interface can issue control requests.
* For most devices, interfaces don't coordinate with each other, so
* such requests may be made at any time.
*/
struct usb_ctrlrequest {
__u8 bRequestType;
__u8 bRequest;
__u16 wValue;
__u16 wIndex;
__u16 wLength;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/*
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
* (rarely) accepted by SET_DESCRIPTOR.
*
* Note that all multi-byte values here are encoded in little endian
* byte order "on the wire". But when exposed through Linux-USB APIs,
* they've been converted to cpu byte order.
*/
/*
* Descriptor types ... USB 2.0 spec table 9.5
*/
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_DEVICE_QUALIFIER 0x06
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_INTERFACE_POWER 0x08
/* All standard descriptors have these 2 fields at the beginning */
struct usb_descriptor_header {
__u8 bLength;
__u8 bDescriptorType;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
#define USB_DT_DEVICE_SIZE 18
/*
* Device and/or Interface Class codes
* as found in bDeviceClass or bInterfaceClass
* and defined by www.usb.org documents
*/
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
#define USB_CLASS_AUDIO 1
#define USB_CLASS_COMM 2
#define USB_CLASS_HID 3
#define USB_CLASS_PHYSICAL 5
#define USB_CLASS_STILL_IMAGE 6
#define USB_CLASS_PRINTER 7
#define USB_CLASS_MASS_STORAGE 8
#define USB_CLASS_HUB 9
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff
/*-------------------------------------------------------------------------*/
/* USB_DT_CONFIG: Configuration descriptor information.
*
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
* descriptor type is different. Highspeed-capable devices can look
* different depending on what speed they're currently running. Only
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
* descriptors.
*/
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
#define USB_DT_CONFIG_SIZE 9
/* from config descriptor bmAttributes */
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
/*-------------------------------------------------------------------------*/
/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 wData[1]; /* UTF-16LE encoded */
} __attribute__ ((packed));
/* note that "string" zero is special, it holds language codes that
* the device supports, not Unicode characters.
*/
/*-------------------------------------------------------------------------*/
/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
#define USB_DT_INTERFACE_SIZE 9
/*-------------------------------------------------------------------------*/
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__u16 wMaxPacketSize;
__u8 bInterval;
// NOTE: these two are _only_ in audio endpoints.
// use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof.
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
/*
* Endpoints
*/
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
#define USB_ENDPOINT_DIR_MASK 0x80
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
#define USB_ENDPOINT_XFER_INT 3
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
struct usb_qualifier_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__u8 bNumConfigurations;
__u8 bRESERVED;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB 2.0 defines three speeds, here's how Linux identifies them */
enum usb_device_speed {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH /* usb 2.0 */
};
enum usb_device_state {
/* NOTATTACHED isn't in the USB spec, and this state acts
* the same as ATTACHED ... but it's clearer this way.
*/
USB_STATE_NOTATTACHED = 0,
/* the chapter 9 device states */
USB_STATE_ATTACHED,
USB_STATE_POWERED,
USB_STATE_DEFAULT, /* limited function */
USB_STATE_ADDRESS,
USB_STATE_CONFIGURED, /* most functions */
USB_STATE_SUSPENDED
/* NOTE: there are actually four different SUSPENDED
* states, returning to POWERED, DEFAULT, ADDRESS, or
* CONFIGURED respectively when SOF tokens flow again.
*/
};
#endif /* __LINUX_USB_CH9_H */

View file

@ -1,90 +1,90 @@
/*
* USB support for XBOX, based on Linux kernel source
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
*/
#include "../usb_wrapper.h"
void subsys_usb_init(void);
void module_exit_usb_exit(void);
extern struct pci_device_id *module_table_pci_ids;
// straigth call...
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id);
void usb_hcd_pci_remove (struct pci_dev *dev);
void XPADInit(void);
void XPADRemove(void);
void XRemoteInit(void);
void XRemoteRemove(void);
extern int (*thread_handler)(void*);
int (*hub_thread_handler)(void*);
extern int nousb;
extern int xpad_num;
struct pci_dev xx_ohci_dev={
.vendor = 0,
.device = 0,
.bus = NULL,
.irq = 1, // currently not used...
.slot_name = "OHCI",
.dev = {.name = "PCI",.dma_mask=1},
.base = {0xfed00000},
.flags = {}
};
/*------------------------------------------------------------------------*/
void BootStartUSB(void)
{
int n;
nousb=0;
init_wrapper();
subsys_usb_init();
hub_thread_handler=thread_handler;
usb_hcd_pci_probe(&xx_ohci_dev, module_table_pci_ids);
XPADInit();
XRemoteInit();
UsbKeyBoardInit();
for(n=0;n<30;n++) {
USBGetEvents();
wait_ms(1);
}
}
/*------------------------------------------------------------------------*/
void USBGetEvents(void)
{
inc_jiffies(1);
do_all_timers();
hub_thread_handler(NULL);
handle_irqs(-1);
}
/*------------------------------------------------------------------------*/
void BootStopUSB(void)
{
int n;
XPADRemove();
XRemoteRemove();
UsbKeyBoardRemove();
for(n=0;n<100;n++)
{
USBGetEvents();
wait_ms(1);
}
module_exit_usb_exit();
usb_hcd_pci_remove(&xx_ohci_dev);
}
/*------------------------------------------------------------------------*/
/*
* USB support for XBOX, based on Linux kernel source
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
*/
#include "../usb_wrapper.h"
void subsys_usb_init(void);
void module_exit_usb_exit(void);
extern struct pci_device_id *module_table_pci_ids;
// straigth call...
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id);
void usb_hcd_pci_remove (struct pci_dev *dev);
void XPADInit(void);
void XPADRemove(void);
void XRemoteInit(void);
void XRemoteRemove(void);
extern int (*thread_handler)(void*);
int (*hub_thread_handler)(void*);
extern int nousb;
extern int xpad_num;
struct pci_dev xx_ohci_dev={
.vendor = 0,
.device = 0,
.bus = NULL,
.irq = 1, // currently not used...
.slot_name = "OHCI",
.dev = {.name = "PCI",.dma_mask=1},
.base = {0xfed00000},
.flags = {}
};
/*------------------------------------------------------------------------*/
void BootStartUSB(void)
{
int n;
nousb=0;
init_wrapper();
subsys_usb_init();
hub_thread_handler=thread_handler;
usb_hcd_pci_probe(&xx_ohci_dev, module_table_pci_ids);
XPADInit();
XRemoteInit();
UsbKeyBoardInit();
for(n=0;n<30;n++) {
USBGetEvents();
wait_ms(1);
}
}
/*------------------------------------------------------------------------*/
void USBGetEvents(void)
{
inc_jiffies(1);
do_all_timers();
hub_thread_handler(NULL);
handle_irqs(-1);
}
/*------------------------------------------------------------------------*/
void BootStopUSB(void)
{
int n;
XPADRemove();
XRemoteRemove();
UsbKeyBoardRemove();
for(n=0;n<100;n++)
{
USBGetEvents();
wait_ms(1);
}
module_exit_usb_exit();
usb_hcd_pci_remove(&xx_ohci_dev);
}
/*------------------------------------------------------------------------*/

View file

@ -1,4 +1,5 @@
O_TARGET := usbwrapper.o BootUSB.o linuxwrapper.o xpad.o xremote.o usbkey.o risefall.o
include $(TOPDIR)/Rules.make
O_TARGET := usbwrapper.o BootUSB.o linuxwrapper.o xpad.o xremote.o usbkey.o risefall.o
include $(TOPDIR)/Rules.make

View file

@ -1,375 +1,382 @@
/*
* USB support based on Linux kernel source
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
* Concept:
*
* 1) Forget all device interrupts, scheduling, semaphores, threads etc.
* 1a) Forget all DMA and PCI helper functions
* 2) Forget usbdevfs, procfs and ioctls
* 3) Emulate OHCI interrupts and root hub timer by polling
* 4) Emulate hub kernel thread by polling
* 5) Emulate synchronous USB-messages (usb_*_msg) with busy waiting
*
* To be done:
* 6) Remove code bloat
*
*/
#include "../usb_wrapper.h"
/* internal state */
static struct pci_dev *pci_probe_dev;
extern int (*thread_handler)(void*);
extern void* thread_parm;
struct my_irqs reg_irqs[MAX_IRQS];
int num_irqs;
int need_wakeup;
int my_jiffies;
struct timer_list *main_timer_list[MAX_TIMERS];
struct dummy_process act_cur={0};
struct dummy_process *my_current;
int (*thread_handler)(void*);
void* thread_parm;
#define MAX_DRVS 8
static struct device_driver *m_drivers[MAX_DRVS];
static int drvs_num;
/*------------------------------------------------------------------------*/
/*
* Helper functions for top-level system
*/
/*------------------------------------------------------------------------*/
void init_wrapper(struct pci_dev *probe_dev)
{
int n;
for(n=0;n<MAX_TIMERS;n++)
{
main_timer_list[n]=NULL;
}
my_jiffies=0;
num_irqs=0;
my_current=&act_cur;
pci_probe_dev=probe_dev;
for(n=0;n<MAX_IRQS;n++)
{
reg_irqs[n].handler=NULL;
reg_irqs[n].irq=-1;
}
drvs_num=0;
need_wakeup=0;
for(n=0;n<MAX_DRVS;n++)
m_drivers[n]=NULL;
}
/*------------------------------------------------------------------------*/
void handle_irqs(int irq)
{
int n;
// printk("handle irqs\n");
for(n=0;n<MAX_IRQS;n++)
{
if (reg_irqs[n].handler && (irq==reg_irqs[n].irq || irq==-1))
reg_irqs[n].handler(reg_irqs[n].irq,reg_irqs[n].data,NULL);
}
}
/*------------------------------------------------------------------------*/
void inc_jiffies(int n)
{
my_jiffies+=n;
}
/*------------------------------------------------------------------------*/
void do_all_timers(void)
{
int n;
for(n=0;n<MAX_TIMERS;n++)
{
if (main_timer_list[n] &&
main_timer_list[n]->function && main_timer_list[n]->expires)
{
void (*function)(unsigned long)=main_timer_list[n]->function;
unsigned long data=main_timer_list[n]->data;
main_timer_list[n]->expires=0;
main_timer_list[n]=NULL; // remove timer
// printk("do timer %i fn %p\n",n,function);
function(data);
}
}
}
/*------------------------------------------------------------------------*/
// Purpose: Remember thread procedure and data in global var
// ReactOS Purpose: Create real kernel thread
int my_kernel_thread(int STDCALL (*handler)(void*), void* parm, int flags)
{
HANDLE hThread;
//thread_handler=handler;
//thread_parm=parm;
//return 42; // PID :-)
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
PsCreateSystemThread(&hThread,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE)handler,
parm);
return (int)hThread; // FIXME: Correct?
}
// Kill the process
int my_kill_proc(int pid, int signal, int unk)
{
HANDLE hThread;
// TODO: Implement actual process killing
hThread = (HANDLE)pid;
ZwClose(hThread);
return 0;
}
/*------------------------------------------------------------------------*/
/* Device management
* As simple as possible, but as complete as necessary ...
*/
/*------------------------------------------------------------------------*/
/* calls probe function for hotplug (which does device matching), this is the
only link between usbcore and the registered device drivers! */
int my_device_add(struct device *dev)
{
int n,found=0;
// printk("drv_num %i %p %p\n",drvs_num,m_drivers[0]->probe,m_drivers[1]->probe);
if (dev->driver)
{
if (dev->driver->probe)
return dev->driver->probe(dev);
}
else
{
for(n=0;n<drvs_num;n++)
{
if (m_drivers[n]->probe)
{
dev->driver=m_drivers[n];
// printk("probe%i %p ",n,m_drivers[n]->probe);
if (m_drivers[n]->probe(dev) == 0)
{
// return 0;
found=1;
}
}
}
if (found) return 0;
}
dev->driver=NULL;
return -ENODEV;
}
/*------------------------------------------------------------------------*/
int my_driver_register(struct device_driver *driver)
{
if (drvs_num<MAX_DRVS)
{
// printk("driver_register %i: %p %p",drvs_num,driver,driver->probe);
m_drivers[drvs_num++]=driver;
return 0;
}
return -1;
}
/*------------------------------------------------------------------------*/
int my_device_unregister(struct device *dev)
{
if (dev->driver && dev->driver->remove)
dev->driver->remove(dev);
return 0;
}
/*------------------------------------------------------------------------*/
struct device *my_get_device(struct device *dev)
{
return NULL;
}
/*------------------------------------------------------------------------*/
void my_device_initialize(struct device *dev)
{
}
/*------------------------------------------------------------------------*/
void my_wake_up(PKEVENT evnt)
{
need_wakeup=1;
KeSetEvent(evnt, 0, FALSE); // Signal event
}
/*------------------------------------------------------------------------*/
void my_init_waitqueue_head(PKEVENT evnt)
{
// this is used only in core/message.c, and it isn't needed there
//KeInitializeEvent(evnt, NotificationEvent, TRUE); // signalled state
}
/*------------------------------------------------------------------------*/
/* wait until woken up (only one wait allowed!) */
int my_schedule_timeout(int x)
{
int wait=1;
x+=10; // safety
// printk("schedule_timeout %i\n",x);
while(x>0)
{
do_all_timers();
#ifndef HAVE_IRQS
handle_irqs(-1);
#endif
if (need_wakeup)
break;
wait_ms(wait);
inc_jiffies(wait);
x-=wait;
}
need_wakeup=0;
// printk("schedule DONE!!!!!!\n");
return x;
}
/*------------------------------------------------------------------------*/
void my_wait_for_completion(struct completion *x)
{
int n=100;
// printk("wait for completion\n");
while(!x->done && (n>0))
{
do_all_timers();
#ifndef HAVE_IRQS
handle_irqs(-1);
#endif
wait_ms(10);
n--;
}
// printk("wait for completion done %i\n",x->done);
}
/*------------------------------------------------------------------------*/
void my_interruptible_sleep_on(PKEVENT evnt)
{
KeWaitForSingleObject(evnt, Executive, KernelMode, FALSE, NULL);
KeClearEvent(evnt); // reset to not-signalled
}
/*------------------------------------------------------------------------*/
// Helper for pci_module_init
/*------------------------------------------------------------------------*/
int my_pci_module_init(struct pci_driver *x)
{
struct pci_dev *dev=pci_probe_dev;
const struct pci_device_id *id=NULL;
if (!pci_probe_dev)
{
printk(KERN_ERR "PCI device not set!\n");
return 0;
}
x->probe(dev, id);
return 0;
}
/*------------------------------------------------------------------------*/
struct pci_dev *my_pci_find_slot(int a,int b)
{
return NULL;
}
/*------------------------------------------------------------------------*/
int my_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
{
//dev->bus, dev->devfn, where, val
OHCI_DEVICE_EXTENSION *dev_ext = (OHCI_DEVICE_EXTENSION *)dev->dev_ext;
//FIXME: Is returning this value correct?
//FIXME: Mixing pci_dev and win structs isn't a good thing at all
return HalSetBusDataByOffset(PCIConfiguration, dev->bus->number, dev_ext->SystemIoSlotNumber, &val, where, sizeof(val));
}
/*------------------------------------------------------------------------*/
int my_request_irq(unsigned int irq,
int (*handler)(int,void *, struct pt_regs *),
unsigned long mode, const char *desc, void *data)
{
if (num_irqs<MAX_IRQS)
{
reg_irqs[num_irqs].handler=handler;
reg_irqs[num_irqs].irq=irq;
reg_irqs[num_irqs].data=data;
num_irqs++;
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
int my_free_irq(int irq, void* p)
{
/* No free... */
return 0;
}
/*------------------------------------------------------------------------*/
// Lookaside funcs
/*------------------------------------------------------------------------*/
kmem_cache_t *my_kmem_cache_create(const char *tag, size_t alloc_size,
size_t offset, unsigned long flags,
void *ctor,
void *dtor)
{
//TODO: Take in account ctor and dtor - callbacks for alloc/free, flags and offset
//FIXME: We assume this cache is always NPaged
PNPAGED_LOOKASIDE_LIST Lookaside;
ULONG Tag=0x11223344; //FIXME: Make this from tag
Lookaside = ExAllocatePool(NonPagedPool, sizeof(NPAGED_LOOKASIDE_LIST));
ExInitializeNPagedLookasideList(
Lookaside,
NULL,
NULL,
0,
alloc_size,
Tag,
0);
return (kmem_cache_t *)Lookaside;
}
/*------------------------------------------------------------------------*/
BOOLEAN my_kmem_cache_destroy(kmem_cache_t *co)
{
ExDeleteNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co);
ExFreePool(co);
return FALSE;
}
/*------------------------------------------------------------------------*/
void *my_kmem_cache_alloc(kmem_cache_t *co, int flags)
{
return ExAllocateFromNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co);
}
/*------------------------------------------------------------------------*/
void my_kmem_cache_free(kmem_cache_t *co, void *ptr)
{
ExFreeToNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co, ptr);
}
/*------------------------------------------------------------------------*/
// DMA, not used now
/*------------------------------------------------------------------------*/
void *my_dma_pool_alloc(struct dma_pool *pool, int gfp_flags, dma_addr_t *dma_handle)
{
// HalAllocCommonBuffer
// But ideally IoGetDmaAdapter
return NULL;
}
/*
* USB support based on Linux kernel source
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
* Concept:
*
* 1) Forget all device interrupts, scheduling, semaphores, threads etc.
* 1a) Forget all DMA and PCI helper functions
* 2) Forget usbdevfs, procfs and ioctls
* 3) Emulate OHCI interrupts and root hub timer by polling
* 4) Emulate hub kernel thread by polling
* 5) Emulate synchronous USB-messages (usb_*_msg) with busy waiting
*
* To be done:
* 6) Remove code bloat
*
*/
#include "../usb_wrapper.h"
/* internal state */
static struct pci_dev *pci_probe_dev;
extern int (*thread_handler)(void*);
extern void* thread_parm;
struct my_irqs reg_irqs[MAX_IRQS];
int num_irqs;
int need_wakeup;
int my_jiffies;
struct timer_list *main_timer_list[MAX_TIMERS];
struct dummy_process act_cur={0};
struct dummy_process *my_current;
int (*thread_handler)(void*);
void* thread_parm;
#define MAX_DRVS 8
static struct device_driver *m_drivers[MAX_DRVS];
static int drvs_num;
/*------------------------------------------------------------------------*/
/*
* Helper functions for top-level system
*/
/*------------------------------------------------------------------------*/
void init_wrapper(struct pci_dev *probe_dev)
{
int n;
for(n=0;n<MAX_TIMERS;n++)
{
main_timer_list[n]=NULL;
}
my_jiffies=0;
num_irqs=0;
my_current=&act_cur;
pci_probe_dev=probe_dev;
for(n=0;n<MAX_IRQS;n++)
{
reg_irqs[n].handler=NULL;
reg_irqs[n].irq=-1;
}
drvs_num=0;
need_wakeup=0;
for(n=0;n<MAX_DRVS;n++)
m_drivers[n]=NULL;
}
/*------------------------------------------------------------------------*/
void handle_irqs(int irq)
{
int n;
printk("handle irqs\n");
for(n=0;n<MAX_IRQS;n++)
{
if (reg_irqs[n].handler && (irq==reg_irqs[n].irq || irq==-1))
reg_irqs[n].handler(reg_irqs[n].irq,reg_irqs[n].data,NULL);
}
}
/*------------------------------------------------------------------------*/
void inc_jiffies(int n)
{
my_jiffies+=n;
}
/*------------------------------------------------------------------------*/
void do_all_timers(void)
{
int n;
for(n=0;n<MAX_TIMERS;n++)
{
if (main_timer_list[n] &&
main_timer_list[n]->function && main_timer_list[n]->expires)
{
void (*function)(unsigned long)=main_timer_list[n]->function;
unsigned long data=main_timer_list[n]->data;
main_timer_list[n]->expires=0;
main_timer_list[n]=NULL; // remove timer
printk("do timer %i fn %p\n",n,function);
function(data);
}
}
}
/*------------------------------------------------------------------------*/
// Purpose: Remember thread procedure and data in global var
// ReactOS Purpose: Create real kernel thread
int my_kernel_thread(int STDCALL (*handler)(void*), void* parm, int flags)
{
HANDLE hThread;
//thread_handler=handler;
//thread_parm=parm;
//return 42; // PID :-)
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
PsCreateSystemThread(&hThread,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE)handler,
parm);
return (int)hThread; // FIXME: Correct?
}
// Kill the process
int my_kill_proc(int pid, int signal, int unk)
{
HANDLE hThread;
// TODO: Implement actual process killing
hThread = (HANDLE)pid;
ZwClose(hThread);
return 0;
}
/*------------------------------------------------------------------------*/
/* Device management
* As simple as possible, but as complete as necessary ...
*/
/*------------------------------------------------------------------------*/
/* calls probe function for hotplug (which does device matching), this is the
only link between usbcore and the registered device drivers! */
int my_device_add(struct device *dev)
{
int n,found=0;
printk("drv_num %i %p %p\n",drvs_num,m_drivers[0]->probe,m_drivers[1]->probe);
if (dev->driver)
{
if (dev->driver->probe)
return dev->driver->probe(dev);
}
else
{
for(n=0;n<drvs_num;n++)
{
if (m_drivers[n]->probe)
{
dev->driver=m_drivers[n];
printk("probe%i %p ",n,m_drivers[n]->probe);
if (m_drivers[n]->probe(dev) == 0)
{
// return 0;
found=1;
}
}
}
if (found) return 0;
}
dev->driver=NULL;
return -ENODEV;
}
/*------------------------------------------------------------------------*/
int my_driver_register(struct device_driver *driver)
{
if (drvs_num<MAX_DRVS)
{
printk("driver_register %i: %p %p",drvs_num,driver,driver->probe);
m_drivers[drvs_num++]=driver;
return 0;
}
return -1;
}
/*------------------------------------------------------------------------*/
int my_device_unregister(struct device *dev)
{
if (dev->driver && dev->driver->remove)
dev->driver->remove(dev);
return 0;
}
/*------------------------------------------------------------------------*/
struct device *my_get_device(struct device *dev)
{
return NULL;
}
/*------------------------------------------------------------------------*/
void my_device_initialize(struct device *dev)
{
}
/*------------------------------------------------------------------------*/
void my_wake_up(PKEVENT evnt)
{
need_wakeup=1;
KeSetEvent(evnt, 0, FALSE); // Signal event
}
/*------------------------------------------------------------------------*/
void my_init_waitqueue_head(PKEVENT evnt)
{
// this is used only in core/message.c, and it isn't needed there
//KeInitializeEvent(evnt, NotificationEvent, TRUE); // signalled state
}
/*------------------------------------------------------------------------*/
/* wait until woken up (only one wait allowed!) */
int my_schedule_timeout(int x)
{
int wait=1;
x+=10; // safety
printk("schedule_timeout %i\n",x);
while(x>0)
{
do_all_timers();
#ifndef HAVE_IRQS
handle_irqs(-1);
#endif
if (need_wakeup)
break;
wait_ms(wait);
inc_jiffies(wait);
x-=wait;
}
need_wakeup=0;
printk("schedule DONE!!!!!!\n");
return x;
}
/*------------------------------------------------------------------------*/
void my_wait_for_completion(struct completion *x)
{
int n=100;
printk("wait for completion\n");
while(!x->done && (n>0))
{
do_all_timers();
#ifndef HAVE_IRQS
handle_irqs(-1);
#endif
wait_ms(10);
n--;
}
printk("wait for completion done %i\n",x->done);
}
/*------------------------------------------------------------------------*/
void my_interruptible_sleep_on(PKEVENT evnt)
{
KeWaitForSingleObject(evnt, Executive, KernelMode, FALSE, NULL);
KeClearEvent(evnt); // reset to not-signalled
}
/*------------------------------------------------------------------------*/
// Helper for pci_module_init
/*------------------------------------------------------------------------*/
int my_pci_module_init(struct pci_driver *x)
{
struct pci_dev *dev=pci_probe_dev;
const struct pci_device_id *id=NULL;
if (!pci_probe_dev)
{
DPRINT1("PCI device not set!\n");
return 0;
}
x->probe(dev, id);
return 0;
}
/*------------------------------------------------------------------------*/
struct pci_dev *my_pci_find_slot(int a,int b)
{
return NULL;
}
/*------------------------------------------------------------------------*/
int my_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
{
//dev->bus, dev->devfn, where, val
OHCI_DEVICE_EXTENSION *dev_ext = (OHCI_DEVICE_EXTENSION *)dev->dev_ext;
//FIXME: Is returning this value correct?
//FIXME: Mixing pci_dev and win structs isn't a good thing at all
return HalSetBusDataByOffset(PCIConfiguration, dev->bus->number, dev_ext->SystemIoSlotNumber, &val, where, sizeof(val));
}
/*------------------------------------------------------------------------*/
int my_request_irq(unsigned int irq,
int (*handler)(int,void *, struct pt_regs *),
unsigned long mode, const char *desc, void *data)
{
if (num_irqs<MAX_IRQS)
{
reg_irqs[num_irqs].handler=handler;
reg_irqs[num_irqs].irq=irq;
reg_irqs[num_irqs].data=data;
num_irqs++;
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
int my_free_irq(int irq, void* p)
{
/* No free... */
return 0;
}
/*------------------------------------------------------------------------*/
// Lookaside funcs
/*------------------------------------------------------------------------*/
kmem_cache_t *my_kmem_cache_create(const char *tag, size_t alloc_size,
size_t offset, unsigned long flags,
void *ctor,
void *dtor)
{
//TODO: Take in account ctor and dtor - callbacks for alloc/free, flags and offset
//FIXME: We assume this cache is always NPaged
PNPAGED_LOOKASIDE_LIST Lookaside;
ULONG Tag=0x11223344; //FIXME: Make this from tag
Lookaside = ExAllocatePool(NonPagedPool, sizeof(NPAGED_LOOKASIDE_LIST));
ExInitializeNPagedLookasideList(
Lookaside,
NULL,
NULL,
0,
alloc_size,
Tag,
0);
return (kmem_cache_t *)Lookaside;
}
/*------------------------------------------------------------------------*/
BOOLEAN my_kmem_cache_destroy(kmem_cache_t *co)
{
ExDeleteNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co);
ExFreePool(co);
return FALSE;
}
/*------------------------------------------------------------------------*/
void *my_kmem_cache_alloc(kmem_cache_t *co, int flags)
{
return ExAllocateFromNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co);
}
/*------------------------------------------------------------------------*/
void my_kmem_cache_free(kmem_cache_t *co, void *ptr)
{
ExFreeToNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)co, ptr);
}
/*------------------------------------------------------------------------*/
// DMA, not used now
/*------------------------------------------------------------------------*/
void *my_dma_pool_alloc(struct dma_pool *pool, int gfp_flags, dma_addr_t *dma_handle)
{
// HalAllocCommonBuffer
// But ideally IoGetDmaAdapter
return NULL;
}

View file

@ -1,138 +1,138 @@
#include "../usb_wrapper.h"
#include "config.h"
#include "xremote.h"
// This is for the Xpad
extern unsigned char xpad_button_history[7];
// This is for the Keyboard
extern unsigned int current_keyboard_key;
int risefall_xpad_BUTTON(unsigned char selected_Button) {
int xpad_id;
int match;
extern int xpad_num;
// USB keyboard section
match=0;
if (current_keyboard_key!=0) {
switch (selected_Button) {
case TRIGGER_XPAD_KEY_A :
if (current_keyboard_key == 0x28) match=1;
break;
case TRIGGER_XPAD_KEY_B :
if (current_keyboard_key == 0x29) match=1;
break;
case TRIGGER_XPAD_PAD_UP :
if (current_keyboard_key == 0x52) match=1;
break;
case TRIGGER_XPAD_PAD_DOWN :
if (current_keyboard_key == 0x51) match=1;
break;
case TRIGGER_XPAD_PAD_LEFT :
if (current_keyboard_key == 0x50) match=1;
break;
case TRIGGER_XPAD_PAD_RIGHT :
if (current_keyboard_key == 0x4f) match=1;
break;
}
if (match) {
//A match occurred, so the event has now been processed
//Clear it, and return success
current_keyboard_key=0;
return 1;
}
}
// Xbox IR remote section
match=0;
if (!remotekeyIsRepeat) {
/* We only grab the key event when the button is first pressed.
* If it's being held down, we ignore the multiple events this
* generates */
switch (selected_Button) {
case TRIGGER_XPAD_KEY_A:
if (current_remote_key == RC_KEY_SELECT) match=1;
break;
case TRIGGER_XPAD_PAD_UP:
if (current_remote_key == RC_KEY_UP) match=1;
break;
case TRIGGER_XPAD_PAD_DOWN:
if (current_remote_key == RC_KEY_DOWN) match=1;
break;
case TRIGGER_XPAD_PAD_LEFT:
if (current_remote_key == RC_KEY_LEFT) match=1;
break;
case TRIGGER_XPAD_PAD_RIGHT:
if (current_remote_key == RC_KEY_RIGHT) match=1;
break;
case TRIGGER_XPAD_KEY_BACK:
if (current_remote_key == RC_KEY_BACK) match=1;
break;
}
if (match) {
//A match occurred, so the event has now been processed
//Clear it, and return success
current_remote_key=0;
remotekeyIsRepeat=0;
return 1;
}
}
// Xbox controller section
if (selected_Button < 6) {
unsigned char Button;
Button = XPAD_current[0].keys[selected_Button];
if ((Button>0x30)&&(xpad_button_history[selected_Button]==0)) {
// Button Rising Edge
xpad_button_history[selected_Button] = 1;
return 1;
}
if ((Button==0x00)&&(xpad_button_history[selected_Button]==1)) {
// Button Falling Edge
xpad_button_history[selected_Button] = 0;
return -1;
}
}
if ((selected_Button > 5) & (selected_Button < 10) ) {
unsigned char Buttonmask;
switch (selected_Button) {
case TRIGGER_XPAD_PAD_UP :
Buttonmask = XPAD_PAD_UP;
break;
case TRIGGER_XPAD_PAD_DOWN :
Buttonmask = XPAD_PAD_DOWN;
break;
case TRIGGER_XPAD_PAD_LEFT :
Buttonmask = XPAD_PAD_LEFT;
break;
case TRIGGER_XPAD_PAD_RIGHT :
Buttonmask = XPAD_PAD_RIGHT;
break;
}
// Rising Edge
if (((XPAD_current[0].pad&Buttonmask) != 0) & ((xpad_button_history[6]&Buttonmask) == 0)) {
xpad_button_history[6] ^= Buttonmask; // Flip the Bit
return 1;
}
// Falling Edge
if (((XPAD_current[0].pad&Buttonmask) == 0) & ((xpad_button_history[6]&Buttonmask) != 0)) {
xpad_button_history[6] ^= Buttonmask; // Flip the Bit
return -1;
}
}
return 0;
}
#include "../usb_wrapper.h"
#include "config.h"
#include "xremote.h"
// This is for the Xpad
extern unsigned char xpad_button_history[7];
// This is for the Keyboard
extern unsigned int current_keyboard_key;
int risefall_xpad_BUTTON(unsigned char selected_Button) {
int xpad_id;
int match;
extern int xpad_num;
// USB keyboard section
match=0;
if (current_keyboard_key!=0) {
switch (selected_Button) {
case TRIGGER_XPAD_KEY_A :
if (current_keyboard_key == 0x28) match=1;
break;
case TRIGGER_XPAD_KEY_B :
if (current_keyboard_key == 0x29) match=1;
break;
case TRIGGER_XPAD_PAD_UP :
if (current_keyboard_key == 0x52) match=1;
break;
case TRIGGER_XPAD_PAD_DOWN :
if (current_keyboard_key == 0x51) match=1;
break;
case TRIGGER_XPAD_PAD_LEFT :
if (current_keyboard_key == 0x50) match=1;
break;
case TRIGGER_XPAD_PAD_RIGHT :
if (current_keyboard_key == 0x4f) match=1;
break;
}
if (match) {
//A match occurred, so the event has now been processed
//Clear it, and return success
current_keyboard_key=0;
return 1;
}
}
// Xbox IR remote section
match=0;
if (!remotekeyIsRepeat) {
/* We only grab the key event when the button is first pressed.
* If it's being held down, we ignore the multiple events this
* generates */
switch (selected_Button) {
case TRIGGER_XPAD_KEY_A:
if (current_remote_key == RC_KEY_SELECT) match=1;
break;
case TRIGGER_XPAD_PAD_UP:
if (current_remote_key == RC_KEY_UP) match=1;
break;
case TRIGGER_XPAD_PAD_DOWN:
if (current_remote_key == RC_KEY_DOWN) match=1;
break;
case TRIGGER_XPAD_PAD_LEFT:
if (current_remote_key == RC_KEY_LEFT) match=1;
break;
case TRIGGER_XPAD_PAD_RIGHT:
if (current_remote_key == RC_KEY_RIGHT) match=1;
break;
case TRIGGER_XPAD_KEY_BACK:
if (current_remote_key == RC_KEY_BACK) match=1;
break;
}
if (match) {
//A match occurred, so the event has now been processed
//Clear it, and return success
current_remote_key=0;
remotekeyIsRepeat=0;
return 1;
}
}
// Xbox controller section
if (selected_Button < 6) {
unsigned char Button;
Button = XPAD_current[0].keys[selected_Button];
if ((Button>0x30)&&(xpad_button_history[selected_Button]==0)) {
// Button Rising Edge
xpad_button_history[selected_Button] = 1;
return 1;
}
if ((Button==0x00)&&(xpad_button_history[selected_Button]==1)) {
// Button Falling Edge
xpad_button_history[selected_Button] = 0;
return -1;
}
}
if ((selected_Button > 5) & (selected_Button < 10) ) {
unsigned char Buttonmask;
switch (selected_Button) {
case TRIGGER_XPAD_PAD_UP :
Buttonmask = XPAD_PAD_UP;
break;
case TRIGGER_XPAD_PAD_DOWN :
Buttonmask = XPAD_PAD_DOWN;
break;
case TRIGGER_XPAD_PAD_LEFT :
Buttonmask = XPAD_PAD_LEFT;
break;
case TRIGGER_XPAD_PAD_RIGHT :
Buttonmask = XPAD_PAD_RIGHT;
break;
}
// Rising Edge
if (((XPAD_current[0].pad&Buttonmask) != 0) & ((xpad_button_history[6]&Buttonmask) == 0)) {
xpad_button_history[6] ^= Buttonmask; // Flip the Bit
return 1;
}
// Falling Edge
if (((XPAD_current[0].pad&Buttonmask) == 0) & ((xpad_button_history[6]&Buttonmask) != 0)) {
xpad_button_history[6] ^= Buttonmask; // Flip the Bit
return -1;
}
}
return 0;
}

View file

@ -1,10 +1,10 @@
#include "../usb_wrapper.h"
void wait_ms(int mils)
{
LARGE_INTEGER Interval;
Interval.QuadPart = -mils*10;
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}
#include "../usb_wrapper.h"
void wait_ms(int mils)
{
LARGE_INTEGER Interval;
Interval.QuadPart = -mils*10;
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}

View file

@ -1,123 +1,123 @@
#include "../usb_wrapper.h"
#define keyboarddebug 0
#if keyboarddebug
extern int printe(const char *szFormat, ...);
int ycoffset = 0;
#endif
unsigned int current_keyboard_key;
struct usb_kbd_info {
struct urb *urb;
unsigned char kbd_pkt[8];
unsigned char old[8];
/*
struct input_dev dev;
struct usb_device *usbdev;
struct urb irq, led;
struct usb_ctrlrequest dr;
unsigned char leds, newleds;
char name[128];
int open;
*/
};
static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_kbd_info *kbd = urb->context;
int i;
if (urb->status) return;
memcpy(kbd->kbd_pkt, urb->transfer_buffer, 8);
current_keyboard_key = kbd->kbd_pkt[2];
#if keyboarddebug
ycoffset += 15;
ycoffset = ycoffset % 600;
VIDEO_CURSOR_POSX=20;
VIDEO_CURSOR_POSY=ycoffset;
printe(" -%02x %02x %02x %02x %02x %02x\n",kbd->kbd_pkt[0],kbd->kbd_pkt[1],kbd->kbd_pkt[2],kbd->kbd_pkt[3],kbd->kbd_pkt[4],kbd->kbd_pkt[5]);
#endif
usb_submit_urb(urb,GFP_ATOMIC);
}
static int usb_kbd_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct usb_kbd_info *usbk;
int i, pipe, maxp;
char *buf;
usbk=(struct usb_kbd_info *)kmalloc(sizeof(struct usb_kbd_info),0);
if (!usbk) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
usbk->urb=urb;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
usbk->kbd_pkt, 8, usb_kbd_irq,
usbk, 8);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,usbk);
#if keyboarddebug
printe("USB Keyboard Connected\n");
#endif
}
static void usb_kbd_disconnect(struct usb_interface *intf)
{
struct usb_kbd_info *usbk = usb_get_intfdata (intf);
usbprintk("Keyboard disconnected\n ");
usb_unlink_urb(usbk->urb);
usb_free_urb(usbk->urb);
kfree(usbk);
}
static struct usb_device_id usb_kbd_id_table [] = {
{ USB_INTERFACE_INFO(3, 1, 1) },
{ } /* Terminating entry */
};
static struct usb_driver usb_kbd_driver = {
.owner = THIS_MODULE,
.name = "keyboard",
.probe = usb_kbd_probe,
.disconnect = usb_kbd_disconnect,
.id_table = usb_kbd_id_table,
};
void UsbKeyBoardInit(void)
{
//current_remote_key=0;
//sbprintk("Keyboard probe %p ",xremote_probe);
if (usb_register(&usb_kbd_driver) < 0) {
#if keyboarddebug
printe("Unable to register Keyboard driver");
#endif
return;
}
}
void UsbKeyBoardRemove(void) {
usb_deregister(&usb_kbd_driver);
}
#include "../usb_wrapper.h"
#define keyboarddebug 0
#if keyboarddebug
extern int printe(const char *szFormat, ...);
int ycoffset = 0;
#endif
unsigned int current_keyboard_key;
struct usb_kbd_info {
struct urb *urb;
unsigned char kbd_pkt[8];
unsigned char old[8];
/*
struct input_dev dev;
struct usb_device *usbdev;
struct urb irq, led;
struct usb_ctrlrequest dr;
unsigned char leds, newleds;
char name[128];
int open;
*/
};
static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_kbd_info *kbd = urb->context;
int i;
if (urb->status) return;
memcpy(kbd->kbd_pkt, urb->transfer_buffer, 8);
current_keyboard_key = kbd->kbd_pkt[2];
#if keyboarddebug
ycoffset += 15;
ycoffset = ycoffset % 600;
VIDEO_CURSOR_POSX=20;
VIDEO_CURSOR_POSY=ycoffset;
printe(" -%02x %02x %02x %02x %02x %02x\n",kbd->kbd_pkt[0],kbd->kbd_pkt[1],kbd->kbd_pkt[2],kbd->kbd_pkt[3],kbd->kbd_pkt[4],kbd->kbd_pkt[5]);
#endif
usb_submit_urb(urb,GFP_ATOMIC);
}
static int usb_kbd_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct usb_kbd_info *usbk;
int i, pipe, maxp;
char *buf;
usbk=(struct usb_kbd_info *)kmalloc(sizeof(struct usb_kbd_info),0);
if (!usbk) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
usbk->urb=urb;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
usbk->kbd_pkt, 8, usb_kbd_irq,
usbk, 8);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,usbk);
#if keyboarddebug
printe("USB Keyboard Connected\n");
#endif
}
static void usb_kbd_disconnect(struct usb_interface *intf)
{
struct usb_kbd_info *usbk = usb_get_intfdata (intf);
usbprintk("Keyboard disconnected\n ");
usb_unlink_urb(usbk->urb);
usb_free_urb(usbk->urb);
kfree(usbk);
}
static struct usb_device_id usb_kbd_id_table [] = {
{ USB_INTERFACE_INFO(3, 1, 1) },
{ } /* Terminating entry */
};
static struct usb_driver usb_kbd_driver = {
.owner = THIS_MODULE,
.name = "keyboard",
.probe = usb_kbd_probe,
.disconnect = usb_kbd_disconnect,
.id_table = usb_kbd_id_table,
};
void UsbKeyBoardInit(void)
{
//current_remote_key=0;
//sbprintk("Keyboard probe %p ",xremote_probe);
if (usb_register(&usb_kbd_driver) < 0) {
#if keyboarddebug
printe("Unable to register Keyboard driver");
#endif
return;
}
}
void UsbKeyBoardRemove(void) {
usb_deregister(&usb_kbd_driver);
}

View file

@ -1,65 +1,65 @@
/*
* Interface calls to BIOS
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
*/
#include "boot.h"
#include <stdarg.h>
#include "video.h"
/*------------------------------------------------------------------------*/
// Output window for USB messages
int usb_curs_x=0;
int usb_curs_y=0;
void zxprintf(char* fmt, ...)
{
va_list ap;
char buffer[1024];
int tmp_x, tmp_y;
tmp_x=VIDEO_CURSOR_POSX;
tmp_y=VIDEO_CURSOR_POSY;
VIDEO_CURSOR_POSX=usb_curs_x;
VIDEO_CURSOR_POSY=usb_curs_y;
if ((VIDEO_CURSOR_POSY==0) || (VIDEO_CURSOR_POSY > (vmode.height -16)))
{
BootVideoClearScreen(&jpegBackdrop, 3*vmode.height/4,
vmode.height);
VIDEO_CURSOR_POSY=3*vmode.height/4;
}
va_start(ap, fmt);
vsprintf(buffer,fmt,ap);
//printk(buffer);
va_end(ap);
usb_curs_x=VIDEO_CURSOR_POSX;
usb_curs_y=VIDEO_CURSOR_POSY;
VIDEO_CURSOR_POSX=tmp_x;
VIDEO_CURSOR_POSY=tmp_y;
}
/*------------------------------------------------------------------------*/
int zxsnprintf(char *buffer, size_t s, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/
int zxsprintf(char *buffer, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/
/*
* Interface calls to BIOS
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
*/
#include "boot.h"
#include <stdarg.h>
#include "video.h"
/*------------------------------------------------------------------------*/
// Output window for USB messages
int usb_curs_x=0;
int usb_curs_y=0;
void zxprintf(char* fmt, ...)
{
va_list ap;
char buffer[1024];
int tmp_x, tmp_y;
tmp_x=VIDEO_CURSOR_POSX;
tmp_y=VIDEO_CURSOR_POSY;
VIDEO_CURSOR_POSX=usb_curs_x;
VIDEO_CURSOR_POSY=usb_curs_y;
if ((VIDEO_CURSOR_POSY==0) || (VIDEO_CURSOR_POSY > (vmode.height -16)))
{
BootVideoClearScreen(&jpegBackdrop, 3*vmode.height/4,
vmode.height);
VIDEO_CURSOR_POSY=3*vmode.height/4;
}
va_start(ap, fmt);
vsprintf(buffer,fmt,ap);
//printk(buffer);
va_end(ap);
usb_curs_x=VIDEO_CURSOR_POSX;
usb_curs_y=VIDEO_CURSOR_POSY;
VIDEO_CURSOR_POSX=tmp_x;
VIDEO_CURSOR_POSY=tmp_y;
}
/*------------------------------------------------------------------------*/
int zxsnprintf(char *buffer, size_t s, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/
int zxsprintf(char *buffer, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/

View file

@ -1,183 +1,183 @@
/*
* Simple XPAD driver for XBOX
*
* (c) 2003-07-04, Georg Acher (georg@acher.org)
*
* Inspired by linux/drivers/usb/input/xpad.c
* by Marko Friedemann <mfr@bmx-chemnitz.de>
*
*/
#include "../usb_wrapper.h"
#include "config.h"
// history for the Rising - falling events
unsigned char xpad_button_history[7];
/* Stores time and XPAD state */
struct xpad_data XPAD_current[4];
struct xpad_data XPAD_last[4];
struct xpad_info
{
struct urb *urb;
int num;
unsigned char data[32];
};
int xpad_num=0;
/*------------------------------------------------------------------------*/
static void xpad_irq(struct urb *urb, struct pt_regs *regs)
{
struct xpad_info *xpi = urb->context;
unsigned char* data= urb->transfer_buffer;
// struct xpad_data *xp=&XPAD_current[xpi->num];
// struct xpad_data *xpo=&XPAD_last[xpi->num];
/* This hack means the xpad event always gets posted to the
* first xpad - avoids problems iterating over multiple xpads
* as the xpi->num entries are not reused when xpads are
* connected, then removed */
struct xpad_data *xp=&XPAD_current[0];
struct xpad_data *xpo=&XPAD_last[0];
if (xpi->num<0 || xpi->num>3)
return;
memcpy(xpo,xp,sizeof(struct xpad_data));
xp->stick_left_x=(short) (((short)data[13] << 8) | data[12]);
xp->stick_left_y=(short) (((short)data[15] << 8) | data[14]);
xp->stick_right_x=(short) (((short)data[17] << 8) | data[16]);
xp->stick_right_y=(short) (((short)data[19] << 8) | data[18]);
xp->trig_left= data[10];
xp->trig_right= data[11];
xp->pad = data[2]&0xf;
xp->state = (data[2]>>4)&0xf;
xp->keys[0] = data[4]; // a
xp->keys[1] = data[5]; // b
xp->keys[2] = data[6]; // x
xp->keys[3] = data[7]; // y
xp->keys[4] = data[8]; // black
xp->keys[5] = data[9]; // white
xp->timestamp=jiffies; // FIXME: A more uniform flowing time would be better...
usb_submit_urb(urb,GFP_ATOMIC);
}
/*------------------------------------------------------------------------*/
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct xpad_info *xpi;
xpi=kmalloc(sizeof(struct xpad_info),GFP_KERNEL);
if (!xpi) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
xpi->urb=urb;
xpi->num=xpad_num;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpi->data, 32, xpad_irq,
xpi, 32);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,xpi);
usbprintk("XPAD #%i connected\n",xpad_num);
#ifdef XPAD_VIBRA_STARTUP
{
// Brum Brum
char data1[6]={0,6,0,120,0,120};
char data2[6]={0,6,0,0,0,0};
int dummy;
usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
data1, 6, &dummy, 500);
wait_ms(500);
usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
data2, 6, &dummy, 500);
}
#endif
xpad_num++;
return 0;
}
/*------------------------------------------------------------------------*/
static void xpad_disconnect(struct usb_interface *intf)
{
struct xpad_info *xpi=usb_get_intfdata (intf);
usb_unlink_urb(xpi->urb);
usb_free_urb(xpi->urb);
kfree(xpi);
xpad_num--;
}
/*------------------------------------------------------------------------*/
static struct usb_device_id xpad_ids [] = {
{ USB_DEVICE(0x044f, 0x0f07) },//Thrustmaster, Inc. Controller
{ USB_DEVICE(0x045e, 0x0202) },//Microsoft Xbox Controller
{ USB_DEVICE(0x045e, 0x0285) },//Microsoft Xbox Controller S
{ USB_DEVICE(0x045e, 0x0289) },//Microsoft Xbox Controller S
{ USB_DEVICE(0x046d, 0xca88) },//Logitech Compact Controller for Xbox
{ USB_DEVICE(0x05fd, 0x1007) },//???Mad Catz Controller???
{ USB_DEVICE(0x05fd, 0x107a) },//InterAct PowerPad Pro
{ USB_DEVICE(0x0738, 0x4516) },//Mad Catz Control Pad
{ USB_DEVICE(0x0738, 0x4522) },//Mad Catz LumiCON
{ USB_DEVICE(0x0738, 0x4526) },//Mad Catz Control Pad Pro
{ USB_DEVICE(0x0738, 0x4536) },//Mad Catz MicroCON
{ USB_DEVICE(0x0738, 0x4556) },//Mad Catz Lynx Wireless Controller
{ USB_DEVICE(0x0c12, 0x9902) },//HAMA VibraX - *FAULTY HARDWARE*
{ USB_DEVICE(0x0e4c, 0x1097) },//Radica Gamester Controller
{ USB_DEVICE(0x0e4c, 0x2390) },//Radica Games Jtech Controller
{ USB_DEVICE(0x0e6f, 0x0003) },//Logic3 Freebird wireless Controller
{ USB_DEVICE(0x0e6f, 0x0005) },//Eclipse wireless Controlle
{ USB_DEVICE(0x0f30, 0x0202) },//Joytech Advanced Controller
{ USB_DEVICE(0xffff, 0xffff) },//Chinese-made Xbox Controller
{ USB_DEVICE(0x0000, 0x0000) }, // nothing detected - FAIL
{ } /* Terminating entry */
};
static struct usb_driver xpad_driver = {
.owner = THIS_MODULE,
.name = "XPAD",
.probe = xpad_probe,
.disconnect = xpad_disconnect,
.id_table = xpad_ids,
};
/*------------------------------------------------------------------------*/
void XPADInit(void)
{
int n;
for(n=0;n<4;n++)
{
memset(&XPAD_current[n], 0, sizeof(struct xpad_data));
memset(&XPAD_last[n], 0, sizeof(struct xpad_data));
}
memset(&xpad_button_history, 0, sizeof(xpad_button_history));
usbprintk("XPAD probe %p ",xpad_probe);
if (usb_register(&xpad_driver) < 0) {
err("Unable to register XPAD driver");
return;
}
}
/*------------------------------------------------------------------------*/
void XPADRemove(void) {
usb_deregister(&xpad_driver);
}
/*------------------------------------------------------------------------*/
/*
* Simple XPAD driver for XBOX
*
* (c) 2003-07-04, Georg Acher (georg@acher.org)
*
* Inspired by linux/drivers/usb/input/xpad.c
* by Marko Friedemann <mfr@bmx-chemnitz.de>
*
*/
#include "../usb_wrapper.h"
#include "config.h"
// history for the Rising - falling events
unsigned char xpad_button_history[7];
/* Stores time and XPAD state */
struct xpad_data XPAD_current[4];
struct xpad_data XPAD_last[4];
struct xpad_info
{
struct urb *urb;
int num;
unsigned char data[32];
};
int xpad_num=0;
/*------------------------------------------------------------------------*/
static void xpad_irq(struct urb *urb, struct pt_regs *regs)
{
struct xpad_info *xpi = urb->context;
unsigned char* data= urb->transfer_buffer;
// struct xpad_data *xp=&XPAD_current[xpi->num];
// struct xpad_data *xpo=&XPAD_last[xpi->num];
/* This hack means the xpad event always gets posted to the
* first xpad - avoids problems iterating over multiple xpads
* as the xpi->num entries are not reused when xpads are
* connected, then removed */
struct xpad_data *xp=&XPAD_current[0];
struct xpad_data *xpo=&XPAD_last[0];
if (xpi->num<0 || xpi->num>3)
return;
memcpy(xpo,xp,sizeof(struct xpad_data));
xp->stick_left_x=(short) (((short)data[13] << 8) | data[12]);
xp->stick_left_y=(short) (((short)data[15] << 8) | data[14]);
xp->stick_right_x=(short) (((short)data[17] << 8) | data[16]);
xp->stick_right_y=(short) (((short)data[19] << 8) | data[18]);
xp->trig_left= data[10];
xp->trig_right= data[11];
xp->pad = data[2]&0xf;
xp->state = (data[2]>>4)&0xf;
xp->keys[0] = data[4]; // a
xp->keys[1] = data[5]; // b
xp->keys[2] = data[6]; // x
xp->keys[3] = data[7]; // y
xp->keys[4] = data[8]; // black
xp->keys[5] = data[9]; // white
xp->timestamp=jiffies; // FIXME: A more uniform flowing time would be better...
usb_submit_urb(urb,GFP_ATOMIC);
}
/*------------------------------------------------------------------------*/
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct xpad_info *xpi;
xpi=kmalloc(sizeof(struct xpad_info),GFP_KERNEL);
if (!xpi) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
xpi->urb=urb;
xpi->num=xpad_num;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpi->data, 32, xpad_irq,
xpi, 32);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,xpi);
usbprintk("XPAD #%i connected\n",xpad_num);
#ifdef XPAD_VIBRA_STARTUP
{
// Brum Brum
char data1[6]={0,6,0,120,0,120};
char data2[6]={0,6,0,0,0,0};
int dummy;
usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
data1, 6, &dummy, 500);
wait_ms(500);
usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
data2, 6, &dummy, 500);
}
#endif
xpad_num++;
return 0;
}
/*------------------------------------------------------------------------*/
static void xpad_disconnect(struct usb_interface *intf)
{
struct xpad_info *xpi=usb_get_intfdata (intf);
usb_unlink_urb(xpi->urb);
usb_free_urb(xpi->urb);
kfree(xpi);
xpad_num--;
}
/*------------------------------------------------------------------------*/
static struct usb_device_id xpad_ids [] = {
{ USB_DEVICE(0x044f, 0x0f07) },//Thrustmaster, Inc. Controller
{ USB_DEVICE(0x045e, 0x0202) },//Microsoft Xbox Controller
{ USB_DEVICE(0x045e, 0x0285) },//Microsoft Xbox Controller S
{ USB_DEVICE(0x045e, 0x0289) },//Microsoft Xbox Controller S
{ USB_DEVICE(0x046d, 0xca88) },//Logitech Compact Controller for Xbox
{ USB_DEVICE(0x05fd, 0x1007) },//???Mad Catz Controller???
{ USB_DEVICE(0x05fd, 0x107a) },//InterAct PowerPad Pro
{ USB_DEVICE(0x0738, 0x4516) },//Mad Catz Control Pad
{ USB_DEVICE(0x0738, 0x4522) },//Mad Catz LumiCON
{ USB_DEVICE(0x0738, 0x4526) },//Mad Catz Control Pad Pro
{ USB_DEVICE(0x0738, 0x4536) },//Mad Catz MicroCON
{ USB_DEVICE(0x0738, 0x4556) },//Mad Catz Lynx Wireless Controller
{ USB_DEVICE(0x0c12, 0x9902) },//HAMA VibraX - *FAULTY HARDWARE*
{ USB_DEVICE(0x0e4c, 0x1097) },//Radica Gamester Controller
{ USB_DEVICE(0x0e4c, 0x2390) },//Radica Games Jtech Controller
{ USB_DEVICE(0x0e6f, 0x0003) },//Logic3 Freebird wireless Controller
{ USB_DEVICE(0x0e6f, 0x0005) },//Eclipse wireless Controlle
{ USB_DEVICE(0x0f30, 0x0202) },//Joytech Advanced Controller
{ USB_DEVICE(0xffff, 0xffff) },//Chinese-made Xbox Controller
{ USB_DEVICE(0x0000, 0x0000) }, // nothing detected - FAIL
{ } /* Terminating entry */
};
static struct usb_driver xpad_driver = {
.owner = THIS_MODULE,
.name = "XPAD",
.probe = xpad_probe,
.disconnect = xpad_disconnect,
.id_table = xpad_ids,
};
/*------------------------------------------------------------------------*/
void XPADInit(void)
{
int n;
for(n=0;n<4;n++)
{
memset(&XPAD_current[n], 0, sizeof(struct xpad_data));
memset(&XPAD_last[n], 0, sizeof(struct xpad_data));
}
memset(&xpad_button_history, 0, sizeof(xpad_button_history));
usbprintk("XPAD probe %p ",xpad_probe);
if (usb_register(&xpad_driver) < 0) {
err("Unable to register XPAD driver");
return;
}
}
/*------------------------------------------------------------------------*/
void XPADRemove(void) {
usb_deregister(&xpad_driver);
}
/*------------------------------------------------------------------------*/

View file

@ -1,142 +1,142 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* $Id: xremote.c,v 1.5 2004/11/22 19:10:57 davidmpye Exp $
*
* Copyright (c) 2002 Steven Toth <steve@toth.demon.co.uk>
*
* XBOX DVD dongle infrared device driver for the input driver suite.
*
* This work was derived from the usbkbd.c kernel module.
*
* History:
*
* 2002_08_31 - 0.1 - Initial release
* 2002_09_02 - 0.2 - Added IOCTL support enabling user space administration
* of the translation matrix.
*
*/
#include "../usb_wrapper.h"
u16 current_remote_key;
u8 remotekeyIsRepeat;
struct xremote_info
{
struct urb *urb;
unsigned char irpkt[8];
};
/* USB callback completion handler
* Code in transfer_buffer is received as six unsigned chars
* Example PLAY=00 06 ea 0a 40 00
* The command is located in byte[2], the rest are ignored.
* Key position is byte[4] bit0 (7-0 format) 0=down, 1=up
* All other bits are unknown / now required.
*/
static void xremote_irq(struct urb *urb, struct pt_regs *regs)
{
struct xremote_info *xri = urb->context;
if (urb->status) return;
if (urb->actual_length < 6) return;
/* Messy/unnecessary, fix this */
memcpy(xri->irpkt, urb->transfer_buffer, 6);
/* Set the key action based in the sent action */
current_remote_key = ((xri->irpkt[2] & 0xff)<<8) | (xri->irpkt[3] & 0xff);
if (((xri->irpkt[4] & 0xff) + ((xri->irpkt[5] & 0xff ) << 8))>0x41) {
remotekeyIsRepeat=0;
}
else remotekeyIsRepeat=1;
usb_submit_urb(urb,GFP_ATOMIC);
}
static int xremote_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct xremote_info *xri;
xri=(struct xremote_info *)kmalloc(sizeof(struct xremote_info),0);
if (!xri) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
xri->urb=urb;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xri->irpkt, 8, xremote_irq,
xri, 8);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,xri);
usbprintk("DVD Remote connected\n");
return 0;
}
static void xremote_disconnect(struct usb_interface *intf)
{
struct xremote_info *xri = usb_get_intfdata (intf);
usbprintk("DVD Remote disconnected\n ");
usb_unlink_urb(xri->urb);
usb_free_urb(xri->urb);
kfree(xri);
}
static struct usb_device_id xremote_id_table [] = {
{ USB_DEVICE(0x040b, 0x6521) }, /* Gamester Xbox DVD Movie Playback Kit IR */
{ USB_DEVICE(0x045e, 0x0284) }, /* Microsoft Xbox DVD Movie Playback Kit IR */
{ USB_DEVICE(0x0000, 0x0000) }, // nothing detected - FAIL
{ } /* Terminating entry */
};
static struct usb_driver xremote_driver = {
.owner = THIS_MODULE,
.name = "XRemote",
.probe = xremote_probe,
.disconnect = xremote_disconnect,
.id_table = xremote_id_table,
};
void XRemoteInit(void)
{
current_remote_key=0;
usbprintk("XRemote probe %p ",xremote_probe);
if (usb_register(&xremote_driver) < 0) {
err("Unable to register XRemote driver");
return;
}
}
void XRemoteRemove(void) {
usb_deregister(&xremote_driver);
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* $Id$
*
* Copyright (c) 2002 Steven Toth <steve@toth.demon.co.uk>
*
* XBOX DVD dongle infrared device driver for the input driver suite.
*
* This work was derived from the usbkbd.c kernel module.
*
* History:
*
* 2002_08_31 - 0.1 - Initial release
* 2002_09_02 - 0.2 - Added IOCTL support enabling user space administration
* of the translation matrix.
*
*/
#include "../usb_wrapper.h"
u16 current_remote_key;
u8 remotekeyIsRepeat;
struct xremote_info
{
struct urb *urb;
unsigned char irpkt[8];
};
/* USB callback completion handler
* Code in transfer_buffer is received as six unsigned chars
* Example PLAY=00 06 ea 0a 40 00
* The command is located in byte[2], the rest are ignored.
* Key position is byte[4] bit0 (7-0 format) 0=down, 1=up
* All other bits are unknown / now required.
*/
static void xremote_irq(struct urb *urb, struct pt_regs *regs)
{
struct xremote_info *xri = urb->context;
if (urb->status) return;
if (urb->actual_length < 6) return;
/* Messy/unnecessary, fix this */
memcpy(xri->irpkt, urb->transfer_buffer, 6);
/* Set the key action based in the sent action */
current_remote_key = ((xri->irpkt[2] & 0xff)<<8) | (xri->irpkt[3] & 0xff);
if (((xri->irpkt[4] & 0xff) + ((xri->irpkt[5] & 0xff ) << 8))>0x41) {
remotekeyIsRepeat=0;
}
else remotekeyIsRepeat=1;
usb_submit_urb(urb,GFP_ATOMIC);
}
static int xremote_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct xremote_info *xri;
xri=(struct xremote_info *)kmalloc(sizeof(struct xremote_info),0);
if (!xri) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
xri->urb=urb;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xri->irpkt, 8, xremote_irq,
xri, 8);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,xri);
usbprintk("DVD Remote connected\n");
return 0;
}
static void xremote_disconnect(struct usb_interface *intf)
{
struct xremote_info *xri = usb_get_intfdata (intf);
usbprintk("DVD Remote disconnected\n ");
usb_unlink_urb(xri->urb);
usb_free_urb(xri->urb);
kfree(xri);
}
static struct usb_device_id xremote_id_table [] = {
{ USB_DEVICE(0x040b, 0x6521) }, /* Gamester Xbox DVD Movie Playback Kit IR */
{ USB_DEVICE(0x045e, 0x0284) }, /* Microsoft Xbox DVD Movie Playback Kit IR */
{ USB_DEVICE(0x0000, 0x0000) }, // nothing detected - FAIL
{ } /* Terminating entry */
};
static struct usb_driver xremote_driver = {
.owner = THIS_MODULE,
.name = "XRemote",
.probe = xremote_probe,
.disconnect = xremote_disconnect,
.id_table = xremote_id_table,
};
void XRemoteInit(void)
{
current_remote_key=0;
usbprintk("XRemote probe %p ",xremote_probe);
if (usb_register(&xremote_driver) < 0) {
err("Unable to register XRemote driver");
return;
}
}
void XRemoteRemove(void) {
usb_deregister(&xremote_driver);
}

View file

@ -1,16 +1,16 @@
PATH_TO_TOP = ../../../..
TARGET_TYPE = export_driver
TARGET_NAME = uhci
TARGET_DDKLIBS = ntoskrnl.a usbcore.a
TARGET_CFLAGS = -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -DDEBUG_MODE
TARGET_OBJECTS = \
uhci-hcd.o uhci_main.o ../sys/ros_wrapper.o ../sys/linuxwrapper.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
PATH_TO_TOP = ../../../..
TARGET_TYPE = export_driver
TARGET_NAME = uhci
TARGET_DDKLIBS = ntoskrnl.a usbcore.a
TARGET_CFLAGS = -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -DDEBUG_MODE
TARGET_OBJECTS = \
uhci-hcd.o uhci_main.o ../sys/ros_wrapper.o ../sys/linuxwrapper.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk

View file

@ -42,11 +42,15 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#endif
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#if 0
#include <linux/usb.h>
#include <asm/uaccess.h>
@ -79,9 +83,9 @@
* debug = 3, show all TD's in URB's when dumping
*/
#ifdef DEBUG
static int debug = 1;
static int debug = 3;
#else
static int debug = 0;
static int debug = 2;
#endif
MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "Debug level");
@ -1873,7 +1877,7 @@ static void uhci_remove_pending_qhs(struct uhci_hcd *uhci)
spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
}
static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
static int uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
unsigned int io_addr = uhci->io_addr;
@ -1886,7 +1890,7 @@ static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
*/
status = inw(io_addr + USBSTS);
if (!status) /* shared interrupt, not mine */
return;
return 0;
outw(status, io_addr + USBSTS); /* Clear it */
if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
@ -1925,6 +1929,8 @@ static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
spin_unlock(&uhci->urb_list_lock);
uhci_finish_completion(hcd, regs);
return 0;
}
static void reset_hc(struct uhci_hcd *uhci)
@ -2271,6 +2277,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
err("unable to allocate root hub");
goto err_alloc_root_hub;
}
hcd->pdev->bus = (struct pci_bus *)udev; /* Fix bus pointer for initial device */
uhci->term_td = uhci_alloc_td(uhci, udev);
if (!uhci->term_td) {
@ -2484,7 +2491,7 @@ static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
static const char hcd_name[] = "uhci-hcd";
static const struct hc_driver uhci_driver = {
static struct hc_driver uhci_driver = {
.description = hcd_name,
/* Generic hardware linkage */

View file

@ -1,2 +1,2 @@
LIBRARY uhci.sys
EXPORTS
LIBRARY uhci.sys
EXPORTS

View file

@ -1,5 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB UHCI Device Driver\0"
#define REACTOS_STR_INTERNAL_NAME "uhci\0"
#define REACTOS_STR_ORIGINAL_FILENAME "uhci.sys\0"
#include <reactos/version.rc>
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB UHCI Device Driver\0"
#define REACTOS_STR_INTERNAL_NAME "uhci\0"
#define REACTOS_STR_ORIGINAL_FILENAME "uhci.sys\0"
#include <reactos/version.rc>

View file

@ -1,5 +1,5 @@
/*
* Configs for UHCI
*/
#define CONFIG_PCI
/*
* Configs for UHCI
*/
#define CONFIG_PCI

View file

@ -1,309 +1,337 @@
/*
ReactOS specific functions for UHCI module
by Aleksey Bragin (aleksey@reactos.com)
Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
*/
#include <ddk/ntddk.h>
#include <debug.h>
#include "../linux/linux_wrapper.h"
#include "../host/ohci_main.h"
// declare basic init funcs
void init_wrapper(struct pci_dev *probe_dev);
int uhci_hcd_init(void);
void uhci_hcd_cleanup(void);
int STDCALL usb_init(void);
void STDCALL usb_exit(void);
extern struct pci_driver uhci_pci_driver;
extern const struct pci_device_id uhci_pci_ids[];
// This should be removed, but for testing purposes it's here
struct pci_dev *dev;
//struct pci_device_id *dev_id;
#define USB_UHCI_TAG TAG('u','s','b','u')
NTSTATUS STDCALL AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
PDEVICE_OBJECT fdo;
NTSTATUS Status;
WCHAR DeviceBuffer[20];
UNICODE_STRING DeviceName;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
ULONG Size, DeviceNumber;
DPRINT1("uhci: AddDevice called\n");
// Allocate driver extension now
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
if (DriverExtension == NULL)
{
Status = IoAllocateDriverObjectExtension(
DriverObject,
DriverObject,
sizeof(OHCI_DRIVER_EXTENSION),
(PVOID *)&DriverExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("Allocating DriverObjectExtension failed.\n");
return Status;
}
}
// Create a unicode device name
DeviceNumber = 0; //TODO: Allocate new device number every time
swprintf(DeviceBuffer, L"\\Device\\USBFDO-%lu", DeviceNumber);
RtlInitUnicodeString(&DeviceName, DeviceBuffer);
Status = IoCreateDevice(DriverObject,
sizeof(OHCI_DEVICE_EXTENSION)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
&DeviceName,
FILE_DEVICE_CONTROLLER,
0,
FALSE,
&fdo);
if (!NT_SUCCESS(Status))
{
DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
return Status;
}
// zerofill device extension
DeviceExtension = (POHCI_DEVICE_EXTENSION)pdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
// Initialize device extension
DeviceExtension->DeviceNumber = DeviceNumber;
DeviceExtension->PhysicalDeviceObject = pdo;
DeviceExtension->FunctionalDeviceObject = fdo;
DeviceExtension->DriverExtension = DriverExtension;
/* Get bus number from the upper level bus driver. */
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(
pdo,
DevicePropertyBusNumber,
Size,
&DeviceExtension->SystemIoBusNumber,
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
return Status;
}
DPRINT("Done AddDevice\n");
return STATUS_SUCCESS;
}
VOID STDCALL DriverUnload(PDRIVER_OBJECT DriverObject)
{
DPRINT1("DriverUnload()\n");
// Exit usb device
usb_exit();
// Remove device (ohci_pci_driver.remove)
uhci_pci_driver.remove(dev);
ExFreePool(dev->slot_name);
ExFreePool(dev);
// Perform some cleanup
uhci_hcd_cleanup();
}
NTSTATUS InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Fill generic linux structs
dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_UHCI_TAG);
init_wrapper(dev);
dev->irq = DeviceExtension->InterruptLevel;
dev->dev_ext = (PVOID)DeviceExtension;
dev->slot_name = ExAllocatePoolWithTag(NonPagedPool, 128, USB_UHCI_TAG); // 128 max len for slot name
strcpy(dev->dev.name, "UnivHCI PCI-USB Controller");
strcpy(dev->slot_name, "UHCD PCI Slot");
// Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL
Status = uhci_hcd_init();
//FIXME: Check status returned value
// Init core usb
usb_init();
// Probe device with real id now
uhci_pci_driver.probe(dev, uhci_pci_ids);
DPRINT("InitLinuxWrapper() done\n");
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PDRIVER_OBJECT DriverObject;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
/*
* Get the initialization data we saved in VideoPortInitialize.
*/
DriverObject = DeviceObject->DriverObject;
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/*
* Store some resources in the DeviceExtension.
*/
AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
if (AllocatedResources != NULL)
{
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
ULONG ResourceCount;
ULONG ResourceListSize;
/* Save the resource list */
ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
ResourceListSize =
FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
PartialDescriptors[ResourceCount]);
DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
if (DeviceExtension->AllocatedResources == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(DeviceExtension->AllocatedResources,
AllocatedResources,
ResourceListSize);
/* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
for (FullList = AllocatedResources->List;
FullList < AllocatedResources->List + AllocatedResources->Count;
FullList++)
{
/* FIXME: Is this ASSERT ok for resources from the PNP manager? */
/*ASSERT(FullList->InterfaceType == PCIBus &&
FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
1 == FullList->PartialResourceList.Version &&
1 == FullList->PartialResourceList.Revision);*/
for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
Descriptor++)
{
if (Descriptor->Type == CmResourceTypeInterrupt)
{
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
}
else if (Descriptor->Type == CmResourceTypeMemory)
{
DeviceExtension->BaseAddress = Descriptor->u.Memory.Start;
DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
}
}
}
}
DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
DeviceExtension->InterruptLevel,
DeviceExtension->InterruptVector);
/*
* Init wrapper with this object
*/
return InitLinuxWrapper(DeviceObject);
}
// Dispatch PNP
NTSTATUS STDCALL DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = OHCD_PnPStartDevice(DeviceObject, Irp);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_STOP_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoDeleteDevice(DeviceObject); // just delete device for now
break;
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
default:
return STATUS_NOT_IMPLEMENTED;
break;
}
return Status;
}
NTSTATUS STDCALL DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DbgPrint("IRP_MJ_POWER dispatch\n");
return STATUS_SUCCESS;
}
/*
* Standard DriverEntry method.
*/
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}
/*
ReactOS specific functions for UHCI module
by Aleksey Bragin (aleksey@reactos.com)
Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
*/
#include <ddk/ntddk.h>
#include <debug.h>
// config and include core/hcd.h, for hc_device struct
#include "../usb_wrapper.h"
#include "../core/hcd.h"
#include "../host/ohci_main.h"
// declare basic init funcs
void init_wrapper(struct pci_dev *probe_dev);
int uhci_hcd_init(void);
void uhci_hcd_cleanup(void);
int STDCALL usb_init(void);
void STDCALL usb_exit(void);
extern struct pci_driver uhci_pci_driver;
extern struct pci_device_id uhci_pci_ids[];
// This should be removed, but for testing purposes it's here
struct pci_dev *dev;
//struct pci_device_id *dev_id;
#define USB_UHCI_TAG TAG('u','s','b','u')
NTSTATUS STDCALL AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
PDEVICE_OBJECT fdo;
NTSTATUS Status;
WCHAR DeviceBuffer[20];
UNICODE_STRING DeviceName;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
ULONG Size, DeviceNumber;
DPRINT1("uhci: AddDevice called\n");
// Allocate driver extension now
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
if (DriverExtension == NULL)
{
Status = IoAllocateDriverObjectExtension(
DriverObject,
DriverObject,
sizeof(OHCI_DRIVER_EXTENSION),
(PVOID *)&DriverExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("Allocating DriverObjectExtension failed.\n");
return Status;
}
}
// Create a unicode device name
DeviceNumber = 0; //TODO: Allocate new device number every time
swprintf(DeviceBuffer, L"\\Device\\USBFDO-%lu", DeviceNumber);
RtlInitUnicodeString(&DeviceName, DeviceBuffer);
Status = IoCreateDevice(DriverObject,
sizeof(OHCI_DEVICE_EXTENSION)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
&DeviceName,
FILE_DEVICE_CONTROLLER,
0,
FALSE,
&fdo);
if (!NT_SUCCESS(Status))
{
DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
return Status;
}
// zerofill device extension
DeviceExtension = (POHCI_DEVICE_EXTENSION)pdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
// Initialize device extension
DeviceExtension->DeviceNumber = DeviceNumber;
DeviceExtension->PhysicalDeviceObject = pdo;
DeviceExtension->FunctionalDeviceObject = fdo;
DeviceExtension->DriverExtension = DriverExtension;
/* Get bus number from the upper level bus driver. */
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(
pdo,
DevicePropertyBusNumber,
Size,
&DeviceExtension->SystemIoBusNumber,
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
return Status;
}
DPRINT("Done AddDevice\n");
return STATUS_SUCCESS;
}
VOID STDCALL DriverUnload(PDRIVER_OBJECT DriverObject)
{
DPRINT1("DriverUnload()\n");
// Exit usb device
usb_exit();
// Remove device (ohci_pci_driver.remove)
uhci_pci_driver.remove(dev);
ExFreePool(dev->slot_name);
ExFreePool(dev);
// Perform some cleanup
uhci_hcd_cleanup();
}
NTSTATUS InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Fill generic linux structs
dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_UHCI_TAG);
init_wrapper(dev);
dev->irq = DeviceExtension->InterruptVector;
dev->dev_ext = (PVOID)DeviceExtension;
dev->slot_name = ExAllocatePoolWithTag(NonPagedPool, 128, USB_UHCI_TAG); // 128 max len for slot name
strcpy(dev->dev.name, "UnivHCI PCI-USB Controller");
strcpy(dev->slot_name, "UHCD PCI Slot");
// Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL
Status = uhci_hcd_init();
//FIXME: Check status returned value
// Init core usb
usb_init();
// Probe device with real id now
uhci_pci_driver.probe(dev, uhci_pci_ids);
DPRINT("InitLinuxWrapper() done\n");
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PDRIVER_OBJECT DriverObject;
POHCI_DRIVER_EXTENSION DriverExtension;
POHCI_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
/*
* Get the initialization data we saved in VideoPortInitialize.
*/
DriverObject = DeviceObject->DriverObject;
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/*
* Store some resources in the DeviceExtension.
*/
AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
if (AllocatedResources != NULL)
{
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
ULONG ResourceCount;
ULONG ResourceListSize;
/* Save the resource list */
ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
ResourceListSize =
FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
PartialDescriptors[ResourceCount]);
DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
if (DeviceExtension->AllocatedResources == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(DeviceExtension->AllocatedResources,
AllocatedResources,
ResourceListSize);
/* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
for (FullList = AllocatedResources->List;
FullList < AllocatedResources->List + AllocatedResources->Count;
FullList++)
{
/* FIXME: Is this ASSERT ok for resources from the PNP manager? */
/*ASSERT(FullList->InterfaceType == PCIBus &&
FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
1 == FullList->PartialResourceList.Version &&
1 == FullList->PartialResourceList.Revision);*/
DPRINT1("AllocRess->Count: %d, PartResList.Count: %d\n",
AllocatedResources->Count, FullList->PartialResourceList.Count);
for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
Descriptor++)
{
if (Descriptor->Type == CmResourceTypeInterrupt)
{
DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
DeviceExtension->InterruptLevel,
DeviceExtension->InterruptVector);
}
else if (Descriptor->Type == CmResourceTypePort)
{
DeviceExtension->BaseAddress = Descriptor->u.Port.Start;
DeviceExtension->BaseAddrLength = Descriptor->u.Port.Length;
DeviceExtension->Flags = Descriptor->Flags;
((struct hc_driver *)uhci_pci_ids->driver_data)->flags &= ~HCD_MEMORY;
DPRINT1("I/O resource: start=0x%x, length=0x%x\n",
DeviceExtension->BaseAddress.u.LowPart, DeviceExtension->BaseAddrLength);
}
else if (Descriptor->Type == CmResourceTypeMemory)
{
DeviceExtension->BaseAddress = Descriptor->u.Memory.Start;
DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
DeviceExtension->Flags = Descriptor->Flags;
((struct hc_driver *)uhci_pci_ids->driver_data)->flags |= HCD_MEMORY;
DPRINT1("Memory resource: start=0x%x, length=0x%x\n",
DeviceExtension->BaseAddress.u.LowPart, DeviceExtension->BaseAddrLength);
}
else
DPRINT1("Get resource type: %d, Generic start=0x%x Generic length=0x%x\n",
Descriptor->Type, Descriptor->u.Generic.Start.u.LowPart, Descriptor->u.Generic.Length);
}
}
}
/*
* Init wrapper with this object
*/
return InitLinuxWrapper(DeviceObject);
}
// Dispatch PNP
NTSTATUS STDCALL DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = OHCD_PnPStartDevice(DeviceObject, Irp);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_STOP_DEVICE:
//Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoDeleteDevice(DeviceObject); // just delete device for now
break;
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
default:
return STATUS_NOT_IMPLEMENTED;
break;
}
return Status;
}
NTSTATUS STDCALL DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DbgPrint("IRP_MJ_POWER dispatch\n");
return STATUS_SUCCESS;
}
/*
* Standard DriverEntry method.
*/
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
return STATUS_SUCCESS;
}

View file

@ -1,15 +1,16 @@
//#include <stdlib.h>
//#include <ntos/types.h>
//#include <ddk/extypes.h>
#include <ddk/ntddk.h>
#include <debug.h>
void wait_ms(int mils);
#include "linux/linux_wrapper.h"
#define __KERNEL__
#undef CONFIG_PCI
#define CONFIG_PCI
#include "linux/usb.h"
#include "linux/pci_ids.h"
//#include <stdlib.h>
//#include <ntos/types.h>
//#include <ddk/extypes.h>
#include <ddk/ntddk.h>
#include <debug.h>
void wait_ms(int mils);
#include "linux/linux_wrapper.h"
#define __KERNEL__
#undef CONFIG_PCI
#define CONFIG_PCI
#include "linux/usb.h"
#include "linux/pci_ids.h"

View file

@ -158,7 +158,6 @@ IntInitScreenInfo(
ModeInfoPtr = ModeInfo;
while (ModeCount-- > 0)
{
if (ModeInfoPtr->Length > 0 &&
pDevMode->dmPelsWidth == ModeInfoPtr->VisScreenWidth &&
pDevMode->dmPelsHeight == ModeInfoPtr->VisScreenHeight &&
@ -170,7 +169,8 @@ IntInitScreenInfo(
break;
}
ModeInfoPtr++;
ModeInfoPtr = (PVIDEO_MODE_INFORMATION)
(((PUCHAR)ModeInfoPtr) + ModeInfoSize);
}
}
@ -383,6 +383,7 @@ DrvGetModes(
{
if (ModeInfoPtr->Length == 0)
{
ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize);
continue;
}

View file

@ -885,6 +885,14 @@ VBEQueryMode(
VideoMode->YMillimeter = 0; /* FIXME */
if (VBEMode->BitsPerPixel > 8)
{
/*
* Always report 16bpp modes and not 15bpp mode...
*/
if (VBEMode->BitsPerPixel == 15 && VBEMode->NumberOfPlanes == 1)
{
VideoMode->BitsPerPlane = 16;
}
if (DeviceExtension->VbeInfo.Version < 0x300)
{
VideoMode->NumberRedBits = VBEMode->RedMaskSize;

View file

@ -32,7 +32,7 @@
#include <ddk/ntapi.h>
#ifdef DBG
#define DPRINT(arg) DbgPrint arg;
#define DPRINT(arg) DbgPrint(arg)
#else
#define DPRINT(arg)
#endif

View file

@ -16,7 +16,7 @@
#include <apic.h>
#include <ioapic.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
@ -58,7 +58,7 @@ HaliMPIntSrcInfo(PMP_CONFIGURATION_INTSRC m)
IRQCount++;
}
static PCHAR
PCHAR
HaliMPFamily(ULONG Family,
ULONG Model)
{
@ -275,9 +275,9 @@ HaliReadMPConfigTable(PMP_CONFIGURATION_TABLE Table)
{
PUCHAR pc = (PUCHAR)&Table->Signature;
DPRINT1("Bad MP configuration block signature: %c%c%c%c\n",
DPRINT1("Bad MP configuration block signature: %c%c%c%c\n",
pc[0], pc[1], pc[2], pc[3]);
KEBUGCHECK(0);
KEBUGCHECKEX(0, pc[0], pc[1], pc[2], pc[3]);
return FALSE;
}

View file

@ -63,6 +63,43 @@ typedef NTSTATUS STDCALL_FUNC
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength);
typedef struct _OBJECT_HANDLE_COUNT_ENTRY
{
struct _EPROCESS *Process;
ULONG HandleCount;
} OBJECT_HANDLE_COUNT_ENTRY, *POBJECT_HANDLE_COUNT_ENTRY;
typedef struct _OBJECT_HANDLE_COUNT_DATABASE
{
ULONG CountEntries;
POBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1];
} OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE;
typedef struct _OBJECT_HEADER_HANDLE_INFO
{
union {
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase;
OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
};
} OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
typedef struct _OBJECT_HEADER_CREATOR_INFO
{
LIST_ENTRY TypeList;
PVOID CreatorUniqueProcess;
USHORT CreatorBackTraceIndex;
USHORT Reserved;
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
typedef struct _OBJECT_HEADER_NAME_INFO
{
struct _DIRECTORY_OBJECT *Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
ULONG Reserved2;
ULONG DbgReferenceCount;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;

View file

@ -48,11 +48,19 @@
#endif
#endif
/* TODO: Make the output of file/line and the debug message atomic */
#ifdef DBG
#define DPRINT1 DbgPrint("(%s:%d) ",__FILE__,__LINE__), DbgPrint
#define CHECKPOINT1 do { DbgPrint("%s:%d\n",__FILE__,__LINE__); } while(0);
#else
#ifdef __GNUC__
#define DPRINT1(args...)
#define CHECKPOINT1
#else
#define DPRINT1
#define CHECKPOINT1
#endif /* __GNUC__ */
#endif
#ifndef NDEBUG
#define DPRINT(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0);

Some files were not shown because too many files have changed in this diff Show more