From owner-p4-projects@FreeBSD.ORG Tue Jan 16 23:33:10 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 BDCF416A417; Tue, 16 Jan 2007 23:33:10 +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 99FEE16A412 for ; Tue, 16 Jan 2007 23:33:10 +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 8999713C467 for ; Tue, 16 Jan 2007 23:33:10 +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 l0GNXA5Q059448 for ; Tue, 16 Jan 2007 23:33:10 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l0GNX9S2059444 for perforce@freebsd.org; Tue, 16 Jan 2007 23:33:09 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 16 Jan 2007 23:33:09 GMT Message-Id: <200701162333.l0GNX9S2059444@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 113031 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: Tue, 16 Jan 2007 23:33:11 -0000 http://perforce.freebsd.org/chv.cgi?CH=113031 Change 113031 by hselasky@hselasky_mini_itx on 2007/01/16 23:32:59 Implement proper support for high speed isochronous and interrupt transfer multiplier, bits 11..12 of wMaxPacketSize. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/ehci.c#15 edit .. //depot/projects/usb/src/sys/dev/usb/ohci.c#13 edit .. //depot/projects/usb/src/sys/dev/usb/ugen.c#10 edit .. //depot/projects/usb/src/sys/dev/usb/uhci.c#14 edit .. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#23 edit .. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#27 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/ehci.c#15 (text+ko) ==== @@ -1672,7 +1672,7 @@ } qh->qh_endphub = htole32 - (EHCI_QH_SET_MULT(1)| + (EHCI_QH_SET_MULT(xfer->max_packet_count & 3)| EHCI_QH_SET_CMASK(0xf0)); if(xfer->udev->myhsport) @@ -2519,7 +2519,7 @@ } /* set transfer multiplier */ - td->itd_bp[2] = htole32(1); + td->itd_bp[2] = htole32(xfer->max_packet_count & 3); } return; } @@ -3545,8 +3545,11 @@ (xfer->pipe->methods == &ehci_device_bulk_methods) || (xfer->pipe->methods == &ehci_device_intr_methods)) { - usbd_std_transfer_setup(xfer, setup, 0x400, 0x400); - + if ((xfer->pipe->methods == &ehci_device_intr_methods) && + (udev->speed == USB_SPEED_HIGH)) + usbd_std_transfer_setup(xfer, setup, 0x400, 0xC00, 3); + else + usbd_std_transfer_setup(xfer, setup, 0x400, 0x400, 1); nqh = 1; nqtd = (1+ /* SETUP */ 1+ /* STATUS */ 1 /* SHORTPKT */) + @@ -3554,7 +3557,7 @@ } else if(xfer->pipe->methods == &ehci_device_isoc_fs_methods) { - usbd_std_transfer_setup(xfer, setup, 188, 188); + usbd_std_transfer_setup(xfer, setup, 188, 188, 1); if(xfer->nframes == 0) { @@ -3578,7 +3581,7 @@ } else if(xfer->pipe->methods == &ehci_device_isoc_hs_methods) { - usbd_std_transfer_setup(xfer, setup, 0x400, 0xC00); + usbd_std_transfer_setup(xfer, setup, 0x400, 0xC00, 3); if(xfer->nframes == 0) { @@ -3602,7 +3605,7 @@ } else { - usbd_std_transfer_setup(xfer, setup, 0x400, 0x400); + usbd_std_transfer_setup(xfer, setup, 0x400, 0x400, 1); } } ==== //depot/projects/usb/src/sys/dev/usb/ohci.c#13 (text+ko) ==== @@ -2614,7 +2614,7 @@ } else { - usbd_std_transfer_setup(xfer, setup, 0x500, 0x500); + usbd_std_transfer_setup(xfer, setup, 0x500, 0x500, 1); /* * calculate ntd and nqh ==== //depot/projects/usb/src/sys/dev/usb/ugen.c#10 (text+ko) ==== @@ -642,9 +642,9 @@ break; case UE_ISOCHRONOUS: - isize = UGETW(ed->wMaxPacketSize); + isize = usbd_get_max_frame_size(ed); - /* wMaxPacketSize is validated + /* the maximum frame size is validated * by "usbd_fill_iface_data()" */ @@ -736,14 +736,15 @@ switch(ed->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: + isize = usbd_get_max_frame_size(ed); usbd_config[0].flags = USBD_SHORT_XFER_OK; usbd_config[0].callback = ugen_interrupt_callback; - usbd_config[0].bufsize = UGETW(ed->wMaxPacketSize); + usbd_config[0].bufsize = isize; usbd_config[0].interval = USBD_DEFAULT_INTERVAL; if(ugen_allocate_blocks (sc, sce, UGEN_RD_CFG, - &sce->in_queue, 1, UGETW(ed->wMaxPacketSize)) == 0) + &sce->in_queue, 1, isize) == 0) { return ENOMEM; } @@ -786,9 +787,11 @@ case UE_ISOCHRONOUS: - isize = UGETW(ed->wMaxPacketSize); + isize = usbd_get_max_frame_size(ed); - /* wMaxPacketSize is validated by "usbd_fill_iface_data()" */ + /* the maximum frame size is validated + * by "usbd_fill_iface_data()" + */ if(usbd_get_speed(sc->sc_udev) == USB_SPEED_HIGH) { @@ -1385,7 +1388,7 @@ plen1 = xfer->frlengths; ptr1 = xfer->buffer; - isize = UGETW(sce->pipe_in->edesc->wMaxPacketSize); + isize = usbd_get_max_frame_size(sce->pipe_in->edesc); n = sce->in_frames; while(n--) { @@ -1423,7 +1426,7 @@ tr_setup: tr_error: - isize = UGETW(sce->pipe_in->edesc->wMaxPacketSize); + isize = usbd_get_max_frame_size(sce->pipe_in->edesc); for(n = 0; n < sce->in_frames; n++) { /* setup size for next transfer */ @@ -1454,7 +1457,7 @@ plen1 = xfer->frlengths; ptr1 = xfer->buffer; - isize = UGETW(sce->pipe_out->edesc->wMaxPacketSize); + isize = usbd_get_max_frame_size(sce->pipe_out->edesc); n = sce->out_frames; while(n--) { @@ -1663,7 +1666,7 @@ case USB_GET_FRAME_SIZE: if(sce->pipe_in) { - *(int *)addr = UGETW(sce->pipe_in->edesc->wMaxPacketSize); + *(int *)addr = usbd_get_max_frame_size(sce->pipe_in->edesc); } else { ==== //depot/projects/usb/src/sys/dev/usb/uhci.c#14 (text+ko) ==== @@ -2873,7 +2873,7 @@ } else { - usbd_std_transfer_setup(xfer, setup, 0x500, 0x500); + usbd_std_transfer_setup(xfer, setup, 0x500, 0x500, 1); /* * compute ntd and nqh ==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#23 (text+ko) ==== @@ -512,38 +512,27 @@ if(udev->speed == USB_SPEED_HIGH) { - u_int16_t mps; - /* control and bulk endpoints have max packet limits */ + /* control and bulk endpoints have fixed max packet sizes */ switch (UE_GET_XFERTYPE(ed->bmAttributes)) { case UE_CONTROL: - mps = USB_2_MAX_CTRL_PACKET; - goto check; + USETW(ed->wMaxPacketSize, USB_2_MAX_CTRL_PACKET); + break; case UE_BULK: - mps = USB_2_MAX_BULK_PACKET; - check: - if(UGETW(ed->wMaxPacketSize) != mps) - { - USETW(ed->wMaxPacketSize, mps); -#ifdef DIAGNOSTIC - printf("%s: bad wMaxPacketSize, addr=%d!\n", - __FUNCTION__, udev->address); -#endif - } - break; - default: + USETW(ed->wMaxPacketSize, USB_2_MAX_BULK_PACKET); break; } } - if(UGETW(ed->wMaxPacketSize) == 0) - { + + if (usbd_get_max_frame_size(ed) == 0) { #ifdef USB_DEBUG - printf("%s: invalid wMaxPacketSize, addr=%d!\n", - __FUNCTION__, udev->address); + printf("%s: invalid wMaxPacketSize=0x%04x, addr=%d!\n", + __FUNCTION__, UGETW(ed->wMaxPacketSize), + udev->address); #endif - /* avoid division by zero - * (in EHCI/UHCI/OHCI drivers) - */ - USETW(ed->wMaxPacketSize, USB_MAX_IPACKET); + /* avoid division by zero + * (in EHCI/UHCI/OHCI drivers) + */ + usbd_set_max_packet_size_count(ed, USB_MAX_IPACKET, 1); } /* find a free pipe */ @@ -1293,20 +1282,13 @@ if(speed == USB_SPEED_HIGH) { /* max packet size must be 64 (sec 5.5.3) */ - if(udev->ddesc.bMaxPacketSize != USB_2_MAX_CTRL_PACKET) - { -#ifdef DIAGNOSTIC - printf("%s: addr=%d bad max packet size\n", - __FUNCTION__, udev->address); -#endif - udev->ddesc.bMaxPacketSize = USB_2_MAX_CTRL_PACKET; - } + udev->ddesc.bMaxPacketSize = USB_2_MAX_CTRL_PACKET; } if(udev->ddesc.bMaxPacketSize == 0) { #ifdef USB_DEBUG - printf("%s: addr=%d invalid bMaxPacketSize!\n", + printf("%s: addr=%d invalid bMaxPacketSize=0x00!\n", __FUNCTION__, udev->address); #endif /* avoid division by zero */ @@ -2212,7 +2194,8 @@ void usbd_std_transfer_setup(struct usbd_xfer *xfer, const struct usbd_config *setup, - u_int16_t max_packet_size, u_int16_t max_frame_size) + u_int16_t max_packet_size, u_int16_t max_frame_size, + uint8_t max_packet_count) { __callout_init_mtx(&xfer->timeout_handle, xfer->usb_mtx, CALLOUT_RETURNUNLOCKED); @@ -2223,16 +2206,18 @@ xfer->callback = setup->callback; xfer->interval = setup->interval; xfer->endpoint = xfer->pipe->edesc->bEndpointAddress; - xfer->max_packet_size = UGETW(xfer->pipe->edesc->wMaxPacketSize); + xfer->max_packet_size = usbd_get_max_packet_size(xfer->pipe->edesc); + xfer->max_packet_count = usbd_get_max_packet_count(xfer->pipe->edesc); + xfer->max_frame_size = usbd_get_max_frame_size(xfer->pipe->edesc); xfer->length = setup->bufsize; - if(xfer->interval == 0) - { + /* check interrupt interval */ + + if (xfer->interval == 0) { xfer->interval = xfer->pipe->edesc->bInterval; } - if(xfer->interval == 0) - { + if (xfer->interval == 0) { /* one is the smallest interval */ xfer->interval = 1; } @@ -2247,18 +2232,27 @@ xfer->max_packet_size = max_packet_size; } - /* frame_size: isochronous frames only */ + /* check the maximum packet count */ + + if (xfer->max_packet_count == 0) { + xfer->max_packet_count = 1; + } + + if (xfer->max_packet_count > max_packet_count) { + xfer->max_packet_count = max_packet_count; + } + + /* check the maximum frame size */ - xfer->max_frame_size = max_frame_size; + if (xfer->max_frame_size > max_frame_size) { + xfer->max_frame_size = max_frame_size; + } if (xfer->length == 0) { - xfer->length = xfer->max_packet_size; + xfer->length = xfer->max_frame_size; if (xfer->nframes) { xfer->length *= xfer->nframes; } - if (setup->sub_frames) { - xfer->length *= setup->sub_frames; - } } return; } @@ -2677,3 +2671,45 @@ } return error; } + +/*---------------------------------------------------------------------------* + * usbd_get_max_packet_size - get maximum packet size + *---------------------------------------------------------------------------*/ +uint16_t +usbd_get_max_packet_size(usb_endpoint_descriptor_t *edesc) +{ + return (UGETW(edesc->wMaxPacketSize) & 0x7FF); +} + +/*---------------------------------------------------------------------------* + * usbd_get_max_packet_count - get maximum packet count + *---------------------------------------------------------------------------*/ +uint16_t +usbd_get_max_packet_count(usb_endpoint_descriptor_t *edesc) +{ + return (1 + ((UGETW(edesc->wMaxPacketSize) >> 11) & 3)); +} + +/*---------------------------------------------------------------------------* + * usbd_get_max_frame_size - get maximum frame size + *---------------------------------------------------------------------------*/ +uint16_t +usbd_get_max_frame_size(usb_endpoint_descriptor_t *edesc) +{ + uint16_t n; + n = UGETW(edesc->wMaxPacketSize); + return (n & 0x7FF) * (1 + ((n >> 11) & 3)); +} + +/*---------------------------------------------------------------------------* + * usbd_set_max_packet_size_count - set maximum packet size and count + *---------------------------------------------------------------------------*/ +void +usbd_set_max_packet_size_count(usb_endpoint_descriptor_t *edesc, + uint16_t size, uint16_t count) +{ + uint16_t n; + n = (size & 0x7FF)|(((count-1) & 3) << 11); + USETW(edesc->wMaxPacketSize, n); + return; +} ==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#27 (text+ko) ==== @@ -279,11 +279,6 @@ * used in isochronous * mode */ - u_int8_t sub_frames; /* number of sub-frames - * contained within each - * frame. Used in High-Speed - * isochronous mode. - */ u_int8_t index; /* pipe index to use, if more * than one descriptor matches * type, address, direction ... @@ -376,6 +371,7 @@ u_int8_t address; u_int8_t endpoint; u_int8_t interval; /* milliseconds */ + uint8_t max_packet_count; u_int16_t max_packet_size; u_int16_t max_frame_size; @@ -702,9 +698,8 @@ #endif #endif -void -usbd_std_transfer_setup(struct usbd_xfer *xfer, const struct usbd_config *setup, - u_int16_t max_packet_size, u_int16_t max_frame_size); +void usbd_std_transfer_setup(struct usbd_xfer *xfer, const struct usbd_config *setup, u_int16_t max_packet_size, u_int16_t max_frame_size, uint8_t max_packet_count); + u_int8_t usbd_make_str_desc(void *ptr, u_int16_t max_len, const char *s); @@ -741,6 +736,12 @@ int32_t device_delete_all_children(device_t dev); +uint16_t usbd_get_max_packet_size(usb_endpoint_descriptor_t *edesc); +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); + /* routines from usb.c */ #if 0