From owner-p4-projects@FreeBSD.ORG Sat Jan 27 15:01:03 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B996916A407; Sat, 27 Jan 2007 15:01:03 +0000 (UTC) X-Original-To: perforce@FreeBSD.org 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 78D6016A402 for ; Sat, 27 Jan 2007 15:01:03 +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 D4A0713C46E for ; Sat, 27 Jan 2007 15:01:02 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l0RF12aD083478 for ; Sat, 27 Jan 2007 15:01:02 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l0RF12C3083473 for perforce@freebsd.org; Sat, 27 Jan 2007 15:01:02 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 27 Jan 2007 15:01:02 GMT Message-Id: <200701271501.l0RF12C3083473@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 Cc: Subject: PERFORCE change 113598 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Jan 2007 15:01:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=113598 Change 113598 by hselasky@hselasky_mini_itx on 2007/01/27 15:00:54 Make the isochronous end-of-transfer timestamp 16-bits in width. This simplifies the USB device drivers doing echo-cancelling for example. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/ehci.c#25 edit .. //depot/projects/usb/src/sys/dev/usb/ohci.c#19 edit .. //depot/projects/usb/src/sys/dev/usb/uhci.c#21 edit .. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#27 edit .. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#32 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/ehci.c#25 (text+ko) ==== @@ -2458,11 +2458,18 @@ DPRINTFN(5,("xfer=%p next=%d nframes=%d\n", xfer, xfer->pipe->isoc_next, xfer->nframes)); + /* get the current frame index */ + nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; - if(((nframes - xfer->pipe->isoc_next) & - (EHCI_VIRTUAL_FRAMELIST_COUNT-1)) < xfer->nframes) - { + /* check if the frame index is within + * the window where the frames will be + * inserted + */ + buf_offset = (nframes - xfer->pipe->isoc_next) & + (EHCI_VIRTUAL_FRAMELIST_COUNT-1); + + if (buf_offset < xfer->nframes) { /* not in use yet, schedule it a few frames ahead */ /* data underflow */ xfer->pipe->isoc_next = (nframes + 3) & @@ -2470,7 +2477,21 @@ DPRINTFN(2,("start next=%d\n", xfer->pipe->isoc_next)); } - xfer->isoc_complete_time = (xfer->pipe->isoc_next + xfer->nframes) % USBD_ISOC_TIME_MAX; + /* compute how many milliseconds the + * insertion is ahead of the current + * frame position: + */ + buf_offset = (xfer->pipe->isoc_next - nframes) & + (EHCI_VIRTUAL_FRAMELIST_COUNT-1); + + /* pre-compute when the isochronous transfer + * will be finished: + */ + xfer->isoc_time_complete = + usbd_isoc_time_expand(&(sc->sc_bus), nframes) + buf_offset + + xfer->nframes; + + /* get the real number of frames */ nframes = xfer->nframes; @@ -2693,11 +2714,18 @@ DPRINTFN(5,("xfer=%p next=%d nframes=%d\n", xfer, xfer->pipe->isoc_next, xfer->nframes)); + /* get the current frame index */ + nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; - if(((nframes - xfer->pipe->isoc_next) & - (EHCI_VIRTUAL_FRAMELIST_COUNT-1)) < xfer->nframes) - { + /* check if the frame index is within + * the window where the frames will be + * inserted + */ + buf_offset = (nframes - xfer->pipe->isoc_next) & + (EHCI_VIRTUAL_FRAMELIST_COUNT-1); + + if (buf_offset < xfer->nframes) { /* not in use yet, schedule it a few frames ahead */ /* data underflow */ xfer->pipe->isoc_next = (nframes + 3) & @@ -2705,7 +2733,21 @@ DPRINTFN(2,("start next=%d\n", xfer->pipe->isoc_next)); } - xfer->isoc_complete_time = (xfer->pipe->isoc_next + ((xfer->nframes+7)/8)) % USBD_ISOC_TIME_MAX; + /* compute how many milliseconds the + * insertion is ahead of the current + * frame position: + */ + buf_offset = (xfer->pipe->isoc_next - nframes) & + (EHCI_VIRTUAL_FRAMELIST_COUNT-1); + + /* pre-compute when the isochronous transfer + * will be finished: + */ + xfer->isoc_time_complete = + usbd_isoc_time_expand(&(sc->sc_bus), nframes) + buf_offset + + ((xfer->nframes+7)/8); + + /* get the real number of frames */ nframes = xfer->nframes; ==== //depot/projects/usb/src/sys/dev/usb/ohci.c#19 (text+ko) ==== @@ -1896,16 +1896,34 @@ nframes = le32toh(hw_ptr->hcca.hcca_frame_number); usbd_page_dma_enter(&(sc->sc_hw_page)); - if((((nframes - xfer->pipe->isoc_next) & ((1<<16)-1)) < xfer->nframes) || - (((xfer->pipe->isoc_next - nframes) & ((1<<16)-1)) >= 256)) + /* check if the frame index is within + * the window where the frames will be + * inserted and if the delay until start + * is too long + */ + if ((((nframes - xfer->pipe->isoc_next) & 0xFFFF) < xfer->nframes) || + (((xfer->pipe->isoc_next - nframes) & 0xFFFF) >= 128)) { /* not in use yet, schedule it a few frames ahead */ /* data underflow */ - xfer->pipe->isoc_next = (nframes + 5) & ((1<<16)-1); + xfer->pipe->isoc_next = (nframes + 3) & 0xFFFF; DPRINTFN(2,("start next=%d\n", xfer->pipe->isoc_next)); } - xfer->isoc_complete_time = (xfer->pipe->isoc_next + xfer->nframes) % USBD_ISOC_TIME_MAX; + /* compute how many milliseconds the + * insertion is ahead of the current + * frame position: + */ + buf_offset = ((xfer->pipe->isoc_next - nframes) & 0xFFFF); + + /* pre-compute when the isochronous transfer + * will be finished: + */ + xfer->isoc_time_complete = + (usbd_isoc_time_expand(&(sc->sc_bus), nframes) + buf_offset + + xfer->nframes); + + /* get the real number of frames */ nframes = xfer->nframes; ==== //depot/projects/usb/src/sys/dev/usb/uhci.c#21 (text+ko) ==== @@ -1998,16 +1998,31 @@ nframes = UREAD2(sc, UHCI_FRNUM); - if(((nframes - xfer->pipe->isoc_next) & - (UHCI_VFRAMELIST_COUNT-1)) < xfer->nframes) - { + buf_offset = (nframes - xfer->pipe->isoc_next) & + (UHCI_VFRAMELIST_COUNT-1); + + if (buf_offset < xfer->nframes) { /* not in use yet, schedule it a few frames ahead */ /* data underflow */ xfer->pipe->isoc_next = (nframes + 3) & (UHCI_VFRAMELIST_COUNT-1); DPRINTFN(2,("start next=%d\n", xfer->pipe->isoc_next)); } - xfer->isoc_complete_time = (xfer->pipe->isoc_next + xfer->nframes) % USBD_ISOC_TIME_MAX; + /* compute how many milliseconds the + * insertion is ahead of the current + * frame position: + */ + buf_offset = (xfer->pipe->isoc_next - nframes) & + (UHCI_VFRAMELIST_COUNT-1); + + /* pre-compute when the isochronous transfer + * will be finished: + */ + xfer->isoc_time_complete = + usbd_isoc_time_expand(&(sc->sc_bus), nframes) + buf_offset + + xfer->nframes; + + /* get the real number of frames */ nframes = xfer->nframes; ==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#27 (text+ko) ==== @@ -2774,3 +2774,30 @@ USETW(edesc->wMaxPacketSize, n); return; } + +/*---------------------------------------------------------------------------* + * usbd_isoc_time_expand - expand time counter from 7-bit to 16-bit + *---------------------------------------------------------------------------*/ +uint16_t +usbd_isoc_time_expand(struct usbd_bus *bus, uint16_t isoc_time_curr) +{ + uint16_t rem; + + mtx_assert(&(bus->mtx), MA_OWNED); + + rem = bus->isoc_time_last & (USBD_ISOC_TIME_MAX-1); + + isoc_time_curr &= (USBD_ISOC_TIME_MAX-1); + + if (isoc_time_curr < rem) { + /* the time counter wrapped around */ + bus->isoc_time_last += USBD_ISOC_TIME_MAX; + } + + /* update the remainder */ + + bus->isoc_time_last &= ~(USBD_ISOC_TIME_MAX-1); + bus->isoc_time_last |= isoc_time_curr; + + return bus->isoc_time_last; +} ==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#32 (text+ko) ==== @@ -178,6 +178,9 @@ uint32_t no_intrs; + uint16_t isoc_time_last; /* ms */ +#define USBD_ISOC_TIME_MAX 128 /* ms */ + uint8_t is_exploring; uint8_t wait_explore; uint8_t needs_explore;/* Set if a hub signalled a change. @@ -361,10 +364,8 @@ uint16_t max_packet_size; uint16_t max_frame_size; uint16_t qh_pos; + uint16_t isoc_time_complete; /* in ms */ -#define USBD_ISOC_TIME_MAX 128 /* ms */ - - uint8_t isoc_complete_time; /* in ms */ uint8_t address; uint8_t endpoint; uint8_t interval; /* milliseconds */ @@ -602,6 +603,7 @@ uint16_t usbd_get_max_packet_count(usb_endpoint_descriptor_t *edesc); uint16_t usbd_get_max_frame_size(usb_endpoint_descriptor_t *edesc); void usbd_set_max_packet_size_count(usb_endpoint_descriptor_t *edesc, uint16_t size, uint16_t count); +uint16_t usbd_isoc_time_expand(struct usbd_bus *bus, uint16_t isoc_time_curr); /* prototypes from usb.c */