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

Commit 8ed5d192 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'topic/usb-ep-check-v2' into for-next



Pulling the EP validity checks in USB audio drivers.
It also adds a new helper in USB core, which was acked by Greg.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 19b592da 4f95646c
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -187,6 +187,31 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);

/*-------------------------------------------------------------------*/

static const int pipetypes[4] = {
	PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
};

/**
 * usb_urb_ep_type_check - sanity check of endpoint in the given urb
 * @urb: urb to be checked
 *
 * This performs a light-weight sanity check for the endpoint in the
 * given urb.  It returns 0 if the urb contains a valid endpoint, otherwise
 * a negative error code.
 */
int usb_urb_ep_type_check(const struct urb *urb)
{
	const struct usb_host_endpoint *ep;

	ep = usb_pipe_endpoint(urb->dev, urb->pipe);
	if (!ep)
		return -EINVAL;
	if (usb_pipetype(urb->pipe) != pipetypes[usb_endpoint_type(&ep->desc)])
		return -EINVAL;
	return 0;
}
EXPORT_SYMBOL_GPL(usb_urb_ep_type_check);

/**
 * usb_submit_urb - issue an asynchronous transfer request for an endpoint
 * @urb: pointer to the urb describing the request
@@ -326,9 +351,6 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
 */
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
	static int			pipetypes[4] = {
		PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
	};
	int				xfertype, max;
	struct usb_device		*dev;
	struct usb_host_endpoint	*ep;
@@ -444,7 +466,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
	 */

	/* Check that the pipe's type matches the endpoint's type */
	if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
	if (usb_urb_ep_type_check(urb))
		dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
			usb_pipetype(urb->pipe), pipetypes[xfertype]);

+2 −0
Original line number Diff line number Diff line
@@ -1728,6 +1728,8 @@ static inline int usb_urb_dir_out(struct urb *urb)
	return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
}

int usb_urb_ep_type_check(const struct urb *urb);

void *usb_alloc_coherent(struct usb_device *dev, size_t size,
	gfp_t mem_flags, dma_addr_t *dma);
void usb_free_coherent(struct usb_device *dev, size_t size,
+7 −0
Original line number Diff line number Diff line
@@ -342,6 +342,13 @@ static int bcd2000_init_midi(struct bcd2000 *bcd2k)
				bcd2k->midi_out_buf, BUFSIZE,
				bcd2000_output_complete, bcd2k, 1);

	/* sanity checks of EPs before actually submitting */
	if (usb_urb_ep_type_check(bcd2k->midi_in_urb) ||
	    usb_urb_ep_type_check(bcd2k->midi_out_urb)) {
		dev_err(&bcd2k->dev->dev, "invalid MIDI EP\n");
		return -EINVAL;
	}

	bcd2000_init_device(bcd2k);

	return 0;
+7 −0
Original line number Diff line number Diff line
@@ -461,6 +461,13 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
			  cdev->midi_out_buf, EP1_BUFSIZE,
			  snd_usb_caiaq_midi_output_done, cdev);

	/* sanity checks of EPs before actually submitting */
	if (usb_urb_ep_type_check(&cdev->ep1_in_urb) ||
	    usb_urb_ep_type_check(&cdev->midi_out_urb)) {
		dev_err(dev, "invalid EPs\n");
		return -EINVAL;
	}

	init_waitqueue_head(&cdev->ep1_wait_queue);
	init_waitqueue_head(&cdev->prepare_wait_queue);

+9 −0
Original line number Diff line number Diff line
@@ -718,6 +718,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
				  usb_rcvbulkpipe(usb_dev, 0x4),
				  cdev->ep4_in_buf, EP4_BUFSIZE,
				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
		if (ret < 0)
			goto exit_free_idev;

		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);

@@ -757,6 +760,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
				  usb_rcvbulkpipe(usb_dev, 0x4),
				  cdev->ep4_in_buf, EP4_BUFSIZE,
				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
		if (ret < 0)
			goto exit_free_idev;

		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);

@@ -802,6 +808,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
				  usb_rcvbulkpipe(usb_dev, 0x4),
				  cdev->ep4_in_buf, EP4_BUFSIZE,
				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
		if (ret < 0)
			goto exit_free_idev;

		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
		break;
Loading