Skip to contentSkip to conversation

zfcp patches for 2.6.37 merge window

PATCH New Christof Schmitt 1 participant 13 messages Sep 8, 2010

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

cover zfcp patches for 2.6.37 merge window

James,

here is the series of zfcp updates for the 2.6.37 merge window. The patches apply on top of the scsi-misc tree. The first patch is the same as the one submitted as fix for 2.6.36 here:
http://marc.info/?l=linux-scsi&m=128324031704285&w=2
The patch is required for the following patches to apply.

The main change is the restructuring of the LUN data structures and related code. With this change, zfcp finally can make use of the REPORT LUNs scan in the SCSI midlayer when using a NPIV subchannel.

--
Christof

#1 lore raw

PATCH 1/12 zfcp: Reorder registration of initial SCSI device

From: Christof Schmitt <[email protected]>

Make sure that the rport registration did complete and then register SCSI device directly. Otherwise the unit_unqueue would race with the call to zfcp_scsi_queue_unit_register.

---

 drivers/s390/scsi/zfcp_aux.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/s390/scsi/zfcp_aux.c +2 -1
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_aux.c linux-2.6-patched/drivers/s390/scsi/zfcp_aux.c
@@ -73,13 +73,14 @@ static void __init zfcp_init_device_conf
 	if (!port)
 		goto out_port;
 
+	flush_work(&port->rport_work);
 	unit = zfcp_unit_enqueue(port, lun);
 	if (IS_ERR(unit))
 		goto out_unit;
 
 	zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
 	zfcp_erp_wait(adapter);
-	flush_work(&unit->scsi_work);
+	zfcp_scsi_scan(unit);
 
 out_unit:
 	put_device(&port->dev);
#2 lore raw

PATCH 2/12 zfcp: Add zfcp private struct as SCSI device driver data

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Add a new data structure zfcp_scsi_dev that holds zfcp private data for each SCSI device. Use scsi_transport_reserve_device to let the SCSI midlayer automatically allocate this with each SCSI device.

---

 drivers/s390/scsi/zfcp_aux.c |    3 +++
 drivers/s390/scsi/zfcp_def.h |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
drivers/s390/scsi/zfcp_aux.c +3 -0
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_aux.c linux-2.6-patched/drivers/s390/scsi/zfcp_aux.c
@@ -159,6 +159,9 @@ static int __init zfcp_module_init(void)
 		fc_attach_transport(&zfcp_transport_functions);
 	if (!zfcp_data.scsi_transport_template)
 		goto out_transport;
+	scsi_transport_reserve_device(zfcp_data.scsi_transport_template,
+				      sizeof(struct zfcp_scsi_dev));
+
 
 	retval = misc_register(&zfcp_cfdc_misc);
 	if (retval) {
drivers/s390/scsi/zfcp_def.h +39 -0
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_def.h linux-2.6-patched/drivers/s390/scsi/zfcp_def.h
@@ -234,6 +234,45 @@ struct zfcp_unit {
 };
 
 /**
+ * struct zfcp_scsi_dev - zfcp data per SCSI device
+ * @status: zfcp internal status flags
+ * @lun_handle: handle from "open lun" for issuing FSF requests
+ * @erp_action: zfcp erp data for opening and recovering this LUN
+ * @erp_counter: zfcp erp counter for this LUN
+ * @latencies: FSF channel and fabric latencies
+ * @port: zfcp_port where this LUN belongs to
+ */
+struct zfcp_scsi_dev {
+	atomic_t		status;
+	u32			lun_handle;
+	struct zfcp_erp_action	erp_action;
+	atomic_t		erp_counter;
+	struct zfcp_latencies	latencies;
+	struct zfcp_port	*port;
+};
+
+/**
+ * sdev_to_zfcp - Access zfcp LUN data for SCSI device
+ * @sdev: scsi_device where to get the zfcp_scsi_dev pointer
+ */
+static inline struct zfcp_scsi_dev *sdev_to_zfcp(struct scsi_device *sdev)
+{
+	return scsi_transport_device_data(sdev);
+}
+
+/**
+ * zfcp_scsi_dev_lun - Return SCSI device LUN as 64 bit FCP LUN
+ * @sdev: SCSI device where to get the LUN from
+ */
+static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev)
+{
+	u64 fcp_lun;
+
+	int_to_scsilun(sdev->lun, (struct scsi_lun *)&fcp_lun);
+	return fcp_lun;
+}
+
+/**
  * struct zfcp_fsf_req - basic FSF request structure
  * @list: list of FSF requests
  * @req_id: unique request ID
#3 lore raw

PATCH 3/12 zfcp: Move code for managing zfcp_unit devices to new file

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Move the code for managing zfcp_unit devices to the new file zfcp_unit.c. This is in preparation for the change that zfcp_unit will only track the LUNs configured via unit_add, other data will be moved from zfcp_unit to the new struct zfcp_scsi_dev.

---

 drivers/s390/scsi/Makefile     |    5 
 drivers/s390/scsi/zfcp_aux.c   |  122 -------------------
 drivers/s390/scsi/zfcp_ext.h   |   13 +-
 drivers/s390/scsi/zfcp_scsi.c  |   41 ------
 drivers/s390/scsi/zfcp_sysfs.c |   60 +--------
 drivers/s390/scsi/zfcp_unit.c  |  255 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 281 insertions(+), 215 deletions(-)
drivers/s390/scsi/Makefile +3 -2
diff -urpN linux-2.6/drivers/s390/scsi/Makefile linux-2.6-patched/drivers/s390/scsi/Makefile
@@ -2,7 +2,8 @@
 # Makefile for the S/390 specific device drivers
 #
 
-zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
-	     zfcp_fsf.o zfcp_dbf.o zfcp_sysfs.o zfcp_fc.o zfcp_cfdc.o
+zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_cfdc.o zfcp_dbf.o zfcp_erp.o \
+	     zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \
+	     zfcp_unit.o
 
 obj-$(CONFIG_ZFCP) += zfcp.o
drivers/s390/scsi/zfcp_aux.c +2 -120

149 lines not on this page · raw message

drivers/s390/scsi/zfcp_ext.h +9 -4
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_ext.h linux-2.6-patched/drivers/s390/scsi/zfcp_ext.h
@@ -15,12 +15,10 @@
 #include "zfcp_fc.h"
 
 /* zfcp_aux.c */
-extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
 extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
 extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
 extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
 					   u32);
-extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
 extern void zfcp_sg_free_table(struct scatterlist *, int);
 extern int zfcp_sg_setup_table(struct scatterlist *, int);
 extern void zfcp_device_unregister(struct device *,
@@ -163,8 +161,6 @@ extern void zfcp_scsi_rport_work(struct
 extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
 extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
 extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
-extern void zfcp_scsi_scan(struct zfcp_unit *);
-extern void zfcp_scsi_scan_work(struct work_struct *);
 extern void zfcp_scsi_set_prot(struct zfcp_adapter *);
 extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
 
@@ -175,4 +171,13 @@ extern struct attribute_group zfcp_sysfs
 extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
 extern struct device_attribute *zfcp_sysfs_shost_attrs[];
 
+/* zfcp_unit.c */
+extern int zfcp_unit_add(struct zfcp_port *, u64);
+extern int zfcp_unit_remove(struct zfcp_port *, u64);
+extern struct zfcp_unit *zfcp_unit_find(struct zfcp_port *, u64);
+extern struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit);
+extern void zfcp_unit_scsi_scan(struct zfcp_unit *);
+extern void zfcp_unit_queue_scsi_scan(struct zfcp_port *);
+extern unsigned int zfcp_unit_sdev_status(struct zfcp_unit *);
+
 #endif	/* ZFCP_EXT_H */
drivers/s390/scsi/zfcp_scsi.c +2 -39

65 lines not on this page · raw message

drivers/s390/scsi/zfcp_sysfs.c +10 -50

80 lines not on this page · raw message

drivers/s390/scsi/zfcp_unit.c +255 -0

255 lines not on this page · raw message

#4 lore raw

PATCH 4/12 zfcp: Remove ZFCP_SYSFS_FAILED macro and implement fcp_lun_show without macro

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

These sysfs attributes will require different functions. Implement them without using macros, so that the open coded functions can be changed later.

---

 drivers/s390/scsi/zfcp_sysfs.c |  121 ++++++++++++++++++++++++++---------------
 1 file changed, 77 insertions(+), 44 deletions(-)
drivers/s390/scsi/zfcp_sysfs.c +77 -44
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_sysfs.c linux-2.6-patched/drivers/s390/scsi/zfcp_sysfs.c
@@ -82,49 +82,73 @@ ZFCP_DEFINE_ATTR(zfcp_unit, unit, access
 		 (atomic_read(&unit->status) &
 		  ZFCP_STATUS_UNIT_READONLY) != 0);
 
-#define ZFCP_SYSFS_FAILED(_feat_def, _feat, _adapter, _mod_id, _reopen_id)     \
-static ssize_t zfcp_sysfs_##_feat##_failed_show(struct device *dev,	       \
-						struct device_attribute *attr, \
-						char *buf)		       \
-{									       \
-	struct _feat_def *_feat = container_of(dev, struct _feat_def, dev);    \
-									       \
-	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED)       \
-		return sprintf(buf, "1\n");				       \
-	else								       \
-		return sprintf(buf, "0\n");				       \
-}									       \
-static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev,	       \
-						 struct device_attribute *attr,\
-						 const char *buf, size_t count)\
-{									       \
-	struct _feat_def *_feat = container_of(dev, struct _feat_def, dev);    \
-	unsigned long val;						       \
-	int retval = 0;							       \
-									       \
-	if (!(_feat && get_device(&_feat->dev)))			       \
-		return -EBUSY;						       \
-									       \
-	if (strict_strtoul(buf, 0, &val) || val != 0) {			       \
-		retval = -EINVAL;					       \
-		goto out;						       \
-	}								       \
-									       \
-	zfcp_erp_modify_##_feat##_status(_feat, _mod_id, NULL,		       \
-					 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);\
-	zfcp_erp_##_feat##_reopen(_feat, ZFCP_STATUS_COMMON_ERP_FAILED,	       \
-				  _reopen_id, NULL);			       \
-	zfcp_erp_wait(_adapter);					       \
-out:									       \
-	put_device(&_feat->dev);					       \
-	return retval ? retval : (ssize_t) count;			       \
-}									       \
-static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO,			       \
-		     zfcp_sysfs_##_feat##_failed_show,			       \
-		     zfcp_sysfs_##_feat##_failed_store);
+static ssize_t zfcp_sysfs_port_failed_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
+
+	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+		return sprintf(buf, "1\n");
+
+	return sprintf(buf, "0\n");
+}
+
+static ssize_t zfcp_sysfs_port_failed_store(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 0, &val) || val != 0)
+		return -EINVAL;
+
+	zfcp_erp_modify_port_status(port, "sypfai1", NULL,
+				    ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2",
+			     NULL);
+	zfcp_erp_wait(port->adapter);
+
+	return count;
+}
+static ZFCP_DEV_ATTR(port, failed, S_IWUSR | S_IRUGO,
+		     zfcp_sysfs_port_failed_show,
+		     zfcp_sysfs_port_failed_store);
+
+static ssize_t zfcp_sysfs_unit_failed_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
 
-ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2");
-ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2");
+	if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+		return sprintf(buf, "1\n");
+
+	return sprintf(buf, "0\n");
+}
+
+static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 0, &val) || val != 0)
+		return -EINVAL;
+
+	zfcp_erp_modify_unit_status(unit, "syufai1", NULL,
+				    ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED,
+			     "syufai2", NULL);
+	zfcp_erp_wait(unit->port->adapter);
+
+	return count;
+}
+static ZFCP_DEV_ATTR(unit, failed, S_IWUSR | S_IRUGO,
+		     zfcp_sysfs_unit_failed_show,
+		     zfcp_sysfs_unit_failed_store);
 
 static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev,
 					      struct device_attribute *attr,
@@ -394,8 +418,17 @@ ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
 		      dev_name(&unit->port->adapter->ccw_device->dev));
 ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
 		      (unsigned long long) unit->port->wwpn);
-ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n",
-		      (unsigned long long) unit->fcp_lun);
+
+static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct zfcp_unit *unit = sdev->hostdata;
+
+	return sprintf(buf, "0x%016llx\n", (unsigned long long) unit->fcp_lun);
+}
+static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL);
 
 struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
 	&dev_attr_fcp_lun,
#5 lore raw

PATCH 5/12 zfcp: Allow running unit/LUN shutdown without acquiring reference

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

With the change for the LUN data to be part of the scsi_device, the slave_destroy callback will be the final call to the zfcp_erp_unit_shutdown function. The erp tries to acquire a reference to run the action asynchronously and fail, if it cannot get the reference. But calling scsi_device_get from slave_destroy will fail, because the scsi_device is already in the state SDEV_DEL.

Introduce a new call into the zfcp erp to solve this: The function zfcp_erp_unit_shutdown_wait will close the LUN and wait for the erp to finish without acquiring an additional reference. The wait allows to omit the reference; the caller waiting for the erp to finish already has a reference that holds the struct in place.

---

 drivers/s390/scsi/zfcp_erp.c |   98 +++++++++++++++++++++++++++----------------
 drivers/s390/scsi/zfcp_ext.h |    1 
 2 files changed, 63 insertions(+), 36 deletions(-)
drivers/s390/scsi/zfcp_erp.c +62 -36
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_erp.c linux-2.6-patched/drivers/s390/scsi/zfcp_erp.c
@@ -21,6 +21,7 @@ enum zfcp_erp_act_flags {
 	ZFCP_STATUS_ERP_DISMISSING	= 0x00100000,
 	ZFCP_STATUS_ERP_DISMISSED	= 0x00200000,
 	ZFCP_STATUS_ERP_LOWMEM		= 0x00400000,
+	ZFCP_STATUS_ERP_NO_REF		= 0x00800000,
 };
 
 enum zfcp_erp_steps {
@@ -169,22 +170,22 @@ static int zfcp_erp_required_act(int wan
 	return need;
 }
 
-static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
+static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
 						  struct zfcp_adapter *adapter,
 						  struct zfcp_port *port,
 						  struct zfcp_unit *unit)
 {
 	struct zfcp_erp_action *erp_action;
-	u32 status = 0;
 
 	switch (need) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
-		if (!get_device(&unit->dev))
-			return NULL;
+		if (!(act_status & ZFCP_STATUS_ERP_NO_REF))
+			if (!get_device(&unit->dev))
+				return NULL;
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
 		erp_action = &unit->erp_action;
 		if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
-			status = ZFCP_STATUS_ERP_CLOSE_ONLY;
+			act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
@@ -195,7 +196,7 @@ static struct zfcp_erp_action *zfcp_erp_
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
 		erp_action = &port->erp_action;
 		if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
-			status = ZFCP_STATUS_ERP_CLOSE_ONLY;
+			act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
@@ -205,7 +206,7 @@ static struct zfcp_erp_action *zfcp_erp_
 		erp_action = &adapter->erp_action;
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING))
-			status = ZFCP_STATUS_ERP_CLOSE_ONLY;
+			act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
 		break;
 
 	default:
@@ -217,14 +218,15 @@ static struct zfcp_erp_action *zfcp_erp_
 	erp_action->port = port;
 	erp_action->unit = unit;
 	erp_action->action = need;
-	erp_action->status = status;
+	erp_action->status = act_status;
 
 	return erp_action;
 }
 
 static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
 				   struct zfcp_port *port,
