162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef USB_STORAGE_COMMON_H 362306a36Sopenharmony_ci#define USB_STORAGE_COMMON_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/device.h> 662306a36Sopenharmony_ci#include <linux/usb/storage.h> 762306a36Sopenharmony_ci#include <scsi/scsi.h> 862306a36Sopenharmony_ci#include <asm/unaligned.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef DEBUG 1162306a36Sopenharmony_ci#undef VERBOSE_DEBUG 1262306a36Sopenharmony_ci#undef DUMP_MSGS 1362306a36Sopenharmony_ci#endif /* !DEBUG */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#ifdef VERBOSE_DEBUG 1662306a36Sopenharmony_ci#define VLDBG LDBG 1762306a36Sopenharmony_ci#else 1862306a36Sopenharmony_ci#define VLDBG(lun, fmt, args...) do { } while (0) 1962306a36Sopenharmony_ci#endif /* VERBOSE_DEBUG */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define _LMSG(func, lun, fmt, args...) \ 2262306a36Sopenharmony_ci do { \ 2362306a36Sopenharmony_ci if ((lun)->name_pfx && *(lun)->name_pfx) \ 2462306a36Sopenharmony_ci func("%s/%s: " fmt, *(lun)->name_pfx, \ 2562306a36Sopenharmony_ci (lun)->name, ## args); \ 2662306a36Sopenharmony_ci else \ 2762306a36Sopenharmony_ci func("%s: " fmt, (lun)->name, ## args); \ 2862306a36Sopenharmony_ci } while (0) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define LDBG(lun, fmt, args...) _LMSG(pr_debug, lun, fmt, ## args) 3162306a36Sopenharmony_ci#define LERROR(lun, fmt, args...) _LMSG(pr_err, lun, fmt, ## args) 3262306a36Sopenharmony_ci#define LWARN(lun, fmt, args...) _LMSG(pr_warn, lun, fmt, ## args) 3362306a36Sopenharmony_ci#define LINFO(lun, fmt, args...) _LMSG(pr_info, lun, fmt, ## args) 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#ifdef DUMP_MSGS 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci# define dump_msg(fsg, /* const char * */ label, \ 3962306a36Sopenharmony_ci /* const u8 * */ buf, /* unsigned */ length) \ 4062306a36Sopenharmony_cido { \ 4162306a36Sopenharmony_ci if (length < 512) { \ 4262306a36Sopenharmony_ci DBG(fsg, "%s, length %u:\n", label, length); \ 4362306a36Sopenharmony_ci print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \ 4462306a36Sopenharmony_ci 16, 1, buf, length, 0); \ 4562306a36Sopenharmony_ci } \ 4662306a36Sopenharmony_ci} while (0) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci# define dump_cdb(fsg) do { } while (0) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#else 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci# define dump_msg(fsg, /* const char * */ label, \ 5362306a36Sopenharmony_ci /* const u8 * */ buf, /* unsigned */ length) do { } while (0) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci# ifdef VERBOSE_DEBUG 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci# define dump_cdb(fsg) \ 5862306a36Sopenharmony_ci print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, \ 5962306a36Sopenharmony_ci 16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0) \ 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci# else 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci# define dump_cdb(fsg) do { } while (0) 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci# endif /* VERBOSE_DEBUG */ 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci#endif /* DUMP_MSGS */ 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* Length of a SCSI Command Data Block */ 7062306a36Sopenharmony_ci#define MAX_COMMAND_SIZE 16 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ 7362306a36Sopenharmony_ci#define SS_NO_SENSE 0 7462306a36Sopenharmony_ci#define SS_COMMUNICATION_FAILURE 0x040800 7562306a36Sopenharmony_ci#define SS_INVALID_COMMAND 0x052000 7662306a36Sopenharmony_ci#define SS_INVALID_FIELD_IN_CDB 0x052400 7762306a36Sopenharmony_ci#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 7862306a36Sopenharmony_ci#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 7962306a36Sopenharmony_ci#define SS_MEDIUM_NOT_PRESENT 0x023a00 8062306a36Sopenharmony_ci#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 8162306a36Sopenharmony_ci#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 8262306a36Sopenharmony_ci#define SS_RESET_OCCURRED 0x062900 8362306a36Sopenharmony_ci#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 8462306a36Sopenharmony_ci#define SS_UNRECOVERED_READ_ERROR 0x031100 8562306a36Sopenharmony_ci#define SS_WRITE_ERROR 0x030c02 8662306a36Sopenharmony_ci#define SS_WRITE_PROTECTED 0x072700 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ 8962306a36Sopenharmony_ci#define ASC(x) ((u8) ((x) >> 8)) 9062306a36Sopenharmony_ci#define ASCQ(x) ((u8) (x)) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* 9362306a36Sopenharmony_ci * Vendor (8 chars), product (16 chars), release (4 hexadecimal digits) and NUL 9462306a36Sopenharmony_ci * byte 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ci#define INQUIRY_STRING_LEN ((size_t) (8 + 16 + 4 + 1)) 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistruct fsg_lun { 9962306a36Sopenharmony_ci struct file *filp; 10062306a36Sopenharmony_ci loff_t file_length; 10162306a36Sopenharmony_ci loff_t num_sectors; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci unsigned int initially_ro:1; 10462306a36Sopenharmony_ci unsigned int ro:1; 10562306a36Sopenharmony_ci unsigned int removable:1; 10662306a36Sopenharmony_ci unsigned int cdrom:1; 10762306a36Sopenharmony_ci unsigned int prevent_medium_removal:1; 10862306a36Sopenharmony_ci unsigned int registered:1; 10962306a36Sopenharmony_ci unsigned int info_valid:1; 11062306a36Sopenharmony_ci unsigned int nofua:1; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci u32 sense_data; 11362306a36Sopenharmony_ci u32 sense_data_info; 11462306a36Sopenharmony_ci u32 unit_attention_data; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci unsigned int blkbits; /* Bits of logical block size 11762306a36Sopenharmony_ci of bound block device */ 11862306a36Sopenharmony_ci unsigned int blksize; /* logical block size of bound block device */ 11962306a36Sopenharmony_ci struct device dev; 12062306a36Sopenharmony_ci const char *name; /* "lun.name" */ 12162306a36Sopenharmony_ci const char **name_pfx; /* "function.name" */ 12262306a36Sopenharmony_ci char inquiry_string[INQUIRY_STRING_LEN]; 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic inline bool fsg_lun_is_open(struct fsg_lun *curlun) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci return curlun->filp != NULL; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/* Default size of buffer length. */ 13162306a36Sopenharmony_ci#define FSG_BUFLEN ((u32)16384) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci/* Maximal number of LUNs supported in mass storage function */ 13462306a36Sopenharmony_ci#define FSG_MAX_LUNS 16 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cienum fsg_buffer_state { 13762306a36Sopenharmony_ci BUF_STATE_SENDING = -2, 13862306a36Sopenharmony_ci BUF_STATE_RECEIVING, 13962306a36Sopenharmony_ci BUF_STATE_EMPTY = 0, 14062306a36Sopenharmony_ci BUF_STATE_FULL 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistruct fsg_buffhd { 14462306a36Sopenharmony_ci void *buf; 14562306a36Sopenharmony_ci enum fsg_buffer_state state; 14662306a36Sopenharmony_ci struct fsg_buffhd *next; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci /* 14962306a36Sopenharmony_ci * The NetChip 2280 is faster, and handles some protocol faults 15062306a36Sopenharmony_ci * better, if we don't submit any short bulk-out read requests. 15162306a36Sopenharmony_ci * So we will record the intended request length here. 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_ci unsigned int bulk_out_intended_length; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci struct usb_request *inreq; 15662306a36Sopenharmony_ci struct usb_request *outreq; 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cienum fsg_state { 16062306a36Sopenharmony_ci FSG_STATE_NORMAL, 16162306a36Sopenharmony_ci FSG_STATE_ABORT_BULK_OUT, 16262306a36Sopenharmony_ci FSG_STATE_PROTOCOL_RESET, 16362306a36Sopenharmony_ci FSG_STATE_CONFIG_CHANGE, 16462306a36Sopenharmony_ci FSG_STATE_EXIT, 16562306a36Sopenharmony_ci FSG_STATE_TERMINATED 16662306a36Sopenharmony_ci}; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cienum data_direction { 16962306a36Sopenharmony_ci DATA_DIR_UNKNOWN = 0, 17062306a36Sopenharmony_ci DATA_DIR_FROM_HOST, 17162306a36Sopenharmony_ci DATA_DIR_TO_HOST, 17262306a36Sopenharmony_ci DATA_DIR_NONE 17362306a36Sopenharmony_ci}; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistatic inline struct fsg_lun *fsg_lun_from_dev(struct device *dev) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci return container_of(dev, struct fsg_lun, dev); 17862306a36Sopenharmony_ci} 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cienum { 18162306a36Sopenharmony_ci FSG_STRING_INTERFACE 18262306a36Sopenharmony_ci}; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ciextern struct usb_interface_descriptor fsg_intf_desc; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ciextern struct usb_endpoint_descriptor fsg_fs_bulk_in_desc; 18762306a36Sopenharmony_ciextern struct usb_endpoint_descriptor fsg_fs_bulk_out_desc; 18862306a36Sopenharmony_ciextern struct usb_descriptor_header *fsg_fs_function[]; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciextern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc; 19162306a36Sopenharmony_ciextern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc; 19262306a36Sopenharmony_ciextern struct usb_descriptor_header *fsg_hs_function[]; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ciextern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc; 19562306a36Sopenharmony_ciextern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc; 19662306a36Sopenharmony_ciextern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc; 19762306a36Sopenharmony_ciextern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc; 19862306a36Sopenharmony_ciextern struct usb_descriptor_header *fsg_ss_function[]; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_civoid fsg_lun_close(struct fsg_lun *curlun); 20162306a36Sopenharmony_ciint fsg_lun_open(struct fsg_lun *curlun, const char *filename); 20262306a36Sopenharmony_ciint fsg_lun_fsync_sub(struct fsg_lun *curlun); 20362306a36Sopenharmony_civoid store_cdrom_address(u8 *dest, int msf, u32 addr); 20462306a36Sopenharmony_cissize_t fsg_show_ro(struct fsg_lun *curlun, char *buf); 20562306a36Sopenharmony_cissize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf); 20662306a36Sopenharmony_cissize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, 20762306a36Sopenharmony_ci char *buf); 20862306a36Sopenharmony_cissize_t fsg_show_inquiry_string(struct fsg_lun *curlun, char *buf); 20962306a36Sopenharmony_cissize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf); 21062306a36Sopenharmony_cissize_t fsg_show_removable(struct fsg_lun *curlun, char *buf); 21162306a36Sopenharmony_cissize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, 21262306a36Sopenharmony_ci const char *buf, size_t count); 21362306a36Sopenharmony_cissize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count); 21462306a36Sopenharmony_cissize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, 21562306a36Sopenharmony_ci const char *buf, size_t count); 21662306a36Sopenharmony_cissize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, 21762306a36Sopenharmony_ci const char *buf, size_t count); 21862306a36Sopenharmony_cissize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, 21962306a36Sopenharmony_ci size_t count); 22062306a36Sopenharmony_cissize_t fsg_store_inquiry_string(struct fsg_lun *curlun, const char *buf, 22162306a36Sopenharmony_ci size_t count); 22262306a36Sopenharmony_cissize_t fsg_store_forced_eject(struct fsg_lun *curlun, struct rw_semaphore *filesem, 22362306a36Sopenharmony_ci const char *buf, size_t count); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci#endif /* USB_STORAGE_COMMON_H */ 226