diff options
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r-- | drivers/net/cnic.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 3a7d3ce6db7b..9f80fb40380a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -279,6 +279,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, | |||
279 | u32 msg_type = ISCSI_KEVENT_IF_DOWN; | 279 | u32 msg_type = ISCSI_KEVENT_IF_DOWN; |
280 | struct cnic_ulp_ops *ulp_ops; | 280 | struct cnic_ulp_ops *ulp_ops; |
281 | struct cnic_uio_dev *udev = cp->udev; | 281 | struct cnic_uio_dev *udev = cp->udev; |
282 | int rc = 0, retry = 0; | ||
282 | 283 | ||
283 | if (!udev || udev->uio_dev == -1) | 284 | if (!udev || udev->uio_dev == -1) |
284 | return -ENODEV; | 285 | return -ENODEV; |
@@ -303,11 +304,21 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, | |||
303 | path_req.pmtu = csk->mtu; | 304 | path_req.pmtu = csk->mtu; |
304 | } | 305 | } |
305 | 306 | ||
306 | rcu_read_lock(); | 307 | while (retry < 3) { |
307 | ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); | 308 | rc = 0; |
308 | if (ulp_ops) | 309 | rcu_read_lock(); |
309 | ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len); | 310 | ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); |
310 | rcu_read_unlock(); | 311 | if (ulp_ops) |
312 | rc = ulp_ops->iscsi_nl_send_msg( | ||
313 | cp->ulp_handle[CNIC_ULP_ISCSI], | ||
314 | msg_type, buf, len); | ||
315 | rcu_read_unlock(); | ||
316 | if (rc == 0 || msg_type != ISCSI_KEVENT_PATH_REQ) | ||
317 | break; | ||
318 | |||
319 | msleep(100); | ||
320 | retry++; | ||
321 | } | ||
311 | return 0; | 322 | return 0; |
312 | } | 323 | } |
313 | 324 | ||