mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
360 lines
8.5 KiB
360 lines
8.5 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pcmcmd.c
|
|
|
|
Abstract:
|
|
|
|
This program converses with the PCMCIA support driver to display
|
|
tuple and other information.
|
|
|
|
Author:
|
|
|
|
Bob Rinne
|
|
|
|
Environment:
|
|
|
|
User process.
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
|
|
Ravisankar Pudipeddi (ravisp) June 27 1997
|
|
- command line options & support for multiple controllers
|
|
Neil Sandlin (neilsa) Sept 20, 1998
|
|
- more commands
|
|
|
|
--*/
|
|
|
|
#include <pch.h>
|
|
|
|
//
|
|
// Procedures
|
|
//
|
|
|
|
|
|
NTSTATUS
|
|
OpenDevice(
|
|
IN PUCHAR DeviceName,
|
|
IN OUT PHANDLE HandlePtr
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will open the device.
|
|
|
|
Arguments:
|
|
|
|
DeviceName - ASCI string of device path to open.
|
|
HandlePtr - A pointer to a location for the handle returned on a
|
|
successful open.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
STRING NtFtName;
|
|
IO_STATUS_BLOCK status_block;
|
|
UNICODE_STRING unicodeDeviceName;
|
|
NTSTATUS status;
|
|
|
|
RtlInitString(&NtFtName,
|
|
DeviceName);
|
|
|
|
|
|
(VOID)RtlAnsiStringToUnicodeString(&unicodeDeviceName,
|
|
&NtFtName,
|
|
TRUE);
|
|
|
|
memset(&objectAttributes, 0, sizeof(OBJECT_ATTRIBUTES));
|
|
|
|
InitializeObjectAttributes(&objectAttributes,
|
|
&unicodeDeviceName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
|
|
status = NtOpenFile(HandlePtr,
|
|
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
|
|
&objectAttributes,
|
|
&status_block,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_SYNCHRONOUS_IO_ALERT );
|
|
|
|
RtlFreeUnicodeString(&unicodeDeviceName);
|
|
|
|
return status;
|
|
|
|
} // OpenDevice
|
|
|
|
PUCHAR Controllers[] = {
|
|
"PcmciaIntelCompatible",
|
|
"PcmciaCardBusCompatible",
|
|
"PcmciaElcController",
|
|
"PcmciaDatabook",
|
|
"PcmciaPciPcmciaBridge",
|
|
"PcmciaCirrusLogic",
|
|
"PcmciaTI",
|
|
"PcmciaTopic",
|
|
"PcmciaRicoh",
|
|
"PcmciaDatabookCB",
|
|
"PcmciaOpti",
|
|
"PcmciaTrid",
|
|
"PcmciaO2Micro",
|
|
"PcmciaNEC",
|
|
"PcmciaNEC_98",
|
|
};
|
|
|
|
|
|
|
|
VOID
|
|
DumpSocketInfo(
|
|
HANDLE Handle,
|
|
ULONG Slot,
|
|
PUCHAR Buffer,
|
|
ULONG BufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
IO_STATUS_BLOCK statusBlock;
|
|
PCMCIA_SOCKET_INFORMATION commandBlock;
|
|
ULONG index;
|
|
ULONG ctlClass, ctlModel, ctlRev;
|
|
|
|
memset(&commandBlock, 0, sizeof(commandBlock));
|
|
commandBlock.Socket = (USHORT) Slot;
|
|
|
|
status = NtDeviceIoControlFile(Handle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&statusBlock,
|
|
IOCTL_SOCKET_INFORMATION,
|
|
&commandBlock,
|
|
sizeof(commandBlock),
|
|
&commandBlock,
|
|
sizeof(commandBlock));
|
|
if (NT_SUCCESS(status)) {
|
|
printf("Basic Information for Socket %d:\n", Slot);
|
|
|
|
printf(" Manufacturer = %s\n", commandBlock.Manufacturer);
|
|
printf(" Identifier = %s\n", commandBlock.Identifier);
|
|
printf(" TupleCRC = %x\n", commandBlock.TupleCrc);
|
|
printf(" DriverName = %s\n", commandBlock.DriverName);
|
|
printf(" Function ID = %d\n", commandBlock.DeviceFunctionId);
|
|
|
|
ctlClass = PcmciaClassFromControllerType(commandBlock.ControllerType);
|
|
if (ctlClass >= sizeof(Controllers)/sizeof(PUCHAR)) {
|
|
printf(" ControllerType = Unknown (%x)\n", commandBlock.ControllerType);
|
|
} else {
|
|
printf(" ControllerType(%x) = %s", commandBlock.ControllerType,
|
|
Controllers[ctlClass]);
|
|
ctlModel = PcmciaModelFromControllerType(commandBlock.ControllerType);
|
|
ctlRev = PcmciaRevisionFromControllerType(commandBlock.ControllerType);
|
|
|
|
if (ctlModel) {
|
|
printf("%d", ctlModel);
|
|
}
|
|
if (ctlRev) {
|
|
printf(", rev(%d)", ctlRev);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
if (commandBlock.CardInSocket) {
|
|
printf(" Card In Socket\n");
|
|
}
|
|
if (commandBlock.CardEnabled) {
|
|
printf(" Card Enabled\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ProcessCommands(IN ULONG DeviceNumber,
|
|
IN ULONG slotNumberMin,
|
|
IN ULONG slotNumberMax,
|
|
IN ULONG Commands
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE handle;
|
|
PUCHAR buffer;
|
|
UCHAR deviceName[128];
|
|
ULONG slotNumber;
|
|
|
|
sprintf(deviceName, "%s%d", PCMCIA_DEVICE_NAME, DeviceNumber);
|
|
status = OpenDevice(deviceName, &handle);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
buffer = malloc(BUFFER_SIZE);
|
|
if (!buffer) {
|
|
printf("Unable to malloc\n");
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
printf("\n** PC-Card information for PCMCIA controller %s **\n\n", deviceName);
|
|
|
|
|
|
for (slotNumber = slotNumberMin; slotNumber <= slotNumberMax; slotNumber++) {
|
|
|
|
if (Commands & CMD_DUMP_TUPLES) {
|
|
DumpCIS(handle, slotNumber, buffer, BUFFER_SIZE);
|
|
}
|
|
if (!Commands || (Commands & CMD_DUMP_SOCKET_INFO)) {
|
|
DumpSocketInfo(handle, slotNumber, buffer, BUFFER_SIZE);
|
|
}
|
|
}
|
|
|
|
NtClose(handle);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
int __cdecl
|
|
main(
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG deviceNumber = 0;
|
|
ULONG slotNumber = 0;
|
|
NTSTATUS status;
|
|
BOOLEAN error = FALSE;
|
|
CHAR c;
|
|
BOOLEAN allControllers = TRUE, allSlots = TRUE, registers = FALSE, configuration = FALSE;
|
|
ULONG slotNumberMin, slotNumberMax;
|
|
ULONG Commands = 0;
|
|
|
|
extern PUCHAR optarg;
|
|
|
|
while ((c = getopt(argc, argv, "d:s:crti?")) != EOF) {
|
|
switch (c) {
|
|
case 'd': {
|
|
allControllers = FALSE;
|
|
deviceNumber = atoi(optarg);
|
|
break;
|
|
}
|
|
case 's': {
|
|
allSlots = FALSE;
|
|
slotNumber = atoi(optarg);
|
|
break;
|
|
}
|
|
case 't': {
|
|
Commands |= CMD_DUMP_TUPLES;
|
|
break;
|
|
}
|
|
case 'i': {
|
|
Commands |= CMD_DUMP_IRQ_SCAN_INFO;
|
|
break;
|
|
}
|
|
case '?': {
|
|
error = TRUE;
|
|
break;
|
|
}
|
|
case 0: {
|
|
error = TRUE;
|
|
printf("Error in command line options\n");
|
|
break;
|
|
}
|
|
default: {
|
|
error = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (error) {
|
|
printf("Usage: pcmcmd [-[d <arg>] [s <arg>][c][r][t]]\n");
|
|
printf("Issues commands to the pc-card (PCMCIA) driver\n");
|
|
printf("-d ControllerNumber specifies PCMCIA controller number (zero-based)\n");
|
|
printf("-s SocketNumber specifies PCMCIA socket number (zero-based)\n");
|
|
printf("-t Dumps the CIS tuples of the PC-Card\n");
|
|
printf("-i Dumps irq detection info\n");
|
|
return (1);
|
|
}
|
|
|
|
if (Commands & CMD_DUMP_IRQ_SCAN_INFO) {
|
|
DumpIrqScanInfo();
|
|
if (!(Commands & ~CMD_DUMP_IRQ_SCAN_INFO)) {
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if (allSlots) {
|
|
//
|
|
// Probe all slots
|
|
//
|
|
|
|
slotNumberMin = 0;
|
|
slotNumberMax = 7;
|
|
} else {
|
|
//
|
|
// Probe only the specified slot
|
|
//
|
|
|
|
slotNumberMin = slotNumberMax = slotNumber;
|
|
}
|
|
|
|
if (allControllers) {
|
|
|
|
deviceNumber = 0;
|
|
do {
|
|
status = ProcessCommands(deviceNumber++, slotNumberMin, slotNumberMax, Commands);
|
|
} while (NT_SUCCESS(status));
|
|
deviceNumber--; // set back to last device processed
|
|
|
|
if (status != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
printf("Failed for Pcmcia controller number %d: status 0x%x\n", deviceNumber, status);
|
|
} else if (deviceNumber == 0) {
|
|
printf("Error - no active Pcmcia controllers found\n");
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
status = ProcessCommands(deviceNumber, slotNumberMin, slotNumberMax, Commands);
|
|
if (!NT_SUCCESS(status)) {
|
|
printf("Failed for Pcmcia controller number %d: status 0x%x\n", deviceNumber, status);
|
|
}
|
|
|
|
};
|
|
|
|
return (0);
|
|
}
|