summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-08-12 18:42:02 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-08-12 18:42:02 -0700
commit322bdbf706ac632cc1eb48cd247e752281a0cd99 (patch)
tree11b0a3ad1c853865697c7a43eec8dc67252fe356 /include/linux
parentb2520184afc11a47eaad785dd9f5d79c4048cef5 (diff)
parent7442ce495b8072d22431a5cf692260c228612dba (diff)
Merge http://linuxusb.bkbits.net/linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/usb.h53
1 files changed, 47 insertions, 6 deletions
diff --git a/include/linux/usb.h b/include/linux/usb.h
index d9907d770a30..7f44f0ff05ef 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -734,6 +734,7 @@ extern void usb_deregister_dev(int num_minors, int start_minor);
*/
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
#define USB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
+#define URB_NO_DMA_MAP 0x0004 /* urb->*_dma are valid on submit */
#define USB_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */
#define USB_NO_FSBR 0x0020 /* UHCI-specific */
#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
@@ -771,11 +772,15 @@ typedef void (*usb_complete_t)(struct urb *);
* @transfer_flags: A variety of flags may be used to affect how URB
* submission, unlinking, or operation are handled. Different
* kinds of URB can use different flags.
- * @transfer_buffer: For non-iso transfers, this identifies the buffer
- * to (or from) which the I/O request will be performed. This
- * buffer must be suitable for DMA; allocate it with kmalloc()
+ * @transfer_buffer: This identifies the buffer to (or from) which
+ * the I/O request will be performed (unless URB_NO_DMA_MAP is set).
+ * This buffer must be suitable for DMA; allocate it with kmalloc()
* or equivalent. For transfers to "in" endpoints, contents of
- * this buffer will be modified.
+ * this buffer will be modified. This buffer is used for data
+ * phases of control transfers.
+ * @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device
+ * driver is saying that it provided this DMA address, which the host
+ * controller driver should use instead of the transfer_buffer.
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet
* size for the endpoint, which is a function of the configuration
@@ -789,6 +794,11 @@ typedef void (*usb_complete_t)(struct urb *);
* @setup_packet: Only used for control transfers, this points to eight bytes
* of setup data. Control transfers always start by sending this data
* to the device. Then transfer_buffer is read or written, if needed.
+ * (Not used when URB_NO_DMA_MAP is set.)
+ * @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device
+ * driver has provided this DMA address for the setup packet. The
+ * host controller driver should use instead of setup_buffer.
+ * If there is a data phase, its buffer is identified by transfer_dma.
* @start_frame: Returns the initial frame for interrupt or isochronous
* transfers.
* @number_of_packets: Lists the number of ISO transfer buffers.
@@ -811,6 +821,23 @@ typedef void (*usb_complete_t)(struct urb *);
* are submitted using usb_submit_urb(), and pending requests may be canceled
* using usb_unlink_urb().
*
+ * Data Transfer Buffers:
+ *
+ * Normally drivers provide I/O buffers allocated with kmalloc() or otherwise
+ * taken from the general page pool. That is provided by transfer_buffer
+ * (control requests also use setup_packet), and host controller drivers
+ * perform a dma mapping (and unmapping) for each buffer transferred. Those
+ * mapping operations can be expensive on some platforms (such using a dma
+ * bounce buffer), although they're cheap on commodity x86 and ppc hardware.
+ *
+ * Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which
+ * tells the host controller driver that no such mapping is needed since
+ * the device driver is DMA-aware. For example, they might allocate a DMA
+ * buffer with usb_buffer_alloc(), or call usb_buffer_map().
+ * When this transfer flag is provided, host controller drivers will use the
+ * dma addresses found in the transfer_dma and/or setup_dma fields rather than
+ * determing a dma address themselves.
+ *
* Initialization:
*
* All URBs submitted must initialize dev, pipe,
@@ -818,10 +845,10 @@ typedef void (*usb_complete_t)(struct urb *);
* The USB_ASYNC_UNLINK transfer flag affects later invocations of
* the usb_unlink_urb() routine.
*
- * All non-isochronous URBs must also initialize
+ * All URBs must also initialize
* transfer_buffer and transfer_buffer_length. They may provide the
* URB_SHORT_NOT_OK transfer flag, indicating that short reads are
- * to be treated as errors.
+ * to be treated as errors; that flag is invalid for write requests.
*
* Bulk URBs may
* use the USB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers
@@ -896,10 +923,12 @@ struct urb
int status; /* (return) non-ISO status */
unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
void *transfer_buffer; /* (in) associated data buffer */
+ dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
int transfer_buffer_length; /* (in) data buffer length */
int actual_length; /* (return) actual transfer length */
int bandwidth; /* bandwidth for INT/ISO request */
unsigned char *setup_packet; /* (in) setup packet (control only) */
+ dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
int start_frame; /* (modify) start frame (INT/ISO) */
int number_of_packets; /* (in) number of ISO packets */
int interval; /* (in) transfer interval (INT/ISO) */
@@ -910,6 +939,8 @@ struct urb
struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */
};
+/* -------------------------------------------------------------------------- */
+
/**
* usb_fill_control_urb - initializes a control urb
* @urb: pointer to the urb to initialize.
@@ -1032,6 +1063,16 @@ extern struct urb *usb_get_urb(struct urb *urb);
extern int usb_submit_urb(struct urb *urb, int mem_flags);
extern int usb_unlink_urb(struct urb *urb);
+#define HAVE_USB_BUFFERS
+void *usb_buffer_alloc (struct usb_device *dev, size_t size,
+ int mem_flags, dma_addr_t *dma);
+void usb_buffer_free (struct usb_device *dev, size_t size,
+ void *addr, dma_addr_t dma);
+
+struct urb *usb_buffer_map (struct urb *urb);
+void usb_buffer_dmasync (struct urb *urb);
+void usb_buffer_unmap (struct urb *urb);
+
/*-------------------------------------------------------------------*
* SYNCHRONOUS CALL SUPPORT *
*-------------------------------------------------------------------*/