?? go7007drv.c
字號(hào):
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include "usb-func.h"
#include "go7007drv.h"
#define MAXBLOCKSIZE 4096
/* Debug status */
static int debug = 0;
/* Redefine debug macro */
#undef dbg
#define dbg(format, arg...) \
do { if (debug) printk(KERN_DEBUG __FILE__ ": [" __FUNCTION__ "] " \
format "\n" , ## arg); \
} while (0)
#undef err
#define err(format, arg...) printk(KERN_ERR __FILE__ ": [" __FUNCTION__ "] " \
format "\n" , ## arg)
////////////////////////////////////////////////////////////////////////////////////////////
//
// SDK interacts with driver via send coomand to driver.
// All commands are sent accompanied by a "CMD_PACKET" structure , the "Type" field of
// the structure holds the command type which is defined as following enum. The other fields varies
// according to different command.
enum CMD
{
CMD_BOOTUP,
CMD_INITIALIZE,
CMD_UNINITIALIZE,
CMD_SENDPACKETS,
CMD_SETBLOCKSIZE,
// set interface mode
//
// CMD_PACKET::Param : IM_HPI -- hpi mode,
// IM_USB -- usb mode,
// IM_STANDBY -- standby
CMD_SETINTERFACEMODE,
// read cbus registers via firmware
//
// CMD_PACKET::Param : number of registers to read
// CMD_PACKET::pBuf : each unit of word holds an address
//
// return buffer : each unit of word holds a read result data
CMD_READCBUSREGFW,
// write cbus registers via firmware
//
// CMD_PACKET::Param : number of registers to write
// CMD_PACKET::pBuf : each unit of word holds alternated address and data
CMD_WRITECBUSREGFW,
// read a hpi register
//
// CMD_PACKET::Param : address of hpi register
//
// return buffer : a word that holds the read result data
CMD_READHPIREGISTER,
// write a hpi register
//
// CMD_PACKET::Param : address of hpi register
// CMD_PACKET::pBuf : a word that holds data to write
CMD_WRITEHPIREGISTER,
// do a self test
// CMD_PACKET::Param : ST_HWMBIST -- hardware mbist
// CMD_PACKET::pBuf :
// CMD_PACKET::Param : ST_BASICHPICHECK -- basic hpi check
// CMD_PACKET::pBuf :
// CMD_PACKET::Param : ST_IOCHECK -- io check
// CMD_PACKET::pBuf :
// CMD_PACKET::Param : ST_SWMBIST -- software mbist
// CMD_PACKET::pBuf :
// CMD_PACKET::Param : ST_MEMSCAN -- memory scan
// CMD_PACKET::pBuf : WORD[0] : memory size, 0 -- 4M, 1-- 8M
CMD_SELFTEST,
CMD_SENDPACKETSWITHRETURN,
CMD_INITIALIZEI2C,
};
// DECLARE_WAIT_QUEUE_HEAD(delay_wq);
static void Delay()
{
wait_queue_head_t wq_delay;
init_waitqueue_head(&wq_delay);
sleep_on_timeout(&wq_delay, 0.1*HZ);
// sleep_on_timeout(&delay_wq, 0.1*HZ);
}
// 0 -- success
// -1 -- timeout
// -2 -- error interrupt type
int CheckInterruptPipe(pusb_t pdx, int InterruptType, int RepeatNum)
{
int i;
int r;
USHORT IntRetVal, IntRetData;
for(i=0;i<RepeatNum;i++)
{
r = ReadInterruptPipe(pdx, &IntRetVal, &IntRetData);
if (r != 0)
{
if(IntRetVal == InterruptType)
return 0;
else
{
PrintMsg1(("<DRV> CheckInterruptPipe : Error Interrupt 0x%08X, required 0x%08X",IntRetVal, InterruptType));
Delay();
continue;//return IntRetVal;
}
}
else
{
PrintMsg1(("<DRV> CheckInterruptPipe : Timeout"));
return -1;
}
}
return -2;
}
int CheckInterruptPipeWithReturn(pusb_t pdx, int InterruptType, int InterruptData, int RepeatNum)
{
int i;
int r;
USHORT IntRetVal, IntRetData;
r = ReadInterruptPipe(pdx, &IntRetVal, &IntRetData);
if (r != 0)
{
if(IntRetVal==InterruptType || IntRetVal == 0x555b)
{
if(InterruptData<0) {
err("IntRetData = 0x%x", IntRetData);
return IntRetData;
} else {
err("IntRetVal==InterruptVal, InterruptData >= 0");
return 0;
}
}
else
{
err("<DRV> CheckInterruptPipe : Error Interrupt 0x%08X, required 0x%08X",IntRetVal, InterruptType);
return IntRetVal;
}
}
else
{
err("<DRV> CheckInterruptPipe : Timeout");
return -1;
}
}
// 0 -- success
// -1 -- timeout
// -2 -- error interrupt type
int CheckInterruptPipe2(pusb_t pdx, int InterruptType, int InterruptData, int RepeatNum)
{
int i;
int r;
USHORT IntRetVal, IntRetData;
for(i=0;i<RepeatNum;i++)
{
r = ReadInterruptPipe(pdx, &IntRetVal, &IntRetData);
if (r != 0)
{
if((IntRetVal == InterruptType) && (IntRetData == InterruptData))
return 0;
else
{
dbg("Error Interrupt 0x%08x 0x%08x", IntRetVal,IntRetData);
Delay();
continue;//return IntRetVal;
}
}
else
{
dbg("Timeout");
return -1;
}
}
return -2;
}
////// return 0 -- success
int BootupChipWithFirmware(pusb_t pdx, unsigned char *pFirmware, int Firmlen)
{
int r;
PrintMsg1(("<DRV> BootupChipWithFirmware : Enter, FirmLen : %d",Firmlen));
if(pdx->DeviceState != DS_OPENED && pdx->DeviceState != DS_BOOTUPED)
return 1;
WriteInterrupt(pdx,0x0001,0x0001);
mdelay(50);
WriteInterrupt(pdx,0x0001,0x0001);
mdelay(50);
if(CheckInterruptPipe(pdx, 0x55aa, 10)!=0)
{
PrintMsg(("<DRV> BootupChip : Bootup Fail 1"));
PrintMsg1(("<DRV> BootupChip : Bootup Fail 1"));
return 2;
}
// DownloadFirmware
r = DownloadBuffer(pdx, pFirmware, Firmlen);
if (r == 0)
return 3;
if(CheckInterruptPipe(pdx, 0x5a5a, 10)!=0)
{
PrintMsg(("<DRV> BootupChip : Fail 2"));
PrintMsg1(("<DRV> BootupChip : Fail 2"));
return 3;
}
err("<DRV> BootupChip : Success");
PrintMsg1(("<DRV> BootupChip : Success"));
pdx->DeviceState = DS_BOOTUPED;
return 0;
}
// DECLARE_WAIT_QUEUE_HEAD(wq_stop_stream_thread);
void StopStreamThread(void *arg)
{
int rv;
pusb_t pdx = (pusb_t)arg;
pdx->StreamThreadState = 0;
rv = sleep_on_timeout(&pdx->wq_stop_stream_thread, 5*HZ);
dbg("StopStreamThread: rv = %d", rv);
}
DECLARE_MUTEX (stream_thread_mutex);
int StreamThreadProc(void *arg)
{
unsigned char *pBlock;
int r;
int ncount;
pusb_t pdx = (pusb_t)arg;
PrintMsg(("<DRV> StreamThreadProc : Enter"));
if(pdx->bulk_in_buffer == NULL)
{
dbg("ERROR: bulk_in_buffer is NULL");
}
pBlock = pdx->bulk_in_buffer;
ncount = 0;
while(pdx->StreamThreadState == 1)
{
int BlockSize1 = BULK_IN_BUFSIZE; //pdx->BlockSize;
// down(&stream_thread_mutex);
r = ReadStreamPipe(pdx, pBlock, BlockSize1);
if(pdx->StreamThreadState == 1 && r != 0 ) {
StreamBuffer_AddBlock(&(pdx->StreamBuffer),pBlock, BlockSize1);
}
// up(&stream_thread_mutex);
#if 0
while(ncount++ > 50) {
schedule();
ncount = 0;
}
#endif
}
PrintMsg1(("<DRV> StreamThreadProc : Need exit"));
PrintMsg(("<DRV> StreamThreadProc : Exit"));
wake_up(&pdx->wq_stop_stream_thread);
}
extern void begin_stream_input(pusb_t s);
// return 0: success
int InitializeDevice(pusb_t pdx, INT_PACKET *pInitPackets, int InitPacketsNum)
{
// HANDLE InterruptThreadHandle;
// HANDLE StreamThreadHandle;
// NTSTATUS ntStatus;
int r;
PrintMsg(("<DRV> InitializeDevice : Enter"));
if(pdx->DeviceState != DS_BOOTUPED)
return 1;
StreamBuffer_Reset(&(pdx->StreamBuffer));
// pdx->IFrameNum = 0;
// pdx->PFrameNum = 0;
// pdx->TotalDelay = 0;
// pdx->ChipDelay = 0;
r = DownloadBuffer(pdx, (unsigned char *)pInitPackets, sizeof(INT_PACKET)*InitPacketsNum);
if (r == 0)
return 3;
if(CheckInterruptPipe(pdx, 0x0000, 10)!=0)
{
PrintMsg(("<DRV> Initialize : fail"));
PrintMsg1(("<DRV> Initialize : fail"));
return 3;
}
// pdx->InterruptThreadState = 1;
// ntStatus = PsCreateSystemThread( &InterruptThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL,
// InterruptThreadProc, (PVOID)fdo);
pdx->StreamThreadState = 1;
// kernel_thread(StreamThreadProc, (void *)pdx, 0);
begin_stream_input(pdx);
pdx->DeviceState = DS_RUNNING;
err("<DRV> InitializeDevice : Completed SUCCESSFUL");
return 0;
}
int UninitializeDevice(pusb_t pdx)
{
// PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
// unsigned short *pBuffer;
// unsigned int i;
PrintMsg(("<DRV> UninitializeDevice : Enter"));
if(pdx->DeviceState != DS_RUNNING)
return 1;
// pdx->StreamThreadState = 0; // stop stream thread
StopStreamThread(pdx);
WriteInterrupt(pdx,0x0001,0x0001);
// send 0x0020 packet to make chip stop
/* pBuffer = (unsigned short *)ExAllocatePool(NonPagedPool,64);
RtlZeroMemory(pBuffer,64);
pBuffer[0] = 0x0020;
DownloadBuffer(fdo, (unsigned char *)pBuffer,64);
ExFreePool(pBuffer);
*/
// pdx->InterruptThreadState = 0; // stop interrupt thread
// for (i = 0; i < pdx->Interface->NumberOfPipes; i++)
// AbortPipe(fdo,(USBD_PIPE_HANDLE) pdx->Interface->Pipes[i].PipeHandle);
// for (i = 0; i < pdx->Interface->NumberOfPipes; i++)
// ResetPipe(fdo,i);
PrintMsg(("<DRV> Left"));
pdx->DeviceState = DS_OPENED;
return 0;
}
// return 0: success
int InitializeI2C(pusb_t pdx, INT_PACKET *pInitPackets, int InitPacketsNum)
{
int r;
PrintMsg1(("<DRV> InitializeI2C : Enter"));
if(pdx->DeviceState != DS_BOOTUPED)
return 1;
r = DownloadBuffer(pdx, (unsigned char *)pInitPackets, sizeof(INT_PACKET)*InitPacketsNum);
if (r == 0)
return 3;
if(CheckInterruptPipe2(pdx, 0x555a, 0, 10)!=0)
{
PrintMsg(("<DRV> InitializeI2C : fail"));
PrintMsg1(("<DRV> InitializeI2C : fail"));
return 3;
}
PrintMsg1(("<DRV> InitializeI2C : Completed"));
return 0;
}
// return 0 : success
// 1 : fail
int OnWriteProc(pusb_t pdx, const char *buf)
{
int r = 0;
CMD_PACKET *pCmd = (CMD_PACKET *)buf;
// PrintMsg1(("<DRV> Write : %d %d",FrameSize,pCmd->Type));
switch (pCmd->Type)
{
case CMD_BOOTUP:
r = BootupChipWithFirmware(pdx, pCmd->pBuf, pCmd->Param);
break;
case CMD_INITIALIZE:
{
int PacketNum = pCmd->Param;
INT_PACKET *p = (INT_PACKET *)(pCmd->pBuf);
// DumpBuffer(pBuf,PacketNum*64+5);
r = InitializeDevice(pdx, p, PacketNum);
break;
}
case CMD_UNINITIALIZE:
err("CMD_UNINITIALIZE called");
UninitializeDevice(pdx);
break;
case CMD_INITIALIZEI2C:
{
int PacketNum = pCmd->Param;
INT_PACKET *p = (INT_PACKET *)(pCmd->pBuf);
// DumpBuffer(pBuf,PacketNum*64+5);
r = InitializeI2C(pdx, p, PacketNum);
break;
}
case CMD_SENDPACKETS:
{
int PacketNum = pCmd->Param;
INT_PACKET *p = (INT_PACKET *)(pCmd->pBuf);
int rv;
// PrintMsg1(("<DRV> Send Packet to chip : PacketNum(%d)",PacketNum));
// DumpBuffer1(p,64);
rv = DownloadBuffer(pdx,(UCHAR *)p,64*PacketNum);
err("CMD_SENDPACKETS,rv = %i", rv);
break;
}
/* case CMD_SETBLOCKSIZE:
{
int BlockSize1 = pCmd->Param;
if(BlockSize1>0&&BlockSize1<=64)
BlockSize1 = 64;
else if(BlockSize1>64&&BlockSize1<=128)
BlockSize1 = 128;
else if(BlockSize1>128&&BlockSize1<=256)
BlockSize1 = 256;
else if(BlockSize1>256&&BlockSize1<=512)
BlockSize1 = 512;
else if(BlockSize1>512&&BlockSize1<=1024)
BlockSize1 = 1024;
else if(BlockSize1>1024&&BlockSize1<=2048)
BlockSize1 = 2048;
else if(BlockSize1>2048&&BlockSize1<=4096)
BlockSize1 = 4096;
else
BlockSize1 = 8192;
pdx->BlockSize = BlockSize1;
PrintMsg1(("<DRV> BLOCKSIZE : %d",pdx->BlockSize));
break;
}
case CMD_SETINTERFACEMODE:
{
int IfMode = pCmd->Param;
UCHAR Data[1];
if(IfMode == IM_HPI)
{
DoVendorRequest(fdo, VR_STARTHPI, 0, 0, Data, 1, DIR_IN);
if(Data[0] == 0xaa)
r=0;
else
r=1;
}
else if(IfMode == IM_USB)
{
DoVendorRequest(fdo, VR_STARTUSB, 0, 0, Data, 1, DIR_IN);
if(Data[0] == 0x55)
r=0;
else
r=1;
}
else if(IfMode == IM_STANDBY)
{
DoVendorRequest(fdo, VR_STANDBY, 0, 0, Data, 1, DIR_IN);
if(Data[0] == 0x88)
r=0;
else
r=1;
}
PrintMsg1(("<DRV> CMD_SETINTERFACEMODE %d, Return : 0x%02x",IfMode,Data[0]));
break;
}
case CMD_WRITEHPIREGISTER:
r = WriteHPIRegister(fdo, (USHORT)(pCmd->Param), *((USHORT *)(pCmd->pBuf)));
break;
case CMD_WRITECBUSREGFW:
r = WriteCBusRegFW(fdo, pCmd->Param, (USHORT *)pCmd->pBuf);
break;
case CMD_SELFTEST:
{
int SelfTest = pCmd->Param;
PrintMsg1(("<DRV> Self Test : %d",SelfTest));
switch (SelfTest)
{
case ST_HWMBIST:
{
UCHAR Data[1];
DoVendorRequest(fdo, VR_STARTBIST, 0, 0, Data, 1, DIR_IN);
if(Data[0] == 0)
r=0;
else
r=1;
PrintMsg1(("<DRV> Return val : %d",Data[0]));
break;
}
case ST_BASICHPICHECK:
r = ST_BasicHPICheck(fdo, pCmd->pBuf);
break;
case ST_IOCHECK:
r = ST_IOCheck(fdo, pCmd->pBuf);
break;
case ST_SWMBIST:
r = ST_SwMBist(fdo, pCmd->pBuf);
break;
// case ST_REGSCAN:
// r = ST_RegScan(fdo, pCmd->pBuf);
// break;
case ST_MEMSCAN:
r = ST_MemoryScan(fdo, *((USHORT *)(pCmd->pBuf)));
break;
}
break;
}
*/
default:
break;
}
return r;
}
int OnIoctlProc(pusb_t pdx, unsigned long arg)
{
int r = 0;
CMD_PACKET *pCmd = (CMD_PACKET *)arg;
err("OnIoctlProc : %d", pCmd->Type);
switch (pCmd->Type)
{
case CMD_SENDPACKETSWITHRETURN:
{
int PacketNum = pCmd->Param;
INT_PACKET *p = (INT_PACKET *)(pCmd->pBuf);
err("CMD_SENDPACKETSWITHRETURN,will downloadbuffer");
DownloadBuffer(pdx,(UCHAR *)p, 64);
err("[0x%x..0x%x..0x%x..0x%x..0x%x]", pCmd->pBuf[4], pCmd->pBuf[3], pCmd->pBuf[2], pCmd->pBuf[1], pCmd->pBuf[0]);
r = CheckInterruptPipeWithReturn(pdx, 0x555a, -1, 10);
if (r >= 0) {
err("checkInterruptPipeWithReturn return 0x%x", r);
put_user(r, (unsigned short *)arg);
r = 0;
} else {
err("CMD_SENDPACKETSWITHRETURN, fail r = 0");
}
break;
}
default:
break;
}
return r;
}
void dump_bin(char *Title,unsigned char *buf, int len)
{
char s[256],s1[16];
int i;
PrintMsg1(("%s",Title));
strcpy(s,"");
for(i=0;i<len;i++)
{
sprintf(s1, "%02X ", buf[i]);
strcat(s,s1);
if(i%16==15)
{
PrintMsg1(("%s",s));
strcpy(s,"");
}
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -