summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usbfvar.h
blob: 2d684d18cee5816f8d8aa3d1422ceaed343d868c (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
/*	$OpenBSD: usbfvar.h,v 1.2 2007/06/06 19:25:50 mk Exp $	*/

/*
 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * USB function driver interface
 *
 * This file is to be included only by the logical device driver and the
 * USB device controller (DC) driver.
 */

/*** structures corresponding to USB protocol components ***/

struct usbf_endpoint {
	struct usbf_interface	    *iface;
	usb_endpoint_descriptor_t   *edesc;
	int			     halted;	/* UF_ENDPOINT_HALT set */
	int			     refcnt;
	SIMPLEQ_ENTRY(usbf_endpoint) next;
};

struct usbf_interface {
	struct usbf_config	     *config;
	usb_interface_descriptor_t   *idesc;
	LIST_HEAD(, usbf_pipe)        pipes;
	SIMPLEQ_HEAD(, usbf_endpoint) endpoint_head;
	SIMPLEQ_ENTRY(usbf_interface) next;
};

struct usbf_config {
	struct usbf_device *uc_device;
	usb_config_descriptor_t *uc_cdesc;
	size_t uc_cdesc_size;
	int uc_closed;
	SIMPLEQ_HEAD(, usbf_interface) iface_head;
	SIMPLEQ_ENTRY(usbf_config) next;
};

struct usbf_device {
	struct device		 bdev;		/* base device */
	struct usbf_bus		*bus;		/* device controller */
	struct usbf_function	*function;	/* function driver */
	struct usbf_pipe	*default_pipe;	/* pipe 0 (device control) */
	struct usbf_xfer	*default_xfer;	/* device request xfer */
	struct usbf_xfer	*data_xfer;	/* request response xfer */
	int			 address;	/* assigned by host (or 0) */
	usbf_config_handle	 config;	/* set by host (or NULL) */
	usb_status_t		 status;	/* device status */
	usb_device_request_t	 def_req;	/* device request buffer */
	struct usbf_endpoint	 def_ep;	/* for pipe 0 */
	usb_endpoint_descriptor_t def_ep_desc;	/* for pipe 0 */
	usb_device_descriptor_t  ddesc;		/* device descriptor */
	usb_string_descriptor_t *sdesc;		/* string descriptors */
	size_t			 sdesc_size;	/* size of ud_sdesc */
	uByte			 string_id;	/* next string id */
	SIMPLEQ_HEAD(, usbf_config) configs;
};

/*** software control structures ***/

struct usbf_pipe_methods {
	usbf_status	(*transfer)(usbf_xfer_handle);
	usbf_status	(*start)(usbf_xfer_handle);
	void		(*abort)(usbf_xfer_handle);
	void		(*done)(usbf_xfer_handle);
	void		(*close)(usbf_pipe_handle);
};

struct usbf_bus_methods {
	usbf_status	  (*open_pipe)(struct usbf_pipe *);
	void		  (*soft_intr)(void *);
	usbf_status	  (*allocm)(struct usbf_bus *, usb_dma_t *, u_int32_t);
	void		  (*freem)(struct usbf_bus *, usb_dma_t *);
	struct usbf_xfer *(*allocx)(struct usbf_bus *);
	void		  (*freex)(struct usbf_bus *, struct usbf_xfer *);
};

struct usbf_softc;

struct usbf_bus {
	/* Filled by DC driver */
	struct device		 bdev;		/* base device */
	struct usbf_bus_methods	*methods;
	size_t			 pipe_size;	/* size of pipe struct */
	u_int8_t		 ep0_maxp;	/* packet size for EP0 */
	int			 usbrev;	/* as in struct usbd_bus */
	/* Filled by usbf driver */
	struct usbf_softc	*usbfctl;
	int			 intr_context;
#ifdef USB_USE_SOFTINTR
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
	void			*soft;		/* soft interrupt cookie */
#else
	usb_callout_t		 softi;		/* timeout handle */
#endif
#endif
	bus_dma_tag_t		 dmatag;	/* DMA tag */
};

struct usbf_port {
	usb_port_status_t	 status;
	u_int8_t		 portno;
	struct usbf_device	*device;	/* connected function */
};

struct usbf_pipe {
	struct usbf_device	 *device;
	struct usbf_interface	 *iface;	/* unless default pipe */
	struct usbf_endpoint	 *endpoint;
	int			  refcnt;
	int			  running;
	int			  aborting;
	SIMPLEQ_HEAD(, usbf_xfer) queue;
	LIST_ENTRY(usbf_pipe)	  next;

	char			  repeat;
	int			  interval;

	/* Filled by DC driver. */
	struct usbf_pipe_methods *methods;
};

struct usbf_xfer {
	struct usbf_pipe	*pipe;
	usbf_private_handle	 priv;
	void			*buffer;
	u_int32_t		 length;
	u_int32_t		 actlen;
	u_int16_t		 flags;
	u_int32_t		 timeout;
	usbf_status		 status;
	usbf_callback		 callback;
	SIMPLEQ_ENTRY(usbf_xfer) next;

	/* for memory management */
	struct usbf_device	*device;
	int			 rqflags;
	usb_dma_t		 dmabuf;

	usb_callout_t		 timeout_handle;
};


/* usbf.c */
void	    usbf_host_reset(usbf_bus_handle);
void	    usbf_do_request(usbf_xfer_handle, usbf_private_handle,
			    usbf_status);

/* usbf_subr.c */
usbf_status usbf_new_device(device_ptr_t, usbf_bus_handle, int,
			    int, int, struct usbf_port *);
usbf_status usbf_set_endpoint_feature(usbf_config_handle, u_int8_t,
				      u_int16_t);
usbf_status usbf_clear_endpoint_feature(usbf_config_handle, u_int8_t,
					u_int16_t);
usbf_status usbf_insert_transfer(usbf_xfer_handle xfer);
void	    usbf_transfer_complete(usbf_xfer_handle xfer);
usbf_status usbf_allocmem(usbf_bus_handle, size_t, size_t, usb_dma_t *);
void	    usbf_freemem(usbf_bus_handle, usb_dma_t *);
usbf_status usbf_softintr_establish(struct usbf_bus *);
void	    usbf_schedsoftintr(struct usbf_bus *);