diff options
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 8 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 231 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 5 |
4 files changed, 175 insertions, 71 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 40fa056e2575..31c217898772 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -2197,7 +2197,7 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | |||
2197 | zfcp_erp_action_to_running(erp_action); | 2197 | zfcp_erp_action_to_running(erp_action); |
2198 | write_unlock_irq(&adapter->erp_lock); | 2198 | write_unlock_irq(&adapter->erp_lock); |
2199 | 2199 | ||
2200 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); | 2200 | ret = zfcp_fsf_exchange_port_data(erp_action); |
2201 | if (ret == -EOPNOTSUPP) { | 2201 | if (ret == -EOPNOTSUPP) { |
2202 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); | 2202 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); |
2203 | return ZFCP_ERP_SUCCEEDED; | 2203 | return ZFCP_ERP_SUCCEEDED; |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 991d45667a44..722c55b9f8fa 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -82,9 +82,11 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); | |||
82 | extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); | 82 | extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); |
83 | 83 | ||
84 | extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); | 84 | extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); |
85 | extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *, | 85 | extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *, |
86 | struct zfcp_adapter *, | 86 | struct fsf_qtcb_bottom_config *); |
87 | struct fsf_qtcb_bottom_port *); | 87 | extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); |
88 | extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *, | ||
89 | struct fsf_qtcb_bottom_port *); | ||
88 | extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, | 90 | extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, |
89 | u32, u32, struct zfcp_sg_list *); | 91 | u32, u32, struct zfcp_sg_list *); |
90 | extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); | 92 | extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 13ed689c4d8d..4aa8834276f9 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1941,25 +1941,28 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1941 | { | 1941 | { |
1942 | volatile struct qdio_buffer_element *sbale; | 1942 | volatile struct qdio_buffer_element *sbale; |
1943 | struct zfcp_fsf_req *fsf_req; | 1943 | struct zfcp_fsf_req *fsf_req; |
1944 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
1944 | unsigned long lock_flags; | 1945 | unsigned long lock_flags; |
1945 | int retval = 0; | 1946 | int retval; |
1946 | 1947 | ||
1947 | /* setup new FSF request */ | 1948 | /* setup new FSF request */ |
1948 | retval = zfcp_fsf_req_create(erp_action->adapter, | 1949 | retval = zfcp_fsf_req_create(adapter, |
1949 | FSF_QTCB_EXCHANGE_CONFIG_DATA, | 1950 | FSF_QTCB_EXCHANGE_CONFIG_DATA, |
1950 | ZFCP_REQ_AUTO_CLEANUP, | 1951 | ZFCP_REQ_AUTO_CLEANUP, |
1951 | erp_action->adapter->pool.fsf_req_erp, | 1952 | adapter->pool.fsf_req_erp, |
1952 | &lock_flags, &fsf_req); | 1953 | &lock_flags, &fsf_req); |
1953 | if (retval < 0) { | 1954 | if (retval) { |
1954 | ZFCP_LOG_INFO("error: Could not create exchange configuration " | 1955 | ZFCP_LOG_INFO("error: Could not create exchange configuration " |
1955 | "data request for adapter %s.\n", | 1956 | "data request for adapter %s.\n", |
1956 | zfcp_get_busid_by_adapter(erp_action->adapter)); | 1957 | zfcp_get_busid_by_adapter(adapter)); |
1957 | goto out; | 1958 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
1959 | lock_flags); | ||
1960 | return retval; | ||
1958 | } | 1961 | } |
1959 | 1962 | ||
1960 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | 1963 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); |
1961 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | 1964 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; |
1962 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 1965 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
1963 | 1966 | ||
1964 | fsf_req->qtcb->bottom.config.feature_selection = | 1967 | fsf_req->qtcb->bottom.config.feature_selection = |
1965 | FSF_FEATURE_CFDC | | 1968 | FSF_FEATURE_CFDC | |
@@ -1971,23 +1974,71 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1971 | 1974 | ||
1972 | zfcp_erp_start_timer(fsf_req); | 1975 | zfcp_erp_start_timer(fsf_req); |
1973 | retval = zfcp_fsf_req_send(fsf_req); | 1976 | retval = zfcp_fsf_req_send(fsf_req); |
1977 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | ||
1978 | lock_flags); | ||
1974 | if (retval) { | 1979 | if (retval) { |
1975 | ZFCP_LOG_INFO | 1980 | ZFCP_LOG_INFO("error: Could not send exchange configuration " |
1976 | ("error: Could not send exchange configuration data " | 1981 | "data command on the adapter %s\n", |
1977 | "command on the adapter %s\n", | 1982 | zfcp_get_busid_by_adapter(adapter)); |
1978 | zfcp_get_busid_by_adapter(erp_action->adapter)); | ||
1979 | zfcp_fsf_req_free(fsf_req); | 1983 | zfcp_fsf_req_free(fsf_req); |
1980 | erp_action->fsf_req = NULL; | 1984 | erp_action->fsf_req = NULL; |
1981 | goto out; | ||
1982 | } | 1985 | } |
1986 | else | ||
1987 | ZFCP_LOG_DEBUG("exchange configuration data request initiated " | ||
1988 | "(adapter %s)\n", | ||
1989 | zfcp_get_busid_by_adapter(adapter)); | ||
1983 | 1990 | ||
1984 | ZFCP_LOG_DEBUG("exchange configuration data request initiated " | 1991 | return retval; |
1985 | "(adapter %s)\n", | 1992 | } |
1986 | zfcp_get_busid_by_adapter(erp_action->adapter)); | ||
1987 | 1993 | ||
1988 | out: | 1994 | int |
1989 | write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, | 1995 | zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, |
1996 | struct fsf_qtcb_bottom_config *data) | ||
1997 | { | ||
1998 | volatile struct qdio_buffer_element *sbale; | ||
1999 | struct zfcp_fsf_req *fsf_req; | ||
2000 | unsigned long lock_flags; | ||
2001 | int retval; | ||
2002 | |||
2003 | /* setup new FSF request */ | ||
2004 | retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, | ||
2005 | 0, NULL, &lock_flags, &fsf_req); | ||
2006 | if (retval) { | ||
2007 | ZFCP_LOG_INFO("error: Could not create exchange configuration " | ||
2008 | "data request for adapter %s.\n", | ||
2009 | zfcp_get_busid_by_adapter(adapter)); | ||
2010 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | ||
2011 | lock_flags); | ||
2012 | return retval; | ||
2013 | } | ||
2014 | |||
2015 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | ||
2016 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | ||
2017 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | ||
2018 | |||
2019 | fsf_req->qtcb->bottom.config.feature_selection = | ||
2020 | FSF_FEATURE_CFDC | | ||
2021 | FSF_FEATURE_LUN_SHARING | | ||
2022 | FSF_FEATURE_NOTIFICATION_LOST | | ||
2023 | FSF_FEATURE_UPDATE_ALERT; | ||
2024 | |||
2025 | if (data) | ||
2026 | fsf_req->data = (unsigned long) data; | ||
2027 | |||
2028 | zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
2029 | retval = zfcp_fsf_req_send(fsf_req); | ||
2030 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | ||
1990 | lock_flags); | 2031 | lock_flags); |
2032 | if (retval) | ||
2033 | ZFCP_LOG_INFO("error: Could not send exchange configuration " | ||
2034 | "data command on the adapter %s\n", | ||
2035 | zfcp_get_busid_by_adapter(adapter)); | ||
2036 | else | ||
2037 | wait_event(fsf_req->completion_wq, | ||
2038 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | ||
2039 | |||
2040 | zfcp_fsf_req_free(fsf_req); | ||
2041 | |||
1991 | return retval; | 2042 | return retval; |
1992 | } | 2043 | } |
1993 | 2044 | ||
@@ -2016,11 +2067,17 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2016 | adapter->peer_d_id = 0; | 2067 | adapter->peer_d_id = 0; |
2017 | 2068 | ||
2018 | if (xchg_ok) { | 2069 | if (xchg_ok) { |
2070 | |||
2071 | if (fsf_req->data) | ||
2072 | memcpy((struct fsf_qtcb_bottom_config *) fsf_req->data, | ||
2073 | bottom, sizeof (struct fsf_qtcb_bottom_config)); | ||
2074 | |||
2019 | fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; | 2075 | fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; |
2020 | fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; | 2076 | fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; |
2021 | fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; | 2077 | fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; |
2022 | fc_host_speed(shost) = bottom->fc_link_speed; | 2078 | fc_host_speed(shost) = bottom->fc_link_speed; |
2023 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; | 2079 | fc_host_supported_classes(shost) = |
2080 | FC_COS_CLASS2 | FC_COS_CLASS3; | ||
2024 | adapter->hydra_version = bottom->adapter_type; | 2081 | adapter->hydra_version = bottom->adapter_type; |
2025 | if (fc_host_permanent_port_name(shost) == -1) | 2082 | if (fc_host_permanent_port_name(shost) == -1) |
2026 | fc_host_permanent_port_name(shost) = | 2083 | fc_host_permanent_port_name(shost) = |
@@ -2053,7 +2110,8 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2053 | min(FC_SERIAL_NUMBER_SIZE, 17)); | 2110 | min(FC_SERIAL_NUMBER_SIZE, 17)); |
2054 | } | 2111 | } |
2055 | 2112 | ||
2056 | ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" | 2113 | ZFCP_LOG_NORMAL("The adapter %s reported the following " |
2114 | "characteristics:\n" | ||
2057 | "WWNN 0x%016Lx, " | 2115 | "WWNN 0x%016Lx, " |
2058 | "WWPN 0x%016Lx, " | 2116 | "WWPN 0x%016Lx, " |
2059 | "S_ID 0x%06x,\n" | 2117 | "S_ID 0x%06x,\n" |
@@ -2090,7 +2148,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2090 | return 0; | 2148 | return 0; |
2091 | } | 2149 | } |
2092 | 2150 | ||
2093 | /* | 2151 | /** |
2094 | * function: zfcp_fsf_exchange_config_data_handler | 2152 | * function: zfcp_fsf_exchange_config_data_handler |
2095 | * | 2153 | * |
2096 | * purpose: is called for finished Exchange Configuration Data command | 2154 | * purpose: is called for finished Exchange Configuration Data command |
@@ -2125,7 +2183,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2125 | adapter->peer_wwpn, | 2183 | adapter->peer_wwpn, |
2126 | adapter->peer_d_id); | 2184 | adapter->peer_d_id); |
2127 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 2185 | debug_text_event(fsf_req->adapter->erp_dbf, 0, |
2128 | "top-p-to-p"); | 2186 | "top-p-to-p"); |
2129 | break; | 2187 | break; |
2130 | case FC_PORTTYPE_NLPORT: | 2188 | case FC_PORTTYPE_NLPORT: |
2131 | ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " | 2189 | ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " |
@@ -2138,8 +2196,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2138 | return -EIO; | 2196 | return -EIO; |
2139 | case FC_PORTTYPE_NPORT: | 2197 | case FC_PORTTYPE_NPORT: |
2140 | ZFCP_LOG_NORMAL("Switched fabric fibrechannel " | 2198 | ZFCP_LOG_NORMAL("Switched fabric fibrechannel " |
2141 | "network detected at adapter %s.\n", | 2199 | "network detected at adapter %s.\n", |
2142 | zfcp_get_busid_by_adapter(adapter)); | 2200 | zfcp_get_busid_by_adapter(adapter)); |
2143 | break; | 2201 | break; |
2144 | default: | 2202 | default: |
2145 | ZFCP_LOG_NORMAL("bug: The fibrechannel topology " | 2203 | ZFCP_LOG_NORMAL("bug: The fibrechannel topology " |
@@ -2179,7 +2237,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2179 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) | 2237 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) |
2180 | return -EIO; | 2238 | return -EIO; |
2181 | 2239 | ||
2182 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); | 2240 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, |
2241 | &adapter->status); | ||
2183 | 2242 | ||
2184 | zfcp_fsf_link_down_info_eval(adapter, | 2243 | zfcp_fsf_link_down_info_eval(adapter, |
2185 | &qtcb->header.fsf_status_qual.link_down_info); | 2244 | &qtcb->header.fsf_status_qual.link_down_info); |
@@ -2187,7 +2246,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2187 | default: | 2246 | default: |
2188 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); | 2247 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); |
2189 | debug_event(fsf_req->adapter->erp_dbf, 0, | 2248 | debug_event(fsf_req->adapter->erp_dbf, 0, |
2190 | &fsf_req->qtcb->header.fsf_status, sizeof (u32)); | 2249 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); |
2191 | zfcp_erp_adapter_shutdown(adapter, 0); | 2250 | zfcp_erp_adapter_shutdown(adapter, 0); |
2192 | return -EIO; | 2251 | return -EIO; |
2193 | } | 2252 | } |
@@ -2197,74 +2256,118 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2197 | /** | 2256 | /** |
2198 | * zfcp_fsf_exchange_port_data - request information about local port | 2257 | * zfcp_fsf_exchange_port_data - request information about local port |
2199 | * @erp_action: ERP action for the adapter for which port data is requested | 2258 | * @erp_action: ERP action for the adapter for which port data is requested |
2200 | * @adapter: for which port data is requested | ||
2201 | * @data: response to exchange port data request | ||
2202 | */ | 2259 | */ |
2203 | int | 2260 | int |
2204 | zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, | 2261 | zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) |
2205 | struct zfcp_adapter *adapter, | ||
2206 | struct fsf_qtcb_bottom_port *data) | ||
2207 | { | 2262 | { |
2208 | volatile struct qdio_buffer_element *sbale; | 2263 | volatile struct qdio_buffer_element *sbale; |
2209 | struct zfcp_fsf_req *fsf_req; | 2264 | struct zfcp_fsf_req *fsf_req; |
2265 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2210 | unsigned long lock_flags; | 2266 | unsigned long lock_flags; |
2211 | int retval = 0; | 2267 | int retval; |
2212 | 2268 | ||
2213 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { | 2269 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { |
2214 | ZFCP_LOG_INFO("error: exchange port data " | 2270 | ZFCP_LOG_INFO("error: exchange port data " |
2215 | "command not supported by adapter %s\n", | 2271 | "command not supported by adapter %s\n", |
2216 | zfcp_get_busid_by_adapter(adapter)); | 2272 | zfcp_get_busid_by_adapter(adapter)); |
2217 | return -EOPNOTSUPP; | 2273 | return -EOPNOTSUPP; |
2218 | } | 2274 | } |
2219 | 2275 | ||
2220 | /* setup new FSF request */ | 2276 | /* setup new FSF request */ |
2221 | retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | 2277 | retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, |
2222 | erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0, | 2278 | ZFCP_REQ_AUTO_CLEANUP, |
2223 | NULL, &lock_flags, &fsf_req); | 2279 | adapter->pool.fsf_req_erp, |
2224 | if (retval < 0) { | 2280 | &lock_flags, &fsf_req); |
2281 | if (retval) { | ||
2225 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " | 2282 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " |
2226 | "exchange port data request for" | 2283 | "exchange port data request for" |
2227 | "the adapter %s.\n", | 2284 | "the adapter %s.\n", |
2228 | zfcp_get_busid_by_adapter(adapter)); | 2285 | zfcp_get_busid_by_adapter(adapter)); |
2229 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | 2286 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
2230 | lock_flags); | 2287 | lock_flags); |
2231 | return retval; | 2288 | return retval; |
2232 | } | 2289 | } |
2233 | 2290 | ||
2234 | if (data) | ||
2235 | fsf_req->data = (unsigned long) data; | ||
2236 | |||
2237 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | 2291 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); |
2238 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | 2292 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; |
2239 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 2293 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
2240 | 2294 | ||
2241 | if (erp_action) { | 2295 | erp_action->fsf_req = fsf_req; |
2242 | erp_action->fsf_req = fsf_req; | 2296 | fsf_req->erp_action = erp_action; |
2243 | fsf_req->erp_action = erp_action; | 2297 | zfcp_erp_start_timer(fsf_req); |
2244 | zfcp_erp_start_timer(fsf_req); | ||
2245 | } else | ||
2246 | zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
2247 | 2298 | ||
2248 | retval = zfcp_fsf_req_send(fsf_req); | 2299 | retval = zfcp_fsf_req_send(fsf_req); |
2300 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); | ||
2301 | |||
2249 | if (retval) { | 2302 | if (retval) { |
2250 | ZFCP_LOG_INFO("error: Could not send an exchange port data " | 2303 | ZFCP_LOG_INFO("error: Could not send an exchange port data " |
2251 | "command on the adapter %s\n", | 2304 | "command on the adapter %s\n", |
2252 | zfcp_get_busid_by_adapter(adapter)); | 2305 | zfcp_get_busid_by_adapter(adapter)); |
2253 | zfcp_fsf_req_free(fsf_req); | 2306 | zfcp_fsf_req_free(fsf_req); |
2254 | if (erp_action) | 2307 | erp_action->fsf_req = NULL; |
2255 | erp_action->fsf_req = NULL; | 2308 | } |
2309 | else | ||
2310 | ZFCP_LOG_DEBUG("exchange port data request initiated " | ||
2311 | "(adapter %s)\n", | ||
2312 | zfcp_get_busid_by_adapter(adapter)); | ||
2313 | return retval; | ||
2314 | } | ||
2315 | |||
2316 | |||
2317 | /** | ||
2318 | * zfcp_fsf_exchange_port_data_sync - request information about local port | ||
2319 | * and wait until information is ready | ||
2320 | */ | ||
2321 | int | ||
2322 | zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | ||
2323 | struct fsf_qtcb_bottom_port *data) | ||
2324 | { | ||
2325 | volatile struct qdio_buffer_element *sbale; | ||
2326 | struct zfcp_fsf_req *fsf_req; | ||
2327 | unsigned long lock_flags; | ||
2328 | int retval; | ||
2329 | |||
2330 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { | ||
2331 | ZFCP_LOG_INFO("error: exchange port data " | ||
2332 | "command not supported by adapter %s\n", | ||
2333 | zfcp_get_busid_by_adapter(adapter)); | ||
2334 | return -EOPNOTSUPP; | ||
2335 | } | ||
2336 | |||
2337 | /* setup new FSF request */ | ||
2338 | retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | ||
2339 | 0, NULL, &lock_flags, &fsf_req); | ||
2340 | if (retval) { | ||
2341 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " | ||
2342 | "exchange port data request for" | ||
2343 | "the adapter %s.\n", | ||
2344 | zfcp_get_busid_by_adapter(adapter)); | ||
2256 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | 2345 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
2257 | lock_flags); | 2346 | lock_flags); |
2258 | return retval; | 2347 | return retval; |
2259 | } | 2348 | } |
2260 | 2349 | ||
2350 | if (data) | ||
2351 | fsf_req->data = (unsigned long) data; | ||
2352 | |||
2353 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | ||
2354 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | ||
2355 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | ||
2356 | |||
2357 | zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
2358 | retval = zfcp_fsf_req_send(fsf_req); | ||
2261 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); | 2359 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); |
2262 | 2360 | ||
2263 | if (!erp_action) { | 2361 | if (retval) |
2362 | ZFCP_LOG_INFO("error: Could not send an exchange port data " | ||
2363 | "command on the adapter %s\n", | ||
2364 | zfcp_get_busid_by_adapter(adapter)); | ||
2365 | else | ||
2264 | wait_event(fsf_req->completion_wq, | 2366 | wait_event(fsf_req->completion_wq, |
2265 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 2367 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
2266 | zfcp_fsf_req_free(fsf_req); | 2368 | |
2267 | } | 2369 | zfcp_fsf_req_free(fsf_req); |
2370 | |||
2268 | return retval; | 2371 | return retval; |
2269 | } | 2372 | } |
2270 | 2373 | ||
@@ -2277,18 +2380,16 @@ static void | |||
2277 | zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | 2380 | zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) |
2278 | { | 2381 | { |
2279 | struct zfcp_adapter *adapter; | 2382 | struct zfcp_adapter *adapter; |
2280 | struct fsf_qtcb *qtcb; | 2383 | struct fsf_qtcb_bottom_port *bottom; |
2281 | struct fsf_qtcb_bottom_port *bottom, *data; | ||
2282 | struct Scsi_Host *shost; | 2384 | struct Scsi_Host *shost; |
2283 | 2385 | ||
2284 | adapter = fsf_req->adapter; | 2386 | adapter = fsf_req->adapter; |
2285 | qtcb = fsf_req->qtcb; | 2387 | bottom = &fsf_req->qtcb->bottom.port; |
2286 | bottom = &qtcb->bottom.port; | ||
2287 | shost = adapter->scsi_host; | 2388 | shost = adapter->scsi_host; |
2288 | 2389 | ||
2289 | data = (struct fsf_qtcb_bottom_port*) fsf_req->data; | 2390 | if (fsf_req->data) |
2290 | if (data) | 2391 | memcpy((struct fsf_qtcb_bottom_port*) fsf_req->data, bottom, |
2291 | memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); | 2392 | sizeof(struct fsf_qtcb_bottom_port)); |
2292 | 2393 | ||
2293 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) | 2394 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) |
2294 | fc_host_permanent_port_name(shost) = bottom->wwpn; | 2395 | fc_host_permanent_port_name(shost) = bottom->wwpn; |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 3a7f3b87fb36..5fbbd21a88e4 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -731,7 +731,7 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost) | |||
731 | if (!data) | 731 | if (!data) |
732 | return NULL; | 732 | return NULL; |
733 | 733 | ||
734 | ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); | 734 | ret = zfcp_fsf_exchange_port_data_sync(adapter, data); |
735 | if (ret) { | 735 | if (ret) { |
736 | kfree(data); | 736 | kfree(data); |
737 | return NULL; /* XXX return zeroed fc_stats? */ | 737 | return NULL; /* XXX return zeroed fc_stats? */ |
@@ -761,7 +761,7 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) | |||
761 | if (!data) | 761 | if (!data) |
762 | return; | 762 | return; |
763 | 763 | ||
764 | ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); | 764 | ret = zfcp_fsf_exchange_port_data_sync(adapter, data); |
765 | if (ret) { | 765 | if (ret) { |
766 | kfree(data); | 766 | kfree(data); |
767 | } else { | 767 | } else { |
@@ -800,6 +800,7 @@ struct fc_function_template zfcp_transport_functions = { | |||
800 | .show_host_port_type = 1, | 800 | .show_host_port_type = 1, |
801 | .show_host_speed = 1, | 801 | .show_host_speed = 1, |
802 | .show_host_port_id = 1, | 802 | .show_host_port_id = 1, |
803 | .disable_target_scan = 1, | ||
803 | }; | 804 | }; |
804 | 805 | ||
805 | /** | 806 | /** |