-				   struct zfcp_unit *unit, char *id, void *ref)
+				   struct zfcp_unit *unit, char *id, void *ref,
+				   u32 act_status)
 {
 	int retval = 1, need;
 	struct zfcp_erp_action *act = NULL;
@@ -236,10 +238,10 @@ static int zfcp_erp_action_enqueue(int w
 	if (!need)
 		goto out;
 
-	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
-	act = zfcp_erp_setup_act(need, adapter, port, unit);
+	act = zfcp_erp_setup_act(need, act_status, adapter, port, unit);
 	if (!act)
 		goto out;
+	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
 	++adapter->erp_total_count;
 	list_add_tail(&act->list, &adapter->erp_ready_head);
 	wake_up(&adapter->erp_ready_wq);
@@ -262,7 +264,7 @@ static int _zfcp_erp_adapter_reopen(stru
 		return -EIO;
 	}
 	return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
-				       adapter, NULL, NULL, id, ref);
+				       adapter, NULL, NULL, id, ref, 0);
 }
 
 /**
@@ -285,7 +287,7 @@ void zfcp_erp_adapter_reopen(struct zfcp
 		zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
 	else
 		zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
-					NULL, NULL, id, ref);
+					NULL, NULL, id, ref, 0);
 	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
@@ -317,20 +319,6 @@ void zfcp_erp_port_shutdown(struct zfcp_
 	zfcp_erp_port_reopen(port, clear | flags, id, ref);
 }
 
-/**
- * zfcp_erp_unit_shutdown - Shutdown unit
- * @unit: Unit to shut down.
- * @clear: Status flags to clear.
- * @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
- */
-void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id,
-			    void *ref)
-{
-	int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
-	zfcp_erp_unit_reopen(unit, clear | flags, id, ref);
-}
-
 static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
 {
 	zfcp_erp_modify_port_status(port, "erpblk1", NULL,
@@ -348,7 +336,7 @@ static void _zfcp_erp_port_forced_reopen
 		return;
 
 	zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
-				port->adapter, port, NULL, id, ref);
+				port->adapter, port, NULL, id, ref, 0);
 }
 
 /**
@@ -381,7 +369,7 @@ static int _zfcp_erp_port_reopen(struct
 	}
 
 	return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
-				       port->adapter, port, NULL, id, ref);
+				       port->adapter, port, NULL, id, ref, 0);
 }
 
 /**
@@ -412,7 +400,7 @@ static void zfcp_erp_unit_block(struct z
 }
 
 static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
-				  void *ref)
+				  void *ref, u32 act_status)
 {
 	struct zfcp_adapter *adapter = unit->port->adapter;
 
@@ -422,7 +410,7 @@ static void _zfcp_erp_unit_reopen(struct
 		return;
 
 	zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,
-				adapter, unit->port, unit, id, ref);
+				adapter, unit->port, unit, id, ref, act_status);
 }
 
 /**
@@ -439,8 +427,45 @@ void zfcp_erp_unit_reopen(struct zfcp_un
 	struct zfcp_adapter *adapter = port->adapter;
 
 	write_lock_irqsave(&adapter->erp_lock, flags);
-	_zfcp_erp_unit_reopen(unit, clear, id, ref);
+	_zfcp_erp_unit_reopen(unit, clear, id, ref, 0);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
+}
+
+/**
+ * zfcp_erp_unit_shutdown - Shutdown unit
+ * @unit: Unit to shut down.
+ * @clear: Status flags to clear.
+ * @id: Id for debug trace event.
+ * @ref: Reference for debug trace event.
+ */
+void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id,
+			    void *ref)
+{
+	int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
+	zfcp_erp_unit_reopen(unit, clear | flags, id, ref);
+}
+
+/**
+ * zfcp_erp_unit_shutdown_wait - Shutdown unit and wait for erp completion
+ * @unit: Unit to shut down.
+ * @id: Id for debug trace event.
+ *
+ * Do not acquire a reference for the unit when creating the ERP
+ * action. It is safe, because this function waits for the ERP to
+ * complete first.
+ */
+void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *unit, char *id)
+{
+	unsigned long flags;
+	struct zfcp_port *port = unit->port;
+	struct zfcp_adapter *adapter = port->adapter;
+	int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
+
+	write_lock_irqsave(&adapter->erp_lock, flags);
+	_zfcp_erp_unit_reopen(unit, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF);
 	write_unlock_irqrestore(&adapter->erp_lock, flags);
+
+	zfcp_erp_wait(adapter);
 }
 
 static int status_change_set(unsigned long mask, atomic_t *status)
@@ -566,7 +591,7 @@ static void _zfcp_erp_unit_reopen_all(st
 
 	read_lock(&port->unit_list_lock);
 	list_for_each_entry(unit, &port->unit_list, list)
-		_zfcp_erp_unit_reopen(unit, clear, id, ref);
+		_zfcp_erp_unit_reopen(unit, clear, id, ref, 0);
 	read_unlock(&port->unit_list_lock);
 }
 
@@ -583,7 +608,7 @@ static void zfcp_erp_strategy_followup_f
 		_zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL);
 		break;
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
-		_zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL);
+		_zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL, 0);
 		break;
 	}
 }
@@ -1143,7 +1168,7 @@ static int zfcp_erp_strategy_statechange
 		if (zfcp_erp_strat_change_det(&unit->status, erp_status)) {
 			_zfcp_erp_unit_reopen(unit,
 					      ZFCP_STATUS_COMMON_ERP_FAILED,
-					      "ersscg3", NULL);
+					      "ersscg3", NULL, 0);
 			return ZFCP_ERP_EXIT;
 		}
 		break;
@@ -1191,7 +1216,8 @@ static void zfcp_erp_action_cleanup(stru
 
 	switch (act->action) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
-		put_device(&unit->dev);
+		if (!(act->status & ZFCP_STATUS_ERP_NO_REF))
+			put_device(&unit->dev);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
drivers/s390/scsi/zfcp_ext.h +1 -0
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_ext.h linux-2.6-patched/drivers/s390/scsi/zfcp_ext.h
@@ -80,6 +80,7 @@ extern void zfcp_erp_modify_unit_status(
 					int);
 extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *);
 extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *);
+extern void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *, char *);
 extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *);
 extern int  zfcp_erp_thread_setup(struct zfcp_adapter *);
 extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
#6 lore raw

PATCH 6/12 zfcp: Use SCSI device data zfcp_scsi_dev instead of zfcp_unit

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

This is the large change to switch from using the data in zfcp_unit to zfcp_scsi_dev. Keeping everything working requires doing the switch in one piece. To ensure that no code keeps using the data in zfcp_unit, this patch also removes the data from zfcp_unit that is now being replaced with zfcp_scsi_dev.

For zfcp, the scsi_device together with zfcp_scsi_dev exist from the call of slave_alloc to the call of slave_destroy. The data in zfcp_scsi_dev is initialized in zfcp_scsi_slave_alloc and the LUN is opened; the final shutdown for the LUN is run from slave_destroy.

Where the scsi_device or zfcp_scsi_dev is needed, the pointer to the scsi_device is passed as function argument and inside the function converted to the pointer to zfcp_scsi_dev; this avoids back and forth conversion betweeen scsi_device and zfcp_scsi_dev.

While changing the function arguments from zfcp_unit to scsi_device, the functions names are renamed form "unit" to "lun". This is to have a seperation between zfcp_scsi_dev/LUN and the zfcp_unit; only code referring to the remaining configuration information in zfcp_unit struct uses "unit".

---

 drivers/s390/scsi/zfcp_dbf.c   |   28 +--
 drivers/s390/scsi/zfcp_dbf.h   |   12 -
 drivers/s390/scsi/zfcp_def.h   |   34 ++-
 drivers/s390/scsi/zfcp_erp.c   |  369 +++++++++++++++++++++--------------------
 drivers/s390/scsi/zfcp_ext.h   |   32 +--
 drivers/s390/scsi/zfcp_fsf.c   |  279 +++++++++++++++----------------
 drivers/s390/scsi/zfcp_scsi.c  |  116 +++++-------
 drivers/s390/scsi/zfcp_sysfs.c |   64 ++++---
 drivers/s390/scsi/zfcp_unit.c  |   11 -
 9 files changed, 480 insertions(+), 465 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +15 -13
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_dbf.c linux-2.6-patched/drivers/s390/scsi/zfcp_dbf.c
@@ -482,7 +482,7 @@ static int zfcp_dbf_rec_view_format(debu
 		zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
 		zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
 		zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
-		zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us);
+		zfcp_dbf_out(&p, "lun_status", "0x%08x", r->u.trigger.ls);
 		break;
 	case ZFCP_REC_DBF_ID_ACTION:
 		zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
@@ -600,19 +600,20 @@ void zfcp_dbf_rec_port(char *id, void *r
 }
 
 /**
- * zfcp_dbf_rec_unit - trace event for unit state change
+ * zfcp_dbf_rec_lun - trace event for LUN state change
  * @id: identifier for trigger of state change
  * @ref: additional reference (e.g. request)
- * @unit: unit
+ * @sdev: SCSI device
  */
-void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit)
+void zfcp_dbf_rec_lun(char *id, void *ref, struct scsi_device *sdev)
 {
-	struct zfcp_port *port = unit->port;
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+	struct zfcp_port *port = zfcp_sdev->port;
 	struct zfcp_dbf *dbf = port->adapter->dbf;
 
-	zfcp_dbf_rec_target(id, ref, dbf, &unit->status,
-				  &unit->erp_counter, port->wwpn, port->d_id,
-				  unit->fcp_lun);
+	zfcp_dbf_rec_target(id, ref, dbf, &zfcp_sdev->status,
+			    &zfcp_sdev->erp_counter, port->wwpn, port->d_id,
+			    zfcp_scsi_dev_lun(sdev));
 }
 
 /**
@@ -624,11 +625,11 @@ void zfcp_dbf_rec_unit(char *id, void *r
  * @action: address of error recovery action struct
  * @adapter: adapter
  * @port: port
- * @unit: unit
+ * @sdev: SCSI device
  */
 void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action,
 			  struct zfcp_adapter *adapter, struct zfcp_port *port,
