尝试在/ dev中打开设备文件,然后我得到:open()失败,错误为[无此设备]

时间:2019-02-15 17:49:38

标签: linux-kernel driver system linux-device-driver device-driver

我正在尝试使用系统调用open在/ dev / devname中打开设备。 它返回-1,当我打印错误消息时,我得到open() failed with error [No such device]

当我尝试运行cat / dev / devname时,我也会得到No such device 下面是我对模块进行惰性化的代码

insmod devname.ko
major=`cat /proc/devices | awk '$2=="devname" { print $1 }'`
cp contec_smc.conf /proc/contec_smc.conf
mknod /dev/devname c $major 0
#end 

我的开发文件在/ dev中以/dev/devname000的形式提供,在/ proc / devices中也可以使用相同的名称 运动控制卡的实际硬件已插入计算机中

我正在使用内核版本4.15,模块代码如下

#include <linux/fs.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/pci.h>      
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/ioctl.h>
#ifndef LINUX_VERSION_CODE
#include <linux/version.h>
//#include <linux/proc_fs.h>
#include <linux/sched.h> 
#include <linux/uaccess.h> 
#endif

#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c)   ((a)<<16+(b)<<8+c)
#endif

// Kernel version 2.6.X
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,7,0))
#include <linux/moduleparam.h>
#endif
struct task_struct;
#include "Ccom_module.h"

static  CCOM_DEVICE_LIST    device_list;                // 
static  CCOM_RAW_FILE_DATA  raw_file_data;              // 
static  CCOM_TIMER_DATA     timer_data[CCOM_TIMER_MAX]; // 
static  int                 major = 0;                  
char *msg;
int len, temp;

// Kernel version 2.2.X - 2.4.X
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
MODULE_PARM(major, "h");
// Kernel version 2.6.X
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,7,0))
module_param(major, int, 0);
#endif

//================================================================
//
//================================================================
static int Ccom_sub_add_device(void);
static int Ccom_file_read_proc(struct file *filp, char *buf, size_t count, loff_t *offp);
static int Ccom_file_write_proc(struct file *filp,const char *buf,size_t count,loff_t *offp);

static struct file_operations proc_fops = {
        .owner = THIS_MODULE,
        .read =(ssize_t) Ccom_file_read_proc,
        .write =(ssize_t) Ccom_file_write_proc,


};


int init_module(void)
{
    int         ret;
    CCOM_ENTRY  entry;
    struct  proc_dir_entry  *proc_entry;
    int         tmp_major;
    //--------------------------------------

    //--------------------------------------
    //----------------------------------------
    // Kernel version 2.2.X - 2.4.X
    //----------------------------------------
    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
    EXPORT_NO_SYMBOLS;
    #endif
    //--------------------------------------

    //--------------------------------------
    ret = Ccom_register_entry(&entry);
    if (ret != 0) {
        return ret;
    }
    //--------------------------------------

    //--------------------------------------

    device_list.entry.major = 0;

    device_list.entry.fops.open     = Ccom_open;
    device_list.entry.fops.release  = Ccom_close;
    //device_list.entry.fops.unlocked_ioctl = Ccom_ioctl;
    strcpy(device_list.entry.name   , entry.name);              // 
    device_list.entry.add_device    = entry.add_device;         // 
    device_list.entry.delete_device = entry.delete_device;      // 
    device_list.entry.open          = entry.open;               // 
    device_list.entry.close         = entry.close;              // 
    device_list.entry.dispatch      = entry.dispatch;           // 
    //--------------------------------------

    //--------------------------------------
    strcpy(raw_file_data.file_name  , entry.file_name);         // 
    //--------------------------------------

    //--------------------------------------
    if (strlen(device_list.entry.name) == 0 ||
        strlen(raw_file_data.file_name) == 0) {
        return -ENODEV;
    }
    //--------------------------------------

    //--------------------------------------
    tmp_major = register_chrdev(major, device_list.entry.name, &device_list.entry.fops);
    if (tmp_major < 0) {
        return tmp_major;
    }
    if (major == 0) {
        device_list.entry.major = tmp_major;
    } else {
        device_list.entry.major = major;
    }
    //--------------------------------------
    //
    //--------------------------------------

    //proc_entry = proc_create(raw_file_data.file_name, 0, NULL, &proc_fops);
    proc_create("contec_smc.conf",0,NULL,&proc_fops);
    msg=kmalloc(10000*sizeof(char), GFP_KERNEL);

    return 0;
}

