[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>
This commit is contained in:
parent
ff88443080
commit
ac20c7bf07
3 changed files with 84 additions and 0 deletions
|
@ -1507,6 +1507,35 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iscsi_post_host_event);
|
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
|
static int
|
||||||
iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
|
iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
|
||||||
void *payload, int size)
|
void *payload, int size)
|
||||||
|
@ -1945,6 +1974,33 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
|
||||||
return err;
|
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
|
static int
|
||||||
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
|
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,
|
err = iscsi_set_iface_params(transport, ev,
|
||||||
nlmsg_attrlen(nlh, sizeof(*ev)));
|
nlmsg_attrlen(nlh, sizeof(*ev)));
|
||||||
break;
|
break;
|
||||||
|
case ISCSI_UEVENT_PING:
|
||||||
|
err = iscsi_send_ping(transport, ev);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
err = -ENOSYS;
|
err = -ENOSYS;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum iscsi_uevent_e {
|
||||||
|
|
||||||
ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20,
|
ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20,
|
||||||
ISCSI_UEVENT_SET_IFACE_PARAMS = UEVENT_BASE + 21,
|
ISCSI_UEVENT_SET_IFACE_PARAMS = UEVENT_BASE + 21,
|
||||||
|
ISCSI_UEVENT_PING = UEVENT_BASE + 22,
|
||||||
|
|
||||||
/* up events */
|
/* up events */
|
||||||
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
|
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
|
||||||
|
@ -73,6 +74,7 @@ enum iscsi_uevent_e {
|
||||||
ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8,
|
ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8,
|
||||||
ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9,
|
ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9,
|
||||||
ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10,
|
ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10,
|
||||||
|
ISCSI_KEVENT_PING_COMP = KEVENT_BASE + 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum iscsi_tgt_dscvr {
|
enum iscsi_tgt_dscvr {
|
||||||
|
@ -186,6 +188,14 @@ struct iscsi_uevent {
|
||||||
uint32_t host_no;
|
uint32_t host_no;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
} set_iface_params;
|
} 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;
|
} u;
|
||||||
union {
|
union {
|
||||||
/* messages k -> u */
|
/* messages k -> u */
|
||||||
|
@ -235,6 +245,13 @@ struct iscsi_uevent {
|
||||||
uint32_t data_size;
|
uint32_t data_size;
|
||||||
enum iscsi_host_event_code code;
|
enum iscsi_host_event_code code;
|
||||||
} host_event;
|
} 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;
|
} r;
|
||||||
} __attribute__ ((aligned (sizeof(uint64_t))));
|
} __attribute__ ((aligned (sizeof(uint64_t))));
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,9 @@ struct iscsi_transport {
|
||||||
int param, char *buf);
|
int param, char *buf);
|
||||||
umode_t (*attr_is_visible)(int param_type, int param);
|
umode_t (*attr_is_visible)(int param_type, int param);
|
||||||
int (*bsg_request)(struct bsg_job *job);
|
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,
|
uint32_t data_size,
|
||||||
uint8_t *data);
|
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 iscsi_cls_conn {
|
||||||
struct list_head conn_list; /* item in connlist */
|
struct list_head conn_list; /* item in connlist */
|
||||||
void *dd_data; /* LLD private data */
|
void *dd_data; /* LLD private data */
|
||||||
|
|
Loading…
Reference in a new issue