-			  struct zfcp_unit *unit)
+			  struct scsi_device *sdev)
 {
 	struct zfcp_dbf *dbf = adapter->dbf;
 	struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
@@ -647,9 +648,10 @@ void zfcp_dbf_rec_trigger(char *id2, voi
 		r->u.trigger.ps = atomic_read(&port->status);
 		r->u.trigger.wwpn = port->wwpn;
 	}
-	if (unit)
-		r->u.trigger.us = atomic_read(&unit->status);
-	r->u.trigger.fcp_lun = unit ? unit->fcp_lun : ZFCP_DBF_INVALID_LUN;
+	if (sdev)
+		r->u.trigger.ls = atomic_read(&sdev_to_zfcp(sdev)->status);
+	r->u.trigger.fcp_lun = sdev ? zfcp_scsi_dev_lun(sdev) :
+				      ZFCP_DBF_INVALID_LUN;
 	debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r));
 	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
drivers/s390/scsi/zfcp_dbf.h +6 -6
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_dbf.h linux-2.6-patched/drivers/s390/scsi/zfcp_dbf.h
@@ -60,7 +60,7 @@ struct zfcp_dbf_rec_record_trigger {
 	u8 need;
 	u32 as;
 	u32 ps;
-	u32 us;
+	u32 ls;
 	u64 ref;
 	u64 action;
 	u64 wwpn;
@@ -350,16 +350,16 @@ void zfcp_dbf_scsi_abort(const char *tag
 /**
  * zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset
  * @tag: tag indicating success or failure of reset operation
+ * @scmnd: SCSI command which caused this error recovery
  * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
- * @unit: unit that needs reset
- * @scsi_cmnd: SCSI command which caused this error recovery
  */
 static inline
-void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
-			    struct scsi_cmnd *scsi_cmnd)
+void zfcp_dbf_scsi_devreset(const char *tag, struct scsi_cmnd *scmnd, u8 flag)
 {
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);
+
 	zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
-			    unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
+		      zfcp_sdev->port->adapter->dbf, scmnd, NULL, 0);
 }
 
 #endif /* ZFCP_DBF_H */
drivers/s390/scsi/zfcp_def.h +19 -15
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_def.h linux-2.6-patched/drivers/s390/scsi/zfcp_def.h
@@ -85,8 +85,8 @@ struct zfcp_reqlist;
 #define ZFCP_STATUS_PORT_LINK_TEST		0x00000002
 
 /* logical unit status */
-#define ZFCP_STATUS_UNIT_SHARED			0x00000004
-#define ZFCP_STATUS_UNIT_READONLY		0x00000008
+#define ZFCP_STATUS_LUN_SHARED			0x00000004
+#define ZFCP_STATUS_LUN_READONLY		0x00000008
 
 /* FSF request status (this does not have a common part) */
 #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT	0x00000002
@@ -118,7 +118,7 @@ struct zfcp_erp_action {
 	int action;	              /* requested action code */
 	struct zfcp_adapter *adapter; /* device which should be recovered */
 	struct zfcp_port *port;
-	struct zfcp_unit *unit;
+	struct scsi_device *sdev;
 	u32		status;	      /* recovery status */
 	u32 step;	              /* active step of this erp action */
 	unsigned long		fsf_req_id;
@@ -219,17 +219,23 @@ struct zfcp_port {
 	unsigned int		starget_id;
 };
 
+/**
+ * struct zfcp_unit - LUN configured via zfcp sysfs
+ * @dev: struct device for sysfs representation and reference counting
+ * @list: entry in LUN/unit list per zfcp_port
+ * @port: reference to zfcp_port where this LUN is configured
+ * @fcp_lun: 64 bit LUN value
+ * @scsi_work: for running scsi_scan_target
+ *
+ * This is the representation of a LUN that has been configured for
+ * usage. The main data here is the 64 bit LUN value, data for
+ * running I/O and recovery is in struct zfcp_scsi_dev.
+ */
 struct zfcp_unit {
-	struct device          dev;
-	struct list_head       list;	       /* list of logical units */
-	struct zfcp_port       *port;	       /* remote port of unit */
-	atomic_t	       status;	       /* status of this logical unit */
-	u64		       fcp_lun;	       /* own FCP_LUN */
-	u32		       handle;	       /* handle assigned by FSF */
-        struct scsi_device     *device;        /* scsi device struct pointer */
-	struct zfcp_erp_action erp_action;     /* pending error recovery */
-        atomic_t               erp_counter;
-	struct zfcp_latencies	latencies;
+	struct device		dev;
+	struct list_head	list;
+	struct zfcp_port	*port;
+	u64			fcp_lun;
 	struct work_struct	scsi_work;
 };
 
@@ -288,7 +294,6 @@ static inline u64 zfcp_scsi_dev_lun(stru
  * @erp_action: reference to erp action if request issued on behalf of ERP
  * @pool: reference to memory pool if used for this request
  * @issued: time when request was send (STCK)
- * @unit: reference to unit if this request is a SCSI request
  * @handler: handler which should be called to process response
  */
 struct zfcp_fsf_req {
@@ -306,7 +311,6 @@ struct zfcp_fsf_req {
 	struct zfcp_erp_action	*erp_action;
 	mempool_t		*pool;
 	unsigned long long	issued;
-	struct zfcp_unit	*unit;
 	void			(*handler)(struct zfcp_fsf_req *);
 };
 
drivers/s390/scsi/zfcp_erp.c +194 -175

706 lines not on this page · raw message

drivers/s390/scsi/zfcp_ext.h +15 -17
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_ext.h linux-2.6-patched/drivers/s390/scsi/zfcp_ext.h
@@ -42,10 +42,10 @@ extern void zfcp_dbf_rec_thread(char *,
 extern void zfcp_dbf_rec_thread_lock(char *, struct zfcp_dbf *);
 extern void zfcp_dbf_rec_adapter(char *, void *, struct zfcp_dbf *);
 extern void zfcp_dbf_rec_port(char *, void *, struct zfcp_port *);
-extern void zfcp_dbf_rec_unit(char *, void *, struct zfcp_unit *);
+extern void zfcp_dbf_rec_lun(char *, void *, struct scsi_device *);
 extern void zfcp_dbf_rec_trigger(char *, void *, u8, u8, void *,
 				 struct zfcp_adapter *, struct zfcp_port *,
-				 struct zfcp_unit *);
+				 struct scsi_device *);
 extern void zfcp_dbf_rec_action(char *, struct zfcp_erp_action *);
 extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *,
 				       struct zfcp_dbf *);
@@ -76,20 +76,20 @@ extern void zfcp_erp_port_shutdown(struc
 extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
 					void *);
 extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *);
-extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32,
-					int);
-extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *);
-extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *);
-extern void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *, char *);
-extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *);
+extern void zfcp_erp_modify_lun_status(struct scsi_device *, char *, void *,
+				       u32, int);
+extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *);
+extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *);
+extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *);
+extern void zfcp_erp_lun_failed(struct scsi_device *, char *, void *);
 extern int  zfcp_erp_thread_setup(struct zfcp_adapter *);
 extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
 extern void zfcp_erp_wait(struct zfcp_adapter *);
 extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
 extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *);
-extern void zfcp_erp_unit_boxed(struct zfcp_unit *, char *, void *);
+extern void zfcp_erp_lun_boxed(struct scsi_device *, char *, void *);
 extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *);
-extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *);
+extern void zfcp_erp_lun_access_denied(struct scsi_device *, char *, void *);
 extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
 					    void *);
 extern void zfcp_erp_timeout_handler(unsigned long);
@@ -117,8 +117,8 @@ extern int zfcp_fsf_open_wka_port(struct
 extern int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *);
 extern int zfcp_fsf_close_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
-extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
-extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
+extern int zfcp_fsf_open_lun(struct zfcp_erp_action *);
+extern int zfcp_fsf_close_lun(struct zfcp_erp_action *);
 extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
 extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *,
 					      struct fsf_qtcb_bottom_config *);
@@ -134,12 +134,10 @@ extern int zfcp_fsf_send_ct(struct zfcp_
 			    mempool_t *, unsigned int);
 extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
 			     struct zfcp_fsf_ct_els *, unsigned int);
-extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
-					  struct scsi_cmnd *);
+extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
-extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
-extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
-						       struct zfcp_unit *);
+extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *, u8);
+extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *);
 extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
 
 /* zfcp_qdio.c */
drivers/s390/scsi/zfcp_fsf.c +140 -139

638 lines not on this page · raw message

drivers/s390/scsi/zfcp_scsi.c +53 -63

211 lines not on this page · raw message

drivers/s390/scsi/zfcp_sysfs.c +38 -26

126 lines not on this page · raw message

