sc2440_usb_ser.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:45k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /*+
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
- Copyright (c) 2001. Samsung Electronics, co. ltd All rights reserved.
- Module Name:
- Abstract:
- S3C2440 USB function(ACTIVE SYNC) device driver (Wrapper layer)
- rev:
- 2003.3.19 : updated for USB-DMA (purnnamu)
- 2002.5.7 : Add to s3c2410_code (Seung-han, Lim)
- 2002.1.22 : First release/no error recovery (kwangyoon LEE, kwangyoon@samsung.com)
- Notes:
- */
- #include <windows.h>
- #include <types.h>
- #include <ceddk.h>
- #include <memory.h>
- #include <notify.h>
- #include <serhw.h>
- #include "S2440.h"
- #include <SC2440_usb_hw.h>
- #include <SC2440_usb_ser.h>
- #include <nkintr.h>
- #include <oalintr.h>
- #include <devload.h>
- #include <windev.h>
- #undef ZONE_INIT
- #include <serdbg.h>
- #include <celog.h>
- #include <drv_glob.h> //:-)
- extern VOID SerialEventHandler(PVOID pHead);
- extern void msWait(unsigned msVal);
- extern volatile USBD_GLOBALS *usbdShMem; //:-)
- __inline static VOID
- SignalRemoval( PSER_INFO pHWHead )
- {
- pHWHead->ModemStatus &= ~MS_RLSD_ON;
- EvaluateEventFlag(pHWHead->pMddHead, EV_RLSD);
- }
- static
- DWORD WINAPI SerEventThread(PSER_INFO pHWHead)
- {
- ULONG WaitReturn;
- static HWND fgp=NULL, prev_fgp = NULL;
- static HWND dialog_hwnd = NULL;
- static ULONG firstplug = 0, toretry = 0;
- static PROCESS_INFORMATION pi_usbcnect, pi_repllog;
- DEBUGMSG(1, (TEXT("++SerEventThreadrn")));
- DEBUGMSG(1, (TEXT("Spinning in dispatch thread %Xnr"), pHWHead));
- while (!pHWHead->pDispatchThread)
- Sleep(20);
- while (!pHWHead->KillRxThread) {
- DEBUGMSG (1, (TEXT("Event %X, Index %d, Int %drn"),
- pHWHead->hSerialEvent,
- pHWHead->dwDevIndex,
- pHWHead->pHWObj->dwIntID ));
- // Ugly. We don't get an interrupt when we are unplugged from the
- // bus, but we'd like to know when that happens. So we use a timeout
- // on our interrupt wait. This effectively allows me to poll the SOF
- // status, and if SOFs stop arriving, I'll assume we have been
- // disconnected from the bus. Wait is last, allowing us to essentially
- // spoof one interrupt right at startup.
- // Only poll if we are opened and active. Otherwise no one cares
- #ifdef POLL_FOR_DISCONNECT
- if (pHWHead->cOpenCount && pHWHead->dConfIdx)
- {
- // DEBUGMSG(1, (TEXT("waitforsingleobject in uprn")));
- WaitReturn = WaitForSingleObject(pHWHead->hSerialEvent, SC2440_USB_POLL_RATE);
- // DEBUGMSG(1, (TEXT("waitforsingleobject inrn")));
- }
- else
- #endif
- {
- //DEBUGMSG(1, (TEXT("waitforsingleobject out uprn")));
- WaitReturn = WaitForSingleObject(pHWHead->hSerialEvent, INFINITE);
- /*
- DEBUGMSG(1, (TEXT("waitforsingleobject outrn")));
- if (WaitReturn == WAIT_ABANDONED)
- {
- DEBUGMSG(1, (TEXT("WAIT_ABANDONEDrn")));
- }
- if (WaitReturn == WAIT_OBJECT_0)
- {
- DEBUGMSG(1, (TEXT("WAIT_OBJECT_0rn")));
- }
- if (WaitReturn == WAIT_TIMEOUT)
- {
- DEBUGMSG(1, (TEXT("WAIT_TIMEOUTrn")));
- }
- if (WaitReturn == WAIT_FAILED)
- {
- DEBUGMSG(1, (TEXT("WAIT_FAILEDrn")));
- }
- */
- }
- SerialEventHandler(pHWHead->pMddHead);
- InterruptDone(pHWHead->pHWObj->dwIntID);
- }
- DEBUGMSG (1, (TEXT("--SerEventThread %x exitingrn"), pHWHead));
- return (0);
- }
- static
- BOOL StartEventThread(PSER_INFO pHWHead)
- {
- // Initialize the interrupt to be associated with the hSerialEvent
- // event. If this call fails, then another process has registered
- // for the interrupt, so fail the init and set the hSerialEvent to NULL.
- DEBUGMSG(1, (TEXT("Initializing interrupt 0x%X, 0x%Xnr"),
- pHWHead->pHWObj->dwIntID, pHWHead->hSerialEvent));
- if (!InterruptInitialize(pHWHead->pHWObj->dwIntID, pHWHead->hSerialEvent, 0, 0))
- {
- DEBUGMSG(1, (TEXT("Error initializing interruptnr")));
- return (FALSE);
- }
- InterruptDone(pHWHead->pHWObj->dwIntID);
- // Now set up the dispatch thread
- pHWHead->KillRxThread = 0;
- DEBUGMSG(1, (TEXT("Spinning thread%Xnr"), pHWHead));
- pHWHead->pDispatchThread = CreateThread(NULL,0, SerEventThread,
- pHWHead, 0,NULL);
- if (pHWHead->pDispatchThread == NULL)
- {
- DEBUGMSG(1, (TEXT("Error creating Event thread (%d)nr"), GetLastError()));
- return (FALSE);
- }
- DEBUGMSG (1, (TEXT("Created Event thread %Xrn"), pHWHead->pDispatchThread));
- DEBUGMSG (1, (TEXT("About to set priorityrn")));
- CeSetThreadPriority(pHWHead->pDispatchThread, DEFAULT_THREAD_PRIO);
- DEBUGMSG (1, (TEXT("Back from setting priorityrn")));
- return (TRUE);
- }
- /***************************************************************
- @doc OEM
- @func VOID | SerSetBaudRate |
- * This routine sets the baud rate of the device.
- * Not exported to users, only to driver.
- *
- @rdesc None.
- ****************************************************************/
- static
- BOOL SerSetBaudRate( PVOID pHead, // @parm PVOID returned by SerInit
- ULONG BaudRate ) // @parm ULONG representing decimal baud rate.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("SerSetBaudRatern")));
- // Baudrate is meaningless. Just be agreeable and say we did it.
- return (TRUE);
- }
- /****************************************************************
- @doc INTERNAL
- @func VOID | SerUSB_InternalMapRegisterAddresses |
- This routine maps the ASIC registers.
- It's an artifact of this
- implementation.
- @rdesc None.
- ****************************************************************/
- static
- void SerUSBInternalMapRegisterAddresses( PSER_INFO pHWHead )
- {
- PUCHAR pVMem;
- BOOL bMapReturn;
- ULONG err = 0;
- DEBUGMSG(1, (TEXT("++SerUSBInternalMapRegisterAddressesrn")));
- // Map CSR registers.
- pVMem = (PUCHAR)VirtualAlloc(0, PAGE_SIZE*2, MEM_RESERVE, PAGE_NOACCESS);
- if (pVMem)
- {
- DEBUGMSG(1, (TEXT("VirtualAlloc Succeededrn")));
- bMapReturn = VirtualCopy( pVMem,
- (LPVOID)pHWHead->dwIOBase,
- PAGE_SIZE,
- PAGE_READWRITE | PAGE_NOCACHE );
- if (!bMapReturn)
- {
- err = GetLastError();
- DEBUGMSG(1, (TEXT("Virtual Copy: Serial SPACE FAILEDrn")));
- }
- pVMem = (BYTE *)pVMem;
- pHWHead->pUSBCtrlAddr=(volatile struct udcreg *)((BYTE *)pVMem + 0x140); // offset
- bMapReturn = VirtualCopy( pVMem+PAGE_SIZE,
- (LPVOID)IOP_BASE,
- PAGE_SIZE,
- PAGE_READWRITE | PAGE_NOCACHE );
- if (!bMapReturn)
- {
- err = GetLastError();
- DEBUGMSG(1, (TEXT("Virtual Copy: IOP SPACE FAILEDrn")));
- }
- pHWHead->pIrqCtrlAddr=(volatile IOPreg *)(pVMem+PAGE_SIZE);
- bMapReturn = VirtualCopy( pVMem+PAGE_SIZE,
- (LPVOID)CLKPWR_BASE,
- PAGE_SIZE,
- PAGE_READWRITE | PAGE_NOCACHE );
- if (!bMapReturn)
- {
- err = GetLastError();
- DEBUGMSG(1, (TEXT("Virtual Copy: CLKPWR SPACE FAILEDrn")));
- }
- pHWHead->pCLKPWR = (volatile CLKPWRreg *)(pVMem+PAGE_SIZE);
- } else {
- DEBUGMSG(1, (TEXT("Virtual Alloc: FAILEDrn")));
- }
- DEBUGMSG(1, (TEXT("VirtualCopy Succeeded, pVMem:%xrn"), pVMem));
- DEBUGMSG(1, (TEXT("--SerUSBInternalMapRegisterAddressesrn")));
- }
- static
- BOOL SerSetIRBaudRate( PSER_INFO pHWHead, ULONG baud ) // @parm baud rate - ignored
- {
- DEBUGMSG(1, (TEXT("Serial set IR Baud %drn"), baud));
- // We don't support IR
- return (FALSE);
- }
- /*******************************************************************************
- Routine:
- Ser_GetRegistryData
- Description:
- Take the registry path provided to COM_Init and use it to find this
- requested comm port's DeviceArrayIndex, the IOPort Base Address, and the
- Interrupt number.
- Arguments:
- LPCTSTR regKeyPath the registry path passed in to COM_Init.
- Return Value:
- -1 if there is an error.
- ******************************************************************************/
- static
- BOOL Ser_GetRegistryData(PSER_INFO pHWHead, LPCTSTR regKeyPath)
- {
- #define GCI_BUFFER_SIZE 256
- LONG regError;
- HKEY hKey;
- TCHAR devKeyPath[GCI_BUFFER_SIZE];
- DWORD dwDataSize = GCI_BUFFER_SIZE;
- DEBUGMSG(1,
- (TEXT("Ser_GetRegistryData Try to open %srn"),regKeyPath));
- // We've been handed the name of a key in the registry that was generated
- // on the fly by device.exe. We're going to open that key and pull from it
- // a value that is the name of this serial port's real key. That key
- // will have the DeviceArrayIndex that we're trying to find.
- regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- regKeyPath,
- 0,
- KEY_ALL_ACCESS,
- &hKey);
- if (regError != ERROR_SUCCESS)
- {
- DEBUGMSG(1,(TEXT("Failed to open %s, Error 0x%Xrn"),regKeyPath,regError));
- return (FALSE);
- }
- regError = RegQueryValueEx( hKey,
- DEVLOAD_DEVKEY_VALNAME,
- NULL,
- NULL,
- (LPBYTE)devKeyPath,
- &dwDataSize);
- // We're done with that registry key, so close it.
- RegCloseKey (hKey);
- if (regError != ERROR_SUCCESS)
- {
- DEBUGMSG(1, (TEXT("Failed to find data at %s\%s, Error 0x%Xrn"),
- regKeyPath, DEVLOAD_DEVKEY_VALNAME, regError));
- return (FALSE);
- }
- DEBUGMSG(1, (TEXT("Try to open %srn"), devKeyPath));
- regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- devKeyPath,
- 0,
- KEY_ALL_ACCESS,
- &hKey);
- if (regError != ERROR_SUCCESS)
- {
- DEBUGMSG(1,(TEXT("Failed to open %s, Error 0x%Xrn"), devKeyPath, regError));
- return (FALSE);
- }
- // Okay, we're finally ready to try and load our registry data.
- dwDataSize = SC2440USB_REG_DEVINDEX_VAL_LEN;
- regError = RegQueryValueEx(hKey,
- SC2440USB_REG_DEVINDEX_VAL_NAME,
- NULL,
- NULL,
- (LPBYTE)(&pHWHead->dwDevIndex),
- &dwDataSize);
- if (regError == ERROR_SUCCESS)
- {
- dwDataSize = SC2440USB_REG_IRQ_VAL_LEN;
- regError = RegQueryValueEx( hKey,
- SC2440USB_REG_IRQ_VAL_NAME,
- NULL,
- NULL,
- (LPBYTE)(&pHWHead->dwIRQ),
- &dwDataSize );
- }
- if (regError == ERROR_SUCCESS)
- {
- dwDataSize = SC2440USB_REG_IOBASE_VAL_LEN;
- regError = RegQueryValueEx( hKey,
- SC2440USB_REG_IOBASE_VAL_NAME,
- NULL,
- NULL,
- (LPBYTE)(&pHWHead->dwIOBase),
- &dwDataSize);
- }
- if (regError == ERROR_SUCCESS)
- {
- dwDataSize = SC2440USB_REG_IOLEN_VAL_LEN;
- regError = RegQueryValueEx( hKey,
- SC2440USB_REG_IOLEN_VAL_NAME,
- NULL,
- NULL,
- (LPBYTE)(&pHWHead->dwIOLen),
- &dwDataSize);
- }
- RegCloseKey (hKey);
- if (regError != ERROR_SUCCESS)
- {
- DEBUGMSG(1,(TEXT("Failed to get serial registry values, Error 0x%Xrn"),
- regError));
- return (FALSE);
- }
- DEBUGMSG(1,(TEXT("SerInit - Devindex %d, IRQ %d, IOB %X, IOLen %X rn"),
- pHWHead->dwDevIndex,
- pHWHead->dwIRQ,
- pHWHead->dwIOBase,
- pHWHead->dwIOLen));
- return (TRUE);
- }
- /*************************************************************************
- @doc OEM
- @func PVOID | SerInit | Initializes device identified by argument.
- * This routine sets information controlled by the user
- * such as Line control and baud rate. It can also initialize events and
- * interrupts, thereby indirectly managing initializing hardware buffers.
- * Exported only to driver, called only once per process.
- *
- @rdesc The return value is a PVOID to be passed back into the HW
- dependent layer when HW functions are called.
- ************************************************************************/
- static
- PVOID SerInit( ULONG Identifier, // @parm Device identifier.
- PVOID pMddHead, // @parm First argument to mdd callbacks.
- PHWOBJ pHWObj ) // @parm Pointer to our own HW OBJ for this device
- {
- PSER_INFO pHWHead;
- PHYSICAL_ADDRESS PhysicalAddress = {0,0};
- #ifdef DEBUG
- dpCurSettings.ulZoneMask = 0;
- #endif
- DEBUGMSG (1, (TEXT("++SerInit %Xrn"), pMddHead ));
- // Allocate for our main data structure and one of it's fields.
- pHWHead = (PSER_INFO)LocalAlloc( LPTR, sizeof(SER_INFO) );
- if ( !pHWHead )
- goto ALLOCFAILED;
- if (!Ser_GetRegistryData(pHWHead, (LPCTSTR)Identifier))
- {
- DEBUGMSG (1,(TEXT("SerInit - Unable to read registry data. Failing Init !!! rn")));
- goto ALLOCFAILED;
- }
- // Create our interrupt event.
- pHWHead->hSerialEvent = CreateEvent(0,FALSE,FALSE,NULL);
- // Initialize our critical sections
- InitializeCriticalSection(&(pHWHead->TransmitCritSec));
- InitializeCriticalSection(&(pHWHead->HwRegCritSec));
- SerUSBInternalMapRegisterAddresses(pHWHead);
- if(!InitUsbdDriverGlobals()) //:-)
- goto ALLOCFAILED;
- if(!UsbdAllocateVm()) //:-)
- goto ALLOCFAILED;
- pHWHead->pMddHead = pMddHead;
- pHWHead->cOpenCount = 0;
- pHWHead->pHWObj = pHWObj;
- pHWHead->wSOFStableCnt = 0;
- // Set up our Comm Properties data
- pHWHead->CommProp.wPacketLength = 0xffff;
- pHWHead->CommProp.wPacketVersion = 0xffff;
- pHWHead->CommProp.dwServiceMask = SP_SERIALCOMM;
- pHWHead->CommProp.dwReserved1 = 0;
- pHWHead->CommProp.dwMaxTxQueue = 64;
- pHWHead->CommProp.dwMaxRxQueue = 64;
- pHWHead->CommProp.dwMaxBaud = BAUD_115200;
- pHWHead->CommProp.dwProvSubType = PST_RS232;
- pHWHead->CommProp.dwProvCapabilities = PCF_RLSD |
- PCF_SETXCHAR |
- PCF_INTTIMEOUTS |
- PCF_SPECIALCHARS |
- PCF_TOTALTIMEOUTS |
- PCF_XONXOFF;
- pHWHead->CommProp.dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_150 |
- BAUD_300 | BAUD_600 |
- BAUD_1200 | BAUD_1800 |
- BAUD_2400 | BAUD_4800 |
- BAUD_7200 | BAUD_9600 | BAUD_14400 |
- BAUD_19200 | BAUD_38400 |
- BAUD_56K | BAUD_128K |
- BAUD_115200 | BAUD_57600 | BAUD_USER;
- pHWHead->CommProp.dwSettableParams = SP_BAUD | SP_RLSD ;
- pHWHead->CommProp.wSettableData = DATABITS_8;
- pHWHead->CommProp.wSettableStopParity = STOPBITS_10 | STOPBITS_20 |
- PARITY_NONE | PARITY_ODD |
- PARITY_EVEN | PARITY_SPACE |
- PARITY_MARK;
- pHWHead->fIRMode = FALSE; // Select wired by default
- pHWHead->State = IDLE;
- // Here is where we do any actual init for the hardware. In the case of
- // USB function, we mostly just validate the hardware and then enable
- // interrupts. When we detect the presence of the bus, GetIntr will take
- // care of identify us to the host and kicking things off.
- SC2440_USB_Init(pHWHead);
- DEBUGMSG (1, (TEXT("--SerInit - %Xrn"), pHWHead ));
- return (pHWHead);
- ALLOCFAILED:
- // Unmap any memory areas that we may have mapped.
- if ( pHWHead->pUSBCtrlAddr)
- VirtualFree((PVOID)pHWHead->pUSBCtrlAddr, 0, MEM_RELEASE);
- if ( pHWHead->pIrqCtrlAddr)
- VirtualFree((PVOID)pHWHead->pIrqCtrlAddr, 0, MEM_RELEASE);
- if ( pHWHead->pCLKPWR)
- VirtualFree((PVOID)pHWHead->pCLKPWR, 0, MEM_RELEASE);
- LocalFree(pHWHead);
- // Free any critical sections we have allocated
- DeleteCriticalSection(&(pHWHead->TransmitCritSec));
- DeleteCriticalSection(&(pHWHead->HwRegCritSec));
- // And free the context data structure
- LocalFree(pHWHead);
- DEBUGMSG (1,(TEXT("--SerInit - %Xrn"), pHWHead ));
- return (NULL);
- }
- /*************************************************************************
- @doc OEM
- @func PVOID | SerPostInit | Performs final hardware initialization.
- ************************************************************************/
- static
- BOOL SerPostInit(PVOID pHead) // @parm PVOID returned by SerInit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("+++SerPostInitrn")));
- // We use a PDD specific thread, rather than the default thread provided
- // by the MDD.
- StartEventThread( pHWHead );
- // Enable interrupts after thread is started - DAL
- // ....
- return TRUE;
- }
- /*************************************************************************
- @doc OEM
- @func PVOID | SerDeinit | Deinitializes device identified by argument.
- * This routine frees any memory allocated by SerInit.
- ************************************************************************/
- static
- BOOL SerDeinit(PVOID pHead) // @parm PVOID returned by SerInit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("+SerDeinitrn")));
- // Disable interrupts
- // ...
- if ( !pHWHead )
- return (FALSE);
- // Make sure device is closed before doing DeInit
- if ( pHWHead->cOpenCount )
- SerClose( pHead );
- if ( pHWHead->pUSBCtrlAddr)
- VirtualFree((PVOID)pHWHead->pUSBCtrlAddr, 0, MEM_RELEASE);
- if ( pHWHead->pIrqCtrlAddr)
- VirtualFree((PVOID)pHWHead->pIrqCtrlAddr, 0, MEM_RELEASE);
- if ( pHWHead->pCLKPWR)
- VirtualFree((PVOID)pHWHead->pCLKPWR, 0, MEM_RELEASE);
- UsbdDeallocateVm(); //:-)
- // Free any critical sections we have allocated
- DeleteCriticalSection(&(pHWHead->TransmitCritSec));
- DeleteCriticalSection(&(pHWHead->HwRegCritSec));
- // Free the HWObj allocated in GetSerialObject
- LocalFree(pHWHead->pHWObj);
- LocalFree(pHWHead);
- DEBUGMSG(1, (TEXT("-SerDeinitrn")));
- return (TRUE);
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerOpen | This routine is called when the port is opened.
- * Not exported to users, only to driver.
- *
- @rdesc Returns TRUE if successful, FALSEotherwise.
- ************************************************************************/
- static
- BOOL SerOpen(PVOID pHead) /*@parm PVOID returned by Serinit. */
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1,
- (TEXT("SerOpen+rn")));
- // Disallow multiple simultaneous opens
- if (pHWHead->cOpenCount)
- return (FALSE);
- pHWHead->cOpenCount++;
- #ifdef POLL_FOR_DISCONNECT
- // Yuck. We want to poll for detaches when the device is open.
- // But right now, the IST is in a wait infinite. Spoof an interrupt
- // to let him know we have been opened and he needs to start polling.
- SetEvent(pHWHead->hSerialEvent);
- #endif
- return (TRUE);
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerClose | This routine closes the device identified by the
- * PVOID returned by SerInit.
- * Not exported to users, only to driver.
- *
- @rdesc The return value is 0.
- ************************************************************************/
- static
- ULONG SerClose(PVOID pHead) // @parm PVOID returned by SerInit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG (1, (TEXT("++SerClosern")));
- if (pHWHead->cOpenCount)
- {
- DEBUGMSG (1, (TEXT("SerClose, closing devicern")));
- pHWHead->cOpenCount--;
- #ifdef TODO
- // Do we need something similar on USB???
- // while we are still transmitting, sleep.
- uTries = 0;
- while ( ((pHWHead->ser16550.IER = READ_PORT_UCHAR(pHWHead->ser16550.pIER))
- & SERIAL_IER_THR) && // indicates TX in progress
- (uTries++ < 100) && // safety net
- // indicates FIFO not yet empty
- !(pHWHead->ser16550.LSR & SERIAL_LSR_TEMT))
- {
- DEBUGMSG(1, (TEXT("SerClose, TX in progress, IER 0x%X, LSR 0x%Xrn"),
- *pHWHead->ser16550.pIER, pHWHead->ser16550.LSR));
- Sleep(10);
- }
- #endif
- // TODO - When the device is closed, should power it down or somehow try to
- // let the desktop know that we aren't doing anything with any data that it
- // might be sending our way..
- // Mask interrupts? - No, we wont see any more traffic - MBE.
- //pHWHead->pIrqCtrlAddr->icmr.sp0 = 0;
- }
- DEBUGMSG(1,(TEXT("--SerClosern")));
- return (0);
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerRxIntr | This routine gets several characters from the
- hardware receive buffer and puts them in a buffer provided via the se-
- cond argument. It returns the number of bytes lost to overrun.
- @rdesc The return value indicates the number of overruns detected.
- The actual number of dropped characters may be higher.
- **************************************************************************/
- static
- ULONG SerRxIntr(PVOID pHead, // @parm Pointer to hardware head
- PUCHAR pRxBuffer, // @parm Pointer to receive buffer
- ULONG *pBufflen ) // @parm In = max bytes to read, out = bytes read
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- ULONG RetVal = 0;
- ULONG TargetRoom = *pBufflen;
- BOOL fRXFlag = FALSE;
- BOOL fReplaceparityErrors = FALSE;
- BOOL fNull;
- UCHAR cEvtChar;
- PUCHAR pRxOrig = pRxBuffer;
- DEBUGMSG(1, (TEXT("++SerRxIntr %drn"), *pBufflen));
- cEvtChar = pHWHead->dcb.EvtChar;
- fNull = pHWHead->dcb.fNull;
- if( pHWHead->dcb.fErrorChar && pHWHead->dcb.fParity )
- fReplaceparityErrors = TRUE;
- // Protect the following from collision on hardware registers.
- // In particular, we can't let anyone else do SC2440_USB_ accesses between
- // time we set the read address and time we do the actual read in
- // the loop below.
- EnterCriticalSection(&(pHWHead->HwRegCritSec));
- fRXFlag = SC2440_USB_RxIntHandler(pHWHead, pRxBuffer, pBufflen);
- LeaveCriticalSection(&(pHWHead->HwRegCritSec));
- // if we saw one (or more) EVT chars, then generate an event
- if( fRXFlag )
- EvaluateEventFlag( pHWHead->pMddHead, EV_RXFLAG );
- #ifdef DEBUG
- if( ZONE_RXDATA )
- CELOGDATA(1, CELID_RAW_UCHAR, pRxOrig, (WORD)*pBufflen, 1, CELZONE_MISC);
- #endif
- DEBUGMSG(1, (TEXT("--SerRxIntr - rx %d, drop %d.rn"),
- *pBufflen,
- pHWHead->DroppedBytes));
- RetVal = pHWHead->DroppedBytes;
- pHWHead->DroppedBytes = 0;
- return RetVal;
- }
- /*************************************************************************
- @doc OEM
- @func PVOID | SerGetRxStart | This routine returns the start of the
- hardware receive buffer. See SerGetRxBufferSize.
- @rdesc The return value is a pointer to the start of the device
- receive buffer.
- *************************************************************************/
- static
- PVOID SerGetRxStart( PVOID pHead ) // @parm PVOID returned by Serinit.
- {
- DEBUGMSG(1, (TEXT("SerGetRxStartrn")));
- return NULL;
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerGetInterruptType | This function is called
- by the MDD whenever an interrupt occurs. The return code
- is then checked by the MDD to determine which of the four
- interrupt handling routines are to be called.
- @rdesc This routine returns a bitmask indicating which interrupts
- are currently pending.
- *************************************************************************/
- static
- INTERRUPT_TYPE SerGetInterruptType( PVOID pHead ) // Pointer to hardware head
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- INTERRUPT_TYPE interrupts=0;
- DEBUGMSG(1, (TEXT("++SerGetInterruptType 0x%Xrn"), pHead));
- interrupts = SC2440_USB_GetInterruptType(pHWHead);
- if (INTR_LINE & interrupts)
- {
- pHWHead->dConfIdx = 0;
- SignalRemoval(pHWHead);
- }
- #ifdef POLL_FOR_DISCONNECT
- //interrupts = HW_GetInterruptType(pHWHead);
- //RETAILMSG(1, (TEXT("interrupts = 0x%xrn"), interrupts));
- if (interrupts)
- {
- pHWHead->wSOFStableCnt = 0;
- //RETAILMSG(1, (TEXT("pHWHead->wSOFStableCnt = 0x%xrn"), pHWHead->wSOFStableCnt));
- }
- else if (pHWHead->dConfIdx && (pHWHead->wPrevSOF == pHWHead->wSOF))
- {
- if (++pHWHead->wSOFStableCnt > SOF_STABLE_MAX)
- {
- //RETAILMSG(1, (TEXT("DCD Dropped due to: wSOFStableCnt: %urn"), pHWHead->wSOFStableCnt));
- pHWHead->dConfIdx = 0;
- SignalRemoval(pHWHead);
- }
- }
- #endif
- DEBUGMSG (1, (TEXT("--SerGetInterruptType 0x%X, 0x%Xrn"),
- pHead, interrupts));
- return interrupts;
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerModemIntr | This routine is called from the MDD
- whenever INTR_MODEM is returned by SerGetInterruptType.
- @rdesc None
- *************************************************************************/
- static
- VOID SerModemIntr( PVOID pHead ) // Hardware Head
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DWORD dwModemStatus;
- dwModemStatus = pHWHead->ModemStatus;
- DEBUGMSG(1, (TEXT("+++SerModemIntrrn")));
- SC2440_USB_DoEndpoint0(pHWHead, &dwModemStatus);
- if ( pHWHead->dConfIdx )
- {
- if ( pHWHead->cOpenCount)
- {
- // If open, notify app of any control line changes.
- DEBUGMSG(1, (TEXT("Modem Status %2.2X <> %2.2Xrn"),
- pHWHead->ModemStatus, dwModemStatus));
- if( (pHWHead->ModemStatus & MS_DSR_ON) != (dwModemStatus & MS_DSR_ON) )
- EvaluateEventFlag(pHWHead->pMddHead, EV_DSR);
- if( (pHWHead->ModemStatus & MS_CTS_ON) != (dwModemStatus & MS_CTS_ON) )
- EvaluateEventFlag(pHWHead->pMddHead, EV_CTS);
- if( (pHWHead->ModemStatus & MS_RLSD_ON) != (dwModemStatus & MS_RLSD_ON) )
- EvaluateEventFlag(pHWHead->pMddHead, EV_RLSD);
- } else {
- // If RLSD transitioned to active, we need to generate event.
- if( (dwModemStatus & MS_RLSD_ON) && !(pHWHead->ModemStatus & MS_RLSD_ON) )
- {
- if ( IsAPIReady(SH_WMGR) )
- {
- CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED, NULL);
- }
- DEBUGMSG (0, (TEXT("Indicated RS232 Cable Eventrn")));
- }
- }
- }
- pHWHead->ModemStatus = dwModemStatus;
- DEBUGMSG(1, (TEXT("---SerModemIntrrn")));
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerLineIntr | This routine is called from the MDD
- whenever INTR_LINE is returned by SerGetInterruptType.
- @rdesc None
- *************************************************************************/
- static
- VOID SerLineIntr( PVOID pHead ) // Hardware Head
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("SerLineIntrrn")));
- // USB serial doesn't have a concept of anything like the LSR.
- // But since a bus reset is what we sort of equate to DCD, I use
- // this routine to handle USB reset conditions.
- // Note that by the time we get here with an SC2440_USB , we are actually
- //plugged back into the bus. I added some polling code to try and detect
- // detaches sooner
- SC2440_USB_LineIntHandler(pHWHead); // Re-initialize the hardware
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerGetRxBufferSize | This function returns
- the size of the hardware buffer passed to the interrupt
- initialize function. It would be used only for devices
- which share a buffer between the MDD/PDD and an ISR.
- @rdesc This routine always returns 0 for 16550 UARTS.
- **************************************************************************/
- static
- ULONG SerGetRxBufferSize( PVOID pHead )
- {
- DEBUGMSG(1, (TEXT("SerGetRxBufferSizern")));
- return 10280;
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerTXIntr | This routine is called from the new MDD
- whenever INTR_TX is returned by SerGetInterruptType. It is
- responsible for loading up the TX FIFO with next block of data.
- @rdesc None
- **************************************************************************/
- static
- VOID SerTxIntr( PVOID pHead, // Hardware Head
- PUCHAR pTxBuffer, // @parm Pointer to receive buffer
- ULONG *pBuffLen ) // @parm In = max bytes to transmit,
- // out = bytes transmitted
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("SerTxIntr+rn")));
- pHWHead->CommErrors &= ~CE_TXFULL;
- SC2440_USB_TxIntHandler(pHWHead, pTxBuffer, pBuffLen);
- DEBUGMSG(1, (TEXT("SerTxIntr-, %d bytesrn"), *pBuffLen));
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerPowerOff | Called by driver to turn off power to
- serial port.
- Not exported to users, only to driver.
- @rdesc This routine returns a status.
- ************************************************************************/
- static
- BOOL SerPowerOff( PVOID pHead ) // @parm PVOID returned by SerInit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- pHWHead->cOpenCount = 0;
- //RETAILMSG(1,(TEXT("USB : SerPowerOff rn")));
- /*
- if ( pHWHead->cOpenCount )
- {
- EvaluateEventFlag( pHWHead->pMddHead, EV_RXFLAG );
- }
- return (TRUE);
- */
- return HW_PowerOff(pHead);
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerPowerOn |
- Called by driver to turn on power to serial port.
- Not exported to users, only to driver.
- @rdesc This routine returns a status.
- ************************************************************************/
- static
- BOOL SerPowerOn( PVOID pHead ) // @parm PVOID returned by SerInit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- //RETAILMSG(1,(TEXT("USB : SerPowerOn rn")));
- return HW_PowerOn(pHead);
- }
- /*************************************************************************
- @doc OEM
- @func void | SerClearDtr | This routine clears DTR.
- @rdesc None.
- **************************************************************************/
- static
- VOID SerClearDTR( PVOID pHead ) // @parm PVOID returned by HWinit.
- {
- DEBUGMSG(1, (TEXT("SerClearDTR, 0x%Xrn"), pHead));
- // We don't support DTR emulation.
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerSetDTR | This routine sets DTR.
- @rdesc None.
- **************************************************************************/
- static
- VOID SerSetDTR( PVOID pHead ) // @parm PVOID returned by HWinit.
- {
- DEBUGMSG(1, (TEXT("SerSetDTR, 0x%Xrn"), pHead));
- // We don't support DTR emulation.
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerClearRTS | This routine clears RTS.
- @rdesc None.
- **************************************************************************/
- static
- VOID SerClearRTS( PVOID pHead ) // @parm PVOID returned by HWinit.
- {
- DEBUGMSG(1, (TEXT("SerClearRTS, 0x%Xrn"), pHead));
- // We don't support RTS emulation.
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerSetRTS | This routine sets RTS.
- @rdesc None.
- **************************************************************************/
- static
- VOID SerSetRTS( PVOID pHead ) // @parm PVOID returned by HWinit.
- {
- DEBUGMSG(1, (TEXT("SerSetRTS, 0x%Xrn"), pHead));
- // We don't support RTS emulation.
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerEnableIR | This routine enables ir.
- Not exported to users, only to driver.
- @rdesc Returns TRUE if successful, FALSEotherwise.
- **************************************************************************/
- static
- BOOL SerEnableIR( PVOID pHead, // @parm PVOID returned by Serinit.
- ULONG BaudRate ) // @parm PVOID returned by HWinit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("SerEnableIR, 0x%Xrn"), pHead));
- // We don't support an IR mode, so fail.
- return (FALSE);
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerDisableIR | This routine disable the ir.
- Not exported to users, only to driver.
- @rdesc Returns TRUE if successful, FALSEotherwise.
- **************************************************************************/
- static
- BOOL SerDisableIR( PVOID pHead ) // @parm PVOID returned by Serinit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("SerDisableIR, 0x%Xrn"), pHead));
- // We don't support an IR mode. But don't fail, in case
- // someone calls this redundantly to ensure that we are
- // in wired mode, which is what we support.
- return (TRUE);
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerClearBreak | This routine clears break.
- @rdesc None.
- *************************************************************************/
- static
- VOID SerClearBreak( PVOID pHead ) // @parm PVOID returned by HWinit.
- {
- DEBUGMSG(1, (TEXT("SerClearBreak, 0x%Xrn"), pHead));
- // We don't have a concept of break over USB serial
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerSetBreak | This routine sets break.
- @rdesc None.
- *************************************************************************/
- static
- VOID SerSetBreak( PVOID pHead ) // @parm PVOID returned by HWinit.
- {
- DEBUGMSG(1, (TEXT("SerSetBreak, 0x%Xrn"), pHead));
- // We don't have a concept of break over USB serial
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerXmitComChar | Transmit a char immediately
- @rdesc TRUE if succesful
- *************************************************************************/
- static
- BOOL SerXmitComChar( PVOID pHead, // @parm PVOID returned by HWInit.
- UCHAR ComChar ) // @parm Character to transmit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("+SerXmitComChar 0x%Xrn"), pHead));
- // Get critical section, then transmit when buffer empties
- DEBUGMSG(1, (TEXT("XmitComChar wait for CritSec %x.rn"),
- &(pHWHead->TransmitCritSec)));
- EnterCriticalSection(&(pHWHead->TransmitCritSec));
- DEBUGMSG(1, (TEXT("XmitComChar got CritSec %x.rn"),
- &(pHWHead->TransmitCritSec)));
- try
- {
- // TODO - We need to wait for the current transmit to finish and
- // then sneak this data in ahead of whatever else is queued.
- #ifdef TODO
- while( TRUE ) // We know THR will eventually empty
- {
- // Write the character if we can
- ReadLSR( pHWHead );
- if( pHWHead->LSR & SERIAL_LSR_THRE )
- {
- OUTB(pHWHead, pData, ComChar);
- DEBUGMSG(1, (TEXT("XmitComChar wrote x%Xrn"), ComChar));
- break;
- }
- // If we couldn't write the data yet, then wait for a
- // TXINTR to come in and try it again.
- // Enable xmit intr.
- OUTB(pHWHead, pIER, IER_NORMAL_INTS | SERIAL_IER_THR);
- // Wait until the txintr has signalled.
- DEBUGMSG(1, (TEXT("XmitComChar WaitIntr x%Xrn"),
- pHWHead->FlushDone));
- WaitForSingleObject(pHWHead->FlushDone, (ULONG)1000);
- }
- #else
- DEBUGMSG (0, (TEXT("!!! SerXmitComChar 0x%X not implementedrn"),
- pHead));
- #endif
- }
- except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
- EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
- {
- // Just exit
- }
- LeaveCriticalSection(&(pHWHead->TransmitCritSec));
- DEBUGMSG(1, (TEXT("XmitComChar released CritSec %x.rn"),
- &(pHWHead->TransmitCritSec)));
- DEBUGMSG(1, (TEXT("-SerXmitComChar 0x%Xrn"), pHead));
- return TRUE;
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerGetStatus | This structure is called by the MDD
- to retrieve the contents of a COMSTAT structure.
- @rdesc The return is a ULONG, representing success (0) or failure (-1).
- *************************************************************************/
- static
- ULONG SerGetStatus( PVOID pHead, // @parm PVOID returned by HWInit.
- LPCOMSTAT lpStat )// Pointer to LPCOMMSTAT to hold status.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- ULONG RetVal = pHWHead->CommErrors;
- DEBUGMSG(1, (TEXT("++SerGetStatus 0x%Xrn"), pHead));
- pHWHead->CommErrors = 0; // Clear old errors each time
- // We don't emulate any of this, so always return a fixed result.
- if (lpStat)
- {
- // TODO - Make sure we return reasonable results here.
- pHWHead->Status.fCtsHold = 0;
- pHWHead->Status.fDsrHold = 0;
- pHWHead->Status.cbInQue = 0;
- pHWHead->Status.cbOutQue = 0;
- }
- else
- RetVal = (ULONG)-1;
- DEBUGMSG(1, (TEXT("--SerGetStatus 0x%Xrn"), pHead));
- return RetVal;
- }
- /*************************************************************************
- @doc OEM
- @func ULONG | SerReset | Perform any operations associated
- with a device reset
- @rdesc None.
- *************************************************************************/
- static
- VOID SerReset( PVOID pHead ) // @parm PVOID returned by HWInit.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("++SerReset 0x%Xrn"), pHead));
- memset(&pHWHead->Status, 0, sizeof(COMSTAT));
- // TODO - Is there anything special we need to do here.
- DEBUGMSG(1, (TEXT("--SerReset 0x%Xrn"), pHead));
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerGetModemStatus | Retrieves modem status.
- @rdesc None.
- *************************************************************************/
- static
- VOID SerGetModemStatus( PVOID pHead, // @parm PVOID returned by HWInit.
- PULONG pModemStatus ) // @parm PULONG passed in by user.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("++SerGetModemStatus 0x%Xrn"), pHead));
- *pModemStatus = pHWHead->ModemStatus;
- DEBUGMSG (0, (TEXT("--SerGetModemStatus 0x%X (stat x%X) rn"),
- pHead,
- *pModemStatus));
- return;
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerGetCommProperties | Retrieves Comm Properties.
- @rdesc None.
- *************************************************************************/
- static
- VOID SerGetCommProperties(
- PVOID pHead, // @parm PVOID returned by SerInit.
- LPCOMMPROP pCommProp ) // @parm Pointer to receive COMMPROP structure.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("SerGetCommProperties 0x%Xrn"), pHead));
- *pCommProp = pHWHead->CommProp;
- return;
- }
- /*************************************************************************
- @doc OEM
- @func VOID | SerPurgeComm | Purge RX and/or TX
- @rdesc None.
- *************************************************************************/
- static
- VOID SerPurgeComm( PVOID pHead, // @parm PVOID returned by HWInit.
- DWORD fdwAction ) // @parm Action to take.
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- DEBUGMSG(1, (TEXT("++SerPurgeComm 0x%Xrn"), pHead));
- EnterCriticalSection(&(pHWHead->HwRegCritSec));
- if ( (fdwAction & PURGE_TXCLEAR) || (fdwAction & PURGE_TXABORT) )
- {
- // Abort any pending TX data. The MDD takes care of aborting
- // data pended in the driver. All I can do to stop an IN that
- // has already been queued is to Un-Arm this endpoint, causing
- // subsequent INs to get naked. If the IN transfer has started,
- // its not clear I can stop it in progress.
- // In addition to NAKing host, clearing ARM tells TxIntr that he
- // can use the buffer for the next write that comes down.
- #if TODO
- ucECR = SC2440_USB_Read(pHWHead, EP1AControl);
- ucECR &= 0xFE; // Clear the ARM bit.
- SC2440_USB_Write(pHWHead, EP1AControl, ucECR );
- #endif
- }
- if ( (fdwAction & PURGE_RXCLEAR) || (fdwAction & PURGE_RXABORT) ) {
- #if TODO
- // Abort any pending RX data.
- SC2440_USB_Write(pHWHead, IntStatus, 0x04 ); // Clear the EP2 interrupt
- SC2440_USB_Write(pHWHead, EP2AControl, 0x03); // Reenable the endpoint
- #endif
- }
- LeaveCriticalSection(&(pHWHead->HwRegCritSec));
- DEBUGMSG(1,
- (TEXT("--SerPurgeComm 0x%Xrn"), pHead));
- return;
- }
- /************************************************************************
- @doc OEM
- @func BOOL | SerSetDCB | Sets new values for DCB. This
- routine gets a DCB from the MDD. It must then compare
- this to the current DCB, and if any fields have changed take
- appropriate action.
- @rdesc BOOL
- ************************************************************************/
- static
- BOOL SerSetDCB( PVOID pHead, // @parm PVOID returned by HWInit.
- LPDCB lpDCB ) // @parm Pointer to DCB structure
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- BOOL bRet;
- DEBUGMSG(1, (TEXT("++SerSetDCB 0x%Xrn"), pHead));
- bRet = TRUE;
- // If the device is open, scan for changes and do whatever
- // is needed for the changed fields. if the device isn't
- // open yet, just save the DCB for later use by the open.
- if( pHWHead->OpenCount )
- {
- #ifdef TODO
- // We don't really support any of this. Ignore for now
- // Note, fparity just says whether we should check
- // receive parity. And the 16550 won't let us NOT
- // check parity if we generate it. So this field
- // has no effect on the hardware.
- if ( lpDCB->BaudRate != pHWHead->dcb.BaudRate )
- {
- bRet = SerSetBaudRate( pHWHead, lpDCB->BaudRate );
- }
- if ( bRet && (lpDCB->ByteSize != pHWHead->dcb.ByteSize ))
- {
- bRet = SerSetByteSize( pHWHead, lpDCB->ByteSize );
- }
- if ( bRet && (lpDCB->Parity != pHWHead->dcb.Parity ))
- {
- bRet = SerSetParity( pHWHead, lpDCB->Parity );
- }
- if ( bRet && (lpDCB->StopBits != pHWHead->dcb.StopBits ))
- {
- bRet = SerSetStopBits( pHWHead, lpDCB->StopBits );
- }
- // Don't worry about fOutxCtsFlow. It is a flag which
- // will be examined every time we load the TX buffer.
- // No special action required here.
- #endif
- }
- if (bRet)
- {
- // Now that we have done the right thing, store this DCB
- pHWHead->dcb = *lpDCB;
- }
- DEBUGMSG(1, (TEXT("--SerSetDCB 0x%Xrn"), pHead));
- return bRet;
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerSetCommTimeouts | Sets new values for the
- CommTimeouts structure. routine gets a DCB from the MDD. It
- must then compare this to the current DCB, and if any fields
- have changed take appropriate action.
- @rdesc ULONG
- *************************************************************************/
- static
- ULONG SerSetCommTimeouts(
- PVOID pHead, // @parm PVOID returned by HWInit.
- LPCOMMTIMEOUTS lpCommTimeouts ) // @parm Pointer to CommTimeout structure
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- ULONG retval = 0;
- DEBUGMSG(1, (TEXT("++SerSetCommTimeout 0x%Xrn"), pHead));
- // OK, first check for any changes and act upon them
- if( lpCommTimeouts->WriteTotalTimeoutMultiplier !=
- pHWHead->CommTimeouts.WriteTotalTimeoutMultiplier )
- {
- }
- // Now that we have done the right thing, store this DCB
- pHWHead->CommTimeouts = *lpCommTimeouts;
- DEBUGMSG(1, (TEXT("--SerSetCommTimeout 0x%Xrn"), pHead));
- return retval;
- }
- /*************************************************************************
- @doc OEM
- @func BOOL | SerIoctl | Device IO control routine.
- @parm DWORD | dwOpenData | value returned from COM_Open call
- @parm DWORD | dwCode | io control code to be performed
- @parm PBYTE | pBufIn | input data to the device
- @parm DWORD | dwLenIn | number of bytes being passed in
- @parm PBYTE | pBufOut | output data from the device
- @parm DWORD | dwLenOut |maximum number of bytes to receive from device
- @parm PDWORD | pdwActualOut | actual number of bytes received from device
- @rdesc Returns TRUE for success, FALSE for failure
- @remark The MDD will pass any unrecognized IOCTLs through to this function.
- *************************************************************************/
- static
- BOOL SerIoctl(PVOID pHead, DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
- PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
- {
- PSER_INFO pHWHead = (PSER_INFO)pHead;
- BOOL RetVal = TRUE;
- DEBUGMSG(1, (TEXT("++SerIoctl 0x%Xrn"), pHead));
- switch (dwCode)
- {
- // Currently, no defined IOCTLs
- default:
- RetVal = FALSE;
- DEBUGMSG(1, (TEXT(" Unsupported ioctl 0x%Xrn"), dwCode));
- break;
- }
- DEBUGMSG(1, (TEXT("--SerIoctl 0x%Xrn"), pHead));
- return(RetVal);
- }
- const
- HW_VTBL IoVTbl = {
- SerInit,
- SerPostInit,
- SerDeinit,
- SerOpen,
- SerClose,
- SerGetInterruptType,
- SerRxIntr,
- SerTxIntr,
- SerModemIntr,
- SerLineIntr,
- SerGetRxBufferSize,
- SerPowerOff,
- SerPowerOn,
- SerClearDTR,
- SerSetDTR,
- SerClearRTS,
- SerSetRTS,
- SerEnableIR,
- SerDisableIR,
- SerClearBreak,
- SerSetBreak,
- SerXmitComChar,
- SerGetStatus,
- SerReset,
- SerGetModemStatus,
- SerGetCommProperties,
- SerPurgeComm,
- SerSetDCB,
- SerSetCommTimeouts,
- SerIoctl};
- extern const HW_VTBL SerCardIoVTbl;
- PHWOBJ
- GetSerialObject( DWORD DeviceArrayIndex )
- {
- PHWOBJ pSerObj;
- // We do not have a statically allocated array of HWObjs. Instead, we
- // allocate a new HWObj for each instance of the driver. The MDD will
- // always call GetSerialObj/HWInit/HWDeinit in that order, so we can do
- // the alloc here and do any subsequent free in HWDeInit.
- // Allocate space for the HWOBJ.
- pSerObj = (PHWOBJ)LocalAlloc( LPTR, sizeof(HWOBJ) );
- if ( !pSerObj )
- return (NULL);
- // Fill in the HWObj structure that we just allocated.
- pSerObj->BindFlags = THREAD_IN_PDD; // We take care of our own IST
- pSerObj->dwIntID = SYSINTR_USBD; // SysIntr
- pSerObj->pFuncTbl = (HW_VTBL *) &IoVTbl; // Return pointer to functions
- // Now return this structure to the MDD.
- return (pSerObj);
- }