1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2015 Karol Kosik <karo9@interia.eu> |
4 | * Copyright (C) 2015-2016 Samsung Electronics |
5 | * Igor Kotrasinski <i.kotrasinsk@samsung.com> |
6 | * Krzysztof Opasiak <k.opasiak@samsung.com> |
7 | */ |
8 | |
9 | #ifndef __USBIP_VUDC_H |
10 | #define __USBIP_VUDC_H |
11 | |
12 | #include <linux/platform_device.h> |
13 | #include <linux/usb.h> |
14 | #include <linux/usb/gadget.h> |
15 | #include <linux/usb/ch9.h> |
16 | #include <linux/list.h> |
17 | #include <linux/timer.h> |
18 | #include <linux/time.h> |
19 | #include <linux/sysfs.h> |
20 | |
21 | #include "usbip_common.h" |
22 | |
23 | #define GADGET_NAME "usbip-vudc" |
24 | |
25 | struct vep { |
26 | struct usb_ep ep; |
27 | unsigned type:2; /* type, as USB_ENDPOINT_XFER_* */ |
28 | char name[8]; /* space for ep name */ |
29 | |
30 | const struct usb_endpoint_descriptor *desc; |
31 | struct usb_gadget *gadget; |
32 | struct list_head req_queue; /* Request queue */ |
33 | unsigned halted:1; |
34 | unsigned wedged:1; |
35 | unsigned already_seen:1; |
36 | unsigned setup_stage:1; |
37 | }; |
38 | |
39 | struct vrequest { |
40 | struct usb_request req; |
41 | struct vudc *udc; |
42 | struct list_head req_entry; /* Request queue */ |
43 | }; |
44 | |
45 | struct urbp { |
46 | struct urb *urb; |
47 | struct vep *ep; |
48 | struct list_head urb_entry; /* urb queue */ |
49 | unsigned long seqnum; |
50 | unsigned type:2; /* for tx, since ep type can change after */ |
51 | unsigned new:1; |
52 | }; |
53 | |
54 | struct v_unlink { |
55 | unsigned long seqnum; |
56 | __u32 status; |
57 | }; |
58 | |
59 | enum tx_type { |
60 | TX_UNLINK, |
61 | TX_SUBMIT, |
62 | }; |
63 | |
64 | struct tx_item { |
65 | struct list_head tx_entry; |
66 | enum tx_type type; |
67 | union { |
68 | struct urbp *s; |
69 | struct v_unlink *u; |
70 | }; |
71 | }; |
72 | |
73 | enum tr_state { |
74 | VUDC_TR_RUNNING, |
75 | VUDC_TR_IDLE, |
76 | VUDC_TR_STOPPED, |
77 | }; |
78 | |
79 | struct transfer_timer { |
80 | struct timer_list timer; |
81 | enum tr_state state; |
82 | unsigned long frame_start; |
83 | int frame_limit; |
84 | }; |
85 | |
86 | struct vudc { |
87 | struct usb_gadget gadget; |
88 | struct usb_gadget_driver *driver; |
89 | struct platform_device *pdev; |
90 | |
91 | struct usb_device_descriptor dev_desc; |
92 | |
93 | struct usbip_device ud; |
94 | struct transfer_timer tr_timer; |
95 | struct timespec64 start_time; |
96 | |
97 | struct list_head urb_queue; |
98 | |
99 | spinlock_t lock_tx; |
100 | struct list_head tx_queue; |
101 | wait_queue_head_t tx_waitq; |
102 | |
103 | spinlock_t lock; |
104 | struct vep *ep; |
105 | int address; |
106 | u16 devstatus; |
107 | |
108 | unsigned pullup:1; |
109 | unsigned connected:1; |
110 | unsigned desc_cached:1; |
111 | }; |
112 | |
113 | struct vudc_device { |
114 | struct platform_device *pdev; |
115 | struct list_head dev_entry; |
116 | }; |
117 | |
118 | extern const struct attribute_group *vudc_groups[]; |
119 | |
120 | /* visible everywhere */ |
121 | |
122 | static inline struct vep *to_vep(struct usb_ep *_ep) |
123 | { |
124 | return container_of(_ep, struct vep, ep); |
125 | } |
126 | |
127 | static inline struct vrequest *to_vrequest( |
128 | struct usb_request *_req) |
129 | { |
130 | return container_of(_req, struct vrequest, req); |
131 | } |
132 | |
133 | static inline struct vudc *usb_gadget_to_vudc( |
134 | struct usb_gadget *_gadget) |
135 | { |
136 | return container_of(_gadget, struct vudc, gadget); |
137 | } |
138 | |
139 | static inline struct vudc *ep_to_vudc(struct vep *ep) |
140 | { |
141 | return container_of(ep->gadget, struct vudc, gadget); |
142 | } |
143 | |
144 | /* vudc_sysfs.c */ |
145 | |
146 | int get_gadget_descs(struct vudc *udc); |
147 | |
148 | /* vudc_tx.c */ |
149 | |
150 | int v_tx_loop(void *data); |
151 | void v_enqueue_ret_unlink(struct vudc *udc, __u32 seqnum, __u32 status); |
152 | void v_enqueue_ret_submit(struct vudc *udc, struct urbp *urb_p); |
153 | |
154 | /* vudc_rx.c */ |
155 | |
156 | int v_rx_loop(void *data); |
157 | |
158 | /* vudc_transfer.c */ |
159 | |
160 | void v_init_timer(struct vudc *udc); |
161 | void v_start_timer(struct vudc *udc); |
162 | void v_kick_timer(struct vudc *udc, unsigned long time); |
163 | void v_stop_timer(struct vudc *udc); |
164 | |
165 | /* vudc_dev.c */ |
166 | |
167 | struct urbp *alloc_urbp(void); |
168 | void free_urbp_and_urb(struct urbp *urb_p); |
169 | |
170 | struct vep *vudc_find_endpoint(struct vudc *udc, u8 address); |
171 | |
172 | struct vudc_device *alloc_vudc_device(int devid); |
173 | void put_vudc_device(struct vudc_device *udc_dev); |
174 | |
175 | int vudc_probe(struct platform_device *pdev); |
176 | int vudc_remove(struct platform_device *pdev); |
177 | |
178 | #endif /* __USBIP_VUDC_H */ |
179 | |