aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be.h21
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c88
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h14
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c136
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.h2
-rw-r--r--drivers/scsi/be2iscsi/be_main.c488
-rw-r--r--drivers/scsi/be2iscsi/be_main.h27
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c139
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h6
9 files changed, 547 insertions, 374 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index a93a5040f087..136b49cea791 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,6 +24,10 @@
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
28/* BladeEngine Generation numbers */
29#define BE_GEN2 2
30#define BE_GEN3 3
27 31
28struct be_dma_mem { 32struct be_dma_mem {
29 void *va; 33 void *va;
@@ -57,6 +61,11 @@ static inline void *queue_head_node(struct be_queue_info *q)
57 return q->dma_mem.va + q->head * q->entry_size; 61 return q->dma_mem.va + q->head * q->entry_size;
58} 62}
59 63
64static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num)
65{
66 return q->dma_mem.va + wrb_num * q->entry_size;
67}
68
60static inline void *queue_tail_node(struct be_queue_info *q) 69static inline void *queue_tail_node(struct be_queue_info *q)
61{ 70{
62 return q->dma_mem.va + q->tail * q->entry_size; 71 return q->dma_mem.va + q->tail * q->entry_size;
@@ -104,15 +113,19 @@ struct be_ctrl_info {
104 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ 113 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
105 spinlock_t mcc_cq_lock; 114 spinlock_t mcc_cq_lock;
106 115
107 /* MCC Async callback */ 116 wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
108 void (*async_cb) (void *adapter, bool link_up); 117 unsigned int mcc_tag[MAX_MCC_CMD];
109 void *adapter_ctxt; 118 unsigned int mcc_numtag[MAX_MCC_CMD + 1];
119 unsigned short mcc_alloc_index;
120 unsigned short mcc_free_index;
121 unsigned int mcc_tag_available;
110}; 122};
111 123
112#include "be_cmds.h" 124#include "be_cmds.h"
113 125
114#define PAGE_SHIFT_4K 12 126#define PAGE_SHIFT_4K 12
115#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) 127#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
128#define mcc_timeout 120000 /* 5s timeout */
116 129
117/* Returns number of pages spanned by the data starting at the given addr */ 130/* Returns number of pages spanned by the data starting at the given addr */
118#define PAGES_4K_SPANNED(_address, size) \ 131#define PAGES_4K_SPANNED(_address, size) \
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index f008708f1b08..67098578fba4 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -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) {
@@ -97,13 +161,13 @@ static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
97 SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", 161 SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n",
98 evt->physical_port); 162 evt->physical_port);
99 phba->state |= BE_ADAPTER_LINK_DOWN; 163 phba->state |= BE_ADAPTER_LINK_DOWN;
164 iscsi_host_for_each_session(phba->shost,
165 be2iscsi_fail_session);
100 break; 166 break;
101 case ASYNC_EVENT_LINK_UP: 167 case ASYNC_EVENT_LINK_UP:
102 phba->state = BE_ADAPTER_UP; 168 phba->state = BE_ADAPTER_UP;
103 SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", 169 SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n",
104 evt->physical_port); 170 evt->physical_port);
105 iscsi_host_for_each_session(phba->shost,
106 be2iscsi_fail_session);
107 break; 171 break;
108 default: 172 default:
109 SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" 173 SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
@@ -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..49fcc787ee8b 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -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 d587b0362f18..29a3aaf35f9f 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -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;
@@ -271,8 +274,8 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
271 conn->max_recv_dlength = 65536; 274 conn->max_recv_dlength = 65536;
272 break; 275 break;
273 case ISCSI_PARAM_MAX_BURST: 276 case ISCSI_PARAM_MAX_BURST:
274 if (session->first_burst > 262144) 277 if (session->max_burst > 262144)
275 session->first_burst = 262144; 278 session->max_burst = 262144;
276 break; 279 break;
277 default: 280 default:
278 return 0; 281 return 0;
@@ -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");
@@ -431,15 +470,44 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
431 } 470 }
432 SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ", 471 SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ",
433 beiscsi_ep->ep_cid); 472 beiscsi_ep->ep_cid);
434 phba->ep_array[beiscsi_ep->ep_cid] = ep; 473 phba->ep_array[beiscsi_ep->ep_cid -
435 if (beiscsi_ep->ep_cid > 474 phba->fw_config.iscsi_cid_start] = ep;
436 (phba->fw_config.iscsi_cid_start + phba->params.cxns_per_ctrl)) { 475 if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
476 phba->params.cxns_per_ctrl * 2)) {
437 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); 477 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
438 return ret; 478 return ret;
439 } 479 }
440 480
441 beiscsi_ep->cid_vld = 0; 481 beiscsi_ep->cid_vld = 0;
442 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;
443} 511}
444 512
445/** 513/**
@@ -459,14 +527,12 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
459 * beiscsi_free_ep - free endpoint 527 * beiscsi_free_ep - free endpoint
460 * @ep: pointer to iscsi endpoint structure 528 * @ep: pointer to iscsi endpoint structure
461 */ 529 */
462static void beiscsi_free_ep(struct iscsi_endpoint *ep) 530static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
463{ 531{
464 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
465 struct beiscsi_hba *phba = beiscsi_ep->phba; 532 struct beiscsi_hba *phba = beiscsi_ep->phba;
466 533
467 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 534 beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
468 beiscsi_ep->phba = NULL; 535 beiscsi_ep->phba = NULL;
469 iscsi_destroy_endpoint(ep);
470} 536}
471 537
472/** 538/**
@@ -495,9 +561,9 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
495 return ERR_PTR(ret); 561 return ERR_PTR(ret);
496 } 562 }
497 563
498 if (phba->state) { 564 if (phba->state != BE_ADAPTER_UP) {
499 ret = -EBUSY; 565 ret = -EBUSY;
500 SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n"); 566 SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n");
501 return ERR_PTR(ret); 567 return ERR_PTR(ret);
502 } 568 }
503 569
@@ -509,9 +575,9 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
509 575
510 beiscsi_ep = ep->dd_data; 576 beiscsi_ep = ep->dd_data;
511 beiscsi_ep->phba = phba; 577 beiscsi_ep->phba = phba;
512 578 beiscsi_ep->openiscsi_ep = ep;
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 allocate iscsi cid\n"); 580 SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
515 ret = -ENOMEM; 581 ret = -ENOMEM;
516 goto free_ep; 582 goto free_ep;
517 } 583 }
@@ -519,7 +585,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
519 return ep; 585 return ep;
520 586
521free_ep: 587free_ep:
522 beiscsi_free_ep(ep); 588 beiscsi_free_ep(beiscsi_ep);
523 return ERR_PTR(ret); 589 return ERR_PTR(ret);
524} 590}
525 591
@@ -546,20 +612,22 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
546 * @ep: The iscsi endpoint 612 * @ep: The iscsi endpoint
547 * @flag: The type of connection closure 613 * @flag: The type of connection closure
548 */ 614 */
549static int beiscsi_close_conn(struct iscsi_endpoint *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;
552 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 618 unsigned int tag;
553 struct beiscsi_hba *phba = beiscsi_ep->phba; 619 struct beiscsi_hba *phba = beiscsi_ep->phba;
554 620
555 if (MGMT_STATUS_SUCCESS != 621 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
556 mgmt_upload_connection(phba, beiscsi_ep->ep_cid, 622 if (!tag) {
557 CONNECTION_UPLOAD_GRACEFUL)) {
558 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", 623 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
559 beiscsi_ep->ep_cid); 624 beiscsi_ep->ep_cid);
560 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);
561 } 630 }
562
563 return ret; 631 return ret;
564} 632}
565 633
@@ -574,19 +642,17 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
574 struct beiscsi_conn *beiscsi_conn; 642 struct beiscsi_conn *beiscsi_conn;
575 struct beiscsi_endpoint *beiscsi_ep; 643 struct beiscsi_endpoint *beiscsi_ep;
576 struct beiscsi_hba *phba; 644 struct beiscsi_hba *phba;
577 int flag = 0;
578 645
579 beiscsi_ep = ep->dd_data; 646 beiscsi_ep = ep->dd_data;
580 phba = beiscsi_ep->phba; 647 phba = beiscsi_ep->phba;
581 SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect\n"); 648 SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
649 beiscsi_ep->ep_cid);
582 650
583 if (beiscsi_ep->conn) { 651 if (beiscsi_ep->conn) {
584 beiscsi_conn = beiscsi_ep->conn; 652 beiscsi_conn = beiscsi_ep->conn;
585 iscsi_suspend_queue(beiscsi_conn->conn); 653 iscsi_suspend_queue(beiscsi_conn->conn);
586 beiscsi_close_conn(ep, flag);
587 } 654 }
588 655
589 beiscsi_free_ep(ep);
590} 656}
591 657
592/** 658/**
@@ -619,23 +685,31 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
619 struct iscsi_session *session = conn->session; 685 struct iscsi_session *session = conn->session;
620 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); 686 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
621 struct beiscsi_hba *phba = iscsi_host_priv(shost); 687 struct beiscsi_hba *phba = iscsi_host_priv(shost);
622 unsigned int status; 688 unsigned int tag;
623 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 689 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
624 690
625 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n");
626 beiscsi_ep = beiscsi_conn->ep; 691 beiscsi_ep = beiscsi_conn->ep;
627 if (!beiscsi_ep) { 692 if (!beiscsi_ep) {
628 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");
629 return; 694 return;
630 } 695 }
631 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,
632 beiscsi_ep->ep_cid, 1, 699 beiscsi_ep->ep_cid, 1,
633 savecfg_flag); 700 savecfg_flag);
634 if (status != MGMT_STATUS_SUCCESS) { 701 if (!tag) {
635 SE_DEBUG(DBG_LVL_1, 702 SE_DEBUG(DBG_LVL_1,
636 "mgmt_invalidate_connection Failed for cid=%d \n", 703 "mgmt_invalidate_connection Failed for cid=%d \n",
637 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);
638 } 709 }
710 beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
711 beiscsi_free_ep(beiscsi_ep);
712 iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
639 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 713 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
640 iscsi_conn_stop(cls_conn, flag); 714 iscsi_conn_stop(cls_conn, flag);
641} 715}
diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h
index f92ffc5349fb..1f512c28cbf9 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.h
+++ b/drivers/scsi/be2iscsi/be_iscsi.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 1a557fa77888..7c22616ab141 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -40,7 +40,6 @@
40static unsigned int be_iopoll_budget = 10; 40static unsigned int be_iopoll_budget = 10;
41static unsigned int be_max_phys_size = 64; 41static unsigned int be_max_phys_size = 64;
42static unsigned int enable_msix = 1; 42static unsigned int enable_msix = 1;
43static unsigned int ring_mode;
44 43
45MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); 44MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
46MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); 45MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -62,10 +61,10 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
62/*------------------- PCI Driver operations and data ----------------- */ 61/*------------------- PCI Driver operations and data ----------------- */
63static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { 62static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
64 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, 63 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
64 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
65 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, 65 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
66 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, 66 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
67 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) }, 67 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
68 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID4) },
69 { 0 } 68 { 0 }
70}; 69};
71MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); 70MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
@@ -112,6 +111,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
112 memset(phba, 0, sizeof(*phba)); 111 memset(phba, 0, sizeof(*phba));
113 phba->shost = shost; 112 phba->shost = shost;
114 phba->pcidev = pci_dev_get(pcidev); 113 phba->pcidev = pci_dev_get(pcidev);
114 pci_set_drvdata(pcidev, phba);
115 115
116 if (iscsi_host_add(shost, &phba->pcidev->dev)) 116 if (iscsi_host_add(shost, &phba->pcidev->dev))
117 goto free_devices; 117 goto free_devices;
@@ -143,6 +143,7 @@ static int beiscsi_map_pci_bars(struct beiscsi_hba *phba,
143 struct pci_dev *pcidev) 143 struct pci_dev *pcidev)
144{ 144{
145 u8 __iomem *addr; 145 u8 __iomem *addr;
146 int pcicfg_reg;
146 147
147 addr = ioremap_nocache(pci_resource_start(pcidev, 2), 148 addr = ioremap_nocache(pci_resource_start(pcidev, 2),
148 pci_resource_len(pcidev, 2)); 149 pci_resource_len(pcidev, 2));
@@ -159,13 +160,19 @@ static int beiscsi_map_pci_bars(struct beiscsi_hba *phba,
159 phba->db_va = addr; 160 phba->db_va = addr;
160 phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4); 161 phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4);
161 162
162 addr = ioremap_nocache(pci_resource_start(pcidev, 1), 163 if (phba->generation == BE_GEN2)
163 pci_resource_len(pcidev, 1)); 164 pcicfg_reg = 1;
165 else
166 pcicfg_reg = 0;
167
168 addr = ioremap_nocache(pci_resource_start(pcidev, pcicfg_reg),
169 pci_resource_len(pcidev, pcicfg_reg));
170
164 if (addr == NULL) 171 if (addr == NULL)
165 goto pci_map_err; 172 goto pci_map_err;
166 phba->ctrl.pcicfg = addr; 173 phba->ctrl.pcicfg = addr;
167 phba->pci_va = addr; 174 phba->pci_va = addr;
168 phba->pci_pa.u.a64.address = pci_resource_start(pcidev, 1); 175 phba->pci_pa.u.a64.address = pci_resource_start(pcidev, pcicfg_reg);
169 return 0; 176 return 0;
170 177
171pci_map_err: 178pci_map_err:
@@ -230,29 +237,27 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
230 237
231static void beiscsi_get_params(struct beiscsi_hba *phba) 238static void beiscsi_get_params(struct beiscsi_hba *phba)
232{ 239{
233 phba->params.ios_per_ctrl = BE2_IO_DEPTH; 240 phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count
234 phba->params.cxns_per_ctrl = BE2_MAX_SESSIONS; 241 - (phba->fw_config.iscsi_cid_count
235 phba->params.asyncpdus_per_ctrl = BE2_ASYNCPDUS; 242 + BE2_TMFS
236 phba->params.icds_per_ctrl = BE2_MAX_ICDS / 2; 243 + BE2_NOPOUT_REQ));
244 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
245 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;;
246 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
237 phba->params.num_sge_per_io = BE2_SGE; 247 phba->params.num_sge_per_io = BE2_SGE;
238 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; 248 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
239 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; 249 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ;
240 phba->params.eq_timer = 64; 250 phba->params.eq_timer = 64;
241 phba->params.num_eq_entries = 251 phba->params.num_eq_entries =
242 (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) / 252 (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
243 512) + 1) * 512; 253 + BE2_TMFS) / 512) + 1) * 512;
244 phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024) 254 phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
245 ? 1024 : phba->params.num_eq_entries; 255 ? 1024 : phba->params.num_eq_entries;
246 SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n", 256 SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n",
247 phba->params.num_eq_entries); 257 phba->params.num_eq_entries);
248 phba->params.num_cq_entries = 258 phba->params.num_cq_entries =
249 (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) / 259 (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
250 512) + 1) * 512; 260 + BE2_TMFS) / 512) + 1) * 512;
251 SE_DEBUG(DBG_LVL_8,
252 "phba->params.num_cq_entries=%d BE2_CMDS_PER_CXN=%d"
253 "BE2_LOGOUTS=%d BE2_TMFS=%d BE2_ASYNCPDUS=%d \n",
254 phba->params.num_cq_entries, BE2_CMDS_PER_CXN,
255 BE2_LOGOUTS, BE2_TMFS, BE2_ASYNCPDUS);
256 phba->params.wrbs_per_cxn = 256; 261 phba->params.wrbs_per_cxn = 256;
257} 262}
258 263
@@ -443,7 +448,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
443 if (phba->todo_mcc_cq) 448 if (phba->todo_mcc_cq)
444 queue_work(phba->wq, &phba->work_cqs); 449 queue_work(phba->wq, &phba->work_cqs);
445 450
446 if ((num_mcceq_processed) && (!num_ioeq_processed)) 451 if ((num_mcceq_processed) && (!num_ioeq_processed))
447 hwi_ring_eq_db(phba, eq->id, 0, 452 hwi_ring_eq_db(phba, eq->id, 0,
448 (num_ioeq_processed + 453 (num_ioeq_processed +
449 num_mcceq_processed) , 1, 1); 454 num_mcceq_processed) , 1, 1);
@@ -561,6 +566,7 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
561 SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n"); 566 SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
562 break; 567 break;
563 case ISCSI_OP_LOGIN_RSP: 568 case ISCSI_OP_LOGIN_RSP:
569 case ISCSI_OP_TEXT_RSP:
564 task = conn->login_task; 570 task = conn->login_task;
565 io_task = task->dd_data; 571 io_task = task->dd_data;
566 login_hdr = (struct iscsi_hdr *)ppdu; 572 login_hdr = (struct iscsi_hdr *)ppdu;
@@ -631,29 +637,29 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
631 * alloc_wrb_handle - To allocate a wrb handle 637 * alloc_wrb_handle - To allocate a wrb handle
632 * @phba: The hba pointer 638 * @phba: The hba pointer
633 * @cid: The cid to use for allocation 639 * @cid: The cid to use for allocation
634 * @index: index allocation and wrb index
635 * 640 *
636 * This happens under session_lock until submission to chip 641 * This happens under session_lock until submission to chip
637 */ 642 */
638struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, 643struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
639 int index)
640{ 644{
641 struct hwi_wrb_context *pwrb_context; 645 struct hwi_wrb_context *pwrb_context;
642 struct hwi_controller *phwi_ctrlr; 646 struct hwi_controller *phwi_ctrlr;
643 struct wrb_handle *pwrb_handle; 647 struct wrb_handle *pwrb_handle, *pwrb_handle_tmp;
644 648
645 phwi_ctrlr = phba->phwi_ctrlr; 649 phwi_ctrlr = phba->phwi_ctrlr;
646 pwrb_context = &phwi_ctrlr->wrb_context[cid]; 650 pwrb_context = &phwi_ctrlr->wrb_context[cid];
647 if (pwrb_context->wrb_handles_available) { 651 if (pwrb_context->wrb_handles_available >= 2) {
648 pwrb_handle = pwrb_context->pwrb_handle_base[ 652 pwrb_handle = pwrb_context->pwrb_handle_base[
649 pwrb_context->alloc_index]; 653 pwrb_context->alloc_index];
650 pwrb_context->wrb_handles_available--; 654 pwrb_context->wrb_handles_available--;
651 pwrb_handle->nxt_wrb_index = pwrb_handle->wrb_index;
652 if (pwrb_context->alloc_index == 655 if (pwrb_context->alloc_index ==
653 (phba->params.wrbs_per_cxn - 1)) 656 (phba->params.wrbs_per_cxn - 1))
654 pwrb_context->alloc_index = 0; 657 pwrb_context->alloc_index = 0;
655 else 658 else
656 pwrb_context->alloc_index++; 659 pwrb_context->alloc_index++;
660 pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
661 pwrb_context->alloc_index];
662 pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
657 } else 663 } else
658 pwrb_handle = NULL; 664 pwrb_handle = NULL;
659 return pwrb_handle; 665 return pwrb_handle;
@@ -671,9 +677,7 @@ static void
671free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, 677free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
672 struct wrb_handle *pwrb_handle) 678 struct wrb_handle *pwrb_handle)
673{ 679{
674 if (!ring_mode) 680 pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
675 pwrb_context->pwrb_handle_base[pwrb_context->free_index] =
676 pwrb_handle;
677 pwrb_context->wrb_handles_available++; 681 pwrb_context->wrb_handles_available++;
678 if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1)) 682 if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
679 pwrb_context->free_index = 0; 683 pwrb_context->free_index = 0;
@@ -790,6 +794,7 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
790 memcpy(task->sc->sense_buffer, sense, 794 memcpy(task->sc->sense_buffer, sense,
791 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); 795 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
792 } 796 }
797
793 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { 798 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
794 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] 799 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
795 & SOL_RES_CNT_MASK) 800 & SOL_RES_CNT_MASK)
@@ -811,6 +816,7 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
811 struct iscsi_conn *conn = beiscsi_conn->conn; 816 struct iscsi_conn *conn = beiscsi_conn->conn;
812 817
813 hdr = (struct iscsi_logout_rsp *)task->hdr; 818 hdr = (struct iscsi_logout_rsp *)task->hdr;
819 hdr->opcode = ISCSI_OP_LOGOUT_RSP;
814 hdr->t2wait = 5; 820 hdr->t2wait = 5;
815 hdr->t2retain = 0; 821 hdr->t2retain = 0;
816 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 822 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -825,6 +831,9 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
825 & SOL_EXP_CMD_SN_MASK) + 831 & SOL_EXP_CMD_SN_MASK) +
826 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) 832 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
827 / 32] & SOL_CMD_WND_MASK) >> 24) - 1); 833 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
834 hdr->dlength[0] = 0;
835 hdr->dlength[1] = 0;
836 hdr->dlength[2] = 0;
828 hdr->hlength = 0; 837 hdr->hlength = 0;
829 hdr->itt = io_task->libiscsi_itt; 838 hdr->itt = io_task->libiscsi_itt;
830 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); 839 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
@@ -839,6 +848,7 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
839 struct beiscsi_io_task *io_task = task->dd_data; 848 struct beiscsi_io_task *io_task = task->dd_data;
840 849
841 hdr = (struct iscsi_tm_rsp *)task->hdr; 850 hdr = (struct iscsi_tm_rsp *)task->hdr;
851 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
842 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 852 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
843 & SOL_FLAGS_MASK) >> 24) | 0x80; 853 & SOL_FLAGS_MASK) >> 24) | 0x80;
844 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 854 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
@@ -859,7 +869,6 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
859{ 869{
860 struct hwi_wrb_context *pwrb_context; 870 struct hwi_wrb_context *pwrb_context;
861 struct wrb_handle *pwrb_handle = NULL; 871 struct wrb_handle *pwrb_handle = NULL;
862 struct sgl_handle *psgl_handle = NULL;
863 struct hwi_controller *phwi_ctrlr; 872 struct hwi_controller *phwi_ctrlr;
864 struct iscsi_task *task; 873 struct iscsi_task *task;
865 struct beiscsi_io_task *io_task; 874 struct beiscsi_io_task *io_task;
@@ -867,22 +876,14 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
867 struct iscsi_session *session = conn->session; 876 struct iscsi_session *session = conn->session;
868 877
869 phwi_ctrlr = phba->phwi_ctrlr; 878 phwi_ctrlr = phba->phwi_ctrlr;
870 if (ring_mode) { 879 pwrb_context = &phwi_ctrlr->wrb_context[((psol->
871 psgl_handle = phba->sgl_hndl_array[((psol->
872 dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
873 32] & SOL_ICD_INDEX_MASK) >> 6)];
874 pwrb_context = &phwi_ctrlr->wrb_context[psgl_handle->cid];
875 task = psgl_handle->task;
876 pwrb_handle = NULL;
877 } else {
878 pwrb_context = &phwi_ctrlr->wrb_context[((psol->
879 dw[offsetof(struct amap_sol_cqe, cid) / 32] & 880 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
880 SOL_CID_MASK) >> 6)]; 881 SOL_CID_MASK) >> 6) -
881 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> 882 phba->fw_config.iscsi_cid_start];
883 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
882 dw[offsetof(struct amap_sol_cqe, wrb_index) / 884 dw[offsetof(struct amap_sol_cqe, wrb_index) /
883 32] & SOL_WRB_INDEX_MASK) >> 16)]; 885 32] & SOL_WRB_INDEX_MASK) >> 16)];
884 task = pwrb_handle->pio_handle; 886 task = pwrb_handle->pio_handle;
885 }
886 887
887 io_task = task->dd_data; 888 io_task = task->dd_data;
888 spin_lock(&phba->mgmt_sgl_lock); 889 spin_lock(&phba->mgmt_sgl_lock);
@@ -923,31 +924,23 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
923 struct iscsi_wrb *pwrb = NULL; 924 struct iscsi_wrb *pwrb = NULL;
924 struct hwi_controller *phwi_ctrlr; 925 struct hwi_controller *phwi_ctrlr;
925 struct iscsi_task *task; 926 struct iscsi_task *task;
926 struct sgl_handle *psgl_handle = NULL;
927 unsigned int type; 927 unsigned int type;
928 struct iscsi_conn *conn = beiscsi_conn->conn; 928 struct iscsi_conn *conn = beiscsi_conn->conn;
929 struct iscsi_session *session = conn->session; 929 struct iscsi_session *session = conn->session;
930 930
931 phwi_ctrlr = phba->phwi_ctrlr; 931 phwi_ctrlr = phba->phwi_ctrlr;
932 if (ring_mode) { 932 pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof
933 psgl_handle = phba->sgl_hndl_array[((psol->
934 dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
935 32] & SOL_ICD_INDEX_MASK) >> 6)];
936 task = psgl_handle->task;
937 type = psgl_handle->type;
938 } else {
939 pwrb_context = &phwi_ctrlr->
940 wrb_context[((psol->dw[offsetof
941 (struct amap_sol_cqe, cid) / 32] 933 (struct amap_sol_cqe, cid) / 32]
942 & SOL_CID_MASK) >> 6)]; 934 & SOL_CID_MASK) >> 6) -
943 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> 935 phba->fw_config.iscsi_cid_start];
936 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
944 dw[offsetof(struct amap_sol_cqe, wrb_index) / 937 dw[offsetof(struct amap_sol_cqe, wrb_index) /
945 32] & SOL_WRB_INDEX_MASK) >> 16)]; 938 32] & SOL_WRB_INDEX_MASK) >> 16)];
946 task = pwrb_handle->pio_handle; 939 task = pwrb_handle->pio_handle;
947 pwrb = pwrb_handle->pwrb; 940 pwrb = pwrb_handle->pwrb;
948 type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & 941 type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
949 WRB_TYPE_MASK) >> 28; 942 WRB_TYPE_MASK) >> 28;
950 } 943
951 spin_lock_bh(&session->lock); 944 spin_lock_bh(&session->lock);
952 switch (type) { 945 switch (type) {
953 case HWH_TYPE_IO: 946 case HWH_TYPE_IO:
@@ -978,15 +971,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
978 break; 971 break;
979 972
980 default: 973 default:
981 if (ring_mode) 974 shost_printk(KERN_WARNING, phba->shost,
982 shost_printk(KERN_WARNING, phba->shost,
983 "In hwi_complete_cmd, unknown type = %d"
984 "icd_index 0x%x CID 0x%x\n", type,
985 ((psol->dw[offsetof(struct amap_sol_cqe_ring,
986 icd_index) / 32] & SOL_ICD_INDEX_MASK) >> 6),
987 psgl_handle->cid);
988 else
989 shost_printk(KERN_WARNING, phba->shost,
990 "In hwi_complete_cmd, unknown type = %d" 975 "In hwi_complete_cmd, unknown type = %d"
991 "wrb_index 0x%x CID 0x%x\n", type, 976 "wrb_index 0x%x CID 0x%x\n", type,
992 ((psol->dw[offsetof(struct amap_iscsi_wrb, 977 ((psol->dw[offsetof(struct amap_iscsi_wrb,
@@ -1077,7 +1062,8 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
1077 1062
1078 WARN_ON(!pasync_handle); 1063 WARN_ON(!pasync_handle);
1079 1064
1080 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid; 1065 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid -
1066 phba->fw_config.iscsi_cid_start;
1081 pasync_handle->is_header = is_header; 1067 pasync_handle->is_header = is_header;
1082 pasync_handle->buffer_len = ((pdpdu_cqe-> 1068 pasync_handle->buffer_len = ((pdpdu_cqe->
1083 dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] 1069 dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
@@ -1327,9 +1313,10 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn,
1327 } 1313 }
1328 1314
1329 status = beiscsi_process_async_pdu(beiscsi_conn, phba, 1315 status = beiscsi_process_async_pdu(beiscsi_conn, phba,
1330 beiscsi_conn->beiscsi_conn_cid, 1316 (beiscsi_conn->beiscsi_conn_cid -
1331 phdr, hdr_len, pfirst_buffer, 1317 phba->fw_config.iscsi_cid_start),
1332 buf_len); 1318 phdr, hdr_len, pfirst_buffer,
1319 buf_len);
1333 1320
1334 if (status == 0) 1321 if (status == 0)
1335 hwi_free_async_msg(phba, cri); 1322 hwi_free_async_msg(phba, cri);
@@ -1422,6 +1409,48 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn,
1422 hwi_post_async_buffers(phba, pasync_handle->is_header); 1409 hwi_post_async_buffers(phba, pasync_handle->is_header);
1423} 1410}
1424 1411
1412static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
1413{
1414 struct be_queue_info *mcc_cq;
1415 struct be_mcc_compl *mcc_compl;
1416 unsigned int num_processed = 0;
1417
1418 mcc_cq = &phba->ctrl.mcc_obj.cq;
1419 mcc_compl = queue_tail_node(mcc_cq);
1420 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1421 while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
1422
1423 if (num_processed >= 32) {
1424 hwi_ring_cq_db(phba, mcc_cq->id,
1425 num_processed, 0, 0);
1426 num_processed = 0;
1427 }
1428 if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
1429 /* Interpret flags as an async trailer */
1430 if (is_link_state_evt(mcc_compl->flags))
1431 /* Interpret compl as a async link evt */
1432 beiscsi_async_link_state_process(phba,
1433 (struct be_async_event_link_state *) mcc_compl);
1434 else
1435 SE_DEBUG(DBG_LVL_1,
1436 " Unsupported Async Event, flags"
1437 " = 0x%08x \n", mcc_compl->flags);
1438 } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
1439 be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
1440 atomic_dec(&phba->ctrl.mcc_obj.q.used);
1441 }
1442
1443 mcc_compl->flags = 0;
1444 queue_tail_inc(mcc_cq);
1445 mcc_compl = queue_tail_node(mcc_cq);
1446 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1447 num_processed++;
1448 }
1449
1450 if (num_processed > 0)
1451 hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
1452
1453}
1425 1454
1426static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) 1455static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1427{ 1456{
@@ -1431,7 +1460,8 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1431 unsigned int num_processed = 0; 1460 unsigned int num_processed = 0;
1432 unsigned int tot_nump = 0; 1461 unsigned int tot_nump = 0;
1433 struct beiscsi_conn *beiscsi_conn; 1462 struct beiscsi_conn *beiscsi_conn;
1434 struct sgl_handle *psgl_handle = NULL; 1463 struct beiscsi_endpoint *beiscsi_ep;
1464 struct iscsi_endpoint *ep;
1435 struct beiscsi_hba *phba; 1465 struct beiscsi_hba *phba;
1436 1466
1437 cq = pbe_eq->cq; 1467 cq = pbe_eq->cq;
@@ -1442,32 +1472,13 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1442 CQE_VALID_MASK) { 1472 CQE_VALID_MASK) {
1443 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); 1473 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
1444 1474
1445 if (ring_mode) { 1475 ep = phba->ep_array[(u32) ((sol->
1446 psgl_handle = phba->sgl_hndl_array[((sol-> 1476 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
1447 dw[offsetof(struct amap_sol_cqe_ring, 1477 SOL_CID_MASK) >> 6) -
1448 icd_index) / 32] & SOL_ICD_INDEX_MASK) 1478 phba->fw_config.iscsi_cid_start];
1449 >> 6)];
1450 beiscsi_conn = phba->conn_table[psgl_handle->cid];
1451 if (!beiscsi_conn || !beiscsi_conn->ep) {
1452 shost_printk(KERN_WARNING, phba->shost,
1453 "Connection table empty for cid = %d\n",
1454 psgl_handle->cid);
1455 return 0;
1456 }
1457 1479
1458 } else { 1480 beiscsi_ep = ep->dd_data;
1459 beiscsi_conn = phba->conn_table[(u32) (sol-> 1481 beiscsi_conn = beiscsi_ep->conn;
1460 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
1461 SOL_CID_MASK) >> 6];
1462
1463 if (!beiscsi_conn || !beiscsi_conn->ep) {
1464 shost_printk(KERN_WARNING, phba->shost,
1465 "Connection table empty for cid = %d\n",
1466 (u32)(sol->dw[offsetof(struct amap_sol_cqe,
1467 cid) / 32] & SOL_CID_MASK) >> 6);
1468 return 0;
1469 }
1470 }
1471 1482
1472 if (num_processed >= 32) { 1483 if (num_processed >= 32) {
1473 hwi_ring_cq_db(phba, cq->id, 1484 hwi_ring_cq_db(phba, cq->id,
@@ -1511,21 +1522,13 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1511 case CMD_CXN_KILLED_ITT_INVALID: 1522 case CMD_CXN_KILLED_ITT_INVALID:
1512 case CMD_CXN_KILLED_SEQ_OUTOFORDER: 1523 case CMD_CXN_KILLED_SEQ_OUTOFORDER:
1513 case CMD_CXN_KILLED_INVALID_DATASN_RCVD: 1524 case CMD_CXN_KILLED_INVALID_DATASN_RCVD:
1514 if (ring_mode) { 1525 SE_DEBUG(DBG_LVL_1,
1515 SE_DEBUG(DBG_LVL_1,
1516 "CQ Error notification for cmd.. "
1517 "code %d cid 0x%x\n",
1518 sol->dw[offsetof(struct amap_sol_cqe, code) /
1519 32] & CQE_CODE_MASK, psgl_handle->cid);
1520 } else {
1521 SE_DEBUG(DBG_LVL_1,
1522 "CQ Error notification for cmd.. " 1526 "CQ Error notification for cmd.. "
1523 "code %d cid 0x%x\n", 1527 "code %d cid 0x%x\n",
1524 sol->dw[offsetof(struct amap_sol_cqe, code) / 1528 sol->dw[offsetof(struct amap_sol_cqe, code) /
1525 32] & CQE_CODE_MASK, 1529 32] & CQE_CODE_MASK,
1526 (sol->dw[offsetof(struct amap_sol_cqe, cid) / 1530 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1527 32] & SOL_CID_MASK)); 1531 32] & SOL_CID_MASK));
1528 }
1529 break; 1532 break;
1530 case UNSOL_DATA_DIGEST_ERROR_NOTIFY: 1533 case UNSOL_DATA_DIGEST_ERROR_NOTIFY:
1531 SE_DEBUG(DBG_LVL_1, 1534 SE_DEBUG(DBG_LVL_1,
@@ -1547,37 +1550,23 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1547 case CXN_KILLED_OVER_RUN_RESIDUAL: 1550 case CXN_KILLED_OVER_RUN_RESIDUAL:
1548 case CXN_KILLED_UNDER_RUN_RESIDUAL: 1551 case CXN_KILLED_UNDER_RUN_RESIDUAL:
1549 case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: 1552 case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
1550 if (ring_mode) { 1553 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
1551 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
1552 "0x%x...\n",
1553 sol->dw[offsetof(struct amap_sol_cqe, code) /
1554 32] & CQE_CODE_MASK, psgl_handle->cid);
1555 } else {
1556 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
1557 "0x%x...\n", 1554 "0x%x...\n",
1558 sol->dw[offsetof(struct amap_sol_cqe, code) / 1555 sol->dw[offsetof(struct amap_sol_cqe, code) /
1559 32] & CQE_CODE_MASK, 1556 32] & CQE_CODE_MASK,
1560 sol->dw[offsetof(struct amap_sol_cqe, cid) / 1557 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1561 32] & CQE_CID_MASK); 1558 32] & CQE_CID_MASK));
1562 }
1563 iscsi_conn_failure(beiscsi_conn->conn, 1559 iscsi_conn_failure(beiscsi_conn->conn,
1564 ISCSI_ERR_CONN_FAILED); 1560 ISCSI_ERR_CONN_FAILED);
1565 break; 1561 break;
1566 case CXN_KILLED_RST_SENT: 1562 case CXN_KILLED_RST_SENT:
1567 case CXN_KILLED_RST_RCVD: 1563 case CXN_KILLED_RST_RCVD:
1568 if (ring_mode) { 1564 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
1569 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
1570 "received/sent on CID 0x%x...\n",
1571 sol->dw[offsetof(struct amap_sol_cqe, code) /
1572 32] & CQE_CODE_MASK, psgl_handle->cid);
1573 } else {
1574 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
1575 "received/sent on CID 0x%x...\n", 1565 "received/sent on CID 0x%x...\n",
1576 sol->dw[offsetof(struct amap_sol_cqe, code) / 1566 sol->dw[offsetof(struct amap_sol_cqe, code) /
1577 32] & CQE_CODE_MASK, 1567 32] & CQE_CODE_MASK,
1578 sol->dw[offsetof(struct amap_sol_cqe, cid) / 1568 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1579 32] & CQE_CID_MASK); 1569 32] & CQE_CID_MASK));
1580 }
1581 iscsi_conn_failure(beiscsi_conn->conn, 1570 iscsi_conn_failure(beiscsi_conn->conn,
1582 ISCSI_ERR_CONN_FAILED); 1571 ISCSI_ERR_CONN_FAILED);
1583 break; 1572 break;
@@ -1586,8 +1575,8 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1586 "received on CID 0x%x...\n", 1575 "received on CID 0x%x...\n",
1587 sol->dw[offsetof(struct amap_sol_cqe, code) / 1576 sol->dw[offsetof(struct amap_sol_cqe, code) /
1588 32] & CQE_CODE_MASK, 1577 32] & CQE_CODE_MASK,
1589 sol->dw[offsetof(struct amap_sol_cqe, cid) / 1578 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1590 32] & CQE_CID_MASK); 1579 32] & CQE_CID_MASK));
1591 break; 1580 break;
1592 } 1581 }
1593 1582
@@ -1604,7 +1593,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1604 return tot_nump; 1593 return tot_nump;
1605} 1594}
1606 1595
1607static void beiscsi_process_all_cqs(struct work_struct *work) 1596void beiscsi_process_all_cqs(struct work_struct *work)
1608{ 1597{
1609 unsigned long flags; 1598 unsigned long flags;
1610 struct hwi_controller *phwi_ctrlr; 1599 struct hwi_controller *phwi_ctrlr;
@@ -1624,6 +1613,7 @@ static void beiscsi_process_all_cqs(struct work_struct *work)
1624 spin_lock_irqsave(&phba->isr_lock, flags); 1613 spin_lock_irqsave(&phba->isr_lock, flags);
1625 phba->todo_mcc_cq = 0; 1614 phba->todo_mcc_cq = 0;
1626 spin_unlock_irqrestore(&phba->isr_lock, flags); 1615 spin_unlock_irqrestore(&phba->isr_lock, flags);
1616 beiscsi_process_mcc_isr(phba);
1627 } 1617 }
1628 1618
1629 if (phba->todo_cq) { 1619 if (phba->todo_cq) {
@@ -1668,7 +1658,8 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1668 io_task->bhs_pa.u.a32.address_hi); 1658 io_task->bhs_pa.u.a32.address_hi);
1669 1659
1670 l_sg = sg; 1660 l_sg = sg;
1671 for (index = 0; (index < num_sg) && (index < 2); index++, sg_next(sg)) { 1661 for (index = 0; (index < num_sg) && (index < 2); index++,
1662 sg = sg_next(sg)) {
1672 if (index == 0) { 1663 if (index == 0) {
1673 sg_len = sg_dma_len(sg); 1664 sg_len = sg_dma_len(sg);
1674 addr = (u64) sg_dma_address(sg); 1665 addr = (u64) sg_dma_address(sg);
@@ -1679,11 +1670,7 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1679 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, 1670 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
1680 sg_len); 1671 sg_len);
1681 sge_len = sg_len; 1672 sge_len = sg_len;
1682 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1683 1);
1684 } else { 1673 } else {
1685 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1686 0);
1687 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset, 1674 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset,
1688 pwrb, sge_len); 1675 pwrb, sge_len);
1689 sg_len = sg_dma_len(sg); 1676 sg_len = sg_dma_len(sg);
@@ -1706,13 +1693,27 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1706 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, 1693 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
1707 io_task->bhs_pa.u.a32.address_lo); 1694 io_task->bhs_pa.u.a32.address_lo);
1708 1695
1709 if (num_sg == 2) 1696 if (num_sg == 1) {
1710 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, 1); 1697 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1698 1);
1699 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
1700 0);
1701 } else if (num_sg == 2) {
1702 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1703 0);
1704 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
1705 1);
1706 } else {
1707 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1708 0);
1709 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
1710 0);
1711 }
1711 sg = l_sg; 1712 sg = l_sg;
1712 psgl++; 1713 psgl++;
1713 psgl++; 1714 psgl++;
1714 offset = 0; 1715 offset = 0;
1715 for (index = 0; index < num_sg; index++, sg_next(sg), psgl++) { 1716 for (index = 0; index < num_sg; index++, sg = sg_next(sg), psgl++) {
1716 sg_len = sg_dma_len(sg); 1717 sg_len = sg_dma_len(sg);
1717 addr = (u64) sg_dma_address(sg); 1718 addr = (u64) sg_dma_address(sg);
1718 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, 1719 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
@@ -2048,10 +2049,9 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
2048 } 2049 }
2049 idx = 0; 2050 idx = 0;
2050 pwrb = mem_descr_wrb->mem_array[idx].virtual_address; 2051 pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
2051 num_cxn_wrb = 2052 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
2052 ((mem_descr_wrb->mem_array[idx].size) / (sizeof(struct iscsi_wrb)) * 2053 ((sizeof(struct iscsi_wrb) *
2053 phba->params.wrbs_per_cxn); 2054 phba->params.wrbs_per_cxn));
2054
2055 for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { 2055 for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
2056 pwrb_context = &phwi_ctrlr->wrb_context[index]; 2056 pwrb_context = &phwi_ctrlr->wrb_context[index];
2057 if (num_cxn_wrb) { 2057 if (num_cxn_wrb) {
@@ -2064,9 +2064,9 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
2064 } else { 2064 } else {
2065 idx++; 2065 idx++;
2066 pwrb = mem_descr_wrb->mem_array[idx].virtual_address; 2066 pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
2067 num_cxn_wrb = ((mem_descr_wrb->mem_array[idx].size) / 2067 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
2068 (sizeof(struct iscsi_wrb)) * 2068 ((sizeof(struct iscsi_wrb) *
2069 phba->params.wrbs_per_cxn); 2069 phba->params.wrbs_per_cxn));
2070 for (j = 0; j < phba->params.wrbs_per_cxn; j++) { 2070 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
2071 pwrb_handle = pwrb_context->pwrb_handle_base[j]; 2071 pwrb_handle = pwrb_context->pwrb_handle_base[j];
2072 pwrb_handle->pwrb = pwrb; 2072 pwrb_handle->pwrb = pwrb;
@@ -2383,7 +2383,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba,
2383 &paddr); 2383 &paddr);
2384 if (!cq_vaddress) 2384 if (!cq_vaddress)
2385 goto create_cq_error; 2385 goto create_cq_error;
2386 ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2, 2386 ret = be_fill_queue(cq, phba->params.num_cq_entries,
2387 sizeof(struct sol_cqe), cq_vaddress); 2387 sizeof(struct sol_cqe), cq_vaddress);
2388 if (ret) { 2388 if (ret) {
2389 shost_printk(KERN_ERR, phba->shost, 2389 shost_printk(KERN_ERR, phba->shost,
@@ -2634,7 +2634,8 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
2634 "wrbq create failed."); 2634 "wrbq create failed.");
2635 return status; 2635 return status;
2636 } 2636 }
2637 phwi_ctrlr->wrb_context[i].cid = phwi_context->be_wrbq[i].id; 2637 phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i].
2638 id;
2638 } 2639 }
2639 kfree(pwrb_arr); 2640 kfree(pwrb_arr);
2640 return 0; 2641 return 0;
@@ -2803,17 +2804,6 @@ static int hwi_init_port(struct beiscsi_hba *phba)
2803 goto error; 2804 goto error;
2804 } 2805 }
2805 2806
2806 if (phba->fw_config.iscsi_features == 0x1)
2807 ring_mode = 1;
2808 else
2809 ring_mode = 0;
2810 status = mgmt_get_fw_config(ctrl, phba);
2811 if (status != 0) {
2812 shost_printk(KERN_ERR, phba->shost,
2813 "Error getting fw config\n");
2814 goto error;
2815 }
2816
2817 status = beiscsi_create_cqs(phba, phwi_context); 2807 status = beiscsi_create_cqs(phba, phwi_context);
2818 if (status != 0) { 2808 if (status != 0) {
2819 shost_printk(KERN_ERR, phba->shost, "CQ not created\n"); 2809 shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
@@ -2941,17 +2931,6 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
2941 phba->io_sgl_hndl_avbl = 0; 2931 phba->io_sgl_hndl_avbl = 0;
2942 phba->eh_sgl_hndl_avbl = 0; 2932 phba->eh_sgl_hndl_avbl = 0;
2943 2933
2944 if (ring_mode) {
2945 phba->sgl_hndl_array = kzalloc(sizeof(struct sgl_handle *) *
2946 phba->params.icds_per_ctrl,
2947 GFP_KERNEL);
2948 if (!phba->sgl_hndl_array) {
2949 shost_printk(KERN_ERR, phba->shost,
2950 "Mem Alloc Failed. Failing to load\n");
2951 return -ENOMEM;
2952 }
2953 }
2954
2955 mem_descr_sglh = phba->init_mem; 2934 mem_descr_sglh = phba->init_mem;
2956 mem_descr_sglh += HWI_MEM_SGLH; 2935 mem_descr_sglh += HWI_MEM_SGLH;
2957 if (1 == mem_descr_sglh->num_elements) { 2936 if (1 == mem_descr_sglh->num_elements) {
@@ -2959,8 +2938,6 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
2959 phba->params.ios_per_ctrl, 2938 phba->params.ios_per_ctrl,
2960 GFP_KERNEL); 2939 GFP_KERNEL);
2961 if (!phba->io_sgl_hndl_base) { 2940 if (!phba->io_sgl_hndl_base) {
2962 if (ring_mode)
2963 kfree(phba->sgl_hndl_array);
2964 shost_printk(KERN_ERR, phba->shost, 2941 shost_printk(KERN_ERR, phba->shost,
2965 "Mem Alloc Failed. Failing to load\n"); 2942 "Mem Alloc Failed. Failing to load\n");
2966 return -ENOMEM; 2943 return -ENOMEM;
@@ -3032,7 +3009,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
3032 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); 3009 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0);
3033 pfrag += phba->params.num_sge_per_io; 3010 pfrag += phba->params.num_sge_per_io;
3034 psgl_handle->sgl_index = 3011 psgl_handle->sgl_index =
3035 phba->fw_config.iscsi_cid_start + arr_index++; 3012 phba->fw_config.iscsi_icd_start + arr_index++;
3036 } 3013 }
3037 idx++; 3014 idx++;
3038 } 3015 }
@@ -3047,7 +3024,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
3047{ 3024{
3048 int i, new_cid; 3025 int i, new_cid;
3049 3026
3050 phba->cid_array = kmalloc(sizeof(void *) * phba->params.cxns_per_ctrl, 3027 phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
3051 GFP_KERNEL); 3028 GFP_KERNEL);
3052 if (!phba->cid_array) { 3029 if (!phba->cid_array) {
3053 shost_printk(KERN_ERR, phba->shost, 3030 shost_printk(KERN_ERR, phba->shost,
@@ -3055,7 +3032,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
3055 "hba_setup_cid_tbls\n"); 3032 "hba_setup_cid_tbls\n");
3056 return -ENOMEM; 3033 return -ENOMEM;
3057 } 3034 }
3058 phba->ep_array = kmalloc(sizeof(struct iscsi_endpoint *) * 3035 phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) *
3059 phba->params.cxns_per_ctrl * 2, GFP_KERNEL); 3036 phba->params.cxns_per_ctrl * 2, GFP_KERNEL);
3060 if (!phba->ep_array) { 3037 if (!phba->ep_array) {
3061 shost_printk(KERN_ERR, phba->shost, 3038 shost_printk(KERN_ERR, phba->shost,
@@ -3064,7 +3041,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
3064 kfree(phba->cid_array); 3041 kfree(phba->cid_array);
3065 return -ENOMEM; 3042 return -ENOMEM;
3066 } 3043 }
3067 new_cid = phba->fw_config.iscsi_icd_start; 3044 new_cid = phba->fw_config.iscsi_cid_start;
3068 for (i = 0; i < phba->params.cxns_per_ctrl; i++) { 3045 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
3069 phba->cid_array[i] = new_cid; 3046 phba->cid_array[i] = new_cid;
3070 new_cid += 2; 3047 new_cid += 2;
@@ -3145,8 +3122,6 @@ static int beiscsi_init_port(struct beiscsi_hba *phba)
3145 if (hba_setup_cid_tbls(phba)) { 3122 if (hba_setup_cid_tbls(phba)) {
3146 shost_printk(KERN_ERR, phba->shost, 3123 shost_printk(KERN_ERR, phba->shost,
3147 "Failed in hba_setup_cid_tbls\n"); 3124 "Failed in hba_setup_cid_tbls\n");
3148 if (ring_mode)
3149 kfree(phba->sgl_hndl_array);
3150 kfree(phba->io_sgl_hndl_base); 3125 kfree(phba->io_sgl_hndl_base);
3151 kfree(phba->eh_sgl_hndl_base); 3126 kfree(phba->eh_sgl_hndl_base);
3152 goto do_cleanup_ctrlr; 3127 goto do_cleanup_ctrlr;
@@ -3166,6 +3141,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
3166 struct be_queue_info *eq; 3141 struct be_queue_info *eq;
3167 struct be_eq_entry *eqe = NULL; 3142 struct be_eq_entry *eqe = NULL;
3168 int i, eq_msix; 3143 int i, eq_msix;
3144 unsigned int num_processed;
3169 3145
3170 phwi_ctrlr = phba->phwi_ctrlr; 3146 phwi_ctrlr = phba->phwi_ctrlr;
3171 phwi_context = phwi_ctrlr->phwi_ctxt; 3147 phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -3177,13 +3153,17 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
3177 for (i = 0; i < (phba->num_cpus + eq_msix); i++) { 3153 for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
3178 eq = &phwi_context->be_eq[i].q; 3154 eq = &phwi_context->be_eq[i].q;
3179 eqe = queue_tail_node(eq); 3155 eqe = queue_tail_node(eq);
3180 3156 num_processed = 0;
3181 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] 3157 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
3182 & EQE_VALID_MASK) { 3158 & EQE_VALID_MASK) {
3183 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); 3159 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
3184 queue_tail_inc(eq); 3160 queue_tail_inc(eq);
3185 eqe = queue_tail_node(eq); 3161 eqe = queue_tail_node(eq);
3162 num_processed++;
3186 } 3163 }
3164
3165 if (num_processed)
3166 hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1);
3187 } 3167 }
3188} 3168}
3189 3169
@@ -3195,10 +3175,9 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
3195 if (mgmt_status) 3175 if (mgmt_status)
3196 shost_printk(KERN_WARNING, phba->shost, 3176 shost_printk(KERN_WARNING, phba->shost,
3197 "mgmt_epfw_cleanup FAILED \n"); 3177 "mgmt_epfw_cleanup FAILED \n");
3198 hwi_cleanup(phba); 3178
3199 hwi_purge_eq(phba); 3179 hwi_purge_eq(phba);
3200 if (ring_mode) 3180 hwi_cleanup(phba);
3201 kfree(phba->sgl_hndl_array);
3202 kfree(phba->io_sgl_hndl_base); 3181 kfree(phba->io_sgl_hndl_base);
3203 kfree(phba->eh_sgl_hndl_base); 3182 kfree(phba->eh_sgl_hndl_base);
3204 kfree(phba->cid_array); 3183 kfree(phba->cid_array);
@@ -3219,7 +3198,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
3219 * We can always use 0 here because it is reserved by libiscsi for 3198 * We can always use 0 here because it is reserved by libiscsi for
3220 * login/startup related tasks. 3199 * login/startup related tasks.
3221 */ 3200 */
3222 pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid, 0); 3201 pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid -
3202 phba->fw_config.iscsi_cid_start));
3223 pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb; 3203 pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb;
3224 memset(pwrb, 0, sizeof(*pwrb)); 3204 memset(pwrb, 0, sizeof(*pwrb));
3225 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 3205 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
@@ -3283,8 +3263,7 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
3283 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); 3263 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb));
3284 3264
3285 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; 3265 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
3286 if (!ring_mode) 3266 doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
3287 doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
3288 << DB_DEF_PDU_WRB_INDEX_SHIFT; 3267 << DB_DEF_PDU_WRB_INDEX_SHIFT;
3289 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; 3268 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
3290 3269
@@ -3328,8 +3307,9 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
3328 io_task->bhs_pa.u.a64.address = paddr; 3307 io_task->bhs_pa.u.a64.address = paddr;
3329 io_task->libiscsi_itt = (itt_t)task->itt; 3308 io_task->libiscsi_itt = (itt_t)task->itt;
3330 io_task->pwrb_handle = alloc_wrb_handle(phba, 3309 io_task->pwrb_handle = alloc_wrb_handle(phba,
3331 beiscsi_conn->beiscsi_conn_cid, 3310 beiscsi_conn->beiscsi_conn_cid -
3332 task->itt); 3311 phba->fw_config.iscsi_cid_start
3312 );
3333 io_task->conn = beiscsi_conn; 3313 io_task->conn = beiscsi_conn;
3334 3314
3335 task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; 3315 task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
@@ -3343,7 +3323,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
3343 goto free_hndls; 3323 goto free_hndls;
3344 } else { 3324 } else {
3345 io_task->scsi_cmnd = NULL; 3325 io_task->scsi_cmnd = NULL;
3346 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { 3326 if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
3347 if (!beiscsi_conn->login_in_progress) { 3327 if (!beiscsi_conn->login_in_progress) {
3348 spin_lock(&phba->mgmt_sgl_lock); 3328 spin_lock(&phba->mgmt_sgl_lock);
3349 io_task->psgl_handle = (struct sgl_handle *) 3329 io_task->psgl_handle = (struct sgl_handle *)
@@ -3370,21 +3350,16 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
3370 itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> 3350 itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
3371 wrb_index << 16) | (unsigned int) 3351 wrb_index << 16) | (unsigned int)
3372 (io_task->psgl_handle->sgl_index)); 3352 (io_task->psgl_handle->sgl_index));
3373 if (ring_mode) { 3353 io_task->pwrb_handle->pio_handle = task;
3374 phba->sgl_hndl_array[io_task->psgl_handle->sgl_index -
3375 phba->fw_config.iscsi_cid_start] =
3376 io_task->psgl_handle;
3377 io_task->psgl_handle->task = task;
3378 io_task->psgl_handle->cid = beiscsi_conn->beiscsi_conn_cid;
3379 } else
3380 io_task->pwrb_handle->pio_handle = task;
3381 3354
3382 io_task->cmd_bhs->iscsi_hdr.itt = itt; 3355 io_task->cmd_bhs->iscsi_hdr.itt = itt;
3383 return 0; 3356 return 0;
3384 3357
3385free_hndls: 3358free_hndls:
3386 phwi_ctrlr = phba->phwi_ctrlr; 3359 phwi_ctrlr = phba->phwi_ctrlr;
3387 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid]; 3360 pwrb_context = &phwi_ctrlr->wrb_context[
3361 beiscsi_conn->beiscsi_conn_cid -
3362 phba->fw_config.iscsi_cid_start];
3388 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); 3363 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
3389 io_task->pwrb_handle = NULL; 3364 io_task->pwrb_handle = NULL;
3390 pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, 3365 pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
@@ -3404,7 +3379,8 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
3404 struct hwi_controller *phwi_ctrlr; 3379 struct hwi_controller *phwi_ctrlr;
3405 3380
3406 phwi_ctrlr = phba->phwi_ctrlr; 3381 phwi_ctrlr = phba->phwi_ctrlr;
3407 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid]; 3382 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid
3383 - phba->fw_config.iscsi_cid_start];
3408 if (io_task->pwrb_handle) { 3384 if (io_task->pwrb_handle) {
3409 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); 3385 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
3410 io_task->pwrb_handle = NULL; 3386 io_task->pwrb_handle = NULL;
@@ -3460,18 +3436,12 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3460 ISCSI_OPCODE_SCSI_DATA_OUT); 3436 ISCSI_OPCODE_SCSI_DATA_OUT);
3461 AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, 3437 AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
3462 &io_task->cmd_bhs->iscsi_data_pdu, 1); 3438 &io_task->cmd_bhs->iscsi_data_pdu, 1);
3463 if (ring_mode) 3439 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3464 io_task->psgl_handle->type = INI_WR_CMD; 3440 INI_WR_CMD);
3465 else
3466 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3467 INI_WR_CMD);
3468 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); 3441 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
3469 } else { 3442 } else {
3470 if (ring_mode) 3443 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3471 io_task->psgl_handle->type = INI_RD_CMD; 3444 INI_RD_CMD);
3472 else
3473 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3474 INI_RD_CMD);
3475 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); 3445 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
3476 } 3446 }
3477 memcpy(&io_task->cmd_bhs->iscsi_data_pdu. 3447 memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
@@ -3496,8 +3466,7 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3496 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); 3466 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
3497 3467
3498 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; 3468 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
3499 if (!ring_mode) 3469 doorbell |= (io_task->pwrb_handle->wrb_index &
3500 doorbell |= (io_task->pwrb_handle->wrb_index &
3501 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; 3470 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
3502 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; 3471 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
3503 3472
@@ -3519,49 +3488,46 @@ static int beiscsi_mtask(struct iscsi_task *task)
3519 unsigned int doorbell = 0; 3488 unsigned int doorbell = 0;
3520 unsigned int i, cid; 3489 unsigned int i, cid;
3521 struct iscsi_task *aborted_task; 3490 struct iscsi_task *aborted_task;
3491 unsigned int tag;
3522 3492
3523 cid = beiscsi_conn->beiscsi_conn_cid; 3493 cid = beiscsi_conn->beiscsi_conn_cid;
3524 pwrb = io_task->pwrb_handle->pwrb; 3494 pwrb = io_task->pwrb_handle->pwrb;
3495 memset(pwrb, 0, sizeof(*pwrb));
3525 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 3496 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
3526 be32_to_cpu(task->cmdsn)); 3497 be32_to_cpu(task->cmdsn));
3527 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, 3498 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb,
3528 io_task->pwrb_handle->wrb_index); 3499 io_task->pwrb_handle->wrb_index);
3529 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, 3500 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
3530 io_task->psgl_handle->sgl_index); 3501 io_task->psgl_handle->sgl_index);
3531
3532 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { 3502 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
3533 case ISCSI_OP_LOGIN: 3503 case ISCSI_OP_LOGIN:
3534 if (ring_mode) 3504 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3535 io_task->psgl_handle->type = TGT_DM_CMD; 3505 TGT_DM_CMD);
3536 else
3537 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3538 TGT_DM_CMD);
3539 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3506 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3540 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); 3507 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
3541 hwi_write_buffer(pwrb, task); 3508 hwi_write_buffer(pwrb, task);
3542 break; 3509 break;
3543 case ISCSI_OP_NOOP_OUT: 3510 case ISCSI_OP_NOOP_OUT:
3544 if (ring_mode) 3511 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3545 io_task->psgl_handle->type = INI_RD_CMD; 3512 INI_RD_CMD);
3513 if (task->hdr->ttt == ISCSI_RESERVED_TAG)
3514 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3546 else 3515 else
3547 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3516 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1);
3548 INI_RD_CMD);
3549 hwi_write_buffer(pwrb, task); 3517 hwi_write_buffer(pwrb, task);
3550 break; 3518 break;
3551 case ISCSI_OP_TEXT: 3519 case ISCSI_OP_TEXT:
3552 if (ring_mode) 3520 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3553 io_task->psgl_handle->type = INI_WR_CMD; 3521 TGT_DM_CMD);
3554 else 3522 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3555 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3556 INI_WR_CMD);
3557 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
3558 hwi_write_buffer(pwrb, task); 3523 hwi_write_buffer(pwrb, task);
3559 break; 3524 break;
3560 case ISCSI_OP_SCSI_TMFUNC: 3525 case ISCSI_OP_SCSI_TMFUNC:
3561 session = conn->session; 3526 session = conn->session;
3562 i = ((struct iscsi_tm *)task->hdr)->rtt; 3527 i = ((struct iscsi_tm *)task->hdr)->rtt;
3563 phwi_ctrlr = phba->phwi_ctrlr; 3528 phwi_ctrlr = phba->phwi_ctrlr;
3564 pwrb_context = &phwi_ctrlr->wrb_context[cid]; 3529 pwrb_context = &phwi_ctrlr->wrb_context[cid -
3530 phba->fw_config.iscsi_cid_start];
3565 pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i) 3531 pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
3566 >> 16]; 3532 >> 16];
3567 aborted_task = pwrb_handle->pio_handle; 3533 aborted_task = pwrb_handle->pio_handle;
@@ -3572,22 +3538,25 @@ static int beiscsi_mtask(struct iscsi_task *task)
3572 if (!aborted_io_task->scsi_cmnd) 3538 if (!aborted_io_task->scsi_cmnd)
3573 return 0; 3539 return 0;
3574 3540
3575 mgmt_invalidate_icds(phba, 3541 tag = mgmt_invalidate_icds(phba,
3576 aborted_io_task->psgl_handle->sgl_index, 3542 aborted_io_task->psgl_handle->sgl_index,
3577 cid); 3543 cid);
3578 if (ring_mode) 3544 if (!tag) {
3579 io_task->psgl_handle->type = INI_TMF_CMD; 3545 shost_printk(KERN_WARNING, phba->shost,
3580 else 3546 "mgmt_invalidate_icds could not be"
3581 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3547 " submitted\n");
3582 INI_TMF_CMD); 3548 } else {
3549 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
3550 phba->ctrl.mcc_numtag[tag]);
3551 free_mcc_tag(&phba->ctrl, tag);
3552 }
3553 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3554 INI_TMF_CMD);
3583 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3555 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3584 hwi_write_buffer(pwrb, task); 3556 hwi_write_buffer(pwrb, task);
3585 break; 3557 break;
3586 case ISCSI_OP_LOGOUT: 3558 case ISCSI_OP_LOGOUT:
3587 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3559 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3588 if (ring_mode)
3589 io_task->psgl_handle->type = HWH_TYPE_LOGOUT;
3590 else
3591 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3560 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3592 HWH_TYPE_LOGOUT); 3561 HWH_TYPE_LOGOUT);
3593 hwi_write_buffer(pwrb, task); 3562 hwi_write_buffer(pwrb, task);
@@ -3600,14 +3569,13 @@ static int beiscsi_mtask(struct iscsi_task *task)
3600 } 3569 }
3601 3570
3602 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, 3571 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb,
3603 be32_to_cpu(task->data_count)); 3572 task->data_count);
3604 AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, 3573 AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
3605 io_task->pwrb_handle->nxt_wrb_index); 3574 io_task->pwrb_handle->nxt_wrb_index);
3606 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); 3575 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
3607 3576
3608 doorbell |= cid & DB_WRB_POST_CID_MASK; 3577 doorbell |= cid & DB_WRB_POST_CID_MASK;
3609 if (!ring_mode) 3578 doorbell |= (io_task->pwrb_handle->wrb_index &
3610 doorbell |= (io_task->pwrb_handle->wrb_index &
3611 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; 3579 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
3612 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; 3580 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
3613 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); 3581 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -3649,7 +3617,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
3649 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); 3617 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
3650} 3618}
3651 3619
3652
3653static void beiscsi_remove(struct pci_dev *pcidev) 3620static void beiscsi_remove(struct pci_dev *pcidev)
3654{ 3621{
3655 struct beiscsi_hba *phba = NULL; 3622 struct beiscsi_hba *phba = NULL;
@@ -3734,7 +3701,20 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3734 } 3701 }
3735 SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba); 3702 SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
3736 3703
3737 pci_set_drvdata(pcidev, phba); 3704 switch (pcidev->device) {
3705 case BE_DEVICE_ID1:
3706 case OC_DEVICE_ID1:
3707 case OC_DEVICE_ID2:
3708 phba->generation = BE_GEN2;
3709 break;
3710 case BE_DEVICE_ID2:
3711 case OC_DEVICE_ID3:
3712 phba->generation = BE_GEN3;
3713 break;
3714 default:
3715 phba->generation = 0;
3716 }
3717
3738 if (enable_msix) 3718 if (enable_msix)
3739 num_cpus = find_num_cpus(); 3719 num_cpus = find_num_cpus();
3740 else 3720 else
@@ -3754,7 +3734,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3754 spin_lock_init(&phba->io_sgl_lock); 3734 spin_lock_init(&phba->io_sgl_lock);
3755 spin_lock_init(&phba->mgmt_sgl_lock); 3735 spin_lock_init(&phba->mgmt_sgl_lock);
3756 spin_lock_init(&phba->isr_lock); 3736 spin_lock_init(&phba->isr_lock);
3737 ret = mgmt_get_fw_config(&phba->ctrl, phba);
3738 if (ret != 0) {
3739 shost_printk(KERN_ERR, phba->shost,
3740 "Error getting fw config\n");
3741 goto free_port;
3742 }
3743 phba->shost->max_id = phba->fw_config.iscsi_cid_count;
3757 beiscsi_get_params(phba); 3744 beiscsi_get_params(phba);
3745 phba->shost->can_queue = phba->params.ios_per_ctrl;
3758 ret = beiscsi_init_port(phba); 3746 ret = beiscsi_init_port(phba);
3759 if (ret < 0) { 3747 if (ret < 0) {
3760 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" 3748 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3762,6 +3750,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3762 goto free_port; 3750 goto free_port;
3763 } 3751 }
3764 3752
3753 for (i = 0; i < MAX_MCC_CMD ; i++) {
3754 init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
3755 phba->ctrl.mcc_tag[i] = i + 1;
3756 phba->ctrl.mcc_numtag[i + 1] = 0;
3757 phba->ctrl.mcc_tag_available++;
3758 }
3759
3760 phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
3761
3765 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", 3762 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
3766 phba->shost->host_no); 3763 phba->shost->host_no);
3767 phba->wq = create_workqueue(phba->wq_name); 3764 phba->wq = create_workqueue(phba->wq_name);
@@ -3836,7 +3833,7 @@ disable_pci:
3836struct iscsi_transport beiscsi_iscsi_transport = { 3833struct iscsi_transport beiscsi_iscsi_transport = {
3837 .owner = THIS_MODULE, 3834 .owner = THIS_MODULE,
3838 .name = DRV_NAME, 3835 .name = DRV_NAME,
3839 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | 3836 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO |
3840 CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD, 3837 CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD,
3841 .param_mask = ISCSI_MAX_RECV_DLENGTH | 3838 .param_mask = ISCSI_MAX_RECV_DLENGTH |
3842 ISCSI_MAX_XMIT_DLENGTH | 3839 ISCSI_MAX_XMIT_DLENGTH |
@@ -3859,7 +3856,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
3859 ISCSI_USERNAME | ISCSI_PASSWORD | 3856 ISCSI_USERNAME | ISCSI_PASSWORD |
3860 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | 3857 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
3861 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | 3858 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
3862 ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | 3859 ISCSI_LU_RESET_TMO |
3863 ISCSI_PING_TMO | ISCSI_RECV_TMO | 3860 ISCSI_PING_TMO | ISCSI_RECV_TMO |
3864 ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, 3861 ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
3865 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | 3862 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
@@ -3905,7 +3902,7 @@ static int __init beiscsi_module_init(void)
3905 SE_DEBUG(DBG_LVL_1, 3902 SE_DEBUG(DBG_LVL_1,
3906 "beiscsi_module_init - Unable to register beiscsi" 3903 "beiscsi_module_init - Unable to register beiscsi"
3907 "transport.\n"); 3904 "transport.\n");
3908 ret = -ENOMEM; 3905 return -ENOMEM;
3909 } 3906 }
3910 SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n", 3907 SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n",
3911 &beiscsi_iscsi_transport); 3908 &beiscsi_iscsi_transport);
@@ -3917,7 +3914,6 @@ static int __init beiscsi_module_init(void)
3917 "beiscsi pci driver.\n"); 3914 "beiscsi pci driver.\n");
3918 goto unregister_iscsi_transport; 3915 goto unregister_iscsi_transport;
3919 } 3916 }
3920 ring_mode = 0;
3921 return 0; 3917 return 0;
3922 3918
3923unregister_iscsi_transport: 3919unregister_iscsi_transport:
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 25e6b208b771..c53a80ab796c 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -40,31 +40,29 @@
40#define DRV_DESC BE_NAME " " "Driver" 40#define DRV_DESC BE_NAME " " "Driver"
41 41
42#define BE_VENDOR_ID 0x19A2 42#define BE_VENDOR_ID 0x19A2
43/* DEVICE ID's for BE2 */
43#define BE_DEVICE_ID1 0x212 44#define BE_DEVICE_ID1 0x212
44#define OC_DEVICE_ID1 0x702 45#define OC_DEVICE_ID1 0x702
45#define OC_DEVICE_ID2 0x703 46#define OC_DEVICE_ID2 0x703
47
48/* DEVICE ID's for BE3 */
49#define BE_DEVICE_ID2 0x222
46#define OC_DEVICE_ID3 0x712 50#define OC_DEVICE_ID3 0x712
47#define OC_DEVICE_ID4 0x222
48 51
49#define BE2_MAX_SESSIONS 64 52#define BE2_IO_DEPTH 1024
53#define BE2_MAX_SESSIONS 256
50#define BE2_CMDS_PER_CXN 128 54#define BE2_CMDS_PER_CXN 128
51#define BE2_LOGOUTS BE2_MAX_SESSIONS
52#define BE2_TMFS 16 55#define BE2_TMFS 16
53#define BE2_NOPOUT_REQ 16 56#define BE2_NOPOUT_REQ 16
54#define BE2_ASYNCPDUS BE2_MAX_SESSIONS
55#define BE2_MAX_ICDS 2048
56#define BE2_SGE 32 57#define BE2_SGE 32
57#define BE2_DEFPDU_HDR_SZ 64 58#define BE2_DEFPDU_HDR_SZ 64
58#define BE2_DEFPDU_DATA_SZ 8192 59#define BE2_DEFPDU_DATA_SZ 8192
59#define BE2_IO_DEPTH \
60 (BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ))
61 60
62#define MAX_CPUS 31 61#define MAX_CPUS 31
63#define BEISCSI_SGLIST_ELEMENTS BE2_SGE 62#define BEISCSI_SGLIST_ELEMENTS 30
64 63
65#define BEISCSI_MAX_CMNDS 1024 /* Max IO's per Ctrlr sht->can_queue */
66#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ 64#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
67#define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ 65#define BEISCSI_MAX_SECTORS 256 /* scsi_host->max_sectors */
68 66
69#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ 67#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
70#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ 68#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */
@@ -330,6 +328,7 @@ struct beiscsi_hba {
330 struct workqueue_struct *wq; /* The actuak work queue */ 328 struct workqueue_struct *wq; /* The actuak work queue */
331 struct work_struct work_cqs; /* The work being queued */ 329 struct work_struct work_cqs; /* The work being queued */
332 struct be_ctrl_info ctrl; 330 struct be_ctrl_info ctrl;
331 unsigned int generation;
333}; 332};
334 333
335struct beiscsi_session { 334struct beiscsi_session {
@@ -656,11 +655,12 @@ struct amap_iscsi_wrb {
656 655
657} __packed; 656} __packed;
658 657
659struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, 658struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
660 int index);
661void 659void
662free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); 660free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
663 661
662void beiscsi_process_all_cqs(struct work_struct *work);
663
664struct pdu_nop_out { 664struct pdu_nop_out {
665 u32 dw[12]; 665 u32 dw[12];
666}; 666};
@@ -802,7 +802,6 @@ struct hwi_controller {
802 struct be_ring default_pdu_hdr; 802 struct be_ring default_pdu_hdr;
803 struct be_ring default_pdu_data; 803 struct be_ring default_pdu_data;
804 struct hwi_context_memory *phwi_ctxt; 804 struct hwi_context_memory *phwi_ctxt;
805 unsigned short cq_errors[CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN];
806}; 805};
807 806
808enum hwh_type_enum { 807enum hwh_type_enum {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 79c2bd525a84..317bcd042ced 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -48,6 +48,14 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
48 pfw_cfg->ulp[0].sq_base; 48 pfw_cfg->ulp[0].sq_base;
49 phba->fw_config.iscsi_cid_count = 49 phba->fw_config.iscsi_cid_count =
50 pfw_cfg->ulp[0].sq_count; 50 pfw_cfg->ulp[0].sq_count;
51 if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
52 SE_DEBUG(DBG_LVL_8,
53 "FW reported MAX CXNS as %d \t"
54 "Max Supported = %d.\n",
55 phba->fw_config.iscsi_cid_count,
56 BE2_MAX_SESSIONS);
57 phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
58 }
51 } else { 59 } else {
52 shost_printk(KERN_WARNING, phba->shost, 60 shost_printk(KERN_WARNING, phba->shost,
53 "Failed in mgmt_get_fw_config \n"); 61 "Failed in mgmt_get_fw_config \n");
@@ -77,6 +85,7 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
77 } 85 }
78 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes); 86 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
79 req = nonemb_cmd.va; 87 req = nonemb_cmd.va;
88 memset(req, 0, sizeof(*req));
80 spin_lock(&ctrl->mbox_lock); 89 spin_lock(&ctrl->mbox_lock);
81 memset(wrb, 0, sizeof(*wrb)); 90 memset(wrb, 0, sizeof(*wrb));
82 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 91 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
@@ -140,10 +149,17 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
140{ 149{
141 struct be_dma_mem nonemb_cmd; 150 struct be_dma_mem nonemb_cmd;
142 struct be_ctrl_info *ctrl = &phba->ctrl; 151 struct be_ctrl_info *ctrl = &phba->ctrl;
143 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 152 struct be_mcc_wrb *wrb;
144 struct be_sge *sge = nonembedded_sgl(wrb); 153 struct be_sge *sge;
145 struct invalidate_commands_params_in *req; 154 struct invalidate_commands_params_in *req;
146 int status = 0; 155 unsigned int tag = 0;
156
157 spin_lock(&ctrl->mbox_lock);
158 tag = alloc_mcc_tag(phba);
159 if (!tag) {
160 spin_unlock(&ctrl->mbox_lock);
161 return tag;
162 }
147 163
148 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, 164 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
149 sizeof(struct invalidate_commands_params_in), 165 sizeof(struct invalidate_commands_params_in),
@@ -156,8 +172,10 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
156 } 172 }
157 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); 173 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
158 req = nonemb_cmd.va; 174 req = nonemb_cmd.va;
159 spin_lock(&ctrl->mbox_lock); 175 memset(req, 0, sizeof(*req));
160 memset(wrb, 0, sizeof(*wrb)); 176 wrb = wrb_from_mccq(phba);
177 sge = nonembedded_sgl(wrb);
178 wrb->tag0 |= tag;
161 179
162 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 180 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
163 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 181 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -172,14 +190,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
172 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 190 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
173 sge->len = cpu_to_le32(nonemb_cmd.size); 191 sge->len = cpu_to_le32(nonemb_cmd.size);
174 192
175 status = be_mcc_notify_wait(phba); 193 be_mcc_notify(phba);
176 if (status)
177 SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
178 spin_unlock(&ctrl->mbox_lock); 194 spin_unlock(&ctrl->mbox_lock);
179 if (nonemb_cmd.va) 195 if (nonemb_cmd.va)
180 pci_free_consistent(ctrl->pdev, nonemb_cmd.size, 196 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
181 nonemb_cmd.va, nonemb_cmd.dma); 197 nonemb_cmd.va, nonemb_cmd.dma);
182 return status; 198 return tag;
183} 199}
184 200
185unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, 201unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
@@ -189,13 +205,19 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
189 unsigned short savecfg_flag) 205 unsigned short savecfg_flag)
190{ 206{
191 struct be_ctrl_info *ctrl = &phba->ctrl; 207 struct be_ctrl_info *ctrl = &phba->ctrl;
192 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 208 struct be_mcc_wrb *wrb;
193 struct iscsi_invalidate_connection_params_in *req = 209 struct iscsi_invalidate_connection_params_in *req;
194 embedded_payload(wrb); 210 unsigned int tag = 0;
195 int status = 0;
196 211
197 spin_lock(&ctrl->mbox_lock); 212 spin_lock(&ctrl->mbox_lock);
198 memset(wrb, 0, sizeof(*wrb)); 213 tag = alloc_mcc_tag(phba);
214 if (!tag) {
215 spin_unlock(&ctrl->mbox_lock);
216 return tag;
217 }
218 wrb = wrb_from_mccq(phba);
219 wrb->tag0 |= tag;
220 req = embedded_payload(wrb);
199 221
200 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 222 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
201 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 223 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
@@ -208,35 +230,37 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
208 else 230 else
209 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; 231 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
210 req->save_cfg = savecfg_flag; 232 req->save_cfg = savecfg_flag;
211 status = be_mcc_notify_wait(phba); 233 be_mcc_notify(phba);
212 if (status)
213 SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
214
215 spin_unlock(&ctrl->mbox_lock); 234 spin_unlock(&ctrl->mbox_lock);
216 return status; 235 return tag;
217} 236}
218 237
219unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, 238unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
220 unsigned short cid, unsigned int upload_flag) 239 unsigned short cid, unsigned int upload_flag)
221{ 240{
222 struct be_ctrl_info *ctrl = &phba->ctrl; 241 struct be_ctrl_info *ctrl = &phba->ctrl;
223 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 242 struct be_mcc_wrb *wrb;
224 struct tcp_upload_params_in *req = embedded_payload(wrb); 243 struct tcp_upload_params_in *req;
225 int status = 0; 244 unsigned int tag = 0;
226 245
227 spin_lock(&ctrl->mbox_lock); 246 spin_lock(&ctrl->mbox_lock);
228 memset(wrb, 0, sizeof(*wrb)); 247 tag = alloc_mcc_tag(phba);
248 if (!tag) {
249 spin_unlock(&ctrl->mbox_lock);
250 return tag;
251 }
252 wrb = wrb_from_mccq(phba);
253 req = embedded_payload(wrb);
254 wrb->tag0 |= tag;
229 255
230 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 256 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
231 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, 257 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
232 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); 258 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
233 req->id = (unsigned short)cid; 259 req->id = (unsigned short)cid;
234 req->upload_type = (unsigned char)upload_flag; 260 req->upload_type = (unsigned char)upload_flag;
235 status = be_mcc_notify_wait(phba); 261 be_mcc_notify(phba);
236 if (status)
237 SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
238 spin_unlock(&ctrl->mbox_lock); 262 spin_unlock(&ctrl->mbox_lock);
239 return status; 263 return tag;
240} 264}
241 265
242int mgmt_open_connection(struct beiscsi_hba *phba, 266int mgmt_open_connection(struct beiscsi_hba *phba,
@@ -248,13 +272,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
248 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; 272 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
249 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; 273 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
250 struct be_ctrl_info *ctrl = &phba->ctrl; 274 struct be_ctrl_info *ctrl = &phba->ctrl;
251 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 275 struct be_mcc_wrb *wrb;
252 struct tcp_connect_and_offload_in *req = embedded_payload(wrb); 276 struct tcp_connect_and_offload_in *req;
253 unsigned short def_hdr_id; 277 unsigned short def_hdr_id;
254 unsigned short def_data_id; 278 unsigned short def_data_id;
255 struct phys_addr template_address = { 0, 0 }; 279 struct phys_addr template_address = { 0, 0 };
256 struct phys_addr *ptemplate_address; 280 struct phys_addr *ptemplate_address;
257 int status = 0; 281 unsigned int tag = 0;
258 unsigned int i; 282 unsigned int i;
259 unsigned short cid = beiscsi_ep->ep_cid; 283 unsigned short cid = beiscsi_ep->ep_cid;
260 284
@@ -266,7 +290,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
266 ptemplate_address = &template_address; 290 ptemplate_address = &template_address;
267 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); 291 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
268 spin_lock(&ctrl->mbox_lock); 292 spin_lock(&ctrl->mbox_lock);
269 memset(wrb, 0, sizeof(*wrb)); 293 tag = alloc_mcc_tag(phba);
294 if (!tag) {
295 spin_unlock(&ctrl->mbox_lock);
296 return tag;
297 }
298 wrb = wrb_from_mccq(phba);
299 req = embedded_payload(wrb);
300 wrb->tag0 |= tag;
270 301
271 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 302 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
272 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 303 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -311,46 +342,36 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
311 req->do_offload = 1; 342 req->do_offload = 1;
312 req->dataout_template_pa.lo = ptemplate_address->lo; 343 req->dataout_template_pa.lo = ptemplate_address->lo;
313 req->dataout_template_pa.hi = ptemplate_address->hi; 344 req->dataout_template_pa.hi = ptemplate_address->hi;
314 status = be_mcc_notify_wait(phba); 345 be_mcc_notify(phba);
315 if (!status) {
316 struct iscsi_endpoint *ep;
317 struct tcp_connect_and_offload_out *ptcpcnct_out =
318 embedded_payload(wrb);
319
320 ep = phba->ep_array[ptcpcnct_out->cid];
321 beiscsi_ep = ep->dd_data;
322 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
323 beiscsi_ep->cid_vld = 1;
324 SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
325 } else
326 SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n");
327 spin_unlock(&ctrl->mbox_lock); 346 spin_unlock(&ctrl->mbox_lock);
328 return status; 347 return tag;
329} 348}
330 349
331int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr) 350unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba)
332{ 351{
333 struct be_ctrl_info *ctrl = &phba->ctrl; 352 struct be_ctrl_info *ctrl = &phba->ctrl;
334 struct be_mcc_wrb *wrb = wrb_from_mccq(phba); 353 struct be_mcc_wrb *wrb;
335 struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb); 354 struct be_cmd_req_get_mac_addr *req;
336 int status; 355 unsigned int tag = 0;
337 356
338 SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); 357 SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
339 spin_lock(&ctrl->mbox_lock); 358 spin_lock(&ctrl->mbox_lock);
340 memset(wrb, 0, sizeof(*wrb)); 359 tag = alloc_mcc_tag(phba);
360 if (!tag) {
361 spin_unlock(&ctrl->mbox_lock);
362 return tag;
363 }
364
365 wrb = wrb_from_mccq(phba);
366 req = embedded_payload(wrb);
367 wrb->tag0 |= tag;
341 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 368 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
342 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 369 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
343 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, 370 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
344 sizeof(*req)); 371 sizeof(*req));
345 372
346 status = be_mcc_notify_wait(phba); 373 be_mcc_notify(phba);
347 if (!status) {
348 struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
349
350 memcpy(mac_addr, resp->mac_address, ETH_ALEN);
351 }
352
353 spin_unlock(&ctrl->mbox_lock); 374 spin_unlock(&ctrl->mbox_lock);
354 return status; 375 return tag;
355} 376}
356 377
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 24eaff923f85..ecead6a5aa56 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2009 ServerEngines 2 * Copyright (C) 2005 - 2010 ServerEngines
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -231,6 +231,7 @@ struct beiscsi_endpoint {
231 struct beiscsi_hba *phba; 231 struct beiscsi_hba *phba;
232 struct beiscsi_sess *sess; 232 struct beiscsi_sess *sess;
233 struct beiscsi_conn *conn; 233 struct beiscsi_conn *conn;
234 struct iscsi_endpoint *openiscsi_ep;
234 unsigned short ip_type; 235 unsigned short ip_type;
235 char dst6_addr[ISCSI_ADDRESS_BUF_LEN]; 236 char dst6_addr[ISCSI_ADDRESS_BUF_LEN];
236 unsigned long dst_addr; 237 unsigned long dst_addr;
@@ -249,7 +250,4 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
249 unsigned short issue_reset, 250 unsigned short issue_reset,
250 unsigned short savecfg_flag); 251 unsigned short savecfg_flag);
251 252
252unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl,
253 struct beiscsi_hba *phba,
254 char *buf, unsigned int len);
255#endif 253#endif