summaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c1
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c5
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c40
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c3
4 files changed, 18 insertions, 31 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index ddff40c4212..821cde65e36 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -1127,6 +1127,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
int retval = 0;
unsigned long flags;
+ zfcp_adapter_scsi_unregister(adapter);
device_unregister(&adapter->generic_services);
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 81680efa172..1c8f71a5985 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -189,9 +189,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
* @ccw_device: pointer to belonging ccw device
*
* This function gets called by the common i/o layer and sets an adapter
- * into state offline. Setting an fcp device offline means that it will be
- * unregistered from the SCSI stack and that the adapter will be shut down
- * asynchronously.
+ * into state offline.
*/
static int
zfcp_ccw_set_offline(struct ccw_device *ccw_device)
@@ -202,7 +200,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
adapter = dev_get_drvdata(&ccw_device->dev);
zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter);
- zfcp_adapter_scsi_unregister(adapter);
zfcp_erp_thread_kill(adapter);
zfcp_adapter_debug_unregister(adapter);
up(&zfcp_data.config_sema);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index a8b02542ac2..0eb31e162b1 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -156,44 +156,30 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
kfree(fsf_req);
}
-/**
- * zfcp_fsf_req_dismiss - dismiss a single fsf request
- */
-static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
- struct zfcp_fsf_req *fsf_req,
- unsigned int counter)
-{
- u64 dbg_tmp[2];
-
- dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
- dbg_tmp[1] = (u64) counter;
- debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
- list_del(&fsf_req->list);
- fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
- zfcp_fsf_req_complete(fsf_req);
-}
-
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
+/*
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
*/
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
- struct zfcp_fsf_req *request, *tmp;
+ struct zfcp_fsf_req *fsf_req, *tmp;
unsigned long flags;
LIST_HEAD(remove_queue);
- unsigned int i, counter;
+ unsigned int i;
+ BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
spin_lock_irqsave(&adapter->req_list_lock, flags);
atomic_set(&adapter->reqs_active, 0);
- for (i=0; i<REQUEST_LIST_SIZE; i++)
+ for (i = 0; i < REQUEST_LIST_SIZE; i++)
list_splice_init(&adapter->req_list[i], &remove_queue);
-
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
- counter = 0;
- list_for_each_entry_safe(request, tmp, &remove_queue, list) {
- zfcp_fsf_req_dismiss(adapter, request, counter);
- counter++;
+ list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+ list_del(&fsf_req->list);
+ fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+ zfcp_fsf_req_complete(fsf_req);
}
}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 16e2d64658a..0acf6db0a08 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -569,6 +569,9 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
int retval = 0;
static unsigned int unique_id = 0;
+ if (adapter->scsi_host)
+ goto out;
+
/* register adapter as SCSI host with mid layer of SCSI stack */
adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template,
sizeof (struct zfcp_adapter *));