Merge branch 'origin'
[pandora-kernel.git] / drivers / s390 / scsi / zfcp_ccw.c
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