Difference between revisions of "Unit Storage"
Line 340: | Line 340: | ||
---- | ---- | ||
− | '' | + | |
+ | '''Storage enumeration callback''' | ||
+ | |||
+ | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" | ||
+ | |- | ||
+ | | <code>TStorageEnumerate = function(Storage:PStorageDevice; Data:Pointer):LongWord;</code> | ||
+ | | style="width: 40%;"| | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | '''Storage notification callback''' | ||
+ | |||
+ | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" | ||
+ | |- | ||
+ | | <code>TStorageNotification = function(Device:PDevice; Data:Pointer; Notification:LongWord):LongWord;</code> | ||
+ | | style="width: 40%;"| | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | '''Storage device read''' | ||
+ | |||
+ | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" | ||
+ | |- | ||
+ | | <code>TStorageDeviceRead = function(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;</code> | ||
+ | | style="width: 40%;"| | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | '''Storage device write''' | ||
+ | |||
+ | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" | ||
+ | |- | ||
+ | | <code>TStorageDeviceWrite = function(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;</code> | ||
+ | | style="width: 40%;"| | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | '''Storage device erase''' | ||
+ | |||
+ | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" | ||
+ | |- | ||
+ | | <code>TStorageDeviceErase = function(Storage:PStorageDevice; const Start,Count:Int64):LongWord;</code> | ||
+ | | style="width: 40%;"| | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | '''Storage device control''' | ||
+ | |||
+ | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" | ||
+ | |- | ||
+ | | <code>TStorageDeviceControl = function(Storage:PStorageDevice; Request:Integer; Argument1:LongWord; var Argument2:LongWord):LongWord;</code> | ||
+ | | style="width: 40%;"| | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | '''Storage device''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PStorageDevice = ^TStorageDevice;</code> | ||
+ | |||
+ | <code>TStorageDevice = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''Device Properties'' | ||
+ | |- | ||
+ | | <code>Device:TDevice;</code> | ||
+ | | The Device entry for this Storage | ||
+ | |- | ||
+ | |colspan="2"|''Storage Properties'' | ||
+ | |- | ||
+ | | <code>StorageId:LongWord;</code> | ||
+ | | Unique Id of this Storage in the Storage table | ||
+ | |- | ||
+ | | <code>StorageState:LongWord;</code> | ||
+ | | Storage state (eg STORAGE_STATE_INSERTED) | ||
+ | |- | ||
+ | | <code>DeviceRead:TStorageDeviceRead;</code> | ||
+ | | A Device specific DeviceRead method implementing a standard Storage device interface | ||
+ | |- | ||
+ | | <code>DeviceWrite:TStorageDeviceWrite;</code> | ||
+ | | A Device specific DeviceWrite method implementing a standard Storage device interface | ||
+ | |- | ||
+ | | <code>DeviceErase:TStorageDeviceErase;</code> | ||
+ | | A Device specific DeviceErase method implementing a standard Storage device interface | ||
+ | |- | ||
+ | | <code>DeviceControl:TStorageDeviceControl;</code> | ||
+ | | A Device specific DeviceControl method implementing a standard Storage device interface | ||
+ | |- | ||
+ | |colspan="2"|''Driver Properties'' | ||
+ | |- | ||
+ | | <code>Lock:TMutexHandle;</code> | ||
+ | | Storage lock | ||
+ | |- | ||
+ | | <code>TargetID:LongWord;</code> | ||
+ | | SCSI ID | ||
+ | |- | ||
+ | | <code>TargetLUN:LongWord;</code> | ||
+ | | LUN | ||
+ | |- | ||
+ | | <code>BlockSize:LongWord;</code> | ||
+ | | Block Size | ||
+ | |- | ||
+ | | <code>BlockCount:Int64;</code> | ||
+ | | Number of Blocks | ||
+ | |- | ||
+ | | <code>BlockShift:LongWord;</code> | ||
+ | | Shift Count for Blocks to Bytes conversion (eg 9 for 512 byte blocks) | ||
+ | |- | ||
+ | | <code>Vendor:PChar;</code> | ||
+ | | ATA Model, SCSI Vendor | ||
+ | |- | ||
+ | | <code>Product:PChar;</code> | ||
+ | | ATA Serial No, SCSI Product | ||
+ | |- | ||
+ | | <code>Revision:PChar;</code> | ||
+ | | Firmware Revision | ||
+ | |- | ||
+ | | <code>StatusTimer:TTimerHandle;</code> | ||
+ | | Timer for status change detection | ||
+ | |- | ||
+ | |colspan="2"|''Statistics Properties'' | ||
+ | |- | ||
+ | | <code>ReadCount:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ReadErrors:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>WriteCount:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>WriteErrors:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>EraseCount:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>EraseErrors:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"|''Internal Properties'' | ||
+ | |- | ||
+ | | <code>Prev:PStorageDevice;</code> | ||
+ | | Previous entry in Storage table | ||
+ | |- | ||
+ | | <code>Next:PStorageDevice;</code> | ||
+ | | Next entry in Storage table | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''USB command block''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PUSBCommandBlock = ^TUSBCommandBlock;</code> | ||
+ | |||
+ | <code>TUSBCommandBlock = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|Note: SBC Command Block (Derived from TSCSICommandBlock) | ||
+ | |- | ||
+ | |colspan="2"|''SCSI Properties'' | ||
+ | |- | ||
+ | | <code>Command:array[0..USB_STORAGE_COMMAND_MAX_SIZE - 1] of Byte;</code> | ||
+ | | Command | ||
+ | |- | ||
+ | | <code>SenseData:array[0..63] of Byte;</code> | ||
+ | | Request Sense | ||
+ | |- | ||
+ | | <code>Status:Byte;</code> | ||
+ | | SCSI Status | ||
+ | |- | ||
+ | | <code>TargetID:Byte;</code> | ||
+ | | Target ID | ||
+ | |- | ||
+ | | <code>TargetLUN:Byte;</code> | ||
+ | | Target LUN | ||
+ | |- | ||
+ | | <code>CommandLength:Byte;</code> | ||
+ | | Command Length | ||
+ | |- | ||
+ | | <code>DataLength:LongWord;</code> | ||
+ | | Data Length | ||
+ | |- | ||
+ | | <code>Data:Pointer;</code> | ||
+ | | Pointer to Data | ||
+ | |- | ||
+ | | <code>MessageOut:array[0..11] of Byte;</code> | ||
+ | | Message out buffer | ||
+ | |- | ||
+ | | <code>MessageIn:array[0..11] of Byte;</code> | ||
+ | | Message in buffer | ||
+ | |- | ||
+ | | <code>SenseCommandLength:Byte;</code> | ||
+ | | Sense Command Length | ||
+ | |- | ||
+ | | <code>SenseDataLength:LongWord;</code> | ||
+ | | Sense Data Length | ||
+ | |- | ||
+ | | <code>SenseCommand:array[0..5] of Byte;</code> | ||
+ | | Sense Command | ||
+ | |- | ||
+ | | <code>ControllerStatus:LongWord;</code> | ||
+ | | Controller Status | ||
+ | |- | ||
+ | | <code>TransferredBytes:LongWord;</code> | ||
+ | | Transferred Bytes | ||
+ | |- | ||
+ | |colspan="2"|''USB Properties'' | ||
+ | |- | ||
+ | | <code>Direction:Byte;</code> | ||
+ | | USB Direction (eg USB_DIRECTION_OUT or USB_DIRECTION_IN) | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''USB storage device''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PUSBStorageDevice = ^TUSBStorageDevice;</code> | ||
+ | |||
+ | <code>TUSBStorageDevice = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''Storage Properties'' | ||
+ | |- | ||
+ | | <code>Storage:TStorageDevice;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"|''USB Properties'' | ||
+ | |- | ||
+ | | <code>Subclass:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Protocol:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>MaxLUN:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Sequence:LongWord;</code> | ||
+ | | For dCBWTag property | ||
+ | |- | ||
+ | | <code>Primary:PUSBStorageDevice;</code> | ||
+ | | Primary storage device (for multi LUN devices) | ||
+ | |- | ||
+ | | <code>StorageInterface:PUSBInterface;</code> | ||
+ | | USB Mass Storage device Interface | ||
+ | |- | ||
+ | | <code>ReadWait:TSemaphoreHandle;</code> | ||
+ | | Read completed semaphore | ||
+ | |- | ||
+ | | <code>WriteWait:TSemaphoreHandle;</code> | ||
+ | | Write completed semaphore | ||
+ | |- | ||
+ | | <code>InterruptWait:TSemaphoreHandle;</code> | ||
+ | | Interrupt completed semaphore | ||
+ | |- | ||
+ | | <code>ReadRequest:PUSBRequest;</code> | ||
+ | | Bulk IN Request | ||
+ | |- | ||
+ | | <code>WriteRequest:PUSBRequest;</code> | ||
+ | | Bulk OUT Request | ||
+ | |- | ||
+ | | <code>InterruptRequest:PUSBRequest;</code> | ||
+ | | Interrupt IN Request | ||
+ | |- | ||
+ | | <code>ReadEndpoint:PUSBEndpointDescriptor;</code> | ||
+ | | Bulk IN Endpoint | ||
+ | |- | ||
+ | | <code>WriteEndpoint:PUSBEndpointDescriptor;</code> | ||
+ | | Bulk OUT Endpoint | ||
+ | |- | ||
+ | | <code>InterruptEndpoint:PUSBEndpointDescriptor;</code> | ||
+ | | Interrupt IN Endpoint | ||
+ | |- | ||
+ | | <code>PendingCount:LongWord;</code> | ||
+ | | Number of USB requests pending for this storage | ||
+ | |- | ||
+ | | <code>WaiterThread:TThreadId;</code> | ||
+ | | Thread waiting for pending requests to complete (for storage eject) | ||
+ | |- | ||
+ | |colspan="2"|''SCSI Properties'' | ||
+ | |- | ||
+ | | <code>CommandBlock:TUSBCommandBlock;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"|''ATAPI Properties'' | ||
+ | |- | ||
+ | | | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |colspan="2"|''RBC Properties'' | ||
+ | |- | ||
+ | | | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''USB command block wrapper''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PUSBCommandBlockWrapper = ^TUSBCommandBlockWrapper;</code> | ||
+ | |||
+ | <code>TUSBCommandBlockWrapper = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>dCBWSignature:LongWord;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>dCBWTag:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>dCBWDataTransferLength:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>bCBWFlags:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>bCBWLUN:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>bCBWCBLength:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>CBWCB:array[0..USB_STORAGE_CBW_CB_LENGTH - 1] of Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''USB command status wrapper''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PUSBCommandStatusWrapper = ^TUSBCommandStatusWrapper;</code> | ||
+ | |||
+ | <code>TUSBCommandStatusWrapper = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>dCSWSignature:LongWord;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>dCSWTag:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>dCSWDataResidue:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>bCSWStatus:Byte;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Public variables === | === Public variables === |
Revision as of 04:48, 25 January 2017
Return to Unit Reference
Contents
[hide]Description
Ultibo Storage interface unit
This unit provides both the Storage device interface and the generic USB mass storage driver.
USB Mass Storage Devices
The USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport specification is approved for use only with full-speed floppy disk drives. CBI shall not be used in high-speed capable devices, or in devices other than floppy disk drives. CBI shall not be used in devices that implement LSDFS. Usage of CBI for any new design is discouraged.
Therefore the majority of USB Mass Storage devices use the Bulk only interface.
USB mass storage class devices normally use the SCSI command set and therefore the USB storage driver consumes the SCSI unit for the protocol and command definitions. USB mass storage devices are registered directly as Storage devices not as SCSI devices.
Constants
STORAGE_*
STORAGE_TYPE_*
STORAGE_STATE_*
STORAGE_FLAG_*
STORAGE_CONTROL_*
STORAGE_LOG_*
USB_STORAGE_*
Type definitions
Storage enumeration callback
TStorageEnumerate = function(Storage:PStorageDevice; Data:Pointer):LongWord;
|
Storage notification callback
TStorageNotification = function(Device:PDevice; Data:Pointer; Notification:LongWord):LongWord;
|
Storage device read
TStorageDeviceRead = function(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
|
Storage device write
TStorageDeviceWrite = function(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
|
Storage device erase
TStorageDeviceErase = function(Storage:PStorageDevice; const Start,Count:Int64):LongWord;
|
Storage device control
TStorageDeviceControl = function(Storage:PStorageDevice; Request:Integer; Argument1:LongWord; var Argument2:LongWord):LongWord;
|
Storage device
USB command block
USB storage device
USB command block wrapper
USB command status wrapper
Public variables
Storage logging
STORAGE_DEFAULT_LOG_LEVEL:LongWord = STORAGE_LOG_LEVEL_DEBUG;
|
Minimum level for Storage messages. Only messages with level greater than or equal to this will be printed. |
STORAGE_LOG_ENABLED:Boolean;
|
Function declarations
Initialization functions
Storage functions
function StorageDeviceRead(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
function StorageDeviceWrite(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
function StorageDeviceErase(Storage:PStorageDevice; const Start,Count:Int64):LongWord;
function StorageDeviceControl(Storage:PStorageDevice; Request:Integer; Argument1:LongWord; var Argument2:LongWord):LongWord;
function StorageDeviceSetState(Storage:PStorageDevice; State:LongWord):LongWord;
function StorageDeviceStartStatus(Storage:PStorageDevice; Interval:LongWord):LongWord;
function StorageDeviceStopStatus(Storage:PStorageDevice):LongWord;
function StorageDeviceCreateEx(Size:LongWord):PStorageDevice;
function StorageDeviceDestroy(Storage:PStorageDevice):LongWord;
function StorageDeviceRegister(Storage:PStorageDevice):LongWord;
function StorageDeviceDeregister(Storage:PStorageDevice):LongWord;
function StorageDeviceFind(StorageId:LongWord):PStorageDevice;
function StorageDeviceFindByName(const Name:String):PStorageDevice; inline;
function StorageDeviceFindByDescription(const Description:String):PStorageDevice; inline;
function StorageDeviceEnumerate(Callback:TStorageEnumerate; Data:Pointer):LongWord;
function StorageDeviceNotification(Storage:PStorageDevice; Callback:TStorageNotification; Data:Pointer; Notification,Flags:LongWord):LongWord;
USB storage functions
function USBStorageDeviceRead(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
function USBStorageDeviceWrite(Storage:PStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
function USBStorageDeviceControl(Storage:PStorageDevice; Request:Integer; Argument1:LongWord; var Argument2:LongWord):LongWord;
function USBStorageDriverBind(Device:PUSBDevice; Interrface:PUSBInterface):LongWord;
function USBStorageDriverUnbind(Device:PUSBDevice; Interrface:PUSBInterface):LongWord;
procedure USBStorageReadComplete(Request:PUSBRequest);
procedure USBStorageWriteComplete(Request:PUSBRequest);
procedure USBStorageInterruptComplete(Request:PUSBRequest);
Storage helper functions
function StorageDeviceCheck(Storage:PStorageDevice):PStorageDevice;
function StorageDeviceTypeToString(StorageType:LongWord):String;
function StorageDeviceStateToString(StorageState:LongWord):String;
function StorageDeviceStateToNotification(State:LongWord):LongWord;
procedure StorageLog(Level:LongWord; Storage:PStorageDevice; const AText:String);
procedure StorageLogInfo(Storage:PStorageDevice; const AText:String);
procedure StorageLogError(Storage:PStorageDevice; const AText:String);
procedure StorageLogDebug(Storage:PStorageDevice; const AText:String);
USB storage helper functions
function USBStorageBlockSizeToBlockShift(BlockSize:LongWord):LongWord;
function USBStoragePatchDevice(Device:PUSBDevice; var Subclass,Protocol:Byte):LongWord;
function USBStorageFixupDevice(Device:PUSBDevice; var Vendor,Product:String):LongWord;
function USBStorageDeviceLock(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceUnlock(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceLoad(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceEject(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceReset(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceGetInfo(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceGetStatus(Device:PUSBDevice; Storage:PUSBStorageDevice):LongWord;
function USBStorageDeviceGetMaxLUN(Device:PUSBDevice; Storage:PUSBStorageDevice; var MaxLUN:Byte):LongWord;
function USBStorageDeviceClearStall(Device:PUSBDevice; Storage:PUSBStorageDevice; Endpoint:PUSBEndpointDescriptor):LongWord;
function USBStorageDeviceInquiry(Device:PUSBDevice; Storage:PUSBStorageDevice; var DeviceType,DeviceFlags:LongWord;v ar Vendor,Product,Revision:PChar):LongWord;
function USBStorageDeviceRequestSense(Device:PUSBDevice; Storage:PUSBStorageDevice; var SenseKey,ASC,ASCQ:Byte):LongWord;
function USBStorageDeviceReadCapacity(Device:PUSBDevice; Storage:PUSBStorageDevice; var BlockSize,BlockShift:LongWord; var BlockCount:Int64):LongWord;
function USBStorageDeviceTestUnitReady(Device:PUSBDevice; Storage:PUSBStorageDevice; var DeviceFlags:LongWord):LongWord;
function USBStorageDeviceRead10(Device:PUSBDevice; Storage:PUSBStorageDevice; Start:LongWord;Count:Word; Buffer:Pointer):LongWord;
function USBStorageDeviceWrite10(Device:PUSBDevice; Storage:PUSBStorageDevice; Start:LongWord; Count:Word; Buffer:Pointer):LongWord;
function USBStorageDeviceRead16(Device:PUSBDevice; Storage:PUSBStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
function USBStorageDeviceWrite16(Device:PUSBDevice; Storage:PUSBStorageDevice; const Start,Count:Int64; Buffer:Pointer):LongWord;
function USBStorageDeviceTransport(Device:PUSBDevice; Storage:PUSBStorageDevice; Command:PUSBCommandBlock):LongWord;
Return to Unit Reference