#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <gpxe/blockdev.h>
#include <gpxe/process.h>
#include <gpxe/scsi.h>
Go to the source code of this file.
Defines | |
| #define | SCSI_MAX_DUMMY_READ_CAP 10 |
| Maximum number of dummy "read capacity (10)" operations. | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static struct scsi_device * | block_to_scsi (struct block_device *blockdev) |
| int | scsi_detached_command (struct scsi_device *scsi __unused, struct scsi_command *command __unused) |
| Handle SCSI command with no backing device. | |
| static int | scsi_command (struct scsi_device *scsi, struct scsi_command *command) |
| Issue SCSI command. | |
| static int | scsi_read_10 (struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer) |
| Read block from SCSI device using READ (10). | |
| static int | scsi_read_16 (struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer) |
| Read block from SCSI device using READ (16). | |
| static int | scsi_write_10 (struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer) |
| Write block to SCSI device using WRITE (10). | |
| static int | scsi_write_16 (struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer) |
| Write block to SCSI device using WRITE (16). | |
| static int | scsi_read_capacity_10 (struct block_device *blockdev) |
| Read capacity of SCSI device via READ CAPACITY (10). | |
| static int | scsi_read_capacity_16 (struct block_device *blockdev) |
| Read capacity of SCSI device via READ CAPACITY (16). | |
| int | init_scsidev (struct scsi_device *scsi) |
| Initialise SCSI device. | |
| int | scsi_parse_lun (const char *lun_string, struct scsi_lun *lun) |
| Parse SCSI LUN. | |
Variables | |
| static struct block_device_operations | scsi_operations_16 |
| static struct block_device_operations | scsi_operations_10 |
Definition in file scsi.c.
| #define SCSI_MAX_DUMMY_READ_CAP 10 |
Maximum number of dummy "read capacity (10)" operations.
These are issued at connection setup to draw out various useless power-on messages.
Definition at line 41 of file scsi.c.
Referenced by init_scsidev().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static struct scsi_device* block_to_scsi | ( | struct block_device * | blockdev | ) | [static, read] |
Definition at line 44 of file scsi.c.
References container_of.
Referenced by scsi_read_10(), scsi_read_16(), scsi_read_capacity_10(), scsi_read_capacity_16(), scsi_write_10(), and scsi_write_16().
00044 { 00045 return container_of ( blockdev, struct scsi_device, blockdev ); 00046 }
| int scsi_detached_command | ( | struct scsi_device *scsi | __unused, | |
| struct scsi_command *command | __unused | |||
| ) |
| static int scsi_command | ( | struct scsi_device * | scsi, | |
| struct scsi_command * | command | |||
| ) | [static] |
Issue SCSI command.
| rc | Return status code |
Definition at line 67 of file scsi.c.
References scsi_command::cdb, scsi_device::command, DBGC, DBGC2, EINPROGRESS, EIO, scsi_command::rc, SCSI_CDB_DATA, SCSI_CDB_FORMAT, scsi_command::sense_response, scsi_command::status, step(), and strerror().
Referenced by scsi_read_10(), scsi_read_16(), scsi_write_10(), and scsi_write_16().
00068 { 00069 int rc; 00070 00071 DBGC2 ( scsi, "SCSI %p " SCSI_CDB_FORMAT "\n", 00072 scsi, SCSI_CDB_DATA ( command->cdb ) ); 00073 00074 /* Clear sense response code before issuing command */ 00075 command->sense_response = 0; 00076 00077 /* Flag command as in-progress */ 00078 command->rc = -EINPROGRESS; 00079 00080 /* Issue SCSI command */ 00081 if ( ( rc = scsi->command ( scsi, command ) ) != 0 ) { 00082 /* Something went wrong with the issuing mechanism */ 00083 DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " err %s\n", 00084 scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) ); 00085 return rc; 00086 } 00087 00088 /* Wait for command to complete */ 00089 while ( command->rc == -EINPROGRESS ) 00090 step(); 00091 if ( ( rc = command->rc ) != 0 ) { 00092 /* Something went wrong with the command execution */ 00093 DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " err %s\n", 00094 scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) ); 00095 return rc; 00096 } 00097 00098 /* Check for SCSI errors */ 00099 if ( command->status != 0 ) { 00100 DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " status %02x sense " 00101 "%02x\n", scsi, SCSI_CDB_DATA ( command->cdb ), 00102 command->status, command->sense_response ); 00103 return -EIO; 00104 } 00105 00106 return 0; 00107 }
| static int scsi_read_10 | ( | struct block_device * | blockdev, | |
| uint64_t | block, | |||
| unsigned long | count, | |||
| userptr_t | buffer | |||
| ) | [static] |
Read block from SCSI device using READ (10).
| blockdev | Block device | |
| block | LBA block number | |
| count | Block count | |
| buffer | Data buffer |
| rc | Return status code |
Definition at line 118 of file scsi.c.
References block_device::blksize, block_to_scsi(), scsi_command::cdb, cpu_to_be16, cpu_to_be32, scsi_command::data_in, scsi_command::data_in_len, scsi_cdb_read_10::lba, scsi_cdb_read_10::len, memset(), scsi_cdb_read_10::opcode, scsi_cdb::read10, scsi_command(), and SCSI_OPCODE_READ_10.
00119 { 00120 struct scsi_device *scsi = block_to_scsi ( blockdev ); 00121 struct scsi_command command; 00122 struct scsi_cdb_read_10 *cdb = &command.cdb.read10; 00123 00124 /* Issue READ (10) */ 00125 memset ( &command, 0, sizeof ( command ) ); 00126 cdb->opcode = SCSI_OPCODE_READ_10; 00127 cdb->lba = cpu_to_be32 ( block ); 00128 cdb->len = cpu_to_be16 ( count ); 00129 command.data_in = buffer; 00130 command.data_in_len = ( count * blockdev->blksize ); 00131 return scsi_command ( scsi, &command ); 00132 }
| static int scsi_read_16 | ( | struct block_device * | blockdev, | |
| uint64_t | block, | |||
| unsigned long | count, | |||
| userptr_t | buffer | |||
| ) | [static] |
Read block from SCSI device using READ (16).
| blockdev | Block device | |
| block | LBA block number | |
| count | Block count | |
| buffer | Data buffer |
| rc | Return status code |
Definition at line 143 of file scsi.c.
References block_device::blksize, block_to_scsi(), scsi_command::cdb, cpu_to_be32, cpu_to_be64, scsi_command::data_in, scsi_command::data_in_len, scsi_cdb_read_16::lba, scsi_cdb_read_16::len, memset(), scsi_cdb_read_16::opcode, scsi_cdb::read16, scsi_command(), and SCSI_OPCODE_READ_16.
00144 { 00145 struct scsi_device *scsi = block_to_scsi ( blockdev ); 00146 struct scsi_command command; 00147 struct scsi_cdb_read_16 *cdb = &command.cdb.read16; 00148 00149 /* Issue READ (16) */ 00150 memset ( &command, 0, sizeof ( command ) ); 00151 cdb->opcode = SCSI_OPCODE_READ_16; 00152 cdb->lba = cpu_to_be64 ( block ); 00153 cdb->len = cpu_to_be32 ( count ); 00154 command.data_in = buffer; 00155 command.data_in_len = ( count * blockdev->blksize ); 00156 return scsi_command ( scsi, &command ); 00157 }
| static int scsi_write_10 | ( | struct block_device * | blockdev, | |
| uint64_t | block, | |||
| unsigned long | count, | |||
| userptr_t | buffer | |||
| ) | [static] |
Write block to SCSI device using WRITE (10).
| blockdev | Block device | |
| block | LBA block number | |
| count | Block count | |
| buffer | Data buffer |
| rc | Return status code |
Definition at line 168 of file scsi.c.
References block_device::blksize, block_to_scsi(), scsi_command::cdb, cpu_to_be16, cpu_to_be32, scsi_command::data_out, scsi_command::data_out_len, scsi_cdb_write_10::lba, scsi_cdb_write_10::len, memset(), scsi_cdb_write_10::opcode, scsi_command(), SCSI_OPCODE_WRITE_10, and scsi_cdb::write10.
00169 { 00170 struct scsi_device *scsi = block_to_scsi ( blockdev ); 00171 struct scsi_command command; 00172 struct scsi_cdb_write_10 *cdb = &command.cdb.write10; 00173 00174 /* Issue WRITE (10) */ 00175 memset ( &command, 0, sizeof ( command ) ); 00176 cdb->opcode = SCSI_OPCODE_WRITE_10; 00177 cdb->lba = cpu_to_be32 ( block ); 00178 cdb->len = cpu_to_be16 ( count ); 00179 command.data_out = buffer; 00180 command.data_out_len = ( count * blockdev->blksize ); 00181 return scsi_command ( scsi, &command ); 00182 }
| static int scsi_write_16 | ( | struct block_device * | blockdev, | |
| uint64_t | block, | |||
| unsigned long | count, | |||
| userptr_t | buffer | |||
| ) | [static] |
Write block to SCSI device using WRITE (16).
| blockdev | Block device | |
| block | LBA block number | |
| count | Block count | |
| buffer | Data buffer |
| rc | Return status code |
Definition at line 193 of file scsi.c.
References block_device::blksize, block_to_scsi(), scsi_command::cdb, cpu_to_be32, cpu_to_be64, scsi_command::data_out, scsi_command::data_out_len, scsi_cdb_write_16::lba, scsi_cdb_write_16::len, memset(), scsi_cdb_write_16::opcode, scsi_command(), SCSI_OPCODE_WRITE_16, and scsi_cdb::write16.
00194 { 00195 struct scsi_device *scsi = block_to_scsi ( blockdev ); 00196 struct scsi_command command; 00197 struct scsi_cdb_write_16 *cdb = &command.cdb.write16; 00198 00199 /* Issue WRITE (16) */ 00200 memset ( &command, 0, sizeof ( command ) ); 00201 cdb->opcode = SCSI_OPCODE_WRITE_16; 00202 cdb->lba = cpu_to_be64 ( block ); 00203 cdb->len = cpu_to_be32 ( count ); 00204 command.data_out = buffer; 00205 command.data_out_len = ( count * blockdev->blksize ); 00206 return scsi_command ( scsi, &command ); 00207 }
| static int scsi_read_capacity_10 | ( | struct block_device * | blockdev | ) | [static] |
Read capacity of SCSI device via READ CAPACITY (10).
| blockdev | Block device |
| rc | Return status code |
Definition at line 215 of file scsi.c.
References be32_to_cpu, scsi_capacity_10::blksize, block_device::blksize, block_to_scsi(), block_device::blocks, scsi_command::cdb, scsi_command::data_in, scsi_command::data_in_len, scsi_capacity_10::lba, memset(), scsi_cdb_read_capacity_10::opcode, scsi_cdb::readcap10, SCSI_OPCODE_READ_CAPACITY_10, and virt_to_user().
Referenced by init_scsidev().
00215 { 00216 struct scsi_device *scsi = block_to_scsi ( blockdev ); 00217 struct scsi_command command; 00218 struct scsi_cdb_read_capacity_10 *cdb = &command.cdb.readcap10; 00219 struct scsi_capacity_10 capacity; 00220 int rc; 00221 00222 /* Issue READ CAPACITY (10) */ 00223 memset ( &command, 0, sizeof ( command ) ); 00224 cdb->opcode = SCSI_OPCODE_READ_CAPACITY_10; 00225 command.data_in = virt_to_user ( &capacity ); 00226 command.data_in_len = sizeof ( capacity ); 00227 00228 if ( ( rc = scsi_command ( scsi, &command ) ) != 0 ) 00229 return rc; 00230 00231 /* Fill in block device fields */ 00232 blockdev->blksize = be32_to_cpu ( capacity.blksize ); 00233 blockdev->blocks = ( be32_to_cpu ( capacity.lba ) + 1 ); 00234 00235 return 0; 00236 }
| static int scsi_read_capacity_16 | ( | struct block_device * | blockdev | ) | [static] |
Read capacity of SCSI device via READ CAPACITY (16).
| blockdev | Block device |
| rc | Return status code |
Definition at line 244 of file scsi.c.
References be32_to_cpu, be64_to_cpu, scsi_capacity_16::blksize, block_device::blksize, block_to_scsi(), block_device::blocks, scsi_command::cdb, cpu_to_be32, scsi_command::data_in, scsi_command::data_in_len, scsi_capacity_16::lba, scsi_cdb_read_capacity_16::len, memset(), scsi_cdb_read_capacity_16::opcode, scsi_cdb::readcap16, SCSI_OPCODE_SERVICE_ACTION_IN, SCSI_SERVICE_ACTION_READ_CAPACITY_16, scsi_cdb_read_capacity_16::service_action, and virt_to_user().
Referenced by init_scsidev().
00244 { 00245 struct scsi_device *scsi = block_to_scsi ( blockdev ); 00246 struct scsi_command command; 00247 struct scsi_cdb_read_capacity_16 *cdb = &command.cdb.readcap16; 00248 struct scsi_capacity_16 capacity; 00249 int rc; 00250 00251 /* Issue READ CAPACITY (16) */ 00252 memset ( &command, 0, sizeof ( command ) ); 00253 cdb->opcode = SCSI_OPCODE_SERVICE_ACTION_IN; 00254 cdb->service_action = SCSI_SERVICE_ACTION_READ_CAPACITY_16; 00255 cdb->len = cpu_to_be32 ( sizeof ( capacity ) ); 00256 command.data_in = virt_to_user ( &capacity ); 00257 command.data_in_len = sizeof ( capacity ); 00258 00259 if ( ( rc = scsi_command ( scsi, &command ) ) != 0 ) 00260 return rc; 00261 00262 /* Fill in block device fields */ 00263 blockdev->blksize = be32_to_cpu ( capacity.blksize ); 00264 blockdev->blocks = ( be64_to_cpu ( capacity.lba ) + 1 ); 00265 return 0; 00266 }
| int init_scsidev | ( | struct scsi_device * | scsi | ) |
Initialise SCSI device.
| scsi | SCSI device |
| rc | Return status code |
Definition at line 289 of file scsi.c.
References scsi_device::blockdev, block_device::blocks, DBGC, block_device::op, SCSI_MAX_DUMMY_READ_CAP, scsi_read_capacity_10(), scsi_read_capacity_16(), and strerror().
Referenced by ib_srpboot(), and iscsiboot().
00289 { 00290 unsigned int i; 00291 int rc; 00292 00293 /* Issue some theoretically extraneous READ CAPACITY (10) 00294 * commands, solely in order to draw out the "CHECK CONDITION 00295 * (power-on occurred)", "CHECK CONDITION (reported LUNs data 00296 * has changed)" etc. that some dumb targets insist on sending 00297 * as an error at start of day. The precise command that we 00298 * use is unimportant; we just need to provide the target with 00299 * an opportunity to send its responses. 00300 */ 00301 for ( i = 0 ; i < SCSI_MAX_DUMMY_READ_CAP ; i++ ) { 00302 if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) == 0 ) 00303 break; 00304 DBGC ( scsi, "SCSI %p ignoring start-of-day error (#%d)\n", 00305 scsi, ( i + 1 ) ); 00306 } 00307 00308 /* Try READ CAPACITY (10), which is a mandatory command, first. */ 00309 scsi->blockdev.op = &scsi_operations_10; 00310 if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) != 0 ) { 00311 DBGC ( scsi, "SCSI %p could not READ CAPACITY (10): %s\n", 00312 scsi, strerror ( rc ) ); 00313 return rc; 00314 } 00315 00316 /* If capacity range was exceeded (i.e. capacity.lba was 00317 * 0xffffffff, meaning that blockdev->blocks is now zero), use 00318 * READ CAPACITY (16) instead. READ CAPACITY (16) is not 00319 * mandatory, so we can't just use it straight off. 00320 */ 00321 if ( scsi->blockdev.blocks == 0 ) { 00322 scsi->blockdev.op = &scsi_operations_16; 00323 if ( ( rc = scsi_read_capacity_16 ( &scsi->blockdev ) ) != 0 ){ 00324 DBGC ( scsi, "SCSI %p could not READ CAPACITY (16): " 00325 "%s\n", scsi, strerror ( rc ) ); 00326 return rc; 00327 } 00328 } 00329 00330 DBGC ( scsi, "SCSI %p using READ/WRITE (%d) commands\n", scsi, 00331 ( ( scsi->blockdev.op == &scsi_operations_10 ) ? 10 : 16 ) ); 00332 DBGC ( scsi, "SCSI %p capacity is %ld MB (%#llx blocks)\n", scsi, 00333 ( ( unsigned long ) ( scsi->blockdev.blocks >> 11 ) ), 00334 scsi->blockdev.blocks ); 00335 00336 return 0; 00337 }
| int scsi_parse_lun | ( | const char * | lun_string, | |
| struct scsi_lun * | lun | |||
| ) |
Parse SCSI LUN.
| lun_string | LUN string representation | |
| lun | LUN to fill in |
| rc | Return status code |
Definition at line 346 of file scsi.c.
References EINVAL, htons, memset(), strtoul(), and scsi_lun::u16.
Referenced by ib_srp_parse_lun(), and iscsi_parse_root_path().
00346 { 00347 char *p; 00348 int i; 00349 00350 memset ( lun, 0, sizeof ( *lun ) ); 00351 if ( lun_string ) { 00352 p = ( char * ) lun_string; 00353 for ( i = 0 ; i < 4 ; i++ ) { 00354 lun->u16[i] = htons ( strtoul ( p, &p, 16 ) ); 00355 if ( *p == '\0' ) 00356 break; 00357 if ( *p != '-' ) 00358 return -EINVAL; 00359 p++; 00360 } 00361 if ( *p ) 00362 return -EINVAL; 00363 } 00364 00365 return 0; 00366 }
struct block_device_operations scsi_operations_16 [static] |
Initial value:
{
.read = scsi_read_16,
.write = scsi_write_16,
}
struct block_device_operations scsi_operations_10 [static] |
Initial value:
{
.read = scsi_read_10,
.write = scsi_write_10,
}
1.5.7.1