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

Commit f9e609b8 authored by Guoqing Zhang's avatar Guoqing Zhang Committed by Greg Kroah-Hartman
Browse files

usb: xhci: Add helper function xhci_disable_slot().



Refactoring slot disable related code into a helper
function xhci_disable_slot() which can be used when
enabling test mode.

Signed-off-by: default avatarGuoqing Zhang <guoqing.zhang@intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a6ff6cbf
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -3561,8 +3561,6 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
{
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
	struct xhci_virt_device *virt_dev;
	unsigned long flags;
	u32 state;
	int i, ret;
	struct xhci_command *command;

@@ -3597,30 +3595,50 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
		del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
	}

	xhci_disable_slot(xhci, command, udev->slot_id);
	/*
	 * Event command completion handler will free any data structures
	 * associated with the slot.  XXX Can free sleep?
	 */
}

int xhci_disable_slot(struct xhci_hcd *xhci, struct xhci_command *command,
			u32 slot_id)
{
	unsigned long flags;
	u32 state;
	int ret = 0;
	struct xhci_virt_device *virt_dev;

	virt_dev = xhci->devs[slot_id];
	if (!virt_dev)
		return -EINVAL;
	if (!command)
		command = xhci_alloc_command(xhci, false, false, GFP_KERNEL);
	if (!command)
		return -ENOMEM;

	spin_lock_irqsave(&xhci->lock, flags);
	/* Don't disable the slot if the host controller is dead. */
	state = readl(&xhci->op_regs->status);
	if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||
			(xhci->xhc_state & XHCI_STATE_HALTED)) {
		xhci_free_virt_device(xhci, udev->slot_id);
		xhci_free_virt_device(xhci, slot_id);
		spin_unlock_irqrestore(&xhci->lock, flags);
		kfree(command);
		return;
		return ret;
	}

	if (xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT,
				    udev->slot_id)) {
	ret = xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT,
				slot_id);
	if (ret) {
		spin_unlock_irqrestore(&xhci->lock, flags);
		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
		return;
		return ret;
	}
	xhci_ring_cmd_db(xhci);
	spin_unlock_irqrestore(&xhci->lock, flags);

	/*
	 * Event command completion handler will free any data structures
	 * associated with the slot.  XXX Can free sleep?
	 */
	return ret;
}

/*
@@ -3727,15 +3745,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)

disable_slot:
	/* Disable slot, if we can do it without mem alloc */
	spin_lock_irqsave(&xhci->lock, flags);
	kfree(command->completion);
	command->completion = NULL;
	command->status = 0;
	if (!xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT,
				     udev->slot_id))
		xhci_ring_cmd_db(xhci);
	spin_unlock_irqrestore(&xhci->lock, flags);
	return 0;
	return xhci_disable_slot(xhci, command, udev->slot_id);
}

/*
+2 −0
Original line number Diff line number Diff line
@@ -2018,6 +2018,8 @@ void xhci_shutdown(struct usb_hcd *hcd);
int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
void xhci_init_driver(struct hc_driver *drv,
		      const struct xhci_driver_overrides *over);
int xhci_disable_slot(struct xhci_hcd *xhci,
			struct xhci_command *command, u32 slot_id);

#ifdef	CONFIG_PM
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);