diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 3376305609f9d02aabf86fd5c4e54c3c3267de82..878b8f86ddc7bd013308e54968e44585f19c3b80 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -644,38 +644,38 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) } } -static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter) +static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter) { - struct zfcp_qdio_queue *req_q = &adapter->req_q; - - spin_lock_bh(&adapter->req_q_lock); - if (atomic_read(&req_q->count)) + if (atomic_read(&adapter->req_q.count) > 0) return 1; - spin_unlock_bh(&adapter->req_q_lock); + atomic_inc(&adapter->qdio_outb_full); return 0; } -static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter) -{ - unsigned int count = atomic_read(&adapter->req_q.count); - if (!count) - atomic_inc(&adapter->qdio_outb_full); - return count > 0; -} - static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) + __releases(&adapter->req_q_lock) + __acquires(&adapter->req_q_lock) { + struct zfcp_qdio_queue *req_q = &adapter->req_q; long ret; + if (atomic_read(&req_q->count) <= -REQUEST_LIST_SIZE) + return -EIO; + if (atomic_read(&req_q->count) > 0) + return 0; + + atomic_dec(&req_q->count); spin_unlock_bh(&adapter->req_q_lock); ret = wait_event_interruptible_timeout(adapter->request_wq, - zfcp_fsf_sbal_check(adapter), 5 * HZ); + atomic_read(&req_q->count) >= 0, + 5 * HZ); + spin_lock_bh(&adapter->req_q_lock); + atomic_inc(&req_q->count); + if (ret > 0) return 0; if (!ret) atomic_inc(&adapter->qdio_outb_full); - - spin_lock_bh(&adapter->req_q_lock); return -EIO; }