1 /*****************************************************************************
2 ** FILE NAME : ifxhcd.h
3 ** PROJECT : IFX USB sub-system V3
4 ** MODULES : IFX USB sub-system Host and Device driver
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : This file contains the structures, constants, and interfaces for
9 ** the Host Contoller Driver (HCD).
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
17 ** REFERENCE : Synopsys DWC-OTG Driver 2.7
18 ** COPYRIGHT : Copyright (c) 2010
19 ** LANTIQ DEUTSCHLAND GMBH,
20 ** Am Campeon 3, 85579 Neubiberg, Germany
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.
27 ** Version Control Section **
31 ** $Log$ Revision history
32 *****************************************************************************/
35 * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
36 * For this code the following notice is applicable:
38 * ==========================================================================
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.
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.
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
65 * ========================================================================== */
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
79 \ingroup IFXUSB_DRIVER_V3
80 \brief This file contains the structures, constants, and interfaces for
81 the Host Contoller Driver (HCD).
84 #if !defined(__IFXHCD_H__)
88 #define __STRICT_ORDER__
91 #include <linux/list.h>
92 #include <linux/usb.h>
94 #include <linux/usb/hcd.h>
96 #include "ifxusb_cif.h"
97 #include "ifxusb_plat.h"
101 #if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_CTRL__)
102 #define __INNAKSTOP__ 1
104 #if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_BULK__)
105 #define __INNAKSTOP__ 1
109 #if !defined(__PINGSTOP__) && defined(__PINGSTOP_CTRL__)
110 #define __PINGSTOP__ 1
112 #if !defined(__PINGSTOP__) && defined(__PINGSTOP_BULK__)
113 #define __PINGSTOP__ 1
117 #if defined(__INNAKSTOP__) || defined(__PINGSTOP__)
118 #define __NAKSTOP__ 1
122 /* Phases for control transfers.*/
123 typedef enum ifxhcd_epqh_phase {
130 } ifxhcd_epqh_phase_e;
132 /* Phases for control transfers.*/
133 typedef enum ifxhcd_urbd_phase {
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;
143 /* Phases for control transfers.*/
144 typedef enum ifxhcd_hc_phase {
155 \addtogroup IFXUSB_HCD
159 /*! \typedef ifxhcd_control_phase_e
160 \brief Phases for control transfers.
163 typedef enum ifxhcd_control_phase {
164 IFXHCD_CONTROL_SETUP,
166 IFXHCD_CONTROL_STATUS
167 } ifxhcd_control_phase_e;
169 /*! \typedef ifxhcd_halt_status_e
170 \brief Reasons for halting a host channel.
172 typedef enum ifxhcd_halt_status
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
187 HC_XFER_NAK, // HC stopped by nak monitor, downward
189 #if defined(__INTRNAKRETRY__) || defined(__INTRINCRETRY__)
190 HC_XFER_INTR_NAK_RETRY, // HC stopped by nak monitor, downward
192 } ifxhcd_halt_status_e;
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.
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.
212 typedef 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 */
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;
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;
232 // int number_of_packets;
236 // usb_complete_t complete;
237 // struct usb_iso_packet_descriptor iso_frame_desc[0];
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.
264 // URB_NO_TRANSFER_DMA_MAP
265 // URB_NO_SETUP_DMA_MAP
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
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
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.
310 struct ifxhcd_epqh *epqh;
311 // Actual data portion, not SETUP or STATUS in case of CTRL XFER
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. */
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;
324 #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
325 unsigned aligned_checked : 1;
328 #ifndef __STRICT_ORDER__
329 struct tasklet_struct complete_urb_sub;
333 uint8_t error_count; /*!< Holds the number of bus errors that have occurred for a transaction
334 within this transfer.
336 // For ISOC XFER only
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.
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.
354 typedef struct ifxhcd_epqh {
355 struct ifxhcd_hcd *ifxhcd;
356 struct usb_host_endpoint *sysep;
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;
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
375 uint16_t mps; /*!< wMaxPacketSize Field of Endpoint Descriptor. */
376 #ifdef __EPQD_DESTROY_TIMEOUT__
377 struct timer_list destroy_timer;
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.
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. */
390 struct tasklet_struct tasklet_next_isoc;
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 */
399 spinlock_t urbd_list_lock;
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.
409 typedef struct ifxhcd_hc
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;
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 */
432 unsigned sof_delay :16;
436 unsigned stop_on : 1;
437 // unsigned wait_for_sof_quick : 1;
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 */
443 uint32_t start_hcchar_val;
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 */
456 /*! typedef ifxhcd_hcd_t
457 \brief This structure holds the state of the HCD, including the non-periodic and
460 typedef struct ifxhcd_hcd
463 struct hc_driver hc_driver;
464 ifxusb_core_if_t core_if; /*!< Pointer to the core interface structure. */
465 struct usb_hcd *syshcd;
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;
480 } flags; /*!< Internal HCD Flags */
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.
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.
490 #define IFXHCD_STATUS_BUF_SIZE 64 /*!< buffer size of status phase in CTRL xfer */
492 struct list_head epqh_list_all;
493 struct list_head epqh_list_np;
494 struct list_head epqh_list_intr;
496 struct list_head epqh_list_isoc;
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
510 uint8_t isoc_ep_count;
513 spinlock_t epqh_list_lock;
514 spinlock_t epqh_list_all_lock;
516 struct timer_list host_probe_timer;
517 struct timer_list autoprobe_timer;
519 unsigned power_status;
522 #ifdef __DYN_SOF_INTR__
523 uint32_t dyn_sof_count;
524 #define DYN_SOF_COUNT_DEF 40000
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 ;
530 uint8_t pkt_count_limit_bo;
531 uint8_t pkt_count_limit_bi;
534 /* Gets the ifxhcd_hcd from a struct usb_hcd */
535 static inline ifxhcd_hcd_t *syshcd_to_ifxhcd(struct usb_hcd *syshcd)
537 return (ifxhcd_hcd_t *)(syshcd->hcd_priv[0]);
540 /* Gets the struct usb_hcd that contains a ifxhcd_hcd_t. */
541 static inline struct usb_hcd *ifxhcd_to_syshcd(ifxhcd_hcd_t *ifxhcd)
543 return (struct usb_hcd *)(ifxhcd->syshcd);
547 extern ifxhcd_epqh_t * sysep_to_epqh(ifxhcd_hcd_t *_ifxhcd, struct usb_host_endpoint *_sysep);
549 /* HCD Create/Destroy Functions */
550 extern int ifxhcd_init (ifxhcd_hcd_t *_ifxhcd);
551 extern void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd);
553 /*Linux HC Driver API Functions */
555 extern int ifxhcd_start(struct usb_hcd *hcd);
556 extern void ifxhcd_stop (struct usb_hcd *hcd);
557 extern int ifxhcd_get_frame_number(struct usb_hcd *hcd);
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.
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
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.
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.
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
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.
590 extern void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc);
592 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
593 extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep, struct urb *_urb, gfp_t mem_flags);
594 extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb);
596 extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct urb *_urb, gfp_t mem_flags);
597 extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status);
599 extern irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd);
601 extern void ifxhcd_endpoint_disable(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep);
603 extern int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf);
604 extern int ifxhcd_hub_control( struct usb_hcd *_syshcd,
613 /*! \brief Transaction Execution Functions */
615 extern void ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status);
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.
621 extern void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
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
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.
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.
638 extern int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
640 ifxhcd_halt_status_e _halt_status);
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.
648 extern void ifxhcd_hc_init(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
651 \brief This function is called to handle the disconnection of host port.
653 int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd);
656 /*! \brief Interrupt Handler Functions */
658 extern irqreturn_t ifxhcd_oc_irq(int _irq, void *_dev);
660 extern int32_t ifxhcd_handle_oc_intr(ifxhcd_hcd_t *_ifxhcd);
661 extern int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd);
665 /*! \brief Schedule Queue Functions */
667 extern void ifxhcd_epqh_free (ifxhcd_epqh_t *_epqh);
668 extern void select_eps (ifxhcd_hcd_t *_ifxhcd);
669 extern void ifxhcd_epqh_idle(ifxhcd_epqh_t *_epqh);
670 extern void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh);
671 extern ifxhcd_epqh_t *ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb);
674 /*! \brief Gets the usb_host_endpoint associated with an URB. */
675 static inline struct usb_host_endpoint *ifxhcd_urb_to_endpoint(struct urb *_urb)
677 struct usb_device *dev = _urb->dev;
678 int ep_num = usb_pipeendpoint(_urb->pipe);
680 return (usb_pipein(_urb->pipe))?(dev->ep_in[ep_num]):(dev->ep_out[ep_num]);
684 * \brief Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
685 * qualified with its direction (possible 32 endpoints per device).
687 #define ifxhcd_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
688 ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
692 /*! Internal debug function */
693 void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd);
697 extern struct usb_device *usb_alloc_dev (struct usb_device *parent, struct usb_bus *, unsigned port);
698 extern int usb_add_hcd (struct usb_hcd *syshcd, unsigned int irqnum, unsigned long irqflags);
699 extern void usb_remove_hcd (struct usb_hcd *syshcd);
700 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
701 extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name);
703 extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, const char *bus_name);
706 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
707 extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb);
709 extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb,int status);
712 extern void usb_put_hcd (struct usb_hcd *syshcd);
713 extern long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount);
714 extern char *syserr(int errno);
718 static inline void INIT_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
720 spin_lock_init(&_ifxhcd->epqh_list_all_lock);
722 static inline void LOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
724 spin_lock(&_ifxhcd->epqh_list_all_lock);
726 static inline void UNLOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
728 spin_unlock(&_ifxhcd->epqh_list_all_lock);
731 static inline void INIT_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
733 spin_lock_init(&_ifxhcd->epqh_list_lock);
735 static inline void LOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
737 spin_lock(&_ifxhcd->epqh_list_lock);
739 static inline void UNLOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
741 spin_unlock(&_ifxhcd->epqh_list_lock);
744 static inline void INIT_URBD_LIST(ifxhcd_epqh_t *_epqh)
746 spin_lock_init(&_epqh->urbd_list_lock);
748 static inline void LOCK_URBD_LIST(ifxhcd_epqh_t *_epqh)
750 spin_lock(&_epqh->urbd_list_lock);
752 static inline void UNLOCK_URBD_LIST(ifxhcd_epqh_t *_epqh)
754 spin_unlock(&_epqh->urbd_list_lock);
757 #endif // __IFXHCD_H__