#define UHCI_NUMFRAMES 1024/* in the frame list [array] */ #define UHCI_MAX_SOF_NUMBER 2047/* in an SOF packet */ #define CAN_SCHEDULE_FRAMES 1000/* how far in the future frames
* can be scheduled */ #define MAX_PHASE 32/* Periodic scheduling length */
/* When no queues need Full-Speed Bandwidth Reclamation,
* delay this long before turning FSBR off */ #define FSBR_OFF_DELAY msecs_to_jiffies(10)
/* If a queue hasn't advanced after this much time, assume it is stuck */ #define QH_WAIT_TIMEOUT msecs_to_jiffies(200)
/* *OneroleofaQHistoholdaqueueofTDsforsomeendpoint.OneQHgoes *witheachendpoint,andqh->element(updatedbytheHC)iseither: *-thenextunprocessedTDintheendpoint'squeue,or *-UHCI_PTR_TERM(whenthere'snomoretrafficforthisendpoint). * *TheotherroleofaQHistoserveasa"skeleton"framelistentry,sowe *caneasilyspliceaQHforsomeendpointintothescheduleattheright *place.Thenqh->elementisUHCI_PTR_TERM. * *Intheschedule,qh->linkmaintainsalistofQHsseenbytheHC: *skel1-->ep1-qh-->ep2-qh-->...-->skel2-->... * *qh->nodeisthesoftwareequivalentofqh->link.Thedifferences *arethatthesoftwarelistisdoubly-linkedandQHsintheUNLINKING *stateareonthesoftwarelistbutnotthehardwareschedule. * *ForbookkeepingpurposeswemaintainQHsevenforIsochronousendpoints, *buttheynevergetaddedtothehardwareschedule.
*/ #define QH_STATE_IDLE 1/* QH is not being used */ #define QH_STATE_UNLINKING 2/* QH has been removed from the *schedulebutthehardwaremay
* still be using it */ #define QH_STATE_ACTIVE 3/* QH is on the schedule */
struct uhci_qh { /* Hardware fields */
__hc32 link; /* Next QH in the schedule */
__hc32 element; /* Queue element (TD) pointer */
/* Software fields */
dma_addr_t dma_handle;
struct list_head node; /* Node in the list of QHs */ struct usb_host_endpoint *hep; /* Endpoint information */ struct usb_device *udev; struct list_head queue; /* Queue of urbps for this QH */ struct uhci_td *dummy_td; /* Dummy TD to end the queue */ struct uhci_td *post_td; /* Last TD completed */
struct usb_iso_packet_descriptor *iso_packet_desc; /* Next urb->iso_frame_desc entry */ unsignedlong advance_jiffies; /* Time of last queue advance */ unsignedint unlink_frame; /* When the QH was unlinked */ unsignedint period; /* For Interrupt and Isochronous QHs */ short phase; /* Between 0 and period-1 */ short load; /* Periodic time requirement, in us */ unsignedint iso_frame; /* Frame # for iso_packet_desc */
int state; /* QH_STATE_xxx; see above */ int type; /* Queue type (control, bulk, etc) */ int skel; /* Skeleton queue number */
unsignedint initial_toggle:1; /* Endpoint's current toggle value */ unsignedint needs_fixup:1; /* Must fix the TD toggle values */ unsignedint is_stopped:1; /* Queue was stopped by error/unlink */ unsignedint wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ unsignedint bandwidth_reserved:1; /* Periodic bandwidth has
* been allocated */
} __attribute__((aligned(16)));
/* The following entries refer to sublists of skel_async_qh */ #define SKEL_LS_CONTROL 20 #define SKEL_FS_CONTROL 21 #define SKEL_FSBR SKEL_FS_CONTROL #define SKEL_BULK 22
/* *TheUHCIcontrollerandroothub
*/
/* *Statesfortheroothub: * *Toprevent"bouncing"inthepresenceofelectricalnoise, *whentherearenodevicesattachedwedelayfor1secondinthe *RUNNING_NODEVSstatebeforeswitchingtotheAUTO_STOPPEDstate. * *(NotethattheAUTO_STOPPEDstatewon'tbenecessaryoncethehub *driverlearnstoautosuspend.)
*/ enum uhci_rh_state { /* In the following states the HC must be halted.
* These two must come first. */
UHCI_RH_RESET,
UHCI_RH_SUSPENDED,
UHCI_RH_AUTO_STOPPED,
UHCI_RH_RESUMING,
/* In this state the HC changes from running to halted,
* so it can legally appear either way. */
UHCI_RH_SUSPENDING,
/* In the following states it's an error if the HC is halted.
* These two must come last. */
UHCI_RH_RUNNING, /* The normal state */
UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */
};
struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */ struct uhci_qh *next_qh; /* Next QH to scan */
spinlock_t lock;
dma_addr_t frame_dma_handle; /* Hardware frame list */
__hc32 *frame; void **frame_cpu; /* CPU's frame list */
enum uhci_rh_state rh_state; unsignedlong auto_stop_time; /* When to AUTO_STOP */
unsignedint frame_number; /* As of last check */ unsignedint is_stopped; #define UHCI_IS_STOPPED 9999/* Larger than a frame # */ unsignedint last_iso_frame; /* Frame of last scan */ unsignedint cur_iso_frame; /* Frame for current scan */
unsignedint scan_in_progress:1; /* Schedule scan is running */ unsignedint need_rescan:1; /* Redo the schedule scan */ unsignedint dead:1; /* Controller has died */ unsignedint RD_enable:1; /* Suspended root hub with Resume-Detectinterrupts
enabled */ unsignedint is_initialized:1; /* Data structure is usable */ unsignedint fsbr_is_on:1; /* FSBR is turned on */ unsignedint fsbr_is_wanted:1; /* Does any URB want FSBR? */ unsignedint fsbr_expiring:1; /* FSBR is timing out */
struct timer_list fsbr_timer; /* For turning off FBSR */
/* Silicon quirks */ unsignedint oc_low:1; /* OverCurrent bit active low */ unsignedint wait_for_hp:1; /* Wait for HP port reset */ unsignedint big_endian_mmio:1; /* Big endian registers */ unsignedint big_endian_desc:1; /* Big endian descriptors */ unsignedint is_aspeed:1; /* Aspeed impl. workarounds */
/* Support for port suspend/resume/reset */ unsignedlong port_c_suspend; /* Bit-arrays of ports */ unsignedlong resuming_ports; unsignedlong ports_timeout; /* Time to stop signalling */
struct list_head idle_qh_list; /* Where the idle QHs live */
int rh_numports; /* Number of root-hub ports */
wait_queue_head_t waitqh; /* endpoint_disable waiters */ int num_waiting; /* Number of waiters */
int total_load; /* Sum of array values */ short load[MAX_PHASE]; /* Periodic allocations */
struct clk *clk; /* (optional) clock source */
/* Reset host controller */ void (*reset_hc) (struct uhci_hcd *uhci); int (*check_and_reset_hc) (struct uhci_hcd *uhci); /* configure_hc should perform arch specific settings, if needed */ void (*configure_hc) (struct uhci_hcd *uhci); /* Check for broken resume detect interrupts */ int (*resume_detect_interrupts_are_broken) (struct uhci_hcd *uhci); /* Check for broken global suspend */ int (*global_suspend_mode_is_broken) (struct uhci_hcd *uhci);
};
/* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ staticinlinestruct uhci_hcd *hcd_to_uhci(struct usb_hcd *hcd)
{ return (struct uhci_hcd *) (hcd->hcd_priv);
} staticinlinestruct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
{ return container_of((void *) uhci, struct usb_hcd, hcd_priv);
}
#else /* Support non-PCI host controllers */ #ifdefined(CONFIG_USB_PCI) && defined(HAS_IOPORT) /* Support PCI and non-PCI host controllers */ #define uhci_has_pci_registers(u) ((u)->io_addr != 0) #else /* Support non-PCI host controllers only */ #define uhci_has_pci_registers(u) 0 #endif
#ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO /* Support (non-PCI) big endian host controllers */ #define uhci_big_endian_mmio(u) ((u)->big_endian_mmio) #else #define uhci_big_endian_mmio(u) 0 #endif
staticinlineint uhci_aspeed_reg(unsignedint reg)
{ switch (reg) { case USBCMD: return00; case USBSTS: return0x04; case USBINTR: return0x08; case USBFRNUM: return0x80; case USBFLBASEADD: return0x0c; case USBSOF: return0x84; case USBPORTSC1: return0x88; case USBPORTSC2: return0x8c; case USBPORTSC3: return0x90; case USBPORTSC4: return0x94; default:
pr_warn("UHCI: Unsupported register 0x%02x on Aspeed\n", reg); /* Return an unimplemented register */ return0x10;
}
}
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.