zhuchubo
驱动牛犊
驱动牛犊
  • 注册日期2004-06-22
  • 最后登录2005-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:778回复:0

求助:9052接口芯片驱动读数据的问题

楼主#
更多 发布于:2004-07-21 14:35
这个驱动能正确读取配置寄存器的内容,但是把基址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>odd\n");
  
                for(i=0;i<11;i++)
  
                {
  
                        regs=readb(ptr+0x10+i);
  
                        printk("<0>%02x ",regs);
  
                }
  
  
  
        }
  
        else
  
        {
  
                printk("<0>even\n");
  
                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 error\n");
  
            return result;
  
        }
  
    }
  
    return 0;
  
}
  
int readoperregs(u8 *regs)
  
{
  
    return 0;
  
}
  
void cleanup_module(void)
  
{
  
    iounmap((char*)ptr);
  
    printk("<0>zzzz\n");
  
    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 specified\n");
  
        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 allocated\n");
  
    }
  
    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 failed\n");
  
        return -EBUSY;
  
    }
  
  
  
    printk("<0>request_mem_region success!\n");
  
  
  
  
  
    ptr = ioremap(pci_resource_start(pdev,2),pci_resource_len(pdev,2));
  
  
  
    printk("<0>PTR:%04x\n",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
值是:PTR:c88d8000

readb读出来的数据为全0,读了11个字节:00 00 00 00 00 00 00 00 00 00 00
  
  
游客

返回顶部