aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c63
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c62
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c15
4 files changed, 81 insertions, 61 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index 99568cb9ad1c..a44b1b33fa18 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -755,7 +755,7 @@ extern int bnx2i_send_iscsi_tmf(struct bnx2i_conn *conn,
755extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn, 755extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn,
756 struct bnx2i_cmd *cmnd); 756 struct bnx2i_cmd *cmnd);
757extern int bnx2i_send_iscsi_nopout(struct bnx2i_conn *conn, 757extern int bnx2i_send_iscsi_nopout(struct bnx2i_conn *conn,
758 struct iscsi_task *mtask, u32 ttt, 758 struct iscsi_task *mtask,
759 char *datap, int data_len, int unsol); 759 char *datap, int data_len, int unsol);
760extern int bnx2i_send_iscsi_logout(struct bnx2i_conn *conn, 760extern int bnx2i_send_iscsi_logout(struct bnx2i_conn *conn,
761 struct iscsi_task *mtask); 761 struct iscsi_task *mtask);
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 99c71e6d4c14..8d9dbb33972f 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -385,7 +385,6 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
385 struct bnx2i_cmd *bnx2i_cmd; 385 struct bnx2i_cmd *bnx2i_cmd;
386 struct bnx2i_tmf_request *tmfabort_wqe; 386 struct bnx2i_tmf_request *tmfabort_wqe;
387 u32 dword; 387 u32 dword;
388 u32 scsi_lun[2];
389 388
390 bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data; 389 bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
391 tmfabort_hdr = (struct iscsi_tm *)mtask->hdr; 390 tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -393,38 +392,41 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
393 bnx2i_conn->ep->qp.sq_prod_qe; 392 bnx2i_conn->ep->qp.sq_prod_qe;
394 393
395 tmfabort_wqe->op_code = tmfabort_hdr->opcode; 394 tmfabort_wqe->op_code = tmfabort_hdr->opcode;
396 tmfabort_wqe->op_attr = 0; 395 tmfabort_wqe->op_attr = tmfabort_hdr->flags;
397 tmfabort_wqe->op_attr =
398 ISCSI_TMF_REQUEST_ALWAYS_ONE | ISCSI_TM_FUNC_ABORT_TASK;
399 396
400 tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14)); 397 tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14));
401 tmfabort_wqe->reserved2 = 0; 398 tmfabort_wqe->reserved2 = 0;
402 tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn); 399 tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn);
403 400
404 ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt); 401 switch (tmfabort_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) {
405 if (!ctask || !ctask->sc) 402 case ISCSI_TM_FUNC_ABORT_TASK:
406 /* 403 case ISCSI_TM_FUNC_TASK_REASSIGN:
407 * the iscsi layer must have completed the cmd while this 404 ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
408 * was starting up. 405 if (!ctask || !ctask->sc)
409 * 406 /*
410 * Note: In the case of a SCSI cmd timeout, the task's sc 407 * the iscsi layer must have completed the cmd while
411 * is still active; hence ctask->sc != 0 408 * was starting up.
412 * In this case, the task must be aborted 409 *
413 */ 410 * Note: In the case of a SCSI cmd timeout, the task's
414 return 0; 411 * sc is still active; hence ctask->sc != 0
415 412 * In this case, the task must be aborted
416 ref_sc = ctask->sc; 413 */
417 414 return 0;
418 /* Retrieve LUN directly from the ref_sc */ 415
419 int_to_scsilun(ref_sc->device->lun, (struct scsi_lun *) scsi_lun); 416 ref_sc = ctask->sc;
420 tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]); 417 if (ref_sc->sc_data_direction == DMA_TO_DEVICE)
421 tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]); 418 dword = (ISCSI_TASK_TYPE_WRITE <<
422 419 ISCSI_CMD_REQUEST_TYPE_SHIFT);
423 if (ref_sc->sc_data_direction == DMA_TO_DEVICE) 420 else
424 dword = (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT); 421 dword = (ISCSI_TASK_TYPE_READ <<
425 else 422 ISCSI_CMD_REQUEST_TYPE_SHIFT);
426 dword = (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT); 423 tmfabort_wqe->ref_itt = (dword |
427 tmfabort_wqe->ref_itt = (dword | (tmfabort_hdr->rtt & ISCSI_ITT_MASK)); 424 (tmfabort_hdr->rtt & ISCSI_ITT_MASK));
425 break;
426 default:
427 tmfabort_wqe->ref_itt = RESERVED_ITT;
428 }
429 memcpy(tmfabort_wqe->lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
428 tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn); 430 tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
429 431
430 tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma; 432 tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
@@ -464,7 +466,6 @@ int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *bnx2i_conn,
464 * @conn: iscsi connection 466 * @conn: iscsi connection
465 * @cmd: driver command structure which is requesting 467 * @cmd: driver command structure which is requesting
466 * a WQE to sent to chip for further processing 468 * a WQE to sent to chip for further processing
467 * @ttt: TTT to be used when building pdu header
468 * @datap: payload buffer pointer 469 * @datap: payload buffer pointer
469 * @data_len: payload data length 470 * @data_len: payload data length
470 * @unsol: indicated whether nopout pdu is unsolicited pdu or 471 * @unsol: indicated whether nopout pdu is unsolicited pdu or
@@ -473,7 +474,7 @@ int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *bnx2i_conn,
473 * prepare and post a nopout request WQE to CNIC firmware 474 * prepare and post a nopout request WQE to CNIC firmware
474 */ 475 */
475int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn, 476int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
476 struct iscsi_task *task, u32 ttt, 477 struct iscsi_task *task,
477 char *datap, int data_len, int unsol) 478 char *datap, int data_len, int unsol)
478{ 479{
479 struct bnx2i_endpoint *ep = bnx2i_conn->ep; 480 struct bnx2i_endpoint *ep = bnx2i_conn->ep;
@@ -498,7 +499,7 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
498 nopout_wqe->itt = ((u16)task->itt | 499 nopout_wqe->itt = ((u16)task->itt |
499 (ISCSI_TASK_TYPE_MPATH << 500 (ISCSI_TASK_TYPE_MPATH <<
500 ISCSI_TMF_REQUEST_TYPE_SHIFT)); 501 ISCSI_TMF_REQUEST_TYPE_SHIFT));
501 nopout_wqe->ttt = ttt; 502 nopout_wqe->ttt = nopout_hdr->ttt;
502 nopout_wqe->flags = 0; 503 nopout_wqe->flags = 0;
503 if (!unsol) 504 if (!unsol)
504 nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION; 505 nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index a796f565f383..50c2aa3b8eb1 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -17,15 +17,17 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
17static u32 adapter_count; 17static u32 adapter_count;
18 18
19#define DRV_MODULE_NAME "bnx2i" 19#define DRV_MODULE_NAME "bnx2i"
20#define DRV_MODULE_VERSION "2.1.2" 20#define DRV_MODULE_VERSION "2.1.3"
21#define DRV_MODULE_RELDATE "Jun 28, 2010" 21#define DRV_MODULE_RELDATE "Aug 10, 2010"
22 22
23static char version[] __devinitdata = 23static char version[] __devinitdata =
24 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ 24 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
25 " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 25 " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
26 26
27 27
28MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com>"); 28MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com> and "
29 "Eddie Wai <eddie.wai@broadcom.com>");
30
29MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711" 31MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711"
30 " iSCSI Driver"); 32 " iSCSI Driver");
31MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
@@ -167,6 +169,38 @@ void bnx2i_start(void *handle)
167 169
168 170
169/** 171/**
172 * bnx2i_chip_cleanup - local routine to handle chip cleanup
173 * @hba: Adapter instance to register
174 *
175 * Driver checks if adapter still has any active connections before
176 * executing the cleanup process
177 */
178static void bnx2i_chip_cleanup(struct bnx2i_hba *hba)
179{
180 struct bnx2i_endpoint *bnx2i_ep;
181 struct list_head *pos, *tmp;
182
183 if (hba->ofld_conns_active) {
184 /* Stage to force the disconnection
185 * This is the case where the daemon is either slow or
186 * not present
187 */
188 printk(KERN_ALERT "bnx2i: (%s) chip cleanup for %d active "
189 "connections\n", hba->netdev->name,
190 hba->ofld_conns_active);
191 mutex_lock(&hba->net_dev_lock);
192 list_for_each_safe(pos, tmp, &hba->ep_active_list) {
193 bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
194 /* Clean up the chip only */
195 bnx2i_hw_ep_disconnect(bnx2i_ep);
196 bnx2i_ep->cm_sk = NULL;
197 }
198 mutex_unlock(&hba->net_dev_lock);
199 }
200}
201
202
203/**
170 * bnx2i_stop - cnic callback to shutdown adapter instance 204 * bnx2i_stop - cnic callback to shutdown adapter instance
171 * @handle: transparent handle pointing to adapter structure 205 * @handle: transparent handle pointing to adapter structure
172 * 206 *
@@ -176,8 +210,6 @@ void bnx2i_start(void *handle)
176void bnx2i_stop(void *handle) 210void bnx2i_stop(void *handle)
177{ 211{
178 struct bnx2i_hba *hba = handle; 212 struct bnx2i_hba *hba = handle;
179 struct list_head *pos, *tmp;
180 struct bnx2i_endpoint *bnx2i_ep;
181 int conns_active; 213 int conns_active;
182 214
183 /* check if cleanup happened in GOING_DOWN context */ 215 /* check if cleanup happened in GOING_DOWN context */
@@ -198,24 +230,7 @@ void bnx2i_stop(void *handle)
198 if (hba->ofld_conns_active == conns_active) 230 if (hba->ofld_conns_active == conns_active)
199 break; 231 break;
200 } 232 }
201 if (hba->ofld_conns_active) { 233 bnx2i_chip_cleanup(hba);
202 /* Stage to force the disconnection
203 * This is the case where the daemon is either slow or
204 * not present
205 */
206 printk(KERN_ALERT "bnx2i: Wait timeout, force all eps "
207 "to disconnect (%d)\n", hba->ofld_conns_active);
208 mutex_lock(&hba->net_dev_lock);
209 list_for_each_safe(pos, tmp, &hba->ep_active_list) {
210 bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
211 /* Clean up the chip only */
212 bnx2i_hw_ep_disconnect(bnx2i_ep);
213 }
214 mutex_unlock(&hba->net_dev_lock);
215 if (hba->ofld_conns_active)
216 printk(KERN_ERR "bnx2i: EP disconnect timeout (%d)!\n",
217 hba->ofld_conns_active);
218 }
219 234
220 /* This flag should be cleared last so that ep_disconnect() gracefully 235 /* This flag should be cleared last so that ep_disconnect() gracefully
221 * cleans up connection context 236 * cleans up connection context
@@ -457,6 +472,7 @@ static void __exit bnx2i_mod_exit(void)
457 adapter_count--; 472 adapter_count--;
458 473
459 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 474 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
475 bnx2i_chip_cleanup(hba);
460 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); 476 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
461 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); 477 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
462 } 478 }
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index a46ccc380ab1..fb50efbce087 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1078,11 +1078,9 @@ static int bnx2i_iscsi_send_generic_request(struct iscsi_task *task)
1078 buf = bnx2i_conn->gen_pdu.req_buf; 1078 buf = bnx2i_conn->gen_pdu.req_buf;
1079 if (data_len) 1079 if (data_len)
1080 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task, 1080 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task,
1081 RESERVED_ITT,
1082 buf, data_len, 1); 1081 buf, data_len, 1);
1083 else 1082 else
1084 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task, 1083 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task,
1085 RESERVED_ITT,
1086 NULL, 0, 1); 1084 NULL, 0, 1);
1087 break; 1085 break;
1088 case ISCSI_OP_LOGOUT: 1086 case ISCSI_OP_LOGOUT:
@@ -1955,6 +1953,9 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1955 if (!cnic) 1953 if (!cnic)
1956 return 0; 1954 return 0;
1957 1955
1956 if (bnx2i_ep->state == EP_STATE_IDLE)
1957 return 0;
1958
1958 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep)) 1959 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
1959 goto destroy_conn; 1960 goto destroy_conn;
1960 1961
@@ -1998,11 +1999,13 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1998 else 1999 else
1999 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk); 2000 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
2000 2001
2002 /* No longer allow CFC delete if cm_close/abort fails the request */
2001 if (close_ret) 2003 if (close_ret)
2002 bnx2i_ep->state = EP_STATE_DISCONN_COMPL; 2004 printk(KERN_ALERT "bnx2i: %s close/abort(%d) returned %d\n",
2003 2005 bnx2i_ep->hba->netdev->name, close, close_ret);
2004 /* wait for option-2 conn teardown */ 2006 else
2005 wait_event_interruptible(bnx2i_ep->ofld_wait, 2007 /* wait for option-2 conn teardown */
2008 wait_event_interruptible(bnx2i_ep->ofld_wait,
2006 bnx2i_ep->state != EP_STATE_DISCONN_START); 2009 bnx2i_ep->state != EP_STATE_DISCONN_START);
2007 2010
2008 if (signal_pending(current)) 2011 if (signal_pending(current))