📄 sd_data.c
字号:
/**************************************************************************** File: sd_data.c - Read / Write Functions* * 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 <linux/sched.h>#include "sd.h"#define SD_DATA_DEBUG_LEVEL 0unsigned long TempBufAl[SECTORS_PER_BATCH*BYTES_PER_SECTOR/4];unsigned long TempBufA2[SECTORS_PER_BATCH*BYTES_PER_SECTOR/4];extern unsigned long RCA;//------------------------------------------------------------------------------//// Block read - read a number of sectors from the card//// Arguments:// controller - instance created in SDI_InitInterface// SectorNum - the number of first sector to be read// SectorCnt - how many sectors to be read// buffer - buffer to receive data// errorcode - record error. //// Functions:// Call function SDI_SafeRead to read data sector by sector. ////------------------------------------------------------------------------------BOOL SDI_BlockRead( SD_controller* controller, unsigned long SectorNum, unsigned long SectorCnt, unsigned char* buffer, unsigned long* errorcode ){ unsigned long error = 0; if (!controller) error = 1; if (!error) { unsigned long i; unsigned long sectors_this = 0; for (i=0; i<SectorCnt; i+=SECTORS_PER_BATCH) { sectors_this = MIN(SECTORS_PER_BATCH, (SectorCnt-i)); if (!SDI_SafeRead(controller, SectorNum+i, sectors_this, buffer+i*BYTES_PER_SECTOR, &error)) { printk("<1>saferead result:%ld\n", error); error = 2; break; } } } if (error) { if (errorcode) *errorcode = error; return FALSE; } return TRUE;}//------------------------------------------------------------------------------//// Block write - write a number of sectors to the card//// Arguments:// controller - handle for the instance// SectorNum - the number of first sector to be write// SectorCnt - how many sectors to be write// buffer - buffer to send data// errorcode - record error//// Functions:// Call function SDI_SafeWrite to write data sector by sector. ////------------------------------------------------------------------------------BOOL SDI_BlockWrite( SD_controller* controller, unsigned long SectorNum, unsigned long SectorCnt, unsigned char* buffer, unsigned long* errorcode ){ unsigned long error = 0; if (!controller) error = 1; if (!error) { unsigned long i; unsigned long sectors_this = 0; for (i=0; i<SectorCnt; i+=SECTORS_PER_BATCH) { sectors_this = MIN(SECTORS_PER_BATCH, (SectorCnt-i)); if (!SDI_SafeWrite(controller, SectorNum+i, sectors_this, buffer+i*BYTES_PER_SECTOR, &error)) { printk("<1>safewrite result:%ld\n", error); error = 2; break; } } } if (error) { if (errorcode) *errorcode = error; return FALSE; } return TRUE;}// for safe, retry RETRYNUM times if error.#define RETRYNUM 3 //------------------------------------------------------------------------------//// Safe read - read a sector from the card//// Arguments:// controller - instance created in SDI_InitInterface// SectorNum - the number of first sector to be read// buffer - buffer to receive data// errorcode - record error. //// Functions:// Call function SDI_SectorRead_FIFO or SDI_SectorRead_DMA // to read data from a single sector. Reset if error occured, // and retry last sector. ////------------------------------------------------------------------------------BOOL SDI_SafeRead( SD_controller* controller, unsigned long SectorNum, unsigned long SectorCnt, unsigned char* buffer, unsigned long* errorcode ){ unsigned long error = 0; unsigned long retry = RETRYNUM; unsigned char * bufthis; if ((int)buffer&0x3) bufthis = (unsigned char*)TempBufAl; else bufthis = (unsigned char*)buffer; if (!controller) error = 1; if (!error) { while (retry--) { if (controller->ifDMA) { SDI_BatchRead_DMA(controller, SectorNum, SectorCnt, bufthis, &error); } else { return FALSE; } if (!error) break; else { if (error > 2) { int resetretry=3; while(resetretry){ error = 0; SDI_ResetInterface(controller, &error); SDI_StartUpCard(controller, &error); if(!error) break; printk("<1>reset error:%ld, retry\n", error); resetretry--; } if (error) { printk("<1>reset failed\n"); error = 4; break; } } else { error = 3; break; } } } if (retry != (RETRYNUM)){ } if (!retry) error = 2; } if ((int)buffer&0x3) memcpy(buffer, TempBufAl, BYTES_PER_SECTOR*SectorCnt); if (error) { if (errorcode) *errorcode = error; return FALSE; } return TRUE;}//------------------------------------------------------------------------------//// Safe write - write a sector to the card//// Arguments:// controller - instance created in SDI_InitInterface// SectorNum - the number of first sector to be write// buffer - buffer to send data// errorcode - record error. //// Functions:// Call function SDI_SectorWrite_FIFO or SDI_SectorWrite_DMA // to write data to a single sector. Reset if error occured, // and retry last sector. ////------------------------------------------------------------------------------BOOL SDI_SafeWrite( SD_controller* controller, unsigned long SectorNum, unsigned long SectorCnt, unsigned char* buffer, unsigned long* errorcode ){ unsigned long error = 0; unsigned long retry = RETRYNUM; unsigned char * bufthis; if ((int)buffer&0x3) { printk("buffer misalign!\n"); bufthis = (unsigned char*)TempBufA2; memcpy(TempBufA2, buffer, BYTES_PER_SECTOR*SectorCnt); } else bufthis = (unsigned char*)buffer; if (!controller) error = 1; if (!error) { while (retry--) { if (controller->ifDMA) { SDI_BatchWrite_DMA(controller, SectorNum, SectorCnt, bufthis, &error); } else { return FALSE; } if (!error) break; else { if (error > 2) { int resetretry=3; while(resetretry){ error = 0; SDI_ResetInterface(controller, &error); SDI_StartUpCard(controller, &error); if(!error) break; printk("<1>reset error:%ld, retry\n", error); resetretry--; } if (error) { printk("<1>reset failed\n"); error = 4; break; } } else { error = 3; break; } } } if (retry != (RETRYNUM)){ } if (!retry) error = 2; } if (error) { if (errorcode) *errorcode = error; return FALSE; } return TRUE;}//-------------dma#include <asm/dma.h>#include <asm/mach/dma.h>#include <linux/completion.h>/******************************************************************* * 07.06.28: * add supprt to use 1 or 2 dma line, default is 1 dma line*******************************************************************/#define USE_ONE_DMA_LINE 0 #if USE_ONE_DMA_LINEstatic int ch;#elsestatic int ch_r;static int ch_w;#endifstatic struct ver_dma_param pa;static void sd_dma_done(int a, int b, void *data){ if (data != NULL) complete(data);}#if USE_ONE_DMA_LINEint sd_request_dma(void){ ch = ver_request_dma(0, "dma_sd", 0, 0); if(ch < 0){ printk("<1> alloc sd dma error\n"); return -1; }else{ printk("<1> sd dma chan: %d\n", ch); } memset(&pa, 0, sizeof (pa)); return 0;}static int sd_free_dma(void){ if (ver_free_dma(ch) !=0) { printk("<1>free sd dma error\n"); return -1; } return 0;}static int sd_start_dma(int read, void *buffer, u32 size, void *p_comp){ pa.SWidth = DMAC_TSIZE_WORD; pa.DWidth = DMAC_TSIZE_WORD; if(read){ pa.SBsize = BURST_SIZE_8; pa.DBsize = BURST_SIZE_1; pa.FlowCntrl = FLOW_PER_MEM_DMAC; pa.SIncr = 0; pa.DIncr = 1; }else{ pa.SBsize = BURST_SIZE_1; pa.DBsize = BURST_SIZE_8; pa.FlowCntrl = FLOW_MEM_PER_DMAC; pa.SIncr = 1; pa.DIncr = 0; } if (ver_set_dma(ch, &pa) != 0) { printk("<1>sd :set dma fail:\n"); return -1; } pa.sg_len = 0; pa.tsize = size; if(read){ pa.sbuf = (void *) (PHYS_SD0_BASE+0x80); pa.dbuf = buffer; }else{ pa.sbuf = buffer; pa.dbuf = (void *) (PHYS_SD0_BASE+0x80); } pa.trans_done = sd_dma_done; pa.done_data = p_comp; if (ver_start_dma(ch, &pa) != 0) { printk("<1>sd:start dma fail:%d\n", size); return -1; } return 0;}#elseint sd_request_dma(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -