📄 sd_sys.c
字号:
/***************************************************************************
* File: sd_sys.c - Export stream interface to OS
*
* The content of this file or document is CONFIDENTIAL and PROPRIETARY
* to Jade Technologies Co., Ltd. It is subject to the terms of a
* License Agreement between Licensee and Jade Technologies Co., Ltd.
* restricting among other things, the use, reproduction, distribution
* and transfer. Each of the embodiments, including this information
* and any derivative work shall retain this copyright notice.
*
* Copyright (c) 2005 Jade Technologies Co., Ltd.
* All rights reserved.
****************************************************************************/
#include "sd.h"
//------------------------------------------------------------------------------
// Global Variables in SD_SYS.C
//------------------------------------------------------------------------------
DISK_INFO DiskInfo = {0}; // store information of card
LPWSTR ActivePath = NULL; // get strings in register
HANDLE DetectThread = NULL; // thread for detecting plug and play
SD_controller g_Controller = {0}; // structure of card's instance
CRITICAL_SECTION g_DiskCardCrit; // guard access to global state and card
int g_ExcCnt = 0; // count times open/close error ocurred
int g_CardStatus = 0; // indicate the card's state
//------------------------------------------------------------------------------
//
// SD.DLL entry
//
// Arguments:
// All ignored
//
// Functions:
// The entry of this driver.
//
//------------------------------------------------------------------------------
BOOL WINAPI
DllMain(HANDLE hinstDLL,
unsigned long dwReason,
LPVOID lpReserved)
{
return TRUE;
} // DllMain
//------------------------------------------------------------------------------
//
// DoDiskIO - Perform requested I/O.
// This function is called from SDI_IOControl.
//
// Requests are serialized using the disk's critical section.
//
// Arguments:
// controller - handle of instance
// Opcode - indicate read or write
// pSgr - the structure of read/write command from FAT system
// errorcode - record errors
//
// Functions:
// Decode the command from FAT system,
// and call the corresponded functions to read or write data to card.
//
//------------------------------------------------------------------------------
unsigned long
SDI_DoDiskIO(
SD_controller* controller,
unsigned long Opcode,
PSG_REQ pSgr,
unsigned long * errorcode
)
{
unsigned long status = ERROR_SUCCESS;
unsigned long num_sg;
unsigned long bytes_this_sg;
unsigned long sectors_this_sg;
unsigned long start;
unsigned long num_sec;
unsigned char * pBuf;
PSG_BUF pSg;
pSgr->sr_status = ERROR_IO_PENDING;
start = pSgr->sr_start;
num_sec = pSgr->sr_num_sec;
num_sg = pSgr->sr_num_sg;
pSg = &(pSgr->sr_sglist[0]);
bytes_this_sg = pSg->sb_len;
pBuf = (unsigned char *)MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());
EnterCriticalSection(&g_DiskCardCrit);
// Read or write sectors from/to disk.
// RETAILMSG(MSG_SYS, (_T("SD: SDI_DoDiskIO - Number of scatter/gather descriptors %d\r\n"), num_sg));
while (num_sg)
{
RETAILMSG(MSG_SYS, (_T("SD: SDI_DoDiskIO - Bytes left for this sg:0x%x, Start addr:0x%x\r\n"), bytes_this_sg, (unsigned long)pBuf));
if (Opcode == DISK_IOCTL_READ)
{
sectors_this_sg = (int) (bytes_this_sg/BYTES_PER_SECTOR);
SDI_BlockRead(
controller, start,
bytes_this_sg/BYTES_PER_SECTOR,
pBuf, errorcode);
}
else
{
sectors_this_sg = (int) (bytes_this_sg/BYTES_PER_SECTOR);
SDI_BlockWrite(
controller, start,
bytes_this_sg/BYTES_PER_SECTOR,
pBuf, errorcode);
}
// Use the next scatter/gather buffer
num_sg--;
if (num_sg == 0)
break;
pSg++;
pBuf = (unsigned char *)MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());
bytes_this_sg = pSg->sb_len;
} // while sg
LeaveCriticalSection(&g_DiskCardCrit);
pSgr->sr_status = status;
return status;
} // DoDiskIO
//------------------------------------------------------------------------------
//
// Generates context data for this Init instance
//
// Arguments:
// dwContext - registry path for this device's active key
//
// Functions:
// Get the device key from active device registry key
// Create the thread for plug and play
//
//------------------------------------------------------------------------------
unsigned long
SDI_Init(
unsigned long dwContext
)
{
unsigned long errorcode = 0;
InitializeCriticalSection(&g_DiskCardCrit);
EnterCriticalSection(&g_DiskCardCrit);
if (dwContext)
{ // Get the device key from active device registry key
if (ActivePath = (unsigned short *)LocalAlloc(LPTR, wcslen((LPWSTR)dwContext)*sizeof(WCHAR)+sizeof(WCHAR)))
{
wcscpy(ActivePath, (LPWSTR)dwContext);
}
RETAILMSG(1, (_T("SD: SDI_Init - ActiveKey(copy) = %s (0x%x)\r\n"), ActivePath, ActivePath));
}
RETAILMSG(MSG_SYS, (_T("SD: SDI_Init(0x%x) entered\r\n"),dwContext));
if (!SDI_InitInterface(&g_Controller, &errorcode))
return 0;
g_CardStatus = STATE_INITING;
#if SD_TEST
g_CardStatus = STATE_TEST;
#endif
DetectThread = CreateThread(NULL,0,SDI_DetectStatus,(LPVOID)(&g_Controller),0,NULL);
RETAILMSG(MSG_SYS, (_T("SD: SDI_Init(0x%x) returning, errorcode %d\r\n"), dwContext, errorcode));
LeaveCriticalSection(&g_DiskCardCrit);
return 1;
} // SDI_Init
//------------------------------------------------------------------------------
//
// Updates handle value for the open instance.
//
// Arguments:
// dwData - handle for the instance
// dwAccess - ignore
// dwShareMode - ignore
//
// Functions:
// Starp up the card for use and remark the status opened
// Store disk-informations about card
//
//------------------------------------------------------------------------------
unsigned long
SDI_Open(
unsigned long dwData,
unsigned long dwAccess,
unsigned long dwShareMode
)
{
SD_controller *controller = &g_Controller;
unsigned long ret = 0;
unsigned long errorcode = 0;
RETAILMSG(MSG_SYS, (_T("SD: SDI_Open(0x%x) entered\r\n"), dwData));
if (SDI_StartUpCard(controller, &errorcode))
{
ret = 1;
if (g_CardStatus != STATE_TEST)
g_CardStatus = STATE_OPENED;
g_ExcCnt = 0;
}
else
{
if (g_CardStatus != STATE_TEST)
g_CardStatus = STATE_CLOSED;
if ((g_ExcCnt++) > 8)
g_CardStatus = STATE_DEAD;
return ret;
}
DiskInfo.di_total_sectors = (controller->CardCSD.CardSize)/BYTES_PER_SECTOR;
DiskInfo.di_bytes_per_sect = BYTES_PER_SECTOR;
DiskInfo.di_flags = DISK_INFO_FLAG_CHS_UNCERTAIN;
RETAILMSG(MSG_SYS, (_T("SD: SDI_Open(0x%x) returning %d, errorcode %d\r\n"), dwData, ret, errorcode));
return ret;
} // SDI_Open
//------------------------------------------------------------------------------
//
// Updates handle value for the close instance.
//
// Arguments:
// dwContext - handle for the instance
//
// Functions:
// Close the instance and remark the card status closed
//
//------------------------------------------------------------------------------
BOOL
SDI_Close(
unsigned long dwContext
)
{
SD_controller *controller = &g_Controller;
BOOL bClose = FALSE;
unsigned long errorcode = 0;
RETAILMSG(MSG_SYS, (_T("SD: SDI_Close entered\r\n")));
if (SDI_ResetInterface(controller, &errorcode))
{
bClose = TRUE;
if (g_CardStatus != STATE_TEST)
g_CardStatus = STATE_CLOSED;
g_ExcCnt = 0;
}
else
{
if (g_CardStatus != STATE_TEST)
g_CardStatus = STATE_OPENED;
if ((g_ExcCnt++) > 8)
g_CardStatus = STATE_DEAD;
return bClose;
}
RETAILMSG(MSG_SYS, (_T("SD: SDI_Close done, errorcode %d\r\n"), errorcode));
return bClose;
} // SDI_Close
//------------------------------------------------------------------------------
//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
// Arguments:
// dwContext - handle for the instance
//
// Functions:
// Deinit the interface and close all unuseful handles
//
//------------------------------------------------------------------------------
BOOL
SDI_Deinit(
unsigned long dwContext
)
{
SD_controller * controller = &g_Controller;
BOOL bDeinit = FALSE;
unsigned long errorcode = 0;
EnterCriticalSection(&g_DiskCardCrit);
RETAILMSG(MSG_SYS, (_T("SD: SDI_Deinit entered\r\n")));
if (SDI_DeinitInterface(controller, &errorcode))
{
bDeinit = TRUE;
g_CardStatus = STATE_DEINITING;
}
else
{
g_CardStatus = STATE_DEAD;
}
Sleep(100);
if (g_CardStatus != STATE_DEAD)
TerminateThread(DetectThread,1);
CloseHandle(DetectThread);
RETAILMSG(MSG_SYS, (_T("SD: SDI_Deinit done, errorcode %d\r\n"), errorcode));
LeaveCriticalSection(&g_DiskCardCrit);
return bDeinit;
} // SDI_Deinit
//------------------------------------------------------------------------------
//
// I/O Control function - responds to info, read and write control codes.
// The read and write take a scatter/gather list in pInBuf
//
// Arguments:
// Handle - handle for the instance
// dwIoControlCode - Control code chose the operation
// pInBuf - The pointer to space of parameters passed in
// nInBufSize - The size of buffer passed in
// pOutBuf - The pointer to space of parameters passed out
// nOutBufSize - The size of buffer passed out
// pBytesReturned - Return the actual number of bytes received from device
//
//
// Functions:
// Read or write.
// Get information from card.
//
//------------------------------------------------------------------------------
BOOL
SDI_IOControl(
unsigned long Handle,
unsigned long dwIoControlCode,
unsigned char * pInBuf,
unsigned long nInBufSize,
unsigned char * pOutBuf,
unsigned long nOutBufSize,
unsigned long * pBytesReturned
)
{
PSG_REQ pSG;
SD_controller * controller = &g_Controller;
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl(%d) entered\r\n"), dwIoControlCode));
//
// Check parameters
//
switch (dwIoControlCode)
{
case DISK_IOCTL_READ:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - read\r\n")));
if (pInBuf == NULL)
{
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - invalid parameter\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_WRITE:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - write\r\n")));
if (pInBuf == NULL)
{
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - invalid parameter\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_GETINFO:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - get info\r\n")));
if (pInBuf == NULL)
{
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - invalid parameter\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_SETINFO:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - set info\r\n")));
if (pInBuf == NULL)
{
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - invalid parameter\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_INITIALIZED:
if (pInBuf == NULL)
{
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - invalid parameter\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_GETNAME:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - get name\r\n")));
if (pOutBuf == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_DISK_DEVICE_INFO:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl - device info\r\n")));
if(!pInBuf || nInBufSize != sizeof(STORAGEDEVICEINFO))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_FORMAT_MEDIA:
SetLastError(ERROR_SUCCESS);
return TRUE;
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//
// Execute dwIoControlCode
//
switch (dwIoControlCode)
{
case DISK_IOCTL_READ:
case DISK_IOCTL_WRITE:
{
unsigned long errorcode = 0;
pSG = (PSG_REQ)pInBuf;
SDI_DoDiskIO(controller, dwIoControlCode, pSG, &errorcode);
if (errorcode)
{
pSG->sr_status = errorcode;
return FALSE;
}
return TRUE;
}
case DISK_IOCTL_GETINFO:
{
DISK_INFO * pDiskInfo = (DISK_INFO *)pInBuf;
*pDiskInfo = DiskInfo;
return TRUE;
}
case DISK_IOCTL_SETINFO:
{
DISK_INFO * pDiskInfo = (DISK_INFO *)pInBuf;
DiskInfo = *pDiskInfo;
return TRUE;
}
case DISK_IOCTL_INITIALIZED:
return TRUE;
case DISK_IOCTL_GETNAME:
{
unsigned short *namestring = L"SD Card";
if (!SDI_GetFolderName(ActivePath, (LPWSTR)pOutBuf, nOutBufSize, pBytesReturned))
memcpy(pOutBuf, namestring, nOutBufSize);
return TRUE;
}
case IOCTL_DISK_DEVICE_INFO: // new ioctl for disk info
return SDI_GetDeviceInfo(ActivePath, (PSTORAGEDEVICEINFO)pInBuf);
default:
RETAILMSG(MSG_SYS, (_T("SD: SDI_IOControl- (default) \r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
} // SDI_IOControl
//------------------------------------------------------------------------------
//
// Reserved
//
//------------------------------------------------------------------------------
unsigned long SDI_Read(unsigned long Handle, LPVOID pBuffer, unsigned long dwNumBytes){return 0;}
unsigned long SDI_Write(unsigned long Handle, LPVOID pBuffer, unsigned long dwNumBytes){return 0;}
unsigned long SDI_Seek(unsigned long Handle, long lDistance, unsigned long dwMoveMethod){return 0;}
void SDI_PowerUp(void){}
void SDI_PowerDown(void){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -