diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-05-08 21:29:27 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-05-08 21:29:27 -0400 |
commit | d585a021c0b10b0477d6b608c53e1feb8cde0507 (patch) | |
tree | 5ca059da1db7f15d4b29427644ad9c08270c885c /include/scsi | |
parent | 84e5b0d00f8f84c4ae226be131d4bebbcee88bd3 (diff) | |
parent | 091bf7624d1c90cec9e578a18529f615213ff847 (diff) |
Merge commit 'v2.6.30-rc5' into next
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/fc/fc_fcoe.h | 11 | ||||
-rw-r--r-- | include/scsi/fc/fc_fip.h | 237 | ||||
-rw-r--r-- | include/scsi/fc/fc_fs.h | 6 | ||||
-rw-r--r-- | include/scsi/fc_frame.h | 19 | ||||
-rw-r--r-- | include/scsi/fc_transport_fcoe.h | 54 | ||||
-rw-r--r-- | include/scsi/libfc.h | 213 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 250 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 21 | ||||
-rw-r--r-- | include/scsi/osd_attributes.h | 327 | ||||
-rw-r--r-- | include/scsi/osd_initiator.h | 433 | ||||
-rw-r--r-- | include/scsi/osd_protocol.h | 625 | ||||
-rw-r--r-- | include/scsi/osd_sec.h | 45 | ||||
-rw-r--r-- | include/scsi/osd_sense.h | 260 | ||||
-rw-r--r-- | include/scsi/osd_types.h | 40 | ||||
-rw-r--r-- | include/scsi/scsi.h | 31 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 15 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 10 | ||||
-rw-r--r-- | include/scsi/scsi_scan.h | 11 | ||||
-rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 4 |
19 files changed, 2287 insertions, 325 deletions
diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h index 57aaa8f0d613..ccb3dbe90463 100644 --- a/include/scsi/fc/fc_fcoe.h +++ b/include/scsi/fc/fc_fcoe.h | |||
@@ -25,17 +25,6 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * The FCoE ethertype eventually goes in net/if_ether.h. | ||
29 | */ | ||
30 | #ifndef ETH_P_FCOE | ||
31 | #define ETH_P_FCOE 0x8906 /* FCOE ether type */ | ||
32 | #endif | ||
33 | |||
34 | #ifndef ETH_P_8021Q | ||
35 | #define ETH_P_8021Q 0x8100 | ||
36 | #endif | ||
37 | |||
38 | /* | ||
39 | * FC_FCOE_OUI hasn't been standardized yet. XXX TBD. | 28 | * FC_FCOE_OUI hasn't been standardized yet. XXX TBD. |
40 | */ | 29 | */ |
41 | #ifndef FC_FCOE_OUI | 30 | #ifndef FC_FCOE_OUI |
diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h new file mode 100644 index 000000000000..0627a9ae6347 --- /dev/null +++ b/include/scsi/fc/fc_fip.h | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you may redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
9 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
10 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
11 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
12 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
15 | * SOFTWARE. | ||
16 | */ | ||
17 | #ifndef _FC_FIP_H_ | ||
18 | #define _FC_FIP_H_ | ||
19 | |||
20 | /* | ||
21 | * This version is based on: | ||
22 | * http://www.t11.org/ftp/t11/pub/fc/bb-5/08-543v1.pdf | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | * The FIP ethertype eventually goes in net/if_ether.h. | ||
27 | */ | ||
28 | #ifndef ETH_P_FIP | ||
29 | #define ETH_P_FIP 0x8914 /* FIP Ethertype */ | ||
30 | #endif | ||
31 | |||
32 | #define FIP_DEF_PRI 128 /* default selection priority */ | ||
33 | #define FIP_DEF_FC_MAP 0x0efc00 /* default FCoE MAP (MAC OUI) value */ | ||
34 | #define FIP_DEF_FKA 8000 /* default FCF keep-alive/advert period (mS) */ | ||
35 | #define FIP_VN_KA_PERIOD 90000 /* required VN_port keep-alive period (mS) */ | ||
36 | #define FIP_FCF_FUZZ 100 /* random time added by FCF (mS) */ | ||
37 | |||
38 | /* | ||
39 | * Multicast MAC addresses. T11-adopted. | ||
40 | */ | ||
41 | #define FIP_ALL_FCOE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 0 }) | ||
42 | #define FIP_ALL_ENODE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 1 }) | ||
43 | #define FIP_ALL_FCF_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 2 }) | ||
44 | |||
45 | #define FIP_VER 1 /* version for fip_header */ | ||
46 | |||
47 | struct fip_header { | ||
48 | __u8 fip_ver; /* upper 4 bits are the version */ | ||
49 | __u8 fip_resv1; /* reserved */ | ||
50 | __be16 fip_op; /* operation code */ | ||
51 | __u8 fip_resv2; /* reserved */ | ||
52 | __u8 fip_subcode; /* lower 4 bits are sub-code */ | ||
53 | __be16 fip_dl_len; /* length of descriptors in words */ | ||
54 | __be16 fip_flags; /* header flags */ | ||
55 | } __attribute__((packed)); | ||
56 | |||
57 | #define FIP_VER_SHIFT 4 | ||
58 | #define FIP_VER_ENCAPS(v) ((v) << FIP_VER_SHIFT) | ||
59 | #define FIP_VER_DECAPS(v) ((v) >> FIP_VER_SHIFT) | ||
60 | #define FIP_BPW 4 /* bytes per word for lengths */ | ||
61 | |||
62 | /* | ||
63 | * fip_op. | ||
64 | */ | ||
65 | enum fip_opcode { | ||
66 | FIP_OP_DISC = 1, /* discovery, advertisement, etc. */ | ||
67 | FIP_OP_LS = 2, /* Link Service request or reply */ | ||
68 | FIP_OP_CTRL = 3, /* Keep Alive / Link Reset */ | ||
69 | FIP_OP_VLAN = 4, /* VLAN discovery */ | ||
70 | FIP_OP_VENDOR_MIN = 0xfff8, /* min vendor-specific opcode */ | ||
71 | FIP_OP_VENDOR_MAX = 0xfffe, /* max vendor-specific opcode */ | ||
72 | }; | ||
73 | |||
74 | /* | ||
75 | * Subcodes for FIP_OP_DISC. | ||
76 | */ | ||
77 | enum fip_disc_subcode { | ||
78 | FIP_SC_SOL = 1, /* solicitation */ | ||
79 | FIP_SC_ADV = 2, /* advertisement */ | ||
80 | }; | ||
81 | |||
82 | /* | ||
83 | * Subcodes for FIP_OP_LS. | ||
84 | */ | ||
85 | enum fip_trans_subcode { | ||
86 | FIP_SC_REQ = 1, /* request */ | ||
87 | FIP_SC_REP = 2, /* reply */ | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * Subcodes for FIP_OP_RESET. | ||
92 | */ | ||
93 | enum fip_reset_subcode { | ||
94 | FIP_SC_KEEP_ALIVE = 1, /* keep-alive from VN_Port */ | ||
95 | FIP_SC_CLR_VLINK = 2, /* clear virtual link from VF_Port */ | ||
96 | }; | ||
97 | |||
98 | /* | ||
99 | * Subcodes for FIP_OP_VLAN. | ||
100 | */ | ||
101 | enum fip_vlan_subcode { | ||
102 | FIP_SC_VL_REQ = 1, /* request */ | ||
103 | FIP_SC_VL_REP = 2, /* reply */ | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * flags in header fip_flags. | ||
108 | */ | ||
109 | enum fip_flag { | ||
110 | FIP_FL_FPMA = 0x8000, /* supports FPMA fabric-provided MACs */ | ||
111 | FIP_FL_SPMA = 0x4000, /* supports SPMA server-provided MACs */ | ||
112 | FIP_FL_AVAIL = 0x0004, /* available for FLOGI/ELP */ | ||
113 | FIP_FL_SOL = 0x0002, /* this is a solicited message */ | ||
114 | FIP_FL_FPORT = 0x0001, /* sent from an F port */ | ||
115 | }; | ||
116 | |||
117 | /* | ||
118 | * Common descriptor header format. | ||
119 | */ | ||
120 | struct fip_desc { | ||
121 | __u8 fip_dtype; /* type - see below */ | ||
122 | __u8 fip_dlen; /* length - in 32-bit words */ | ||
123 | }; | ||
124 | |||
125 | enum fip_desc_type { | ||
126 | FIP_DT_PRI = 1, /* priority for forwarder selection */ | ||
127 | FIP_DT_MAC = 2, /* MAC address */ | ||
128 | FIP_DT_MAP_OUI = 3, /* FC-MAP OUI */ | ||
129 | FIP_DT_NAME = 4, /* switch name or node name */ | ||
130 | FIP_DT_FAB = 5, /* fabric descriptor */ | ||
131 | FIP_DT_FCOE_SIZE = 6, /* max FCoE frame size */ | ||
132 | FIP_DT_FLOGI = 7, /* FLOGI request or response */ | ||
133 | FIP_DT_FDISC = 8, /* FDISC request or response */ | ||
134 | FIP_DT_LOGO = 9, /* LOGO request or response */ | ||
135 | FIP_DT_ELP = 10, /* ELP request or response */ | ||
136 | FIP_DT_VN_ID = 11, /* VN_Node Identifier */ | ||
137 | FIP_DT_FKA = 12, /* advertisement keep-alive period */ | ||
138 | FIP_DT_VENDOR = 13, /* vendor ID */ | ||
139 | FIP_DT_VLAN = 14, /* vlan number */ | ||
140 | FIP_DT_LIMIT, /* max defined desc_type + 1 */ | ||
141 | FIP_DT_VENDOR_BASE = 128, /* first vendor-specific desc_type */ | ||
142 | }; | ||
143 | |||
144 | /* | ||
145 | * FIP_DT_PRI - priority descriptor. | ||
146 | */ | ||
147 | struct fip_pri_desc { | ||
148 | struct fip_desc fd_desc; | ||
149 | __u8 fd_resvd; | ||
150 | __u8 fd_pri; /* FCF priority: higher is better */ | ||
151 | } __attribute__((packed)); | ||
152 | |||
153 | /* | ||
154 | * FIP_DT_MAC - MAC address descriptor. | ||
155 | */ | ||
156 | struct fip_mac_desc { | ||
157 | struct fip_desc fd_desc; | ||
158 | __u8 fd_mac[ETH_ALEN]; | ||
159 | } __attribute__((packed)); | ||
160 | |||
161 | /* | ||
162 | * FIP_DT_MAP - descriptor. | ||
163 | */ | ||
164 | struct fip_map_desc { | ||
165 | struct fip_desc fd_desc; | ||
166 | __u8 fd_resvd[3]; | ||
167 | __u8 fd_map[3]; | ||
168 | } __attribute__((packed)); | ||
169 | |||
170 | /* | ||
171 | * FIP_DT_NAME descriptor. | ||
172 | */ | ||
173 | struct fip_wwn_desc { | ||
174 | struct fip_desc fd_desc; | ||
175 | __u8 fd_resvd[2]; | ||
176 | __be64 fd_wwn; /* 64-bit WWN, unaligned */ | ||
177 | } __attribute__((packed)); | ||
178 | |||
179 | /* | ||
180 | * FIP_DT_FAB descriptor. | ||
181 | */ | ||
182 | struct fip_fab_desc { | ||
183 | struct fip_desc fd_desc; | ||
184 | __be16 fd_vfid; /* virtual fabric ID */ | ||
185 | __u8 fd_resvd; | ||
186 | __u8 fd_map[3]; /* FC-MAP value */ | ||
187 | __be64 fd_wwn; /* fabric name, unaligned */ | ||
188 | } __attribute__((packed)); | ||
189 | |||
190 | /* | ||
191 | * FIP_DT_FCOE_SIZE descriptor. | ||
192 | */ | ||
193 | struct fip_size_desc { | ||
194 | struct fip_desc fd_desc; | ||
195 | __be16 fd_size; | ||
196 | } __attribute__((packed)); | ||
197 | |||
198 | /* | ||
199 | * Descriptor that encapsulates an ELS or ILS frame. | ||
200 | * The encapsulated frame immediately follows this header, without | ||
201 | * SOF, EOF, or CRC. | ||
202 | */ | ||
203 | struct fip_encaps { | ||
204 | struct fip_desc fd_desc; | ||
205 | __u8 fd_resvd[2]; | ||
206 | } __attribute__((packed)); | ||
207 | |||
208 | /* | ||
209 | * FIP_DT_VN_ID - VN_Node Identifier descriptor. | ||
210 | */ | ||
211 | struct fip_vn_desc { | ||
212 | struct fip_desc fd_desc; | ||
213 | __u8 fd_mac[ETH_ALEN]; | ||
214 | __u8 fd_resvd; | ||
215 | __u8 fd_fc_id[3]; | ||
216 | __be64 fd_wwpn; /* port name, unaligned */ | ||
217 | } __attribute__((packed)); | ||
218 | |||
219 | /* | ||
220 | * FIP_DT_FKA - Advertisement keep-alive period. | ||
221 | */ | ||
222 | struct fip_fka_desc { | ||
223 | struct fip_desc fd_desc; | ||
224 | __u8 fd_resvd[2]; | ||
225 | __be32 fd_fka_period; /* adv./keep-alive period in mS */ | ||
226 | } __attribute__((packed)); | ||
227 | |||
228 | /* | ||
229 | * FIP_DT_VENDOR descriptor. | ||
230 | */ | ||
231 | struct fip_vendor_desc { | ||
232 | struct fip_desc fd_desc; | ||
233 | __u8 fd_resvd[2]; | ||
234 | __u8 fd_vendor_id[8]; | ||
235 | } __attribute__((packed)); | ||
236 | |||
237 | #endif /* _FC_FIP_H_ */ | ||
diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h index 3e4801d2bdbb..ac4cd38c860e 100644 --- a/include/scsi/fc/fc_fs.h +++ b/include/scsi/fc/fc_fs.h | |||
@@ -149,6 +149,7 @@ enum fc_rctl { | |||
149 | * Well-known fabric addresses. | 149 | * Well-known fabric addresses. |
150 | */ | 150 | */ |
151 | enum fc_well_known_fid { | 151 | enum fc_well_known_fid { |
152 | FC_FID_NONE = 0x000000, /* No destination */ | ||
152 | FC_FID_BCAST = 0xffffff, /* broadcast */ | 153 | FC_FID_BCAST = 0xffffff, /* broadcast */ |
153 | FC_FID_FLOGI = 0xfffffe, /* fabric login */ | 154 | FC_FID_FLOGI = 0xfffffe, /* fabric login */ |
154 | FC_FID_FCTRL = 0xfffffd, /* fabric controller */ | 155 | FC_FID_FCTRL = 0xfffffd, /* fabric controller */ |
@@ -337,4 +338,9 @@ enum fc_pf_rjt_reason { | |||
337 | FC_RJT_VENDOR = 0xff, /* vendor specific reject */ | 338 | FC_RJT_VENDOR = 0xff, /* vendor specific reject */ |
338 | }; | 339 | }; |
339 | 340 | ||
341 | /* default timeout values */ | ||
342 | |||
343 | #define FC_DEF_E_D_TOV 2000UL | ||
344 | #define FC_DEF_R_A_TOV 10000UL | ||
345 | |||
340 | #endif /* _FC_FS_H_ */ | 346 | #endif /* _FC_FS_H_ */ |
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h index 04d34a71355f..59511057cee0 100644 --- a/include/scsi/fc_frame.h +++ b/include/scsi/fc_frame.h | |||
@@ -54,8 +54,7 @@ | |||
54 | #define fr_eof(fp) (fr_cb(fp)->fr_eof) | 54 | #define fr_eof(fp) (fr_cb(fp)->fr_eof) |
55 | #define fr_flags(fp) (fr_cb(fp)->fr_flags) | 55 | #define fr_flags(fp) (fr_cb(fp)->fr_flags) |
56 | #define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) | 56 | #define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) |
57 | #define fr_cmd(fp) (fr_cb(fp)->fr_cmd) | 57 | #define fr_fsp(fp) (fr_cb(fp)->fr_fsp) |
58 | #define fr_dir(fp) (fr_cmd(fp)->sc_data_direction) | ||
59 | #define fr_crc(fp) (fr_cb(fp)->fr_crc) | 58 | #define fr_crc(fp) (fr_cb(fp)->fr_crc) |
60 | 59 | ||
61 | struct fc_frame { | 60 | struct fc_frame { |
@@ -66,7 +65,7 @@ struct fcoe_rcv_info { | |||
66 | struct packet_type *ptype; | 65 | struct packet_type *ptype; |
67 | struct fc_lport *fr_dev; /* transport layer private pointer */ | 66 | struct fc_lport *fr_dev; /* transport layer private pointer */ |
68 | struct fc_seq *fr_seq; /* for use with exchange manager */ | 67 | struct fc_seq *fr_seq; /* for use with exchange manager */ |
69 | struct scsi_cmnd *fr_cmd; /* for use of scsi command */ | 68 | struct fc_fcp_pkt *fr_fsp; /* for the corresponding fcp I/O */ |
70 | u32 fr_crc; | 69 | u32 fr_crc; |
71 | u16 fr_max_payload; /* max FC payload */ | 70 | u16 fr_max_payload; /* max FC payload */ |
72 | enum fc_sof fr_sof; /* start of frame delimiter */ | 71 | enum fc_sof fr_sof; /* start of frame delimiter */ |
@@ -218,20 +217,6 @@ static inline bool fc_frame_is_cmd(const struct fc_frame *fp) | |||
218 | return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; | 217 | return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; |
219 | } | 218 | } |
220 | 219 | ||
221 | static inline bool fc_frame_is_read(const struct fc_frame *fp) | ||
222 | { | ||
223 | if (fc_frame_is_cmd(fp) && fr_cmd(fp)) | ||
224 | return fr_dir(fp) == DMA_FROM_DEVICE; | ||
225 | return false; | ||
226 | } | ||
227 | |||
228 | static inline bool fc_frame_is_write(const struct fc_frame *fp) | ||
229 | { | ||
230 | if (fc_frame_is_cmd(fp) && fr_cmd(fp)) | ||
231 | return fr_dir(fp) == DMA_TO_DEVICE; | ||
232 | return false; | ||
233 | } | ||
234 | |||
235 | /* | 220 | /* |
236 | * Check for leaks. | 221 | * Check for leaks. |
237 | * Print the frame header of any currently allocated frame, assuming there | 222 | * Print the frame header of any currently allocated frame, assuming there |
diff --git a/include/scsi/fc_transport_fcoe.h b/include/scsi/fc_transport_fcoe.h deleted file mode 100644 index 8dca2af14ffc..000000000000 --- a/include/scsi/fc_transport_fcoe.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | #ifndef FC_TRANSPORT_FCOE_H | ||
2 | #define FC_TRANSPORT_FCOE_H | ||
3 | |||
4 | #include <linux/device.h> | ||
5 | #include <linux/netdevice.h> | ||
6 | #include <scsi/scsi_host.h> | ||
7 | #include <scsi/libfc.h> | ||
8 | |||
9 | /** | ||
10 | * struct fcoe_transport - FCoE transport struct for generic transport | ||
11 | * for Ethernet devices as well as pure HBAs | ||
12 | * | ||
13 | * @name: name for thsi transport | ||
14 | * @bus: physical bus type (pci_bus_type) | ||
15 | * @driver: physical bus driver for network device | ||
16 | * @create: entry create function | ||
17 | * @destroy: exit destroy function | ||
18 | * @list: list of transports | ||
19 | */ | ||
20 | struct fcoe_transport { | ||
21 | char *name; | ||
22 | unsigned short vendor; | ||
23 | unsigned short device; | ||
24 | struct bus_type *bus; | ||
25 | struct device_driver *driver; | ||
26 | int (*create)(struct net_device *device); | ||
27 | int (*destroy)(struct net_device *device); | ||
28 | bool (*match)(struct net_device *device); | ||
29 | struct list_head list; | ||
30 | struct list_head devlist; | ||
31 | struct mutex devlock; | ||
32 | }; | ||
33 | |||
34 | /** | ||
35 | * MODULE_ALIAS_FCOE_PCI | ||
36 | * | ||
37 | * some care must be taken with this, vendor and device MUST be a hex value | ||
38 | * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB) | ||
39 | */ | ||
40 | #define MODULE_ALIAS_FCOE_PCI(vendor, device) \ | ||
41 | MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device)) | ||
42 | |||
43 | /* exported funcs */ | ||
44 | int fcoe_transport_attach(struct net_device *netdev); | ||
45 | int fcoe_transport_release(struct net_device *netdev); | ||
46 | int fcoe_transport_register(struct fcoe_transport *t); | ||
47 | int fcoe_transport_unregister(struct fcoe_transport *t); | ||
48 | int fcoe_load_transport_driver(struct net_device *netdev); | ||
49 | int __init fcoe_transport_init(void); | ||
50 | int __exit fcoe_transport_exit(void); | ||
51 | |||
52 | /* fcow_sw is the default transport */ | ||
53 | extern struct fcoe_transport fcoe_sw_transport; | ||
54 | #endif /* FC_TRANSPORT_FCOE_H */ | ||
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 9f2876397dda..45f9cc642c46 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
24 | #include <linux/if.h> | 24 | #include <linux/if.h> |
25 | #include <linux/percpu.h> | ||
25 | 26 | ||
26 | #include <scsi/scsi_transport.h> | 27 | #include <scsi/scsi_transport.h> |
27 | #include <scsi/scsi_transport_fc.h> | 28 | #include <scsi/scsi_transport_fc.h> |
@@ -68,9 +69,6 @@ | |||
68 | /* | 69 | /* |
69 | * FC HBA status | 70 | * FC HBA status |
70 | */ | 71 | */ |
71 | #define FC_PAUSE (1 << 1) | ||
72 | #define FC_LINK_UP (1 << 0) | ||
73 | |||
74 | enum fc_lport_state { | 72 | enum fc_lport_state { |
75 | LPORT_ST_NONE = 0, | 73 | LPORT_ST_NONE = 0, |
76 | LPORT_ST_FLOGI, | 74 | LPORT_ST_FLOGI, |
@@ -248,6 +246,7 @@ struct fc_fcp_pkt { | |||
248 | */ | 246 | */ |
249 | struct fcp_cmnd cdb_cmd; | 247 | struct fcp_cmnd cdb_cmd; |
250 | size_t xfer_len; | 248 | size_t xfer_len; |
249 | u16 xfer_ddp; /* this xfer is ddped */ | ||
251 | u32 xfer_contig_end; /* offset of end of contiguous xfer */ | 250 | u32 xfer_contig_end; /* offset of end of contiguous xfer */ |
252 | u16 max_payload; /* max payload size in bytes */ | 251 | u16 max_payload; /* max payload size in bytes */ |
253 | 252 | ||
@@ -270,6 +269,15 @@ struct fc_fcp_pkt { | |||
270 | u8 recov_retry; /* count of recovery retries */ | 269 | u8 recov_retry; /* count of recovery retries */ |
271 | struct fc_seq *recov_seq; /* sequence for REC or SRR */ | 270 | struct fc_seq *recov_seq; /* sequence for REC or SRR */ |
272 | }; | 271 | }; |
272 | /* | ||
273 | * FC_FCP HELPER FUNCTIONS | ||
274 | *****************************/ | ||
275 | static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp) | ||
276 | { | ||
277 | if (fsp && fsp->cmd) | ||
278 | return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE; | ||
279 | return false; | ||
280 | } | ||
273 | 281 | ||
274 | /* | 282 | /* |
275 | * Structure and function definitions for managing Fibre Channel Exchanges | 283 | * Structure and function definitions for managing Fibre Channel Exchanges |
@@ -339,31 +347,17 @@ struct fc_exch { | |||
339 | 347 | ||
340 | struct libfc_function_template { | 348 | struct libfc_function_template { |
341 | 349 | ||
342 | /** | ||
343 | * Mandatory Fields | ||
344 | * | ||
345 | * These handlers must be implemented by the LLD. | ||
346 | */ | ||
347 | |||
348 | /* | 350 | /* |
349 | * Interface to send a FC frame | 351 | * Interface to send a FC frame |
350 | */ | ||
351 | int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); | ||
352 | |||
353 | /** | ||
354 | * Optional Fields | ||
355 | * | 352 | * |
356 | * The LLD may choose to implement any of the following handlers. | 353 | * STATUS: REQUIRED |
357 | * If LLD doesn't specify hander and leaves its pointer NULL then | ||
358 | * the default libfc function will be used for that handler. | ||
359 | */ | ||
360 | |||
361 | /** | ||
362 | * ELS/CT interfaces | ||
363 | */ | 354 | */ |
355 | int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); | ||
364 | 356 | ||
365 | /* | 357 | /* |
366 | * elsct_send - sends ELS/CT frame | 358 | * Interface to send ELS/CT frames |
359 | * | ||
360 | * STATUS: OPTIONAL | ||
367 | */ | 361 | */ |
368 | struct fc_seq *(*elsct_send)(struct fc_lport *lport, | 362 | struct fc_seq *(*elsct_send)(struct fc_lport *lport, |
369 | struct fc_rport *rport, | 363 | struct fc_rport *rport, |
@@ -373,9 +367,6 @@ struct libfc_function_template { | |||
373 | struct fc_frame *fp, | 367 | struct fc_frame *fp, |
374 | void *arg), | 368 | void *arg), |
375 | void *arg, u32 timer_msec); | 369 | void *arg, u32 timer_msec); |
376 | /** | ||
377 | * Exhance Manager interfaces | ||
378 | */ | ||
379 | 370 | ||
380 | /* | 371 | /* |
381 | * Send the FC frame payload using a new exchange and sequence. | 372 | * Send the FC frame payload using a new exchange and sequence. |
@@ -407,6 +398,8 @@ struct libfc_function_template { | |||
407 | * timer_msec argument is specified. The timer is canceled when | 398 | * timer_msec argument is specified. The timer is canceled when |
408 | * it fires or when the exchange is done. The exchange timeout handler | 399 | * it fires or when the exchange is done. The exchange timeout handler |
409 | * is registered by EM layer. | 400 | * is registered by EM layer. |
401 | * | ||
402 | * STATUS: OPTIONAL | ||
410 | */ | 403 | */ |
411 | struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, | 404 | struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, |
412 | struct fc_frame *fp, | 405 | struct fc_frame *fp, |
@@ -418,14 +411,33 @@ struct libfc_function_template { | |||
418 | void *arg, unsigned int timer_msec); | 411 | void *arg, unsigned int timer_msec); |
419 | 412 | ||
420 | /* | 413 | /* |
421 | * send a frame using existing sequence and exchange. | 414 | * Sets up the DDP context for a given exchange id on the given |
415 | * scatterlist if LLD supports DDP for large receive. | ||
416 | * | ||
417 | * STATUS: OPTIONAL | ||
418 | */ | ||
419 | int (*ddp_setup)(struct fc_lport *lp, u16 xid, | ||
420 | struct scatterlist *sgl, unsigned int sgc); | ||
421 | /* | ||
422 | * Completes the DDP transfer and returns the length of data DDPed | ||
423 | * for the given exchange id. | ||
424 | * | ||
425 | * STATUS: OPTIONAL | ||
426 | */ | ||
427 | int (*ddp_done)(struct fc_lport *lp, u16 xid); | ||
428 | /* | ||
429 | * Send a frame using an existing sequence and exchange. | ||
430 | * | ||
431 | * STATUS: OPTIONAL | ||
422 | */ | 432 | */ |
423 | int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, | 433 | int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, |
424 | struct fc_frame *fp); | 434 | struct fc_frame *fp); |
425 | 435 | ||
426 | /* | 436 | /* |
427 | * Send ELS response using mainly infomation | 437 | * Send an ELS response using infomation from a previous |
428 | * in exchange and sequence in EM layer. | 438 | * exchange and sequence. |
439 | * | ||
440 | * STATUS: OPTIONAL | ||
429 | */ | 441 | */ |
430 | void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, | 442 | void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, |
431 | struct fc_seq_els_data *els_data); | 443 | struct fc_seq_els_data *els_data); |
@@ -437,6 +449,8 @@ struct libfc_function_template { | |||
437 | * A timer_msec can be specified for abort timeout, if non-zero | 449 | * A timer_msec can be specified for abort timeout, if non-zero |
438 | * timer_msec value is specified then exchange resp handler | 450 | * timer_msec value is specified then exchange resp handler |
439 | * will be called with timeout error if no response to abort. | 451 | * will be called with timeout error if no response to abort. |
452 | * | ||
453 | * STATUS: OPTIONAL | ||
440 | */ | 454 | */ |
441 | int (*seq_exch_abort)(const struct fc_seq *req_sp, | 455 | int (*seq_exch_abort)(const struct fc_seq *req_sp, |
442 | unsigned int timer_msec); | 456 | unsigned int timer_msec); |
@@ -444,6 +458,8 @@ struct libfc_function_template { | |||
444 | /* | 458 | /* |
445 | * Indicate that an exchange/sequence tuple is complete and the memory | 459 | * Indicate that an exchange/sequence tuple is complete and the memory |
446 | * allocated for the related objects may be freed. | 460 | * allocated for the related objects may be freed. |
461 | * | ||
462 | * STATUS: OPTIONAL | ||
447 | */ | 463 | */ |
448 | void (*exch_done)(struct fc_seq *sp); | 464 | void (*exch_done)(struct fc_seq *sp); |
449 | 465 | ||
@@ -451,6 +467,8 @@ struct libfc_function_template { | |||
451 | * Assigns a EM and a free XID for an new exchange and then | 467 | * Assigns a EM and a free XID for an new exchange and then |
452 | * allocates a new exchange and sequence pair. | 468 | * allocates a new exchange and sequence pair. |
453 | * The fp can be used to determine free XID. | 469 | * The fp can be used to determine free XID. |
470 | * | ||
471 | * STATUS: OPTIONAL | ||
454 | */ | 472 | */ |
455 | struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); | 473 | struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); |
456 | 474 | ||
@@ -458,12 +476,16 @@ struct libfc_function_template { | |||
458 | * Release previously assigned XID by exch_get API. | 476 | * Release previously assigned XID by exch_get API. |
459 | * The LLD may implement this if XID is assigned by LLD | 477 | * The LLD may implement this if XID is assigned by LLD |
460 | * in exch_get(). | 478 | * in exch_get(). |
479 | * | ||
480 | * STATUS: OPTIONAL | ||
461 | */ | 481 | */ |
462 | void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, | 482 | void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, |
463 | u16 ex_id); | 483 | u16 ex_id); |
464 | 484 | ||
465 | /* | 485 | /* |
466 | * Start a new sequence on the same exchange/sequence tuple. | 486 | * Start a new sequence on the same exchange/sequence tuple. |
487 | * | ||
488 | * STATUS: OPTIONAL | ||
467 | */ | 489 | */ |
468 | struct fc_seq *(*seq_start_next)(struct fc_seq *sp); | 490 | struct fc_seq *(*seq_start_next)(struct fc_seq *sp); |
469 | 491 | ||
@@ -471,26 +493,38 @@ struct libfc_function_template { | |||
471 | * Reset an exchange manager, completing all sequences and exchanges. | 493 | * Reset an exchange manager, completing all sequences and exchanges. |
472 | * If s_id is non-zero, reset only exchanges originating from that FID. | 494 | * If s_id is non-zero, reset only exchanges originating from that FID. |
473 | * If d_id is non-zero, reset only exchanges sending to that FID. | 495 | * If d_id is non-zero, reset only exchanges sending to that FID. |
496 | * | ||
497 | * STATUS: OPTIONAL | ||
474 | */ | 498 | */ |
475 | void (*exch_mgr_reset)(struct fc_exch_mgr *, | 499 | void (*exch_mgr_reset)(struct fc_lport *, |
476 | u32 s_id, u32 d_id); | 500 | u32 s_id, u32 d_id); |
477 | 501 | ||
478 | void (*rport_flush_queue)(void); | 502 | /* |
479 | /** | 503 | * Flush the rport work queue. Generally used before shutdown. |
480 | * Local Port interfaces | 504 | * |
505 | * STATUS: OPTIONAL | ||
481 | */ | 506 | */ |
507 | void (*rport_flush_queue)(void); | ||
482 | 508 | ||
483 | /* | 509 | /* |
484 | * Receive a frame to a local port. | 510 | * Receive a frame for a local port. |
511 | * | ||
512 | * STATUS: OPTIONAL | ||
485 | */ | 513 | */ |
486 | void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, | 514 | void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, |
487 | struct fc_frame *fp); | 515 | struct fc_frame *fp); |
488 | 516 | ||
517 | /* | ||
518 | * Reset the local port. | ||
519 | * | ||
520 | * STATUS: OPTIONAL | ||
521 | */ | ||
489 | int (*lport_reset)(struct fc_lport *); | 522 | int (*lport_reset)(struct fc_lport *); |
490 | 523 | ||
491 | /** | 524 | /* |
492 | * Remote Port interfaces | 525 | * Create a remote port |
493 | */ | 526 | */ |
527 | struct fc_rport *(*rport_create)(struct fc_disc_port *); | ||
494 | 528 | ||
495 | /* | 529 | /* |
496 | * Initiates the RP state machine. It is called from the LP module. | 530 | * Initiates the RP state machine. It is called from the LP module. |
@@ -500,26 +534,33 @@ struct libfc_function_template { | |||
500 | * - PLOGI | 534 | * - PLOGI |
501 | * - PRLI | 535 | * - PRLI |
502 | * - RTV | 536 | * - RTV |
537 | * | ||
538 | * STATUS: OPTIONAL | ||
503 | */ | 539 | */ |
504 | int (*rport_login)(struct fc_rport *rport); | 540 | int (*rport_login)(struct fc_rport *rport); |
505 | 541 | ||
506 | /* | 542 | /* |
507 | * Logoff, and remove the rport from the transport if | 543 | * Logoff, and remove the rport from the transport if |
508 | * it had been added. This will send a LOGO to the target. | 544 | * it had been added. This will send a LOGO to the target. |
545 | * | ||
546 | * STATUS: OPTIONAL | ||
509 | */ | 547 | */ |
510 | int (*rport_logoff)(struct fc_rport *rport); | 548 | int (*rport_logoff)(struct fc_rport *rport); |
511 | 549 | ||
512 | /* | 550 | /* |
513 | * Recieve a request from a remote port. | 551 | * Recieve a request from a remote port. |
552 | * | ||
553 | * STATUS: OPTIONAL | ||
514 | */ | 554 | */ |
515 | void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, | 555 | void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, |
516 | struct fc_rport *); | 556 | struct fc_rport *); |
517 | 557 | ||
518 | struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); | 558 | /* |
519 | 559 | * lookup an rport by it's port ID. | |
520 | /** | 560 | * |
521 | * FCP interfaces | 561 | * STATUS: OPTIONAL |
522 | */ | 562 | */ |
563 | struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); | ||
523 | 564 | ||
524 | /* | 565 | /* |
525 | * Send a fcp cmd from fsp pkt. | 566 | * Send a fcp cmd from fsp pkt. |
@@ -527,30 +568,38 @@ struct libfc_function_template { | |||
527 | * | 568 | * |
528 | * The resp handler is called when FCP_RSP received. | 569 | * The resp handler is called when FCP_RSP received. |
529 | * | 570 | * |
571 | * STATUS: OPTIONAL | ||
530 | */ | 572 | */ |
531 | int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, | 573 | int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, |
532 | void (*resp)(struct fc_seq *, struct fc_frame *fp, | 574 | void (*resp)(struct fc_seq *, struct fc_frame *fp, |
533 | void *arg)); | 575 | void *arg)); |
534 | 576 | ||
535 | /* | 577 | /* |
536 | * Used at least durring linkdown and reset | 578 | * Cleanup the FCP layer, used durring link down and reset |
579 | * | ||
580 | * STATUS: OPTIONAL | ||
537 | */ | 581 | */ |
538 | void (*fcp_cleanup)(struct fc_lport *lp); | 582 | void (*fcp_cleanup)(struct fc_lport *lp); |
539 | 583 | ||
540 | /* | 584 | /* |
541 | * Abort all I/O on a local port | 585 | * Abort all I/O on a local port |
586 | * | ||
587 | * STATUS: OPTIONAL | ||
542 | */ | 588 | */ |
543 | void (*fcp_abort_io)(struct fc_lport *lp); | 589 | void (*fcp_abort_io)(struct fc_lport *lp); |
544 | 590 | ||
545 | /** | 591 | /* |
546 | * Discovery interfaces | 592 | * Receive a request for the discovery layer. |
593 | * | ||
594 | * STATUS: OPTIONAL | ||
547 | */ | 595 | */ |
548 | |||
549 | void (*disc_recv_req)(struct fc_seq *, | 596 | void (*disc_recv_req)(struct fc_seq *, |
550 | struct fc_frame *, struct fc_lport *); | 597 | struct fc_frame *, struct fc_lport *); |
551 | 598 | ||
552 | /* | 599 | /* |
553 | * Start discovery for a local port. | 600 | * Start discovery for a local port. |
601 | * | ||
602 | * STATUS: OPTIONAL | ||
554 | */ | 603 | */ |
555 | void (*disc_start)(void (*disc_callback)(struct fc_lport *, | 604 | void (*disc_start)(void (*disc_callback)(struct fc_lport *, |
556 | enum fc_disc_event), | 605 | enum fc_disc_event), |
@@ -559,6 +608,8 @@ struct libfc_function_template { | |||
559 | /* | 608 | /* |
560 | * Stop discovery for a given lport. This will remove | 609 | * Stop discovery for a given lport. This will remove |
561 | * all discovered rports | 610 | * all discovered rports |
611 | * | ||
612 | * STATUS: OPTIONAL | ||
562 | */ | 613 | */ |
563 | void (*disc_stop) (struct fc_lport *); | 614 | void (*disc_stop) (struct fc_lport *); |
564 | 615 | ||
@@ -566,6 +617,8 @@ struct libfc_function_template { | |||
566 | * Stop discovery for a given lport. This will block | 617 | * Stop discovery for a given lport. This will block |
567 | * until all discovered rports are deleted from the | 618 | * until all discovered rports are deleted from the |
568 | * FC transport class | 619 | * FC transport class |
620 | * | ||
621 | * STATUS: OPTIONAL | ||
569 | */ | 622 | */ |
570 | void (*disc_stop_final) (struct fc_lport *); | 623 | void (*disc_stop_final) (struct fc_lport *); |
571 | }; | 624 | }; |
@@ -584,6 +637,7 @@ struct fc_disc { | |||
584 | enum fc_disc_event); | 637 | enum fc_disc_event); |
585 | 638 | ||
586 | struct list_head rports; | 639 | struct list_head rports; |
640 | struct list_head rogue_rports; | ||
587 | struct fc_lport *lport; | 641 | struct fc_lport *lport; |
588 | struct mutex disc_mutex; | 642 | struct mutex disc_mutex; |
589 | struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ | 643 | struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ |
@@ -603,12 +657,14 @@ struct fc_lport { | |||
603 | 657 | ||
604 | /* Operational Information */ | 658 | /* Operational Information */ |
605 | struct libfc_function_template tt; | 659 | struct libfc_function_template tt; |
606 | u16 link_status; | 660 | u8 link_up; |
661 | u8 qfull; | ||
607 | enum fc_lport_state state; | 662 | enum fc_lport_state state; |
608 | unsigned long boot_time; | 663 | unsigned long boot_time; |
609 | 664 | ||
610 | struct fc_host_statistics host_stats; | 665 | struct fc_host_statistics host_stats; |
611 | struct fcoe_dev_stats *dev_stats[NR_CPUS]; | 666 | struct fcoe_dev_stats *dev_stats; |
667 | |||
612 | u64 wwpn; | 668 | u64 wwpn; |
613 | u64 wwnn; | 669 | u64 wwnn; |
614 | u8 retry_count; | 670 | u8 retry_count; |
@@ -626,6 +682,7 @@ struct fc_lport { | |||
626 | u16 link_speed; | 682 | u16 link_speed; |
627 | u16 link_supported_speeds; | 683 | u16 link_supported_speeds; |
628 | u16 lro_xid; /* max xid for fcoe lro */ | 684 | u16 lro_xid; /* max xid for fcoe lro */ |
685 | unsigned int lso_max; /* max large send size */ | ||
629 | struct fc_ns_fts fcts; /* FC-4 type masks */ | 686 | struct fc_ns_fts fcts; /* FC-4 type masks */ |
630 | struct fc_els_rnid_gen rnid_gen; /* RNID information */ | 687 | struct fc_els_rnid_gen rnid_gen; /* RNID information */ |
631 | 688 | ||
@@ -637,14 +694,9 @@ struct fc_lport { | |||
637 | struct delayed_work disc_work; | 694 | struct delayed_work disc_work; |
638 | }; | 695 | }; |
639 | 696 | ||
640 | /** | 697 | /* |
641 | * FC_LPORT HELPER FUNCTIONS | 698 | * FC_LPORT HELPER FUNCTIONS |
642 | *****************************/ | 699 | *****************************/ |
643 | static inline void *lport_priv(const struct fc_lport *lp) | ||
644 | { | ||
645 | return (void *)(lp + 1); | ||
646 | } | ||
647 | |||
648 | static inline int fc_lport_test_ready(struct fc_lport *lp) | 700 | static inline int fc_lport_test_ready(struct fc_lport *lp) |
649 | { | 701 | { |
650 | return lp->state == LPORT_ST_READY; | 702 | return lp->state == LPORT_ST_READY; |
@@ -668,8 +720,44 @@ static inline void fc_lport_state_enter(struct fc_lport *lp, | |||
668 | lp->state = state; | 720 | lp->state = state; |
669 | } | 721 | } |
670 | 722 | ||
723 | static inline int fc_lport_init_stats(struct fc_lport *lp) | ||
724 | { | ||
725 | /* allocate per cpu stats block */ | ||
726 | lp->dev_stats = alloc_percpu(struct fcoe_dev_stats); | ||
727 | if (!lp->dev_stats) | ||
728 | return -ENOMEM; | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static inline void fc_lport_free_stats(struct fc_lport *lp) | ||
733 | { | ||
734 | free_percpu(lp->dev_stats); | ||
735 | } | ||
736 | |||
737 | static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lp) | ||
738 | { | ||
739 | return per_cpu_ptr(lp->dev_stats, smp_processor_id()); | ||
740 | } | ||
741 | |||
742 | static inline void *lport_priv(const struct fc_lport *lp) | ||
743 | { | ||
744 | return (void *)(lp + 1); | ||
745 | } | ||
671 | 746 | ||
672 | /** | 747 | /** |
748 | * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport | ||
749 | * @sht: ptr to the scsi host templ | ||
750 | * @priv_size: size of private data after fc_lport | ||
751 | * | ||
752 | * Returns: ptr to Scsi_Host | ||
753 | */ | ||
754 | static inline struct Scsi_Host * | ||
755 | libfc_host_alloc(struct scsi_host_template *sht, int priv_size) | ||
756 | { | ||
757 | return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size); | ||
758 | } | ||
759 | |||
760 | /* | ||
673 | * LOCAL PORT LAYER | 761 | * LOCAL PORT LAYER |
674 | *****************************/ | 762 | *****************************/ |
675 | int fc_lport_init(struct fc_lport *lp); | 763 | int fc_lport_init(struct fc_lport *lp); |
@@ -704,12 +792,6 @@ void fc_linkup(struct fc_lport *); | |||
704 | void fc_linkdown(struct fc_lport *); | 792 | void fc_linkdown(struct fc_lport *); |
705 | 793 | ||
706 | /* | 794 | /* |
707 | * Pause and unpause traffic. | ||
708 | */ | ||
709 | void fc_pause(struct fc_lport *); | ||
710 | void fc_unpause(struct fc_lport *); | ||
711 | |||
712 | /* | ||
713 | * Configure the local port. | 795 | * Configure the local port. |
714 | */ | 796 | */ |
715 | int fc_lport_config(struct fc_lport *); | 797 | int fc_lport_config(struct fc_lport *); |
@@ -725,19 +807,19 @@ int fc_lport_reset(struct fc_lport *); | |||
725 | int fc_set_mfs(struct fc_lport *lp, u32 mfs); | 807 | int fc_set_mfs(struct fc_lport *lp, u32 mfs); |
726 | 808 | ||
727 | 809 | ||
728 | /** | 810 | /* |
729 | * REMOTE PORT LAYER | 811 | * REMOTE PORT LAYER |
730 | *****************************/ | 812 | *****************************/ |
731 | int fc_rport_init(struct fc_lport *lp); | 813 | int fc_rport_init(struct fc_lport *lp); |
732 | void fc_rport_terminate_io(struct fc_rport *rp); | 814 | void fc_rport_terminate_io(struct fc_rport *rp); |
733 | 815 | ||
734 | /** | 816 | /* |
735 | * DISCOVERY LAYER | 817 | * DISCOVERY LAYER |
736 | *****************************/ | 818 | *****************************/ |
737 | int fc_disc_init(struct fc_lport *lp); | 819 | int fc_disc_init(struct fc_lport *lp); |
738 | 820 | ||
739 | 821 | ||
740 | /** | 822 | /* |
741 | * SCSI LAYER | 823 | * SCSI LAYER |
742 | *****************************/ | 824 | *****************************/ |
743 | /* | 825 | /* |
@@ -798,7 +880,12 @@ int fc_change_queue_type(struct scsi_device *sdev, int tag_type); | |||
798 | */ | 880 | */ |
799 | void fc_fcp_destroy(struct fc_lport *); | 881 | void fc_fcp_destroy(struct fc_lport *); |
800 | 882 | ||
801 | /** | 883 | /* |
884 | * Set up direct-data placement for this I/O request | ||
885 | */ | ||
886 | void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid); | ||
887 | |||
888 | /* | ||
802 | * ELS/CT interface | 889 | * ELS/CT interface |
803 | *****************************/ | 890 | *****************************/ |
804 | /* | 891 | /* |
@@ -807,7 +894,7 @@ void fc_fcp_destroy(struct fc_lport *); | |||
807 | int fc_elsct_init(struct fc_lport *lp); | 894 | int fc_elsct_init(struct fc_lport *lp); |
808 | 895 | ||
809 | 896 | ||
810 | /** | 897 | /* |
811 | * EXCHANGE MANAGER LAYER | 898 | * EXCHANGE MANAGER LAYER |
812 | *****************************/ | 899 | *****************************/ |
813 | /* | 900 | /* |
@@ -916,7 +1003,7 @@ struct fc_seq *fc_seq_start_next(struct fc_seq *sp); | |||
916 | * If s_id is non-zero, reset only exchanges originating from that FID. | 1003 | * If s_id is non-zero, reset only exchanges originating from that FID. |
917 | * If d_id is non-zero, reset only exchanges sending to that FID. | 1004 | * If d_id is non-zero, reset only exchanges sending to that FID. |
918 | */ | 1005 | */ |
919 | void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id); | 1006 | void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); |
920 | 1007 | ||
921 | /* | 1008 | /* |
922 | * Functions for fc_functions_template | 1009 | * Functions for fc_functions_template |
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 89fdbb9a6a1b..666cc131732e 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | 2 | * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. |
3 | * Copyright (c) 2007-2008 Intel Corporation. All rights reserved. | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
@@ -20,157 +21,144 @@ | |||
20 | #ifndef _LIBFCOE_H | 21 | #ifndef _LIBFCOE_H |
21 | #define _LIBFCOE_H | 22 | #define _LIBFCOE_H |
22 | 23 | ||
24 | #include <linux/etherdevice.h> | ||
25 | #include <linux/if_ether.h> | ||
23 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
24 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
28 | #include <linux/workqueue.h> | ||
25 | #include <scsi/fc/fc_fcoe.h> | 29 | #include <scsi/fc/fc_fcoe.h> |
26 | #include <scsi/libfc.h> | 30 | #include <scsi/libfc.h> |
27 | 31 | ||
28 | /* | 32 | /* |
29 | * this percpu struct for fcoe | 33 | * FIP tunable parameters. |
30 | */ | 34 | */ |
31 | struct fcoe_percpu_s { | 35 | #define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */ |
32 | int cpu; | 36 | #define FCOE_CTRL_SOL_TOV 2000 /* min. solicitation interval (mS) */ |
33 | struct task_struct *thread; | 37 | #define FCOE_CTLR_FCF_LIMIT 20 /* max. number of FCF entries */ |
34 | struct sk_buff_head fcoe_rx_list; | 38 | |
35 | struct page *crc_eof_page; | 39 | /** |
36 | int crc_eof_offset; | 40 | * enum fip_state - internal state of FCoE controller. |
41 | * @FIP_ST_DISABLED: controller has been disabled or not yet enabled. | ||
42 | * @FIP_ST_LINK_WAIT: the physical link is down or unusable. | ||
43 | * @FIP_ST_AUTO: determining whether to use FIP or non-FIP mode. | ||
44 | * @FIP_ST_NON_FIP: non-FIP mode selected. | ||
45 | * @FIP_ST_ENABLED: FIP mode selected. | ||
46 | */ | ||
47 | enum fip_state { | ||
48 | FIP_ST_DISABLED, | ||
49 | FIP_ST_LINK_WAIT, | ||
50 | FIP_ST_AUTO, | ||
51 | FIP_ST_NON_FIP, | ||
52 | FIP_ST_ENABLED, | ||
37 | }; | 53 | }; |
38 | 54 | ||
39 | /* | 55 | /** |
40 | * the fcoe sw transport private data | 56 | * struct fcoe_ctlr - FCoE Controller and FIP state. |
57 | * @state: internal FIP state for network link and FIP or non-FIP mode. | ||
58 | * @lp: &fc_lport: libfc local port. | ||
59 | * @sel_fcf: currently selected FCF, or NULL. | ||
60 | * @fcfs: list of discovered FCFs. | ||
61 | * @fcf_count: number of discovered FCF entries. | ||
62 | * @sol_time: time when a multicast solicitation was last sent. | ||
63 | * @sel_time: time after which to select an FCF. | ||
64 | * @port_ka_time: time of next port keep-alive. | ||
65 | * @ctlr_ka_time: time of next controller keep-alive. | ||
66 | * @timer: timer struct used for all delayed events. | ||
67 | * @link_work: &work_struct for doing FCF selection. | ||
68 | * @recv_work: &work_struct for receiving FIP frames. | ||
69 | * @fip_recv_list: list of received FIP frames. | ||
70 | * @user_mfs: configured maximum FC frame size, including FC header. | ||
71 | * @flogi_oxid: exchange ID of most recent fabric login. | ||
72 | * @flogi_count: number of FLOGI attempts in AUTO mode. | ||
73 | * @link: current link status for libfc. | ||
74 | * @last_link: last link state reported to libfc. | ||
75 | * @map_dest: use the FC_MAP mode for destination MAC addresses. | ||
76 | * @dest_addr: MAC address of the selected FC forwarder. | ||
77 | * @ctl_src_addr: the native MAC address of our local port. | ||
78 | * @data_src_addr: the assigned MAC address for the local port after FLOGI. | ||
79 | * @send: LLD-supplied function to handle sending of FIP Ethernet frames. | ||
80 | * @update_mac: LLD-supplied function to handle changes to MAC addresses. | ||
81 | * @lock: lock protecting this structure. | ||
82 | * | ||
83 | * This structure is used by all FCoE drivers. It contains information | ||
84 | * needed by all FCoE low-level drivers (LLDs) as well as internal state | ||
85 | * for FIP, and fields shared with the LLDS. | ||
41 | */ | 86 | */ |
42 | struct fcoe_softc { | 87 | struct fcoe_ctlr { |
43 | struct list_head list; | 88 | enum fip_state state; |
44 | struct fc_lport *lp; | 89 | struct fc_lport *lp; |
45 | struct net_device *real_dev; | 90 | struct fcoe_fcf *sel_fcf; |
46 | struct net_device *phys_dev; /* device with ethtool_ops */ | 91 | struct list_head fcfs; |
47 | struct packet_type fcoe_packet_type; | 92 | u16 fcf_count; |
48 | struct sk_buff_head fcoe_pending_queue; | 93 | unsigned long sol_time; |
49 | 94 | unsigned long sel_time; | |
95 | unsigned long port_ka_time; | ||
96 | unsigned long ctlr_ka_time; | ||
97 | struct timer_list timer; | ||
98 | struct work_struct link_work; | ||
99 | struct work_struct recv_work; | ||
100 | struct sk_buff_head fip_recv_list; | ||
101 | u16 user_mfs; | ||
102 | u16 flogi_oxid; | ||
103 | u8 flogi_count; | ||
104 | u8 link; | ||
105 | u8 last_link; | ||
106 | u8 map_dest; | ||
50 | u8 dest_addr[ETH_ALEN]; | 107 | u8 dest_addr[ETH_ALEN]; |
51 | u8 ctl_src_addr[ETH_ALEN]; | 108 | u8 ctl_src_addr[ETH_ALEN]; |
52 | u8 data_src_addr[ETH_ALEN]; | 109 | u8 data_src_addr[ETH_ALEN]; |
53 | /* | ||
54 | * fcoe protocol address learning related stuff | ||
55 | */ | ||
56 | u16 flogi_oxid; | ||
57 | u8 flogi_progress; | ||
58 | u8 address_mode; | ||
59 | }; | ||
60 | |||
61 | static inline struct fcoe_softc *fcoe_softc( | ||
62 | const struct fc_lport *lp) | ||
63 | { | ||
64 | return (struct fcoe_softc *)lport_priv(lp); | ||
65 | } | ||
66 | |||
67 | static inline struct net_device *fcoe_netdev( | ||
68 | const struct fc_lport *lp) | ||
69 | { | ||
70 | return fcoe_softc(lp)->real_dev; | ||
71 | } | ||
72 | |||
73 | static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) | ||
74 | { | ||
75 | return (struct fcoe_hdr *)skb_network_header(skb); | ||
76 | } | ||
77 | |||
78 | static inline int skb_fcoe_offset(const struct sk_buff *skb) | ||
79 | { | ||
80 | return skb_network_offset(skb); | ||
81 | } | ||
82 | |||
83 | static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb) | ||
84 | { | ||
85 | return (struct fc_frame_header *)skb_transport_header(skb); | ||
86 | } | ||
87 | |||
88 | static inline int skb_fc_offset(const struct sk_buff *skb) | ||
89 | { | ||
90 | return skb_transport_offset(skb); | ||
91 | } | ||
92 | |||
93 | static inline void skb_reset_fc_header(struct sk_buff *skb) | ||
94 | { | ||
95 | skb_reset_network_header(skb); | ||
96 | skb_set_transport_header(skb, skb_network_offset(skb) + | ||
97 | sizeof(struct fcoe_hdr)); | ||
98 | } | ||
99 | 110 | ||
100 | static inline bool skb_fc_is_data(const struct sk_buff *skb) | 111 | void (*send)(struct fcoe_ctlr *, struct sk_buff *); |
101 | { | 112 | void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new); |
102 | return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA; | 113 | spinlock_t lock; |
103 | } | 114 | }; |
104 | |||
105 | static inline bool skb_fc_is_cmd(const struct sk_buff *skb) | ||
106 | { | ||
107 | return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD; | ||
108 | } | ||
109 | |||
110 | static inline bool skb_fc_has_exthdr(const struct sk_buff *skb) | ||
111 | { | ||
112 | return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) || | ||
113 | (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) || | ||
114 | (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH); | ||
115 | } | ||
116 | |||
117 | static inline bool skb_fc_is_roff(const struct sk_buff *skb) | ||
118 | { | ||
119 | return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF; | ||
120 | } | ||
121 | 115 | ||
122 | static inline u16 skb_fc_oxid(const struct sk_buff *skb) | 116 | /* |
123 | { | 117 | * struct fcoe_fcf - Fibre-Channel Forwarder. |
124 | return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); | 118 | * @list: list linkage. |
125 | } | 119 | * @time: system time (jiffies) when an advertisement was last received. |
120 | * @switch_name: WWN of switch from advertisement. | ||
121 | * @fabric_name: WWN of fabric from advertisement. | ||
122 | * @fc_map: FC_MAP value from advertisement. | ||
123 | * @fcf_mac: Ethernet address of the FCF. | ||
124 | * @vfid: virtual fabric ID. | ||
125 | * @pri: seletion priority, smaller values are better. | ||
126 | * @flags: flags received from advertisement. | ||
127 | * @fka_period: keep-alive period, in jiffies. | ||
128 | * | ||
129 | * A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that | ||
130 | * passes FCoE frames on to an FC fabric. This structure represents | ||
131 | * one FCF from which advertisements have been received. | ||
132 | * | ||
133 | * When looking up an FCF, @switch_name, @fabric_name, @fc_map, @vfid, and | ||
134 | * @fcf_mac together form the lookup key. | ||
135 | */ | ||
136 | struct fcoe_fcf { | ||
137 | struct list_head list; | ||
138 | unsigned long time; | ||
126 | 139 | ||
127 | static inline u16 skb_fc_rxid(const struct sk_buff *skb) | 140 | u64 switch_name; |
128 | { | 141 | u64 fabric_name; |
129 | return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); | 142 | u32 fc_map; |
130 | } | 143 | u16 vfid; |
144 | u8 fcf_mac[ETH_ALEN]; | ||
131 | 145 | ||
132 | /* FIXME - DMA_BIDIRECTIONAL ? */ | 146 | u8 pri; |
133 | #define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0])) | 147 | u16 flags; |
134 | #define skb_cmd(skb) (skb_cb(skb)->fr_cmd) | 148 | u32 fka_period; |
135 | #define skb_dir(skb) (skb_cmd(skb)->sc_data_direction) | 149 | }; |
136 | static inline bool skb_fc_is_read(const struct sk_buff *skb) | ||
137 | { | ||
138 | if (skb_fc_is_cmd(skb) && skb_cmd(skb)) | ||
139 | return skb_dir(skb) == DMA_FROM_DEVICE; | ||
140 | return false; | ||
141 | } | ||
142 | 150 | ||
143 | static inline bool skb_fc_is_write(const struct sk_buff *skb) | 151 | /* FIP API functions */ |
144 | { | 152 | void fcoe_ctlr_init(struct fcoe_ctlr *); |
145 | if (skb_fc_is_cmd(skb) && skb_cmd(skb)) | 153 | void fcoe_ctlr_destroy(struct fcoe_ctlr *); |
146 | return skb_dir(skb) == DMA_TO_DEVICE; | 154 | void fcoe_ctlr_link_up(struct fcoe_ctlr *); |
147 | return false; | 155 | int fcoe_ctlr_link_down(struct fcoe_ctlr *); |
148 | } | 156 | int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *); |
157 | void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *); | ||
158 | int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa); | ||
149 | 159 | ||
150 | /* libfcoe funcs */ | 160 | /* libfcoe funcs */ |
151 | int fcoe_reset(struct Scsi_Host *shost); | 161 | u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); |
152 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], | ||
153 | unsigned int scheme, unsigned int port); | ||
154 | |||
155 | u32 fcoe_fc_crc(struct fc_frame *fp); | ||
156 | int fcoe_xmit(struct fc_lport *, struct fc_frame *); | ||
157 | int fcoe_rcv(struct sk_buff *, struct net_device *, | ||
158 | struct packet_type *, struct net_device *); | ||
159 | |||
160 | int fcoe_percpu_receive_thread(void *arg); | ||
161 | void fcoe_clean_pending_queue(struct fc_lport *lp); | ||
162 | void fcoe_percpu_clean(struct fc_lport *lp); | ||
163 | void fcoe_watchdog(ulong vp); | ||
164 | int fcoe_link_ok(struct fc_lport *lp); | ||
165 | |||
166 | struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); | ||
167 | int fcoe_hostlist_add(const struct fc_lport *); | ||
168 | int fcoe_hostlist_remove(const struct fc_lport *); | ||
169 | |||
170 | struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); | ||
171 | int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); | 162 | int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); |
172 | 163 | ||
173 | /* fcoe sw hba */ | ||
174 | int __init fcoe_sw_init(void); | ||
175 | int __exit fcoe_sw_exit(void); | ||
176 | #endif /* _LIBFCOE_H */ | 164 | #endif /* _LIBFCOE_H */ |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 7360e1916e75..0289f5745fb9 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
@@ -36,6 +36,7 @@ struct scsi_transport_template; | |||
36 | struct scsi_host_template; | 36 | struct scsi_host_template; |
37 | struct scsi_device; | 37 | struct scsi_device; |
38 | struct Scsi_Host; | 38 | struct Scsi_Host; |
39 | struct scsi_target; | ||
39 | struct scsi_cmnd; | 40 | struct scsi_cmnd; |
40 | struct socket; | 41 | struct socket; |
41 | struct iscsi_transport; | 42 | struct iscsi_transport; |
@@ -45,18 +46,10 @@ struct iscsi_session; | |||
45 | struct iscsi_nopin; | 46 | struct iscsi_nopin; |
46 | struct device; | 47 | struct device; |
47 | 48 | ||
48 | /* #define DEBUG_SCSI */ | ||
49 | #ifdef DEBUG_SCSI | ||
50 | #define debug_scsi(fmt...) printk(KERN_INFO "iscsi: " fmt) | ||
51 | #else | ||
52 | #define debug_scsi(fmt...) | ||
53 | #endif | ||
54 | |||
55 | #define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ | 49 | #define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ |
56 | #define ISCSI_MGMT_CMDS_MAX 15 | 50 | #define ISCSI_MGMT_CMDS_MAX 15 |
57 | 51 | ||
58 | #define ISCSI_DEF_CMD_PER_LUN 32 | 52 | #define ISCSI_DEF_CMD_PER_LUN 32 |
59 | #define ISCSI_MAX_CMD_PER_LUN 128 | ||
60 | 53 | ||
61 | /* Task Mgmt states */ | 54 | /* Task Mgmt states */ |
62 | enum { | 55 | enum { |
@@ -326,6 +319,9 @@ struct iscsi_host { | |||
326 | spinlock_t lock; | 319 | spinlock_t lock; |
327 | int num_sessions; | 320 | int num_sessions; |
328 | int state; | 321 | int state; |
322 | |||
323 | struct workqueue_struct *workq; | ||
324 | char workq_name[20]; | ||
329 | }; | 325 | }; |
330 | 326 | ||
331 | /* | 327 | /* |
@@ -351,9 +347,11 @@ extern int iscsi_host_get_param(struct Scsi_Host *shost, | |||
351 | enum iscsi_host_param param, char *buf); | 347 | enum iscsi_host_param param, char *buf); |
352 | extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); | 348 | extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); |
353 | extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, | 349 | extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, |
354 | int dd_data_size, uint16_t qdepth); | 350 | int dd_data_size, |
351 | bool xmit_can_sleep); | ||
355 | extern void iscsi_host_remove(struct Scsi_Host *shost); | 352 | extern void iscsi_host_remove(struct Scsi_Host *shost); |
356 | extern void iscsi_host_free(struct Scsi_Host *shost); | 353 | extern void iscsi_host_free(struct Scsi_Host *shost); |
354 | extern int iscsi_target_alloc(struct scsi_target *starget); | ||
357 | 355 | ||
358 | /* | 356 | /* |
359 | * session management | 357 | * session management |
@@ -382,11 +380,12 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); | |||
382 | extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, | 380 | extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, |
383 | int); | 381 | int); |
384 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); | 382 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); |
385 | extern void iscsi_session_failure(struct iscsi_cls_session *cls_session, | 383 | extern void iscsi_session_failure(struct iscsi_session *session, |
386 | enum iscsi_err err); | 384 | enum iscsi_err err); |
387 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | 385 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, |
388 | enum iscsi_param param, char *buf); | 386 | enum iscsi_param param, char *buf); |
389 | extern void iscsi_suspend_tx(struct iscsi_conn *conn); | 387 | extern void iscsi_suspend_tx(struct iscsi_conn *conn); |
388 | extern void iscsi_conn_queue_work(struct iscsi_conn *conn); | ||
390 | 389 | ||
391 | #define iscsi_conn_printk(prefix, _c, fmt, a...) \ | 390 | #define iscsi_conn_printk(prefix, _c, fmt, a...) \ |
392 | iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ | 391 | iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ |
diff --git a/include/scsi/osd_attributes.h b/include/scsi/osd_attributes.h new file mode 100644 index 000000000000..f888a6fda073 --- /dev/null +++ b/include/scsi/osd_attributes.h | |||
@@ -0,0 +1,327 @@ | |||
1 | #ifndef __OSD_ATTRIBUTES_H__ | ||
2 | #define __OSD_ATTRIBUTES_H__ | ||
3 | |||
4 | #include "osd_protocol.h" | ||
5 | |||
6 | /* | ||
7 | * Contains types and constants that define attribute pages and attribute | ||
8 | * numbers and their data types. | ||
9 | */ | ||
10 | |||
11 | #define ATTR_SET(pg, id, l, ptr) \ | ||
12 | { .attr_page = pg, .attr_id = id, .len = l, .val_ptr = ptr } | ||
13 | |||
14 | #define ATTR_DEF(pg, id, l) ATTR_SET(pg, id, l, NULL) | ||
15 | |||
16 | /* osd-r10 4.7.3 Attributes pages */ | ||
17 | enum { | ||
18 | OSD_APAGE_OBJECT_FIRST = 0x0, | ||
19 | OSD_APAGE_OBJECT_DIRECTORY = 0, | ||
20 | OSD_APAGE_OBJECT_INFORMATION = 1, | ||
21 | OSD_APAGE_OBJECT_QUOTAS = 2, | ||
22 | OSD_APAGE_OBJECT_TIMESTAMP = 3, | ||
23 | OSD_APAGE_OBJECT_COLLECTIONS = 4, | ||
24 | OSD_APAGE_OBJECT_SECURITY = 5, | ||
25 | OSD_APAGE_OBJECT_LAST = 0x2fffffff, | ||
26 | |||
27 | OSD_APAGE_PARTITION_FIRST = 0x30000000, | ||
28 | OSD_APAGE_PARTITION_DIRECTORY = OSD_APAGE_PARTITION_FIRST + 0, | ||
29 | OSD_APAGE_PARTITION_INFORMATION = OSD_APAGE_PARTITION_FIRST + 1, | ||
30 | OSD_APAGE_PARTITION_QUOTAS = OSD_APAGE_PARTITION_FIRST + 2, | ||
31 | OSD_APAGE_PARTITION_TIMESTAMP = OSD_APAGE_PARTITION_FIRST + 3, | ||
32 | OSD_APAGE_PARTITION_SECURITY = OSD_APAGE_PARTITION_FIRST + 5, | ||
33 | OSD_APAGE_PARTITION_LAST = 0x5FFFFFFF, | ||
34 | |||
35 | OSD_APAGE_COLLECTION_FIRST = 0x60000000, | ||
36 | OSD_APAGE_COLLECTION_DIRECTORY = OSD_APAGE_COLLECTION_FIRST + 0, | ||
37 | OSD_APAGE_COLLECTION_INFORMATION = OSD_APAGE_COLLECTION_FIRST + 1, | ||
38 | OSD_APAGE_COLLECTION_TIMESTAMP = OSD_APAGE_COLLECTION_FIRST + 3, | ||
39 | OSD_APAGE_COLLECTION_SECURITY = OSD_APAGE_COLLECTION_FIRST + 5, | ||
40 | OSD_APAGE_COLLECTION_LAST = 0x8FFFFFFF, | ||
41 | |||
42 | OSD_APAGE_ROOT_FIRST = 0x90000000, | ||
43 | OSD_APAGE_ROOT_DIRECTORY = OSD_APAGE_ROOT_FIRST + 0, | ||
44 | OSD_APAGE_ROOT_INFORMATION = OSD_APAGE_ROOT_FIRST + 1, | ||
45 | OSD_APAGE_ROOT_QUOTAS = OSD_APAGE_ROOT_FIRST + 2, | ||
46 | OSD_APAGE_ROOT_TIMESTAMP = OSD_APAGE_ROOT_FIRST + 3, | ||
47 | OSD_APAGE_ROOT_SECURITY = OSD_APAGE_ROOT_FIRST + 5, | ||
48 | OSD_APAGE_ROOT_LAST = 0xBFFFFFFF, | ||
49 | |||
50 | OSD_APAGE_RESERVED_TYPE_FIRST = 0xC0000000, | ||
51 | OSD_APAGE_RESERVED_TYPE_LAST = 0xEFFFFFFF, | ||
52 | |||
53 | OSD_APAGE_COMMON_FIRST = 0xF0000000, | ||
54 | OSD_APAGE_COMMON_LAST = 0xFFFFFFFE, | ||
55 | |||
56 | OSD_APAGE_REQUEST_ALL = 0xFFFFFFFF, | ||
57 | }; | ||
58 | |||
59 | /* subcategories of attr pages within each range above */ | ||
60 | enum { | ||
61 | OSD_APAGE_STD_FIRST = 0x0, | ||
62 | OSD_APAGE_STD_DIRECTORY = 0, | ||
63 | OSD_APAGE_STD_INFORMATION = 1, | ||
64 | OSD_APAGE_STD_QUOTAS = 2, | ||
65 | OSD_APAGE_STD_TIMESTAMP = 3, | ||
66 | OSD_APAGE_STD_COLLECTIONS = 4, | ||
67 | OSD_APAGE_STD_POLICY_SECURITY = 5, | ||
68 | OSD_APAGE_STD_LAST = 0x0000007F, | ||
69 | |||
70 | OSD_APAGE_RESERVED_FIRST = 0x00000080, | ||
71 | OSD_APAGE_RESERVED_LAST = 0x00007FFF, | ||
72 | |||
73 | OSD_APAGE_OTHER_STD_FIRST = 0x00008000, | ||
74 | OSD_APAGE_OTHER_STD_LAST = 0x0000EFFF, | ||
75 | |||
76 | OSD_APAGE_PUBLIC_FIRST = 0x0000F000, | ||
77 | OSD_APAGE_PUBLIC_LAST = 0x0000FFFF, | ||
78 | |||
79 | OSD_APAGE_APP_DEFINED_FIRST = 0x00010000, | ||
80 | OSD_APAGE_APP_DEFINED_LAST = 0x1FFFFFFF, | ||
81 | |||
82 | OSD_APAGE_VENDOR_SPECIFIC_FIRST = 0x20000000, | ||
83 | OSD_APAGE_VENDOR_SPECIFIC_LAST = 0x2FFFFFFF, | ||
84 | }; | ||
85 | |||
86 | enum { | ||
87 | OSD_ATTR_PAGE_IDENTIFICATION = 0, /* in all pages 40 bytes */ | ||
88 | }; | ||
89 | |||
90 | struct page_identification { | ||
91 | u8 vendor_identification[8]; | ||
92 | u8 page_identification[32]; | ||
93 | } __packed; | ||
94 | |||
95 | struct osd_attr_page_header { | ||
96 | __be32 page_number; | ||
97 | __be32 page_length; | ||
98 | } __packed; | ||
99 | |||
100 | /* 7.1.2.8 Root Information attributes page (OSD_APAGE_ROOT_INFORMATION) */ | ||
101 | enum { | ||
102 | OSD_ATTR_RI_OSD_SYSTEM_ID = 0x3, /* 20 */ | ||
103 | OSD_ATTR_RI_VENDOR_IDENTIFICATION = 0x4, /* 8 */ | ||
104 | OSD_ATTR_RI_PRODUCT_IDENTIFICATION = 0x5, /* 16 */ | ||
105 | OSD_ATTR_RI_PRODUCT_MODEL = 0x6, /* 32 */ | ||
106 | OSD_ATTR_RI_PRODUCT_REVISION_LEVEL = 0x7, /* 4 */ | ||
107 | OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER = 0x8, /* variable */ | ||
108 | OSD_ATTR_RI_OSD_NAME = 0x9, /* variable */ | ||
109 | OSD_ATTR_RI_TOTAL_CAPACITY = 0x80, /* 8 */ | ||
110 | OSD_ATTR_RI_USED_CAPACITY = 0x81, /* 8 */ | ||
111 | OSD_ATTR_RI_NUMBER_OF_PARTITIONS = 0xC0, /* 8 */ | ||
112 | OSD_ATTR_RI_CLOCK = 0x100, /* 6 */ | ||
113 | }; | ||
114 | /* Root_Information_attributes_page does not have a get_page structure */ | ||
115 | |||
116 | /* 7.1.2.9 Partition Information attributes page | ||
117 | * (OSD_APAGE_PARTITION_INFORMATION) | ||
118 | */ | ||
119 | enum { | ||
120 | OSD_ATTR_PI_PARTITION_ID = 0x1, /* 8 */ | ||
121 | OSD_ATTR_PI_USERNAME = 0x9, /* variable */ | ||
122 | OSD_ATTR_PI_USED_CAPACITY = 0x81, /* 8 */ | ||
123 | OSD_ATTR_PI_NUMBER_OF_OBJECTS = 0xC1, /* 8 */ | ||
124 | }; | ||
125 | /* Partition Information attributes page does not have a get_page structure */ | ||
126 | |||
127 | /* 7.1.2.10 Collection Information attributes page | ||
128 | * (OSD_APAGE_COLLECTION_INFORMATION) | ||
129 | */ | ||
130 | enum { | ||
131 | OSD_ATTR_CI_PARTITION_ID = 0x1, /* 8 */ | ||
132 | OSD_ATTR_CI_COLLECTION_OBJECT_ID = 0x2, /* 8 */ | ||
133 | OSD_ATTR_CI_USERNAME = 0x9, /* variable */ | ||
134 | OSD_ATTR_CI_USED_CAPACITY = 0x81, /* 8 */ | ||
135 | }; | ||
136 | /* Collection Information attributes page does not have a get_page structure */ | ||
137 | |||
138 | /* 7.1.2.11 User Object Information attributes page | ||
139 | * (OSD_APAGE_OBJECT_INFORMATION) | ||
140 | */ | ||
141 | enum { | ||
142 | OSD_ATTR_OI_PARTITION_ID = 0x1, /* 8 */ | ||
143 | OSD_ATTR_OI_OBJECT_ID = 0x2, /* 8 */ | ||
144 | OSD_ATTR_OI_USERNAME = 0x9, /* variable */ | ||
145 | OSD_ATTR_OI_USED_CAPACITY = 0x81, /* 8 */ | ||
146 | OSD_ATTR_OI_LOGICAL_LENGTH = 0x82, /* 8 */ | ||
147 | }; | ||
148 | /* Object Information attributes page does not have a get_page structure */ | ||
149 | |||
150 | /* 7.1.2.12 Root Quotas attributes page (OSD_APAGE_ROOT_QUOTAS) */ | ||
151 | enum { | ||
152 | OSD_ATTR_RQ_DEFAULT_MAXIMUM_USER_OBJECT_LENGTH = 0x1, /* 8 */ | ||
153 | OSD_ATTR_RQ_PARTITION_CAPACITY_QUOTA = 0x10001, /* 8 */ | ||
154 | OSD_ATTR_RQ_PARTITION_OBJECT_COUNT = 0x10002, /* 8 */ | ||
155 | OSD_ATTR_RQ_PARTITION_COLLECTIONS_PER_USER_OBJECT = 0x10081, /* 4 */ | ||
156 | OSD_ATTR_RQ_PARTITION_COUNT = 0x20002, /* 8 */ | ||
157 | }; | ||
158 | |||
159 | struct Root_Quotas_attributes_page { | ||
160 | struct osd_attr_page_header hdr; /* id=R+2, size=0x24 */ | ||
161 | __be64 default_maximum_user_object_length; | ||
162 | __be64 partition_capacity_quota; | ||
163 | __be64 partition_object_count; | ||
164 | __be64 partition_collections_per_user_object; | ||
165 | __be64 partition_count; | ||
166 | } __packed; | ||
167 | |||
168 | /* 7.1.2.13 Partition Quotas attributes page (OSD_APAGE_PARTITION_QUOTAS)*/ | ||
169 | enum { | ||
170 | OSD_ATTR_PQ_DEFAULT_MAXIMUM_USER_OBJECT_LENGTH = 0x1, /* 8 */ | ||
171 | OSD_ATTR_PQ_CAPACITY_QUOTA = 0x10001, /* 8 */ | ||
172 | OSD_ATTR_PQ_OBJECT_COUNT = 0x10002, /* 8 */ | ||
173 | OSD_ATTR_PQ_COLLECTIONS_PER_USER_OBJECT = 0x10081, /* 4 */ | ||
174 | }; | ||
175 | |||
176 | struct Partition_Quotas_attributes_page { | ||
177 | struct osd_attr_page_header hdr; /* id=P+2, size=0x1C */ | ||
178 | __be64 default_maximum_user_object_length; | ||
179 | __be64 capacity_quota; | ||
180 | __be64 object_count; | ||
181 | __be64 collections_per_user_object; | ||
182 | } __packed; | ||
183 | |||
184 | /* 7.1.2.14 User Object Quotas attributes page (OSD_APAGE_OBJECT_QUOTAS) */ | ||
185 | enum { | ||
186 | OSD_ATTR_OQ_MAXIMUM_LENGTH = 0x1, /* 8 */ | ||
187 | }; | ||
188 | |||
189 | struct Object_Quotas_attributes_page { | ||
190 | struct osd_attr_page_header hdr; /* id=U+2, size=0x8 */ | ||
191 | __be64 maximum_length; | ||
192 | } __packed; | ||
193 | |||
194 | /* 7.1.2.15 Root Timestamps attributes page (OSD_APAGE_ROOT_TIMESTAMP) */ | ||
195 | enum { | ||
196 | OSD_ATTR_RT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */ | ||
197 | OSD_ATTR_RT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */ | ||
198 | OSD_ATTR_RT_TIMESTAMP_BYPASS = 0xFFFFFFFE, /* 1 */ | ||
199 | }; | ||
200 | |||
201 | struct root_timestamps_attributes_page { | ||
202 | struct osd_attr_page_header hdr; /* id=R+3, size=0xD */ | ||
203 | struct osd_timestamp attributes_accessed_time; | ||
204 | struct osd_timestamp attributes_modified_time; | ||
205 | u8 timestamp_bypass; | ||
206 | } __packed; | ||
207 | |||
208 | /* 7.1.2.16 Partition Timestamps attributes page | ||
209 | * (OSD_APAGE_PARTITION_TIMESTAMP) | ||
210 | */ | ||
211 | enum { | ||
212 | OSD_ATTR_PT_CREATED_TIME = 0x1, /* 6 */ | ||
213 | OSD_ATTR_PT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */ | ||
214 | OSD_ATTR_PT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */ | ||
215 | OSD_ATTR_PT_DATA_ACCESSED_TIME = 0x4, /* 6 */ | ||
216 | OSD_ATTR_PT_DATA_MODIFIED_TIME = 0x5, /* 6 */ | ||
217 | OSD_ATTR_PT_TIMESTAMP_BYPASS = 0xFFFFFFFE, /* 1 */ | ||
218 | }; | ||
219 | |||
220 | struct partition_timestamps_attributes_page { | ||
221 | struct osd_attr_page_header hdr; /* id=P+3, size=0x1F */ | ||
222 | struct osd_timestamp created_time; | ||
223 | struct osd_timestamp attributes_accessed_time; | ||
224 | struct osd_timestamp attributes_modified_time; | ||
225 | struct osd_timestamp data_accessed_time; | ||
226 | struct osd_timestamp data_modified_time; | ||
227 | u8 timestamp_bypass; | ||
228 | } __packed; | ||
229 | |||
230 | /* 7.1.2.17/18 Collection/Object Timestamps attributes page | ||
231 | * (OSD_APAGE_COLLECTION_TIMESTAMP/OSD_APAGE_OBJECT_TIMESTAMP) | ||
232 | */ | ||
233 | enum { | ||
234 | OSD_ATTR_OT_CREATED_TIME = 0x1, /* 6 */ | ||
235 | OSD_ATTR_OT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */ | ||
236 | OSD_ATTR_OT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */ | ||
237 | OSD_ATTR_OT_DATA_ACCESSED_TIME = 0x4, /* 6 */ | ||
238 | OSD_ATTR_OT_DATA_MODIFIED_TIME = 0x5, /* 6 */ | ||
239 | }; | ||
240 | |||
241 | /* same for collection */ | ||
242 | struct object_timestamps_attributes_page { | ||
243 | struct osd_attr_page_header hdr; /* id=C+3/3, size=0x1E */ | ||
244 | struct osd_timestamp created_time; | ||
245 | struct osd_timestamp attributes_accessed_time; | ||
246 | struct osd_timestamp attributes_modified_time; | ||
247 | struct osd_timestamp data_accessed_time; | ||
248 | struct osd_timestamp data_modified_time; | ||
249 | } __packed; | ||
250 | |||
251 | /* 7.1.2.19 Collections attributes page */ | ||
252 | /* TBD */ | ||
253 | |||
254 | /* 7.1.2.20 Root Policy/Security attributes page (OSD_APAGE_ROOT_SECURITY) */ | ||
255 | enum { | ||
256 | OSD_ATTR_RS_DEFAULT_SECURITY_METHOD = 0x1, /* 1 */ | ||
257 | OSD_ATTR_RS_OLDEST_VALID_NONCE_LIMIT = 0x2, /* 6 */ | ||
258 | OSD_ATTR_RS_NEWEST_VALID_NONCE_LIMIT = 0x3, /* 6 */ | ||
259 | OSD_ATTR_RS_PARTITION_DEFAULT_SECURITY_METHOD = 0x6, /* 1 */ | ||
260 | OSD_ATTR_RS_SUPPORTED_SECURITY_METHODS = 0x7, /* 2 */ | ||
261 | OSD_ATTR_RS_ADJUSTABLE_CLOCK = 0x9, /* 6 */ | ||
262 | OSD_ATTR_RS_MASTER_KEY_IDENTIFIER = 0x7FFD, /* 0 or 7 */ | ||
263 | OSD_ATTR_RS_ROOT_KEY_IDENTIFIER = 0x7FFE, /* 0 or 7 */ | ||
264 | OSD_ATTR_RS_SUPPORTED_INTEGRITY_ALGORITHM_0 = 0x80000000,/* 1,(x16)*/ | ||
265 | OSD_ATTR_RS_SUPPORTED_DH_GROUP_0 = 0x80000010,/* 1,(x16)*/ | ||
266 | }; | ||
267 | |||
268 | struct root_security_attributes_page { | ||
269 | struct osd_attr_page_header hdr; /* id=R+5, size=0x3F */ | ||
270 | u8 default_security_method; | ||
271 | u8 partition_default_security_method; | ||
272 | __be16 supported_security_methods; | ||
273 | u8 mki_valid_rki_valid; | ||
274 | struct osd_timestamp oldest_valid_nonce_limit; | ||
275 | struct osd_timestamp newest_valid_nonce_limit; | ||
276 | struct osd_timestamp adjustable_clock; | ||
277 | u8 master_key_identifier[32-25]; | ||
278 | u8 root_key_identifier[39-32]; | ||
279 | u8 supported_integrity_algorithm[16]; | ||
280 | u8 supported_dh_group[16]; | ||
281 | } __packed; | ||
282 | |||
283 | /* 7.1.2.21 Partition Policy/Security attributes page | ||
284 | * (OSD_APAGE_PARTITION_SECURITY) | ||
285 | */ | ||
286 | enum { | ||
287 | OSD_ATTR_PS_DEFAULT_SECURITY_METHOD = 0x1, /* 1 */ | ||
288 | OSD_ATTR_PS_OLDEST_VALID_NONCE = 0x2, /* 6 */ | ||
289 | OSD_ATTR_PS_NEWEST_VALID_NONCE = 0x3, /* 6 */ | ||
290 | OSD_ATTR_PS_REQUEST_NONCE_LIST_DEPTH = 0x4, /* 2 */ | ||
291 | OSD_ATTR_PS_FROZEN_WORKING_KEY_BIT_MASK = 0x5, /* 2 */ | ||
292 | OSD_ATTR_PS_PARTITION_KEY_IDENTIFIER = 0x7FFF, /* 0 or 7 */ | ||
293 | OSD_ATTR_PS_WORKING_KEY_IDENTIFIER_FIRST = 0x8000, /* 0 or 7 */ | ||
294 | OSD_ATTR_PS_WORKING_KEY_IDENTIFIER_LAST = 0x800F, /* 0 or 7 */ | ||
295 | OSD_ATTR_PS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */ | ||
296 | OSD_ATTR_PS_USER_OBJECT_POLICY_ACCESS_TAG = 0x40000002, /* 4 */ | ||
297 | }; | ||
298 | |||
299 | struct partition_security_attributes_page { | ||
300 | struct osd_attr_page_header hdr; /* id=p+5, size=0x8f */ | ||
301 | u8 reserved[3]; | ||
302 | u8 default_security_method; | ||
303 | struct osd_timestamp oldest_valid_nonce; | ||
304 | struct osd_timestamp newest_valid_nonce; | ||
305 | __be16 request_nonce_list_depth; | ||
306 | __be16 frozen_working_key_bit_mask; | ||
307 | __be32 policy_access_tag; | ||
308 | __be32 user_object_policy_access_tag; | ||
309 | u8 pki_valid; | ||
310 | __be16 wki_00_0f_vld; | ||
311 | struct osd_key_identifier partition_key_identifier; | ||
312 | struct osd_key_identifier working_key_identifiers[16]; | ||
313 | } __packed; | ||
314 | |||
315 | /* 7.1.2.22/23 Collection/Object Policy-Security attributes page | ||
316 | * (OSD_APAGE_COLLECTION_SECURITY/OSD_APAGE_OBJECT_SECURITY) | ||
317 | */ | ||
318 | enum { | ||
319 | OSD_ATTR_OS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */ | ||
320 | }; | ||
321 | |||
322 | struct object_security_attributes_page { | ||
323 | struct osd_attr_page_header hdr; /* id=C+5/5, size=4 */ | ||
324 | __be32 policy_access_tag; | ||
325 | } __packed; | ||
326 | |||
327 | #endif /*ndef __OSD_ATTRIBUTES_H__*/ | ||
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h new file mode 100644 index 000000000000..b24d9616eb46 --- /dev/null +++ b/include/scsi/osd_initiator.h | |||
@@ -0,0 +1,433 @@ | |||
1 | /* | ||
2 | * osd_initiator.h - OSD initiator API definition | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <bharrosh@panasas.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __OSD_INITIATOR_H__ | ||
15 | #define __OSD_INITIATOR_H__ | ||
16 | |||
17 | #include "osd_protocol.h" | ||
18 | #include "osd_types.h" | ||
19 | |||
20 | #include <linux/blkdev.h> | ||
21 | |||
22 | /* Note: "NI" in comments below means "Not Implemented yet" */ | ||
23 | |||
24 | /* Configure of code: | ||
25 | * #undef if you *don't* want OSD v1 support in runtime. | ||
26 | * If #defined the initiator will dynamically configure to encode OSD v1 | ||
27 | * CDB's if the target is detected to be OSD v1 only. | ||
28 | * OSD v2 only commands, options, and attributes will be ignored if target | ||
29 | * is v1 only. | ||
30 | * If #defined will result in bigger/slower code (OK Slower maybe not) | ||
31 | * Q: Should this be CONFIG_SCSI_OSD_VER1_SUPPORT and set from Kconfig? | ||
32 | */ | ||
33 | #define OSD_VER1_SUPPORT y | ||
34 | |||
35 | enum osd_std_version { | ||
36 | OSD_VER_NONE = 0, | ||
37 | OSD_VER1 = 1, | ||
38 | OSD_VER2 = 2, | ||
39 | }; | ||
40 | |||
41 | /* | ||
42 | * Object-based Storage Device. | ||
43 | * This object represents an OSD device. | ||
44 | * It is not a full linux device in any way. It is only | ||
45 | * a place to hang resources associated with a Linux | ||
46 | * request Q and some default properties. | ||
47 | */ | ||
48 | struct osd_dev { | ||
49 | struct scsi_device *scsi_device; | ||
50 | unsigned def_timeout; | ||
51 | |||
52 | #ifdef OSD_VER1_SUPPORT | ||
53 | enum osd_std_version version; | ||
54 | #endif | ||
55 | }; | ||
56 | |||
57 | /* Retrieve/return osd_dev(s) for use by Kernel clients */ | ||
58 | struct osd_dev *osduld_path_lookup(const char *dev_name); /*Use IS_ERR/ERR_PTR*/ | ||
59 | void osduld_put_device(struct osd_dev *od); | ||
60 | |||
61 | /* Add/remove test ioctls from external modules */ | ||
62 | typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg); | ||
63 | int osduld_register_test(unsigned ioctl, do_test_fn *do_test); | ||
64 | void osduld_unregister_test(unsigned ioctl); | ||
65 | |||
66 | /* These are called by uld at probe time */ | ||
67 | void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); | ||
68 | void osd_dev_fini(struct osd_dev *od); | ||
69 | |||
70 | /* some hi level device operations */ | ||
71 | int osd_auto_detect_ver(struct osd_dev *od, void *caps); /* GFP_KERNEL */ | ||
72 | |||
73 | /* we might want to use function vector in the future */ | ||
74 | static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) | ||
75 | { | ||
76 | #ifdef OSD_VER1_SUPPORT | ||
77 | od->version = v; | ||
78 | #endif | ||
79 | } | ||
80 | |||
81 | struct osd_request; | ||
82 | typedef void (osd_req_done_fn)(struct osd_request *or, void *private); | ||
83 | |||
84 | struct osd_request { | ||
85 | struct osd_cdb cdb; | ||
86 | struct osd_data_out_integrity_info out_data_integ; | ||
87 | struct osd_data_in_integrity_info in_data_integ; | ||
88 | |||
89 | struct osd_dev *osd_dev; | ||
90 | struct request *request; | ||
91 | |||
92 | struct _osd_req_data_segment { | ||
93 | void *buff; | ||
94 | unsigned alloc_size; /* 0 here means: don't call kfree */ | ||
95 | unsigned total_bytes; | ||
96 | } set_attr, enc_get_attr, get_attr; | ||
97 | |||
98 | struct _osd_io_info { | ||
99 | struct bio *bio; | ||
100 | u64 total_bytes; | ||
101 | struct request *req; | ||
102 | struct _osd_req_data_segment *last_seg; | ||
103 | u8 *pad_buff; | ||
104 | } out, in; | ||
105 | |||
106 | gfp_t alloc_flags; | ||
107 | unsigned timeout; | ||
108 | unsigned retries; | ||
109 | u8 sense[OSD_MAX_SENSE_LEN]; | ||
110 | enum osd_attributes_mode attributes_mode; | ||
111 | |||
112 | osd_req_done_fn *async_done; | ||
113 | void *async_private; | ||
114 | int async_error; | ||
115 | }; | ||
116 | |||
117 | /* OSD Version control */ | ||
118 | static inline bool osd_req_is_ver1(struct osd_request *or) | ||
119 | { | ||
120 | #ifdef OSD_VER1_SUPPORT | ||
121 | return or->osd_dev->version == OSD_VER1; | ||
122 | #else | ||
123 | return false; | ||
124 | #endif | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * How to use the osd library: | ||
129 | * | ||
130 | * osd_start_request | ||
131 | * Allocates a request. | ||
132 | * | ||
133 | * osd_req_* | ||
134 | * Call one of, to encode the desired operation. | ||
135 | * | ||
136 | * osd_add_{get,set}_attr | ||
137 | * Optionally add attributes to the CDB, list or page mode. | ||
138 | * | ||
139 | * osd_finalize_request | ||
140 | * Computes final data out/in offsets and signs the request, | ||
141 | * making it ready for execution. | ||
142 | * | ||
143 | * osd_execute_request | ||
144 | * May be called to execute it through the block layer. Other wise submit | ||
145 | * the associated block request in some other way. | ||
146 | * | ||
147 | * After execution: | ||
148 | * osd_req_decode_sense | ||
149 | * Decodes sense information to verify execution results. | ||
150 | * | ||
151 | * osd_req_decode_get_attr | ||
152 | * Retrieve osd_add_get_attr_list() values if used. | ||
153 | * | ||
154 | * osd_end_request | ||
155 | * Must be called to deallocate the request. | ||
156 | */ | ||
157 | |||
158 | /** | ||
159 | * osd_start_request - Allocate and initialize an osd_request | ||
160 | * | ||
161 | * @osd_dev: OSD device that holds the scsi-device and default values | ||
162 | * that the request is associated with. | ||
163 | * @gfp: The allocation flags to use for request allocation, and all | ||
164 | * subsequent allocations. This will be stored at | ||
165 | * osd_request->alloc_flags, can be changed by user later | ||
166 | * | ||
167 | * Allocate osd_request and initialize all members to the | ||
168 | * default/initial state. | ||
169 | */ | ||
170 | struct osd_request *osd_start_request(struct osd_dev *od, gfp_t gfp); | ||
171 | |||
172 | enum osd_req_options { | ||
173 | OSD_REQ_FUA = 0x08, /* Force Unit Access */ | ||
174 | OSD_REQ_DPO = 0x10, /* Disable Page Out */ | ||
175 | |||
176 | OSD_REQ_BYPASS_TIMESTAMPS = 0x80, | ||
177 | }; | ||
178 | |||
179 | /** | ||
180 | * osd_finalize_request - Sign request and prepare request for execution | ||
181 | * | ||
182 | * @or: osd_request to prepare | ||
183 | * @options: combination of osd_req_options bit flags or 0. | ||
184 | * @cap: A Pointer to an OSD_CAP_LEN bytes buffer that is received from | ||
185 | * The security manager as capabilities for this cdb. | ||
186 | * @cap_key: The cryptographic key used to sign the cdb/data. Can be null | ||
187 | * if NOSEC is used. | ||
188 | * | ||
189 | * The actual request and bios are only allocated here, so are the get_attr | ||
190 | * buffers that will receive the returned attributes. Copy's @cap to cdb. | ||
191 | * Sign the cdb/data with @cap_key. | ||
192 | */ | ||
193 | int osd_finalize_request(struct osd_request *or, | ||
194 | u8 options, const void *cap, const u8 *cap_key); | ||
195 | |||
196 | /** | ||
197 | * osd_execute_request - Execute the request synchronously through block-layer | ||
198 | * | ||
199 | * @or: osd_request to Executed | ||
200 | * | ||
201 | * Calls blk_execute_rq to q the command and waits for completion. | ||
202 | */ | ||
203 | int osd_execute_request(struct osd_request *or); | ||
204 | |||
205 | /** | ||
206 | * osd_execute_request_async - Execute the request without waitting. | ||
207 | * | ||
208 | * @or: - osd_request to Executed | ||
209 | * @done: (Optional) - Called at end of execution | ||
210 | * @private: - Will be passed to @done function | ||
211 | * | ||
212 | * Calls blk_execute_rq_nowait to queue the command. When execution is done | ||
213 | * optionally calls @done with @private as parameter. @or->async_error will | ||
214 | * have the return code | ||
215 | */ | ||
216 | int osd_execute_request_async(struct osd_request *or, | ||
217 | osd_req_done_fn *done, void *private); | ||
218 | |||
219 | /** | ||
220 | * osd_req_decode_sense_full - Decode sense information after execution. | ||
221 | * | ||
222 | * @or: - osd_request to examine | ||
223 | * @osi - Recievs a more detailed error report information (optional). | ||
224 | * @silent - Do not print to dmsg (Even if enabled) | ||
225 | * @bad_obj_list - Some commands act on multiple objects. Failed objects will | ||
226 | * be recieved here (optional) | ||
227 | * @max_obj - Size of @bad_obj_list. | ||
228 | * @bad_attr_list - List of failing attributes (optional) | ||
229 | * @max_attr - Size of @bad_attr_list. | ||
230 | * | ||
231 | * After execution, sense + return code can be analyzed using this function. The | ||
232 | * return code is the final disposition on the error. So it is possible that a | ||
233 | * CHECK_CONDITION was returned from target but this will return NO_ERROR, for | ||
234 | * example on recovered errors. All parameters are optional if caller does | ||
235 | * not need any returned information. | ||
236 | * Note: This function will also dump the error to dmsg according to settings | ||
237 | * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the | ||
238 | * command would routinely fail, to not spam the dmsg file. | ||
239 | */ | ||
240 | struct osd_sense_info { | ||
241 | int key; /* one of enum scsi_sense_keys */ | ||
242 | int additional_code ; /* enum osd_additional_sense_codes */ | ||
243 | union { /* Sense specific information */ | ||
244 | u16 sense_info; | ||
245 | u16 cdb_field_offset; /* scsi_invalid_field_in_cdb */ | ||
246 | }; | ||
247 | union { /* Command specific information */ | ||
248 | u64 command_info; | ||
249 | }; | ||
250 | |||
251 | u32 not_initiated_command_functions; /* osd_command_functions_bits */ | ||
252 | u32 completed_command_functions; /* osd_command_functions_bits */ | ||
253 | struct osd_obj_id obj; | ||
254 | struct osd_attr attr; | ||
255 | }; | ||
256 | |||
257 | int osd_req_decode_sense_full(struct osd_request *or, | ||
258 | struct osd_sense_info *osi, bool silent, | ||
259 | struct osd_obj_id *bad_obj_list, int max_obj, | ||
260 | struct osd_attr *bad_attr_list, int max_attr); | ||
261 | |||
262 | static inline int osd_req_decode_sense(struct osd_request *or, | ||
263 | struct osd_sense_info *osi) | ||
264 | { | ||
265 | return osd_req_decode_sense_full(or, osi, false, NULL, 0, NULL, 0); | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * osd_end_request - return osd_request to free store | ||
270 | * | ||
271 | * @or: osd_request to free | ||
272 | * | ||
273 | * Deallocate all osd_request resources (struct req's, BIOs, buffers, etc.) | ||
274 | */ | ||
275 | void osd_end_request(struct osd_request *or); | ||
276 | |||
277 | /* | ||
278 | * CDB Encoding | ||
279 | * | ||
280 | * Note: call only one of the following methods. | ||
281 | */ | ||
282 | |||
283 | /* | ||
284 | * Device commands | ||
285 | */ | ||
286 | void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */ | ||
287 | void osd_req_set_master_key(struct osd_request *or, ...);/* NI */ | ||
288 | |||
289 | void osd_req_format(struct osd_request *or, u64 tot_capacity); | ||
290 | |||
291 | /* list all partitions | ||
292 | * @list header must be initialized to zero on first run. | ||
293 | * | ||
294 | * Call osd_is_obj_list_done() to find if we got the complete list. | ||
295 | */ | ||
296 | int osd_req_list_dev_partitions(struct osd_request *or, | ||
297 | osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem); | ||
298 | |||
299 | void osd_req_flush_obsd(struct osd_request *or, | ||
300 | enum osd_options_flush_scope_values); | ||
301 | |||
302 | void osd_req_perform_scsi_command(struct osd_request *or, | ||
303 | const u8 *cdb, ...);/* NI */ | ||
304 | void osd_req_task_management(struct osd_request *or, ...);/* NI */ | ||
305 | |||
306 | /* | ||
307 | * Partition commands | ||
308 | */ | ||
309 | void osd_req_create_partition(struct osd_request *or, osd_id partition); | ||
310 | void osd_req_remove_partition(struct osd_request *or, osd_id partition); | ||
311 | |||
312 | void osd_req_set_partition_key(struct osd_request *or, | ||
313 | osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE], | ||
314 | u8 seed[OSD_CRYPTO_SEED_SIZE]);/* NI */ | ||
315 | |||
316 | /* list all collections in the partition | ||
317 | * @list header must be init to zero on first run. | ||
318 | * | ||
319 | * Call osd_is_obj_list_done() to find if we got the complete list. | ||
320 | */ | ||
321 | int osd_req_list_partition_collections(struct osd_request *or, | ||
322 | osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, | ||
323 | unsigned nelem); | ||
324 | |||
325 | /* list all objects in the partition | ||
326 | * @list header must be init to zero on first run. | ||
327 | * | ||
328 | * Call osd_is_obj_list_done() to find if we got the complete list. | ||
329 | */ | ||
330 | int osd_req_list_partition_objects(struct osd_request *or, | ||
331 | osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, | ||
332 | unsigned nelem); | ||
333 | |||
334 | void osd_req_flush_partition(struct osd_request *or, | ||
335 | osd_id partition, enum osd_options_flush_scope_values); | ||
336 | |||
337 | /* | ||
338 | * Collection commands | ||
339 | */ | ||
340 | void osd_req_create_collection(struct osd_request *or, | ||
341 | const struct osd_obj_id *);/* NI */ | ||
342 | void osd_req_remove_collection(struct osd_request *or, | ||
343 | const struct osd_obj_id *);/* NI */ | ||
344 | |||
345 | /* list all objects in the collection */ | ||
346 | int osd_req_list_collection_objects(struct osd_request *or, | ||
347 | const struct osd_obj_id *, osd_id initial_id, | ||
348 | struct osd_obj_id_list *list, unsigned nelem); | ||
349 | |||
350 | /* V2 only filtered list of objects in the collection */ | ||
351 | void osd_req_query(struct osd_request *or, ...);/* NI */ | ||
352 | |||
353 | void osd_req_flush_collection(struct osd_request *or, | ||
354 | const struct osd_obj_id *, enum osd_options_flush_scope_values); | ||
355 | |||
356 | void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */ | ||
357 | void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */ | ||
358 | |||
359 | /* | ||
360 | * Object commands | ||
361 | */ | ||
362 | void osd_req_create_object(struct osd_request *or, struct osd_obj_id *); | ||
363 | void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *); | ||
364 | |||
365 | void osd_req_write(struct osd_request *or, | ||
366 | const struct osd_obj_id *, struct bio *data_out, u64 offset); | ||
367 | void osd_req_append(struct osd_request *or, | ||
368 | const struct osd_obj_id *, struct bio *data_out);/* NI */ | ||
369 | void osd_req_create_write(struct osd_request *or, | ||
370 | const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */ | ||
371 | void osd_req_clear(struct osd_request *or, | ||
372 | const struct osd_obj_id *, u64 offset, u64 len);/* NI */ | ||
373 | void osd_req_punch(struct osd_request *or, | ||
374 | const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */ | ||
375 | |||
376 | void osd_req_flush_object(struct osd_request *or, | ||
377 | const struct osd_obj_id *, enum osd_options_flush_scope_values, | ||
378 | /*V2*/ u64 offset, /*V2*/ u64 len); | ||
379 | |||
380 | void osd_req_read(struct osd_request *or, | ||
381 | const struct osd_obj_id *, struct bio *data_in, u64 offset); | ||
382 | |||
383 | /* | ||
384 | * Root/Partition/Collection/Object Attributes commands | ||
385 | */ | ||
386 | |||
387 | /* get before set */ | ||
388 | void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *); | ||
389 | |||
390 | /* set before get */ | ||
391 | void osd_req_set_attributes(struct osd_request *or, const struct osd_obj_id *); | ||
392 | |||
393 | /* | ||
394 | * Attributes appended to most commands | ||
395 | */ | ||
396 | |||
397 | /* Attributes List mode (or V2 CDB) */ | ||
398 | /* | ||
399 | * TODO: In ver2 if at finalize time only one attr was set and no gets, | ||
400 | * then the Attributes CDB mode is used automatically to save IO. | ||
401 | */ | ||
402 | |||
403 | /* set a list of attributes. */ | ||
404 | int osd_req_add_set_attr_list(struct osd_request *or, | ||
405 | const struct osd_attr *, unsigned nelem); | ||
406 | |||
407 | /* get a list of attributes */ | ||
408 | int osd_req_add_get_attr_list(struct osd_request *or, | ||
409 | const struct osd_attr *, unsigned nelem); | ||
410 | |||
411 | /* | ||
412 | * Attributes list decoding | ||
413 | * Must be called after osd_request.request was executed | ||
414 | * It is called in a loop to decode the returned get_attr | ||
415 | * (see osd_add_get_attr) | ||
416 | */ | ||
417 | int osd_req_decode_get_attr_list(struct osd_request *or, | ||
418 | struct osd_attr *, int *nelem, void **iterator); | ||
419 | |||
420 | /* Attributes Page mode */ | ||
421 | |||
422 | /* | ||
423 | * Read an attribute page and optionally set one attribute | ||
424 | * | ||
425 | * Retrieves the attribute page directly to a user buffer. | ||
426 | * @attr_page_data shall stay valid until end of execution. | ||
427 | * See osd_attributes.h for common page structures | ||
428 | */ | ||
429 | int osd_req_add_get_attr_page(struct osd_request *or, | ||
430 | u32 page_id, void *attr_page_data, unsigned max_page_len, | ||
431 | const struct osd_attr *set_one); | ||
432 | |||
433 | #endif /* __OSD_LIB_H__ */ | ||
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h new file mode 100644 index 000000000000..62b2ab8c69d4 --- /dev/null +++ b/include/scsi/osd_protocol.h | |||
@@ -0,0 +1,625 @@ | |||
1 | /* | ||
2 | * osd_protocol.h - OSD T10 standard C definitions. | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <bharrosh@panasas.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | * This file contains types and constants that are defined by the protocol | ||
14 | * Note: All names and symbols are taken from the OSD standard's text. | ||
15 | */ | ||
16 | #ifndef __OSD_PROTOCOL_H__ | ||
17 | #define __OSD_PROTOCOL_H__ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <asm/unaligned.h> | ||
21 | #include <scsi/scsi.h> | ||
22 | |||
23 | enum { | ||
24 | OSDv1_ADDITIONAL_CDB_LENGTH = 192, | ||
25 | OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8, | ||
26 | OSDv1_CAP_LEN = 80, | ||
27 | |||
28 | /* Latest supported version */ | ||
29 | OSDv2_ADDITIONAL_CDB_LENGTH = 228, | ||
30 | OSD_ADDITIONAL_CDB_LENGTH = | ||
31 | OSDv2_ADDITIONAL_CDB_LENGTH, | ||
32 | OSD_TOTAL_CDB_LEN = OSD_ADDITIONAL_CDB_LENGTH + 8, | ||
33 | OSD_CAP_LEN = 104, | ||
34 | |||
35 | OSD_SYSTEMID_LEN = 20, | ||
36 | OSDv1_CRYPTO_KEYID_SIZE = 20, | ||
37 | OSDv2_CRYPTO_KEYID_SIZE = 32, | ||
38 | OSD_CRYPTO_KEYID_SIZE = OSDv2_CRYPTO_KEYID_SIZE, | ||
39 | OSD_CRYPTO_SEED_SIZE = 4, | ||
40 | OSD_CRYPTO_NONCE_SIZE = 12, | ||
41 | OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ | ||
42 | |||
43 | OSD_PARTITION_FIRST_ID = 0x10000, | ||
44 | OSD_OBJECT_FIRST_ID = 0x10000, | ||
45 | }; | ||
46 | |||
47 | /* (osd-r10 5.2.4) | ||
48 | * osd2r03: 5.2.3 Caching control bits | ||
49 | */ | ||
50 | enum osd_options_byte { | ||
51 | OSD_CDB_FUA = 0x08, /* Force Unit Access */ | ||
52 | OSD_CDB_DPO = 0x10, /* Disable Page Out */ | ||
53 | }; | ||
54 | |||
55 | /* | ||
56 | * osd2r03: 5.2.5 Isolation. | ||
57 | * First 3 bits, V2-only. | ||
58 | * Also for attr 110h "default isolation method" at Root Information page | ||
59 | */ | ||
60 | enum osd_options_byte_isolation { | ||
61 | OSD_ISOLATION_DEFAULT = 0, | ||
62 | OSD_ISOLATION_NONE = 1, | ||
63 | OSD_ISOLATION_STRICT = 2, | ||
64 | OSD_ISOLATION_RANGE = 4, | ||
65 | OSD_ISOLATION_FUNCTIONAL = 5, | ||
66 | OSD_ISOLATION_VENDOR = 7, | ||
67 | }; | ||
68 | |||
69 | /* (osd-r10: 6.7) | ||
70 | * osd2r03: 6.8 FLUSH, FLUSH COLLECTION, FLUSH OSD, FLUSH PARTITION | ||
71 | */ | ||
72 | enum osd_options_flush_scope_values { | ||
73 | OSD_CDB_FLUSH_ALL = 0, | ||
74 | OSD_CDB_FLUSH_ATTR_ONLY = 1, | ||
75 | |||
76 | OSD_CDB_FLUSH_ALL_RECURSIVE = 2, | ||
77 | /* V2-only */ | ||
78 | OSD_CDB_FLUSH_ALL_RANGE = 2, | ||
79 | }; | ||
80 | |||
81 | /* osd2r03: 5.2.10 Timestamps control */ | ||
82 | enum { | ||
83 | OSD_CDB_NORMAL_TIMESTAMPS = 0, | ||
84 | OSD_CDB_BYPASS_TIMESTAMPS = 0x7f, | ||
85 | }; | ||
86 | |||
87 | /* (osd-r10: 5.2.2.1) | ||
88 | * osd2r03: 5.2.4.1 Get and set attributes CDB format selection | ||
89 | * 2 bits at second nibble of command_specific_options byte | ||
90 | */ | ||
91 | enum osd_attributes_mode { | ||
92 | /* V2-only */ | ||
93 | OSD_CDB_SET_ONE_ATTR = 0x10, | ||
94 | |||
95 | OSD_CDB_GET_ATTR_PAGE_SET_ONE = 0x20, | ||
96 | OSD_CDB_GET_SET_ATTR_LISTS = 0x30, | ||
97 | |||
98 | OSD_CDB_GET_SET_ATTR_MASK = 0x30, | ||
99 | }; | ||
100 | |||
101 | /* (osd-r10: 4.12.5) | ||
102 | * osd2r03: 4.14.5 Data-In and Data-Out buffer offsets | ||
103 | * byte offset = mantissa * (2^(exponent+8)) | ||
104 | * struct { | ||
105 | * unsigned mantissa: 28; | ||
106 | * int exponent: 04; | ||
107 | * } | ||
108 | */ | ||
109 | typedef __be32 __bitwise osd_cdb_offset; | ||
110 | |||
111 | enum { | ||
112 | OSD_OFFSET_UNUSED = 0xFFFFFFFF, | ||
113 | OSD_OFFSET_MAX_BITS = 28, | ||
114 | |||
115 | OSDv1_OFFSET_MIN_SHIFT = 8, | ||
116 | OSD_OFFSET_MIN_SHIFT = 3, | ||
117 | OSD_OFFSET_MAX_SHIFT = 16, | ||
118 | }; | ||
119 | |||
120 | /* Return the smallest allowed encoded offset that contains @offset. | ||
121 | * | ||
122 | * The actual encoded offset returned is @offset + *padding. | ||
123 | * (up to max_shift, non-inclusive) | ||
124 | */ | ||
125 | osd_cdb_offset __osd_encode_offset(u64 offset, unsigned *padding, | ||
126 | int min_shift, int max_shift); | ||
127 | |||
128 | /* Minimum alignment is 256 bytes | ||
129 | * Note: Seems from std v1 that exponent can be from 0+8 to 0xE+8 (inclusive) | ||
130 | * which is 8 to 23 but IBM code restricts it to 16, so be it. | ||
131 | */ | ||
132 | static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding) | ||
133 | { | ||
134 | return __osd_encode_offset(offset, padding, | ||
135 | OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); | ||
136 | } | ||
137 | |||
138 | /* Minimum 8 bytes alignment | ||
139 | * Same as v1 but since exponent can be signed than a less than | ||
140 | * 256 alignment can be reached with small offsets (<2GB) | ||
141 | */ | ||
142 | static inline osd_cdb_offset osd_encode_offset_v2(u64 offset, unsigned *padding) | ||
143 | { | ||
144 | return __osd_encode_offset(offset, padding, | ||
145 | OSD_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); | ||
146 | } | ||
147 | |||
148 | /* osd2r03: 5.2.1 Overview */ | ||
149 | struct osd_cdb_head { | ||
150 | struct scsi_varlen_cdb_hdr varlen_cdb; | ||
151 | /*10*/ u8 options; | ||
152 | u8 command_specific_options; | ||
153 | u8 timestamp_control; | ||
154 | /*13*/ u8 reserved1[3]; | ||
155 | /*16*/ __be64 partition; | ||
156 | /*24*/ __be64 object; | ||
157 | /*32*/ union { /* V1 vs V2 alignment differences */ | ||
158 | struct __osdv1_cdb_addr_len { | ||
159 | /*32*/ __be32 list_identifier;/* Rarely used */ | ||
160 | /*36*/ __be64 length; | ||
161 | /*44*/ __be64 start_address; | ||
162 | } __packed v1; | ||
163 | |||
164 | struct __osdv2_cdb_addr_len { | ||
165 | /* called allocation_length in some commands */ | ||
166 | /*32*/ __be64 length; | ||
167 | /*40*/ __be64 start_address; | ||
168 | union { | ||
169 | /*48*/ __be32 list_identifier;/* Rarely used */ | ||
170 | /* OSD2r05 5.2.5 CDB continuation length */ | ||
171 | /*48*/ __be32 cdb_continuation_length; | ||
172 | }; | ||
173 | } __packed v2; | ||
174 | }; | ||
175 | /*52*/ union { /* selected attributes mode Page/List/Single */ | ||
176 | struct osd_attributes_page_mode { | ||
177 | /*52*/ __be32 get_attr_page; | ||
178 | /*56*/ __be32 get_attr_alloc_length; | ||
179 | /*60*/ osd_cdb_offset get_attr_offset; | ||
180 | |||
181 | /*64*/ __be32 set_attr_page; | ||
182 | /*68*/ __be32 set_attr_id; | ||
183 | /*72*/ __be32 set_attr_length; | ||
184 | /*76*/ osd_cdb_offset set_attr_offset; | ||
185 | /*80*/ } __packed attrs_page; | ||
186 | |||
187 | struct osd_attributes_list_mode { | ||
188 | /*52*/ __be32 get_attr_desc_bytes; | ||
189 | /*56*/ osd_cdb_offset get_attr_desc_offset; | ||
190 | |||
191 | /*60*/ __be32 get_attr_alloc_length; | ||
192 | /*64*/ osd_cdb_offset get_attr_offset; | ||
193 | |||
194 | /*68*/ __be32 set_attr_bytes; | ||
195 | /*72*/ osd_cdb_offset set_attr_offset; | ||
196 | __be32 not_used; | ||
197 | /*80*/ } __packed attrs_list; | ||
198 | |||
199 | /* osd2r03:5.2.4.2 Set one attribute value using CDB fields */ | ||
200 | struct osd_attributes_cdb_mode { | ||
201 | /*52*/ __be32 set_attr_page; | ||
202 | /*56*/ __be32 set_attr_id; | ||
203 | /*60*/ __be16 set_attr_len; | ||
204 | /*62*/ u8 set_attr_val[18]; | ||
205 | /*80*/ } __packed attrs_cdb; | ||
206 | /*52*/ u8 get_set_attributes_parameters[28]; | ||
207 | }; | ||
208 | } __packed; | ||
209 | /*80*/ | ||
210 | |||
211 | /*160 v1*/ | ||
212 | struct osdv1_security_parameters { | ||
213 | /*160*/u8 integrity_check_value[OSDv1_CRYPTO_KEYID_SIZE]; | ||
214 | /*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | ||
215 | /*192*/osd_cdb_offset data_in_integrity_check_offset; | ||
216 | /*196*/osd_cdb_offset data_out_integrity_check_offset; | ||
217 | } __packed; | ||
218 | /*200 v1*/ | ||
219 | |||
220 | /*184 v2*/ | ||
221 | struct osdv2_security_parameters { | ||
222 | /*184*/u8 integrity_check_value[OSDv2_CRYPTO_KEYID_SIZE]; | ||
223 | /*216*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | ||
224 | /*228*/osd_cdb_offset data_in_integrity_check_offset; | ||
225 | /*232*/osd_cdb_offset data_out_integrity_check_offset; | ||
226 | } __packed; | ||
227 | /*236 v2*/ | ||
228 | |||
229 | struct osd_security_parameters { | ||
230 | union { | ||
231 | struct osdv1_security_parameters v1; | ||
232 | struct osdv2_security_parameters v2; | ||
233 | }; | ||
234 | }; | ||
235 | |||
236 | struct osdv1_cdb { | ||
237 | struct osd_cdb_head h; | ||
238 | u8 caps[OSDv1_CAP_LEN]; | ||
239 | struct osdv1_security_parameters sec_params; | ||
240 | } __packed; | ||
241 | |||
242 | struct osdv2_cdb { | ||
243 | struct osd_cdb_head h; | ||
244 | u8 caps[OSD_CAP_LEN]; | ||
245 | struct osdv2_security_parameters sec_params; | ||
246 | } __packed; | ||
247 | |||
248 | struct osd_cdb { | ||
249 | union { | ||
250 | struct osdv1_cdb v1; | ||
251 | struct osdv2_cdb v2; | ||
252 | u8 buff[OSD_TOTAL_CDB_LEN]; | ||
253 | }; | ||
254 | } __packed; | ||
255 | |||
256 | static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb) | ||
257 | { | ||
258 | return (struct osd_cdb_head *)ocdb->buff; | ||
259 | } | ||
260 | |||
261 | /* define both version actions | ||
262 | * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD | ||
263 | */ | ||
264 | #define OSD_ACT___(Name, Num) \ | ||
265 | OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), \ | ||
266 | OSDv1_ACT_##Name = __constant_cpu_to_be16(0x8800 + Num), | ||
267 | |||
268 | /* V2 only actions */ | ||
269 | #define OSD_ACT_V2(Name, Num) \ | ||
270 | OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), | ||
271 | |||
272 | #define OSD_ACT_V1_V2(Name, Num1, Num2) \ | ||
273 | OSD_ACT_##Name = __constant_cpu_to_be16(Num2), \ | ||
274 | OSDv1_ACT_##Name = __constant_cpu_to_be16(Num1), | ||
275 | |||
276 | enum osd_service_actions { | ||
277 | OSD_ACT_V2(OBJECT_STRUCTURE_CHECK, 0x00) | ||
278 | OSD_ACT___(FORMAT_OSD, 0x01) | ||
279 | OSD_ACT___(CREATE, 0x02) | ||
280 | OSD_ACT___(LIST, 0x03) | ||
281 | OSD_ACT_V2(PUNCH, 0x04) | ||
282 | OSD_ACT___(READ, 0x05) | ||
283 | OSD_ACT___(WRITE, 0x06) | ||
284 | OSD_ACT___(APPEND, 0x07) | ||
285 | OSD_ACT___(FLUSH, 0x08) | ||
286 | OSD_ACT_V2(CLEAR, 0x09) | ||
287 | OSD_ACT___(REMOVE, 0x0A) | ||
288 | OSD_ACT___(CREATE_PARTITION, 0x0B) | ||
289 | OSD_ACT___(REMOVE_PARTITION, 0x0C) | ||
290 | OSD_ACT___(GET_ATTRIBUTES, 0x0E) | ||
291 | OSD_ACT___(SET_ATTRIBUTES, 0x0F) | ||
292 | OSD_ACT___(CREATE_AND_WRITE, 0x12) | ||
293 | OSD_ACT___(CREATE_COLLECTION, 0x15) | ||
294 | OSD_ACT___(REMOVE_COLLECTION, 0x16) | ||
295 | OSD_ACT___(LIST_COLLECTION, 0x17) | ||
296 | OSD_ACT___(SET_KEY, 0x18) | ||
297 | OSD_ACT___(SET_MASTER_KEY, 0x19) | ||
298 | OSD_ACT___(FLUSH_COLLECTION, 0x1A) | ||
299 | OSD_ACT___(FLUSH_PARTITION, 0x1B) | ||
300 | OSD_ACT___(FLUSH_OSD, 0x1C) | ||
301 | |||
302 | OSD_ACT_V2(QUERY, 0x20) | ||
303 | OSD_ACT_V2(REMOVE_MEMBER_OBJECTS, 0x21) | ||
304 | OSD_ACT_V2(GET_MEMBER_ATTRIBUTES, 0x22) | ||
305 | OSD_ACT_V2(SET_MEMBER_ATTRIBUTES, 0x23) | ||
306 | OSD_ACT_V2(READ_MAP, 0x31) | ||
307 | |||
308 | OSD_ACT_V1_V2(PERFORM_SCSI_COMMAND, 0x8F7E, 0x8F7C) | ||
309 | OSD_ACT_V1_V2(SCSI_TASK_MANAGEMENT, 0x8F7F, 0x8F7D) | ||
310 | /* 0x8F80 to 0x8FFF are Vendor specific */ | ||
311 | }; | ||
312 | |||
313 | /* osd2r03: 7.1.3.2 List entry format for retrieving attributes */ | ||
314 | struct osd_attributes_list_attrid { | ||
315 | __be32 attr_page; | ||
316 | __be32 attr_id; | ||
317 | } __packed; | ||
318 | |||
319 | /* | ||
320 | * NOTE: v1: is not aligned. | ||
321 | */ | ||
322 | struct osdv1_attributes_list_element { | ||
323 | __be32 attr_page; | ||
324 | __be32 attr_id; | ||
325 | __be16 attr_bytes; /* valid bytes at attr_val without padding */ | ||
326 | u8 attr_val[0]; | ||
327 | } __packed; | ||
328 | |||
329 | /* | ||
330 | * osd2r03: 7.1.3.3 List entry format for retrieved attributes and | ||
331 | * for setting attributes | ||
332 | * NOTE: v2 is 8-bytes aligned | ||
333 | */ | ||
334 | struct osdv2_attributes_list_element { | ||
335 | __be32 attr_page; | ||
336 | __be32 attr_id; | ||
337 | u8 reserved[6]; | ||
338 | __be16 attr_bytes; /* valid bytes at attr_val without padding */ | ||
339 | u8 attr_val[0]; | ||
340 | } __packed; | ||
341 | |||
342 | enum { | ||
343 | OSDv1_ATTRIBUTES_ELEM_ALIGN = 1, | ||
344 | OSD_ATTRIBUTES_ELEM_ALIGN = 8, | ||
345 | }; | ||
346 | |||
347 | enum { | ||
348 | OSD_ATTR_LIST_ALL_PAGES = 0xFFFFFFFF, | ||
349 | OSD_ATTR_LIST_ALL_IN_PAGE = 0xFFFFFFFF, | ||
350 | }; | ||
351 | |||
352 | static inline unsigned osdv1_attr_list_elem_size(unsigned len) | ||
353 | { | ||
354 | return ALIGN(len + sizeof(struct osdv1_attributes_list_element), | ||
355 | OSDv1_ATTRIBUTES_ELEM_ALIGN); | ||
356 | } | ||
357 | |||
358 | static inline unsigned osdv2_attr_list_elem_size(unsigned len) | ||
359 | { | ||
360 | return ALIGN(len + sizeof(struct osdv2_attributes_list_element), | ||
361 | OSD_ATTRIBUTES_ELEM_ALIGN); | ||
362 | } | ||
363 | |||
364 | /* | ||
365 | * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values | ||
366 | */ | ||
367 | enum osd_attr_list_types { | ||
368 | OSD_ATTR_LIST_GET = 0x1, /* descriptors only */ | ||
369 | OSD_ATTR_LIST_SET_RETRIEVE = 0x9, /*descriptors/values variable-length*/ | ||
370 | OSD_V2_ATTR_LIST_MULTIPLE = 0xE, /* ver2, Multiple Objects lists*/ | ||
371 | OSD_V1_ATTR_LIST_CREATE_MULTIPLE = 0xF,/*ver1, used by create_multple*/ | ||
372 | }; | ||
373 | |||
374 | /* osd2r03: 7.1.3.4 Multi-object retrieved attributes format */ | ||
375 | struct osd_attributes_list_multi_header { | ||
376 | __be64 object_id; | ||
377 | u8 object_type; /* object_type enum below */ | ||
378 | u8 reserved[5]; | ||
379 | __be16 list_bytes; | ||
380 | /* followed by struct osd_attributes_list_element's */ | ||
381 | }; | ||
382 | |||
383 | struct osdv1_attributes_list_header { | ||
384 | u8 type; /* low 4-bit only */ | ||
385 | u8 pad; | ||
386 | __be16 list_bytes; /* Initiator shall set to Zero. Only set by target */ | ||
387 | /* | ||
388 | * type=9 followed by struct osd_attributes_list_element's | ||
389 | * type=E followed by struct osd_attributes_list_multi_header's | ||
390 | */ | ||
391 | } __packed; | ||
392 | |||
393 | static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h) | ||
394 | { | ||
395 | return be16_to_cpu(h->list_bytes); | ||
396 | } | ||
397 | |||
398 | struct osdv2_attributes_list_header { | ||
399 | u8 type; /* lower 4-bits only */ | ||
400 | u8 pad[3]; | ||
401 | /*4*/ __be32 list_bytes; /* Initiator shall set to zero. Only set by target */ | ||
402 | /* | ||
403 | * type=9 followed by struct osd_attributes_list_element's | ||
404 | * type=E followed by struct osd_attributes_list_multi_header's | ||
405 | */ | ||
406 | } __packed; | ||
407 | |||
408 | static inline unsigned osdv2_list_size(struct osdv2_attributes_list_header *h) | ||
409 | { | ||
410 | return be32_to_cpu(h->list_bytes); | ||
411 | } | ||
412 | |||
413 | /* (osd-r10 6.13) | ||
414 | * osd2r03: 6.15 LIST (Table 79) LIST command parameter data. | ||
415 | * for root_lstchg below | ||
416 | */ | ||
417 | enum { | ||
418 | OSD_OBJ_ID_LIST_PAR = 0x1, /* V1-only. Not used in V2 */ | ||
419 | OSD_OBJ_ID_LIST_LSTCHG = 0x2, | ||
420 | }; | ||
421 | |||
422 | /* | ||
423 | * osd2r03: 6.15.2 LIST command parameter data | ||
424 | * (Also for LIST COLLECTION) | ||
425 | */ | ||
426 | struct osd_obj_id_list { | ||
427 | __be64 list_bytes; /* bytes in list excluding list_bytes (-8) */ | ||
428 | __be64 continuation_id; | ||
429 | __be32 list_identifier; | ||
430 | u8 pad[3]; | ||
431 | u8 root_lstchg; | ||
432 | __be64 object_ids[0]; | ||
433 | } __packed; | ||
434 | |||
435 | static inline bool osd_is_obj_list_done(struct osd_obj_id_list *list, | ||
436 | bool *is_changed) | ||
437 | { | ||
438 | *is_changed = (0 != (list->root_lstchg & OSD_OBJ_ID_LIST_LSTCHG)); | ||
439 | return 0 != list->continuation_id; | ||
440 | } | ||
441 | |||
442 | /* | ||
443 | * osd2r03: 4.12.4.5 The ALLDATA security method | ||
444 | */ | ||
445 | struct osd_data_out_integrity_info { | ||
446 | __be64 data_bytes; | ||
447 | __be64 set_attributes_bytes; | ||
448 | __be64 get_attributes_bytes; | ||
449 | __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | ||
450 | } __packed; | ||
451 | |||
452 | /* Same osd_data_out_integrity_info is used for OSD2/OSD1. The only difference | ||
453 | * Is the sizeof the structure since in OSD1 the last array is smaller. Use | ||
454 | * below for version independent handling of this structure | ||
455 | */ | ||
456 | static inline int osd_data_out_integrity_info_sizeof(bool is_ver1) | ||
457 | { | ||
458 | return sizeof(struct osd_data_out_integrity_info) - | ||
459 | (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); | ||
460 | } | ||
461 | |||
462 | struct osd_data_in_integrity_info { | ||
463 | __be64 data_bytes; | ||
464 | __be64 retrieved_attributes_bytes; | ||
465 | __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | ||
466 | } __packed; | ||
467 | |||
468 | /* Same osd_data_in_integrity_info is used for OSD2/OSD1. The only difference | ||
469 | * Is the sizeof the structure since in OSD1 the last array is smaller. Use | ||
470 | * below for version independent handling of this structure | ||
471 | */ | ||
472 | static inline int osd_data_in_integrity_info_sizeof(bool is_ver1) | ||
473 | { | ||
474 | return sizeof(struct osd_data_in_integrity_info) - | ||
475 | (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); | ||
476 | } | ||
477 | |||
478 | struct osd_timestamp { | ||
479 | u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */ | ||
480 | } __packed; | ||
481 | /* FIXME: define helper functions to convert to/from osd time format */ | ||
482 | |||
483 | /* | ||
484 | * Capability & Security definitions | ||
485 | * osd2r03: 4.11.2.2 Capability format | ||
486 | * osd2r03: 5.2.8 Security parameters | ||
487 | */ | ||
488 | |||
489 | struct osd_key_identifier { | ||
490 | u8 id[7]; /* if you know why 7 please email bharrosh@panasas.com */ | ||
491 | } __packed; | ||
492 | |||
493 | /* for osd_capability.format */ | ||
494 | enum { | ||
495 | OSD_SEC_CAP_FORMAT_NO_CAPS = 0, | ||
496 | OSD_SEC_CAP_FORMAT_VER1 = 1, | ||
497 | OSD_SEC_CAP_FORMAT_VER2 = 2, | ||
498 | }; | ||
499 | |||
500 | /* security_method */ | ||
501 | enum { | ||
502 | OSD_SEC_NOSEC = 0, | ||
503 | OSD_SEC_CAPKEY = 1, | ||
504 | OSD_SEC_CMDRSP = 2, | ||
505 | OSD_SEC_ALLDATA = 3, | ||
506 | }; | ||
507 | |||
508 | enum object_type { | ||
509 | OSD_SEC_OBJ_ROOT = 0x1, | ||
510 | OSD_SEC_OBJ_PARTITION = 0x2, | ||
511 | OSD_SEC_OBJ_COLLECTION = 0x40, | ||
512 | OSD_SEC_OBJ_USER = 0x80, | ||
513 | }; | ||
514 | |||
515 | enum osd_capability_bit_masks { | ||
516 | OSD_SEC_CAP_APPEND = BIT(0), | ||
517 | OSD_SEC_CAP_OBJ_MGMT = BIT(1), | ||
518 | OSD_SEC_CAP_REMOVE = BIT(2), | ||
519 | OSD_SEC_CAP_CREATE = BIT(3), | ||
520 | OSD_SEC_CAP_SET_ATTR = BIT(4), | ||
521 | OSD_SEC_CAP_GET_ATTR = BIT(5), | ||
522 | OSD_SEC_CAP_WRITE = BIT(6), | ||
523 | OSD_SEC_CAP_READ = BIT(7), | ||
524 | |||
525 | OSD_SEC_CAP_NONE1 = BIT(8), | ||
526 | OSD_SEC_CAP_NONE2 = BIT(9), | ||
527 | OSD_SEC_GBL_REM = BIT(10), /*v2 only*/ | ||
528 | OSD_SEC_CAP_QUERY = BIT(11), /*v2 only*/ | ||
529 | OSD_SEC_CAP_M_OBJECT = BIT(12), /*v2 only*/ | ||
530 | OSD_SEC_CAP_POL_SEC = BIT(13), | ||
531 | OSD_SEC_CAP_GLOBAL = BIT(14), | ||
532 | OSD_SEC_CAP_DEV_MGMT = BIT(15), | ||
533 | }; | ||
534 | |||
535 | /* for object_descriptor_type (hi nibble used) */ | ||
536 | enum { | ||
537 | OSD_SEC_OBJ_DESC_NONE = 0, /* Not allowed */ | ||
538 | OSD_SEC_OBJ_DESC_OBJ = 1 << 4, /* v1: also collection */ | ||
539 | OSD_SEC_OBJ_DESC_PAR = 2 << 4, /* also root */ | ||
540 | OSD_SEC_OBJ_DESC_COL = 3 << 4, /* v2 only */ | ||
541 | }; | ||
542 | |||
543 | /* (osd-r10:4.9.2.2) | ||
544 | * osd2r03:4.11.2.2 Capability format | ||
545 | */ | ||
546 | struct osd_capability_head { | ||
547 | u8 format; /* low nibble */ | ||
548 | u8 integrity_algorithm__key_version; /* MAKE_BYTE(integ_alg, key_ver) */ | ||
549 | u8 security_method; | ||
550 | u8 reserved1; | ||
551 | /*04*/ struct osd_timestamp expiration_time; | ||
552 | /*10*/ u8 audit[20]; | ||
553 | /*30*/ u8 discriminator[12]; | ||
554 | /*42*/ struct osd_timestamp object_created_time; | ||
555 | /*48*/ u8 object_type; | ||
556 | /*49*/ u8 permissions_bit_mask[5]; | ||
557 | /*54*/ u8 reserved2; | ||
558 | /*55*/ u8 object_descriptor_type; /* high nibble */ | ||
559 | } __packed; | ||
560 | |||
561 | /*56 v1*/ | ||
562 | struct osdv1_cap_object_descriptor { | ||
563 | union { | ||
564 | struct { | ||
565 | /*56*/ __be32 policy_access_tag; | ||
566 | /*60*/ __be64 allowed_partition_id; | ||
567 | /*68*/ __be64 allowed_object_id; | ||
568 | /*76*/ __be32 reserved; | ||
569 | } __packed obj_desc; | ||
570 | |||
571 | /*56*/ u8 object_descriptor[24]; | ||
572 | }; | ||
573 | } __packed; | ||
574 | /*80 v1*/ | ||
575 | |||
576 | /*56 v2*/ | ||
577 | struct osd_cap_object_descriptor { | ||
578 | union { | ||
579 | struct { | ||
580 | /*56*/ __be32 allowed_attributes_access; | ||
581 | /*60*/ __be32 policy_access_tag; | ||
582 | /*64*/ __be16 boot_epoch; | ||
583 | /*66*/ u8 reserved[6]; | ||
584 | /*72*/ __be64 allowed_partition_id; | ||
585 | /*80*/ __be64 allowed_object_id; | ||
586 | /*88*/ __be64 allowed_range_length; | ||
587 | /*96*/ __be64 allowed_range_start; | ||
588 | } __packed obj_desc; | ||
589 | |||
590 | /*56*/ u8 object_descriptor[48]; | ||
591 | }; | ||
592 | } __packed; | ||
593 | /*104 v2*/ | ||
594 | |||
595 | struct osdv1_capability { | ||
596 | struct osd_capability_head h; | ||
597 | struct osdv1_cap_object_descriptor od; | ||
598 | } __packed; | ||
599 | |||
600 | struct osd_capability { | ||
601 | struct osd_capability_head h; | ||
602 | struct osd_cap_object_descriptor od; | ||
603 | } __packed; | ||
604 | |||
605 | /** | ||
606 | * osd_sec_set_caps - set cap-bits into the capabilities header | ||
607 | * | ||
608 | * @cap: The osd_capability_head to set cap bits to. | ||
609 | * @bit_mask: Use an ORed list of enum osd_capability_bit_masks values | ||
610 | * | ||
611 | * permissions_bit_mask is unaligned use below to set into caps | ||
612 | * in a version independent way | ||
613 | */ | ||
614 | static inline void osd_sec_set_caps(struct osd_capability_head *cap, | ||
615 | u16 bit_mask) | ||
616 | { | ||
617 | /* | ||
618 | *Note: The bits above are defined LE order this is because this way | ||
619 | * they can grow in the future to more then 16, and still retain | ||
620 | * there constant values. | ||
621 | */ | ||
622 | put_unaligned_le16(bit_mask, &cap->permissions_bit_mask); | ||
623 | } | ||
624 | |||
625 | #endif /* ndef __OSD_PROTOCOL_H__ */ | ||
diff --git a/include/scsi/osd_sec.h b/include/scsi/osd_sec.h new file mode 100644 index 000000000000..4c09fee8ae1e --- /dev/null +++ b/include/scsi/osd_sec.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * osd_sec.h - OSD security manager API | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <bharrosh@panasas.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __OSD_SEC_H__ | ||
15 | #define __OSD_SEC_H__ | ||
16 | |||
17 | #include "osd_protocol.h" | ||
18 | #include "osd_types.h" | ||
19 | |||
20 | /* | ||
21 | * Contains types and constants of osd capabilities and security | ||
22 | * encoding/decoding. | ||
23 | * API is trying to keep security abstract so initiator of an object | ||
24 | * based pNFS client knows as little as possible about security and | ||
25 | * capabilities. It is the Server's osd-initiator place to know more. | ||
26 | * Also can be used by osd-target. | ||
27 | */ | ||
28 | void osd_sec_encode_caps(void *caps, ...);/* NI */ | ||
29 | void osd_sec_init_nosec_doall_caps(void *caps, | ||
30 | const struct osd_obj_id *obj, bool is_collection, const bool is_v1); | ||
31 | |||
32 | bool osd_is_sec_alldata(struct osd_security_parameters *sec_params); | ||
33 | |||
34 | /* Conditionally sign the CDB according to security setting in ocdb | ||
35 | * with cap_key */ | ||
36 | void osd_sec_sign_cdb(struct osd_cdb *ocdb, const u8 *cap_key); | ||
37 | |||
38 | /* Unconditionally sign the BIO data with cap_key. | ||
39 | * Check for osd_is_sec_alldata() was done prior to calling this. */ | ||
40 | void osd_sec_sign_data(void *data_integ, struct bio *bio, const u8 *cap_key); | ||
41 | |||
42 | /* Version independent copy of caps into the cdb */ | ||
43 | void osd_set_caps(struct osd_cdb *cdb, const void *caps); | ||
44 | |||
45 | #endif /* ndef __OSD_SEC_H__ */ | ||
diff --git a/include/scsi/osd_sense.h b/include/scsi/osd_sense.h new file mode 100644 index 000000000000..ff9b33c773c7 --- /dev/null +++ b/include/scsi/osd_sense.h | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * osd_sense.h - OSD Related sense handling definitions. | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <bharrosh@panasas.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | * This file contains types and constants that are defined by the protocol | ||
14 | * Note: All names and symbols are taken from the OSD standard's text. | ||
15 | */ | ||
16 | #ifndef __OSD_SENSE_H__ | ||
17 | #define __OSD_SENSE_H__ | ||
18 | |||
19 | #include <scsi/osd_protocol.h> | ||
20 | |||
21 | /* SPC3r23 4.5.6 Sense key and sense code definitions table 27 */ | ||
22 | enum scsi_sense_keys { | ||
23 | scsi_sk_no_sense = 0x0, | ||
24 | scsi_sk_recovered_error = 0x1, | ||
25 | scsi_sk_not_ready = 0x2, | ||
26 | scsi_sk_medium_error = 0x3, | ||
27 | scsi_sk_hardware_error = 0x4, | ||
28 | scsi_sk_illegal_request = 0x5, | ||
29 | scsi_sk_unit_attention = 0x6, | ||
30 | scsi_sk_data_protect = 0x7, | ||
31 | scsi_sk_blank_check = 0x8, | ||
32 | scsi_sk_vendor_specific = 0x9, | ||
33 | scsi_sk_copy_aborted = 0xa, | ||
34 | scsi_sk_aborted_command = 0xb, | ||
35 | scsi_sk_volume_overflow = 0xd, | ||
36 | scsi_sk_miscompare = 0xe, | ||
37 | scsi_sk_reserved = 0xf, | ||
38 | }; | ||
39 | |||
40 | /* SPC3r23 4.5.6 Sense key and sense code definitions table 28 */ | ||
41 | /* Note: only those which can be returned by an OSD target. Most of | ||
42 | * these errors are taken care of by the generic scsi layer. | ||
43 | */ | ||
44 | enum osd_additional_sense_codes { | ||
45 | scsi_no_additional_sense_information = 0x0000, | ||
46 | scsi_operation_in_progress = 0x0016, | ||
47 | scsi_cleaning_requested = 0x0017, | ||
48 | scsi_lunr_cause_not_reportable = 0x0400, | ||
49 | scsi_logical_unit_is_in_process_of_becoming_ready = 0x0401, | ||
50 | scsi_lunr_initializing_command_required = 0x0402, | ||
51 | scsi_lunr_manual_intervention_required = 0x0403, | ||
52 | scsi_lunr_operation_in_progress = 0x0407, | ||
53 | scsi_lunr_selftest_in_progress = 0x0409, | ||
54 | scsi_luna_asymmetric_access_state_transition = 0x040a, | ||
55 | scsi_luna_target_port_in_standby_state = 0x040b, | ||
56 | scsi_luna_target_port_in_unavailable_state = 0x040c, | ||
57 | scsi_lunr_notify_enable_spinup_required = 0x0411, | ||
58 | scsi_logical_unit_does_not_respond_to_selection = 0x0500, | ||
59 | scsi_logical_unit_communication_failure = 0x0800, | ||
60 | scsi_logical_unit_communication_timeout = 0x0801, | ||
61 | scsi_logical_unit_communication_parity_error = 0x0802, | ||
62 | scsi_error_log_overflow = 0x0a00, | ||
63 | scsi_warning = 0x0b00, | ||
64 | scsi_warning_specified_temperature_exceeded = 0x0b01, | ||
65 | scsi_warning_enclosure_degraded = 0x0b02, | ||
66 | scsi_write_error_unexpected_unsolicited_data = 0x0c0c, | ||
67 | scsi_write_error_not_enough_unsolicited_data = 0x0c0d, | ||
68 | scsi_invalid_information_unit = 0x0e00, | ||
69 | scsi_invalid_field_in_command_information_unit = 0x0e03, | ||
70 | scsi_read_error_failed_retransmission_request = 0x1113, | ||
71 | scsi_parameter_list_length_error = 0x1a00, | ||
72 | scsi_invalid_command_operation_code = 0x2000, | ||
73 | scsi_invalid_field_in_cdb = 0x2400, | ||
74 | osd_security_audit_value_frozen = 0x2404, | ||
75 | osd_security_working_key_frozen = 0x2405, | ||
76 | osd_nonce_not_unique = 0x2406, | ||
77 | osd_nonce_timestamp_out_of_range = 0x2407, | ||
78 | scsi_logical_unit_not_supported = 0x2500, | ||
79 | scsi_invalid_field_in_parameter_list = 0x2600, | ||
80 | scsi_parameter_not_supported = 0x2601, | ||
81 | scsi_parameter_value_invalid = 0x2602, | ||
82 | scsi_invalid_release_of_persistent_reservation = 0x2604, | ||
83 | osd_invalid_dataout_buffer_integrity_check_value = 0x260f, | ||
84 | scsi_not_ready_to_ready_change_medium_may_have_changed = 0x2800, | ||
85 | scsi_power_on_reset_or_bus_device_reset_occurred = 0x2900, | ||
86 | scsi_power_on_occurred = 0x2901, | ||
87 | scsi_scsi_bus_reset_occurred = 0x2902, | ||
88 | scsi_bus_device_reset_function_occurred = 0x2903, | ||
89 | scsi_device_internal_reset = 0x2904, | ||
90 | scsi_transceiver_mode_changed_to_single_ended = 0x2905, | ||
91 | scsi_transceiver_mode_changed_to_lvd = 0x2906, | ||
92 | scsi_i_t_nexus_loss_occurred = 0x2907, | ||
93 | scsi_parameters_changed = 0x2a00, | ||
94 | scsi_mode_parameters_changed = 0x2a01, | ||
95 | scsi_asymmetric_access_state_changed = 0x2a06, | ||
96 | scsi_priority_changed = 0x2a08, | ||
97 | scsi_command_sequence_error = 0x2c00, | ||
98 | scsi_previous_busy_status = 0x2c07, | ||
99 | scsi_previous_task_set_full_status = 0x2c08, | ||
100 | scsi_previous_reservation_conflict_status = 0x2c09, | ||
101 | osd_partition_or_collection_contains_user_objects = 0x2c0a, | ||
102 | scsi_commands_cleared_by_another_initiator = 0x2f00, | ||
103 | scsi_cleaning_failure = 0x3007, | ||
104 | scsi_enclosure_failure = 0x3400, | ||
105 | scsi_enclosure_services_failure = 0x3500, | ||
106 | scsi_unsupported_enclosure_function = 0x3501, | ||
107 | scsi_enclosure_services_unavailable = 0x3502, | ||
108 | scsi_enclosure_services_transfer_failure = 0x3503, | ||
109 | scsi_enclosure_services_transfer_refused = 0x3504, | ||
110 | scsi_enclosure_services_checksum_error = 0x3505, | ||
111 | scsi_rounded_parameter = 0x3700, | ||
112 | osd_read_past_end_of_user_object = 0x3b17, | ||
113 | scsi_logical_unit_has_not_self_configured_yet = 0x3e00, | ||
114 | scsi_logical_unit_failure = 0x3e01, | ||
115 | scsi_timeout_on_logical_unit = 0x3e02, | ||
116 | scsi_logical_unit_failed_selftest = 0x3e03, | ||
117 | scsi_logical_unit_unable_to_update_selftest_log = 0x3e04, | ||
118 | scsi_target_operating_conditions_have_changed = 0x3f00, | ||
119 | scsi_microcode_has_been_changed = 0x3f01, | ||
120 | scsi_inquiry_data_has_changed = 0x3f03, | ||
121 | scsi_echo_buffer_overwritten = 0x3f0f, | ||
122 | scsi_diagnostic_failure_on_component_nn_first = 0x4080, | ||
123 | scsi_diagnostic_failure_on_component_nn_last = 0x40ff, | ||
124 | scsi_message_error = 0x4300, | ||
125 | scsi_internal_target_failure = 0x4400, | ||
126 | scsi_select_or_reselect_failure = 0x4500, | ||
127 | scsi_scsi_parity_error = 0x4700, | ||
128 | scsi_data_phase_crc_error_detected = 0x4701, | ||
129 | scsi_scsi_parity_error_detected_during_st_data_phase = 0x4702, | ||
130 | scsi_asynchronous_information_protection_error_detected = 0x4704, | ||
131 | scsi_protocol_service_crc_error = 0x4705, | ||
132 | scsi_phy_test_function_in_progress = 0x4706, | ||
133 | scsi_invalid_message_error = 0x4900, | ||
134 | scsi_command_phase_error = 0x4a00, | ||
135 | scsi_data_phase_error = 0x4b00, | ||
136 | scsi_logical_unit_failed_self_configuration = 0x4c00, | ||
137 | scsi_overlapped_commands_attempted = 0x4e00, | ||
138 | osd_quota_error = 0x5507, | ||
139 | scsi_failure_prediction_threshold_exceeded = 0x5d00, | ||
140 | scsi_failure_prediction_threshold_exceeded_false = 0x5dff, | ||
141 | scsi_voltage_fault = 0x6500, | ||
142 | }; | ||
143 | |||
144 | enum scsi_descriptor_types { | ||
145 | scsi_sense_information = 0x0, | ||
146 | scsi_sense_command_specific_information = 0x1, | ||
147 | scsi_sense_key_specific = 0x2, | ||
148 | scsi_sense_field_replaceable_unit = 0x3, | ||
149 | scsi_sense_stream_commands = 0x4, | ||
150 | scsi_sense_block_commands = 0x5, | ||
151 | osd_sense_object_identification = 0x6, | ||
152 | osd_sense_response_integrity_check = 0x7, | ||
153 | osd_sense_attribute_identification = 0x8, | ||
154 | scsi_sense_ata_return = 0x9, | ||
155 | |||
156 | scsi_sense_Reserved_first = 0x0A, | ||
157 | scsi_sense_Reserved_last = 0x7F, | ||
158 | scsi_sense_Vendor_specific_first = 0x80, | ||
159 | scsi_sense_Vendor_specific_last = 0xFF, | ||
160 | }; | ||
161 | |||
162 | struct scsi_sense_descriptor { /* for picking into desc type */ | ||
163 | u8 descriptor_type; /* one of enum scsi_descriptor_types */ | ||
164 | u8 additional_length; /* n - 1 */ | ||
165 | u8 data[]; | ||
166 | } __packed; | ||
167 | |||
168 | /* OSD deploys only scsi descriptor_based sense buffers */ | ||
169 | struct scsi_sense_descriptor_based { | ||
170 | /*0*/ u8 response_code; /* 0x72 or 0x73 */ | ||
171 | /*1*/ u8 sense_key; /* one of enum scsi_sense_keys (4 lower bits) */ | ||
172 | /*2*/ __be16 additional_sense_code; /* enum osd_additional_sense_codes */ | ||
173 | /*4*/ u8 Reserved[3]; | ||
174 | /*7*/ u8 additional_sense_length; /* n - 7 */ | ||
175 | /*8*/ struct scsi_sense_descriptor ssd[0]; /* variable length, 1 or more */ | ||
176 | } __packed; | ||
177 | |||
178 | /* some descriptors deployed by OSD */ | ||
179 | |||
180 | /* SPC3r23 4.5.2.3 Command-specific information sense data descriptor */ | ||
181 | /* Note: this is the same for descriptor_type=00 but with type=00 the | ||
182 | * Reserved[0] == 0x80 (ie. bit-7 set) | ||
183 | */ | ||
184 | struct scsi_sense_command_specific_data_descriptor { | ||
185 | /*0*/ u8 descriptor_type; /* (00h/01h) */ | ||
186 | /*1*/ u8 additional_length; /* (0Ah) */ | ||
187 | /*2*/ u8 Reserved[2]; | ||
188 | /*4*/ __be64 information; | ||
189 | } __packed; | ||
190 | /*12*/ | ||
191 | |||
192 | struct scsi_sense_key_specific_data_descriptor { | ||
193 | /*0*/ u8 descriptor_type; /* (02h) */ | ||
194 | /*1*/ u8 additional_length; /* (06h) */ | ||
195 | /*2*/ u8 Reserved[2]; | ||
196 | /* SKSV, C/D, Reserved (2), BPV, BIT POINTER (3) */ | ||
197 | /*4*/ u8 sksv_cd_bpv_bp; | ||
198 | /*5*/ __be16 value; /* field-pointer/progress-value/retry-count/... */ | ||
199 | /*7*/ u8 Reserved2; | ||
200 | } __packed; | ||
201 | /*8*/ | ||
202 | |||
203 | /* 4.16.2.1 OSD error identification sense data descriptor - table 52 */ | ||
204 | /* Note: these bits are defined LE order for easy definition, this way the BIT() | ||
205 | * number is the same as in the documentation. Below members at | ||
206 | * osd_sense_identification_data_descriptor are therefore defined __le32. | ||
207 | */ | ||
208 | enum osd_command_functions_bits { | ||
209 | OSD_CFB_COMMAND = BIT(4), | ||
210 | OSD_CFB_CMD_CAP_VERIFIED = BIT(5), | ||
211 | OSD_CFB_VALIDATION = BIT(7), | ||
212 | OSD_CFB_IMP_ST_ATT = BIT(12), | ||
213 | OSD_CFB_SET_ATT = BIT(20), | ||
214 | OSD_CFB_SA_CAP_VERIFIED = BIT(21), | ||
215 | OSD_CFB_GET_ATT = BIT(28), | ||
216 | OSD_CFB_GA_CAP_VERIFIED = BIT(29), | ||
217 | }; | ||
218 | |||
219 | struct osd_sense_identification_data_descriptor { | ||
220 | /*0*/ u8 descriptor_type; /* (06h) */ | ||
221 | /*1*/ u8 additional_length; /* (1Eh) */ | ||
222 | /*2*/ u8 Reserved[6]; | ||
223 | /*8*/ __le32 not_initiated_functions; /*osd_command_functions_bits*/ | ||
224 | /*12*/ __le32 completed_functions; /*osd_command_functions_bits*/ | ||
225 | /*16*/ __be64 partition_id; | ||
226 | /*24*/ __be64 object_id; | ||
227 | } __packed; | ||
228 | /*32*/ | ||
229 | |||
230 | struct osd_sense_response_integrity_check_descriptor { | ||
231 | /*0*/ u8 descriptor_type; /* (07h) */ | ||
232 | /*1*/ u8 additional_length; /* (20h) */ | ||
233 | /*2*/ u8 integrity_check_value[32]; /*FIXME: OSDv2_CRYPTO_KEYID_SIZE*/ | ||
234 | } __packed; | ||
235 | /*34*/ | ||
236 | |||
237 | struct osd_sense_attributes_data_descriptor { | ||
238 | /*0*/ u8 descriptor_type; /* (08h) */ | ||
239 | /*1*/ u8 additional_length; /* (n-2) */ | ||
240 | /*2*/ u8 Reserved[6]; | ||
241 | struct osd_sense_attr { | ||
242 | /*8*/ __be32 attr_page; | ||
243 | /*12*/ __be32 attr_id; | ||
244 | /*16*/ } sense_attrs[0]; /* 1 or more */ | ||
245 | } __packed; | ||
246 | /*variable*/ | ||
247 | |||
248 | /* Dig into scsi_sk_illegal_request/scsi_invalid_field_in_cdb errors */ | ||
249 | |||
250 | /*FIXME: Support also field in CAPS*/ | ||
251 | #define OSD_CDB_OFFSET(F) offsetof(struct osd_cdb_head, F) | ||
252 | |||
253 | enum osdv2_cdb_field_offset { | ||
254 | OSDv1_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v1.start_address), | ||
255 | OSD_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v2.start_address), | ||
256 | OSD_CFO_PARTITION_ID = OSD_CDB_OFFSET(partition), | ||
257 | OSD_CFO_OBJECT_ID = OSD_CDB_OFFSET(object), | ||
258 | }; | ||
259 | |||
260 | #endif /* ndef __OSD_SENSE_H__ */ | ||
diff --git a/include/scsi/osd_types.h b/include/scsi/osd_types.h new file mode 100644 index 000000000000..3f5e88cc75c0 --- /dev/null +++ b/include/scsi/osd_types.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * osd_types.h - Types and constants which are not part of the protocol. | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <bharrosh@panasas.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | * Contains types and constants that are implementation specific and are | ||
14 | * used by more than one part of the osd library. | ||
15 | * (Eg initiator/target/security_manager/...) | ||
16 | */ | ||
17 | #ifndef __OSD_TYPES_H__ | ||
18 | #define __OSD_TYPES_H__ | ||
19 | |||
20 | struct osd_systemid { | ||
21 | u8 data[OSD_SYSTEMID_LEN]; | ||
22 | }; | ||
23 | |||
24 | typedef u64 __bitwise osd_id; | ||
25 | |||
26 | struct osd_obj_id { | ||
27 | osd_id partition; | ||
28 | osd_id id; | ||
29 | }; | ||
30 | |||
31 | static const struct __weak osd_obj_id osd_root_object = {0, 0}; | ||
32 | |||
33 | struct osd_attr { | ||
34 | u32 attr_page; | ||
35 | u32 attr_id; | ||
36 | u16 len; /* byte count of operand */ | ||
37 | void *val_ptr; /* in network order */ | ||
38 | }; | ||
39 | |||
40 | #endif /* ndef __OSD_TYPES_H__ */ | ||
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index a109165714d6..084478e14d24 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h | |||
@@ -9,7 +9,8 @@ | |||
9 | #define _SCSI_SCSI_H | 9 | #define _SCSI_SCSI_H |
10 | 10 | ||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <scsi/scsi_cmnd.h> | 12 | |
13 | struct scsi_cmnd; | ||
13 | 14 | ||
14 | /* | 15 | /* |
15 | * The maximum number of SG segments that we will put inside a | 16 | * The maximum number of SG segments that we will put inside a |
@@ -263,6 +264,7 @@ static inline int scsi_status_is_good(int status) | |||
263 | #define TYPE_RAID 0x0c | 264 | #define TYPE_RAID 0x0c |
264 | #define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ | 265 | #define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ |
265 | #define TYPE_RBC 0x0e | 266 | #define TYPE_RBC 0x0e |
267 | #define TYPE_OSD 0x11 | ||
266 | #define TYPE_NO_LUN 0x7f | 268 | #define TYPE_NO_LUN 0x7f |
267 | 269 | ||
268 | /* SCSI protocols; these are taken from SPC-3 section 7.5 */ | 270 | /* SCSI protocols; these are taken from SPC-3 section 7.5 */ |
@@ -402,16 +404,6 @@ static inline int scsi_is_wlun(unsigned int lun) | |||
402 | #define DRIVER_HARD 0x07 | 404 | #define DRIVER_HARD 0x07 |
403 | #define DRIVER_SENSE 0x08 | 405 | #define DRIVER_SENSE 0x08 |
404 | 406 | ||
405 | #define SUGGEST_RETRY 0x10 | ||
406 | #define SUGGEST_ABORT 0x20 | ||
407 | #define SUGGEST_REMAP 0x30 | ||
408 | #define SUGGEST_DIE 0x40 | ||
409 | #define SUGGEST_SENSE 0x80 | ||
410 | #define SUGGEST_IS_OK 0xff | ||
411 | |||
412 | #define DRIVER_MASK 0x0f | ||
413 | #define SUGGEST_MASK 0xf0 | ||
414 | |||
415 | /* | 407 | /* |
416 | * Internal return values. | 408 | * Internal return values. |
417 | */ | 409 | */ |
@@ -447,23 +439,6 @@ static inline int scsi_is_wlun(unsigned int lun) | |||
447 | #define msg_byte(result) (((result) >> 8) & 0xff) | 439 | #define msg_byte(result) (((result) >> 8) & 0xff) |
448 | #define host_byte(result) (((result) >> 16) & 0xff) | 440 | #define host_byte(result) (((result) >> 16) & 0xff) |
449 | #define driver_byte(result) (((result) >> 24) & 0xff) | 441 | #define driver_byte(result) (((result) >> 24) & 0xff) |
450 | #define suggestion(result) (driver_byte(result) & SUGGEST_MASK) | ||
451 | |||
452 | static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) | ||
453 | { | ||
454 | cmd->result |= status << 8; | ||
455 | } | ||
456 | |||
457 | static inline void set_host_byte(struct scsi_cmnd *cmd, char status) | ||
458 | { | ||
459 | cmd->result |= status << 16; | ||
460 | } | ||
461 | |||
462 | static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) | ||
463 | { | ||
464 | cmd->result |= status << 24; | ||
465 | } | ||
466 | |||
467 | 442 | ||
468 | #define sense_class(sense) (((sense) >> 4) & 0x7) | 443 | #define sense_class(sense) (((sense) >> 4) & 0x7) |
469 | #define sense_error(sense) ((sense) & 0xf) | 444 | #define sense_error(sense) ((sense) & 0xf) |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 855bf95963e7..43b50d36925c 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -291,4 +291,19 @@ static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd) | |||
291 | #define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \ | 291 | #define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \ |
292 | for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i) | 292 | for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i) |
293 | 293 | ||
294 | static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) | ||
295 | { | ||
296 | cmd->result |= status << 8; | ||
297 | } | ||
298 | |||
299 | static inline void set_host_byte(struct scsi_cmnd *cmd, char status) | ||
300 | { | ||
301 | cmd->result |= status << 16; | ||
302 | } | ||
303 | |||
304 | static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) | ||
305 | { | ||
306 | cmd->result |= status << 24; | ||
307 | } | ||
308 | |||
294 | #endif /* _SCSI_SCSI_CMND_H */ | 309 | #endif /* _SCSI_SCSI_CMND_H */ |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 01a4c58f8bad..3f566af3f101 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -340,6 +340,7 @@ extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, | |||
340 | struct scsi_sense_hdr *); | 340 | struct scsi_sense_hdr *); |
341 | extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, | 341 | extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, |
342 | int retries, struct scsi_sense_hdr *sshdr); | 342 | int retries, struct scsi_sense_hdr *sshdr); |
343 | extern unsigned char *scsi_get_vpd_page(struct scsi_device *, u8 page); | ||
343 | extern int scsi_device_set_state(struct scsi_device *sdev, | 344 | extern int scsi_device_set_state(struct scsi_device *sdev, |
344 | enum scsi_device_state state); | 345 | enum scsi_device_state state); |
345 | extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, | 346 | extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, |
@@ -370,12 +371,6 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, | |||
370 | int data_direction, void *buffer, unsigned bufflen, | 371 | int data_direction, void *buffer, unsigned bufflen, |
371 | struct scsi_sense_hdr *, int timeout, int retries, | 372 | struct scsi_sense_hdr *, int timeout, int retries, |
372 | int *resid); | 373 | int *resid); |
373 | extern int scsi_execute_async(struct scsi_device *sdev, | ||
374 | const unsigned char *cmd, int cmd_len, int data_direction, | ||
375 | void *buffer, unsigned bufflen, int use_sg, | ||
376 | int timeout, int retries, void *privdata, | ||
377 | void (*done)(void *, char *, int, int), | ||
378 | gfp_t gfp); | ||
379 | 374 | ||
380 | static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) | 375 | static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) |
381 | { | 376 | { |
@@ -400,7 +395,8 @@ static inline unsigned int sdev_id(struct scsi_device *sdev) | |||
400 | */ | 395 | */ |
401 | static inline int scsi_device_online(struct scsi_device *sdev) | 396 | static inline int scsi_device_online(struct scsi_device *sdev) |
402 | { | 397 | { |
403 | return sdev->sdev_state != SDEV_OFFLINE; | 398 | return (sdev->sdev_state != SDEV_OFFLINE && |
399 | sdev->sdev_state != SDEV_DEL); | ||
404 | } | 400 | } |
405 | static inline int scsi_device_blocked(struct scsi_device *sdev) | 401 | static inline int scsi_device_blocked(struct scsi_device *sdev) |
406 | { | 402 | { |
diff --git a/include/scsi/scsi_scan.h b/include/scsi/scsi_scan.h new file mode 100644 index 000000000000..78898889243d --- /dev/null +++ b/include/scsi/scsi_scan.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef _SCSI_SCSI_SCAN_H | ||
2 | #define _SCSI_SCSI_SCAN_H | ||
3 | |||
4 | #ifdef CONFIG_SCSI | ||
5 | /* drivers/scsi/scsi_scan.c */ | ||
6 | extern int scsi_complete_async_scans(void); | ||
7 | #else | ||
8 | static inline int scsi_complete_async_scans(void) { return 0; } | ||
9 | #endif | ||
10 | |||
11 | #endif /* _SCSI_SCSI_SCAN_H */ | ||
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index b50aabe2861e..457588e1119b 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
@@ -88,7 +88,7 @@ struct iscsi_transport { | |||
88 | uint64_t host_param_mask; | 88 | uint64_t host_param_mask; |
89 | struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep, | 89 | struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep, |
90 | uint16_t cmds_max, uint16_t qdepth, | 90 | uint16_t cmds_max, uint16_t qdepth, |
91 | uint32_t sn, uint32_t *hn); | 91 | uint32_t sn); |
92 | void (*destroy_session) (struct iscsi_cls_session *session); | 92 | void (*destroy_session) (struct iscsi_cls_session *session); |
93 | struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, | 93 | struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, |
94 | uint32_t cid); | 94 | uint32_t cid); |
@@ -206,8 +206,6 @@ struct iscsi_cls_session { | |||
206 | struct iscsi_cls_host { | 206 | struct iscsi_cls_host { |
207 | atomic_t nr_scans; | 207 | atomic_t nr_scans; |
208 | struct mutex mutex; | 208 | struct mutex mutex; |
209 | struct workqueue_struct *scan_workq; | ||
210 | char scan_workq_name[20]; | ||
211 | }; | 209 | }; |
212 | 210 | ||
213 | extern void iscsi_host_for_each_session(struct Scsi_Host *shost, | 211 | extern void iscsi_host_for_each_session(struct Scsi_Host *shost, |