aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-08-18 09:43:13 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 09:49:16 -0400
commitbd63eaf4b8d783e6033930e377e516169abcadc4 (patch)
treecbb160657a3c6e0366c3d8b69275008f88e43fb9 /drivers/s390
parent55c770fa11d21456e02dc7afb9a37404da9c7b4c (diff)
[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>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_ext.h2
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c100
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c45
3 files changed, 73 insertions, 74 deletions
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 1a66695f11a2..6a3727bdb386 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -133,11 +133,11 @@ extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
133extern int zfcp_fsf_send_els(struct zfcp_send_els *); 133extern int zfcp_fsf_send_els(struct zfcp_send_els *);
134extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, 134extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
135 struct scsi_cmnd *); 135 struct scsi_cmnd *);
136extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *);
137extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); 136extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
138extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8); 137extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
139extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long, 138extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
140 struct zfcp_unit *); 139 struct zfcp_unit *);
140extern void zfcp_fsf_reqid_check(struct zfcp_adapter *, int);
141 141
142/* zfcp_qdio.c */ 142/* zfcp_qdio.c */
143extern int zfcp_qdio_allocate(struct zfcp_adapter *); 143extern int zfcp_qdio_allocate(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index c023db864dc5..7ca2995aaf68 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -122,35 +122,6 @@ void zfcp_fsf_req_free(struct zfcp_fsf_req *req)
122 } 122 }
123} 123}
124 124
125/**
126 * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
127 * @adapter: pointer to struct zfcp_adapter
128 *
129 * Never ever call this without shutting down the adapter first.
130 * Otherwise the adapter would continue using and corrupting s390 storage.
131 * Included BUG_ON() call to ensure this is done.
132 * ERP is supposed to be the only user of this function.
133 */
134void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
135{
136 struct zfcp_fsf_req *req, *tmp;
137 unsigned long flags;
138 LIST_HEAD(remove_queue);
139 unsigned int i;
140
141 BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
142 spin_lock_irqsave(&adapter->req_list_lock, flags);
143 for (i = 0; i < REQUEST_LIST_SIZE; i++)
144 list_splice_init(&adapter->req_list[i], &remove_queue);
145 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
146
147 list_for_each_entry_safe(req, tmp, &remove_queue, list) {
148 list_del(&req->list);
149 req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
150 zfcp_fsf_req_complete(req);
151 }
152}
153
154static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) 125static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
155{ 126{
156 struct fsf_status_read_buffer *sr_buf = req->data; 127 struct fsf_status_read_buffer *sr_buf = req->data;
@@ -459,7 +430,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
459 * is called to process the completion status and trigger further 430 * is called to process the completion status and trigger further
460 * events related to the FSF request. 431 * events related to the FSF request.
461 */ 432 */
462void zfcp_fsf_req_complete(struct zfcp_fsf_req *req) 433static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
463{ 434{
464 if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) { 435 if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
465 zfcp_fsf_status_read_handler(req); 436 zfcp_fsf_status_read_handler(req);
@@ -492,6 +463,35 @@ void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
492 wake_up(&req->completion_wq); 463 wake_up(&req->completion_wq);
493} 464}
494 465
466/**
467 * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
468 * @adapter: pointer to struct zfcp_adapter
469 *
470 * Never ever call this without shutting down the adapter first.
471 * Otherwise the adapter would continue using and corrupting s390 storage.
472 * Included BUG_ON() call to ensure this is done.
473 * ERP is supposed to be the only user of this function.
474 */
475void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
476{
477 struct zfcp_fsf_req *req, *tmp;
478 unsigned long flags;
479 LIST_HEAD(remove_queue);
480 unsigned int i;
481
482 BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
483 spin_lock_irqsave(&adapter->req_list_lock, flags);
484 for (i = 0; i < REQUEST_LIST_SIZE; i++)
485 list_splice_init(&adapter->req_list[i], &remove_queue);
486 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
487
488 list_for_each_entry_safe(req, tmp, &remove_queue, list) {
489 list_del(&req->list);
490 req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
491 zfcp_fsf_req_complete(req);
492 }
493}
494
495static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) 495static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
496{ 496{
497 struct fsf_qtcb_bottom_config *bottom; 497 struct fsf_qtcb_bottom_config *bottom;
@@ -2578,3 +2578,43 @@ out:
2578 } 2578 }
2579 return ERR_PTR(retval); 2579 return ERR_PTR(retval);
2580} 2580}
2581
2582/**
2583 * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
2584 * @adapter: pointer to struct zfcp_adapter
2585 * @sbal_idx: response queue index of SBAL to be processed
2586 */
2587void zfcp_fsf_reqid_check(struct zfcp_adapter *adapter, int sbal_idx)
2588{
2589 struct qdio_buffer *sbal = adapter->resp_q.sbal[sbal_idx];
2590 struct qdio_buffer_element *sbale;
2591 struct zfcp_fsf_req *fsf_req;
2592 unsigned long flags, req_id;
2593 int idx;
2594
2595 for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
2596
2597 sbale = &sbal->element[idx];
2598 req_id = (unsigned long) sbale->addr;
2599 spin_lock_irqsave(&adapter->req_list_lock, flags);
2600 fsf_req = zfcp_reqlist_find(adapter, req_id);
2601
2602 if (!fsf_req)
2603 /*
2604 * Unknown request means that we have potentially memory
2605 * corruption and must stop the machine immediately.
2606 */
2607 panic("error: unknown req_id (%lx) on adapter %s.\n",
2608 req_id, dev_name(&adapter->ccw_device->dev));
2609
2610 list_del(&fsf_req->list);
2611 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
2612
2613 fsf_req->sbal_response = sbal_idx;
2614 fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
2615 zfcp_fsf_req_complete(fsf_req);
2616
2617 if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
2618 break;
2619 }
2620}
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index e0a215309df0..2e9b3a9cebd9 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -112,31 +112,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
112 wake_up(&adapter->request_wq); 112 wake_up(&adapter->request_wq);
113} 113}
114 114
115static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
116 unsigned long req_id, int sbal_idx)
117{
118 struct zfcp_fsf_req *fsf_req;
119 unsigned long flags;
120
121 spin_lock_irqsave(&adapter->req_list_lock, flags);
122 fsf_req = zfcp_reqlist_find(adapter, req_id);
123
124 if (!fsf_req)
125 /*
126 * Unknown request means that we have potentially memory
127 * corruption and must stop the machine immediatly.
128 */
129 panic("error: unknown request id (%lx) on adapter %s.\n",
130 req_id, dev_name(&adapter->ccw_device->dev));
131
132 zfcp_reqlist_remove(adapter, fsf_req);
133 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
134
135 fsf_req->sbal_response = sbal_idx;
136 fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
137 zfcp_fsf_req_complete(fsf_req);
138}
139
140static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed) 115static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed)
141{ 116{
142 struct zfcp_qdio_queue *queue = &adapter->resp_q; 117 struct zfcp_qdio_queue *queue = &adapter->resp_q;
@@ -163,9 +138,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
163 unsigned long parm) 138 unsigned long parm)
164{ 139{
165 struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; 140 struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm;
166 struct zfcp_qdio_queue *queue = &adapter->resp_q; 141 int sbal_idx, sbal_no;
167 struct qdio_buffer_element *sbale;
168 int sbal_idx, sbale_idx, sbal_no;
169 142
170 if (unlikely(qdio_err)) { 143 if (unlikely(qdio_err)) {
171 zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); 144 zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
@@ -179,22 +152,8 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
179 */ 152 */
180 for (sbal_no = 0; sbal_no < count; sbal_no++) { 153 for (sbal_no = 0; sbal_no < count; sbal_no++) {
181 sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q; 154 sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q;
182
183 /* go through all SBALEs of SBAL */ 155 /* go through all SBALEs of SBAL */
184 for (sbale_idx = 0; sbale_idx < QDIO_MAX_ELEMENTS_PER_BUFFER; 156 zfcp_fsf_reqid_check(adapter, sbal_idx);
185 sbale_idx++) {
186 sbale = zfcp_qdio_sbale(queue, sbal_idx, sbale_idx);
187 zfcp_qdio_reqid_check(adapter,
188 (unsigned long) sbale->addr,
189 sbal_idx);
190 if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
191 break;
192 };
193
194 if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY)))
195 dev_warn(&adapter->ccw_device->dev,
196 "A QDIO protocol error occurred, "
197 "operations continue\n");
198 } 157 }
199 158
200 /* 159 /*