diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2009-10-23 02:22:33 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:38 -0500 |
commit | bfead3b2cb4607c71831423c3ee97d22cd0c9dcb (patch) | |
tree | 13822ffd73826b315f8be0077c0dc9b65ab3ff86 /drivers/scsi/be2iscsi | |
parent | b4a9c7ede96e90f7b1ec009ce7256059295e76df (diff) |
[SCSI] be2iscsi: Adding msix and mcc_rings V3
This patch enables msix for be2iscsi. It also enables use
of mcc_rings for fw commands. Since the mcc eq creation is
dependent on msix I am sending as one patch
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 24 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 263 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 37 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 23 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 888 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 49 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 69 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 8 |
8 files changed, 1030 insertions, 331 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index b36020dcf012..a93a5040f087 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h | |||
@@ -20,8 +20,10 @@ | |||
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 | ||
25 | 27 | ||
26 | struct be_dma_mem { | 28 | struct be_dma_mem { |
27 | void *va; | 29 | void *va; |
@@ -74,18 +76,14 @@ static inline void queue_tail_inc(struct be_queue_info *q) | |||
74 | 76 | ||
75 | struct be_eq_obj { | 77 | struct be_eq_obj { |
76 | struct be_queue_info q; | 78 | struct be_queue_info q; |
77 | char desc[32]; | 79 | struct beiscsi_hba *phba; |
78 | 80 | struct be_queue_info *cq; | |
79 | /* Adaptive interrupt coalescing (AIC) info */ | 81 | 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 | }; | 82 | }; |
85 | 83 | ||
86 | struct be_mcc_obj { | 84 | struct be_mcc_obj { |
87 | struct be_queue_info *q; | 85 | struct be_queue_info q; |
88 | struct be_queue_info *cq; | 86 | struct be_queue_info cq; |
89 | }; | 87 | }; |
90 | 88 | ||
91 | struct be_ctrl_info { | 89 | struct be_ctrl_info { |
@@ -176,8 +174,4 @@ static inline void swap_dws(void *wrb, int len) | |||
176 | } while (len); | 174 | } while (len); |
177 | #endif /* __BIG_ENDIAN */ | 175 | #endif /* __BIG_ENDIAN */ |
178 | } | 176 | } |
179 | |||
180 | extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm, | ||
181 | u16 num_popped); | ||
182 | |||
183 | #endif /* BEISCSI_H */ | 177 | #endif /* BEISCSI_H */ |
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 08007b6e42df..10f8fe7a38d2 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -19,6 +19,16 @@ | |||
19 | #include "be_mgmt.h" | 19 | #include "be_mgmt.h" |
20 | #include "be_main.h" | 20 | #include "be_main.h" |
21 | 21 | ||
22 | static void 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 | |||
22 | static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) | 32 | static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) |
23 | { | 33 | { |
24 | if (compl->flags != 0) { | 34 | if (compl->flags != 0) { |
@@ -54,13 +64,56 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, | |||
54 | return 0; | 64 | return 0; |
55 | } | 65 | } |
56 | 66 | ||
67 | |||
57 | static inline bool is_link_state_evt(u32 trailer) | 68 | static inline bool is_link_state_evt(u32 trailer) |
58 | { | 69 | { |
59 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | 70 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & |
60 | ASYNC_TRAILER_EVENT_CODE_MASK) == ASYNC_EVENT_CODE_LINK_STATE); | 71 | ASYNC_TRAILER_EVENT_CODE_MASK) == |
72 | ASYNC_EVENT_CODE_LINK_STATE); | ||
73 | } | ||
74 | |||
75 | static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba) | ||
76 | { | ||
77 | struct be_queue_info *mcc_cq = &phba->ctrl.mcc_obj.cq; | ||
78 | struct be_mcc_compl *compl = queue_tail_node(mcc_cq); | ||
79 | |||
80 | if (be_mcc_compl_is_new(compl)) { | ||
81 | queue_tail_inc(mcc_cq); | ||
82 | return compl; | ||
83 | } | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session) | ||
88 | { | ||
89 | iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); | ||
90 | } | ||
91 | |||
92 | static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | ||
93 | struct be_async_event_link_state *evt) | ||
94 | { | ||
95 | switch (evt->port_link_status) { | ||
96 | case ASYNC_EVENT_LINK_DOWN: | ||
97 | SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", | ||
98 | evt->physical_port); | ||
99 | phba->state |= BE_ADAPTER_LINK_DOWN; | ||
100 | break; | ||
101 | case ASYNC_EVENT_LINK_UP: | ||
102 | phba->state = BE_ADAPTER_UP; | ||
103 | SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", | ||
104 | evt->physical_port); | ||
105 | iscsi_host_for_each_session(phba->shost, | ||
106 | be2iscsi_fail_session); | ||
107 | break; | ||
108 | default: | ||
109 | SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" | ||
110 | "Physical Port %d \n", | ||
111 | evt->port_link_status, | ||
112 | evt->physical_port); | ||
113 | } | ||
61 | } | 114 | } |
62 | 115 | ||
63 | void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm, | 116 | static void beiscsi_cq_notify(struct beiscsi_hba *phba, u16 qid, bool arm, |
64 | u16 num_popped) | 117 | u16 num_popped) |
65 | { | 118 | { |
66 | u32 val = 0; | 119 | u32 val = 0; |
@@ -68,7 +121,66 @@ void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm, | |||
68 | if (arm) | 121 | if (arm) |
69 | val |= 1 << DB_CQ_REARM_SHIFT; | 122 | val |= 1 << DB_CQ_REARM_SHIFT; |
70 | val |= num_popped << DB_CQ_NUM_POPPED_SHIFT; | 123 | val |= num_popped << DB_CQ_NUM_POPPED_SHIFT; |
71 | iowrite32(val, ctrl->db + DB_CQ_OFFSET); | 124 | iowrite32(val, phba->db_va + DB_CQ_OFFSET); |
125 | } | ||
126 | |||
127 | |||
128 | int be_process_mcc(struct beiscsi_hba *phba) | ||
129 | { | ||
130 | struct be_mcc_compl *compl; | ||
131 | int num = 0, status = 0; | ||
132 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
133 | |||
134 | spin_lock_bh(&phba->ctrl.mcc_cq_lock); | ||
135 | while ((compl = be_mcc_compl_get(phba))) { | ||
136 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { | ||
137 | /* Interpret flags as an async trailer */ | ||
138 | BUG_ON(!is_link_state_evt(compl->flags)); | ||
139 | |||
140 | /* Interpret compl as a async link evt */ | ||
141 | beiscsi_async_link_state_process(phba, | ||
142 | (struct be_async_event_link_state *) compl); | ||
143 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | ||
144 | status = be_mcc_compl_process(ctrl, compl); | ||
145 | atomic_dec(&phba->ctrl.mcc_obj.q.used); | ||
146 | } | ||
147 | be_mcc_compl_use(compl); | ||
148 | num++; | ||
149 | } | ||
150 | |||
151 | if (num) | ||
152 | beiscsi_cq_notify(phba, phba->ctrl.mcc_obj.cq.id, true, num); | ||
153 | |||
154 | spin_unlock_bh(&phba->ctrl.mcc_cq_lock); | ||
155 | return status; | ||
156 | } | ||
157 | |||
158 | /* Wait till no more pending mcc requests are present */ | ||
159 | static int be_mcc_wait_compl(struct beiscsi_hba *phba) | ||
160 | { | ||
161 | #define mcc_timeout 120000 /* 5s timeout */ | ||
162 | int i, status; | ||
163 | for (i = 0; i < mcc_timeout; i++) { | ||
164 | status = be_process_mcc(phba); | ||
165 | if (status) | ||
166 | return status; | ||
167 | |||
168 | if (atomic_read(&phba->ctrl.mcc_obj.q.used) == 0) | ||
169 | break; | ||
170 | udelay(100); | ||
171 | } | ||
172 | if (i == mcc_timeout) { | ||
173 | dev_err(&phba->pcidev->dev, "mccq poll timed out\n"); | ||
174 | return -1; | ||
175 | } | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | /* Notify MCC requests and wait for completion */ | ||
180 | int be_mcc_notify_wait(struct beiscsi_hba *phba) | ||
181 | { | ||
182 | be_mcc_notify(phba); | ||
183 | return be_mcc_wait_compl(phba); | ||
72 | } | 184 | } |
73 | 185 | ||
74 | static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) | 186 | static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) |
@@ -142,6 +254,52 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) | |||
142 | return 0; | 254 | return 0; |
143 | } | 255 | } |
144 | 256 | ||
257 | /* | ||
258 | * Insert the mailbox address into the doorbell in two steps | ||
259 | * Polls on the mbox doorbell till a command completion (or a timeout) occurs | ||
260 | */ | ||
261 | static int be_mbox_notify_wait(struct beiscsi_hba *phba) | ||
262 | { | ||
263 | int status; | ||
264 | u32 val = 0; | ||
265 | void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET; | ||
266 | struct be_dma_mem *mbox_mem = &phba->ctrl.mbox_mem; | ||
267 | struct be_mcc_mailbox *mbox = mbox_mem->va; | ||
268 | struct be_mcc_compl *compl = &mbox->compl; | ||
269 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
270 | |||
271 | val |= MPU_MAILBOX_DB_HI_MASK; | ||
272 | /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */ | ||
273 | val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2; | ||
274 | iowrite32(val, db); | ||
275 | |||
276 | /* wait for ready to be set */ | ||
277 | status = be_mbox_db_ready_wait(ctrl); | ||
278 | if (status != 0) | ||
279 | return status; | ||
280 | |||
281 | val = 0; | ||
282 | /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */ | ||
283 | val |= (u32)(mbox_mem->dma >> 4) << 2; | ||
284 | iowrite32(val, db); | ||
285 | |||
286 | status = be_mbox_db_ready_wait(ctrl); | ||
287 | if (status != 0) | ||
288 | return status; | ||
289 | |||
290 | /* A cq entry has been made now */ | ||
291 | if (be_mcc_compl_is_new(compl)) { | ||
292 | status = be_mcc_compl_process(ctrl, &mbox->compl); | ||
293 | be_mcc_compl_use(compl); | ||
294 | if (status) | ||
295 | return status; | ||
296 | } else { | ||
297 | dev_err(&phba->pcidev->dev, "invalid mailbox completion\n"); | ||
298 | return -1; | ||
299 | } | ||
300 | return 0; | ||
301 | } | ||
302 | |||
145 | void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, | 303 | void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, |
146 | bool embedded, u8 sge_cnt) | 304 | bool embedded, u8 sge_cnt) |
147 | { | 305 | { |
@@ -203,6 +361,20 @@ struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem) | |||
203 | return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; | 361 | return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; |
204 | } | 362 | } |
205 | 363 | ||
364 | struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba) | ||
365 | { | ||
366 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
367 | struct be_mcc_wrb *wrb; | ||
368 | |||
369 | BUG_ON(atomic_read(&mccq->used) >= mccq->len); | ||
370 | wrb = queue_head_node(mccq); | ||
371 | queue_head_inc(mccq); | ||
372 | atomic_inc(&mccq->used); | ||
373 | memset(wrb, 0, sizeof(*wrb)); | ||
374 | return wrb; | ||
375 | } | ||
376 | |||
377 | |||
206 | int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, | 378 | int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, |
207 | struct be_queue_info *eq, int eq_delay) | 379 | struct be_queue_info *eq, int eq_delay) |
208 | { | 380 | { |
@@ -212,6 +384,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, | |||
212 | struct be_dma_mem *q_mem = &eq->dma_mem; | 384 | struct be_dma_mem *q_mem = &eq->dma_mem; |
213 | int status; | 385 | int status; |
214 | 386 | ||
387 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_eq_create\n"); | ||
215 | spin_lock(&ctrl->mbox_lock); | 388 | spin_lock(&ctrl->mbox_lock); |
216 | memset(wrb, 0, sizeof(*wrb)); | 389 | memset(wrb, 0, sizeof(*wrb)); |
217 | 390 | ||
@@ -249,6 +422,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl) | |||
249 | int status; | 422 | int status; |
250 | u8 *endian_check; | 423 | u8 *endian_check; |
251 | 424 | ||
425 | SE_DEBUG(DBG_LVL_8, "In be_cmd_fw_initialize\n"); | ||
252 | spin_lock(&ctrl->mbox_lock); | 426 | spin_lock(&ctrl->mbox_lock); |
253 | memset(wrb, 0, sizeof(*wrb)); | 427 | memset(wrb, 0, sizeof(*wrb)); |
254 | 428 | ||
@@ -282,6 +456,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, | |||
282 | void *ctxt = &req->context; | 456 | void *ctxt = &req->context; |
283 | int status; | 457 | int status; |
284 | 458 | ||
459 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n"); | ||
285 | spin_lock(&ctrl->mbox_lock); | 460 | spin_lock(&ctrl->mbox_lock); |
286 | memset(wrb, 0, sizeof(*wrb)); | 461 | memset(wrb, 0, sizeof(*wrb)); |
287 | 462 | ||
@@ -289,7 +464,6 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, | |||
289 | 464 | ||
290 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 465 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
291 | OPCODE_COMMON_CQ_CREATE, sizeof(*req)); | 466 | OPCODE_COMMON_CQ_CREATE, sizeof(*req)); |
292 | |||
293 | if (!q_mem->va) | 467 | if (!q_mem->va) |
294 | SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n"); | 468 | SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n"); |
295 | 469 | ||
@@ -329,6 +503,53 @@ static u32 be_encoded_q_len(int q_len) | |||
329 | len_encoded = 0; | 503 | len_encoded = 0; |
330 | return len_encoded; | 504 | return len_encoded; |
331 | } | 505 | } |
506 | |||
507 | int be_cmd_mccq_create(struct beiscsi_hba *phba, | ||
508 | struct be_queue_info *mccq, | ||
509 | struct be_queue_info *cq) | ||
510 | { | ||
511 | struct be_mcc_wrb *wrb; | ||
512 | struct be_cmd_req_mcc_create *req; | ||
513 | struct be_dma_mem *q_mem = &mccq->dma_mem; | ||
514 | struct be_ctrl_info *ctrl; | ||
515 | void *ctxt; | ||
516 | int status; | ||
517 | |||
518 | spin_lock(&phba->ctrl.mbox_lock); | ||
519 | ctrl = &phba->ctrl; | ||
520 | wrb = wrb_from_mbox(&ctrl->mbox_mem); | ||
521 | req = embedded_payload(wrb); | ||
522 | ctxt = &req->context; | ||
523 | |||
524 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | ||
525 | |||
526 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
527 | OPCODE_COMMON_MCC_CREATE, sizeof(*req)); | ||
528 | |||
529 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | ||
530 | |||
531 | AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, | ||
532 | PCI_FUNC(phba->pcidev->devfn)); | ||
533 | AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); | ||
534 | AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, | ||
535 | be_encoded_q_len(mccq->len)); | ||
536 | AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id); | ||
537 | |||
538 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); | ||
539 | |||
540 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | ||
541 | |||
542 | status = be_mbox_notify_wait(phba); | ||
543 | if (!status) { | ||
544 | struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb); | ||
545 | mccq->id = le16_to_cpu(resp->id); | ||
546 | mccq->created = true; | ||
547 | } | ||
548 | spin_unlock(&phba->ctrl.mbox_lock); | ||
549 | |||
550 | return status; | ||
551 | } | ||
552 | |||
332 | int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | 553 | int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, |
333 | int queue_type) | 554 | int queue_type) |
334 | { | 555 | { |
@@ -337,6 +558,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
337 | u8 subsys = 0, opcode = 0; | 558 | u8 subsys = 0, opcode = 0; |
338 | int status; | 559 | int status; |
339 | 560 | ||
561 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n"); | ||
340 | spin_lock(&ctrl->mbox_lock); | 562 | spin_lock(&ctrl->mbox_lock); |
341 | memset(wrb, 0, sizeof(*wrb)); | 563 | memset(wrb, 0, sizeof(*wrb)); |
342 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 564 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -350,6 +572,10 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
350 | subsys = CMD_SUBSYSTEM_COMMON; | 572 | subsys = CMD_SUBSYSTEM_COMMON; |
351 | opcode = OPCODE_COMMON_CQ_DESTROY; | 573 | opcode = OPCODE_COMMON_CQ_DESTROY; |
352 | break; | 574 | break; |
575 | case QTYPE_MCCQ: | ||
576 | subsys = CMD_SUBSYSTEM_COMMON; | ||
577 | opcode = OPCODE_COMMON_MCC_DESTROY; | ||
578 | break; | ||
353 | case QTYPE_WRBQ: | 579 | case QTYPE_WRBQ: |
354 | subsys = CMD_SUBSYSTEM_ISCSI; | 580 | subsys = CMD_SUBSYSTEM_ISCSI; |
355 | opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY; | 581 | opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY; |
@@ -377,30 +603,6 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
377 | return status; | 603 | return status; |
378 | } | 604 | } |
379 | 605 | ||
380 | int 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 | |||
404 | int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, | 606 | int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, |
405 | struct be_queue_info *cq, | 607 | struct be_queue_info *cq, |
406 | struct be_queue_info *dq, int length, | 608 | struct be_queue_info *dq, int length, |
@@ -412,6 +614,7 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, | |||
412 | void *ctxt = &req->context; | 614 | void *ctxt = &req->context; |
413 | int status; | 615 | int status; |
414 | 616 | ||
617 | SE_DEBUG(DBG_LVL_8, "In be_cmd_create_default_pdu_queue\n"); | ||
415 | spin_lock(&ctrl->mbox_lock); | 618 | spin_lock(&ctrl->mbox_lock); |
416 | memset(wrb, 0, sizeof(*wrb)); | 619 | memset(wrb, 0, sizeof(*wrb)); |
417 | 620 | ||
@@ -468,8 +671,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); | 671 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); |
469 | 672 | ||
470 | status = be_mbox_notify(ctrl); | 673 | status = be_mbox_notify(ctrl); |
471 | if (!status) | 674 | if (!status) { |
472 | wrbq->id = le16_to_cpu(resp->cid); | 675 | wrbq->id = le16_to_cpu(resp->cid); |
676 | wrbq->created = true; | ||
677 | } | ||
473 | spin_unlock(&ctrl->mbox_lock); | 678 | spin_unlock(&ctrl->mbox_lock); |
474 | return status; | 679 | return status; |
475 | } | 680 | } |
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index c20d686cbb43..76fe1f9dd4cb 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -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 | ||
179 | struct be_cmd_resp_hdr { | 181 | struct 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 | |||
386 | struct be_cmd_req_get_mac_addr { | 387 | struct 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,21 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, | |||
417 | 418 | ||
418 | int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | 419 | int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, |
419 | int type); | 420 | int type); |
421 | int be_cmd_mccq_create(struct beiscsi_hba *phba, | ||
422 | struct be_queue_info *mccq, | ||
423 | struct be_queue_info *cq); | ||
424 | |||
420 | int be_poll_mcc(struct be_ctrl_info *ctrl); | 425 | int be_poll_mcc(struct be_ctrl_info *ctrl); |
421 | unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl); | 426 | unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, |
422 | int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr); | 427 | struct beiscsi_hba *phba); |
428 | int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr); | ||
423 | 429 | ||
424 | /*ISCSI Functuions */ | 430 | /*ISCSI Functuions */ |
425 | int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); | 431 | int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); |
426 | 432 | ||
427 | struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); | 433 | struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); |
434 | struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba); | ||
435 | int be_mcc_notify_wait(struct beiscsi_hba *phba); | ||
428 | 436 | ||
429 | int be_mbox_notify(struct be_ctrl_info *ctrl); | 437 | int be_mbox_notify(struct be_ctrl_info *ctrl); |
430 | 438 | ||
@@ -531,6 +539,23 @@ struct amap_sol_cqe { | |||
531 | u8 valid; /* dword 3 */ | 539 | u8 valid; /* dword 3 */ |
532 | } __packed; | 540 | } __packed; |
533 | 541 | ||
542 | #define SOL_ICD_INDEX_MASK 0x0003FFC0 | ||
543 | struct amap_sol_cqe_ring { | ||
544 | u8 hw_sts[8]; /* dword 0 */ | ||
545 | u8 i_sts[8]; /* dword 0 */ | ||
546 | u8 i_resp[8]; /* dword 0 */ | ||
547 | u8 i_flags[7]; /* dword 0 */ | ||
548 | u8 s; /* dword 0 */ | ||
549 | u8 i_exp_cmd_sn[32]; /* dword 1 */ | ||
550 | u8 code[6]; /* dword 2 */ | ||
551 | u8 icd_index[12]; /* dword 2 */ | ||
552 | u8 rsvd[6]; /* dword 2 */ | ||
553 | u8 i_cmd_wnd[8]; /* dword 2 */ | ||
554 | u8 i_res_cnt[31]; /* dword 3 */ | ||
555 | u8 valid; /* dword 3 */ | ||
556 | } __packed; | ||
557 | |||
558 | |||
534 | 559 | ||
535 | /** | 560 | /** |
536 | * Post WRB Queue Doorbell Register used by the host Storage | 561 | * Post WRB Queue Doorbell Register used by the host Storage |
@@ -664,8 +689,8 @@ struct be_fw_cfg { | |||
664 | #define OPCODE_COMMON_TCP_UPLOAD 56 | 689 | #define OPCODE_COMMON_TCP_UPLOAD 56 |
665 | #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1 | 690 | #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1 |
666 | /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ | 691 | /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ |
667 | #define CMD_ISCSI_CONNECTION_INVALIDATE 1 | 692 | #define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001 |
668 | #define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 2 | 693 | #define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002 |
669 | #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 | 694 | #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 |
670 | 695 | ||
671 | #define INI_WR_CMD 1 /* Initiator write command */ | 696 | #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..d587b0362f18 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -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; |
@@ -297,7 +297,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
297 | 297 | ||
298 | switch (param) { | 298 | switch (param) { |
299 | case ISCSI_HOST_PARAM_HWADDRESS: | 299 | case ISCSI_HOST_PARAM_HWADDRESS: |
300 | be_cmd_get_mac_addr(&phba->ctrl, phba->mac_address); | 300 | be_cmd_get_mac_addr(phba, phba->mac_address); |
301 | len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); | 301 | len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); |
302 | break; | 302 | break; |
303 | default: | 303 | default: |
@@ -377,16 +377,12 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
377 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 377 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
378 | struct beiscsi_endpoint *beiscsi_ep; | 378 | struct beiscsi_endpoint *beiscsi_ep; |
379 | struct beiscsi_offload_params params; | 379 | 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 | 380 | ||
384 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); | 381 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); |
385 | beiscsi_ep = beiscsi_conn->ep; | 382 | beiscsi_ep = beiscsi_conn->ep; |
386 | if (!beiscsi_ep) | 383 | if (!beiscsi_ep) |
387 | SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n"); | 384 | SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n"); |
388 | 385 | ||
389 | free_mgmt_sgl_handle(phba, beiscsi_conn->plogin_sgl_handle); | ||
390 | beiscsi_conn->login_in_progress = 0; | 386 | beiscsi_conn->login_in_progress = 0; |
391 | beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); | 387 | beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); |
392 | beiscsi_offload_connection(beiscsi_conn, ¶ms); | 388 | beiscsi_offload_connection(beiscsi_conn, ¶ms); |
@@ -498,6 +494,13 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
498 | SE_DEBUG(DBG_LVL_1, "shost is NULL \n"); | 494 | SE_DEBUG(DBG_LVL_1, "shost is NULL \n"); |
499 | return ERR_PTR(ret); | 495 | return ERR_PTR(ret); |
500 | } | 496 | } |
497 | |||
498 | if (phba->state) { | ||
499 | ret = -EBUSY; | ||
500 | SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n"); | ||
501 | return ERR_PTR(ret); | ||
502 | } | ||
503 | |||
501 | ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); | 504 | ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); |
502 | if (!ep) { | 505 | if (!ep) { |
503 | ret = -ENOMEM; | 506 | ret = -ENOMEM; |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 4f1aca346e38..2c3e99eeff82 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | static unsigned int be_iopoll_budget = 10; | 40 | static unsigned int be_iopoll_budget = 10; |
41 | static unsigned int be_max_phys_size = 64; | 41 | static unsigned int be_max_phys_size = 64; |
42 | static unsigned int enable_msix; | 42 | static unsigned int enable_msix = 1; |
43 | 43 | ||
44 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | 44 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); |
45 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); | 45 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); |
@@ -58,6 +58,17 @@ static int beiscsi_slave_configure(struct scsi_device *sdev) | |||
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | /*------------------- PCI Driver operations and data ----------------- */ | ||
62 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { | ||
63 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | ||
64 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, | ||
65 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, | ||
66 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) }, | ||
67 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID4) }, | ||
68 | { 0 } | ||
69 | }; | ||
70 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | ||
71 | |||
61 | static struct scsi_host_template beiscsi_sht = { | 72 | static struct scsi_host_template beiscsi_sht = { |
62 | .module = THIS_MODULE, | 73 | .module = THIS_MODULE, |
63 | .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", | 74 | .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", |
@@ -76,16 +87,8 @@ static struct scsi_host_template beiscsi_sht = { | |||
76 | .cmd_per_lun = BEISCSI_CMD_PER_LUN, | 87 | .cmd_per_lun = BEISCSI_CMD_PER_LUN, |
77 | .use_clustering = ENABLE_CLUSTERING, | 88 | .use_clustering = ENABLE_CLUSTERING, |
78 | }; | 89 | }; |
79 | static struct scsi_transport_template *beiscsi_scsi_transport; | ||
80 | 90 | ||
81 | /*------------------- PCI Driver operations and data ----------------- */ | 91 | static struct scsi_transport_template *beiscsi_scsi_transport; |
82 | static 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 | }; | ||
88 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | ||
89 | 92 | ||
90 | static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) | 93 | static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) |
91 | { | 94 | { |
@@ -104,7 +107,6 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) | |||
104 | shost->max_cmd_len = BEISCSI_MAX_CMD_LEN; | 107 | shost->max_cmd_len = BEISCSI_MAX_CMD_LEN; |
105 | shost->max_lun = BEISCSI_NUM_MAX_LUN; | 108 | shost->max_lun = BEISCSI_NUM_MAX_LUN; |
106 | shost->transportt = beiscsi_scsi_transport; | 109 | shost->transportt = beiscsi_scsi_transport; |
107 | |||
108 | phba = iscsi_host_priv(shost); | 110 | phba = iscsi_host_priv(shost); |
109 | memset(phba, 0, sizeof(*phba)); | 111 | memset(phba, 0, sizeof(*phba)); |
110 | phba->shost = shost; | 112 | phba->shost = shost; |
@@ -181,6 +183,7 @@ static int beiscsi_enable_pci(struct pci_dev *pcidev) | |||
181 | return ret; | 183 | return ret; |
182 | } | 184 | } |
183 | 185 | ||
186 | pci_set_master(pcidev); | ||
184 | if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) { | 187 | if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) { |
185 | ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32)); | 188 | ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32)); |
186 | if (ret) { | 189 | if (ret) { |
@@ -203,7 +206,6 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev) | |||
203 | status = beiscsi_map_pci_bars(phba, pdev); | 206 | status = beiscsi_map_pci_bars(phba, pdev); |
204 | if (status) | 207 | if (status) |
205 | return status; | 208 | return status; |
206 | |||
207 | mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; | 209 | mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; |
208 | mbox_mem_alloc->va = pci_alloc_consistent(pdev, | 210 | mbox_mem_alloc->va = pci_alloc_consistent(pdev, |
209 | mbox_mem_alloc->size, | 211 | mbox_mem_alloc->size, |
@@ -219,6 +221,9 @@ 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); | 221 | mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); |
220 | memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); | 222 | memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); |
221 | spin_lock_init(&ctrl->mbox_lock); | 223 | spin_lock_init(&ctrl->mbox_lock); |
224 | spin_lock_init(&phba->ctrl.mcc_lock); | ||
225 | spin_lock_init(&phba->ctrl.mcc_cq_lock); | ||
226 | |||
222 | return status; | 227 | return status; |
223 | } | 228 | } |
224 | 229 | ||
@@ -268,6 +273,113 @@ static void hwi_ring_eq_db(struct beiscsi_hba *phba, | |||
268 | } | 273 | } |
269 | 274 | ||
270 | /** | 275 | /** |
276 | * be_isr_mcc - The isr routine of the driver. | ||
277 | * @irq: Not used | ||
278 | * @dev_id: Pointer to host adapter structure | ||
279 | */ | ||
280 | static irqreturn_t be_isr_mcc(int irq, void *dev_id) | ||
281 | { | ||
282 | struct beiscsi_hba *phba; | ||
283 | struct be_eq_entry *eqe = NULL; | ||
284 | struct be_queue_info *eq; | ||
285 | struct be_queue_info *mcc; | ||
286 | unsigned int num_eq_processed; | ||
287 | struct be_eq_obj *pbe_eq; | ||
288 | unsigned long flags; | ||
289 | |||
290 | pbe_eq = dev_id; | ||
291 | eq = &pbe_eq->q; | ||
292 | phba = pbe_eq->phba; | ||
293 | mcc = &phba->ctrl.mcc_obj.cq; | ||
294 | eqe = queue_tail_node(eq); | ||
295 | if (!eqe) | ||
296 | SE_DEBUG(DBG_LVL_1, "eqe is NULL\n"); | ||
297 | |||
298 | num_eq_processed = 0; | ||
299 | |||
300 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | ||
301 | & EQE_VALID_MASK) { | ||
302 | if (((eqe->dw[offsetof(struct amap_eq_entry, | ||
303 | resource_id) / 32] & | ||
304 | EQE_RESID_MASK) >> 16) == mcc->id) { | ||
305 | spin_lock_irqsave(&phba->isr_lock, flags); | ||
306 | phba->todo_mcc_cq = 1; | ||
307 | spin_unlock_irqrestore(&phba->isr_lock, flags); | ||
308 | } | ||
309 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | ||
310 | queue_tail_inc(eq); | ||
311 | eqe = queue_tail_node(eq); | ||
312 | num_eq_processed++; | ||
313 | } | ||
314 | if (phba->todo_mcc_cq) | ||
315 | queue_work(phba->wq, &phba->work_cqs); | ||
316 | if (num_eq_processed) | ||
317 | hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 1, 1); | ||
318 | |||
319 | return IRQ_HANDLED; | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * be_isr_msix - The isr routine of the driver. | ||
324 | * @irq: Not used | ||
325 | * @dev_id: Pointer to host adapter structure | ||
326 | */ | ||
327 | static irqreturn_t be_isr_msix(int irq, void *dev_id) | ||
328 | { | ||
329 | struct beiscsi_hba *phba; | ||
330 | struct be_eq_entry *eqe = NULL; | ||
331 | struct be_queue_info *eq; | ||
332 | struct be_queue_info *cq; | ||
333 | unsigned int num_eq_processed; | ||
334 | struct be_eq_obj *pbe_eq; | ||
335 | unsigned long flags; | ||
336 | |||
337 | pbe_eq = dev_id; | ||
338 | eq = &pbe_eq->q; | ||
339 | cq = pbe_eq->cq; | ||
340 | eqe = queue_tail_node(eq); | ||
341 | if (!eqe) | ||
342 | SE_DEBUG(DBG_LVL_1, "eqe is NULL\n"); | ||
343 | |||
344 | phba = pbe_eq->phba; | ||
345 | num_eq_processed = 0; | ||
346 | if (blk_iopoll_enabled) { | ||
347 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | ||
348 | & EQE_VALID_MASK) { | ||
349 | if (!blk_iopoll_sched_prep(&pbe_eq->iopoll)) | ||
350 | blk_iopoll_sched(&pbe_eq->iopoll); | ||
351 | |||
352 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | ||
353 | queue_tail_inc(eq); | ||
354 | eqe = queue_tail_node(eq); | ||
355 | num_eq_processed++; | ||
356 | } | ||
357 | if (num_eq_processed) | ||
358 | hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1); | ||
359 | |||
360 | return IRQ_HANDLED; | ||
361 | } else { | ||
362 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | ||
363 | & EQE_VALID_MASK) { | ||
364 | spin_lock_irqsave(&phba->isr_lock, flags); | ||
365 | phba->todo_cq = 1; | ||
366 | spin_unlock_irqrestore(&phba->isr_lock, flags); | ||
367 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | ||
368 | queue_tail_inc(eq); | ||
369 | eqe = queue_tail_node(eq); | ||
370 | num_eq_processed++; | ||
371 | } | ||
372 | if (phba->todo_cq) | ||
373 | queue_work(phba->wq, &phba->work_cqs); | ||
374 | |||
375 | if (num_eq_processed) | ||
376 | hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 1, 1); | ||
377 | |||
378 | return IRQ_HANDLED; | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /** | ||
271 | * be_isr - The isr routine of the driver. | 383 | * be_isr - The isr routine of the driver. |
272 | * @irq: Not used | 384 | * @irq: Not used |
273 | * @dev_id: Pointer to host adapter structure | 385 | * @dev_id: Pointer to host adapter structure |
@@ -280,48 +392,70 @@ static irqreturn_t be_isr(int irq, void *dev_id) | |||
280 | struct be_eq_entry *eqe = NULL; | 392 | struct be_eq_entry *eqe = NULL; |
281 | struct be_queue_info *eq; | 393 | struct be_queue_info *eq; |
282 | struct be_queue_info *cq; | 394 | struct be_queue_info *cq; |
395 | struct be_queue_info *mcc; | ||
283 | unsigned long flags, index; | 396 | unsigned long flags, index; |
284 | unsigned int num_eq_processed; | 397 | unsigned int num_mcceq_processed, num_ioeq_processed; |
285 | struct be_ctrl_info *ctrl; | 398 | struct be_ctrl_info *ctrl; |
399 | struct be_eq_obj *pbe_eq; | ||
286 | int isr; | 400 | int isr; |
287 | 401 | ||
288 | phba = dev_id; | 402 | phba = dev_id; |
289 | if (!enable_msix) { | 403 | ctrl = &phba->ctrl;; |
290 | ctrl = &phba->ctrl;; | 404 | isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET + |
291 | isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET + | 405 | (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE)); |
292 | (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE)); | 406 | if (!isr) |
293 | if (!isr) | 407 | return IRQ_NONE; |
294 | return IRQ_NONE; | ||
295 | } | ||
296 | 408 | ||
297 | phwi_ctrlr = phba->phwi_ctrlr; | 409 | phwi_ctrlr = phba->phwi_ctrlr; |
298 | phwi_context = phwi_ctrlr->phwi_ctxt; | 410 | phwi_context = phwi_ctrlr->phwi_ctxt; |
299 | eq = &phwi_context->be_eq.q; | 411 | pbe_eq = &phwi_context->be_eq[0]; |
300 | cq = &phwi_context->be_cq; | 412 | |
413 | eq = &phwi_context->be_eq[0].q; | ||
414 | mcc = &phba->ctrl.mcc_obj.cq; | ||
301 | index = 0; | 415 | index = 0; |
302 | eqe = queue_tail_node(eq); | 416 | eqe = queue_tail_node(eq); |
303 | if (!eqe) | 417 | if (!eqe) |
304 | SE_DEBUG(DBG_LVL_1, "eqe is NULL\n"); | 418 | SE_DEBUG(DBG_LVL_1, "eqe is NULL\n"); |
305 | 419 | ||
306 | num_eq_processed = 0; | 420 | num_ioeq_processed = 0; |
421 | num_mcceq_processed = 0; | ||
307 | if (blk_iopoll_enabled) { | 422 | if (blk_iopoll_enabled) { |
308 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | 423 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] |
309 | & EQE_VALID_MASK) { | 424 | & EQE_VALID_MASK) { |
310 | if (!blk_iopoll_sched_prep(&phba->iopoll)) | 425 | if (((eqe->dw[offsetof(struct amap_eq_entry, |
311 | blk_iopoll_sched(&phba->iopoll); | 426 | resource_id) / 32] & |
312 | 427 | EQE_RESID_MASK) >> 16) == mcc->id) { | |
428 | spin_lock_irqsave(&phba->isr_lock, flags); | ||
429 | phba->todo_mcc_cq = 1; | ||
430 | spin_unlock_irqrestore(&phba->isr_lock, flags); | ||
431 | num_mcceq_processed++; | ||
432 | } else { | ||
433 | if (!blk_iopoll_sched_prep(&pbe_eq->iopoll)) | ||
434 | blk_iopoll_sched(&pbe_eq->iopoll); | ||
435 | num_ioeq_processed++; | ||
436 | } | ||
313 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | 437 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); |
314 | queue_tail_inc(eq); | 438 | queue_tail_inc(eq); |
315 | eqe = queue_tail_node(eq); | 439 | eqe = queue_tail_node(eq); |
316 | num_eq_processed++; | ||
317 | SE_DEBUG(DBG_LVL_8, "Valid EQE\n"); | ||
318 | } | 440 | } |
319 | if (num_eq_processed) { | 441 | if (num_ioeq_processed || num_mcceq_processed) { |
320 | hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 0, 1); | 442 | if (phba->todo_mcc_cq) |
443 | queue_work(phba->wq, &phba->work_cqs); | ||
444 | |||
445 | if ((num_mcceq_processed) && (!num_ioeq_processed)) | ||
446 | hwi_ring_eq_db(phba, eq->id, 0, | ||
447 | (num_ioeq_processed + | ||
448 | num_mcceq_processed) , 1, 1); | ||
449 | else | ||
450 | hwi_ring_eq_db(phba, eq->id, 0, | ||
451 | (num_ioeq_processed + | ||
452 | num_mcceq_processed), 0, 1); | ||
453 | |||
321 | return IRQ_HANDLED; | 454 | return IRQ_HANDLED; |
322 | } else | 455 | } else |
323 | return IRQ_NONE; | 456 | return IRQ_NONE; |
324 | } else { | 457 | } else { |
458 | cq = &phwi_context->be_cq[0]; | ||
325 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | 459 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] |
326 | & EQE_VALID_MASK) { | 460 | & EQE_VALID_MASK) { |
327 | 461 | ||
@@ -339,13 +473,14 @@ static irqreturn_t be_isr(int irq, void *dev_id) | |||
339 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | 473 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); |
340 | queue_tail_inc(eq); | 474 | queue_tail_inc(eq); |
341 | eqe = queue_tail_node(eq); | 475 | eqe = queue_tail_node(eq); |
342 | num_eq_processed++; | 476 | num_ioeq_processed++; |
343 | } | 477 | } |
344 | if (phba->todo_cq || phba->todo_mcc_cq) | 478 | if (phba->todo_cq || phba->todo_mcc_cq) |
345 | queue_work(phba->wq, &phba->work_cqs); | 479 | queue_work(phba->wq, &phba->work_cqs); |
346 | 480 | ||
347 | if (num_eq_processed) { | 481 | if (num_ioeq_processed) { |
348 | hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 1, 1); | 482 | hwi_ring_eq_db(phba, eq->id, 0, |
483 | num_ioeq_processed, 1, 1); | ||
349 | return IRQ_HANDLED; | 484 | return IRQ_HANDLED; |
350 | } else | 485 | } else |
351 | return IRQ_NONE; | 486 | return IRQ_NONE; |
@@ -355,13 +490,32 @@ static irqreturn_t be_isr(int irq, void *dev_id) | |||
355 | static int beiscsi_init_irqs(struct beiscsi_hba *phba) | 490 | static int beiscsi_init_irqs(struct beiscsi_hba *phba) |
356 | { | 491 | { |
357 | struct pci_dev *pcidev = phba->pcidev; | 492 | struct pci_dev *pcidev = phba->pcidev; |
358 | int ret; | 493 | struct hwi_controller *phwi_ctrlr; |
494 | struct hwi_context_memory *phwi_context; | ||
495 | int ret, msix_vec, i = 0; | ||
496 | char desc[32]; | ||
359 | 497 | ||
360 | ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, "beiscsi", phba); | 498 | phwi_ctrlr = phba->phwi_ctrlr; |
361 | if (ret) { | 499 | phwi_context = phwi_ctrlr->phwi_ctxt; |
362 | shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-" | 500 | |
363 | "Failed to register irq\\n"); | 501 | if (phba->msix_enabled) { |
364 | return ret; | 502 | for (i = 0; i < phba->num_cpus; i++) { |
503 | sprintf(desc, "beiscsi_msix_%04x", i); | ||
504 | msix_vec = phba->msix_entries[i].vector; | ||
505 | ret = request_irq(msix_vec, be_isr_msix, 0, desc, | ||
506 | &phwi_context->be_eq[i]); | ||
507 | } | ||
508 | msix_vec = phba->msix_entries[i].vector; | ||
509 | ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc", | ||
510 | &phwi_context->be_eq[i]); | ||
511 | } else { | ||
512 | ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, | ||
513 | "beiscsi", phba); | ||
514 | if (ret) { | ||
515 | shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-" | ||
516 | "Failed to register irq\\n"); | ||
517 | return ret; | ||
518 | } | ||
365 | } | 519 | } |
366 | return 0; | 520 | return 0; |
367 | } | 521 | } |
@@ -378,15 +532,6 @@ static void hwi_ring_cq_db(struct beiscsi_hba *phba, | |||
378 | iowrite32(val, phba->db_va + DB_CQ_OFFSET); | 532 | iowrite32(val, phba->db_va + DB_CQ_OFFSET); |
379 | } | 533 | } |
380 | 534 | ||
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 | */ | ||
390 | static unsigned int | 535 | static unsigned int |
391 | beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, | 536 | beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, |
392 | struct beiscsi_hba *phba, | 537 | struct beiscsi_hba *phba, |
@@ -397,6 +542,9 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, | |||
397 | { | 542 | { |
398 | struct iscsi_conn *conn = beiscsi_conn->conn; | 543 | struct iscsi_conn *conn = beiscsi_conn->conn; |
399 | struct iscsi_session *session = conn->session; | 544 | struct iscsi_session *session = conn->session; |
545 | struct iscsi_task *task; | ||
546 | struct beiscsi_io_task *io_task; | ||
547 | struct iscsi_hdr *login_hdr; | ||
400 | 548 | ||
401 | switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] & | 549 | switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] & |
402 | PDUBASE_OPCODE_MASK) { | 550 | PDUBASE_OPCODE_MASK) { |
@@ -412,6 +560,10 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, | |||
412 | SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n"); | 560 | SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n"); |
413 | break; | 561 | break; |
414 | case ISCSI_OP_LOGIN_RSP: | 562 | case ISCSI_OP_LOGIN_RSP: |
563 | task = conn->login_task; | ||
564 | io_task = task->dd_data; | ||
565 | login_hdr = (struct iscsi_hdr *)ppdu; | ||
566 | login_hdr->itt = io_task->libiscsi_itt; | ||
415 | break; | 567 | break; |
416 | default: | 568 | default: |
417 | shost_printk(KERN_WARNING, phba->shost, | 569 | shost_printk(KERN_WARNING, phba->shost, |
@@ -440,7 +592,8 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba) | |||
440 | io_sgl_alloc_index]; | 592 | io_sgl_alloc_index]; |
441 | phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL; | 593 | phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL; |
442 | phba->io_sgl_hndl_avbl--; | 594 | phba->io_sgl_hndl_avbl--; |
443 | if (phba->io_sgl_alloc_index == (phba->params.ios_per_ctrl - 1)) | 595 | if (phba->io_sgl_alloc_index == (phba->params. |
596 | ios_per_ctrl - 1)) | ||
444 | phba->io_sgl_alloc_index = 0; | 597 | phba->io_sgl_alloc_index = 0; |
445 | else | 598 | else |
446 | phba->io_sgl_alloc_index++; | 599 | phba->io_sgl_alloc_index++; |
@@ -490,9 +643,18 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, | |||
490 | 643 | ||
491 | phwi_ctrlr = phba->phwi_ctrlr; | 644 | phwi_ctrlr = phba->phwi_ctrlr; |
492 | pwrb_context = &phwi_ctrlr->wrb_context[cid]; | 645 | pwrb_context = &phwi_ctrlr->wrb_context[cid]; |
493 | pwrb_handle = pwrb_context->pwrb_handle_base[index]; | 646 | if (pwrb_context->wrb_handles_available) { |
494 | pwrb_handle->wrb_index = index; | 647 | pwrb_handle = pwrb_context->pwrb_handle_base[ |
495 | pwrb_handle->nxt_wrb_index = index; | 648 | pwrb_context->alloc_index]; |
649 | pwrb_context->wrb_handles_available--; | ||
650 | pwrb_handle->nxt_wrb_index = pwrb_handle->wrb_index; | ||
651 | if (pwrb_context->alloc_index == | ||
652 | (phba->params.wrbs_per_cxn - 1)) | ||
653 | pwrb_context->alloc_index = 0; | ||
654 | else | ||
655 | pwrb_context->alloc_index++; | ||
656 | } else | ||
657 | pwrb_handle = NULL; | ||
496 | return pwrb_handle; | 658 | return pwrb_handle; |
497 | } | 659 | } |
498 | 660 | ||
@@ -508,11 +670,19 @@ static void | |||
508 | free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, | 670 | free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, |
509 | struct wrb_handle *pwrb_handle) | 671 | struct wrb_handle *pwrb_handle) |
510 | { | 672 | { |
673 | |||
674 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle; | ||
675 | pwrb_context->wrb_handles_available++; | ||
676 | if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1)) | ||
677 | pwrb_context->free_index = 0; | ||
678 | else | ||
679 | pwrb_context->free_index++; | ||
680 | |||
511 | SE_DEBUG(DBG_LVL_8, | 681 | SE_DEBUG(DBG_LVL_8, |
512 | "FREE WRB: pwrb_handle=%p free_index=%d=0x%x" | 682 | "FREE WRB: pwrb_handle=%p free_index=0x%x" |
513 | "wrb_handles_available=%d \n", | 683 | "wrb_handles_available=%d \n", |
514 | pwrb_handle, pwrb_context->free_index, | 684 | pwrb_handle, pwrb_context->free_index, |
515 | pwrb_context->free_index, pwrb_context->wrb_handles_available); | 685 | pwrb_context->wrb_handles_available); |
516 | } | 686 | } |
517 | 687 | ||
518 | static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) | 688 | static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) |
@@ -540,6 +710,8 @@ void | |||
540 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | 710 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) |
541 | { | 711 | { |
542 | 712 | ||
713 | SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d \n", | ||
714 | phba->eh_sgl_free_index); | ||
543 | if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) { | 715 | if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) { |
544 | /* | 716 | /* |
545 | * this can happen if clean_task is called on a task that | 717 | * this can happen if clean_task is called on a task that |
@@ -572,10 +744,10 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, | |||
572 | u32 resid = 0, exp_cmdsn, max_cmdsn; | 744 | u32 resid = 0, exp_cmdsn, max_cmdsn; |
573 | u8 rsp, status, flags; | 745 | u8 rsp, status, flags; |
574 | 746 | ||
575 | exp_cmdsn = be32_to_cpu(psol-> | 747 | exp_cmdsn = (psol-> |
576 | dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] | 748 | dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] |
577 | & SOL_EXP_CMD_SN_MASK); | 749 | & SOL_EXP_CMD_SN_MASK); |
578 | max_cmdsn = be32_to_cpu((psol-> | 750 | max_cmdsn = ((psol-> |
579 | dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] | 751 | dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32] |
580 | & SOL_EXP_CMD_SN_MASK) + | 752 | & SOL_EXP_CMD_SN_MASK) + |
581 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) | 753 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) |
@@ -610,9 +782,9 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, | |||
610 | } | 782 | } |
611 | 783 | ||
612 | if (status == SAM_STAT_CHECK_CONDITION) { | 784 | if (status == SAM_STAT_CHECK_CONDITION) { |
785 | unsigned short *slen = (unsigned short *)sts_bhs->sense_info; | ||
613 | sense = sts_bhs->sense_info + sizeof(unsigned short); | 786 | sense = sts_bhs->sense_info + sizeof(unsigned short); |
614 | sense_len = | 787 | sense_len = cpu_to_be16(*slen); |
615 | cpu_to_be16((unsigned short)(sts_bhs->sense_info[0])); | ||
616 | memcpy(task->sc->sense_buffer, sense, | 788 | memcpy(task->sc->sense_buffer, sense, |
617 | min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); | 789 | min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); |
618 | } | 790 | } |
@@ -620,8 +792,8 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, | |||
620 | if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] | 792 | if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] |
621 | & SOL_RES_CNT_MASK) | 793 | & SOL_RES_CNT_MASK) |
622 | conn->rxdata_octets += (psol-> | 794 | conn->rxdata_octets += (psol-> |
623 | dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] | 795 | dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] |
624 | & SOL_RES_CNT_MASK); | 796 | & SOL_RES_CNT_MASK); |
625 | } | 797 | } |
626 | unmap: | 798 | unmap: |
627 | scsi_dma_unmap(io_task->scsi_cmnd); | 799 | scsi_dma_unmap(io_task->scsi_cmnd); |
@@ -633,6 +805,7 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn, | |||
633 | struct iscsi_task *task, struct sol_cqe *psol) | 805 | struct iscsi_task *task, struct sol_cqe *psol) |
634 | { | 806 | { |
635 | struct iscsi_logout_rsp *hdr; | 807 | struct iscsi_logout_rsp *hdr; |
808 | struct beiscsi_io_task *io_task = task->dd_data; | ||
636 | struct iscsi_conn *conn = beiscsi_conn->conn; | 809 | struct iscsi_conn *conn = beiscsi_conn->conn; |
637 | 810 | ||
638 | hdr = (struct iscsi_logout_rsp *)task->hdr; | 811 | hdr = (struct iscsi_logout_rsp *)task->hdr; |
@@ -651,7 +824,7 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn, | |||
651 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) | 824 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) |
652 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); | 825 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); |
653 | hdr->hlength = 0; | 826 | hdr->hlength = 0; |
654 | 827 | hdr->itt = io_task->libiscsi_itt; | |
655 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); | 828 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); |
656 | } | 829 | } |
657 | 830 | ||
@@ -661,6 +834,7 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn, | |||
661 | { | 834 | { |
662 | struct iscsi_tm_rsp *hdr; | 835 | struct iscsi_tm_rsp *hdr; |
663 | struct iscsi_conn *conn = beiscsi_conn->conn; | 836 | struct iscsi_conn *conn = beiscsi_conn->conn; |
837 | struct beiscsi_io_task *io_task = task->dd_data; | ||
664 | 838 | ||
665 | hdr = (struct iscsi_tm_rsp *)task->hdr; | 839 | hdr = (struct iscsi_tm_rsp *)task->hdr; |
666 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | 840 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] |
@@ -668,11 +842,12 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn, | |||
668 | hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / | 842 | hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / |
669 | 32] & SOL_RESP_MASK); | 843 | 32] & SOL_RESP_MASK); |
670 | hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, | 844 | hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe, |
671 | i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); | 845 | i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK); |
672 | hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe, | 846 | hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe, |
673 | i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) + | 847 | i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) + |
674 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) | 848 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) |
675 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); | 849 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); |
850 | hdr->itt = io_task->libiscsi_itt; | ||
676 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); | 851 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); |
677 | } | 852 | } |
678 | 853 | ||
@@ -681,18 +856,25 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, | |||
681 | struct beiscsi_hba *phba, struct sol_cqe *psol) | 856 | struct beiscsi_hba *phba, struct sol_cqe *psol) |
682 | { | 857 | { |
683 | struct hwi_wrb_context *pwrb_context; | 858 | struct hwi_wrb_context *pwrb_context; |
684 | struct wrb_handle *pwrb_handle; | 859 | struct wrb_handle *pwrb_handle = NULL; |
685 | struct hwi_controller *phwi_ctrlr; | 860 | struct hwi_controller *phwi_ctrlr; |
861 | struct iscsi_task *task; | ||
862 | struct beiscsi_io_task *io_task; | ||
686 | struct iscsi_conn *conn = beiscsi_conn->conn; | 863 | struct iscsi_conn *conn = beiscsi_conn->conn; |
687 | struct iscsi_session *session = conn->session; | 864 | struct iscsi_session *session = conn->session; |
688 | 865 | ||
689 | phwi_ctrlr = phba->phwi_ctrlr; | 866 | phwi_ctrlr = phba->phwi_ctrlr; |
690 | pwrb_context = &phwi_ctrlr->wrb_context[((psol-> | 867 | pwrb_context = &phwi_ctrlr->wrb_context[((psol-> |
691 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & | 868 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & |
692 | SOL_CID_MASK) >> 6)]; | 869 | SOL_CID_MASK) >> 6)]; |
693 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | 870 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> |
694 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | 871 | dw[offsetof(struct amap_sol_cqe, wrb_index) / |
695 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | 872 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; |
873 | task = pwrb_handle->pio_handle; | ||
874 | io_task = task->dd_data; | ||
875 | spin_lock(&phba->mgmt_sgl_lock); | ||
876 | free_mgmt_sgl_handle(phba, io_task->psgl_handle); | ||
877 | spin_unlock(&phba->mgmt_sgl_lock); | ||
696 | spin_lock_bh(&session->lock); | 878 | spin_lock_bh(&session->lock); |
697 | free_wrb_handle(phba, pwrb_context, pwrb_handle); | 879 | free_wrb_handle(phba, pwrb_context, pwrb_handle); |
698 | spin_unlock_bh(&session->lock); | 880 | spin_unlock_bh(&session->lock); |
@@ -704,6 +886,7 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, | |||
704 | { | 886 | { |
705 | struct iscsi_nopin *hdr; | 887 | struct iscsi_nopin *hdr; |
706 | struct iscsi_conn *conn = beiscsi_conn->conn; | 888 | struct iscsi_conn *conn = beiscsi_conn->conn; |
889 | struct beiscsi_io_task *io_task = task->dd_data; | ||
707 | 890 | ||
708 | hdr = (struct iscsi_nopin *)task->hdr; | 891 | hdr = (struct iscsi_nopin *)task->hdr; |
709 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | 892 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] |
@@ -715,6 +898,7 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, | |||
715 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) | 898 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) |
716 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); | 899 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); |
717 | hdr->opcode = ISCSI_OP_NOOP_IN; | 900 | hdr->opcode = ISCSI_OP_NOOP_IN; |
901 | hdr->itt = io_task->libiscsi_itt; | ||
718 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); | 902 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); |
719 | } | 903 | } |
720 | 904 | ||
@@ -726,25 +910,25 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
726 | struct iscsi_wrb *pwrb = NULL; | 910 | struct iscsi_wrb *pwrb = NULL; |
727 | struct hwi_controller *phwi_ctrlr; | 911 | struct hwi_controller *phwi_ctrlr; |
728 | struct iscsi_task *task; | 912 | struct iscsi_task *task; |
729 | struct beiscsi_io_task *io_task; | 913 | unsigned int type; |
730 | struct iscsi_conn *conn = beiscsi_conn->conn; | 914 | struct iscsi_conn *conn = beiscsi_conn->conn; |
731 | struct iscsi_session *session = conn->session; | 915 | struct iscsi_session *session = conn->session; |
732 | 916 | ||
733 | phwi_ctrlr = phba->phwi_ctrlr; | 917 | phwi_ctrlr = phba->phwi_ctrlr; |
734 | |||
735 | pwrb_context = &phwi_ctrlr-> | 918 | pwrb_context = &phwi_ctrlr-> |
736 | wrb_context[((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32] | 919 | wrb_context[((psol->dw[offsetof |
737 | & SOL_CID_MASK) >> 6)]; | 920 | (struct amap_sol_cqe, cid) / 32] |
921 | & SOL_CID_MASK) >> 6)]; | ||
738 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | 922 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> |
739 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | 923 | dw[offsetof(struct amap_sol_cqe, wrb_index) / |
740 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | 924 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; |
741 | |||
742 | task = pwrb_handle->pio_handle; | 925 | task = pwrb_handle->pio_handle; |
743 | io_task = task->dd_data; | ||
744 | spin_lock_bh(&session->lock); | ||
745 | pwrb = pwrb_handle->pwrb; | 926 | pwrb = pwrb_handle->pwrb; |
746 | switch ((pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & | 927 | type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & |
747 | WRB_TYPE_MASK) >> 28) { | 928 | WRB_TYPE_MASK) >> 28; |
929 | |||
930 | spin_lock_bh(&session->lock); | ||
931 | switch (type) { | ||
748 | case HWH_TYPE_IO: | 932 | case HWH_TYPE_IO: |
749 | case HWH_TYPE_IO_RD: | 933 | case HWH_TYPE_IO_RD: |
750 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == | 934 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == |
@@ -774,14 +958,14 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
774 | 958 | ||
775 | default: | 959 | default: |
776 | shost_printk(KERN_WARNING, phba->shost, | 960 | shost_printk(KERN_WARNING, phba->shost, |
777 | "wrb_index 0x%x CID 0x%x\n", | 961 | "In hwi_complete_cmd, unknown type = %d" |
778 | ((psol->dw[offsetof(struct amap_iscsi_wrb, type) / | 962 | "wrb_index 0x%x CID 0x%x\n", type, |
779 | 32] & SOL_WRB_INDEX_MASK) >> 16), | 963 | ((psol->dw[offsetof(struct amap_iscsi_wrb, |
780 | ((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32] | 964 | type) / 32] & SOL_WRB_INDEX_MASK) >> 16), |
781 | & SOL_CID_MASK) >> 6)); | 965 | ((psol->dw[offsetof(struct amap_sol_cqe, |
966 | cid) / 32] & SOL_CID_MASK) >> 6)); | ||
782 | break; | 967 | break; |
783 | } | 968 | } |
784 | |||
785 | spin_unlock_bh(&session->lock); | 969 | spin_unlock_bh(&session->lock); |
786 | } | 970 | } |
787 | 971 | ||
@@ -1208,21 +1392,20 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn, | |||
1208 | hwi_post_async_buffers(phba, pasync_handle->is_header); | 1392 | hwi_post_async_buffers(phba, pasync_handle->is_header); |
1209 | } | 1393 | } |
1210 | 1394 | ||
1211 | static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | 1395 | |
1396 | static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | ||
1212 | { | 1397 | { |
1213 | struct hwi_controller *phwi_ctrlr; | ||
1214 | struct hwi_context_memory *phwi_context; | ||
1215 | struct be_queue_info *cq; | 1398 | struct be_queue_info *cq; |
1216 | struct sol_cqe *sol; | 1399 | struct sol_cqe *sol; |
1217 | struct dmsg_cqe *dmsg; | 1400 | struct dmsg_cqe *dmsg; |
1218 | unsigned int num_processed = 0; | 1401 | unsigned int num_processed = 0; |
1219 | unsigned int tot_nump = 0; | 1402 | unsigned int tot_nump = 0; |
1220 | struct beiscsi_conn *beiscsi_conn; | 1403 | struct beiscsi_conn *beiscsi_conn; |
1404 | struct beiscsi_hba *phba; | ||
1221 | 1405 | ||
1222 | phwi_ctrlr = phba->phwi_ctrlr; | 1406 | cq = pbe_eq->cq; |
1223 | phwi_context = phwi_ctrlr->phwi_ctxt; | ||
1224 | cq = &phwi_context->be_cq; | ||
1225 | sol = queue_tail_node(cq); | 1407 | sol = queue_tail_node(cq); |
1408 | phba = pbe_eq->phba; | ||
1226 | 1409 | ||
1227 | while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] & | 1410 | while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] & |
1228 | CQE_VALID_MASK) { | 1411 | CQE_VALID_MASK) { |
@@ -1237,11 +1420,11 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | |||
1237 | "Connection table empty for cid = %d\n", | 1420 | "Connection table empty for cid = %d\n", |
1238 | (u32)(sol->dw[offsetof(struct amap_sol_cqe, | 1421 | (u32)(sol->dw[offsetof(struct amap_sol_cqe, |
1239 | cid) / 32] & SOL_CID_MASK) >> 6); | 1422 | cid) / 32] & SOL_CID_MASK) >> 6); |
1240 | return 0; | 1423 | return 0; |
1241 | } | 1424 | } |
1242 | 1425 | ||
1243 | if (num_processed >= 32) { | 1426 | if (num_processed >= 32) { |
1244 | hwi_ring_cq_db(phba, phwi_context->be_cq.id, | 1427 | hwi_ring_cq_db(phba, cq->id, |
1245 | num_processed, 0, 0); | 1428 | num_processed, 0, 0); |
1246 | tot_nump += num_processed; | 1429 | tot_nump += num_processed; |
1247 | num_processed = 0; | 1430 | num_processed = 0; |
@@ -1258,8 +1441,12 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | |||
1258 | hwi_complete_drvr_msgs(beiscsi_conn, phba, sol); | 1441 | hwi_complete_drvr_msgs(beiscsi_conn, phba, sol); |
1259 | break; | 1442 | break; |
1260 | case UNSOL_HDR_NOTIFY: | 1443 | case UNSOL_HDR_NOTIFY: |
1444 | SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR_ NOTIFY\n"); | ||
1445 | hwi_process_default_pdu_ring(beiscsi_conn, phba, | ||
1446 | (struct i_t_dpdu_cqe *)sol); | ||
1447 | break; | ||
1261 | case UNSOL_DATA_NOTIFY: | 1448 | case UNSOL_DATA_NOTIFY: |
1262 | SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR/DATA_NOTIFY\n"); | 1449 | SE_DEBUG(DBG_LVL_8, "Received UNSOL_DATA_NOTIFY\n"); |
1263 | hwi_process_default_pdu_ring(beiscsi_conn, phba, | 1450 | hwi_process_default_pdu_ring(beiscsi_conn, phba, |
1264 | (struct i_t_dpdu_cqe *)sol); | 1451 | (struct i_t_dpdu_cqe *)sol); |
1265 | break; | 1452 | break; |
@@ -1306,7 +1493,7 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | |||
1306 | case CXN_KILLED_OVER_RUN_RESIDUAL: | 1493 | case CXN_KILLED_OVER_RUN_RESIDUAL: |
1307 | case CXN_KILLED_UNDER_RUN_RESIDUAL: | 1494 | case CXN_KILLED_UNDER_RUN_RESIDUAL: |
1308 | case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: | 1495 | case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: |
1309 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, resetting CID " | 1496 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " |
1310 | "0x%x...\n", | 1497 | "0x%x...\n", |
1311 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1498 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1312 | 32] & CQE_CODE_MASK, | 1499 | 32] & CQE_CODE_MASK, |
@@ -1317,8 +1504,8 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | |||
1317 | break; | 1504 | break; |
1318 | case CXN_KILLED_RST_SENT: | 1505 | case CXN_KILLED_RST_SENT: |
1319 | case CXN_KILLED_RST_RCVD: | 1506 | case CXN_KILLED_RST_RCVD: |
1320 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset received/sent " | 1507 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" |
1321 | "on CID 0x%x...\n", | 1508 | "received/sent on CID 0x%x...\n", |
1322 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1509 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1323 | 32] & CQE_CODE_MASK, | 1510 | 32] & CQE_CODE_MASK, |
1324 | sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1511 | sol->dw[offsetof(struct amap_sol_cqe, cid) / |
@@ -1344,8 +1531,7 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | |||
1344 | 1531 | ||
1345 | if (num_processed > 0) { | 1532 | if (num_processed > 0) { |
1346 | tot_nump += num_processed; | 1533 | tot_nump += num_processed; |
1347 | hwi_ring_cq_db(phba, phwi_context->be_cq.id, num_processed, | 1534 | hwi_ring_cq_db(phba, cq->id, num_processed, 1, 0); |
1348 | 1, 0); | ||
1349 | } | 1535 | } |
1350 | return tot_nump; | 1536 | return tot_nump; |
1351 | } | 1537 | } |
@@ -1353,21 +1539,30 @@ static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba) | |||
1353 | static void beiscsi_process_all_cqs(struct work_struct *work) | 1539 | static void beiscsi_process_all_cqs(struct work_struct *work) |
1354 | { | 1540 | { |
1355 | unsigned long flags; | 1541 | unsigned long flags; |
1542 | struct hwi_controller *phwi_ctrlr; | ||
1543 | struct hwi_context_memory *phwi_context; | ||
1544 | struct be_eq_obj *pbe_eq; | ||
1356 | struct beiscsi_hba *phba = | 1545 | struct beiscsi_hba *phba = |
1357 | container_of(work, struct beiscsi_hba, work_cqs); | 1546 | container_of(work, struct beiscsi_hba, work_cqs); |
1358 | 1547 | ||
1548 | phwi_ctrlr = phba->phwi_ctrlr; | ||
1549 | phwi_context = phwi_ctrlr->phwi_ctxt; | ||
1550 | if (phba->msix_enabled) | ||
1551 | pbe_eq = &phwi_context->be_eq[phba->num_cpus]; | ||
1552 | else | ||
1553 | pbe_eq = &phwi_context->be_eq[0]; | ||
1554 | |||
1359 | if (phba->todo_mcc_cq) { | 1555 | if (phba->todo_mcc_cq) { |
1360 | spin_lock_irqsave(&phba->isr_lock, flags); | 1556 | spin_lock_irqsave(&phba->isr_lock, flags); |
1361 | phba->todo_mcc_cq = 0; | 1557 | phba->todo_mcc_cq = 0; |
1362 | spin_unlock_irqrestore(&phba->isr_lock, flags); | 1558 | spin_unlock_irqrestore(&phba->isr_lock, flags); |
1363 | SE_DEBUG(DBG_LVL_1, "MCC Interrupt Not expected \n"); | ||
1364 | } | 1559 | } |
1365 | 1560 | ||
1366 | if (phba->todo_cq) { | 1561 | if (phba->todo_cq) { |
1367 | spin_lock_irqsave(&phba->isr_lock, flags); | 1562 | spin_lock_irqsave(&phba->isr_lock, flags); |
1368 | phba->todo_cq = 0; | 1563 | phba->todo_cq = 0; |
1369 | spin_unlock_irqrestore(&phba->isr_lock, flags); | 1564 | spin_unlock_irqrestore(&phba->isr_lock, flags); |
1370 | beiscsi_process_cq(phba); | 1565 | beiscsi_process_cq(pbe_eq); |
1371 | } | 1566 | } |
1372 | } | 1567 | } |
1373 | 1568 | ||
@@ -1375,19 +1570,15 @@ static int be_iopoll(struct blk_iopoll *iop, int budget) | |||
1375 | { | 1570 | { |
1376 | static unsigned int ret; | 1571 | static unsigned int ret; |
1377 | struct beiscsi_hba *phba; | 1572 | struct beiscsi_hba *phba; |
1573 | struct be_eq_obj *pbe_eq; | ||
1378 | 1574 | ||
1379 | phba = container_of(iop, struct beiscsi_hba, iopoll); | 1575 | pbe_eq = container_of(iop, struct be_eq_obj, iopoll); |
1380 | 1576 | ret = beiscsi_process_cq(pbe_eq); | |
1381 | ret = beiscsi_process_cq(phba); | ||
1382 | if (ret < budget) { | 1577 | if (ret < budget) { |
1383 | struct hwi_controller *phwi_ctrlr; | 1578 | 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); | 1579 | blk_iopoll_complete(iop); |
1389 | hwi_ring_eq_db(phba, phwi_context->be_eq.q.id, 0, | 1580 | SE_DEBUG(DBG_LVL_8, "rearm pbe_eq->q.id =%d\n", pbe_eq->q.id); |
1390 | 0, 1, 1); | 1581 | hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1); |
1391 | } | 1582 | } |
1392 | return ret; | 1583 | return ret; |
1393 | } | 1584 | } |
@@ -1537,14 +1728,12 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) | |||
1537 | 1728 | ||
1538 | static void beiscsi_find_mem_req(struct beiscsi_hba *phba) | 1729 | static void beiscsi_find_mem_req(struct beiscsi_hba *phba) |
1539 | { | 1730 | { |
1540 | unsigned int num_cq_pages, num_eq_pages, num_async_pdu_buf_pages; | 1731 | unsigned int num_cq_pages, num_async_pdu_buf_pages; |
1541 | unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn; | 1732 | 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; | 1733 | unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages; |
1543 | 1734 | ||
1544 | num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ | 1735 | num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ |
1545 | sizeof(struct sol_cqe)); | 1736 | 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 = | 1737 | num_async_pdu_buf_pages = |
1549 | PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ | 1738 | PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \ |
1550 | phba->params.defpdu_hdr_sz); | 1739 | phba->params.defpdu_hdr_sz); |
@@ -1565,8 +1754,6 @@ static void beiscsi_find_mem_req(struct beiscsi_hba *phba) | |||
1565 | phba->mem_req[HWI_MEM_ADDN_CONTEXT] = | 1754 | phba->mem_req[HWI_MEM_ADDN_CONTEXT] = |
1566 | sizeof(struct hwi_context_memory); | 1755 | sizeof(struct hwi_context_memory); |
1567 | 1756 | ||
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 | 1757 | ||
1571 | phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb) | 1758 | phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb) |
1572 | * (phba->params.wrbs_per_cxn) | 1759 | * (phba->params.wrbs_per_cxn) |
@@ -1751,8 +1938,6 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
1751 | 1938 | ||
1752 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { | 1939 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { |
1753 | pwrb_context = &phwi_ctrlr->wrb_context[index]; | 1940 | 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 = | 1941 | pwrb_context->pwrb_handle_base = |
1757 | kzalloc(sizeof(struct wrb_handle *) * | 1942 | kzalloc(sizeof(struct wrb_handle *) * |
1758 | phba->params.wrbs_per_cxn, GFP_KERNEL); | 1943 | phba->params.wrbs_per_cxn, GFP_KERNEL); |
@@ -1767,6 +1952,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
1767 | pwrb_context->pwrb_handle_basestd[j] = | 1952 | pwrb_context->pwrb_handle_basestd[j] = |
1768 | pwrb_handle; | 1953 | pwrb_handle; |
1769 | pwrb_context->wrb_handles_available++; | 1954 | pwrb_context->wrb_handles_available++; |
1955 | pwrb_handle->wrb_index = j; | ||
1770 | pwrb_handle++; | 1956 | pwrb_handle++; |
1771 | } | 1957 | } |
1772 | pwrb_context->free_index = 0; | 1958 | pwrb_context->free_index = 0; |
@@ -1785,6 +1971,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
1785 | pwrb_context->pwrb_handle_basestd[j] = | 1971 | pwrb_context->pwrb_handle_basestd[j] = |
1786 | pwrb_handle; | 1972 | pwrb_handle; |
1787 | pwrb_context->wrb_handles_available++; | 1973 | pwrb_context->wrb_handles_available++; |
1974 | pwrb_handle->wrb_index = j; | ||
1788 | pwrb_handle++; | 1975 | pwrb_handle++; |
1789 | } | 1976 | } |
1790 | pwrb_context->free_index = 0; | 1977 | pwrb_context->free_index = 0; |
@@ -2042,79 +2229,126 @@ static int be_fill_queue(struct be_queue_info *q, | |||
2042 | return 0; | 2229 | return 0; |
2043 | } | 2230 | } |
2044 | 2231 | ||
2045 | static int beiscsi_create_eq(struct beiscsi_hba *phba, | 2232 | static int beiscsi_create_eqs(struct beiscsi_hba *phba, |
2046 | struct hwi_context_memory *phwi_context) | 2233 | struct hwi_context_memory *phwi_context) |
2047 | { | 2234 | { |
2048 | unsigned int idx; | 2235 | unsigned int i, num_eq_pages; |
2049 | int ret; | 2236 | int ret, eq_for_mcc; |
2050 | struct be_queue_info *eq; | 2237 | struct be_queue_info *eq; |
2051 | struct be_dma_mem *mem; | 2238 | struct be_dma_mem *mem; |
2052 | struct be_mem_descriptor *mem_descr; | ||
2053 | void *eq_vaddress; | 2239 | void *eq_vaddress; |
2240 | dma_addr_t paddr; | ||
2054 | 2241 | ||
2055 | idx = 0; | 2242 | num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \ |
2056 | eq = &phwi_context->be_eq.q; | 2243 | 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 | 2244 | ||
2070 | mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address; | 2245 | if (phba->msix_enabled) |
2246 | eq_for_mcc = 1; | ||
2247 | else | ||
2248 | eq_for_mcc = 0; | ||
2249 | for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) { | ||
2250 | eq = &phwi_context->be_eq[i].q; | ||
2251 | mem = &eq->dma_mem; | ||
2252 | phwi_context->be_eq[i].phba = phba; | ||
2253 | eq_vaddress = pci_alloc_consistent(phba->pcidev, | ||
2254 | num_eq_pages * PAGE_SIZE, | ||
2255 | &paddr); | ||
2256 | if (!eq_vaddress) | ||
2257 | goto create_eq_error; | ||
2258 | |||
2259 | mem->va = eq_vaddress; | ||
2260 | ret = be_fill_queue(eq, phba->params.num_eq_entries, | ||
2261 | sizeof(struct be_eq_entry), eq_vaddress); | ||
2262 | if (ret) { | ||
2263 | shost_printk(KERN_ERR, phba->shost, | ||
2264 | "be_fill_queue Failed for EQ \n"); | ||
2265 | goto create_eq_error; | ||
2266 | } | ||
2071 | 2267 | ||
2072 | ret = beiscsi_cmd_eq_create(&phba->ctrl, eq, | 2268 | mem->dma = paddr; |
2073 | phwi_context->be_eq.cur_eqd); | 2269 | ret = beiscsi_cmd_eq_create(&phba->ctrl, eq, |
2074 | if (ret) { | 2270 | phwi_context->cur_eqd); |
2075 | shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create" | 2271 | if (ret) { |
2076 | "Failedfor EQ \n"); | 2272 | shost_printk(KERN_ERR, phba->shost, |
2077 | return ret; | 2273 | "beiscsi_cmd_eq_create" |
2274 | "Failedfor EQ \n"); | ||
2275 | goto create_eq_error; | ||
2276 | } | ||
2277 | SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id); | ||
2078 | } | 2278 | } |
2079 | SE_DEBUG(DBG_LVL_8, "eq id is %d\n", phwi_context->be_eq.q.id); | ||
2080 | return 0; | 2279 | return 0; |
2280 | create_eq_error: | ||
2281 | for (i = 0; i < (phba->num_cpus + 1); i++) { | ||
2282 | eq = &phwi_context->be_eq[i].q; | ||
2283 | mem = &eq->dma_mem; | ||
2284 | if (mem->va) | ||
2285 | pci_free_consistent(phba->pcidev, num_eq_pages | ||
2286 | * PAGE_SIZE, | ||
2287 | mem->va, mem->dma); | ||
2288 | } | ||
2289 | return ret; | ||
2081 | } | 2290 | } |
2082 | 2291 | ||
2083 | static int beiscsi_create_cq(struct beiscsi_hba *phba, | 2292 | static int beiscsi_create_cqs(struct beiscsi_hba *phba, |
2084 | struct hwi_context_memory *phwi_context) | 2293 | struct hwi_context_memory *phwi_context) |
2085 | { | 2294 | { |
2086 | unsigned int idx; | 2295 | unsigned int i, num_cq_pages; |
2087 | int ret; | 2296 | int ret; |
2088 | struct be_queue_info *cq, *eq; | 2297 | struct be_queue_info *cq, *eq; |
2089 | struct be_dma_mem *mem; | 2298 | struct be_dma_mem *mem; |
2090 | struct be_mem_descriptor *mem_descr; | 2299 | struct be_eq_obj *pbe_eq; |
2091 | void *cq_vaddress; | 2300 | void *cq_vaddress; |
2301 | dma_addr_t paddr; | ||
2092 | 2302 | ||
2093 | idx = 0; | 2303 | num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ |
2094 | cq = &phwi_context->be_cq; | 2304 | 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 | 2305 | ||
2108 | mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address; | 2306 | for (i = 0; i < phba->num_cpus; i++) { |
2109 | ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, false, 0); | 2307 | cq = &phwi_context->be_cq[i]; |
2110 | if (ret) { | 2308 | eq = &phwi_context->be_eq[i].q; |
2111 | shost_printk(KERN_ERR, phba->shost, | 2309 | pbe_eq = &phwi_context->be_eq[i]; |
2112 | "beiscsi_cmd_eq_create Failed for ISCSI CQ \n"); | 2310 | pbe_eq->cq = cq; |
2113 | return ret; | 2311 | pbe_eq->phba = phba; |
2312 | mem = &cq->dma_mem; | ||
2313 | cq_vaddress = pci_alloc_consistent(phba->pcidev, | ||
2314 | num_cq_pages * PAGE_SIZE, | ||
2315 | &paddr); | ||
2316 | if (!cq_vaddress) | ||
2317 | goto create_cq_error; | ||
2318 | ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2, | ||
2319 | sizeof(struct sol_cqe), cq_vaddress); | ||
2320 | if (ret) { | ||
2321 | shost_printk(KERN_ERR, phba->shost, | ||
2322 | "be_fill_queue Failed for ISCSI CQ \n"); | ||
2323 | goto create_cq_error; | ||
2324 | } | ||
2325 | |||
2326 | mem->dma = paddr; | ||
2327 | ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, | ||
2328 | false, 0); | ||
2329 | if (ret) { | ||
2330 | shost_printk(KERN_ERR, phba->shost, | ||
2331 | "beiscsi_cmd_eq_create" | ||
2332 | "Failed for ISCSI CQ \n"); | ||
2333 | goto create_cq_error; | ||
2334 | } | ||
2335 | SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n", | ||
2336 | cq->id, eq->id); | ||
2337 | SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n"); | ||
2114 | } | 2338 | } |
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; | 2339 | return 0; |
2340 | |||
2341 | create_cq_error: | ||
2342 | for (i = 0; i < phba->num_cpus; i++) { | ||
2343 | cq = &phwi_context->be_cq[i]; | ||
2344 | mem = &cq->dma_mem; | ||
2345 | if (mem->va) | ||
2346 | pci_free_consistent(phba->pcidev, num_cq_pages | ||
2347 | * PAGE_SIZE, | ||
2348 | mem->va, mem->dma); | ||
2349 | } | ||
2350 | return ret; | ||
2351 | |||
2118 | } | 2352 | } |
2119 | 2353 | ||
2120 | static int | 2354 | static int |
@@ -2132,7 +2366,7 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba, | |||
2132 | 2366 | ||
2133 | idx = 0; | 2367 | idx = 0; |
2134 | dq = &phwi_context->be_def_hdrq; | 2368 | dq = &phwi_context->be_def_hdrq; |
2135 | cq = &phwi_context->be_cq; | 2369 | cq = &phwi_context->be_cq[0]; |
2136 | mem = &dq->dma_mem; | 2370 | mem = &dq->dma_mem; |
2137 | mem_descr = phba->init_mem; | 2371 | mem_descr = phba->init_mem; |
2138 | mem_descr += HWI_MEM_ASYNC_HEADER_RING; | 2372 | mem_descr += HWI_MEM_ASYNC_HEADER_RING; |
@@ -2176,7 +2410,7 @@ beiscsi_create_def_data(struct beiscsi_hba *phba, | |||
2176 | 2410 | ||
2177 | idx = 0; | 2411 | idx = 0; |
2178 | dataq = &phwi_context->be_def_dataq; | 2412 | dataq = &phwi_context->be_def_dataq; |
2179 | cq = &phwi_context->be_cq; | 2413 | cq = &phwi_context->be_cq[0]; |
2180 | mem = &dataq->dma_mem; | 2414 | mem = &dataq->dma_mem; |
2181 | mem_descr = phba->init_mem; | 2415 | mem_descr = phba->init_mem; |
2182 | mem_descr += HWI_MEM_ASYNC_DATA_RING; | 2416 | mem_descr += HWI_MEM_ASYNC_DATA_RING; |
@@ -2239,6 +2473,30 @@ beiscsi_post_pages(struct beiscsi_hba *phba) | |||
2239 | return 0; | 2473 | return 0; |
2240 | } | 2474 | } |
2241 | 2475 | ||
2476 | static void be_queue_free(struct beiscsi_hba *phba, struct be_queue_info *q) | ||
2477 | { | ||
2478 | struct be_dma_mem *mem = &q->dma_mem; | ||
2479 | if (mem->va) | ||
2480 | pci_free_consistent(phba->pcidev, mem->size, | ||
2481 | mem->va, mem->dma); | ||
2482 | } | ||
2483 | |||
2484 | static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q, | ||
2485 | u16 len, u16 entry_size) | ||
2486 | { | ||
2487 | struct be_dma_mem *mem = &q->dma_mem; | ||
2488 | |||
2489 | memset(q, 0, sizeof(*q)); | ||
2490 | q->len = len; | ||
2491 | q->entry_size = entry_size; | ||
2492 | mem->size = len * entry_size; | ||
2493 | mem->va = pci_alloc_consistent(phba->pcidev, mem->size, &mem->dma); | ||
2494 | if (!mem->va) | ||
2495 | return -1; | ||
2496 | memset(mem->va, 0, mem->size); | ||
2497 | return 0; | ||
2498 | } | ||
2499 | |||
2242 | static int | 2500 | static int |
2243 | beiscsi_create_wrb_rings(struct beiscsi_hba *phba, | 2501 | beiscsi_create_wrb_rings(struct beiscsi_hba *phba, |
2244 | struct hwi_context_memory *phwi_context, | 2502 | struct hwi_context_memory *phwi_context, |
@@ -2328,13 +2586,29 @@ static void free_wrb_handles(struct beiscsi_hba *phba) | |||
2328 | } | 2586 | } |
2329 | } | 2587 | } |
2330 | 2588 | ||
2589 | static void be_mcc_queues_destroy(struct beiscsi_hba *phba) | ||
2590 | { | ||
2591 | struct be_queue_info *q; | ||
2592 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
2593 | |||
2594 | q = &phba->ctrl.mcc_obj.q; | ||
2595 | if (q->created) | ||
2596 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ); | ||
2597 | be_queue_free(phba, q); | ||
2598 | |||
2599 | q = &phba->ctrl.mcc_obj.cq; | ||
2600 | if (q->created) | ||
2601 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ); | ||
2602 | be_queue_free(phba, q); | ||
2603 | } | ||
2604 | |||
2331 | static void hwi_cleanup(struct beiscsi_hba *phba) | 2605 | static void hwi_cleanup(struct beiscsi_hba *phba) |
2332 | { | 2606 | { |
2333 | struct be_queue_info *q; | 2607 | struct be_queue_info *q; |
2334 | struct be_ctrl_info *ctrl = &phba->ctrl; | 2608 | struct be_ctrl_info *ctrl = &phba->ctrl; |
2335 | struct hwi_controller *phwi_ctrlr; | 2609 | struct hwi_controller *phwi_ctrlr; |
2336 | struct hwi_context_memory *phwi_context; | 2610 | struct hwi_context_memory *phwi_context; |
2337 | int i; | 2611 | int i, eq_num; |
2338 | 2612 | ||
2339 | phwi_ctrlr = phba->phwi_ctrlr; | 2613 | phwi_ctrlr = phba->phwi_ctrlr; |
2340 | phwi_context = phwi_ctrlr->phwi_ctxt; | 2614 | phwi_context = phwi_ctrlr->phwi_ctxt; |
@@ -2343,7 +2617,6 @@ static void hwi_cleanup(struct beiscsi_hba *phba) | |||
2343 | if (q->created) | 2617 | if (q->created) |
2344 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ); | 2618 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ); |
2345 | } | 2619 | } |
2346 | |||
2347 | free_wrb_handles(phba); | 2620 | free_wrb_handles(phba); |
2348 | 2621 | ||
2349 | q = &phwi_context->be_def_hdrq; | 2622 | q = &phwi_context->be_def_hdrq; |
@@ -2356,13 +2629,76 @@ static void hwi_cleanup(struct beiscsi_hba *phba) | |||
2356 | 2629 | ||
2357 | beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL); | 2630 | beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL); |
2358 | 2631 | ||
2359 | q = &phwi_context->be_cq; | 2632 | for (i = 0; i < (phba->num_cpus); i++) { |
2360 | if (q->created) | 2633 | q = &phwi_context->be_cq[i]; |
2361 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ); | 2634 | if (q->created) |
2635 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ); | ||
2636 | } | ||
2637 | if (phba->msix_enabled) | ||
2638 | eq_num = 1; | ||
2639 | else | ||
2640 | eq_num = 0; | ||
2641 | for (i = 0; i < (phba->num_cpus + eq_num); i++) { | ||
2642 | q = &phwi_context->be_eq[i].q; | ||
2643 | if (q->created) | ||
2644 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ); | ||
2645 | } | ||
2646 | be_mcc_queues_destroy(phba); | ||
2647 | } | ||
2362 | 2648 | ||
2363 | q = &phwi_context->be_eq.q; | 2649 | static int be_mcc_queues_create(struct beiscsi_hba *phba, |
2364 | if (q->created) | 2650 | struct hwi_context_memory *phwi_context) |
2365 | beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ); | 2651 | { |
2652 | struct be_queue_info *q, *cq; | ||
2653 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
2654 | |||
2655 | /* Alloc MCC compl queue */ | ||
2656 | cq = &phba->ctrl.mcc_obj.cq; | ||
2657 | if (be_queue_alloc(phba, cq, MCC_CQ_LEN, | ||
2658 | sizeof(struct be_mcc_compl))) | ||
2659 | goto err; | ||
2660 | /* Ask BE to create MCC compl queue; */ | ||
2661 | if (phba->msix_enabled) { | ||
2662 | if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq | ||
2663 | [phba->num_cpus].q, false, true, 0)) | ||
2664 | goto mcc_cq_free; | ||
2665 | } else { | ||
2666 | if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq[0].q, | ||
2667 | false, true, 0)) | ||
2668 | goto mcc_cq_free; | ||
2669 | } | ||
2670 | |||
2671 | /* Alloc MCC queue */ | ||
2672 | q = &phba->ctrl.mcc_obj.q; | ||
2673 | if (be_queue_alloc(phba, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb))) | ||
2674 | goto mcc_cq_destroy; | ||
2675 | |||
2676 | /* Ask BE to create MCC queue */ | ||
2677 | if (be_cmd_mccq_create(phba, q, cq)) | ||
2678 | goto mcc_q_free; | ||
2679 | |||
2680 | return 0; | ||
2681 | |||
2682 | mcc_q_free: | ||
2683 | be_queue_free(phba, q); | ||
2684 | mcc_cq_destroy: | ||
2685 | beiscsi_cmd_q_destroy(ctrl, cq, QTYPE_CQ); | ||
2686 | mcc_cq_free: | ||
2687 | be_queue_free(phba, cq); | ||
2688 | err: | ||
2689 | return -1; | ||
2690 | } | ||
2691 | |||
2692 | static int find_num_cpus(void) | ||
2693 | { | ||
2694 | int num_cpus = 0; | ||
2695 | |||
2696 | num_cpus = num_online_cpus(); | ||
2697 | if (num_cpus >= MAX_CPUS) | ||
2698 | num_cpus = MAX_CPUS - 1; | ||
2699 | |||
2700 | SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", num_cpus); | ||
2701 | return num_cpus; | ||
2366 | } | 2702 | } |
2367 | 2703 | ||
2368 | static int hwi_init_port(struct beiscsi_hba *phba) | 2704 | static int hwi_init_port(struct beiscsi_hba *phba) |
@@ -2376,20 +2712,23 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
2376 | def_pdu_ring_sz = | 2712 | def_pdu_ring_sz = |
2377 | phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr); | 2713 | phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr); |
2378 | phwi_ctrlr = phba->phwi_ctrlr; | 2714 | phwi_ctrlr = phba->phwi_ctrlr; |
2379 | |||
2380 | phwi_context = phwi_ctrlr->phwi_ctxt; | 2715 | phwi_context = phwi_ctrlr->phwi_ctxt; |
2381 | phwi_context->be_eq.max_eqd = 0; | 2716 | phwi_context->max_eqd = 0; |
2382 | phwi_context->be_eq.min_eqd = 0; | 2717 | phwi_context->min_eqd = 0; |
2383 | phwi_context->be_eq.cur_eqd = 64; | 2718 | phwi_context->cur_eqd = 64; |
2384 | phwi_context->be_eq.enable_aic = false; | ||
2385 | be_cmd_fw_initialize(&phba->ctrl); | 2719 | be_cmd_fw_initialize(&phba->ctrl); |
2386 | status = beiscsi_create_eq(phba, phwi_context); | 2720 | |
2721 | status = beiscsi_create_eqs(phba, phwi_context); | ||
2387 | if (status != 0) { | 2722 | if (status != 0) { |
2388 | shost_printk(KERN_ERR, phba->shost, "EQ not created \n"); | 2723 | shost_printk(KERN_ERR, phba->shost, "EQ not created \n"); |
2389 | goto error; | 2724 | goto error; |
2390 | } | 2725 | } |
2391 | 2726 | ||
2392 | status = mgmt_check_supported_fw(ctrl); | 2727 | status = be_mcc_queues_create(phba, phwi_context); |
2728 | if (status != 0) | ||
2729 | goto error; | ||
2730 | |||
2731 | status = mgmt_check_supported_fw(ctrl, phba); | ||
2393 | if (status != 0) { | 2732 | if (status != 0) { |
2394 | shost_printk(KERN_ERR, phba->shost, | 2733 | shost_printk(KERN_ERR, phba->shost, |
2395 | "Unsupported fw version \n"); | 2734 | "Unsupported fw version \n"); |
@@ -2403,7 +2742,7 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
2403 | goto error; | 2742 | goto error; |
2404 | } | 2743 | } |
2405 | 2744 | ||
2406 | status = beiscsi_create_cq(phba, phwi_context); | 2745 | status = beiscsi_create_cqs(phba, phwi_context); |
2407 | if (status != 0) { | 2746 | if (status != 0) { |
2408 | shost_printk(KERN_ERR, phba->shost, "CQ not created\n"); | 2747 | shost_printk(KERN_ERR, phba->shost, "CQ not created\n"); |
2409 | goto error; | 2748 | goto error; |
@@ -2447,7 +2786,6 @@ error: | |||
2447 | return -ENOMEM; | 2786 | return -ENOMEM; |
2448 | } | 2787 | } |
2449 | 2788 | ||
2450 | |||
2451 | static int hwi_init_controller(struct beiscsi_hba *phba) | 2789 | static int hwi_init_controller(struct beiscsi_hba *phba) |
2452 | { | 2790 | { |
2453 | struct hwi_controller *phwi_ctrlr; | 2791 | struct hwi_controller *phwi_ctrlr; |
@@ -2530,6 +2868,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
2530 | 2868 | ||
2531 | phba->io_sgl_hndl_avbl = 0; | 2869 | phba->io_sgl_hndl_avbl = 0; |
2532 | phba->eh_sgl_hndl_avbl = 0; | 2870 | phba->eh_sgl_hndl_avbl = 0; |
2871 | |||
2533 | mem_descr_sglh = phba->init_mem; | 2872 | mem_descr_sglh = phba->init_mem; |
2534 | mem_descr_sglh += HWI_MEM_SGLH; | 2873 | mem_descr_sglh += HWI_MEM_SGLH; |
2535 | if (1 == mem_descr_sglh->num_elements) { | 2874 | if (1 == mem_descr_sglh->num_elements) { |
@@ -2656,13 +2995,12 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) | |||
2656 | struct hwi_context_memory *phwi_context; | 2995 | struct hwi_context_memory *phwi_context; |
2657 | struct be_queue_info *eq; | 2996 | struct be_queue_info *eq; |
2658 | u8 __iomem *addr; | 2997 | u8 __iomem *addr; |
2659 | u32 reg; | 2998 | u32 reg, i; |
2660 | u32 enabled; | 2999 | u32 enabled; |
2661 | 3000 | ||
2662 | phwi_ctrlr = phba->phwi_ctrlr; | 3001 | phwi_ctrlr = phba->phwi_ctrlr; |
2663 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3002 | phwi_context = phwi_ctrlr->phwi_ctxt; |
2664 | 3003 | ||
2665 | eq = &phwi_context->be_eq.q; | ||
2666 | addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg + | 3004 | addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg + |
2667 | PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); | 3005 | PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); |
2668 | reg = ioread32(addr); | 3006 | reg = ioread32(addr); |
@@ -2673,9 +3011,11 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) | |||
2673 | reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; | 3011 | reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; |
2674 | SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); | 3012 | SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); |
2675 | iowrite32(reg, addr); | 3013 | iowrite32(reg, addr); |
2676 | SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); | 3014 | for (i = 0; i <= phba->num_cpus; i++) { |
2677 | 3015 | eq = &phwi_context->be_eq[i].q; | |
2678 | hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); | 3016 | SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); |
3017 | hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); | ||
3018 | } | ||
2679 | } else | 3019 | } else |
2680 | shost_printk(KERN_WARNING, phba->shost, | 3020 | shost_printk(KERN_WARNING, phba->shost, |
2681 | "In hwi_enable_intr, Not Enabled \n"); | 3021 | "In hwi_enable_intr, Not Enabled \n"); |
@@ -2738,17 +3078,25 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
2738 | struct hwi_context_memory *phwi_context; | 3078 | struct hwi_context_memory *phwi_context; |
2739 | struct be_queue_info *eq; | 3079 | struct be_queue_info *eq; |
2740 | struct be_eq_entry *eqe = NULL; | 3080 | struct be_eq_entry *eqe = NULL; |
3081 | int i, eq_msix; | ||
2741 | 3082 | ||
2742 | phwi_ctrlr = phba->phwi_ctrlr; | 3083 | phwi_ctrlr = phba->phwi_ctrlr; |
2743 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3084 | phwi_context = phwi_ctrlr->phwi_ctxt; |
2744 | eq = &phwi_context->be_eq.q; | 3085 | if (phba->msix_enabled) |
2745 | eqe = queue_tail_node(eq); | 3086 | eq_msix = 1; |
3087 | else | ||
3088 | eq_msix = 0; | ||
2746 | 3089 | ||
2747 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | 3090 | for (i = 0; i < (phba->num_cpus + eq_msix); i++) { |
2748 | & EQE_VALID_MASK) { | 3091 | 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); | 3092 | eqe = queue_tail_node(eq); |
3093 | |||
3094 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | ||
3095 | & EQE_VALID_MASK) { | ||
3096 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | ||
3097 | queue_tail_inc(eq); | ||
3098 | eqe = queue_tail_node(eq); | ||
3099 | } | ||
2752 | } | 3100 | } |
2753 | } | 3101 | } |
2754 | 3102 | ||
@@ -2846,8 +3194,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, | |||
2846 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); | 3194 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); |
2847 | 3195 | ||
2848 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | 3196 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; |
2849 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) << | 3197 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) |
2850 | DB_DEF_PDU_WRB_INDEX_SHIFT; | 3198 | << DB_DEF_PDU_WRB_INDEX_SHIFT; |
2851 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3199 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
2852 | 3200 | ||
2853 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 3201 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); |
@@ -2856,7 +3204,7 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, | |||
2856 | static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt, | 3204 | static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt, |
2857 | int *index, int *age) | 3205 | int *index, int *age) |
2858 | { | 3206 | { |
2859 | *index = be32_to_cpu(itt) >> 16; | 3207 | *index = (int)itt; |
2860 | if (age) | 3208 | if (age) |
2861 | *age = conn->session->age; | 3209 | *age = conn->session->age; |
2862 | } | 3210 | } |
@@ -2885,15 +3233,13 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
2885 | 3233 | ||
2886 | io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool, | 3234 | io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool, |
2887 | GFP_KERNEL, &paddr); | 3235 | GFP_KERNEL, &paddr); |
2888 | |||
2889 | if (!io_task->cmd_bhs) | 3236 | if (!io_task->cmd_bhs) |
2890 | return -ENOMEM; | 3237 | return -ENOMEM; |
2891 | |||
2892 | io_task->bhs_pa.u.a64.address = paddr; | 3238 | io_task->bhs_pa.u.a64.address = paddr; |
3239 | io_task->libiscsi_itt = (itt_t)task->itt; | ||
2893 | io_task->pwrb_handle = alloc_wrb_handle(phba, | 3240 | io_task->pwrb_handle = alloc_wrb_handle(phba, |
2894 | beiscsi_conn->beiscsi_conn_cid, | 3241 | beiscsi_conn->beiscsi_conn_cid, |
2895 | task->itt); | 3242 | task->itt); |
2896 | io_task->pwrb_handle->pio_handle = task; | ||
2897 | io_task->conn = beiscsi_conn; | 3243 | io_task->conn = beiscsi_conn; |
2898 | 3244 | ||
2899 | task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; | 3245 | task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; |
@@ -2905,7 +3251,6 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
2905 | spin_unlock(&phba->io_sgl_lock); | 3251 | spin_unlock(&phba->io_sgl_lock); |
2906 | if (!io_task->psgl_handle) | 3252 | if (!io_task->psgl_handle) |
2907 | goto free_hndls; | 3253 | goto free_hndls; |
2908 | |||
2909 | } else { | 3254 | } else { |
2910 | io_task->scsi_cmnd = NULL; | 3255 | io_task->scsi_cmnd = NULL; |
2911 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { | 3256 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { |
@@ -2932,8 +3277,11 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
2932 | goto free_hndls; | 3277 | goto free_hndls; |
2933 | } | 3278 | } |
2934 | } | 3279 | } |
2935 | itt = (itt_t) cpu_to_be32(((unsigned int)task->itt << 16) | | 3280 | itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> |
2936 | (unsigned int)(io_task->psgl_handle->sgl_index)); | 3281 | wrb_index << 16) | (unsigned int) |
3282 | (io_task->psgl_handle->sgl_index)); | ||
3283 | io_task->pwrb_handle->pio_handle = task; | ||
3284 | |||
2937 | io_task->cmd_bhs->iscsi_hdr.itt = itt; | 3285 | io_task->cmd_bhs->iscsi_hdr.itt = itt; |
2938 | return 0; | 3286 | return 0; |
2939 | 3287 | ||
@@ -3006,7 +3354,6 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3006 | io_task->bhs_len = sizeof(struct be_cmd_bhs); | 3354 | io_task->bhs_len = sizeof(struct be_cmd_bhs); |
3007 | 3355 | ||
3008 | if (writedir) { | 3356 | if (writedir) { |
3009 | SE_DEBUG(DBG_LVL_4, " WRITE Command \t"); | ||
3010 | memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48); | 3357 | memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48); |
3011 | AMAP_SET_BITS(struct amap_pdu_data_out, itt, | 3358 | AMAP_SET_BITS(struct amap_pdu_data_out, itt, |
3012 | &io_task->cmd_bhs->iscsi_data_pdu, | 3359 | &io_task->cmd_bhs->iscsi_data_pdu, |
@@ -3016,11 +3363,12 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3016 | ISCSI_OPCODE_SCSI_DATA_OUT); | 3363 | ISCSI_OPCODE_SCSI_DATA_OUT); |
3017 | AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, | 3364 | AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, |
3018 | &io_task->cmd_bhs->iscsi_data_pdu, 1); | 3365 | &io_task->cmd_bhs->iscsi_data_pdu, 1); |
3019 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD); | 3366 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3367 | INI_WR_CMD); | ||
3020 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | 3368 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); |
3021 | } else { | 3369 | } else { |
3022 | SE_DEBUG(DBG_LVL_4, "READ Command \t"); | 3370 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3023 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD); | 3371 | INI_RD_CMD); |
3024 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); | 3372 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); |
3025 | } | 3373 | } |
3026 | memcpy(&io_task->cmd_bhs->iscsi_data_pdu. | 3374 | memcpy(&io_task->cmd_bhs->iscsi_data_pdu. |
@@ -3059,10 +3407,16 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3059 | struct iscsi_conn *conn = task->conn; | 3407 | struct iscsi_conn *conn = task->conn; |
3060 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 3408 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
3061 | struct beiscsi_hba *phba = beiscsi_conn->phba; | 3409 | struct beiscsi_hba *phba = beiscsi_conn->phba; |
3410 | struct iscsi_session *session; | ||
3062 | struct iscsi_wrb *pwrb = NULL; | 3411 | struct iscsi_wrb *pwrb = NULL; |
3412 | struct hwi_controller *phwi_ctrlr; | ||
3413 | struct hwi_wrb_context *pwrb_context; | ||
3414 | struct wrb_handle *pwrb_handle; | ||
3063 | unsigned int doorbell = 0; | 3415 | unsigned int doorbell = 0; |
3416 | unsigned int i, cid; | ||
3064 | struct iscsi_task *aborted_task; | 3417 | struct iscsi_task *aborted_task; |
3065 | 3418 | ||
3419 | cid = beiscsi_conn->beiscsi_conn_cid; | ||
3066 | pwrb = io_task->pwrb_handle->pwrb; | 3420 | pwrb = io_task->pwrb_handle->pwrb; |
3067 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, | 3421 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, |
3068 | be32_to_cpu(task->cmdsn)); | 3422 | be32_to_cpu(task->cmdsn)); |
@@ -3073,33 +3427,43 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3073 | 3427 | ||
3074 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { | 3428 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { |
3075 | case ISCSI_OP_LOGIN: | 3429 | case ISCSI_OP_LOGIN: |
3076 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, TGT_DM_CMD); | 3430 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3431 | TGT_DM_CMD); | ||
3077 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3432 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3078 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); | 3433 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); |
3079 | hwi_write_buffer(pwrb, task); | 3434 | hwi_write_buffer(pwrb, task); |
3080 | break; | 3435 | break; |
3081 | case ISCSI_OP_NOOP_OUT: | 3436 | case ISCSI_OP_NOOP_OUT: |
3082 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD); | 3437 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3438 | INI_RD_CMD); | ||
3083 | hwi_write_buffer(pwrb, task); | 3439 | hwi_write_buffer(pwrb, task); |
3084 | break; | 3440 | break; |
3085 | case ISCSI_OP_TEXT: | 3441 | case ISCSI_OP_TEXT: |
3086 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD); | 3442 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3443 | INI_WR_CMD); | ||
3087 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | 3444 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); |
3088 | hwi_write_buffer(pwrb, task); | 3445 | hwi_write_buffer(pwrb, task); |
3089 | break; | 3446 | break; |
3090 | case ISCSI_OP_SCSI_TMFUNC: | 3447 | case ISCSI_OP_SCSI_TMFUNC: |
3091 | aborted_task = iscsi_itt_to_task(conn, | 3448 | session = conn->session; |
3092 | ((struct iscsi_tm *)task->hdr)->rtt); | 3449 | i = ((struct iscsi_tm *)task->hdr)->rtt; |
3450 | phwi_ctrlr = phba->phwi_ctrlr; | ||
3451 | pwrb_context = &phwi_ctrlr->wrb_context[cid]; | ||
3452 | pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i) | ||
3453 | >> 16]; | ||
3454 | aborted_task = pwrb_handle->pio_handle; | ||
3093 | if (!aborted_task) | 3455 | if (!aborted_task) |
3094 | return 0; | 3456 | return 0; |
3457 | |||
3095 | aborted_io_task = aborted_task->dd_data; | 3458 | aborted_io_task = aborted_task->dd_data; |
3096 | if (!aborted_io_task->scsi_cmnd) | 3459 | if (!aborted_io_task->scsi_cmnd) |
3097 | return 0; | 3460 | return 0; |
3098 | 3461 | ||
3099 | mgmt_invalidate_icds(phba, | 3462 | mgmt_invalidate_icds(phba, |
3100 | aborted_io_task->psgl_handle->sgl_index, | 3463 | aborted_io_task->psgl_handle->sgl_index, |
3101 | beiscsi_conn->beiscsi_conn_cid); | 3464 | cid); |
3102 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_TMF_CMD); | 3465 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3466 | INI_TMF_CMD); | ||
3103 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3467 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3104 | hwi_write_buffer(pwrb, task); | 3468 | hwi_write_buffer(pwrb, task); |
3105 | break; | 3469 | break; |
@@ -3122,7 +3486,7 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3122 | io_task->pwrb_handle->nxt_wrb_index); | 3486 | io_task->pwrb_handle->nxt_wrb_index); |
3123 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | 3487 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); |
3124 | 3488 | ||
3125 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | 3489 | doorbell |= cid & DB_WRB_POST_CID_MASK; |
3126 | doorbell |= (io_task->pwrb_handle->wrb_index & | 3490 | doorbell |= (io_task->pwrb_handle->wrb_index & |
3127 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3491 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3128 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3492 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
@@ -3165,9 +3529,14 @@ static int beiscsi_task_xmit(struct iscsi_task *task) | |||
3165 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); | 3529 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); |
3166 | } | 3530 | } |
3167 | 3531 | ||
3532 | |||
3168 | static void beiscsi_remove(struct pci_dev *pcidev) | 3533 | static void beiscsi_remove(struct pci_dev *pcidev) |
3169 | { | 3534 | { |
3170 | struct beiscsi_hba *phba = NULL; | 3535 | struct beiscsi_hba *phba = NULL; |
3536 | struct hwi_controller *phwi_ctrlr; | ||
3537 | struct hwi_context_memory *phwi_context; | ||
3538 | struct be_eq_obj *pbe_eq; | ||
3539 | unsigned int i, msix_vec; | ||
3171 | 3540 | ||
3172 | phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); | 3541 | phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); |
3173 | if (!phba) { | 3542 | if (!phba) { |
@@ -3175,12 +3544,24 @@ static void beiscsi_remove(struct pci_dev *pcidev) | |||
3175 | return; | 3544 | return; |
3176 | } | 3545 | } |
3177 | 3546 | ||
3547 | phwi_ctrlr = phba->phwi_ctrlr; | ||
3548 | phwi_context = phwi_ctrlr->phwi_ctxt; | ||
3178 | hwi_disable_intr(phba); | 3549 | hwi_disable_intr(phba); |
3179 | if (phba->pcidev->irq) | 3550 | if (phba->msix_enabled) { |
3180 | free_irq(phba->pcidev->irq, phba); | 3551 | for (i = 0; i <= phba->num_cpus; i++) { |
3552 | msix_vec = phba->msix_entries[i].vector; | ||
3553 | free_irq(msix_vec, &phwi_context->be_eq[i]); | ||
3554 | } | ||
3555 | } else | ||
3556 | if (phba->pcidev->irq) | ||
3557 | free_irq(phba->pcidev->irq, phba); | ||
3558 | pci_disable_msix(phba->pcidev); | ||
3181 | destroy_workqueue(phba->wq); | 3559 | destroy_workqueue(phba->wq); |
3182 | if (blk_iopoll_enabled) | 3560 | if (blk_iopoll_enabled) |
3183 | blk_iopoll_disable(&phba->iopoll); | 3561 | for (i = 0; i < phba->num_cpus; i++) { |
3562 | pbe_eq = &phwi_context->be_eq[i]; | ||
3563 | blk_iopoll_disable(&pbe_eq->iopoll); | ||
3564 | } | ||
3184 | 3565 | ||
3185 | beiscsi_clean_port(phba); | 3566 | beiscsi_clean_port(phba); |
3186 | beiscsi_free_mem(phba); | 3567 | beiscsi_free_mem(phba); |
@@ -3194,11 +3575,29 @@ static void beiscsi_remove(struct pci_dev *pcidev) | |||
3194 | iscsi_host_free(phba->shost); | 3575 | iscsi_host_free(phba->shost); |
3195 | } | 3576 | } |
3196 | 3577 | ||
3578 | static void beiscsi_msix_enable(struct beiscsi_hba *phba) | ||
3579 | { | ||
3580 | int i, status; | ||
3581 | |||
3582 | for (i = 0; i <= phba->num_cpus; i++) | ||
3583 | phba->msix_entries[i].entry = i; | ||
3584 | |||
3585 | status = pci_enable_msix(phba->pcidev, phba->msix_entries, | ||
3586 | (phba->num_cpus + 1)); | ||
3587 | if (!status) | ||
3588 | phba->msix_enabled = true; | ||
3589 | |||
3590 | return; | ||
3591 | } | ||
3592 | |||
3197 | static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | 3593 | static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, |
3198 | const struct pci_device_id *id) | 3594 | const struct pci_device_id *id) |
3199 | { | 3595 | { |
3200 | struct beiscsi_hba *phba = NULL; | 3596 | struct beiscsi_hba *phba = NULL; |
3201 | int ret; | 3597 | struct hwi_controller *phwi_ctrlr; |
3598 | struct hwi_context_memory *phwi_context; | ||
3599 | struct be_eq_obj *pbe_eq; | ||
3600 | int ret, msix_vec, num_cpus, i; | ||
3202 | 3601 | ||
3203 | ret = beiscsi_enable_pci(pcidev); | 3602 | ret = beiscsi_enable_pci(pcidev); |
3204 | if (ret < 0) { | 3603 | if (ret < 0) { |
@@ -3213,8 +3612,18 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3213 | " Failed in beiscsi_hba_alloc \n"); | 3612 | " Failed in beiscsi_hba_alloc \n"); |
3214 | goto disable_pci; | 3613 | goto disable_pci; |
3215 | } | 3614 | } |
3615 | SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba); | ||
3216 | 3616 | ||
3217 | pci_set_drvdata(pcidev, phba); | 3617 | pci_set_drvdata(pcidev, phba); |
3618 | if (enable_msix) | ||
3619 | num_cpus = find_num_cpus(); | ||
3620 | else | ||
3621 | num_cpus = 1; | ||
3622 | phba->num_cpus = num_cpus; | ||
3623 | SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", phba->num_cpus); | ||
3624 | |||
3625 | if (enable_msix) | ||
3626 | beiscsi_msix_enable(phba); | ||
3218 | ret = be_ctrl_init(phba, pcidev); | 3627 | ret = be_ctrl_init(phba, pcidev); |
3219 | if (ret) { | 3628 | if (ret) { |
3220 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" | 3629 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" |
@@ -3235,7 +3644,7 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3235 | 3644 | ||
3236 | snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", | 3645 | snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", |
3237 | phba->shost->host_no); | 3646 | phba->shost->host_no); |
3238 | phba->wq = create_singlethread_workqueue(phba->wq_name); | 3647 | phba->wq = create_workqueue(phba->wq_name); |
3239 | if (!phba->wq) { | 3648 | if (!phba->wq) { |
3240 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" | 3649 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" |
3241 | "Failed to allocate work queue\n"); | 3650 | "Failed to allocate work queue\n"); |
@@ -3244,11 +3653,16 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3244 | 3653 | ||
3245 | INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs); | 3654 | INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs); |
3246 | 3655 | ||
3656 | phwi_ctrlr = phba->phwi_ctrlr; | ||
3657 | phwi_context = phwi_ctrlr->phwi_ctxt; | ||
3247 | if (blk_iopoll_enabled) { | 3658 | if (blk_iopoll_enabled) { |
3248 | blk_iopoll_init(&phba->iopoll, be_iopoll_budget, be_iopoll); | 3659 | for (i = 0; i < phba->num_cpus; i++) { |
3249 | blk_iopoll_enable(&phba->iopoll); | 3660 | pbe_eq = &phwi_context->be_eq[i]; |
3661 | blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget, | ||
3662 | be_iopoll); | ||
3663 | blk_iopoll_enable(&pbe_eq->iopoll); | ||
3664 | } | ||
3250 | } | 3665 | } |
3251 | |||
3252 | ret = beiscsi_init_irqs(phba); | 3666 | ret = beiscsi_init_irqs(phba); |
3253 | if (ret < 0) { | 3667 | if (ret < 0) { |
3254 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" | 3668 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" |
@@ -3261,17 +3675,26 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3261 | "Failed to hwi_enable_intr\n"); | 3675 | "Failed to hwi_enable_intr\n"); |
3262 | goto free_ctrlr; | 3676 | goto free_ctrlr; |
3263 | } | 3677 | } |
3264 | |||
3265 | SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n"); | 3678 | SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n"); |
3266 | return 0; | 3679 | return 0; |
3267 | 3680 | ||
3268 | free_ctrlr: | 3681 | free_ctrlr: |
3269 | if (phba->pcidev->irq) | 3682 | if (phba->msix_enabled) { |
3270 | free_irq(phba->pcidev->irq, phba); | 3683 | for (i = 0; i <= phba->num_cpus; i++) { |
3684 | msix_vec = phba->msix_entries[i].vector; | ||
3685 | free_irq(msix_vec, &phwi_context->be_eq[i]); | ||
3686 | } | ||
3687 | } else | ||
3688 | if (phba->pcidev->irq) | ||
3689 | free_irq(phba->pcidev->irq, phba); | ||
3690 | pci_disable_msix(phba->pcidev); | ||
3271 | free_blkenbld: | 3691 | free_blkenbld: |
3272 | destroy_workqueue(phba->wq); | 3692 | destroy_workqueue(phba->wq); |
3273 | if (blk_iopoll_enabled) | 3693 | if (blk_iopoll_enabled) |
3274 | blk_iopoll_disable(&phba->iopoll); | 3694 | for (i = 0; i < phba->num_cpus; i++) { |
3695 | pbe_eq = &phwi_context->be_eq[i]; | ||
3696 | blk_iopoll_disable(&pbe_eq->iopoll); | ||
3697 | } | ||
3275 | free_twq: | 3698 | free_twq: |
3276 | beiscsi_clean_port(phba); | 3699 | beiscsi_clean_port(phba); |
3277 | beiscsi_free_mem(phba); | 3700 | beiscsi_free_mem(phba); |
@@ -3351,6 +3774,7 @@ static struct pci_driver beiscsi_pci_driver = { | |||
3351 | .id_table = beiscsi_pci_id_table | 3774 | .id_table = beiscsi_pci_id_table |
3352 | }; | 3775 | }; |
3353 | 3776 | ||
3777 | |||
3354 | static int __init beiscsi_module_init(void) | 3778 | static int __init beiscsi_module_init(void) |
3355 | { | 3779 | { |
3356 | int ret; | 3780 | int ret; |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 53c9b70ac7ac..25e6b208b771 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -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,12 +33,8 @@ | |||
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" |
@@ -49,6 +43,8 @@ | |||
49 | #define BE_DEVICE_ID1 0x212 | 43 | #define BE_DEVICE_ID1 0x212 |
50 | #define OC_DEVICE_ID1 0x702 | 44 | #define OC_DEVICE_ID1 0x702 |
51 | #define OC_DEVICE_ID2 0x703 | 45 | #define OC_DEVICE_ID2 0x703 |
46 | #define OC_DEVICE_ID3 0x712 | ||
47 | #define OC_DEVICE_ID4 0x222 | ||
52 | 48 | ||
53 | #define BE2_MAX_SESSIONS 64 | 49 | #define BE2_MAX_SESSIONS 64 |
54 | #define BE2_CMDS_PER_CXN 128 | 50 | #define BE2_CMDS_PER_CXN 128 |
@@ -63,6 +59,7 @@ | |||
63 | #define BE2_IO_DEPTH \ | 59 | #define BE2_IO_DEPTH \ |
64 | (BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ)) | 60 | (BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ)) |
65 | 61 | ||
62 | #define MAX_CPUS 31 | ||
66 | #define BEISCSI_SGLIST_ELEMENTS BE2_SGE | 63 | #define BEISCSI_SGLIST_ELEMENTS BE2_SGE |
67 | 64 | ||
68 | #define BEISCSI_MAX_CMNDS 1024 /* Max IO's per Ctrlr sht->can_queue */ | 65 | #define BEISCSI_MAX_CMNDS 1024 /* Max IO's per Ctrlr sht->can_queue */ |
@@ -79,7 +76,7 @@ | |||
79 | #define BE_SENSE_INFO_SIZE 258 | 76 | #define BE_SENSE_INFO_SIZE 258 |
80 | #define BE_ISCSI_PDU_HEADER_SIZE 64 | 77 | #define BE_ISCSI_PDU_HEADER_SIZE 64 |
81 | #define BE_MIN_MEM_SIZE 16384 | 78 | #define BE_MIN_MEM_SIZE 16384 |
82 | 79 | #define MAX_CMD_SZ 65536 | |
83 | #define IIOC_SCSI_DATA 0x05 /* Write Operation */ | 80 | #define IIOC_SCSI_DATA 0x05 /* Write Operation */ |
84 | 81 | ||
85 | #define DBG_LVL 0x00000001 | 82 | #define DBG_LVL 0x00000001 |
@@ -100,6 +97,8 @@ do { \ | |||
100 | } \ | 97 | } \ |
101 | } while (0); | 98 | } while (0); |
102 | 99 | ||
100 | #define BE_ADAPTER_UP 0x00000000 | ||
101 | #define BE_ADAPTER_LINK_DOWN 0x00000001 | ||
103 | /** | 102 | /** |
104 | * hardware needs the async PDU buffers to be posted in multiples of 8 | 103 | * hardware needs the async PDU buffers to be posted in multiples of 8 |
105 | * So have atleast 8 of them by default | 104 | * So have atleast 8 of them by default |
@@ -160,21 +159,19 @@ do { \ | |||
160 | 159 | ||
161 | enum be_mem_enum { | 160 | enum be_mem_enum { |
162 | HWI_MEM_ADDN_CONTEXT, | 161 | HWI_MEM_ADDN_CONTEXT, |
163 | HWI_MEM_CQ, | ||
164 | HWI_MEM_EQ, | ||
165 | HWI_MEM_WRB, | 162 | HWI_MEM_WRB, |
166 | HWI_MEM_WRBH, | 163 | HWI_MEM_WRBH, |
167 | HWI_MEM_SGLH, /* 5 */ | 164 | HWI_MEM_SGLH, |
168 | HWI_MEM_SGE, | 165 | HWI_MEM_SGE, |
169 | HWI_MEM_ASYNC_HEADER_BUF, | 166 | HWI_MEM_ASYNC_HEADER_BUF, /* 5 */ |
170 | HWI_MEM_ASYNC_DATA_BUF, | 167 | HWI_MEM_ASYNC_DATA_BUF, |
171 | HWI_MEM_ASYNC_HEADER_RING, | 168 | HWI_MEM_ASYNC_HEADER_RING, |
172 | HWI_MEM_ASYNC_DATA_RING, /* 10 */ | 169 | HWI_MEM_ASYNC_DATA_RING, |
173 | HWI_MEM_ASYNC_HEADER_HANDLE, | 170 | HWI_MEM_ASYNC_HEADER_HANDLE, |
174 | HWI_MEM_ASYNC_DATA_HANDLE, | 171 | HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */ |
175 | HWI_MEM_ASYNC_PDU_CONTEXT, | 172 | HWI_MEM_ASYNC_PDU_CONTEXT, |
176 | ISCSI_MEM_GLOBAL_HEADER, | 173 | ISCSI_MEM_GLOBAL_HEADER, |
177 | SE_MEM_MAX /* 15 */ | 174 | SE_MEM_MAX |
178 | }; | 175 | }; |
179 | 176 | ||
180 | struct be_bus_address32 { | 177 | struct be_bus_address32 { |
@@ -212,6 +209,9 @@ struct be_mem_descriptor { | |||
212 | 209 | ||
213 | struct sgl_handle { | 210 | struct sgl_handle { |
214 | unsigned int sgl_index; | 211 | unsigned int sgl_index; |
212 | unsigned int type; | ||
213 | unsigned int cid; | ||
214 | struct iscsi_task *task; | ||
215 | struct iscsi_sge *pfrag; | 215 | struct iscsi_sge *pfrag; |
216 | }; | 216 | }; |
217 | 217 | ||
@@ -274,13 +274,17 @@ struct beiscsi_hba { | |||
274 | struct pci_dev *pcidev; | 274 | struct pci_dev *pcidev; |
275 | unsigned int state; | 275 | unsigned int state; |
276 | unsigned short asic_revision; | 276 | unsigned short asic_revision; |
277 | struct blk_iopoll iopoll; | 277 | unsigned int num_cpus; |
278 | unsigned int nxt_cqid; | ||
279 | struct msix_entry msix_entries[MAX_CPUS + 1]; | ||
280 | bool msix_enabled; | ||
278 | struct be_mem_descriptor *init_mem; | 281 | struct be_mem_descriptor *init_mem; |
279 | 282 | ||
280 | unsigned short io_sgl_alloc_index; | 283 | unsigned short io_sgl_alloc_index; |
281 | unsigned short io_sgl_free_index; | 284 | unsigned short io_sgl_free_index; |
282 | unsigned short io_sgl_hndl_avbl; | 285 | unsigned short io_sgl_hndl_avbl; |
283 | struct sgl_handle **io_sgl_hndl_base; | 286 | struct sgl_handle **io_sgl_hndl_base; |
287 | struct sgl_handle **sgl_hndl_array; | ||
284 | 288 | ||
285 | unsigned short eh_sgl_alloc_index; | 289 | unsigned short eh_sgl_alloc_index; |
286 | unsigned short eh_sgl_free_index; | 290 | unsigned short eh_sgl_free_index; |
@@ -315,6 +319,7 @@ struct beiscsi_hba { | |||
315 | unsigned short cid_alloc; | 319 | unsigned short cid_alloc; |
316 | unsigned short cid_free; | 320 | unsigned short cid_free; |
317 | unsigned short avlbl_cids; | 321 | unsigned short avlbl_cids; |
322 | unsigned short iscsi_features; | ||
318 | spinlock_t cid_lock; | 323 | spinlock_t cid_lock; |
319 | } fw_config; | 324 | } fw_config; |
320 | 325 | ||
@@ -343,6 +348,7 @@ struct beiscsi_conn { | |||
343 | unsigned short login_in_progress; | 348 | unsigned short login_in_progress; |
344 | struct sgl_handle *plogin_sgl_handle; | 349 | struct sgl_handle *plogin_sgl_handle; |
345 | struct beiscsi_session *beiscsi_sess; | 350 | struct beiscsi_session *beiscsi_sess; |
351 | struct iscsi_task *task; | ||
346 | }; | 352 | }; |
347 | 353 | ||
348 | /* This structure is used by the chip */ | 354 | /* This structure is used by the chip */ |
@@ -390,7 +396,7 @@ struct beiscsi_io_task { | |||
390 | unsigned int flags; | 396 | unsigned int flags; |
391 | unsigned short cid; | 397 | unsigned short cid; |
392 | unsigned short header_len; | 398 | unsigned short header_len; |
393 | 399 | itt_t libiscsi_itt; | |
394 | struct be_cmd_bhs *cmd_bhs; | 400 | struct be_cmd_bhs *cmd_bhs; |
395 | struct be_bus_address bhs_pa; | 401 | struct be_bus_address bhs_pa; |
396 | unsigned short bhs_len; | 402 | unsigned short bhs_len; |
@@ -599,7 +605,6 @@ struct amap_cq_db { | |||
599 | 605 | ||
600 | void beiscsi_process_eq(struct beiscsi_hba *phba); | 606 | void beiscsi_process_eq(struct beiscsi_hba *phba); |
601 | 607 | ||
602 | |||
603 | struct iscsi_wrb { | 608 | struct iscsi_wrb { |
604 | u32 dw[16]; | 609 | u32 dw[16]; |
605 | } __packed; | 610 | } __packed; |
@@ -820,10 +825,12 @@ struct wrb_handle { | |||
820 | }; | 825 | }; |
821 | 826 | ||
822 | struct hwi_context_memory { | 827 | struct hwi_context_memory { |
823 | struct be_eq_obj be_eq; | 828 | /* Adaptive interrupt coalescing (AIC) info */ |
824 | struct be_queue_info be_cq; | 829 | u16 min_eqd; /* in usecs */ |
825 | struct be_queue_info be_mcc_cq; | 830 | u16 max_eqd; /* in usecs */ |
826 | struct be_queue_info be_mcc; | 831 | u16 cur_eqd; /* in usecs */ |
832 | struct be_eq_obj be_eq[MAX_CPUS]; | ||
833 | struct be_queue_info be_cq[MAX_CPUS]; | ||
827 | 834 | ||
828 | struct be_queue_info be_def_hdrq; | 835 | struct be_queue_info be_def_hdrq; |
829 | struct be_queue_info be_def_dataq; | 836 | 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..79c2bd525a84 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -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; |
@@ -58,7 +57,8 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl, | |||
58 | return status; | 57 | return status; |
59 | } | 58 | } |
60 | 59 | ||
61 | unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl) | 60 | unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, |
61 | struct beiscsi_hba *phba) | ||
62 | { | 62 | { |
63 | struct be_dma_mem nonemb_cmd; | 63 | struct be_dma_mem nonemb_cmd; |
64 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 64 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); |
@@ -85,7 +85,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)); | 85 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); |
86 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); | 86 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); |
87 | sge->len = cpu_to_le32(nonemb_cmd.size); | 87 | sge->len = cpu_to_le32(nonemb_cmd.size); |
88 | |||
89 | status = be_mbox_notify(ctrl); | 88 | status = be_mbox_notify(ctrl); |
90 | if (!status) { | 89 | if (!status) { |
91 | struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va; | 90 | struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va; |
@@ -95,21 +94,25 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl) | |||
95 | resp->params.hba_attribs.firmware_version_string); | 94 | resp->params.hba_attribs.firmware_version_string); |
96 | SE_DEBUG(DBG_LVL_8, | 95 | SE_DEBUG(DBG_LVL_8, |
97 | "Developer Build, not performing version check...\n"); | 96 | "Developer Build, not performing version check...\n"); |
98 | 97 | phba->fw_config.iscsi_features = | |
98 | resp->params.hba_attribs.iscsi_features; | ||
99 | SE_DEBUG(DBG_LVL_8, " phba->fw_config.iscsi_features = %d\n", | ||
100 | phba->fw_config.iscsi_features); | ||
99 | } else | 101 | } else |
100 | SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n"); | 102 | SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n"); |
103 | spin_unlock(&ctrl->mbox_lock); | ||
101 | if (nonemb_cmd.va) | 104 | if (nonemb_cmd.va) |
102 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, | 105 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, |
103 | nonemb_cmd.va, nonemb_cmd.dma); | 106 | nonemb_cmd.va, nonemb_cmd.dma); |
104 | 107 | ||
105 | spin_unlock(&ctrl->mbox_lock); | ||
106 | return status; | 108 | return status; |
107 | } | 109 | } |
108 | 110 | ||
111 | |||
109 | unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) | 112 | unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) |
110 | { | 113 | { |
111 | struct be_ctrl_info *ctrl = &phba->ctrl; | 114 | struct be_ctrl_info *ctrl = &phba->ctrl; |
112 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 115 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); |
113 | struct iscsi_cleanup_req *req = embedded_payload(wrb); | 116 | struct iscsi_cleanup_req *req = embedded_payload(wrb); |
114 | int status = 0; | 117 | int status = 0; |
115 | 118 | ||
@@ -124,7 +127,7 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) | |||
124 | req->hdr_ring_id = 0; | 127 | req->hdr_ring_id = 0; |
125 | req->data_ring_id = 0; | 128 | req->data_ring_id = 0; |
126 | 129 | ||
127 | status = be_mbox_notify(ctrl); | 130 | status = be_mcc_notify_wait(phba); |
128 | if (status) | 131 | if (status) |
129 | shost_printk(KERN_WARNING, phba->shost, | 132 | shost_printk(KERN_WARNING, phba->shost, |
130 | " mgmt_epfw_cleanup , FAILED\n"); | 133 | " mgmt_epfw_cleanup , FAILED\n"); |
@@ -137,7 +140,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
137 | { | 140 | { |
138 | struct be_dma_mem nonemb_cmd; | 141 | struct be_dma_mem nonemb_cmd; |
139 | struct be_ctrl_info *ctrl = &phba->ctrl; | 142 | struct be_ctrl_info *ctrl = &phba->ctrl; |
140 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 143 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); |
141 | struct be_sge *sge = nonembedded_sgl(wrb); | 144 | struct be_sge *sge = nonembedded_sgl(wrb); |
142 | struct invalidate_commands_params_in *req; | 145 | struct invalidate_commands_params_in *req; |
143 | int status = 0; | 146 | int status = 0; |
@@ -169,7 +172,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
169 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); | 172 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); |
170 | sge->len = cpu_to_le32(nonemb_cmd.size); | 173 | sge->len = cpu_to_le32(nonemb_cmd.size); |
171 | 174 | ||
172 | status = be_mbox_notify(ctrl); | 175 | status = be_mcc_notify_wait(phba); |
173 | if (status) | 176 | if (status) |
174 | SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n"); | 177 | SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n"); |
175 | spin_unlock(&ctrl->mbox_lock); | 178 | spin_unlock(&ctrl->mbox_lock); |
@@ -186,7 +189,7 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
186 | unsigned short savecfg_flag) | 189 | unsigned short savecfg_flag) |
187 | { | 190 | { |
188 | struct be_ctrl_info *ctrl = &phba->ctrl; | 191 | struct be_ctrl_info *ctrl = &phba->ctrl; |
189 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 192 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); |
190 | struct iscsi_invalidate_connection_params_in *req = | 193 | struct iscsi_invalidate_connection_params_in *req = |
191 | embedded_payload(wrb); | 194 | embedded_payload(wrb); |
192 | int status = 0; | 195 | int status = 0; |
@@ -205,7 +208,7 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
205 | else | 208 | else |
206 | req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; | 209 | req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; |
207 | req->save_cfg = savecfg_flag; | 210 | req->save_cfg = savecfg_flag; |
208 | status = be_mbox_notify(ctrl); | 211 | status = be_mcc_notify_wait(phba); |
209 | if (status) | 212 | if (status) |
210 | SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n"); | 213 | SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n"); |
211 | 214 | ||
@@ -217,7 +220,7 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, | |||
217 | unsigned short cid, unsigned int upload_flag) | 220 | unsigned short cid, unsigned int upload_flag) |
218 | { | 221 | { |
219 | struct be_ctrl_info *ctrl = &phba->ctrl; | 222 | struct be_ctrl_info *ctrl = &phba->ctrl; |
220 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 223 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); |
221 | struct tcp_upload_params_in *req = embedded_payload(wrb); | 224 | struct tcp_upload_params_in *req = embedded_payload(wrb); |
222 | int status = 0; | 225 | int status = 0; |
223 | 226 | ||
@@ -229,7 +232,7 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, | |||
229 | OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); | 232 | OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); |
230 | req->id = (unsigned short)cid; | 233 | req->id = (unsigned short)cid; |
231 | req->upload_type = (unsigned char)upload_flag; | 234 | req->upload_type = (unsigned char)upload_flag; |
232 | status = be_mbox_notify(ctrl); | 235 | status = be_mcc_notify_wait(phba); |
233 | if (status) | 236 | if (status) |
234 | SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n"); | 237 | SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n"); |
235 | spin_unlock(&ctrl->mbox_lock); | 238 | spin_unlock(&ctrl->mbox_lock); |
@@ -245,13 +248,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
245 | struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; | 248 | struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; |
246 | struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; | 249 | struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; |
247 | struct be_ctrl_info *ctrl = &phba->ctrl; | 250 | struct be_ctrl_info *ctrl = &phba->ctrl; |
248 | struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); | 251 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); |
249 | struct tcp_connect_and_offload_in *req = embedded_payload(wrb); | 252 | struct tcp_connect_and_offload_in *req = embedded_payload(wrb); |
250 | unsigned short def_hdr_id; | 253 | unsigned short def_hdr_id; |
251 | unsigned short def_data_id; | 254 | unsigned short def_data_id; |
252 | struct phys_addr template_address = { 0, 0 }; | 255 | struct phys_addr template_address = { 0, 0 }; |
253 | struct phys_addr *ptemplate_address; | 256 | struct phys_addr *ptemplate_address; |
254 | int status = 0; | 257 | int status = 0; |
258 | unsigned int i; | ||
255 | unsigned short cid = beiscsi_ep->ep_cid; | 259 | unsigned short cid = beiscsi_ep->ep_cid; |
256 | 260 | ||
257 | phwi_ctrlr = phba->phwi_ctrlr; | 261 | phwi_ctrlr = phba->phwi_ctrlr; |
@@ -296,14 +300,18 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
296 | 300 | ||
297 | } | 301 | } |
298 | req->cid = cid; | 302 | req->cid = cid; |
299 | req->cq_id = phwi_context->be_cq.id; | 303 | i = phba->nxt_cqid++; |
304 | if (phba->nxt_cqid == phba->num_cpus) | ||
305 | phba->nxt_cqid = 0; | ||
306 | req->cq_id = phwi_context->be_cq[i].id; | ||
307 | SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d \n", i, req->cq_id); | ||
300 | req->defq_id = def_hdr_id; | 308 | req->defq_id = def_hdr_id; |
301 | req->hdr_ring_id = def_hdr_id; | 309 | req->hdr_ring_id = def_hdr_id; |
302 | req->data_ring_id = def_data_id; | 310 | req->data_ring_id = def_data_id; |
303 | req->do_offload = 1; | 311 | req->do_offload = 1; |
304 | req->dataout_template_pa.lo = ptemplate_address->lo; | 312 | req->dataout_template_pa.lo = ptemplate_address->lo; |
305 | req->dataout_template_pa.hi = ptemplate_address->hi; | 313 | req->dataout_template_pa.hi = ptemplate_address->hi; |
306 | status = be_mbox_notify(ctrl); | 314 | status = be_mcc_notify_wait(phba); |
307 | if (!status) { | 315 | if (!status) { |
308 | struct iscsi_endpoint *ep; | 316 | struct iscsi_endpoint *ep; |
309 | struct tcp_connect_and_offload_out *ptcpcnct_out = | 317 | struct tcp_connect_and_offload_out *ptcpcnct_out = |
@@ -311,7 +319,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
311 | 319 | ||
312 | ep = phba->ep_array[ptcpcnct_out->cid]; | 320 | ep = phba->ep_array[ptcpcnct_out->cid]; |
313 | beiscsi_ep = ep->dd_data; | 321 | beiscsi_ep = ep->dd_data; |
314 | beiscsi_ep->fw_handle = 0; | 322 | beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; |
315 | beiscsi_ep->cid_vld = 1; | 323 | beiscsi_ep->cid_vld = 1; |
316 | SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); | 324 | SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); |
317 | } else | 325 | } else |
@@ -319,3 +327,30 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
319 | spin_unlock(&ctrl->mbox_lock); | 327 | spin_unlock(&ctrl->mbox_lock); |
320 | return status; | 328 | return status; |
321 | } | 329 | } |
330 | |||
331 | int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr) | ||
332 | { | ||
333 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
334 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | ||
335 | struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb); | ||
336 | int status; | ||
337 | |||
338 | SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); | ||
339 | spin_lock(&ctrl->mbox_lock); | ||
340 | memset(wrb, 0, sizeof(*wrb)); | ||
341 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | ||
342 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | ||
343 | OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, | ||
344 | sizeof(*req)); | ||
345 | |||
346 | status = be_mcc_notify_wait(phba); | ||
347 | if (!status) { | ||
348 | struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb); | ||
349 | |||
350 | memcpy(mac_addr, resp->mac_address, ETH_ALEN); | ||
351 | } | ||
352 | |||
353 | spin_unlock(&ctrl->mbox_lock); | ||
354 | return status; | ||
355 | } | ||
356 | |||
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 00e816ee8070..24eaff923f85 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
@@ -175,7 +175,9 @@ struct mgmt_hba_attributes { | |||
175 | u8 phy_port; | 175 | u8 phy_port; |
176 | u32 firmware_post_status; | 176 | u32 firmware_post_status; |
177 | u32 hba_mtu[8]; | 177 | u32 hba_mtu[8]; |
178 | u32 future_u32[4]; | 178 | u8 iscsi_features; |
179 | u8 future_u8[3]; | ||
180 | u32 future_u32[3]; | ||
179 | } __packed; | 181 | } __packed; |
180 | 182 | ||
181 | struct mgmt_controller_attributes { | 183 | struct mgmt_controller_attributes { |
@@ -246,4 +248,8 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
246 | unsigned short cid, | 248 | unsigned short cid, |
247 | unsigned short issue_reset, | 249 | unsigned short issue_reset, |
248 | unsigned short savecfg_flag); | 250 | unsigned short savecfg_flag); |
251 | |||
252 | unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl, | ||
253 | struct beiscsi_hba *phba, | ||
254 | char *buf, unsigned int len); | ||
249 | #endif | 255 | #endif |