linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Boot <bootc@bootc.net>
To: linux1394-devel@lists.sourceforge.net, target-devel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, agrover@redhat.com,
	clemens@ladisch.de, nab@linux-iscsi.org,
	stefanr@s5r6.in-berlin.de, Chris Boot <bootc@bootc.net>
Subject: [PATCH v2 06/11] firewire-sbp-target: Add sbp_fabric.{c,h}
Date: Wed, 15 Feb 2012 14:47:23 +0000	[thread overview]
Message-ID: <1329317248-94128-7-git-send-email-bootc@bootc.net> (raw)
In-Reply-To: <1329317248-94128-1-git-send-email-bootc@bootc.net>

This serves as further glue between the target framework and SBP-2, in
this case dealing with SCSI command submission and data in/out.

Signed-off-by: Chris Boot <bootc@bootc.net>
Cc: Andy Grover <agrover@redhat.com>
Cc: Clemens Ladisch <clemens@ladisch.de>
Cc: Nicholas A. Bellinger <nab@linux-iscsi.org>
Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
 drivers/target/sbp/sbp_fabric.c |  353 +++++++++++++++++++++++++++++++++++++++
 drivers/target/sbp/sbp_fabric.h |   42 +++++
 2 files changed, 395 insertions(+), 0 deletions(-)
 create mode 100644 drivers/target/sbp/sbp_fabric.c
 create mode 100644 drivers/target/sbp/sbp_fabric.h

