443 lines
17 KiB
C
443 lines
17 KiB
C
|
|
/*
|
|
* $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;
|
|
}
|