//打开设备文件系统调用对应的操作
static int card_open(struct inode *inode, struct file *filp)
{
return 0;
}
//关闭设备文件系统调用对应的操作
static int card_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t card_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
{
void* virt_addr = NULL;
dma_addr_t dma_write_addr;
u32 base, w_ddr2, w_addr,w_size,cst_32,w_counter,dma_cst;
u32 ddr2;
int i;
i = 0;
pci_read_config_dword(adapter->pci_dev, 0x10, &base);
printk(KERN_DEBUG " pci_read_config_dword, base:%x\n",base);
printk(KERN_DEBUG "adater -> pci_bar0 %lx\n",(unsigned long)(adapter -> pci_bar0));
/*********Request virt_addr(kernel) for Read(DMA write)********/
virt_addr = kmalloc(count, GFP_KERNEL|__GFP_DMA);
if(unlikely(!virt_addr))
{
//PDEBUG("cannot alloc rx memory you want ... \n");
return -EIO;
}
printk(KERN_DEBUG " virt_addr(kernel):%x\n",(u32)virt_addr);
/*********Request virt_addr(kernel) for Read(DMA write)********/
/**********************dma_write_addr************************/
//将存储器域的虚拟地址virt_addr转化为pci总线域的物理地址dma_write_addr,供card的DMA控制器使用。
dma_write_addr = pci_map_single(adapter->pci_dev, virt_addr, count, PCI_DMA_FROMDEVICE);
if(unlikely(pci_dma_mapping_error(adapter->pci_dev, dma_write_addr)))
{
//PDEBUG("RX DMA MAPPING FAIL...\n");
goto err_kmalloc;
}
printk(KERN_DEBUG " dma_write_addr:%x\n",dma_write_addr);
/**********************dma_write_addr************************/
/**********************BAR0 kong jian ***********************/
// START, w_counter
w_counter = ioread32((adapter -> pci_bar0+WRITE_DMA_COUNTER_OFFSET));
printk(KERN_DEBUG " START, w_counter: %x",w_counter);
// w_ddr2
iowrite32(*f_pos,(adapter -> pci_bar0 + WRITE_DDR2_SA_OFFSET));
ddr2 = ioread32((adapter -> pci_bar0 + WRITE_DDR2_SA_OFFSET));
printk(KERN_DEBUG " WRITE_DDR2_SA_OFFSET: %x",ddr2);
// w_addr
// Lower 32-bit address of system memory buffer for DMA write operation.
iowrite32(dma_write_addr,(adapter -> pci_bar0 + WRITE_HOST_DA_L_OFFSET));
// w_size
// Write DMA TLP Size Register(from DDR2 to mm).
iowrite32(count,(adapter -> pci_bar0 + WRITE_SIZE_OFFSET));
// Write DMA Control && Status Register
dma_cst = 0;
dma_cst = ioread32((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst1: %x",dma_cst);
dma_cst = dma_cst | 0x1;
printk(KERN_DEBUG "dma_cst2: %x",dma_cst);
// dma_cst
//writel(dma_cst,(void __iomem *) (unsigned long) (adapter -> pci_bar0 + DMA_CST_OFFSET));
iowrite32(dma_cst,(adapter -> pci_bar0 + DMA_CST_OFFSET));
dma_cst = ioread32((adapter -> pci_bar0+DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst3: %x",dma_cst);
while( (!(dma_cst & 0x2))&&(i<1000) )
{
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
i++;
printk(KERN_DEBUG "#########################################");
}
i = 0;
dma_cst = dma_cst | 0x2;
iowrite32(dma_cst,(adapter -> pci_bar0 + DMA_CST_OFFSET));
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst4: %x",dma_cst);
//interruptible_sleep_on((adapter->dma_write_wait));
//wait_event_interruptible(dma_write_wait,flag);
//flag = 0;
//test (w_ddr2, w_addr,w_size,cst_32,w_counter)
w_ddr2 = ioread32((adapter -> pci_bar0 + WRITE_DDR2_SA_OFFSET));
w_addr = ioread32((adapter -> pci_bar0 + WRITE_HOST_DA_L_OFFSET));
w_size = ioread32((adapter -> pci_bar0 + WRITE_SIZE_OFFSET));
cst_32 = ioread32((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "w_ddr2: %x; w_addr: %x; w_size: %u; w_cst:%x \n",w_ddr2,w_addr,w_size,cst_32);
//END, w_counter
w_counter = ioread32((adapter -> pci_bar0+WRITE_DMA_COUNTER_OFFSET));
printk(KERN_DEBUG "END, w_counter: %x\n",w_counter);
/*************************BAR0 kong jian **************************/
/*************************copy_to_user****************************/
if(unlikely(copy_to_user(buf,virt_addr,count)))
goto err_pci_map;
/*************************copy_to_user****************************/
pci_unmap_single(adapter->pci_dev, dma_write_addr, count, PCI_DMA_FROMDEVICE);
kfree(virt_addr);
printk(KERN_DEBUG "Here I am: %s:%i\n",__FILE__,__LINE__);
return count;
err_pci_map:
//wake_up_interruptible(&adapter->dma_write_wait);
return -1;
err_kmalloc:
return -1;
}
static ssize_t card_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
{
//unsigned int dma_cst = 0;
int err = -EINVAL;
void * virt_addr = NULL;
dma_addr_t dma_read_addr;
u32 base, r_addr, r_ddr2, r_size, cst_32, r_counter,dma_cst;
struct timeval tv1;
struct timeval tv2;
spinlock_t write_lock;
int i;
i = 0;
/************************BAR0****************************/
pci_read_config_dword(adapter->pci_dev, 0x10, &base);
printk(KERN_DEBUG " pci_read_config_dword, base:%x\n",base);
printk(KERN_DEBUG "adater -> pci_bar0 %lx\n",(unsigned long)(adapter -> pci_bar0));
/************************BAR0****************************/
/***********Request virt_addr(kernel) for Write(DMA Read)*********/
virt_addr = kmalloc(count, GFP_KERNEL|__GFP_DMA);
if(unlikely(copy_from_user(virt_addr, buf, count)))
return err;
printk(KERN_DEBUG " virt_addr(kernel):%x\n",(u32)virt_addr);
/***********Request virt_addr(kernel) for Write(DMA Read)*********/
/************************dma_read_addr****************************/
dma_read_addr = pci_map_single(adapter->pci_dev, virt_addr, count, PCI_DMA_TODEVICE);
if(unlikely(pci_dma_mapping_error(adapter->pci_dev, dma_read_addr)))
{
//PDEBUG("RX DMA MAPPING FAIL...\n");
goto err_kmalloc;
}
printk(KERN_DEBUG " dma_read_addr:%x\n", dma_read_addr);
/************************dma_read_addr****************************/
spin_lock_init(&write_lock);
/*************************BAR0 kong jian **************************/
spin_lock(&write_lock);
// START, r_counter
r_counter = ioread32((adapter -> pci_bar0 + READ_DMA_COUNTER_OFFSET));
printk(KERN_DEBUG " START, r_counter: %x",r_counter);
// r_addr
// Lower 32-bit address of system memory buffer for DMA READ operation.
iowrite32(dma_read_addr, (adapter -> pci_bar0 + READ_HOST_SA_L_OFFSET));
// r_ddr2
iowrite32(*f_pos,(adapter -> pci_bar0 + READ_DDR2_DA_OFFSET));
// r_size
// Read DMA TLP Size Register(from mm to DDR2).
iowrite32(count, (adapter -> pci_bar0 + READ_SIZE_OFFSET));
// dma_cst
// Read DMA Control and Status Register
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst1: %x",dma_cst);
dma_cst = dma_cst | 0x4;
iowrite8(dma_cst,(adapter -> pci_bar0 + DMA_CST_OFFSET));
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst2: %x",dma_cst);
do_gettimeofday(&tv1);
while( (!(dma_cst & 0x8)) && (i < 1000) )
{
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
i++;
//printk(KERN_DEBUG "******************%d \n",i);
}
do_gettimeofday(&tv2);
printk(KERN_DEBUG "time_time: %ld",(tv2.tv_usec-tv1.tv_usec));
i = 0;
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst3: %x",dma_cst);
dma_cst = dma_cst | 0x8;
iowrite8(dma_cst,(adapter -> pci_bar0 + DMA_CST_OFFSET));
dma_cst = ioread8((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "dma_cst4: %x",dma_cst);
//adapter->dma_read_done = 0;
//if(unlikely(interruptible_sleep_on(adapter->dma_read_wait)))
// goto err_pci_map;
//interruptible_sleep_on(adapter->dma_read_wait);
//test (r_addr,r_ddr2,r_size,cst_32, r_counter)
r_ddr2 = ioread32((adapter -> pci_bar0 + READ_DDR2_DA_OFFSET));
r_addr = ioread32((adapter -> pci_bar0 + READ_HOST_SA_L_OFFSET));
r_size = ioread32((adapter -> pci_bar0 + READ_SIZE_OFFSET));
cst_32 = ioread32((adapter -> pci_bar0 + DMA_CST_OFFSET));
printk(KERN_DEBUG "r_ddr2: %x; r_addr: %x; r_size: %u; r_cst:%x \n",r_ddr2,r_addr,r_size,cst_32);
//END, w_counter
r_counter = ioread32((adapter -> pci_bar0 + READ_DMA_COUNTER_OFFSET));
printk(KERN_DEBUG "END, r_counter: %x\n",r_counter);
spin_unlock(&write_lock);
/*************************BAR0 kong jian **************************/
pci_unmap_single(adapter->pci_dev, dma_read_addr, count, PCI_DMA_TODEVICE);
kfree(virt_addr);
printk(KERN_DEBUG "Here I am: %s:%i\n",__FILE__,__LINE__);
return count;
err_kmalloc:
return -1;
}
/*
static irqreturn_t card_interrupt(int irq, void * dev)
{
u8 status,abc;
status = 0;
printk(KERN_DEBUG "jinru zhonduan!!! Here I am: %s:%i\n",__FILE__,__LINE__);
//status = card_r32(INT_REG);
//pci_read_config_dword(adapter->pci_dev, DCSR_OFFSET, &status);
status = ioread8((adapter -> pci_bar0+DMA_CST_OFFSET));
//if(!(status & INT_ASSERT))
//{
// PDEBUG("irq_none ... \n");
// return IRQ_NONE;
//}
if(status & INT_ASSERT_W) //DMA Write Complete
{
//card_w32(status, INT_REG);
//clear ISR
//pci_read_config_dword(adapter->pci_dev, DCSR_OFFSET, status);
abc = status | INT_ASSERT_W;
iowrite8(abc,(adapter -> pci_bar0+DMA_CST_OFFSET));
//writel(status,(void __iomem *) (unsigned long) (adapter -> pci_bar0 + DMA_CST_OFFSET));
//i = 1;
//wake_up_interruptible(adapter->dma_write_wait);
flag = 1;
wake_up_interruptible(&dma_write_wait);
return IRQ_HANDLED;
}
if(status & INT_ASSERT_R) //DMA Read Complete
{
//card_w32(status, INT_REG);
//clear ISR
//pci_read_config_dword(adapter->pci_dev, DCSR_OFFSET, status);
status = status & ~INT_ASSERT_R;
writel(status,(void __iomem *) (unsigned long) (adapter -> pci_bar0 + DMA_CST_OFFSET));
//wake_up_interruptible(adapter->dma_read_wait);
return IRQ_HANDLED;
}
//PDEBUG("irq handled ... \n");
return IRQ_HANDLED;
} */