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

📄 u132-hcd.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 5 页
字号:
                up(&u132->scheduler_lock);                u132_hcd_giveback_urb(u132, endp, urb, -EINTR);                return;        } else if (u132->going > 0) {                dev_err(&u132->platform_dev->dev, "device is being removed urb="                        "%p status=%d\n", urb, urb->status);                up(&u132->scheduler_lock);                u132_hcd_giveback_urb(u132, endp, urb, -ENODEV);                return;        } else if (urb->status == -EINPROGRESS) {                int retval;                struct u132_ring *ring = endp->ring;                up(&u132->scheduler_lock);                retval = usb_ftdi_elan_edset_input(u132->platform_dev,                        ring->number, endp, urb, address, endp->usb_endp, 0,                        u132_hcd_initial_input_recv);                if (retval == 0) {                } else                        u132_hcd_giveback_urb(u132, endp, urb, retval);                return;        } else {                dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu"                        "s=%d\n", urb, urb->status);                up(&u132->scheduler_lock);                u132_hcd_giveback_urb(u132, endp, urb, urb->status);                return;        }}/** this work function is only executed from the work queue**/static void u132_hcd_ring_work_scheduler(struct work_struct *work){        struct u132_ring *ring =		container_of(work, struct u132_ring, scheduler.work);        struct u132 *u132 = ring->u132;        down(&u132->scheduler_lock);        if (ring->in_use) {                up(&u132->scheduler_lock);                u132_ring_put_kref(u132, ring);                return;        } else if (ring->curr_endp) {                struct u132_endp *last_endp = ring->curr_endp;                struct list_head *scan;                struct list_head *head = &last_endp->endp_ring;                unsigned long wakeup = 0;                list_for_each(scan, head) {                        struct u132_endp *endp = list_entry(scan,                                struct u132_endp, endp_ring);                        if (endp->queue_next == endp->queue_last) {                        } else if ((endp->delayed == 0)                                || time_after_eq(jiffies, endp->jiffies)) {                                ring->curr_endp = endp;                                u132_endp_cancel_work(u132, last_endp);                                u132_endp_queue_work(u132, last_endp, 0);                                up(&u132->scheduler_lock);                                u132_ring_put_kref(u132, ring);                                return;                        } else {                                unsigned long delta = endp->jiffies - jiffies;                                if (delta > wakeup)                                        wakeup = delta;                        }                }                if (last_endp->queue_next == last_endp->queue_last) {                } else if ((last_endp->delayed == 0) || time_after_eq(jiffies,                        last_endp->jiffies)) {                        u132_endp_cancel_work(u132, last_endp);                        u132_endp_queue_work(u132, last_endp, 0);                        up(&u132->scheduler_lock);                        u132_ring_put_kref(u132, ring);                        return;                } else {                        unsigned long delta = last_endp->jiffies - jiffies;                        if (delta > wakeup)                                wakeup = delta;                }                if (wakeup > 0) {                        u132_ring_requeue_work(u132, ring, wakeup);                        up(&u132->scheduler_lock);                        return;                } else {                        up(&u132->scheduler_lock);                        u132_ring_put_kref(u132, ring);                        return;                }        } else {                up(&u132->scheduler_lock);                u132_ring_put_kref(u132, ring);                return;        }}static void u132_hcd_endp_work_scheduler(struct work_struct *work){        struct u132_ring *ring;        struct u132_endp *endp =		container_of(work, struct u132_endp, scheduler.work);        struct u132 *u132 = endp->u132;        down(&u132->scheduler_lock);        ring = endp->ring;        if (endp->edset_flush) {                endp->edset_flush = 0;                if (endp->dequeueing)                        usb_ftdi_elan_edset_flush(u132->platform_dev,                                ring->number, endp);                up(&u132->scheduler_lock);                u132_endp_put_kref(u132, endp);                return;        } else if (endp->active) {                up(&u132->scheduler_lock);                u132_endp_put_kref(u132, endp);                return;        } else if (ring->in_use) {                up(&u132->scheduler_lock);                u132_endp_put_kref(u132, endp);                return;        } else if (endp->queue_next == endp->queue_last) {                up(&u132->scheduler_lock);                u132_endp_put_kref(u132, endp);                return;        } else if (endp->pipetype == PIPE_INTERRUPT) {                u8 address = u132->addr[endp->usb_addr].address;                if (ring->in_use) {                        up(&u132->scheduler_lock);                        u132_endp_put_kref(u132, endp);                        return;                } else {                        int retval;                        struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &                                endp->queue_next];                        endp->active = 1;                        ring->curr_endp = endp;                        ring->in_use = 1;                        up(&u132->scheduler_lock);                        retval = edset_single(u132, ring, endp, urb, address,                                endp->toggle_bits, u132_hcd_interrupt_recv);                        if (retval == 0) {                        } else                                u132_hcd_giveback_urb(u132, endp, urb, retval);                        return;                }        } else if (endp->pipetype == PIPE_CONTROL) {                u8 address = u132->addr[endp->usb_addr].address;                if (ring->in_use) {                        up(&u132->scheduler_lock);                        u132_endp_put_kref(u132, endp);                        return;                } else if (address == 0) {                        int retval;                        struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &                                endp->queue_next];                        endp->active = 1;                        ring->curr_endp = endp;                        ring->in_use = 1;                        up(&u132->scheduler_lock);                        retval = edset_setup(u132, ring, endp, urb, address,                                0x2, u132_hcd_initial_setup_sent);                        if (retval == 0) {                        } else                                u132_hcd_giveback_urb(u132, endp, urb, retval);                        return;                } else if (endp->usb_addr == 0) {                        int retval;                        struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &                                endp->queue_next];                        endp->active = 1;                        ring->curr_endp = endp;                        ring->in_use = 1;                        up(&u132->scheduler_lock);                        retval = edset_setup(u132, ring, endp, urb, 0, 0x2,                                u132_hcd_enumeration_address_sent);                        if (retval == 0) {                        } else                                u132_hcd_giveback_urb(u132, endp, urb, retval);                        return;                } else {                        int retval;                        u8 address = u132->addr[endp->usb_addr].address;                        struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK &                                endp->queue_next];                        endp->active = 1;                        ring->curr_endp = endp;                        ring->in_use = 1;                        up(&u132->scheduler_lock);                        retval = edset_setup(u132, ring, endp, urb, address,                                0x2, u132_hcd_configure_setup_sent);                        if (retval == 0) {                        } else                                u132_hcd_giveback_urb(u132, endp, urb, retval);                        return;                }        } else {                if (endp->input) {                        u8 address = u132->addr[endp->usb_addr].address;                        if (ring->in_use) {                                up(&u132->scheduler_lock);                                u132_endp_put_kref(u132, endp);                                return;                        } else {                                int retval;                                struct urb *urb = endp->urb_list[                                        ENDP_QUEUE_MASK & endp->queue_next];                                endp->active = 1;                                ring->curr_endp = endp;                                ring->in_use = 1;                                up(&u132->scheduler_lock);                                retval = edset_input(u132, ring, endp, urb,                                        address, endp->toggle_bits,                                        u132_hcd_bulk_input_recv);                                if (retval == 0) {                                } else                                        u132_hcd_giveback_urb(u132, endp, urb,                                                retval);                                return;                        }                } else {        /* output pipe */                        u8 address = u132->addr[endp->usb_addr].address;                        if (ring->in_use) {                                up(&u132->scheduler_lock);                                u132_endp_put_kref(u132, endp);                                return;                        } else {                                int retval;                                struct urb *urb = endp->urb_list[                                        ENDP_QUEUE_MASK & endp->queue_next];                                endp->active = 1;                                ring->curr_endp = endp;                                ring->in_use = 1;                                up(&u132->scheduler_lock);                                retval = edset_output(u132, ring, endp, urb,                                        address, endp->toggle_bits,                                        u132_hcd_bulk_output_sent);                                if (retval == 0) {                                } else                                        u132_hcd_giveback_urb(u132, endp, urb,                                                retval);                                return;                        }                }        }}static void port_power(struct u132 *u132, int pn, int is_on){        u132->port[pn].power = is_on;}static void u132_power(struct u132 *u132, int is_on){        struct usb_hcd *hcd = u132_to_hcd(u132)                ;        /* hub is inactive unless the port is powered */        if (is_on) {                if (u132->power)                        return;                u132->power = 1;                hcd->self.controller->power.power_state = PMSG_ON;        } else {                u132->power = 0;                hcd->state = HC_STATE_HALT;                hcd->self.controller->power.power_state = PMSG_SUSPEND;        }}static int u132_periodic_reinit(struct u132 *u132){        int retval;        u32 fi = u132->hc_fminterval & 0x03fff;        u32 fit;        u32 fminterval;        retval = u132_read_pcimem(u132, fminterval, &fminterval);        if (retval)                return retval;        fit = fminterval & FIT;        retval = u132_write_pcimem(u132, fminterval,                (fit ^ FIT) | u132->hc_fminterval);        if (retval)                return retval;        retval = u132_write_pcimem(u132, periodicstart,                ((9 *fi) / 10) & 0x3fff);        if (retval)                return retval;        return 0;}static char *hcfs2string(int state){        switch (state) {        case OHCI_USB_RESET:                return "reset";        case OHCI_USB_RESUME:                return "resume";        case OHCI_USB_OPER:                return "operational";        case OHCI_USB_SUSPEND:                return "suspend";        }        return "?";}static int u132_init(struct u132 *u132){        int retval;        u32 control;        u132_disable(u132);        u132->next_statechange = jiffies;        retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE);        if (retval)                return retval;        retval = u132_read_pcimem(u132, control, &control);        if (retval)                return retval;        if (u132->num_ports == 0) {         

⌨️ 快捷键说明

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