Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 264903
b: refs/heads/master
c: e879990
h: refs/heads/master
i:
  264901: ad5f0d0
  264899: 4d8916a
  264895: 76898ac
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Aug 22, 2011
1 parent 481bd24 commit a1f7d54
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dfd8c81fd1c09c740140a2334669994d5c6edcaa
refs/heads/master: e8799906045302776b35b66b16495c575db3b69c
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/ehci-au1xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
/* here we "know" root ports should always stay powered */
ehci_port_power(ehci, 1);

hcd->state = HC_STATE_SUSPENDED;
ehci->rh_state = EHCI_RH_SUSPENDED;

return 0;
}
Expand Down
17 changes: 15 additions & 2 deletions trunk/drivers/usb/host/ehci-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,19 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
}
#undef DBG_SCHED_LIMIT

static const char *rh_state_string(struct ehci_hcd *ehci)
{
switch (ehci->rh_state) {
case EHCI_RH_HALTED:
return "halted";
case EHCI_RH_SUSPENDED:
return "suspended";
case EHCI_RH_RUNNING:
return "running";
}
return "?";
}

static ssize_t fill_registers_buffer(struct debug_buffer *buf)
{
struct usb_hcd *hcd;
Expand Down Expand Up @@ -730,11 +743,11 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
temp = scnprintf (next, size,
"bus %s, device %s\n"
"%s\n"
"EHCI %x.%02x, hcd state %d\n",
"EHCI %x.%02x, rh state %s\n",
hcd->self.controller->bus->name,
dev_name(hcd->self.controller),
hcd->product_desc,
i >> 8, i & 0x0ff, hcd->state);
i >> 8, i & 0x0ff, rh_state_string(ehci));
size -= temp;
next += temp;

Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/usb/host/ehci-fsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ static int ehci_fsl_mpc512x_drv_suspend(struct device *dev)

dev_dbg(dev, "suspending...\n");

hcd->state = HC_STATE_SUSPENDED;
ehci->rh_state = EHCI_RH_SUSPENDED;
dev->power.power_state = PMSG_SUSPEND;

/* ignore non-host interrupts */
Expand Down Expand Up @@ -481,7 +481,7 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev)
ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]);

set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
hcd->state = HC_STATE_RUNNING;
ehci->rh_state = EHCI_RH_RUNNING;
dev->power.power_state = PMSG_ON;

tmp = ehci_readl(ehci, &ehci->regs->command);
Expand Down
20 changes: 10 additions & 10 deletions trunk/drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
error = handshake(ehci, ptr, mask, done, usec);
if (error) {
ehci_halt(ehci);
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
ehci->rh_state = EHCI_RH_HALTED;
ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n",
ptr, mask, done, error);
}
Expand Down Expand Up @@ -278,7 +278,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
command |= CMD_RESET;
dbg_cmd (ehci, "reset", command);
ehci_writel(ehci, command, &ehci->regs->command);
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
ehci->rh_state = EHCI_RH_HALTED;
ehci->next_statechange = jiffies;
retval = handshake (ehci, &ehci->regs->command,
CMD_RESET, 0, 250 * 1000);
Expand Down Expand Up @@ -307,7 +307,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
u32 temp;

#ifdef DEBUG
if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
if (ehci->rh_state != EHCI_RH_RUNNING)
BUG ();
#endif

Expand Down Expand Up @@ -356,7 +356,7 @@ static void ehci_iaa_watchdog(unsigned long param)
*/
if (ehci->reclaim
&& !timer_pending(&ehci->iaa_watchdog)
&& HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
&& ehci->rh_state == EHCI_RH_RUNNING) {
u32 cmd, status;

/* If we get here, IAA is *REALLY* late. It's barely
Expand Down Expand Up @@ -496,7 +496,7 @@ static void ehci_work (struct ehci_hcd *ehci)
* misplace IRQs, and should let us run completely without IRQs.
* such lossage has been observed on both VT6202 and VT8235.
*/
if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
if (ehci->rh_state == EHCI_RH_RUNNING &&
(ehci->async->qh_next.ptr != NULL ||
ehci->periodic_sched != 0))
timer_action (ehci, TIMER_IO_WATCHDOG);
Expand All @@ -516,7 +516,7 @@ static void ehci_stop (struct usb_hcd *hcd)
del_timer_sync(&ehci->iaa_watchdog);

spin_lock_irq(&ehci->lock);
if (HC_IS_RUNNING (hcd->state))
if (ehci->rh_state == EHCI_RH_RUNNING)
ehci_quiesce (ehci);

ehci_silence_controller(ehci);
Expand Down Expand Up @@ -741,7 +741,7 @@ static int ehci_run (struct usb_hcd *hcd)
* be started before the port switching actions could complete.
*/
down_write(&ehci_cf_port_reset_rwsem);
hcd->state = HC_STATE_RUNNING;
ehci->rh_state = EHCI_RH_RUNNING;
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
msleep(5);
Expand Down Expand Up @@ -788,7 +788,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)

