aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>2016-08-19 05:50:12 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-08-23 22:42:43 -0400
commit50a4b824be9e4a01f3b87790865e26b1546fcbb8 (patch)
treea677875c94ddad99dd6a1274bbd21a83ffc7c683
parent9122e991cebb90a7225109ed7627950f485c5f58 (diff)
scsi: be2iscsi: Fix to make boot discovery non-blocking
Boot work involves: 1. Find and fetch configured boot session and its handle. 2. Attempt to open the session if its not. 3. Get the session details for boot kset creation. 4. Logout of that session owned by FW. 5. Create boot kset for session details. All these actions were done in blocking call with retries in global wq. Other works in wq suffered if the IOCTLs stalled or timed out. This change moves all the boot work to make it non-blocking. The work queued in global wq just issues the IOCTL depending on the action to be taken and mcc wq schedules work depending on status of the IOCTL. Initial boot_work is started on link and ASYNC event. The other code changes move all boot related functions in one place and follow naming conventions. Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/be2iscsi/be.h2
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c161
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h18
-rw-r--r--drivers/scsi/be2iscsi/be_main.c608
-rw-r--r--drivers/scsi/be2iscsi/be_main.h33
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c537
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h23
7 files changed, 725 insertions, 657 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 621291ab0214..454002d98bcd 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -113,6 +113,8 @@ struct beiscsi_mcc_tag_state {
113 unsigned long tag_state; 113 unsigned long tag_state;
114#define MCC_TAG_STATE_RUNNING 1 114#define MCC_TAG_STATE_RUNNING 1
115#define MCC_TAG_STATE_TIMEOUT 2 115#define MCC_TAG_STATE_TIMEOUT 2
116#define MCC_TAG_STATE_ASYNC 3
117 void (*cbfn)(struct beiscsi_hba *, unsigned int);
116 struct be_dma_mem tag_mem_state; 118 struct be_dma_mem tag_mem_state;
117}; 119};
118 120
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index f16de6cf2678..27d10cee0c40 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -84,6 +84,7 @@ struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
84 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; 84 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
85 phba->ctrl.mcc_tag_status[tag] = 0; 85 phba->ctrl.mcc_tag_status[tag] = 0;
86 phba->ctrl.ptag_state[tag].tag_state = 0; 86 phba->ctrl.ptag_state[tag].tag_state = 0;
87 phba->ctrl.ptag_state[tag].cbfn = NULL;
87 phba->ctrl.mcc_tag_available--; 88 phba->ctrl.mcc_tag_available--;
88 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1)) 89 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
89 phba->ctrl.mcc_alloc_index = 0; 90 phba->ctrl.mcc_alloc_index = 0;
@@ -128,6 +129,70 @@ void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
128} 129}
129 130
130/* 131/*
132 * beiscsi_mcc_compl_status - Return the status of MCC completion
133 * @phba: Driver private structure
134 * @tag: Tag for the MBX Command
135 * @wrb: the WRB used for the MBX Command
136 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
137 *
138 * return
139 * Success: 0
140 * Failure: Non-Zero
141 */
142int __beiscsi_mcc_compl_status(struct beiscsi_hba *phba,
143 unsigned int tag,
144 struct be_mcc_wrb **wrb,
145 struct be_dma_mem *mbx_cmd_mem)
146{
147 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
148 uint16_t status = 0, addl_status = 0, wrb_num = 0;
149 struct be_cmd_resp_hdr *mbx_resp_hdr;
150 struct be_cmd_req_hdr *mbx_hdr;
151 struct be_mcc_wrb *temp_wrb;
152 uint32_t mcc_tag_status;
153 int rc = 0;
154
155 mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
156 status = (mcc_tag_status & CQE_STATUS_MASK);
157 addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
158 CQE_STATUS_ADDL_SHIFT);
159
160 if (mbx_cmd_mem) {
161 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
162 } else {
163 wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
164 CQE_STATUS_WRB_SHIFT;
165 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
166 mbx_hdr = embedded_payload(temp_wrb);
167
168 if (wrb)
169 *wrb = temp_wrb;
170 }
171
172 if (status || addl_status) {
173 beiscsi_log(phba, KERN_WARNING,
174 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
175 BEISCSI_LOG_CONFIG,
176 "BC_%d : MBX Cmd Failed for Subsys : %d Opcode : %d with Status : %d and Extd_Status : %d\n",
177 mbx_hdr->subsystem, mbx_hdr->opcode,
178 status, addl_status);
179 rc = -EIO;
180 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
181 mbx_resp_hdr = (struct be_cmd_resp_hdr *)mbx_hdr;
182 beiscsi_log(phba, KERN_WARNING,
183 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
184 BEISCSI_LOG_CONFIG,
185 "BC_%d : Insufficient Buffer Error Resp_Len : %d Actual_Resp_Len : %d\n",
186 mbx_resp_hdr->response_length,
187 mbx_resp_hdr->actual_resp_len);
188 rc = -EAGAIN;
189 }
190 }
191
192 return rc;
193}
194
195/*
131 * beiscsi_mccq_compl_wait()- Process completion in MCC CQ 196 * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
132 * @phba: Driver private structure 197 * @phba: Driver private structure
133 * @tag: Tag for the MBX Command 198 * @tag: Tag for the MBX Command
@@ -141,16 +206,11 @@ void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
141 * Failure: Non-Zero 206 * Failure: Non-Zero
142 **/ 207 **/
143int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, 208int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
144 uint32_t tag, struct be_mcc_wrb **wrb, 209 unsigned int tag,
210 struct be_mcc_wrb **wrb,
145 struct be_dma_mem *mbx_cmd_mem) 211 struct be_dma_mem *mbx_cmd_mem)
146{ 212{
147 int rc = 0; 213 int rc = 0;
148 uint32_t mcc_tag_status;
149 uint16_t status = 0, addl_status = 0, wrb_num = 0;
150 struct be_mcc_wrb *temp_wrb;
151 struct be_cmd_req_hdr *mbx_hdr;
152 struct be_cmd_resp_hdr *mbx_resp_hdr;
153 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
154 214
155 if (beiscsi_hba_in_error(phba)) { 215 if (beiscsi_hba_in_error(phba)) {
156 clear_bit(MCC_TAG_STATE_RUNNING, 216 clear_bit(MCC_TAG_STATE_RUNNING,
@@ -159,11 +219,11 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
159 } 219 }
160 220
161 /* wait for the mccq completion */ 221 /* wait for the mccq completion */
162 rc = wait_event_interruptible_timeout( 222 rc = wait_event_interruptible_timeout(phba->ctrl.mcc_wait[tag],
163 phba->ctrl.mcc_wait[tag], 223 phba->ctrl.mcc_tag_status[tag],
164 phba->ctrl.mcc_tag_status[tag], 224 msecs_to_jiffies(
165 msecs_to_jiffies( 225 BEISCSI_HOST_MBX_TIMEOUT));
166 BEISCSI_HOST_MBX_TIMEOUT)); 226
167 /** 227 /**
168 * If MBOX cmd timeout expired, tag and resource allocated 228 * If MBOX cmd timeout expired, tag and resource allocated
169 * for cmd is not freed until FW returns completion. 229 * for cmd is not freed until FW returns completion.
@@ -197,47 +257,7 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
197 return -EBUSY; 257 return -EBUSY;
198 } 258 }
199 259
200 rc = 0; 260 rc = __beiscsi_mcc_compl_status(phba, tag, wrb, mbx_cmd_mem);
201 mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
202 status = (mcc_tag_status & CQE_STATUS_MASK);
203 addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
204 CQE_STATUS_ADDL_SHIFT);
205
206 if (mbx_cmd_mem) {
207 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
208 } else {
209 wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
210 CQE_STATUS_WRB_SHIFT;
211 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
212 mbx_hdr = embedded_payload(temp_wrb);
213
214 if (wrb)
215 *wrb = temp_wrb;
216 }
217
218 if (status || addl_status) {
219 beiscsi_log(phba, KERN_WARNING,
220 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
221 BEISCSI_LOG_CONFIG,
222 "BC_%d : MBX Cmd Failed for "
223 "Subsys : %d Opcode : %d with "
224 "Status : %d and Extd_Status : %d\n",
225 mbx_hdr->subsystem,
226 mbx_hdr->opcode,
227 status, addl_status);
228 rc = -EIO;
229 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
230 mbx_resp_hdr = (struct be_cmd_resp_hdr *) mbx_hdr;
231 beiscsi_log(phba, KERN_WARNING,
232 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
233 BEISCSI_LOG_CONFIG,
234 "BC_%d : Insufficient Buffer Error "
235 "Resp_Len : %d Actual_Resp_Len : %d\n",
236 mbx_resp_hdr->response_length,
237 mbx_resp_hdr->actual_resp_len);
238 rc = -EAGAIN;
239 }
240 }
241 261
242 free_mcc_wrb(&phba->ctrl, tag); 262 free_mcc_wrb(&phba->ctrl, tag);
243 return rc; 263 return rc;
@@ -318,11 +338,9 @@ static void beiscsi_process_async_link(struct beiscsi_hba *phba,
318 * This has been newly introduced in SKH-R Firmware 10.0.338.45. 338 * This has been newly introduced in SKH-R Firmware 10.0.338.45.
319 **/ 339 **/
320 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) { 340 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
321 phba->get_boot = BE_GET_BOOT_RETRIES; 341 set_bit(BEISCSI_HBA_LINK_UP, &phba->state);
322 /* first this needs to be visible to worker thread */ 342 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
323 wmb(); 343 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
324 set_bit(BEISCSI_HBA_LINK_UP | BEISCSI_HBA_BOOT_FOUND,
325 &phba->state);
326 __beiscsi_log(phba, KERN_ERR, 344 __beiscsi_log(phba, KERN_ERR,
327 "BC_%d : Link Up on Port %d tag 0x%x\n", 345 "BC_%d : Link Up on Port %d tag 0x%x\n",
328 evt->physical_port, evt->event_tag); 346 evt->physical_port, evt->event_tag);
@@ -412,10 +430,8 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
412 beiscsi_process_async_link(phba, compl); 430 beiscsi_process_async_link(phba, compl);
413 break; 431 break;
414 case ASYNC_EVENT_CODE_ISCSI: 432 case ASYNC_EVENT_CODE_ISCSI:
415 phba->get_boot = BE_GET_BOOT_RETRIES; 433 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
416 /* first this needs to be visible to worker thread */ 434 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
417 wmb();
418 set_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state);
419 sev = KERN_ERR; 435 sev = KERN_ERR;
420 break; 436 break;
421 case ASYNC_EVENT_CODE_SLI: 437 case ASYNC_EVENT_CODE_SLI:
@@ -451,6 +467,9 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
451 return 0; 467 return 0;
452 } 468 }
453 469
470 /* end MCC with this tag */
471 clear_bit(MCC_TAG_STATE_RUNNING, &ctrl->ptag_state[tag].tag_state);
472
454 if (test_bit(MCC_TAG_STATE_TIMEOUT, &ctrl->ptag_state[tag].tag_state)) { 473 if (test_bit(MCC_TAG_STATE_TIMEOUT, &ctrl->ptag_state[tag].tag_state)) {
455 beiscsi_log(phba, KERN_WARNING, 474 beiscsi_log(phba, KERN_WARNING,
456 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT | 475 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
@@ -461,9 +480,11 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
461 * Only for non-embedded cmd, PCI resource is allocated. 480 * Only for non-embedded cmd, PCI resource is allocated.
462 **/ 481 **/
463 tag_mem = &ctrl->ptag_state[tag].tag_mem_state; 482 tag_mem = &ctrl->ptag_state[tag].tag_mem_state;
464 if (tag_mem->size) 483 if (tag_mem->size) {
465 pci_free_consistent(ctrl->pdev, tag_mem->size, 484 pci_free_consistent(ctrl->pdev, tag_mem->size,
466 tag_mem->va, tag_mem->dma); 485 tag_mem->va, tag_mem->dma);
486 tag_mem->size = 0;
487 }
467 free_mcc_wrb(ctrl, tag); 488 free_mcc_wrb(ctrl, tag);
468 return 0; 489 return 0;
469 } 490 }
@@ -482,8 +503,18 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
482 CQE_STATUS_ADDL_MASK; 503 CQE_STATUS_ADDL_MASK;
483 ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK); 504 ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK);
484 505
485 /* write ordering forced in wake_up_interruptible */ 506 if (test_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state)) {
486 clear_bit(MCC_TAG_STATE_RUNNING, &ctrl->ptag_state[tag].tag_state); 507 if (ctrl->ptag_state[tag].cbfn)
508 ctrl->ptag_state[tag].cbfn(phba, tag);
509 else
510 beiscsi_log(phba, KERN_ERR,
511 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
512 BEISCSI_LOG_CONFIG,
513 "BC_%d : MBX ASYNC command with no callback\n");
514 free_mcc_wrb(ctrl, tag);
515 return 0;
516 }
517
487 wake_up_interruptible(&ctrl->mcc_wait[tag]); 518 wake_up_interruptible(&ctrl->mcc_wait[tag]);
488 return 0; 519 return 0;
489} 520}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index c50b74afd00a..0510b6767341 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -345,8 +345,8 @@ struct be_cmd_req_logout_fw_sess {
345 345
346struct be_cmd_resp_logout_fw_sess { 346struct be_cmd_resp_logout_fw_sess {
347 struct be_cmd_resp_hdr hdr; /* dw[4] */ 347 struct be_cmd_resp_hdr hdr; /* dw[4] */
348#define BEISCSI_MGMT_SESSION_CLOSE 0x20
349 uint32_t session_status; 348 uint32_t session_status;
349#define BE_SESS_STATUS_CLOSE 0x20
350} __packed; 350} __packed;
351 351
352struct mgmt_conn_login_options { 352struct mgmt_conn_login_options {
@@ -438,8 +438,13 @@ struct be_cmd_get_boot_target_req {
438 438
439struct be_cmd_get_boot_target_resp { 439struct be_cmd_get_boot_target_resp {
440 struct be_cmd_resp_hdr hdr; 440 struct be_cmd_resp_hdr hdr;
441 u32 boot_session_count; 441 u32 boot_session_count;
442 int boot_session_handle; 442 u32 boot_session_handle;
443/**
444 * FW returns 0xffffffff if it couldn't establish connection with
445 * configured boot target.
446 */
447#define BE_BOOT_INVALID_SHANDLE 0xffffffff
443}; 448};
444 449
445struct be_cmd_reopen_session_req { 450struct be_cmd_reopen_session_req {
@@ -741,8 +746,13 @@ void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag);
741int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *, 746int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *,
742 int num); 747 int num);
743int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, 748int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
744 uint32_t tag, struct be_mcc_wrb **wrb, 749 unsigned int tag,
750 struct be_mcc_wrb **wrb,
745 struct be_dma_mem *mbx_cmd_mem); 751 struct be_dma_mem *mbx_cmd_mem);
752int __beiscsi_mcc_compl_status(struct beiscsi_hba *phba,
753 unsigned int tag,
754 struct be_mcc_wrb **wrb,
755 struct be_dma_mem *mbx_cmd_mem);
746/*ISCSI Functuions */ 756/*ISCSI Functuions */
747int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); 757int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
748int be_cmd_fw_uninit(struct be_ctrl_info *ctrl); 758int be_cmd_fw_uninit(struct be_ctrl_info *ctrl);
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 22fcbea6894d..eb4ce17a683d 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -374,152 +374,6 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
374 return iscsi_eh_device_reset(sc); 374 return iscsi_eh_device_reset(sc);
375} 375}
376 376
377static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
378{
379 struct beiscsi_hba *phba = data;
380 struct mgmt_session_info *boot_sess = &phba->boot_sess;
381 struct mgmt_conn_info *boot_conn = &boot_sess->conn_list[0];
382 char *str = buf;
383 int rc = -EPERM;
384
385 switch (type) {
386 case ISCSI_BOOT_TGT_NAME:
387 rc = sprintf(buf, "%.*s\n",
388 (int)strlen(boot_sess->target_name),
389 (char *)&boot_sess->target_name);
390 break;
391 case ISCSI_BOOT_TGT_IP_ADDR:
392 if (boot_conn->dest_ipaddr.ip_type == BEISCSI_IP_TYPE_V4)
393 rc = sprintf(buf, "%pI4\n",
394 (char *)&boot_conn->dest_ipaddr.addr);
395 else
396 rc = sprintf(str, "%pI6\n",
397 (char *)&boot_conn->dest_ipaddr.addr);
398 break;
399 case ISCSI_BOOT_TGT_PORT:
400 rc = sprintf(str, "%d\n", boot_conn->dest_port);
401 break;
402
403 case ISCSI_BOOT_TGT_CHAP_NAME:
404 rc = sprintf(str, "%.*s\n",
405 boot_conn->negotiated_login_options.auth_data.chap.
406 target_chap_name_length,
407 (char *)&boot_conn->negotiated_login_options.
408 auth_data.chap.target_chap_name);
409 break;
410 case ISCSI_BOOT_TGT_CHAP_SECRET:
411 rc = sprintf(str, "%.*s\n",
412 boot_conn->negotiated_login_options.auth_data.chap.
413 target_secret_length,
414 (char *)&boot_conn->negotiated_login_options.
415 auth_data.chap.target_secret);
416 break;
417 case ISCSI_BOOT_TGT_REV_CHAP_NAME:
418 rc = sprintf(str, "%.*s\n",
419 boot_conn->negotiated_login_options.auth_data.chap.
420 intr_chap_name_length,
421 (char *)&boot_conn->negotiated_login_options.
422 auth_data.chap.intr_chap_name);
423 break;
424 case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
425 rc = sprintf(str, "%.*s\n",
426 boot_conn->negotiated_login_options.auth_data.chap.
427 intr_secret_length,
428 (char *)&boot_conn->negotiated_login_options.
429 auth_data.chap.intr_secret);
430 break;
431 case ISCSI_BOOT_TGT_FLAGS:
432 rc = sprintf(str, "2\n");
433 break;
434 case ISCSI_BOOT_TGT_NIC_ASSOC:
435 rc = sprintf(str, "0\n");
436 break;
437 }
438 return rc;
439}
440
441static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
442{
443 struct beiscsi_hba *phba = data;
444 char *str = buf;
445 int rc = -EPERM;
446
447 switch (type) {
448 case ISCSI_BOOT_INI_INITIATOR_NAME:
449 rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname);
450 break;
451 }
452 return rc;
453}
454
455static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
456{
457 struct beiscsi_hba *phba = data;
458 char *str = buf;
459 int rc = -EPERM;
460
461 switch (type) {
462 case ISCSI_BOOT_ETH_FLAGS:
463 rc = sprintf(str, "2\n");
464 break;
465 case ISCSI_BOOT_ETH_INDEX:
466 rc = sprintf(str, "0\n");
467 break;
468 case ISCSI_BOOT_ETH_MAC:
469 rc = beiscsi_get_macaddr(str, phba);
470 break;
471 }
472 return rc;
473}
474
475
476static umode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
477{
478 umode_t rc = 0;
479
480 switch (type) {
481 case ISCSI_BOOT_TGT_NAME:
482 case ISCSI_BOOT_TGT_IP_ADDR:
483 case ISCSI_BOOT_TGT_PORT:
484 case ISCSI_BOOT_TGT_CHAP_NAME:
485 case ISCSI_BOOT_TGT_CHAP_SECRET:
486 case ISCSI_BOOT_TGT_REV_CHAP_NAME:
487 case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
488 case ISCSI_BOOT_TGT_NIC_ASSOC:
489 case ISCSI_BOOT_TGT_FLAGS:
490 rc = S_IRUGO;
491 break;
492 }
493 return rc;
494}
495
496static umode_t beiscsi_ini_get_attr_visibility(void *data, int type)
497{
498 umode_t rc = 0;
499
500 switch (type) {
501 case ISCSI_BOOT_INI_INITIATOR_NAME:
502 rc = S_IRUGO;
503 break;
504 }
505 return rc;
506}
507
508
509static umode_t beiscsi_eth_get_attr_visibility(void *data, int type)
510{
511 umode_t rc = 0;
512
513 switch (type) {
514 case ISCSI_BOOT_ETH_FLAGS:
515 case ISCSI_BOOT_ETH_MAC:
516 case ISCSI_BOOT_ETH_INDEX:
517 rc = S_IRUGO;
518 break;
519 }
520 return rc;
521}
522
523/*------------------- PCI Driver operations and data ----------------- */ 377/*------------------- PCI Driver operations and data ----------------- */
524static const struct pci_device_id beiscsi_pci_id_table[] = { 378static const struct pci_device_id beiscsi_pci_id_table[] = {
525 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, 379 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -4312,149 +4166,6 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
4312 "BM_%d : In hwi_disable_intr, Already Disabled\n"); 4166 "BM_%d : In hwi_disable_intr, Already Disabled\n");
4313} 4167}
4314 4168
4315/**
4316 * beiscsi_get_boot_info()- Get the boot session info
4317 * @phba: The device priv structure instance
4318 *
4319 * Get the boot target info and store in driver priv structure
4320 *
4321 * return values
4322 * Success: 0
4323 * Failure: Non-Zero Value
4324 **/
4325static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
4326{
4327 struct be_cmd_get_session_resp *session_resp;
4328 struct be_dma_mem nonemb_cmd;
4329 unsigned int tag;
4330 unsigned int s_handle;
4331 int ret = -ENOMEM;
4332
4333 /* Get the session handle of the boot target */
4334 ret = be_mgmt_get_boot_shandle(phba, &s_handle);
4335 if (ret) {
4336 beiscsi_log(phba, KERN_ERR,
4337 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
4338 "BM_%d : No boot session\n");
4339
4340 if (ret == -ENXIO)
4341 phba->get_boot = 0;
4342
4343
4344 return ret;
4345 }
4346 phba->get_boot = 0;
4347 nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
4348 sizeof(*session_resp),
4349 &nonemb_cmd.dma);
4350 if (nonemb_cmd.va == NULL) {
4351 beiscsi_log(phba, KERN_ERR,
4352 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
4353 "BM_%d : Failed to allocate memory for"
4354 "beiscsi_get_session_info\n");
4355
4356 return -ENOMEM;
4357 }
4358
4359 tag = mgmt_get_session_info(phba, s_handle,
4360 &nonemb_cmd);
4361 if (!tag) {
4362 beiscsi_log(phba, KERN_ERR,
4363 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
4364 "BM_%d : beiscsi_get_session_info"
4365 " Failed\n");
4366
4367 goto boot_freemem;
4368 }
4369
4370 ret = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
4371 if (ret) {
4372 beiscsi_log(phba, KERN_ERR,
4373 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
4374 "BM_%d : beiscsi_get_session_info Failed");
4375
4376 if (ret != -EBUSY)
4377 goto boot_freemem;
4378 else
4379 return ret;
4380 }
4381
4382 session_resp = nonemb_cmd.va ;
4383
4384 memcpy(&phba->boot_sess, &session_resp->session_info,
4385 sizeof(struct mgmt_session_info));
4386
4387 beiscsi_logout_fw_sess(phba,
4388 phba->boot_sess.session_handle);
4389 ret = 0;
4390
4391boot_freemem:
4392 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
4393 nonemb_cmd.va, nonemb_cmd.dma);
4394 return ret;
4395}
4396
4397static void beiscsi_boot_release(void *data)
4398{
4399 struct beiscsi_hba *phba = data;
4400
4401 scsi_host_put(phba->shost);
4402}
4403
4404static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
4405{
4406 struct iscsi_boot_kobj *boot_kobj;
4407
4408 /* it has been created previously */
4409 if (phba->boot_kset)
4410 return 0;
4411
4412 /* get boot info using mgmt cmd */
4413 if (beiscsi_get_boot_info(phba))
4414 /* Try to see if we can carry on without this */
4415 return 0;
4416
4417 phba->boot_kset = iscsi_boot_create_host_kset(phba->shost->host_no);
4418 if (!phba->boot_kset)
4419 return -ENOMEM;
4420
4421 /* get a ref because the show function will ref the phba */
4422 if (!scsi_host_get(phba->shost))
4423 goto free_kset;
4424 boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
4425 beiscsi_show_boot_tgt_info,
4426 beiscsi_tgt_get_attr_visibility,
4427 beiscsi_boot_release);
4428 if (!boot_kobj)
4429 goto put_shost;
4430
4431 if (!scsi_host_get(phba->shost))
4432 goto free_kset;
4433 boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
4434 beiscsi_show_boot_ini_info,
4435 beiscsi_ini_get_attr_visibility,
4436 beiscsi_boot_release);
4437 if (!boot_kobj)
4438 goto put_shost;
4439
4440 if (!scsi_host_get(phba->shost))
4441 goto free_kset;
4442 boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
4443 beiscsi_show_boot_eth_info,
4444 beiscsi_eth_get_attr_visibility,
4445 beiscsi_boot_release);
4446 if (!boot_kobj)
4447 goto put_shost;
4448 return 0;
4449
4450put_shost:
4451 scsi_host_put(phba->shost);
4452free_kset:
4453 iscsi_boot_destroy_kset(phba->boot_kset);
4454 phba->boot_kset = NULL;
4455 return -ENOMEM;
4456}
4457
4458static int beiscsi_init_port(struct beiscsi_hba *phba) 4169static int beiscsi_init_port(struct beiscsi_hba *phba)
4459{ 4170{
4460 int ret; 4171 int ret;
@@ -5289,6 +5000,7 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba)
5289 free_irq(phba->pcidev->irq, phba); 5000 free_irq(phba->pcidev->irq, phba);
5290 pci_disable_msix(phba->pcidev); 5001 pci_disable_msix(phba->pcidev);
5291 cancel_delayed_work_sync(&phba->beiscsi_hw_check_task); 5002 cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
5003 cancel_work_sync(&phba->boot_work);
5292 5004
5293 for (i = 0; i < phba->num_cpus; i++) { 5005 for (i = 0; i < phba->num_cpus; i++) {
5294 pbe_eq = &phwi_context->be_eq[i]; 5006 pbe_eq = &phwi_context->be_eq[i];
@@ -5325,9 +5037,10 @@ static void beiscsi_remove(struct pci_dev *pcidev)
5325 5037
5326 clear_bit(BEISCSI_HBA_RUNNING, &phba->state); 5038 clear_bit(BEISCSI_HBA_RUNNING, &phba->state);
5327 beiscsi_iface_destroy_default(phba); 5039 beiscsi_iface_destroy_default(phba);
5328 iscsi_boot_destroy_kset(phba->boot_kset);
5329 iscsi_host_remove(phba->shost); 5040 iscsi_host_remove(phba->shost);
5330 beiscsi_quiesce(phba); 5041 beiscsi_quiesce(phba);
5042 /* after cancelling boot_work */
5043 iscsi_boot_destroy_kset(phba->boot_struct.boot_kset);
5331 pci_dev_put(phba->pcidev); 5044 pci_dev_put(phba->pcidev);
5332 iscsi_host_free(phba->shost); 5045 iscsi_host_free(phba->shost);
5333 pci_disable_pcie_error_reporting(pcidev); 5046 pci_disable_pcie_error_reporting(pcidev);
@@ -5351,6 +5064,281 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
5351 return; 5064 return;
5352} 5065}
5353 5066
5067void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle)
5068{
5069 if (phba->boot_struct.boot_kset)
5070 return;
5071
5072 /* skip if boot work is already in progress */
5073 if (test_and_set_bit(BEISCSI_HBA_BOOT_WORK, &phba->state))
5074 return;
5075
5076 phba->boot_struct.retry = 3;
5077 phba->boot_struct.tag = 0;
5078 phba->boot_struct.s_handle = s_handle;
5079 phba->boot_struct.action = BEISCSI_BOOT_GET_SHANDLE;
5080 schedule_work(&phba->boot_work);
5081}
5082
5083static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
5084{
5085 struct beiscsi_hba *phba = data;
5086 struct mgmt_session_info *boot_sess = &phba->boot_struct.boot_sess;
5087 struct mgmt_conn_info *boot_conn = &boot_sess->conn_list[0];
5088 char *str = buf;
5089 int rc = -EPERM;
5090
5091 switch (type) {
5092 case ISCSI_BOOT_TGT_NAME:
5093 rc = sprintf(buf, "%.*s\n",
5094 (int)strlen(boot_sess->target_name),
5095 (char *)&boot_sess->target_name);
5096 break;
5097 case ISCSI_BOOT_TGT_IP_ADDR:
5098 if (boot_conn->dest_ipaddr.ip_type == BEISCSI_IP_TYPE_V4)
5099 rc = sprintf(buf, "%pI4\n",
5100 (char *)&boot_conn->dest_ipaddr.addr);
5101 else
5102 rc = sprintf(str, "%pI6\n",
5103 (char *)&boot_conn->dest_ipaddr.addr);
5104 break;
5105 case ISCSI_BOOT_TGT_PORT:
5106 rc = sprintf(str, "%d\n", boot_conn->dest_port);
5107 break;
5108
5109 case ISCSI_BOOT_TGT_CHAP_NAME:
5110 rc = sprintf(str, "%.*s\n",
5111 boot_conn->negotiated_login_options.auth_data.chap.
5112 target_chap_name_length,
5113 (char *)&boot_conn->negotiated_login_options.
5114 auth_data.chap.target_chap_name);
5115 break;
5116 case ISCSI_BOOT_TGT_CHAP_SECRET:
5117 rc = sprintf(str, "%.*s\n",
5118 boot_conn->negotiated_login_options.auth_data.chap.
5119 target_secret_length,
5120 (char *)&boot_conn->negotiated_login_options.
5121 auth_data.chap.target_secret);
5122 break;
5123 case ISCSI_BOOT_TGT_REV_CHAP_NAME:
5124 rc = sprintf(str, "%.*s\n",
5125 boot_conn->negotiated_login_options.auth_data.chap.
5126 intr_chap_name_length,
5127 (char *)&boot_conn->negotiated_login_options.
5128 auth_data.chap.intr_chap_name);
5129 break;
5130 case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
5131 rc = sprintf(str, "%.*s\n",
5132 boot_conn->negotiated_login_options.auth_data.chap.
5133 intr_secret_length,
5134 (char *)&boot_conn->negotiated_login_options.
5135 auth_data.chap.intr_secret);
5136 break;
5137 case ISCSI_BOOT_TGT_FLAGS:
5138 rc = sprintf(str, "2\n");
5139 break;
5140 case ISCSI_BOOT_TGT_NIC_ASSOC:
5141 rc = sprintf(str, "0\n");
5142 break;
5143 }
5144 return rc;
5145}
5146
5147static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
5148{
5149 struct beiscsi_hba *phba = data;
5150 char *str = buf;
5151 int rc = -EPERM;
5152
5153 switch (type) {
5154 case ISCSI_BOOT_INI_INITIATOR_NAME:
5155 rc = sprintf(str, "%s\n",
5156 phba->boot_struct.boot_sess.initiator_iscsiname);
5157 break;
5158 }
5159 return rc;
5160}
5161
5162static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
5163{
5164 struct beiscsi_hba *phba = data;
5165 char *str = buf;
5166 int rc = -EPERM;
5167
5168 switch (type) {
5169 case ISCSI_BOOT_ETH_FLAGS:
5170 rc = sprintf(str, "2\n");
5171 break;
5172 case ISCSI_BOOT_ETH_INDEX:
5173 rc = sprintf(str, "0\n");
5174 break;
5175 case ISCSI_BOOT_ETH_MAC:
5176 rc = beiscsi_get_macaddr(str, phba);
5177 break;
5178 }
5179 return rc;
5180}
5181
5182
5183static umode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
5184{
5185 umode_t rc = 0;
5186
5187 switch (type) {
5188 case ISCSI_BOOT_TGT_NAME:
5189 case ISCSI_BOOT_TGT_IP_ADDR:
5190 case ISCSI_BOOT_TGT_PORT:
5191 case ISCSI_BOOT_TGT_CHAP_NAME:
5192 case ISCSI_BOOT_TGT_CHAP_SECRET:
5193 case ISCSI_BOOT_TGT_REV_CHAP_NAME:
5194 case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
5195 case ISCSI_BOOT_TGT_NIC_ASSOC:
5196 case ISCSI_BOOT_TGT_FLAGS:
5197 rc = S_IRUGO;
5198 break;
5199 }
5200 return rc;
5201}
5202
5203static umode_t beiscsi_ini_get_attr_visibility(void *data, int type)
5204{
5205 umode_t rc = 0;
5206
5207 switch (type) {
5208 case ISCSI_BOOT_INI_INITIATOR_NAME:
5209 rc = S_IRUGO;
5210 break;
5211 }
5212 return rc;
5213}
5214
5215
5216static umode_t beiscsi_eth_get_attr_visibility(void *data, int type)
5217{
5218 umode_t rc = 0;
5219
5220 switch (type) {
5221 case ISCSI_BOOT_ETH_FLAGS:
5222 case ISCSI_BOOT_ETH_MAC:
5223 case ISCSI_BOOT_ETH_INDEX:
5224 rc = S_IRUGO;
5225 break;
5226 }
5227 return rc;
5228}
5229
5230static void beiscsi_boot_kobj_release(void *data)
5231{
5232 struct beiscsi_hba *phba = data;
5233
5234 scsi_host_put(phba->shost);
5235}
5236
5237static int beiscsi_boot_create_kset(struct beiscsi_hba *phba)
5238{
5239 struct boot_struct *bs = &phba->boot_struct;
5240 struct iscsi_boot_kobj *boot_kobj;
5241
5242 if (bs->boot_kset) {
5243 __beiscsi_log(phba, KERN_ERR,
5244 "BM_%d: boot_kset already created\n");
5245 return 0;
5246 }
5247
5248 bs->boot_kset = iscsi_boot_create_host_kset(phba->shost->host_no);
5249 if (!bs->boot_kset) {
5250 __beiscsi_log(phba, KERN_ERR,
5251 "BM_%d: boot_kset alloc failed\n");
5252 return -ENOMEM;
5253 }
5254
5255 /* get shost ref because the show function will refer phba */
5256 if (!scsi_host_get(phba->shost))
5257 goto free_kset;
5258
5259 boot_kobj = iscsi_boot_create_target(bs->boot_kset, 0, phba,
5260 beiscsi_show_boot_tgt_info,
5261 beiscsi_tgt_get_attr_visibility,
5262 beiscsi_boot_kobj_release);
5263 if (!boot_kobj)
5264 goto put_shost;
5265
5266 if (!scsi_host_get(phba->shost))
5267 goto free_kset;
5268
5269 boot_kobj = iscsi_boot_create_initiator(bs->boot_kset, 0, phba,
5270 beiscsi_show_boot_ini_info,
5271 beiscsi_ini_get_attr_visibility,
5272 beiscsi_boot_kobj_release);
5273 if (!boot_kobj)
5274 goto put_shost;
5275
5276 if (!scsi_host_get(phba->shost))
5277 goto free_kset;
5278
5279 boot_kobj = iscsi_boot_create_ethernet(bs->boot_kset, 0, phba,
5280 beiscsi_show_boot_eth_info,
5281 beiscsi_eth_get_attr_visibility,
5282 beiscsi_boot_kobj_release);
5283 if (!boot_kobj)
5284 goto put_shost;
5285
5286 return 0;
5287
5288put_shost:
5289 scsi_host_put(phba->shost);
5290free_kset:
5291 iscsi_boot_destroy_kset(bs->boot_kset);
5292 bs->boot_kset = NULL;
5293 return -ENOMEM;
5294}
5295
5296static void beiscsi_boot_work(struct work_struct *work)
5297{
5298 struct beiscsi_hba *phba =
5299 container_of(work, struct beiscsi_hba, boot_work);
5300 struct boot_struct *bs = &phba->boot_struct;
5301 unsigned int tag = 0;
5302
5303 if (beiscsi_hba_in_error(phba))
5304 return;
5305
5306 beiscsi_log(phba, KERN_INFO,
5307 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
5308 "BM_%d : %s action %d\n",
5309 __func__, phba->boot_struct.action);
5310
5311 switch (phba->boot_struct.action) {
5312 case BEISCSI_BOOT_REOPEN_SESS:
5313 tag = beiscsi_boot_reopen_sess(phba);
5314 break;
5315 case BEISCSI_BOOT_GET_SHANDLE:
5316 tag = __beiscsi_boot_get_shandle(phba, 1);
5317 break;
5318 case BEISCSI_BOOT_GET_SINFO:
5319 tag = beiscsi_boot_get_sinfo(phba);
5320 break;
5321 case BEISCSI_BOOT_LOGOUT_SESS:
5322 tag = beiscsi_boot_logout_sess(phba);
5323 break;
5324 case BEISCSI_BOOT_CREATE_KSET:
5325 beiscsi_boot_create_kset(phba);
5326 /**
5327 * updated boot_kset is made visible to all before
5328 * ending the boot work.
5329 */
5330 mb();
5331 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
5332 return;
5333 }
5334 if (!tag) {
5335 if (bs->retry--)
5336 schedule_work(&phba->boot_work);
5337 else
5338 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
5339 }
5340}
5341
5354static void be_eqd_update(struct beiscsi_hba *phba) 5342static void be_eqd_update(struct beiscsi_hba *phba)
5355{ 5343{
5356 struct be_set_eqd set_eqd[MAX_CPUS]; 5344 struct be_set_eqd set_eqd[MAX_CPUS];
@@ -5405,17 +5393,6 @@ static void be_eqd_update(struct beiscsi_hba *phba)
5405 } 5393 }
5406} 5394}
5407 5395
5408static void be_check_boot_session(struct beiscsi_hba *phba)
5409{
5410 if (beiscsi_hba_in_error(phba))
5411 return;
5412
5413 if (beiscsi_setup_boot_info(phba))
5414 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5415 "BM_%d : Could not set up "
5416 "iSCSI boot info on async event.\n");
5417}
5418
5419/* 5396/*
5420 * beiscsi_hw_health_check()- Check adapter health 5397 * beiscsi_hw_health_check()- Check adapter health
5421 * @work: work item to check HW health 5398 * @work: work item to check HW health
@@ -5431,17 +5408,6 @@ beiscsi_hw_health_check(struct work_struct *work)
5431 5408
5432 be_eqd_update(phba); 5409 be_eqd_update(phba);
5433 5410
5434 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state)) {
5435 if ((phba->get_boot > 0) && (!phba->boot_kset)) {
5436 phba->get_boot--;
5437 if (!(phba->get_boot % BE_GET_BOOT_TO))
5438 be_check_boot_session(phba);
5439 } else {
5440 clear_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state);
5441 phba->get_boot = 0;
5442 }
5443 }
5444
5445 beiscsi_ue_detect(phba); 5411 beiscsi_ue_detect(phba);
5446 5412
5447 schedule_delayed_work(&phba->beiscsi_hw_check_task, 5413 schedule_delayed_work(&phba->beiscsi_hw_check_task,
@@ -5607,6 +5573,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5607 struct hwi_controller *phwi_ctrlr; 5573 struct hwi_controller *phwi_ctrlr;
5608 struct hwi_context_memory *phwi_context; 5574 struct hwi_context_memory *phwi_context;
5609 struct be_eq_obj *pbe_eq; 5575 struct be_eq_obj *pbe_eq;
5576 unsigned int s_handle;
5610 int ret = 0, i; 5577 int ret = 0, i;
5611 5578
5612 ret = beiscsi_enable_pci(pcidev); 5579 ret = beiscsi_enable_pci(pcidev);
@@ -5769,14 +5736,17 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5769 if (iscsi_host_add(phba->shost, &phba->pcidev->dev)) 5736 if (iscsi_host_add(phba->shost, &phba->pcidev->dev))
5770 goto free_blkenbld; 5737 goto free_blkenbld;
5771 5738
5772 if (beiscsi_setup_boot_info(phba)) 5739 INIT_WORK(&phba->boot_work, beiscsi_boot_work);
5773 /* 5740 ret = beiscsi_boot_get_shandle(phba, &s_handle);
5774 * log error but continue, because we may not be using 5741 if (ret > 0) {
5775 * iscsi boot. 5742 beiscsi_start_boot_work(phba, s_handle);
5743 /**
5744 * Set this bit after starting the work to let
5745 * probe handle it first.
5746 * ASYNC event can too schedule this work.
5776 */ 5747 */
5777 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5748 set_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state);
5778 "BM_%d : Could not set up " 5749 }
5779 "iSCSI boot info.\n");
5780 5750
5781 beiscsi_iface_create_default(phba); 5751 beiscsi_iface_create_default(phba);
5782 schedule_delayed_work(&phba->beiscsi_hw_check_task, 5752 schedule_delayed_work(&phba->beiscsi_hw_check_task,
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 8ab16516ae9a..780c3fc16ec6 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -96,11 +96,6 @@
96#define MAX_CMD_SZ 65536 96#define MAX_CMD_SZ 65536
97#define IIOC_SCSI_DATA 0x05 /* Write Operation */ 97#define IIOC_SCSI_DATA 0x05 /* Write Operation */
98 98
99#define INVALID_SESS_HANDLE 0xFFFFFFFF
100
101#define BE_GET_BOOT_RETRIES 45
102#define BE_GET_BOOT_TO 20
103
104/** 99/**
105 * hardware needs the async PDU buffers to be posted in multiples of 8 100 * hardware needs the async PDU buffers to be posted in multiples of 8
106 * So have atleast 8 of them by default 101 * So have atleast 8 of them by default
@@ -378,7 +373,6 @@ struct beiscsi_hba {
378 struct ulp_cid_info *cid_array_info[BEISCSI_ULP_COUNT]; 373 struct ulp_cid_info *cid_array_info[BEISCSI_ULP_COUNT];
379 struct iscsi_endpoint **ep_array; 374 struct iscsi_endpoint **ep_array;
380 struct beiscsi_conn **conn_table; 375 struct beiscsi_conn **conn_table;
381 struct iscsi_boot_kset *boot_kset;
382 struct Scsi_Host *shost; 376 struct Scsi_Host *shost;
383 struct iscsi_iface *ipv4_iface; 377 struct iscsi_iface *ipv4_iface;
384 struct iscsi_iface *ipv6_iface; 378 struct iscsi_iface *ipv6_iface;
@@ -410,16 +404,16 @@ struct beiscsi_hba {
410#define BEISCSI_HBA_RUNNING 0 404#define BEISCSI_HBA_RUNNING 0
411#define BEISCSI_HBA_LINK_UP 1 405#define BEISCSI_HBA_LINK_UP 1
412#define BEISCSI_HBA_BOOT_FOUND 2 406#define BEISCSI_HBA_BOOT_FOUND 2
413#define BEISCSI_HBA_PCI_ERR 3 407#define BEISCSI_HBA_BOOT_WORK 3
414#define BEISCSI_HBA_FW_TIMEOUT 4 408#define BEISCSI_HBA_PCI_ERR 4
415#define BEISCSI_HBA_IN_UE 5 409#define BEISCSI_HBA_FW_TIMEOUT 5
410#define BEISCSI_HBA_IN_UE 6
416/* error bits */ 411/* error bits */
417#define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \ 412#define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \
418 (1 << BEISCSI_HBA_FW_TIMEOUT) | \ 413 (1 << BEISCSI_HBA_FW_TIMEOUT) | \
419 (1 << BEISCSI_HBA_IN_UE)) 414 (1 << BEISCSI_HBA_IN_UE))
420 415
421 u8 optic_state; 416 u8 optic_state;
422 int get_boot;
423 struct delayed_work beiscsi_hw_check_task; 417 struct delayed_work beiscsi_hw_check_task;
424 418
425 bool mac_addr_set; 419 bool mac_addr_set;
@@ -432,7 +426,6 @@ struct beiscsi_hba {
432 struct be_ctrl_info ctrl; 426 struct be_ctrl_info ctrl;
433 unsigned int generation; 427 unsigned int generation;
434 unsigned int interface_handle; 428 unsigned int interface_handle;
435 struct mgmt_session_info boot_sess;
436 struct invalidate_command_table inv_tbl[128]; 429 struct invalidate_command_table inv_tbl[128];
437 430
438 struct be_aic_obj aic_obj[MAX_CPUS]; 431 struct be_aic_obj aic_obj[MAX_CPUS];
@@ -441,6 +434,22 @@ struct beiscsi_hba {
441 struct scatterlist *sg, 434 struct scatterlist *sg,
442 uint32_t num_sg, uint32_t xferlen, 435 uint32_t num_sg, uint32_t xferlen,
443 uint32_t writedir); 436 uint32_t writedir);
437 struct boot_struct {
438 int retry;
439 unsigned int tag;
440 unsigned int s_handle;
441 struct be_dma_mem nonemb_cmd;
442 enum {
443 BEISCSI_BOOT_REOPEN_SESS = 1,
444 BEISCSI_BOOT_GET_SHANDLE,
445 BEISCSI_BOOT_GET_SINFO,
446 BEISCSI_BOOT_LOGOUT_SESS,
447 BEISCSI_BOOT_CREATE_KSET,
448 } action;
449 struct mgmt_session_info boot_sess;
450 struct iscsi_boot_kset *boot_kset;
451 } boot_struct;
452 struct work_struct boot_work;
444}; 453};
445 454
446#define beiscsi_hba_in_error(phba) ((phba)->state & BEISCSI_HBA_IN_ERR) 455#define beiscsi_hba_in_error(phba) ((phba)->state & BEISCSI_HBA_IN_ERR)
@@ -1066,6 +1075,8 @@ struct hwi_context_memory {
1066 struct hwi_async_pdu_context *pasync_ctx[BEISCSI_ULP_COUNT]; 1075 struct hwi_async_pdu_context *pasync_ctx[BEISCSI_ULP_COUNT];
1067}; 1076};
1068 1077
1078void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle);
1079
1069/* Logging related definitions */ 1080/* Logging related definitions */
1070#define BEISCSI_LOG_INIT 0x0001 /* Initialization events */ 1081#define BEISCSI_LOG_INIT 0x0001 /* Initialization events */
1071#define BEISCSI_LOG_MBOX 0x0002 /* Mailbox Events */ 1082#define BEISCSI_LOG_MBOX 0x0002 /* Mailbox Events */
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 4f2194e324ae..756e7ae33e2c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -187,120 +187,6 @@ int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
187} 187}
188 188
189/** 189/**
190 * mgmt_reopen_session()- Reopen a session based on reopen_type
191 * @phba: Device priv structure instance
192 * @reopen_type: Type of reopen_session FW should do.
193 * @sess_handle: Session Handle of the session to be re-opened
194 *
195 * return
196 * the TAG used for MBOX Command
197 *
198 **/
199unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
200 unsigned int reopen_type,
201 unsigned int sess_handle)
202{
203 struct be_ctrl_info *ctrl = &phba->ctrl;
204 struct be_mcc_wrb *wrb;
205 struct be_cmd_reopen_session_req *req;
206 unsigned int tag;
207
208 beiscsi_log(phba, KERN_INFO,
209 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
210 "BG_%d : In bescsi_get_boot_target\n");
211
212 mutex_lock(&ctrl->mbox_lock);
213 wrb = alloc_mcc_wrb(phba, &tag);
214 if (!wrb) {
215 mutex_unlock(&ctrl->mbox_lock);
216 return 0;
217 }
218
219 req = embedded_payload(wrb);
220 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
221 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
222 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
223 sizeof(struct be_cmd_reopen_session_resp));
224
225 /* set the reopen_type,sess_handle */
226 req->reopen_type = reopen_type;
227 req->session_handle = sess_handle;
228
229 be_mcc_notify(phba, tag);
230 mutex_unlock(&ctrl->mbox_lock);
231 return tag;
232}
233
234unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
235{
236 struct be_ctrl_info *ctrl = &phba->ctrl;
237 struct be_mcc_wrb *wrb;
238 struct be_cmd_get_boot_target_req *req;
239 unsigned int tag;
240
241 beiscsi_log(phba, KERN_INFO,
242 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
243 "BG_%d : In bescsi_get_boot_target\n");
244
245 mutex_lock(&ctrl->mbox_lock);
246 wrb = alloc_mcc_wrb(phba, &tag);
247 if (!wrb) {
248 mutex_unlock(&ctrl->mbox_lock);
249 return 0;
250 }
251
252 req = embedded_payload(wrb);
253 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
254 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
255 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
256 sizeof(struct be_cmd_get_boot_target_resp));
257
258 be_mcc_notify(phba, tag);
259 mutex_unlock(&ctrl->mbox_lock);
260 return tag;
261}
262
263unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
264 u32 boot_session_handle,
265 struct be_dma_mem *nonemb_cmd)
266{
267 struct be_ctrl_info *ctrl = &phba->ctrl;
268 struct be_mcc_wrb *wrb;
269 unsigned int tag;
270 struct be_cmd_get_session_req *req;
271 struct be_cmd_get_session_resp *resp;
272 struct be_sge *sge;
273
274 beiscsi_log(phba, KERN_INFO,
275 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
276 "BG_%d : In beiscsi_get_session_info\n");
277
278 mutex_lock(&ctrl->mbox_lock);
279 wrb = alloc_mcc_wrb(phba, &tag);
280 if (!wrb) {
281 mutex_unlock(&ctrl->mbox_lock);
282 return 0;
283 }
284
285 nonemb_cmd->size = sizeof(*resp);
286 req = nonemb_cmd->va;
287 memset(req, 0, sizeof(*req));
288 sge = nonembedded_sgl(wrb);
289 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
290 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
291 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
292 sizeof(*resp));
293 req->session_handle = boot_session_handle;
294 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
295 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
296 sge->len = cpu_to_le32(nonemb_cmd->size);
297
298 be_mcc_notify(phba, tag);
299 mutex_unlock(&ctrl->mbox_lock);
300 return tag;
301}
302
303/**
304 * mgmt_get_port_name()- Get port name for the function 190 * mgmt_get_port_name()- Get port name for the function
305 * @ctrl: ptr to Ctrl Info 191 * @ctrl: ptr to Ctrl Info
306 * @phba: ptr to the dev priv structure 192 * @phba: ptr to the dev priv structure
@@ -1419,87 +1305,315 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1419 return tag; 1305 return tag;
1420} 1306}
1421 1307
1308static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
1309 unsigned int tag)
1310{
1311 struct be_cmd_get_boot_target_resp *boot_resp;
1312 struct be_cmd_resp_logout_fw_sess *logo_resp;
1313 struct be_cmd_get_session_resp *sess_resp;
1314 struct be_mcc_wrb *wrb;
1315 struct boot_struct *bs;
1316 int boot_work, status;
1317
1318 if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
1319 __beiscsi_log(phba, KERN_ERR,
1320 "BG_%d : %s no boot work %lx\n",
1321 __func__, phba->state);
1322 return;
1323 }
1324
1325 if (phba->boot_struct.tag != tag) {
1326 __beiscsi_log(phba, KERN_ERR,
1327 "BG_%d : %s tag mismatch %d:%d\n",
1328 __func__, tag, phba->boot_struct.tag);
1329 return;
1330 }
1331 bs = &phba->boot_struct;
1332 boot_work = 1;
1333 status = 0;
1334 switch (bs->action) {
1335 case BEISCSI_BOOT_REOPEN_SESS:
1336 status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
1337 if (!status)
1338 bs->action = BEISCSI_BOOT_GET_SHANDLE;
1339 else
1340 bs->retry--;
1341 break;
1342 case BEISCSI_BOOT_GET_SHANDLE:
1343 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
1344 if (!status) {
1345 boot_resp = embedded_payload(wrb);
1346 bs->s_handle = boot_resp->boot_session_handle;
1347 }
1348 if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
1349 bs->action = BEISCSI_BOOT_REOPEN_SESS;
1350 bs->retry--;
1351 } else {
1352 bs->action = BEISCSI_BOOT_GET_SINFO;
1353 }
1354 break;
1355 case BEISCSI_BOOT_GET_SINFO:
1356 status = __beiscsi_mcc_compl_status(phba, tag, NULL,
1357 &bs->nonemb_cmd);
1358 if (!status) {
1359 sess_resp = bs->nonemb_cmd.va;
1360 memcpy(&bs->boot_sess, &sess_resp->session_info,
1361 sizeof(struct mgmt_session_info));
1362 bs->action = BEISCSI_BOOT_LOGOUT_SESS;
1363 } else {
1364 __beiscsi_log(phba, KERN_ERR,
1365 "BG_%d : get boot session info error : 0x%x\n",
1366 status);
1367 boot_work = 0;
1368 }
1369 pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
1370 bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
1371 bs->nonemb_cmd.va = NULL;
1372 break;
1373 case BEISCSI_BOOT_LOGOUT_SESS:
1374 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
1375 if (!status) {
1376 logo_resp = embedded_payload(wrb);
1377 if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
1378 __beiscsi_log(phba, KERN_ERR,
1379 "BG_%d : FW boot session logout error : 0x%x\n",
1380 logo_resp->session_status);
1381 }
1382 }
1383 /* continue to create boot_kset even if logout failed? */
1384 bs->action = BEISCSI_BOOT_CREATE_KSET;
1385 break;
1386 default:
1387 break;
1388 }
1389
1390 /* clear the tag so no other completion matches this tag */
1391 bs->tag = 0;
1392 if (!bs->retry) {
1393 boot_work = 0;
1394 __beiscsi_log(phba, KERN_ERR,
1395 "BG_%d : failed to setup boot target: status %d action %d\n",
1396 status, bs->action);
1397 }
1398 if (!boot_work) {
1399 /* wait for next event to start boot_work */
1400 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
1401 return;
1402 }
1403 schedule_work(&phba->boot_work);
1404}
1405
1422/** 1406/**
1423 * be_mgmt_get_boot_shandle()- Get the session handle 1407 * beiscsi_boot_logout_sess()- Logout from boot FW session
1424 * @phba: device priv structure instance 1408 * @phba: Device priv structure instance
1425 * @s_handle: session handle returned for boot session. 1409 *
1410 * return
1411 * the TAG used for MBOX Command
1426 * 1412 *
1427 * Get the boot target session handle. In case of 1413 */
1428 * crashdump mode driver has to issue and MBX Cmd 1414unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
1429 * for FW to login to boot target 1415{
1416 struct be_ctrl_info *ctrl = &phba->ctrl;
1417 struct be_mcc_wrb *wrb;
1418 struct be_cmd_req_logout_fw_sess *req;
1419 unsigned int tag;
1420
1421 mutex_lock(&ctrl->mbox_lock);
1422 wrb = alloc_mcc_wrb(phba, &tag);
1423 if (!wrb) {
1424 mutex_unlock(&ctrl->mbox_lock);
1425 return 0;
1426 }
1427
1428 req = embedded_payload(wrb);
1429 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1430 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1431 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1432 sizeof(struct be_cmd_req_logout_fw_sess));
1433 /* Use the session handle copied into boot_sess */
1434 req->session_handle = phba->boot_struct.boot_sess.session_handle;
1435
1436 phba->boot_struct.tag = tag;
1437 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1438 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1439
1440 be_mcc_notify(phba, tag);
1441 mutex_unlock(&ctrl->mbox_lock);
1442
1443 return tag;
1444}
1445/**
1446 * beiscsi_boot_reopen_sess()- Reopen boot session
1447 * @phba: Device priv structure instance
1430 * 1448 *
1431 * return 1449 * return
1432 * Success: 0 1450 * the TAG used for MBOX Command
1433 * Failure: Non-Zero value
1434 * 1451 *
1435 **/ 1452 **/
1436int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, 1453unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
1437 unsigned int *s_handle)
1438{ 1454{
1439 struct be_cmd_get_boot_target_resp *boot_resp; 1455 struct be_ctrl_info *ctrl = &phba->ctrl;
1440 struct be_mcc_wrb *wrb; 1456 struct be_mcc_wrb *wrb;
1457 struct be_cmd_reopen_session_req *req;
1441 unsigned int tag; 1458 unsigned int tag;
1442 uint8_t boot_retry = 3;
1443 int rc;
1444 1459
1445 do { 1460 mutex_lock(&ctrl->mbox_lock);
1446 /* Get the Boot Target Session Handle and Count*/ 1461 wrb = alloc_mcc_wrb(phba, &tag);
1447 tag = mgmt_get_boot_target(phba); 1462 if (!wrb) {
1448 if (!tag) { 1463 mutex_unlock(&ctrl->mbox_lock);
1449 beiscsi_log(phba, KERN_ERR, 1464 return 0;
1450 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, 1465 }
1451 "BG_%d : Getting Boot Target Info Failed\n");
1452 return -EAGAIN;
1453 }
1454 1466
1455 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); 1467 req = embedded_payload(wrb);
1456 if (rc) { 1468 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1457 beiscsi_log(phba, KERN_ERR, 1469 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1458 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1470 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
1459 "BG_%d : MBX CMD get_boot_target Failed\n"); 1471 sizeof(struct be_cmd_reopen_session_resp));
1460 return -EBUSY; 1472 req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
1461 } 1473 req->session_handle = BE_BOOT_INVALID_SHANDLE;
1462 1474
1463 boot_resp = embedded_payload(wrb); 1475 phba->boot_struct.tag = tag;
1476 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1477 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1464 1478
1465 /* Check if the there are any Boot targets configured */ 1479 be_mcc_notify(phba, tag);
1466 if (!boot_resp->boot_session_count) { 1480 mutex_unlock(&ctrl->mbox_lock);
1467 beiscsi_log(phba, KERN_INFO, 1481 return tag;
1468 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1482}
1469 "BG_%d ;No boot targets configured\n");
1470 return -ENXIO;
1471 }
1472 1483
1473 /* FW returns the session handle of the boot session */
1474 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1475 *s_handle = boot_resp->boot_session_handle;
1476 return 0;
1477 }
1478 1484
1479 /* Issue MBX Cmd to FW to login to the boot target */ 1485/**
1480 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS, 1486 * beiscsi_boot_get_sinfo()- Get boot session info
1481 INVALID_SESS_HANDLE); 1487 * @phba: device priv structure instance
1482 if (!tag) { 1488 *
1483 beiscsi_log(phba, KERN_ERR, 1489 * Fetches the boot_struct.s_handle info from FW.
1484 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1490 * return
1485 "BG_%d : mgmt_reopen_session Failed\n"); 1491 * the TAG used for MBOX Command
1486 return -EAGAIN; 1492 *
1487 } 1493 **/
1494unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
1495{
1496 struct be_ctrl_info *ctrl = &phba->ctrl;
1497 struct be_cmd_get_session_resp *resp;
1498 struct be_cmd_get_session_req *req;
1499 struct be_dma_mem *nonemb_cmd;
1500 struct be_mcc_wrb *wrb;
1501 struct be_sge *sge;
1502 unsigned int tag;
1488 1503
1489 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 1504 mutex_lock(&ctrl->mbox_lock);
1490 if (rc) { 1505 wrb = alloc_mcc_wrb(phba, &tag);
1491 beiscsi_log(phba, KERN_ERR, 1506 if (!wrb) {
1492 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1507 mutex_unlock(&ctrl->mbox_lock);
1493 "BG_%d : mgmt_reopen_session Failed"); 1508 return 0;
1494 return rc; 1509 }
1495 }
1496 } while (--boot_retry);
1497 1510
1498 /* Couldn't log into the boot target */ 1511 nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1499 beiscsi_log(phba, KERN_ERR, 1512 nonemb_cmd->size = sizeof(*resp);
1500 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1513 nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
1501 "BG_%d : Login to Boot Target Failed\n"); 1514 sizeof(nonemb_cmd->size),
1502 return -ENXIO; 1515 &nonemb_cmd->dma);
1516 if (!nonemb_cmd->va)
1517 return 0;
1518
1519 req = nonemb_cmd->va;
1520 memset(req, 0, sizeof(*req));
1521 sge = nonembedded_sgl(wrb);
1522 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1523 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1524 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1525 sizeof(*resp));
1526 req->session_handle = phba->boot_struct.s_handle;
1527 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1528 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1529 sge->len = cpu_to_le32(nonemb_cmd->size);
1530
1531 phba->boot_struct.tag = tag;
1532 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1533 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1534
1535 be_mcc_notify(phba, tag);
1536 mutex_unlock(&ctrl->mbox_lock);
1537 return tag;
1538}
1539
1540unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1541{
1542 struct be_ctrl_info *ctrl = &phba->ctrl;
1543 struct be_mcc_wrb *wrb;
1544 struct be_cmd_get_boot_target_req *req;
1545 unsigned int tag;
1546
1547 mutex_lock(&ctrl->mbox_lock);
1548 wrb = alloc_mcc_wrb(phba, &tag);
1549 if (!wrb) {
1550 mutex_unlock(&ctrl->mbox_lock);
1551 return 0;
1552 }
1553
1554 req = embedded_payload(wrb);
1555 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1556 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1557 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1558 sizeof(struct be_cmd_get_boot_target_resp));
1559
1560 if (async) {
1561 phba->boot_struct.tag = tag;
1562 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1563 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1564 }
1565
1566 be_mcc_notify(phba, tag);
1567 mutex_unlock(&ctrl->mbox_lock);
1568 return tag;
1569}
1570
1571/**
1572 * beiscsi_boot_get_shandle()- Get boot session handle
1573 * @phba: device priv structure instance
1574 * @s_handle: session handle returned for boot session.
1575 *
1576 * return
1577 * Success: 1
1578 * Failure: negative
1579 *
1580 **/
1581int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1582{
1583 struct be_cmd_get_boot_target_resp *boot_resp;
1584 struct be_mcc_wrb *wrb;
1585 unsigned int tag;
1586 int rc;
1587
1588 *s_handle = BE_BOOT_INVALID_SHANDLE;
1589 /* get configured boot session count and handle */
1590 tag = __beiscsi_boot_get_shandle(phba, 0);
1591 if (!tag) {
1592 beiscsi_log(phba, KERN_ERR,
1593 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1594 "BG_%d : Getting Boot Target Info Failed\n");
1595 return -EAGAIN;
1596 }
1597
1598 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1599 if (rc) {
1600 beiscsi_log(phba, KERN_ERR,
1601 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1602 "BG_%d : MBX CMD get_boot_target Failed\n");
1603 return -EBUSY;
1604 }
1605
1606 boot_resp = embedded_payload(wrb);
1607 /* check if there are any boot targets configured */
1608 if (!boot_resp->boot_session_count) {
1609 __beiscsi_log(phba, KERN_INFO,
1610 "BG_%d : No boot targets configured\n");
1611 return -ENXIO;
1612 }
1613
1614 /* only if FW has logged in to the boot target, s_handle is valid */
1615 *s_handle = boot_resp->boot_session_handle;
1616 return 1;
1503} 1617}
1504 1618
1505/** 1619/**
@@ -1809,70 +1923,3 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1809 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1923 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1810 exp_statsn) / 32] + 1)); 1924 exp_statsn) / 32] + 1));
1811} 1925}
1812
1813/**
1814 * beiscsi_logout_fw_sess()- Firmware Session Logout
1815 * @phba: Device priv structure instance
1816 * @fw_sess_handle: FW session handle
1817 *
1818 * Logout from the FW established sessions.
1819 * returns
1820 * Success: 0
1821 * Failure: Non-Zero Value
1822 *
1823 */
1824int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
1825 uint32_t fw_sess_handle)
1826{
1827 struct be_ctrl_info *ctrl = &phba->ctrl;
1828 struct be_mcc_wrb *wrb;
1829 struct be_cmd_req_logout_fw_sess *req;
1830 struct be_cmd_resp_logout_fw_sess *resp;
1831 unsigned int tag;
1832 int rc;
1833
1834 beiscsi_log(phba, KERN_INFO,
1835 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1836 "BG_%d : In bescsi_logout_fwboot_sess\n");
1837
1838 mutex_lock(&ctrl->mbox_lock);
1839 wrb = alloc_mcc_wrb(phba, &tag);
1840 if (!wrb) {
1841 mutex_unlock(&ctrl->mbox_lock);
1842 beiscsi_log(phba, KERN_INFO,
1843 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1844 "BG_%d : MBX Tag Failure\n");
1845 return -EINVAL;
1846 }
1847
1848 req = embedded_payload(wrb);
1849 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1850 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1851 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1852 sizeof(struct be_cmd_req_logout_fw_sess));
1853
1854 /* Set the session handle */
1855 req->session_handle = fw_sess_handle;
1856 be_mcc_notify(phba, tag);
1857 mutex_unlock(&ctrl->mbox_lock);
1858
1859 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1860 if (rc) {
1861 beiscsi_log(phba, KERN_ERR,
1862 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1863 "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
1864 return -EBUSY;
1865 }
1866
1867 resp = embedded_payload(wrb);
1868 if (resp->session_status !=
1869 BEISCSI_MGMT_SESSION_CLOSE) {
1870 beiscsi_log(phba, KERN_ERR,
1871 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1872 "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
1873 resp->session_status);
1874 rc = -EINVAL;
1875 }
1876
1877 return rc;
1878}
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 294b740805a6..25053483cf28 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -282,16 +282,6 @@ int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type);
282int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type, 282int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
283 u8 *ip, u8 *subnet); 283 u8 *ip, u8 *subnet);
284 284
285unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba);
286
287unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
288 unsigned int reopen_type,
289 unsigned sess_handle);
290
291unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
292 u32 boot_session_handle,
293 struct be_dma_mem *nonemb_cmd);
294
295int mgmt_get_nic_conf(struct beiscsi_hba *phba, 285int mgmt_get_nic_conf(struct beiscsi_hba *phba,
296 struct be_cmd_get_nic_conf_resp *mac); 286 struct be_cmd_get_nic_conf_resp *mac);
297 287
@@ -303,13 +293,20 @@ int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
303 293
304int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw); 294int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw);
305 295
306int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
307 unsigned int *s_handle);
308
309unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba); 296unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba);
310 297
311int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag); 298int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
312 299
300unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba);
301
302unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba);
303
304unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba);
305
306unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async);
307
308int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle);
309
313ssize_t beiscsi_drvr_ver_disp(struct device *dev, 310ssize_t beiscsi_drvr_ver_disp(struct device *dev,
314 struct device_attribute *attr, char *buf); 311 struct device_attribute *attr, char *buf);
315 312