scsi.c File Reference

SCSI block device. More...

#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_deviceblock_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


Detailed Description

SCSI block device.

Definition in file scsi.c.


Define Documentation

#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().


Function Documentation

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 
)

Handle SCSI command with no backing device.

Parameters:
scsi SCSI device
command SCSI command
Return values:
rc Return status code

Definition at line 55 of file scsi.c.

References ENODEV.

Referenced by iscsi_detach(), and srp_detach().

00056                                                                     {
00057         return -ENODEV;
00058 }

static int scsi_command ( struct scsi_device scsi,
struct scsi_command command 
) [static]

Issue SCSI command.

Parameters:
scsi SCSI device
command SCSI command
Return values:
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).

Parameters:
blockdev Block device
block LBA block number
count Block count
buffer Data buffer
Return values:
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).

Parameters:
blockdev Block device
block LBA block number
count Block count
buffer Data buffer
Return values:
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).

Parameters:
blockdev Block device
block LBA block number
count Block count
buffer Data buffer
Return values:
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).

Parameters:
blockdev Block device
block LBA block number
count Block count
buffer Data buffer
Return values:
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).

Parameters:
blockdev Block device
Return values:
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).

Parameters:
blockdev Block device
Return values:
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.

Parameters:
scsi SCSI device
Return values:
rc Return status code
Initialises a SCSI device. The scsi_device::command and scsi_device::lun fields must already be filled in. This function will configure scsi_device::blockdev, including issuing a READ CAPACITY call to determine the block size and total device size.

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.

Parameters:
lun_string LUN string representation
lun LUN to fill in
Return values:
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 }


Variable Documentation

Initial value:

 {
        .read   = scsi_read_16,
        .write  = scsi_write_16,
}

Definition at line 268 of file scsi.c.

Initial value:

 {
        .read   = scsi_read_10,
        .write  = scsi_write_10,
}

Definition at line 273 of file scsi.c.


Generated on Tue Apr 6 20:01:16 2010 for gPXE by  doxygen 1.5.7.1