aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVikas Chaudhary <vikas.chaudhary@qlogic.com>2012-02-13 08:00:48 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 10:34:50 -0500
commitac20c7bf070df2b0feb410558ec4d75dbe59b701 (patch)
tree7af9b3e1ef4b8abbb8232fb264a1db51c57f6679
parentff884430801c08bd909fd95f6cb1a0446afd30db (diff)
[SCSI] iscsi_transport: Added Ping support
Added ping support for iscsi adapter, application can use this interface for diagnostic network connection. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c59
-rw-r--r--include/scsi/iscsi_if.h17
-rw-r--r--include/scsi/scsi_transport_iscsi.h8
3 files changed, 84 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 38f0bf8ea91a..a20f1813cb51 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1507,6 +1507,35 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
1507} 1507}
1508EXPORT_SYMBOL_GPL(iscsi_post_host_event); 1508EXPORT_SYMBOL_GPL(iscsi_post_host_event);
1509 1509
1510void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
1511 uint32_t status, uint32_t pid, uint32_t data_size,
1512 uint8_t *data)
1513{
1514 struct nlmsghdr *nlh;
1515 struct sk_buff *skb;
1516 struct iscsi_uevent *ev;
1517 int len = NLMSG_SPACE(sizeof(*ev) + data_size);
1518
1519 skb = alloc_skb(len, GFP_KERNEL);
1520 if (!skb) {
1521 printk(KERN_ERR "gracefully ignored ping comp: OOM\n");
1522 return;
1523 }
1524
1525 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
1526 ev = NLMSG_DATA(nlh);
1527 ev->transport_handle = iscsi_handle(transport);
1528 ev->type = ISCSI_KEVENT_PING_COMP;
1529 ev->r.ping_comp.host_no = host_no;
1530 ev->r.ping_comp.status = status;
1531 ev->r.ping_comp.pid = pid;
1532 ev->r.ping_comp.data_size = data_size;
1533 memcpy((char *)ev + sizeof(*ev), data, data_size);
1534
1535 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
1536}
1537EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
1538
1510static int 1539static int
1511iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi, 1540iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
1512 void *payload, int size) 1541 void *payload, int size)
@@ -1946,6 +1975,33 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
1946} 1975}
1947 1976
1948static int 1977static int
1978iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
1979{
1980 struct Scsi_Host *shost;
1981 struct sockaddr *dst_addr;
1982 int err;
1983
1984 if (!transport->send_ping)
1985 return -ENOSYS;
1986
1987 shost = scsi_host_lookup(ev->u.iscsi_ping.host_no);
1988 if (!shost) {
1989 printk(KERN_ERR "iscsi_ping could not find host no %u\n",
1990 ev->u.iscsi_ping.host_no);
1991 return -ENODEV;
1992 }
1993
1994 dst_addr = (struct sockaddr *)((char *)ev + sizeof(*ev));
1995 err = transport->send_ping(shost, ev->u.iscsi_ping.iface_num,
1996 ev->u.iscsi_ping.iface_type,
1997 ev->u.iscsi_ping.payload_size,
1998 ev->u.iscsi_ping.pid,
1999 dst_addr);
2000 scsi_host_put(shost);
2001 return err;
2002}
2003
2004static int
1949iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) 2005iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
1950{ 2006{
1951 int err = 0; 2007 int err = 0;
@@ -2090,6 +2146,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
2090 err = iscsi_set_iface_params(transport, ev, 2146 err = iscsi_set_iface_params(transport, ev,
2091 nlmsg_attrlen(nlh, sizeof(*ev))); 2147 nlmsg_attrlen(nlh, sizeof(*ev)));
2092 break; 2148 break;
2149 case ISCSI_UEVENT_PING:
2150 err = iscsi_send_ping(transport, ev);
2151 break;
2093 default: 2152 default:
2094 err = -ENOSYS; 2153 err = -ENOSYS;
2095 break; 2154 break;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 3aac99155e80..7ff9678b7e79 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -60,6 +60,7 @@ enum iscsi_uevent_e {
60 60
61 ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20, 61 ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20,
62 ISCSI_UEVENT_SET_IFACE_PARAMS = UEVENT_BASE + 21, 62 ISCSI_UEVENT_SET_IFACE_PARAMS = UEVENT_BASE + 21,
63 ISCSI_UEVENT_PING = UEVENT_BASE + 22,
63 64
64 /* up events */ 65 /* up events */
65 ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, 66 ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
@@ -73,6 +74,7 @@ enum iscsi_uevent_e {
73 ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, 74 ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8,
74 ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9, 75 ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9,
75 ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10, 76 ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10,
77 ISCSI_KEVENT_PING_COMP = KEVENT_BASE + 11,
76}; 78};
77 79
78enum iscsi_tgt_dscvr { 80enum iscsi_tgt_dscvr {
@@ -186,6 +188,14 @@ struct iscsi_uevent {
186 uint32_t host_no; 188 uint32_t host_no;
187 uint32_t count; 189 uint32_t count;
188 } set_iface_params; 190 } set_iface_params;
191 struct msg_iscsi_ping {
192 uint32_t host_no;
193 uint32_t iface_num;
194 uint32_t iface_type;
195 uint32_t payload_size;
196 uint32_t pid; /* unique ping id associated
197 with each ping request */
198 } iscsi_ping;
189 } u; 199 } u;
190 union { 200 union {
191 /* messages k -> u */ 201 /* messages k -> u */
@@ -235,6 +245,13 @@ struct iscsi_uevent {
235 uint32_t data_size; 245 uint32_t data_size;
236 enum iscsi_host_event_code code; 246 enum iscsi_host_event_code code;
237 } host_event; 247 } host_event;
248 struct msg_ping_comp {
249 uint32_t host_no;
250 uint32_t status;
251 uint32_t pid; /* unique ping id associated
252 with each ping request */
253 uint32_t data_size;
254 } ping_comp;
238 } r; 255 } r;
239} __attribute__ ((aligned (sizeof(uint64_t)))); 256} __attribute__ ((aligned (sizeof(uint64_t))));
240 257
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 7f047314281b..aede513f99bd 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -144,6 +144,9 @@ struct iscsi_transport {
144 int param, char *buf); 144 int param, char *buf);
145 umode_t (*attr_is_visible)(int param_type, int param); 145 umode_t (*attr_is_visible)(int param_type, int param);
146 int (*bsg_request)(struct bsg_job *job); 146 int (*bsg_request)(struct bsg_job *job);
147 int (*send_ping) (struct Scsi_Host *shost, uint32_t iface_num,
148 uint32_t iface_type, uint32_t payload_size,
149 uint32_t pid, struct sockaddr *dst_addr);
147}; 150};
148 151
149/* 152/*
@@ -172,6 +175,11 @@ extern void iscsi_post_host_event(uint32_t host_no,
172 uint32_t data_size, 175 uint32_t data_size,
173 uint8_t *data); 176 uint8_t *data);
174 177
178extern void iscsi_ping_comp_event(uint32_t host_no,
179 struct iscsi_transport *transport,
180 uint32_t status, uint32_t pid,
181 uint32_t data_size, uint8_t *data);
182
175struct iscsi_cls_conn { 183struct iscsi_cls_conn {
176 struct list_head conn_list; /* item in connlist */ 184 struct list_head conn_list; /* item in connlist */
177 void *dd_data; /* LLD private data */ 185 void *dd_data; /* LLD private data */