aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2008-11-04 10:35:08 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-11-05 12:46:39 -0500
commit3765138ae946e6e29b22bf15a9647c600c232639 (patch)
tree5704fb770db648506bba7ca8e7fa2c887b4998d0 /drivers/s390/scsi/zfcp_fsf.c
parent88f2a977870af655296a682fe2a58c822cd25bb2 (diff)
[SCSI] zfcp: Fix request list handling in error path
Fix the handling of the request list in the error path: - Use irqsave for the lock as in the good path. - Before removing the request, check if it is still in the list, a call to dismiss_all might have changed the list in between. - zfcp_qdio_send does not change the queue counters on failure, trying revert something is wrong, so remove this. Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 5e8517fc8b62..d024442ee128 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -770,7 +770,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
770static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) 770static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
771{ 771{
772 struct zfcp_adapter *adapter = req->adapter; 772 struct zfcp_adapter *adapter = req->adapter;
773 struct zfcp_qdio_queue *req_q = &adapter->req_q;
774 unsigned long flags; 773 unsigned long flags;
775 int idx; 774 int idx;
776 775
@@ -780,19 +779,15 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
780 list_add_tail(&req->list, &adapter->req_list[idx]); 779 list_add_tail(&req->list, &adapter->req_list[idx]);
781 spin_unlock_irqrestore(&adapter->req_list_lock, flags); 780 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
782 781
783 req->qdio_outb_usage = atomic_read(&req_q->count); 782 req->qdio_outb_usage = atomic_read(&adapter->req_q.count);
784 req->issued = get_clock(); 783 req->issued = get_clock();
785 if (zfcp_qdio_send(req)) { 784 if (zfcp_qdio_send(req)) {
786 /* Queues are down..... */
787 del_timer(&req->timer); 785 del_timer(&req->timer);
788 spin_lock(&adapter->req_list_lock); 786 spin_lock_irqsave(&adapter->req_list_lock, flags);
789 zfcp_reqlist_remove(adapter, req); 787 /* lookup request again, list might have changed */
790 spin_unlock(&adapter->req_list_lock); 788 if (zfcp_reqlist_find_safe(adapter, req))
791 /* undo changes in request queue made for this request */ 789 zfcp_reqlist_remove(adapter, req);
792 atomic_add(req->sbal_number, &req_q->count); 790 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
793 req_q->first -= req->sbal_number;
794 req_q->first += QDIO_MAX_BUFFERS_PER_Q;
795 req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
796 zfcp_erp_adapter_reopen(adapter, 0, 116, req); 791 zfcp_erp_adapter_reopen(adapter, 0, 116, req);
797 return -EIO; 792 return -EIO;
798 } 793 }