diff --git a/drivers/target/sbp/sbp_fabric.c b/drivers/target/sbp/sbp_fabric.c
new file mode 100644
index 0000000..354ef93
--- /dev/null
+++ b/drivers/target/sbp/sbp_fabric.c
@@ -0,0 +1,353 @@
+/*
+ * SBP2 target driver (SCSI over IEEE1394 in target mode)
+ *
+ * Copyright (C) 2011  Chris Boot <bootc@bootc.net>
+ *
+ * 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.
+ */
+
+#define KMSG_COMPONENT "sbp_target"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/firewire.h>
+
+#include <asm/unaligned.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/libfc.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+
+#include "sbp_base.h"
+#include "sbp_fabric.h"
+#include "sbp_target_agent.h"
+#include "sbp_scsi_cmnd.h"
+
+int sbp_check_true(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+int sbp_check_false(struct se_portal_group *se_tpg)
+{
+	return 0;
+}
+
+char *sbp_get_fabric_name(void)
+{
+	return "sbp";
+}
+
+char *sbp_get_fabric_wwn(struct se_portal_group *se_tpg)
+{
+	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
+	struct sbp_tport *tport = tpg->tport;
+
+	return &tport->tport_name[0];
+}
+
+u16 sbp_get_tag(struct se_portal_group *se_tpg)
+{
+	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
+	return tpg->tport_tpgt;
+}
+
+u32 sbp_get_default_depth(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *se_tpg)
+{
+	struct sbp_nacl *nacl;
+
+	nacl = kzalloc(sizeof(struct sbp_nacl), GFP_KERNEL);
+	if (!nacl) {
+		pr_err("Unable to alocate struct sbp_nacl\n");
+		return NULL;
+	}
+
+	return &nacl->se_node_acl;
+}
+
+void sbp_release_fabric_acl(
+	struct se_portal_group *se_tpg,
+	struct se_node_acl *se_nacl)
+{
+	struct sbp_nacl *nacl =
+		container_of(se_nacl, struct sbp_nacl, se_node_acl);
+	kfree(nacl);
+}
+
+u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+void sbp_release_cmd(struct se_cmd *se_cmd)
+{
+	struct sbp_target_request *req = container_of(se_cmd,
+			struct sbp_target_request, se_cmd);
+
+	sbp_free_request(req);
+}
+
+int sbp_shutdown_session(struct se_session *se_sess)
+{
+	return 0;
+}
+
+void sbp_close_session(struct se_session *se_sess)
+{
+	return;
+}
+
+void sbp_stop_session(struct se_session *se_sess, int sess_sleep,
+		int conn_sleep)
+{
+	return;
+}
+
+void sbp_reset_nexus(struct se_session *se_sess)
+{
+	return;
+}
+
+int sbp_sess_logged_in(struct se_session *se_sess)
+{
+	return 0;
+}
+
+u32 sbp_sess_get_index(struct se_session *se_sess)
+{
+	return 0;
+}
+
+int sbp_write_pending(struct se_cmd *se_cmd)
+{
+	struct sbp_target_request *req = container_of(se_cmd,
+			struct sbp_target_request, se_cmd);
+	int ret;
+
+	req->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL);
+	if (!req->data_buf)
+		return -ENOMEM;
+
+	ret = sbp_rw_data(req);
+	if (ret) {
+		req->status.status |= cpu_to_be32(
+			STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |
+			STATUS_BLOCK_DEAD(0) |
+			STATUS_BLOCK_LEN(1) |
+			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));
+		sbp_send_status(req);
+		pr_warn("sbp_write_pending: data write error\n");
+		return ret;
+	}
+
+	sg_copy_from_buffer(se_cmd->t_data_sg,
+			se_cmd->t_data_nents,
+			req->data_buf,
+			se_cmd->data_length);
+
+	transport_generic_process_write(se_cmd);
+
+	return 0;
+}
+
+int sbp_write_pending_status(struct se_cmd *se_cmd)
+{
+	return 0;
+}
+
+void sbp_set_default_node_attrs(struct se_node_acl *nacl)
+{
+	return;
+}
+
+u32 sbp_get_task_tag(struct se_cmd *se_cmd)
+{
+	struct sbp_target_request *req = container_of(se_cmd,
+			struct sbp_target_request, se_cmd);
+
+	/* only used for printk until we do TMRs */
+	return (u32)req->orb_pointer;
+}
+
+int sbp_get_cmd_state(struct se_cmd *se_cmd)
+{
+	return 0;
+}
+
+int sbp_queue_data_in(struct se_cmd *se_cmd)
+{
+	struct sbp_target_request *req = container_of(se_cmd,
+			struct sbp_target_request, se_cmd);
+	int ret;
+
+	req->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL);
+	if (!req->data_buf)
+		return -ENOMEM;
+
+	sg_copy_to_buffer(se_cmd->t_data_sg,
+		se_cmd->t_data_nents,
+		req->data_buf,
+		se_cmd->data_length);
+
+	ret = sbp_rw_data(req);
+	if (ret) {
+		req->status.status |= cpu_to_be32(
+			STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |
+			STATUS_BLOCK_DEAD(0) |
+			STATUS_BLOCK_LEN(1) |
+			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));
+		sbp_send_status(req);
+		return ret;
+	}
+
+	return sbp_send_sense(req);
+}
+
+/*
+ * Called after command (no data transfer) or after the write (to device)
+ * operation is completed
+ */
+int sbp_queue_status(struct se_cmd *se_cmd)
+{
+	struct sbp_target_request *req = container_of(se_cmd,
+			struct sbp_target_request, se_cmd);
+
+	return sbp_send_sense(req);
+}
+
+int sbp_queue_tm_rsp(struct se_cmd *se_cmd)
+{
+	return 0;
+}
+
+u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
+{
+	return 0;
+}
+
+u16 sbp_get_fabric_sense_len(void)
+{
+	return 0;
+}
+
+int sbp_is_state_remove(struct se_cmd *se_cmd)
+{
+	return 0;
+}
+
+int sbp_check_stop_free(struct se_cmd *se_cmd)
+{
+	struct sbp_target_request *req = container_of(se_cmd,
+			struct sbp_target_request, se_cmd);
+
+	transport_generic_free_cmd(&req->se_cmd, 0);
+	return 1;
+}
+
+/*
+ * Handlers for Serial Bus Protocol 2/3 (SBP-2 / SBP-3)
+ */
+u8 sbp_get_fabric_proto_ident(struct se_portal_group *se_tpg)
+{
+	/*
+	 * Return a IEEE 1394 SCSI Protocol identifier for loopback operations
+	 * This is defined in section 7.5.1 Table 362 in spc4r17
+	 */
+	return SCSI_PROTOCOL_SBP;
+}
+
+u32 sbp_get_pr_transport_id(
+	struct se_portal_group *se_tpg,
+	struct se_node_acl *se_nacl,
+	struct t10_pr_registration *pr_reg,
+	int *format_code,
+	unsigned char *buf)
+{
+	int ret;
+
+	/*
+	 * Set PROTOCOL IDENTIFIER to 3h for SBP
+	 */
+	buf[0] = SCSI_PROTOCOL_SBP;
+	/*
+	 * From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI
+	 * over IEEE 1394
+	 */
+	ret = hex2bin(&buf[8], se_nacl->initiatorname, 8);
+	if (ret < 0)
+		pr_debug("sbp transport_id: invalid hex string\n");
+
+	/*
+	 * The IEEE 1394 Transport ID is a hardcoded 24-byte length
+	 */
+	return 24;
+}
+
+u32 sbp_get_pr_transport_id_len(
+	struct se_portal_group *se_tpg,
+	struct se_node_acl *se_nacl,
+	struct t10_pr_registration *pr_reg,
+	int *format_code)
+{
+	*format_code = 0;
+	/*
+	 * From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI
+	 * over IEEE 1394
+	 *
+	 * The SBP Transport ID is a hardcoded 24-byte length
+	 */
+	return 24;
+}
+
+/*
+ * Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
+ * Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
+ */
+char *sbp_parse_pr_out_transport_id(
+	struct se_portal_group *se_tpg,
+	const char *buf,
+	u32 *out_tid_len,
+	char **port_nexus_ptr)
+{
+	/*
+	 * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.4 TransportID
+	 * for initiator ports using SCSI over SBP Serial SCSI Protocol
+	 *
+	 * The TransportID for a IEEE 1394 Initiator Port is of fixed size of
+	 * 24 bytes, and IEEE 1394 does not contain a I_T nexus identifier,
+	 * so we return the **port_nexus_ptr set to NULL.
+	 */
+	*port_nexus_ptr = NULL;
+	*out_tid_len = 24;
+
+	return (char *)&buf[8];
+}
+
diff --git a/drivers/target/sbp/sbp_fabric.h b/drivers/target/sbp/sbp_fabric.h
new file mode 100644
index 0000000..eb757a0
--- /dev/null
+++ b/drivers/target/sbp/sbp_fabric.h
@@ -0,0 +1,42 @@
+
+int sbp_check_true(struct se_portal_group *);
+int sbp_check_false(struct se_portal_group *);
+char *sbp_get_fabric_name(void);
+char *sbp_get_fabric_wwn(struct se_portal_group *);
+u16 sbp_get_tag(struct se_portal_group *);
+u32 sbp_get_default_depth(struct se_portal_group *);
+struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *);
+void sbp_release_fabric_acl(struct se_portal_group *,
+		struct se_node_acl *);
+u32 sbp_tpg_get_inst_index(struct se_portal_group *);
+void sbp_release_cmd(struct se_cmd *se_cmd);
+int sbp_shutdown_session(struct se_session *);
+void sbp_close_session(struct se_session *);
+void sbp_stop_session(struct se_session *, int, int);
+void sbp_reset_nexus(struct se_session *);
+int sbp_sess_logged_in(struct se_session *);
+u32 sbp_sess_get_index(struct se_session *);
+int sbp_write_pending(struct se_cmd *);
+int sbp_write_pending_status(struct se_cmd *);
+void sbp_set_default_node_attrs(struct se_node_acl *);
+u32 sbp_get_task_tag(struct se_cmd *);
+int sbp_get_cmd_state(struct se_cmd *);
+int sbp_queue_data_in(struct se_cmd *);
+int sbp_queue_status(struct se_cmd *);
+int sbp_queue_tm_rsp(struct se_cmd *);
+u16 sbp_set_fabric_sense_len(struct se_cmd *, u32);
+u16 sbp_get_fabric_sense_len(void);
+int sbp_is_state_remove(struct se_cmd *);
+int sbp_check_stop_free(struct se_cmd *se_cmd);
+
+u8 sbp_get_fabric_proto_ident(struct se_portal_group *se_tpg);
+u32 sbp_get_pr_transport_id(struct se_portal_group *se_tpg,
+		struct se_node_acl *se_nacl, struct t10_pr_registration *pr_reg,
+		int *format_code, unsigned char *buf);
+u32 sbp_get_pr_transport_id_len(
+		struct se_portal_group *se_tpg, struct se_node_acl *se_nacl,
+		struct t10_pr_registration *pr_reg, int *format_code);
+char *sbp_parse_pr_out_transport_id(
+		struct se_portal_group *se_tpg, const char *buf,
+		u32 *out_tid_len, char **port_nexus_ptr);
+
-- 
1.7.9


  parent reply	other threads:[~2012-02-15 14:54 UTC|newest]