/* Shared IRQ? */
masked_status = status & INTR_MASK;
if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) {
if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
spin_unlock(&ehci->lock);
return IRQ_NONE;
}
Expand Down Expand Up @@ -952,7 +952,7 @@ static int ehci_urb_enqueue (
static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
/* failfast */
if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim)
if (ehci->rh_state != EHCI_RH_RUNNING && ehci->reclaim)
end_unlink_async(ehci);

/* If the QH isn't linked then there's nothing we can do
Expand Down Expand Up @@ -1079,7 +1079,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
goto idle_timeout;
}

if (!HC_IS_RUNNING (hcd->state))
if (ehci->rh_state != EHCI_RH_RUNNING)
qh->qh_state = QH_STATE_IDLE;
switch (qh->qh_state) {
case QH_STATE_LINKED:
Expand Down
10 changes: 4 additions & 6 deletions trunk/drivers/usb/host/ehci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
}

/* stop schedules, clean any completed work */
if (HC_IS_RUNNING(hcd->state)) {
if (ehci->rh_state == EHCI_RH_RUNNING)
ehci_quiesce (ehci);
hcd->state = HC_STATE_QUIESCING;
}
ehci->command = ehci_readl(ehci, &ehci->regs->command);
ehci_work(ehci);

Expand Down Expand Up @@ -313,7 +311,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)

/* turn off now-idle HC */
ehci_halt (ehci);
hcd->state = HC_STATE_SUSPENDED;
ehci->rh_state = EHCI_RH_SUSPENDED;

if (ehci->reclaim)
end_unlink_async(ehci);
Expand Down Expand Up @@ -382,6 +380,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)

/* restore CMD_RUN, framelist size, and irq threshold */
ehci_writel(ehci, ehci->command, &ehci->regs->command);
ehci->rh_state = EHCI_RH_RUNNING;

/* Some controller/firmware combinations need a delay during which
* they set up the port statuses. See Bugzilla #8190. */
Expand Down Expand Up @@ -452,7 +451,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
}

ehci->next_statechange = jiffies + msecs_to_jiffies(5);
hcd->state = HC_STATE_RUNNING;

/* Now we can safely re-enable irqs */
ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
Expand Down Expand Up @@ -564,7 +562,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
u32 ppcd = 0;

/* if !USB_SUSPEND, root hub timers won't get shut down ... */
if (!HC_IS_RUNNING(hcd->state))
if (ehci->rh_state != EHCI_RH_RUNNING)
return 0;

/* init status to no-changes */
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/ehci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
/* here we "know" root ports should always stay powered */
ehci_port_power(ehci, 1);

hcd->state = HC_STATE_SUSPENDED;
ehci->rh_state = EHCI_RH_SUSPENDED;
return 0;
}
#endif
Expand Down
22 changes: 10 additions & 12 deletions trunk/drivers/usb/host/ehci-q.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd,
spin_lock_irqsave(&ehci->lock, flags);
qh->clearing_tt = 0;
if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
&& HC_IS_RUNNING(hcd->state))
&& ehci->rh_state == EHCI_RH_RUNNING)
qh_link_async(ehci, qh);
spin_unlock_irqrestore(&ehci->lock, flags);
}
Expand Down Expand Up @@ -425,15 +425,15 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)

/* stop scanning when we reach qtds the hc is using */
} else if (likely (!stopped
&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) {
&& ehci->rh_state == EHCI_RH_RUNNING)) {
break;

/* scan the whole queue for unlinks whenever it stops */
} else {
stopped = 1;

/* cancel everything if we halt, suspend, etc */
if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))
if (ehci->rh_state != EHCI_RH_RUNNING)
last_status = -ESHUTDOWN;

/* this qtd is active; skip it unless a previous qtd
Expand Down Expand Up @@ -977,9 +977,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* in case a clear of CMD_ASE didn't take yet */
(void)handshake(ehci, &ehci->regs->status,
STS_ASS, 0, 150);
cmd |= CMD_ASE | CMD_RUN;
cmd |= CMD_ASE;
ehci_writel(ehci, cmd, &ehci->regs->command);
ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;
/* posted write need not be known to HC yet ... */
}
}
Expand Down Expand Up @@ -1168,14 +1167,13 @@ static void end_unlink_async (struct ehci_hcd *ehci)

qh_completions (ehci, qh);

