分享

Chapter 7. PCI Devices

 迎风初开 2014-02-05

Chapter 7. PCI Devices

The Linux pci interface provides a mechanism to access the PCI bus address spaces from user programs.

Performing programmed I/O on pci devices on SGI Linux systems involves the following steps:

  1. Examine /proc/bus/pci/devices and obtain offsets for the base address registers (BARs) of the devices that you want to map. The format of the lines is as follows (with field widths in the number of hexadecimal characters shown, and line breaks added for readability):

    bus:2x (slotnumber<<3_|_fn):2x vend:8x bar0 bar1 bar2 bar3 ...

    For example:

    if ((fptr = fopen( "/proc/bus/pci/devices", "r")) == NULL) {
                    printf( "Unable to open /proc/bus/pci/devices\n" );
            }
    
            while(fgets(buf, sizeof(buf) - 1, fptr)) {
                    sscanf( buf, "%2x%2x %8x %*x %lx %lx %lx %lx %lx %lx %lx %lx %*lx %*lx %*lx %*lx %*lx %*lx",
                    &sbus, &sdevfn, &svend, &sbar[0], &sbar[1], &sbar[2], &sbar[3],
                    &sbar[4], &sbar[5], &sbar[6], &sbar[7]);
                    if(( sbus == bus ) && (sdevfn == devfn)) {
                            /* This is the bus, slot and function we're looking for, 
                             * so save the base address register offset information.  */
                            for(int i=0; i> 16;
                            device = svend & 0xffff;
                    }
            }
            fclose( fptr );

  2. Open the appropriate device file for the bus, slot, and function in which you are interested. The device files are named as follows:

    /proc/bus/pci/bus/slot.function

    For example:

    memfile = (char*) malloc( 32 );
            sprintf( memfile, "/proc/bus/pci/%02d/%02d.%d", bus, slot, function );
            fd = open( memfile, O_RDWR );

  3. Set the memory map state for the file to MEM space using the PCIIOC_MMAP_IS_MEM request to the ioctl() system call.

    For example:

    ioctl(fd, PCIIOC_MMAP_IS_MEM);

  4. Map the opened file, using the offset obtained in step 1 as the offset parameter.

    For example:

    tmpPtr = (char *) mmap( NULL, (size_t) len, PROT_READ | PROT_WRITE,
                    MAP_SHARED, fd, (off_t) offset[bar]);

For a complete example, see Appendix D, “Reading MAC Addresses Sample Program”.

For details about kernel-level PCI device drivers, see the Linux Device Driver Programmer's Guide-Porting to SGI Altix Systems,

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多