diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 13:43:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 13:43:21 -0700 |
commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /drivers/net/cnic.c | |
parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) | |
download | op-kernel-dev-06f4e926d256d902dd9a53dcb400fd74974ce087.zip op-kernel-dev-06f4e926d256d902dd9a53dcb400fd74974ce087.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits)
macvlan: fix panic if lowerdev in a bond
tg3: Add braces around 5906 workaround.
tg3: Fix NETIF_F_LOOPBACK error
macvlan: remove one synchronize_rcu() call
networking: NET_CLS_ROUTE4 depends on INET
irda: Fix error propagation in ircomm_lmp_connect_response()
irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
be2net: Kill set but unused variable 'req' in lancer_fw_download()
irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
isdn: capi: Use pr_debug() instead of ifdefs.
tg3: Update version to 3.119
tg3: Apply rx_discards fix to 5719/5720
...
Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r-- | drivers/net/cnic.c | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 8cca60e..cde59b4 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2966,31 +2966,36 @@ static int cnic_service_bnx2x(void *data, void *status_blk) return 0; } -static void cnic_ulp_stop(struct cnic_dev *dev) +static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type) { - struct cnic_local *cp = dev->cnic_priv; - int if_type; - - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + struct cnic_ulp_ops *ulp_ops; - for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { - struct cnic_ulp_ops *ulp_ops; + if (if_type == CNIC_ULP_ISCSI) + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); - mutex_lock(&cnic_lock); - ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], - lockdep_is_held(&cnic_lock)); - if (!ulp_ops) { - mutex_unlock(&cnic_lock); - continue; - } - set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); + mutex_lock(&cnic_lock); + ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], + lockdep_is_held(&cnic_lock)); + if (!ulp_ops) { mutex_unlock(&cnic_lock); + return; + } + set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); + mutex_unlock(&cnic_lock); - if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) - ulp_ops->cnic_stop(cp->ulp_handle[if_type]); + if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) + ulp_ops->cnic_stop(cp->ulp_handle[if_type]); - clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); - } + clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); +} + +static void cnic_ulp_stop(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + int if_type; + + for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) + cnic_ulp_stop_one(cp, if_type); } static void cnic_ulp_start(struct cnic_dev *dev) @@ -3039,6 +3044,12 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info) cnic_put(dev); break; + case CNIC_CTL_STOP_ISCSI_CMD: { + struct cnic_local *cp = dev->cnic_priv; + set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags); + queue_delayed_work(cnic_wq, &cp->delete_task, 0); + break; + } case CNIC_CTL_COMPLETION_CMD: { u32 cid = BNX2X_SW_CID(info->data.comp.cid); u32 l5_cid; @@ -3562,8 +3573,12 @@ static void cnic_init_csk_state(struct cnic_sock *csk) static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr) { + struct cnic_local *cp = csk->dev->cnic_priv; int err = 0; + if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI) + return -EOPNOTSUPP; + if (!cnic_in_use(csk)) return -EINVAL; @@ -3965,6 +3980,15 @@ static void cnic_delete_task(struct work_struct *work) cp = container_of(work, struct cnic_local, delete_task.work); dev = cp->dev; + if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) { + struct drv_ctl_info info; + + cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI); + + info.cmd = DRV_CTL_ISCSI_STOPPED_CMD; + cp->ethdev->drv_ctl(dev->netdev, &info); + } + for (i = 0; i < cp->max_cid_space; i++) { struct cnic_context *ctx = &cp->ctx_tbl[i]; |