[SCSI] zfcp: cleanup port sysfs attribute usage
[deliverable/linux.git] / drivers / s390 / scsi / zfcp_ccw.c
CommitLineData
1da177e4 1/*
fa04c281 2 * zfcp device driver
1da177e4 3 *
fa04c281 4 * Registration and callback for the s390 common I/O layer.
1da177e4 5 *
a53c8fab 6 * Copyright IBM Corp. 2002, 2010
1da177e4
LT
7 */
8
ecf39d42
CS
9#define KMSG_COMPONENT "zfcp"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11
3a4c5d59 12#include <linux/module.h>
1da177e4 13#include "zfcp_ext.h"
b6bd2fb9 14#include "zfcp_reqlist.h"
1da177e4 15
6fcf41d1
CS
16#define ZFCP_MODEL_PRIV 0x4
17
de3dc572
SS
18static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
19
20struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
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
33void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
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
cb452149
SM
42/**
43 * zfcp_ccw_activate - activate adapter and wait for it to finish
44 * @cdev: pointer to belonging ccw device
45 * @clear: Status flags to clear.
46 * @tag: s390dbf trace record tag
47 */
48static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
daa70fa9 49{
de3dc572 50 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
daa70fa9 51
143bb6bf
CS
52 if (!adapter)
53 return 0;
54
cb452149 55 zfcp_erp_clear_adapter_status(adapter, clear);
edaed859 56 zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
daa70fa9 57 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
cb452149 58 tag);
daa70fa9 59 zfcp_erp_wait(adapter);
43f60cbd 60 flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
daa70fa9 61
de3dc572
SS
62 zfcp_ccw_adapter_put(adapter);
63
daa70fa9
MP
64 return 0;
65}
66
6fcf41d1
CS
67static 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};
72MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
73
74/**
75 * zfcp_ccw_priv_sch - check if subchannel is privileged
76 * @adapter: Adapter/Subchannel to check
77 */
78int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
79{
80 return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV;
81}
82
1da177e4
LT
83/**
84 * zfcp_ccw_probe - probe function of zfcp driver
de3dc572 85 * @cdev: pointer to belonging ccw device
1da177e4 86 *
143bb6bf
CS
87 * This function gets called by the common i/o layer for each FCP
88 * device found on the current system. This is only a stub to make cio
89 * work: To only allocate adapter resources for devices actually used,
90 * the allocation is deferred to the first call to ccw_set_online.
1da177e4 91 */
de3dc572 92static int zfcp_ccw_probe(struct ccw_device *cdev)
1da177e4 93{
143bb6bf 94 return 0;
1da177e4
LT
95}
96
97/**
98 * zfcp_ccw_remove - remove function of zfcp driver
de3dc572 99 * @cdev: pointer to belonging ccw device
1da177e4
LT
100 *
101 * This function gets called by the common i/o layer and removes an adapter
102 * from the system. Task of this function is to get rid of all units and
103 * ports that belong to this adapter. And in addition all resources of this
104 * adapter will be freed too.
105 */
de3dc572 106static void zfcp_ccw_remove(struct ccw_device *cdev)
1da177e4
LT
107{
108 struct zfcp_adapter *adapter;
109 struct zfcp_port *port, *p;
110 struct zfcp_unit *unit, *u;
0406289e
CS
111 LIST_HEAD(unit_remove_lh);
112 LIST_HEAD(port_remove_lh);
1da177e4 113
de3dc572 114 ccw_device_set_offline(cdev);
f45a5421 115
de3dc572 116 adapter = zfcp_ccw_adapter_by_cdev(cdev);
ecf0c772
SS
117 if (!adapter)
118 return;
119
ecf0c772
SS
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);
6b183334 123 list_for_each_entry_safe(unit, u, &port->unit_list, list)
ecf0c772 124 list_move(&unit->list, &unit_remove_lh);
ecf0c772 125 write_unlock(&port->unit_list_lock);
ecf0c772 126 list_move(&port->list, &port_remove_lh);
1da177e4 127 }
ecf0c772 128 write_unlock_irq(&adapter->port_list_lock);
de3dc572 129 zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
1da177e4 130
f3450c7b 131 list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
615f59e0 132 zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
f3450c7b
SS
133
134 list_for_each_entry_safe(port, p, &port_remove_lh, list)
83d4e1c3 135 device_unregister(&port->dev);
f3450c7b 136
de3dc572 137 zfcp_adapter_unregister(adapter);
1da177e4
LT
138}
139
140/**
141 * zfcp_ccw_set_online - set_online function of zfcp driver
de3dc572 142 * @cdev: pointer to belonging ccw device
1da177e4 143 *
143bb6bf
CS
144 * This function gets called by the common i/o layer and sets an
145 * adapter into state online. The first call will allocate all
146 * adapter resources that will be retained until the device is removed
147 * via zfcp_ccw_remove.
148 *
149 * Setting an fcp device online means that it will be registered with
150 * the SCSI stack, that the QDIO queues will be set up and that the
151 * adapter will be opened.
1da177e4 152 */
de3dc572 153static int zfcp_ccw_set_online(struct ccw_device *cdev)
1da177e4 154{
de3dc572 155 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
1da177e4 156
143bb6bf 157 if (!adapter) {
de3dc572
SS
158 adapter = zfcp_adapter_enqueue(cdev);
159
160 if (IS_ERR(adapter)) {
161 dev_err(&cdev->dev,
143bb6bf
CS
162 "Setting up data structures for the "
163 "FCP adapter failed\n");
de3dc572 164 return PTR_ERR(adapter);
143bb6bf 165 }
de3dc572 166 kref_get(&adapter->ref);
143bb6bf 167 }
1da177e4 168
fea9d6c7 169 /* initialize request counter */
b6bd2fb9 170 BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
fea9d6c7
VS
171 adapter->req_no = 0;
172
cb452149 173 zfcp_ccw_activate(cdev, 0, "ccsonl1");
43f60cbd
SM
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 */
177 zfcp_fc_inverse_conditional_port_scan(adapter);
178 flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
de3dc572
SS
179 zfcp_ccw_adapter_put(adapter);
180 return 0;
1da177e4
LT
181}
182
183/**
cb452149 184 * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
de3dc572 185 * @cdev: pointer to belonging ccw device
cb452149
SM
186 * @set: Status flags to set.
187 * @tag: s390dbf trace record tag
1da177e4
LT
188 *
189 * This function gets called by the common i/o layer and sets an adapter
9f28745a 190 * into state offline.
1da177e4 191 */
cb452149 192static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
1da177e4 193{
de3dc572
SS
194 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
195
196 if (!adapter)
197 return 0;
1da177e4 198
cb452149
SM
199 zfcp_erp_set_adapter_status(adapter, set);
200 zfcp_erp_adapter_shutdown(adapter, 0, tag);
1da177e4 201 zfcp_erp_wait(adapter);
de3dc572
SS
202
203 zfcp_ccw_adapter_put(adapter);
1da177e4
LT
204 return 0;
205}
206
cb452149
SM
207/**
208 * zfcp_ccw_set_offline - set_offline function of zfcp driver
209 * @cdev: pointer to belonging ccw device
210 *
211 * This function gets called by the common i/o layer and sets an adapter
212 * into state offline.
213 */
214static int zfcp_ccw_set_offline(struct ccw_device *cdev)
215{
216 return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
217}
218
1da177e4 219/**
fa04c281 220 * zfcp_ccw_notify - ccw notify function
de3dc572 221 * @cdev: pointer to belonging ccw device
1da177e4
LT
222 * @event: indicates if adapter was detached or attached
223 *
224 * This function gets called by the common i/o layer if an adapter has gone
225 * or reappeared.
226 */
de3dc572 227static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
1da177e4 228{
de3dc572
SS
229 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
230
231 if (!adapter)
232 return 1;
1da177e4 233
1da177e4
LT
234 switch (event) {
235 case CIO_GONE:
cb452149
SM
236 if (atomic_read(&adapter->status) &
237 ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
238 zfcp_dbf_hba_basic("ccnigo1", adapter);
239 break;
240 }
de3dc572 241 dev_warn(&cdev->dev, "The FCP device has been detached\n");
ea4a3a6a 242 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
1da177e4
LT
243 break;
244 case CIO_NO_PATH:
de3dc572 245 dev_warn(&cdev->dev,
ff3b24fa 246 "The CHPID for the FCP device is offline\n");
ea4a3a6a 247 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
1da177e4
LT
248 break;
249 case CIO_OPER:
cb452149
SM
250 if (atomic_read(&adapter->status) &
251 ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
252 zfcp_dbf_hba_basic("ccniop1", adapter);
253 break;
254 }
de3dc572 255 dev_info(&cdev->dev, "The FCP device is operational again\n");
edaed859
SS
256 zfcp_erp_set_adapter_status(adapter,
257 ZFCP_STATUS_COMMON_RUNNING);
1f6f7129 258 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
ea4a3a6a 259 "ccnoti4");
1da177e4 260 break;
47593bfa 261 case CIO_BOXED:
de3dc572
SS
262 dev_warn(&cdev->dev, "The FCP device did not respond within "
263 "the specified time\n");
ea4a3a6a 264 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
47593bfa 265 break;
1da177e4 266 }
de3dc572
SS
267
268 zfcp_ccw_adapter_put(adapter);
1da177e4
LT
269 return 1;
270}
271
272/**
fa04c281
CS
273 * zfcp_ccw_shutdown - handle shutdown from cio
274 * @cdev: device for adapter to shutdown.
1da177e4 275 */
fa04c281 276static void zfcp_ccw_shutdown(struct ccw_device *cdev)
1da177e4 277{
de3dc572 278 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
1da177e4 279
1f99bd4c 280 if (!adapter)
de3dc572 281 return;
1f99bd4c 282
ea4a3a6a 283 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
1da177e4 284 zfcp_erp_wait(adapter);
143bb6bf 285 zfcp_erp_thread_kill(adapter);
de3dc572
SS
286
287 zfcp_ccw_adapter_put(adapter);
1da177e4
LT
288}
289
cb452149
SM
290static 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
296static 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
306static int zfcp_ccw_resume(struct ccw_device *cdev)
307{
308 zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
309 return 0;
310}
311
c5afd81e 312struct ccw_driver zfcp_ccw_driver = {
3bda058b
SO
313 .driver = {
314 .owner = THIS_MODULE,
315 .name = "zfcp",
316 },
fa04c281
CS
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,
cb452149
SM
324 .freeze = zfcp_ccw_suspend,
325 .thaw = zfcp_ccw_thaw,
326 .restore = zfcp_ccw_resume,
fa04c281 327};
This page took 0.684062 seconds and 5 git commands to generate.