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

📄 sd_sys.c

📁 linux 2.6下的sd卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
		spin_lock_irq(q->queue_lock);		set_current_state(TASK_INTERRUPTIBLE);		if (!blk_queue_plugged(q))			pSDI->req = req = elv_next_request(q);		spin_unlock_irq(q->queue_lock);		if (!req) {			if (pSDI->flags & SD_QUEUE_EXIT)				break;			up(&pSDI->thread_sem);			schedule();			down(&pSDI->thread_sem);			continue;		}		set_current_state(TASK_RUNNING);				SD_issue_rq(req);					} while (1);		remove_wait_queue(&pSDI->thread_wq, &wait);	up(&pSDI->thread_sem);	complete_and_exit(&pSDI->thread_complete, 0);	return 0;}/* * Prepare a SD request.  Essentially, this means passing the * preparation off to the media driver.  The media driver will * create a mmc_io_request in req->special. */static int SD_prep_request(struct request_queue *q, struct request *req){	int ret = BLKPREP_KILL;	if (req->flags & REQ_SPECIAL) {		/*		 * Special commands already have the command		 * blocks already setup in req->special.		 */		BUG_ON(!req->special);		ret = BLKPREP_OK;	} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {		/*		 * Block I/O requests need translating according		 * to the protocol.		 */		ret = BLKPREP_OK;	} else {		/*		 * Everything else is invalid.		 */		blk_dump_rq_flags(req, "SD bad request");	}	if (ret == BLKPREP_OK)		req->flags |= REQ_DONTPREP;	return ret;}static void SD_request(request_queue_t *q){	if (!pSDI->req)		wake_up(&pSDI->thread_wq);}//----------------------------------------static int use_sd=1;static int __init setup_sd(char *str){	if(str[0] == '0') use_sd=0;	return 1;}__setup("sd=", setup_sd);static int use_sdplug=0;static int __init setup_sdplug(char *str){	if(str[0] == '1') use_sdplug=1;	return 1;}__setup("sdplug=", setup_sdplug);#include <asm/io.h>#include <asm/sizes.h>extern unsigned long RCA;//2007-07-31: add soft irq to handle timer irqstatic void SD_tasklet_card(unsigned long param){	//1--inserted, 0--uninserted		if (sdinsert == 1) {		if (!SDI_SendCmd(pSDI, &CommandParameters[SEND_STATUS], RCA, 0, 0)) {			sdinsert = 0;			SD_remove(pSDI);			printk("<1>SD Card removed\n");		}	} else {		if(SD_insert(pSDI)) {			sdinsert = 1;			printk("<1>SD Card inserted!\n");		}			}			mod_timer(&pSDI->timer, jiffies + HZ);}static void SD_check_status(unsigned long data){	tasklet_schedule(&pSDI->card_tasklet);	}static int check_sd_status(void){	return sdinsert;}#define SDPLUG_IOC_MAGIC  'n'#define SDPLUG_IOCREQUEST	 _IOR(SDPLUG_IOC_MAGIC, 1, unsigned long )static int sdplug_ioctl(struct inode *inode, struct file *filp,                       unsigned int cmd, unsigned long arg){    switch (cmd)    {	    case SDPLUG_IOCREQUEST :			return check_sd_status();	}	return 0;}static struct file_operations sdplug_fops = {	ioctl:sdplug_ioctl,};//2007-07-31: add request thread to handle request.//TODO: timer handle to support hot-plugstatic int __init SD_init(void){   	int ret;		printk("SD_init\n");	if(use_sd == 0) return -ENODEV;                    	if(register_chrdev(218, "sd-plug", &sdplug_fops) < 0){    	printk("<1>sd-plug: unable to register major\n");		return -ENODEV;	}    if(register_blkdev(SD_MAJOR,"z228_sd")){//register the block device         printk("cann't register the block device z228_sd\n");        return -EBUSY;    }                               pSDI = kmalloc(sizeof(SD_controller),GFP_KERNEL);//malloc the SD_controller struct    if(!pSDI){        printk("fail to malloc device!\n");        goto unregister_device;    }    if (!SDI_init(pSDI)){//call the SDI_Initface        printk("fail to  init the SDI!\n");        goto out_disk;    }                   		spin_lock_init(&pSDI->lock);	spin_lock_init(&pSDI->cmd_lock);	//blk_cleanup_queue should be called in release funciont!    pSDI->queue = blk_init_queue(SD_request, (spinlock_t *) (&pSDI->lock));    if(pSDI->queue == NULL){        printk("cannot init queue z228_sd\n");        goto out_disk;    }	blk_queue_prep_rq(pSDI->queue, SD_prep_request);		blk_queue_bounce_limit(pSDI->queue, BLK_BOUNCE_HIGH);	blk_queue_max_sectors(pSDI->queue, 8);	blk_queue_max_phys_segments(pSDI->queue, 16);	blk_queue_max_hw_segments(pSDI->queue, 16);	blk_queue_max_segment_size(pSDI->queue, 64<<9);	blk_queue_hardsect_size(pSDI->queue, 1 << BYTES_PER_SECTOR_SH);	pSDI->req = NULL;	init_completion(&pSDI->thread_complete);	init_waitqueue_head(&pSDI->thread_wq);	init_MUTEX(&pSDI->thread_sem);	ret = kernel_thread(SD_queue_thread, NULL, CLONE_KERNEL);	if (ret < 0) {		printk("create queue thread error\n");				goto out_disk;	}	wait_for_completion(&pSDI->thread_complete);	init_completion(&pSDI->thread_complete);	tasklet_init(&pSDI->card_tasklet, SD_tasklet_card, NULL);	pSDI->gd = alloc_disk(1);//alloc a gendisk    if(!pSDI->gd){        printk(KERN_NOTICE "alloc_disk failure\n");        return 1;    }	    //initialize the gen disk    pSDI->gd->major = SD_MAJOR;    pSDI->gd->first_minor = 0;    pSDI->gd->fops = &SD_ops;    pSDI->gd->queue = pSDI->queue;    pSDI->gd->private_data = NULL;	strcpy(pSDI->gd->disk_name, "z228_sd");	//SD_controller *dev = inode->i_bdev->bd_disk->private_data;    if(sd_request_dma() < 0){//reuest a dma channel        printk("sd dma error!\n");        goto out_disk;    }	if(use_sdplug==0) {		if(SD_insert(pSDI)) {			sdinsert = 1;			//add_disk(pSDI->gd);					} else {			void *r;			u32 data;			r = ioremap(0x2002c000, SZ_4K);			if(r==NULL){				printk("sd gpio setup error3\n");				return -ENODEV;			}			data = readl(r+0x400);			writel((data & 0xef), r+0x400);			data = readl(r+0x410);			writel((data & 0xef), r+0x400);			iounmap(r);		}	}#if 0	init_timer(&pSDI->timer);	pSDI->timer.data = NULL;	pSDI->timer.function = SD_check_status;	pSDI->timer.expires = jiffies + HZ;	add_timer(&pSDI->timer);#endif		printk("<1>Z228 SD init OK\n");	return 0;out_disk:	if(pSDI){		pSDI->flags |= SD_QUEUE_EXIT;						wake_up(&pSDI->thread_wq);					wait_for_completion(&pSDI->thread_complete);		       	if(pSDI->irq_request_sign)	    	free_irq(14,NULL);		       	if(pSDI->Registers)			iounmap((void *)pSDI->Registers);		       	if(pSDI->queue)	       	blk_cleanup_queue(pSDI->queue);		if(pSDI->gd)            del_gendisk(pSDI->gd);		       	kfree((void *)pSDI);  	}	unregister_device:	    unregister_blkdev(SD_MAJOR,"z228_sd");	unregister_chrdev(218, "sd-plug");    return -ENODEV;}//--------------------------------------------------------static void __exit SD_cleanup(void){           if(pSDI){	    SDI_close(pSDI);	    SDI_deInit(pSDI);		pSDI->flags |= SD_QUEUE_EXIT;				wake_up(&pSDI->thread_wq);						wait_for_completion(&pSDI->thread_complete);        if(pSDI->irq_request_sign)            free_irq(14,NULL);		        if(pSDI->Registers)            iounmap((void *)pSDI->Registers);		        if(pSDI->queue)            blk_cleanup_queue(pSDI->queue);		        if(pSDI->gd)            del_gendisk(pSDI->gd);		        kfree((void *)pSDI);    }    unregister_blkdev(SD_MAJOR,"z228_sd");	unregister_chrdev(218, "sd-plug");}               module_init(SD_init);module_exit(SD_cleanup);MODULE_AUTHOR("Jade Tech");MODULE_LICENSE("Dual BSD/GPL");MODULE_DESCRIPTION("z228 SD card driver!");

⌨️ 快捷键说明

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