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
#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:516

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:307
uint16_t additional
Additional sense code and qualifier.
Definition scsi.h:286
uint16_t additional
Additional sense code and qualifier.
Definition scsi.h:276
SCSI sense data.
Definition scsi.h:290
struct scsi_sns_fixed fixed
Fixed-format sense data.
Definition scsi.h:294
uint8_t code
Response code.
Definition scsi.h:292
struct scsi_sns_descriptor desc
Descriptor-format sense data.
Definition scsi.h:296

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:333
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:338
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:321
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:530
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 xferbuf_void_init ( &command.data_in );
426 xferbuf_void_init ( &command.data_out );
427 scsicmd->type->cmd ( scsicmd, &command );
428
429 /* Issue command */
430 if ( ( tag = scsi_command ( &scsidev->scsi, &scsicmd->scsi,
431 &command ) ) < 0 ) {
432 rc = tag;
433 DBGC ( scsidev, "SCSI %p could not issue command: %s\n",
434 scsidev, strerror ( rc ) );
435 return rc;
436 }
437
438 /* Record tag */
439 if ( scsicmd->tag ) {
440 DBGC ( scsidev, "SCSI %p tag %08x is now tag %08x\n",
441 scsidev, scsicmd->tag, tag );
442 }
443 scsicmd->tag = tag;
444 DBGC2 ( scsidev, "SCSI %p tag %08x %s " SCSI_CDB_FORMAT "\n",
445 scsidev, scsicmd->tag, scsicmd->type->name,
446 SCSI_CDB_DATA ( command.cdb ) );
447
448 return 0;
449}
uint64_t tag
Identity tag.
Definition edd.h:1
#define DBGC2(...)
Definition compiler.h:547
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:224
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:220
A SCSI command information unit.
Definition scsi.h:250
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
static void xferbuf_void_init(struct xfer_buffer *xferbuf)
Initialise void data transfer buffer.
Definition xferbuf.h:108

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, scsi_command::type, and xferbuf_void_init().

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 457 of file scsi.c.

457 {
458
459 /* Restart SCSI interface */
460 intf_restart ( &scsicmd->scsi, rc );
461
462 /* Hand over to the command completion handler */
463 scsicmd->type->done ( scsicmd, rc );
464}
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 472 of file scsi.c.

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

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 508 of file scsi.c.

509 {
510
511 if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
512 /* Use READ (16) */
513 command->cdb.read16.opcode = SCSI_OPCODE_READ_16;
514 command->cdb.read16.lba = cpu_to_be64 ( scsicmd->lba );
515 command->cdb.read16.len = cpu_to_be32 ( scsicmd->count );
516 } else {
517 /* Use READ (10) */
518 command->cdb.read10.opcode = SCSI_OPCODE_READ_10;
519 command->cdb.read10.lba = cpu_to_be32 ( scsicmd->lba );
520 command->cdb.read10.len = cpu_to_be16 ( scsicmd->count );
521 }
522 xferbuf_fixed_init ( &command->data_in, scsicmd->buffer,
523 scsicmd->len );
524}
#define SCSI_OPCODE_READ_10
READ (10).
Definition scsi.h:25
#define SCSI_OPCODE_READ_16
READ (16).
Definition scsi.h:26
#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:18
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
static void xferbuf_fixed_init(struct xfer_buffer *xferbuf, void *data, size_t len)
Initialise fixed-size data transfer buffer.
Definition xferbuf.h:93

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, SCSI_OPCODE_READ_16, and xferbuf_fixed_init().

◆ 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 539 of file scsi.c.

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

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, SCSI_OPCODE_WRITE_16, and xferbuf_fixed_init().

◆ 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 583 of file scsi.c.

584 {
585 struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
586 struct scsi_cdb_read_capacity_16 *readcap16 = &command->cdb.readcap16;
587 struct scsi_cdb_read_capacity_10 *readcap10 = &command->cdb.readcap10;
588 struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
589 struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
590
591 if ( priv->use16 ) {
592 /* Use READ CAPACITY (16) */
594 readcap16->service_action =
596 readcap16->len = cpu_to_be32 ( sizeof ( *capacity16 ) );
597 xferbuf_fixed_init ( &command->data_in, capacity16,
598 sizeof ( *capacity16 ) );
599 } else {
600 /* Use READ CAPACITY (10) */
602 xferbuf_fixed_init ( &command->data_in, capacity10,
603 sizeof ( *capacity10 ) );
604 }
605}
#define SCSI_OPCODE_SERVICE_ACTION_IN
SERVICE ACTION IN.
Definition scsi.h:30
#define SCSI_OPCODE_READ_CAPACITY_10
READ CAPACITY (10).
Definition scsi.h:29
#define SCSI_SERVICE_ACTION_READ_CAPACITY_16
READ CAPACITY (16).
Definition scsi.h:31
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:158
SCSI "READ CAPACITY (16)" parameter data.
Definition scsi.h:188
A SCSI "READ CAPACITY (10)" CDB.
Definition scsi.h:141
uint8_t opcode
Opcode (0x25).
Definition scsi.h:143
A SCSI "READ CAPACITY (16)" CDB.
Definition scsi.h:166
uint8_t service_action
Service action.
Definition scsi.h:170
uint8_t opcode
Opcode (0x9e).
Definition scsi.h:168
uint32_t len
Transfer length.
Definition scsi.h:180
SCSI READ CAPACITY private data.
Definition scsi.c:565
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(), scsi_cdb_read_capacity_16::service_action, and xferbuf_fixed_init().

