diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_target.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 151 |
1 files changed, 13 insertions, 138 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index fcdc22306cab..83a8f7a9ec76 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -544,102 +544,6 @@ out_free_id_list: | |||
544 | return res; | 544 | return res; |
545 | } | 545 | } |
546 | 546 | ||
547 | static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, | ||
548 | struct qla_tgt_sess *sess) | ||
549 | { | ||
550 | struct qla_hw_data *ha = vha->hw; | ||
551 | struct qla_port_24xx_data *pmap24; | ||
552 | bool res, found = false; | ||
553 | int rc, i; | ||
554 | uint16_t loop_id = 0xFFFF; /* to eliminate compiler's warning */ | ||
555 | uint16_t entries; | ||
556 | void *pmap; | ||
557 | int pmap_len; | ||
558 | fc_port_t *fcport; | ||
559 | int global_resets; | ||
560 | unsigned long flags; | ||
561 | |||
562 | retry: | ||
563 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); | ||
564 | |||
565 | rc = qla2x00_get_node_name_list(vha, &pmap, &pmap_len); | ||
566 | if (rc != QLA_SUCCESS) { | ||
567 | res = false; | ||
568 | goto out; | ||
569 | } | ||
570 | |||
571 | pmap24 = pmap; | ||
572 | entries = pmap_len/sizeof(*pmap24); | ||
573 | |||
574 | for (i = 0; i < entries; ++i) { | ||
575 | if (!memcmp(sess->port_name, pmap24[i].port_name, WWN_SIZE)) { | ||
576 | loop_id = le16_to_cpu(pmap24[i].loop_id); | ||
577 | found = true; | ||
578 | break; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | kfree(pmap); | ||
583 | |||
584 | if (!found) { | ||
585 | res = false; | ||
586 | goto out; | ||
587 | } | ||
588 | |||
589 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf046, | ||
590 | "qlt_check_fcport_exist(): loop_id %d", loop_id); | ||
591 | |||
592 | fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); | ||
593 | if (fcport == NULL) { | ||
594 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf047, | ||
595 | "qla_target(%d): Allocation of tmp FC port failed", | ||
596 | vha->vp_idx); | ||
597 | res = false; | ||
598 | goto out; | ||
599 | } | ||
600 | |||
601 | fcport->loop_id = loop_id; | ||
602 | |||
603 | rc = qla2x00_get_port_database(vha, fcport, 0); | ||
604 | if (rc != QLA_SUCCESS) { | ||
605 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf048, | ||
606 | "qla_target(%d): Failed to retrieve fcport " | ||
607 | "information -- get_port_database() returned %x " | ||
608 | "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id); | ||
609 | res = false; | ||
610 | goto out_free_fcport; | ||
611 | } | ||
612 | |||
613 | if (global_resets != | ||
614 | atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { | ||
615 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf002, | ||
616 | "qla_target(%d): global reset during session discovery" | ||
617 | " (counter was %d, new %d), retrying", | ||
618 | vha->vp_idx, global_resets, | ||
619 | atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); | ||
620 | goto retry; | ||
621 | } | ||
622 | |||
623 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003, | ||
624 | "Updating sess %p s_id %x:%x:%x, loop_id %d) to d_id %x:%x:%x, " | ||
625 | "loop_id %d", sess, sess->s_id.b.domain, sess->s_id.b.al_pa, | ||
626 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, | ||
627 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); | ||
628 | |||
629 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
630 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, | ||
631 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); | ||
632 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
633 | |||
634 | res = true; | ||
635 | |||
636 | out_free_fcport: | ||
637 | kfree(fcport); | ||
638 | |||
639 | out: | ||
640 | return res; | ||
641 | } | ||
642 | |||
643 | /* ha->hardware_lock supposed to be held on entry */ | 547 | /* ha->hardware_lock supposed to be held on entry */ |
644 | static void qlt_undelete_sess(struct qla_tgt_sess *sess) | 548 | static void qlt_undelete_sess(struct qla_tgt_sess *sess) |
645 | { | 549 | { |
@@ -663,43 +567,13 @@ static void qlt_del_sess_work_fn(struct delayed_work *work) | |||
663 | sess = list_entry(tgt->del_sess_list.next, typeof(*sess), | 567 | sess = list_entry(tgt->del_sess_list.next, typeof(*sess), |
664 | del_list_entry); | 568 | del_list_entry); |
665 | if (time_after_eq(jiffies, sess->expires)) { | 569 | if (time_after_eq(jiffies, sess->expires)) { |
666 | bool cancel; | ||
667 | |||
668 | qlt_undelete_sess(sess); | 570 | qlt_undelete_sess(sess); |
669 | 571 | ||
670 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 572 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, |
671 | cancel = qlt_check_fcport_exist(vha, sess); | 573 | "Timeout: sess %p about to be deleted\n", |
672 | 574 | sess); | |
673 | if (cancel) { | 575 | ha->tgt.tgt_ops->shutdown_sess(sess); |
674 | if (sess->deleted) { | 576 | ha->tgt.tgt_ops->put_sess(sess); |
675 | /* | ||
676 | * sess was again deleted while we were | ||
677 | * discovering it | ||
678 | */ | ||
679 | spin_lock_irqsave(&ha->hardware_lock, | ||
680 | flags); | ||
681 | continue; | ||
682 | } | ||
683 | |||
684 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf049, | ||
685 | "qla_target(%d): cancel deletion of " | ||
686 | "session for port %02x:%02x:%02x:%02x:%02x:" | ||
687 | "%02x:%02x:%02x (loop ID %d), because " | ||
688 | " it isn't deleted by firmware", | ||
689 | vha->vp_idx, sess->port_name[0], | ||
690 | sess->port_name[1], sess->port_name[2], | ||
691 | sess->port_name[3], sess->port_name[4], | ||
692 | sess->port_name[5], sess->port_name[6], | ||
693 | sess->port_name[7], sess->loop_id); | ||
694 | } else { | ||
695 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, | ||
696 | "Timeout: sess %p about to be deleted\n", | ||
697 | sess); | ||
698 | ha->tgt.tgt_ops->shutdown_sess(sess); | ||
699 | ha->tgt.tgt_ops->put_sess(sess); | ||
700 | } | ||
701 | |||
702 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
703 | } else { | 577 | } else { |
704 | schedule_delayed_work(&tgt->sess_del_work, | 578 | schedule_delayed_work(&tgt->sess_del_work, |
705 | jiffies - sess->expires); | 579 | jiffies - sess->expires); |
@@ -884,9 +758,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
884 | sess->loop_id); | 758 | sess->loop_id); |
885 | sess->local = 0; | 759 | sess->local = 0; |
886 | } | 760 | } |
887 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
888 | |||
889 | ha->tgt.tgt_ops->put_sess(sess); | 761 | ha->tgt.tgt_ops->put_sess(sess); |
762 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
890 | } | 763 | } |
891 | 764 | ||
892 | void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) | 765 | void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) |
@@ -2706,7 +2579,9 @@ static void qlt_do_work(struct work_struct *work) | |||
2706 | /* | 2579 | /* |
2707 | * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( | 2580 | * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( |
2708 | */ | 2581 | */ |
2582 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
2709 | ha->tgt.tgt_ops->put_sess(sess); | 2583 | ha->tgt.tgt_ops->put_sess(sess); |
2584 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2710 | return; | 2585 | return; |
2711 | 2586 | ||
2712 | out_term: | 2587 | out_term: |
@@ -2718,9 +2593,9 @@ out_term: | |||
2718 | spin_lock_irqsave(&ha->hardware_lock, flags); | 2593 | spin_lock_irqsave(&ha->hardware_lock, flags); |
2719 | qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); | 2594 | qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); |
2720 | kmem_cache_free(qla_tgt_cmd_cachep, cmd); | 2595 | kmem_cache_free(qla_tgt_cmd_cachep, cmd); |
2721 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2722 | if (sess) | 2596 | if (sess) |
2723 | ha->tgt.tgt_ops->put_sess(sess); | 2597 | ha->tgt.tgt_ops->put_sess(sess); |
2598 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2724 | } | 2599 | } |
2725 | 2600 | ||
2726 | /* ha->hardware_lock supposed to be held on entry */ | 2601 | /* ha->hardware_lock supposed to be held on entry */ |
@@ -4169,16 +4044,16 @@ static void qlt_abort_work(struct qla_tgt *tgt, | |||
4169 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); | 4044 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); |
4170 | if (rc != 0) | 4045 | if (rc != 0) |
4171 | goto out_term; | 4046 | goto out_term; |
4172 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4173 | 4047 | ||
4174 | ha->tgt.tgt_ops->put_sess(sess); | 4048 | ha->tgt.tgt_ops->put_sess(sess); |
4049 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4175 | return; | 4050 | return; |
4176 | 4051 | ||
4177 | out_term: | 4052 | out_term: |
4178 | qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); | 4053 | qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); |
4179 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4180 | if (sess) | 4054 | if (sess) |
4181 | ha->tgt.tgt_ops->put_sess(sess); | 4055 | ha->tgt.tgt_ops->put_sess(sess); |
4056 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4182 | } | 4057 | } |
4183 | 4058 | ||
4184 | static void qlt_tmr_work(struct qla_tgt *tgt, | 4059 | static void qlt_tmr_work(struct qla_tgt *tgt, |
@@ -4226,16 +4101,16 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
4226 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); | 4101 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); |
4227 | if (rc != 0) | 4102 | if (rc != 0) |
4228 | goto out_term; | 4103 | goto out_term; |
4229 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4230 | 4104 | ||
4231 | ha->tgt.tgt_ops->put_sess(sess); | 4105 | ha->tgt.tgt_ops->put_sess(sess); |
4106 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4232 | return; | 4107 | return; |
4233 | 4108 | ||
4234 | out_term: | 4109 | out_term: |
4235 | qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1); | 4110 | qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1); |
4236 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4237 | if (sess) | 4111 | if (sess) |
4238 | ha->tgt.tgt_ops->put_sess(sess); | 4112 | ha->tgt.tgt_ops->put_sess(sess); |
4113 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4239 | } | 4114 | } |
4240 | 4115 | ||
4241 | static void qlt_sess_work_fn(struct work_struct *work) | 4116 | static void qlt_sess_work_fn(struct work_struct *work) |