|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
1394f.C
Abstract:
Environment:
kernel mode only
Notes:
Revision History:
--*/
#include <wdm.h>
#include "stdarg.h"
#include "stdio.h"
#include "dbci.h"
#include "dbclass.h" //private data strutures
#include "dbfilter.h"
#include "1394.h"
#if DBG
VOID DBCLASS_PrintTopologyMap( PTOPOLOGY_MAP TopologyMap ) /* ++
* * Routine Description: * * Passes a IRB to the 1394 stack, and waits for return. * * Arguments: * * DeviceObject - Device object of the to of the port driver * stack * * Return Value: * * STATUS_SUCCESS if successful * * -- */ { USHORT nodeCount, selfIdCount; ULONG i;
DBCLASS_KdPrint((2, "'***********************\n")); DBCLASS_KdPrint((2, "'TopologyMap = (%08X)\n", TopologyMap)); DBCLASS_KdPrint((2, "'TOP_Length = (%08X)\n", TopologyMap->TOP_Length)); DBCLASS_KdPrint((2, "'TOP_CRC = (%08X)\n", TopologyMap->TOP_CRC)); DBCLASS_KdPrint((2, "'TOP_Generation = (%08X)\n", TopologyMap->TOP_Generation)); DBCLASS_KdPrint((2, "'TOP_Node_Count = (%08X)\n", TopologyMap->TOP_Node_Count)); DBCLASS_KdPrint((2, "'TOP_Self_ID_Count = (%08X)\n", TopologyMap->TOP_Self_ID_Count));
nodeCount = TopologyMap->TOP_Node_Count; selfIdCount = TopologyMap->TOP_Self_ID_Count; DBCLASS_KdPrint((2, "'nodeCount = (%08X) selfIdCount = (%08X)\n", nodeCount, selfIdCount));
for (i=0; i< selfIdCount; i++) {
SELF_ID selfId; SELF_ID_MORE selfIdMore;
selfId = TopologyMap->TOP_Self_ID_Array[i]; DBCLASS_KdPrint((2, "'TOP_Self_ID = (%08X)\n", selfId)); DBCLASS_KdPrint((2, "'SID_Phys_ID = (%08X)\n", (ULONG) selfId.SID_Phys_ID)); DBCLASS_KdPrint((2, "'SID_Port1 = (%08X)\n", (ULONG) selfId.SID_Port1)); DBCLASS_KdPrint((2, "'SID_Port2 = (%08X)\n", (ULONG) selfId.SID_Port2)); DBCLASS_KdPrint((2, "'SID_Port3 = (%08X)\n", (ULONG) selfId.SID_Port3)); DBCLASS_KdPrint((2, "'SID_More_Packets = (%08X)\n", (ULONG) selfId.SID_More_Packets));
if (selfId.SID_More_Packets) {
do { i++; RtlCopyMemory(&selfIdMore, &TopologyMap->TOP_Self_ID_Array[i], sizeof(ULONG));
DBCLASS_KdPrint((2, "'SID_Phys_ID = (%08X)\n", (ULONG) selfIdMore.SID_Phys_ID)); DBCLASS_KdPrint((2, "'SID_PortA = (%08X)\n", (ULONG) selfIdMore.SID_PortA)); DBCLASS_KdPrint((2, "'SID_PortB = (%08X)\n", (ULONG) selfIdMore.SID_PortB)); DBCLASS_KdPrint((2, "'SID_PortC = (%08X)\n", (ULONG) selfIdMore.SID_PortC)); DBCLASS_KdPrint((2, "'SID_PortD = (%08X)\n", (ULONG) selfIdMore.SID_PortD)); DBCLASS_KdPrint((2, "'SID_PortE = (%08X)\n", (ULONG) selfIdMore.SID_PortE)); DBCLASS_KdPrint((2, "'SID_PortF = (%08X)\n", (ULONG) selfIdMore.SID_PortF)); DBCLASS_KdPrint((2, "'SID_PortG = (%08X)\n", (ULONG) selfIdMore.SID_PortG)); DBCLASS_KdPrint((2, "'SID_PortH = (%08X)\n", (ULONG) selfIdMore.SID_PortH)); } while (selfIdMore.SID_More_Packets); } } /* for */ DBCLASS_KdPrint((2, "'***********************\n")); } #else
#define DBCLASS_PrintTopologyMap(x) x
#endif /* DBG */
NTSTATUS DBCLASS_SyncSubmitIrb( IN PDEVICE_OBJECT DeviceObject, IN PIRB Irb ) /* ++
* * Routine Description: * * Passes a IRB to the 1394 stack, and waits for return. * * Arguments: * * DeviceObject - Device object of the to of the port driver * stack * * Return Value: * * STATUS_SUCCESS if successful * * -- */ { NTSTATUS ntStatus, status; PIRP irp; KEVENT event; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION nextStack; #ifdef DEADMAN_TIMER
BOOLEAN haveTimer = FALSE; KDPC timeoutDpc; KTIMER timeoutTimer; #endif
PAGED_CODE();
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(IOCTL_1394_CLASS, DeviceObject, NULL, 0, NULL, 0, TRUE, // INTERNAL
&event, &ioStatus);
if (NULL == irp) { DBCLASS_KdPrint((0, "'could not allocate an irp!\n")); TRAP(); return STATUS_INSUFFICIENT_RESOURCES; } //
// Call the port driver to perform the operation. If the returned
// status
// is PENDING, wait for the request to complete.
//
nextStack = IoGetNextIrpStackLocation(irp);
//
// pass the DRB
//
nextStack->Parameters.Others.Argument1 = Irb; ntStatus = IoCallDriver(DeviceObject, irp); if (ntStatus == STATUS_PENDING) {
#ifdef DEADMAN_TIMER
LARGE_INTEGER dueTime;
KeInitializeTimer(&timeoutTimer); KeInitializeDpc(&timeoutDpc, UsbhTimeoutDPC, irp);
dueTime.QuadPart = -10000 * DEADMAN_TIMEOUT;
KeSetTimer(&timeoutTimer, dueTime, &timeoutDpc);
haveTimer = TRUE; #endif
status = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
} else { ioStatus.Status = ntStatus; }
#ifdef DEADMAN_TIMER
//
// remove our timeoutDPC from the queue
//
if (haveTimer) { KeCancelTimer(&timeoutTimer); } #endif /* DEADMAN_TIMER */
ntStatus = ioStatus.Status;
DBCLASS_KdPrint((2,"'DBCLASS_SyncSubmitIrb (%x)\n", ntStatus));
return ntStatus; }
#define DBCLASS_COUNT_PORT(s, d) (d)->NumberOf1394Ports++;
USHORT DBCLASS_GetNodeId( PTOPOLOGY_MAP TopologyMap, USHORT Index, USHORT Connect ) /*++
Routine Description:
Given an index walk the map and return the NodeId
Arguments:
Return Value:
zero if not a device bay PDO.
--*/ { USHORT i; USHORT nodeCount; USHORT nodeId = 0xffff; USHORT idCount = 0; USHORT selfIdCount;
nodeCount = TopologyMap->TOP_Node_Count; selfIdCount = TopologyMap->TOP_Self_ID_Count; DBCLASS_KdPrint((2, "'>GetNodeId Index = %d\n", Index));
for (i=0; i< selfIdCount; i++) {
SELF_ID selfId; SELF_ID_MORE selfIdMore;
selfId = TopologyMap->TOP_Self_ID_Array[i]; if (idCount == Index && ((USHORT)selfId.SID_Port1 == Connect || (USHORT)selfId.SID_Port2 == Connect || (USHORT)selfId.SID_Port3 == Connect)) { nodeId = (USHORT) selfId.SID_Phys_ID; break; }
if (selfId.SID_More_Packets) {
do { i++; RtlCopyMemory(&selfIdMore, &TopologyMap->TOP_Self_ID_Array[i], sizeof(ULONG)); if (idCount == Index && ((USHORT)selfIdMore.SID_PortA == Connect || (USHORT)selfIdMore.SID_PortB == Connect || (USHORT)selfIdMore.SID_PortC == Connect || (USHORT)selfIdMore.SID_PortD == Connect || (USHORT)selfIdMore.SID_PortE == Connect || (USHORT)selfIdMore.SID_PortF == Connect || (USHORT)selfIdMore.SID_PortG == Connect || (USHORT)selfIdMore.SID_PortH == Connect)) { nodeId = (USHORT) selfId.SID_Phys_ID; goto DBCLASS_GetNodeId_Done; }
} while (selfIdMore.SID_More_Packets); }
idCount++; } DBCLASS_KdPrint((2, "'>nodeId = (%08X)\n", nodeId));
DBCLASS_GetNodeId_Done:
return nodeId; }
PBUS1394_PORT_INFO DBCLASS_SetNodeId( PTOPOLOGY_MAP TopologyMap, SELF_ID HcSelfId, USHORT SelfIdPortX, PUSHORT ChildIdx, PUSHORT ParentIdx, PBUS1394_PORT_INFO Bus1394PortInfo ) /*++
Routine Description:
Arguments:
Return Value:
zero if not a device bay PDO.
--*/ { ULONG flags = 0; USHORT nodeId = 0xffff, idCount;
idCount = TopologyMap->TOP_Self_ID_Count; DBCLASS_KdPrint((2, "'ParentIdx = %d ChildIdx = %d count = %d\n", *ParentIdx, *ChildIdx, idCount));
//Scan forward through the map looking for potential children
if (SelfIdPortX == SELF_ID_CONNECTED_TO_CHILD) { DBCLASS_KdPrint((2, "'find child\n"));
do { (*ChildIdx)++;
// are we out of children?
if (*ChildIdx > idCount) { // yes, check the root
*ChildIdx = 0; } flags = DBCLASS_PORTFLAG_DEVICE_CONNECTED;
// find the child node id
nodeId = DBCLASS_GetNodeId(TopologyMap, *ChildIdx, SELF_ID_CONNECTED_TO_PARENT); } while (nodeId == 0xffff); DBCLASS_KdPrint((2, "'Found ChildIdx = %d nodeId = %d\n", *ChildIdx, nodeId));
} else if (SelfIdPortX == SELF_ID_CONNECTED_TO_PARENT) { do { (*ParentIdx)++;
// are we out of parents?
if (*ParentIdx > idCount) { // yes, check the root
*ParentIdx = 0; } flags = DBCLASS_PORTFLAG_DEVICE_CONNECTED;
nodeId = DBCLASS_GetNodeId(TopologyMap, *ParentIdx, SELF_ID_CONNECTED_TO_CHILD); } while (nodeId == 0xffff);
DBCLASS_KdPrint((2, "'Found ParentIdx = %d nodeId = %d\n", *ParentIdx, nodeId)); }
Bus1394PortInfo->Flags = flags; Bus1394PortInfo->NodeId = nodeId; Bus1394PortInfo->BayNumber = 0; Bus1394PortInfo++;
return Bus1394PortInfo; }
#if DBG
VOID DBCLASS_KdPrintGuid( ULONG Level, PUCHAR P ) { DBCLASS_KdPrint((Level, "'>>>>GUID1 = [%02.2x] [%02.2x] [%02.2x] [%02.2x]\n", *P, *(P+1), *(P+2), *(P+3))); DBCLASS_KdPrint((Level, "'>>>>GUID2 = [%02.2x] [%02.2x] [%02.2x] [%02.2x]\n", *(P+4), *(P+5), *(P+6), *(P+7))); } #endif
BOOLEAN DBCLASS_IsLinkDeviceObject( PDBC_CONTEXT DbcContext, PDEVICE_OBJECT Pdo1394 ) /*++
Routine Description:
check the link guid in dbcContext against the link guid for a 1394 device,
Arguments:
Return Value:
true if link guid matches
--*/ { PNODE_DEVICE_EXTENSION nodeExtension;
nodeExtension = Pdo1394->DeviceExtension;
DBCLASS_KdPrint((2, "'>NodeExt (%08X) ConfigRom (%08X)\n", nodeExtension, nodeExtension->ConfigRom));
DBCLASS_KdPrint((2, "'>1394 PDO GUID\n"));
if(nodeExtension->ConfigRom) {
#if DBG
DBCLASS_KdPrintGuid(2, (PUCHAR)&nodeExtension->ConfigRom->CR_Node_UniqueID[0]); #endif
DBCLASS_KdPrint((2, "'>DBC Link GUID\n"));
#if DBG
DBCLASS_KdPrintGuid(2, &DbcContext->SubsystemDescriptor.guid1394Link[0]); #endif
return RtlCompareMemory(&DbcContext->SubsystemDescriptor.guid1394Link[0], &nodeExtension->ConfigRom->CR_Node_UniqueID[0], 8) == 8; } else return FALSE; }
NTSTATUS DBCLASS_GetSpeedAndTopologyMaps( PTOPOLOGY_MAP *TopologyMap, PDEVICE_OBJECT BusFilterMdo ) /*++
Routine Description:
Arguments:
Return Value:
topology map or NULL
--*/ { NTSTATUS ntStatus = STATUS_SUCCESS; IRB irb; PDEVICE_EXTENSION deviceExtension; GET_LOCAL_HOST_INFO6 info6; PUCHAR buffer = NULL;
if(BusFilterMdo == NULL) return STATUS_UNSUCCESSFUL; deviceExtension = BusFilterMdo->DeviceExtension; DBCLASS_KdPrint((2, "'>Get 1394 Speed & Topology Maps MDO (%08X)\n", BusFilterMdo)); BRK_ON_TRAP(); irb.FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO; irb.u.GetLocalHostInformation.nLevel = GET_HOST_CSR_CONTENTS; info6.CsrBaseAddress.Off_High = 0xffff; info6.CsrBaseAddress.Off_Low = TOPOLOGY_MAP_LOCATION; info6.CsrDataLength = 0; info6.CsrDataBuffer = buffer;
irb.u.GetLocalHostInformation.Information = &info6; ntStatus = DBCLASS_SyncSubmitIrb( deviceExtension->TopOfStackDeviceObject, &irb);
DBCLASS_KdPrint((2, "'GetLocalHostInfo(), first call = (%08X)\n", ntStatus));
if (ntStatus == STATUS_INVALID_BUFFER_SIZE) { // try again with correct size
buffer = DbcExAllocatePool(NonPagedPool, info6.CsrDataLength); if (buffer) { info6.CsrDataBuffer = buffer; ntStatus = DBCLASS_SyncSubmitIrb( deviceExtension->TopOfStackDeviceObject, &irb); } else { ntStatus = STATUS_INSUFFICIENT_RESOURCES; }
DBCLASS_KdPrint((2, "'GetLocalHostInfo(), second call = (%08X) buffer = %x\n", ntStatus, buffer)); }
if (NT_SUCCESS(ntStatus)) { *TopologyMap = (PTOPOLOGY_MAP) buffer;
DBCLASS_PrintTopologyMap(*TopologyMap); }
return ntStatus; }
NTSTATUS DBCLASS_Get1394BayPortMapping( PDEVICE_OBJECT BusFilterMdo, PDBC_CONTEXT DbcContext ) /*++
Routine Description:
Arguments:
Return Value:
zero if not a device bay PDO.
--*/ { NTSTATUS ntStatus = STATUS_SUCCESS; IRB irb; PDEVICE_EXTENSION deviceExtension; PTOPOLOGY_MAP topologyMap = NULL; USHORT i, nodeCount, selfIdCount, linkNodeId; USHORT linkSelfId_Index = 0; PDEVICE_OBJECT linkDeviceObject;
DBCLASS_KdPrint((1, "'>Get 1394 Port Mapping\n")); DBCLASS_ASSERT(DbcContext); BRK_ON_TRAP();
//
// get the topology map & local node id from the 1394 port driver
//
// our mission her is to find the parent nodeid
//
// if the DBC controller is ACPI then this will be the 1394 host controller
// if it is USB based it will be the PHY for DBC
if (DbcContext->ControllerSig == DBC_ACPI_CONTROLLER_SIG) {
//
// link device object is the PDO for the 1394 HC
//
DBCLASS_KdPrint((2, "'DBC is ACPI \n")); deviceExtension = DbcContext->BusFilterMdo1394->DeviceExtension; DBCLASS_ASSERT(DbcContext->BusFilterMdo1394 == BusFilterMdo); DBCLASS_ASSERT(DbcContext->LinkDeviceObject == NULL); linkDeviceObject = deviceExtension->TopOfStackDeviceObject; } else {
//
// for USBDBC the link is stored in the dbcContext
//
DBCLASS_KdPrint((2, "'DBC is USB \n")); linkDeviceObject = DbcContext->LinkDeviceObject;
BRK_ON_TRAP(); }
DBCLASS_KdPrint((2, "'DbcContext (%08X) LinkDeviceObject (%08X)\n", DbcContext, linkDeviceObject));
// check for invalid device object
if(((linkDeviceObject) == (PDEVICE_OBJECT)(-1)) || (linkDeviceObject == NULL)) { ntStatus = STATUS_UNSUCCESSFUL; goto BayPort_End; }
// should only get here if the db controller
// has been found
DBCLASS_ASSERT(linkDeviceObject != NULL);
irb.u.Get1394AddressFromDeviceObject.fulFlags = 0; irb.FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT; ntStatus = DBCLASS_SyncSubmitIrb(linkDeviceObject, &irb);
DBCLASS_KdPrint((2, "'GetLocalNodeId() = (%08X)\n", ntStatus));
if (NT_SUCCESS(ntStatus)) {
linkNodeId = irb.u.Get1394AddressFromDeviceObject.NodeAddress.NA_Node_Number; DBCLASS_KdPrint((2, "'link node id (%08X)\n", linkNodeId)); ntStatus = DBCLASS_GetSpeedAndTopologyMaps( &topologyMap, DbcContext->BusFilterMdo1394);
DBCLASS_KdPrint((2, "'GetTopologyMap() = (%08X)\n", ntStatus)); }
if(NT_SUCCESS(ntStatus)) { DBCLASS_ASSERT(topologyMap != NULL); DbcContext->NumberOf1394Ports = 0; // free the old information
if (DbcContext->Bus1394PortInfo) { DbcExFreePool(DbcContext->Bus1394PortInfo); DbcContext->Bus1394PortInfo = NULL; }
//
// parse the map
//
if(topologyMap) { nodeCount = topologyMap->TOP_Node_Count; selfIdCount = topologyMap->TOP_Self_ID_Count; // walk the topology map and find the node for the
// for the link
//
// first pass we just count up the ports
// we count all SID entries for ports if if
// not present.
//
for (i=0; i< selfIdCount; i++) {
SELF_ID selfId; SELF_ID_MORE selfIdMore;
selfId = topologyMap->TOP_Self_ID_Array[i]; if (selfId.SID_Phys_ID == linkNodeId) { // this is the host, count the ports
linkSelfId_Index = i;
DBCLASS_COUNT_PORT(selfId.SID_Port1, DbcContext); DBCLASS_COUNT_PORT(selfId.SID_Port2, DbcContext); DBCLASS_COUNT_PORT(selfId.SID_Port3, DbcContext); }
if (selfId.SID_More_Packets) {
do { i++; RtlCopyMemory(&selfIdMore, &topologyMap->TOP_Self_ID_Array[i], sizeof(ULONG));
if (selfIdMore.SID_Phys_ID == linkNodeId) { // this is the link, count the ports
DBCLASS_COUNT_PORT(selfIdMore.SID_PortA, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortB, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortC, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortD, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortE, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortF, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortG, DbcContext); DBCLASS_COUNT_PORT(selfIdMore.SID_PortH, DbcContext); }
} while(selfIdMore.SID_More_Packets); } } }
// now set up the port map
DbcContext->Bus1394PortInfo = DbcExAllocatePool(NonPagedPool, sizeof(BUS1394_PORT_INFO) * DbcContext->NumberOf1394Ports);
DBCLASS_KdPrint((2, "'link index = %d\n", linkSelfId_Index)); DBCLASS_KdPrint((2, "'link id = %d\n", linkNodeId)); if(DbcContext->Bus1394PortInfo && topologyMap) { SELF_ID selfId; SELF_ID_MORE selfIdMore; USHORT parentIdx, childIdx; PBUS1394_PORT_INFO bus1394PortInfo = DbcContext->Bus1394PortInfo;
// scan children and parents
// now parse the self id for the link and fill in the port map
// fill in the phys ids for all child devices
selfId = topologyMap->TOP_Self_ID_Array[linkSelfId_Index]; parentIdx = childIdx = linkNodeId;
DBCLASS_ASSERT(selfId.SID_Phys_ID == linkNodeId);
bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfId.SID_Port1, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfId.SID_Port2, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfId.SID_Port3, &parentIdx, &childIdx, bus1394PortInfo);
if (selfId.SID_More_Packets) {
do { linkSelfId_Index++; RtlCopyMemory(&selfIdMore, &topologyMap->TOP_Self_ID_Array[linkSelfId_Index], sizeof(ULONG));
bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortA, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortB, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortC, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortD, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortE, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortF, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortG, &parentIdx, &childIdx, bus1394PortInfo); bus1394PortInfo = DBCLASS_SetNodeId(topologyMap, selfId, (USHORT)selfIdMore.SID_PortH, &parentIdx, &childIdx, bus1394PortInfo); } while (selfIdMore.SID_More_Packets); }
// now update the bay/port map
for (i=0; i< DbcContext->NumberOf1394Ports; i++) { USHORT bay; // find the bay for this port
// note: phy port index start at 1
for (bay=1; bay <=NUMBER_OF_BAYS(DbcContext); bay++) { if (DbcContext->BayInformation[bay].BayDescriptor.bPHYPortNumber == i+1) { DbcContext->Bus1394PortInfo[i].BayNumber = bay; break; } } } #if DBG
for (i=0; i<DbcContext->NumberOf1394Ports; i++) { DBCLASS_KdPrint((2, "'Port [%d] = nodeId (%08X) bay (%08X) flg = (%08X)\n", i+1, DbcContext->Bus1394PortInfo[i].NodeId, DbcContext->Bus1394PortInfo[i].BayNumber, DbcContext->Bus1394PortInfo[i].Flags)); }
for (i=1; i<= NUMBER_OF_BAYS(DbcContext); i++) { DBCLASS_KdPrint((2, "'Port [%d] = bay (%08X)\n", DbcContext->BayInformation[i].BayDescriptor.bPHYPortNumber, DbcContext->BayInformation[i].BayDescriptor.bBayNumber )); } #endif
} else { ntStatus = STATUS_INSUFFICIENT_RESOURCES; DBCLASS_KdPrint((0, "No memory for Port Info'\n")); TRAP(); }
}
if (topologyMap) { DbcExFreePool(topologyMap); }
BayPort_End:
return ntStatus; }
USHORT DBCLASS_GetBayFor1394Pdo( PDEVICE_OBJECT BusFilterMdo, PDBC_CONTEXT DbcContext, PDEVICE_OBJECT Pdo1394 ) /*++
Routine Description:
given a 1394 PDO figure out wich bay it is associated with Arguments:
Return Value:
zero if not a device bay PDO.
--*/ { PNODE_DEVICE_EXTENSION nodeExtension; USHORT nodeId; ULONG i; NTSTATUS ntStatus; PBUS1394_PORT_INFO bus1394PortInfo;
PAGED_CODE(); ntStatus = DBCLASS_Get1394BayPortMapping(BusFilterMdo, DbcContext);
if (NT_SUCCESS(ntStatus)) { nodeExtension = Pdo1394->DeviceExtension;
// check the node id against the bay port mapping
nodeId = nodeExtension->NodeAddress.NA_Node_Number; DBCLASS_KdPrint((1, "'>1394 PDO (%08X) has NodeID = (%08X)\n", Pdo1394, nodeId));
bus1394PortInfo = DbcContext->Bus1394PortInfo; for (i=0; i< DbcContext->NumberOf1394Ports; i++) { if (bus1394PortInfo->NodeId == nodeId) { DBCLASS_KdPrint((1, "'>1394 PDO is in bay = %d\n", bus1394PortInfo->BayNumber)); return bus1394PortInfo->BayNumber; } bus1394PortInfo++; } } #if DBG
else { DBCLASS_KdPrint((1, "'failed to get 1394 bay->port mapping!\n")); } #endif
return 0; }
NTSTATUS DBCLASS_DeferIrpCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++
Routine Description:
This routine is called when the port driver completes an IRP.
Arguments:
DeviceObject - Pointer to the device object for the class device.
Irp - Irp completed.
Context - Driver defined context.
Return Value:
The function value is the final status from the operation.
--*/ { PKEVENT event = Context;
KeSetEvent(event, 1, FALSE);
DBCLASS_KdPrint((2, "'defer irp %x\n", Irp)); return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS DBCLASS_CreateDeviceFilterObject( IN PDRIVER_OBJECT DriverObject, IN OUT PDEVICE_OBJECT *DeviceObject, IN PDEVICE_OBJECT DevicePdo, IN PDBC_CONTEXT DbcContext, IN ULONG BusTypeSig ) /*++
Routine Description:
This routine is called to create a new instance of the DBC bus filter.
Arguments:
DriverObject - pointer to the driver object for USBD.
*DeviceObject - ptr to DeviceObject ptr to be filled in with the device object we create.
Return Value:
NT status code
--*/ { NTSTATUS ntStatus;
PAGED_CODE();
ntStatus = IoCreateDevice(DriverObject, sizeof (DEVICE_EXTENSION), NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, //NOT Exclusive
DeviceObject);
if (!NT_SUCCESS(ntStatus) && *DeviceObject) { IoDeleteDevice(*DeviceObject); }
if (NT_SUCCESS(ntStatus)) {
PDEVICE_OBJECT deviceObject = *DeviceObject, stackTopDO; PDEVICE_EXTENSION deviceExtension;
// initialize the FDO
// and attach it to the PDO
//
// clone some charateristics of the PDO.
//
deviceExtension = deviceObject->DeviceExtension; deviceExtension->PhysicalDeviceObject = DevicePdo;
stackTopDO = deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, DevicePdo); //
// Preserve flags in lower device object
//
deviceObject->Flags |= (DevicePdo->Flags & (DO_POWER_INRUSH | DO_POWER_PAGABLE));
deviceObject->Flags |= (DevicePdo->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO));
deviceExtension->DbcContext = DbcContext;
deviceExtension->FdoType = BusTypeSig;
// object is ready
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
return ntStatus; }
NTSTATUS DBCLASS_1394QBusRelationsComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
/*++
Routine Description:
Arguments:
DeviceObject - a pointer to the device object
Irp - a pointer to the irp
Context - NULL ptr
Return Value:
STATUS_SUCCESS
--*/
{ PDEVICE_RELATIONS deviceRelations; ULONG i; PDEVICE_OBJECT busFilterMdo = Context; PDEVICE_EXTENSION deviceExtension; PDEVICE_OBJECT mdo1394; deviceExtension = busFilterMdo->DeviceExtension; deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information;
LOGENTRY(LOG_MISC, '3QBR', busFilterMdo, 0, deviceRelations);
if ((!NT_SUCCESS(Irp->IoStatus.Status)) || deviceRelations == NULL) { LOGENTRY(LOG_MISC, '3QBn', busFilterMdo, 0, deviceRelations);
DBCLASS_KdPrint((0, "'>QBR 1394 Failed\n"));
deviceExtension->QBusRelations1394Success = FALSE;
goto DBCLASS_1394QBR_Done; } else { DBCLASS_KdPrint((0, "'>QBR 1394 Passed\n"));
deviceExtension->QBusRelations1394Success = TRUE; }
for (i=0; i< deviceRelations->Count; i++) {
DBCLASS_KdPrint((1, "'>QBR 1394 PDO[%d] %x \n", i, deviceRelations->Objects[i])); LOGENTRY(LOG_MISC, 'QBRd', deviceRelations->Objects[i], i, 0);
// 1394 is returning a PDO, see if we know
// about it
// if this is the PHY/LINK for a DBC link it to the
// DBC context
DBCLASS_CheckPhyLink(deviceRelations->Objects[i]); mdo1394 = DBCLASS_FindDevicePdo(deviceRelations->Objects[i]);
if (mdo1394) { // we know about this one,
PDEVICE_EXTENSION mdo1394DeviceExtension; PDBC_CONTEXT dbcContext; mdo1394DeviceExtension = mdo1394->DeviceExtension; dbcContext = mdo1394DeviceExtension->DbcContext;
} else { PDEVICE_OBJECT deviceFilterObject; NTSTATUS ntStatus; PDBC_CONTEXT dbcContext; PDEVICE_OBJECT devObj; PNODE_DEVICE_EXTENSION nodeExtension;
devObj = deviceRelations->Objects[i]; nodeExtension = devObj->DeviceExtension;
// if this is a "virtual" device, just skip it
if(nodeExtension->Tag == VIRTUAL_DEVICE_EXTENSION_TAG) { DBCLASS_KdPrint((1, "'****> Virtual 1394 Device\n")); continue; }
// don't know about it,
// create an MDO for this device
dbcContext = NULL;
ntStatus = DBCLASS_CreateDeviceFilterObject( deviceExtension->DriverObject, &deviceFilterObject, devObj, dbcContext, DB_FDO_1394_DEVICE);
if (NT_SUCCESS(ntStatus)) { DBCLASS_AddDevicePDOToList(deviceFilterObject, deviceRelations->Objects[i]); }
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(1394) Create DO %x for 1394 PDO\n", deviceFilterObject));
} }
DBCLASS_1394QBR_Done:
KeSetEvent(&deviceExtension->QBusRelations1394Event, 1, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED; }
ULONG DBCLASS_CountConnectedPorts( PTOPOLOGY_MAP TopologyMap, ULONG Index, ULONG Connection ) /*++
Routine Description:
Arguments:
Return Value:
NTSTATUS
--*/ { SELF_ID selfId; SELF_ID_MORE selfIdMore; ULONG count = 0;
selfId = TopologyMap->TOP_Self_ID_Array[Index];
DBCLASS_KdPrint((2, "'TOP_Self_ID = (%08X)\n", selfId)); DBCLASS_KdPrint((2, "'SID_Phys_ID = (%08X)\n", (ULONG) selfId.SID_Phys_ID)); DBCLASS_KdPrint((2, "'SID_Port1 = (%08X)\n", (ULONG) selfId.SID_Port1)); DBCLASS_KdPrint((2, "'SID_Port2 = (%08X)\n", (ULONG) selfId.SID_Port2)); DBCLASS_KdPrint((2, "'SID_Port3 = (%08X)\n", (ULONG) selfId.SID_Port3)); DBCLASS_KdPrint((2, "'SID_More_Packets = (%08X)\n", (ULONG) selfId.SID_More_Packets));
#define COUNT_PORT(s) if ((s) == Connection) { count++;}
COUNT_PORT(selfId.SID_Port1); COUNT_PORT(selfId.SID_Port2); COUNT_PORT(selfId.SID_Port3); if (selfId.SID_More_Packets) {
do { Index++; RtlCopyMemory(&selfIdMore, &TopologyMap->TOP_Self_ID_Array[Index], sizeof(ULONG));
DBCLASS_KdPrint((2, "'SID_Phys_ID = (%08X)\n", (ULONG) selfIdMore.SID_Phys_ID)); DBCLASS_KdPrint((2, "'SID_PortA = (%08X)\n", (ULONG) selfIdMore.SID_PortA)); DBCLASS_KdPrint((2, "'SID_PortB = (%08X)\n", (ULONG) selfIdMore.SID_PortB)); DBCLASS_KdPrint((2, "'SID_PortC = (%08X)\n", (ULONG) selfIdMore.SID_PortC)); DBCLASS_KdPrint((2, "'SID_PortD = (%08X)\n", (ULONG) selfIdMore.SID_PortD)); DBCLASS_KdPrint((2, "'SID_PortE = (%08X)\n", (ULONG) selfIdMore.SID_PortE)); DBCLASS_KdPrint((2, "'SID_PortF = (%08X)\n", (ULONG) selfIdMore.SID_PortF)); DBCLASS_KdPrint((2, "'SID_PortG = (%08X)\n", (ULONG) selfIdMore.SID_PortG)); DBCLASS_KdPrint((2, "'SID_PortH = (%08X)\n", (ULONG) selfIdMore.SID_PortH));
COUNT_PORT(selfIdMore.SID_PortA); COUNT_PORT(selfIdMore.SID_PortB); COUNT_PORT(selfIdMore.SID_PortC); COUNT_PORT(selfIdMore.SID_PortD); COUNT_PORT(selfIdMore.SID_PortE); COUNT_PORT(selfIdMore.SID_PortF); COUNT_PORT(selfIdMore.SID_PortG); COUNT_PORT(selfIdMore.SID_PortH); } while (selfIdMore.SID_More_Packets); }
#undef COUNT_PORT
return count; }
BOOLEAN DBCLASS_IsParent( PTOPOLOGY_MAP TopologyMap, ULONG SelfIdIndex ) /*++
Routine Description:
returns true if the node is 'connetected to parent' (2)
Arguments:
Return Value:
NTSTATUS
--*/ { return TRUE; }
BOOLEAN DBCLASS_IsChild( PTOPOLOGY_MAP TopologyMap, ULONG SelfIdIndex ) /*++
Routine Description:
returns true if the node is 'connetected to child' (3)
Arguments:
Return Value:
NTSTATUS
--*/ { ULONG i = SelfIdIndex; BOOLEAN isChild = FALSE; SELF_ID selfId; SELF_ID_MORE selfIdMore; selfId = TopologyMap->TOP_Self_ID_Array[i];
if (selfId.SID_Port1 == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfId.SID_Port2 == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfId.SID_Port3 == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfId.SID_More_Packets) { do { i++; RtlCopyMemory(&selfIdMore, &TopologyMap->TOP_Self_ID_Array[i], sizeof(ULONG));
if (selfIdMore.SID_PortA == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortB == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortC == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortD == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortE == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortF == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortG == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } if (selfIdMore.SID_PortH == SELF_ID_CONNECTED_TO_CHILD) { isChild = TRUE; } } while (selfIdMore.SID_More_Packets); } DBCLASS_KdPrint((2, "'IsChild %d\n", isChild)); return isChild; }
BOOLEAN DBCLASS_IsNodeConnectedToLink( PDBC_CONTEXT DbcContext, PTOPOLOGY_MAP TopologyMap, USHORT CurrentNodeId, USHORT LinkNodeId ) /*++
Routine Description:
Given the nodeId for a Device and the node Id for the link figure out if the node is connected to the link
return true if it is
Arguments:
Return Value:
NTSTATUS
--*/ { NTSTATUS ntStatus = STATUS_SUCCESS; USHORT nodeCount, selfIdCount; BOOLEAN connected = FALSE; LONG device_Index = -1; ULONG connectCount, i, childCount, parentCount; DBCLASS_KdPrint((2, "'TopologyMap = (%08X)\n", TopologyMap)); DBCLASS_KdPrint((2, "'TOP_Length = (%08X)\n", TopologyMap->TOP_Length)); DBCLASS_KdPrint((2, "'TOP_CRC = (%08X)\n", TopologyMap->TOP_CRC)); DBCLASS_KdPrint((2, "'TOP_Generation = (%08X)\n", TopologyMap->TOP_Generation)); DBCLASS_KdPrint((2, "'TOP_Node_Count = (%08X)\n", TopologyMap->TOP_Node_Count)); DBCLASS_KdPrint((2, "'TOP_Self_ID_Count = (%08X)\n", TopologyMap->TOP_Self_ID_Count));
nodeCount = TopologyMap->TOP_Node_Count; selfIdCount = TopologyMap->TOP_Self_ID_Count; DBCLASS_KdPrint((2, "'nodeCount = (%08X) selfIdCount = (%08X)\n", nodeCount, selfIdCount));
//
// walk the topology map and find the index of the node for the
// device
//
DBCLASS_KdPrint((2, "'Find Node Index\n"));
for (i=0; i< nodeCount; i++) {
SELF_ID selfId; SELF_ID_MORE selfIdMore;
selfId = TopologyMap->TOP_Self_ID_Array[i]; DBCLASS_KdPrint((2, "'[%d] SID_Phys_ID = (%08X)\n", i, (ULONG) selfId.SID_Phys_ID));
if (selfId.SID_Phys_ID == CurrentNodeId) { // this is the host, count the ports
device_Index = i; }
if (selfId.SID_More_Packets) {
do { i++; RtlCopyMemory(&selfIdMore, &TopologyMap->TOP_Self_ID_Array[i], sizeof(ULONG));
DBCLASS_KdPrint((2, "'[%d].more SID_Phys_ID = (%08X)\n", i, (ULONG) selfIdMore.SID_Phys_ID)); } while (selfIdMore.SID_More_Packets); } } /* for */
// did we find the device?
if (device_Index != -1) {
// yes
DBCLASS_KdPrint((2, "'-->device_Index found = (%08X)\n", device_Index));
// OK if this is a device bay device then it can
// have only one connected port
childCount = DBCLASS_CountConnectedPorts( TopologyMap, device_Index, SELF_ID_CONNECTED_TO_CHILD); parentCount = DBCLASS_CountConnectedPorts( TopologyMap, device_Index, SELF_ID_CONNECTED_TO_PARENT);
connectCount = childCount + parentCount;
DBCLASS_KdPrint((2, "'parent = %d child %d\n", parentCount, childCount)); DBCLASS_KdPrint((2, "'connectCount = %d \n", connectCount));
if (parentCount == 1) { // OK possible device bay device
SELF_ID selfId; SELF_ID_MORE selfIdMore;
i = device_Index; // port is 'connected to parent' see if it is
// the link
// if it is not the link then this cannot be a DB
// device
i++; if (i == selfIdCount) { DBCLASS_KdPrint((2, "'NXT ENTRY wraps\n")); i=0; }
while (!DBCLASS_IsChild(TopologyMap, i)) {
// advance to the next selfId until we find one
// that is connected to child(3)
selfId = TopologyMap->TOP_Self_ID_Array[i];
// skip 'more packets'
if (selfId.SID_More_Packets) { do { i++; RtlCopyMemory(&selfIdMore, &TopologyMap->TOP_Self_ID_Array[i], sizeof(ULONG));
DBCLASS_KdPrint((2, "'SID_Phys_ID = (%08X)\n", (ULONG) selfIdMore.SID_Phys_ID)); } while (selfIdMore.SID_More_Packets); }
i++; if (i == selfIdCount) { DBCLASS_KdPrint((2, "'NXT ENTRY wraps\n")); i=0; } } // now check the next entry
selfId = TopologyMap->TOP_Self_ID_Array[i]; DBCLASS_KdPrint((2, "'NXT ENTRY - SID_Phys_ID = (%08X)\n", (ULONG) selfId.SID_Phys_ID));
if (selfId.SID_Phys_ID == LinkNodeId) { connected = TRUE; } } else if (childCount == 1) { // possible DB device
SELF_ID selfId; ULONG physIdPrev, top; i = device_Index;
do { if (i==0) { i = nodeCount-1; } else { i--; } selfId = TopologyMap->TOP_Self_ID_Array[i]; physIdPrev = selfId.SID_Phys_ID;
do { top = i; if (i==0) { i = nodeCount-1; } else { i--; } selfId = TopologyMap->TOP_Self_ID_Array[i]; } while (physIdPrev == selfId.SID_Phys_ID);
i = top;
DBCLASS_KdPrint((2, "'PREV - idx = %d\n", i));
// stop when we find a parent
} while (!DBCLASS_IsParent(TopologyMap, i)); // entry !=2
// port is 'connected to parent' see if it is
// the link
// advance to the next selfId
selfId = TopologyMap->TOP_Self_ID_Array[i]; // note that PhysID is the same even if this is a 'more packets'
// SID
DBCLASS_KdPrint((2, "'NXT ENTRY - SID_Phys_ID = (%08X)\n", (ULONG) selfId.SID_Phys_ID));
if (selfId.SID_Phys_ID == LinkNodeId) { connected = TRUE; } } }
DBCLASS_KdPrint((2, "'>CurrentNodeId %d, LinkNodeId = %d CONNECTED(%d)\n", CurrentNodeId, LinkNodeId, connected)); BRK_ON_TRAP(); return connected; }
NTSTATUS DBCLASS_Check1394DevicePDO( PDEVICE_OBJECT FilterDeviceObject, PDBC_CONTEXT DbcContext, PDEVICE_OBJECT DevicePDO ) /*++
Routine Description:
Arguments:
Return Value:
NTSTATUS
--*/ { NTSTATUS ntStatus; PTOPOLOGY_MAP topologyMap = NULL; PNODE_DEVICE_EXTENSION nodeExtension; PDEVICE_EXTENSION deviceExtension; USHORT nodeId, linkNodeId; IRB irb; // get the node id for the device
deviceExtension = FilterDeviceObject->DeviceExtension; nodeExtension = DevicePDO->DeviceExtension; nodeId = nodeExtension->NodeAddress.NA_Node_Number; DBCLASS_KdPrint((2, "'1394 PDO (%08X) has NodeID = (%08X)\n", DevicePDO, nodeId));
// get the topology map from the local host
ntStatus = DBCLASS_GetSpeedAndTopologyMaps(&topologyMap, FilterDeviceObject);
if (DbcContext->ControllerSig == DBC_ACPI_CONTROLLER_SIG && topologyMap) { // ACPI dbc
// PDO must be a child or parent of the controller
irb.u.Get1394AddressFromDeviceObject.fulFlags = 0; irb.FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT; ntStatus = DBCLASS_SyncSubmitIrb(deviceExtension->TopOfStackDeviceObject, &irb);
DBCLASS_KdPrint((2, "'GetLocalNodeId() = (%08X)\n", ntStatus)); linkNodeId = irb.u.Get1394AddressFromDeviceObject.NodeAddress.NA_Node_Number; if (DBCLASS_IsNodeConnectedToLink(DbcContext, topologyMap, nodeId, linkNodeId)) { ntStatus = STATUS_SUCCESS; } else { ntStatus = STATUS_DEVICE_NOT_CONNECTED; } } else { // USB dbc
PNODE_DEVICE_EXTENSION linkExtension; // USB dbc
// PDO must be a child or parent of the link
DBCLASS_ASSERT(DbcContext->LinkDeviceObject); linkExtension = DbcContext->LinkDeviceObject->DeviceExtension; linkNodeId = linkExtension->NodeAddress.NA_Node_Number; DBCLASS_ASSERT(RtlCompareMemory(&DbcContext->SubsystemDescriptor.guid1394Link[0], &linkExtension->ConfigRom->CR_Node_UniqueID[0], 8) == 8);
if(topologyMap) { if (DBCLASS_IsNodeConnectedToLink(DbcContext, topologyMap, nodeId, linkNodeId)) { ntStatus = STATUS_SUCCESS; } else { ntStatus = STATUS_DEVICE_NOT_CONNECTED; } } }
return ntStatus; }
NTSTATUS DBCLASS_1394GetBusGuid( PDEVICE_OBJECT DeviceObject, PUCHAR BusGuid ) /*++
Routine Description:
Arguments:
Return Value:
NTSTATUS
--*/ { NTSTATUS ntStatus; BOOLEAN waitForIt = FALSE; IRB irb;
irb.u.GetLocalHostInformation.nLevel = GET_HOST_UNIQUE_ID; irb.FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO; irb.u.GetLocalHostInformation.Information = BusGuid; ntStatus = DBCLASS_SyncSubmitIrb(DeviceObject, &irb);
DBCLASS_KdPrint((2, "'GetBusGuid() = (%08X)\n", ntStatus)); #if DBG
DBCLASS_KdPrint((1, "'>Local Host GUID\n")); DBCLASS_KdPrintGuid(1, BusGuid); #endif
return ntStatus; }
NTSTATUS DBCLASS_1394BusFilterDispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp, PBOOLEAN Handled ) /*++
Routine Description:
Arguments:
Return Value:
NTSTATUS
--*/ { PIO_STACK_LOCATION irpStack; NTSTATUS ntStatus; PDEVICE_EXTENSION deviceExtension; BOOLEAN waitForIt = FALSE; UCHAR busGuid1394[8]; deviceExtension = DeviceObject->DeviceExtension; ntStatus = Irp->IoStatus.Status; *Handled = FALSE;
LOGENTRY(LOG_MISC, '13b>', 0, DeviceObject, Irp); ntStatus = Irp->IoStatus.Status; irpStack = IoGetCurrentIrpStackLocation (Irp);
DBCLASS_KdPrint((1, "'(dbfilter)(bus)(1394)IRP_MJ_ (%08X) IRP_MN_ (%08X)\n", irpStack->MajorFunction, irpStack->MinorFunction));
switch (irpStack->MajorFunction) {
case IRP_MJ_PNP: switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: DBCLASS_KdPrint((1, "'(dbfilter)(bus)(1394)IRP_MN_START_DEVICE\n")); break; case IRP_MN_STOP_DEVICE: DBCLASS_KdPrint((1, "'(dbfilter)(bus)(1394)IRP_MN_STOP_DEVICE\n")); break; case IRP_MN_REMOVE_DEVICE: DBCLASS_KdPrint((1, "'(dbfilter)(bus)(1394)IRP_MN_REMOVE_DEVICE\n"));
DBCLASS_RemoveBusFilterMDOFromList(DeviceObject);
IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
IoDeleteDevice (DeviceObject); DBCLASS_KdPrint((1, "'REMOVE DB Filter on 1394 BUS\n")); break; case IRP_MN_QUERY_DEVICE_RELATIONS: DBCLASS_KdPrint((1, "'(dbfilter)(bus)(1394)IRP_MN_QUERY_DEVICE_RELATIONS\n"));
*Handled = TRUE; if (irpStack->Parameters.QueryDeviceRelations.Type == BusRelations) {
DBCLASS_KdPrint((1,"'>>QBR 1394 BUS\n")); IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent(&deviceExtension->QBusRelations1394Event, NotificationEvent, FALSE);
// Set up a completion routine to handle marking the IRP.
IoSetCompletionRoutine(Irp, DBCLASS_1394QBusRelationsComplete, DeviceObject, TRUE, TRUE, TRUE); waitForIt = TRUE; } else { IoSkipCurrentIrpStackLocation(Irp); }
// Now Pass down the IRP
deviceExtension->QBusRelations1394Success = FALSE;
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
if (waitForIt) { NTSTATUS status;
status = KeWaitForSingleObject(&deviceExtension->QBusRelations1394Event, Suspended, KernelMode, FALSE, NULL);
// let's see if the call down the stack failed
if(!deviceExtension->QBusRelations1394Success) { IoCompleteRequest(Irp, IO_NO_INCREMENT); break; }
DBCLASS_KdPrint((1, "'**** Searching for Device Bay PDOs \n"));
//
// get the bus guid
//
if (NT_SUCCESS(DBCLASS_1394GetBusGuid( deviceExtension->TopOfStackDeviceObject, &busGuid1394[0]))) {
PDEVICE_RELATIONS deviceRelations; ULONG i; deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information;
// loop thru DOs finding a DBC links
for (i=0; i< deviceRelations->Count; i++) { PDEVICE_EXTENSION mdo1394DeviceExtension; PDEVICE_OBJECT mdo1394;
// should always be found
mdo1394 = DBCLASS_FindDevicePdo(deviceRelations->Objects[i]);
if(!mdo1394) continue; mdo1394DeviceExtension = mdo1394->DeviceExtension;
DBCLASS_Find1394DbcLinks( mdo1394DeviceExtension->PhysicalDeviceObject);
} // loop through PDO list
// and try to find the controllers
DBCLASS_KdPrint((1, "'**>> DevRel Count (%08X)\n", deviceRelations->Count));
for (i=0; i< deviceRelations->Count; i++) { PDEVICE_EXTENSION mdo1394DeviceExtension; PDEVICE_OBJECT mdo1394; PDEVICE_OBJECT DevicePDO; PNODE_DEVICE_EXTENSION nodeExtension; LOGENTRY(LOG_MISC, 'FCQB', deviceRelations->Objects[i], i, 0);
// should always be found
mdo1394 = DBCLASS_FindDevicePdo(deviceRelations->Objects[i]);
if(!mdo1394) continue;
mdo1394DeviceExtension = mdo1394->DeviceExtension;
DevicePDO = mdo1394DeviceExtension->PhysicalDeviceObject;
nodeExtension = DevicePDO->DeviceExtension;
DBCLASS_KdPrint((1, "'****>> MDO (%08X) DbcContext (%08X) DrvObj (%08X) DevObj (%08X) PhysDevObj (%08X)\n", mdo1394, mdo1394DeviceExtension->DbcContext, deviceExtension->DriverObject, DeviceObject, mdo1394DeviceExtension->PhysicalDeviceObject));
// if this is a "virtual" device, just skip it
if(nodeExtension->Tag == VIRTUAL_DEVICE_EXTENSION_TAG) { DBCLASS_KdPrint((1, "'****> Virtual 1394 Device\n")); continue; }
DBCLASS_KdPrint((1, "'****>> NodeNumber (%08X) BusNumber (%08X) DevObj (%08X) PortDevObj (%08X)\n", nodeExtension->NodeAddress.NA_Node_Number, nodeExtension->NodeAddress.NA_Bus_Number, nodeExtension->DeviceObject, nodeExtension->PortDeviceObject));
if (mdo1394DeviceExtension->DbcContext == NULL) { mdo1394DeviceExtension->DbcContext = DBCLASS_FindController1394DevicePdo( deviceExtension->DriverObject, DeviceObject, mdo1394DeviceExtension->PhysicalDeviceObject, &busGuid1394[0]); }
// this PDO is associated with a controller
// see if is really a device bay device
DBCLASS_KdPrint((1, "'****> Check 1394 Device\n")); if (mdo1394DeviceExtension->DbcContext) { PDBC_CONTEXT dbcContext; USHORT bay = 0;
DBCLASS_KdPrint((1, "'****>> DBC detected on bus\n"));
DBCLASS_KdPrint((2, "'DbcContext (%08X) PhyDevObj (%08X)\n", mdo1394DeviceExtension->DbcContext, mdo1394DeviceExtension->PhysicalDeviceObject));
dbcContext = mdo1394DeviceExtension->DbcContext; bay = DBCLASS_GetBayFor1394Pdo( DeviceObject, mdo1394DeviceExtension->DbcContext, mdo1394DeviceExtension->PhysicalDeviceObject);
if (bay) { // This is device bay device
dbcContext->BayInformation[bay].DeviceFilterObject = mdo1394;
mdo1394DeviceExtension->Bay = bay; DBCLASS_KdPrint((1, "'****>>> 1394 PDO(%x) is in BAY[%d]\n", mdo1394DeviceExtension->PhysicalDeviceObject, bay));
// Notify PNP that this Device object
// is tied to the controller PDO
//TEST_TRAP();
IoInvalidateDeviceRelations(dbcContext->ControllerPdo, RemovalRelations); } else { // not a device bay device
mdo1394DeviceExtension->Bay = 0; DBCLASS_KdPrint((1, "'****>>> 1394 PDO(%x) is not a DB device\n", mdo1394DeviceExtension->PhysicalDeviceObject)); } } else { // no DBC phy link on this bus therefore this is
// not a device bay device
DBCLASS_KdPrint( (1, "'****>> No DBC detected on bus\n")); mdo1394DeviceExtension->Bay = 0; DBCLASS_KdPrint((1, "'****>>> 1394 PDO(%x) is not a DB device\n", mdo1394DeviceExtension->PhysicalDeviceObject)); } #if DBG
// dump the guid for this PDO
{ PNODE_DEVICE_EXTENSION nodeExtension; nodeExtension = mdo1394DeviceExtension->PhysicalDeviceObject->DeviceExtension; DBCLASS_KdPrint((2, "'****>>>> 1394 PDO GUID\n")); DBCLASS_KdPrintGuid(2, (PUCHAR)&nodeExtension->ConfigRom->CR_Node_UniqueID[0]); } #endif
DBCLASS_KdPrint((2, "'****>>>>> FC-QBR 1394 PDO[%d] %x DbcContext %x\n", i, deviceRelations->Objects[i], mdo1394DeviceExtension->DbcContext)); } }
IoCompleteRequest(Irp, IO_NO_INCREMENT); }
break; } /* irpStack->MinorFunction */ break; } /* irpStack->MajorFunction */
LOGENTRY(LOG_MISC, '13b<', 0, DeviceObject, 0); return ntStatus; }
|