◆ 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 613 of file scsi.c.

614 {
615 struct scsi_device *scsidev = scsicmd->scsidev;
616 struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
617 struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
618 struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
619 struct block_device_capacity capacity;
620
621 /* Close if command failed */
622 if ( rc != 0 ) {
623 scsicmd_close ( scsicmd, rc );
624 return;
625 }
626
627 /* Extract capacity */
628 if ( priv->use16 ) {
629 capacity.blocks = ( be64_to_cpu ( capacity16->lba ) + 1 );
630 capacity.blksize = be32_to_cpu ( capacity16->blksize );
631 } else {
632 capacity.blocks = ( be32_to_cpu ( capacity10->lba ) + 1 );
633 capacity.blksize = be32_to_cpu ( capacity10->blksize );
634
635 /* If capacity range was exceeded (i.e. capacity.lba
636 * was 0xffffffff, meaning that blockdev->blocks is
637 * now zero), use READ CAPACITY (16) instead. READ
638 * CAPACITY (16) is not mandatory, so we can't just
639 * use it straight off.
640 */
641 if ( capacity.blocks == 0 ) {
642 priv->use16 = 1;
643 if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 ) {
644 scsicmd_close ( scsicmd, rc );
645 return;
646 }
647 return;
648 }
649 }
650 capacity.max_count = -1U;
651
652 /* Allow transport layer to update capacity */
653 block_capacity ( &scsidev->scsi, &capacity );
654
655 /* Return capacity to caller */
656 block_capacity ( &scsicmd->block, &capacity );
657
658 /* Close command */
659 scsicmd_close ( scsicmd, 0 );
660}
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:160
uint32_t blksize
Block length in bytes.
Definition scsi.h:162
uint32_t blksize
Block length in bytes.
Definition scsi.h:192
uint64_t lba
Maximum logical block number.
Definition scsi.h:190

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 676 of file scsi.c.

677 {
678 struct scsi_cdb_test_unit_ready *testready = &command->cdb.testready;
679
681}
#define SCSI_OPCODE_TEST_UNIT_READY
TEST UNIT READY.
Definition scsi.h:32
A SCSI "TEST UNIT READY" CDB.
Definition scsi.h:198
uint8_t opcode
Opcode (0x00).
Definition scsi.h:200

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 723 of file scsi.c.

727 {
728 struct scsi_command *scsicmd;
729 int rc;
730
731 /* Allocate and initialise structure */
732 scsicmd = zalloc ( sizeof ( *scsicmd ) + type->priv_len );
733 if ( ! scsicmd ) {
734 rc = -ENOMEM;
735 goto err_zalloc;
736 }
737 ref_init ( &scsicmd->refcnt, scsicmd_free );
738 intf_init ( &scsicmd->block, &scsicmd_block_desc, &scsicmd->refcnt );
739 intf_init ( &scsicmd->scsi, &scsicmd_scsi_desc,
740 &scsicmd->refcnt );
741 scsicmd->scsidev = scsidev_get ( scsidev );
742 list_add ( &scsicmd->list, &scsidev->cmds );
743 scsicmd->type = type;
744 scsicmd->lba = lba;
745 scsicmd->count = count;
746 scsicmd->buffer = buffer;
747 scsicmd->len = len;
748
749 /* Issue SCSI command */
750 if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 )
751 goto err_command;
752
753 /* Attach to parent interface, transfer reference to list, and return */
754 intf_plug_plug ( &scsicmd->block, block );
755 return 0;
756
757 err_command:
758 scsicmd_close ( scsicmd, rc );
759 ref_put ( &scsicmd->refcnt );
760 err_zalloc:
761 return rc;
762}
uint32_t type
Operating system type.
Definition ena.h:1
uint64_t lba
Starting block number.
Definition int13.h:11
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
#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:707
static struct interface_descriptor scsicmd_block_desc
SCSI command block interface descriptor.
Definition scsi.c:696
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 776 of file scsi.c.

779 {
780 return scsidev_command ( scsidev, block, &scsicmd_read,
781 lba, count, buffer, len );
782}
static struct scsi_command_type scsicmd_read
SCSI READ command type.
Definition scsi.c:527
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:723

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 795 of file scsi.c.

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

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 810 of file scsi.c.

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

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 823 of file scsi.c.

