lkml.org 
[lkml]   [2005]   [Jan]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH] USB and Driver Core patches for 2.6.10
    Date
    From
    ChangeSet 1.1938.446.29, 2004/12/17 11:39:40-08:00, david-b@pacbell.net

    [PATCH] USB: HCDs and per-device state (16/15)

    SL811 changes getting rid of the "hcd_dev" support, using
    usb_host_endpoint to hold the QH. This also eliminates the
    "sl811h_req" data type. Compile-tested only!

    Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
    Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>


    drivers/usb/host/sl811-hcd.c | 149 +++++++++++++++----------------------------
    drivers/usb/host/sl811.h | 10 --
    2 files changed, 53 insertions(+), 106 deletions(-)


    diff -Nru a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
    --- a/drivers/usb/host/sl811-hcd.c 2005-01-07 15:47:03 -08:00
    +++ b/drivers/usb/host/sl811-hcd.c 2005-01-07 15:47:03 -08:00
    @@ -67,7 +67,7 @@
    MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");
    MODULE_LICENSE("GPL");

    -#define DRIVER_VERSION "06 Dec 2004"
    +#define DRIVER_VERSION "15 Dec 2004"


    #ifndef DEBUG
    @@ -314,7 +314,6 @@
    static struct sl811h_ep *start(struct sl811 *sl811, u8 bank)
    {
    struct sl811h_ep *ep;
    - struct sl811h_req *req;
    struct urb *urb;
    int fclock;
    u8 control;
    @@ -348,13 +347,12 @@
    struct sl811h_ep, schedule);
    }

    - if (unlikely(list_empty(&ep->queue))) {
    + if (unlikely(list_empty(&ep->hep->urb_list))) {
    DBG("empty %p queue?\n", ep);
    return NULL;
    }

    - req = container_of(ep->queue.next, struct sl811h_req, queue);
    - urb = req->urb;
    + urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
    control = ep->defctrl;

    /* if this frame doesn't have enough time left to transfer this
    @@ -432,17 +430,12 @@
    static void finish_request(
    struct sl811 *sl811,
    struct sl811h_ep *ep,
    - struct sl811h_req *req,
    + struct urb *urb,
    struct pt_regs *regs,
    int status
    ) __releases(sl811->lock) __acquires(sl811->lock)
    {
    unsigned i;
    - struct urb *urb = req->urb;
    -
    - list_del(&req->queue);
    - kfree(req);
    - urb->hcpriv = NULL;

    if (usb_pipecontrol(urb->pipe))
    ep->nextpid = USB_PID_SETUP;
    @@ -457,7 +450,7 @@
    spin_lock(&sl811->lock);

    /* leave active endpoints in the schedule */
    - if (!list_empty(&ep->queue))
    + if (!list_empty(&ep->hep->urb_list))
    return;

    /* async deschedule? */
    @@ -496,7 +489,6 @@
    done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs)
    {
    u8 status;
    - struct sl811h_req *req;
    struct urb *urb;
    int urbstat = -EINPROGRESS;

    @@ -505,8 +497,7 @@

    status = sl811_read(sl811, bank + SL11H_PKTSTATREG);

    - req = container_of(ep->queue.next, struct sl811h_req, queue);
    - urb = req->urb;
    + urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);

    /* we can safely ignore NAKs */
    if (status & SL11H_STATMASK_NAK) {
    @@ -577,7 +568,7 @@
    urb->status = urbstat;
    spin_unlock(&urb->lock);

    - req = NULL;
    + urb = NULL;
    ep->nextpid = USB_PID_ACK;
    }
    break;
    @@ -618,9 +609,8 @@
    bank, status, ep, urbstat);
    }

    - if ((urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)
    - && req)
    - finish_request(sl811, ep, req, regs, urbstat);
    + if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS))
    + finish_request(sl811, ep, urb, regs, urbstat);
    }

    static inline u8 checkdone(struct sl811 *sl811)
    @@ -643,7 +633,7 @@
    ctl = sl811_read(sl811, SL811_EP_B(SL11H_HOSTCTLREG));
    if (ctl & SL11H_HCTLMASK_ARM)
    sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
    - DBG("%s DONE_B: ctrl %02x sts %02x\n", ctl,
    + DBG("%s DONE_B: ctrl %02x sts %02x\n",
    (ctl & SL11H_HCTLMASK_ARM) ? "timeout" : "lost",
    ctl,
    sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
    @@ -732,8 +722,8 @@
    if (sl811->active_a) {
    sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0);
    finish_request(sl811, sl811->active_a,
    - container_of(sl811->active_a->queue.next,
    - struct sl811h_req, queue),
    + container_of(sl811->active_a->hep->urb_list.next,
    + struct urb, urb_list),
    NULL, -ESHUTDOWN);
    sl811->active_a = NULL;
    }
    @@ -741,8 +731,8 @@
    if (sl811->active_b) {
    sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
    finish_request(sl811, sl811->active_b,
    - container_of(sl811->active_b->queue.next,
    - struct sl811h_req, queue),
    + container_of(sl811->active_b->hep->urb_list.next,
    + struct urb, urb_list),
    NULL, -ESHUTDOWN);
    sl811->active_b = NULL;
    }
    @@ -816,19 +806,18 @@
    /*-------------------------------------------------------------------------*/

    static int sl811h_urb_enqueue(
    - struct usb_hcd *hcd,
    - struct urb *urb,
    - int mem_flags
    + struct usb_hcd *hcd,
    + struct usb_host_endpoint *hep,
    + struct urb *urb,
    + int mem_flags
    ) {
    struct sl811 *sl811 = hcd_to_sl811(hcd);
    struct usb_device *udev = urb->dev;
    - struct hcd_dev *hdev = (struct hcd_dev *) udev->hcpriv;
    unsigned int pipe = urb->pipe;
    int is_out = !usb_pipein(pipe);
    int type = usb_pipetype(pipe);
    int epnum = usb_pipeendpoint(pipe);
    struct sl811h_ep *ep = NULL;
    - struct sl811h_req *req;
    unsigned long flags;
    int i;
    int retval = 0;
    @@ -838,16 +827,8 @@
    return -ENOSPC;
    #endif

    - /* avoid all allocations within spinlocks: request or endpoint */
    - urb->hcpriv = req = kmalloc(sizeof *req, mem_flags);
    - if (!req)
    - return -ENOMEM;
    - req->urb = urb;
    -
    - i = epnum << 1;
    - if (i && is_out)
    - i |= 1;
    - if (!hdev->ep[i])
    + /* avoid all allocations within spinlocks */
    + if (!hep->hcpriv)
    ep = kcalloc(1, sizeof *ep, mem_flags);

    spin_lock_irqsave(&sl811->lock, flags);
    @@ -859,15 +840,14 @@
    goto fail;
    }

    - if (hdev->ep[i]) {
    + if (hep->hcpriv) {
    kfree(ep);
    - ep = hdev->ep[i];
    + ep = hep->hcpriv;
    } else if (!ep) {
    retval = -ENOMEM;
    goto fail;

    } else {
    - INIT_LIST_HEAD(&ep->queue);
    INIT_LIST_HEAD(&ep->schedule);
    ep->udev = usb_get_dev(udev);
    ep->epnum = epnum;
    @@ -911,7 +891,7 @@
    break;
    }

    - hdev->ep[i] = ep;
    + hep->hcpriv = ep;
    }

    /* maybe put endpoint into schedule */
    @@ -966,47 +946,38 @@
    spin_lock(&urb->lock);
    if (urb->status != -EINPROGRESS) {
    spin_unlock(&urb->lock);
    - finish_request(sl811, ep, req, NULL, 0);
    - req = NULL;
    + finish_request(sl811, ep, urb, NULL, 0);
    retval = 0;
    goto fail;
    }
    - list_add_tail(&req->queue, &ep->queue);
    + urb->hcpriv = hep;
    spin_unlock(&urb->lock);

    start_transfer(sl811);
    sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable);
    fail:
    spin_unlock_irqrestore(&sl811->lock, flags);
    - if (retval)
    - kfree(req);
    return retval;
    }

    static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
    {
    struct sl811 *sl811 = hcd_to_sl811(hcd);
    - struct usb_device *udev = urb->dev;
    - struct hcd_dev *hdev = (struct hcd_dev *) udev->hcpriv;
    - unsigned int pipe = urb->pipe;
    - int is_out = !usb_pipein(pipe);
    + struct usb_host_endpoint *hep = urb->hcpriv;
    unsigned long flags;
    - unsigned i;
    struct sl811h_ep *ep;
    - struct sl811h_req *req = urb->hcpriv;
    int retval = 0;

    - i = usb_pipeendpoint(pipe) << 1;
    - if (i && is_out)
    - i |= 1;
    + if (!hep)
    + return -EINVAL;

    spin_lock_irqsave(&sl811->lock, flags);
    - ep = hdev->ep[i];
    + ep = hep->hcpriv;
    if (ep) {
    /* finish right away if this urb can't be active ...
    * note that some drivers wrongly expect delays
    */
    - if (ep->queue.next != &req->queue) {
    + if (ep->hep->urb_list.next != &urb->urb_list) {
    /* not front of queue? never active */

    /* for active transfers, we expect an IRQ */
    @@ -1022,7 +993,7 @@
    0);
    sl811->active_a = NULL;
    } else
    - req = NULL;
    + urb = NULL;
    #ifdef USE_B
    } else if (sl811->active_b == ep) {
    if (time_before_eq(sl811->jiffies_a, jiffies)) {
    @@ -1036,14 +1007,14 @@
    0);
    sl811->active_b = NULL;
    } else
    - req = NULL;
    + urb = NULL;
    #endif
    } else {
    /* front of queue for inactive endpoint */
    }

    - if (req)
    - finish_request(sl811, ep, req, NULL, 0);
    + if (urb)
    + finish_request(sl811, ep, urb, NULL, 0);
    else
    VDBG("dequeue, urb %p active %s; wait4irq\n", urb,
    (sl811->active_a == ep) ? "A" : "B");
    @@ -1054,33 +1025,22 @@
    }

    static void
    -sl811h_endpoint_disable(struct usb_hcd *hcd, struct hcd_dev *hdev, int epnum)
    +sl811h_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
    {
    - struct sl811 *sl811 = hcd_to_sl811(hcd);
    - struct sl811h_ep *ep;
    - unsigned long flags;
    - int i;
    -
    - i = (epnum & 0xf) << 1;
    - if (epnum && !(epnum & USB_DIR_IN))
    - i |= 1;
    -
    - spin_lock_irqsave(&sl811->lock, flags);
    - ep = hdev->ep[i];
    - hdev->ep[i] = NULL;
    - spin_unlock_irqrestore(&sl811->lock, flags);
    + struct sl811h_ep *ep = hep->hcpriv;

    - if (ep) {
    - /* assume we'd just wait for the irq */
    - if (!list_empty(&ep->queue))
    - msleep(3);
    - if (!list_empty(&ep->queue))
    - WARN("ep %p not empty?\n", ep);
    + if (!ep)
    + return;

    - usb_put_dev(ep->udev);
    - kfree(ep);
    - }
    - return;
    + /* assume we'd just wait for the irq */
    + if (!list_empty(&hep->urb_list))
    + msleep(3);
    + if (!list_empty(&hep->urb_list))
    + WARN("ep %p not empty?\n", ep);
    +
    + usb_put_dev(ep->udev);
    + kfree(ep);
    + hep->hcpriv = 0;
    }

    static int
    @@ -1481,7 +1441,7 @@
    sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
    seq_printf(s, "\n");
    list_for_each_entry (ep, &sl811->async, schedule) {
    - struct sl811h_req *req;
    + struct urb *urb;

    seq_printf(s, "%s%sqh%p, ep%d%s, maxpacket %d"
    " nak %d err %d\n",
    @@ -1497,10 +1457,10 @@
    }; s;}),
    ep->maxpacket,
    ep->nak_count, ep->error_count);
    - list_for_each_entry (req, &ep->queue, queue) {
    - seq_printf(s, " urb%p, %d/%d\n", req->urb,
    - req->urb->actual_length,
    - req->urb->transfer_buffer_length);
    + list_for_each_entry (urb, &ep->hep->urb_list, urb_list) {
    + seq_printf(s, " urb%p, %d/%d\n", urb,
    + urb->actual_length,
    + urb->transfer_buffer_length);
    }
    }
    if (!list_empty(&sl811->async))
    @@ -1743,11 +1703,6 @@
    sl811->hcd.self.op = &usb_hcd_operations;
    sl811->hcd.self.hcpriv = sl811;

    - // NOTE: 2.6.11 starts to change the hcd glue layer some more,
    - // eventually letting us eliminate struct sl811h_req and a
    - // lot of the boilerplate code here
    -
    - INIT_LIST_HEAD(&sl811->hcd.dev_list);
    sl811->hcd.self.release = &usb_hcd_release;

    sl811->hcd.description = sl811h_hc_driver.description;
    diff -Nru a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h
    --- a/drivers/usb/host/sl811.h 2005-01-07 15:47:03 -08:00
    +++ b/drivers/usb/host/sl811.h 2005-01-07 15:47:03 -08:00
    @@ -162,7 +162,7 @@
    }

    struct sl811h_ep {
    - struct list_head queue;
    + struct usb_host_endpoint *hep;
    struct usb_device *udev;

    u8 defctrl;
    @@ -182,14 +182,6 @@

    /* async schedule */
    struct list_head schedule;
    -};
    -
    -struct sl811h_req {
    - /* FIXME usbcore should maintain endpoints' urb queues
    - * directly in 'struct usb_host_endpoint'
    - */
    - struct urb *urb;
    - struct list_head queue;
    };

    /*-------------------------------------------------------------------------*/
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:09    [W:0.050 / U:238.328 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site