iPXE
scsi.c File Reference

SCSI block device. More...

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <ipxe/list.h>
#include <ipxe/process.h>
#include <ipxe/xfer.h>
#include <ipxe/blockdev.h>
#include <ipxe/scsi.h>

Go to the source code of this file.

Data Structures

struct  scsi_device
 A SCSI device. More...
struct  scsi_command
 A SCSI command. More...
struct  scsi_command_type
 A SCSI command type. More...
struct  scsi_read_capacity_private
 SCSI READ CAPACITY private data. More...

Macros

#define SCSI_READY_MAX_RETRIES   10
 Maximum number of TEST UNIT READY retries.
#define EIO_NO_SENSE   __einfo_error ( EINFO_EIO_NO_SENSE )
#define EINFO_EIO_NO_SENSE    __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )
#define EIO_RECOVERED_ERROR   __einfo_error ( EINFO_EIO_RECOVERED_ERROR )
#define EINFO_EIO_RECOVERED_ERROR    __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )
#define EIO_NOT_READY   __einfo_error ( EINFO_EIO_NOT_READY )
#define EINFO_EIO_NOT_READY    __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )
#define EIO_MEDIUM_ERROR   __einfo_error ( EINFO_EIO_MEDIUM_ERROR )
#define EINFO_EIO_MEDIUM_ERROR    __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )
#define EIO_HARDWARE_ERROR   __einfo_error ( EINFO_EIO_HARDWARE_ERROR )
#define EINFO_EIO_HARDWARE_ERROR    __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )
#define EIO_ILLEGAL_REQUEST   __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )
#define EINFO_EIO_ILLEGAL_REQUEST    __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )
#define EIO_UNIT_ATTENTION   __einfo_error ( EINFO_EIO_UNIT_ATTENTION )
#define EINFO_EIO_UNIT_ATTENTION    __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )
#define EIO_DATA_PROTECT   __einfo_error ( EINFO_EIO_DATA_PROTECT )
#define EINFO_EIO_DATA_PROTECT    __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )
#define EIO_BLANK_CHECK   __einfo_error ( EINFO_EIO_BLANK_CHECK )
#define EINFO_EIO_BLANK_CHECK    __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )
#define EIO_VENDOR_SPECIFIC   __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )
#define EINFO_EIO_VENDOR_SPECIFIC    __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )
#define EIO_COPY_ABORTED   __einfo_error ( EINFO_EIO_COPY_ABORTED )
#define EINFO_EIO_COPY_ABORTED    __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )
#define EIO_ABORTED_COMMAND   __einfo_error ( EINFO_EIO_ABORTED_COMMAND )
#define EINFO_EIO_ABORTED_COMMAND    __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )
#define EIO_RESERVED   __einfo_error ( EINFO_EIO_RESERVED )
#define EINFO_EIO_RESERVED    __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )
#define EIO_VOLUME_OVERFLOW   __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )
#define EINFO_EIO_VOLUME_OVERFLOW    __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )
#define EIO_MISCOMPARE   __einfo_error ( EINFO_EIO_MISCOMPARE )
#define EINFO_EIO_MISCOMPARE    __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )
#define EIO_COMPLETED   __einfo_error ( EINFO_EIO_COMPLETED )
#define EINFO_EIO_COMPLETED    __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )
#define EIO_SENSE(key)

Enumerations

enum  scsi_device_flags { SCSIDEV_UNIT_TESTED = 0x0001 , SCSIDEV_UNIT_READY = 0x0002 }
 SCSI device flags. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
int scsi_parse_lun (const char *lun_string, struct scsi_lun *lun)
 Parse SCSI LUN.
void scsi_parse_sense (const void *data, size_t len, struct scsi_sns_descriptor *sense)
 Parse SCSI sense data.
int scsi_command (struct interface *control, struct interface *data, struct scsi_cmd *command)
 Issue SCSI command.
void scsi_response (struct interface *intf, struct scsi_rsp *response)
 Report SCSI response.
static struct scsi_devicescsidev_get (struct scsi_device *scsidev)
 Get reference to SCSI device.
static void scsidev_put (struct scsi_device *scsidev)
 Drop reference to SCSI device.
static struct scsi_commandscsicmd_get (struct scsi_command *scsicmd)
 Get reference to SCSI command.
static void scsicmd_put (struct scsi_command *scsicmd)
 Drop reference to SCSI command.
static void * scsicmd_priv (struct scsi_command *scsicmd)
 Get SCSI command private data.
static void scsicmd_free (struct refcnt *refcnt)
 Free SCSI command.
static void scsicmd_close (struct scsi_command *scsicmd, int rc)
 Close SCSI command.
static int scsicmd_command (struct scsi_command *scsicmd)
 Construct and issue SCSI command.
static void scsicmd_done (struct scsi_command *scsicmd, int rc)
 Handle SCSI command completion.
static void scsicmd_response (struct scsi_command *scsicmd, struct scsi_rsp *response)
 Handle SCSI response.
static void scsicmd_read_cmd (struct scsi_command *scsicmd, struct scsi_cmd *command)
 Construct SCSI READ command.
static void scsicmd_write_cmd (struct scsi_command *scsicmd, struct scsi_cmd *command)
 Construct SCSI WRITE command.
static void scsicmd_read_capacity_cmd (struct scsi_command *scsicmd, struct scsi_cmd *command)
 Construct SCSI READ CAPACITY command.
static void scsicmd_read_capacity_done (struct scsi_command *scsicmd, int rc)
 Handle SCSI READ CAPACITY command completion.
static void scsicmd_test_unit_ready_cmd (struct scsi_command *scsicmd __unused, struct scsi_cmd *command)
 Construct SCSI TEST UNIT READY command.
static int scsidev_command (struct scsi_device *scsidev, struct interface *block, struct scsi_command_type *type, uint64_t lba, unsigned int count, void *buffer, size_t len)
 Create SCSI command.
static int scsidev_read (struct scsi_device *scsidev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
 Issue SCSI block read.
static int scsidev_write (struct scsi_device *scsidev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
 Issue SCSI block write.
static int scsidev_read_capacity (struct scsi_device *scsidev, struct interface *block)
 Read SCSI device capacity.
static int scsidev_test_unit_ready (struct scsi_device *scsidev, struct interface *block)
 Test to see if SCSI device is ready.
static size_t scsidev_window (struct scsi_device *scsidev)
 Check SCSI device flow-control window.
static void scsidev_close (struct scsi_device *scsidev, int rc)
 Close SCSI device.
static void scsidev_ready (struct scsi_device *scsidev, int rc)
 Handle SCSI TEST UNIT READY response.
static void scsidev_step (struct scsi_device *scsidev)
 SCSI TEST UNIT READY process.
int scsi_open (struct interface *block, struct interface *scsi, struct scsi_lun *lun)
 Open SCSI device.

Variables

static struct scsi_command_type scsicmd_read
 SCSI READ command type.
static struct scsi_command_type scsicmd_write
 SCSI WRITE command type.
static struct scsi_command_type scsicmd_read_capacity
 SCSI READ CAPACITY command type.
static struct scsi_command_type scsicmd_test_unit_ready
 SCSI TEST UNIT READY command type.
static struct interface_operation scsicmd_block_op []
 SCSI command block interface operations.
static struct interface_descriptor scsicmd_block_desc
 SCSI command block interface descriptor.
static struct interface_operation scsicmd_scsi_op []
 SCSI command SCSI interface operations.
static struct interface_descriptor scsicmd_scsi_desc
 SCSI command SCSI interface descriptor.
static struct interface_operation scsidev_block_op []
 SCSI device block interface operations.
static struct interface_descriptor scsidev_block_desc
 SCSI device block interface descriptor.
static struct interface_operation scsidev_ready_op []
 SCSI device TEST UNIT READY interface operations.
static struct interface_descriptor scsidev_ready_desc
 SCSI device TEST UNIT READY interface descriptor.
static struct interface_operation scsidev_scsi_op []
 SCSI device SCSI interface operations.
static struct interface_descriptor scsidev_scsi_desc
 SCSI device SCSI interface descriptor.
static struct process_descriptor scsidev_process_desc
 SCSI device process descriptor.

Detailed Description

SCSI block device.

Definition in file scsi.c.

Macro Definition Documentation

◆ SCSI_READY_MAX_RETRIES

#define SCSI_READY_MAX_RETRIES   10

Maximum number of TEST UNIT READY retries.

Definition at line 45 of file scsi.c.

Referenced by scsidev_ready().

◆ EIO_NO_SENSE

#define EIO_NO_SENSE   __einfo_error ( EINFO_EIO_NO_SENSE )

Definition at line 48 of file scsi.c.

◆ EINFO_EIO_NO_SENSE

#define EINFO_EIO_NO_SENSE    __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )

Definition at line 49 of file scsi.c.

49#define EINFO_EIO_NO_SENSE \
50 __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )

◆ EIO_RECOVERED_ERROR

#define EIO_RECOVERED_ERROR   __einfo_error ( EINFO_EIO_RECOVERED_ERROR )

Definition at line 51 of file scsi.c.

◆ EINFO_EIO_RECOVERED_ERROR

#define EINFO_EIO_RECOVERED_ERROR    __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )

Definition at line 52 of file scsi.c.

52#define EINFO_EIO_RECOVERED_ERROR \
53 __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )

◆ EIO_NOT_READY

#define EIO_NOT_READY   __einfo_error ( EINFO_EIO_NOT_READY )

Definition at line 54 of file scsi.c.

◆ EINFO_EIO_NOT_READY

#define EINFO_EIO_NOT_READY    __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )

Definition at line 55 of file scsi.c.

55#define EINFO_EIO_NOT_READY \
56 __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )

◆ EIO_MEDIUM_ERROR

#define EIO_MEDIUM_ERROR   __einfo_error ( EINFO_EIO_MEDIUM_ERROR )

Definition at line 57 of file scsi.c.

◆ EINFO_EIO_MEDIUM_ERROR

#define EINFO_EIO_MEDIUM_ERROR    __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )

Definition at line 58 of file scsi.c.

58#define EINFO_EIO_MEDIUM_ERROR \
59 __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )

◆ EIO_HARDWARE_ERROR

#define EIO_HARDWARE_ERROR   __einfo_error ( EINFO_EIO_HARDWARE_ERROR )

Definition at line 60 of file scsi.c.

◆ EINFO_EIO_HARDWARE_ERROR

#define EINFO_EIO_HARDWARE_ERROR    __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )

Definition at line 61 of file scsi.c.

61#define EINFO_EIO_HARDWARE_ERROR \
62 __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )

◆ EIO_ILLEGAL_REQUEST

#define EIO_ILLEGAL_REQUEST   __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )

Definition at line 63 of file scsi.c.

◆ EINFO_EIO_ILLEGAL_REQUEST

#define EINFO_EIO_ILLEGAL_REQUEST    __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )

Definition at line 64 of file scsi.c.

64#define EINFO_EIO_ILLEGAL_REQUEST \
65 __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )

◆ EIO_UNIT_ATTENTION

#define EIO_UNIT_ATTENTION   __einfo_error ( EINFO_EIO_UNIT_ATTENTION )

Definition at line 66 of file scsi.c.

◆ EINFO_EIO_UNIT_ATTENTION

#define EINFO_EIO_UNIT_ATTENTION    __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )

Definition at line 67 of file scsi.c.

67#define EINFO_EIO_UNIT_ATTENTION \
68 __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )

◆ EIO_DATA_PROTECT

#define EIO_DATA_PROTECT   __einfo_error ( EINFO_EIO_DATA_PROTECT )

Definition at line 69 of file scsi.c.

◆ EINFO_EIO_DATA_PROTECT

#define EINFO_EIO_DATA_PROTECT    __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )

Definition at line 70 of file scsi.c.

70#define EINFO_EIO_DATA_PROTECT \
71 __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )

◆ EIO_BLANK_CHECK

#define EIO_BLANK_CHECK   __einfo_error ( EINFO_EIO_BLANK_CHECK )

Definition at line 72 of file scsi.c.

◆ EINFO_EIO_BLANK_CHECK

#define EINFO_EIO_BLANK_CHECK    __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )

Definition at line 73 of file scsi.c.

73#define EINFO_EIO_BLANK_CHECK \
74 __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )

◆ EIO_VENDOR_SPECIFIC

#define EIO_VENDOR_SPECIFIC   __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )

Definition at line 75 of file scsi.c.

◆ EINFO_EIO_VENDOR_SPECIFIC

#define EINFO_EIO_VENDOR_SPECIFIC    __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )

Definition at line 76 of file scsi.c.

76#define EINFO_EIO_VENDOR_SPECIFIC \
77 __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )

◆ EIO_COPY_ABORTED

#define EIO_COPY_ABORTED   __einfo_error ( EINFO_EIO_COPY_ABORTED )

Definition at line 78 of file scsi.c.

◆ EINFO_EIO_COPY_ABORTED

#define EINFO_EIO_COPY_ABORTED    __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )

Definition at line 79 of file scsi.c.

79#define EINFO_EIO_COPY_ABORTED \
80 __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )

◆ EIO_ABORTED_COMMAND

#define EIO_ABORTED_COMMAND   __einfo_error ( EINFO_EIO_ABORTED_COMMAND )

Definition at line 81 of file scsi.c.

◆ EINFO_EIO_ABORTED_COMMAND

#define EINFO_EIO_ABORTED_COMMAND    __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )

Definition at line 82 of file scsi.c.

82#define EINFO_EIO_ABORTED_COMMAND \
83 __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )

◆ EIO_RESERVED

#define EIO_RESERVED   __einfo_error ( EINFO_EIO_RESERVED )

Definition at line 84 of file scsi.c.

◆ EINFO_EIO_RESERVED

#define EINFO_EIO_RESERVED    __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )

Definition at line 85 of file scsi.c.

85#define EINFO_EIO_RESERVED \
86 __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )

◆ EIO_VOLUME_OVERFLOW

#define EIO_VOLUME_OVERFLOW   __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )

Definition at line 87 of file scsi.c.

◆ EINFO_EIO_VOLUME_OVERFLOW

#define EINFO_EIO_VOLUME_OVERFLOW    __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )

Definition at line 88 of file scsi.c.

88#define EINFO_EIO_VOLUME_OVERFLOW \
89 __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )

◆ EIO_MISCOMPARE

#define EIO_MISCOMPARE   __einfo_error ( EINFO_EIO_MISCOMPARE )

Definition at line 90 of file scsi.c.

◆ EINFO_EIO_MISCOMPARE

#define EINFO_EIO_MISCOMPARE    __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )

Definition at line 91 of file scsi.c.

91#define EINFO_EIO_MISCOMPARE \
92 __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )

◆ EIO_COMPLETED

#define EIO_COMPLETED   __einfo_error ( EINFO_EIO_COMPLETED )

Definition at line 93 of file scsi.c.

◆ EINFO_EIO_COMPLETED

#define EINFO_EIO_COMPLETED    __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )

Definition at line 94 of file scsi.c.

94#define EINFO_EIO_COMPLETED \
95 __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )

◆ EIO_SENSE

#define EIO_SENSE ( key)
Value:
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition errno.h:226
#define EINFO_EIO
Definition errno.h:435
#define EIO_RESERVED
Definition scsi.c:84
#define EIO_MISCOMPARE
Definition scsi.c:90
#define EIO_VOLUME_OVERFLOW
Definition scsi.c:87
#define EIO_DATA_PROTECT
Definition scsi.c:69
#define EIO_BLANK_CHECK
Definition scsi.c:72
#define EIO_COMPLETED
Definition scsi.c:93
#define EIO_RECOVERED_ERROR
Definition scsi.c:51
#define EIO_UNIT_ATTENTION
Definition scsi.c:66
#define EIO_ILLEGAL_REQUEST
Definition scsi.c:63
#define EIO_MEDIUM_ERROR
Definition scsi.c:57
#define EIO_HARDWARE_ERROR
Definition scsi.c:60
#define EIO_VENDOR_SPECIFIC
Definition scsi.c:75
#define EIO_ABORTED_COMMAND
Definition scsi.c:81
#define EIO_NOT_READY
Definition scsi.c:54
#define EIO_NO_SENSE
Definition scsi.c:48
#define EIO_COPY_ABORTED
Definition scsi.c:78

