zfcp_fsf.c 70.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
L
Linus Torvalds 已提交
2
/*
C
Christof Schmitt 已提交
3
 * zfcp device driver
L
Linus Torvalds 已提交
4
 *
C
Christof Schmitt 已提交
5
 * Implementation of FSF commands.
L
Linus Torvalds 已提交
6
 *
7
 * Copyright IBM Corp. 2002, 2018
L
Linus Torvalds 已提交
8 9
 */

10 11 12
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

S
Stefan Raspl 已提交
13
#include <linux/blktrace_api.h>
14
#include <linux/jiffies.h>
15
#include <linux/types.h>
16
#include <linux/slab.h>
17
#include <scsi/fc/fc_els.h>
L
Linus Torvalds 已提交
18
#include "zfcp_ext.h"
19
#include "zfcp_fc.h"
20
#include "zfcp_dbf.h"
21
#include "zfcp_qdio.h"
22
#include "zfcp_reqlist.h"
23
#include "zfcp_diag.h"
L
Linus Torvalds 已提交
24

25 26 27 28 29
/* timeout for FSF requests sent during scsi_eh: abort or FCP TMF */
#define ZFCP_FSF_SCSI_ER_TIMEOUT (10*HZ)
/* timeout for: exchange config/port data outside ERP, or open/close WKA port */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)

30 31
struct kmem_cache *zfcp_fsf_qtcb_cache;

32 33 34 35 36
static bool ber_stop = true;
module_param(ber_stop, bool, 0600);
MODULE_PARM_DESC(ber_stop,
		 "Shuts down FCP devices for FCP channels that report a bit-error count in excess of its threshold (default on)");

37
static void zfcp_fsf_request_timeout_handler(struct timer_list *t)
38
{
39 40
	struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer);
	struct zfcp_adapter *adapter = fsf_req->adapter;
41

42
	zfcp_qdio_siosl(adapter);
43
	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
44
				"fsrth_1");
45 46 47 48 49
}

static void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req,
				 unsigned long timeout)
{
50
	fsf_req->timer.function = zfcp_fsf_request_timeout_handler;
51 52 53 54 55 56 57
	fsf_req->timer.expires = jiffies + timeout;
	add_timer(&fsf_req->timer);
}

static void zfcp_fsf_start_erp_timer(struct zfcp_fsf_req *fsf_req)
{
	BUG_ON(!fsf_req->erp_action);
58
	fsf_req->timer.function = zfcp_erp_timeout_handler;
59 60 61 62
	fsf_req->timer.expires = jiffies + 30 * HZ;
	add_timer(&fsf_req->timer);
}

L
Linus Torvalds 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
/* association between FSF command and FSF QTCB type */
static u32 fsf_qtcb_type[] = {
	[FSF_QTCB_FCP_CMND] =             FSF_IO_COMMAND,
	[FSF_QTCB_ABORT_FCP_CMND] =       FSF_SUPPORT_COMMAND,
	[FSF_QTCB_OPEN_PORT_WITH_DID] =   FSF_SUPPORT_COMMAND,
	[FSF_QTCB_OPEN_LUN] =             FSF_SUPPORT_COMMAND,
	[FSF_QTCB_CLOSE_LUN] =            FSF_SUPPORT_COMMAND,
	[FSF_QTCB_CLOSE_PORT] =           FSF_SUPPORT_COMMAND,
	[FSF_QTCB_CLOSE_PHYSICAL_PORT] =  FSF_SUPPORT_COMMAND,
	[FSF_QTCB_SEND_ELS] =             FSF_SUPPORT_COMMAND,
	[FSF_QTCB_SEND_GENERIC] =         FSF_SUPPORT_COMMAND,
	[FSF_QTCB_EXCHANGE_CONFIG_DATA] = FSF_CONFIG_COMMAND,
	[FSF_QTCB_EXCHANGE_PORT_DATA] =   FSF_PORT_COMMAND,
	[FSF_QTCB_DOWNLOAD_CONTROL_FILE] = FSF_SUPPORT_COMMAND,
	[FSF_QTCB_UPLOAD_CONTROL_FILE] =  FSF_SUPPORT_COMMAND
};

C
Christof Schmitt 已提交
80 81
static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
{
82 83
	dev_err(&req->adapter->ccw_device->dev, "FCP device not "
		"operational because of an unsupported FC class\n");
84
	zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1");
C
Christof Schmitt 已提交
85 86 87
	req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}

S
Swen Schillig 已提交
88 89
/**
 * zfcp_fsf_req_free - free memory used by fsf request
90
 * @req: pointer to struct zfcp_fsf_req
L
Linus Torvalds 已提交
91
 */
S
Swen Schillig 已提交
92
void zfcp_fsf_req_free(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
93
{
S
Swen Schillig 已提交
94
	if (likely(req->pool)) {
95
		if (likely(!zfcp_fsf_req_is_status_read_buffer(req)))
96
			mempool_free(req->qtcb, req->adapter->pool.qtcb_pool);
S
Swen Schillig 已提交
97
		mempool_free(req, req->pool);
98 99 100
		return;
	}

101
	if (likely(!zfcp_fsf_req_is_status_read_buffer(req)))
102
		kmem_cache_free(zfcp_fsf_qtcb_cache, req->qtcb);
103
	kfree(req);
L
Linus Torvalds 已提交
104 105
}

S
Swen Schillig 已提交
106
static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
107
{
108
	unsigned long flags;
S
Swen Schillig 已提交
109 110 111
	struct fsf_status_read_buffer *sr_buf = req->data;
	struct zfcp_adapter *adapter = req->adapter;
	struct zfcp_port *port;
112
	int d_id = ntoh24(sr_buf->d_id);
L
Linus Torvalds 已提交
113

114 115
	read_lock_irqsave(&adapter->port_list_lock, flags);
	list_for_each_entry(port, &adapter->port_list, list)
S
Swen Schillig 已提交
116
		if (port->d_id == d_id) {
117
			zfcp_erp_port_reopen(port, 0, "fssrpc1");
118
			break;
S
Swen Schillig 已提交
119
		}
120
	read_unlock_irqrestore(&adapter->port_list_lock, flags);
L
Linus Torvalds 已提交
121 122
}

123
static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req,
S
Swen Schillig 已提交
124
					 struct fsf_link_down_info *link_down)
125
{
S
Swen Schillig 已提交
126
	struct zfcp_adapter *adapter = req->adapter;
127

S
Swen Schillig 已提交
128
	if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED)
129 130
		return;

131
	atomic_or(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
132

133
	zfcp_scsi_schedule_rports_block(adapter);
134

S
Swen Schillig 已提交
135
	if (!link_down)
136
		goto out;
137

138 139
	switch (link_down->error_code) {
	case FSF_PSQ_LINK_NO_LIGHT:
S
Swen Schillig 已提交
140
		dev_warn(&req->adapter->ccw_device->dev,
141 142
			 "There is no light signal from the local "
			 "fibre channel cable\n");
143 144
		break;
	case FSF_PSQ_LINK_WRAP_PLUG:
S
Swen Schillig 已提交
145
		dev_warn(&req->adapter->ccw_device->dev,
146 147
			 "There is a wrap plug instead of a fibre "
			 "channel cable\n");
148 149
		break;
	case FSF_PSQ_LINK_NO_FCP:
S
Swen Schillig 已提交
150
		dev_warn(&req->adapter->ccw_device->dev,
151 152
			 "The adjacent fibre channel node does not "
			 "support FCP\n");
153 154
		break;
	case FSF_PSQ_LINK_FIRMWARE_UPDATE:
S
Swen Schillig 已提交
155
		dev_warn(&req->adapter->ccw_device->dev,
156 157
			 "The FCP device is suspended because of a "
			 "firmware update\n");
C
Christof Schmitt 已提交
158
		break;
159
	case FSF_PSQ_LINK_INVALID_WWPN:
S
Swen Schillig 已提交
160
		dev_warn(&req->adapter->ccw_device->dev,
161 162
			 "The FCP device detected a WWPN that is "
			 "duplicate or not valid\n");
163 164
		break;
	case FSF_PSQ_LINK_NO_NPIV_SUPPORT:
S
Swen Schillig 已提交
165
		dev_warn(&req->adapter->ccw_device->dev,
166
			 "The fibre channel fabric does not support NPIV\n");
167 168
		break;
	case FSF_PSQ_LINK_NO_FCP_RESOURCES:
S
Swen Schillig 已提交
169
		dev_warn(&req->adapter->ccw_device->dev,
170
			 "The FCP adapter cannot support more NPIV ports\n");
171 172
		break;
	case FSF_PSQ_LINK_NO_FABRIC_RESOURCES:
S
Swen Schillig 已提交
173
		dev_warn(&req->adapter->ccw_device->dev,
174 175
			 "The adjacent switch cannot support "
			 "more NPIV ports\n");
176 177
		break;
	case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE:
S
Swen Schillig 已提交
178
		dev_warn(&req->adapter->ccw_device->dev,
179 180
			 "The FCP adapter could not log in to the "
			 "fibre channel fabric\n");
181 182
		break;
	case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED:
S
Swen Schillig 已提交
183
		dev_warn(&req->adapter->ccw_device->dev,
184 185
			 "The WWPN assignment file on the FCP adapter "
			 "has been damaged\n");
186 187
		break;
	case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED:
S
Swen Schillig 已提交
188
		dev_warn(&req->adapter->ccw_device->dev,
189 190
			 "The mode table on the FCP adapter "
			 "has been damaged\n");
191 192
		break;
	case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT:
S
Swen Schillig 已提交
193
		dev_warn(&req->adapter->ccw_device->dev,
194 195
			 "All NPIV ports on the FCP adapter have "
			 "been assigned\n");
196 197
		break;
	default:
S
Swen Schillig 已提交
198
		dev_warn(&req->adapter->ccw_device->dev,
199 200
			 "The link between the FCP adapter and "
			 "the FC fabric is down\n");
201
	}
S
Swen Schillig 已提交
202
out:
203
	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
204 205
}

S
Swen Schillig 已提交
206
static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
207
{
S
Swen Schillig 已提交
208 209 210
	struct fsf_status_read_buffer *sr_buf = req->data;
	struct fsf_link_down_info *ldi =
		(struct fsf_link_down_info *) &sr_buf->payload;
L
Linus Torvalds 已提交
211

S
Swen Schillig 已提交
212 213 214
	switch (sr_buf->status_subtype) {
	case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
	case FSF_STATUS_READ_SUB_FDISC_FAILED:
215
		zfcp_fsf_link_down_info_eval(req, ldi);
L
Linus Torvalds 已提交
216
		break;
S
Swen Schillig 已提交
217
	case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
218
		zfcp_fsf_link_down_info_eval(req, NULL);
219
	}
S
Swen Schillig 已提交
220
}
L
Linus Torvalds 已提交
221

S
Swen Schillig 已提交
222 223 224 225
static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
{
	struct zfcp_adapter *adapter = req->adapter;
	struct fsf_status_read_buffer *sr_buf = req->data;
L
Linus Torvalds 已提交
226

S
Swen Schillig 已提交
227
	if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
228
		zfcp_dbf_hba_fsf_uss("fssrh_1", req);
229
		mempool_free(virt_to_page(sr_buf), adapter->pool.sr_data);
S
Swen Schillig 已提交
230 231 232
		zfcp_fsf_req_free(req);
		return;
	}
L
Linus Torvalds 已提交
233

234
	zfcp_dbf_hba_fsf_uss("fssrh_4", req);
L
Linus Torvalds 已提交
235

S
Swen Schillig 已提交
236 237 238
	switch (sr_buf->status_type) {
	case FSF_STATUS_READ_PORT_CLOSED:
		zfcp_fsf_status_read_port_closed(req);
L
Linus Torvalds 已提交
239
		break;
S
Swen Schillig 已提交
240 241
	case FSF_STATUS_READ_INCOMING_ELS:
		zfcp_fc_incoming_els(req);
L
Linus Torvalds 已提交
242
		break;
S
Swen Schillig 已提交
243
	case FSF_STATUS_READ_SENSE_DATA_AVAIL:
L
Linus Torvalds 已提交
244
		break;
S
Swen Schillig 已提交
245
	case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
246
		zfcp_dbf_hba_bit_err("fssrh_3", req);
247 248 249 250 251 252 253 254
		if (ber_stop) {
			dev_warn(&adapter->ccw_device->dev,
				 "All paths over this FCP device are disused because of excessive bit errors\n");
			zfcp_erp_adapter_shutdown(adapter, 0, "fssrh_b");
		} else {
			dev_warn(&adapter->ccw_device->dev,
				 "The error threshold for checksum statistics has been exceeded\n");
		}
L
Linus Torvalds 已提交
255
		break;
S
Swen Schillig 已提交
256 257
	case FSF_STATUS_READ_LINK_DOWN:
		zfcp_fsf_status_read_link_down(req);
258
		zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKDOWN, 0);
S
Swen Schillig 已提交
259 260 261
		break;
	case FSF_STATUS_READ_LINK_UP:
		dev_info(&adapter->ccw_device->dev,
262
			 "The local link has been restored\n");
S
Swen Schillig 已提交
263
		/* All ports should be marked as ready to run again */
264 265
		zfcp_erp_set_adapter_status(adapter,
					    ZFCP_STATUS_COMMON_RUNNING);
S
Swen Schillig 已提交
266 267 268
		zfcp_erp_adapter_reopen(adapter,
					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
					ZFCP_STATUS_COMMON_ERP_FAILED,
269
					"fssrh_2");
270 271
		zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKUP, 0);

S
Swen Schillig 已提交
272 273 274
		break;
	case FSF_STATUS_READ_NOTIFICATION_LOST:
		if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