824 {
826 0, 0, NULL, 0 );
827}
static struct scsi_command_type scsicmd_test_unit_ready
SCSI TEST UNIT READY command type.
Definition scsi.c:684

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 835 of file scsi.c.

835 {
836
837 /* Refuse commands until unit is confirmed ready */
838 if ( ! ( scsidev->flags & SCSIDEV_UNIT_READY ) )
839 return 0;
840
841 return xfer_window ( &scsidev->scsi );
842}
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 850 of file scsi.c.

850 {
851 struct scsi_command *scsicmd;
852 struct scsi_command *tmp;
853
854 /* Stop process */
856
857 /* Shut down interfaces */
859 NULL );
860
861 /* Shut down any remaining commands */
863 scsicmd_close ( scsicmd, rc );
864}
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 887 of file scsi.c.

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

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

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 987 of file scsi.c.

988 {
989 struct scsi_device *scsidev;
990
991 /* Allocate and initialise structure */
992 scsidev = zalloc ( sizeof ( *scsidev ) );
993 if ( ! scsidev )
994 return -ENOMEM;
995 ref_init ( &scsidev->refcnt, NULL );
996 intf_init ( &scsidev->block, &scsidev_block_desc, &scsidev->refcnt );
997 intf_init ( &scsidev->scsi, &scsidev_scsi_desc, &scsidev->refcnt );
998 intf_init ( &scsidev->ready, &scsidev_ready_desc, &scsidev->refcnt );
1000 &scsidev->refcnt );
1001 INIT_LIST_HEAD ( &scsidev->cmds );
1002 memcpy ( &scsidev->lun, lun, sizeof ( scsidev->lun ) );
1003 DBGC ( scsidev, "SCSI %p created for LUN " SCSI_LUN_FORMAT "\n",
1004 scsidev, SCSI_LUN_DATA ( scsidev->lun ) );
1005
1006 /* Attach to SCSI and parent interfaces, mortalise self, and return */
1007 intf_plug_plug ( &scsidev->scsi, scsi );
1008 intf_plug_plug ( &scsidev->block, block );
1009 ref_put ( &scsidev->refcnt );
1010 return 0;
1011}
#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:932
static struct interface_descriptor scsidev_scsi_desc
SCSI device SCSI interface descriptor.
Definition scsi.c:971
static struct interface_descriptor scsidev_block_desc
SCSI device block interface descriptor.
Definition scsi.c:877
static struct process_descriptor scsidev_process_desc
SCSI device process descriptor.
Definition scsi.c:976
#define SCSI_LUN_FORMAT
printf() format for dumping a scsi_lun
Definition scsi.h:242
#define SCSI_LUN_DATA(lun)
printf() parameters for dumping a scsi_lun
Definition scsi.h:245

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:508

SCSI READ command type.

Definition at line 527 of file scsi.c.

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

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:539

SCSI WRITE command type.

Definition at line 558 of file scsi.c.

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

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:583
static void scsicmd_read_capacity_done(struct scsi_command *scsicmd, int rc)
Handle SCSI READ CAPACITY command completion.
Definition scsi.c:613

SCSI READ CAPACITY command type.

Definition at line 663 of file scsi.c.

663 {
664 .name = "READ CAPACITY",
665 .priv_len = sizeof ( struct scsi_read_capacity_private ),
668};

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:676

SCSI TEST UNIT READY command type.

Definition at line 684 of file scsi.c.

684 {
685 .name = "TEST UNIT READY",
687 .done = scsicmd_close,
688};

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 691 of file scsi.c.

691 {
693};

◆ 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:691

SCSI command block interface descriptor.

Definition at line 696 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:472

SCSI command SCSI interface operations.

Definition at line 701 of file scsi.c.

701 {
704};

◆ 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:701

SCSI command SCSI interface descriptor.

Definition at line 707 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:795
static size_t scsidev_window(struct scsi_device *scsidev)
Check SCSI device flow-control window.
Definition scsi.c:835
static int scsidev_read_capacity(struct scsi_device *scsidev, struct interface *block)
Read SCSI device capacity.
Definition scsi.c:810
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:776

SCSI device block interface operations.

Definition at line 867 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:867

SCSI device block interface descriptor.

Definition at line 877 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:887

SCSI device TEST UNIT READY interface operations.

Definition at line 927 of file scsi.c.

927 {
929};

◆ 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:927

SCSI device TEST UNIT READY interface descriptor.

Definition at line 932 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:940

SCSI device SCSI interface operations.

Definition at line 965 of file scsi.c.

965 {
968};

◆ 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:965

SCSI device SCSI interface descriptor.

Definition at line 971 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 976 of file scsi.c.

Referenced by scsi_open().