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.
443 lines
11 KiB
443 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
activate.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code to prepare an SD card in a given
|
|
slot for use. This is done when the host is started, after
|
|
device insertions, and after a power up transition.
|
|
|
|
Authors:
|
|
|
|
Neil Sandlin (neilsa) Jan 1, 2002
|
|
|
|
Environment:
|
|
|
|
Kernel mode only
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
|
|
//
|
|
// Internal References
|
|
//
|
|
|
|
|
|
|
|
VOID
|
|
SdbusActivatePowerUpComplete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
VOID
|
|
SdbusActivateIdentifyPhase1Complete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
VOID
|
|
SdbusActivateIdentifyPhase2Complete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
VOID
|
|
SdbusActivateInitializeCardComplete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
);
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
VOID
|
|
SdbusActivateSocket(
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PSDBUS_ACTIVATE_COMPLETION_ROUTINE CompletionRoutine,
|
|
IN PVOID Context
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Fdo - Pointer to the device object for the host controller
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
|
|
PSD_WORK_PACKET workPacket1 = NULL, workPacket2 = NULL, workPacket3 = NULL, workPacket4 = NULL;
|
|
BOOLEAN cardInSlot;
|
|
BOOLEAN callCompletion;
|
|
PSD_ACTIVATE_CONTEXT activateContext;
|
|
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x activate socket START\n", Fdo));
|
|
|
|
activateContext = ExAllocatePool(NonPagedPool, sizeof(SD_ACTIVATE_CONTEXT));
|
|
|
|
if (!activateContext) {
|
|
ASSERT(activateContext != NULL);
|
|
return;
|
|
}
|
|
|
|
activateContext->CompletionRoutine = CompletionRoutine;
|
|
activateContext->Context = Context;
|
|
|
|
try{
|
|
|
|
cardInSlot = (*(fdoExtension->FunctionBlock->DetectCardInSocket))(fdoExtension);
|
|
|
|
if (!cardInSlot) {
|
|
|
|
if (fdoExtension->SocketState != SOCKET_EMPTY) {
|
|
IoInvalidateDeviceRelations(fdoExtension->Pdo, BusRelations);
|
|
}
|
|
//ISSUE: implement synchronization
|
|
fdoExtension->SocketState = SOCKET_EMPTY;
|
|
|
|
callCompletion = TRUE;
|
|
status = STATUS_SUCCESS;
|
|
leave;
|
|
}
|
|
|
|
fdoExtension->SocketState = CARD_DETECTED;
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_POWER_ON,
|
|
SdbusActivatePowerUpComplete,
|
|
NULL,
|
|
&workPacket1);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_IDENTIFY_IO_DEVICE,
|
|
SdbusActivateIdentifyPhase1Complete,
|
|
NULL,
|
|
&workPacket2);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_IDENTIFY_MEMORY_DEVICE,
|
|
SdbusActivateIdentifyPhase2Complete,
|
|
NULL,
|
|
&workPacket3);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_INITIALIZE_CARD,
|
|
SdbusActivateInitializeCardComplete,
|
|
activateContext,
|
|
&workPacket4);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
workPacket1->NextWorkPacketInChain = workPacket2;
|
|
workPacket2->NextWorkPacketInChain = workPacket3;
|
|
workPacket3->NextWorkPacketInChain = workPacket4;
|
|
|
|
SdbusQueueWorkPacket(fdoExtension, workPacket1, WP_TYPE_SYSTEM);
|
|
|
|
callCompletion = FALSE;
|
|
|
|
} finally {
|
|
if (callCompletion) {
|
|
if (activateContext->CompletionRoutine) {
|
|
(*activateContext->CompletionRoutine)(Fdo, activateContext->Context, status);
|
|
}
|
|
if (workPacket1) {
|
|
ExFreePool(workPacket1);
|
|
}
|
|
if (workPacket2) {
|
|
ExFreePool(workPacket2);
|
|
}
|
|
if (workPacket3) {
|
|
ExFreePool(workPacket3);
|
|
}
|
|
if (workPacket4) {
|
|
ExFreePool(workPacket4);
|
|
}
|
|
ExFreePool(activateContext);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SdbusActivatePowerUpComplete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x activate PowerUp Complete\n", WorkPacket->FdoExtension->DeviceObject));
|
|
|
|
if (WorkPacket->NextWorkPacketInChain) {
|
|
WorkPacket->NextWorkPacketInChain->ChainedStatus = status;
|
|
}
|
|
ExFreePool(WorkPacket);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SdbusActivateIdentifyPhase1Complete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x activate Identify Phase1 Complete\n", WorkPacket->FdoExtension->DeviceObject));
|
|
|
|
if (WorkPacket->NextWorkPacketInChain) {
|
|
WorkPacket->NextWorkPacketInChain->ChainedStatus = status;
|
|
}
|
|
ExFreePool(WorkPacket);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SdbusActivateIdentifyPhase2Complete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Fdo - Pointer to the device object for the host controller
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = WorkPacket->FdoExtension;
|
|
PDEVICE_OBJECT Fdo = fdoExtension->DeviceObject;
|
|
PSD_ACTIVATE_CONTEXT activateContext = WorkPacket->CompletionContext;
|
|
BOOLEAN callCompletion;
|
|
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x activate Identify Phase2 Complete\n", WorkPacket->FdoExtension->DeviceObject));
|
|
|
|
ExFreePool(WorkPacket);
|
|
|
|
#if 0
|
|
try{
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
//
|
|
// If we get this far, we expect that there is at least one function detected
|
|
//
|
|
|
|
if (!fdoExtension->numFunctions && !fdoExtension->memFunction) {
|
|
callCompletion = TRUE;
|
|
SdbusDumpDbgLog();
|
|
status = STATUS_UNSUCCESSFUL;
|
|
leave;
|
|
}
|
|
|
|
//
|
|
// The card should be in the Identification state. Send a CMD3 to get the relative address,
|
|
// and to move the card to the standby state.
|
|
//
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_PASSTHRU,
|
|
SdbusActivateTransitionToStandbyCompletion,
|
|
activateContext,
|
|
&WorkPacket);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
WorkPacket->ExecutingSDCommand = TRUE;
|
|
WorkPacket->Cmd = SDCMD_SEND_RELATIVE_ADDR;
|
|
WorkPacket->ResponseType = SDCMD_RESP_6;
|
|
|
|
|
|
SdbusQueueWorkPacket(fdoExtension, WorkPacket, WP_TYPE_SYSTEM_PRIORITY);
|
|
|
|
callCompletion = FALSE;
|
|
} finally {
|
|
if (callCompletion) {
|
|
if (activateContext->CompletionRoutine) {
|
|
(*activateContext->CompletionRoutine)(Fdo, activateContext->Context, status);
|
|
}
|
|
ExFreePool(activateContext);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
VOID
|
|
SdbusActivateTransitionToStandbyCompletion(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Fdo - Pointer to the device object for the host controller
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = WorkPacket->FdoExtension;
|
|
PDEVICE_OBJECT Fdo = fdoExtension->DeviceObject;
|
|
PSD_ACTIVATE_CONTEXT activateContext = WorkPacket->CompletionContext;
|
|
BOOLEAN callCompletion;
|
|
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x activate TransitionToStandby COMPLETE %08x\n", Fdo, status));
|
|
|
|
try{
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
fdoExtension->RelativeAddr = WorkPacket->ResponseBuffer[0] & 0xFFFF0000;
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x relative addr %08x\n", Fdo, fdoExtension->RelativeAddr));
|
|
|
|
status = SdbusBuildWorkPacket(fdoExtension,
|
|
SDWP_INITIALIZE_CARD,
|
|
SdbusActivateInitializeCardComplete,
|
|
activateContext,
|
|
&workPacket);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
callCompletion = TRUE;
|
|
leave;
|
|
}
|
|
|
|
} else {
|
|
if (activateContext->CompletionRoutine) {
|
|
(*activateContext->CompletionRoutine)(Fdo, activateContext->Context, status);
|
|
}
|
|
ExFreePool(activateContext);
|
|
}
|
|
|
|
ExFreePool(WorkPacket);
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
VOID
|
|
SdbusActivateInitializeCardComplete(
|
|
IN PSD_WORK_PACKET WorkPacket,
|
|
IN NTSTATUS status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Fdo - Pointer to the device object for the host controller
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PFDO_EXTENSION fdoExtension = WorkPacket->FdoExtension;
|
|
PDEVICE_OBJECT Fdo = fdoExtension->DeviceObject;
|
|
PSD_ACTIVATE_CONTEXT activateContext = WorkPacket->CompletionContext;
|
|
|
|
DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x activate socket COMPLETE %08x\n", Fdo, status));
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
fdoExtension->SocketState = CARD_NEEDS_ENUMERATION;
|
|
IoInvalidateDeviceRelations(fdoExtension->Pdo, BusRelations);
|
|
} else {
|
|
DebugPrint((SDBUS_DEBUG_FAIL, "fdo %08x activate failure %08x\n", Fdo, status));
|
|
SdbusDumpDbgLog();
|
|
}
|
|
|
|
ExFreePool(WorkPacket);
|
|
|
|
if (activateContext->CompletionRoutine) {
|
|
(*activateContext->CompletionRoutine)(Fdo, activateContext->Context, status);
|
|
}
|
|
ExFreePool(activateContext);
|
|
}
|