275
			zfcp_fc_conditional_port_scan(adapter);
S
Swen Schillig 已提交
276 277 278
		break;
	case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
		adapter->adapter_features = sr_buf->payload.word[0];
L
Linus Torvalds 已提交
279 280 281
		break;
	}

282
	mempool_free(virt_to_page(sr_buf), adapter->pool.sr_data);
S
Swen Schillig 已提交
283
	zfcp_fsf_req_free(req);
L
Linus Torvalds 已提交
284

S
Swen Schillig 已提交
285
	atomic_inc(&adapter->stat_miss);
286
	queue_work(adapter->work_queue, &adapter->stat_work);
S
Swen Schillig 已提交
287
}
L
Linus Torvalds 已提交
288

S
Swen Schillig 已提交
289 290 291 292 293 294 295 296 297 298 299 300
static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
{
	switch (req->qtcb->header.fsf_status_qual.word[0]) {
	case FSF_SQ_FCP_RSP_AVAILABLE:
	case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
	case FSF_SQ_NO_RETRY_POSSIBLE:
	case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
		return;
	case FSF_SQ_COMMAND_ABORTED:
		break;
	case FSF_SQ_NO_RECOM:
		dev_err(&req->adapter->ccw_device->dev,
301 302
			"The FCP adapter reported a problem "
			"that cannot be recovered\n");
303
		zfcp_qdio_siosl(req->adapter);
304
		zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1");
S
Swen Schillig 已提交
305 306 307 308
		break;
	}
	/* all non-return stats set FSFREQ_ERROR*/
	req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
309 310
}

S
Swen Schillig 已提交
311
static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
312
{
S
Swen Schillig 已提交
313 314
	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
		return;
L
Linus Torvalds 已提交
315

S
Swen Schillig 已提交
316 317 318
	switch (req->qtcb->header.fsf_status) {
	case FSF_UNKNOWN_COMMAND:
		dev_err(&req->adapter->ccw_device->dev,
319
			"The FCP adapter does not recognize the command 0x%x\n",
S
Swen Schillig 已提交
320
			req->qtcb->header.fsf_command);
321
		zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1");
S
Swen Schillig 已提交
322 323 324 325 326 327 328
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		zfcp_fsf_fsfstatus_qual_eval(req);
		break;
	}
}
L
Linus Torvalds 已提交
329

S
Swen Schillig 已提交
330 331 332 333 334
static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
{
	struct zfcp_adapter *adapter = req->adapter;
	struct fsf_qtcb *qtcb = req->qtcb;
	union fsf_prot_status_qual *psq = &qtcb->prefix.prot_status_qual;
L
Linus Torvalds 已提交
335

S
Swen Schillig 已提交
336
	zfcp_dbf_hba_fsf_response(req);
L
Linus Torvalds 已提交
337

S
Swen Schillig 已提交
338
	if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
339
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
S
Swen Schillig 已提交
340 341
		return;
	}
L
Linus Torvalds 已提交
342

S
Swen Schillig 已提交
343 344 345 346 347 348
	switch (qtcb->prefix.prot_status) {
	case FSF_PROT_GOOD:
	case FSF_PROT_FSF_STATUS_PRESENTED:
		return;
	case FSF_PROT_QTCB_VERSION_ERROR:
		dev_err(&adapter->ccw_device->dev,
349 350 351
			"QTCB version 0x%x not supported by FCP adapter "
			"(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION,
			psq->word[0], psq->word[1]);
352
		zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1");
S
Swen Schillig 已提交
353 354 355
		break;
	case FSF_PROT_ERROR_STATE:
	case FSF_PROT_SEQ_NUMB_ERROR:
356
		zfcp_erp_adapter_reopen(adapter, 0, "fspse_2");
357
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
S
Swen Schillig 已提交
358 359 360
		break;
	case FSF_PROT_UNSUPP_QTCB_TYPE:
		dev_err(&adapter->ccw_device->dev,
361
			"The QTCB type is not supported by the FCP adapter\n");
362
		zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3");
S
Swen Schillig 已提交
363 364
		break;
	case FSF_PROT_HOST_CONNECTION_INITIALIZING:
365
		atomic_or(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
S
Swen Schillig 已提交
366 367 368 369
				&adapter->status);
		break;
	case FSF_PROT_DUPLICATE_REQUEST_ID:
		dev_err(&adapter->ccw_device->dev,
370
			"0x%Lx is an ambiguous request identifier\n",
S
Swen Schillig 已提交
371
			(unsigned long long)qtcb->bottom.support.req_handle);
372
		zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4");
S
Swen Schillig 已提交
373 374
		break;
	case FSF_PROT_LINK_DOWN:
375
		zfcp_fsf_link_down_info_eval(req, &psq->link_down_info);
376
		/* go through reopen to flush pending requests */
377
		zfcp_erp_adapter_reopen(adapter, 0, "fspse_6");
S
Swen Schillig 已提交
378 379 380
		break;
	case FSF_PROT_REEST_QUEUE:
		/* All ports should be marked as ready to run again */
381 382
		zfcp_erp_set_adapter_status(adapter,
					    ZFCP_STATUS_COMMON_RUNNING);
S
Swen Schillig 已提交
383 384
		zfcp_erp_adapter_reopen(adapter,
					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
385
					ZFCP_STATUS_COMMON_ERP_FAILED,
386
					"fspse_8");
S
Swen Schillig 已提交
387 388 389
		break;
	default:
		dev_err(&adapter->ccw_device->dev,
390
			"0x%x is not a valid transfer protocol status\n",
S
Swen Schillig 已提交
391
			qtcb->prefix.prot_status);
392
		zfcp_qdio_siosl(adapter);
393
		zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9");
S
Swen Schillig 已提交
394 395
	}
	req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
396 397
}

S
Swen Schillig 已提交
398 399
/**
 * zfcp_fsf_req_complete - process completion of a FSF request
400
 * @req: The FSF request that has been completed.
S
Swen Schillig 已提交
401 402 403 404 405 406
 *
 * When a request has been completed either from the FCP adapter,
 * or it has been dismissed due to a queue shutdown, this function
 * is called to process the completion status and trigger further
 * events related to the FSF request.
 */
407
static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
408
{
409
	if (unlikely(zfcp_fsf_req_is_status_read_buffer(req))) {
S
Swen Schillig 已提交
410 411 412
		zfcp_fsf_status_read_handler(req);
		return;
	}
L
Linus Torvalds 已提交
413

S
Swen Schillig 已提交
414 415 416 417
	del_timer(&req->timer);
	zfcp_fsf_protstatus_eval(req);
	zfcp_fsf_fsfstatus_eval(req);
	req->handler(req);
L
Linus Torvalds 已提交
418

S
Swen Schillig 已提交
419
	if (req->erp_action)
420
		zfcp_erp_notify(req->erp_action, 0);
L
Linus Torvalds 已提交
421

S
Swen Schillig 已提交
422 423 424
	if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP))
		zfcp_fsf_req_free(req);
	else
425
		complete(&req->completion);
S
Swen Schillig 已提交
426
}
L
Linus Torvalds 已提交
427

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
/**
 * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
 * @adapter: pointer to struct zfcp_adapter
 *
 * Never ever call this without shutting down the adapter first.
 * Otherwise the adapter would continue using and corrupting s390 storage.
 * Included BUG_ON() call to ensure this is done.
 * ERP is supposed to be the only user of this function.
 */
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
	struct zfcp_fsf_req *req, *tmp;
	LIST_HEAD(remove_queue);

	BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
443
	zfcp_reqlist_move(adapter->req_list, &remove_queue);
444 445 446 447 448 449 450 451

	list_for_each_entry_safe(req, tmp, &remove_queue, list) {
		list_del(&req->list);
		req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
		zfcp_fsf_req_complete(req);
	}
}

452 453 454 455 456 457
#define ZFCP_FSF_PORTSPEED_1GBIT	(1 <<  0)
#define ZFCP_FSF_PORTSPEED_2GBIT	(1 <<  1)
#define ZFCP_FSF_PORTSPEED_4GBIT	(1 <<  2)
#define ZFCP_FSF_PORTSPEED_10GBIT	(1 <<  3)
#define ZFCP_FSF_PORTSPEED_8GBIT	(1 <<  4)
#define ZFCP_FSF_PORTSPEED_16GBIT	(1 <<  5)
458 459 460
#define ZFCP_FSF_PORTSPEED_32GBIT	(1 <<  6)
#define ZFCP_FSF_PORTSPEED_64GBIT	(1 <<  7)
#define ZFCP_FSF_PORTSPEED_128GBIT	(1 <<  8)
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
#define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15)

static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
{
	u32 fdmi_speed = 0;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_1GBIT)
		fdmi_speed |= FC_PORTSPEED_1GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_2GBIT)
		fdmi_speed |= FC_PORTSPEED_2GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_4GBIT)
		fdmi_speed |= FC_PORTSPEED_4GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_10GBIT)
		fdmi_speed |= FC_PORTSPEED_10GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_8GBIT)
		fdmi_speed |= FC_PORTSPEED_8GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_16GBIT)
		fdmi_speed |= FC_PORTSPEED_16GBIT;
478 479 480 481 482 483
	if (fsf_speed & ZFCP_FSF_PORTSPEED_32GBIT)
		fdmi_speed |= FC_PORTSPEED_32GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_64GBIT)
		fdmi_speed |= FC_PORTSPEED_64GBIT;
	if (fsf_speed & ZFCP_FSF_PORTSPEED_128GBIT)
		fdmi_speed |= FC_PORTSPEED_128GBIT;
484 485 486 487 488
	if (fsf_speed & ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED)
		fdmi_speed |= FC_PORTSPEED_NOT_NEGOTIATED;
	return fdmi_speed;
}

S
Swen Schillig 已提交
489 490
static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
{
491
	struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
S
Swen Schillig 已提交
492 493
	struct zfcp_adapter *adapter = req->adapter;
	struct Scsi_Host *shost = adapter->scsi_host;
494
	struct fc_els_flogi *nsp, *plogi;
L
Linus Torvalds 已提交
495

496 497 498 499 500
	/* adjust pointers for missing command code */
	nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
					- sizeof(u32));
	plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
					- sizeof(u32));
L
Linus Torvalds 已提交
501

S
Swen Schillig 已提交
502 503 504
	if (req->data)
		memcpy(req->data, bottom, sizeof(*bottom));

505 506
	fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn);
	fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn);
S
Swen Schillig 已提交
507 508
	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;

509
	adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK;
510 511
	adapter->stat_read_buf_num = max(bottom->status_read_buf_num,
					 (u16)FSF_STATUS_READS_RECOM);
S
Swen Schillig 已提交
512 513 514 515

	if (fc_host_permanent_port_name(shost) == -1)
		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);

516 517 518 519 520 521 522 523 524 525 526 527 528
	zfcp_scsi_set_prot(adapter);

	/* no error return above here, otherwise must fix call chains */
	/* do not evaluate invalid fields */
	if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE)
		return 0;

	fc_host_port_id(shost) = ntoh24(bottom->s_id);
	fc_host_speed(shost) =
		zfcp_fsf_convert_portspeed(bottom->fc_link_speed);

	adapter->hydra_version = bottom->adapter_type;

S
Swen Schillig 已提交
529 530
	switch (bottom->fc_topology) {
	case FSF_TOPO_P2P:
531
		adapter->peer_d_id = ntoh24(bottom->peer_d_id);
532 533
		adapter->peer_wwpn = be64_to_cpu(plogi->fl_wwpn);
		adapter->peer_wwnn = be64_to_cpu(plogi->fl_wwnn);
S
Swen Schillig 已提交
534 535 536
		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
		break;
	case FSF_TOPO_FABRIC:
537 538 539 540
		if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
			fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
		else
			fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
S
Swen Schillig 已提交
541 542 543
		break;
	case FSF_TOPO_AL:
		fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
544
		/* fall through */
S
Swen Schillig 已提交
545 546
	default:
		dev_err(&adapter->ccw_device->dev,
547 548
			"Unknown or unsupported arbitrated loop "
			"fibre channel topology detected\n");
549
		zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1");
S
Swen Schillig 已提交
550
		return -EIO;
L
Linus Torvalds 已提交
551
	}
S
Swen Schillig 已提交
552

L
Linus Torvalds 已提交
553 554 555
	return 0;
}

S
Swen Schillig 已提交
556
static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
C
Christof Schmitt 已提交
557 558
{
	struct zfcp_adapter *adapter = req->adapter;
559 560
	struct zfcp_diag_header *const diag_hdr =
		&adapter->diagnostics->config_data.header;
S
Swen Schillig 已提交
561 562 563
	struct fsf_qtcb *qtcb = req->qtcb;
	struct fsf_qtcb_bottom_config *bottom = &qtcb->bottom.config;
	struct Scsi_Host *shost = adapter->scsi_host;
C
Christof Schmitt 已提交
564

S
Swen Schillig 已提交
565 566
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
		return;
L
Linus Torvalds 已提交
567

S
Swen Schillig 已提交
568 569 570 571 572 573
	adapter->fsf_lic_version = bottom->lic_version;
	adapter->adapter_features = bottom->adapter_features;
	adapter->connection_features = bottom->connection_features;
	adapter->peer_wwpn = 0;
	adapter->peer_wwnn = 0;
	adapter->peer_d_id = 0;
574

S
Swen Schillig 已提交
575 576
	switch (qtcb->header.fsf_status) {
	case FSF_GOOD:
577 578 579 580 581 582
		/*
		 * usually we wait with an update till the cache is too old,
		 * but because we have the data available, update it anyway
		 */
		zfcp_diag_update_xdata(diag_hdr, bottom, false);

S
Swen Schillig 已提交
583 584
		if (zfcp_fsf_exchange_config_evaluate(req))
			return;
L
Linus Torvalds 已提交
585

S
Swen Schillig 已提交
586 587
		if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) {
			dev_err(&adapter->ccw_device->dev,
588 589 590
				"FCP adapter maximum QTCB size (%d bytes) "
				"is too small\n",
				bottom->max_qtcb_size);
591
			zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1");
S
Swen Schillig 已提交
592 593
			return;
		}
594
		atomic_or(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
S
Swen Schillig 已提交
595
				&adapter->status);
L
Linus Torvalds 已提交
596
		break;
S
Swen Schillig 已提交
597
	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
598
		zfcp_diag_update_xdata(diag_hdr, bottom, true);
599 600
		req->status |= ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE;

S
Swen Schillig 已提交
601 602 603 604 605 606
		fc_host_node_name(shost) = 0;
		fc_host_port_name(shost) = 0;
		fc_host_port_id(shost) = 0;
		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
		fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
		adapter->hydra_version = 0;
L
Linus Torvalds 已提交
607

608 609
		/* avoids adapter shutdown to be able to recognize
		 * events such as LINK UP */
610
		atomic_or(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
611
				&adapter->status);
612
		zfcp_fsf_link_down_info_eval(req,
S
Swen Schillig 已提交
613
			&qtcb->header.fsf_status_qual.link_down_info);
614 615
		if (zfcp_fsf_exchange_config_evaluate(req))
			return;
L
Linus Torvalds 已提交
616
		break;
S
Swen Schillig 已提交
617
	default:
618
		zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3");
S
Swen Schillig 已提交
619 620
		return;
	}
L
Linus Torvalds 已提交
621

S
Swen Schillig 已提交
622 623 624 625 626 627 628
	if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
		adapter->hardware_version = bottom->hardware_version;
		memcpy(fc_host_serial_number(shost), bottom->serial_number,
		       min(FC_SERIAL_NUMBER_SIZE, 17));
		EBCASC(fc_host_serial_number(shost),
		       min(FC_SERIAL_NUMBER_SIZE, 17));
	}
L
Linus Torvalds 已提交
629

S
Swen Schillig 已提交
630 631
	if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) {
		dev_err(&adapter->ccw_device->dev,
632 633
			"The FCP adapter only supports newer "
			"control block versions\n");
634
		zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4");
S
Swen Schillig 已提交
635 636 637 638
		return;
	}
	if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) {
		dev_err(&adapter->ccw_device->dev,
639 640
			"The FCP adapter only supports older "
			"control block versions\n");
641
		zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5");
S
Swen Schillig 已提交
642 643
	}
}
L
Linus Torvalds 已提交
644

S
Swen Schillig 已提交
645 646 647 648 649
static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
{
	struct zfcp_adapter *adapter = req->adapter;
	struct fsf_qtcb_bottom_port *bottom = &req->qtcb->bottom.port;
	struct Scsi_Host *shost = adapter->scsi_host;
L
Linus Torvalds 已提交
650

S
Swen Schillig 已提交
651 652
	if (req->data)
		memcpy(req->data, bottom, sizeof(*bottom));
653

654
	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
S
Swen Schillig 已提交
655
		fc_host_permanent_port_name(shost) = bottom->wwpn;
656
	} else
S
Swen Schillig 已提交
657 658
		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
659 660
	fc_host_supported_speeds(shost) =
		zfcp_fsf_convert_portspeed(bottom->supported_speed);
661 662 663 664
	memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
	       FC_FC4_LIST_SIZE);
	memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
	       FC_FC4_LIST_SIZE);
S
Swen Schillig 已提交
665
}
L
Linus Torvalds 已提交
666

S
Swen Schillig 已提交
667 668
static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
{
669 670
	struct zfcp_diag_header *const diag_hdr =
		&req->adapter->diagnostics->port_data.header;
S
Swen Schillig 已提交
671
	struct fsf_qtcb *qtcb = req->qtcb;
672
	struct fsf_qtcb_bottom_port *bottom = &qtcb->bottom.port;
S
Swen Schillig 已提交
673 674 675 676 677 678

	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
		return;

	switch (qtcb->header.fsf_status) {
	case FSF_GOOD:
679 680 681 682 683 684
		/*
		 * usually we wait with an update till the cache is too old,
		 * but because we have the data available, update it anyway
		 */
		zfcp_diag_update_xdata(diag_hdr, bottom, false);

S
Swen Schillig 已提交
685 686 687
		zfcp_fsf_exchange_port_evaluate(req);
		break;
	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
688
		zfcp_diag_update_xdata(diag_hdr, bottom, true);
689 690
		req->status |= ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE;

S
Swen Schillig 已提交
691
		zfcp_fsf_exchange_port_evaluate(req);
692
		zfcp_fsf_link_down_info_eval(req,
S
Swen Schillig 已提交
693
			&qtcb->header.fsf_status_qual.link_down_info);
694
		break;
L
Linus Torvalds 已提交
695
	}
S
Swen Schillig 已提交
696
}
697

698
static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool)
S
Swen Schillig 已提交
699 700
{
	struct zfcp_fsf_req *req;
701 702 703 704 705 706 707

	if (likely(pool))
		req = mempool_alloc(pool, GFP_ATOMIC);
	else
		req = kmalloc(sizeof(*req), GFP_ATOMIC);

	if (unlikely(!req))
S
Swen Schillig 已提交
708
		return NULL;
709

S
Swen Schillig 已提交
710
	memset(req, 0, sizeof(*req));
711
	req->pool = pool;
S
Swen Schillig 已提交
712 713 714
	return req;
}

715
static struct fsf_qtcb *zfcp_fsf_qtcb_alloc(mempool_t *pool)
S
Swen Schillig 已提交
716
{
717
	struct fsf_qtcb *qtcb;
S
Swen Schillig 已提交
718 719 720 721

	if (likely(pool))
		qtcb = mempool_alloc(pool, GFP_ATOMIC);
	else
722
		qtcb = kmem_cache_alloc(zfcp_fsf_qtcb_cache, GFP_ATOMIC);
723

S
Swen Schillig 已提交
724 725 726 727
	if (unlikely(!qtcb))
		return NULL;

	memset(qtcb, 0, sizeof(*qtcb));
728
	return qtcb;
S
Swen Schillig 已提交
729 730
}

731
static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio,
732
						u32 fsf_cmd, u8 sbtype,
733
						mempool_t *pool)
L
Linus Torvalds 已提交
734
{
735
	struct zfcp_adapter *adapter = qdio->adapter;
736
	struct zfcp_fsf_req *req = zfcp_fsf_alloc(pool);
L
Linus Torvalds 已提交
737

S
Swen Schillig 已提交
738
	if (unlikely(!req))
739
		return ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
740

S
Swen Schillig 已提交
741 742
	if (adapter->req_no == 0)
		adapter->req_no++;
L
Linus Torvalds 已提交
743

S
Swen Schillig 已提交
744
	INIT_LIST_HEAD(&req->list);
745
	timer_setup(&req->timer, NULL, 0);
746
	init_completion(&req->completion);
L
Linus Torvalds 已提交
747

S
Swen Schillig 已提交
748
	req->adapter = adapter;
749
	req->req_id = adapter->req_no;
S
Swen Schillig 已提交
750

751 752
	if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) {
		if (likely(pool))
753 754
			req->qtcb = zfcp_fsf_qtcb_alloc(
				adapter->pool.qtcb_pool);
755
		else
756
			req->qtcb = zfcp_fsf_qtcb_alloc(NULL);
757 758 759 760 761 762

		if (unlikely(!req->qtcb)) {
			zfcp_fsf_req_free(req);
			return ERR_PTR(-ENOMEM);
		}

763
		req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
S
Swen Schillig 已提交
764 765
		req->qtcb->prefix.req_id = req->req_id;
		req->qtcb->prefix.ulp_info = 26;
766
		req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_cmd];
S
Swen Schillig 已提交
767 768
		req->qtcb->prefix.qtcb_version = FSF_QTCB_CURRENT_VERSION;
		req->qtcb->header.req_handle = req->req_id;
769
		req->qtcb->header.fsf_command = fsf_cmd;
S
Swen Schillig 已提交
770 771
	}

772 773 774
	zfcp_qdio_req_init(adapter->qdio, &req->qdio_req, req->req_id, sbtype,
			   req->qtcb, sizeof(struct fsf_qtcb));

S
Swen Schillig 已提交
775
	return req;
L
Linus Torvalds 已提交
776 777
}

S
Swen Schillig 已提交
778 779
static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
{
780
	const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req);
S
Swen Schillig 已提交
781
	struct zfcp_adapter *adapter = req->adapter;
782
	struct zfcp_qdio *qdio = adapter->qdio;
783
	int req_id = req->req_id;
S
Swen Schillig 已提交
784

785
	zfcp_reqlist_add(adapter->req_list, req);
S
Swen Schillig 已提交
786

787
	req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q_free);
788
	req->issued = get_tod_clock();
789
	if (zfcp_qdio_send(qdio, &req->qdio_req)) {
S
Swen Schillig 已提交
790
		del_timer(&req->timer);
791
		/* lookup request again, list might have changed */
792
		zfcp_reqlist_find_rm(adapter->req_list, req_id);
793
		zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1");
S
Swen Schillig 已提交
794 795 796
		return -EIO;
	}

797 798 799 800 801 802 803 804 805 806 807 808
	/*
	 * NOTE: DO NOT TOUCH ASYNC req PAST THIS POINT.
	 *	 ONLY TOUCH SYNC req AGAIN ON req->completion.
	 *
	 * The request might complete and be freed concurrently at any point
	 * now. This is not protected by the QDIO-lock (req_q_lock). So any
	 * uncontrolled access after this might result in an use-after-free bug.
	 * Only if the request doesn't have ZFCP_STATUS_FSFREQ_CLEANUP set, and
	 * when it is completed via req->completion, is it safe to use req
	 * again.
	 */

S
Swen Schillig 已提交
809
	/* Don't increase for unsolicited status */
810
	if (!is_srb)
S
Swen Schillig 已提交
811
		adapter->fsf_req_seq_no++;
812
	adapter->req_no++;
S
Swen Schillig 已提交
813 814 815 816 817 818

	return 0;
}

/**
 * zfcp_fsf_status_read - send status read request
819
 * @qdio: pointer to struct zfcp_qdio
S
Swen Schillig 已提交
820
 * Returns: 0 on success, ERROR otherwise
L
Linus Torvalds 已提交
821
 */
822
int zfcp_fsf_status_read(struct zfcp_qdio *qdio)
L
Linus Torvalds 已提交
823
{
824
	struct zfcp_adapter *adapter = qdio->adapter;
S
Swen Schillig 已提交
825 826
	struct zfcp_fsf_req *req;
	struct fsf_status_read_buffer *sr_buf;
827
	struct page *page;
S
Swen Schillig 已提交
828
	int retval = -EIO;
L
Linus Torvalds 已提交
829

830
	spin_lock_irq(&qdio->req_q_lock);
831
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
832 833
		goto out;

834 835
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_UNSOLICITED_STATUS,
				  SBAL_SFLAGS0_TYPE_STATUS,
836
				  adapter->pool.status_read_req);
837
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
838 839
		retval = PTR_ERR(req);
		goto out;
L
Linus Torvalds 已提交
840 841
	}

842 843
	page = mempool_alloc(adapter->pool.sr_data, GFP_ATOMIC);
	if (!page) {
S
Swen Schillig 已提交
844 845 846
		retval = -ENOMEM;
		goto failed_buf;
	}
847
	sr_buf = page_address(page);
S
Swen Schillig 已提交
848 849
	memset(sr_buf, 0, sizeof(*sr_buf));
	req->data = sr_buf;
850 851 852

	zfcp_qdio_fill_next(qdio, &req->qdio_req, sr_buf, sizeof(*sr_buf));
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
853

S
Swen Schillig 已提交
854 855 856
	retval = zfcp_fsf_req_send(req);
	if (retval)
		goto failed_req_send;
857
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
L
Linus Torvalds 已提交
858

S
Swen Schillig 已提交
859 860 861
	goto out;

failed_req_send:
862
	req->data = NULL;
863
	mempool_free(virt_to_page(sr_buf), adapter->pool.sr_data);
S
Swen Schillig 已提交
864
failed_buf:
865
	zfcp_dbf_hba_fsf_uss("fssr__1", req);
S
Swen Schillig 已提交
866 867
	zfcp_fsf_req_free(req);
out:
868
	spin_unlock_irq(&qdio->req_q_lock);
S
Swen Schillig 已提交
869 870 871 872 873
	return retval;
}

