FROMLIST: usb: xhci: Fix panic if disconnect

After a device is disconnected, xhci_stop_device() will be invoked
in xhci_bus_suspend().
Also the "disconnect" IRQ will have ISR to invoke
xhci_free_virt_device() in this sequence.
xhci_irq -> xhci_handle_event -> handle_cmd_completion ->
xhci_handle_cmd_disable_slot -> xhci_free_virt_device

If xhci->devs[slot_id] has been assigned to NULL in
xhci_free_virt_device(), then virt_dev->eps[i].ring in
xhci_stop_device() may point to an invlid address to cause kernel
panic.

 virt_dev = xhci->devs[slot_id];
 :
 if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue)

[] Unable to handle kernel paging request at virtual address 00001a68
[] pgd = ffffffc001430000
[] [00001a68] *pgd=000000013c807003, *pud=000000013c807003,
  *pmd=000000013c808003, *pte=0000000000000000
[] Internal error: Oops: 96000006 [#1] PREEMPT SMP
[] CPU: 0 PID: 39 Comm: kworker/0:1 Tainted: G     U
[] Workqueue: pm pm_runtime_work
[] task: ffffffc0bc0e0bc0 ti: ffffffc0bc0ec000 task.ti:
  ffffffc0bc0ec000
[] PC is at xhci_stop_device.constprop.11+0xb4/0x1a4

This issue is found when running with realtek ethernet device
(0bda:8153).

BUG=chrome-os-partner:54766
TEST=Connected realtek ethernet device (0bda:8153) to smaug platform
with ehthernet cable attached. Ran 100 cycles of suspend/resume.
also tried with "ehthernet cable detached" case.

Change-Id: I7d9329ee9dcce65bfa784cc7789f3075cd2f7bf3
Signed-off-by: Jim Lin <jilin@nvidia.com>
Reviewed-on: https://chromium-review.googlesource.com/360716
Reviewed-by: Benson Leung <bleung@chromium.org>
(cherry picked from commit 4ad93afeb20f5c033c3c39cc03700252b73622a7)
Reviewed-on: https://chromium-review.googlesource.com/363627
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Commit-Queue: Benson Leung <bleung@chromium.org>
Trybot-Ready: Benson Leung <bleung@chromium.org>
Tested-by: Benson Leung <bleung@chromium.org>
1 file changed