summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_core.h
blob: afd74ed693b31b44ca81a8fc83741dce7f12575d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/* $FreeBSD$ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Including this file is mandatory for all USB related c-files in the kernel.
 */

#ifndef _USB_CORE_H_
#define	_USB_CORE_H_

/*
 * The following macro will tell if an USB transfer is currently
 * receiving or transferring data.
 */
#define	USB_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.usb_mode == \
	USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \
	(((xfer)->endpointno & UE_DIR_IN) ? 1 : 0))

/* macros */

#define	USB_BUS_LOCK(_b)		mtx_lock(&(_b)->bus_mtx)
#define	USB_BUS_UNLOCK(_b)		mtx_unlock(&(_b)->bus_mtx)
#define	USB_BUS_LOCK_ASSERT(_b, _t)	mtx_assert(&(_b)->bus_mtx, _t)
#define	USB_XFER_LOCK(_x)		mtx_lock((_x)->xroot->xfer_mtx)
#define	USB_XFER_UNLOCK(_x)		mtx_unlock((_x)->xroot->xfer_mtx)
#define	USB_XFER_LOCK_ASSERT(_x, _t)	mtx_assert((_x)->xroot->xfer_mtx, _t)

/* helper for converting pointers to integers */
#define	USB_P2U(ptr) \
  (((const uint8_t *)(ptr)) - ((const uint8_t *)0))

/* helper for computing offsets */
#define	USB_ADD_BYTES(ptr,size) \
  ((void *)(USB_P2U(ptr) + (size)))

/* debug macro */
#define	USB_ASSERT KASSERT

/* structure prototypes */

struct file;
struct usb_bus;
struct usb_device;
struct usb_device_request;
struct usb_page;
struct usb_page_cache;
struct usb_xfer;
struct usb_xfer_root;
struct usb_string_lang;

/* typedefs */

/* structures */

/*
 * The following structure defines a set of internal USB transfer
 * flags.
 */
struct usb_xfer_flags_int {

	enum usb_hc_mode usb_mode;	/* shadow copy of "udev->usb_mode" */
	uint16_t control_rem;		/* remainder in bytes */

	uint8_t	open:1;			/* set if USB pipe has been opened */
	uint8_t	transferring:1;		/* set if an USB transfer is in
					 * progress */
	uint8_t	did_dma_delay:1;	/* set if we waited for HW DMA */
	uint8_t	did_close:1;		/* set if we closed the USB transfer */
	uint8_t	draining:1;		/* set if we are draining an USB
					 * transfer */
	uint8_t	started:1;		/* keeps track of started or stopped */
	uint8_t	bandwidth_reclaimed:1;
	uint8_t	control_xfr:1;		/* set if control transfer */
	uint8_t	control_hdr:1;		/* set if control header should be
					 * sent */
	uint8_t	control_act:1;		/* set if control transfer is active */
	uint8_t	control_stall:1;	/* set if control transfer should be stalled */

	uint8_t	short_frames_ok:1;	/* filtered version */
	uint8_t	short_xfer_ok:1;	/* filtered version */
#if USB_HAVE_BUSDMA
	uint8_t	bdma_enable:1;		/* filtered version (only set if
					 * hardware supports DMA) */
	uint8_t	bdma_no_post_sync:1;	/* set if the USB callback wrapper
					 * should not do the BUS-DMA post sync
					 * operation */
	uint8_t	bdma_setup:1;		/* set if BUS-DMA has been setup */
#endif
	uint8_t	isochronous_xfr:1;	/* set if isochronous transfer */
	uint8_t	curr_dma_set:1;		/* used by USB HC/DC driver */
	uint8_t	can_cancel_immed:1;	/* set if USB transfer can be
					 * cancelled immediately */
	uint8_t	doing_callback:1;	/* set if executing the callback */
};

/*
 * The following structure defines an USB transfer.
 */
struct usb_xfer {
	struct usb_callout timeout_handle;
	TAILQ_ENTRY(usb_xfer) wait_entry;	/* used at various places */

	struct usb_page_cache *buf_fixup;	/* fixup buffer(s) */
	struct usb_xfer_queue *wait_queue;	/* pointer to queue that we
						 * are waiting on */
	struct usb_page *dma_page_ptr;
	struct usb_endpoint *endpoint;	/* our USB endpoint */
	struct usb_xfer_root *xroot;	/* used by HC driver */
	void   *qh_start[2];		/* used by HC driver */
	void   *td_start[2];		/* used by HC driver */
	void   *td_transfer_first;	/* used by HC driver */
	void   *td_transfer_last;	/* used by HC driver */
	void   *td_transfer_cache;	/* used by HC driver */
	void   *priv_sc;		/* device driver data pointer 1 */
	void   *priv_fifo;		/* device driver data pointer 2 */
	void   *local_buffer;
	usb_frlength_t *frlengths;
	struct usb_page_cache *frbuffers;
	usb_callback_t *callback;

	usb_frlength_t max_hc_frame_size;
	usb_frlength_t max_data_length;
	usb_frlength_t sumlen;		/* sum of all lengths in bytes */
	usb_frlength_t actlen;		/* actual length in bytes */
	usb_timeout_t timeout;		/* milliseconds */

	usb_frcount_t max_frame_count;	/* initial value of "nframes" after
					 * setup */
	usb_frcount_t nframes;		/* number of USB frames to transfer */
	usb_frcount_t aframes;		/* actual number of USB frames
					 * transferred */
	usb_stream_t stream_id;		/* USB3.0 specific field */

	uint16_t max_packet_size;
	uint16_t max_frame_size;
	uint16_t qh_pos;
	uint16_t isoc_time_complete;	/* in ms */
	usb_timeout_t interval;	/* milliseconds */

	uint8_t	address;		/* physical USB address */
	uint8_t	endpointno;		/* physical USB endpoint */
	uint8_t	max_packet_count;
	uint8_t	usb_state;
	uint8_t fps_shift;		/* down shift of FPS, 0..3 */

	usb_error_t error;

	struct usb_xfer_flags flags;
	struct usb_xfer_flags_int flags_int;
};

/* external variables */

extern struct mtx usb_ref_lock;
extern const struct usb_string_lang usb_string_lang_en;

/* typedefs */

typedef struct malloc_type *usb_malloc_type;

/* prototypes */

#endif					/* _USB_CORE_H_ */
OpenPOWER on IntegriCloud