static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
{
874
	struct scsi_device *sdev = req->data;
875
	struct zfcp_scsi_dev *zfcp_sdev;
S
Swen Schillig 已提交
876 877 878 879 880
	union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual;

	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
		return;

881 882
	zfcp_sdev = sdev_to_zfcp(sdev);

S
Swen Schillig 已提交
883
	switch (req->qtcb->header.fsf_status) {
L
Linus Torvalds 已提交
884
	case FSF_PORT_HANDLE_NOT_VALID:
S
Swen Schillig 已提交
885
		if (fsq->word[0] == fsq->word[1]) {
886
			zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0,
887
						"fsafch1");
S
Swen Schillig 已提交
888
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
889 890 891
		}
		break;
	case FSF_LUN_HANDLE_NOT_VALID:
S
Swen Schillig 已提交
892
		if (fsq->word[0] == fsq->word[1]) {
893
			zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fsafch2");
S
Swen Schillig 已提交
894
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
895 896 897
		}
		break;
	case FSF_FCP_COMMAND_DOES_NOT_EXIST:
S
Swen Schillig 已提交
898
		req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;
L
Linus Torvalds 已提交
899 900
		break;
	case FSF_PORT_BOXED:
901 902 903
		zfcp_erp_set_port_status(zfcp_sdev->port,
					 ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_port_reopen(zfcp_sdev->port,
904
				     ZFCP_STATUS_COMMON_ERP_FAILED, "fsafch3");
905
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
906 907
		break;
	case FSF_LUN_BOXED:
908 909
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
910
				    "fsafch4");
911
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
912 913
                break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
S
Swen Schillig 已提交
914
		switch (fsq->word[0]) {
L
Linus Torvalds 已提交
915
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
916
			zfcp_fc_test_link(zfcp_sdev->port);
917
			/* fall through */
L
Linus Torvalds 已提交
918
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
S
Swen Schillig 已提交
919
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
920 921 922 923
			break;
		}
		break;
	case FSF_GOOD:
S
Swen Schillig 已提交
924
		req->status |= ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED;
L
Linus Torvalds 已提交
925 926 927 928 929
		break;
	}
}

/**
930 931
 * zfcp_fsf_abort_fcp_cmnd - abort running SCSI command
 * @scmnd: The SCSI command to abort
S
Swen Schillig 已提交
932
 * Returns: pointer to struct zfcp_fsf_req
L
Linus Torvalds 已提交
933 934
 */

935
struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
L
Linus Torvalds 已提交
936
{
S
Swen Schillig 已提交
937
	struct zfcp_fsf_req *req = NULL;
938 939 940 941
	struct scsi_device *sdev = scmnd->device;
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
	struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
	unsigned long old_req_id = (unsigned long) scmnd->host_scribble;
942

943
	spin_lock_irq(&qdio->req_q_lock);
944
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
945
		goto out;
946
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND,
947
				  SBAL_SFLAGS0_TYPE_READ,
948
				  qdio->adapter->pool.scsi_abort);
949 950
	if (IS_ERR(req)) {
		req = NULL;
S
Swen Schillig 已提交
951
		goto out;
952
	}
953

954
	if (unlikely(!(atomic_read(&zfcp_sdev->status) &
S
Swen Schillig 已提交
955 956
		       ZFCP_STATUS_COMMON_UNBLOCKED)))
		goto out_error_free;
L
Linus Torvalds 已提交
957

958
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
959

960
	req->data = sdev;
S
Swen Schillig 已提交
961
	req->handler = zfcp_fsf_abort_fcp_command_handler;
962 963
	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
	req->qtcb->header.port_handle = zfcp_sdev->port->handle;
S
Swen Schillig 已提交
964 965
	req->qtcb->bottom.support.req_handle = (u64) old_req_id;

966
	zfcp_fsf_start_timer(req, ZFCP_FSF_SCSI_ER_TIMEOUT);
967 968
	if (!zfcp_fsf_req_send(req)) {
		/* NOTE: DO NOT TOUCH req, UNTIL IT COMPLETES! */
S
Swen Schillig 已提交
969
		goto out;
970
	}
S
Swen Schillig 已提交
971 972 973 974 975

out_error_free:
	zfcp_fsf_req_free(req);
	req = NULL;
out:
976
	spin_unlock_irq(&qdio->req_q_lock);
S
Swen Schillig 已提交
977
	return req;
L
Linus Torvalds 已提交
978 979
}

S
Swen Schillig 已提交
980
static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
981
{
S
Swen Schillig 已提交
982
	struct zfcp_adapter *adapter = req->adapter;
983
	struct zfcp_fsf_ct_els *ct = req->data;
S
Swen Schillig 已提交
984
	struct fsf_qtcb_header *header = &req->qtcb->header;
L
Linus Torvalds 已提交
985

986
	ct->status = -EINVAL;
L
Linus Torvalds 已提交
987

S
Swen Schillig 已提交
988
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
L
Linus Torvalds 已提交
989 990 991 992
		goto skip_fsfstatus;

	switch (header->fsf_status) {
        case FSF_GOOD:
993
		ct->status = 0;
994
		zfcp_dbf_san_res("fsscth2", req);
L
Linus Torvalds 已提交
995 996
		break;
        case FSF_SERVICE_CLASS_NOT_SUPPORTED:
S
Swen Schillig 已提交
997
		zfcp_fsf_class_not_supp(req);
L
Linus Torvalds 已提交
998 999 1000 1001 1002
		break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
                switch (header->fsf_status_qual.word[0]){
                case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
                case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
S
Swen Schillig 已提交
1003
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1004 1005 1006 1007
			break;
                }
                break;
        case FSF_PORT_BOXED:
1008
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1009
		break;
S
Swen Schillig 已提交
1010
	case FSF_PORT_HANDLE_NOT_VALID:
1011
		zfcp_erp_adapter_reopen(adapter, 0, "fsscth1");
1012
		/* fall through */
S
Swen Schillig 已提交
1013
	case FSF_GENERIC_COMMAND_REJECTED:
L
Linus Torvalds 已提交
1014 1015 1016 1017
	case FSF_PAYLOAD_SIZE_MISMATCH:
	case FSF_REQUEST_SIZE_TOO_LARGE:
	case FSF_RESPONSE_SIZE_TOO_LARGE:
	case FSF_SBAL_MISMATCH:
S
Swen Schillig 已提交
1018
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1019 1020 1021 1022
		break;
	}

skip_fsfstatus:
1023 1024
	if (ct->handler)
		ct->handler(ct->handler_data);
S
Swen Schillig 已提交
1025
}
L
Linus Torvalds 已提交
1026

1027 1028
static void zfcp_fsf_setup_ct_els_unchained(struct zfcp_qdio *qdio,
					    struct zfcp_qdio_req *q_req,
1029 1030 1031
					    struct scatterlist *sg_req,
					    struct scatterlist *sg_resp)
{
1032 1033 1034
	zfcp_qdio_fill_next(qdio, q_req, sg_virt(sg_req), sg_req->length);
	zfcp_qdio_fill_next(qdio, q_req, sg_virt(sg_resp), sg_resp->length);
	zfcp_qdio_set_sbale_last(qdio, q_req);
1035 1036
}

1037 1038
static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
				       struct scatterlist *sg_req,
1039
				       struct scatterlist *sg_resp)
S
Swen Schillig 已提交
1040
{
1041
	struct zfcp_adapter *adapter = req->adapter;
1042 1043
	struct zfcp_qdio *qdio = adapter->qdio;
	struct fsf_qtcb *qtcb = req->qtcb;
1044
	u32 feat = adapter->adapter_features;
S
Swen Schillig 已提交
1045

1046 1047 1048
	if (zfcp_adapter_multi_buffer_active(adapter)) {
		if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
			return -EIO;
1049 1050
		qtcb->bottom.support.req_buf_length =
			zfcp_qdio_real_bytes(sg_req);
1051 1052
		if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
			return -EIO;
1053 1054
		qtcb->bottom.support.resp_buf_length =
			zfcp_qdio_real_bytes(sg_resp);
1055

1056
		zfcp_qdio_set_data_div(qdio, &req->qdio_req, sg_nents(sg_req));
1057 1058
		zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
		zfcp_qdio_set_scount(qdio, &req->qdio_req);
1059 1060 1061 1062
		return 0;
	}

	/* use single, unchained SBAL if it can hold the request */
1063
	if (zfcp_qdio_sg_one_sbale(sg_req) && zfcp_qdio_sg_one_sbale(sg_resp)) {
1064
		zfcp_fsf_setup_ct_els_unchained(qdio, &req->qdio_req,
1065
						sg_req, sg_resp);
1066 1067 1068
		return 0;
	}

1069 1070 1071 1072
	if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS))
		return -EOPNOTSUPP;

	if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
1073
		return -EIO;
S
Swen Schillig 已提交
1074

1075 1076 1077 1078 1079 1080
	qtcb->bottom.support.req_buf_length = zfcp_qdio_real_bytes(sg_req);

	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
	zfcp_qdio_skip_to_last_sbale(qdio, &req->qdio_req);

	if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
1081
		return -EIO;
1082 1083 1084 1085

	qtcb->bottom.support.resp_buf_length = zfcp_qdio_real_bytes(sg_resp);

	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
1086

1087 1088 1089 1090 1091 1092
	return 0;
}

static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
				 struct scatterlist *sg_req,
				 struct scatterlist *sg_resp,
1093
				 unsigned int timeout)
1094 1095 1096
{
	int ret;

1097
	ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp);
1098 1099 1100
	if (ret)
		return ret;

1101
	/* common settings for ct/gs and els requests */
1102 1103
	if (timeout > 255)
		timeout = 255; /* max value accepted by hardware */
1104
	req->qtcb->bottom.support.service_class = FSF_CLASS_3;
1105 1106
	req->qtcb->bottom.support.timeout = timeout;
	zfcp_fsf_start_timer(req, (timeout + 10) * HZ);
S
Swen Schillig 已提交
1107 1108

	return 0;
L
Linus Torvalds 已提交
1109 1110 1111
}

/**
S
Swen Schillig 已提交
1112
 * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS)
1113
 * @wka_port: pointer to zfcp WKA port to send CT/GS to
S
Swen Schillig 已提交
1114 1115
 * @ct: pointer to struct zfcp_send_ct with data for request
 * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
1116
 * @timeout: timeout that hardware should use, and a later software timeout
L
Linus Torvalds 已提交
1117
 */
1118
int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
1119 1120
		     struct zfcp_fsf_ct_els *ct, mempool_t *pool,
		     unsigned int timeout)
L
Linus Torvalds 已提交
1121
{
1122
	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
S
Swen Schillig 已提交
1123 1124
	struct zfcp_fsf_req *req;
	int ret = -EIO;
L
Linus Torvalds 已提交
1125

1126
	spin_lock_irq(&qdio->req_q_lock);
1127
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
1128
		goto out;
L
Linus Torvalds 已提交
1129

1130
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC,
1131
				  SBAL_SFLAGS0_TYPE_WRITE_READ, pool);
1132

1133
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1134 1135
		ret = PTR_ERR(req);
		goto out;
1136 1137
	}

1138
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1139
	ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, timeout);
C
Christof Schmitt 已提交
1140
	if (ret)
L
Linus Torvalds 已提交
1141 1142
		goto failed_send;

S
Swen Schillig 已提交
1143
	req->handler = zfcp_fsf_send_ct_handler;
1144
	req->qtcb->header.port_handle = wka_port->handle;
1145
	ct->d_id = wka_port->d_id;
S
Swen Schillig 已提交
1146 1147
	req->data = ct;

1148
	zfcp_dbf_san_req("fssct_1", req, wka_port->d_id);
L
Linus Torvalds 已提交
1149

S
Swen Schillig 已提交
1150 1151 1152
	ret = zfcp_fsf_req_send(req);
	if (ret)
		goto failed_send;
1153
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
L
Linus Torvalds 已提交
1154

S
Swen Schillig 已提交
1155
	goto out;
L
Linus Torvalds 已提交
1156

S
Swen Schillig 已提交
1157 1158 1159
failed_send:
	zfcp_fsf_req_free(req);
out:
1160
	spin_unlock_irq(&qdio->req_q_lock);
S
Swen Schillig 已提交
1161
	return ret;
L
Linus Torvalds 已提交
1162 1163
}

S
Swen Schillig 已提交
1164
static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
1165
{
1166
	struct zfcp_fsf_ct_els *send_els = req->data;
S
Swen Schillig 已提交
1167
	struct fsf_qtcb_header *header = &req->qtcb->header;
L
Linus Torvalds 已提交
1168

S
Swen Schillig 已提交
1169
	send_els->status = -EINVAL;
L
Linus Torvalds 已提交
1170

S
Swen Schillig 已提交
1171
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
L
Linus Torvalds 已提交
1172 1173 1174 1175
		goto skip_fsfstatus;

	switch (header->fsf_status) {
	case FSF_GOOD:
S
Swen Schillig 已提交
1176
		send_els->status = 0;
1177
		zfcp_dbf_san_res("fsselh1", req);
L
Linus Torvalds 已提交
1178 1179
		break;
	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
S
Swen Schillig 已提交
1180
		zfcp_fsf_class_not_supp(req);
L
Linus Torvalds 已提交
1181 1182 1183 1184 1185 1186
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (header->fsf_status_qual.word[0]){
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
		case FSF_SQ_RETRY_IF_POSSIBLE:
S
Swen Schillig 已提交
1187
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1188 1189 1190 1191 1192 1193 1194 1195
			break;
		}
		break;
	case FSF_ELS_COMMAND_REJECTED:
	case FSF_PAYLOAD_SIZE_MISMATCH:
	case FSF_REQUEST_SIZE_TOO_LARGE:
	case FSF_RESPONSE_SIZE_TOO_LARGE:
		break;
S
Swen Schillig 已提交
1196
	case FSF_SBAL_MISMATCH:
L
Lucas De Marchi 已提交
1197
		/* should never occur, avoided in zfcp_fsf_send_els */
S
Swen Schillig 已提交
1198
		/* fall through */
L
Linus Torvalds 已提交
1199
	default:
S
Swen Schillig 已提交
1200
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1201 1202 1203
		break;
	}
skip_fsfstatus:
H
Heiko Carstens 已提交
1204
	if (send_els->handler)
L
Linus Torvalds 已提交
1205
		send_els->handler(send_els->handler_data);
S
Swen Schillig 已提交
1206
}
L
Linus Torvalds 已提交
1207

