Skip to contentSkip to conversation

zfcp patches for 2.6.29

PATCH New Christof Schmitt 1 participant 12 messages Dec 19, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover zfcp patches for 2.6.29

James,

this is the series of zfcp patches for the 2.6.29 merge window. The patches apply on top of the current scsi-misc tree.

Christof

#1 lore raw

PATCH 1/11 zfcp: Fix message line break

From: Christof Schmitt <[email protected]>

Move the closing parenthesis before the line break.

---

 drivers/s390/scsi/zfcp_fsf.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/scsi/zfcp_fsf.c +1 -1
@@ -1904,7 +1904,7 @@ static void zfcp_fsf_open_unit_handler(s
 				dev_err(&adapter->ccw_device->dev,
 					"Shared read-write access not "
 					"supported (unit 0x%016Lx, port "
-					"0x%016Lx\n)",
+					"0x%016Lx)\n",
 					(unsigned long long)unit->fcp_lun,
 					(unsigned long long)unit->port->wwpn);
 				zfcp_erp_unit_failed(unit, 36, req);
#2 lore raw

PATCH 2/11 zfcp: register with SCSI layer on ccw registration

In reply to Christof Schmitt

From: Swen Schillig <[email protected]>

Synchronize the registration and de-registration with the SCSI layer at CCW registration, de-registration. Before we registered with the SCSI layer on adapter activation. This way the reg and de-reg process is in balance.

---

 drivers/s390/scsi/zfcp_aux.c |    3 ++-
 drivers/s390/scsi/zfcp_ccw.c |    6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)
drivers/s390/scsi/zfcp_aux.c +2 -1
@@ -516,7 +516,8 @@ int zfcp_adapter_enqueue(struct ccw_devi
 
 	zfcp_fc_nameserver_init(adapter);
 
-	return 0;
+	if (!zfcp_adapter_scsi_register(adapter))
+		return 0;
 
 sysfs_failed:
 	zfcp_adapter_debug_unregister(adapter);
drivers/s390/scsi/zfcp_ccw.c +0 -6
@@ -103,10 +103,6 @@ static int zfcp_ccw_set_online(struct cc
 	if (retval)
 		goto out;
 
-	retval = zfcp_adapter_scsi_register(adapter);
-	if (retval)
-		goto out_scsi_register;
-
 	/* initialize request counter */
 	BUG_ON(!zfcp_reqlist_isempty(adapter));
 	adapter->req_no = 0;
@@ -120,8 +116,6 @@ static int zfcp_ccw_set_online(struct cc
 	flush_work(&adapter->scan_work);
 	return 0;
 
- out_scsi_register:
-	zfcp_erp_thread_kill(adapter);
  out:
 	up(&zfcp_data.config_sema);
 	return retval;
#3 lore raw

PATCH 3/11 zfcp: Simplify SBAL allocation to fix sparse warnings

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

When waiting for a request claim the SBAL before waiting. This way, locking before each check of the free counter is not required and sparse does not emit warnings for the complicated locking scheme.

---
 drivers/s390/scsi/zfcp_fsf.c |   34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +17 -17
@@ -641,38 +641,38 @@ static void zfcp_fsf_exchange_port_data_
 	}
 }
 
-static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter)
+static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
 {
-	struct zfcp_qdio_queue *req_q = &adapter->req_q;
-
-	spin_lock_bh(&adapter->req_q_lock);
-	if (atomic_read(&req_q->count))
+	if (atomic_read(&adapter->req_q.count) > 0)
 		return 1;
-	spin_unlock_bh(&adapter->req_q_lock);
+	atomic_inc(&adapter->qdio_outb_full);
 	return 0;
 }
 
-static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
-{
-	unsigned int count = atomic_read(&adapter->req_q.count);
-	if (!count)
-		atomic_inc(&adapter->qdio_outb_full);
-	return count > 0;
-}
-
 static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
+	__releases(&adapter->req_q_lock)
+	__acquires(&adapter->req_q_lock)
 {
+	struct zfcp_qdio_queue *req_q = &adapter->req_q;
 	long ret;
 
+	if (atomic_read(&req_q->count) <= -REQUEST_LIST_SIZE)
+		return -EIO;
+	if (atomic_read(&req_q->count) > 0)
+		return 0;
+
+	atomic_dec(&req_q->count);
 	spin_unlock_bh(&adapter->req_q_lock);
 	ret = wait_event_interruptible_timeout(adapter->request_wq,
-					zfcp_fsf_sbal_check(adapter), 5 * HZ);
+					atomic_read(&req_q->count) >= 0,
+					5 * HZ);
+	spin_lock_bh(&adapter->req_q_lock);
+	atomic_inc(&req_q->count);
+
 	if (ret > 0)
 		return 0;
 	if (!ret)
 		atomic_inc(&adapter->qdio_outb_full);
-
-	spin_lock_bh(&adapter->req_q_lock);
 	return -EIO;
 }
 
#4 lore raw

PATCH 4/11 zfcp: Remove adapter list

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

After the latest changes, the list of FCP devices is only used to lookup the adapter for requests from the actcli tool. Change this to use the lookup function in the cio layer. Now we can remove the adapter list and have one place less to use the global config_lock.

---
 drivers/s390/scsi/zfcp_aux.c  |   12 ------------
 drivers/s390/scsi/zfcp_cfdc.c |   17 +++--------------
 drivers/s390/scsi/zfcp_def.h  |    2 --
 3 files changed, 3 insertions(+), 28 deletions(-)
drivers/s390/scsi/zfcp_aux.c +0 -12
@@ -175,7 +175,6 @@ static int __init zfcp_module_init(void)
 
 	zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq");
 
-	INIT_LIST_HEAD(&zfcp_data.adapter_list_head);
 	sema_init(&zfcp_data.config_sema, 1);
 	rwlock_init(&zfcp_data.config_lock);
 
@@ -509,11 +508,7 @@ int zfcp_adapter_enqueue(struct ccw_devi
 			       &zfcp_sysfs_adapter_attrs))
 		goto sysfs_failed;
 
-	write_lock_irq(&zfcp_data.config_lock);
 	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-	list_add_tail(&adapter->list, &zfcp_data.adapter_list_head);
-	write_unlock_irq(&zfcp_data.config_lock);
-
 	zfcp_fc_nameserver_init(adapter);
 
 	if (!zfcp_adapter_scsi_register(adapter))
@@ -556,14 +551,7 @@ void zfcp_adapter_dequeue(struct zfcp_ad
 		return;
 
 	zfcp_adapter_debug_unregister(adapter);
-
-	/* remove specified adapter data structure from list */
-	write_lock_irq(&zfcp_data.config_lock);
-	list_del(&adapter->list);
-	write_unlock_irq(&zfcp_data.config_lock);
-
 	zfcp_qdio_free(adapter);
-
 	zfcp_free_low_mem_buffers(adapter);
 	kfree(adapter->req_list);
 	kfree(adapter->fc_stats);
drivers/s390/scsi/zfcp_cfdc.c +3 -14
@@ -82,20 +82,9 @@ static int zfcp_cfdc_copy_to_user(void _
 
 static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
 {
-	struct zfcp_adapter *adapter = NULL, *cur_adapter;
-	struct ccw_dev_id dev_id;
-
-	read_lock_irq(&zfcp_data.config_lock);
-	list_for_each_entry(cur_adapter, &zfcp_data.adapter_list_head, list) {
-		ccw_device_get_id(cur_adapter->ccw_device, &dev_id);
-		if (dev_id.devno == devno) {
-			adapter = cur_adapter;
-			zfcp_adapter_get(adapter);
-			break;
-		}
-	}
-	read_unlock_irq(&zfcp_data.config_lock);
-	return adapter;
+	char busid[9];
+	snprintf(busid, sizeof(busid), "0.0.%04x", devno);
+	return zfcp_get_adapter_by_busid(busid);
 }
 
 static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
drivers/s390/scsi/zfcp_def.h +0 -2
@@ -450,7 +450,6 @@ struct zfcp_latencies {
 };
 
 struct zfcp_adapter {
-	struct list_head	list;              /* list of adapters */
 	atomic_t                refcount;          /* reference count */
 	wait_queue_head_t	remove_wq;         /* can be used to wait for
 						      refcount drop to zero */
@@ -591,7 +590,6 @@ struct zfcp_fsf_req {
 struct zfcp_data {
 	struct scsi_host_template scsi_host_template;
 	struct scsi_transport_template *scsi_transport_template;
-	struct list_head	adapter_list_head;  /* head of adapter list */
 	rwlock_t                config_lock;        /* serialises changes
 						       to adapter/port/unit
 						       lists */
#5 lore raw

PATCH 5/11 zfcp: fix compile warning

In reply to Christof Schmitt

From: Heiko Carstens <[email protected]>

Get rid of this one:

drivers/s390/scsi/zfcp_erp.c: In function 'zfcp_erp_thread':
drivers/s390/scsi/zfcp_erp.c:1400: warning: ignoring return value of 'down_interruptible', declared with attribute warn_unused_result

zfcp_erp_thread is a kernel thread which can't receive any signals. So introduce a dummy variable and get rid of the warning.

---

 drivers/s390/scsi/zfcp_erp.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/s390/scsi/zfcp_erp.c +2 -1
@@ -1379,6 +1379,7 @@ static int zfcp_erp_thread(void *data)
 	struct list_head *next;
 	struct zfcp_erp_action *act;
 	unsigned long flags;
+	int ignore;
 
 	daemonize("zfcperp%s", dev_name(&adapter->ccw_device->dev));
 	/* Block all signals */
@@ -1401,7 +1402,7 @@ static int zfcp_erp_thread(void *data)
 		}
 
 		zfcp_rec_dbf_event_thread_lock(4, adapter);
-		down_interruptible(&adapter->erp_ready_sem);
+		ignore = down_interruptible(&adapter->erp_ready_sem);
 		zfcp_rec_dbf_event_thread_lock(5, adapter);
 	}
 
#6 lore raw

PATCH 6/11 zfcp: Remove initial device data from zfcp_data

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

The information from the kernel parameter is only needed during init. Keep the three pieces (busid, wwpn and lun) local to simplify the global zfcp_data structures. While at it, also remove the unused loglevel variable and give the module parameter variable a better name.

---

 drivers/s390/scsi/zfcp_aux.c |   95 ++++++++++++++++++++-----------------------
 drivers/s390/scsi/zfcp_def.h |    4 -
 2 files changed, 46 insertions(+), 53 deletions(-)
drivers/s390/scsi/zfcp_aux.c +46 -49
@@ -28,13 +28,14 @@
 #include <linux/miscdevice.h>
 #include "zfcp_ext.h"
 
-static char *device;
+#define ZFCP_BUS_ID_SIZE	20
 
 MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - [email protected]");
 MODULE_DESCRIPTION("FCP HBA driver");
 MODULE_LICENSE("GPL");
 
-module_param(device, charp, 0400);
+static char *init_device;
+module_param_named(device, init_device, charp, 0400);
 MODULE_PARM_DESC(device, "specify initial device");
 
 static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter)
@@ -67,46 +68,7 @@ int zfcp_reqlist_isempty(struct zfcp_ada
 	return 1;
 }
 
-static int __init zfcp_device_setup(char *devstr)
-{
-	char *token;
-	char *str;
-
-	if (!devstr)
-		return 0;
-
-	/* duplicate devstr and keep the original for sysfs presentation*/
-	str = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
-	if (!str)
-		return 0;
-
-	strcpy(str, devstr);
-
-	token = strsep(&str, ",");
-	if (!token || strlen(token) >= BUS_ID_SIZE)
-		goto err_out;
-	strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE);
-
-	token = strsep(&str, ",");
-	if (!token || strict_strtoull(token, 0,
-				(unsigned long long *) &zfcp_data.init_wwpn))
-		goto err_out;
-
-	token = strsep(&str, ",");
-	if (!token || strict_strtoull(token, 0,
-				(unsigned long long *) &zfcp_data.init_fcp_lun))
-		goto err_out;
-
-	kfree(str);
-	return 1;
-
- err_out:
-	kfree(str);
-	pr_err("zfcp: %s is not a valid SCSI device\n", devstr);
-	return 0;
-}
-
-static void __init zfcp_init_device_configure(void)
+static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
 {
 	struct zfcp_adapter *adapter;
 	struct zfcp_port *port;
@@ -114,17 +76,17 @@ static void __init zfcp_init_device_conf
 
 	down(&zfcp_data.config_sema);
 	read_lock_irq(&zfcp_data.config_lock);
-	adapter = zfcp_get_adapter_by_busid(zfcp_data.init_busid);
+	adapter = zfcp_get_adapter_by_busid(busid);
 	if (adapter)
 		zfcp_adapter_get(adapter);
 	read_unlock_irq(&zfcp_data.config_lock);
 
 	if (!adapter)
 		goto out_adapter;
-	port = zfcp_port_enqueue(adapter, zfcp_data.init_wwpn, 0, 0);
+	port = zfcp_port_enqueue(adapter, wwpn, 0, 0);
 	if (IS_ERR(port))
 		goto out_port;
-	unit = zfcp_unit_enqueue(port, zfcp_data.init_fcp_lun);
+	unit = zfcp_unit_enqueue(port, lun);
 	if (IS_ERR(unit))
 		goto out_unit;
 	up(&zfcp_data.config_sema);
@@ -154,6 +116,42 @@ static struct kmem_cache *zfcp_cache_cre
 	return kmem_cache_create(name , size, align, 0, NULL);
 }
 
+static void __init zfcp_init_device_setup(char *devstr)
+{
+	char *token;
+	char *str;
+	char busid[ZFCP_BUS_ID_SIZE];
+	u64 wwpn, lun;
+
+	/* duplicate devstr and keep the original for sysfs presentation*/
+	str = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
+	if (!str)
+		return;
+
+	strcpy(str, devstr);
+
+	token = strsep(&str, ",");
+	if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE)
+		goto err_out;
+	strncpy(busid, token, ZFCP_BUS_ID_SIZE);
+
+	token = strsep(&str, ",");
+	if (!token || strict_strtoull(token, 0, (unsigned long long *) &wwpn))
+		goto err_out;
+
+	token = strsep(&str, ",");
+	if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun))
+		goto err_out;
+
+	kfree(str);
+	zfcp_init_device_configure(busid, wwpn, lun);
+	return;
+
+ err_out:
+	kfree(str);
+	pr_err("%s is not a valid SCSI device\n", devstr);
+}
+
 static int __init zfcp_module_init(void)
 {
 	int retval = -ENOMEM;
@@ -196,10 +194,9 @@ static int __init zfcp_module_init(void)
 		goto out_ccw_register;
 	}
 
-	if (zfcp_device_setup(device))
-		zfcp_init_device_configure();
-
-	goto out;
+	if (init_device)
+		zfcp_init_device_setup(init_device);
+	return 0;
 
 out_ccw_register:
 	misc_deregister(&zfcp_cfdc_misc);
drivers/s390/scsi/zfcp_def.h +0 -4
@@ -595,10 +595,6 @@ struct zfcp_data {
 						       lists */
 	struct semaphore        config_sema;        /* serialises configuration
 						       changes */
-	atomic_t		loglevel;            /* current loglevel */
-	char			init_busid[20];
-	u64			init_wwpn;
-	u64			init_fcp_lun;
 	struct kmem_cache	*fsf_req_qtcb_cache;
 	struct kmem_cache	*sr_buffer_cache;
 	struct kmem_cache	*gid_pn_cache;
#7 lore raw

PATCH 7/11 zfcp: Simplify mask lookups for incoming RSCNs

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Use an array for looking up the mask corresponding to the 2-bit information instead of the switch/case.

---
 drivers/s390/scsi/zfcp_def.h |   14 --------------
 drivers/s390/scsi/zfcp_fc.c  |   31 +++++++++++++++----------------
 2 files changed, 15 insertions(+), 30 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -14
@@ -158,20 +158,6 @@ struct fcp_rscn_element {
         u32 nport_did:24;
 } __attribute__((packed));
 
-#define ZFCP_PORT_ADDRESS   0x0
-#define ZFCP_AREA_ADDRESS   0x1
-#define ZFCP_DOMAIN_ADDRESS 0x2
-#define ZFCP_FABRIC_ADDRESS 0x3
-
-#define ZFCP_PORTS_RANGE_PORT   0xFFFFFF
-#define ZFCP_PORTS_RANGE_AREA   0xFFFF00
-#define ZFCP_PORTS_RANGE_DOMAIN 0xFF0000
-#define ZFCP_PORTS_RANGE_FABRIC 0x000000
-
-#define ZFCP_NO_PORTS_PER_AREA    0x100
-#define ZFCP_NO_PORTS_PER_DOMAIN  0x10000
-#define ZFCP_NO_PORTS_PER_FABRIC  0x1000000
-
 /* see fc-ph */
 struct fcp_logo {
         u32 command;
drivers/s390/scsi/zfcp_fc.c +15 -16
@@ -8,6 +8,20 @@
 
 #include "zfcp_ext.h"
 
+enum rscn_address_format {
+	RSCN_PORT_ADDRESS	= 0x0,
+	RSCN_AREA_ADDRESS	= 0x1,
+	RSCN_DOMAIN_ADDRESS	= 0x2,
+	RSCN_FABRIC_ADDRESS	= 0x3,
+};
+
+static u32 rscn_range_mask[] = {
+	[RSCN_PORT_ADDRESS]		= 0xFFFFFF,
+	[RSCN_AREA_ADDRESS]		= 0xFFFF00,
+	[RSCN_DOMAIN_ADDRESS]		= 0xFF0000,
+	[RSCN_FABRIC_ADDRESS]		= 0x000000,
+};
+
 struct ct_iu_gpn_ft_req {
 	struct ct_hdr header;
 	u8 flags;
@@ -157,22 +171,7 @@ static void zfcp_fc_incoming_rscn(struct
 	for (i = 1; i < no_entries; i++) {
 		/* skip head and start with 1st element */
 		fcp_rscn_element++;
-		switch (fcp_rscn_element->addr_format) {
-		case ZFCP_PORT_ADDRESS:
-			range_mask = ZFCP_PORTS_RANGE_PORT;
-			break;
-		case ZFCP_AREA_ADDRESS:
-			range_mask = ZFCP_PORTS_RANGE_AREA;
-			break;
-		case ZFCP_DOMAIN_ADDRESS:
-			range_mask = ZFCP_PORTS_RANGE_DOMAIN;
-			break;
-		case ZFCP_FABRIC_ADDRESS:
-			range_mask = ZFCP_PORTS_RANGE_FABRIC;
-			break;
-		default:
-			continue;
-		}
+		range_mask = rscn_range_mask[fcp_rscn_element->addr_format];
 		_zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element);
 	}
 	schedule_work(&fsf_req->adapter->scan_work);
#8 lore raw

PATCH 8/11 zfcp: remove DID_DID flag

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

The port flag DID_DID indicates whether we know the current id of the port. This is always set in parallel. Since the id 0 is invalid (because the port id 0 is invalid) we can remove the DID_DID flag:
d_id of 0 indicates an invalid d_id != 0 is a valid one.

---
 drivers/s390/scsi/zfcp_def.h |    1 -
 drivers/s390/scsi/zfcp_erp.c |    7 +++----
 drivers/s390/scsi/zfcp_fc.c  |    2 --
 drivers/s390/scsi/zfcp_fsf.c |    3 +--
 4 files changed, 4 insertions(+), 9 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -1
@@ -243,7 +243,6 @@ struct zfcp_ls_adisc {
 
 /* remote port status */
 #define ZFCP_STATUS_PORT_PHYS_OPEN		0x00000001
-#define ZFCP_STATUS_PORT_DID_DID		0x00000002
 #define ZFCP_STATUS_PORT_PHYS_CLOSING		0x00000004
 #define ZFCP_STATUS_PORT_NO_WWPN		0x00000008
 #define ZFCP_STATUS_PORT_INVALID_WWPN		0x00000020
drivers/s390/scsi/zfcp_erp.c +3 -4
@@ -837,7 +837,6 @@ static int zfcp_erp_open_ptp_port(struct
 		return ZFCP_ERP_FAILED;
 	}
 	port->d_id = adapter->peer_d_id;
-	atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
 	return zfcp_erp_port_strategy_open_port(act);
 }
 
@@ -868,12 +867,12 @@ static int zfcp_erp_port_strategy_open_c
 	case ZFCP_ERP_STEP_PORT_CLOSING:
 		if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
 			return zfcp_erp_open_ptp_port(act);
-		if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
+		if (!port->d_id) {
 			queue_work(zfcp_data.work_queue, &port->gid_pn_work);
 			return ZFCP_ERP_CONTINUES;
 		}
 	case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
-		if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
+		if (!port->d_id) {
 			if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) {
 				zfcp_erp_port_failed(port, 26, NULL);
 				return ZFCP_ERP_EXIT;
@@ -885,7 +884,7 @@ static int zfcp_erp_port_strategy_open_c
 	case ZFCP_ERP_STEP_PORT_OPENING:
 		/* D_ID might have changed during open */
 		if (p_status & ZFCP_STATUS_COMMON_OPEN) {
-			if (p_status & ZFCP_STATUS_PORT_DID_DID)
+			if (port->d_id)
 				return ZFCP_ERP_SUCCEEDED;
 			else {
 				act->step = ZFCP_ERP_STEP_PORT_CLOSING;
drivers/s390/scsi/zfcp_fc.c +0 -2
@@ -262,7 +262,6 @@ static void zfcp_fc_ns_gid_pn_eval(unsig
 		return;
 	/* looks like a valid d_id */
 	port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
-	atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
 }
 
 int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
@@ -585,7 +584,6 @@ static int zfcp_scan_eval_gpn_ft(struct 
 		}
 
 		port = zfcp_port_enqueue(adapter, acc->wwpn,
-					 ZFCP_STATUS_PORT_DID_DID |
 					 ZFCP_STATUS_COMMON_NOESC, d_id);
 		if (IS_ERR(port))
 			ret = PTR_ERR(port);
drivers/s390/scsi/zfcp_fsf.c +1 -2
@@ -1439,8 +1439,7 @@ static void zfcp_fsf_open_port_handler(s
 		plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
 		if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) {
 			if (plogi->serv_param.wwpn != port->wwpn)
-				atomic_clear_mask(ZFCP_STATUS_PORT_DID_DID,
-						  &port->status);
+				port->d_id = 0;
 			else {
 				port->wwnn = plogi->serv_param.wwnn;
 				zfcp_fc_plogi_evaluate(port, plogi);
#9 lore raw

PATCH 9/11 zfcp: Remove busid macro

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

With the change to the dev_ message macros, the macro to get the busid is only used in a few places. Remove it and directly get the dev_name from the device.

---
 drivers/s390/scsi/zfcp_dbf.c  |    8 ++++----
 drivers/s390/scsi/zfcp_def.h  |    2 --
 drivers/s390/scsi/zfcp_qdio.c |    4 ++--
 3 files changed, 6 insertions(+), 8 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +4 -4
@@ -1246,7 +1246,7 @@ int zfcp_adapter_debug_register(struct z
 	char dbf_name[DEBUG_MAX_NAME_LEN];
 
 	/* debug feature area which records recovery activity */
-	sprintf(dbf_name, "zfcp_%s_rec", zfcp_get_busid_by_adapter(adapter));
+	sprintf(dbf_name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev));
 	adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1,
 					  sizeof(struct zfcp_rec_dbf_record));
 	if (!adapter->rec_dbf)
@@ -1256,7 +1256,7 @@ int zfcp_adapter_debug_register(struct z
 	debug_set_level(adapter->rec_dbf, 3);
 
 	/* debug feature area which records HBA (FSF and QDIO) conditions */
-	sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
+	sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev));
 	adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
 					  sizeof(struct zfcp_hba_dbf_record));
 	if (!adapter->hba_dbf)
@@ -1266,7 +1266,7 @@ int zfcp_adapter_debug_register(struct z
 	debug_set_level(adapter->hba_dbf, 3);
 
 	/* debug feature area which records SAN command failures and recovery */
-	sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
+	sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev));
 	adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
 					  sizeof(struct zfcp_san_dbf_record));
 	if (!adapter->san_dbf)
@@ -1276,7 +1276,7 @@ int zfcp_adapter_debug_register(struct z
 	debug_set_level(adapter->san_dbf, 6);
 
 	/* debug feature area which records SCSI command failures and recovery */
-	sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
+	sprintf(dbf_name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev));
 	adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
 					   sizeof(struct zfcp_scsi_dbf_record));
 	if (!adapter->scsi_dbf)
drivers/s390/scsi/zfcp_def.h +0 -2
@@ -600,8 +600,6 @@ struct zfcp_fsf_req_qtcb {
 #define ZFCP_SET                0x00000100
 #define ZFCP_CLEAR              0x00000200
 
-#define zfcp_get_busid_by_adapter(adapter) (dev_name(&adapter->ccw_device->dev))
-
 /*
  * Helper functions for request ID management.
  */
drivers/s390/scsi/zfcp_qdio.c +2 -2
@@ -109,7 +109,7 @@ static void zfcp_qdio_reqid_check(struct
 		 * corruption and must stop the machine immediatly.
 		 */
 		panic("error: unknown request id (%lx) on adapter %s.\n",
-		      req_id, zfcp_get_busid_by_adapter(adapter));
+		      req_id, dev_name(&adapter->ccw_device->dev));
 
 	zfcp_reqlist_remove(adapter, fsf_req);
 	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
@@ -389,7 +389,7 @@ int zfcp_qdio_allocate(struct zfcp_adapt
 
 	init_data->cdev = adapter->ccw_device;
 	init_data->q_format = QDIO_ZFCP_QFMT;
-	memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8);
+	memcpy(init_data->adapter_name, dev_name(&adapter->ccw_device->dev), 8);
 	ASCEBC(init_data->adapter_name, 8);
 	init_data->qib_param_field_format = 0;
 	init_data->qib_param_field = NULL;
#10 lore raw

PATCH 10/11 zfcp: Add support for unchained FSF requests

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Add the support to send CT and ELS requests as unchained FSF requests. This is required for older hardware and was somehow omitted during the cleanup of the FSF layer. The req_count and resp_count attributes are unused, so remove them instead of adding a special case for setting them. Also add debug data and a warning, when the ct request hits a limit.

---
 drivers/s390/scsi/zfcp_dbf.c |    2 +
 drivers/s390/scsi/zfcp_dbf.h |    1 
 drivers/s390/scsi/zfcp_def.h |    9 -------
 drivers/s390/scsi/zfcp_fc.c  |   55 ++++++++++++++++++++++++-------------------
 drivers/s390/scsi/zfcp_fsf.c |   32 +++++++++++++++++++------
 drivers/s390/scsi/zfcp_fsf.h |    2 +
 6 files changed, 61 insertions(+), 40 deletions(-)
drivers/s390/scsi/zfcp_fc.c +31 -24
@@ -37,9 +37,12 @@ struct gpn_ft_resp_acc {
 	u64 wwpn;
 } __attribute__ ((packed));
 
-#define ZFCP_GPN_FT_ENTRIES ((PAGE_SIZE - sizeof(struct ct_hdr)) \
-				/ sizeof(struct gpn_ft_resp_acc))
+#define ZFCP_CT_SIZE_ONE_PAGE	(PAGE_SIZE - sizeof(struct ct_hdr))
+#define ZFCP_GPN_FT_ENTRIES	(ZFCP_CT_SIZE_ONE_PAGE \
+					/ sizeof(struct gpn_ft_resp_acc))
 #define ZFCP_GPN_FT_BUFFERS 4
+#define ZFCP_GPN_FT_MAX_SIZE (ZFCP_GPN_FT_BUFFERS * PAGE_SIZE \
+				- sizeof(struct ct_hdr))
 #define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1)
 
 struct ct_iu_gpn_ft_resp {
@@ -279,8 +282,6 @@ int static zfcp_fc_ns_gid_pn_request(str
 	gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT;
 	gid_pn->ct.req = &gid_pn->req;
 	gid_pn->ct.resp = &gid_pn->resp;
-	gid_pn->ct.req_count = 1;
-	gid_pn->ct.resp_count = 1;
 	sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req,
 		    sizeof(struct ct_iu_gid_pn_req));
 	sg_init_one(&gid_pn->resp, &gid_pn->ct_iu_resp,
@@ -292,7 +293,7 @@ int static zfcp_fc_ns_gid_pn_request(str
 	gid_pn->ct_iu_req.header.gs_subtype = ZFCP_CT_NAME_SERVER;
 	gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
 	gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
-	gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE;
+	gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
 	gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn;
 
 	init_completion(&compl_rec.done);
@@ -402,8 +403,6 @@ static int zfcp_fc_adisc(struct zfcp_por
 	sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc,
 		    sizeof(struct zfcp_ls_adisc));
 
-	adisc->els.req_count = 1;
-	adisc->els.resp_count = 1;
 	adisc->els.adapter = adapter;
 	adisc->els.port = port;
 	adisc->els.d_id = port->d_id;
@@ -443,17 +442,17 @@ void zfcp_test_link(struct zfcp_port *po
 		zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
 }
 
-static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft)
+static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
 {
 	struct scatterlist *sg = &gpn_ft->sg_req;
 
 	kfree(sg_virt(sg)); /* free request buffer */
-	zfcp_sg_free_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS);
+	zfcp_sg_free_table(gpn_ft->sg_resp, buf_num);
 
 	kfree(gpn_ft);
 }
 
-static struct zfcp_gpn_ft *zfcp_alloc_sg_env(void)
+static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
 {
 	struct zfcp_gpn_ft *gpn_ft;
 	struct ct_iu_gpn_ft_req *req;
@@ -470,8 +469,8 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg
 	}
 	sg_init_one(&gpn_ft->sg_req, req, sizeof(*req));
 
-	if (zfcp_sg_setup_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS)) {
-		zfcp_free_sg_env(gpn_ft);
+	if (zfcp_sg_setup_table(gpn_ft->sg_resp, buf_num)) {
+		zfcp_free_sg_env(gpn_ft, buf_num);
 		gpn_ft = NULL;
 	}
 out:
@@ -480,7 +479,8 @@ out:
 
 
 static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
-				  struct zfcp_adapter *adapter)
+				  struct zfcp_adapter *adapter,
+				  int max_bytes)
 {
 	struct zfcp_send_ct *ct = &gpn_ft->ct;
 	struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
@@ -493,8 +493,7 @@ static int zfcp_scan_issue_gpn_ft(struct
 	req->header.gs_subtype = ZFCP_CT_NAME_SERVER;
 	req->header.options = ZFCP_CT_SYNCHRONOUS;
 	req->header.cmd_rsp_code = ZFCP_CT_GPN_FT;
-	req->header.max_res_size = (sizeof(struct gpn_ft_resp_acc) *
-					(ZFCP_GPN_FT_MAX_ENTRIES - 1)) >> 2;
+	req->header.max_res_size = max_bytes / 4;
 	req->flags = 0;
 	req->domain_id_scope = 0;
 	req->area_id_scope = 0;
@@ -507,8 +506,6 @@ static int zfcp_scan_issue_gpn_ft(struct
 	ct->timeout = 10;
 	ct->req = &gpn_ft->sg_req;
 	ct->resp = gpn_ft->sg_resp;
-	ct->req_count = 1;
-	ct->resp_count = ZFCP_GPN_FT_BUFFERS;
 
 	init_completion(&compl_rec.done);
 	compl_rec.handler = NULL;
@@ -535,7 +532,7 @@ static void zfcp_validate_port(struct zf
 	zfcp_port_dequeue(port);
 }
 
-static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
+static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
 {
 	struct zfcp_send_ct *ct = &gpn_ft->ct;
 	struct scatterlist *sg = gpn_ft->sg_resp;
@@ -555,13 +552,17 @@ static int zfcp_scan_eval_gpn_ft(struct 
 		return -EIO;
 	}
 
-	if (hdr->max_res_size)
+	if (hdr->max_res_size) {
+		dev_warn(&adapter->ccw_device->dev,
+			 "The name server reported %d words residual data\n",
+			 hdr->max_res_size);
 		return -E2BIG;
+	}
 
 	down(&zfcp_data.config_sema);
 
 	/* first entry is the header */
-	for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {
+	for (x = 1; x < max_entries && !last; x++) {
 		if (x % (ZFCP_GPN_FT_ENTRIES + 1))
 			acc++;
 		else
@@ -606,6 +607,12 @@ int zfcp_scan_ports(struct zfcp_adapter 
 {
 	int ret, i;
 	struct zfcp_gpn_ft *gpn_ft;
+	int chain, max_entries, buf_num, max_bytes;
+
+	chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS;
+	buf_num = chain ? ZFCP_GPN_FT_BUFFERS : 1;
+	max_entries = chain ? ZFCP_GPN_FT_MAX_ENTRIES : ZFCP_GPN_FT_ENTRIES;
+	max_bytes = chain ? ZFCP_GPN_FT_MAX_SIZE : ZFCP_CT_SIZE_ONE_PAGE;
 
 	if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT)
 		return 0;
@@ -614,23 +621,23 @@ int zfcp_scan_ports(struct zfcp_adapter 
 	if (ret)
 		return ret;
 
-	gpn_ft = zfcp_alloc_sg_env();
+	gpn_ft = zfcp_alloc_sg_env(buf_num);
 	if (!gpn_ft) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
 	for (i = 0; i < 3; i++) {
-		ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter);
+		ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter, max_bytes);
 		if (!ret) {
-			ret = zfcp_scan_eval_gpn_ft(gpn_ft);
+			ret = zfcp_scan_eval_gpn_ft(gpn_ft, max_entries);
 			if (ret == -EAGAIN)
 				ssleep(1);
 			else
 				break;
 		}
 	}
-	zfcp_free_sg_env(gpn_ft);
+	zfcp_free_sg_env(gpn_ft, buf_num);
 out:
 	zfcp_wka_port_put(&adapter->nsp);
 	return ret;
drivers/s390/scsi/zfcp_fsf.h +2 -0
@@ -164,6 +164,7 @@
 #define FSF_FEATURE_LUN_SHARING			0x00000004
 #define FSF_FEATURE_NOTIFICATION_LOST		0x00000008
 #define FSF_FEATURE_HBAAPI_MANAGEMENT           0x00000010
+#define FSF_FEATURE_ELS_CT_CHAINED_SBALS	0x00000020
 #define FSF_FEATURE_UPDATE_ALERT		0x00000100
 #define FSF_FEATURE_MEASUREMENT_DATA		0x00000200
 
@@ -322,6 +323,7 @@ struct fsf_nport_serv_param {
 	u8  vendor_version_level[16];
 } __attribute__ ((packed));
 
+#define FSF_PLOGI_MIN_LEN	112
 struct fsf_plogi {
 	u32    code;
 	struct fsf_nport_serv_param serv_param;
drivers/s390/scsi/zfcp_fsf.c +25 -7
@@ -1010,12 +1010,29 @@ skip_fsfstatus:
 		send_ct->handler(send_ct->handler_data);
 }
 
-static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req,
-				struct scatterlist *sg_req,
-				struct scatterlist *sg_resp, int max_sbals)
+static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
+				       struct scatterlist *sg_req,
+				       struct scatterlist *sg_resp,
+				       int max_sbals)
 {
+	struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(req);
+	u32 feat = req->adapter->adapter_features;
 	int bytes;
 
+	if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
+		if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE ||
+		    !sg_is_last(sg_req) || !sg_is_last(sg_resp))
+			return -EOPNOTSUPP;
+
+		sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
+		sbale[2].addr   = sg_virt(sg_req);
+		sbale[2].length = sg_req->length;
+		sbale[3].addr   = sg_virt(sg_resp);
+		sbale[3].length = sg_resp->length;
+		sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
+		return 0;
+	}
+
 	bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
 					sg_req, max_sbals);
 	if (bytes <= 0)
@@ -1057,8 +1074,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct
 		goto out;
 	}
 
-	ret = zfcp_fsf_setup_sbals(req, ct->req, ct->resp,
-				   FSF_MAX_SBALS_PER_REQ);
+	ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
+					  FSF_MAX_SBALS_PER_REQ);
 	if (ret)
 		goto failed_send;
 
