Skip to content

Commit ac20c7b

Browse files
Vikas ChaudharyJames Bottomley
authored andcommitted
[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>
1 parent ff88443 commit ac20c7b

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,35 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
15071507
}
15081508
EXPORT_SYMBOL_GPL(iscsi_post_host_event);
15091509

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+
15101539
static int
15111540
iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
15121541
void *payload, int size)
@@ -1945,6 +1974,33 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
19451974
return err;
19461975
}
19471976

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+
19482004
static int
19492005
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
19502006
{
@@ -2090,6 +2146,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
20902146
err = iscsi_set_iface_params(transport, ev,
20912147
nlmsg_attrlen(nlh, sizeof(*ev)));
20922148
break;
2149+
case ISCSI_UEVENT_PING:
2150+
err = iscsi_send_ping(transport, ev);
2151+
break;
20932152
default:
20942153
err = -ENOSYS;
20952154
break;

include/scsi/iscsi_if.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum iscsi_uevent_e {
6060

6161
ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20,
6262
ISCSI_UEVENT_SET_IFACE_PARAMS = UEVENT_BASE + 21,
63+
ISCSI_UEVENT_PING = UEVENT_BASE + 22,
6364

6465
/* up events */
6566
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
@@ -73,6 +74,7 @@ enum iscsi_uevent_e {
7374
ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8,
7475
ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9,
7576
ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10,
77+
ISCSI_KEVENT_PING_COMP = KEVENT_BASE + 11,
7678
};
7779

7880
enum iscsi_tgt_dscvr {
@@ -186,6 +188,14 @@ struct iscsi_uevent {
186188
uint32_t host_no;
187189
uint32_t count;
188190
} 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;
189199
} u;
190200
union {
191201
/* messages k -> u */
@@ -235,6 +245,13 @@ struct iscsi_uevent {
235245
uint32_t data_size;
236246
enum iscsi_host_event_code code;
237247
} 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;
238255
} r;
239256
} __attribute__ ((aligned (sizeof(uint64_t))));
240257

include/scsi/scsi_transport_iscsi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ struct iscsi_transport {
144144
int param, char *buf);
145145
umode_t (*attr_is_visible)(int param_type, int param);
146146
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);
147150
};
148151

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

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+
175183
struct iscsi_cls_conn {
176184
struct list_head conn_list; /* item in connlist */
177185
void *dd_data; /* LLD private data */

0 commit comments

Comments
 (0)