diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-08-18 09:43:13 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:49:16 -0400 |
commit | bd63eaf4b8d783e6033930e377e516169abcadc4 (patch) | |
tree | cbb160657a3c6e0366c3d8b69275008f88e43fb9 | |
parent | 55c770fa11d21456e02dc7afb9a37404da9c7b4c (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>
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 100 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 45 |
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 *, | |||
133 | extern int zfcp_fsf_send_els(struct zfcp_send_els *); | 133 | extern int zfcp_fsf_send_els(struct zfcp_send_els *); |
134 | extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, | 134 | extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, |
135 | struct scsi_cmnd *); | 135 | struct scsi_cmnd *); |
136 | extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *); | ||
137 | extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); | 136 | extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); |
138 | extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8); | 137 | extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8); |
139 | extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long, | 138 | extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long, |
140 | struct zfcp_unit *); | 139 | struct zfcp_unit *); |
140 | extern void zfcp_fsf_reqid_check(struct zfcp_adapter *, int); | ||
141 | 141 | ||
142 | /* zfcp_qdio.c */ | 142 | /* zfcp_qdio.c */ |
143 | extern int zfcp_qdio_allocate(struct zfcp_adapter *); | 143 | extern 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 | */ | ||
134 | void 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 | |||
154 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) | 125 | static 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 | */ |
462 | void zfcp_fsf_req_complete(struct zfcp_fsf_req *req) | 433 | static 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 | */ | ||
475 | void 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 | |||
495 | static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) | 495 | static 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 | */ | ||
2587 | void 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 | ||
115 | static 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 | |||
140 | static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed) | 115 | static 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 | /* |