// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * hcd_queue.c - DesignWare HS OTG Controller host queuing routines * * Copyright (C) 2004-2013 Synopsys, Inc. */ /* * This file contains the functions to manage Queue Heads and Queue * Transfer Descriptors for Host mode */ #include <linux/gcd.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> #include <linux/io.h> #include <linux/seq_buf.h> #include <linux/slab.h> #include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/usb/ch11.h> #include "core.h" #include "hcd.h" /* Wait this long before releasing periodic reservation */ #define DWC2_UNRESERVE_DELAY … /* If we get a NAK, wait this long before retrying */ #define DWC2_RETRY_WAIT_DELAY … /** * dwc2_periodic_channel_available() - Checks that a channel is available for a * periodic transfer * * @hsotg: The HCD state structure for the DWC OTG controller * * Return: 0 if successful, negative error code otherwise */ static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg) { … } /** * dwc2_check_periodic_bandwidth() - Checks that there is sufficient bandwidth * for the specified QH in the periodic schedule * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH containing periodic bandwidth required * * Return: 0 if successful, negative error code otherwise * * For simplicity, this calculation assumes that all the transfers in the * periodic schedule may occur in the same (micro)frame */ static int dwc2_check_periodic_bandwidth(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * pmap_schedule() - Schedule time in a periodic bitmap (pmap). * * @map: The bitmap representing the schedule; will be updated * upon success. * @bits_per_period: The schedule represents several periods. This is how many * bits are in each period. It's assumed that the beginning * of the schedule will repeat after its end. * @periods_in_map: The number of periods in the schedule. * @num_bits: The number of bits we need per period we want to reserve * in this function call. * @interval: How often we need to be scheduled for the reservation this * time. 1 means every period. 2 means every other period. * ...you get the picture? * @start: The bit number to start at. Normally 0. Must be within * the interval or we return failure right away. * @only_one_period: Normally we'll allow picking a start anywhere within the * first interval, since we can still make all repetition * requirements by doing that. However, if you pass true * here then we'll return failure if we can't fit within * the period that "start" is in. * * The idea here is that we want to schedule time for repeating events that all * want the same resource. The resource is divided into fixed-sized periods * and the events want to repeat every "interval" periods. The schedule * granularity is one bit. * * To keep things "simple", we'll represent our schedule with a bitmap that * contains a fixed number of periods. This gets rid of a lot of complexity * but does mean that we need to handle things specially (and non-ideally) if * the number of the periods in the schedule doesn't match well with the * intervals that we're trying to schedule. * * Here's an explanation of the scheme we'll implement, assuming 8 periods. * - If interval is 1, we need to take up space in each of the 8 * periods we're scheduling. Easy. * - If interval is 2, we need to take up space in half of the * periods. Again, easy. * - If interval is 3, we actually need to fall back to interval 1. * Why? Because we might need time in any period. AKA for the * first 8 periods, we'll be in slot 0, 3, 6. Then we'll be * in slot 1, 4, 7. Then we'll be in 2, 5. Then we'll be back to * 0, 3, and 6. Since we could be in any frame we need to reserve * for all of them. Sucks, but that's what you gotta do. Note that * if we were instead scheduling 8 * 3 = 24 we'd do much better, but * then we need more memory and time to do scheduling. * - If interval is 4, easy. * - If interval is 5, we again need interval 1. The schedule will be * 0, 5, 2, 7, 4, 1, 6, 3, 0 * - If interval is 6, we need interval 2. 0, 6, 4, 2. * - If interval is 7, we need interval 1. * - If interval is 8, we need interval 8. * * If you do the math, you'll see that we need to pretend that interval is * equal to the greatest_common_divisor(interval, periods_in_map). * * Note that at the moment this function tends to front-pack the schedule. * In some cases that's really non-ideal (it's hard to schedule things that * need to repeat every period). In other cases it's perfect (you can easily * schedule bigger, less often repeating things). * * Here's the algorithm in action (8 periods, 5 bits per period): * |** | |** | |** | |** | | OK 2 bits, intv 2 at 0 * |*****| ***|*****| ***|*****| ***|*****| ***| OK 3 bits, intv 3 at 2 * |*****|* ***|*****| ***|*****|* ***|*****| ***| OK 1 bits, intv 4 at 5 * |** |* |** | |** |* |** | | Remv 3 bits, intv 3 at 2 * |*** |* |*** | |*** |* |*** | | OK 1 bits, intv 6 at 2 * |**** |* * |**** | * |**** |* * |**** | * | OK 1 bits, intv 1 at 3 * |**** |**** |**** | *** |**** |**** |**** | *** | OK 2 bits, intv 2 at 6 * |*****|*****|*****| ****|*****|*****|*****| ****| OK 1 bits, intv 1 at 4 * |*****|*****|*****| ****|*****|*****|*****| ****| FAIL 1 bits, intv 1 * | ***|*****| ***| ****| ***|*****| ***| ****| Remv 2 bits, intv 2 at 0 * | ***| ****| ***| ****| ***| ****| ***| ****| Remv 1 bits, intv 4 at 5 * | **| ****| **| ****| **| ****| **| ****| Remv 1 bits, intv 6 at 2 * | *| ** *| *| ** *| *| ** *| *| ** *| Remv 1 bits, intv 1 at 3 * | *| *| *| *| *| *| *| *| Remv 2 bits, intv 2 at 6 * | | | | | | | | | Remv 1 bits, intv 1 at 4 * |** | |** | |** | |** | | OK 2 bits, intv 2 at 0 * |*** | |** | |*** | |** | | OK 1 bits, intv 4 at 2 * |*****| |** **| |*****| |** **| | OK 2 bits, intv 2 at 3 * |*****|* |** **| |*****|* |** **| | OK 1 bits, intv 4 at 5 * |*****|*** |** **| ** |*****|*** |** **| ** | OK 2 bits, intv 2 at 6 * |*****|*****|** **| ****|*****|*****|** **| ****| OK 2 bits, intv 2 at 8 * |*****|*****|*****| ****|*****|*****|*****| ****| OK 1 bits, intv 4 at 12 * * This function is pretty generic and could be easily abstracted if anything * needed similar scheduling. * * Returns either -ENOSPC or a >= 0 start bit which should be passed to the * unschedule routine. The map bitmap will be updated on a non-error result. */ static int pmap_schedule(unsigned long *map, int bits_per_period, int periods_in_map, int num_bits, int interval, int start, bool only_one_period) { … } /** * pmap_unschedule() - Undo work done by pmap_schedule() * * @map: See pmap_schedule(). * @bits_per_period: See pmap_schedule(). * @periods_in_map: See pmap_schedule(). * @num_bits: The number of bits that was passed to schedule. * @interval: The interval that was passed to schedule. * @start: The return value from pmap_schedule(). */ static void pmap_unschedule(unsigned long *map, int bits_per_period, int periods_in_map, int num_bits, int interval, int start) { … } /** * dwc2_get_ls_map() - Get the map used for the given qh * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. * * We'll always get the periodic map out of our TT. Note that even if we're * running the host straight in low speed / full speed mode it appears as if * a TT is allocated for us, so we'll use it. If that ever changes we can * add logic here to get a map out of "hsotg" if !qh->do_split. * * Returns: the map or NULL if a map couldn't be found. */ static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } #ifdef DWC2_PRINT_SCHEDULE /* * pmap_print() - Print the given periodic map * * Will attempt to print out the periodic schedule. * * @map: See pmap_schedule(). * @bits_per_period: See pmap_schedule(). * @periods_in_map: See pmap_schedule(). * @period_name: The name of 1 period, like "uFrame" * @units: The name of the units, like "us". * @print_fn: The function to call for printing. * @print_data: Opaque data to pass to the print function. */ static void pmap_print(unsigned long *map, int bits_per_period, int periods_in_map, const char *period_name, const char *units, void (*print_fn)(const char *str, void *data), void *print_data) { int period; for (period = 0; period < periods_in_map; period++) { DECLARE_SEQ_BUF(buf, 64); int period_start = period * bits_per_period; int period_end = period_start + bits_per_period; int start = 0; int count = 0; bool printed = false; int i; for (i = period_start; i < period_end + 1; i++) { /* Handle case when ith bit is set */ if (i < period_end && bitmap_find_next_zero_area(map, i + 1, i, 1, 0) != i) { if (count == 0) start = i - period_start; count++; continue; } /* ith bit isn't set; don't care if count == 0 */ if (count == 0) continue; if (!printed) seq_buf_printf(&buf, "%s %d: ", period_name, period); else seq_buf_puts(&buf, ", "); printed = true; seq_buf_printf(&buf, "%d %s -%3d %s", start, units, start + count - 1, units); count = 0; } if (printed) print_fn(seq_buf_str(&buf), print_data); } } struct dwc2_qh_print_data { struct dwc2_hsotg *hsotg; struct dwc2_qh *qh; }; /** * dwc2_qh_print() - Helper function for dwc2_qh_schedule_print() * * @str: The string to print * @data: A pointer to a struct dwc2_qh_print_data */ static void dwc2_qh_print(const char *str, void *data) { struct dwc2_qh_print_data *print_data = data; dwc2_sch_dbg(print_data->hsotg, "QH=%p ...%s\n", print_data->qh, str); } /** * dwc2_qh_schedule_print() - Print the periodic schedule * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH to print. */ static void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { struct dwc2_qh_print_data print_data = { hsotg, qh }; int i; /* * The printing functions are quite slow and inefficient. * If we don't have tracing turned on, don't run unless the special * define is turned on. */ if (qh->schedule_low_speed) { unsigned long *map = dwc2_get_ls_map(hsotg, qh); dwc2_sch_dbg(hsotg, "QH=%p LS/FS trans: %d=>%d us @ %d us", qh, qh->device_us, DWC2_ROUND_US_TO_SLICE(qh->device_us), DWC2_US_PER_SLICE * qh->ls_start_schedule_slice); if (map) { dwc2_sch_dbg(hsotg, "QH=%p Whole low/full speed map %p now:\n", qh, map); pmap_print(map, DWC2_LS_PERIODIC_SLICES_PER_FRAME, DWC2_LS_SCHEDULE_FRAMES, "Frame ", "slices", dwc2_qh_print, &print_data); } } for (i = 0; i < qh->num_hs_transfers; i++) { struct dwc2_hs_transfer_time *trans_time = qh->hs_transfers + i; int uframe = trans_time->start_schedule_us / DWC2_HS_PERIODIC_US_PER_UFRAME; int rel_us = trans_time->start_schedule_us % DWC2_HS_PERIODIC_US_PER_UFRAME; dwc2_sch_dbg(hsotg, "QH=%p HS trans #%d: %d us @ uFrame %d + %d us\n", qh, i, trans_time->duration_us, uframe, rel_us); } if (qh->num_hs_transfers) { dwc2_sch_dbg(hsotg, "QH=%p Whole high speed map now:\n", qh); pmap_print(hsotg->hs_periodic_bitmap, DWC2_HS_PERIODIC_US_PER_UFRAME, DWC2_HS_SCHEDULE_UFRAMES, "uFrame", "us", dwc2_qh_print, &print_data); } } #else static inline void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) {}; #endif /** * dwc2_ls_pmap_schedule() - Schedule a low speed QH * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. * @search_slice: We'll start trying to schedule at the passed slice. * Remember that slices are the units of the low speed * schedule (think 25us or so). * * Wraps pmap_schedule() with the right parameters for low speed scheduling. * * Normally we schedule low speed devices on the map associated with the TT. * * Returns: 0 for success or an error code. */ static int dwc2_ls_pmap_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, int search_slice) { … } /** * dwc2_ls_pmap_unschedule() - Undo work done by dwc2_ls_pmap_schedule() * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. */ static void dwc2_ls_pmap_unschedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_hs_pmap_schedule - Schedule in the main high speed schedule * * This will schedule something on the main dwc2 schedule. * * We'll start looking in qh->hs_transfers[index].start_schedule_us. We'll * update this with the result upon success. We also use the duration from * the same structure. * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. * @only_one_period: If true we will limit ourselves to just looking at * one period (aka one 100us chunk). This is used if we have * already scheduled something on the low speed schedule and * need to find something that matches on the high speed one. * @index: The index into qh->hs_transfers that we're working with. * * Returns: 0 for success or an error code. Upon success the * dwc2_hs_transfer_time specified by "index" will be updated. */ static int dwc2_hs_pmap_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, bool only_one_period, int index) { … } /** * dwc2_hs_pmap_unschedule() - Undo work done by dwc2_hs_pmap_schedule() * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. * @index: Transfer index */ static void dwc2_hs_pmap_unschedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, int index) { … } /** * dwc2_uframe_schedule_split - Schedule a QH for a periodic split xfer. * * This is the most complicated thing in USB. We have to find matching time * in both the global high speed schedule for the port and the low speed * schedule for the TT associated with the given device. * * Being here means that the host must be running in high speed mode and the * device is in low or full speed mode (and behind a hub). * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. */ static int dwc2_uframe_schedule_split(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_uframe_schedule_hs - Schedule a QH for a periodic high speed xfer. * * Basically this just wraps dwc2_hs_pmap_schedule() to provide a clean * interface. * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. */ static int dwc2_uframe_schedule_hs(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_uframe_schedule_ls - Schedule a QH for a periodic low/full speed xfer. * * Basically this just wraps dwc2_ls_pmap_schedule() to provide a clean * interface. * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. */ static int dwc2_uframe_schedule_ls(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_uframe_schedule - Schedule a QH for a periodic xfer. * * Calls one of the 3 sub-function depending on what type of transfer this QH * is for. Also adds some printing. * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. */ static int dwc2_uframe_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_uframe_unschedule - Undoes dwc2_uframe_schedule(). * * @hsotg: The HCD state structure for the DWC OTG controller. * @qh: QH for the periodic transfer. */ static void dwc2_uframe_unschedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_pick_first_frame() - Choose 1st frame for qh that's already scheduled * * Takes a qh that has already been scheduled (which means we know we have the * bandwdith reserved for us) and set the next_active_frame and the * start_active_frame. * * This is expected to be called on qh's that weren't previously actively * running. It just picks the next frame that we can fit into without any * thought about the past. * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH for a periodic endpoint * */ static void dwc2_pick_first_frame(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_do_reserve() - Make a periodic reservation * * Try to allocate space in the periodic schedule. Depending on parameters * this might use the microframe scheduler or the dumb scheduler. * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH for the periodic transfer. * * Returns: 0 upon success; error upon failure. */ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_do_unreserve() - Actually release the periodic reservation * * This function actually releases the periodic bandwidth that was reserved * by the given qh. * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH for the periodic transfer. */ static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_unreserve_timer_fn() - Timer function to release periodic reservation * * According to the kernel doc for usb_submit_urb() (specifically the part about * "Reserved Bandwidth Transfers"), we need to keep a reservation active as * long as a device driver keeps submitting. Since we're using HCD_BH to give * back the URB we need to give the driver a little bit of time before we * release the reservation. This worker is called after the appropriate * delay. * * @t: Address to a qh unreserve_work. */ static void dwc2_unreserve_timer_fn(struct timer_list *t) { … } /** * dwc2_check_max_xfer_size() - Checks that the max transfer size allowed in a * host channel is large enough to handle the maximum data transfer in a single * (micro)frame for a periodic transfer * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH for a periodic endpoint * * Return: 0 if successful, negative error code otherwise */ static int dwc2_check_max_xfer_size(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_schedule_periodic() - Schedules an interrupt or isochronous transfer in * the periodic schedule * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH for the periodic transfer. The QH should already contain the * scheduling information. * * Return: 0 if successful, negative error code otherwise */ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_deschedule_periodic() - Removes an interrupt or isochronous transfer * from the periodic schedule * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: QH for the periodic transfer */ static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_wait_timer_fn() - Timer function to re-queue after waiting * * As per the spec, a NAK indicates that "a function is temporarily unable to * transmit or receive data, but will eventually be able to do so without need * of host intervention". * * That means that when we encounter a NAK we're supposed to retry. * * ...but if we retry right away (from the interrupt handler that saw the NAK) * then we can end up with an interrupt storm (if the other side keeps NAKing * us) because on slow enough CPUs it could take us longer to get out of the * interrupt routine than it takes for the device to send another NAK. That * leads to a constant stream of NAK interrupts and the CPU locks. * * ...so instead of retrying right away in the case of a NAK we'll set a timer * to retry some time later. This function handles that timer and moves the * qh back to the "inactive" list, then queues transactions. * * @t: Pointer to wait_timer in a qh. * * Return: HRTIMER_NORESTART to not automatically restart this timer. */ static enum hrtimer_restart dwc2_wait_timer_fn(struct hrtimer *t) { … } /** * dwc2_qh_init() - Initializes a QH structure * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: The QH to init * @urb: Holds the information about the device/endpoint needed to initialize * the QH * @mem_flags: Flags for allocating memory. */ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, struct dwc2_hcd_urb *urb, gfp_t mem_flags) { … } /** * dwc2_hcd_qh_create() - Allocates and initializes a QH * * @hsotg: The HCD state structure for the DWC OTG controller * @urb: Holds the information about the device/endpoint needed * to initialize the QH * @mem_flags: Flags for allocating memory. * * Return: Pointer to the newly allocated QH, or NULL on error */ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, struct dwc2_hcd_urb *urb, gfp_t mem_flags) { … } /** * dwc2_hcd_qh_free() - Frees the QH * * @hsotg: HCD instance * @qh: The QH to free * * QH should already be removed from the list. QTD list should already be empty * if called from URB Dequeue. * * Must NOT be called with interrupt disabled or spinlock held */ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_hcd_qh_add() - Adds a QH to either the non periodic or periodic * schedule if it is not already in the schedule. If the QH is already in * the schedule, no action is taken. * * @hsotg: The HCD state structure for the DWC OTG controller * @qh: The QH to add * * Return: 0 if successful, negative error code otherwise */ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_hcd_qh_unlink() - Removes a QH from either the non-periodic or periodic * schedule. Memory is not freed. * * @hsotg: The HCD state structure * @qh: QH to remove from schedule */ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { … } /** * dwc2_next_for_periodic_split() - Set next_active_frame midway thru a split. * * This is called for setting next_active_frame for periodic splits for all but * the first packet of the split. Confusing? I thought so... * * Periodic splits are single low/full speed transfers that we end up splitting * up into several high speed transfers. They always fit into one full (1 ms) * frame but might be split over several microframes (125 us each). We to put * each of the parts on a very specific high speed frame. * * This function figures out where the next active uFrame needs to be. * * @hsotg: The HCD state structure * @qh: QH for the periodic transfer. * @frame_number: The current frame number. * * Return: number missed by (or 0 if we didn't miss). */ static int dwc2_next_for_periodic_split(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, u16 frame_number) { … } /** * dwc2_next_periodic_start() - Set next_active_frame for next transfer start * * This is called for setting next_active_frame for a periodic transfer for * all cases other than midway through a periodic split. This will also update * start_active_frame. * * Since we _always_ keep start_active_frame as the start of the previous * transfer this is normally pretty easy: we just add our interval to * start_active_frame and we've got our answer. * * The tricks come into play if we miss. In that case we'll look for the next * slot we can fit into. * * @hsotg: The HCD state structure * @qh: QH for the periodic transfer. * @frame_number: The current frame number. * * Return: number missed by (or 0 if we didn't miss). */ static int dwc2_next_periodic_start(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, u16 frame_number) { … } /* * Deactivates a QH. For non-periodic QHs, removes the QH from the active * non-periodic schedule. The QH is added to the inactive non-periodic * schedule if any QTDs are still attached to the QH. * * For periodic QHs, the QH is removed from the periodic queued schedule. If * there are any QTDs still attached to the QH, the QH is added to either the * periodic inactive schedule or the periodic ready schedule and its next * scheduled frame is calculated. The QH is placed in the ready schedule if * the scheduled frame has been reached already. Otherwise it's placed in the * inactive schedule. If there are no QTDs attached to the QH, the QH is * completely removed from the periodic schedule. */ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, int sched_next_periodic_split) { … } /** * dwc2_hcd_qtd_init() - Initializes a QTD structure * * @qtd: The QTD to initialize * @urb: The associated URB */ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) { … } /** * dwc2_hcd_qtd_add() - Adds a QTD to the QTD-list of a QH * Caller must hold driver lock. * * @hsotg: The DWC HCD structure * @qtd: The QTD to add * @qh: Queue head to add qtd to * * Return: 0 if successful, negative error code otherwise * * If the QH to which the QTD is added is not currently scheduled, it is placed * into the proper schedule based on its EP type. */ int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, struct dwc2_qh *qh) { … }