Definition at line 96 of file scsi.c.

96#define EIO_SENSE( key ) \
97 EUNIQ ( EINFO_EIO, (key), EIO_NO_SENSE, EIO_RECOVERED_ERROR, \
98 EIO_NOT_READY, EIO_MEDIUM_ERROR, EIO_HARDWARE_ERROR, \
99 EIO_ILLEGAL_REQUEST, EIO_UNIT_ATTENTION, \
100 EIO_DATA_PROTECT, EIO_BLANK_CHECK, EIO_VENDOR_SPECIFIC, \
101 EIO_COPY_ABORTED, EIO_ABORTED_COMMAND, EIO_RESERVED, \
102 EIO_VOLUME_OVERFLOW, EIO_MISCOMPARE, EIO_COMPLETED )

Referenced by scsicmd_response().

Enumeration Type Documentation

◆ scsi_device_flags

SCSI device flags.

Enumerator
SCSIDEV_UNIT_TESTED 

TEST UNIT READY has been issued.

SCSIDEV_UNIT_READY 

TEST UNIT READY has completed successfully.

Definition at line 255 of file scsi.c.

255 {
256 /** TEST UNIT READY has been issued */
257 SCSIDEV_UNIT_TESTED = 0x0001,
258 /** TEST UNIT READY has completed successfully */
259 SCSIDEV_UNIT_READY = 0x0002,
260};
@ SCSIDEV_UNIT_READY
TEST UNIT READY has completed successfully.
Definition scsi.c:259
@ SCSIDEV_UNIT_TESTED
TEST UNIT READY has been issued.
Definition scsi.c:257

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ scsi_parse_lun()

int scsi_parse_lun ( const char * lun_string,
struct scsi_lun * lun )

Parse SCSI LUN.

Parameters
lun_stringLUN string representation
lunLUN to fill in
Return values
rcReturn status code

Definition at line 118 of file scsi.c.

118 {
119 char *p;
120 int i;
121
122 memset ( lun, 0, sizeof ( *lun ) );
123 if ( lun_string ) {
124 p = ( char * ) lun_string;
125 for ( i = 0 ; i < 4 ; i++ ) {
126 lun->u16[i] = htons ( strtoul ( p, &p, 16 ) );
127 if ( *p == '\0' )
128 break;
129 if ( *p != '-' )
130 return -EINVAL;
131 p++;
132 }
133 if ( *p )
134 return -EINVAL;
135 }
136
137 return 0;
138}
uint8_t lun
Logical Unit Number.
Definition edd.h:3
#define EINVAL
Invalid argument.
Definition errno.h:429
#define htons(value)
Definition byteswap.h:136
void * memset(void *dest, int character, size_t len) __nonnull
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:485

References EINVAL, htons, lun, memset(), and strtoul().

Referenced by fcp_parse_uri(), ib_srp_parse_lun(), and iscsi_parse_root_path().

◆ scsi_parse_sense()

void scsi_parse_sense ( const void * data,
size_t len,
struct scsi_sns_descriptor * sense )

Parse SCSI sense data.

Parameters
dataRaw sense data
lenLength of raw sense data
senseDescriptor-format sense data to fill in

Definition at line 147 of file scsi.c.

148 {
149 const union scsi_sns *sns = data;
150
151 /* Avoid returning uninitialised data */
152 memset ( sense, 0, sizeof ( *sense ) );
153
154 /* Copy, assuming descriptor-format data */
155 if ( len < sizeof ( sns->desc ) )
156 return;
157 memcpy ( sense, &sns->desc, sizeof ( *sense ) );
158
159 /* Convert fixed-format to descriptor-format, if applicable */
160 if ( len < sizeof ( sns->fixed ) )
161 return;
162 if ( ! SCSI_SENSE_FIXED ( sns->code ) )
163 return;
164 sense->additional = sns->fixed.additional;
165}
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define SCSI_SENSE_FIXED(code)
Test if SCSI sense data is in fixed format.
Definition scsi.h:316
uint16_t additional
Additional sense code and qualifier.
Definition scsi.h:295
uint16_t additional
Additional sense code and qualifier.
Definition scsi.h:285
SCSI sense data.
Definition scsi.h:299
struct scsi_sns_fixed fixed
Fixed-format sense data.
Definition scsi.h:303
uint8_t code
Response code.
Definition scsi.h:301
struct scsi_sns_descriptor desc
Descriptor-format sense data.
Definition scsi.h:305

References scsi_sns_descriptor::additional, scsi_sns_fixed::additional, scsi_sns::code, data, scsi_sns::desc, scsi_sns::fixed, len, memcpy(), memset(), and SCSI_SENSE_FIXED.

Referenced by fcpcmd_recv_rsp(), iscsi_rx_scsi_response(), and srp_rsp().

◆ scsi_command()

int scsi_command ( struct interface * control,
struct interface * data,
struct scsi_cmd * command )

Issue SCSI command.

Parameters
controlSCSI control interface
dataSCSI data interface
commandSCSI command
Return values
tagCommand tag, or negative error

Definition at line 182 of file scsi.c.

183 {
184 struct interface *dest;
185 scsi_command_TYPE ( void * ) *op =
187 void *object = intf_object ( dest );
188 int tap;
189
190 if ( op ) {
191 tap = op ( object, data, command );
192 } else {
193 /* Default is to fail to issue the command */
194 tap = -EOPNOTSUPP;
195 }
196
197 intf_put ( dest );
198 return tap;
199}
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:605
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition interface.c:160
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition interface.c:150
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition interface.h:270
uint32_t control
Control.
Definition myson.h:3
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
#define scsi_command_TYPE(object_type)
Definition scsi.h:342
A command-line command.
Definition command.h:10
An object interface.
Definition interface.h:125
A SCSI command.
Definition scsi.c:263

References control, data, dest, EOPNOTSUPP, intf_get_dest_op, intf_object(), intf_put(), op, and scsi_command_TYPE.

◆ scsi_response()

void scsi_response ( struct interface * intf,
struct scsi_rsp * response )

Report SCSI response.

Parameters
interfaceSCSI command interface
responseSCSI response

Definition at line 207 of file scsi.c.

207 {
208 struct interface *dest;
209 scsi_response_TYPE ( void * ) *op =
211 void *object = intf_object ( dest );
212
213 if ( op ) {
214 op ( object, response );
215 } else {
216 /* Default is to ignore the response */
217 }
218
219 intf_put ( dest );
220}
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition scsi.c:207
#define scsi_response_TYPE(object_type)
Definition scsi.h:347
struct interface * intf
Original interface.
Definition interface.h:159

References dest, interface::intf, intf_get_dest_op, intf_object(), intf_put(), op, scsi_response(), and scsi_response_TYPE.

Referenced by fcpcmd_recv_rsp(), iscsi_scsi_done(), scsi_response(), and srp_rsp().

◆ scsidev_get()

struct scsi_device * scsidev_get ( struct scsi_device * scsidev)
inlinestatic

Get reference to SCSI device.

Parameters
scsidevSCSI device
Return values
scsidevSCSI device

Definition at line 323 of file scsi.c.

323 {
324 ref_get ( &scsidev->refcnt );
325 return scsidev;
326}
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
struct refcnt refcnt
Reference count.
Definition scsi.c:232

References ref_get, and scsi_device::refcnt.

Referenced by scsidev_command().

◆ scsidev_put()

void scsidev_put ( struct scsi_device * scsidev)
inlinestatic

Drop reference to SCSI device.

Parameters
scsidevSCSI device

Definition at line 334 of file scsi.c.

334 {
335 ref_put ( &scsidev->refcnt );
336}
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References ref_put, and scsi_device::refcnt.

Referenced by scsicmd_free().

◆ scsicmd_get()

struct scsi_command * scsicmd_get ( struct scsi_command * scsicmd)
inlinestatic

Get reference to SCSI command.

Parameters
scsicmdSCSI command
Return values
scsicmdSCSI command

Definition at line 345 of file scsi.c.

