zcy618
驱动牛犊
驱动牛犊
  • 注册日期2007-05-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:1388回复:0

9052linux的驱动开发中,关于从iomem地址上读数据问题请教!!

楼主#
更多 发布于:2007-08-31 16:28
我写了一个plx9052的linux驱动程序,写就先不去说它了,在从地址上读数据的时候总是不对,现在我先将部分我写的程序打印于下面,然后再说我遇到的具体问题:
/*
预定义所需变量
*/
#define plx_VendorID 0x10b5
#define plx_DeviceID 0x9050

unsigned int plx_major=0;
struct pci_dev *plx_dev=NULL;
/*
定义卡可用资源区域
*/
unsigned long base0start=0,base0len=0;
unsigned long base4start=0,base4len=0;

unsigned long offset=0,step=0;
unsigned long i=0;//测试用作计数
void *iomembase=NULL;
void *las4membase = NULL;


static struct pci_device_id PLX9052_pci_table[] = {

{0x10b5,0x5201,0x10b5,0x9050},
{0}

};



MODULE_DEVICE_TABLE(pci,PLX9052_pci_table);



static struct file_operations fops={

    .owner = THIS_MODULE,

    .open = device_open,
    .release = device_release,

    .read = device_read,

    .write = device_write,

};

********************************
********************************
********************************
                          *
省略部分无关程序
                          *
********************************
********************************

/*
主模块开始
*/
int pci_init_module(void)
{
    int result;
    unsigned long endsrc=0;
        

    result = register_chrdev(0,"plx_dev",&fops);
    
    if(result<0)
    {
        printk("pci-can : can't get major number");
        return result;
    }
    if(plx_major==0)
    {
        plx_major=result;
        printk("pci-can major number is %d!\n",plx_major);
    }
    printk("hello world!\n");
    /*
    开始查找卡
    */
    plx_dev=pci_find_device(plx_VendorID,plx_DeviceID,NULL);
    if(!plx_dev)
    {
        printk("no Card!\n");
        return -1;
    }
    else
    {
        printk("Found card!\n");
    }

    
    /*
    启用卡
    */
    pci_enable_device(plx_dev);


    /*
    查找卡资源
    */
    /*
    base 0
    */
    base0start=pci_resource_start(plx_dev,0);
    endsrc=pci_resource_end(plx_dev,0);
    base0len=endsrc-base0start;
    printk("PCI base 0 addr is 0x%lx,len is 0x%lx!\n",base0start,base0len);
    /*
    base 4
    */
    base4start=pci_resource_start(plx_dev,4);
    endsrc=pci_resource_end(plx_dev,4);
    base4len=endsrc-base4start;
    printk("PCI base 4 addr is 0x%lx,len is 0x%lx!\n",base4start,base4len);
    
    /*
    申请使用io内存
    */
//    request_mem_region(base4start,base4len,"plx_dev");
    /*
    映射io内存
    */
    iomembase=ioremap(base0start,base0len);
    las4membase = ioremap(base4start,base4len);

    if(iomembase==NULL)
    {
        printk("can't get iomem!\n");
    }
    else
    {
        printk("get iomem addr is 0x%lx!\n", (unsigned long)iomembase);
    }

    if(las4membase==NULL)
    {
        printk("can't get las0membase!\n");
    }
    else
    {
        printk("get las4membase addr is 0x%lx!\n", (unsigned long)las4membase);
    }

    /*
    测试获取数据base4
    */
    
    endsrc=inb(base4start+0x8);
    printk("base4start+0x8 : the data is 0x%lx!\n",endsrc);
    endsrc=0x11;
    printk("endsrc : the data is 0x%lx!\n",endsrc);
    printk("write endsrc into base4start+0x8 \n");
    outb(endsrc,base4start+0x8);
    endsrc=inb(base4start+0x8);
    printk("base4start+0x8 : the data is 0x%lx!\n",endsrc);
    endsrc=inb(base4start+0x8);
    printk("base4start+0x8 : the data is 0x%lx!\n",endsrc);
    endsrc=inb(base4start);
    printk("base4start the data is 0x%lx!\n",endsrc);

    endsrc=inl(base0start);
    printk("base0start the data is 0x%lx!\n",endsrc);
    
    /*
    测试获取数据base0
    */
    endsrc=ioread32(base0start);
    printk("base0start the data is 0x%lx!\n",endsrc);

    endsrc=readl(base0start);
    printk("base0start the data is 0x%lx!\n",endsrc);

    endsrc=ioread16(base0start);
    printk("base0start the data is 0x%lx!\n",endsrc);

    endsrc=ioread8(base0start);
    printk("base0start the data is 0x%lx!\n",endsrc);

    endsrc=ioread32(base0start+0x4);
    printk("base0start the data is 0x%lx!\n",endsrc);

    endsrc=ioread32(base4start);
    printk("base0start the data is 0x%lx!\n",endsrc);

    endsrc=ioread32(iomembase);
    printk("after ioremap base0start the data is 0x%lx!\n",endsrc);
    
    endsrc=ioread32(iomembase+0x4);
    printk("after ioremap base0start+0x4 the data is 0x%lx!\n",endsrc);

    endsrc=ioread32(las4membase);
    printk("after ioremap base4start the data is 0x%lx!\n",endsrc);

//    endsrc=ioread32(las4membase);
//    printk("after ioremap base4start the data is 0x%lx!\n",endsrc);

    return 0;
    }

