1/* ========================================================================== 2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.h $ 3 * $Revision: 1.3 $ 4 * $Date: 2008-12-15 06:51:32 $ 5 * $Change: 1064918 $ 6 * 7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, 8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless 9 * otherwise expressly agreed to in writing between Synopsys and you. 10 * 11 * The Software IS NOT an item of Licensed Software or Licensed Product under 12 * any End User Software License Agreement or Agreement for Licensed Product 13 * with Synopsys or any supplement thereto. You are permitted to use and 14 * redistribute this Software in source and binary forms, with or without 15 * modification, provided that redistributions of source code must retain this 16 * notice. You may not view, use, disclose, copy or distribute this file or 17 * any information contained herein except pursuant to this license grant from 18 * Synopsys. If you do not agree with this notice, including the disclaimer 19 * below, then you are not authorized to use the Software. 20 * 21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 31 * DAMAGE. 32 * ========================================================================== */ 33#ifndef DWC_DEVICE_ONLY 34#ifndef __DWC_HCD_H__ 35#define __DWC_HCD_H__ 36 37#include <linux/list.h> 38#include <linux/usb.h> 39#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) 40#include <linux/usb/hcd.h> 41#else 42#include <../drivers/usb/core/hcd.h> 43#endif 44 45struct dwc_otg_device; 46 47#include "dwc_otg_cil.h" 48 49/** 50 * @file 51 * 52 * This file contains the structures, constants, and interfaces for 53 * the Host Contoller Driver (HCD). 54 * 55 * The Host Controller Driver (HCD) is responsible for translating requests 56 * from the USB Driver into the appropriate actions on the DWC_otg controller. 57 * It isolates the USBD from the specifics of the controller by providing an 58 * API to the USBD. 59 */ 60 61/** 62 * Phases for control transfers. 63 */ 64typedef enum dwc_otg_control_phase { 65 DWC_OTG_CONTROL_SETUP, 66 DWC_OTG_CONTROL_DATA, 67 DWC_OTG_CONTROL_STATUS 68} dwc_otg_control_phase_e; 69 70/** Transaction types. */ 71typedef enum dwc_otg_transaction_type { 72 DWC_OTG_TRANSACTION_NONE, 73 DWC_OTG_TRANSACTION_PERIODIC, 74 DWC_OTG_TRANSACTION_NON_PERIODIC, 75 DWC_OTG_TRANSACTION_ALL 76} dwc_otg_transaction_type_e; 77 78/** 79 * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control, 80 * interrupt, or isochronous transfer. A single QTD is created for each URB 81 * (of one of these types) submitted to the HCD. The transfer associated with 82 * a QTD may require one or multiple transactions. 83 * 84 * A QTD is linked to a Queue Head, which is entered in either the 85 * non-periodic or periodic schedule for execution. When a QTD is chosen for 86 * execution, some or all of its transactions may be executed. After 87 * execution, the state of the QTD is updated. The QTD may be retired if all 88 * its transactions are complete or if an error occurred. Otherwise, it 89 * remains in the schedule so more transactions can be executed later. 90 */ 91typedef struct dwc_otg_qtd { 92 /** 93 * Determines the PID of the next data packet for the data phase of 94 * control transfers. Ignored for other transfer types.<br> 95 * One of the following values: 96 * - DWC_OTG_HC_PID_DATA0 97 * - DWC_OTG_HC_PID_DATA1 98 */ 99 uint8_t data_toggle; 100 101 /** Current phase for control transfers (Setup, Data, or Status). */ 102 dwc_otg_control_phase_e control_phase; 103 104 /** Keep track of the current split type 105 * for FS/LS endpoints on a HS Hub */ 106 uint8_t complete_split; 107 108 /** How many bytes transferred during SSPLIT OUT */ 109 uint32_t ssplit_out_xfer_count; 110 111 /** 112 * Holds the number of bus errors that have occurred for a transaction 113 * within this transfer. 114 */ 115 uint8_t error_count; 116 117 /** 118 * Index of the next frame descriptor for an isochronous transfer. A 119 * frame descriptor describes the buffer position and length of the 120 * data to be transferred in the next scheduled (micro)frame of an 121 * isochronous transfer. It also holds status for that transaction. 122 * The frame index starts at 0. 123 */ 124 int isoc_frame_index; 125 126 /** Position of the ISOC split on full/low speed */ 127 uint8_t isoc_split_pos; 128 129 /** Position of the ISOC split in the buffer for the current frame */ 130 uint16_t isoc_split_offset; 131 132 /** URB for this transfer */ 133 struct urb *urb; 134 135 /** This list of QTDs */ 136 struct list_head qtd_list_entry; 137 138} dwc_otg_qtd_t; 139 140/** 141 * A Queue Head (QH) holds the static characteristics of an endpoint and 142 * maintains a list of transfers (QTDs) for that endpoint. A QH structure may 143 * be entered in either the non-periodic or periodic schedule. 144 */ 145typedef struct dwc_otg_qh { 146 /** 147 * Endpoint type. 148 * One of the following values: 149 * - USB_ENDPOINT_XFER_CONTROL 150 * - USB_ENDPOINT_XFER_ISOC 151 * - USB_ENDPOINT_XFER_BULK 152 * - USB_ENDPOINT_XFER_INT 153 */ 154 uint8_t ep_type; 155 uint8_t ep_is_in; 156 157 /** wMaxPacketSize Field of Endpoint Descriptor. */ 158 uint16_t maxp; 159 160 /** 161 * Determines the PID of the next data packet for non-control 162 * transfers. Ignored for control transfers.<br> 163 * One of the following values: 164 * - DWC_OTG_HC_PID_DATA0 165 * - DWC_OTG_HC_PID_DATA1 166 */ 167 uint8_t data_toggle; 168 169 /** Ping state if 1. */ 170 uint8_t ping_state; 171 172 /** 173 * List of QTDs for this QH. 174 */ 175 struct list_head qtd_list; 176 177 /** Host channel currently processing transfers for this QH. */ 178 dwc_hc_t *channel; 179 180 /** QTD currently assigned to a host channel for this QH. */ 181 dwc_otg_qtd_t *qtd_in_process; 182 183 /** Full/low speed endpoint on high-speed hub requires split. */ 184 uint8_t do_split; 185 186 /** @name Periodic schedule information */ 187 /** @{ */ 188 189 /** Bandwidth in microseconds per (micro)frame. */ 190 uint8_t usecs; 191 192 /** Interval between transfers in (micro)frames. */ 193 uint16_t interval; 194 195 /** 196 * (micro)frame to initialize a periodic transfer. The transfer 197 * executes in the following (micro)frame. 198 */ 199 uint16_t sched_frame; 200 201 /** (micro)frame at which last start split was initialized. */ 202 uint16_t start_split_frame; 203 204 /** @} */ 205 206 /** Entry for QH in either the periodic or non-periodic schedule. */ 207 struct list_head qh_list_entry; 208 209 /* For non-dword aligned buffer support */ 210 uint8_t *dw_align_buf; 211 dma_addr_t dw_align_buf_dma; 212} dwc_otg_qh_t; 213 214/** 215 * This structure holds the state of the HCD, including the non-periodic and 216 * periodic schedules. 217 */ 218typedef struct dwc_otg_hcd { 219 /** The DWC otg device pointer */ 220 struct dwc_otg_device *otg_dev; 221 222 /** DWC OTG Core Interface Layer */ 223 dwc_otg_core_if_t *core_if; 224 225 /** Internal DWC HCD Flags */ 226 volatile union dwc_otg_hcd_internal_flags { 227 uint32_t d32; 228 struct { 229 unsigned port_connect_status_change : 1; 230 unsigned port_connect_status : 1; 231 unsigned port_reset_change : 1; 232 unsigned port_enable_change : 1; 233 unsigned port_suspend_change : 1; 234 unsigned port_over_current_change : 1; 235 unsigned reserved : 27; 236 } b; 237 } flags; 238 239 /** 240 * Inactive items in the non-periodic schedule. This is a list of 241 * Queue Heads. Transfers associated with these Queue Heads are not 242 * currently assigned to a host channel. 243 */ 244 struct list_head non_periodic_sched_inactive; 245 246 /** 247 * Active items in the non-periodic schedule. This is a list of 248 * Queue Heads. Transfers associated with these Queue Heads are 249 * currently assigned to a host channel. 250 */ 251 struct list_head non_periodic_sched_active; 252 253 /** 254 * Pointer to the next Queue Head to process in the active 255 * non-periodic schedule. 256 */ 257 struct list_head *non_periodic_qh_ptr; 258 259 /** 260 * Inactive items in the periodic schedule. This is a list of QHs for 261 * periodic transfers that are _not_ scheduled for the next frame. 262 * Each QH in the list has an interval counter that determines when it 263 * needs to be scheduled for execution. This scheduling mechanism 264 * allows only a simple calculation for periodic bandwidth used (i.e. 265 * must assume that all periodic transfers may need to execute in the 266 * same frame). However, it greatly simplifies scheduling and should 267 * be sufficient for the vast majority of OTG hosts, which need to 268 * connect to a small number of peripherals at one time. 269 * 270 * Items move from this list to periodic_sched_ready when the QH 271 * interval counter is 0 at SOF. 272 */ 273 struct list_head periodic_sched_inactive; 274 275 /** 276 * List of periodic QHs that are ready for execution in the next 277 * frame, but have not yet been assigned to host channels. 278 * 279 * Items move from this list to periodic_sched_assigned as host 280 * channels become available during the current frame. 281 */ 282 struct list_head periodic_sched_ready; 283 284 /** 285 * List of periodic QHs to be executed in the next frame that are 286 * assigned to host channels. 287 * 288 * Items move from this list to periodic_sched_queued as the 289 * transactions for the QH are queued to the DWC_otg controller. 290 */ 291 struct list_head periodic_sched_assigned; 292 293 /** 294 * List of periodic QHs that have been queued for execution. 295 * 296 * Items move from this list to either periodic_sched_inactive or 297 * periodic_sched_ready when the channel associated with the transfer 298 * is released. If the interval for the QH is 1, the item moves to 299 * periodic_sched_ready because it must be rescheduled for the next 300 * frame. Otherwise, the item moves to periodic_sched_inactive. 301 */ 302 struct list_head periodic_sched_queued; 303 304 /** 305 * Total bandwidth claimed so far for periodic transfers. This value 306 * is in microseconds per (micro)frame. The assumption is that all 307 * periodic transfers may occur in the same (micro)frame. 308 */ 309 uint16_t periodic_usecs; 310 311 /** 312 * Frame number read from the core at SOF. The value ranges from 0 to 313 * DWC_HFNUM_MAX_FRNUM. 314 */ 315 uint16_t frame_number; 316 317 /** 318 * Free host channels in the controller. This is a list of 319 * dwc_hc_t items. 320 */ 321 struct list_head free_hc_list; 322 323 /** 324 * Number of host channels assigned to periodic transfers. Currently 325 * assuming that there is a dedicated host channel for each periodic 326 * transaction and at least one host channel available for 327 * non-periodic transactions. 328 */ 329 int periodic_channels; 330 331 /** 332 * Number of host channels assigned to non-periodic transfers. 333 */ 334 int non_periodic_channels; 335 336 /** 337 * Array of pointers to the host channel descriptors. Allows accessing 338 * a host channel descriptor given the host channel number. This is 339 * useful in interrupt handlers. 340 */ 341 dwc_hc_t *hc_ptr_array[MAX_EPS_CHANNELS]; 342 343 /** 344 * Buffer to use for any data received during the status phase of a 345 * control transfer. Normally no data is transferred during the status 346 * phase. This buffer is used as a bit bucket. 347 */ 348 uint8_t *status_buf; 349 350 /** 351 * DMA address for status_buf. 352 */ 353 dma_addr_t status_buf_dma; 354#define DWC_OTG_HCD_STATUS_BUF_SIZE 64 355 356 /** 357 * Structure to allow starting the HCD in a non-interrupt context 358 * during an OTG role change. 359 */ 360#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 361 struct work_struct start_work; 362#else 363 struct delayed_work start_work; 364#endif 365 366 /** 367 * Connection timer. An OTG host must display a message if the device 368 * does not connect. Started when the VBus power is turned on via 369 * sysfs attribute "buspower". 370 */ 371 struct timer_list conn_timer; 372 373 /* Tasket to do a reset */ 374 struct tasklet_struct *reset_tasklet; 375 376 /* */ 377 spinlock_t lock; 378 379#ifdef DEBUG 380 uint32_t frrem_samples; 381 uint64_t frrem_accum; 382 383 uint32_t hfnum_7_samples_a; 384 uint64_t hfnum_7_frrem_accum_a; 385 uint32_t hfnum_0_samples_a; 386 uint64_t hfnum_0_frrem_accum_a; 387 uint32_t hfnum_other_samples_a; 388 uint64_t hfnum_other_frrem_accum_a; 389 390 uint32_t hfnum_7_samples_b; 391 uint64_t hfnum_7_frrem_accum_b; 392 uint32_t hfnum_0_samples_b; 393 uint64_t hfnum_0_frrem_accum_b; 394 uint32_t hfnum_other_samples_b; 395 uint64_t hfnum_other_frrem_accum_b; 396#endif 397} dwc_otg_hcd_t; 398 399/** Gets the dwc_otg_hcd from a struct usb_hcd */ 400static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd) 401{ 402 return (dwc_otg_hcd_t *)(hcd->hcd_priv); 403} 404 405/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */ 406static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd) 407{ 408 return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv); 409} 410 411/** @name HCD Create/Destroy Functions */ 412/** @{ */ 413extern int dwc_otg_hcd_init(struct device *dev); 414extern void dwc_otg_hcd_remove(struct device *dev); 415/** @} */ 416 417/** @name Linux HC Driver API Functions */ 418/** @{ */ 419 420extern int dwc_otg_hcd_start(struct usb_hcd *hcd); 421extern void dwc_otg_hcd_stop(struct usb_hcd *hcd); 422extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd); 423extern void dwc_otg_hcd_free(struct usb_hcd *hcd); 424extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd, 425 struct urb *urb, 426#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 427 int mem_flags 428#else 429 gfp_t mem_flags 430#endif 431 ); 432extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, 433#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 434#endif 435 struct urb *urb, int status); 436extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd, 437 struct usb_host_endpoint *ep); 438extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd 439#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 440 , struct pt_regs *regs 441#endif 442 ); 443extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, 444 char *buf); 445extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd, 446 u16 typeReq, 447 u16 wValue, 448 u16 wIndex, 449 char *buf, 450 u16 wLength); 451 452/** @} */ 453 454/** @name Transaction Execution Functions */ 455/** @{ */ 456extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *hcd); 457extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *hcd, 458 dwc_otg_transaction_type_e tr_type); 459extern void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *_hcd, struct urb *urb, 460 int status); 461/** @} */ 462 463/** @name Interrupt Handler Functions */ 464/** @{ */ 465extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd); 466extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t *dwc_otg_hcd); 467extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *dwc_otg_hcd); 468extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd); 469extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t *dwc_otg_hcd); 470extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t *dwc_otg_hcd); 471extern int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t *dwc_otg_hcd); 472extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(dwc_otg_hcd_t *dwc_otg_hcd); 473extern int32_t dwc_otg_hcd_handle_disconnect_intr(dwc_otg_hcd_t *dwc_otg_hcd); 474extern int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t *dwc_otg_hcd); 475extern int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t *dwc_otg_hcd, uint32_t num); 476extern int32_t dwc_otg_hcd_handle_session_req_intr(dwc_otg_hcd_t *dwc_otg_hcd); 477extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(dwc_otg_hcd_t *dwc_otg_hcd); 478/** @} */ 479 480 481/** @name Schedule Queue Functions */ 482/** @{ */ 483 484/* Implemented in dwc_otg_hcd_queue.c */ 485extern dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t *hcd, struct urb *urb); 486extern void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, struct urb *urb); 487extern void dwc_otg_hcd_qh_free(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh); 488extern int dwc_otg_hcd_qh_add(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh); 489extern void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh); 490extern void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, int sched_csplit); 491 492/** Remove and free a QH */ 493static inline void dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd_t *hcd, 494 dwc_otg_qh_t *qh) 495{ 496 dwc_otg_hcd_qh_remove(hcd, qh); 497 dwc_otg_hcd_qh_free(hcd, qh); 498} 499 500/** Allocates memory for a QH structure. 501 * @return Returns the memory allocate or NULL on error. */ 502static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(void) 503{ 504 return (dwc_otg_qh_t *) kmalloc(sizeof(dwc_otg_qh_t), GFP_KERNEL); 505} 506 507extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(struct urb *urb); 508extern void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t *qtd, struct urb *urb); 509extern int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *qtd, dwc_otg_hcd_t *dwc_otg_hcd); 510 511/** Allocates memory for a QTD structure. 512 * @return Returns the memory allocate or NULL on error. */ 513static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(void) 514{ 515 return (dwc_otg_qtd_t *) kmalloc(sizeof(dwc_otg_qtd_t), GFP_KERNEL); 516} 517 518/** Frees the memory for a QTD structure. QTD should already be removed from 519 * list. 520 * @param[in] qtd QTD to free.*/ 521static inline void dwc_otg_hcd_qtd_free(dwc_otg_qtd_t *qtd) 522{ 523 kfree(qtd); 524} 525 526/** Removes a QTD from list. 527 * @param[in] hcd HCD instance. 528 * @param[in] qtd QTD to remove from list. */ 529static inline void dwc_otg_hcd_qtd_remove(dwc_otg_hcd_t *hcd, dwc_otg_qtd_t *qtd) 530{ 531 unsigned long flags; 532 SPIN_LOCK_IRQSAVE(&hcd->lock, flags); 533 list_del(&qtd->qtd_list_entry); 534 SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags); 535} 536 537/** Remove and free a QTD */ 538static inline void dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd_t *hcd, dwc_otg_qtd_t *qtd) 539{ 540 dwc_otg_hcd_qtd_remove(hcd, qtd); 541 dwc_otg_hcd_qtd_free(qtd); 542} 543 544/** @} */ 545 546 547/** @name Internal Functions */ 548/** @{ */ 549dwc_otg_qh_t *dwc_urb_to_qh(struct urb *urb); 550void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *hcd); 551void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *hcd); 552/** @} */ 553 554/** Gets the usb_host_endpoint associated with an URB. */ 555static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb) 556{ 557 struct usb_device *dev = urb->dev; 558 int ep_num = usb_pipeendpoint(urb->pipe); 559 560 if (usb_pipein(urb->pipe)) 561 return dev->ep_in[ep_num]; 562 else 563 return dev->ep_out[ep_num]; 564} 565 566/** 567 * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is 568 * qualified with its direction (possible 32 endpoints per device). 569 */ 570#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \ 571 ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4) 572 573/** Gets the QH that contains the list_head */ 574#define dwc_list_to_qh(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qh_t, qh_list_entry) 575 576/** Gets the QTD that contains the list_head */ 577#define dwc_list_to_qtd(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qtd_t, qtd_list_entry) 578 579/** Check if QH is non-periodic */ 580#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \ 581 (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL)) 582 583/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */ 584#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) 585 586/** Packet size for any kind of endpoint descriptor */ 587#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) 588 589/** 590 * Returns true if _frame1 is less than or equal to _frame2. The comparison is 591 * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the 592 * frame number when the max frame number is reached. 593 */ 594static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2) 595{ 596 return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <= 597 (DWC_HFNUM_MAX_FRNUM >> 1); 598} 599 600/** 601 * Returns true if _frame1 is greater than _frame2. The comparison is done 602 * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame 603 * number when the max frame number is reached. 604 */ 605static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2) 606{ 607 return (frame1 != frame2) && 608 (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) < 609 (DWC_HFNUM_MAX_FRNUM >> 1)); 610} 611 612/** 613 * Increments _frame by the amount specified by _inc. The addition is done 614 * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value. 615 */ 616static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc) 617{ 618 return (frame + inc) & DWC_HFNUM_MAX_FRNUM; 619} 620 621static inline uint16_t dwc_full_frame_num(uint16_t frame) 622{ 623 return (frame & DWC_HFNUM_MAX_FRNUM) >> 3; 624} 625 626static inline uint16_t dwc_micro_frame_num(uint16_t frame) 627{ 628 return frame & 0x7; 629} 630 631#ifdef DEBUG 632/** 633 * Macro to sample the remaining PHY clocks left in the current frame. This 634 * may be used during debugging to determine the average time it takes to 635 * execute sections of code. There are two possible sample points, "a" and 636 * "b", so the _letter argument must be one of these values. 637 * 638 * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For 639 * example, "cat /sys/devices/lm0/hcd_frrem". 640 */ 641#define dwc_sample_frrem(_hcd, _qh, _letter) \ 642{ \ 643 hfnum_data_t hfnum; \ 644 dwc_otg_qtd_t *qtd; \ 645 qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \ 646 if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \ 647 hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \ 648 switch (hfnum.b.frnum & 0x7) { \ 649 case 7: \ 650 _hcd->hfnum_7_samples_##_letter++; \ 651 _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \ 652 break; \ 653 case 0: \ 654 _hcd->hfnum_0_samples_##_letter++; \ 655 _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \ 656 break; \ 657 default: \ 658 _hcd->hfnum_other_samples_##_letter++; \ 659 _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \ 660 break; \ 661 } \ 662 } \ 663} 664#else 665#define dwc_sample_frrem(_hcd, _qh, _letter) 666#endif 667#endif 668#endif /* DWC_DEVICE_ONLY */ 669