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 void vudc_remove(struct platform_device *pdev); 177 178 #endif /* __USBIP_VUDC_H */ 179