diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 5ae1d497e5ed..dc0367690405 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -683,6 +683,7 @@ static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool) | |||
683 | if (!req) | 683 | if (!req) |
684 | return NULL; | 684 | return NULL; |
685 | memset(req, 0, sizeof(*req)); | 685 | memset(req, 0, sizeof(*req)); |
686 | req->pool = pool; | ||
686 | return req; | 687 | return req; |
687 | } | 688 | } |
688 | 689 | ||
@@ -769,28 +770,24 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
769 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | 770 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) |
770 | { | 771 | { |
771 | struct zfcp_adapter *adapter = req->adapter; | 772 | struct zfcp_adapter *adapter = req->adapter; |
772 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 773 | unsigned long flags; |
773 | int idx; | 774 | int idx; |
774 | 775 | ||
775 | /* put allocated FSF request into hash table */ | 776 | /* put allocated FSF request into hash table */ |
776 | spin_lock(&adapter->req_list_lock); | 777 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
777 | idx = zfcp_reqlist_hash(req->req_id); | 778 | idx = zfcp_reqlist_hash(req->req_id); |
778 | list_add_tail(&req->list, &adapter->req_list[idx]); | 779 | list_add_tail(&req->list, &adapter->req_list[idx]); |
779 | spin_unlock(&adapter->req_list_lock); | 780 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
780 | 781 | ||
781 | req->qdio_outb_usage = atomic_read(&req_q->count); | 782 | req->qdio_outb_usage = atomic_read(&adapter->req_q.count); |
782 | req->issued = get_clock(); | 783 | req->issued = get_clock(); |
783 | if (zfcp_qdio_send(req)) { | 784 | if (zfcp_qdio_send(req)) { |
784 | /* Queues are down..... */ | ||
785 | del_timer(&req->timer); | 785 | del_timer(&req->timer); |
786 | spin_lock(&adapter->req_list_lock); | 786 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
787 | zfcp_reqlist_remove(adapter, req); | 787 | /* lookup request again, list might have changed */ |
788 | spin_unlock(&adapter->req_list_lock); | 788 | if (zfcp_reqlist_find_safe(adapter, req)) |
789 | /* undo changes in request queue made for this request */ | 789 | zfcp_reqlist_remove(adapter, req); |
790 | atomic_add(req->sbal_number, &req_q->count); | 790 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
791 | req_q->first -= req->sbal_number; | ||
792 | req_q->first += QDIO_MAX_BUFFERS_PER_Q; | ||
793 | req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ | ||
794 | zfcp_erp_adapter_reopen(adapter, 0, 116, req); | 791 | zfcp_erp_adapter_reopen(adapter, 0, 116, req); |
795 | return -EIO; | 792 | return -EIO; |
796 | } | 793 | } |
@@ -933,8 +930,10 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
933 | goto out; | 930 | goto out; |
934 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | 931 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, |
935 | req_flags, adapter->pool.fsf_req_abort); | 932 | req_flags, adapter->pool.fsf_req_abort); |
936 | if (IS_ERR(req)) | 933 | if (IS_ERR(req)) { |
934 | req = NULL; | ||
937 | goto out; | 935 | goto out; |
936 | } | ||
938 | 937 | ||
939 | if (unlikely(!(atomic_read(&unit->status) & | 938 | if (unlikely(!(atomic_read(&unit->status) & |
940 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 939 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
@@ -1587,6 +1586,7 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) | |||
1587 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 1586 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; |
1588 | break; | 1587 | break; |
1589 | case FSF_PORT_ALREADY_OPEN: | 1588 | case FSF_PORT_ALREADY_OPEN: |
1589 | break; | ||
1590 | case FSF_GOOD: | 1590 | case FSF_GOOD: |
1591 | wka_port->handle = header->port_handle; | 1591 | wka_port->handle = header->port_handle; |
1592 | wka_port->status = ZFCP_WKA_PORT_ONLINE; | 1592 | wka_port->status = ZFCP_WKA_PORT_ONLINE; |
@@ -2116,18 +2116,21 @@ static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | |||
2116 | 2116 | ||
2117 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2117 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) |
2118 | { | 2118 | { |
2119 | struct scsi_cmnd *scpnt = req->data; | 2119 | struct scsi_cmnd *scpnt; |
2120 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 2120 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) |
2121 | &(req->qtcb->bottom.io.fcp_rsp); | 2121 | &(req->qtcb->bottom.io.fcp_rsp); |
2122 | u32 sns_len; | 2122 | u32 sns_len; |
2123 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; | 2123 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; |
2124 | unsigned long flags; | 2124 | unsigned long flags; |
2125 | 2125 | ||
2126 | if (unlikely(!scpnt)) | ||
2127 | return; | ||
2128 | |||
2129 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2126 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
2130 | 2127 | ||
2128 | scpnt = req->data; | ||
2129 | if (unlikely(!scpnt)) { | ||
2130 | read_unlock_irqrestore(&req->adapter->abort_lock, flags); | ||
2131 | return; | ||
2132 | } | ||
2133 | |||
2131 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { | 2134 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { |
2132 | set_host_byte(scpnt, DID_SOFT_ERROR); | 2135 | set_host_byte(scpnt, DID_SOFT_ERROR); |
2133 | set_driver_byte(scpnt, SUGGEST_RETRY); | 2136 | set_driver_byte(scpnt, SUGGEST_RETRY); |
@@ -2445,8 +2448,10 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
2445 | goto out; | 2448 | goto out; |
2446 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | 2449 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, |
2447 | adapter->pool.fsf_req_scsi); | 2450 | adapter->pool.fsf_req_scsi); |
2448 | if (IS_ERR(req)) | 2451 | if (IS_ERR(req)) { |
2452 | req = NULL; | ||
2449 | goto out; | 2453 | goto out; |
2454 | } | ||
2450 | 2455 | ||
2451 | req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; | 2456 | req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; |
2452 | req->data = unit; | 2457 | req->data = unit; |