345 {
346 ref_get ( &scsicmd->refcnt );
347 return scsicmd;
348}
struct refcnt refcnt
Reference count.
Definition scsi.c:265

References ref_get, and scsi_command::refcnt.

◆ scsicmd_put()

void scsicmd_put ( struct scsi_command * scsicmd)
inlinestatic

Drop reference to SCSI command.

Parameters
scsicmdSCSI command

Definition at line 356 of file scsi.c.

356 {
357 ref_put ( &scsicmd->refcnt );
358}

References ref_put, and scsi_command::refcnt.

Referenced by scsicmd_close().

◆ scsicmd_priv()

void * scsicmd_priv ( struct scsi_command * scsicmd)
inlinestatic

Get SCSI command private data.

Parameters
scsicmdSCSI command
Return values
privPrivate data

Definition at line 367 of file scsi.c.

367 {
368 return scsicmd->priv;
369}
uint8_t priv[0]
Private data.
Definition scsi.c:290

References scsi_command::priv.

Referenced by scsicmd_read_capacity_cmd(), and scsicmd_read_capacity_done().

◆ scsicmd_free()

void scsicmd_free ( struct refcnt * refcnt)
static

Free SCSI command.

Parameters
refcntReference count

Definition at line 376 of file scsi.c.

376 {
377 struct scsi_command *scsicmd =
379
380 /* Drop reference to SCSI device */
381 scsidev_put ( scsicmd->scsidev );
382
383 /* Free command */
384 free ( scsicmd );
385}
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
static void scsidev_put(struct scsi_device *scsidev)
Drop reference to SCSI device.
Definition scsi.c:334
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A reference counter.
Definition refcnt.h:27
struct scsi_device * scsidev
SCSI device.
Definition scsi.c:267

References container_of, free, scsi_command::scsidev, and scsidev_put().

Referenced by scsidev_command().

◆ scsicmd_close()

void scsicmd_close ( struct scsi_command * scsicmd,
int rc )
static

Close SCSI command.

Parameters
scsicmdSCSI command
rcReason for close

Definition at line 393 of file scsi.c.

393 {
394 struct scsi_device *scsidev = scsicmd->scsidev;
395
396 if ( rc != 0 ) {
397 DBGC ( scsidev, "SCSI %p tag %08x closed: %s\n",
398 scsidev, scsicmd->tag, strerror ( rc ) );
399 }
400
401 /* Remove from list of commands */
402 list_del ( &scsicmd->list );
403
404 /* Shut down interfaces */
405 intfs_shutdown ( rc, &scsicmd->scsi, &scsicmd->block, NULL );
406
407 /* Drop list's reference */
408 scsicmd_put ( scsicmd );
409}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:505
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition interface.c:327
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void scsicmd_put(struct scsi_command *scsicmd)
Drop reference to SCSI command.
Definition scsi.c:356
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct interface block
Block data interface.
Definition scsi.c:272
uint32_t tag
Command tag.
Definition scsi.c:287
struct list_head list
List of SCSI commands.
Definition scsi.c:269
struct interface scsi
SCSI data interface.
Definition scsi.c:274
A SCSI device.
Definition scsi.c:230

References scsi_command::block, DBGC, intfs_shutdown(), scsi_command::list, list_del, NULL, rc, scsi_command::scsi, scsicmd_put(), scsi_command::scsidev, strerror(), and scsi_command::tag.

Referenced by scsicmd_read_capacity_done(), scsidev_close(), and scsidev_command().

◆ scsicmd_command()

int scsicmd_command ( struct scsi_command * scsicmd)
static

Construct and issue SCSI command.

Return values
rcReturn status code

Definition at line 416 of file scsi.c.

416 {
417 struct scsi_device *scsidev = scsicmd->scsidev;
418 struct scsi_cmd command;
419 int tag;
420 int rc;
421
422 /* Construct command */
423 memset ( &command, 0, sizeof ( command ) );
424 memcpy ( &command.lun, &scsidev->lun, sizeof ( command.lun ) );
425 scsicmd->type->cmd ( scsicmd, &command );
426
427 /* Issue command */
428 if ( ( tag = scsi_command ( &scsidev->scsi, &scsicmd->scsi,
429 &command ) ) < 0 ) {
430 rc = tag;
431 DBGC ( scsidev, "SCSI %p could not issue command: %s\n",
432 scsidev, strerror ( rc ) );
433 return rc;
434 }
435
436 /* Record tag */
437 if ( scsicmd->tag ) {
438 DBGC ( scsidev, "SCSI %p tag %08x is now tag %08x\n",
439 scsidev, scsicmd->tag, tag );
440 }
441 scsicmd->tag = tag;
442 DBGC2 ( scsidev, "SCSI %p tag %08x %s " SCSI_CDB_FORMAT "\n",
443 scsidev, scsicmd->tag, scsicmd->type->name,
444 SCSI_CDB_DATA ( command.cdb ) );
445
446 return 0;
447}
uint64_t tag
Identity tag.
Definition edd.h:1
#define DBGC2(...)
Definition compiler.h:522
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:223
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:219
A SCSI command information unit.
Definition scsi.h:249
void(* cmd)(struct scsi_command *scsicmd, struct scsi_cmd *command)
Construct SCSI command IU.
Definition scsi.c:305
const char * name
Name.
Definition scsi.c:296
struct scsi_command_type * type
Command type.
Definition scsi.c:277
struct interface scsi
SCSI control interface.
Definition scsi.c:236
struct scsi_lun lun
SCSI LUN.
Definition scsi.c:239

References scsi_command_type::cmd, DBGC, DBGC2, scsi_device::lun, memcpy(), memset(), scsi_command_type::name, rc, scsi_command::scsi, scsi_device::scsi, SCSI_CDB_DATA, SCSI_CDB_FORMAT, scsi_command::scsidev, strerror(), scsi_command::tag, tag, and scsi_command::type.

Referenced by scsicmd_read_capacity_done(), and scsidev_command().

◆ scsicmd_done()

void scsicmd_done ( struct scsi_command * scsicmd,
int rc )
static

Handle SCSI command completion.

Parameters
scsicmdSCSI command
rcReason for close

Definition at line 455 of file scsi.c.

455 {
456
457 /* Restart SCSI interface */
458 intf_restart ( &scsicmd->scsi, rc );
459
460 /* Hand over to the command completion handler */
461 scsicmd->type->done ( scsicmd, rc );
462}
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
void(* done)(struct scsi_command *scsicmd, int rc)
Handle SCSI command completion.
Definition scsi.c:313

References scsi_command_type::done, intf_restart(), rc, scsi_command::scsi, and scsi_command::type.

Referenced by scsicmd_response().

◆ scsicmd_response()

void scsicmd_response ( struct scsi_command * scsicmd,
struct scsi_rsp * response )
static

Handle SCSI response.

Parameters
scsicmdSCSI command
responseSCSI response

Definition at line 470 of file scsi.c.

471 {
472 struct scsi_device *scsidev = scsicmd->scsidev;
473 size_t overrun;
474 size_t underrun;
475 int rc;
476
477 if ( response->status == 0 ) {
478 scsicmd_done ( scsicmd, 0 );
479 } else {
480 DBGC ( scsidev, "SCSI %p tag %08x status %02x",
481 scsidev, scsicmd->tag, response->status );
482 if ( response->overrun > 0 ) {
483 overrun = response->overrun;
484 DBGC ( scsidev, " overrun +%zd", overrun );
485 } else if ( response->overrun < 0 ) {
486 underrun = -(response->overrun);
487 DBGC ( scsidev, " underrun -%zd", underrun );
488 }
489 DBGC ( scsidev, " sense %02x key %02x additional %04x\n",
490 ( response->sense.code & SCSI_SENSE_CODE_MASK ),
491 ( response->sense.key & SCSI_SENSE_KEY_MASK ),
492 ntohs ( response->sense.additional ) );
493
494 /* Construct error number from sense data */
495 rc = -EIO_SENSE ( response->sense.key & SCSI_SENSE_KEY_MASK );
496 scsicmd_done ( scsicmd, rc );
497 }
498}
#define ntohs(value)
Definition byteswap.h:137
static void scsicmd_done(struct scsi_command *scsicmd, int rc)
Handle SCSI command completion.
Definition scsi.c:455
#define EIO_SENSE(key)
Definition scsi.c:96
#define SCSI_SENSE_KEY_MASK
SCSI sense key mask.
Definition scsi.h:319
#define SCSI_SENSE_CODE_MASK
SCSI sense response code mask.
Definition scsi.h:309
struct scsi_sns_descriptor sense
Autosense data (if any)
Definition scsi.h:333
uint8_t status
SCSI status code.
Definition scsi.h:324
ssize_t overrun
Data overrun (or negative underrun)
Definition scsi.h:326
uint8_t code
Response code.
Definition scsi.h:291
uint8_t key
Sense key.
Definition scsi.h:293