drivers/s390/scsi/zfcp_unit.c +0 -11
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_unit.c linux-2.6-patched/drivers/s390/scsi/zfcp_unit.c
@@ -134,14 +134,7 @@ int zfcp_unit_add(struct zfcp_port *port
 	unit->fcp_lun = fcp_lun;
 	unit->dev.parent = &port->dev;
 	unit->dev.release = zfcp_unit_release;
-	unit->latencies.write.channel.min = 0xFFFFFFFF;
-	unit->latencies.write.fabric.min = 0xFFFFFFFF;
-	unit->latencies.read.channel.min = 0xFFFFFFFF;
-	unit->latencies.read.fabric.min = 0xFFFFFFFF;
-	unit->latencies.cmd.channel.min = 0xFFFFFFFF;
-	unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
 	INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work);
-	spin_lock_init(&unit->latencies.lock);
 
 	if (dev_set_name(&unit->dev, "0x%016llx",
 			 (unsigned long long) fcp_lun)) {
@@ -165,9 +158,6 @@ int zfcp_unit_add(struct zfcp_port *port
 	list_add_tail(&unit->list, &port->unit_list);
 	write_unlock_irq(&port->unit_list_lock);
 
-	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
-	zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
-	zfcp_erp_wait(unit->port->adapter);
 	zfcp_unit_scsi_scan(unit);
 
 	return 0;
@@ -248,7 +238,6 @@ int zfcp_unit_remove(struct zfcp_port *p
 
 	put_device(&unit->dev);
 
-	zfcp_erp_unit_shutdown(unit, 0, "unrem_1", NULL);
 	zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
 
 	return 0;
#7 lore raw

PATCH 7/12 zfcp: Allow midlayer to scan for LUNs when running in NPIV mode

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Enable the LUN scanning mechanism in the SCSI midlayer:
- Do not set the disable_target_scan bit in the FC transport class.
- Set max_lun to 0xFFFFFFFF to allow the midlayer scan to include the two-level hierachical LUNs (like 0x40XX40XX00000000, but in SCSI midlayer LUN format).
- Set max_id to a high value to allow triggering the SCSI device rescan from sysfs.

When running in NPIV mode, zfcp accepts all LUNs in slave_attach. When running in non-NPIV mode, the list of zfcp_unit structs determines which SCSI devices are allowed on the current system.

---

 drivers/s390/scsi/zfcp_scsi.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/s390/scsi/zfcp_scsi.c +4 -4
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_scsi.c linux-2.6-patched/drivers/s390/scsi/zfcp_scsi.c
@@ -143,7 +143,8 @@ static int zfcp_scsi_slave_alloc(struct
 	unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
 	if (unit)
 		put_device(&unit->dev);
-	else {
+
+	if (!unit && !(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
 		put_device(&port->dev);
 		return -ENXIO;
 	}
@@ -309,8 +310,8 @@ int zfcp_adapter_scsi_register(struct zf
 	}
 
 	/* tell the SCSI stack some characteristics of this adapter */
-	adapter->scsi_host->max_id = 1;
-	adapter->scsi_host->max_lun = 1;
+	adapter->scsi_host->max_id = 511;
+	adapter->scsi_host->max_lun = 0xFFFFFFFF;
 	adapter->scsi_host->max_channel = 0;
 	adapter->scsi_host->unique_id = dev_id.devno;
 	adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */
@@ -687,7 +688,6 @@ struct fc_function_template zfcp_transpo
 	.show_host_port_type = 1,
 	.show_host_speed = 1,
 	.show_host_port_id = 1,
-	.disable_target_scan = 1,
 	.dd_bsg_size = sizeof(struct zfcp_fsf_ct_els),
 };
 
#8 lore raw

PATCH 8/12 zfcp: Change spin_lock_bh to spin_lock_irq to fix lockdep warning

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

With the change to use the data on the SCSI device, iterating through all LUNs/scsi_devices takes the SCSI host_lock. This triggers warnings from the lock dependency checker:

=========================================================
[ INFO: possible irq lock inversion dependency detected ]
2.6.34.1 #97
---------------------------------------------------------
chchp/3224 just changed the state of lock:
(&(shost->host_lock)->rlock){-.-...}, at: [<00000000003a73f4>] __scsi_iterate_devices+0x38/0xbc
but this lock took another, HARDIRQ-unsafe lock in the past:
(&(&qdio->req_q_lock)->rlock){+.-...}

and interrupts could create inverse lock ordering between them.

other info that might help us debug this: [ 24.972394] 2 locks held by chchp/3224:
#0: (&(sch->lock)->rlock){-.-...}, at: [<0000000000401efa>] do_IRQ+0xb2/0x1e4
#1: (&adapter->port_list_lock){.-....}, at: [<0000000000490302>] zfcp_erp_modify_adapter_status+0x9e/0x16c
[...]

=========================================================
[ INFO: possible irq lock inversion dependency detected ]
2.6.34.1 #98
---------------------------------------------------------
chchp/3235 just changed the state of lock:
(&(shost->host_lock)->rlock){-.-...}, at: [<00000000003a73f4>] __scsi_iterate_devices+0x38/0xbc
but this lock took another, HARDIRQ-unsafe lock in the past:
(&(&qdio->stat_lock)->rlock){+.-...}

and interrupts could create inverse lock ordering between them.

other info that might help us debug this:
2 locks held by chchp/3235:
#0: (&(sch->lock)->rlock){-.-...}, at: [<0000000000401efa>] do_IRQ+0xb2/0x1e4
#1: (&adapter->port_list_lock){.-.-..}, at: [<00000000004902f6>] zfcp_erp_modify_adapter_status+0x9e/0x16c
[...]

To stop this warning, change the request queue lock to disable irqs, not only softirq. The changes are required only outside of the critical "send fcp command" path.

---

 drivers/s390/scsi/zfcp_fsf.c  |   72 +++++++++++++++++++++---------------------
 drivers/s390/scsi/zfcp_qdio.c |   18 +++++-----
 2 files changed, 46 insertions(+), 44 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +36 -36
@@ -773,7 +773,7 @@ int zfcp_fsf_status_read(struct zfcp_qdi
 	struct fsf_status_read_buffer *sr_buf;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -807,7 +807,7 @@ failed_buf:
 	zfcp_fsf_req_free(req);
 	zfcp_dbf_hba_fsf_unsol("fail", adapter->dbf, NULL);
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -876,7 +876,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_
 	struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
 	unsigned long old_req_id = (unsigned long) scmnd->host_scribble;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND,
@@ -907,7 +907,7 @@ out_error_free:
 	zfcp_fsf_req_free(req);
 	req = NULL;
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return req;
 }
 
@@ -1046,7 +1046,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_
 	struct zfcp_fsf_req *req;
 	int ret = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1078,7 +1078,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_
 failed_send:
 	zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return ret;
 }
 
@@ -1142,7 +1142,7 @@ int zfcp_fsf_send_els(struct zfcp_adapte
 	struct zfcp_qdio *qdio = adapter->qdio;
 	int ret = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1178,7 +1178,7 @@ int zfcp_fsf_send_els(struct zfcp_adapte
 failed_send:
 	zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return ret;
 }
 
@@ -1188,7 +1188,7 @@ int zfcp_fsf_exchange_config_data(struct
 	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1220,7 +1220,7 @@ int zfcp_fsf_exchange_config_data(struct
 		erp_action->fsf_req_id = 0;
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1230,7 +1230,7 @@ int zfcp_fsf_exchange_config_data_sync(s
 	struct zfcp_fsf_req *req = NULL;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out_unlock;
 
@@ -1256,7 +1256,7 @@ int zfcp_fsf_exchange_config_data_sync(s
 
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	if (!retval)
 		wait_for_completion(&req->completion);
 
@@ -1264,7 +1264,7 @@ int zfcp_fsf_exchange_config_data_sync(s
 	return retval;
 
 out_unlock:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1282,7 +1282,7 @@ int zfcp_fsf_exchange_port_data(struct z
 	if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
 		return -EOPNOTSUPP;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1309,7 +1309,7 @@ int zfcp_fsf_exchange_port_data(struct z
 		erp_action->fsf_req_id = 0;
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1328,7 +1328,7 @@ int zfcp_fsf_exchange_port_data_sync(str
 	if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
 		return -EOPNOTSUPP;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out_unlock;
 
@@ -1348,7 +1348,7 @@ int zfcp_fsf_exchange_port_data_sync(str
 	req->handler = zfcp_fsf_exchange_port_data_handler;
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 
 	if (!retval)
 		wait_for_completion(&req->completion);
@@ -1358,7 +1358,7 @@ int zfcp_fsf_exchange_port_data_sync(str
 	return retval;
 
 out_unlock:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1442,7 +1442,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_a
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1473,7 +1473,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_a
 		put_device(&port->dev);
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1510,7 +1510,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1539,7 +1539,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_
 		erp_action->fsf_req_id = 0;
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1585,7 +1585,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_f
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1610,7 +1610,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_f
 	if (retval)
 		zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1638,7 +1638,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1663,7 +1663,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_
 	if (retval)
 		zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1728,7 +1728,7 @@ int zfcp_fsf_close_physical_port(struct
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1757,7 +1757,7 @@ int zfcp_fsf_close_physical_port(struct
 		erp_action->fsf_req_id = 0;
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1900,7 +1900,7 @@ int zfcp_fsf_open_lun(struct zfcp_erp_ac
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -1933,7 +1933,7 @@ int zfcp_fsf_open_lun(struct zfcp_erp_ac
 		erp_action->fsf_req_id = 0;
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1987,7 +1987,7 @@ int zfcp_fsf_close_lun(struct zfcp_erp_a
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -2017,7 +2017,7 @@ int zfcp_fsf_close_lun(struct zfcp_erp_a
 		erp_action->fsf_req_id = 0;
 	}
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -2363,7 +2363,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_m
 		       ZFCP_STATUS_COMMON_UNBLOCKED)))
 		return NULL;
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -2397,7 +2397,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_m
 	zfcp_fsf_req_free(req);
 	req = NULL;
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return req;
 }
 
@@ -2433,7 +2433,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_fi
 		return ERR_PTR(-EINVAL);
 	}
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 
@@ -2460,7 +2460,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_fi
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
 out:
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 
 	if (!retval) {
 		wait_for_completion(&req->completion);
drivers/s390/scsi/zfcp_qdio.c +10 -8
@@ -60,13 +60,11 @@ static inline void zfcp_qdio_account(str
 	unsigned long long now, span;
 	int used;
 
-	spin_lock(&qdio->stat_lock);
 	now = get_clock_monotonic();
 	span = (now - qdio->req_q_time) >> 12;
 	used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free);
 	qdio->req_q_util += used * span;
 	qdio->req_q_time = now;
-	spin_unlock(&qdio->stat_lock);
 }
 
 static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
@@ -84,7 +82,9 @@ static void zfcp_qdio_int_req(struct ccw
 	/* cleanup all SBALs being program-owned now */
 	zfcp_qdio_zero_sbals(qdio->req_q, idx, count);
 
+	spin_lock_irq(&qdio->stat_lock);
 	zfcp_qdio_account(qdio);
+	spin_unlock_irq(&qdio->stat_lock);
 	atomic_add(count, &qdio->req_q_free);
 	wake_up(&qdio->req_q_wq);
 }
@@ -201,11 +201,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_
 
 static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
 {
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	if (atomic_read(&qdio->req_q_free) ||
 	    !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
 		return 1;
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	return 0;
 }
 
@@ -223,7 +223,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio
 {
 	long ret;
 
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 	ret = wait_event_interruptible_timeout(qdio->req_q_wq,
 			       zfcp_qdio_sbal_check(qdio), 5 * HZ);
 
@@ -239,7 +239,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio
 		zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL);
 	}
 
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	return -EIO;
 }
 
@@ -254,7 +254,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdi
 	int retval;
 	u8 sbal_number = q_req->sbal_number;
 
+	spin_lock(&qdio->stat_lock);
 	zfcp_qdio_account(qdio);
+	spin_unlock(&qdio->stat_lock);
 
 	retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
 			 q_req->sbal_first, sbal_number);
@@ -328,9 +330,9 @@ void zfcp_qdio_close(struct zfcp_qdio *q
 		return;
 
 	/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
-	spin_lock_bh(&qdio->req_q_lock);
+	spin_lock_irq(&qdio->req_q_lock);
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-	spin_unlock_bh(&qdio->req_q_lock);
+	spin_unlock_irq(&qdio->req_q_lock);
 
 	wake_up(&qdio->req_q_wq);
 
#9 lore raw

PATCH 9/12 zfcp: Reorder FCP I/O and task management handler functions

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Instead of calling the same handler for both, I/O and task management commands, use different handlers that call a function for the common part.

---

 drivers/s390/scsi/zfcp_fsf.c |  147 +++++++++++++++++++++----------------------
 1 file changed, 72 insertions(+), 75 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +72 -75
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_fsf.c linux-2.6-patched/drivers/s390/scsi/zfcp_fsf.c
@@ -2080,73 +2080,7 @@ static void zfcp_fsf_req_trace(struct zf
 			    sizeof(blktrc));
 }
 
-static void zfcp_fsf_send_fcp_command_task_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;
-	}
-
-	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;
-	}
-	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
-	zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
-
-skip_fsfstatus:
-	zfcp_fsf_req_trace(req, scpnt);
-	zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
-
-	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);
-}
-
-static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req)
-{
-	struct fcp_resp_with_ext *fcp_rsp;
-	struct fcp_resp_rsp_info *rsp_info;
-
-	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
-	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;
-}
-
-
-static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
+static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
 {
 	struct scsi_cmnd *scmnd = req->data;
 	struct scsi_device *sdev = scmnd->device;
@@ -2154,7 +2088,7 @@ static void zfcp_fsf_send_fcp_command_ha
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
 	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
-		goto skip_fsfstatus;
+		return;
 
 	switch (header->fsf_status) {
 	case FSF_HANDLE_MISMATCH:
@@ -2211,12 +2145,60 @@ static void zfcp_fsf_send_fcp_command_ha
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	}
-skip_fsfstatus:
-	if (req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
-		zfcp_fsf_send_fcp_ctm_handler(req);
-	else {
-		zfcp_fsf_send_fcp_command_task_handler(req);
+}
+
+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;
+
+	zfcp_fsf_fcp_handler_common(req);
+
+	read_lock_irqsave(&req->adapter->abort_lock, flags);
+
+	scpnt = req->data;
+	if (unlikely(!scpnt)) {
+		read_unlock_irqrestore(&req->adapter->abort_lock, flags);
+		return;
 	}
+
+	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;
+	}
+	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
+	zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
+
+skip_fsfstatus:
+	zfcp_fsf_req_trace(req, scpnt);
+	zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
+
+	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);
 }
 
 static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir)
@@ -2299,7 +2281,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *
 	io = &req->qtcb->bottom.io;
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
 	req->data = scsi_cmnd;
-	req->handler = zfcp_fsf_send_fcp_command_handler;
+	req->handler = zfcp_fsf_fcp_cmnd_handler;
 	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
 	req->qtcb->header.port_handle = zfcp_sdev->port->handle;
 	io->service_class = FSF_CLASS_3;
@@ -2345,6 +2327,21 @@ out:
 	return retval;
 }
 
+static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
+{
+	struct fcp_resp_with_ext *fcp_rsp;
+	struct fcp_resp_rsp_info *rsp_info;
+
+	zfcp_fsf_fcp_handler_common(req);
+
+	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
+	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;
+}
+
 /**
  * zfcp_fsf_fcp_task_mgmt - send SCSI task management command
  * @scmnd: SCSI command to send the task management command for
@@ -2378,7 +2375,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_m
 
 	req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT;
 	req->data = scmnd;
-	req->handler = zfcp_fsf_send_fcp_command_handler;
+	req->handler = zfcp_fsf_fcp_task_mgmt_handler;
 	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
 	req->qtcb->header.port_handle = zfcp_sdev->port->handle;
 	req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
#10 lore raw

PATCH 10/12 zfcp: Move ACL/CFDC code to zfcp_cfdc.c

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

Move the code evaluating the ACL/CFDC specific errors to the file zfcp_cfdc.c. With this change, all code related to the old access control feature is kept in one file, not split across zfcp_erp.c and zfcp_fsf.c.

---

 drivers/s390/scsi/zfcp_cfdc.c |  186 +++++++++++++++++++++++++++++++++++++++++-
 drivers/s390/scsi/zfcp_erp.c  |   82 ------------------
 drivers/s390/scsi/zfcp_ext.h  |   12 +-
 drivers/s390/scsi/zfcp_fsf.c  |  129 +++--------------------------
 4 files changed, 207 insertions(+), 202 deletions(-)
drivers/s390/scsi/zfcp_cfdc.c +184 -2
@@ -2,9 +2,10 @@
  * zfcp device driver
  *
  * Userspace interface for accessing the
- * Access Control Lists / Control File Data Channel
+ * Access Control Lists / Control File Data Channel;
+ * handling of response code and states for ports and LUNs.
  *
- * Copyright IBM Corporation 2008, 2009
+ * Copyright IBM Corporation 2008, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -260,3 +261,184 @@ struct miscdevice zfcp_cfdc_misc = {
 	.name = "zfcp_cfdc",
 	.fops = &zfcp_cfdc_fops,
 };
+
+/**
+ * zfcp_cfdc_adapter_access_changed - Process change in adapter ACT
+ * @adapter: Adapter where the Access Control Table (ACT) changed
+ *
+ * After a change in the adapter ACT, check if access to any
+ * previously denied resources is now possible.
+ */
+void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
+{
+	unsigned long flags;
+	struct zfcp_port *port;
+	struct scsi_device *sdev;
+	struct zfcp_scsi_dev *zfcp_sdev;
+	int status;
+
+	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+		return;
+
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list) {
+		status = atomic_read(&port->status);
+		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
+		    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
+			zfcp_erp_port_reopen(port,
+					     ZFCP_STATUS_COMMON_ERP_FAILED,
+					     "cfaac_1", NULL);
+	}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
+
+	shost_for_each_device(sdev, port->adapter->scsi_host) {
+		zfcp_sdev = sdev_to_zfcp(sdev);
+		status = atomic_read(&zfcp_sdev->status);
+		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
+		    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
+			zfcp_erp_lun_reopen(sdev,
+					    ZFCP_STATUS_COMMON_ERP_FAILED,
+					    "cfaac_2", NULL);
+	}
+}
+
+static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table)
+{
+	u16 subtable = table >> 16;
+	u16 rule = table & 0xffff;
+	const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" };
+
+	if (subtable && subtable < ARRAY_SIZE(act_type))
+		dev_warn(&adapter->ccw_device->dev,
+			 "Access denied according to ACT rule type %s, "
+			 "rule %d\n", act_type[subtable], rule);
+}
+
+/**
+ * zfcp_cfdc_port_denied - Process "access denied" for port
+ * @port: The port where the acces has been denied
+ * @qual: The FSF status qualifier for the access denied FSF status
+ */
+void zfcp_cfdc_port_denied(struct zfcp_port *port,
+			   union fsf_status_qual *qual)
+{
+	dev_warn(&port->adapter->ccw_device->dev,
+		 "Access denied to port 0x%016Lx\n",
+		 (unsigned long long)port->wwpn);
+
+	zfcp_act_eval_err(port->adapter, qual->halfword[0]);
+	zfcp_act_eval_err(port->adapter, qual->halfword[1]);
+	zfcp_erp_modify_port_status(port, "cfadp_1", NULL,
+				    ZFCP_STATUS_COMMON_ERP_FAILED |
+				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+}
+
+/**
+ * zfcp_cfdc_lun_denied - Process "access denied" for LUN
+ * @sdev: The SCSI device / LUN where the access has been denied
+ * @qual: The FSF status qualifier for the access denied FSF status
+ */
+void zfcp_cfdc_lun_denied(struct scsi_device *sdev,
+			  union fsf_status_qual *qual)
+{
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+
+	dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
+		 "Access denied to LUN 0x%016Lx on port 0x%016Lx\n",
+		 zfcp_scsi_dev_lun(sdev),
+		 (unsigned long long)zfcp_sdev->port->wwpn);
+	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]);
+	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]);
+	zfcp_erp_modify_lun_status(sdev, "cfadl_1", NULL,
+				   ZFCP_STATUS_COMMON_ERP_FAILED |
+				   ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+
+	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
+	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
+}
+
+/**
+ * zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status
+ * @sdev: The LUN / SCSI device where sharing violation occurred
+ * @qual: The FSF status qualifier from the LUN sharing violation
+ */
+void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev,
+			      union fsf_status_qual *qual)
+{
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+
+	if (qual->word[0])
+		dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
+			 "LUN 0x%Lx on port 0x%Lx is already in "
+			 "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);
+	else
+		zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]);
+
+	zfcp_erp_modify_lun_status(sdev, "fsosh_3", NULL,
+				   ZFCP_STATUS_COMMON_ERP_FAILED |
+				   ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
+	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
+}
+
+/**
+ * zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun"
+ * @sdev: The SCSI device / LUN where to evaluate the status
+ * @bottom: The qtcb bottom with the status from the "open lun"
+ *
+ * Returns: 0 if LUN is usable, -EACCES if the access control table
+ *          reports an unsupported configuration.
+ */
+int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
+			    struct fsf_qtcb_bottom_support *bottom)
+{
+	int shared, rw;
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
+
+	if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) ||
+	    !(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) ||
+	    zfcp_ccw_priv_sch(adapter))
+		return 0;
+
+	shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE);
+	rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);
+
+	if (shared)
+		atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
+
+	if (!rw) {
+		atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
+		dev_info(&adapter->ccw_device->dev, "SCSI device at LUN "
+			 "0x%016Lx on port 0x%016Lx opened read-only\n",
+			 zfcp_scsi_dev_lun(sdev),
+			 (unsigned long long)zfcp_sdev->port->wwpn);
+	}
+
+	if (!shared && !rw) {
+		dev_err(&adapter->ccw_device->dev, "Exclusive read-only access "
+			"not supported (LUN 0x%016Lx, port 0x%016Lx)\n",
+			zfcp_scsi_dev_lun(sdev),
+			(unsigned long long)zfcp_sdev->port->wwpn);
+		zfcp_erp_lun_failed(sdev, "fsosh_5", NULL);
+		zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL);
+		return -EACCES;
+	}
+
+	if (shared && rw) {
+		dev_err(&adapter->ccw_device->dev,
+			"Shared read-write access not supported "
+			"(LUN 0x%016Lx, port 0x%016Lx)\n",
+			zfcp_scsi_dev_lun(sdev),
+			(unsigned long long)zfcp_sdev->port->wwpn);
+		zfcp_erp_lun_failed(sdev, "fsosh_7", NULL);
+		zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL);
+		return -EACCES;
+	}
+
+	return 0;
+}
drivers/s390/scsi/zfcp_erp.c +0 -82

