blob: 54c7b48fdb4640167ee842ab3ef0f5149e656524 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Christof Schmittfa04c282008-06-10 18:20:56 +02002 * zfcp device driver
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
Christof Schmittfa04c282008-06-10 18:20:56 +02004 * Registration and callback for the s390 common I/O layer.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02006 * Copyright IBM Corp. 2002, 2010
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 */
8
Christof Schmittecf39d42008-12-25 13:39:53 +01009#define KMSG_COMPONENT "zfcp"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11
Heiko Carstens3a4c5d52011-07-30 09:25:15 +020012#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include "zfcp_ext.h"
Christof Schmittb6bd2fb2010-02-17 11:18:50 +010014#include "zfcp_reqlist.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070015
Christof Schmitt6fcf41d2009-05-15 13:18:21 +020016#define ZFCP_MODEL_PRIV 0x4
17
Swen Schilligde3dc572009-11-24 16:54:00 +010018static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
19
20struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
21{
22 struct zfcp_adapter *adapter;
23 unsigned long flags;
24
25 spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
26 adapter = dev_get_drvdata(&cdev->dev);
27 if (adapter)
28 kref_get(&adapter->ref);
29 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
30 return adapter;
31}
32
33void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
34{
35 unsigned long flags;
36
37 spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
38 kref_put(&adapter->ref, zfcp_adapter_release);
39 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
40}
41
Steffen Maiercb4521492012-09-04 15:23:32 +020042/**
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)
Martin Petermanndaa70fa2009-06-16 10:30:34 +020049{
Swen Schilligde3dc572009-11-24 16:54:00 +010050 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
Martin Petermanndaa70fa2009-06-16 10:30:34 +020051
Christof Schmitt143bb6b2009-08-18 15:43:27 +020052 if (!adapter)
53 return 0;
54
Steffen Maiercb4521492012-09-04 15:23:32 +020055 zfcp_erp_clear_adapter_status(adapter, clear);
Swen Schilligedaed852010-09-08 14:40:01 +020056 zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
Martin Petermanndaa70fa2009-06-16 10:30:34 +020057 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
Steffen Maiercb4521492012-09-04 15:23:32 +020058 tag);
Martin Peschke18f87a62014-11-13 14:59:48 +010059
60 /*
61 * We want to scan ports here, with some random backoff and without
62 * rate limit. Recovery has already scheduled a port scan for us,
63 * but with both random delay and rate limit. Nevertheless we get
64 * what we want here by flushing the scheduled work after sleeping
65 * an equivalent random time.
66 * Let the port scan random delay elapse first. If recovery finishes
67 * up to that point in time, that would be perfect for both recovery
68 * and port scan. If not, i.e. recovery takes ages, there was no
69 * point in waiting a random delay on top of the time consumed by
70 * recovery.
71 */
72 msleep(zfcp_fc_port_scan_backoff());
Martin Petermanndaa70fa2009-06-16 10:30:34 +020073 zfcp_erp_wait(adapter);
Martin Peschke18f87a62014-11-13 14:59:48 +010074 flush_delayed_work(&adapter->scan_work);
Martin Petermanndaa70fa2009-06-16 10:30:34 +020075
Swen Schilligde3dc572009-11-24 16:54:00 +010076 zfcp_ccw_adapter_put(adapter);
77
Martin Petermanndaa70fa2009-06-16 10:30:34 +020078 return 0;
79}
80
Christof Schmitt6fcf41d2009-05-15 13:18:21 +020081static struct ccw_device_id zfcp_ccw_device_id[] = {
82 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
83 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
84 {},
85};
86MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
87
88/**
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 * zfcp_ccw_probe - probe function of zfcp driver
Swen Schilligde3dc572009-11-24 16:54:00 +010090 * @cdev: pointer to belonging ccw device
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 *
Christof Schmitt143bb6b2009-08-18 15:43:27 +020092 * This function gets called by the common i/o layer for each FCP
93 * device found on the current system. This is only a stub to make cio
94 * work: To only allocate adapter resources for devices actually used,
95 * the allocation is deferred to the first call to ccw_set_online.
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 */
Swen Schilligde3dc572009-11-24 16:54:00 +010097static int zfcp_ccw_probe(struct ccw_device *cdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -070098{
Christof Schmitt143bb6b2009-08-18 15:43:27 +020099 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100}
101
102/**
103 * zfcp_ccw_remove - remove function of zfcp driver
Swen Schilligde3dc572009-11-24 16:54:00 +0100104 * @cdev: pointer to belonging ccw device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 *
106 * This function gets called by the common i/o layer and removes an adapter
107 * from the system. Task of this function is to get rid of all units and
108 * ports that belong to this adapter. And in addition all resources of this
109 * adapter will be freed too.
110 */
Swen Schilligde3dc572009-11-24 16:54:00 +0100111static void zfcp_ccw_remove(struct ccw_device *cdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112{
113 struct zfcp_adapter *adapter;
114 struct zfcp_port *port, *p;
115 struct zfcp_unit *unit, *u;
Christof Schmitt04062892008-10-01 12:42:20 +0200116 LIST_HEAD(unit_remove_lh);
117 LIST_HEAD(port_remove_lh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Swen Schilligde3dc572009-11-24 16:54:00 +0100119 ccw_device_set_offline(cdev);
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200120
Swen Schilligde3dc572009-11-24 16:54:00 +0100121 adapter = zfcp_ccw_adapter_by_cdev(cdev);
Swen Schilligecf0c772009-11-24 16:53:58 +0100122 if (!adapter)
123 return;
124
Swen Schilligecf0c772009-11-24 16:53:58 +0100125 write_lock_irq(&adapter->port_list_lock);
126 list_for_each_entry_safe(port, p, &adapter->port_list, list) {
127 write_lock(&port->unit_list_lock);
Swen Schillig6b1833342009-11-24 16:54:05 +0100128 list_for_each_entry_safe(unit, u, &port->unit_list, list)
Swen Schilligecf0c772009-11-24 16:53:58 +0100129 list_move(&unit->list, &unit_remove_lh);
Swen Schilligecf0c772009-11-24 16:53:58 +0100130 write_unlock(&port->unit_list_lock);
Swen Schilligecf0c772009-11-24 16:53:58 +0100131 list_move(&port->list, &port_remove_lh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 }
Swen Schilligecf0c772009-11-24 16:53:58 +0100133 write_unlock_irq(&adapter->port_list_lock);
Swen Schilligde3dc572009-11-24 16:54:00 +0100134 zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Swen Schilligf3450c72009-11-24 16:53:59 +0100136 list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
Sebastian Ott86bdf212013-04-26 16:13:49 +0200137 device_unregister(&unit->dev);
Swen Schilligf3450c72009-11-24 16:53:59 +0100138
139 list_for_each_entry_safe(port, p, &port_remove_lh, list)
Sebastian Ott83d4e1c2013-04-26 16:13:48 +0200140 device_unregister(&port->dev);
Swen Schilligf3450c72009-11-24 16:53:59 +0100141
Swen Schilligde3dc572009-11-24 16:54:00 +0100142 zfcp_adapter_unregister(adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143}
144
145/**
146 * zfcp_ccw_set_online - set_online function of zfcp driver
Swen Schilligde3dc572009-11-24 16:54:00 +0100147 * @cdev: pointer to belonging ccw device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 *
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200149 * This function gets called by the common i/o layer and sets an
150 * adapter into state online. The first call will allocate all
151 * adapter resources that will be retained until the device is removed
152 * via zfcp_ccw_remove.
153 *
154 * Setting an fcp device online means that it will be registered with
155 * the SCSI stack, that the QDIO queues will be set up and that the
156 * adapter will be opened.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 */
Swen Schilligde3dc572009-11-24 16:54:00 +0100158static int zfcp_ccw_set_online(struct ccw_device *cdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159{
Swen Schilligde3dc572009-11-24 16:54:00 +0100160 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200162 if (!adapter) {
Swen Schilligde3dc572009-11-24 16:54:00 +0100163 adapter = zfcp_adapter_enqueue(cdev);
164
165 if (IS_ERR(adapter)) {
166 dev_err(&cdev->dev,
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200167 "Setting up data structures for the "
168 "FCP adapter failed\n");
Swen Schilligde3dc572009-11-24 16:54:00 +0100169 return PTR_ERR(adapter);
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200170 }
Swen Schilligde3dc572009-11-24 16:54:00 +0100171 kref_get(&adapter->ref);
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200172 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Volker Sameskefea9d6c2006-08-02 11:05:16 +0200174 /* initialize request counter */
Christof Schmittb6bd2fb2010-02-17 11:18:50 +0100175 BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
Volker Sameskefea9d6c2006-08-02 11:05:16 +0200176 adapter->req_no = 0;
177
Steffen Maiercb4521492012-09-04 15:23:32 +0200178 zfcp_ccw_activate(cdev, 0, "ccsonl1");
Martin Peschke18f87a62014-11-13 14:59:48 +0100179
180 /*
181 * We want to scan ports here, always, with some random delay and
182 * without rate limit - basically what zfcp_ccw_activate() has
183 * achieved for us. Not quite! That port scan depended on
184 * !no_auto_port_rescan. So let's cover the no_auto_port_rescan
185 * case here to make sure a port scan is done unconditionally.
186 * Since zfcp_ccw_activate() has waited the desired random time,
187 * we can immediately schedule and flush a port scan for the
188 * remaining cases.
189 */
Steffen Maier43f60cb2012-09-04 15:23:35 +0200190 zfcp_fc_inverse_conditional_port_scan(adapter);
Martin Peschke18f87a62014-11-13 14:59:48 +0100191 flush_delayed_work(&adapter->scan_work);
Steffen Maiercb4521492012-09-04 15:23:32 +0200192 zfcp_ccw_adapter_put(adapter);
193 return 0;
194}
195
196/**
197 * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
198 * @cdev: pointer to belonging ccw device
199 * @set: Status flags to set.
200 * @tag: s390dbf trace record tag
201 *
202 * This function gets called by the common i/o layer and sets an adapter
203 * into state offline.
204 */
205static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
206{
207 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
208
209 if (!adapter)
210 return 0;
211
212 zfcp_erp_set_adapter_status(adapter, set);
213 zfcp_erp_adapter_shutdown(adapter, 0, tag);
214 zfcp_erp_wait(adapter);
215
Swen Schilligde3dc572009-11-24 16:54:00 +0100216 zfcp_ccw_adapter_put(adapter);
217 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218}
219
220/**
221 * zfcp_ccw_set_offline - set_offline function of zfcp driver
Swen Schilligde3dc572009-11-24 16:54:00 +0100222 * @cdev: pointer to belonging ccw device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 *
224 * This function gets called by the common i/o layer and sets an adapter
Michael Loehr9f287452007-05-09 11:01:24 +0200225 * into state offline.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 */
Swen Schilligde3dc572009-11-24 16:54:00 +0100227static int zfcp_ccw_set_offline(struct ccw_device *cdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228{
Steffen Maiercb4521492012-09-04 15:23:32 +0200229 return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230}
231
232/**
Christof Schmittfa04c282008-06-10 18:20:56 +0200233 * zfcp_ccw_notify - ccw notify function
Swen Schilligde3dc572009-11-24 16:54:00 +0100234 * @cdev: pointer to belonging ccw device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 * @event: indicates if adapter was detached or attached
236 *
237 * This function gets called by the common i/o layer if an adapter has gone
238 * or reappeared.
239 */
Swen Schilligde3dc572009-11-24 16:54:00 +0100240static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241{
Swen Schilligde3dc572009-11-24 16:54:00 +0100242 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
243
244 if (!adapter)
245 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 switch (event) {
248 case CIO_GONE:
Steffen Maiercb4521492012-09-04 15:23:32 +0200249 if (atomic_read(&adapter->status) &
250 ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
251 zfcp_dbf_hba_basic("ccnigo1", adapter);
252 break;
253 }
Swen Schilligde3dc572009-11-24 16:54:00 +0100254 dev_warn(&cdev->dev, "The FCP device has been detached\n");
Swen Schilligea4a3a62010-12-02 15:16:16 +0100255 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 break;
257 case CIO_NO_PATH:
Swen Schilligde3dc572009-11-24 16:54:00 +0100258 dev_warn(&cdev->dev,
Christof Schmittff3b24f2008-10-01 12:42:15 +0200259 "The CHPID for the FCP device is offline\n");
Swen Schilligea4a3a62010-12-02 15:16:16 +0100260 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 break;
262 case CIO_OPER:
Steffen Maiercb4521492012-09-04 15:23:32 +0200263 if (atomic_read(&adapter->status) &
264 ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
265 zfcp_dbf_hba_basic("ccniop1", adapter);
266 break;
267 }
Swen Schilligde3dc572009-11-24 16:54:00 +0100268 dev_info(&cdev->dev, "The FCP device is operational again\n");
Swen Schilligedaed852010-09-08 14:40:01 +0200269 zfcp_erp_set_adapter_status(adapter,
270 ZFCP_STATUS_COMMON_RUNNING);
Martin Peschke1f6f7122008-04-18 12:51:55 +0200271 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
Swen Schilligea4a3a62010-12-02 15:16:16 +0100272 "ccnoti4");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 break;
Sebastian Ott47593bf2009-03-31 19:16:05 +0200274 case CIO_BOXED:
Swen Schilligde3dc572009-11-24 16:54:00 +0100275 dev_warn(&cdev->dev, "The FCP device did not respond within "
276 "the specified time\n");
Swen Schilligea4a3a62010-12-02 15:16:16 +0100277 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
Sebastian Ott47593bf2009-03-31 19:16:05 +0200278 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 }
Swen Schilligde3dc572009-11-24 16:54:00 +0100280
281 zfcp_ccw_adapter_put(adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 return 1;
283}
284
285/**
Christof Schmittfa04c282008-06-10 18:20:56 +0200286 * zfcp_ccw_shutdown - handle shutdown from cio
287 * @cdev: device for adapter to shutdown.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 */
Christof Schmittfa04c282008-06-10 18:20:56 +0200289static void zfcp_ccw_shutdown(struct ccw_device *cdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290{
Swen Schilligde3dc572009-11-24 16:54:00 +0100291 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
Christof Schmitt1f99bd42009-09-24 10:23:23 +0200293 if (!adapter)
Swen Schilligde3dc572009-11-24 16:54:00 +0100294 return;
Christof Schmitt1f99bd42009-09-24 10:23:23 +0200295
Swen Schilligea4a3a62010-12-02 15:16:16 +0100296 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 zfcp_erp_wait(adapter);
Christof Schmitt143bb6b2009-08-18 15:43:27 +0200298 zfcp_erp_thread_kill(adapter);
Swen Schilligde3dc572009-11-24 16:54:00 +0100299
300 zfcp_ccw_adapter_put(adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301}
302
Steffen Maiercb4521492012-09-04 15:23:32 +0200303static int zfcp_ccw_suspend(struct ccw_device *cdev)
304{
305 zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
306 return 0;
307}
308
309static int zfcp_ccw_thaw(struct ccw_device *cdev)
310{
311 /* trace records for thaw and final shutdown during suspend
312 can only be found in system dump until the end of suspend
313 but not after resume because it's based on the memory image
314 right after the very first suspend (freeze) callback */
315 zfcp_ccw_activate(cdev, 0, "ccthaw1");
316 return 0;
317}
318
319static int zfcp_ccw_resume(struct ccw_device *cdev)
320{
321 zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
322 return 0;
323}
324
Christof Schmittc5afd812009-09-24 10:23:22 +0200325struct ccw_driver zfcp_ccw_driver = {
Sebastian Ott3bda0582011-03-23 10:16:02 +0100326 .driver = {
327 .owner = THIS_MODULE,
328 .name = "zfcp",
329 },
Christof Schmittfa04c282008-06-10 18:20:56 +0200330 .ids = zfcp_ccw_device_id,
331 .probe = zfcp_ccw_probe,
332 .remove = zfcp_ccw_remove,
333 .set_online = zfcp_ccw_set_online,
334 .set_offline = zfcp_ccw_set_offline,
335 .notify = zfcp_ccw_notify,
336 .shutdown = zfcp_ccw_shutdown,
Steffen Maiercb4521492012-09-04 15:23:32 +0200337 .freeze = zfcp_ccw_suspend,
338 .thaw = zfcp_ccw_thaw,
339 .restore = zfcp_ccw_resume,
Christof Schmittfa04c282008-06-10 18:20:56 +0200340};