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

📄 m8xxhci.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        dump_frame_list("current", hp->current_frame);        dump_frame_list("next", hp->next_frame);}/* ----- */static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED;static int queues_busy;static spinlock_t txbd_list_lock = SPIN_LOCK_UNLOCKED;static int txbd_list_busy;static struct m8xxhci_qe *delay_qe_list;static int qdbg = 0;static intmap_pipe_to_qtype(int pipe){        switch (usb_pipetype(pipe)) {        case PIPE_CONTROL:      return Q_CTRL;        case PIPE_INTERRUPT:    return Q_INTR;        case PIPE_BULK:         return Q_BULK;        case PIPE_ISOCHRONOUS:  return Q_ISO;        }#ifdef DEBUG_CHECKS        printk("map_pipe_to_qtype(%x) -> unknown pipe type!\n", pipe);#endif        return 0;}/* allocate an internal queue entry for sending frames */static struct m8xxhci_qe *allocate_qe(struct m8xxhci_device *dev, int qtype){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        struct m8xxhci_qe *qe;        int inuse;        if (0) printk("allocate_qe(dev=%p,qtype=%d)\n", dev, qtype);        qe = hp->queues[qtype];        while ((inuse = test_and_set_bit(0, &qe->inuse)) != 0 &&               qe < &hp->queues[qtype][M8XXHCI_MAXQE])        {                qe++;        }#ifdef DEBUG_CHECKS        if (qe == &hp->queues[qtype][M8XXHCI_MAXQE])                inuse = 1;#endif        if (!inuse) {                qe->qtype = qtype;                qe->qstate = 0;                qe->retries = 0;                qe->busys = 0;                qe->recv_len = 0;                qe->send_len = 0;                qe->reschedule = 0;                qe->shortread = 0;                qe->dev = 0;                qe->urb = 0;                qe->iso_ptr = 0;                qe->frames = 0;		qe->on_frame_list = 0;                INIT_LIST_HEAD(&qe->frame_list);                INIT_LIST_HEAD(&qe->qe_list);                init_waitqueue_head(&qe->wakeup);                if (0) printk("allocate_qe(dev=%p,qtype=%d) -> %p\n",                              dev, qtype, qe);                return(qe);        }        printk("m8xxhci: out of qe's for dev %p\n", dev);        return(NULL);}static voiddeallocate_qe(struct m8xxhci_qe *qe){        if (0) printk("deallocate_qe(qe=%p)\n", qe);        log_event(2, "deallocate_qe qe", (int)qe);        clear_bit(0, &qe->inuse);}/* remove qe from pending list */static voiddequeue_qe(struct m8xxhci_qe *qe){        if (!list_empty(&qe->qe_list)) {                list_del(&qe->qe_list);                INIT_LIST_HEAD(&qe->qe_list);        }}/* place internal queue entry at end of queue */static voidenqueue_qe(struct m8xxhci_qe *qe, int qtype){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        if (0) printk("enqueue_qe(qe=%p,qtype=%d)\n", qe, qtype);        INIT_LIST_HEAD(&qe->qe_list);        list_add_tail(&qe->qe_list, &hp->qe_list[qtype]);}static voiddump_pending_qe_list(void){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        struct list_head *head, *l;        struct m8xxhci_qe *qe;        unsigned long flags;        int i;        spin_lock_irqsave(&queue_lock, flags);        for (i = 0; i < MAX_Q_TYPES; i++) {                printk("qtype %d:\n", i);                head = &hp->qe_list[i];                if (list_empty(head))                        continue;                for (l = head->next; l != head; l = l->next)                {                        qe = list_entry(l, struct m8xxhci_qe, qe_list);                        printk("qe %p, next %p, urb %p, delta %d, next %p\n",                               qe,                               list_entry(&qe->qe_list.next,                                          struct m8xxhci_qe,                                          qe_list),                               qe->urb, qe->delta, qe->next);                        printk("  devnum %d, state %d, reschedule %d\n",                               qe->devnum, qe->qstate, qe->reschedule);                }        }        spin_unlock_irqrestore(&queue_lock, flags);}/* remove qe from any list it might be on and reset qe & driver state */static voiddeactivate_qe(struct m8xxhci_qe *qe){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        unsigned long flags;        struct m8xxhci_qe *q = NULL;	struct m8xxhci_frame *frame;        spin_lock_irqsave(&queue_lock, flags);        qe->qstate = 0;        /* if active, reset state */        if (hp->active_qe == qe) {                make_inactive_qe_idle_endpoint(qe);        }        /* if on current/next frame list, remove */        if (!list_empty(&qe->frame_list)) {                list_del(&qe->frame_list);                INIT_LIST_HEAD(&qe->frame_list);		frame = qe->on_frame_list;		qe->on_frame_list = 0;				/* fix frame accounting */		if (frame) {			frame->total_bytes -= qe->data_len;			frame->bytes[qe->qtype] -= qe->data_len;			/* if on a frame list, ep was marked busy */			mark_endpoint_idle(qe);		}	}        /* if on delay list, remove */        if (delay_qe_list == qe) {                delay_qe_list = qe->next;                q = delay_qe_list;        } else {                for (q = delay_qe_list; q; q = q->next) {                        if (q->next == qe) {                                q->next = qe->next;                                break;                        }                }        }        if (q) {                q->delta += qe->delta;        }                spin_unlock_irqrestore(&queue_lock, flags);}static voidmake_active_qe(struct m8xxhci_qe *qe){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        hp->active_qe = qe;}static voidmake_inactive_qe(struct m8xxhci_qe *qe){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        hp->active_qe = 0;        hp->xmit_state[qe->qtype] = XS_IDLE;}static voidmake_inactive_qe_idle_endpoint(struct m8xxhci_qe *qe){        make_inactive_qe(qe);        mark_endpoint_idle(qe);}static intcomplete_qe(struct m8xxhci_qe *qe, int status){        struct m8xxhci_private *hp = (struct m8xxhci_private *)m8xxhci_ptr;        struct urb *urb = qe->urb;        log_event(1, "complete_qe qe", (int)qe);        log_event(3, "complete_qe status", status);        log_event(3, "complete_qe urb", (int)urb);        log_event(3, "qe->qtype", qe->qtype);        if (urb)                log_event(3, "complete_qe urb->complete", (int)urb->complete);        qe->status = status;#if 0 /*def DEBUG_CHECKS*/        if (status != 0) {                if (m8xxhci_verbose > 1 || status != -1)                        printk("complete_qe(qe=%p,status=%d)\n", qe, status);        }#endif        if (urb) {                urb->actual_length = usb_pipein(urb->pipe) ?                        qe->recv_len : qe->send_len;                log_event(3, "complete_qe set status", urb->status);		if (status == -1)			status = USB_ST_TIMEOUT;		urb->status = status;                log_event(3, "complete_qe after set status", urb->status);#if 0		/* debug; turn off logging to catch last error */                if (status != 0) {			logging_off();		}#endif#if 0                if (m8xxhci_verbose && status != 0) {                        printk("complete urb %p, "                               "actual_length %d, status %d\n",                               urb, urb->actual_length, status);//                      m8xxhci_dump();                }#endif                /* interrupt urbs restart themselves */                switch (qe->qtype) {                case Q_INTR:                        if (urb->interval) {                                qe->recv_len = 0;                                qe->send_len = 0;                                qe->retries = 0;                                qe->busys = 0;                                qe->reschedule = 1;				if (urb->complete) {					urb->complete(urb);					hp->stats.completes[1]++;				}				break;                        }			/* fall through */                default:                        unlink_urb(urb, qe->qtype);			log_event(3, "complete_qe after unlink",				  (int)urb->complete);// not sure we should do this//			urb->dev = NULL;			if (urb->complete) {				urb->complete(urb);				hp->stats.completes[qe->qtype]++;			}                }        }        if (waitqueue_active(&qe->wakeup))                wake_up(&qe->wakeup);        return 0;}/* abort a qe; only works if it's active or just dequeued */static voidabort_qe(struct m8xxhci_qe *qe, int status){        log_event(1, "abort_qe qe", (int)qe);        deactivate_qe(qe);        complete_qe(qe, status);}static voidwait_for_qe(struct m8xxhci_qe *qe){        DECLARE_WAITQUEUE (wait, current);        log_event(3, "wait_for_qe qe", (int)qe);        if (0) printk("wait_for_qe(qe=%p) urb=%p\n", qe, qe->urb);        set_current_state(TASK_UNINTERRUPTIBLE);        add_wait_queue(&qe->wakeup, &wait);//      schedule_timeout(HZ/10);        schedule_timeout(HZ);        remove_wait_queue(&qe->wakeup, &wait);        set_current_state(TASK_RUNNING);        if (qe->status > 0) {                log_event(1, "wait_for_qe timeout qe", (int)qe);                if (qe->urb) printk("wait_for_qe(qe=%p) timeout; urb %p\n",                                    qe, qe->urb);                abort_qe(qe, USB_ST_NORESPONSE);        }        log_event(3, "wait_for_qe done qe", (int)qe);        if (qe->status != 0) {                if (m8xxhci_verbose > 1 || qe->status != -1)                        printk("wait_for_qe(qe=%p) done; urb %p, status %d\n",                               qe, qe->urb, qe->status);        }}static intlock_queues(struct m8xxhci_private *hp){        unsigned long flags;        spin_lock_irqsave(&queue_lock, flags);        if (queues_busy) {                spin_unlock_irqrestore(&queue_lock, flags);                return -1;        }        queues_busy++;        spin_unlock_irqrestore(&queue_lock, flags);        return 0;}static voidunlock_queues(struct m8xxhci_private *hp){        unsigned long flags;        spin_lock_irqsave(&queue_lock, flags);        queues_busy--;        spin_unlock_irqrestore(&queue_lock, flags);}static intendpoint_busy(struct m8xxhci_qe *qe){        struct m8xxhci_device *dev;        int io, ep;        dev = qe->dev ? usb_to_m8xxhci(qe->dev) : NULL;        if (dev) {                io = usb_pipein(qe->pipe) ? 0 : 1;                ep = usb_pipeendpoint(qe->pipe);                if (dev->busy[io][ep]) {                        /* if iso, don't timeout for busy */                        if (qe->qstate == QS_ISO) {                                return 1;                        }                        if (1) {                                log_event(3, "dev is busy dev", (int)dev);                                log_event(3, "dev is busy qe", (int)qe);                                log_event(3, "dev is busy io", io);                        }                        dev->busy_count[io][ep]++;                        if (dev->busy_count[io][ep] > MAX_EP_BUSYS) {                                int devnum;                                devnum = dev ? dev->usb->devnum : 0;                                if (m8xxhci_verbose)                                        printk("m8xxhci: EXCESSIVE BUSYS "                                               "on device %d, ep %d!\n",                                               devnum, ep);                                                                log_event(1, "excessive busys; dnum", devnum);                                log_event(1, "excessive busys; ep", ep);#ifdef DEBUG_CHECKS                                if (0) dump_events();#endif                        }                        return 1;                }        }        return 0;}

⌨️ 快捷键说明

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