int Ccom_open(struct inode *inode, struct file *file)
{
    int     major, minor;
    int     i;
    int     iret;
    //--------------------------------------

    //--------------------------------------
    major = MAJOR(inode->i_rdev);
    minor = MINOR(inode->i_rdev);
    //--------------------------------------
    //--------------------------------------
    if (major != device_list.entry.major) {
        return -ENODEV;
    }
    //--------------------------------------
    //--------------------------------------
    for (i=0; i<device_list.device_num; i++) {
        if (minor == device_list.device[i].minor) {
            //--------------------------------------
            //--------------------------------------
            if (device_list.entry.open != NULL) {
                iret = device_list.entry.open(device_list.device[i].device_data);
            }
            //--------------------------------------
            //--------------------------------------
            //----------------------------------------
            // Kernel version 2.2.X - 2.4.X
            //----------------------------------------
    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
            MOD_INC_USE_COUNT;
            //----------------------------------------
            // Kernel version 2.6.X
            //----------------------------------------
    #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,7,0))
            try_module_get(THIS_MODULE);
    #endif
            return 0;
        }
    }
    return -ENODEV;
}
//================================================================

//================================================================
int Ccom_close(struct inode *inode, struct file *file)
{
    int     major, minor;
    int     i;
    int     iret;
    //--------------------------------------

    //--------------------------------------
    major = MAJOR(inode->i_rdev);
    minor = MINOR(inode->i_rdev);
    //--------------------------------------

    //--------------------------------------
    if (major != device_list.entry.major) {
        return -ENODEV;
    }
    //--------------------------------------
    // 
    //--------------------------------------
    for (i=0; i<device_list.device_num; i++) {
        if (minor == device_list.device[i].minor) {
            //--------------------------------------
            //
            //--------------------------------------
            if (device_list.entry.close != NULL) {
                iret = device_list.entry.close(device_list.device[i].device_data);
            }
            //--------------------------------------
            // 
            //--------------------------------------
            //----------------------------------------
            // Kernel version 2.2.X - 2.4.X
            //----------------------------------------
    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
            MOD_DEC_USE_COUNT;
            //----------------------------------------
            // Kernel version 2.6.X
            //----------------------------------------
    #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,7,0))
            module_put(THIS_MODULE);
    #endif
            return 0;
        }
    }
    return -ENODEV;
}
//================================================================
// 
//================================================================
int Ccom_ioctl(struct inode *inode, struct file *file, unsigned int ctl_code, unsigned long param)
{
    int     major, minor;
    int     i;
    int     iret;

    major = MAJOR(inode->i_rdev);
    minor = MINOR(inode->i_rdev);

    if (major != device_list.entry.major) {
        return -ENODEV;
    }
    //--------------------------------------

    //--------------------------------------
    for (i=0; i<device_list.device_num; i++) {
        if (minor == device_list.device[i].minor) {

            iret = 0;
            if (device_list.entry.dispatch != NULL) {
                iret = device_list.entry.dispatch(device_list.device[i].device_data, ctl_code, (void *)param);
            }

            if (iret != 0) {
                return -EINVAL;
            }
            return 0;
        }
    }
    return -ENODEV;
}

 void Ccom_disconnect_interrupt(PCCOM_ISR_OBJ pisr)
{
    if (pisr == NULL || pisr->flag != 1) {
        return;
    }

    free_irq((short)(pisr->irq & 0xffff), pisr);
}

void *Ccom_alloc_mem(unsigned int size)
{
    return kmalloc(size, GFP_KERNEL);
}



//========================================================================
void *Ccom_alloc_pages(int priority, unsigned int size)
{
    unsigned long page_log;
    //--------------------------------------
    // Kernel version 2.2.X
    //--------------------------------------
 //#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
    //---------------------------
    //---------------------------
    size = (size-1) >> (PAGE_SHIFT-1);
    page_log = -1;
    do{
        size >>= 1;
        page_log++;
    }while(size);
    //--------------------------------------

    return (void *)__get_free_pages(priority, page_log);
}

//========================================================================

//========================================================================
void Ccom_free_pages(unsigned long addr, unsigned int size)
{
    unsigned long page_log;
    //--------------------------------------
    // Kernel version 2.2.X
    //--------------------------------------
 //#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
    //---------------------------

    //---------------------------
    size = (size-1) >> (PAGE_SHIFT-1);
    page_log = -1;
    do {
        size >>= 1;
        page_log++;
    } while (size);
    //--------------------------------------
    // Kernel version 2.4.X-
    //--------------------------------------
//#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,7,0))
    page_log = get_order(size);
//#endif
    //---------------------------

    //---------------------------
    free_pages(addr, page_log);
}


