aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Herrmann <aherrman@de.ibm.com>2006-08-02 05:05:52 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-06 12:31:17 -0400
commitf6c0e7a7b3b6db15146877c0cef43b413af5b76e (patch)
tree2ac31f5ea2cd66eb3aff8c6a4584074be407319d /drivers
parentfea9d6c7bcd8ff1d60ff74f27ba483b3820b18a3 (diff)
[SCSI] zfcp: minor erp bug fixes
Bug fixes for zfcp's erp: - trigger adapter reopen if do_QDIO fails - avoid erp deadlock if registration of scsi target or remote port hang - do not treat as error if exchange port data fails - decrease timeout for target reset and aborts - mark unit failed if slave_destroy is called Additionally some code cleanup was done: - made some functions void when retval is not of interest - shortened initialization of zfcp's host_template - corrected some comments Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/scsi/zfcp_def.h2
-rw-r--r--drivers/s390/scsi/zfcp_erp.c196
-rw-r--r--drivers/s390/scsi/zfcp_ext.h3
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c73
4 files changed, 107 insertions, 167 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 72293f3870b5..904d6a7e9312 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -80,7 +80,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
80#define REQUEST_LIST_SIZE 128 80#define REQUEST_LIST_SIZE 128
81 81
82/********************* SCSI SPECIFIC DEFINES *********************************/ 82/********************* SCSI SPECIFIC DEFINES *********************************/
83#define ZFCP_SCSI_ER_TIMEOUT (100*HZ) 83#define ZFCP_SCSI_ER_TIMEOUT (10*HZ)
84 84
85/********************* CIO/QDIO SPECIFIC DEFINES *****************************/ 85/********************* CIO/QDIO SPECIFIC DEFINES *****************************/
86 86
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index f74412bd9d6a..7f60b6fdf724 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -64,8 +64,8 @@ static int zfcp_erp_strategy_check_action(struct zfcp_erp_action *, int);
64static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *); 64static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *);
65static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *, int); 65static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *, int);
66static int zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *); 66static int zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *);
67static int zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *); 67static void zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *);
68static int zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *); 68static void zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *);
69static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *); 69static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *);
70static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *); 70static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *);
71static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *); 71static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *);
@@ -93,10 +93,9 @@ static int zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *);
93static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *); 93static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *);
94static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *); 94static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *);
95 95
96static int zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *); 96static void zfcp_erp_action_dismiss_port(struct zfcp_port *);
97static int zfcp_erp_action_dismiss_port(struct zfcp_port *); 97static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *);
98static int zfcp_erp_action_dismiss_unit(struct zfcp_unit *); 98static void zfcp_erp_action_dismiss(struct zfcp_erp_action *);
99static int zfcp_erp_action_dismiss(struct zfcp_erp_action *);
100 99
101static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *, 100static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *,
102 struct zfcp_port *, struct zfcp_unit *); 101 struct zfcp_port *, struct zfcp_unit *);
@@ -135,29 +134,39 @@ zfcp_fsf_request_timeout_handler(unsigned long data)
135 zfcp_erp_adapter_reopen(adapter, 0); 134 zfcp_erp_adapter_reopen(adapter, 0);
136} 135}
137 136
138/* 137/**
139 * function: zfcp_fsf_scsi_er_timeout_handler 138 * zfcp_fsf_scsi_er_timeout_handler - timeout handler for scsi eh tasks
140 * 139 *
141 * purpose: This function needs to be called whenever a SCSI error recovery 140 * This function needs to be called whenever a SCSI error recovery
142 * action (abort/reset) does not return. 141 * action (abort/reset) does not return. Re-opening the adapter means
143 * Re-opening the adapter means that the command can be returned 142 * that the abort/reset command can be returned by zfcp. It won't complete
144 * by zfcp (it is guarranteed that it does not return via the 143 * via the adapter anymore (because qdio queues are closed). If ERP is
145 * adapter anymore). The buffer can then be used again. 144 * already running on this adapter it will be stopped.
146 *
147 * returns: sod all
148 */ 145 */
149void 146void zfcp_fsf_scsi_er_timeout_handler(unsigned long data)
150zfcp_fsf_scsi_er_timeout_handler(unsigned long data)
151{ 147{
152 struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; 148 struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
149 unsigned long flags;
153 150
154 ZFCP_LOG_NORMAL("warning: SCSI error recovery timed out. " 151 ZFCP_LOG_NORMAL("warning: SCSI error recovery timed out. "
155 "Restarting all operations on the adapter %s\n", 152 "Restarting all operations on the adapter %s\n",
156 zfcp_get_busid_by_adapter(adapter)); 153 zfcp_get_busid_by_adapter(adapter));
157 debug_text_event(adapter->erp_dbf, 1, "eh_lmem_tout"); 154 debug_text_event(adapter->erp_dbf, 1, "eh_lmem_tout");
158 zfcp_erp_adapter_reopen(adapter, 0);
159 155
160 return; 156 write_lock_irqsave(&adapter->erp_lock, flags);
157 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
158 &adapter->status)) {
159 zfcp_erp_modify_adapter_status(adapter,
160 ZFCP_STATUS_COMMON_UNBLOCKED|ZFCP_STATUS_COMMON_OPEN,
161 ZFCP_CLEAR);
162 zfcp_erp_action_dismiss_adapter(adapter);
163 write_unlock_irqrestore(&adapter->erp_lock, flags);
164 /* dismiss all pending requests including requests for ERP */
165 zfcp_fsf_req_dismiss_all(adapter);
166 adapter->fsf_req_seq_no = 0;
167 } else
168 write_unlock_irqrestore(&adapter->erp_lock, flags);
169 zfcp_erp_adapter_reopen(adapter, 0);
161} 170}
162 171
163/* 172/*
@@ -670,17 +679,10 @@ zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask)
670 return retval; 679 return retval;
671} 680}
672 681
673/* 682/**
674 * function: 683 * zfcp_erp_adapter_block - mark adapter as blocked, block scsi requests
675 *
676 * purpose: disable I/O,
677 * return any open requests and clean them up,
678 * aim: no pending and incoming I/O
679 *
680 * returns:
681 */ 684 */
682static void 685static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask)
683zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask)
684{ 686{
685 debug_text_event(adapter->erp_dbf, 6, "a_bl"); 687 debug_text_event(adapter->erp_dbf, 6, "a_bl");
686 zfcp_erp_modify_adapter_status(adapter, 688 zfcp_erp_modify_adapter_status(adapter,
@@ -688,15 +690,10 @@ zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask)
688 clear_mask, ZFCP_CLEAR); 690 clear_mask, ZFCP_CLEAR);
689} 691}
690 692
691/* 693/**
692 * function: 694 * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests
693 *
694 * purpose: enable I/O
695 *
696 * returns:
697 */ 695 */
698static void 696static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
699zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
700{ 697{
701 debug_text_event(adapter->erp_dbf, 6, "a_ubl"); 698 debug_text_event(adapter->erp_dbf, 6, "a_ubl");
702 atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status); 699 atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
@@ -897,23 +894,15 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
897 return retval; 894 return retval;
898} 895}
899 896
900/* 897/**
901 * purpose: generic handler for asynchronous events related to erp_action events 898 * zfcp_erp_async_handler_nolock - complete erp_action
902 * (normal completion, time-out, dismissing, retry after
903 * low memory condition)
904 *
905 * note: deletion of timer is not required (e.g. in case of a time-out),
906 * but a second try does no harm,
907 * we leave it in here to allow for greater simplification
908 * 899 *
909 * returns: 0 - there was an action to handle 900 * Used for normal completion, time-out, dismissal and failure after
910 * !0 - otherwise 901 * low memory condition.
911 */ 902 */
912static int 903static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
913zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, 904 unsigned long set_mask)
914 unsigned long set_mask)
915{ 905{
916 int retval;
917 struct zfcp_adapter *adapter = erp_action->adapter; 906 struct zfcp_adapter *adapter = erp_action->adapter;
918 907
919 if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) { 908 if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) {
@@ -924,43 +913,26 @@ zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
924 del_timer(&erp_action->timer); 913 del_timer(&erp_action->timer);
925 erp_action->status |= set_mask; 914 erp_action->status |= set_mask;
926 zfcp_erp_action_ready(erp_action); 915 zfcp_erp_action_ready(erp_action);
927 retval = 0;
928 } else { 916 } else {
929 /* action is ready or gone - nothing to do */ 917 /* action is ready or gone - nothing to do */
930 debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone"); 918 debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone");
931 debug_event(adapter->erp_dbf, 3, &erp_action->action, 919 debug_event(adapter->erp_dbf, 3, &erp_action->action,
932 sizeof (int)); 920 sizeof (int));
933 retval = 1;
934 } 921 }
935
936 return retval;
937} 922}
938 923
939/* 924/**
940 * purpose: generic handler for asynchronous events related to erp_action 925 * zfcp_erp_async_handler - wrapper for erp_async_handler_nolock w/ locking
941 * events (normal completion, time-out, dismissing, retry after
942 * low memory condition)
943 *
944 * note: deletion of timer is not required (e.g. in case of a time-out),
945 * but a second try does no harm,
946 * we leave it in here to allow for greater simplification
947 *
948 * returns: 0 - there was an action to handle
949 * !0 - otherwise
950 */ 926 */
951int 927void zfcp_erp_async_handler(struct zfcp_erp_action *erp_action,
952zfcp_erp_async_handler(struct zfcp_erp_action *erp_action, 928 unsigned long set_mask)
953 unsigned long set_mask)
954{ 929{
955 struct zfcp_adapter *adapter = erp_action->adapter; 930 struct zfcp_adapter *adapter = erp_action->adapter;
956 unsigned long flags; 931 unsigned long flags;
957 int retval;
958 932
959 write_lock_irqsave(&adapter->erp_lock, flags); 933 write_lock_irqsave(&adapter->erp_lock, flags);
960 retval = zfcp_erp_async_handler_nolock(erp_action, set_mask); 934 zfcp_erp_async_handler_nolock(erp_action, set_mask);
961 write_unlock_irqrestore(&adapter->erp_lock, flags); 935 write_unlock_irqrestore(&adapter->erp_lock, flags);
962
963 return retval;
964} 936}
965 937
966/* 938/*
@@ -997,17 +969,15 @@ zfcp_erp_timeout_handler(unsigned long data)
997 zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT); 969 zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT);
998} 970}
999 971
1000/* 972/**
1001 * purpose: is called for an erp_action which needs to be ended 973 * zfcp_erp_action_dismiss - dismiss an erp_action
1002 * though not being done,
1003 * this is usually required if an higher is generated,
1004 * action gets an appropriate flag and will be processed
1005 * accordingly
1006 * 974 *
1007 * locks: erp_lock held (thus we need to call another handler variant) 975 * adapter->erp_lock must be held
976 *
977 * Dismissal of an erp_action is usually required if an erp_action of
978 * higher priority is generated.
1008 */ 979 */
1009static int 980static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
1010zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
1011{ 981{
1012 struct zfcp_adapter *adapter = erp_action->adapter; 982 struct zfcp_adapter *adapter = erp_action->adapter;
1013 983
@@ -1015,8 +985,6 @@ zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
1015 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int)); 985 debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
1016 986
1017 zfcp_erp_async_handler_nolock(erp_action, ZFCP_STATUS_ERP_DISMISSED); 987 zfcp_erp_async_handler_nolock(erp_action, ZFCP_STATUS_ERP_DISMISSED);
1018
1019 return 0;
1020} 988}
1021 989
1022int 990int
@@ -2072,18 +2040,12 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
2072 return retval; 2040 return retval;
2073} 2041}
2074 2042
2075/* 2043/**
2076 * function: zfcp_qdio_cleanup 2044 * zfcp_erp_adapter_strategy_close_qdio - close qdio queues for an adapter
2077 *
2078 * purpose: cleans up QDIO operation for the specified adapter
2079 *
2080 * returns: 0 - successful cleanup
2081 * !0 - failed cleanup
2082 */ 2045 */
2083int 2046static void
2084zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) 2047zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
2085{ 2048{
2086 int retval = ZFCP_ERP_SUCCEEDED;
2087 int first_used; 2049 int first_used;
2088 int used_count; 2050 int used_count;
2089 struct zfcp_adapter *adapter = erp_action->adapter; 2051 struct zfcp_adapter *adapter = erp_action->adapter;
@@ -2092,15 +2054,13 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
2092 ZFCP_LOG_DEBUG("error: attempt to shut down inactive QDIO " 2054 ZFCP_LOG_DEBUG("error: attempt to shut down inactive QDIO "
2093 "queues on adapter %s\n", 2055 "queues on adapter %s\n",
2094 zfcp_get_busid_by_adapter(adapter)); 2056 zfcp_get_busid_by_adapter(adapter));
2095 retval = ZFCP_ERP_FAILED; 2057 return;
2096 goto out;
2097 } 2058 }
2098 2059
2099 /* 2060 /*
2100 * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that 2061 * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that
2101 * do_QDIO won't be called while qdio_shutdown is in progress. 2062 * do_QDIO won't be called while qdio_shutdown is in progress.
2102 */ 2063 */
2103
2104 write_lock_irq(&adapter->request_queue.queue_lock); 2064 write_lock_irq(&adapter->request_queue.queue_lock);
2105 atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); 2065 atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
2106 write_unlock_irq(&adapter->request_queue.queue_lock); 2066 write_unlock_irq(&adapter->request_queue.queue_lock);
@@ -2132,8 +2092,6 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
2132 adapter->request_queue.free_index = 0; 2092 adapter->request_queue.free_index = 0;
2133 atomic_set(&adapter->request_queue.free_count, 0); 2093 atomic_set(&adapter->request_queue.free_count, 0);
2134 adapter->request_queue.distance_from_int = 0; 2094 adapter->request_queue.distance_from_int = 0;
2135 out:
2136 return retval;
2137} 2095}
2138 2096
2139static int 2097static int
@@ -2256,11 +2214,11 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
2256 "%s)\n", zfcp_get_busid_by_adapter(adapter)); 2214 "%s)\n", zfcp_get_busid_by_adapter(adapter));
2257 ret = ZFCP_ERP_FAILED; 2215 ret = ZFCP_ERP_FAILED;
2258 } 2216 }
2259 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) { 2217
2260 ZFCP_LOG_INFO("error: exchange port data failed (adapter " 2218 /* don't treat as error for the sake of compatibility */
2219 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status))
2220 ZFCP_LOG_INFO("warning: exchange port data failed (adapter "
2261 "%s\n", zfcp_get_busid_by_adapter(adapter)); 2221 "%s\n", zfcp_get_busid_by_adapter(adapter));
2262 ret = ZFCP_ERP_FAILED;
2263 }
2264 2222
2265 return ret; 2223 return ret;
2266} 2224}
@@ -2290,18 +2248,12 @@ zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action
2290 return retval; 2248 return retval;
2291} 2249}
2292 2250
2293/* 2251/**
2294 * function: zfcp_fsf_cleanup 2252 * zfcp_erp_adapter_strategy_close_fsf - stop FSF operations for an adapter
2295 *
2296 * purpose: cleanup FSF operation for specified adapter
2297 *
2298 * returns: 0 - FSF operation successfully cleaned up
2299 * !0 - failed to cleanup FSF operation for this adapter
2300 */ 2253 */
2301static int 2254static void
2302zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action) 2255zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action)
2303{ 2256{
2304 int retval = ZFCP_ERP_SUCCEEDED;
2305 struct zfcp_adapter *adapter = erp_action->adapter; 2257 struct zfcp_adapter *adapter = erp_action->adapter;
2306 2258
2307 /* 2259 /*
@@ -2315,8 +2267,6 @@ zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action)
2315 /* all ports and units are closed */ 2267 /* all ports and units are closed */
2316 zfcp_erp_modify_adapter_status(adapter, 2268 zfcp_erp_modify_adapter_status(adapter,
2317 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); 2269 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
2318
2319 return retval;
2320} 2270}
2321 2271
2322/* 2272/*
@@ -3291,10 +3241,8 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
3291} 3241}
3292 3242
3293 3243
3294static int 3244void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
3295zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
3296{ 3245{
3297 int retval = 0;
3298 struct zfcp_port *port; 3246 struct zfcp_port *port;
3299 3247
3300 debug_text_event(adapter->erp_dbf, 5, "a_actab"); 3248 debug_text_event(adapter->erp_dbf, 5, "a_actab");
@@ -3303,14 +3251,10 @@ zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
3303 else 3251 else
3304 list_for_each_entry(port, &adapter->port_list_head, list) 3252 list_for_each_entry(port, &adapter->port_list_head, list)
3305 zfcp_erp_action_dismiss_port(port); 3253 zfcp_erp_action_dismiss_port(port);
3306
3307 return retval;
3308} 3254}
3309 3255
3310static int 3256static void zfcp_erp_action_dismiss_port(struct zfcp_port *port)
3311zfcp_erp_action_dismiss_port(struct zfcp_port *port)
3312{ 3257{
3313 int retval = 0;
3314 struct zfcp_unit *unit; 3258 struct zfcp_unit *unit;
3315 struct zfcp_adapter *adapter = port->adapter; 3259 struct zfcp_adapter *adapter = port->adapter;
3316 3260
@@ -3321,22 +3265,16 @@ zfcp_erp_action_dismiss_port(struct zfcp_port *port)
3321 else 3265 else
3322 list_for_each_entry(unit, &port->unit_list_head, list) 3266 list_for_each_entry(unit, &port->unit_list_head, list)
3323 zfcp_erp_action_dismiss_unit(unit); 3267 zfcp_erp_action_dismiss_unit(unit);
3324
3325 return retval;
3326} 3268}
3327 3269
3328static int 3270static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
3329zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
3330{ 3271{
3331 int retval = 0;
3332 struct zfcp_adapter *adapter = unit->port->adapter; 3272 struct zfcp_adapter *adapter = unit->port->adapter;
3333 3273
3334 debug_text_event(adapter->erp_dbf, 5, "u_actab"); 3274 debug_text_event(adapter->erp_dbf, 5, "u_actab");
3335 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t)); 3275 debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
3336 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) 3276 if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status))
3337 zfcp_erp_action_dismiss(&unit->erp_action); 3277 zfcp_erp_action_dismiss(&unit->erp_action);
3338
3339 return retval;
3340} 3278}
3341 3279
3342static inline void 3280static inline void
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 04bb3a9d90a8..146d7a2b4c4a 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -139,6 +139,7 @@ extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int);
139extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int); 139extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int);
140extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int); 140extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int);
141extern void zfcp_erp_adapter_failed(struct zfcp_adapter *); 141extern void zfcp_erp_adapter_failed(struct zfcp_adapter *);
142extern void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *);
142 143
143extern void zfcp_erp_modify_port_status(struct zfcp_port *, u32, int); 144extern void zfcp_erp_modify_port_status(struct zfcp_port *, u32, int);
144extern int zfcp_erp_port_reopen(struct zfcp_port *, int); 145extern int zfcp_erp_port_reopen(struct zfcp_port *, int);
@@ -155,7 +156,7 @@ extern void zfcp_erp_unit_failed(struct zfcp_unit *);
155extern int zfcp_erp_thread_setup(struct zfcp_adapter *); 156extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
156extern int zfcp_erp_thread_kill(struct zfcp_adapter *); 157extern int zfcp_erp_thread_kill(struct zfcp_adapter *);
157extern int zfcp_erp_wait(struct zfcp_adapter *); 158extern int zfcp_erp_wait(struct zfcp_adapter *);
158extern int zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long); 159extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long);
159 160
160extern int zfcp_test_link(struct zfcp_port *); 161extern int zfcp_test_link(struct zfcp_port *);
161 162
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 671f4a6a5d18..1bb55086db9f 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -30,7 +30,6 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *,
30 void (*done) (struct scsi_cmnd *)); 30 void (*done) (struct scsi_cmnd *));
31static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); 31static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
32static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); 32static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
33static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *);
34static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); 33static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
35static int zfcp_task_management_function(struct zfcp_unit *, u8, 34static int zfcp_task_management_function(struct zfcp_unit *, u8,
36 struct scsi_cmnd *); 35 struct scsi_cmnd *);
@@ -46,30 +45,22 @@ struct zfcp_data zfcp_data = {
46 .scsi_host_template = { 45 .scsi_host_template = {
47 .name = ZFCP_NAME, 46 .name = ZFCP_NAME,
48 .proc_name = "zfcp", 47 .proc_name = "zfcp",
49 .proc_info = NULL,
50 .detect = NULL,
51 .slave_alloc = zfcp_scsi_slave_alloc, 48 .slave_alloc = zfcp_scsi_slave_alloc,
52 .slave_configure = zfcp_scsi_slave_configure, 49 .slave_configure = zfcp_scsi_slave_configure,
53 .slave_destroy = zfcp_scsi_slave_destroy, 50 .slave_destroy = zfcp_scsi_slave_destroy,
54 .queuecommand = zfcp_scsi_queuecommand, 51 .queuecommand = zfcp_scsi_queuecommand,
55 .eh_abort_handler = zfcp_scsi_eh_abort_handler, 52 .eh_abort_handler = zfcp_scsi_eh_abort_handler,
56 .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, 53 .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler,
57 .eh_bus_reset_handler = zfcp_scsi_eh_bus_reset_handler, 54 .eh_bus_reset_handler = zfcp_scsi_eh_host_reset_handler,
58 .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, 55 .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler,
59 .can_queue = 4096, 56 .can_queue = 4096,
60 .this_id = -1, 57 .this_id = -1,
61 /*
62 * FIXME:
63 * one less? can zfcp_create_sbale cope with it?
64 */
65 .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ, 58 .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ,
66 .cmd_per_lun = 1, 59 .cmd_per_lun = 1,
67 .unchecked_isa_dma = 0,
68 .use_clustering = 1, 60 .use_clustering = 1,
69 .sdev_attrs = zfcp_sysfs_sdev_attrs, 61 .sdev_attrs = zfcp_sysfs_sdev_attrs,
70 }, 62 },
71 .driver_version = ZFCP_VERSION, 63 .driver_version = ZFCP_VERSION,
72 /* rest initialised with zeros */
73}; 64};
74 65
75/* Find start of Response Information in FCP response unit*/ 66/* Find start of Response Information in FCP response unit*/
@@ -176,8 +167,14 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp)
176 return retval; 167 return retval;
177} 168}
178 169
179static void 170/**
180zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) 171 * zfcp_scsi_slave_destroy - called when scsi device is removed
172 *
173 * Remove reference to associated scsi device for an zfcp_unit.
174 * Mark zfcp_unit as failed. The scsi device might be deleted via sysfs
175 * or a scan for this device might have failed.
176 */
177static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
181{ 178{
182 struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; 179 struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
183 180
@@ -185,6 +182,7 @@ zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
185 atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); 182 atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
186 sdpnt->hostdata = NULL; 183 sdpnt->hostdata = NULL;
187 unit->device = NULL; 184 unit->device = NULL;
185 zfcp_erp_unit_failed(unit);
188 zfcp_unit_put(unit); 186 zfcp_unit_put(unit);
189 } else { 187 } else {
190 ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " 188 ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at "
@@ -549,35 +547,38 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,
549} 547}
550 548
551/** 549/**
552 * zfcp_scsi_eh_bus_reset_handler - reset bus (reopen adapter) 550 * zfcp_scsi_eh_host_reset_handler - handler for host and bus reset
551 *
552 * If ERP is already running it will be stopped.
553 */ 553 */
554int 554int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
555zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
556{ 555{
557 struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata; 556 struct zfcp_unit *unit;
558 struct zfcp_adapter *adapter = unit->port->adapter; 557 struct zfcp_adapter *adapter;
559 558 unsigned long flags;
560 ZFCP_LOG_NORMAL("bus reset because of problems with "
561 "unit 0x%016Lx\n", unit->fcp_lun);
562 zfcp_erp_adapter_reopen(adapter, 0);
563 zfcp_erp_wait(adapter);
564
565 return SUCCESS;
566}
567 559
568/** 560 unit = (struct zfcp_unit*) scpnt->device->hostdata;
569 * zfcp_scsi_eh_host_reset_handler - reset host (reopen adapter) 561 adapter = unit->port->adapter;
570 */
571int
572zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
573{
574 struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;
575 struct zfcp_adapter *adapter = unit->port->adapter;
576 562
577 ZFCP_LOG_NORMAL("host reset because of problems with " 563 ZFCP_LOG_NORMAL("host/bus reset because of problems with "
578 "unit 0x%016Lx\n", unit->fcp_lun); 564 "unit 0x%016Lx\n", unit->fcp_lun);
579 zfcp_erp_adapter_reopen(adapter, 0); 565
580 zfcp_erp_wait(adapter); 566 write_lock_irqsave(&adapter->erp_lock, flags);
567 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
568 &adapter->status)) {
569 zfcp_erp_modify_adapter_status(adapter,
570 ZFCP_STATUS_COMMON_UNBLOCKED|ZFCP_STATUS_COMMON_OPEN,
571 ZFCP_CLEAR);
572 zfcp_erp_action_dismiss_adapter(adapter);
573 write_unlock_irqrestore(&adapter->erp_lock, flags);
574 zfcp_fsf_req_dismiss_all(adapter);
575 adapter->fsf_req_seq_no = 0;
576 zfcp_erp_adapter_reopen(adapter, 0);
577 } else {
578 write_unlock_irqrestore(&adapter->erp_lock, flags);
579 zfcp_erp_adapter_reopen(adapter, 0);
580 zfcp_erp_wait(adapter);
581 }
581 582
582 return SUCCESS; 583 return SUCCESS;
583} 584}