|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 2000
//
// File: ppa3x.c
//
//--------------------------------------------------------------------------
#include "pch.h"
VOID PptLegacyZipClockDiskModeByte( PUCHAR Controller, UCHAR ModeByte ) { P5WritePortUchar( Controller, ModeByte ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_AUTOFEED) ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_SELECT_IN) );
} // end PptLegacyZipClockDiskModeByte()
VOID PptLegacyZipClockPrtModeByte( PUCHAR Controller, UCHAR ModeByte ) { P5WritePortUchar( Controller, ModeByte ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT) ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT | DCR_AUTOFEED) ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT) ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT ); P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT) );
} // end PptLegacyZipClockPrtModeByte()
VOID PptLegacyZipSetDiskMode( PUCHAR Controller, UCHAR Mode ) { ULONG i;
for ( i = 0; i < LEGACYZIP_MODE_LEN; i++ ) { PptLegacyZipClockDiskModeByte( Controller, LegacyZipModeQualifier[i] ); }
PptLegacyZipClockDiskModeByte( Controller, Mode );
} // end of PptLegacyZipSetDiskMode()
BOOLEAN PptLegacyZipCheckDevice( PUCHAR Controller ) { P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_AUTOFEED) );
if ( (P5ReadPortUchar( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) == DSR_NOT_FAULT ) {
P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
if ( (P5ReadPortUchar( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) != DSR_NOT_FAULT ) { // A device was found
return TRUE; } }
// No device is there
return FALSE;
} // end PptLegacyZipCheckDevice()
NTSTATUS PptTrySelectLegacyZip( IN PVOID Context, IN PVOID TrySelectCommand ) { PFDO_EXTENSION fdx = Context; PPARALLEL_1284_COMMAND Command = TrySelectCommand; NTSTATUS Status = STATUS_SUCCESS; // default success
PUCHAR Controller = fdx->PortInfo.Controller; SYNCHRONIZED_COUNT_CONTEXT SyncContext; KIRQL CancelIrql;
DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip - Enter\n");
// test to see if we need to grab port
if( !(Command->CommandFlags & PAR_HAVE_PORT_KEEP_PORT) ) { // Don't have the port
//
// Try to acquire port and select device
//
DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip Try get port.\n");
IoAcquireCancelSpinLock(&CancelIrql); SyncContext.Count = &fdx->WorkQueueCount; if (fdx->InterruptRefCount) { KeSynchronizeExecution(fdx->InterruptObject, PptSynchronizedIncrement, &SyncContext); } else { PptSynchronizedIncrement(&SyncContext); } if (SyncContext.NewCount) { // Port is busy, queue request
Status = STATUS_PENDING; } // endif - test for port busy
IoReleaseCancelSpinLock(CancelIrql);
} // endif - test if already have port
//
// If we have port select legacy Zip
//
if ( NT_SUCCESS( Status ) && (Status != STATUS_PENDING) ) { if ( Command->CommandFlags & PAR_LEGACY_ZIP_DRIVE_EPP_MODE ) { // Select in EPP mode
PptLegacyZipSetDiskMode( Controller, (UCHAR)0xCF ); } else { // Select in Nibble or Byte mode
PptLegacyZipSetDiskMode( Controller, (UCHAR)0x8F ); }
if ( PptLegacyZipCheckDevice( Controller ) ) { DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip - SUCCESS\n");
//
// Legacy Zip is selected - test for EPP if we haven't previously done the test
//
if( !fdx->CheckedForGenericEpp ) { // haven't done the test yet
if( fdx->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT ) { // we have an ECR - required for generic EPP
if( !fdx->NationalChipFound ) { // we don't have a NationalSemi chipset - no generic EPP on NatSemi chips
PptDetectEppPort( fdx ); }
} fdx->CheckedForGenericEpp = TRUE; // check is complete
}
} else { DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip - FAIL\n"); PptDeselectLegacyZip( Context, TrySelectCommand ); Status = STATUS_UNSUCCESSFUL; } } return( Status );
} // end PptTrySelectLegacyZip()
NTSTATUS PptDeselectLegacyZip( IN PVOID Context, IN PVOID DeselectCommand ) { ULONG i; PFDO_EXTENSION fdx = Context; PUCHAR Controller = fdx->PortInfo.Controller; PPARALLEL_1284_COMMAND Command = DeselectCommand;
DD((PCE)fdx,DDT,"par12843::PptDeselectLegacyZip - Enter\n");
for ( i = 0; i < LEGACYZIP_MODE_LEN; i++ ) { PptLegacyZipClockPrtModeByte( Controller, LegacyZipModeQualifier[i] ); }
// set to printer pass thru mode
PptLegacyZipClockPrtModeByte( Controller, (UCHAR)0x0F );
// check if requester wants to keep port or free port
if( !(Command->CommandFlags & PAR_HAVE_PORT_KEEP_PORT) ) { PptFreePort( fdx ); }
return STATUS_SUCCESS;
} // end PptDeselectLegacyZip()
VOID P5SelectLegacyZip( IN PUCHAR Controller ) // select Legacy Zip drive in NIBBLE/BYTE mode - use this only for PnP
// detection of drive so that drive will answer a subsequent check
// drive command
//
// N.B. caller must own (lock for exclusive access) the port prior to
// calling this function
{ PptLegacyZipSetDiskMode( Controller, (UCHAR)0x8F ); }
VOID P5DeselectLegacyZip( IN PUCHAR Controller ) // deselect drive - set Legacy Zip drive to printer pass thru mode
{ ULONG i; for ( i = 0; i < LEGACYZIP_MODE_LEN; i++ ) { PptLegacyZipClockPrtModeByte( Controller, LegacyZipModeQualifier[i] ); } PptLegacyZipClockPrtModeByte( Controller, (UCHAR)0x0F ); P5WritePortUchar( Controller, 0 ); // set data wires back to zero
}
BOOLEAN P5LegacyZipDetected( IN PUCHAR Controller ) // Detect Legacy Zip drive - return TRUE if Legacy Zip found on port, FALSE otherwise
{ BOOLEAN foundZip;
// Try to select drive so that following CheckDevice will be able
// to determine if there is a legacy zip connected
P5SelectLegacyZip( Controller );
// Try to talk to drive
if( PptLegacyZipCheckDevice( Controller ) ) { foundZip = TRUE; } else { // no drive detected
foundZip = FALSE; }
// send deselect sequence whether we found the drive or not
P5DeselectLegacyZip( Controller );
return foundZip; }
// parclass ppa3x.c follows
PCHAR ParBuildLegacyZipDeviceId() { ULONG size = sizeof(PAR_LGZIP_PSEUDO_1284_ID_STRING) + sizeof(CHAR); PCHAR id = ExAllocatePool(PagedPool, size); if( id ) { RtlZeroMemory( id, size ); RtlCopyMemory( id, ParLegacyZipPseudoId, size - sizeof(CHAR) ); return id; } else { return NULL; } } PCHAR Par3QueryLegacyZipDeviceId( IN PPDO_EXTENSION Extension, OUT PCHAR CallerDeviceIdBuffer, OPTIONAL IN ULONG CallerBufferSize, OUT PULONG DeviceIdSize, IN BOOLEAN bReturnRawString // TRUE == include the 2 size bytes in the returned string
// FALSE == discard the 2 size bytes
) { USHORT deviceIdSize; PCHAR deviceIdBuffer;
UNREFERENCED_PARAMETER( Extension ); UNREFERENCED_PARAMETER( bReturnRawString ); // initialize returned size in case we have an error
*DeviceIdSize = 0;
deviceIdBuffer = ParBuildLegacyZipDeviceId(); if( !deviceIdBuffer ) { // error, likely out of resources
return NULL; }
deviceIdSize = (USHORT)strlen(deviceIdBuffer); *DeviceIdSize = deviceIdSize; if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize + sizeof(CHAR) ) ) { // caller supplied buffer is large enough, use it
RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize ); RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize ); ExFreePool( deviceIdBuffer ); return CallerDeviceIdBuffer; } else { // caller buffer too small, return pointer to our buffer
return deviceIdBuffer; } }
|