[PATCH] USB: cleanups for ohci-s3c2410.c
[safe/jmp/linux-2.6] / drivers / usb / host / ehci-sched.c
index ccc7300..5871944 100644 (file)
@@ -589,7 +589,7 @@ static int intr_submit (
        struct usb_host_endpoint *ep,
        struct urb              *urb,
        struct list_head        *qtd_list,
-       unsigned                mem_flags
+       gfp_t                   mem_flags
 ) {
        unsigned                epnum;
        unsigned long           flags;
@@ -602,6 +602,12 @@ static int intr_submit (
 
        spin_lock_irqsave (&ehci->lock, flags);
 
+       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+                              &ehci_to_hcd(ehci)->flags))) {
+               status = -ESHUTDOWN;
+               goto done;
+       }
+
        /* get qh and force any scheduling errors */
        INIT_LIST_HEAD (&empty);
        qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
@@ -634,7 +640,7 @@ done:
 /* ehci_iso_stream ops work with both ITD and SITD */
 
 static struct ehci_iso_stream *
-iso_stream_alloc (unsigned mem_flags)
+iso_stream_alloc (gfp_t mem_flags)
 {
        struct ehci_iso_stream *stream;
 
@@ -701,6 +707,7 @@ iso_stream_init (
        } else {
                u32             addr;
                int             think_time;
+               int             hs_transfers;
 
                addr = dev->ttport << 24;
                if (!ehci_is_TDI(ehci)
@@ -713,6 +720,7 @@ iso_stream_init (
                think_time = dev->tt ? dev->tt->think_time : 0;
                stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
                                dev->speed, is_input, 1, maxp));
+               hs_transfers = max (1u, (maxp + 187) / 188);
                if (is_input) {
                        u32     tmp;
 
@@ -721,12 +729,11 @@ iso_stream_init (
                        stream->usecs = HS_USECS_ISO (1);
                        stream->raw_mask = 1;
 
-                       /* pessimistic c-mask */
-                       tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp)
-                                       / (125 * 1000);
-                       stream->raw_mask |= 3 << (tmp + 9);
+                       /* c-mask as specified in USB 2.0 11.18.4 3.c */
+                       tmp = (1 << (hs_transfers + 2)) - 1;
+                       stream->raw_mask |= tmp << (8 + 2);
                } else
-                       stream->raw_mask = smask_out [maxp / 188];
+                       stream->raw_mask = smask_out [hs_transfers - 1];
                bandwidth = stream->usecs + stream->c_usecs;
                bandwidth /= 1 << (interval + 2);
 
@@ -851,15 +858,14 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
 /* ehci_iso_sched ops can be ITD-only or SITD-only */
 
 static struct ehci_iso_sched *
-iso_sched_alloc (unsigned packets, unsigned mem_flags)
+iso_sched_alloc (unsigned packets, gfp_t mem_flags)
 {
        struct ehci_iso_sched   *iso_sched;
        int                     size = sizeof *iso_sched;
 
        size += packets * sizeof (struct ehci_iso_packet);
-       iso_sched = kmalloc (size, mem_flags);
+       iso_sched = kzalloc(size, mem_flags);
        if (likely (iso_sched != NULL)) {
-               memset(iso_sched, 0, size);
                INIT_LIST_HEAD (&iso_sched->td_list);
        }
        return iso_sched;
@@ -924,7 +930,7 @@ itd_urb_transaction (
        struct ehci_iso_stream  *stream,
        struct ehci_hcd         *ehci,
        struct urb              *urb,
-       unsigned                mem_flags
+       gfp_t                   mem_flags
 )
 {
        struct ehci_itd         *itd;
@@ -1057,6 +1063,7 @@ sitd_slot_ok (
 
                /* for IN, check CSPLIT */
                if (stream->c_usecs) {
+                       uf = uframe & 7;
                        max_used = 100 - stream->c_usecs;
                        do {
                                tmp = 1 << uf;
@@ -1391,7 +1398,7 @@ itd_complete (
         */
 
        /* give urb back to the driver ... can be out-of-order */
-       dev = usb_get_dev (urb->dev);
+       dev = urb->dev;
        ehci_urb_done (ehci, urb, regs);
        urb = NULL;
 
@@ -1410,7 +1417,6 @@ itd_complete (
                        (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
        }
        iso_stream_put (ehci, stream);
-       usb_put_dev (dev);
 
        return 1;
 }
@@ -1418,7 +1424,7 @@ itd_complete (
 /*-------------------------------------------------------------------------*/
 
 static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
-       unsigned mem_flags)
+       gfp_t mem_flags)
 {
        int                     status = -EINVAL;
        unsigned long           flags;
@@ -1456,7 +1462,11 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
 
        /* schedule ... need to lock */
        spin_lock_irqsave (&ehci->lock, flags);
-       status = iso_stream_schedule (ehci, urb, stream);
+       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+                              &ehci_to_hcd(ehci)->flags)))
+               status = -ESHUTDOWN;
+       else
+               status = iso_stream_schedule (ehci, urb, stream);
        if (likely (status == 0))
                itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
        spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1529,7 +1539,7 @@ sitd_urb_transaction (
        struct ehci_iso_stream  *stream,
        struct ehci_hcd         *ehci,
        struct urb              *urb,
-       unsigned                mem_flags
+       gfp_t                   mem_flags
 )
 {
        struct ehci_sitd        *sitd;
@@ -1753,7 +1763,7 @@ sitd_complete (
         */
 
        /* give urb back to the driver */
-       dev = usb_get_dev (urb->dev);
+       dev = urb->dev;
        ehci_urb_done (ehci, urb, regs);
        urb = NULL;
 
@@ -1772,14 +1782,13 @@ sitd_complete (
                        (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
        }
        iso_stream_put (ehci, stream);
-       usb_put_dev (dev);
 
        return 1;
 }
 
 
 static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
-       unsigned mem_flags)
+       gfp_t mem_flags)
 {
        int                     status = -EINVAL;
        unsigned long           flags;
@@ -1815,7 +1824,11 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
 
        /* schedule ... need to lock */
        spin_lock_irqsave (&ehci->lock, flags);
-       status = iso_stream_schedule (ehci, urb, stream);
+       if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+                              &ehci_to_hcd(ehci)->flags)))
+               status = -ESHUTDOWN;
+       else
+               status = iso_stream_schedule (ehci, urb, stream);
        if (status == 0)
                sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
        spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1829,8 +1842,7 @@ done:
 #else
 
 static inline int
-sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
-       unsigned mem_flags)
+sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags)
 {
        ehci_dbg (ehci, "split iso support is disabled\n");
        return -ENOSYS;