Lines Matching +full:rx +full:- +full:num +full:- +full:evt

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ibmvfc.c -- driver for IBM Power Virtual Fibre Channel Adapter
12 #include <linux/dma-mapping.h>
22 #include <linux/bsg-lib.h>
71 MODULE_PARM_DESC(mig_channels_only, "Prevent migration to non-channelized system. "
106 MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver. "
191 u64 host_caps = be64_to_cpu(vhost->login_buf->resp.capabilities); in ibmvfc_check_caps()
200 return &vfc_cmd->v2.iu; in ibmvfc_get_fcp_iu()
202 return &vfc_cmd->v1.iu; in ibmvfc_get_fcp_iu()
209 return &vfc_cmd->v2.rsp; in ibmvfc_get_fcp_rsp()
211 return &vfc_cmd->v1.rsp; in ibmvfc_get_fcp_rsp()
216 * ibmvfc_trc_start - Log a start trace entry
217 * @evt: ibmvfc event struct
220 static void ibmvfc_trc_start(struct ibmvfc_event *evt) in ibmvfc_trc_start() argument
222 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_trc_start()
223 struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd; in ibmvfc_trc_start()
224 struct ibmvfc_mad_common *mad = &evt->iu.mad_common; in ibmvfc_trc_start()
227 int index = atomic_inc_return(&vhost->trace_index) & IBMVFC_TRACE_INDEX_MASK; in ibmvfc_trc_start()
229 entry = &vhost->trace[index]; in ibmvfc_trc_start()
230 entry->evt = evt; in ibmvfc_trc_start()
231 entry->time = jiffies; in ibmvfc_trc_start()
232 entry->fmt = evt->crq.format; in ibmvfc_trc_start()
233 entry->type = IBMVFC_TRC_START; in ibmvfc_trc_start()
235 switch (entry->fmt) { in ibmvfc_trc_start()
237 entry->op_code = iu->cdb[0]; in ibmvfc_trc_start()
238 entry->scsi_id = be64_to_cpu(vfc_cmd->tgt_scsi_id); in ibmvfc_trc_start()
239 entry->lun = scsilun_to_int(&iu->lun); in ibmvfc_trc_start()
240 entry->tmf_flags = iu->tmf_flags; in ibmvfc_trc_start()
241 entry->u.start.xfer_len = be32_to_cpu(iu->xfer_len); in ibmvfc_trc_start()
244 entry->op_code = be32_to_cpu(mad->opcode); in ibmvfc_trc_start()
252 * ibmvfc_trc_end - Log an end trace entry
253 * @evt: ibmvfc event struct
256 static void ibmvfc_trc_end(struct ibmvfc_event *evt) in ibmvfc_trc_end() argument
258 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_trc_end()
259 struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; in ibmvfc_trc_end()
260 struct ibmvfc_mad_common *mad = &evt->xfer_iu->mad_common; in ibmvfc_trc_end()
264 int index = atomic_inc_return(&vhost->trace_index) & IBMVFC_TRACE_INDEX_MASK; in ibmvfc_trc_end()
266 entry = &vhost->trace[index]; in ibmvfc_trc_end()
267 entry->evt = evt; in ibmvfc_trc_end()
268 entry->time = jiffies; in ibmvfc_trc_end()
269 entry->fmt = evt->crq.format; in ibmvfc_trc_end()
270 entry->type = IBMVFC_TRC_END; in ibmvfc_trc_end()
272 switch (entry->fmt) { in ibmvfc_trc_end()
274 entry->op_code = iu->cdb[0]; in ibmvfc_trc_end()
275 entry->scsi_id = be64_to_cpu(vfc_cmd->tgt_scsi_id); in ibmvfc_trc_end()
276 entry->lun = scsilun_to_int(&iu->lun); in ibmvfc_trc_end()
277 entry->tmf_flags = iu->tmf_flags; in ibmvfc_trc_end()
278 entry->u.end.status = be16_to_cpu(vfc_cmd->status); in ibmvfc_trc_end()
279 entry->u.end.error = be16_to_cpu(vfc_cmd->error); in ibmvfc_trc_end()
280 entry->u.end.fcp_rsp_flags = rsp->flags; in ibmvfc_trc_end()
281 entry->u.end.rsp_code = rsp->data.info.rsp_code; in ibmvfc_trc_end()
282 entry->u.end.scsi_status = rsp->scsi_status; in ibmvfc_trc_end()
285 entry->op_code = be32_to_cpu(mad->opcode); in ibmvfc_trc_end()
286 entry->u.end.status = be16_to_cpu(mad->status); in ibmvfc_trc_end()
295 #define ibmvfc_trc_start(evt) do { } while (0) argument
296 #define ibmvfc_trc_end(evt) do { } while (0) argument
300 * ibmvfc_get_err_index - Find the index into cmd_status for the fcp response
305 * index into cmd_status / -EINVAL on failure
316 return -EINVAL; in ibmvfc_get_err_index()
320 * ibmvfc_get_cmd_error - Find the error description for the fcp response
336 * ibmvfc_get_err_result - Find the scsi status to return for the fcp response
347 int fc_rsp_len = be32_to_cpu(rsp->fcp_rsp_len); in ibmvfc_get_err_result()
349 if ((rsp->flags & FCP_RSP_LEN_VALID) && in ibmvfc_get_err_result()
351 rsp->data.info.rsp_code)) in ibmvfc_get_err_result()
354 err = ibmvfc_get_err_index(be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error)); in ibmvfc_get_err_result()
356 return rsp->scsi_status | (cmd_status[err].result << 16); in ibmvfc_get_err_result()
357 return rsp->scsi_status | (DID_ERROR << 16); in ibmvfc_get_err_result()
361 * ibmvfc_retry_cmd - Determine if error status is retryable
384 { 0x01, "service parameter error - options" },
385 { 0x03, "service parameter error - initiator control" },
386 { 0x05, "service parameter error - recipient control" },
387 { 0x07, "service parameter error - received data field size" },
388 { 0x09, "service parameter error - concurrent seq" },
389 { 0x0B, "service parameter error - credit" },
396 { 0x17, "invalid OX_ID-RX-ID combination" },
412 { 0x07, "FC-4 TYPEs not registered" },
426 * ibmvfc_get_ls_explain - Return the FC Explain description text
444 * ibmvfc_get_gs_explain - Return the FC Explain description text
476 * ibmvfc_get_fc_type - Return the FC Type description text
494 * ibmvfc_set_tgt_action - Set the next init action for the target
499 * 0 if action changed / non-zero if not changed
504 int rc = -EINVAL; in ibmvfc_set_tgt_action()
506 switch (tgt->action) { in ibmvfc_set_tgt_action()
510 tgt->action = action; in ibmvfc_set_tgt_action()
517 tgt->action = action; in ibmvfc_set_tgt_action()
523 tgt->action = action; in ibmvfc_set_tgt_action()
529 tgt->action = action; in ibmvfc_set_tgt_action()
535 tgt->action = action; in ibmvfc_set_tgt_action()
542 tgt->action = action; in ibmvfc_set_tgt_action()
548 tgt->add_rport = 0; in ibmvfc_set_tgt_action()
554 * ibmvfc_set_host_state - Set the state for the host
559 * 0 if state changed / non-zero if not changed
566 switch (vhost->state) { in ibmvfc_set_host_state()
568 rc = -EINVAL; in ibmvfc_set_host_state()
571 vhost->state = state; in ibmvfc_set_host_state()
579 * ibmvfc_set_host_action - Set the next init action for the host
589 if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) in ibmvfc_set_host_action()
590 vhost->action = action; in ibmvfc_set_host_action()
593 if (vhost->action == IBMVFC_HOST_ACTION_LOGO) in ibmvfc_set_host_action()
594 vhost->action = action; in ibmvfc_set_host_action()
597 if (vhost->action == IBMVFC_HOST_ACTION_INIT) in ibmvfc_set_host_action()
598 vhost->action = action; in ibmvfc_set_host_action()
601 switch (vhost->action) { in ibmvfc_set_host_action()
605 vhost->action = action; in ibmvfc_set_host_action()
612 if (vhost->action == IBMVFC_HOST_ACTION_ALLOC_TGTS) in ibmvfc_set_host_action()
613 vhost->action = action; in ibmvfc_set_host_action()
617 vhost->action = action; in ibmvfc_set_host_action()
626 switch (vhost->action) { in ibmvfc_set_host_action()
631 vhost->action = action; in ibmvfc_set_host_action()
639 * ibmvfc_reinit_host - Re-start host initialization (no NPIV Login)
647 if (vhost->action == IBMVFC_HOST_ACTION_NONE && in ibmvfc_reinit_host()
648 vhost->state == IBMVFC_ACTIVE) { in ibmvfc_reinit_host()
650 scsi_block_requests(vhost->host); in ibmvfc_reinit_host()
654 vhost->reinit = 1; in ibmvfc_reinit_host()
656 wake_up(&vhost->work_wait_q); in ibmvfc_reinit_host()
660 * ibmvfc_del_tgt - Schedule cleanup and removal of the target
666 tgt->job_step = ibmvfc_tgt_implicit_logout_and_del; in ibmvfc_del_tgt()
667 tgt->init_retries = 0; in ibmvfc_del_tgt()
669 wake_up(&tgt->vhost->work_wait_q); in ibmvfc_del_tgt()
673 * ibmvfc_link_down - Handle a link down event from the adapter
684 scsi_block_requests(vhost->host); in ibmvfc_link_down()
685 list_for_each_entry(tgt, &vhost->targets, queue) in ibmvfc_link_down()
689 vhost->events_to_log |= IBMVFC_AE_LINKDOWN; in ibmvfc_link_down()
690 wake_up(&vhost->work_wait_q); in ibmvfc_link_down()
695 * ibmvfc_init_host - Start host initialization
705 if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) { in ibmvfc_init_host()
706 if (++vhost->init_retries > IBMVFC_MAX_HOST_INIT_RETRIES) { in ibmvfc_init_host()
707 dev_err(vhost->dev, in ibmvfc_init_host()
715 memset(vhost->async_crq.msgs.async, 0, PAGE_SIZE); in ibmvfc_init_host()
716 vhost->async_crq.cur = 0; in ibmvfc_init_host()
718 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_init_host()
719 if (vhost->client_migrated) in ibmvfc_init_host()
720 tgt->need_login = 1; in ibmvfc_init_host()
725 scsi_block_requests(vhost->host); in ibmvfc_init_host()
727 vhost->job_step = ibmvfc_npiv_login; in ibmvfc_init_host()
728 wake_up(&vhost->work_wait_q); in ibmvfc_init_host()
733 * ibmvfc_send_crq - Send a CRQ
743 struct vio_dev *vdev = to_vio_dev(vhost->dev); in ibmvfc_send_crq()
744 return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); in ibmvfc_send_crq()
750 struct vio_dev *vdev = to_vio_dev(vhost->dev); in ibmvfc_send_sub_crq()
752 return plpar_hcall_norets(H_SEND_SUB_CRQ, vdev->unit_address, cookie, in ibmvfc_send_sub_crq()
757 * ibmvfc_send_crq_init - Send a CRQ init message
770 * ibmvfc_send_crq_init_complete - Send a CRQ init complete message
783 * ibmvfc_init_event_pool - Allocates and initializes the event pool for a host
793 struct ibmvfc_event_pool *pool = &queue->evt_pool; in ibmvfc_init_event_pool()
796 if (!queue->total_depth) in ibmvfc_init_event_pool()
799 pool->size = queue->total_depth; in ibmvfc_init_event_pool()
800 pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL); in ibmvfc_init_event_pool()
801 if (!pool->events) in ibmvfc_init_event_pool()
802 return -ENOMEM; in ibmvfc_init_event_pool()
804 pool->iu_storage = dma_alloc_coherent(vhost->dev, in ibmvfc_init_event_pool()
805 pool->size * sizeof(*pool->iu_storage), in ibmvfc_init_event_pool()
806 &pool->iu_token, 0); in ibmvfc_init_event_pool()
808 if (!pool->iu_storage) { in ibmvfc_init_event_pool()
809 kfree(pool->events); in ibmvfc_init_event_pool()
810 return -ENOMEM; in ibmvfc_init_event_pool()
813 INIT_LIST_HEAD(&queue->sent); in ibmvfc_init_event_pool()
814 INIT_LIST_HEAD(&queue->free); in ibmvfc_init_event_pool()
815 queue->evt_free = queue->evt_depth; in ibmvfc_init_event_pool()
816 queue->reserved_free = queue->reserved_depth; in ibmvfc_init_event_pool()
817 spin_lock_init(&queue->l_lock); in ibmvfc_init_event_pool()
819 for (i = 0; i < pool->size; ++i) { in ibmvfc_init_event_pool()
820 struct ibmvfc_event *evt = &pool->events[i]; in ibmvfc_init_event_pool() local
823 * evt->active states in ibmvfc_init_event_pool()
826 * -1 = free/freed in ibmvfc_init_event_pool()
828 atomic_set(&evt->active, -1); in ibmvfc_init_event_pool()
829 atomic_set(&evt->free, 1); in ibmvfc_init_event_pool()
830 evt->crq.valid = 0x80; in ibmvfc_init_event_pool()
831 evt->crq.ioba = cpu_to_be64(pool->iu_token + (sizeof(*evt->xfer_iu) * i)); in ibmvfc_init_event_pool()
832 evt->xfer_iu = pool->iu_storage + i; in ibmvfc_init_event_pool()
833 evt->vhost = vhost; in ibmvfc_init_event_pool()
834 evt->queue = queue; in ibmvfc_init_event_pool()
835 evt->ext_list = NULL; in ibmvfc_init_event_pool()
836 list_add_tail(&evt->queue_list, &queue->free); in ibmvfc_init_event_pool()
844 * ibmvfc_free_event_pool - Frees memory of the event pool of a host
853 struct ibmvfc_event_pool *pool = &queue->evt_pool; in ibmvfc_free_event_pool()
856 for (i = 0; i < pool->size; ++i) { in ibmvfc_free_event_pool()
857 list_del(&pool->events[i].queue_list); in ibmvfc_free_event_pool()
858 BUG_ON(atomic_read(&pool->events[i].free) != 1); in ibmvfc_free_event_pool()
859 if (pool->events[i].ext_list) in ibmvfc_free_event_pool()
860 dma_pool_free(vhost->sg_pool, in ibmvfc_free_event_pool()
861 pool->events[i].ext_list, in ibmvfc_free_event_pool()
862 pool->events[i].ext_list_token); in ibmvfc_free_event_pool()
865 kfree(pool->events); in ibmvfc_free_event_pool()
866 dma_free_coherent(vhost->dev, in ibmvfc_free_event_pool()
867 pool->size * sizeof(*pool->iu_storage), in ibmvfc_free_event_pool()
868 pool->iu_storage, pool->iu_token); in ibmvfc_free_event_pool()
873 * ibmvfc_free_queue - Deallocate queue
882 struct device *dev = vhost->dev; in ibmvfc_free_queue()
884 dma_unmap_single(dev, queue->msg_token, PAGE_SIZE, DMA_BIDIRECTIONAL); in ibmvfc_free_queue()
885 free_page((unsigned long)queue->msgs.handle); in ibmvfc_free_queue()
886 queue->msgs.handle = NULL; in ibmvfc_free_queue()
892 * ibmvfc_release_crq_queue - Deallocates data and unregisters CRQ
901 struct vio_dev *vdev = to_vio_dev(vhost->dev); in ibmvfc_release_crq_queue()
902 struct ibmvfc_queue *crq = &vhost->crq; in ibmvfc_release_crq_queue()
905 free_irq(vdev->irq, vhost); in ibmvfc_release_crq_queue()
906 tasklet_kill(&vhost->tasklet); in ibmvfc_release_crq_queue()
910 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); in ibmvfc_release_crq_queue()
913 vhost->state = IBMVFC_NO_CRQ; in ibmvfc_release_crq_queue()
914 vhost->logged_in = 0; in ibmvfc_release_crq_queue()
920 * ibmvfc_reenable_crq_queue - reenables the CRQ
929 struct vio_dev *vdev = to_vio_dev(vhost->dev); in ibmvfc_reenable_crq_queue()
932 ibmvfc_dereg_sub_crqs(vhost, &vhost->scsi_scrqs); in ibmvfc_reenable_crq_queue()
934 /* Re-enable the CRQ */ in ibmvfc_reenable_crq_queue()
938 rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); in ibmvfc_reenable_crq_queue()
942 dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc); in ibmvfc_reenable_crq_queue()
944 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_reenable_crq_queue()
945 spin_lock(vhost->crq.q_lock); in ibmvfc_reenable_crq_queue()
946 vhost->do_enquiry = 1; in ibmvfc_reenable_crq_queue()
947 vhost->using_channels = 0; in ibmvfc_reenable_crq_queue()
948 spin_unlock(vhost->crq.q_lock); in ibmvfc_reenable_crq_queue()
949 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_reenable_crq_queue()
951 ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); in ibmvfc_reenable_crq_queue()
957 * ibmvfc_reset_crq - resets a crq after a failure
967 struct vio_dev *vdev = to_vio_dev(vhost->dev); in ibmvfc_reset_crq()
968 struct ibmvfc_queue *crq = &vhost->crq; in ibmvfc_reset_crq()
970 ibmvfc_dereg_sub_crqs(vhost, &vhost->scsi_scrqs); in ibmvfc_reset_crq()
976 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); in ibmvfc_reset_crq()
979 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_reset_crq()
980 spin_lock(vhost->crq.q_lock); in ibmvfc_reset_crq()
981 vhost->state = IBMVFC_NO_CRQ; in ibmvfc_reset_crq()
982 vhost->logged_in = 0; in ibmvfc_reset_crq()
983 vhost->do_enquiry = 1; in ibmvfc_reset_crq()
984 vhost->using_channels = 0; in ibmvfc_reset_crq()
987 memset(crq->msgs.crq, 0, PAGE_SIZE); in ibmvfc_reset_crq()
988 crq->cur = 0; in ibmvfc_reset_crq()
990 /* And re-open it again */ in ibmvfc_reset_crq()
991 rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, in ibmvfc_reset_crq()
992 crq->msg_token, PAGE_SIZE); in ibmvfc_reset_crq()
996 dev_warn(vhost->dev, "Partner adapter not ready\n"); in ibmvfc_reset_crq()
998 dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc); in ibmvfc_reset_crq()
1000 spin_unlock(vhost->crq.q_lock); in ibmvfc_reset_crq()
1001 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_reset_crq()
1003 ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); in ibmvfc_reset_crq()
1009 * ibmvfc_valid_event - Determines if event is valid.
1011 * @evt: ibmvfc event to be checked for validity
1017 struct ibmvfc_event *evt) in ibmvfc_valid_event() argument
1019 int index = evt - pool->events; in ibmvfc_valid_event()
1020 if (index < 0 || index >= pool->size) /* outside of bounds */ in ibmvfc_valid_event()
1022 if (evt != pool->events + index) /* unaligned */ in ibmvfc_valid_event()
1028 * ibmvfc_free_event - Free the specified event
1029 * @evt: ibmvfc_event to be freed
1032 static void ibmvfc_free_event(struct ibmvfc_event *evt) in ibmvfc_free_event() argument
1034 struct ibmvfc_event_pool *pool = &evt->queue->evt_pool; in ibmvfc_free_event()
1037 BUG_ON(!ibmvfc_valid_event(pool, evt)); in ibmvfc_free_event()
1038 BUG_ON(atomic_inc_return(&evt->free) != 1); in ibmvfc_free_event()
1039 BUG_ON(atomic_dec_and_test(&evt->active)); in ibmvfc_free_event()
1041 spin_lock_irqsave(&evt->queue->l_lock, flags); in ibmvfc_free_event()
1042 list_add_tail(&evt->queue_list, &evt->queue->free); in ibmvfc_free_event()
1043 if (evt->reserved) { in ibmvfc_free_event()
1044 evt->reserved = 0; in ibmvfc_free_event()
1045 evt->queue->reserved_free++; in ibmvfc_free_event()
1047 evt->queue->evt_free++; in ibmvfc_free_event()
1049 if (evt->eh_comp) in ibmvfc_free_event()
1050 complete(evt->eh_comp); in ibmvfc_free_event()
1051 spin_unlock_irqrestore(&evt->queue->l_lock, flags); in ibmvfc_free_event()
1055 * ibmvfc_scsi_eh_done - EH done function for queuecommand commands
1056 * @evt: ibmvfc event struct
1061 static void ibmvfc_scsi_eh_done(struct ibmvfc_event *evt) in ibmvfc_scsi_eh_done() argument
1063 struct scsi_cmnd *cmnd = evt->cmnd; in ibmvfc_scsi_eh_done()
1070 ibmvfc_free_event(evt); in ibmvfc_scsi_eh_done()
1074 * ibmvfc_complete_purge - Complete failed command list
1082 struct ibmvfc_event *evt, *pos; in ibmvfc_complete_purge() local
1084 list_for_each_entry_safe(evt, pos, purge_list, queue_list) { in ibmvfc_complete_purge()
1085 list_del(&evt->queue_list); in ibmvfc_complete_purge()
1086 ibmvfc_trc_end(evt); in ibmvfc_complete_purge()
1087 evt->done(evt); in ibmvfc_complete_purge()
1092 * ibmvfc_fail_request - Fail request with specified error code
1093 * @evt: ibmvfc event struct
1099 static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code) in ibmvfc_fail_request() argument
1106 BUG_ON(!atomic_dec_and_test(&evt->active)); in ibmvfc_fail_request()
1107 if (evt->cmnd) { in ibmvfc_fail_request()
1108 evt->cmnd->result = (error_code << 16); in ibmvfc_fail_request()
1109 evt->done = ibmvfc_scsi_eh_done; in ibmvfc_fail_request()
1111 evt->xfer_iu->mad_common.status = cpu_to_be16(IBMVFC_MAD_DRIVER_FAILED); in ibmvfc_fail_request()
1113 del_timer(&evt->timer); in ibmvfc_fail_request()
1117 * ibmvfc_purge_requests - Our virtual adapter just shut down. Purge any sent requests
1126 struct ibmvfc_event *evt, *pos; in ibmvfc_purge_requests() local
1127 struct ibmvfc_queue *queues = vhost->scsi_scrqs.scrqs; in ibmvfc_purge_requests()
1132 if (vhost->using_channels) in ibmvfc_purge_requests()
1133 hwqs = vhost->scsi_scrqs.active_queues; in ibmvfc_purge_requests()
1136 spin_lock_irqsave(&vhost->crq.l_lock, flags); in ibmvfc_purge_requests()
1137 list_for_each_entry_safe(evt, pos, &vhost->crq.sent, queue_list) in ibmvfc_purge_requests()
1138 ibmvfc_fail_request(evt, error_code); in ibmvfc_purge_requests()
1139 list_splice_init(&vhost->crq.sent, &vhost->purge); in ibmvfc_purge_requests()
1140 spin_unlock_irqrestore(&vhost->crq.l_lock, flags); in ibmvfc_purge_requests()
1145 list_for_each_entry_safe(evt, pos, &queues[i].sent, queue_list) in ibmvfc_purge_requests()
1146 ibmvfc_fail_request(evt, error_code); in ibmvfc_purge_requests()
1147 list_splice_init(&queues[i].sent, &vhost->purge); in ibmvfc_purge_requests()
1154 * ibmvfc_hard_reset_host - Reset the connection to the server by breaking the CRQ
1165 * __ibmvfc_reset_host - Reset the connection to the server (no locking)
1170 if (vhost->logged_in && vhost->action != IBMVFC_HOST_ACTION_LOGO_WAIT && in __ibmvfc_reset_host()
1172 scsi_block_requests(vhost->host); in __ibmvfc_reset_host()
1174 vhost->job_step = ibmvfc_npiv_logout; in __ibmvfc_reset_host()
1175 wake_up(&vhost->work_wait_q); in __ibmvfc_reset_host()
1181 * ibmvfc_reset_host - Reset the connection to the server
1188 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_reset_host()
1190 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_reset_host()
1194 * ibmvfc_retry_host_init - Retry host initialization if allowed
1204 if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) { in ibmvfc_retry_host_init()
1205 vhost->delay_init = 1; in ibmvfc_retry_host_init()
1206 if (++vhost->init_retries > IBMVFC_MAX_HOST_INIT_RETRIES) { in ibmvfc_retry_host_init()
1207 dev_err(vhost->dev, in ibmvfc_retry_host_init()
1210 } else if (vhost->init_retries == IBMVFC_MAX_HOST_INIT_RETRIES) in ibmvfc_retry_host_init()
1218 wake_up(&vhost->work_wait_q); in ibmvfc_retry_host_init()
1223 * __ibmvfc_get_target - Find the specified scsi_target (no locking)
1231 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); in __ibmvfc_get_target()
1235 list_for_each_entry(tgt, &vhost->targets, queue) in __ibmvfc_get_target()
1236 if (tgt->target_id == starget->id) { in __ibmvfc_get_target()
1237 kref_get(&tgt->kref); in __ibmvfc_get_target()
1244 * ibmvfc_get_target - Find the specified scsi_target
1252 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); in ibmvfc_get_target()
1256 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_get_target()
1258 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_get_target()
1263 * ibmvfc_get_host_speed - Get host port speed
1274 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_get_host_speed()
1275 if (vhost->state == IBMVFC_ACTIVE) { in ibmvfc_get_host_speed()
1276 switch (be64_to_cpu(vhost->login_buf->resp.link_speed) / 100) { in ibmvfc_get_host_speed()
1297 be64_to_cpu(vhost->login_buf->resp.link_speed) / 100); in ibmvfc_get_host_speed()
1303 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_get_host_speed()
1307 * ibmvfc_get_host_port_state - Get host port state
1318 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_get_host_port_state()
1319 switch (vhost->state) { in ibmvfc_get_host_port_state()
1338 ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); in ibmvfc_get_host_port_state()
1342 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_get_host_port_state()
1346 * ibmvfc_set_rport_dev_loss_tmo - Set rport's device loss timeout
1356 rport->dev_loss_tmo = timeout; in ibmvfc_set_rport_dev_loss_tmo()
1358 rport->dev_loss_tmo = 1; in ibmvfc_set_rport_dev_loss_tmo()
1362 * ibmvfc_release_tgt - Free memory allocated for a target
1373 * ibmvfc_get_starget_node_name - Get SCSI target's node name
1382 fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; in ibmvfc_get_starget_node_name()
1384 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_get_starget_node_name()
1388 * ibmvfc_get_starget_port_name - Get SCSI target's port name
1397 fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; in ibmvfc_get_starget_port_name()
1399 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_get_starget_port_name()
1403 * ibmvfc_get_starget_port_id - Get SCSI target's port ID
1412 fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; in ibmvfc_get_starget_port_id()
1414 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_get_starget_port_id()
1418 * ibmvfc_wait_while_resetting - Wait while the host resets
1426 long timeout = wait_event_timeout(vhost->init_wait_q, in ibmvfc_wait_while_resetting()
1427 ((vhost->state == IBMVFC_ACTIVE || in ibmvfc_wait_while_resetting()
1428 vhost->state == IBMVFC_HOST_OFFLINE || in ibmvfc_wait_while_resetting()
1429 vhost->state == IBMVFC_LINK_DEAD) && in ibmvfc_wait_while_resetting()
1430 vhost->action == IBMVFC_HOST_ACTION_NONE), in ibmvfc_wait_while_resetting()
1433 return timeout ? 0 : -EIO; in ibmvfc_wait_while_resetting()
1437 * ibmvfc_issue_fc_host_lip - Re-initiate link initialization
1447 dev_err(vhost->dev, "Initiating host LIP. Resetting connection\n"); in ibmvfc_issue_fc_host_lip()
1453 * ibmvfc_gather_partition_info - Gather info about the LPAR
1463 const unsigned int *num; in ibmvfc_gather_partition_info() local
1469 name = of_get_property(rootdn, "ibm,partition-name", NULL); in ibmvfc_gather_partition_info()
1471 strscpy(vhost->partition_name, name, sizeof(vhost->partition_name)); in ibmvfc_gather_partition_info()
1472 num = of_get_property(rootdn, "ibm,partition-no", NULL); in ibmvfc_gather_partition_info()
1473 if (num) in ibmvfc_gather_partition_info()
1474 vhost->partition_number = *num; in ibmvfc_gather_partition_info()
1479 * ibmvfc_set_login_info - Setup info for NPIV login
1487 struct ibmvfc_npiv_login *login_info = &vhost->login_info; in ibmvfc_set_login_info()
1488 struct ibmvfc_queue *async_crq = &vhost->async_crq; in ibmvfc_set_login_info()
1489 struct device_node *of_node = vhost->dev->of_node; in ibmvfc_set_login_info()
1496 vhost->scsi_scrqs.desired_queues; in ibmvfc_set_login_info()
1500 login_info->ostype = cpu_to_be32(IBMVFC_OS_LINUX); in ibmvfc_set_login_info()
1501 login_info->max_dma_len = cpu_to_be64(max_sectors << 9); in ibmvfc_set_login_info()
1502 login_info->max_payload = cpu_to_be32(sizeof(struct ibmvfc_fcp_cmd_iu)); in ibmvfc_set_login_info()
1503 login_info->max_response = cpu_to_be32(sizeof(struct ibmvfc_fcp_rsp)); in ibmvfc_set_login_info()
1504 login_info->partition_num = cpu_to_be32(vhost->partition_number); in ibmvfc_set_login_info()
1505 login_info->vfc_frame_version = cpu_to_be32(1); in ibmvfc_set_login_info()
1506 login_info->fcp_version = cpu_to_be16(3); in ibmvfc_set_login_info()
1507 login_info->flags = cpu_to_be16(IBMVFC_FLUSH_ON_HALT); in ibmvfc_set_login_info()
1508 if (vhost->client_migrated) in ibmvfc_set_login_info()
1509 login_info->flags |= cpu_to_be16(IBMVFC_CLIENT_MIGRATED); in ibmvfc_set_login_info()
1511 login_info->max_cmds = cpu_to_be32(max_cmds); in ibmvfc_set_login_info()
1512 login_info->capabilities = cpu_to_be64(IBMVFC_CAN_MIGRATE | IBMVFC_CAN_SEND_VF_WWPN); in ibmvfc_set_login_info()
1514 if (vhost->mq_enabled || vhost->using_channels) in ibmvfc_set_login_info()
1515 login_info->capabilities |= cpu_to_be64(IBMVFC_CAN_USE_CHANNELS); in ibmvfc_set_login_info()
1517 login_info->async.va = cpu_to_be64(vhost->async_crq.msg_token); in ibmvfc_set_login_info()
1518 login_info->async.len = cpu_to_be32(async_crq->size * in ibmvfc_set_login_info()
1519 sizeof(*async_crq->msgs.async)); in ibmvfc_set_login_info()
1520 strscpy(login_info->partition_name, vhost->partition_name, in ibmvfc_set_login_info()
1521 sizeof(login_info->partition_name)); in ibmvfc_set_login_info()
1523 strscpy(login_info->device_name, in ibmvfc_set_login_info()
1524 dev_name(&vhost->host->shost_gendev), sizeof(login_info->device_name)); in ibmvfc_set_login_info()
1526 location = of_get_property(of_node, "ibm,loc-code", NULL); in ibmvfc_set_login_info()
1527 location = location ? location : dev_name(vhost->dev); in ibmvfc_set_login_info()
1528 strscpy(login_info->drc_name, location, sizeof(login_info->drc_name)); in ibmvfc_set_login_info()
1532 * __ibmvfc_get_event - Gets the next free event in pool
1540 struct ibmvfc_event *evt = NULL; in __ibmvfc_get_event() local
1543 spin_lock_irqsave(&queue->l_lock, flags); in __ibmvfc_get_event()
1544 if (reserved && queue->reserved_free) { in __ibmvfc_get_event()
1545 evt = list_entry(queue->free.next, struct ibmvfc_event, queue_list); in __ibmvfc_get_event()
1546 evt->reserved = 1; in __ibmvfc_get_event()
1547 queue->reserved_free--; in __ibmvfc_get_event()
1548 } else if (queue->evt_free) { in __ibmvfc_get_event()
1549 evt = list_entry(queue->free.next, struct ibmvfc_event, queue_list); in __ibmvfc_get_event()
1550 queue->evt_free--; in __ibmvfc_get_event()
1555 atomic_set(&evt->free, 0); in __ibmvfc_get_event()
1556 list_del(&evt->queue_list); in __ibmvfc_get_event()
1558 spin_unlock_irqrestore(&queue->l_lock, flags); in __ibmvfc_get_event()
1559 return evt; in __ibmvfc_get_event()
1566 * ibmvfc_locked_done - Calls evt completion with host_lock held
1567 * @evt: ibmvfc evt to complete
1569 * All non-scsi command completion callbacks have the expectation that the
1571 * MAD evt with the host_lock.
1573 static void ibmvfc_locked_done(struct ibmvfc_event *evt) in ibmvfc_locked_done() argument
1577 spin_lock_irqsave(evt->vhost->host->host_lock, flags); in ibmvfc_locked_done()
1578 evt->_done(evt); in ibmvfc_locked_done()
1579 spin_unlock_irqrestore(evt->vhost->host->host_lock, flags); in ibmvfc_locked_done()
1583 * ibmvfc_init_event - Initialize fields in an event struct that are always
1585 * @evt: The event
1589 static void ibmvfc_init_event(struct ibmvfc_event *evt, in ibmvfc_init_event() argument
1592 evt->cmnd = NULL; in ibmvfc_init_event()
1593 evt->sync_iu = NULL; in ibmvfc_init_event()
1594 evt->eh_comp = NULL; in ibmvfc_init_event()
1595 evt->crq.format = format; in ibmvfc_init_event()
1597 evt->done = done; in ibmvfc_init_event()
1599 evt->_done = done; in ibmvfc_init_event()
1600 evt->done = ibmvfc_locked_done; in ibmvfc_init_event()
1602 evt->hwq = 0; in ibmvfc_init_event()
1606 * ibmvfc_map_sg_list - Initialize scatterlist
1625 * ibmvfc_map_sg_data - Maps dma for a scatterlist and initializes descriptor fields
1627 * @evt: ibmvfc event struct
1632 * 0 on success / non-zero on failure
1635 struct ibmvfc_event *evt, in ibmvfc_map_sg_data() argument
1640 struct srp_direct_buf *data = &vfc_cmd->ioba; in ibmvfc_map_sg_data()
1642 struct ibmvfc_fcp_cmd_iu *iu = ibmvfc_get_fcp_iu(evt->vhost, vfc_cmd); in ibmvfc_map_sg_data()
1645 vfc_cmd->flags |= cpu_to_be16(IBMVFC_CLASS_3_ERR); in ibmvfc_map_sg_data()
1649 vfc_cmd->flags |= cpu_to_be16(IBMVFC_NO_MEM_DESC); in ibmvfc_map_sg_data()
1652 if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) in ibmvfc_map_sg_data()
1657 if (scmd->sc_data_direction == DMA_TO_DEVICE) { in ibmvfc_map_sg_data()
1658 vfc_cmd->flags |= cpu_to_be16(IBMVFC_WRITE); in ibmvfc_map_sg_data()
1659 iu->add_cdb_len |= IBMVFC_WRDATA; in ibmvfc_map_sg_data()
1661 vfc_cmd->flags |= cpu_to_be16(IBMVFC_READ); in ibmvfc_map_sg_data()
1662 iu->add_cdb_len |= IBMVFC_RDDATA; in ibmvfc_map_sg_data()
1670 vfc_cmd->flags |= cpu_to_be16(IBMVFC_SCATTERLIST); in ibmvfc_map_sg_data()
1672 if (!evt->ext_list) { in ibmvfc_map_sg_data()
1673 evt->ext_list = dma_pool_alloc(vhost->sg_pool, GFP_ATOMIC, in ibmvfc_map_sg_data()
1674 &evt->ext_list_token); in ibmvfc_map_sg_data()
1676 if (!evt->ext_list) { in ibmvfc_map_sg_data()
1678 if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) in ibmvfc_map_sg_data()
1680 return -ENOMEM; in ibmvfc_map_sg_data()
1684 ibmvfc_map_sg_list(scmd, sg_mapped, evt->ext_list); in ibmvfc_map_sg_data()
1686 data->va = cpu_to_be64(evt->ext_list_token); in ibmvfc_map_sg_data()
1687 data->len = cpu_to_be32(sg_mapped * sizeof(struct srp_direct_buf)); in ibmvfc_map_sg_data()
1688 data->key = 0; in ibmvfc_map_sg_data()
1693 * ibmvfc_timeout - Internal command timeout handler
1700 struct ibmvfc_event *evt = from_timer(evt, t, timer); in ibmvfc_timeout() local
1701 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_timeout()
1702 dev_err(vhost->dev, "Command timed out (%p). Resetting connection\n", evt); in ibmvfc_timeout()
1707 * ibmvfc_send_event - Transforms event to u64 array and calls send_crq()
1708 * @evt: event to be sent
1710 * @timeout: timeout in seconds - 0 means do not time command
1714 static int ibmvfc_send_event(struct ibmvfc_event *evt, in ibmvfc_send_event() argument
1717 __be64 *crq_as_u64 = (__be64 *) &evt->crq; in ibmvfc_send_event()
1722 *evt->xfer_iu = evt->iu; in ibmvfc_send_event()
1723 if (evt->crq.format == IBMVFC_CMD_FORMAT) in ibmvfc_send_event()
1724 evt->xfer_iu->cmd.tag = cpu_to_be64((u64)evt); in ibmvfc_send_event()
1725 else if (evt->crq.format == IBMVFC_MAD_FORMAT) in ibmvfc_send_event()
1726 evt->xfer_iu->mad_common.tag = cpu_to_be64((u64)evt); in ibmvfc_send_event()
1730 timer_setup(&evt->timer, ibmvfc_timeout, 0); in ibmvfc_send_event()
1733 evt->timer.expires = jiffies + (timeout * HZ); in ibmvfc_send_event()
1734 add_timer(&evt->timer); in ibmvfc_send_event()
1737 spin_lock_irqsave(&evt->queue->l_lock, flags); in ibmvfc_send_event()
1738 list_add_tail(&evt->queue_list, &evt->queue->sent); in ibmvfc_send_event()
1739 atomic_set(&evt->active, 1); in ibmvfc_send_event()
1743 if (evt->queue->fmt == IBMVFC_SUB_CRQ_FMT) in ibmvfc_send_event()
1745 evt->queue->vios_cookie, in ibmvfc_send_event()
1754 atomic_set(&evt->active, 0); in ibmvfc_send_event()
1755 list_del(&evt->queue_list); in ibmvfc_send_event()
1756 spin_unlock_irqrestore(&evt->queue->l_lock, flags); in ibmvfc_send_event()
1757 del_timer(&evt->timer); in ibmvfc_send_event()
1766 dev_warn(vhost->dev, "Send warning. Receive queue closed, will retry.\n"); in ibmvfc_send_event()
1767 if (evt->cmnd) in ibmvfc_send_event()
1768 scsi_dma_unmap(evt->cmnd); in ibmvfc_send_event()
1769 ibmvfc_free_event(evt); in ibmvfc_send_event()
1773 dev_err(vhost->dev, "Send error (rc=%d)\n", rc); in ibmvfc_send_event()
1774 if (evt->cmnd) { in ibmvfc_send_event()
1775 evt->cmnd->result = DID_ERROR << 16; in ibmvfc_send_event()
1776 evt->done = ibmvfc_scsi_eh_done; in ibmvfc_send_event()
1778 evt->xfer_iu->mad_common.status = cpu_to_be16(IBMVFC_MAD_CRQ_ERROR); in ibmvfc_send_event()
1780 evt->done(evt); in ibmvfc_send_event()
1782 spin_unlock_irqrestore(&evt->queue->l_lock, flags); in ibmvfc_send_event()
1783 ibmvfc_trc_start(evt); in ibmvfc_send_event()
1790 * ibmvfc_log_error - Log an error for the failed command if appropriate
1791 * @evt: ibmvfc event to log
1794 static void ibmvfc_log_error(struct ibmvfc_event *evt) in ibmvfc_log_error() argument
1796 struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; in ibmvfc_log_error()
1797 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_log_error()
1799 struct scsi_cmnd *cmnd = evt->cmnd; in ibmvfc_log_error()
1801 int index = ibmvfc_get_err_index(be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error)); in ibmvfc_log_error()
1810 if (!logerr && (vhost->log_level <= (IBMVFC_DEFAULT_LOG_LEVEL + 1))) in ibmvfc_log_error()
1813 if (rsp->flags & FCP_RSP_LEN_VALID) in ibmvfc_log_error()
1814 rsp_code = rsp->data.info.rsp_code; in ibmvfc_log_error()
1818 cmnd->cmnd[0], err, be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error), in ibmvfc_log_error()
1819 rsp->flags, rsp_code, scsi_get_resid(cmnd), rsp->scsi_status); in ibmvfc_log_error()
1823 * ibmvfc_relogin - Log back into the specified device
1829 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_relogin()
1834 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_relogin()
1835 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_relogin()
1836 if (rport == tgt->rport) { in ibmvfc_relogin()
1843 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_relogin()
1847 * ibmvfc_scsi_done - Handle responses from commands
1848 * @evt: ibmvfc event to be handled
1852 static void ibmvfc_scsi_done(struct ibmvfc_event *evt) in ibmvfc_scsi_done() argument
1854 struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; in ibmvfc_scsi_done()
1855 struct ibmvfc_fcp_rsp *rsp = ibmvfc_get_fcp_rsp(evt->vhost, vfc_cmd); in ibmvfc_scsi_done()
1856 struct scsi_cmnd *cmnd = evt->cmnd; in ibmvfc_scsi_done()
1858 u32 sense_len = be32_to_cpu(rsp->fcp_sense_len); in ibmvfc_scsi_done()
1861 if (be16_to_cpu(vfc_cmd->response_flags) & IBMVFC_ADAPTER_RESID_VALID) in ibmvfc_scsi_done()
1862 scsi_set_resid(cmnd, be32_to_cpu(vfc_cmd->adapter_resid)); in ibmvfc_scsi_done()
1863 else if (rsp->flags & FCP_RESID_UNDER) in ibmvfc_scsi_done()
1864 scsi_set_resid(cmnd, be32_to_cpu(rsp->fcp_resid)); in ibmvfc_scsi_done()
1868 if (vfc_cmd->status) { in ibmvfc_scsi_done()
1869 cmnd->result = ibmvfc_get_err_result(evt->vhost, vfc_cmd); in ibmvfc_scsi_done()
1871 if (rsp->flags & FCP_RSP_LEN_VALID) in ibmvfc_scsi_done()
1872 rsp_len = be32_to_cpu(rsp->fcp_rsp_len); in ibmvfc_scsi_done()
1874 sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len; in ibmvfc_scsi_done()
1875 if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len && rsp_len <= 8) in ibmvfc_scsi_done()
1876 memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len); in ibmvfc_scsi_done()
1877 if ((be16_to_cpu(vfc_cmd->status) & IBMVFC_VIOS_FAILURE) && in ibmvfc_scsi_done()
1878 (be16_to_cpu(vfc_cmd->error) == IBMVFC_PLOGI_REQUIRED)) in ibmvfc_scsi_done()
1879 ibmvfc_relogin(cmnd->device); in ibmvfc_scsi_done()
1881 if (!cmnd->result && (!scsi_get_resid(cmnd) || (rsp->flags & FCP_RESID_OVER))) in ibmvfc_scsi_done()
1882 cmnd->result = (DID_ERROR << 16); in ibmvfc_scsi_done()
1884 ibmvfc_log_error(evt); in ibmvfc_scsi_done()
1887 if (!cmnd->result && in ibmvfc_scsi_done()
1888 (scsi_bufflen(cmnd) - scsi_get_resid(cmnd) < cmnd->underflow)) in ibmvfc_scsi_done()
1889 cmnd->result = (DID_ERROR << 16); in ibmvfc_scsi_done()
1895 ibmvfc_free_event(evt); in ibmvfc_scsi_done()
1899 * ibmvfc_host_chkready - Check if the host can accept commands
1909 switch (vhost->state) { in ibmvfc_host_chkready()
1928 static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct ibmvfc_event *evt, struct scsi_device *sdev) in ibmvfc_init_vfc_cmd() argument
1931 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_init_vfc_cmd()
1932 struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd; in ibmvfc_init_vfc_cmd()
1940 vfc_cmd->target_wwpn = cpu_to_be64(rport->port_name); in ibmvfc_init_vfc_cmd()
1943 vfc_cmd->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offset); in ibmvfc_init_vfc_cmd()
1944 vfc_cmd->resp.len = cpu_to_be32(sizeof(*rsp)); in ibmvfc_init_vfc_cmd()
1945 vfc_cmd->frame_type = cpu_to_be32(IBMVFC_SCSI_FCP_TYPE); in ibmvfc_init_vfc_cmd()
1946 vfc_cmd->payload_len = cpu_to_be32(sizeof(*iu)); in ibmvfc_init_vfc_cmd()
1947 vfc_cmd->resp_len = cpu_to_be32(sizeof(*rsp)); in ibmvfc_init_vfc_cmd()
1948 vfc_cmd->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata); in ibmvfc_init_vfc_cmd()
1949 vfc_cmd->tgt_scsi_id = cpu_to_be64(rport->port_id); in ibmvfc_init_vfc_cmd()
1950 int_to_scsilun(sdev->lun, &iu->lun); in ibmvfc_init_vfc_cmd()
1956 * ibmvfc_queuecommand - The queuecommand function of the scsi template
1966 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); in ibmvfc_queuecommand()
1969 struct ibmvfc_event *evt; in ibmvfc_queuecommand() local
1977 cmnd->result = rc; in ibmvfc_queuecommand()
1982 cmnd->result = (DID_OK << 16); in ibmvfc_queuecommand()
1983 if (vhost->using_channels) { in ibmvfc_queuecommand()
1984 scsi_channel = hwq % vhost->scsi_scrqs.active_queues; in ibmvfc_queuecommand()
1985 evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[scsi_channel]); in ibmvfc_queuecommand()
1986 if (!evt) in ibmvfc_queuecommand()
1989 evt->hwq = hwq % vhost->scsi_scrqs.active_queues; in ibmvfc_queuecommand()
1991 evt = ibmvfc_get_event(&vhost->crq); in ibmvfc_queuecommand()
1992 if (!evt) in ibmvfc_queuecommand()
1996 ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT); in ibmvfc_queuecommand()
1997 evt->cmnd = cmnd; in ibmvfc_queuecommand()
1999 vfc_cmd = ibmvfc_init_vfc_cmd(evt, cmnd->device); in ibmvfc_queuecommand()
2002 iu->xfer_len = cpu_to_be32(scsi_bufflen(cmnd)); in ibmvfc_queuecommand()
2003 memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); in ibmvfc_queuecommand()
2005 if (cmnd->flags & SCMD_TAGGED) { in ibmvfc_queuecommand()
2006 vfc_cmd->task_tag = cpu_to_be64(scsi_cmd_to_rq(cmnd)->tag); in ibmvfc_queuecommand()
2007 iu->pri_task_attr = IBMVFC_SIMPLE_TASK; in ibmvfc_queuecommand()
2010 vfc_cmd->correlation = cpu_to_be64((u64)evt); in ibmvfc_queuecommand()
2012 if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev)))) in ibmvfc_queuecommand()
2013 return ibmvfc_send_event(evt, vhost, 0); in ibmvfc_queuecommand()
2015 ibmvfc_free_event(evt); in ibmvfc_queuecommand()
2016 if (rc == -ENOMEM) in ibmvfc_queuecommand()
2019 if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) in ibmvfc_queuecommand()
2023 cmnd->result = DID_ERROR << 16; in ibmvfc_queuecommand()
2029 * ibmvfc_sync_completion - Signal that a synchronous command has completed
2030 * @evt: ibmvfc event struct
2033 static void ibmvfc_sync_completion(struct ibmvfc_event *evt) in ibmvfc_sync_completion() argument
2036 if (evt->sync_iu) in ibmvfc_sync_completion()
2037 *evt->sync_iu = *evt->xfer_iu; in ibmvfc_sync_completion()
2039 complete(&evt->comp); in ibmvfc_sync_completion()
2043 * ibmvfc_bsg_timeout_done - Completion handler for cancelling BSG commands
2044 * @evt: struct ibmvfc_event
2047 static void ibmvfc_bsg_timeout_done(struct ibmvfc_event *evt) in ibmvfc_bsg_timeout_done() argument
2049 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_bsg_timeout_done()
2051 ibmvfc_free_event(evt); in ibmvfc_bsg_timeout_done()
2052 vhost->aborting_passthru = 0; in ibmvfc_bsg_timeout_done()
2053 dev_info(vhost->dev, "Passthru command cancelled\n"); in ibmvfc_bsg_timeout_done()
2057 * ibmvfc_bsg_timeout - Handle a BSG timeout
2066 unsigned long port_id = (unsigned long)job->dd_data; in ibmvfc_bsg_timeout()
2067 struct ibmvfc_event *evt; in ibmvfc_bsg_timeout() local
2073 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_bsg_timeout()
2074 if (vhost->aborting_passthru || vhost->state != IBMVFC_ACTIVE) { in ibmvfc_bsg_timeout()
2076 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_timeout()
2080 vhost->aborting_passthru = 1; in ibmvfc_bsg_timeout()
2081 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_bsg_timeout()
2082 if (!evt) { in ibmvfc_bsg_timeout()
2083 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_timeout()
2084 return -ENOMEM; in ibmvfc_bsg_timeout()
2087 ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT); in ibmvfc_bsg_timeout()
2089 tmf = &evt->iu.tmf; in ibmvfc_bsg_timeout()
2091 tmf->common.version = cpu_to_be32(1); in ibmvfc_bsg_timeout()
2092 tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD); in ibmvfc_bsg_timeout()
2093 tmf->common.length = cpu_to_be16(sizeof(*tmf)); in ibmvfc_bsg_timeout()
2094 tmf->scsi_id = cpu_to_be64(port_id); in ibmvfc_bsg_timeout()
2095 tmf->cancel_key = cpu_to_be32(IBMVFC_PASSTHRU_CANCEL_KEY); in ibmvfc_bsg_timeout()
2096 tmf->my_cancel_key = cpu_to_be32(IBMVFC_INTERNAL_CANCEL_KEY); in ibmvfc_bsg_timeout()
2097 rc = ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_bsg_timeout()
2100 vhost->aborting_passthru = 0; in ibmvfc_bsg_timeout()
2101 dev_err(vhost->dev, "Failed to send cancel event. rc=%d\n", rc); in ibmvfc_bsg_timeout()
2102 rc = -EIO; in ibmvfc_bsg_timeout()
2104 dev_info(vhost->dev, "Cancelling passthru command to port id 0x%lx\n", in ibmvfc_bsg_timeout()
2107 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_timeout()
2114 * ibmvfc_bsg_plogi - PLOGI into a target to handle a BSG command
2125 struct ibmvfc_event *evt; in ibmvfc_bsg_plogi() local
2131 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_bsg_plogi()
2132 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_bsg_plogi()
2133 if (tgt->scsi_id == port_id) { in ibmvfc_bsg_plogi()
2144 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_bsg_plogi()
2145 if (!evt) { in ibmvfc_bsg_plogi()
2146 rc = -ENOMEM; in ibmvfc_bsg_plogi()
2149 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); in ibmvfc_bsg_plogi()
2150 plogi = &evt->iu.plogi; in ibmvfc_bsg_plogi()
2152 plogi->common.version = cpu_to_be32(1); in ibmvfc_bsg_plogi()
2153 plogi->common.opcode = cpu_to_be32(IBMVFC_PORT_LOGIN); in ibmvfc_bsg_plogi()
2154 plogi->common.length = cpu_to_be16(sizeof(*plogi)); in ibmvfc_bsg_plogi()
2155 plogi->scsi_id = cpu_to_be64(port_id); in ibmvfc_bsg_plogi()
2156 evt->sync_iu = &rsp_iu; in ibmvfc_bsg_plogi()
2157 init_completion(&evt->comp); in ibmvfc_bsg_plogi()
2159 rc = ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_bsg_plogi()
2160 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_plogi()
2163 return -EIO; in ibmvfc_bsg_plogi()
2165 wait_for_completion(&evt->comp); in ibmvfc_bsg_plogi()
2168 rc = -EIO; in ibmvfc_bsg_plogi()
2170 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_bsg_plogi()
2171 ibmvfc_free_event(evt); in ibmvfc_bsg_plogi()
2173 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_plogi()
2179 * ibmvfc_bsg_request - Handle a BSG request
2190 struct ibmvfc_event *evt; in ibmvfc_bsg_request() local
2192 unsigned long flags, port_id = -1; in ibmvfc_bsg_request()
2193 struct fc_bsg_request *bsg_request = job->request; in ibmvfc_bsg_request()
2194 struct fc_bsg_reply *bsg_reply = job->reply; in ibmvfc_bsg_request()
2195 unsigned int code = bsg_request->msgcode; in ibmvfc_bsg_request()
2200 bsg_reply->reply_payload_rcv_len = 0; in ibmvfc_bsg_request()
2202 port_id = rport->port_id; in ibmvfc_bsg_request()
2206 port_id = (bsg_request->rqst_data.h_els.port_id[0] << 16) | in ibmvfc_bsg_request()
2207 (bsg_request->rqst_data.h_els.port_id[1] << 8) | in ibmvfc_bsg_request()
2208 bsg_request->rqst_data.h_els.port_id[2]; in ibmvfc_bsg_request()
2215 port_id = (bsg_request->rqst_data.h_ct.port_id[0] << 16) | in ibmvfc_bsg_request()
2216 (bsg_request->rqst_data.h_ct.port_id[1] << 8) | in ibmvfc_bsg_request()
2217 bsg_request->rqst_data.h_ct.port_id[2]; in ibmvfc_bsg_request()
2223 return -ENOTSUPP; in ibmvfc_bsg_request()
2226 if (port_id == -1) in ibmvfc_bsg_request()
2227 return -EINVAL; in ibmvfc_bsg_request()
2228 if (!mutex_trylock(&vhost->passthru_mutex)) in ibmvfc_bsg_request()
2229 return -EBUSY; in ibmvfc_bsg_request()
2231 job->dd_data = (void *)port_id; in ibmvfc_bsg_request()
2232 req_seg = dma_map_sg(vhost->dev, job->request_payload.sg_list, in ibmvfc_bsg_request()
2233 job->request_payload.sg_cnt, DMA_TO_DEVICE); in ibmvfc_bsg_request()
2236 mutex_unlock(&vhost->passthru_mutex); in ibmvfc_bsg_request()
2237 return -ENOMEM; in ibmvfc_bsg_request()
2240 rsp_seg = dma_map_sg(vhost->dev, job->reply_payload.sg_list, in ibmvfc_bsg_request()
2241 job->reply_payload.sg_cnt, DMA_FROM_DEVICE); in ibmvfc_bsg_request()
2244 dma_unmap_sg(vhost->dev, job->request_payload.sg_list, in ibmvfc_bsg_request()
2245 job->request_payload.sg_cnt, DMA_TO_DEVICE); in ibmvfc_bsg_request()
2246 mutex_unlock(&vhost->passthru_mutex); in ibmvfc_bsg_request()
2247 return -ENOMEM; in ibmvfc_bsg_request()
2251 rc = -EINVAL; in ibmvfc_bsg_request()
2258 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_bsg_request()
2262 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_request()
2266 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_bsg_request()
2267 if (!evt) { in ibmvfc_bsg_request()
2268 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_request()
2269 rc = -ENOMEM; in ibmvfc_bsg_request()
2272 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); in ibmvfc_bsg_request()
2273 mad = &evt->iu.passthru; in ibmvfc_bsg_request()
2276 mad->common.version = cpu_to_be32(1); in ibmvfc_bsg_request()
2277 mad->common.opcode = cpu_to_be32(IBMVFC_PASSTHRU); in ibmvfc_bsg_request()
2278 mad->common.length = cpu_to_be16(sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu)); in ibmvfc_bsg_request()
2280 mad->cmd_ioba.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + in ibmvfc_bsg_request()
2282 mad->cmd_ioba.len = cpu_to_be32(sizeof(mad->iu)); in ibmvfc_bsg_request()
2284 mad->iu.cmd_len = cpu_to_be32(job->request_payload.payload_len); in ibmvfc_bsg_request()
2285 mad->iu.rsp_len = cpu_to_be32(job->reply_payload.payload_len); in ibmvfc_bsg_request()
2286 mad->iu.flags = cpu_to_be32(fc_flags); in ibmvfc_bsg_request()
2287 mad->iu.cancel_key = cpu_to_be32(IBMVFC_PASSTHRU_CANCEL_KEY); in ibmvfc_bsg_request()
2289 mad->iu.cmd.va = cpu_to_be64(sg_dma_address(job->request_payload.sg_list)); in ibmvfc_bsg_request()
2290 mad->iu.cmd.len = cpu_to_be32(sg_dma_len(job->request_payload.sg_list)); in ibmvfc_bsg_request()
2291 mad->iu.rsp.va = cpu_to_be64(sg_dma_address(job->reply_payload.sg_list)); in ibmvfc_bsg_request()
2292 mad->iu.rsp.len = cpu_to_be32(sg_dma_len(job->reply_payload.sg_list)); in ibmvfc_bsg_request()
2293 mad->iu.scsi_id = cpu_to_be64(port_id); in ibmvfc_bsg_request()
2294 mad->iu.tag = cpu_to_be64((u64)evt); in ibmvfc_bsg_request()
2295 rsp_len = be32_to_cpu(mad->iu.rsp.len); in ibmvfc_bsg_request()
2297 evt->sync_iu = &rsp_iu; in ibmvfc_bsg_request()
2298 init_completion(&evt->comp); in ibmvfc_bsg_request()
2299 rc = ibmvfc_send_event(evt, vhost, 0); in ibmvfc_bsg_request()
2300 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_request()
2303 rc = -EIO; in ibmvfc_bsg_request()
2307 wait_for_completion(&evt->comp); in ibmvfc_bsg_request()
2310 rc = -EIO; in ibmvfc_bsg_request()
2312 bsg_reply->reply_payload_rcv_len = rsp_len; in ibmvfc_bsg_request()
2314 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_bsg_request()
2315 ibmvfc_free_event(evt); in ibmvfc_bsg_request()
2316 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_bsg_request()
2317 bsg_reply->result = rc; in ibmvfc_bsg_request()
2318 bsg_job_done(job, bsg_reply->result, in ibmvfc_bsg_request()
2319 bsg_reply->reply_payload_rcv_len); in ibmvfc_bsg_request()
2322 dma_unmap_sg(vhost->dev, job->request_payload.sg_list, in ibmvfc_bsg_request()
2323 job->request_payload.sg_cnt, DMA_TO_DEVICE); in ibmvfc_bsg_request()
2324 dma_unmap_sg(vhost->dev, job->reply_payload.sg_list, in ibmvfc_bsg_request()
2325 job->reply_payload.sg_cnt, DMA_FROM_DEVICE); in ibmvfc_bsg_request()
2326 mutex_unlock(&vhost->passthru_mutex); in ibmvfc_bsg_request()
2332 * ibmvfc_reset_device - Reset the device with the specified reset type
2342 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_reset_device()
2345 struct ibmvfc_event *evt = NULL; in ibmvfc_reset_device() local
2349 int rsp_rc = -EBUSY; in ibmvfc_reset_device()
2353 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_reset_device()
2354 if (vhost->state == IBMVFC_ACTIVE) { in ibmvfc_reset_device()
2355 if (vhost->using_channels) in ibmvfc_reset_device()
2356 evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[0]); in ibmvfc_reset_device()
2358 evt = ibmvfc_get_event(&vhost->crq); in ibmvfc_reset_device()
2360 if (!evt) { in ibmvfc_reset_device()
2361 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_reset_device()
2362 return -ENOMEM; in ibmvfc_reset_device()
2365 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); in ibmvfc_reset_device()
2366 tmf = ibmvfc_init_vfc_cmd(evt, sdev); in ibmvfc_reset_device()
2369 tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF)); in ibmvfc_reset_device()
2371 tmf->target_wwpn = cpu_to_be64(rport->port_name); in ibmvfc_reset_device()
2372 iu->tmf_flags = type; in ibmvfc_reset_device()
2373 evt->sync_iu = &rsp_iu; in ibmvfc_reset_device()
2375 init_completion(&evt->comp); in ibmvfc_reset_device()
2376 rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_reset_device()
2378 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_reset_device()
2383 return -EIO; in ibmvfc_reset_device()
2387 wait_for_completion(&evt->comp); in ibmvfc_reset_device()
2393 if (fc_rsp->flags & FCP_RSP_LEN_VALID) in ibmvfc_reset_device()
2394 rsp_code = fc_rsp->data.info.rsp_code; in ibmvfc_reset_device()
2399 be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error), fc_rsp->flags, rsp_code, in ibmvfc_reset_device()
2400 fc_rsp->scsi_status); in ibmvfc_reset_device()
2401 rsp_rc = -EIO; in ibmvfc_reset_device()
2405 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_reset_device()
2406 ibmvfc_free_event(evt); in ibmvfc_reset_device()
2407 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_reset_device()
2412 * ibmvfc_match_rport - Match function for specified remote port
2413 * @evt: ibmvfc event struct
2419 static int ibmvfc_match_rport(struct ibmvfc_event *evt, void *rport) in ibmvfc_match_rport() argument
2423 if (evt->cmnd) { in ibmvfc_match_rport()
2424 cmd_rport = starget_to_rport(scsi_target(evt->cmnd->device)); in ibmvfc_match_rport()
2432 * ibmvfc_match_target - Match function for specified target
2433 * @evt: ibmvfc event struct
2439 static int ibmvfc_match_target(struct ibmvfc_event *evt, void *device) in ibmvfc_match_target() argument
2441 if (evt->cmnd && scsi_target(evt->cmnd->device) == device) in ibmvfc_match_target()
2447 * ibmvfc_match_lun - Match function for specified LUN
2448 * @evt: ibmvfc event struct
2454 static int ibmvfc_match_lun(struct ibmvfc_event *evt, void *device) in ibmvfc_match_lun() argument
2456 if (evt->cmnd && evt->cmnd->device == device) in ibmvfc_match_lun()
2462 * ibmvfc_event_is_free - Check if event is free or not
2463 * @evt: ibmvfc event struct
2468 static bool ibmvfc_event_is_free(struct ibmvfc_event *evt) in ibmvfc_event_is_free() argument
2472 list_for_each_entry(loop_evt, &evt->queue->free, queue_list) in ibmvfc_event_is_free()
2473 if (loop_evt == evt) in ibmvfc_event_is_free()
2480 * ibmvfc_wait_for_ops - Wait for ops to complete
2491 struct ibmvfc_event *evt; in ibmvfc_wait_for_ops() local
2499 if (vhost->mq_enabled && vhost->using_channels) { in ibmvfc_wait_for_ops()
2500 queues = vhost->scsi_scrqs.scrqs; in ibmvfc_wait_for_ops()
2501 q_size = vhost->scsi_scrqs.active_queues; in ibmvfc_wait_for_ops()
2503 queues = &vhost->crq; in ibmvfc_wait_for_ops()
2509 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_wait_for_ops()
2513 evt = &queues[q_index].evt_pool.events[i]; in ibmvfc_wait_for_ops()
2514 if (!ibmvfc_event_is_free(evt)) { in ibmvfc_wait_for_ops()
2515 if (match(evt, device)) { in ibmvfc_wait_for_ops()
2516 evt->eh_comp = &comp; in ibmvfc_wait_for_ops()
2523 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_wait_for_ops()
2530 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_wait_for_ops()
2534 evt = &queues[q_index].evt_pool.events[i]; in ibmvfc_wait_for_ops()
2535 if (!ibmvfc_event_is_free(evt)) { in ibmvfc_wait_for_ops()
2536 if (match(evt, device)) { in ibmvfc_wait_for_ops()
2537 evt->eh_comp = NULL; in ibmvfc_wait_for_ops()
2544 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_wait_for_ops()
2546 dev_err(vhost->dev, "Timed out waiting for aborted commands\n"); in ibmvfc_wait_for_ops()
2561 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_init_tmf()
2564 struct ibmvfc_event *evt; in ibmvfc_init_tmf() local
2567 evt = ibmvfc_get_reserved_event(queue); in ibmvfc_init_tmf()
2568 if (!evt) in ibmvfc_init_tmf()
2570 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); in ibmvfc_init_tmf()
2572 tmf = &evt->iu.tmf; in ibmvfc_init_tmf()
2575 tmf->common.version = cpu_to_be32(2); in ibmvfc_init_tmf()
2576 tmf->target_wwpn = cpu_to_be64(rport->port_name); in ibmvfc_init_tmf()
2578 tmf->common.version = cpu_to_be32(1); in ibmvfc_init_tmf()
2580 tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD); in ibmvfc_init_tmf()
2581 tmf->common.length = cpu_to_be16(sizeof(*tmf)); in ibmvfc_init_tmf()
2582 tmf->scsi_id = cpu_to_be64(rport->port_id); in ibmvfc_init_tmf()
2583 int_to_scsilun(sdev->lun, &tmf->lun); in ibmvfc_init_tmf()
2586 if (vhost->state == IBMVFC_ACTIVE) in ibmvfc_init_tmf()
2587 tmf->flags = cpu_to_be32((type | IBMVFC_TMF_LUA_VALID)); in ibmvfc_init_tmf()
2589 tmf->flags = cpu_to_be32(((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID)); in ibmvfc_init_tmf()
2590 tmf->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata); in ibmvfc_init_tmf()
2591 tmf->my_cancel_key = cpu_to_be32((unsigned long)starget->hostdata); in ibmvfc_init_tmf()
2593 init_completion(&evt->comp); in ibmvfc_init_tmf()
2595 return evt; in ibmvfc_init_tmf()
2600 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_cancel_all_mq()
2601 struct ibmvfc_event *evt, *found_evt, *temp; in ibmvfc_cancel_all_mq() local
2602 struct ibmvfc_queue *queues = vhost->scsi_scrqs.scrqs; in ibmvfc_cancel_all_mq()
2610 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_cancel_all_mq()
2611 num_hwq = vhost->scsi_scrqs.active_queues; in ibmvfc_cancel_all_mq()
2616 list_for_each_entry(evt, &queues[i].sent, queue_list) { in ibmvfc_cancel_all_mq()
2617 if (evt->cmnd && evt->cmnd->device == sdev) { in ibmvfc_cancel_all_mq()
2618 found_evt = evt; in ibmvfc_cancel_all_mq()
2624 if (found_evt && vhost->logged_in) { in ibmvfc_cancel_all_mq()
2625 evt = ibmvfc_init_tmf(&queues[i], sdev, type); in ibmvfc_cancel_all_mq()
2626 if (!evt) { in ibmvfc_cancel_all_mq()
2628 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_cancel_all_mq()
2629 return -ENOMEM; in ibmvfc_cancel_all_mq()
2631 evt->sync_iu = &queues[i].cancel_rsp; in ibmvfc_cancel_all_mq()
2632 ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_cancel_all_mq()
2633 list_add_tail(&evt->cancel, &cancelq); in ibmvfc_cancel_all_mq()
2638 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_cancel_all_mq()
2641 if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) in ibmvfc_cancel_all_mq()
2648 list_for_each_entry_safe(evt, temp, &cancelq, cancel) { in ibmvfc_cancel_all_mq()
2649 wait_for_completion(&evt->comp); in ibmvfc_cancel_all_mq()
2650 status = be16_to_cpu(evt->queue->cancel_rsp.mad_common.status); in ibmvfc_cancel_all_mq()
2651 list_del(&evt->cancel); in ibmvfc_cancel_all_mq()
2652 ibmvfc_free_event(evt); in ibmvfc_cancel_all_mq()
2671 return -EIO; in ibmvfc_cancel_all_mq()
2680 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_cancel_all_sq()
2681 struct ibmvfc_event *evt, *found_evt; in ibmvfc_cancel_all_sq() local
2683 int rsp_rc = -EBUSY; in ibmvfc_cancel_all_sq()
2689 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_cancel_all_sq()
2690 spin_lock(&vhost->crq.l_lock); in ibmvfc_cancel_all_sq()
2691 list_for_each_entry(evt, &vhost->crq.sent, queue_list) { in ibmvfc_cancel_all_sq()
2692 if (evt->cmnd && evt->cmnd->device == sdev) { in ibmvfc_cancel_all_sq()
2693 found_evt = evt; in ibmvfc_cancel_all_sq()
2697 spin_unlock(&vhost->crq.l_lock); in ibmvfc_cancel_all_sq()
2700 if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) in ibmvfc_cancel_all_sq()
2702 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_cancel_all_sq()
2706 if (vhost->logged_in) { in ibmvfc_cancel_all_sq()
2707 evt = ibmvfc_init_tmf(&vhost->crq, sdev, type); in ibmvfc_cancel_all_sq()
2708 evt->sync_iu = &rsp; in ibmvfc_cancel_all_sq()
2709 rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_cancel_all_sq()
2712 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_cancel_all_sq()
2724 wait_for_completion(&evt->comp); in ibmvfc_cancel_all_sq()
2726 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_cancel_all_sq()
2727 ibmvfc_free_event(evt); in ibmvfc_cancel_all_sq()
2728 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_cancel_all_sq()
2739 return -EIO; in ibmvfc_cancel_all_sq()
2748 * ibmvfc_cancel_all - Cancel all outstanding commands to the device
2760 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_cancel_all()
2762 if (vhost->mq_enabled && vhost->using_channels) in ibmvfc_cancel_all()
2769 * ibmvfc_match_key - Match function for specified cancel key
2770 * @evt: ibmvfc event struct
2776 static int ibmvfc_match_key(struct ibmvfc_event *evt, void *key) in ibmvfc_match_key() argument
2780 if (evt->crq.format == IBMVFC_CMD_FORMAT && in ibmvfc_match_key()
2781 be32_to_cpu(evt->iu.cmd.cancel_key) == cancel_key) in ibmvfc_match_key()
2787 * ibmvfc_match_evt - Match function for specified event
2788 * @evt: ibmvfc event struct
2794 static int ibmvfc_match_evt(struct ibmvfc_event *evt, void *match) in ibmvfc_match_evt() argument
2796 if (evt == match) in ibmvfc_match_evt()
2802 * ibmvfc_abort_task_set - Abort outstanding commands to the device
2813 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_abort_task_set()
2816 struct ibmvfc_event *evt, *found_evt; in ibmvfc_abort_task_set() local
2820 int rc, rsp_rc = -EBUSY; in ibmvfc_abort_task_set()
2825 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2826 spin_lock(&vhost->crq.l_lock); in ibmvfc_abort_task_set()
2827 list_for_each_entry(evt, &vhost->crq.sent, queue_list) { in ibmvfc_abort_task_set()
2828 if (evt->cmnd && evt->cmnd->device == sdev) { in ibmvfc_abort_task_set()
2829 found_evt = evt; in ibmvfc_abort_task_set()
2833 spin_unlock(&vhost->crq.l_lock); in ibmvfc_abort_task_set()
2836 if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) in ibmvfc_abort_task_set()
2838 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2842 if (vhost->state == IBMVFC_ACTIVE) { in ibmvfc_abort_task_set()
2843 evt = ibmvfc_get_event(&vhost->crq); in ibmvfc_abort_task_set()
2844 if (!evt) { in ibmvfc_abort_task_set()
2845 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2846 return -ENOMEM; in ibmvfc_abort_task_set()
2848 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); in ibmvfc_abort_task_set()
2849 tmf = ibmvfc_init_vfc_cmd(evt, sdev); in ibmvfc_abort_task_set()
2853 tmf->target_wwpn = cpu_to_be64(rport->port_name); in ibmvfc_abort_task_set()
2854 iu->tmf_flags = IBMVFC_ABORT_TASK_SET; in ibmvfc_abort_task_set()
2855 tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF)); in ibmvfc_abort_task_set()
2856 evt->sync_iu = &rsp_iu; in ibmvfc_abort_task_set()
2858 tmf->correlation = cpu_to_be64((u64)evt); in ibmvfc_abort_task_set()
2860 init_completion(&evt->comp); in ibmvfc_abort_task_set()
2861 rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_abort_task_set()
2864 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2868 return -EIO; in ibmvfc_abort_task_set()
2872 timeout = wait_for_completion_timeout(&evt->comp, timeout); in ibmvfc_abort_task_set()
2877 rc = ibmvfc_wait_for_ops(vhost, sdev->hostdata, ibmvfc_match_key); in ibmvfc_abort_task_set()
2885 rsp_rc = -EIO; in ibmvfc_abort_task_set()
2886 rc = ibmvfc_wait_for_ops(vhost, sdev->hostdata, ibmvfc_match_key); in ibmvfc_abort_task_set()
2891 rc = ibmvfc_wait_for_ops(vhost, evt, ibmvfc_match_evt); in ibmvfc_abort_task_set()
2893 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2895 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2907 if (fc_rsp->flags & FCP_RSP_LEN_VALID) in ibmvfc_abort_task_set()
2908 rsp_code = fc_rsp->data.info.rsp_code; in ibmvfc_abort_task_set()
2913 be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error), fc_rsp->flags, rsp_code, in ibmvfc_abort_task_set()
2914 fc_rsp->scsi_status); in ibmvfc_abort_task_set()
2915 rsp_rc = -EIO; in ibmvfc_abort_task_set()
2920 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2921 ibmvfc_free_event(evt); in ibmvfc_abort_task_set()
2922 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_abort_task_set()
2927 * ibmvfc_eh_abort_handler - Abort a command
2935 struct scsi_device *sdev = cmd->device; in ibmvfc_eh_abort_handler()
2936 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_eh_abort_handler()
2960 * ibmvfc_eh_device_reset_handler - Reset a single LUN
2968 struct scsi_device *sdev = cmd->device; in ibmvfc_eh_device_reset_handler()
2969 struct ibmvfc_host *vhost = shost_priv(sdev->host); in ibmvfc_eh_device_reset_handler()
2993 * ibmvfc_dev_cancel_all_noreset - Device iterated cancel all function
3005 * ibmvfc_eh_target_reset_handler - Reset the target
3013 struct scsi_target *starget = scsi_target(cmd->device); in ibmvfc_eh_target_reset_handler()
3030 if ((sdev->channel != starget->channel) || in ibmvfc_eh_target_reset_handler()
3031 (sdev->id != starget->id)) in ibmvfc_eh_target_reset_handler()
3057 * ibmvfc_eh_host_reset_handler - Reset the connection to the server
3064 struct ibmvfc_host *vhost = shost_priv(cmd->device->host); in ibmvfc_eh_host_reset_handler()
3066 dev_err(vhost->dev, "Resetting connection due to error recovery\n"); in ibmvfc_eh_host_reset_handler()
3067 rc = ibmvfc_issue_fc_host_lip(vhost->host); in ibmvfc_eh_host_reset_handler()
3073 * ibmvfc_terminate_rport_io - Terminate all pending I/O to the rport.
3102 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_terminate_rport_io()
3104 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_terminate_rport_io()
3105 if (tgt->scsi_id == rport->port_id) { in ibmvfc_terminate_rport_io()
3111 if (found && tgt->action == IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT) { in ibmvfc_terminate_rport_io()
3121 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_terminate_rport_io()
3129 { "N-Port SCN", IBMVFC_AE_SCN_NPORT, IBMVFC_DEFAULT_LOG_LEVEL + 1 },
3146 * ibmvfc_get_ae_desc - Get text description for async event
3172 * ibmvfc_get_link_state - Get text description for link state
3188 * ibmvfc_handle_async - Handle an async event from the adapter
3196 const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be64_to_cpu(crq->event)); in ibmvfc_handle_async()
3199 ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx," in ibmvfc_handle_async()
3200 " node_name: %llx%s\n", desc->desc, be64_to_cpu(crq->scsi_id), in ibmvfc_handle_async()
3201 be64_to_cpu(crq->wwpn), be64_to_cpu(crq->node_name), in ibmvfc_handle_async()
3202 ibmvfc_get_link_state(crq->link_state)); in ibmvfc_handle_async()
3204 switch (be64_to_cpu(crq->event)) { in ibmvfc_handle_async()
3206 switch (crq->link_state) { in ibmvfc_handle_async()
3216 vhost->events_to_log |= IBMVFC_AE_LINKUP; in ibmvfc_handle_async()
3217 vhost->delay_init = 1; in ibmvfc_handle_async()
3224 vhost->events_to_log |= IBMVFC_AE_LINKUP; in ibmvfc_handle_async()
3225 vhost->delay_init = 1; in ibmvfc_handle_async()
3230 vhost->events_to_log |= IBMVFC_AE_RSCN; in ibmvfc_handle_async()
3231 if (vhost->state < IBMVFC_HALTED) { in ibmvfc_handle_async()
3232 vhost->delay_init = 1; in ibmvfc_handle_async()
3238 vhost->events_to_log |= IBMVFC_AE_RSCN; in ibmvfc_handle_async()
3244 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_handle_async()
3245 if (!crq->scsi_id && !crq->wwpn && !crq->node_name) in ibmvfc_handle_async()
3247 if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) != crq->scsi_id) in ibmvfc_handle_async()
3249 if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) != crq->wwpn) in ibmvfc_handle_async()
3251 if (crq->node_name && cpu_to_be64(tgt->ids.node_name) != crq->node_name) in ibmvfc_handle_async()
3253 if (tgt->need_login && be64_to_cpu(crq->event) == IBMVFC_AE_ELS_LOGO) in ibmvfc_handle_async()
3254 tgt->logo_rcvd = 1; in ibmvfc_handle_async()
3255 if (!tgt->need_login || be64_to_cpu(crq->event) == IBMVFC_AE_ELS_PLOGI) { in ibmvfc_handle_async()
3272 dev_err(vhost->dev, "Unknown async event received: %lld\n", crq->event); in ibmvfc_handle_async()
3278 * ibmvfc_handle_crq - Handles and frees received events in the CRQ
3288 struct ibmvfc_event *evt = (struct ibmvfc_event *)be64_to_cpu(crq->ioba); in ibmvfc_handle_crq() local
3290 switch (crq->valid) { in ibmvfc_handle_crq()
3292 switch (crq->format) { in ibmvfc_handle_crq()
3294 dev_info(vhost->dev, "Partner initialized\n"); in ibmvfc_handle_crq()
3300 dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc); in ibmvfc_handle_crq()
3303 dev_info(vhost->dev, "Partner initialization complete\n"); in ibmvfc_handle_crq()
3307 dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format); in ibmvfc_handle_crq()
3311 vhost->state = IBMVFC_NO_CRQ; in ibmvfc_handle_crq()
3312 vhost->logged_in = 0; in ibmvfc_handle_crq()
3314 if (crq->format == IBMVFC_PARTITION_MIGRATED) { in ibmvfc_handle_crq()
3315 /* We need to re-setup the interpartition connection */ in ibmvfc_handle_crq()
3316 dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n"); in ibmvfc_handle_crq()
3317 vhost->client_migrated = 1; in ibmvfc_handle_crq()
3319 scsi_block_requests(vhost->host); in ibmvfc_handle_crq()
3323 wake_up(&vhost->work_wait_q); in ibmvfc_handle_crq()
3324 } else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) { in ibmvfc_handle_crq()
3325 dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format); in ibmvfc_handle_crq()
3330 dev_err(vhost->dev, "Received unknown transport event from partner (rc=%d)\n", crq->format); in ibmvfc_handle_crq()
3336 dev_err(vhost->dev, "Got an invalid message type 0x%02x\n", crq->valid); in ibmvfc_handle_crq()
3340 if (crq->format == IBMVFC_ASYNC_EVENT) in ibmvfc_handle_crq()
3347 if (unlikely(!ibmvfc_valid_event(&vhost->crq.evt_pool, evt))) { in ibmvfc_handle_crq()
3348 dev_err(vhost->dev, "Returned correlation_token 0x%08llx is invalid!\n", in ibmvfc_handle_crq()
3349 crq->ioba); in ibmvfc_handle_crq()
3353 if (unlikely(atomic_dec_if_positive(&evt->active))) { in ibmvfc_handle_crq()
3354 dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n", in ibmvfc_handle_crq()
3355 crq->ioba); in ibmvfc_handle_crq()
3359 spin_lock(&evt->queue->l_lock); in ibmvfc_handle_crq()
3360 list_move_tail(&evt->queue_list, evt_doneq); in ibmvfc_handle_crq()
3361 spin_unlock(&evt->queue->l_lock); in ibmvfc_handle_crq()
3365 * ibmvfc_scan_finished - Check if the device scan is done.
3378 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_scan_finished()
3379 if (!vhost->scan_timeout) in ibmvfc_scan_finished()
3381 else if (time >= (vhost->scan_timeout * HZ)) { in ibmvfc_scan_finished()
3382 dev_info(vhost->dev, "Scan taking longer than %d seconds, " in ibmvfc_scan_finished()
3383 "continuing initialization\n", vhost->scan_timeout); in ibmvfc_scan_finished()
3387 if (vhost->scan_complete) { in ibmvfc_scan_finished()
3388 vhost->scan_timeout = init_timeout; in ibmvfc_scan_finished()
3391 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_scan_finished()
3396 * ibmvfc_sdev_init - Setup the device's task set value
3403 * 0 on success / -ENXIO if device does not exist
3407 struct Scsi_Host *shost = sdev->host; in ibmvfc_sdev_init()
3413 return -ENXIO; in ibmvfc_sdev_init()
3415 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_sdev_init()
3416 sdev->hostdata = (void *)(unsigned long)vhost->task_set++; in ibmvfc_sdev_init()
3417 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_sdev_init()
3422 * ibmvfc_target_alloc - Setup the target's task set value
3429 * 0 on success / -ENXIO if device does not exist
3433 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); in ibmvfc_target_alloc()
3437 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_target_alloc()
3438 starget->hostdata = (void *)(unsigned long)vhost->task_set++; in ibmvfc_target_alloc()
3439 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_target_alloc()
3444 * ibmvfc_sdev_configure - Configure the device
3457 struct Scsi_Host *shost = sdev->host; in ibmvfc_sdev_configure()
3460 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_sdev_configure()
3461 if (sdev->type == TYPE_DISK) { in ibmvfc_sdev_configure()
3462 sdev->allow_restart = 1; in ibmvfc_sdev_configure()
3463 blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); in ibmvfc_sdev_configure()
3465 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_sdev_configure()
3470 * ibmvfc_change_queue_depth - Change the device's queue depth
3491 return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.partition_name); in ibmvfc_show_host_partition_name()
3500 return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.device_name); in ibmvfc_show_host_device_name()
3509 return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.port_loc_code); in ibmvfc_show_host_loc_code()
3518 return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.drc_name); in ibmvfc_show_host_drc_name()
3527 be32_to_cpu(vhost->login_buf->resp.version)); in ibmvfc_show_host_npiv_version()
3536 be64_to_cpu(vhost->login_buf->resp.capabilities)); in ibmvfc_show_host_capabilities()
3540 * ibmvfc_show_log_level - Show the adapter's error logging level
3556 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_show_log_level()
3557 len = sysfs_emit(buf, "%d\n", vhost->log_level); in ibmvfc_show_log_level()
3558 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_show_log_level()
3563 * ibmvfc_store_log_level - Change the adapter's error logging level
3580 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_store_log_level()
3581 vhost->log_level = simple_strtoul(buf, NULL, 10); in ibmvfc_store_log_level()
3582 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_store_log_level()
3591 struct ibmvfc_channels *scsi = &vhost->scsi_scrqs; in ibmvfc_show_scsi_channels()
3595 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_show_scsi_channels()
3596 len = sysfs_emit(buf, "%d\n", scsi->desired_queues); in ibmvfc_show_scsi_channels()
3597 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_show_scsi_channels()
3607 struct ibmvfc_channels *scsi = &vhost->scsi_scrqs; in ibmvfc_store_scsi_channels()
3611 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_store_scsi_channels()
3613 scsi->desired_queues = min(channels, shost->nr_hw_queues); in ibmvfc_store_scsi_channels()
3615 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_store_scsi_channels()
3632 * ibmvfc_read_trace - Dump the adapter trace
3652 char *src = (char *)vhost->trace; in ibmvfc_read_trace()
3657 size -= off; in ibmvfc_read_trace()
3661 spin_lock_irqsave(shost->host_lock, flags); in ibmvfc_read_trace()
3663 spin_unlock_irqrestore(shost->host_lock, flags); in ibmvfc_read_trace()
3708 .this_id = -1,
3716 * ibmvfc_next_async_crq - Returns the next entry in async queue
3724 struct ibmvfc_queue *async_crq = &vhost->async_crq; in ibmvfc_next_async_crq()
3727 crq = &async_crq->msgs.async[async_crq->cur]; in ibmvfc_next_async_crq()
3728 if (crq->valid & 0x80) { in ibmvfc_next_async_crq()
3729 if (++async_crq->cur == async_crq->size) in ibmvfc_next_async_crq()
3730 async_crq->cur = 0; in ibmvfc_next_async_crq()
3739 * ibmvfc_next_crq - Returns the next entry in message queue
3747 struct ibmvfc_queue *queue = &vhost->crq; in ibmvfc_next_crq()
3750 crq = &queue->msgs.crq[queue->cur]; in ibmvfc_next_crq()
3751 if (crq->valid & 0x80) { in ibmvfc_next_crq()
3752 if (++queue->cur == queue->size) in ibmvfc_next_crq()
3753 queue->cur = 0; in ibmvfc_next_crq()
3762 * ibmvfc_interrupt - Interrupt handler
3774 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_interrupt()
3775 vio_disable_interrupts(to_vio_dev(vhost->dev)); in ibmvfc_interrupt()
3776 tasklet_schedule(&vhost->tasklet); in ibmvfc_interrupt()
3777 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_interrupt()
3782 * ibmvfc_tasklet - Interrupt handler tasklet
3791 struct vio_dev *vdev = to_vio_dev(vhost->dev); in ibmvfc_tasklet()
3794 struct ibmvfc_event *evt, *temp; in ibmvfc_tasklet() local
3799 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_tasklet()
3800 spin_lock(vhost->crq.q_lock); in ibmvfc_tasklet()
3805 async->valid = 0; in ibmvfc_tasklet()
3812 crq->valid = 0; in ibmvfc_tasklet()
3820 async->valid = 0; in ibmvfc_tasklet()
3825 crq->valid = 0; in ibmvfc_tasklet()
3831 spin_unlock(vhost->crq.q_lock); in ibmvfc_tasklet()
3832 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_tasklet()
3834 list_for_each_entry_safe(evt, temp, &evt_doneq, queue_list) { in ibmvfc_tasklet()
3835 del_timer(&evt->timer); in ibmvfc_tasklet()
3836 list_del(&evt->queue_list); in ibmvfc_tasklet()
3837 ibmvfc_trc_end(evt); in ibmvfc_tasklet()
3838 evt->done(evt); in ibmvfc_tasklet()
3844 struct device *dev = scrq->vhost->dev; in ibmvfc_toggle_scrq_irq()
3852 rc = plpar_hcall_norets(H_VIOCTL, vdev->unit_address, irq_action, in ibmvfc_toggle_scrq_irq()
3853 scrq->hw_irq, 0, 0); in ibmvfc_toggle_scrq_irq()
3856 dev_err(dev, "Couldn't %s sub-crq[%lu] irq. rc=%ld\n", in ibmvfc_toggle_scrq_irq()
3857 enable ? "enable" : "disable", scrq->hwq_id, rc); in ibmvfc_toggle_scrq_irq()
3865 struct ibmvfc_event *evt = (struct ibmvfc_event *)be64_to_cpu(crq->ioba); in ibmvfc_handle_scrq() local
3867 switch (crq->valid) { in ibmvfc_handle_scrq()
3873 dev_err(vhost->dev, "Got and invalid message type 0x%02x\n", crq->valid); in ibmvfc_handle_scrq()
3881 if (unlikely(!ibmvfc_valid_event(&evt->queue->evt_pool, evt))) { in ibmvfc_handle_scrq()
3882 dev_err(vhost->dev, "Returned correlation_token 0x%08llx is invalid!\n", in ibmvfc_handle_scrq()
3883 crq->ioba); in ibmvfc_handle_scrq()
3887 if (unlikely(atomic_dec_if_positive(&evt->active))) { in ibmvfc_handle_scrq()
3888 dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n", in ibmvfc_handle_scrq()
3889 crq->ioba); in ibmvfc_handle_scrq()
3893 spin_lock(&evt->queue->l_lock); in ibmvfc_handle_scrq()
3894 list_move_tail(&evt->queue_list, evt_doneq); in ibmvfc_handle_scrq()
3895 spin_unlock(&evt->queue->l_lock); in ibmvfc_handle_scrq()
3902 crq = &scrq->msgs.scrq[scrq->cur].crq; in ibmvfc_next_scrq()
3903 if (crq->valid & 0x80) { in ibmvfc_next_scrq()
3904 if (++scrq->cur == scrq->size) in ibmvfc_next_scrq()
3905 scrq->cur = 0; in ibmvfc_next_scrq()
3916 struct ibmvfc_event *evt, *temp; in ibmvfc_drain_sub_crq() local
3921 spin_lock_irqsave(scrq->q_lock, flags); in ibmvfc_drain_sub_crq()
3924 ibmvfc_handle_scrq(crq, scrq->vhost, &evt_doneq); in ibmvfc_drain_sub_crq()
3925 crq->valid = 0; in ibmvfc_drain_sub_crq()
3932 ibmvfc_handle_scrq(crq, scrq->vhost, &evt_doneq); in ibmvfc_drain_sub_crq()
3933 crq->valid = 0; in ibmvfc_drain_sub_crq()
3938 spin_unlock_irqrestore(scrq->q_lock, flags); in ibmvfc_drain_sub_crq()
3940 list_for_each_entry_safe(evt, temp, &evt_doneq, queue_list) { in ibmvfc_drain_sub_crq()
3941 del_timer(&evt->timer); in ibmvfc_drain_sub_crq()
3942 list_del(&evt->queue_list); in ibmvfc_drain_sub_crq()
3943 ibmvfc_trc_end(evt); in ibmvfc_drain_sub_crq()
3944 evt->done(evt); in ibmvfc_drain_sub_crq()
3959 * ibmvfc_init_tgt - Set the next init job step for the target
3968 tgt->job_step = job_step; in ibmvfc_init_tgt()
3969 wake_up(&tgt->vhost->work_wait_q); in ibmvfc_init_tgt()
3973 * ibmvfc_retry_tgt_init - Attempt to retry a step in target initialization
3983 if (++tgt->init_retries > IBMVFC_MAX_TGT_INIT_RETRIES) { in ibmvfc_retry_tgt_init()
3985 wake_up(&tgt->vhost->work_wait_q); in ibmvfc_retry_tgt_init()
3992 /* Defined in FC-LS */
4010 * ibmvfc_get_prli_rsp - Find PRLI response index
4027 * ibmvfc_tgt_prli_done - Completion handler for Process Login
4028 * @evt: ibmvfc event struct
4031 static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt) in ibmvfc_tgt_prli_done() argument
4033 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_prli_done()
4034 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_prli_done()
4035 struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli; in ibmvfc_tgt_prli_done()
4036 struct ibmvfc_prli_svc_parms *parms = &rsp->parms; in ibmvfc_tgt_prli_done()
4037 u32 status = be16_to_cpu(rsp->common.status); in ibmvfc_tgt_prli_done()
4040 vhost->discovery_threads--; in ibmvfc_tgt_prli_done()
4045 parms->type, parms->flags, parms->service_parms); in ibmvfc_tgt_prli_done()
4047 if (parms->type == IBMVFC_SCSI_FCP_TYPE) { in ibmvfc_tgt_prli_done()
4048 index = ibmvfc_get_prli_rsp(be16_to_cpu(parms->flags)); in ibmvfc_tgt_prli_done()
4050 if (be16_to_cpu(parms->flags) & IBMVFC_PRLI_EST_IMG_PAIR) { in ibmvfc_tgt_prli_done()
4051 tgt->need_login = 0; in ibmvfc_tgt_prli_done()
4052 tgt->ids.roles = 0; in ibmvfc_tgt_prli_done()
4053 if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_TARGET_FUNC) in ibmvfc_tgt_prli_done()
4054 tgt->ids.roles |= FC_PORT_ROLE_FCP_TARGET; in ibmvfc_tgt_prli_done()
4055 if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_INITIATOR_FUNC) in ibmvfc_tgt_prli_done()
4056 tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR; in ibmvfc_tgt_prli_done()
4057 tgt->add_rport = 1; in ibmvfc_tgt_prli_done()
4074 if ((be16_to_cpu(rsp->status) & IBMVFC_VIOS_FAILURE) && in ibmvfc_tgt_prli_done()
4075 be16_to_cpu(rsp->error) == IBMVFC_PLOGI_REQUIRED) in ibmvfc_tgt_prli_done()
4077 else if (tgt->logo_rcvd) in ibmvfc_tgt_prli_done()
4079 else if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error))) in ibmvfc_tgt_prli_done()
4085 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), in ibmvfc_tgt_prli_done()
4086 be16_to_cpu(rsp->status), be16_to_cpu(rsp->error), status); in ibmvfc_tgt_prli_done()
4090 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_prli_done()
4091 ibmvfc_free_event(evt); in ibmvfc_tgt_prli_done()
4092 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_prli_done()
4096 * ibmvfc_tgt_send_prli - Send a process login
4103 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_send_prli()
4104 struct ibmvfc_event *evt; in ibmvfc_tgt_send_prli() local
4106 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_send_prli()
4109 kref_get(&tgt->kref); in ibmvfc_tgt_send_prli()
4110 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_tgt_send_prli()
4111 if (!evt) { in ibmvfc_tgt_send_prli()
4113 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_send_prli()
4117 vhost->discovery_threads++; in ibmvfc_tgt_send_prli()
4118 ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT); in ibmvfc_tgt_send_prli()
4119 evt->tgt = tgt; in ibmvfc_tgt_send_prli()
4120 prli = &evt->iu.prli; in ibmvfc_tgt_send_prli()
4123 prli->common.version = cpu_to_be32(2); in ibmvfc_tgt_send_prli()
4124 prli->target_wwpn = cpu_to_be64(tgt->wwpn); in ibmvfc_tgt_send_prli()
4126 prli->common.version = cpu_to_be32(1); in ibmvfc_tgt_send_prli()
4128 prli->common.opcode = cpu_to_be32(IBMVFC_PROCESS_LOGIN); in ibmvfc_tgt_send_prli()
4129 prli->common.length = cpu_to_be16(sizeof(*prli)); in ibmvfc_tgt_send_prli()
4130 prli->scsi_id = cpu_to_be64(tgt->scsi_id); in ibmvfc_tgt_send_prli()
4132 prli->parms.type = IBMVFC_SCSI_FCP_TYPE; in ibmvfc_tgt_send_prli()
4133 prli->parms.flags = cpu_to_be16(IBMVFC_PRLI_EST_IMG_PAIR); in ibmvfc_tgt_send_prli()
4134 prli->parms.service_parms = cpu_to_be32(IBMVFC_PRLI_INITIATOR_FUNC); in ibmvfc_tgt_send_prli()
4135 prli->parms.service_parms |= cpu_to_be32(IBMVFC_PRLI_READ_FCP_XFER_RDY_DISABLED); in ibmvfc_tgt_send_prli()
4138 prli->parms.service_parms |= cpu_to_be32(IBMVFC_PRLI_RETRY); in ibmvfc_tgt_send_prli()
4141 if (ibmvfc_send_event(evt, vhost, default_timeout)) { in ibmvfc_tgt_send_prli()
4142 vhost->discovery_threads--; in ibmvfc_tgt_send_prli()
4144 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_send_prli()
4150 * ibmvfc_tgt_plogi_done - Completion handler for Port Login
4151 * @evt: ibmvfc event struct
4154 static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt) in ibmvfc_tgt_plogi_done() argument
4156 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_plogi_done()
4157 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_plogi_done()
4158 struct ibmvfc_port_login *rsp = &evt->xfer_iu->plogi; in ibmvfc_tgt_plogi_done()
4159 u32 status = be16_to_cpu(rsp->common.status); in ibmvfc_tgt_plogi_done()
4162 vhost->discovery_threads--; in ibmvfc_tgt_plogi_done()
4167 if (tgt->ids.port_name && in ibmvfc_tgt_plogi_done()
4168 tgt->ids.port_name != wwn_to_u64(rsp->service_parms.port_name)) { in ibmvfc_tgt_plogi_done()
4169 vhost->reinit = 1; in ibmvfc_tgt_plogi_done()
4170 tgt_dbg(tgt, "Port re-init required\n"); in ibmvfc_tgt_plogi_done()
4173 tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name); in ibmvfc_tgt_plogi_done()
4174 tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name); in ibmvfc_tgt_plogi_done()
4175 tgt->ids.port_id = tgt->scsi_id; in ibmvfc_tgt_plogi_done()
4176 memcpy(&tgt->service_parms, &rsp->service_parms, in ibmvfc_tgt_plogi_done()
4177 sizeof(tgt->service_parms)); in ibmvfc_tgt_plogi_done()
4178 memcpy(&tgt->service_parms_change, &rsp->service_parms_change, in ibmvfc_tgt_plogi_done()
4179 sizeof(tgt->service_parms_change)); in ibmvfc_tgt_plogi_done()
4189 if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error))) in ibmvfc_tgt_plogi_done()
4195 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), in ibmvfc_tgt_plogi_done()
4196 be16_to_cpu(rsp->status), be16_to_cpu(rsp->error), in ibmvfc_tgt_plogi_done()
4197 ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), be16_to_cpu(rsp->fc_type), in ibmvfc_tgt_plogi_done()
4198 ibmvfc_get_ls_explain(be16_to_cpu(rsp->fc_explain)), be16_to_cpu(rsp->fc_explain), status); in ibmvfc_tgt_plogi_done()
4202 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_plogi_done()
4203 ibmvfc_free_event(evt); in ibmvfc_tgt_plogi_done()
4204 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_plogi_done()
4208 * ibmvfc_tgt_send_plogi - Send PLOGI to the specified target
4215 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_send_plogi()
4216 struct ibmvfc_event *evt; in ibmvfc_tgt_send_plogi() local
4218 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_send_plogi()
4221 kref_get(&tgt->kref); in ibmvfc_tgt_send_plogi()
4222 tgt->logo_rcvd = 0; in ibmvfc_tgt_send_plogi()
4223 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_tgt_send_plogi()
4224 if (!evt) { in ibmvfc_tgt_send_plogi()
4226 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_send_plogi()
4230 vhost->discovery_threads++; in ibmvfc_tgt_send_plogi()
4232 ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT); in ibmvfc_tgt_send_plogi()
4233 evt->tgt = tgt; in ibmvfc_tgt_send_plogi()
4234 plogi = &evt->iu.plogi; in ibmvfc_tgt_send_plogi()
4237 plogi->common.version = cpu_to_be32(2); in ibmvfc_tgt_send_plogi()
4238 plogi->target_wwpn = cpu_to_be64(tgt->wwpn); in ibmvfc_tgt_send_plogi()
4240 plogi->common.version = cpu_to_be32(1); in ibmvfc_tgt_send_plogi()
4242 plogi->common.opcode = cpu_to_be32(IBMVFC_PORT_LOGIN); in ibmvfc_tgt_send_plogi()
4243 plogi->common.length = cpu_to_be16(sizeof(*plogi)); in ibmvfc_tgt_send_plogi()
4244 plogi->scsi_id = cpu_to_be64(tgt->scsi_id); in ibmvfc_tgt_send_plogi()
4246 if (ibmvfc_send_event(evt, vhost, default_timeout)) { in ibmvfc_tgt_send_plogi()
4247 vhost->discovery_threads--; in ibmvfc_tgt_send_plogi()
4249 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_send_plogi()
4255 * ibmvfc_tgt_implicit_logout_done - Completion handler for Implicit Logout MAD
4256 * @evt: ibmvfc event struct
4259 static void ibmvfc_tgt_implicit_logout_done(struct ibmvfc_event *evt) in ibmvfc_tgt_implicit_logout_done() argument
4261 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_implicit_logout_done()
4262 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_implicit_logout_done()
4263 struct ibmvfc_implicit_logout *rsp = &evt->xfer_iu->implicit_logout; in ibmvfc_tgt_implicit_logout_done()
4264 u32 status = be16_to_cpu(rsp->common.status); in ibmvfc_tgt_implicit_logout_done()
4266 vhost->discovery_threads--; in ibmvfc_tgt_implicit_logout_done()
4267 ibmvfc_free_event(evt); in ibmvfc_tgt_implicit_logout_done()
4275 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_implicit_logout_done()
4276 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_implicit_logout_done()
4285 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_implicit_logout_done()
4286 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_implicit_logout_done()
4290 * __ibmvfc_tgt_get_implicit_logout_evt - Allocate and init an event for implicit logout
4301 struct ibmvfc_host *vhost = tgt->vhost; in __ibmvfc_tgt_get_implicit_logout_evt()
4302 struct ibmvfc_event *evt; in __ibmvfc_tgt_get_implicit_logout_evt() local
4304 kref_get(&tgt->kref); in __ibmvfc_tgt_get_implicit_logout_evt()
4305 evt = ibmvfc_get_reserved_event(&vhost->crq); in __ibmvfc_tgt_get_implicit_logout_evt()
4306 if (!evt) in __ibmvfc_tgt_get_implicit_logout_evt()
4308 ibmvfc_init_event(evt, done, IBMVFC_MAD_FORMAT); in __ibmvfc_tgt_get_implicit_logout_evt()
4309 evt->tgt = tgt; in __ibmvfc_tgt_get_implicit_logout_evt()
4310 mad = &evt->iu.implicit_logout; in __ibmvfc_tgt_get_implicit_logout_evt()
4312 mad->common.version = cpu_to_be32(1); in __ibmvfc_tgt_get_implicit_logout_evt()
4313 mad->common.opcode = cpu_to_be32(IBMVFC_IMPLICIT_LOGOUT); in __ibmvfc_tgt_get_implicit_logout_evt()
4314 mad->common.length = cpu_to_be16(sizeof(*mad)); in __ibmvfc_tgt_get_implicit_logout_evt()
4315 mad->old_scsi_id = cpu_to_be64(tgt->scsi_id); in __ibmvfc_tgt_get_implicit_logout_evt()
4316 return evt; in __ibmvfc_tgt_get_implicit_logout_evt()
4320 * ibmvfc_tgt_implicit_logout - Initiate an Implicit Logout for specified target
4326 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_implicit_logout()
4327 struct ibmvfc_event *evt; in ibmvfc_tgt_implicit_logout() local
4329 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_implicit_logout()
4332 vhost->discovery_threads++; in ibmvfc_tgt_implicit_logout()
4333 evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt, in ibmvfc_tgt_implicit_logout()
4335 if (!evt) { in ibmvfc_tgt_implicit_logout()
4336 vhost->discovery_threads--; in ibmvfc_tgt_implicit_logout()
4338 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_implicit_logout()
4344 if (ibmvfc_send_event(evt, vhost, default_timeout)) { in ibmvfc_tgt_implicit_logout()
4345 vhost->discovery_threads--; in ibmvfc_tgt_implicit_logout()
4347 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_implicit_logout()
4353 * ibmvfc_tgt_implicit_logout_and_del_done - Completion handler for Implicit Logout MAD
4354 * @evt: ibmvfc event struct
4357 static void ibmvfc_tgt_implicit_logout_and_del_done(struct ibmvfc_event *evt) in ibmvfc_tgt_implicit_logout_and_del_done() argument
4359 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_implicit_logout_and_del_done()
4360 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_implicit_logout_and_del_done()
4361 struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru; in ibmvfc_tgt_implicit_logout_and_del_done()
4362 u32 status = be16_to_cpu(mad->common.status); in ibmvfc_tgt_implicit_logout_and_del_done()
4364 vhost->discovery_threads--; in ibmvfc_tgt_implicit_logout_and_del_done()
4365 ibmvfc_free_event(evt); in ibmvfc_tgt_implicit_logout_and_del_done()
4374 if (status == IBMVFC_MAD_SUCCESS || vhost->state == IBMVFC_HOST_OFFLINE) in ibmvfc_tgt_implicit_logout_and_del_done()
4380 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_implicit_logout_and_del_done()
4381 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_implicit_logout_and_del_done()
4385 * ibmvfc_tgt_implicit_logout_and_del - Initiate an Implicit Logout for specified target
4391 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_implicit_logout_and_del()
4392 struct ibmvfc_event *evt; in ibmvfc_tgt_implicit_logout_and_del() local
4394 if (!vhost->logged_in) { in ibmvfc_tgt_implicit_logout_and_del()
4399 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_implicit_logout_and_del()
4402 vhost->discovery_threads++; in ibmvfc_tgt_implicit_logout_and_del()
4403 evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt, in ibmvfc_tgt_implicit_logout_and_del()
4407 if (ibmvfc_send_event(evt, vhost, default_timeout)) { in ibmvfc_tgt_implicit_logout_and_del()
4408 vhost->discovery_threads--; in ibmvfc_tgt_implicit_logout_and_del()
4410 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_implicit_logout_and_del()
4416 * ibmvfc_tgt_move_login_done - Completion handler for Move Login
4417 * @evt: ibmvfc event struct
4420 static void ibmvfc_tgt_move_login_done(struct ibmvfc_event *evt) in ibmvfc_tgt_move_login_done() argument
4422 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_move_login_done()
4423 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_move_login_done()
4424 struct ibmvfc_move_login *rsp = &evt->xfer_iu->move_login; in ibmvfc_tgt_move_login_done()
4425 u32 status = be16_to_cpu(rsp->common.status); in ibmvfc_tgt_move_login_done()
4428 vhost->discovery_threads--; in ibmvfc_tgt_move_login_done()
4432 tgt_dbg(tgt, "Move Login succeeded for new scsi_id: %llX\n", tgt->new_scsi_id); in ibmvfc_tgt_move_login_done()
4433 tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name); in ibmvfc_tgt_move_login_done()
4434 tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name); in ibmvfc_tgt_move_login_done()
4435 tgt->scsi_id = tgt->new_scsi_id; in ibmvfc_tgt_move_login_done()
4436 tgt->ids.port_id = tgt->scsi_id; in ibmvfc_tgt_move_login_done()
4437 memcpy(&tgt->service_parms, &rsp->service_parms, in ibmvfc_tgt_move_login_done()
4438 sizeof(tgt->service_parms)); in ibmvfc_tgt_move_login_done()
4439 memcpy(&tgt->service_parms_change, &rsp->service_parms_change, in ibmvfc_tgt_move_login_done()
4440 sizeof(tgt->service_parms_change)); in ibmvfc_tgt_move_login_done()
4454 tgt->new_scsi_id, be32_to_cpu(rsp->flags), be16_to_cpu(rsp->vios_flags), in ibmvfc_tgt_move_login_done()
4459 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_move_login_done()
4460 ibmvfc_free_event(evt); in ibmvfc_tgt_move_login_done()
4461 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_move_login_done()
4466 * ibmvfc_tgt_move_login - Initiate a move login for specified target
4472 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_move_login()
4474 struct ibmvfc_event *evt; in ibmvfc_tgt_move_login() local
4476 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_move_login()
4479 kref_get(&tgt->kref); in ibmvfc_tgt_move_login()
4480 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_tgt_move_login()
4481 if (!evt) { in ibmvfc_tgt_move_login()
4483 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_move_login()
4487 vhost->discovery_threads++; in ibmvfc_tgt_move_login()
4489 ibmvfc_init_event(evt, ibmvfc_tgt_move_login_done, IBMVFC_MAD_FORMAT); in ibmvfc_tgt_move_login()
4490 evt->tgt = tgt; in ibmvfc_tgt_move_login()
4491 move = &evt->iu.move_login; in ibmvfc_tgt_move_login()
4493 move->common.version = cpu_to_be32(1); in ibmvfc_tgt_move_login()
4494 move->common.opcode = cpu_to_be32(IBMVFC_MOVE_LOGIN); in ibmvfc_tgt_move_login()
4495 move->common.length = cpu_to_be16(sizeof(*move)); in ibmvfc_tgt_move_login()
4497 move->old_scsi_id = cpu_to_be64(tgt->scsi_id); in ibmvfc_tgt_move_login()
4498 move->new_scsi_id = cpu_to_be64(tgt->new_scsi_id); in ibmvfc_tgt_move_login()
4499 move->wwpn = cpu_to_be64(tgt->wwpn); in ibmvfc_tgt_move_login()
4500 move->node_name = cpu_to_be64(tgt->ids.node_name); in ibmvfc_tgt_move_login()
4502 if (ibmvfc_send_event(evt, vhost, default_timeout)) { in ibmvfc_tgt_move_login()
4503 vhost->discovery_threads--; in ibmvfc_tgt_move_login()
4505 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_move_login()
4507 tgt_dbg(tgt, "Sent Move Login for new scsi_id: %llX\n", tgt->new_scsi_id); in ibmvfc_tgt_move_login()
4511 * ibmvfc_adisc_needs_plogi - Does device need PLOGI?
4521 if (wwn_to_u64((u8 *)&mad->fc_iu.response[2]) != tgt->ids.port_name) in ibmvfc_adisc_needs_plogi()
4523 if (wwn_to_u64((u8 *)&mad->fc_iu.response[4]) != tgt->ids.node_name) in ibmvfc_adisc_needs_plogi()
4525 if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id) in ibmvfc_adisc_needs_plogi()
4531 * ibmvfc_tgt_adisc_done - Completion handler for ADISC
4532 * @evt: ibmvfc event struct
4535 static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt) in ibmvfc_tgt_adisc_done() argument
4537 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_adisc_done()
4538 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_adisc_done()
4539 struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru; in ibmvfc_tgt_adisc_done()
4540 u32 status = be16_to_cpu(mad->common.status); in ibmvfc_tgt_adisc_done()
4543 vhost->discovery_threads--; in ibmvfc_tgt_adisc_done()
4545 del_timer(&tgt->timer); in ibmvfc_tgt_adisc_done()
4558 fc_reason = (be32_to_cpu(mad->fc_iu.response[1]) & 0x00ff0000) >> 16; in ibmvfc_tgt_adisc_done()
4559 fc_explain = (be32_to_cpu(mad->fc_iu.response[1]) & 0x0000ff00) >> 8; in ibmvfc_tgt_adisc_done()
4561 ibmvfc_get_cmd_error(be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error)), in ibmvfc_tgt_adisc_done()
4562 be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error), in ibmvfc_tgt_adisc_done()
4568 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_adisc_done()
4569 ibmvfc_free_event(evt); in ibmvfc_tgt_adisc_done()
4570 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_adisc_done()
4574 * ibmvfc_init_passthru - Initialize an event struct for FC passthru
4575 * @evt: ibmvfc event struct
4578 static void ibmvfc_init_passthru(struct ibmvfc_event *evt) in ibmvfc_init_passthru() argument
4580 struct ibmvfc_passthru_mad *mad = &evt->iu.passthru; in ibmvfc_init_passthru()
4583 mad->common.version = cpu_to_be32(1); in ibmvfc_init_passthru()
4584 mad->common.opcode = cpu_to_be32(IBMVFC_PASSTHRU); in ibmvfc_init_passthru()
4585 mad->common.length = cpu_to_be16(sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu)); in ibmvfc_init_passthru()
4586 mad->cmd_ioba.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) + in ibmvfc_init_passthru()
4588 mad->cmd_ioba.len = cpu_to_be32(sizeof(mad->iu)); in ibmvfc_init_passthru()
4589 mad->iu.cmd_len = cpu_to_be32(sizeof(mad->fc_iu.payload)); in ibmvfc_init_passthru()
4590 mad->iu.rsp_len = cpu_to_be32(sizeof(mad->fc_iu.response)); in ibmvfc_init_passthru()
4591 mad->iu.cmd.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) + in ibmvfc_init_passthru()
4594 mad->iu.cmd.len = cpu_to_be32(sizeof(mad->fc_iu.payload)); in ibmvfc_init_passthru()
4595 mad->iu.rsp.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) + in ibmvfc_init_passthru()
4598 mad->iu.rsp.len = cpu_to_be32(sizeof(mad->fc_iu.response)); in ibmvfc_init_passthru()
4602 * ibmvfc_tgt_adisc_cancel_done - Completion handler when cancelling an ADISC
4603 * @evt: ibmvfc event struct
4611 static void ibmvfc_tgt_adisc_cancel_done(struct ibmvfc_event *evt) in ibmvfc_tgt_adisc_cancel_done() argument
4613 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_adisc_cancel_done()
4614 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_adisc_cancel_done()
4617 vhost->abort_threads--; in ibmvfc_tgt_adisc_cancel_done()
4618 ibmvfc_free_event(evt); in ibmvfc_tgt_adisc_cancel_done()
4619 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_adisc_cancel_done()
4620 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_adisc_cancel_done()
4624 * ibmvfc_adisc_timeout - Handle an ADISC timeout
4634 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_adisc_timeout()
4635 struct ibmvfc_event *evt; in ibmvfc_adisc_timeout() local
4641 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_adisc_timeout()
4642 if (vhost->abort_threads >= disc_threads || in ibmvfc_adisc_timeout()
4643 tgt->action != IBMVFC_TGT_ACTION_INIT_WAIT || in ibmvfc_adisc_timeout()
4644 vhost->state != IBMVFC_INITIALIZING || in ibmvfc_adisc_timeout()
4645 vhost->action != IBMVFC_HOST_ACTION_QUERY_TGTS) { in ibmvfc_adisc_timeout()
4646 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_adisc_timeout()
4650 vhost->abort_threads++; in ibmvfc_adisc_timeout()
4651 kref_get(&tgt->kref); in ibmvfc_adisc_timeout()
4652 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_adisc_timeout()
4653 if (!evt) { in ibmvfc_adisc_timeout()
4655 vhost->abort_threads--; in ibmvfc_adisc_timeout()
4656 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_adisc_timeout()
4658 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_adisc_timeout()
4661 ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT); in ibmvfc_adisc_timeout()
4663 evt->tgt = tgt; in ibmvfc_adisc_timeout()
4664 tmf = &evt->iu.tmf; in ibmvfc_adisc_timeout()
4667 tmf->common.version = cpu_to_be32(2); in ibmvfc_adisc_timeout()
4668 tmf->target_wwpn = cpu_to_be64(tgt->wwpn); in ibmvfc_adisc_timeout()
4670 tmf->common.version = cpu_to_be32(1); in ibmvfc_adisc_timeout()
4672 tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD); in ibmvfc_adisc_timeout()
4673 tmf->common.length = cpu_to_be16(sizeof(*tmf)); in ibmvfc_adisc_timeout()
4674 tmf->scsi_id = cpu_to_be64(tgt->scsi_id); in ibmvfc_adisc_timeout()
4675 tmf->cancel_key = cpu_to_be32(tgt->cancel_key); in ibmvfc_adisc_timeout()
4677 rc = ibmvfc_send_event(evt, vhost, default_timeout); in ibmvfc_adisc_timeout()
4681 vhost->abort_threads--; in ibmvfc_adisc_timeout()
4682 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_adisc_timeout()
4686 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_adisc_timeout()
4690 * ibmvfc_tgt_adisc - Initiate an ADISC for specified target
4703 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_adisc()
4704 struct ibmvfc_event *evt; in ibmvfc_tgt_adisc() local
4706 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_adisc()
4709 kref_get(&tgt->kref); in ibmvfc_tgt_adisc()
4710 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_tgt_adisc()
4711 if (!evt) { in ibmvfc_tgt_adisc()
4713 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_adisc()
4717 vhost->discovery_threads++; in ibmvfc_tgt_adisc()
4718 ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); in ibmvfc_tgt_adisc()
4719 evt->tgt = tgt; in ibmvfc_tgt_adisc()
4721 ibmvfc_init_passthru(evt); in ibmvfc_tgt_adisc()
4722 mad = &evt->iu.passthru; in ibmvfc_tgt_adisc()
4723 mad->iu.flags = cpu_to_be32(IBMVFC_FC_ELS); in ibmvfc_tgt_adisc()
4724 mad->iu.scsi_id = cpu_to_be64(tgt->scsi_id); in ibmvfc_tgt_adisc()
4725 mad->iu.cancel_key = cpu_to_be32(tgt->cancel_key); in ibmvfc_tgt_adisc()
4727 mad->fc_iu.payload[0] = cpu_to_be32(IBMVFC_ADISC); in ibmvfc_tgt_adisc()
4728 memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name, in ibmvfc_tgt_adisc()
4729 sizeof(vhost->login_buf->resp.port_name)); in ibmvfc_tgt_adisc()
4730 memcpy(&mad->fc_iu.payload[4], &vhost->login_buf->resp.node_name, in ibmvfc_tgt_adisc()
4731 sizeof(vhost->login_buf->resp.node_name)); in ibmvfc_tgt_adisc()
4732 mad->fc_iu.payload[6] = cpu_to_be32(be64_to_cpu(vhost->login_buf->resp.scsi_id) & 0x00ffffff); in ibmvfc_tgt_adisc()
4734 if (timer_pending(&tgt->timer)) in ibmvfc_tgt_adisc()
4735 mod_timer(&tgt->timer, jiffies + (IBMVFC_ADISC_TIMEOUT * HZ)); in ibmvfc_tgt_adisc()
4737 tgt->timer.expires = jiffies + (IBMVFC_ADISC_TIMEOUT * HZ); in ibmvfc_tgt_adisc()
4738 add_timer(&tgt->timer); in ibmvfc_tgt_adisc()
4742 if (ibmvfc_send_event(evt, vhost, IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT)) { in ibmvfc_tgt_adisc()
4743 vhost->discovery_threads--; in ibmvfc_tgt_adisc()
4744 del_timer(&tgt->timer); in ibmvfc_tgt_adisc()
4746 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_adisc()
4752 * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD
4753 * @evt: ibmvfc event struct
4756 static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt) in ibmvfc_tgt_query_target_done() argument
4758 struct ibmvfc_target *tgt = evt->tgt; in ibmvfc_tgt_query_target_done()
4759 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_tgt_query_target_done()
4760 struct ibmvfc_query_tgt *rsp = &evt->xfer_iu->query_tgt; in ibmvfc_tgt_query_target_done()
4761 u32 status = be16_to_cpu(rsp->common.status); in ibmvfc_tgt_query_target_done()
4764 vhost->discovery_threads--; in ibmvfc_tgt_query_target_done()
4769 if (be64_to_cpu(rsp->scsi_id) != tgt->scsi_id) in ibmvfc_tgt_query_target_done()
4781 if ((be16_to_cpu(rsp->status) & IBMVFC_FABRIC_MAPPED) == IBMVFC_FABRIC_MAPPED && in ibmvfc_tgt_query_target_done()
4782 be16_to_cpu(rsp->error) == IBMVFC_UNABLE_TO_PERFORM_REQ && in ibmvfc_tgt_query_target_done()
4783 be16_to_cpu(rsp->fc_explain) == IBMVFC_PORT_NAME_NOT_REG) in ibmvfc_tgt_query_target_done()
4785 else if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error))) in ibmvfc_tgt_query_target_done()
4791 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), in ibmvfc_tgt_query_target_done()
4792 be16_to_cpu(rsp->status), be16_to_cpu(rsp->error), in ibmvfc_tgt_query_target_done()
4793 ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), be16_to_cpu(rsp->fc_type), in ibmvfc_tgt_query_target_done()
4794 ibmvfc_get_gs_explain(be16_to_cpu(rsp->fc_explain)), be16_to_cpu(rsp->fc_explain), in ibmvfc_tgt_query_target_done()
4799 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_query_target_done()
4800 ibmvfc_free_event(evt); in ibmvfc_tgt_query_target_done()
4801 wake_up(&vhost->work_wait_q); in ibmvfc_tgt_query_target_done()
4805 * ibmvfc_tgt_query_target - Initiate a Query Target for specified target
4812 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_query_target()
4813 struct ibmvfc_event *evt; in ibmvfc_tgt_query_target() local
4815 if (vhost->discovery_threads >= disc_threads) in ibmvfc_tgt_query_target()
4818 kref_get(&tgt->kref); in ibmvfc_tgt_query_target()
4819 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_tgt_query_target()
4820 if (!evt) { in ibmvfc_tgt_query_target()
4822 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_query_target()
4826 vhost->discovery_threads++; in ibmvfc_tgt_query_target()
4827 evt->tgt = tgt; in ibmvfc_tgt_query_target()
4828 ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT); in ibmvfc_tgt_query_target()
4829 query_tgt = &evt->iu.query_tgt; in ibmvfc_tgt_query_target()
4831 query_tgt->common.version = cpu_to_be32(1); in ibmvfc_tgt_query_target()
4832 query_tgt->common.opcode = cpu_to_be32(IBMVFC_QUERY_TARGET); in ibmvfc_tgt_query_target()
4833 query_tgt->common.length = cpu_to_be16(sizeof(*query_tgt)); in ibmvfc_tgt_query_target()
4834 query_tgt->wwpn = cpu_to_be64(tgt->ids.port_name); in ibmvfc_tgt_query_target()
4837 if (ibmvfc_send_event(evt, vhost, default_timeout)) { in ibmvfc_tgt_query_target()
4838 vhost->discovery_threads--; in ibmvfc_tgt_query_target()
4840 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_query_target()
4846 * ibmvfc_alloc_target - Allocate and initialize an ibmvfc target
4860 u64 scsi_id = be32_to_cpu(target->scsi_id) & IBMVFC_DISC_TGT_SCSI_ID_MASK; in ibmvfc_alloc_target()
4861 u64 wwpn = be64_to_cpu(target->wwpn); in ibmvfc_alloc_target()
4864 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_alloc_target()
4865 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_alloc_target()
4866 if (tgt->wwpn == wwpn) { in ibmvfc_alloc_target()
4872 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_alloc_target()
4873 if (tgt->scsi_id == scsi_id) { in ibmvfc_alloc_target()
4893 if (wtgt->action == IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT) { in ibmvfc_alloc_target()
4894 if (wtgt->move_login) { in ibmvfc_alloc_target()
4901 wtgt->new_scsi_id = scsi_id; in ibmvfc_alloc_target()
4902 wtgt->action = IBMVFC_TGT_ACTION_INIT; in ibmvfc_alloc_target()
4903 wtgt->init_retries = 0; in ibmvfc_alloc_target()
4909 wtgt->action, wtgt->rport); in ibmvfc_alloc_target()
4912 if (tgt->need_login) in ibmvfc_alloc_target()
4916 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_alloc_target()
4918 tgt = mempool_alloc(vhost->tgt_pool, GFP_NOIO); in ibmvfc_alloc_target()
4920 tgt->scsi_id = scsi_id; in ibmvfc_alloc_target()
4921 tgt->wwpn = wwpn; in ibmvfc_alloc_target()
4922 tgt->vhost = vhost; in ibmvfc_alloc_target()
4923 tgt->need_login = 1; in ibmvfc_alloc_target()
4924 timer_setup(&tgt->timer, ibmvfc_adisc_timeout, 0); in ibmvfc_alloc_target()
4925 kref_init(&tgt->kref); in ibmvfc_alloc_target()
4927 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_alloc_target()
4928 tgt->cancel_key = vhost->task_set++; in ibmvfc_alloc_target()
4929 list_add_tail(&tgt->queue, &vhost->targets); in ibmvfc_alloc_target()
4932 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_alloc_target()
4937 * ibmvfc_alloc_targets - Allocate and initialize ibmvfc targets
4947 for (i = 0, rc = 0; !rc && i < vhost->num_targets; i++) in ibmvfc_alloc_targets()
4948 rc = ibmvfc_alloc_target(vhost, &vhost->scsi_scrqs.disc_buf[i]); in ibmvfc_alloc_targets()
4954 * ibmvfc_discover_targets_done - Completion handler for discover targets MAD
4955 * @evt: ibmvfc event struct
4958 static void ibmvfc_discover_targets_done(struct ibmvfc_event *evt) in ibmvfc_discover_targets_done() argument
4960 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_discover_targets_done()
4961 struct ibmvfc_discover_targets *rsp = &evt->xfer_iu->discover_targets; in ibmvfc_discover_targets_done()
4962 u32 mad_status = be16_to_cpu(rsp->common.status); in ibmvfc_discover_targets_done()
4968 vhost->num_targets = be32_to_cpu(rsp->num_written); in ibmvfc_discover_targets_done()
4974 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), in ibmvfc_discover_targets_done()
4975 be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)); in ibmvfc_discover_targets_done()
4980 dev_err(vhost->dev, "Invalid Discover Targets response: 0x%x\n", mad_status); in ibmvfc_discover_targets_done()
4985 ibmvfc_free_event(evt); in ibmvfc_discover_targets_done()
4986 wake_up(&vhost->work_wait_q); in ibmvfc_discover_targets_done()
4990 * ibmvfc_discover_targets - Send Discover Targets MAD
4997 struct ibmvfc_event *evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_discover_targets() local
5000 if (!evt) { in ibmvfc_discover_targets()
5006 ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT); in ibmvfc_discover_targets()
5007 mad = &evt->iu.discover_targets; in ibmvfc_discover_targets()
5009 mad->common.version = cpu_to_be32(1); in ibmvfc_discover_targets()
5010 mad->common.opcode = cpu_to_be32(IBMVFC_DISC_TARGETS); in ibmvfc_discover_targets()
5011 mad->common.length = cpu_to_be16(sizeof(*mad)); in ibmvfc_discover_targets()
5012 mad->bufflen = cpu_to_be32(vhost->scsi_scrqs.disc_buf_sz); in ibmvfc_discover_targets()
5013 mad->buffer.va = cpu_to_be64(vhost->scsi_scrqs.disc_buf_dma); in ibmvfc_discover_targets()
5014 mad->buffer.len = cpu_to_be32(vhost->scsi_scrqs.disc_buf_sz); in ibmvfc_discover_targets()
5015 mad->flags = cpu_to_be32(IBMVFC_DISC_TGT_PORT_ID_WWPN_LIST); in ibmvfc_discover_targets()
5018 if (!ibmvfc_send_event(evt, vhost, default_timeout)) in ibmvfc_discover_targets()
5024 static void ibmvfc_channel_setup_done(struct ibmvfc_event *evt) in ibmvfc_channel_setup_done() argument
5026 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_channel_setup_done()
5027 struct ibmvfc_channel_setup *setup = vhost->channel_setup_buf; in ibmvfc_channel_setup_done()
5028 struct ibmvfc_channels *scrqs = &vhost->scsi_scrqs; in ibmvfc_channel_setup_done()
5029 u32 mad_status = be16_to_cpu(evt->xfer_iu->channel_setup.common.status); in ibmvfc_channel_setup_done()
5033 ibmvfc_free_event(evt); in ibmvfc_channel_setup_done()
5038 flags = be32_to_cpu(setup->flags); in ibmvfc_channel_setup_done()
5039 vhost->do_enquiry = 0; in ibmvfc_channel_setup_done()
5040 active_queues = be32_to_cpu(setup->num_scsi_subq_channels); in ibmvfc_channel_setup_done()
5041 scrqs->active_queues = active_queues; in ibmvfc_channel_setup_done()
5045 vhost->using_channels = 0; in ibmvfc_channel_setup_done()
5048 vhost->using_channels = 1; in ibmvfc_channel_setup_done()
5050 scrqs->scrqs[i].vios_cookie = in ibmvfc_channel_setup_done()
5051 be64_to_cpu(setup->channel_handles[i]); in ibmvfc_channel_setup_done()
5054 vhost->scsi_scrqs.active_queues); in ibmvfc_channel_setup_done()
5064 dev_err(vhost->dev, "Invalid Channel Setup response: 0x%x\n", in ibmvfc_channel_setup_done()
5071 wake_up(&vhost->work_wait_q); in ibmvfc_channel_setup_done()
5077 struct ibmvfc_channel_setup *setup_buf = vhost->channel_setup_buf; in ibmvfc_channel_setup()
5078 struct ibmvfc_event *evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_channel_setup() local
5079 struct ibmvfc_channels *scrqs = &vhost->scsi_scrqs; in ibmvfc_channel_setup()
5081 min(scrqs->desired_queues, vhost->max_vios_scsi_channels); in ibmvfc_channel_setup()
5085 if (!evt) { in ibmvfc_channel_setup()
5093 setup_buf->flags = cpu_to_be32(IBMVFC_CANCEL_CHANNELS); in ibmvfc_channel_setup()
5095 setup_buf->num_scsi_subq_channels = cpu_to_be32(num_channels); in ibmvfc_channel_setup()
5097 setup_buf->channel_handles[i] = cpu_to_be64(scrqs->scrqs[i].cookie); in ibmvfc_channel_setup()
5100 ibmvfc_init_event(evt, ibmvfc_channel_setup_done, IBMVFC_MAD_FORMAT); in ibmvfc_channel_setup()
5101 mad = &evt->iu.channel_setup; in ibmvfc_channel_setup()
5103 mad->common.version = cpu_to_be32(1); in ibmvfc_channel_setup()
5104 mad->common.opcode = cpu_to_be32(IBMVFC_CHANNEL_SETUP); in ibmvfc_channel_setup()
5105 mad->common.length = cpu_to_be16(sizeof(*mad)); in ibmvfc_channel_setup()
5106 mad->buffer.va = cpu_to_be64(vhost->channel_setup_dma); in ibmvfc_channel_setup()
5107 mad->buffer.len = cpu_to_be32(sizeof(*vhost->channel_setup_buf)); in ibmvfc_channel_setup()
5111 if (!ibmvfc_send_event(evt, vhost, default_timeout)) in ibmvfc_channel_setup()
5117 static void ibmvfc_channel_enquiry_done(struct ibmvfc_event *evt) in ibmvfc_channel_enquiry_done() argument
5119 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_channel_enquiry_done()
5120 struct ibmvfc_channel_enquiry *rsp = &evt->xfer_iu->channel_enquiry; in ibmvfc_channel_enquiry_done()
5121 u32 mad_status = be16_to_cpu(rsp->common.status); in ibmvfc_channel_enquiry_done()
5127 vhost->max_vios_scsi_channels = be32_to_cpu(rsp->num_scsi_subq_channels); in ibmvfc_channel_enquiry_done()
5128 ibmvfc_free_event(evt); in ibmvfc_channel_enquiry_done()
5135 ibmvfc_free_event(evt); in ibmvfc_channel_enquiry_done()
5138 dev_err(vhost->dev, "Invalid Channel Enquiry response: 0x%x\n", in ibmvfc_channel_enquiry_done()
5141 ibmvfc_free_event(evt); in ibmvfc_channel_enquiry_done()
5151 struct ibmvfc_event *evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_channel_enquiry() local
5154 if (!evt) { in ibmvfc_channel_enquiry()
5160 ibmvfc_init_event(evt, ibmvfc_channel_enquiry_done, IBMVFC_MAD_FORMAT); in ibmvfc_channel_enquiry()
5161 mad = &evt->iu.channel_enquiry; in ibmvfc_channel_enquiry()
5163 mad->common.version = cpu_to_be32(1); in ibmvfc_channel_enquiry()
5164 mad->common.opcode = cpu_to_be32(IBMVFC_CHANNEL_ENQUIRY); in ibmvfc_channel_enquiry()
5165 mad->common.length = cpu_to_be16(sizeof(*mad)); in ibmvfc_channel_enquiry()
5168 mad->flags |= cpu_to_be32(IBMVFC_NO_CHANNELS_TO_CRQ_SUPPORT); in ibmvfc_channel_enquiry()
5170 mad->flags |= cpu_to_be32(IBMVFC_NO_N_TO_M_CHANNELS_SUPPORT); in ibmvfc_channel_enquiry()
5174 if (!ibmvfc_send_event(evt, vhost, default_timeout)) in ibmvfc_channel_enquiry()
5181 * ibmvfc_npiv_login_done - Completion handler for NPIV Login
5182 * @evt: ibmvfc event struct
5185 static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt) in ibmvfc_npiv_login_done() argument
5187 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_npiv_login_done()
5188 u32 mad_status = be16_to_cpu(evt->xfer_iu->npiv_login.common.status); in ibmvfc_npiv_login_done()
5189 struct ibmvfc_npiv_login_resp *rsp = &vhost->login_buf->resp; in ibmvfc_npiv_login_done()
5195 ibmvfc_free_event(evt); in ibmvfc_npiv_login_done()
5198 if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error))) in ibmvfc_npiv_login_done()
5203 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), in ibmvfc_npiv_login_done()
5204 be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)); in ibmvfc_npiv_login_done()
5205 ibmvfc_free_event(evt); in ibmvfc_npiv_login_done()
5211 ibmvfc_free_event(evt); in ibmvfc_npiv_login_done()
5214 dev_err(vhost->dev, "Invalid NPIV Login response: 0x%x\n", mad_status); in ibmvfc_npiv_login_done()
5216 ibmvfc_free_event(evt); in ibmvfc_npiv_login_done()
5220 vhost->client_migrated = 0; in ibmvfc_npiv_login_done()
5222 if (!(be32_to_cpu(rsp->flags) & IBMVFC_NATIVE_FC)) { in ibmvfc_npiv_login_done()
5223 dev_err(vhost->dev, "Virtual adapter does not support FC. %x\n", in ibmvfc_npiv_login_done()
5224 rsp->flags); in ibmvfc_npiv_login_done()
5226 wake_up(&vhost->work_wait_q); in ibmvfc_npiv_login_done()
5230 if (be32_to_cpu(rsp->max_cmds) <= IBMVFC_NUM_INTERNAL_REQ) { in ibmvfc_npiv_login_done()
5231 dev_err(vhost->dev, "Virtual adapter supported queue depth too small: %d\n", in ibmvfc_npiv_login_done()
5232 rsp->max_cmds); in ibmvfc_npiv_login_done()
5234 wake_up(&vhost->work_wait_q); in ibmvfc_npiv_login_done()
5238 vhost->logged_in = 1; in ibmvfc_npiv_login_done()
5239 npiv_max_sectors = min((uint)(be64_to_cpu(rsp->max_dma_len) >> 9), max_sectors); in ibmvfc_npiv_login_done()
5240 dev_info(vhost->dev, "Host partition: %s, device: %s %s %s max sectors %u\n", in ibmvfc_npiv_login_done()
5241 rsp->partition_name, rsp->device_name, rsp->port_loc_code, in ibmvfc_npiv_login_done()
5242 rsp->drc_name, npiv_max_sectors); in ibmvfc_npiv_login_done()
5244 fc_host_fabric_name(vhost->host) = be64_to_cpu(rsp->node_name); in ibmvfc_npiv_login_done()
5245 fc_host_node_name(vhost->host) = be64_to_cpu(rsp->node_name); in ibmvfc_npiv_login_done()
5246 fc_host_port_name(vhost->host) = be64_to_cpu(rsp->port_name); in ibmvfc_npiv_login_done()
5247 fc_host_port_id(vhost->host) = be64_to_cpu(rsp->scsi_id); in ibmvfc_npiv_login_done()
5248 fc_host_port_type(vhost->host) = FC_PORTTYPE_NPIV; in ibmvfc_npiv_login_done()
5249 fc_host_supported_classes(vhost->host) = 0; in ibmvfc_npiv_login_done()
5250 if (be32_to_cpu(rsp->service_parms.class1_parms[0]) & 0x80000000) in ibmvfc_npiv_login_done()
5251 fc_host_supported_classes(vhost->host) |= FC_COS_CLASS1; in ibmvfc_npiv_login_done()
5252 if (be32_to_cpu(rsp->service_parms.class2_parms[0]) & 0x80000000) in ibmvfc_npiv_login_done()
5253 fc_host_supported_classes(vhost->host) |= FC_COS_CLASS2; in ibmvfc_npiv_login_done()
5254 if (be32_to_cpu(rsp->service_parms.class3_parms[0]) & 0x80000000) in ibmvfc_npiv_login_done()
5255 fc_host_supported_classes(vhost->host) |= FC_COS_CLASS3; in ibmvfc_npiv_login_done()
5256 fc_host_maxframe_size(vhost->host) = in ibmvfc_npiv_login_done()
5257 be16_to_cpu(rsp->service_parms.common.bb_rcv_sz) & 0x0fff; in ibmvfc_npiv_login_done()
5259 vhost->host->can_queue = be32_to_cpu(rsp->max_cmds) - IBMVFC_NUM_INTERNAL_REQ; in ibmvfc_npiv_login_done()
5260 vhost->host->max_sectors = npiv_max_sectors; in ibmvfc_npiv_login_done()
5262 if (ibmvfc_check_caps(vhost, IBMVFC_CAN_SUPPORT_CHANNELS) && vhost->do_enquiry) { in ibmvfc_npiv_login_done()
5265 vhost->do_enquiry = 0; in ibmvfc_npiv_login_done()
5267 wake_up(&vhost->work_wait_q); in ibmvfc_npiv_login_done()
5272 * ibmvfc_npiv_login - Sends NPIV login
5279 struct ibmvfc_event *evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_npiv_login() local
5281 if (!evt) { in ibmvfc_npiv_login()
5289 ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT); in ibmvfc_npiv_login()
5291 memcpy(vhost->login_buf, &vhost->login_info, sizeof(vhost->login_info)); in ibmvfc_npiv_login()
5292 mad = &evt->iu.npiv_login; in ibmvfc_npiv_login()
5294 mad->common.version = cpu_to_be32(1); in ibmvfc_npiv_login()
5295 mad->common.opcode = cpu_to_be32(IBMVFC_NPIV_LOGIN); in ibmvfc_npiv_login()
5296 mad->common.length = cpu_to_be16(sizeof(struct ibmvfc_npiv_login_mad)); in ibmvfc_npiv_login()
5297 mad->buffer.va = cpu_to_be64(vhost->login_buf_dma); in ibmvfc_npiv_login()
5298 mad->buffer.len = cpu_to_be32(sizeof(*vhost->login_buf)); in ibmvfc_npiv_login()
5302 if (!ibmvfc_send_event(evt, vhost, default_timeout)) in ibmvfc_npiv_login()
5309 * ibmvfc_npiv_logout_done - Completion handler for NPIV Logout
5310 * @evt: ibmvfc event struct
5313 static void ibmvfc_npiv_logout_done(struct ibmvfc_event *evt) in ibmvfc_npiv_logout_done() argument
5315 struct ibmvfc_host *vhost = evt->vhost; in ibmvfc_npiv_logout_done()
5316 u32 mad_status = be16_to_cpu(evt->xfer_iu->npiv_logout.common.status); in ibmvfc_npiv_logout_done()
5318 ibmvfc_free_event(evt); in ibmvfc_npiv_logout_done()
5322 if (list_empty(&vhost->crq.sent) && in ibmvfc_npiv_logout_done()
5323 vhost->action == IBMVFC_HOST_ACTION_LOGO_WAIT) { in ibmvfc_npiv_logout_done()
5341 * ibmvfc_npiv_logout - Issue an NPIV Logout
5348 struct ibmvfc_event *evt; in ibmvfc_npiv_logout() local
5350 evt = ibmvfc_get_reserved_event(&vhost->crq); in ibmvfc_npiv_logout()
5351 if (!evt) { in ibmvfc_npiv_logout()
5357 ibmvfc_init_event(evt, ibmvfc_npiv_logout_done, IBMVFC_MAD_FORMAT); in ibmvfc_npiv_logout()
5359 mad = &evt->iu.npiv_logout; in ibmvfc_npiv_logout()
5361 mad->common.version = cpu_to_be32(1); in ibmvfc_npiv_logout()
5362 mad->common.opcode = cpu_to_be32(IBMVFC_NPIV_LOGOUT); in ibmvfc_npiv_logout()
5363 mad->common.length = cpu_to_be16(sizeof(struct ibmvfc_npiv_logout_mad)); in ibmvfc_npiv_logout()
5367 if (!ibmvfc_send_event(evt, vhost, default_timeout)) in ibmvfc_npiv_logout()
5374 * ibmvfc_dev_init_to_do - Is there target initialization work to do?
5384 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_dev_init_to_do()
5385 if (tgt->action == IBMVFC_TGT_ACTION_INIT || in ibmvfc_dev_init_to_do()
5386 tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT) in ibmvfc_dev_init_to_do()
5394 * ibmvfc_dev_logo_to_do - Is there target logout work to do?
5404 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_dev_logo_to_do()
5405 if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT || in ibmvfc_dev_logo_to_do()
5406 tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT) in ibmvfc_dev_logo_to_do()
5413 * __ibmvfc_work_to_do - Is there task level work to do? (no locking)
5425 switch (vhost->action) { in __ibmvfc_work_to_do()
5432 if (vhost->discovery_threads == disc_threads) in __ibmvfc_work_to_do()
5434 list_for_each_entry(tgt, &vhost->targets, queue) in __ibmvfc_work_to_do()
5435 if (tgt->action == IBMVFC_TGT_ACTION_INIT) in __ibmvfc_work_to_do()
5437 list_for_each_entry(tgt, &vhost->targets, queue) in __ibmvfc_work_to_do()
5438 if (tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT) in __ibmvfc_work_to_do()
5443 if (vhost->discovery_threads == disc_threads) in __ibmvfc_work_to_do()
5445 list_for_each_entry(tgt, &vhost->targets, queue) in __ibmvfc_work_to_do()
5446 if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT) in __ibmvfc_work_to_do()
5448 list_for_each_entry(tgt, &vhost->targets, queue) in __ibmvfc_work_to_do()
5449 if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT) in __ibmvfc_work_to_do()
5466 * ibmvfc_work_to_do - Is there task level work to do?
5477 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_work_to_do()
5479 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_work_to_do()
5484 * ibmvfc_log_ae - Log async events if necessary
5492 fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_RSCN, 0); in ibmvfc_log_ae()
5494 vhost->state >= IBMVFC_HALTED) in ibmvfc_log_ae()
5495 fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_LINKDOWN, 0); in ibmvfc_log_ae()
5497 vhost->state == IBMVFC_INITIALIZING) in ibmvfc_log_ae()
5498 fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_LINKUP, 0); in ibmvfc_log_ae()
5502 * ibmvfc_tgt_add_rport - Tell the FC transport about a new remote port
5508 struct ibmvfc_host *vhost = tgt->vhost; in ibmvfc_tgt_add_rport()
5513 rport = fc_remote_port_add(vhost->host, 0, &tgt->ids); in ibmvfc_tgt_add_rport()
5514 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_tgt_add_rport()
5516 if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { in ibmvfc_tgt_add_rport()
5518 list_del(&tgt->queue); in ibmvfc_tgt_add_rport()
5520 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_tgt_add_rport()
5522 del_timer_sync(&tgt->timer); in ibmvfc_tgt_add_rport()
5523 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_tgt_add_rport()
5525 } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) { in ibmvfc_tgt_add_rport()
5528 tgt->rport = NULL; in ibmvfc_tgt_add_rport()
5529 tgt->init_retries = 0; in ibmvfc_tgt_add_rport()
5530 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_tgt_add_rport()
5533 } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) { in ibmvfc_tgt_add_rport()
5534 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_tgt_add_rport()
5540 tgt->rport = rport; in ibmvfc_tgt_add_rport()
5541 rport->maxframe_size = be16_to_cpu(tgt->service_parms.common.bb_rcv_sz) & 0x0fff; in ibmvfc_tgt_add_rport()
5542 rport->supported_classes = 0; in ibmvfc_tgt_add_rport()
5543 tgt->target_id = rport->scsi_target_id; in ibmvfc_tgt_add_rport()
5544 if (be32_to_cpu(tgt->service_parms.class1_parms[0]) & 0x80000000) in ibmvfc_tgt_add_rport()
5545 rport->supported_classes |= FC_COS_CLASS1; in ibmvfc_tgt_add_rport()
5546 if (be32_to_cpu(tgt->service_parms.class2_parms[0]) & 0x80000000) in ibmvfc_tgt_add_rport()
5547 rport->supported_classes |= FC_COS_CLASS2; in ibmvfc_tgt_add_rport()
5548 if (be32_to_cpu(tgt->service_parms.class3_parms[0]) & 0x80000000) in ibmvfc_tgt_add_rport()
5549 rport->supported_classes |= FC_COS_CLASS3; in ibmvfc_tgt_add_rport()
5552 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_tgt_add_rport()
5556 * ibmvfc_do_work - Do task level work
5568 ibmvfc_log_ae(vhost, vhost->events_to_log); in ibmvfc_do_work()
5569 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_do_work()
5570 vhost->events_to_log = 0; in ibmvfc_do_work()
5571 switch (vhost->action) { in ibmvfc_do_work()
5577 list_splice_init(&vhost->purge, &purge); in ibmvfc_do_work()
5578 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5582 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_do_work()
5584 vio_enable_interrupts(to_vio_dev(vhost->dev)); in ibmvfc_do_work()
5585 if (vhost->action == IBMVFC_HOST_ACTION_RESET) { in ibmvfc_do_work()
5589 * this path and wait until we've done the re-enable in ibmvfc_do_work()
5592 vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; in ibmvfc_do_work()
5595 (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { in ibmvfc_do_work()
5597 dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc); in ibmvfc_do_work()
5602 list_splice_init(&vhost->purge, &purge); in ibmvfc_do_work()
5603 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5607 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_do_work()
5608 if (vhost->action == IBMVFC_HOST_ACTION_REENABLE) { in ibmvfc_do_work()
5615 vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; in ibmvfc_do_work()
5618 dev_err(vhost->dev, "Error after enable (rc=%d)\n", rc); in ibmvfc_do_work()
5623 vhost->job_step(vhost); in ibmvfc_do_work()
5626 BUG_ON(vhost->state != IBMVFC_INITIALIZING); in ibmvfc_do_work()
5627 if (vhost->delay_init) { in ibmvfc_do_work()
5628 vhost->delay_init = 0; in ibmvfc_do_work()
5629 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5633 vhost->job_step(vhost); in ibmvfc_do_work()
5636 list_for_each_entry(tgt, &vhost->targets, queue) in ibmvfc_do_work()
5641 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_do_work()
5642 if (tgt->action == IBMVFC_TGT_ACTION_INIT) { in ibmvfc_do_work()
5643 tgt->job_step(tgt); in ibmvfc_do_work()
5653 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_do_work()
5654 if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT) { in ibmvfc_do_work()
5655 tgt->job_step(tgt); in ibmvfc_do_work()
5661 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5665 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_do_work()
5666 if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { in ibmvfc_do_work()
5668 rport = tgt->rport; in ibmvfc_do_work()
5669 tgt->rport = NULL; in ibmvfc_do_work()
5670 list_del(&tgt->queue); in ibmvfc_do_work()
5672 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5675 del_timer_sync(&tgt->timer); in ibmvfc_do_work()
5676 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_do_work()
5678 } else if (tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) { in ibmvfc_do_work()
5680 rport = tgt->rport; in ibmvfc_do_work()
5681 tgt->rport = NULL; in ibmvfc_do_work()
5682 tgt->init_retries = 0; in ibmvfc_do_work()
5694 if (rport && rport->fast_io_fail_tmo == -1) in ibmvfc_do_work()
5695 tgt->move_login = 1; in ibmvfc_do_work()
5696 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5703 if (vhost->state == IBMVFC_INITIALIZING) { in ibmvfc_do_work()
5704 if (vhost->action == IBMVFC_HOST_ACTION_TGT_DEL_FAILED) { in ibmvfc_do_work()
5705 if (vhost->reinit) { in ibmvfc_do_work()
5706 vhost->reinit = 0; in ibmvfc_do_work()
5707 scsi_block_requests(vhost->host); in ibmvfc_do_work()
5709 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5713 wake_up(&vhost->init_wait_q); in ibmvfc_do_work()
5714 schedule_work(&vhost->rport_add_work_q); in ibmvfc_do_work()
5715 vhost->init_retries = 0; in ibmvfc_do_work()
5716 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5717 scsi_unblock_requests(vhost->host); in ibmvfc_do_work()
5723 vhost->job_step = ibmvfc_discover_targets; in ibmvfc_do_work()
5727 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5728 scsi_unblock_requests(vhost->host); in ibmvfc_do_work()
5729 wake_up(&vhost->init_wait_q); in ibmvfc_do_work()
5735 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5737 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_do_work()
5740 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_do_work()
5741 if (tgt->action == IBMVFC_TGT_ACTION_INIT) { in ibmvfc_do_work()
5742 tgt->job_step(tgt); in ibmvfc_do_work()
5754 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_do_work()
5758 * ibmvfc_work - Do task level work
5772 rc = wait_event_interruptible(vhost->work_wait_q, in ibmvfc_work()
5788 * ibmvfc_alloc_queue - Allocate queue
5794 * 0 on success / non-zero on failure
5800 struct device *dev = vhost->dev; in ibmvfc_alloc_queue()
5804 spin_lock_init(&queue->_lock); in ibmvfc_alloc_queue()
5805 queue->q_lock = &queue->_lock; in ibmvfc_alloc_queue()
5809 fmt_size = sizeof(*queue->msgs.crq); in ibmvfc_alloc_queue()
5810 queue->total_depth = scsi_qdepth + IBMVFC_NUM_INTERNAL_REQ; in ibmvfc_alloc_queue()
5811 queue->evt_depth = scsi_qdepth; in ibmvfc_alloc_queue()
5812 queue->reserved_depth = IBMVFC_NUM_INTERNAL_REQ; in ibmvfc_alloc_queue()
5815 fmt_size = sizeof(*queue->msgs.async); in ibmvfc_alloc_queue()
5818 fmt_size = sizeof(*queue->msgs.scrq); in ibmvfc_alloc_queue()
5820 queue->total_depth = scsi_qdepth + IBMVFC_NUM_INTERNAL_SUBQ_REQ; in ibmvfc_alloc_queue()
5821 queue->evt_depth = scsi_qdepth; in ibmvfc_alloc_queue()
5822 queue->reserved_depth = IBMVFC_NUM_INTERNAL_SUBQ_REQ; in ibmvfc_alloc_queue()
5826 return -EINVAL; in ibmvfc_alloc_queue()
5829 queue->fmt = fmt; in ibmvfc_alloc_queue()
5832 return -ENOMEM; in ibmvfc_alloc_queue()
5835 queue->msgs.handle = (void *)get_zeroed_page(GFP_KERNEL); in ibmvfc_alloc_queue()
5836 if (!queue->msgs.handle) in ibmvfc_alloc_queue()
5837 return -ENOMEM; in ibmvfc_alloc_queue()
5839 queue->msg_token = dma_map_single(dev, queue->msgs.handle, PAGE_SIZE, in ibmvfc_alloc_queue()
5842 if (dma_mapping_error(dev, queue->msg_token)) { in ibmvfc_alloc_queue()
5843 free_page((unsigned long)queue->msgs.handle); in ibmvfc_alloc_queue()
5844 queue->msgs.handle = NULL; in ibmvfc_alloc_queue()
5845 return -ENOMEM; in ibmvfc_alloc_queue()
5848 queue->cur = 0; in ibmvfc_alloc_queue()
5849 queue->size = PAGE_SIZE / fmt_size; in ibmvfc_alloc_queue()
5851 queue->vhost = vhost; in ibmvfc_alloc_queue()
5856 * ibmvfc_init_crq - Initializes and registers CRQ with hypervisor
5867 int rc, retrc = -ENOMEM; in ibmvfc_init_crq()
5868 struct device *dev = vhost->dev; in ibmvfc_init_crq()
5870 struct ibmvfc_queue *crq = &vhost->crq; in ibmvfc_init_crq()
5874 return -ENOMEM; in ibmvfc_init_crq()
5876 retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, in ibmvfc_init_crq()
5877 crq->msg_token, PAGE_SIZE); in ibmvfc_init_crq()
5892 tasklet_init(&vhost->tasklet, (void *)ibmvfc_tasklet, (unsigned long)vhost); in ibmvfc_init_crq()
5894 if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) { in ibmvfc_init_crq()
5895 dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc); in ibmvfc_init_crq()
5908 tasklet_kill(&vhost->tasklet); in ibmvfc_init_crq()
5910 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); in ibmvfc_init_crq()
5921 struct device *dev = vhost->dev; in ibmvfc_register_channel()
5923 struct ibmvfc_queue *scrq = &channels->scrqs[index]; in ibmvfc_register_channel()
5924 int rc = -ENOMEM; in ibmvfc_register_channel()
5928 rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE, in ibmvfc_register_channel()
5929 &scrq->cookie, &scrq->hw_irq); in ibmvfc_register_channel()
5933 dev_warn(dev, "Error registering sub-crq: %d\n", rc); in ibmvfc_register_channel()
5939 scrq->irq = irq_create_mapping(NULL, scrq->hw_irq); in ibmvfc_register_channel()
5941 if (!scrq->irq) { in ibmvfc_register_channel()
5942 rc = -EINVAL; in ibmvfc_register_channel()
5943 dev_err(dev, "Error mapping sub-crq[%d] irq\n", index); in ibmvfc_register_channel()
5947 switch (channels->protocol) { in ibmvfc_register_channel()
5949 snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-scsi%d", in ibmvfc_register_channel()
5950 vdev->unit_address, index); in ibmvfc_register_channel()
5951 scrq->handler = ibmvfc_interrupt_mq; in ibmvfc_register_channel()
5954 snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-nvmf%d", in ibmvfc_register_channel()
5955 vdev->unit_address, index); in ibmvfc_register_channel()
5956 scrq->handler = ibmvfc_interrupt_mq; in ibmvfc_register_channel()
5960 channels->protocol); in ibmvfc_register_channel()
5964 rc = request_irq(scrq->irq, scrq->handler, 0, scrq->name, scrq); in ibmvfc_register_channel()
5967 dev_err(dev, "Couldn't register sub-crq[%d] irq\n", index); in ibmvfc_register_channel()
5968 irq_dispose_mapping(scrq->irq); in ibmvfc_register_channel()
5972 scrq->hwq_id = index; in ibmvfc_register_channel()
5979 rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); in ibmvfc_register_channel()
5990 struct device *dev = vhost->dev; in ibmvfc_deregister_channel()
5992 struct ibmvfc_queue *scrq = &channels->scrqs[index]; in ibmvfc_deregister_channel()
5997 free_irq(scrq->irq, scrq); in ibmvfc_deregister_channel()
5998 irq_dispose_mapping(scrq->irq); in ibmvfc_deregister_channel()
5999 scrq->irq = 0; in ibmvfc_deregister_channel()
6002 rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, in ibmvfc_deregister_channel()
6003 scrq->cookie); in ibmvfc_deregister_channel()
6007 dev_err(dev, "Failed to free sub-crq[%d]: rc=%ld\n", index, rc); in ibmvfc_deregister_channel()
6010 memset(scrq->msgs.crq, 0, PAGE_SIZE); in ibmvfc_deregister_channel()
6011 scrq->cur = 0; in ibmvfc_deregister_channel()
6022 if (!vhost->mq_enabled || !channels->scrqs) in ibmvfc_reg_sub_crqs()
6025 for (i = 0; i < channels->max_queues; i++) { in ibmvfc_reg_sub_crqs()
6027 for (j = i; j > 0; j--) in ibmvfc_reg_sub_crqs()
6028 ibmvfc_deregister_channel(vhost, channels, j - 1); in ibmvfc_reg_sub_crqs()
6029 vhost->do_enquiry = 0; in ibmvfc_reg_sub_crqs()
6043 if (!vhost->mq_enabled || !channels->scrqs) in ibmvfc_dereg_sub_crqs()
6046 for (i = 0; i < channels->max_queues; i++) in ibmvfc_dereg_sub_crqs()
6059 channels->scrqs = kcalloc(channels->max_queues, in ibmvfc_alloc_channels()
6060 sizeof(*channels->scrqs), in ibmvfc_alloc_channels()
6062 if (!channels->scrqs) in ibmvfc_alloc_channels()
6063 return -ENOMEM; in ibmvfc_alloc_channels()
6065 for (i = 0; i < channels->max_queues; i++) { in ibmvfc_alloc_channels()
6066 scrq = &channels->scrqs[i]; in ibmvfc_alloc_channels()
6069 for (j = i; j > 0; j--) { in ibmvfc_alloc_channels()
6070 scrq = &channels->scrqs[j - 1]; in ibmvfc_alloc_channels()
6073 kfree(channels->scrqs); in ibmvfc_alloc_channels()
6074 channels->scrqs = NULL; in ibmvfc_alloc_channels()
6075 channels->active_queues = 0; in ibmvfc_alloc_channels()
6086 if (!vhost->mq_enabled) in ibmvfc_init_sub_crqs()
6089 if (ibmvfc_alloc_channels(vhost, &vhost->scsi_scrqs)) { in ibmvfc_init_sub_crqs()
6090 vhost->do_enquiry = 0; in ibmvfc_init_sub_crqs()
6091 vhost->mq_enabled = 0; in ibmvfc_init_sub_crqs()
6095 ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); in ibmvfc_init_sub_crqs()
6106 if (channels->scrqs) { in ibmvfc_release_channels()
6107 for (i = 0; i < channels->max_queues; i++) { in ibmvfc_release_channels()
6108 scrq = &channels->scrqs[i]; in ibmvfc_release_channels()
6112 kfree(channels->scrqs); in ibmvfc_release_channels()
6113 channels->scrqs = NULL; in ibmvfc_release_channels()
6114 channels->active_queues = 0; in ibmvfc_release_channels()
6121 if (!vhost->scsi_scrqs.scrqs) in ibmvfc_release_sub_crqs()
6124 ibmvfc_dereg_sub_crqs(vhost, &vhost->scsi_scrqs); in ibmvfc_release_sub_crqs()
6126 ibmvfc_release_channels(vhost, &vhost->scsi_scrqs); in ibmvfc_release_sub_crqs()
6132 dma_free_coherent(dev, channels->disc_buf_sz, channels->disc_buf, in ibmvfc_free_disc_buf()
6133 channels->disc_buf_dma); in ibmvfc_free_disc_buf()
6137 * ibmvfc_free_mem - Free memory for vhost
6145 struct ibmvfc_queue *async_q = &vhost->async_crq; in ibmvfc_free_mem()
6148 mempool_destroy(vhost->tgt_pool); in ibmvfc_free_mem()
6149 kfree(vhost->trace); in ibmvfc_free_mem()
6150 ibmvfc_free_disc_buf(vhost->dev, &vhost->scsi_scrqs); in ibmvfc_free_mem()
6151 dma_free_coherent(vhost->dev, sizeof(*vhost->login_buf), in ibmvfc_free_mem()
6152 vhost->login_buf, vhost->login_buf_dma); in ibmvfc_free_mem()
6153 dma_free_coherent(vhost->dev, sizeof(*vhost->channel_setup_buf), in ibmvfc_free_mem()
6154 vhost->channel_setup_buf, vhost->channel_setup_dma); in ibmvfc_free_mem()
6155 dma_pool_destroy(vhost->sg_pool); in ibmvfc_free_mem()
6162 channels->disc_buf_sz = sizeof(*channels->disc_buf) * max_targets; in ibmvfc_alloc_disc_buf()
6163 channels->disc_buf = dma_alloc_coherent(dev, channels->disc_buf_sz, in ibmvfc_alloc_disc_buf()
6164 &channels->disc_buf_dma, GFP_KERNEL); in ibmvfc_alloc_disc_buf()
6166 if (!channels->disc_buf) { in ibmvfc_alloc_disc_buf()
6168 (channels->protocol == IBMVFC_PROTO_SCSI) ? "SCSI" : "NVMe"); in ibmvfc_alloc_disc_buf()
6169 return -ENOMEM; in ibmvfc_alloc_disc_buf()
6176 * ibmvfc_alloc_mem - Allocate memory for vhost
6180 * 0 on success / non-zero on failure
6184 struct ibmvfc_queue *async_q = &vhost->async_crq; in ibmvfc_alloc_mem()
6185 struct device *dev = vhost->dev; in ibmvfc_alloc_mem()
6193 vhost->sg_pool = dma_pool_create(IBMVFC_NAME, dev, in ibmvfc_alloc_mem()
6197 if (!vhost->sg_pool) { in ibmvfc_alloc_mem()
6202 vhost->login_buf = dma_alloc_coherent(dev, sizeof(*vhost->login_buf), in ibmvfc_alloc_mem()
6203 &vhost->login_buf_dma, GFP_KERNEL); in ibmvfc_alloc_mem()
6205 if (!vhost->login_buf) { in ibmvfc_alloc_mem()
6210 if (ibmvfc_alloc_disc_buf(dev, &vhost->scsi_scrqs)) in ibmvfc_alloc_mem()
6213 vhost->trace = kcalloc(IBMVFC_NUM_TRACE_ENTRIES, in ibmvfc_alloc_mem()
6215 atomic_set(&vhost->trace_index, -1); in ibmvfc_alloc_mem()
6217 if (!vhost->trace) in ibmvfc_alloc_mem()
6220 vhost->tgt_pool = mempool_create_kmalloc_pool(IBMVFC_TGT_MEMPOOL_SZ, in ibmvfc_alloc_mem()
6223 if (!vhost->tgt_pool) { in ibmvfc_alloc_mem()
6228 vhost->channel_setup_buf = dma_alloc_coherent(dev, sizeof(*vhost->channel_setup_buf), in ibmvfc_alloc_mem()
6229 &vhost->channel_setup_dma, in ibmvfc_alloc_mem()
6232 if (!vhost->channel_setup_buf) { in ibmvfc_alloc_mem()
6241 mempool_destroy(vhost->tgt_pool); in ibmvfc_alloc_mem()
6243 kfree(vhost->trace); in ibmvfc_alloc_mem()
6245 ibmvfc_free_disc_buf(dev, &vhost->scsi_scrqs); in ibmvfc_alloc_mem()
6247 dma_free_coherent(dev, sizeof(*vhost->login_buf), in ibmvfc_alloc_mem()
6248 vhost->login_buf, vhost->login_buf_dma); in ibmvfc_alloc_mem()
6250 dma_pool_destroy(vhost->sg_pool); in ibmvfc_alloc_mem()
6255 return -ENOMEM; in ibmvfc_alloc_mem()
6259 * ibmvfc_rport_add_thread - Worker thread for rport adds
6273 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_rport_add_thread()
6276 if (vhost->state != IBMVFC_ACTIVE) in ibmvfc_rport_add_thread()
6279 list_for_each_entry(tgt, &vhost->targets, queue) { in ibmvfc_rport_add_thread()
6280 if (tgt->add_rport) { in ibmvfc_rport_add_thread()
6282 tgt->add_rport = 0; in ibmvfc_rport_add_thread()
6283 kref_get(&tgt->kref); in ibmvfc_rport_add_thread()
6284 rport = tgt->rport; in ibmvfc_rport_add_thread()
6286 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_rport_add_thread()
6288 } else if (get_device(&rport->dev)) { in ibmvfc_rport_add_thread()
6289 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_rport_add_thread()
6291 fc_remote_port_rolechg(rport, tgt->ids.roles); in ibmvfc_rport_add_thread()
6292 put_device(&rport->dev); in ibmvfc_rport_add_thread()
6294 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_rport_add_thread()
6297 kref_put(&tgt->kref, ibmvfc_release_tgt); in ibmvfc_rport_add_thread()
6298 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_rport_add_thread()
6304 if (vhost->state == IBMVFC_ACTIVE) in ibmvfc_rport_add_thread()
6305 vhost->scan_complete = 1; in ibmvfc_rport_add_thread()
6306 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_rport_add_thread()
6311 * ibmvfc_probe - Adapter hot plug add entry point
6316 * 0 on success / non-zero on failure
6322 struct device *dev = &vdev->dev; in ibmvfc_probe()
6323 int rc = -ENOMEM; in ibmvfc_probe()
6334 shost->transportt = ibmvfc_transport_template; in ibmvfc_probe()
6335 shost->can_queue = scsi_qdepth; in ibmvfc_probe()
6336 shost->max_lun = max_lun; in ibmvfc_probe()
6337 shost->max_id = max_targets; in ibmvfc_probe()
6338 shost->max_sectors = max_sectors; in ibmvfc_probe()
6339 shost->max_cmd_len = IBMVFC_MAX_CDB_LEN; in ibmvfc_probe()
6340 shost->unique_id = shost->host_no; in ibmvfc_probe()
6341 shost->nr_hw_queues = mq_enabled ? min(max_scsi_queues, nr_scsi_hw_queues) : 1; in ibmvfc_probe()
6344 INIT_LIST_HEAD(&vhost->targets); in ibmvfc_probe()
6345 INIT_LIST_HEAD(&vhost->purge); in ibmvfc_probe()
6346 sprintf(vhost->name, IBMVFC_NAME); in ibmvfc_probe()
6347 vhost->host = shost; in ibmvfc_probe()
6348 vhost->dev = dev; in ibmvfc_probe()
6349 vhost->partition_number = -1; in ibmvfc_probe()
6350 vhost->log_level = log_level; in ibmvfc_probe()
6351 vhost->task_set = 1; in ibmvfc_probe()
6353 vhost->mq_enabled = mq_enabled; in ibmvfc_probe()
6354 vhost->scsi_scrqs.desired_queues = min(shost->nr_hw_queues, nr_scsi_channels); in ibmvfc_probe()
6355 vhost->scsi_scrqs.max_queues = shost->nr_hw_queues; in ibmvfc_probe()
6356 vhost->scsi_scrqs.protocol = IBMVFC_PROTO_SCSI; in ibmvfc_probe()
6357 vhost->using_channels = 0; in ibmvfc_probe()
6358 vhost->do_enquiry = 1; in ibmvfc_probe()
6359 vhost->scan_timeout = 0; in ibmvfc_probe()
6361 strcpy(vhost->partition_name, "UNKNOWN"); in ibmvfc_probe()
6362 init_waitqueue_head(&vhost->work_wait_q); in ibmvfc_probe()
6363 init_waitqueue_head(&vhost->init_wait_q); in ibmvfc_probe()
6364 INIT_WORK(&vhost->rport_add_work_q, ibmvfc_rport_add_thread); in ibmvfc_probe()
6365 mutex_init(&vhost->passthru_mutex); in ibmvfc_probe()
6370 vhost->work_thread = kthread_run(ibmvfc_work, vhost, "%s_%d", IBMVFC_NAME, in ibmvfc_probe()
6371 shost->host_no); in ibmvfc_probe()
6373 if (IS_ERR(vhost->work_thread)) { in ibmvfc_probe()
6375 PTR_ERR(vhost->work_thread)); in ibmvfc_probe()
6376 rc = PTR_ERR(vhost->work_thread); in ibmvfc_probe()
6390 if ((rc = ibmvfc_create_trace_file(&shost->shost_dev.kobj, in ibmvfc_probe()
6400 list_add_tail(&vhost->queue, &ibmvfc_head); in ibmvfc_probe()
6412 kthread_stop(vhost->work_thread); in ibmvfc_probe()
6423 * ibmvfc_remove - Adapter hot plug remove entry point
6431 struct ibmvfc_host *vhost = dev_get_drvdata(&vdev->dev); in ibmvfc_remove()
6436 ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); in ibmvfc_remove()
6438 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_remove()
6440 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_remove()
6443 kthread_stop(vhost->work_thread); in ibmvfc_remove()
6444 fc_remove_host(vhost->host); in ibmvfc_remove()
6445 scsi_remove_host(vhost->host); in ibmvfc_remove()
6447 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_remove()
6449 list_splice_init(&vhost->purge, &purge); in ibmvfc_remove()
6450 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_remove()
6457 list_del(&vhost->queue); in ibmvfc_remove()
6459 scsi_host_put(vhost->host); in ibmvfc_remove()
6464 * ibmvfc_resume - Resume from suspend
6477 spin_lock_irqsave(vhost->host->host_lock, flags); in ibmvfc_resume()
6479 tasklet_schedule(&vhost->tasklet); in ibmvfc_resume()
6480 spin_unlock_irqrestore(vhost->host->host_lock, flags); in ibmvfc_resume()
6485 * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver
6501 {"fcp", "IBM,vfc-client"},
6558 * ibmvfc_module_init - Initialize the ibmvfc module
6569 return -ENODEV; in ibmvfc_module_init()
6586 return -ENOMEM; in ibmvfc_module_init()
6595 * ibmvfc_module_exit - Teardown the ibmvfc module