176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (C) 2009 Fen Systems Ltd <mbrown@fensystems.co.uk>. 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * All rights reserved. 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Redistribution and use in source and binary forms, with or without 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * modification, are permitted provided that the following conditions 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * are met: 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Redistributions of source code must retain the above copyright 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * notice, this list of conditions and the following disclaimer. 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Redistributions in binary form must reproduce the above copyright 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * notice, this list of conditions and the following disclaimer in 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the documentation and/or other materials provided with the 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * distribution. 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * OF THE POSSIBILITY OF SUCH DAMAGE. 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( BSD2 ); 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h> 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h> 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/srp.h> 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/infiniband.h> 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/ib_cmrc.h> 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/ib_srp.h> 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @file 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * SCSI RDMA Protocol over Infiniband 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Disambiguate the various possible EINVALs */ 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EINVAL_BYTE_STRING_LEN ( EINVAL | EUNIQ_01 ) 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EINVAL_BYTE_STRING ( EINVAL | EUNIQ_02 ) 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EINVAL_INTEGER ( EINVAL | EUNIQ_03 ) 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EINVAL_RP_TOO_SHORT ( EINVAL | EUNIQ_04 ) 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** IB SRP parse flags */ 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum ib_srp_parse_flags { 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_REQUIRED = 0x0000, 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_OPTIONAL = 0x8000, 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_FLAG_MASK = 0xf000, 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** IB SRP root path parameters */ 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct ib_srp_root_path { 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** SCSI LUN */ 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct scsi_lun *lun; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** SRP port IDs */ 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct srp_port_ids *port_ids; 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** IB SRP parameters */ 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_parameters *ib; 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path byte-string value 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v default_value Default value to use if component string is empty 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret value Value 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_byte_string ( const char *rp_comp, uint8_t *bytes, 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int size_flags ) { 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t size = ( size_flags & ~IB_SRP_PARSE_FLAG_MASK ); 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t rp_comp_len = strlen ( rp_comp ); 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char buf[3]; 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *buf_end; 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Allow optional components to be empty */ 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( rp_comp_len == 0 ) && 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( size_flags & IB_SRP_PARSE_OPTIONAL ) ) 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check string length */ 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( rp_comp_len != ( 2 * size ) ) 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -EINVAL_BYTE_STRING_LEN; 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Parse byte string */ 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( ; size ; size--, rp_comp += 2, bytes++ ) { 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy ( buf, rp_comp, 2 ); 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman buf[2] = '\0'; 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *bytes = strtoul ( buf, &buf_end, 16 ); 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( buf_end != &buf[2] ) 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -EINVAL_BYTE_STRING; 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path integer value 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v default_value Default value to use if component string is empty 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret value Value 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_integer ( const char *rp_comp, int default_value ) { 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int value; 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *end; 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman value = strtoul ( rp_comp, &end, 16 ); 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( *end ) 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -EINVAL_INTEGER; 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( end == rp_comp ) 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return default_value; 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return value; 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path literal component 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_literal ( const char *rp_comp __unused, 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp __unused ) { 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Ignore */ 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path source GID 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_sgid ( const char *rp_comp, 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_device *ibdev; 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Default to the GID of the last opened Infiniband device */ 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( ibdev = last_opened_ibdev() ) != NULL ) 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy ( &rp->ib->sgid, &ibdev->gid, sizeof ( rp->ib->sgid ) ); 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, rp->ib->sgid.u.bytes, 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( rp->ib->sgid ) | 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_OPTIONAL ) ); 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path initiator identifier extension 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_initiator_id_ext ( const char *rp_comp, 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_initiator_port_id *port_id = 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ib_srp_initiator_port_id ( rp->port_ids ); 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, port_id->id_ext.u.bytes, 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( port_id->id_ext ) | 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_OPTIONAL ) ); 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path initiator HCA GUID 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_initiator_hca_guid ( const char *rp_comp, 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_initiator_port_id *port_id = 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ib_srp_initiator_port_id ( rp->port_ids ); 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Default to the GUID portion of the source GID */ 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy ( &port_id->hca_guid, &rp->ib->sgid.u.half[1], 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sizeof ( port_id->hca_guid ) ); 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, port_id->hca_guid.u.bytes, 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( port_id->hca_guid ) | 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_OPTIONAL ) ); 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path destination GID 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_dgid ( const char *rp_comp, 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, rp->ib->dgid.u.bytes, 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( rp->ib->dgid ) | 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_REQUIRED ) ); 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path partition key 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_pkey ( const char *rp_comp, 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int pkey; 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( pkey = ib_srp_parse_integer ( rp_comp, IB_PKEY_DEFAULT ) ) < 0 ) 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return pkey; 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rp->ib->pkey = pkey; 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path service ID 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_service_id ( const char *rp_comp, 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, rp->ib->service_id.u.bytes, 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( rp->ib->service_id ) | 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_REQUIRED ) ); 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path LUN 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_lun ( const char *rp_comp, 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return scsi_parse_lun ( rp_comp, rp->lun ); 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path target identifier extension 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_target_id_ext ( const char *rp_comp, 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_target_port_id *port_id = 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ib_srp_target_port_id ( rp->port_ids ); 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, port_id->id_ext.u.bytes, 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( port_id->id_ext ) | 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_REQUIRED ) ); 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path target I/O controller GUID 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_target_ioc_guid ( const char *rp_comp, 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path *rp ) { 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_target_port_id *port_id = 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ib_srp_target_port_id ( rp->port_ids ); 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ib_srp_parse_byte_string ( rp_comp, port_id->ioc_guid.u.bytes, 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( port_id->ioc_guid ) | 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IB_SRP_PARSE_REQUIRED ) ); 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** IB SRP root path component parser */ 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct ib_srp_root_path_parser { 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path component 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_comp Root path component string 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp IB SRP root path 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int ( * parse ) ( const char *rp_comp, struct ib_srp_root_path *rp ); 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** IB SRP root path components */ 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct ib_srp_root_path_parser ib_srp_rp_parser[] = { 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_literal }, 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_sgid }, 30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_initiator_id_ext }, 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_initiator_hca_guid }, 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_dgid }, 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_pkey }, 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_service_id }, 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_lun }, 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_target_id_ext }, 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { ib_srp_parse_target_ioc_guid }, 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Number of IB SRP root path components */ 31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IB_SRP_NUM_RP_COMPONENTS \ 31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( sizeof ( ib_srp_rp_parser ) / sizeof ( ib_srp_rp_parser[0] ) ) 31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parse IB SRP root path 31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v srp SRP device 32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v rp_string Root path 32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_parse_root_path ( struct srp_device *srp, 32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *rp_string ) { 32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_parameters *ib_params = ib_srp_params ( srp ); 32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_root_path rp = { 32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .lun = &srp->lun, 32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .port_ids = &srp->port_ids, 33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .ib = ib_params, 33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char rp_string_copy[ strlen ( rp_string ) + 1 ]; 33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *rp_comp[IB_SRP_NUM_RP_COMPONENTS]; 33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *rp_string_tmp = rp_string_copy; 33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i = 0; 33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rc; 33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Split root path into component parts */ 33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman strcpy ( rp_string_copy, rp_string ); 34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while ( 1 ) { 34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rp_comp[i++] = rp_string_tmp; 34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( i == IB_SRP_NUM_RP_COMPONENTS ) 34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( ; *rp_string_tmp != ':' ; rp_string_tmp++ ) { 34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! *rp_string_tmp ) { 34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGC ( srp, "SRP %p root path \"%s\" too " 34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "short\n", srp, rp_string ); 34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -EINVAL_RP_TOO_SHORT; 34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *(rp_string_tmp++) = '\0'; 35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Parse root path components */ 35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( i = 0 ; i < IB_SRP_NUM_RP_COMPONENTS ; i++ ) { 35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( rc = ib_srp_rp_parser[i].parse ( rp_comp[i], 35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman &rp ) ) != 0 ) { 35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGC ( srp, "SRP %p could not parse \"%s\" in root " 35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "path \"%s\": %s\n", srp, rp_comp[i], 36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rp_string, strerror ( rc ) ); 36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rc; 36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Connect IB SRP session 37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v srp SRP device 37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int ib_srp_connect ( struct srp_device *srp ) { 37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_srp_parameters *ib_params = ib_srp_params ( srp ); 37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ib_device *ibdev; 37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rc; 37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Identify Infiniband device */ 38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ibdev = find_ibdev ( &ib_params->sgid ); 38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! ibdev ) { 38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGC ( srp, "SRP %p could not identify Infiniband device\n", 38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman srp ); 38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -ENODEV; 38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Configure remaining SRP parameters */ 38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman srp->memory_handle = ibdev->rdma_key; 38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Open CMRC socket */ 39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( rc = ib_cmrc_open ( &srp->socket, ibdev, &ib_params->dgid, 39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman &ib_params->service_id ) ) != 0 ) { 39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGC ( srp, "SRP %p could not open CMRC socket: %s\n", 39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman srp, strerror ( rc ) ); 39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rc; 39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** IB SRP transport type */ 40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct srp_transport_type ib_srp_transport = { 40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .priv_len = sizeof ( struct ib_srp_parameters ), 40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .parse_root_path = ib_srp_parse_root_path, 40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .connect = ib_srp_connect, 40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 407