|
|
/*
* $Log: $ */
/************************************************************************/ /* */ /* FAT-FTL Lite Software Development Kit */ /* Copyright (C) M-Systems Ltd. 1995-1996 */ /* */ /************************************************************************/
#include "flsocket.h"
#include "scsi.h"
#include "tffsport.h"
#include "INITGUID.H"
#include "ntddpcm.h"
#define ANTI_CRASH_WINDOW
#ifdef ANTI_CRASH_WINDOW
CHAR antiCrashWindow_socketnt[0x2000]; #endif
/*NTsocketParams driveInfo[SOCKETS];
NTsocketParams * pdriveInfo = driveInfo; */ extern NTsocketParams driveInfo[SOCKETS]; extern NTsocketParams * pdriveInfo; PCMCIA_INTERFACE_STANDARD driveContext[SOCKETS];
NTSTATUS queryInterfaceCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PKEVENT event = Context; KeSetEvent(event, EVENT_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS updatePcmciaSocketParams(PDEVICE_EXTENSION fdoExtension) { PIRP irp = NULL; NTSTATUS status;
//
// Setup a query interface request for the pcmcia pdo
//
irp = IoAllocateIrp(fdoExtension->LowerDeviceObject->StackSize, FALSE);
if (irp) { PIO_STACK_LOCATION irpSp; KEVENT event; ULONG device = fdoExtension->UnitNumber;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_PNP; irpSp->MinorFunction = IRP_MN_QUERY_INTERFACE; irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
irpSp->Parameters.QueryInterface.InterfaceType = &GUID_PCMCIA_INTERFACE_STANDARD; irpSp->Parameters.QueryInterface.Size = sizeof(PCMCIA_INTERFACE_STANDARD); irpSp->Parameters.QueryInterface.Version = 1; irpSp->Parameters.QueryInterface.Interface = (PINTERFACE) &driveContext[device]; irpSp->Parameters.QueryInterface.InterfaceSpecificData = NULL;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(irp, queryInterfaceCompletionRoutine, &event, TRUE, TRUE, TRUE); status = IoCallDriver(fdoExtension->LowerDeviceObject, irp);
if (status == STATUS_PENDING) { status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); }
status = irp->IoStatus.Status; IoFreeIrp (irp);
if (NT_SUCCESS(status)) { driveInfo[device].windowSize = fdoExtension->pcmciaParams.windowSize; driveInfo[device].physWindow = fdoExtension->pcmciaParams.physWindow; driveInfo[device].winBase = fdoExtension->pcmciaParams.windowBase; driveInfo[device].fdoExtension = (PVOID) fdoExtension; driveInfo[device].interfAlive = 1; } } else { status = STATUS_INSUFFICIENT_RESOURCES; }
return status; }
/************************************************************************/ /* */ /* Beginning of controller-customizable code */ /* */ /* The function prototypes and interfaces in this section are standard */ /* and are used in this form by the non-customizable code. However, the */ /* function implementations are specific to the 82365SL controller. */ /* */ /* You should replace the function bodies here with the implementation */ /* that is appropriate for your controller. */ /* */ /* All the functions in this section have no parameters. This is */ /* because the parameters needed for an operation may be themselves */ /* depend on the controller. Instead, you should use the value in the */ /* 'vol' structure as parameters. */ /* If you need socket-state variables specific to your implementation, */ /* it is recommended to add them to the 'vol' structure rather than */ /* define them as separate static variables. */ /* */ /************************************************************************/
/*----------------------------------------------------------------------*/ /* c a r d D e t e c t e d */ /* */ /* Detect if a card is present (inserted) */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /* Returns: */ /* 0 = card not present, other = card present */ /*----------------------------------------------------------------------*/
FLBoolean cardDetected_socketnt(FLSocket vol) { return TRUE; /* we will know when card is removed */ /*Implemented by upper layers*/ }
/*----------------------------------------------------------------------*/ /* V c c O n */ /* */ /* Turns on Vcc (3.3/5 Volts). Vcc must be known to be good on exit. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /*----------------------------------------------------------------------*/
VOID VccOn_socketnt(FLSocket vol) { }
/*----------------------------------------------------------------------*/ /* V c c O f f */ /* */ /* Turns off Vcc. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /*----------------------------------------------------------------------*/
VOID VccOff_socketnt(FLSocket vol) { }
#ifdef SOCKET_12_VOLTS
/*----------------------------------------------------------------------*/ /* V p p O n */ /* */ /* Turns on Vpp (12 Volts. Vpp must be known to be good on exit. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /* Returns: */ /* FLStatus : 0 on success, failed otherwise */ /*----------------------------------------------------------------------*/
FLStatus VppOn_socketnt(FLSocket vol) {
if (driveInfo[vol.volNo].fdoExtension != NULL) { if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) { return flVppFailure; } } else return flVppFailure;
if (driveContext[vol.volNo].SetVpp(driveContext[vol.volNo].Context, PCMCIA_VPP_12V)) { return flOK; } else { return flVppFailure; } }
/*----------------------------------------------------------------------*/ /* V p p O f f */ /* */ /* Turns off Vpp. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /*----------------------------------------------------------------------*/
VOID VppOff_socketnt(FLSocket vol) { if (driveInfo[vol.volNo].fdoExtension != NULL) { if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) { return; } } else return;
if (driveInfo[vol.volNo].interfAlive) { driveContext[vol.volNo].SetVpp(driveContext[vol.volNo].Context, PCMCIA_VPP_IS_VCC); } }
#endif /* SOCKET_12_VOLTS */
/*----------------------------------------------------------------------*/ /* i n i t S o c k e t */ /* */ /* Perform all necessary initializations of the socket or controller */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /* Returns: */ /* FLStatus : 0 on success, failed otherwise */ /*----------------------------------------------------------------------*/
FLStatus initSocket_socketnt(FLSocket vol) { return flOK; /* nothing to initialize */ }
/*----------------------------------------------------------------------*/ /* s e t W i n d o w */ /* */ /* Sets in hardware all current window parameters: Base address, size, */ /* speed and bus width. */ /* The requested settings are given in the 'vol.window' structure. */ /* */ /* If it is not possible to set the window size requested in */ /* 'vol.window.size', the window size should be set to a larger value, */ /* if possible. In any case, 'vol.window.size' should contain the */ /* actual window size (in 4 KB units) on exit. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /*----------------------------------------------------------------------*/
VOID setWindow_socketnt(FLSocket vol) { vol.window.size = driveInfo[vol.volNo].windowSize; vol.window.base = driveInfo[vol.volNo].winBase; }
/*----------------------------------------------------------------------*/ /* s e t M a p p i n g C o n t e x t */ /* */ /* Sets the window mapping register to a card address. */ /* */ /* The window should be set to the value of 'vol.window.currentPage', */ /* which is the card address divided by 4 KB. An address over 128KB, */ /* (page over 32K) specifies an attribute-space address. */ /* */ /* The page to map is guaranteed to be on a full window-size boundary. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /*----------------------------------------------------------------------*/
VOID setMappingContext_socketnt(FLSocket vol, unsigned page) { UCHAR winSpeed; if (driveInfo[vol.volNo].fdoExtension != NULL) { if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) { #ifdef ANTI_CRASH_WINDOW
vol.window.base = antiCrashWindow_socketnt; #else
vol.window.base = NULL; #endif
return; } } else { #ifdef ANTI_CRASH_WINDOW
vol.window.base = antiCrashWindow_socketnt; #else
vol.window.base = NULL; #endif
return; } winSpeed = (UCHAR)(4 - ((vol.window.speed - 100) % 50));
driveContext[vol.volNo].ModifyMemoryWindow(driveContext[vol.volNo].Context, driveInfo[vol.volNo].physWindow, ((ULONGLONG)page << 12), FALSE, vol.window.size, winSpeed, (UCHAR)((vol.window.busWidth == 16) ? PCMCIA_MEMORY_16BIT_ACCESS : PCMCIA_MEMORY_8BIT_ACCESS), FALSE);
if (!(driveContext[vol.volNo].ModifyMemoryWindow(driveContext[vol.volNo].Context, driveInfo[vol.volNo].physWindow, ((ULONGLONG)page << 12), TRUE, vol.window.size, winSpeed, (UCHAR)((vol.window.busWidth == 16) ? PCMCIA_MEMORY_16BIT_ACCESS : PCMCIA_MEMORY_8BIT_ACCESS), FALSE))) {
#ifdef ANTI_CRASH_WINDOW
vol.window.base = antiCrashWindow_socketnt; #else
vol.window.base = NULL; #endif
} }
/*----------------------------------------------------------------------*/ /* g e t A n d C l e a r C a r d C h a n g e I n d i c a t o r */ /* */ /* Returns the hardware card-change indicator and clears it if set. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /* Returns: */ /* 0 = Card not changed, other = card changed */ /*----------------------------------------------------------------------*/
FLBoolean getAndClearCardChangeIndicator_socketnt(FLSocket vol) { return FALSE; }
/*----------------------------------------------------------------------*/ /* w r i t e P r o t e c t e d */ /* */ /* Returns the write-protect state of the media */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /* Returns: */ /* 0 = not write-protected, other = write-protected */ /*----------------------------------------------------------------------*/
FLBoolean writeProtected_socketnt(FLSocket vol) { if (driveInfo[vol.volNo].fdoExtension != NULL) { if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) { return TRUE; } } else return TRUE;
return driveContext[vol.volNo].IsWriteProtected(driveContext[vol.volNo].Context); }
#ifdef EXIT
/*----------------------------------------------------------------------*/ /* f r e e S o c k e t */ /* */ /* Free resources that were allocated for this socket. */ /* This function is called when FLite exits. */ /* */ /* Parameters: */ /* vol : Pointer identifying drive */ /* */ /*----------------------------------------------------------------------*/
VOID freeSocket_socketnt(FLSocket vol) { } #endif /* EXIT */
/*----------------------------------------------------------------------*/ /* f l R e g i s t e r P C I C */ /* */ /* Installs routines for the PCIC socket controller. */ /* */ /* Returns: */ /* FLStatus : 0 on success, otherwise failure */ /*----------------------------------------------------------------------*/
FLStatus flRegisterNT5PCIC() { LONG serialNo = 0;
for (; noOfSockets < SOCKETS; noOfSockets++) { FLSocket vol = flSocketOf(noOfSockets);
vol.volNo = noOfSockets; vol.serialNo = serialNo; vol.cardDetected = cardDetected_socketnt; vol.VccOn = VccOn_socketnt; vol.VccOff = VccOff_socketnt; #ifdef SOCKET_12_VOLTS
vol.VppOn = VppOn_socketnt; vol.VppOff = VppOff_socketnt; #endif
vol.initSocket = initSocket_socketnt; vol.setWindow = setWindow_socketnt; vol.setMappingContext = setMappingContext_socketnt; vol.getAndClearCardChangeIndicator = getAndClearCardChangeIndicator_socketnt; vol.writeProtected = writeProtected_socketnt; #ifdef EXIT
vol.freeSocket = freeSocket_socketnt; #endif
PRINTF("Debug: flRegisterNT5PCIC():Socket No %d is register.\n", noOfSockets); } if (noOfSockets == 0) return flAdapterNotFound; return flOK; }
|