Thread overview: 100+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-17 14:51 FireWire/SBP2 Target mode Chris Boot
2011-08-17 18:57 ` Stefan Richter
2011-08-18 16:19 ` Clemens Ladisch
2012-02-01 19:50   ` Andy Grover
2012-02-01 21:41     ` Stefan Richter
2012-02-02  9:22       ` Boaz Harrosh
2012-02-02 10:09         ` Clemens Ladisch
2012-02-06 13:13           ` Chris Boot
2012-02-06 14:43             ` Clemens Ladisch
2012-02-06 14:51               ` Chris Boot
2012-02-06 20:26                 ` Stefan Richter
2012-02-06 22:28                   ` Chris Boot
2012-02-06 23:00                     ` Julian Calaby
2012-02-06 23:09                       ` Chris Boot
2012-02-07  7:38                         ` Chris Boot
2012-02-07 10:06                           ` Julian Calaby
2012-02-07 19:17                           ` Stefan Richter
2012-02-07 19:53                             ` Chris Boot
2012-02-11 19:43 ` [RFC][PATCH 00/13] firewire-sbp-target: FireWire SBP-2 SCSI target Chris Boot
2012-02-11 19:44   ` [PATCH 01/13] firewire: Add function to get speed from opaque struct fw_request Chris Boot
2012-02-11 19:44   ` [PATCH 02/13] firewire: Add EXPORT_SYMBOL_GPL(fw_card_release) Chris Boot
2012-02-11 19:44   ` [PATCH 03/13] firewire-sbp-target: Add Kconfig, Makefile and TODO Chris Boot
2012-02-13 12:50     ` Nicholas A. Bellinger
2012-02-11 19:44   ` [PATCH 04/13] firewire-sbp-target: Add sbp_base.h header Chris Boot
2012-02-11 19:44   ` [PATCH 05/13] firewire-sbp-target: Add sbp_configfs.c Chris Boot
2012-02-11 19:44   ` [PATCH 06/13] firewire-sbp-target: Add sbp_fabric.{c,h} Chris Boot
2012-02-13 13:06     ` Nicholas A. Bellinger
     [not found]       ` <337FFBD7-6B4A-41CA-BB57-6038C935B5BF@bootc.net>
2012-02-13 19:53         ` Stefan Richter
2012-02-13 22:41         ` Nicholas A. Bellinger
2012-02-11 19:44   ` [PATCH 07/13] firewire-sbp-target: Add sbp_proto.{c,h} Chris Boot
2012-02-11 19:44   ` [PATCH 08/13] firewire-sbp-target: add sbp_management_agent.{c,h} Chris Boot
2012-02-11 19:44   ` [PATCH 09/13] firewire-sbp-target: Add sbp_login.{c,h} Chris Boot
2012-02-11 19:44   ` [PATCH 10/13] firewire-sbp-target: Add sbp_target_agent.{c,h} Chris Boot
2012-02-11 19:44   ` [PATCH 11/13] firewire-sbp-target: Add sbp_scsi_cmnd.{c,h} Chris Boot
2012-02-11 19:44   ` [PATCH 12/13] firewire-sbp-target: Add sbp_util.{c,h} Chris Boot
2012-02-11 19:44   ` [PATCH 13/13] firewire-sbp-target: Add to target Kconfig and Makefile Chris Boot
2012-02-12 14:12   ` [RFC][PATCH 00/13] firewire-sbp-target: FireWire SBP-2 SCSI target Stefan Richter
2012-02-12 15:13     ` Chris Boot
2012-02-12 16:16       ` Stefan Richter
2012-02-15 14:47   ` [PATCH v2 00/11] " Chris Boot
2012-02-15 14:47     ` [PATCH v2 01/11] firewire: Add function to get speed from opaque struct fw_request Chris Boot
2012-02-15 19:09       ` Stefan Richter
2012-02-15 19:10         ` Chris Boot
2012-02-15 22:01           ` Stefan Richter
2012-02-16  9:12             ` Chris Boot
2012-02-15 14:47     ` [PATCH v2 02/11] firewire: Move fw_card kref functions into linux/firewire.h Chris Boot
2012-02-15 19:10       ` Stefan Richter
2012-02-16  9:18         ` Chris Boot
2012-02-15 14:47     ` [PATCH v2 03/11] firewire-sbp-target: Add Kconfig, Makefile and TODO Chris Boot
2012-02-15 14:47     ` [PATCH v2 04/11] firewire-sbp-target: Add sbp_base.h header Chris Boot
2012-02-15 19:15       ` Stefan Richter
2012-02-16  9:55         ` Chris Boot
2012-02-15 14:47     ` [PATCH v2 05/11] firewire-sbp-target: Add sbp_configfs.c Chris Boot
2012-02-15 19:21       ` Stefan Richter
2012-02-16  9:57         ` Chris Boot
2012-02-16 13:48           ` Stefan Richter
2012-02-15 14:47     ` Chris Boot [this message]
2012-02-15 14:47     ` [PATCH v2 07/11] firewire-sbp-target: add sbp_management_agent.{c,h} Chris Boot
2012-02-15 19:48       ` Stefan Richter
2012-02-16 10:28         ` Chris Boot
2012-02-16 14:12           ` Stefan Richter
2012-02-15 14:47     ` [PATCH v2 08/11] firewire-sbp-target: Add sbp_login.{c,h} Chris Boot
2012-02-15 21:00       ` Stefan Richter
2012-02-16 11:21         ` Chris Boot
2012-03-03 17:37           ` Stefan Richter
2012-03-15 17:48             ` Paul E. McKenney
2012-02-15 14:47     ` [PATCH v2 09/11] firewire-sbp-target: Add sbp_target_agent.{c,h} Chris Boot
2012-02-15 21:27       ` Stefan Richter
2012-02-16 11:25         ` Chris Boot
2012-02-18 14:59           ` Stefan Richter
2012-02-18 15:05             ` Chris Boot
2012-02-15 14:47     ` [PATCH v2 10/11] firewire-sbp-target: Add sbp_scsi_cmnd.{c,h} Chris Boot
2012-02-15 14:47     ` [PATCH v2 11/11] firewire-sbp-target: Add to target Kconfig and Makefile Chris Boot
2012-04-11 14:20     ` [PATCH v3 00/11] firewire-sbp-target: FireWire SBP-2 SCSI target Chris Boot
2012-04-11 14:20       ` [PATCH 01/11] firewire: Add function to get speed from opaque struct fw_request Chris Boot
2012-04-11 14:20       ` [PATCH 02/11] firewire: Move fw_card kref functions into linux/firewire.h Chris Boot
2012-04-11 14:20       ` [PATCH 03/11] firewire-sbp-target: Add Kconfig, Makefile and TODO Chris Boot
2012-04-11 14:20       ` [PATCH 04/11] firewire-sbp-target: Add sbp_base.h header Chris Boot
2012-04-11 14:20       ` [PATCH 05/11] firewire-sbp-target: Add sbp_configfs.c Chris Boot
2012-04-11 14:20       ` [PATCH 06/11] firewire-sbp-target: Add sbp_fabric.{c,h} Chris Boot
2012-04-11 14:20       ` [PATCH 07/11] firewire-sbp-target: Add sbp_management_agent.{c,h} Chris Boot
2012-04-11 14:20       ` [PATCH 08/11] firewire-sbp-target: Add sbp_login.{c,h} Chris Boot
2012-04-14 10:17         ` Stefan Richter
2012-04-11 14:20       ` [PATCH 09/11] firewire-sbp-target: Add sbp_target_agent.{c,h} Chris Boot
2012-04-14 10:49         ` Stefan Richter
2012-04-14 11:33           ` Stefan Richter
2012-04-11 14:20       ` [PATCH 10/11] firewire-sbp-target: Add sbp_scsi_cmnd.{c,h} Chris Boot
2012-04-11 14:20       ` [PATCH 11/11] firewire-sbp-target: Add to target Kconfig and Makefile Chris Boot
2012-04-12 21:02       ` [PATCH v3 00/11] firewire-sbp-target: FireWire SBP-2 SCSI target Andy Grover
2012-04-13  3:03       ` Nicholas A. Bellinger
2012-04-13 13:16         ` Chris Boot
2012-04-14  1:23           ` Nicholas A. Bellinger
2012-04-14  9:12             ` [PATCH 0/2] sbp-target: cleanup after merge into single file Chris Boot
2012-04-14  9:12               ` [PATCH 1/2] sbp-target: minor cleanups after merging " Chris Boot
2012-04-14  9:12               ` [PATCH 2/2] sbp-target: update TODO file Chris Boot
2012-04-14 21:44               ` [PATCH 0/2] sbp-target: cleanup after merge into single file Nicholas A. Bellinger
2012-04-14 23:11                 ` Stefan Richter
2012-04-15  1:22                   ` Nicholas A. Bellinger
2012-04-17 10:48             ` [PATCH v3 00/11] firewire-sbp-target: FireWire SBP-2 SCSI target Chris Boot
2012-04-18  7:17               ` Nicholas A. Bellinger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1329317248-94128-7-git-send-email-bootc@bootc.net \
    --to=bootc@bootc.net \
    --cc=agrover@redhat.com \
    --cc=clemens@ladisch.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux1394-devel@lists.sourceforge.net \
    --cc=nab@linux-iscsi.org \
    --cc=stefanr@s5r6.in-berlin.de \
    --cc=target-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).