diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvfc.c')
| -rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 208 |
1 files changed, 179 insertions, 29 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c4a7c06793c5..ae560bc04f9d 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
| @@ -521,9 +521,10 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost, | |||
| 521 | static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) | 521 | static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) |
| 522 | { | 522 | { |
| 523 | if (vhost->action == IBMVFC_HOST_ACTION_NONE) { | 523 | if (vhost->action == IBMVFC_HOST_ACTION_NONE) { |
| 524 | scsi_block_requests(vhost->host); | 524 | if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { |
| 525 | ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING); | 525 | scsi_block_requests(vhost->host); |
| 526 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); | 526 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); |
| 527 | } | ||
| 527 | } else | 528 | } else |
| 528 | vhost->reinit = 1; | 529 | vhost->reinit = 1; |
| 529 | 530 | ||
| @@ -854,39 +855,41 @@ static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost) | |||
| 854 | } | 855 | } |
| 855 | 856 | ||
| 856 | /** | 857 | /** |
| 857 | * __ibmvfc_find_target - Find the specified scsi_target (no locking) | 858 | * __ibmvfc_get_target - Find the specified scsi_target (no locking) |
| 858 | * @starget: scsi target struct | 859 | * @starget: scsi target struct |
| 859 | * | 860 | * |
| 860 | * Return value: | 861 | * Return value: |
| 861 | * ibmvfc_target struct / NULL if not found | 862 | * ibmvfc_target struct / NULL if not found |
| 862 | **/ | 863 | **/ |
| 863 | static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget) | 864 | static struct ibmvfc_target *__ibmvfc_get_target(struct scsi_target *starget) |
| 864 | { | 865 | { |
| 865 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 866 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
| 866 | struct ibmvfc_host *vhost = shost_priv(shost); | 867 | struct ibmvfc_host *vhost = shost_priv(shost); |
| 867 | struct ibmvfc_target *tgt; | 868 | struct ibmvfc_target *tgt; |
| 868 | 869 | ||
| 869 | list_for_each_entry(tgt, &vhost->targets, queue) | 870 | list_for_each_entry(tgt, &vhost->targets, queue) |
| 870 | if (tgt->target_id == starget->id) | 871 | if (tgt->target_id == starget->id) { |
| 872 | kref_get(&tgt->kref); | ||
| 871 | return tgt; | 873 | return tgt; |
| 874 | } | ||
| 872 | return NULL; | 875 | return NULL; |
| 873 | } | 876 | } |
| 874 | 877 | ||
| 875 | /** | 878 | /** |
| 876 | * ibmvfc_find_target - Find the specified scsi_target | 879 | * ibmvfc_get_target - Find the specified scsi_target |
| 877 | * @starget: scsi target struct | 880 | * @starget: scsi target struct |
| 878 | * | 881 | * |
| 879 | * Return value: | 882 | * Return value: |
| 880 | * ibmvfc_target struct / NULL if not found | 883 | * ibmvfc_target struct / NULL if not found |
| 881 | **/ | 884 | **/ |
| 882 | static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget) | 885 | static struct ibmvfc_target *ibmvfc_get_target(struct scsi_target *starget) |
| 883 | { | 886 | { |
| 884 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 887 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
| 885 | struct ibmvfc_target *tgt; | 888 | struct ibmvfc_target *tgt; |
| 886 | unsigned long flags; | 889 | unsigned long flags; |
| 887 | 890 | ||
| 888 | spin_lock_irqsave(shost->host_lock, flags); | 891 | spin_lock_irqsave(shost->host_lock, flags); |
| 889 | tgt = __ibmvfc_find_target(starget); | 892 | tgt = __ibmvfc_get_target(starget); |
| 890 | spin_unlock_irqrestore(shost->host_lock, flags); | 893 | spin_unlock_irqrestore(shost->host_lock, flags); |
| 891 | return tgt; | 894 | return tgt; |
| 892 | } | 895 | } |
| @@ -963,6 +966,9 @@ static void ibmvfc_get_host_port_state(struct Scsi_Host *shost) | |||
| 963 | case IBMVFC_HALTED: | 966 | case IBMVFC_HALTED: |
| 964 | fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED; | 967 | fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED; |
| 965 | break; | 968 | break; |
| 969 | case IBMVFC_NO_CRQ: | ||
| 970 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | ||
| 971 | break; | ||
| 966 | default: | 972 | default: |
| 967 | ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); | 973 | ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); |
| 968 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | 974 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; |
| @@ -988,6 +994,17 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
| 988 | } | 994 | } |
| 989 | 995 | ||
| 990 | /** | 996 | /** |
| 997 | * ibmvfc_release_tgt - Free memory allocated for a target | ||
| 998 | * @kref: kref struct | ||
| 999 | * | ||
| 1000 | **/ | ||
| 1001 | static void ibmvfc_release_tgt(struct kref *kref) | ||
| 1002 | { | ||
| 1003 | struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); | ||
| 1004 | kfree(tgt); | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | /** | ||
| 991 | * ibmvfc_get_starget_node_name - Get SCSI target's node name | 1008 | * ibmvfc_get_starget_node_name - Get SCSI target's node name |
| 992 | * @starget: scsi target struct | 1009 | * @starget: scsi target struct |
| 993 | * | 1010 | * |
| @@ -996,8 +1013,10 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
| 996 | **/ | 1013 | **/ |
| 997 | static void ibmvfc_get_starget_node_name(struct scsi_target *starget) | 1014 | static void ibmvfc_get_starget_node_name(struct scsi_target *starget) |
| 998 | { | 1015 | { |
| 999 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1016 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
| 1000 | fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; | 1017 | fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; |
| 1018 | if (tgt) | ||
| 1019 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
| 1001 | } | 1020 | } |
| 1002 | 1021 | ||
| 1003 | /** | 1022 | /** |
| @@ -1009,8 +1028,10 @@ static void ibmvfc_get_starget_node_name(struct scsi_target *starget) | |||
| 1009 | **/ | 1028 | **/ |
| 1010 | static void ibmvfc_get_starget_port_name(struct scsi_target *starget) | 1029 | static void ibmvfc_get_starget_port_name(struct scsi_target *starget) |
| 1011 | { | 1030 | { |
| 1012 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1031 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
| 1013 | fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; | 1032 | fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; |
| 1033 | if (tgt) | ||
| 1034 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
| 1014 | } | 1035 | } |
| 1015 | 1036 | ||
| 1016 | /** | 1037 | /** |
| @@ -1022,8 +1043,10 @@ static void ibmvfc_get_starget_port_name(struct scsi_target *starget) | |||
| 1022 | **/ | 1043 | **/ |
| 1023 | static void ibmvfc_get_starget_port_id(struct scsi_target *starget) | 1044 | static void ibmvfc_get_starget_port_id(struct scsi_target *starget) |
| 1024 | { | 1045 | { |
| 1025 | struct ibmvfc_target *tgt = ibmvfc_find_target(starget); | 1046 | struct ibmvfc_target *tgt = ibmvfc_get_target(starget); |
| 1026 | fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; | 1047 | fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; |
| 1048 | if (tgt) | ||
| 1049 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
| 1027 | } | 1050 | } |
| 1028 | 1051 | ||
| 1029 | /** | 1052 | /** |
| @@ -1113,7 +1136,7 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) | |||
| 1113 | login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; | 1136 | login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; |
| 1114 | login_info->capabilities = IBMVFC_CAN_MIGRATE; | 1137 | login_info->capabilities = IBMVFC_CAN_MIGRATE; |
| 1115 | login_info->async.va = vhost->async_crq.msg_token; | 1138 | login_info->async.va = vhost->async_crq.msg_token; |
| 1116 | login_info->async.len = vhost->async_crq.size; | 1139 | login_info->async.len = vhost->async_crq.size * sizeof(*vhost->async_crq.msgs); |
| 1117 | strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME); | 1140 | strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME); |
| 1118 | strncpy(login_info->device_name, | 1141 | strncpy(login_info->device_name, |
| 1119 | vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME); | 1142 | vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME); |
| @@ -1404,7 +1427,7 @@ static void ibmvfc_log_error(struct ibmvfc_event *evt) | |||
| 1404 | err = cmd_status[index].name; | 1427 | err = cmd_status[index].name; |
| 1405 | } | 1428 | } |
| 1406 | 1429 | ||
| 1407 | if (!logerr && (vhost->log_level <= IBMVFC_DEFAULT_LOG_LEVEL)) | 1430 | if (!logerr && (vhost->log_level <= (IBMVFC_DEFAULT_LOG_LEVEL + 1))) |
| 1408 | return; | 1431 | return; |
| 1409 | 1432 | ||
| 1410 | if (rsp->flags & FCP_RSP_LEN_VALID) | 1433 | if (rsp->flags & FCP_RSP_LEN_VALID) |
| @@ -2054,7 +2077,7 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, | |||
| 2054 | { | 2077 | { |
| 2055 | const char *desc = ibmvfc_get_ae_desc(crq->event); | 2078 | const char *desc = ibmvfc_get_ae_desc(crq->event); |
| 2056 | 2079 | ||
| 2057 | ibmvfc_log(vhost, 2, "%s event received\n", desc); | 2080 | ibmvfc_log(vhost, 3, "%s event received\n", desc); |
| 2058 | 2081 | ||
| 2059 | switch (crq->event) { | 2082 | switch (crq->event) { |
| 2060 | case IBMVFC_AE_LINK_UP: | 2083 | case IBMVFC_AE_LINK_UP: |
| @@ -2648,17 +2671,6 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt, | |||
| 2648 | } | 2671 | } |
| 2649 | 2672 | ||
| 2650 | /** | 2673 | /** |
| 2651 | * ibmvfc_release_tgt - Free memory allocated for a target | ||
| 2652 | * @kref: kref struct | ||
| 2653 | * | ||
| 2654 | **/ | ||
| 2655 | static void ibmvfc_release_tgt(struct kref *kref) | ||
| 2656 | { | ||
| 2657 | struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); | ||
| 2658 | kfree(tgt); | ||
| 2659 | } | ||
| 2660 | |||
| 2661 | /** | ||
| 2662 | * ibmvfc_tgt_prli_done - Completion handler for Process Login | 2674 | * ibmvfc_tgt_prli_done - Completion handler for Process Login |
| 2663 | * @evt: ibmvfc event struct | 2675 | * @evt: ibmvfc event struct |
| 2664 | * | 2676 | * |
| @@ -2902,6 +2914,139 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) | |||
| 2902 | } | 2914 | } |
| 2903 | 2915 | ||
| 2904 | /** | 2916 | /** |
| 2917 | * ibmvfc_adisc_needs_plogi - Does device need PLOGI? | ||
| 2918 | * @mad: ibmvfc passthru mad struct | ||
| 2919 | * @tgt: ibmvfc target struct | ||
| 2920 | * | ||
| 2921 | * Returns: | ||
| 2922 | * 1 if PLOGI needed / 0 if PLOGI not needed | ||
| 2923 | **/ | ||
| 2924 | static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, | ||
| 2925 | struct ibmvfc_target *tgt) | ||
| 2926 | { | ||
| 2927 | if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name, | ||
| 2928 | sizeof(tgt->ids.port_name))) | ||
| 2929 | return 1; | ||
| 2930 | if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name, | ||
| 2931 | sizeof(tgt->ids.node_name))) | ||
| 2932 | return 1; | ||
| 2933 | if (mad->fc_iu.response[6] != tgt->scsi_id) | ||
| 2934 | return 1; | ||
| 2935 | return 0; | ||
| 2936 | } | ||
| 2937 | |||
| 2938 | /** | ||
| 2939 | * ibmvfc_tgt_adisc_done - Completion handler for ADISC | ||
| 2940 | * @evt: ibmvfc event struct | ||
| 2941 | * | ||
| 2942 | **/ | ||
| 2943 | static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt) | ||
| 2944 | { | ||
| 2945 | struct ibmvfc_target *tgt = evt->tgt; | ||
| 2946 | struct ibmvfc_host *vhost = evt->vhost; | ||
| 2947 | struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru; | ||
| 2948 | u32 status = mad->common.status; | ||
| 2949 | u8 fc_reason, fc_explain; | ||
| 2950 | |||
| 2951 | vhost->discovery_threads--; | ||
| 2952 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); | ||
| 2953 | |||
| 2954 | switch (status) { | ||
| 2955 | case IBMVFC_MAD_SUCCESS: | ||
| 2956 | tgt_dbg(tgt, "ADISC succeeded\n"); | ||
| 2957 | if (ibmvfc_adisc_needs_plogi(mad, tgt)) | ||
| 2958 | tgt->need_login = 1; | ||
| 2959 | break; | ||
| 2960 | case IBMVFC_MAD_DRIVER_FAILED: | ||
| 2961 | break; | ||
| 2962 | case IBMVFC_MAD_FAILED: | ||
| 2963 | default: | ||
| 2964 | tgt->need_login = 1; | ||
| 2965 | fc_reason = (mad->fc_iu.response[1] & 0x00ff0000) >> 16; | ||
| 2966 | fc_explain = (mad->fc_iu.response[1] & 0x0000ff00) >> 8; | ||
| 2967 | tgt_info(tgt, "ADISC failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n", | ||
| 2968 | ibmvfc_get_cmd_error(mad->iu.status, mad->iu.error), | ||
| 2969 | mad->iu.status, mad->iu.error, | ||
| 2970 | ibmvfc_get_fc_type(fc_reason), fc_reason, | ||
| 2971 | ibmvfc_get_ls_explain(fc_explain), fc_explain, status); | ||
| 2972 | break; | ||
| 2973 | }; | ||
| 2974 | |||
| 2975 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
| 2976 | ibmvfc_free_event(evt); | ||
| 2977 | wake_up(&vhost->work_wait_q); | ||
| 2978 | } | ||
| 2979 | |||
| 2980 | /** | ||
| 2981 | * ibmvfc_init_passthru - Initialize an event struct for FC passthru | ||
| 2982 | * @evt: ibmvfc event struct | ||
| 2983 | * | ||
| 2984 | **/ | ||
| 2985 | static void ibmvfc_init_passthru(struct ibmvfc_event *evt) | ||
| 2986 | { | ||
| 2987 | struct ibmvfc_passthru_mad *mad = &evt->iu.passthru; | ||
| 2988 | |||
| 2989 | memset(mad, 0, sizeof(*mad)); | ||
| 2990 | mad->common.version = 1; | ||
| 2991 | mad->common.opcode = IBMVFC_PASSTHRU; | ||
| 2992 | mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu); | ||
| 2993 | mad->cmd_ioba.va = (u64)evt->crq.ioba + | ||
| 2994 | offsetof(struct ibmvfc_passthru_mad, iu); | ||
| 2995 | mad->cmd_ioba.len = sizeof(mad->iu); | ||
| 2996 | mad->iu.cmd_len = sizeof(mad->fc_iu.payload); | ||
| 2997 | mad->iu.rsp_len = sizeof(mad->fc_iu.response); | ||
| 2998 | mad->iu.cmd.va = (u64)evt->crq.ioba + | ||
| 2999 | offsetof(struct ibmvfc_passthru_mad, fc_iu) + | ||
| 3000 | offsetof(struct ibmvfc_passthru_fc_iu, payload); | ||
| 3001 | mad->iu.cmd.len = sizeof(mad->fc_iu.payload); | ||
| 3002 | mad->iu.rsp.va = (u64)evt->crq.ioba + | ||
| 3003 | offsetof(struct ibmvfc_passthru_mad, fc_iu) + | ||
| 3004 | offsetof(struct ibmvfc_passthru_fc_iu, response); | ||
| 3005 | mad->iu.rsp.len = sizeof(mad->fc_iu.response); | ||
| 3006 | } | ||
| 3007 | |||
| 3008 | /** | ||
| 3009 | * ibmvfc_tgt_adisc - Initiate an ADISC for specified target | ||
| 3010 | * @tgt: ibmvfc target struct | ||
| 3011 | * | ||
| 3012 | **/ | ||
| 3013 | static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt) | ||
| 3014 | { | ||
| 3015 | struct ibmvfc_passthru_mad *mad; | ||
| 3016 | struct ibmvfc_host *vhost = tgt->vhost; | ||
| 3017 | struct ibmvfc_event *evt; | ||
| 3018 | |||
| 3019 | if (vhost->discovery_threads >= disc_threads) | ||
| 3020 | return; | ||
| 3021 | |||
| 3022 | kref_get(&tgt->kref); | ||
| 3023 | evt = ibmvfc_get_event(vhost); | ||
| 3024 | vhost->discovery_threads++; | ||
| 3025 | ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); | ||
| 3026 | evt->tgt = tgt; | ||
| 3027 | |||
| 3028 | ibmvfc_init_passthru(evt); | ||
| 3029 | mad = &evt->iu.passthru; | ||
| 3030 | mad->iu.flags = IBMVFC_FC_ELS; | ||
| 3031 | mad->iu.scsi_id = tgt->scsi_id; | ||
| 3032 | |||
| 3033 | mad->fc_iu.payload[0] = IBMVFC_ADISC; | ||
| 3034 | memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name, | ||
| 3035 | sizeof(vhost->login_buf->resp.port_name)); | ||
| 3036 | memcpy(&mad->fc_iu.payload[4], &vhost->login_buf->resp.node_name, | ||
| 3037 | sizeof(vhost->login_buf->resp.node_name)); | ||
| 3038 | mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff; | ||
| 3039 | |||
| 3040 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); | ||
| 3041 | if (ibmvfc_send_event(evt, vhost, default_timeout)) { | ||
| 3042 | vhost->discovery_threads--; | ||
| 3043 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); | ||
| 3044 | kref_put(&tgt->kref, ibmvfc_release_tgt); | ||
| 3045 | } else | ||
| 3046 | tgt_dbg(tgt, "Sent ADISC\n"); | ||
| 3047 | } | ||
| 3048 | |||
| 3049 | /** | ||
| 2905 | * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD | 3050 | * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD |
| 2906 | * @evt: ibmvfc event struct | 3051 | * @evt: ibmvfc event struct |
| 2907 | * | 3052 | * |
| @@ -2921,6 +3066,8 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt) | |||
| 2921 | tgt->new_scsi_id = rsp->scsi_id; | 3066 | tgt->new_scsi_id = rsp->scsi_id; |
| 2922 | if (rsp->scsi_id != tgt->scsi_id) | 3067 | if (rsp->scsi_id != tgt->scsi_id) |
| 2923 | ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); | 3068 | ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); |
| 3069 | else | ||
| 3070 | ibmvfc_init_tgt(tgt, ibmvfc_tgt_adisc); | ||
| 2924 | break; | 3071 | break; |
| 2925 | case IBMVFC_MAD_DRIVER_FAILED: | 3072 | case IBMVFC_MAD_DRIVER_FAILED: |
| 2926 | break; | 3073 | break; |
| @@ -3336,6 +3483,7 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) | |||
| 3336 | tgt_dbg(tgt, "rport add succeeded\n"); | 3483 | tgt_dbg(tgt, "rport add succeeded\n"); |
| 3337 | rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff; | 3484 | rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff; |
| 3338 | rport->supported_classes = 0; | 3485 | rport->supported_classes = 0; |
| 3486 | tgt->target_id = rport->scsi_target_id; | ||
| 3339 | if (tgt->service_parms.class1_parms[0] & 0x80000000) | 3487 | if (tgt->service_parms.class1_parms[0] & 0x80000000) |
| 3340 | rport->supported_classes |= FC_COS_CLASS1; | 3488 | rport->supported_classes |= FC_COS_CLASS1; |
| 3341 | if (tgt->service_parms.class2_parms[0] & 0x80000000) | 3489 | if (tgt->service_parms.class2_parms[0] & 0x80000000) |
| @@ -3525,7 +3673,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost) | |||
| 3525 | crq->msg_token = dma_map_single(dev, crq->msgs, | 3673 | crq->msg_token = dma_map_single(dev, crq->msgs, |
| 3526 | PAGE_SIZE, DMA_BIDIRECTIONAL); | 3674 | PAGE_SIZE, DMA_BIDIRECTIONAL); |
| 3527 | 3675 | ||
| 3528 | if (dma_mapping_error(crq->msg_token)) | 3676 | if (dma_mapping_error(dev, crq->msg_token)) |
| 3529 | goto map_failed; | 3677 | goto map_failed; |
| 3530 | 3678 | ||
| 3531 | retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, | 3679 | retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, |
| @@ -3618,7 +3766,7 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) | |||
| 3618 | async_q->size * sizeof(*async_q->msgs), | 3766 | async_q->size * sizeof(*async_q->msgs), |
| 3619 | DMA_BIDIRECTIONAL); | 3767 | DMA_BIDIRECTIONAL); |
| 3620 | 3768 | ||
| 3621 | if (dma_mapping_error(async_q->msg_token)) { | 3769 | if (dma_mapping_error(dev, async_q->msg_token)) { |
| 3622 | dev_err(dev, "Failed to map async queue\n"); | 3770 | dev_err(dev, "Failed to map async queue\n"); |
| 3623 | goto free_async_crq; | 3771 | goto free_async_crq; |
| 3624 | } | 3772 | } |
| @@ -3800,10 +3948,12 @@ static int ibmvfc_remove(struct vio_dev *vdev) | |||
| 3800 | 3948 | ||
| 3801 | ENTER; | 3949 | ENTER; |
| 3802 | ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); | 3950 | ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); |
| 3951 | ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); | ||
| 3952 | ibmvfc_wait_while_resetting(vhost); | ||
| 3953 | ibmvfc_release_crq_queue(vhost); | ||
| 3803 | kthread_stop(vhost->work_thread); | 3954 | kthread_stop(vhost->work_thread); |
| 3804 | fc_remove_host(vhost->host); | 3955 | fc_remove_host(vhost->host); |
| 3805 | scsi_remove_host(vhost->host); | 3956 | scsi_remove_host(vhost->host); |
| 3806 | ibmvfc_release_crq_queue(vhost); | ||
| 3807 | 3957 | ||
| 3808 | spin_lock_irqsave(vhost->host->host_lock, flags); | 3958 | spin_lock_irqsave(vhost->host->host_lock, flags); |
| 3809 | ibmvfc_purge_requests(vhost, DID_ERROR); | 3959 | ibmvfc_purge_requests(vhost, DID_ERROR); |
