From owner-p4-projects@FreeBSD.ORG Mon Nov 9 16:48:38 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A925C1065692; Mon, 9 Nov 2009 16:48:38 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6D8821065679 for ; Mon, 9 Nov 2009 16:48:38 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5AA758FC0A for ; Mon, 9 Nov 2009 16:48:38 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id nA9GmcUs017253 for ; Mon, 9 Nov 2009 16:48:38 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id nA9Gmc3B017251 for perforce@freebsd.org; Mon, 9 Nov 2009 16:48:38 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 9 Nov 2009 16:48:38 GMT Message-Id: <200911091648.nA9Gmc3B017251@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 170406 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2009 16:48:38 -0000 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);