?? sc2410_usb_ser.c
字號:
NULL,
(LPBYTE)(&pHWHead->dwIOLen),
&dwDataSize);
}
RegCloseKey (hKey);
if (regError != ERROR_SUCCESS)
{
DEBUGMSG(1,(TEXT("Failed to get serial registry values, Error 0x%X\r\n"),
regError));
return (FALSE);
}
DEBUGMSG(1,(TEXT("SerInit - Devindex %d, IRQ %d, IOB %X, IOLen %X \r\n"),
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};
ULONG WaitReturn; //Jonathan01_0915
if(hUSBAcInIntr) //edyeh1108
hUSBAcInIntr = CreateEvent(NULL, FALSE, FALSE,TEXT("PNA500:AC-IN Event"));
//Jonathan01_0915 start
if(!pDriverGlobals)
{
pDriverGlobals = (PDRIVER_GLOBALS) VirtualAllocCopy(DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,(char *)TEXT("BLKLGT: DRIVER_GLOBALS"), (PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
if(!pDriverGlobals)
{
return(NULL);
}
}
if(!s2410IOP)
{
s2410IOP = (volatile IOPreg *) VirtualAllocCopy(0x400,(char *)TEXT("IOP: GPIO_BASE_VIRTUAL"), (PVOID)IOP_BASE);
if(!s2410IOP)
{
if (pDriverGlobals)
VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
return(NULL);
}
}
if(!s2410CLKPW)
{
s2410CLKPW = (volatile CLKPWRreg *) VirtualAllocCopy(0x1000,(char *)TEXT("IOP: CLKPW_BASE_VIRTUAL"), (PVOID)CLKPWR_BASE);
if(!s2410CLKPW)
{
if(pDriverGlobals)
VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
if(s2410IOP)
VirtualFree((PVOID)s2410IOP, 0, MEM_RELEASE);
return NULL;
}
}
//Jonathan01_0915 end
#ifdef DEBUG
dpCurSettings.ulZoneMask = 0;
#endif
DEBUGMSG (1, (TEXT("++SerInit %X\r\n"), pMddHead ));
RETAILMSG(1,(TEXT("::: SerInit Start\r\n")));
//Jonathan01_0915 start
s2410IOP->rGPGUP |= (0x1 << 8);
s2410IOP->rGPGCON &= ~(0x3 << 16); //USB_ID
s2410IOP->rGPGUP |= (0x1 << 1);
s2410IOP->rGPGCON &= ~(0x3 << 2); //AC_IN
//USB_EN
s2410IOP->rGPJDAT &= ~(0x1 << 9); //turn off USB_EN
//edyeh1015, Init in Uboot codes.
//edyeh1015 //s2410IOP->rGPJUP |= (0x1 << 9); //the pull up function is disabled
//edyeh1015 //s2410IOP->rGPJCON &= ~(0x3 << 18);//Output
//edyeh1015 //s2410IOP->rGPJCON |= (0x1 << 18);
pDriverGlobals->misc.InitUSBClient = 1;
//Jonathan01_0915 end
// 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 !!! \r\n")));
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.
SC2410_USB_Init(pHWHead);
//Jonathan01_0915 start
pDriverGlobals->misc.USBCableEvent =0;
pHWHead->ModemStatus &= ~MS_RLSD_ON;
EvaluateEventFlag(pHWHead->pMddHead, EV_RLSD);
//make a delay
WaitReturn = WaitForSingleObject(pHWHead->hSerialEvent, 0x00000600L);
if(!(s2410IOP->rGPGDAT & (0x1 << 1)) && (s2410IOP->rGPGDAT & (0x1 << 8)))
{
s2410IOP->rGPJDAT |= (0x1 << 9); //turn on USB_EN
s2410CLKPW->rCLKCON |= (0x1<<7);
pDriverGlobals->misc.USBCableEvent =1;
pDriverGlobals->misc.InitUSBClient = 0;
RETAILMSG(1,(TEXT("::: SerInit -- USB IN \r\n")));
}
else //NO USB IN
{
s2410IOP->rGPJDAT &= ~(0x1 << 9); //turn off USB_EN
s2410CLKPW->rCLKCON &= ~(0x1<<7);
RETAILMSG(1,(TEXT("::: SerInit -- NO USB IN \r\n")));
}
//Jonathan01_0915 end
DEBUGMSG (1, (TEXT("--SerInit - %X\r\n"), pHWHead ));
RETAILMSG(1,(TEXT("::: SerInit end\r\n")));
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 - %X\r\n"), pHWHead ));
//RETAILMSG(1,(TEXT("::: SerInit end\r\n")));
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("+++SerPostInit\r\n")));
// 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("+SerDeinit\r\n")));
// 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("-SerDeinit\r\n")));
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+\r\n")));
NKDbgPrintfW(L"SerOpen++\r\n");//jocky0308
// 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("++SerClose\r\n")));
if (pHWHead->cOpenCount)
{
DEBUGMSG (1, (TEXT("SerClose, closing device\r\n")));
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%X\r\n"),
*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("--SerClose\r\n")));
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 %d\r\n"), *pBufflen));
cEvtChar = pHWHead->dcb.EvtChar;
fNull = pHWHead->dcb.fNull;
if( pHWHead->dcb.fErrorChar && pHWHead->dcb.fParity )
fReplaceparityErrors = TRUE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -