mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
24ceb9c669
Now that the SPDX tag is in all USB files, that identifies the license in a specific and legally-defined manner. So the extra GPL text wording can be removed as it is no longer needed at all. This is done on a quest to remove the 700+ different ways that files in the kernel describe the GPL license text. And there's unneeded stuff like the address (sometimes incorrect) for the FSF which is never needed. No copyright headers or other non-license-description text was removed. Cc: Oliver Neukum <oneukum@suse.com> Cc: Johan Hovold <johan@kernel.org> Cc: Jerry Zhang <zhangjerry@google.com> Cc: John Keeping <john@metanate.com> Cc: Krzysztof Opasiak <k.opasiak@samsung.com> Cc: Abdulhadi Mohamed <abdulahhadi2@gmail.com> Cc: Matthew Wilcox <willy@linux.intel.com> Cc: Janusz Dziedzic <januszx.dziedzic@linux.intel.com> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Vincent Pelletier <plr.vincent@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
304 lines
8.2 KiB
C
304 lines
8.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* u_fs.h
|
|
*
|
|
* Utility definitions for the FunctionFS
|
|
*
|
|
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
|
|
* http://www.samsung.com
|
|
*
|
|
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
|
*/
|
|
|
|
#ifndef U_FFS_H
|
|
#define U_FFS_H
|
|
|
|
#include <linux/usb/composite.h>
|
|
#include <linux/list.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/refcount.h>
|
|
|
|
#ifdef VERBOSE_DEBUG
|
|
#ifndef pr_vdebug
|
|
# define pr_vdebug pr_debug
|
|
#endif /* pr_vdebug */
|
|
# define ffs_dump_mem(prefix, ptr, len) \
|
|
print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
|
|
#else
|
|
#ifndef pr_vdebug
|
|
# define pr_vdebug(...) do { } while (0)
|
|
#endif /* pr_vdebug */
|
|
# define ffs_dump_mem(prefix, ptr, len) do { } while (0)
|
|
#endif /* VERBOSE_DEBUG */
|
|
|
|
#define ENTER() pr_vdebug("%s()\n", __func__)
|
|
|
|
struct f_fs_opts;
|
|
|
|
struct ffs_dev {
|
|
struct ffs_data *ffs_data;
|
|
struct f_fs_opts *opts;
|
|
struct list_head entry;
|
|
|
|
char name[41];
|
|
|
|
bool mounted;
|
|
bool desc_ready;
|
|
bool single;
|
|
|
|
int (*ffs_ready_callback)(struct ffs_data *ffs);
|
|
void (*ffs_closed_callback)(struct ffs_data *ffs);
|
|
void *(*ffs_acquire_dev_callback)(struct ffs_dev *dev);
|
|
void (*ffs_release_dev_callback)(struct ffs_dev *dev);
|
|
};
|
|
|
|
extern struct mutex ffs_lock;
|
|
|
|
static inline void ffs_dev_lock(void)
|
|
{
|
|
mutex_lock(&ffs_lock);
|
|
}
|
|
|
|
static inline void ffs_dev_unlock(void)
|
|
{
|
|
mutex_unlock(&ffs_lock);
|
|
}
|
|
|
|
int ffs_name_dev(struct ffs_dev *dev, const char *name);
|
|
int ffs_single_dev(struct ffs_dev *dev);
|
|
|
|
struct ffs_epfile;
|
|
struct ffs_function;
|
|
|
|
enum ffs_state {
|
|
/*
|
|
* Waiting for descriptors and strings.
|
|
*
|
|
* In this state no open(2), read(2) or write(2) on epfiles
|
|
* may succeed (which should not be the problem as there
|
|
* should be no such files opened in the first place).
|
|
*/
|
|
FFS_READ_DESCRIPTORS,
|
|
FFS_READ_STRINGS,
|
|
|
|
/*
|
|
* We've got descriptors and strings. We are or have called
|
|
* functionfs_ready_callback(). functionfs_bind() may have
|
|
* been called but we don't know.
|
|
*
|
|
* This is the only state in which operations on epfiles may
|
|
* succeed.
|
|
*/
|
|
FFS_ACTIVE,
|
|
|
|
/*
|
|
* Function is visible to host, but it's not functional. All
|
|
* setup requests are stalled and transfers on another endpoints
|
|
* are refused. All epfiles, except ep0, are deleted so there
|
|
* is no way to perform any operations on them.
|
|
*
|
|
* This state is set after closing all functionfs files, when
|
|
* mount parameter "no_disconnect=1" has been set. Function will
|
|
* remain in deactivated state until filesystem is umounted or
|
|
* ep0 is opened again. In the second case functionfs state will
|
|
* be reset, and it will be ready for descriptors and strings
|
|
* writing.
|
|
*
|
|
* This is useful only when functionfs is composed to gadget
|
|
* with another function which can perform some critical
|
|
* operations, and it's strongly desired to have this operations
|
|
* completed, even after functionfs files closure.
|
|
*/
|
|
FFS_DEACTIVATED,
|
|
|
|
/*
|
|
* All endpoints have been closed. This state is also set if
|
|
* we encounter an unrecoverable error. The only
|
|
* unrecoverable error is situation when after reading strings
|
|
* from user space we fail to initialise epfiles or
|
|
* functionfs_ready_callback() returns with error (<0).
|
|
*
|
|
* In this state no open(2), read(2) or write(2) (both on ep0
|
|
* as well as epfile) may succeed (at this point epfiles are
|
|
* unlinked and all closed so this is not a problem; ep0 is
|
|
* also closed but ep0 file exists and so open(2) on ep0 must
|
|
* fail).
|
|
*/
|
|
FFS_CLOSING
|
|
};
|
|
|
|
enum ffs_setup_state {
|
|
/* There is no setup request pending. */
|
|
FFS_NO_SETUP,
|
|
/*
|
|
* User has read events and there was a setup request event
|
|
* there. The next read/write on ep0 will handle the
|
|
* request.
|
|
*/
|
|
FFS_SETUP_PENDING,
|
|
/*
|
|
* There was event pending but before user space handled it
|
|
* some other event was introduced which canceled existing
|
|
* setup. If this state is set read/write on ep0 return
|
|
* -EIDRM. This state is only set when adding event.
|
|
*/
|
|
FFS_SETUP_CANCELLED
|
|
};
|
|
|
|
struct ffs_data {
|
|
struct usb_gadget *gadget;
|
|
|
|
/*
|
|
* Protect access read/write operations, only one read/write
|
|
* at a time. As a consequence protects ep0req and company.
|
|
* While setup request is being processed (queued) this is
|
|
* held.
|
|
*/
|
|
struct mutex mutex;
|
|
|
|
/*
|
|
* Protect access to endpoint related structures (basically
|
|
* usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for
|
|
* endpoint zero.
|
|
*/
|
|
spinlock_t eps_lock;
|
|
|
|
/*
|
|
* XXX REVISIT do we need our own request? Since we are not
|
|
* handling setup requests immediately user space may be so
|
|
* slow that another setup will be sent to the gadget but this
|
|
* time not to us but another function and then there could be
|
|
* a race. Is that the case? Or maybe we can use cdev->req
|
|
* after all, maybe we just need some spinlock for that?
|
|
*/
|
|
struct usb_request *ep0req; /* P: mutex */
|
|
struct completion ep0req_completion; /* P: mutex */
|
|
|
|
/* reference counter */
|
|
refcount_t ref;
|
|
/* how many files are opened (EP0 and others) */
|
|
atomic_t opened;
|
|
|
|
/* EP0 state */
|
|
enum ffs_state state;
|
|
|
|
/*
|
|
* Possible transitions:
|
|
* + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock
|
|
* happens only in ep0 read which is P: mutex
|
|
* + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock
|
|
* happens only in ep0 i/o which is P: mutex
|
|
* + FFS_SETUP_PENDING -> FFS_SETUP_CANCELLED -- P: ev.waitq.lock
|
|
* + FFS_SETUP_CANCELLED -> FFS_NO_SETUP -- cmpxchg
|
|
*
|
|
* This field should never be accessed directly and instead
|
|
* ffs_setup_state_clear_cancelled function should be used.
|
|
*/
|
|
enum ffs_setup_state setup_state;
|
|
|
|
/* Events & such. */
|
|
struct {
|
|
u8 types[4];
|
|
unsigned short count;
|
|
/* XXX REVISIT need to update it in some places, or do we? */
|
|
unsigned short can_stall;
|
|
struct usb_ctrlrequest setup;
|
|
|
|
wait_queue_head_t waitq;
|
|
} ev; /* the whole structure, P: ev.waitq.lock */
|
|
|
|
/* Flags */
|
|
unsigned long flags;
|
|
#define FFS_FL_CALL_CLOSED_CALLBACK 0
|
|
#define FFS_FL_BOUND 1
|
|
|
|
/* For waking up blocked threads when function is enabled. */
|
|
wait_queue_head_t wait;
|
|
|
|
/* Active function */
|
|
struct ffs_function *func;
|
|
|
|
/*
|
|
* Device name, write once when file system is mounted.
|
|
* Intended for user to read if she wants.
|
|
*/
|
|
const char *dev_name;
|
|
/* Private data for our user (ie. gadget). Managed by user. */
|
|
void *private_data;
|
|
|
|
/* filled by __ffs_data_got_descs() */
|
|
/*
|
|
* raw_descs is what you kfree, real_descs points inside of raw_descs,
|
|
* where full speed, high speed and super speed descriptors start.
|
|
* real_descs_length is the length of all those descriptors.
|
|
*/
|
|
const void *raw_descs_data;
|
|
const void *raw_descs;
|
|
unsigned raw_descs_length;
|
|
unsigned fs_descs_count;
|
|
unsigned hs_descs_count;
|
|
unsigned ss_descs_count;
|
|
unsigned ms_os_descs_count;
|
|
unsigned ms_os_descs_ext_prop_count;
|
|
unsigned ms_os_descs_ext_prop_name_len;
|
|
unsigned ms_os_descs_ext_prop_data_len;
|
|
void *ms_os_descs_ext_prop_avail;
|
|
void *ms_os_descs_ext_prop_name_avail;
|
|
void *ms_os_descs_ext_prop_data_avail;
|
|
|
|
unsigned user_flags;
|
|
|
|
#define FFS_MAX_EPS_COUNT 31
|
|
u8 eps_addrmap[FFS_MAX_EPS_COUNT];
|
|
|
|
unsigned short strings_count;
|
|
unsigned short interfaces_count;
|
|
unsigned short eps_count;
|
|
unsigned short _pad1;
|
|
|
|
/* filled by __ffs_data_got_strings() */
|
|
/* ids in stringtabs are set in functionfs_bind() */
|
|
const void *raw_strings;
|
|
struct usb_gadget_strings **stringtabs;
|
|
|
|
/*
|
|
* File system's super block, write once when file system is
|
|
* mounted.
|
|
*/
|
|
struct super_block *sb;
|
|
|
|
/* File permissions, written once when fs is mounted */
|
|
struct ffs_file_perms {
|
|
umode_t mode;
|
|
kuid_t uid;
|
|
kgid_t gid;
|
|
} file_perms;
|
|
|
|
struct eventfd_ctx *ffs_eventfd;
|
|
struct workqueue_struct *io_completion_wq;
|
|
bool no_disconnect;
|
|
struct work_struct reset_work;
|
|
|
|
/*
|
|
* The endpoint files, filled by ffs_epfiles_create(),
|
|
* destroyed by ffs_epfiles_destroy().
|
|
*/
|
|
struct ffs_epfile *epfiles;
|
|
};
|
|
|
|
|
|
struct f_fs_opts {
|
|
struct usb_function_instance func_inst;
|
|
struct ffs_dev *dev;
|
|
unsigned refcnt;
|
|
bool no_configfs;
|
|
};
|
|
|
|
static inline struct f_fs_opts *to_f_fs_opts(struct usb_function_instance *fi)
|
|
{
|
|
return container_of(fi, struct f_fs_opts, func_inst);
|
|
}
|
|
|
|
#endif /* U_FFS_H */
|