1/*	$NetBSD: usbdi.h,v 1.108 2022/08/20 11:32:20 riastradh Exp $	*/
2/*	$FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $	*/
3
4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _USBDI_H_
35#define _USBDI_H_
36
37#include <sys/types.h>
38
39#include <dev/usb/usb.h>
40
41struct usbd_bus;
42struct usbd_device;
43struct usbd_interface;
44struct usbd_pipe;
45struct usbd_xfer;
46
47typedef enum {		/* keep in sync with usbd_error_strs */
48	USBD_NORMAL_COMPLETION = 0, /* must be 0 */
49	USBD_IN_PROGRESS,	/* 1 */
50	/* errors */
51	USBD_PENDING_REQUESTS,	/* 2 */
52	USBD_NOT_STARTED,	/* 3 */
53	USBD_INVAL,		/* 4 */
54	USBD_NOMEM,		/* 5 */
55	USBD_CANCELLED,		/* 6 */
56	USBD_BAD_ADDRESS,	/* 7 */
57	USBD_IN_USE,		/* 8 */
58	USBD_NO_ADDR,		/* 9 */
59	USBD_SET_ADDR_FAILED,	/* 10 */
60	USBD_NO_POWER,		/* 11 */
61	USBD_TOO_DEEP,		/* 12 */
62	USBD_IOERROR,		/* 13 */
63	USBD_NOT_CONFIGURED,	/* 14 */
64	USBD_TIMEOUT,		/* 15 */
65	USBD_SHORT_XFER,	/* 16 */
66	USBD_STALLED,		/* 17 */
67	USBD_INTERRUPTED,	/* 18 */
68
69	USBD_ERROR_MAX		/* must be last */
70} usbd_status;
71
72typedef void (*usbd_callback)(struct usbd_xfer *, void *, usbd_status);
73
74/* Use default (specified by ep. desc.) interval on interrupt pipe */
75#define USBD_DEFAULT_INTERVAL	(-1)
76
77/* Open flags */
78#define USBD_EXCLUSIVE_USE	0x01
79#define USBD_MPSAFE		0x80
80
81/* Request flags */
82#define USBD_SYNCHRONOUS	0x02	/* wait for completion */
83/* in usb.h #define USBD_SHORT_XFER_OK	0x04*/	/* allow short reads */
84#define USBD_FORCE_SHORT_XFER	0x08	/* force last short packet on write */
85#define USBD_SYNCHRONOUS_SIG	0x10	/* if waiting for completion,
86					 * also take signals */
87
88#define USBD_NO_TIMEOUT 0
89#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
90#define	USBD_CONFIG_TIMEOUT  (3*USBD_DEFAULT_TIMEOUT)
91
92#define DEVINFOSIZE 1024
93
94usbd_status usbd_open_pipe_intr(struct usbd_interface *, uint8_t, uint8_t,
95    struct usbd_pipe **, void *, void *, uint32_t, usbd_callback, int);
96usbd_status usbd_open_pipe(struct usbd_interface *, uint8_t, uint8_t,
97     struct usbd_pipe **);
98void usbd_close_pipe(struct usbd_pipe *);
99
100usbd_status usbd_transfer(struct usbd_xfer *);
101
102void *usbd_get_buffer(struct usbd_xfer *);
103struct usbd_pipe *usbd_get_pipe0(struct usbd_device *);
104
105int usbd_create_xfer(struct usbd_pipe *, size_t, unsigned int, unsigned int,
106    struct usbd_xfer **);
107void usbd_destroy_xfer(struct usbd_xfer *);
108
109void usbd_setup_xfer(struct usbd_xfer *, void *, void *,
110    uint32_t, uint16_t, uint32_t, usbd_callback);
111
112void usbd_setup_default_xfer(struct usbd_xfer *, struct usbd_device *,
113    void *, uint32_t, usb_device_request_t *, void *,
114    uint32_t, uint16_t, usbd_callback);
115
116void usbd_setup_isoc_xfer(struct usbd_xfer *, void *, uint16_t *,
117    uint32_t, uint16_t, usbd_callback);
118
119void usbd_get_xfer_status(struct usbd_xfer *, void **,
120    void **, uint32_t *, usbd_status *);
121
122usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
123    (struct usbd_interface *, uint8_t);
124
125void usbd_abort_pipe(struct usbd_pipe *);
126void usbd_abort_default_pipe(struct usbd_device *);
127
128void usbd_suspend_pipe(struct usbd_pipe *);
129void usbd_resume_pipe(struct usbd_pipe *);
130
131usbd_status usbd_clear_endpoint_stall(struct usbd_pipe *);
132void usbd_clear_endpoint_stall_async(struct usbd_pipe *);
133
134void usbd_clear_endpoint_toggle(struct usbd_pipe *);
135usbd_status usbd_endpoint_count(struct usbd_interface *, uint8_t *);
136
137usbd_status usbd_interface_count(struct usbd_device *, uint8_t *);
138
139void usbd_interface2device_handle(struct usbd_interface *, struct usbd_device **);
140usbd_status usbd_device2interface_handle(struct usbd_device *,
141    uint8_t, struct usbd_interface **);
142
143struct usbd_device *usbd_pipe2device_handle(struct usbd_pipe *);
144
145usbd_status usbd_sync_transfer(struct usbd_xfer *);
146usbd_status usbd_sync_transfer_sig(struct usbd_xfer *);
147
148usbd_status usbd_do_request(struct usbd_device *, usb_device_request_t *, void *);
149usbd_status usbd_do_request_flags(struct usbd_device *, usb_device_request_t *,
150    void *, uint16_t, int *, uint32_t);
151usbd_status usbd_do_request_len(struct usbd_device *dev,
152    usb_device_request_t *req, size_t len, void *data, uint16_t flags,
153    int *actlen, uint32_t timeout);
154
155usb_interface_descriptor_t *
156    usbd_get_interface_descriptor(struct usbd_interface *);
157usb_endpoint_descriptor_t *
158    usbd_get_endpoint_descriptor(struct usbd_interface *, uint8_t);
159
160usb_config_descriptor_t *usbd_get_config_descriptor(struct usbd_device *);
161usb_device_descriptor_t *usbd_get_device_descriptor(struct usbd_device *);
162
163usbd_status usbd_set_interface(struct usbd_interface *, int);
164usbd_status usbd_get_interface(struct usbd_interface *, uint8_t *);
165
166int usbd_get_no_alts(usb_config_descriptor_t *, int);
167
168void usbd_fill_deviceinfo(struct usbd_device *, struct usb_device_info *, int);
169int usbd_get_interface_altindex(struct usbd_interface *);
170
171usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *,
172    int, int);
173usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *,
174    int, int, int);
175
176void usbd_dopoll(struct usbd_interface *);
177void usbd_set_polling(struct usbd_device *, int);
178
179const char *usbd_errstr(usbd_status);
180
181void usbd_add_dev_event(int, struct usbd_device *);
182void usbd_add_drv_event(int, struct usbd_device *, device_t);
183
184char *usbd_devinfo_alloc(struct usbd_device *, int);
185void usbd_devinfo_free(char *);
186
187const struct usbd_quirks *usbd_get_quirks(struct usbd_device *);
188
189usbd_status usbd_reload_device_desc(struct usbd_device *);
190
191int usbd_ratecheck(struct timeval *);
192
193usbd_status usbd_get_string(struct usbd_device *, int, char *);
194usbd_status usbd_get_string0(struct usbd_device *, int, char *, int);
195
196/* For use by HCI drivers, not USB device drivers */
197void usbd_xfer_schedule_timeout(struct usbd_xfer *);
198bool usbd_xfer_trycomplete(struct usbd_xfer *);
199void usbd_xfer_abort(struct usbd_xfer *);
200
201/* Used to clear endpoint stalls from the softint */
202void usbd_clear_endpoint_stall_task(void *);
203
204/*
205 * The usb_task structs form a queue of things to run in the USB event
206 * thread.  Normally this is just device discovery when a connect/disconnect
207 * has been detected.  But it may also be used by drivers that need to
208 * perform (short) tasks that must have a process context.
209 */
210struct usb_task {
211	TAILQ_ENTRY(usb_task) next;
212	void (*fun)(void *);
213	void *arg;
214	volatile unsigned queue;
215	int flags;
216};
217#define	USB_TASKQ_HC		0
218#define	USB_TASKQ_DRIVER	1
219#define	USB_NUM_TASKQS		2
220#define	USB_TASKQ_NAMES		{"usbtask-hc", "usbtask-dr"}
221#define	USB_TASKQ_MPSAFE	0x80
222
223void usb_add_task(struct usbd_device *, struct usb_task *, int);
224bool usb_rem_task(struct usbd_device *, struct usb_task *);
225bool usb_rem_task_wait(struct usbd_device *, struct usb_task *, int,
226    kmutex_t *);
227bool usb_task_pending(struct usbd_device *, struct usb_task *);
228#define usb_init_task(t, f, a, fl) ((t)->fun = (f), (t)->arg = (a), (t)->queue = USB_NUM_TASKQS, (t)->flags = (fl))
229
230bool usb_in_event_thread(device_t);
231
232struct usb_devno {
233	uint16_t ud_vendor;
234	uint16_t ud_product;
235};
236const struct usb_devno *usb_match_device(const struct usb_devno *,
237	u_int, u_int, uint16_t, uint16_t);
238#define usb_lookup(tbl, vendor, product) \
239	usb_match_device((const struct usb_devno *)(tbl), sizeof(tbl) / sizeof((tbl)[0]), sizeof((tbl)[0]), (vendor), (product))
240#define	USB_PRODUCT_ANY		0xffff
241
242/* compat callbacks */
243void usbd_devinfo_vp(struct usbd_device *, char *, size_t, char *, size_t,
244    int, int);
245int usbd_printBCD(char *, size_t, int);
246
247
248/* NetBSD attachment information */
249
250/* Attach data */
251struct usb_attach_arg {
252	int			uaa_port;
253	int			uaa_vendor;
254	int			uaa_product;
255	int			uaa_release;
256	struct usbd_device *	uaa_device;	/* current device */
257	int			uaa_class;
258	int			uaa_subclass;
259	int			uaa_proto;
260	int			uaa_usegeneric;
261};
262
263struct usbif_attach_arg {
264	int			uiaa_port;
265	int			uiaa_configno;
266	int			uiaa_ifaceno;
267	int			uiaa_vendor;
268	int			uiaa_product;
269	int			uiaa_release;
270	struct usbd_device *	uiaa_device;	/* current device */
271
272	struct usbd_interface *	uiaa_iface;	/* current interface */
273	int			uiaa_class;
274	int			uiaa_subclass;
275	int			uiaa_proto;
276
277	/* XXX need accounting for interfaces not matched to */
278
279	struct usbd_interface **uiaa_ifaces;	/* all interfaces */
280	int			uiaa_nifaces;	/* number of interfaces */
281};
282
283/* Match codes. */
284#define UMATCH_HIGHEST					15
285/* First five codes is for a whole device. */
286#define UMATCH_VENDOR_PRODUCT_REV			14
287#define UMATCH_VENDOR_PRODUCT				13
288#define UMATCH_VENDOR_DEVCLASS_DEVPROTO			12
289#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO		11
290#define UMATCH_DEVCLASS_DEVSUBCLASS			10
291/* Next six codes are for interfaces. */
292#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE		 9
293#define UMATCH_VENDOR_PRODUCT_CONF_IFACE		 8
294#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO		 7
295#define UMATCH_VENDOR_IFACESUBCLASS			 6
296#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO	 5
297#define UMATCH_IFACECLASS_IFACESUBCLASS			 4
298#define UMATCH_IFACECLASS				 3
299#define UMATCH_IFACECLASS_GENERIC			 2
300/* Generic driver */
301#define UMATCH_GENERIC					 1
302/* No match */
303#define UMATCH_NONE					 0
304
305
306/*
307 * IPL_USB is defined as IPL_VM for drivers that have not been made MP safe.
308 * IPL_VM (currently) takes the kernel lock.
309 *
310 * Eventually, IPL_USB can/should be changed
311 */
312#define IPL_USB IPL_VM
313#define splhardusb splvm
314
315#define SOFTINT_USB SOFTINT_SERIAL
316#define IPL_SOFTUSB IPL_SOFTSERIAL
317#define splusb splsoftserial
318
319#endif /* _USBDI_H_ */
320