大家可以看到,pci空间我使用的pci las0和las4,las0用于访问eeprom而las4对应的是8KX8的idt7005,而我在配置eeprom时将las0的大小设置成了0x7f,基地址设置为0xc0131000,las4的大小设置成了 0x1ffff,基地址设为0xc0100000,这些在我加载模块后输入dmesg查看系统消息后都是对的,可是从这些地址上读出的数据却怎么也对不上,查看系统消息如下:
pci-can major number is 253!
hello world!
Found card!
PCI: Enabling device 0000:02:01.0 (0000 -> 0003)
ACPI: PCI Interrupt 0000:02:01.0[A] -> GSI 17 (level, low) -> IRQ 225
PCI base 0 addr is 0xc0131000,len is 0x7f!
PCI base 4 addr is 0xc0100000,len is 0x1ffff!
get iomem addr is 0xe0836000!
get las4membase addr is 0xe0c40000!
base4start+0x8 : the data is 0x0!
endsrc : the data is 0x11!
write endsrc into base4start+0x8
base4start+0x8 : the data is 0x0!
base4start+0x8 : the data is 0x0!
base4start the data is 0x84!
base0start the data is 0xffffffff!
base0start the data is 0x81a4!
base0start the data is 0x81a4!
base0start the data is 0x81a4!
base0start the data is 0xa4!
base0start the data is 0x1f13!
base0start the data is 0x0!
after ioremap base0start the data is 0xff00000!
after ioremap base0start+0x4 the data is 0x0!
after ioremap base4start the data is 0x28724a5a!
在终端中输入cat /proc/iomem查看端口内存使用情况,如下:
[root@zcy ~]# cat /proc/iomem
00000000-0009f3ff : System RAM
  00000000-00000000 : Crash kernel
0009f400-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000f0000-000fffff : System ROM
00100000-1ffeffff : System RAM
  00400000-006168ba : Kernel code
  006168bb-006ef8cb : Kernel data
1fff0000-1fff2fff : ACPI Non-volatile Storage
1fff3000-1fffffff : ACPI Tables
30000000-300fffff : PCI Bus #01
  30000000-3001ffff : 0000:01:00.0
30100000-301fffff : PCI Bus #02
  30100000-3010ffff : 0000:02:01.0
  30110000-3011ffff : 0000:02:0d.0
80000000-9fffffff : PCI Bus #01
  80000000-8fffffff : 0000:01:00.0
  90000000-90ffffff : 0000:01:00.0
  91000000-91ffffff : 0000:01:00.0
a0000000-cfffffff : PCI Bus #02
  a0000000-afffffff : 0000:02:01.0
  b0000000-bfffffff : 0000:02:01.0
  c0000000-c00fffff : 0000:02:01.0
  c0100000-c011ffff : 0000:02:01.0
  c0130000-c01300ff : 0000:02:0d.0
    c0130000-c01300ff : 8139too
  c0131000-c013107f : 0000:02:01.0
d0000000-d00003ff : 0000:00:1d.7
  d0000000-d00003ff : ehci_hcd
d0001000-d00011ff : 0000:00:1e.2
  d0001000-d00011ff : Intel ICH6
d0002000-d00020ff : 0000:00:1e.2
  d0002000-d00020ff : Intel ICH6
e0000000-efffffff : reserved
fec00000-ffffffff : reserved
从上可以看到,地址分配还是正确的,就是从地址上读出的数据不对,从eeprom的首地址读出的数据是一个32bit的0x000081a4h,而eeprom的头4个地址上的数据是0x5201h和0x10b5h,无论用那个方法去读总是无法得到正确的数据,而我设置的las4是pci memory space,不是pci i/o space,而我用的pci las0本身就是memory空间。

所以,我在这里想请问一下各位高人,我现在遇到的这个问题是怎么回事?到底要如何解决?
游客

返回顶部