/*++ Copyright (C) Microsoft Corporation, 1993 - 1998 Module Name: sppieee.c Abstract: This module contains code for the host to utilize an ieee version of compatibility mode Author: Robbie Harris (Hewlett-Packard) 29-July-1998 Environment: Kernel mode Revision History : --*/ #include "pch.h" #include "readwrit.h" NTSTATUS SppIeeeWrite( IN PDEVICE_EXTENSION Extension, IN PVOID Buffer, IN ULONG BytesToWrite, OUT PULONG BytesTransferred ) /*++ Routine Description: Arguments: Extension - Supplies the device extension. Return Value: None. --*/ { NTSTATUS status = STATUS_SUCCESS; PUCHAR Controller = Extension->Controller; PUCHAR pPortDSR = Extension->Controller + OFFSET_DSR; PUCHAR pPortDCR = Extension->Controller + OFFSET_DCR; PUCHAR pPortData = Extension->Controller + OFFSET_DATA; ULONG wByteCount = BytesToWrite; UCHAR bDCRstrobe; // Holds precomputed value for state 35 UCHAR bDCRnormal; // Holds precomputed value for state 37 PUCHAR lpsBufPtr = (PUCHAR)Buffer; // Pointer to buffer cast to desired data type // Make precomputed DCR values for strobe and periph ack bDCRstrobe = SET_DCR(DIR_WRITE, IRQEN_DISABLE, ACTIVE, ACTIVE, ACTIVE, INACTIVE); bDCRnormal = SET_DCR(DIR_WRITE, IRQEN_DISABLE, ACTIVE, ACTIVE, ACTIVE, ACTIVE); // Wait a bit to give nBusy a chance to settle, because // WriteComm will bail immediately if the device says busy if ( CHECK_DSR( Controller, INACTIVE, DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE, IEEE_MAXTIME_TL ) ) { while (wByteCount) { // Place a data byte on the bus WRITE_PORT_UCHAR(pPortData, *lpsBufPtr); // Start handshake by dropping strobe WRITE_PORT_UCHAR(pPortDCR, bDCRstrobe); // Wait for Periph Busy Response if ( !CHECK_DSR(Controller, ACTIVE, DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE, IEEE_MAXTIME_TL) ) { status = STATUS_DEVICE_BUSY; break; } // Printer responded by making Busy high -- the byte has // been accepted. Adjust the data pointer. lpsBufPtr++; // Finish handshake by raising strobe WRITE_PORT_UCHAR(pPortDCR, bDCRnormal); // Adjust count while we're waiting for the peripheral // to respond with state 32 wByteCount--; // Wait for PeriphAck and PeriphBusy response if ( !CHECK_DSR(Controller, INACTIVE, ACTIVE, DONT_CARE, DONT_CARE, DONT_CARE, IEEE_MAXTIME_TL) ) { // Set appropriate error based on relaxed timeout. status = STATUS_DEVICE_BUSY; break; } } // while... *BytesTransferred = BytesToWrite - wByteCount; // Set current count. } return status; }