linux-iscsi driver
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
@@ -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