diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_ccw.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 152 |
1 files changed, 50 insertions, 102 deletions
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 66d3b88844b0..391dd29749f8 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -1,64 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * This file is part of the zfcp device driver for | 2 | * zfcp device driver |
3 | * FCP adapters for IBM System z9 and zSeries. | ||
4 | * | 3 | * |
5 | * (C) Copyright IBM Corp. 2002, 2006 | 4 | * Registration and callback for the s390 common I/O layer. |
6 | * | 5 | * |
7 | * This program is free software; you can redistribute it and/or modify | 6 | * Copyright IBM Corporation 2002, 2008 |
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | 7 | */ |
21 | 8 | ||
22 | #include "zfcp_ext.h" | 9 | #include "zfcp_ext.h" |
23 | 10 | ||
24 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG | ||
25 | |||
26 | static int zfcp_ccw_probe(struct ccw_device *); | ||
27 | static void zfcp_ccw_remove(struct ccw_device *); | ||
28 | static int zfcp_ccw_set_online(struct ccw_device *); | ||
29 | static int zfcp_ccw_set_offline(struct ccw_device *); | ||
30 | static int zfcp_ccw_notify(struct ccw_device *, int); | ||
31 | static void zfcp_ccw_shutdown(struct ccw_device *); | ||
32 | |||
33 | static struct ccw_device_id zfcp_ccw_device_id[] = { | ||
34 | {CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE, | ||
35 | ZFCP_CONTROL_UNIT_MODEL, | ||
36 | ZFCP_DEVICE_TYPE, | ||
37 | ZFCP_DEVICE_MODEL)}, | ||
38 | {CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE, | ||
39 | ZFCP_CONTROL_UNIT_MODEL, | ||
40 | ZFCP_DEVICE_TYPE, | ||
41 | ZFCP_DEVICE_MODEL_PRIV)}, | ||
42 | {}, | ||
43 | }; | ||
44 | |||
45 | static struct ccw_driver zfcp_ccw_driver = { | ||
46 | .owner = THIS_MODULE, | ||
47 | .name = ZFCP_NAME, | ||
48 | .ids = zfcp_ccw_device_id, | ||
49 | .probe = zfcp_ccw_probe, | ||
50 | .remove = zfcp_ccw_remove, | ||
51 | .set_online = zfcp_ccw_set_online, | ||
52 | .set_offline = zfcp_ccw_set_offline, | ||
53 | .notify = zfcp_ccw_notify, | ||
54 | .shutdown = zfcp_ccw_shutdown, | ||
55 | .driver = { | ||
56 | .groups = zfcp_driver_attr_groups, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); | ||
61 | |||
62 | /** | 11 | /** |
63 | * zfcp_ccw_probe - probe function of zfcp driver | 12 | * zfcp_ccw_probe - probe function of zfcp driver |
64 | * @ccw_device: pointer to belonging ccw device | 13 | * @ccw_device: pointer to belonging ccw device |
@@ -69,19 +18,16 @@ MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); | |||
69 | * In addition the nameserver port will be added to the ports of the adapter | 18 | * In addition the nameserver port will be added to the ports of the adapter |
70 | * and its sysfs representation will be created too. | 19 | * and its sysfs representation will be created too. |
71 | */ | 20 | */ |
72 | static int | 21 | static int zfcp_ccw_probe(struct ccw_device *ccw_device) |
73 | zfcp_ccw_probe(struct ccw_device *ccw_device) | ||
74 | { | 22 | { |
75 | struct zfcp_adapter *adapter; | ||
76 | int retval = 0; | 23 | int retval = 0; |
77 | 24 | ||
78 | down(&zfcp_data.config_sema); | 25 | down(&zfcp_data.config_sema); |
79 | adapter = zfcp_adapter_enqueue(ccw_device); | 26 | if (zfcp_adapter_enqueue(ccw_device)) { |
80 | if (!adapter) | 27 | dev_err(&ccw_device->dev, |
28 | "Setup of data structures failed.\n"); | ||
81 | retval = -EINVAL; | 29 | retval = -EINVAL; |
82 | else | 30 | } |
83 | ZFCP_LOG_DEBUG("Probed adapter %s\n", | ||
84 | zfcp_get_busid_by_adapter(adapter)); | ||
85 | up(&zfcp_data.config_sema); | 31 | up(&zfcp_data.config_sema); |
86 | return retval; | 32 | return retval; |
87 | } | 33 | } |
@@ -95,8 +41,7 @@ zfcp_ccw_probe(struct ccw_device *ccw_device) | |||
95 | * ports that belong to this adapter. And in addition all resources of this | 41 | * ports that belong to this adapter. And in addition all resources of this |
96 | * adapter will be freed too. | 42 | * adapter will be freed too. |
97 | */ | 43 | */ |
98 | static void | 44 | static void zfcp_ccw_remove(struct ccw_device *ccw_device) |
99 | zfcp_ccw_remove(struct ccw_device *ccw_device) | ||
100 | { | 45 | { |
101 | struct zfcp_adapter *adapter; | 46 | struct zfcp_adapter *adapter; |
102 | struct zfcp_port *port, *p; | 47 | struct zfcp_port *port, *p; |
@@ -106,8 +51,6 @@ zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
106 | down(&zfcp_data.config_sema); | 51 | down(&zfcp_data.config_sema); |
107 | adapter = dev_get_drvdata(&ccw_device->dev); | 52 | adapter = dev_get_drvdata(&ccw_device->dev); |
108 | 53 | ||
109 | ZFCP_LOG_DEBUG("Removing adapter %s\n", | ||
110 | zfcp_get_busid_by_adapter(adapter)); | ||
111 | write_lock_irq(&zfcp_data.config_lock); | 54 | write_lock_irq(&zfcp_data.config_lock); |
112 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { | 55 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { |
113 | list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { | 56 | list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { |
@@ -145,8 +88,7 @@ zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
145 | * registered with the SCSI stack, that the QDIO queues will be set up | 88 | * registered with the SCSI stack, that the QDIO queues will be set up |
146 | * and that the adapter will be opened (asynchronously). | 89 | * and that the adapter will be opened (asynchronously). |
147 | */ | 90 | */ |
148 | static int | 91 | static int zfcp_ccw_set_online(struct ccw_device *ccw_device) |
149 | zfcp_ccw_set_online(struct ccw_device *ccw_device) | ||
150 | { | 92 | { |
151 | struct zfcp_adapter *adapter; | 93 | struct zfcp_adapter *adapter; |
152 | int retval; | 94 | int retval; |
@@ -155,12 +97,8 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) | |||
155 | adapter = dev_get_drvdata(&ccw_device->dev); | 97 | adapter = dev_get_drvdata(&ccw_device->dev); |
156 | 98 | ||
157 | retval = zfcp_erp_thread_setup(adapter); | 99 | retval = zfcp_erp_thread_setup(adapter); |
158 | if (retval) { | 100 | if (retval) |
159 | ZFCP_LOG_INFO("error: start of error recovery thread for " | ||
160 | "adapter %s failed\n", | ||
161 | zfcp_get_busid_by_adapter(adapter)); | ||
162 | goto out; | 101 | goto out; |
163 | } | ||
164 | 102 | ||
165 | retval = zfcp_adapter_scsi_register(adapter); | 103 | retval = zfcp_adapter_scsi_register(adapter); |
166 | if (retval) | 104 | if (retval) |
@@ -191,8 +129,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) | |||
191 | * This function gets called by the common i/o layer and sets an adapter | 129 | * This function gets called by the common i/o layer and sets an adapter |
192 | * into state offline. | 130 | * into state offline. |
193 | */ | 131 | */ |
194 | static int | 132 | static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) |
195 | zfcp_ccw_set_offline(struct ccw_device *ccw_device) | ||
196 | { | 133 | { |
197 | struct zfcp_adapter *adapter; | 134 | struct zfcp_adapter *adapter; |
198 | 135 | ||
@@ -206,15 +143,14 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device) | |||
206 | } | 143 | } |
207 | 144 | ||
208 | /** | 145 | /** |
209 | * zfcp_ccw_notify | 146 | * zfcp_ccw_notify - ccw notify function |
210 | * @ccw_device: pointer to belonging ccw device | 147 | * @ccw_device: pointer to belonging ccw device |
211 | * @event: indicates if adapter was detached or attached | 148 | * @event: indicates if adapter was detached or attached |
212 | * | 149 | * |
213 | * This function gets called by the common i/o layer if an adapter has gone | 150 | * This function gets called by the common i/o layer if an adapter has gone |
214 | * or reappeared. | 151 | * or reappeared. |
215 | */ | 152 | */ |
216 | static int | 153 | static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) |
217 | zfcp_ccw_notify(struct ccw_device *ccw_device, int event) | ||
218 | { | 154 | { |
219 | struct zfcp_adapter *adapter; | 155 | struct zfcp_adapter *adapter; |
220 | 156 | ||
@@ -222,18 +158,15 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event) | |||
222 | adapter = dev_get_drvdata(&ccw_device->dev); | 158 | adapter = dev_get_drvdata(&ccw_device->dev); |
223 | switch (event) { | 159 | switch (event) { |
224 | case CIO_GONE: | 160 | case CIO_GONE: |
225 | ZFCP_LOG_NORMAL("adapter %s: device gone\n", | 161 | dev_warn(&adapter->ccw_device->dev, "device gone\n"); |
226 | zfcp_get_busid_by_adapter(adapter)); | ||
227 | zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); | 162 | zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); |
228 | break; | 163 | break; |
229 | case CIO_NO_PATH: | 164 | case CIO_NO_PATH: |
230 | ZFCP_LOG_NORMAL("adapter %s: no path\n", | 165 | dev_warn(&adapter->ccw_device->dev, "no path\n"); |
231 | zfcp_get_busid_by_adapter(adapter)); | ||
232 | zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); | 166 | zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); |
233 | break; | 167 | break; |
234 | case CIO_OPER: | 168 | case CIO_OPER: |
235 | ZFCP_LOG_NORMAL("adapter %s: operational again\n", | 169 | dev_info(&adapter->ccw_device->dev, "operational again\n"); |
236 | zfcp_get_busid_by_adapter(adapter)); | ||
237 | zfcp_erp_modify_adapter_status(adapter, 11, NULL, | 170 | zfcp_erp_modify_adapter_status(adapter, 11, NULL, |
238 | ZFCP_STATUS_COMMON_RUNNING, | 171 | ZFCP_STATUS_COMMON_RUNNING, |
239 | ZFCP_SET); | 172 | ZFCP_SET); |
@@ -247,24 +180,10 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event) | |||
247 | } | 180 | } |
248 | 181 | ||
249 | /** | 182 | /** |
250 | * zfcp_ccw_register - ccw register function | 183 | * zfcp_ccw_shutdown - handle shutdown from cio |
251 | * | 184 | * @cdev: device for adapter to shutdown. |
252 | * Registers the driver at the common i/o layer. This function will be called | ||
253 | * at module load time/system start. | ||
254 | */ | ||
255 | int __init | ||
256 | zfcp_ccw_register(void) | ||
257 | { | ||
258 | return ccw_driver_register(&zfcp_ccw_driver); | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * zfcp_ccw_shutdown - gets called on reboot/shutdown | ||
263 | * | ||
264 | * Makes sure that QDIO queues are down when the system gets stopped. | ||
265 | */ | 185 | */ |
266 | static void | 186 | static void zfcp_ccw_shutdown(struct ccw_device *cdev) |
267 | zfcp_ccw_shutdown(struct ccw_device *cdev) | ||
268 | { | 187 | { |
269 | struct zfcp_adapter *adapter; | 188 | struct zfcp_adapter *adapter; |
270 | 189 | ||
@@ -275,4 +194,33 @@ zfcp_ccw_shutdown(struct ccw_device *cdev) | |||
275 | up(&zfcp_data.config_sema); | 194 | up(&zfcp_data.config_sema); |
276 | } | 195 | } |
277 | 196 | ||
278 | #undef ZFCP_LOG_AREA | 197 | static struct ccw_device_id zfcp_ccw_device_id[] = { |
198 | { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, | ||
199 | { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x4) }, /* priv. */ | ||
200 | {}, | ||
201 | }; | ||
202 | |||
203 | MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); | ||
204 | |||
205 | static struct ccw_driver zfcp_ccw_driver = { | ||
206 | .owner = THIS_MODULE, | ||
207 | .name = "zfcp", | ||
208 | .ids = zfcp_ccw_device_id, | ||
209 | .probe = zfcp_ccw_probe, | ||
210 | .remove = zfcp_ccw_remove, | ||
211 | .set_online = zfcp_ccw_set_online, | ||
212 | .set_offline = zfcp_ccw_set_offline, | ||
213 | .notify = zfcp_ccw_notify, | ||
214 | .shutdown = zfcp_ccw_shutdown, | ||
215 | }; | ||
216 | |||
217 | /** | ||
218 | * zfcp_ccw_register - ccw register function | ||
219 | * | ||
220 | * Registers the driver at the common i/o layer. This function will be called | ||
221 | * at module load time/system start. | ||
222 | */ | ||
223 | int __init zfcp_ccw_register(void) | ||
224 | { | ||
225 | return ccw_driver_register(&zfcp_ccw_driver); | ||
226 | } | ||