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