Skip to contentSkip to conversation

linux-iscsi driver

RFC PATCH In review Mike Christie 1 participant 1 message Jan 10, 2005 SCSI

lore
Share & tools
lore
#0 lore raw

RFC PATCH 9/10 linux-iscsi driver

Implements the driver interface which includes the IOCTL and sysfs files. We currently do not have any 32/64 bit conversion code but we will add it if/when we know for sure the IOCL is the correct way to go.

drivers/scsi/iscsi-sfnet/iscsi-attr.c +214 -0
diff -Naurp scsi-misc-2.6.orig/drivers/scsi/iscsi-sfnet/iscsi-attr.c scsi-misc-2.6.patch/drivers/scsi/iscsi-sfnet/iscsi-attr.c
@@ -0,0 +1,214 @@
+/*
+ * iSCSI driver for Linux
+ * Copyright (C) 2002 Cisco Systems, Inc.
+ * Copyright (C) 2004 Mike Christie
+ * Copyright (C) 2004 IBM Corporation
+ * maintained by [email protected]
+ *
+ * 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.
+ *
+ * The sysfs host attributes are defined here. 
+ */
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_host.h>
+
+#include "iscsi-session.h"
+#include "iscsi-sfnet.h"
+
+static ssize_t
+store_do_shutdown(struct class_device *class_dev, const char *buf, size_t count)
+{
+	iscsi_destroy_host(class_to_shost(class_dev));
+	return count;
+}
+
+static ssize_t
+store_drop_session(struct class_device *class_dev, const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(class_dev);
+	struct iscsi_session *session = (struct iscsi_session *)shost->hostdata;
+
+	iscsi_drop_session(session);
+	return count;
+}
+
+static CLASS_DEVICE_ATTR(shutdown, S_IWUSR, NULL, store_do_shutdown);
+static CLASS_DEVICE_ATTR(drop_session, S_IWUSR, NULL, store_drop_session);
+
+/*
+ * Macro to show session values specific to this driver
+ * on the scsi host's class dev. Some of them could also
+ * be moved to the transport class one day.
+ */
+#define session_show_function(field, format_string)			\
+static ssize_t								\
+show_##field (struct class_device *class_dev, char *buf)		\
+{									\
+	struct Scsi_Host *shost = class_to_shost(class_dev);		\
+	struct iscsi_session *session;					\
+	session = (struct iscsi_session *)shost->hostdata;		\
+	return snprintf(buf, 20, format_string, session->field);	\
+}
+
+#define session_rd_attr(field, format_string)			\
+	session_show_function(field, format_string)		\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+/*
+ * These times need to be fixed if they are going to be used
+ * by userspace. Should we also just spit out the time for the app
+ * instead.
+ */
+session_rd_attr(session_established_time, "%lu");
+session_rd_attr(session_drop_time, "%lu");
+session_rd_attr(ever_established, "%d");
+session_rd_attr(login_timeout, "%d");
+session_rd_attr(active_timeout, "%d");
+session_rd_attr(idle_timeout, "%d");
+session_rd_attr(ping_timeout, "%d");
+session_rd_attr(window_closed, "%lu");
+
+struct class_device_attribute *iscsi_host_attrs[] = {
+	&class_device_attr_shutdown,
+	&class_device_attr_drop_session,
+	&class_device_attr_session_established_time,
+	&class_device_attr_session_drop_time,
+	&class_device_attr_ever_established,
+	&class_device_attr_login_timeout,
+	&class_device_attr_active_timeout,
+	&class_device_attr_idle_timeout,
+	&class_device_attr_ping_timeout,
+	&class_device_attr_window_closed,
+	NULL
+};
+
+
+#define iscsi_transport_get_fn(field)					\
+static void								\
+iscsi_get_##field (struct scsi_target *stgt)				\
+{									\
+	struct Scsi_Host *shost = dev_to_shost(stgt->dev.parent);	\
+	struct iscsi_session *session;					\
+	session = (struct iscsi_session *)shost->hostdata;		\
+	iscsi_##field(stgt) = session->field;				\
+}
+
+iscsi_transport_get_fn(tsih);
+iscsi_transport_get_fn(initial_r2t);
+iscsi_transport_get_fn(immediate_data);
+iscsi_transport_get_fn(header_digest);
+iscsi_transport_get_fn(data_digest);
+iscsi_transport_get_fn(max_burst_len);
+iscsi_transport_get_fn(first_burst_len);
+iscsi_transport_get_fn(max_recv_data_segment_len);
+
+#define iscsi_target_transport_cp_fn(field)				\
+static ssize_t								\
+iscsi_get_##field (struct scsi_target *stgt, char *buf, ssize_t count)	\
+{									\
+	struct Scsi_Host *shost = dev_to_shost(stgt->dev.parent);	\
+	struct iscsi_session *session;					\
+	session = (struct iscsi_session *)shost->hostdata;		\
+	return snprintf(buf, count - 1, "%s\n", session->field);	\
+}
+
+iscsi_target_transport_cp_fn(target_name);
+iscsi_target_transport_cp_fn(target_alias);
+
+static void
+iscsi_get_ip_address(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_session *session = (struct iscsi_session *)shost->hostdata;
+	struct sockaddr_in *addr = (struct sockaddr_in *)&session->addr;
+	/*
+	 * I am pretty sure I messed up the socket data structure
+	 * for ipv6 support. For now just do ipv4 until I can test
+	 */
+	iscsi_addr_type(starget) = addr->sin_family;
+	memcpy(&iscsi_sin_addr(starget), &addr->sin_addr,
+	       sizeof(struct in_addr));
+}
+
+static void
+iscsi_get_port(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_session *session = (struct iscsi_session *)shost->hostdata;
+
+	struct sockaddr_in *addr = (struct sockaddr_in *)&session->addr;
+	iscsi_port(starget) = addr->sin_port;
+}
+
+static void
+iscsi_get_tpgt(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_session *session = (struct iscsi_session *)shost->hostdata;
+
+	iscsi_tpgt(starget) = session->portal_group_tag;
+}
+
+static void
+iscsi_get_isid(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_session *session = (struct iscsi_session *)shost->hostdata;
+	memcpy(iscsi_isid(starget), session->isid, sizeof(session->isid));
+}
+
+#define iscsi_host_transport_cp_fn(field)				\
+static ssize_t								\
+iscsi_get_##field (struct Scsi_Host *shost, char *buf, ssize_t count)	\
+{									\
+	struct iscsi_session *s = (struct iscsi_session *)shost->hostdata; \
+	return snprintf(buf, count - 1, "%s\n", s->field);		\
+}
+
+iscsi_host_transport_cp_fn(initiator_name);
+iscsi_host_transport_cp_fn(initiator_alias);
+
+struct iscsi_function_template iscsi_fnt = {
+	.get_isid = iscsi_get_isid,
+	.show_isid = 1,
+	.get_tsih = iscsi_get_tsih,
+	.show_tsih = 1,
+	.get_port = iscsi_get_port,
+	.show_port = 1,
+	.get_tpgt = iscsi_get_tpgt,
+	.show_tpgt = 1,
+	.get_ip_address = iscsi_get_ip_address,
+	.show_ip_address = 1, 
+	.get_initial_r2t = iscsi_get_initial_r2t,
+	.show_initial_r2t = 1,
+	.get_immediate_data = iscsi_get_immediate_data,
+	.show_immediate_data = 1,
+	.get_header_digest = iscsi_get_header_digest,
+	.show_header_digest = 1,
+	.get_data_digest = iscsi_get_data_digest,
+	.show_data_digest = 1,
+	.get_max_burst_len = iscsi_get_max_burst_len,
+	.show_max_burst_len = 1,
+	.get_first_burst_len = iscsi_get_first_burst_len,
+	.show_first_burst_len = 1,
+	.get_max_recv_data_segment_len = iscsi_get_max_recv_data_segment_len,
+	.show_max_recv_data_segment_len = 1,
+	.get_target_name = iscsi_get_target_name,
+	.show_target_name = 1,
+	.get_target_alias = iscsi_get_target_alias,
+	.show_target_alias = 1,
+	.get_initiator_alias = iscsi_get_initiator_alias,
+	.show_initiator_alias = 1,
+	.get_initiator_name = iscsi_get_initiator_name,
+	.show_initiator_name = 1,
+};
drivers/scsi/iscsi-sfnet/iscsi-ioctl.c +140 -0

140 lines not on this page · raw message

drivers/scsi/iscsi-sfnet/iscsi-ioctl.h +67 -0

67 lines not on this page · raw message

drivers/scsi/iscsi-sfnet/iscsi-protocol.h +53 -0

53 lines not on this page · raw message