References scsi_sns_descriptor::additional, scsi_sns_descriptor::code, DBGC, EIO_SENSE, scsi_sns_descriptor::key, ntohs, scsi_rsp::overrun, rc, SCSI_SENSE_CODE_MASK, SCSI_SENSE_KEY_MASK, scsicmd_done(), scsi_command::scsidev, scsi_rsp::sense, scsi_rsp::status, and scsi_command::tag.

◆ scsicmd_read_cmd()

void scsicmd_read_cmd ( struct scsi_command * scsicmd,
struct scsi_cmd * command )
static

Construct SCSI READ command.

Parameters
scsicmdSCSI command
commandSCSI command IU

Definition at line 506 of file scsi.c.

507 {
508
509 if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
510 /* Use READ (16) */
511 command->cdb.read16.opcode = SCSI_OPCODE_READ_16;
512 command->cdb.read16.lba = cpu_to_be64 ( scsicmd->lba );
513 command->cdb.read16.len = cpu_to_be32 ( scsicmd->count );
514 } else {
515 /* Use READ (10) */
516 command->cdb.read10.opcode = SCSI_OPCODE_READ_10;
517 command->cdb.read10.lba = cpu_to_be32 ( scsicmd->lba );
518 command->cdb.read10.len = cpu_to_be16 ( scsicmd->count );
519 }
520 command->data_in = scsicmd->buffer;
521 command->data_in_len = scsicmd->len;
522}
#define SCSI_OPCODE_READ_10
READ (10)
Definition scsi.h:24
#define SCSI_OPCODE_READ_16
READ (16)
Definition scsi.h:25
#define cpu_to_be16(value)
Definition byteswap.h:110
#define cpu_to_be32(value)
Definition byteswap.h:111
#define cpu_to_be64(value)
Definition byteswap.h:112
#define SCSI_MAX_BLOCK_10
Maximum block for READ/WRITE (10) commands.
Definition scsi.h:17
uint64_t lba
Starting logical block address.
Definition scsi.c:279
unsigned int count
Number of blocks.
Definition scsi.c:281
size_t len
Length of data buffer.
Definition scsi.c:285
void * buffer
Data buffer.
Definition scsi.c:283

References scsi_command::buffer, scsi_command::count, cpu_to_be16, cpu_to_be32, cpu_to_be64, scsi_command::lba, scsi_command::len, SCSI_MAX_BLOCK_10, SCSI_OPCODE_READ_10, and SCSI_OPCODE_READ_16.

◆ scsicmd_write_cmd()

void scsicmd_write_cmd ( struct scsi_command * scsicmd,
struct scsi_cmd * command )
static

Construct SCSI WRITE command.

Parameters
scsicmdSCSI command
commandSCSI command IU

Definition at line 537 of file scsi.c.

538 {
539
540 if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
541 /* Use WRITE (16) */
542 command->cdb.write16.opcode = SCSI_OPCODE_WRITE_16;
543 command->cdb.write16.lba = cpu_to_be64 ( scsicmd->lba );
544 command->cdb.write16.len = cpu_to_be32 ( scsicmd->count );
545 } else {
546 /* Use WRITE (10) */
547 command->cdb.write10.opcode = SCSI_OPCODE_WRITE_10;
548 command->cdb.write10.lba = cpu_to_be32 ( scsicmd->lba );
549 command->cdb.write10.len = cpu_to_be16 ( scsicmd->count );
550 }
551 command->data_out = scsicmd->buffer;
552 command->data_out_len = scsicmd->len;
553}
#define SCSI_OPCODE_WRITE_16
WRITE (16)
Definition scsi.h:27
#define SCSI_OPCODE_WRITE_10
WRITE (10)
Definition scsi.h:26

References scsi_command::buffer, scsi_command::count, cpu_to_be16, cpu_to_be32, cpu_to_be64, scsi_command::lba, scsi_command::len, SCSI_MAX_BLOCK_10, SCSI_OPCODE_WRITE_10, and SCSI_OPCODE_WRITE_16.

◆ scsicmd_read_capacity_cmd()

void scsicmd_read_capacity_cmd ( struct scsi_command * scsicmd,
struct scsi_cmd * command )
static

Construct SCSI READ CAPACITY command.

Parameters
scsicmdSCSI command
commandSCSI command IU

Definition at line 581 of file scsi.c.

582 {
583 struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
584 struct scsi_cdb_read_capacity_16 *readcap16 = &command->cdb.readcap16;
585 struct scsi_cdb_read_capacity_10 *readcap10 = &command->cdb.readcap10;
586 struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
587 struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
588
589 if ( priv->use16 ) {
590 /* Use READ CAPACITY (16) */
592 readcap16->service_action =
594 readcap16->len = cpu_to_be32 ( sizeof ( *capacity16 ) );
595 command->data_in = capacity16;
596 command->data_in_len = sizeof ( *capacity16 );
597 } else {
598 /* Use READ CAPACITY (10) */
600 command->data_in = capacity10;
601 command->data_in_len = sizeof ( *capacity10 );
602 }
603}
#define SCSI_OPCODE_SERVICE_ACTION_IN
SERVICE ACTION IN.
Definition scsi.h:29
#define SCSI_OPCODE_READ_CAPACITY_10
READ CAPACITY (10)
Definition scsi.h:28
#define SCSI_SERVICE_ACTION_READ_CAPACITY_16
READ CAPACITY (16)
Definition scsi.h:30
static void * scsicmd_priv(struct scsi_command *scsicmd)
Get SCSI command private data.
Definition scsi.c:367
SCSI "READ CAPACITY (10)" parameter data.
Definition scsi.h:157
SCSI "READ CAPACITY (16)" parameter data.
Definition scsi.h:187
A SCSI "READ CAPACITY (10)" CDB.
Definition scsi.h:140
uint8_t opcode
Opcode (0x25)
Definition scsi.h:142
A SCSI "READ CAPACITY (16)" CDB.
Definition scsi.h:165
uint8_t service_action
Service action.
Definition scsi.h:169
uint8_t opcode
Opcode (0x9e)
Definition scsi.h:167
uint32_t len
Transfer length.
Definition scsi.h:179
SCSI READ CAPACITY private data.
Definition scsi.c:563
static struct tlan_private * priv
Definition tlan.c:225

References cpu_to_be32, scsi_cdb_read_capacity_16::len, scsi_cdb_read_capacity_10::opcode, scsi_cdb_read_capacity_16::opcode, priv, SCSI_OPCODE_READ_CAPACITY_10, SCSI_OPCODE_SERVICE_ACTION_IN, SCSI_SERVICE_ACTION_READ_CAPACITY_16, scsicmd_priv(), and scsi_cdb_read_capacity_16::service_action.

◆ scsicmd_read_capacity_done()

void scsicmd_read_capacity_done ( struct scsi_command * scsicmd,
int rc )
static

Handle SCSI READ CAPACITY command completion.

Parameters
scsicmdSCSI command
rcReason for completion

Definition at line 611 of file scsi.c.

612 {
613 struct scsi_device *scsidev = scsicmd->scsidev;
614 struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
615 struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
616 struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
617 struct block_device_capacity capacity;
618
619 /* Close if command failed */
620 if ( rc != 0 ) {
621 scsicmd_close ( scsicmd, rc );
622 return;
623 }
624
625 /* Extract capacity */
626 if ( priv->use16 ) {
627 capacity.blocks = ( be64_to_cpu ( capacity16->lba ) + 1 );
628 capacity.blksize = be32_to_cpu ( capacity16->blksize );
629 } else {
630 capacity.blocks = ( be32_to_cpu ( capacity10->lba ) + 1 );
631 capacity.blksize = be32_to_cpu ( capacity10->blksize );
632
633 /* If capacity range was exceeded (i.e. capacity.lba
634 * was 0xffffffff, meaning that blockdev->blocks is
635 * now zero), use READ CAPACITY (16) instead. READ
636 * CAPACITY (16) is not mandatory, so we can't just
637 * use it straight off.
638 */
639 if ( capacity.blocks == 0 ) {
640 priv->use16 = 1;
641 if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 ) {
642 scsicmd_close ( scsicmd, rc );
643 return;
644 }
645 return;
646 }
647 }
648 capacity.max_count = -1U;
649
650 /* Allow transport layer to update capacity */
651 block_capacity ( &scsidev->scsi, &capacity );
652
653 /* Return capacity to caller */
654 block_capacity ( &scsicmd->block, &capacity );
655
656 /* Close command */
657 scsicmd_close ( scsicmd, 0 );
658}
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition blockdev.c:130
#define be32_to_cpu(value)
Definition byteswap.h:117
#define be64_to_cpu(value)
Definition byteswap.h:118
static int scsicmd_command(struct scsi_command *scsicmd)
Construct and issue SCSI command.
Definition scsi.c:416
static void scsicmd_close(struct scsi_command *scsicmd, int rc)
Close SCSI command.
Definition scsi.c:393
Block device capacity.
Definition blockdev.h:18
unsigned int max_count
Maximum number of blocks per single transfer.
Definition blockdev.h:24
uint32_t lba
Maximum logical block number.
Definition scsi.h:159
uint32_t blksize
Block length in bytes.
Definition scsi.h:161
uint32_t blksize
Block length in bytes.
Definition scsi.h:191
uint64_t lba
Maximum logical block number.
Definition scsi.h:189

References be32_to_cpu, be64_to_cpu, block_device_capacity::blksize, scsi_capacity_10::blksize, scsi_capacity_16::blksize, scsi_command::block, block_capacity(), block_device_capacity::blocks, scsi_capacity_10::lba, scsi_capacity_16::lba, block_device_capacity::max_count, priv, rc, scsi_device::scsi, scsicmd_close(), scsicmd_command(), scsicmd_priv(), and scsi_command::scsidev.

◆ scsicmd_test_unit_ready_cmd()

void scsicmd_test_unit_ready_cmd ( struct scsi_command *scsicmd __unused,
struct scsi_cmd * command )
static

Construct SCSI TEST UNIT READY command.

Parameters
scsicmdSCSI command
commandSCSI command IU

Definition at line 674 of file scsi.c.

675 {
676 struct scsi_cdb_test_unit_ready *testready = &command->cdb.testready;
677
679}
#define SCSI_OPCODE_TEST_UNIT_READY
TEST UNIT READY.
Definition scsi.h:31
A SCSI "TEST UNIT READY" CDB.
Definition scsi.h:197
uint8_t opcode
Opcode (0x00)
Definition scsi.h:199

References __unused, scsi_cdb_test_unit_ready::opcode, and SCSI_OPCODE_TEST_UNIT_READY.

◆ scsidev_command()

int scsidev_command ( struct scsi_device * scsidev,
struct interface * block,
struct scsi_command_type * type,
uint64_t lba,
unsigned int count,
void * buffer,
size_t len )
static

Create SCSI command.

Parameters
scsidevSCSI device
blockBlock data interface
typeSCSI command type
lbaStarting logical block address
countNumber of blocks to transfer
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 721 of file scsi.c.

725 {
726 struct scsi_command *scsicmd;
727 int rc;
728
729 /* Allocate and initialise structure */
730 scsicmd = zalloc ( sizeof ( *scsicmd ) + type->priv_len );
731 if ( ! scsicmd ) {
732 rc = -ENOMEM;
733 goto err_zalloc;
734 }
735 ref_init ( &scsicmd->refcnt, scsicmd_free );
736 intf_init ( &scsicmd->block, &scsicmd_block_desc, &scsicmd->refcnt );
737 intf_init ( &scsicmd->scsi, &scsicmd_scsi_desc,
738 &scsicmd->refcnt );
739 scsicmd->scsidev = scsidev_get ( scsidev );
740 list_add ( &scsicmd->list, &scsidev->cmds );
741 scsicmd->type = type;
742 scsicmd->lba = lba;
743 scsicmd->count = count;
744 scsicmd->buffer = buffer;
745 scsicmd->len = len;
746
747 /* Issue SCSI command */
748 if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 )
749 goto err_command;
750
751 /* Attach to parent interface, transfer reference to list, and return */
752 intf_plug_plug ( &scsicmd->block, block );
753 return 0;
754
755 err_command:
756 scsicmd_close ( scsicmd, rc );
757 ref_put ( &scsicmd->refcnt );
758 err_zalloc:
759 return rc;
760}
uint32_t type
Operating system type.
Definition ena.h:1
static unsigned int count
Number of entries.
Definition dwmac.h:220
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
uint64_t lba
Starting block number.
Definition int13.h:11
#define ENOMEM
Not enough space.
Definition errno.h:535
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
static struct scsi_device * scsidev_get(struct scsi_device *scsidev)
Get reference to SCSI device.
Definition scsi.c:323
static struct interface_descriptor scsicmd_scsi_desc
SCSI command SCSI interface descriptor.
Definition scsi.c:705
static struct interface_descriptor scsicmd_block_desc
SCSI command block interface descriptor.
Definition scsi.c:694
static void scsicmd_free(struct refcnt *refcnt)
Free SCSI command.
Definition scsi.c:376
struct list_head cmds
List of commands.
Definition scsi.c:251

References block, scsi_command::block, buffer, scsi_command::buffer, scsi_device::cmds, count, scsi_command::count, ENOMEM, intf_init(), intf_plug_plug(), lba, scsi_command::lba, len, scsi_command::len, scsi_command::list, list_add, rc, ref_init, ref_put, scsi_command::refcnt, scsi_command::scsi, scsicmd_block_desc, scsicmd_close(), scsicmd_command(), scsicmd_free(), scsicmd_scsi_desc, scsi_command::scsidev, scsidev_get(), scsi_command::type, type, and zalloc().

Referenced by scsidev_read(), scsidev_read_capacity(), scsidev_test_unit_ready(), and scsidev_write().

◆ scsidev_read()

int scsidev_read ( struct scsi_device * scsidev,
struct interface * block,
uint64_t lba,
unsigned int count,
void * buffer,
size_t len )
static

Issue SCSI block read.

Parameters
scsidevSCSI device
blockBlock data interface
lbaStarting logical block address
countNumber of blocks to transfer
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 774 of file scsi.c.

777 {
778 return scsidev_command ( scsidev, block, &scsicmd_read,
779 lba, count, buffer, len );
780}
static struct scsi_command_type scsicmd_read
SCSI READ command type.
Definition scsi.c:525
static int scsidev_command(struct scsi_device *scsidev, struct interface *block, struct scsi_command_type *type, uint64_t lba, unsigned int count, void *buffer, size_t len)
Create SCSI command.
Definition scsi.c:721

References block, buffer, count, lba, len, scsicmd_read, scsi_command::scsidev, and scsidev_command().

◆ scsidev_write()

int scsidev_write ( struct scsi_device * scsidev,
struct interface * block,
uint64_t lba,
unsigned int count,
void * buffer,
size_t len )
static

Issue SCSI block write.

Parameters
scsidevSCSI device
blockBlock data interface
lbaStarting logical block address
countNumber of blocks to transfer
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 793 of file scsi.c.

796 {
797 return scsidev_command ( scsidev, block, &scsicmd_write,
798 lba, count, buffer, len );
799}
static struct scsi_command_type scsicmd_write
SCSI WRITE command type.
Definition scsi.c:556

References block, buffer, count, lba, len, scsicmd_write, scsi_command::scsidev, and scsidev_command().

◆ scsidev_read_capacity()

int scsidev_read_capacity ( struct scsi_device * scsidev,
struct interface * block )
static

Read SCSI device capacity.

