aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/be2iscsi
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be.h45
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c330
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h49
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c155
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.h2
-rw-r--r--drivers/scsi/be2iscsi/be_main.c1297
-rw-r--r--drivers/scsi/be2iscsi/be_main.h85
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c177
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h16
9 files changed, 1618 insertions, 538 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index b36020dcf012..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
@@ -20,8 +20,14 @@
20 20
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/if_vlan.h> 22#include <linux/if_vlan.h>
23 23#include <linux/blk-iopoll.h>
24#define FW_VER_LEN 32 24#define FW_VER_LEN 32
25#define MCC_Q_LEN 128
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
25 31
26struct be_dma_mem { 32struct be_dma_mem {
27 void *va; 33 void *va;
@@ -55,6 +61,11 @@ static inline void *queue_head_node(struct be_queue_info *q)
55 return q->dma_mem.va + q->head * q->entry_size; 61 return q->dma_mem.va + q->head * q->entry_size;
56} 62}
57 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
58static inline void *queue_tail_node(struct be_queue_info *q) 69static inline void *queue_tail_node(struct be_queue_info *q)
59{ 70{
60 return q->dma_mem.va + q->tail * q->entry_size; 71 return q->dma_mem.va + q->tail * q->entry_size;
@@ -74,18 +85,14 @@ static inline void queue_tail_inc(struct be_queue_info *q)
74 85
75struct be_eq_obj { 86struct be_eq_obj {
76 struct be_queue_info q; 87 struct be_queue_info q;
77 char desc[32]; 88 struct beiscsi_hba *phba;
78 89 struct be_queue_info *cq;
79 /* Adaptive interrupt coalescing (AIC) info */ 90 struct blk_iopoll iopoll;
80 bool enable_aic;
81 u16 min_eqd; /* in usecs */
82 u16 max_eqd; /* in usecs */
83 u16 cur_eqd; /* in usecs */
84}; 91};
85 92
86struct be_mcc_obj { 93struct be_mcc_obj {
87 struct be_queue_info *q; 94 struct be_queue_info q;
88 struct be_queue_info *cq; 95 struct be_queue_info cq;
89}; 96};
90 97
91struct be_ctrl_info { 98struct be_ctrl_info {
@@ -106,15 +113,19 @@ struct be_ctrl_info {
106 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ 113 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
107 spinlock_t mcc_cq_lock; 114 spinlock_t mcc_cq_lock;
108 115
109 /* MCC Async callback */ 116 wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
110 void (*async_cb) (void *adapter, bool link_up); 117 unsigned int mcc_tag[MAX_MCC_CMD];
111 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;
112}; 122};
113 123
114#include "be_cmds.h" 124#include "be_cmds.h"
115 125
116#define PAGE_SHIFT_4K 12 126#define PAGE_SHIFT_4K 12
117#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) 127#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
128#define mcc_timeout 120000 /* 5s timeout */
118 129
119/* 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 */
120#define PAGES_4K_SPANNED(_address, size) \ 131#define PAGES_4K_SPANNED(_address, size) \
@@ -176,8 +187,4 @@ static inline void swap_dws(void *wrb, int len)
176 } while (len); 187 } while (len);
177#endif /* __BIG_ENDIAN */ 188#endif /* __BIG_ENDIAN */
178} 189}
179
180extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
181 u16 num_popped);
182
183#endif /* BEISCSI_H */ 190#endif /* BEISCSI_H */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 08007b6e42df..cda6642c7368 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,6 +19,55 @@
19#include "be_mgmt.h" 19#include "be_mgmt.h"
20#include "be_main.h" 20#include "be_main.h"
21 21
22void be_mcc_notify(struct beiscsi_hba *phba)
23{
24 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
25 u32 val = 0;
26
27 val |= mccq->id & DB_MCCQ_RING_ID_MASK;
28 val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
29 iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
30}
31
32unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
33{
34 unsigned int tag = 0;
35
36 if (phba->ctrl.mcc_tag_available) {
37 tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
38 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
39 phba->ctrl.mcc_numtag[tag] = 0;
40 }
41 if (tag) {
42 phba->ctrl.mcc_tag_available--;
43 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
44 phba->ctrl.mcc_alloc_index = 0;
45 else
46 phba->ctrl.mcc_alloc_index++;
47 }
48 return tag;
49}
50
51void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
52{
53 spin_lock(&ctrl->mbox_lock);
54 tag = tag & 0x000000FF;
55 ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
56 if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
57 ctrl->mcc_free_index = 0;
58 else
59 ctrl->mcc_free_index++;
60 ctrl->mcc_tag_available++;
61 spin_unlock(&ctrl->mbox_lock);
62}
63
64bool is_link_state_evt(u32 trailer)
65{
66 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
67 ASYNC_TRAILER_EVENT_CODE_MASK) ==
68 ASYNC_EVENT_CODE_LINK_STATE);
69}
70
22static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) 71static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
23{ 72{
24 if (compl->flags != 0) { 73 if (compl->flags != 0) {
@@ -54,13 +103,74 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
54 return 0; 103 return 0;
55} 104}
56 105
57static inline bool is_link_state_evt(u32 trailer) 106int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
107 struct be_mcc_compl *compl)
58{ 108{
59 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & 109 u16 compl_status, extd_status;
60 ASYNC_TRAILER_EVENT_CODE_MASK) == ASYNC_EVENT_CODE_LINK_STATE); 110 unsigned short tag;
111
112 be_dws_le_to_cpu(compl, 4);
113
114 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
115 CQE_STATUS_COMPL_MASK;
116 /* The ctrl.mcc_numtag[tag] is filled with
117 * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
118 * [7:0] = compl_status
119 */
120 tag = (compl->tag0 & 0x000000FF);
121 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
122 CQE_STATUS_EXTD_MASK;
123
124 ctrl->mcc_numtag[tag] = 0x80000000;
125 ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000);
126 ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8;
127 ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF);
128 wake_up_interruptible(&ctrl->mcc_wait[tag]);
129 return 0;
130}
131
132static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
133{
134 struct be_queue_info *mcc_cq = &phba->ctrl.mcc_obj.cq;
135 struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
136
137 if (be_mcc_compl_is_new(compl)) {
138 queue_tail_inc(mcc_cq);
139 return compl;
140 }
141 return NULL;
142}
143
144static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
145{
146 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
61} 147}
62 148
63void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm, 149void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
150 struct be_async_event_link_state *evt)
151{
152 switch (evt->port_link_status) {
153 case ASYNC_EVENT_LINK_DOWN:
154 SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n",
155 evt->physical_port);
156 phba->state |= BE_ADAPTER_LINK_DOWN;
157 iscsi_host_for_each_session(phba->shost,
158 be2iscsi_fail_session);
159 break;
160 case ASYNC_EVENT_LINK_UP:
161 phba->state = BE_ADAPTER_UP;
162 SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n",
163 evt->physical_port);
164 break;
165 default:
166 SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
167 "Physical Port %d \n",
168 evt->port_link_status,
169 evt->physical_port);
170 }
171}
172
173static void beiscsi_cq_notify(struct beiscsi_hba *phba, u16 qid, bool arm,
64 u16 num_popped) 174 u16 num_popped)
65{ 175{
66 u32 val = 0; 176 u32 val = 0;
@@ -68,7 +178,69 @@ void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
68 if (arm) 178 if (arm)
69 val |= 1 << DB_CQ_REARM_SHIFT; 179 val |= 1 << DB_CQ_REARM_SHIFT;
70 val |= num_popped << DB_CQ_NUM_POPPED_SHIFT; 180 val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
71 iowrite32(val, ctrl->db + DB_CQ_OFFSET); 181 iowrite32(val, phba->db_va + DB_CQ_OFFSET);
182}
183
184
185int beiscsi_process_mcc(struct beiscsi_hba *phba)
186{
187 struct be_mcc_compl *compl;
188 int num = 0, status = 0;
189 struct be_ctrl_info *ctrl = &phba->ctrl;
190
191 spin_lock_bh(&phba->ctrl.mcc_cq_lock);
192 while ((compl = be_mcc_compl_get(phba))) {
193 if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
194 /* Interpret flags as an async trailer */
195 if (is_link_state_evt(compl->flags))
196 /* Interpret compl as a async link evt */
197 beiscsi_async_link_state_process(phba,
198 (struct be_async_event_link_state *) compl);
199 else
200 SE_DEBUG(DBG_LVL_1,
201 " Unsupported Async Event, flags"
202 " = 0x%08x \n", compl->flags);
203
204 } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
205 status = be_mcc_compl_process(ctrl, compl);
206 atomic_dec(&phba->ctrl.mcc_obj.q.used);
207 }
208 be_mcc_compl_use(compl);
209 num++;
210 }
211
212 if (num)
213 beiscsi_cq_notify(phba, phba->ctrl.mcc_obj.cq.id, true, num);
214
215 spin_unlock_bh(&phba->ctrl.mcc_cq_lock);
216 return status;
217}
218
219/* Wait till no more pending mcc requests are present */
220static int be_mcc_wait_compl(struct beiscsi_hba *phba)
221{
222 int i, status;
223 for (i = 0; i < mcc_timeout; i++) {
224 status = beiscsi_process_mcc(phba);
225 if (status)
226 return status;
227
228 if (atomic_read(&phba->ctrl.mcc_obj.q.used) == 0)
229 break;
230 udelay(100);
231 }
232 if (i == mcc_timeout) {
233 dev_err(&phba->pcidev->dev, "mccq poll timed out\n");
234 return -1;
235 }
236 return 0;
237}
238
239/* Notify MCC requests and wait for completion */
240int be_mcc_notify_wait(struct beiscsi_hba *phba)
241{
242 be_mcc_notify(phba);
243 return be_mcc_wait_compl(phba);
72} 244}
73 245
74static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) 246static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
@@ -142,6 +314,52 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
142 return 0; 314 return 0;
143} 315}
144 316
317/*
318 * Insert the mailbox address into the doorbell in two steps
319 * Polls on the mbox doorbell till a command completion (or a timeout) occurs
320 */
321static int be_mbox_notify_wait(struct beiscsi_hba *phba)
322{
323 int status;
324 u32 val = 0;
325 void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET;
326 struct be_dma_mem *mbox_mem = &phba->ctrl.mbox_mem;
327 struct be_mcc_mailbox *mbox = mbox_mem->va;
328 struct be_mcc_compl *compl = &mbox->compl;
329 struct be_ctrl_info *ctrl = &phba->ctrl;
330
331 val |= MPU_MAILBOX_DB_HI_MASK;
332 /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
333 val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
334 iowrite32(val, db);
335
336 /* wait for ready to be set */
337 status = be_mbox_db_ready_wait(ctrl);
338 if (status != 0)
339 return status;
340
341 val = 0;
342 /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
343 val |= (u32)(mbox_mem->dma >> 4) << 2;
344 iowrite32(val, db);
345
346 status = be_mbox_db_ready_wait(ctrl);
347 if (status != 0)
348 return status;
349
350 /* A cq entry has been made now */
351 if (be_mcc_compl_is_new(compl)) {
352 status = be_mcc_compl_process(ctrl, &mbox->compl);
353 be_mcc_compl_use(compl);
354 if (status)
355 return status;
356 } else {
357 dev_err(&phba->pcidev->dev, "invalid mailbox completion\n");
358 return -1;
359 }
360 return 0;
361}
362
145void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, 363void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
146 bool embedded, u8 sge_cnt) 364 bool embedded, u8 sge_cnt)
147{ 365{
@@ -203,6 +421,21 @@ struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
203 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; 421 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
204} 422}
205 423
424struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
425{
426 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
427 struct be_mcc_wrb *wrb;
428
429 BUG_ON(atomic_read(&mccq->used) >= mccq->len);
430 wrb = queue_head_node(mccq);
431 memset(wrb, 0, sizeof(*wrb));
432 wrb->tag0 = (mccq->head & 0x000000FF) << 16;
433 queue_head_inc(mccq);
434 atomic_inc(&mccq->used);
435 return wrb;
436}
437
438
206int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, 439int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
207 struct be_queue_info *eq, int eq_delay) 440 struct be_queue_info *eq, int eq_delay)
208{ 441{
@@ -212,6 +445,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
212 struct be_dma_mem *q_mem = &eq->dma_mem; 445 struct be_dma_mem *q_mem = &eq->dma_mem;
213 int status; 446 int status;
214 447
448 SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_eq_create\n");
215 spin_lock(&ctrl->mbox_lock); 449 spin_lock(&ctrl->mbox_lock);
216 memset(wrb, 0, sizeof(*wrb)); 450 memset(wrb, 0, sizeof(*wrb));
217 451
@@ -249,6 +483,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
249 int status; 483 int status;
250 u8 *endian_check; 484 u8 *endian_check;
251 485
486 SE_DEBUG(DBG_LVL_8, "In be_cmd_fw_initialize\n");
252 spin_lock(&ctrl->mbox_lock); 487 spin_lock(&ctrl->mbox_lock);
253 memset(wrb, 0, sizeof(*wrb)); 488 memset(wrb, 0, sizeof(*wrb));
254 489
@@ -282,6 +517,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
282 void *ctxt = &req->context; 517 void *ctxt = &req->context;
283 int status; 518 int status;
284 519
520 SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n");
285 spin_lock(&ctrl->mbox_lock); 521 spin_lock(&ctrl->mbox_lock);
286 memset(wrb, 0, sizeof(*wrb)); 522 memset(wrb, 0, sizeof(*wrb));
287 523
@@ -289,7 +525,6 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
289 525
290 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 526 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
291 OPCODE_COMMON_CQ_CREATE, sizeof(*req)); 527 OPCODE_COMMON_CQ_CREATE, sizeof(*req));
292
293 if (!q_mem->va) 528 if (!q_mem->va)
294 SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n"); 529 SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n");
295 530
@@ -329,6 +564,53 @@ static u32 be_encoded_q_len(int q_len)
329 len_encoded = 0; 564 len_encoded = 0;
330 return len_encoded; 565 return len_encoded;
331} 566}
567
568int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
569 struct be_queue_info *mccq,
570 struct be_queue_info *cq)
571{
572 struct be_mcc_wrb *wrb;
573 struct be_cmd_req_mcc_create *req;
574 struct be_dma_mem *q_mem = &mccq->dma_mem;
575 struct be_ctrl_info *ctrl;
576 void *ctxt;
577 int status;
578
579 spin_lock(&phba->ctrl.mbox_lock);
580 ctrl = &phba->ctrl;
581 wrb = wrb_from_mbox(&ctrl->mbox_mem);
582 req = embedded_payload(wrb);
583 ctxt = &req->context;
584
585 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
586
587 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
588 OPCODE_COMMON_MCC_CREATE, sizeof(*req));
589
590 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
591
592 AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt,
593 PCI_FUNC(phba->pcidev->devfn));
594 AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
595 AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
596 be_encoded_q_len(mccq->len));
597 AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
598
599 be_dws_cpu_to_le(ctxt, sizeof(req->context));
600
601 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
602
603 status = be_mbox_notify_wait(phba);
604 if (!status) {
605 struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
606 mccq->id = le16_to_cpu(resp->id);
607 mccq->created = true;
608 }
609 spin_unlock(&phba->ctrl.mbox_lock);
610
611 return status;
612}
613
332int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, 614int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
333 int queue_type) 615 int queue_type)
334{ 616{
@@ -337,6 +619,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
337 u8 subsys = 0, opcode = 0; 619 u8 subsys = 0, opcode = 0;
338 int status; 620 int status;
339 621
622 SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n");
340 spin_lock(&ctrl->mbox_lock); 623 spin_lock(&ctrl->mbox_lock);
341 memset(wrb, 0, sizeof(*wrb)); 624 memset(wrb, 0, sizeof(*wrb));
342 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 625 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -350,6 +633,10 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
350 subsys = CMD_SUBSYSTEM_COMMON; 633 subsys = CMD_SUBSYSTEM_COMMON;
351 opcode = OPCODE_COMMON_CQ_DESTROY; 634 opcode = OPCODE_COMMON_CQ_DESTROY;
352 break; 635 break;
636 case QTYPE_MCCQ:
637 subsys = CMD_SUBSYSTEM_COMMON;
638 opcode = OPCODE_COMMON_MCC_DESTROY;
639 break;
353 case QTYPE_WRBQ: 640 case QTYPE_WRBQ:
354 subsys = CMD_SUBSYSTEM_ISCSI; 641 subsys = CMD_SUBSYSTEM_ISCSI;
355 opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY; 642 opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
@@ -377,30 +664,6 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
377 return status; 664 return status;
378} 665}
379 666
380int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr)
381{
382 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
383 struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
384 int status;
385
386 spin_lock(&ctrl->mbox_lock);
387 memset(wrb, 0, sizeof(*wrb));
388 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
389 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
390 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
391 sizeof(*req));
392
393 status = be_mbox_notify(ctrl);
394 if (!status) {
395 struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
396
397 memcpy(mac_addr, resp->mac_address, ETH_ALEN);
398 }
399
400 spin_unlock(&ctrl->mbox_lock);
401 return status;
402}
403
404int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, 667int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
405 struct be_queue_info *cq, 668 struct be_queue_info *cq,
406 struct be_queue_info *dq, int length, 669 struct be_queue_info *dq, int length,
@@ -412,6 +675,7 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
412 void *ctxt = &req->context; 675 void *ctxt = &req->context;
413 int status; 676 int status;
414 677
678 SE_DEBUG(DBG_LVL_8, "In be_cmd_create_default_pdu_queue\n");
415 spin_lock(&ctrl->mbox_lock); 679 spin_lock(&ctrl->mbox_lock);
416 memset(wrb, 0, sizeof(*wrb)); 680 memset(wrb, 0, sizeof(*wrb));
417 681
@@ -468,8 +732,10 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
468 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); 732 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
469 733
470 status = be_mbox_notify(ctrl); 734 status = be_mbox_notify(ctrl);
471 if (!status) 735 if (!status) {
472 wrbq->id = le16_to_cpu(resp->cid); 736 wrbq->id = le16_to_cpu(resp->cid);
737 wrbq->created = true;
738 }
473 spin_unlock(&ctrl->mbox_lock); 739 spin_unlock(&ctrl->mbox_lock);
474 return status; 740 return status;
475} 741}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index c20d686cbb43..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
@@ -47,6 +47,8 @@ struct be_mcc_wrb {
47 47
48#define CQE_FLAGS_VALID_MASK (1 << 31) 48#define CQE_FLAGS_VALID_MASK (1 << 31)
49#define CQE_FLAGS_ASYNC_MASK (1 << 30) 49#define CQE_FLAGS_ASYNC_MASK (1 << 30)
50#define CQE_FLAGS_COMPLETED_MASK (1 << 28)
51#define CQE_FLAGS_CONSUMED_MASK (1 << 27)
50 52
51/* Completion Status */ 53/* Completion Status */
52#define MCC_STATUS_SUCCESS 0x0 54#define MCC_STATUS_SUCCESS 0x0
@@ -173,7 +175,7 @@ struct be_cmd_req_hdr {
173 u8 domain; /* dword 0 */ 175 u8 domain; /* dword 0 */
174 u32 timeout; /* dword 1 */ 176 u32 timeout; /* dword 1 */
175 u32 request_length; /* dword 2 */ 177 u32 request_length; /* dword 2 */
176 u32 rsvd; /* dword 3 */ 178 u32 rsvd0; /* dword 3 */
177}; 179};
178 180
179struct be_cmd_resp_hdr { 181struct be_cmd_resp_hdr {
@@ -382,7 +384,6 @@ struct be_cmd_req_modify_eq_delay {
382 384
383#define ETH_ALEN 6 385#define ETH_ALEN 6
384 386
385
386struct be_cmd_req_get_mac_addr { 387struct be_cmd_req_get_mac_addr {
387 struct be_cmd_req_hdr hdr; 388 struct be_cmd_req_hdr hdr;
388 u32 nic_port_count; 389 u32 nic_port_count;
@@ -417,14 +418,27 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
417 418
418int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, 419int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
419 int type); 420 int type);
420int be_poll_mcc(struct be_ctrl_info *ctrl); 421int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
421unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl); 422 struct be_queue_info *mccq,
422int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr); 423 struct be_queue_info *cq);
423 424
425int be_poll_mcc(struct be_ctrl_info *ctrl);
426unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
427 struct beiscsi_hba *phba);
428unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba);
429void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
424/*ISCSI Functuions */ 430/*ISCSI Functuions */
425int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); 431int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
426 432
427struct 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);
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);
428 442
429int be_mbox_notify(struct be_ctrl_info *ctrl); 443int be_mbox_notify(struct be_ctrl_info *ctrl);
430 444
@@ -440,6 +454,8 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
440int 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,
441 struct be_queue_info *wrbq); 455 struct be_queue_info *wrbq);
442 456
457bool is_link_state_evt(u32 trailer);
458
443struct be_default_pdu_context { 459struct be_default_pdu_context {
444 u32 dw[4]; 460 u32 dw[4];
445} __packed; 461} __packed;
@@ -531,6 +547,23 @@ struct amap_sol_cqe {
531 u8 valid; /* dword 3 */ 547 u8 valid; /* dword 3 */
532} __packed; 548} __packed;
533 549
550#define SOL_ICD_INDEX_MASK 0x0003FFC0
551struct amap_sol_cqe_ring {
552 u8 hw_sts[8]; /* dword 0 */
553 u8 i_sts[8]; /* dword 0 */
554 u8 i_resp[8]; /* dword 0 */
555 u8 i_flags[7]; /* dword 0 */
556 u8 s; /* dword 0 */
557 u8 i_exp_cmd_sn[32]; /* dword 1 */
558 u8 code[6]; /* dword 2 */
559 u8 icd_index[12]; /* dword 2 */
560 u8 rsvd[6]; /* dword 2 */
561 u8 i_cmd_wnd[8]; /* dword 2 */
562 u8 i_res_cnt[31]; /* dword 3 */
563 u8 valid; /* dword 3 */
564} __packed;
565
566
534 567
535/** 568/**
536 * Post WRB Queue Doorbell Register used by the host Storage 569 * Post WRB Queue Doorbell Register used by the host Storage
@@ -664,8 +697,8 @@ struct be_fw_cfg {
664#define OPCODE_COMMON_TCP_UPLOAD 56 697#define OPCODE_COMMON_TCP_UPLOAD 56
665#define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1 698#define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1
666/* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ 699/* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
667#define CMD_ISCSI_CONNECTION_INVALIDATE 1 700#define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001
668#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 2 701#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002
669#define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 702#define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
670 703
671#define INI_WR_CMD 1 /* Initiator write command */ 704#define INI_WR_CMD 1 /* Initiator write command */
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 2fd25442cfaf..c3928cb8b042 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
@@ -67,11 +67,11 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
67 cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; 67 cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
68 } 68 }
69 69
70 cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, 70 cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
71 shost, cmds_max, 71 shost, cmds_max,
72 sizeof(*beiscsi_sess), 72 sizeof(*beiscsi_sess),
73 sizeof(*io_task), 73 sizeof(*io_task),
74 initial_cmdsn, ISCSI_MAX_TARGET); 74 initial_cmdsn, ISCSI_MAX_TARGET);
75 if (!cls_session) 75 if (!cls_session)
76 return NULL; 76 return NULL;
77 sess = cls_session->dd_data; 77 sess = cls_session->dd_data;
@@ -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->ctrl, 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);
@@ -377,16 +409,13 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
377 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 409 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
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 struct iscsi_session *session = conn->session;
381 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
382 struct beiscsi_hba *phba = iscsi_host_priv(shost);
383 412
413 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n");
384 memset(&params, 0, sizeof(struct beiscsi_offload_params)); 414 memset(&params, 0, sizeof(struct beiscsi_offload_params));
385 beiscsi_ep = beiscsi_conn->ep; 415 beiscsi_ep = beiscsi_conn->ep;
386 if (!beiscsi_ep) 416 if (!beiscsi_ep)
387 SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n"); 417 SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
388 418
389 free_mgmt_sgl_handle(phba, beiscsi_conn->plogin_sgl_handle);
390 beiscsi_conn->login_in_progress = 0; 419 beiscsi_conn->login_in_progress = 0;
391 beiscsi_set_params_for_offld(beiscsi_conn, &params); 420 beiscsi_set_params_for_offld(beiscsi_conn, &params);
392 beiscsi_offload_connection(beiscsi_conn, &params); 421 beiscsi_offload_connection(beiscsi_conn, &params);
@@ -426,8 +455,14 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
426{ 455{
427 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 456 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
428 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;
429 int ret = -1; 463 int ret = -1;
430 464
465 SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
431 beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 466 beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
432 if (beiscsi_ep->ep_cid == 0xFFFF) { 467 if (beiscsi_ep->ep_cid == 0xFFFF) {
433 SE_DEBUG(DBG_LVL_1, "No free cid available\n"); 468 SE_DEBUG(DBG_LVL_1, "No free cid available\n");
@@ -435,15 +470,44 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
435 } 470 }
436 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 ",
437 beiscsi_ep->ep_cid); 472 beiscsi_ep->ep_cid);
438 phba->ep_array[beiscsi_ep->ep_cid] = ep; 473 phba->ep_array[beiscsi_ep->ep_cid -
439 if (beiscsi_ep->ep_cid > 474 phba->fw_config.iscsi_cid_start] = ep;
440 (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)) {
441 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); 477 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
442 return ret; 478 return ret;
443 } 479 }
444 480
445 beiscsi_ep->cid_vld = 0; 481 beiscsi_ep->cid_vld = 0;
446 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_open_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;
447} 511}
448 512
449/** 513/**
@@ -463,14 +527,12 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
463 * beiscsi_free_ep - free endpoint 527 * beiscsi_free_ep - free endpoint
464 * @ep: pointer to iscsi endpoint structure 528 * @ep: pointer to iscsi endpoint structure
465 */ 529 */
466static void beiscsi_free_ep(struct iscsi_endpoint *ep) 530static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
467{ 531{
468 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
469 struct beiscsi_hba *phba = beiscsi_ep->phba; 532 struct beiscsi_hba *phba = beiscsi_ep->phba;
470 533
471 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 534 beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
472 beiscsi_ep->phba = NULL; 535 beiscsi_ep->phba = NULL;
473 iscsi_destroy_endpoint(ep);
474} 536}
475 537
476/** 538/**
@@ -498,6 +560,13 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
498 SE_DEBUG(DBG_LVL_1, "shost is NULL \n"); 560 SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
499 return ERR_PTR(ret); 561 return ERR_PTR(ret);
500 } 562 }
563
564 if (phba->state != BE_ADAPTER_UP) {
565 ret = -EBUSY;
566 SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n");
567 return ERR_PTR(ret);
568 }
569
501 ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); 570 ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
502 if (!ep) { 571 if (!ep) {
503 ret = -ENOMEM; 572 ret = -ENOMEM;
@@ -506,9 +575,9 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
506 575
507 beiscsi_ep = ep->dd_data; 576 beiscsi_ep = ep->dd_data;
508 beiscsi_ep->phba = phba; 577 beiscsi_ep->phba = phba;
509 578 beiscsi_ep->openiscsi_ep = ep;
510 if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { 579 if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
511 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); 580 SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
512 ret = -ENOMEM; 581 ret = -ENOMEM;
513 goto free_ep; 582 goto free_ep;
514 } 583 }
@@ -516,7 +585,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
516 return ep; 585 return ep;
517 586
518free_ep: 587free_ep:
519 beiscsi_free_ep(ep); 588 beiscsi_free_ep(beiscsi_ep);
520 return ERR_PTR(ret); 589 return ERR_PTR(ret);
521} 590}
522 591
@@ -543,20 +612,22 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
543 * @ep: The iscsi endpoint 612 * @ep: The iscsi endpoint
544 * @flag: The type of connection closure 613 * @flag: The type of connection closure
545 */ 614 */
546static int beiscsi_close_conn(struct iscsi_endpoint *ep, int flag) 615static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
547{ 616{
548 int ret = 0; 617 int ret = 0;
549 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 618 unsigned int tag;
550 struct beiscsi_hba *phba = beiscsi_ep->phba; 619 struct beiscsi_hba *phba = beiscsi_ep->phba;
551 620
552 if (MGMT_STATUS_SUCCESS != 621 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
553 mgmt_upload_connection(phba, beiscsi_ep->ep_cid, 622 if (!tag) {
554 CONNECTION_UPLOAD_GRACEFUL)) {
555 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", 623 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
556 beiscsi_ep->ep_cid); 624 beiscsi_ep->ep_cid);
557 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);
558 } 630 }
559
560 return ret; 631 return ret;
561} 632}
562 633
@@ -571,19 +642,17 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
571 struct beiscsi_conn *beiscsi_conn; 642 struct beiscsi_conn *beiscsi_conn;
572 struct beiscsi_endpoint *beiscsi_ep; 643 struct beiscsi_endpoint *beiscsi_ep;
573 struct beiscsi_hba *phba; 644 struct beiscsi_hba *phba;
574 int flag = 0;
575 645
576 beiscsi_ep = ep->dd_data; 646 beiscsi_ep = ep->dd_data;
577 phba = beiscsi_ep->phba; 647 phba = beiscsi_ep->phba;
578 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);
579 650
580 if (beiscsi_ep->conn) { 651 if (beiscsi_ep->conn) {
581 beiscsi_conn = beiscsi_ep->conn; 652 beiscsi_conn = beiscsi_ep->conn;
582 iscsi_suspend_queue(beiscsi_conn->conn); 653 iscsi_suspend_queue(beiscsi_conn->conn);
583 beiscsi_close_conn(ep, flag);
584 } 654 }
585 655
586 beiscsi_free_ep(ep);
587} 656}
588 657
589/** 658/**
@@ -616,23 +685,31 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
616 struct iscsi_session *session = conn->session; 685 struct iscsi_session *session = conn->session;
617 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); 686 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
618 struct beiscsi_hba *phba = iscsi_host_priv(shost); 687 struct beiscsi_hba *phba = iscsi_host_priv(shost);
619 unsigned int status; 688 unsigned int tag;
620 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 689 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
621 690
622 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n");
623 beiscsi_ep = beiscsi_conn->ep; 691 beiscsi_ep = beiscsi_conn->ep;
624 if (!beiscsi_ep) { 692 if (!beiscsi_ep) {
625 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");
626 return; 694 return;
627 } 695 }
628 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,
629 beiscsi_ep->ep_cid, 1, 699 beiscsi_ep->ep_cid, 1,
630 savecfg_flag); 700 savecfg_flag);
631 if (status != MGMT_STATUS_SUCCESS) { 701 if (!tag) {
632 SE_DEBUG(DBG_LVL_1, 702 SE_DEBUG(DBG_LVL_1,
633 "mgmt_invalidate_connection Failed for cid=%d \n", 703 "mgmt_invalidate_connection Failed for cid=%d \n",
634 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);
635 } 709 }
710 beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
711 beiscsi_free_ep(beiscsi_ep);
712 iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
636 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 713 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
637 iscsi_conn_stop(cls_conn, flag); 714 iscsi_conn_stop(cls_conn, flag);
638} 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 4f1aca346e38..dd5b105f8f47 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
@@ -19,6 +19,7 @@
19 */ 19 */
20#include <linux/reboot.h> 20#include <linux/reboot.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/slab.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/blkdev.h> 24#include <linux/blkdev.h>
24#include <linux/pci.h> 25#include <linux/pci.h>
@@ -39,7 +40,7 @@
39 40
40static unsigned int be_iopoll_budget = 10; 41static unsigned int be_iopoll_budget = 10;
41static unsigned int be_max_phys_size = 64; 42static unsigned int be_max_phys_size = 64;
42static unsigned int enable_msix; 43static unsigned int enable_msix = 1;
43 44
44MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); 45MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
45MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); 46MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -58,17 +59,145 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
58 return 0; 59 return 0;
59} 60}
60 61
62static int beiscsi_eh_abort(struct scsi_cmnd *sc)
63{
64 struct iscsi_cls_session *cls_session;
65 struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
66 struct beiscsi_io_task *aborted_io_task;
67 struct iscsi_conn *conn;
68 struct beiscsi_conn *beiscsi_conn;
69 struct beiscsi_hba *phba;
70 struct iscsi_session *session;
71 struct invalidate_command_table *inv_tbl;
72 unsigned int cid, tag, num_invalidate;
73
74 cls_session = starget_to_session(scsi_target(sc->device));
75 session = cls_session->dd_data;
76
77 spin_lock_bh(&session->lock);
78 if (!aborted_task || !aborted_task->sc) {
79 /* we raced */
80 spin_unlock_bh(&session->lock);
81 return SUCCESS;
82 }
83
84 aborted_io_task = aborted_task->dd_data;
85 if (!aborted_io_task->scsi_cmnd) {
86 /* raced or invalid command */
87 spin_unlock_bh(&session->lock);
88 return SUCCESS;
89 }
90 spin_unlock_bh(&session->lock);
91 conn = aborted_task->conn;
92 beiscsi_conn = conn->dd_data;
93 phba = beiscsi_conn->phba;
94
95 /* invalidate iocb */
96 cid = beiscsi_conn->beiscsi_conn_cid;
97 inv_tbl = phba->inv_tbl;
98 memset(inv_tbl, 0x0, sizeof(*inv_tbl));
99 inv_tbl->cid = cid;
100 inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
101 num_invalidate = 1;
102 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
103 if (!tag) {
104 shost_printk(KERN_WARNING, phba->shost,
105 "mgmt_invalidate_icds could not be"
106 " submitted\n");
107 return FAILED;
108 } else {
109 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
110 phba->ctrl.mcc_numtag[tag]);
111 free_mcc_tag(&phba->ctrl, tag);
112 }
113
114 return iscsi_eh_abort(sc);
115}
116
117static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
118{
119 struct iscsi_task *abrt_task;
120 struct beiscsi_io_task *abrt_io_task;
121 struct iscsi_conn *conn;
122 struct beiscsi_conn *beiscsi_conn;
123 struct beiscsi_hba *phba;
124 struct iscsi_session *session;
125 struct iscsi_cls_session *cls_session;
126 struct invalidate_command_table *inv_tbl;
127 unsigned int cid, tag, i, num_invalidate;
128 int rc = FAILED;
129
130 /* invalidate iocbs */
131 cls_session = starget_to_session(scsi_target(sc->device));
132 session = cls_session->dd_data;
133 spin_lock_bh(&session->lock);
134 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
135 goto unlock;
136
137 conn = session->leadconn;
138 beiscsi_conn = conn->dd_data;
139 phba = beiscsi_conn->phba;
140 cid = beiscsi_conn->beiscsi_conn_cid;
141 inv_tbl = phba->inv_tbl;
142 memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
143 num_invalidate = 0;
144 for (i = 0; i < conn->session->cmds_max; i++) {
145 abrt_task = conn->session->cmds[i];
146 abrt_io_task = abrt_task->dd_data;
147 if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
148 continue;
149
150 if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
151 continue;
152
153 inv_tbl->cid = cid;
154 inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
155 num_invalidate++;
156 inv_tbl++;
157 }
158 spin_unlock_bh(&session->lock);
159 inv_tbl = phba->inv_tbl;
160
161 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
162 if (!tag) {
163 shost_printk(KERN_WARNING, phba->shost,
164 "mgmt_invalidate_icds could not be"
165 " submitted\n");
166 return FAILED;
167 } else {
168 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
169 phba->ctrl.mcc_numtag[tag]);
170 free_mcc_tag(&phba->ctrl, tag);
171 }
172
173 return iscsi_eh_device_reset(sc);
174unlock:
175 spin_unlock_bh(&session->lock);
176 return rc;
177}
178
179/*------------------- PCI Driver operations and data ----------------- */
180static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
181 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
182 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
183 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
184 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
185 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
186 { 0 }
187};
188MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
189
61static struct scsi_host_template beiscsi_sht = { 190static struct scsi_host_template beiscsi_sht = {
62 .module = THIS_MODULE, 191 .module = THIS_MODULE,
63 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", 192 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
64 .proc_name = DRV_NAME, 193 .proc_name = DRV_NAME,
65 .queuecommand = iscsi_queuecommand, 194 .queuecommand = iscsi_queuecommand,
66 .eh_abort_handler = iscsi_eh_abort,
67 .change_queue_depth = iscsi_change_queue_depth, 195 .change_queue_depth = iscsi_change_queue_depth,
68 .slave_configure = beiscsi_slave_configure, 196 .slave_configure = beiscsi_slave_configure,
69 .target_alloc = iscsi_target_alloc, 197 .target_alloc = iscsi_target_alloc,
70 .eh_device_reset_handler = iscsi_eh_device_reset, 198 .eh_abort_handler = beiscsi_eh_abort,
71 .eh_target_reset_handler = iscsi_eh_target_reset, 199 .eh_device_reset_handler = beiscsi_eh_device_reset,
200 .eh_target_reset_handler = iscsi_eh_session_reset,
72 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, 201 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
73 .can_queue = BE2_IO_DEPTH, 202 .can_queue = BE2_IO_DEPTH,
74 .this_id = -1, 203 .this_id = -1,
@@ -76,16 +205,8 @@ static struct scsi_host_template beiscsi_sht = {
76 .cmd_per_lun = BEISCSI_CMD_PER_LUN, 205 .cmd_per_lun = BEISCSI_CMD_PER_LUN,
77 .use_clustering = ENABLE_CLUSTERING, 206 .use_clustering = ENABLE_CLUSTERING,
78}; 207};
79static struct scsi_transport_template *beiscsi_scsi_transport;
80 208
81/*------------------- PCI Driver operations and data ----------------- */ 209static struct scsi_transport_template *beiscsi_scsi_transport;
82static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
83 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
84 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
85 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
86 { 0 }
87};
88MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
89 210
90static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) 211static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
91{ 212{
@@ -104,11 +225,11 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
104 shost->max_cmd_len = BEISCSI_MAX_CMD_LEN; 225 shost->max_cmd_len = BEISCSI_MAX_CMD_LEN;
105 shost->max_lun = BEISCSI_NUM_MAX_LUN; 226 shost->max_lun = BEISCSI_NUM_MAX_LUN;
106 shost->transportt = beiscsi_scsi_transport; 227 shost->transportt = beiscsi_scsi_transport;
107
108 phba = iscsi_host_priv(shost); 228 phba = iscsi_host_priv(shost);
109 memset(phba, 0, sizeof(*phba)); 229 memset(phba, 0, sizeof(*phba));
110 phba->shost = shost; 230 phba->shost = shost;
111 phba->pcidev = pci_dev_get(pcidev); 231 phba->pcidev = pci_dev_get(pcidev);
232 pci_set_drvdata(pcidev, phba);
112 233
113 if (iscsi_host_add(shost, &phba->pcidev->dev)) 234 if (iscsi_host_add(shost, &phba->pcidev->dev))
114 goto free_devices; 235 goto free_devices;
@@ -140,6 +261,7 @@ static int beiscsi_map_pci_bars(struct beiscsi_hba *phba,
140 struct pci_dev *pcidev) 261 struct pci_dev *pcidev)
141{ 262{
142 u8 __iomem *addr; 263 u8 __iomem *addr;
264 int pcicfg_reg;
143 265
144 addr = ioremap_nocache(pci_resource_start(pcidev, 2), 266 addr = ioremap_nocache(pci_resource_start(pcidev, 2),
145 pci_resource_len(pcidev, 2)); 267 pci_resource_len(pcidev, 2));
@@ -156,13 +278,19 @@ static int beiscsi_map_pci_bars(struct beiscsi_hba *phba,
156 phba->db_va = addr; 278 phba->db_va = addr;
157 phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4); 279 phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4);
158 280
159 addr = ioremap_nocache(pci_resource_start(pcidev, 1), 281 if (phba->generation == BE_GEN2)
160 pci_resource_len(pcidev, 1)); 282 pcicfg_reg = 1;
283 else
284 pcicfg_reg = 0;
285
286 addr = ioremap_nocache(pci_resource_start(pcidev, pcicfg_reg),
287 pci_resource_len(pcidev, pcicfg_reg));
288
161 if (addr == NULL) 289 if (addr == NULL)
162 goto pci_map_err; 290 goto pci_map_err;
163 phba->ctrl.pcicfg = addr; 291 phba->ctrl.pcicfg = addr;
164 phba->pci_va = addr; 292 phba->pci_va = addr;
165 phba->pci_pa.u.a64.address = pci_resource_start(pcidev, 1); 293 phba->pci_pa.u.a64.address = pci_resource_start(pcidev, pcicfg_reg);
166 return 0; 294 return 0;
167 295
168pci_map_err: 296pci_map_err:
@@ -181,6 +309,7 @@ static int beiscsi_enable_pci(struct pci_dev *pcidev)
181 return ret; 309 return ret;
182 } 310 }
183 311
312 pci_set_master(pcidev);
184 if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) { 313 if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
185 ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32)); 314 ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
186 if (ret) { 315 if (ret) {
@@ -203,7 +332,6 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
203 status = beiscsi_map_pci_bars(phba, pdev); 332 status = beiscsi_map_pci_bars(phba, pdev);
204 if (status) 333 if (status)
205 return status; 334 return status;
206
207 mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; 335 mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
208 mbox_mem_alloc->va = pci_alloc_consistent(pdev, 336 mbox_mem_alloc->va = pci_alloc_consistent(pdev,
209 mbox_mem_alloc->size, 337 mbox_mem_alloc->size,
@@ -219,34 +347,35 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
219 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); 347 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
220 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); 348 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
221 spin_lock_init(&ctrl->mbox_lock); 349 spin_lock_init(&ctrl->mbox_lock);
350 spin_lock_init(&phba->ctrl.mcc_lock);
351 spin_lock_init(&phba->ctrl.mcc_cq_lock);
352
222 return status; 353 return status;
223} 354}
224 355
225static void beiscsi_get_params(struct beiscsi_hba *phba) 356static void beiscsi_get_params(struct beiscsi_hba *phba)
226{ 357{
227 phba->params.ios_per_ctrl = BE2_IO_DEPTH; 358 phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count
228 phba->params.cxns_per_ctrl = BE2_MAX_SESSIONS; 359 - (phba->fw_config.iscsi_cid_count
229 phba->params.asyncpdus_per_ctrl = BE2_ASYNCPDUS; 360 + BE2_TMFS
230 phba->params.icds_per_ctrl = BE2_MAX_ICDS / 2; 361 + BE2_NOPOUT_REQ));
362 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
363 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
364 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
231 phba->params.num_sge_per_io = BE2_SGE; 365 phba->params.num_sge_per_io = BE2_SGE;
232 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; 366 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
233 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; 367 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ;
234 phba->params.eq_timer = 64; 368 phba->params.eq_timer = 64;
235 phba->params.num_eq_entries = 369 phba->params.num_eq_entries =
236 (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) / 370 (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
237 512) + 1) * 512; 371 + BE2_TMFS) / 512) + 1) * 512;
238 phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024) 372 phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
239 ? 1024 : phba->params.num_eq_entries; 373 ? 1024 : phba->params.num_eq_entries;
240 SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n", 374 SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n",
241 phba->params.num_eq_entries); 375 phba->params.num_eq_entries);
242 phba->params.num_cq_entries = 376 phba->params.num_cq_entries =
243 (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) / 377 (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
244 512) + 1) * 512; 378 + BE2_TMFS) / 512) + 1) * 512;
245 SE_DEBUG(DBG_LVL_8,
246 "phba->params.num_cq_entries=%d BE2_CMDS_PER_CXN=%d"
247 "BE2_LOGOUTS=%d BE2_TMFS=%d BE2_ASYNCPDUS=%d \n",
248 phba->params.num_cq_entries, BE2_CMDS_PER_CXN,
249 BE2_LOGOUTS, BE2_TMFS, BE2_ASYNCPDUS);
250 phba->params.wrbs_per_cxn = 256; 379 phba->params.wrbs_per_cxn = 256;
251} 380}
252 381
@@ -268,6 +397,113 @@ static void hwi_ring_eq_db(struct beiscsi_hba *phba,
268} 397}
269 398
270/** 399/**
400 * be_isr_mcc - The isr routine of the driver.
401 * @irq: Not used
402 * @dev_id: Pointer to host adapter structure
403 */
404static irqreturn_t be_isr_mcc(int irq, void *dev_id)
405{
406 struct beiscsi_hba *phba;
407 struct be_eq_entry *eqe = NULL;
408 struct be_queue_info *eq;
409 struct be_queue_info *mcc;
410 unsigned int num_eq_processed;
411 struct be_eq_obj *pbe_eq;
412 unsigned long flags;
413
414 pbe_eq = dev_id;
415 eq = &pbe_eq->q;
416 phba = pbe_eq->phba;
417 mcc = &phba->ctrl.mcc_obj.cq;
418 eqe = queue_tail_node(eq);
419 if (!eqe)
420 SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
421
422 num_eq_processed = 0;
423
424 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
425 & EQE_VALID_MASK) {
426 if (((eqe->dw[offsetof(struct amap_eq_entry,
427 resource_id) / 32] &
428 EQE_RESID_MASK) >> 16) == mcc->id) {
429 spin_lock_irqsave(&phba->isr_lock, flags);
430 phba->todo_mcc_cq = 1;
431 spin_unlock_irqrestore(&phba->isr_lock, flags);
432 }
433 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
434 queue_tail_inc(eq);
435 eqe = queue_tail_node(eq);
436 num_eq_processed++;
437 }
438 if (phba->todo_mcc_cq)
439 queue_work(phba->wq, &phba->work_cqs);
440 if (num_eq_processed)
441 hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 1, 1);
442
443 return IRQ_HANDLED;
444}
445
446/**
447 * be_isr_msix - The isr routine of the driver.
448 * @irq: Not used
449 * @dev_id: Pointer to host adapter structure
450 */
451static irqreturn_t be_isr_msix(int irq, void *dev_id)
452{
453 struct beiscsi_hba *phba;
454 struct be_eq_entry *eqe = NULL;
455 struct be_queue_info *eq;
456 struct be_queue_info *cq;
457 unsigned int num_eq_processed;
458 struct be_eq_obj *pbe_eq;
459 unsigned long flags;
460
461 pbe_eq = dev_id;
462 eq = &pbe_eq->q;
463 cq = pbe_eq->cq;
464 eqe = queue_tail_node(eq);
465 if (!eqe)
466 SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
467
468 phba = pbe_eq->phba;
469 num_eq_processed = 0;
470 if (blk_iopoll_enabled) {
471 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
472 & EQE_VALID_MASK) {
473 if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
474 blk_iopoll_sched(&pbe_eq->iopoll);
475
476 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
477 queue_tail_inc(eq);
478 eqe = queue_tail_node(eq);
479 num_eq_processed++;
480 }
481 if (num_eq_processed)
482 hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
483
484 return IRQ_HANDLED;
485 } else {
486 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
487 & EQE_VALID_MASK) {
488 spin_lock_irqsave(&phba->isr_lock, flags);
489 phba->todo_cq = 1;
490 spin_unlock_irqrestore(&phba->isr_lock, flags);
491 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
492 queue_tail_inc(eq);
493 eqe = queue_tail_node(eq);
494 num_eq_processed++;
495 }
496 if (phba->todo_cq)
497 queue_work(phba->wq, &phba->work_cqs);
498
499 if (num_eq_processed)
500 hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 1, 1);
501
502 return IRQ_HANDLED;
503 }
504}
505
506/**
271 * be_isr - The isr routine of the driver. 507 * be_isr - The isr routine of the driver.
272 * @irq: Not used 508 * @irq: Not used
273 * @dev_id: Pointer to host adapter structure 509 * @dev_id: Pointer to host adapter structure
@@ -280,48 +516,70 @@ static irqreturn_t be_isr(int irq, void *dev_id)
280 struct be_eq_entry *eqe = NULL; 516 struct be_eq_entry *eqe = NULL;
281 struct be_queue_info *eq; 517 struct be_queue_info *eq;
282 struct be_queue_info *cq; 518 struct be_queue_info *cq;
519 struct be_queue_info *mcc;
283 unsigned long flags, index; 520 unsigned long flags, index;
284 unsigned int num_eq_processed; 521 unsigned int num_mcceq_processed, num_ioeq_processed;
285 struct be_ctrl_info *ctrl; 522 struct be_ctrl_info *ctrl;
523 struct be_eq_obj *pbe_eq;
286 int isr; 524 int isr;
287 525
288 phba = dev_id; 526 phba = dev_id;
289 if (!enable_msix) { 527 ctrl = &phba->ctrl;;
290 ctrl = &phba->ctrl;; 528 isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
291 isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET + 529 (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
292 (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE)); 530 if (!isr)
293 if (!isr) 531 return IRQ_NONE;
294 return IRQ_NONE;
295 }
296 532
297 phwi_ctrlr = phba->phwi_ctrlr; 533 phwi_ctrlr = phba->phwi_ctrlr;
298 phwi_context = phwi_ctrlr->phwi_ctxt; 534 phwi_context = phwi_ctrlr->phwi_ctxt;
299 eq = &phwi_context->be_eq.q; 535 pbe_eq = &phwi_context->be_eq[0];
300 cq = &phwi_context->be_cq; 536
537 eq = &phwi_context->be_eq[0].q;
538 mcc = &phba->ctrl.mcc_obj.cq;
301 index = 0; 539 index = 0;
302 eqe = queue_tail_node(eq); 540 eqe = queue_tail_node(eq);
303 if (!eqe) 541 if (!eqe)
304 SE_DEBUG(DBG_LVL_1, "eqe is NULL\n"); 542 SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
305 543
306 num_eq_processed = 0; 544 num_ioeq_processed = 0;
545 num_mcceq_processed = 0;
307 if (blk_iopoll_enabled) { 546 if (blk_iopoll_enabled) {
308 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] 547 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
309 & EQE_VALID_MASK) { 548 & EQE_VALID_MASK) {
310 if (!blk_iopoll_sched_prep(&phba->iopoll)) 549 if (((eqe->dw[offsetof(struct amap_eq_entry,
311 blk_iopoll_sched(&phba->iopoll); 550 resource_id) / 32] &
312 551 EQE_RESID_MASK) >> 16) == mcc->id) {
552 spin_lock_irqsave(&phba->isr_lock, flags);
553 phba->todo_mcc_cq = 1;
554 spin_unlock_irqrestore(&phba->isr_lock, flags);
555 num_mcceq_processed++;
556 } else {
557 if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
558 blk_iopoll_sched(&pbe_eq->iopoll);
559 num_ioeq_processed++;
560 }
313 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); 561 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
314 queue_tail_inc(eq); 562 queue_tail_inc(eq);
315 eqe = queue_tail_node(eq); 563 eqe = queue_tail_node(eq);
316 num_eq_processed++;
317 SE_DEBUG(DBG_LVL_8, "Valid EQE\n");
318 } 564 }
319 if (num_eq_processed) { 565 if (num_ioeq_processed || num_mcceq_processed) {
320 hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 0, 1); 566 if (phba->todo_mcc_cq)
567 queue_work(phba->wq, &phba->work_cqs);
568
569 if ((num_mcceq_processed) && (!num_ioeq_processed))
570 hwi_ring_eq_db(phba, eq->id, 0,
571 (num_ioeq_processed +
572 num_mcceq_processed) , 1, 1);
573 else
574 hwi_ring_eq_db(phba, eq->id, 0,
575 (num_ioeq_processed +
576 num_mcceq_processed), 0, 1);
577
321 return IRQ_HANDLED; 578 return IRQ_HANDLED;
322 } else 579 } else
323 return IRQ_NONE; 580 return IRQ_NONE;
324 } else { 581 } else {
582 cq = &phwi_context->be_cq[0];
325 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] 583 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
326 & EQE_VALID_MASK) { 584 & EQE_VALID_MASK) {
327 585
@@ -339,13 +597,14 @@ static irqreturn_t be_isr(int irq, void *dev_id)
339 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); 597 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
340 queue_tail_inc(eq); 598 queue_tail_inc(eq);
341 eqe = queue_tail_node(eq); 599 eqe = queue_tail_node(eq);
342 num_eq_processed++; 600 num_ioeq_processed++;
343 } 601 }
344 if (phba->todo_cq || phba->todo_mcc_cq) 602 if (phba->todo_cq || phba->todo_mcc_cq)
345 queue_work(phba->wq, &phba->work_cqs); 603 queue_work(phba->wq, &phba->work_cqs);
346 604
347 if (num_eq_processed) { 605 if (num_ioeq_processed) {
348 hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 1, 1); 606 hwi_ring_eq_db(phba, eq->id, 0,
607 num_ioeq_processed, 1, 1);
349 return IRQ_HANDLED; 608 return IRQ_HANDLED;
350 } else 609 } else
351 return IRQ_NONE; 610 return IRQ_NONE;
@@ -355,13 +614,32 @@ static irqreturn_t be_isr(int irq, void *dev_id)
355static int beiscsi_init_irqs(struct beiscsi_hba *phba) 614static int beiscsi_init_irqs(struct beiscsi_hba *phba)
356{ 615{
357 struct pci_dev *pcidev = phba->pcidev; 616 struct pci_dev *pcidev = phba->pcidev;
358 int ret; 617 struct hwi_controller *phwi_ctrlr;
618 struct hwi_context_memory *phwi_context;
619 int ret, msix_vec, i = 0;
620 char desc[32];
359 621
360 ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, "beiscsi", phba); 622 phwi_ctrlr = phba->phwi_ctrlr;
361 if (ret) { 623 phwi_context = phwi_ctrlr->phwi_ctxt;
362 shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-" 624
363 "Failed to register irq\\n"); 625 if (phba->msix_enabled) {
364 return ret; 626 for (i = 0; i < phba->num_cpus; i++) {
627 sprintf(desc, "beiscsi_msix_%04x", i);
628 msix_vec = phba->msix_entries[i].vector;
629 ret = request_irq(msix_vec, be_isr_msix, 0, desc,
630 &phwi_context->be_eq[i]);
631 }
632 msix_vec = phba->msix_entries[i].vector;
633 ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc",
634 &phwi_context->be_eq[i]);
635 } else {
636 ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED,
637 "beiscsi", phba);
638 if (ret) {
639 shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
640 "Failed to register irq\\n");
641 return ret;
642 }
365 } 643 }
366 return 0; 644 return 0;
367} 645}
@@ -378,15 +656,6 @@ static void hwi_ring_cq_db(struct beiscsi_hba *phba,
378 iowrite32(val, phba->db_va + DB_CQ_OFFSET); 656 iowrite32(val, phba->db_va + DB_CQ_OFFSET);
379} 657}
380 658
381/*
382 * async pdus include
383 * a. unsolicited NOP-In (target initiated NOP-In)
384 * b. Async Messages
385 * c. Reject PDU
386 * d. Login response
387 * These headers arrive unprocessed by the EP firmware and iSCSI layer
388 * process them
389 */
390static unsigned int 659static unsigned int
391beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, 660beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
392 struct beiscsi_hba *phba, 661 struct beiscsi_hba *phba,
@@ -397,6 +666,9 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
397{ 666{
398 struct iscsi_conn *conn = beiscsi_conn->conn; 667 struct iscsi_conn *conn = beiscsi_conn->conn;
399 struct iscsi_session *session = conn->session; 668 struct iscsi_session *session = conn->session;
669 struct iscsi_task *task;
670 struct beiscsi_io_task *io_task;
671 struct iscsi_hdr *login_hdr;
400 672
401 switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] & 673 switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] &
402 PDUBASE_OPCODE_MASK) { 674 PDUBASE_OPCODE_MASK) {
@@ -412,6 +684,11 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
412 SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n"); 684 SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
413 break; 685 break;
414 case ISCSI_OP_LOGIN_RSP: 686 case ISCSI_OP_LOGIN_RSP:
687 case ISCSI_OP_TEXT_RSP:
688 task = conn->login_task;
689 io_task = task->dd_data;
690 login_hdr = (struct iscsi_hdr *)ppdu;
691 login_hdr->itt = io_task->libiscsi_itt;
415 break; 692 break;
416 default: 693 default:
417 shost_printk(KERN_WARNING, phba->shost, 694 shost_printk(KERN_WARNING, phba->shost,
@@ -440,7 +717,8 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
440 io_sgl_alloc_index]; 717 io_sgl_alloc_index];
441 phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL; 718 phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL;
442 phba->io_sgl_hndl_avbl--; 719 phba->io_sgl_hndl_avbl--;
443 if (phba->io_sgl_alloc_index == (phba->params.ios_per_ctrl - 1)) 720 if (phba->io_sgl_alloc_index == (phba->params.
721 ios_per_ctrl - 1))
444 phba->io_sgl_alloc_index = 0; 722 phba->io_sgl_alloc_index = 0;
445 else 723 else
446 phba->io_sgl_alloc_index++; 724 phba->io_sgl_alloc_index++;
@@ -477,22 +755,31 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
477 * alloc_wrb_handle - To allocate a wrb handle 755 * alloc_wrb_handle - To allocate a wrb handle
478 * @phba: The hba pointer 756 * @phba: The hba pointer
479 * @cid: The cid to use for allocation 757 * @cid: The cid to use for allocation
480 * @index: index allocation and wrb index
481 * 758 *
482 * This happens under session_lock until submission to chip 759 * This happens under session_lock until submission to chip
483 */ 760 */
484struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, 761struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
485 int index)
486{ 762{
487 struct hwi_wrb_context *pwrb_context; 763 struct hwi_wrb_context *pwrb_context;
488 struct hwi_controller *phwi_ctrlr; 764 struct hwi_controller *phwi_ctrlr;
489 struct wrb_handle *pwrb_handle; 765 struct wrb_handle *pwrb_handle, *pwrb_handle_tmp;
490 766
491 phwi_ctrlr = phba->phwi_ctrlr; 767 phwi_ctrlr = phba->phwi_ctrlr;
492 pwrb_context = &phwi_ctrlr->wrb_context[cid]; 768 pwrb_context = &phwi_ctrlr->wrb_context[cid];
493 pwrb_handle = pwrb_context->pwrb_handle_base[index]; 769 if (pwrb_context->wrb_handles_available >= 2) {
494 pwrb_handle->wrb_index = index; 770 pwrb_handle = pwrb_context->pwrb_handle_base[
495 pwrb_handle->nxt_wrb_index = index; 771 pwrb_context->alloc_index];
772 pwrb_context->wrb_handles_available--;
773 if (pwrb_context->alloc_index ==
774 (phba->params.wrbs_per_cxn - 1))
775 pwrb_context->alloc_index = 0;
776 else
777 pwrb_context->alloc_index++;
778 pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
779 pwrb_context->alloc_index];
780 pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
781 } else
782 pwrb_handle = NULL;
496 return pwrb_handle; 783 return pwrb_handle;
497} 784}
498 785
@@ -508,11 +795,18 @@ static void
508free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, 795free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
509 struct wrb_handle *pwrb_handle) 796 struct wrb_handle *pwrb_handle)
510{ 797{
798 pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
799 pwrb_context->wrb_handles_available++;
800 if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
801 pwrb_context->free_index = 0;
802 else
803 pwrb_context->free_index++;
804
511 SE_DEBUG(DBG_LVL_8, 805 SE_DEBUG(DBG_LVL_8,
512 "FREE WRB: pwrb_handle=%p free_index=%d=0x%x" 806 "FREE WRB: pwrb_handle=%p free_index=0x%x"
513 "wrb_handles_available=%d \n", 807 "wrb_handles_available=%d \n",
514 pwrb_handle, pwrb_context->free_index, 808 pwrb_handle, pwrb_context->free_index,
515 pwrb_context->free_index, pwrb_context->wrb_handles_available); 809 pwrb_context->wrb_handles_available);
516} 810}
517 811
518static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) 812static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
@@ -540,6 +834,8 @@ void
540free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) 834free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
541{ 835{
542 836
837 SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d \n",
838 phba->eh_sgl_free_index);
543 if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) { 839 if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) {
544 /* 840 /*
545 * this can happen if clean_task is called on a task that 841 * this can happen if clean_task is called on a task that
@@ -572,10 +868,10 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
572 u32 resid = 0, exp_cmdsn, max_cmdsn; 868 u32 resid = 0, exp_cmdsn, max_cmdsn;
573 u8 rsp, status, flags; 869 u8 rsp, status, flags;
574 870
575 exp_cmdsn = be32_to_cpu(psol-> 871 exp_cmdsn = (psol->
576 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] 872 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
577 & SOL_EXP_CMD_SN_MASK); 873 & SOL_EXP_CMD_SN_MASK);
578 max_cmdsn = be32_to_cpu((psol-> 874 max_cmdsn = ((psol->
579 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] 875 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
580 & SOL_EXP_CMD_SN_MASK) + 876 & SOL_EXP_CMD_SN_MASK) +
581 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) 877 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
@@ -610,18 +906,19 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
610 } 906 }
611 907
612 if (status == SAM_STAT_CHECK_CONDITION) { 908 if (status == SAM_STAT_CHECK_CONDITION) {
909 unsigned short *slen = (unsigned short *)sts_bhs->sense_info;
613 sense = sts_bhs->sense_info + sizeof(unsigned short); 910 sense = sts_bhs->sense_info + sizeof(unsigned short);
614 sense_len = 911 sense_len = cpu_to_be16(*slen);
615 cpu_to_be16((unsigned short)(sts_bhs->sense_info[0]));
616 memcpy(task->sc->sense_buffer, sense, 912 memcpy(task->sc->sense_buffer, sense,
617 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); 913 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
618 } 914 }
915
619 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { 916 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
620 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] 917 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
621 & SOL_RES_CNT_MASK) 918 & SOL_RES_CNT_MASK)
622 conn->rxdata_octets += (psol-> 919 conn->rxdata_octets += (psol->
623 dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] 920 dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
624 & SOL_RES_CNT_MASK); 921 & SOL_RES_CNT_MASK);
625 } 922 }
626unmap: 923unmap:
627 scsi_dma_unmap(io_task->scsi_cmnd); 924 scsi_dma_unmap(io_task->scsi_cmnd);
@@ -633,9 +930,11 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
633 struct iscsi_task *task, struct sol_cqe *psol) 930 struct iscsi_task *task, struct sol_cqe *psol)
634{ 931{
635 struct iscsi_logout_rsp *hdr; 932 struct iscsi_logout_rsp *hdr;
933 struct beiscsi_io_task *io_task = task->dd_data;
636 struct iscsi_conn *conn = beiscsi_conn->conn; 934 struct iscsi_conn *conn = beiscsi_conn->conn;
637 935
638 hdr = (struct iscsi_logout_rsp *)task->hdr; 936 hdr = (struct iscsi_logout_rsp *)task->hdr;
937 hdr->opcode = ISCSI_OP_LOGOUT_RSP;
639 hdr->t2wait = 5; 938 hdr->t2wait = 5;
640 hdr->t2retain = 0; 939 hdr->t2retain = 0;
641 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 940 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -650,8 +949,11 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
650 & SOL_EXP_CMD_SN_MASK) + 949 & SOL_EXP_CMD_SN_MASK) +
651 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) 950 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
652 / 32] & SOL_CMD_WND_MASK) >> 24) - 1); 951 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
952 hdr->dlength[0] = 0;
953 hdr->dlength[1] = 0;
954 hdr->dlength[2] = 0;
653 hdr->hlength = 0; 955 hdr->hlength = 0;
654 956 hdr->itt = io_task->libiscsi_itt;
655 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); 957 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
656} 958}
657 959
@@ -661,18 +963,21 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
661{ 963{
662 struct iscsi_tm_rsp *hdr; 964 struct iscsi_tm_rsp *hdr;
663 struct iscsi_conn *conn = beiscsi_conn->conn; 965 struct iscsi_conn *conn = beiscsi_conn->conn;
966 struct beiscsi_io_task *io_task = task->dd_data;
664 967
665 hdr = (struct iscsi_tm_rsp *)task->hdr; 968 hdr = (struct iscsi_tm_rsp *)task->hdr;
969 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
666 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 970 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
667 & SOL_FLAGS_MASK) >> 24) | 0x80; 971 & SOL_FLAGS_MASK) >> 24) | 0x80;
668 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 972 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
669 32] & SOL_RESP_MASK); 973 32] & SOL_RESP_MASK);
670 hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, 974 hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
671 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); 975 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
672 hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe, 976 hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
673 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) + 977 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
674 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) 978 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
675 / 32] & SOL_CMD_WND_MASK) >> 24) - 1); 979 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
980 hdr->itt = io_task->libiscsi_itt;
676 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); 981 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
677} 982}
678 983
@@ -681,18 +986,27 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
681 struct beiscsi_hba *phba, struct sol_cqe *psol) 986 struct beiscsi_hba *phba, struct sol_cqe *psol)
682{ 987{
683 struct hwi_wrb_context *pwrb_context; 988 struct hwi_wrb_context *pwrb_context;
684 struct wrb_handle *pwrb_handle; 989 struct wrb_handle *pwrb_handle = NULL;
685 struct hwi_controller *phwi_ctrlr; 990 struct hwi_controller *phwi_ctrlr;
991 struct iscsi_task *task;
992 struct beiscsi_io_task *io_task;
686 struct iscsi_conn *conn = beiscsi_conn->conn; 993 struct iscsi_conn *conn = beiscsi_conn->conn;
687 struct iscsi_session *session = conn->session; 994 struct iscsi_session *session = conn->session;
688 995
689 phwi_ctrlr = phba->phwi_ctrlr; 996 phwi_ctrlr = phba->phwi_ctrlr;
690 pwrb_context = &phwi_ctrlr->wrb_context[((psol-> 997 pwrb_context = &phwi_ctrlr->wrb_context[((psol->
691 dw[offsetof(struct amap_sol_cqe, cid) / 32] & 998 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
692 SOL_CID_MASK) >> 6)]; 999 SOL_CID_MASK) >> 6) -
1000 phba->fw_config.iscsi_cid_start];
693 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> 1001 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
694 dw[offsetof(struct amap_sol_cqe, wrb_index) / 1002 dw[offsetof(struct amap_sol_cqe, wrb_index) /
695 32] & SOL_WRB_INDEX_MASK) >> 16)]; 1003 32] & SOL_WRB_INDEX_MASK) >> 16)];
1004 task = pwrb_handle->pio_handle;
1005
1006 io_task = task->dd_data;
1007 spin_lock(&phba->mgmt_sgl_lock);
1008 free_mgmt_sgl_handle(phba, io_task->psgl_handle);
1009 spin_unlock(&phba->mgmt_sgl_lock);
696 spin_lock_bh(&session->lock); 1010 spin_lock_bh(&session->lock);
697 free_wrb_handle(phba, pwrb_context, pwrb_handle); 1011 free_wrb_handle(phba, pwrb_context, pwrb_handle);
698 spin_unlock_bh(&session->lock); 1012 spin_unlock_bh(&session->lock);
@@ -704,6 +1018,7 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
704{ 1018{
705 struct iscsi_nopin *hdr; 1019 struct iscsi_nopin *hdr;
706 struct iscsi_conn *conn = beiscsi_conn->conn; 1020 struct iscsi_conn *conn = beiscsi_conn->conn;
1021 struct beiscsi_io_task *io_task = task->dd_data;
707 1022
708 hdr = (struct iscsi_nopin *)task->hdr; 1023 hdr = (struct iscsi_nopin *)task->hdr;
709 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] 1024 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -715,6 +1030,7 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
715 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) 1030 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
716 / 32] & SOL_CMD_WND_MASK) >> 24) - 1); 1031 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
717 hdr->opcode = ISCSI_OP_NOOP_IN; 1032 hdr->opcode = ISCSI_OP_NOOP_IN;
1033 hdr->itt = io_task->libiscsi_itt;
718 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); 1034 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
719} 1035}
720 1036
@@ -726,36 +1042,40 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
726 struct iscsi_wrb *pwrb = NULL; 1042 struct iscsi_wrb *pwrb = NULL;
727 struct hwi_controller *phwi_ctrlr; 1043 struct hwi_controller *phwi_ctrlr;
728 struct iscsi_task *task; 1044 struct iscsi_task *task;
729 struct beiscsi_io_task *io_task; 1045 unsigned int type;
730 struct iscsi_conn *conn = beiscsi_conn->conn; 1046 struct iscsi_conn *conn = beiscsi_conn->conn;
731 struct iscsi_session *session = conn->session; 1047 struct iscsi_session *session = conn->session;
732 1048
733 phwi_ctrlr = phba->phwi_ctrlr; 1049 phwi_ctrlr = phba->phwi_ctrlr;
734 1050 pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof
735 pwrb_context = &phwi_ctrlr-> 1051 (struct amap_sol_cqe, cid) / 32]
736 wrb_context[((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32] 1052 & SOL_CID_MASK) >> 6) -
737 & SOL_CID_MASK) >> 6)]; 1053 phba->fw_config.iscsi_cid_start];
738 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> 1054 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
739 dw[offsetof(struct amap_sol_cqe, wrb_index) / 1055 dw[offsetof(struct amap_sol_cqe, wrb_index) /
740 32] & SOL_WRB_INDEX_MASK) >> 16)]; 1056 32] & SOL_WRB_INDEX_MASK) >> 16)];
741
742 task = pwrb_handle->pio_handle; 1057 task = pwrb_handle->pio_handle;
743 io_task = task->dd_data;
744 spin_lock_bh(&session->lock);
745 pwrb = pwrb_handle->pwrb; 1058 pwrb = pwrb_handle->pwrb;
746 switch ((pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & 1059 type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
747 WRB_TYPE_MASK) >> 28) { 1060 WRB_TYPE_MASK) >> 28;
1061
1062 spin_lock_bh(&session->lock);
1063 switch (type) {
748 case HWH_TYPE_IO: 1064 case HWH_TYPE_IO:
749 case HWH_TYPE_IO_RD: 1065 case HWH_TYPE_IO_RD:
750 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == 1066 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
751 ISCSI_OP_NOOP_OUT) { 1067 ISCSI_OP_NOOP_OUT)
752 be_complete_nopin_resp(beiscsi_conn, task, psol); 1068 be_complete_nopin_resp(beiscsi_conn, task, psol);
753 } else 1069 else
754 be_complete_io(beiscsi_conn, task, psol); 1070 be_complete_io(beiscsi_conn, task, psol);
755 break; 1071 break;
756 1072
757 case HWH_TYPE_LOGOUT: 1073 case HWH_TYPE_LOGOUT:
758 be_complete_logout(beiscsi_conn, task, psol); 1074 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
1075 be_complete_logout(beiscsi_conn, task, psol);
1076 else
1077 be_complete_tmf(beiscsi_conn, task, psol);
1078
759 break; 1079 break;
760 1080
761 case HWH_TYPE_LOGIN: 1081 case HWH_TYPE_LOGIN:
@@ -764,21 +1084,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
764 "- Solicited path \n"); 1084 "- Solicited path \n");
765 break; 1085 break;
766 1086
767 case HWH_TYPE_TMF:
768 be_complete_tmf(beiscsi_conn, task, psol);
769 break;
770
771 case HWH_TYPE_NOP: 1087 case HWH_TYPE_NOP:
772 be_complete_nopin_resp(beiscsi_conn, task, psol); 1088 be_complete_nopin_resp(beiscsi_conn, task, psol);
773 break; 1089 break;
774 1090
775 default: 1091 default:
776 shost_printk(KERN_WARNING, phba->shost, 1092 shost_printk(KERN_WARNING, phba->shost,
777 "wrb_index 0x%x CID 0x%x\n", 1093 "In hwi_complete_cmd, unknown type = %d"
778 ((psol->dw[offsetof(struct amap_iscsi_wrb, type) / 1094 "wrb_index 0x%x CID 0x%x\n", type,
779 32] & SOL_WRB_INDEX_MASK) >> 16), 1095 ((psol->dw[offsetof(struct amap_iscsi_wrb,
780 ((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32] 1096 type) / 32] & SOL_WRB_INDEX_MASK) >> 16),
781 & SOL_CID_MASK) >> 6)); 1097 ((psol->dw[offsetof(struct amap_sol_cqe,
1098 cid) / 32] & SOL_CID_MASK) >> 6));
782 break; 1099 break;
783 } 1100 }
784 1101
@@ -863,7 +1180,8 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
863 1180
864 WARN_ON(!pasync_handle); 1181 WARN_ON(!pasync_handle);
865 1182
866 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid; 1183 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid -
1184 phba->fw_config.iscsi_cid_start;
867 pasync_handle->is_header = is_header; 1185 pasync_handle->is_header = is_header;
868 pasync_handle->buffer_len = ((pdpdu_cqe-> 1186 pasync_handle->buffer_len = ((pdpdu_cqe->
869 dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] 1187 dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
@@ -1113,9 +1431,10 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn,
1113 } 1431 }
1114 1432
1115 status = beiscsi_process_async_pdu(beiscsi_conn, phba, 1433 status = beiscsi_process_async_pdu(beiscsi_conn, phba,
1116 beiscsi_conn->beiscsi_conn_cid, 1434 (beiscsi_conn->beiscsi_conn_cid -
1117 phdr, hdr_len, pfirst_buffer, 1435 phba->fw_config.iscsi_cid_start),
1118 buf_len); 1436 phdr, hdr_len, pfirst_buffer,
1437 buf_len);
1119 1438
1120 if (status == 0) 1439 if (status == 0)
1121 hwi_free_async_msg(phba, cri); 1440 hwi_free_async_msg(phba, cri);
@@ -1208,40 +1527,79 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn,
1208 hwi_post_async_buffers(phba, pasync_handle->is_header); 1527 hwi_post_async_buffers(phba, pasync_handle->is_header);
1209} 1528}
1210 1529
1211static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) 1530static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
1531{
1532 struct be_queue_info *mcc_cq;
1533 struct be_mcc_compl *mcc_compl;
1534 unsigned int num_processed = 0;
1535
1536 mcc_cq = &phba->ctrl.mcc_obj.cq;
1537 mcc_compl = queue_tail_node(mcc_cq);
1538 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1539 while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
1540
1541 if (num_processed >= 32) {
1542 hwi_ring_cq_db(phba, mcc_cq->id,
1543 num_processed, 0, 0);
1544 num_processed = 0;
1545 }
1546 if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
1547 /* Interpret flags as an async trailer */
1548 if (is_link_state_evt(mcc_compl->flags))
1549 /* Interpret compl as a async link evt */
1550 beiscsi_async_link_state_process(phba,
1551 (struct be_async_event_link_state *) mcc_compl);
1552 else
1553 SE_DEBUG(DBG_LVL_1,
1554 " Unsupported Async Event, flags"
1555 " = 0x%08x \n", mcc_compl->flags);
1556 } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
1557 be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
1558 atomic_dec(&phba->ctrl.mcc_obj.q.used);
1559 }
1560
1561 mcc_compl->flags = 0;
1562 queue_tail_inc(mcc_cq);
1563 mcc_compl = queue_tail_node(mcc_cq);
1564 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1565 num_processed++;
1566 }
1567
1568 if (num_processed > 0)
1569 hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
1570
1571}
1572
1573static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1212{ 1574{
1213 struct hwi_controller *phwi_ctrlr;
1214 struct hwi_context_memory *phwi_context;
1215 struct be_queue_info *cq; 1575 struct be_queue_info *cq;
1216 struct sol_cqe *sol; 1576 struct sol_cqe *sol;
1217 struct dmsg_cqe *dmsg; 1577 struct dmsg_cqe *dmsg;
1218 unsigned int num_processed = 0; 1578 unsigned int num_processed = 0;
1219 unsigned int tot_nump = 0; 1579 unsigned int tot_nump = 0;
1220 struct beiscsi_conn *beiscsi_conn; 1580 struct beiscsi_conn *beiscsi_conn;
1581 struct beiscsi_endpoint *beiscsi_ep;
1582 struct iscsi_endpoint *ep;
1583 struct beiscsi_hba *phba;
1221 1584
1222 phwi_ctrlr = phba->phwi_ctrlr; 1585 cq = pbe_eq->cq;
1223 phwi_context = phwi_ctrlr->phwi_ctxt;
1224 cq = &phwi_context->be_cq;
1225 sol = queue_tail_node(cq); 1586 sol = queue_tail_node(cq);
1587 phba = pbe_eq->phba;
1226 1588
1227 while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] & 1589 while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] &
1228 CQE_VALID_MASK) { 1590 CQE_VALID_MASK) {
1229 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); 1591 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
1230 1592
1231 beiscsi_conn = phba->conn_table[(u32) (sol-> 1593 ep = phba->ep_array[(u32) ((sol->
1232 dw[offsetof(struct amap_sol_cqe, cid) / 32] & 1594 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
1233 SOL_CID_MASK) >> 6]; 1595 SOL_CID_MASK) >> 6) -
1596 phba->fw_config.iscsi_cid_start];
1234 1597
1235 if (!beiscsi_conn || !beiscsi_conn->ep) { 1598 beiscsi_ep = ep->dd_data;
1236 shost_printk(KERN_WARNING, phba->shost, 1599 beiscsi_conn = beiscsi_ep->conn;
1237 "Connection table empty for cid = %d\n",
1238 (u32)(sol->dw[offsetof(struct amap_sol_cqe,
1239 cid) / 32] & SOL_CID_MASK) >> 6);
1240 return 0;
1241 }
1242 1600
1243 if (num_processed >= 32) { 1601 if (num_processed >= 32) {
1244 hwi_ring_cq_db(phba, phwi_context->be_cq.id, 1602 hwi_ring_cq_db(phba, cq->id,
1245 num_processed, 0, 0); 1603 num_processed, 0, 0);
1246 tot_nump += num_processed; 1604 tot_nump += num_processed;
1247 num_processed = 0; 1605 num_processed = 0;
@@ -1258,8 +1616,12 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
1258 hwi_complete_drvr_msgs(beiscsi_conn, phba, sol); 1616 hwi_complete_drvr_msgs(beiscsi_conn, phba, sol);
1259 break; 1617 break;
1260 case UNSOL_HDR_NOTIFY: 1618 case UNSOL_HDR_NOTIFY:
1619 SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR_ NOTIFY\n");
1620 hwi_process_default_pdu_ring(beiscsi_conn, phba,
1621 (struct i_t_dpdu_cqe *)sol);
1622 break;
1261 case UNSOL_DATA_NOTIFY: 1623 case UNSOL_DATA_NOTIFY:
1262 SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR/DATA_NOTIFY\n"); 1624 SE_DEBUG(DBG_LVL_8, "Received UNSOL_DATA_NOTIFY\n");
1263 hwi_process_default_pdu_ring(beiscsi_conn, phba, 1625 hwi_process_default_pdu_ring(beiscsi_conn, phba,
1264 (struct i_t_dpdu_cqe *)sol); 1626 (struct i_t_dpdu_cqe *)sol);
1265 break; 1627 break;
@@ -1306,23 +1668,23 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
1306 case CXN_KILLED_OVER_RUN_RESIDUAL: 1668 case CXN_KILLED_OVER_RUN_RESIDUAL:
1307 case CXN_KILLED_UNDER_RUN_RESIDUAL: 1669 case CXN_KILLED_UNDER_RUN_RESIDUAL:
1308 case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: 1670 case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
1309 SE_DEBUG(DBG_LVL_1, "CQ Error %d, resetting CID " 1671 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
1310 "0x%x...\n", 1672 "0x%x...\n",
1311 sol->dw[offsetof(struct amap_sol_cqe, code) / 1673 sol->dw[offsetof(struct amap_sol_cqe, code) /
1312 32] & CQE_CODE_MASK, 1674 32] & CQE_CODE_MASK,
1313 sol->dw[offsetof(struct amap_sol_cqe, cid) / 1675 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1314 32] & CQE_CID_MASK); 1676 32] & CQE_CID_MASK));
1315 iscsi_conn_failure(beiscsi_conn->conn, 1677 iscsi_conn_failure(beiscsi_conn->conn,
1316 ISCSI_ERR_CONN_FAILED); 1678 ISCSI_ERR_CONN_FAILED);
1317 break; 1679 break;
1318 case CXN_KILLED_RST_SENT: 1680 case CXN_KILLED_RST_SENT:
1319 case CXN_KILLED_RST_RCVD: 1681 case CXN_KILLED_RST_RCVD:
1320 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset received/sent " 1682 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
1321 "on CID 0x%x...\n", 1683 "received/sent on CID 0x%x...\n",
1322 sol->dw[offsetof(struct amap_sol_cqe, code) / 1684 sol->dw[offsetof(struct amap_sol_cqe, code) /
1323 32] & CQE_CODE_MASK, 1685 32] & CQE_CODE_MASK,
1324 sol->dw[offsetof(struct amap_sol_cqe, cid) / 1686 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1325 32] & CQE_CID_MASK); 1687 32] & CQE_CID_MASK));
1326 iscsi_conn_failure(beiscsi_conn->conn, 1688 iscsi_conn_failure(beiscsi_conn->conn,
1327 ISCSI_ERR_CONN_FAILED); 1689 ISCSI_ERR_CONN_FAILED);
1328 break; 1690 break;
@@ -1331,8 +1693,8 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
1331 "received on CID 0x%x...\n", 1693 "received on CID 0x%x...\n",
1332 sol->dw[offsetof(struct amap_sol_cqe, code) / 1694 sol->dw[offsetof(struct amap_sol_cqe, code) /
1333 32] & CQE_CODE_MASK, 1695 32] & CQE_CODE_MASK,
1334 sol->dw[offsetof(struct amap_sol_cqe, cid) / 1696 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1335 32] & CQE_CID_MASK); 1697 32] & CQE_CID_MASK));
1336 break; 1698 break;
1337 } 1699 }
1338 1700
@@ -1344,30 +1706,39 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
1344 1706
1345 if (num_processed > 0) { 1707 if (num_processed > 0) {
1346 tot_nump += num_processed; 1708 tot_nump += num_processed;
1347 hwi_ring_cq_db(phba, phwi_context->be_cq.id, num_processed, 1709 hwi_ring_cq_db(phba, cq->id, num_processed, 1, 0);
1348 1, 0);
1349 } 1710 }
1350 return tot_nump; 1711 return tot_nump;
1351} 1712}
1352 1713
1353static void beiscsi_process_all_cqs(struct work_struct *work) 1714void beiscsi_process_all_cqs(struct work_struct *work)
1354{ 1715{
1355 unsigned long flags; 1716 unsigned long flags;
1717 struct hwi_controller *phwi_ctrlr;
1718 struct hwi_context_memory *phwi_context;
1719 struct be_eq_obj *pbe_eq;
1356 struct beiscsi_hba *phba = 1720 struct beiscsi_hba *phba =
1357 container_of(work, struct beiscsi_hba, work_cqs); 1721 container_of(work, struct beiscsi_hba, work_cqs);
1358 1722
1723 phwi_ctrlr = phba->phwi_ctrlr;
1724 phwi_context = phwi_ctrlr->phwi_ctxt;
1725 if (phba->msix_enabled)
1726 pbe_eq = &phwi_context->be_eq[phba->num_cpus];
1727 else
1728 pbe_eq = &phwi_context->be_eq[0];
1729
1359 if (phba->todo_mcc_cq) { 1730 if (phba->todo_mcc_cq) {
1360 spin_lock_irqsave(&phba->isr_lock, flags); 1731 spin_lock_irqsave(&phba->isr_lock, flags);
1361 phba->todo_mcc_cq = 0; 1732 phba->todo_mcc_cq = 0;
1362 spin_unlock_irqrestore(&phba->isr_lock, flags); 1733 spin_unlock_irqrestore(&phba->isr_lock, flags);
1363 SE_DEBUG(DBG_LVL_1, "MCC Interrupt Not expected \n"); 1734 beiscsi_process_mcc_isr(phba);
1364 } 1735 }
1365 1736
1366 if (phba->todo_cq) { 1737 if (phba->todo_cq) {
1367 spin_lock_irqsave(&phba->isr_lock, flags); 1738 spin_lock_irqsave(&phba->isr_lock, flags);
1368 phba->todo_cq = 0; 1739 phba->todo_cq = 0;
1369 spin_unlock_irqrestore(&phba->isr_lock, flags); 1740 spin_unlock_irqrestore(&phba->isr_lock, flags);
1370 beiscsi_process_cq(phba); 1741 beiscsi_process_cq(pbe_eq);
1371 } 1742 }
1372} 1743}
1373 1744
@@ -1375,19 +1746,15 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)
1375{ 1746{
1376 static unsigned int ret; 1747 static unsigned int ret;
1377 struct beiscsi_hba *phba; 1748 struct beiscsi_hba *phba;
1749 struct be_eq_obj *pbe_eq;
1378 1750
1379 phba = container_of(iop, struct beiscsi_hba, iopoll); 1751 pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
1380 1752 ret = beiscsi_process_cq(pbe_eq);
1381 ret = beiscsi_process_cq(phba);
1382 if (ret < budget) { 1753 if (ret < budget) {
1383 struct hwi_controller *phwi_ctrlr; 1754 phba = pbe_eq->phba;
1384 struct hwi_context_memory *phwi_context;
1385
1386 phwi_ctrlr = phba->phwi_ctrlr;
1387 phwi_context = phwi_ctrlr->phwi_ctxt;
1388 blk_iopoll_complete(iop); 1755 blk_iopoll_complete(iop);
1389 hwi_ring_eq_db(phba, phwi_context->be_eq.q.id, 0, 1756 SE_DEBUG(DBG_LVL_8, "rearm pbe_eq->q.id =%d\n", pbe_eq->q.id);
1390 0, 1, 1); 1757 hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
1391 } 1758 }
1392 return ret; 1759 return ret;
1393} 1760}
@@ -1409,7 +1776,8 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1409 io_task->bhs_pa.u.a32.address_hi); 1776 io_task->bhs_pa.u.a32.address_hi);
1410 1777
1411 l_sg = sg; 1778 l_sg = sg;
1412 for (index = 0; (index < num_sg) && (index < 2); index++, sg_next(sg)) { 1779 for (index = 0; (index < num_sg) && (index < 2); index++,
1780 sg = sg_next(sg)) {
1413 if (index == 0) { 1781 if (index == 0) {
1414 sg_len = sg_dma_len(sg); 1782 sg_len = sg_dma_len(sg);
1415 addr = (u64) sg_dma_address(sg); 1783 addr = (u64) sg_dma_address(sg);
@@ -1420,11 +1788,7 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1420 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, 1788 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
1421 sg_len); 1789 sg_len);
1422 sge_len = sg_len; 1790 sge_len = sg_len;
1423 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1424 1);
1425 } else { 1791 } else {
1426 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1427 0);
1428 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset, 1792 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset,
1429 pwrb, sge_len); 1793 pwrb, sge_len);
1430 sg_len = sg_dma_len(sg); 1794 sg_len = sg_dma_len(sg);
@@ -1447,13 +1811,27 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1447 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, 1811 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
1448 io_task->bhs_pa.u.a32.address_lo); 1812 io_task->bhs_pa.u.a32.address_lo);
1449 1813
1450 if (num_sg == 2) 1814 if (num_sg == 1) {
1451 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, 1); 1815 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1816 1);
1817 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
1818 0);
1819 } else if (num_sg == 2) {
1820 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1821 0);
1822 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
1823 1);
1824 } else {
1825 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1826 0);
1827 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb,
1828 0);
1829 }
1452 sg = l_sg; 1830 sg = l_sg;
1453 psgl++; 1831 psgl++;
1454 psgl++; 1832 psgl++;
1455 offset = 0; 1833 offset = 0;
1456 for (index = 0; index < num_sg; index++, sg_next(sg), psgl++) { 1834 for (index = 0; index < num_sg; index++, sg = sg_next(sg), psgl++) {
1457 sg_len = sg_dma_len(sg); 1835 sg_len = sg_dma_len(sg);
1458 addr = (u64) sg_dma_address(sg); 1836 addr = (u64) sg_dma_address(sg);
1459 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, 1837 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
@@ -1537,14 +1915,12 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
1537 1915
1538static void beiscsi_find_mem_req(struct beiscsi_hba *phba) 1916static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
1539{ 1917{
1540 unsigned int num_cq_pages, num_eq_pages, num_async_pdu_buf_pages; 1918 unsigned int num_cq_pages, num_async_pdu_buf_pages;
1541 unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn; 1919 unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn;
1542 unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages; 1920 unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages;
1543 1921
1544 num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ 1922 num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
1545 sizeof(struct sol_cqe)); 1923 sizeof(struct sol_cqe));
1546 num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
1547 sizeof(struct be_eq_entry));
1548 num_async_pdu_buf_pages = 1924 num_async_pdu_buf_pages =
1549 PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ 1925 PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
1550 phba->params.defpdu_hdr_sz); 1926 phba->params.defpdu_hdr_sz);
@@ -1565,8 +1941,6 @@ static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
1565 phba->mem_req[HWI_MEM_ADDN_CONTEXT] = 1941 phba->mem_req[HWI_MEM_ADDN_CONTEXT] =
1566 sizeof(struct hwi_context_memory); 1942 sizeof(struct hwi_context_memory);
1567 1943
1568 phba->mem_req[HWI_MEM_CQ] = num_cq_pages * PAGE_SIZE;
1569 phba->mem_req[HWI_MEM_EQ] = num_eq_pages * PAGE_SIZE;
1570 1944
1571 phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb) 1945 phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb)
1572 * (phba->params.wrbs_per_cxn) 1946 * (phba->params.wrbs_per_cxn)
@@ -1751,8 +2125,6 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
1751 2125
1752 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { 2126 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
1753 pwrb_context = &phwi_ctrlr->wrb_context[index]; 2127 pwrb_context = &phwi_ctrlr->wrb_context[index];
1754 SE_DEBUG(DBG_LVL_8, "cid=%d pwrb_context=%p \n", index,
1755 pwrb_context);
1756 pwrb_context->pwrb_handle_base = 2128 pwrb_context->pwrb_handle_base =
1757 kzalloc(sizeof(struct wrb_handle *) * 2129 kzalloc(sizeof(struct wrb_handle *) *
1758 phba->params.wrbs_per_cxn, GFP_KERNEL); 2130 phba->params.wrbs_per_cxn, GFP_KERNEL);
@@ -1767,6 +2139,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
1767 pwrb_context->pwrb_handle_basestd[j] = 2139 pwrb_context->pwrb_handle_basestd[j] =
1768 pwrb_handle; 2140 pwrb_handle;
1769 pwrb_context->wrb_handles_available++; 2141 pwrb_context->wrb_handles_available++;
2142 pwrb_handle->wrb_index = j;
1770 pwrb_handle++; 2143 pwrb_handle++;
1771 } 2144 }
1772 pwrb_context->free_index = 0; 2145 pwrb_context->free_index = 0;
@@ -1785,6 +2158,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
1785 pwrb_context->pwrb_handle_basestd[j] = 2158 pwrb_context->pwrb_handle_basestd[j] =
1786 pwrb_handle; 2159 pwrb_handle;
1787 pwrb_context->wrb_handles_available++; 2160 pwrb_context->wrb_handles_available++;
2161 pwrb_handle->wrb_index = j;
1788 pwrb_handle++; 2162 pwrb_handle++;
1789 } 2163 }
1790 pwrb_context->free_index = 0; 2164 pwrb_context->free_index = 0;
@@ -1793,11 +2167,10 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
1793 } 2167 }
1794 idx = 0; 2168 idx = 0;
1795 pwrb = mem_descr_wrb->mem_array[idx].virtual_address; 2169 pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
1796 num_cxn_wrb = 2170 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
1797 ((mem_descr_wrb->mem_array[idx].size) / (sizeof(struct iscsi_wrb)) * 2171 ((sizeof(struct iscsi_wrb) *
1798 phba->params.wrbs_per_cxn); 2172 phba->params.wrbs_per_cxn));
1799 2173 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
1800 for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
1801 pwrb_context = &phwi_ctrlr->wrb_context[index]; 2174 pwrb_context = &phwi_ctrlr->wrb_context[index];
1802 if (num_cxn_wrb) { 2175 if (num_cxn_wrb) {
1803 for (j = 0; j < phba->params.wrbs_per_cxn; j++) { 2176 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -1809,9 +2182,9 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
1809 } else { 2182 } else {
1810 idx++; 2183 idx++;
1811 pwrb = mem_descr_wrb->mem_array[idx].virtual_address; 2184 pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
1812 num_cxn_wrb = ((mem_descr_wrb->mem_array[idx].size) / 2185 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
1813 (sizeof(struct iscsi_wrb)) * 2186 ((sizeof(struct iscsi_wrb) *
1814 phba->params.wrbs_per_cxn); 2187 phba->params.wrbs_per_cxn));
1815 for (j = 0; j < phba->params.wrbs_per_cxn; j++) { 2188 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
1816 pwrb_handle = pwrb_context->pwrb_handle_base[j]; 2189 pwrb_handle = pwrb_context->pwrb_handle_base[j];
1817 pwrb_handle->pwrb = pwrb; 2190 pwrb_handle->pwrb = pwrb;
@@ -2042,79 +2415,126 @@ static int be_fill_queue(struct be_queue_info *q,
2042 return 0; 2415 return 0;
2043} 2416}
2044 2417
2045static int beiscsi_create_eq(struct beiscsi_hba *phba, 2418static int beiscsi_create_eqs(struct beiscsi_hba *phba,
2046 struct hwi_context_memory *phwi_context) 2419 struct hwi_context_memory *phwi_context)
2047{ 2420{
2048 unsigned int idx; 2421 unsigned int i, num_eq_pages;
2049 int ret; 2422 int ret, eq_for_mcc;
2050 struct be_queue_info *eq; 2423 struct be_queue_info *eq;
2051 struct be_dma_mem *mem; 2424 struct be_dma_mem *mem;
2052 struct be_mem_descriptor *mem_descr;
2053 void *eq_vaddress; 2425 void *eq_vaddress;
2426 dma_addr_t paddr;
2054 2427
2055 idx = 0; 2428 num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
2056 eq = &phwi_context->be_eq.q; 2429 sizeof(struct be_eq_entry));
2057 mem = &eq->dma_mem;
2058 mem_descr = phba->init_mem;
2059 mem_descr += HWI_MEM_EQ;
2060 eq_vaddress = mem_descr->mem_array[idx].virtual_address;
2061
2062 ret = be_fill_queue(eq, phba->params.num_eq_entries,
2063 sizeof(struct be_eq_entry), eq_vaddress);
2064 if (ret) {
2065 shost_printk(KERN_ERR, phba->shost,
2066 "be_fill_queue Failed for EQ \n");
2067 return ret;
2068 }
2069 2430
2070 mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address; 2431 if (phba->msix_enabled)
2432 eq_for_mcc = 1;
2433 else
2434 eq_for_mcc = 0;
2435 for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
2436 eq = &phwi_context->be_eq[i].q;
2437 mem = &eq->dma_mem;
2438 phwi_context->be_eq[i].phba = phba;
2439 eq_vaddress = pci_alloc_consistent(phba->pcidev,
2440 num_eq_pages * PAGE_SIZE,
2441 &paddr);
2442 if (!eq_vaddress)
2443 goto create_eq_error;
2444
2445 mem->va = eq_vaddress;
2446 ret = be_fill_queue(eq, phba->params.num_eq_entries,
2447 sizeof(struct be_eq_entry), eq_vaddress);
2448 if (ret) {
2449 shost_printk(KERN_ERR, phba->shost,
2450 "be_fill_queue Failed for EQ \n");
2451 goto create_eq_error;
2452 }
2071 2453
2072 ret = beiscsi_cmd_eq_create(&phba->ctrl, eq, 2454 mem->dma = paddr;
2073 phwi_context->be_eq.cur_eqd); 2455 ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
2074 if (ret) { 2456 phwi_context->cur_eqd);
2075 shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create" 2457 if (ret) {
2076 "Failedfor EQ \n"); 2458 shost_printk(KERN_ERR, phba->shost,
2077 return ret; 2459 "beiscsi_cmd_eq_create"
2460 "Failedfor EQ \n");
2461 goto create_eq_error;
2462 }
2463 SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id);
2078 } 2464 }
2079 SE_DEBUG(DBG_LVL_8, "eq id is %d\n", phwi_context->be_eq.q.id);
2080 return 0; 2465 return 0;
2466create_eq_error:
2467 for (i = 0; i < (phba->num_cpus + 1); i++) {
2468 eq = &phwi_context->be_eq[i].q;
2469 mem = &eq->dma_mem;
2470 if (mem->va)
2471 pci_free_consistent(phba->pcidev, num_eq_pages
2472 * PAGE_SIZE,
2473 mem->va, mem->dma);
2474 }
2475 return ret;
2081} 2476}
2082 2477
2083static int beiscsi_create_cq(struct beiscsi_hba *phba, 2478static int beiscsi_create_cqs(struct beiscsi_hba *phba,
2084 struct hwi_context_memory *phwi_context) 2479 struct hwi_context_memory *phwi_context)
2085{ 2480{
2086 unsigned int idx; 2481 unsigned int i, num_cq_pages;
2087 int ret; 2482 int ret;
2088 struct be_queue_info *cq, *eq; 2483 struct be_queue_info *cq, *eq;
2089 struct be_dma_mem *mem; 2484 struct be_dma_mem *mem;
2090 struct be_mem_descriptor *mem_descr; 2485 struct be_eq_obj *pbe_eq;
2091 void *cq_vaddress; 2486 void *cq_vaddress;
2487 dma_addr_t paddr;
2092 2488
2093 idx = 0; 2489 num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
2094 cq = &phwi_context->be_cq; 2490 sizeof(struct sol_cqe));
2095 eq = &phwi_context->be_eq.q;
2096 mem = &cq->dma_mem;
2097 mem_descr = phba->init_mem;
2098 mem_descr += HWI_MEM_CQ;
2099 cq_vaddress = mem_descr->mem_array[idx].virtual_address;
2100 ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
2101 sizeof(struct sol_cqe), cq_vaddress);
2102 if (ret) {
2103 shost_printk(KERN_ERR, phba->shost,
2104 "be_fill_queue Failed for ISCSI CQ \n");
2105 return ret;
2106 }
2107 2491
2108 mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address; 2492 for (i = 0; i < phba->num_cpus; i++) {
2109 ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, false, 0); 2493 cq = &phwi_context->be_cq[i];
2110 if (ret) { 2494 eq = &phwi_context->be_eq[i].q;
2111 shost_printk(KERN_ERR, phba->shost, 2495 pbe_eq = &phwi_context->be_eq[i];
2112 "beiscsi_cmd_eq_create Failed for ISCSI CQ \n"); 2496 pbe_eq->cq = cq;
2113 return ret; 2497 pbe_eq->phba = phba;
2498 mem = &cq->dma_mem;
2499 cq_vaddress = pci_alloc_consistent(phba->pcidev,
2500 num_cq_pages * PAGE_SIZE,
2501 &paddr);
2502 if (!cq_vaddress)
2503 goto create_cq_error;
2504 ret = be_fill_queue(cq, phba->params.num_cq_entries,
2505 sizeof(struct sol_cqe), cq_vaddress);
2506 if (ret) {
2507 shost_printk(KERN_ERR, phba->shost,
2508 "be_fill_queue Failed for ISCSI CQ \n");
2509 goto create_cq_error;
2510 }
2511
2512 mem->dma = paddr;
2513 ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false,
2514 false, 0);
2515 if (ret) {
2516 shost_printk(KERN_ERR, phba->shost,
2517 "beiscsi_cmd_eq_create"
2518 "Failed for ISCSI CQ \n");
2519 goto create_cq_error;
2520 }
2521 SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n",
2522 cq->id, eq->id);
2523 SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
2114 } 2524 }
2115 SE_DEBUG(DBG_LVL_8, "iscsi cq id is %d\n", phwi_context->be_cq.id);
2116 SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
2117 return 0; 2525 return 0;
2526
2527create_cq_error:
2528 for (i = 0; i < phba->num_cpus; i++) {
2529 cq = &phwi_context->be_cq[i];
2530 mem = &cq->dma_mem;
2531 if (mem->va)
2532 pci_free_consistent(phba->pcidev, num_cq_pages
2533 * PAGE_SIZE,
2534 mem->va, mem->dma);
2535 }
2536 return ret;
2537
2118} 2538}
2119 2539
2120static int 2540static int
@@ -2132,7 +2552,7 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba,
2132 2552
2133 idx = 0; 2553 idx = 0;
2134 dq = &phwi_context->be_def_hdrq; 2554 dq = &phwi_context->be_def_hdrq;
2135 cq = &phwi_context->be_cq; 2555 cq = &phwi_context->be_cq[0];
2136 mem = &dq->dma_mem; 2556 mem = &dq->dma_mem;
2137 mem_descr = phba->init_mem; 2557 mem_descr = phba->init_mem;
2138 mem_descr += HWI_MEM_ASYNC_HEADER_RING; 2558 mem_descr += HWI_MEM_ASYNC_HEADER_RING;
@@ -2176,7 +2596,7 @@ beiscsi_create_def_data(struct beiscsi_hba *phba,
2176 2596
2177 idx = 0; 2597 idx = 0;
2178 dataq = &phwi_context->be_def_dataq; 2598 dataq = &phwi_context->be_def_dataq;
2179 cq = &phwi_context->be_cq; 2599 cq = &phwi_context->be_cq[0];
2180 mem = &dataq->dma_mem; 2600 mem = &dataq->dma_mem;
2181 mem_descr = phba->init_mem; 2601 mem_descr = phba->init_mem;
2182 mem_descr += HWI_MEM_ASYNC_DATA_RING; 2602 mem_descr += HWI_MEM_ASYNC_DATA_RING;
@@ -2239,6 +2659,30 @@ beiscsi_post_pages(struct beiscsi_hba *phba)
2239 return 0; 2659 return 0;
2240} 2660}
2241 2661
2662static void be_queue_free(struct beiscsi_hba *phba, struct be_queue_info *q)
2663{
2664 struct be_dma_mem *mem = &q->dma_mem;
2665 if (mem->va)
2666 pci_free_consistent(phba->pcidev, mem->size,
2667 mem->va, mem->dma);
2668}
2669
2670static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q,
2671 u16 len, u16 entry_size)
2672{
2673 struct be_dma_mem *mem = &q->dma_mem;
2674
2675 memset(q, 0, sizeof(*q));
2676 q->len = len;
2677 q->entry_size = entry_size;
2678 mem->size = len * entry_size;
2679 mem->va = pci_alloc_consistent(phba->pcidev, mem->size, &mem->dma);
2680 if (!mem->va)
2681 return -1;
2682 memset(mem->va, 0, mem->size);
2683 return 0;
2684}
2685
2242static int 2686static int
2243beiscsi_create_wrb_rings(struct beiscsi_hba *phba, 2687beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
2244 struct hwi_context_memory *phwi_context, 2688 struct hwi_context_memory *phwi_context,
@@ -2308,7 +2752,8 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
2308 "wrbq create failed."); 2752 "wrbq create failed.");
2309 return status; 2753 return status;
2310 } 2754 }
2311 phwi_ctrlr->wrb_context[i].cid = phwi_context->be_wrbq[i].id; 2755 phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i].
2756 id;
2312 } 2757 }
2313 kfree(pwrb_arr); 2758 kfree(pwrb_arr);
2314 return 0; 2759 return 0;
@@ -2328,13 +2773,29 @@ static void free_wrb_handles(struct beiscsi_hba *phba)
2328 } 2773 }
2329} 2774}
2330 2775
2776static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
2777{
2778 struct be_queue_info *q;
2779 struct be_ctrl_info *ctrl = &phba->ctrl;
2780
2781 q = &phba->ctrl.mcc_obj.q;
2782 if (q->created)
2783 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
2784 be_queue_free(phba, q);
2785
2786 q = &phba->ctrl.mcc_obj.cq;
2787 if (q->created)
2788 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
2789 be_queue_free(phba, q);
2790}
2791
2331static void hwi_cleanup(struct beiscsi_hba *phba) 2792static void hwi_cleanup(struct beiscsi_hba *phba)
2332{ 2793{
2333 struct be_queue_info *q; 2794 struct be_queue_info *q;
2334 struct be_ctrl_info *ctrl = &phba->ctrl; 2795 struct be_ctrl_info *ctrl = &phba->ctrl;
2335 struct hwi_controller *phwi_ctrlr; 2796 struct hwi_controller *phwi_ctrlr;
2336 struct hwi_context_memory *phwi_context; 2797 struct hwi_context_memory *phwi_context;
2337 int i; 2798 int i, eq_num;
2338 2799
2339 phwi_ctrlr = phba->phwi_ctrlr; 2800 phwi_ctrlr = phba->phwi_ctrlr;
2340 phwi_context = phwi_ctrlr->phwi_ctxt; 2801 phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -2343,7 +2804,6 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
2343 if (q->created) 2804 if (q->created)
2344 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ); 2805 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ);
2345 } 2806 }
2346
2347 free_wrb_handles(phba); 2807 free_wrb_handles(phba);
2348 2808
2349 q = &phwi_context->be_def_hdrq; 2809 q = &phwi_context->be_def_hdrq;
@@ -2356,13 +2816,76 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
2356 2816
2357 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL); 2817 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
2358 2818
2359 q = &phwi_context->be_cq; 2819 for (i = 0; i < (phba->num_cpus); i++) {
2360 if (q->created) 2820 q = &phwi_context->be_cq[i];
2361 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ); 2821 if (q->created)
2822 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
2823 }
2824 if (phba->msix_enabled)
2825 eq_num = 1;
2826 else
2827 eq_num = 0;
2828 for (i = 0; i < (phba->num_cpus + eq_num); i++) {
2829 q = &phwi_context->be_eq[i].q;
2830 if (q->created)
2831 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
2832 }
2833 be_mcc_queues_destroy(phba);
2834}
2362 2835
2363 q = &phwi_context->be_eq.q; 2836static int be_mcc_queues_create(struct beiscsi_hba *phba,
2364 if (q->created) 2837 struct hwi_context_memory *phwi_context)
2365 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ); 2838{
2839 struct be_queue_info *q, *cq;
2840 struct be_ctrl_info *ctrl = &phba->ctrl;
2841
2842 /* Alloc MCC compl queue */
2843 cq = &phba->ctrl.mcc_obj.cq;
2844 if (be_queue_alloc(phba, cq, MCC_CQ_LEN,
2845 sizeof(struct be_mcc_compl)))
2846 goto err;
2847 /* Ask BE to create MCC compl queue; */
2848 if (phba->msix_enabled) {
2849 if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq
2850 [phba->num_cpus].q, false, true, 0))
2851 goto mcc_cq_free;
2852 } else {
2853 if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq[0].q,
2854 false, true, 0))
2855 goto mcc_cq_free;
2856 }
2857
2858 /* Alloc MCC queue */
2859 q = &phba->ctrl.mcc_obj.q;
2860 if (be_queue_alloc(phba, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
2861 goto mcc_cq_destroy;
2862
2863 /* Ask BE to create MCC queue */
2864 if (beiscsi_cmd_mccq_create(phba, q, cq))
2865 goto mcc_q_free;
2866
2867 return 0;
2868
2869mcc_q_free:
2870 be_queue_free(phba, q);
2871mcc_cq_destroy:
2872 beiscsi_cmd_q_destroy(ctrl, cq, QTYPE_CQ);
2873mcc_cq_free:
2874 be_queue_free(phba, cq);
2875err:
2876 return -1;
2877}
2878
2879static int find_num_cpus(void)
2880{
2881 int num_cpus = 0;
2882
2883 num_cpus = num_online_cpus();
2884 if (num_cpus >= MAX_CPUS)
2885 num_cpus = MAX_CPUS - 1;
2886
2887 SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", num_cpus);
2888 return num_cpus;
2366} 2889}
2367 2890
2368static int hwi_init_port(struct beiscsi_hba *phba) 2891static int hwi_init_port(struct beiscsi_hba *phba)
@@ -2376,34 +2899,30 @@ static int hwi_init_port(struct beiscsi_hba *phba)
2376 def_pdu_ring_sz = 2899 def_pdu_ring_sz =
2377 phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr); 2900 phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr);
2378 phwi_ctrlr = phba->phwi_ctrlr; 2901 phwi_ctrlr = phba->phwi_ctrlr;
2379
2380 phwi_context = phwi_ctrlr->phwi_ctxt; 2902 phwi_context = phwi_ctrlr->phwi_ctxt;
2381 phwi_context->be_eq.max_eqd = 0; 2903 phwi_context->max_eqd = 0;
2382 phwi_context->be_eq.min_eqd = 0; 2904 phwi_context->min_eqd = 0;
2383 phwi_context->be_eq.cur_eqd = 64; 2905 phwi_context->cur_eqd = 64;
2384 phwi_context->be_eq.enable_aic = false;
2385 be_cmd_fw_initialize(&phba->ctrl); 2906 be_cmd_fw_initialize(&phba->ctrl);
2386 status = beiscsi_create_eq(phba, phwi_context); 2907
2908 status = beiscsi_create_eqs(phba, phwi_context);
2387 if (status != 0) { 2909 if (status != 0) {
2388 shost_printk(KERN_ERR, phba->shost, "EQ not created \n"); 2910 shost_printk(KERN_ERR, phba->shost, "EQ not created \n");
2389 goto error; 2911 goto error;
2390 } 2912 }
2391 2913
2392 status = mgmt_check_supported_fw(ctrl); 2914 status = be_mcc_queues_create(phba, phwi_context);
2393 if (status != 0) { 2915 if (status != 0)
2394 shost_printk(KERN_ERR, phba->shost,
2395 "Unsupported fw version \n");
2396 goto error; 2916 goto error;
2397 }
2398 2917
2399 status = mgmt_get_fw_config(ctrl, phba); 2918 status = mgmt_check_supported_fw(ctrl, phba);
2400 if (status != 0) { 2919 if (status != 0) {
2401 shost_printk(KERN_ERR, phba->shost, 2920 shost_printk(KERN_ERR, phba->shost,
2402 "Error getting fw config\n"); 2921 "Unsupported fw version \n");
2403 goto error; 2922 goto error;
2404 } 2923 }
2405 2924
2406 status = beiscsi_create_cq(phba, phwi_context); 2925 status = beiscsi_create_cqs(phba, phwi_context);
2407 if (status != 0) { 2926 if (status != 0) {
2408 shost_printk(KERN_ERR, phba->shost, "CQ not created\n"); 2927 shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
2409 goto error; 2928 goto error;
@@ -2447,7 +2966,6 @@ error:
2447 return -ENOMEM; 2966 return -ENOMEM;
2448} 2967}
2449 2968
2450
2451static int hwi_init_controller(struct beiscsi_hba *phba) 2969static int hwi_init_controller(struct beiscsi_hba *phba)
2452{ 2970{
2453 struct hwi_controller *phwi_ctrlr; 2971 struct hwi_controller *phwi_ctrlr;
@@ -2530,6 +3048,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
2530 3048
2531 phba->io_sgl_hndl_avbl = 0; 3049 phba->io_sgl_hndl_avbl = 0;
2532 phba->eh_sgl_hndl_avbl = 0; 3050 phba->eh_sgl_hndl_avbl = 0;
3051
2533 mem_descr_sglh = phba->init_mem; 3052 mem_descr_sglh = phba->init_mem;
2534 mem_descr_sglh += HWI_MEM_SGLH; 3053 mem_descr_sglh += HWI_MEM_SGLH;
2535 if (1 == mem_descr_sglh->num_elements) { 3054 if (1 == mem_descr_sglh->num_elements) {
@@ -2608,7 +3127,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
2608 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); 3127 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0);
2609 pfrag += phba->params.num_sge_per_io; 3128 pfrag += phba->params.num_sge_per_io;
2610 psgl_handle->sgl_index = 3129 psgl_handle->sgl_index =
2611 phba->fw_config.iscsi_cid_start + arr_index++; 3130 phba->fw_config.iscsi_icd_start + arr_index++;
2612 } 3131 }
2613 idx++; 3132 idx++;
2614 } 3133 }
@@ -2623,7 +3142,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
2623{ 3142{
2624 int i, new_cid; 3143 int i, new_cid;
2625 3144
2626 phba->cid_array = kmalloc(sizeof(void *) * phba->params.cxns_per_ctrl, 3145 phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
2627 GFP_KERNEL); 3146 GFP_KERNEL);
2628 if (!phba->cid_array) { 3147 if (!phba->cid_array) {
2629 shost_printk(KERN_ERR, phba->shost, 3148 shost_printk(KERN_ERR, phba->shost,
@@ -2631,7 +3150,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
2631 "hba_setup_cid_tbls\n"); 3150 "hba_setup_cid_tbls\n");
2632 return -ENOMEM; 3151 return -ENOMEM;
2633 } 3152 }
2634 phba->ep_array = kmalloc(sizeof(struct iscsi_endpoint *) * 3153 phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) *
2635 phba->params.cxns_per_ctrl * 2, GFP_KERNEL); 3154 phba->params.cxns_per_ctrl * 2, GFP_KERNEL);
2636 if (!phba->ep_array) { 3155 if (!phba->ep_array) {
2637 shost_printk(KERN_ERR, phba->shost, 3156 shost_printk(KERN_ERR, phba->shost,
@@ -2640,7 +3159,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
2640 kfree(phba->cid_array); 3159 kfree(phba->cid_array);
2641 return -ENOMEM; 3160 return -ENOMEM;
2642 } 3161 }
2643 new_cid = phba->fw_config.iscsi_icd_start; 3162 new_cid = phba->fw_config.iscsi_cid_start;
2644 for (i = 0; i < phba->params.cxns_per_ctrl; i++) { 3163 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
2645 phba->cid_array[i] = new_cid; 3164 phba->cid_array[i] = new_cid;
2646 new_cid += 2; 3165 new_cid += 2;
@@ -2656,13 +3175,12 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
2656 struct hwi_context_memory *phwi_context; 3175 struct hwi_context_memory *phwi_context;
2657 struct be_queue_info *eq; 3176 struct be_queue_info *eq;
2658 u8 __iomem *addr; 3177 u8 __iomem *addr;
2659 u32 reg; 3178 u32 reg, i;
2660 u32 enabled; 3179 u32 enabled;
2661 3180
2662 phwi_ctrlr = phba->phwi_ctrlr; 3181 phwi_ctrlr = phba->phwi_ctrlr;
2663 phwi_context = phwi_ctrlr->phwi_ctxt; 3182 phwi_context = phwi_ctrlr->phwi_ctxt;
2664 3183
2665 eq = &phwi_context->be_eq.q;
2666 addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg + 3184 addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg +
2667 PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); 3185 PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
2668 reg = ioread32(addr); 3186 reg = ioread32(addr);
@@ -2673,12 +3191,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
2673 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; 3191 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
2674 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); 3192 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
2675 iowrite32(reg, addr); 3193 iowrite32(reg, addr);
2676 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); 3194 if (!phba->msix_enabled) {
2677 3195 eq = &phwi_context->be_eq[0].q;
2678 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); 3196 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
2679 } else 3197 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
2680 shost_printk(KERN_WARNING, phba->shost, 3198 } else {
2681 "In hwi_enable_intr, Not Enabled \n"); 3199 for (i = 0; i <= phba->num_cpus; i++) {
3200 eq = &phwi_context->be_eq[i].q;
3201 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
3202 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
3203 }
3204 }
3205 }
2682 return true; 3206 return true;
2683} 3207}
2684 3208
@@ -2738,17 +3262,30 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
2738 struct hwi_context_memory *phwi_context; 3262 struct hwi_context_memory *phwi_context;
2739 struct be_queue_info *eq; 3263 struct be_queue_info *eq;
2740 struct be_eq_entry *eqe = NULL; 3264 struct be_eq_entry *eqe = NULL;
3265 int i, eq_msix;
3266 unsigned int num_processed;
2741 3267
2742 phwi_ctrlr = phba->phwi_ctrlr; 3268 phwi_ctrlr = phba->phwi_ctrlr;
2743 phwi_context = phwi_ctrlr->phwi_ctxt; 3269 phwi_context = phwi_ctrlr->phwi_ctxt;
2744 eq = &phwi_context->be_eq.q; 3270 if (phba->msix_enabled)
2745 eqe = queue_tail_node(eq); 3271 eq_msix = 1;
3272 else
3273 eq_msix = 0;
2746 3274
2747 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] 3275 for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
2748 & EQE_VALID_MASK) { 3276 eq = &phwi_context->be_eq[i].q;
2749 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
2750 queue_tail_inc(eq);
2751 eqe = queue_tail_node(eq); 3277 eqe = queue_tail_node(eq);
3278 num_processed = 0;
3279 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
3280 & EQE_VALID_MASK) {
3281 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
3282 queue_tail_inc(eq);
3283 eqe = queue_tail_node(eq);
3284 num_processed++;
3285 }
3286
3287 if (num_processed)
3288 hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1);
2752 } 3289 }
2753} 3290}
2754 3291
@@ -2760,8 +3297,9 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
2760 if (mgmt_status) 3297 if (mgmt_status)
2761 shost_printk(KERN_WARNING, phba->shost, 3298 shost_printk(KERN_WARNING, phba->shost,
2762 "mgmt_epfw_cleanup FAILED \n"); 3299 "mgmt_epfw_cleanup FAILED \n");
2763 hwi_cleanup(phba); 3300
2764 hwi_purge_eq(phba); 3301 hwi_purge_eq(phba);
3302 hwi_cleanup(phba);
2765 kfree(phba->io_sgl_hndl_base); 3303 kfree(phba->io_sgl_hndl_base);
2766 kfree(phba->eh_sgl_hndl_base); 3304 kfree(phba->eh_sgl_hndl_base);
2767 kfree(phba->cid_array); 3305 kfree(phba->cid_array);
@@ -2782,7 +3320,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
2782 * We can always use 0 here because it is reserved by libiscsi for 3320 * We can always use 0 here because it is reserved by libiscsi for
2783 * login/startup related tasks. 3321 * login/startup related tasks.
2784 */ 3322 */
2785 pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid, 0); 3323 pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid -
3324 phba->fw_config.iscsi_cid_start));
2786 pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb; 3325 pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb;
2787 memset(pwrb, 0, sizeof(*pwrb)); 3326 memset(pwrb, 0, sizeof(*pwrb));
2788 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 3327 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
@@ -2846,8 +3385,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
2846 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); 3385 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb));
2847 3386
2848 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; 3387 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
2849 doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) << 3388 doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
2850 DB_DEF_PDU_WRB_INDEX_SHIFT; 3389 << DB_DEF_PDU_WRB_INDEX_SHIFT;
2851 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; 3390 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
2852 3391
2853 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); 3392 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -2856,7 +3395,7 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
2856static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt, 3395static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt,
2857 int *index, int *age) 3396 int *index, int *age)
2858{ 3397{
2859 *index = be32_to_cpu(itt) >> 16; 3398 *index = (int)itt;
2860 if (age) 3399 if (age)
2861 *age = conn->session->age; 3400 *age = conn->session->age;
2862} 3401}
@@ -2885,15 +3424,14 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
2885 3424
2886 io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool, 3425 io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool,
2887 GFP_KERNEL, &paddr); 3426 GFP_KERNEL, &paddr);
2888
2889 if (!io_task->cmd_bhs) 3427 if (!io_task->cmd_bhs)
2890 return -ENOMEM; 3428 return -ENOMEM;
2891
2892 io_task->bhs_pa.u.a64.address = paddr; 3429 io_task->bhs_pa.u.a64.address = paddr;
3430 io_task->libiscsi_itt = (itt_t)task->itt;
2893 io_task->pwrb_handle = alloc_wrb_handle(phba, 3431 io_task->pwrb_handle = alloc_wrb_handle(phba,
2894 beiscsi_conn->beiscsi_conn_cid, 3432 beiscsi_conn->beiscsi_conn_cid -
2895 task->itt); 3433 phba->fw_config.iscsi_cid_start
2896 io_task->pwrb_handle->pio_handle = task; 3434 );
2897 io_task->conn = beiscsi_conn; 3435 io_task->conn = beiscsi_conn;
2898 3436
2899 task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; 3437 task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
@@ -2905,10 +3443,9 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
2905 spin_unlock(&phba->io_sgl_lock); 3443 spin_unlock(&phba->io_sgl_lock);
2906 if (!io_task->psgl_handle) 3444 if (!io_task->psgl_handle)
2907 goto free_hndls; 3445 goto free_hndls;
2908
2909 } else { 3446 } else {
2910 io_task->scsi_cmnd = NULL; 3447 io_task->scsi_cmnd = NULL;
2911 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { 3448 if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
2912 if (!beiscsi_conn->login_in_progress) { 3449 if (!beiscsi_conn->login_in_progress) {
2913 spin_lock(&phba->mgmt_sgl_lock); 3450 spin_lock(&phba->mgmt_sgl_lock);
2914 io_task->psgl_handle = (struct sgl_handle *) 3451 io_task->psgl_handle = (struct sgl_handle *)
@@ -2932,14 +3469,19 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
2932 goto free_hndls; 3469 goto free_hndls;
2933 } 3470 }
2934 } 3471 }
2935 itt = (itt_t) cpu_to_be32(((unsigned int)task->itt << 16) | 3472 itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
2936 (unsigned int)(io_task->psgl_handle->sgl_index)); 3473 wrb_index << 16) | (unsigned int)
3474 (io_task->psgl_handle->sgl_index));
3475 io_task->pwrb_handle->pio_handle = task;
3476
2937 io_task->cmd_bhs->iscsi_hdr.itt = itt; 3477 io_task->cmd_bhs->iscsi_hdr.itt = itt;
2938 return 0; 3478 return 0;
2939 3479
2940free_hndls: 3480free_hndls:
2941 phwi_ctrlr = phba->phwi_ctrlr; 3481 phwi_ctrlr = phba->phwi_ctrlr;
2942 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid]; 3482 pwrb_context = &phwi_ctrlr->wrb_context[
3483 beiscsi_conn->beiscsi_conn_cid -
3484 phba->fw_config.iscsi_cid_start];
2943 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); 3485 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
2944 io_task->pwrb_handle = NULL; 3486 io_task->pwrb_handle = NULL;
2945 pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, 3487 pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
@@ -2959,7 +3501,8 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
2959 struct hwi_controller *phwi_ctrlr; 3501 struct hwi_controller *phwi_ctrlr;
2960 3502
2961 phwi_ctrlr = phba->phwi_ctrlr; 3503 phwi_ctrlr = phba->phwi_ctrlr;
2962 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid]; 3504 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid
3505 - phba->fw_config.iscsi_cid_start];
2963 if (io_task->pwrb_handle) { 3506 if (io_task->pwrb_handle) {
2964 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); 3507 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
2965 io_task->pwrb_handle = NULL; 3508 io_task->pwrb_handle = NULL;
@@ -3006,7 +3549,6 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3006 io_task->bhs_len = sizeof(struct be_cmd_bhs); 3549 io_task->bhs_len = sizeof(struct be_cmd_bhs);
3007 3550
3008 if (writedir) { 3551 if (writedir) {
3009 SE_DEBUG(DBG_LVL_4, " WRITE Command \t");
3010 memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48); 3552 memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48);
3011 AMAP_SET_BITS(struct amap_pdu_data_out, itt, 3553 AMAP_SET_BITS(struct amap_pdu_data_out, itt,
3012 &io_task->cmd_bhs->iscsi_data_pdu, 3554 &io_task->cmd_bhs->iscsi_data_pdu,
@@ -3016,11 +3558,12 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3016 ISCSI_OPCODE_SCSI_DATA_OUT); 3558 ISCSI_OPCODE_SCSI_DATA_OUT);
3017 AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, 3559 AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
3018 &io_task->cmd_bhs->iscsi_data_pdu, 1); 3560 &io_task->cmd_bhs->iscsi_data_pdu, 1);
3019 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD); 3561 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3562 INI_WR_CMD);
3020 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); 3563 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
3021 } else { 3564 } else {
3022 SE_DEBUG(DBG_LVL_4, "READ Command \t"); 3565 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3023 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD); 3566 INI_RD_CMD);
3024 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); 3567 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
3025 } 3568 }
3026 memcpy(&io_task->cmd_bhs->iscsi_data_pdu. 3569 memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
@@ -3055,15 +3598,17 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3055 3598
3056static int beiscsi_mtask(struct iscsi_task *task) 3599static int beiscsi_mtask(struct iscsi_task *task)
3057{ 3600{
3058 struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data; 3601 struct beiscsi_io_task *io_task = task->dd_data;
3059 struct iscsi_conn *conn = task->conn; 3602 struct iscsi_conn *conn = task->conn;
3060 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 3603 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3061 struct beiscsi_hba *phba = beiscsi_conn->phba; 3604 struct beiscsi_hba *phba = beiscsi_conn->phba;
3062 struct iscsi_wrb *pwrb = NULL; 3605 struct iscsi_wrb *pwrb = NULL;
3063 unsigned int doorbell = 0; 3606 unsigned int doorbell = 0;
3064 struct iscsi_task *aborted_task; 3607 unsigned int cid;
3065 3608
3609 cid = beiscsi_conn->beiscsi_conn_cid;
3066 pwrb = io_task->pwrb_handle->pwrb; 3610 pwrb = io_task->pwrb_handle->pwrb;
3611 memset(pwrb, 0, sizeof(*pwrb));
3067 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 3612 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
3068 be32_to_cpu(task->cmdsn)); 3613 be32_to_cpu(task->cmdsn));
3069 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, 3614 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb,
@@ -3073,40 +3618,37 @@ static int beiscsi_mtask(struct iscsi_task *task)
3073 3618
3074 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { 3619 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
3075 case ISCSI_OP_LOGIN: 3620 case ISCSI_OP_LOGIN:
3076 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, TGT_DM_CMD); 3621 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3622 TGT_DM_CMD);
3077 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3623 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3078 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); 3624 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
3079 hwi_write_buffer(pwrb, task); 3625 hwi_write_buffer(pwrb, task);
3080 break; 3626 break;
3081 case ISCSI_OP_NOOP_OUT: 3627 case ISCSI_OP_NOOP_OUT:
3082 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD); 3628 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3629 INI_RD_CMD);
3630 if (task->hdr->ttt == ISCSI_RESERVED_TAG)
3631 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3632 else
3633 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1);
3083 hwi_write_buffer(pwrb, task); 3634 hwi_write_buffer(pwrb, task);
3084 break; 3635 break;
3085 case ISCSI_OP_TEXT: 3636 case ISCSI_OP_TEXT:
3086 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD); 3637 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3087 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); 3638 TGT_DM_CMD);
3639 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3088 hwi_write_buffer(pwrb, task); 3640 hwi_write_buffer(pwrb, task);
3089 break; 3641 break;
3090 case ISCSI_OP_SCSI_TMFUNC: 3642 case ISCSI_OP_SCSI_TMFUNC:
3091 aborted_task = iscsi_itt_to_task(conn, 3643 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3092 ((struct iscsi_tm *)task->hdr)->rtt); 3644 INI_TMF_CMD);
3093 if (!aborted_task)
3094 return 0;
3095 aborted_io_task = aborted_task->dd_data;
3096 if (!aborted_io_task->scsi_cmnd)
3097 return 0;
3098
3099 mgmt_invalidate_icds(phba,
3100 aborted_io_task->psgl_handle->sgl_index,
3101 beiscsi_conn->beiscsi_conn_cid);
3102 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_TMF_CMD);
3103 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3645 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3104 hwi_write_buffer(pwrb, task); 3646 hwi_write_buffer(pwrb, task);
3105 break; 3647 break;
3106 case ISCSI_OP_LOGOUT: 3648 case ISCSI_OP_LOGOUT:
3107 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3649 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3108 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3650 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3109 HWH_TYPE_LOGOUT); 3651 HWH_TYPE_LOGOUT);
3110 hwi_write_buffer(pwrb, task); 3652 hwi_write_buffer(pwrb, task);
3111 break; 3653 break;
3112 3654
@@ -3117,12 +3659,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
3117 } 3659 }
3118 3660
3119 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, 3661 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb,
3120 be32_to_cpu(task->data_count)); 3662 task->data_count);
3121 AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, 3663 AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
3122 io_task->pwrb_handle->nxt_wrb_index); 3664 io_task->pwrb_handle->nxt_wrb_index);
3123 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); 3665 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
3124 3666
3125 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; 3667 doorbell |= cid & DB_WRB_POST_CID_MASK;
3126 doorbell |= (io_task->pwrb_handle->wrb_index & 3668 doorbell |= (io_task->pwrb_handle->wrb_index &
3127 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; 3669 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
3128 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; 3670 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
@@ -3132,17 +3674,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
3132 3674
3133static int beiscsi_task_xmit(struct iscsi_task *task) 3675static int beiscsi_task_xmit(struct iscsi_task *task)
3134{ 3676{
3135 struct iscsi_conn *conn = task->conn;
3136 struct beiscsi_io_task *io_task = task->dd_data; 3677 struct beiscsi_io_task *io_task = task->dd_data;
3137 struct scsi_cmnd *sc = task->sc; 3678 struct scsi_cmnd *sc = task->sc;
3138 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3139 struct scatterlist *sg; 3679 struct scatterlist *sg;
3140 int num_sg; 3680 int num_sg;
3141 unsigned int writedir = 0, xferlen = 0; 3681 unsigned int writedir = 0, xferlen = 0;
3142 3682
3143 SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
3144 "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
3145 task, conn, beiscsi_conn);
3146 if (!sc) 3683 if (!sc)
3147 return beiscsi_mtask(task); 3684 return beiscsi_mtask(task);
3148 3685
@@ -3168,6 +3705,10 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
3168static void beiscsi_remove(struct pci_dev *pcidev) 3705static void beiscsi_remove(struct pci_dev *pcidev)
3169{ 3706{
3170 struct beiscsi_hba *phba = NULL; 3707 struct beiscsi_hba *phba = NULL;
3708 struct hwi_controller *phwi_ctrlr;
3709 struct hwi_context_memory *phwi_context;
3710 struct be_eq_obj *pbe_eq;
3711 unsigned int i, msix_vec;
3171 3712
3172 phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); 3713 phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
3173 if (!phba) { 3714 if (!phba) {
@@ -3175,12 +3716,24 @@ static void beiscsi_remove(struct pci_dev *pcidev)
3175 return; 3716 return;
3176 } 3717 }
3177 3718
3719 phwi_ctrlr = phba->phwi_ctrlr;
3720 phwi_context = phwi_ctrlr->phwi_ctxt;
3178 hwi_disable_intr(phba); 3721 hwi_disable_intr(phba);
3179 if (phba->pcidev->irq) 3722 if (phba->msix_enabled) {
3180 free_irq(phba->pcidev->irq, phba); 3723 for (i = 0; i <= phba->num_cpus; i++) {
3724 msix_vec = phba->msix_entries[i].vector;
3725 free_irq(msix_vec, &phwi_context->be_eq[i]);
3726 }
3727 } else
3728 if (phba->pcidev->irq)
3729 free_irq(phba->pcidev->irq, phba);
3730 pci_disable_msix(phba->pcidev);
3181 destroy_workqueue(phba->wq); 3731 destroy_workqueue(phba->wq);
3182 if (blk_iopoll_enabled) 3732 if (blk_iopoll_enabled)
3183 blk_iopoll_disable(&phba->iopoll); 3733 for (i = 0; i < phba->num_cpus; i++) {
3734 pbe_eq = &phwi_context->be_eq[i];
3735 blk_iopoll_disable(&pbe_eq->iopoll);
3736 }
3184 3737
3185 beiscsi_clean_port(phba); 3738 beiscsi_clean_port(phba);
3186 beiscsi_free_mem(phba); 3739 beiscsi_free_mem(phba);
@@ -3194,11 +3747,29 @@ static void beiscsi_remove(struct pci_dev *pcidev)
3194 iscsi_host_free(phba->shost); 3747 iscsi_host_free(phba->shost);
3195} 3748}
3196 3749
3750static void beiscsi_msix_enable(struct beiscsi_hba *phba)
3751{
3752 int i, status;
3753
3754 for (i = 0; i <= phba->num_cpus; i++)
3755 phba->msix_entries[i].entry = i;
3756
3757 status = pci_enable_msix(phba->pcidev, phba->msix_entries,
3758 (phba->num_cpus + 1));
3759 if (!status)
3760 phba->msix_enabled = true;
3761
3762 return;
3763}
3764
3197static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, 3765static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3198 const struct pci_device_id *id) 3766 const struct pci_device_id *id)
3199{ 3767{
3200 struct beiscsi_hba *phba = NULL; 3768 struct beiscsi_hba *phba = NULL;
3201 int ret; 3769 struct hwi_controller *phwi_ctrlr;
3770 struct hwi_context_memory *phwi_context;
3771 struct be_eq_obj *pbe_eq;
3772 int ret, msix_vec, num_cpus, i;
3202 3773
3203 ret = beiscsi_enable_pci(pcidev); 3774 ret = beiscsi_enable_pci(pcidev);
3204 if (ret < 0) { 3775 if (ret < 0) {
@@ -3214,7 +3785,29 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3214 goto disable_pci; 3785 goto disable_pci;
3215 } 3786 }
3216 3787
3217 pci_set_drvdata(pcidev, phba); 3788 switch (pcidev->device) {
3789 case BE_DEVICE_ID1:
3790 case OC_DEVICE_ID1:
3791 case OC_DEVICE_ID2:
3792 phba->generation = BE_GEN2;
3793 break;
3794 case BE_DEVICE_ID2:
3795 case OC_DEVICE_ID3:
3796 phba->generation = BE_GEN3;
3797 break;
3798 default:
3799 phba->generation = 0;
3800 }
3801
3802 if (enable_msix)
3803 num_cpus = find_num_cpus();
3804 else
3805 num_cpus = 1;
3806 phba->num_cpus = num_cpus;
3807 SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", phba->num_cpus);
3808
3809 if (enable_msix)
3810 beiscsi_msix_enable(phba);
3218 ret = be_ctrl_init(phba, pcidev); 3811 ret = be_ctrl_init(phba, pcidev);
3219 if (ret) { 3812 if (ret) {
3220 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" 3813 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3225,7 +3818,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3225 spin_lock_init(&phba->io_sgl_lock); 3818 spin_lock_init(&phba->io_sgl_lock);
3226 spin_lock_init(&phba->mgmt_sgl_lock); 3819 spin_lock_init(&phba->mgmt_sgl_lock);
3227 spin_lock_init(&phba->isr_lock); 3820 spin_lock_init(&phba->isr_lock);
3821 ret = mgmt_get_fw_config(&phba->ctrl, phba);
3822 if (ret != 0) {
3823 shost_printk(KERN_ERR, phba->shost,
3824 "Error getting fw config\n");
3825 goto free_port;
3826 }
3827 phba->shost->max_id = phba->fw_config.iscsi_cid_count;
3228 beiscsi_get_params(phba); 3828 beiscsi_get_params(phba);
3829 phba->shost->can_queue = phba->params.ios_per_ctrl;
3229 ret = beiscsi_init_port(phba); 3830 ret = beiscsi_init_port(phba);
3230 if (ret < 0) { 3831 if (ret < 0) {
3231 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" 3832 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3233,9 +3834,18 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3233 goto free_port; 3834 goto free_port;
3234 } 3835 }
3235 3836
3837 for (i = 0; i < MAX_MCC_CMD ; i++) {
3838 init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
3839 phba->ctrl.mcc_tag[i] = i + 1;
3840 phba->ctrl.mcc_numtag[i + 1] = 0;
3841 phba->ctrl.mcc_tag_available++;
3842 }
3843
3844 phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
3845
3236 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", 3846 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
3237 phba->shost->host_no); 3847 phba->shost->host_no);
3238 phba->wq = create_singlethread_workqueue(phba->wq_name); 3848 phba->wq = create_workqueue(phba->wq_name);
3239 if (!phba->wq) { 3849 if (!phba->wq) {
3240 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" 3850 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3241 "Failed to allocate work queue\n"); 3851 "Failed to allocate work queue\n");
@@ -3244,11 +3854,16 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3244 3854
3245 INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs); 3855 INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs);
3246 3856
3857 phwi_ctrlr = phba->phwi_ctrlr;
3858 phwi_context = phwi_ctrlr->phwi_ctxt;
3247 if (blk_iopoll_enabled) { 3859 if (blk_iopoll_enabled) {
3248 blk_iopoll_init(&phba->iopoll, be_iopoll_budget, be_iopoll); 3860 for (i = 0; i < phba->num_cpus; i++) {
3249 blk_iopoll_enable(&phba->iopoll); 3861 pbe_eq = &phwi_context->be_eq[i];
3862 blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget,
3863 be_iopoll);
3864 blk_iopoll_enable(&pbe_eq->iopoll);
3865 }
3250 } 3866 }
3251
3252 ret = beiscsi_init_irqs(phba); 3867 ret = beiscsi_init_irqs(phba);
3253 if (ret < 0) { 3868 if (ret < 0) {
3254 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" 3869 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3261,17 +3876,26 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3261 "Failed to hwi_enable_intr\n"); 3876 "Failed to hwi_enable_intr\n");
3262 goto free_ctrlr; 3877 goto free_ctrlr;
3263 } 3878 }
3264
3265 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n"); 3879 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n");
3266 return 0; 3880 return 0;
3267 3881
3268free_ctrlr: 3882free_ctrlr:
3269 if (phba->pcidev->irq) 3883 if (phba->msix_enabled) {
3270 free_irq(phba->pcidev->irq, phba); 3884 for (i = 0; i <= phba->num_cpus; i++) {
3885 msix_vec = phba->msix_entries[i].vector;
3886 free_irq(msix_vec, &phwi_context->be_eq[i]);
3887 }
3888 } else
3889 if (phba->pcidev->irq)
3890 free_irq(phba->pcidev->irq, phba);
3891 pci_disable_msix(phba->pcidev);
3271free_blkenbld: 3892free_blkenbld:
3272 destroy_workqueue(phba->wq); 3893 destroy_workqueue(phba->wq);
3273 if (blk_iopoll_enabled) 3894 if (blk_iopoll_enabled)
3274 blk_iopoll_disable(&phba->iopoll); 3895 for (i = 0; i < phba->num_cpus; i++) {
3896 pbe_eq = &phwi_context->be_eq[i];
3897 blk_iopoll_disable(&pbe_eq->iopoll);
3898 }
3275free_twq: 3899free_twq:
3276 beiscsi_clean_port(phba); 3900 beiscsi_clean_port(phba);
3277 beiscsi_free_mem(phba); 3901 beiscsi_free_mem(phba);
@@ -3293,7 +3917,7 @@ disable_pci:
3293struct iscsi_transport beiscsi_iscsi_transport = { 3917struct iscsi_transport beiscsi_iscsi_transport = {
3294 .owner = THIS_MODULE, 3918 .owner = THIS_MODULE,
3295 .name = DRV_NAME, 3919 .name = DRV_NAME,
3296 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | 3920 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO |
3297 CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD, 3921 CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD,
3298 .param_mask = ISCSI_MAX_RECV_DLENGTH | 3922 .param_mask = ISCSI_MAX_RECV_DLENGTH |
3299 ISCSI_MAX_XMIT_DLENGTH | 3923 ISCSI_MAX_XMIT_DLENGTH |
@@ -3351,6 +3975,7 @@ static struct pci_driver beiscsi_pci_driver = {
3351 .id_table = beiscsi_pci_id_table 3975 .id_table = beiscsi_pci_id_table
3352}; 3976};
3353 3977
3978
3354static int __init beiscsi_module_init(void) 3979static int __init beiscsi_module_init(void)
3355{ 3980{
3356 int ret; 3981 int ret;
@@ -3361,7 +3986,7 @@ static int __init beiscsi_module_init(void)
3361 SE_DEBUG(DBG_LVL_1, 3986 SE_DEBUG(DBG_LVL_1,
3362 "beiscsi_module_init - Unable to register beiscsi" 3987 "beiscsi_module_init - Unable to register beiscsi"
3363 "transport.\n"); 3988 "transport.\n");
3364 ret = -ENOMEM; 3989 return -ENOMEM;
3365 } 3990 }
3366 SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n", 3991 SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n",
3367 &beiscsi_iscsi_transport); 3992 &beiscsi_iscsi_transport);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 53c9b70ac7ac..87ec21280a37 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
@@ -21,11 +21,9 @@
21#ifndef _BEISCSI_MAIN_ 21#ifndef _BEISCSI_MAIN_
22#define _BEISCSI_MAIN_ 22#define _BEISCSI_MAIN_
23 23
24
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/pci.h> 25#include <linux/pci.h>
27#include <linux/in.h> 26#include <linux/in.h>
28#include <linux/blk-iopoll.h>
29#include <scsi/scsi.h> 27#include <scsi/scsi.h>
30#include <scsi/scsi_cmnd.h> 28#include <scsi/scsi_cmnd.h>
31#include <scsi/scsi_device.h> 29#include <scsi/scsi_device.h>
@@ -35,39 +33,36 @@
35#include <scsi/scsi_transport_iscsi.h> 33#include <scsi/scsi_transport_iscsi.h>
36 34
37#include "be.h" 35#include "be.h"
38
39
40
41#define DRV_NAME "be2iscsi" 36#define DRV_NAME "be2iscsi"
42#define BUILD_STR "2.0.527.0" 37#define BUILD_STR "2.0.527.0"
43
44#define BE_NAME "ServerEngines BladeEngine2" \ 38#define BE_NAME "ServerEngines BladeEngine2" \
45 "Linux iSCSI Driver version" BUILD_STR 39 "Linux iSCSI Driver version" BUILD_STR
46#define DRV_DESC BE_NAME " " "Driver" 40#define DRV_DESC BE_NAME " " "Driver"
47 41
48#define BE_VENDOR_ID 0x19A2 42#define BE_VENDOR_ID 0x19A2
43/* DEVICE ID's for BE2 */
49#define BE_DEVICE_ID1 0x212 44#define BE_DEVICE_ID1 0x212
50#define OC_DEVICE_ID1 0x702 45#define OC_DEVICE_ID1 0x702
51#define OC_DEVICE_ID2 0x703 46#define OC_DEVICE_ID2 0x703
52 47
53#define BE2_MAX_SESSIONS 64 48/* DEVICE ID's for BE3 */
49#define BE_DEVICE_ID2 0x222
50#define OC_DEVICE_ID3 0x712
51
52#define BE2_IO_DEPTH 1024
53#define BE2_MAX_SESSIONS 256
54#define BE2_CMDS_PER_CXN 128 54#define BE2_CMDS_PER_CXN 128
55#define BE2_LOGOUTS BE2_MAX_SESSIONS
56#define BE2_TMFS 16 55#define BE2_TMFS 16
57#define BE2_NOPOUT_REQ 16 56#define BE2_NOPOUT_REQ 16
58#define BE2_ASYNCPDUS BE2_MAX_SESSIONS
59#define BE2_MAX_ICDS 2048
60#define BE2_SGE 32 57#define BE2_SGE 32
61#define BE2_DEFPDU_HDR_SZ 64 58#define BE2_DEFPDU_HDR_SZ 64
62#define BE2_DEFPDU_DATA_SZ 8192 59#define BE2_DEFPDU_DATA_SZ 8192
63#define BE2_IO_DEPTH \
64 (BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ))
65 60
66#define BEISCSI_SGLIST_ELEMENTS BE2_SGE 61#define MAX_CPUS 31
62#define BEISCSI_SGLIST_ELEMENTS 30
67 63
68#define BEISCSI_MAX_CMNDS 1024 /* Max IO's per Ctrlr sht->can_queue */
69#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ 64#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
70#define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ 65#define BEISCSI_MAX_SECTORS 256 /* scsi_host->max_sectors */
71 66
72#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ 67#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
73#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ 68#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */
@@ -79,7 +74,7 @@
79#define BE_SENSE_INFO_SIZE 258 74#define BE_SENSE_INFO_SIZE 258
80#define BE_ISCSI_PDU_HEADER_SIZE 64 75#define BE_ISCSI_PDU_HEADER_SIZE 64
81#define BE_MIN_MEM_SIZE 16384 76#define BE_MIN_MEM_SIZE 16384
82 77#define MAX_CMD_SZ 65536
83#define IIOC_SCSI_DATA 0x05 /* Write Operation */ 78#define IIOC_SCSI_DATA 0x05 /* Write Operation */
84 79
85#define DBG_LVL 0x00000001 80#define DBG_LVL 0x00000001
@@ -100,6 +95,8 @@ do { \
100 } \ 95 } \
101} while (0); 96} while (0);
102 97
98#define BE_ADAPTER_UP 0x00000000
99#define BE_ADAPTER_LINK_DOWN 0x00000001
103/** 100/**
104 * hardware needs the async PDU buffers to be posted in multiples of 8 101 * hardware needs the async PDU buffers to be posted in multiples of 8
105 * So have atleast 8 of them by default 102 * So have atleast 8 of them by default
@@ -160,21 +157,19 @@ do { \
160 157
161enum be_mem_enum { 158enum be_mem_enum {
162 HWI_MEM_ADDN_CONTEXT, 159 HWI_MEM_ADDN_CONTEXT,
163 HWI_MEM_CQ,
164 HWI_MEM_EQ,
165 HWI_MEM_WRB, 160 HWI_MEM_WRB,
166 HWI_MEM_WRBH, 161 HWI_MEM_WRBH,
167 HWI_MEM_SGLH, /* 5 */ 162 HWI_MEM_SGLH,
168 HWI_MEM_SGE, 163 HWI_MEM_SGE,
169 HWI_MEM_ASYNC_HEADER_BUF, 164 HWI_MEM_ASYNC_HEADER_BUF, /* 5 */
170 HWI_MEM_ASYNC_DATA_BUF, 165 HWI_MEM_ASYNC_DATA_BUF,
171 HWI_MEM_ASYNC_HEADER_RING, 166 HWI_MEM_ASYNC_HEADER_RING,
172 HWI_MEM_ASYNC_DATA_RING, /* 10 */ 167 HWI_MEM_ASYNC_DATA_RING,
173 HWI_MEM_ASYNC_HEADER_HANDLE, 168 HWI_MEM_ASYNC_HEADER_HANDLE,
174 HWI_MEM_ASYNC_DATA_HANDLE, 169 HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */
175 HWI_MEM_ASYNC_PDU_CONTEXT, 170 HWI_MEM_ASYNC_PDU_CONTEXT,
176 ISCSI_MEM_GLOBAL_HEADER, 171 ISCSI_MEM_GLOBAL_HEADER,
177 SE_MEM_MAX /* 15 */ 172 SE_MEM_MAX
178}; 173};
179 174
180struct be_bus_address32 { 175struct be_bus_address32 {
@@ -212,6 +207,9 @@ struct be_mem_descriptor {
212 207
213struct sgl_handle { 208struct sgl_handle {
214 unsigned int sgl_index; 209 unsigned int sgl_index;
210 unsigned int type;
211 unsigned int cid;
212 struct iscsi_task *task;
215 struct iscsi_sge *pfrag; 213 struct iscsi_sge *pfrag;
216}; 214};
217 215
@@ -259,6 +257,11 @@ struct hba_parameters {
259 unsigned int num_sge; 257 unsigned int num_sge;
260}; 258};
261 259
260struct invalidate_command_table {
261 unsigned short icd;
262 unsigned short cid;
263} __packed;
264
262struct beiscsi_hba { 265struct beiscsi_hba {
263 struct hba_parameters params; 266 struct hba_parameters params;
264 struct hwi_controller *phwi_ctrlr; 267 struct hwi_controller *phwi_ctrlr;
@@ -274,13 +277,17 @@ struct beiscsi_hba {
274 struct pci_dev *pcidev; 277 struct pci_dev *pcidev;
275 unsigned int state; 278 unsigned int state;
276 unsigned short asic_revision; 279 unsigned short asic_revision;
277 struct blk_iopoll iopoll; 280 unsigned int num_cpus;
281 unsigned int nxt_cqid;
282 struct msix_entry msix_entries[MAX_CPUS + 1];
283 bool msix_enabled;
278 struct be_mem_descriptor *init_mem; 284 struct be_mem_descriptor *init_mem;
279 285
280 unsigned short io_sgl_alloc_index; 286 unsigned short io_sgl_alloc_index;
281 unsigned short io_sgl_free_index; 287 unsigned short io_sgl_free_index;
282 unsigned short io_sgl_hndl_avbl; 288 unsigned short io_sgl_hndl_avbl;
283 struct sgl_handle **io_sgl_hndl_base; 289 struct sgl_handle **io_sgl_hndl_base;
290 struct sgl_handle **sgl_hndl_array;
284 291
285 unsigned short eh_sgl_alloc_index; 292 unsigned short eh_sgl_alloc_index;
286 unsigned short eh_sgl_free_index; 293 unsigned short eh_sgl_free_index;
@@ -315,6 +322,7 @@ struct beiscsi_hba {
315 unsigned short cid_alloc; 322 unsigned short cid_alloc;
316 unsigned short cid_free; 323 unsigned short cid_free;
317 unsigned short avlbl_cids; 324 unsigned short avlbl_cids;
325 unsigned short iscsi_features;
318 spinlock_t cid_lock; 326 spinlock_t cid_lock;
319 } fw_config; 327 } fw_config;
320 328
@@ -325,6 +333,9 @@ struct beiscsi_hba {
325 struct workqueue_struct *wq; /* The actuak work queue */ 333 struct workqueue_struct *wq; /* The actuak work queue */
326 struct work_struct work_cqs; /* The work being queued */ 334 struct work_struct work_cqs; /* The work being queued */
327 struct be_ctrl_info ctrl; 335 struct be_ctrl_info ctrl;
336 unsigned int generation;
337 struct invalidate_command_table inv_tbl[128];
338
328}; 339};
329 340
330struct beiscsi_session { 341struct beiscsi_session {
@@ -343,6 +354,7 @@ struct beiscsi_conn {
343 unsigned short login_in_progress; 354 unsigned short login_in_progress;
344 struct sgl_handle *plogin_sgl_handle; 355 struct sgl_handle *plogin_sgl_handle;
345 struct beiscsi_session *beiscsi_sess; 356 struct beiscsi_session *beiscsi_sess;
357 struct iscsi_task *task;
346}; 358};
347 359
348/* This structure is used by the chip */ 360/* This structure is used by the chip */
@@ -390,7 +402,7 @@ struct beiscsi_io_task {
390 unsigned int flags; 402 unsigned int flags;
391 unsigned short cid; 403 unsigned short cid;
392 unsigned short header_len; 404 unsigned short header_len;
393 405 itt_t libiscsi_itt;
394 struct be_cmd_bhs *cmd_bhs; 406 struct be_cmd_bhs *cmd_bhs;
395 struct be_bus_address bhs_pa; 407 struct be_bus_address bhs_pa;
396 unsigned short bhs_len; 408 unsigned short bhs_len;
@@ -486,8 +498,6 @@ struct hwi_async_entry {
486 struct list_head data_busy_list; 498 struct list_head data_busy_list;
487}; 499};
488 500
489#define BE_MIN_ASYNC_ENTRIES 128
490
491struct hwi_async_pdu_context { 501struct hwi_async_pdu_context {
492 struct { 502 struct {
493 struct be_bus_address pa_base; 503 struct be_bus_address pa_base;
@@ -528,7 +538,7 @@ struct hwi_async_pdu_context {
528 * This is a varying size list! Do not add anything 538 * This is a varying size list! Do not add anything
529 * after this entry!! 539 * after this entry!!
530 */ 540 */
531 struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES]; 541 struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2];
532}; 542};
533 543
534#define PDUCQE_CODE_MASK 0x0000003F 544#define PDUCQE_CODE_MASK 0x0000003F
@@ -599,7 +609,6 @@ struct amap_cq_db {
599 609
600void beiscsi_process_eq(struct beiscsi_hba *phba); 610void beiscsi_process_eq(struct beiscsi_hba *phba);
601 611
602
603struct iscsi_wrb { 612struct iscsi_wrb {
604 u32 dw[16]; 613 u32 dw[16];
605} __packed; 614} __packed;
@@ -651,11 +660,12 @@ struct amap_iscsi_wrb {
651 660
652} __packed; 661} __packed;
653 662
654struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, 663struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid);
655 int index);
656void 664void
657free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); 665free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
658 666
667void beiscsi_process_all_cqs(struct work_struct *work);
668
659struct pdu_nop_out { 669struct pdu_nop_out {
660 u32 dw[12]; 670 u32 dw[12];
661}; 671};
@@ -797,7 +807,6 @@ struct hwi_controller {
797 struct be_ring default_pdu_hdr; 807 struct be_ring default_pdu_hdr;
798 struct be_ring default_pdu_data; 808 struct be_ring default_pdu_data;
799 struct hwi_context_memory *phwi_ctxt; 809 struct hwi_context_memory *phwi_ctxt;
800 unsigned short cq_errors[CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN];
801}; 810};
802 811
803enum hwh_type_enum { 812enum hwh_type_enum {
@@ -820,10 +829,12 @@ struct wrb_handle {
820}; 829};
821 830
822struct hwi_context_memory { 831struct hwi_context_memory {
823 struct be_eq_obj be_eq; 832 /* Adaptive interrupt coalescing (AIC) info */
824 struct be_queue_info be_cq; 833 u16 min_eqd; /* in usecs */
825 struct be_queue_info be_mcc_cq; 834 u16 max_eqd; /* in usecs */
826 struct be_queue_info be_mcc; 835 u16 cur_eqd; /* in usecs */
836 struct be_eq_obj be_eq[MAX_CPUS];
837 struct be_queue_info be_cq[MAX_CPUS];
827 838
828 struct be_queue_info be_def_hdrq; 839 struct be_queue_info be_def_hdrq;
829 struct be_queue_info be_def_dataq; 840 struct be_queue_info be_def_dataq;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 12e644fc746e..e641922f20bc 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
@@ -35,7 +35,6 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
35 35
36 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 36 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
37 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); 37 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
38
39 status = be_mbox_notify(ctrl); 38 status = be_mbox_notify(ctrl);
40 if (!status) { 39 if (!status) {
41 struct be_fw_cfg *pfw_cfg; 40 struct be_fw_cfg *pfw_cfg;
@@ -49,6 +48,14 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
49 pfw_cfg->ulp[0].sq_base; 48 pfw_cfg->ulp[0].sq_base;
50 phba->fw_config.iscsi_cid_count = 49 phba->fw_config.iscsi_cid_count =
51 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 }
52 } else { 59 } else {
53 shost_printk(KERN_WARNING, phba->shost, 60 shost_printk(KERN_WARNING, phba->shost,
54 "Failed in mgmt_get_fw_config \n"); 61 "Failed in mgmt_get_fw_config \n");
@@ -58,7 +65,8 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
58 return status; 65 return status;
59} 66}
60 67
61unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl) 68unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
69 struct beiscsi_hba *phba)
62{ 70{
63 struct be_dma_mem nonemb_cmd; 71 struct be_dma_mem nonemb_cmd;
64 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 72 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
@@ -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);
@@ -85,7 +94,6 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl)
85 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); 94 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
86 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 95 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
87 sge->len = cpu_to_le32(nonemb_cmd.size); 96 sge->len = cpu_to_le32(nonemb_cmd.size);
88
89 status = be_mbox_notify(ctrl); 97 status = be_mbox_notify(ctrl);
90 if (!status) { 98 if (!status) {
91 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va; 99 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
@@ -95,21 +103,25 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl)
95 resp->params.hba_attribs.firmware_version_string); 103 resp->params.hba_attribs.firmware_version_string);
96 SE_DEBUG(DBG_LVL_8, 104 SE_DEBUG(DBG_LVL_8,
97 "Developer Build, not performing version check...\n"); 105 "Developer Build, not performing version check...\n");
98 106 phba->fw_config.iscsi_features =
107 resp->params.hba_attribs.iscsi_features;
108 SE_DEBUG(DBG_LVL_8, " phba->fw_config.iscsi_features = %d\n",
109 phba->fw_config.iscsi_features);
99 } else 110 } else
100 SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n"); 111 SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n");
112 spin_unlock(&ctrl->mbox_lock);
101 if (nonemb_cmd.va) 113 if (nonemb_cmd.va)
102 pci_free_consistent(ctrl->pdev, nonemb_cmd.size, 114 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
103 nonemb_cmd.va, nonemb_cmd.dma); 115 nonemb_cmd.va, nonemb_cmd.dma);
104 116
105 spin_unlock(&ctrl->mbox_lock);
106 return status; 117 return status;
107} 118}
108 119
120
109unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) 121unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
110{ 122{
111 struct be_ctrl_info *ctrl = &phba->ctrl; 123 struct be_ctrl_info *ctrl = &phba->ctrl;
112 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 124 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
113 struct iscsi_cleanup_req *req = embedded_payload(wrb); 125 struct iscsi_cleanup_req *req = embedded_payload(wrb);
114 int status = 0; 126 int status = 0;
115 127
@@ -124,7 +136,7 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
124 req->hdr_ring_id = 0; 136 req->hdr_ring_id = 0;
125 req->data_ring_id = 0; 137 req->data_ring_id = 0;
126 138
127 status = be_mbox_notify(ctrl); 139 status = be_mcc_notify_wait(phba);
128 if (status) 140 if (status)
129 shost_printk(KERN_WARNING, phba->shost, 141 shost_printk(KERN_WARNING, phba->shost,
130 " mgmt_epfw_cleanup , FAILED\n"); 142 " mgmt_epfw_cleanup , FAILED\n");
@@ -133,14 +145,22 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
133} 145}
134 146
135unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 147unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
136 unsigned int icd, unsigned int cid) 148 struct invalidate_command_table *inv_tbl,
149 unsigned int num_invalidate, unsigned int cid)
137{ 150{
138 struct be_dma_mem nonemb_cmd; 151 struct be_dma_mem nonemb_cmd;
139 struct be_ctrl_info *ctrl = &phba->ctrl; 152 struct be_ctrl_info *ctrl = &phba->ctrl;
140 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 153 struct be_mcc_wrb *wrb;
141 struct be_sge *sge = nonembedded_sgl(wrb); 154 struct be_sge *sge;
142 struct invalidate_commands_params_in *req; 155 struct invalidate_commands_params_in *req;
143 int status = 0; 156 unsigned int i, tag = 0;
157
158 spin_lock(&ctrl->mbox_lock);
159 tag = alloc_mcc_tag(phba);
160 if (!tag) {
161 spin_unlock(&ctrl->mbox_lock);
162 return tag;
163 }
144 164
145 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, 165 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
146 sizeof(struct invalidate_commands_params_in), 166 sizeof(struct invalidate_commands_params_in),
@@ -149,12 +169,15 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
149 SE_DEBUG(DBG_LVL_1, 169 SE_DEBUG(DBG_LVL_1,
150 "Failed to allocate memory for" 170 "Failed to allocate memory for"
151 "mgmt_invalidate_icds \n"); 171 "mgmt_invalidate_icds \n");
172 spin_unlock(&ctrl->mbox_lock);
152 return -1; 173 return -1;
153 } 174 }
154 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); 175 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
155 req = nonemb_cmd.va; 176 req = nonemb_cmd.va;
156 spin_lock(&ctrl->mbox_lock); 177 memset(req, 0, sizeof(*req));
157 memset(wrb, 0, sizeof(*wrb)); 178 wrb = wrb_from_mccq(phba);
179 sge = nonembedded_sgl(wrb);
180 wrb->tag0 |= tag;
158 181
159 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 182 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
160 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 183 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -162,21 +185,22 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
162 sizeof(*req)); 185 sizeof(*req));
163 req->ref_handle = 0; 186 req->ref_handle = 0;
164 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; 187 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
165 req->icd_count = 0; 188 for (i = 0; i < num_invalidate; i++) {
166 req->table[req->icd_count].icd = icd; 189 req->table[i].icd = inv_tbl->icd;
167 req->table[req->icd_count].cid = cid; 190 req->table[i].cid = inv_tbl->cid;
191 req->icd_count++;
192 inv_tbl++;
193 }
168 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); 194 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
169 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 195 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
170 sge->len = cpu_to_le32(nonemb_cmd.size); 196 sge->len = cpu_to_le32(nonemb_cmd.size);
171 197
172 status = be_mbox_notify(ctrl); 198 be_mcc_notify(phba);
173 if (status)
174 SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
175 spin_unlock(&ctrl->mbox_lock); 199 spin_unlock(&ctrl->mbox_lock);
176 if (nonemb_cmd.va) 200 if (nonemb_cmd.va)
177 pci_free_consistent(ctrl->pdev, nonemb_cmd.size, 201 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
178 nonemb_cmd.va, nonemb_cmd.dma); 202 nonemb_cmd.va, nonemb_cmd.dma);
179 return status; 203 return tag;
180} 204}
181 205
182unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, 206unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
@@ -186,13 +210,19 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
186 unsigned short savecfg_flag) 210 unsigned short savecfg_flag)
187{ 211{
188 struct be_ctrl_info *ctrl = &phba->ctrl; 212 struct be_ctrl_info *ctrl = &phba->ctrl;
189 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 213 struct be_mcc_wrb *wrb;
190 struct iscsi_invalidate_connection_params_in *req = 214 struct iscsi_invalidate_connection_params_in *req;
191 embedded_payload(wrb); 215 unsigned int tag = 0;
192 int status = 0;
193 216
194 spin_lock(&ctrl->mbox_lock); 217 spin_lock(&ctrl->mbox_lock);
195 memset(wrb, 0, sizeof(*wrb)); 218 tag = alloc_mcc_tag(phba);
219 if (!tag) {
220 spin_unlock(&ctrl->mbox_lock);
221 return tag;
222 }
223 wrb = wrb_from_mccq(phba);
224 wrb->tag0 |= tag;
225 req = embedded_payload(wrb);
196 226
197 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 227 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
198 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 228 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
@@ -205,35 +235,37 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
205 else 235 else
206 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; 236 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
207 req->save_cfg = savecfg_flag; 237 req->save_cfg = savecfg_flag;
208 status = be_mbox_notify(ctrl); 238 be_mcc_notify(phba);
209 if (status)
210 SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
211
212 spin_unlock(&ctrl->mbox_lock); 239 spin_unlock(&ctrl->mbox_lock);
213 return status; 240 return tag;
214} 241}
215 242
216unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, 243unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
217 unsigned short cid, unsigned int upload_flag) 244 unsigned short cid, unsigned int upload_flag)
218{ 245{
219 struct be_ctrl_info *ctrl = &phba->ctrl; 246 struct be_ctrl_info *ctrl = &phba->ctrl;
220 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 247 struct be_mcc_wrb *wrb;
221 struct tcp_upload_params_in *req = embedded_payload(wrb); 248 struct tcp_upload_params_in *req;
222 int status = 0; 249 unsigned int tag = 0;
223 250
224 spin_lock(&ctrl->mbox_lock); 251 spin_lock(&ctrl->mbox_lock);
225 memset(wrb, 0, sizeof(*wrb)); 252 tag = alloc_mcc_tag(phba);
253 if (!tag) {
254 spin_unlock(&ctrl->mbox_lock);
255 return tag;
256 }
257 wrb = wrb_from_mccq(phba);
258 req = embedded_payload(wrb);
259 wrb->tag0 |= tag;
226 260
227 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 261 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
228 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, 262 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
229 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); 263 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
230 req->id = (unsigned short)cid; 264 req->id = (unsigned short)cid;
231 req->upload_type = (unsigned char)upload_flag; 265 req->upload_type = (unsigned char)upload_flag;
232 status = be_mbox_notify(ctrl); 266 be_mcc_notify(phba);
233 if (status)
234 SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
235 spin_unlock(&ctrl->mbox_lock); 267 spin_unlock(&ctrl->mbox_lock);
236 return status; 268 return tag;
237} 269}
238 270
239int mgmt_open_connection(struct beiscsi_hba *phba, 271int mgmt_open_connection(struct beiscsi_hba *phba,
@@ -245,13 +277,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
245 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; 277 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
246 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; 278 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
247 struct be_ctrl_info *ctrl = &phba->ctrl; 279 struct be_ctrl_info *ctrl = &phba->ctrl;
248 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 280 struct be_mcc_wrb *wrb;
249 struct tcp_connect_and_offload_in *req = embedded_payload(wrb); 281 struct tcp_connect_and_offload_in *req;
250 unsigned short def_hdr_id; 282 unsigned short def_hdr_id;
251 unsigned short def_data_id; 283 unsigned short def_data_id;
252 struct phys_addr template_address = { 0, 0 }; 284 struct phys_addr template_address = { 0, 0 };
253 struct phys_addr *ptemplate_address; 285 struct phys_addr *ptemplate_address;
254 int status = 0; 286 unsigned int tag = 0;
287 unsigned int i;
255 unsigned short cid = beiscsi_ep->ep_cid; 288 unsigned short cid = beiscsi_ep->ep_cid;
256 289
257 phwi_ctrlr = phba->phwi_ctrlr; 290 phwi_ctrlr = phba->phwi_ctrlr;
@@ -262,7 +295,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
262 ptemplate_address = &template_address; 295 ptemplate_address = &template_address;
263 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); 296 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
264 spin_lock(&ctrl->mbox_lock); 297 spin_lock(&ctrl->mbox_lock);
265 memset(wrb, 0, sizeof(*wrb)); 298 tag = alloc_mcc_tag(phba);
299 if (!tag) {
300 spin_unlock(&ctrl->mbox_lock);
301 return tag;
302 }
303 wrb = wrb_from_mccq(phba);
304 req = embedded_payload(wrb);
305 wrb->tag0 |= tag;
266 306
267 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 307 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
268 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 308 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
@@ -296,26 +336,47 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
296 336
297 } 337 }
298 req->cid = cid; 338 req->cid = cid;
299 req->cq_id = phwi_context->be_cq.id; 339 i = phba->nxt_cqid++;
340 if (phba->nxt_cqid == phba->num_cpus)
341 phba->nxt_cqid = 0;
342 req->cq_id = phwi_context->be_cq[i].id;
343 SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d \n", i, req->cq_id);
300 req->defq_id = def_hdr_id; 344 req->defq_id = def_hdr_id;
301 req->hdr_ring_id = def_hdr_id; 345 req->hdr_ring_id = def_hdr_id;
302 req->data_ring_id = def_data_id; 346 req->data_ring_id = def_data_id;
303 req->do_offload = 1; 347 req->do_offload = 1;
304 req->dataout_template_pa.lo = ptemplate_address->lo; 348 req->dataout_template_pa.lo = ptemplate_address->lo;
305 req->dataout_template_pa.hi = ptemplate_address->hi; 349 req->dataout_template_pa.hi = ptemplate_address->hi;
306 status = be_mbox_notify(ctrl); 350 be_mcc_notify(phba);
307 if (!status) {
308 struct iscsi_endpoint *ep;
309 struct tcp_connect_and_offload_out *ptcpcnct_out =
310 embedded_payload(wrb);
311
312 ep = phba->ep_array[ptcpcnct_out->cid];
313 beiscsi_ep = ep->dd_data;
314 beiscsi_ep->fw_handle = 0;
315 beiscsi_ep->cid_vld = 1;
316 SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
317 } else
318 SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n");
319 spin_unlock(&ctrl->mbox_lock); 351 spin_unlock(&ctrl->mbox_lock);
320 return status; 352 return tag;
321} 353}
354
355unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba)
356{
357 struct be_ctrl_info *ctrl = &phba->ctrl;
358 struct be_mcc_wrb *wrb;
359 struct be_cmd_req_get_mac_addr *req;
360 unsigned int tag = 0;
361
362 SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
363 spin_lock(&ctrl->mbox_lock);
364 tag = alloc_mcc_tag(phba);
365 if (!tag) {
366 spin_unlock(&ctrl->mbox_lock);
367 return tag;
368 }
369
370 wrb = wrb_from_mccq(phba);
371 req = embedded_payload(wrb);
372 wrb->tag0 |= tag;
373 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
374 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
375 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
376 sizeof(*req));
377
378 be_mcc_notify(phba);
379 spin_unlock(&ctrl->mbox_lock);
380 return tag;
381}
382
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 00e816ee8070..3d316b82feb1 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
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
94 unsigned short cid, 94 unsigned short cid,
95 unsigned int upload_flag); 95 unsigned int upload_flag);
96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
97 unsigned int icd, unsigned int cid); 97 struct invalidate_command_table *inv_tbl,
98 unsigned int num_invalidate, unsigned int cid);
98 99
99struct iscsi_invalidate_connection_params_in { 100struct iscsi_invalidate_connection_params_in {
100 struct be_cmd_req_hdr hdr; 101 struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
116 struct iscsi_invalidate_connection_params_out response; 117 struct iscsi_invalidate_connection_params_out response;
117} __packed; 118} __packed;
118 119
119struct invalidate_command_table {
120 unsigned short icd;
121 unsigned short cid;
122} __packed;
123
124struct invalidate_commands_params_in { 120struct invalidate_commands_params_in {
125 struct be_cmd_req_hdr hdr; 121 struct be_cmd_req_hdr hdr;
126 unsigned int ref_handle; 122 unsigned int ref_handle;
@@ -175,7 +171,9 @@ struct mgmt_hba_attributes {
175 u8 phy_port; 171 u8 phy_port;
176 u32 firmware_post_status; 172 u32 firmware_post_status;
177 u32 hba_mtu[8]; 173 u32 hba_mtu[8];
178 u32 future_u32[4]; 174 u8 iscsi_features;
175 u8 future_u8[3];
176 u32 future_u32[3];
179} __packed; 177} __packed;
180 178
181struct mgmt_controller_attributes { 179struct mgmt_controller_attributes {
@@ -229,6 +227,7 @@ struct beiscsi_endpoint {
229 struct beiscsi_hba *phba; 227 struct beiscsi_hba *phba;
230 struct beiscsi_sess *sess; 228 struct beiscsi_sess *sess;
231 struct beiscsi_conn *conn; 229 struct beiscsi_conn *conn;
230 struct iscsi_endpoint *openiscsi_ep;
232 unsigned short ip_type; 231 unsigned short ip_type;
233 char dst6_addr[ISCSI_ADDRESS_BUF_LEN]; 232 char dst6_addr[ISCSI_ADDRESS_BUF_LEN];
234 unsigned long dst_addr; 233 unsigned long dst_addr;
@@ -246,4 +245,5 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
246 unsigned short cid, 245 unsigned short cid,
247 unsigned short issue_reset, 246 unsigned short issue_reset,
248 unsigned short savecfg_flag); 247 unsigned short savecfg_flag);
248
249#endif 249#endif