diff options
author | Vikas Chaudhary <vikas.chaudhary@qlogic.com> | 2012-02-13 08:00:46 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 10:33:32 -0500 |
commit | a11e25459558421ec5c4adc3fc46fe320ab74bd3 (patch) | |
tree | f1112f31c65b28337b9b25082a1c5a8246ceb1ad | |
parent | 46801ba698b3366cf8d293d9f3d4253b6fd5210b (diff) |
[SCSI] scsi_transport_iscsi: added support for host event
Added support to post kernel host event to application using
netlink interface.
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 | 31 | ||||
-rw-r--r-- | include/scsi/iscsi_if.h | 13 | ||||
-rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 6 |
3 files changed, 50 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 787044828a70..38f0bf8ea91a 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -1476,6 +1476,37 @@ void iscsi_conn_login_event(struct iscsi_cls_conn *conn, | |||
1476 | } | 1476 | } |
1477 | EXPORT_SYMBOL_GPL(iscsi_conn_login_event); | 1477 | EXPORT_SYMBOL_GPL(iscsi_conn_login_event); |
1478 | 1478 | ||
1479 | void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport, | ||
1480 | enum iscsi_host_event_code code, uint32_t data_size, | ||
1481 | uint8_t *data) | ||
1482 | { | ||
1483 | struct nlmsghdr *nlh; | ||
1484 | struct sk_buff *skb; | ||
1485 | struct iscsi_uevent *ev; | ||
1486 | int len = NLMSG_SPACE(sizeof(*ev) + data_size); | ||
1487 | |||
1488 | skb = alloc_skb(len, GFP_KERNEL); | ||
1489 | if (!skb) { | ||
1490 | printk(KERN_ERR "gracefully ignored host event (%d):%d OOM\n", | ||
1491 | host_no, code); | ||
1492 | return; | ||
1493 | } | ||
1494 | |||
1495 | nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); | ||
1496 | ev = NLMSG_DATA(nlh); | ||
1497 | ev->transport_handle = iscsi_handle(transport); | ||
1498 | ev->type = ISCSI_KEVENT_HOST_EVENT; | ||
1499 | ev->r.host_event.host_no = host_no; | ||
1500 | ev->r.host_event.code = code; | ||
1501 | ev->r.host_event.data_size = data_size; | ||
1502 | |||
1503 | if (data_size) | ||
1504 | memcpy((char *)ev + sizeof(*ev), data, data_size); | ||
1505 | |||
1506 | iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL); | ||
1507 | } | ||
1508 | EXPORT_SYMBOL_GPL(iscsi_post_host_event); | ||
1509 | |||
1479 | static int | 1510 | static int |
1480 | iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi, | 1511 | iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi, |
1481 | void *payload, int size) | 1512 | void *payload, int size) |
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index e49b7c8dd217..3aac99155e80 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h | |||
@@ -72,6 +72,7 @@ enum iscsi_uevent_e { | |||
72 | ISCSI_KEVENT_PATH_REQ = KEVENT_BASE + 7, | 72 | ISCSI_KEVENT_PATH_REQ = KEVENT_BASE + 7, |
73 | ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, | 73 | ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, |
74 | ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9, | 74 | ISCSI_KEVENT_CONN_LOGIN_STATE = KEVENT_BASE + 9, |
75 | ISCSI_KEVENT_HOST_EVENT = KEVENT_BASE + 10, | ||
75 | }; | 76 | }; |
76 | 77 | ||
77 | enum iscsi_tgt_dscvr { | 78 | enum iscsi_tgt_dscvr { |
@@ -80,6 +81,13 @@ enum iscsi_tgt_dscvr { | |||
80 | ISCSI_TGT_DSCVR_SLP = 3, | 81 | ISCSI_TGT_DSCVR_SLP = 3, |
81 | }; | 82 | }; |
82 | 83 | ||
84 | enum iscsi_host_event_code { | ||
85 | ISCSI_EVENT_LINKUP = 1, | ||
86 | ISCSI_EVENT_LINKDOWN, | ||
87 | /* must always be last */ | ||
88 | ISCSI_EVENT_MAX, | ||
89 | }; | ||
90 | |||
83 | struct iscsi_uevent { | 91 | struct iscsi_uevent { |
84 | uint32_t type; /* k/u events type */ | 92 | uint32_t type; /* k/u events type */ |
85 | uint32_t iferror; /* carries interface or resource errors */ | 93 | uint32_t iferror; /* carries interface or resource errors */ |
@@ -222,6 +230,11 @@ struct iscsi_uevent { | |||
222 | struct msg_notify_if_down { | 230 | struct msg_notify_if_down { |
223 | uint32_t host_no; | 231 | uint32_t host_no; |
224 | } notify_if_down; | 232 | } notify_if_down; |
233 | struct msg_host_event { | ||
234 | uint32_t host_no; | ||
235 | uint32_t data_size; | ||
236 | enum iscsi_host_event_code code; | ||
237 | } host_event; | ||
225 | } r; | 238 | } r; |
226 | } __attribute__ ((aligned (sizeof(uint64_t)))); | 239 | } __attribute__ ((aligned (sizeof(uint64_t)))); |
227 | 240 | ||
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index fa7ca4e16020..7f047314281b 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
@@ -166,6 +166,12 @@ extern int iscsi_offload_mesg(struct Scsi_Host *shost, | |||
166 | struct iscsi_transport *transport, uint32_t type, | 166 | struct iscsi_transport *transport, uint32_t type, |
167 | char *data, uint16_t data_size); | 167 | char *data, uint16_t data_size); |
168 | 168 | ||
169 | extern void iscsi_post_host_event(uint32_t host_no, | ||
170 | struct iscsi_transport *transport, | ||
171 | enum iscsi_host_event_code code, | ||
172 | uint32_t data_size, | ||
173 | uint8_t *data); | ||
174 | |||
169 | struct iscsi_cls_conn { | 175 | struct iscsi_cls_conn { |
170 | struct list_head conn_list; /* item in connlist */ | 176 | struct list_head conn_list; /* item in connlist */ |
171 | void *dd_data; /* LLD private data */ | 177 | void *dd_data; /* LLD private data */ |