Author: thompsa
Date: Tue Jan 13 19:04:58 2009
New Revision: 187180
URL: http://svn.freebsd.org/changeset/base/187180

Log:
  MFp4: //depot/projects/u...@155957
  
        Make code more compliant with SuperSpeed USB and Wireless USB.
  
  Submitted by: Hans Petter Selasky

Modified:
  head/sys/dev/usb2/core/usb2_compat_linux.c
  head/sys/dev/usb2/core/usb2_device.c
  head/sys/dev/usb2/core/usb2_generic.c
  head/sys/dev/usb2/core/usb2_hub.c
  head/sys/dev/usb2/core/usb2_transfer.c
  head/sys/dev/usb2/include/usb2_standard.h

Modified: head/sys/dev/usb2/core/usb2_compat_linux.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_compat_linux.c  Tue Jan 13 19:04:48 2009        
(r187179)
+++ head/sys/dev/usb2/core/usb2_compat_linux.c  Tue Jan 13 19:04:58 2009        
(r187180)
@@ -393,8 +393,14 @@ usb_linux_shutdown(device_t dev)
 static uint16_t
 usb_max_isoc_frames(struct usb_device *dev)
 {
-       return ((usb2_get_speed(dev->bsd_udev) == USB_SPEED_HIGH) ?
-           USB_MAX_HIGH_SPEED_ISOC_FRAMES : USB_MAX_FULL_SPEED_ISOC_FRAMES);
+       ;                               /* indent fix */
+       switch (usb2_get_speed(dev->bsd_udev)) {
+       case USB_SPEED_LOW:
+       case USB_SPEED_FULL:
+               return (USB_MAX_FULL_SPEED_ISOC_FRAMES);
+       default:
+               return (USB_MAX_HIGH_SPEED_ISOC_FRAMES);
+       }
 }
 
 /*------------------------------------------------------------------------*

Modified: head/sys/dev/usb2/core/usb2_device.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_device.c        Tue Jan 13 19:04:48 2009        
(r187179)
+++ head/sys/dev/usb2/core/usb2_device.c        Tue Jan 13 19:04:58 2009        
(r187180)
@@ -75,18 +75,6 @@ static usb2_error_t usb2_fill_iface_data
 static void    usb2_notify_addq(const char *type, struct usb2_device *);
 static void    usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t);
 
-/* static structures */
-
-static const uint8_t usb2_hub_speed_combs[USB_SPEED_MAX][USB_SPEED_MAX] = {
-       /* HUB *//* subdevice */
-       [USB_SPEED_HIGH][USB_SPEED_HIGH] = 1,
-       [USB_SPEED_HIGH][USB_SPEED_FULL] = 1,
-       [USB_SPEED_HIGH][USB_SPEED_LOW] = 1,
-       [USB_SPEED_FULL][USB_SPEED_FULL] = 1,
-       [USB_SPEED_FULL][USB_SPEED_LOW] = 1,
-       [USB_SPEED_LOW][USB_SPEED_LOW] = 1,
-};
-
 /* This variable is global to allow easy access to it: */
 
 int    usb2_template = 0;
