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

Commit 7de8b926 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (34 commits)
  USB: xhci: Stall handling bug fixes.
  USB: xhci: Support for 64-byte contexts
  USB: xhci: Always align output device contexts to 64 bytes.
  USB: xhci: Scratchpad buffer allocation
  USB: Fix parsing of SuperSpeed Endpoint Companion descriptor.
  USB: xhci: Fail gracefully if there's no SS ep companion descriptor.
  USB: xhci: Handle babble errors on transfers.
  USB: xhci: Setup HW retries correctly.
  USB: xhci: Check if the host controller died in IRQ handler.
  USB: xhci: Don't oops if the host doesn't halt.
  USB: xhci: Make debugging more verbose.
  USB: xhci: Correct Event Handler Busy flag usage.
  USB: xhci: Handle short control packets correctly.
  USB: xhci: Represent 64-bit addresses with one u64.
  USB: xhci: Use GFP_ATOMIC while holding spinlocks.
  USB: xhci: Deal with stalled endpoints.
  USB: xhci: Set TD size in transfer TRB.
  USB: xhci: fix less- and greater than confusion
  USB: usbtest: no need for USB_DEVICEFS
  USB: musb: fix CONFIGDATA register read issue
  ...
parents e043e42b c92bcfa7
Loading
Loading
Loading
Loading
+27 −21
Original line number Diff line number Diff line
@@ -80,38 +80,18 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
	int max_tx;
	int i;

	/* Allocate space for the SS endpoint companion descriptor */
	ep->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp),
			GFP_KERNEL);
	if (!ep->ss_ep_comp)
		return -ENOMEM;
	desc = (struct usb_ss_ep_comp_descriptor *) buffer;
	if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) {
		dev_warn(ddev, "No SuperSpeed endpoint companion for config %d "
				" interface %d altsetting %d ep %d: "
				"using minimum values\n",
				cfgno, inum, asnum, ep->desc.bEndpointAddress);
		ep->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE;
		ep->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP;
		ep->ss_ep_comp->desc.bMaxBurst = 0;
		/*
		 * Leave bmAttributes as zero, which will mean no streams for
		 * bulk, and isoc won't support multiple bursts of packets.
		 * With bursts of only one packet, and a Mult of 1, the max
		 * amount of data moved per endpoint service interval is one
		 * packet.
		 */
		if (usb_endpoint_xfer_isoc(&ep->desc) ||
				usb_endpoint_xfer_int(&ep->desc))
			ep->ss_ep_comp->desc.wBytesPerInterval =
				ep->desc.wMaxPacketSize;
		/*
		 * The next descriptor is for an Endpoint or Interface,
		 * no extra descriptors to copy into the companion structure,
		 * and we didn't eat up any of the buffer.
		 */
		retval = 0;
		goto valid;
		return 0;
	}
	memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE);
	desc = &ep->ss_ep_comp->desc;
