- 論壇徽章:
- 0
|
回復(fù) #2 dreamice 的帖子
:wink:
整個的太長,大都是寄存器和初始化的一些操作,主要的處理函數(shù)就3個:
mcard_make_request
mcard_interrupt
mcard_transfer
mcard_make_request 調(diào)用 mcard_transfer 來進(jìn)行具體的傳輸
mcard_interrupt 通過中斷來喚醒mcard_make_request繼續(xù)下面的操作
/*********************************************************************
* transfer: mcard_transfer
* handle the DMA ops
*/
void mcard_transfer(unsigned long sector, int rw, struct bio *bio, unsigned long long * addr)
{
unsigned long long local_addr;
unsigned long byte_count;
local_addr = sector * 512; //當(dāng)前處理的設(shè)備內(nèi)存的偏移
byte_count = bio_iovec(bio)->bv_len;
switch(rw){
case READA:
case READ:
dma_read_flag = 0;
MCARD_START_DMA_WRITE(addr, local_addr, byte_count);
wait_event_interruptible(mcard_read_queue, dma_read_flag == 1));
break;
case WRITE:
dma_write_flag = 0;
MCARD_START_DMA_READ(addr, local_addr, byte_count);
wait_event_interruptible(mcard_write_queue, dma_write_flag == 1);
break;
default:
printk("ERROR: blk cmd error!!!.\n" ;
break;
}
}
/*********************************************************************
* make_request: mcard__make_request
*make request function
*/
static int mcard_make_request(request_queue_t *mcard_que, struct bio * bio)
{
int i, rw;
sector_t sector;
unsigned long len;
struct bio_vec *bvec;
sector = bio->bi_sector; //bio起始的sector
rw = bio_data_dir(bio);
bio_for_each_segment(bvec,bio,i)
{
char * addr = bio_to_phys(bio); //物理地址
mcard_transfer(sector, rw, bio, addr);
sector += bio_cur_sectors(bio);
}
bio_endio(bio,bio->bi_size,0);
return 0;
}
/*********************************************************************
* mcard_interrupt
*/
static irqreturn_t mcard_interrupt(int irq, void *data, struct pt_regs *regs)
{
unsigned int interrupt_flag;
interrupt_flag = MEMORY_MAPPED_IO_32BIT(MCARD_INTERRUPT_STATUS);
smp_mb();
if(!(interrupt_flag))
return IRQ_NONE;
MEMORY_MAPPED_IO_32BIT(MCARD_INTERRUPT_CLEAR)= interrupt_flag;//0xFFFFFFFF;
smp_wmb();
switch (tmp_interrupt_flag )
{
case DMA_READ_SUCCESS_FLAG : //DMA READ -- sys_wtire
dma_write_flag = 1;
smp_mb();
wake_up_interruptible(&mcard_write_queue);
break;
case DMA_WRITE_SUCCESS_FLAG :
dma_read_flag = 1;
smp_mb();
wake_up_interruptible(&mcard_read_queue);
break;
case TIMEOUT_WRITE_FLAG:
panic("time out for write occurred\n" ;
break;
case TIMEOUT_READ_FLAG:
panic("time out for read occurred\n" ;
break;
default:
printk("INTERRUPT ERROR,flag error, val is %d\n", interrupt_flag);
break;
}
return IRQ_HANDLED;
}
[ 本帖最后由 taylergreen 于 2008-12-23 17:58 編輯 ] |
|