阅读:1368回复:0
请教:9052接口芯片驱动读数据的问题
这个驱动能正确读取配置寄存器的内容,但是把基址2的数据读取出来时发现全是0
读取方法大概是这样一个过程:pci_find_device,check_mem_region,request_mem_regio n,ioremap,readb。其中check_mem_region返回0,成功。request_mem_region返回非0, 成功申请mem。 会不会是使用ioremap返回的内核虚拟地址不正确,还是需要设置配置寄存器里的某个寄存 器?配置寄存器中的PCI_COMMAND寄存器的PCI_COMMAND_MEMORY位已为1 为什么会出现 这种错误呢?请高手赐教~! 下面是我的驱动源代码以及用户程序调用驱动程序接口打印出来的配置寄存器的信息 #ifndef __KERNEL__ # define __KERNEL__ #endif #ifndef MODULE # define MODULE #endif #include <linux/pci.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/module.h> #include <asm/uaccess.h> /***************************************** |* IOCTL MACRO DEFINITIONS *| *****************************************/ #define TRNDRV_IOC_MAGIC 'k' #define TRNDRV_IOCREADCONFREGS _IOR(TRNDRV_IOC_MAGIC, 0, 0x40) #define TRNDRV_IOCREADOPERREGS _IOR(TRNDRV_IOC_MAGIC, 1, 0x40) #define TRNDRV_IOC_MAXNR 2 /***************************************** |* IOCTL MACRO DEFINITIONS *| *****************************************/ #define VENDORID 0x10b5 // unsigned short for vendor id of the PCI car d #define DEVICEID 0x9050 // unsigned short for device id of the PCI card /***************************************** |* GLOBAL DEFINITIONS *| *****************************************/ struct pci_dev * pdev = NULL; long * ptr; int readconfregs(u8 *regs); int readoperregs(u8 *regs); /**************************************** |* Driver "trndrv.o"s entries *| ****************************************/ loff_t trndrv_llseek(struct file *filp, loff_t off, int whence) { loff_t newpos = -EINVAL; return newpos; } int trndrv_open(struct inode *inode, struct file *filp) { return 0; } int trndrv_release(struct inode *inode, struct file *filp) { return 0; } ssize_t trndrv_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { u8 regs[11]; u8 check; int i; check=readb(ptr+0x0f); if(check & 0x80) { printk("<0>oddn"); for(i=0;i<11;i++) { regs=readb(ptr+0x10+i); printk("<0>%02x ",regs); } } else { printk("<0>evenn"); for(i=0;i<11;i++) { regs=readb(ptr+0x20+i); printk("<0>%02x ",regs); } } for(i=0;i<11;i++) { put_user(regs,( u8 * )(buf+i) ); } return 0; } ssize_t trndrv_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) { return 0; } int trndrv_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { u8 regs[256]; int i; switch (cmd) { case TRNDRV_IOCREADCONFREGS: if (readconfregs(regs)) return -PCIBIOS_BAD_REGISTER_NUMBER; for (i = 0; i < 256; i ++) put_user(regs, (u8 *)(arg + i)); break; case TRNDRV_IOCREADOPERREGS: readoperregs(regs); break; default: return -EINVAL; } return 0; } struct file_operations trndrv_fops = { llseek: trndrv_llseek, read: trndrv_read, write: trndrv_write, ioctl: trndrv_ioctl, open: trndrv_open, release: trndrv_release, }; /***************************************** |* Self-defined Functions *| *****************************************/ struct proc_dir_entry *create_proc_fops_entry(const char *name, mode_t mode, struct proc_dir_entry *base, void * data) { struct proc_dir_entry *result = create_proc_entry(name, mode, base); if (result) { result->proc_fops = &trndrv_fops; result->data = data; } return result; } int readconfregs(u8 *regs) { int result; int i; for (i = 0; i < 256; i ++) { result = pci_read_config_byte(pdev, i, regs + i); if (result) { printk(KERN_EMERG "reading config regs errorn"); return result; } } return 0; } int readoperregs(u8 *regs) { return 0; } void cleanup_module(void) { iounmap((char*)ptr); printk("<0>zzzzn"); release_mem_region(pci_resource_start(pdev,2),pci_resource_len(pdev, 2)); remove_proc_entry("trndrv", 0); } int init_module(void) { create_proc_fops_entry("trndrv", 0, NULL, NULL); pdev = pci_find_device(VENDORID, DEVICEID, NULL); if (pdev == NULL) { printk(KERN_EMERG "no pci card specifiedn"); return -PCIBIOS_DEVICE_NOT_FOUND; } pci_enable_device(pdev); if(check_mem_region(pci_resource_start(pdev,2),pci_resource_len(pdev ,2))) { printk("<0>check_mem_region already allocatedn"); } else printk("<0>check_mem_region success!n"); if(!request_mem_region(pci_resource_start(pdev,2),pci_resource_len(p dev,2),"gtw")) { printk("<0>request_mem_region failedn"); return -EBUSY; } printk("<0>request_mem_region success!n"); ptr = ioremap(pci_resource_start(pdev,2),pci_resource_len(pdev,2)); printk("<0>PTR:%04xn",ptr); return 0; } 用户程序读配置寄存器的内容: VID = 0x10b5 DID = 0x9050 COMMAND = 0x0003 STATUS = 0x0280 RID = 0x02 CLCD = 0x068000 CALN = 0x08 LAT = 0x00 HDR = 0x00 BIST = 0x00 BADR0 = 0xd9002000 BADR1 = 0x0000dc01 BADR2 = 0xd9000000 BADR3 = 0x00000000 BADR4 = 0x00000000 BADR5 = 0x00000000 EXROM = 0x00 INTLN = 0x09 INTPIN = 0x01 MINGNT = 0x00 MAXLAT = 0x00 在驱动程序中的init_modules用print打印出来的用ioremap映射到的内核的虚拟地址的ptr 值是TR:c88d8000 readb读出来的数据为全0,读了11个字节:00 00 00 00 00 00 00 00 00 00 00 |
|