@@ -320,6 +300,28 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
		buffer += i;
		size -= i;

		/* Allocate space for the SS endpoint companion descriptor */
		endpoint->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp),
				GFP_KERNEL);
		if (!endpoint->ss_ep_comp)
			return -ENOMEM;

		/* Fill in some default values (may be overwritten later) */
		endpoint->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE;
		endpoint->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP;
		endpoint->ss_ep_comp->desc.bMaxBurst = 0;
		/*
		 * Leave bmAttributes as zero, which will mean no streams for
		 * bulk, and isoc won't support multiple bursts of packets.
		 * With bursts of only one packet, and a Mult of 1, the max
		 * amount of data moved per endpoint service interval is one
		 * packet.
		 */
		if (usb_endpoint_xfer_isoc(&endpoint->desc) ||
				usb_endpoint_xfer_int(&endpoint->desc))
			endpoint->ss_ep_comp->desc.wBytesPerInterval =
				endpoint->desc.wMaxPacketSize;

		if (size > 0) {
			retval = usb_parse_ss_endpoint_companion(ddev, cfgno,
					inum, asnum, endpoint, num_ep, buffer,
@@ -329,6 +331,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
				retval = buffer - buffer0;
			}
		} else {
			dev_warn(ddev, "config %d interface %d altsetting %d "
				"endpoint 0x%X has no "
				"SuperSpeed companion descriptor\n",
				cfgno, inum, asnum, d->bEndpointAddress);
			retval = buffer - buffer0;
		}
	} else {
+1 −1
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ static int ehci_orion_setup(struct usb_hcd *hcd)
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	int retval;

	ehci_reset(ehci);
	retval = ehci_halt(ehci);
	if (retval)
		return retval;
@@ -118,7 +119,6 @@ static int ehci_orion_setup(struct usb_hcd *hcd)

	hcd->has_tt = 1;

	ehci_reset(ehci);
	ehci_port_power(ehci, 0);

	return retval;
+1 −0
Original line number Diff line number Diff line
@@ -282,6 +282,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
static void ohci_omap_stop(struct usb_hcd *hcd)
{
	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
	ohci_stop(hcd);
	omap_ohci_clock_power(0);
}

+122 −77
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int
{
	void *addr;
	u32 temp;
	u64 temp_64;

	addr = &ir_set->irq_pending;
	temp = xhci_readl(xhci, addr);
@@ -200,25 +201,15 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int
		xhci_dbg(xhci, "  WARN: %p: ir_set.rsvd = 0x%x\n",
				addr, (unsigned int)temp);

	addr = &ir_set->erst_base[0];
	temp = xhci_readl(xhci, addr);
	xhci_dbg(xhci, "  %p: ir_set.erst_base[0] = 0x%x\n",
			addr, (unsigned int) temp);

	addr = &ir_set->erst_base[1];
	temp = xhci_readl(xhci, addr);
	xhci_dbg(xhci, "  %p: ir_set.erst_base[1] = 0x%x\n",
			addr, (unsigned int) temp);

	addr = &ir_set->erst_dequeue[0];
	temp = xhci_readl(xhci, addr);
	xhci_dbg(xhci, "  %p: ir_set.erst_dequeue[0] = 0x%x\n",
			addr, (unsigned int) temp);
	addr = &ir_set->erst_base;
	temp_64 = xhci_read_64(xhci, addr);
	xhci_dbg(xhci, "  %p: ir_set.erst_base = @%08llx\n",
			addr, temp_64);

	addr = &ir_set->erst_dequeue[1];
	temp = xhci_readl(xhci, addr);
	xhci_dbg(xhci, "  %p: ir_set.erst_dequeue[1] = 0x%x\n",
			addr, (unsigned int) temp);
	addr = &ir_set->erst_dequeue;
	temp_64 = xhci_read_64(xhci, addr);
	xhci_dbg(xhci, "  %p: ir_set.erst_dequeue = @%08llx\n",
			addr, temp_64);
}

void xhci_print_run_regs(struct xhci_hcd *xhci)
@@ -268,8 +259,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
		xhci_dbg(xhci, "Link TRB:\n");
		xhci_print_trb_offsets(xhci, trb);

		address = trb->link.segment_ptr[0] +
			(((u64) trb->link.segment_ptr[1]) << 32);
		address = trb->link.segment_ptr;
		xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address);

		xhci_dbg(xhci, "Interrupter target = 0x%x\n",
@@ -282,8 +272,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
				(unsigned int) (trb->link.control & TRB_NO_SNOOP));
		break;
	case TRB_TYPE(TRB_TRANSFER):
		address = trb->trans_event.buffer[0] +
			(((u64) trb->trans_event.buffer[1]) << 32);
		address = trb->trans_event.buffer;
		/*
		 * FIXME: look at flags to figure out if it's an address or if
		 * the data is directly in the buffer field.
@@ -291,8 +280,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
		xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address);
		break;
	case TRB_TYPE(TRB_COMPLETION):
		address = trb->event_cmd.cmd_trb[0] +
			(((u64) trb->event_cmd.cmd_trb[1]) << 32);
		address = trb->event_cmd.cmd_trb;
		xhci_dbg(xhci, "Command TRB pointer = %llu\n", address);
		xhci_dbg(xhci, "Completion status = %u\n",
				(unsigned int) GET_COMP_CODE(trb->event_cmd.status));
@@ -328,8 +316,8 @@ void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
	for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
		trb = &seg->trbs[i];
		xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr,
				(unsigned int) trb->link.segment_ptr[0],
				(unsigned int) trb->link.segment_ptr[1],
				lower_32_bits(trb->link.segment_ptr),
				upper_32_bits(trb->link.segment_ptr),
				(unsigned int) trb->link.intr_target,
				(unsigned int) trb->link.control);
		addr += sizeof(*trb);
@@ -386,8 +374,8 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
		entry = &erst->entries[i];
		xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n",
				(unsigned int) addr,
				(unsigned int) entry->seg_addr[0],
				(unsigned int) entry->seg_addr[1],
				lower_32_bits(entry->seg_addr),
				upper_32_bits(entry->seg_addr),
				(unsigned int) entry->seg_size,
				(unsigned int) entry->rsvd);
		addr += sizeof(*entry);
@@ -396,90 +384,147 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)

void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
{
	u32 val;
	u64 val;

	val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]);
	xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = 0x%x\n", val);
	val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[1]);
	xhci_dbg(xhci, "// xHC command ring deq ptr high bits = 0x%x\n", val);
	val = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
	xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = @%08x\n",
			lower_32_bits(val));
	xhci_dbg(xhci, "// xHC command ring deq ptr high bits = @%08x\n",
			upper_32_bits(val));
}

void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep)
/* Print the last 32 bytes for 64-byte contexts */
static void dbg_rsvd64(struct xhci_hcd *xhci, u64 *ctx, dma_addr_t dma)
{
	int i;
	for (i = 0; i < 4; ++i) {
		xhci_dbg(xhci, "@%p (virt) @%08llx "
			 "(dma) %#08llx - rsvd64[%d]\n",
			 &ctx[4 + i], (unsigned long long)dma,
			 ctx[4 + i], i);
		dma += 8;
	}
}

