1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef _USB_DEVICE_H
9 #define _USB_DEVICE_H
10 #include <libusb-1.0/libusb.h>
11 #include "usb_core.h"
12 
13 #define USB_NUM_INTERFACE 16
14 #define USB_NUM_ENDPOINT  15
15 
16 #define USB_EP_ADDR(d) ((d)->bEndpointAddress)
17 #define USB_EP_ATTR(d) ((d)->bmAttributes)
18 #define USB_EP_PID(d) (USB_EP_ADDR(d) & USB_DIR_IN ? TOKEN_IN : TOKEN_OUT)
19 #define USB_EP_TYPE(d) (USB_EP_ATTR(d) & 0x3)
20 #define USB_EP_NR(d) (USB_EP_ADDR(d) & 0xF)
21 #define USB_EP_MAXP(d) ((d)->wMaxPacketSize)
22 #define USB_EP_ERR_TYPE 0xFF
23 
24 #define USB_EP_MAXP_SZ(m) ((m) & 0x7ff)
25 #define USB_EP_MAXP_MT(m) (((m) >> 11) & 0x3)
26 
27 enum {
28 	USB_INFO_VERSION,
29 	USB_INFO_SPEED,
30 	USB_INFO_BUS,
31 	USB_INFO_PORT,
32 	USB_INFO_VID,
33 	USB_INFO_PID
34 };
35 
36 struct usb_dev_ep {
37 	uint8_t pid;
38 	uint8_t type;
39 	uint16_t maxp;
40 };
41 
42 struct usb_dev {
43 	/* physical device info */
44 	struct usb_native_devinfo info;
45 	int addr;
46 	int version;
47 	int configuration;
48 
49 	/* interface info */
50 	int if_num;
51 	int alts[USB_NUM_INTERFACE];
52 
53 	/* endpoints info */
54 	struct usb_dev_ep epc;
55 	struct usb_dev_ep epi[USB_NUM_ENDPOINT];
56 	struct usb_dev_ep epo[USB_NUM_ENDPOINT];
57 
58 	/* libusb data */
59 	libusb_device_handle *handle;
60 };
61 
62 /*
63  * The purpose to implement struct usb_dev_req is to adapt
64  * struct usb_xfer to make a proper data format to talk
65  * with libusb.
66  */
67 struct usb_dev_req {
68 	struct usb_dev *udev;
69 	int    in;
70 	int    seq;
71 	/*
72 	 * buffer could include data from multiple usb_block,
73 	 * so here need some data to record it.
74 	 */
75 	uint8_t	*buffer;
76 	int     buf_size;
77 	int     blk_head;
78 	int     blk_tail;
79 
80 	struct usb_xfer *xfer;
81 	struct libusb_transfer *trn;
82 	struct usb_block *setup_blk;
83 };
84 
85 /* callback type used by code from HCD layer */
86 typedef int (*usb_dev_sys_cb)(void *hci_data, void *dev_data);
87 
88 struct usb_dev_sys_ctx_info {
89 	/*
90 	 * Libusb related global variables
91 	 */
92 	libusb_context *libusb_ctx;
93 	pthread_t thread;
94 	int thread_exit;
95 
96 	/* handles of callback */
97 	libusb_hotplug_callback_handle conn_handle;
98 	libusb_hotplug_callback_handle disconn_handle;
99 
100 	/*
101 	 * The following callback funtions will be registered by
102 	 * the code from HCD(eg: XHCI, EHCI...) emulation layer.
103 	 */
104 	usb_dev_sys_cb conn_cb;
105 	usb_dev_sys_cb disconn_cb;
106 	usb_dev_sys_cb notify_cb;
107 	usb_dev_sys_cb intr_cb;
108 	usb_dev_sys_cb lock_ep_cb;
109 	usb_dev_sys_cb unlock_ep_cb;
110 
111 	libusb_device **devlist;
112 
113 	/*
114 	 * private data from HCD layer
115 	 */
116 	void *hci_data;
117 };
118 
119 /* intialize the usb_dev subsystem and register callbacks for HCD layer */
120 int usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
121 		usb_dev_sys_cb notify_cb, usb_dev_sys_cb intr_cb,
122 		usb_dev_sys_cb lock_ep_cb,
123 		usb_dev_sys_cb unlock_ep_cb,
124 		void *hci_data, int log_level);
125 void usb_dev_sys_deinit(void);
126 void *usb_dev_init(void *pdata, char *opt);
127 void usb_dev_deinit(void *pdata);
128 int usb_dev_info(void *pdata, int type, void *value, int size);
129 int usb_dev_request(void *pdata, struct usb_xfer *xfer);
130 int usb_dev_reset(void *pdata);
131 int usb_dev_data(void *pdata, struct usb_xfer *xfer, int dir, int epctx);
132 void usb_dev_cancel_request(void *pdata);
133 void usb_dev_free_request(void *pdata);
134 #endif
135