PERFORCE change 170406 for review

View: New views
1 Messages — Rating Filter:   Alert me  

PERFORCE change 170406 for review

by Hans Petter Selasky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

http://p4web.freebsd.org/chv.cgi?CH=170406

Change 170406 by hselasky@hselasky_laptop001 on 2009/11/09 16:47:48

       
        USB CORE:
         - Improve High Speed slot allocation mechanism.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#42 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_hub.c#36 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_hub.h#14 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#42 (text+ko) ====

@@ -2356,19 +2356,21 @@
 
  /* Allocate a microframe slot first: */
 
- slot = usb_intr_schedule_adjust
-    (xfer->xroot->udev, xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX);
+ slot = usb_intr_schedule_adjust(xfer->xroot->udev,
+    xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, 0x01);
 
  if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
  xfer->usb_uframe = slot;
- xfer->usb_smask = (1 << slot) & 0xFF;
- xfer->usb_cmask = 0;
+ xfer->usb_smask = (0x01 << slot) & 0xFF;
+ xfer->usb_cmask = 0x00;
  } else {
  xfer->usb_uframe = slot;
- xfer->usb_smask = (1 << slot) & 0x3F;
- xfer->usb_cmask = (-(4 << slot)) & 0xFE;
+ xfer->usb_smask = (0x01 << slot) & 0x3F;
+ xfer->usb_cmask = (-(0x04 << slot)) & 0xFE;
  }
 
+ DPRINTFN(11, "slot=%d\n", slot);
+
  /*
  * Find the best QH position corresponding to the given interval:
  */
@@ -2403,8 +2405,10 @@
 {
  ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
 
+ /* Free microframe slot: */
+
  usb_intr_schedule_adjust(xfer->xroot->udev,
-    -(xfer->max_frame_size), xfer->usb_uframe);
+    -xfer->max_frame_size, xfer->usb_uframe, 0x01);
 
  sc->sc_intr_stat[xfer->qh_pos]--;
 
@@ -2731,28 +2735,34 @@
  uint32_t temp;
  uint8_t ds;
  uint8_t slot;
-
- slot = usb_intr_schedule_adjust(xfer->xroot->udev, xfer->max_frame_size,
-    USB_HS_MICRO_FRAMES_MAX);
-
- xfer->usb_uframe = slot;
- xfer->usb_cmask = 0;
+ uint8_t mask;
 
  switch (usbd_xfer_get_fps_shift(xfer)) {
  case 0:
- xfer->usb_smask = 0xFF;
+ mask = 0xFF;
  break;
  case 1:
- xfer->usb_smask = 0x55 << (slot & 1);
+ mask = 0x55;
  break;
  case 2:
- xfer->usb_smask = 0x11 << (slot & 3);
+ mask = 0x11;
  break;
  default:
- xfer->usb_smask = 0x01 << (slot & 7);
+ mask = 0x01;
  break;
  }
 
+ /* Allocate a microframe multi-slot first: */
+
+ slot = usb_intr_schedule_adjust(xfer->xroot->udev,
+    xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask);
+
+ xfer->usb_uframe = slot;
+ xfer->usb_cmask = 0;
+ xfer->usb_smask = mask << slot;
+
+ DPRINTFN(11, "slot=%d, mask=0x%02x\n", slot, mask);
+
  /* initialize all TD's */
 
  for (ds = 0; ds != 2; ds++) {
@@ -2796,8 +2806,11 @@
 ehci_device_isoc_hs_close(struct usb_xfer *xfer)
 {
 
+ /* Free microframe multi-slot: */
+
  usb_intr_schedule_adjust(xfer->xroot->udev,
-    -(xfer->max_frame_size), xfer->usb_uframe);
+    -xfer->max_frame_size, xfer->usb_uframe,
+    xfer->usb_smask >> xfer->usb_uframe);
 
  ehci_device_done(xfer, USB_ERR_CANCELLED);
 }

