1*f439973dSWarner Losh /** @file 2*f439973dSWarner Losh EFI_SCSI_IO_PROTOCOL as defined in UEFI 2.0. 3*f439973dSWarner Losh This protocol is used by code, typically drivers, running in the EFI boot 4*f439973dSWarner Losh services environment to access SCSI devices. In particular, functions for 5*f439973dSWarner Losh managing devices on SCSI buses are defined here. 6*f439973dSWarner Losh 7*f439973dSWarner Losh Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> 8*f439973dSWarner Losh SPDX-License-Identifier: BSD-2-Clause-Patent 9*f439973dSWarner Losh 10*f439973dSWarner Losh **/ 11*f439973dSWarner Losh 12*f439973dSWarner Losh #ifndef __EFI_SCSI_IO_PROTOCOL_H__ 13*f439973dSWarner Losh #define __EFI_SCSI_IO_PROTOCOL_H__ 14*f439973dSWarner Losh 15*f439973dSWarner Losh #define EFI_SCSI_IO_PROTOCOL_GUID \ 16*f439973dSWarner Losh { \ 17*f439973dSWarner Losh 0x932f47e6, 0x2362, 0x4002, {0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ 18*f439973dSWarner Losh } 19*f439973dSWarner Losh 20*f439973dSWarner Losh /// 21*f439973dSWarner Losh /// Forward reference for pure ANSI compatability 22*f439973dSWarner Losh /// 23*f439973dSWarner Losh typedef struct _EFI_SCSI_IO_PROTOCOL EFI_SCSI_IO_PROTOCOL; 24*f439973dSWarner Losh 25*f439973dSWarner Losh // 26*f439973dSWarner Losh // SCSI Device type information, defined in the SCSI Primary Commands standard (e.g., SPC-4) 27*f439973dSWarner Losh // 28*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_DISK 0x00 ///< Disk device 29*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_TAPE 0x01 ///< Tape device 30*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_PRINTER 0x02 ///< Printer 31*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_PROCESSOR 0x03 ///< Processor 32*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_WORM 0x04 ///< Write-once read-multiple 33*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_CDROM 0x05 ///< CD or DVD device 34*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_SCANNER 0x06 ///< Scanner device 35*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_OPTICAL 0x07 ///< Optical memory device 36*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_MEDIUMCHANGER 0x08 ///< Medium Changer device 37*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_COMMUNICATION 0x09 ///< Communications device 38*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_A 0x0A ///< Obsolete 39*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_B 0x0B ///< Obsolete 40*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_RAID 0x0C ///< Storage array controller device (e.g., RAID) 41*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_SES 0x0D ///< Enclosure services device 42*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_RBC 0x0E ///< Simplified direct-access device (e.g., magnetic disk) 43*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_OCRW 0x0F ///< Optical card reader/writer device 44*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_BRIDGE 0x10 ///< Bridge Controller Commands 45*f439973dSWarner Losh #define MFI_SCSI_IO_TYPE_OSD 0x11 ///< Object-based Storage Device 46*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_RESERVED_LOW 0x12 ///< Reserved (low) 47*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_RESERVED_HIGH 0x1E ///< Reserved (high) 48*f439973dSWarner Losh #define EFI_SCSI_IO_TYPE_UNKNOWN 0x1F ///< Unknown no device type 49*f439973dSWarner Losh 50*f439973dSWarner Losh // 51*f439973dSWarner Losh // SCSI Data Direction definition 52*f439973dSWarner Losh // 53*f439973dSWarner Losh #define EFI_SCSI_IO_DATA_DIRECTION_READ 0 54*f439973dSWarner Losh #define EFI_SCSI_IO_DATA_DIRECTION_WRITE 1 55*f439973dSWarner Losh #define EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL 2 56*f439973dSWarner Losh 57*f439973dSWarner Losh // 58*f439973dSWarner Losh // SCSI Host Adapter Status definition 59*f439973dSWarner Losh // 60*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK 0x00 61*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 ///< timeout when processing the command 62*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT 0x0b ///< timeout when waiting for the command processing 63*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d ///< a message reject was received when processing command 64*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET 0x0e ///< a bus reset was detected 65*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f 66*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 ///< the adapter failed in issuing request sense command 67*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 ///< selection timeout 68*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 ///< data overrun or data underrun 69*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE 0x13 ///< Unexepected bus free 70*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 ///< Target bus phase sequence failure 71*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OTHER 0x7f 72*f439973dSWarner Losh 73*f439973dSWarner Losh // 74*f439973dSWarner Losh // SCSI Target Status definition 75*f439973dSWarner Losh // 76*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_GOOD 0x00 77*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION 0x02 ///< check condition 78*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET 0x04 ///< condition met 79*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_BUSY 0x08 ///< busy 80*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE 0x10 ///< intermediate 81*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 ///< intermediate-condition met 82*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT 0x18 ///< reservation conflict 83*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED 0x22 ///< command terminated 84*f439973dSWarner Losh #define EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL 0x28 ///< queue full 85*f439973dSWarner Losh 86*f439973dSWarner Losh typedef struct { 87*f439973dSWarner Losh /// 88*f439973dSWarner Losh /// The timeout, in 100 ns units, to use for the execution of this SCSI 89*f439973dSWarner Losh /// Request Packet. A Timeout value of 0 means that this function 90*f439973dSWarner Losh /// will wait indefinitely for the SCSI Request Packet to execute. If 91*f439973dSWarner Losh /// Timeout is greater than zero, then this function will return 92*f439973dSWarner Losh /// EFI_TIMEOUT if the time required to execute the SCSI Request 93*f439973dSWarner Losh /// Packet is greater than Timeout. 94*f439973dSWarner Losh /// 95*f439973dSWarner Losh UINT64 Timeout; 96*f439973dSWarner Losh /// 97*f439973dSWarner Losh /// A pointer to the data buffer to transfer between the SCSI 98*f439973dSWarner Losh /// controller and the SCSI device for SCSI READ command 99*f439973dSWarner Losh /// 100*f439973dSWarner Losh VOID *InDataBuffer; 101*f439973dSWarner Losh /// 102*f439973dSWarner Losh /// A pointer to the data buffer to transfer between the SCSI 103*f439973dSWarner Losh /// controller and the SCSI device for SCSI WRITE command. 104*f439973dSWarner Losh /// 105*f439973dSWarner Losh VOID *OutDataBuffer; 106*f439973dSWarner Losh /// 107*f439973dSWarner Losh /// A pointer to the sense data that was generated by the execution of 108*f439973dSWarner Losh /// the SCSI Request Packet. 109*f439973dSWarner Losh /// 110*f439973dSWarner Losh VOID *SenseData; 111*f439973dSWarner Losh /// 112*f439973dSWarner Losh /// A pointer to buffer that contains the Command Data Block to 113*f439973dSWarner Losh /// send to the SCSI device. 114*f439973dSWarner Losh /// 115*f439973dSWarner Losh VOID *Cdb; 116*f439973dSWarner Losh /// 117*f439973dSWarner Losh /// On Input, the size, in bytes, of InDataBuffer. On output, the 118*f439973dSWarner Losh /// number of bytes transferred between the SCSI controller and the SCSI device. 119*f439973dSWarner Losh /// 120*f439973dSWarner Losh UINT32 InTransferLength; 121*f439973dSWarner Losh /// 122*f439973dSWarner Losh /// On Input, the size, in bytes of OutDataBuffer. On Output, the 123*f439973dSWarner Losh /// Number of bytes transferred between SCSI Controller and the SCSI device. 124*f439973dSWarner Losh /// 125*f439973dSWarner Losh UINT32 OutTransferLength; 126*f439973dSWarner Losh /// 127*f439973dSWarner Losh /// The length, in bytes, of the buffer Cdb. The standard values are 128*f439973dSWarner Losh /// 6, 10, 12, and 16, but other values are possible if a variable length CDB is used. 129*f439973dSWarner Losh /// 130*f439973dSWarner Losh UINT8 CdbLength; 131*f439973dSWarner Losh /// 132*f439973dSWarner Losh /// The direction of the data transfer. 0 for reads, 1 for writes. A 133*f439973dSWarner Losh /// value of 2 is Reserved for Bi-Directional SCSI commands. 134*f439973dSWarner Losh /// 135*f439973dSWarner Losh UINT8 DataDirection; 136*f439973dSWarner Losh /// 137*f439973dSWarner Losh /// The status of the SCSI Host Controller that produces the SCSI 138*f439973dSWarner Losh /// bus where the SCSI device attached when the SCSI Request 139*f439973dSWarner Losh /// Packet was executed on the SCSI Controller. 140*f439973dSWarner Losh /// 141*f439973dSWarner Losh UINT8 HostAdapterStatus; 142*f439973dSWarner Losh /// 143*f439973dSWarner Losh /// The status returned by the SCSI device when the SCSI Request 144*f439973dSWarner Losh /// Packet was executed. 145*f439973dSWarner Losh /// 146*f439973dSWarner Losh UINT8 TargetStatus; 147*f439973dSWarner Losh /// 148*f439973dSWarner Losh /// On input, the length in bytes of the SenseData buffer. On 149*f439973dSWarner Losh /// output, the number of bytes written to the SenseData buffer. 150*f439973dSWarner Losh /// 151*f439973dSWarner Losh UINT8 SenseDataLength; 152*f439973dSWarner Losh } EFI_SCSI_IO_SCSI_REQUEST_PACKET; 153*f439973dSWarner Losh 154*f439973dSWarner Losh /** 155*f439973dSWarner Losh Retrieves the device type information of the SCSI Controller. 156*f439973dSWarner Losh 157*f439973dSWarner Losh @param This Protocol instance pointer. 158*f439973dSWarner Losh @param DeviceType A pointer to the device type information 159*f439973dSWarner Losh retrieved from the SCSI Controller. 160*f439973dSWarner Losh 161*f439973dSWarner Losh @retval EFI_SUCCESS Retrieved the device type information successfully. 162*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER The DeviceType is NULL. 163*f439973dSWarner Losh 164*f439973dSWarner Losh **/ 165*f439973dSWarner Losh typedef 166*f439973dSWarner Losh EFI_STATUS 167*f439973dSWarner Losh (EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE)( 168*f439973dSWarner Losh IN EFI_SCSI_IO_PROTOCOL *This, 169*f439973dSWarner Losh OUT UINT8 *DeviceType 170*f439973dSWarner Losh ); 171*f439973dSWarner Losh 172*f439973dSWarner Losh /** 173*f439973dSWarner Losh Retrieves the device location in the SCSI channel. 174*f439973dSWarner Losh 175*f439973dSWarner Losh @param This Protocol instance pointer. 176*f439973dSWarner Losh @param Target A pointer to the Target ID of a SCSI device 177*f439973dSWarner Losh on the SCSI channel. 178*f439973dSWarner Losh @param Lun A pointer to the LUN of the SCSI device on 179*f439973dSWarner Losh the SCSI channel. 180*f439973dSWarner Losh 181*f439973dSWarner Losh @retval EFI_SUCCESS Retrieves the device location successfully. 182*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER The Target or Lun is NULL. 183*f439973dSWarner Losh 184*f439973dSWarner Losh **/ 185*f439973dSWarner Losh typedef 186*f439973dSWarner Losh EFI_STATUS 187*f439973dSWarner Losh (EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION)( 188*f439973dSWarner Losh IN EFI_SCSI_IO_PROTOCOL *This, 189*f439973dSWarner Losh IN OUT UINT8 **Target, 190*f439973dSWarner Losh OUT UINT64 *Lun 191*f439973dSWarner Losh ); 192*f439973dSWarner Losh 193*f439973dSWarner Losh /** 194*f439973dSWarner Losh Resets the SCSI Bus that the SCSI Controller is attached to. 195*f439973dSWarner Losh 196*f439973dSWarner Losh @param This Protocol instance pointer. 197*f439973dSWarner Losh 198*f439973dSWarner Losh @retval EFI_SUCCESS The SCSI bus is reset successfully. 199*f439973dSWarner Losh @retval EFI_DEVICE_ERROR Errors encountered when resetting the SCSI bus. 200*f439973dSWarner Losh @retval EFI_UNSUPPORTED The bus reset operation is not supported by the 201*f439973dSWarner Losh SCSI Host Controller. 202*f439973dSWarner Losh @retval EFI_TIMEOUT A timeout occurred while attempting to reset 203*f439973dSWarner Losh the SCSI bus. 204*f439973dSWarner Losh 205*f439973dSWarner Losh **/ 206*f439973dSWarner Losh typedef 207*f439973dSWarner Losh EFI_STATUS 208*f439973dSWarner Losh (EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_BUS)( 209*f439973dSWarner Losh IN EFI_SCSI_IO_PROTOCOL *This 210*f439973dSWarner Losh ); 211*f439973dSWarner Losh 212*f439973dSWarner Losh /** 213*f439973dSWarner Losh Resets the SCSI Controller that the device handle specifies. 214*f439973dSWarner Losh 215*f439973dSWarner Losh @param This Protocol instance pointer. 216*f439973dSWarner Losh 217*f439973dSWarner Losh @retval EFI_SUCCESS Reset the SCSI controller successfully. 218*f439973dSWarner Losh @retval EFI_DEVICE_ERROR Errors were encountered when resetting the 219*f439973dSWarner Losh SCSI Controller. 220*f439973dSWarner Losh @retval EFI_UNSUPPORTED The SCSI bus does not support a device 221*f439973dSWarner Losh reset operation. 222*f439973dSWarner Losh @retval EFI_TIMEOUT A timeout occurred while attempting to 223*f439973dSWarner Losh reset the SCSI Controller. 224*f439973dSWarner Losh 225*f439973dSWarner Losh **/ 226*f439973dSWarner Losh typedef 227*f439973dSWarner Losh EFI_STATUS 228*f439973dSWarner Losh (EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_DEVICE)( 229*f439973dSWarner Losh IN EFI_SCSI_IO_PROTOCOL *This 230*f439973dSWarner Losh ); 231*f439973dSWarner Losh 232*f439973dSWarner Losh /** 233*f439973dSWarner Losh Sends a SCSI Request Packet to the SCSI Controller for execution. 234*f439973dSWarner Losh 235*f439973dSWarner Losh @param This Protocol instance pointer. 236*f439973dSWarner Losh @param Packet The SCSI request packet to send to the SCSI 237*f439973dSWarner Losh Controller specified by the device handle. 238*f439973dSWarner Losh @param Event If the SCSI bus to which the SCSI device is attached 239*f439973dSWarner Losh does not support non-blocking I/O, then Event is 240*f439973dSWarner Losh ignored, and blocking I/O is performed. 241*f439973dSWarner Losh If Event is NULL, then blocking I/O is performed. 242*f439973dSWarner Losh If Event is not NULL and non-blocking I/O is 243*f439973dSWarner Losh supported, then non-blocking I/O is performed, 244*f439973dSWarner Losh and Event will be signaled when the SCSI Request 245*f439973dSWarner Losh Packet completes. 246*f439973dSWarner Losh 247*f439973dSWarner Losh @retval EFI_SUCCESS The SCSI Request Packet was sent by the host 248*f439973dSWarner Losh successfully, and TransferLength bytes were 249*f439973dSWarner Losh transferred to/from DataBuffer. See 250*f439973dSWarner Losh HostAdapterStatus, TargetStatus, 251*f439973dSWarner Losh SenseDataLength, and SenseData in that order 252*f439973dSWarner Losh for additional status information. 253*f439973dSWarner Losh @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, 254*f439973dSWarner Losh but the entire DataBuffer could not be transferred. 255*f439973dSWarner Losh The actual number of bytes transferred is returned 256*f439973dSWarner Losh in TransferLength. See HostAdapterStatus, 257*f439973dSWarner Losh TargetStatus, SenseDataLength, and SenseData in 258*f439973dSWarner Losh that order for additional status information. 259*f439973dSWarner Losh @retval EFI_NOT_READY The SCSI Request Packet could not be sent because 260*f439973dSWarner Losh there are too many SCSI Command Packets already 261*f439973dSWarner Losh queued.The caller may retry again later. 262*f439973dSWarner Losh @retval EFI_DEVICE_ERROR A device error occurred while attempting to send 263*f439973dSWarner Losh the SCSI Request Packet. See HostAdapterStatus, 264*f439973dSWarner Losh TargetStatus, SenseDataLength, and SenseData in 265*f439973dSWarner Losh that order for additional status information. 266*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid. 267*f439973dSWarner Losh The SCSI Request Packet was not sent, so no 268*f439973dSWarner Losh additional status information is available. 269*f439973dSWarner Losh @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet 270*f439973dSWarner Losh is not supported by the SCSI initiator(i.e., SCSI 271*f439973dSWarner Losh Host Controller). The SCSI Request Packet was not 272*f439973dSWarner Losh sent, so no additional status information is 273*f439973dSWarner Losh available. 274*f439973dSWarner Losh @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI 275*f439973dSWarner Losh Request Packet to execute. See HostAdapterStatus, 276*f439973dSWarner Losh TargetStatus, SenseDataLength, and SenseData in 277*f439973dSWarner Losh that order for additional status information. 278*f439973dSWarner Losh 279*f439973dSWarner Losh **/ 280*f439973dSWarner Losh typedef 281*f439973dSWarner Losh EFI_STATUS 282*f439973dSWarner Losh (EFIAPI *EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND)( 283*f439973dSWarner Losh IN EFI_SCSI_IO_PROTOCOL *This, 284*f439973dSWarner Losh IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet, 285*f439973dSWarner Losh IN EFI_EVENT Event OPTIONAL 286*f439973dSWarner Losh ); 287*f439973dSWarner Losh 288*f439973dSWarner Losh /// 289*f439973dSWarner Losh /// Provides services to manage and communicate with SCSI devices. 290*f439973dSWarner Losh /// 291*f439973dSWarner Losh struct _EFI_SCSI_IO_PROTOCOL { 292*f439973dSWarner Losh EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE GetDeviceType; 293*f439973dSWarner Losh EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION GetDeviceLocation; 294*f439973dSWarner Losh EFI_SCSI_IO_PROTOCOL_RESET_BUS ResetBus; 295*f439973dSWarner Losh EFI_SCSI_IO_PROTOCOL_RESET_DEVICE ResetDevice; 296*f439973dSWarner Losh EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND ExecuteScsiCommand; 297*f439973dSWarner Losh 298*f439973dSWarner Losh /// 299*f439973dSWarner Losh /// Supplies the alignment requirement for any buffer used in a data transfer. 300*f439973dSWarner Losh /// IoAlign values of 0 and 1 mean that the buffer can be placed anywhere in memory. 301*f439973dSWarner Losh /// Otherwise, IoAlign must be a power of 2, and the requirement is that the 302*f439973dSWarner Losh /// start address of a buffer must be evenly divisible by IoAlign with no remainder. 303*f439973dSWarner Losh /// 304*f439973dSWarner Losh UINT32 IoAlign; 305*f439973dSWarner Losh }; 306*f439973dSWarner Losh 307*f439973dSWarner Losh extern EFI_GUID gEfiScsiIoProtocolGuid; 308*f439973dSWarner Losh 309*f439973dSWarner Losh #endif 310