• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * zfcp device driver
4  *
5  * Registration and callback for the s390 common I/O layer.
6  *
7  * Copyright IBM Corp. 2002, 2010
8  */
9 
10 #define KMSG_COMPONENT "zfcp"
11 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
12 
13 #include <linux/module.h>
14 #include "zfcp_ext.h"
15 #include "zfcp_reqlist.h"
16 
17 #define ZFCP_MODEL_PRIV 0x4
18 
19 static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
20 
zfcp_ccw_adapter_by_cdev(struct ccw_device * cdev)21 struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
22 {
23 	struct zfcp_adapter *adapter;
24 	unsigned long flags;
25 
26 	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
27 	adapter = dev_get_drvdata(&cdev->dev);
28 	if (adapter)
29 		kref_get(&adapter->ref);
30 	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
31 	return adapter;
32 }
33 
zfcp_ccw_adapter_put(struct zfcp_adapter * adapter)34 void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
35 {
36 	unsigned long flags;
37 
38 	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
39 	kref_put(&adapter->ref, zfcp_adapter_release);
40 	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
41 }
42 
43 /**
44  * zfcp_ccw_activate - activate adapter and wait for it to finish
45  * @cdev: pointer to belonging ccw device
46  * @clear: Status flags to clear.
47  * @tag: s390dbf trace record tag
48  */
zfcp_ccw_activate(struct ccw_device * cdev,int clear,char * tag)49 static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
50 {
51 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
52 
53 	if (!adapter)
54 		return 0;
55 
56 	zfcp_erp_clear_adapter_status(adapter, clear);
57 	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
58 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
59 				tag);
60 
61 	/*
62 	 * We want to scan ports here, with some random backoff and without
63 	 * rate limit. Recovery has already scheduled a port scan for us,
64 	 * but with both random delay and rate limit. Nevertheless we get
65 	 * what we want here by flushing the scheduled work after sleeping
66 	 * an equivalent random time.
67 	 * Let the port scan random delay elapse first. If recovery finishes
68 	 * up to that point in time, that would be perfect for both recovery
69 	 * and port scan. If not, i.e. recovery takes ages, there was no
70 	 * point in waiting a random delay on top of the time consumed by
71 	 * recovery.
72 	 */
73 	msleep(zfcp_fc_port_scan_backoff());
74 	zfcp_erp_wait(adapter);
75 	flush_delayed_work(&adapter->scan_work);
76 
77 	zfcp_ccw_adapter_put(adapter);
78 
79 	return 0;
80 }
81 
82 static struct ccw_device_id zfcp_ccw_device_id[] = {
83 	{ CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
84 	{ CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
85 	{},
86 };
87 MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
88 
89 /**
90  * zfcp_ccw_probe - probe function of zfcp driver
91  * @cdev: pointer to belonging ccw device
92  *
93  * This function gets called by the common i/o layer for each FCP
94  * device found on the current system. This is only a stub to make cio
95  * work: To only allocate adapter resources for devices actually used,
96  * the allocation is deferred to the first call to ccw_set_online.
97  */
zfcp_ccw_probe(struct ccw_device * cdev)98 static int zfcp_ccw_probe(struct ccw_device *cdev)
99 {
100 	return 0;
101 }
102 
103 /**
104  * zfcp_ccw_remove - remove function of zfcp driver
105  * @cdev: pointer to belonging ccw device
106  *
107  * This function gets called by the common i/o layer and removes an adapter
108  * from the system. Task of this function is to get rid of all units and
109  * ports that belong to this adapter. And in addition all resources of this
110  * adapter will be freed too.
111  */
zfcp_ccw_remove(struct ccw_device * cdev)112 static void zfcp_ccw_remove(struct ccw_device *cdev)
113 {
114 	struct zfcp_adapter *adapter;
115 	struct zfcp_port *port, *p;
116 	struct zfcp_unit *unit, *u;
117 	LIST_HEAD(unit_remove_lh);
118 	LIST_HEAD(port_remove_lh);
119 
120 	ccw_device_set_offline(cdev);
121 
122 	adapter = zfcp_ccw_adapter_by_cdev(cdev);
123 	if (!adapter)
124 		return;
125 
126 	write_lock_irq(&adapter->port_list_lock);
127 	list_for_each_entry(port, &adapter->port_list, list) {
128 		write_lock(&port->unit_list_lock);
129 		list_splice_init(&port->unit_list, &unit_remove_lh);
130 		write_unlock(&port->unit_list_lock);
131 	}
132 	list_splice_init(&adapter->port_list, &port_remove_lh);
133 	write_unlock_irq(&adapter->port_list_lock);
134 	zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
135 
136 	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
137 		device_unregister(&unit->dev);
138 
139 	list_for_each_entry_safe(port, p, &port_remove_lh, list)
140 		device_unregister(&port->dev);
141 
142 	zfcp_adapter_unregister(adapter);
143 }
144 
145 /**
146  * zfcp_ccw_set_online - set_online function of zfcp driver
147  * @cdev: pointer to belonging ccw device
148  *
149  * 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.
157  */
zfcp_ccw_set_online(struct ccw_device * cdev)158 static int zfcp_ccw_set_online(struct ccw_device *cdev)
159 {
160 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
161 
162 	if (!adapter) {
163 		adapter = zfcp_adapter_enqueue(cdev);
164 
165 		if (IS_ERR(adapter)) {
166 			dev_err(&cdev->dev,
167 				"Setting up data structures for the "
168 				"FCP adapter failed\n");
169 			return PTR_ERR(adapter);
170 		}
171 		kref_get(&adapter->ref);
172 	}
173 
174 	/* initialize request counter */
175 	BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
176 	adapter->req_no = 0;
177 
178 	zfcp_ccw_activate(cdev, 0, "ccsonl1");
179 
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 	 */
190 	zfcp_fc_inverse_conditional_port_scan(adapter);
191 	flush_delayed_work(&adapter->scan_work);
192 	zfcp_ccw_adapter_put(adapter);
193 	return 0;
194 }
195 
196 /**
197  * zfcp_ccw_set_offline - set_offline function of zfcp driver
198  * @cdev: pointer to belonging ccw device
199  *
200  * This function gets called by the common i/o layer and sets an adapter
201  * into state offline.
202  */
zfcp_ccw_set_offline(struct ccw_device * cdev)203 static int zfcp_ccw_set_offline(struct ccw_device *cdev)
204 {
205 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
206 
207 	if (!adapter)
208 		return 0;
209 
210 	zfcp_erp_set_adapter_status(adapter, 0);
211 	zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
212 	zfcp_erp_wait(adapter);
213 
214 	zfcp_ccw_adapter_put(adapter);
215 	return 0;
216 }
217 
218 /**
219  * zfcp_ccw_notify - ccw notify function
220  * @cdev: pointer to belonging ccw device
221  * @event: indicates if adapter was detached or attached
222  *
223  * This function gets called by the common i/o layer if an adapter has gone
224  * or reappeared.
225  */
zfcp_ccw_notify(struct ccw_device * cdev,int event)226 static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
227 {
228 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
229 
230 	if (!adapter)
231 		return 1;
232 
233 	switch (event) {
234 	case CIO_GONE:
235 		dev_warn(&cdev->dev, "The FCP device has been detached\n");
236 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
237 		break;
238 	case CIO_NO_PATH:
239 		dev_warn(&cdev->dev,
240 			 "The CHPID for the FCP device is offline\n");
241 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
242 		break;
243 	case CIO_OPER:
244 		dev_info(&cdev->dev, "The FCP device is operational again\n");
245 		zfcp_erp_set_adapter_status(adapter,
246 					    ZFCP_STATUS_COMMON_RUNNING);
247 		zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
248 					"ccnoti4");
249 		break;
250 	case CIO_BOXED:
251 		dev_warn(&cdev->dev, "The FCP device did not respond within "
252 				     "the specified time\n");
253 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
254 		break;
255 	}
256 
257 	zfcp_ccw_adapter_put(adapter);
258 	return 1;
259 }
260 
261 /**
262  * zfcp_ccw_shutdown - handle shutdown from cio
263  * @cdev: device for adapter to shutdown.
264  */
zfcp_ccw_shutdown(struct ccw_device * cdev)265 static void zfcp_ccw_shutdown(struct ccw_device *cdev)
266 {
267 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
268 
269 	if (!adapter)
270 		return;
271 
272 	zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
273 	zfcp_erp_wait(adapter);
274 	zfcp_erp_thread_kill(adapter);
275 
276 	zfcp_ccw_adapter_put(adapter);
277 }
278 
279 struct ccw_driver zfcp_ccw_driver = {
280 	.driver = {
281 		.owner	= THIS_MODULE,
282 		.name	= "zfcp",
283 	},
284 	.ids         = zfcp_ccw_device_id,
285 	.probe       = zfcp_ccw_probe,
286 	.remove      = zfcp_ccw_remove,
287 	.set_online  = zfcp_ccw_set_online,
288 	.set_offline = zfcp_ccw_set_offline,
289 	.notify      = zfcp_ccw_notify,
290 	.shutdown    = zfcp_ccw_shutdown,
291 };
292