Author: hselasky
Date: Thu Jun  5 18:23:51 2014
New Revision: 267122
URL: http://svnweb.freebsd.org/changeset/base/267122

Log:
  - Verify that we don't load more data into a FIFO than it is
  configured to handle.
  - Add code to handle suspend and resume.
  
  MFC after:    3 days

Modified:
  head/sys/dev/usb/controller/musb_otg.c
  head/sys/dev/usb/controller/musb_otg.h

Modified: head/sys/dev/usb/controller/musb_otg.c
==============================================================================
--- head/sys/dev/usb/controller/musb_otg.c      Thu Jun  5 18:19:48 2014        
(r267121)
+++ head/sys/dev/usb/controller/musb_otg.c      Thu Jun  5 18:23:51 2014        
(r267122)
@@ -131,7 +131,7 @@ static void musbotg_do_poll(struct usb_b
 static void    musbotg_standard_done(struct usb_xfer *);
 static void    musbotg_interrupt_poll(struct musbotg_softc *);
 static void    musbotg_root_intr(struct musbotg_softc *);
-static int     musbotg_channel_alloc(struct musbotg_softc *, struct musbotg_td 
*td);
+static int     musbotg_channel_alloc(struct musbotg_softc *, struct musbotg_td 
*td, uint8_t);
 static void    musbotg_channel_free(struct musbotg_softc *, struct musbotg_td 
*td);
 static void    musbotg_ep_int_set(struct musbotg_softc *sc, int channel, int 
on);
 
@@ -149,7 +149,7 @@ static const struct usb_hw_ep_profile mu
 };
 
 static int
-musbotg_channel_alloc(struct musbotg_softc *sc, struct musbotg_td *td)
+musbotg_channel_alloc(struct musbotg_softc *sc, struct musbotg_td *td, uint8_t 
is_tx)
 {
        int ch;
        int ep;
@@ -173,12 +173,23 @@ musbotg_channel_alloc(struct musbotg_sof
                return (0);
        }
 
-       for (ch = 1; ch < MUSB2_EP_MAX; ch++) {
-               if (!(sc->sc_channel_mask & (1 << ch))) {
-                       sc->sc_channel_mask |= (1 << ch);
-                       musbotg_ep_int_set(sc, ch, 1);
-                       return (ch);
-               }
+       for (ch = sc->sc_ep_max; ch != 0; ch--) {
+               if (sc->sc_channel_mask & (1 << ch))
+                       continue;
+
+               /* check FIFO size requirement */
+               if (is_tx) {
+                       if (td->max_frame_size >
+                           sc->sc_hw_ep_profile[ch].max_in_frame_size)
+                               continue;
+               } else {
+                       if (td->max_frame_size >
+                           sc->sc_hw_ep_profile[ch].max_out_frame_size)
+                               continue;
+               }
+               sc->sc_channel_mask |= (1 << ch);
+               musbotg_ep_int_set(sc, ch, 1);
+               return (ch);
        }
 
        DPRINTFN(-1, "No available channels. Mask: %04x\n",  
sc->sc_channel_mask);
@@ -377,7 +388,7 @@ musbotg_dev_ctrl_setup_rx(struct musbotg
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 0);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -498,7 +509,7 @@ musbotg_host_ctrl_setup_tx(struct musbot
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 1);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -870,7 +881,7 @@ musbotg_host_ctrl_data_rx(struct musbotg
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 0);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -1049,7 +1060,7 @@ musbotg_host_ctrl_data_tx(struct musbotg
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 1);
 
        /* No free EPs */
        if (td->channel == -1)
@@ -1259,7 +1270,7 @@ musbotg_host_ctrl_status_rx(struct musbo
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 0);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -1346,7 +1357,7 @@ musbotg_host_ctrl_status_tx(struct musbo
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 1);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -1419,7 +1430,7 @@ musbotg_dev_data_rx(struct musbotg_td *t
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 0);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -1567,7 +1578,7 @@ musbotg_dev_data_tx(struct musbotg_td *t
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 1);
 
        /* EP0 is busy, wait */
        if (td->channel == -1)
@@ -1695,7 +1706,7 @@ musbotg_host_data_rx(struct musbotg_td *
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 0);
 
        /* No free EPs */
        if (td->channel == -1)
@@ -1917,7 +1928,7 @@ musbotg_host_data_tx(struct musbotg_td *
        sc = MUSBOTG_PC2SC(td->pc);
 
        if (td->channel == -1)
-               td->channel = musbotg_channel_alloc(sc, td);
+               td->channel = musbotg_channel_alloc(sc, td, 1);
 
        /* No free EPs */
        if (td->channel == -1)
@@ -3226,6 +3237,7 @@ musbotg_init(struct musbotg_softc *sc)
                        pf->support_out = 1;
                } else if (frx && (temp <= nrx)) {
                        pf->max_out_frame_size = 1 << frx;
+                       pf->max_in_frame_size = 0;
                        pf->is_simplex = 1;     /* simplex */
                        pf->support_multi_buffer = 1;
                        pf->support_bulk = 1;
@@ -3234,6 +3246,7 @@ musbotg_init(struct musbotg_softc *sc)
                        pf->support_out = 1;
                } else if (ftx && (temp <= ntx)) {
                        pf->max_in_frame_size = 1 << ftx;
+                       pf->max_out_frame_size = 0;
                        pf->is_simplex = 1;     /* simplex */
                        pf->support_multi_buffer = 1;
                        pf->support_bulk = 1;
@@ -3287,18 +3300,6 @@ musbotg_uninit(struct musbotg_softc *sc)
 }
 
 static void
-musbotg_suspend(struct musbotg_softc *sc)
-{
-       /* TODO */
-}
-
-static void
-musbotg_resume(struct musbotg_softc *sc)
-{
-       /* TODO */
-}
-
-static void
 musbotg_do_poll(struct usb_bus *bus)
 {
        struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
@@ -4214,13 +4215,13 @@ musbotg_set_hw_power_sleep(struct usb_bu
 
        switch (state) {
        case USB_HW_POWER_SUSPEND:
-               musbotg_suspend(sc);
+               musbotg_uninit(sc);
                break;
        case USB_HW_POWER_SHUTDOWN:
                musbotg_uninit(sc);
                break;
        case USB_HW_POWER_RESUME:
-               musbotg_resume(sc);
+               musbotg_init(sc);
                break;
        default:
                break;

Modified: head/sys/dev/usb/controller/musb_otg.h
==============================================================================
--- head/sys/dev/usb/controller/musb_otg.h      Thu Jun  5 18:19:48 2014        
(r267121)
+++ head/sys/dev/usb/controller/musb_otg.h      Thu Jun  5 18:23:51 2014        
(r267122)
@@ -388,7 +388,7 @@ struct musbotg_flags {
 struct musbotg_softc {
        struct usb_bus sc_bus;
        union musbotg_hub_temp sc_hub_temp;
-       struct usb_hw_ep_profile sc_hw_ep_profile[16];
+       struct usb_hw_ep_profile sc_hw_ep_profile[MUSB2_EP_MAX];
 
        struct usb_device *sc_devices[MUSB2_MAX_DEVICES];
        struct resource *sc_io_res;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to