Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac20c7bf authored by Vikas Chaudhary's avatar Vikas Chaudhary Committed by James Bottomley
Browse files

[SCSI] iscsi_transport: Added Ping support



Added ping support for iscsi adapter, application can use this
interface for diagnostic network connection.

Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ff884430
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -1507,6 +1507,35 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
}
EXPORT_SYMBOL_GPL(iscsi_post_host_event);

void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
			   uint32_t status, uint32_t pid, uint32_t data_size,
			   uint8_t *data)
{
	struct nlmsghdr *nlh;
	struct sk_buff *skb;
	struct iscsi_uevent *ev;
	int len = NLMSG_SPACE(sizeof(*ev) + data_size);

	skb = alloc_skb(len, GFP_KERNEL);
	if (!skb) {
		printk(KERN_ERR "gracefully ignored ping comp: OOM\n");
		return;
	}

	nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
	ev = NLMSG_DATA(nlh);
	ev->transport_handle = iscsi_handle(transport);
	ev->type = ISCSI_KEVENT_PING_COMP;
	ev->r.ping_comp.host_no = host_no;
	ev->r.ping_comp.status = status;
	ev->r.ping_comp.pid = pid;
	ev->r.ping_comp.data_size = data_size;
	memcpy((char *)ev + sizeof(*ev), data, data_size);

	iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);

static int
iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
		    void *payload, int size)
@@ -1945,6 +1974,33 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
	return err;
}

static int
iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
{
	struct Scsi_Host *shost;
	struct sockaddr *dst_addr;
	int err;

	if (!transport->send_ping)
		return -ENOSYS;

	shost = scsi_host_lookup(ev->u.iscsi_ping.host_no);
	if (!shost) {
		printk(KERN_ERR "iscsi_ping could not find host no %u\n",
		       ev->u.iscsi_ping.host_no);
		return -ENODEV;
	}

	dst_addr = (struct sockaddr *)((char *)ev + sizeof(*ev));
	err = transport->send_ping(shost, ev->u.iscsi_ping.iface_num,
				   ev->u.iscsi_ping.iface_type,
				   ev->u.iscsi_ping.payload_size,
				   ev->u.iscsi_ping.pid,
				   dst_addr);
	scsi_host_put(shost);
	return err;
}

static int
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
{
@@ -2090,6 +2146,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
		err = iscsi_set_iface_params(transport, ev,
					     nlmsg_attrlen(nlh, sizeof(*ev)));
		break;
	case ISCSI_UEVENT_PING:
		err = iscsi_send_ping(transport, ev);
		break;
	default:
		err = -ENOSYS;
		break;
+17 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ enum iscsi_uevent_e {

	ISCSI_UEVENT_PATH_UPDATE	= UEVENT_BASE + 20,
	ISCSI_UEVENT_SET_IFACE_PARAMS	= UEVENT_BASE + 21,
	ISCSI_UEVENT_PING		= UEVENT_BASE + 22,

	/* up events */
	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1,
@@ -73,6 +74,7 @@ enum iscsi_uevent_e {
	ISCSI_KEVENT_IF_DOWN		= KEVENT_BASE + 8,
	ISCSI_KEVENT_CONN_LOGIN_STATE   = KEVENT_BASE + 9,
	ISCSI_KEVENT_HOST_EVENT		= KEVENT_BASE + 10,
	ISCSI_KEVENT_PING_COMP		= KEVENT_BASE + 11,
};

enum iscsi_tgt_dscvr {
@@ -186,6 +188,14 @@ struct iscsi_uevent {
			uint32_t	host_no;
			uint32_t	count;
		} set_iface_params;
		struct msg_iscsi_ping {
			uint32_t        host_no;
			uint32_t        iface_num;
			uint32_t        iface_type;
			uint32_t        payload_size;
			uint32_t	pid;	/* unique ping id associated
						   with each ping request */
		} iscsi_ping;
	} u;
	union {
		/* messages k -> u */
@@ -235,6 +245,13 @@ struct iscsi_uevent {
			uint32_t	data_size;
			enum iscsi_host_event_code code;
		} host_event;
		struct msg_ping_comp {
			uint32_t        host_no;
			uint32_t        status;
			uint32_t	pid;	/* unique ping id associated
						   with each ping request */
			uint32_t        data_size;
		} ping_comp;
	} r;
} __attribute__ ((aligned (sizeof(uint64_t))));

+8 −0
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ struct iscsi_transport {
				int param, char *buf);
	umode_t (*attr_is_visible)(int param_type, int param);
	int (*bsg_request)(struct bsg_job *job);
	int (*send_ping) (struct Scsi_Host *shost, uint32_t iface_num,
			  uint32_t iface_type, uint32_t payload_size,
			  uint32_t pid, struct sockaddr *dst_addr);
};

/*
@@ -172,6 +175,11 @@ extern void iscsi_post_host_event(uint32_t host_no,
				  uint32_t data_size,
				  uint8_t *data);

extern void iscsi_ping_comp_event(uint32_t host_no,
				  struct iscsi_transport *transport,
				  uint32_t status, uint32_t pid,
				  uint32_t data_size, uint8_t *data);

struct iscsi_cls_conn {
	struct list_head conn_list;	/* item in connlist */
	void *dd_data;			/* LLD private data */