1*2e759738SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0 */
200a2430fSAndrzej Pietrasiewicz /*
300a2430fSAndrzej Pietrasiewicz * u_fs.h
400a2430fSAndrzej Pietrasiewicz *
500a2430fSAndrzej Pietrasiewicz * Utility definitions for the FunctionFS
600a2430fSAndrzej Pietrasiewicz *
700a2430fSAndrzej Pietrasiewicz * Copyright (c) 2013 Samsung Electronics Co., Ltd.
800a2430fSAndrzej Pietrasiewicz * http://www.samsung.com
900a2430fSAndrzej Pietrasiewicz *
101b4a3b51SAndrzej Pietrasiewicz * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
1100a2430fSAndrzej Pietrasiewicz */
1200a2430fSAndrzej Pietrasiewicz
1300a2430fSAndrzej Pietrasiewicz #ifndef U_FFS_H
1400a2430fSAndrzej Pietrasiewicz #define U_FFS_H
1500a2430fSAndrzej Pietrasiewicz
1600a2430fSAndrzej Pietrasiewicz #include <linux/usb/composite.h>
1700a2430fSAndrzej Pietrasiewicz #include <linux/list.h>
1800a2430fSAndrzej Pietrasiewicz #include <linux/mutex.h>
1918d6b32fSRobert Baldyga #include <linux/workqueue.h>
2043938613SElena Reshetova #include <linux/refcount.h>
2100a2430fSAndrzej Pietrasiewicz
2200a2430fSAndrzej Pietrasiewicz #ifdef VERBOSE_DEBUG
2300a2430fSAndrzej Pietrasiewicz #ifndef pr_vdebug
2400a2430fSAndrzej Pietrasiewicz # define pr_vdebug pr_debug
2500a2430fSAndrzej Pietrasiewicz #endif /* pr_vdebug */
2600a2430fSAndrzej Pietrasiewicz # define ffs_dump_mem(prefix, ptr, len) \
2700a2430fSAndrzej Pietrasiewicz print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
2800a2430fSAndrzej Pietrasiewicz #else
2900a2430fSAndrzej Pietrasiewicz #ifndef pr_vdebug
3000a2430fSAndrzej Pietrasiewicz # define pr_vdebug(...) do { } while (0)
3100a2430fSAndrzej Pietrasiewicz #endif /* pr_vdebug */
3200a2430fSAndrzej Pietrasiewicz # define ffs_dump_mem(prefix, ptr, len) do { } while (0)
3300a2430fSAndrzej Pietrasiewicz #endif /* VERBOSE_DEBUG */
3400a2430fSAndrzej Pietrasiewicz
3500a2430fSAndrzej Pietrasiewicz struct f_fs_opts;
3600a2430fSAndrzej Pietrasiewicz
3700a2430fSAndrzej Pietrasiewicz struct ffs_dev {
3800a2430fSAndrzej Pietrasiewicz struct ffs_data *ffs_data;
3900a2430fSAndrzej Pietrasiewicz struct f_fs_opts *opts;
4000a2430fSAndrzej Pietrasiewicz struct list_head entry;
4100a2430fSAndrzej Pietrasiewicz
42ea920bb4SMichal Nazarewicz char name[41];
43ea920bb4SMichal Nazarewicz
44ea920bb4SMichal Nazarewicz bool mounted;
45ea920bb4SMichal Nazarewicz bool desc_ready;
46ea920bb4SMichal Nazarewicz bool single;
47ea920bb4SMichal Nazarewicz
4800a2430fSAndrzej Pietrasiewicz int (*ffs_ready_callback)(struct ffs_data *ffs);
4900a2430fSAndrzej Pietrasiewicz void (*ffs_closed_callback)(struct ffs_data *ffs);
5000a2430fSAndrzej Pietrasiewicz void *(*ffs_acquire_dev_callback)(struct ffs_dev *dev);
5100a2430fSAndrzej Pietrasiewicz void (*ffs_release_dev_callback)(struct ffs_dev *dev);
5200a2430fSAndrzej Pietrasiewicz };
5300a2430fSAndrzej Pietrasiewicz
5400a2430fSAndrzej Pietrasiewicz extern struct mutex ffs_lock;
5500a2430fSAndrzej Pietrasiewicz
ffs_dev_lock(void)5600a2430fSAndrzej Pietrasiewicz static inline void ffs_dev_lock(void)
5700a2430fSAndrzej Pietrasiewicz {
5800a2430fSAndrzej Pietrasiewicz mutex_lock(&ffs_lock);
5900a2430fSAndrzej Pietrasiewicz }
6000a2430fSAndrzej Pietrasiewicz
ffs_dev_unlock(void)6100a2430fSAndrzej Pietrasiewicz static inline void ffs_dev_unlock(void)
6200a2430fSAndrzej Pietrasiewicz {
6300a2430fSAndrzej Pietrasiewicz mutex_unlock(&ffs_lock);
6400a2430fSAndrzej Pietrasiewicz }
6500a2430fSAndrzej Pietrasiewicz
6600a2430fSAndrzej Pietrasiewicz int ffs_name_dev(struct ffs_dev *dev, const char *name);
6700a2430fSAndrzej Pietrasiewicz int ffs_single_dev(struct ffs_dev *dev);
6800a2430fSAndrzej Pietrasiewicz
6900a2430fSAndrzej Pietrasiewicz struct ffs_epfile;
7000a2430fSAndrzej Pietrasiewicz struct ffs_function;
7100a2430fSAndrzej Pietrasiewicz
7200a2430fSAndrzej Pietrasiewicz enum ffs_state {
7300a2430fSAndrzej Pietrasiewicz /*
7400a2430fSAndrzej Pietrasiewicz * Waiting for descriptors and strings.
7500a2430fSAndrzej Pietrasiewicz *
7600a2430fSAndrzej Pietrasiewicz * In this state no open(2), read(2) or write(2) on epfiles
7700a2430fSAndrzej Pietrasiewicz * may succeed (which should not be the problem as there
7800a2430fSAndrzej Pietrasiewicz * should be no such files opened in the first place).
7900a2430fSAndrzej Pietrasiewicz */
8000a2430fSAndrzej Pietrasiewicz FFS_READ_DESCRIPTORS,
8100a2430fSAndrzej Pietrasiewicz FFS_READ_STRINGS,
8200a2430fSAndrzej Pietrasiewicz
8300a2430fSAndrzej Pietrasiewicz /*
8400a2430fSAndrzej Pietrasiewicz * We've got descriptors and strings. We are or have called
8500a2430fSAndrzej Pietrasiewicz * functionfs_ready_callback(). functionfs_bind() may have
8600a2430fSAndrzej Pietrasiewicz * been called but we don't know.
8700a2430fSAndrzej Pietrasiewicz *
8800a2430fSAndrzej Pietrasiewicz * This is the only state in which operations on epfiles may
8900a2430fSAndrzej Pietrasiewicz * succeed.
9000a2430fSAndrzej Pietrasiewicz */
9100a2430fSAndrzej Pietrasiewicz FFS_ACTIVE,
9200a2430fSAndrzej Pietrasiewicz
9300a2430fSAndrzej Pietrasiewicz /*
9418d6b32fSRobert Baldyga * Function is visible to host, but it's not functional. All
9518d6b32fSRobert Baldyga * setup requests are stalled and transfers on another endpoints
9618d6b32fSRobert Baldyga * are refused. All epfiles, except ep0, are deleted so there
9718d6b32fSRobert Baldyga * is no way to perform any operations on them.
9818d6b32fSRobert Baldyga *
9918d6b32fSRobert Baldyga * This state is set after closing all functionfs files, when
10018d6b32fSRobert Baldyga * mount parameter "no_disconnect=1" has been set. Function will
10118d6b32fSRobert Baldyga * remain in deactivated state until filesystem is umounted or
10218d6b32fSRobert Baldyga * ep0 is opened again. In the second case functionfs state will
10318d6b32fSRobert Baldyga * be reset, and it will be ready for descriptors and strings
10418d6b32fSRobert Baldyga * writing.
10518d6b32fSRobert Baldyga *
10618d6b32fSRobert Baldyga * This is useful only when functionfs is composed to gadget
10718d6b32fSRobert Baldyga * with another function which can perform some critical
10818d6b32fSRobert Baldyga * operations, and it's strongly desired to have this operations
10918d6b32fSRobert Baldyga * completed, even after functionfs files closure.
11018d6b32fSRobert Baldyga */
11118d6b32fSRobert Baldyga FFS_DEACTIVATED,
11218d6b32fSRobert Baldyga
11318d6b32fSRobert Baldyga /*
11400a2430fSAndrzej Pietrasiewicz * All endpoints have been closed. This state is also set if
11500a2430fSAndrzej Pietrasiewicz * we encounter an unrecoverable error. The only
11600a2430fSAndrzej Pietrasiewicz * unrecoverable error is situation when after reading strings
11700a2430fSAndrzej Pietrasiewicz * from user space we fail to initialise epfiles or
11800a2430fSAndrzej Pietrasiewicz * functionfs_ready_callback() returns with error (<0).
11900a2430fSAndrzej Pietrasiewicz *
12000a2430fSAndrzej Pietrasiewicz * In this state no open(2), read(2) or write(2) (both on ep0
12100a2430fSAndrzej Pietrasiewicz * as well as epfile) may succeed (at this point epfiles are
12200a2430fSAndrzej Pietrasiewicz * unlinked and all closed so this is not a problem; ep0 is
12300a2430fSAndrzej Pietrasiewicz * also closed but ep0 file exists and so open(2) on ep0 must
12400a2430fSAndrzej Pietrasiewicz * fail).
12500a2430fSAndrzej Pietrasiewicz */
12600a2430fSAndrzej Pietrasiewicz FFS_CLOSING
12700a2430fSAndrzej Pietrasiewicz };
12800a2430fSAndrzej Pietrasiewicz
12900a2430fSAndrzej Pietrasiewicz enum ffs_setup_state {
13000a2430fSAndrzej Pietrasiewicz /* There is no setup request pending. */
13100a2430fSAndrzej Pietrasiewicz FFS_NO_SETUP,
13200a2430fSAndrzej Pietrasiewicz /*
13300a2430fSAndrzej Pietrasiewicz * User has read events and there was a setup request event
13400a2430fSAndrzej Pietrasiewicz * there. The next read/write on ep0 will handle the
13500a2430fSAndrzej Pietrasiewicz * request.
13600a2430fSAndrzej Pietrasiewicz */
13700a2430fSAndrzej Pietrasiewicz FFS_SETUP_PENDING,
13800a2430fSAndrzej Pietrasiewicz /*
13900a2430fSAndrzej Pietrasiewicz * There was event pending but before user space handled it
14000a2430fSAndrzej Pietrasiewicz * some other event was introduced which canceled existing
14100a2430fSAndrzej Pietrasiewicz * setup. If this state is set read/write on ep0 return
14200a2430fSAndrzej Pietrasiewicz * -EIDRM. This state is only set when adding event.
14300a2430fSAndrzej Pietrasiewicz */
14400a2430fSAndrzej Pietrasiewicz FFS_SETUP_CANCELLED
14500a2430fSAndrzej Pietrasiewicz };
14600a2430fSAndrzej Pietrasiewicz
14700a2430fSAndrzej Pietrasiewicz struct ffs_data {
14800a2430fSAndrzej Pietrasiewicz struct usb_gadget *gadget;
14900a2430fSAndrzej Pietrasiewicz
15000a2430fSAndrzej Pietrasiewicz /*
15100a2430fSAndrzej Pietrasiewicz * Protect access read/write operations, only one read/write
15200a2430fSAndrzej Pietrasiewicz * at a time. As a consequence protects ep0req and company.
15300a2430fSAndrzej Pietrasiewicz * While setup request is being processed (queued) this is
15400a2430fSAndrzej Pietrasiewicz * held.
15500a2430fSAndrzej Pietrasiewicz */
15600a2430fSAndrzej Pietrasiewicz struct mutex mutex;
15700a2430fSAndrzej Pietrasiewicz
15800a2430fSAndrzej Pietrasiewicz /*
15900a2430fSAndrzej Pietrasiewicz * Protect access to endpoint related structures (basically
16000a2430fSAndrzej Pietrasiewicz * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for
16100a2430fSAndrzej Pietrasiewicz * endpoint zero.
16200a2430fSAndrzej Pietrasiewicz */
16300a2430fSAndrzej Pietrasiewicz spinlock_t eps_lock;
16400a2430fSAndrzej Pietrasiewicz
16500a2430fSAndrzej Pietrasiewicz /*
16600a2430fSAndrzej Pietrasiewicz * XXX REVISIT do we need our own request? Since we are not
16700a2430fSAndrzej Pietrasiewicz * handling setup requests immediately user space may be so
16800a2430fSAndrzej Pietrasiewicz * slow that another setup will be sent to the gadget but this
16900a2430fSAndrzej Pietrasiewicz * time not to us but another function and then there could be
17000a2430fSAndrzej Pietrasiewicz * a race. Is that the case? Or maybe we can use cdev->req
17100a2430fSAndrzej Pietrasiewicz * after all, maybe we just need some spinlock for that?
17200a2430fSAndrzej Pietrasiewicz */
17300a2430fSAndrzej Pietrasiewicz struct usb_request *ep0req; /* P: mutex */
17400a2430fSAndrzej Pietrasiewicz struct completion ep0req_completion; /* P: mutex */
17500a2430fSAndrzej Pietrasiewicz
17600a2430fSAndrzej Pietrasiewicz /* reference counter */
17743938613SElena Reshetova refcount_t ref;
17800a2430fSAndrzej Pietrasiewicz /* how many files are opened (EP0 and others) */
17900a2430fSAndrzej Pietrasiewicz atomic_t opened;
18000a2430fSAndrzej Pietrasiewicz
18100a2430fSAndrzej Pietrasiewicz /* EP0 state */
18200a2430fSAndrzej Pietrasiewicz enum ffs_state state;
18300a2430fSAndrzej Pietrasiewicz
18400a2430fSAndrzej Pietrasiewicz /*
18500a2430fSAndrzej Pietrasiewicz * Possible transitions:
18600a2430fSAndrzej Pietrasiewicz * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock
18700a2430fSAndrzej Pietrasiewicz * happens only in ep0 read which is P: mutex
18800a2430fSAndrzej Pietrasiewicz * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock
18900a2430fSAndrzej Pietrasiewicz * happens only in ep0 i/o which is P: mutex
19000a2430fSAndrzej Pietrasiewicz * + FFS_SETUP_PENDING -> FFS_SETUP_CANCELLED -- P: ev.waitq.lock
19100a2430fSAndrzej Pietrasiewicz * + FFS_SETUP_CANCELLED -> FFS_NO_SETUP -- cmpxchg
19200a2430fSAndrzej Pietrasiewicz *
19300a2430fSAndrzej Pietrasiewicz * This field should never be accessed directly and instead
19400a2430fSAndrzej Pietrasiewicz * ffs_setup_state_clear_cancelled function should be used.
19500a2430fSAndrzej Pietrasiewicz */
19600a2430fSAndrzej Pietrasiewicz enum ffs_setup_state setup_state;
19700a2430fSAndrzej Pietrasiewicz
19800a2430fSAndrzej Pietrasiewicz /* Events & such. */
19900a2430fSAndrzej Pietrasiewicz struct {
20000a2430fSAndrzej Pietrasiewicz u8 types[4];
20100a2430fSAndrzej Pietrasiewicz unsigned short count;
20200a2430fSAndrzej Pietrasiewicz /* XXX REVISIT need to update it in some places, or do we? */
20300a2430fSAndrzej Pietrasiewicz unsigned short can_stall;
20400a2430fSAndrzej Pietrasiewicz struct usb_ctrlrequest setup;
20500a2430fSAndrzej Pietrasiewicz
20600a2430fSAndrzej Pietrasiewicz wait_queue_head_t waitq;
20700a2430fSAndrzej Pietrasiewicz } ev; /* the whole structure, P: ev.waitq.lock */
20800a2430fSAndrzej Pietrasiewicz
20900a2430fSAndrzej Pietrasiewicz /* Flags */
21000a2430fSAndrzej Pietrasiewicz unsigned long flags;
21100a2430fSAndrzej Pietrasiewicz #define FFS_FL_CALL_CLOSED_CALLBACK 0
21200a2430fSAndrzej Pietrasiewicz #define FFS_FL_BOUND 1
21300a2430fSAndrzej Pietrasiewicz
214e16828cfSJerry Zhang /* For waking up blocked threads when function is enabled. */
215e16828cfSJerry Zhang wait_queue_head_t wait;
216e16828cfSJerry Zhang
21700a2430fSAndrzej Pietrasiewicz /* Active function */
21800a2430fSAndrzej Pietrasiewicz struct ffs_function *func;
21900a2430fSAndrzej Pietrasiewicz
22000a2430fSAndrzej Pietrasiewicz /*
22100a2430fSAndrzej Pietrasiewicz * Device name, write once when file system is mounted.
22200a2430fSAndrzej Pietrasiewicz * Intended for user to read if she wants.
22300a2430fSAndrzej Pietrasiewicz */
22400a2430fSAndrzej Pietrasiewicz const char *dev_name;
22500a2430fSAndrzej Pietrasiewicz /* Private data for our user (ie. gadget). Managed by user. */
22600a2430fSAndrzej Pietrasiewicz void *private_data;
22700a2430fSAndrzej Pietrasiewicz
22800a2430fSAndrzej Pietrasiewicz /* filled by __ffs_data_got_descs() */
22900a2430fSAndrzej Pietrasiewicz /*
23000a2430fSAndrzej Pietrasiewicz * raw_descs is what you kfree, real_descs points inside of raw_descs,
23100a2430fSAndrzej Pietrasiewicz * where full speed, high speed and super speed descriptors start.
23200a2430fSAndrzej Pietrasiewicz * real_descs_length is the length of all those descriptors.
23300a2430fSAndrzej Pietrasiewicz */
23400a2430fSAndrzej Pietrasiewicz const void *raw_descs_data;
23500a2430fSAndrzej Pietrasiewicz const void *raw_descs;
23600a2430fSAndrzej Pietrasiewicz unsigned raw_descs_length;
23700a2430fSAndrzej Pietrasiewicz unsigned fs_descs_count;
23800a2430fSAndrzej Pietrasiewicz unsigned hs_descs_count;
23900a2430fSAndrzej Pietrasiewicz unsigned ss_descs_count;
24000a2430fSAndrzej Pietrasiewicz unsigned ms_os_descs_count;
24100a2430fSAndrzej Pietrasiewicz unsigned ms_os_descs_ext_prop_count;
24200a2430fSAndrzej Pietrasiewicz unsigned ms_os_descs_ext_prop_name_len;
24300a2430fSAndrzej Pietrasiewicz unsigned ms_os_descs_ext_prop_data_len;
24400a2430fSAndrzej Pietrasiewicz void *ms_os_descs_ext_prop_avail;
24500a2430fSAndrzej Pietrasiewicz void *ms_os_descs_ext_prop_name_avail;
24600a2430fSAndrzej Pietrasiewicz void *ms_os_descs_ext_prop_data_avail;
24700a2430fSAndrzej Pietrasiewicz
2481b0bf88fSRobert Baldyga unsigned user_flags;
2491b0bf88fSRobert Baldyga
25041dc9ac1SVincent Pelletier #define FFS_MAX_EPS_COUNT 31
25141dc9ac1SVincent Pelletier u8 eps_addrmap[FFS_MAX_EPS_COUNT];
2526d5c1c77SRobert Baldyga
25300a2430fSAndrzej Pietrasiewicz unsigned short strings_count;
25400a2430fSAndrzej Pietrasiewicz unsigned short interfaces_count;
25500a2430fSAndrzej Pietrasiewicz unsigned short eps_count;
25600a2430fSAndrzej Pietrasiewicz unsigned short _pad1;
25700a2430fSAndrzej Pietrasiewicz
25800a2430fSAndrzej Pietrasiewicz /* filled by __ffs_data_got_strings() */
25900a2430fSAndrzej Pietrasiewicz /* ids in stringtabs are set in functionfs_bind() */
26000a2430fSAndrzej Pietrasiewicz const void *raw_strings;
26100a2430fSAndrzej Pietrasiewicz struct usb_gadget_strings **stringtabs;
26200a2430fSAndrzej Pietrasiewicz
26300a2430fSAndrzej Pietrasiewicz /*
26400a2430fSAndrzej Pietrasiewicz * File system's super block, write once when file system is
26500a2430fSAndrzej Pietrasiewicz * mounted.
26600a2430fSAndrzej Pietrasiewicz */
26700a2430fSAndrzej Pietrasiewicz struct super_block *sb;
26800a2430fSAndrzej Pietrasiewicz
26900a2430fSAndrzej Pietrasiewicz /* File permissions, written once when fs is mounted */
27000a2430fSAndrzej Pietrasiewicz struct ffs_file_perms {
27100a2430fSAndrzej Pietrasiewicz umode_t mode;
27200a2430fSAndrzej Pietrasiewicz kuid_t uid;
27300a2430fSAndrzej Pietrasiewicz kgid_t gid;
27400a2430fSAndrzej Pietrasiewicz } file_perms;
27500a2430fSAndrzej Pietrasiewicz
2765e33f6fdSRobert Baldyga struct eventfd_ctx *ffs_eventfd;
277addfc582SJohn Keeping struct workqueue_struct *io_completion_wq;
27818d6b32fSRobert Baldyga bool no_disconnect;
27918d6b32fSRobert Baldyga struct work_struct reset_work;
28018d6b32fSRobert Baldyga
28100a2430fSAndrzej Pietrasiewicz /*
28200a2430fSAndrzej Pietrasiewicz * The endpoint files, filled by ffs_epfiles_create(),
28300a2430fSAndrzej Pietrasiewicz * destroyed by ffs_epfiles_destroy().
28400a2430fSAndrzej Pietrasiewicz */
28500a2430fSAndrzej Pietrasiewicz struct ffs_epfile *epfiles;
28600a2430fSAndrzej Pietrasiewicz };
28700a2430fSAndrzej Pietrasiewicz
28800a2430fSAndrzej Pietrasiewicz
28900a2430fSAndrzej Pietrasiewicz struct f_fs_opts {
29000a2430fSAndrzej Pietrasiewicz struct usb_function_instance func_inst;
29100a2430fSAndrzej Pietrasiewicz struct ffs_dev *dev;
29200a2430fSAndrzej Pietrasiewicz unsigned refcnt;
29300a2430fSAndrzej Pietrasiewicz bool no_configfs;
29400a2430fSAndrzej Pietrasiewicz };
29500a2430fSAndrzej Pietrasiewicz
to_f_fs_opts(struct usb_function_instance * fi)29600a2430fSAndrzej Pietrasiewicz static inline struct f_fs_opts *to_f_fs_opts(struct usb_function_instance *fi)
29700a2430fSAndrzej Pietrasiewicz {
29800a2430fSAndrzej Pietrasiewicz return container_of(fi, struct f_fs_opts, func_inst);
29900a2430fSAndrzej Pietrasiewicz }
30000a2430fSAndrzej Pietrasiewicz
30100a2430fSAndrzej Pietrasiewicz #endif /* U_FFS_H */
302