aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohank@serverengines.com>2010-01-04 18:40:46 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-01-18 11:48:23 -0500
commit756d29c8c7ed8887ed7d752371ce2f6d12399267 (patch)
treeeb70b756dc22a798538b306010647b72709a6206 /drivers/scsi/be2iscsi
parent51a462500fbed4a1e8110dc60a421a3f12b9580b (diff)
[SCSI] be2iscsi: Enable async mode for mcc rings
This patches enables async mode for mcc rings so that multiple requests can be queued. Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be.h16
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c82
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h12
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c100
-rw-r--r--drivers/scsi/be2iscsi/be_main.c83
-rw-r--r--drivers/scsi/be2iscsi/be_main.h2
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c128
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h3
8 files changed, 330 insertions, 96 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index a93a5040f087..3861cf44dc15 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -24,6 +24,7 @@
24#define FW_VER_LEN 32 24#define FW_VER_LEN 32
25#define MCC_Q_LEN 128 25#define MCC_Q_LEN 128
26#define MCC_CQ_LEN 256 26#define MCC_CQ_LEN 256
27#define MAX_MCC_CMD 16
27 28
28struct be_dma_mem { 29struct be_dma_mem {
29 void *va; 30 void *va;
@@ -57,6 +58,11 @@ static inline void *queue_head_node(struct be_queue_info *q)
57 return q->dma_mem.va + q->head * q->entry_size; 58 return q->dma_mem.va + q->head * q->entry_size;
58} 59}
59 60
61static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num)
62{
63 return q->dma_mem.va + wrb_num * q->entry_size;
64}
65
60static inline void *queue_tail_node(struct be_queue_info *q) 66static inline void *queue_tail_node(struct be_queue_info *q)
61{ 67{
62 return q->dma_mem.va + q->tail * q->entry_size; 68 return q->dma_mem.va + q->tail * q->entry_size;
@@ -104,15 +110,19 @@ struct be_ctrl_info {
104 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ 110 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
105 spinlock_t mcc_cq_lock; 111 spinlock_t mcc_cq_lock;
106 112
107 /* MCC Async callback */ 113 wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
108 void (*async_cb) (void *adapter, bool link_up); 114 unsigned int mcc_tag[MAX_MCC_CMD];
109 void *adapter_ctxt; 115 unsigned int mcc_numtag[MAX_MCC_CMD + 1];
116 unsigned short mcc_alloc_index;
117 unsigned short mcc_free_index;
118 unsigned int mcc_tag_available;
110}; 119};
111 120
112#include "be_cmds.h" 121#include "be_cmds.h"
113 122
114#define PAGE_SHIFT_4K 12 123#define PAGE_SHIFT_4K 12
115#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) 124#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
125#define mcc_timeout 120000 /* 5s timeout */
116 126
117/* Returns number of pages spanned by the data starting at the given addr */ 127/* Returns number of pages spanned by the data starting at the given addr */
118#define PAGES_4K_SPANNED(_address, size) \ 128#define PAGES_4K_SPANNED(_address, size) \
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index f008708f1b08..d4a0d1da4875 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -19,7 +19,7 @@
19#include "be_mgmt.h" 19#include "be_mgmt.h"
20#include "be_main.h" 20#include "be_main.h"
21 21
22static void be_mcc_notify(struct beiscsi_hba *phba) 22void be_mcc_notify(struct beiscsi_hba *phba)
23{ 23{
24 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 24 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
25 u32 val = 0; 25 u32 val = 0;
@@ -29,6 +29,52 @@ static void be_mcc_notify(struct beiscsi_hba *phba)
29 iowrite32(val, phba->db_va + DB_MCCQ_OFFSET); 29 iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
30} 30}
31 31
32unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
33{
34 unsigned int tag = 0;
35 unsigned int num = 0;
36
37mcc_tag_rdy:
38 if (phba->ctrl.mcc_tag_available) {
39 tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
40 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
41 phba->ctrl.mcc_numtag[tag] = 0;
42 } else {
43 udelay(100);
44 num++;
45 if (num < mcc_timeout)
46 goto mcc_tag_rdy;
47 }
48 if (tag) {
49 phba->ctrl.mcc_tag_available--;
50 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
51 phba->ctrl.mcc_alloc_index = 0;
52 else
53 phba->ctrl.mcc_alloc_index++;
54 }
55 return tag;
56}
57
58void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
59{
60 spin_lock(&ctrl->mbox_lock);
61 tag = tag & 0x000000FF;
62 ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
63 if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
64 ctrl->mcc_free_index = 0;
65 else
66 ctrl->mcc_free_index++;
67 ctrl->mcc_tag_available++;
68 spin_unlock(&ctrl->mbox_lock);
69}
70
71bool is_link_state_evt(u32 trailer)
72{
73 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
74 ASYNC_TRAILER_EVENT_CODE_MASK) ==
75 ASYNC_EVENT_CODE_LINK_STATE);
76}
77
32static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) 78static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
33{ 79{
34 if (compl->flags != 0) { 80 if (compl->flags != 0) {
@@ -64,12 +110,30 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
64 return 0; 110 return 0;
65} 111}
66 112
67 113int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
68static inline bool is_link_state_evt(u32 trailer) 114 struct be_mcc_compl *compl)
69{ 115{
70 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & 116 u16 compl_status, extd_status;
71 ASYNC_TRAILER_EVENT_CODE_MASK) == 117 unsigned short tag;
72 ASYNC_EVENT_CODE_LINK_STATE); 118
119 be_dws_le_to_cpu(compl, 4);
120
121 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
122 CQE_STATUS_COMPL_MASK;
123 /* The ctrl.mcc_numtag[tag] is filled with
124 * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
125 * [7:0] = compl_status
126 */
127 tag = (compl->tag0 & 0x000000FF);
128 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
129 CQE_STATUS_EXTD_MASK;
130
131 ctrl->mcc_numtag[tag] = 0x80000000;
132 ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000);
133 ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8;
134 ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF);
135 wake_up_interruptible(&ctrl->mcc_wait[tag]);
136 return 0;
73} 137}
74 138
75static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba) 139static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
@@ -89,7 +153,7 @@ static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
89 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 153 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
90} 154}
91 155
92static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, 156void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
93 struct be_async_event_link_state *evt) 157 struct be_async_event_link_state *evt)
94{ 158{
95 switch (evt->port_link_status) { 159 switch (evt->port_link_status) {
@@ -162,7 +226,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
162/* Wait till no more pending mcc requests are present */ 226/* Wait till no more pending mcc requests are present */
163static int be_mcc_wait_compl(struct beiscsi_hba *phba) 227static int be_mcc_wait_compl(struct beiscsi_hba *phba)
164{ 228{
165#define mcc_timeout 120000 /* 5s timeout */
166 int i, status; 229 int i, status;
167 for (i = 0; i < mcc_timeout; i++) { 230 for (i = 0; i < mcc_timeout; i++) {
168 status = beiscsi_process_mcc(phba); 231 status = beiscsi_process_mcc(phba);
@@ -372,9 +435,10 @@ struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
372 435
373 BUG_ON(atomic_read(&mccq->used) >= mccq->len); 436 BUG_ON(atomic_read(&mccq->used) >= mccq->len);
374 wrb = queue_head_node(mccq); 437 wrb = queue_head_node(mccq);
438 memset(wrb, 0, sizeof(*wrb));
439 wrb->tag0 = (mccq->head & 0x000000FF) << 16;
375 queue_head_inc(mccq); 440 queue_head_inc(mccq);
376 atomic_inc(&mccq->used); 441 atomic_inc(&mccq->used);
377 memset(wrb, 0, sizeof(*wrb));
378 return wrb; 442 return wrb;
379} 443}
380 444
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 5de8acb924cb..69dddfaebe59 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -425,14 +425,20 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
425int be_poll_mcc(struct be_ctrl_info *ctrl); 425int be_poll_mcc(struct be_ctrl_info *ctrl);
426unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, 426unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
427 struct beiscsi_hba *phba); 427 struct beiscsi_hba *phba);
428int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr); 428unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba);
429 429void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
430/*ISCSI Functuions */ 430/*ISCSI Functuions */
431int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); 431int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
432 432
433struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); 433struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem);
434struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba); 434struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba);
435int be_mcc_notify_wait(struct beiscsi_hba *phba); 435int be_mcc_notify_wait(struct beiscsi_hba *phba);
436void be_mcc_notify(struct beiscsi_hba *phba);
437unsigned int alloc_mcc_tag(struct beiscsi_hba *phba);
438void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
439 struct be_async_event_link_state *evt);
440int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
441 struct be_mcc_compl *compl);
436 442
437int be_mbox_notify(struct be_ctrl_info *ctrl); 443int be_mbox_notify(struct be_ctrl_info *ctrl);
438 444
@@ -448,6 +454,8 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
448int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, 454int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
449 struct be_queue_info *wrbq); 455 struct be_queue_info *wrbq);
450 456
457bool is_link_state_evt(u32 trailer);
458
451struct be_default_pdu_context { 459struct be_default_pdu_context {
452 u32 dw[4]; 460 u32 dw[4];
453} __packed; 461} __packed;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index f22918427a2e..95694d3d2089 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -101,6 +101,7 @@ void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
101 struct iscsi_session *sess = cls_session->dd_data; 101 struct iscsi_session *sess = cls_session->dd_data;
102 struct beiscsi_session *beiscsi_sess = sess->dd_data; 102 struct beiscsi_session *beiscsi_sess = sess->dd_data;
103 103
104 SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n");
104 pci_pool_destroy(beiscsi_sess->bhs_pool); 105 pci_pool_destroy(beiscsi_sess->bhs_pool);
105 iscsi_session_teardown(cls_session); 106 iscsi_session_teardown(cls_session);
106} 107}
@@ -224,6 +225,7 @@ int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
224 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 225 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
225 int len = 0; 226 int len = 0;
226 227
228 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param);
227 beiscsi_ep = beiscsi_conn->ep; 229 beiscsi_ep = beiscsi_conn->ep;
228 if (!beiscsi_ep) { 230 if (!beiscsi_ep) {
229 SE_DEBUG(DBG_LVL_1, 231 SE_DEBUG(DBG_LVL_1,
@@ -254,6 +256,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
254 struct iscsi_session *session = conn->session; 256 struct iscsi_session *session = conn->session;
255 int ret; 257 int ret;
256 258
259 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param);
257 ret = iscsi_set_param(cls_conn, param, buf, buflen); 260 ret = iscsi_set_param(cls_conn, param, buf, buflen);
258 if (ret) 261 if (ret)
259 return ret; 262 return ret;
@@ -293,12 +296,41 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
293 enum iscsi_host_param param, char *buf) 296 enum iscsi_host_param param, char *buf)
294{ 297{
295 struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); 298 struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
299 struct be_cmd_resp_get_mac_addr *resp;
300 struct be_mcc_wrb *wrb;
301 unsigned int tag, wrb_num;
296 int len = 0; 302 int len = 0;
303 unsigned short status, extd_status;
304 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
297 305
306 SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
298 switch (param) { 307 switch (param) {
299 case ISCSI_HOST_PARAM_HWADDRESS: 308 case ISCSI_HOST_PARAM_HWADDRESS:
300 be_cmd_get_mac_addr(phba, phba->mac_address); 309 tag = be_cmd_get_mac_addr(phba);
301 len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 310 if (!tag) {
311 SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n");
312 return -1;
313 } else
314 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
315 phba->ctrl.mcc_numtag[tag]);
316
317 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
318 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
319 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
320 if (status || extd_status) {
321 SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
322 " status = %d extd_status = %d \n",
323 status, extd_status);
324 free_mcc_tag(&phba->ctrl, tag);
325 return -1;
326 } else {
327 wrb = queue_get_wrb(mccq, wrb_num);
328 free_mcc_tag(&phba->ctrl, tag);
329 resp = embedded_payload(wrb);
330 memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
331 len = sysfs_format_mac(buf, phba->mac_address,
332 ETH_ALEN);
333 }
302 break; 334 break;
303 default: 335 default:
304 return iscsi_host_get_param(shost, param, buf); 336 return iscsi_host_get_param(shost, param, buf);
@@ -378,6 +410,7 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
378 struct beiscsi_endpoint *beiscsi_ep; 410 struct beiscsi_endpoint *beiscsi_ep;
379 struct beiscsi_offload_params params; 411 struct beiscsi_offload_params params;
380 412
413 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n");
381 memset(&params, 0, sizeof(struct beiscsi_offload_params)); 414 memset(&params, 0, sizeof(struct beiscsi_offload_params));
382 beiscsi_ep = beiscsi_conn->ep; 415 beiscsi_ep = beiscsi_conn->ep;
383 if (!beiscsi_ep) 416 if (!beiscsi_ep)
@@ -422,8 +455,14 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
422{ 455{
423 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 456 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
424 struct beiscsi_hba *phba = beiscsi_ep->phba; 457 struct beiscsi_hba *phba = beiscsi_ep->phba;
458 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
459 struct be_mcc_wrb *wrb;
460 struct tcp_connect_and_offload_out *ptcpcnct_out;
461 unsigned short status, extd_status;
462 unsigned int tag, wrb_num;
425 int ret = -1; 463 int ret = -1;
426 464
465 SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
427 beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 466 beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
428 if (beiscsi_ep->ep_cid == 0xFFFF) { 467 if (beiscsi_ep->ep_cid == 0xFFFF) {
429 SE_DEBUG(DBG_LVL_1, "No free cid available\n"); 468 SE_DEBUG(DBG_LVL_1, "No free cid available\n");
@@ -440,7 +479,35 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
440 } 479 }
441 480
442 beiscsi_ep->cid_vld = 0; 481 beiscsi_ep->cid_vld = 0;
443 return mgmt_open_connection(phba, dst_addr, beiscsi_ep); 482 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
483 if (!tag) {
484 SE_DEBUG(DBG_LVL_1,
485 "mgmt_invalidate_connection Failed for cid=%d \n",
486 beiscsi_ep->ep_cid);
487 } else {
488 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
489 phba->ctrl.mcc_numtag[tag]);
490 }
491 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
492 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
493 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
494 if (status || extd_status) {
495 SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
496 " status = %d extd_status = %d \n",
497 status, extd_status);
498 free_mcc_tag(&phba->ctrl, tag);
499 return -1;
500 } else {
501 wrb = queue_get_wrb(mccq, wrb_num);
502 free_mcc_tag(&phba->ctrl, tag);
503
504 ptcpcnct_out = embedded_payload(wrb);
505 beiscsi_ep = ep->dd_data;
506 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
507 beiscsi_ep->cid_vld = 1;
508 SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
509 }
510 return 0;
444} 511}
445 512
446/** 513/**
@@ -509,7 +576,6 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
509 beiscsi_ep = ep->dd_data; 576 beiscsi_ep = ep->dd_data;
510 beiscsi_ep->phba = phba; 577 beiscsi_ep->phba = phba;
511 beiscsi_ep->openiscsi_ep = ep; 578 beiscsi_ep->openiscsi_ep = ep;
512
513 if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { 579 if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
514 SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n"); 580 SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
515 ret = -ENOMEM; 581 ret = -ENOMEM;
@@ -549,16 +615,19 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
549static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) 615static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
550{ 616{
551 int ret = 0; 617 int ret = 0;
618 unsigned int tag;
552 struct beiscsi_hba *phba = beiscsi_ep->phba; 619 struct beiscsi_hba *phba = beiscsi_ep->phba;
553 620
554 if (MGMT_STATUS_SUCCESS != 621 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
555 mgmt_upload_connection(phba, beiscsi_ep->ep_cid, 622 if (!tag) {
556 flag)) {
557 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", 623 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
558 beiscsi_ep->ep_cid); 624 beiscsi_ep->ep_cid);
559 ret = -1; 625 ret = -1;
626 } else {
627 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
628 phba->ctrl.mcc_numtag[tag]);
629 free_mcc_tag(&phba->ctrl, tag);
560 } 630 }
561
562 return ret; 631 return ret;
563} 632}
564 633
@@ -576,6 +645,8 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
576 645
577 beiscsi_ep = ep->dd_data; 646 beiscsi_ep = ep->dd_data;
578 phba = beiscsi_ep->phba; 647 phba = beiscsi_ep->phba;
648 SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
649 beiscsi_ep->ep_cid);
579 650
580 if (beiscsi_ep->conn) { 651 if (beiscsi_ep->conn) {
581 beiscsi_conn = beiscsi_ep->conn; 652 beiscsi_conn = beiscsi_ep->conn;
@@ -614,22 +685,27 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
614 struct iscsi_session *session = conn->session; 685 struct iscsi_session *session = conn->session;
615 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); 686 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
616 struct beiscsi_hba *phba = iscsi_host_priv(shost); 687 struct beiscsi_hba *phba = iscsi_host_priv(shost);
617 unsigned int status; 688 unsigned int tag;
618 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 689 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
619 690
620 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n");
621 beiscsi_ep = beiscsi_conn->ep; 691 beiscsi_ep = beiscsi_conn->ep;
622 if (!beiscsi_ep) { 692 if (!beiscsi_ep) {
623 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n"); 693 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n");
624 return; 694 return;
625 } 695 }
626 status = mgmt_invalidate_connection(phba, beiscsi_ep, 696 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop ep_cid = %d\n",
697 beiscsi_ep->ep_cid);
698 tag = mgmt_invalidate_connection(phba, beiscsi_ep,
627 beiscsi_ep->ep_cid, 1, 699 beiscsi_ep->ep_cid, 1,
628 savecfg_flag); 700 savecfg_flag);
629 if (status != MGMT_STATUS_SUCCESS) { 701 if (!tag) {
630 SE_DEBUG(DBG_LVL_1, 702 SE_DEBUG(DBG_LVL_1,
631 "mgmt_invalidate_connection Failed for cid=%d \n", 703 "mgmt_invalidate_connection Failed for cid=%d \n",
632 beiscsi_ep->ep_cid); 704 beiscsi_ep->ep_cid);
705 } else {
706 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
707 phba->ctrl.mcc_numtag[tag]);
708 free_mcc_tag(&phba->ctrl, tag);
633 } 709 }
634 beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); 710 beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
635 beiscsi_free_ep(beiscsi_ep); 711 beiscsi_free_ep(beiscsi_ep);
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 6170548a5289..a6a2c6469677 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -442,7 +442,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
442 if (phba->todo_mcc_cq) 442 if (phba->todo_mcc_cq)
443 queue_work(phba->wq, &phba->work_cqs); 443 queue_work(phba->wq, &phba->work_cqs);
444 444
445 if ((num_mcceq_processed) && (!num_ioeq_processed)) 445 if ((num_mcceq_processed) && (!num_ioeq_processed))
446 hwi_ring_eq_db(phba, eq->id, 0, 446 hwi_ring_eq_db(phba, eq->id, 0,
447 (num_ioeq_processed + 447 (num_ioeq_processed +
448 num_mcceq_processed) , 1, 1); 448 num_mcceq_processed) , 1, 1);
@@ -651,7 +651,6 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
651 pwrb_context->alloc_index = 0; 651 pwrb_context->alloc_index = 0;
652 else 652 else
653 pwrb_context->alloc_index++; 653 pwrb_context->alloc_index++;
654
655 pwrb_handle_tmp = pwrb_context->pwrb_handle_base[ 654 pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
656 pwrb_context->alloc_index]; 655 pwrb_context->alloc_index];
657 pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index; 656 pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
@@ -791,6 +790,7 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
791 memcpy(task->sc->sense_buffer, sense, 790 memcpy(task->sc->sense_buffer, sense,
792 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); 791 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
793 } 792 }
793
794 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { 794 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
795 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] 795 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
796 & SOL_RES_CNT_MASK) 796 & SOL_RES_CNT_MASK)
@@ -1432,6 +1432,48 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn,
1432 hwi_post_async_buffers(phba, pasync_handle->is_header); 1432 hwi_post_async_buffers(phba, pasync_handle->is_header);
1433} 1433}
1434 1434
1435static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
1436{
1437 struct be_queue_info *mcc_cq;
1438 struct be_mcc_compl *mcc_compl;
1439 unsigned int num_processed = 0;
1440
1441 mcc_cq = &phba->ctrl.mcc_obj.cq;
1442 mcc_compl = queue_tail_node(mcc_cq);
1443 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1444 while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
1445
1446 if (num_processed >= 32) {
1447 hwi_ring_cq_db(phba, mcc_cq->id,
1448 num_processed, 0, 0);
1449 num_processed = 0;
1450 }
1451 if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
1452 /* Interpret flags as an async trailer */
1453 if (is_link_state_evt(mcc_compl->flags))
1454 /* Interpret compl as a async link evt */
1455 beiscsi_async_link_state_process(phba,
1456 (struct be_async_event_link_state *) mcc_compl);
1457 else
1458 SE_DEBUG(DBG_LVL_1,
1459 " Unsupported Async Event, flags"
1460 " = 0x%08x \n", mcc_compl->flags);
1461 } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
1462 be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
1463 atomic_dec(&phba->ctrl.mcc_obj.q.used);
1464 }
1465
1466 mcc_compl->flags = 0;
1467 queue_tail_inc(mcc_cq);
1468 mcc_compl = queue_tail_node(mcc_cq);
1469 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1470 num_processed++;
1471 }
1472
1473 if (num_processed > 0)
1474 hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
1475
1476}
1435 1477
1436static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) 1478static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1437{ 1479{
@@ -1468,6 +1510,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1468 } 1510 }
1469 beiscsi_ep = ep->dd_data; 1511 beiscsi_ep = ep->dd_data;
1470 beiscsi_conn = beiscsi_ep->conn; 1512 beiscsi_conn = beiscsi_ep->conn;
1513
1471 if (num_processed >= 32) { 1514 if (num_processed >= 32) {
1472 hwi_ring_cq_db(phba, cq->id, 1515 hwi_ring_cq_db(phba, cq->id,
1473 num_processed, 0, 0); 1516 num_processed, 0, 0);
@@ -1603,7 +1646,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1603 return tot_nump; 1646 return tot_nump;
1604} 1647}
1605 1648
1606static void beiscsi_process_all_cqs(struct work_struct *work) 1649void beiscsi_process_all_cqs(struct work_struct *work)
1607{ 1650{
1608 unsigned long flags; 1651 unsigned long flags;
1609 struct hwi_controller *phwi_ctrlr; 1652 struct hwi_controller *phwi_ctrlr;
@@ -1623,6 +1666,7 @@ static void beiscsi_process_all_cqs(struct work_struct *work)
1623 spin_lock_irqsave(&phba->isr_lock, flags); 1666 spin_lock_irqsave(&phba->isr_lock, flags);
1624 phba->todo_mcc_cq = 0; 1667 phba->todo_mcc_cq = 0;
1625 spin_unlock_irqrestore(&phba->isr_lock, flags); 1668 spin_unlock_irqrestore(&phba->isr_lock, flags);
1669 beiscsi_process_mcc_isr(phba);
1626 } 1670 }
1627 1671
1628 if (phba->todo_cq) { 1672 if (phba->todo_cq) {
@@ -3160,6 +3204,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
3160 struct be_queue_info *eq; 3204 struct be_queue_info *eq;
3161 struct be_eq_entry *eqe = NULL; 3205 struct be_eq_entry *eqe = NULL;
3162 int i, eq_msix; 3206 int i, eq_msix;
3207 unsigned int num_processed;
3163 3208
3164 phwi_ctrlr = phba->phwi_ctrlr; 3209 phwi_ctrlr = phba->phwi_ctrlr;
3165 phwi_context = phwi_ctrlr->phwi_ctxt; 3210 phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -3171,13 +3216,17 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
3171 for (i = 0; i < (phba->num_cpus + eq_msix); i++) { 3216 for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
3172 eq = &phwi_context->be_eq[i].q; 3217 eq = &phwi_context->be_eq[i].q;
3173 eqe = queue_tail_node(eq); 3218 eqe = queue_tail_node(eq);
3174 3219 num_processed = 0;
3175 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] 3220 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
3176 & EQE_VALID_MASK) { 3221 & EQE_VALID_MASK) {
3177 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); 3222 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
3178 queue_tail_inc(eq); 3223 queue_tail_inc(eq);
3179 eqe = queue_tail_node(eq); 3224 eqe = queue_tail_node(eq);
3225 num_processed++;
3180 } 3226 }
3227
3228 if (num_processed)
3229 hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1);
3181 } 3230 }
3182} 3231}
3183 3232
@@ -3189,8 +3238,9 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
3189 if (mgmt_status) 3238 if (mgmt_status)
3190 shost_printk(KERN_WARNING, phba->shost, 3239 shost_printk(KERN_WARNING, phba->shost,
3191 "mgmt_epfw_cleanup FAILED \n"); 3240 "mgmt_epfw_cleanup FAILED \n");
3192 hwi_cleanup(phba); 3241
3193 hwi_purge_eq(phba); 3242 hwi_purge_eq(phba);
3243 hwi_cleanup(phba);
3194 if (ring_mode) 3244 if (ring_mode)
3195 kfree(phba->sgl_hndl_array); 3245 kfree(phba->sgl_hndl_array);
3196 kfree(phba->io_sgl_hndl_base); 3246 kfree(phba->io_sgl_hndl_base);
@@ -3519,6 +3569,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
3519 unsigned int doorbell = 0; 3569 unsigned int doorbell = 0;
3520 unsigned int i, cid; 3570 unsigned int i, cid;
3521 struct iscsi_task *aborted_task; 3571 struct iscsi_task *aborted_task;
3572 unsigned int tag;
3522 3573
3523 cid = beiscsi_conn->beiscsi_conn_cid; 3574 cid = beiscsi_conn->beiscsi_conn_cid;
3524 pwrb = io_task->pwrb_handle->pwrb; 3575 pwrb = io_task->pwrb_handle->pwrb;
@@ -3550,7 +3601,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
3550 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3601 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3551 else 3602 else
3552 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); 3603 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1);
3553
3554 hwi_write_buffer(pwrb, task); 3604 hwi_write_buffer(pwrb, task);
3555 break; 3605 break;
3556 case ISCSI_OP_TEXT: 3606 case ISCSI_OP_TEXT:
@@ -3579,9 +3629,18 @@ static int beiscsi_mtask(struct iscsi_task *task)
3579 if (!aborted_io_task->scsi_cmnd) 3629 if (!aborted_io_task->scsi_cmnd)
3580 return 0; 3630 return 0;
3581 3631
3582 mgmt_invalidate_icds(phba, 3632 tag = mgmt_invalidate_icds(phba,
3583 aborted_io_task->psgl_handle->sgl_index, 3633 aborted_io_task->psgl_handle->sgl_index,
3584 cid); 3634 cid);
3635 if (!tag) {
3636 shost_printk(KERN_WARNING, phba->shost,
3637 "mgmt_invalidate_icds could not be"
3638 " submitted\n");
3639 } else {
3640 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
3641 phba->ctrl.mcc_numtag[tag]);
3642 free_mcc_tag(&phba->ctrl, tag);
3643 }
3585 if (ring_mode) 3644 if (ring_mode)
3586 io_task->psgl_handle->type = INI_TMF_CMD; 3645 io_task->psgl_handle->type = INI_TMF_CMD;
3587 else 3646 else
@@ -3656,7 +3715,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
3656 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); 3715 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
3657} 3716}
3658 3717
3659
3660static void beiscsi_remove(struct pci_dev *pcidev) 3718static void beiscsi_remove(struct pci_dev *pcidev)
3661{ 3719{
3662 struct beiscsi_hba *phba = NULL; 3720 struct beiscsi_hba *phba = NULL;
@@ -3776,6 +3834,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3776 goto free_port; 3834 goto free_port;
3777 } 3835 }
3778 3836
3837 for (i = 0; i < MAX_MCC_CMD ; i++) {
3838 init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
3839 phba->ctrl.mcc_tag[i] = i + 1;
3840 phba->ctrl.mcc_numtag[i + 1] = 0;
3841 phba->ctrl.mcc_tag_available++;
3842 }
3843
3844 phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
3845
3779 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", 3846 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
3780 phba->shost->host_no); 3847 phba->shost->host_no);
3781 phba->wq = create_workqueue(phba->wq_name); 3848 phba->wq = create_workqueue(phba->wq_name);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 0553f49db9be..4cde8f6eb5bc 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -655,6 +655,8 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
655void 655void
656free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); 656free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
657 657
658void beiscsi_process_all_cqs(struct work_struct *work);
659
658struct pdu_nop_out { 660struct pdu_nop_out {
659 u32 dw[12]; 661 u32 dw[12];
660}; 662};
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index df1b327fe17b..18f80411aef6 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -148,10 +148,17 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
148{ 148{
149 struct be_dma_mem nonemb_cmd; 149 struct be_dma_mem nonemb_cmd;
150 struct be_ctrl_info *ctrl = &phba->ctrl; 150 struct be_ctrl_info *ctrl = &phba->ctrl;
151 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 151 struct be_mcc_wrb *wrb;
152 struct be_sge *sge = nonembedded_sgl(wrb); 152 struct be_sge *sge;
153 struct invalidate_commands_params_in *req; 153 struct invalidate_commands_params_in *req;
154 int status = 0; 154 unsigned int tag = 0;
155
156 spin_lock(&ctrl->mbox_lock);
157 tag = alloc_mcc_tag(phba);
158 if (!tag) {
159 spin_unlock(&ctrl->mbox_lock);
160 return tag;
161 }
155 162
156 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, 163 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
157 sizeof(struct invalidate_commands_params_in), 164 sizeof(struct invalidate_commands_params_in),
@@ -164,8 +171,9 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
164 } 171 }
165 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); 172 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
166 req = nonemb_cmd.va; 173 req = nonemb_cmd.va;
167 spin_lock(&ctrl->mbox_lock); 174 wrb = wrb_from_mccq(phba);
168 memset(wrb, 0, sizeof(*wrb)); 175 sge = nonembedded_sgl(wrb);
176 wrb->tag0 |= tag;
169 177
170 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 178 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
171 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 179 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -180,14 +188,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
180 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 188 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
181 sge->len = cpu_to_le32(nonemb_cmd.size); 189 sge->len = cpu_to_le32(nonemb_cmd.size);
182 190
183 status = be_mcc_notify_wait(phba); 191 be_mcc_notify(phba);
184 if (status)
185 SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
186 spin_unlock(&ctrl->mbox_lock); 192 spin_unlock(&ctrl->mbox_lock);
187 if (nonemb_cmd.va) 193 if (nonemb_cmd.va)
188 pci_free_consistent(ctrl->pdev, nonemb_cmd.size, 194 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
189 nonemb_cmd.va, nonemb_cmd.dma); 195 nonemb_cmd.va, nonemb_cmd.dma);
190 return status; 196 return tag;
191} 197}
192 198
193unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, 199unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
@@ -197,13 +203,19 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
197 unsigned short savecfg_flag) 203 unsigned short savecfg_flag)
198{ 204{
199 struct be_ctrl_info *ctrl = &phba->ctrl; 205 struct be_ctrl_info *ctrl = &phba->ctrl;
200 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 206 struct be_mcc_wrb *wrb;
201 struct iscsi_invalidate_connection_params_in *req = 207 struct iscsi_invalidate_connection_params_in *req;
202 embedded_payload(wrb); 208 unsigned int tag = 0;
203 int status = 0;
204 209
205 spin_lock(&ctrl->mbox_lock); 210 spin_lock(&ctrl->mbox_lock);
206 memset(wrb, 0, sizeof(*wrb)); 211 tag = alloc_mcc_tag(phba);
212 if (!tag) {
213 spin_unlock(&ctrl->mbox_lock);
214 return tag;
215 }
216 wrb = wrb_from_mccq(phba);
217 wrb->tag0 |= tag;
218 req = embedded_payload(wrb);
207 219
208 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 220 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
209 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 221 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
@@ -216,35 +228,37 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
216 else 228 else
217 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; 229 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
218 req->save_cfg = savecfg_flag; 230 req->save_cfg = savecfg_flag;
219 status = be_mcc_notify_wait(phba); 231 be_mcc_notify(phba);
220 if (status)
221 SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
222
223 spin_unlock(&ctrl->mbox_lock); 232 spin_unlock(&ctrl->mbox_lock);
224 return status; 233 return tag;
225} 234}
226 235
227unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, 236unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
228 unsigned short cid, unsigned int upload_flag) 237 unsigned short cid, unsigned int upload_flag)
229{ 238{
230 struct be_ctrl_info *ctrl = &phba->ctrl; 239 struct be_ctrl_info *ctrl = &phba->ctrl;
231 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 240 struct be_mcc_wrb *wrb;
232 struct tcp_upload_params_in *req = embedded_payload(wrb); 241 struct tcp_upload_params_in *req;
233 int status = 0; 242 unsigned int tag = 0;
234 243
235 spin_lock(&ctrl->mbox_lock); 244 spin_lock(&ctrl->mbox_lock);
236 memset(wrb, 0, sizeof(*wrb)); 245 tag = alloc_mcc_tag(phba);
246 if (!tag) {
247 spin_unlock(&ctrl->mbox_lock);
248 return tag;
249 }
250 wrb = wrb_from_mccq(phba);
251 req = embedded_payload(wrb);
252 wrb->tag0 |= tag;
237 253
238 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 254 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
239 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, 255 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
240 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); 256 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
241 req->id = (unsigned short)cid; 257 req->id = (unsigned short)cid;
242 req->upload_type = (unsigned char)upload_flag; 258 req->upload_type = (unsigned char)upload_flag;
243 status = be_mcc_notify_wait(phba); 259 be_mcc_notify(phba);
244 if (status)
245 SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
246 spin_unlock(&ctrl->mbox_lock); 260 spin_unlock(&ctrl->mbox_lock);
247 return status; 261 return tag;
248} 262}
249 263
250int mgmt_open_connection(struct beiscsi_hba *phba, 264int mgmt_open_connection(struct beiscsi_hba *phba,
@@ -256,13 +270,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
256 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; 270 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
257 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; 271 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
258 struct be_ctrl_info *ctrl = &phba->ctrl; 272 struct be_ctrl_info *ctrl = &phba->ctrl;
259 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 273 struct be_mcc_wrb *wrb;
260 struct tcp_connect_and_offload_in *req = embedded_payload(wrb); 274 struct tcp_connect_and_offload_in *req;
261 unsigned short def_hdr_id; 275 unsigned short def_hdr_id;
262 unsigned short def_data_id; 276 unsigned short def_data_id;
263 struct phys_addr template_address = { 0, 0 }; 277 struct phys_addr template_address = { 0, 0 };
264 struct phys_addr *ptemplate_address; 278 struct phys_addr *ptemplate_address;
265 int status = 0; 279 unsigned int tag = 0;
266 unsigned int i; 280 unsigned int i;
267 unsigned short cid = beiscsi_ep->ep_cid; 281 unsigned short cid = beiscsi_ep->ep_cid;
268 282
@@ -274,7 +288,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
274 ptemplate_address = &template_address; 288 ptemplate_address = &template_address;
275 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); 289 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
276 spin_lock(&ctrl->mbox_lock); 290 spin_lock(&ctrl->mbox_lock);
277 memset(wrb, 0, sizeof(*wrb)); 291 tag = alloc_mcc_tag(phba);
292 if (!tag) {
293 spin_unlock(&ctrl->mbox_lock);
294 return tag;
295 }
296 wrb = wrb_from_mccq(phba);
297 req = embedded_payload(wrb);
298 wrb->tag0 |= tag;
278 299
279 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 300 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
280 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 301 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -319,47 +340,36 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
319 req->do_offload = 1; 340 req->do_offload = 1;
320 req->dataout_template_pa.lo = ptemplate_address->lo; 341 req->dataout_template_pa.lo = ptemplate_address->lo;
321 req->dataout_template_pa.hi = ptemplate_address->hi; 342 req->dataout_template_pa.hi = ptemplate_address->hi;
322 status = be_mcc_notify_wait(phba); 343 be_mcc_notify(phba);
323 if (!status) {
324 struct iscsi_endpoint *ep;
325 struct tcp_connect_and_offload_out *ptcpcnct_out =
326 embedded_payload(wrb);
327
328 ep = phba->ep_array[ptcpcnct_out->cid -
329 phba->fw_config.iscsi_cid_start];
330 beiscsi_ep = ep->dd_data;
331 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
332 beiscsi_ep->cid_vld = 1;
333 SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
334 } else
335 SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n");
336 spin_unlock(&ctrl->mbox_lock); 344 spin_unlock(&ctrl->mbox_lock);
337 return status; 345 return tag;
338} 346}
339 347
340int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr) 348unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba)
341{ 349{
342 struct be_ctrl_info *ctrl = &phba->ctrl; 350 struct be_ctrl_info *ctrl = &phba->ctrl;
343 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 351 struct be_mcc_wrb *wrb;
344 struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb); 352 struct be_cmd_req_get_mac_addr *req;
345 int status; 353 unsigned int tag = 0;
346 354
347 SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); 355 SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
348 spin_lock(&ctrl->mbox_lock); 356 spin_lock(&ctrl->mbox_lock);
349 memset(wrb, 0, sizeof(*wrb)); 357 tag = alloc_mcc_tag(phba);
358 if (!tag) {
359 spin_unlock(&ctrl->mbox_lock);
360 return tag;
361 }
362
363 wrb = wrb_from_mccq(phba);
364 req = embedded_payload(wrb);
365 wrb->tag0 |= tag;
350 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 366 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
351 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 367 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
352 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, 368 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
353 sizeof(*req)); 369 sizeof(*req));
354 370
355 status = be_mcc_notify_wait(phba); 371 be_mcc_notify(phba);
356 if (!status) {
357 struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
358
359 memcpy(mac_addr, resp->mac_address, ETH_ALEN);
360 }
361
362 spin_unlock(&ctrl->mbox_lock); 372 spin_unlock(&ctrl->mbox_lock);
363 return status; 373 return tag;
364} 374}
365 375
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 6bc59e8e1fe5..f873a66cd48f 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -250,7 +250,4 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
250 unsigned short issue_reset, 250 unsigned short issue_reset,
251 unsigned short savecfg_flag); 251 unsigned short savecfg_flag);
252 252
253unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl,
254 struct beiscsi_hba *phba,
255 char *buf, unsigned int len);
256#endif 253#endif