xref: /linux/drivers/s390/scsi/zfcp_ccw.c (revision de2fe5e07d58424bc286fff3fd3c1b0bf933cd58)
1 /*
2  * linux/drivers/s390/scsi/zfcp_ccw.c
3  *
4  * FCP adapter driver for IBM eServer zSeries
5  *
6  * CCW driver related routines
7  *
8  * (C) Copyright IBM Corp. 2003, 2004
9  *
10  * Authors:
11  *      Martin Peschke <mpeschke@de.ibm.com>
12  *	Heiko Carstens <heiko.carstens@de.ibm.com>
13  *      Andreas Herrmann <aherrman@de.ibm.com>
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2, or (at your option)
18  * any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28  */
29 
30 #include "zfcp_ext.h"
31 
32 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
33 
34 static int zfcp_ccw_probe(struct ccw_device *);
35 static void zfcp_ccw_remove(struct ccw_device *);
36 static int zfcp_ccw_set_online(struct ccw_device *);
37 static int zfcp_ccw_set_offline(struct ccw_device *);
38 static int zfcp_ccw_notify(struct ccw_device *, int);
39 static void zfcp_ccw_shutdown(struct device *);
40 
41 static struct ccw_device_id zfcp_ccw_device_id[] = {
42 	{CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE,
43 			    ZFCP_CONTROL_UNIT_MODEL,
44 			    ZFCP_DEVICE_TYPE,
45 			    ZFCP_DEVICE_MODEL)},
46 	{CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE,
47 			    ZFCP_CONTROL_UNIT_MODEL,
48 			    ZFCP_DEVICE_TYPE,
49 			    ZFCP_DEVICE_MODEL_PRIV)},
50 	{},
51 };
52 
53 static struct ccw_driver zfcp_ccw_driver = {
54 	.owner       = THIS_MODULE,
55 	.name        = ZFCP_NAME,
56 	.ids         = zfcp_ccw_device_id,
57 	.probe       = zfcp_ccw_probe,
58 	.remove      = zfcp_ccw_remove,
59 	.set_online  = zfcp_ccw_set_online,
60 	.set_offline = zfcp_ccw_set_offline,
61 	.notify      = zfcp_ccw_notify,
62 	.driver      = {
63 		.shutdown = zfcp_ccw_shutdown,
64 	},
65 };
66 
67 MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
68 
69 /**
70  * zfcp_ccw_probe - probe function of zfcp driver
71  * @ccw_device: pointer to belonging ccw device
72  *
73  * This function gets called by the common i/o layer and sets up the initial
74  * data structures for each fcp adapter, which was detected by the system.
75  * Also the sysfs files for this adapter will be created by this function.
76  * In addition the nameserver port will be added to the ports of the adapter
77  * and its sysfs representation will be created too.
78  */
79 static int
80 zfcp_ccw_probe(struct ccw_device *ccw_device)
81 {
82 	struct zfcp_adapter *adapter;
83 	int retval = 0;
84 
85 	down(&zfcp_data.config_sema);
86 	adapter = zfcp_adapter_enqueue(ccw_device);
87 	if (!adapter)
88 		retval = -EINVAL;
89 	else
90 		ZFCP_LOG_DEBUG("Probed adapter %s\n",
91 			       zfcp_get_busid_by_adapter(adapter));
92 	up(&zfcp_data.config_sema);
93 	return retval;
94 }
95 
96 /**
97  * zfcp_ccw_remove - remove function of zfcp driver
98  * @ccw_device: pointer to belonging ccw device
99  *
100  * This function gets called by the common i/o layer and removes an adapter
101  * from the system. Task of this function is to get rid of all units and
102  * ports that belong to this adapter. And in addition all resources of this
103  * adapter will be freed too.
104  */
105 static void
106 zfcp_ccw_remove(struct ccw_device *ccw_device)
107 {
108 	struct zfcp_adapter *adapter;
109 	struct zfcp_port *port, *p;
110 	struct zfcp_unit *unit, *u;
111 
112 	ccw_device_set_offline(ccw_device);
113 	down(&zfcp_data.config_sema);
114 	adapter = dev_get_drvdata(&ccw_device->dev);
115 
116 	ZFCP_LOG_DEBUG("Removing adapter %s\n",
117 		       zfcp_get_busid_by_adapter(adapter));
118 	write_lock_irq(&zfcp_data.config_lock);
119 	list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
120 		list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
121 			list_move(&unit->list, &port->unit_remove_lh);
122 			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
123 					&unit->status);
124 		}
125 		list_move(&port->list, &adapter->port_remove_lh);
126 		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
127 	}
128 	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
129 	write_unlock_irq(&zfcp_data.config_lock);
130 
131 	list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) {
132 		list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) {
133 			zfcp_unit_dequeue(unit);
134 		}
135 		zfcp_port_dequeue(port);
136 	}
137 	zfcp_adapter_wait(adapter);
138 	zfcp_adapter_dequeue(adapter);
139 
140 	up(&zfcp_data.config_sema);
141 }
142 
143 /**
144  * zfcp_ccw_set_online - set_online function of zfcp driver
145  * @ccw_device: pointer to belonging ccw device
146  *
147  * This function gets called by the common i/o layer and sets an adapter
148  * into state online. Setting an fcp device online means that it will be
149  * registered with the SCSI stack, that the QDIO queues will be set up
150  * and that the adapter will be opened (asynchronously).
151  */
152 static int
153 zfcp_ccw_set_online(struct ccw_device *ccw_device)
154 {
155 	struct zfcp_adapter *adapter;
156 	int retval;
157 
158 	down(&zfcp_data.config_sema);
159 	adapter = dev_get_drvdata(&ccw_device->dev);
160 
161 	retval = zfcp_adapter_debug_register(adapter);
162 	if (retval)
163 		goto out;
164 	retval = zfcp_erp_thread_setup(adapter);
165 	if (retval) {
166 		ZFCP_LOG_INFO("error: start of error recovery thread for "
167 			      "adapter %s failed\n",
168 			      zfcp_get_busid_by_adapter(adapter));
169 		goto out_erp_thread;
170 	}
171 
172 	retval = zfcp_adapter_scsi_register(adapter);
173 	if (retval)
174 		goto out_scsi_register;
175 	zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING,
176 				       ZFCP_SET);
177 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
178 	zfcp_erp_wait(adapter);
179 	goto out;
180 
181  out_scsi_register:
182 	zfcp_erp_thread_kill(adapter);
183  out_erp_thread:
184 	zfcp_adapter_debug_unregister(adapter);
185  out:
186 	up(&zfcp_data.config_sema);
187 	return retval;
188 }
189 
190 /**
191  * zfcp_ccw_set_offline - set_offline function of zfcp driver
192  * @ccw_device: pointer to belonging ccw device
193  *
194  * This function gets called by the common i/o layer and sets an adapter
195  * into state offline. Setting an fcp device offline means that it will be
196  * unregistered from the SCSI stack and that the adapter will be shut down
197  * asynchronously.
198  */
199 static int
200 zfcp_ccw_set_offline(struct ccw_device *ccw_device)
201 {
202 	struct zfcp_adapter *adapter;
203 
204 	down(&zfcp_data.config_sema);
205 	adapter = dev_get_drvdata(&ccw_device->dev);
206 	zfcp_erp_adapter_shutdown(adapter, 0);
207 	zfcp_erp_wait(adapter);
208 	zfcp_adapter_scsi_unregister(adapter);
209 	zfcp_erp_thread_kill(adapter);
210 	zfcp_adapter_debug_unregister(adapter);
211 	up(&zfcp_data.config_sema);
212 	return 0;
213 }
214 
215 /**
216  * zfcp_ccw_notify
217  * @ccw_device: pointer to belonging ccw device
218  * @event: indicates if adapter was detached or attached
219  *
220  * This function gets called by the common i/o layer if an adapter has gone
221  * or reappeared.
222  */
223 static int
224 zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
225 {
226 	struct zfcp_adapter *adapter;
227 
228 	down(&zfcp_data.config_sema);
229 	adapter = dev_get_drvdata(&ccw_device->dev);
230 	switch (event) {
231 	case CIO_GONE:
232 		ZFCP_LOG_NORMAL("adapter %s: device gone\n",
233 				zfcp_get_busid_by_adapter(adapter));
234 		debug_text_event(adapter->erp_dbf,1,"dev_gone");
235 		zfcp_erp_adapter_shutdown(adapter, 0);
236 		break;
237 	case CIO_NO_PATH:
238 		ZFCP_LOG_NORMAL("adapter %s: no path\n",
239 				zfcp_get_busid_by_adapter(adapter));
240 		debug_text_event(adapter->erp_dbf,1,"no_path");
241 		zfcp_erp_adapter_shutdown(adapter, 0);
242 		break;
243 	case CIO_OPER:
244 		ZFCP_LOG_NORMAL("adapter %s: operational again\n",
245 				zfcp_get_busid_by_adapter(adapter));
246 		debug_text_event(adapter->erp_dbf,1,"dev_oper");
247 		zfcp_erp_modify_adapter_status(adapter,
248 					       ZFCP_STATUS_COMMON_RUNNING,
249 					       ZFCP_SET);
250 		zfcp_erp_adapter_reopen(adapter,
251 					ZFCP_STATUS_COMMON_ERP_FAILED);
252 		break;
253 	}
254 	zfcp_erp_wait(adapter);
255 	up(&zfcp_data.config_sema);
256 	return 1;
257 }
258 
259 /**
260  * zfcp_ccw_register - ccw register function
261  *
262  * Registers the driver at the common i/o layer. This function will be called
263  * at module load time/system start.
264  */
265 int __init
266 zfcp_ccw_register(void)
267 {
268 	int retval;
269 
270 	retval = ccw_driver_register(&zfcp_ccw_driver);
271 	if (retval)
272 		goto out;
273 	retval = zfcp_sysfs_driver_create_files(&zfcp_ccw_driver.driver);
274 	if (retval)
275 		ccw_driver_unregister(&zfcp_ccw_driver);
276  out:
277 	return retval;
278 }
279 
280 /**
281  * zfcp_ccw_unregister - ccw unregister function
282  *
283  * Unregisters the driver from common i/o layer. Function will be called at
284  * module unload/system shutdown.
285  */
286 void __exit
287 zfcp_ccw_unregister(void)
288 {
289 	zfcp_sysfs_driver_remove_files(&zfcp_ccw_driver.driver);
290 	ccw_driver_unregister(&zfcp_ccw_driver);
291 }
292 
293 /**
294  * zfcp_ccw_shutdown - gets called on reboot/shutdown
295  *
296  * Makes sure that QDIO queues are down when the system gets stopped.
297  */
298 static void
299 zfcp_ccw_shutdown(struct device *dev)
300 {
301 	struct zfcp_adapter *adapter;
302 
303 	down(&zfcp_data.config_sema);
304 	adapter = dev_get_drvdata(dev);
305 	zfcp_erp_adapter_shutdown(adapter, 0);
306 	zfcp_erp_wait(adapter);
307 	up(&zfcp_data.config_sema);
308 }
309 
310 #undef ZFCP_LOG_AREA
311