162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * u_fs.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Utility definitions for the FunctionFS 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2013 Samsung Electronics Co., Ltd. 862306a36Sopenharmony_ci * http://www.samsung.com 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#ifndef U_FFS_H 1462306a36Sopenharmony_ci#define U_FFS_H 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/usb/composite.h> 1762306a36Sopenharmony_ci#include <linux/list.h> 1862306a36Sopenharmony_ci#include <linux/mutex.h> 1962306a36Sopenharmony_ci#include <linux/workqueue.h> 2062306a36Sopenharmony_ci#include <linux/refcount.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#ifdef VERBOSE_DEBUG 2362306a36Sopenharmony_ci#ifndef pr_vdebug 2462306a36Sopenharmony_ci# define pr_vdebug pr_debug 2562306a36Sopenharmony_ci#endif /* pr_vdebug */ 2662306a36Sopenharmony_ci# define ffs_dump_mem(prefix, ptr, len) \ 2762306a36Sopenharmony_ci print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) 2862306a36Sopenharmony_ci#else 2962306a36Sopenharmony_ci#ifndef pr_vdebug 3062306a36Sopenharmony_ci# define pr_vdebug(...) do { } while (0) 3162306a36Sopenharmony_ci#endif /* pr_vdebug */ 3262306a36Sopenharmony_ci# define ffs_dump_mem(prefix, ptr, len) do { } while (0) 3362306a36Sopenharmony_ci#endif /* VERBOSE_DEBUG */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistruct f_fs_opts; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistruct ffs_dev { 3862306a36Sopenharmony_ci struct ffs_data *ffs_data; 3962306a36Sopenharmony_ci struct f_fs_opts *opts; 4062306a36Sopenharmony_ci struct list_head entry; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci char name[41]; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci bool mounted; 4562306a36Sopenharmony_ci bool desc_ready; 4662306a36Sopenharmony_ci bool single; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci int (*ffs_ready_callback)(struct ffs_data *ffs); 4962306a36Sopenharmony_ci void (*ffs_closed_callback)(struct ffs_data *ffs); 5062306a36Sopenharmony_ci void *(*ffs_acquire_dev_callback)(struct ffs_dev *dev); 5162306a36Sopenharmony_ci void (*ffs_release_dev_callback)(struct ffs_dev *dev); 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciextern struct mutex ffs_lock; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic inline void ffs_dev_lock(void) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci mutex_lock(&ffs_lock); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic inline void ffs_dev_unlock(void) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci mutex_unlock(&ffs_lock); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ciint ffs_name_dev(struct ffs_dev *dev, const char *name); 6762306a36Sopenharmony_ciint ffs_single_dev(struct ffs_dev *dev); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistruct ffs_epfile; 7062306a36Sopenharmony_cistruct ffs_function; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cienum ffs_state { 7362306a36Sopenharmony_ci /* 7462306a36Sopenharmony_ci * Waiting for descriptors and strings. 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * In this state no open(2), read(2) or write(2) on epfiles 7762306a36Sopenharmony_ci * may succeed (which should not be the problem as there 7862306a36Sopenharmony_ci * should be no such files opened in the first place). 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci FFS_READ_DESCRIPTORS, 8162306a36Sopenharmony_ci FFS_READ_STRINGS, 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci /* 8462306a36Sopenharmony_ci * We've got descriptors and strings. We are or have called 8562306a36Sopenharmony_ci * functionfs_ready_callback(). functionfs_bind() may have 8662306a36Sopenharmony_ci * been called but we don't know. 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * This is the only state in which operations on epfiles may 8962306a36Sopenharmony_ci * succeed. 9062306a36Sopenharmony_ci */ 9162306a36Sopenharmony_ci FFS_ACTIVE, 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /* 9462306a36Sopenharmony_ci * Function is visible to host, but it's not functional. All 9562306a36Sopenharmony_ci * setup requests are stalled and transfers on another endpoints 9662306a36Sopenharmony_ci * are refused. All epfiles, except ep0, are deleted so there 9762306a36Sopenharmony_ci * is no way to perform any operations on them. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * This state is set after closing all functionfs files, when 10062306a36Sopenharmony_ci * mount parameter "no_disconnect=1" has been set. Function will 10162306a36Sopenharmony_ci * remain in deactivated state until filesystem is umounted or 10262306a36Sopenharmony_ci * ep0 is opened again. In the second case functionfs state will 10362306a36Sopenharmony_ci * be reset, and it will be ready for descriptors and strings 10462306a36Sopenharmony_ci * writing. 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * This is useful only when functionfs is composed to gadget 10762306a36Sopenharmony_ci * with another function which can perform some critical 10862306a36Sopenharmony_ci * operations, and it's strongly desired to have this operations 10962306a36Sopenharmony_ci * completed, even after functionfs files closure. 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci FFS_DEACTIVATED, 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /* 11462306a36Sopenharmony_ci * All endpoints have been closed. This state is also set if 11562306a36Sopenharmony_ci * we encounter an unrecoverable error. The only 11662306a36Sopenharmony_ci * unrecoverable error is situation when after reading strings 11762306a36Sopenharmony_ci * from user space we fail to initialise epfiles or 11862306a36Sopenharmony_ci * functionfs_ready_callback() returns with error (<0). 11962306a36Sopenharmony_ci * 12062306a36Sopenharmony_ci * In this state no open(2), read(2) or write(2) (both on ep0 12162306a36Sopenharmony_ci * as well as epfile) may succeed (at this point epfiles are 12262306a36Sopenharmony_ci * unlinked and all closed so this is not a problem; ep0 is 12362306a36Sopenharmony_ci * also closed but ep0 file exists and so open(2) on ep0 must 12462306a36Sopenharmony_ci * fail). 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci FFS_CLOSING 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cienum ffs_setup_state { 13062306a36Sopenharmony_ci /* There is no setup request pending. */ 13162306a36Sopenharmony_ci FFS_NO_SETUP, 13262306a36Sopenharmony_ci /* 13362306a36Sopenharmony_ci * User has read events and there was a setup request event 13462306a36Sopenharmony_ci * there. The next read/write on ep0 will handle the 13562306a36Sopenharmony_ci * request. 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_ci FFS_SETUP_PENDING, 13862306a36Sopenharmony_ci /* 13962306a36Sopenharmony_ci * There was event pending but before user space handled it 14062306a36Sopenharmony_ci * some other event was introduced which canceled existing 14162306a36Sopenharmony_ci * setup. If this state is set read/write on ep0 return 14262306a36Sopenharmony_ci * -EIDRM. This state is only set when adding event. 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ci FFS_SETUP_CANCELLED 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistruct ffs_data { 14862306a36Sopenharmony_ci struct usb_gadget *gadget; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci /* 15162306a36Sopenharmony_ci * Protect access read/write operations, only one read/write 15262306a36Sopenharmony_ci * at a time. As a consequence protects ep0req and company. 15362306a36Sopenharmony_ci * While setup request is being processed (queued) this is 15462306a36Sopenharmony_ci * held. 15562306a36Sopenharmony_ci */ 15662306a36Sopenharmony_ci struct mutex mutex; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* 15962306a36Sopenharmony_ci * Protect access to endpoint related structures (basically 16062306a36Sopenharmony_ci * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for 16162306a36Sopenharmony_ci * endpoint zero. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_ci spinlock_t eps_lock; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci /* 16662306a36Sopenharmony_ci * XXX REVISIT do we need our own request? Since we are not 16762306a36Sopenharmony_ci * handling setup requests immediately user space may be so 16862306a36Sopenharmony_ci * slow that another setup will be sent to the gadget but this 16962306a36Sopenharmony_ci * time not to us but another function and then there could be 17062306a36Sopenharmony_ci * a race. Is that the case? Or maybe we can use cdev->req 17162306a36Sopenharmony_ci * after all, maybe we just need some spinlock for that? 17262306a36Sopenharmony_ci */ 17362306a36Sopenharmony_ci struct usb_request *ep0req; /* P: mutex */ 17462306a36Sopenharmony_ci struct completion ep0req_completion; /* P: mutex */ 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* reference counter */ 17762306a36Sopenharmony_ci refcount_t ref; 17862306a36Sopenharmony_ci /* how many files are opened (EP0 and others) */ 17962306a36Sopenharmony_ci atomic_t opened; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci /* EP0 state */ 18262306a36Sopenharmony_ci enum ffs_state state; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci /* 18562306a36Sopenharmony_ci * Possible transitions: 18662306a36Sopenharmony_ci * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock 18762306a36Sopenharmony_ci * happens only in ep0 read which is P: mutex 18862306a36Sopenharmony_ci * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock 18962306a36Sopenharmony_ci * happens only in ep0 i/o which is P: mutex 19062306a36Sopenharmony_ci * + FFS_SETUP_PENDING -> FFS_SETUP_CANCELLED -- P: ev.waitq.lock 19162306a36Sopenharmony_ci * + FFS_SETUP_CANCELLED -> FFS_NO_SETUP -- cmpxchg 19262306a36Sopenharmony_ci * 19362306a36Sopenharmony_ci * This field should never be accessed directly and instead 19462306a36Sopenharmony_ci * ffs_setup_state_clear_cancelled function should be used. 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_ci enum ffs_setup_state setup_state; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci /* Events & such. */ 19962306a36Sopenharmony_ci struct { 20062306a36Sopenharmony_ci u8 types[4]; 20162306a36Sopenharmony_ci unsigned short count; 20262306a36Sopenharmony_ci /* XXX REVISIT need to update it in some places, or do we? */ 20362306a36Sopenharmony_ci unsigned short can_stall; 20462306a36Sopenharmony_ci struct usb_ctrlrequest setup; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci wait_queue_head_t waitq; 20762306a36Sopenharmony_ci } ev; /* the whole structure, P: ev.waitq.lock */ 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* Flags */ 21062306a36Sopenharmony_ci unsigned long flags; 21162306a36Sopenharmony_ci#define FFS_FL_CALL_CLOSED_CALLBACK 0 21262306a36Sopenharmony_ci#define FFS_FL_BOUND 1 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /* For waking up blocked threads when function is enabled. */ 21562306a36Sopenharmony_ci wait_queue_head_t wait; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* Active function */ 21862306a36Sopenharmony_ci struct ffs_function *func; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci /* 22162306a36Sopenharmony_ci * Device name, write once when file system is mounted. 22262306a36Sopenharmony_ci * Intended for user to read if she wants. 22362306a36Sopenharmony_ci */ 22462306a36Sopenharmony_ci const char *dev_name; 22562306a36Sopenharmony_ci /* Private data for our user (ie. gadget). Managed by user. */ 22662306a36Sopenharmony_ci void *private_data; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci /* filled by __ffs_data_got_descs() */ 22962306a36Sopenharmony_ci /* 23062306a36Sopenharmony_ci * raw_descs is what you kfree, real_descs points inside of raw_descs, 23162306a36Sopenharmony_ci * where full speed, high speed and super speed descriptors start. 23262306a36Sopenharmony_ci * real_descs_length is the length of all those descriptors. 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_ci const void *raw_descs_data; 23562306a36Sopenharmony_ci const void *raw_descs; 23662306a36Sopenharmony_ci unsigned raw_descs_length; 23762306a36Sopenharmony_ci unsigned fs_descs_count; 23862306a36Sopenharmony_ci unsigned hs_descs_count; 23962306a36Sopenharmony_ci unsigned ss_descs_count; 24062306a36Sopenharmony_ci unsigned ms_os_descs_count; 24162306a36Sopenharmony_ci unsigned ms_os_descs_ext_prop_count; 24262306a36Sopenharmony_ci unsigned ms_os_descs_ext_prop_name_len; 24362306a36Sopenharmony_ci unsigned ms_os_descs_ext_prop_data_len; 24462306a36Sopenharmony_ci void *ms_os_descs_ext_prop_avail; 24562306a36Sopenharmony_ci void *ms_os_descs_ext_prop_name_avail; 24662306a36Sopenharmony_ci void *ms_os_descs_ext_prop_data_avail; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci unsigned user_flags; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci#define FFS_MAX_EPS_COUNT 31 25162306a36Sopenharmony_ci u8 eps_addrmap[FFS_MAX_EPS_COUNT]; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci unsigned short strings_count; 25462306a36Sopenharmony_ci unsigned short interfaces_count; 25562306a36Sopenharmony_ci unsigned short eps_count; 25662306a36Sopenharmony_ci unsigned short _pad1; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci /* filled by __ffs_data_got_strings() */ 25962306a36Sopenharmony_ci /* ids in stringtabs are set in functionfs_bind() */ 26062306a36Sopenharmony_ci const void *raw_strings; 26162306a36Sopenharmony_ci struct usb_gadget_strings **stringtabs; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* 26462306a36Sopenharmony_ci * File system's super block, write once when file system is 26562306a36Sopenharmony_ci * mounted. 26662306a36Sopenharmony_ci */ 26762306a36Sopenharmony_ci struct super_block *sb; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* File permissions, written once when fs is mounted */ 27062306a36Sopenharmony_ci struct ffs_file_perms { 27162306a36Sopenharmony_ci umode_t mode; 27262306a36Sopenharmony_ci kuid_t uid; 27362306a36Sopenharmony_ci kgid_t gid; 27462306a36Sopenharmony_ci } file_perms; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci struct eventfd_ctx *ffs_eventfd; 27762306a36Sopenharmony_ci struct workqueue_struct *io_completion_wq; 27862306a36Sopenharmony_ci bool no_disconnect; 27962306a36Sopenharmony_ci struct work_struct reset_work; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci /* 28262306a36Sopenharmony_ci * The endpoint files, filled by ffs_epfiles_create(), 28362306a36Sopenharmony_ci * destroyed by ffs_epfiles_destroy(). 28462306a36Sopenharmony_ci */ 28562306a36Sopenharmony_ci struct ffs_epfile *epfiles; 28662306a36Sopenharmony_ci}; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistruct f_fs_opts { 29062306a36Sopenharmony_ci struct usb_function_instance func_inst; 29162306a36Sopenharmony_ci struct ffs_dev *dev; 29262306a36Sopenharmony_ci unsigned refcnt; 29362306a36Sopenharmony_ci bool no_configfs; 29462306a36Sopenharmony_ci}; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic inline struct f_fs_opts *to_f_fs_opts(struct usb_function_instance *fi) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci return container_of(fi, struct f_fs_opts, func_inst); 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci#endif /* U_FFS_H */ 302