Mass Storage Gadget (MSG)¶
Overview¶
Mass Storage Gadget (or MSG) acts as a USB Mass Storage device,appearing to the host as a disk or a CD-ROM drive. It supportsmultiple logical units (LUNs). Backing storage for each LUN isprovided by a regular file or a block device, access can be limitedto read-only, and gadget can indicate that it is removable and/orCD-ROM (the latter implies read-only access).
Its requirements are modest; only a bulk-in and a bulk-out endpointare needed. The memory requirement amounts to two 16K buffers.Support is included for full-speed, high-speed and SuperSpeedoperation.
Note that the driver is slightly non-portable in that it assumesa single memory/DMA buffer will be usable for bulk-in and bulk-outendpoints. With most device controllers this is not an issue, butthere may be some with hardware restrictions that prevent a bufferfrom being used by more than one endpoint.
This document describes how to use the gadget from user space, itsrelation to mass storage function (or MSF) and different gadgetsusing it, and how it differs from File Storage Gadget (or FSG)(which is no longer included in Linux). It will talk only brieflyabout how to use MSF within composite gadgets.
Module parameters¶
The mass storage gadget accepts the following mass storage specificmodule parameters:
file=filename[,filename…]
This parameter lists paths to files or block devices used forbacking storage for each logical unit. There may be at mostFSG_MAX_LUNS (8) LUNs set. If more files are specified, they willbe silently ignored. See also “luns” parameter.
BEWARE that if a file is used as a backing storage, it may notbe modified by any other process. This is because the hostassumes the data does not change without its knowledge. It may beread, but (if the logical unit is writable) due to buffering onthe host side, the contents are not well defined.
The size of the logical unit will be rounded down to a fulllogical block. The logical block size is 2048 bytes for LUNssimulating CD-ROM, block size of the device if the backing file isa block device, or 512 bytes otherwise.
removable=b[,b…]
This parameter specifies whether each logical unit should beremovable. “b” here is either “y”, “Y” or “1” for true or “n”,“N” or “0” for false.
If this option is set for a logical unit, gadget will accept an“eject” SCSI request (Start/Stop Unit). When it is sent, thebacking file will be closed to simulate ejection and the logicalunit will not be mountable by the host until a new backing file isspecified by userspace on the device (see “sysfs entries”section).
If a logical unit is not removable (the default), a backing filemust be specified for it with the “file” parameter as the moduleis loaded. The same applies if the module is built in, noexceptions.
The default value of the flag is false,HOWEVER it used to betrue. This has been changed to better match File Storage Gadgetand because it seems like a saner default after all. Thus tomaintain compatibility with older kernels, it’s best to specifythe default values. Also, if one relied on old default, explicit“n” needs to be specified now.
Note that “removable” means the logical unit’s media can beejected or removed (as is true for a CD-ROM drive or a cardreader). It doesnot mean that the entire gadget can beunplugged from the host; the proper term for that is“hot-unpluggable”.
cdrom=b[,b…]
This parameter specifies whether each logical unit should simulateCD-ROM. The default is false.
ro=b[,b…]
This parameter specifies whether each logical unit should bereported as read only. This will prevent host from modifying thebacking files.
Note that if this flag for given logical unit is false but thebacking file could not be opened in read/write mode, the gadgetwill fall back to read only mode anyway.
The default value for non-CD-ROM logical units is false; forlogical units simulating CD-ROM it is forced to true.
nofua=b[,b…]
This parameter specifies whether FUA flag should be ignored in SCSIWrite10 and Write12 commands sent to given logical units.
MS Windows mounts removable storage in “Removal optimised mode” bydefault. All the writes to the media are synchronous, which isachieved by setting the FUA (Force Unit Access) bit in SCSIWrite(10,12) commands. This forces each write to wait until thedata has actually been written out and prevents I/O requestsaggregation in block layer dramatically decreasing performance.
Note that this may mean that if the device is powered from USB andthe user unplugs the device without unmounting it first (which atleast some Windows users do), the data may be lost.
The default value is false.
luns=N
This parameter specifies number of logical units the gadget willhave. It is limited by FSG_MAX_LUNS (8) and higher value will becapped.
If this parameter is provided, and the number of files specifiedin “file” argument is greater then the value of “luns”, all excessfiles will be ignored.
If this parameter is not present, the number of logical units willbe deduced from the number of files specified in the “file”parameter. If the file parameter is missing as well, one isassumed.
stall=b
Specifies whether the gadget is allowed to halt bulk endpoints.The default is determined according to the type of USB devicecontroller, but usually true.
In addition to the above, the gadget also accepts the followingparameters defined by the composite framework (they are common toall composite gadgets so just a quick listing):
- idVendor – USB Vendor ID (16 bit integer)
- idProduct – USB Product ID (16 bit integer)
- bcdDevice – USB Device version (BCD) (16 bit integer)
- iManufacturer – USB Manufacturer string (string)
- iProduct – USB Product string (string)
- iSerialNumber – SerialNumber string (sting)
sysfs entries¶
For each logical unit, the gadget creates a directory in the sysfshierarchy. Inside of it the following three files are created:
file
When read it returns the path to the backing file for the givenlogical unit. If there is no backing file (possible only if thelogical unit is removable), the content is empty.
When written into, it changes the backing file for given logicalunit. This change can be performed even if given logical unit isnot specified as removable (but that may look strange to thehost). It may fail, however, if host disallowed medium removalwith the Prevent-Allow Medium Removal SCSI command.
ro
Reflects the state of ro flag for the given logical unit. It canbe read any time, and written to when there is no backing fileopen for given logical unit.
nofua
Reflects the state of nofua flag for given logical unit. It canbe read and written.
Other then those, as usual, the values of module parameters can beread from /sys/module/g_mass_storage/parameters/* files.
Other gadgets using mass storage function¶
The Mass Storage Gadget uses the Mass Storage Function to handlemass storage protocol. As a composite function, MSF may be used byother gadgets as well (eg. g_multi and acm_ms).
All of the information in previous sections are valid for othergadgets using MSF, except that support for mass storage relatedmodule parameters may be missing, or the parameters may havea prefix. To figure out whether any of this is true one needs toconsult the gadget’s documentation or its source code.
For examples of how to include mass storage function in gadgets, onemay take a look at mass_storage.c, acm_ms.c and multi.c (sorted bycomplexity).
Relation to file storage gadget¶
The Mass Storage Function and thus the Mass Storage Gadget has beenbased on the File Storage Gadget. The difference between the two isthat MSG is a composite gadget (ie. uses the composite framework)while file storage gadget was a traditional gadget. From userspacepoint of view this distinction does not really matter, but fromkernel hacker’s point of view, this means that (i) MSG does notduplicate code needed for handling basic USB protocol commands and(ii) MSF can be used in any other composite gadget.
Because of that, File Storage Gadget has been removed in Linux 3.8.All users need to transition to the Mass Storage Gadget. The twogadgets behave mostly the same from the outside except:
- In FSG the “removable” and “cdrom” module parameters set the flagfor all logical units whereas in MSG they accept a list of y/nvalues for each logical unit. If one uses only a single logicalunit this does not matter, but if there are more, the y/n valueneeds to be repeated for each logical unit.
- FSG’s “serial”, “vendor”, “product” and “release” moduleparameters are handled in MSG by the composite layer’s parametersnamed respectively: “iSerialnumber”, “idVendor”, “idProduct” and“bcdDevice”.
- MSG does not support FSG’s test mode, thus “transport”,“protocol” and “buflen” FSG’s module parameters are notsupported. MSG always uses SCSI protocol with bulk onlytransport mode and 16 KiB buffers.