static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd,
	struct urb *urb, gfp_t mem_flags)
{
	int ret;

	ret = alloc_align_buffer(urb, mem_flags);
	if (ret)
		return ret;

	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);

	/* Control packets over dma */
	if (urb->setup_dma)
		dma_sync_single_for_device(hcd->self.controller,
			urb->setup_dma, sizeof(struct usb_ctrlrequest),
			DMA_TO_DEVICE);

	/* urb buffers over dma */
	if (urb->transfer_dma) {
		enum dma_data_direction dir;
		dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;

		dma_sync_single_for_device(hcd->self.controller,
			urb->transfer_dma, urb->transfer_buffer_length, dir);
	}

	if (ret)
		free_align_buffer(urb);

	return ret;
}
static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd,
	struct urb *urb, gfp_t mem_flags)
{
	int ret;

	ret = alloc_align_buffer(urb, mem_flags, hcd);
	if (ret)
		return ret;

	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);

	if (ret)
		free_align_buffer(urb, hcd);

	return ret;
}
Beispiel #3
0
/*
 * Allocate a URB and initialize the various fields of it.
 * This API is used by the single_step_set_feature test of
 * EHSET where IN packet of the GetDescriptor request is
 * sent 15secs after the SETUP packet.
 * Return NULL if failed.
 */
static struct urb *xhci_request_single_step_set_feature_urb(
		struct usb_device *udev,
		void *dr,
		void *buf,
		struct completion *done)
{
	struct urb *urb;
	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
	struct usb_host_endpoint *ep;

	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb)
		return NULL;

	urb->pipe = usb_rcvctrlpipe(udev, 0);
	ep = udev->ep_in[usb_pipeendpoint(urb->pipe)];
	if (!ep) {
		usb_free_urb(urb);
		return NULL;
	}

	/*
	 * Initialize the various URB fields as these are used by the HCD
	 * driver to queue it and as well as when completion happens.
	 */
	urb->ep = ep;
	urb->dev = udev;
	urb->setup_packet = dr;
	urb->transfer_buffer = buf;
	urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
	urb->complete = xhci_single_step_completion;
	urb->status = -EINPROGRESS;
	urb->actual_length = 0;
	urb->transfer_flags = URB_DIR_IN;
	usb_get_urb(urb);
	atomic_inc(&urb->use_count);
	atomic_inc(&urb->dev->urbnum);
	usb_hcd_map_urb_for_dma(hcd, urb, GFP_KERNEL);
	urb->context = done;
	return urb;
}
int sunxi_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
				     gfp_t mem_flags)
{
	int ret;

	ret = sunxi_hcd_alloc_temp_buffer(urb, mem_flags);
	if (ret)
		return ret;

	ret = sunxi_hcd_alloc_temp_setup(urb, mem_flags);
	if (ret) {
		sunxi_hcd_free_temp_buffer(urb);
		return ret;
	}

	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
	if (ret) {
		sunxi_hcd_free_temp_setup(urb);
		sunxi_hcd_free_temp_buffer(urb);
		return ret;
	}

	return ret;
}