Also, names of various functions, structures and variables have been changed. This is to prevent potential name collision when the common file will be used with other code. Signed-off-by: Michal Nazarewicz <mnazarewicz@xxxxxxxxxxx> --- drivers/usb/gadget/file_storage.c | 1126 +++++++++-------------------------- drivers/usb/gadget/storage_common.c | 653 ++++++++++++++++++++ 2 files changed, 938 insertions(+), 841 deletions(-) create mode 100644 drivers/usb/gadget/storage_common.c diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 1e6aa50..d1d463c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -2,6 +2,8 @@ * file_storage.c -- File-backed USB Storage Gadget, for USB development * * Copyright (C) 2003-2008 Alan Stern + * Copyeight (C) 2009 Samsung Electronics + * Author: Michal Nazarewicz (m.nazarewicz@xxxxxxxxxxx) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -170,10 +172,10 @@ * REGISTERED atomic bitflag; the driver will only be deregistered once. * The second problem is resolved by having fsg_unbind() check * fsg->state; it won't try to stop the thread if the state is already - * FSG_STATE_TERMINATED. + * STOR_STATE_TERMINATED. * * To provide maximum throughput, the driver uses a circular pipeline of - * buffer heads (struct fsg_buffhd). In principle the pipeline can be + * buffer heads (struct stor_buffhd). In principle the pipeline can be * arbitrarily long; in practice the benefits don't justify having more * than 2 stages (i.e., double buffering). But it helps to think of the * pipeline as being a long one. Each buffer head contains a bulk-in and @@ -248,8 +250,6 @@ #include <linux/freezer.h> #include <linux/utsname.h> -#include <asm/unaligned.h> - #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -257,38 +257,22 @@ -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - /*-------------------------------------------------------------------------*/ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" #define DRIVER_VERSION "20 November 2008" -static const char longname[] = DRIVER_DESC; -static const char shortname[] = DRIVER_NAME; +static char stor_string_manufacturer[64]; +static const char stor_string_product[] = DRIVER_DESC; +static char stor_string_serial[13]; +static char stor_string_config[] = "Self Powered"; +static const char stor_string_interface[] = "Mass Storage"; MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Alan Stern"); MODULE_LICENSE("Dual BSD/GPL"); -/* Thanks to NetChip Technologies for donating this product ID. - * - * DO NOT REUSE THESE IDs with any other driver!! Ever!! - * Instead: allocate your own, using normal USB-IF procedures. */ -#define DRIVER_VENDOR_ID 0x0525 // NetChip -#define DRIVER_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget - - /* * This driver assumes self-powered hardware and has no way for users to * trigger remote wakeup. It uses autoconfiguration to select endpoints @@ -298,54 +282,29 @@ MODULE_LICENSE("Dual BSD/GPL"); /*-------------------------------------------------------------------------*/ -#define LDBG(lun,fmt,args...) \ - dev_dbg(&(lun)->dev , fmt , ## args) -#define MDBG(fmt,args...) \ - pr_debug(DRIVER_NAME ": " fmt , ## args) -#ifndef DEBUG -#undef VERBOSE_DEBUG -#undef DUMP_MSGS -#endif /* !DEBUG */ +/* + * Kbuild is not very cooperative with respect to linking separately + * compiled library objects into one module. So for now we won't use + * separate compilation ... ensuring init/exit sections work to shrink + * the runtime footprint, and giving us at least some parts of what + * a "gcc --combine ... part1.c part2.c part3.c ... " build would. + */ +#include "usbstring.c" +#include "config.c" +#include "epautoconf.c" -#ifdef VERBOSE_DEBUG -#define VLDBG LDBG -#else -#define VLDBG(lun,fmt,args...) \ - do { } while (0) -#endif /* VERBOSE_DEBUG */ - -#define LERROR(lun,fmt,args...) \ - dev_err(&(lun)->dev , fmt , ## args) -#define LWARN(lun,fmt,args...) \ - dev_warn(&(lun)->dev , fmt , ## args) -#define LINFO(lun,fmt,args...) \ - dev_info(&(lun)->dev , fmt , ## args) - -#define MINFO(fmt,args...) \ - pr_info(DRIVER_NAME ": " fmt , ## args) - -#define DBG(d, fmt, args...) \ - dev_dbg(&(d)->gadget->dev , fmt , ## args) -#define VDBG(d, fmt, args...) \ - dev_vdbg(&(d)->gadget->dev , fmt , ## args) -#define ERROR(d, fmt, args...) \ - dev_err(&(d)->gadget->dev , fmt , ## args) -#define WARNING(d, fmt, args...) \ - dev_warn(&(d)->gadget->dev , fmt , ## args) -#define INFO(d, fmt, args...) \ - dev_info(&(d)->gadget->dev , fmt , ## args) +#define STOR_DESCRIPTORS_DEVICE_STRINGS 1 +#define STOR_DESCRIPTORS_INTR_EP 1 +#include "storage_common.c" -/*-------------------------------------------------------------------------*/ /* Encapsulate the module parameter settings */ -#define MAX_LUNS 8 - static struct { - char *file[MAX_LUNS]; - int ro[MAX_LUNS]; + char *file[STORAGE_MAX_LUNS]; + int ro[STORAGE_MAX_LUNS]; unsigned int num_filenames; unsigned int num_ros; unsigned int nluns; @@ -372,8 +331,8 @@ static struct { .removable = 0, .can_stall = 1, .cdrom = 0, - .vendor = DRIVER_VENDOR_ID, - .product = DRIVER_PRODUCT_ID, + .vendor = STORAGE_VENDOR_ID, + .product = STORAGE_PRODUCT_ID, .release = 0xffff, // Use controller chip type .buflen = 16384, }; @@ -425,125 +384,6 @@ MODULE_PARM_DESC(buflen, "I/O buffer size"); #endif /* CONFIG_USB_FILE_STORAGE_TEST */ -/*-------------------------------------------------------------------------*/ - -/* SCSI device types */ -#define TYPE_DISK 0x00 -#define TYPE_CDROM 0x05 - -/* USB protocol value = the transport method */ -#define USB_PR_CBI 0x00 // Control/Bulk/Interrupt -#define USB_PR_CB 0x01 // Control/Bulk w/o interrupt -#define USB_PR_BULK 0x50 // Bulk-only - -/* USB subclass value = the protocol encapsulation */ -#define USB_SC_RBC 0x01 // Reduced Block Commands (flash) -#define USB_SC_8020 0x02 // SFF-8020i, MMC-2, ATAPI (CD-ROM) -#define USB_SC_QIC 0x03 // QIC-157 (tape) -#define USB_SC_UFI 0x04 // UFI (floppy) -#define USB_SC_8070 0x05 // SFF-8070i (removable) -#define USB_SC_SCSI 0x06 // Transparent SCSI - -/* Bulk-only data structures */ - -/* Command Block Wrapper */ -struct bulk_cb_wrap { - __le32 Signature; // Contains 'USBC' - u32 Tag; // Unique per command id - __le32 DataTransferLength; // Size of the data - u8 Flags; // Direction in bit 7 - u8 Lun; // LUN (normally 0) - u8 Length; // Of the CDB, <= MAX_COMMAND_SIZE - u8 CDB[16]; // Command Data Block -}; - -#define USB_BULK_CB_WRAP_LEN 31 -#define USB_BULK_CB_SIG 0x43425355 // Spells out USBC -#define USB_BULK_IN_FLAG 0x80 - -/* 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_READ_HEADER 0x44 -#define SC_READ_TOC 0x43 -#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 @@ -566,82 +406,6 @@ struct interrupt_data { #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; - unsigned int info_valid : 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 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 2 - -enum fsg_buffer_state { - BUF_STATE_EMPTY = 0, - BUF_STATE_FULL, - BUF_STATE_BUSY -}; - -struct fsg_buffhd { - void *buf; - 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; - int inreq_busy; - struct usb_request *outreq; - 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; @@ -660,10 +424,10 @@ struct fsg_dev { struct usb_request *intreq; // For interrupt responses int intreq_busy; - struct fsg_buffhd *intr_buffhd; + struct stor_buffhd *intr_buffhd; - unsigned int bulk_out_maxpacket; - enum fsg_state state; // For exception handling + unsigned int bulk_out_maxpacket; + enum stor_state state; // For exception handling unsigned int exception_req_tag; u8 config, new_config; @@ -685,9 +449,9 @@ struct fsg_dev { 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]; + struct stor_buffhd *next_buffhd_to_fill; + struct stor_buffhd *next_buffhd_to_drain; + struct stor_buffhd buffhds[STORAGE_NUM_BUFFERS]; int thread_wakeup_needed; struct completion thread_notifier; @@ -695,7 +459,7 @@ struct fsg_dev { int cmnd_size; u8 cmnd[MAX_COMMAND_SIZE]; - enum data_direction data_dir; + enum stor_data_direction data_dir; u32 data_size; u32 data_size_from_cmnd; u32 tag; @@ -712,20 +476,20 @@ struct fsg_dev { u8 cbbuf_cmnd[MAX_COMMAND_SIZE]; unsigned int nluns; - struct lun *luns; - struct lun *curlun; + struct storage_lun *luns; + struct storage_lun *curlun; }; typedef void (*fsg_routine_t)(struct fsg_dev *); static int exception_in_progress(struct fsg_dev *fsg) { - return (fsg->state > FSG_STATE_IDLE); + return (fsg->state > STOR_STATE_IDLE); } /* Make bulk-out requests be divisible by the maxpacket size */ static void set_bulk_out_req_length(struct fsg_dev *fsg, - struct fsg_buffhd *bh, unsigned int length) + struct stor_buffhd *bh, unsigned int length) { unsigned int rem; @@ -739,48 +503,17 @@ static void set_bulk_out_req_length(struct fsg_dev *fsg, static struct fsg_dev *the_fsg; static struct usb_gadget_driver fsg_driver; -static void close_backing_file(struct lun *curlun); - /*-------------------------------------------------------------------------*/ -#ifdef DUMP_MSGS - -static void dump_msg(struct fsg_dev *fsg, const char *label, - const u8 *buf, unsigned int length) -{ - if (length < 512) { - DBG(fsg, "%s, length %u:\n", label, length); - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, - 16, 1, buf, length, 0); - } -} - -static void dump_cdb(struct fsg_dev *fsg) -{} - -#else - -static void dump_msg(struct fsg_dev *fsg, const char *label, - const u8 *buf, unsigned int length) -{} - -#ifdef VERBOSE_DEBUG - -static void dump_cdb(struct fsg_dev *fsg) +static inline void dump_cdb(struct fsg_dev *fsg) { +#if defined DUMP_MSGS || !defined VERBOSE_DEBUG print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, 16, 1, fsg->cmnd, fsg->cmnd_size, 0); +#endif } -#else - -static void dump_cdb(struct fsg_dev *fsg) -{} - -#endif /* VERBOSE_DEBUG */ -#endif /* DUMP_MSGS */ - static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) { @@ -792,33 +525,20 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) name = "bulk-out"; else name = ep->name; - DBG(fsg, "%s set halt\n", name); + SDBG(fsg, "%s set halt\n", name); return usb_ep_set_halt(ep); } /*-------------------------------------------------------------------------*/ -/* Routines for unaligned data access */ - -static u32 get_unaligned_be24(u8 *buf) -{ - return 0xffffff & (u32) get_unaligned_be32(buf - 1); -} - - -/*-------------------------------------------------------------------------*/ - /* * 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 + +/* Some of the descriptors are defined in storage_common.c file. */ /* There is only one configuration. */ #define CONFIG_VALUE 1 @@ -832,13 +552,13 @@ device_desc = { .bDeviceClass = USB_CLASS_PER_INTERFACE, /* The next three values can be overridden by module parameters */ - .idVendor = cpu_to_le16(DRIVER_VENDOR_ID), - .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID), + .idVendor = cpu_to_le16(STORAGE_VENDOR_ID), + .idProduct = cpu_to_le16(STORAGE_PRODUCT_ID), .bcdDevice = cpu_to_le16(0xffff), - .iManufacturer = STRING_MANUFACTURER, - .iProduct = STRING_PRODUCT, - .iSerialNumber = STRING_SERIAL, + .iManufacturer = STOR_STRING_MANUFACTURER, + .iProduct = STOR_STRING_PRODUCT, + .iSerialNumber = STOR_STRING_SERIAL, .bNumConfigurations = 1, }; @@ -850,86 +570,12 @@ config_desc = { /* wTotalLength computed by usb_gadget_config_buf() */ .bNumInterfaces = 1, .bConfigurationValue = CONFIG_VALUE, - .iConfiguration = STRING_CONFIG, + .iConfiguration = STOR_STRING_CONFIG, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, }; -static struct usb_otg_descriptor -otg_desc = { - .bLength = sizeof(otg_desc), - .bDescriptorType = USB_DT_OTG, - - .bmAttributes = USB_OTG_SRP, -}; - -/* There is only one interface. */ - -static struct usb_interface_descriptor -intf_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() - .iInterface = STRING_INTERFACE, -}; - -/* Three full-speed endpoint descriptors: bulk-in, bulk-out, - * and interrupt-in. */ - -static struct usb_endpoint_descriptor -fs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ -}; -static struct usb_endpoint_descriptor -fs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ -}; - -static struct usb_endpoint_descriptor -fs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 32, // frames -> 32 ms -}; - -static const struct usb_descriptor_header *fs_function[] = { - (struct usb_descriptor_header *) &otg_desc, - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &fs_bulk_in_desc, - (struct usb_descriptor_header *) &fs_bulk_out_desc, - (struct usb_descriptor_header *) &fs_intr_in_desc, - NULL, -}; -#define FS_FUNCTION_PRE_EP_ENTRIES 2 - - -/* - * USB 2.0 devices need to expose both high speed and full speed - * descriptors, unless they only run at full speed. - * - * That means alternate endpoint descriptors (bigger packets) - * and a "device qualifier" ... plus more construction options - * for the config descriptor. - */ static struct usb_qualifier_descriptor dev_qualifier = { .bLength = sizeof dev_qualifier, @@ -941,78 +587,6 @@ dev_qualifier = { .bNumConfigurations = 1, }; -static struct usb_endpoint_descriptor -hs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor -hs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), - .bInterval = 1, // NAK every 1 uframe -}; - -static struct usb_endpoint_descriptor -hs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms -}; - -static const struct usb_descriptor_header *hs_function[] = { - (struct usb_descriptor_header *) &otg_desc, - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &hs_bulk_in_desc, - (struct usb_descriptor_header *) &hs_bulk_out_desc, - (struct usb_descriptor_header *) &hs_intr_in_desc, - NULL, -}; -#define HS_FUNCTION_PRE_EP_ENTRIES 2 - -/* Maxpacket and other transfer characteristics vary by speed. */ -static struct usb_endpoint_descriptor * -ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, - struct usb_endpoint_descriptor *hs) -{ - if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) - return hs; - return fs; -} - - -/* The CBI specification limits the serial string to 12 uppercase hexadecimal - * characters. */ -static char manufacturer[64]; -static char serial[13]; - -/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ -static struct usb_string strings[] = { - {STRING_MANUFACTURER, manufacturer}, - {STRING_PRODUCT, longname}, - {STRING_SERIAL, serial}, - {STRING_CONFIG, "Self-powered"}, - {STRING_INTERFACE, "Mass Storage"}, - {} -}; - -static struct usb_gadget_strings stringtab = { - .language = 0x0409, // en-us - .strings = strings, -}; /* @@ -1033,9 +607,9 @@ static int populate_config_buf(struct usb_gadget *gadget, if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH) - function = hs_function; + function = stor_hs_function; else - function = fs_function; + function = stor_fs_function; /* for now, don't advertise srp-only devices */ if (!gadget_is_otg(gadget)) @@ -1061,7 +635,7 @@ static void wakeup_thread(struct fsg_dev *fsg) } -static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) +static void raise_exception(struct fsg_dev *fsg, enum stor_state new_state) { unsigned long flags; @@ -1091,8 +665,8 @@ static void fsg_disconnect(struct usb_gadget *gadget) { struct fsg_dev *fsg = get_gadget_data(gadget); - DBG(fsg, "disconnect or port reset\n"); - raise_exception(fsg, FSG_STATE_DISCONNECT); + SDBG(fsg, "disconnect or port reset\n"); + raise_exception(fsg, STOR_STATE_DISCONNECT); } @@ -1104,8 +678,8 @@ static int ep0_queue(struct fsg_dev *fsg) if (rc != 0 && rc != -ESHUTDOWN) { /* We can't do much more than wait for a reset */ - WARNING(fsg, "error in submission: %s --> %d\n", - fsg->ep0->name, rc); + SWARN(fsg, "error in submission: %s --> %d\n", + fsg->ep0->name, rc); } return rc; } @@ -1117,8 +691,8 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req) if (req->actual > 0) dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); + SDBG(fsg, "%s --> %d, %u/%u\n", __func__, + req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1135,11 +709,11 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req) static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) { struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; + struct stor_buffhd *bh = req->context; if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); + SDBG(fsg, "%s --> %d, %u/%u\n", __func__, + req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1155,13 +729,13 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) { struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; + struct stor_buffhd *bh = req->context; dump_msg(fsg, "bulk-out", req->buf, req->actual); if (req->status || req->actual != bh->bulk_out_intended_length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, - bh->bulk_out_intended_length); + SDBG(fsg, "%s --> %d, %u/%u\n", __func__, + req->status, req->actual, + bh->bulk_out_intended_length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1179,11 +753,11 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) { struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; + struct stor_buffhd *bh = req->context; if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); + SDBG(fsg, "%s --> %d, %u/%u\n", __func__, + req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1207,7 +781,7 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) /* Ep0 class-specific handlers. These always run in_irq. */ #ifdef CONFIG_USB_FILE_STORAGE_TEST -static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static void received_cbi_adsc(struct fsg_dev *fsg, struct stor_buffhd *bh) { struct usb_request *req = fsg->ep0req; static u8 cbi_reset_cmnd[6] = { @@ -1230,17 +804,17 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) /* Raise an exception to stop the current operation * and reinitialize our state. */ - DBG(fsg, "cbi reset request\n"); - raise_exception(fsg, FSG_STATE_RESET); + SDBG(fsg, "cbi reset request\n"); + raise_exception(fsg, STOR_STATE_RESET); return; } - VDBG(fsg, "CB[I] accept device-specific command\n"); + VSDBG(fsg, "CB[I] accept device-specific command\n"); spin_lock(&fsg->lock); /* Save the command for later */ if (fsg->cbbuf_cmnd_size) - WARNING(fsg, "CB[I] overwriting previous command\n"); + SWARN(fsg, "CB[I] overwriting previous command\n"); fsg->cbbuf_cmnd_size = req->actual; memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); @@ -1249,7 +823,7 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) } #else -static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static void received_cbi_adsc(struct fsg_dev *fsg, struct stor_buffhd *bh) {} #endif /* CONFIG_USB_FILE_STORAGE_TEST */ @@ -1281,8 +855,8 @@ static int class_setup_req(struct fsg_dev *fsg, /* Raise an exception to stop the current operation * and reinitialize our state. */ - DBG(fsg, "bulk reset request\n"); - raise_exception(fsg, FSG_STATE_RESET); + SDBG(fsg, "bulk reset request\n"); + raise_exception(fsg, STOR_STATE_RESET); value = DELAYED_STATUS; break; @@ -1294,7 +868,7 @@ static int class_setup_req(struct fsg_dev *fsg, value = -EDOM; break; } - VDBG(fsg, "get max LUN\n"); + VSDBG(fsg, "get max LUN\n"); *(u8 *) req->buf = fsg->nluns - 1; value = 1; break; @@ -1324,7 +898,7 @@ static int class_setup_req(struct fsg_dev *fsg, } if (value == -EOPNOTSUPP) - VDBG(fsg, + VSDBG(fsg, "unknown class-specific control req " "%02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, @@ -1356,12 +930,12 @@ static int standard_setup_req(struct fsg_dev *fsg, switch (w_value >> 8) { case USB_DT_DEVICE: - VDBG(fsg, "get device descriptor\n"); + VSDBG(fsg, "get device descriptor\n"); value = sizeof device_desc; memcpy(req->buf, &device_desc, value); break; case USB_DT_DEVICE_QUALIFIER: - VDBG(fsg, "get device qualifier\n"); + VSDBG(fsg, "get device qualifier\n"); if (!gadget_is_dualspeed(fsg->gadget)) break; value = sizeof dev_qualifier; @@ -1369,12 +943,12 @@ static int standard_setup_req(struct fsg_dev *fsg, break; case USB_DT_OTHER_SPEED_CONFIG: - VDBG(fsg, "get other-speed config descriptor\n"); + VSDBG(fsg, "get other-speed config descriptor\n"); if (!gadget_is_dualspeed(fsg->gadget)) break; goto get_config; case USB_DT_CONFIG: - VDBG(fsg, "get configuration descriptor\n"); + VSDBG(fsg, "get configuration descriptor\n"); get_config: value = populate_config_buf(fsg->gadget, req->buf, @@ -1383,10 +957,10 @@ get_config: break; case USB_DT_STRING: - VDBG(fsg, "get string descriptor\n"); + VSDBG(fsg, "get string descriptor\n"); /* wIndex == language code */ - value = usb_gadget_get_string(&stringtab, + value = usb_gadget_get_string(&stor_stringtab, w_value & 0xff, req->buf); break; } @@ -1397,13 +971,13 @@ get_config: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; - VDBG(fsg, "set configuration\n"); + VSDBG(fsg, "set configuration\n"); if (w_value == CONFIG_VALUE || w_value == 0) { fsg->new_config = w_value; /* Raise an exception to wipe out previous transaction * state (queued bufs, etc) and set the new config. */ - raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); + raise_exception(fsg, STOR_STATE_CONFIG_CHANGE); value = DELAYED_STATUS; } break; @@ -1411,7 +985,7 @@ get_config: if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; - VDBG(fsg, "get configuration\n"); + VSDBG(fsg, "get configuration\n"); *(u8 *) req->buf = fsg->config; value = 1; break; @@ -1425,7 +999,7 @@ get_config: /* Raise an exception to wipe out previous transaction * state (queued bufs, etc) and install the new * interface altsetting. */ - raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE); + raise_exception(fsg, STOR_STATE_INTERFACE_CHANGE); value = DELAYED_STATUS; } break; @@ -1439,13 +1013,13 @@ get_config: value = -EDOM; break; } - VDBG(fsg, "get interface\n"); + VSDBG(fsg, "get interface\n"); *(u8 *) req->buf = 0; value = 1; break; default: - VDBG(fsg, + VSDBG(fsg, "unknown control req %02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, le16_to_cpu(ctrl->wLength)); @@ -1495,7 +1069,7 @@ static int fsg_setup(struct usb_gadget *gadget, /* Use this for bulk or interrupt transfers, not ep0 */ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, struct usb_request *req, int *pbusy, - enum fsg_buffer_state *state) + enum stor_buffer_state *state) { int rc; @@ -1519,8 +1093,8 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, * submissions if DMA is enabled. */ if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP && req->length == 0)) - WARNING(fsg, "error in submission: %s --> %d\n", - ep->name, rc); + SWARN(fsg, "error in submission: %s --> %d\n", + ep->name, rc); } } @@ -1551,9 +1125,9 @@ static int sleep_thread(struct fsg_dev *fsg) static int do_read(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; u32 lba; - struct fsg_buffhd *bh; + struct stor_buffhd *bh; int rc; u32 amount_left; loff_t file_offset, file_offset_tmp; @@ -1677,9 +1251,9 @@ static int do_read(struct fsg_dev *fsg) static int do_write(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; u32 lba; - struct fsg_buffhd *bh; + struct stor_buffhd *bh; int get_some_more; u32 amount_left_to_req, amount_left_to_write; loff_t usb_offset, file_offset, file_offset_tmp; @@ -1864,33 +1438,14 @@ static int do_write(struct fsg_dev *fsg) /*-------------------------------------------------------------------------*/ -/* Sync the file data, don't bother with the metadata. - * This code was copied from fs/buffer.c:sys_fdatasync(). */ -static int fsync_sub(struct lun *curlun) -{ - struct file *filp = curlun->filp; - - if (curlun->ro || !filp) - return 0; - return vfs_fsync(filp, filp->f_path.dentry, 1); -} - -static void fsync_all(struct fsg_dev *fsg) -{ - int i; - - for (i = 0; i < fsg->nluns; ++i) - fsync_sub(&fsg->luns[i]); -} - static int do_synchronize_cache(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; int rc; /* We ignore the requested LBA and write out all file's * dirty data buffers. */ - rc = fsync_sub(curlun); + rc = stor_lun_fsync_sub(curlun); if (rc) curlun->sense_data = SS_WRITE_ERROR; return 0; @@ -1899,7 +1454,7 @@ static int do_synchronize_cache(struct fsg_dev *fsg) /*-------------------------------------------------------------------------*/ -static void invalidate_sub(struct lun *curlun) +static void invalidate_sub(struct storage_lun *curlun) { struct file *filp = curlun->filp; struct inode *inode = filp->f_path.dentry->d_inode; @@ -1911,10 +1466,10 @@ static void invalidate_sub(struct lun *curlun) static int do_verify(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; u32 lba; u32 verification_length; - struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; + struct stor_buffhd *bh = fsg->next_buffhd_to_fill; loff_t file_offset, file_offset_tmp; u32 amount_left; unsigned int amount; @@ -1944,7 +1499,7 @@ static int do_verify(struct fsg_dev *fsg) file_offset = ((loff_t) lba) << 9; /* Write out all the dirty buffers before invalidating them */ - fsync_sub(curlun); + stor_lun_fsync_sub(curlun); if (signal_pending(current)) return -EINTR; @@ -2007,7 +1562,7 @@ static int do_verify(struct fsg_dev *fsg) /*-------------------------------------------------------------------------*/ -static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int do_inquiry(struct fsg_dev *fsg, struct stor_buffhd *bh) { u8 *buf = (u8 *) bh->buf; @@ -2039,9 +1594,9 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) } -static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int do_request_sense(struct fsg_dev *fsg, struct stor_buffhd *bh) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; u8 *buf = (u8 *) bh->buf; u32 sd, sdinfo; int valid; @@ -2093,9 +1648,9 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) } -static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int do_read_capacity(struct fsg_dev *fsg, struct stor_buffhd *bh) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; u32 lba = get_unaligned_be32(&fsg->cmnd[2]); int pmi = fsg->cmnd[8]; u8 *buf = (u8 *) bh->buf; @@ -2113,27 +1668,9 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) } -static void store_cdrom_address(u8 *dest, int msf, u32 addr) +static int do_read_header(struct fsg_dev *fsg, struct stor_buffhd *bh) { - if (msf) { - /* Convert to Minutes-Seconds-Frames */ - addr >>= 2; /* Convert to 2048-byte frames */ - addr += 2*75; /* Lead-in occupies 2 seconds */ - dest[3] = addr % 75; /* Frames */ - addr /= 75; - dest[2] = addr % 60; /* Seconds */ - addr /= 60; - dest[1] = addr; /* Minutes */ - dest[0] = 0; /* Reserved */ - } else { - /* Absolute sector */ - put_unaligned_be32(addr, dest); - } -} - -static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; int msf = fsg->cmnd[1] & 0x02; u32 lba = get_unaligned_be32(&fsg->cmnd[2]); u8 *buf = (u8 *) bh->buf; @@ -2154,9 +1691,9 @@ static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) } -static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int do_read_toc(struct fsg_dev *fsg, struct stor_buffhd *bh) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; int msf = fsg->cmnd[1] & 0x02; int start_track = fsg->cmnd[6]; u8 *buf = (u8 *) bh->buf; @@ -2182,9 +1719,9 @@ static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh) } -static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int do_mode_sense(struct fsg_dev *fsg, struct stor_buffhd *bh) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; int mscmnd = fsg->cmnd[0]; u8 *buf = (u8 *) bh->buf; u8 *buf0 = buf; @@ -2265,7 +1802,7 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) static int do_start_stop(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; int loej, start; if (!mod_data.removable) { @@ -2295,7 +1832,7 @@ static int do_start_stop(struct fsg_dev *fsg) if (loej) { // Simulate an unload/eject up_read(&fsg->filesem); down_write(&fsg->filesem); - close_backing_file(curlun); + stor_lun_close(curlun); up_write(&fsg->filesem); down_read(&fsg->filesem); } @@ -2315,7 +1852,7 @@ static int do_start_stop(struct fsg_dev *fsg) static int do_prevent_allow(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; int prevent; if (!mod_data.removable) { @@ -2330,16 +1867,16 @@ static int do_prevent_allow(struct fsg_dev *fsg) } if (curlun->prevent_medium_removal && !prevent) - fsync_sub(curlun); + stor_lun_fsync_sub(curlun); curlun->prevent_medium_removal = prevent; return 0; } static int do_read_format_capacities(struct fsg_dev *fsg, - struct fsg_buffhd *bh) + struct stor_buffhd *bh) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; u8 *buf = (u8 *) bh->buf; buf[0] = buf[1] = buf[2] = 0; @@ -2354,9 +1891,9 @@ static int do_read_format_capacities(struct fsg_dev *fsg, } -static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int do_mode_select(struct fsg_dev *fsg, struct stor_buffhd *bh) { - struct lun *curlun = fsg->curlun; + struct storage_lun *curlun = fsg->curlun; /* We don't support MODE SELECT */ curlun->sense_data = SS_INVALID_COMMAND; @@ -2372,10 +1909,10 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg) rc = fsg_set_halt(fsg, fsg->bulk_in); if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint halt\n"); + VSDBG(fsg, "delayed bulk-in endpoint halt\n"); while (rc != 0) { if (rc != -EAGAIN) { - WARNING(fsg, "usb_ep_set_halt -> %d\n", rc); + SWARN(fsg, "usb_ep_set_halt -> %d\n", rc); rc = 0; break; } @@ -2392,13 +1929,13 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) { int rc; - DBG(fsg, "bulk-in set wedge\n"); + SDBG(fsg, "bulk-in set wedge\n"); rc = usb_ep_set_wedge(fsg->bulk_in); if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint wedge\n"); + VSDBG(fsg, "delayed bulk-in endpoint wedge\n"); while (rc != 0) { if (rc != -EAGAIN) { - WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc); + SWARN(fsg, "usb_ep_set_wedge -> %d\n", rc); rc = 0; break; } @@ -2413,7 +1950,7 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) static int pad_with_zeros(struct fsg_dev *fsg) { - struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; + struct stor_buffhd *bh = fsg->next_buffhd_to_fill; u32 nkeep = bh->inreq->length; u32 nsend; int rc; @@ -2444,7 +1981,7 @@ static int pad_with_zeros(struct fsg_dev *fsg) static int throw_away_data(struct fsg_dev *fsg) { - struct fsg_buffhd *bh; + struct stor_buffhd *bh; u32 amount; int rc; @@ -2460,7 +1997,7 @@ static int throw_away_data(struct fsg_dev *fsg) /* A short packet or an error ends everything */ if (bh->outreq->actual != bh->outreq->length || bh->outreq->status != 0) { - raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); + raise_exception(fsg, STOR_STATE_ABORT_BULK_OUT); return -EINTR; } continue; @@ -2495,7 +2032,7 @@ static int throw_away_data(struct fsg_dev *fsg) static int finish_reply(struct fsg_dev *fsg) { - struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; + struct stor_buffhd *bh = fsg->next_buffhd_to_fill; int rc = 0; switch (fsg->data_dir) { @@ -2569,7 +2106,7 @@ static int finish_reply(struct fsg_dev *fsg) /* Did the host stop sending unexpectedly early? */ else if (fsg->short_packet_received) { - raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); + raise_exception(fsg, STOR_STATE_ABORT_BULK_OUT); rc = -EINTR; } @@ -2582,7 +2119,7 @@ static int finish_reply(struct fsg_dev *fsg) #if 0 else if (mod_data.can_stall) { fsg_set_halt(fsg, fsg->bulk_out); - raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); + raise_exception(fsg, STOR_STATE_ABORT_BULK_OUT); rc = -EINTR; } #endif @@ -2599,8 +2136,8 @@ static int finish_reply(struct fsg_dev *fsg) static int send_status(struct fsg_dev *fsg) { - struct lun *curlun = fsg->curlun; - struct fsg_buffhd *bh; + struct storage_lun *curlun = fsg->curlun; + struct stor_buffhd *bh; int rc; u8 status = USB_STATUS_PASS; u32 sd, sdinfo = 0; @@ -2622,19 +2159,19 @@ static int send_status(struct fsg_dev *fsg) sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; if (fsg->phase_error) { - DBG(fsg, "sending phase-error status\n"); + SDBG(fsg, "sending phase-error status\n"); status = USB_STATUS_PHASE_ERROR; sd = SS_INVALID_COMMAND; } else if (sd != SS_NO_SENSE) { - DBG(fsg, "sending command-failure status\n"); + SDBG(fsg, "sending command-failure status\n"); status = USB_STATUS_FAIL; - VDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" - " info x%x\n", - SK(sd), ASC(sd), ASCQ(sd), sdinfo); + VSDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" + " info x%x\n", + SK(sd), ASC(sd), ASCQ(sd), sdinfo); } if (transport_is_bbb()) { - struct bulk_cs_wrap *csw = bh->buf; + struct stor_bulk_cs_wrap *csw = bh->buf; /* Store and send the Bulk-only CSW */ csw->Signature = cpu_to_le32(USB_BULK_CS_SIG); @@ -2653,7 +2190,7 @@ static int send_status(struct fsg_dev *fsg) return 0; } else { // USB_PR_CBI - struct interrupt_data *buf = bh->buf; + struct stor_interrupt_data *buf = bh->buf; /* Store and send the Interrupt data. UFI sends the ASC * and ASCQ bytes. Everything else sends a Type (which @@ -2684,14 +2221,14 @@ static int send_status(struct fsg_dev *fsg) /* Check whether the command is properly formed and whether its data size * and direction agree with the values we already have. */ static int check_command(struct fsg_dev *fsg, int cmnd_size, - enum data_direction data_dir, unsigned int mask, + enum stor_data_direction data_dir, unsigned int mask, int needs_medium, const char *name) { int i; int lun = fsg->cmnd[1] >> 5; static const char dirletter[4] = {'u', 'o', 'i', 'n'}; char hdlen[20]; - struct lun *curlun; + struct storage_lun *curlun; /* Adjust the expected cmnd_size for protocol encapsulation padding. * Transparent SCSI doesn't pad. */ @@ -2711,10 +2248,10 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, hdlen[0] = 0; if (fsg->data_dir != DATA_DIR_UNKNOWN) sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir], - fsg->data_size); - VDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", - name, cmnd_size, dirletter[(int) data_dir], - fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen); + fsg->data_size); + VSDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", + name, cmnd_size, dirletter[(int) data_dir], + fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen); /* We can't reply at all until we know the correct data direction * and size. */ @@ -2758,9 +2295,9 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, * be 6 as well. */ if (cmnd_size <= fsg->cmnd_size) { - DBG(fsg, "%s is buggy! Expected length %d " - "but we got %d\n", name, - cmnd_size, fsg->cmnd_size); + SDBG(fsg, "%s is buggy! Expected length %d " + "but we got %d\n", name, + cmnd_size, fsg->cmnd_size); cmnd_size = fsg->cmnd_size; } else { fsg->phase_error = 1; @@ -2771,9 +2308,9 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* Check that the LUN values are consistent */ if (transport_is_bbb()) { if (fsg->lun != lun) - DBG(fsg, "using LUN %d from CBW, " - "not LUN %d from CDB\n", - fsg->lun, lun); + SDBG(fsg, "using LUN %d from CBW, " + "not LUN %d from CDB\n", + fsg->lun, lun); } else fsg->lun = lun; // Use LUN from the command @@ -2792,8 +2329,8 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* INQUIRY and REQUEST SENSE commands are explicitly allowed * to use unsupported LUNs; all others may not. */ if (fsg->cmnd[0] != SC_INQUIRY && - fsg->cmnd[0] != SC_REQUEST_SENSE) { - DBG(fsg, "unsupported LUN %d\n", fsg->lun); + fsg->cmnd[0] != SC_REQUEST_SENSE) { + SDBG(fsg, "unsupported LUN %d\n", fsg->lun); return -EINVAL; } } @@ -2820,7 +2357,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, /* If the medium isn't mounted and the command needs to access * it, return an error. */ - if (curlun && !backing_file_is_open(curlun) && needs_medium) { + if (curlun && !stor_lun_is_open(curlun) && needs_medium) { curlun->sense_data = SS_MEDIUM_NOT_PRESENT; return -EINVAL; } @@ -2831,7 +2368,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, static int do_scsi_command(struct fsg_dev *fsg) { - struct fsg_buffhd *bh; + struct stor_buffhd *bh; int rc; int reply = -EINVAL; int i; @@ -3073,10 +2610,10 @@ static int do_scsi_command(struct fsg_dev *fsg) /*-------------------------------------------------------------------------*/ -static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) +static int received_cbw(struct fsg_dev *fsg, struct stor_buffhd *bh) { struct usb_request *req = bh->outreq; - struct bulk_cb_wrap *cbw = req->buf; + struct stor_bulk_cb_wrap *cbw = req->buf; /* Was this a real packet? Should it be ignored? */ if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) @@ -3086,9 +2623,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) if (req->actual != USB_BULK_CB_WRAP_LEN || cbw->Signature != cpu_to_le32( USB_BULK_CB_SIG)) { - DBG(fsg, "invalid CBW: len %u sig 0x%x\n", - req->actual, - le32_to_cpu(cbw->Signature)); + SDBG(fsg, "invalid CBW: len %u sig 0x%x\n", + req->actual, + le32_to_cpu(cbw->Signature)); /* The Bulk-only spec says we MUST stall the IN endpoint * (6.6.1), so it's unavoidable. It also says we must @@ -3105,11 +2642,11 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) } /* Is the CBW meaningful? */ - if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || + if (cbw->Lun >= STORAGE_MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { - DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " - "cmdlen %u\n", - cbw->Lun, cbw->Flags, cbw->Length); + SDBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " + "cmdlen %u\n", + cbw->Lun, cbw->Flags, cbw->Length); /* We can do anything we want here, so let's stall the * bulk pipes if we are allowed to. */ @@ -3138,7 +2675,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) static int get_next_command(struct fsg_dev *fsg) { - struct fsg_buffhd *bh; + struct stor_buffhd *bh; int rc = 0; if (transport_is_bbb()) { @@ -3208,7 +2745,7 @@ static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep, ep->driver_data = fsg; rc = usb_ep_enable(ep, d); if (rc) - ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc); + SERROR(fsg, "can't enable %s, result %d\n", ep->name, rc); return rc; } @@ -3218,7 +2755,7 @@ static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep, *preq = usb_ep_alloc_request(ep, GFP_ATOMIC); if (*preq) return 0; - ERROR(fsg, "can't allocate request for %s\n", ep->name); + SERROR(fsg, "can't allocate request for %s\n", ep->name); return -ENOMEM; } @@ -3234,12 +2771,12 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting) const struct usb_endpoint_descriptor *d; if (fsg->running) - DBG(fsg, "reset interface\n"); + SDBG(fsg, "reset interface\n"); reset: /* Deallocate the requests */ - for (i = 0; i < NUM_BUFFERS; ++i) { - struct fsg_buffhd *bh = &fsg->buffhds[i]; + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) { + struct stor_buffhd *bh = &fsg->buffhds[i]; if (bh->inreq) { usb_ep_free_request(fsg->bulk_in, bh->inreq); @@ -3273,15 +2810,16 @@ reset: if (altsetting < 0 || rc != 0) return rc; - DBG(fsg, "set interface %d\n", altsetting); + SDBG(fsg, "set interface %d\n", altsetting); /* Enable the endpoints */ - d = ep_desc(fsg->gadget, &fs_bulk_in_desc, &hs_bulk_in_desc); + d = ep_desc(fsg->gadget, &stor_fs_bulk_in_desc, &stor_hs_bulk_in_desc); if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) goto reset; fsg->bulk_in_enabled = 1; - d = ep_desc(fsg->gadget, &fs_bulk_out_desc, &hs_bulk_out_desc); + d = ep_desc(fsg->gadget, + &stor_fs_bulk_out_desc, &stor_hs_bulk_out_desc); if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) goto reset; fsg->bulk_out_enabled = 1; @@ -3289,15 +2827,16 @@ reset: clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); if (transport_is_cbi()) { - d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc); + d = ep_desc(fsg->gadget, + &stor_fs_intr_in_desc, &stor_hs_intr_in_desc); if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) goto reset; fsg->intr_in_enabled = 1; } /* Allocate the requests */ - for (i = 0; i < NUM_BUFFERS; ++i) { - struct fsg_buffhd *bh = &fsg->buffhds[i]; + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) { + struct stor_buffhd *bh = &fsg->buffhds[i]; if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) goto reset; @@ -3335,7 +2874,7 @@ static int do_set_config(struct fsg_dev *fsg, u8 new_config) /* Disable the single interface */ if (fsg->config != 0) { - DBG(fsg, "reset config\n"); + SDBG(fsg, "reset config\n"); fsg->config = 0; rc = do_set_interface(fsg, -1); } @@ -3354,7 +2893,7 @@ static int do_set_config(struct fsg_dev *fsg, u8 new_config) case USB_SPEED_HIGH: speed = "high"; break; default: speed = "?"; break; } - INFO(fsg, "%s speed config #%d\n", speed, fsg->config); + SINFO(fsg, "%s speed config #%d\n", speed, fsg->config); } } return rc; @@ -3369,10 +2908,10 @@ static void handle_exception(struct fsg_dev *fsg) int sig; int i; int num_active; - struct fsg_buffhd *bh; - enum fsg_state old_state; + struct stor_buffhd *bh; + enum stor_state old_state; u8 new_config; - struct lun *curlun; + struct storage_lun *curlun; unsigned int exception_req_tag; int rc; @@ -3383,16 +2922,16 @@ static void handle_exception(struct fsg_dev *fsg) if (!sig) break; if (sig != SIGUSR1) { - if (fsg->state < FSG_STATE_EXIT) - DBG(fsg, "Main thread exiting on signal\n"); - raise_exception(fsg, FSG_STATE_EXIT); + if (fsg->state < STOR_STATE_EXIT) + SDBG(fsg, "Main thread exiting on signal\n"); + raise_exception(fsg, STOR_STATE_EXIT); } } /* Cancel all the pending transfers */ if (fsg->intreq_busy) usb_ep_dequeue(fsg->intr_in, fsg->intreq); - for (i = 0; i < NUM_BUFFERS; ++i) { + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) { bh = &fsg->buffhds[i]; if (bh->inreq_busy) usb_ep_dequeue(fsg->bulk_in, bh->inreq); @@ -3403,7 +2942,7 @@ static void handle_exception(struct fsg_dev *fsg) /* Wait until everything is idle */ for (;;) { num_active = fsg->intreq_busy; - for (i = 0; i < NUM_BUFFERS; ++i) { + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) { bh = &fsg->buffhds[i]; num_active += bh->inreq_busy + bh->outreq_busy; } @@ -3425,7 +2964,7 @@ static void handle_exception(struct fsg_dev *fsg) * state, and the exception. Then invoke the handler. */ spin_lock_irq(&fsg->lock); - for (i = 0; i < NUM_BUFFERS; ++i) { + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) { bh = &fsg->buffhds[i]; bh->state = BUF_STATE_EMPTY; } @@ -3436,8 +2975,8 @@ static void handle_exception(struct fsg_dev *fsg) new_config = fsg->new_config; old_state = fsg->state; - if (old_state == FSG_STATE_ABORT_BULK_OUT) - fsg->state = FSG_STATE_STATUS_PHASE; + if (old_state == STOR_STATE_ABORT_BULK_OUT) + fsg->state = STOR_STATE_STATUS_PHASE; else { for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; @@ -3447,7 +2986,7 @@ static void handle_exception(struct fsg_dev *fsg) curlun->sense_data_info = 0; curlun->info_valid = 0; } - fsg->state = FSG_STATE_IDLE; + fsg->state = STOR_STATE_IDLE; } spin_unlock_irq(&fsg->lock); @@ -3456,15 +2995,15 @@ static void handle_exception(struct fsg_dev *fsg) default: break; - case FSG_STATE_ABORT_BULK_OUT: + case STOR_STATE_ABORT_BULK_OUT: send_status(fsg); spin_lock_irq(&fsg->lock); - if (fsg->state == FSG_STATE_STATUS_PHASE) - fsg->state = FSG_STATE_IDLE; + if (fsg->state == STOR_STATE_STATUS_PHASE) + fsg->state = STOR_STATE_IDLE; spin_unlock_irq(&fsg->lock); break; - case FSG_STATE_RESET: + case STOR_STATE_RESET: /* In case we were forced against our will to halt a * bulk endpoint, clear the halt now. (The SuperH UDC * requires this.) */ @@ -3485,7 +3024,7 @@ static void handle_exception(struct fsg_dev *fsg) // fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; break; - case FSG_STATE_INTERFACE_CHANGE: + case STOR_STATE_INTERFACE_CHANGE: rc = do_set_interface(fsg, 0); if (fsg->ep0_req_tag != exception_req_tag) break; @@ -3495,7 +3034,7 @@ static void handle_exception(struct fsg_dev *fsg) ep0_queue(fsg); break; - case FSG_STATE_CONFIG_CHANGE: + case STOR_STATE_CONFIG_CHANGE: rc = do_set_config(fsg, new_config); if (fsg->ep0_req_tag != exception_req_tag) break; @@ -3505,16 +3044,17 @@ static void handle_exception(struct fsg_dev *fsg) ep0_queue(fsg); break; - case FSG_STATE_DISCONNECT: - fsync_all(fsg); + case STOR_STATE_DISCONNECT: + for (i = 0; i < fsg->nluns; ++i) + stor_lun_fsync_sub(&fsg->luns[i]); do_set_config(fsg, 0); // Unconfigured state break; - case FSG_STATE_EXIT: - case FSG_STATE_TERMINATED: + case STOR_STATE_EXIT: + case STOR_STATE_TERMINATED: do_set_config(fsg, 0); // Free resources spin_lock_irq(&fsg->lock); - fsg->state = FSG_STATE_TERMINATED; // Stop the thread + fsg->state = STOR_STATE_TERMINATED; // Stop the thread spin_unlock_irq(&fsg->lock); break; } @@ -3543,7 +3083,7 @@ static int fsg_main_thread(void *fsg_) set_fs(get_ds()); /* The main loop */ - while (fsg->state != FSG_STATE_TERMINATED) { + while (fsg->state != STOR_STATE_TERMINATED) { if (exception_in_progress(fsg) || signal_pending(current)) { handle_exception(fsg); continue; @@ -3559,7 +3099,7 @@ static int fsg_main_thread(void *fsg_) spin_lock_irq(&fsg->lock); if (!exception_in_progress(fsg)) - fsg->state = FSG_STATE_DATA_PHASE; + fsg->state = STOR_STATE_DATA_PHASE; spin_unlock_irq(&fsg->lock); if (do_scsi_command(fsg) || finish_reply(fsg)) @@ -3567,7 +3107,7 @@ static int fsg_main_thread(void *fsg_) spin_lock_irq(&fsg->lock); if (!exception_in_progress(fsg)) - fsg->state = FSG_STATE_STATUS_PHASE; + fsg->state = STOR_STATE_STATUS_PHASE; spin_unlock_irq(&fsg->lock); if (send_status(fsg)) @@ -3575,7 +3115,7 @@ static int fsg_main_thread(void *fsg_) spin_lock_irq(&fsg->lock); if (!exception_in_progress(fsg)) - fsg->state = FSG_STATE_IDLE; + fsg->state = STOR_STATE_IDLE; spin_unlock_irq(&fsg->lock); } @@ -3595,106 +3135,9 @@ static int fsg_main_thread(void *fsg_) /*-------------------------------------------------------------------------*/ -/* If the next two routines are called while the gadget is registered, - * the caller must own fsg->filesem for writing. */ - -static int open_backing_file(struct lun *curlun, const char *filename) -{ - int ro; - struct file *filp = NULL; - int rc = -EINVAL; - struct inode *inode = NULL; - loff_t size; - loff_t num_sectors; - loff_t min_sectors; - - /* R/W if we can, R/O if we must */ - ro = curlun->ro; - if (!ro) { - filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); - if (-EROFS == PTR_ERR(filp)) - ro = 1; - } - if (ro) - filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - LINFO(curlun, "unable to open backing file: %s\n", filename); - return PTR_ERR(filp); - } - - if (!(filp->f_mode & FMODE_WRITE)) - ro = 1; - - if (filp->f_path.dentry) - inode = filp->f_path.dentry->d_inode; - if (inode && S_ISBLK(inode->i_mode)) { - if (bdev_read_only(inode->i_bdev)) - ro = 1; - } else if (!inode || !S_ISREG(inode->i_mode)) { - LINFO(curlun, "invalid file type: %s\n", filename); - goto out; - } - - /* If we can't read the file, it's no good. - * If we can't write the file, use it read-only. */ - if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) { - LINFO(curlun, "file not readable: %s\n", filename); - goto out; - } - if (!(filp->f_op->write || filp->f_op->aio_write)) - ro = 1; - - size = i_size_read(inode->i_mapping->host); - if (size < 0) { - LINFO(curlun, "unable to find file size: %s\n", filename); - rc = (int) size; - goto out; - } - num_sectors = size >> 9; // File size in 512-byte blocks - min_sectors = 1; - if (mod_data.cdrom) { - num_sectors &= ~3; // Reduce to a multiple of 2048 - min_sectors = 300*4; // Smallest track is 300 frames - if (num_sectors >= 256*60*75*4) { - num_sectors = (256*60*75 - 1) * 4; - LINFO(curlun, "file too big: %s\n", filename); - LINFO(curlun, "using only first %d blocks\n", - (int) num_sectors); - } - } - if (num_sectors < min_sectors) { - LINFO(curlun, "file too small: %s\n", filename); - rc = -ETOOSMALL; - goto out; - } - - get_file(filp); - curlun->ro = ro; - curlun->filp = filp; - curlun->file_length = size; - curlun->num_sectors = num_sectors; - LDBG(curlun, "open backing file: %s\n", filename); - rc = 0; - -out: - filp_close(filp, current->files); - return rc; -} - - -static void close_backing_file(struct lun *curlun) -{ - if (curlun->filp) { - LDBG(curlun, "close backing file\n"); - fput(curlun->filp); - curlun->filp = NULL; - } -} - - static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf) { - struct lun *curlun = dev_to_lun(dev); + struct storage_lun *curlun = stor_lun_from_dev(dev); return sprintf(buf, "%d\n", curlun->ro); } @@ -3702,13 +3145,13 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char * static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) { - struct lun *curlun = dev_to_lun(dev); + struct storage_lun *curlun = stor_lun_from_dev(dev); struct fsg_dev *fsg = dev_get_drvdata(dev); char *p; ssize_t rc; down_read(&fsg->filesem); - if (backing_file_is_open(curlun)) { // Get the complete pathname + if (stor_lun_is_open(curlun)) { // Get the complete pathname p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1); if (IS_ERR(p)) rc = PTR_ERR(p); @@ -3731,7 +3174,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ssize_t rc = count; - struct lun *curlun = dev_to_lun(dev); + struct storage_lun *curlun = stor_lun_from_dev(dev); struct fsg_dev *fsg = dev_get_drvdata(dev); int i; @@ -3741,7 +3184,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, /* Allow the write-enable status to change only while the backing file * is closed. */ down_read(&fsg->filesem); - if (backing_file_is_open(curlun)) { + if (stor_lun_is_open(curlun)) { LDBG(curlun, "read-only status change prevented\n"); rc = -EBUSY; } else { @@ -3755,11 +3198,11 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lun *curlun = dev_to_lun(dev); + struct storage_lun *curlun = stor_lun_from_dev(dev); struct fsg_dev *fsg = dev_get_drvdata(dev); int rc = 0; - if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) { + if (curlun->prevent_medium_removal && stor_lun_is_open(curlun)) { LDBG(curlun, "eject attempt prevented\n"); return -EBUSY; // "Door is locked" } @@ -3770,14 +3213,14 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, /* Eject current medium */ down_write(&fsg->filesem); - if (backing_file_is_open(curlun)) { - close_backing_file(curlun); + if (stor_lun_is_open(curlun)) { + stor_lun_close(curlun); curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; } /* Load new medium */ if (count > 0 && buf[0]) { - rc = open_backing_file(curlun, buf); + rc = stor_lun_open(curlun, buf); if (rc == 0) curlun->unit_attention_data = SS_NOT_READY_TO_READY_TRANSITION; @@ -3813,10 +3256,10 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) { struct fsg_dev *fsg = get_gadget_data(gadget); int i; - struct lun *curlun; + struct storage_lun *curlun; struct usb_request *req = fsg->ep0req; - DBG(fsg, "unbind\n"); + SDBG(fsg, "unbind\n"); clear_bit(REGISTERED, &fsg->atomic_bitflags); /* Unregister the sysfs attribute files and the LUNs */ @@ -3825,15 +3268,15 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) if (curlun->registered) { device_remove_file(&curlun->dev, &dev_attr_ro); device_remove_file(&curlun->dev, &dev_attr_file); - close_backing_file(curlun); + stor_lun_close(curlun); device_unregister(&curlun->dev); curlun->registered = 0; } } /* If the thread isn't already dead, tell it to exit now */ - if (fsg->state != FSG_STATE_TERMINATED) { - raise_exception(fsg, FSG_STATE_EXIT); + if (fsg->state != STOR_STATE_TERMINATED) { + raise_exception(fsg, STOR_STATE_EXIT); wait_for_completion(&fsg->thread_notifier); /* The cleanup routine waits for this completion also */ @@ -3841,7 +3284,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) } /* Free the data buffers */ - for (i = 0; i < NUM_BUFFERS; ++i) + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) kfree(fsg->buffhds[i].buf); /* Free the request and buffer for endpoint 0 */ @@ -3881,8 +3324,8 @@ static int __init check_parameters(struct fsg_dev *fsg) if (gcnum >= 0) mod_data.release = 0x0300 + gcnum; else { - WARNING(fsg, "controller '%s' not recognized\n", - fsg->gadget->name); + SWARN(fsg, "controller '%s' not recognized\n", + fsg->gadget->name); mod_data.release = 0x0399; } } @@ -3899,7 +3342,7 @@ static int __init check_parameters(struct fsg_dev *fsg) mod_data.transport_type = USB_PR_CBI; mod_data.transport_name = "Control-Bulk-Interrupt"; } else { - ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm); + SERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm); return -EINVAL; } @@ -3928,13 +3371,13 @@ static int __init check_parameters(struct fsg_dev *fsg) mod_data.protocol_type = USB_SC_8070; mod_data.protocol_name = "8070i"; } else { - ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); + SERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); return -EINVAL; } mod_data.buflen &= PAGE_CACHE_MASK; if (mod_data.buflen <= 0) { - ERROR(fsg, "invalid buflen\n"); + SERROR(fsg, "invalid buflen\n"); return -ETOOSMALL; } #endif /* CONFIG_USB_FILE_STORAGE_TEST */ @@ -3948,7 +3391,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) struct fsg_dev *fsg = the_fsg; int rc; int i; - struct lun *curlun; + struct storage_lun *curlun; struct usb_ep *ep; struct usb_request *req; char *pathbuf, *p; @@ -3974,15 +3417,15 @@ static int __init fsg_bind(struct usb_gadget *gadget) i = mod_data.nluns; if (i == 0) i = max(mod_data.num_filenames, 1u); - if (i > MAX_LUNS) { - ERROR(fsg, "invalid number of LUNs: %d\n", i); + if (i > STORAGE_MAX_LUNS) { + SERROR(fsg, "invalid number of LUNs: %d\n", i); rc = -EINVAL; goto out; } /* Create the LUNs, open their backing files, and register the * LUN devices in sysfs. */ - fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL); + fsg->luns = kzalloc(i * sizeof(struct storage_lun), GFP_KERNEL); if (!fsg->luns) { rc = -ENOMEM; goto out; @@ -3991,9 +3434,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; - curlun->ro = mod_data.ro[i]; - if (mod_data.cdrom) - curlun->ro = 1; + curlun->cdrom = mod_data.cdrom; + curlun->ro = mod_data.cdrom || mod_data.ro[i]; + curlun->removable = mod_data.removable; curlun->dev.release = lun_release; curlun->dev.parent = &gadget->dev; curlun->dev.driver = &fsg_driver.driver; @@ -4002,7 +3445,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) dev_name(&gadget->dev), i); if ((rc = device_register(&curlun->dev)) != 0) { - INFO(fsg, "failed to register LUN%d: %d\n", i, rc); + SINFO(fsg, "failed to register LUN%d: %d\n", i, rc); goto out; } if ((rc = device_create_file(&curlun->dev, @@ -4016,11 +3459,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) kref_get(&fsg->ref); if (mod_data.file[i] && *mod_data.file[i]) { - if ((rc = open_backing_file(curlun, + if ((rc = stor_lun_open(curlun, mod_data.file[i])) != 0) goto out; } else if (!mod_data.removable) { - ERROR(fsg, "no file given for LUN%d\n", i); + SERROR(fsg, "no file given for LUN%d\n", i); rc = -EINVAL; goto out; } @@ -4028,20 +3471,20 @@ static int __init fsg_bind(struct usb_gadget *gadget) /* Find all the endpoints we will use */ usb_ep_autoconfig_reset(gadget); - ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc); + ep = usb_ep_autoconfig(gadget, &stor_fs_bulk_in_desc); if (!ep) goto autoconf_fail; ep->driver_data = fsg; // claim the endpoint fsg->bulk_in = ep; - ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc); + ep = usb_ep_autoconfig(gadget, &stor_fs_bulk_out_desc); if (!ep) goto autoconf_fail; ep->driver_data = fsg; // claim the endpoint fsg->bulk_out = ep; if (transport_is_cbi()) { - ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc); + ep = usb_ep_autoconfig(gadget, &stor_fs_intr_in_desc); if (!ep) goto autoconf_fail; ep->driver_data = fsg; // claim the endpoint @@ -4055,28 +3498,28 @@ static int __init fsg_bind(struct usb_gadget *gadget) device_desc.bcdDevice = cpu_to_le16(mod_data.release); i = (transport_is_cbi() ? 3 : 2); // Number of endpoints - intf_desc.bNumEndpoints = i; - intf_desc.bInterfaceSubClass = mod_data.protocol_type; - intf_desc.bInterfaceProtocol = mod_data.transport_type; - fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL; + stor_intf_desc.bNumEndpoints = i; + stor_intf_desc.bInterfaceSubClass = mod_data.protocol_type; + stor_intf_desc.bInterfaceProtocol = mod_data.transport_type; + stor_fs_function[i + STOR_FS_FUNCTION_PRE_EP_ENTRIES] = NULL; if (gadget_is_dualspeed(gadget)) { - hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL; + stor_hs_function[i + STOR_HS_FUNCTION_PRE_EP_ENTRIES] = NULL; /* Assume ep0 uses the same maxpacket value for both speeds */ dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; /* Assume endpoint addresses are the same for both speeds */ - hs_bulk_in_desc.bEndpointAddress = - fs_bulk_in_desc.bEndpointAddress; - hs_bulk_out_desc.bEndpointAddress = - fs_bulk_out_desc.bEndpointAddress; - hs_intr_in_desc.bEndpointAddress = - fs_intr_in_desc.bEndpointAddress; + stor_hs_bulk_in_desc.bEndpointAddress = + stor_fs_bulk_in_desc.bEndpointAddress; + stor_hs_bulk_out_desc.bEndpointAddress = + stor_fs_bulk_out_desc.bEndpointAddress; + stor_hs_intr_in_desc.bEndpointAddress = + stor_fs_intr_in_desc.bEndpointAddress; } if (gadget_is_otg(gadget)) - otg_desc.bmAttributes |= USB_OTG_HNP; + stor_otg_desc.bmAttributes |= USB_OTG_HNP; rc = -ENOMEM; @@ -4090,8 +3533,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) req->complete = ep0_complete; /* Allocate the data buffers */ - for (i = 0; i < NUM_BUFFERS; ++i) { - struct fsg_buffhd *bh = &fsg->buffhds[i]; + for (i = 0; i < STORAGE_NUM_BUFFERS; ++i) { + struct stor_buffhd *bh = &fsg->buffhds[i]; /* Allocate for the bulk-in endpoint. We assume that * the buffer will also work with the bulk-out (and @@ -4101,23 +3544,24 @@ static int __init fsg_bind(struct usb_gadget *gadget) goto out; bh->next = bh + 1; } - fsg->buffhds[NUM_BUFFERS - 1].next = &fsg->buffhds[0]; + fsg->buffhds[STORAGE_NUM_BUFFERS - 1].next = &fsg->buffhds[0]; /* This should reflect the actual gadget power source */ usb_gadget_set_selfpowered(gadget); - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); + snprintf(stor_string_manufacturer, sizeof stor_string_manufacturer, + "%s %s with %s", + init_utsname()->sysname, init_utsname()->release, + gadget->name); /* On a real device, serial[] would be loaded from permanent * storage. We just encode it from the driver version string. */ - for (i = 0; i < sizeof(serial) - 2; i += 2) { + for (i = 0; i < sizeof(stor_string_serial) - 2; i += 2) { unsigned char c = DRIVER_VERSION[i / 2]; if (!c) break; - sprintf(&serial[i], "%02X", c); + sprintf(&stor_string_serial[i], "%02X", c); } fsg->thread_task = kthread_create(fsg_main_thread, fsg, @@ -4127,13 +3571,13 @@ static int __init fsg_bind(struct usb_gadget *gadget) goto out; } - INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); - INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); + SINFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); + SINFO(fsg, "Number of LUNs=%d\n", fsg->nluns); pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; - if (backing_file_is_open(curlun)) { + if (stor_lun_is_open(curlun)) { p = NULL; if (pathbuf) { p = d_path(&curlun->filp->f_path, @@ -4147,16 +3591,16 @@ static int __init fsg_bind(struct usb_gadget *gadget) } kfree(pathbuf); - DBG(fsg, "transport=%s (x%02x)\n", - mod_data.transport_name, mod_data.transport_type); - DBG(fsg, "protocol=%s (x%02x)\n", - mod_data.protocol_name, mod_data.protocol_type); - DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", - mod_data.vendor, mod_data.product, mod_data.release); - DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", - mod_data.removable, mod_data.can_stall, - mod_data.cdrom, mod_data.buflen); - DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); + SDBG(fsg, "transport=%s (x%02x)\n", + mod_data.transport_name, mod_data.transport_type); + SDBG(fsg, "protocol=%s (x%02x)\n", + mod_data.protocol_name, mod_data.protocol_type); + SDBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", + mod_data.vendor, mod_data.product, mod_data.release); + SDBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", + mod_data.removable, mod_data.can_stall, + mod_data.cdrom, mod_data.buflen); + SDBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); set_bit(REGISTERED, &fsg->atomic_bitflags); @@ -4165,11 +3609,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) return 0; autoconf_fail: - ERROR(fsg, "unable to autoconfigure all endpoints\n"); + SERROR(fsg, "unable to autoconfigure all endpoints\n"); rc = -ENOTSUPP; out: - fsg->state = FSG_STATE_TERMINATED; // The thread is dead + fsg->state = STOR_STATE_TERMINATED; // The thread is dead fsg_unbind(gadget); complete(&fsg->thread_notifier); return rc; @@ -4182,7 +3626,7 @@ static void fsg_suspend(struct usb_gadget *gadget) { struct fsg_dev *fsg = get_gadget_data(gadget); - DBG(fsg, "suspend\n"); + SDBG(fsg, "suspend\n"); set_bit(SUSPENDED, &fsg->atomic_bitflags); } @@ -4190,7 +3634,7 @@ static void fsg_resume(struct usb_gadget *gadget) { struct fsg_dev *fsg = get_gadget_data(gadget); - DBG(fsg, "resume\n"); + SDBG(fsg, "resume\n"); clear_bit(SUSPENDED, &fsg->atomic_bitflags); } @@ -4203,7 +3647,7 @@ static struct usb_gadget_driver fsg_driver = { #else .speed = USB_SPEED_FULL, #endif - .function = (char *) longname, + .function = (char *)stor_string_product, .bind = fsg_bind, .unbind = fsg_unbind, .disconnect = fsg_disconnect, @@ -4212,7 +3656,7 @@ static struct usb_gadget_driver fsg_driver = { .resume = fsg_resume, .driver = { - .name = (char *) shortname, + .name = (char *) DRIVER_NAME, .owner = THIS_MODULE, // .release = ... // .suspend = ... diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c new file mode 100644 index 0000000..2c155e3 --- /dev/null +++ b/drivers/usb/gadget/storage_common.c @@ -0,0 +1,653 @@ +/* + * storage_common.c -- Common definitions for mass storage functionality. + * + * Copyright (C) 2003-2008 Alan Stern + * Copyeight (C) 2009 Samsung Electronics + * Author: Michal Nazarewicz (m.nazarewicz@xxxxxxxxxxx) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* + * This file requires the following identifiers used in USB strings to + * be defined (each of type pointer to char): + * - stor_string_manufacturer -- name of the manufacturer + * - stor_string_product -- name of the product + * - stor_string_serial -- product's serial + * - stor_string_config -- name of the configuration + * - stor_string_interface -- name of the interface + * The first four are only needed when STOR_DESCRIPTORS_DEVICE_STRINGS + * macro is defined prior to including this file. + * + * If STOR_DESCRIPTORS_DEVICE_STRINGS is defined, the file will define + * USB strings for manufacturer, product, serial and config. + * Otherwise, only interface string will be defined. (See end of the + * file if you are confused.) + * + * If STOR_DESCRIPTORS_INTR_EP is defined, the file will define + * an interrupt endpoint descriptor. Otherwise, it will be ommited. + * + * If STOR_BUFFHD_STATIC_BUFFER is defined, the struct stor_buffhd buf + * field will be an array of STORAGE_BUFFLEN chars rather then + * a pointer to void. + */ + + +#include <asm/unaligned.h> + + + +/* Thanks to NetChip Technologies for donating this product ID. + * + * DO NOT REUSE THESE IDs with any other driver!! Ever!! + * Instead: allocate your own, using normal USB-IF procedures. */ +/* NetChip */ +#define STORAGE_VENDOR_ID 0x0525 +/* Linux-USB File-backed Storage Gadget */ +#define STORAGE_PRODUCT_ID 0xa4a5 + + +#if !defined STORAGE_MAX_LUNS +# define STORAGE_MAX_LUNS 8 +#elif STORAGE_MAX_LUNS < 1 +# error STORAGE_MAX_LUNS < 1 +#endif + +/* Number of buffers we will use. 2 is enough for double-buffering */ +#if !defined STORAGE_NUM_BUFFERS +# define STORAGE_NUM_BUFFERS 2 +#elif STORAGE_NUM_BUFFERS < 2 +# error STORAGE_NUM_BUFFERS < 2 +#endif + + +/*-------------------------------------------------------------------------*/ + + +#ifndef DEBUG +#undef VERBOSE_DEBUG +#undef DUMP_MSGS +#endif /* !DEBUG */ + +#ifdef VERBOSE_DEBUG +#define VLDBG LDBG +#else +#define VLDBG(lun, fmt, args...) do { } while (0) +#endif /* VERBOSE_DEBUG */ + +#define LDBG(lun, fmt, args...) dev_dbg (&(lun)->dev, fmt, ## args) +#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args) +#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args) +#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args) + +#define SDBG(d, fmt, args...) dev_dbg (&(d)->gadget->dev, fmt, ## args) +#define VSDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev, fmt, ## args) +#define SERROR(d, fmt, args...) dev_err (&(d)->gadget->dev, fmt, ## args) +#define SWARN(d, fmt, args...) dev_warn(&(d)->gadget->dev, fmt, ## args) +#define SINFO(d, fmt, args...) dev_info(&(d)->gadget->dev, fmt, ## args) + + +#ifdef DUMP_MSGS + +# define dump_msg(instance, /* const char * */ label, /* const u8 * */ buf, /* unsigned */ length) \ + do if (length < 512) { \ + SDBG(instance, "%s, length %u:\n", label, length); \ + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \ + 16, 1, buf, length, 0); \ + } while (0) + +#else + +# define dump_msg(instance, /* const char * */ label, /* const u8 * */ buf, /* unsigned */ length) do { } while (0) + +#endif /* DUMP_MSGS */ + + +/*-------------------------------------------------------------------------*/ + + +/* SCSI device types */ +#define TYPE_DISK 0x00 +#define TYPE_CDROM 0x05 + +/* USB protocol value = the transport method */ +#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */ +#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */ +#define USB_PR_BULK 0x50 /* Bulk-only */ + +/* USB subclass value = the protocol encapsulation */ +#define USB_SC_RBC 0x01 /* Reduced Block Commands (flash) */ +#define USB_SC_8020 0x02 /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */ +#define USB_SC_QIC 0x03 /* QIC-157 (tape) */ +#define USB_SC_UFI 0x04 /* UFI (floppy) */ +#define USB_SC_8070 0x05 /* SFF-8070i (removable) */ +#define USB_SC_SCSI 0x06 /* Transparent SCSI */ + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct stor_bulk_cb_wrap { + __le32 Signature; /* Contains 'USBC' */ + u32 Tag; /* Unique per command id */ + __le32 DataTransferLength; /* Size of the data */ + u8 Flags; /* Direction in bit 7 */ + u8 Lun; /* LUN (normally 0) */ + u8 Length; /* Of the CDB, <= MAX_COMMAND_SIZE */ + u8 CDB[16]; /* Command Data Block */ +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355 /* Spells out USBC */ +#define USB_BULK_IN_FLAG 0x80 + +/* Command Status Wrapper */ +struct stor_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 stor_interrupt_data { + u8 bType; + u8 bValue; +}; + +#define CBI_INTERRUPT_DATA_LEN 2 + +/* CBI Accept Device-Specific Command request */ +#define USB_CBI_ADSC_REQUEST 0x00 + + +/* Length of a SCSI Command Data Block */ +#define MAX_COMMAND_SIZE 16 + +/* 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_READ_HEADER 0x44 +#define SC_READ_TOC 0x43 +#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)) + + +/*-------------------------------------------------------------------------*/ + + +struct storage_lun { + struct file *filp; + loff_t file_length; + loff_t num_sectors; + + unsigned int ro : 1; + unsigned int removable : 1; + unsigned int cdrom : 1; + unsigned int prevent_medium_removal : 1; + unsigned int registered : 1; + unsigned int info_valid : 1; + + u32 sense_data; + u32 sense_data_info; + u32 unit_attention_data; + + struct device dev; +}; + + +static inline int stor_lun_is_open(struct storage_lun *lun) +{ + return lun->filp != 0; +} + +static int stor_lun_open(struct storage_lun *curlun, const char *filename); +static void stor_lun_close(struct storage_lun *lun); +static int stor_lun_fsync_sub(struct storage_lun *curlun); + +static struct storage_lun *stor_lun_from_dev(struct device *dev) +{ + return container_of(dev, struct storage_lun, dev); +} + + +/*-------------------------------------------------------------------------*/ + + +/* Big enough to hold our biggest descriptor */ +#define EP0_BUFSIZE 256 +#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ + +enum stor_buffer_state { + BUF_STATE_EMPTY = 0, + BUF_STATE_FULL, + BUF_STATE_BUSY +}; + +struct stor_buffhd { +#ifdef STOR_BUFFHD_STATIC_BUFFER + char buf[STORAGE_BUFLEN]; +#else + void *buf; +#endif + enum stor_buffer_state state; + struct stor_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; + int inreq_busy; + struct usb_request *outreq; + int outreq_busy; +}; + +enum stor_state { + STOR_STATE_COMMAND_PHASE = -10, /* This one isn't used anywhere */ + STOR_STATE_DATA_PHASE, + STOR_STATE_STATUS_PHASE, + + STOR_STATE_IDLE = 0, + STOR_STATE_ABORT_BULK_OUT, + STOR_STATE_RESET, + STOR_STATE_INTERFACE_CHANGE, + STOR_STATE_CONFIG_CHANGE, + STOR_STATE_DISCONNECT, + STOR_STATE_EXIT, + STOR_STATE_TERMINATED +}; + +enum stor_data_direction { + DATA_DIR_UNKNOWN = 0, + DATA_DIR_FROM_HOST, + DATA_DIR_TO_HOST, + DATA_DIR_NONE +}; + + +/*-------------------------------------------------------------------------*/ + +/* Routines for unaligned data access */ + +static u32 get_unaligned_be24(u8 *buf) +{ + return 0xffffff & (u32) get_unaligned_be32(buf - 1); +} + + + +/*-------------------------------------------------------------------------*/ + + +/* If the next two routines are called while the gadget is registered, + * the caller must own fsg->filesem for writing. */ + +static int stor_lun_open(struct storage_lun *curlun, const char *filename) +{ + int ro; + struct file *filp = NULL; + int rc = -EINVAL; + struct inode *inode = NULL; + loff_t size; + loff_t num_sectors; + loff_t min_sectors; + + /* R/W if we can, R/O if we must */ + ro = curlun->ro; + if (!ro) { + filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); + if (-EROFS == PTR_ERR(filp)) + ro = 1; + } + if (ro) + filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(filp)) { + LINFO(curlun, "unable to open backing file: %s\n", filename); + return PTR_ERR(filp); + } + + if (!(filp->f_mode & FMODE_WRITE)) + ro = 1; + + if (filp->f_path.dentry) + inode = filp->f_path.dentry->d_inode; + if (inode && S_ISBLK(inode->i_mode)) { + if (bdev_read_only(inode->i_bdev)) + ro = 1; + } else if (!inode || !S_ISREG(inode->i_mode)) { + LINFO(curlun, "invalid file type: %s\n", filename); + goto out; + } + + /* If we can't read the file, it's no good. + * If we can't write the file, use it read-only. */ + if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) { + LINFO(curlun, "file not readable: %s\n", filename); + goto out; + } + if (!(filp->f_op->write || filp->f_op->aio_write)) + ro = 1; + + size = i_size_read(inode->i_mapping->host); + if (size < 0) { + LINFO(curlun, "unable to find file size: %s\n", filename); + rc = (int) size; + goto out; + } + num_sectors = size >> 9; /* File size in 512-byte blocks */ + min_sectors = 1; + if (curlun->cdrom) { + num_sectors &= ~3; /* Reduce to a multiple of 2048 */ + min_sectors = 300*4; /* Smallest track is 300 frames */ + if (num_sectors >= 256*60*75*4) { + num_sectors = (256*60*75 - 1) * 4; + LINFO(curlun, "file too big: %s\n", filename); + LINFO(curlun, "using only first %d blocks\n", + (int) num_sectors); + } + } + if (num_sectors < min_sectors) { + LINFO(curlun, "file too small: %s\n", filename); + rc = -ETOOSMALL; + goto out; + } + + get_file(filp); + curlun->ro = ro; + curlun->filp = filp; + curlun->file_length = size; + curlun->num_sectors = num_sectors; + LDBG(curlun, "open backing file: %s\n", filename); + rc = 0; + +out: + filp_close(filp, current->files); + return rc; +} + + +static void stor_lun_close(struct storage_lun *curlun) +{ + if (curlun->filp) { + LDBG(curlun, "close backing file\n"); + fput(curlun->filp); + curlun->filp = NULL; + } +} + + +/* Sync the file data, don't bother with the metadata. + * This code was copied from fs/buffer.c:sys_fdatasync(). */ +static int stor_lun_fsync_sub(struct storage_lun *curlun) +{ + struct file *filp = curlun->filp; + + if (curlun->ro || !filp) + return 0; + return vfs_fsync(filp, filp->f_path.dentry, 1); +} + + + +/*-------------------------------------------------------------------------*/ + + +static void store_cdrom_address(u8 *dest, int msf, u32 addr) +{ + if (msf) { + /* Convert to Minutes-Seconds-Frames */ + addr >>= 2; /* Convert to 2048-byte frames */ + addr += 2*75; /* Lead-in occupies 2 seconds */ + dest[3] = addr % 75; /* Frames */ + addr /= 75; + dest[2] = addr % 60; /* Seconds */ + addr /= 60; + dest[1] = addr; /* Minutes */ + dest[0] = 0; /* Reserved */ + } else { + /* Absolute sector */ + put_unaligned_be32(addr, dest); + } +} + + + + +/*-------------------------------------------------------------------------*/ + + +enum { +#ifdef STOR_DESCRIPTORS_DEVICE_STRINGS + STOR_STRING_MANUFACTURER = 1, + STOR_STRING_PRODUCT, + STOR_STRING_SERIAL, + STOR_STRING_CONFIG, +#endif + /* As a side effect, when STOR_DESCRIPTORS_DEVICE_STRINGS is + * set STOR_STRING_INTERFACE equals 5 whereas, if it's not + * defined, it equals 0. */ + STOR_STRING_INTERFACE +}; + + +static struct usb_otg_descriptor +stor_otg_desc = { + .bLength = sizeof stor_otg_desc, + .bDescriptorType = USB_DT_OTG, + + .bmAttributes = USB_OTG_SRP, +}; + +/* There is only one interface. */ + +static struct usb_interface_descriptor +stor_intf_desc = { + .bLength = sizeof stor_intf_desc, + .bDescriptorType = USB_DT_INTERFACE, + + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = USB_SC_SCSI, + .bInterfaceProtocol = USB_PR_BULK, + .iInterface = STOR_STRING_INTERFACE, +}; + +/* Three full-speed endpoint descriptors: bulk-in, bulk-out, + * and interrupt-in. */ + +static struct usb_endpoint_descriptor +stor_fs_bulk_in_desc = { + .bLength = sizeof stor_fs_bulk_in_desc, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + /* wMaxPacketSize set by autoconfiguration */ +}; + +static struct usb_endpoint_descriptor +stor_fs_bulk_out_desc = { + .bLength = sizeof stor_fs_bulk_out_desc, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + /* wMaxPacketSize set by autoconfiguration */ +}; + +#ifdef STOR_DESCRIPTORS_INTR_EP + +static struct usb_endpoint_descriptor +stor_fs_intr_in_desc = { + .bLength = sizeof stor_fs_intr_in_desc, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(2), + .bInterval = 32, /* frames -> 32 ms */ +}; + +#endif + +static const struct usb_descriptor_header *stor_fs_function[] = { + (struct usb_descriptor_header *) &stor_otg_desc, + (struct usb_descriptor_header *) &stor_intf_desc, + (struct usb_descriptor_header *) &stor_fs_bulk_in_desc, + (struct usb_descriptor_header *) &stor_fs_bulk_out_desc, +#ifdef STOR_DESCRIPTORS_INTR_EP + (struct usb_descriptor_header *) &stor_fs_intr_in_desc, +#endif + NULL, +}; + +#define STOR_FS_FUNCTION_PRE_EP_ENTRIES 2 + + +/* + * USB 2.0 devices need to expose both high speed and full speed + * descriptors, unless they only run at full speed. + * + * That means alternate endpoint descriptors (bigger packets) + * and a "device qualifier" ... plus more construction options + * for the config descriptor. + */ + +static struct usb_endpoint_descriptor +stor_hs_bulk_in_desc = { + .bLength = sizeof stor_hs_bulk_in_desc, + .bDescriptorType = USB_DT_ENDPOINT, + + /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), +}; + +static struct usb_endpoint_descriptor +stor_hs_bulk_out_desc = { + .bLength = sizeof stor_hs_bulk_out_desc, + .bDescriptorType = USB_DT_ENDPOINT, + + /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), + .bInterval = 1, /* NAK every 1 uframe */ +}; + +#ifdef STOR_DESCRIPTORS_INTR_EP + +static struct usb_endpoint_descriptor +stor_hs_intr_in_desc = { + .bLength = sizeof stor_hs_intr_in_desc, + .bDescriptorType = USB_DT_ENDPOINT, + + /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(2), + .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ +}; + +#endif + +static const struct usb_descriptor_header *stor_hs_function[] = { + (struct usb_descriptor_header *) &stor_otg_desc, + (struct usb_descriptor_header *) &stor_intf_desc, + (struct usb_descriptor_header *) &stor_hs_bulk_in_desc, + (struct usb_descriptor_header *) &stor_hs_bulk_out_desc, +#ifdef STOR_DESCRIPTORS_INTR_EP + (struct usb_descriptor_header *) &stor_hs_intr_in_desc, +#endif + NULL, +}; +#define STOR_HS_FUNCTION_PRE_EP_ENTRIES 2 + + +/* Maxpacket and other transfer characteristics vary by speed. */ +static struct usb_endpoint_descriptor * +ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, + struct usb_endpoint_descriptor *hs) +{ + return gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH ? hs : fs; +} + + +/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ +static struct usb_string stor_strings[] = { +#ifdef STOR_DESCRIPTORS_DEVICE_STRINGS + {STOR_STRING_MANUFACTURER, stor_string_manufacturer}, + {STOR_STRING_PRODUCT, stor_string_product}, + {STOR_STRING_SERIAL, stor_string_serial}, + {STOR_STRING_CONFIG, stor_string_config}, +#endif + {STOR_STRING_INTERFACE, stor_string_interface}, + {} +}; + +static struct usb_gadget_strings stor_stringtab = { + .language = 0x0409, /* en-us */ + .strings = stor_strings, +}; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html