Linux Audio

Check our new training course

Loading...
v5.9
  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
 19static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
 20
 21struct 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
 34void 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 */
 49static 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
 82static 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};
 87MODULE_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 */
 98static 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 */
112static 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 */
158static 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_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
216	zfcp_ccw_adapter_put(adapter);
217	return 0;
218}
219
220/**
221 * zfcp_ccw_set_offline - set_offline function of zfcp driver
222 * @cdev: pointer to belonging ccw device
223 *
224 * This function gets called by the common i/o layer and sets an adapter
225 * into state offline.
226 */
227static int zfcp_ccw_set_offline(struct ccw_device *cdev)
228{
229	return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
230}
231
232/**
233 * zfcp_ccw_notify - ccw notify function
234 * @cdev: pointer to belonging ccw device
235 * @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 */
240static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
241{
242	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
243
244	if (!adapter)
245		return 1;
246
247	switch (event) {
248	case CIO_GONE:
249		if (atomic_read(&adapter->status) &
250		    ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
251			zfcp_dbf_hba_basic("ccnigo1", adapter);
252			break;
253		}
254		dev_warn(&cdev->dev, "The FCP device has been detached\n");
255		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
256		break;
257	case CIO_NO_PATH:
258		dev_warn(&cdev->dev,
259			 "The CHPID for the FCP device is offline\n");
260		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
261		break;
262	case CIO_OPER:
263		if (atomic_read(&adapter->status) &
264		    ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
265			zfcp_dbf_hba_basic("ccniop1", adapter);
266			break;
267		}
268		dev_info(&cdev->dev, "The FCP device is operational again\n");
269		zfcp_erp_set_adapter_status(adapter,
270					    ZFCP_STATUS_COMMON_RUNNING);
271		zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
272					"ccnoti4");
273		break;
274	case CIO_BOXED:
275		dev_warn(&cdev->dev, "The FCP device did not respond within "
276				     "the specified time\n");
277		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
278		break;
279	}
280
281	zfcp_ccw_adapter_put(adapter);
282	return 1;
283}
284
285/**
286 * zfcp_ccw_shutdown - handle shutdown from cio
287 * @cdev: device for adapter to shutdown.
288 */
289static void zfcp_ccw_shutdown(struct ccw_device *cdev)
290{
291	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
292
293	if (!adapter)
294		return;
295
296	zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
297	zfcp_erp_wait(adapter);
298	zfcp_erp_thread_kill(adapter);
299
300	zfcp_ccw_adapter_put(adapter);
301}
302
303static 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
325struct ccw_driver zfcp_ccw_driver = {
326	.driver = {
327		.owner	= THIS_MODULE,
328		.name	= "zfcp",
329	},
330	.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,
337	.freeze      = zfcp_ccw_suspend,
338	.thaw	     = zfcp_ccw_thaw,
339	.restore     = zfcp_ccw_resume,
340};
v3.1
 
  1/*
  2 * zfcp device driver
  3 *
  4 * Registration and callback for the s390 common I/O layer.
  5 *
  6 * Copyright IBM Corporation 2002, 2010
  7 */
  8
  9#define KMSG_COMPONENT "zfcp"
 10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 11
 
 12#include "zfcp_ext.h"
 13#include "zfcp_reqlist.h"
 14
 15#define ZFCP_MODEL_PRIV 0x4
 16
 17static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
 18
 19struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
 20{
 21	struct zfcp_adapter *adapter;
 22	unsigned long flags;
 23
 24	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
 25	adapter = dev_get_drvdata(&cdev->dev);
 26	if (adapter)
 27		kref_get(&adapter->ref);
 28	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
 29	return adapter;
 30}
 31
 32void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
 33{
 34	unsigned long flags;
 35
 36	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
 37	kref_put(&adapter->ref, zfcp_adapter_release);
 38	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
 39}
 40
 41static int zfcp_ccw_activate(struct ccw_device *cdev)
 42
 
 
 
 
 
 43{
 44	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 45
 46	if (!adapter)
 47		return 0;
 48
 
 49	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
 50	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 51				"ccresu2");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 52	zfcp_erp_wait(adapter);
 53	flush_work(&adapter->scan_work);
 54
 55	zfcp_ccw_adapter_put(adapter);
 56
 57	return 0;
 58}
 59
 60static struct ccw_device_id zfcp_ccw_device_id[] = {
 61	{ CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
 62	{ CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
 63	{},
 64};
 65MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
 66
 67/**
 68 * zfcp_ccw_priv_sch - check if subchannel is privileged
 69 * @adapter: Adapter/Subchannel to check
 70 */
 71int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
 72{
 73	return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV;
 74}
 75
 76/**
 77 * zfcp_ccw_probe - probe function of zfcp driver
 78 * @cdev: pointer to belonging ccw device
 79 *
 80 * This function gets called by the common i/o layer for each FCP
 81 * device found on the current system. This is only a stub to make cio
 82 * work: To only allocate adapter resources for devices actually used,
 83 * the allocation is deferred to the first call to ccw_set_online.
 84 */
 85static int zfcp_ccw_probe(struct ccw_device *cdev)
 86{
 87	return 0;
 88}
 89
 90/**
 91 * zfcp_ccw_remove - remove function of zfcp driver
 92 * @cdev: pointer to belonging ccw device
 93 *
 94 * This function gets called by the common i/o layer and removes an adapter
 95 * from the system. Task of this function is to get rid of all units and
 96 * ports that belong to this adapter. And in addition all resources of this
 97 * adapter will be freed too.
 98 */
 99static void zfcp_ccw_remove(struct ccw_device *cdev)
100{
101	struct zfcp_adapter *adapter;
102	struct zfcp_port *port, *p;
103	struct zfcp_unit *unit, *u;
104	LIST_HEAD(unit_remove_lh);
105	LIST_HEAD(port_remove_lh);
106
107	ccw_device_set_offline(cdev);
108
109	adapter = zfcp_ccw_adapter_by_cdev(cdev);
110	if (!adapter)
111		return;
112
113	write_lock_irq(&adapter->port_list_lock);
114	list_for_each_entry_safe(port, p, &adapter->port_list, list) {
115		write_lock(&port->unit_list_lock);
116		list_for_each_entry_safe(unit, u, &port->unit_list, list)
117			list_move(&unit->list, &unit_remove_lh);
118		write_unlock(&port->unit_list_lock);
119		list_move(&port->list, &port_remove_lh);
120	}
 
121	write_unlock_irq(&adapter->port_list_lock);
122	zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
123
124	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
125		zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
126
127	list_for_each_entry_safe(port, p, &port_remove_lh, list)
128		zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
129
130	zfcp_adapter_unregister(adapter);
131}
132
133/**
134 * zfcp_ccw_set_online - set_online function of zfcp driver
135 * @cdev: pointer to belonging ccw device
136 *
137 * This function gets called by the common i/o layer and sets an
138 * adapter into state online.  The first call will allocate all
139 * adapter resources that will be retained until the device is removed
140 * via zfcp_ccw_remove.
141 *
142 * Setting an fcp device online means that it will be registered with
143 * the SCSI stack, that the QDIO queues will be set up and that the
144 * adapter will be opened.
145 */
146static int zfcp_ccw_set_online(struct ccw_device *cdev)
147{
148	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
149
150	if (!adapter) {
151		adapter = zfcp_adapter_enqueue(cdev);
152
153		if (IS_ERR(adapter)) {
154			dev_err(&cdev->dev,
155				"Setting up data structures for the "
156				"FCP adapter failed\n");
157			return PTR_ERR(adapter);
158		}
159		kref_get(&adapter->ref);
160	}
161
162	/* initialize request counter */
163	BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
164	adapter->req_no = 0;
165
166	zfcp_ccw_activate(cdev);
 
 
 
 
 
 
 
 
 
 
 
 
 
167	zfcp_ccw_adapter_put(adapter);
168	return 0;
169}
170
171/**
172 * zfcp_ccw_set_offline - set_offline function of zfcp driver
173 * @cdev: pointer to belonging ccw device
 
 
174 *
175 * This function gets called by the common i/o layer and sets an adapter
176 * into state offline.
177 */
178static int zfcp_ccw_set_offline(struct ccw_device *cdev)
179{
180	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
181
182	if (!adapter)
183		return 0;
184
185	zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
 
186	zfcp_erp_wait(adapter);
187
188	zfcp_ccw_adapter_put(adapter);
189	return 0;
190}
191
192/**
 
 
 
 
 
 
 
 
 
 
 
 
193 * zfcp_ccw_notify - ccw notify function
194 * @cdev: pointer to belonging ccw device
195 * @event: indicates if adapter was detached or attached
196 *
197 * This function gets called by the common i/o layer if an adapter has gone
198 * or reappeared.
199 */
200static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
201{
202	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
203
204	if (!adapter)
205		return 1;
206
207	switch (event) {
208	case CIO_GONE:
 
 
 
 
 
209		dev_warn(&cdev->dev, "The FCP device has been detached\n");
210		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
211		break;
212	case CIO_NO_PATH:
213		dev_warn(&cdev->dev,
214			 "The CHPID for the FCP device is offline\n");
215		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
216		break;
217	case CIO_OPER:
 
 
 
 
 
218		dev_info(&cdev->dev, "The FCP device is operational again\n");
219		zfcp_erp_set_adapter_status(adapter,
220					    ZFCP_STATUS_COMMON_RUNNING);
221		zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
222					"ccnoti4");
223		break;
224	case CIO_BOXED:
225		dev_warn(&cdev->dev, "The FCP device did not respond within "
226				     "the specified time\n");
227		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
228		break;
229	}
230
231	zfcp_ccw_adapter_put(adapter);
232	return 1;
233}
234
235/**
236 * zfcp_ccw_shutdown - handle shutdown from cio
237 * @cdev: device for adapter to shutdown.
238 */
239static void zfcp_ccw_shutdown(struct ccw_device *cdev)
240{
241	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
242
243	if (!adapter)
244		return;
245
246	zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
247	zfcp_erp_wait(adapter);
248	zfcp_erp_thread_kill(adapter);
249
250	zfcp_ccw_adapter_put(adapter);
251}
252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253struct ccw_driver zfcp_ccw_driver = {
254	.driver = {
255		.owner	= THIS_MODULE,
256		.name	= "zfcp",
257	},
258	.ids         = zfcp_ccw_device_id,
259	.probe       = zfcp_ccw_probe,
260	.remove      = zfcp_ccw_remove,
261	.set_online  = zfcp_ccw_set_online,
262	.set_offline = zfcp_ccw_set_offline,
263	.notify      = zfcp_ccw_notify,
264	.shutdown    = zfcp_ccw_shutdown,
265	.freeze      = zfcp_ccw_set_offline,
266	.thaw	     = zfcp_ccw_activate,
267	.restore     = zfcp_ccw_activate,
268};