From owner-p4-projects@FreeBSD.ORG Mon May 10 23:35:50 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4C37C1065676; Mon, 10 May 2010 23:35:50 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id EC927106566B for ; Mon, 10 May 2010 23:35:49 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id D2C248FC21 for ; Mon, 10 May 2010 23:35:49 +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 o4ANZngH090025 for ; Mon, 10 May 2010 23:35:49 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o4ANZnb9090023 for perforce@freebsd.org; Mon, 10 May 2010 23:35:49 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 10 May 2010 23:35:49 GMT Message-Id: <201005102335.o4ANZnb9090023@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 178075 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, 10 May 2010 23:35:50 -0000 http://p4web.freebsd.org/@@178075?ac=10 Change 178075 by hselasky@hselasky_laptop001 on 2010/05/10 23:35:13 USB CORE + USB CONTROLLER: - fix for intervalled High Speed isochronous transfers. ehci.c: - back out USB P4 change #173002 which was causing problems when the first and the last microframe slot was not in the smask. The problem was that the EHCI driver was then thinking that the transfer was immediately complete in some cases. Which could lead to freeze-like situations, which can be recovered by unplugging the USB device. I have chosen a simple method over a faster one, because making a faster solution takes some more time to investigate, and I don't have that time right now. usb_hub.c: - overload the "bandwidth_reclaimed" bit-flag, which should only be used for the UHCI. When used with the EHCI it means we have allocated bandwidth for a high speed endpoint. This bit is checked when allocating and freeing to avoid duplicate operations. At least the close method of a USB transfer type can be called two times in a row, with only one open, due to the current design. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#51 edit .. //depot/projects/usb/src/sys/dev/usb/usb_hub.c#43 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#51 (text+ko) ==== @@ -1352,22 +1352,32 @@ } } else if (methods == &ehci_device_isoc_hs_methods) { ehci_itd_t *td; - uint8_t n = (xfer->nframes & 7); /* isochronous high speed transfer */ /* check last transfer */ td = xfer->td_transfer_last; usb_pc_cpu_invalidate(td->page_cache); - if (n == 0) - status = td->itd_status[7]; - else - status = td->itd_status[n-1]; + status = td->itd_status[0]; + status |= td->itd_status[1]; + status |= td->itd_status[2]; + status |= td->itd_status[3]; + status |= td->itd_status[4]; + status |= td->itd_status[5]; + status |= td->itd_status[6]; + status |= td->itd_status[7]; /* also check first transfer */ td = xfer->td_transfer_first; usb_pc_cpu_invalidate(td->page_cache); status |= td->itd_status[0]; + status |= td->itd_status[1]; + status |= td->itd_status[2]; + status |= td->itd_status[3]; + status |= td->itd_status[4]; + status |= td->itd_status[5]; + status |= td->itd_status[6]; + status |= td->itd_status[7]; /* if no transactions are active we continue */ if (!(status & htohc32(sc, EHCI_ITD_ACTIVE))) { @@ -2799,14 +2809,15 @@ uint8_t x; uint8_t td_no; uint8_t page_no; + uint8_t shift = usbd_xfer_get_fps_shift(xfer); #ifdef USB_DEBUG uint8_t once = 1; #endif - DPRINTFN(6, "xfer=%p next=%d nframes=%d\n", - xfer, xfer->endpoint->isoc_next, xfer->nframes); + DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n", + xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift); /* get the current frame index */ @@ -2820,7 +2831,7 @@ (EHCI_VIRTUAL_FRAMELIST_COUNT - 1); if ((xfer->endpoint->is_synced == 0) || - (buf_offset < ((xfer->nframes + 7) / 8))) { + (buf_offset < (((xfer->nframes << shift) + 7) / 8))) { /* * If there is data underflow or the pipe queue is empty we * schedule the transfer a few frames ahead of the current @@ -2844,7 +2855,7 @@ */ xfer->isoc_time_complete = usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset + - ((xfer->nframes + 7) / 8); + (((xfer->nframes << shift) + 7) / 8); /* get the real number of frames */ ==== //depot/projects/usb/src/sys/dev/usb/usb_hub.c#43 (text+ko) ==== @@ -1230,6 +1230,11 @@ if (udev->flags.usb_mode != USB_MODE_HOST) return; /* not supported */ + if (xfer->flags_int.bandwidth_reclaimed != 0) + return; /* bandwidth already allocated */ + + xfer->flags_int.bandwidth_reclaimed = 1; + xfer->endpoint->refcount_bw++; if (xfer->endpoint->refcount_bw != 1) return; /* already allocated */ @@ -1310,6 +1315,11 @@ if (udev->flags.usb_mode != USB_MODE_HOST) return; /* not supported */ + if (xfer->flags_int.bandwidth_reclaimed == 0) + return; /* bandwidth already freed */ + + xfer->flags_int.bandwidth_reclaimed = 0; + xfer->endpoint->refcount_bw--; if (xfer->endpoint->refcount_bw != 0) return; /* still allocated */