summaryrefslogtreecommitdiff
path: root/include/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/fc/fc_encaps.h14
-rw-r--r--include/scsi/fc/fc_fc2.h14
-rw-r--r--include/scsi/fc/fc_fcoe.h14
-rw-r--r--include/scsi/fc/fc_fcp.h14
-rw-r--r--include/scsi/fc/fc_fip.h14
-rw-r--r--include/scsi/fc/fc_ms.h76
-rw-r--r--include/scsi/fc_encode.h739
-rw-r--r--include/scsi/fc_frame.h44
-rw-r--r--include/scsi/fcoe_sysfs.h16
-rw-r--r--include/scsi/iscsi_if.h24
-rw-r--r--include/scsi/iscsi_proto.h15
-rw-r--r--include/scsi/iser.h2
-rw-r--r--include/scsi/libfc.h103
-rw-r--r--include/scsi/libfcoe.h59
-rw-r--r--include/scsi/libiscsi.h79
-rw-r--r--include/scsi/libiscsi_tcp.h29
-rw-r--r--include/scsi/libsas.h269
-rw-r--r--include/scsi/osd_attributes.h398
-rw-r--r--include/scsi/osd_initiator.h511
-rw-r--r--include/scsi/osd_ore.h201
-rw-r--r--include/scsi/osd_protocol.h676
-rw-r--r--include/scsi/osd_sec.h45
-rw-r--r--include/scsi/osd_sense.h263
-rw-r--r--include/scsi/osd_types.h45
-rw-r--r--include/scsi/sas.h86
-rw-r--r--include/scsi/sas_ata.h88
-rw-r--r--include/scsi/scsi.h188
-rw-r--r--include/scsi/scsi_bsg_iscsi.h22
-rw-r--r--include/scsi/scsi_cmnd.h181
-rw-r--r--include/scsi/scsi_common.h20
-rw-r--r--include/scsi/scsi_dbg.h13
-rw-r--r--include/scsi/scsi_device.h252
-rw-r--r--include/scsi/scsi_devinfo.h14
-rw-r--r--include/scsi/scsi_dh.h20
-rw-r--r--include/scsi/scsi_driver.h14
-rw-r--r--include/scsi/scsi_eh.h8
-rw-r--r--include/scsi/scsi_host.h316
-rw-r--r--include/scsi/scsi_ioctl.h10
-rw-r--r--include/scsi/scsi_proto.h166
-rw-r--r--include/scsi/scsi_request.h33
-rw-r--r--include/scsi/scsi_status.h74
-rw-r--r--include/scsi/scsi_tcq.h2
-rw-r--r--include/scsi/scsi_transport.h17
-rw-r--r--include/scsi/scsi_transport_fc.h126
-rw-r--r--include/scsi/scsi_transport_iscsi.h76
-rw-r--r--include/scsi/scsi_transport_sas.h3
-rw-r--r--include/scsi/scsi_transport_spi.h15
-rw-r--r--include/scsi/scsi_transport_srp.h6
-rw-r--r--include/scsi/scsicam.h8
-rw-r--r--include/scsi/sg.h71
-rw-r--r--include/scsi/srp.h32
-rw-r--r--include/scsi/viosrp.h27
52 files changed, 1528 insertions, 4024 deletions
diff --git a/include/scsi/fc/fc_encaps.h b/include/scsi/fc/fc_encaps.h
index f180c3e16220..4261e609cae6 100644
--- a/include/scsi/fc/fc_encaps.h
+++ b/include/scsi/fc/fc_encaps.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
#ifndef _FC_ENCAPS_H_
diff --git a/include/scsi/fc/fc_fc2.h b/include/scsi/fc/fc_fc2.h
index 0b2671431305..0ffd314ebfaa 100644
--- a/include/scsi/fc/fc_fc2.h
+++ b/include/scsi/fc/fc_fc2.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h
index d5dcd6062815..d8c921c856cf 100644
--- a/include/scsi/fc/fc_fcoe.h
+++ b/include/scsi/fc/fc_fcoe.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
index 9c8702942b61..4b968448f424 100644
--- a/include/scsi/fc/fc_fcp.h
+++ b/include/scsi/fc/fc_fcp.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h
index 9710254fd98c..e0a3423ba09e 100644
--- a/include/scsi/fc/fc_fip.h
+++ b/include/scsi/fc/fc_fip.h
@@ -1,18 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
- *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
*/
#ifndef _FC_FIP_H_
#define _FC_FIP_H_
diff --git a/include/scsi/fc/fc_ms.h b/include/scsi/fc/fc_ms.h
index f52b921b5c70..56a5d2b5a624 100644
--- a/include/scsi/fc/fc_ms.h
+++ b/include/scsi/fc/fc_ms.h
@@ -1,17 +1,6 @@
-/* * Copyright(c) 2011 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright(c) 2011 Intel Corporation. All rights reserved.
*
* Maintained at www.Open-FCoE.org
*/
@@ -36,6 +25,12 @@
#define FC_FDMI_SUBTYPE 0x10 /* fs_ct_hdr.ct_fs_subtype */
/*
+ * Management server FDMI specifications.
+ */
+#define FDMI_V1 1 /* FDMI version 1 specifications */
+#define FDMI_V2 2 /* FDMI version 2 specifications */
+
+/*
* Management server FDMI Requests.
*/
enum fc_fdmi_req {
@@ -68,6 +63,13 @@ enum fc_fdmi_hba_attr_type {
FC_FDMI_HBA_ATTR_FIRMWAREVERSION = 0x0009,
FC_FDMI_HBA_ATTR_OSNAMEVERSION = 0x000A,
FC_FDMI_HBA_ATTR_MAXCTPAYLOAD = 0x000B,
+ FC_FDMI_HBA_ATTR_NODESYMBLNAME = 0x000C,
+ FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO = 0x000D,
+ FC_FDMI_HBA_ATTR_NUMBEROFPORTS = 0x000E,
+ FC_FDMI_HBA_ATTR_FABRICNAME = 0x000F,
+ FC_FDMI_HBA_ATTR_BIOSVERSION = 0x0010,
+ FC_FDMI_HBA_ATTR_BIOSSTATE = 0x0011,
+ FC_FDMI_HBA_ATTR_VENDORIDENTIFIER = 0x00E0,
};
/*
@@ -76,14 +78,21 @@ enum fc_fdmi_hba_attr_type {
#define FC_FDMI_HBA_ATTR_NODENAME_LEN 8
#define FC_FDMI_HBA_ATTR_MANUFACTURER_LEN 64
#define FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN 64
-#define FC_FDMI_HBA_ATTR_MODEL_LEN 256
-#define FC_FDMI_HBA_ATTR_MODELDESCR_LEN 256
-#define FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN 256
-#define FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN 256
-#define FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN 256
-#define FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN 256
-#define FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN 256
+#define FC_FDMI_HBA_ATTR_MODEL_LEN 64
+#define FC_FDMI_HBA_ATTR_MODELDESCR_LEN 64
+#define FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN 64
+#define FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN 64
+#define FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN 64
+#define FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN 64
+#define FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN 128
#define FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN 4
+#define FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN 64
+#define FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN 4
+#define FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN 4
+#define FC_FDMI_HBA_ATTR_FABRICNAME_LEN 8
+#define FC_FDMI_HBA_ATTR_BIOSVERSION_LEN 64
+#define FC_FDMI_HBA_ATTR_BIOSSTATE_LEN 4
+#define FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN 8
/*
* Port Attribute Type
@@ -95,6 +104,16 @@ enum fc_fdmi_port_attr_type {
FC_FDMI_PORT_ATTR_MAXFRAMESIZE = 0x0004,
FC_FDMI_PORT_ATTR_OSDEVICENAME = 0x0005,
FC_FDMI_PORT_ATTR_HOSTNAME = 0x0006,
+ FC_FDMI_PORT_ATTR_NODENAME = 0x0007,
+ FC_FDMI_PORT_ATTR_PORTNAME = 0x0008,
+ FC_FDMI_PORT_ATTR_SYMBOLICNAME = 0x0009,
+ FC_FDMI_PORT_ATTR_PORTTYPE = 0x000A,
+ FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC = 0x000B,
+ FC_FDMI_PORT_ATTR_FABRICNAME = 0x000C,
+ FC_FDMI_PORT_ATTR_CURRENTFC4TYPE = 0x000D,
+ FC_FDMI_PORT_ATTR_PORTSTATE = 0x101,
+ FC_FDMI_PORT_ATTR_DISCOVEREDPORTS = 0x102,
+ FC_FDMI_PORT_ATTR_PORTID = 0x103,
};
/*
@@ -106,6 +125,17 @@ enum fc_fdmi_port_attr_type {
#define FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN 4
#define FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN 256
#define FC_FDMI_PORT_ATTR_HOSTNAME_LEN 256
+#define FC_FDMI_PORT_ATTR_NODENAME_LEN 8
+#define FC_FDMI_PORT_ATTR_PORTNAME_LEN 8
+#define FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN 256
+#define FC_FDMI_PORT_ATTR_PORTTYPE_LEN 4
+#define FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN 4
+#define FC_FDMI_PORT_ATTR_FABRICNAME_LEN 8
+#define FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN 32
+#define FC_FDMI_PORT_ATTR_PORTSTATE_LEN 4
+#define FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN 4
+#define FC_FDMI_PORT_ATTR_PORTID_LEN 4
+
/*
* HBA Attribute ID
@@ -128,7 +158,7 @@ struct fc_fdmi_port_name {
struct fc_fdmi_attr_entry {
__be16 type;
__be16 len;
- __u8 value[1];
+ __u8 value[];
} __attribute__((__packed__));
/*
@@ -136,7 +166,7 @@ struct fc_fdmi_attr_entry {
*/
struct fs_fdmi_attrs {
__be32 numattrs;
- struct fc_fdmi_attr_entry attr[1];
+ struct fc_fdmi_attr_entry attr[];
} __attribute__((__packed__));
/*
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
deleted file mode 100644
index 35fd4744f3e9..000000000000
--- a/include/scsi/fc_encode.h
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#ifndef _FC_ENCODE_H_
-#define _FC_ENCODE_H_
-#include <asm/unaligned.h>
-#include <linux/utsname.h>
-
-/*
- * F_CTL values for simple requests and responses.
- */
-#define FC_FCTL_REQ (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)
-#define FC_FCTL_RESP (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \
- FC_FC_END_SEQ | FC_FC_SEQ_INIT)
-
-struct fc_ns_rft {
- struct fc_ns_fid fid; /* port ID object */
- struct fc_ns_fts fts; /* FC4-types object */
-};
-
-struct fc_ct_req {
- struct fc_ct_hdr hdr;
- union {
- struct fc_ns_gid_ft gid;
- struct fc_ns_rn_id rn;
- struct fc_ns_rft rft;
- struct fc_ns_rff_id rff;
- struct fc_ns_fid fid;
- struct fc_ns_rsnn snn;
- struct fc_ns_rspn spn;
- struct fc_fdmi_rhba rhba;
- struct fc_fdmi_rpa rpa;
- struct fc_fdmi_dprt dprt;
- struct fc_fdmi_dhba dhba;
- } payload;
-};
-
-static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh,
- enum fc_rctl r_ctl,
- u32 did, u32 sid, enum fc_fh_type type,
- u32 f_ctl, u32 parm_offset)
-{
- WARN_ON(r_ctl == 0);
- fh->fh_r_ctl = r_ctl;
- hton24(fh->fh_d_id, did);
- hton24(fh->fh_s_id, sid);
- fh->fh_type = type;
- hton24(fh->fh_f_ctl, f_ctl);
- fh->fh_cs_ctl = 0;
- fh->fh_df_ctl = 0;
- fh->fh_parm_offset = htonl(parm_offset);
-}
-
-/**
- * fill FC header fields in specified fc_frame
- */
-static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
- u32 did, u32 sid, enum fc_fh_type type,
- u32 f_ctl, u32 parm_offset)
-{
- struct fc_frame_header *fh;
-
- fh = fc_frame_header_get(fp);
- __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset);
-}
-
-/**
- * fc_adisc_fill() - Fill in adisc request frame
- * @lport: local port.
- * @fp: fc frame where payload will be placed.
- */
-static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_adisc *adisc;
-
- adisc = fc_frame_payload_get(fp, sizeof(*adisc));
- memset(adisc, 0, sizeof(*adisc));
- adisc->adisc_cmd = ELS_ADISC;
- put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
- put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
- hton24(adisc->adisc_port_id, lport->port_id);
-}
-
-/**
- * fc_ct_hdr_fill- fills ct header and reset ct payload
- * returns pointer to ct request.
- */
-static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
- unsigned int op, size_t req_size,
- enum fc_ct_fs_type fs_type,
- u8 subtype)
-{
- struct fc_ct_req *ct;
- size_t ct_plen;
-
- ct_plen = sizeof(struct fc_ct_hdr) + req_size;
- ct = fc_frame_payload_get(fp, ct_plen);
- memset(ct, 0, ct_plen);
- ct->hdr.ct_rev = FC_CT_REV;
- ct->hdr.ct_fs_type = fs_type;
- ct->hdr.ct_fs_subtype = subtype;
- ct->hdr.ct_cmd = htons((u16) op);
- return ct;
-}
-
-/**
- * fc_ct_ns_fill() - Fill in a name service request frame
- * @lport: local port.
- * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
- * @fp: frame to contain payload.
- * @op: CT opcode.
- * @r_ctl: pointer to FC header R_CTL.
- * @fh_type: pointer to FC-4 type.
- */
-static inline int fc_ct_ns_fill(struct fc_lport *lport,
- u32 fc_id, struct fc_frame *fp,
- unsigned int op, enum fc_rctl *r_ctl,
- enum fc_fh_type *fh_type)
-{
- struct fc_ct_req *ct;
- size_t len;
-
- switch (op) {
- case FC_NS_GPN_FT:
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
- FC_FST_DIR, FC_NS_SUBTYPE);
- ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
- break;
-
- case FC_NS_GPN_ID:
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
- FC_FST_DIR, FC_NS_SUBTYPE);
- ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
- hton24(ct->payload.fid.fp_fid, fc_id);
- break;
-
- case FC_NS_RFT_ID:
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
- FC_FST_DIR, FC_NS_SUBTYPE);
- hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
- ct->payload.rft.fts = lport->fcts;
- break;
-
- case FC_NS_RFF_ID:
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
- FC_FST_DIR, FC_NS_SUBTYPE);
- hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
- ct->payload.rff.fr_type = FC_TYPE_FCP;
- if (lport->service_params & FCP_SPPF_INIT_FCN)
- ct->payload.rff.fr_feat = FCP_FEAT_INIT;
- if (lport->service_params & FCP_SPPF_TARG_FCN)
- ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
- break;
-
- case FC_NS_RNN_ID:
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
- FC_FST_DIR, FC_NS_SUBTYPE);
- hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
- put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
- break;
-
- case FC_NS_RSPN_ID:
- len = strnlen(fc_host_symbolic_name(lport->host), 255);
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
- FC_FST_DIR, FC_NS_SUBTYPE);
- hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
- strncpy(ct->payload.spn.fr_name,
- fc_host_symbolic_name(lport->host), len);
- ct->payload.spn.fr_name_len = len;
- break;
-
- case FC_NS_RSNN_NN:
- len = strnlen(fc_host_symbolic_name(lport->host), 255);
- ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
- FC_FST_DIR, FC_NS_SUBTYPE);
- put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
- strncpy(ct->payload.snn.fr_name,
- fc_host_symbolic_name(lport->host), len);
- ct->payload.snn.fr_name_len = len;
- break;
-
- default:
- return -EINVAL;
- }
- *r_ctl = FC_RCTL_DD_UNSOL_CTL;
- *fh_type = FC_TYPE_CT;
- return 0;
-}
-
-/**
- * fc_ct_ms_fill() - Fill in a mgmt service request frame
- * @lport: local port.
- * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
- * @fp: frame to contain payload.
- * @op: CT opcode.
- * @r_ctl: pointer to FC header R_CTL.
- * @fh_type: pointer to FC-4 type.
- */
-static inline int fc_ct_ms_fill(struct fc_lport *lport,
- u32 fc_id, struct fc_frame *fp,
- unsigned int op, enum fc_rctl *r_ctl,
- enum fc_fh_type *fh_type)
-{
- struct fc_ct_req *ct;
- size_t len;
- struct fc_fdmi_attr_entry *entry;
- struct fs_fdmi_attrs *hba_attrs;
- int numattrs = 0;
-
- switch (op) {
- case FC_FDMI_RHBA:
- numattrs = 10;
- len = sizeof(struct fc_fdmi_rhba);
- len -= sizeof(struct fc_fdmi_attr_entry);
- len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
- len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
- len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
- len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
- len += FC_FDMI_HBA_ATTR_MODEL_LEN;
- len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
- len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
- len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
- len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
- len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
- len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
- ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
- FC_FDMI_SUBTYPE);
-
- /* HBA Identifier */
- put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id);
- /* Number of Ports - always 1 */
- put_unaligned_be32(1, &ct->payload.rhba.port.numport);
- /* Port Name */
- put_unaligned_be64(lport->wwpn,
- &ct->payload.rhba.port.port[0].portname);
-
- /* HBA Attributes */
- put_unaligned_be32(numattrs,
- &ct->payload.rhba.hba_attrs.numattrs);
- hba_attrs = &ct->payload.rhba.hba_attrs;
- entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
- /* NodeName*/
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- put_unaligned_be64(lport->wwnn,
- (__be64 *)&entry->value[0]);
-
- /* Manufacturer */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_NODENAME_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_manufacturer(lport->host),
- FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
-
- /* SerialNumber */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_serial_number(lport->host),
- FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
-
- /* Model */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_MODEL_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_model(lport->host),
- FC_FDMI_HBA_ATTR_MODEL_LEN);
-
- /* Model Description */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_MODEL_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_model_description(lport->host),
- FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
-
- /* Hardware Version */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_hardware_version(lport->host),
- FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
-
- /* Driver Version */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_driver_version(lport->host),
- FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
-
- /* OptionROM Version */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_optionrom_version(lport->host),
- FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
-
- /* Firmware Version */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- strncpy((char *)&entry->value,
- fc_host_firmware_version(lport->host),
- FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
-
- /* OS Name and Version */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
- put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- snprintf((char *)&entry->value,
- FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN,
- "%s v%s",
- init_utsname()->sysname,
- init_utsname()->release);
- break;
- case FC_FDMI_RPA:
- numattrs = 6;
- len = sizeof(struct fc_fdmi_rpa);
- len -= sizeof(struct fc_fdmi_attr_entry);
- len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
- len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
- len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
- len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
- len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
- len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
- len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
- ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
- FC_FDMI_SUBTYPE);
-
- /* Port Name */
- put_unaligned_be64(lport->wwpn,
- &ct->payload.rpa.port.portname);
-
- /* Port Attributes */
- put_unaligned_be32(numattrs,
- &ct->payload.rpa.hba_attrs.numattrs);
-
- hba_attrs = &ct->payload.rpa.hba_attrs;
- entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
-
- /* FC4 types */
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
- put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- memcpy(&entry->value, fc_host_supported_fc4s(lport->host),
- FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
-
- /* Supported Speed */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
- put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
-
- put_unaligned_be32(fc_host_supported_speeds(lport->host),
- &entry->value);
-
- /* Current Port Speed */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
- put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- put_unaligned_be32(lport->link_speed,
- &entry->value);
-
- /* Max Frame Size */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
- put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- put_unaligned_be32(fc_host_maxframe_size(lport->host),
- &entry->value);
-
- /* OS Device Name */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
- put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- /* Use the sysfs device name */
- strncpy((char *)&entry->value,
- dev_name(&lport->host->shost_gendev),
- strnlen(dev_name(&lport->host->shost_gendev),
- FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
-
- /* Host Name */
- entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
- FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN);
- len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
- len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
- put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME,
- &entry->type);
- put_unaligned_be16(len, &entry->len);
- if (strlen(fc_host_system_hostname(lport->host)))
- strncpy((char *)&entry->value,
- fc_host_system_hostname(lport->host),
- strnlen(fc_host_system_hostname(lport->host),
- FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
- else
- strncpy((char *)&entry->value,
- init_utsname()->nodename,
- FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
- break;
- case FC_FDMI_DPRT:
- len = sizeof(struct fc_fdmi_dprt);
- ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
- FC_FDMI_SUBTYPE);
- /* Port Name */
- put_unaligned_be64(lport->wwpn,
- &ct->payload.dprt.port.portname);
- break;
- case FC_FDMI_DHBA:
- len = sizeof(struct fc_fdmi_dhba);
- ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
- FC_FDMI_SUBTYPE);
- /* HBA Identifier */
- put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id);
- break;
- default:
- return -EINVAL;
- }
- *r_ctl = FC_RCTL_DD_UNSOL_CTL;
- *fh_type = FC_TYPE_CT;
- return 0;
-}
-
-/**
- * fc_ct_fill() - Fill in a common transport service request frame
- * @lport: local port.
- * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
- * @fp: frame to contain payload.
- * @op: CT opcode.
- * @r_ctl: pointer to FC header R_CTL.
- * @fh_type: pointer to FC-4 type.
- */
-static inline int fc_ct_fill(struct fc_lport *lport,
- u32 fc_id, struct fc_frame *fp,
- unsigned int op, enum fc_rctl *r_ctl,
- enum fc_fh_type *fh_type, u32 *did)
-{
- int rc = -EINVAL;
-
- switch (fc_id) {
- case FC_FID_MGMT_SERV:
- rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type);
- *did = FC_FID_MGMT_SERV;
- break;
- case FC_FID_DIR_SERV:
- default:
- rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
- *did = FC_FID_DIR_SERV;
- break;
- }
-
- return rc;
-}
-/**
- * fc_plogi_fill - Fill in plogi request frame
- */
-static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
- unsigned int op)
-{
- struct fc_els_flogi *plogi;
- struct fc_els_csp *csp;
- struct fc_els_cssp *cp;
-
- plogi = fc_frame_payload_get(fp, sizeof(*plogi));
- memset(plogi, 0, sizeof(*plogi));
- plogi->fl_cmd = (u8) op;
- put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
- put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
-
- csp = &plogi->fl_csp;
- csp->sp_hi_ver = 0x20;
- csp->sp_lo_ver = 0x20;
- csp->sp_bb_cred = htons(10); /* this gets set by gateway */
- csp->sp_bb_data = htons((u16) lport->mfs);
- cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */
- cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
- csp->sp_features = htons(FC_SP_FT_CIRO);
- csp->sp_tot_seq = htons(255); /* seq. we accept */
- csp->sp_rel_off = htons(0x1f);
- csp->sp_e_d_tov = htonl(lport->e_d_tov);
-
- cp->cp_rdfs = htons((u16) lport->mfs);
- cp->cp_con_seq = htons(255);
- cp->cp_open_seq = 1;
-}
-
-/**
- * fc_flogi_fill - Fill in a flogi request frame.
- */
-static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_csp *sp;
- struct fc_els_cssp *cp;
- struct fc_els_flogi *flogi;
-
- flogi = fc_frame_payload_get(fp, sizeof(*flogi));
- memset(flogi, 0, sizeof(*flogi));
- flogi->fl_cmd = (u8) ELS_FLOGI;
- put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
- put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
- sp = &flogi->fl_csp;
- sp->sp_hi_ver = 0x20;
- sp->sp_lo_ver = 0x20;
- sp->sp_bb_cred = htons(10); /* this gets set by gateway */
- sp->sp_bb_data = htons((u16) lport->mfs);
- cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
- cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
- if (lport->does_npiv)
- sp->sp_features = htons(FC_SP_FT_NPIV);
-}
-
-/**
- * fc_fdisc_fill - Fill in a fdisc request frame.
- */
-static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_csp *sp;
- struct fc_els_cssp *cp;
- struct fc_els_flogi *fdisc;
-
- fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
- memset(fdisc, 0, sizeof(*fdisc));
- fdisc->fl_cmd = (u8) ELS_FDISC;
- put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
- put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
- sp = &fdisc->fl_csp;
- sp->sp_hi_ver = 0x20;
- sp->sp_lo_ver = 0x20;
- sp->sp_bb_cred = htons(10); /* this gets set by gateway */
- sp->sp_bb_data = htons((u16) lport->mfs);
- cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */
- cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
-}
-
-/**
- * fc_logo_fill - Fill in a logo request frame.
- */
-static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_logo *logo;
-
- logo = fc_frame_payload_get(fp, sizeof(*logo));
- memset(logo, 0, sizeof(*logo));
- logo->fl_cmd = ELS_LOGO;
- hton24(logo->fl_n_port_id, lport->port_id);
- logo->fl_n_port_wwn = htonll(lport->wwpn);
-}
-
-/**
- * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
- */
-static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_rtv *rtv;
-
- rtv = fc_frame_payload_get(fp, sizeof(*rtv));
- memset(rtv, 0, sizeof(*rtv));
- rtv->rtv_cmd = ELS_RTV;
-}
-
-/**
- * fc_rec_fill - Fill in rec request frame
- */
-static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_rec *rec;
- struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
-
- rec = fc_frame_payload_get(fp, sizeof(*rec));
- memset(rec, 0, sizeof(*rec));
- rec->rec_cmd = ELS_REC;
- hton24(rec->rec_s_id, lport->port_id);
- rec->rec_ox_id = htons(ep->oxid);
- rec->rec_rx_id = htons(ep->rxid);
-}
-
-/**
- * fc_prli_fill - Fill in prli request frame
- */
-static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct {
- struct fc_els_prli prli;
- struct fc_els_spp spp;
- } *pp;
-
- pp = fc_frame_payload_get(fp, sizeof(*pp));
- memset(pp, 0, sizeof(*pp));
- pp->prli.prli_cmd = ELS_PRLI;
- pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
- pp->prli.prli_len = htons(sizeof(*pp));
- pp->spp.spp_type = FC_TYPE_FCP;
- pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
- pp->spp.spp_params = htonl(lport->service_params);
-}
-
-/**
- * fc_scr_fill - Fill in a scr request frame.
- */
-static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
-{
- struct fc_els_scr *scr;
-
- scr = fc_frame_payload_get(fp, sizeof(*scr));
- memset(scr, 0, sizeof(*scr));
- scr->scr_cmd = ELS_SCR;
- scr->scr_reg_func = ELS_SCRF_FULL;
-}
-
-/**
- * fc_els_fill - Fill in an ELS request frame
- */
-static inline int fc_els_fill(struct fc_lport *lport,
- u32 did,
- struct fc_frame *fp, unsigned int op,
- enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
-{
- switch (op) {
- case ELS_ADISC:
- fc_adisc_fill(lport, fp);
- break;
-
- case ELS_PLOGI:
- fc_plogi_fill(lport, fp, ELS_PLOGI);
- break;
-
- case ELS_FLOGI:
- fc_flogi_fill(lport, fp);
- break;
-
- case ELS_FDISC:
- fc_fdisc_fill(lport, fp);
- break;
-
- case ELS_LOGO:
- fc_logo_fill(lport, fp);
- break;
-
- case ELS_RTV:
- fc_rtv_fill(lport, fp);
- break;
-
- case ELS_REC:
- fc_rec_fill(lport, fp);
- break;
-
- case ELS_PRLI:
- fc_prli_fill(lport, fp);
- break;
-
- case ELS_SCR:
- fc_scr_fill(lport, fp);
- break;
-
- default:
- return -EINVAL;
- }
-
- *r_ctl = FC_RCTL_ELS_REQ;
- *fh_type = FC_TYPE_ELS;
- return 0;
-}
-#endif /* _FC_ENCODE_H_ */
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 8225d8063ec4..d544dc5057fc 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
@@ -258,4 +246,34 @@ static inline bool fc_frame_is_cmd(const struct fc_frame *fp)
*/
void fc_frame_leak_check(void);
+static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh,
+ enum fc_rctl r_ctl,
+ u32 did, u32 sid, enum fc_fh_type type,
+ u32 f_ctl, u32 parm_offset)
+{
+ WARN_ON(r_ctl == 0);
+ fh->fh_r_ctl = r_ctl;
+ hton24(fh->fh_d_id, did);
+ hton24(fh->fh_s_id, sid);
+ fh->fh_type = type;
+ hton24(fh->fh_f_ctl, f_ctl);
+ fh->fh_cs_ctl = 0;
+ fh->fh_df_ctl = 0;
+ fh->fh_parm_offset = htonl(parm_offset);
+}
+
+/**
+ * fill FC header fields in specified fc_frame
+ */
+static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
+ u32 did, u32 sid, enum fc_fh_type type,
+ u32 f_ctl, u32 parm_offset)
+{
+ struct fc_frame_header *fh;
+
+ fh = fc_frame_header_get(fp);
+ __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset);
+}
+
+
#endif /* _FC_FRAME_H_ */
diff --git a/include/scsi/fcoe_sysfs.h b/include/scsi/fcoe_sysfs.h
index 7e2314870341..2b28a05e492b 100644
--- a/include/scsi/fcoe_sysfs.h
+++ b/include/scsi/fcoe_sysfs.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2011-2012 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
@@ -62,9 +50,7 @@ struct fcoe_ctlr_device {
struct fcoe_sysfs_function_template *f;
struct list_head fcfs;
- char work_q_name[20];
struct workqueue_struct *work_q;
- char devloss_work_q_name[20];
struct workqueue_struct *devloss_work_q;
struct mutex lock;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index d66c07077d68..5225a23f2d0e 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc)
*
* Copyright (C) 2005 Dmitry Yusupov
* Copyright (C) 2005 Alex Aizman
* maintained by open-iscsi@googlegroups.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * See the file COPYING included with this distribution for more details.
*/
#ifndef ISCSI_IF_H
@@ -71,6 +60,7 @@ enum iscsi_uevent_e {
ISCSI_UEVENT_LOGOUT_FLASHNODE_SID = UEVENT_BASE + 30,
ISCSI_UEVENT_SET_CHAP = UEVENT_BASE + 31,
ISCSI_UEVENT_GET_HOST_STATS = UEVENT_BASE + 32,
+ ISCSI_UEVENT_DESTROY_SESSION_ASYNC = UEVENT_BASE + 33,
/* up events */
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
@@ -322,7 +312,7 @@ enum iscsi_param_type {
struct iscsi_param_info {
uint32_t len; /* Actual length of the param value */
uint16_t param; /* iscsi param */
- uint8_t value[0]; /* length sized value follows */
+ uint8_t value[]; /* length sized value follows */
} __packed;
struct iscsi_iface_param_info {
@@ -331,7 +321,7 @@ struct iscsi_iface_param_info {
uint16_t param; /* iscsi param value */
uint8_t iface_type; /* IPv4 or IPv6 */
uint8_t param_type; /* iscsi_param_type */
- uint8_t value[0]; /* length sized value follows */
+ uint8_t value[]; /* length sized value follows */
} __packed;
/*
@@ -708,7 +698,7 @@ enum iscsi_flashnode_param {
struct iscsi_flashnode_param_info {
uint32_t len; /* Actual length of the param */
uint16_t param; /* iscsi param value */
- uint8_t value[0]; /* length sized value follows */
+ uint8_t value[]; /* length sized value follows */
} __packed;
enum iscsi_discovery_parent_type {
@@ -826,7 +816,7 @@ struct iscsi_stats {
* up to ISCSI_STATS_CUSTOM_MAX
*/
uint32_t custom_length;
- struct iscsi_stats_custom custom[0]
+ struct iscsi_stats_custom custom[]
__attribute__ ((aligned (sizeof(uint64_t))));
};
@@ -957,7 +947,7 @@ struct iscsi_offload_host_stats {
* up to ISCSI_HOST_STATS_CUSTOM_MAX
*/
uint32_t custom_length;
- struct iscsi_host_stats_custom custom[0]
+ struct iscsi_host_stats_custom custom[]
__aligned(sizeof(uint64_t));
};
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h
index df156f1d50b2..7b192d88f186 100644
--- a/include/scsi/iscsi_proto.h
+++ b/include/scsi/iscsi_proto.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* RFC 3720 (iSCSI) protocol data types
*
* Copyright (C) 2005 Dmitry Yusupov
* Copyright (C) 2005 Alex Aizman
* maintained by open-iscsi@googlegroups.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * See the file COPYING included with this distribution for more details.
*/
#ifndef ISCSI_PROTO_H
@@ -63,7 +52,7 @@ static inline int iscsi_sna_gte(u32 n1, u32 n2)
}
/*
- * useful common(control and data pathes) macro
+ * useful common(control and data paths) macro
*/
#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
#define hton24(p, v) { \
diff --git a/include/scsi/iser.h b/include/scsi/iser.h
index 2e678fa74eca..07a83bfa2b8e 100644
--- a/include/scsi/iser.h
+++ b/include/scsi/iser.h
@@ -63,7 +63,7 @@ struct iser_cm_hdr {
* @rsvd: reserved
* @write_stag: write rkey
* @write_va: write virtual address
- * @reaf_stag: read rkey
+ * @read_stag: read rkey
* @read_va: read virtual address
*/
struct iser_ctrl {
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 2109844be53d..183d9fd50d2d 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -1,19 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
@@ -56,11 +44,16 @@
* @LPORT_ST_DISABLED: Disabled
* @LPORT_ST_FLOGI: Fabric login (FLOGI) sent
* @LPORT_ST_DNS: Waiting for name server remote port to become ready
- * @LPORT_ST_RPN_ID: Register port name by ID (RPN_ID) sent
+ * @LPORT_ST_RNN_ID: Register port name by ID (RNN_ID) sent
+ * @LPORT_ST_RSNN_NN: Waiting for host symbolic node name
+ * @LPORT_ST_RSPN_ID: Waiting for host symbolic port name
* @LPORT_ST_RFT_ID: Register Fibre Channel types by ID (RFT_ID) sent
* @LPORT_ST_RFF_ID: Register FC-4 Features by ID (RFF_ID) sent
* @LPORT_ST_FDMI: Waiting for mgmt server rport to become ready
- * @LPORT_ST_RHBA:
+ * @LPORT_ST_RHBA: Register HBA
+ * @LPORT_ST_RPA: Register Port Attributes
+ * @LPORT_ST_DHBA: Deregister HBA
+ * @LPORT_ST_DPRT: Deregister Port
* @LPORT_ST_SCR: State Change Register (SCR) sent
* @LPORT_ST_READY: Ready for use
* @LPORT_ST_LOGO: Local port logout (LOGO) sent
@@ -127,7 +120,7 @@ struct fc_disc_port {
struct fc_lport *lp;
struct list_head peers;
struct work_struct rport_work;
- u32 port_id;
+ u32 port_id;
};
/**
@@ -167,14 +160,14 @@ struct fc_rport_operations {
*/
struct fc_rport_libfc_priv {
struct fc_lport *local_port;
- enum fc_rport_state rp_state;
+ enum fc_rport_state rp_state;
u16 flags;
#define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
#define FC_RP_FLAGS_RETRY (1 << 1)
#define FC_RP_STARTED (1 << 2)
#define FC_RP_FLAGS_CONF_REQ (1 << 3)
- unsigned int e_d_tov;
- unsigned int r_a_tov;
+ unsigned int e_d_tov;
+ unsigned int r_a_tov;
};
/**
@@ -195,7 +188,7 @@ struct fc_rport_libfc_priv {
* @r_a_tov: Resource allocation timeout value (in msec)
* @rp_mutex: The mutex that protects the remote port
* @retry_work: Handle for retries
- * @event_callback: Callback when READY, FAILED or LOGO states complete
+ * @lld_event_callback: Callback when READY, FAILED or LOGO states complete
* @prli_count: Count of open PRLI sessions in providers
* @rcu: Structure used for freeing in an RCU-safe manner
*/
@@ -203,24 +196,24 @@ struct fc_rport_priv {
struct fc_lport *local_port;
struct fc_rport *rport;
struct kref kref;
- enum fc_rport_state rp_state;
+ enum fc_rport_state rp_state;
struct fc_rport_identifiers ids;
u16 flags;
- u16 max_seq;
+ u16 max_seq;
u16 disc_id;
u16 maxframe_size;
- unsigned int retries;
- unsigned int major_retries;
- unsigned int e_d_tov;
- unsigned int r_a_tov;
- struct mutex rp_mutex;
+ unsigned int retries;
+ unsigned int major_retries;
+ unsigned int e_d_tov;
+ unsigned int r_a_tov;
+ struct mutex rp_mutex;
struct delayed_work retry_work;
- enum fc_rport_event event;
+ enum fc_rport_event event;
struct fc_rport_operations *ops;
- struct list_head peers;
- struct work_struct event_work;
+ struct list_head peers;
+ struct work_struct event_work;
u32 supported_classes;
- u16 prli_count;
+ u16 prli_count;
struct rcu_head rcu;
u16 sp_features;
u8 spp_type;
@@ -301,6 +294,7 @@ struct fc_seq_els_data {
* @timer: The command timer
* @tm_done: Completion indicator
* @wait_for_comp: Indicator to wait for completion of the I/O (in jiffies)
+ * @timer_delay: FCP packet timer delay in jiffies
* @data_len: The length of the data
* @cdb_cmd: The CDB command
* @xfer_len: The transfer length
@@ -364,6 +358,15 @@ struct fc_fcp_pkt {
} ____cacheline_aligned_in_smp;
/*
+ * @fsp should be tested and set under the scsi_pkt_queue lock
+ */
+struct libfc_cmd_priv {
+ struct fc_fcp_pkt *fsp;
+ u32 resid_len;
+ u8 status;
+};
+
+/*
* Structure and function definitions for managing Fibre Channel Exchanges
* and Sequences
*
@@ -411,7 +414,7 @@ struct fc_seq {
* @sid: Source FCID
* @did: Destination FCID
* @esb_stat: ESB exchange status
- * @r_a_tov: Resouce allocation time out value (in msecs)
+ * @r_a_tov: Resource allocation time out value (in msecs)
* @seq_id: The next sequence ID to use
* @encaps: encapsulation information for lower-level driver
* @f_ctl: F_CTL flags for the sequence
@@ -630,12 +633,12 @@ struct libfc_function_template {
* @disc_callback: Callback routine called when discovery completes
*/
struct fc_disc {
- unsigned char retry_count;
- unsigned char pending;
- unsigned char requested;
- unsigned short seq_count;
- unsigned char buf_len;
- u16 disc_id;
+ unsigned char retry_count;
+ unsigned char pending;
+ unsigned char requested;
+ unsigned short seq_count;
+ unsigned char buf_len;
+ u16 disc_id;
struct list_head rports;
void *priv;
@@ -680,7 +683,7 @@ enum fc_lport_event {
* @wwnn: World Wide Node Name
* @service_params: Common service parameters
* @e_d_tov: Error detection timeout value
- * @r_a_tov: Resouce allocation timeout value
+ * @r_a_tov: Resource allocation timeout value
* @rnid_gen: RNID information
* @sg_supp: Indicates if scatter gather is supported
* @seq_offload: Indicates if sequence offload is supported
@@ -709,7 +712,7 @@ struct fc_lport {
struct fc_rport_priv *ms_rdata;
struct fc_rport_priv *ptp_rdata;
void *scsi_priv;
- struct fc_disc disc;
+ struct fc_disc disc;
/* Virtual port information */
struct list_head vports;
@@ -727,7 +730,7 @@ struct fc_lport {
u8 retry_count;
/* Fabric information */
- u32 port_id;
+ u32 port_id;
u64 wwpn;
u64 wwnn;
unsigned int service_params;
@@ -755,11 +758,11 @@ struct fc_lport {
struct fc_ns_fts fcts;
/* Miscellaneous */
- struct mutex lp_mutex;
- struct list_head list;
+ struct mutex lp_mutex;
+ struct list_head list;
struct delayed_work retry_work;
void *prov[FC_FC4_PROV_SIZE];
- struct list_head lport_list;
+ struct list_head lport_list;
};
/**
@@ -791,6 +794,8 @@ void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *);
/**
* fc_lport_test_ready() - Determine if a local port is in the READY state
* @lport: The local port to test
+ *
+ * Returns: %true if local port is in the READY state, %false otherwise
*/
static inline int fc_lport_test_ready(struct fc_lport *lport)
{
@@ -833,6 +838,8 @@ static inline void fc_lport_state_enter(struct fc_lport *lport,
/**
* fc_lport_init_stats() - Allocate per-CPU statistics for a local port
* @lport: The local port whose statistics are to be initialized
+ *
+ * Returns: %0 on success, %-ENOMEM on failure
*/
static inline int fc_lport_init_stats(struct fc_lport *lport)
{
@@ -853,7 +860,9 @@ static inline void fc_lport_free_stats(struct fc_lport *lport)
/**
* lport_priv() - Return the private data from a local port
- * @lport: The local port whose private data is to be retreived
+ * @lport: The local port whose private data is to be retrieved
+ *
+ * Returns: the local port's private data pointer
*/
static inline void *lport_priv(const struct fc_lport *lport)
{
@@ -869,7 +878,7 @@ static inline void *lport_priv(const struct fc_lport *lport)
* Returns: libfc lport
*/
static inline struct fc_lport *
-libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
+libfc_host_alloc(const struct scsi_host_template *sht, int priv_size)
{
struct fc_lport *lport;
struct Scsi_Host *shost;
@@ -954,7 +963,7 @@ int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
int fc_eh_abort(struct scsi_cmnd *);
int fc_eh_device_reset(struct scsi_cmnd *);
int fc_eh_host_reset(struct scsi_cmnd *);
-int fc_slave_alloc(struct scsi_device *);
+int fc_sdev_init(struct scsi_device *);
/*
* ELS/CT interface
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index cb8a273732cf..6616348e59b9 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2007-2008 Intel Corporation. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
* Maintained at www.Open-FCoE.org
*/
@@ -26,7 +14,8 @@
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
-#include <linux/random.h>
+#include <linux/local_lock.h>
+#include <linux/prandom.h>
#include <scsi/fc/fc_fcoe.h>
#include <scsi/libfc.h>
#include <scsi/fcoe_sysfs.h>
@@ -43,7 +32,7 @@
* FIP tunable parameters.
*/
#define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */
-#define FCOE_CTRL_SOL_TOV 2000 /* min. solicitation interval (mS) */
+#define FCOE_CTLR_SOL_TOV 2000 /* min. solicitation interval (mS) */
#define FCOE_CTLR_FCF_LIMIT 20 /* max. number of FCF entries */
#define FCOE_CTLR_VN2VN_LOGIN_LIMIT 3 /* max. VN2VN rport login retries */
@@ -79,7 +68,7 @@ enum fip_state {
* It must not change after fcoe_ctlr_init() sets it.
*/
enum fip_mode {
- FIP_MODE_AUTO = FIP_ST_AUTO,
+ FIP_MODE_AUTO,
FIP_MODE_NON_FIP,
FIP_MODE_FABRIC,
FIP_MODE_VN2VN,
@@ -168,7 +157,9 @@ struct fcoe_ctlr {
/**
* fcoe_ctlr_priv() - Return the private data from a fcoe_ctlr
- * @cltr: The fcoe_ctlr whose private data will be returned
+ * @ctlr: The fcoe_ctlr whose private data will be returned
+ *
+ * Returns: pointer to the private data
*/
static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
{
@@ -185,7 +176,6 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
* struct fcoe_fcf - Fibre-Channel Forwarder
* @list: list linkage
* @event_work: Work for FC Transport actions queue
- * @event: The event to be processed
* @fip: The controller that the FCF was discovered on
* @fcf_dev: The associated fcoe_fcf_device instance
* @time: system time (jiffies) when an advertisement was last received
@@ -199,6 +189,7 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
* @flogi_sent: current FLOGI sent to this FCF
* @flags: flags received from advertisement
* @fka_period: keep-alive period, in jiffies
+ * @fd_flags: no need for FKA from ENode
*
* A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that
* passes FCoE frames on to an FC fabric. This structure represents
@@ -233,6 +224,7 @@ struct fcoe_fcf {
/**
* struct fcoe_rport - VN2VN remote port
+ * @rdata: libfc remote port private data
* @time: time of create or last beacon packet received from node
* @fcoe_len: max FCoE frame size, not including VLAN or Ethernet headers
* @flags: flags from probe or claim
@@ -241,6 +233,7 @@ struct fcoe_fcf {
* @vn_mac: VN_Node assigned MAC address for data
*/
struct fcoe_rport {
+ struct fc_rport_priv rdata;
unsigned long time;
u16 fcoe_len;
u16 flags;
@@ -250,7 +243,7 @@ struct fcoe_rport {
};
/* FIP API functions */
-void fcoe_ctlr_init(struct fcoe_ctlr *, enum fip_state);
+void fcoe_ctlr_init(struct fcoe_ctlr *, enum fip_mode);
void fcoe_ctlr_destroy(struct fcoe_ctlr *);
void fcoe_ctlr_link_up(struct fcoe_ctlr *);
int fcoe_ctlr_link_down(struct fcoe_ctlr *);
@@ -260,7 +253,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,
struct fc_frame *);
/* libfcoe funcs */
-u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
+u64 fcoe_wwn_from_mac(unsigned char mac[ETH_ALEN], unsigned int scheme,
+ unsigned int port);
int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *,
const struct libfc_function_template *, int init_fcp);
u32 fcoe_fc_crc(struct fc_frame *fp);
@@ -275,8 +269,10 @@ void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);
/**
- * is_fip_mode() - returns true if FIP mode selected.
+ * is_fip_mode() - test if FIP mode selected.
* @fip: FCoE controller.
+ *
+ * Returns: %true if FIP mode is selected
*/
static inline bool is_fip_mode(struct fcoe_ctlr *fip)
{
@@ -327,9 +323,10 @@ struct fcoe_transport {
* @kthread: The thread context (used by bnx2fc)
* @work: The work item (used by fcoe)
* @fcoe_rx_list: The queue of pending packets to process
- * @page: The memory page for calculating frame trailer CRCs
+ * @crc_eof_page: The memory page for calculating frame trailer CRCs
* @crc_eof_offset: The offset into the CRC page pointing to available
* memory for a new trailer
+ * @lock: local lock for members of this struct
*/
struct fcoe_percpu_s {
struct task_struct *kthread;
@@ -337,6 +334,7 @@ struct fcoe_percpu_s {
struct sk_buff_head fcoe_rx_list;
struct page *crc_eof_page;
int crc_eof_offset;
+ local_lock_t lock;
};
/**
@@ -351,7 +349,8 @@ struct fcoe_percpu_s {
* @timer: The queue timer
* @destroy_work: Handle for work context
* (to prevent RTNL deadlocks)
- * @data_srt_addr: Source address for data
+ * @data_src_addr: Source address for data
+ * @get_netdev: function that returns a &net_device from @lport
*
* An instance of this structure is to be allocated along with the
* Scsi_Host and libfc fc_lport structures.
@@ -372,6 +371,8 @@ struct fcoe_port {
/**
* fcoe_get_netdev() - Return the net device associated with a local port
* @lport: The local port to get the net device from
+ *
+ * Returns: the &net_device associated with this @lport
*/
static inline struct net_device *fcoe_get_netdev(const struct fc_lport *lport)
{
@@ -391,8 +392,10 @@ void fcoe_fcf_get_selected(struct fcoe_fcf_device *);
void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *);
/**
- * struct netdev_list
- * A mapping from netdevice to fcoe_transport
+ * struct fcoe_netdev_mapping - A mapping from &net_device to &fcoe_transport
+ * @list: list linkage of the mappings
+ * @netdev: the &net_device
+ * @ft: the fcoe_transport associated with @netdev
*/
struct fcoe_netdev_mapping {
struct list_head list;
@@ -405,10 +408,8 @@ int fcoe_transport_attach(struct fcoe_transport *ft);
int fcoe_transport_detach(struct fcoe_transport *ft);
/* sysfs store handler for ctrl_control interface */
-ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
- const char *buf, size_t count);
-ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus,
- const char *buf, size_t count);
+ssize_t fcoe_ctlr_create_store(const char *buf, size_t count);
+ssize_t fcoe_ctlr_destroy_store(const char *buf, size_t count);
#endif /* _LIBFCOE_H */
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c9bd935f4fd1..7282555adfd5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* iSCSI lib definitions
*
@@ -5,20 +6,6 @@
* Copyright (C) 2004 - 2006 Mike Christie
* Copyright (C) 2004 - 2005 Dmitry Yusupov
* Copyright (C) 2004 - 2005 Alex Aizman
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef LIBISCSI_H
#define LIBISCSI_H
@@ -32,6 +19,7 @@
#include <linux/refcount.h>
#include <scsi/iscsi_proto.h>
#include <scsi/iscsi_if.h>
+#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_transport_iscsi.h>
struct scsi_transport_template;
@@ -65,8 +53,10 @@ enum {
#define ISID_SIZE 6
-/* Connection suspend "bit" */
-#define ISCSI_SUSPEND_BIT 1
+/* Connection flags */
+#define ISCSI_CONN_FLAG_SUSPEND_TX 0
+#define ISCSI_CONN_FLAG_SUSPEND_RX 1
+#define ISCSI_CONN_FLAG_BOUND 2
#define ISCSI_ITT_MASK 0x1fff
#define ISCSI_TOTAL_CMDS_MAX 4096
@@ -155,6 +145,24 @@ static inline void* iscsi_next_hdr(struct iscsi_task *task)
return (void*)task->hdr + task->hdr_len;
}
+static inline bool iscsi_task_is_completed(struct iscsi_task *task)
+{
+ return task->state == ISCSI_TASK_COMPLETED ||
+ task->state == ISCSI_TASK_ABRT_TMF ||
+ task->state == ISCSI_TASK_ABRT_SESS_RECOV;
+}
+
+/* Private data associated with struct scsi_cmnd. */
+struct iscsi_cmd {
+ struct iscsi_task *task;
+ int age;
+};
+
+static inline struct iscsi_cmd *iscsi_cmd(struct scsi_cmnd *cmd)
+{
+ return scsi_cmd_priv(cmd);
+}
+
/* Connection's states */
enum {
ISCSI_CONN_INITIAL_STAGE,
@@ -197,19 +205,14 @@ struct iscsi_conn {
struct iscsi_task *task; /* xmit task in progress */
/* xmit */
- spinlock_t taskqueuelock; /* protects the next three lists */
+ /* items must be added/deleted under frwd lock */
struct list_head mgmtqueue; /* mgmt (control) xmit queue */
struct list_head cmdqueue; /* data-path cmd queue */
struct list_head requeue; /* tasks needing another run */
struct work_struct xmitwork; /* per-conn. xmit workqueue */
- unsigned long suspend_tx; /* suspend Tx */
- unsigned long suspend_rx; /* suspend Rx */
-
- /* abort */
- wait_queue_head_t ehwait; /* used in eh_abort() */
- struct iscsi_tm tmhdr;
- struct timer_list tmf_timer;
- int tmf_state; /* see TMF_INITIAL, etc.*/
+ /* recv */
+ struct work_struct recvwork;
+ unsigned long flags; /* ISCSI_CONN_FLAGs */
/* negotiated params */
unsigned max_recv_dlength; /* initiator_max_recv_dsl*/
@@ -280,6 +283,12 @@ struct iscsi_session {
* and recv lock.
*/
struct mutex eh_mutex;
+ /* abort */
+ wait_queue_head_t ehwait; /* used in eh_abort() */
+ struct iscsi_tm tmhdr;
+ struct timer_list tmf_timer;
+ int tmf_state; /* see TMF_INITIAL, etc.*/
+ struct iscsi_task *running_aborted_task;
/* iSCSI session-wide sequencing */
uint32_t cmdsn;
@@ -342,7 +351,7 @@ struct iscsi_session {
* cmdsn, queued_cmdsn *
* session resources: *
* - cmdpool kfifo_out , *
- * - mgmtpool, */
+ * - mgmtpool, queues */
spinlock_t back_lock; /* protects cmdsn_exp *
* cmdsn_max, *
* cmdpool kfifo_in */
@@ -374,7 +383,6 @@ struct iscsi_host {
int state;
struct workqueue_struct *workq;
- char workq_name[20];
};
/*
@@ -385,7 +393,7 @@ extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
-extern enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc);
+extern enum scsi_timeout_action iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc);
/*
* iSCSI host helpers.
@@ -399,12 +407,14 @@ extern int iscsi_host_set_param(struct Scsi_Host *shost,
extern int iscsi_host_get_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf);
extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
-extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
+extern struct Scsi_Host *iscsi_host_alloc(const struct scsi_host_template *sht,
int dd_data_size,
bool xmit_can_sleep);
-extern void iscsi_host_remove(struct Scsi_Host *shost);
+extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown);
extern void iscsi_host_free(struct Scsi_Host *shost);
extern int iscsi_target_alloc(struct scsi_target *starget);
+extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
+ uint16_t requested_cmds_max);
/*
* session management
@@ -412,6 +422,8 @@ extern int iscsi_target_alloc(struct scsi_target *starget);
extern struct iscsi_cls_session *
iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
uint16_t, int, int, uint32_t, unsigned int);
+void iscsi_session_remove(struct iscsi_cls_session *cls_session);
+void iscsi_session_free(struct iscsi_cls_session *cls_session);
extern void iscsi_session_teardown(struct iscsi_cls_session *);
extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
@@ -432,6 +444,7 @@ extern int iscsi_conn_start(struct iscsi_cls_conn *);
extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
int);
+extern void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active);
extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
extern void iscsi_session_failure(struct iscsi_session *session,
enum iscsi_err err);
@@ -440,8 +453,10 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr,
enum iscsi_param param, char *buf);
extern void iscsi_suspend_tx(struct iscsi_conn *conn);
+extern void iscsi_suspend_rx(struct iscsi_conn *conn);
extern void iscsi_suspend_queue(struct iscsi_conn *conn);
-extern void iscsi_conn_queue_work(struct iscsi_conn *conn);
+extern void iscsi_conn_queue_xmit(struct iscsi_conn *conn);
+extern void iscsi_conn_queue_recv(struct iscsi_conn *conn);
#define iscsi_conn_printk(prefix, _c, fmt, a...) \
iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
@@ -466,7 +481,7 @@ extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
extern void iscsi_requeue_task(struct iscsi_task *task);
extern void iscsi_put_task(struct iscsi_task *task);
extern void __iscsi_put_task(struct iscsi_task *task);
-extern void __iscsi_get_task(struct iscsi_task *task);
+extern bool iscsi_get_task(struct iscsi_task *task);
extern void iscsi_complete_scsi_task(struct iscsi_task *task,
uint32_t exp_cmdsn, uint32_t max_cmdsn);
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h
index 30520d5ee3d1..ef53d4bea28a 100644
--- a/include/scsi/libiscsi_tcp.h
+++ b/include/scsi/libiscsi_tcp.h
@@ -1,21 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* iSCSI over TCP/IP Data-Path lib
*
* Copyright (C) 2008 Mike Christie
* Copyright (C) 2008 Red Hat, Inc. All rights reserved.
* maintained by open-iscsi@googlegroups.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * See the file COPYING included with this distribution for more details.
*/
#ifndef LIBISCSI_TCP_H
@@ -26,7 +15,6 @@
struct iscsi_tcp_conn;
struct iscsi_segment;
struct sk_buff;
-struct ahash_request;
typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *,
struct iscsi_segment *);
@@ -38,7 +26,7 @@ struct iscsi_segment {
unsigned int total_size;
unsigned int total_copied;
- struct ahash_request *hash;
+ u32 *crcp;
unsigned char padbuf[ISCSI_PAD_LEN];
unsigned char recv_digest[ISCSI_DIGEST_SIZE];
unsigned char digest[ISCSI_DIGEST_SIZE];
@@ -72,8 +60,8 @@ struct iscsi_tcp_conn {
* stop to terminate */
/* control data */
struct iscsi_tcp_recv in; /* TCP receive context */
- /* CRC32C (Rx) LLD should set this is they do not offload */
- struct ahash_request *rx_hash;
+ /* CRC32C (Rx) LLD should set this if they do not offload */
+ u32 *rx_crcp;
};
struct iscsi_tcp_task {
@@ -110,18 +98,15 @@ extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment);
extern void iscsi_segment_init_linear(struct iscsi_segment *segment,
void *data, size_t size,
- iscsi_segment_done_fn_t *done,
- struct ahash_request *hash);
+ iscsi_segment_done_fn_t *done, u32 *crcp);
extern int
iscsi_segment_seek_sg(struct iscsi_segment *segment,
struct scatterlist *sg_list, unsigned int sg_count,
unsigned int offset, size_t size,
- iscsi_segment_done_fn_t *done,
- struct ahash_request *hash);
+ iscsi_segment_done_fn_t *done, u32 *crcp);
/* digest helpers */
-extern void iscsi_tcp_dgst_header(struct ahash_request *hash, const void *hdr,
- size_t hdrlen,
+extern void iscsi_tcp_dgst_header(const void *hdr, size_t hdrlen,
unsigned char digest[ISCSI_DIGEST_SIZE]);
extern struct iscsi_cls_conn *
iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size,
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 3de3b10da19a..a0635b128d7a 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -1,26 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* SAS host prototypes and structures header file
*
* Copyright (C) 2005 Adaptec, Inc. All rights reserved.
* Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
- *
- * This file is licensed under GPLv2.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
*/
#ifndef _LIBSAS_H_
@@ -40,22 +23,12 @@
struct block_device;
-enum sas_class {
- SAS,
- EXPANDER
-};
-
enum sas_phy_role {
PHY_ROLE_NONE = 0,
PHY_ROLE_TARGET = 0x40,
PHY_ROLE_INITIATOR = 0x80,
};
-enum sas_phy_type {
- PHY_TYPE_PHYSICAL,
- PHY_TYPE_VIRTUAL
-};
-
/* The events are mnemonically described in sas_dump.c
* so when updating/adding events here, please also
* update the other file too.
@@ -91,7 +64,7 @@ enum discover_event {
#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
#define to_dev_attr(_attr) container_of(_attr, struct domain_dev_attribute,\
- attr)
+ attr)
enum routing_attribute {
DIRECT_ROUTING,
@@ -162,7 +135,7 @@ struct sata_device {
struct ata_port *ap;
struct ata_host *ata_host;
- struct smp_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
+ struct smp_rps_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
u8 fis[ATA_RESP_FIS_SIZE];
};
@@ -184,37 +157,37 @@ struct domain_device {
spinlock_t done_lock;
enum sas_device_type dev_type;
- enum sas_linkrate linkrate;
- enum sas_linkrate min_linkrate;
- enum sas_linkrate max_linkrate;
+ enum sas_linkrate linkrate;
+ enum sas_linkrate min_linkrate;
+ enum sas_linkrate max_linkrate;
- int pathways;
+ int pathways;
- struct domain_device *parent;
- struct list_head siblings; /* devices on the same level */
- struct asd_sas_port *port; /* shortcut to root of the tree */
+ struct domain_device *parent;
+ struct list_head siblings; /* devices on the same level */
+ struct asd_sas_port *port; /* shortcut to root of the tree */
struct sas_phy *phy;
- struct list_head dev_list_node;
+ struct list_head dev_list_node;
struct list_head disco_list_node; /* awaiting probe or destruct */
- enum sas_protocol iproto;
- enum sas_protocol tproto;
+ enum sas_protocol iproto;
+ enum sas_protocol tproto;
- struct sas_rphy *rphy;
+ struct sas_rphy *rphy;
- u8 sas_addr[SAS_ADDR_SIZE];
- u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
+ u8 sas_addr[SAS_ADDR_SIZE];
+ u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
- u8 frame_rcvd[32];
+ u8 frame_rcvd[32];
- union {
- struct expander_device ex_dev;
- struct sata_device sata_dev; /* STP & directly attached */
+ union {
+ struct expander_device ex_dev;
+ struct sata_device sata_dev; /* STP & directly attached */
struct ssp_device ssp_dev;
- };
+ };
- void *lldd_dev;
+ void *lldd_dev;
unsigned long state;
struct kref kref;
};
@@ -224,6 +197,20 @@ struct sas_work {
struct work_struct work;
};
+static inline bool dev_is_expander(enum sas_device_type type)
+{
+ return type == SAS_EDGE_EXPANDER_DEVICE ||
+ type == SAS_FANOUT_EXPANDER_DEVICE;
+}
+
+static inline bool dev_parent_is_expander(struct domain_device *dev)
+{
+ if (!dev->parent)
+ return false;
+
+ return dev_is_expander(dev->parent->dev_type);
+}
+
static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *))
{
INIT_WORK(&sw->work, fn);
@@ -245,9 +232,9 @@ static inline struct sas_discovery_event *to_sas_discovery_event(struct work_str
struct sas_discovery {
struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
unsigned long pending;
- u8 fanout_sas_addr[8];
- u8 eeds_a[8];
- u8 eeds_b[8];
+ u8 fanout_sas_addr[SAS_ADDR_SIZE];
+ u8 eeds_a[SAS_ADDR_SIZE];
+ u8 eeds_b[SAS_ADDR_SIZE];
int max_level;
};
@@ -269,7 +256,6 @@ struct asd_sas_port {
/* public: */
int id;
- enum sas_class class;
u8 sas_addr[SAS_ADDR_SIZE];
u8 attached_sas_addr[SAS_ADDR_SIZE];
enum sas_protocol iproto;
@@ -330,11 +316,9 @@ struct asd_sas_phy {
int enabled; /* must be set */
int id; /* must be set */
- enum sas_class class;
enum sas_protocol iproto;
enum sas_protocol tproto;
- enum sas_phy_type type;
enum sas_phy_role role;
enum sas_oob_mode oob_mode;
enum sas_linkrate linkrate;
@@ -357,16 +341,12 @@ struct asd_sas_phy {
void *lldd_phy; /* not touched by the sas_class_code */
};
-struct scsi_core {
- struct Scsi_Host *shost;
-
-};
-
enum sas_ha_state {
SAS_HA_REGISTERED,
SAS_HA_DRAINING,
SAS_HA_ATA_EH_ACTIVE,
SAS_HA_FROZEN,
+ SAS_HA_RESUMING,
};
struct sas_ha_struct {
@@ -381,12 +361,11 @@ struct sas_ha_struct {
struct mutex disco_mutex;
- struct scsi_core core;
+ struct Scsi_Host *shost;
/* public: */
char *sas_ha_name;
struct device *dev; /* should be set */
- struct module *lldd_module; /* should be set */
struct workqueue_struct *event_q;
struct workqueue_struct *disco_q;
@@ -402,10 +381,6 @@ struct sas_ha_struct {
int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
* their siblings when forming wide ports */
- /* LLDD calls these to notify the class of an event. */
- int (*notify_port_event)(struct asd_sas_phy *, enum port_event);
- int (*notify_phy_event)(struct asd_sas_phy *, enum phy_event);
-
void *lldd_ha; /* not touched by sas class code */
struct list_head eh_done_q; /* complete via scsi_eh_flush_done_q */
@@ -437,8 +412,6 @@ cmd_to_domain_dev(struct scsi_cmnd *cmd)
return sdev_to_domain_dev(cmd->device);
}
-void sas_hash_addr(u8 *hashed, const u8 *sas_addr);
-
/* Before calling a notify event, LLDD should use this function
* when the link is severed (possibly from its tasklet).
* The idea is that the Class only reads those, while the LLDD,
@@ -489,10 +462,16 @@ enum service_response {
};
enum exec_status {
- /* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of
- * them here to silence 'case value not in enumerated type' warnings
+ /*
+ * Values 0..0x7f are used to return the SAM_STAT_* codes. To avoid
+ * 'case value not in enumerated type' compiler warnings every value
+ * returned through the exec_status enum needs an alias with the SAS_
+ * prefix here.
*/
- __SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
+ SAS_SAM_STAT_GOOD = SAM_STAT_GOOD,
+ SAS_SAM_STAT_BUSY = SAM_STAT_BUSY,
+ SAS_SAM_STAT_TASK_ABORTED = SAM_STAT_TASK_ABORTED,
+ SAS_SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
SAS_DEV_NO_RESPONSE = 0x80,
SAS_DATA_UNDERRUN,
@@ -500,7 +479,6 @@ enum exec_status {
SAS_INTERRUPTED,
SAS_QUEUE_FULL,
SAS_DEVICE_UNKNOWN,
- SAS_SG_ERR,
SAS_OPEN_REJECT,
SAS_OPEN_TO,
SAS_PROTO_RESPONSE,
@@ -512,10 +490,10 @@ enum exec_status {
/* When a task finishes with a response, the LLDD examines the
* response:
- * - For an ATA task task_status_struct::stat is set to
+ * - For an ATA task task_status_struct::stat is set to
* SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the
* contents of struct ata_task_resp.
- * - For SSP tasks, if no data is present or status/TMF response
+ * - For SSP tasks, if no data is present or status/TMF response
* is valid, task_status_struct::stat is set. If data is present
* (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets
* task_status_struct::buf_valid_size, and task_status_struct::stat is
@@ -553,14 +531,26 @@ struct sas_ata_task {
struct host_to_dev_fis fis;
u8 atapi_packet[16]; /* 0 if not ATAPI task */
- u8 retry_count; /* hardware retry, should be > 0 */
-
u8 dma_xfer:1; /* PIO:0 or DMA:1 */
u8 use_ncq:1;
- u8 set_affil_pol:1;
- u8 stp_affil_pol:1;
+ u8 return_fis_on_success:1;
u8 device_control_reg_update:1;
+
+ bool force_phy;
+ int force_phy_id;
+};
+
+/* LLDDs rely on these values */
+enum sas_internal_abort {
+ SAS_INTERNAL_ABORT_SINGLE = 0,
+ SAS_INTERNAL_ABORT_DEV = 1,
+};
+
+struct sas_internal_abort_task {
+ enum sas_internal_abort type;
+ unsigned int qid;
+ u16 tag;
};
struct sas_smp_task {
@@ -576,15 +566,16 @@ enum task_attribute {
};
struct sas_ssp_task {
- u8 retry_count; /* hardware retry, should be > 0 */
-
u8 LUN[8];
- u8 enable_first_burst:1;
enum task_attribute task_attr;
- u8 task_prio;
struct scsi_cmnd *cmd;
};
+struct sas_tmf_task {
+ u8 tmf;
+ u16 tag_of_task_to_be_managed;
+};
+
struct sas_task {
struct domain_device *dev;
@@ -597,6 +588,7 @@ struct sas_task {
struct sas_ata_task ata_task;
struct sas_smp_task smp_task;
struct sas_ssp_task ssp_task;
+ struct sas_internal_abort_task abort_task;
};
struct scatterlist *scatter;
@@ -610,6 +602,7 @@ struct sas_task {
void *lldd_task; /* for use by LLDDs */
void *uldd_task;
struct sas_task_slow *slow_task;
+ struct sas_tmf_task *tmf;
};
struct sas_task_slow {
@@ -625,11 +618,29 @@ struct sas_task_slow {
#define SAS_TASK_STATE_DONE 2
#define SAS_TASK_STATE_ABORTED 4
#define SAS_TASK_NEED_DEV_RESET 8
-#define SAS_TASK_AT_INITIATOR 16
-extern struct sas_task *sas_alloc_task(gfp_t flags);
-extern struct sas_task *sas_alloc_slow_task(gfp_t flags);
-extern void sas_free_task(struct sas_task *task);
+static inline bool sas_is_internal_abort(struct sas_task *task)
+{
+ return task->task_proto == SAS_PROTOCOL_INTERNAL_ABORT;
+}
+
+static inline struct request *sas_task_find_rq(struct sas_task *task)
+{
+ struct scsi_cmnd *scmd;
+
+ if (task->task_proto & SAS_PROTOCOL_STP_ALL) {
+ struct ata_queued_cmd *qc = task->uldd_task;
+
+ scmd = qc ? qc->scsicmd : NULL;
+ } else {
+ scmd = task->uldd_task;
+ }
+
+ if (!scmd)
+ return NULL;
+
+ return scsi_cmd_to_rq(scmd);
+}
struct sas_domain_function_template {
/* The class calls these to notify the LLDD of an event. */
@@ -645,7 +656,6 @@ struct sas_domain_function_template {
/* Task Management Functions. Must be called from process context. */
int (*lldd_abort_task)(struct sas_task *);
int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
- int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
int (*lldd_I_T_nexus_reset)(struct domain_device *);
int (*lldd_ata_check_ready)(struct domain_device *);
@@ -653,6 +663,11 @@ struct sas_domain_function_template {
int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
int (*lldd_query_task)(struct sas_task *);
+ /* Special TMF callbacks */
+ void (*lldd_tmf_exec_complete)(struct domain_device *dev);
+ void (*lldd_tmf_aborted)(struct sas_task *task);
+ bool (*lldd_abort_timeout)(struct sas_task *task, void *data);
+
/* Port and Adapter management */
int (*lldd_clear_nexus_port)(struct asd_sas_port *);
int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
@@ -669,47 +684,35 @@ extern int sas_register_ha(struct sas_ha_struct *);
extern int sas_unregister_ha(struct sas_ha_struct *);
extern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha);
extern void sas_resume_ha(struct sas_ha_struct *sas_ha);
+extern void sas_resume_ha_no_sync(struct sas_ha_struct *sas_ha);
extern void sas_suspend_ha(struct sas_ha_struct *sas_ha);
-int sas_set_phy_speed(struct sas_phy *phy,
- struct sas_phy_linkrates *rates);
int sas_phy_reset(struct sas_phy *phy, int hard_reset);
-extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
+int sas_phy_enable(struct sas_phy *phy, int enable);
+extern int sas_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
extern int sas_target_alloc(struct scsi_target *);
-extern int sas_slave_configure(struct scsi_device *);
+int sas_sdev_configure(struct scsi_device *dev, struct queue_limits *lim);
extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
-extern int sas_bios_param(struct scsi_device *,
- struct block_device *,
+extern int sas_bios_param(struct scsi_device *, struct gendisk *,
sector_t capacity, int *hsc);
+int sas_execute_internal_abort_single(struct domain_device *device,
+ u16 tag, unsigned int qid,
+ void *data);
+int sas_execute_internal_abort_dev(struct domain_device *device,
+ unsigned int qid, void *data);
extern struct scsi_transport_template *
sas_domain_attach_transport(struct sas_domain_function_template *);
extern struct device_attribute dev_attr_phy_event_threshold;
-int sas_discover_root_expander(struct domain_device *);
-
-void sas_init_ex_attr(void);
-
-int sas_ex_revalidate_domain(struct domain_device *);
-
-void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
-void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
-int sas_discover_event(struct asd_sas_port *, enum discover_event ev);
-
-int sas_discover_sata(struct domain_device *);
-int sas_discover_end_dev(struct domain_device *);
-
-void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
-
-void sas_init_dev(struct domain_device *);
-
void sas_task_abort(struct sas_task *);
int sas_eh_abort_handler(struct scsi_cmnd *cmd);
int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
int sas_eh_target_reset_handler(struct scsi_cmnd *cmd);
extern void sas_target_destroy(struct scsi_target *);
-extern int sas_slave_alloc(struct scsi_device *);
-extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
+extern int sas_sdev_init(struct scsi_device *);
+extern int sas_ioctl(struct scsi_device *sdev, unsigned int cmd,
+ void __user *arg);
extern int sas_drain_work(struct sas_ha_struct *ha);
extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
@@ -718,4 +721,46 @@ struct sas_phy *sas_get_local_phy(struct domain_device *dev);
int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
+int sas_abort_task_set(struct domain_device *dev, u8 *lun);
+int sas_clear_task_set(struct domain_device *dev, u8 *lun);
+int sas_lu_reset(struct domain_device *dev, u8 *lun);
+int sas_query_task(struct sas_task *task, u16 tag);
+int sas_abort_task(struct sas_task *task, u16 tag);
+int sas_find_attached_phy_id(struct expander_device *ex_dev,
+ struct domain_device *dev);
+
+void sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event,
+ gfp_t gfp_flags);
+void sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event,
+ gfp_t gfp_flags);
+
+#define __LIBSAS_SHT_BASE \
+ .module = THIS_MODULE, \
+ .name = DRV_NAME, \
+ .proc_name = DRV_NAME, \
+ .queuecommand = sas_queuecommand, \
+ .dma_need_drain = ata_scsi_dma_need_drain, \
+ .target_alloc = sas_target_alloc, \
+ .change_queue_depth = sas_change_queue_depth, \
+ .bios_param = sas_bios_param, \
+ .this_id = -1, \
+ .eh_device_reset_handler = sas_eh_device_reset_handler, \
+ .eh_target_reset_handler = sas_eh_target_reset_handler, \
+ .target_destroy = sas_target_destroy, \
+ .ioctl = sas_ioctl, \
+
+#ifdef CONFIG_COMPAT
+#define _LIBSAS_SHT_BASE __LIBSAS_SHT_BASE \
+ .compat_ioctl = sas_ioctl,
+#else
+#define _LIBSAS_SHT_BASE __LIBSAS_SHT_BASE
+#endif
+
+#define LIBSAS_SHT_BASE _LIBSAS_SHT_BASE \
+ .sdev_configure = sas_sdev_configure, \
+ .sdev_init = sas_sdev_init, \
+
+#define LIBSAS_SHT_BASE_NO_SLAVE_INIT _LIBSAS_SHT_BASE
+
+
#endif /* _SASLIB_H_ */
diff --git a/include/scsi/osd_attributes.h b/include/scsi/osd_attributes.h
deleted file mode 100644
index 8a6acd054e4e..000000000000
--- a/include/scsi/osd_attributes.h
+++ /dev/null
@@ -1,398 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __OSD_ATTRIBUTES_H__
-#define __OSD_ATTRIBUTES_H__
-
-#include <scsi/osd_protocol.h>
-
-/*
- * Contains types and constants that define attribute pages and attribute
- * numbers and their data types.
- */
-
-#define ATTR_SET(pg, id, l, ptr) \
- { .attr_page = pg, .attr_id = id, .len = l, .val_ptr = ptr }
-
-#define ATTR_DEF(pg, id, l) ATTR_SET(pg, id, l, NULL)
-
-/* osd-r10 4.7.3 Attributes pages */
-enum {
- OSD_APAGE_OBJECT_FIRST = 0x0,
- OSD_APAGE_OBJECT_DIRECTORY = 0,
- OSD_APAGE_OBJECT_INFORMATION = 1,
- OSD_APAGE_OBJECT_QUOTAS = 2,
- OSD_APAGE_OBJECT_TIMESTAMP = 3,
- OSD_APAGE_OBJECT_COLLECTIONS = 4,
- OSD_APAGE_OBJECT_SECURITY = 5,
- OSD_APAGE_OBJECT_LAST = 0x2fffffff,
-
- OSD_APAGE_PARTITION_FIRST = 0x30000000,
- OSD_APAGE_PARTITION_DIRECTORY = OSD_APAGE_PARTITION_FIRST + 0,
- OSD_APAGE_PARTITION_INFORMATION = OSD_APAGE_PARTITION_FIRST + 1,
- OSD_APAGE_PARTITION_QUOTAS = OSD_APAGE_PARTITION_FIRST + 2,
- OSD_APAGE_PARTITION_TIMESTAMP = OSD_APAGE_PARTITION_FIRST + 3,
- OSD_APAGE_PARTITION_ATTR_ACCESS = OSD_APAGE_PARTITION_FIRST + 4,
- OSD_APAGE_PARTITION_SECURITY = OSD_APAGE_PARTITION_FIRST + 5,
- OSD_APAGE_PARTITION_LAST = 0x5FFFFFFF,
-
- OSD_APAGE_COLLECTION_FIRST = 0x60000000,
- OSD_APAGE_COLLECTION_DIRECTORY = OSD_APAGE_COLLECTION_FIRST + 0,
- OSD_APAGE_COLLECTION_INFORMATION = OSD_APAGE_COLLECTION_FIRST + 1,
- OSD_APAGE_COLLECTION_TIMESTAMP = OSD_APAGE_COLLECTION_FIRST + 3,
- OSD_APAGE_COLLECTION_SECURITY = OSD_APAGE_COLLECTION_FIRST + 5,
- OSD_APAGE_COLLECTION_LAST = 0x8FFFFFFF,
-
- OSD_APAGE_ROOT_FIRST = 0x90000000,
- OSD_APAGE_ROOT_DIRECTORY = OSD_APAGE_ROOT_FIRST + 0,
- OSD_APAGE_ROOT_INFORMATION = OSD_APAGE_ROOT_FIRST + 1,
- OSD_APAGE_ROOT_QUOTAS = OSD_APAGE_ROOT_FIRST + 2,
- OSD_APAGE_ROOT_TIMESTAMP = OSD_APAGE_ROOT_FIRST + 3,
- OSD_APAGE_ROOT_SECURITY = OSD_APAGE_ROOT_FIRST + 5,
- OSD_APAGE_ROOT_LAST = 0xBFFFFFFF,
-
- OSD_APAGE_RESERVED_TYPE_FIRST = 0xC0000000,
- OSD_APAGE_RESERVED_TYPE_LAST = 0xEFFFFFFF,
-
- OSD_APAGE_COMMON_FIRST = 0xF0000000,
- OSD_APAGE_COMMON_LAST = 0xFFFFFFFD,
-
- OSD_APAGE_CURRENT_COMMAND = 0xFFFFFFFE,
-
- OSD_APAGE_REQUEST_ALL = 0xFFFFFFFF,
-};
-
-/* subcategories of attr pages within each range above */
-enum {
- OSD_APAGE_STD_FIRST = 0x0,
- OSD_APAGE_STD_DIRECTORY = 0,
- OSD_APAGE_STD_INFORMATION = 1,
- OSD_APAGE_STD_QUOTAS = 2,
- OSD_APAGE_STD_TIMESTAMP = 3,
- OSD_APAGE_STD_COLLECTIONS = 4,
- OSD_APAGE_STD_POLICY_SECURITY = 5,
- OSD_APAGE_STD_LAST = 0x0000007F,
-
- OSD_APAGE_RESERVED_FIRST = 0x00000080,
- OSD_APAGE_RESERVED_LAST = 0x00007FFF,
-
- OSD_APAGE_OTHER_STD_FIRST = 0x00008000,
- OSD_APAGE_OTHER_STD_LAST = 0x0000EFFF,
-
- OSD_APAGE_PUBLIC_FIRST = 0x0000F000,
- OSD_APAGE_PUBLIC_LAST = 0x0000FFFF,
-
- OSD_APAGE_APP_DEFINED_FIRST = 0x00010000,
- OSD_APAGE_APP_DEFINED_LAST = 0x1FFFFFFF,
-
- OSD_APAGE_VENDOR_SPECIFIC_FIRST = 0x20000000,
- OSD_APAGE_VENDOR_SPECIFIC_LAST = 0x2FFFFFFF,
-};
-
-enum {
- OSD_ATTR_PAGE_IDENTIFICATION = 0, /* in all pages 40 bytes */
-};
-
-struct page_identification {
- u8 vendor_identification[8];
- u8 page_identification[32];
-} __packed;
-
-struct osd_attr_page_header {
- __be32 page_number;
- __be32 page_length;
-} __packed;
-
-/* 7.1.2.8 Root Information attributes page (OSD_APAGE_ROOT_INFORMATION) */
-enum {
- OSD_ATTR_RI_OSD_SYSTEM_ID = 0x3, /* 20 */
- OSD_ATTR_RI_VENDOR_IDENTIFICATION = 0x4, /* 8 */
- OSD_ATTR_RI_PRODUCT_IDENTIFICATION = 0x5, /* 16 */
- OSD_ATTR_RI_PRODUCT_MODEL = 0x6, /* 32 */
- OSD_ATTR_RI_PRODUCT_REVISION_LEVEL = 0x7, /* 4 */
- OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER = 0x8, /* variable */
- OSD_ATTR_RI_OSD_NAME = 0x9, /* variable */
- OSD_ATTR_RI_MAX_CDB_CONTINUATION_LEN = 0xA, /* 4 */
- OSD_ATTR_RI_TOTAL_CAPACITY = 0x80, /* 8 */
- OSD_ATTR_RI_USED_CAPACITY = 0x81, /* 8 */
- OSD_ATTR_RI_NUMBER_OF_PARTITIONS = 0xC0, /* 8 */
- OSD_ATTR_RI_CLOCK = 0x100, /* 6 */
- OARI_DEFAULT_ISOLATION_METHOD = 0X110, /* 1 */
- OARI_SUPPORTED_ISOLATION_METHODS = 0X111, /* 32 */
-
- OARI_DATA_ATOMICITY_GUARANTEE = 0X120, /* 8 */
- OARI_DATA_ATOMICITY_ALIGNMENT = 0X121, /* 8 */
- OARI_ATTRIBUTES_ATOMICITY_GUARANTEE = 0X122, /* 8 */
- OARI_DATA_ATTRIBUTES_ATOMICITY_MULTIPLIER = 0X123, /* 1 */
-
- OARI_MAXIMUM_SNAPSHOTS_COUNT = 0X1C1, /* 0 or 4 */
- OARI_MAXIMUM_CLONES_COUNT = 0X1C2, /* 0 or 4 */
- OARI_MAXIMUM_BRANCH_DEPTH = 0X1CC, /* 0 or 4 */
- OARI_SUPPORTED_OBJECT_DUPLICATION_METHOD_FIRST = 0X200, /* 0 or 4 */
- OARI_SUPPORTED_OBJECT_DUPLICATION_METHOD_LAST = 0X2ff, /* 0 or 4 */
- OARI_SUPPORTED_TIME_OF_DUPLICATION_METHOD_FIRST = 0X300, /* 0 or 4 */
- OARI_SUPPORTED_TIME_OF_DUPLICATION_METHOD_LAST = 0X30F, /* 0 or 4 */
- OARI_SUPPORT_FOR_DUPLICATED_OBJECT_FREEZING = 0X310, /* 0 or 4 */
- OARI_SUPPORT_FOR_SNAPSHOT_REFRESHING = 0X311, /* 0 or 1 */
- OARI_SUPPORTED_CDB_CONTINUATION_DESC_TYPE_FIRST = 0X7000001,/* 0 or 4 */
- OARI_SUPPORTED_CDB_CONTINUATION_DESC_TYPE_LAST = 0X700FFFF,/* 0 or 4 */
-};
-/* Root_Information_attributes_page does not have a get_page structure */
-
-/* 7.1.2.9 Partition Information attributes page
- * (OSD_APAGE_PARTITION_INFORMATION)
- */
-enum {
- OSD_ATTR_PI_PARTITION_ID = 0x1, /* 8 */
- OSD_ATTR_PI_USERNAME = 0x9, /* variable */
- OSD_ATTR_PI_USED_CAPACITY = 0x81, /* 8 */
- OSD_ATTR_PI_USED_CAPACITY_INCREMENT = 0x84, /* 0 or 8 */
- OSD_ATTR_PI_NUMBER_OF_OBJECTS = 0xC1, /* 8 */
-
- OSD_ATTR_PI_ACTUAL_DATA_SPACE = 0xD1, /* 0 or 8 */
- OSD_ATTR_PI_RESERVED_DATA_SPACE = 0xD2, /* 0 or 8 */
- OSD_ATTR_PI_DEFAULT_SNAPSHOT_DUPLICATION_METHOD = 0x200,/* 0 or 4 */
- OSD_ATTR_PI_DEFAULT_CLONE_DUPLICATION_METHOD = 0x201,/* 0 or 4 */
- OSD_ATTR_PI_DEFAULT_SP_TIME_OF_DUPLICATION = 0x300,/* 0 or 4 */
- OSD_ATTR_PI_DEFAULT_CLONE_TIME_OF_DUPLICATION = 0x301,/* 0 or 4 */
-};
-/* Partition Information attributes page does not have a get_page structure */
-
-/* 7.1.2.10 Collection Information attributes page
- * (OSD_APAGE_COLLECTION_INFORMATION)
- */
-enum {
- OSD_ATTR_CI_PARTITION_ID = 0x1, /* 8 */
- OSD_ATTR_CI_COLLECTION_OBJECT_ID = 0x2, /* 8 */
- OSD_ATTR_CI_USERNAME = 0x9, /* variable */
- OSD_ATTR_CI_COLLECTION_TYPE = 0xA, /* 1 */
- OSD_ATTR_CI_USED_CAPACITY = 0x81, /* 8 */
-};
-/* Collection Information attributes page does not have a get_page structure */
-
-/* 7.1.2.11 User Object Information attributes page
- * (OSD_APAGE_OBJECT_INFORMATION)
- */
-enum {
- OSD_ATTR_OI_PARTITION_ID = 0x1, /* 8 */
- OSD_ATTR_OI_OBJECT_ID = 0x2, /* 8 */
- OSD_ATTR_OI_USERNAME = 0x9, /* variable */
- OSD_ATTR_OI_USED_CAPACITY = 0x81, /* 8 */
- OSD_ATTR_OI_LOGICAL_LENGTH = 0x82, /* 8 */
- SD_ATTR_OI_ACTUAL_DATA_SPACE = 0XD1, /* 0 OR 8 */
- SD_ATTR_OI_RESERVED_DATA_SPACE = 0XD2, /* 0 OR 8 */
-};
-/* Object Information attributes page does not have a get_page structure */
-
-/* 7.1.2.12 Root Quotas attributes page (OSD_APAGE_ROOT_QUOTAS) */
-enum {
- OSD_ATTR_RQ_DEFAULT_MAXIMUM_USER_OBJECT_LENGTH = 0x1, /* 8 */
- OSD_ATTR_RQ_PARTITION_CAPACITY_QUOTA = 0x10001, /* 8 */
- OSD_ATTR_RQ_PARTITION_OBJECT_COUNT = 0x10002, /* 8 */
- OSD_ATTR_RQ_PARTITION_COLLECTIONS_PER_USER_OBJECT = 0x10081, /* 4 */
- OSD_ATTR_RQ_PARTITION_COUNT = 0x20002, /* 8 */
-};
-
-struct Root_Quotas_attributes_page {
- struct osd_attr_page_header hdr; /* id=R+2, size=0x24 */
- __be64 default_maximum_user_object_length;
- __be64 partition_capacity_quota;
- __be64 partition_object_count;
- __be64 partition_collections_per_user_object;
- __be64 partition_count;
-} __packed;
-
-/* 7.1.2.13 Partition Quotas attributes page (OSD_APAGE_PARTITION_QUOTAS)*/
-enum {
- OSD_ATTR_PQ_DEFAULT_MAXIMUM_USER_OBJECT_LENGTH = 0x1, /* 8 */
- OSD_ATTR_PQ_CAPACITY_QUOTA = 0x10001, /* 8 */
- OSD_ATTR_PQ_OBJECT_COUNT = 0x10002, /* 8 */
- OSD_ATTR_PQ_COLLECTIONS_PER_USER_OBJECT = 0x10081, /* 4 */
-};
-
-struct Partition_Quotas_attributes_page {
- struct osd_attr_page_header hdr; /* id=P+2, size=0x1C */
- __be64 default_maximum_user_object_length;
- __be64 capacity_quota;
- __be64 object_count;
- __be64 collections_per_user_object;
-} __packed;
-
-/* 7.1.2.14 User Object Quotas attributes page (OSD_APAGE_OBJECT_QUOTAS) */
-enum {
- OSD_ATTR_OQ_MAXIMUM_LENGTH = 0x1, /* 8 */
-};
-
-struct Object_Quotas_attributes_page {
- struct osd_attr_page_header hdr; /* id=U+2, size=0x8 */
- __be64 maximum_length;
-} __packed;
-
-/* 7.1.2.15 Root Timestamps attributes page (OSD_APAGE_ROOT_TIMESTAMP) */
-enum {
- OSD_ATTR_RT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */
- OSD_ATTR_RT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */
- OSD_ATTR_RT_TIMESTAMP_BYPASS = 0xFFFFFFFE, /* 1 */
-};
-
-struct root_timestamps_attributes_page {
- struct osd_attr_page_header hdr; /* id=R+3, size=0xD */
- struct osd_timestamp attributes_accessed_time;
- struct osd_timestamp attributes_modified_time;
- u8 timestamp_bypass;
-} __packed;
-
-/* 7.1.2.16 Partition Timestamps attributes page
- * (OSD_APAGE_PARTITION_TIMESTAMP)
- */
-enum {
- OSD_ATTR_PT_CREATED_TIME = 0x1, /* 6 */
- OSD_ATTR_PT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */
- OSD_ATTR_PT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */
- OSD_ATTR_PT_DATA_ACCESSED_TIME = 0x4, /* 6 */
- OSD_ATTR_PT_DATA_MODIFIED_TIME = 0x5, /* 6 */
- OSD_ATTR_PT_TIMESTAMP_BYPASS = 0xFFFFFFFE, /* 1 */
-};
-
-struct partition_timestamps_attributes_page {
- struct osd_attr_page_header hdr; /* id=P+3, size=0x1F */
- struct osd_timestamp created_time;
- struct osd_timestamp attributes_accessed_time;
- struct osd_timestamp attributes_modified_time;
- struct osd_timestamp data_accessed_time;
- struct osd_timestamp data_modified_time;
- u8 timestamp_bypass;
-} __packed;
-
-/* 7.1.2.17/18 Collection/Object Timestamps attributes page
- * (OSD_APAGE_COLLECTION_TIMESTAMP/OSD_APAGE_OBJECT_TIMESTAMP)
- */
-enum {
- OSD_ATTR_OT_CREATED_TIME = 0x1, /* 6 */
- OSD_ATTR_OT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */
- OSD_ATTR_OT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */
- OSD_ATTR_OT_DATA_ACCESSED_TIME = 0x4, /* 6 */
- OSD_ATTR_OT_DATA_MODIFIED_TIME = 0x5, /* 6 */
-};
-
-/* same for collection */
-struct object_timestamps_attributes_page {
- struct osd_attr_page_header hdr; /* id=C+3/3, size=0x1E */
- struct osd_timestamp created_time;
- struct osd_timestamp attributes_accessed_time;
- struct osd_timestamp attributes_modified_time;
- struct osd_timestamp data_accessed_time;
- struct osd_timestamp data_modified_time;
-} __packed;
-
-/* OSD2r05: 7.1.3.19 Attributes Access attributes page
- * (OSD_APAGE_PARTITION_ATTR_ACCESS)
- *
- * each attribute is of the form below. Total array length is deduced
- * from the attribute's length
- * (See allowed_attributes_access of the struct osd_cap_object_descriptor)
- */
-struct attributes_access_attr {
- struct osd_attributes_list_attrid attr_list[0];
-} __packed;
-
-/* OSD2r05: 7.1.2.21 Collections attributes page */
-/* TBD */
-
-/* 7.1.2.20 Root Policy/Security attributes page (OSD_APAGE_ROOT_SECURITY) */
-enum {
- OSD_ATTR_RS_DEFAULT_SECURITY_METHOD = 0x1, /* 1 */
- OSD_ATTR_RS_OLDEST_VALID_NONCE_LIMIT = 0x2, /* 6 */
- OSD_ATTR_RS_NEWEST_VALID_NONCE_LIMIT = 0x3, /* 6 */
- OSD_ATTR_RS_PARTITION_DEFAULT_SECURITY_METHOD = 0x6, /* 1 */
- OSD_ATTR_RS_SUPPORTED_SECURITY_METHODS = 0x7, /* 2 */
- OSD_ATTR_RS_ADJUSTABLE_CLOCK = 0x9, /* 6 */
- OSD_ATTR_RS_MASTER_KEY_IDENTIFIER = 0x7FFD, /* 0 or 7 */
- OSD_ATTR_RS_ROOT_KEY_IDENTIFIER = 0x7FFE, /* 0 or 7 */
- OSD_ATTR_RS_SUPPORTED_INTEGRITY_ALGORITHM_0 = 0x80000000,/* 1,(x16)*/
- OSD_ATTR_RS_SUPPORTED_DH_GROUP_0 = 0x80000010,/* 1,(x16)*/
-};
-
-struct root_security_attributes_page {
- struct osd_attr_page_header hdr; /* id=R+5, size=0x3F */
- u8 default_security_method;
- u8 partition_default_security_method;
- __be16 supported_security_methods;
- u8 mki_valid_rki_valid;
- struct osd_timestamp oldest_valid_nonce_limit;
- struct osd_timestamp newest_valid_nonce_limit;
- struct osd_timestamp adjustable_clock;
- u8 master_key_identifier[32-25];
- u8 root_key_identifier[39-32];
- u8 supported_integrity_algorithm[16];
- u8 supported_dh_group[16];
-} __packed;
-
-/* 7.1.2.21 Partition Policy/Security attributes page
- * (OSD_APAGE_PARTITION_SECURITY)
- */
-enum {
- OSD_ATTR_PS_DEFAULT_SECURITY_METHOD = 0x1, /* 1 */
- OSD_ATTR_PS_OLDEST_VALID_NONCE = 0x2, /* 6 */
- OSD_ATTR_PS_NEWEST_VALID_NONCE = 0x3, /* 6 */
- OSD_ATTR_PS_REQUEST_NONCE_LIST_DEPTH = 0x4, /* 2 */
- OSD_ATTR_PS_FROZEN_WORKING_KEY_BIT_MASK = 0x5, /* 2 */
- OSD_ATTR_PS_PARTITION_KEY_IDENTIFIER = 0x7FFF, /* 0 or 7 */
- OSD_ATTR_PS_WORKING_KEY_IDENTIFIER_FIRST = 0x8000, /* 0 or 7 */
- OSD_ATTR_PS_WORKING_KEY_IDENTIFIER_LAST = 0x800F, /* 0 or 7 */
- OSD_ATTR_PS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */
- OSD_ATTR_PS_USER_OBJECT_POLICY_ACCESS_TAG = 0x40000002, /* 4 */
-};
-
-struct partition_security_attributes_page {
- struct osd_attr_page_header hdr; /* id=p+5, size=0x8f */
- u8 reserved[3];
- u8 default_security_method;
- struct osd_timestamp oldest_valid_nonce;
- struct osd_timestamp newest_valid_nonce;
- __be16 request_nonce_list_depth;
- __be16 frozen_working_key_bit_mask;
- __be32 policy_access_tag;
- __be32 user_object_policy_access_tag;
- u8 pki_valid;
- __be16 wki_00_0f_vld;
- struct osd_key_identifier partition_key_identifier;
- struct osd_key_identifier working_key_identifiers[16];
-} __packed;
-
-/* 7.1.2.22/23 Collection/Object Policy-Security attributes page
- * (OSD_APAGE_COLLECTION_SECURITY/OSD_APAGE_OBJECT_SECURITY)
- */
-enum {
- OSD_ATTR_OS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */
-};
-
-struct object_security_attributes_page {
- struct osd_attr_page_header hdr; /* id=C+5/5, size=4 */
- __be32 policy_access_tag;
-} __packed;
-
-/* OSD2r05: 7.1.3.31 Current Command attributes page
- * (OSD_APAGE_CURRENT_COMMAND)
- */
-enum {
- OSD_ATTR_CC_RESPONSE_INTEGRITY_CHECK_VALUE = 0x1, /* 32 */
- OSD_ATTR_CC_OBJECT_TYPE = 0x2, /* 1 */
- OSD_ATTR_CC_PARTITION_ID = 0x3, /* 8 */
- OSD_ATTR_CC_OBJECT_ID = 0x4, /* 8 */
- OSD_ATTR_CC_STARTING_BYTE_ADDRESS_OF_APPEND = 0x5, /* 8 */
- OSD_ATTR_CC_CHANGE_IN_USED_CAPACITY = 0x6, /* 8 */
-};
-
-/*TBD: osdv1_current_command_attributes_page */
-
-struct osdv2_current_command_attributes_page {
- struct osd_attr_page_header hdr; /* id=0xFFFFFFFE, size=0x44 */
- u8 response_integrity_check_value[OSD_CRYPTO_KEYID_SIZE];
- u8 object_type;
- u8 reserved[3];
- __be64 partition_id;
- __be64 object_id;
- __be64 starting_byte_address_of_append;
- __be64 change_in_used_capacity;
-};
-
-#endif /*ndef __OSD_ATTRIBUTES_H__*/
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
deleted file mode 100644
index 86a569d008b2..000000000000
--- a/include/scsi/osd_initiator.h
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * osd_initiator.h - OSD initiator API definition
- *
- * Copyright (C) 2008 Panasas Inc. All rights reserved.
- *
- * Authors:
- * Boaz Harrosh <ooo@electrozaur.com>
- * Benny Halevy <bhalevy@panasas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- *
- */
-#ifndef __OSD_INITIATOR_H__
-#define __OSD_INITIATOR_H__
-
-#include <scsi/osd_protocol.h>
-#include <scsi/osd_types.h>
-
-#include <linux/blkdev.h>
-#include <scsi/scsi_device.h>
-
-/* Note: "NI" in comments below means "Not Implemented yet" */
-
-/* Configure of code:
- * #undef if you *don't* want OSD v1 support in runtime.
- * If #defined the initiator will dynamically configure to encode OSD v1
- * CDB's if the target is detected to be OSD v1 only.
- * OSD v2 only commands, options, and attributes will be ignored if target
- * is v1 only.
- * If #defined will result in bigger/slower code (OK Slower maybe not)
- * Q: Should this be CONFIG_SCSI_OSD_VER1_SUPPORT and set from Kconfig?
- */
-#define OSD_VER1_SUPPORT y
-
-enum osd_std_version {
- OSD_VER_NONE = 0,
- OSD_VER1 = 1,
- OSD_VER2 = 2,
-};
-
-/*
- * Object-based Storage Device.
- * This object represents an OSD device.
- * It is not a full linux device in any way. It is only
- * a place to hang resources associated with a Linux
- * request Q and some default properties.
- */
-struct osd_dev {
- struct scsi_device *scsi_device;
- unsigned def_timeout;
-
-#ifdef OSD_VER1_SUPPORT
- enum osd_std_version version;
-#endif
-};
-
-/* Unique Identification of an OSD device */
-struct osd_dev_info {
- unsigned systemid_len;
- u8 systemid[OSD_SYSTEMID_LEN];
- unsigned osdname_len;
- u8 *osdname;
-};
-
-/* Retrieve/return osd_dev(s) for use by Kernel clients
- * Use IS_ERR/ERR_PTR on returned "osd_dev *".
- */
-struct osd_dev *osduld_path_lookup(const char *dev_name);
-struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi);
-void osduld_put_device(struct osd_dev *od);
-
-const struct osd_dev_info *osduld_device_info(struct osd_dev *od);
-bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi);
-
-/* Add/remove test ioctls from external modules */
-typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg);
-int osduld_register_test(unsigned ioctl, do_test_fn *do_test);
-void osduld_unregister_test(unsigned ioctl);
-
-/* These are called by uld at probe time */
-void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
-void osd_dev_fini(struct osd_dev *od);
-
-/**
- * osd_auto_detect_ver - Detect the OSD version, return Unique Identification
- *
- * @od: OSD target lun handle
- * @caps: Capabilities authorizing OSD root read attributes access
- * @odi: Retrieved information uniquely identifying the osd target lun
- * Note: odi->osdname must be kfreed by caller.
- *
- * Auto detects the OSD version of the OSD target and sets the @od
- * accordingly. Meanwhile also returns the "system id" and "osd name" root
- * attributes which uniquely identify the OSD target. This member is usually
- * called by the ULD. ULD users should call osduld_device_info().
- * This rutine allocates osd requests and memory at GFP_KERNEL level and might
- * sleep.
- */
-int osd_auto_detect_ver(struct osd_dev *od,
- void *caps, struct osd_dev_info *odi);
-
-static inline struct request_queue *osd_request_queue(struct osd_dev *od)
-{
- return od->scsi_device->request_queue;
-}
-
-/* we might want to use function vector in the future */
-static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v)
-{
-#ifdef OSD_VER1_SUPPORT
- od->version = v;
-#endif
-}
-
-static inline bool osd_dev_is_ver1(struct osd_dev *od)
-{
-#ifdef OSD_VER1_SUPPORT
- return od->version == OSD_VER1;
-#else
- return false;
-#endif
-}
-
-struct osd_request;
-typedef void (osd_req_done_fn)(struct osd_request *or, void *private);
-
-struct osd_request {
- struct osd_cdb cdb;
- struct osd_data_out_integrity_info out_data_integ;
- struct osd_data_in_integrity_info in_data_integ;
-
- struct osd_dev *osd_dev;
- struct request *request;
-
- struct _osd_req_data_segment {
- void *buff;
- unsigned alloc_size; /* 0 here means: don't call kfree */
- unsigned total_bytes;
- } cdb_cont, set_attr, enc_get_attr, get_attr;
-
- struct _osd_io_info {
- struct bio *bio;
- u64 total_bytes;
- u64 residual;
- struct request *req;
- struct _osd_req_data_segment *last_seg;
- u8 *pad_buff;
- } out, in;
-
- unsigned timeout;
- unsigned retries;
- unsigned sense_len;
- u8 sense[OSD_MAX_SENSE_LEN];
- enum osd_attributes_mode attributes_mode;
-
- osd_req_done_fn *async_done;
- void *async_private;
- blk_status_t async_error;
- int req_errors;
-};
-
-static inline bool osd_req_is_ver1(struct osd_request *or)
-{
- return osd_dev_is_ver1(or->osd_dev);
-}
-
-/*
- * How to use the osd library:
- *
- * osd_start_request
- * Allocates a request.
- *
- * osd_req_*
- * Call one of, to encode the desired operation.
- *
- * osd_add_{get,set}_attr
- * Optionally add attributes to the CDB, list or page mode.
- *
- * osd_finalize_request
- * Computes final data out/in offsets and signs the request,
- * making it ready for execution.
- *
- * osd_execute_request
- * May be called to execute it through the block layer. Other wise submit
- * the associated block request in some other way.
- *
- * After execution:
- * osd_req_decode_sense
- * Decodes sense information to verify execution results.
- *
- * osd_req_decode_get_attr
- * Retrieve osd_add_get_attr_list() values if used.
- *
- * osd_end_request
- * Must be called to deallocate the request.
- */
-
-/**
- * osd_start_request - Allocate and initialize an osd_request
- *
- * @osd_dev: OSD device that holds the scsi-device and default values
- * that the request is associated with.
- *
- * Allocate osd_request and initialize all members to the
- * default/initial state.
- */
-struct osd_request *osd_start_request(struct osd_dev *od);
-
-enum osd_req_options {
- OSD_REQ_FUA = 0x08, /* Force Unit Access */
- OSD_REQ_DPO = 0x10, /* Disable Page Out */
-
- OSD_REQ_BYPASS_TIMESTAMPS = 0x80,
-};
-
-/**
- * osd_finalize_request - Sign request and prepare request for execution
- *
- * @or: osd_request to prepare
- * @options: combination of osd_req_options bit flags or 0.
- * @cap: A Pointer to an OSD_CAP_LEN bytes buffer that is received from
- * The security manager as capabilities for this cdb.
- * @cap_key: The cryptographic key used to sign the cdb/data. Can be null
- * if NOSEC is used.
- *
- * The actual request and bios are only allocated here, so are the get_attr
- * buffers that will receive the returned attributes. Copy's @cap to cdb.
- * Sign the cdb/data with @cap_key.
- */
-int osd_finalize_request(struct osd_request *or,
- u8 options, const void *cap, const u8 *cap_key);
-
-/**
- * osd_execute_request - Execute the request synchronously through block-layer
- *
- * @or: osd_request to Executed
- *
- * Calls blk_execute_rq to q the command and waits for completion.
- */
-int osd_execute_request(struct osd_request *or);
-
-/**
- * osd_execute_request_async - Execute the request without waitting.
- *
- * @or: - osd_request to Executed
- * @done: (Optional) - Called at end of execution
- * @private: - Will be passed to @done function
- *
- * Calls blk_execute_rq_nowait to queue the command. When execution is done
- * optionally calls @done with @private as parameter. @or->async_error will
- * have the return code
- */
-int osd_execute_request_async(struct osd_request *or,
- osd_req_done_fn *done, void *private);
-
-/**
- * osd_req_decode_sense_full - Decode sense information after execution.
- *
- * @or: - osd_request to examine
- * @osi - Receives a more detailed error report information (optional).
- * @silent - Do not print to dmsg (Even if enabled)
- * @bad_obj_list - Some commands act on multiple objects. Failed objects will
- * be received here (optional)
- * @max_obj - Size of @bad_obj_list.
- * @bad_attr_list - List of failing attributes (optional)
- * @max_attr - Size of @bad_attr_list.
- *
- * After execution, osd_request results are analyzed using this function. The
- * return code is the final disposition on the error. So it is possible that a
- * CHECK_CONDITION was returned from target but this will return NO_ERROR, for
- * example on recovered errors. All parameters are optional if caller does
- * not need any returned information.
- * Note: This function will also dump the error to dmsg according to settings
- * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the
- * command would routinely fail, to not spam the dmsg file.
- */
-
-/**
- * osd_err_priority - osd categorized return codes in ascending severity.
- *
- * The categories are borrowed from the pnfs_osd_errno enum.
- * See comments for translated Linux codes returned by osd_req_decode_sense.
- */
-enum osd_err_priority {
- OSD_ERR_PRI_NO_ERROR = 0,
- /* Recoverable, caller should clear_highpage() all pages */
- OSD_ERR_PRI_CLEAR_PAGES = 1, /* -EFAULT */
- OSD_ERR_PRI_RESOURCE = 2, /* -ENOMEM */
- OSD_ERR_PRI_BAD_CRED = 3, /* -EINVAL */
- OSD_ERR_PRI_NO_ACCESS = 4, /* -EACCES */
- OSD_ERR_PRI_UNREACHABLE = 5, /* any other */
- OSD_ERR_PRI_NOT_FOUND = 6, /* -ENOENT */
- OSD_ERR_PRI_NO_SPACE = 7, /* -ENOSPC */
- OSD_ERR_PRI_EIO = 8, /* -EIO */
-};
-
-struct osd_sense_info {
- enum osd_err_priority osd_err_pri;
-
- int key; /* one of enum scsi_sense_keys */
- int additional_code ; /* enum osd_additional_sense_codes */
- union { /* Sense specific information */
- u16 sense_info;
- u16 cdb_field_offset; /* scsi_invalid_field_in_cdb */
- };
- union { /* Command specific information */
- u64 command_info;
- };
-
- u32 not_initiated_command_functions; /* osd_command_functions_bits */
- u32 completed_command_functions; /* osd_command_functions_bits */
- struct osd_obj_id obj;
- struct osd_attr attr;
-};
-
-int osd_req_decode_sense_full(struct osd_request *or,
- struct osd_sense_info *osi, bool silent,
- struct osd_obj_id *bad_obj_list, int max_obj,
- struct osd_attr *bad_attr_list, int max_attr);
-
-static inline int osd_req_decode_sense(struct osd_request *or,
- struct osd_sense_info *osi)
-{
- return osd_req_decode_sense_full(or, osi, false, NULL, 0, NULL, 0);
-}
-
-/**
- * osd_end_request - return osd_request to free store
- *
- * @or: osd_request to free
- *
- * Deallocate all osd_request resources (struct req's, BIOs, buffers, etc.)
- */
-void osd_end_request(struct osd_request *or);
-
-/*
- * CDB Encoding
- *
- * Note: call only one of the following methods.
- */
-
-/*
- * Device commands
- */
-void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */
-void osd_req_set_master_key(struct osd_request *or, ...);/* NI */
-
-void osd_req_format(struct osd_request *or, u64 tot_capacity);
-
-/* list all partitions
- * @list header must be initialized to zero on first run.
- *
- * Call osd_is_obj_list_done() to find if we got the complete list.
- */
-int osd_req_list_dev_partitions(struct osd_request *or,
- osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem);
-
-void osd_req_flush_obsd(struct osd_request *or,
- enum osd_options_flush_scope_values);
-
-void osd_req_perform_scsi_command(struct osd_request *or,
- const u8 *cdb, ...);/* NI */
-void osd_req_task_management(struct osd_request *or, ...);/* NI */
-
-/*
- * Partition commands
- */
-void osd_req_create_partition(struct osd_request *or, osd_id partition);
-void osd_req_remove_partition(struct osd_request *or, osd_id partition);
-
-void osd_req_set_partition_key(struct osd_request *or,
- osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
- u8 seed[OSD_CRYPTO_SEED_SIZE]);/* NI */
-
-/* list all collections in the partition
- * @list header must be init to zero on first run.
- *
- * Call osd_is_obj_list_done() to find if we got the complete list.
- */
-int osd_req_list_partition_collections(struct osd_request *or,
- osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
- unsigned nelem);
-
-/* list all objects in the partition
- * @list header must be init to zero on first run.
- *
- * Call osd_is_obj_list_done() to find if we got the complete list.
- */
-int osd_req_list_partition_objects(struct osd_request *or,
- osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
- unsigned nelem);
-
-void osd_req_flush_partition(struct osd_request *or,
- osd_id partition, enum osd_options_flush_scope_values);
-
-/*
- * Collection commands
- */
-void osd_req_create_collection(struct osd_request *or,
- const struct osd_obj_id *);/* NI */
-void osd_req_remove_collection(struct osd_request *or,
- const struct osd_obj_id *);/* NI */
-
-/* list all objects in the collection */
-int osd_req_list_collection_objects(struct osd_request *or,
- const struct osd_obj_id *, osd_id initial_id,
- struct osd_obj_id_list *list, unsigned nelem);
-
-/* V2 only filtered list of objects in the collection */
-void osd_req_query(struct osd_request *or, ...);/* NI */
-
-void osd_req_flush_collection(struct osd_request *or,
- const struct osd_obj_id *, enum osd_options_flush_scope_values);
-
-void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */
-void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */
-
-/*
- * Object commands
- */
-void osd_req_create_object(struct osd_request *or, struct osd_obj_id *);
-void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *);
-
-void osd_req_write(struct osd_request *or,
- const struct osd_obj_id *obj, u64 offset, struct bio *bio, u64 len);
-int osd_req_write_kern(struct osd_request *or,
- const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
-void osd_req_append(struct osd_request *or,
- const struct osd_obj_id *, struct bio *data_out);/* NI */
-void osd_req_create_write(struct osd_request *or,
- const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */
-void osd_req_clear(struct osd_request *or,
- const struct osd_obj_id *, u64 offset, u64 len);/* NI */
-void osd_req_punch(struct osd_request *or,
- const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */
-
-void osd_req_flush_object(struct osd_request *or,
- const struct osd_obj_id *, enum osd_options_flush_scope_values,
- /*V2*/ u64 offset, /*V2*/ u64 len);
-
-void osd_req_read(struct osd_request *or,
- const struct osd_obj_id *obj, u64 offset, struct bio *bio, u64 len);
-int osd_req_read_kern(struct osd_request *or,
- const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
-
-/* Scatter/Gather write/read commands */
-int osd_req_write_sg(struct osd_request *or,
- const struct osd_obj_id *obj, struct bio *bio,
- const struct osd_sg_entry *sglist, unsigned numentries);
-int osd_req_read_sg(struct osd_request *or,
- const struct osd_obj_id *obj, struct bio *bio,
- const struct osd_sg_entry *sglist, unsigned numentries);
-int osd_req_write_sg_kern(struct osd_request *or,
- const struct osd_obj_id *obj, void **buff,
- const struct osd_sg_entry *sglist, unsigned numentries);
-int osd_req_read_sg_kern(struct osd_request *or,
- const struct osd_obj_id *obj, void **buff,
- const struct osd_sg_entry *sglist, unsigned numentries);
-
-/*
- * Root/Partition/Collection/Object Attributes commands
- */
-
-/* get before set */
-void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *);
-
-/* set before get */
-void osd_req_set_attributes(struct osd_request *or, const struct osd_obj_id *);
-
-/*
- * Attributes appended to most commands
- */
-
-/* Attributes List mode (or V2 CDB) */
- /*
- * TODO: In ver2 if at finalize time only one attr was set and no gets,
- * then the Attributes CDB mode is used automatically to save IO.
- */
-
-/* set a list of attributes. */
-int osd_req_add_set_attr_list(struct osd_request *or,
- const struct osd_attr *, unsigned nelem);
-
-/* get a list of attributes */
-int osd_req_add_get_attr_list(struct osd_request *or,
- const struct osd_attr *, unsigned nelem);
-
-/*
- * Attributes list decoding
- * Must be called after osd_request.request was executed
- * It is called in a loop to decode the returned get_attr
- * (see osd_add_get_attr)
- */
-int osd_req_decode_get_attr_list(struct osd_request *or,
- struct osd_attr *, int *nelem, void **iterator);
-
-/* Attributes Page mode */
-
-/*
- * Read an attribute page and optionally set one attribute
- *
- * Retrieves the attribute page directly to a user buffer.
- * @attr_page_data shall stay valid until end of execution.
- * See osd_attributes.h for common page structures
- */
-int osd_req_add_get_attr_page(struct osd_request *or,
- u32 page_id, void *attr_page_data, unsigned max_page_len,
- const struct osd_attr *set_one);
-
-#endif /* __OSD_LIB_H__ */
diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h
deleted file mode 100644
index 7a8d2cd30328..000000000000
--- a/include/scsi/osd_ore.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2011
- * Boaz Harrosh <ooo@electrozaur.com>
- *
- * Public Declarations of the ORE API
- *
- * This file is part of the ORE (Object Raid Engine) library.
- *
- * ORE is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation. (GPL v2)
- *
- * ORE is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the ORE; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __ORE_H__
-#define __ORE_H__
-
-#include <scsi/osd_initiator.h>
-#include <scsi/osd_attributes.h>
-#include <scsi/osd_sec.h>
-#include <linux/pnfs_osd_xdr.h>
-#include <linux/bug.h>
-
-struct ore_comp {
- struct osd_obj_id obj;
- u8 cred[OSD_CAP_LEN];
-};
-
-struct ore_layout {
- /* Our way of looking at the data_map */
- enum pnfs_osd_raid_algorithm4
- raid_algorithm;
- unsigned stripe_unit;
- unsigned mirrors_p1;
-
- unsigned group_width;
- unsigned parity;
- u64 group_depth;
- unsigned group_count;
-
- /* Cached often needed calculations filled in by
- * ore_verify_layout
- */
- unsigned long max_io_length; /* Max length that should be passed to
- * ore_get_rw_state
- */
-};
-
-struct ore_dev {
- struct osd_dev *od;
-};
-
-struct ore_components {
- unsigned first_dev; /* First logical device no */
- unsigned numdevs; /* Num of devices in array */
- /* If @single_comp == EC_SINGLE_COMP, @comps points to a single
- * component. else there are @numdevs components
- */
- enum EC_COMP_USAGE {
- EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff
- } single_comp;
- struct ore_comp *comps;
-
- /* Array of pointers to ore_dev-* . User will usually have these pointed
- * too a bigger struct which contain an "ore_dev ored" member and use
- * container_of(oc->ods[i], struct foo_dev, ored) to access the bigger
- * structure.
- */
- struct ore_dev **ods;
-};
-
-/* ore_comp_dev Recievies a logical device index */
-static inline struct osd_dev *ore_comp_dev(
- const struct ore_components *oc, unsigned i)
-{
- BUG_ON((i < oc->first_dev) || (oc->first_dev + oc->numdevs <= i));
- return oc->ods[i - oc->first_dev]->od;
-}
-
-static inline void ore_comp_set_dev(
- struct ore_components *oc, unsigned i, struct osd_dev *od)
-{
- oc->ods[i - oc->first_dev]->od = od;
-}
-
-struct ore_striping_info {
- u64 offset;
- u64 obj_offset;
- u64 length;
- u64 first_stripe_start; /* only used in raid writes */
- u64 M; /* for truncate */
- unsigned bytes_in_stripe;
- unsigned dev;
- unsigned par_dev;
- unsigned unit_off;
- unsigned cur_pg;
- unsigned cur_comp;
- unsigned maxdevUnits;
-};
-
-struct ore_io_state;
-typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private);
-struct _ore_r4w_op {
- /* @Priv given here is passed ios->private */
- struct page * (*get_page)(void *priv, u64 page_index, bool *uptodate);
- void (*put_page)(void *priv, struct page *page);
-};
-
-struct ore_io_state {
- struct kref kref;
- struct ore_striping_info si;
-
- void *private;
- ore_io_done_fn done;
-
- struct ore_layout *layout;
- struct ore_components *oc;
-
- /* Global read/write IO*/
- loff_t offset;
- unsigned long length;
- void *kern_buff;
-
- struct page **pages;
- unsigned nr_pages;
- unsigned pgbase;
- unsigned pages_consumed;
-
- /* Attributes */
- unsigned in_attr_len;
- struct osd_attr *in_attr;
- unsigned out_attr_len;
- struct osd_attr *out_attr;
-
- bool reading;
-
- /* House keeping of Parity pages */
- bool extra_part_alloc;
- struct page **parity_pages;
- unsigned max_par_pages;
- unsigned cur_par_page;
- unsigned sgs_per_dev;
- struct __stripe_pages_2d *sp2d;
- struct ore_io_state *ios_read_4_write;
- const struct _ore_r4w_op *r4w;
-
- /* Variable array of size numdevs */
- unsigned numdevs;
- struct ore_per_dev_state {
- struct osd_request *or;
- struct bio *bio;
- loff_t offset;
- unsigned length;
- unsigned last_sgs_total;
- unsigned dev;
- struct osd_sg_entry *sglist;
- unsigned cur_sg;
- } per_dev[];
-};
-
-static inline unsigned ore_io_state_size(unsigned numdevs)
-{
- return sizeof(struct ore_io_state) +
- sizeof(struct ore_per_dev_state) * numdevs;
-}
-
-/* ore.c */
-int ore_verify_layout(unsigned total_comps, struct ore_layout *layout);
-void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
- u64 length, struct ore_striping_info *si);
-int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps,
- bool is_reading, u64 offset, u64 length,
- struct ore_io_state **ios);
-int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps,
- struct ore_io_state **ios);
-void ore_put_io_state(struct ore_io_state *ios);
-
-typedef void (*ore_on_dev_error)(struct ore_io_state *ios, struct ore_dev *od,
- unsigned dev_index, enum osd_err_priority oep,
- u64 dev_offset, u64 dev_len);
-int ore_check_io(struct ore_io_state *ios, ore_on_dev_error rep);
-
-int ore_create(struct ore_io_state *ios);
-int ore_remove(struct ore_io_state *ios);
-int ore_write(struct ore_io_state *ios);
-int ore_read(struct ore_io_state *ios);
-int ore_truncate(struct ore_layout *layout, struct ore_components *comps,
- u64 size);
-
-int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr);
-
-extern const struct osd_attr g_attr_logical_length;
-
-#endif
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h
deleted file mode 100644
index e0ca835e7bf7..000000000000
--- a/include/scsi/osd_protocol.h
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * osd_protocol.h - OSD T10 standard C definitions.
- *
- * Copyright (C) 2008 Panasas Inc. All rights reserved.
- *
- * Authors:
- * Boaz Harrosh <ooo@electrozaur.com>
- * Benny Halevy <bhalevy@panasas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- *
- * This file contains types and constants that are defined by the protocol
- * Note: All names and symbols are taken from the OSD standard's text.
- */
-#ifndef __OSD_PROTOCOL_H__
-#define __OSD_PROTOCOL_H__
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/unaligned.h>
-#include <scsi/scsi.h>
-
-enum {
- OSDv1_ADDITIONAL_CDB_LENGTH = 192,
- OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8,
- OSDv1_CAP_LEN = 80,
-
- /* Latest supported version */
- OSDv2_ADDITIONAL_CDB_LENGTH = 228,
- OSD_ADDITIONAL_CDB_LENGTH =
- OSDv2_ADDITIONAL_CDB_LENGTH,
- OSD_TOTAL_CDB_LEN = OSD_ADDITIONAL_CDB_LENGTH + 8,
- OSD_CAP_LEN = 104,
-
- OSD_SYSTEMID_LEN = 20,
- OSDv1_CRYPTO_KEYID_SIZE = 20,
- OSDv2_CRYPTO_KEYID_SIZE = 32,
- OSD_CRYPTO_KEYID_SIZE = OSDv2_CRYPTO_KEYID_SIZE,
- OSD_CRYPTO_SEED_SIZE = 4,
- OSD_CRYPTO_NONCE_SIZE = 12,
- OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */
-
- OSD_PARTITION_FIRST_ID = 0x10000,
- OSD_OBJECT_FIRST_ID = 0x10000,
-};
-
-/* (osd-r10 5.2.4)
- * osd2r03: 5.2.3 Caching control bits
- */
-enum osd_options_byte {
- OSD_CDB_FUA = 0x08, /* Force Unit Access */
- OSD_CDB_DPO = 0x10, /* Disable Page Out */
-};
-
-/*
- * osd2r03: 5.2.5 Isolation.
- * First 3 bits, V2-only.
- * Also for attr 110h "default isolation method" at Root Information page
- */
-enum osd_options_byte_isolation {
- OSD_ISOLATION_DEFAULT = 0,
- OSD_ISOLATION_NONE = 1,
- OSD_ISOLATION_STRICT = 2,
- OSD_ISOLATION_RANGE = 4,
- OSD_ISOLATION_FUNCTIONAL = 5,
- OSD_ISOLATION_VENDOR = 7,
-};
-
-/* (osd-r10: 6.7)
- * osd2r03: 6.8 FLUSH, FLUSH COLLECTION, FLUSH OSD, FLUSH PARTITION
- */
-enum osd_options_flush_scope_values {
- OSD_CDB_FLUSH_ALL = 0,
- OSD_CDB_FLUSH_ATTR_ONLY = 1,
-
- OSD_CDB_FLUSH_ALL_RECURSIVE = 2,
- /* V2-only */
- OSD_CDB_FLUSH_ALL_RANGE = 2,
-};
-
-/* osd2r03: 5.2.10 Timestamps control */
-enum {
- OSD_CDB_NORMAL_TIMESTAMPS = 0,
- OSD_CDB_BYPASS_TIMESTAMPS = 0x7f,
-};
-
-/* (osd-r10: 5.2.2.1)
- * osd2r03: 5.2.4.1 Get and set attributes CDB format selection
- * 2 bits at second nibble of command_specific_options byte
- */
-enum osd_attributes_mode {
- /* V2-only */
- OSD_CDB_SET_ONE_ATTR = 0x10,
-
- OSD_CDB_GET_ATTR_PAGE_SET_ONE = 0x20,
- OSD_CDB_GET_SET_ATTR_LISTS = 0x30,
-
- OSD_CDB_GET_SET_ATTR_MASK = 0x30,
-};
-
-/* (osd-r10: 4.12.5)
- * osd2r03: 4.14.5 Data-In and Data-Out buffer offsets
- * byte offset = mantissa * (2^(exponent+8))
- * struct {
- * unsigned mantissa: 28;
- * int exponent: 04;
- * }
- */
-typedef __be32 osd_cdb_offset;
-
-enum {
- OSD_OFFSET_UNUSED = 0xFFFFFFFF,
- OSD_OFFSET_MAX_BITS = 28,
-
- OSDv1_OFFSET_MIN_SHIFT = 8,
- OSD_OFFSET_MIN_SHIFT = 3,
- OSD_OFFSET_MAX_SHIFT = 16,
-};
-
-/* Return the smallest allowed encoded offset that contains @offset.
- *
- * The actual encoded offset returned is @offset + *padding.
- * (up to max_shift, non-inclusive)
- */
-osd_cdb_offset __osd_encode_offset(u64 offset, unsigned *padding,
- int min_shift, int max_shift);
-
-/* Minimum alignment is 256 bytes
- * Note: Seems from std v1 that exponent can be from 0+8 to 0xE+8 (inclusive)
- * which is 8 to 23 but IBM code restricts it to 16, so be it.
- */
-static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding)
-{
- return __osd_encode_offset(offset, padding,
- OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT);
-}
-
-/* Minimum 8 bytes alignment
- * Same as v1 but since exponent can be signed than a less than
- * 256 alignment can be reached with small offsets (<2GB)
- */
-static inline osd_cdb_offset osd_encode_offset_v2(u64 offset, unsigned *padding)
-{
- return __osd_encode_offset(offset, padding,
- OSD_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT);
-}
-
-/* osd2r03: 5.2.1 Overview */
-struct osd_cdb_head {
- struct scsi_varlen_cdb_hdr varlen_cdb;
-/*10*/ u8 options;
- u8 command_specific_options;
- u8 timestamp_control;
-/*13*/ u8 reserved1[3];
-/*16*/ __be64 partition;
-/*24*/ __be64 object;
-/*32*/ union { /* V1 vs V2 alignment differences */
- struct __osdv1_cdb_addr_len {
-/*32*/ __be32 list_identifier;/* Rarely used */
-/*36*/ __be64 length;
-/*44*/ __be64 start_address;
- } __packed v1;
-
- struct __osdv2_cdb_addr_len {
- /* called allocation_length in some commands */
-/*32*/ __be64 length;
-/*40*/ __be64 start_address;
- union {
-/*48*/ __be32 list_identifier;/* Rarely used */
- /* OSD2r05 5.2.5 CDB continuation length */
-/*48*/ __be32 cdb_continuation_length;
- };
- } __packed v2;
- };
-/*52*/ union { /* selected attributes mode Page/List/Single */
- struct osd_attributes_page_mode {
-/*52*/ __be32 get_attr_page;
-/*56*/ __be32 get_attr_alloc_length;
-/*60*/ osd_cdb_offset get_attr_offset;
-
-/*64*/ __be32 set_attr_page;
-/*68*/ __be32 set_attr_id;
-/*72*/ __be32 set_attr_length;
-/*76*/ osd_cdb_offset set_attr_offset;
-/*80*/ } __packed attrs_page;
-
- struct osd_attributes_list_mode {
-/*52*/ __be32 get_attr_desc_bytes;
-/*56*/ osd_cdb_offset get_attr_desc_offset;
-
-/*60*/ __be32 get_attr_alloc_length;
-/*64*/ osd_cdb_offset get_attr_offset;
-
-/*68*/ __be32 set_attr_bytes;
-/*72*/ osd_cdb_offset set_attr_offset;
- __be32 not_used;
-/*80*/ } __packed attrs_list;
-
- /* osd2r03:5.2.4.2 Set one attribute value using CDB fields */
- struct osd_attributes_cdb_mode {
-/*52*/ __be32 set_attr_page;
-/*56*/ __be32 set_attr_id;
-/*60*/ __be16 set_attr_len;
-/*62*/ u8 set_attr_val[18];
-/*80*/ } __packed attrs_cdb;
-/*52*/ u8 get_set_attributes_parameters[28];
- };
-} __packed;
-/*80*/
-
-/*160 v1*/
-struct osdv1_security_parameters {
-/*160*/u8 integrity_check_value[OSDv1_CRYPTO_KEYID_SIZE];
-/*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE];
-/*192*/osd_cdb_offset data_in_integrity_check_offset;
-/*196*/osd_cdb_offset data_out_integrity_check_offset;
-} __packed;
-/*200 v1*/
-
-/*184 v2*/
-struct osdv2_security_parameters {
-/*184*/u8 integrity_check_value[OSDv2_CRYPTO_KEYID_SIZE];
-/*216*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE];
-/*228*/osd_cdb_offset data_in_integrity_check_offset;
-/*232*/osd_cdb_offset data_out_integrity_check_offset;
-} __packed;
-/*236 v2*/
-
-struct osd_security_parameters {
- union {
- struct osdv1_security_parameters v1;
- struct osdv2_security_parameters v2;
- };
-};
-
-struct osdv1_cdb {
- struct osd_cdb_head h;
- u8 caps[OSDv1_CAP_LEN];
- struct osdv1_security_parameters sec_params;
-} __packed;
-
-struct osdv2_cdb {
- struct osd_cdb_head h;
- u8 caps[OSD_CAP_LEN];
- struct osdv2_security_parameters sec_params;
-} __packed;
-
-struct osd_cdb {
- union {
- struct osdv1_cdb v1;
- struct osdv2_cdb v2;
- u8 buff[OSD_TOTAL_CDB_LEN];
- };
-} __packed;
-
-static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb)
-{
- return (struct osd_cdb_head *)ocdb->buff;
-}
-
-/* define both version actions
- * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD
- */
-#define OSD_ACT___(Name, Num) \
- OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), \
- OSDv1_ACT_##Name = cpu_to_be16(0x8800 + Num),
-
-/* V2 only actions */
-#define OSD_ACT_V2(Name, Num) \
- OSD_ACT_##Name = cpu_to_be16(0x8880 + Num),
-
-#define OSD_ACT_V1_V2(Name, Num1, Num2) \
- OSD_ACT_##Name = cpu_to_be16(Num2), \
- OSDv1_ACT_##Name = cpu_to_be16(Num1),
-
-enum osd_service_actions {
- OSD_ACT_V2(OBJECT_STRUCTURE_CHECK, 0x00)
- OSD_ACT___(FORMAT_OSD, 0x01)
- OSD_ACT___(CREATE, 0x02)
- OSD_ACT___(LIST, 0x03)
- OSD_ACT_V2(PUNCH, 0x04)
- OSD_ACT___(READ, 0x05)
- OSD_ACT___(WRITE, 0x06)
- OSD_ACT___(APPEND, 0x07)
- OSD_ACT___(FLUSH, 0x08)
- OSD_ACT_V2(CLEAR, 0x09)
- OSD_ACT___(REMOVE, 0x0A)
- OSD_ACT___(CREATE_PARTITION, 0x0B)
- OSD_ACT___(REMOVE_PARTITION, 0x0C)
- OSD_ACT___(GET_ATTRIBUTES, 0x0E)
- OSD_ACT___(SET_ATTRIBUTES, 0x0F)
- OSD_ACT___(CREATE_AND_WRITE, 0x12)
- OSD_ACT___(CREATE_COLLECTION, 0x15)
- OSD_ACT___(REMOVE_COLLECTION, 0x16)
- OSD_ACT___(LIST_COLLECTION, 0x17)
- OSD_ACT___(SET_KEY, 0x18)
- OSD_ACT___(SET_MASTER_KEY, 0x19)
- OSD_ACT___(FLUSH_COLLECTION, 0x1A)
- OSD_ACT___(FLUSH_PARTITION, 0x1B)
- OSD_ACT___(FLUSH_OSD, 0x1C)
-
- OSD_ACT_V2(QUERY, 0x20)
- OSD_ACT_V2(REMOVE_MEMBER_OBJECTS, 0x21)
- OSD_ACT_V2(GET_MEMBER_ATTRIBUTES, 0x22)
- OSD_ACT_V2(SET_MEMBER_ATTRIBUTES, 0x23)
-
- OSD_ACT_V2(CREATE_CLONE, 0x28)
- OSD_ACT_V2(CREATE_SNAPSHOT, 0x29)
- OSD_ACT_V2(DETACH_CLONE, 0x2A)
- OSD_ACT_V2(REFRESH_SNAPSHOT_CLONE, 0x2B)
- OSD_ACT_V2(RESTORE_PARTITION_FROM_SNAPSHOT, 0x2C)
-
- OSD_ACT_V2(READ_MAP, 0x31)
- OSD_ACT_V2(READ_MAPS_COMPARE, 0x32)
-
- OSD_ACT_V1_V2(PERFORM_SCSI_COMMAND, 0x8F7E, 0x8F7C)
- OSD_ACT_V1_V2(SCSI_TASK_MANAGEMENT, 0x8F7F, 0x8F7D)
- /* 0x8F80 to 0x8FFF are Vendor specific */
-};
-
-/* osd2r03: 7.1.3.2 List entry format for retrieving attributes */
-struct osd_attributes_list_attrid {
- __be32 attr_page;
- __be32 attr_id;
-} __packed;
-
-/*
- * NOTE: v1: is not aligned.
- */
-struct osdv1_attributes_list_element {
- __be32 attr_page;
- __be32 attr_id;
- __be16 attr_bytes; /* valid bytes at attr_val without padding */
- u8 attr_val[0];
-} __packed;
-
-/*
- * osd2r03: 7.1.3.3 List entry format for retrieved attributes and
- * for setting attributes
- * NOTE: v2 is 8-bytes aligned
- */
-struct osdv2_attributes_list_element {
- __be32 attr_page;
- __be32 attr_id;
- u8 reserved[6];
- __be16 attr_bytes; /* valid bytes at attr_val without padding */
- u8 attr_val[0];
-} __packed;
-
-enum {
- OSDv1_ATTRIBUTES_ELEM_ALIGN = 1,
- OSD_ATTRIBUTES_ELEM_ALIGN = 8,
-};
-
-enum {
- OSD_ATTR_LIST_ALL_PAGES = 0xFFFFFFFF,
- OSD_ATTR_LIST_ALL_IN_PAGE = 0xFFFFFFFF,
-};
-
-static inline unsigned osdv1_attr_list_elem_size(unsigned len)
-{
- return ALIGN(len + sizeof(struct osdv1_attributes_list_element),
- OSDv1_ATTRIBUTES_ELEM_ALIGN);
-}
-
-static inline unsigned osdv2_attr_list_elem_size(unsigned len)
-{
- return ALIGN(len + sizeof(struct osdv2_attributes_list_element),
- OSD_ATTRIBUTES_ELEM_ALIGN);
-}
-
-/*
- * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values
- */
-enum osd_attr_list_types {
- OSD_ATTR_LIST_GET = 0x1, /* descriptors only */
- OSD_ATTR_LIST_SET_RETRIEVE = 0x9, /*descriptors/values variable-length*/
- OSD_V2_ATTR_LIST_MULTIPLE = 0xE, /* ver2, Multiple Objects lists*/
- OSD_V1_ATTR_LIST_CREATE_MULTIPLE = 0xF,/*ver1, used by create_multple*/
-};
-
-/* osd2r03: 7.1.3.4 Multi-object retrieved attributes format */
-struct osd_attributes_list_multi_header {
- __be64 object_id;
- u8 object_type; /* object_type enum below */
- u8 reserved[5];
- __be16 list_bytes;
- /* followed by struct osd_attributes_list_element's */
-};
-
-struct osdv1_attributes_list_header {
- u8 type; /* low 4-bit only */
- u8 pad;
- __be16 list_bytes; /* Initiator shall set to Zero. Only set by target */
- /*
- * type=9 followed by struct osd_attributes_list_element's
- * type=E followed by struct osd_attributes_list_multi_header's
- */
-} __packed;
-
-static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h)
-{
- return be16_to_cpu(h->list_bytes);
-}
-
-struct osdv2_attributes_list_header {
- u8 type; /* lower 4-bits only */
- u8 pad[3];
-/*4*/ __be32 list_bytes; /* Initiator shall set to zero. Only set by target */
- /*
- * type=9 followed by struct osd_attributes_list_element's
- * type=E followed by struct osd_attributes_list_multi_header's
- */
-} __packed;
-
-static inline unsigned osdv2_list_size(struct osdv2_attributes_list_header *h)
-{
- return be32_to_cpu(h->list_bytes);
-}
-
-/* (osd-r10 6.13)
- * osd2r03: 6.15 LIST (Table 79) LIST command parameter data.
- * for root_lstchg below
- */
-enum {
- OSD_OBJ_ID_LIST_PAR = 0x1, /* V1-only. Not used in V2 */
- OSD_OBJ_ID_LIST_LSTCHG = 0x2,
-};
-
-/*
- * osd2r03: 6.15.2 LIST command parameter data
- * (Also for LIST COLLECTION)
- */
-struct osd_obj_id_list {
- __be64 list_bytes; /* bytes in list excluding list_bytes (-8) */
- __be64 continuation_id;
- __be32 list_identifier;
- u8 pad[3];
- u8 root_lstchg;
- __be64 object_ids[0];
-} __packed;
-
-static inline bool osd_is_obj_list_done(struct osd_obj_id_list *list,
- bool *is_changed)
-{
- *is_changed = (0 != (list->root_lstchg & OSD_OBJ_ID_LIST_LSTCHG));
- return 0 != list->continuation_id;
-}
-
-/*
- * osd2r03: 4.12.4.5 The ALLDATA security method
- */
-struct osd_data_out_integrity_info {
- __be64 data_bytes;
- __be64 set_attributes_bytes;
- __be64 get_attributes_bytes;
- __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE];
-} __packed;
-
-/* Same osd_data_out_integrity_info is used for OSD2/OSD1. The only difference
- * Is the sizeof the structure since in OSD1 the last array is smaller. Use
- * below for version independent handling of this structure
- */
-static inline int osd_data_out_integrity_info_sizeof(bool is_ver1)
-{
- return sizeof(struct osd_data_out_integrity_info) -
- (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE));
-}
-
-struct osd_data_in_integrity_info {
- __be64 data_bytes;
- __be64 retrieved_attributes_bytes;
- __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE];
-} __packed;
-
-/* Same osd_data_in_integrity_info is used for OSD2/OSD1. The only difference
- * Is the sizeof the structure since in OSD1 the last array is smaller. Use
- * below for version independent handling of this structure
- */
-static inline int osd_data_in_integrity_info_sizeof(bool is_ver1)
-{
- return sizeof(struct osd_data_in_integrity_info) -
- (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE));
-}
-
-struct osd_timestamp {
- u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */
-} __packed;
-/* FIXME: define helper functions to convert to/from osd time format */
-
-/*
- * Capability & Security definitions
- * osd2r03: 4.11.2.2 Capability format
- * osd2r03: 5.2.8 Security parameters
- */
-
-struct osd_key_identifier {
- u8 id[7]; /* if you know why 7 please email ooo@electrozaur.com */
-} __packed;
-
-/* for osd_capability.format */
-enum {
- OSD_SEC_CAP_FORMAT_NO_CAPS = 0,
- OSD_SEC_CAP_FORMAT_VER1 = 1,
- OSD_SEC_CAP_FORMAT_VER2 = 2,
-};
-
-/* security_method */
-enum {
- OSD_SEC_NOSEC = 0,
- OSD_SEC_CAPKEY = 1,
- OSD_SEC_CMDRSP = 2,
- OSD_SEC_ALLDATA = 3,
-};
-
-enum object_type {
- OSD_SEC_OBJ_ROOT = 0x1,
- OSD_SEC_OBJ_PARTITION = 0x2,
- OSD_SEC_OBJ_COLLECTION = 0x40,
- OSD_SEC_OBJ_USER = 0x80,
-};
-
-enum osd_capability_bit_masks {
- OSD_SEC_CAP_APPEND = BIT(0),
- OSD_SEC_CAP_OBJ_MGMT = BIT(1),
- OSD_SEC_CAP_REMOVE = BIT(2),
- OSD_SEC_CAP_CREATE = BIT(3),
- OSD_SEC_CAP_SET_ATTR = BIT(4),
- OSD_SEC_CAP_GET_ATTR = BIT(5),
- OSD_SEC_CAP_WRITE = BIT(6),
- OSD_SEC_CAP_READ = BIT(7),
-
- OSD_SEC_CAP_NONE1 = BIT(8),
- OSD_SEC_CAP_NONE2 = BIT(9),
- OSD_SEC_GBL_REM = BIT(10), /*v2 only*/
- OSD_SEC_CAP_QUERY = BIT(11), /*v2 only*/
- OSD_SEC_CAP_M_OBJECT = BIT(12), /*v2 only*/
- OSD_SEC_CAP_POL_SEC = BIT(13),
- OSD_SEC_CAP_GLOBAL = BIT(14),
- OSD_SEC_CAP_DEV_MGMT = BIT(15),
-};
-
-/* for object_descriptor_type (hi nibble used) */
-enum {
- OSD_SEC_OBJ_DESC_NONE = 0, /* Not allowed */
- OSD_SEC_OBJ_DESC_OBJ = 1 << 4, /* v1: also collection */
- OSD_SEC_OBJ_DESC_PAR = 2 << 4, /* also root */
- OSD_SEC_OBJ_DESC_COL = 3 << 4, /* v2 only */
-};
-
-/* (osd-r10:4.9.2.2)
- * osd2r03:4.11.2.2 Capability format
- */
-struct osd_capability_head {
- u8 format; /* low nibble */
- u8 integrity_algorithm__key_version; /* MAKE_BYTE(integ_alg, key_ver) */
- u8 security_method;
- u8 reserved1;
-/*04*/ struct osd_timestamp expiration_time;
-/*10*/ u8 audit[20];
-/*30*/ u8 discriminator[12];
-/*42*/ struct osd_timestamp object_created_time;
-/*48*/ u8 object_type;
-/*49*/ u8 permissions_bit_mask[5];
-/*54*/ u8 reserved2;
-/*55*/ u8 object_descriptor_type; /* high nibble */
-} __packed;
-
-/*56 v1*/
-struct osdv1_cap_object_descriptor {
- union {
- struct {
-/*56*/ __be32 policy_access_tag;
-/*60*/ __be64 allowed_partition_id;
-/*68*/ __be64 allowed_object_id;
-/*76*/ __be32 reserved;
- } __packed obj_desc;
-
-/*56*/ u8 object_descriptor[24];
- };
-} __packed;
-/*80 v1*/
-
-/*56 v2*/
-struct osd_cap_object_descriptor {
- union {
- struct {
-/*56*/ __be32 allowed_attributes_access;
-/*60*/ __be32 policy_access_tag;
-/*64*/ __be16 boot_epoch;
-/*66*/ u8 reserved[6];
-/*72*/ __be64 allowed_partition_id;
-/*80*/ __be64 allowed_object_id;
-/*88*/ __be64 allowed_range_length;
-/*96*/ __be64 allowed_range_start;
- } __packed obj_desc;
-
-/*56*/ u8 object_descriptor[48];
- };
-} __packed;
-/*104 v2*/
-
-struct osdv1_capability {
- struct osd_capability_head h;
- struct osdv1_cap_object_descriptor od;
-} __packed;
-
-struct osd_capability {
- struct osd_capability_head h;
- struct osd_cap_object_descriptor od;
-} __packed;
-
-/**
- * osd_sec_set_caps - set cap-bits into the capabilities header
- *
- * @cap: The osd_capability_head to set cap bits to.
- * @bit_mask: Use an ORed list of enum osd_capability_bit_masks values
- *
- * permissions_bit_mask is unaligned use below to set into caps
- * in a version independent way
- */
-static inline void osd_sec_set_caps(struct osd_capability_head *cap,
- u16 bit_mask)
-{
- /*
- *Note: The bits above are defined LE order this is because this way
- * they can grow in the future to more then 16, and still retain
- * there constant values.
- */
- put_unaligned_le16(bit_mask, &cap->permissions_bit_mask);
-}
-
-/* osd2r05a sec 5.3: CDB continuation segment formats */
-enum osd_continuation_segment_format {
- CDB_CONTINUATION_FORMAT_V2 = 0x01,
-};
-
-struct osd_continuation_segment_header {
- u8 format;
- u8 reserved1;
- __be16 service_action;
- __be32 reserved2;
- u8 integrity_check[OSDv2_CRYPTO_KEYID_SIZE];
-} __packed;
-
-/* osd2r05a sec 5.4.1: CDB continuation descriptors */
-enum osd_continuation_descriptor_type {
- NO_MORE_DESCRIPTORS = 0x0000,
- SCATTER_GATHER_LIST = 0x0001,
- QUERY_LIST = 0x0002,
- USER_OBJECT = 0x0003,
- COPY_USER_OBJECT_SOURCE = 0x0101,
- EXTENSION_CAPABILITIES = 0xFFEE
-};
-
-struct osd_continuation_descriptor_header {
- __be16 type;
- u8 reserved;
- u8 pad_length;
- __be32 length;
-} __packed;
-
-
-/* osd2r05a sec 5.4.2: Scatter/gather list */
-struct osd_sg_list_entry {
- __be64 offset;
- __be64 len;
-};
-
-struct osd_sg_continuation_descriptor {
- struct osd_continuation_descriptor_header hdr;
- struct osd_sg_list_entry entries[];
-};
-
-#endif /* ndef __OSD_PROTOCOL_H__ */
diff --git a/include/scsi/osd_sec.h b/include/scsi/osd_sec.h
deleted file mode 100644
index 7abeb0f0db30..000000000000
--- a/include/scsi/osd_sec.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * osd_sec.h - OSD security manager API
- *
- * Copyright (C) 2008 Panasas Inc. All rights reserved.
- *
- * Authors:
- * Boaz Harrosh <ooo@electrozaur.com>
- * Benny Halevy <bhalevy@panasas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- *
- */
-#ifndef __OSD_SEC_H__
-#define __OSD_SEC_H__
-
-#include <scsi/osd_protocol.h>
-#include <scsi/osd_types.h>
-
-/*
- * Contains types and constants of osd capabilities and security
- * encoding/decoding.
- * API is trying to keep security abstract so initiator of an object
- * based pNFS client knows as little as possible about security and
- * capabilities. It is the Server's osd-initiator place to know more.
- * Also can be used by osd-target.
- */
-void osd_sec_encode_caps(void *caps, ...);/* NI */
-void osd_sec_init_nosec_doall_caps(void *caps,
- const struct osd_obj_id *obj, bool is_collection, const bool is_v1);
-
-bool osd_is_sec_alldata(struct osd_security_parameters *sec_params);
-
-/* Conditionally sign the CDB according to security setting in ocdb
- * with cap_key */
-void osd_sec_sign_cdb(struct osd_cdb *ocdb, const u8 *cap_key);
-
-/* Unconditionally sign the BIO data with cap_key.
- * Check for osd_is_sec_alldata() was done prior to calling this. */
-void osd_sec_sign_data(void *data_integ, struct bio *bio, const u8 *cap_key);
-
-/* Version independent copy of caps into the cdb */
-void osd_set_caps(struct osd_cdb *cdb, const void *caps);
-
-#endif /* ndef __OSD_SEC_H__ */
diff --git a/include/scsi/osd_sense.h b/include/scsi/osd_sense.h
deleted file mode 100644
index d52aa93a0b2d..000000000000
--- a/include/scsi/osd_sense.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * osd_sense.h - OSD Related sense handling definitions.
- *
- * Copyright (C) 2008 Panasas Inc. All rights reserved.
- *
- * Authors:
- * Boaz Harrosh <ooo@electrozaur.com>
- * Benny Halevy <bhalevy@panasas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- *
- * This file contains types and constants that are defined by the protocol
- * Note: All names and symbols are taken from the OSD standard's text.
- */
-#ifndef __OSD_SENSE_H__
-#define __OSD_SENSE_H__
-
-#include <scsi/osd_protocol.h>
-
-/* SPC3r23 4.5.6 Sense key and sense code definitions table 27 */
-enum scsi_sense_keys {
- scsi_sk_no_sense = 0x0,
- scsi_sk_recovered_error = 0x1,
- scsi_sk_not_ready = 0x2,
- scsi_sk_medium_error = 0x3,
- scsi_sk_hardware_error = 0x4,
- scsi_sk_illegal_request = 0x5,
- scsi_sk_unit_attention = 0x6,
- scsi_sk_data_protect = 0x7,
- scsi_sk_blank_check = 0x8,
- scsi_sk_vendor_specific = 0x9,
- scsi_sk_copy_aborted = 0xa,
- scsi_sk_aborted_command = 0xb,
- scsi_sk_volume_overflow = 0xd,
- scsi_sk_miscompare = 0xe,
- scsi_sk_reserved = 0xf,
-};
-
-/* SPC3r23 4.5.6 Sense key and sense code definitions table 28 */
-/* Note: only those which can be returned by an OSD target. Most of
- * these errors are taken care of by the generic scsi layer.
- */
-enum osd_additional_sense_codes {
- scsi_no_additional_sense_information = 0x0000,
- scsi_operation_in_progress = 0x0016,
- scsi_cleaning_requested = 0x0017,
- scsi_lunr_cause_not_reportable = 0x0400,
- scsi_logical_unit_is_in_process_of_becoming_ready = 0x0401,
- scsi_lunr_initializing_command_required = 0x0402,
- scsi_lunr_manual_intervention_required = 0x0403,
- scsi_lunr_operation_in_progress = 0x0407,
- scsi_lunr_selftest_in_progress = 0x0409,
- scsi_luna_asymmetric_access_state_transition = 0x040a,
- scsi_luna_target_port_in_standby_state = 0x040b,
- scsi_luna_target_port_in_unavailable_state = 0x040c,
- scsi_lunr_notify_enable_spinup_required = 0x0411,
- scsi_logical_unit_does_not_respond_to_selection = 0x0500,
- scsi_logical_unit_communication_failure = 0x0800,
- scsi_logical_unit_communication_timeout = 0x0801,
- scsi_logical_unit_communication_parity_error = 0x0802,
- scsi_error_log_overflow = 0x0a00,
- scsi_warning = 0x0b00,
- scsi_warning_specified_temperature_exceeded = 0x0b01,
- scsi_warning_enclosure_degraded = 0x0b02,
- scsi_write_error_unexpected_unsolicited_data = 0x0c0c,
- scsi_write_error_not_enough_unsolicited_data = 0x0c0d,
- scsi_invalid_information_unit = 0x0e00,
- scsi_invalid_field_in_command_information_unit = 0x0e03,
- scsi_read_error_failed_retransmission_request = 0x1113,
- scsi_parameter_list_length_error = 0x1a00,
- scsi_invalid_command_operation_code = 0x2000,
- scsi_invalid_field_in_cdb = 0x2400,
- osd_security_audit_value_frozen = 0x2404,
- osd_security_working_key_frozen = 0x2405,
- osd_nonce_not_unique = 0x2406,
- osd_nonce_timestamp_out_of_range = 0x2407,
- scsi_logical_unit_not_supported = 0x2500,
- scsi_invalid_field_in_parameter_list = 0x2600,
- scsi_parameter_not_supported = 0x2601,
- scsi_parameter_value_invalid = 0x2602,
- scsi_invalid_release_of_persistent_reservation = 0x2604,
- osd_invalid_dataout_buffer_integrity_check_value = 0x260f,
- scsi_not_ready_to_ready_change_medium_may_have_changed = 0x2800,
- scsi_power_on_reset_or_bus_device_reset_occurred = 0x2900,
- scsi_power_on_occurred = 0x2901,
- scsi_scsi_bus_reset_occurred = 0x2902,
- scsi_bus_device_reset_function_occurred = 0x2903,
- scsi_device_internal_reset = 0x2904,
- scsi_transceiver_mode_changed_to_single_ended = 0x2905,
- scsi_transceiver_mode_changed_to_lvd = 0x2906,
- scsi_i_t_nexus_loss_occurred = 0x2907,
- scsi_parameters_changed = 0x2a00,
- scsi_mode_parameters_changed = 0x2a01,
- scsi_asymmetric_access_state_changed = 0x2a06,
- scsi_priority_changed = 0x2a08,
- scsi_command_sequence_error = 0x2c00,
- scsi_previous_busy_status = 0x2c07,
- scsi_previous_task_set_full_status = 0x2c08,
- scsi_previous_reservation_conflict_status = 0x2c09,
- osd_partition_or_collection_contains_user_objects = 0x2c0a,
- scsi_commands_cleared_by_another_initiator = 0x2f00,
- scsi_cleaning_failure = 0x3007,
- scsi_enclosure_failure = 0x3400,
- scsi_enclosure_services_failure = 0x3500,
- scsi_unsupported_enclosure_function = 0x3501,
- scsi_enclosure_services_unavailable = 0x3502,
- scsi_enclosure_services_transfer_failure = 0x3503,
- scsi_enclosure_services_transfer_refused = 0x3504,
- scsi_enclosure_services_checksum_error = 0x3505,
- scsi_rounded_parameter = 0x3700,
- osd_read_past_end_of_user_object = 0x3b17,
- scsi_logical_unit_has_not_self_configured_yet = 0x3e00,
- scsi_logical_unit_failure = 0x3e01,
- scsi_timeout_on_logical_unit = 0x3e02,
- scsi_logical_unit_failed_selftest = 0x3e03,
- scsi_logical_unit_unable_to_update_selftest_log = 0x3e04,
- scsi_target_operating_conditions_have_changed = 0x3f00,
- scsi_microcode_has_been_changed = 0x3f01,
- scsi_inquiry_data_has_changed = 0x3f03,
- scsi_echo_buffer_overwritten = 0x3f0f,
- scsi_diagnostic_failure_on_component_nn_first = 0x4080,
- scsi_diagnostic_failure_on_component_nn_last = 0x40ff,
- scsi_message_error = 0x4300,
- scsi_internal_target_failure = 0x4400,
- scsi_select_or_reselect_failure = 0x4500,
- scsi_scsi_parity_error = 0x4700,
- scsi_data_phase_crc_error_detected = 0x4701,
- scsi_scsi_parity_error_detected_during_st_data_phase = 0x4702,
- scsi_asynchronous_information_protection_error_detected = 0x4704,
- scsi_protocol_service_crc_error = 0x4705,
- scsi_phy_test_function_in_progress = 0x4706,
- scsi_invalid_message_error = 0x4900,
- scsi_command_phase_error = 0x4a00,
- scsi_data_phase_error = 0x4b00,
- scsi_logical_unit_failed_self_configuration = 0x4c00,
- scsi_overlapped_commands_attempted = 0x4e00,
- osd_quota_error = 0x5507,
- scsi_failure_prediction_threshold_exceeded = 0x5d00,
- scsi_failure_prediction_threshold_exceeded_false = 0x5dff,
- scsi_voltage_fault = 0x6500,
-};
-
-enum scsi_descriptor_types {
- scsi_sense_information = 0x0,
- scsi_sense_command_specific_information = 0x1,
- scsi_sense_key_specific = 0x2,
- scsi_sense_field_replaceable_unit = 0x3,
- scsi_sense_stream_commands = 0x4,
- scsi_sense_block_commands = 0x5,
- osd_sense_object_identification = 0x6,
- osd_sense_response_integrity_check = 0x7,
- osd_sense_attribute_identification = 0x8,
- scsi_sense_ata_return = 0x9,
-
- scsi_sense_Reserved_first = 0x0A,
- scsi_sense_Reserved_last = 0x7F,
- scsi_sense_Vendor_specific_first = 0x80,
- scsi_sense_Vendor_specific_last = 0xFF,
-};
-
-struct scsi_sense_descriptor { /* for picking into desc type */
- u8 descriptor_type; /* one of enum scsi_descriptor_types */
- u8 additional_length; /* n - 1 */
- u8 data[];
-} __packed;
-
-/* OSD deploys only scsi descriptor_based sense buffers */
-struct scsi_sense_descriptor_based {
-/*0*/ u8 response_code; /* 0x72 or 0x73 */
-/*1*/ u8 sense_key; /* one of enum scsi_sense_keys (4 lower bits) */
-/*2*/ __be16 additional_sense_code; /* enum osd_additional_sense_codes */
-/*4*/ u8 Reserved[3];
-/*7*/ u8 additional_sense_length; /* n - 7 */
-/*8*/ struct scsi_sense_descriptor ssd[0]; /* variable length, 1 or more */
-} __packed;
-
-/* some descriptors deployed by OSD */
-
-/* SPC3r23 4.5.2.3 Command-specific information sense data descriptor */
-/* Note: this is the same for descriptor_type=00 but with type=00 the
- * Reserved[0] == 0x80 (ie. bit-7 set)
- */
-struct scsi_sense_command_specific_data_descriptor {
-/*0*/ u8 descriptor_type; /* (00h/01h) */
-/*1*/ u8 additional_length; /* (0Ah) */
-/*2*/ u8 Reserved[2];
-/*4*/ __be64 information;
-} __packed;
-/*12*/
-
-struct scsi_sense_key_specific_data_descriptor {
-/*0*/ u8 descriptor_type; /* (02h) */
-/*1*/ u8 additional_length; /* (06h) */
-/*2*/ u8 Reserved[2];
-/* SKSV, C/D, Reserved (2), BPV, BIT POINTER (3) */
-/*4*/ u8 sksv_cd_bpv_bp;
-/*5*/ __be16 value; /* field-pointer/progress-value/retry-count/... */
-/*7*/ u8 Reserved2;
-} __packed;
-/*8*/
-
-/* 4.16.2.1 OSD error identification sense data descriptor - table 52 */
-/* Note: these bits are defined LE order for easy definition, this way the BIT()
- * number is the same as in the documentation. Below members at
- * osd_sense_identification_data_descriptor are therefore defined __le32.
- */
-enum osd_command_functions_bits {
- OSD_CFB_COMMAND = BIT(4),
- OSD_CFB_CMD_CAP_VERIFIED = BIT(5),
- OSD_CFB_VALIDATION = BIT(7),
- OSD_CFB_IMP_ST_ATT = BIT(12),
- OSD_CFB_SET_ATT = BIT(20),
- OSD_CFB_SA_CAP_VERIFIED = BIT(21),
- OSD_CFB_GET_ATT = BIT(28),
- OSD_CFB_GA_CAP_VERIFIED = BIT(29),
-};
-
-struct osd_sense_identification_data_descriptor {
-/*0*/ u8 descriptor_type; /* (06h) */
-/*1*/ u8 additional_length; /* (1Eh) */
-/*2*/ u8 Reserved[6];
-/*8*/ __le32 not_initiated_functions; /*osd_command_functions_bits*/
-/*12*/ __le32 completed_functions; /*osd_command_functions_bits*/
-/*16*/ __be64 partition_id;
-/*24*/ __be64 object_id;
-} __packed;
-/*32*/
-
-struct osd_sense_response_integrity_check_descriptor {
-/*0*/ u8 descriptor_type; /* (07h) */
-/*1*/ u8 additional_length; /* (20h) */
-/*2*/ u8 integrity_check_value[32]; /*FIXME: OSDv2_CRYPTO_KEYID_SIZE*/
-} __packed;
-/*34*/
-
-struct osd_sense_attributes_data_descriptor {
-/*0*/ u8 descriptor_type; /* (08h) */
-/*1*/ u8 additional_length; /* (n-2) */
-/*2*/ u8 Reserved[6];
- struct osd_sense_attr {
-/*8*/ __be32 attr_page;
-/*12*/ __be32 attr_id;
-/*16*/ } sense_attrs[0]; /* 1 or more */
-} __packed;
-/*variable*/
-
-/* Dig into scsi_sk_illegal_request/scsi_invalid_field_in_cdb errors */
-
-/*FIXME: Support also field in CAPS*/
-#define OSD_CDB_OFFSET(F) offsetof(struct osd_cdb_head, F)
-
-enum osdv2_cdb_field_offset {
- OSDv1_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v1.start_address),
- OSD_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v2.start_address),
- OSD_CFO_PARTITION_ID = OSD_CDB_OFFSET(partition),
- OSD_CFO_OBJECT_ID = OSD_CDB_OFFSET(object),
- OSD_CFO_PERMISSIONS = sizeof(struct osd_cdb_head) +
- offsetof(struct osd_capability_head,
- permissions_bit_mask),
-};
-
-#endif /* ndef __OSD_SENSE_H__ */
diff --git a/include/scsi/osd_types.h b/include/scsi/osd_types.h
deleted file mode 100644
index 48e8a165e136..000000000000
--- a/include/scsi/osd_types.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * osd_types.h - Types and constants which are not part of the protocol.
- *
- * Copyright (C) 2008 Panasas Inc. All rights reserved.
- *
- * Authors:
- * Boaz Harrosh <ooo@electrozaur.com>
- * Benny Halevy <bhalevy@panasas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- *
- * Contains types and constants that are implementation specific and are
- * used by more than one part of the osd library.
- * (Eg initiator/target/security_manager/...)
- */
-#ifndef __OSD_TYPES_H__
-#define __OSD_TYPES_H__
-
-struct osd_systemid {
- u8 data[OSD_SYSTEMID_LEN];
-};
-
-typedef u64 __bitwise osd_id;
-
-struct osd_obj_id {
- osd_id partition;
- osd_id id;
-};
-
-static const struct __weak osd_obj_id osd_root_object = {0, 0};
-
-struct osd_attr {
- u32 attr_page;
- u32 attr_id;
- u16 len; /* byte count of operand */
- void *val_ptr; /* in network order */
-};
-
-struct osd_sg_entry {
- u64 offset;
- u64 len;
-};
-
-#endif /* ndef __OSD_TYPES_H__ */
diff --git a/include/scsi/sas.h b/include/scsi/sas.h
index 42a84ef42683..71b749bed3b0 100644
--- a/include/scsi/sas.h
+++ b/include/scsi/sas.h
@@ -1,26 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* SAS structures and definitions header file
*
* Copyright (C) 2005 Adaptec, Inc. All rights reserved.
* Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
- *
- * This file is licensed under GPLv2.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
*/
#ifndef _SAS_H_
@@ -112,6 +95,8 @@ enum sas_protocol {
SAS_PROTOCOL_SSP = 0x08,
SAS_PROTOCOL_ALL = 0x0E,
SAS_PROTOCOL_STP_ALL = SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA,
+ /* these are internal to libsas */
+ SAS_PROTOCOL_INTERNAL_ABORT = 0x10,
};
/* From the spec; local phys only */
@@ -208,6 +193,13 @@ enum sas_gpio_reg_type {
SAS_GPIO_REG_TX_GP = 4,
};
+/* Response frame DATAPRES field */
+enum {
+ SAS_DATAPRES_NO_DATA = 0,
+ SAS_DATAPRES_RESPONSE_DATA = 1,
+ SAS_DATAPRES_SENSE_DATA = 2,
+};
+
struct dev_to_host_fis {
u8 fis_type; /* 0x34 */
u8 flags;
@@ -340,8 +332,10 @@ struct ssp_response_iu {
__be32 sense_data_len;
__be32 response_data_len;
- u8 resp_data[0];
- u8 sense_data[0];
+ union {
+ DECLARE_FLEX_ARRAY(u8, resp_data);
+ DECLARE_FLEX_ARRAY(u8, sense_data);
+ };
} __attribute__ ((packed));
struct ssp_command_iu {
@@ -363,7 +357,7 @@ struct ssp_command_iu {
u8 add_cdb_len:6;
u8 cdb[16];
- u8 add_cdb[0];
+ u8 add_cdb[];
} __attribute__ ((packed));
struct xfer_rdy_iu {
@@ -477,18 +471,6 @@ struct report_phy_sata_resp {
__be32 crc;
} __attribute__ ((packed));
-struct smp_resp {
- u8 frame_type;
- u8 function;
- u8 result;
- u8 reserved;
- union {
- struct report_general_resp rg;
- struct discover_resp disc;
- struct report_phy_sata_resp rps;
- };
-} __attribute__ ((packed));
-
#elif defined(__BIG_ENDIAN_BITFIELD)
struct sas_identify_frame {
/* Byte 0 */
@@ -571,8 +553,10 @@ struct ssp_response_iu {
__be32 sense_data_len;
__be32 response_data_len;
- u8 resp_data[0];
- u8 sense_data[0];
+ union {
+ DECLARE_FLEX_ARRAY(u8, resp_data);
+ DECLARE_FLEX_ARRAY(u8, sense_data);
+ };
} __attribute__ ((packed));
struct ssp_command_iu {
@@ -594,7 +578,7 @@ struct ssp_command_iu {
u8 _r_c:2;
u8 cdb[16];
- u8 add_cdb[0];
+ u8 add_cdb[];
} __attribute__ ((packed));
struct xfer_rdy_iu {
@@ -708,20 +692,32 @@ struct report_phy_sata_resp {
__be32 crc;
} __attribute__ ((packed));
-struct smp_resp {
+#else
+#error "Bitfield order not defined!"
+#endif
+
+struct smp_rg_resp {
u8 frame_type;
u8 function;
u8 result;
u8 reserved;
- union {
- struct report_general_resp rg;
- struct discover_resp disc;
- struct report_phy_sata_resp rps;
- };
+ struct report_general_resp rg;
} __attribute__ ((packed));
-#else
-#error "Bitfield order not defined!"
-#endif
+struct smp_disc_resp {
+ u8 frame_type;
+ u8 function;
+ u8 result;
+ u8 reserved;
+ struct discover_resp disc;
+} __attribute__ ((packed));
+
+struct smp_rps_resp {
+ u8 frame_type;
+ u8 function;
+ u8 result;
+ u8 reserved;
+ struct report_phy_sata_resp rps;
+} __attribute__ ((packed));
#endif /* _SAS_H_ */
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
index 00f41aeeecf5..a161c0222931 100644
--- a/include/scsi/sas_ata.h
+++ b/include/scsi/sas_ata.h
@@ -1,25 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Support for SATA devices on Serial Attached SCSI (SAS) controllers
*
* Copyright (C) 2006 IBM Corporation
*
* Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
*/
#ifndef _SAS_ATA_H_
@@ -30,76 +15,55 @@
#ifdef CONFIG_SCSI_SAS_ATA
-static inline int dev_is_sata(struct domain_device *dev)
+static inline bool dev_is_sata(struct domain_device *dev)
{
- return dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM ||
- dev->dev_type == SAS_SATA_PM_PORT || dev->dev_type == SAS_SATA_PENDING;
+ switch (dev->dev_type) {
+ case SAS_SATA_DEV:
+ case SAS_SATA_PENDING:
+ case SAS_SATA_PM:
+ case SAS_SATA_PM_PORT:
+ return true;
+ default:
+ return false;
+ }
}
-int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy);
-int sas_ata_init(struct domain_device *dev);
-void sas_ata_task_abort(struct sas_task *task);
-void sas_ata_strategy_handler(struct Scsi_Host *shost);
-void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
- struct list_head *done_q);
void sas_ata_schedule_reset(struct domain_device *dev);
-void sas_ata_wait_eh(struct domain_device *dev);
-void sas_probe_sata(struct asd_sas_port *port);
-void sas_suspend_sata(struct asd_sas_port *port);
-void sas_resume_sata(struct asd_sas_port *port);
-void sas_ata_end_eh(struct ata_port *ap);
-#else
-
+void sas_ata_device_link_abort(struct domain_device *dev, bool force_reset);
+int sas_execute_ata_cmd(struct domain_device *device, u8 *fis, int force_phy_id);
+int smp_ata_check_ready_type(struct ata_link *link);
-static inline int dev_is_sata(struct domain_device *dev)
-{
- return 0;
-}
-static inline int sas_ata_init(struct domain_device *dev)
-{
- return 0;
-}
-static inline void sas_ata_task_abort(struct sas_task *task)
-{
-}
+extern const struct attribute_group sas_ata_sdev_attr_group;
-static inline void sas_ata_strategy_handler(struct Scsi_Host *shost)
-{
-}
+#else
-static inline void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
- struct list_head *done_q)
+static inline bool dev_is_sata(struct domain_device *dev)
{
+ return false;
}
static inline void sas_ata_schedule_reset(struct domain_device *dev)
{
}
-static inline void sas_ata_wait_eh(struct domain_device *dev)
+static inline void sas_ata_device_link_abort(struct domain_device *dev,
+ bool force_reset)
{
}
-static inline void sas_probe_sata(struct asd_sas_port *port)
-{
-}
-
-static inline void sas_suspend_sata(struct asd_sas_port *port)
-{
-}
-
-static inline void sas_resume_sata(struct asd_sas_port *port)
+static inline int sas_execute_ata_cmd(struct domain_device *device, u8 *fis,
+ int force_phy_id)
{
+ return 0;
}
-static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
+static inline int smp_ata_check_ready_type(struct ata_link *link)
{
return 0;
}
-static inline void sas_ata_end_eh(struct ata_port *ap)
-{
-}
+#define sas_ata_sdev_attr_group ((struct attribute_group) {})
+
#endif
#endif /* _SAS_ATA_H_ */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index eb7853c1a23b..96b350366670 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -7,10 +7,12 @@
#define _SCSI_SCSI_H
#include <linux/types.h>
-#include <linux/scatterlist.h>
-#include <linux/kernel.h>
+
+#include <asm/param.h>
+
#include <scsi/scsi_common.h>
#include <scsi/scsi_proto.h>
+#include <scsi/scsi_status.h>
struct scsi_cmnd;
@@ -30,32 +32,6 @@ enum scsi_timeouts {
*/
#define SCAN_WILD_CARD ~0
-/** scsi_status_is_good - check the status return.
- *
- * @status: the status passed up from the driver (including host and
- * driver components)
- *
- * This returns true for known good conditions that may be treated as
- * command completed normally
- */
-static inline int scsi_status_is_good(int status)
-{
- /*
- * FIXME: bit0 is listed as reserved in SCSI-2, but is
- * significant in SCSI-3. For now, we follow the SCSI-2
- * behaviour and ignore reserved bits.
- */
- status &= 0xfe;
- return ((status == SAM_STAT_GOOD) ||
- (status == SAM_STAT_CONDITION_MET) ||
- /* Next two "intermediate" statuses are obsolete in SAM-4 */
- (status == SAM_STAT_INTERMEDIATE) ||
- (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
- /* FIXME: this is obsolete in SAM-3 */
- (status == SAM_STAT_COMMAND_TERMINATED));
-}
-
-
/*
* standard mode-select header prepended to all mode-select commands
*/
@@ -88,106 +64,46 @@ static inline int scsi_is_wlun(u64 lun)
return (lun & 0xff00) == SCSI_W_LUN_BASE;
}
+/**
+ * scsi_status_is_check_condition - check the status return.
+ *
+ * @status: the status passed up from the driver (including host and
+ * driver components)
+ *
+ * Returns: %true if the status code is SAM_STAT_CHECK_CONDITION.
+ */
+static inline int scsi_status_is_check_condition(int status)
+{
+ if (status < 0)
+ return false;
+ status &= 0xfe;
+ return status == SAM_STAT_CHECK_CONDITION;
+}
/*
- * MESSAGE CODES
+ * Extended message codes.
*/
-
-#define COMMAND_COMPLETE 0x00
-#define EXTENDED_MESSAGE 0x01
#define EXTENDED_MODIFY_DATA_POINTER 0x00
#define EXTENDED_SDTR 0x01
#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */
#define EXTENDED_WDTR 0x03
#define EXTENDED_PPR 0x04
#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05
-#define SAVE_POINTERS 0x02
-#define RESTORE_POINTERS 0x03
-#define DISCONNECT 0x04
-#define INITIATOR_ERROR 0x05
-#define ABORT_TASK_SET 0x06
-#define MESSAGE_REJECT 0x07
-#define NOP 0x08
-#define MSG_PARITY_ERROR 0x09
-#define LINKED_CMD_COMPLETE 0x0a
-#define LINKED_FLG_CMD_COMPLETE 0x0b
-#define TARGET_RESET 0x0c
-#define ABORT_TASK 0x0d
-#define CLEAR_TASK_SET 0x0e
-#define INITIATE_RECOVERY 0x0f /* SCSI-II only */
-#define RELEASE_RECOVERY 0x10 /* SCSI-II only */
-#define CLEAR_ACA 0x16
-#define LOGICAL_UNIT_RESET 0x17
-#define SIMPLE_QUEUE_TAG 0x20
-#define HEAD_OF_QUEUE_TAG 0x21
-#define ORDERED_QUEUE_TAG 0x22
-#define IGNORE_WIDE_RESIDUE 0x23
-#define ACA 0x24
-#define QAS_REQUEST 0x55
-
-/* Old SCSI2 names, don't use in new code */
-#define BUS_DEVICE_RESET TARGET_RESET
-#define ABORT ABORT_TASK_SET
-
-/*
- * Host byte codes
- */
-
-#define DID_OK 0x00 /* NO error */
-#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
-#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
-#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */
-#define DID_BAD_TARGET 0x04 /* BAD target. */
-#define DID_ABORT 0x05 /* Told to abort for some other reason */
-#define DID_PARITY 0x06 /* Parity error */
-#define DID_ERROR 0x07 /* Internal error */
-#define DID_RESET 0x08 /* Reset by somebody. */
-#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */
-#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */
-#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */
-#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */
-#define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also
- * without decrementing the retry count */
-#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution
- * and the driver blocked the port to
- * recover the link. Transport class will
- * retry or fail IO */
-#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */
-#define DID_TARGET_FAILURE 0x10 /* Permanent target failure, do not retry on
- * other paths */
-#define DID_NEXUS_FAILURE 0x11 /* Permanent nexus failure, retry on other
- * paths might yield different results */
-#define DID_ALLOC_FAILURE 0x12 /* Space allocation on the device failed */
-#define DID_MEDIUM_ERROR 0x13 /* Medium error */
-#define DRIVER_OK 0x00 /* Driver status */
-
-/*
- * These indicate the error that occurred, and what is available.
- */
-
-#define DRIVER_BUSY 0x01
-#define DRIVER_SOFT 0x02
-#define DRIVER_MEDIA 0x03
-#define DRIVER_ERROR 0x04
-
-#define DRIVER_INVALID 0x05
-#define DRIVER_TIMEOUT 0x06
-#define DRIVER_HARD 0x07
-#define DRIVER_SENSE 0x08
/*
* Internal return values.
*/
-
-#define NEEDS_RETRY 0x2001
-#define SUCCESS 0x2002
-#define FAILED 0x2003
-#define QUEUED 0x2004
-#define SOFT_ERROR 0x2005
-#define ADD_TO_MLQUEUE 0x2006
-#define TIMEOUT_ERROR 0x2007
-#define SCSI_RETURN_NOT_HANDLED 0x2008
-#define FAST_IO_FAIL 0x2009
+enum scsi_disposition {
+ NEEDS_RETRY = 0x2001,
+ SUCCESS = 0x2002,
+ FAILED = 0x2003,
+ QUEUED = 0x2004,
+ SOFT_ERROR = 0x2005,
+ ADD_TO_MLQUEUE = 0x2006,
+ TIMEOUT_ERROR = 0x2007,
+ SCSI_RETURN_NOT_HANDLED = 0x2008,
+ FAST_IO_FAIL = 0x2009,
+};
/*
* Midlevel queue return values.
@@ -203,14 +119,11 @@ static inline int scsi_is_wlun(u64 lun)
* These are set by:
*
* status byte = set from target device
- * msg_byte = return status from host adapter itself.
+ * msg_byte (unused)
* host_byte = set by low-level driver to indicate status.
- * driver_byte = set by mid-level.
*/
-#define status_byte(result) (((result) >> 1) & 0x7f)
-#define msg_byte(result) (((result) >> 8) & 0xff)
+#define status_byte(result) (result & 0xff)
#define host_byte(result) (((result) >> 16) & 0xff)
-#define driver_byte(result) (((result) >> 24) & 0xff)
#define sense_class(sense) (((sense) >> 4) & 0x7)
#define sense_error(sense) ((sense) & 0xf)
@@ -245,6 +158,9 @@ static inline int scsi_is_wlun(u64 lun)
#define SCSI_3 4 /* SPC */
#define SCSI_SPC_2 5
#define SCSI_SPC_3 6
+#define SCSI_SPC_4 7
+#define SCSI_SPC_5 8
+#define SCSI_SPC_6 14
/*
* INQ PERIPHERAL QUALIFIERS
@@ -274,10 +190,36 @@ static inline int scsi_is_wlun(u64 lun)
/* Used to obtain the PCI location of a device */
#define SCSI_IOCTL_GET_PCI 0x5387
-/* Pull a u32 out of a SCSI message (using BE SCSI conventions) */
-static inline __u32 scsi_to_u32(__u8 *ptr)
+/**
+ * scsi_status_is_good - check the status return.
+ *
+ * @status: the status passed up from the driver (including host and
+ * driver components)
+ *
+ * Returns: %true for known good conditions that may be treated as
+ * command completed normally
+ */
+static inline bool scsi_status_is_good(int status)
{
- return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
+ if (status < 0)
+ return false;
+
+ if (host_byte(status) == DID_NO_CONNECT)
+ return false;
+
+ /*
+ * FIXME: bit0 is listed as reserved in SCSI-2, but is
+ * significant in SCSI-3. For now, we follow the SCSI-2
+ * behaviour and ignore reserved bits.
+ */
+ status &= 0xfe;
+ return ((status == SAM_STAT_GOOD) ||
+ (status == SAM_STAT_CONDITION_MET) ||
+ /* Next two "intermediate" statuses are obsolete in SAM-4 */
+ (status == SAM_STAT_INTERMEDIATE) ||
+ (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
+ /* FIXME: this is obsolete in SAM-3 */
+ (status == SAM_STAT_COMMAND_TERMINATED));
}
#endif /* _SCSI_SCSI_H */
diff --git a/include/scsi/scsi_bsg_iscsi.h b/include/scsi/scsi_bsg_iscsi.h
index fd5689d4c052..a569c35b258d 100644
--- a/include/scsi/scsi_bsg_iscsi.h
+++ b/include/scsi/scsi_bsg_iscsi.h
@@ -1,22 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* iSCSI Transport BSG Interface
*
* Copyright (C) 2009 James Smart, Emulex Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
*/
#ifndef SCSI_BSG_ISCSI_H
@@ -66,14 +52,14 @@ struct iscsi_bsg_host_vendor {
uint64_t vendor_id;
/* start of vendor command area */
- uint32_t vendor_cmd[0];
+ uint32_t vendor_cmd[];
};
/* Response:
*/
struct iscsi_bsg_host_vendor_reply {
/* start of vendor response area */
- uint32_t vendor_rsp[0];
+ DECLARE_FLEX_ARRAY(uint32_t, vendor_rsp);
};
@@ -98,7 +84,7 @@ struct iscsi_bsg_reply {
*/
uint32_t result;
- /* If there was reply_payload, how much was recevied ? */
+ /* If there was reply_payload, how much was received ? */
uint32_t reply_payload_rcv_len;
union {
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index d85e6befa26b..8ecfb94049db 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -10,10 +10,8 @@
#include <linux/timer.h>
#include <linux/scatterlist.h>
#include <scsi/scsi_device.h>
-#include <scsi/scsi_request.h>
struct Scsi_Host;
-struct scsi_driver;
/*
* MAX_COMMAND_SIZE is:
@@ -28,14 +26,10 @@ struct scsi_driver;
* supports without specifying a cmd_len by ULD's
*/
#define MAX_COMMAND_SIZE 16
-#if (MAX_COMMAND_SIZE > BLK_MAX_CDB)
-# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB
-#endif
struct scsi_data_buffer {
struct sg_table table;
unsigned length;
- int resid;
};
/* embedded in scsi_cmnd */
@@ -56,34 +50,37 @@ struct scsi_pointer {
/* for scmd->flags */
#define SCMD_TAGGED (1 << 0)
-#define SCMD_UNCHECKED_ISA_DMA (1 << 1)
-#define SCMD_INITIALIZED (1 << 2)
+#define SCMD_INITIALIZED (1 << 1)
+#define SCMD_LAST (1 << 2)
+/*
+ * libata uses SCSI EH to fetch sense data for successful commands.
+ * SCSI EH should not overwrite scmd->result when SCMD_FORCE_EH_SUCCESS is set.
+ */
+#define SCMD_FORCE_EH_SUCCESS (1 << 3)
+#define SCMD_FAIL_IF_RECOVERING (1 << 4)
/* flags preserved across unprep / reprep */
-#define SCMD_PRESERVED_FLAGS (SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED)
+#define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING)
/* for scmd->state */
#define SCMD_STATE_COMPLETE 0
+#define SCMD_STATE_INFLIGHT 1
+
+enum scsi_cmnd_submitter {
+ SUBMITTED_BY_BLOCK_LAYER = 0,
+ SUBMITTED_BY_SCSI_ERROR_HANDLER = 1,
+ SUBMITTED_BY_SCSI_RESET_IOCTL = 2,
+} __packed;
struct scsi_cmnd {
- struct scsi_request req;
struct scsi_device *device;
- struct list_head list; /* scsi_cmnd participates in queue lists */
- struct list_head eh_entry; /* entry for the host eh_cmd_q */
+ struct list_head eh_entry; /* entry for the host eh_abort_list/eh_cmd_q */
struct delayed_work abort_work;
struct rcu_head rcu;
int eh_eflags; /* Used by error handlr */
- /*
- * A SCSI Command is assigned a nonzero serial_number before passed
- * to the driver's queue command function. The serial_number is
- * cleared when scsi_done is entered indicating that the command
- * has been completed. It is a bug for LLDDs to use this number
- * for purposes other than printk (and even that is only useful
- * for debugging).
- */
- unsigned long serial_number;
+ int budget_token;
/*
* This is set to jiffies as it was when the command was first
@@ -98,13 +95,12 @@ struct scsi_cmnd {
unsigned char prot_op;
unsigned char prot_type;
unsigned char prot_flags;
+ enum scsi_cmnd_submitter submitter;
unsigned short cmd_len;
enum dma_data_direction sc_data_direction;
- /* These elements define the operation we are about to perform */
- unsigned char *cmnd;
-
+ unsigned char cmnd[32]; /* SCSI CDB */
/* These elements define the operation we ultimately want to perform */
struct scsi_data_buffer sdb;
@@ -118,25 +114,23 @@ struct scsi_cmnd {
(ie, between disconnect /
reconnects. Probably == sector
size */
-
- struct request *request; /* The command we are
- working on */
-
+ unsigned resid_len; /* residual count */
+ unsigned sense_len;
unsigned char *sense_buffer;
/* obtained by REQUEST SENSE when
* CHECK CONDITION is received on original
* command (auto-sense). Length must be
* SCSI_SENSE_BUFFERSIZE bytes. */
- /* Low-level done function - can be used by low-level driver to point
- * to completion function. Not used by mid/upper level code. */
- void (*scsi_done) (struct scsi_cmnd *);
+ int flags; /* Command flags */
+ unsigned long state; /* Command completion state */
+
+ unsigned int extra_len; /* length of alignment and padding */
/*
- * The following fields can be written to by the host specific code.
- * Everything else should be left alone.
+ * The fields below can be modified by the LLD but the fields above
+ * must not be modified.
*/
- struct scsi_pointer SCp; /* Scratchpad used by some host adapters */
unsigned char *host_scribble; /* The host adapter is allowed to
* call scsi_malloc and get some memory
@@ -147,12 +141,14 @@ struct scsi_cmnd {
* to be at an address < 16Mb). */
int result; /* Status code from lower level driver */
- int flags; /* Command flags */
- unsigned long state; /* Command completion state */
-
- unsigned char tag; /* SCSI-II queued command tag */
};
+/* Variant of blk_mq_rq_from_pdu() that verifies the type of its argument. */
+static inline struct request *scsi_cmd_to_rq(struct scsi_cmnd *scmd)
+{
+ return blk_mq_rq_from_pdu(scmd);
+}
+
/*
* Return the driver private allocation behind the command.
* Only works if cmd_size is set in the host template.
@@ -162,20 +158,17 @@ static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd)
return cmd + 1;
}
-/* make sure not to use it with passthrough commands */
-static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
-{
- return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
-}
+void scsi_done(struct scsi_cmnd *cmd);
+void scsi_done_direct(struct scsi_cmnd *cmd);
-extern void scsi_put_command(struct scsi_cmnd *);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
size_t *offset, size_t *len);
extern void scsi_kunmap_atomic_sg(void *virt);
-extern blk_status_t scsi_init_io(struct scsi_cmnd *cmd);
+blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd);
+void scsi_free_sgtables(struct scsi_cmnd *cmd);
#ifdef CONFIG_SCSI_DMA
extern int scsi_dma_map(struct scsi_cmnd *cmd);
@@ -200,48 +193,50 @@ static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
return cmd->sdb.length;
}
-static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
+static inline void scsi_set_resid(struct scsi_cmnd *cmd, unsigned int resid)
{
- cmd->sdb.resid = resid;
+ cmd->resid_len = resid;
}
-static inline int scsi_get_resid(struct scsi_cmnd *cmd)
+static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd)
{
- return cmd->sdb.resid;
+ return cmd->resid_len;
}
#define scsi_for_each_sg(cmd, sg, nseg, __i) \
for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
-static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd)
+static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
+ const void *buf, int buflen)
{
- return blk_bidi_rq(cmd->request) &&
- (cmd->request->next_rq->special != NULL);
+ return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
+ buf, buflen);
}
-static inline struct scsi_data_buffer *scsi_in(struct scsi_cmnd *cmd)
+static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd,
+ void *buf, int buflen)
{
- return scsi_bidi_cmnd(cmd) ?
- cmd->request->next_rq->special : &cmd->sdb;
+ return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
+ buf, buflen);
}
-static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd)
+static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd)
{
- return &cmd->sdb;
+ return blk_rq_pos(scsi_cmd_to_rq(scmd));
}
-static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
- void *buf, int buflen)
+static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
{
- return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
- buf, buflen);
+ unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT;
+
+ return blk_rq_pos(scsi_cmd_to_rq(scmd)) >> shift;
}
-static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd,
- void *buf, int buflen)
+static inline unsigned int scsi_logical_block_count(struct scsi_cmnd *scmd)
{
- return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
- buf, buflen);
+ unsigned int shift = ilog2(scmd->device->sector_size);
+
+ return blk_rq_bytes(scsi_cmd_to_rq(scmd)) >> shift;
}
/*
@@ -306,9 +301,11 @@ static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd)
return scmd->prot_type;
}
-static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
+static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd)
{
- return blk_rq_pos(scmd->request);
+ struct request *rq = blk_mq_rq_from_pdu(scmd);
+
+ return t10_pi_ref_tag(rq);
}
static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd)
@@ -334,9 +331,14 @@ static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd)
#define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \
for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i)
-static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
+static inline void set_status_byte(struct scsi_cmnd *cmd, char status)
+{
+ cmd->result = (cmd->result & 0xffffff00) | status;
+}
+
+static inline u8 get_status_byte(struct scsi_cmnd *cmd)
{
- cmd->result = (cmd->result & 0xffff00ff) | (status << 8);
+ return cmd->result & 0xff;
}
static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
@@ -344,14 +346,43 @@ static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
cmd->result = (cmd->result & 0xff00ffff) | (status << 16);
}
-static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
+static inline u8 get_host_byte(struct scsi_cmnd *cmd)
{
- cmd->result = (cmd->result & 0x00ffffff) | (status << 24);
+ return (cmd->result >> 16) & 0xff;
+}
+
+/**
+ * scsi_msg_to_host_byte() - translate message byte
+ * @cmd: the SCSI command
+ * @msg: the SCSI parallel message byte to translate
+ *
+ * Translate the SCSI parallel message byte to a matching
+ * host byte setting. A message of COMMAND_COMPLETE indicates
+ * a successful command execution, any other message indicate
+ * an error. As the messages themselves only have a meaning
+ * for the SCSI parallel protocol this function translates
+ * them into a matching host byte value for SCSI EH.
+ */
+static inline void scsi_msg_to_host_byte(struct scsi_cmnd *cmd, u8 msg)
+{
+ switch (msg) {
+ case COMMAND_COMPLETE:
+ break;
+ case ABORT_TASK_SET:
+ set_host_byte(cmd, DID_ABORT);
+ break;
+ case TARGET_RESET:
+ set_host_byte(cmd, DID_RESET);
+ break;
+ default:
+ set_host_byte(cmd, DID_ERROR);
+ break;
+ }
}
static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
{
- unsigned int xfer_len = scsi_out(scmd)->length;
+ unsigned int xfer_len = scmd->sdb.length;
unsigned int prot_interval = scsi_prot_interval(scmd);
if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
@@ -360,4 +391,10 @@ static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
return xfer_len;
}
+extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc,
+ u8 key, u8 asc, u8 ascq);
+
+struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf,
+ blk_mq_req_flags_t flags);
+
#endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_common.h b/include/scsi/scsi_common.h
index 731ac09ed231..fb58715fac86 100644
--- a/include/scsi/scsi_common.h
+++ b/include/scsi/scsi_common.h
@@ -7,8 +7,21 @@
#define _SCSI_COMMON_H_
#include <linux/types.h>
+#include <uapi/linux/pr.h>
#include <scsi/scsi_proto.h>
+enum scsi_pr_type {
+ SCSI_PR_WRITE_EXCLUSIVE = 0x01,
+ SCSI_PR_EXCLUSIVE_ACCESS = 0x03,
+ SCSI_PR_WRITE_EXCLUSIVE_REG_ONLY = 0x05,
+ SCSI_PR_EXCLUSIVE_ACCESS_REG_ONLY = 0x06,
+ SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS = 0x07,
+ SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS = 0x08,
+};
+
+enum scsi_pr_type block_pr_type_to_scsi(enum pr_type type);
+enum pr_type scsi_pr_type_to_block(enum scsi_pr_type type);
+
static inline unsigned
scsi_varlen_cdb_length(const void *hdr)
{
@@ -25,6 +38,13 @@ scsi_command_size(const unsigned char *cmnd)
scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
}
+static inline unsigned char
+scsi_command_control(const unsigned char *cmnd)
+{
+ return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
+ cmnd[1] : cmnd[COMMAND_SIZE(cmnd[0]) - 1];
+}
+
/* Returns a human-readable name for the device */
extern const char *scsi_device_type(unsigned type);
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index e03bd9d41fa8..efcdc78530d5 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -6,18 +6,16 @@ struct scsi_cmnd;
struct scsi_device;
struct scsi_sense_hdr;
-#define SCSI_LOG_BUFSIZE 128
-
extern void scsi_print_command(struct scsi_cmnd *);
extern size_t __scsi_format_command(char *, size_t,
const unsigned char *, size_t);
extern void scsi_print_sense_hdr(const struct scsi_device *, const char *,
const struct scsi_sense_hdr *);
-extern void scsi_print_sense(const struct scsi_cmnd *);
+extern void scsi_print_sense(struct scsi_cmnd *);
extern void __scsi_print_sense(const struct scsi_device *, const char *name,
const unsigned char *sense_buffer,
int sense_len);
-extern void scsi_print_result(const struct scsi_cmnd *, const char *, int);
+extern void scsi_print_result(struct scsi_cmnd *, const char *, int);
#ifdef CONFIG_SCSI_CONSTANTS
extern bool scsi_opcode_sa_name(int, int, const char **, const char **);
@@ -26,7 +24,6 @@ extern const char *scsi_extd_sense_format(unsigned char, unsigned char,
const char **);
extern const char *scsi_mlreturn_string(int);
extern const char *scsi_hostbyte_string(int);
-extern const char *scsi_driverbyte_string(int);
#else
static inline bool
scsi_opcode_sa_name(int cmd, int sa,
@@ -78,12 +75,6 @@ scsi_hostbyte_string(int result)
return NULL;
}
-static inline const char *
-scsi_driverbyte_string(int result)
-{
- return NULL;
-}
-
#endif
#endif /* _SCSI_SCSI_DBG_H */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 202f4d6a4342..d32f5841f4f8 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -5,10 +5,12 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
-#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
#include <scsi/scsi.h>
#include <linux/atomic.h>
+#include <linux/sbitmap.h>
+struct bsg_device;
struct device;
struct request_queue;
struct scsi_cmnd;
@@ -106,11 +108,11 @@ struct scsi_device {
struct list_head siblings; /* list of all devices on this host */
struct list_head same_target_siblings; /* just the devices sharing same target id */
- atomic_t device_busy; /* commands actually active on LLDD */
+ struct sbitmap budget_map;
atomic_t device_blocked; /* Device returned QUEUE_FULL. */
+ atomic_t restarts;
spinlock_t list_lock;
- struct list_head cmd_list; /* queue of in use SCSI Command structures */
struct list_head starved_entry;
unsigned short queue_depth; /* How deep of a queue we want */
unsigned short max_queue_depth; /* max queue depth */
@@ -139,17 +141,60 @@ struct scsi_device {
const char * model; /* ... after scan; point to static string */
const char * rev; /* ... "nullnullnullnull" before scan */
-#define SCSI_VPD_PG_LEN 255
+#define SCSI_DEFAULT_VPD_LEN 255 /* default SCSI VPD page size (max) */
+ struct scsi_vpd __rcu *vpd_pg0;
struct scsi_vpd __rcu *vpd_pg83;
struct scsi_vpd __rcu *vpd_pg80;
- unsigned char current_tag; /* current tag */
- struct scsi_target *sdev_target; /* used only for single_lun */
+ struct scsi_vpd __rcu *vpd_pg89;
+ struct scsi_vpd __rcu *vpd_pgb0;
+ struct scsi_vpd __rcu *vpd_pgb1;
+ struct scsi_vpd __rcu *vpd_pgb2;
+ struct scsi_vpd __rcu *vpd_pgb7;
+
+ struct scsi_target *sdev_target;
blist_flags_t sdev_bflags; /* black/white flags as also found in
* scsi_devinfo.[hc]. For now used only to
- * pass settings from slave_alloc to scsi
+ * pass settings from sdev_init to scsi
* core. */
unsigned int eh_timeout; /* Error handling timeout */
+
+ /*
+ * If true, let the high-level device driver (sd) manage the device
+ * power state for system suspend/resume (suspend to RAM and
+ * hibernation) operations.
+ */
+ unsigned manage_system_start_stop:1;
+
+ /*
+ * If true, let the high-level device driver (sd) manage the device
+ * power state for runtime device suspand and resume operations.
+ */
+ unsigned manage_runtime_start_stop:1;
+
+ /*
+ * If true, let the high-level device driver (sd) manage the device
+ * power state for system shutdown (power off) operations.
+ */
+ unsigned manage_shutdown:1;
+
+ /*
+ * If true, let the high-level device driver (sd) manage the device
+ * power state for system restart (reboot) operations.
+ */
+ unsigned manage_restart:1;
+
+ /*
+ * If set and if the device is runtime suspended, ask the high-level
+ * device driver (sd) to force a runtime resume of the device.
+ */
+ unsigned force_runtime_start_on_system_start:1;
+
+ /*
+ * Set if the device is an ATA device.
+ */
+ unsigned is_ata:1;
+
unsigned removable:1;
unsigned changed:1; /* Data invalid due to media change */
unsigned busy:1; /* Used to prevent races */
@@ -170,9 +215,12 @@ struct scsi_device {
* because we did a bus reset. */
unsigned use_10_for_rw:1; /* first try 10-byte read / write */
unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
+ unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */
+ unsigned read_before_ms:1; /* perform a READ before MODE SENSE */
unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */
unsigned no_write_same:1; /* no WRITE SAME command */
unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */
+ unsigned use_16_for_sync:1; /* Use sync (16) over sync (10) */
unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */
unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */
unsigned skip_vpd_pages:1; /* do not read VPD pages */
@@ -180,7 +228,6 @@ struct scsi_device {
unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
unsigned no_start_on_add:1; /* do not issue start on add */
unsigned allow_restart:1; /* issue START_UNIT in error handler */
- unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */
unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */
unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
unsigned select_no_atn:1;
@@ -199,6 +246,20 @@ struct scsi_device {
unsigned broken_fua:1; /* Don't set FUA bit */
unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */
unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
+ unsigned rpm_autosuspend:1; /* Enable runtime autosuspend at device
+ * creation time */
+ unsigned ignore_media_change:1; /* Ignore MEDIA CHANGE on resume */
+ unsigned silence_suspend:1; /* Do not print runtime PM related messages */
+ unsigned no_vpd_size:1; /* No VPD size reported in header */
+
+ unsigned cdl_supported:1; /* Command duration limits supported */
+ unsigned cdl_enable:1; /* Enable/disable Command duration limits */
+
+ unsigned int queue_stopped; /* request queue is quiesced */
+ bool offline_already; /* Device offline message logged */
+
+ atomic_t ua_new_media_ctr; /* Counter for New Media UNIT ATTENTIONs */
+ atomic_t ua_por_ctr; /* Counter for Power On / Reset UAs */
atomic_t disk_events_disable_depth; /* disable depth for disk events */
@@ -213,21 +274,28 @@ struct scsi_device {
atomic_t iorequest_cnt;
atomic_t iodone_cnt;
atomic_t ioerr_cnt;
+ atomic_t iotmo_cnt;
struct device sdev_gendev,
sdev_dev;
- struct execute_work ew; /* used to get process context on put */
struct work_struct requeue_work;
struct scsi_device_handler *handler;
void *handler_data;
+ size_t dma_drain_len;
+ void *dma_drain_buf;
+
+ unsigned int sg_timeout;
+ unsigned int sg_reserved_size;
+
+ struct bsg_device *bsg_dev;
unsigned char access_state;
struct mutex state_mutex;
enum scsi_device_state sdev_state;
struct task_struct *quiesced_by;
- unsigned long sdev_data[0];
+ unsigned long sdev_data[];
} __attribute__((aligned(sizeof(unsigned long))));
#define to_scsi_device(d) \
@@ -251,16 +319,18 @@ sdev_prefix_printk(const char *, const struct scsi_device *, const char *,
#define sdev_printk(l, sdev, fmt, a...) \
sdev_prefix_printk(l, sdev, NULL, fmt, ##a)
-__printf(3, 4) void
-scmd_printk(const char *, const struct scsi_cmnd *, const char *, ...);
-
-#define scmd_dbg(scmd, fmt, a...) \
- do { \
- if ((scmd)->request->rq_disk) \
- sdev_dbg((scmd)->device, "[%s] " fmt, \
- (scmd)->request->rq_disk->disk_name, ##a);\
- else \
- sdev_dbg((scmd)->device, fmt, ##a); \
+__printf(3, 4) void scmd_printk(const char *, struct scsi_cmnd *, const char *,
+ ...);
+
+#define scmd_dbg(scmd, fmt, a...) \
+ do { \
+ struct request *__rq = scsi_cmd_to_rq((scmd)); \
+ \
+ if (__rq->q->disk) \
+ sdev_dbg((scmd)->device, "[%s] " fmt, \
+ __rq->q->disk->disk_name, ##a); \
+ else \
+ sdev_dbg((scmd)->device, fmt, ##a); \
} while (0)
enum scsi_target_state {
@@ -301,7 +371,7 @@ struct scsi_target {
atomic_t target_blocked;
/*
- * LLDs should set this in the slave_alloc host template callout.
+ * LLDs should set this in the sdev_init host template callout.
* If set to zero then there is not limit.
*/
unsigned int can_queue;
@@ -311,7 +381,7 @@ struct scsi_target {
char scsi_level;
enum scsi_target_state state;
void *hostdata; /* available to low-level driver */
- unsigned long starget_data[0]; /* for the transport */
+ unsigned long starget_data[]; /* for the transport */
/* starget_data must be the last element!!!! */
} __attribute__((aligned(sizeof(unsigned long))));
@@ -334,6 +404,8 @@ extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh);
extern void scsi_remove_device(struct scsi_device *);
extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
void scsi_attach_vpd(struct scsi_device *sdev);
+void scsi_cdl_check(struct scsi_device *sdev);
+int scsi_cdl_enable(struct scsi_device *sdev, bool enable);
extern struct scsi_device *scsi_device_from_queue(struct request_queue *q);
extern int __must_check scsi_device_get(struct scsi_device *);
@@ -391,21 +463,21 @@ extern int scsi_track_queue_full(struct scsi_device *, int);
extern int scsi_set_medium_removal(struct scsi_device *, char);
-extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
- unsigned char *buffer, int len, int timeout,
- int retries, struct scsi_mode_data *data,
- struct scsi_sense_hdr *);
+int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
+ int subpage, unsigned char *buffer, int len, int timeout,
+ int retries, struct scsi_mode_data *data,
+ struct scsi_sense_hdr *);
extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp,
- int modepage, unsigned char *buffer, int len,
- int timeout, int retries,
- struct scsi_mode_data *data,
+ unsigned char *buffer, int len, int timeout,
+ int retries, struct scsi_mode_data *data,
struct scsi_sense_hdr *);
extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
int retries, struct scsi_sense_hdr *sshdr);
extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf,
int buf_len);
-extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
- unsigned int len, unsigned char opcode);
+int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
+ unsigned int len, unsigned char opcode,
+ unsigned short sa);
extern int scsi_device_set_state(struct scsi_device *sdev,
enum scsi_device_state state);
extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type,
@@ -421,36 +493,81 @@ extern void scsi_scan_target(struct device *parent, unsigned int channel,
unsigned int id, u64 lun,
enum scsi_scan_mode rescan);
extern void scsi_target_reap(struct scsi_target *);
-extern void scsi_target_block(struct device *);
+void scsi_block_targets(struct Scsi_Host *shost, struct device *dev);
extern void scsi_target_unblock(struct device *, enum scsi_device_state);
extern void scsi_remove_target(struct device *);
extern const char *scsi_device_state_name(enum scsi_device_state);
extern int scsi_is_sdev_device(const struct device *);
extern int scsi_is_target_device(const struct device *);
extern void scsi_sanitize_inquiry_string(unsigned char *s, int len);
-extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
- int data_direction, void *buffer, unsigned bufflen,
- unsigned char *sense, struct scsi_sense_hdr *sshdr,
- int timeout, int retries, u64 flags,
- req_flags_t rq_flags, int *resid);
-/* Make sure any sense buffer is the correct size. */
-#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \
- sshdr, timeout, retries, flags, rq_flags, resid) \
-({ \
- BUILD_BUG_ON((sense) != NULL && \
- sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \
- __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \
- sense, sshdr, timeout, retries, flags, rq_flags, \
- resid); \
-})
-static inline int scsi_execute_req(struct scsi_device *sdev,
- const unsigned char *cmd, int data_direction, void *buffer,
- unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,
- int retries, int *resid)
-{
- return scsi_execute(sdev, cmd, data_direction, buffer,
- bufflen, NULL, sshdr, timeout, retries, 0, 0, resid);
-}
+
+/*
+ * scsi_execute_cmd users can set scsi_failure.result to have
+ * scsi_check_passthrough fail/retry a command. scsi_failure.result can be a
+ * specific host byte or message code, or SCMD_FAILURE_RESULT_ANY can be used
+ * to match any host or message code.
+ */
+#define SCMD_FAILURE_RESULT_ANY 0x7fffffff
+/*
+ * Set scsi_failure.result to SCMD_FAILURE_STAT_ANY to fail/retry any failure
+ * scsi_status_is_good returns false for.
+ */
+#define SCMD_FAILURE_STAT_ANY 0xff
+/*
+ * The following can be set to the scsi_failure sense, asc and ascq fields to
+ * match on any sense, ASC, or ASCQ value.
+ */
+#define SCMD_FAILURE_SENSE_ANY 0xff
+#define SCMD_FAILURE_ASC_ANY 0xff
+#define SCMD_FAILURE_ASCQ_ANY 0xff
+/* Always retry a matching failure. */
+#define SCMD_FAILURE_NO_LIMIT -1
+
+struct scsi_failure {
+ int result;
+ u8 sense;
+ u8 asc;
+ u8 ascq;
+ /*
+ * Number of times scsi_execute_cmd will retry the failure. It does
+ * not count for the total_allowed.
+ */
+ s8 allowed;
+ /* Number of times the failure has been retried. */
+ s8 retries;
+};
+
+struct scsi_failures {
+ /*
+ * If a scsi_failure does not have a retry limit setup this limit will
+ * be used.
+ */
+ int total_allowed;
+ int total_retries;
+ struct scsi_failure *failure_definitions;
+};
+
+/* Optional arguments to scsi_execute_cmd */
+struct scsi_exec_args {
+ unsigned char *sense; /* sense buffer */
+ unsigned int sense_len; /* sense buffer len */
+ struct scsi_sense_hdr *sshdr; /* decoded sense header */
+ blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */
+ int scmd_flags; /* SCMD flags */
+ int *resid; /* residual length */
+ struct scsi_failures *failures; /* failures to retry */
+};
+
+int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd,
+ blk_opf_t opf, void *buffer, unsigned int bufflen,
+ int timeout, int retries,
+ const struct scsi_exec_args *args);
+void scsi_failures_reset_retries(struct scsi_failures *failures);
+
+struct scsi_cmnd *scsi_get_internal_cmd(struct scsi_device *sdev,
+ enum dma_data_direction data_direction,
+ blk_mq_req_flags_t flags);
+void scsi_put_internal_cmd(struct scsi_cmnd *scmd);
extern void sdev_disable_disk_events(struct scsi_device *sdev);
extern void sdev_enable_disk_events(struct scsi_device *sdev);
extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t);
@@ -482,6 +599,22 @@ static inline unsigned int sdev_id(struct scsi_device *sdev)
#define scmd_id(scmd) sdev_id((scmd)->device)
#define scmd_channel(scmd) sdev_channel((scmd)->device)
+/**
+ * scsi_device_is_pseudo_dev() - Whether a device is a pseudo SCSI device.
+ * @sdev: SCSI device to examine
+ *
+ * A pseudo SCSI device can be used to allocate SCSI commands but does not show
+ * up in sysfs. Additionally, the logical unit information in *@sdev is made up.
+ *
+ * This function tests the LUN number instead of comparing @sdev with
+ * @sdev->host->pseudo_sdev because this function may be called before
+ * @sdev->host->pseudo_sdev has been initialized.
+ */
+static inline bool scsi_device_is_pseudo_dev(struct scsi_device *sdev)
+{
+ return sdev->lun == U64_MAX;
+}
+
/*
* checks for positions of the SCSI state machine
*/
@@ -580,6 +713,15 @@ static inline int scsi_device_supports_vpd(struct scsi_device *sdev)
return 0;
}
+static inline int scsi_device_busy(struct scsi_device *sdev)
+{
+ return sbitmap_weight(&sdev->budget_map);
+}
+
+/* Macros to access the UNIT ATTENTION counters */
+#define scsi_get_ua_new_media_ctr(sdev) atomic_read(&sdev->ua_new_media_ctr)
+#define scsi_get_ua_por_ctr(sdev) atomic_read(&sdev->ua_por_ctr)
+
#define MODULE_ALIAS_SCSI_DEVICE(type) \
MODULE_ALIAS("scsi:t-" __stringify(type) "*")
#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"
diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h
index 3fdb322d4c4b..1d79a3b536ce 100644
--- a/include/scsi/scsi_devinfo.h
+++ b/include/scsi/scsi_devinfo.h
@@ -28,10 +28,12 @@
#define BLIST_LARGELUN ((__force blist_flags_t)(1ULL << 9))
/* override additional length field */
#define BLIST_INQUIRY_36 ((__force blist_flags_t)(1ULL << 10))
-#define __BLIST_UNUSED_11 ((__force blist_flags_t)(1ULL << 11))
+/* ignore MEDIA CHANGE unit attention after resuming from runtime suspend */
+#define BLIST_IGN_MEDIA_CHANGE ((__force blist_flags_t)(1ULL << 11))
/* do not do automatic start on add */
#define BLIST_NOSTARTONADD ((__force blist_flags_t)(1ULL << 12))
-#define __BLIST_UNUSED_13 ((__force blist_flags_t)(1ULL << 13))
+/* do not ask for VPD page size first on some broken targets */
+#define BLIST_NO_VPD_SIZE ((__force blist_flags_t)(1ULL << 13))
#define __BLIST_UNUSED_14 ((__force blist_flags_t)(1ULL << 14))
#define __BLIST_UNUSED_15 ((__force blist_flags_t)(1ULL << 15))
#define __BLIST_UNUSED_16 ((__force blist_flags_t)(1ULL << 16))
@@ -67,15 +69,15 @@
#define BLIST_RETRY_ITF ((__force blist_flags_t)(1ULL << 32))
/* Always retry ABORTED_COMMAND with ASC 0xc1 */
#define BLIST_RETRY_ASC_C1 ((__force blist_flags_t)(1ULL << 33))
+/* Do not query the IO Advice Hints Grouping mode page */
+#define BLIST_SKIP_IO_HINTS ((__force blist_flags_t)(1ULL << 34))
-#define __BLIST_LAST_USED BLIST_RETRY_ASC_C1
+#define __BLIST_LAST_USED BLIST_SKIP_IO_HINTS
#define __BLIST_HIGH_UNUSED (~(__BLIST_LAST_USED | \
(__force blist_flags_t) \
((__force __u64)__BLIST_LAST_USED - 1ULL)))
-#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_11 | \
- __BLIST_UNUSED_13 | \
- __BLIST_UNUSED_14 | \
+#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_14 | \
__BLIST_UNUSED_15 | \
__BLIST_UNUSED_16 | \
__BLIST_UNUSED_24 | \
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index a862dc23c68d..4df943c1b90b 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -1,22 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
- * Header file for SCSI device handler infrastruture.
+ * Header file for SCSI device handler infrastructure.
*
* Modified version of patches posted by Mike Christie <michaelc@cs.wisc.edu>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
* Copyright IBM Corporation, 2007
* Authors:
* Chandra Seetharaman <sekharan@us.ibm.com>
@@ -65,7 +52,8 @@ struct scsi_device_handler {
/* Filled by the hardware handler */
struct module *module;
const char *name;
- int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
+ enum scsi_disposition (*check_sense)(struct scsi_device *,
+ struct scsi_sense_hdr *);
int (*attach)(struct scsi_device *);
void (*detach)(struct scsi_device *);
int (*activate)(struct scsi_device *, activate_complete, void *);
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index 6dffa8555a39..c0e89996bdb3 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -4,15 +4,15 @@
#include <linux/blk_types.h>
#include <linux/device.h>
+#include <scsi/scsi_cmnd.h>
struct module;
struct request;
-struct scsi_cmnd;
-struct scsi_device;
struct scsi_driver {
struct device_driver gendrv;
+ int (*resume)(struct device *);
void (*rescan)(struct device *);
blk_status_t (*init_command)(struct scsi_cmnd *);
void (*uninit_command)(struct scsi_cmnd *);
@@ -23,7 +23,9 @@ struct scsi_driver {
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
-extern int scsi_register_driver(struct device_driver *);
+#define scsi_register_driver(drv) \
+ __scsi_register_driver(drv, THIS_MODULE)
+int __scsi_register_driver(struct device_driver *, struct module *);
#define scsi_unregister_driver(drv) \
driver_unregister(drv);
@@ -31,4 +33,10 @@ extern int scsi_register_interface(struct class_interface *);
#define scsi_unregister_interface(intf) \
class_interface_unregister(intf)
+/* make sure not to use it with passthrough commands */
+static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
+{
+ return to_scsi_driver(cmd->device->sdev_gendev.driver);
+}
+
#endif /* _SCSI_SCSI_DRIVER_H */
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index 2b7e227960e1..1ae08e81339f 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -17,7 +17,7 @@ extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
extern int scsi_block_when_processing_errors(struct scsi_device *);
extern bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd,
struct scsi_sense_hdr *sshdr);
-extern int scsi_check_sense(struct scsi_cmnd *);
+extern enum scsi_disposition scsi_check_sense(struct scsi_cmnd *);
static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr)
{
@@ -32,16 +32,14 @@ extern int scsi_ioctl_reset(struct scsi_device *, int __user *);
struct scsi_eh_save {
/* saved state */
int result;
+ unsigned int resid_len;
int eh_eflags;
enum dma_data_direction data_direction;
unsigned underflow;
unsigned char cmd_len;
unsigned char prot_op;
- unsigned char *cmnd;
+ unsigned char cmnd[32];
struct scsi_data_buffer sdb;
- struct request *next_rq;
- /* new command support */
- unsigned char eh_cmnd[BLK_MAX_CDB];
struct scatterlist sense_sgl;
};
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 6ca954e9f752..e87cf7eadd26 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -16,70 +16,49 @@ struct completion;
struct module;
struct scsi_cmnd;
struct scsi_device;
-struct scsi_host_cmd_pool;
struct scsi_target;
struct Scsi_Host;
-struct scsi_host_cmd_pool;
struct scsi_transport_template;
-/*
- * The various choices mean:
- * NONE: Self evident. Host adapter is not capable of scatter-gather.
- * ALL: Means that the host adapter module can do scatter-gather,
- * and that there is no limit to the size of the table to which
- * we scatter/gather data. The value we set here is the maximum
- * single element sglist. To use chained sglists, the adapter
- * has to set a value beyond ALL (and correctly use the chain
- * handling API.
- * Anything else: Indicates the maximum number of chains that can be
- * used in one scatter-gather request.
- */
-#define SG_NONE 0
#define SG_ALL SG_CHUNK_SIZE
#define MODE_UNKNOWN 0x00
#define MODE_INITIATOR 0x01
#define MODE_TARGET 0x02
-struct scsi_host_template {
- struct module *module;
- const char *name;
+/**
+ * enum scsi_timeout_action - How to handle a command that timed out.
+ * @SCSI_EH_DONE: The command has already been completed.
+ * @SCSI_EH_RESET_TIMER: Reset the timer and continue waiting for completion.
+ * @SCSI_EH_NOT_HANDLED: The command has not yet finished. Abort the command.
+ */
+enum scsi_timeout_action {
+ SCSI_EH_DONE,
+ SCSI_EH_RESET_TIMER,
+ SCSI_EH_NOT_HANDLED,
+};
+struct scsi_host_template {
/*
- * The info function will return whatever useful information the
- * developer sees fit. If not provided, then the name field will
- * be used instead.
- *
- * Status: OPTIONAL
+ * Put fields referenced in IO submission path together in
+ * same cacheline
*/
- const char *(* info)(struct Scsi_Host *);
/*
- * Ioctl interface
- *
- * Status: OPTIONAL
- */
- int (* ioctl)(struct scsi_device *dev, int cmd, void __user *arg);
-
-
-#ifdef CONFIG_COMPAT
- /*
- * Compat handler. Handle 32bit ABI.
- * When unknown ioctl is passed return -ENOIOCTLCMD.
- *
- * Status: OPTIONAL
+ * Additional per-command data allocated for the driver.
*/
- int (* compat_ioctl)(struct scsi_device *dev, int cmd, void __user *arg);
-#endif
+ unsigned int cmd_size;
/*
* The queuecommand function is used to queue up a scsi
* command block to the LLDD. When the driver finished
* processing the command the done callback is invoked.
*
- * If queuecommand returns 0, then the HBA has accepted the
- * command. The done() function must be called on the command
+ * If queuecommand returns 0, then the driver has accepted the
+ * command. It must also push it to the HBA if the scsi_cmnd
+ * flag SCMD_LAST is set, or if the driver does not implement
+ * commit_rqs. The done() function must be called on the command
* when the driver has finished with it. (you may call done on the
* command before queuecommand returns, but in this case you
* *must* return 0 from queuecommand).
@@ -108,6 +87,57 @@ struct scsi_host_template {
int (* queuecommand)(struct Scsi_Host *, struct scsi_cmnd *);
/*
+ * Queue a reserved command (BLK_MQ_REQ_RESERVED). The .queuecommand()
+ * documentation also applies to the .queue_reserved_command() callback.
+ */
+ int (*queue_reserved_command)(struct Scsi_Host *, struct scsi_cmnd *);
+
+ /*
+ * The commit_rqs function is used to trigger a hardware
+ * doorbell after some requests have been queued with
+ * queuecommand, when an error is encountered before sending
+ * the request with SCMD_LAST set.
+ *
+ * STATUS: OPTIONAL
+ */
+ void (*commit_rqs)(struct Scsi_Host *, u16);
+
+ struct module *module;
+ const char *name;
+
+ /*
+ * The info function will return whatever useful information the
+ * developer sees fit. If not provided, then the name field will
+ * be used instead.
+ *
+ * Status: OPTIONAL
+ */
+ const char *(*info)(struct Scsi_Host *);
+
+ /*
+ * Ioctl interface
+ *
+ * Status: OPTIONAL
+ */
+ int (*ioctl)(struct scsi_device *dev, unsigned int cmd,
+ void __user *arg);
+
+
+#ifdef CONFIG_COMPAT
+ /*
+ * Compat handler. Handle 32bit ABI.
+ * When unknown ioctl is passed return -ENOIOCTLCMD.
+ *
+ * Status: OPTIONAL
+ */
+ int (*compat_ioctl)(struct scsi_device *dev, unsigned int cmd,
+ void __user *arg);
+#endif
+
+ int (*init_cmd_priv)(struct Scsi_Host *shost, struct scsi_cmnd *cmd);
+ int (*exit_cmd_priv)(struct Scsi_Host *shost, struct scsi_cmnd *cmd);
+
+ /*
* This is an error handling strategy routine. You don't need to
* define one of these if you don't want to - there is a default
* routine that is present that should work in most cases. For those
@@ -144,20 +174,20 @@ struct scsi_host_template {
* Return values: 0 on success, non-0 on failure
*
* Deallocation: If we didn't find any devices at this ID, you will
- * get an immediate call to slave_destroy(). If we find something
- * here then you will get a call to slave_configure(), then the
+ * get an immediate call to sdev_destroy(). If we find something
+ * here then you will get a call to sdev_configure(), then the
* device will be used for however long it is kept around, then when
* the device is removed from the system (or * possibly at reboot
- * time), you will then get a call to slave_destroy(). This is
- * assuming you implement slave_configure and slave_destroy.
+ * time), you will then get a call to sdev_destroy(). This is
+ * assuming you implement sdev_configure and sdev_destroy.
* However, if you allocate memory and hang it off the device struct,
- * then you must implement the slave_destroy() routine at a minimum
+ * then you must implement the sdev_destroy() routine at a minimum
* in order to avoid leaking memory
* each time a device is tore down.
*
* Status: OPTIONAL
*/
- int (* slave_alloc)(struct scsi_device *);
+ int (* sdev_init)(struct scsi_device *);
/*
* Once the device has responded to an INQUIRY and we know the
@@ -182,24 +212,24 @@ struct scsi_host_template {
* specific setup basis...
* 6. Return 0 on success, non-0 on error. The device will be marked
* as offline on error so that no access will occur. If you return
- * non-0, your slave_destroy routine will never get called for this
+ * non-0, your sdev_destroy routine will never get called for this
* device, so don't leave any loose memory hanging around, clean
* up after yourself before returning non-0
*
* Status: OPTIONAL
*/
- int (* slave_configure)(struct scsi_device *);
+ int (* sdev_configure)(struct scsi_device *, struct queue_limits *lim);
/*
* Immediately prior to deallocating the device and after all activity
* has ceased the mid layer calls this point so that the low level
* driver may completely detach itself from the scsi device and vice
* versa. The low level driver is responsible for freeing any memory
- * it allocated in the slave_alloc or slave_configure calls.
+ * it allocated in the sdev_init or sdev_configure calls.
*
* Status: OPTIONAL
*/
- void (* slave_destroy)(struct scsi_device *);
+ void (* sdev_destroy)(struct scsi_device *);
/*
* Before the mid layer attempts to scan for a new device attached
@@ -221,6 +251,9 @@ struct scsi_host_template {
* midlayer calls this point so that the driver may deallocate
* and terminate any references to the target.
*
+ * Note: This callback is called with the host lock held and hence
+ * must not sleep.
+ *
* Status: OPTIONAL
*/
void (* target_destroy)(struct scsi_target *);
@@ -264,7 +297,24 @@ struct scsi_host_template {
*
* Status: OPTIONAL
*/
- int (* map_queues)(struct Scsi_Host *shost);
+ void (* map_queues)(struct Scsi_Host *shost);
+
+ /*
+ * SCSI interface of blk_poll - poll for IO completions.
+ * Only applicable if SCSI LLD exposes multiple h/w queues.
+ *
+ * Return value: Number of completed entries found.
+ *
+ * Status: OPTIONAL
+ */
+ int (* mq_poll)(struct Scsi_Host *shost, unsigned int queue_num);
+
+ /*
+ * Check if scatterlists need to be padded for DMA draining.
+ *
+ * Status: OPTIONAL
+ */
+ bool (* dma_need_drain)(struct request *rq);
/*
* This function determines the BIOS parameters for a given
@@ -274,7 +324,7 @@ struct scsi_host_template {
*
* Status: OPTIONAL
*/
- int (* bios_param)(struct scsi_device *, struct block_device *,
+ int (* bios_param)(struct scsi_device *, struct gendisk *,
sector_t, int []);
/*
@@ -298,15 +348,17 @@ struct scsi_host_template {
/*
* This is an optional routine that allows the transport to become
* involved when a scsi io timer fires. The return value tells the
- * timer routine how to finish the io timeout handling:
- * EH_HANDLED: I fixed the error, please complete the command
- * EH_RESET_TIMER: I need more time, reset the timer and
- * begin counting again
- * EH_DONE: Begin normal error recovery
+ * timer routine how to finish the io timeout handling.
*
* Status: OPTIONAL
*/
- enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
+ enum scsi_timeout_action (*eh_timed_out)(struct scsi_cmnd *);
+ /*
+ * Optional routine that allows the transport to decide if a cmd
+ * is retryable. Return true if the transport is in a state the
+ * cmd should be retried on.
+ */
+ bool (*eh_should_retry_cmd)(struct scsi_cmnd *scmd);
/* This is an optional routine that allows transport to initiate
* LLD adapter or firmware reset using sysfs attribute.
@@ -327,19 +379,22 @@ struct scsi_host_template {
const char *proc_name;
/*
- * Used to store the procfs directory if a driver implements the
- * show_info method.
- */
- struct proc_dir_entry *proc_dir;
-
- /*
* This determines if we will use a non-interrupt driven
* or an interrupt driven scheme. It is set to the maximum number
- * of simultaneous commands a given host adapter will accept.
+ * of simultaneous commands a single hw queue in HBA will accept
+ * excluding internal commands.
*/
int can_queue;
/*
+ * This determines how many commands the HBA will set aside
+ * for internal commands. This number will be added to
+ * @can_queue to calculate the maximum number of simultaneous
+ * commands sent to the host.
+ */
+ int nr_reserved_cmds;
+
+ /*
* In many instances, especially where disconnect / reconnect are
* supported, our host also has an ID on the SCSI bus. If this is
* the case, then it must be reserved. Please set this_id to -1 if
@@ -365,12 +420,16 @@ struct scsi_host_template {
*/
unsigned int max_segment_size;
+ unsigned int dma_alignment;
+
/*
* DMA scatter gather segment boundary limit. A segment crossing this
* boundary will be split in two.
*/
unsigned long dma_boundary;
+ unsigned long virt_boundary_mask;
+
/*
* This specifies "machine infinity" for host templates which don't
* limit the transfer size. Note this limit represents an absolute
@@ -391,13 +450,9 @@ struct scsi_host_template {
short cmd_per_lun;
/*
- * present contains counter indicating how many boards of this
- * type were found when we did the scan.
+ * Allocate tags starting from last allocated tag.
*/
- unsigned char present;
-
- /* If use block layer to manage tags, this is tag allocation policy */
- int tag_alloc_policy;
+ bool tag_alloc_policy_rr : 1;
/*
* Track QUEUE_FULL events and reduce queue depth on demand.
@@ -410,11 +465,6 @@ struct scsi_host_template {
unsigned supported_mode:2;
/*
- * True if this host adapter uses unchecked DMA onto an ISA bus.
- */
- unsigned unchecked_isa_dma:1;
-
- /*
* True for emulated SCSI host adapters (e.g. ATAPI).
*/
unsigned emulated:1;
@@ -427,8 +477,11 @@ struct scsi_host_template {
/* True if the controller does not support WRITE SAME */
unsigned no_write_same:1;
- /* True if the low-level driver supports blk-mq only */
- unsigned force_blk_mq:1;
+ /* True if the host uses host-wide tagspace */
+ unsigned host_tagset:1;
+
+ /* The queuecommand callback may block. See also BLK_MQ_F_BLOCKING. */
+ unsigned queuecommand_may_block:1;
/*
* Countdown for host blocking with no commands outstanding.
@@ -445,14 +498,9 @@ struct scsi_host_template {
#define SCSI_DEFAULT_HOST_BLOCKED 7
/*
- * Pointer to the sysfs class properties for this host, NULL terminated.
+ * Pointer to the SCSI host sysfs attribute groups, NULL terminated.
*/
- struct device_attribute **shost_attrs;
-
- /*
- * Pointer to the SCSI device properties for this host, NULL terminated.
- */
- struct device_attribute **sdev_attrs;
+ const struct attribute_group **shost_groups;
/*
* Pointer to the SCSI device attribute groups for this host,
@@ -468,12 +516,6 @@ struct scsi_host_template {
* scsi_netlink.h
*/
u64 vendor_id;
-
- /*
- * Additional per-command data allocated for the driver.
- */
- unsigned int cmd_size;
- struct scsi_host_cmd_pool *cmd_pool;
};
/*
@@ -488,8 +530,7 @@ struct scsi_host_template {
unsigned long irq_flags; \
int rc; \
spin_lock_irqsave(shost->host_lock, irq_flags); \
- scsi_cmd_get_serial(shost, cmd); \
- rc = func_name##_lck (cmd, cmd->scsi_done); \
+ rc = func_name##_lck(cmd); \
spin_unlock_irqrestore(shost->host_lock, irq_flags); \
return rc; \
}
@@ -529,18 +570,20 @@ struct Scsi_Host {
struct mutex scan_mutex;/* serialize scanning activity */
+ struct list_head eh_abort_list;
struct list_head eh_cmd_q;
struct task_struct * ehandler; /* Error recovery thread. */
struct completion * eh_action; /* Wait for specific actions on the
host. */
wait_queue_head_t host_wait;
- struct scsi_host_template *hostt;
+ const struct scsi_host_template *hostt;
struct scsi_transport_template *transportt;
+ struct kref tagset_refcnt;
+ struct completion tagset_freed;
/* Area to keep a shared tag map */
struct blk_mq_tag_set tag_set;
- atomic_t host_busy; /* commands actually active on low-level */
atomic_t host_blocked;
unsigned int host_failed; /* commands that failed.
@@ -569,7 +612,7 @@ struct Scsi_Host {
* have some way of identifying each detected host adapter properly
* and uniquely. For hosts that do not support more than one card
* in the system at one time, this does not need to be set. It is
- * initialized to 0 in scsi_register.
+ * initialized to 0 in scsi_host_alloc.
*/
unsigned int unique_id;
@@ -583,29 +626,37 @@ struct Scsi_Host {
unsigned short max_cmd_len;
int this_id;
+
+ /*
+ * Number of commands this host can handle at the same time.
+ * This excludes reserved commands as specified by nr_reserved_cmds.
+ */
int can_queue;
+ /*
+ * Number of reserved commands to allocate, if any.
+ */
+ unsigned int nr_reserved_cmds;
+
short cmd_per_lun;
short unsigned int sg_tablesize;
short unsigned int sg_prot_tablesize;
unsigned int max_sectors;
+ unsigned int opt_sectors;
unsigned int max_segment_size;
+ unsigned int dma_alignment;
unsigned long dma_boundary;
+ unsigned long virt_boundary_mask;
/*
* In scsi-mq mode, the number of hardware queues supported by the LLD.
*
* Note: it is assumed that each hardware queue has a queue depth of
* can_queue. In other words, the total queue depth per host
- * is nr_hw_queues * can_queue.
+ * is nr_hw_queues * can_queue. However, for when host_tagset is set,
+ * the total queue depth is can_queue.
*/
unsigned nr_hw_queues;
- /*
- * Used to assign serial numbers to the cmds.
- * Protected by the host lock.
- */
- unsigned long cmd_serial_number;
-
+ unsigned nr_maps;
unsigned active_mode:2;
- unsigned unchecked_isa_dma:1;
/*
* Host has requested that no further requests come through for the
@@ -632,15 +683,21 @@ struct Scsi_Host {
/* The controller does not support WRITE SAME */
unsigned no_write_same:1;
- unsigned use_cmd_list:1;
+ /* True if the host uses host-wide tagspace */
+ unsigned host_tagset:1;
+
+ /* The queuecommand callback may block. See also BLK_MQ_F_BLOCKING. */
+ unsigned queuecommand_may_block:1;
/* Host responded with short (<36 bytes) INQUIRY result */
unsigned short_inquiry:1;
+ /* The transport requires the LUN bits NOT to be stored in CDB[1] */
+ unsigned no_scsi2_lun_in_cdb:1;
+
/*
* Optional work queue to be utilized by the transport
*/
- char work_q_name[20];
struct workqueue_struct *work_q;
/*
@@ -648,9 +705,6 @@ struct Scsi_Host {
*/
struct workqueue_struct *tmf_work_q;
- /* The transport requires the LUN bits NOT to be stored in CDB[1] */
- unsigned no_scsi2_lun_in_cdb:1;
-
/*
* Value host_blocked counts down from
*/
@@ -674,6 +728,12 @@ struct Scsi_Host {
struct device shost_gendev, shost_dev;
/*
+ * A SCSI device structure used for sending internal commands to the
+ * HBA. There is no corresponding logical unit inside the SCSI device.
+ */
+ struct scsi_device *pseudo_sdev;
+
+ /*
* Points to the transport data (if any) which is allocated
* separately
*/
@@ -685,12 +745,15 @@ struct Scsi_Host {
*/
struct device *dma_dev;
+ /* Delay for runtime autosuspend */
+ int rpm_autosuspend_delay;
+
/*
* We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force
* alignment to a long boundary.
*/
- unsigned long hostdata[0] /* Used for storage of host specific stuff */
+ unsigned long hostdata[] /* Used for storage of host specific stuff */
__attribute__ ((aligned (sizeof(unsigned long))));
};
@@ -728,19 +791,27 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
extern void scsi_flush_work(struct Scsi_Host *);
-extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
+extern struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *, int);
extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *,
struct device *,
struct device *);
+#if defined(CONFIG_SCSI_PROC_FS)
+struct proc_dir_entry *
+scsi_template_proc_dir(const struct scsi_host_template *sht);
+#else
+#define scsi_template_proc_dir(sht) NULL
+#endif
extern void scsi_scan_host(struct Scsi_Host *);
-extern void scsi_rescan_device(struct device *);
+extern int scsi_resume_device(struct scsi_device *sdev);
+extern int scsi_rescan_device(struct scsi_device *sdev);
extern void scsi_remove_host(struct Scsi_Host *);
extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
extern int scsi_host_busy(struct Scsi_Host *shost);
extern void scsi_host_put(struct Scsi_Host *t);
-extern struct Scsi_Host *scsi_host_lookup(unsigned short);
+extern struct Scsi_Host *scsi_host_lookup(unsigned int hostnum);
extern const char *scsi_host_state_name(enum scsi_host_state);
-extern void scsi_cmd_get_serial(struct Scsi_Host *, struct scsi_cmnd *);
+extern void scsi_host_complete_all_commands(struct Scsi_Host *shost,
+ enum scsi_host_status status);
static inline int __must_check scsi_add_host(struct Scsi_Host *host,
struct device *dev)
@@ -765,18 +836,13 @@ static inline int scsi_host_scan_allowed(struct Scsi_Host *shost)
extern void scsi_unblock_requests(struct Scsi_Host *);
extern void scsi_block_requests(struct Scsi_Host *);
+extern int scsi_host_block(struct Scsi_Host *shost);
+extern int scsi_host_unblock(struct Scsi_Host *shost, int new_state);
-struct class_container;
+void scsi_host_busy_iter(struct Scsi_Host *,
+ bool (*fn)(struct scsi_cmnd *, void *), void *priv);
-/*
- * These two functions are used to allocate and free a pseudo device
- * which will connect to the host adapter itself rather than any
- * physical device. You must deallocate when you are done with the
- * thing. This physical pseudo-device isn't real and won't be available
- * from any high-level drivers.
- */
-extern void scsi_free_host_dev(struct scsi_device *);
-extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
+struct class_container;
/*
* DIF defines the exchange of protection information between
diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h
index 5101e987c0ef..a207c07da9d2 100644
--- a/include/scsi/scsi_ioctl.h
+++ b/include/scsi/scsi_ioctl.h
@@ -18,7 +18,9 @@
#ifdef __KERNEL__
+struct gendisk;
struct scsi_device;
+struct sg_io_hdr;
/*
* Structures used for scsi_ioctl et al.
@@ -27,7 +29,7 @@ struct scsi_device;
typedef struct scsi_ioctl_command {
unsigned int inlen;
unsigned int outlen;
- unsigned char data[0];
+ unsigned char data[];
} Scsi_Ioctl_Command;
typedef struct scsi_idlun {
@@ -43,7 +45,11 @@ typedef struct scsi_fctargaddress {
int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
int cmd, bool ndelay);
-extern int scsi_ioctl(struct scsi_device *, int, void __user *);
+int scsi_ioctl(struct scsi_device *sdev, bool open_for_write, int cmd,
+ void __user *arg);
+int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp);
+int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp);
+bool scsi_cmd_allowed(unsigned char *cmd, bool open_for_write);
#endif /* __KERNEL__ */
#endif /* _SCSI_IOCTL_H */
diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
index c36860111932..f64385cde5b9 100644
--- a/include/scsi/scsi_proto.h
+++ b/include/scsi/scsi_proto.h
@@ -10,6 +10,7 @@
#ifndef _SCSI_PROTO_H_
#define _SCSI_PROTO_H_
+#include <linux/build_bug.h>
#include <linux/types.h>
/*
@@ -32,8 +33,8 @@
#define INQUIRY 0x12
#define RECOVER_BUFFERED_DATA 0x14
#define MODE_SELECT 0x15
-#define RESERVE 0x16
-#define RELEASE 0x17
+#define RESERVE_6 0x16
+#define RELEASE_6 0x17
#define COPY 0x18
#define ERASE 0x19
#define MODE_SENSE 0x1a
@@ -119,6 +120,7 @@
#define WRITE_SAME_16 0x93
#define ZBC_OUT 0x94
#define ZBC_IN 0x95
+#define WRITE_ATOMIC_16 0x9c
#define SERVICE_ACTION_BIDIRECTIONAL 0x9d
#define SERVICE_ACTION_IN_16 0x9e
#define SERVICE_ACTION_OUT_16 0x9f
@@ -126,6 +128,7 @@
#define SAI_READ_CAPACITY_16 0x10
#define SAI_GET_LBA_STATUS 0x12
#define SAI_REPORT_REFERRALS 0x13
+#define SAI_GET_STREAM_STATUS 0x16
/* values for maintenance in */
#define MI_REPORT_IDENTIFYING_INFORMATION 0x05
#define MI_REPORT_TARGET_PGS 0x0a
@@ -151,6 +154,11 @@
#define ZO_FINISH_ZONE 0x02
#define ZO_OPEN_ZONE 0x03
#define ZO_RESET_WRITE_POINTER 0x04
+/* values for PR in service action */
+#define READ_KEYS 0x00
+#define READ_RESERVATION 0x01
+#define REPORT_CAPABILITES 0x02
+#define READ_FULL_STATUS 0x03
/* values for variable length command */
#define XDREAD_32 0x03
#define XDWRITE_32 0x04
@@ -190,43 +198,25 @@ struct scsi_varlen_cdb_hdr {
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
* T10/1561-D Revision 4 Draft dated 7th November 2002.
*/
-#define SAM_STAT_GOOD 0x00
-#define SAM_STAT_CHECK_CONDITION 0x02
-#define SAM_STAT_CONDITION_MET 0x04
-#define SAM_STAT_BUSY 0x08
-#define SAM_STAT_INTERMEDIATE 0x10
-#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
-#define SAM_STAT_RESERVATION_CONFLICT 0x18
-#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */
-#define SAM_STAT_TASK_SET_FULL 0x28
-#define SAM_STAT_ACA_ACTIVE 0x30
-#define SAM_STAT_TASK_ABORTED 0x40
-
-/*
- * Status codes. These are deprecated as they are shifted 1 bit right
- * from those found in the SCSI standards. This causes confusion for
- * applications that are ported to several OSes. Prefer SAM Status codes
- * above.
- */
-
-#define GOOD 0x00
-#define CHECK_CONDITION 0x01
-#define CONDITION_GOOD 0x02
-#define BUSY 0x04
-#define INTERMEDIATE_GOOD 0x08
-#define INTERMEDIATE_C_GOOD 0x0a
-#define RESERVATION_CONFLICT 0x0c
-#define COMMAND_TERMINATED 0x11
-#define QUEUE_FULL 0x14
-#define ACA_ACTIVE 0x18
-#define TASK_ABORTED 0x20
+enum sam_status {
+ SAM_STAT_GOOD = 0x00,
+ SAM_STAT_CHECK_CONDITION = 0x02,
+ SAM_STAT_CONDITION_MET = 0x04,
+ SAM_STAT_BUSY = 0x08,
+ SAM_STAT_INTERMEDIATE = 0x10,
+ SAM_STAT_INTERMEDIATE_CONDITION_MET = 0x14,
+ SAM_STAT_RESERVATION_CONFLICT = 0x18,
+ SAM_STAT_COMMAND_TERMINATED = 0x22, /* obsolete in SAM-3 */
+ SAM_STAT_TASK_SET_FULL = 0x28,
+ SAM_STAT_ACA_ACTIVE = 0x30,
+ SAM_STAT_TASK_ABORTED = 0x40,
+};
-#define STATUS_MASK 0xfe
+#define STATUS_MASK 0xfe
/*
* SENSE KEYS
*/
-
#define NO_SENSE 0x00
#define RECOVERED_ERROR 0x01
#define NOT_READY 0x02
@@ -241,7 +231,7 @@ struct scsi_varlen_cdb_hdr {
#define ABORTED_COMMAND 0x0b
#define VOLUME_OVERFLOW 0x0d
#define MISCOMPARE 0x0e
-
+#define COMPLETED 0x0f
/*
* DEVICE TYPES
@@ -288,6 +278,81 @@ struct scsi_lun {
__u8 scsi_lun[8];
};
+/* SBC-5 IO advice hints group descriptor */
+struct scsi_io_group_descriptor {
+#if defined(__BIG_ENDIAN)
+ u8 io_advice_hints_mode: 2;
+ u8 reserved1: 3;
+ u8 st_enble: 1;
+ u8 cs_enble: 1;
+ u8 ic_enable: 1;
+#elif defined(__LITTLE_ENDIAN)
+ u8 ic_enable: 1;
+ u8 cs_enble: 1;
+ u8 st_enble: 1;
+ u8 reserved1: 3;
+ u8 io_advice_hints_mode: 2;
+#else
+#error
+#endif
+ u8 reserved2[3];
+ /* Logical block markup descriptor */
+#if defined(__BIG_ENDIAN)
+ u8 acdlu: 1;
+ u8 reserved3: 1;
+ u8 rlbsr: 2;
+ u8 lbm_descriptor_type: 4;
+#elif defined(__LITTLE_ENDIAN)
+ u8 lbm_descriptor_type: 4;
+ u8 rlbsr: 2;
+ u8 reserved3: 1;
+ u8 acdlu: 1;
+#else
+#error
+#endif
+ u8 params[2];
+ u8 reserved4;
+ u8 reserved5[8];
+};
+
+static_assert(sizeof(struct scsi_io_group_descriptor) == 16);
+
+/* SCSI stream status descriptor */
+struct scsi_stream_status {
+#if defined(__BIG_ENDIAN)
+ u8 perm: 1;
+ u8 reserved1: 7;
+#elif defined(__LITTLE_ENDIAN)
+ u8 reserved1: 7;
+ u8 perm: 1;
+#else
+#error
+#endif
+ u8 reserved2;
+ __be16 stream_identifier;
+#if defined(__BIG_ENDIAN)
+ u8 reserved3: 2;
+ u8 rel_lifetime: 6;
+#elif defined(__LITTLE_ENDIAN)
+ u8 rel_lifetime: 6;
+ u8 reserved3: 2;
+#else
+#error
+#endif
+ u8 reserved4[3];
+};
+
+static_assert(sizeof(struct scsi_stream_status) == 8);
+
+/* GET STREAM STATUS parameter data */
+struct scsi_stream_status_header {
+ __be32 len; /* length in bytes of following payload */
+ u16 reserved;
+ __be16 number_of_open_streams;
+};
+
+static_assert(sizeof(struct scsi_stream_status_header) == 8);
+
/* SPC asymmetric access states */
#define SCSI_ACCESS_STATE_OPTIMAL 0x00
#define SCSI_ACCESS_STATE_ACTIVE 0x01
@@ -325,7 +390,9 @@ enum zbc_zone_type {
ZBC_ZONE_TYPE_CONV = 0x1,
ZBC_ZONE_TYPE_SEQWRITE_REQ = 0x2,
ZBC_ZONE_TYPE_SEQWRITE_PREF = 0x3,
- /* 0x4 to 0xf are reserved */
+ ZBC_ZONE_TYPE_SEQ_OR_BEFORE_REQ = 0x4,
+ ZBC_ZONE_TYPE_GAP = 0x5,
+ /* 0x6 to 0xf are reserved */
};
/* Zone conditions of REPORT ZONES zone descriptors */
@@ -341,4 +408,31 @@ enum zbc_zone_cond {
ZBC_ZONE_COND_OFFLINE = 0xf,
};
+enum zbc_zone_alignment_method {
+ ZBC_CONSTANT_ZONE_LENGTH = 0x1,
+ ZBC_CONSTANT_ZONE_START_OFFSET = 0x8,
+};
+
+/* Version descriptor values for INQUIRY */
+enum scsi_version_descriptor {
+ SCSI_VERSION_DESCRIPTOR_FCP4 = 0x0a40,
+ SCSI_VERSION_DESCRIPTOR_ISCSI = 0x0960,
+ SCSI_VERSION_DESCRIPTOR_SAM5 = 0x00a0,
+ SCSI_VERSION_DESCRIPTOR_SAS3 = 0x0c60,
+ SCSI_VERSION_DESCRIPTOR_SBC3 = 0x04c0,
+ SCSI_VERSION_DESCRIPTOR_SBP3 = 0x0980,
+ SCSI_VERSION_DESCRIPTOR_SPC4 = 0x0460,
+ SCSI_VERSION_DESCRIPTOR_SRP = 0x0940
+};
+
+enum scsi_support_opcode {
+ SCSI_SUPPORT_NO_INFO = 0,
+ SCSI_SUPPORT_NOT_SUPPORTED = 1,
+ SCSI_SUPPORT_FULL = 3,
+ SCSI_SUPPORT_VENDOR = 5,
+};
+
+#define SCSI_CONTROL_MASK 0
+#define SCSI_GROUP_NUMBER_MASK 0
+
#endif /* _SCSI_PROTO_H_ */
diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
deleted file mode 100644
index b06f28c74908..000000000000
--- a/include/scsi/scsi_request.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _SCSI_SCSI_REQUEST_H
-#define _SCSI_SCSI_REQUEST_H
-
-#include <linux/blk-mq.h>
-
-#define BLK_MAX_CDB 16
-
-struct scsi_request {
- unsigned char __cmd[BLK_MAX_CDB];
- unsigned char *cmd;
- unsigned short cmd_len;
- int result;
- unsigned int sense_len;
- unsigned int resid_len; /* residual count */
- int retries;
- void *sense;
-};
-
-static inline struct scsi_request *scsi_req(struct request *rq)
-{
- return blk_mq_rq_to_pdu(rq);
-}
-
-static inline void scsi_req_free_cmd(struct scsi_request *req)
-{
- if (req->cmd != req->__cmd)
- kfree(req->cmd);
-}
-
-void scsi_req_init(struct scsi_request *req);
-
-#endif /* _SCSI_SCSI_REQUEST_H */
diff --git a/include/scsi/scsi_status.h b/include/scsi/scsi_status.h
new file mode 100644
index 000000000000..9cb85262de64
--- /dev/null
+++ b/include/scsi/scsi_status.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _SCSI_SCSI_STATUS_H
+#define _SCSI_SCSI_STATUS_H
+
+#include <linux/types.h>
+#include <scsi/scsi_proto.h>
+
+/* Message codes. */
+enum scsi_msg_byte {
+ COMMAND_COMPLETE = 0x00,
+ EXTENDED_MESSAGE = 0x01,
+ SAVE_POINTERS = 0x02,
+ RESTORE_POINTERS = 0x03,
+ DISCONNECT = 0x04,
+ INITIATOR_ERROR = 0x05,
+ ABORT_TASK_SET = 0x06,
+ MESSAGE_REJECT = 0x07,
+ NOP = 0x08,
+ MSG_PARITY_ERROR = 0x09,
+ LINKED_CMD_COMPLETE = 0x0a,
+ LINKED_FLG_CMD_COMPLETE = 0x0b,
+ TARGET_RESET = 0x0c,
+ ABORT_TASK = 0x0d,
+ CLEAR_TASK_SET = 0x0e,
+ INITIATE_RECOVERY = 0x0f, /* SCSI-II only */
+ RELEASE_RECOVERY = 0x10, /* SCSI-II only */
+ TERMINATE_IO_PROC = 0x11, /* SCSI-II only */
+ CLEAR_ACA = 0x16,
+ LOGICAL_UNIT_RESET = 0x17,
+ SIMPLE_QUEUE_TAG = 0x20,
+ HEAD_OF_QUEUE_TAG = 0x21,
+ ORDERED_QUEUE_TAG = 0x22,
+ IGNORE_WIDE_RESIDUE = 0x23,
+ ACA = 0x24,
+ QAS_REQUEST = 0x55,
+
+ /* Old SCSI2 names, don't use in new code */
+ BUS_DEVICE_RESET = TARGET_RESET,
+ ABORT = ABORT_TASK_SET,
+};
+
+/* Host byte codes. */
+enum scsi_host_status {
+ DID_OK = 0x00, /* NO error */
+ DID_NO_CONNECT = 0x01, /* Couldn't connect before timeout period */
+ DID_BUS_BUSY = 0x02, /* BUS stayed busy through time out period */
+ DID_TIME_OUT = 0x03, /* TIMED OUT for other reason */
+ DID_BAD_TARGET = 0x04, /* BAD target. */
+ DID_ABORT = 0x05, /* Told to abort for some other reason */
+ DID_PARITY = 0x06, /* Parity error */
+ DID_ERROR = 0x07, /* Internal error */
+ DID_RESET = 0x08, /* Reset by somebody. */
+ DID_BAD_INTR = 0x09, /* Got an interrupt we weren't expecting. */
+ DID_PASSTHROUGH = 0x0a, /* Force command past mid-layer */
+ DID_SOFT_ERROR = 0x0b, /* The low level driver just wish a retry */
+ DID_IMM_RETRY = 0x0c, /* Retry without decrementing retry count */
+ DID_REQUEUE = 0x0d, /* Requeue command (no immediate retry) also
+ * without decrementing the retry count */
+ DID_TRANSPORT_DISRUPTED = 0x0e, /* Transport error disrupted execution
+ * and the driver blocked the port to
+ * recover the link. Transport class will
+ * retry or fail IO */
+ DID_TRANSPORT_FAILFAST = 0x0f, /* Transport class fastfailed the io */
+ /*
+ * We used to have DID_TARGET_FAILURE, DID_NEXUS_FAILURE,
+ * DID_ALLOC_FAILURE and DID_MEDIUM_ERROR at 0x10 - 0x13. For compat
+ * with userspace apps that parse the host byte for SG IO, we leave
+ * that block of codes unused and start at 0x14 below.
+ */
+ DID_TRANSPORT_MARGINAL = 0x14, /* Transport marginal errors */
+};
+
+#endif /* _SCSI_SCSI_STATUS_H */
diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h
index 6053d46e794e..ea7848e74d25 100644
--- a/include/scsi/scsi_tcq.h
+++ b/include/scsi/scsi_tcq.h
@@ -34,7 +34,7 @@ static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost,
blk_mq_unique_tag_to_tag(tag));
}
- if (!req)
+ if (!req || !blk_mq_request_started(req))
return NULL;
return blk_mq_rq_to_pdu(req);
}
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
index a3dcb1bfb362..1394cf313bb3 100644
--- a/include/scsi/scsi_transport.h
+++ b/include/scsi/scsi_transport.h
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Transport specific attributes.
*
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SCSI_TRANSPORT_H
#define SCSI_TRANSPORT_H
@@ -96,6 +83,6 @@ scsi_transport_device_data(struct scsi_device *sdev)
+ shost->transportt->device_private_offset;
}
-void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q);
+void scsi_init_limits(struct Scsi_Host *shost, struct queue_limits *lim);
#endif /* SCSI_TRANSPORT_H */
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 15da45dc2a5d..b908aacfef48 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -1,35 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* FiberChannel transport specific attributes exported to sysfs.
*
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * ========
- *
* Copyright (C) 2004-2007 James Smart, Emulex Corporation
* Rewrite for host, target, device, and remote port attributes,
* statistics, and service functions...
- *
*/
#ifndef SCSI_TRANSPORT_FC_H
#define SCSI_TRANSPORT_FC_H
#include <linux/sched.h>
#include <linux/bsg-lib.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_netlink.h>
#include <scsi/scsi_host.h>
@@ -84,6 +67,7 @@ enum fc_port_state {
FC_PORTSTATE_ERROR,
FC_PORTSTATE_LOOPBACK,
FC_PORTSTATE_DELETED,
+ FC_PORTSTATE_MARGINAL,
};
@@ -141,6 +125,7 @@ enum fc_vport_state {
#define FC_PORTSPEED_25GBIT 0x800
#define FC_PORTSPEED_64GBIT 0x1000
#define FC_PORTSPEED_128GBIT 0x2000
+#define FC_PORTSPEED_256GBIT 0x4000
#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */
/*
@@ -165,6 +150,9 @@ enum fc_tgtid_binding_type {
#define FC_PORT_ROLE_FCP_INITIATOR 0x02
#define FC_PORT_ROLE_IP_PORT 0x04
#define FC_PORT_ROLE_FCP_DUMMY_INITIATOR 0x08
+#define FC_PORT_ROLE_NVME_INITIATOR 0x10
+#define FC_PORT_ROLE_NVME_TARGET 0x20
+#define FC_PORT_ROLE_NVME_DISCOVERY 0x40
/* The following are for compatibility */
#define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN
@@ -298,6 +286,36 @@ struct fc_rport_identifiers {
u32 roles;
};
+/*
+ * Fabric Performance Impact Notification Statistics
+ */
+struct fc_fpin_stats {
+ /* Delivery */
+ u64 dn;
+ u64 dn_unknown;
+ u64 dn_timeout;
+ u64 dn_unable_to_route;
+ u64 dn_device_specific;
+
+ /* Link Integrity */
+ u64 li;
+ u64 li_failure_unknown;
+ u64 li_link_failure_count;
+ u64 li_loss_of_sync_count;
+ u64 li_loss_of_signals_count;
+ u64 li_prim_seq_err_count;
+ u64 li_invalid_tx_word_count;
+ u64 li_invalid_crc_count;
+ u64 li_device_specific;
+
+ /* Congestion/Peer Congestion */
+ u64 cn;
+ u64 cn_clear;
+ u64 cn_lost_credit;
+ u64 cn_credit_stall;
+ u64 cn_oversubscription;
+ u64 cn_device_specific;
+};
/* Macro for use in defining Remote Port attributes */
#define FC_RPORT_ATTR(_name,_mode,_show,_store) \
@@ -339,6 +357,7 @@ struct fc_rport { /* aka fc_starget_attrs */
/* Dynamic Attributes */
u32 dev_loss_tmo; /* Remote Port loss timeout in seconds. */
+ struct fc_fpin_stats fpin_stats;
/* Private (Transport-managed) Attributes */
u64 node_name;
@@ -364,6 +383,8 @@ struct fc_rport { /* aka fc_starget_attrs */
struct work_struct stgt_delete_work;
struct work_struct rport_delete_work;
struct request_queue *rqst_q; /* bsg support */
+
+ struct workqueue_struct *devloss_work_q;
} __attribute__((aligned(sizeof(unsigned long))));
/* bit field values for struct fc_rport "flags" field: */
@@ -450,6 +471,9 @@ struct fc_host_statistics {
u64 fc_seq_not_found; /* seq is not found for exchange */
u64 fc_non_bls_resp; /* a non BLS response frame with
a sequence responder in new exch */
+ /* Host Congestion Signals */
+ u64 cn_sig_warn;
+ u64 cn_sig_alarm;
};
@@ -473,6 +497,8 @@ enum fc_host_event_code {
FCH_EVT_PORT_ONLINE = 0x202,
FCH_EVT_PORT_FABRIC = 0x204,
FCH_EVT_LINK_UNKNOWN = 0x500,
+ FCH_EVT_LINK_FPIN = 0x501,
+ FCH_EVT_LINK_FPIN_ACK = 0x502,
FCH_EVT_VENDOR_UNIQUE = 0xffff,
};
@@ -494,10 +520,11 @@ enum fc_host_event_code {
* managed by the transport w/o driver interaction.
*/
+#define FC_VENDOR_IDENTIFIER 8
#define FC_FC4_LIST_SIZE 32
#define FC_SYMBOLIC_NAME_SIZE 256
#define FC_VERSION_STRING_SIZE 64
-#define FC_SERIAL_NUMBER_SIZE 80
+#define FC_SERIAL_NUMBER_SIZE 64
struct fc_host_attrs {
/* Fixed Attributes */
@@ -509,6 +536,10 @@ struct fc_host_attrs {
u32 supported_speeds;
u32 maxframe_size;
u16 max_npiv_vports;
+ u32 max_ct_payload;
+ u32 num_ports;
+ u32 num_discovered_ports;
+ u32 bootbios_state;
char serial_number[FC_SERIAL_NUMBER_SIZE];
char manufacturer[FC_SERIAL_NUMBER_SIZE];
char model[FC_SYMBOLIC_NAME_SIZE];
@@ -517,6 +548,9 @@ struct fc_host_attrs {
char driver_version[FC_VERSION_STRING_SIZE];
char firmware_version[FC_VERSION_STRING_SIZE];
char optionrom_version[FC_VERSION_STRING_SIZE];
+ char vendor_identifier[FC_VENDOR_IDENTIFIER];
+ char bootbios_version[FC_SYMBOLIC_NAME_SIZE];
+
/* Dynamic Attributes */
u32 port_id;
@@ -528,6 +562,7 @@ struct fc_host_attrs {
char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
char system_hostname[FC_SYMBOLIC_NAME_SIZE];
u32 dev_loss_tmo;
+ struct fc_fpin_stats fpin_stats;
/* Private (Transport-managed) Attributes */
enum fc_tgtid_binding_type tgtid_bind_type;
@@ -542,13 +577,13 @@ struct fc_host_attrs {
u16 npiv_vports_inuse;
/* work queues for rport state manipulation */
- char work_q_name[20];
struct workqueue_struct *work_q;
- char devloss_work_q_name[20];
- struct workqueue_struct *devloss_work_q;
/* bsg support */
struct request_queue *rqst_q;
+
+ /* FDMI support version*/
+ u8 fdmi_version;
};
#define shost_to_fc_host(x) \
@@ -618,16 +653,22 @@ struct fc_host_attrs {
(((struct fc_host_attrs *)(x)->shost_data)->next_vport_number)
#define fc_host_npiv_vports_inuse(x) \
(((struct fc_host_attrs *)(x)->shost_data)->npiv_vports_inuse)
-#define fc_host_work_q_name(x) \
- (((struct fc_host_attrs *)(x)->shost_data)->work_q_name)
#define fc_host_work_q(x) \
(((struct fc_host_attrs *)(x)->shost_data)->work_q)
-#define fc_host_devloss_work_q_name(x) \
- (((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q_name)
-#define fc_host_devloss_work_q(x) \
- (((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q)
#define fc_host_dev_loss_tmo(x) \
(((struct fc_host_attrs *)(x)->shost_data)->dev_loss_tmo)
+#define fc_host_max_ct_payload(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->max_ct_payload)
+#define fc_host_vendor_identifier(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->vendor_identifier)
+#define fc_host_num_discovered_ports(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->num_discovered_ports)
+#define fc_host_num_ports(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->num_ports)
+#define fc_host_bootbios_version(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->bootbios_version)
+#define fc_host_bootbios_state(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->bootbios_state)
/* The functions by which the transport class and the driver communicate */
struct fc_function_template {
@@ -661,6 +702,7 @@ struct fc_function_template {
int (*vport_delete)(struct fc_vport *);
/* bsg support */
+ u32 max_bsg_segments;
int (*bsg_request)(struct bsg_job *);
int (*bsg_timeout)(struct bsg_job *);
@@ -719,14 +761,12 @@ struct fc_function_template {
unsigned long disable_target_scan:1;
};
-
/**
* fc_remote_port_chkready - called to validate the remote port state
* prior to initiating io to the port.
- *
- * Returns a scsi result code that can be returned by the LLDD.
- *
* @rport: remote port to be checked
+ *
+ * Returns: a scsi result code that can be returned by the LLDD.
**/
static inline int
fc_remote_port_chkready(struct fc_rport *rport)
@@ -735,6 +775,7 @@ fc_remote_port_chkready(struct fc_rport *rport)
switch (rport->port_state) {
case FC_PORTSTATE_ONLINE:
+ case FC_PORTSTATE_MARGINAL:
if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
result = 0;
else if (rport->flags & FC_RPORT_DEVLOSS_PENDING)
@@ -755,7 +796,7 @@ fc_remote_port_chkready(struct fc_rport *rport)
return result;
}
-static inline u64 wwn_to_u64(u8 *wwn)
+static inline u64 wwn_to_u64(const u8 *wwn)
{
return get_unaligned_be64(wwn);
}
@@ -798,17 +839,26 @@ u32 fc_get_event_number(void);
void fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
enum fc_host_event_code event_code, u32 event_data);
void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
- u32 data_len, char * data_buf, u64 vendor_id);
+ u32 data_len, char *data_buf, u64 vendor_id);
+struct fc_rport *fc_find_rport_by_wwpn(struct Scsi_Host *shost, u64 wwpn);
+void fc_host_post_fc_event(struct Scsi_Host *shost, u32 event_number,
+ enum fc_host_event_code event_code,
+ u32 data_len, char *data_buf, u64 vendor_id);
/* Note: when specifying vendor_id to fc_host_post_vendor_event()
- * be sure to read the Vendor Type and ID formatting requirements
- * specified in scsi_netlink.h
+ * or fc_host_post_fc_event(), be sure to read the Vendor Type
+ * and ID formatting requirements specified in scsi_netlink.h
+ * Note: when calling fc_host_post_fc_event(), vendor_id may be
+ * specified as 0.
*/
+void fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf,
+ u8 event_acknowledge);
struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
struct fc_vport_identifiers *);
int fc_vport_terminate(struct fc_vport *vport);
int fc_block_rport(struct fc_rport *rport);
int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
-enum blk_eh_timer_return fc_eh_timed_out(struct scsi_cmnd *scmd);
+enum scsi_timeout_action fc_eh_timed_out(struct scsi_cmnd *scmd);
+bool fc_eh_should_retry_cmd(struct scsi_cmnd *scmd);
static inline struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job)
{
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index b266d2a3bcb1..76de2b662f4f 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* iSCSI transport class definitions
*
@@ -5,20 +6,6 @@
* Copyright (C) Mike Christie, 2004 - 2006
* Copyright (C) Dmitry Yusupov, 2004 - 2005
* Copyright (C) Alex Aizman, 2004 - 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SCSI_TRANSPORT_ISCSI_H
#define SCSI_TRANSPORT_ISCSI_H
@@ -70,7 +57,7 @@ struct iscsi_bus_flash_conn;
* When not offloading the data path, this is called
* from the scsi work queue without the session lock.
* @xmit_task Requests LLD to transfer cmd task. Returns 0 or the
- * the number of bytes transferred on success, and -Exyz
+ * number of bytes transferred on success, and -Exyz
* value on error. When offloading the data path, this
* is called from queuecommand with the session lock, or
* from the iscsi_conn_send_pdu context with the session
@@ -95,6 +82,7 @@ struct iscsi_transport {
void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid);
+ void (*unbind_conn) (struct iscsi_cls_conn *conn, bool is_active);
int (*bind_conn) (struct iscsi_cls_session *session,
struct iscsi_cls_conn *cls_conn,
uint64_t transport_eph, int is_leading);
@@ -174,7 +162,7 @@ struct iscsi_transport {
* transport registration upcalls
*/
extern struct scsi_transport_template *iscsi_register_transport(struct iscsi_transport *tt);
-extern int iscsi_unregister_transport(struct iscsi_transport *tt);
+extern void iscsi_unregister_transport(struct iscsi_transport *tt);
/*
* control plane upcalls
@@ -201,15 +189,35 @@ extern void iscsi_ping_comp_event(uint32_t host_no,
uint32_t status, uint32_t pid,
uint32_t data_size, uint8_t *data);
+/* iscsi class connection state */
+enum iscsi_connection_state {
+ ISCSI_CONN_UP = 0,
+ ISCSI_CONN_DOWN,
+ ISCSI_CONN_FAILED,
+ ISCSI_CONN_BOUND,
+};
+
+#define ISCSI_CLS_CONN_BIT_CLEANUP 1
+
struct iscsi_cls_conn {
struct list_head conn_list; /* item in connlist */
void *dd_data; /* LLD private data */
struct iscsi_transport *transport;
uint32_t cid; /* connection id */
+ /*
+ * This protects the conn startup and binding/unbinding of the ep to
+ * the conn. Unbinding includes ep_disconnect and stop_conn.
+ */
struct mutex ep_mutex;
struct iscsi_endpoint *ep;
+ /* Used when accessing flags and queueing work. */
+ spinlock_t lock;
+ unsigned long flags;
+ struct work_struct cleanup_work;
+
struct device dev; /* sysfs transport/container device */
+ enum iscsi_connection_state state;
};
#define iscsi_dev_to_conn(_dev) \
@@ -228,6 +236,14 @@ enum {
ISCSI_SESSION_FREE,
};
+enum {
+ ISCSI_SESSION_TARGET_UNBOUND,
+ ISCSI_SESSION_TARGET_ALLOCATED,
+ ISCSI_SESSION_TARGET_SCANNED,
+ ISCSI_SESSION_TARGET_UNBINDING,
+ ISCSI_SESSION_TARGET_MAX,
+};
+
#define ISCSI_MAX_TARGET -1
struct iscsi_cls_session {
@@ -238,12 +254,15 @@ struct iscsi_cls_session {
struct work_struct unblock_work;
struct work_struct scan_work;
struct work_struct unbind_work;
+ struct work_struct destroy_work;
/* recovery fields */
int recovery_tmo;
bool recovery_tmo_sysfs_override;
struct delayed_work recovery_work;
+ struct workqueue_struct *workq;
+
unsigned int target_id;
bool ida_used;
@@ -253,6 +272,7 @@ struct iscsi_cls_session {
*/
pid_t creator;
int state;
+ int target_state; /* session target bind state */
int sid; /* session id */
void *dd_data; /* LLD private data */
struct device dev; /* sysfs transport/container device */
@@ -271,7 +291,6 @@ struct iscsi_cls_session {
iscsi_dev_to_session(_stgt->dev.parent)
struct iscsi_cls_host {
- atomic_t nr_scans;
struct mutex mutex;
struct request_queue *bsg_q;
uint32_t port_speed;
@@ -287,7 +306,7 @@ extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
struct iscsi_endpoint {
void *dd_data; /* LLD private data */
struct device dev;
- uint64_t id;
+ int id;
struct iscsi_cls_conn *conn;
};
@@ -428,28 +447,27 @@ extern int iscsi_add_session(struct iscsi_cls_session *session,
unsigned int target_id);
extern int iscsi_session_event(struct iscsi_cls_session *session,
enum iscsi_uevent_e event);
-extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
- struct iscsi_transport *t,
- int dd_size,
- unsigned int target_id);
+extern void iscsi_force_destroy_session(struct iscsi_cls_session *session);
extern void iscsi_remove_session(struct iscsi_cls_session *session);
extern void iscsi_free_session(struct iscsi_cls_session *session);
-extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
+extern struct iscsi_cls_conn *iscsi_alloc_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
-extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
+extern int iscsi_add_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_remove_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
extern void iscsi_unblock_session(struct iscsi_cls_session *session);
extern void iscsi_block_session(struct iscsi_cls_session *session);
-extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
+extern void iscsi_put_endpoint(struct iscsi_endpoint *ep);
extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd);
extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
struct iscsi_transport *t,
uint32_t iface_type,
uint32_t iface_num, int dd_size);
extern void iscsi_destroy_iface(struct iscsi_iface *iface);
-extern struct iscsi_iface *iscsi_lookup_iface(int handle);
extern char *iscsi_get_port_speed_name(struct Scsi_Host *shost);
extern char *iscsi_get_port_state_name(struct Scsi_Host *shost);
extern int iscsi_is_session_dev(const struct device *dev);
@@ -473,10 +491,10 @@ iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess);
extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost);
extern int iscsi_flashnode_bus_match(struct device *dev,
- struct device_driver *drv);
+ const struct device_driver *drv);
extern struct device *
-iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
- int (*fn)(struct device *dev, void *data));
+iscsi_find_flashnode_sess(struct Scsi_Host *shost, const void *data,
+ device_match_t fn);
extern struct device *
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess);
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h
index 05ec927a3c72..e3b6ce3cbf88 100644
--- a/include/scsi/scsi_transport_sas.h
+++ b/include/scsi/scsi_transport_sas.h
@@ -41,6 +41,7 @@ enum sas_linkrate {
SAS_LINK_RATE_G2 = SAS_LINK_RATE_3_0_GBPS,
SAS_LINK_RATE_6_0_GBPS = 10,
SAS_LINK_RATE_12_0_GBPS = 11,
+ SAS_LINK_RATE_22_5_GBPS = 12,
/* These are virtual to the transport class and may never
* be signalled normally since the standard defined field
* is only 4 bits */
@@ -199,6 +200,8 @@ unsigned int sas_is_tlr_enabled(struct scsi_device *);
void sas_disable_tlr(struct scsi_device *);
void sas_enable_tlr(struct scsi_device *);
+bool sas_ata_ncq_prio_supported(struct scsi_device *sdev);
+
extern struct sas_rphy *sas_end_device_alloc(struct sas_port *);
extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type);
void sas_rphy_free(struct sas_rphy *);
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index a4fa52b4d5c5..78324502b1c9 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Parallel SCSI (SPI) transport specific attributes exported to sysfs.
*
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SCSI_TRANSPORT_SPI_H
#define SCSI_TRANSPORT_SPI_H
diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h
index d22df12584f9..5b70b538447e 100644
--- a/include/scsi/scsi_transport_srp.h
+++ b/include/scsi/scsi_transport_srp.h
@@ -74,7 +74,7 @@ struct srp_rport {
};
/**
- * struct srp_function_template
+ * struct srp_function_template - template for SRP initiator drivers
*
* Fields that are only relevant for SRP initiator drivers:
* @has_rport_state: Whether or not to create the state, fast_io_fail_tmo and
@@ -118,13 +118,13 @@ extern int srp_reconnect_rport(struct srp_rport *rport);
extern void srp_start_tl_fail_timers(struct srp_rport *rport);
extern void srp_remove_host(struct Scsi_Host *);
extern void srp_stop_rport_timers(struct srp_rport *rport);
-enum blk_eh_timer_return srp_timed_out(struct scsi_cmnd *scmd);
+enum scsi_timeout_action srp_timed_out(struct scsi_cmnd *scmd);
/**
* srp_chkready() - evaluate the transport layer state before I/O
* @rport: SRP target port pointer.
*
- * Returns a SCSI result code that can be returned by the LLD queuecommand()
+ * Returns: a SCSI result code that can be returned by the LLD queuecommand()
* implementation. The role of this function is similar to that of
* fc_remote_port_chkready().
*/
diff --git a/include/scsi/scsicam.h b/include/scsi/scsicam.h
index 57c729254569..1131f51ed2c8 100644
--- a/include/scsi/scsicam.h
+++ b/include/scsi/scsicam.h
@@ -13,8 +13,8 @@
#ifndef SCSICAM_H
#define SCSICAM_H
-extern int scsicam_bios_param (struct block_device *bdev, sector_t capacity, int *ip);
-extern int scsi_partsize(unsigned char *buf, unsigned long capacity,
- unsigned int *cyls, unsigned int *hds, unsigned int *secs);
-extern unsigned char *scsi_bios_ptable(struct block_device *bdev);
+struct gendisk;
+int scsicam_bios_param(struct gendisk *disk, sector_t capacity, int *ip);
+bool scsi_partsize(struct gendisk *disk, sector_t capacity, int geom[3]);
+unsigned char *scsi_bios_ptable(struct gendisk *disk);
#endif /* def SCSICAM_H */
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index f91bcca604e4..af31cecd9012 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -24,15 +24,11 @@
* http://sg.danny.cz/sg [alternatively check the MAINTAINERS file]
* The documentation for the sg version 3 driver can be found at:
* http://sg.danny.cz/sg/p/sg_v3_ho.html
- * Also see: <kernel_source>/Documentation/scsi/scsi-generic.txt
+ * Also see: <kernel_source>/Documentation/scsi/scsi-generic.rst
*
* For utility and test programs see: http://sg.danny.cz/sg/sg3_utils.html
*/
-#ifdef __KERNEL__
-extern int sg_big_buff; /* for sysctl */
-#endif
-
typedef struct sg_iovec /* same structure as used by readv() Linux system */
{ /* call. It defines one scatter-gather element. */
@@ -68,6 +64,36 @@ typedef struct sg_io_hdr
unsigned int info; /* [o] auxiliary information */
} sg_io_hdr_t; /* 64 bytes long (on i386) */
+#if defined(__KERNEL__)
+#include <linux/compat.h>
+
+struct compat_sg_io_hdr {
+ compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */
+ compat_int_t dxfer_direction; /* [i] data transfer direction */
+ unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
+ unsigned char mx_sb_len; /* [i] max length to write to sbp */
+ unsigned short iovec_count; /* [i] 0 implies no scatter gather */
+ compat_uint_t dxfer_len; /* [i] byte count of data transfer */
+ compat_uint_t dxferp; /* [i], [*io] points to data transfer memory
+ or scatter gather list */
+ compat_uptr_t cmdp; /* [i], [*i] points to command to perform */
+ compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */
+ compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
+ compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */
+ compat_int_t pack_id; /* [i->o] unused internally (normally) */
+ compat_uptr_t usr_ptr; /* [i->o] unused internally */
+ unsigned char status; /* [o] scsi status */
+ unsigned char masked_status; /* [o] shifted, masked scsi status */
+ unsigned char msg_status; /* [o] messaging level data (optional) */
+ unsigned char sb_len_wr; /* [o] byte count actually written to sbp */
+ unsigned short host_status; /* [o] errors from host adapter */
+ unsigned short driver_status; /* [o] errors from software driver */
+ compat_int_t resid; /* [o] dxfer_len - actual_transferred */
+ compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */
+ compat_uint_t info; /* [o] auxiliary information */
+};
+#endif
+
#define SG_INTERFACE_ID_ORIG 'S'
/* Use negative values to flag difference from original sg_header structure */
@@ -101,6 +127,39 @@ typedef struct sg_io_hdr
#define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */
#define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */
+/*
+ * Obsolete DRIVER_SENSE driver byte
+ *
+ * Originally the SCSI midlayer would set the DRIVER_SENSE driver byte when
+ * a sense code was generated and a sense buffer was allocated.
+ * However, as nowadays every scsi command has a sense code allocated this
+ * distinction became moot as one could check the sense buffer directly.
+ * Consequently this byte is not set anymore from the midlayer, but SG will
+ * keep setting this byte to be compatible with previous releases.
+ */
+#define DRIVER_SENSE 0x08
+/* Obsolete driver_byte() declaration */
+#define driver_byte(result) (((result) >> 24) & 0xff)
+
+/*
+ * Original linux SCSI Status codes. They are shifted 1 bit right
+ * from those found in the SCSI standards.
+ */
+
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+#define ACA_ACTIVE 0x18
+#define TASK_ABORTED 0x20
+
+/* Obsolete status_byte() declaration */
+#define sg_status_byte(result) (((result) >> 1) & 0x7f)
typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */
int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */
@@ -115,7 +174,7 @@ typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */
typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
char req_state; /* 0 -> not used, 1 -> written, 2 -> ready to read */
- char orphan; /* 0 -> normal request, 1 -> from interruped SG_IO */
+ char orphan; /* 0 -> normal request, 1 -> from interrupted SG_IO */
char sg_io_owned; /* 0 -> complete with read(), 1 -> owned by SG_IO */
char problem; /* 0 -> no problem detected, 1 -> error to report */
int pack_id; /* pack_id associated with request */
diff --git a/include/scsi/srp.h b/include/scsi/srp.h
index 9220758d5087..dfe0984b58a9 100644
--- a/include/scsi/srp.h
+++ b/include/scsi/srp.h
@@ -107,10 +107,10 @@ struct srp_direct_buf {
* having the 20-byte structure padded to 24 bytes on 64-bit architectures.
*/
struct srp_indirect_buf {
- struct srp_direct_buf table_desc;
+ struct srp_direct_buf table_desc __packed __aligned(4);
__be32 len;
- struct srp_direct_buf desc_list[0];
-} __attribute__((packed));
+ struct srp_direct_buf desc_list[] __packed __aligned(4);
+};
/* Immediate data buffer descriptor as defined in SRP2. */
struct srp_imm_buf {
@@ -175,13 +175,13 @@ struct srp_login_rsp {
u8 opcode;
u8 reserved1[3];
__be32 req_lim_delta;
- u64 tag;
+ u64 tag __packed __aligned(4);
__be32 max_it_iu_len;
__be32 max_ti_iu_len;
__be16 buf_fmt;
u8 rsp_flags;
u8 reserved2[25];
-} __attribute__((packed));
+};
struct srp_login_rej {
u8 opcode;
@@ -207,10 +207,6 @@ struct srp_t_logout {
u64 tag;
};
-/*
- * We need the packed attribute because the SRP spec only aligns the
- * 8-byte LUN field to 4 bytes.
- */
struct srp_tsk_mgmt {
u8 opcode;
u8 sol_not;
@@ -225,10 +221,6 @@ struct srp_tsk_mgmt {
u8 reserved5[8];
};
-/*
- * We need the packed attribute because the SRP spec only aligns the
- * 8-byte LUN field to 4 bytes.
- */
struct srp_cmd {
u8 opcode;
u8 sol_not;
@@ -244,7 +236,7 @@ struct srp_cmd {
u8 reserved4;
u8 add_cdb_len;
u8 cdb[16];
- u8 add_data[0];
+ u8 add_data[];
};
enum {
@@ -266,7 +258,7 @@ struct srp_rsp {
u8 sol_not;
u8 reserved1[2];
__be32 req_lim_delta;
- u64 tag;
+ u64 tag __packed __aligned(4);
u8 reserved2[2];
u8 flags;
u8 status;
@@ -274,8 +266,8 @@ struct srp_rsp {
__be32 data_in_res_cnt;
__be32 sense_data_len;
__be32 resp_data_len;
- u8 data[0];
-} __attribute__((packed));
+ u8 data[];
+};
struct srp_cred_req {
u8 opcode;
@@ -301,13 +293,13 @@ struct srp_aer_req {
u8 sol_not;
u8 reserved[2];
__be32 req_lim_delta;
- u64 tag;
+ u64 tag __packed __aligned(4);
u32 reserved2;
struct scsi_lun lun;
__be32 sense_data_len;
u32 reserved3;
- u8 sense_data[0];
-} __attribute__((packed));
+ u8 sense_data[];
+};
struct srp_aer_rsp {
u8 opcode;
diff --git a/include/scsi/viosrp.h b/include/scsi/viosrp.h
index 974e07bd8e59..6c5559d2b285 100644
--- a/include/scsi/viosrp.h
+++ b/include/scsi/viosrp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*****************************************************************************/
/* srp.h -- SCSI RDMA Protocol definitions */
/* */
@@ -5,15 +6,6 @@
/* */
/* Copyright (C) 2003 IBM Corporation */
/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or */
-/* (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
/* */
/* This file contains structures and definitions for IBM RPA (RS/6000 */
/* platform architecture) implementation of the SRP (SCSI RDMA Protocol) */
@@ -78,12 +70,17 @@ enum viosrp_crq_status {
};
struct viosrp_crq {
- u8 valid; /* used by RPA */
- u8 format; /* SCSI vs out-of-band */
- u8 reserved;
- u8 status; /* non-scsi failure? (e.g. DMA failure) */
- __be16 timeout; /* in seconds */
- __be16 IU_length; /* in bytes */
+ union {
+ __be64 high; /* High 64 bits */
+ struct {
+ u8 valid; /* used by RPA */
+ u8 format; /* SCSI vs out-of-band */
+ u8 reserved;
+ u8 status; /* non-scsi failure? (e.g. DMA failure) */
+ __be16 timeout; /* in seconds */
+ __be16 IU_length; /* in bytes */
+ };
+ };
__be64 IU_data_ptr; /* the TCE for transferring data */
};