diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 293 |
1 files changed, 197 insertions, 96 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 99299976e89..ff866ebd44a 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -80,10 +80,10 @@ static const char zfcp_act_subtable_type[5][8] = { | |||
80 | /* | 80 | /* |
81 | * function: zfcp_fsf_req_alloc | 81 | * function: zfcp_fsf_req_alloc |
82 | * | 82 | * |
83 | * purpose: Obtains an fsf_req and potentially a qtcb (for all but | 83 | * purpose: Obtains an fsf_req and potentially a qtcb (for all but |
84 | * unsolicited requests) via helper functions | 84 | * unsolicited requests) via helper functions |
85 | * Does some initial fsf request set-up. | 85 | * Does some initial fsf request set-up. |
86 | * | 86 | * |
87 | * returns: pointer to allocated fsf_req if successfull | 87 | * returns: pointer to allocated fsf_req if successfull |
88 | * NULL otherwise | 88 | * NULL otherwise |
89 | * | 89 | * |
@@ -192,7 +192,7 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) | |||
192 | * returns: 0 - success | 192 | * returns: 0 - success |
193 | * !0 - failure | 193 | * !0 - failure |
194 | * | 194 | * |
195 | * context: | 195 | * context: |
196 | */ | 196 | */ |
197 | int | 197 | int |
198 | zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) | 198 | zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) |
@@ -214,8 +214,8 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | /* | 216 | /* |
217 | * fsf_req may be deleted due to waking up functions, so | 217 | * fsf_req may be deleted due to waking up functions, so |
218 | * cleanup is saved here and used later | 218 | * cleanup is saved here and used later |
219 | */ | 219 | */ |
220 | if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) | 220 | if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) |
221 | cleanup = 1; | 221 | cleanup = 1; |
@@ -259,9 +259,9 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) | |||
259 | * and initiates appropriate actions | 259 | * and initiates appropriate actions |
260 | * (usually calling FSF command specific handlers) | 260 | * (usually calling FSF command specific handlers) |
261 | * | 261 | * |
262 | * returns: | 262 | * returns: |
263 | * | 263 | * |
264 | * context: | 264 | * context: |
265 | * | 265 | * |
266 | * locks: | 266 | * locks: |
267 | */ | 267 | */ |
@@ -638,7 +638,7 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, | |||
638 | * | 638 | * |
639 | * purpose: calls the appropriate command specific handler | 639 | * purpose: calls the appropriate command specific handler |
640 | * | 640 | * |
641 | * returns: | 641 | * returns: |
642 | */ | 642 | */ |
643 | static int | 643 | static int |
644 | zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | 644 | zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) |
@@ -854,7 +854,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) | |||
854 | * | 854 | * |
855 | * purpose: is called for finished Open Port command | 855 | * purpose: is called for finished Open Port command |
856 | * | 856 | * |
857 | * returns: | 857 | * returns: |
858 | */ | 858 | */ |
859 | static int | 859 | static int |
860 | zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | 860 | zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) |
@@ -1088,7 +1088,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
1088 | * returns: address of initiated FSF request | 1088 | * returns: address of initiated FSF request |
1089 | * NULL - request could not be initiated | 1089 | * NULL - request could not be initiated |
1090 | * | 1090 | * |
1091 | * FIXME(design): should be watched by a timeout !!! | 1091 | * FIXME(design): should be watched by a timeout !!! |
1092 | * FIXME(design) shouldn't this be modified to return an int | 1092 | * FIXME(design) shouldn't this be modified to return an int |
1093 | * also...don't know how though | 1093 | * also...don't know how though |
1094 | */ | 1094 | */ |
@@ -1157,7 +1157,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
1157 | * | 1157 | * |
1158 | * purpose: is called for finished Abort FCP Command request | 1158 | * purpose: is called for finished Abort FCP Command request |
1159 | * | 1159 | * |
1160 | * returns: | 1160 | * returns: |
1161 | */ | 1161 | */ |
1162 | static int | 1162 | static int |
1163 | zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | 1163 | zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) |
@@ -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; |
@@ -2336,10 +2437,10 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2336 | /* | 2437 | /* |
2337 | * function: zfcp_fsf_open_port | 2438 | * function: zfcp_fsf_open_port |
2338 | * | 2439 | * |
2339 | * purpose: | 2440 | * purpose: |
2340 | * | 2441 | * |
2341 | * returns: address of initiated FSF request | 2442 | * returns: address of initiated FSF request |
2342 | * NULL - request could not be initiated | 2443 | * NULL - request could not be initiated |
2343 | */ | 2444 | */ |
2344 | int | 2445 | int |
2345 | zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | 2446 | zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) |
@@ -2400,7 +2501,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
2400 | * | 2501 | * |
2401 | * purpose: is called for finished Open Port command | 2502 | * purpose: is called for finished Open Port command |
2402 | * | 2503 | * |
2403 | * returns: | 2504 | * returns: |
2404 | */ | 2505 | */ |
2405 | static int | 2506 | static int |
2406 | zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | 2507 | zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) |
@@ -3002,7 +3103,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
3002 | * | 3103 | * |
3003 | * purpose: is called for finished Open LUN command | 3104 | * purpose: is called for finished Open LUN command |
3004 | * | 3105 | * |
3005 | * returns: | 3106 | * returns: |
3006 | */ | 3107 | */ |
3007 | static int | 3108 | static int |
3008 | zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | 3109 | zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) |
@@ -3265,7 +3366,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3265 | * purpose: | 3366 | * purpose: |
3266 | * | 3367 | * |
3267 | * returns: address of fsf_req - request successfully initiated | 3368 | * returns: address of fsf_req - request successfully initiated |
3268 | * NULL - | 3369 | * NULL - |
3269 | * | 3370 | * |
3270 | * assumptions: This routine does not check whether the associated | 3371 | * assumptions: This routine does not check whether the associated |
3271 | * remote port/lun has already been opened. This should be | 3372 | * remote port/lun has already been opened. This should be |
@@ -3586,17 +3687,17 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
3586 | ZFCP_LOG_DEBUG( | 3687 | ZFCP_LOG_DEBUG( |
3587 | "Data did not fit into available buffer(s), " | 3688 | "Data did not fit into available buffer(s), " |
3588 | "waiting for more...\n"); | 3689 | "waiting for more...\n"); |
3589 | retval = -EIO; | 3690 | retval = -EIO; |
3590 | } else { | 3691 | } else { |
3591 | ZFCP_LOG_NORMAL("error: No truncation implemented but " | 3692 | ZFCP_LOG_NORMAL("error: No truncation implemented but " |
3592 | "required. Shutting down unit " | 3693 | "required. Shutting down unit " |
3593 | "(adapter %s, port 0x%016Lx, " | 3694 | "(adapter %s, port 0x%016Lx, " |
3594 | "unit 0x%016Lx)\n", | 3695 | "unit 0x%016Lx)\n", |
3595 | zfcp_get_busid_by_unit(unit), | 3696 | zfcp_get_busid_by_unit(unit), |
3596 | unit->port->wwpn, | 3697 | unit->port->wwpn, |
3597 | unit->fcp_lun); | 3698 | unit->fcp_lun); |
3598 | zfcp_erp_unit_shutdown(unit, 0); | 3699 | zfcp_erp_unit_shutdown(unit, 0); |
3599 | retval = -EINVAL; | 3700 | retval = -EINVAL; |
3600 | } | 3701 | } |
3601 | goto no_fit; | 3702 | goto no_fit; |
3602 | } | 3703 | } |
@@ -3727,7 +3828,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, | |||
3727 | * | 3828 | * |
3728 | * purpose: is called for finished Send FCP Command | 3829 | * purpose: is called for finished Send FCP Command |
3729 | * | 3830 | * |
3730 | * returns: | 3831 | * returns: |
3731 | */ | 3832 | */ |
3732 | static int | 3833 | static int |
3733 | zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | 3834 | zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) |
@@ -3964,7 +4065,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3964 | * | 4065 | * |
3965 | * purpose: evaluates FCP_RSP IU | 4066 | * purpose: evaluates FCP_RSP IU |
3966 | * | 4067 | * |
3967 | * returns: | 4068 | * returns: |
3968 | */ | 4069 | */ |
3969 | static int | 4070 | static int |
3970 | zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | 4071 | zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) |
@@ -4192,7 +4293,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4192 | * | 4293 | * |
4193 | * purpose: evaluates FCP_RSP IU | 4294 | * purpose: evaluates FCP_RSP IU |
4194 | * | 4295 | * |
4195 | * returns: | 4296 | * returns: |
4196 | */ | 4297 | */ |
4197 | static int | 4298 | static int |
4198 | zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) | 4299 | zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) |
@@ -4635,7 +4736,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
4635 | INIT_LIST_HEAD(&fsf_req->list); | 4736 | INIT_LIST_HEAD(&fsf_req->list); |
4636 | init_timer(&fsf_req->timer); | 4737 | init_timer(&fsf_req->timer); |
4637 | 4738 | ||
4638 | /* initialize waitqueue which may be used to wait on | 4739 | /* initialize waitqueue which may be used to wait on |
4639 | this request completion */ | 4740 | this request completion */ |
4640 | init_waitqueue_head(&fsf_req->completion_wq); | 4741 | init_waitqueue_head(&fsf_req->completion_wq); |
4641 | 4742 | ||