aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_ccw.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 22:01:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 22:01:32 -0400
commit3151367f8778a1789d6f6e6f6c642681b6cd6d64 (patch)
tree1869d5429a25abd994ae94079808b8db060ec6f3 /drivers/s390/scsi/zfcp_ccw.c
parent16642a2e7be23bbda013fc32d8f6c68982eab603 (diff)
parentfe709ed827d370e6b0c0a9f9456da1c22bdcd118 (diff)
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley: "This is a large set of updates, mostly for drivers (qla2xxx [including support for new 83xx based card], qla4xxx, mpt2sas, bfa, zfcp, hpsa, be2iscsi, isci, lpfc, ipr, ibmvfc, ibmvscsi, megaraid_sas). There's also a rework for tape adding virtually unlimited numbers of tape drives plus a set of dif fixes for sd and a fix for a live lock on hot remove of SCSI devices. This round includes a signed tag pull of isci-for-3.6 Signed-off-by: James Bottomley <JBottomley@Parallels.com>" Fix up trivial conflict in drivers/scsi/qla2xxx/qla_nx.c due to new PCI helper function use in a function that was removed by this pull. * tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (198 commits) [SCSI] st: remove st_mutex [SCSI] sd: Ensure we correctly disable devices with unknown protection type [SCSI] hpsa: gen8plus Smart Array IDs [SCSI] qla4xxx: Update driver version to 5.03.00-k1 [SCSI] qla4xxx: Disable generating pause frames for ISP83XX [SCSI] qla4xxx: Fix double clearing of risc_intr for ISP83XX [SCSI] qla4xxx: IDC implementation for Loopback [SCSI] qla4xxx: update copyrights in LICENSE.qla4xxx [SCSI] qla4xxx: Fix panic while rmmod [SCSI] qla4xxx: Fail probe_adapter if IRQ allocation fails [SCSI] qla4xxx: Prevent MSI/MSI-X falling back to INTx for ISP82XX [SCSI] qla4xxx: Update idc reg in case of PCI AER [SCSI] qla4xxx: Fix double IDC locking in qla4_8xxx_error_recovery [SCSI] qla4xxx: Clear interrupt while unloading driver for ISP83XX [SCSI] qla4xxx: Print correct IDC version [SCSI] qla4xxx: Added new mbox cmd to pass driver version to FW [SCSI] scsi_dh_alua: Enable STPG for unavailable ports [SCSI] scsi_remove_target: fix softlockup regression on hot remove [SCSI] ibmvscsi: Fix host config length field overflow [SCSI] ibmvscsi: Remove backend abstraction ...
Diffstat (limited to 'drivers/s390/scsi/zfcp_ccw.c')
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index e37f04551948..f2dd3a0a39eb 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -39,19 +39,25 @@ void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
39 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags); 39 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
40} 40}
41 41
42static int zfcp_ccw_activate(struct ccw_device *cdev) 42/**
43 43 * zfcp_ccw_activate - activate adapter and wait for it to finish
44 * @cdev: pointer to belonging ccw device
45 * @clear: Status flags to clear.
46 * @tag: s390dbf trace record tag
47 */
48static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
44{ 49{
45 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 50 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
46 51
47 if (!adapter) 52 if (!adapter)
48 return 0; 53 return 0;
49 54
55 zfcp_erp_clear_adapter_status(adapter, clear);
50 zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); 56 zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
51 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 57 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
52 "ccresu2"); 58 tag);
53 zfcp_erp_wait(adapter); 59 zfcp_erp_wait(adapter);
54 flush_work(&adapter->scan_work); 60 flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
55 61
56 zfcp_ccw_adapter_put(adapter); 62 zfcp_ccw_adapter_put(adapter);
57 63
@@ -164,26 +170,34 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
164 BUG_ON(!zfcp_reqlist_isempty(adapter->req_list)); 170 BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
165 adapter->req_no = 0; 171 adapter->req_no = 0;
166 172
167 zfcp_ccw_activate(cdev); 173 zfcp_ccw_activate(cdev, 0, "ccsonl1");
174 /* scan for remote ports
175 either at the end of any successful adapter recovery
176 or only after the adapter recovery for setting a device online */
177 zfcp_fc_inverse_conditional_port_scan(adapter);
178 flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
168 zfcp_ccw_adapter_put(adapter); 179 zfcp_ccw_adapter_put(adapter);
169 return 0; 180 return 0;
170} 181}
171 182
172/** 183/**
173 * zfcp_ccw_set_offline - set_offline function of zfcp driver 184 * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
174 * @cdev: pointer to belonging ccw device 185 * @cdev: pointer to belonging ccw device
186 * @set: Status flags to set.
187 * @tag: s390dbf trace record tag
175 * 188 *
176 * This function gets called by the common i/o layer and sets an adapter 189 * This function gets called by the common i/o layer and sets an adapter
177 * into state offline. 190 * into state offline.
178 */ 191 */
179static int zfcp_ccw_set_offline(struct ccw_device *cdev) 192static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
180{ 193{
181 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 194 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
182 195
183 if (!adapter) 196 if (!adapter)
184 return 0; 197 return 0;
185 198
186 zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1"); 199 zfcp_erp_set_adapter_status(adapter, set);
200 zfcp_erp_adapter_shutdown(adapter, 0, tag);
187 zfcp_erp_wait(adapter); 201 zfcp_erp_wait(adapter);
188 202
189 zfcp_ccw_adapter_put(adapter); 203 zfcp_ccw_adapter_put(adapter);
@@ -191,6 +205,18 @@ static int zfcp_ccw_set_offline(struct ccw_device *cdev)
191} 205}
192 206
193/** 207/**
208 * zfcp_ccw_set_offline - set_offline function of zfcp driver
209 * @cdev: pointer to belonging ccw device
210 *
211 * This function gets called by the common i/o layer and sets an adapter
212 * into state offline.
213 */
214static int zfcp_ccw_set_offline(struct ccw_device *cdev)
215{
216 return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
217}
218
219/**
194 * zfcp_ccw_notify - ccw notify function 220 * zfcp_ccw_notify - ccw notify function
195 * @cdev: pointer to belonging ccw device 221 * @cdev: pointer to belonging ccw device
196 * @event: indicates if adapter was detached or attached 222 * @event: indicates if adapter was detached or attached
@@ -207,6 +233,11 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
207 233
208 switch (event) { 234 switch (event) {
209 case CIO_GONE: 235 case CIO_GONE:
236 if (atomic_read(&adapter->status) &
237 ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
238 zfcp_dbf_hba_basic("ccnigo1", adapter);
239 break;
240 }
210 dev_warn(&cdev->dev, "The FCP device has been detached\n"); 241 dev_warn(&cdev->dev, "The FCP device has been detached\n");
211 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1"); 242 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
212 break; 243 break;
@@ -216,6 +247,11 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
216 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2"); 247 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
217 break; 248 break;
218 case CIO_OPER: 249 case CIO_OPER:
250 if (atomic_read(&adapter->status) &
251 ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
252 zfcp_dbf_hba_basic("ccniop1", adapter);
253 break;
254 }
219 dev_info(&cdev->dev, "The FCP device is operational again\n"); 255 dev_info(&cdev->dev, "The FCP device is operational again\n");
220 zfcp_erp_set_adapter_status(adapter, 256 zfcp_erp_set_adapter_status(adapter,
221 ZFCP_STATUS_COMMON_RUNNING); 257 ZFCP_STATUS_COMMON_RUNNING);
@@ -251,6 +287,28 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
251 zfcp_ccw_adapter_put(adapter); 287 zfcp_ccw_adapter_put(adapter);
252} 288}
253 289
290static int zfcp_ccw_suspend(struct ccw_device *cdev)
291{
292 zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
293 return 0;
294}
295
296static int zfcp_ccw_thaw(struct ccw_device *cdev)
297{
298 /* trace records for thaw and final shutdown during suspend
299 can only be found in system dump until the end of suspend
300 but not after resume because it's based on the memory image
301 right after the very first suspend (freeze) callback */
302 zfcp_ccw_activate(cdev, 0, "ccthaw1");
303 return 0;
304}
305
306static int zfcp_ccw_resume(struct ccw_device *cdev)
307{
308 zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
309 return 0;
310}
311
254struct ccw_driver zfcp_ccw_driver = { 312struct ccw_driver zfcp_ccw_driver = {
255 .driver = { 313 .driver = {
256 .owner = THIS_MODULE, 314 .owner = THIS_MODULE,
@@ -263,7 +321,7 @@ struct ccw_driver zfcp_ccw_driver = {
263 .set_offline = zfcp_ccw_set_offline, 321 .set_offline = zfcp_ccw_set_offline,
264 .notify = zfcp_ccw_notify, 322 .notify = zfcp_ccw_notify,
265 .shutdown = zfcp_ccw_shutdown, 323 .shutdown = zfcp_ccw_shutdown,
266 .freeze = zfcp_ccw_set_offline, 324 .freeze = zfcp_ccw_suspend,
267 .thaw = zfcp_ccw_activate, 325 .thaw = zfcp_ccw_thaw,
268 .restore = zfcp_ccw_activate, 326 .restore = zfcp_ccw_resume,
269}; 327};