mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
usb: add a hcd_uses_dma helper
The USB buffer allocation code is the only place in the usb core (and in fact the whole kernel) that uses is_device_dma_capable, while the URB mapping code uses the uses_dma flag in struct usb_bus. Switch the buffer allocation to use the uses_dma flag used by the rest of the USB code, and create a helper in hcd.h that checks this flag as well as the CONFIG_HAS_DMA to simplify the caller a bit. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20190811080520.21712-3-hch@lst.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
dd3ecf17ba
commit
edfbcb321f
@ -66,9 +66,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
|
|||||||
char name[16];
|
char name[16];
|
||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
if (hcd->localmem_pool ||
|
if (hcd->localmem_pool || !hcd_uses_dma(hcd))
|
||||||
!IS_ENABLED(CONFIG_HAS_DMA) ||
|
|
||||||
!is_device_dma_capable(hcd->self.sysdev))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < HCD_BUFFER_POOLS; i++) {
|
for (i = 0; i < HCD_BUFFER_POOLS; i++) {
|
||||||
@ -129,8 +127,7 @@ void *hcd_buffer_alloc(
|
|||||||
return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
|
return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
|
||||||
|
|
||||||
/* some USB hosts just use PIO */
|
/* some USB hosts just use PIO */
|
||||||
if (!IS_ENABLED(CONFIG_HAS_DMA) ||
|
if (!hcd_uses_dma(hcd)) {
|
||||||
!is_device_dma_capable(bus->sysdev)) {
|
|
||||||
*dma = ~(dma_addr_t) 0;
|
*dma = ~(dma_addr_t) 0;
|
||||||
return kmalloc(size, mem_flags);
|
return kmalloc(size, mem_flags);
|
||||||
}
|
}
|
||||||
@ -160,8 +157,7 @@ void hcd_buffer_free(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_HAS_DMA) ||
|
if (!hcd_uses_dma(hcd)) {
|
||||||
!is_device_dma_capable(bus->sysdev)) {
|
|
||||||
kfree(addr);
|
kfree(addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1412,7 +1412,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
|
|||||||
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
|
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
|
||||||
if (hcd->self.uses_pio_for_control)
|
if (hcd->self.uses_pio_for_control)
|
||||||
return ret;
|
return ret;
|
||||||
if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
|
if (hcd_uses_dma(hcd)) {
|
||||||
if (is_vmalloc_addr(urb->setup_packet)) {
|
if (is_vmalloc_addr(urb->setup_packet)) {
|
||||||
WARN_ONCE(1, "setup packet is not dma capable\n");
|
WARN_ONCE(1, "setup packet is not dma capable\n");
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@ -1446,7 +1446,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
|
|||||||
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||||
if (urb->transfer_buffer_length != 0
|
if (urb->transfer_buffer_length != 0
|
||||||
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
|
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
|
||||||
if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
|
if (hcd_uses_dma(hcd)) {
|
||||||
if (urb->num_sgs) {
|
if (urb->num_sgs) {
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
@ -4608,7 +4608,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
|||||||
|
|
||||||
buf = urb->transfer_buffer;
|
buf = urb->transfer_buffer;
|
||||||
|
|
||||||
if (hcd->self.uses_dma) {
|
if (hcd_uses_dma(hcd)) {
|
||||||
if (!buf && (urb->transfer_dma & 3)) {
|
if (!buf && (urb->transfer_dma & 3)) {
|
||||||
dev_err(hsotg->dev,
|
dev_err(hsotg->dev,
|
||||||
"%s: unaligned transfer with no transfer_buffer",
|
"%s: unaligned transfer with no transfer_buffer",
|
||||||
|
@ -1457,7 +1457,7 @@ typedef void (*usb_complete_t)(struct urb *);
|
|||||||
* field rather than determining a dma address themselves.
|
* field rather than determining a dma address themselves.
|
||||||
*
|
*
|
||||||
* Note that transfer_buffer must still be set if the controller
|
* Note that transfer_buffer must still be set if the controller
|
||||||
* does not support DMA (as indicated by bus.uses_dma) and when talking
|
* does not support DMA (as indicated by hcd_uses_dma()) and when talking
|
||||||
* to root hub. If you have to trasfer between highmem zone and the device
|
* to root hub. If you have to trasfer between highmem zone and the device
|
||||||
* on such controller, create a bounce buffer or bail out with an error.
|
* on such controller, create a bounce buffer or bail out with an error.
|
||||||
* If transfer_buffer cannot be set (is in highmem) and the controller is DMA
|
* If transfer_buffer cannot be set (is in highmem) and the controller is DMA
|
||||||
|
@ -422,6 +422,9 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
|
|||||||
return hcd->high_prio_bh.completing_ep == ep;
|
return hcd->high_prio_bh.completing_ep == ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define hcd_uses_dma(hcd) \
|
||||||
|
(IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma)
|
||||||
|
|
||||||
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
|
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
|
||||||
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
|
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
|
||||||
int status);
|
int status);
|
||||||
|
Loading…
Reference in New Issue
Block a user