2017-11-03 11:28:30 +01:00
// SPDX-License-Identifier: GPL-2.0+
2016-03-08 21:48:56 +01:00
/*
* Copyright ( C ) 2015 Karol Kosik < karo9 @ interia . eu >
* Copyright ( C ) 2015 - 2016 Samsung Electronics
* Igor Kotrasinski < i . kotrasinsk @ samsung . com >
* Krzysztof Opasiak < k . opasiak @ samsung . com >
*/
# ifndef __USBIP_VUDC_H
# define __USBIP_VUDC_H
# include <linux/platform_device.h>
# include <linux/usb.h>
# include <linux/usb/gadget.h>
# include <linux/usb/ch9.h>
# include <linux/list.h>
# include <linux/timer.h>
# include <linux/time.h>
# include <linux/sysfs.h>
# include "usbip_common.h"
# define GADGET_NAME "usbip-vudc"
struct vep {
struct usb_ep ep ;
unsigned type : 2 ; /* type, as USB_ENDPOINT_XFER_* */
char name [ 8 ] ; /* space for ep name */
const struct usb_endpoint_descriptor * desc ;
struct usb_gadget * gadget ;
struct list_head req_queue ; /* Request queue */
unsigned halted : 1 ;
unsigned wedged : 1 ;
unsigned already_seen : 1 ;
unsigned setup_stage : 1 ;
} ;
struct vrequest {
struct usb_request req ;
struct vudc * udc ;
struct list_head req_entry ; /* Request queue */
} ;
struct urbp {
struct urb * urb ;
struct vep * ep ;
struct list_head urb_entry ; /* urb queue */
unsigned long seqnum ;
unsigned type : 2 ; /* for tx, since ep type can change after */
unsigned new : 1 ;
} ;
struct v_unlink {
unsigned long seqnum ;
__u32 status ;
} ;
enum tx_type {
TX_UNLINK ,
TX_SUBMIT ,
} ;
struct tx_item {
struct list_head tx_entry ;
enum tx_type type ;
union {
struct urbp * s ;
struct v_unlink * u ;
} ;
} ;
enum tr_state {
VUDC_TR_RUNNING ,
VUDC_TR_IDLE ,
VUDC_TR_STOPPED ,
} ;
struct transfer_timer {
struct timer_list timer ;
enum tr_state state ;
unsigned long frame_start ;
int frame_limit ;
} ;
struct vudc {
struct usb_gadget gadget ;
struct usb_gadget_driver * driver ;
struct platform_device * pdev ;
struct usb_device_descriptor dev_desc ;
struct usbip_device ud ;
struct transfer_timer tr_timer ;
2017-11-07 11:39:57 +01:00
struct timespec64 start_time ;
2016-03-08 21:48:56 +01:00
struct list_head urb_queue ;
spinlock_t lock_tx ;
struct list_head tx_queue ;
wait_queue_head_t tx_waitq ;
spinlock_t lock ;
struct vep * ep ;
int address ;
u16 devstatus ;
unsigned pullup : 1 ;
unsigned connected : 1 ;
unsigned desc_cached : 1 ;
} ;
struct vudc_device {
struct platform_device * pdev ;
struct list_head dev_entry ;
} ;
2019-08-05 21:36:35 +02:00
extern const struct attribute_group * vudc_groups [ ] ;
2016-03-08 21:48:56 +01:00
/* visible everywhere */
static inline struct vep * to_vep ( struct usb_ep * _ep )
{
return container_of ( _ep , struct vep , ep ) ;
}
static inline struct vrequest * to_vrequest (
struct usb_request * _req )
{
return container_of ( _req , struct vrequest , req ) ;
}
static inline struct vudc * usb_gadget_to_vudc (
struct usb_gadget * _gadget )
{
return container_of ( _gadget , struct vudc , gadget ) ;
}
static inline struct vudc * ep_to_vudc ( struct vep * ep )
{
return container_of ( ep - > gadget , struct vudc , gadget ) ;
}
/* vudc_sysfs.c */
int get_gadget_descs ( struct vudc * udc ) ;
/* vudc_tx.c */
int v_tx_loop ( void * data ) ;
void v_enqueue_ret_unlink ( struct vudc * udc , __u32 seqnum , __u32 status ) ;
void v_enqueue_ret_submit ( struct vudc * udc , struct urbp * urb_p ) ;
/* vudc_rx.c */
int v_rx_loop ( void * data ) ;
/* vudc_transfer.c */
void v_init_timer ( struct vudc * udc ) ;
void v_start_timer ( struct vudc * udc ) ;
void v_kick_timer ( struct vudc * udc , unsigned long time ) ;
void v_stop_timer ( struct vudc * udc ) ;
/* vudc_dev.c */
struct urbp * alloc_urbp ( void ) ;
void free_urbp_and_urb ( struct urbp * urb_p ) ;
2016-04-27 20:02:07 +02:00
struct vep * vudc_find_endpoint ( struct vudc * udc , u8 address ) ;
2016-03-08 21:48:56 +01:00
struct vudc_device * alloc_vudc_device ( int devid ) ;
void put_vudc_device ( struct vudc_device * udc_dev ) ;
int vudc_probe ( struct platform_device * pdev ) ;
int vudc_remove ( struct platform_device * pdev ) ;
# endif /* __USBIP_VUDC_H */