1*0223a09fSskrll /* $NetBSD: dwc2_hcdqueue.c,v 1.6 2013/11/24 12:25:19 skrll Exp $ */ 2e30d28aaSskrll 3de63295cSskrll /* 4de63295cSskrll * hcd_queue.c - DesignWare HS OTG Controller host queuing routines 5de63295cSskrll * 6de63295cSskrll * Copyright (C) 2004-2013 Synopsys, Inc. 7de63295cSskrll * 8de63295cSskrll * Redistribution and use in source and binary forms, with or without 9de63295cSskrll * modification, are permitted provided that the following conditions 10de63295cSskrll * are met: 11de63295cSskrll * 1. Redistributions of source code must retain the above copyright 12de63295cSskrll * notice, this list of conditions, and the following disclaimer, 13de63295cSskrll * without modification. 14de63295cSskrll * 2. Redistributions in binary form must reproduce the above copyright 15de63295cSskrll * notice, this list of conditions and the following disclaimer in the 16de63295cSskrll * documentation and/or other materials provided with the distribution. 17de63295cSskrll * 3. The names of the above-listed copyright holders may not be used 18de63295cSskrll * to endorse or promote products derived from this software without 19de63295cSskrll * specific prior written permission. 20de63295cSskrll * 21de63295cSskrll * ALTERNATIVELY, this software may be distributed under the terms of the 22de63295cSskrll * GNU General Public License ("GPL") as published by the Free Software 23de63295cSskrll * Foundation; either version 2 of the License, or (at your option) any 24de63295cSskrll * later version. 25de63295cSskrll * 26de63295cSskrll * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 27de63295cSskrll * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 28de63295cSskrll * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29de63295cSskrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 30de63295cSskrll * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31de63295cSskrll * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32de63295cSskrll * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33de63295cSskrll * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34de63295cSskrll * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35de63295cSskrll * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36de63295cSskrll * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37de63295cSskrll */ 38de63295cSskrll 39de63295cSskrll /* 40de63295cSskrll * This file contains the functions to manage Queue Heads and Queue 41de63295cSskrll * Transfer Descriptors for Host mode 42de63295cSskrll */ 435f137d9bSskrll 445f137d9bSskrll #include <sys/cdefs.h> 45*0223a09fSskrll __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdqueue.c,v 1.6 2013/11/24 12:25:19 skrll Exp $"); 465f137d9bSskrll 475f137d9bSskrll #include <sys/types.h> 485f137d9bSskrll #include <sys/kmem.h> 495f137d9bSskrll #include <sys/pool.h> 505f137d9bSskrll 515f137d9bSskrll #include <dev/usb/usb.h> 525f137d9bSskrll #include <dev/usb/usbdi.h> 535f137d9bSskrll #include <dev/usb/usbdivar.h> 545f137d9bSskrll #include <dev/usb/usb_mem.h> 555f137d9bSskrll 565f137d9bSskrll #include <machine/param.h> 575f137d9bSskrll 58de63295cSskrll #include <linux/kernel.h> 59de63295cSskrll 605f137d9bSskrll #include <dwc2/dwc2.h> 615f137d9bSskrll #include <dwc2/dwc2var.h> 62de63295cSskrll 635f137d9bSskrll #include "dwc2_core.h" 645f137d9bSskrll #include "dwc2_hcd.h" 655f137d9bSskrll 665f137d9bSskrll static u32 dwc2_calc_bus_time(struct dwc2_hsotg *, int, int, int, int); 67de63295cSskrll 68de63295cSskrll /** 69de63295cSskrll * dwc2_qh_init() - Initializes a QH structure 70de63295cSskrll * 71de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 72de63295cSskrll * @qh: The QH to init 73de63295cSskrll * @urb: Holds the information about the device/endpoint needed to initialize 74de63295cSskrll * the QH 75de63295cSskrll */ 76de63295cSskrll #define SCHEDULE_SLOP 10 77de63295cSskrll static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, 78de63295cSskrll struct dwc2_hcd_urb *urb) 79de63295cSskrll { 80de63295cSskrll int dev_speed, hub_addr, hub_port; 815f137d9bSskrll const char *speed, *type; 82de63295cSskrll 83de63295cSskrll dev_vdbg(hsotg->dev, "%s()\n", __func__); 84de63295cSskrll 85de63295cSskrll /* Initialize QH */ 86de63295cSskrll qh->ep_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); 87de63295cSskrll qh->ep_is_in = dwc2_hcd_is_pipe_in(&urb->pipe_info) ? 1 : 0; 88de63295cSskrll 89de63295cSskrll qh->data_toggle = DWC2_HC_PID_DATA0; 90de63295cSskrll qh->maxp = dwc2_hcd_get_mps(&urb->pipe_info); 91de63295cSskrll INIT_LIST_HEAD(&qh->qtd_list); 92de63295cSskrll INIT_LIST_HEAD(&qh->qh_list_entry); 93de63295cSskrll 94de63295cSskrll /* FS/LS Endpoint on HS Hub, NOT virtual root hub */ 95de63295cSskrll dev_speed = dwc2_host_get_speed(hsotg, urb->priv); 96de63295cSskrll 97de63295cSskrll dwc2_host_hub_info(hsotg, urb->priv, &hub_addr, &hub_port); 98de63295cSskrll 99de63295cSskrll if ((dev_speed == USB_SPEED_LOW || dev_speed == USB_SPEED_FULL) && 100de63295cSskrll hub_addr != 0 && hub_addr != 1) { 101de63295cSskrll dev_vdbg(hsotg->dev, 102de63295cSskrll "QH init: EP %d: TT found at hub addr %d, for port %d\n", 103de63295cSskrll dwc2_hcd_get_ep_num(&urb->pipe_info), hub_addr, 104de63295cSskrll hub_port); 105de63295cSskrll qh->do_split = 1; 106de63295cSskrll } 107de63295cSskrll 108de63295cSskrll if (qh->ep_type == USB_ENDPOINT_XFER_INT || 109de63295cSskrll qh->ep_type == USB_ENDPOINT_XFER_ISOC) { 110de63295cSskrll /* Compute scheduling parameters once and save them */ 111de63295cSskrll u32 hprt, prtspd; 112de63295cSskrll 113de63295cSskrll /* Todo: Account for split transfers in the bus time */ 114de63295cSskrll int bytecount = 115de63295cSskrll dwc2_hb_mult(qh->maxp) * dwc2_max_packet(qh->maxp); 116de63295cSskrll 1175f137d9bSskrll qh->usecs = dwc2_calc_bus_time(hsotg, qh->do_split ? 118de63295cSskrll USB_SPEED_HIGH : dev_speed, qh->ep_is_in, 119de63295cSskrll qh->ep_type == USB_ENDPOINT_XFER_ISOC, 1205f137d9bSskrll bytecount); 121de63295cSskrll /* Start in a slightly future (micro)frame */ 122de63295cSskrll qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number, 123de63295cSskrll SCHEDULE_SLOP); 124de63295cSskrll qh->interval = urb->interval; 125de63295cSskrll #if 0 126de63295cSskrll /* Increase interrupt polling rate for debugging */ 127de63295cSskrll if (qh->ep_type == USB_ENDPOINT_XFER_INT) 128de63295cSskrll qh->interval = 8; 129de63295cSskrll #endif 1305f137d9bSskrll hprt = DWC2_READ_4(hsotg, HPRT0); 13101999631Sskrll prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; 132de63295cSskrll if (prtspd == HPRT0_SPD_HIGH_SPEED && 133de63295cSskrll (dev_speed == USB_SPEED_LOW || 134de63295cSskrll dev_speed == USB_SPEED_FULL)) { 135de63295cSskrll qh->interval *= 8; 136de63295cSskrll qh->sched_frame |= 0x7; 137de63295cSskrll qh->start_split_frame = qh->sched_frame; 138de63295cSskrll } 139de63295cSskrll dev_dbg(hsotg->dev, "interval=%d\n", qh->interval); 140de63295cSskrll } 141de63295cSskrll 142de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH Initialized\n"); 143de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - qh = %p\n", qh); 144de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Device Address = %d\n", 145de63295cSskrll dwc2_hcd_get_dev_addr(&urb->pipe_info)); 146de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Endpoint %d, %s\n", 147de63295cSskrll dwc2_hcd_get_ep_num(&urb->pipe_info), 148de63295cSskrll dwc2_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT"); 149de63295cSskrll 150de63295cSskrll qh->dev_speed = dev_speed; 151de63295cSskrll 152de63295cSskrll switch (dev_speed) { 153de63295cSskrll case USB_SPEED_LOW: 154de63295cSskrll speed = "low"; 155de63295cSskrll break; 156de63295cSskrll case USB_SPEED_FULL: 157de63295cSskrll speed = "full"; 158de63295cSskrll break; 159de63295cSskrll case USB_SPEED_HIGH: 160de63295cSskrll speed = "high"; 161de63295cSskrll break; 162de63295cSskrll default: 163de63295cSskrll speed = "?"; 164de63295cSskrll break; 165de63295cSskrll } 166de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Speed = %s\n", speed); 167de63295cSskrll 168de63295cSskrll switch (qh->ep_type) { 169de63295cSskrll case USB_ENDPOINT_XFER_ISOC: 170de63295cSskrll type = "isochronous"; 171de63295cSskrll break; 172de63295cSskrll case USB_ENDPOINT_XFER_INT: 173de63295cSskrll type = "interrupt"; 174de63295cSskrll break; 175de63295cSskrll case USB_ENDPOINT_XFER_CONTROL: 176de63295cSskrll type = "control"; 177de63295cSskrll break; 178de63295cSskrll case USB_ENDPOINT_XFER_BULK: 179de63295cSskrll type = "bulk"; 180de63295cSskrll break; 181de63295cSskrll default: 182de63295cSskrll type = "?"; 183de63295cSskrll break; 184de63295cSskrll } 185de63295cSskrll 186de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Type = %s\n", type); 187de63295cSskrll 188de63295cSskrll if (qh->ep_type == USB_ENDPOINT_XFER_INT) { 189de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - usecs = %d\n", 190de63295cSskrll qh->usecs); 191de63295cSskrll dev_vdbg(hsotg->dev, "DWC OTG HCD QH - interval = %d\n", 192de63295cSskrll qh->interval); 193de63295cSskrll } 194de63295cSskrll } 195de63295cSskrll 196de63295cSskrll /** 197de63295cSskrll * dwc2_hcd_qh_create() - Allocates and initializes a QH 198de63295cSskrll * 199de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 200de63295cSskrll * @urb: Holds the information about the device/endpoint needed 201de63295cSskrll * to initialize the QH 20201999631Sskrll * @mem_flags: Flag to do atomic allocation if needed 203de63295cSskrll * 204de63295cSskrll * Return: Pointer to the newly allocated QH, or NULL on error 205de63295cSskrll */ 206de63295cSskrll static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, 207de63295cSskrll struct dwc2_hcd_urb *urb, 208de63295cSskrll gfp_t mem_flags) 209de63295cSskrll { 2105f137d9bSskrll struct dwc2_softc *sc = hsotg->hsotg_sc; 211de63295cSskrll struct dwc2_qh *qh; 212de63295cSskrll 213de63295cSskrll if (!urb->priv) 214de63295cSskrll return NULL; 215de63295cSskrll 216de63295cSskrll /* Allocate memory */ 2175f137d9bSskrll qh = pool_cache_get(sc->sc_qhpool, PR_NOWAIT); 218de63295cSskrll if (!qh) 219de63295cSskrll return NULL; 220de63295cSskrll 2215f137d9bSskrll memset(qh, 0, sizeof(*qh)); 222de63295cSskrll dwc2_qh_init(hsotg, qh, urb); 223de63295cSskrll 224de63295cSskrll if (hsotg->core_params->dma_desc_enable > 0 && 225de63295cSskrll dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) { 226de63295cSskrll dwc2_hcd_qh_free(hsotg, qh); 227de63295cSskrll return NULL; 228de63295cSskrll } 229de63295cSskrll 230de63295cSskrll return qh; 231de63295cSskrll } 232de63295cSskrll 233de63295cSskrll /** 234de63295cSskrll * dwc2_hcd_qh_free() - Frees the QH 235de63295cSskrll * 236de63295cSskrll * @hsotg: HCD instance 237de63295cSskrll * @qh: The QH to free 238de63295cSskrll * 239de63295cSskrll * QH should already be removed from the list. QTD list should already be empty 240de63295cSskrll * if called from URB Dequeue. 241de63295cSskrll * 242de63295cSskrll * Must NOT be called with interrupt disabled or spinlock held 243de63295cSskrll */ 244de63295cSskrll void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 245de63295cSskrll { 2465f137d9bSskrll struct dwc2_softc *sc = hsotg->hsotg_sc; 247de63295cSskrll 248de63295cSskrll if (hsotg->core_params->dma_desc_enable > 0) { 249de63295cSskrll dwc2_hcd_qh_free_ddma(hsotg, qh); 250de63295cSskrll } else if (qh->dw_align_buf) { 2515f137d9bSskrll /* XXXNH */ 2525f137d9bSskrll usb_freemem(&hsotg->hsotg_sc->sc_bus, &qh->dw_align_buf_usbdma); 253de63295cSskrll } 254de63295cSskrll 2555f137d9bSskrll pool_cache_put(sc->sc_qhpool, qh); 256de63295cSskrll } 257de63295cSskrll 258de63295cSskrll /** 259de63295cSskrll * dwc2_periodic_channel_available() - Checks that a channel is available for a 260de63295cSskrll * periodic transfer 261de63295cSskrll * 262de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 263de63295cSskrll * 26401999631Sskrll * Return: 0 if successful, negative error code otherwise 265de63295cSskrll */ 266de63295cSskrll static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg) 267de63295cSskrll { 268de63295cSskrll /* 26901999631Sskrll * Currently assuming that there is a dedicated host channel for 270de63295cSskrll * each periodic transaction plus at least one host channel for 271de63295cSskrll * non-periodic transactions 272de63295cSskrll */ 273de63295cSskrll int status; 274de63295cSskrll int num_channels; 275de63295cSskrll 276de63295cSskrll num_channels = hsotg->core_params->host_channels; 277de63295cSskrll if (hsotg->periodic_channels + hsotg->non_periodic_channels < 278de63295cSskrll num_channels 279de63295cSskrll && hsotg->periodic_channels < num_channels - 1) { 280de63295cSskrll status = 0; 281de63295cSskrll } else { 282de63295cSskrll dev_dbg(hsotg->dev, 283de63295cSskrll "%s: Total channels: %d, Periodic: %d, " 284de63295cSskrll "Non-periodic: %d\n", __func__, num_channels, 285de63295cSskrll hsotg->periodic_channels, hsotg->non_periodic_channels); 286de63295cSskrll status = -ENOSPC; 287de63295cSskrll } 288de63295cSskrll 289de63295cSskrll return status; 290de63295cSskrll } 291de63295cSskrll 292de63295cSskrll /** 293de63295cSskrll * dwc2_check_periodic_bandwidth() - Checks that there is sufficient bandwidth 294de63295cSskrll * for the specified QH in the periodic schedule 295de63295cSskrll * 296de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 297de63295cSskrll * @qh: QH containing periodic bandwidth required 298de63295cSskrll * 299de63295cSskrll * Return: 0 if successful, negative error code otherwise 300de63295cSskrll * 301de63295cSskrll * For simplicity, this calculation assumes that all the transfers in the 302de63295cSskrll * periodic schedule may occur in the same (micro)frame 303de63295cSskrll */ 304de63295cSskrll static int dwc2_check_periodic_bandwidth(struct dwc2_hsotg *hsotg, 305de63295cSskrll struct dwc2_qh *qh) 306de63295cSskrll { 307de63295cSskrll int status; 308de63295cSskrll s16 max_claimed_usecs; 309de63295cSskrll 310de63295cSskrll status = 0; 311de63295cSskrll 312de63295cSskrll if (qh->dev_speed == USB_SPEED_HIGH || qh->do_split) { 313de63295cSskrll /* 314de63295cSskrll * High speed mode 315de63295cSskrll * Max periodic usecs is 80% x 125 usec = 100 usec 316de63295cSskrll */ 317de63295cSskrll max_claimed_usecs = 100 - qh->usecs; 318de63295cSskrll } else { 319de63295cSskrll /* 320de63295cSskrll * Full speed mode 321de63295cSskrll * Max periodic usecs is 90% x 1000 usec = 900 usec 322de63295cSskrll */ 323de63295cSskrll max_claimed_usecs = 900 - qh->usecs; 324de63295cSskrll } 325de63295cSskrll 326de63295cSskrll if (hsotg->periodic_usecs > max_claimed_usecs) { 327de63295cSskrll dev_err(hsotg->dev, 328de63295cSskrll "%s: already claimed usecs %d, required usecs %d\n", 329de63295cSskrll __func__, hsotg->periodic_usecs, qh->usecs); 330de63295cSskrll status = -ENOSPC; 331de63295cSskrll } 332de63295cSskrll 333de63295cSskrll return status; 334de63295cSskrll } 335de63295cSskrll 336de63295cSskrll /** 337de63295cSskrll * Microframe scheduler 338de63295cSskrll * track the total use in hsotg->frame_usecs 339de63295cSskrll * keep each qh use in qh->frame_usecs 340de63295cSskrll * when surrendering the qh then donate the time back 341de63295cSskrll */ 342de63295cSskrll static const unsigned short max_uframe_usecs[] = { 343de63295cSskrll 100, 100, 100, 100, 100, 100, 30, 0 344de63295cSskrll }; 345de63295cSskrll 346de63295cSskrll void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg) 347de63295cSskrll { 348de63295cSskrll int i; 349de63295cSskrll 350de63295cSskrll for (i = 0; i < 8; i++) 351de63295cSskrll hsotg->frame_usecs[i] = max_uframe_usecs[i]; 352de63295cSskrll } 353de63295cSskrll 354de63295cSskrll static int dwc2_find_single_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 355de63295cSskrll { 356de63295cSskrll unsigned short utime = qh->usecs; 357*0223a09fSskrll int i; 358de63295cSskrll 359*0223a09fSskrll for (i = 0; i < 8; i++) { 360de63295cSskrll /* At the start hsotg->frame_usecs[i] = max_uframe_usecs[i] */ 361de63295cSskrll if (utime <= hsotg->frame_usecs[i]) { 362de63295cSskrll hsotg->frame_usecs[i] -= utime; 363de63295cSskrll qh->frame_usecs[i] += utime; 364*0223a09fSskrll return i; 365de63295cSskrll } 366de63295cSskrll } 367*0223a09fSskrll return -1; 368de63295cSskrll } 369de63295cSskrll 370de63295cSskrll /* 371de63295cSskrll * use this for FS apps that can span multiple uframes 372de63295cSskrll */ 373de63295cSskrll static int dwc2_find_multi_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 374de63295cSskrll { 375de63295cSskrll unsigned short utime = qh->usecs; 376de63295cSskrll unsigned short xtime; 377*0223a09fSskrll int t_left; 378*0223a09fSskrll int i; 379de63295cSskrll int j; 380*0223a09fSskrll int k; 381de63295cSskrll 382*0223a09fSskrll for (i = 0; i < 8; i++) { 383*0223a09fSskrll if (hsotg->frame_usecs[i] <= 0) 384de63295cSskrll continue; 385de63295cSskrll 386de63295cSskrll /* 387de63295cSskrll * we need n consecutive slots so use j as a start slot 388de63295cSskrll * j plus j+1 must be enough time (for now) 389de63295cSskrll */ 390de63295cSskrll xtime = hsotg->frame_usecs[i]; 391de63295cSskrll for (j = i + 1; j < 8; j++) { 392de63295cSskrll /* 393de63295cSskrll * if we add this frame remaining time to xtime we may 394de63295cSskrll * be OK, if not we need to test j for a complete frame 395de63295cSskrll */ 396de63295cSskrll if (xtime + hsotg->frame_usecs[j] < utime) { 397de63295cSskrll if (hsotg->frame_usecs[j] < 398*0223a09fSskrll max_uframe_usecs[j]) 399*0223a09fSskrll continue; 400de63295cSskrll } 401de63295cSskrll if (xtime >= utime) { 402*0223a09fSskrll t_left = utime; 403*0223a09fSskrll for (k = i; k < 8; k++) { 404*0223a09fSskrll t_left -= hsotg->frame_usecs[k]; 405*0223a09fSskrll if (t_left <= 0) { 406*0223a09fSskrll qh->frame_usecs[k] += 407*0223a09fSskrll hsotg->frame_usecs[k] 408*0223a09fSskrll + t_left; 409*0223a09fSskrll hsotg->frame_usecs[k] = -t_left; 410*0223a09fSskrll return i; 411*0223a09fSskrll } else { 412*0223a09fSskrll qh->frame_usecs[k] += 413*0223a09fSskrll hsotg->frame_usecs[k]; 414*0223a09fSskrll hsotg->frame_usecs[k] = 0; 415*0223a09fSskrll } 416*0223a09fSskrll } 417de63295cSskrll } 418de63295cSskrll /* add the frame time to x time */ 419de63295cSskrll xtime += hsotg->frame_usecs[j]; 420de63295cSskrll /* we must have a fully available next frame or break */ 421de63295cSskrll if (xtime < utime && 422*0223a09fSskrll hsotg->frame_usecs[j] == max_uframe_usecs[j]) 423*0223a09fSskrll continue; 424de63295cSskrll } 425de63295cSskrll } 426*0223a09fSskrll return -1; 427de63295cSskrll } 428de63295cSskrll 429de63295cSskrll static int dwc2_find_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 430de63295cSskrll { 431de63295cSskrll int ret; 432de63295cSskrll 433de63295cSskrll if (qh->dev_speed == USB_SPEED_HIGH) { 434de63295cSskrll /* if this is a hs transaction we need a full frame */ 435de63295cSskrll ret = dwc2_find_single_uframe(hsotg, qh); 436de63295cSskrll } else { 437de63295cSskrll /* 438de63295cSskrll * if this is a fs transaction we may need a sequence 439de63295cSskrll * of frames 440de63295cSskrll */ 441de63295cSskrll ret = dwc2_find_multi_uframe(hsotg, qh); 442de63295cSskrll } 443de63295cSskrll return ret; 444de63295cSskrll } 445de63295cSskrll 446de63295cSskrll /** 447de63295cSskrll * dwc2_check_max_xfer_size() - Checks that the max transfer size allowed in a 448de63295cSskrll * host channel is large enough to handle the maximum data transfer in a single 449de63295cSskrll * (micro)frame for a periodic transfer 450de63295cSskrll * 451de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 452de63295cSskrll * @qh: QH for a periodic endpoint 453de63295cSskrll * 454de63295cSskrll * Return: 0 if successful, negative error code otherwise 455de63295cSskrll */ 456de63295cSskrll static int dwc2_check_max_xfer_size(struct dwc2_hsotg *hsotg, 457de63295cSskrll struct dwc2_qh *qh) 458de63295cSskrll { 459de63295cSskrll u32 max_xfer_size; 460de63295cSskrll u32 max_channel_xfer_size; 461de63295cSskrll int status = 0; 462de63295cSskrll 463de63295cSskrll max_xfer_size = dwc2_max_packet(qh->maxp) * dwc2_hb_mult(qh->maxp); 464de63295cSskrll max_channel_xfer_size = hsotg->core_params->max_transfer_size; 465de63295cSskrll 466de63295cSskrll if (max_xfer_size > max_channel_xfer_size) { 467de63295cSskrll dev_err(hsotg->dev, 468de63295cSskrll "%s: Periodic xfer length %d > max xfer length for channel %d\n", 469de63295cSskrll __func__, max_xfer_size, max_channel_xfer_size); 470de63295cSskrll status = -ENOSPC; 471de63295cSskrll } 472de63295cSskrll 473de63295cSskrll return status; 474de63295cSskrll } 475de63295cSskrll 476de63295cSskrll /** 477de63295cSskrll * dwc2_schedule_periodic() - Schedules an interrupt or isochronous transfer in 478de63295cSskrll * the periodic schedule 479de63295cSskrll * 480de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 481de63295cSskrll * @qh: QH for the periodic transfer. The QH should already contain the 482de63295cSskrll * scheduling information. 483de63295cSskrll * 484de63295cSskrll * Return: 0 if successful, negative error code otherwise 485de63295cSskrll */ 486de63295cSskrll static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 487de63295cSskrll { 488de63295cSskrll int status; 489de63295cSskrll 490de63295cSskrll if (hsotg->core_params->uframe_sched > 0) { 491de63295cSskrll int frame = -1; 492de63295cSskrll 493de63295cSskrll status = dwc2_find_uframe(hsotg, qh); 494de63295cSskrll if (status == 0) 495de63295cSskrll frame = 7; 496de63295cSskrll else if (status > 0) 497de63295cSskrll frame = status - 1; 498de63295cSskrll 499de63295cSskrll /* Set the new frame up */ 500de63295cSskrll if (frame > -1) { 501de63295cSskrll qh->sched_frame &= ~0x7; 502de63295cSskrll qh->sched_frame |= (frame & 7); 503de63295cSskrll } 504de63295cSskrll 505de63295cSskrll if (status != -1) 506de63295cSskrll status = 0; 507de63295cSskrll } else { 508de63295cSskrll status = dwc2_periodic_channel_available(hsotg); 509de63295cSskrll if (status) { 510de63295cSskrll dev_info(hsotg->dev, 511de63295cSskrll "%s: No host channel available for periodic transfer\n", 512de63295cSskrll __func__); 513de63295cSskrll return status; 514de63295cSskrll } 515de63295cSskrll 516de63295cSskrll status = dwc2_check_periodic_bandwidth(hsotg, qh); 517de63295cSskrll } 518de63295cSskrll 519de63295cSskrll if (status) { 520de63295cSskrll dev_dbg(hsotg->dev, 521de63295cSskrll "%s: Insufficient periodic bandwidth for periodic transfer\n", 522de63295cSskrll __func__); 523de63295cSskrll return status; 524de63295cSskrll } 525de63295cSskrll 526de63295cSskrll status = dwc2_check_max_xfer_size(hsotg, qh); 527de63295cSskrll if (status) { 528de63295cSskrll dev_dbg(hsotg->dev, 529de63295cSskrll "%s: Channel max transfer size too small for periodic transfer\n", 530de63295cSskrll __func__); 531de63295cSskrll return status; 532de63295cSskrll } 533de63295cSskrll 53401999631Sskrll if (hsotg->core_params->dma_desc_enable > 0) 535de63295cSskrll /* Don't rely on SOF and start in ready schedule */ 536de63295cSskrll list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); 53701999631Sskrll else 538de63295cSskrll /* Always start in inactive schedule */ 539de63295cSskrll list_add_tail(&qh->qh_list_entry, 540de63295cSskrll &hsotg->periodic_sched_inactive); 541de63295cSskrll 542de63295cSskrll if (hsotg->core_params->uframe_sched <= 0) 543de63295cSskrll /* Reserve periodic channel */ 544de63295cSskrll hsotg->periodic_channels++; 545de63295cSskrll 546de63295cSskrll /* Update claimed usecs per (micro)frame */ 547de63295cSskrll hsotg->periodic_usecs += qh->usecs; 548de63295cSskrll 549de63295cSskrll return status; 550de63295cSskrll } 551de63295cSskrll 552de63295cSskrll /** 553de63295cSskrll * dwc2_deschedule_periodic() - Removes an interrupt or isochronous transfer 554de63295cSskrll * from the periodic schedule 555de63295cSskrll * 556de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 557de63295cSskrll * @qh: QH for the periodic transfer 558de63295cSskrll */ 559de63295cSskrll static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg, 560de63295cSskrll struct dwc2_qh *qh) 561de63295cSskrll { 562de63295cSskrll int i; 563de63295cSskrll 564de63295cSskrll list_del_init(&qh->qh_list_entry); 565de63295cSskrll 566de63295cSskrll /* Update claimed usecs per (micro)frame */ 567de63295cSskrll hsotg->periodic_usecs -= qh->usecs; 568de63295cSskrll 569de63295cSskrll if (hsotg->core_params->uframe_sched > 0) { 570de63295cSskrll for (i = 0; i < 8; i++) { 571de63295cSskrll hsotg->frame_usecs[i] += qh->frame_usecs[i]; 572de63295cSskrll qh->frame_usecs[i] = 0; 573de63295cSskrll } 574de63295cSskrll } else { 575de63295cSskrll /* Release periodic channel reservation */ 576de63295cSskrll hsotg->periodic_channels--; 577de63295cSskrll } 578de63295cSskrll } 579de63295cSskrll 580de63295cSskrll /** 581de63295cSskrll * dwc2_hcd_qh_add() - Adds a QH to either the non periodic or periodic 582de63295cSskrll * schedule if it is not already in the schedule. If the QH is already in 583de63295cSskrll * the schedule, no action is taken. 584de63295cSskrll * 585de63295cSskrll * @hsotg: The HCD state structure for the DWC OTG controller 586de63295cSskrll * @qh: The QH to add 587de63295cSskrll * 588de63295cSskrll * Return: 0 if successful, negative error code otherwise 589de63295cSskrll */ 590de63295cSskrll int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 591de63295cSskrll { 592de63295cSskrll int status = 0; 593de63295cSskrll u32 intr_mask; 594de63295cSskrll 595de63295cSskrll if (dbg_qh(qh)) 596de63295cSskrll dev_vdbg(hsotg->dev, "%s()\n", __func__); 597de63295cSskrll 598de63295cSskrll if (!list_empty(&qh->qh_list_entry)) 599de63295cSskrll /* QH already in a schedule */ 600de63295cSskrll return status; 601de63295cSskrll 602de63295cSskrll /* Add the new QH to the appropriate schedule */ 603de63295cSskrll if (dwc2_qh_is_non_per(qh)) { 604de63295cSskrll /* Always start in inactive schedule */ 605de63295cSskrll list_add_tail(&qh->qh_list_entry, 606de63295cSskrll &hsotg->non_periodic_sched_inactive); 607de63295cSskrll } else { 608de63295cSskrll status = dwc2_schedule_periodic(hsotg, qh); 609de63295cSskrll if (status == 0) { 610de63295cSskrll if (!hsotg->periodic_qh_count) { 6115f137d9bSskrll intr_mask = DWC2_READ_4(hsotg, GINTMSK); 612de63295cSskrll intr_mask |= GINTSTS_SOF; 6135f137d9bSskrll DWC2_WRITE_4(hsotg, GINTMSK, intr_mask); 614de63295cSskrll } 615de63295cSskrll hsotg->periodic_qh_count++; 616de63295cSskrll } 617de63295cSskrll } 618de63295cSskrll 619de63295cSskrll return status; 620de63295cSskrll } 621de63295cSskrll 622de63295cSskrll /** 623de63295cSskrll * dwc2_hcd_qh_unlink() - Removes a QH from either the non-periodic or periodic 624de63295cSskrll * schedule. Memory is not freed. 625de63295cSskrll * 626de63295cSskrll * @hsotg: The HCD state structure 627de63295cSskrll * @qh: QH to remove from schedule 628de63295cSskrll */ 629de63295cSskrll void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 630de63295cSskrll { 631de63295cSskrll u32 intr_mask; 632de63295cSskrll 633de63295cSskrll dev_vdbg(hsotg->dev, "%s()\n", __func__); 634de63295cSskrll 635de63295cSskrll if (list_empty(&qh->qh_list_entry)) 636de63295cSskrll /* QH is not in a schedule */ 637de63295cSskrll return; 638de63295cSskrll 639de63295cSskrll if (dwc2_qh_is_non_per(qh)) { 640de63295cSskrll if (hsotg->non_periodic_qh_ptr == &qh->qh_list_entry) 641de63295cSskrll hsotg->non_periodic_qh_ptr = 642de63295cSskrll hsotg->non_periodic_qh_ptr->next; 643de63295cSskrll list_del_init(&qh->qh_list_entry); 644de63295cSskrll } else { 645de63295cSskrll dwc2_deschedule_periodic(hsotg, qh); 646de63295cSskrll hsotg->periodic_qh_count--; 647de63295cSskrll if (!hsotg->periodic_qh_count) { 6485f137d9bSskrll intr_mask = DWC2_READ_4(hsotg, GINTMSK); 649de63295cSskrll intr_mask &= ~GINTSTS_SOF; 6505f137d9bSskrll DWC2_WRITE_4(hsotg, GINTMSK, intr_mask); 651de63295cSskrll } 652de63295cSskrll } 653de63295cSskrll } 654de63295cSskrll 655de63295cSskrll /* 656de63295cSskrll * Schedule the next continuing periodic split transfer 657de63295cSskrll */ 658de63295cSskrll static void dwc2_sched_periodic_split(struct dwc2_hsotg *hsotg, 659de63295cSskrll struct dwc2_qh *qh, u16 frame_number, 660de63295cSskrll int sched_next_periodic_split) 661de63295cSskrll { 662de63295cSskrll u16 incr; 663de63295cSskrll 664de63295cSskrll if (sched_next_periodic_split) { 665de63295cSskrll qh->sched_frame = frame_number; 666de63295cSskrll incr = dwc2_frame_num_inc(qh->start_split_frame, 1); 667de63295cSskrll if (dwc2_frame_num_le(frame_number, incr)) { 668de63295cSskrll /* 669de63295cSskrll * Allow one frame to elapse after start split 670de63295cSskrll * microframe before scheduling complete split, but 671de63295cSskrll * DON'T if we are doing the next start split in the 672de63295cSskrll * same frame for an ISOC out 673de63295cSskrll */ 674de63295cSskrll if (qh->ep_type != USB_ENDPOINT_XFER_ISOC || 675de63295cSskrll qh->ep_is_in != 0) { 676de63295cSskrll qh->sched_frame = 677de63295cSskrll dwc2_frame_num_inc(qh->sched_frame, 1); 678de63295cSskrll } 679de63295cSskrll } 680de63295cSskrll } else { 681de63295cSskrll qh->sched_frame = dwc2_frame_num_inc(qh->start_split_frame, 682de63295cSskrll qh->interval); 683de63295cSskrll if (dwc2_frame_num_le(qh->sched_frame, frame_number)) 684de63295cSskrll qh->sched_frame = frame_number; 685de63295cSskrll qh->sched_frame |= 0x7; 686de63295cSskrll qh->start_split_frame = qh->sched_frame; 687de63295cSskrll } 688de63295cSskrll } 689de63295cSskrll 690de63295cSskrll /* 691de63295cSskrll * Deactivates a QH. For non-periodic QHs, removes the QH from the active 692de63295cSskrll * non-periodic schedule. The QH is added to the inactive non-periodic 693de63295cSskrll * schedule if any QTDs are still attached to the QH. 694de63295cSskrll * 695de63295cSskrll * For periodic QHs, the QH is removed from the periodic queued schedule. If 696de63295cSskrll * there are any QTDs still attached to the QH, the QH is added to either the 697de63295cSskrll * periodic inactive schedule or the periodic ready schedule and its next 698de63295cSskrll * scheduled frame is calculated. The QH is placed in the ready schedule if 699de63295cSskrll * the scheduled frame has been reached already. Otherwise it's placed in the 700de63295cSskrll * inactive schedule. If there are no QTDs attached to the QH, the QH is 701de63295cSskrll * completely removed from the periodic schedule. 702de63295cSskrll */ 703de63295cSskrll void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, 704de63295cSskrll int sched_next_periodic_split) 705de63295cSskrll { 706de63295cSskrll if (dbg_qh(qh)) 707de63295cSskrll dev_vdbg(hsotg->dev, "%s()\n", __func__); 708de63295cSskrll 709de63295cSskrll if (dwc2_qh_is_non_per(qh)) { 710de63295cSskrll dwc2_hcd_qh_unlink(hsotg, qh); 711de63295cSskrll if (!list_empty(&qh->qtd_list)) 712de63295cSskrll /* Add back to inactive non-periodic schedule */ 713de63295cSskrll dwc2_hcd_qh_add(hsotg, qh); 714de63295cSskrll } else { 715de63295cSskrll u16 frame_number = dwc2_hcd_get_frame_number(hsotg); 716de63295cSskrll 717de63295cSskrll if (qh->do_split) { 718de63295cSskrll dwc2_sched_periodic_split(hsotg, qh, frame_number, 719de63295cSskrll sched_next_periodic_split); 720de63295cSskrll } else { 721de63295cSskrll qh->sched_frame = dwc2_frame_num_inc(qh->sched_frame, 722de63295cSskrll qh->interval); 723de63295cSskrll if (dwc2_frame_num_le(qh->sched_frame, frame_number)) 724de63295cSskrll qh->sched_frame = frame_number; 725de63295cSskrll } 726de63295cSskrll 727de63295cSskrll if (list_empty(&qh->qtd_list)) { 728de63295cSskrll dwc2_hcd_qh_unlink(hsotg, qh); 729de63295cSskrll } else { 730de63295cSskrll /* 731de63295cSskrll * Remove from periodic_sched_queued and move to 732de63295cSskrll * appropriate queue 733de63295cSskrll */ 734de63295cSskrll if ((hsotg->core_params->uframe_sched > 0 && 735de63295cSskrll dwc2_frame_num_le(qh->sched_frame, frame_number)) 736de63295cSskrll || (hsotg->core_params->uframe_sched <= 0 && 73701999631Sskrll qh->sched_frame == frame_number)) 738de63295cSskrll list_move(&qh->qh_list_entry, 739de63295cSskrll &hsotg->periodic_sched_ready); 74001999631Sskrll else 741de63295cSskrll list_move(&qh->qh_list_entry, 742de63295cSskrll &hsotg->periodic_sched_inactive); 743de63295cSskrll } 744de63295cSskrll } 745de63295cSskrll } 746de63295cSskrll 747de63295cSskrll /** 748de63295cSskrll * dwc2_hcd_qtd_init() - Initializes a QTD structure 749de63295cSskrll * 750de63295cSskrll * @qtd: The QTD to initialize 751de63295cSskrll * @urb: The associated URB 752de63295cSskrll */ 753de63295cSskrll void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) 754de63295cSskrll { 755de63295cSskrll qtd->urb = urb; 756de63295cSskrll if (dwc2_hcd_get_pipe_type(&urb->pipe_info) == 757de63295cSskrll USB_ENDPOINT_XFER_CONTROL) { 758de63295cSskrll /* 759de63295cSskrll * The only time the QTD data toggle is used is on the data 760de63295cSskrll * phase of control transfers. This phase always starts with 761de63295cSskrll * DATA1. 762de63295cSskrll */ 763de63295cSskrll qtd->data_toggle = DWC2_HC_PID_DATA1; 764de63295cSskrll qtd->control_phase = DWC2_CONTROL_SETUP; 765de63295cSskrll } 766de63295cSskrll 767de63295cSskrll /* Start split */ 768de63295cSskrll qtd->complete_split = 0; 769de63295cSskrll qtd->isoc_split_pos = DWC2_HCSPLT_XACTPOS_ALL; 770de63295cSskrll qtd->isoc_split_offset = 0; 771de63295cSskrll qtd->in_process = 0; 772de63295cSskrll 773de63295cSskrll /* Store the qtd ptr in the urb to reference the QTD */ 774de63295cSskrll urb->qtd = qtd; 775de63295cSskrll } 776de63295cSskrll 777de63295cSskrll /** 778de63295cSskrll * dwc2_hcd_qtd_add() - Adds a QTD to the QTD-list of a QH 779de63295cSskrll * 780de63295cSskrll * @hsotg: The DWC HCD structure 781de63295cSskrll * @qtd: The QTD to add 782de63295cSskrll * @qh: Out parameter to return queue head 78301999631Sskrll * @mem_flags: Flag to do atomic alloc if needed 784de63295cSskrll * 785de63295cSskrll * Return: 0 if successful, negative error code otherwise 786de63295cSskrll * 787de63295cSskrll * Finds the correct QH to place the QTD into. If it does not find a QH, it 788de63295cSskrll * will create a new QH. If the QH to which the QTD is added is not currently 789de63295cSskrll * scheduled, it is placed into the proper schedule based on its EP type. 790de63295cSskrll */ 791de63295cSskrll int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, 792de63295cSskrll struct dwc2_qh **qh, gfp_t mem_flags) 793de63295cSskrll { 794de63295cSskrll struct dwc2_hcd_urb *urb = qtd->urb; 795de63295cSskrll unsigned long flags; 796de63295cSskrll int allocated = 0; 797de63295cSskrll int retval; 798de63295cSskrll 799de63295cSskrll /* 800de63295cSskrll * Get the QH which holds the QTD-list to insert to. Create QH if it 801de63295cSskrll * doesn't exist. 802de63295cSskrll */ 803de63295cSskrll if (*qh == NULL) { 804de63295cSskrll *qh = dwc2_hcd_qh_create(hsotg, urb, mem_flags); 805de63295cSskrll if (*qh == NULL) 806de63295cSskrll return -ENOMEM; 807de63295cSskrll allocated = 1; 808de63295cSskrll } 809de63295cSskrll 810de63295cSskrll spin_lock_irqsave(&hsotg->lock, flags); 811de63295cSskrll 812de63295cSskrll retval = dwc2_hcd_qh_add(hsotg, *qh); 813de63295cSskrll if (retval) 814de63295cSskrll goto fail; 815de63295cSskrll 816de63295cSskrll qtd->qh = *qh; 817de63295cSskrll list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); 818de63295cSskrll spin_unlock_irqrestore(&hsotg->lock, flags); 819de63295cSskrll 820de63295cSskrll return 0; 821de63295cSskrll 822de63295cSskrll fail: 823de63295cSskrll if (allocated) { 824de63295cSskrll struct dwc2_qtd *qtd2, *qtd2_tmp; 825de63295cSskrll struct dwc2_qh *qh_tmp = *qh; 826de63295cSskrll 827de63295cSskrll *qh = NULL; 828de63295cSskrll dwc2_hcd_qh_unlink(hsotg, qh_tmp); 829de63295cSskrll 830de63295cSskrll /* Free each QTD in the QH's QTD list */ 831de63295cSskrll list_for_each_entry_safe(qtd2, qtd2_tmp, &qh_tmp->qtd_list, 832de63295cSskrll qtd_list_entry) 833de63295cSskrll dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp); 834de63295cSskrll 835de63295cSskrll spin_unlock_irqrestore(&hsotg->lock, flags); 836de63295cSskrll dwc2_hcd_qh_free(hsotg, qh_tmp); 837de63295cSskrll } else { 838de63295cSskrll spin_unlock_irqrestore(&hsotg->lock, flags); 839de63295cSskrll } 840de63295cSskrll 841de63295cSskrll return retval; 842de63295cSskrll } 8435f137d9bSskrll 8445f137d9bSskrll void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, 8455f137d9bSskrll struct dwc2_qtd *qtd, 8465f137d9bSskrll struct dwc2_qh *qh) 8475f137d9bSskrll { 8485f137d9bSskrll struct dwc2_softc *sc = hsotg->hsotg_sc; 8495f137d9bSskrll 8505f137d9bSskrll list_del_init(&qtd->qtd_list_entry); 8515f137d9bSskrll pool_cache_put(sc->sc_qtdpool, qtd); 8525f137d9bSskrll } 8535f137d9bSskrll 8545f137d9bSskrll #define BITSTUFFTIME(bytecount) ((8 * 7 * (bytecount)) / 6) 8555f137d9bSskrll #define HS_HOST_DELAY 5 /* nanoseconds */ 8565f137d9bSskrll #define FS_LS_HOST_DELAY 1000 /* nanoseconds */ 8575f137d9bSskrll #define HUB_LS_SETUP 333 /* nanoseconds */ 8585f137d9bSskrll 8595f137d9bSskrll static u32 dwc2_calc_bus_time(struct dwc2_hsotg *hsotg, int speed, int is_in, 8605f137d9bSskrll int is_isoc, int bytecount) 8615f137d9bSskrll { 8625f137d9bSskrll unsigned long retval; 8635f137d9bSskrll 8645f137d9bSskrll switch (speed) { 8655f137d9bSskrll case USB_SPEED_HIGH: 8665f137d9bSskrll if (is_isoc) 8675f137d9bSskrll retval = 8685f137d9bSskrll ((38 * 8 * 2083) + 8695f137d9bSskrll (2083 * (3 + BITSTUFFTIME(bytecount)))) / 1000 + 8705f137d9bSskrll HS_HOST_DELAY; 8715f137d9bSskrll else 8725f137d9bSskrll retval = 8735f137d9bSskrll ((55 * 8 * 2083) + 8745f137d9bSskrll (2083 * (3 + BITSTUFFTIME(bytecount)))) / 1000 + 8755f137d9bSskrll HS_HOST_DELAY; 8765f137d9bSskrll break; 8775f137d9bSskrll case USB_SPEED_FULL: 8785f137d9bSskrll if (is_isoc) { 8795f137d9bSskrll retval = 8805f137d9bSskrll (8354 * (31 + 10 * BITSTUFFTIME(bytecount))) / 1000; 8815f137d9bSskrll if (is_in) 8825f137d9bSskrll retval = 7268 + FS_LS_HOST_DELAY + retval; 8835f137d9bSskrll else 8845f137d9bSskrll retval = 6265 + FS_LS_HOST_DELAY + retval; 8855f137d9bSskrll } else { 8865f137d9bSskrll retval = 8875f137d9bSskrll (8354 * (31 + 10 * BITSTUFFTIME(bytecount))) / 1000; 8885f137d9bSskrll retval = 9107 + FS_LS_HOST_DELAY + retval; 8895f137d9bSskrll } 8905f137d9bSskrll break; 8915f137d9bSskrll case USB_SPEED_LOW: 8925f137d9bSskrll if (is_in) { 8935f137d9bSskrll retval = 8945f137d9bSskrll (67667 * (31 + 10 * BITSTUFFTIME(bytecount))) / 8955f137d9bSskrll 1000; 8965f137d9bSskrll retval = 8975f137d9bSskrll 64060 + (2 * HUB_LS_SETUP) + FS_LS_HOST_DELAY + 8985f137d9bSskrll retval; 8995f137d9bSskrll } else { 9005f137d9bSskrll retval = 9015f137d9bSskrll (66700 * (31 + 10 * BITSTUFFTIME(bytecount))) / 9025f137d9bSskrll 1000; 9035f137d9bSskrll retval = 9045f137d9bSskrll 64107 + (2 * HUB_LS_SETUP) + FS_LS_HOST_DELAY + 9055f137d9bSskrll retval; 9065f137d9bSskrll } 9075f137d9bSskrll break; 9085f137d9bSskrll default: 9095f137d9bSskrll dev_warn(hsotg->dev, "Unknown device speed\n"); 9105f137d9bSskrll retval = -1; 9115f137d9bSskrll } 9125f137d9bSskrll 9135f137d9bSskrll return NS_TO_US(retval); 9145f137d9bSskrll } 915