Home | History | Annotate | Download | only in scsi
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_SYS_SCSI_SCSI_ADDRESS_H
     27 #define	_SYS_SCSI_SCSI_ADDRESS_H
     28 
     29 #include <sys/scsi/scsi_types.h>
     30 
     31 #ifdef	__cplusplus
     32 extern "C" {
     33 #endif
     34 
     35 /*
     36  * SCSI address definition.
     37  *
     38  * A scsi_address(9S) structure stores the host adapter routing and
     39  * scsi_device(9S) unit-address routing information necessary to reference
     40  * a specific SCSI target device logical unit function.
     41  *
     42  * Host adapter routing information is stored in the scsi_hba_tran(9S)
     43  * structure, pointed to by the scsi_address(9S) 'a_hba_tran' field.
     44  *
     45  * The scsi_device(9S) unit-address routing information (i.e. SCSA's
     46  * representation of leaf disk/tape driver's "@unit-address" portion of
     47  * a /devices path) is maintained in three different forms:
     48  *
     49  * SCSI_HBA_ADDR_SPI: In SCSI_HBA_ADDR_SPI mode (default), the SCSA
     50  *	framework, during initialization, places unit-address property
     51  *	information, converted to numeric form, directly into the
     52  *	'a_target' and 'a_lun' fields of the scsi_address(9S) structure
     53  *	(embedded in the scsi_device(9S) structure). To maintain
     54  *	per-scsi_device(9S) state, host adapter drivers often use
     55  *	'a_target' and 'a_lun' to index into a large fixed array
     56  *	(limited by the drivers idea of maximum supported target and
     57  *	lun).
     58  *
     59  *	NOTE: a_sublun is reserved for internal use only and has never
     60  *	been part of DDI scsi_address(9S).
     61  *
     62  * SCSI_HBA_ADDR_COMPLEX: The host adapter driver will maintain
     63  *	per-unit-address/per-scsi_device(9S) HBA private state by using
     64  *	scsi_device_hba_private_set(9F) during tran_tgt_init(9E) (using
     65  *	property interfaces to obtain/convert unit-address information into
     66  *	a host adapter private form).  In SCSI_HBA_ADDR_COMPLEX mode, the SCSA
     67  *	framework, prior to tran_tgt_init(9E), places a pointer to the
     68  *	scsi_device(9S) in the 'a.a_sd' scsi_address(9S) field, and uses
     69  *	'sd_hba_private' to store per-scsi_device hba private data.
     70  *
     71  * SCSI_HBA_TRAN_CLONE: SCSI_HBA_TRAN_CLONE is an older method for
     72  *	supporting devices with non-SPI unit-address. It is still
     73  *	supported, but its use is discouraged. From a unit-address
     74  *	perspective, operation is similar to SCSI_HBA_ADDR_COMPLEX, but
     75  *	per-scsi_device(9S) state is supported via 'cloning' of the
     76  *	scsi_hba_tran(9S) structure (to provide a per-scsi_device(9S)
     77  *	version of 'tran_tgt_private'/'tran_sd' accessible via
     78  *	'a_hba_tran').
     79  *
     80  * NOTE: Compatible evolution of SCSA is constrained by the fact that the
     81  * scsi_address(9S) structure is embedded at the base of the scsi_device(9S)
     82  * structure, and is structure copied into the base of each allocated
     83  * scsi_pkt(9S) structure.
     84  *
     85  * In general, device unit-address information is used exclusively by
     86  * the host adapter driver (the exception being target drivers
     87  * communicating with SCSI Parallel Interconnect (SPI) SCSI-1 devices
     88  * that embed SCSI logical unit addressing in the CDB). Target drivers
     89  * which need to communicate with SPI SCSI-1 devices that embed logical
     90  * unit addresses in the CDB must obtain target and logical unit
     91  * addresses from the device's properties (SCSI_ADDR_PROP_TARGET and
     92  * SCSI_ADDR_PROP_LUN).
     93  */
     94 struct scsi_address {
     95 	struct scsi_hba_tran	*a_hba_tran;	/* Transport vector */
     96 	union {
     97 		struct {			/* SPI: */
     98 			ushort_t a_target;	/* ua target */
     99 			uchar_t	 a_lun;		/* ua lun on target */
    100 			uchar_t	 _a_sublun;	/* (private) */
    101 		} spi;
    102 		struct scsi_device *a_sd;	/* COMPLEX: (private) */
    103 	} a;					/* device unit-adddress info */
    104 };
    105 #define	a_target	a.spi.a_target
    106 #define	a_lun		a.spi.a_lun
    107 #define	a_sublun	a.spi._a_sublun
    108 
    109 /* Device unit-address property names */
    110 #define	SCSI_ADDR_PROP_TARGET		"target"	/* int */
    111 #define	SCSI_ADDR_PROP_LUN		"lun"		/* int */
    112 
    113 #define	SCSI_ADDR_PROP_TARGET_PORT	"target-port"	/* string */
    114 #define	SCSI_ADDR_PROP_LUN64		"lun64"		/* int64 */
    115 #define	SCSI_ADDR_PROP_SFUNC		"sfunc"		/* int */
    116 
    117 #define	SCSI_ADDR_PROP_IPORTUA		"scsi-iport"	/* string */
    118 
    119 #define	SCSI_ADDR_PROP_SATA_PHY		"sata-phy"	/* int */
    120 
    121 /*
    122  * Addressing property names, values are in string form compatible
    123  * with the SCSI_ADDR_PROP_TARGET_PORT part of the related
    124  * IEEE-1275 OpenFirmware binding unit-address string.
    125  */
    126 #define	SCSI_ADDR_PROP_INITIATOR_PORT	"initiator-port"
    127 #define	SCSI_ADDR_PROP_ATTACHED_PORT	"attached-port"
    128 #define	SCSI_ADDR_PROP_BRIDGE_PORT	"bridge-port"
    129 
    130 /*
    131  * Normalized representation of a scsi_lun (with SCSI-2 lun positioned
    132  * for compatibility).
    133  */
    134 typedef uint64_t	scsi_lun64_t;
    135 #define	PRIlun64	PRIx64
    136 #ifdef	_LP64
    137 #define	SCSI_LUN64_ILLEGAL	(-1L)
    138 #else	/* _LP64 */
    139 #define	SCSI_LUN64_ILLEGAL	(-1LL)
    140 #endif	/* _LP64 */
    141 
    142 /* Structure of a 64-bit SCSI LUN per SCSI standard */
    143 typedef	struct scsi_lun {
    144 	uchar_t	sl_lun1_msb;	/* format */
    145 	uchar_t	sl_lun1_lsb;	/* first level */
    146 	uchar_t	sl_lun2_msb;
    147 	uchar_t	sl_lun2_lsb;	/* second level */
    148 	uchar_t	sl_lun3_msb;
    149 	uchar_t	sl_lun3_lsb;	/* third level */
    150 	uchar_t	sl_lun4_msb;
    151 	uchar_t	sl_lun4_lsb;	/* fourth level */
    152 } scsi_lun_t;
    153 
    154 /* SCSI standard defined lun addressing methods (in sl_lunX_msb) */
    155 #define	SCSI_LUN_AM_MASK	0xC0		/* Address Method Mask */
    156 #define	SCSI_LUN_AM_PDEV	0x00		/* Peripheral device AM */
    157 #define	SCSI_LUN_AM_FLAT	0x40		/* Flat space AM */
    158 #define	SCSI_LUN_AM_LUN		0x80		/* Logical unit AM */
    159 #define	SCSI_LUN_AM_EFLAT	0xC0		/* Extended flat space AM */
    160 #define	SCSI_LUN_AM_ELUN	0xC0		/* Extended logical unit AM */
    161 
    162 #ifdef	_KERNEL
    163 /* SCSI LUN conversion between SCSI_ADDR_PROP_LUN64 and SCSI standard forms */
    164 scsi_lun64_t	scsi_lun_to_lun64(scsi_lun_t lun);
    165 scsi_lun_t	scsi_lun64_to_lun(scsi_lun64_t lun64);
    166 
    167 /* SCSI WWN conversion (property values should be in unit_address form) */
    168 int		scsi_wwnstr_to_wwn(const char *wwnstr, uint64_t *wwnp);
    169 char		*scsi_wwn_to_wwnstr(uint64_t wwn,
    170 		    int unit_address_form, char *wwnstr);
    171 void		scsi_wwnstr_hexcase(char *wwnstr, int lower_case);
    172 const char	*scsi_wwnstr_skip_ua_prefix(const char *wwnstr);
    173 void		scsi_free_wwnstr(char *wwnstr);
    174 #endif	/* _KERNEL */
    175 
    176 #ifdef	__cplusplus
    177 }
    178 #endif
    179 
    180 #endif	/* _SYS_SCSI_SCSI_ADDRESS_H */
    181