/* periodic schedule support */ #define DEFAULT_I_TDPS 1024/* some HCs can do less */ unsigned periodic_size;
__hc32 *periodic; /* hw periodic table */
dma_addr_t periodic_dma; struct list_head intr_qh_list; unsigned i_thresh; /* uframes HC might cache */
union fotg210_shadow *pshadow; /* mirror hw periodic table */ struct fotg210_qh *intr_unlink; struct fotg210_qh *intr_unlink_last; unsigned intr_unlink_cycle; unsigned now_frame; /* frame from HC hardware */ unsigned next_frame; /* scan periodic, start here */ unsigned intr_count; /* intr activity count */ unsigned isoc_count; /* isoc activity count */ unsigned periodic_count; /* periodic activity count */ /* max periodic time per uframe */ unsigned uframe_periodic_max;
/* list of itds completed while now_frame was still active */ struct list_head cached_itd_list; struct fotg210_itd *last_itd_to_free;
/* per root hub port */ unsignedlong reset_done[FOTG210_MAX_ROOT_PORTS];
/* bit vectors (one bit per port) *whichportswerealreadysuspendedatthestartofabussuspend
*/ unsignedlong bus_suspended;
/* which ports are edicated to the companion controller */ unsignedlong companion_ports;
/* which ports are owned by the companion during a bus suspend */ unsignedlong owned_ports;
/* which ports have the change-suspend feature turned on */ unsignedlong port_c_suspend;
/* which ports are suspended */ unsignedlong suspended_ports;
/* which ports have started to resume */ unsignedlong resuming_ports;
/* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ struct dma_pool *qtd_pool; /* one or more per qh */ struct dma_pool *itd_pool; /* itd per iso urb */
/* type tag from {qh,itd,fstn}->hw_next */ #define Q_NEXT_TYPE(fotg210, dma) ((dma) & cpu_to_hc32(fotg210, 3 << 1))
/* *Nowthefollowingdefinesarenotconvertedusingthe *cpu_to_le32()macroanymore,sincewehavetosupport *"dynamic"switchingbetweenbeandlesupport,sothatthedriver *canbeusedononesystemwithSoCEHCIcontrollerusingbig-endian *descriptorsaswellasanormallittle-endianPCIEHCIcontroller.
*/ /* values for that type tag */ #define Q_TYPE_ITD (0 << 1) #define Q_TYPE_QH (1 << 1) #define Q_TYPE_SITD (2 << 1) #define Q_TYPE_FSTN (3 << 1)
/* next async queue entry, or pointer to interrupt/periodic QH */ #define QH_NEXT(fotg210, dma) \
(cpu_to_hc32(fotg210, (((u32)dma)&~0x01f)|Q_TYPE_QH))
/* for periodic/async schedules and qtd lists, mark end of list */ #define FOTG210_LIST_END(fotg210) \
cpu_to_hc32(fotg210, 1) /* "null pointer" to hw */
/* first part defined by EHCI spec */ struct fotg210_qh_hw {
__hc32 hw_next; /* see EHCI 3.6.1 */
__hc32 hw_info1; /* see EHCI 3.6.2 */ #define QH_CONTROL_EP (1 << 27) /* FS/LS control endpoint */ #define QH_HEAD (1 << 15) /* Head of async reclamation list */ #define QH_TOGGLE_CTL (1 << 14) /* Data toggle control */ #define QH_HIGH_SPEED (2 << 12) /* Endpoint speed */ #define QH_LOW_SPEED (1 << 12) #define QH_FULL_SPEED (0 << 12) #define QH_INACTIVATE (1 << 7) /* Inactivate on next transaction */
__hc32 hw_info2; /* see EHCI 3.6.2 */ #define QH_SMASK 0x000000ff #define QH_CMASK 0x0000ff00 #define QH_HUBADDR 0x007f0000 #define QH_HUBPORT 0x3f800000 #define QH_MULT 0xc0000000
__hc32 hw_current; /* qtd list - see EHCI 3.6.4 */
/* qtd overlay (hardware parts of a struct fotg210_qtd) */
__hc32 hw_qtd_next;
__hc32 hw_alt_next;
__hc32 hw_token;
__hc32 hw_buf[5];
__hc32 hw_buf_hi[5];
} __aligned(32);
struct fotg210_qh { struct fotg210_qh_hw *hw; /* Must come first */ /* the rest is HCD-private */
dma_addr_t qh_dma; /* address of qh */ union fotg210_shadow qh_next; /* ptr to qh; or periodic */ struct list_head qtd_list; /* sw qtd list */ struct list_head intr_node; /* list of intr QHs */ struct fotg210_qtd *dummy; struct fotg210_qh *unlink_next; /* next on unlink list */
unsigned unlink_cycle;
u8 needs_rescan; /* Dequeue during giveback */
u8 qh_state; #define QH_STATE_LINKED 1/* HC sees this */ #define QH_STATE_UNLINK 2/* HC may still see this */ #define QH_STATE_IDLE 3/* HC doesn't see this */ #define QH_STATE_UNLINK_WAIT 4/* LINKED and on unlink q */ #define QH_STATE_COMPLETING 5/* don't touch token.HALT */
/* description of one iso transaction (up to 3 KB data if highspeed) */ struct fotg210_iso_packet { /* These will be copied to iTD when scheduling */
u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */
__hc32 transaction; /* itd->hw_transaction[i] |= */
u8 cross; /* buf crosses pages */ /* for full speed OUT splits */
u32 buf1;
};
/* temporary schedule data for packets from iso urbs (both speeds) *eachpacketisonelogicalusbtransactiontothedevice(notTT), *beginningatstream->next_uframe
*/ struct fotg210_iso_sched { struct list_head td_list; unsigned span; struct fotg210_iso_packet packet[];
};
/* *fotg210_iso_stream-groupsall(s)itdsforthisendpoint. *actslikeaqhwould,ifEHCIhadthemforISO.
*/ struct fotg210_iso_stream { /* first field matches fotg210_hq, but is NULL */ struct fotg210_qh_hw *hw;
__hc32 hw_bufp[7]; /* see EHCI 3.3.3 */
__hc32 hw_bufp_hi[7]; /* Appendix B */
/* the rest is HCD-private */
dma_addr_t itd_dma; /* for this itd */ union fotg210_shadow itd_next; /* ptr to periodic q entry */
struct urb *urb; struct fotg210_iso_stream *stream; /* endpoint's queue */ struct list_head itd_list; /* list of stream's itds */
/* any/all hw_transactions here may be used by that urb */ unsigned frame; /* where scheduled */ unsigned pg; unsigned index[8]; /* in urb->iso_frame_desc */
} __aligned(32);
/* Returns the speed of a device attached to a port on the root hub. */ staticinlineunsignedint
fotg210_port_speed(struct fotg210_hcd *fotg210, unsignedint portsc)
{ switch (fotg210_get_speed(fotg210, portsc)) { case0: return0; case1: return USB_PORT_STAT_LOW_SPEED; case2: default: return USB_PORT_STAT_HIGH_SPEED;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.