⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file_storage.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Command Status Wrapper */struct bulk_cs_wrap {	__le32	Signature;		// Should = 'USBS'	u32	Tag;			// Same as original command	__le32	Residue;		// Amount not transferred	u8	Status;			// See below};#define USB_BULK_CS_WRAP_LEN	13#define USB_BULK_CS_SIG		0x53425355	// Spells out 'USBS'#define USB_STATUS_PASS		0#define USB_STATUS_FAIL		1#define USB_STATUS_PHASE_ERROR	2/* Bulk-only class specific requests */#define USB_BULK_RESET_REQUEST		0xff#define USB_BULK_GET_MAX_LUN_REQUEST	0xfe/* CBI Interrupt data structure */struct interrupt_data {	u8	bType;	u8	bValue;};#define CBI_INTERRUPT_DATA_LEN		2/* CBI Accept Device-Specific Command request */#define USB_CBI_ADSC_REQUEST		0x00#define MAX_COMMAND_SIZE	16	// Length of a SCSI Command Data Block/* SCSI commands that we recognize */#define SC_FORMAT_UNIT			0x04#define SC_INQUIRY			0x12#define SC_MODE_SELECT_6		0x15#define SC_MODE_SELECT_10		0x55#define SC_MODE_SENSE_6			0x1a#define SC_MODE_SENSE_10		0x5a#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL	0x1e#define SC_READ_6			0x08#define SC_READ_10			0x28#define SC_READ_12			0xa8#define SC_READ_CAPACITY		0x25#define SC_READ_FORMAT_CAPACITIES	0x23#define SC_RELEASE			0x17#define SC_REQUEST_SENSE		0x03#define SC_RESERVE			0x16#define SC_SEND_DIAGNOSTIC		0x1d#define SC_START_STOP_UNIT		0x1b#define SC_SYNCHRONIZE_CACHE		0x35#define SC_TEST_UNIT_READY		0x00#define SC_VERIFY			0x2f#define SC_WRITE_6			0x0a#define SC_WRITE_10			0x2a#define SC_WRITE_12			0xaa/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */#define SS_NO_SENSE				0#define SS_COMMUNICATION_FAILURE		0x040800#define SS_INVALID_COMMAND			0x052000#define SS_INVALID_FIELD_IN_CDB			0x052400#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE	0x052100#define SS_LOGICAL_UNIT_NOT_SUPPORTED		0x052500#define SS_MEDIUM_NOT_PRESENT			0x023a00#define SS_MEDIUM_REMOVAL_PREVENTED		0x055302#define SS_NOT_READY_TO_READY_TRANSITION	0x062800#define SS_RESET_OCCURRED			0x062900#define SS_SAVING_PARAMETERS_NOT_SUPPORTED	0x053900#define SS_UNRECOVERED_READ_ERROR		0x031100#define SS_WRITE_ERROR				0x030c02#define SS_WRITE_PROTECTED			0x072700#define SK(x)		((u8) ((x) >> 16))	// Sense Key byte, etc.#define ASC(x)		((u8) ((x) >> 8))#define ASCQ(x)		((u8) (x))/*-------------------------------------------------------------------------*//* * These definitions will permit the compiler to avoid generating code for * parts of the driver that aren't used in the non-TEST version.  Even gcc * can recognize when a test of a constant expression yields a dead code * path. */#ifdef CONFIG_USB_FILE_STORAGE_TEST#define transport_is_bbb()	(mod_data.transport_type == USB_PR_BULK)#define transport_is_cbi()	(mod_data.transport_type == USB_PR_CBI)#define protocol_is_scsi()	(mod_data.protocol_type == USB_SC_SCSI)#else#define transport_is_bbb()	1#define transport_is_cbi()	0#define protocol_is_scsi()	1#endif /* CONFIG_USB_FILE_STORAGE_TEST */struct lun {	struct file	*filp;	loff_t		file_length;	loff_t		num_sectors;	unsigned int	ro : 1;	unsigned int	prevent_medium_removal : 1;	unsigned int	registered : 1;	u32		sense_data;	u32		sense_data_info;	u32		unit_attention_data;	struct device	dev;};#define backing_file_is_open(curlun)	((curlun)->filp != NULL)static inline struct lun *dev_to_lun(struct device *dev){	return container_of(dev, struct lun, dev);}/* Big enough to hold our biggest descriptor */#define EP0_BUFSIZE	256#define DELAYED_STATUS	(EP0_BUFSIZE + 999)	// An impossibly large value/* Number of buffers we will use.  2 is enough for double-buffering */#define NUM_BUFFERS	2enum fsg_buffer_state {	BUF_STATE_EMPTY = 0,	BUF_STATE_FULL,	BUF_STATE_BUSY};struct fsg_buffhd {	void				*buf;	dma_addr_t			dma;	volatile enum fsg_buffer_state	state;	struct fsg_buffhd		*next;	/* The NetChip 2280 is faster, and handles some protocol faults	 * better, if we don't submit any short bulk-out read requests.	 * So we will record the intended request length here. */	unsigned int			bulk_out_intended_length;	struct usb_request		*inreq;	volatile int			inreq_busy;	struct usb_request		*outreq;	volatile int			outreq_busy;};enum fsg_state {	FSG_STATE_COMMAND_PHASE = -10,		// This one isn't used anywhere	FSG_STATE_DATA_PHASE,	FSG_STATE_STATUS_PHASE,	FSG_STATE_IDLE = 0,	FSG_STATE_ABORT_BULK_OUT,	FSG_STATE_RESET,	FSG_STATE_INTERFACE_CHANGE,	FSG_STATE_CONFIG_CHANGE,	FSG_STATE_DISCONNECT,	FSG_STATE_EXIT,	FSG_STATE_TERMINATED};enum data_direction {	DATA_DIR_UNKNOWN = 0,	DATA_DIR_FROM_HOST,	DATA_DIR_TO_HOST,	DATA_DIR_NONE};struct fsg_dev {	/* lock protects: state, all the req_busy's, and cbbuf_cmnd */	spinlock_t		lock;	struct usb_gadget	*gadget;	/* filesem protects: backing files in use */	struct rw_semaphore	filesem;	struct usb_ep		*ep0;		// Handy copy of gadget->ep0	struct usb_request	*ep0req;	// For control responses	volatile unsigned int	ep0_req_tag;	const char		*ep0req_name;	struct usb_request	*intreq;	// For interrupt responses	volatile int		intreq_busy;	struct fsg_buffhd	*intr_buffhd; 	unsigned int		bulk_out_maxpacket;	enum fsg_state		state;		// For exception handling	unsigned int		exception_req_tag;	u8			config, new_config;	unsigned int		running : 1;	unsigned int		bulk_in_enabled : 1;	unsigned int		bulk_out_enabled : 1;	unsigned int		intr_in_enabled : 1;	unsigned int		phase_error : 1;	unsigned int		short_packet_received : 1;	unsigned int		bad_lun_okay : 1;	unsigned long		atomic_bitflags;#define REGISTERED		0#define CLEAR_BULK_HALTS	1#define SUSPENDED		2	struct usb_ep		*bulk_in;	struct usb_ep		*bulk_out;	struct usb_ep		*intr_in;	struct fsg_buffhd	*next_buffhd_to_fill;	struct fsg_buffhd	*next_buffhd_to_drain;	struct fsg_buffhd	buffhds[NUM_BUFFERS];	wait_queue_head_t	thread_wqh;	int			thread_wakeup_needed;	struct completion	thread_notifier;	struct task_struct	*thread_task;	sigset_t		thread_signal_mask;	int			cmnd_size;	u8			cmnd[MAX_COMMAND_SIZE];	enum data_direction	data_dir;	u32			data_size;	u32			data_size_from_cmnd;	u32			tag;	unsigned int		lun;	u32			residue;	u32			usb_amount_left;	/* The CB protocol offers no way for a host to know when a command	 * has completed.  As a result the next command may arrive early,	 * and we will still have to handle it.  For that reason we need	 * a buffer to store new commands when using CB (or CBI, which	 * does not oblige a host to wait for command completion either). */	int			cbbuf_cmnd_size;	u8			cbbuf_cmnd[MAX_COMMAND_SIZE];	unsigned int		nluns;	struct lun		*luns;	struct lun		*curlun;	struct completion	lun_released;};typedef void (*fsg_routine_t)(struct fsg_dev *);static int inline exception_in_progress(struct fsg_dev *fsg){	return (fsg->state > FSG_STATE_IDLE);}/* Make bulk-out requests be divisible by the maxpacket size */static void inline set_bulk_out_req_length(struct fsg_dev *fsg,		struct fsg_buffhd *bh, unsigned int length){	unsigned int	rem;	bh->bulk_out_intended_length = length;	rem = length % fsg->bulk_out_maxpacket;	if (rem > 0)		length += fsg->bulk_out_maxpacket - rem;	bh->outreq->length = length;}static struct fsg_dev			*the_fsg;static struct usb_gadget_driver		fsg_driver;static void	close_backing_file(struct lun *curlun);static void	close_all_backing_files(struct fsg_dev *fsg);/*-------------------------------------------------------------------------*/#ifdef DUMP_MSGSstatic void dump_msg(struct fsg_dev *fsg, const char *label,		const u8 *buf, unsigned int length){	unsigned int	start, num, i;	char		line[52], *p;	if (length >= 512)		return;	DBG(fsg, "%s, length %u:\n", label, length);	start = 0;	while (length > 0) {		num = min(length, 16u);		p = line;		for (i = 0; i < num; ++i) {			if (i == 8)				*p++ = ' ';			sprintf(p, " %02x", buf[i]);			p += 3;		}		*p = 0;		printk(KERN_DEBUG "%6x: %s\n", start, line);		buf += num;		start += num;		length -= num;	}}static void inline dump_cdb(struct fsg_dev *fsg){}#elsestatic void inline dump_msg(struct fsg_dev *fsg, const char *label,		const u8 *buf, unsigned int length){}static void inline dump_cdb(struct fsg_dev *fsg){	int	i;	char	cmdbuf[3*MAX_COMMAND_SIZE + 1];	for (i = 0; i < fsg->cmnd_size; ++i)		sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]);	VDBG(fsg, "SCSI CDB: %s\n", cmdbuf);}#endif /* DUMP_MSGS */static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep){	const char	*name;	if (ep == fsg->bulk_in)		name = "bulk-in";	else if (ep == fsg->bulk_out)		name = "bulk-out";	else		name = ep->name;	DBG(fsg, "%s set halt\n", name);	return usb_ep_set_halt(ep);}/*-------------------------------------------------------------------------*//* Routines for unaligned data access */static u16 inline get_be16(u8 *buf){	return ((u16) buf[0] << 8) | ((u16) buf[1]);}static u32 inline get_be32(u8 *buf){	return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) |			((u32) buf[2] << 8) | ((u32) buf[3]);}static void inline put_be16(u8 *buf, u16 val){	buf[0] = val >> 8;	buf[1] = val;}static void inline put_be32(u8 *buf, u32 val){	buf[0] = val >> 24;	buf[1] = val >> 16;	buf[2] = val >> 8;	buf[3] = val & 0xff;}/*-------------------------------------------------------------------------*//* * DESCRIPTORS ... most are static, but strings and (full) configuration * descriptors are built on demand.  Also the (static) config and interface * descriptors are adjusted during fsg_bind(). */#define STRING_MANUFACTURER	1#define STRING_PRODUCT		2#define STRING_SERIAL		3#define STRING_CONFIG		4#define STRING_INTERFACE	5/* There is only one configuration. */#define	CONFIG_VALUE		1static struct usb_device_descriptordevice_desc = {	.bLength =		sizeof device_desc,	.bDescriptorType =	USB_DT_DEVICE,	.bcdUSB =		__constant_cpu_to_le16(0x0200),	.bDeviceClass =		USB_CLASS_PER_INTERFACE,	/* The next three values can be overridden by module parameters */	.idVendor =		__constant_cpu_to_le16(DRIVER_VENDOR_ID),	.idProduct =		__constant_cpu_to_le16(DRIVER_PRODUCT_ID),	.bcdDevice =		__constant_cpu_to_le16(0xffff),	.iManufacturer =	STRING_MANUFACTURER,	.iProduct =		STRING_PRODUCT,	.iSerialNumber =	STRING_SERIAL,	.bNumConfigurations =	1,};static struct usb_config_descriptorconfig_desc = {	.bLength =		sizeof config_desc,	.bDescriptorType =	USB_DT_CONFIG,	/* wTotalLength computed by usb_gadget_config_buf() */	.bNumInterfaces =	1,	.bConfigurationValue =	CONFIG_VALUE,	.iConfiguration =	STRING_CONFIG,	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,	.bMaxPower =		1,	// self-powered};static struct usb_otg_descriptorotg_desc = {	.bLength =		sizeof(otg_desc),	.bDescriptorType =	USB_DT_OTG,	.bmAttributes =		USB_OTG_SRP,};/* There is only one interface. */static struct usb_interface_descriptorintf_desc = {	.bLength =		sizeof intf_desc,	.bDescriptorType =	USB_DT_INTERFACE,	.bNumEndpoints =	2,		// Adjusted during fsg_bind()	.bInterfaceClass =	USB_CLASS_MASS_STORAGE,	.bInterfaceSubClass =	USB_SC_SCSI,	// Adjusted during fsg_bind()	.bInterfaceProtocol =	USB_PR_BULK,	// Adjusted during fsg_bind()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -