1/***************************************************************************** 2 ** FILE NAME : ifxhcd.h 3 ** PROJECT : IFX USB sub-system V3 4 ** MODULES : IFX USB sub-system Host and Device driver 5 ** SRC VERSION : 3.2 6 ** DATE : 1/Jan/2011 7 ** AUTHOR : Chen, Howard 8 ** DESCRIPTION : This file contains the structures, constants, and interfaces for 9 ** the Host Contoller Driver (HCD). 10 ** 11 ** The Host Controller Driver (HCD) is responsible for translating requests 12 ** from the USB Driver into the appropriate actions on the IFXUSB controller. 13 ** It isolates the USBD from the specifics of the controller by providing an 14 ** API to the USBD. 15 ** FUNCTIONS : 16 ** COMPILER : gcc 17 ** REFERENCE : Synopsys DWC-OTG Driver 2.7 18 ** COPYRIGHT : Copyright (c) 2010 19 ** LANTIQ DEUTSCHLAND GMBH, 20 ** Am Campeon 3, 85579 Neubiberg, Germany 21 ** 22 ** This program is free software; you can redistribute it and/or modify 23 ** it under the terms of the GNU General Public License as published by 24 ** the Free Software Foundation; either version 2 of the License, or 25 ** (at your option) any later version. 26 ** 27 ** Version Control Section ** 28 ** $Author$ 29 ** $Date$ 30 ** $Revisions$ 31 ** $Log$ Revision history 32 *****************************************************************************/ 33 34/* 35 * This file contains code fragments from Synopsys HS OTG Linux Software Driver. 36 * For this code the following notice is applicable: 37 * 38 * ========================================================================== 39 * 40 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, 41 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless 42 * otherwise expressly agreed to in writing between Synopsys and you. 43 * 44 * The Software IS NOT an item of Licensed Software or Licensed Product under 45 * any End User Software License Agreement or Agreement for Licensed Product 46 * with Synopsys or any supplement thereto. You are permitted to use and 47 * redistribute this Software in source and binary forms, with or without 48 * modification, provided that redistributions of source code must retain this 49 * notice. You may not view, use, disclose, copy or distribute this file or 50 * any information contained herein except pursuant to this license grant from 51 * Synopsys. If you do not agree with this notice, including the disclaimer 52 * below, then you are not authorized to use the Software. 53 * 54 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS 55 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, 58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 61 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 64 * DAMAGE. 65 * ========================================================================== */ 66 67/*! 68 \defgroup IFXUSB_HCD HCD Interface 69 \ingroup IFXUSB_DRIVER_V3 70 \brief The Host Controller Driver (HCD) is responsible for translating requests 71 from the USB Driver into the appropriate actions on the IFXUSB controller. 72 It isolates the USBD from the specifics of the controller by providing an 73 API to the USBD. 74 */ 75 76 77/*! 78 \file ifxhcd.h 79 \ingroup IFXUSB_DRIVER_V3 80 \brief This file contains the structures, constants, and interfaces for 81 the Host Contoller Driver (HCD). 82 */ 83 84#if !defined(__IFXHCD_H__) 85#define __IFXHCD_H__ 86 87 88#define __STRICT_ORDER__ 89 90 91#include <linux/list.h> 92#include <linux/usb.h> 93 94#include <linux/usb/hcd.h> 95 96#include "ifxusb_cif.h" 97#include "ifxusb_plat.h" 98 99 100#undef __INNAKSTOP__ 101#if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_CTRL__) 102 #define __INNAKSTOP__ 1 103#endif 104#if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_BULK__) 105 #define __INNAKSTOP__ 1 106#endif 107 108#undef __PINGSTOP__ 109#if !defined(__PINGSTOP__) && defined(__PINGSTOP_CTRL__) 110 #define __PINGSTOP__ 1 111#endif 112#if !defined(__PINGSTOP__) && defined(__PINGSTOP_BULK__) 113 #define __PINGSTOP__ 1 114#endif 115 116#undef __NAKSTOP__ 117#if defined(__INNAKSTOP__) || defined(__PINGSTOP__) 118 #define __NAKSTOP__ 1 119#endif 120 121 122/* Phases for control transfers.*/ 123typedef enum ifxhcd_epqh_phase { 124 EPQH_IDLE=0, 125 EPQH_DISABLING, 126// EPQH_COMPLETING, 127 EPQH_STDBY, 128 EPQH_READY, 129 EPQH_ACTIVE 130} ifxhcd_epqh_phase_e; 131 132/* Phases for control transfers.*/ 133typedef enum ifxhcd_urbd_phase { 134 URBD_IDLE=0, 135 URBD_ACTIVE, 136 URBD_STARTING, 137 URBD_STARTED, 138 URBD_FINISHING, //URB_Complete already scheduled 139 URBD_COMPLETING, //To URB_Complete, it's normal finish 140 URBD_DEQUEUEING, //To URB_Complete, it's abnormal finish 141} ifxhcd_urbd_phase_e; 142 143/* Phases for control transfers.*/ 144typedef enum ifxhcd_hc_phase { 145 HC_IDLE=0, 146 HC_ASSIGNED, 147 HC_WAITING, 148 HC_STARTING, 149 HC_STARTED, 150 HC_STOPPING, 151 HC_STOPPED, 152} ifxhcd_hc_phase_e; 153 154/*! 155 \addtogroup IFXUSB_HCD 156 */ 157/*@{*/ 158 159/*! \typedef ifxhcd_control_phase_e 160 \brief Phases for control transfers. 161*/ 162 163typedef enum ifxhcd_control_phase { 164 IFXHCD_CONTROL_SETUP, 165 IFXHCD_CONTROL_DATA, 166 IFXHCD_CONTROL_STATUS 167} ifxhcd_control_phase_e; 168 169/*! \typedef ifxhcd_halt_status_e 170 \brief Reasons for halting a host channel. 171*/ 172typedef enum ifxhcd_halt_status 173{ 174 HC_XFER_NO_HALT_STATUS, // Initial 175 HC_XFER_COMPLETE, // Xact complete without error, upward 176 HC_XFER_URB_COMPLETE, // Xfer complete without error, short upward 177 HC_XFER_STALL, // HC stopped abnormally, upward/downward 178 HC_XFER_XACT_ERR, // HC stopped abnormally, upward 179 HC_XFER_FRAME_OVERRUN, // HC stopped abnormally, upward 180 HC_XFER_BABBLE_ERR, // HC stopped abnormally, upward 181 HC_XFER_AHB_ERR, // HC stopped abnormally, upward 182 HC_XFER_DATA_TOGGLE_ERR, 183 HC_XFER_URB_DEQUEUE, // HC stopper manually, downward 184 HC_XFER_NO_URB, // HC stopper manually, downward 185 HC_XFER_NO_EPQH, // HC stopper manually, downward 186 #ifdef __NAKSTOP__ 187 HC_XFER_NAK, // HC stopped by nak monitor, downward 188 #endif 189 #if defined(__INTRNAKRETRY__) || defined(__INTRINCRETRY__) 190 HC_XFER_INTR_NAK_RETRY, // HC stopped by nak monitor, downward 191 #endif 192} ifxhcd_halt_status_e; 193 194struct ifxhcd_urbd; 195struct ifxhcd_hc ; 196struct ifxhcd_epqh ; 197struct ifxhcd_hcd; 198 199/*! typedef ifxhcd_urbd_t 200 \brief A URB Descriptor (URBD) holds the state of a bulk, control, 201 interrupt, or isochronous transfer. A single URBD is created for each URB 202 (of one of these types) submitted to the HCD. The transfer associated with 203 a URBD may require one or multiple transactions. 204 205 A URBD is linked to a EP Queue Head, which is entered in either the 206 isoc, intr or non-periodic schedule for execution. When a URBD is chosen for 207 execution, some or all of its transactions may be executed. After 208 execution, the state of the URBD is updated. The URBD may be retired if all 209 its transactions are complete or if an error occurred. Otherwise, it 210 remains in the schedule so more transactions can be executed later. 211 */ 212typedef struct ifxhcd_urbd { 213 ifxhcd_urbd_phase_e phase; 214 struct list_head ql; // Hook for EPQH->urbd_list 215 struct urb *urb; /*!< URB for this transfer */ 216 //struct urb { 217 // struct list_head urb_list; 218 // struct list_head anchor_list; 219 // struct usb_anchor * anchor; 220 // struct usb_device * dev; 221 // struct usb_host_endpoint * ep; 222 // unsigned int pipe; 223 // int status; 224 // unsigned int transfer_flags; 225 // void * transfer_buffer; 226 // dma_addr_t transfer_dma; 227 // u32 transfer_buffer_length; 228 // u32 actual_length; 229 // unsigned char * setup_packet; 230 // dma_addr_t setup_dma; 231 // int start_frame; 232 // int number_of_packets; 233 // int interval; 234 // int error_count; 235 // void * context; 236 // usb_complete_t complete; 237 // struct usb_iso_packet_descriptor iso_frame_desc[0]; 238 //}; 239 //urb_list For use by current owner of the URB. 240 //anchor_list membership in the list of an anchor 241 //anchor to anchor URBs to a common mooring 242 //dev Identifies the USB device to perform the request. 243 //ep Points to the endpoint's data structure. Will 244 // eventually replace pipe. 245 //pipe Holds endpoint number, direction, type, and more. 246 // Create these values with the eight macros available; u 247 // sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is 248 // "ctrl", "bulk", "int" or "iso". For example 249 // usb_sndbulkpipe or usb_rcvintpipe. Endpoint numbers 250 // range from zero to fifteen. Note that "in" endpoint two 251 // is a different endpoint (and pipe) from "out" endpoint 252 // two. The current configuration controls the existence, 253 // type, and maximum packet size of any given endpoint. 254 //status This is read in non-iso completion functions to get 255 // the status of the particular request. ISO requests 256 // only use it to tell whether the URB was unlinked; 257 // detailed status for each frame is in the fields of 258 // the iso_frame-desc. 259 //transfer_flags A variety of flags may be used to affect how URB 260 // submission, unlinking, or operation are handled. 261 // Different kinds of URB can use different flags. 262 // URB_SHORT_NOT_OK 263 // URB_ISO_ASAP 264 // URB_NO_TRANSFER_DMA_MAP 265 // URB_NO_SETUP_DMA_MAP 266 // URB_NO_FSBR 267 // URB_ZERO_PACKET 268 // URB_NO_INTERRUPT 269 //transfer_buffer This identifies the buffer to (or from) which the I/O 270 // request will be performed (unless URB_NO_TRANSFER_DMA_MAP 271 // is set). This buffer must be suitable for DMA; allocate it 272 // with kmalloc or equivalent. For transfers to "in" 273 // endpoints, contents of this buffer will be modified. This 274 // buffer is used for the data stage of control transfers. 275 //transfer_dma When transfer_flags includes URB_NO_TRANSFER_DMA_MAP, the 276 // device driver is saying that it provided this DMA address, 277 // which the host controller driver should use in preference 278 // to the transfer_buffer. 279 //transfer_buffer_length How big is transfer_buffer. The transfer may be broken 280 // up into chunks according to the current maximum packet size 281 // for the endpoint, which is a function of the configuration 282 // and is encoded in the pipe. When the length is zero, neither 283 // transfer_buffer nor transfer_dma is used. 284 //actual_length This is read in non-iso completion functions, and it tells 285 // how many bytes (out of transfer_buffer_length) were transferred. 286 // It will normally be the same as requested, unless either an error 287 // was reported or a short read was performed. The URB_SHORT_NOT_OK 288 // transfer flag may be used to make such short reads be reported 289 // as errors. 290 //setup_packet Only used for control transfers, this points to eight bytes of 291 // setup data. Control transfers always start by sending this data 292 // to the device. Then transfer_buffer is read or written, if needed. 293 //setup_dma For control transfers with URB_NO_SETUP_DMA_MAP set, the device 294 // driver has provided this DMA address for the setup packet. The 295 // host controller driver should use this in preference to setup_packet. 296 //start_frame Returns the initial frame for isochronous transfers. 297 //number_of_packets Lists the number of ISO transfer buffers. 298 //interval Specifies the polling interval for interrupt or isochronous transfers. 299 // The units are frames (milliseconds) for for full and low speed devices, 300 // and microframes (1/8 millisecond) for highspeed ones. 301 //error_count Returns the number of ISO transfers that reported errors. 302 //context For use in completion functions. This normally points to request-specific 303 // driver context. 304 //complete Completion handler. This URB is passed as the parameter to the completion 305 // function. The completion function may then do what it likes with the URB, 306 // including resubmitting or freeing it. 307 //iso_frame_desc[0] Used to provide arrays of ISO transfer buffers and to collect the transfer 308 // status for each buffer. 309 310 struct ifxhcd_epqh *epqh; 311 // Actual data portion, not SETUP or STATUS in case of CTRL XFER 312 // DMA adjusted 313 uint8_t *setup_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/ 314 uint8_t *xfer_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/ 315 uint32_t xfer_len; /*!< Total number of bytes to transfer in this xfer. */ 316 317 #if defined(__UNALIGNED_BUF_ADJ__) 318// uint8_t using_aligned_setup; 319 uint8_t *aligned_setup; 320// uint8_t using_aligned_buf; 321 uint8_t *aligned_buf; 322 unsigned aligned_buf_len : 19; 323 #endif 324 #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__) 325 unsigned aligned_checked : 1; 326 #endif 327 unsigned is_in :1; 328 #ifndef __STRICT_ORDER__ 329 struct tasklet_struct complete_urb_sub; 330 #endif 331 332 // For ALL XFER 333 uint8_t error_count; /*!< Holds the number of bus errors that have occurred for a transaction 334 within this transfer. 335 */ 336 // For ISOC XFER only 337 #ifdef __EN_ISOC__ 338 int isoc_frame_index; /*!< Index of the next frame descriptor for an isochronous transfer. A 339 frame descriptor describes the buffer position and length of the 340 data to be transferred in the next scheduled (micro)frame of an 341 isochronous transfer. It also holds status for that transaction. 342 The frame index starts at 0. 343 */ 344 #endif 345 int status; 346} ifxhcd_urbd_t; 347 348/*! typedef ifxhcd_epqh_t 349 \brief A EP Queue Head (EPQH) holds the static characteristics of an endpoint and 350 maintains a list of transfers (URBDs) for that endpoint. A EPQH structure may 351 be entered in either the isoc, intr or non-periodic schedule. 352 */ 353 354typedef struct ifxhcd_epqh { 355 struct ifxhcd_hcd *ifxhcd; 356 struct usb_host_endpoint *sysep; 357 uint8_t devno; 358 359 ifxhcd_epqh_phase_e phase; 360 struct list_head ql_all; 361 struct list_head ql; // Hook for EP Queues 362 struct list_head urbd_list; /*!< List of URBDs for this EPQH. */ 363 #ifdef __STRICT_ORDER__ 364 struct list_head release_list; 365 struct tasklet_struct complete_urb_sub; 366 #endif 367 struct ifxhcd_hc *hc; /*!< Host channel currently processing transfers for this EPQH. */ 368 struct ifxhcd_urbd *urbd; /*!< URBD currently assigned to a host channel for this EPQH. */ 369 uint8_t ep_type; /*!< Endpoint type. One of the following values: 370 - IFXUSB_EP_TYPE_CTRL 371 - IFXUSB_EP_TYPE_ISOC 372 - IFXUSB_EP_TYPE_BULK 373 - IFXUSB_EP_TYPE_INTR 374 */ 375 uint16_t mps; /*!< wMaxPacketSize Field of Endpoint Descriptor. */ 376 #ifdef __EPQD_DESTROY_TIMEOUT__ 377 struct timer_list destroy_timer; 378 #endif 379 380 unsigned need_split : 1 ; 381 unsigned do_ping : 1 ; /*!< Set to 1 to indicate that a PING request should be issued on this 382 channel. If 0, process normally. 383 */ 384 unsigned pause : 1; 385 unsigned period_do : 1; 386 uint16_t interval; /*!< Interval between transfers in (micro)frames. (for INTR)*/ 387 uint16_t period_counter; /*!< Interval between transfers in (micro)frames. */ 388 389 #ifdef __EN_ISOC__ 390 struct tasklet_struct tasklet_next_isoc; 391 uint8_t isoc_now; 392 uint32_t isoc_start_frame; 393 // For SPLITed ISOC XFER only 394 #ifdef __EN_ISOC_SPLIT__ 395 uint8_t isoc_split_pos; /*!< Position of the ISOC split on full/low speed */ 396 uint16_t isoc_split_offset;/*!< Position of the ISOC split in the buffer for the current frame */ 397 #endif 398 #endif 399 spinlock_t urbd_list_lock; 400 int urbd_count; 401} ifxhcd_epqh_t; 402 403 404/*! typedef ifxhcd_hc_t 405 \brief Host channel descriptor. This structure represents the state of a single 406 host channel when acting in host mode. It contains the data items needed to 407 transfer packets to an endpoint via a host channel. 408 */ 409typedef struct ifxhcd_hc 410{ 411 struct ifxhcd_epqh *epqh ; /*!< EP Queue Head for the transfer being processed by this channel. */ 412 uint8_t hc_num ; /*!< Host channel number used for register address lookup */ 413 uint8_t *xfer_buff ; /*!< Pointer to the entire transfer buffer. */ 414 uint32_t xfer_count ; /*!< Number of bytes transferred so far. The offset of the begin of the buf */ 415 uint32_t xfer_len ; /*!< Total number of bytes to transfer in this xfer. */ 416 uint16_t start_pkt_count ; /*!< Packet count at start of transfer. Used to calculate the actual xfer size*/ 417 ifxhcd_halt_status_e halt_status; /*!< Reason for halting the host channel. */ 418 ifxhcd_hc_phase_e phase; 419 420 unsigned dev_addr : 7; /*!< Device to access */ 421 unsigned ep_num : 4; /*!< EP to access */ 422 unsigned is_in : 1; /*!< EP direction. 0: OUT, 1: IN */ 423 unsigned speed : 2; /*!< EP speed. */ 424 unsigned ep_type : 2; /*!< Endpoint type. */ 425 unsigned mps :11; /*!< Max packet size in bytes */ 426 unsigned data_pid_start : 2; /*!< PID for initial transaction. */ 427 unsigned short_rw : 1; /*!< When Tx, means termination needed. 428 When Rx, indicate Short Read */ 429 /* Split settings for the host channel */ 430 unsigned split : 2; /*!< Split: 0-Non Split, 1-SSPLIT, 2&3 CSPLIT */ 431 432 unsigned sof_delay :16; 433 unsigned erron : 1; 434 435 #ifdef __NAKSTOP__ 436 unsigned stop_on : 1; 437// unsigned wait_for_sof_quick : 1; 438 #endif 439 440 ifxhcd_control_phase_e control_phase; /*!< Current phase for control transfers (Setup, Data, or Status). */ 441 uint32_t ssplit_out_xfer_count; /*!< How many bytes transferred during SSPLIT OUT */ 442 #ifdef __DEBUG__ 443 uint32_t start_hcchar_val; 444 #endif 445 uint32_t hcchar; 446 447 /* Split settings for the host channel */ 448 uint8_t hub_addr; /*!< Address of high speed hub */ 449 uint8_t port_addr; /*!< Port of the low/full speed device */ 450 #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__) 451 uint8_t isoc_xact_pos; /*!< Split transaction position */ 452 #endif 453} ifxhcd_hc_t; 454 455 456/*! typedef ifxhcd_hcd_t 457 \brief This structure holds the state of the HCD, including the non-periodic and 458 periodic schedules. 459 */ 460typedef struct ifxhcd_hcd 461{ 462 struct device *dev; 463 struct hc_driver hc_driver; 464 ifxusb_core_if_t core_if; /*!< Pointer to the core interface structure. */ 465 struct usb_hcd *syshcd; 466 467 volatile union 468 { 469 uint32_t d32; 470 struct 471 { 472 unsigned port_connect_status_change : 1; 473 unsigned port_connect_status : 1; 474 unsigned port_reset_change : 1; 475 unsigned port_enable_change : 1; 476 unsigned port_suspend_change : 1; 477 unsigned port_over_current_change : 1; 478 unsigned reserved : 27; 479 } b; 480 } flags; /*!< Internal HCD Flags */ 481 482 struct ifxhcd_hc ifxhc[MAX_EPS_CHANNELS]; /*!< Array of pointers to the host channel descriptors. Allows accessing 483 a host channel descriptor given the host channel number. This is 484 useful in interrupt handlers. 485 */ 486 uint8_t *status_buf; /*!< Buffer to use for any data received during the status phase of a 487 control transfer. Normally no data is transferred during the status 488 phase. This buffer is used as a bit bucket. 489 */ 490 #define IFXHCD_STATUS_BUF_SIZE 64 /*!< buffer size of status phase in CTRL xfer */ 491 492 struct list_head epqh_list_all; 493 struct list_head epqh_list_np; 494 struct list_head epqh_list_intr; 495 #ifdef __EN_ISOC__ 496 struct list_head epqh_list_isoc; 497 #endif 498 499 uint32_t lastframe; 500 501 uint16_t pkt_remaining; 502 uint16_t pkt_remaining_reload; 503 uint16_t pkt_remaining_reload_hs; 504 uint16_t pkt_remaining_reload_fs; 505 uint16_t pkt_remaining_reload_ls; 506 #define PKT_REMAINING_RELOAD_HS 88 507 #define PKT_REMAINING_RELOAD_FS 10 508 #define PKT_REMAINING_RELOAD_LS 20 509 #ifdef __EN_ISOC__ 510 uint8_t isoc_ep_count; 511 #endif 512 513 spinlock_t epqh_list_lock; 514 spinlock_t epqh_list_all_lock; 515 516 struct timer_list host_probe_timer; 517 struct timer_list autoprobe_timer; 518 519 unsigned power_status; 520 int probe_sec; 521 int autoprobe_sec; 522 #ifdef __DYN_SOF_INTR__ 523 uint32_t dyn_sof_count; 524 #define DYN_SOF_COUNT_DEF 40000 525 #endif 526 struct tasklet_struct tasklet_select_eps; /*!< Tasket to do a reset */ 527 struct tasklet_struct tasklet_free_epqh_list ; /*!< Tasket to do a reset */ 528 unsigned disconnecting : 1 ; 529 530 uint8_t pkt_count_limit_bo; 531 uint8_t pkt_count_limit_bi; 532} ifxhcd_hcd_t; 533 534/* Gets the ifxhcd_hcd from a struct usb_hcd */ 535static inline ifxhcd_hcd_t *syshcd_to_ifxhcd(struct usb_hcd *syshcd) 536{ 537 return (ifxhcd_hcd_t *)(syshcd->hcd_priv[0]); 538} 539 540/* Gets the struct usb_hcd that contains a ifxhcd_hcd_t. */ 541static inline struct usb_hcd *ifxhcd_to_syshcd(ifxhcd_hcd_t *ifxhcd) 542{ 543 return (struct usb_hcd *)(ifxhcd->syshcd); 544} 545 546 547extern ifxhcd_epqh_t * sysep_to_epqh(ifxhcd_hcd_t *_ifxhcd, struct usb_host_endpoint *_sysep); 548 549/* HCD Create/Destroy Functions */ 550 extern int ifxhcd_init (ifxhcd_hcd_t *_ifxhcd); 551 extern void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd); 552 553/*Linux HC Driver API Functions */ 554 555extern int ifxhcd_start(struct usb_hcd *hcd); 556extern void ifxhcd_stop (struct usb_hcd *hcd); 557extern int ifxhcd_get_frame_number(struct usb_hcd *hcd); 558 559 560/*! 561 \brief This function does the setup for a data transfer for a host channel and 562 starts the transfer. May be called in either Slave mode or DMA mode. In 563 Slave mode, the caller must ensure that there is sufficient space in the 564 request queue and Tx Data FIFO. 565 566 For an OUT transfer in Slave mode, it loads a data packet into the 567 appropriate FIFO. If necessary, additional data packets will be loaded in 568 the Host ISR. 569 570 For an IN transfer in Slave mode, a data packet is requested. The data 571 packets are unloaded from the Rx FIFO in the Host ISR. If necessary, 572 additional data packets are requested in the Host ISR. 573 574 For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ 575 register along with a packet count of 1 and the channel is enabled. This 576 causes a single PING transaction to occur. Other fields in HCTSIZ are 577 simply set to 0 since no data transfer occurs in this case. 578 579 For a PING transfer in DMA mode, the HCTSIZ register is initialized with 580 all the information required to perform the subsequent data transfer. In 581 addition, the Do Ping bit is set in the HCTSIZ register. In this case, the 582 controller performs the entire PING protocol, then starts the data 583 transfer. 584 585 @param _ifxhc Information needed to initialize the host channel. The xfer_len 586 value may be reduced to accommodate the max widths of the XferSize and 587 PktCnt fields in the HCTSIZn register. The multi_count value may be changed 588 to reflect the final xfer_len value. 589 */ 590extern void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc); 591 592#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) 593extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep, struct urb *_urb, gfp_t mem_flags); 594extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb); 595#else 596extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct urb *_urb, gfp_t mem_flags); 597extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status); 598#endif 599extern irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd); 600 601extern void ifxhcd_endpoint_disable(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep); 602 603extern int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf); 604extern int ifxhcd_hub_control( struct usb_hcd *_syshcd, 605 u16 _typeReq, 606 u16 _wValue, 607 u16 _wIndex, 608 char *_buf, 609 u16 _wLength); 610 611/*@}*/ 612 613/*! \brief Transaction Execution Functions */ 614/*@{*/ 615extern void ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status); 616 617/*! 618 \brief Clears the transfer state for a host channel. This function is normally 619 called after a transfer is done and the host channel is being released. 620 */ 621extern void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc); 622 623/*! 624 \brief Attempts to halt a host channel. This function should only be called in 625 Slave mode or to abort a transfer in either Slave mode or DMA mode. Under 626 normal circumstances in DMA mode, the controller halts the channel when the 627 transfer is complete or a condition occurs that requires application 628 intervention. 629 630 In DMA mode, always sets the Channel Enable and Channel Disable bits of the 631 HCCHARn register. The controller ensures there is space in the request 632 queue before submitting the halt request. 633 634 Some time may elapse before the core flushes any posted requests for this 635 host channel and halts. The Channel Halted interrupt handler completes the 636 deactivation of the host channel. 637 */ 638extern int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if, 639 ifxhcd_hc_t *_ifxhc, 640 ifxhcd_halt_status_e _halt_status); 641 642/*! 643 \brief Prepares a host channel for transferring packets to/from a specific 644 endpoint. The HCCHARn register is set up with the characteristics specified 645 in _ifxhc. Host channel interrupts that may need to be serviced while this 646 transfer is in progress are enabled. 647 */ 648extern void ifxhcd_hc_init(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc); 649 650/*! 651 \brief This function is called to handle the disconnection of host port. 652 */ 653int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd); 654/*@}*/ 655 656/*! \brief Interrupt Handler Functions */ 657/*@{*/ 658extern irqreturn_t ifxhcd_oc_irq(int _irq, void *_dev); 659 660extern int32_t ifxhcd_handle_oc_intr(ifxhcd_hcd_t *_ifxhcd); 661extern int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd); 662/*@}*/ 663 664 665/*! \brief Schedule Queue Functions */ 666/*@{*/ 667extern void ifxhcd_epqh_free (ifxhcd_epqh_t *_epqh); 668extern void select_eps (ifxhcd_hcd_t *_ifxhcd); 669extern void ifxhcd_epqh_idle(ifxhcd_epqh_t *_epqh); 670extern void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh); 671extern ifxhcd_epqh_t *ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb); 672/*@}*/ 673 674/*! \brief Gets the usb_host_endpoint associated with an URB. */ 675static inline struct usb_host_endpoint *ifxhcd_urb_to_endpoint(struct urb *_urb) 676{ 677 struct usb_device *dev = _urb->dev; 678 int ep_num = usb_pipeendpoint(_urb->pipe); 679 680 return (usb_pipein(_urb->pipe))?(dev->ep_in[ep_num]):(dev->ep_out[ep_num]); 681} 682 683/*! 684 * \brief Gets the endpoint number from a _bEndpointAddress argument. The endpoint is 685 * qualified with its direction (possible 32 endpoints per device). 686 */ 687#define ifxhcd_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \ 688 ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4) 689 690 691 692/*! Internal debug function */ 693void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd); 694 695/*@}*//*IFXUSB_HCD*/ 696 697extern struct usb_device *usb_alloc_dev (struct usb_device *parent, struct usb_bus *, unsigned port); 698extern int usb_add_hcd (struct usb_hcd *syshcd, unsigned int irqnum, unsigned long irqflags); 699extern void usb_remove_hcd (struct usb_hcd *syshcd); 700#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) 701extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name); 702#else 703extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, const char *bus_name); 704#endif 705 706#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) 707extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb); 708#else 709extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb,int status); 710#endif 711 712extern void usb_put_hcd (struct usb_hcd *syshcd); 713extern long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount); 714extern char *syserr(int errno); 715 716 717 718static inline void INIT_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd) 719{ 720 spin_lock_init(&_ifxhcd->epqh_list_all_lock); 721} 722static inline void LOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd) 723{ 724 spin_lock(&_ifxhcd->epqh_list_all_lock); 725} 726static inline void UNLOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd) 727{ 728 spin_unlock(&_ifxhcd->epqh_list_all_lock); 729} 730 731static inline void INIT_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd) 732{ 733 spin_lock_init(&_ifxhcd->epqh_list_lock); 734} 735static inline void LOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd) 736{ 737 spin_lock(&_ifxhcd->epqh_list_lock); 738} 739static inline void UNLOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd) 740{ 741 spin_unlock(&_ifxhcd->epqh_list_lock); 742} 743 744static inline void INIT_URBD_LIST(ifxhcd_epqh_t *_epqh) 745{ 746 spin_lock_init(&_epqh->urbd_list_lock); 747} 748static inline void LOCK_URBD_LIST(ifxhcd_epqh_t *_epqh) 749{ 750 spin_lock(&_epqh->urbd_list_lock); 751} 752static inline void UNLOCK_URBD_LIST(ifxhcd_epqh_t *_epqh) 753{ 754 spin_unlock(&_epqh->urbd_list_lock); 755} 756 757#endif // __IFXHCD_H__ 758 759