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