85 lines not on this page · raw message

drivers/s390/scsi/zfcp_ext.h +8 -4
@@ -34,6 +34,14 @@ extern void zfcp_ccw_adapter_put(struct
 
 /* zfcp_cfdc.c */
 extern struct miscdevice zfcp_cfdc_misc;
+extern void zfcp_cfdc_port_denied(struct zfcp_port *, union fsf_status_qual *);
+extern void zfcp_cfdc_lun_denied(struct scsi_device *, union fsf_status_qual *);
+extern void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *,
+				     union fsf_status_qual *);
+extern int zfcp_cfdc_open_lun_eval(struct scsi_device *,
+				   struct fsf_qtcb_bottom_support *);
+extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *);
+
 
 /* zfcp_dbf.c */
 extern int zfcp_dbf_adapter_register(struct zfcp_adapter *);
@@ -88,10 +96,6 @@ extern void zfcp_erp_wait(struct zfcp_ad
 extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
 extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *);
 extern void zfcp_erp_lun_boxed(struct scsi_device *, char *, void *);
-extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *);
-extern void zfcp_erp_lun_access_denied(struct scsi_device *, char *, void *);
-extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
-					    void *);
 extern void zfcp_erp_timeout_handler(unsigned long);
 
 /* zfcp_fc.c */