S
Swen Schillig 已提交
1208 1209
/**
 * zfcp_fsf_send_els - initiate an ELS command (FC-FS)
1210 1211
 * @adapter: pointer to zfcp adapter
 * @d_id: N_Port_ID to send ELS to
S
Swen Schillig 已提交
1212
 * @els: pointer to struct zfcp_send_els with data for the command
1213
 * @timeout: timeout that hardware should use, and a later software timeout
S
Swen Schillig 已提交
1214
 */
1215
int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
1216
		      struct zfcp_fsf_ct_els *els, unsigned int timeout)
S
Swen Schillig 已提交
1217 1218
{
	struct zfcp_fsf_req *req;
1219
	struct zfcp_qdio *qdio = adapter->qdio;
S
Swen Schillig 已提交
1220 1221
	int ret = -EIO;

1222
	spin_lock_irq(&qdio->req_q_lock);
1223
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
1224
		goto out;
1225

1226
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS,
1227
				  SBAL_SFLAGS0_TYPE_WRITE_READ, NULL);
1228

1229
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1230 1231 1232 1233
		ret = PTR_ERR(req);
		goto out;
	}

1234
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1235

1236 1237
	if (!zfcp_adapter_multi_buffer_active(adapter))
		zfcp_qdio_sbal_limit(qdio, &req->qdio_req, 2);
1238 1239

	ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, timeout);
1240

S
Swen Schillig 已提交
1241 1242 1243
	if (ret)
		goto failed_send;

1244
	hton24(req->qtcb->bottom.support.d_id, d_id);
S
Swen Schillig 已提交
1245
	req->handler = zfcp_fsf_send_els_handler;
1246
	els->d_id = d_id;
S
Swen Schillig 已提交
1247 1248
	req->data = els;

1249
	zfcp_dbf_san_req("fssels1", req, d_id);
S
Swen Schillig 已提交
1250 1251 1252 1253

	ret = zfcp_fsf_req_send(req);
	if (ret)
		goto failed_send;
1254
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
1255 1256 1257 1258 1259 1260

	goto out;

failed_send:
	zfcp_fsf_req_free(req);
out:
1261
	spin_unlock_irq(&qdio->req_q_lock);
S
Swen Schillig 已提交
1262
	return ret;
L
Linus Torvalds 已提交
1263 1264
}

S
Swen Schillig 已提交
1265
int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
1266
{
S
Swen Schillig 已提交
1267
	struct zfcp_fsf_req *req;
1268
	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
S
Swen Schillig 已提交
1269 1270
	int retval = -EIO;

1271
	spin_lock_irq(&qdio->req_q_lock);
1272
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
1273
		goto out;
1274

1275
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
1276
				  SBAL_SFLAGS0_TYPE_READ,
1277
				  qdio->adapter->pool.erp_req);
1278

1279
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1280 1281
		retval = PTR_ERR(req);
		goto out;
L
Linus Torvalds 已提交
1282 1283
	}

1284
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1285
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
1286

S
Swen Schillig 已提交
1287
	req->qtcb->bottom.config.feature_selection =
1288
			FSF_FEATURE_NOTIFICATION_LOST |
1289 1290
			FSF_FEATURE_UPDATE_ALERT |
			FSF_FEATURE_REQUEST_SFP_DATA;
S
Swen Schillig 已提交
1291 1292
	req->erp_action = erp_action;
	req->handler = zfcp_fsf_exchange_config_data_handler;
1293
	erp_action->fsf_req_id = req->req_id;
L
Linus Torvalds 已提交
1294

1295
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
1296
	retval = zfcp_fsf_req_send(req);
L
Linus Torvalds 已提交
1297
	if (retval) {
S
Swen Schillig 已提交
1298
		zfcp_fsf_req_free(req);
1299
		erp_action->fsf_req_id = 0;
L
Linus Torvalds 已提交
1300
	}
1301
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
1302
out:
1303
	spin_unlock_irq(&qdio->req_q_lock);
1304 1305
	return retval;
}
L
Linus Torvalds 已提交
1306

1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319

/**
 * zfcp_fsf_exchange_config_data_sync() - Request information about FCP channel.
 * @qdio: pointer to the QDIO-Queue to use for sending the command.
 * @data: pointer to the QTCB-Bottom for storing the result of the command,
 *	  might be %NULL.
 *
 * Returns:
 * * 0		- Exchange Config Data was successful, @data is complete
 * * -EIO	- Exchange Config Data was not successful, @data is invalid
 * * -EAGAIN	- @data contains incomplete data
 * * -ENOMEM	- Some memory allocation failed along the way
 */
1320
int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio,
S
Swen Schillig 已提交
1321
				       struct fsf_qtcb_bottom_config *data)
1322
{
S
Swen Schillig 已提交
1323 1324 1325
	struct zfcp_fsf_req *req = NULL;
	int retval = -EIO;

1326
	spin_lock_irq(&qdio->req_q_lock);
1327
	if (zfcp_qdio_sbal_get(qdio))
1328
		goto out_unlock;
S
Swen Schillig 已提交
1329

1330
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
1331
				  SBAL_SFLAGS0_TYPE_READ, NULL);
1332

1333
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1334
		retval = PTR_ERR(req);
1335
		goto out_unlock;
1336 1337
	}

1338
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
S
Swen Schillig 已提交
1339
	req->handler = zfcp_fsf_exchange_config_data_handler;
1340

S
Swen Schillig 已提交
1341
	req->qtcb->bottom.config.feature_selection =
1342
			FSF_FEATURE_NOTIFICATION_LOST |
1343 1344
			FSF_FEATURE_UPDATE_ALERT |
			FSF_FEATURE_REQUEST_SFP_DATA;
1345 1346

	if (data)
S
Swen Schillig 已提交
1347
		req->data = data;
1348

S
Swen Schillig 已提交
1349 1350
	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(req);
1351
	spin_unlock_irq(&qdio->req_q_lock);
1352

1353 1354
	if (!retval) {
		/* NOTE: ONLY TOUCH SYNC req AGAIN ON req->completion. */
1355
		wait_for_completion(&req->completion);
1356 1357 1358 1359 1360 1361

		if (req->status &
		    (ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_DISMISSED))
			retval = -EIO;
		else if (req->status & ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE)
			retval = -EAGAIN;
1362
	}
1363

S
Swen Schillig 已提交
1364
	zfcp_fsf_req_free(req);
1365
	return retval;
1366

1367
out_unlock:
1368
	spin_unlock_irq(&qdio->req_q_lock);
L
Linus Torvalds 已提交
1369 1370 1371 1372 1373
	return retval;
}

/**
 * zfcp_fsf_exchange_port_data - request information about local port
1374
 * @erp_action: ERP action for the adapter for which port data is requested
S
Swen Schillig 已提交
1375
 * Returns: 0 on success, error otherwise
L
Linus Torvalds 已提交
1376
 */
S
Swen Schillig 已提交
1377
int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
1378
{
1379
	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
S
Swen Schillig 已提交
1380 1381
	struct zfcp_fsf_req *req;
	int retval = -EIO;
L
Linus Torvalds 已提交
1382

1383
	if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
1384
		return -EOPNOTSUPP;
L
Linus Torvalds 已提交
1385

1386
	spin_lock_irq(&qdio->req_q_lock);
1387
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
1388
		goto out;
1389

1390
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
1391
				  SBAL_SFLAGS0_TYPE_READ,
1392
				  qdio->adapter->pool.erp_req);
1393

1394
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1395 1396
		retval = PTR_ERR(req);
		goto out;
1397 1398
	}

1399
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1400
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
1401

S
Swen Schillig 已提交
1402 1403
	req->handler = zfcp_fsf_exchange_port_data_handler;
	req->erp_action = erp_action;
1404
	erp_action->fsf_req_id = req->req_id;
1405

1406
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
1407
	retval = zfcp_fsf_req_send(req);
L
Linus Torvalds 已提交
1408
	if (retval) {
S
Swen Schillig 已提交
1409
		zfcp_fsf_req_free(req);
1410
		erp_action->fsf_req_id = 0;
1411
	}
1412
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
1413
out:
1414
	spin_unlock_irq(&qdio->req_q_lock);
1415 1416 1417 1418
	return retval;
}

/**
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
 * zfcp_fsf_exchange_port_data_sync() - Request information about local port.
 * @qdio: pointer to the QDIO-Queue to use for sending the command.
 * @data: pointer to the QTCB-Bottom for storing the result of the command,
 *	  might be %NULL.
 *
 * Returns:
 * * 0		- Exchange Port Data was successful, @data is complete
 * * -EIO	- Exchange Port Data was not successful, @data is invalid
 * * -EAGAIN	- @data contains incomplete data
 * * -ENOMEM	- Some memory allocation failed along the way
 * * -EOPNOTSUPP	- This operation is not supported
1430
 */
1431
int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio,
S
Swen Schillig 已提交
1432
				     struct fsf_qtcb_bottom_port *data)
1433
{
S
Swen Schillig 已提交
1434 1435
	struct zfcp_fsf_req *req = NULL;
	int retval = -EIO;
1436

1437
	if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
1438 1439
		return -EOPNOTSUPP;

1440
	spin_lock_irq(&qdio->req_q_lock);
1441
	if (zfcp_qdio_sbal_get(qdio))
1442
		goto out_unlock;
S
Swen Schillig 已提交
1443

1444
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
1445
				  SBAL_SFLAGS0_TYPE_READ, NULL);
1446

1447
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1448
		retval = PTR_ERR(req);
1449
		goto out_unlock;
L
Linus Torvalds 已提交
1450 1451
	}

1452
	if (data)
S
Swen Schillig 已提交
1453
		req->data = data;
1454

1455
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
1456

S
Swen Schillig 已提交
1457 1458 1459
	req->handler = zfcp_fsf_exchange_port_data_handler;
	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(req);
1460
	spin_unlock_irq(&qdio->req_q_lock);
1461

1462 1463
	if (!retval) {
		/* NOTE: ONLY TOUCH SYNC req AGAIN ON req->completion. */
1464
		wait_for_completion(&req->completion);
1465 1466 1467 1468 1469 1470

		if (req->status &
		    (ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_DISMISSED))
			retval = -EIO;
		else if (req->status & ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE)
			retval = -EAGAIN;
1471
	}
1472

S
Swen Schillig 已提交
1473
	zfcp_fsf_req_free(req);
L
Linus Torvalds 已提交
1474
	return retval;
1475 1476

out_unlock:
1477
	spin_unlock_irq(&qdio->req_q_lock);
1478
	return retval;
L
Linus Torvalds 已提交
1479 1480
}

S
Swen Schillig 已提交
1481
static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
1482
{
S
Swen Schillig 已提交
1483 1484
	struct zfcp_port *port = req->data;
	struct fsf_qtcb_header *header = &req->qtcb->header;
1485
	struct fc_els_flogi *plogi;
L
Linus Torvalds 已提交
1486

S
Swen Schillig 已提交
1487
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
1488
		goto out;
L
Linus Torvalds 已提交
1489 1490 1491 1492 1493

	switch (header->fsf_status) {
	case FSF_PORT_ALREADY_OPEN:
		break;
	case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
S
Swen Schillig 已提交
1494
		dev_warn(&req->adapter->ccw_device->dev,
1495
			 "Not enough FCP adapter resources to open "
1496 1497
			 "remote port 0x%016Lx\n",
			 (unsigned long long)port->wwpn);
1498 1499
		zfcp_erp_set_port_status(port,
					 ZFCP_STATUS_COMMON_ERP_FAILED);
S
Swen Schillig 已提交
1500
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1501 1502 1503 1504
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (header->fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
1505 1506
			/* no zfcp_fc_test_link() with failed open port */
			/* fall through */
L
Linus Torvalds 已提交
1507 1508
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
		case FSF_SQ_NO_RETRY_POSSIBLE:
S
Swen Schillig 已提交
1509
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1510 1511 1512 1513 1514
			break;
		}
		break;
	case FSF_GOOD:
		port->handle = header->port_handle;
1515
		atomic_or(ZFCP_STATUS_COMMON_OPEN |
L
Linus Torvalds 已提交
1516
				ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
1517
		atomic_andnot(ZFCP_STATUS_COMMON_ACCESS_BOXED,
1518
		                  &port->status);
L
Linus Torvalds 已提交
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
		/* check whether D_ID has changed during open */
		/*
		 * FIXME: This check is not airtight, as the FCP channel does
		 * not monitor closures of target port connections caused on
		 * the remote side. Thus, they might miss out on invalidating
		 * locally cached WWPNs (and other N_Port parameters) of gone
		 * target ports. So, our heroic attempt to make things safe
		 * could be undermined by 'open port' response data tagged with
		 * obsolete WWPNs. Another reason to monitor potential
		 * connection closures ourself at least (by interpreting
		 * incoming ELS' and unsolicited status). It just crosses my
		 * mind that one should be able to cross-check by means of
		 * another GID_PN straight after a port has been opened.
		 * Alternately, an ADISC/PDISC ELS should suffice, as well.
		 */
1534
		plogi = (struct fc_els_flogi *) req->qtcb->bottom.support.els;
1535
		if (req->qtcb->bottom.support.els1_length >=
1536
		    FSF_PLOGI_MIN_LEN)
S
Swen Schillig 已提交
1537
				zfcp_fc_plogi_evaluate(port, plogi);
L
Linus Torvalds 已提交
1538 1539
		break;
	case FSF_UNKNOWN_OP_SUBTYPE:
S
Swen Schillig 已提交
1540
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1541 1542
		break;
	}
1543 1544

out:
1545
	put_device(&port->dev);
L
Linus Torvalds 已提交
1546 1547
}

S
Swen Schillig 已提交
1548 1549 1550 1551
/**
 * zfcp_fsf_open_port - create and send open port request
 * @erp_action: pointer to struct zfcp_erp_action
 * Returns: 0 on success, error otherwise
L
Linus Torvalds 已提交
1552
 */
S
Swen Schillig 已提交
1553
int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
1554
{
1555
	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
1556
	struct zfcp_port *port = erp_action->port;
1557
	struct zfcp_fsf_req *req;
S
Swen Schillig 已提交
1558 1559
	int retval = -EIO;

1560
	spin_lock_irq(&qdio->req_q_lock);
1561
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
1562 1563
		goto out;

1564
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
1565
				  SBAL_SFLAGS0_TYPE_READ,
1566
				  qdio->adapter->pool.erp_req);
1567

1568
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1569
		retval = PTR_ERR(req);
L
Linus Torvalds 已提交
1570
		goto out;
S
Swen Schillig 已提交
1571
	}
