/*++ Copyright (C) Microsoft Corporation, 1999 - 1999 Module Name: sbp2kdx.c Abstract Kernel debugger extension dll for sbp2port.sys (1394 sbp2 protocol driver) Author: Dan Knudson (dankn) 25 Jun 1999 Revision History: --*/ #include #include #include #include #include #include #include #include #include #include // // Utility routine prototypes // void DisplayAddressContext( char *Name, PADDRESS_CONTEXT Context, char *Indent ); void DisplayAsyncContextFlags( ULONG Flags ); void DisplayDeviceFlags( ULONG Flags ); void DisplayDeviceInformation( PDEVICE_INFORMATION Info, ULONG Index ); void DisplayLeaf( char *Name, PTEXTUAL_LEAF Leaf, char *Indent ); void DisplayStatusFifoBlock( char *Name, PSTATUS_FIFO_BLOCK Block ); // // Global variables // char Indent0[] = "", Indent1[] = " ", Indent2[] = " "; EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 }; WINDBG_EXTENSION_APIS ExtensionApis; USHORT SavedMajorVersion; USHORT SavedMinorVersion; BOOLEAN Verbose, OrbFields; char *Help[] = { "\n", " *** SBP2PORT.SYS Debugger Extensions ***\n\n", "Command Displays...\n", "---------------------------------------------------------------\n", "arc async request context\n", "fdoext [-v] fdo device extension (-v = verbose)\n", "help this\n", "pdoext [-v] [-o] pdo device extension (-o = Orb fields)\n\n", "NOTE: ' !devnode 0 1 ohci1394 ' shows the pdo device stack\n", "NOTE: pdoext.BusFdo shows the fdo address\n", "\n", NULL }; BOOL WINAPI DLLMain( HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved ) { return (TRUE); } void WinDbgExtensionDllInit( PWINDBG_EXTENSION_APIS pExtensionApis, USHORT MajorVersion, USHORT MinorVersion ) { ExtensionApis = *pExtensionApis; SavedMajorVersion = MajorVersion; SavedMinorVersion = MinorVersion; return; } void CheckVersion( void ) { // no-op? } LPEXT_API_VERSION ExtensionApiVersion( void ) { return (&ApiVersion); } DECLARE_API(arc) { ULONG bytesRead; ULONG_PTR p; ASYNC_REQUEST_CONTEXT context, *pcontext; dprintf ("\n"); if (args[0] == 0) { dprintf ("usage: arc
\n\n"); return; } sscanf (args, "%lx", &p); if (!ReadMemory (p, &context, sizeof (context), &bytesRead)) { dprintf ("Unable to read context\n\n"); return; } if (bytesRead < sizeof (context)) { dprintf( "Only read %d bytes of context, expected %d\n\n", bytesRead, sizeof (context) ); return; } OrbFields = TRUE; // so address context below will get displayed // BUGUG validation? like : if (context.Tag != SBP2_ASYNC_CONTEXT_TAG) pcontext = (PASYNC_REQUEST_CONTEXT) p; dprintf ("&OrbList = x%p\n", &pcontext->OrbList); dprintf (" Flink = x%p\n", context.OrbList.Flink); dprintf (" Blink = x%p\n", context.OrbList.Blink); dprintf ("&LookasideList = x%p\n", &pcontext->LookasideList); dprintf (" Next = x%p\n", context.LookasideList.Next); dprintf ("Tag = x%x\n", context.Tag); dprintf ("DeviceObject = x%p\n", context.DeviceObject); dprintf ("Srb = x%p\n", context.Srb); DisplayAsyncContextFlags (context.Flags); dprintf ("CmdOrb = x%p\n", context.CmdOrb); dprintf ("CmdOrbAddress = x%x%08x\n", context.CmdOrbAddress.u.HighQuad, context.CmdOrbAddress.u.LowQuad); dprintf ("PartialMdl = x%p\n", context.PartialMdl); dprintf ("RequestMdl = x%p\n", context.RequestMdl); dprintf ("PageTableContext\n"); dprintf (" MaxPages = x%x\n", context.PageTableContext.MaxPages); dprintf (" NumberOfPages = x%x\n", context.PageTableContext.NumberOfPages); dprintf (" PageTable = x%p\n", context.PageTableContext.PageTable); DisplayAddressContext (" AddressContext\n", &context.PageTableContext.AddressContext, Indent2); dprintf ("DataMappingHandle = x%p\n", context.DataMappingHandle); dprintf ("Packet = x%p\n", context.Packet); dprintf ("\n"); } DECLARE_API(fdoext) { ULONG bytesRead, i; ULONG_PTR p; DEVICE_OBJECT obj; FDO_DEVICE_EXTENSION ext; dprintf ("\n"); // // Get the fdo pointer & any args from the cmd line // if (args[0] == 0) { dprintf ("usage: fdoext [-v]\n\n"); return; } sscanf (args, "%lx", &p); Verbose = (BOOLEAN) strstr (args, "-v"); // // Read the DEVICE_OBJECT to retrieve the device extension pointer // if (!ReadMemory (p, &obj, sizeof (obj), &bytesRead)) { dprintf ("Unable to read pdo\n\n"); return; } if (bytesRead < sizeof (obj)) { dprintf( "Only read %d bytes of pdo, expected %d\n\n", bytesRead, sizeof (obj) ); return; } p = (ULONG_PTR) obj.DeviceExtension; // // Read the device extension // if (!ReadMemory (p, &ext, sizeof (ext), &bytesRead)) { dprintf ("Unable to read pdo extension\n\n"); return; } if (bytesRead < sizeof (ext)) { dprintf( "Only read %d bytes of fdo extension, expected %d\n\n", bytesRead, sizeof (ext) ); return; } if (ext.Type != SBP2_FDO) { dprintf ("Not a fdo extension (ext.Type=x%x)\n\n", ext.Type); return; } // // Display the extension fields // dprintf ("DeviceObject = x%p\n", ext.DeviceObject); dprintf ("LowerDeviceObject = x%p\n", ext.LowerDeviceObject); DisplayDeviceFlags (ext.DeviceFlags); dprintf ("ConfigRom\n"); dprintf (" CR_Info = x%x\n", ext.ConfigRom.CR_Info); dprintf (" CR_Signiture = x%x\n", ext.ConfigRom.CR_Signiture); dprintf (" CR_BusInfoBlockCaps = x%x\n", ext.ConfigRom.CR_BusInfoBlockCaps); dprintf (" CR_Node_UniqueID[0] = x%x\n", ext.ConfigRom.CR_Node_UniqueID[0]); dprintf (" CR_Node_UniqueID[1] = x%x\n", ext.ConfigRom.CR_Node_UniqueID[1]); dprintf (" CR_Root_Info = x%x\n", ext.ConfigRom.CR_Root_Info); for (i = 0; i < SBP2_MAX_LUNS_PER_NODE; i++) { DisplayDeviceInformation (ext.DeviceList + i, i); } dprintf ("DeviceListSize = x%x\n", ext.DeviceListSize); DisplayLeaf ("VendorLeaf", ext.VendorLeaf, Indent1); dprintf ("MaxClassTransferSize = x%x\n", ext.MaxClassTransferSize); dprintf ("Sbp2ObjectDirectory = x%p\n", ext.Sbp2ObjectDirectory); dprintf ("\n"); } DECLARE_API(help) { ULONG i; for (i = 0; Help[i]; i++) { dprintf (Help[i]); } return; } DECLARE_API(pdoext) { ULONG bytesRead; ULONG_PTR p; DEVICE_OBJECT obj; DEVICE_EXTENSION ext; dprintf ("\n"); // // Get the fdo pointer & any args from the cmd line // if (args[0] == 0) { dprintf ("usage: pdoext [-v]\n\n"); return; } sscanf (args, "%lx", &p); Verbose = (BOOLEAN) strstr (args, "-v"); OrbFields = (BOOLEAN) strstr (args, "-o"); // // Read the DEVICE_OBJECT to retrieve the device extension pointer // if (!ReadMemory (p, &obj, sizeof (obj), &bytesRead)) { dprintf ("Unable to read pdo\n\n"); return; } if (bytesRead < sizeof (obj)) { dprintf( "Only read %d bytes of pdo, expected %d\n\n", bytesRead, sizeof (obj) ); return; } p = (ULONG_PTR) obj.DeviceExtension; // // Read the device extension // if (!ReadMemory (p, &ext, sizeof (ext), &bytesRead)) { dprintf ("Unable to read pdo extension\n\n"); return; } if (bytesRead < sizeof (ext)) { dprintf( "Only read %d bytes of pdo extension, expected %d\n\n", bytesRead, sizeof (ext) ); return; } if (ext.Type != SBP2_PDO) { dprintf ("Not a pdo extension (ext.Type=x%x)\n\n", ext.Type); return; } // // Display the extension fields // dprintf ("DeviceObject = x%p\n", ext.DeviceObject); dprintf ("LowerDeviceObject = x%p\n", ext.LowerDeviceObject); DisplayDeviceFlags (ext.DeviceFlags); dprintf ("BusFdo = x%p\n", ext.BusFdo); DisplayDeviceInformation (ext.DeviceInfo, 0xffffffff); dprintf ("MaxOrbListDepth = %d\n", ext.MaxOrbListDepth); dprintf ("&PendingOrbList = x%p\n", &((PDEVICE_EXTENSION) p)->PendingOrbList); if (Verbose) { dprintf (" Flink = x%p\n", ext.PendingOrbList.Flink); dprintf (" Blink = x%p\n", ext.PendingOrbList.Blink); } dprintf ("OrbListDepth = %d\n", ext.OrbListDepth); dprintf ("CurrentKey = x%x\n", ext.CurrentKey); dprintf ("LastFetchedContext = x%p\n", ext.LastFetchedContext); dprintf ("NextContextToFree = x%p\n", ext.NextContextToFree); dprintf ("DevicePowerState = %d\n", (ULONG) ext.DevicePowerState); dprintf ("SystemPowerState = %d\n", (ULONG) ext.SystemPowerState); dprintf ("PowerDeferredIrp = x%p\n", ext.PowerDeferredIrp); dprintf ("DeferredPowerRequest = x%p\n", ext.DeferredPowerRequest); dprintf ("PagingPathCount = %d\n", (ULONG) ext.PagingPathCount); dprintf ("HibernateCount = %d\n", (ULONG) ext.HibernateCount); dprintf ("CrashDumpCount = %d\n", (ULONG) ext.CrashDumpCount); dprintf ("HandleCount = %d\n", (ULONG) ext.HandleCount); dprintf ("IdleCounter = x%p\n", &((PDEVICE_EXTENSION) p)->IdleCounter); // DueTime dprintf ("Reserved = x%x (%d)\n", ext.Reserved, ext.Reserved); dprintf ("LastTransactionStatus = x%x\n", ext.LastTransactionStatus); dprintf ("ReservedMdl = x%p\n", ext.ReservedMdl); dprintf ("&InquiryData = x%p\n", &((PDEVICE_EXTENSION) p)->InquiryData); dprintf ("InitiatorAddressId = x%d\n", ext.InitiatorAddressId); dprintf ("CurrentGeneration = x%d\n", ext.CurrentGeneration); dprintf ("MaxControllerPhySpeed = x%d\n", ext.MaxControllerPhySpeed); dprintf ("OrbReadPayloadMask = x%d\n", (ULONG) ext.OrbReadPayloadMask); dprintf ("OrbWritePayloadMask = x%d\n", (ULONG) ext.OrbWritePayloadMask); if (Verbose) { dprintf ("HostControllerInformation\n"); dprintf (" HostCapabilities = x%d\n", ext.HostControllerInformation.HostCapabilities); dprintf (" MaxAsyncReadReq = x%d\n", ext.HostControllerInformation.MaxAsyncReadRequest); dprintf (" MaxAsyncWriteReq = x%d\n", ext.HostControllerInformation.MaxAsyncWriteRequest); dprintf ("HostRoutineAPI\n"); dprintf (" PhysAddrMappingRtn = x%p\n", ext.HostRoutineAPI.PhysAddrMappingRoutine); dprintf (" Context = x%p\n", ext.HostRoutineAPI.Context); } if (OrbFields) { dprintf ("TaskOrb\n"); dprintf (" OrbAddress = x%x%08x\n", ext.TaskOrb.OrbAddress.u.HighQuad, ext.TaskOrb.OrbAddress.u.LowQuad); dprintf (" Reserved = x%x%08x\n", ext.TaskOrb.Reserved.u.HighQuad, ext.TaskOrb.Reserved.u.LowQuad); dprintf (" OrbInfo = x%x\n", ext.TaskOrb.OrbInfo); dprintf (" Reserved1 = x%x\n", ext.TaskOrb.Reserved1); dprintf (" StatusBlockAddress = x%x%08x\n", ext.TaskOrb.StatusBlockAddress.u.HighQuad, ext.TaskOrb.StatusBlockAddress.u.LowQuad); dprintf ("ManagementOrb\n"); dprintf (" Reserved[0] = x%x%08x\n", ext.ManagementOrb.Reserved[0].u.HighQuad, ext.ManagementOrb.Reserved[0].u.LowQuad); dprintf (" Reserved[1] = x%x%08x\n", ext.ManagementOrb.Reserved[1].u.HighQuad, ext.ManagementOrb.Reserved[1].u.LowQuad); dprintf (" OrbInfo = x%x\n", ext.ManagementOrb.OrbInfo); dprintf (" Reserved1 = x%x\n", ext.ManagementOrb.Reserved1); dprintf (" StatusBlockAddress = x%x%08x\n", ext.ManagementOrb.StatusBlockAddress.u.HighQuad, ext.ManagementOrb.StatusBlockAddress.u.LowQuad); } DisplayAddressContext ("TaskOrbContext\n", &ext.TaskOrbContext, Indent1); DisplayAddressContext ("ManagementOrbContext\n", &ext.ManagementOrbContext, Indent1); DisplayStatusFifoBlock ("ManagementOrbStatusBlock\n", &ext.ManagementOrbStatusBlock); DisplayAddressContext ("ManagementOrbStatusContext\n", &ext.ManagementOrbStatusContext, Indent1); DisplayStatusFifoBlock ("TaskOrbStatusBlock\n", &ext.TaskOrbStatusBlock); DisplayAddressContext ("TaskOrbStatusContext\n", &ext.TaskOrbStatusContext, Indent1); DisplayAddressContext ("GlobalStatusContext\n", &ext.GlobalStatusContext, Indent1); if (Verbose) { dprintf ("LoginResponse\n"); dprintf (" LengthAndLoginId = x%x\n", ext.LoginResponse.LengthAndLoginId); dprintf (" Csr_Off_High = x%x\n", ext.LoginResponse.Csr_Off_High); dprintf (" Csr_Off_Low = x%x\n", ext.LoginResponse.Csr_Off_Low); dprintf (" Reserved = x%x\n", ext.LoginResponse.Reserved); } DisplayAddressContext ("LoginRespContext\n", &ext.LoginRespContext, Indent1); if (Verbose) { dprintf ("&QueryLoginResponse = x%p\n", &((PDEVICE_EXTENSION) p)->QueryLoginResponse); dprintf (" LengthAndNumLogins = x%x\n", ext.QueryLoginResponse.LengthAndNumLogins); dprintf (" Elements[0]\n"); dprintf (" NodeAndLoginId = x%x\n", ext.QueryLoginResponse.Elements[0].NodeAndLoginId); dprintf (" EUI64 = x%x%08x\n", ext.QueryLoginResponse.Elements[0].EUI64.u.HighQuad, ext.QueryLoginResponse.Elements[0].EUI64.u.LowQuad); } // there's 3 more elements in the Elements[] array above we could display DisplayAddressContext ("QueryLoginRespContext\n", &ext.QueryLoginRespContext, Indent1); dprintf ("&StatusFifoListHead = x%p\n", &((PDEVICE_EXTENSION) p)->StatusFifoListHead); // KSPIN_LOCK StatusFifoLock; dprintf ("StatusFifoBase = x%p\n", ext.StatusFifoBase); dprintf ("&FreeContextListHead = x%p\n", &((PDEVICE_EXTENSION) p)->FreeContextListHead); dprintf ("&BusReqContxtListHead = x%p\n", &((PDEVICE_EXTENSION) p)->BusRequestContextListHead); dprintf ("&BusReqIrpIrbListHead = x%p\n", &((PDEVICE_EXTENSION) p)->BusRequestIrpIrbListHead); // KSPIN_LOCK BusRequestLock; // KSPIN_LOCK FreeContextLock; dprintf ("AsyncContextBase = x%p\n", ext.AsyncContextBase); DisplayAddressContext ("OrbPoolContext\n", &ext.OrbPoolContext, Indent1); // KSPIN_LOCK ExtensionDataSpinLock; // KDPC DeviceManagementTimeoutDpc; // KTIMER DeviceManagementTimer; dprintf ("\n"); } // // Utility funcs // void DisplayAddressContext( char *Name, PADDRESS_CONTEXT pContext, char *Indent ) { char *postIndent = (Indent == Indent1 ? Indent1 : Indent0); if (!OrbFields) { return; } dprintf (Name); dprintf ("%sDeviceObject%s = x%p\n", Indent, postIndent, pContext->DeviceObject); dprintf ("%sAddress%s = x%x%08x\n", Indent, postIndent, pContext->Address.u.HighQuad, pContext->Address.u.LowQuad); dprintf ("%sReservedAddr%s = x%x%08x\n", Indent, postIndent, pContext->ReservedAddr.u.HighQuad, pContext->ReservedAddr.u.LowQuad); dprintf ("%sAddressHandle%s = x%p\n", Indent, postIndent, pContext->AddressHandle); dprintf ("%sRequestMdl%s = x%p\n", Indent, postIndent, pContext->RequestMdl); dprintf ("%sTransactionType%s = x%x\n", Indent, postIndent, pContext->TransactionType); dprintf ("%sReserved%s = x%p\n", Indent, postIndent, pContext->Reserved); } void DisplayAsyncContextFlags( ULONG Flags ) { ULONG i; char *flagNames[] = { "TIMER_STARTED", "COMPLETED", "PAGE_ALLOC", "DATA_ALLOC", NULL }; dprintf ("DeviceFlags = x%x, ", Flags); for (i = 0; Flags && flagNames[i]; i++) { if (Flags & (1 << i)) { dprintf (flagNames[i]); Flags &= ~(1 << i); } } if (Flags) { dprintf ("", Flags); } dprintf ("\n"); } void DisplayDeviceFlags( ULONG Flags ) { ULONG i; char *flagNames[] = { "STOPPED ", "RESET_IN_PROGRESS ", "REMOVED ", "LOGIN_IN_PROGRESS ", "RECONNECT ", "CLAIMED ", "INITIALIZING ", "QUEUE_LOCKED ", "SPC_CMD_SET ", "INITIALIZED ", "REMOVE_PENDING ", "DEVICE_FAILED ", NULL }; dprintf ("DeviceFlags = x%x, ", Flags); for (i = 0; Flags && flagNames[i]; i++) { if (Flags & (1 << i)) { dprintf (flagNames[i]); Flags &= ~(1 << i); } } if (Flags) { dprintf ("", Flags); } dprintf ("\n"); } void DisplayDeviceInformation( PDEVICE_INFORMATION Info, ULONG Index ) { ULONG bytesRead; DEVICE_INFORMATION info; if (Index == 0xffffffff) { // // Called from pdoext(), Info is simple a debugee pointer, need // to read in the data // dprintf ("DeviceInfo = x%p\n", Info); if (!Verbose) { return; } if (!ReadMemory ((ULONG_PTR) Info, &info, sizeof (info), &bytesRead)) { dprintf (" \n"); return; } if (bytesRead < sizeof (info)) { dprintf( " \n", bytesRead, sizeof (info) ); return; } Info = &info; } else { // // Called from fdoext(), Info data is valid // if (!Verbose || !Info->DeviceObject) { return; } dprintf ("DeviceInfo[%d]\n", Index); } dprintf (" DeviceObject = x%p\n", Info->DeviceObject); dprintf (" Lun = x%x\n", Info->Lun); dprintf (" CmdSetId = x%x\n", Info->CmdSetId); dprintf (" UnitCharactristics = x%x\n", Info->UnitCharacteristics); dprintf (" MgmtAgentBaseReg = x%x%08x\n", Info->ManagementAgentBaseReg.u.HighQuad, Info->ManagementAgentBaseReg.u.LowQuad); dprintf (" CsrRegisterBase = x%x%08x\n", Info->CsrRegisterBase.u.HighQuad, Info->CsrRegisterBase.u.LowQuad); dprintf (" ConfigRom = x%p\n", Info->ConfigRom); // display crom DisplayLeaf (" ModelLeaf", Info->ModelLeaf, Indent2); DisplayLeaf (" VendorLeaf", Info->VendorLeaf, Indent2); dprintf (" GenericName = %s\n", Info->GenericName); dprintf (" MaxClassXferSize = x%x\n", Info->MaxClassTransferSize); } void DisplayLeaf( char *Name, PTEXTUAL_LEAF Leaf, char *Indent ) { char *postIndent = (Indent == Indent1 ? Indent1 : Indent0); BYTE buf[sizeof (TEXTUAL_LEAF) + SBP2_MAX_TEXT_LEAF_LENGTH]; ULONG bytesRead, length; ULONG_PTR p = (ULONG_PTR) Leaf; PTEXTUAL_LEAF leaf = (PTEXTUAL_LEAF) buf; dprintf ("%-22.22s= x%p\n", Name, p); if (Leaf && Verbose) { // // First read in, byte swap, & display the fixed size of the leaf // if (!ReadMemory (p, buf, sizeof (*leaf), &bytesRead)) { dprintf (" \n"); return; } if (bytesRead < sizeof (*leaf)) { dprintf( " \n", bytesRead, sizeof (buf) ); return; } { ULONG *p = (ULONG *) &leaf->TL_CRC; *p = bswap (*p); } leaf->TL_Spec_Id = bswap (leaf->TL_Spec_Id); leaf->TL_Language_Id = bswap (leaf->TL_Language_Id); dprintf ("%sTL_CRC%s = x%x\n", Indent, postIndent, (ULONG) leaf->TL_CRC); dprintf ("%sTL_Length%s = x%x\n", Indent, postIndent, (ULONG) leaf->TL_Length); dprintf ("%sTL_Spec_Id%s = x%x\n", Indent, postIndent, leaf->TL_Spec_Id); dprintf ("%sTL_Language_Id%s = x%x\n", Indent, postIndent, leaf->TL_Language_Id); // // Now read in the whole leaf (but not more than will fit in // our stack buffer). Display only the first 50 chars // length = (ULONG) (leaf->TL_Length * sizeof (QUADLET)) + sizeof (*leaf) - sizeof (leaf->TL_Data); length = (length > sizeof (buf) ? sizeof (buf) : length); if (!ReadMemory (p, buf, length, &bytesRead)) { dprintf (" \n"); return; } if (bytesRead < sizeof (*leaf)) { dprintf( " \n", bytesRead, sizeof (buf) ); return; } leaf->TL_Spec_Id = bswap (leaf->TL_Spec_Id); if (leaf->TL_Spec_Id & 0x80000000) // unicode { dprintf ("%sTL_Data%s = %ws\n", Indent, postIndent, &leaf->TL_Data); } else // ascii { dprintf ("%sTL_Data%s = %s\n", Indent, postIndent, &leaf->TL_Data); } } } void DisplayStatusFifoBlock( char *Name, PSTATUS_FIFO_BLOCK Block ) { if (!OrbFields) { return; } dprintf (Name); dprintf (" AddressAndStatus = x%x%08x\n", Block->AddressAndStatus.u.HighQuad, Block->AddressAndStatus.u.LowQuad); dprintf (" Contents[0] = x%x%08x\n", Block->Contents[0].u.HighQuad, Block->Contents[0].u.LowQuad); dprintf (" Contents[1] = x%x%08x\n", Block->Contents[1].u.HighQuad, Block->Contents[1].u.LowQuad); dprintf (" Contents[2] = x%x%08x\n", Block->Contents[2].u.HighQuad, Block->Contents[2].u.LowQuad); }