aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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