⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_sys.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 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 + -