diff options
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 23 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 4 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 19 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 18 |
6 files changed, 32 insertions, 35 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index d23027a2f2f0..41635b13ccb1 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -970,6 +970,27 @@ static void zfcp_dummy_release(struct device *dev) | |||
970 | return; | 970 | return; |
971 | } | 971 | } |
972 | 972 | ||
973 | int zfcp_status_read_refill(struct zfcp_adapter *adapter) | ||
974 | { | ||
975 | while (atomic_read(&adapter->stat_miss) > 0) | ||
976 | if (zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL)) | ||
977 | break; | ||
978 | else | ||
979 | atomic_dec(&adapter->stat_miss); | ||
980 | |||
981 | if (ZFCP_STATUS_READS_RECOM <= atomic_read(&adapter->stat_miss)) { | ||
982 | zfcp_erp_adapter_reopen(adapter, 0, 103, NULL); | ||
983 | return 1; | ||
984 | } | ||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | static void _zfcp_status_read_scheduler(struct work_struct *work) | ||
989 | { | ||
990 | zfcp_status_read_refill(container_of(work, struct zfcp_adapter, | ||
991 | stat_work)); | ||
992 | } | ||
993 | |||
973 | /* | 994 | /* |
974 | * Enqueues an adapter at the end of the adapter list in the driver data. | 995 | * Enqueues an adapter at the end of the adapter list in the driver data. |
975 | * All adapter internal structures are set up. | 996 | * All adapter internal structures are set up. |
@@ -1063,6 +1084,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
1063 | 1084 | ||
1064 | /* initialize lock of associated request queue */ | 1085 | /* initialize lock of associated request queue */ |
1065 | rwlock_init(&adapter->request_queue.queue_lock); | 1086 | rwlock_init(&adapter->request_queue.queue_lock); |
1087 | INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); | ||
1066 | 1088 | ||
1067 | /* mark adapter unusable as long as sysfs registration is not complete */ | 1089 | /* mark adapter unusable as long as sysfs registration is not complete */ |
1068 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 1090 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
@@ -1123,6 +1145,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
1123 | int retval = 0; | 1145 | int retval = 0; |
1124 | unsigned long flags; | 1146 | unsigned long flags; |
1125 | 1147 | ||
1148 | cancel_work_sync(&adapter->stat_work); | ||
1126 | zfcp_adapter_scsi_unregister(adapter); | 1149 | zfcp_adapter_scsi_unregister(adapter); |
1127 | device_unregister(&adapter->generic_services); | 1150 | device_unregister(&adapter->generic_services); |
1128 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); | 1151 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); |
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index c8bad675dbd1..1710c12a32c4 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -268,7 +268,7 @@ void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, | |||
268 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); | 268 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); |
269 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); | 269 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); |
270 | 270 | ||
271 | rec->u.status.failed = adapter->status_read_failed; | 271 | rec->u.status.failed = atomic_read(&adapter->stat_miss); |
272 | if (status_buffer != NULL) { | 272 | if (status_buffer != NULL) { |
273 | rec->u.status.status_type = status_buffer->status_type; | 273 | rec->u.status.status_type = status_buffer->status_type; |
274 | rec->u.status.status_subtype = status_buffer->status_subtype; | 274 | rec->u.status.status_subtype = status_buffer->status_subtype; |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 306fcd0cae31..adfbbb07448a 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -136,7 +136,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) | |||
136 | #define ZFCP_QTCB_VERSION FSF_QTCB_CURRENT_VERSION | 136 | #define ZFCP_QTCB_VERSION FSF_QTCB_CURRENT_VERSION |
137 | /* ATTENTION: value must not be used by hardware */ | 137 | /* ATTENTION: value must not be used by hardware */ |
138 | #define FSF_QTCB_UNSOLICITED_STATUS 0x6305 | 138 | #define FSF_QTCB_UNSOLICITED_STATUS 0x6305 |
139 | #define ZFCP_STATUS_READ_FAILED_THRESHOLD 3 | ||
140 | #define ZFCP_STATUS_READS_RECOM FSF_STATUS_READS_RECOM | 139 | #define ZFCP_STATUS_READS_RECOM FSF_STATUS_READS_RECOM |
141 | 140 | ||
142 | /* Do 1st retry in 1 second, then double the timeout for each following retry */ | 141 | /* Do 1st retry in 1 second, then double the timeout for each following retry */ |
@@ -759,7 +758,8 @@ struct zfcp_adapter { | |||
759 | rwlock_t abort_lock; /* Protects against SCSI | 758 | rwlock_t abort_lock; /* Protects against SCSI |
760 | stack abort/command | 759 | stack abort/command |
761 | completion races */ | 760 | completion races */ |
762 | u16 status_read_failed; /* # failed status reads */ | 761 | atomic_t stat_miss; /* # missing status reads*/ |
762 | struct work_struct stat_work; | ||
763 | atomic_t status; /* status of this adapter */ | 763 | atomic_t status; /* status of this adapter */ |
764 | struct list_head erp_ready_head; /* error recovery for this | 764 | struct list_head erp_ready_head; /* error recovery for this |
765 | adapter/devices */ | 765 | adapter/devices */ |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 805484658dd9..55a4fdc42626 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -2139,25 +2139,10 @@ static int | |||
2139 | zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action | 2139 | zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action |
2140 | *erp_action) | 2140 | *erp_action) |
2141 | { | 2141 | { |
2142 | int retval = ZFCP_ERP_SUCCEEDED; | ||
2143 | int temp_ret; | ||
2144 | struct zfcp_adapter *adapter = erp_action->adapter; | 2142 | struct zfcp_adapter *adapter = erp_action->adapter; |
2145 | int i; | ||
2146 | 2143 | ||
2147 | adapter->status_read_failed = 0; | 2144 | atomic_set(&adapter->stat_miss, 16); |
2148 | for (i = 0; i < ZFCP_STATUS_READS_RECOM; i++) { | 2145 | return zfcp_status_read_refill(adapter); |
2149 | temp_ret = zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL); | ||
2150 | if (temp_ret < 0) { | ||
2151 | ZFCP_LOG_INFO("error: set-up of unsolicited status " | ||
2152 | "notification failed on adapter %s\n", | ||
2153 | zfcp_get_busid_by_adapter(adapter)); | ||
2154 | retval = ZFCP_ERP_FAILED; | ||
2155 | i--; | ||
2156 | break; | ||
2157 | } | ||
2158 | } | ||
2159 | |||
2160 | return retval; | ||
2161 | } | 2146 | } |
2162 | 2147 | ||
2163 | /* | 2148 | /* |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 6abf178fda5d..250565794fa5 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -92,6 +92,7 @@ extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); | |||
92 | extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); | 92 | extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); |
93 | extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); | 93 | extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); |
94 | extern int zfcp_fsf_status_read(struct zfcp_adapter *, int); | 94 | extern int zfcp_fsf_status_read(struct zfcp_adapter *, int); |
95 | extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); | ||
95 | extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *, | 96 | extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *, |
96 | unsigned long *, struct zfcp_fsf_req **); | 97 | unsigned long *, struct zfcp_fsf_req **); |
97 | extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, | 98 | extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 1e7136483c1b..b344e8a72f1f 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1029,21 +1029,9 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
1029 | * FIXME: | 1029 | * FIXME: |
1030 | * allocation failure possible? (Is this code needed?) | 1030 | * allocation failure possible? (Is this code needed?) |
1031 | */ | 1031 | */ |
1032 | retval = zfcp_fsf_status_read(adapter, 0); | 1032 | |
1033 | if (retval < 0) { | 1033 | atomic_inc(&adapter->stat_miss); |
1034 | ZFCP_LOG_INFO("Failed to create unsolicited status read " | 1034 | schedule_work(&adapter->stat_work); |
1035 | "request for the adapter %s.\n", | ||
1036 | zfcp_get_busid_by_adapter(adapter)); | ||
1037 | /* temporary fix to avoid status read buffer shortage */ | ||
1038 | adapter->status_read_failed++; | ||
1039 | if ((ZFCP_STATUS_READS_RECOM - adapter->status_read_failed) | ||
1040 | < ZFCP_STATUS_READ_FAILED_THRESHOLD) { | ||
1041 | ZFCP_LOG_INFO("restart adapter %s due to status read " | ||
1042 | "buffer shortage\n", | ||
1043 | zfcp_get_busid_by_adapter(adapter)); | ||
1044 | zfcp_erp_adapter_reopen(adapter, 0, 103, fsf_req); | ||
1045 | } | ||
1046 | } | ||
1047 | out: | 1035 | out: |
1048 | return retval; | 1036 | return retval; |
1049 | } | 1037 | } |