drivers/s390/scsi/zfcp_fsf.c +15 -114

193 lines not on this page · raw message

#11 lore raw

PATCH 11/12 zfcp: Remove duplicated code from zfcp_ccw_set_online

In reply to Christof Schmitt

From: Christof Schmitt <[email protected]>

The steps for setting the zfcp_adapter online are the same in zfcp_ccw_set_online and zfcp_ccw_activate. Remove the code duplication by calling zfcp_ccw_activate from zfcp_ccw_set_online.

---

 drivers/s390/scsi/zfcp_ccw.c |    9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/s390/scsi/zfcp_ccw.c +1 -8
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_ccw.c linux-2.6-patched/drivers/s390/scsi/zfcp_ccw.c
@@ -164,14 +164,7 @@ static int zfcp_ccw_set_online(struct cc
 	BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
 	adapter->req_no = 0;
 
-	zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
-				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
-	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
-				"ccsonl2", NULL);
-	zfcp_erp_wait(adapter);
-
-	flush_work(&adapter->scan_work);
-
+	zfcp_ccw_activate(cdev);
 	zfcp_ccw_adapter_put(adapter);
 	return 0;
 }
#12 lore raw

PATCH 12/12 zfcp: Replace status modifier functions.

In reply to Christof Schmitt

From: Swen Schillig <[email protected]>

Replace the zfcp_modify_<xxx>_status functions and its accompanying wrappers with dedicated status modifier functions. This eases code readability and maintenance.

