aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_iscsi.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 041928b23cb0..5c55a75ae597 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver. 2 * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver.
3 * 3 *
4 * Copyright (c) 2006 - 2010 Broadcom Corporation 4 * Copyright (c) 2006 - 2011 Broadcom Corporation
5 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. 5 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
6 * Copyright (c) 2007, 2008 Mike Christie 6 * Copyright (c) 2007, 2008 Mike Christie
7 * 7 *
@@ -27,6 +27,7 @@ static struct scsi_host_template bnx2i_host_template;
27 */ 27 */
28static DEFINE_SPINLOCK(bnx2i_resc_lock); /* protects global resources */ 28static DEFINE_SPINLOCK(bnx2i_resc_lock); /* protects global resources */
29 29
30DECLARE_PER_CPU(struct bnx2i_percpu_s, bnx2i_percpu);
30 31
31static int bnx2i_adapter_ready(struct bnx2i_hba *hba) 32static int bnx2i_adapter_ready(struct bnx2i_hba *hba)
32{ 33{
@@ -1214,7 +1215,8 @@ static int bnx2i_task_xmit(struct iscsi_task *task)
1214 struct bnx2i_cmd *cmd = task->dd_data; 1215 struct bnx2i_cmd *cmd = task->dd_data;
1215 struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; 1216 struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
1216 1217
1217 if (bnx2i_conn->ep->num_active_cmds + 1 > hba->max_sqes) 1218 if (atomic_read(&bnx2i_conn->ep->num_active_cmds) + 1 >
1219 hba->max_sqes)
1218 return -ENOMEM; 1220 return -ENOMEM;
1219 1221
1220 /* 1222 /*
@@ -1354,6 +1356,9 @@ bnx2i_conn_create(struct iscsi_cls_session *cls_session, uint32_t cid)
1354 bnx2i_conn = conn->dd_data; 1356 bnx2i_conn = conn->dd_data;
1355 bnx2i_conn->cls_conn = cls_conn; 1357 bnx2i_conn->cls_conn = cls_conn;
1356 bnx2i_conn->hba = hba; 1358 bnx2i_conn->hba = hba;
1359
1360 atomic_set(&bnx2i_conn->work_cnt, 0);
1361
1357 /* 'ep' ptr will be assigned in bind() call */ 1362 /* 'ep' ptr will be assigned in bind() call */
1358 bnx2i_conn->ep = NULL; 1363 bnx2i_conn->ep = NULL;
1359 init_completion(&bnx2i_conn->cmd_cleanup_cmpl); 1364 init_completion(&bnx2i_conn->cmd_cleanup_cmpl);
@@ -1457,11 +1462,34 @@ static void bnx2i_conn_destroy(struct iscsi_cls_conn *cls_conn)
1457 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1462 struct bnx2i_conn *bnx2i_conn = conn->dd_data;
1458 struct Scsi_Host *shost; 1463 struct Scsi_Host *shost;
1459 struct bnx2i_hba *hba; 1464 struct bnx2i_hba *hba;
1465 struct bnx2i_work *work, *tmp;
1466 unsigned cpu = 0;
1467 struct bnx2i_percpu_s *p;
1460 1468
1461 shost = iscsi_session_to_shost(iscsi_conn_to_session(cls_conn)); 1469 shost = iscsi_session_to_shost(iscsi_conn_to_session(cls_conn));
1462 hba = iscsi_host_priv(shost); 1470 hba = iscsi_host_priv(shost);
1463 1471
1464 bnx2i_conn_free_login_resources(hba, bnx2i_conn); 1472 bnx2i_conn_free_login_resources(hba, bnx2i_conn);
1473
1474 if (atomic_read(&bnx2i_conn->work_cnt)) {
1475 for_each_online_cpu(cpu) {
1476 p = &per_cpu(bnx2i_percpu, cpu);
1477 spin_lock_bh(&p->p_work_lock);
1478 list_for_each_entry_safe(work, tmp,
1479 &p->work_list, list) {
1480 if (work->session == conn->session &&
1481 work->bnx2i_conn == bnx2i_conn) {
1482 list_del_init(&work->list);
1483 kfree(work);
1484 if (!atomic_dec_and_test(
1485 &bnx2i_conn->work_cnt))
1486 break;
1487 }
1488 }
1489 spin_unlock_bh(&p->p_work_lock);
1490 }
1491 }
1492
1465 iscsi_conn_teardown(cls_conn); 1493 iscsi_conn_teardown(cls_conn);
1466} 1494}
1467 1495
@@ -1769,7 +1797,7 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1769 } 1797 }
1770 bnx2i_ep = ep->dd_data; 1798 bnx2i_ep = ep->dd_data;
1771 1799
1772 bnx2i_ep->num_active_cmds = 0; 1800 atomic_set(&bnx2i_ep->num_active_cmds, 0);
1773 iscsi_cid = bnx2i_alloc_iscsi_cid(hba); 1801 iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
1774 if (iscsi_cid == -1) { 1802 if (iscsi_cid == -1) {
1775 printk(KERN_ALERT "bnx2i (%s): alloc_ep - unable to allocate " 1803 printk(KERN_ALERT "bnx2i (%s): alloc_ep - unable to allocate "
@@ -2163,9 +2191,9 @@ static struct scsi_host_template bnx2i_host_template = {
2163 .eh_device_reset_handler = iscsi_eh_device_reset, 2191 .eh_device_reset_handler = iscsi_eh_device_reset,
2164 .eh_target_reset_handler = iscsi_eh_recover_target, 2192 .eh_target_reset_handler = iscsi_eh_recover_target,
2165 .change_queue_depth = iscsi_change_queue_depth, 2193 .change_queue_depth = iscsi_change_queue_depth,
2166 .can_queue = 1024, 2194 .can_queue = 2048,
2167 .max_sectors = 127, 2195 .max_sectors = 127,
2168 .cmd_per_lun = 24, 2196 .cmd_per_lun = 128,
2169 .this_id = -1, 2197 .this_id = -1,
2170 .use_clustering = ENABLE_CLUSTERING, 2198 .use_clustering = ENABLE_CLUSTERING,
2171 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, 2199 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD,