aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-sched.c1
-rw-r--r--drivers/usb/host/isp1362-hcd.c18
-rw-r--r--drivers/usb/host/isp1362.h12
-rw-r--r--drivers/usb/host/xhci-hcd.c29
4 files changed, 44 insertions, 16 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 3ea05936851..3efa59b1804 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1425,6 +1425,7 @@ iso_stream_schedule (
status = -EFBIG;
goto fail;
}
+ stream->next_uframe = start;
goto ready;
}
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index e35d82808ba..5c774ab9825 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2284,10 +2284,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd)
dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n",
istl_size / 2, istl_size, 0, istl_size / 2);
- dev_info(hcd->self.controller, " INTL: %4d * (%3u+8): %4d @ $%04x\n",
+ dev_info(hcd->self.controller, " INTL: %4d * (%3lu+8): %4d @ $%04x\n",
ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
intl_size, istl_size);
- dev_info(hcd->self.controller, " ATL : %4d * (%3u+8): %4d @ $%04x\n",
+ dev_info(hcd->self.controller, " ATL : %4d * (%3lu+8): %4d @ $%04x\n",
atl_buffers, atl_blksize - PTD_HEADER_SIZE,
atl_size, istl_size + intl_size);
dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total,
@@ -2677,12 +2677,12 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
DBG(0, "%s: Removing HCD\n", __func__);
usb_remove_hcd(hcd);
- DBG(0, "%s: Unmapping data_reg @ %08x\n", __func__,
- (u32)isp1362_hcd->data_reg);
+ DBG(0, "%s: Unmapping data_reg @ %p\n", __func__,
+ isp1362_hcd->data_reg);
iounmap(isp1362_hcd->data_reg);
- DBG(0, "%s: Unmapping addr_reg @ %08x\n", __func__,
- (u32)isp1362_hcd->addr_reg);
+ DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__,
+ isp1362_hcd->addr_reg);
iounmap(isp1362_hcd->addr_reg);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -2810,16 +2810,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
return 0;
err6:
- DBG(0, "%s: Freeing dev %08x\n", __func__, (u32)isp1362_hcd);
+ DBG(0, "%s: Freeing dev %p\n", __func__, isp1362_hcd);
usb_put_hcd(hcd);
err5:
- DBG(0, "%s: Unmapping data_reg @ %08x\n", __func__, (u32)data_reg);
+ DBG(0, "%s: Unmapping data_reg @ %p\n", __func__, data_reg);
iounmap(data_reg);
err4:
DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start);
release_mem_region(data->start, resource_len(data));
err3:
- DBG(0, "%s: Unmapping addr_reg @ %08x\n", __func__, (u32)addr_reg);
+ DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__, addr_reg);
iounmap(addr_reg);
err2:
DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start);
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index fe60f62a32f..1a253ebf7e5 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -580,7 +580,7 @@ static inline const char *ISP1362_INT_NAME(int n)
static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr)
{
- unsigned p = (unsigned)ptr;
+ unsigned long p = (unsigned long)ptr;
if (!(p & 0xf))
isp1362_hcd->stat16++;
else if (!(p & 0x7))
@@ -770,7 +770,7 @@ static void isp1362_write_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 l
if (!len)
return;
- if ((unsigned)dp & 0x1) {
+ if ((unsigned long)dp & 0x1) {
/* not aligned */
for (; len > 1; len -= 2) {
data = *dp++;
@@ -962,8 +962,8 @@ static void isp1362_read_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16
isp1362_write_diraddr(isp1362_hcd, offset, len);
- DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %08x\n", __func__,
- len, offset, (u32)buf);
+ DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %p\n",
+ __func__, len, offset, buf);
isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
_WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT));
@@ -982,8 +982,8 @@ static void isp1362_write_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16
isp1362_write_diraddr(isp1362_hcd, offset, len);
- DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %08x\n", __func__,
- len, offset, (u32)buf);
+ DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %p\n",
+ __func__, len, offset, buf);
isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
_WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT));
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 99911e727e0..932f9993848 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -335,6 +335,12 @@ void xhci_event_ring_work(unsigned long arg)
spin_lock_irqsave(&xhci->lock, flags);
temp = xhci_readl(xhci, &xhci->op_regs->status);
xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
+ if (temp == 0xffffffff) {
+ xhci_dbg(xhci, "HW died, polling stopped.\n");
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return;
+ }
+
temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
@@ -776,6 +782,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
{
unsigned long flags;
int ret;
+ u32 temp;
struct xhci_hcd *xhci;
struct xhci_td *td;
unsigned int ep_index;
@@ -788,6 +795,17 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
ret = usb_hcd_check_unlink_urb(hcd, urb, status);
if (ret || !urb->hcpriv)
goto done;
+ temp = xhci_readl(xhci, &xhci->op_regs->status);
+ if (temp == 0xffffffff) {
+ xhci_dbg(xhci, "HW died, freeing TD.\n");
+ td = (struct xhci_td *) urb->hcpriv;
+
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
+ kfree(td);
+ return ret;
+ }
xhci_dbg(xhci, "Cancel URB %p\n", urb);
xhci_dbg(xhci, "Event ring:\n");
@@ -877,7 +895,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
ctrl_ctx->drop_flags |= drop_flag;
new_drop_flags = ctrl_ctx->drop_flags;
- ctrl_ctx->add_flags = ~drop_flag;
+ ctrl_ctx->add_flags &= ~drop_flag;
new_add_flags = ctrl_ctx->add_flags;
last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
@@ -1410,11 +1428,20 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
unsigned long flags;
+ u32 state;
if (udev->slot_id == 0)
return;
spin_lock_irqsave(&xhci->lock, flags);
+ /* Don't disable the slot if the host controller is dead. */
+ state = xhci_readl(xhci, &xhci->op_regs->status);
+ if (state == 0xffffffff) {
+ xhci_free_virt_device(xhci, udev->slot_id);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return;
+ }
+
if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");