---

 drivers/s390/scsi/zfcp_ccw.c   |    8 -
 drivers/s390/scsi/zfcp_cfdc.c  |   22 +--
 drivers/s390/scsi/zfcp_def.h   |    5 
 drivers/s390/scsi/zfcp_erp.c   |  258 ++++++++++++++++++-----------------------
 drivers/s390/scsi/zfcp_ext.h   |   17 --
 drivers/s390/scsi/zfcp_fc.c    |    2 
 drivers/s390/scsi/zfcp_fsf.c   |   72 +++++++----
 drivers/s390/scsi/zfcp_scsi.c  |    3 
 drivers/s390/scsi/zfcp_sysfs.c |   10 -
 9 files changed, 189 insertions(+), 208 deletions(-)
drivers/s390/scsi/zfcp_ccw.c +3 -5
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_ccw.c linux-2.6-patched/drivers/s390/scsi/zfcp_ccw.c
@@ -46,8 +46,7 @@ static int zfcp_ccw_activate(struct ccw_
 	if (!adapter)
 		return 0;
 
-	zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL,
-				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 				"ccresu2", NULL);
 	zfcp_erp_wait(adapter);
@@ -217,9 +216,8 @@ static int zfcp_ccw_notify(struct ccw_de
 		break;
 	case CIO_OPER:
 		dev_info(&cdev->dev, "The FCP device is operational again\n");
-		zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
-					       ZFCP_STATUS_COMMON_RUNNING,
-					       ZFCP_SET);
+		zfcp_erp_set_adapter_status(adapter,
+					    ZFCP_STATUS_COMMON_RUNNING);
 		zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 					"ccnoti4", NULL);
 		break;
drivers/s390/scsi/zfcp_cfdc.c +11 -11
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_cfdc.c linux-2.6-patched/drivers/s390/scsi/zfcp_cfdc.c
@@ -328,9 +328,9 @@ void zfcp_cfdc_port_denied(struct zfcp_p
 
 	zfcp_act_eval_err(port->adapter, qual->halfword[0]);
 	zfcp_act_eval_err(port->adapter, qual->halfword[1]);
-	zfcp_erp_modify_port_status(port, "cfadp_1", NULL,
-				    ZFCP_STATUS_COMMON_ERP_FAILED |
-				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+	zfcp_erp_set_port_status(port,
+				 ZFCP_STATUS_COMMON_ERP_FAILED |
+				 ZFCP_STATUS_COMMON_ACCESS_DENIED);
 }
 
 /**
@@ -349,9 +349,9 @@ void zfcp_cfdc_lun_denied(struct scsi_de
 		 (unsigned long long)zfcp_sdev->port->wwpn);
 	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]);
 	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]);
-	zfcp_erp_modify_lun_status(sdev, "cfadl_1", NULL,
-				   ZFCP_STATUS_COMMON_ERP_FAILED |
-				   ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+	zfcp_erp_set_lun_status(sdev,
+				ZFCP_STATUS_COMMON_ERP_FAILED |
+				ZFCP_STATUS_COMMON_ACCESS_DENIED);
 
 	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
 	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
@@ -378,9 +378,9 @@ void zfcp_cfdc_lun_shrng_vltn(struct scs
 	else
 		zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]);
 
-	zfcp_erp_modify_lun_status(sdev, "fsosh_3", NULL,
-				   ZFCP_STATUS_COMMON_ERP_FAILED |
-				   ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+	zfcp_erp_set_lun_status(sdev,
+				ZFCP_STATUS_COMMON_ERP_FAILED |
+				ZFCP_STATUS_COMMON_ACCESS_DENIED);
 	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
 	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
 }
@@ -424,7 +424,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_
 			"not supported (LUN 0x%016Lx, port 0x%016Lx)\n",
 			zfcp_scsi_dev_lun(sdev),
 			(unsigned long long)zfcp_sdev->port->wwpn);
-		zfcp_erp_lun_failed(sdev, "fsosh_5", NULL);
+		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
 		zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL);
 		return -EACCES;
 	}
@@ -435,7 +435,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_
 			"(LUN 0x%016Lx, port 0x%016Lx)\n",
 			zfcp_scsi_dev_lun(sdev),
 			(unsigned long long)zfcp_sdev->port->wwpn);
-		zfcp_erp_lun_failed(sdev, "fsosh_7", NULL);
+		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
 		zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL);
 		return -EACCES;
 	}
drivers/s390/scsi/zfcp_def.h +0 -5
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_def.h linux-2.6-patched/drivers/s390/scsi/zfcp_def.h
@@ -325,9 +325,4 @@ struct zfcp_data {
 	struct kmem_cache	*adisc_cache;
 };
 
-/********************** ZFCP SPECIFIC DEFINES ********************************/
-
-#define ZFCP_SET                0x00000100
-#define ZFCP_CLEAR              0x00000200
-
 #endif /* ZFCP_DEF_H */
drivers/s390/scsi/zfcp_erp.c +119 -139

389 lines not on this page · raw message

drivers/s390/scsi/zfcp_ext.h +6 -11
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_ext.h linux-2.6-patched/drivers/s390/scsi/zfcp_ext.h
@@ -71,31 +71,26 @@ extern void _zfcp_dbf_scsi(const char *,
 			   unsigned long);
 
 /* zfcp_erp.c */
-extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *,
-					   void *, u32, int);
+extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
+extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
 extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *);
 extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *,
 				      void *);
-extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, char *, void *);
-extern void zfcp_erp_modify_port_status(struct zfcp_port *, char *, void *, u32,
-					int);
+extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
+extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32);
 extern int  zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *);
 extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *);
 extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
 					void *);
-extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *);
-extern void zfcp_erp_modify_lun_status(struct scsi_device *, char *, void *,
-				       u32, int);
+extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
+extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32);
 extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *);
 extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *);
 extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *);
-extern void zfcp_erp_lun_failed(struct scsi_device *, char *, void *);
 extern int  zfcp_erp_thread_setup(struct zfcp_adapter *);
 extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
 extern void zfcp_erp_wait(struct zfcp_adapter *);
 extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
-extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *);
-extern void zfcp_erp_lun_boxed(struct scsi_device *, char *, void *);
 extern void zfcp_erp_timeout_handler(unsigned long);
 
 /* zfcp_fc.c */
drivers/s390/scsi/zfcp_fc.c +1 -1
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_fc.c linux-2.6-patched/drivers/s390/scsi/zfcp_fc.c
@@ -365,7 +365,7 @@ void zfcp_fc_port_did_lookup(struct work
 	}
 
 	if (!port->d_id) {
-		zfcp_erp_port_failed(port, "fcgpn_2", NULL);
+		zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED);
 		goto out;
 	}
 
drivers/s390/scsi/zfcp_fsf.c +45 -27

177 lines not on this page · raw message

drivers/s390/scsi/zfcp_scsi.c +1 -2
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_scsi.c linux-2.6-patched/drivers/s390/scsi/zfcp_scsi.c
@@ -158,8 +158,7 @@ static int zfcp_scsi_slave_alloc(struct
 	zfcp_sdev->latencies.cmd.fabric.min = 0xFFFFFFFF;
 	spin_lock_init(&zfcp_sdev->latencies.lock);
 
-	zfcp_erp_modify_lun_status(sdev, "scsla_0", NULL,
-				   ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
 	zfcp_erp_lun_reopen(sdev, 0, "scsla_1", NULL);
 	zfcp_erp_wait(port->adapter);
 
drivers/s390/scsi/zfcp_sysfs.c +3 -7
diff -urpN linux-2.6/drivers/s390/scsi/zfcp_sysfs.c linux-2.6-patched/drivers/s390/scsi/zfcp_sysfs.c
@@ -104,8 +104,7 @@ static ssize_t zfcp_sysfs_port_failed_st
 	if (strict_strtoul(buf, 0, &val) || val != 0)
 		return -EINVAL;
 
-	zfcp_erp_modify_port_status(port, "sypfai1", NULL,
-				    ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING);
 	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2",
 			     NULL);
 	zfcp_erp_wait(port->adapter);
@@ -147,9 +146,7 @@ static ssize_t zfcp_sysfs_unit_failed_st
 
 	sdev = zfcp_unit_sdev(unit);
 	if (sdev) {
-		zfcp_erp_modify_lun_status(sdev, "syufai1", NULL,
-					   ZFCP_STATUS_COMMON_RUNNING,
-					   ZFCP_SET);
+		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
 		zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
 				    "syufai2", NULL);
 		zfcp_erp_wait(unit->port->adapter);
@@ -199,8 +196,7 @@ static ssize_t zfcp_sysfs_adapter_failed
 		goto out;
 	}
 
-	zfcp_erp_modify_adapter_status(adapter, "syafai1", NULL,
-				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 				"syafai2", NULL);
 	zfcp_erp_wait(adapter);