[SCSI] zfcp: fix layering oddities between zfcp_fsf and zfcp_qdio
There is no need for the QDIO layer to have knowledge or do things
wich are done better by the FSF layer and vice versa. Straighten a
few things to improve vividness.
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_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index c023db8..7ca2995 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -122,35 +122,6 @@
}
}
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
- * @adapter: pointer to struct zfcp_adapter
- *
- * Never ever call this without shutting down the adapter first.
- * Otherwise the adapter would continue using and corrupting s390 storage.
- * Included BUG_ON() call to ensure this is done.
- * ERP is supposed to be the only user of this function.
- */
-void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
-{
- struct zfcp_fsf_req *req, *tmp;
- unsigned long flags;
- LIST_HEAD(remove_queue);
- unsigned int i;
-
- BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
- spin_lock_irqsave(&adapter->req_list_lock, flags);
- 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);
-
- list_for_each_entry_safe(req, tmp, &remove_queue, list) {
- list_del(&req->list);
- req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
- zfcp_fsf_req_complete(req);
- }
-}
-
static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
{
struct fsf_status_read_buffer *sr_buf = req->data;
@@ -459,7 +430,7 @@
* is called to process the completion status and trigger further
* events related to the FSF request.
*/
-void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
+static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
{
if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
zfcp_fsf_status_read_handler(req);
@@ -492,6 +463,35 @@
wake_up(&req->completion_wq);
}
+/**
+ * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
+ * @adapter: pointer to struct zfcp_adapter
+ *
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
+ */
+void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
+{
+ struct zfcp_fsf_req *req, *tmp;
+ unsigned long flags;
+ LIST_HEAD(remove_queue);
+ unsigned int i;
+
+ BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
+ spin_lock_irqsave(&adapter->req_list_lock, flags);
+ 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);
+
+ list_for_each_entry_safe(req, tmp, &remove_queue, list) {
+ list_del(&req->list);
+ req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+ zfcp_fsf_req_complete(req);
+ }
+}
+
static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
{
struct fsf_qtcb_bottom_config *bottom;
@@ -2578,3 +2578,43 @@
}
return ERR_PTR(retval);
}
+
+/**
+ * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
+ * @adapter: pointer to struct zfcp_adapter
+ * @sbal_idx: response queue index of SBAL to be processed
+ */
+void zfcp_fsf_reqid_check(struct zfcp_adapter *adapter, int sbal_idx)
+{
+ struct qdio_buffer *sbal = adapter->resp_q.sbal[sbal_idx];
+ struct qdio_buffer_element *sbale;
+ struct zfcp_fsf_req *fsf_req;
+ unsigned long flags, req_id;
+ int idx;
+
+ for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
+
+ sbale = &sbal->element[idx];
+ req_id = (unsigned long) sbale->addr;
+ spin_lock_irqsave(&adapter->req_list_lock, flags);
+ fsf_req = zfcp_reqlist_find(adapter, req_id);
+
+ if (!fsf_req)
+ /*
+ * Unknown request means that we have potentially memory
+ * corruption and must stop the machine immediately.
+ */
+ panic("error: unknown req_id (%lx) on adapter %s.\n",
+ req_id, dev_name(&adapter->ccw_device->dev));
+
+ list_del(&fsf_req->list);
+ spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+
+ fsf_req->sbal_response = sbal_idx;
+ fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
+ zfcp_fsf_req_complete(fsf_req);
+
+ if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
+ break;
+ }
+}