Annotation of qemu/roms/ipxe/src/drivers/block/scsi.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2006 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <stddef.h>
                     22: #include <stdlib.h>
                     23: #include <string.h>
                     24: #include <byteswap.h>
                     25: #include <errno.h>
                     26: #include <ipxe/list.h>
                     27: #include <ipxe/process.h>
                     28: #include <ipxe/xfer.h>
                     29: #include <ipxe/blockdev.h>
                     30: #include <ipxe/scsi.h>
                     31: 
                     32: /** @file
                     33:  *
                     34:  * SCSI block device
                     35:  *
                     36:  */
                     37: 
                     38: /** Maximum number of command retries */
                     39: #define SCSICMD_MAX_RETRIES 10
                     40: 
                     41: /* Error numbers generated by SCSI sense data */
                     42: #define EIO_NO_SENSE __einfo_error ( EINFO_EIO_NO_SENSE )
                     43: #define EINFO_EIO_NO_SENSE \
                     44:        __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )
                     45: #define EIO_RECOVERED_ERROR __einfo_error ( EINFO_EIO_RECOVERED_ERROR )
                     46: #define EINFO_EIO_RECOVERED_ERROR \
                     47:        __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )
                     48: #define EIO_NOT_READY __einfo_error ( EINFO_EIO_NOT_READY )
                     49: #define EINFO_EIO_NOT_READY \
                     50:        __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )
                     51: #define EIO_MEDIUM_ERROR __einfo_error ( EINFO_EIO_MEDIUM_ERROR )
                     52: #define EINFO_EIO_MEDIUM_ERROR \
                     53:        __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )
                     54: #define EIO_HARDWARE_ERROR __einfo_error ( EINFO_EIO_HARDWARE_ERROR )
                     55: #define EINFO_EIO_HARDWARE_ERROR \
                     56:        __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )
                     57: #define EIO_ILLEGAL_REQUEST __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )
                     58: #define EINFO_EIO_ILLEGAL_REQUEST \
                     59:        __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )
                     60: #define EIO_UNIT_ATTENTION __einfo_error ( EINFO_EIO_UNIT_ATTENTION )
                     61: #define EINFO_EIO_UNIT_ATTENTION \
                     62:        __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )
                     63: #define EIO_DATA_PROTECT __einfo_error ( EINFO_EIO_DATA_PROTECT )
                     64: #define EINFO_EIO_DATA_PROTECT \
                     65:        __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )
                     66: #define EIO_BLANK_CHECK __einfo_error ( EINFO_EIO_BLANK_CHECK )
                     67: #define EINFO_EIO_BLANK_CHECK \
                     68:        __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )
                     69: #define EIO_VENDOR_SPECIFIC __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )
                     70: #define EINFO_EIO_VENDOR_SPECIFIC \
                     71:        __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )
                     72: #define EIO_COPY_ABORTED __einfo_error ( EINFO_EIO_COPY_ABORTED )
                     73: #define EINFO_EIO_COPY_ABORTED \
                     74:        __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )
                     75: #define EIO_ABORTED_COMMAND __einfo_error ( EINFO_EIO_ABORTED_COMMAND )
                     76: #define EINFO_EIO_ABORTED_COMMAND \
                     77:        __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )
                     78: #define EIO_RESERVED __einfo_error ( EINFO_EIO_RESERVED )
                     79: #define EINFO_EIO_RESERVED \
                     80:        __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )
                     81: #define EIO_VOLUME_OVERFLOW __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )
                     82: #define EINFO_EIO_VOLUME_OVERFLOW \
                     83:        __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )
                     84: #define EIO_MISCOMPARE __einfo_error ( EINFO_EIO_MISCOMPARE )
                     85: #define EINFO_EIO_MISCOMPARE \
                     86:        __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )
                     87: #define EIO_COMPLETED __einfo_error ( EINFO_EIO_COMPLETED )
                     88: #define EINFO_EIO_COMPLETED \
                     89:        __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )
                     90: #define EIO_SENSE( key )                                               \
                     91:        EUNIQ ( EIO, (key), EIO_NO_SENSE, EIO_RECOVERED_ERROR,          \
                     92:                EIO_NOT_READY, EIO_MEDIUM_ERROR, EIO_HARDWARE_ERROR,    \
                     93:                EIO_ILLEGAL_REQUEST, EIO_UNIT_ATTENTION,                \
                     94:                EIO_DATA_PROTECT, EIO_BLANK_CHECK, EIO_VENDOR_SPECIFIC, \
                     95:                EIO_COPY_ABORTED, EIO_ABORTED_COMMAND, EIO_RESERVED,    \
                     96:                EIO_VOLUME_OVERFLOW, EIO_MISCOMPARE, EIO_COMPLETED )
                     97: 
                     98: /******************************************************************************
                     99:  *
                    100:  * Utility functions
                    101:  *
                    102:  ******************************************************************************
                    103:  */
                    104: 
                    105: /**
                    106:  * Parse SCSI LUN
                    107:  *
                    108:  * @v lun_string       LUN string representation
                    109:  * @v lun              LUN to fill in
                    110:  * @ret rc             Return status code
                    111:  */
                    112: int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) {
                    113:        char *p;
                    114:        int i;
                    115: 
                    116:        memset ( lun, 0, sizeof ( *lun ) );
                    117:        if ( lun_string ) {
                    118:                p = ( char * ) lun_string;
                    119:                for ( i = 0 ; i < 4 ; i++ ) {
                    120:                        lun->u16[i] = htons ( strtoul ( p, &p, 16 ) );
                    121:                        if ( *p == '\0' )
                    122:                                break;
                    123:                        if ( *p != '-' )
                    124:                                return -EINVAL;
                    125:                        p++;
                    126:                }
                    127:                if ( *p )
                    128:                        return -EINVAL;
                    129:        }
                    130: 
                    131:        return 0;
                    132: }
                    133: 
                    134: /******************************************************************************
                    135:  *
                    136:  * Interface methods
                    137:  *
                    138:  ******************************************************************************
                    139:  */
                    140: 
                    141: /**
                    142:  * Issue SCSI command
                    143:  *
                    144:  * @v control          SCSI control interface
                    145:  * @v data             SCSI data interface
                    146:  * @v command          SCSI command
                    147:  * @ret tag            Command tag, or negative error
                    148:  */
                    149: int scsi_command ( struct interface *control, struct interface *data,
                    150:                   struct scsi_cmd *command ) {
                    151:        struct interface *dest;
                    152:        scsi_command_TYPE ( void * ) *op =
                    153:                intf_get_dest_op ( control, scsi_command, &dest );
                    154:        void *object = intf_object ( dest );
                    155:        int tap;
                    156: 
                    157:        if ( op ) {
                    158:                tap = op ( object, data, command );
                    159:        } else {
                    160:                /* Default is to fail to issue the command */
                    161:                tap = -EOPNOTSUPP;
                    162:        }
                    163: 
                    164:        intf_put ( dest );
                    165:        return tap;
                    166: }
                    167: 
                    168: /**
                    169:  * Report SCSI response
                    170:  *
                    171:  * @v interface                SCSI command interface
                    172:  * @v response         SCSI response
                    173:  */
                    174: void scsi_response ( struct interface *intf, struct scsi_rsp *response ) {
                    175:        struct interface *dest;
                    176:        scsi_response_TYPE ( void * ) *op =
                    177:                intf_get_dest_op ( intf, scsi_response, &dest );
                    178:        void *object = intf_object ( dest );
                    179: 
                    180:        if ( op ) {
                    181:                op ( object, response );
                    182:        } else {
                    183:                /* Default is to ignore the response */
                    184:        }
                    185: 
                    186:        intf_put ( dest );
                    187: }
                    188: 
                    189: /******************************************************************************
                    190:  *
                    191:  * SCSI devices and commands
                    192:  *
                    193:  ******************************************************************************
                    194:  */
                    195: 
                    196: /** A SCSI device */
                    197: struct scsi_device {
                    198:        /** Reference count */
                    199:        struct refcnt refcnt;
                    200:        /** Block control interface */
                    201:        struct interface block;
                    202:        /** SCSI control interface */
                    203:        struct interface scsi;
                    204: 
                    205:        /** SCSI LUN */
                    206:        struct scsi_lun lun;
                    207:        /** Flags */
                    208:        unsigned int flags;
                    209: 
                    210:        /** TEST UNIT READY interface */
                    211:        struct interface ready;
                    212:        /** TEST UNIT READY process */
                    213:        struct process process;
                    214: 
                    215:        /** List of commands */
                    216:        struct list_head cmds;
                    217: };
                    218: 
                    219: /** SCSI device flags */
                    220: enum scsi_device_flags {
                    221:        /** Unit is ready */
                    222:        SCSIDEV_UNIT_READY = 0x0001,
                    223: };
                    224: 
                    225: /** A SCSI command */
                    226: struct scsi_command {
                    227:        /** Reference count */
                    228:        struct refcnt refcnt;
                    229:        /** SCSI device */
                    230:        struct scsi_device *scsidev;
                    231:        /** List of SCSI commands */
                    232:        struct list_head list;
                    233: 
                    234:        /** Block data interface */
                    235:        struct interface block;
                    236:        /** SCSI data interface */
                    237:        struct interface scsi;
                    238: 
                    239:        /** Command type */
                    240:        struct scsi_command_type *type;
                    241:        /** Starting logical block address */
                    242:        uint64_t lba;
                    243:        /** Number of blocks */
                    244:        unsigned int count;
                    245:        /** Data buffer */
                    246:        userptr_t buffer;
                    247:        /** Length of data buffer */
                    248:        size_t len;
                    249:        /** Command tag */
                    250:        uint32_t tag;
                    251: 
                    252:        /** Retry count */
                    253:        unsigned int retries;
                    254: 
                    255:        /** Private data */
                    256:        uint8_t priv[0];
                    257: };
                    258: 
                    259: /** A SCSI command type */
                    260: struct scsi_command_type {
                    261:        /** Name */
                    262:        const char *name;
                    263:        /** Additional working space */
                    264:        size_t priv_len;
                    265:        /**
                    266:         * Construct SCSI command IU
                    267:         *
                    268:         * @v scsicmd           SCSI command
                    269:         * @v command           SCSI command IU
                    270:         */
                    271:        void ( * cmd ) ( struct scsi_command *scsicmd,
                    272:                         struct scsi_cmd *command );
                    273:        /**
                    274:         * Handle SCSI command completion
                    275:         *
                    276:         * @v scsicmd           SCSI command
                    277:         * @v rc                Reason for completion
                    278:         */
                    279:        void ( * done ) ( struct scsi_command *scsicmd, int rc );
                    280: };
                    281: 
                    282: /**
                    283:  * Get reference to SCSI device
                    284:  *
                    285:  * @v scsidev          SCSI device
                    286:  * @ret scsidev                SCSI device
                    287:  */
                    288: static inline __attribute__ (( always_inline )) struct scsi_device *
                    289: scsidev_get ( struct scsi_device *scsidev ) {
                    290:        ref_get ( &scsidev->refcnt );
                    291:        return scsidev;
                    292: }
                    293: 
                    294: /**
                    295:  * Drop reference to SCSI device
                    296:  *
                    297:  * @v scsidev          SCSI device
                    298:  */
                    299: static inline __attribute__ (( always_inline )) void
                    300: scsidev_put ( struct scsi_device *scsidev ) {
                    301:        ref_put ( &scsidev->refcnt );
                    302: }
                    303: 
                    304: /**
                    305:  * Get reference to SCSI command
                    306:  *
                    307:  * @v scsicmd          SCSI command
                    308:  * @ret scsicmd                SCSI command
                    309:  */
                    310: static inline __attribute__ (( always_inline )) struct scsi_command *
                    311: scsicmd_get ( struct scsi_command *scsicmd ) {
                    312:        ref_get ( &scsicmd->refcnt );
                    313:        return scsicmd;
                    314: }
                    315: 
                    316: /**
                    317:  * Drop reference to SCSI command
                    318:  *
                    319:  * @v scsicmd          SCSI command
                    320:  */
                    321: static inline __attribute__ (( always_inline )) void
                    322: scsicmd_put ( struct scsi_command *scsicmd ) {
                    323:        ref_put ( &scsicmd->refcnt );
                    324: }
                    325: 
                    326: /**
                    327:  * Get SCSI command private data
                    328:  *
                    329:  * @v scsicmd          SCSI command
                    330:  * @ret priv           Private data
                    331:  */
                    332: static inline __attribute__ (( always_inline )) void *
                    333: scsicmd_priv ( struct scsi_command *scsicmd ) {
                    334:        return scsicmd->priv;
                    335: }
                    336: 
                    337: /**
                    338:  * Free SCSI command
                    339:  *
                    340:  * @v refcnt           Reference count
                    341:  */
                    342: static void scsicmd_free ( struct refcnt *refcnt ) {
                    343:        struct scsi_command *scsicmd =
                    344:                container_of ( refcnt, struct scsi_command, refcnt );
                    345: 
                    346:        /* Remove from list of commands */
                    347:        list_del ( &scsicmd->list );
                    348:        scsidev_put ( scsicmd->scsidev );
                    349: 
                    350:        /* Free command */
                    351:        free ( scsicmd );
                    352: }
                    353: 
                    354: /**
                    355:  * Close SCSI command
                    356:  *
                    357:  * @v scsicmd          SCSI command
                    358:  * @v rc               Reason for close
                    359:  */
                    360: static void scsicmd_close ( struct scsi_command *scsicmd, int rc ) {
                    361:        struct scsi_device *scsidev = scsicmd->scsidev;
                    362: 
                    363:        if ( rc != 0 ) {
                    364:                DBGC ( scsidev, "SCSI %p tag %08x closed: %s\n",
                    365:                       scsidev, scsicmd->tag, strerror ( rc ) );
                    366:        }
                    367: 
                    368:        /* Shut down interfaces */
                    369:        intf_shutdown ( &scsicmd->scsi, rc );
                    370:        intf_shutdown ( &scsicmd->block, rc );
                    371: }
                    372: 
                    373: /**
                    374:  * Construct and issue SCSI command
                    375:  *
                    376:  * @ret rc             Return status code
                    377:  */
                    378: static int scsicmd_command ( struct scsi_command *scsicmd ) {
                    379:        struct scsi_device *scsidev = scsicmd->scsidev;
                    380:        struct scsi_cmd command;
                    381:        int tag;
                    382:        int rc;
                    383: 
                    384:        /* Construct command */
                    385:        memset ( &command, 0, sizeof ( command ) );
                    386:        memcpy ( &command.lun, &scsidev->lun, sizeof ( command.lun ) );
                    387:        scsicmd->type->cmd ( scsicmd, &command );
                    388: 
                    389:        /* Issue command */
                    390:        if ( ( tag = scsi_command ( &scsidev->scsi, &scsicmd->scsi,
                    391:                                    &command ) ) < 0 ) {
                    392:                rc = tag;
                    393:                DBGC ( scsidev, "SCSI %p could not issue command: %s\n",
                    394:                       scsidev, strerror ( rc ) );
                    395:                return rc;
                    396:        }
                    397: 
                    398:        /* Record tag */
                    399:        if ( scsicmd->tag ) {
                    400:                DBGC ( scsidev, "SCSI %p tag %08x is now tag %08x\n",
                    401:                       scsidev, scsicmd->tag, tag );
                    402:        }
                    403:        scsicmd->tag = tag;
                    404:        DBGC2 ( scsidev, "SCSI %p tag %08x %s " SCSI_CDB_FORMAT "\n",
                    405:                scsidev, scsicmd->tag, scsicmd->type->name,
                    406:                SCSI_CDB_DATA ( command.cdb ) );
                    407: 
                    408:        return 0;
                    409: }
                    410: 
                    411: /**
                    412:  * Handle SCSI command completion
                    413:  *
                    414:  * @v scsicmd          SCSI command
                    415:  * @v rc               Reason for close
                    416:  */
                    417: static void scsicmd_done ( struct scsi_command *scsicmd, int rc ) {
                    418:        struct scsi_device *scsidev = scsicmd->scsidev;
                    419: 
                    420:        /* Restart SCSI interface */
                    421:        intf_restart ( &scsicmd->scsi, rc );
                    422: 
                    423:        /* SCSI targets have an annoying habit of returning occasional
                    424:         * pointless "error" messages such as "power-on occurred", so
                    425:         * we have to be prepared to retry commands.
                    426:         */
                    427:        if ( ( rc != 0 ) && ( scsicmd->retries++ < SCSICMD_MAX_RETRIES ) ) {
                    428:                /* Retry command */
                    429:                DBGC ( scsidev, "SCSI %p tag %08x failed: %s\n",
                    430:                       scsidev, scsicmd->tag, strerror ( rc ) );
                    431:                DBGC ( scsidev, "SCSI %p tag %08x retrying (retry %d)\n",
                    432:                       scsidev, scsicmd->tag, scsicmd->retries );
                    433:                if ( ( rc = scsicmd_command ( scsicmd ) ) == 0 )
                    434:                        return;
                    435:        }
                    436: 
                    437:        /* If we didn't (successfully) reissue the command, hand over
                    438:         * to the command completion handler.
                    439:         */
                    440:        scsicmd->type->done ( scsicmd, rc );
                    441: }
                    442: 
                    443: /**
                    444:  * Handle SCSI response
                    445:  *
                    446:  * @v scsicmd          SCSI command
                    447:  * @v response         SCSI response
                    448:  */
                    449: static void scsicmd_response ( struct scsi_command *scsicmd,
                    450:                               struct scsi_rsp *response ) {
                    451:        struct scsi_device *scsidev = scsicmd->scsidev;
                    452:        size_t overrun;
                    453:        size_t underrun;
                    454:        int rc;
                    455: 
                    456:        if ( response->status == 0 ) {
                    457:                scsicmd_done ( scsicmd, 0 );
                    458:        } else {
                    459:                DBGC ( scsidev, "SCSI %p tag %08x status %02x",
                    460:                       scsidev, scsicmd->tag, response->status );
                    461:                if ( response->overrun > 0 ) {
                    462:                        overrun = response->overrun;
                    463:                        DBGC ( scsidev, " overrun +%zd", overrun );
                    464:                } else if ( response->overrun < 0 ) {
                    465:                        underrun = -(response->overrun);
                    466:                        DBGC ( scsidev, " underrun -%zd", underrun );
                    467:                }
                    468:                DBGC ( scsidev, " sense %02x:%02x:%08x\n",
                    469:                       response->sense.code, response->sense.key,
                    470:                       ntohl ( response->sense.info ) );
                    471: 
                    472:                /* Construct error number from sense data */
                    473:                rc = -EIO_SENSE ( response->sense.key & SCSI_SENSE_KEY_MASK );
                    474:                scsicmd_done ( scsicmd, rc );
                    475:        }
                    476: }
                    477: 
                    478: /**
                    479:  * Construct SCSI READ command
                    480:  *
                    481:  * @v scsicmd          SCSI command
                    482:  * @v command          SCSI command IU
                    483:  */
                    484: static void scsicmd_read_cmd ( struct scsi_command *scsicmd,
                    485:                               struct scsi_cmd *command ) {
                    486: 
                    487:        if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
                    488:                /* Use READ (16) */
                    489:                command->cdb.read16.opcode = SCSI_OPCODE_READ_16;
                    490:                command->cdb.read16.lba = cpu_to_be64 ( scsicmd->lba );
                    491:                command->cdb.read16.len = cpu_to_be32 ( scsicmd->count );
                    492:        } else {
                    493:                /* Use READ (10) */
                    494:                command->cdb.read10.opcode = SCSI_OPCODE_READ_10;
                    495:                command->cdb.read10.lba = cpu_to_be32 ( scsicmd->lba );
                    496:                command->cdb.read10.len = cpu_to_be16 ( scsicmd->count );
                    497:        }
                    498:        command->data_in = scsicmd->buffer;
                    499:        command->data_in_len = scsicmd->len;
                    500: }
                    501: 
                    502: /** SCSI READ command type */
                    503: static struct scsi_command_type scsicmd_read = {
                    504:        .name = "READ",
                    505:        .cmd = scsicmd_read_cmd,
                    506:        .done = scsicmd_close,
                    507: };
                    508: 
                    509: /**
                    510:  * Construct SCSI WRITE command
                    511:  *
                    512:  * @v scsicmd          SCSI command
                    513:  * @v command          SCSI command IU
                    514:  */
                    515: static void scsicmd_write_cmd ( struct scsi_command *scsicmd,
                    516:                                struct scsi_cmd *command ) {
                    517: 
                    518:        if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
                    519:                /* Use WRITE (16) */
                    520:                command->cdb.write16.opcode = SCSI_OPCODE_WRITE_16;
                    521:                command->cdb.write16.lba = cpu_to_be64 ( scsicmd->lba );
                    522:                command->cdb.write16.len = cpu_to_be32 ( scsicmd->count );
                    523:        } else {
                    524:                /* Use WRITE (10) */
                    525:                command->cdb.write10.opcode = SCSI_OPCODE_WRITE_10;
                    526:                command->cdb.write10.lba = cpu_to_be32 ( scsicmd->lba );
                    527:                command->cdb.write10.len = cpu_to_be16 ( scsicmd->count );
                    528:        }
                    529:        command->data_out = scsicmd->buffer;
                    530:        command->data_out_len = scsicmd->len;
                    531: }
                    532: 
                    533: /** SCSI WRITE command type */
                    534: static struct scsi_command_type scsicmd_write = {
                    535:        .name = "WRITE",
                    536:        .cmd = scsicmd_write_cmd,
                    537:        .done = scsicmd_close,
                    538: };
                    539: 
                    540: /** SCSI READ CAPACITY private data */
                    541: struct scsi_read_capacity_private {
                    542:        /** Use READ CAPACITY (16) */
                    543:        int use16;
                    544:        /** Data buffer for READ CAPACITY commands */
                    545:        union {
                    546:                /** Data buffer for READ CAPACITY (10) */
                    547:                struct scsi_capacity_10 capacity10;
                    548:                /** Data buffer for READ CAPACITY (16) */
                    549:                struct scsi_capacity_16 capacity16;
                    550:        } capacity;
                    551: };
                    552: 
                    553: /**
                    554:  * Construct SCSI READ CAPACITY command
                    555:  *
                    556:  * @v scsicmd          SCSI command
                    557:  * @v command          SCSI command IU
                    558:  */
                    559: static void scsicmd_read_capacity_cmd ( struct scsi_command *scsicmd,
                    560:                                        struct scsi_cmd *command ) {
                    561:        struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
                    562:        struct scsi_cdb_read_capacity_16 *readcap16 = &command->cdb.readcap16;
                    563:        struct scsi_cdb_read_capacity_10 *readcap10 = &command->cdb.readcap10;
                    564:        struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
                    565:        struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
                    566: 
                    567:        if ( priv->use16 ) {
                    568:                /* Use READ CAPACITY (16) */
                    569:                readcap16->opcode = SCSI_OPCODE_SERVICE_ACTION_IN;
                    570:                readcap16->service_action =
                    571:                        SCSI_SERVICE_ACTION_READ_CAPACITY_16;
                    572:                readcap16->len = cpu_to_be32 ( sizeof ( *capacity16 ) );
                    573:                command->data_in = virt_to_user ( capacity16 );
                    574:                command->data_in_len = sizeof ( *capacity16 );
                    575:        } else {
                    576:                /* Use READ CAPACITY (10) */
                    577:                readcap10->opcode = SCSI_OPCODE_READ_CAPACITY_10;
                    578:                command->data_in = virt_to_user ( capacity10 );
                    579:                command->data_in_len = sizeof ( *capacity10 );
                    580:        }
                    581: }
                    582: 
                    583: /**
                    584:  * Handle SCSI READ CAPACITY command completion
                    585:  *
                    586:  * @v scsicmd          SCSI command
                    587:  * @v rc               Reason for completion
                    588:  */
                    589: static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
                    590:                                         int rc ) {
                    591:        struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
                    592:        struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
                    593:        struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
                    594:        struct block_device_capacity capacity;
                    595: 
                    596:        /* Close if command failed */
                    597:        if ( rc != 0 ) {
                    598:                scsicmd_close ( scsicmd, rc );
                    599:                return;
                    600:        }
                    601: 
                    602:        /* Extract capacity */
                    603:        if ( priv->use16 ) {
                    604:                capacity.blocks = ( be64_to_cpu ( capacity16->lba ) + 1 );
                    605:                capacity.blksize = be32_to_cpu ( capacity16->blksize );
                    606:        } else {
                    607:                capacity.blocks = ( be32_to_cpu ( capacity10->lba ) + 1 );
                    608:                capacity.blksize = be32_to_cpu ( capacity10->blksize );
                    609: 
                    610:                /* If capacity range was exceeded (i.e. capacity.lba
                    611:                 * was 0xffffffff, meaning that blockdev->blocks is
                    612:                 * now zero), use READ CAPACITY (16) instead.  READ
                    613:                 * CAPACITY (16) is not mandatory, so we can't just
                    614:                 * use it straight off.
                    615:                 */
                    616:                if ( capacity.blocks == 0 ) {
                    617:                        priv->use16 = 1;
                    618:                        if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 ) {
                    619:                                scsicmd_close ( scsicmd, rc );
                    620:                                return;
                    621:                        }
                    622:                        return;
                    623:                }
                    624:        }
                    625:        capacity.max_count = -1U;
                    626: 
                    627:        /* Return capacity to caller */
                    628:        block_capacity ( &scsicmd->block, &capacity );
                    629: 
                    630:        /* Close command */
                    631:        scsicmd_close ( scsicmd, 0 );
                    632: }
                    633: 
                    634: /** SCSI READ CAPACITY command type */
                    635: static struct scsi_command_type scsicmd_read_capacity = {
                    636:        .name = "READ CAPACITY",
                    637:        .priv_len = sizeof ( struct scsi_read_capacity_private ),
                    638:        .cmd = scsicmd_read_capacity_cmd,
                    639:        .done = scsicmd_read_capacity_done,
                    640: };
                    641: 
                    642: /**
                    643:  * Construct SCSI TEST UNIT READY command
                    644:  *
                    645:  * @v scsicmd          SCSI command
                    646:  * @v command          SCSI command IU
                    647:  */
                    648: static void scsicmd_test_unit_ready_cmd ( struct scsi_command *scsicmd __unused,
                    649:                                          struct scsi_cmd *command ) {
                    650:        struct scsi_cdb_test_unit_ready *testready = &command->cdb.testready;
                    651: 
                    652:        testready->opcode = SCSI_OPCODE_TEST_UNIT_READY;
                    653: }
                    654: 
                    655: /** SCSI TEST UNIT READY command type */
                    656: static struct scsi_command_type scsicmd_test_unit_ready = {
                    657:        .name = "TEST UNIT READY",
                    658:        .cmd = scsicmd_test_unit_ready_cmd,
                    659:        .done = scsicmd_close,
                    660: };
                    661: 
                    662: /** SCSI command block interface operations */
                    663: static struct interface_operation scsicmd_block_op[] = {
                    664:        INTF_OP ( intf_close, struct scsi_command *, scsicmd_close ),
                    665: };
                    666: 
                    667: /** SCSI command block interface descriptor */
                    668: static struct interface_descriptor scsicmd_block_desc =
                    669:        INTF_DESC_PASSTHRU ( struct scsi_command, block,
                    670:                             scsicmd_block_op, scsi );
                    671: 
                    672: /** SCSI command SCSI interface operations */
                    673: static struct interface_operation scsicmd_scsi_op[] = {
                    674:        INTF_OP ( intf_close, struct scsi_command *, scsicmd_done ),
                    675:        INTF_OP ( scsi_response, struct scsi_command *, scsicmd_response ),
                    676: };
                    677: 
                    678: /** SCSI command SCSI interface descriptor */
                    679: static struct interface_descriptor scsicmd_scsi_desc =
                    680:        INTF_DESC_PASSTHRU ( struct scsi_command, scsi,
                    681:                             scsicmd_scsi_op, block );
                    682: 
                    683: /**
                    684:  * Create SCSI command
                    685:  *
                    686:  * @v scsidev          SCSI device
                    687:  * @v block            Block data interface
                    688:  * @v type             SCSI command type
                    689:  * @v lba              Starting logical block address
                    690:  * @v count            Number of blocks to transfer
                    691:  * @v buffer           Data buffer
                    692:  * @v len              Length of data buffer
                    693:  * @ret rc             Return status code
                    694:  */
                    695: static int scsidev_command ( struct scsi_device *scsidev,
                    696:                             struct interface *block,
                    697:                             struct scsi_command_type *type,
                    698:                             uint64_t lba, unsigned int count,
                    699:                             userptr_t buffer, size_t len ) {
                    700:        struct scsi_command *scsicmd;
                    701:        int rc;
                    702: 
                    703:        /* Allocate and initialise structure */
                    704:        scsicmd = zalloc ( sizeof ( *scsicmd ) + type->priv_len );
                    705:        if ( ! scsicmd ) {
                    706:                rc = -ENOMEM;
                    707:                goto err_zalloc;
                    708:        }
                    709:        ref_init ( &scsicmd->refcnt, scsicmd_free );
                    710:        intf_init ( &scsicmd->block, &scsicmd_block_desc, &scsicmd->refcnt );
                    711:        intf_init ( &scsicmd->scsi, &scsicmd_scsi_desc,
                    712:                    &scsicmd->refcnt );
                    713:        scsicmd->scsidev = scsidev_get ( scsidev );
                    714:        list_add ( &scsicmd->list, &scsidev->cmds );
                    715:        scsicmd->type = type;
                    716:        scsicmd->lba = lba;
                    717:        scsicmd->count = count;
                    718:        scsicmd->buffer = buffer;
                    719:        scsicmd->len = len;
                    720: 
                    721:        /* Issue SCSI command */
                    722:        if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 )
                    723:                goto err_command;
                    724: 
                    725:        /* Attach to parent interface, mortalise self, and return */
                    726:        intf_plug_plug ( &scsicmd->block, block );
                    727:        ref_put ( &scsicmd->refcnt );
                    728:        return 0;
                    729: 
                    730:  err_command:
                    731:        scsicmd_close ( scsicmd, rc );
                    732:        ref_put ( &scsicmd->refcnt );
                    733:  err_zalloc:
                    734:        return rc;
                    735: }
                    736: 
                    737: /**
                    738:  * Issue SCSI block read
                    739:  *
                    740:  * @v scsidev          SCSI device
                    741:  * @v block            Block data interface
                    742:  * @v lba              Starting logical block address
                    743:  * @v count            Number of blocks to transfer
                    744:  * @v buffer           Data buffer
                    745:  * @v len              Length of data buffer
                    746:  * @ret rc             Return status code
                    747: 
                    748:  */
                    749: static int scsidev_read ( struct scsi_device *scsidev,
                    750:                          struct interface *block,
                    751:                          uint64_t lba, unsigned int count,
                    752:                          userptr_t buffer, size_t len ) {
                    753:        return scsidev_command ( scsidev, block, &scsicmd_read,
                    754:                                 lba, count, buffer, len );
                    755: }
                    756: 
                    757: /**
                    758:  * Issue SCSI block write
                    759:  *
                    760:  * @v scsidev          SCSI device
                    761:  * @v block            Block data interface
                    762:  * @v lba              Starting logical block address
                    763:  * @v count            Number of blocks to transfer
                    764:  * @v buffer           Data buffer
                    765:  * @v len              Length of data buffer
                    766:  * @ret rc             Return status code
                    767:  */
                    768: static int scsidev_write ( struct scsi_device *scsidev,
                    769:                           struct interface *block,
                    770:                           uint64_t lba, unsigned int count,
                    771:                           userptr_t buffer, size_t len ) {
                    772:        return scsidev_command ( scsidev, block, &scsicmd_write,
                    773:                                 lba, count, buffer, len );
                    774: }
                    775: 
                    776: /**
                    777:  * Read SCSI device capacity
                    778:  *
                    779:  * @v scsidev          SCSI device
                    780:  * @v block            Block data interface
                    781:  * @ret rc             Return status code
                    782:  */
                    783: static int scsidev_read_capacity ( struct scsi_device *scsidev,
                    784:                                   struct interface *block ) {
                    785:        return scsidev_command ( scsidev, block, &scsicmd_read_capacity,
                    786:                                 0, 0, UNULL, 0 );
                    787: }
                    788: 
                    789: /**
                    790:  * Test to see if SCSI device is ready
                    791:  *
                    792:  * @v scsidev          SCSI device
                    793:  * @v block            Block data interface
                    794:  * @ret rc             Return status code
                    795:  */
                    796: static int scsidev_test_unit_ready ( struct scsi_device *scsidev,
                    797:                                     struct interface *block ) {
                    798:        return scsidev_command ( scsidev, block, &scsicmd_test_unit_ready,
                    799:                                 0, 0, UNULL, 0 );
                    800: }
                    801: 
                    802: /**
                    803:  * Check SCSI device flow-control window
                    804:  *
                    805:  * @v scsidev          SCSI device
                    806:  * @ret len            Length of window
                    807:  */
                    808: static size_t scsidev_window ( struct scsi_device *scsidev ) {
                    809: 
                    810:        /* Refuse commands until unit is confirmed ready */
                    811:        if ( ! ( scsidev->flags & SCSIDEV_UNIT_READY ) )
                    812:                return 0;
                    813: 
                    814:        return xfer_window ( &scsidev->scsi );
                    815: }
                    816: 
                    817: /**
                    818:  * Close SCSI device
                    819:  *
                    820:  * @v scsidev          SCSI device
                    821:  * @v rc               Reason for close
                    822:  */
                    823: static void scsidev_close ( struct scsi_device *scsidev, int rc ) {
                    824:        struct scsi_command *scsicmd;
                    825:        struct scsi_command *tmp;
                    826: 
                    827:        /* Stop process */
                    828:        process_del ( &scsidev->process );
                    829: 
                    830:        /* Shut down interfaces */
                    831:        intf_shutdown ( &scsidev->block, rc );
                    832:        intf_shutdown ( &scsidev->scsi, rc );
                    833:        intf_shutdown ( &scsidev->ready, rc );
                    834: 
                    835:        /* Shut down any remaining commands */
                    836:        list_for_each_entry_safe ( scsicmd, tmp, &scsidev->cmds, list ) {
                    837:                scsicmd_get ( scsicmd );
                    838:                scsicmd_close ( scsicmd, rc );
                    839:                scsicmd_put ( scsicmd );
                    840:        }
                    841: }
                    842: 
                    843: /** SCSI device block interface operations */
                    844: static struct interface_operation scsidev_block_op[] = {
                    845:        INTF_OP ( xfer_window, struct scsi_device *, scsidev_window ),
                    846:        INTF_OP ( block_read, struct scsi_device *, scsidev_read ),
                    847:        INTF_OP ( block_write, struct scsi_device *, scsidev_write ),
                    848:        INTF_OP ( block_read_capacity, struct scsi_device *,
                    849:                  scsidev_read_capacity ),
                    850:        INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
                    851: };
                    852: 
                    853: /** SCSI device block interface descriptor */
                    854: static struct interface_descriptor scsidev_block_desc =
                    855:        INTF_DESC_PASSTHRU ( struct scsi_device, block,
                    856:                             scsidev_block_op, scsi );
                    857: 
                    858: /**
                    859:  * Handle SCSI TEST UNIT READY response
                    860:  *
                    861:  * @v scsidev          SCSI device
                    862:  * @v rc               Reason for close
                    863:  */
                    864: static void scsidev_ready ( struct scsi_device *scsidev, int rc ) {
                    865: 
                    866:        /* Shut down interface */
                    867:        intf_shutdown ( &scsidev->ready, rc );
                    868: 
                    869:        /* Close device on failure */
                    870:        if ( rc != 0 ) {
                    871:                DBGC ( scsidev, "SCSI %p not ready: %s\n",
                    872:                       scsidev, strerror ( rc ) );
                    873:                scsidev_close ( scsidev, rc );
                    874:                return;
                    875:        }
                    876: 
                    877:        /* Mark device as ready */
                    878:        scsidev->flags |= SCSIDEV_UNIT_READY;
                    879:        xfer_window_changed ( &scsidev->block );
                    880:        DBGC ( scsidev, "SCSI %p unit is ready\n", scsidev );
                    881: }
                    882: 
                    883: /** SCSI device TEST UNIT READY interface operations */
                    884: static struct interface_operation scsidev_ready_op[] = {
                    885:        INTF_OP ( intf_close, struct scsi_device *, scsidev_ready ),
                    886: };
                    887: 
                    888: /** SCSI device TEST UNIT READY interface descriptor */
                    889: static struct interface_descriptor scsidev_ready_desc =
                    890:        INTF_DESC ( struct scsi_device, ready, scsidev_ready_op );
                    891: 
                    892: /**
                    893:  * SCSI TEST UNIT READY process
                    894:  *
                    895:  * @v process          Process
                    896:  */
                    897: static void scsidev_step ( struct process *process ) {
                    898:        struct scsi_device *scsidev =
                    899:                container_of ( process, struct scsi_device, process );
                    900:        int rc;
                    901: 
                    902:        /* Wait until underlying SCSI device is ready */
                    903:        if ( xfer_window ( &scsidev->scsi ) == 0 )
                    904:                return;
                    905: 
                    906:        /* Stop process */
                    907:        process_del ( &scsidev->process );
                    908: 
                    909:        DBGC ( scsidev, "SCSI %p waiting for unit to become ready\n",
                    910:               scsidev );
                    911: 
                    912:        /* Issue TEST UNIT READY command */
                    913:        if ( ( rc = scsidev_test_unit_ready ( scsidev, &scsidev->ready )) !=0){
                    914:                scsidev_close ( scsidev, rc );
                    915:                return;
                    916:        }
                    917: }
                    918: 
                    919: /** SCSI device SCSI interface operations */
                    920: static struct interface_operation scsidev_scsi_op[] = {
                    921:        INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
                    922: };
                    923: 
                    924: /** SCSI device SCSI interface descriptor */
                    925: static struct interface_descriptor scsidev_scsi_desc =
                    926:        INTF_DESC_PASSTHRU ( struct scsi_device, scsi,
                    927:                             scsidev_scsi_op, block );
                    928: 
                    929: /**
                    930:  * Open SCSI device
                    931:  *
                    932:  * @v block            Block control interface
                    933:  * @v scsi             SCSI control interface
                    934:  * @v lun              SCSI LUN
                    935:  * @ret rc             Return status code
                    936:  */
                    937: int scsi_open ( struct interface *block, struct interface *scsi,
                    938:                struct scsi_lun *lun ) {
                    939:        struct scsi_device *scsidev;
                    940: 
                    941:        /* Allocate and initialise structure */
                    942:        scsidev = zalloc ( sizeof ( *scsidev ) );
                    943:        if ( ! scsidev )
                    944:                return -ENOMEM;
                    945:        ref_init ( &scsidev->refcnt, NULL );
                    946:        intf_init ( &scsidev->block, &scsidev_block_desc, &scsidev->refcnt );
                    947:        intf_init ( &scsidev->scsi, &scsidev_scsi_desc, &scsidev->refcnt );
                    948:        intf_init ( &scsidev->ready, &scsidev_ready_desc, &scsidev->refcnt );
                    949:        process_init ( &scsidev->process, scsidev_step, &scsidev->refcnt );
                    950:        INIT_LIST_HEAD ( &scsidev->cmds );
                    951:        memcpy ( &scsidev->lun, lun, sizeof ( scsidev->lun ) );
                    952:        DBGC ( scsidev, "SCSI %p created for LUN " SCSI_LUN_FORMAT "\n",
                    953:               scsidev, SCSI_LUN_DATA ( scsidev->lun ) );
                    954: 
                    955:        /* Attach to SCSI and parent interfaces, mortalise self, and return */
                    956:        intf_plug_plug ( &scsidev->scsi, scsi );
                    957:        intf_plug_plug ( &scsidev->block, block );
                    958:        ref_put ( &scsidev->refcnt );
                    959:        return 0;
                    960: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.