@@ -1364,21 +1352,10 @@ usb2_alloc_device(device_t parent_dev, s
        udev->speed = speed;
        udev->flags.usb2_mode = usb2_mode;
 
-       /* check speed combination */
+       /* speed combination should be checked by the parent HUB */
 
        hub = udev->parent_hub;
-       if (hub) {
-               if (usb2_hub_speed_combs[hub->speed][speed] == 0) {
-#if USB_DEBUG
-                       printf("%s: the selected subdevice and HUB speed "
-                           "combination is not supported %d/%d.\n",
-                           __FUNCTION__, speed, hub->speed);
-#endif
-                       /* reject this combination */
-                       err = USB_ERR_INVAL;
-                       goto done;
-               }
-       }
+
        /* search for our High Speed USB HUB, if any */
 
        adev = udev;

Modified: head/sys/dev/usb2/core/usb2_generic.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_generic.c       Tue Jan 13 19:04:48 2009        
(r187179)
+++ head/sys/dev/usb2/core/usb2_generic.c       Tue Jan 13 19:04:58 2009        
(r187180)
@@ -157,12 +157,16 @@ ugen_open(struct usb2_fifo *f, int fflag
        DPRINTFN(6, "flag=0x%x\n", fflags);
 
        mtx_lock(f->priv_mtx);
-       if (usb2_get_speed(f->udev) == USB_SPEED_HIGH) {
-               f->nframes = UGEN_HW_FRAMES * 8;
-               f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
-       } else {
+       switch (usb2_get_speed(f->udev)) {
+       case USB_SPEED_LOW:
+       case USB_SPEED_FULL:
                f->nframes = UGEN_HW_FRAMES;
                f->bufsize = UGEN_BULK_FS_BUFFER_SIZE;
+               break;
+       default:
+               f->nframes = UGEN_HW_FRAMES * 8;
+               f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
+               break;
        }
 
        type = ed->bmAttributes & UE_XFERTYPE;

Modified: head/sys/dev/usb2/core/usb2_hub.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_hub.c   Tue Jan 13 19:04:48 2009        
(r187179)
+++ head/sys/dev/usb2/core/usb2_hub.c   Tue Jan 13 19:04:58 2009        
(r187180)
@@ -372,18 +372,38 @@ repeat:
        /*
         * Figure out the device speed
         */
-       speed =
-           (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
-           (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : 
USB_SPEED_FULL;
-
+       switch (udev->speed) {
+       case USB_SPEED_HIGH:
+               if (sc->sc_st.port_status & UPS_HIGH_SPEED)
+                       speed = USB_SPEED_HIGH;
+               else if (sc->sc_st.port_status & UPS_LOW_SPEED)
+                       speed = USB_SPEED_LOW;
+               else
+                       speed = USB_SPEED_FULL;
+               break;
+       case USB_SPEED_FULL:
+               if (sc->sc_st.port_status & UPS_LOW_SPEED)
+                       speed = USB_SPEED_LOW;
+               else
+                       speed = USB_SPEED_FULL;
+               break;
+       case USB_SPEED_LOW:
+               speed = USB_SPEED_LOW;
+               break;
+       default:
+               /* same speed like parent */
+               speed = udev->speed;
+               break;
+       }
        /*
         * Figure out the device mode
         *
         * NOTE: This part is currently FreeBSD specific.
         */
-       usb2_mode =
-           (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
-           USB_MODE_DEVICE : USB_MODE_HOST;
+       if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
+               usb2_mode = USB_MODE_DEVICE;
+       else
+               usb2_mode = USB_MODE_HOST;
 
        /* need to create a new child */
 
@@ -1049,17 +1069,16 @@ usb2_intr_schedule_adjust(struct usb2_de
 {
        struct usb2_bus *bus = udev->bus;
        struct usb2_hub *hub;
+       uint8_t speed;
 
        USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
 
-       if (usb2_get_speed(udev) == USB_SPEED_HIGH) {
-               if (slot >= USB_HS_MICRO_FRAMES_MAX) {
-                       slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
-                           USB_HS_MICRO_FRAMES_MAX);
-               }
-               bus->uframe_usage[slot] += len;
-       } else {
-               if (usb2_get_speed(udev) == USB_SPEED_LOW) {
+       speed = usb2_get_speed(udev);
+
+       switch (speed) {
+       case USB_SPEED_LOW:
+       case USB_SPEED_FULL:
+               if (speed == USB_SPEED_LOW) {
                        len *= 8;
                }
                /*
@@ -1076,6 +1095,14 @@ usb2_intr_schedule_adjust(struct usb2_de
                }
                hub->uframe_usage[slot] += len;
                bus->uframe_usage[slot] += len;
+               break;
+       default:
+               if (slot >= USB_HS_MICRO_FRAMES_MAX) {
+                       slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
+                           USB_HS_MICRO_FRAMES_MAX);
+               }
+               bus->uframe_usage[slot] += len;
+               break;
        }
        return (slot);
 }

Modified: head/sys/dev/usb2/core/usb2_transfer.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_transfer.c      Tue Jan 13 19:04:48 2009        
(r187179)
+++ head/sys/dev/usb2/core/usb2_transfer.c      Tue Jan 13 19:04:58 2009        
(r187180)
@@ -63,6 +63,7 @@ static const struct usb2_std_packet_size
                [USB_SPEED_FULL] = {.range = {0, 64}},
                [USB_SPEED_HIGH] = {.range = {0, 1024}},
                [USB_SPEED_VARIABLE] = {.range = {0, 1024}},
+               [USB_SPEED_SUPER] = {.range = {0, 1024}},
        },
 
        [UE_CONTROL] = {
@@ -70,6 +71,7 @@ static const struct usb2_std_packet_size
                [USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
                [USB_SPEED_HIGH] = {.fixed = {64, 64, 64, 64}},
                [USB_SPEED_VARIABLE] = {.fixed = {512, 512, 512, 512}},
+               [USB_SPEED_SUPER] = {.fixed = {512, 512, 512, 512}},
        },
 
        [UE_BULK] = {
@@ -77,6 +79,7 @@ static const struct usb2_std_packet_size
                [USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
                [USB_SPEED_HIGH] = {.fixed = {512, 512, 512, 512}},
                [USB_SPEED_VARIABLE] = {.fixed = {512, 512, 1024, 1536}},
+               [USB_SPEED_SUPER] = {.fixed = {1024, 1024, 1024, 1024}},
        },
 
        [UE_ISOCHRONOUS] = {
@@ -84,6 +87,7 @@ static const struct usb2_std_packet_size
                [USB_SPEED_FULL] = {.range = {0, 1023}},
                [USB_SPEED_HIGH] = {.range = {0, 1024}},
                [USB_SPEED_VARIABLE] = {.range = {0, 3584}},
+               [USB_SPEED_SUPER] = {.range = {0, 1024}},
        },
 };
 
@@ -413,10 +417,14 @@ usb2_transfer_setup_sub(struct usb2_setu
                         */
                        xfer->timeout = 1000 / 4;
                }
-               if (parm->speed == USB_SPEED_HIGH) {
-                       frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
-               } else {
+               switch (parm->speed) {
+               case USB_SPEED_LOW:
+               case USB_SPEED_FULL:
                        frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER;
+                       break;
+               default:
+                       frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
+                       break;
                }
 
                if (xfer->nframes > frame_limit) {
@@ -446,13 +454,29 @@ usb2_transfer_setup_sub(struct usb2_setu
 
                                xfer->interval = edesc->bInterval;
 
-                               if (parm->speed == USB_SPEED_HIGH) {
-                                       xfer->interval /= 8;    /* 125us -> 1ms 
*/
+                               switch (parm->speed) {
+                               case USB_SPEED_SUPER:
+                               case USB_SPEED_VARIABLE:
+                                       /* 125us -> 1ms */
+                                       if (xfer->interval < 4)
+                                               xfer->interval = 1;
+                                       else if (xfer->interval > 16)
+                                               xfer->interval = (1<<(16-4));
+                                       else
+                                               xfer->interval = 
+                                                   (1 << (xfer->interval-4));
+                                       break;
+                               case USB_SPEED_HIGH:
+                                       /* 125us -> 1ms */
+                                       xfer->interval /= 8;
+                                       break;
+                               default:
+                                       break;
                                }
                                if (xfer->interval == 0) {
                                        /*
-                                        * one millisecond is the smallest
-                                        * interval
+                                        * One millisecond is the smallest
+                                        * interval we support:
                                         */
                                        xfer->interval = 1;
                                }

Modified: head/sys/dev/usb2/include/usb2_standard.h
==============================================================================
--- head/sys/dev/usb2/include/usb2_standard.h   Tue Jan 13 19:04:48 2009        
(r187179)
+++ head/sys/dev/usb2/include/usb2_standard.h   Tue Jan 13 19:04:58 2009        
(r187180)
@@ -602,12 +602,12 @@ struct usb2_port_status {
 #define        UPS_SUSPEND                     0x0004
 #define        UPS_OVERCURRENT_INDICATOR       0x0008
 #define        UPS_RESET                       0x0010
-#define        UPS_PORT_MODE_DEVICE            0x0020  /* currently FreeBSD 
specific */
 #define        UPS_PORT_POWER                  0x0100
 #define        UPS_LOW_SPEED                   0x0200
 #define        UPS_HIGH_SPEED                  0x0400
 #define        UPS_PORT_TEST                   0x0800
 #define        UPS_PORT_INDICATOR              0x1000
+#define        UPS_PORT_MODE_DEVICE            0x8000  /* currently FreeBSD 
specific */
        uWord   wPortChange;
 #define        UPS_C_CONNECT_STATUS            0x0001
 #define        UPS_C_PORT_ENABLED              0x0002
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to