if (!list_empty (&qh->qtd_list)
&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
qh_link_async (ehci, qh);
else {
} else {
/* it's not free to turn the async schedule on/off; leave it
* active but idle for a while once it empties.
*/
if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)
if (ehci->rh_state == EHCI_RH_RUNNING
&& ehci->async->qh_next.qh == NULL)
timer_action (ehci, TIMER_ASYNC_OFF);
}
Expand Down Expand Up @@ -1211,7 +1209,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* stop async schedule right now? */
if (unlikely (qh == ehci->async)) {
/* can't get here without STS_ASS set */
if (ehci_to_hcd(ehci)->state != HC_STATE_HALT
if (ehci->rh_state != EHCI_RH_HALTED
&& !ehci->reclaim) {
/* ... and CMD_IAAD clear */
ehci_writel(ehci, cmd & ~CMD_ASE,
Expand All @@ -1237,7 +1235,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
wmb ();

/* If the controller isn't running, we don't have to wait for it */
if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) {
if (unlikely(ehci->rh_state != EHCI_RH_RUNNING)) {
/* if (unlikely (qh->reclaim != 0))
* this will recurse, probably not much
*/
Expand All @@ -1260,7 +1258,7 @@ static void scan_async (struct ehci_hcd *ehci)
enum ehci_timer_action action = TIMER_IO_WATCHDOG;

timer_action_done (ehci, TIMER_ASYNC_SHRINK);
stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);
stopped = (ehci->rh_state != EHCI_RH_RUNNING);

ehci->qh_scan_next = ehci->async->qh_next.qh;
while (ehci->qh_scan_next) {
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/ehci-s5p.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ static int s5p_ehci_resume(struct device *dev)
/* here we "know" root ports should always stay powered */
ehci_port_power(ehci, 1);

hcd->state = HC_STATE_SUSPENDED;
ehci->rh_state = EHCI_RH_SUSPENDED;

return 0;
}
Expand Down
11 changes: 5 additions & 6 deletions trunk/drivers/usb/host/ehci-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ static int enable_periodic (struct ehci_hcd *ehci)
cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
ehci_writel(ehci, cmd, &ehci->regs->command);
/* posted write ... PSS happens later */
ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;

/* make sure ehci_work scans these */
ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
Expand Down Expand Up @@ -677,7 +676,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)

/* reschedule QH iff another request is queued */
if (!list_empty(&qh->qtd_list) &&
HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
ehci->rh_state == EHCI_RH_RUNNING) {
rc = qh_schedule(ehci, qh);

/* An error here likely indicates handshake failure
Expand Down Expand Up @@ -2275,7 +2274,7 @@ scan_periodic (struct ehci_hcd *ehci)
* Touches as few pages as possible: cache-friendly.
*/
now_uframe = ehci->next_uframe;
if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
if (ehci->rh_state == EHCI_RH_RUNNING) {
clock = ehci_readl(ehci, &ehci->regs->frame_index);
clock_frame = (clock >> 3) & (ehci->periodic_size - 1);
} else {
Expand Down Expand Up @@ -2310,7 +2309,7 @@ scan_periodic (struct ehci_hcd *ehci)
union ehci_shadow temp;
int live;

live = HC_IS_RUNNING (ehci_to_hcd(ehci)->state);
live = (ehci->rh_state == EHCI_RH_RUNNING);
switch (hc32_to_cpu(ehci, type)) {
case Q_TYPE_QH:
/* handle any completions */
Expand Down Expand Up @@ -2435,7 +2434,7 @@ scan_periodic (struct ehci_hcd *ehci)
* We can't advance our scan without collecting the ISO
* transfers that are still pending in this frame.
*/
if (incomplete && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
if (incomplete && ehci->rh_state == EHCI_RH_RUNNING) {
ehci->next_uframe = now_uframe;
break;
}
Expand All @@ -2451,7 +2450,7 @@ scan_periodic (struct ehci_hcd *ehci)
if (now_uframe == clock) {
unsigned now;

if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)
if (ehci->rh_state != EHCI_RH_RUNNING
|| ehci->periodic_sched == 0)
break;
ehci->next_uframe = now_uframe;
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ struct ehci_stats {

#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */

enum ehci_rh_state {
EHCI_RH_HALTED,
EHCI_RH_SUSPENDED,
EHCI_RH_RUNNING
};

struct ehci_hcd { /* one per controller */
/* glue to PCI and HCD framework */
struct ehci_caps __iomem *caps;
Expand All @@ -70,6 +76,7 @@ struct ehci_hcd { /* one per controller */

__u32 hcs_params; /* cached register copy */
spinlock_t lock;
enum ehci_rh_state rh_state;

/* async schedule support */
struct ehci_qh *async;
Expand Down

0 comments on commit a1f7d54

Please sign in to comment.