L
Linus Torvalds 已提交
1572

1573
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1574
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
1575

S
Swen Schillig 已提交
1576
	req->handler = zfcp_fsf_open_port_handler;
1577
	hton24(req->qtcb->bottom.support.d_id, port->d_id);
1578
	req->data = port;
S
Swen Schillig 已提交
1579
	req->erp_action = erp_action;
1580
	erp_action->fsf_req_id = req->req_id;
1581
	get_device(&port->dev);
S
Swen Schillig 已提交
1582

1583
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
1584
	retval = zfcp_fsf_req_send(req);
L
Linus Torvalds 已提交
1585
	if (retval) {
S
Swen Schillig 已提交
1586
		zfcp_fsf_req_free(req);
1587
		erp_action->fsf_req_id = 0;
1588
		put_device(&port->dev);
L
Linus Torvalds 已提交
1589
	}
1590
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
1591
out:
1592
	spin_unlock_irq(&qdio->req_q_lock);
L
Linus Torvalds 已提交
1593 1594 1595
	return retval;
}

S
Swen Schillig 已提交
1596
static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
1597
{
S
Swen Schillig 已提交
1598
	struct zfcp_port *port = req->data;
L
Linus Torvalds 已提交
1599

S
Swen Schillig 已提交
1600
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
1601
		return;
L
Linus Torvalds 已提交
1602

S
Swen Schillig 已提交
1603
	switch (req->qtcb->header.fsf_status) {
L
Linus Torvalds 已提交
1604
	case FSF_PORT_HANDLE_NOT_VALID:
1605
		zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1");
S
Swen Schillig 已提交
1606
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1607 1608 1609 1610
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		break;
	case FSF_GOOD:
1611
		zfcp_erp_clear_port_status(port, ZFCP_STATUS_COMMON_OPEN);
L
Linus Torvalds 已提交
1612 1613 1614 1615
		break;
	}
}

S
Swen Schillig 已提交
1616 1617 1618 1619
/**
 * zfcp_fsf_close_port - create and send close port request
 * @erp_action: pointer to struct zfcp_erp_action
 * Returns: 0 on success, error otherwise
L
Linus Torvalds 已提交
1620
 */
S
Swen Schillig 已提交
1621
int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
1622
{
1623
	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
S
Swen Schillig 已提交
1624 1625 1626
	struct zfcp_fsf_req *req;
	int retval = -EIO;

1627
	spin_lock_irq(&qdio->req_q_lock);
1628
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
1629 1630
		goto out;

1631
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
1632
				  SBAL_SFLAGS0_TYPE_READ,
1633
				  qdio->adapter->pool.erp_req);
1634

1635
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1636
		retval = PTR_ERR(req);
L
Linus Torvalds 已提交
1637
		goto out;
S
Swen Schillig 已提交
1638
	}
L
Linus Torvalds 已提交
1639

1640
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1641
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
1642

S
Swen Schillig 已提交
1643 1644 1645 1646
	req->handler = zfcp_fsf_close_port_handler;
	req->data = erp_action->port;
	req->erp_action = erp_action;
	req->qtcb->header.port_handle = erp_action->port->handle;
1647
	erp_action->fsf_req_id = req->req_id;
S
Swen Schillig 已提交
1648

1649
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
1650
	retval = zfcp_fsf_req_send(req);
L
Linus Torvalds 已提交
1651
	if (retval) {
S
Swen Schillig 已提交
1652
		zfcp_fsf_req_free(req);
1653
		erp_action->fsf_req_id = 0;
L
Linus Torvalds 已提交
1654
	}
1655
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
1656
out:
1657
	spin_unlock_irq(&qdio->req_q_lock);
L
Linus Torvalds 已提交
1658 1659 1660
	return retval;
}

1661 1662
static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
{
1663
	struct zfcp_fc_wka_port *wka_port = req->data;
1664 1665 1666
	struct fsf_qtcb_header *header = &req->qtcb->header;

	if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
1667
		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
1668 1669 1670 1671 1672 1673 1674
		goto out;
	}

	switch (header->fsf_status) {
	case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
		dev_warn(&req->adapter->ccw_device->dev,
			 "Opening WKA port 0x%x failed\n", wka_port->d_id);
1675
		/* fall through */
1676 1677
	case FSF_ADAPTER_STATUS_AVAILABLE:
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1678
		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
1679 1680 1681
		break;
	case FSF_GOOD:
		wka_port->handle = header->port_handle;
1682 1683
		/* fall through */
	case FSF_PORT_ALREADY_OPEN:
1684
		wka_port->status = ZFCP_FC_WKA_PORT_ONLINE;
1685 1686 1687 1688 1689 1690 1691
	}
out:
	wake_up(&wka_port->completion_wq);
}

/**
 * zfcp_fsf_open_wka_port - create and send open wka-port request
1692
 * @wka_port: pointer to struct zfcp_fc_wka_port
1693 1694
 * Returns: 0 on success, error otherwise
 */
1695
int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
1696
{
1697
	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
1698
	struct zfcp_fsf_req *req;
1699
	unsigned long req_id = 0;
1700 1701
	int retval = -EIO;

1702
	spin_lock_irq(&qdio->req_q_lock);
1703
	if (zfcp_qdio_sbal_get(qdio))
1704 1705
		goto out;

1706
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
1707
				  SBAL_SFLAGS0_TYPE_READ,
1708
				  qdio->adapter->pool.erp_req);
1709

1710
	if (IS_ERR(req)) {
1711 1712 1713 1714
		retval = PTR_ERR(req);
		goto out;
	}

1715
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1716
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
1717 1718

	req->handler = zfcp_fsf_open_wka_port_handler;
1719
	hton24(req->qtcb->bottom.support.d_id, wka_port->d_id);
1720 1721
	req->data = wka_port;

1722 1723
	req_id = req->req_id;

1724 1725 1726 1727
	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(req);
	if (retval)
		zfcp_fsf_req_free(req);
1728
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
1729
out:
1730
	spin_unlock_irq(&qdio->req_q_lock);
1731
	if (!retval)
1732
		zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req_id);
1733 1734 1735 1736 1737
	return retval;
}

static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
{
1738
	struct zfcp_fc_wka_port *wka_port = req->data;
1739 1740 1741

	if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1742
		zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1");
1743 1744
	}

1745
	wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
1746 1747 1748 1749 1750
	wake_up(&wka_port->completion_wq);
}

/**
 * zfcp_fsf_close_wka_port - create and send close wka port request
1751
 * @wka_port: WKA port to open
1752 1753
 * Returns: 0 on success, error otherwise
 */
1754
int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
1755
{
1756
	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
1757
	struct zfcp_fsf_req *req;
1758
	unsigned long req_id = 0;
1759 1760
	int retval = -EIO;

1761
	spin_lock_irq(&qdio->req_q_lock);
1762
	if (zfcp_qdio_sbal_get(qdio))
1763 1764
		goto out;

1765
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
1766
				  SBAL_SFLAGS0_TYPE_READ,
1767
				  qdio->adapter->pool.erp_req);
1768

1769
	if (IS_ERR(req)) {
1770 1771 1772 1773
		retval = PTR_ERR(req);
		goto out;
	}

1774
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1775
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
1776 1777 1778 1779 1780

	req->handler = zfcp_fsf_close_wka_port_handler;
	req->data = wka_port;
	req->qtcb->header.port_handle = wka_port->handle;

1781 1782
	req_id = req->req_id;

1783 1784 1785 1786
	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(req);
	if (retval)
		zfcp_fsf_req_free(req);
1787
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
1788
out:
1789
	spin_unlock_irq(&qdio->req_q_lock);
1790
	if (!retval)
1791
		zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req_id);
1792 1793 1794
	return retval;
}

S
Swen Schillig 已提交
1795
static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
1796
{
S
Swen Schillig 已提交
1797 1798
	struct zfcp_port *port = req->data;
	struct fsf_qtcb_header *header = &req->qtcb->header;
1799
	struct scsi_device *sdev;
L
Linus Torvalds 已提交
1800

S
Swen Schillig 已提交
1801
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
1802
		return;
L
Linus Torvalds 已提交
1803 1804 1805

	switch (header->fsf_status) {
	case FSF_PORT_HANDLE_NOT_VALID:
1806
		zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1");
S
Swen Schillig 已提交
1807
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1808 1809
		break;
	case FSF_PORT_BOXED:
1810 1811
		/* can't use generic zfcp_erp_modify_port_status because
		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
1812
		atomic_andnot(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
1813 1814
		shost_for_each_device(sdev, port->adapter->scsi_host)
			if (sdev_to_zfcp(sdev)->port == port)
1815
				atomic_andnot(ZFCP_STATUS_COMMON_OPEN,
1816
						  &sdev_to_zfcp(sdev)->status);
1817 1818
		zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
1819
				     "fscpph2");
1820
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1821 1822 1823 1824
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (header->fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
S
Swen Schillig 已提交
1825
			/* fall through */
L
Linus Torvalds 已提交
1826
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
S
Swen Schillig 已提交
1827
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1828 1829 1830 1831 1832 1833 1834
			break;
		}
		break;
	case FSF_GOOD:
		/* can't use generic zfcp_erp_modify_port_status because
		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port
		 */
1835
		atomic_andnot(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
1836 1837
		shost_for_each_device(sdev, port->adapter->scsi_host)
			if (sdev_to_zfcp(sdev)->port == port)
1838
				atomic_andnot(ZFCP_STATUS_COMMON_OPEN,
1839
						  &sdev_to_zfcp(sdev)->status);
L
Linus Torvalds 已提交
1840 1841 1842 1843
		break;
	}
}

S
Swen Schillig 已提交
1844 1845 1846 1847
/**
 * zfcp_fsf_close_physical_port - close physical port
 * @erp_action: pointer to struct zfcp_erp_action
 * Returns: 0 on success
L
Linus Torvalds 已提交
1848
 */
S
Swen Schillig 已提交
1849
int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
1850
{
1851
	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
S
Swen Schillig 已提交
1852 1853 1854
	struct zfcp_fsf_req *req;
	int retval = -EIO;

1855
	spin_lock_irq(&qdio->req_q_lock);
1856
	if (zfcp_qdio_sbal_get(qdio))
L
Linus Torvalds 已提交
1857 1858
		goto out;

1859
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PHYSICAL_PORT,
1860
				  SBAL_SFLAGS0_TYPE_READ,
1861
				  qdio->adapter->pool.erp_req);
1862

1863
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1864 1865 1866
		retval = PTR_ERR(req);
		goto out;
	}
L
Linus Torvalds 已提交
1867

1868
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1869
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
1870

S
Swen Schillig 已提交
1871 1872 1873 1874
	req->data = erp_action->port;
	req->qtcb->header.port_handle = erp_action->port->handle;
	req->erp_action = erp_action;
	req->handler = zfcp_fsf_close_physical_port_handler;
1875
	erp_action->fsf_req_id = req->req_id;
S
Swen Schillig 已提交
1876

1877
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
1878
	retval = zfcp_fsf_req_send(req);
L
Linus Torvalds 已提交
1879
	if (retval) {
S
Swen Schillig 已提交
1880
		zfcp_fsf_req_free(req);
1881
		erp_action->fsf_req_id = 0;
L
Linus Torvalds 已提交
1882
	}
1883
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
1884
out:
1885
	spin_unlock_irq(&qdio->req_q_lock);
L
Linus Torvalds 已提交
1886 1887 1888
	return retval;
}