void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
{
	int i, j;
	int last_ep_ctx = 31;
	/* Fields are 32 bits wide, DMA addresses are in bytes */
	int field_size = 32 / 8;
	int i;

	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
			&ctx->drop_flags, (unsigned long long)dma,
			ctx->drop_flags);
	dma += field_size;
	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
			&ctx->add_flags, (unsigned long long)dma,
			ctx->add_flags);
	dma += field_size;
	for (i = 0; i > 6; ++i) {
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
				&ctx->rsvd[i], (unsigned long long)dma,
				ctx->rsvd[i], i);
		dma += field_size;
	}
	struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
	dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx);
	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);

	xhci_dbg(xhci, "Slot Context:\n");
	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
			&ctx->slot.dev_info,
			(unsigned long long)dma, ctx->slot.dev_info);
			&slot_ctx->dev_info,
			(unsigned long long)dma, slot_ctx->dev_info);
	dma += field_size;
	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
			&ctx->slot.dev_info2,
			(unsigned long long)dma, ctx->slot.dev_info2);
			&slot_ctx->dev_info2,
			(unsigned long long)dma, slot_ctx->dev_info2);
	dma += field_size;
	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
			&ctx->slot.tt_info,
			(unsigned long long)dma, ctx->slot.tt_info);
			&slot_ctx->tt_info,
			(unsigned long long)dma, slot_ctx->tt_info);
	dma += field_size;
	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
			&ctx->slot.dev_state,
			(unsigned long long)dma, ctx->slot.dev_state);
			&slot_ctx->dev_state,
			(unsigned long long)dma, slot_ctx->dev_state);
	dma += field_size;
	for (i = 0; i > 4; ++i) {
	for (i = 0; i < 4; ++i) {
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
				&ctx->slot.reserved[i], (unsigned long long)dma,
				ctx->slot.reserved[i], i);
				&slot_ctx->reserved[i], (unsigned long long)dma,
				slot_ctx->reserved[i], i);
		dma += field_size;
	}

	if (csz)
		dbg_rsvd64(xhci, (u64 *)slot_ctx, dma);
}

