diff options
author | Michael Chan <mchan@broadcom.com> | 2010-06-15 04:57:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-15 17:23:37 -0400 |
commit | 7b34a4644b4342896e0c1967b8f953213ea4a990 (patch) | |
tree | e25d3d267b4ab1d82ace8256b47f6d42dc9d6559 /drivers/net/cnic.c | |
parent | 943189f1d564e69201f7d71e77f5608a701e3e55 (diff) |
cnic: Fix cnic_cm_abort() error handling.
Fix the code that handles the error case when cnic_cm_abort() cannot
proceed normally. We cannot just set the csk->state and we must
go through cnic_ready_to_close() to handle all the conditions. We
also add error return code in cnic_cm_abort().
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Eddie Wai <waie@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r-- | drivers/net/cnic.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 11eeded146d9..e5539f05cbfa 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -2996,7 +2996,7 @@ err_out: | |||
2996 | static int cnic_cm_abort(struct cnic_sock *csk) | 2996 | static int cnic_cm_abort(struct cnic_sock *csk) |
2997 | { | 2997 | { |
2998 | struct cnic_local *cp = csk->dev->cnic_priv; | 2998 | struct cnic_local *cp = csk->dev->cnic_priv; |
2999 | u32 opcode; | 2999 | u32 opcode = L4_KCQE_OPCODE_VALUE_RESET_COMP; |
3000 | 3000 | ||
3001 | if (!cnic_in_use(csk)) | 3001 | if (!cnic_in_use(csk)) |
3002 | return -EINVAL; | 3002 | return -EINVAL; |
@@ -3008,12 +3008,9 @@ static int cnic_cm_abort(struct cnic_sock *csk) | |||
3008 | * connect was not successful. | 3008 | * connect was not successful. |
3009 | */ | 3009 | */ |
3010 | 3010 | ||
3011 | csk->state = L4_KCQE_OPCODE_VALUE_RESET_COMP; | ||
3012 | if (test_bit(SK_F_PG_OFFLD_COMPLETE, &csk->flags)) | ||
3013 | opcode = csk->state; | ||
3014 | else | ||
3015 | opcode = L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD; | ||
3016 | cp->close_conn(csk, opcode); | 3011 | cp->close_conn(csk, opcode); |
3012 | if (csk->state != opcode) | ||
3013 | return -EALREADY; | ||
3017 | 3014 | ||
3018 | return 0; | 3015 | return 0; |
3019 | } | 3016 | } |
@@ -3206,11 +3203,16 @@ static int cnic_ready_to_close(struct cnic_sock *csk, u32 opcode) | |||
3206 | 3203 | ||
3207 | /* 1. If event opcode matches the expected event in csk->state | 3204 | /* 1. If event opcode matches the expected event in csk->state |
3208 | * 2. If the expected event is CLOSE_COMP, we accept any event | 3205 | * 2. If the expected event is CLOSE_COMP, we accept any event |
3206 | * 3. If the expected event is 0, meaning the connection was never | ||
3207 | * never established, we accept the opcode from cm_abort. | ||
3209 | */ | 3208 | */ |
3210 | if (opcode == csk->state || | 3209 | if (opcode == csk->state || csk->state == 0 || |
3211 | csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP) { | 3210 | csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP) { |
3212 | if (!test_and_set_bit(SK_F_CLOSING, &csk->flags)) | 3211 | if (!test_and_set_bit(SK_F_CLOSING, &csk->flags)) { |
3212 | if (csk->state == 0) | ||
3213 | csk->state = opcode; | ||
3213 | return 1; | 3214 | return 1; |
3215 | } | ||
3214 | } | 3216 | } |
3215 | return 0; | 3217 | return 0; |
3216 | } | 3218 | } |
@@ -3227,6 +3229,7 @@ static void cnic_close_bnx2_conn(struct cnic_sock *csk, u32 opcode) | |||
3227 | 3229 | ||
3228 | clear_bit(SK_F_CONNECT_START, &csk->flags); | 3230 | clear_bit(SK_F_CONNECT_START, &csk->flags); |
3229 | cnic_close_conn(csk); | 3231 | cnic_close_conn(csk); |
3232 | csk->state = opcode; | ||
3230 | cnic_cm_upcall(cp, csk, opcode); | 3233 | cnic_cm_upcall(cp, csk, opcode); |
3231 | } | 3234 | } |
3232 | 3235 | ||
@@ -3256,8 +3259,12 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode) | |||
3256 | case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED: | 3259 | case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED: |
3257 | case L4_KCQE_OPCODE_VALUE_CLOSE_COMP: | 3260 | case L4_KCQE_OPCODE_VALUE_CLOSE_COMP: |
3258 | case L4_KCQE_OPCODE_VALUE_RESET_COMP: | 3261 | case L4_KCQE_OPCODE_VALUE_RESET_COMP: |
3259 | if (cnic_ready_to_close(csk, opcode)) | 3262 | if (cnic_ready_to_close(csk, opcode)) { |
3260 | cmd = L5CM_RAMROD_CMD_ID_SEARCHER_DELETE; | 3263 | if (test_bit(SK_F_PG_OFFLD_COMPLETE, &csk->flags)) |
3264 | cmd = L5CM_RAMROD_CMD_ID_SEARCHER_DELETE; | ||
3265 | else | ||
3266 | close_complete = 1; | ||
3267 | } | ||
3261 | break; | 3268 | break; |
3262 | case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE: | 3269 | case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE: |
3263 | cmd = L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD; | 3270 | cmd = L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD; |