1889
static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
1890
{
S
Swen Schillig 已提交
1891
	struct zfcp_adapter *adapter = req->adapter;
1892
	struct scsi_device *sdev = req->data;
1893
	struct zfcp_scsi_dev *zfcp_sdev;
S
Swen Schillig 已提交
1894
	struct fsf_qtcb_header *header = &req->qtcb->header;
1895
	union fsf_status_qual *qual = &header->fsf_status_qual;
L
Linus Torvalds 已提交
1896

S
Swen Schillig 已提交
1897
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
1898
		return;
L
Linus Torvalds 已提交
1899

1900 1901
	zfcp_sdev = sdev_to_zfcp(sdev);

1902
	atomic_andnot(ZFCP_STATUS_COMMON_ACCESS_DENIED |
1903
			  ZFCP_STATUS_COMMON_ACCESS_BOXED,
1904
			  &zfcp_sdev->status);
L
Linus Torvalds 已提交
1905 1906 1907 1908

	switch (header->fsf_status) {

	case FSF_PORT_HANDLE_NOT_VALID:
1909
		zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1");
S
Swen Schillig 已提交
1910
		/* fall through */
L
Linus Torvalds 已提交
1911 1912 1913
	case FSF_LUN_ALREADY_OPEN:
		break;
	case FSF_PORT_BOXED:
1914 1915 1916
		zfcp_erp_set_port_status(zfcp_sdev->port,
					 ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_port_reopen(zfcp_sdev->port,
1917
				     ZFCP_STATUS_COMMON_ERP_FAILED, "fsouh_2");
1918
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1919 1920
		break;
	case FSF_LUN_SHARING_VIOLATION:
1921 1922
		if (qual->word[0])
			dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
1923
				 "LUN 0x%016Lx on port 0x%016Lx is already in "
1924 1925 1926 1927 1928 1929 1930 1931
				 "use by CSS%d, MIF Image ID %x\n",
				 zfcp_scsi_dev_lun(sdev),
				 (unsigned long long)zfcp_sdev->port->wwpn,
				 qual->fsf_queue_designator.cssid,
				 qual->fsf_queue_designator.hla);
		zfcp_erp_set_lun_status(sdev,
					ZFCP_STATUS_COMMON_ERP_FAILED |
					ZFCP_STATUS_COMMON_ACCESS_DENIED);
S
Swen Schillig 已提交
1932
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1933 1934
		break;
	case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED:
S
Swen Schillig 已提交
1935
		dev_warn(&adapter->ccw_device->dev,
1936 1937
			 "No handle is available for LUN "
			 "0x%016Lx on port 0x%016Lx\n",
1938 1939
			 (unsigned long long)zfcp_scsi_dev_lun(sdev),
			 (unsigned long long)zfcp_sdev->port->wwpn);
1940
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
S
Swen Schillig 已提交
1941 1942 1943
		/* fall through */
	case FSF_INVALID_COMMAND_OPTION:
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1944 1945 1946 1947
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (header->fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
1948
			zfcp_fc_test_link(zfcp_sdev->port);
S
Swen Schillig 已提交
1949
			/* fall through */
L
Linus Torvalds 已提交
1950
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
S
Swen Schillig 已提交
1951
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
1952 1953 1954 1955 1956
			break;
		}
		break;

	case FSF_GOOD:
1957
		zfcp_sdev->lun_handle = header->lun_handle;
1958
		atomic_or(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status);
L
Linus Torvalds 已提交
1959 1960 1961 1962
		break;
	}
}

S
Swen Schillig 已提交
1963
/**
1964
 * zfcp_fsf_open_lun - open LUN
S
Swen Schillig 已提交
1965 1966
 * @erp_action: pointer to struct zfcp_erp_action
 * Returns: 0 on success, error otherwise
L
Linus Torvalds 已提交
1967
 */
1968
int zfcp_fsf_open_lun(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
1969
{
S
Swen Schillig 已提交
1970
	struct zfcp_adapter *adapter = erp_action->adapter;
1971
	struct zfcp_qdio *qdio = adapter->qdio;
S
Swen Schillig 已提交
1972 1973 1974
	struct zfcp_fsf_req *req;
	int retval = -EIO;

1975
	spin_lock_irq(&qdio->req_q_lock);
1976
	if (zfcp_qdio_sbal_get(qdio))
L
Linus Torvalds 已提交
1977 1978
		goto out;

1979
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_LUN,
1980
				  SBAL_SFLAGS0_TYPE_READ,
1981
				  adapter->pool.erp_req);
1982

1983
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
1984 1985 1986 1987
		retval = PTR_ERR(req);
		goto out;
	}

1988
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1989
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
1990

S
Swen Schillig 已提交
1991
	req->qtcb->header.port_handle = erp_action->port->handle;
1992 1993 1994
	req->qtcb->bottom.support.fcp_lun = zfcp_scsi_dev_lun(erp_action->sdev);
	req->handler = zfcp_fsf_open_lun_handler;
	req->data = erp_action->sdev;
S
Swen Schillig 已提交
1995
	req->erp_action = erp_action;
1996
	erp_action->fsf_req_id = req->req_id;
S
Swen Schillig 已提交
1997 1998 1999 2000

	if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE))
		req->qtcb->bottom.support.option = FSF_OPEN_LUN_SUPPRESS_BOXING;

2001
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
2002
	retval = zfcp_fsf_req_send(req);
L
Linus Torvalds 已提交
2003
	if (retval) {
S
Swen Schillig 已提交
2004
		zfcp_fsf_req_free(req);
2005
		erp_action->fsf_req_id = 0;
L
Linus Torvalds 已提交
2006
	}
2007
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
2008
out:
2009
	spin_unlock_irq(&qdio->req_q_lock);
L
Linus Torvalds 已提交
2010 2011 2012
	return retval;
}

2013
static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req)
L
Linus Torvalds 已提交
2014
{
2015
	struct scsi_device *sdev = req->data;
2016
	struct zfcp_scsi_dev *zfcp_sdev;
L
Linus Torvalds 已提交
2017

S
Swen Schillig 已提交
2018
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
2019
		return;
L
Linus Torvalds 已提交
2020

2021 2022
	zfcp_sdev = sdev_to_zfcp(sdev);

S
Swen Schillig 已提交
2023
	switch (req->qtcb->header.fsf_status) {
L
Linus Torvalds 已提交
2024
	case FSF_PORT_HANDLE_NOT_VALID:
2025
		zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1");
S
Swen Schillig 已提交
2026
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
2027 2028
		break;
	case FSF_LUN_HANDLE_NOT_VALID:
2029
		zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fscuh_2");
S
Swen Schillig 已提交
2030
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
2031 2032
		break;
	case FSF_PORT_BOXED:
2033 2034 2035
		zfcp_erp_set_port_status(zfcp_sdev->port,
					 ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_port_reopen(zfcp_sdev->port,
2036
				     ZFCP_STATUS_COMMON_ERP_FAILED, "fscuh_3");
2037
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
2038 2039
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
S
Swen Schillig 已提交
2040
		switch (req->qtcb->header.fsf_status_qual.word[0]) {
L
Linus Torvalds 已提交
2041
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
2042
			zfcp_fc_test_link(zfcp_sdev->port);
S
Swen Schillig 已提交
2043
			/* fall through */
L
Linus Torvalds 已提交
2044
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
S
Swen Schillig 已提交
2045
			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
2046 2047 2048 2049
			break;
		}
		break;
	case FSF_GOOD:
2050
		atomic_andnot(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status);
L
Linus Torvalds 已提交
2051 2052 2053 2054 2055
		break;
	}
}

/**
2056 2057
 * zfcp_fsf_close_LUN - close LUN
 * @erp_action: pointer to erp_action triggering the "close LUN"
S
Swen Schillig 已提交
2058
 * Returns: 0 on success, error otherwise
L
Linus Torvalds 已提交
2059
 */
2060
int zfcp_fsf_close_lun(struct zfcp_erp_action *erp_action)
L
Linus Torvalds 已提交
2061
{
2062
	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
2063
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(erp_action->sdev);
S
Swen Schillig 已提交
2064 2065
	struct zfcp_fsf_req *req;
	int retval = -EIO;
L
Linus Torvalds 已提交
2066

2067
	spin_lock_irq(&qdio->req_q_lock);
2068
	if (zfcp_qdio_sbal_get(qdio))
L
Linus Torvalds 已提交
2069
		goto out;
2070

2071
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_LUN,
2072
				  SBAL_SFLAGS0_TYPE_READ,
2073
				  qdio->adapter->pool.erp_req);
2074

2075
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
2076 2077 2078
		retval = PTR_ERR(req);
		goto out;
	}
L
Linus Torvalds 已提交
2079

2080
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
2081
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
2082

S
Swen Schillig 已提交
2083
	req->qtcb->header.port_handle = erp_action->port->handle;
2084 2085 2086
	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
	req->handler = zfcp_fsf_close_lun_handler;
	req->data = erp_action->sdev;
S
Swen Schillig 已提交
2087
	req->erp_action = erp_action;
2088
	erp_action->fsf_req_id = req->req_id;
2089

2090
	zfcp_fsf_start_erp_timer(req);
S
Swen Schillig 已提交
2091 2092 2093
	retval = zfcp_fsf_req_send(req);
	if (retval) {
		zfcp_fsf_req_free(req);
2094
		erp_action->fsf_req_id = 0;
S
Swen Schillig 已提交
2095
	}
2096
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
S
Swen Schillig 已提交
2097
out:
2098
	spin_unlock_irq(&qdio->req_q_lock);
S
Swen Schillig 已提交
2099
	return retval;
L
Linus Torvalds 已提交
2100 2101
}

2102
static void zfcp_fsf_update_lat(struct zfcp_latency_record *lat_rec, u32 lat)
2103 2104
{
	lat_rec->sum += lat;
S
Swen Schillig 已提交
2105 2106
	lat_rec->min = min(lat_rec->min, lat);
	lat_rec->max = max(lat_rec->max, lat);
2107 2108
}

2109
static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
2110
{
2111
	struct fsf_qual_latency_info *lat_in;
2112
	struct zfcp_latency_cont *lat = NULL;
2113
	struct zfcp_scsi_dev *zfcp_sdev;
2114 2115
	struct zfcp_blk_drv_data blktrc;
	int ticks = req->adapter->timer_ticks;
2116

2117
	lat_in = &req->qtcb->prefix.prot_status_qual.latency_info;
2118

2119 2120 2121 2122
	blktrc.flags = 0;
	blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC;
	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
		blktrc.flags |= ZFCP_BLK_REQ_ERROR;
2123
	blktrc.inb_usage = 0;
2124
	blktrc.outb_usage = req->qdio_req.qdio_outb_usage;
2125

2126 2127
	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
	    !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
2128
		zfcp_sdev = sdev_to_zfcp(scsi->device);
2129 2130 2131 2132 2133
		blktrc.flags |= ZFCP_BLK_LAT_VALID;
		blktrc.channel_lat = lat_in->channel_lat * ticks;
		blktrc.fabric_lat = lat_in->fabric_lat * ticks;

		switch (req->qtcb->bottom.io.data_direction) {
2134 2135
		case FSF_DATADIR_DIF_READ_STRIP:
		case FSF_DATADIR_DIF_READ_CONVERT:
2136
		case FSF_DATADIR_READ:
2137
			lat = &zfcp_sdev->latencies.read;
2138
			break;
2139 2140
		case FSF_DATADIR_DIF_WRITE_INSERT:
		case FSF_DATADIR_DIF_WRITE_CONVERT:
2141
		case FSF_DATADIR_WRITE:
2142
			lat = &zfcp_sdev->latencies.write;
2143 2144
			break;
		case FSF_DATADIR_CMND:
2145
			lat = &zfcp_sdev->latencies.cmd;
2146 2147
			break;
		}
L
Linus Torvalds 已提交
2148

2149
		if (lat) {
2150
			spin_lock(&zfcp_sdev->latencies.lock);
2151 2152 2153
			zfcp_fsf_update_lat(&lat->channel, lat_in->channel_lat);
			zfcp_fsf_update_lat(&lat->fabric, lat_in->fabric_lat);
			lat->counter++;
2154
			spin_unlock(&zfcp_sdev->latencies.lock);
2155
		}
S
Stefan Raspl 已提交
2156 2157
	}

2158 2159
	blk_add_driver_data(scsi->request->q, scsi->request, &blktrc,
			    sizeof(blktrc));
S
Stefan Raspl 已提交
2160 2161
}

2162 2163 2164 2165 2166 2167 2168
/**
 * zfcp_fsf_fcp_handler_common() - FCP response handler common to I/O and TMF.
 * @req: Pointer to FSF request.
 * @sdev: Pointer to SCSI device as request context.
 */
static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req,
					struct scsi_device *sdev)
S
Swen Schillig 已提交
2169
{
2170
	struct zfcp_scsi_dev *zfcp_sdev;
S
Swen Schillig 已提交
2171 2172 2173
	struct fsf_qtcb_header *header = &req->qtcb->header;

	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
2174
		return;
L
Linus Torvalds 已提交
2175

2176 2177
	zfcp_sdev = sdev_to_zfcp(sdev);

S
Swen Schillig 已提交
2178 2179 2180
	switch (header->fsf_status) {
	case FSF_HANDLE_MISMATCH:
	case FSF_PORT_HANDLE_NOT_VALID:
2181
		zfcp_erp_adapter_reopen(req->adapter, 0, "fssfch1");
S
Swen Schillig 已提交
2182 2183 2184 2185
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_FCPLUN_NOT_VALID:
	case FSF_LUN_HANDLE_NOT_VALID:
2186
		zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fssfch2");
S
Swen Schillig 已提交
2187
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
2188
		break;
S
Swen Schillig 已提交
2189 2190
	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
		zfcp_fsf_class_not_supp(req);
L
Linus Torvalds 已提交
2191
		break;
S
Swen Schillig 已提交
2192 2193
	case FSF_DIRECTION_INDICATOR_NOT_VALID:
		dev_err(&req->adapter->ccw_device->dev,
2194
			"Incorrect direction %d, LUN 0x%016Lx on port "
2195
			"0x%016Lx closed\n",
S
Swen Schillig 已提交
2196
			req->qtcb->bottom.io.data_direction,
2197 2198
			(unsigned long long)zfcp_scsi_dev_lun(sdev),
			(unsigned long long)zfcp_sdev->port->wwpn);
2199
		zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch3");
S
Swen Schillig 已提交
2200 2201 2202 2203
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_CMND_LENGTH_NOT_VALID:
		dev_err(&req->adapter->ccw_device->dev,
2204 2205
			"Incorrect FCP_CMND length %d, FCP device closed\n",
			req->qtcb->bottom.io.fcp_cmnd_length);
2206
		zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch4");
S
Swen Schillig 已提交
2207 2208 2209
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_PORT_BOXED:
2210 2211 2212
		zfcp_erp_set_port_status(zfcp_sdev->port,
					 ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_port_reopen(zfcp_sdev->port,
2213
				     ZFCP_STATUS_COMMON_ERP_FAILED, "fssfch5");
2214
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
S
Swen Schillig 已提交
2215 2216
		break;
	case FSF_LUN_BOXED:
2217 2218
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED);
		zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
2219
				    "fssfch6");
2220
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
S
Swen Schillig 已提交
2221 2222 2223 2224
		break;
	case FSF_ADAPTER_STATUS_AVAILABLE:
		if (header->fsf_status_qual.word[0] ==
		    FSF_SQ_INVOKE_LINK_TEST_PROCEDURE)
2225
			zfcp_fc_test_link(zfcp_sdev->port);
S
Swen Schillig 已提交
2226
		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
L
Linus Torvalds 已提交
2227 2228
		break;
	}
