From owner-p4-projects@FreeBSD.ORG Fri Mar 20 09:35:36 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1CB861065673; Fri, 20 Mar 2009 09:35:36 +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 CF9A81065672 for ; Fri, 20 Mar 2009 09:35:35 +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 BCA8B8FC13 for ; Fri, 20 Mar 2009 09:35:35 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n2K9ZZB9039823 for ; Fri, 20 Mar 2009 09:35:35 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n2K9ZZm6039821 for perforce@freebsd.org; Fri, 20 Mar 2009 09:35:35 GMT (envelope-from hselasky@FreeBSD.org) Date: Fri, 20 Mar 2009 09:35:35 GMT Message-Id: <200903200935.n2K9ZZm6039821@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 159502 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: Fri, 20 Mar 2009 09:35:37 -0000 http://perforce.freebsd.org/chv.cgi?CH=159502 Change 159502 by hselasky@hselasky_laptop001 on 2009/03/20 09:34:56 USB controller: - get Device Side drivers in line with Host Side drivers regarding the recent short control transfer patches. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/controller/at91dci.c#5 edit .. //depot/projects/usb/src/sys/dev/usb/controller/atmegadci.c#9 edit .. //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#9 edit .. //depot/projects/usb/src/sys/dev/usb/controller/musb_otg.c#4 edit .. //depot/projects/usb/src/sys/dev/usb/controller/ohci.c#6 edit .. //depot/projects/usb/src/sys/dev/usb/controller/uhci.c#5 edit .. //depot/projects/usb/src/sys/dev/usb/controller/uss820dci.c#5 edit .. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#133 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/controller/at91dci.c#5 (text+ko) ==== @@ -887,7 +887,6 @@ temp.td = NULL; temp.td_next = xfer->td_start[0]; - temp.setup_alt_next = xfer->flags_int.short_frames_ok; temp.offset = 0; sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); @@ -902,6 +901,7 @@ temp.len = xfer->frlengths[0]; temp.pc = xfer->frbuffers + 0; temp.short_pkt = temp.len ? 1 : 0; + temp.setup_alt_next = 0; at91dci_setup_standard_chain_sub(&temp); } @@ -910,6 +910,8 @@ x = 0; } + temp.setup_alt_next = xfer->flags_int.short_frames_ok; + if (x != xfer->nframes) { if (xfer->endpoint & UE_DIR_IN) { temp.func = &at91dci_data_tx; @@ -933,7 +935,13 @@ x++; if (x == xfer->nframes) { - temp.setup_alt_next = 0; + if (xfer->flags_int.control_xfr) { + if (xfer->flags_int.control_act) { + temp.setup_alt_next = 0; + } + } else { + temp.setup_alt_next = 0; + } } if (temp.len == 0) { @@ -958,47 +966,46 @@ } } - /* always setup a valid "pc" pointer for status and sync */ - temp.pc = xfer->frbuffers + 0; + /* check for control transfer */ + if (xfer->flags_int.control_xfer) { - /* check if we need to sync */ - if (need_sync && xfer->flags_int.control_xfr) { - - /* we need a SYNC point after TX */ - temp.func = &at91dci_data_tx_sync; + /* always setup a valid "pc" pointer for status and sync */ + temp.pc = xfer->frbuffers + 0; temp.len = 0; temp.short_pkt = 0; + temp.setup_alt_next = 0; - at91dci_setup_standard_chain_sub(&temp); - } - /* check if we should append a status stage */ - if (xfer->flags_int.control_xfr && - !xfer->flags_int.control_act) { - - /* - * Send a DATA1 message and invert the current - * endpoint direction. - */ - if (xfer->endpoint & UE_DIR_IN) { - temp.func = &at91dci_data_rx; - need_sync = 0; - } else { - temp.func = &at91dci_data_tx; - need_sync = 1; - } - temp.len = 0; - temp.short_pkt = 0; - - at91dci_setup_standard_chain_sub(&temp); + /* check if we need to sync */ if (need_sync) { /* we need a SYNC point after TX */ temp.func = &at91dci_data_tx_sync; - temp.len = 0; - temp.short_pkt = 0; + at91dci_setup_standard_chain_sub(&temp); + } + + /* check if we should append a status stage */ + if (!xfer->flags_int.control_act) { + + /* + * Send a DATA1 message and invert the current + * endpoint direction. + */ + if (xfer->endpoint & UE_DIR_IN) { + temp.func = &at91dci_data_rx; + need_sync = 0; + } else { + temp.func = &at91dci_data_tx; + need_sync = 1; + } at91dci_setup_standard_chain_sub(&temp); + if (need_sync) { + /* we need a SYNC point after TX */ + temp.func = &at91dci_data_tx_sync; + at91dci_setup_standard_chain_sub(&temp); + } } } + /* must have at least one frame! */ td = temp.td; xfer->td_transfer_last = td; ==== //depot/projects/usb/src/sys/dev/usb/controller/atmegadci.c#9 (text+ko) ==== @@ -791,7 +791,6 @@ temp.td = NULL; temp.td_next = xfer->td_start[0]; - temp.setup_alt_next = xfer->flags_int.short_frames_ok; temp.offset = 0; sc = ATMEGA_BUS2SC(xfer->xroot->bus); @@ -806,6 +805,7 @@ temp.len = xfer->frlengths[0]; temp.pc = xfer->frbuffers + 0; temp.short_pkt = temp.len ? 1 : 0; + temp.setup_alt_next = 0; atmegadci_setup_standard_chain_sub(&temp); } @@ -814,6 +814,8 @@ x = 0; } + temp.setup_alt_next = xfer->flags_int.short_frames_ok; + if (x != xfer->nframes) { if (xfer->endpoint & UE_DIR_IN) { temp.func = &atmegadci_data_tx; @@ -837,7 +839,13 @@ x++; if (x == xfer->nframes) { - temp.setup_alt_next = 0; + if (xfer->flags_int.control_xfr) { + if (xfer->flags_int.control_act) { + temp.setup_alt_next = 0; + } + } else { + temp.setup_alt_next = 0; + } } if (temp.len == 0) { @@ -862,45 +870,42 @@ } } - /* always setup a valid "pc" pointer for status and sync */ - temp.pc = xfer->frbuffers + 0; + if (xfer->flags_int.control_xfr) { - /* check if we need to sync */ - if (need_sync && xfer->flags_int.control_xfr) { - - /* we need a SYNC point after TX */ - temp.func = &atmegadci_data_tx_sync; + /* always setup a valid "pc" pointer for status and sync */ + temp.pc = xfer->frbuffers + 0; temp.len = 0; temp.short_pkt = 0; + temp.setup_alt_next = 0; - atmegadci_setup_standard_chain_sub(&temp); - } - /* check if we should append a status stage */ - if (xfer->flags_int.control_xfr && - !xfer->flags_int.control_act) { - - /* - * Send a DATA1 message and invert the current - * endpoint direction. - */ - if (xfer->endpoint & UE_DIR_IN) { - temp.func = &atmegadci_data_rx; - need_sync = 0; - } else { - temp.func = &atmegadci_data_tx; - need_sync = 1; - } - temp.len = 0; - temp.short_pkt = 0; - - atmegadci_setup_standard_chain_sub(&temp); + /* check if we need to sync */ if (need_sync) { /* we need a SYNC point after TX */ temp.func = &atmegadci_data_tx_sync; - temp.len = 0; - temp.short_pkt = 0; + atmegadci_setup_standard_chain_sub(&temp); + } + + /* check if we should append a status stage */ + if (!xfer->flags_int.control_act) { + + /* + * Send a DATA1 message and invert the current + * endpoint direction. + */ + if (xfer->endpoint & UE_DIR_IN) { + temp.func = &atmegadci_data_rx; + need_sync = 0; + } else { + temp.func = &atmegadci_data_tx; + need_sync = 1; + } atmegadci_setup_standard_chain_sub(&temp); + if (need_sync) { + /* we need a SYNC point after TX */ + temp.func = &atmegadci_data_tx_sync; + atmegadci_setup_standard_chain_sub(&temp); + } } } /* must have at least one frame! */ ==== //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#9 (text+ko) ==== @@ -1784,7 +1784,6 @@ temp.len = xfer->frlengths[0]; temp.pc = xfer->frbuffers + 0; temp.shortpkt = temp.len ? 1 : 0; - /* no "alt_next" for SETUP stage */ temp.setup_alt_next = 0; /* check for last frame */ if (xfer->nframes == 1) { ==== //depot/projects/usb/src/sys/dev/usb/controller/musb_otg.c#4 (text+ko) ==== @@ -1132,7 +1132,6 @@ temp.td = NULL; temp.td_next = xfer->td_start[0]; - temp.setup_alt_next = xfer->flags_int.short_frames_ok; temp.offset = 0; sc = MUSBOTG_BUS2SC(xfer->xroot->bus); @@ -1147,6 +1146,7 @@ temp.len = xfer->frlengths[0]; temp.pc = xfer->frbuffers + 0; temp.short_pkt = temp.len ? 1 : 0; + temp.setup_alt_next = 0; musbotg_setup_standard_chain_sub(&temp); } @@ -1155,6 +1155,8 @@ x = 0; } + temp.setup_alt_next = xfer->flags_int.short_frames_ok; + if (x != xfer->nframes) { if (xfer->endpoint & UE_DIR_IN) { if (xfer->flags_int.control_xfr) @@ -1180,7 +1182,13 @@ x++; if (x == xfer->nframes) { - temp.setup_alt_next = 0; + if (xfer->flags_int.control_xfr) { + if (xfer->flags_int.control_act) { + temp.setup_alt_next = 0; + } + } else { + temp.setup_alt_next = 0; + } } if (temp.len == 0) { @@ -1205,23 +1213,24 @@ } } - /* always setup a valid "pc" pointer for status and sync */ - temp.pc = xfer->frbuffers + 0; + /* check for control transfer */ + if (xfer->flags_int.control_xfr) { - /* check if we should append a status stage */ - - if (xfer->flags_int.control_xfr && - !xfer->flags_int.control_act) { - - /* - * Send a DATA1 message and invert the current - * endpoint direction. - */ - temp.func = &musbotg_setup_status; + /* always setup a valid "pc" pointer for status and sync */ + temp.pc = xfer->frbuffers + 0; temp.len = 0; temp.short_pkt = 0; + temp.setup_alt_next = 0; - musbotg_setup_standard_chain_sub(&temp); + /* check if we should append a status stage */ + if (!xfer->flags_int.control_act) { + /* + * Send a DATA1 message and invert the current + * endpoint direction. + */ + temp.func = &musbotg_setup_status; + musbotg_setup_standard_chain_sub(&temp); + } } /* must have at least one frame! */ td = temp.td; ==== //depot/projects/usb/src/sys/dev/usb/controller/ohci.c#6 (text+ko) ==== @@ -1439,7 +1439,6 @@ temp.len = xfer->frlengths[0]; temp.pc = xfer->frbuffers + 0; temp.shortpkt = temp.len ? 1 : 0; - /* no "alt_next" for SETUP stage */ temp.setup_alt_next = 0; /* check for last frame */ if (xfer->nframes == 1) { ==== //depot/projects/usb/src/sys/dev/usb/controller/uhci.c#5 (text+ko) ==== @@ -1253,32 +1253,29 @@ td_self = td->td_self; td_alt_next = td->alt_next; - if ((xfer->flags_int.control_xfr) && - (!xfer->flags_int.control_act) && - (((void *)td) == xfer->td_transfer_last)) - goto skip; /* don't touch DT value on STATUS stage */ + if (xfer->flags_int.control_xfr) + goto skip; /* don't touch the DT value! */ - if ((td->td_token ^ td_token) & htole32(UHCI_TD_SET_DT(1))) { - /* - * The data toggle is wrong and - * we need to switch it ! - */ + if (!((td->td_token ^ td_token) & htole32(UHCI_TD_SET_DT(1)))) + goto skip; /* data toggle has correct value */ - while (1) { + /* + * The data toggle is wrong and we need to toggle it ! + */ + while (1) { - td->td_token ^= htole32(UHCI_TD_SET_DT(1)); - usb2_pc_cpu_flush(td->page_cache); + td->td_token ^= htole32(UHCI_TD_SET_DT(1)); + usb2_pc_cpu_flush(td->page_cache); - if (td == xfer->td_transfer_last) { - /* last transfer */ - break; - } - td = td->obj_next; + if (td == xfer->td_transfer_last) { + /* last transfer */ + break; + } + td = td->obj_next; - if (td->alt_next != td_alt_next) { - /* next frame */ - break; - } + if (td->alt_next != td_alt_next) { + /* next frame */ + break; } } skip: @@ -1710,7 +1707,6 @@ temp.len = xfer->frlengths[0]; temp.ml.buf_pc = xfer->frbuffers + 0; temp.shortpkt = temp.len ? 1 : 0; - /* no "alt_next" for SETUP stage */ temp.setup_alt_next = 0; /* check for last frame */ if (xfer->nframes == 1) { ==== //depot/projects/usb/src/sys/dev/usb/controller/uss820dci.c#5 (text+ko) ==== @@ -836,7 +836,6 @@ temp.td = NULL; temp.td_next = xfer->td_start[0]; - temp.setup_alt_next = xfer->flags_int.short_frames_ok; temp.offset = 0; sc = USS820_DCI_BUS2SC(xfer->xroot->bus); @@ -851,6 +850,7 @@ temp.len = xfer->frlengths[0]; temp.pc = xfer->frbuffers + 0; temp.short_pkt = temp.len ? 1 : 0; + temp.setup_alt_next = 0; uss820dci_setup_standard_chain_sub(&temp); } @@ -859,6 +859,8 @@ x = 0; } + temp.setup_alt_next = xfer->flags_int.short_frames_ok; + if (x != xfer->nframes) { if (xfer->endpoint & UE_DIR_IN) { temp.func = &uss820dci_data_tx; @@ -878,7 +880,13 @@ x++; if (x == xfer->nframes) { - temp.setup_alt_next = 0; + if (xfer->flags_int.control_xfr) { + if (xfer->flags_int.control_act) { + temp.setup_alt_next = 0; + } + } else { + temp.setup_alt_next = 0; + } } if (temp.len == 0) { @@ -903,37 +911,39 @@ } } - /* always setup a valid "pc" pointer for status and sync */ - temp.pc = xfer->frbuffers + 0; - - /* check if we should append a status stage */ - - if (xfer->flags_int.control_xfr && - !xfer->flags_int.control_act) { + /* check for control transfer */ + if (xfer->flags_int.control_xfr) { uint8_t need_sync; - /* - * Send a DATA1 message and invert the current - * endpoint direction. - */ - if (xfer->endpoint & UE_DIR_IN) { - temp.func = &uss820dci_data_rx; - need_sync = 0; - } else { - temp.func = &uss820dci_data_tx; - need_sync = 1; - } + /* always setup a valid "pc" pointer for status and sync */ + temp.pc = xfer->frbuffers + 0; temp.len = 0; temp.short_pkt = 0; + temp.setup_alt_next = 0; - uss820dci_setup_standard_chain_sub(&temp); - if (need_sync) { - /* we need a SYNC point after TX */ - temp.func = &uss820dci_data_tx_sync; + /* check if we should append a status stage */ + if (!xfer->flags_int.control_act) { + + /* + * Send a DATA1 message and invert the current + * endpoint direction. + */ + if (xfer->endpoint & UE_DIR_IN) { + temp.func = &uss820dci_data_rx; + need_sync = 0; + } else { + temp.func = &uss820dci_data_tx; + need_sync = 1; + } temp.len = 0; temp.short_pkt = 0; uss820dci_setup_standard_chain_sub(&temp); + if (need_sync) { + /* we need a SYNC point after TX */ + temp.func = &uss820dci_data_tx_sync; + uss820dci_setup_standard_chain_sub(&temp); + } } } /* must have at least one frame! */ ==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#133 (text+ko) ==== @@ -1251,6 +1251,20 @@ /* no longer active */ xfer->flags_int.control_act = 0; } + + /* Check for invalid number of frames */ + if (xfer->nframes > 2) { + /* + * If you need to split a control transfer, you + * have to do one part at a time. Only with + * non-control transfers you can do multiple + * parts a time. + */ + DPRINTFN(0, "Too many frames: %u\n", + (unsigned int)xfer->nframes); + goto error; + } + /* * Check if there is a control * transfer in progress: @@ -1495,32 +1509,28 @@ */ if (USB_GET_DATA_ISREAD(xfer)) { - if (xfer->flags_int.control_xfr) { + if (xfer->flags.short_frames_ok) { + xfer->flags_int.short_xfer_ok = 1; + xfer->flags_int.short_frames_ok = 1; + } else if (xfer->flags.short_xfer_ok) { + xfer->flags_int.short_xfer_ok = 1; - /* - * Control transfers do not support reception - * of multiple short USB frames ! - */ - - if (xfer->flags.short_xfer_ok) { - xfer->flags_int.short_xfer_ok = 1; + /* check for control transfer */ + if (xfer->flags_int.control_xfr) { /* - * Due to sometimes buggy device side - * firmware we need to do a STATUS - * stage in case of short control - * transfers in USB host mode, via - * the "alt_next" feature! + * 1) Control transfers do not support + * reception of multiple short USB + * frames in host mode and device side + * mode, with exception of: + * + * 2) Due to sometimes buggy device + * side firmware we need to do a + * STATUS stage in case of short + * control transfers in USB host mode. + * The STATUS stage then becomes the + * "alt_next" to the DATA stage. */ - if (udev->flags.usb2_mode == USB_MODE_HOST) - xfer->flags_int.short_frames_ok = 1; - } - } else { - - if (xfer->flags.short_frames_ok) { - xfer->flags_int.short_xfer_ok = 1; xfer->flags_int.short_frames_ok = 1; - } else if (xfer->flags.short_xfer_ok) { - xfer->flags_int.short_xfer_ok = 1; } } }