usb.h
来自「AMLOGIC DPF source code」· C头文件 代码 · 共 1,017 行 · 第 1/3 页
H
1,017 行
* transfers are at least double buffered, and then explicitly resubmitted
* in completion handlers, so
* that data (such as audio or video) streams at as constant a rate as the
* host controller scheduler can support.
*
* Completion Callbacks:
*
* The completion callback is made in_interrupt(), and one of the first
* things that a completion handler should do is check the status field.
* The status field is provided for all URBs. It is used to report
* unlinked URBs, and status for all non-ISO transfers. It should not
* be examined before the URB is returned to the completion handler.
*
* The context field is normally used to link URBs back to the relevant
* driver or request state.
*
* When the completion callback is invoked for non-isochronous URBs, the
* actual_length field tells how many bytes were transferred. This field
* is updated even when the URB terminated with an error or was unlinked.
*
* ISO transfer status is reported in the status and actual_length fields
* of the iso_frame_desc array, and the number of errors is reported in
* error_count. Completion callbacks for ISO transfers will normally
* (re)submit URBs to ensure a constant transfer rate.
*
* Note that even fields marked "public" should not be touched by the driver
* when the urb is owned by the hcd, that is, since the call to
* usb_submit_urb() till the entry into the completion routine.
*/
typedef struct urb
{
void *hcpriv; /* private data for host controller */
int bandwidth; /* bandwidth for INT/ISO request */
unsigned use_count; /* concurrent submissions counter */
__u8 reject; /* submissions will fail */
__u8 state; // 2 - SETUP, 1 - DATA, 0 - ACK
// __u8 data_path ; //0-SDRAM, 1- PARSER //for typhoon
/* public, documented fields in the urb that can be used by drivers */
struct list_head urb_list; /* list head for use by the urb owner */
struct usb_device *dev; /* (in) pointer to associated device */
unsigned int pipe; /* (in) pipe information */
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 */
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 (ISO) */
int number_of_packets; /* (in) number of ISO packets */
int interval; /* (modify) transfer interval (INT/ISO) */
int error_count; /* (return) number of ISO errors */
void *context; /* (in) context for completion */
OS_EVENT *done; /*internal use only */
usb_complete_t complete; /* (in) completion routine */
struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */
} urb_t;
//USB data_path
#define USB_DP_PARSER 1
#define USB_DP_SDRAM 0
/* -------------------------------------------------------------------------- */
/**
* usb_fill_control_urb - initializes a control urb
* @urb: pointer to the urb to initialize.
* @dev: pointer to the struct usb_device for this urb.
* @pipe: the endpoint pipe
* @setup_packet: pointer to the setup_packet buffer
* @transfer_buffer: pointer to the transfer buffer
* @buffer_length: length of the transfer buffer
* @complete: pointer to the usb_complete_t function
* @context: what to set the urb context to.
*
* Initializes a control urb with the proper information needed to submit
* it to a device.
*/
static inline void usb_fill_control_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
unsigned char *setup_packet,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete,
void *context)
{
urb->dev = dev;
urb->pipe = pipe;
urb->setup_packet = setup_packet;
urb->transfer_buffer = transfer_buffer;
urb->transfer_buffer_length = buffer_length;
urb->complete = complete;
urb->context = context;
}
/**
* usb_fill_bulk_urb - macro to help initialize a bulk urb
* @urb: pointer to the urb to initialize.
* @dev: pointer to the struct usb_device for this urb.
* @pipe: the endpoint pipe
* @transfer_buffer: pointer to the transfer buffer
* @buffer_length: length of the transfer buffer
* @complete: pointer to the usb_complete_t function
* @context: what to set the urb context to.
*
* Initializes a bulk urb with the proper information needed to submit it
* to a device.
*/
static inline void usb_fill_bulk_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete,
void *context)
{
urb->dev = dev;
urb->pipe = pipe;
urb->transfer_buffer = transfer_buffer;
urb->transfer_buffer_length = buffer_length;
urb->complete = complete;
urb->context = context;
}
/**
* usb_fill_int_urb - macro to help initialize a interrupt urb
* @urb: pointer to the urb to initialize.
* @dev: pointer to the struct usb_device for this urb.
* @pipe: the endpoint pipe
* @transfer_buffer: pointer to the transfer buffer
* @buffer_length: length of the transfer buffer
* @complete: pointer to the usb_complete_t function
* @context: what to set the urb context to.
* @interval: what to set the urb interval to, encoded like
* the endpoint descriptor's bInterval value.
*
* Initializes a interrupt urb with the proper information needed to submit
* it to a device.
* Note that high speed interrupt endpoints use a logarithmic encoding of
* the endpoint interval, and express polling intervals in microframes
* (eight per millisecond) rather than in frames (one per millisecond).
*/
static inline void usb_fill_int_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete,
void *context,
int interval)
{
urb->dev = dev;
urb->pipe = pipe;
urb->transfer_buffer = transfer_buffer;
urb->transfer_buffer_length = buffer_length;
urb->complete = complete;
urb->context = context;
if (dev->speed == USB_SPEED_HIGH)
urb->interval = 1 << (interval - 1);
else
urb->interval = interval;
urb->start_frame = -1;
}
struct urb *usb_alloc_urb(int iso_packets);
struct urb *usb_alloc_urb_no_sem(int iso_packets);
extern void usb_free_urb(struct urb *urb);
#define usb_put_urb usb_free_urb
int usb_submit_urb(urb_t *urb);
extern int usb_unlink_urb(struct urb *urb);
extern void usb_kill_urb(struct urb *urb);
/*-------------------------------------------------------------------*
* SYNCHRONOUS CALL SUPPORT *
*-------------------------------------------------------------------*/
extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
__u8 request, __u8 requesttype, __u16 value, __u16 index,
void *data, __u16 size, int timeout);
extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length,
int timeout);
/* wrappers around usb_control_msg() for the most common standard requests */
extern int usb_get_device_descriptor(struct usb_device *dev,
unsigned int size);
extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
unsigned char descindex, void *buf, int size);
extern int usb_get_status(struct usb_device *dev,
int type, int target, void *data);
extern int usb_get_string(struct usb_device *dev,
unsigned short langid, unsigned char index, void *buf, int size);
extern int usb_string(struct usb_device *dev, int index,
char *buf, size_t size);
/* wrappers that also update important state inside usbcore */
extern int usb_clear_halt(struct usb_device *dev, int pipe);
extern int usb_reset_configuration(struct usb_device *dev);
extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
extern int usb_unbind_interface(struct usb_interface *intf);
extern int usb_probe_interface(struct usb_interface *intf);
extern void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf);
extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
/*
* timeouts, in milliseconds, used for sending/receiving control messages
* they typically complete within a few frames (msec) after they're issued
* USB identifies 5 second timeouts, maybe more in a few cases, and a few
* slow devices (like some MGE Ellipse UPSes) actually push that limit.
*/
#define USB_CTRL_GET_TIMEOUT 5000
#define USB_CTRL_SET_TIMEOUT 5000
/* -------------------------------------------------------------------------- */
/*
* For various legacy reasons, Linux has a small cookie that's paired with
* a struct usb_device to identify an endpoint queue. Queue characteristics
* are defined by the endpoint's descriptor. This cookie is called a "pipe",
* an unsigned int encoded as:
*
* - direction: bit 7 (0 = Host-to-Device [Out],
* 1 = Device-to-Host [In] ...
* like endpoint bEndpointAddress)
* - device address: bits 8-14 ... bit positions known to uhci-hcd
* - endpoint: bits 15-18 ... bit positions known to uhci-hcd
* - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt,
* 10 = control, 11 = bulk)
*
* Given the device address and endpoint descriptor, pipes are redundant.
*/
/* NOTE: these are not the standard USB_ENDPOINT_XFER_* values!! */
/* (yet ... they're the values used by usbfs) */
#define PIPE_ISOCHRONOUS 0
#define PIPE_INTERRUPT 1
#define PIPE_CONTROL 2
#define PIPE_BULK 3
#define usb_pipein(pipe) ((pipe) & USB_DIR_IN)
#define usb_pipeout(pipe) (!usb_pipein(pipe))
#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f)
#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
#define usb_pipetype(pipe) (((pipe) >> 30) & 3)
#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT)
#define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL)
#define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK)
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | ((bit) << (ep)))
#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT)
#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
#define usb_pipedata(pipe) (((pipe) >> 19) & 1)
#define usb_pipeslow(pipe) (((pipe) >> 26) & 1)
/* Endpoint halt control/status */
#define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1)
#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep)))
#define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep)))
#define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep)))
#define __create_pipe(dev, endpoint) ((dev->devnum << 8) | ((endpoint) << 15) | \
((dev->speed == USB_SPEED_LOW) << 26))
#define __default_pipe(dev) ((dev->speed == USB_SPEED_LOW) << 26)
/* Create various pipes... */
#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev))
#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev) | USB_DIR_IN)
unsigned short usb_maxpacket(struct usb_device *udev, int pipe, int is_out);
/*-------------------------------------------------------------------------*/
/* USB status codes */
#define USB_CC_MASK 0x0f
#define USB_ST_NOERROR 0x00
#define USB_ST_CRC 0x01
#define USB_ST_BITSTUFF 0x02
#define USB_ST_TGLMISMATCH 0x03
#define USB_ST_STALL 0x04 /* pipe stalled, also in urb->status*/
#define USB_ST_NORESPONSE 0x05 /* device not responding/handshaking */
#define USB_ST_DATAOVERRUN 0x08
#define USB_ST_DATAUNDERRUN 0x09
#define USB_ST_URB_INVALID 0x0a /* invalid value/transfer type */
#define USB_ST_URB_REQ_ERROR 0x0b /* invalid endpoint */
#define USB_ST_BUFFEROVERRUN 0x0c
#define USB_ST_BUFFERUNDERRUN 0x0d
#define USB_ST_EPHALTED 0x10
#define USB_ST_TIMEOUT 0x20 /* communication timed out, also in urb->status**/
#define USB_ST_REMOVED 0x40 /* device not existing or removed */
#define USB_ST_NOTSUPPORTED 0x80
/* api provided by usbd */
struct usb_device *usb_alloc_dev(struct usb_device *parent,
struct usb_bus *bus, unsigned port0);
void usb_release_dev(struct usb_device *udev);
#define usb_free_dev usb_release_dev
//void usb_free_dev(usb_device_t *dev);
int usb_connect(usb_device_t *dev);
void usb_disconnect(usb_device_t **dev);
void usb_find_driver(usb_device_t *dev);
void usb_release_driver(usb_device_t *dev);
//int usb_device_reset(usb_device_t *dev);
//int usb_clear_halt(usb_device_t *dev, __u32 pipe);
__u16 usb_get_frame_number(struct usb_device *dev);
void usb_set_device_state(struct usb_device *udev,
enum usb_device_state new_state);
void usb_init();
void usb_exit();
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?