aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-05-08 21:29:27 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-05-08 21:29:27 -0400
commitd585a021c0b10b0477d6b608c53e1feb8cde0507 (patch)
tree5ca059da1db7f15d4b29427644ad9c08270c885c /include/scsi
parent84e5b0d00f8f84c4ae226be131d4bebbcee88bd3 (diff)
parent091bf7624d1c90cec9e578a18529f615213ff847 (diff)
Merge commit 'v2.6.30-rc5' into next
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/fc/fc_fcoe.h11
-rw-r--r--include/scsi/fc/fc_fip.h237
-rw-r--r--include/scsi/fc/fc_fs.h6
-rw-r--r--include/scsi/fc_frame.h19
-rw-r--r--include/scsi/fc_transport_fcoe.h54
-rw-r--r--include/scsi/libfc.h213
-rw-r--r--include/scsi/libfcoe.h250
-rw-r--r--include/scsi/libiscsi.h21
-rw-r--r--include/scsi/osd_attributes.h327
-rw-r--r--include/scsi/osd_initiator.h433
-rw-r--r--include/scsi/osd_protocol.h625
-rw-r--r--include/scsi/osd_sec.h45
-rw-r--r--include/scsi/osd_sense.h260
-rw-r--r--include/scsi/osd_types.h40
-rw-r--r--include/scsi/scsi.h31
-rw-r--r--include/scsi/scsi_cmnd.h15
-rw-r--r--include/scsi/scsi_device.h10
-rw-r--r--include/scsi/scsi_scan.h11
-rw-r--r--include/scsi/scsi_transport_iscsi.h4
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
47struct 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 */
65enum 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 */
77enum 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 */
85enum 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 */
93enum 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 */
101enum 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 */
109enum 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 */
120struct fip_desc {
121 __u8 fip_dtype; /* type - see below */
122 __u8 fip_dlen; /* length - in 32-bit words */
123};
124
125enum 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 */
147struct 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 */
156struct 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 */
164struct 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 */
173struct 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 */
182struct 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 */
193struct 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 */
203struct 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 */
211struct 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 */
222struct 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 */
231struct 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 */
151enum fc_well_known_fid { 151enum 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
61struct fc_frame { 60struct 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
221static 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
228static 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 */
20struct 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 */
44int fcoe_transport_attach(struct net_device *netdev);
45int fcoe_transport_release(struct net_device *netdev);
46int fcoe_transport_register(struct fcoe_transport *t);
47int fcoe_transport_unregister(struct fcoe_transport *t);
48int fcoe_load_transport_driver(struct net_device *netdev);
49int __init fcoe_transport_init(void);
50int __exit fcoe_transport_exit(void);
51
52/* fcow_sw is the default transport */
53extern 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
74enum fc_lport_state { 72enum 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 *****************************/
275static 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
340struct libfc_function_template { 348struct 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 *****************************/
643static inline void *lport_priv(const struct fc_lport *lp)
644{
645 return (void *)(lp + 1);
646}
647
648static inline int fc_lport_test_ready(struct fc_lport *lp) 700static 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
723static 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
732static inline void fc_lport_free_stats(struct fc_lport *lp)
733{
734 free_percpu(lp->dev_stats);
735}
736
737static 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
742static 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 */
754static inline struct Scsi_Host *
755libfc_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 *****************************/
675int fc_lport_init(struct fc_lport *lp); 763int fc_lport_init(struct fc_lport *lp);
@@ -704,12 +792,6 @@ void fc_linkup(struct fc_lport *);
704void fc_linkdown(struct fc_lport *); 792void fc_linkdown(struct fc_lport *);
705 793
706/* 794/*
707 * Pause and unpause traffic.
708 */
709void fc_pause(struct fc_lport *);
710void fc_unpause(struct fc_lport *);
711
712/*
713 * Configure the local port. 795 * Configure the local port.
714 */ 796 */
715int fc_lport_config(struct fc_lport *); 797int fc_lport_config(struct fc_lport *);
@@ -725,19 +807,19 @@ int fc_lport_reset(struct fc_lport *);
725int fc_set_mfs(struct fc_lport *lp, u32 mfs); 807int 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 *****************************/
731int fc_rport_init(struct fc_lport *lp); 813int fc_rport_init(struct fc_lport *lp);
732void fc_rport_terminate_io(struct fc_rport *rp); 814void fc_rport_terminate_io(struct fc_rport *rp);
733 815
734/** 816/*
735 * DISCOVERY LAYER 817 * DISCOVERY LAYER
736 *****************************/ 818 *****************************/
737int fc_disc_init(struct fc_lport *lp); 819int 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 */
799void fc_fcp_destroy(struct fc_lport *); 881void fc_fcp_destroy(struct fc_lport *);
800 882
801/** 883/*
884 * Set up direct-data placement for this I/O request
885 */
886void 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 *);
807int fc_elsct_init(struct fc_lport *lp); 894int 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 */
919void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id); 1006void 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 */
31struct 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 */
47enum 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 */
42struct fcoe_softc { 87struct 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
61static inline struct fcoe_softc *fcoe_softc(
62 const struct fc_lport *lp)
63{
64 return (struct fcoe_softc *)lport_priv(lp);
65}
66
67static inline struct net_device *fcoe_netdev(
68 const struct fc_lport *lp)
69{
70 return fcoe_softc(lp)->real_dev;
71}
72
73static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb)
74{
75 return (struct fcoe_hdr *)skb_network_header(skb);
76}
77
78static inline int skb_fcoe_offset(const struct sk_buff *skb)
79{
80 return skb_network_offset(skb);
81}
82
83static 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
88static inline int skb_fc_offset(const struct sk_buff *skb)
89{
90 return skb_transport_offset(skb);
91}
92
93static 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
100static 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
105static 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
110static 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
117static 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
122static 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 */
136struct fcoe_fcf {
137 struct list_head list;
138 unsigned long time;
126 139
127static 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};
136static 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
143static inline bool skb_fc_is_write(const struct sk_buff *skb) 151/* FIP API functions */
144{ 152void fcoe_ctlr_init(struct fcoe_ctlr *);
145 if (skb_fc_is_cmd(skb) && skb_cmd(skb)) 153void fcoe_ctlr_destroy(struct fcoe_ctlr *);
146 return skb_dir(skb) == DMA_TO_DEVICE; 154void fcoe_ctlr_link_up(struct fcoe_ctlr *);
147 return false; 155int fcoe_ctlr_link_down(struct fcoe_ctlr *);
148} 156int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *);
157void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
158int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa);
149 159
150/* libfcoe funcs */ 160/* libfcoe funcs */
151int fcoe_reset(struct Scsi_Host *shost); 161u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
152u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
153 unsigned int scheme, unsigned int port);
154
155u32 fcoe_fc_crc(struct fc_frame *fp);
156int fcoe_xmit(struct fc_lport *, struct fc_frame *);
157int fcoe_rcv(struct sk_buff *, struct net_device *,
158 struct packet_type *, struct net_device *);
159
160int fcoe_percpu_receive_thread(void *arg);
161void fcoe_clean_pending_queue(struct fc_lport *lp);
162void fcoe_percpu_clean(struct fc_lport *lp);
163void fcoe_watchdog(ulong vp);
164int fcoe_link_ok(struct fc_lport *lp);
165
166struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
167int fcoe_hostlist_add(const struct fc_lport *);
168int fcoe_hostlist_remove(const struct fc_lport *);
169
170struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int);
171int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); 162int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *);
172 163
173/* fcoe sw hba */
174int __init fcoe_sw_init(void);
175int __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;
36struct scsi_host_template; 36struct scsi_host_template;
37struct scsi_device; 37struct scsi_device;
38struct Scsi_Host; 38struct Scsi_Host;
39struct scsi_target;
39struct scsi_cmnd; 40struct scsi_cmnd;
40struct socket; 41struct socket;
41struct iscsi_transport; 42struct iscsi_transport;
@@ -45,18 +46,10 @@ struct iscsi_session;
45struct iscsi_nopin; 46struct iscsi_nopin;
46struct device; 47struct 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 */
62enum { 55enum {
@@ -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);
352extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); 348extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
353extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, 349extern 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);
355extern void iscsi_host_remove(struct Scsi_Host *shost); 352extern void iscsi_host_remove(struct Scsi_Host *shost);
356extern void iscsi_host_free(struct Scsi_Host *shost); 353extern void iscsi_host_free(struct Scsi_Host *shost);
354extern 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);
382extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, 380extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
383 int); 381 int);
384extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); 382extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
385extern void iscsi_session_failure(struct iscsi_cls_session *cls_session, 383extern void iscsi_session_failure(struct iscsi_session *session,
386 enum iscsi_err err); 384 enum iscsi_err err);
387extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, 385extern 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);
389extern void iscsi_suspend_tx(struct iscsi_conn *conn); 387extern void iscsi_suspend_tx(struct iscsi_conn *conn);
388extern 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 */
17enum {
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 */
60enum {
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
86enum {
87 OSD_ATTR_PAGE_IDENTIFICATION = 0, /* in all pages 40 bytes */
88};
89
90struct page_identification {
91 u8 vendor_identification[8];
92 u8 page_identification[32];
93} __packed;
94
95struct 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) */
101enum {
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 */
119enum {
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 */
130enum {
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 */
141enum {
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) */
151enum {
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
159struct 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)*/
169enum {
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
176struct 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) */
185enum {
186 OSD_ATTR_OQ_MAXIMUM_LENGTH = 0x1, /* 8 */
187};
188
189struct 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) */
195enum {
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
201struct 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 */
211enum {
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
220struct 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 */
233enum {
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 */
242struct 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) */
255enum {
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
268struct 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 */
286enum {
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
299struct 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 */
318enum {
319 OSD_ATTR_OS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */
320};
321
322struct 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
35enum 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 */
48struct 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 */
58struct osd_dev *osduld_path_lookup(const char *dev_name); /*Use IS_ERR/ERR_PTR*/
59void osduld_put_device(struct osd_dev *od);
60
61/* Add/remove test ioctls from external modules */
62typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg);
63int osduld_register_test(unsigned ioctl, do_test_fn *do_test);
64void osduld_unregister_test(unsigned ioctl);
65
66/* These are called by uld at probe time */
67void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
68void osd_dev_fini(struct osd_dev *od);
69
70/* some hi level device operations */
71int osd_auto_detect_ver(struct osd_dev *od, void *caps); /* GFP_KERNEL */
72
73/* we might want to use function vector in the future */
74static 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
81struct osd_request;
82typedef void (osd_req_done_fn)(struct osd_request *or, void *private);
83
84struct 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 */
118static 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 */
170struct osd_request *osd_start_request(struct osd_dev *od, gfp_t gfp);
171
172enum 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 */
193int 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 */
203int 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 */
216int 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 */
240struct 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
257int 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
262static 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 */
275void 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 */
286void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */
287void osd_req_set_master_key(struct osd_request *or, ...);/* NI */
288
289void 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 */
296int osd_req_list_dev_partitions(struct osd_request *or,
297 osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem);
298
299void osd_req_flush_obsd(struct osd_request *or,
300 enum osd_options_flush_scope_values);
301
302void osd_req_perform_scsi_command(struct osd_request *or,
303 const u8 *cdb, ...);/* NI */
304void osd_req_task_management(struct osd_request *or, ...);/* NI */
305
306/*
307 * Partition commands
308 */
309void osd_req_create_partition(struct osd_request *or, osd_id partition);
310void osd_req_remove_partition(struct osd_request *or, osd_id partition);
311
312void 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 */
321int 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 */
330int 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
334void osd_req_flush_partition(struct osd_request *or,
335 osd_id partition, enum osd_options_flush_scope_values);
336
337/*
338 * Collection commands
339 */
340void osd_req_create_collection(struct osd_request *or,
341 const struct osd_obj_id *);/* NI */
342void osd_req_remove_collection(struct osd_request *or,
343 const struct osd_obj_id *);/* NI */
344
345/* list all objects in the collection */
346int 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 */
351void osd_req_query(struct osd_request *or, ...);/* NI */
352
353void osd_req_flush_collection(struct osd_request *or,
354 const struct osd_obj_id *, enum osd_options_flush_scope_values);
355
356void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */
357void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */
358
359/*
360 * Object commands
361 */
362void osd_req_create_object(struct osd_request *or, struct osd_obj_id *);
363void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *);
364
365void osd_req_write(struct osd_request *or,
366 const struct osd_obj_id *, struct bio *data_out, u64 offset);
367void osd_req_append(struct osd_request *or,
368 const struct osd_obj_id *, struct bio *data_out);/* NI */
369void osd_req_create_write(struct osd_request *or,
370 const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */
371void osd_req_clear(struct osd_request *or,
372 const struct osd_obj_id *, u64 offset, u64 len);/* NI */
373void osd_req_punch(struct osd_request *or,
374 const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */
375
376void 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
380void 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 */
388void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *);
389
390/* set before get */
391void 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. */
404int osd_req_add_set_attr_list(struct osd_request *or,
405 const struct osd_attr *, unsigned nelem);
406
407/* get a list of attributes */
408int 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 */
417int 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 */
429int 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
23enum {
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 */
50enum 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 */
60enum 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 */
72enum 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 */
82enum {
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 */
91enum 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 */
109typedef __be32 __bitwise osd_cdb_offset;
110
111enum {
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 */
125osd_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 */
132static 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 */
142static 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 */
149struct 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*/
212struct 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*/
221struct 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
229struct osd_security_parameters {
230 union {
231 struct osdv1_security_parameters v1;
232 struct osdv2_security_parameters v2;
233 };
234};
235
236struct osdv1_cdb {
237 struct osd_cdb_head h;
238 u8 caps[OSDv1_CAP_LEN];
239 struct osdv1_security_parameters sec_params;
240} __packed;
241
242struct osdv2_cdb {
243 struct osd_cdb_head h;
244 u8 caps[OSD_CAP_LEN];
245 struct osdv2_security_parameters sec_params;
246} __packed;
247
248struct 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
256static 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
276enum 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 */
314struct osd_attributes_list_attrid {
315 __be32 attr_page;
316 __be32 attr_id;
317} __packed;
318
319/*
320 * NOTE: v1: is not aligned.
321 */
322struct 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 */
334struct 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
342enum {
343 OSDv1_ATTRIBUTES_ELEM_ALIGN = 1,
344 OSD_ATTRIBUTES_ELEM_ALIGN = 8,
345};
346
347enum {
348 OSD_ATTR_LIST_ALL_PAGES = 0xFFFFFFFF,
349 OSD_ATTR_LIST_ALL_IN_PAGE = 0xFFFFFFFF,
350};
351
352static 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
358static 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 */
367enum 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 */
375struct 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
383struct 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
393static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h)
394{
395 return be16_to_cpu(h->list_bytes);
396}
397
398struct 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
408static 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 */
417enum {
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 */
426struct 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
435static 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 */
445struct 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 */
456static 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
462struct 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 */
472static 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
478struct 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
489struct 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 */
494enum {
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 */
501enum {
502 OSD_SEC_NOSEC = 0,
503 OSD_SEC_CAPKEY = 1,
504 OSD_SEC_CMDRSP = 2,
505 OSD_SEC_ALLDATA = 3,
506};
507
508enum 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
515enum 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) */
536enum {
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 */
546struct 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*/
562struct 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*/
577struct 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
595struct osdv1_capability {
596 struct osd_capability_head h;
597 struct osdv1_cap_object_descriptor od;
598} __packed;
599
600struct 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 */
614static 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 */
28void osd_sec_encode_caps(void *caps, ...);/* NI */
29void osd_sec_init_nosec_doall_caps(void *caps,
30 const struct osd_obj_id *obj, bool is_collection, const bool is_v1);
31
32bool 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 */
36void 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. */
40void osd_sec_sign_data(void *data_integ, struct bio *bio, const u8 *cap_key);
41
42/* Version independent copy of caps into the cdb */
43void 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 */
22enum 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 */
44enum 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
144enum 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
162struct 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 */
169struct 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 */
184struct 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
192struct 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 */
208enum 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
219struct 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
230struct 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
237struct 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
253enum 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
20struct osd_systemid {
21 u8 data[OSD_SYSTEMID_LEN];
22};
23
24typedef u64 __bitwise osd_id;
25
26struct osd_obj_id {
27 osd_id partition;
28 osd_id id;
29};
30
31static const struct __weak osd_obj_id osd_root_object = {0, 0};
32
33struct 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
13struct 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
452static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
453{
454 cmd->result |= status << 8;
455}
456
457static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
458{
459 cmd->result |= status << 16;
460}
461
462static 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
294static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
295{
296 cmd->result |= status << 8;
297}
298
299static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
300{
301 cmd->result |= status << 16;
302}
303
304static 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 *);
341extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, 341extern 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);
343extern unsigned char *scsi_get_vpd_page(struct scsi_device *, u8 page);
343extern int scsi_device_set_state(struct scsi_device *sdev, 344extern int scsi_device_set_state(struct scsi_device *sdev,
344 enum scsi_device_state state); 345 enum scsi_device_state state);
345extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, 346extern 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);
373extern 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
380static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) 375static 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 */
401static inline int scsi_device_online(struct scsi_device *sdev) 396static 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}
405static inline int scsi_device_blocked(struct scsi_device *sdev) 401static 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 */
6extern int scsi_complete_async_scans(void);
7#else
8static 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 {
206struct iscsi_cls_host { 206struct 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
213extern void iscsi_host_for_each_session(struct Scsi_Host *shost, 211extern void iscsi_host_for_each_session(struct Scsi_Host *shost,