diff options
author | Vikas Chaudhary <vikas.chaudhary@qlogic.com> | 2012-02-13 08:00:48 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 10:34:50 -0500 |
commit | ac20c7bf070df2b0feb410558ec4d75dbe59b701 (patch) | |
tree | 7af9b3e1ef4b8abbb8232fb264a1db51c57f6679 | |
parent | ff884430801c08bd909fd95f6cb1a0446afd30db (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.c | 59 | ||||
-rw-r--r-- | include/scsi/iscsi_if.h | 17 | ||||
-rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 8 |
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 | } |
1508 | EXPORT_SYMBOL_GPL(iscsi_post_host_event); | 1508 | EXPORT_SYMBOL_GPL(iscsi_post_host_event); |
1509 | 1509 | ||
1510 | void 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 | } | ||
1537 | EXPORT_SYMBOL_GPL(iscsi_ping_comp_event); | ||
1538 | |||
1510 | static int | 1539 | static int |
1511 | iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi, | 1540 | iscsi_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 | ||
1948 | static int | 1977 | static int |
1978 | iscsi_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 | |||
2004 | static int | ||
1949 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) | 2005 | iscsi_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 | ||
78 | enum iscsi_tgt_dscvr { | 80 | enum 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 | ||
178 | extern 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 | |||
175 | struct iscsi_cls_conn { | 183 | struct 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 */ |