void Ccom_sleep_on_timeout(long msecs)
{
    long            resolution;
    long            timeout;
    //--------------------------------------
    // jiffies�η׻�
    //--------------------------------------
    resolution  = 1000 / HZ;            //  1000=1sec
    timeout     = msecs / resolution;

    if(msecs % resolution){
        timeout++;
    }
    //----------------------------------------

    //----------------------------------------
//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
    current->state = TASK_INTERRUPTIBLE;
//#else
    //----------------------------------------
    //----------------------------------------
    set_current_state(TASK_INTERRUPTIBLE);
//#endif
    //--------------------------------------
    //--------------------------------------
    schedule_timeout(timeout);
}

static void Ccom_timer(unsigned long param)
{
    PCCOM_TIMER_DATA    ptimer = (PCCOM_TIMER_DATA)param;
    //--------------------------------------

    //--------------------------------------
    if (ptimer->initialized == CCOM_TIMER_NOT_STARTED) {
        return;
    }
    //--------------------------------------

    //--------------------------------------
    if (ptimer->func != NULL) {
        ptimer->func(ptimer->data);
    }
    //--------------------------------------

    //--------------------------------------
    ptimer->tm.expires = jiffies + (ptimer->tim * HZ / 1000);
    add_timer(&ptimer->tm);
}
//================================================================

//================================================================
long Ccom_set_timer(unsigned int timer_id, unsigned long tim, void (*func)(void *), void *param)
{
    PCCOM_TIMER_DATA    ptimer;
    //--------------------------------------

    //--------------------------------------
    if (timer_id >= CCOM_TIMER_MAX) {
        return CCOM_ERROR_TIMER_ID;
    }
    if (func == NULL) {
        return CCOM_ERROR_PARAM;
    }
    if ((tim * HZ / 1000) == 0) {
        return CCOM_ERROR_PARAM;
    }
    //--------------------------------------

    //--------------------------------------
    ptimer = &timer_data[timer_id];
    ptimer->func = func;
    ptimer->tim = tim;
    ptimer->data = param;
    //--------------------------------------

    //--------------------------------------
    if (ptimer->initialized == CCOM_TIMER_NOT_INITIALIZED) {
        //init_timer(&ptimer->tm);
    }

    //--------------------------------------
    //--------------------------------------
    if (ptimer->initialized == CCOM_TIMER_MOVING) {
        return CCOM_NO_ERROR;
    }
    //--------------------------------------

    //--------------------------------------
    ptimer->initialized = CCOM_TIMER_MOVING;
    timer_data[timer_id].tm.expires = jiffies + (tim * HZ /1000);
    add_timer(&ptimer->tm);
    return CCOM_NO_ERROR;
}

void Ccom_kill_timer(unsigned int timer_id)
{

    if (timer_id >= CCOM_TIMER_MAX) {
        return;
    }
    //--------------------------------------

    //--------------------------------------
    if (timer_data[timer_id].initialized == CCOM_TIMER_MOVING) {
        timer_data[timer_id].initialized = CCOM_TIMER_NOT_STARTED;
    }
}


static int Ccom_file_read_proc(struct file *filp, char *buf, size_t count, loff_t *offp)
{
    if(count>temp)
    {
        count=temp;
    }
    temp=temp-count;
    copy_to_user(buf,msg, count);
    if(count==0)
    temp=len;

    return count;
}


static int Ccom_file_write_proc(struct file *filp,const char *buf,size_t count,loff_t *offp)
{
    copy_from_user(msg,buf,count);
    len=count;
    temp=len;
    return count;
}//does

int Ccom_sub_add_device(void)
{
    int             i;
    unsigned long   ul;
    char            line_data[256];
    int             line_pos;
    char            *file_data;
    char            value_name[CCOM_FILE_VALUE_NAME_LEN];
    char            str[CCOM_FILE_VALUE_LEN];
    unsigned long   num;
    short           type;
    unsigned long   file_len;
    int             st;
    int             value_num;
    int             key_num;
    long            lret;
    int             itype;
    static  CCOM_FILE_DATA  com_file_data;
    PCCOM_FILE_DATA ptmp;
    char            device_name[CCOM_DEVICE_NAME_MAX];
    char            file_node[CCOM_FILE_NODE_NAME_MAX];
    long            minor;
    int             len;
    int             iret = 0;
    //--------------------------------------

    //--------------------------------------
    for (i=0; i<device_list.device_num; i++) {
        //--------------------------------------

        //--------------------------------------
        if (device_list.entry.delete_device != NULL) {
            device_list.entry.delete_device(device_list.device[i].device_data);
        }
        device_list.device[i].device_data = NULL;
        //--------------------------------------
        //-------------------------------------
        if (device_list.device[i].file_data != NULL) {
            kfree(device_list.device[i].file_data);
            device_list.device[i].file_data = NULL;
        }
    }
    device_list.device_num = 0;
    //--------------------------------------

    //--------------------------------------
    file_data = &raw_file_data.file_data[0];
    file_len = raw_file_data.file_len;
    line_pos = 0;   // 
    value_num = 0;  // 
    key_num = 0;    // 
    memset(&com_file_data, 0, sizeof(com_file_data));

    com_file_data.key_num = 1;
    for (ul=0; ul<file_len; ul++) {
        //--------------------------------------

        //--------------------------------------
        if (file_data[ul] == '\n') {
            line_data[line_pos] = '\0';
            //--------------------------------------

            //--------------------------------------
            switch (line_data[0]) {
            case '#':       

                break;
            case '{':       
                key_num = 0;
                value_num = 0;
                break;
            case '}':       

                ptmp = kmalloc(sizeof(com_file_data), GFP_KERNEL);
                if (ptmp == NULL) {
                    goto end_loop;
                }
                // 
                memcpy(ptmp, &com_file_data, sizeof(com_file_data));

                device_list.device[device_list.device_num].file_data = ptmp;
                device_list.device_num++;
                value_num = 0;  //
                key_num = 0;
                memset(&com_file_data, 0, sizeof(com_file_data));
                com_file_data.key_num = 1;
                break;
            case '[':       // 
                //
                if (com_file_data.key_num >= CCOM_FILE_MAX_KEY) {
                    break;
                }
                //
                for (i=1; strlen(line_data); i++) {
                    if (line_data[i] == ']') {
                        line_data[i] = '\0';
                        break;
                    }
                }
                //
                key_num++;
                com_file_data.key_num++;
                value_num = 0;  // 
                strcpy(com_file_data.key_data[key_num].key, &line_data[1]);
                break;
            default:        // 
                // 
                if (value_num >= CCOM_FILE_MAX_VALUE) {
                    break;
                }
                // 
                type = CCOM_FILE_VALUE_TYPE_NUM;
                num = 0;
                strcpy(value_name, "");
                strcpy(str, "");
                st = 0;
                len = strlen(line_data);
                // 
                for (i=st; i<len; i++) {
                    if (line_data[i] == ':') {
                        line_data[i] = '\0';
                        strcpy(value_name, &line_data[st]);
                        st = i+1;
                        break;
                    }
                }

                for (i=st; i<len; i++) {
                    if (line_data[i] == ':') {
                        line_data[i] = '\0';
                        if (strcmp(&line_data[st], "String") == 0 ||
                            strcmp(&line_data[st], "string") == 0) {
                            type = CCOM_FILE_VALUE_TYPE_STR;
                        }
                        st = i+1;
                        break;
                    }
                }
                // 
                strcpy(str, &line_data[st]);
                // 
                if ((str[0] == '0' && str[1] == 'x') ||
                    (str[0] == '0' && str[1] == 'X')) {
                    num = Ccom_str_to_hex(&str[2]);
                }
                // 
                else {
                    num = Ccom_str_to_dec(str);
                }
                //
                com_file_data.key_data[key_num].value_data[value_num].type = type;
                //com_file_data.key_data[key_num].value_data[value_num].num = num;
                strcpy(com_file_data.key_data[key_num].value_data[value_num].value_name, value_name);
                strcpy(com_file_data.key_data[key_num].value_data[value_num].str, str);
                value_num++;
                com_file_data.key_data[key_num].value_num++;
                break;
            }
            //--------------------------------------
            //
            //--------------------------------------
            line_pos = 0;
        }
        //--------------------------------------
        // 
        //--------------------------------------
        else {
            line_data[line_pos] = file_data[ul];
            line_pos++;
        }
    }
end_loop:
    //--------------------------------------
    // 
    //
    //--------------------------------------
    for (i=0; i<device_list.device_num; i++) {
        ptmp = device_list.device[i].file_data;
        //
        lret = Ccom_read_value(ptmp, "", "DeviceName", &itype, (void *)device_name);
        if (lret != 0) {
            continue;
        }
        strcpy(device_list.device[i].device_name, device_name);
        // 
        lret = Ccom_read_value(ptmp, "", "FileNode",   &itype, (void *)file_node);
        if (lret != 0) {
            continue;
        }
        strcpy(device_list.device[i].file_node, file_node);
        //
        lret = Ccom_read_value(ptmp, "", "Minor",      &itype, (void *)&minor);
        if (lret != 0) {
            continue;
        }
        device_list.device[i].minor = (int)minor;
        //
        if (device_list.entry.add_device) {
            iret = device_list.entry.add_device(&device_list.device[i].device_data, ptmp);
            if (iret != 0) {
                return iret;
            }
        }
    }
    return iret;
}
//================================================================
//
//================================================================
long Ccom_read_value(PCCOM_FILE_DATA fdata, char *key, char *value_name, int *type, void *value)
{
    int     i, j;
    long    lret;
    //--------------------------------------
    // 
    //--------------------------------------
    if (fdata == NULL ||
        key == NULL ||
        value_name == NULL ||
        type == NULL ||
        value == NULL) {
        return CCOM_ERROR_PARAM;
    }
    //--------------------------------------

    //--------------------------------------
    lret = CCOM_ERROR_NO_KEY;
    for (i=0; i<fdata->key_num; i++) {
        //--------------------------------------
        // 
        //--------------------------------------
        if (strcmp(fdata->key_data[i].key, key) != 0) {
            continue;
        }
        //--------------------------------------
        //
        //--------------------------------------
        lret = CCOM_ERROR_NO_VALUE;
        //--------------------------------------
        // 
        //--------------------------------------
        for (j=0; j<fdata->key_data[i].value_num; j++) {
            //--------------------------------------

            //--------------------------------------
            if (strcmp(fdata->key_data[i].value_data[j].value_name, value_name) == 0) {
                *type = fdata->key_data[i].value_data[j].type;
                if (*type == CCOM_FILE_VALUE_TYPE_NUM) {
                    *(unsigned long *)value = fdata->key_data[i].value_data[j].num;
                } else {
                    strcpy((char *)value, fdata->key_data[i].value_data[j].str);
                }
                return CCOM_NO_ERROR;
            }
        }
    }
    return lret;
}

//================================================================
// 
//================================================================
long Ccom_enum_key(PCCOM_FILE_DATA fdata, int index, char *key)
{
    //--------------------------------------
    //
    //--------------------------------------
    if (fdata == NULL ||
        key == NULL) {
        return CCOM_ERROR_PARAM;
    }
    if (index >= fdata->key_num) {
        return CCOM_ERROR_NO_KEY;
    }
    //--------------------------------------
    //
    //--------------------------------------
    strcpy(key, fdata->key_data[index].key);
    return CCOM_NO_ERROR;
}
//================================================================

//================================================================
PCCOM_FILE_DATA Ccom_get_file_ptr(void *device_ext)
{
    int     i;
    //--------------------------------------
    // 
    //--------------------------------------
    if (device_ext == NULL) {
        return NULL;
    }
    //--------------------------------------
    // 
    //--------------------------------------
    for (i=0; i<device_list.device_num; i++) {
        //--------------------------------------
        // 
        //--------------------------------------
        if (device_ext == device_list.device[i].device_data) {
            return device_list.device[i].file_data;
        }
    }
    return NULL;
}

//================================================================
// PCI
//================================================================
 long Ccom_get_pci_resource(
    unsigned short vendor_id,
    unsigned short device_id,
    unsigned short board_id,
    unsigned long *io_addr,
    unsigned long *io_num,
    unsigned long *mem_addr,
    unsigned long *mem_num,
    unsigned long *irq)

