diff options
author | Vikas Chaudhary <vikas.chaudhary@qlogic.com> | 2012-02-13 18:30:48 +0530 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:34:50 -0600 |
commit | ac20c7bf070df2b0feb410558ec4d75dbe59b701 (patch) | |
tree | 7af9b3e1ef4b8abbb8232fb264a1db51c57f6679 /drivers/scsi | |
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 59 |
1 files changed, 59 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, } 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) @@ -1946,6 +1975,33 @@ iscsi_set_iface_params(struct iscsi_transport *transport, } 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) { int err = 0; @@ -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; |