Annotation of qemu/roms/ipxe/src/net/infiniband/ib_srp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2009 Fen Systems Ltd <[email protected]>.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  *
                      9:  *   Redistributions of source code must retain the above copyright
                     10:  *   notice, this list of conditions and the following disclaimer.
                     11:  *
                     12:  *   Redistributions in binary form must reproduce the above copyright
                     13:  *   notice, this list of conditions and the following disclaimer in
                     14:  *   the documentation and/or other materials provided with the
                     15:  *   distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     18:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     19:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
                     20:  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
                     21:  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
                     22:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     23:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     24:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     26:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     27:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
                     28:  * OF THE POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30: 
                     31: FILE_LICENCE ( BSD2 );
                     32: 
                     33: #include <stdlib.h>
                     34: #include <errno.h>
                     35: #include <ipxe/interface.h>
                     36: #include <ipxe/uri.h>
                     37: #include <ipxe/open.h>
                     38: #include <ipxe/base16.h>
                     39: #include <ipxe/acpi.h>
                     40: #include <ipxe/srp.h>
                     41: #include <ipxe/infiniband.h>
                     42: #include <ipxe/ib_cmrc.h>
                     43: #include <ipxe/ib_srp.h>
                     44: 
                     45: /**
                     46:  * @file
                     47:  *
                     48:  * SCSI RDMA Protocol over Infiniband
                     49:  *
                     50:  */
                     51: 
                     52: /* Disambiguate the various possible EINVALs */
                     53: #define EINVAL_BYTE_STRING_LEN __einfo_error ( EINFO_EINVAL_BYTE_STRING_LEN )
                     54: #define EINFO_EINVAL_BYTE_STRING_LEN __einfo_uniqify \
                     55:        ( EINFO_EINVAL, 0x01, "Invalid byte string length" )
                     56: #define EINVAL_INTEGER __einfo_error ( EINFO_EINVAL_INTEGER )
                     57: #define EINFO_EINVAL_INTEGER __einfo_uniqify \
                     58:        ( EINFO_EINVAL, 0x03, "Invalid integer" )
                     59: #define EINVAL_RP_TOO_SHORT __einfo_error ( EINFO_EINVAL_RP_TOO_SHORT )
                     60: #define EINFO_EINVAL_RP_TOO_SHORT __einfo_uniqify \
                     61:        ( EINFO_EINVAL, 0x04, "Root path too short" )
                     62: 
                     63: /******************************************************************************
                     64:  *
                     65:  * IB SRP devices
                     66:  *
                     67:  ******************************************************************************
                     68:  */
                     69: 
                     70: /** An Infiniband SRP device */
                     71: struct ib_srp_device {
                     72:        /** Reference count */
                     73:        struct refcnt refcnt;
                     74: 
                     75:        /** SRP transport interface */
                     76:        struct interface srp;
                     77:        /** CMRC interface */
                     78:        struct interface cmrc;
                     79: 
                     80:        /** Infiniband device */
                     81:        struct ib_device *ibdev;
                     82: 
                     83:        /** Destination GID (for boot firmware table) */
                     84:        union ib_gid dgid;
                     85:        /** Service ID (for boot firmware table) */
                     86:        union ib_guid service_id;
                     87: };
                     88: 
                     89: /**
                     90:  * Free IB SRP device
                     91:  *
                     92:  * @v refcnt           Reference count
                     93:  */
                     94: static void ib_srp_free ( struct refcnt *refcnt ) {
                     95:        struct ib_srp_device *ib_srp =
                     96:                container_of ( refcnt, struct ib_srp_device, refcnt );
                     97: 
                     98:        ibdev_put ( ib_srp->ibdev );
                     99:        free ( ib_srp );
                    100: }
                    101: 
                    102: /**
                    103:  * Close IB SRP device
                    104:  *
                    105:  * @v ib_srp           IB SRP device
                    106:  * @v rc               Reason for close
                    107:  */
                    108: static void ib_srp_close ( struct ib_srp_device *ib_srp, int rc ) {
                    109: 
                    110:        /* Shut down interfaces */
                    111:        intf_shutdown ( &ib_srp->cmrc, rc );
                    112:        intf_shutdown ( &ib_srp->srp, rc );
                    113: }
                    114: 
                    115: /**
                    116:  * Describe IB SRP device in an ACPI table
                    117:  *
                    118:  * @v srpdev           SRP device
                    119:  * @v acpi             ACPI table
                    120:  * @v len              Length of ACPI table
                    121:  * @ret rc             Return status code
                    122:  */
                    123: static int ib_srp_describe ( struct ib_srp_device *ib_srp,
                    124:                             struct acpi_description_header *acpi,
                    125:                             size_t len ) {
                    126:        struct ib_device *ibdev = ib_srp->ibdev;
                    127:        struct sbft_table *sbft =
                    128:                container_of ( acpi, struct sbft_table, acpi );
                    129:        struct sbft_ib_subtable *ib_sbft;
                    130:        size_t used;
                    131: 
                    132:        /* Sanity check */
                    133:        if ( acpi->signature != SBFT_SIG )
                    134:                return -EINVAL;
                    135: 
                    136:        /* Append IB subtable to existing table */
                    137:        used = le32_to_cpu ( sbft->acpi.length );
                    138:        sbft->ib_offset = cpu_to_le16 ( used );
                    139:        ib_sbft = ( ( ( void * ) sbft ) + used );
                    140:        used += sizeof ( *ib_sbft );
                    141:        if ( used > len )
                    142:                return -ENOBUFS;
                    143:        sbft->acpi.length = cpu_to_le32 ( used );
                    144: 
                    145:        /* Populate subtable */
                    146:        memcpy ( &ib_sbft->sgid, &ibdev->gid, sizeof ( ib_sbft->sgid ) );
                    147:        memcpy ( &ib_sbft->dgid, &ib_srp->dgid, sizeof ( ib_sbft->dgid ) );
                    148:        memcpy ( &ib_sbft->service_id, &ib_srp->service_id,
                    149:                 sizeof ( ib_sbft->service_id ) );
                    150:        ib_sbft->pkey = cpu_to_le16 ( ibdev->pkey );
                    151: 
                    152:        return 0;
                    153: }
                    154: 
                    155: /** IB SRP CMRC interface operations */
                    156: static struct interface_operation ib_srp_cmrc_op[] = {
                    157:        INTF_OP ( intf_close, struct ib_srp_device *, ib_srp_close ),
                    158: };
                    159: 
                    160: /** IB SRP CMRC interface descriptor */
                    161: static struct interface_descriptor ib_srp_cmrc_desc =
                    162:        INTF_DESC_PASSTHRU ( struct ib_srp_device, cmrc, ib_srp_cmrc_op, srp );
                    163: 
                    164: /** IB SRP SRP interface operations */
                    165: static struct interface_operation ib_srp_srp_op[] = {
                    166:        INTF_OP ( acpi_describe, struct ib_srp_device *, ib_srp_describe ),
                    167:        INTF_OP ( intf_close, struct ib_srp_device *, ib_srp_close ),
                    168: };
                    169: 
                    170: /** IB SRP SRP interface descriptor */
                    171: static struct interface_descriptor ib_srp_srp_desc =
                    172:        INTF_DESC_PASSTHRU ( struct ib_srp_device, srp, ib_srp_srp_op, cmrc );
                    173: 
                    174: /**
                    175:  * Open IB SRP device
                    176:  *
                    177:  * @v block            Block control interface
                    178:  * @v ibdev            Infiniband device
                    179:  * @v dgid             Destination GID
                    180:  * @v service_id       Service ID
                    181:  * @v initiator                Initiator port ID
                    182:  * @v target           Target port ID
                    183:  * @v lun              SCSI LUN
                    184:  * @ret rc             Return status code
                    185:  */
                    186: static int ib_srp_open ( struct interface *block, struct ib_device *ibdev,
                    187:                         union ib_gid *dgid, union ib_guid *service_id,
                    188:                         union srp_port_id *initiator,
                    189:                         union srp_port_id *target, struct scsi_lun *lun ) {
                    190:        struct ib_srp_device *ib_srp;
                    191:        int rc;
                    192: 
                    193:        /* Allocate and initialise structure */
                    194:        ib_srp = zalloc ( sizeof ( *ib_srp ) );
                    195:        if ( ! ib_srp ) {
                    196:                rc = -ENOMEM;
                    197:                goto err_zalloc;
                    198:        }
                    199:        ref_init ( &ib_srp->refcnt, ib_srp_free );
                    200:        intf_init ( &ib_srp->srp, &ib_srp_srp_desc, &ib_srp->refcnt );
                    201:        intf_init ( &ib_srp->cmrc, &ib_srp_cmrc_desc, &ib_srp->refcnt );
                    202:        ib_srp->ibdev = ibdev_get ( ibdev );
                    203:        DBGC ( ib_srp, "IBSRP %p for " IB_GID_FMT " " IB_GUID_FMT "\n",
                    204:               ib_srp, IB_GID_ARGS ( dgid ), IB_GUID_ARGS ( service_id ) );
                    205: 
                    206:        /* Preserve parameters required for boot firmware table */
                    207:        memcpy ( &ib_srp->dgid, dgid, sizeof ( ib_srp->dgid ) );
                    208:        memcpy ( &ib_srp->service_id, service_id,
                    209:                 sizeof ( ib_srp->service_id ) );
                    210: 
                    211:        /* Open CMRC socket */
                    212:        if ( ( rc = ib_cmrc_open ( &ib_srp->cmrc, ibdev, dgid,
                    213:                                   service_id ) ) != 0 ) {
                    214:                DBGC ( ib_srp, "IBSRP %p could not open CMRC socket: %s\n",
                    215:                       ib_srp, strerror ( rc ) );
                    216:                goto err_cmrc_open;
                    217:        }
                    218: 
                    219:        /* Attach SRP device to parent interface */
                    220:        if ( ( rc = srp_open ( block, &ib_srp->srp, initiator, target,
                    221:                               ibdev->rdma_key, lun ) ) != 0 ) {
                    222:                DBGC ( ib_srp, "IBSRP %p could not create SRP device: %s\n",
                    223:                       ib_srp, strerror ( rc ) );
                    224:                goto err_srp_open;
                    225:        }
                    226: 
                    227:        /* Mortalise self and return */
                    228:        ref_put ( &ib_srp->refcnt );
                    229:        return 0;
                    230: 
                    231:  err_srp_open:
                    232:  err_cmrc_open:
                    233:        ib_srp_close ( ib_srp, rc );
                    234:        ref_put ( &ib_srp->refcnt );
                    235:  err_zalloc:
                    236:        return rc;
                    237: }
                    238: 
                    239: /******************************************************************************
                    240:  *
                    241:  * IB SRP URIs
                    242:  *
                    243:  ******************************************************************************
                    244:  */
                    245: 
                    246: /** IB SRP parse flags */
                    247: enum ib_srp_parse_flags {
                    248:        IB_SRP_PARSE_REQUIRED = 0x0000,
                    249:        IB_SRP_PARSE_OPTIONAL = 0x8000,
                    250:        IB_SRP_PARSE_FLAG_MASK = 0xf000,
                    251: };
                    252: 
                    253: /** IB SRP root path parameters */
                    254: struct ib_srp_root_path {
                    255:        /** Source GID */
                    256:        union ib_gid sgid;
                    257:        /** Initiator port ID */
                    258:        union ib_srp_initiator_port_id initiator;
                    259:        /** Destination GID */
                    260:        union ib_gid dgid;
                    261:        /** Partition key */
                    262:        uint16_t pkey;
                    263:        /** Service ID */
                    264:        union ib_guid service_id;
                    265:        /** SCSI LUN */
                    266:        struct scsi_lun lun;
                    267:        /** Target port ID */
                    268:        union ib_srp_target_port_id target;
                    269: };
                    270: 
                    271: /**
                    272:  * Parse IB SRP root path byte-string value
                    273:  *
                    274:  * @v rp_comp          Root path component string
                    275:  * @v default_value    Default value to use if component string is empty
                    276:  * @ret value          Value
                    277:  */
                    278: static int ib_srp_parse_byte_string ( const char *rp_comp, uint8_t *bytes,
                    279:                                      unsigned int size_flags ) {
                    280:        size_t size = ( size_flags & ~IB_SRP_PARSE_FLAG_MASK );
                    281:        size_t rp_comp_len = strlen ( rp_comp );
                    282:        int decoded_size;
                    283: 
                    284:        /* Allow optional components to be empty */
                    285:        if ( ( rp_comp_len == 0 ) &&
                    286:             ( size_flags & IB_SRP_PARSE_OPTIONAL ) )
                    287:                return 0;
                    288: 
                    289:        /* Check string length */
                    290:        if ( rp_comp_len != ( 2 * size ) )
                    291:                return -EINVAL_BYTE_STRING_LEN;
                    292: 
                    293:        /* Parse byte string */
                    294:        decoded_size = base16_decode ( rp_comp, bytes );
                    295:        if ( decoded_size < 0 )
                    296:                return decoded_size;
                    297: 
                    298:        return 0;
                    299: }
                    300: 
                    301: /**
                    302:  * Parse IB SRP root path integer value
                    303:  *
                    304:  * @v rp_comp          Root path component string
                    305:  * @v default_value    Default value to use if component string is empty
                    306:  * @ret value          Value
                    307:  */
                    308: static int ib_srp_parse_integer ( const char *rp_comp, int default_value ) {
                    309:        int value;
                    310:        char *end;
                    311: 
                    312:        value = strtoul ( rp_comp, &end, 16 );
                    313:        if ( *end )
                    314:                return -EINVAL_INTEGER;
                    315: 
                    316:        if ( end == rp_comp )
                    317:                return default_value;
                    318: 
                    319:        return value;
                    320: }
                    321: 
                    322: /**
                    323:  * Parse IB SRP root path source GID
                    324:  *
                    325:  * @v rp_comp          Root path component string
                    326:  * @v rp               IB SRP root path
                    327:  * @ret rc             Return status code
                    328:  */
                    329: static int ib_srp_parse_sgid ( const char *rp_comp,
                    330:                               struct ib_srp_root_path *rp ) {
                    331:        struct ib_device *ibdev;
                    332: 
                    333:        /* Default to the GID of the last opened Infiniband device */
                    334:        if ( ( ibdev = last_opened_ibdev() ) != NULL )
                    335:                memcpy ( &rp->sgid, &ibdev->gid, sizeof ( rp->sgid ) );
                    336: 
                    337:        return ib_srp_parse_byte_string ( rp_comp, rp->sgid.bytes,
                    338:                                          ( sizeof ( rp->sgid ) |
                    339:                                            IB_SRP_PARSE_OPTIONAL ) );
                    340: }
                    341: 
                    342: /**
                    343:  * Parse IB SRP root path initiator identifier extension
                    344:  *
                    345:  * @v rp_comp          Root path component string
                    346:  * @v rp               IB SRP root path
                    347:  * @ret rc             Return status code
                    348:  */
                    349: static int ib_srp_parse_initiator_id_ext ( const char *rp_comp,
                    350:                                           struct ib_srp_root_path *rp ) {
                    351:        union ib_srp_initiator_port_id *port_id = &rp->initiator;
                    352: 
                    353:        return ib_srp_parse_byte_string ( rp_comp, port_id->ib.id_ext.bytes,
                    354:                                          ( sizeof ( port_id->ib.id_ext ) |
                    355:                                            IB_SRP_PARSE_OPTIONAL ) );
                    356: }
                    357: 
                    358: /**
                    359:  * Parse IB SRP root path initiator HCA GUID
                    360:  *
                    361:  * @v rp_comp          Root path component string
                    362:  * @v rp               IB SRP root path
                    363:  * @ret rc             Return status code
                    364:  */
                    365: static int ib_srp_parse_initiator_hca_guid ( const char *rp_comp,
                    366:                                             struct ib_srp_root_path *rp ) {
                    367:        union ib_srp_initiator_port_id *port_id = &rp->initiator;
                    368: 
                    369:        /* Default to the GUID portion of the source GID */
                    370:        memcpy ( &port_id->ib.hca_guid, &rp->sgid.s.guid,
                    371:                 sizeof ( port_id->ib.hca_guid ) );
                    372: 
                    373:        return ib_srp_parse_byte_string ( rp_comp, port_id->ib.hca_guid.bytes,
                    374:                                          ( sizeof ( port_id->ib.hca_guid ) |
                    375:                                            IB_SRP_PARSE_OPTIONAL ) );
                    376: }
                    377: 
                    378: /**
                    379:  * Parse IB SRP root path destination GID
                    380:  *
                    381:  * @v rp_comp          Root path component string
                    382:  * @v rp               IB SRP root path
                    383:  * @ret rc             Return status code
                    384:  */
                    385: static int ib_srp_parse_dgid ( const char *rp_comp,
                    386:                               struct ib_srp_root_path *rp ) {
                    387:        return ib_srp_parse_byte_string ( rp_comp, rp->dgid.bytes,
                    388:                                          ( sizeof ( rp->dgid ) |
                    389:                                            IB_SRP_PARSE_REQUIRED ) );
                    390: }
                    391: 
                    392: /**
                    393:  * Parse IB SRP root path partition key
                    394:  *
                    395:  * @v rp_comp          Root path component string
                    396:  * @v rp               IB SRP root path
                    397:  * @ret rc             Return status code
                    398:  */
                    399: static int ib_srp_parse_pkey ( const char *rp_comp,
                    400:                               struct ib_srp_root_path *rp ) {
                    401:        int pkey;
                    402: 
                    403:        if ( ( pkey = ib_srp_parse_integer ( rp_comp, IB_PKEY_DEFAULT ) ) < 0 )
                    404:                return pkey;
                    405:        rp->pkey = pkey;
                    406:        return 0;
                    407: }
                    408: 
                    409: /**
                    410:  * Parse IB SRP root path service ID
                    411:  *
                    412:  * @v rp_comp          Root path component string
                    413:  * @v rp               IB SRP root path
                    414:  * @ret rc             Return status code
                    415:  */
                    416: static int ib_srp_parse_service_id ( const char *rp_comp,
                    417:                                     struct ib_srp_root_path *rp ) {
                    418:        return ib_srp_parse_byte_string ( rp_comp, rp->service_id.bytes,
                    419:                                          ( sizeof ( rp->service_id ) |
                    420:                                            IB_SRP_PARSE_REQUIRED ) );
                    421: }
                    422: 
                    423: /**
                    424:  * Parse IB SRP root path LUN
                    425:  *
                    426:  * @v rp_comp          Root path component string
                    427:  * @v rp               IB SRP root path
                    428:  * @ret rc             Return status code
                    429:  */
                    430: static int ib_srp_parse_lun ( const char *rp_comp,
                    431:                              struct ib_srp_root_path *rp ) {
                    432:        return scsi_parse_lun ( rp_comp, &rp->lun );
                    433: }
                    434: 
                    435: /**
                    436:  * Parse IB SRP root path target identifier extension
                    437:  *
                    438:  * @v rp_comp          Root path component string
                    439:  * @v rp               IB SRP root path
                    440:  * @ret rc             Return status code
                    441:  */
                    442: static int ib_srp_parse_target_id_ext ( const char *rp_comp,
                    443:                                        struct ib_srp_root_path *rp ) {
                    444:        union ib_srp_target_port_id *port_id = &rp->target;
                    445: 
                    446:        return ib_srp_parse_byte_string ( rp_comp, port_id->ib.id_ext.bytes,
                    447:                                          ( sizeof ( port_id->ib.id_ext ) |
                    448:                                            IB_SRP_PARSE_REQUIRED ) );
                    449: }
                    450: 
                    451: /**
                    452:  * Parse IB SRP root path target I/O controller GUID
                    453:  *
                    454:  * @v rp_comp          Root path component string
                    455:  * @v rp               IB SRP root path
                    456:  * @ret rc             Return status code
                    457:  */
                    458: static int ib_srp_parse_target_ioc_guid ( const char *rp_comp,
                    459:                                          struct ib_srp_root_path *rp ) {
                    460:        union ib_srp_target_port_id *port_id = &rp->target;
                    461: 
                    462:        return ib_srp_parse_byte_string ( rp_comp, port_id->ib.ioc_guid.bytes,
                    463:                                          ( sizeof ( port_id->ib.ioc_guid ) |
                    464:                                            IB_SRP_PARSE_REQUIRED ) );
                    465: }
                    466: 
                    467: /** IB SRP root path component parser */
                    468: struct ib_srp_root_path_parser {
                    469:        /**
                    470:         * Parse IB SRP root path component
                    471:         *
                    472:         * @v rp_comp           Root path component string
                    473:         * @v rp                IB SRP root path
                    474:         * @ret rc              Return status code
                    475:         */
                    476:        int ( * parse ) ( const char *rp_comp, struct ib_srp_root_path *rp );
                    477: };
                    478: 
                    479: /** IB SRP root path components */
                    480: static struct ib_srp_root_path_parser ib_srp_rp_parser[] = {
                    481:        { ib_srp_parse_sgid },
                    482:        { ib_srp_parse_initiator_id_ext },
                    483:        { ib_srp_parse_initiator_hca_guid },
                    484:        { ib_srp_parse_dgid },
                    485:        { ib_srp_parse_pkey },
                    486:        { ib_srp_parse_service_id },
                    487:        { ib_srp_parse_lun },
                    488:        { ib_srp_parse_target_id_ext },
                    489:        { ib_srp_parse_target_ioc_guid },
                    490: };
                    491: 
                    492: /** Number of IB SRP root path components */
                    493: #define IB_SRP_NUM_RP_COMPONENTS \
                    494:        ( sizeof ( ib_srp_rp_parser ) / sizeof ( ib_srp_rp_parser[0] ) )
                    495: 
                    496: /**
                    497:  * Parse IB SRP root path
                    498:  *
                    499:  * @v rp_string                Root path string
                    500:  * @v rp               IB SRP root path
                    501:  * @ret rc             Return status code
                    502:  */
                    503: static int ib_srp_parse_root_path ( const char *rp_string,
                    504:                                    struct ib_srp_root_path *rp ) {
                    505:        struct ib_srp_root_path_parser *parser;
                    506:        char rp_string_copy[ strlen ( rp_string ) + 1 ];
                    507:        char *rp_comp[IB_SRP_NUM_RP_COMPONENTS];
                    508:        char *rp_string_tmp = rp_string_copy;
                    509:        unsigned int i = 0;
                    510:        int rc;
                    511: 
                    512:        /* Split root path into component parts */
                    513:        strcpy ( rp_string_copy, rp_string );
                    514:        while ( 1 ) {
                    515:                rp_comp[i++] = rp_string_tmp;
                    516:                if ( i == IB_SRP_NUM_RP_COMPONENTS )
                    517:                        break;
                    518:                for ( ; *rp_string_tmp != ':' ; rp_string_tmp++ ) {
                    519:                        if ( ! *rp_string_tmp ) {
                    520:                                DBG ( "IBSRP root path \"%s\" too short\n",
                    521:                                      rp_string );
                    522:                                return -EINVAL_RP_TOO_SHORT;
                    523:                        }
                    524:                }
                    525:                *(rp_string_tmp++) = '\0';
                    526:        }
                    527: 
                    528:        /* Parse root path components */
                    529:        for ( i = 0 ; i < IB_SRP_NUM_RP_COMPONENTS ; i++ ) {
                    530:                parser = &ib_srp_rp_parser[i];
                    531:                if ( ( rc = parser->parse ( rp_comp[i], rp ) ) != 0 ) {
                    532:                        DBG ( "IBSRP could not parse \"%s\" in root path "
                    533:                              "\"%s\": %s\n", rp_comp[i], rp_string,
                    534:                              strerror ( rc ) );
                    535:                        return rc;
                    536:                }
                    537:        }
                    538: 
                    539:        return 0;
                    540: }
                    541: 
                    542: /**
                    543:  * Open IB SRP URI
                    544:  *
                    545:  * @v parent           Parent interface
                    546:  * @v uri              URI
                    547:  * @ret rc             Return status code
                    548:  */
                    549: static int ib_srp_open_uri ( struct interface *parent, struct uri *uri ) {
                    550:        struct ib_srp_root_path rp;
                    551:        struct ib_device *ibdev;
                    552:        int rc;
                    553: 
                    554:        /* Parse URI */
                    555:        if ( ! uri->opaque )
                    556:                return -EINVAL;
                    557:        memset ( &rp, 0, sizeof ( rp ) );
                    558:        if ( ( rc = ib_srp_parse_root_path ( uri->opaque, &rp ) ) != 0 )
                    559:                return rc;
                    560: 
                    561:        /* Identify Infiniband device */
                    562:        ibdev = find_ibdev ( &rp.sgid );
                    563:        if ( ! ibdev ) {
                    564:                DBG ( "IBSRP could not identify Infiniband device\n" );
                    565:                return -ENODEV;
                    566:        }
                    567: 
                    568:        /* Open IB SRP device */
                    569:        if ( ( rc = ib_srp_open ( parent, ibdev, &rp.dgid, &rp.service_id,
                    570:                                  &rp.initiator.srp, &rp.target.srp,
                    571:                                  &rp.lun ) ) != 0 )
                    572:                return rc;
                    573: 
                    574:        return 0;
                    575: }
                    576: 
                    577: /** IB SRP URI opener */
                    578: struct uri_opener ib_srp_uri_opener __uri_opener = {
                    579:        .scheme = "ib_srp",
                    580:        .open = ib_srp_open_uri,
                    581: };

unix.superglobalmegacorp.com

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