Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8799906 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: EHCI: remove usages of hcd->state



This patch (as1483) improves the ehci-hcd driver family by getting rid
of the reliance on the hcd->state variable.  It has no clear owner and
it isn't protected by the usual HCD locks.  In its place, the patch
adds a new, private ehci->rh_state field to record the state of the
root hub.

Along the way, the patch removes a couple of lines containing
redundant assignments to the state variable.  Also, the QUIESCING
state simply gets changed to the RUNNING state, because the driver
doesn't make any distinction between them.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Acked-by: default avatarJingoo Han <jg1.han@samsung.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent dfd8c81f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+15 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;

+2 −2
Original line number Diff line number Diff line
@@ -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 */
@@ -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);
+10 −10
Original line number Diff line number Diff line
@@ -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);
	}
@@ -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);
@@ -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

@@ -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
@@ -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);
@@ -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);
@@ -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);
@@ -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;
	}
@@ -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
@@ -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:
+4 −6
Original line number Diff line number Diff line
@@ -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);

@@ -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);
@@ -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. */
@@ -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);
@@ -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 */
Loading