diff options
Diffstat (limited to 'drivers/scsi/be2iscsi/be_iscsi.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index f22918427a2e..95694d3d2089 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -101,6 +101,7 @@ void beiscsi_session_destroy(struct iscsi_cls_session *cls_session) | |||
101 | struct iscsi_session *sess = cls_session->dd_data; | 101 | struct iscsi_session *sess = cls_session->dd_data; |
102 | struct beiscsi_session *beiscsi_sess = sess->dd_data; | 102 | struct beiscsi_session *beiscsi_sess = sess->dd_data; |
103 | 103 | ||
104 | SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n"); | ||
104 | pci_pool_destroy(beiscsi_sess->bhs_pool); | 105 | pci_pool_destroy(beiscsi_sess->bhs_pool); |
105 | iscsi_session_teardown(cls_session); | 106 | iscsi_session_teardown(cls_session); |
106 | } | 107 | } |
@@ -224,6 +225,7 @@ int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
224 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 225 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
225 | int len = 0; | 226 | int len = 0; |
226 | 227 | ||
228 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param); | ||
227 | beiscsi_ep = beiscsi_conn->ep; | 229 | beiscsi_ep = beiscsi_conn->ep; |
228 | if (!beiscsi_ep) { | 230 | if (!beiscsi_ep) { |
229 | SE_DEBUG(DBG_LVL_1, | 231 | SE_DEBUG(DBG_LVL_1, |
@@ -254,6 +256,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, | |||
254 | struct iscsi_session *session = conn->session; | 256 | struct iscsi_session *session = conn->session; |
255 | int ret; | 257 | int ret; |
256 | 258 | ||
259 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param); | ||
257 | ret = iscsi_set_param(cls_conn, param, buf, buflen); | 260 | ret = iscsi_set_param(cls_conn, param, buf, buflen); |
258 | if (ret) | 261 | if (ret) |
259 | return ret; | 262 | return ret; |
@@ -293,12 +296,41 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
293 | enum iscsi_host_param param, char *buf) | 296 | enum iscsi_host_param param, char *buf) |
294 | { | 297 | { |
295 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); | 298 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); |
299 | struct be_cmd_resp_get_mac_addr *resp; | ||
300 | struct be_mcc_wrb *wrb; | ||
301 | unsigned int tag, wrb_num; | ||
296 | int len = 0; | 302 | int len = 0; |
303 | unsigned short status, extd_status; | ||
304 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
297 | 305 | ||
306 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); | ||
298 | switch (param) { | 307 | switch (param) { |
299 | case ISCSI_HOST_PARAM_HWADDRESS: | 308 | case ISCSI_HOST_PARAM_HWADDRESS: |
300 | be_cmd_get_mac_addr(phba, phba->mac_address); | 309 | tag = be_cmd_get_mac_addr(phba); |
301 | len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); | 310 | if (!tag) { |
311 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n"); | ||
312 | return -1; | ||
313 | } else | ||
314 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
315 | phba->ctrl.mcc_numtag[tag]); | ||
316 | |||
317 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
318 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
319 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
320 | if (status || extd_status) { | ||
321 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" | ||
322 | " status = %d extd_status = %d \n", | ||
323 | status, extd_status); | ||
324 | free_mcc_tag(&phba->ctrl, tag); | ||
325 | return -1; | ||
326 | } else { | ||
327 | wrb = queue_get_wrb(mccq, wrb_num); | ||
328 | free_mcc_tag(&phba->ctrl, tag); | ||
329 | resp = embedded_payload(wrb); | ||
330 | memcpy(phba->mac_address, resp->mac_address, ETH_ALEN); | ||
331 | len = sysfs_format_mac(buf, phba->mac_address, | ||
332 | ETH_ALEN); | ||
333 | } | ||
302 | break; | 334 | break; |
303 | default: | 335 | default: |
304 | return iscsi_host_get_param(shost, param, buf); | 336 | return iscsi_host_get_param(shost, param, buf); |
@@ -378,6 +410,7 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
378 | struct beiscsi_endpoint *beiscsi_ep; | 410 | struct beiscsi_endpoint *beiscsi_ep; |
379 | struct beiscsi_offload_params params; | 411 | struct beiscsi_offload_params params; |
380 | 412 | ||
413 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n"); | ||
381 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); | 414 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); |
382 | beiscsi_ep = beiscsi_conn->ep; | 415 | beiscsi_ep = beiscsi_conn->ep; |
383 | if (!beiscsi_ep) | 416 | if (!beiscsi_ep) |
@@ -422,8 +455,14 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, | |||
422 | { | 455 | { |
423 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; | 456 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; |
424 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 457 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
458 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
459 | struct be_mcc_wrb *wrb; | ||
460 | struct tcp_connect_and_offload_out *ptcpcnct_out; | ||
461 | unsigned short status, extd_status; | ||
462 | unsigned int tag, wrb_num; | ||
425 | int ret = -1; | 463 | int ret = -1; |
426 | 464 | ||
465 | SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n"); | ||
427 | beiscsi_ep->ep_cid = beiscsi_get_cid(phba); | 466 | beiscsi_ep->ep_cid = beiscsi_get_cid(phba); |
428 | if (beiscsi_ep->ep_cid == 0xFFFF) { | 467 | if (beiscsi_ep->ep_cid == 0xFFFF) { |
429 | SE_DEBUG(DBG_LVL_1, "No free cid available\n"); | 468 | SE_DEBUG(DBG_LVL_1, "No free cid available\n"); |
@@ -440,7 +479,35 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, | |||
440 | } | 479 | } |
441 | 480 | ||
442 | beiscsi_ep->cid_vld = 0; | 481 | beiscsi_ep->cid_vld = 0; |
443 | return mgmt_open_connection(phba, dst_addr, beiscsi_ep); | 482 | tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); |
483 | if (!tag) { | ||
484 | SE_DEBUG(DBG_LVL_1, | ||
485 | "mgmt_invalidate_connection Failed for cid=%d \n", | ||
486 | beiscsi_ep->ep_cid); | ||
487 | } else { | ||
488 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
489 | phba->ctrl.mcc_numtag[tag]); | ||
490 | } | ||
491 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
492 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
493 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
494 | if (status || extd_status) { | ||
495 | SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed" | ||
496 | " status = %d extd_status = %d \n", | ||
497 | status, extd_status); | ||
498 | free_mcc_tag(&phba->ctrl, tag); | ||
499 | return -1; | ||
500 | } else { | ||
501 | wrb = queue_get_wrb(mccq, wrb_num); | ||
502 | free_mcc_tag(&phba->ctrl, tag); | ||
503 | |||
504 | ptcpcnct_out = embedded_payload(wrb); | ||
505 | beiscsi_ep = ep->dd_data; | ||
506 | beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; | ||
507 | beiscsi_ep->cid_vld = 1; | ||
508 | SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); | ||
509 | } | ||
510 | return 0; | ||
444 | } | 511 | } |
445 | 512 | ||
446 | /** | 513 | /** |
@@ -509,7 +576,6 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
509 | beiscsi_ep = ep->dd_data; | 576 | beiscsi_ep = ep->dd_data; |
510 | beiscsi_ep->phba = phba; | 577 | beiscsi_ep->phba = phba; |
511 | beiscsi_ep->openiscsi_ep = ep; | 578 | beiscsi_ep->openiscsi_ep = ep; |
512 | |||
513 | if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { | 579 | if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { |
514 | SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n"); | 580 | SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n"); |
515 | ret = -ENOMEM; | 581 | ret = -ENOMEM; |
@@ -549,16 +615,19 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) | |||
549 | static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) | 615 | static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) |
550 | { | 616 | { |
551 | int ret = 0; | 617 | int ret = 0; |
618 | unsigned int tag; | ||
552 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 619 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
553 | 620 | ||
554 | if (MGMT_STATUS_SUCCESS != | 621 | tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); |
555 | mgmt_upload_connection(phba, beiscsi_ep->ep_cid, | 622 | if (!tag) { |
556 | flag)) { | ||
557 | SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", | 623 | SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", |
558 | beiscsi_ep->ep_cid); | 624 | beiscsi_ep->ep_cid); |
559 | ret = -1; | 625 | ret = -1; |
626 | } else { | ||
627 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
628 | phba->ctrl.mcc_numtag[tag]); | ||
629 | free_mcc_tag(&phba->ctrl, tag); | ||
560 | } | 630 | } |
561 | |||
562 | return ret; | 631 | return ret; |
563 | } | 632 | } |
564 | 633 | ||
@@ -576,6 +645,8 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) | |||
576 | 645 | ||
577 | beiscsi_ep = ep->dd_data; | 646 | beiscsi_ep = ep->dd_data; |
578 | phba = beiscsi_ep->phba; | 647 | phba = beiscsi_ep->phba; |
648 | SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n", | ||
649 | beiscsi_ep->ep_cid); | ||
579 | 650 | ||
580 | if (beiscsi_ep->conn) { | 651 | if (beiscsi_ep->conn) { |
581 | beiscsi_conn = beiscsi_ep->conn; | 652 | beiscsi_conn = beiscsi_ep->conn; |
@@ -614,22 +685,27 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
614 | struct iscsi_session *session = conn->session; | 685 | struct iscsi_session *session = conn->session; |
615 | struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); | 686 | struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); |
616 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 687 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
617 | unsigned int status; | 688 | unsigned int tag; |
618 | unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; | 689 | unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; |
619 | 690 | ||
620 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n"); | ||
621 | beiscsi_ep = beiscsi_conn->ep; | 691 | beiscsi_ep = beiscsi_conn->ep; |
622 | if (!beiscsi_ep) { | 692 | if (!beiscsi_ep) { |
623 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n"); | 693 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n"); |
624 | return; | 694 | return; |
625 | } | 695 | } |
626 | status = mgmt_invalidate_connection(phba, beiscsi_ep, | 696 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop ep_cid = %d\n", |
697 | beiscsi_ep->ep_cid); | ||
698 | tag = mgmt_invalidate_connection(phba, beiscsi_ep, | ||
627 | beiscsi_ep->ep_cid, 1, | 699 | beiscsi_ep->ep_cid, 1, |
628 | savecfg_flag); | 700 | savecfg_flag); |
629 | if (status != MGMT_STATUS_SUCCESS) { | 701 | if (!tag) { |
630 | SE_DEBUG(DBG_LVL_1, | 702 | SE_DEBUG(DBG_LVL_1, |
631 | "mgmt_invalidate_connection Failed for cid=%d \n", | 703 | "mgmt_invalidate_connection Failed for cid=%d \n", |
632 | beiscsi_ep->ep_cid); | 704 | beiscsi_ep->ep_cid); |
705 | } else { | ||
706 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
707 | phba->ctrl.mcc_numtag[tag]); | ||
708 | free_mcc_tag(&phba->ctrl, tag); | ||
633 | } | 709 | } |
634 | beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); | 710 | beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); |
635 | beiscsi_free_ep(beiscsi_ep); | 711 | beiscsi_free_ep(beiscsi_ep); |