[SCSI] zfcp: Replace global config_lock with local list locks

The global config_lock was used to protect the configuration organized
in independent lists. It is not necessary to have a lock on driver
level for this purpose.  This patch replaces the global config_lock
with a set of local list locks.

Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index d310008..8430b51 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -153,15 +153,14 @@
 		goto out;
 	}
 
-	write_lock_irq(&zfcp_data.config_lock);
 	port = zfcp_get_port_by_wwpn(adapter, wwpn);
-	if (port && (atomic_read(&port->refcount) == 0)) {
-		zfcp_port_get(port);
+	if (port && (atomic_read(&port->refcount) == 1)) {
 		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
+		write_lock_irq(&adapter->port_list_lock);
 		list_move(&port->list, &port_remove_lh);
+		write_unlock_irq(&adapter->port_list_lock);
 	} else
 		port = NULL;
-	write_unlock_irq(&zfcp_data.config_lock);
 
 	if (!port) {
 		retval = -ENXIO;
@@ -253,35 +252,28 @@
 		goto out;
 	}
 
-	write_lock_irq(&zfcp_data.config_lock);
 	unit = zfcp_get_unit_by_lun(port, fcp_lun);
-	if (unit) {
-		write_unlock_irq(&zfcp_data.config_lock);
-		/* wait for possible timeout during SCSI probe */
-		flush_work(&unit->scsi_work);
-		write_lock_irq(&zfcp_data.config_lock);
-
-		if (atomic_read(&unit->refcount) == 0) {
-			zfcp_unit_get(unit);
-			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
-					&unit->status);
-			list_move(&unit->list, &unit_remove_lh);
-		} else {
-			unit = NULL;
-		}
-	}
-
-	write_unlock_irq(&zfcp_data.config_lock);
-
 	if (!unit) {
-		retval = -ENXIO;
+		retval = -EINVAL;
 		goto out;
 	}
 
-	zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
-	zfcp_erp_wait(unit->port->adapter);
-	zfcp_unit_put(unit);
-	zfcp_unit_dequeue(unit);
+	/* wait for possible timeout during SCSI probe */
+	flush_work(&unit->scsi_work);
+
+	if (atomic_read(&unit->refcount) == 1) {
+		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
+
+		write_lock_irq(&port->unit_list_lock);
+		list_move(&unit->list, &unit_remove_lh);
+		write_unlock_irq(&port->unit_list_lock);
+
+		zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
+		zfcp_erp_wait(unit->port->adapter);
+		zfcp_unit_put(unit);
+		zfcp_unit_dequeue(unit);
+	} else
+		zfcp_unit_put(unit);
 out:
 	mutex_unlock(&zfcp_data.config_mutex);
 	return retval ? retval : (ssize_t) count;