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

📄 sd_sys.c

📁 linux 2.6下的sd卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************   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 <linux/syscalls.h>#include <linux/module.h>#include <linux/blkdev.h>#include "sd.h"#define SD_SYS_DEBUG	0#define SD_MAJOR  220#define SD_MINOR  0//------------------------------------------------------------------------------// Global Variables in SD_SYS.C//------------------------------------------------------------------------------//DISK_INFO             DiskInfo = {0};                         // store information of card//LPWSTR                ActivePath = NULL;                      // get strings in registerstatic SD_controller    *pSDI = NULL;                   // structure of card's instancestatic int              g_ExcCnt = 0;                   // count times open/close error ocurredstatic int              g_CardStatus = 0;               // indicate the card's statestatic int              nsectors = 8;int sdinsert=0;int irqcount=0;int irqcount1=0;static int SD_open(struct inode *inode,struct file *filp);static int SD_release(struct inode *inode,struct file *filp);static int SD_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);static struct block_device_operations SD_ops = {        .owner  = THIS_MODULE,        .open   = SD_open,        .release= SD_release,        .ioctl  = SD_ioctl};//----------------------------------------------//reset the interface and register SD cmd irq//----------------------------------------------static BOOLSDI_init(SD_controller * pSDI){    unsigned long errorcode = 0;	    pSDI->irq_request_sign  = 1;//indicate no irq is requested    if(!SDI_InitInterface(pSDI,&errorcode))            return 0;    g_CardStatus = STATE_INITING;#if     SD_TEST    g_CardStatus = STATE_TEST;#endif    return 1;}//-------------------------------------------------static BOOLSD_insert1(SD_controller * pSDI){    unsigned long errorcode = 0;	    if (SDI_StartUpCard(pSDI, &errorcode)){						set_capacity(pSDI->gd, (pSDI->CardCSD.CardSize)/BYTES_PER_SECTOR );//set the disk size        if (g_CardStatus != STATE_TEST)            g_CardStatus = STATE_OPENED;        g_ExcCnt = 0;		add_disk(pSDI->gd);		return 1;    }else{        printk("<1>sdi_open:%lu\n", errorcode);        if (g_CardStatus != STATE_TEST)            g_CardStatus = STATE_CLOSED;        if ((g_ExcCnt++) > 8)            g_CardStatus = STATE_DEAD;		return 0;    }}static BOOLSD_insert(SD_controller * pSDI){	int retry=3;	do {		if(SD_insert1(pSDI)) 			return 1;				retry--;		if(retry==0)			break;	} while(1);	return 0;} //------------------------------------------------------------------------------static BOOLSD_remove(SD_controller * pSDI){    BOOL bClose = FALSE;    unsigned long errorcode = 0;	    if (SDI_ResetInterface(pSDI, &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;}   // SDI_Close//------------------------------------------------------------------------------static BOOLSDI_deinit(SD_controller *pSDI){    BOOL bDeinit = FALSE;    unsigned long errorcode = 0;    if (SDI_DeinitInterface(pSDI, &errorcode)){        bDeinit = TRUE;        g_CardStatus = STATE_DEINITING;    }else{        g_CardStatus = STATE_DEAD;    }    msleep(100);    /*{		volatile int a, b; 		for(a=0; a<100; a++);			for(b=0; b<10000; b++); 	}*/    return bDeinit;}   //  SDI_Deinit#if SD_SYS_DEBUGstatic char sector_r[512];static char sector_w[512];static void SD_Demo(void){	int i;	unsigned long errorcode;		memset((void *)sector_r, 0, 512);		memset((void *)sector_w, 0xff, 512);	for (i=0; i<16; i++)		sector_w[i] = i;	{					printk("original w sector: \n");		for (i=0; i<16; i++) {			printk("%02X ", sector_w[i]);						}		printk("\n");	}	for (i=0; i<5; i++)		SDI_BlockWrite(pSDI, 5 + i, 1, sector_w, &errorcode);	for (i=0; i<5; i++)		SDI_BlockRead(pSDI, 5 + i, 1, sector_r, &errorcode);}#endif//-------------------------------------------------------static int SD_open(struct inode *inode,struct file *filp){#if SD_SYS_DEBUG		SD_Demo();#endif    return 0;}      //--------------------------------------------------------static int SD_release(struct inode *inode,struct file *filp){    return 0;}//--------------------------------------------------------static int SD_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){	switch (cmd) {		case HDIO_GETGEO:		{			struct hd_geometry g;			struct hd_geometry __user *geom= (void __user *)arg;			/*			g.heads = ((pSDI->CardCSD.CardSize)/BYTES_PER_SECTOR) >> 24;			g.sectors = (pSDI->CardCSD.CardSize)/BYTES_PER_SECTOR ;			g.cylinders = ((pSDI->CardCSD.CardSize)/BYTES_PER_SECTOR) >> 8 ;			*/			g.heads=4;			g.sectors=60;			g.cylinders = pSDI->CardCSD.CardSize / (g.heads * g.sectors * BYTES_PER_SECTOR) ;			//g.heads = 4;			//g.sectors = 16;			//g.cylinders = pSDI->CardCSD.CardSize / (g.heads * g.sectors * BYTES_PER_SECTOR) ;			g.start = 0;			return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;		}		default:			printk("SD_ioctl:%x, unsupport\n", cmd);			return -EINVAL;	}    return 0;}//--------------------------------------------------------#define SD_QUEUE_EXIT		(1 << 0)//2007-07-31: modify r/w request handle. use one thread to replace// old request function.static BOOL SD_issue_rq(struct request *req){	BOOL i = TRUE;	unsigned long errorcode = 0;	unsigned long start, len;	int ret = 0;	do {		start = req->sector;		len   = req->nr_sectors;		if(len >= 32) len = 31;		req->hard_cur_sectors = len;			//spin_lock(&pSDI->cmd_lock);	    if (rq_data_dir(req) == READ) {			//printk("cmd type: %c\n", 'R');	    	i = SDI_BlockRead(pSDI, start, len , req->buffer, &errorcode);						    } else if (rq_data_dir(req) == WRITE) {			//printk("cmd type: %c\n", 'W');			i = SDI_BlockWrite(pSDI, start, len , req->buffer, &errorcode);	    } else {	    	printk("cmd type: %c\n", 'X');			i = TRUE;		}		//spin_unlock(&pSDI->cmd_lock);				if (i == FALSE)			break;		/*		 * A block was successfully transferred.		 */		spin_lock_irq(&pSDI->lock);		ret = end_that_request_chunk(req, 1, len << 9);		if (!ret) {			/*			 * The whole request completed successfully.			 */			add_disk_randomness(req->rq_disk);			blkdev_dequeue_request(req);			end_that_request_last(req);		}		spin_unlock_irq(&pSDI->lock);			} while (ret);	if (i == FALSE) {		printk("%s errorcode:%lu\n", (rq_data_dir(req) == READ)?"read":"write", errorcode);		/*		 * This is a little draconian, but until we get proper		 * error handling sorted out here, its the best we can		 * do - especially as some hosts have no idea how much		 * data was transferred before the error occurred.		 */		spin_lock_irq(&pSDI->lock);		do {			ret = end_that_request_chunk(req, 0,			req->current_nr_sectors << 9);		} while (ret);		add_disk_randomness(req->rq_disk);		blkdev_dequeue_request(req);		end_that_request_last(req);		spin_unlock_irq(&pSDI->lock);	}	return i;}static int SD_queue_thread(void *d){	struct request_queue *q = pSDI->queue;		DECLARE_WAITQUEUE(wait, current);	/*	 * Set iothread to ensure that we aren't put to sleep by	 * the process freezing.  We handle suspension ourselves.	 */	current->flags |= PF_MEMALLOC|PF_NOFREEZE;	daemonize("mmcqd");	complete(&pSDI->thread_complete);	down(&pSDI->thread_sem);	add_wait_queue(&pSDI->thread_wq, &wait);	do {		struct request *req = NULL;

⌨️ 快捷键说明

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