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

📄 cfc_sys.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
字号:
/***************************************************************************
*   File:    cfc_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 "cfcard.h"

//------------------------------------------------------------------------------
// Global Variables in CFC_SYS.C
//------------------------------------------------------------------------------
extern DISK g_Disk;	// the global structure record the disk instance
//------------------------------------------------------------------------------
//
// CFCARD.DLL entry
//
//------------------------------------------------------------------------------
BOOL WINAPI
DllMain(HANDLE hinstDLL, 
	unsigned long  dwReason, 
	LPVOID lpReserved)
{
    return TRUE;
}   // DllMain


//------------------------------------------------------------------------------
//
// DoDiskIO - Perform requested I/O.
//            This function is called from CFC_IOControl.
//
// Arguments:
//		pDisk - the opened instance
//		Opcode - indicate read or write
//		pSgr - the structure of read/write command from FAT system
//
// Functions:
//		Decode the command from FAT system, 
//		and call the corresponded functions to read or write data to card.  
// 		
//------------------------------------------------------------------------------
unsigned long
CFC_DoDiskIO(
    PDISK pDisk,
    unsigned long Opcode,
    PSG_REQ pSgr
    )
{
	unsigned long status = ERROR_SUCCESS;
	unsigned long num_sg;
	unsigned long bytes_this_sg;
	unsigned long sectors_this_sg;
	unsigned long tail_this_sg = 0;
	unsigned long start;
	unsigned long num_sec;
	unsigned short * pBuf;
	unsigned short pBufTail[512];
	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 short *)MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());

	EnterCriticalSection(&(pDisk->d_DiskCardCrit));

	if (pDisk->d_DiskCardState != STATE_OPENED) 
	{
		RETAILMSG(MSG_SYS, (_T("CFCARD: CFC_DoDiskIO - Disk state != STATE_OPENED\r\n")));
		return 0;
	}

	// Read or write sectors from/to disk.
	// NOTE: Multiple sectors may go in one scatter/gather buffer or one
	// sector may fit in multiple scatter/gather buffers.
	RETAILMSG(MSG_SYS, (_T("CFCARD: CFC_DoDiskIO - Number of scatter/gather descriptors %d\r\n"), num_sg));
	while (num_sg) 
	{
		RETAILMSG(MSG_SYS, (_T("CFCARD: CFC_DoDiskIO - Bytes left for this sg %d\r\n"), bytes_this_sg));
		if (Opcode == DISK_IOCTL_READ) 
		{
			sectors_this_sg = (int) (bytes_this_sg/BYTES_PER_SECTOR);
			CFC_SafeRead(pDisk->d_pCFCardRegs, pBuf, start, sectors_this_sg);
			if (tail_this_sg = bytes_this_sg % BYTES_PER_SECTOR)
			{
				CFC_SafeRead(pDisk->d_pCFCardRegs, pBufTail, (start + sectors_this_sg), 1);
				memcpy((unsigned short *)(pBuf + BYTES_PER_SECTOR*sectors_this_sg/2), pBufTail, tail_this_sg);
			}
		} 
		else 
		{
			sectors_this_sg = (int) (bytes_this_sg/BYTES_PER_SECTOR);
			CFC_SafeWrite(pDisk->d_pCFCardRegs, pBuf, start, sectors_this_sg);
			if (tail_this_sg = bytes_this_sg % BYTES_PER_SECTOR)
			{
				CFC_SafeRead(pDisk->d_pCFCardRegs, pBufTail, (start + sectors_this_sg), 1);
				memcpy(pBufTail, (unsigned short *)(pBuf + BYTES_PER_SECTOR*sectors_this_sg/2), tail_this_sg);
				CFC_SafeWrite(pDisk->d_pCFCardRegs, pBufTail, (unsigned long)(start + sectors_this_sg), 1);
			}
		}
		// Use the next scatter/gather buffer
		num_sg--;
		if (num_sg == 0) 
			break;
		pSg++;
		pBuf = (unsigned short *)MapPtrToProcess((LPVOID)pSg->sb_buf, GetCallerProcess());
		bytes_this_sg = pSg->sb_len;
	}   // while sg
	LeaveCriticalSection(&(pDisk->d_DiskCardCrit));

	if (pDisk->d_DiskCardState != STATE_OPENED) 
	{
		status = DISK_DEAD_ERROR;
	}
	pSgr->sr_status = status;
	return status;
}   // DoDiskIO


//------------------------------------------------------------------------------
//
// Generates context data for this Init instance
//
// Arguments:
//      dwContext - registry path for this device's active key
//
//------------------------------------------------------------------------------
unsigned long
CFC_Init(
    unsigned long dwContext
    )
{
	unsigned long ret = 0;
	LPWSTR ActivePath = (LPWSTR) dwContext;	
    RETAILMSG(1, (_T("CFCARD:  CFC_Init(0x%x) entered (version 2)\r\n"),dwContext));
	ret = CFC_InitDisk(ActivePath);
    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Init(0x%x) returning %d\r\n"),dwContext, ret));
	return ret;
}	// CFC_Init

//------------------------------------------------------------------------------
//
// Updates handle value for the open instance.
//
// Arguments:
//		dwData - the initialized instance
//		dwAccess - ignore
//		dwShareMode - ignore
//
//------------------------------------------------------------------------------
unsigned long
CFC_Open(
    unsigned long dwData,
    unsigned long dwAccess,
    unsigned long dwShareMode
    )
{
    unsigned long ret = 0;
    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Open(0x%x) entered\r\n"),dwData));
	if (dwData)
		ret = CFC_OpenDisk();
    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Open(0x%x) returning %d\r\n"),dwData, ret));
    return ret;
}   // CFC_Open



//------------------------------------------------------------------------------
//
// Updates handle value for the close instance.
//
// Arguments:
//		dwContext - the opened instance
//
//------------------------------------------------------------------------------
BOOL
CFC_Close(
    unsigned long dwContext
    )
{
    BOOL bClose = FALSE;

    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Close entered\r\n")));
	if (dwContext)
		if (CFC_CloseDisk())
			bClose = TRUE;
    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Close done\r\n")));
    return bClose;
}   // CFC_Close


//------------------------------------------------------------------------------
//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
// Arguments:
//		dwContext - the opened instance
//
//------------------------------------------------------------------------------
BOOL
CFC_Deinit(
    unsigned long dwContext
    )
{    
    BOOL bDeinit = FALSE;

    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Deinit entered\r\n")));
	if (dwContext)
		if (CFC_DeinitDisk())
			bDeinit = TRUE;
    RETAILMSG(MSG_SYS, (_T("CFCARD:  CFC_Deinit done\r\n")));
    return bDeinit;
}   // CFC_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
CFC_IOControl(
    unsigned long dwContext,
    unsigned long dwIoControlCode,
    unsigned char * pInBuf,
    unsigned long nInBufSize,
    unsigned char * pOutBuf,
    unsigned long nOutBufSize,
    unsigned long * pBytesReturned
    )
{
    PSG_REQ pSG;
	PDISK_INFO pInfo;
	PDISK pDisk;
	if (dwContext)
		pDisk = &g_Disk;
  
    if (pDisk->d_DiskCardState != STATE_OPENED) {
        RETAILMSG(MSG_SYS, (_T("CFCARD: -CFC_IOControl (disk card state) \r\n")));
        return FALSE;
    }

    // Check parameters
    switch (dwIoControlCode) {
    case DISK_IOCTL_READ:
    case DISK_IOCTL_WRITE:
    case DISK_IOCTL_GETINFO:
    case DISK_IOCTL_SETINFO:
    case DISK_IOCTL_INITIALIZED:
        if (pInBuf == NULL) {
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        break;

    case DISK_IOCTL_GETNAME:
        if (pOutBuf == NULL) {
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        break;

    case IOCTL_DISK_DEVICE_INFO:
        if(!pInBuf || nInBufSize != sizeof(STORAGEDEVICEINFO)) {
            SetLastError(ERROR_INVALID_PARAMETER);   
            return FALSE;
        }
        break;

    case DISK_IOCTL_FORMAT_MEDIA:
        SetLastError(ERROR_SUCCESS);
        return TRUE;
    
    default:
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    // Execute dwIoControlCode
    switch (dwIoControlCode) 
	{
    case DISK_IOCTL_READ:
    case DISK_IOCTL_WRITE:
        pSG = (PSG_REQ)pInBuf;
        CFC_DoDiskIO(pDisk, dwIoControlCode, pSG);
        if (pSG->sr_status) 
		{
            SetLastError(pSG->sr_status);
            return FALSE;
        }
        return TRUE;

    case DISK_IOCTL_GETINFO:
		pInfo = (PDISK_INFO) pInBuf;
		pInfo->di_total_sectors = pDisk->d_DiskInfo.di_total_sectors;
		pInfo->di_bytes_per_sect = pDisk->d_DiskInfo.di_bytes_per_sect;
		pInfo->di_cylinders = pDisk->d_DiskInfo.di_cylinders;
		pInfo->di_heads = pDisk->d_DiskInfo.di_heads;
		pInfo->di_sectors = pDisk->d_DiskInfo.di_sectors;
		pInfo->di_flags = pDisk->d_DiskInfo.di_flags;
        return TRUE;

    case DISK_IOCTL_SETINFO:
		pInfo = (PDISK_INFO) pInBuf;
		pDisk->d_DiskInfo.di_total_sectors = pInfo->di_total_sectors;
		pDisk->d_DiskInfo.di_bytes_per_sect = pInfo->di_bytes_per_sect;
		pDisk->d_DiskInfo.di_cylinders = pInfo->di_cylinders;
		pDisk->d_DiskInfo.di_heads = pInfo->di_heads;
		pDisk->d_DiskInfo.di_sectors = pInfo->di_sectors;
		pDisk->d_DiskInfo.di_flags = pInfo->di_flags;
        return TRUE;

    case DISK_IOCTL_INITIALIZED:
        return TRUE;

    case DISK_IOCTL_GETNAME:
		{
			unsigned short *namestring = L"CF Card";
			RETAILMSG(MSG_SYS, (_T("CFCARD: -CFC_IOControl (name) \r\n")));
			if (!CFC_GetFolderName(pDisk, (LPWSTR)pOutBuf, nOutBufSize, pBytesReturned))
				memcpy(pOutBuf, namestring, nOutBufSize);
			return TRUE;
		}
    case IOCTL_DISK_DEVICE_INFO: // new ioctl for disk info
        RETAILMSG(MSG_SYS, (_T("CFCARD: -CFC_IOControl (device info) \r\n")));
        return CFC_GetDeviceInfo(pDisk, (PSTORAGEDEVICEINFO)pInBuf);

    default:
        RETAILMSG(MSG_SYS, (_T("CFCARD: -CFC_IOControl (default) \r\n")));
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
}   // CFC_IOControl

//------------------------------------------------------------------------------
// Reserved
//------------------------------------------------------------------------------
unsigned long CFC_Read(unsigned long Handle, LPVOID pBuffer, unsigned long dwNumBytes){return 0;}
unsigned long CFC_Write(unsigned long Handle, LPVOID pBuffer, unsigned long dwNumBytes){return 0;}
unsigned long CFC_Seek(unsigned long Handle, long lDistance, unsigned long dwMoveMethod){return 0;}
void CFC_PowerUp(void){}
void CFC_PowerDown(void){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -