⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd-monitor.c

📁 linux嵌入式课程实践中的一个关于声卡驱动程序 。
💻 C
📖 第 1 页 / 共 2 页
字号:
    return rc;}#endif /* CONFIG_PM *//** * monitor_load * * Check status, load if required, set monitor status. */int monitor_load(void){    unsigned long flags;    printk(KERN_DEBUG"monitor_load: \n");    local_irq_save(flags);    switch(monitor.status) {    case MONITOR_UNKNOWN:    case MONITOR_UNLOADED:        monitor.status = MONITOR_LOADING;        local_irq_restore(flags);        monitor_hotplug(MHA_LOAD);        monitor.status = MONITOR_LOADED;        return 0;    case MONITOR_LOADING:    case MONITOR_UNLOADING:#ifdef CONFIG_PM    case MONITOR_SUSPENDING:    case MONITOR_SUSPENDED:    case MONITOR_RESTORING:#endif        // XXX we should wait for this        local_irq_restore(flags);        return -EINVAL;     case MONITOR_LOADED:        local_irq_restore(flags);        return 0;    default:        return -EINVAL;    }}/** * monitor_unload * * Check status, unload if required, set monitor status. */int monitor_unload(void){    unsigned long flags;    printk(KERN_DEBUG"monitor_unload: \n");    local_irq_save(flags);    switch(monitor.status) {    case MONITOR_UNKNOWN:    case MONITOR_UNLOADED:        local_irq_restore(flags);        return 0;    case MONITOR_LOADING:    case MONITOR_UNLOADING:#ifdef CONFIG_PM    case MONITOR_SUSPENDING:    case MONITOR_SUSPENDED:    case MONITOR_RESTORING:#endif        // XXX we should wait for this        local_irq_restore(flags);        return -EINVAL;     case MONITOR_LOADED:        monitor.status = MONITOR_UNLOADING;        local_irq_restore(flags);        monitor_hotplug(MHA_UNLOAD);        monitor.status = MONITOR_UNLOADED;        return 0;    default:        return -EINVAL;    }}/*** monitor_event - called from monitor interrupt handler */void monitor_event(void){    if (monitor_connected()) {        monitor_load();    }    else {        monitor_unload();#if !defined(CONFIG_SA1100_CONNECT_GPIO)         monitor_load();#endif    }}/** * monitor_bh -  * @ignored: * * Check connected status and load/unload as appropriate. */void monitor_bh(void *ignored){    printk(KERN_DEBUG "monitor_bh:\n");    monitor_event();    MOD_DEC_USE_COUNT;}/** * monitor_schedule_bh - */void monitor_schedule_bh(void) {    //printk(KERN_DEBUG "monitor_schedule_bh: schedule bh to %s\n", msg);    if (monitor.monitor_bh.sync) {        return;    }    MOD_INC_USE_COUNT;    if (!schedule_task(&monitor.monitor_bh)) {        printk(KERN_DEBUG "monitor_schedule_bh: failed\n");        MOD_DEC_USE_COUNT;    }}/** * monitor_int_hndlr - * @irq: * @dev_id: * @regs */void monitor_int_hndlr(int irq, void *dev_id, struct pt_regs *regs){    printk(KERN_DEBUG "\n");    printk(KERN_DEBUG "monitor_int_hndlr:\n");    monitor_schedule_bh();}#ifdef CONFIG_USBD_PROCFS/* Proc Filesystem *************************************************************************** *//* * * usbd_monitor_proc_read - implement proc file system read. * @file * @buf * @count * @pos * * Standard proc file system read function. */static ssize_tusbd_monitor_proc_read(struct file *file, char *buf, size_t count, loff_t * pos){    unsigned long   page;    int len = 0;    int index;    MOD_INC_USE_COUNT;    // get a page, max 4095 bytes of data...    if (!(page = get_free_page(GFP_KERNEL))) {        MOD_DEC_USE_COUNT;        return -ENOMEM;    }    len = 0;    index = (*pos)++;    if (index == 0) {        len += sprintf((char *)page+len, "usb-monitor status\n");    }    if (index==1) {        switch(monitor.status) {        case MONITOR_UNKNOWN:            len += sprintf((char *)page+len, "unknown\n");            break;        case MONITOR_UNLOADED:            len += sprintf((char *)page+len, "unloaded\n");            break;        case MONITOR_LOADING:            len += sprintf((char *)page+len, "loading\n");            break;        case MONITOR_UNLOADING:            len += sprintf((char *)page+len, "unloading\n");            break;#ifdef CONFIG_PM        case MONITOR_SUSPENDING:            len += sprintf((char *)page+len, "suspending\n");            break;        case MONITOR_SUSPENDED:            len += sprintf((char *)page+len, "suspended\n");            break;        case MONITOR_RESTORING:            len += sprintf((char *)page+len, "restoring\n");            break;#endif        case MONITOR_LOADED:            len += sprintf((char *)page+len, "loaded\n");            break;        default:            len += sprintf((char *)page+len, "?\n");        }    }    if (len > count) {        len = -EINVAL;    }    else if (len > 0 && copy_to_user(buf, (char *) page, len)) {        len = -EFAULT;    }    free_page(page);    MOD_DEC_USE_COUNT;    return len;}/* * * usbd_monitor_proc_write - implement proc file system write. * @file * @buf * @count * @pos * * Proc file system write function, used to signal monitor actions complete. * (Hotplug script (or whatever) writes to the file to signal the completion * of the script.)  An ugly hack. */static ssize_tusbd_monitor_proc_write(        struct file *file,        const char *buf,        size_t count,        loff_t * pos){    size_t n = count;    char c;    MOD_INC_USE_COUNT;    //printk(KERN_DEBUG "%s: count=%u\n",__FUNCTION__,count);    while (n > 0) {        // Not too efficient, but it shouldn't matter        if (copy_from_user(&c,buf+(count-n),1)) {            count = -EFAULT;            break;        }        n -= 1;        //printk(KERN_DEBUG "%s: %u/%u %02x\n",__FUNCTION__,count-n,count,c);    }    up(&hotplug_done);    MOD_DEC_USE_COUNT;    return(count);}static struct file_operations usbd_monitor_proc_operations_functions = {    read: usbd_monitor_proc_read,    write: usbd_monitor_proc_write,};#endif/* Module Init ******************************************************************************* *//** * monitor_modinit - commission bus interface driver * */static int __init monitor_modinit(void){    printk(KERN_INFO "usbdm: %s\n", __usbd_module_info);    // Initialize data structures _before_ installing interrupt handlers    monitor.status = MONITOR_UNKNOWN;    monitor.monitor_bh.routine = monitor_bh;    monitor.monitor_bh.data = NULL;    // XXX monitor.monitor_bh.sync = 0;    monitor.hotplug_bh.routine = hotplug_bh;    monitor.hotplug_bh.data = NULL;    // XXX monitor.hotplug_bh.sync = 0;    /*     * Architecture specific - request IRQ     */    if (!monitor_request_irq()) {        monitor.have_irq++;    }    else {        printk(KERN_DEBUG"usbdm: request irq failed\n");    }#ifdef CONFIG_PM    /*     * Architecture specific - register with power management     */    monitor.pm_info = NULL;    if (!(monitor.pm_info = pm_register(PM_USB_DEV, PM_SYS_UNKNOWN, monitor_pm_event))) {        printk(KERN_ERR "%s: couldn't register for power management\n", __FUNCTION__);        if (monitor.have_irq) {            free_irq(IRQ_GPIO12, &monitor);         }        return 1;    }    monitor.pm_info->state = 0;#endif#ifdef CONFIG_USBD_PROCFS    {        struct proc_dir_entry *p;        // create proc filesystem entries        if ((p = create_proc_entry("usb-monitor", 0, 0)) == NULL) {            if (monitor.have_irq) {    		monitor_free_irq();                monitor.have_irq = 0;            }#ifdef CONFIG_PM            if (monitor.pm_info) {                pm_unregister(monitor.pm_info);                monitor.pm_info = NULL;            }#endif            return -ENOMEM;	}        p->proc_fops = &usbd_monitor_proc_operations_functions;    }#endif    // Find out if the cable is connected     // and load USBD modules if we are.        monitor_event();    printk(KERN_INFO "monitor_modinit: finished\n");    return 0;}/** * monitor_modexit - decommission bus interface driver * */static void __exit monitor_modexit(void){    printk(KERN_INFO "\n");    printk(KERN_INFO "monitor_modexit:\n");    /* Stop any hotplug actions except unload */    monitor_exiting = 1;    /*     * Architecture specific - free appropriate IRQ     */    monitor_free_irq();#ifdef CONFIG_PM    if (monitor.pm_info) {        pm_unregister(monitor.pm_info);        monitor.pm_info = NULL;    }#endif    /*     * Force unloading     */    monitor_hotplug(MHA_UNLOAD);#ifdef CONFIG_USBD_PROCFS    // remove proc filesystem entry *AFTER* the last hotplug,    // in case it is being used for sync hotplug.    remove_proc_entry("usb-monitor", NULL);#endif    return;}module_init(monitor_modinit);module_exit(monitor_modexit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -