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.
1433 lines
33 KiB
1433 lines
33 KiB
/*++
|
|
|
|
Copyright (c) 2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
toshiba.c
|
|
|
|
Abstract:
|
|
|
|
This module supplies functions that control the Toshiba SD controller.
|
|
Based on the Toshiba "Pelican3"
|
|
|
|
Author(s):
|
|
|
|
Neil Sandlin (neilsa) Jan 1 2002
|
|
|
|
Revisions:
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "toshiba.h"
|
|
|
|
//
|
|
// Internal References
|
|
//
|
|
|
|
VOID
|
|
ToshibaInitializeController(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
ToshibaInitializeFunction(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PPDO_EXTENSION PdoExtension
|
|
);
|
|
|
|
ULONG
|
|
ToshibaGetPendingEvents(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
ToshibaEnableEvent(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN ULONG EventMask
|
|
);
|
|
|
|
VOID
|
|
ToshibaDisableEvent(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN ULONG EventMask
|
|
);
|
|
|
|
VOID
|
|
ToshibaAcknowledgeEvent(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN ULONG EventMask
|
|
);
|
|
|
|
NTSTATUS
|
|
ToshibaSetPower(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN BOOLEAN Enable,
|
|
OUT PULONG pDelayTime
|
|
);
|
|
|
|
NTSTATUS
|
|
ToshibaResetHost(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN UCHAR Phase,
|
|
OUT PULONG pDelayTime
|
|
);
|
|
|
|
VOID
|
|
ToshibaSetLED(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN BOOLEAN Enable
|
|
);
|
|
|
|
VOID
|
|
ToshibaSetFunctionType(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN UCHAR FunctionType
|
|
);
|
|
|
|
BOOLEAN
|
|
ToshibaDetectCardInSocket(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
ToshibaIsWriteProtected(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
ToshibaCheckStatus(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
ToshibaSDCommand(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PSD_WORK_PACKET WorkPacket
|
|
);
|
|
|
|
NTSTATUS
|
|
ToshibaSDGetResponse(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PSD_WORK_PACKET WorkPacket
|
|
);
|
|
|
|
VOID
|
|
ToshibaStartBlockOperation(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
ToshibaSetBlockParameters(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT SectorCount
|
|
);
|
|
|
|
VOID
|
|
ToshibaEndBlockOperation(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
VOID
|
|
ToshibaReadDataPort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PUCHAR Buffer,
|
|
IN ULONG Length
|
|
);
|
|
|
|
VOID
|
|
ToshibaWriteDataPort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PUCHAR Buffer,
|
|
IN ULONG Length
|
|
);
|
|
|
|
UCHAR
|
|
ToshibaReadRegisterUchar(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register
|
|
);
|
|
|
|
USHORT
|
|
ToshibaReadRegisterUshort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register
|
|
);
|
|
|
|
VOID
|
|
ToshibaWriteRegisterUshort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register,
|
|
IN USHORT Data
|
|
);
|
|
|
|
ULONG
|
|
ToshibaReadRegisterUlong(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register
|
|
);
|
|
|
|
VOID
|
|
ToshibaWriteRegisterUlong(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register,
|
|
IN ULONG Data
|
|
);
|
|
|
|
|
|
//
|
|
// Internal Data
|
|
//
|
|
|
|
|
|
SD_FUNCTION_BLOCK ToshibaSupportFns = {
|
|
ToshibaInitializeController,
|
|
ToshibaInitializeFunction,
|
|
ToshibaSetPower,
|
|
ToshibaResetHost,
|
|
ToshibaSetLED,
|
|
ToshibaSetFunctionType,
|
|
ToshibaDetectCardInSocket,
|
|
ToshibaIsWriteProtected,
|
|
ToshibaCheckStatus,
|
|
ToshibaSDCommand,
|
|
ToshibaSDGetResponse,
|
|
ToshibaStartBlockOperation,
|
|
ToshibaSetBlockParameters,
|
|
ToshibaEndBlockOperation,
|
|
ToshibaReadDataPort,
|
|
ToshibaWriteDataPort,
|
|
ToshibaEnableEvent,
|
|
ToshibaDisableEvent,
|
|
ToshibaGetPendingEvents,
|
|
ToshibaAcknowledgeEvent
|
|
};
|
|
|
|
|
|
|
|
VOID
|
|
DebugDumpRegs(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
#if DBG
|
|
if (SdbusDebugMask & SDBUS_DEBUG_DUMP_REGS) {
|
|
USHORT i,j;
|
|
USHORT buffer[8];
|
|
USHORT offset;
|
|
USHORT count = 0;
|
|
ULONG skip = 0x03000000;
|
|
USHORT index;
|
|
|
|
offset = 0;
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
for (i = 0; i < 8; i++) {
|
|
index = offset + (i*2);
|
|
|
|
if (skip & (1 << (index/2))) {
|
|
buffer[i] = 0xFEFE;
|
|
} else {
|
|
buffer[i] = ToshibaReadRegisterUshort(FdoExtension, index);
|
|
}
|
|
count++;
|
|
}
|
|
DebugPrint((SDBUS_DEBUG_DUMP_REGS, "%04x: %04x %04x %04x %04x-%04x %04x %04x %04x\n", offset,
|
|
buffer[0], buffer[1], buffer[2], buffer[3],
|
|
buffer[4], buffer[5], buffer[6], buffer[7]));
|
|
offset += 16;
|
|
|
|
if (offset == 0x40) {
|
|
offset = 0x100;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
// External interface routines
|
|
// ---------------------------------------------------------------
|
|
|
|
VOID
|
|
ToshibaInitializeController(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
USHORT data;
|
|
UCHAR configData;
|
|
|
|
DebugPrint((SDBUS_DEBUG_DEVICE, "ToshibaInitializeController\n"));
|
|
|
|
//
|
|
// The Toshiba device appears to need this in order to function at all
|
|
//
|
|
// SetPciConfigSpace(FdoExtension, 0x40, &configData, 1);
|
|
|
|
configData = 0x1F; // Clock enable
|
|
SetPciConfigSpace(FdoExtension, TOCFG_CLOCK_CONTROL, &configData, 1);
|
|
configData = 0x08; // Power control
|
|
SetPciConfigSpace(FdoExtension, TOCFG_POWER_CTL1, &configData, 1);
|
|
|
|
data = ToshibaReadRegisterUshort(FdoExtension, TOMHC_HOST_CORE_VERSION);
|
|
DebugPrint((SDBUS_DEBUG_DEVICE, "TOMHC_HOST_CORE_VERSION - %x\n",
|
|
data));
|
|
|
|
ToshibaWriteRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK, 0xFFFFFFFF);
|
|
ToshibaWriteRegisterUlong(FdoExtension, TOIOHC_INTERRUPT_MASK, 0xFFFFFFFF);
|
|
|
|
//
|
|
// start the controller off in memory mode
|
|
//
|
|
ToshibaSetFunctionType(FdoExtension, SDBUS_FUNCTION_TYPE_MEMORY);
|
|
}
|
|
|
|
|
|
VOID
|
|
ToshibaInitializeFunction(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PPDO_EXTENSION PdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
ULONG sdRca = FdoExtension->RelativeAddr;
|
|
|
|
DebugPrint((SDBUS_DEBUG_DEVICE, "ToshibaInitializeFunction(%d)\n", PdoExtension->Function));
|
|
|
|
if (PdoExtension->Function == 8) {
|
|
//
|
|
// Memory function
|
|
//
|
|
} else {
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ToshibaSetPower(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN BOOLEAN Enable,
|
|
OUT OPTIONAL PULONG pDelayTime
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
UCHAR reg;
|
|
UCHAR mask;
|
|
UCHAR data;
|
|
|
|
GetPciConfigSpace(FdoExtension, TOCFG_POWER_CTL2, ®, 1);
|
|
|
|
mask = 0x03;
|
|
reg &= ~mask;
|
|
|
|
if (Enable) {
|
|
reg |= TO_POWER_33;
|
|
}
|
|
|
|
SetPciConfigSpace(FdoExtension, TOCFG_POWER_CTL2, ®, 1);
|
|
|
|
if (pDelayTime) {
|
|
*pDelayTime = 0x5dc;
|
|
}
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ToshibaResetHost(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN UCHAR Phase,
|
|
OUT PULONG pDelayTime
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
UCHAR data;
|
|
|
|
switch(Phase) {
|
|
|
|
case 0:
|
|
data = 0x0B;
|
|
SetPciConfigSpace(FdoExtension, TOCFG_CLOCK_CONTROL, &data, 1);
|
|
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_SOFTWARE_RESET, 0);
|
|
*pDelayTime = 0x5dc;
|
|
status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
break;
|
|
|
|
case 1:
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_SOFTWARE_RESET, 1);
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_SOFTWARE_RESET, 0);
|
|
*pDelayTime = 0x5dc;
|
|
status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
break;
|
|
|
|
case 2:
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_SOFTWARE_RESET, 1);
|
|
|
|
// ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_CLOCK_AND_WAIT_CONTROL,
|
|
// ToshibaReadRegisterUshort(FdoExtension, TOIOHC_CLOCK_AND_WAIT_CONTROL) & 0xFCFC);
|
|
//
|
|
// turn off IOHC clock enable and card wait
|
|
//
|
|
ToshibaWriteRegisterUshort(FdoExtension,
|
|
TOIOHC_CLOCK_AND_WAIT_CONTROL,
|
|
ToshibaReadRegisterUshort(FdoExtension, TOIOHC_CLOCK_AND_WAIT_CONTROL) &
|
|
~(TOIO_CWCF_CLOCK_ENABLE | TOIO_CWCF_CARD_WAIT));
|
|
|
|
//
|
|
// turn off MHC clock enable
|
|
//
|
|
ToshibaWriteRegisterUshort(FdoExtension,
|
|
TOMHC_CARD_CLOCK_CTL,
|
|
ToshibaReadRegisterUshort(FdoExtension, TOMHC_CARD_CLOCK_CTL) &
|
|
~TO_CCC_CLOCK_ENABLE);
|
|
|
|
//
|
|
// Turn on MHC clock enable
|
|
//
|
|
ToshibaWriteRegisterUshort(FdoExtension,
|
|
TOMHC_CARD_CLOCK_CTL,
|
|
// (TO_CCC_CLOCK_ENABLE | TO_CCC_CLOCK_DIVISOR_128));
|
|
TO_CCC_CLOCK_ENABLE);
|
|
|
|
//
|
|
// Turn on IOHC clock enable and card wait
|
|
//
|
|
ToshibaWriteRegisterUshort(FdoExtension,
|
|
TOIOHC_CLOCK_AND_WAIT_CONTROL,
|
|
(TOIO_CWCF_CLOCK_ENABLE | TOIO_CWCF_CARD_WAIT));
|
|
|
|
data = 0x1F;
|
|
SetPciConfigSpace(FdoExtension, TOCFG_CLOCK_CONTROL, &data, 1);
|
|
|
|
*pDelayTime = 0x3e8;
|
|
status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
break;
|
|
|
|
case 3:
|
|
status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
VOID
|
|
ToshibaSetLED(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN BOOLEAN Enable
|
|
)
|
|
{
|
|
}
|
|
|
|
|
|
//
|
|
// Event handling functions
|
|
//
|
|
|
|
ULONG
|
|
EventMaskToHardwareMask(
|
|
ULONG EventMask
|
|
)
|
|
{
|
|
ULONG hardwareMask = 0;
|
|
|
|
if (EventMask & SDBUS_EVENT_INSERTION) {
|
|
hardwareMask |= TO_EVT_CARD_INSERTION;
|
|
}
|
|
if (EventMask & SDBUS_EVENT_REMOVAL) {
|
|
hardwareMask |= TO_EVT_CARD_REMOVAL;
|
|
}
|
|
if (EventMask & SDBUS_EVENT_CARD_RESPONSE) {
|
|
hardwareMask |= TO_EVT_RESPONSE;
|
|
}
|
|
if (EventMask & SDBUS_EVENT_CARD_RW_END) {
|
|
hardwareMask |= TO_EVT_RW_END;
|
|
}
|
|
if (EventMask & SDBUS_EVENT_BUFFER_EMPTY) {
|
|
hardwareMask |= TO_EVT_BUFFER_EMPTY;
|
|
}
|
|
if (EventMask & SDBUS_EVENT_BUFFER_FULL) {
|
|
hardwareMask |= TO_EVT_BUFFER_FULL;
|
|
}
|
|
|
|
return hardwareMask;
|
|
}
|
|
|
|
ULONG
|
|
HardwareMaskToEventMask(
|
|
ULONG HardwareMask
|
|
)
|
|
{
|
|
ULONG eventMask = 0;
|
|
|
|
if (HardwareMask & TO_EVT_CARD_INSERTION) {
|
|
eventMask |= SDBUS_EVENT_INSERTION;
|
|
}
|
|
if (HardwareMask & TO_EVT_CARD_REMOVAL) {
|
|
eventMask |= SDBUS_EVENT_REMOVAL;
|
|
}
|
|
if (HardwareMask & TO_EVT_RESPONSE) {
|
|
eventMask |= SDBUS_EVENT_CARD_RESPONSE;
|
|
}
|
|
if (HardwareMask & TO_EVT_RW_END) {
|
|
eventMask |= SDBUS_EVENT_CARD_RW_END;
|
|
}
|
|
if (HardwareMask & TO_EVT_BUFFER_EMPTY) {
|
|
eventMask |= SDBUS_EVENT_BUFFER_EMPTY;
|
|
}
|
|
if (HardwareMask & TO_EVT_BUFFER_FULL) {
|
|
eventMask |= SDBUS_EVENT_BUFFER_FULL;
|
|
}
|
|
return eventMask;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
ToshibaEnableEvent(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN ULONG EventMask
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
ULONG data;
|
|
ULONG cardEvents, ctlrEvents, ioCardEvent;
|
|
ULONG mask;
|
|
|
|
DebugPrint((SDBUS_DEBUG_EVENT, "EnableEvent: %08x\n", EventMask));
|
|
FdoExtension->CurrentlyEnabledEvents |= EventMask;
|
|
|
|
ctlrEvents = EventMask & (SDBUS_EVENT_INSERTION | SDBUS_EVENT_REMOVAL);
|
|
EventMask &= ~(SDBUS_EVENT_INSERTION | SDBUS_EVENT_REMOVAL);
|
|
|
|
ioCardEvent = EventMask & SDBUS_EVENT_CARD_INTERRUPT;
|
|
EventMask &= ~SDBUS_EVENT_CARD_INTERRUPT;
|
|
|
|
cardEvents = EventMask;
|
|
|
|
mask = EventMaskToHardwareMask(cardEvents);
|
|
if (mask) {
|
|
data = ToshibaReadRegisterUlong(FdoExtension, FdoExtension->InterruptMaskReg);
|
|
data &= ~mask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, FdoExtension->InterruptMaskReg, data);
|
|
}
|
|
|
|
mask = EventMaskToHardwareMask(ctlrEvents);
|
|
if (mask) {
|
|
data = ToshibaReadRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK);
|
|
data &= ~mask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK, data);
|
|
}
|
|
|
|
if (ioCardEvent) {
|
|
USHORT usData;
|
|
|
|
usData = ToshibaReadRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL);
|
|
usData &= ~TOIO_CICF_CARD_INTMASK;
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL, usData);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
ToshibaDisableEvent(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN ULONG EventMask
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
ULONG data;
|
|
ULONG cardEvents, ctlrEvents, ioCardEvent;
|
|
ULONG mask;
|
|
|
|
FdoExtension->CurrentlyEnabledEvents &= ~EventMask;
|
|
|
|
ctlrEvents = EventMask & (SDBUS_EVENT_INSERTION | SDBUS_EVENT_REMOVAL);
|
|
EventMask &= ~(SDBUS_EVENT_INSERTION | SDBUS_EVENT_REMOVAL);
|
|
|
|
ioCardEvent = EventMask & SDBUS_EVENT_CARD_INTERRUPT;
|
|
EventMask &= ~SDBUS_EVENT_CARD_INTERRUPT;
|
|
|
|
cardEvents = EventMask;
|
|
|
|
mask = EventMaskToHardwareMask(cardEvents);
|
|
if (mask) {
|
|
data = ToshibaReadRegisterUlong(FdoExtension, FdoExtension->InterruptMaskReg);
|
|
data |= mask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, FdoExtension->InterruptMaskReg, data);
|
|
}
|
|
|
|
mask = EventMaskToHardwareMask(ctlrEvents);
|
|
if (mask) {
|
|
data = ToshibaReadRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK);
|
|
data |= mask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK, data);
|
|
}
|
|
|
|
if (ioCardEvent) {
|
|
USHORT usData;
|
|
|
|
usData = ToshibaReadRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL);
|
|
usData |= TOIO_CICF_CARD_INTMASK;
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL, usData);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ULONG
|
|
ToshibaGetPendingEvents(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
ULONG statusMask, eventMask;
|
|
ULONG mhcEvent = 0, iohcEvent = 0, iocardEvent = 0;
|
|
USHORT usData;
|
|
|
|
//
|
|
// The Pelican3 has interrupt status spread out everywhere. First try
|
|
// the memory host controller
|
|
//
|
|
|
|
statusMask = ToshibaReadRegisterUlong(FdoExtension, TOMHC_CARD_STATUS);
|
|
eventMask = ToshibaReadRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK);
|
|
|
|
// turn off undefined bits
|
|
statusMask &= 0x837F031D;
|
|
// turn off bits that are masked
|
|
statusMask &= ~eventMask;
|
|
|
|
mhcEvent = HardwareMaskToEventMask(statusMask);
|
|
|
|
if (statusMask && (mhcEvent == 0)) {
|
|
// got an interrupt, but we don't know what type
|
|
ASSERT(FALSE);
|
|
|
|
eventMask |= statusMask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, TOMHC_INTERRUPT_MASK, eventMask);
|
|
}
|
|
|
|
//
|
|
// Now try the IO host controller
|
|
//
|
|
if (!mhcEvent) {
|
|
statusMask = ToshibaReadRegisterUlong(FdoExtension, TOIOHC_CARD_STATUS);
|
|
eventMask = ToshibaReadRegisterUlong(FdoExtension, TOIOHC_INTERRUPT_MASK);
|
|
|
|
// turn off undefined bits
|
|
statusMask &= 0xA37F0005;
|
|
// turn off bits that are masked
|
|
statusMask &= ~eventMask;
|
|
|
|
iohcEvent = HardwareMaskToEventMask(statusMask);
|
|
|
|
if (statusMask && (iohcEvent == 0)) {
|
|
// got an interrupt, but we don't know what type
|
|
ASSERT(FALSE);
|
|
|
|
eventMask |= statusMask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, TOIOHC_INTERRUPT_MASK, eventMask);
|
|
}
|
|
|
|
//
|
|
// get IO card interrupt
|
|
//
|
|
|
|
usData = ToshibaReadRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL);
|
|
|
|
if ((usData & TOIO_CICF_CARD_INTERRUPT) && ((usData & TOIO_CICF_CARD_INTMASK)==0)) {
|
|
|
|
if (ToshibaDetectCardInSocket(FdoExtension)) {
|
|
iocardEvent = SDBUS_EVENT_CARD_INTERRUPT;
|
|
} else {
|
|
//
|
|
// the card is gone, this must be spurious
|
|
//
|
|
usData |= TOIO_CICF_CARD_INTMASK;
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL, usData);
|
|
}
|
|
}
|
|
}
|
|
return mhcEvent | iohcEvent | iocardEvent;
|
|
}
|
|
|
|
|
|
VOID
|
|
ToshibaAcknowledgeEvent(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN ULONG EventMask
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
ULONG hardwareMask = EventMaskToHardwareMask(EventMask);
|
|
ULONG data;
|
|
USHORT interruptMaskReg, cardStatusReg;
|
|
|
|
if (EventMask & SDBUS_EVENT_CARD_INTERRUPT) {
|
|
//
|
|
// No need to clear io card IRQ, just reenable it
|
|
//
|
|
USHORT usData;
|
|
|
|
usData = ToshibaReadRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL);
|
|
usData &= ~TOIO_CICF_CARD_INTMASK;
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_CARD_INTERRUPT_CONTROL, usData);
|
|
return;
|
|
}
|
|
|
|
|
|
if (EventMask & (SDBUS_EVENT_INSERTION | SDBUS_EVENT_REMOVAL)) {
|
|
interruptMaskReg = TOMHC_INTERRUPT_MASK;
|
|
cardStatusReg = TOMHC_CARD_STATUS;
|
|
} else {
|
|
interruptMaskReg = FdoExtension->InterruptMaskReg;
|
|
cardStatusReg = FdoExtension->CardStatusReg;
|
|
}
|
|
|
|
|
|
//
|
|
// Clear event in status register
|
|
//
|
|
|
|
data = ToshibaReadRegisterUlong(FdoExtension, cardStatusReg);
|
|
DebugPrint((SDBUS_DEBUG_EVENT, "AcknowledgeEvent: %08x - cardstatus %08x\n", EventMask, data));
|
|
data &= ~hardwareMask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, cardStatusReg, data);
|
|
|
|
#if DBG
|
|
data = ToshibaReadRegisterUlong(FdoExtension, cardStatusReg);
|
|
DebugPrint((SDBUS_DEBUG_EVENT, "AcknowledgeEvent: new cardstatus %08x\n", data));
|
|
#endif
|
|
|
|
//
|
|
// Reenable event
|
|
//
|
|
|
|
FdoExtension->CurrentlyEnabledEvents |= EventMask;
|
|
data = ToshibaReadRegisterUlong(FdoExtension, interruptMaskReg);
|
|
data &= ~hardwareMask;
|
|
ToshibaWriteRegisterUlong(FdoExtension, interruptMaskReg, data);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
ToshibaSetFunctionType(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN UCHAR FunctionType
|
|
)
|
|
{
|
|
ULONG currentlyEnabledEvents = FdoExtension->CurrentlyEnabledEvents;
|
|
|
|
if (FunctionType == FdoExtension->FunctionType) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// The pelican3 implements these event masks in two places, so disable and reenable them
|
|
//
|
|
if (currentlyEnabledEvents) {
|
|
ToshibaDisableEvent(FdoExtension, currentlyEnabledEvents);
|
|
}
|
|
|
|
switch(FunctionType) {
|
|
|
|
case SDBUS_FUNCTION_TYPE_MEMORY:
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_CLOCK_AND_WAIT_CONTROL, 0x100);
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_TRANSACTION_CONTROL,
|
|
ToshibaReadRegisterUshort(FdoExtension, TOIOHC_TRANSACTION_CONTROL) & 0xEFFF);
|
|
|
|
FdoExtension->ArgumentReg = TOMHC_ARGUMENT;
|
|
FdoExtension->CmdReg = TOMHC_COMMAND;
|
|
FdoExtension->CardStatusReg = TOMHC_CARD_STATUS;
|
|
FdoExtension->ResponseReg = TOMHC_RESPONSE;
|
|
FdoExtension->InterruptMaskReg = TOMHC_INTERRUPT_MASK;
|
|
break;
|
|
|
|
case SDBUS_FUNCTION_TYPE_IO:
|
|
|
|
FdoExtension->ArgumentReg = TOIOHC_ARGUMENT;
|
|
FdoExtension->CmdReg = TOIOHC_COMMAND;
|
|
FdoExtension->CardStatusReg = TOIOHC_CARD_STATUS;
|
|
FdoExtension->ResponseReg = TOIOHC_RESPONSE_0;
|
|
FdoExtension->InterruptMaskReg = TOIOHC_INTERRUPT_MASK;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
if (currentlyEnabledEvents) {
|
|
ToshibaEnableEvent(FdoExtension, currentlyEnabledEvents);
|
|
}
|
|
|
|
FdoExtension->FunctionType = FunctionType;
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
ToshibaDetectCardInSocket(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
USHORT data;
|
|
|
|
data = ToshibaReadRegisterUshort(FdoExtension, TOMHC_CARD_STATUS);
|
|
return !((data & TO_STS_CARD_PRESENT) == 0);
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
ToshibaIsWriteProtected(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
USHORT data;
|
|
|
|
data = ToshibaReadRegisterUshort(FdoExtension, TOMHC_CARD_STATUS);
|
|
return ((data & TO_STS_WRITE_PROTECT) == 0);
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
BOOLEAN
|
|
ToshibaClearStatus(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
|
|
//
|
|
// This was stuff that was done before the first SEND... it is unclear how
|
|
// much should be moved to the send
|
|
//
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_TRANSACTION_CONTROL,
|
|
ToshibaReadRegisterUshort(FdoExtension, TOIOHC_TRANSACTION_CONTROL) & 0xEFFF);
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_BUFFER_CTL_AND_ERR,
|
|
ToshibaReadRegisterUshort(FdoExtension, TOMHC_BUFFER_CTL_AND_ERR) & 0x7D00);
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_CARD_STATUS,
|
|
ToshibaReadRegisterUshort(FdoExtension, TOMHC_CARD_STATUS) & 0xFFFA);
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
|
|
NTSTATUS
|
|
ToshibaCheckStatus(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
ULONG cardStatus;
|
|
ULONG errorStatus;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
DebugDumpRegs(FdoExtension);
|
|
|
|
cardStatus = ToshibaReadRegisterUlong(FdoExtension, FdoExtension->CardStatusReg);
|
|
|
|
|
|
if (FdoExtension->FunctionType == SDBUS_FUNCTION_TYPE_MEMORY) {
|
|
errorStatus = cardStatus & (TOMHC_BCE_CMD_INDEX_ERROR |
|
|
TOMHC_BCE_CRC_ERROR |
|
|
TOMHC_BCE_END_BIT_ERROR |
|
|
TOMHC_BCE_CMD_TIMEOUT |
|
|
TOMHC_BCE_DATA_TIMEOUT |
|
|
TOMHC_BCE_FIFO_OVERFLOW |
|
|
TOMHC_BCE_FIFO_UNDERFLOW |
|
|
TOMHC_BCE_ILLEGAL_ACCESS);
|
|
} else {
|
|
errorStatus = cardStatus & (TOMHC_BCE_CMD_INDEX_ERROR |
|
|
// TOMHC_BCE_CRC_ERROR |
|
|
TOMHC_BCE_END_BIT_ERROR |
|
|
TOMHC_BCE_CMD_TIMEOUT |
|
|
TOMHC_BCE_DATA_TIMEOUT |
|
|
TOMHC_BCE_FIFO_OVERFLOW |
|
|
TOMHC_BCE_FIFO_UNDERFLOW |
|
|
TOMHC_BCE_ILLEGAL_ACCESS);
|
|
}
|
|
|
|
if (errorStatus) {
|
|
DebugPrint((SDBUS_DEBUG_WARNING, "CheckStatus detected Error! status = %08x\n", errorStatus));
|
|
|
|
//ISSUE: NEED TO IMPLEMENT: I/O error handling
|
|
ToshibaWriteRegisterUlong(FdoExtension, FdoExtension->CardStatusReg, cardStatus & ~errorStatus);
|
|
|
|
|
|
// possibilities:
|
|
// STATUS_PARITY_ERROR
|
|
// STATUS_DEVICE_DATA_ERROR
|
|
// STATUS_DEVICE_POWER_FAILURE
|
|
// STATUS_DEVICE_NOT_READY
|
|
// STATUS_IO_TIMEOUT
|
|
// STATUS_INVALID_DEVICE_STATE
|
|
// STATUS_IO_DEVICE_ERROR
|
|
// STATUS_DEVICE_PROTOCOL_ERROR
|
|
// STATUS_DEVICE_REMOVED
|
|
// STATUS_POWER_STATE_INVALID
|
|
status = STATUS_IO_DEVICE_ERROR;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ToshibaSDCommand(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PSD_WORK_PACKET WorkPacket
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
USHORT cmdWord;
|
|
ULONG Flags = WorkPacket->Flags;
|
|
NTSTATUS status;
|
|
|
|
ToshibaWriteRegisterUlong(FdoExtension, FdoExtension->ArgumentReg, WorkPacket->Argument);
|
|
|
|
cmdWord = WorkPacket->Cmd;
|
|
|
|
switch (WorkPacket->ResponseType) {
|
|
case SDCMD_RESP_NONE:
|
|
cmdWord |= TOMHC_CMD_RESP_NONE;
|
|
break;
|
|
|
|
case SDCMD_RESP_1:
|
|
case SDCMD_RESP_5:
|
|
case SDCMD_RESP_6:
|
|
cmdWord |= 0x400;
|
|
break;
|
|
|
|
case SDCMD_RESP_2:
|
|
cmdWord |= 0x600;
|
|
break;
|
|
|
|
case SDCMD_RESP_3:
|
|
case SDCMD_RESP_4:
|
|
cmdWord |= 0x700;
|
|
break;
|
|
|
|
case SDCMD_RESP_1B:
|
|
case SDCMD_RESP_5B:
|
|
cmdWord |= 0x500;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
//
|
|
// Add flags
|
|
//
|
|
|
|
if (Flags & SDCMDF_ACMD) {
|
|
cmdWord |= TOMHC_CMD_ACMD;
|
|
}
|
|
|
|
if (Flags & SDCMDF_DATA) {
|
|
cmdWord |= TOMHC_CMD_NTDT;
|
|
}
|
|
|
|
if (Flags & SDCMDF_MULTIBLOCK) {
|
|
cmdWord |= TOMHC_CMD_MSSL;
|
|
}
|
|
|
|
if (Flags & SDCMDF_READ) {
|
|
cmdWord |= TOMHC_CMD_RWDI;
|
|
}
|
|
|
|
//
|
|
// Write Cmd and flags to command register
|
|
//
|
|
|
|
DebugPrint((SDBUS_DEBUG_DEVICE, "SEND: Cmd%d (0x%04x) arg = 0x%08x\n", WorkPacket->Cmd, cmdWord, WorkPacket->Argument));
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, FdoExtension->CmdReg, cmdWord);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ToshibaSDGetResponse(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PSD_WORK_PACKET WorkPacket
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
// ULONG cardStatus;
|
|
UCHAR i;
|
|
PUCHAR pRespPtr;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
pRespPtr = (PUCHAR) WorkPacket->ResponseBuffer;
|
|
for (i=0; i<SDBUS_RESPONSE_BUFFER_LENGTH; i++) {
|
|
*pRespPtr++ = ToshibaReadRegisterUchar(FdoExtension, FdoExtension->ResponseReg+i);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
ToshibaStartBlockOperation(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_CARD_CLOCK_CTL, 0x100);
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_OPTIONS, 0x40e0);
|
|
}
|
|
|
|
VOID
|
|
ToshibaSetBlockParameters(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Length
|
|
)
|
|
{
|
|
if (FdoExtension->FunctionType == SDBUS_FUNCTION_TYPE_MEMORY) {
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_CARD_TRANSFER_LENGTH, 512);
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_STOP_INTERNAL, 0x100);
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_TRANSFER_SECTOR_COUNT, Length);
|
|
|
|
} else {
|
|
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOIOHC_TRANSFER_DATA_LEN_SELECT, Length);
|
|
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ToshibaEndBlockOperation(
|
|
IN PFDO_EXTENSION FdoExtension
|
|
)
|
|
{
|
|
ToshibaWriteRegisterUshort(FdoExtension, TOMHC_BUFFER_CTL_AND_ERR, 0);
|
|
}
|
|
|
|
VOID
|
|
ToshibaReadDataPort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PUCHAR Buffer,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The data port must be accessed maintaining DWORD alignment. So for example:
|
|
|
|
IN DWORD 130
|
|
IN DWORD 130
|
|
|
|
is the same as
|
|
|
|
IN USHORT 130
|
|
IN USHORT 132
|
|
IN UCHAR 130
|
|
IN UCHAR 131
|
|
IN UCHAR 132
|
|
IN UCHAR 133
|
|
|
|
|
|
Arguments:
|
|
|
|
Return value:
|
|
|
|
--*/
|
|
{
|
|
USHORT i;
|
|
ULONG dwordCount, wordCount, byteCount;
|
|
PULONG ulBuffer = (PULONG) Buffer;
|
|
PUSHORT usBuffer;
|
|
USHORT port = (FdoExtension->FunctionType == SDBUS_FUNCTION_TYPE_MEMORY) ? TOMHC_DATA_PORT :
|
|
TOIOHC_DATA_TRANSFER;
|
|
PUCHAR portAddress = ((PUCHAR)FdoExtension->HostRegisterBase + port);
|
|
|
|
dwordCount = Length / 4;
|
|
wordCount = (Length % 4) / 2;
|
|
byteCount = (Length % 4) % 2;
|
|
|
|
for (i = 0; i < dwordCount; i++) {
|
|
READ_REGISTER_BUFFER_ULONG((PULONG) portAddress, ulBuffer, 1);
|
|
ulBuffer++;
|
|
}
|
|
|
|
if (wordCount) {
|
|
usBuffer = (PUSHORT) ulBuffer;
|
|
|
|
ASSERT(wordCount == 1);
|
|
|
|
READ_REGISTER_BUFFER_USHORT((PUSHORT) portAddress, usBuffer, 1);
|
|
usBuffer++;
|
|
}
|
|
|
|
if (byteCount) {
|
|
PUCHAR ucBuffer = (PUCHAR) usBuffer;
|
|
|
|
ASSERT(byteCount == 1);
|
|
|
|
// maintain byte order within ULONG dataport
|
|
portAddress++;
|
|
portAddress++;
|
|
|
|
READ_REGISTER_BUFFER_UCHAR((PUCHAR) portAddress, ucBuffer, 1);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ToshibaWriteDataPort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN PUCHAR Buffer,
|
|
IN ULONG Length
|
|
)
|
|
{
|
|
USHORT i;
|
|
ULONG dwordCount, wordCount, byteCount;
|
|
PULONG ulBuffer = (PULONG) Buffer;
|
|
PUSHORT usBuffer;
|
|
USHORT port = (FdoExtension->FunctionType == SDBUS_FUNCTION_TYPE_MEMORY) ? TOMHC_DATA_PORT :
|
|
TOIOHC_DATA_TRANSFER;
|
|
PUCHAR portAddress = ((PUCHAR)FdoExtension->HostRegisterBase + port);
|
|
|
|
dwordCount = Length / 4;
|
|
wordCount = (Length % 4) / 2;
|
|
byteCount = (Length % 4) % 2;
|
|
|
|
for (i = 0; i < dwordCount; i++) {
|
|
WRITE_REGISTER_BUFFER_ULONG((PULONG) portAddress, ulBuffer, 1);
|
|
ulBuffer++;
|
|
}
|
|
|
|
if (wordCount) {
|
|
usBuffer = (PUSHORT) ulBuffer;
|
|
|
|
ASSERT(wordCount == 1);
|
|
|
|
WRITE_REGISTER_BUFFER_USHORT((PUSHORT) portAddress, usBuffer, 1);
|
|
usBuffer++;
|
|
}
|
|
|
|
if (byteCount) {
|
|
PUCHAR ucBuffer = (PUCHAR) usBuffer;
|
|
|
|
ASSERT(byteCount == 1);
|
|
|
|
// maintain byte order within ULONG dataport
|
|
portAddress++;
|
|
portAddress++;
|
|
|
|
WRITE_REGISTER_BUFFER_UCHAR((PUCHAR) portAddress, ucBuffer, 1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// Internal routines
|
|
// ---------------------------------------------------------------
|
|
|
|
|
|
|
|
UCHAR
|
|
ToshibaReadRegisterUchar(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will read a byte from the specified socket EXCA register
|
|
|
|
Arguments:
|
|
|
|
Socket -- Pointer to the socket from which we should read
|
|
Register -- The register to be read
|
|
|
|
Return Value:
|
|
|
|
The data returned from the port.
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR byte;
|
|
//
|
|
// Sanity check in case controller wasn't started
|
|
//
|
|
if (FdoExtension->HostRegisterBase) {
|
|
byte = READ_REGISTER_UCHAR((PUCHAR) ((PUCHAR)FdoExtension->HostRegisterBase + Register));
|
|
} else {
|
|
byte = 0xff;
|
|
}
|
|
return byte;
|
|
}
|
|
|
|
|
|
|
|
USHORT
|
|
ToshibaReadRegisterUshort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will read a byte from the specified socket EXCA register
|
|
|
|
Arguments:
|
|
|
|
Socket -- Pointer to the socket from which we should read
|
|
Register -- The register to be read
|
|
|
|
Return Value:
|
|
|
|
The data returned from the port.
|
|
|
|
--*/
|
|
|
|
{
|
|
USHORT word;
|
|
//
|
|
// Sanity check in case controller wasn't started
|
|
//
|
|
if (FdoExtension->HostRegisterBase) {
|
|
word = READ_REGISTER_USHORT((PUSHORT) ((PUCHAR)FdoExtension->HostRegisterBase + Register));
|
|
} else {
|
|
word = 0xff;
|
|
}
|
|
return word;
|
|
}
|
|
|
|
|
|
VOID
|
|
ToshibaWriteRegisterUshort(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register,
|
|
IN USHORT Data
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will read a byte from the specified socket EXCA register
|
|
|
|
Arguments:
|
|
|
|
Socket -- Pointer to the socket from which we should read
|
|
Register -- The register to be read
|
|
|
|
Return Value:
|
|
|
|
The data returned from the port.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Sanity check in case controller wasn't started
|
|
//
|
|
if (FdoExtension->HostRegisterBase) {
|
|
WRITE_REGISTER_USHORT((PUSHORT) ((PUCHAR)FdoExtension->HostRegisterBase + Register), Data);
|
|
}
|
|
}
|
|
|
|
|
|
ULONG
|
|
ToshibaReadRegisterUlong(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will read a byte from the specified socket EXCA register
|
|
|
|
Arguments:
|
|
|
|
Socket -- Pointer to the socket from which we should read
|
|
Register -- The register to be read
|
|
|
|
Return Value:
|
|
|
|
The data returned from the port.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG dword;
|
|
//
|
|
// Sanity check in case controller wasn't started
|
|
//
|
|
if (FdoExtension->HostRegisterBase) {
|
|
dword = READ_REGISTER_ULONG((PULONG) ((PUCHAR)FdoExtension->HostRegisterBase + Register));
|
|
} else {
|
|
dword = 0xff;
|
|
}
|
|
return dword;
|
|
}
|
|
|
|
|
|
VOID
|
|
ToshibaWriteRegisterUlong(
|
|
IN PFDO_EXTENSION FdoExtension,
|
|
IN USHORT Register,
|
|
IN ULONG Data
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will read a byte from the specified socket EXCA register
|
|
|
|
Arguments:
|
|
|
|
Socket -- Pointer to the socket from which we should read
|
|
Register -- The register to be read
|
|
|
|
Return Value:
|
|
|
|
The data returned from the port.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Sanity check in case controller wasn't started
|
|
//
|
|
if (FdoExtension->HostRegisterBase) {
|
|
WRITE_REGISTER_ULONG((PULONG) ((PUCHAR)FdoExtension->HostRegisterBase + Register), Data);
|
|
}
|
|
}
|
|
|
|
|