2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
}

static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
{
	struct scsi_cmnd *scpnt;
	struct fcp_resp_with_ext *fcp_rsp;
	unsigned long flags;

	read_lock_irqsave(&req->adapter->abort_lock, flags);

	scpnt = req->data;
	if (unlikely(!scpnt)) {
		read_unlock_irqrestore(&req->adapter->abort_lock, flags);
		return;
S
Swen Schillig 已提交
2243
	}
2244

2245
	zfcp_fsf_fcp_handler_common(req, scpnt->device);
2246

2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266
	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
		set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
		goto skip_fsfstatus;
	}

	switch (req->qtcb->header.fsf_status) {
	case FSF_INCONSISTENT_PROT_DATA:
	case FSF_INVALID_PROT_PARM:
		set_host_byte(scpnt, DID_ERROR);
		goto skip_fsfstatus;
	case FSF_BLOCK_GUARD_CHECK_FAILURE:
		zfcp_scsi_dif_sense_error(scpnt, 0x1);
		goto skip_fsfstatus;
	case FSF_APP_TAG_CHECK_FAILURE:
		zfcp_scsi_dif_sense_error(scpnt, 0x2);
		goto skip_fsfstatus;
	case FSF_REF_TAG_CHECK_FAILURE:
		zfcp_scsi_dif_sense_error(scpnt, 0x3);
		goto skip_fsfstatus;
	}
2267 2268
	BUILD_BUG_ON(sizeof(struct fcp_resp_with_ext) > FSF_FCP_RSP_SIZE);
	fcp_rsp = &req->qtcb->bottom.io.fcp_rsp.iu;
2269 2270 2271 2272
	zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);

skip_fsfstatus:
	zfcp_fsf_req_trace(req, scpnt);
2273
	zfcp_dbf_scsi_result(scpnt, req);
2274 2275 2276 2277 2278 2279 2280 2281 2282 2283

	scpnt->host_scribble = NULL;
	(scpnt->scsi_done) (scpnt);
	/*
	 * We must hold this lock until scsi_done has been called.
	 * Otherwise we may call scsi_done after abort regarding this
	 * command has completed.
	 * Note: scsi_done must not block!
	 */
	read_unlock_irqrestore(&req->adapter->abort_lock, flags);
L
Linus Torvalds 已提交
2284 2285
}

2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir)
{
	switch (scsi_get_prot_op(scsi_cmnd)) {
	case SCSI_PROT_NORMAL:
		switch (scsi_cmnd->sc_data_direction) {
		case DMA_NONE:
			*data_dir = FSF_DATADIR_CMND;
			break;
		case DMA_FROM_DEVICE:
			*data_dir = FSF_DATADIR_READ;
			break;
		case DMA_TO_DEVICE:
			*data_dir = FSF_DATADIR_WRITE;
			break;
		case DMA_BIDIRECTIONAL:
			return -EINVAL;
		}
		break;

	case SCSI_PROT_READ_STRIP:
		*data_dir = FSF_DATADIR_DIF_READ_STRIP;
		break;
	case SCSI_PROT_WRITE_INSERT:
		*data_dir = FSF_DATADIR_DIF_WRITE_INSERT;
		break;
	case SCSI_PROT_READ_PASS:
		*data_dir = FSF_DATADIR_DIF_READ_CONVERT;
		break;
	case SCSI_PROT_WRITE_PASS:
		*data_dir = FSF_DATADIR_DIF_WRITE_CONVERT;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

S
Swen Schillig 已提交
2324
/**
2325
 * zfcp_fsf_fcp_cmnd - initiate an FCP command (for a SCSI command)
S
Swen Schillig 已提交
2326
 * @scsi_cmnd: scsi command to be sent
L
Linus Torvalds 已提交
2327
 */
2328
int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
L
Linus Torvalds 已提交
2329
{
S
Swen Schillig 已提交
2330
	struct zfcp_fsf_req *req;
2331
	struct fcp_cmnd *fcp_cmnd;
2332
	u8 sbtype = SBAL_SFLAGS0_TYPE_READ;
2333
	int retval = -EIO;
2334 2335 2336
	struct scsi_device *sdev = scsi_cmnd->device;
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
2337
	struct zfcp_qdio *qdio = adapter->qdio;
2338
	struct fsf_qtcb_bottom_io *io;
2339
	unsigned long flags;
L
Linus Torvalds 已提交
2340

2341
	if (unlikely(!(atomic_read(&zfcp_sdev->status) &
S
Swen Schillig 已提交
2342 2343
		       ZFCP_STATUS_COMMON_UNBLOCKED)))
		return -EBUSY;
L
Linus Torvalds 已提交
2344

2345
	spin_lock_irqsave(&qdio->req_q_lock, flags);
2346
	if (atomic_read(&qdio->req_q_free) <= 0) {
2347
		atomic_inc(&qdio->req_q_full);
S
Swen Schillig 已提交
2348
		goto out;
2349
	}
2350

2351
	if (scsi_cmnd->sc_data_direction == DMA_TO_DEVICE)
2352
		sbtype = SBAL_SFLAGS0_TYPE_WRITE;
2353

2354
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
2355
				  sbtype, adapter->pool.scsi_req);
2356

2357
	if (IS_ERR(req)) {
S
Swen Schillig 已提交
2358 2359 2360 2361
		retval = PTR_ERR(req);
		goto out;
	}

2362 2363 2364
	scsi_cmnd->host_scribble = (unsigned char *) req->req_id;

	io = &req->qtcb->bottom.io;
2365
	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
S
Swen Schillig 已提交
2366
	req->data = scsi_cmnd;
2367
	req->handler = zfcp_fsf_fcp_cmnd_handler;
2368 2369
	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
	req->qtcb->header.port_handle = zfcp_sdev->port->handle;
2370 2371
	io->service_class = FSF_CLASS_3;
	io->fcp_cmnd_length = FCP_CMND_LEN;
S
Swen Schillig 已提交
2372

2373 2374 2375
	if (scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) {
		io->data_block_length = scsi_cmnd->device->sector_size;
		io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF;
L
Linus Torvalds 已提交
2376 2377
	}

2378 2379
	if (zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction))
		goto failed_scsi_cmnd;
2380

2381 2382
	BUILD_BUG_ON(sizeof(struct fcp_cmnd) > FSF_FCP_CMND_SIZE);
	fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu;
2383
	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
L
Linus Torvalds 已提交
2384

2385 2386
	if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) &&
	    scsi_prot_sg_count(scsi_cmnd)) {
2387 2388
		zfcp_qdio_set_data_div(qdio, &req->qdio_req,
				       scsi_prot_sg_count(scsi_cmnd));
2389 2390 2391 2392 2393
		retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
						 scsi_prot_sglist(scsi_cmnd));
		if (retval)
			goto failed_scsi_cmnd;
		io->prot_data_length = zfcp_qdio_real_bytes(
2394 2395 2396
						scsi_prot_sglist(scsi_cmnd));
	}

2397 2398 2399
	retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
					 scsi_sglist(scsi_cmnd));
	if (unlikely(retval))
S
Swen Schillig 已提交
2400
		goto failed_scsi_cmnd;
L
Linus Torvalds 已提交
2401

2402
	zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
2403 2404
	if (zfcp_adapter_multi_buffer_active(adapter))
		zfcp_qdio_set_scount(qdio, &req->qdio_req);
2405

S
Swen Schillig 已提交
2406 2407 2408
	retval = zfcp_fsf_req_send(req);
	if (unlikely(retval))
		goto failed_scsi_cmnd;
2409
	/* NOTE: DO NOT TOUCH req PAST THIS POINT! */
L
Linus Torvalds 已提交
2410

S
Swen Schillig 已提交
2411
	goto out;
L
Linus Torvalds 已提交
2412

S
Swen Schillig 已提交
2413 2414 2415 2416
failed_scsi_cmnd:
	zfcp_fsf_req_free(req);
	scsi_cmnd->host_scribble = NULL;
out:
2417
	spin_unlock_irqrestore(&qdio->req_q_lock, flags);
S
Swen Schillig 已提交
2418
	return retval;
L
Linus Torvalds 已提交
2419 2420
}

2421 2422
static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
{
2423
	struct scsi_device *sdev = req->data;
2424 2425 2426
	struct fcp_resp_with_ext *fcp_rsp;
	struct fcp_resp_rsp_info *rsp_info;

2427
	zfcp_fsf_fcp_handler_common(req, sdev);
2428

2429
	fcp_rsp = &req->qtcb->bottom.io.fcp_rsp.iu;
2430 2431 2432 2433 2434 2435 2436
	rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];

	if ((rsp_info->rsp_code != FCP_TMF_CMPL) ||
	     (req->status & ZFCP_STATUS_FSFREQ_ERROR))
		req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
}

L
Linus Torvalds 已提交
2437
/**
2438 2439 2440 2441 2442
 * zfcp_fsf_fcp_task_mgmt() - Send SCSI task management command (TMF).
 * @sdev: Pointer to SCSI device to send the task management command to.
 * @tm_flags: Unsigned byte for task management flags.
 *
 * Return: On success pointer to struct zfcp_fsf_req, %NULL otherwise.
L
Linus Torvalds 已提交
2443
 */
2444
struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
2445
					    u8 tm_flags)
L
Linus Torvalds 已提交
2446
{
S
Swen Schillig 已提交
2447
	struct zfcp_fsf_req *req = NULL;
2448
	struct fcp_cmnd *fcp_cmnd;
2449
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
2450
	struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
L
Linus Torvalds 已提交
2451

2452
	if (unlikely(!(atomic_read(&zfcp_sdev->status) &
S
Swen Schillig 已提交
2453 2454
		       ZFCP_STATUS_COMMON_UNBLOCKED)))
		return NULL;
L
Linus Torvalds 已提交
2455

2456
	spin_lock_irq(&qdio->req_q_lock);
2457
	if (zfcp_qdio_sbal_get(qdio))
S
Swen Schillig 已提交
2458
		goto out;
2459

2460
	req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
2461
				  SBAL_SFLAGS0_TYPE_WRITE,
2462
				  qdio->adapter->pool.scsi_req);
2463

2464 2465
	if (IS_ERR(req)) {
		req = NULL;
S
Swen Schillig 已提交
2466
		goto out;
2467
	}
L
Linus Torvalds 已提交
2468

2469 2470
	req->data = sdev;

2471
	req->handler = zfcp_fsf_fcp_task_mgmt_handler;
2472 2473
	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
	req->qtcb->header.port_handle = zfcp_sdev->port->handle;
S
Swen Schillig 已提交
2474 2475
	req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
	req->qtcb->bottom.io.service_class = FSF_CLASS_3;
2476
	req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
S
Swen Schillig 已提交
2477

2478
	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
L
Linus Torvalds 已提交
2479

2480
	fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu;
2481
	zfcp_fc_fcp_tm(fcp_cmnd, sdev, tm_flags);
L
Linus Torvalds 已提交
2482

2483
	zfcp_fsf_start_timer(req, ZFCP_FSF_SCSI_ER_TIMEOUT);
2484 2485
	if (!zfcp_fsf_req_send(req)) {
		/* NOTE: DO NOT TOUCH req, UNTIL IT COMPLETES! */
S
Swen Schillig 已提交
2486
		goto out;
2487
	}
L
Linus Torvalds 已提交
2488

S
Swen Schillig 已提交
2489 2490 2491
	zfcp_fsf_req_free(req);
	req = NULL;
out:
2492
	spin_unlock_irq(&qdio->req_q_lock);
S
Swen Schillig 已提交
2493 2494
	return req;
}
L
Linus Torvalds 已提交
2495

2496 2497
/**
 * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
2498
 * @qdio: pointer to struct zfcp_qdio
2499 2500
 * @sbal_idx: response queue index of SBAL to be processed
 */
2501
void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
2502
{
2503
	struct zfcp_adapter *adapter = qdio->adapter;
2504
	struct qdio_buffer *sbal = qdio->res_q[sbal_idx];
2505 2506
	struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
2507
	unsigned long req_id;
2508 2509 2510 2511 2512
	int idx;

	for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {

		sbale = &sbal->element[idx];
2513
		req_id = sbale->addr;
2514
		fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id);
2515

2516
		if (!fsf_req) {
2517 2518 2519 2520
			/*
			 * Unknown request means that we have potentially memory
			 * corruption and must stop the machine immediately.
			 */
2521
			zfcp_qdio_siosl(adapter);
2522 2523
			panic("error: unknown req_id (%lx) on adapter %s.\n",
			      req_id, dev_name(&adapter->ccw_device->dev));
2524
		}
2525 2526 2527

		zfcp_fsf_req_complete(fsf_req);

2528
		if (likely(sbale->eflags & SBAL_EFLAGS_LAST_ENTRY))
2529 2530 2531
			break;
	}
}