pciScan.c
资源名称:pciexp.zip [点击查看]
上传用户:zhuqijet
上传日期:2007-01-04
资源大小:138k
文件大小:18k
源码类别:
驱动编程
开发平台:
Visual C++
- // pclUtil.c driver utilities for PCI bus adapters
- /*****************************************************************************
- * Change Log
- * Date | Change
- *-----------+-----------------------------------------------------------------
- 09-13-96 create log
- *****************************************************************************/
- /*****************************************************************************
- * To DO
- *-----------------------------------------------------------------------------
- *****************************************************************************/
- #define NT_DEVICE_NAME L"\Device\PCISCAN"
- #define DOS_DEVICE_NAME L"\DosDevices\PCISCAN"
- #define BYTE UCHAR
- /*++
- Module Name:
- pclUtil.c
- Abstract:
- Windows NT device driver utilities for PCI bus adapters.
- Author:
- Edward Dekker
- Environment:
- kernel mode only
- Notes:
- --*/
- #include "ntddk.h"
- //#include "pciScan.h" // include device extension for target driver here
- #include "pciScanIoctl.h" // include device extension for target driver here
- typedef struct _PCISCAN_DEVICE_EXTENSION
- {
- PDEVICE_OBJECT DeviceObject;
- PCI_SLOT_NUMBER returnSlotData;
- PCI_COMMON_CONFIG returnPciData;
- unsigned int returnBusNumber;
- } PCISCAN_DEVICE_EXTENSION;
- typedef PCISCAN_DEVICE_EXTENSION *PPCISCAN_DEVICE_EXTENSION;
- NTSTATUS pciScanOpen(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp );
- NTSTATUS pciScanClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp );
- VOID pciScanUnload( IN PDRIVER_OBJECT DriverObject);
- NTSTATUS pciScanDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp );
- void dumpPciConfig( PCI_COMMON_CONFIG pciData)
- {
- // dump our PCI_COMMON_CONFIG record here
- KdPrint( ("pciScan: pciData.VendorID = %xn", pciData.VendorID ) );
- KdPrint( ("pciScan: pciData.DeviceID = %xn", pciData.DeviceID ) );
- KdPrint( ("pciScan: pciData.Command = %xn", pciData.Command ) );
- KdPrint( ("pciScan: pciData.Status = %xn", pciData.Status ) );
- KdPrint( ("pciScan: pciData.RevisionID = %xn", pciData.RevisionID ) );
- KdPrint( ("pciScan: pciData.ProgIf = %xn", pciData.ProgIf ) );
- KdPrint( ("pciScan: pciData.SubClass = %xn", pciData.SubClass ) );
- KdPrint( ("pciScan: pciData.BaseClass = %xn", pciData.BaseClass ) );
- KdPrint( ("pciScan: pciData.CacheLineSize= %xn", pciData.CacheLineSize ) );
- KdPrint( ("pciScan: pciData.LatencyTimer = %xn", pciData.LatencyTimer ) );
- KdPrint( ("pciScan: pciData.HeaderType = %xn", pciData.HeaderType ) );
- KdPrint( ("pciScan: pciData.BIST = %xn", pciData.BIST ) );
- KdPrint( ("pciScan: pciData.u.type0.BaseAddresses[0] = %xn", pciData.u.type0.BaseAddresses[0] ) );
- KdPrint( ("pciScan: pciData.u.type0.BaseAddresses[1] = %xn", pciData.u.type0.BaseAddresses[1] ) );
- KdPrint( ("pciScan: pciData.u.type0.BaseAddresses[2] = %xn", pciData.u.type0.BaseAddresses[2] ) );
- KdPrint( ("pciScan: pciData.u.type0.ROMBaseAddress = %xn", pciData.u.type0.ROMBaseAddress ) );
- KdPrint( ("pciScan: pciData.u.type0.InterruptLine = %xn", pciData.u.type0.InterruptLine ) );
- KdPrint( ("pciScan: pciData.u.type0.InterruptPin = %xn", pciData.u.type0.InterruptPin ) );
- KdPrint( ("pciScan: pciData.u.type0.MinimumGrant = %xn", pciData.u.type0.MinimumGrant ) );
- KdPrint( ("pciScan: pciData.u.type0.MaximumLatency = %xn", pciData.u.type0.MaximumLatency ) );
- }
- /****************************************************************************
- Function:
- DriverEntry
- Arguments:
- Description:
- Returns:
- *****************************************************************************/
- NTSTATUS DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath )
- {
- PDEVICE_OBJECT deviceObject = NULL;
- NTSTATUS status;
- UNICODE_STRING uniNtNameString;
- UNICODE_STRING uniWin32NameString;
- PPCISCAN_DEVICE_EXTENSION extension;
- BOOLEAN GotResources;
- ULONG ret = 0;
- KdPrint( ("pciScan: Entered the pciScan driver!n") );
- //
- // Create counted string version of our device name.
- //
- RtlInitUnicodeString( &uniNtNameString, NT_DEVICE_NAME );
- //
- // Create the device object
- //
- status = IoCreateDevice(
- DriverObject,
- sizeof(PCISCAN_DEVICE_EXTENSION),
- &uniNtNameString,
- FILE_DEVICE_UNKNOWN,
- 0, // No standard device characteristics
- FALSE, // This isn't an exclusive device
- &deviceObject
- );
- if ( NT_SUCCESS(status) )
- {
- //
- // Create dispatch points for create/open, close, unload.
- //
- KdPrint( ("pciScan: IoCreateDevice successn") );
- DriverObject->MajorFunction[IRP_MJ_CREATE] = pciScanOpen;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = pciScanClose;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = pciScanDeviceControl;
- DriverObject->DriverUnload = pciScanUnload;
- KdPrint( ("pciScan: just about ready!n") );
- //
- // Do direct I/O. I.e., the I/O system will provide pointers to/from user data
- // from/to the user buffer.
- //
- deviceObject->Flags |= DO_DIRECT_IO;
- //
- // Create counted string version of our Win32 device name.
- //
- RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
- status = IoCreateSymbolicLink( &uniWin32NameString, &uniNtNameString );
- if (!NT_SUCCESS(status))
- {
- KdPrint( ("pciScan: Couldn't create the symbolic linkn") );
- IoDeleteDevice( DriverObject->DeviceObject );
- }
- else
- {
- KdPrint( ("pciScan: All initialized!n") );
- }
- }
- else
- {
- KdPrint( ("pciScan: IoCreateDevice failedn") );
- }
- return status;
- }
- BOOLEAN pciScanIteratePCI( IN BOOLEAN First, IN unsigned int pciVendorId,
- IN unsigned int pciDeviceId,
- IN OUT PCI_SLOT_NUMBER *returnSlotData,
- IN OUT PCI_COMMON_CONFIG *returnPciData,
- IN OUT unsigned int *returnBusNumber )
- /*++
- Routine Description:
- This function is called by the driver to find the next PCI card and
- initialize the adapter's configuration.
- Arguments:
- IN BOOLEAN First - TRUE if scan is to start with
- first device
- FALSE to increment to the next
- device
- IN unsigned int pciVendorId - Specified vender ID,
- or 0xFFFF for all venders
- IN unsigned int pciDeviceId - Specified device ID,
- or 0xFFFF for all devices
- IN OUT PCI_SLOT_NUMBER *returnSlotData - Slotdata for found device
- (starting point for
- first == FALSE)
- IN OUT unsigned int *returnBusNumber - Bus number for found card
- Return Value:
- ULONG
- --*/
- {
- PCI_SLOT_NUMBER slotData;
- PCI_COMMON_CONFIG pciData;
- BOOLEAN nextBus = FALSE;
- ULONG busNumber = 1;
- ULONG bytesReturned;
- BOOLEAN firstFunction;
- BOOLEAN firstDevice;
- KdPrint( ("pciScan: FindPCI n") );
- //
- // iterate over all PCI slots
- //
- firstFunction = First;
- firstDevice = First;
- slotData.u.AsULONG = 0;
- if (!First)
- { /* continuation */
- //
- // if not the first we want to point after the last device we found
- //
- returnSlotData->u.bits.FunctionNumber++;
- if (PCI_MAX_FUNCTION <= returnSlotData->u.bits.FunctionNumber)
- { /* next device */
- returnSlotData->u.bits.FunctionNumber = 0;
- returnSlotData->u.bits.DeviceNumber++;
- if (PCI_MAX_DEVICES <= returnSlotData->u.bits.DeviceNumber)
- { /* next bus */
- returnSlotData->u.bits.DeviceNumber = 0;
- *returnBusNumber++;
- } /* next bus */
- } /* next device */
- } /* continuation */
- //
- // iterate over all PCI busses looking for devices
- //
- for ( busNumber = First?0:*returnBusNumber;
- busNumber < 256;
- busNumber++, firstDevice = TRUE)
- { /* busses loop */
- unsigned int DeviceNumber;
- nextBus = FALSE;
- //
- // Iterate over all devices
- //
- for ( DeviceNumber = firstDevice?0:returnSlotData->u.bits.DeviceNumber;
- DeviceNumber < PCI_MAX_DEVICES ;
- DeviceNumber++, firstFunction = TRUE )
- { /* devices loop */
- unsigned int FunctionNumber;
- slotData.u.bits.DeviceNumber = DeviceNumber;
- //
- // Iterate over all functions
- //
- for ( FunctionNumber =
- firstFunction?0:returnSlotData->u.bits.FunctionNumber;
- FunctionNumber < PCI_MAX_FUNCTION ;
- FunctionNumber++)
- { /* functions loop */
- slotData.u.bits.FunctionNumber = FunctionNumber;
- KdPrint( ("pciScan: FindPCI - call HalGetBusData DeviceNumber= %x, Function = %x, busNumber = %x ",
- slotData.u.bits.DeviceNumber,
- slotData.u.bits.FunctionNumber,
- busNumber) );
- RtlZeroMemory(&pciData, sizeof(PCI_COMMON_CONFIG));
- bytesReturned = HalGetBusData( PCIConfiguration,
- busNumber,
- slotData.u.AsULONG,
- &pciData,
- sizeof(PCI_COMMON_CONFIG));
- if (2 == bytesReturned) // device/function does not exist
- { /* no device/function */
- KdPrint( (" - no match 2 returned pciData.VendorID = %x %xn",
- pciData.VendorID,
- slotData.u.AsULONG) );
- //
- // MUST CONTINUE WITH LOOP --
- // functions do not have to be consective
- //
- } /* no device/function */
- else
- if (0 == bytesReturned) // bus does not exist
- { /* no bus */
- KdPrint( (" - no match 0 returned pciData.VendorID = %x %xn",
- pciData.VendorID,
- slotData.u.AsULONG) );
- //
- // We can skip to next bus
- // set flag to break out of device loop
- // and break out of function loop
- //
- nextBus = TRUE;
- break;
- } /* no bus */
- else
- if (0xffff == pciData.VendorID)
- { /* invalid vendor ID */
- KdPrint( (" - no match PCI_INVALID_VENDER_ID HalGetBusData pciData.VendorID = %xn",
- pciData.VendorID) );
- } /* invalid vendor ID */
- else
- if ( ((0xFFFF == pciVendorId)
- || ( pciData.VendorID == pciVendorId )) &&
- ((0xFFFF == pciDeviceId)
- || ( pciData.DeviceID == pciDeviceId)))
- { /* found next */
- // Found it this is the next instance of
- // this card type
- KdPrint( ("npciScan: ( busNumber, device, function ) = ( %x, %x, %x )n",
- busNumber,
- slotData.u.bits.DeviceNumber,
- slotData.u.bits.FunctionNumber));
- dumpPciConfig( pciData );
- KdPrint( ("nn") );
- *returnSlotData = slotData;
- *returnPciData = pciData;
- *returnBusNumber = busNumber;
- KdPrint( ("pciScan: exitingn") );
- return TRUE;
- } /* found next */
- else
- { /* does not match */
- KdPrint( (" - no match pciData.VendorID = %x %xn", pciData.VendorID, slotData.u.AsULONG) );
- } /* does not match */
- } /* functions loop */
- if (nextBus)
- break; // break to next bus
- } /* devices loop */
- } /* busses loop */
- KdPrint( ("pciScan: exitingn") );
- return FALSE;
- } // end pciScanFindPCI()
- /****************************************************************************
- Function:
- pciScanDeviceControl
- Arguments:
- Description:
- Returns:
- *****************************************************************************/
- NTSTATUS pciScanDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp )
- {
- NTSTATUS ret = STATUS_SUCCESS;
- PIO_STACK_LOCATION irpStack;
- PCISCAN_OUTPUT *pOutBuffer;
- PCISCAN_DEVICE_EXTENSION *extension;
- PCI_SLOT_NUMBER returnSlotData;
- PCI_COMMON_CONFIG returnPciData;
- unsigned int returnBusNumber;
- KdPrint( ("pciScan: Device Control!!n") );
- extension = (PCISCAN_DEVICE_EXTENSION *) DeviceObject->DeviceExtension;
- irpStack = IoGetCurrentIrpStackLocation(Irp);
- pOutBuffer = (PCISCAN_OUTPUT *)Irp->UserBuffer; // for buffered i/o
- switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
- { /* IOCTL */
- case IOCTL_PCISCAN_GET_FIRST:
- KdPrint( ("pciScan: Device Control -- enter GET FIRSTn") );
- if (pciScanIteratePCI( TRUE, 0xffff, 0xffff,
- &extension->returnSlotData,
- &extension->returnPciData,
- &extension->returnBusNumber ))
- { /* got first */
- KdPrint( ("pciScanIoctl: found first pci devicen") );
- pOutBuffer->SlotData = extension->returnSlotData;
- pOutBuffer->PciData = extension->returnPciData;
- pOutBuffer->BusNumber = extension->returnBusNumber;
- ret = STATUS_SUCCESS;
- break;
- } /* got first */
- else
- { /* failed first */
- KdPrint( ("pciScanIoctl: FAILED find first pci devicen") );
- ret = STATUS_UNSUCCESSFUL;
- break;
- } /* failed first */
- break;
- case IOCTL_PCISCAN_GET_NEXT:
- KdPrint( ("pciScan: Device Control -- enter GET NEXTn") );
- if (pciScanIteratePCI( FALSE, 0xffff, 0xffff,
- &extension->returnSlotData,
- &extension->returnPciData,
- &extension->returnBusNumber ))
- { /* got next */
- KdPrint( ("npciScanIoctl: found next pci devicen") );
- pOutBuffer->SlotData = extension->returnSlotData;
- pOutBuffer->PciData = extension->returnPciData;
- pOutBuffer->BusNumber = extension->returnBusNumber;
- ret = STATUS_SUCCESS;
- break;
- } /* got next */
- else
- { /* no more */
- KdPrint( ("pciScanIoctl: FAILED find next pci devicen") );
- ret = STATUS_UNSUCCESSFUL;
- break;
- } /* no more */
- break;
- default:
- ret = STATUS_UNSUCCESSFUL;
- } /* IOCTL */
- KdPrint( ("pciScan: Device Control -- returnn") );
- //
- // Fill these in before calling IoCompleteRequest.
- //
- Irp->IoStatus.Status = ret;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest( Irp, IO_NO_INCREMENT );
- return ret;
- }
- VOID pciScanUnload( IN PDRIVER_OBJECT DriverObject)
- {
- UNICODE_STRING uniDosNameString;
- //
- // All *THIS* driver needs to do is to delete the allocated memory objects,
- // the device object and the
- // symbolic link between our device name and the Win32 visible name.
- //
- // Almost every other driver ever witten would need to do a
- // significant amount of work here deallocating stuff.
- //
- KdPrint( ("pciScan: Unloading!!n") );
- //
- // Create counted string version of our Win32 device name.
- //
- RtlInitUnicodeString( &uniDosNameString, DOS_DEVICE_NAME );
- //
- // Delete the link from our device name to a name in the Win32 namespace.
- //
- IoDeleteSymbolicLink( &uniDosNameString );
- //
- // Finally delete our device object
- //
- IoDeleteDevice( DriverObject->DeviceObject );
- }
- NTSTATUS pciScanOpen(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp )
- {
- KdPrint( ("pciScan: Opened!!n") );
- //
- // No need to do anything.
- //
- //
- // Fill these in before calling IoCompleteRequest.
- //
- // DON'T get cute and try to use the status field of
- // the irp in the return status. That IRP IS GONE as
- // soon as you call IoCompleteRequest.
- //
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest( Irp, IO_NO_INCREMENT );
- return STATUS_SUCCESS;
- }
- NTSTATUS pciScanClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp )
- {
- KdPrint( ("pciScan: Closed!!n") );
- //
- // No need to do anything.
- //
- //
- // Fill these in before calling IoCompleteRequest.
- //
- // DON'T get cute and try to use the status field of
- // the irp in the return status. That IRP IS GONE as
- // soon as you call IoCompleteRequest.
- //
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest( Irp, IO_NO_INCREMENT );
- return STATUS_SUCCESS;
- }