Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zfcp_ccw.c
Go to the documentation of this file.
1 /*
2  * zfcp device driver
3  *
4  * Registration and callback for the s390 common I/O layer.
5  *
6  * Copyright IBM Corp. 2002, 2010
7  */
8 
9 #define KMSG_COMPONENT "zfcp"
10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 
12 #include <linux/module.h>
13 #include "zfcp_ext.h"
14 #include "zfcp_reqlist.h"
15 
16 #define ZFCP_MODEL_PRIV 0x4
17 
18 static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
19 
21 {
22  struct zfcp_adapter *adapter;
23  unsigned long flags;
24 
25  spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
26  adapter = dev_get_drvdata(&cdev->dev);
27  if (adapter)
28  kref_get(&adapter->ref);
29  spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
30  return adapter;
31 }
32 
34 {
35  unsigned long flags;
36 
37  spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
38  kref_put(&adapter->ref, zfcp_adapter_release);
39  spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
40 }
41 
48 static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
49 {
51 
52  if (!adapter)
53  return 0;
54 
55  zfcp_erp_clear_adapter_status(adapter, clear);
58  tag);
59  zfcp_erp_wait(adapter);
60  flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
61 
62  zfcp_ccw_adapter_put(adapter);
63 
64  return 0;
65 }
66 
67 static struct ccw_device_id zfcp_ccw_device_id[] = {
68  { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
69  { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
70  {},
71 };
72 MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
73 
78 int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
79 {
80  return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV;
81 }
82 
92 static int zfcp_ccw_probe(struct ccw_device *cdev)
93 {
94  return 0;
95 }
96 
106 static void zfcp_ccw_remove(struct ccw_device *cdev)
107 {
108  struct zfcp_adapter *adapter;
109  struct zfcp_port *port, *p;
110  struct zfcp_unit *unit, *u;
111  LIST_HEAD(unit_remove_lh);
112  LIST_HEAD(port_remove_lh);
113 
115 
116  adapter = zfcp_ccw_adapter_by_cdev(cdev);
117  if (!adapter)
118  return;
119 
120  write_lock_irq(&adapter->port_list_lock);
121  list_for_each_entry_safe(port, p, &adapter->port_list, list) {
122  write_lock(&port->unit_list_lock);
123  list_for_each_entry_safe(unit, u, &port->unit_list, list)
124  list_move(&unit->list, &unit_remove_lh);
125  write_unlock(&port->unit_list_lock);
126  list_move(&port->list, &port_remove_lh);
127  }
128  write_unlock_irq(&adapter->port_list_lock);
129  zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
130 
131  list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
133 
134  list_for_each_entry_safe(port, p, &port_remove_lh, list)
136 
137  zfcp_adapter_unregister(adapter);
138 }
139 
153 static int zfcp_ccw_set_online(struct ccw_device *cdev)
154 {
155  struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
156 
157  if (!adapter) {
158  adapter = zfcp_adapter_enqueue(cdev);
159 
160  if (IS_ERR(adapter)) {
161  dev_err(&cdev->dev,
162  "Setting up data structures for the "
163  "FCP adapter failed\n");
164  return PTR_ERR(adapter);
165  }
166  kref_get(&adapter->ref);
167  }
168 
169  /* initialize request counter */
170  BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
171  adapter->req_no = 0;
172 
173  zfcp_ccw_activate(cdev, 0, "ccsonl1");
174  /* scan for remote ports
175  either at the end of any successful adapter recovery
176  or only after the adapter recovery for setting a device online */
178  flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
179  zfcp_ccw_adapter_put(adapter);
180  return 0;
181 }
182 
192 static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
193 {
194  struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
195 
196  if (!adapter)
197  return 0;
198 
199  zfcp_erp_set_adapter_status(adapter, set);
200  zfcp_erp_adapter_shutdown(adapter, 0, tag);
201  zfcp_erp_wait(adapter);
202 
203  zfcp_ccw_adapter_put(adapter);
204  return 0;
205 }
206 
214 static int zfcp_ccw_set_offline(struct ccw_device *cdev)
215 {
216  return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
217 }
218 
227 static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
228 {
229  struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
230 
231  if (!adapter)
232  return 1;
233 
234  switch (event) {
235  case CIO_GONE:
236  if (atomic_read(&adapter->status) &
237  ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
238  zfcp_dbf_hba_basic("ccnigo1", adapter);
239  break;
240  }
241  dev_warn(&cdev->dev, "The FCP device has been detached\n");
242  zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
243  break;
244  case CIO_NO_PATH:
245  dev_warn(&cdev->dev,
246  "The CHPID for the FCP device is offline\n");
247  zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
248  break;
249  case CIO_OPER:
250  if (atomic_read(&adapter->status) &
251  ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
252  zfcp_dbf_hba_basic("ccniop1", adapter);
253  break;
254  }
255  dev_info(&cdev->dev, "The FCP device is operational again\n");
259  "ccnoti4");
260  break;
261  case CIO_BOXED:
262  dev_warn(&cdev->dev, "The FCP device did not respond within "
263  "the specified time\n");
264  zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
265  break;
266  }
267 
268  zfcp_ccw_adapter_put(adapter);
269  return 1;
270 }
271 
276 static void zfcp_ccw_shutdown(struct ccw_device *cdev)
277 {
278  struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
279 
280  if (!adapter)
281  return;
282 
283  zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
284  zfcp_erp_wait(adapter);
285  zfcp_erp_thread_kill(adapter);
286 
287  zfcp_ccw_adapter_put(adapter);
288 }
289 
290 static int zfcp_ccw_suspend(struct ccw_device *cdev)
291 {
292  zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
293  return 0;
294 }
295 
296 static int zfcp_ccw_thaw(struct ccw_device *cdev)
297 {
298  /* trace records for thaw and final shutdown during suspend
299  can only be found in system dump until the end of suspend
300  but not after resume because it's based on the memory image
301  right after the very first suspend (freeze) callback */
302  zfcp_ccw_activate(cdev, 0, "ccthaw1");
303  return 0;
304 }
305 
306 static int zfcp_ccw_resume(struct ccw_device *cdev)
307 {
308  zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
309  return 0;
310 }
311 
313  .driver = {
314  .owner = THIS_MODULE,
315  .name = "zfcp",
316  },
317  .ids = zfcp_ccw_device_id,
318  .probe = zfcp_ccw_probe,
319  .remove = zfcp_ccw_remove,
320  .set_online = zfcp_ccw_set_online,
321  .set_offline = zfcp_ccw_set_offline,
322  .notify = zfcp_ccw_notify,
323  .shutdown = zfcp_ccw_shutdown,
324  .freeze = zfcp_ccw_suspend,
325  .thaw = zfcp_ccw_thaw,
326  .restore = zfcp_ccw_resume,
327 };