==== //depot/projects/usb/src/sys/dev/usb/usb_hub.c#36 (text+ko) ====

@@ -1108,21 +1108,38 @@
  *   The best Transaction Translation slot for an interrupt endpoint.
  *------------------------------------------------------------------------*/
 static uint8_t
-usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start, uint8_t end)
+usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start,
+    uint8_t end, uint8_t mask)
 {
- usb_size_t max = 0 - 1;
+ usb_size_t min = 0 - 1;
+ usb_size_t sum;
  uint8_t x;
  uint8_t y;
+ uint8_t z;
 
  y = 0;
 
  /* find the last slot with lesser used bandwidth */
 
  for (x = start; x < end; x++) {
- if (max >= ptr[x]) {
- max = ptr[x];
+
+ sum = 0;
+
+ /* compute sum of bandwidth */
+ for (z = x; z < end; z++) {
+ if (mask & (1U << (z - x)))
+ sum += ptr[z];
+ }
+
+ /* check if the current multi-slot is more optimal */
+ if (min >= sum) {
+ min = sum;
  y = x;
  }
+
+ /* check if the mask is about to be shifted out */
+ if (mask & (1U << (end - 1 - x)))
+ break;
  }
  return (y);
 }
@@ -1134,17 +1151,19 @@
  * having index "slot" by "len" bytes. "len" can be negative.  If the
  * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
  * the "slot" argument will be replaced by the slot having least used
- * bandwidth.
+ * bandwidth. The "mask" argument is used for multi-slot allocations.
  *
  * Returns:
- *   The slot on which the bandwidth update was done.
+ *    The slot in which the bandwidth update was done: 0..7
  *------------------------------------------------------------------------*/
 uint8_t
-usb_intr_schedule_adjust(struct usb_device *udev, int16_t len, uint8_t slot)
+usb_intr_schedule_adjust(struct usb_device *udev, int16_t len,
+    uint8_t slot, uint8_t mask)
 {
  struct usb_bus *bus = udev->bus;
  struct usb_hub *hub;
  enum usb_dev_speed speed;
+ uint8_t x;
 
  USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
 
@@ -1166,17 +1185,25 @@
  hub = udev->parent_hs_hub->hub;
  if (slot >= USB_HS_MICRO_FRAMES_MAX) {
  slot = usb_intr_find_best_slot(hub->uframe_usage,
-    USB_FS_ISOC_UFRAME_MAX, 6);
+    USB_FS_ISOC_UFRAME_MAX, 6, mask);
+ }
+ for (x = slot; x < 8; x++) {
+ if (mask & (1U << (x - slot))) {
+ hub->uframe_usage[x] += len;
+ bus->uframe_usage[x] += len;
+ }
  }
- hub->uframe_usage[slot] += len;
- bus->uframe_usage[slot] += len;
  break;
  default:
  if (slot >= USB_HS_MICRO_FRAMES_MAX) {
  slot = usb_intr_find_best_slot(bus->uframe_usage, 0,
-    USB_HS_MICRO_FRAMES_MAX);
+    USB_HS_MICRO_FRAMES_MAX, mask);
+ }
+ for (x = slot; x < 8; x++) {
+ if (mask & (1U << (x - slot))) {
+ bus->uframe_usage[x] += len;
+ }
  }
- bus->uframe_usage[slot] += len;
  break;
  }
  return (slot);

==== //depot/projects/usb/src/sys/dev/usb/usb_hub.h#14 (text+ko) ====

@@ -67,7 +67,7 @@
 /* function prototypes */
 
 uint8_t usb_intr_schedule_adjust(struct usb_device *udev, int16_t len,
-    uint8_t slot);
+    uint8_t slot, uint8_t mask);
 void usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss);
 void usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up,
     struct usb_device *udev, uint8_t device_index);
_______________________________________________
p4-projects@... mailing list
http://lists.freebsd.org/mailman/listinfo/p4-projects
To unsubscribe, send any mail to "p4-projects-unsubscribe@..."