void xhci_dbg_ep_ctx(struct xhci_hcd *xhci,
		     struct xhci_container_ctx *ctx,
		     unsigned int last_ep)
{
	int i, j;
	int last_ep_ctx = 31;
	/* Fields are 32 bits wide, DMA addresses are in bytes */
	int field_size = 32 / 8;
	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);

	if (last_ep < 31)
		last_ep_ctx = last_ep + 1;
	for (i = 0; i < last_ep_ctx; ++i) {
		struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i);
		dma_addr_t dma = ctx->dma +
			((unsigned long)ep_ctx - (unsigned long)ctx);

		xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
				&ctx->ep[i].ep_info,
				(unsigned long long)dma, ctx->ep[i].ep_info);
				&ep_ctx->ep_info,
				(unsigned long long)dma, ep_ctx->ep_info);
		dma += field_size;
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
				&ctx->ep[i].ep_info2,
				(unsigned long long)dma, ctx->ep[i].ep_info2);
		dma += field_size;
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[0]\n",
				&ctx->ep[i].deq[0],
				(unsigned long long)dma, ctx->ep[i].deq[0]);
		dma += field_size;
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[1]\n",
				&ctx->ep[i].deq[1],
				(unsigned long long)dma, ctx->ep[i].deq[1]);
				&ep_ctx->ep_info2,
				(unsigned long long)dma, ep_ctx->ep_info2);
		dma += field_size;
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n",
				&ep_ctx->deq,
				(unsigned long long)dma, ep_ctx->deq);
		dma += 2*field_size;
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
				&ctx->ep[i].tx_info,
				(unsigned long long)dma, ctx->ep[i].tx_info);
				&ep_ctx->tx_info,
				(unsigned long long)dma, ep_ctx->tx_info);
		dma += field_size;
		for (j = 0; j < 3; ++j) {
			xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
					&ctx->ep[i].reserved[j],
					&ep_ctx->reserved[j],
					(unsigned long long)dma,
					ctx->ep[i].reserved[j], j);
					ep_ctx->reserved[j], j);
			dma += field_size;
		}

		if (csz)
			dbg_rsvd64(xhci, (u64 *)ep_ctx, dma);
	}
}

void xhci_dbg_ctx(struct xhci_hcd *xhci,
		  struct xhci_container_ctx *ctx,
		  unsigned int last_ep)
{
	int i;
	/* Fields are 32 bits wide, DMA addresses are in bytes */
	int field_size = 32 / 8;
	struct xhci_slot_ctx *slot_ctx;
	dma_addr_t dma = ctx->dma;
	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);

	if (ctx->type == XHCI_CTX_TYPE_INPUT) {
		struct xhci_input_control_ctx *ctrl_ctx =
			xhci_get_input_control_ctx(xhci, ctx);
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
			 &ctrl_ctx->drop_flags, (unsigned long long)dma,
			 ctrl_ctx->drop_flags);
		dma += field_size;
		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
			 &ctrl_ctx->add_flags, (unsigned long long)dma,
			 ctrl_ctx->add_flags);
		dma += field_size;
		for (i = 0; i < 6; ++i) {
			xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
				 &ctrl_ctx->rsvd2[i], (unsigned long long)dma,
				 ctrl_ctx->rsvd2[i], i);
			dma += field_size;
		}

		if (csz)
			dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma);
	}

	slot_ctx = xhci_get_slot_ctx(xhci, ctx);
	xhci_dbg_slot_ctx(xhci, ctx);
	xhci_dbg_ep_ctx(xhci, ctx, last_ep);
}
+199 −91

File changed.

Preview size limit exceeded, changes collapsed.

Loading