Parameters
scsidevSCSI device
blockBlock data interface
Return values
rcReturn status code

Definition at line 808 of file scsi.c.

809 {
810 return scsidev_command ( scsidev, block, &scsicmd_read_capacity,
811 0, 0, NULL, 0 );
812}
static struct scsi_command_type scsicmd_read_capacity
SCSI READ CAPACITY command type.
Definition scsi.c:661

References block, NULL, scsicmd_read_capacity, scsi_command::scsidev, and scsidev_command().

◆ scsidev_test_unit_ready()

int scsidev_test_unit_ready ( struct scsi_device * scsidev,
struct interface * block )
static

Test to see if SCSI device is ready.

Parameters
scsidevSCSI device
blockBlock data interface
Return values
rcReturn status code

Definition at line 821 of file scsi.c.

822 {
824 0, 0, NULL, 0 );
825}
static struct scsi_command_type scsicmd_test_unit_ready
SCSI TEST UNIT READY command type.
Definition scsi.c:682

References block, NULL, scsicmd_test_unit_ready, scsi_command::scsidev, and scsidev_command().

Referenced by scsidev_step().

◆ scsidev_window()

size_t scsidev_window ( struct scsi_device * scsidev)
static

Check SCSI device flow-control window.

Parameters
scsidevSCSI device
Return values
lenLength of window

Definition at line 833 of file scsi.c.

833 {
834
835 /* Refuse commands until unit is confirmed ready */
836 if ( ! ( scsidev->flags & SCSIDEV_UNIT_READY ) )
837 return 0;
838
839 return xfer_window ( &scsidev->scsi );
840}
unsigned int flags
Flags.
Definition scsi.c:241
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

References scsi_device::flags, scsi_device::scsi, scsi_command::scsidev, SCSIDEV_UNIT_READY, and xfer_window().

◆ scsidev_close()

void scsidev_close ( struct scsi_device * scsidev,
int rc )
static

Close SCSI device.

Parameters
scsidevSCSI device
rcReason for close

Definition at line 848 of file scsi.c.

848 {
849 struct scsi_command *scsicmd;
850 struct scsi_command *tmp;
851
852 /* Stop process */
854
855 /* Shut down interfaces */
857 NULL );
858
859 /* Shut down any remaining commands */
861 scsicmd_close ( scsicmd, rc );
862}
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
struct interface ready
TEST UNIT READY interface.
Definition scsi.c:244
struct process process
TEST UNIT READY process.
Definition scsi.c:246
struct interface block
Block control interface.
Definition scsi.c:234

References scsi_device::block, scsi_device::cmds, intfs_shutdown(), scsi_command::list, list_for_each_entry_safe, NULL, scsi_device::process, process_del(), rc, scsi_device::ready, scsi_device::scsi, scsicmd_close(), scsi_command::scsidev, and tmp.

Referenced by scsidev_ready(), and scsidev_step().

◆ scsidev_ready()

void scsidev_ready ( struct scsi_device * scsidev,
int rc )
static

Handle SCSI TEST UNIT READY response.

Parameters
scsidevSCSI device
rcReason for close

Definition at line 885 of file scsi.c.

885 {
886
887 /* Shut down interface */
888 intf_restart ( &scsidev->ready, rc );
889
890 /* Mark device as ready, if applicable */
891 if ( rc == 0 ) {
892 DBGC ( scsidev, "SCSI %p unit is ready\n", scsidev );
893 scsidev->flags |= SCSIDEV_UNIT_READY;
894 xfer_window_changed ( &scsidev->block );
895 return;
896 }
897 DBGC ( scsidev, "SCSI %p not ready: %s\n", scsidev, strerror ( rc ) );
898
899 /* SCSI targets have an annoying habit of returning occasional
900 * pointless "error" messages such as "power-on occurred", so
901 * we have to be prepared to retry commands.
902 *
903 * For most commands, we rely on the caller (e.g. the generic
904 * SAN device layer) to retry commands as needed. However, a
905 * TEST UNIT READY failure is used as an indication that the
906 * whole SCSI device is unavailable and should be closed. We
907 * must therefore perform this retry loop within the SCSI
908 * layer.
909 */
910 if ( scsidev->retries++ < SCSI_READY_MAX_RETRIES ) {
911 DBGC ( scsidev, "SCSI %p retrying (retry %d)\n",
912 scsidev, scsidev->retries );
913 scsidev->flags &= ~SCSIDEV_UNIT_TESTED;
914 process_add ( &scsidev->process );
915 return;
916 }
917
918 /* Close device */
919 DBGC ( scsidev, "SCSI %p never became ready: %s\n",
920 scsidev, strerror ( rc ) );
921 scsidev_close ( scsidev, rc );
922}
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
#define SCSI_READY_MAX_RETRIES
Maximum number of TEST UNIT READY retries.
Definition scsi.c:45
static void scsidev_close(struct scsi_device *scsidev, int rc)
Close SCSI device.
Definition scsi.c:848
unsigned int retries
TEST UNIT READY retry count.
Definition scsi.c:248
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

References scsi_device::block, DBGC, scsi_device::flags, intf_restart(), scsi_device::process, process_add(), rc, scsi_device::ready, scsi_device::retries, SCSI_READY_MAX_RETRIES, scsidev_close(), SCSIDEV_UNIT_READY, SCSIDEV_UNIT_TESTED, strerror(), and xfer_window_changed().

◆ scsidev_step()

void scsidev_step ( struct scsi_device * scsidev)
static

SCSI TEST UNIT READY process.

Parameters
scsidevSCSI device

Definition at line 938 of file scsi.c.

938 {
939 int rc;
940
941 /* Do nothing if we have already issued TEST UNIT READY */
942 if ( scsidev->flags & SCSIDEV_UNIT_TESTED )
943 return;
944
945 /* Wait until underlying SCSI device is ready */
946 if ( xfer_window ( &scsidev->scsi ) == 0 )
947 return;
948
949 DBGC ( scsidev, "SCSI %p waiting for unit to become ready\n",
950 scsidev );
951
952 /* Mark TEST UNIT READY as sent */
953 scsidev->flags |= SCSIDEV_UNIT_TESTED;
954
955 /* Issue TEST UNIT READY command */
956 if ( ( rc = scsidev_test_unit_ready ( scsidev, &scsidev->ready )) !=0){
957 scsidev_close ( scsidev, rc );
958 return;
959 }
960}
static int scsidev_test_unit_ready(struct scsi_device *scsidev, struct interface *block)
Test to see if SCSI device is ready.
Definition scsi.c:821

References DBGC, scsi_device::flags, rc, scsi_device::ready, scsi_device::scsi, scsidev_close(), scsidev_test_unit_ready(), SCSIDEV_UNIT_TESTED, and xfer_window().

◆ scsi_open()

int scsi_open ( struct interface * block,
struct interface * scsi,
struct scsi_lun * lun )

Open SCSI device.

Parameters
blockBlock control interface
scsiSCSI control interface
lunSCSI LUN
Return values
rcReturn status code

Definition at line 985 of file scsi.c.

