Date: Mon, 9 Nov 2009 16:48:38 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 170406 for review Message-ID: <200911091648.nA9Gmc3B017251@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911091648.nA9Gmc3B017251>