@@ -1168,7 +1185,7 @@ int zfcp_fsf_send_els(struct zfcp_send_e
 		goto out;
 	}
 
-	ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, 2);
+	ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
 
 	if (ret)
 		goto failed_send;
@@ -1437,7 +1454,8 @@ static void zfcp_fsf_open_port_handler(s
 		 * Alternately, an ADISC/PDISC ELS should suffice, as well.
 		 */
 		plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
-		if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) {
+		if (req->qtcb->bottom.support.els1_length >=
+		    FSF_PLOGI_MIN_LEN) {
 			if (plogi->serv_param.wwpn != port->wwpn)
 				port->d_id = 0;
 			else {
drivers/s390/scsi/zfcp_dbf.c +2 -0
@@ -933,6 +933,7 @@ void zfcp_san_dbf_event_ct_response(stru
 	rct->reason_code = hdr->reason_code;
 	rct->expl = hdr->reason_code_expl;
 	rct->vendor_unique = hdr->vendor_unique;
+	rct->max_res_size = hdr->max_res_size;
 	rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
 	debug_event(adapter->san_dbf, level, r, sizeof(*r));
@@ -1040,6 +1041,7 @@ static int zfcp_san_dbf_view_format(debu
 		zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
 		zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
 		zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
+		zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
 	} else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
 		   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
 		   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
drivers/s390/scsi/zfcp_dbf.h +1 -0
@@ -171,6 +171,7 @@ struct zfcp_san_dbf_record_ct_response {
 	u8 reason_code;
 	u8 expl;
 	u8 vendor_unique;
+	u16 max_res_size;
 	u32 len;
 } __attribute__ ((packed));
 
drivers/s390/scsi/zfcp_def.h +0 -9
@@ -196,7 +196,6 @@ struct zfcp_ls_adisc {
 #define ZFCP_CT_UNABLE_TO_PERFORM_CMD	0x09
 #define ZFCP_CT_GID_PN			0x0121
 #define ZFCP_CT_GPN_FT			0x0172
-#define ZFCP_CT_MAX_SIZE		0x1020
 #define ZFCP_CT_ACCEPT			0x8002
 #define ZFCP_CT_REJECT			0x8001
 
@@ -324,8 +323,6 @@ struct ct_iu_gid_pn_resp {
  * @wka_port: port where the request is sent to
  * @req: scatter-gather list for request
  * @resp: scatter-gather list for response
- * @req_count: number of elements in request scatter-gather list
- * @resp_count: number of elements in response scatter-gather list
  * @handler: handler function (called for response to the request)
  * @handler_data: data passed to handler function
  * @timeout: FSF timeout for this request
@@ -336,8 +333,6 @@ struct zfcp_send_ct {
 	struct zfcp_wka_port *wka_port;
 	struct scatterlist *req;
 	struct scatterlist *resp;
-	unsigned int req_count;
-	unsigned int resp_count;
 	void (*handler)(unsigned long);
 	unsigned long handler_data;
 	int timeout;
@@ -362,8 +357,6 @@ struct zfcp_gid_pn_data {
  * @d_id: destiniation id of port where request is sent to
  * @req: scatter-gather list for request
  * @resp: scatter-gather list for response
- * @req_count: number of elements in request scatter-gather list
- * @resp_count: number of elements in response scatter-gather list
  * @handler: handler function (called for response to the request)
  * @handler_data: data passed to handler function
  * @completion: completion for synchronization purposes
@@ -376,8 +369,6 @@ struct zfcp_send_els {
 	u32 d_id;
 	struct scatterlist *req;
 	struct scatterlist *resp;
-	unsigned int req_count;
-	unsigned int resp_count;
 	void (*handler)(unsigned long);
 	unsigned long handler_data;
 	struct completion *completion;
#11 lore raw

PATCH 11/11 zfcp: Remove unnecessary warning message

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Remove a message that was emitted for a port that could not initially be opened. This is a rare case when the port discovery hits an initiator port and only confuses the user with an initator port logged in the message. Remove the whole special case: The failed "open port" request triggers required follow-up actions anyway.

---
 drivers/s390/scsi/zfcp_dbf.c |    2 +-
 drivers/s390/scsi/zfcp_fsf.c |    6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +1 -1
@@ -519,7 +519,7 @@ static const char *zfcp_rec_dbf_ids[] = 
 	[29]	= "link down",
 	[30]	= "link up status read",
 	[31]	= "open port failed",
-	[32]	= "open port failed",
+	[32]	= "",
 	[33]	= "close port",
 	[34]	= "open unit failed",
 	[35]	= "exclusive open unit failed",
drivers/s390/scsi/zfcp_fsf.c +0 -6
@@ -1420,13 +1420,7 @@ static void zfcp_fsf_open_port_handler(s
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-			break;
 		case FSF_SQ_NO_RETRY_POSSIBLE:
-			dev_warn(&req->adapter->ccw_device->dev,
-				 "Remote port 0x%016Lx could not be opened\n",
-				 (unsigned long long)port->wwpn);
-			zfcp_erp_port_failed(port, 32, req);
 			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		}