986 {
987 struct scsi_device *scsidev;
988
989 /* Allocate and initialise structure */
990 scsidev = zalloc ( sizeof ( *scsidev ) );
991 if ( ! scsidev )
992 return -ENOMEM;
993 ref_init ( &scsidev->refcnt, NULL );
994 intf_init ( &scsidev->block, &scsidev_block_desc, &scsidev->refcnt );
995 intf_init ( &scsidev->scsi, &scsidev_scsi_desc, &scsidev->refcnt );
996 intf_init ( &scsidev->ready, &scsidev_ready_desc, &scsidev->refcnt );
998 &scsidev->refcnt );
999 INIT_LIST_HEAD ( &scsidev->cmds );
1000 memcpy ( &scsidev->lun, lun, sizeof ( scsidev->lun ) );
1001 DBGC ( scsidev, "SCSI %p created for LUN " SCSI_LUN_FORMAT "\n",
1002 scsidev, SCSI_LUN_DATA ( scsidev->lun ) );
1003
1004 /* Attach to SCSI and parent interfaces, mortalise self, and return */
1005 intf_plug_plug ( &scsidev->scsi, scsi );
1006 intf_plug_plug ( &scsidev->block, block );
1007 ref_put ( &scsidev->refcnt );
1008 return 0;
1009}
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
static void process_init(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process and add to process list.
Definition process.h:162
static struct interface_descriptor scsidev_ready_desc
SCSI device TEST UNIT READY interface descriptor.
Definition scsi.c:930
static struct interface_descriptor scsidev_scsi_desc
SCSI device SCSI interface descriptor.
Definition scsi.c:969
static struct interface_descriptor scsidev_block_desc
SCSI device block interface descriptor.
Definition scsi.c:875
static struct process_descriptor scsidev_process_desc
SCSI device process descriptor.
Definition scsi.c:974
#define SCSI_LUN_FORMAT
printf() format for dumping a scsi_lun
Definition scsi.h:241
#define SCSI_LUN_DATA(lun)
printf() parameters for dumping a scsi_lun
Definition scsi.h:244

References block, scsi_device::block, scsi_device::cmds, DBGC, ENOMEM, INIT_LIST_HEAD, intf_init(), intf_plug_plug(), lun, scsi_device::lun, memcpy(), NULL, scsi_device::process, process_init(), scsi_device::ready, ref_init, ref_put, scsi_device::refcnt, scsi_device::scsi, SCSI_LUN_DATA, SCSI_LUN_FORMAT, scsidev_block_desc, scsidev_process_desc, scsidev_ready_desc, scsidev_scsi_desc, and zalloc().

Referenced by fcpdev_open(), iscsi_open(), srp_open(), and usbblk_open_uri().

Variable Documentation

◆ scsicmd_read

struct scsi_command_type scsicmd_read
static
Initial value:
= {
.name = "READ",
.done = scsicmd_close,
}
static void scsicmd_read_cmd(struct scsi_command *scsicmd, struct scsi_cmd *command)
Construct SCSI READ command.
Definition scsi.c:506

SCSI READ command type.

Definition at line 525 of file scsi.c.

525 {
526 .name = "READ",
527 .cmd = scsicmd_read_cmd,
528 .done = scsicmd_close,
529};

Referenced by scsidev_read().

◆ scsicmd_write

struct scsi_command_type scsicmd_write
static
Initial value:
= {
.name = "WRITE",
.done = scsicmd_close,
}
static void scsicmd_write_cmd(struct scsi_command *scsicmd, struct scsi_cmd *command)
Construct SCSI WRITE command.
Definition scsi.c:537

SCSI WRITE command type.

Definition at line 556 of file scsi.c.

556 {
557 .name = "WRITE",
558 .cmd = scsicmd_write_cmd,
559 .done = scsicmd_close,
560};

Referenced by scsidev_write().

◆ scsicmd_read_capacity

struct scsi_command_type scsicmd_read_capacity
static
Initial value:
= {
.name = "READ CAPACITY",
.priv_len = sizeof ( struct scsi_read_capacity_private ),
}
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
static void scsicmd_read_capacity_cmd(struct scsi_command *scsicmd, struct scsi_cmd *command)
Construct SCSI READ CAPACITY command.
Definition scsi.c:581
static void scsicmd_read_capacity_done(struct scsi_command *scsicmd, int rc)
Handle SCSI READ CAPACITY command completion.
Definition scsi.c:611

SCSI READ CAPACITY command type.

Definition at line 661 of file scsi.c.

661 {
662 .name = "READ CAPACITY",
663 .priv_len = sizeof ( struct scsi_read_capacity_private ),
666};

Referenced by scsidev_read_capacity().

◆ scsicmd_test_unit_ready

struct scsi_command_type scsicmd_test_unit_ready
static
Initial value:
= {
.name = "TEST UNIT READY",
.done = scsicmd_close,
}
static void scsicmd_test_unit_ready_cmd(struct scsi_command *scsicmd __unused, struct scsi_cmd *command)
Construct SCSI TEST UNIT READY command.
Definition scsi.c:674

SCSI TEST UNIT READY command type.

Definition at line 682 of file scsi.c.

682 {
683 .name = "TEST UNIT READY",
685 .done = scsicmd_close,
686};

Referenced by scsidev_test_unit_ready().

◆ scsicmd_block_op

struct interface_operation scsicmd_block_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

SCSI command block interface operations.

Definition at line 689 of file scsi.c.

689 {
691};

◆ scsicmd_block_desc

struct interface_descriptor scsicmd_block_desc
static
Initial value:
=
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98
static struct interface_operation scsicmd_block_op[]
SCSI command block interface operations.
Definition scsi.c:689

SCSI command block interface descriptor.

Definition at line 694 of file scsi.c.

Referenced by scsidev_command().

◆ scsicmd_scsi_op

struct interface_operation scsicmd_scsi_op[]
static
Initial value:
= {
}
static void scsicmd_response(struct scsi_command *scsicmd, struct scsi_rsp *response)
Handle SCSI response.
Definition scsi.c:470

SCSI command SCSI interface operations.

Definition at line 699 of file scsi.c.

699 {
702};

◆ scsicmd_scsi_desc

struct interface_descriptor scsicmd_scsi_desc
static
Initial value:
=
static struct interface_operation scsicmd_scsi_op[]
SCSI command SCSI interface operations.
Definition scsi.c:699

SCSI command SCSI interface descriptor.

Definition at line 705 of file scsi.c.

Referenced by scsidev_command().

◆ scsidev_block_op

struct interface_operation scsidev_block_op[]
static
Initial value:
= {
}
int block_read_capacity(struct interface *control, struct interface *data)
Read block device capacity.
Definition blockdev.c:106
int block_write(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Write to block device.
Definition blockdev.c:79
int block_read(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Read from block device.
Definition blockdev.c:48
static int scsidev_write(struct scsi_device *scsidev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
Issue SCSI block write.
Definition scsi.c:793
static size_t scsidev_window(struct scsi_device *scsidev)
Check SCSI device flow-control window.
Definition scsi.c:833
static int scsidev_read_capacity(struct scsi_device *scsidev, struct interface *block)
Read SCSI device capacity.
Definition scsi.c:808
static int scsidev_read(struct scsi_device *scsidev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
Issue SCSI block read.
Definition scsi.c:774

SCSI device block interface operations.

Definition at line 865 of file scsi.c.

◆ scsidev_block_desc

struct interface_descriptor scsidev_block_desc
static
Initial value:
=
static struct interface_operation scsidev_block_op[]
SCSI device block interface operations.
Definition scsi.c:865

SCSI device block interface descriptor.

Definition at line 875 of file scsi.c.

Referenced by scsi_open().

◆ scsidev_ready_op

struct interface_operation scsidev_ready_op[]
static
Initial value:
= {
}
static void scsidev_ready(struct scsi_device *scsidev, int rc)
Handle SCSI TEST UNIT READY response.
Definition scsi.c:885

SCSI device TEST UNIT READY interface operations.

Definition at line 925 of file scsi.c.

925 {
927};

◆ scsidev_ready_desc

struct interface_descriptor scsidev_ready_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation scsidev_ready_op[]
SCSI device TEST UNIT READY interface operations.
Definition scsi.c:925

SCSI device TEST UNIT READY interface descriptor.

Definition at line 930 of file scsi.c.

Referenced by scsi_open().

◆ scsidev_scsi_op

struct interface_operation scsidev_scsi_op[]
static
Initial value:
= {
}
static void scsidev_step(struct scsi_device *scsidev)
SCSI TEST UNIT READY process.
Definition scsi.c:938

SCSI device SCSI interface operations.

Definition at line 963 of file scsi.c.

963 {
966};

◆ scsidev_scsi_desc

struct interface_descriptor scsidev_scsi_desc
static
Initial value:
=
static struct interface_operation scsidev_scsi_op[]
SCSI device SCSI interface operations.
Definition scsi.c:963

SCSI device SCSI interface descriptor.

Definition at line 969 of file scsi.c.

Referenced by scsi_open().

◆ scsidev_process_desc

struct process_descriptor scsidev_process_desc
static
Initial value:
=
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition process.h:98
A process.
Definition process.h:18

SCSI device process descriptor.

Definition at line 974 of file scsi.c.

Referenced by scsi_open().