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

Commit ff39074b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some small USB driver fixes for 5.2-rc5

  Nothing major, just some small gadget fixes, usb-serial new device
  ids, a few new quirks, and some small fixes for some regressions that
  have been found after the big 5.2-rc1 merge.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'usb-5.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: typec: Make sure an alt mode exist before getting its partner
  usb: gadget: udc: lpc32xx: fix return value check in lpc32xx_udc_probe()
  usb: gadget: dwc2: fix zlp handling
  usb: dwc2: Set actual frame number for completed ISOC transfer for none DDMA
  usb: gadget: udc: lpc32xx: allocate descriptor with GFP_ATOMIC
  usb: gadget: fusb300_udc: Fix memory leak of fusb300->ep[i]
  usb: phy: mxs: Disable external charger detect in mxs_phy_hw_init()
  usb: dwc2: Fix DMA cache alignment issues
  usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression)
  USB: Fix chipmunk-like voice when using Logitech C270 for recording audio.
  USB: usb-storage: Add new ID to ums-realtek
  usb: typec: ucsi: ccg: fix memory leak in do_flash
  USB: serial: option: add Telit 0x1260 and 0x1261 compositions
  USB: serial: pl2303: add Allied Telesis VT-Kit3
  USB: serial: option: add support for Simcom SIM7500/SIM7600 RNDIS mode
parents fa1827d7 5f54a85d
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -215,6 +215,9 @@ static const struct usb_device_id usb_quirk_list[] = {
	/* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
	/* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
	{ USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
	{ USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },


	/* Logitech HD Webcam C270 */
	{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },

	/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
	/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
	{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
	{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
	{ USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
	{ USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
+16 −8
Original line number Original line Diff line number Diff line
@@ -835,19 +835,22 @@ static void dwc2_gadget_fill_nonisoc_xfer_ddma_one(struct dwc2_hsotg_ep *hs_ep,
 * with corresponding information based on transfer data.
 * with corresponding information based on transfer data.
 */
 */
static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
						 struct usb_request *ureq,
						 dma_addr_t dma_buff,
						 unsigned int offset,
						 unsigned int len)
						 unsigned int len)
{
{
	struct usb_request *ureq = NULL;
	struct dwc2_dma_desc *desc = hs_ep->desc_list;
	struct dwc2_dma_desc *desc = hs_ep->desc_list;
	struct scatterlist *sg;
	struct scatterlist *sg;
	int i;
	int i;
	u8 desc_count = 0;
	u8 desc_count = 0;


	if (hs_ep->req)
		ureq = &hs_ep->req->req;

	/* non-DMA sg buffer */
	/* non-DMA sg buffer */
	if (!ureq->num_sgs) {
	if (!ureq || !ureq->num_sgs) {
		dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
		dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
			ureq->dma + offset, len, true);
			dma_buff, len, true);
		return;
		return;
	}
	}


@@ -1135,7 +1138,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
			offset = ureq->actual;
			offset = ureq->actual;


		/* Fill DDMA chain entries */
		/* Fill DDMA chain entries */
		dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq, offset,
		dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq->dma + offset,
						     length);
						     length);


		/* write descriptor chain address to control register */
		/* write descriptor chain address to control register */
@@ -2037,12 +2040,13 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
		dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
		dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
			index);
			index);
	if (using_desc_dma(hsotg)) {
	if (using_desc_dma(hsotg)) {
		/* Not specific buffer needed for ep0 ZLP */
		dma_addr_t dma = hs_ep->desc_list_dma;

		if (!index)
		if (!index)
			dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);
			dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);


		/* Not specific buffer needed for ep0 ZLP */
		dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0);
		dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &hs_ep->desc_list,
			hs_ep->desc_list_dma, 0, true);
	} else {
	} else {
		dwc2_writel(hsotg, DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
		dwc2_writel(hsotg, DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
			    DXEPTSIZ_XFERSIZE(0),
			    DXEPTSIZ_XFERSIZE(0),
@@ -2417,6 +2421,10 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
			dwc2_gadget_incr_frame_num(hs_ep);
			dwc2_gadget_incr_frame_num(hs_ep);
	}
	}


	/* Set actual frame number for completed transfers */
	if (!using_desc_dma(hsotg) && hs_ep->isochronous)
		req->frame_number = hsotg->frame_number;

	dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
	dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
}
}


+24 −15
Original line number Original line Diff line number Diff line
@@ -2480,8 +2480,10 @@ static void dwc2_free_dma_aligned_buffer(struct urb *urb)
		return;
		return;


	/* Restore urb->transfer_buffer from the end of the allocated area */
	/* Restore urb->transfer_buffer from the end of the allocated area */
	memcpy(&stored_xfer_buffer, urb->transfer_buffer +
	memcpy(&stored_xfer_buffer,
	       urb->transfer_buffer_length, sizeof(urb->transfer_buffer));
	       PTR_ALIGN(urb->transfer_buffer + urb->transfer_buffer_length,
			 dma_get_cache_alignment()),
	       sizeof(urb->transfer_buffer));


	if (usb_urb_dir_in(urb)) {
	if (usb_urb_dir_in(urb)) {
		if (usb_pipeisoc(urb->pipe))
		if (usb_pipeisoc(urb->pipe))
@@ -2513,6 +2515,7 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
	 * DMA
	 * DMA
	 */
	 */
	kmalloc_size = urb->transfer_buffer_length +
	kmalloc_size = urb->transfer_buffer_length +
		(dma_get_cache_alignment() - 1) +
		sizeof(urb->transfer_buffer);
		sizeof(urb->transfer_buffer);


	kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
	kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
@@ -2523,7 +2526,8 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
	 * Position value of original urb->transfer_buffer pointer to the end
	 * Position value of original urb->transfer_buffer pointer to the end
	 * of allocation for later referencing
	 * of allocation for later referencing
	 */
	 */
	memcpy(kmalloc_ptr + urb->transfer_buffer_length,
	memcpy(PTR_ALIGN(kmalloc_ptr + urb->transfer_buffer_length,
			 dma_get_cache_alignment()),
	       &urb->transfer_buffer, sizeof(urb->transfer_buffer));
	       &urb->transfer_buffer, sizeof(urb->transfer_buffer));


	if (usb_urb_dir_out(urb))
	if (usb_urb_dir_out(urb))
@@ -2608,7 +2612,7 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
	chan->dev_addr = dwc2_hcd_get_dev_addr(&urb->pipe_info);
	chan->dev_addr = dwc2_hcd_get_dev_addr(&urb->pipe_info);
	chan->ep_num = dwc2_hcd_get_ep_num(&urb->pipe_info);
	chan->ep_num = dwc2_hcd_get_ep_num(&urb->pipe_info);
	chan->speed = qh->dev_speed;
	chan->speed = qh->dev_speed;
	chan->max_packet = dwc2_max_packet(qh->maxp);
	chan->max_packet = qh->maxp;


	chan->xfer_started = 0;
	chan->xfer_started = 0;
	chan->halt_status = DWC2_HC_XFER_NO_HALT_STATUS;
	chan->halt_status = DWC2_HC_XFER_NO_HALT_STATUS;
@@ -2686,7 +2690,7 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
		 * This value may be modified when the transfer is started
		 * This value may be modified when the transfer is started
		 * to reflect the actual transfer length
		 * to reflect the actual transfer length
		 */
		 */
		chan->multi_count = dwc2_hb_mult(qh->maxp);
		chan->multi_count = qh->maxp_mult;


	if (hsotg->params.dma_desc_enable) {
	if (hsotg->params.dma_desc_enable) {
		chan->desc_list_addr = qh->desc_list_dma;
		chan->desc_list_addr = qh->desc_list_dma;
@@ -3806,19 +3810,21 @@ static struct dwc2_hcd_urb *dwc2_hcd_urb_alloc(struct dwc2_hsotg *hsotg,


static void dwc2_hcd_urb_set_pipeinfo(struct dwc2_hsotg *hsotg,
static void dwc2_hcd_urb_set_pipeinfo(struct dwc2_hsotg *hsotg,
				      struct dwc2_hcd_urb *urb, u8 dev_addr,
				      struct dwc2_hcd_urb *urb, u8 dev_addr,
				      u8 ep_num, u8 ep_type, u8 ep_dir, u16 mps)
				      u8 ep_num, u8 ep_type, u8 ep_dir,
				      u16 maxp, u16 maxp_mult)
{
{
	if (dbg_perio() ||
	if (dbg_perio() ||
	    ep_type == USB_ENDPOINT_XFER_BULK ||
	    ep_type == USB_ENDPOINT_XFER_BULK ||
	    ep_type == USB_ENDPOINT_XFER_CONTROL)
	    ep_type == USB_ENDPOINT_XFER_CONTROL)
		dev_vdbg(hsotg->dev,
		dev_vdbg(hsotg->dev,
			 "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, mps=%d\n",
			 "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, maxp=%d (%d mult)\n",
			 dev_addr, ep_num, ep_dir, ep_type, mps);
			 dev_addr, ep_num, ep_dir, ep_type, maxp, maxp_mult);
	urb->pipe_info.dev_addr = dev_addr;
	urb->pipe_info.dev_addr = dev_addr;
	urb->pipe_info.ep_num = ep_num;
	urb->pipe_info.ep_num = ep_num;
	urb->pipe_info.pipe_type = ep_type;
	urb->pipe_info.pipe_type = ep_type;
	urb->pipe_info.pipe_dir = ep_dir;
	urb->pipe_info.pipe_dir = ep_dir;
	urb->pipe_info.mps = mps;
	urb->pipe_info.maxp = maxp;
	urb->pipe_info.maxp_mult = maxp_mult;
}
}


/*
/*
@@ -3909,8 +3915,9 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
					dwc2_hcd_is_pipe_in(&urb->pipe_info) ?
					dwc2_hcd_is_pipe_in(&urb->pipe_info) ?
					"IN" : "OUT");
					"IN" : "OUT");
				dev_dbg(hsotg->dev,
				dev_dbg(hsotg->dev,
					"      Max packet size: %d\n",
					"      Max packet size: %d (%d mult)\n",
					dwc2_hcd_get_mps(&urb->pipe_info));
					dwc2_hcd_get_maxp(&urb->pipe_info),
					dwc2_hcd_get_maxp_mult(&urb->pipe_info));
				dev_dbg(hsotg->dev,
				dev_dbg(hsotg->dev,
					"      transfer_buffer: %p\n",
					"      transfer_buffer: %p\n",
					urb->buf);
					urb->buf);
@@ -4510,8 +4517,10 @@ static void dwc2_dump_urb_info(struct usb_hcd *hcd, struct urb *urb,
	}
	}


	dev_vdbg(hsotg->dev, "  Speed: %s\n", speed);
	dev_vdbg(hsotg->dev, "  Speed: %s\n", speed);
	dev_vdbg(hsotg->dev, "  Max packet size: %d\n",
	dev_vdbg(hsotg->dev, "  Max packet size: %d (%d mult)\n",
		 usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
		 usb_endpoint_maxp(&urb->ep->desc),
		 usb_endpoint_maxp_mult(&urb->ep->desc));

	dev_vdbg(hsotg->dev, "  Data buffer length: %d\n",
	dev_vdbg(hsotg->dev, "  Data buffer length: %d\n",
		 urb->transfer_buffer_length);
		 urb->transfer_buffer_length);
	dev_vdbg(hsotg->dev, "  Transfer buffer: %p, Transfer DMA: %08lx\n",
	dev_vdbg(hsotg->dev, "  Transfer buffer: %p, Transfer DMA: %08lx\n",
@@ -4594,8 +4603,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
	dwc2_hcd_urb_set_pipeinfo(hsotg, dwc2_urb, usb_pipedevice(urb->pipe),
	dwc2_hcd_urb_set_pipeinfo(hsotg, dwc2_urb, usb_pipedevice(urb->pipe),
				  usb_pipeendpoint(urb->pipe), ep_type,
				  usb_pipeendpoint(urb->pipe), ep_type,
				  usb_pipein(urb->pipe),
				  usb_pipein(urb->pipe),
				  usb_maxpacket(urb->dev, urb->pipe,
				  usb_endpoint_maxp(&ep->desc),
						!(usb_pipein(urb->pipe))));
				  usb_endpoint_maxp_mult(&ep->desc));


	buf = urb->transfer_buffer;
	buf = urb->transfer_buffer;


+11 −9
Original line number Original line Diff line number Diff line
@@ -171,7 +171,8 @@ struct dwc2_hcd_pipe_info {
	u8 ep_num;
	u8 ep_num;
	u8 pipe_type;
	u8 pipe_type;
	u8 pipe_dir;
	u8 pipe_dir;
	u16 mps;
	u16 maxp;
	u16 maxp_mult;
};
};


struct dwc2_hcd_iso_packet_desc {
struct dwc2_hcd_iso_packet_desc {
@@ -264,6 +265,7 @@ struct dwc2_hs_transfer_time {
 *                       - USB_ENDPOINT_XFER_ISOC
 *                       - USB_ENDPOINT_XFER_ISOC
 * @ep_is_in:           Endpoint direction
 * @ep_is_in:           Endpoint direction
 * @maxp:               Value from wMaxPacketSize field of Endpoint Descriptor
 * @maxp:               Value from wMaxPacketSize field of Endpoint Descriptor
 * @maxp_mult:          Multiplier for maxp
 * @dev_speed:          Device speed. One of the following values:
 * @dev_speed:          Device speed. One of the following values:
 *                       - USB_SPEED_LOW
 *                       - USB_SPEED_LOW
 *                       - USB_SPEED_FULL
 *                       - USB_SPEED_FULL
@@ -340,6 +342,7 @@ struct dwc2_qh {
	u8 ep_type;
	u8 ep_type;
	u8 ep_is_in;
	u8 ep_is_in;
	u16 maxp;
	u16 maxp;
	u16 maxp_mult;
	u8 dev_speed;
	u8 dev_speed;
	u8 data_toggle;
	u8 data_toggle;
	u8 ping_state;
	u8 ping_state;
@@ -503,9 +506,14 @@ static inline u8 dwc2_hcd_get_pipe_type(struct dwc2_hcd_pipe_info *pipe)
	return pipe->pipe_type;
	return pipe->pipe_type;
}
}


static inline u16 dwc2_hcd_get_mps(struct dwc2_hcd_pipe_info *pipe)
static inline u16 dwc2_hcd_get_maxp(struct dwc2_hcd_pipe_info *pipe)
{
	return pipe->maxp;
}

static inline u16 dwc2_hcd_get_maxp_mult(struct dwc2_hcd_pipe_info *pipe)
{
{
	return pipe->mps;
	return pipe->maxp_mult;
}
}


static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe)
static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe)
@@ -620,12 +628,6 @@ static inline bool dbg_urb(struct urb *urb)
static inline bool dbg_perio(void) { return false; }
static inline bool dbg_perio(void) { return false; }
#endif
#endif


/* High bandwidth multiplier as encoded in highspeed endpoint descriptors */
#define dwc2_hb_mult(wmaxpacketsize) (1 + (((wmaxpacketsize) >> 11) & 0x03))

/* Packet size for any kind of endpoint descriptor */
#define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff)

/*
/*
 * Returns true if frame1 index is greater than frame2 index. The comparison
 * Returns true if frame1 index is greater than frame2 index. The comparison
 * is done modulo FRLISTEN_64_SIZE. This accounts for the rollover of the
 * is done modulo FRLISTEN_64_SIZE. This accounts for the rollover of the
+3 −2
Original line number Original line Diff line number Diff line
@@ -1617,8 +1617,9 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg,


	dev_err(hsotg->dev, "  Speed: %s\n", speed);
	dev_err(hsotg->dev, "  Speed: %s\n", speed);


	dev_err(hsotg->dev, "  Max packet size: %d\n",
	dev_err(hsotg->dev, "  Max packet size: %d (mult %d)\n",
		dwc2_hcd_get_mps(&urb->pipe_info));
		dwc2_hcd_get_maxp(&urb->pipe_info),
		dwc2_hcd_get_maxp_mult(&urb->pipe_info));
	dev_err(hsotg->dev, "  Data buffer length: %d\n", urb->length);
	dev_err(hsotg->dev, "  Data buffer length: %d\n", urb->length);
	dev_err(hsotg->dev, "  Transfer buffer: %p, Transfer DMA: %08lx\n",
	dev_err(hsotg->dev, "  Transfer buffer: %p, Transfer DMA: %08lx\n",
		urb->buf, (unsigned long)urb->dma);
		urb->buf, (unsigned long)urb->dma);
Loading