{
    struct pci_dev  *ppci_dev = NULL;
    unsigned char   revision;
    unsigned char   irq_pin;
    int             found_num;
    unsigned long   io_tmp[6];
    unsigned long   io_num_tmp;
    unsigned long   mem_tmp[6];
    unsigned long   mem_num_tmp;
    unsigned long   irq_tmp;
    unsigned long   i;

    //----------------------------------------
    // 
    //----------------------------------------
    //----------------------------------------
    // Kernel version 2.2.X - 2.4.X
    //----------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
    if (!pci_present()) {
        return CCOM_ERROR_NO_BOARD;
    }
#endif
    //----------------------------------------
    // 
    //----------------------------------------
    if (io_addr == NULL || *io_num < 6) {
        return CCOM_ERROR_ARRY_SIZE;
    }
    if (mem_addr == NULL || *mem_num < 6) {
        return CCOM_ERROR_ARRY_SIZE;
    }
    if (irq == NULL) {
        return CCOM_ERROR_ARRY_SIZE;
    }
    //----------------------------------------

    //----------------------------------------
    *io_num = 0;
    *mem_num = 0;
    *irq = 0xffffffff;
    //----------------------------------------

    //----------------------------------------
    io_num_tmp = 0;
    mem_num_tmp = 0;
    irq_tmp = 0xffffffff;
    found_num = 0;
    //----------------------------------------
    // 
    //----------------------------------------
    while ((ppci_dev = pci_get_device(vendor_id, device_id, ppci_dev))) {
        //----------------------------------------
        //
        //----------------------------------------
        if (!(ppci_dev->vendor == vendor_id && ppci_dev->device == device_id)) {
            continue;
        }
        //----------------------------------------
        // 
        //----------------------------------------
        pci_read_config_byte(ppci_dev,PCI_REVISION_ID,&revision);
        if (revision != board_id) {
            continue;
        }
        //----------------------------------------
        // 
        //----------------------------------------
        found_num++;
        io_num_tmp = 0;
        mem_num_tmp = 0;
        irq_tmp = 0xffffffff;
        //----------------------------------------
        // I
        //----------------------------------------
        for (i=0; i<6 ;i++) {
            //----------------------------------------
            // 
            //----------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,7,0))
            if (!pci_resource_start(ppci_dev, i)) {
                break;
            }
            if (pci_resource_flags(ppci_dev, i) & IORESOURCE_IO) {
                io_tmp[io_num_tmp] = pci_resource_start(ppci_dev, i);
                io_num_tmp++;
            } else {
                mem_tmp[mem_num_tmp] = pci_resource_start(ppci_dev, i) & PCI_BASE_ADDRESS_MEM_MASK;
                mem_num_tmp++;
            }
#endif
            //----------------------------------------
            // 
            //----------------------------------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
            if ( ppci_dev->base_address[i] & PCI_BASE_ADDRESS_SPACE_IO) {
                io_tmp[io_num_tmp] = ppci_dev->base_address[i] & PCI_BASE_ADDRESS_IO_MASK;
                io_num_tmp++;
            } else if ( ppci_dev->base_address[i] & PCI_BASE_ADDRESS_SPACE_MEMORY) {
                mem_tmp[mem_num_tmp] =  ppci_dev->base_address[i] & PCI_BASE_ADDRESS_MEM_MASK;
                mem_num_tmp++;
            }
#endif
        }
        //----------------------------------------
        // 
        //----------------------------------------
        pci_read_config_byte(ppci_dev, PCI_INTERRUPT_PIN, &irq_pin);
        if (irq_pin != 0 && ppci_dev->irq != 0) {
            irq_tmp = ppci_dev->irq;
        }
    }
    //----------------------------------------
    // 
    //----------------------------------------
    if (found_num == 0) {
        return CCOM_ERROR_NO_BOARD;
    }
    if (found_num > 1) {
        return CCOM_ERROR_BOARDID;
    }
    //----------------------------------------
    // 
    //----------------------------------------
    for (i=0; i<io_num_tmp; i++) {
        io_addr[i] = io_tmp[i];
    }
    *io_num = io_num_tmp;
    for (i=0; i<mem_num_tmp; i++) {
        mem_addr[i] = mem_tmp[i];
    }
    *mem_num = mem_num_tmp;
    *irq = irq_tmp;
    return CCOM_NO_ERROR;
}

long Ccom_report_io(unsigned long port, unsigned long range, char *name)
{
    //--------------------------------------
    // 
    //--------------------------------------
    if (name == NULL) {
        return CCOM_ERROR_PARAM;
    }
    //--------------------------------------

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
    if (check_region(port, range) < 0) {
        return CCOM_ERROR_IO_ADDRESS;
    }
#endif
    //--------------------------------------

    //--------------------------------------
    request_region(port, range, name);
    return CCOM_NO_ERROR;
}
//================================================================

//================================================================
long Ccom_unreport_io(unsigned long port, unsigned long range)
{
    release_region(port, range);
    return CCOM_NO_ERROR;

}


0 个答案:

没有答案