aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_ccw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_ccw.c')
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 51b6a05f4d12..b04038c74786 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -25,7 +25,8 @@ static int zfcp_ccw_probe(struct ccw_device *ccw_device)
25 down(&zfcp_data.config_sema); 25 down(&zfcp_data.config_sema);
26 if (zfcp_adapter_enqueue(ccw_device)) { 26 if (zfcp_adapter_enqueue(ccw_device)) {
27 dev_err(&ccw_device->dev, 27 dev_err(&ccw_device->dev,
28 "Setup of data structures failed.\n"); 28 "Setting up data structures for the "
29 "FCP adapter failed\n");
29 retval = -EINVAL; 30 retval = -EINVAL;
30 } 31 }
31 up(&zfcp_data.config_sema); 32 up(&zfcp_data.config_sema);
@@ -46,6 +47,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
46 struct zfcp_adapter *adapter; 47 struct zfcp_adapter *adapter;
47 struct zfcp_port *port, *p; 48 struct zfcp_port *port, *p;
48 struct zfcp_unit *unit, *u; 49 struct zfcp_unit *unit, *u;
50 LIST_HEAD(unit_remove_lh);
51 LIST_HEAD(port_remove_lh);
49 52
50 ccw_device_set_offline(ccw_device); 53 ccw_device_set_offline(ccw_device);
51 down(&zfcp_data.config_sema); 54 down(&zfcp_data.config_sema);
@@ -54,26 +57,26 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
54 write_lock_irq(&zfcp_data.config_lock); 57 write_lock_irq(&zfcp_data.config_lock);
55 list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { 58 list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
56 list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { 59 list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
57 list_move(&unit->list, &port->unit_remove_lh); 60 list_move(&unit->list, &unit_remove_lh);
58 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, 61 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
59 &unit->status); 62 &unit->status);
60 } 63 }
61 list_move(&port->list, &adapter->port_remove_lh); 64 list_move(&port->list, &port_remove_lh);
62 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 65 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
63 } 66 }
64 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); 67 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
65 write_unlock_irq(&zfcp_data.config_lock); 68 write_unlock_irq(&zfcp_data.config_lock);
66 69
67 list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) { 70 list_for_each_entry_safe(port, p, &port_remove_lh, list) {
68 list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) { 71 list_for_each_entry_safe(unit, u, &unit_remove_lh, list) {
69 if (atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED, 72 if (atomic_read(&unit->status) &
70 &unit->status)) 73 ZFCP_STATUS_UNIT_REGISTERED)
71 scsi_remove_device(unit->device); 74 scsi_remove_device(unit->device);
72 zfcp_unit_dequeue(unit); 75 zfcp_unit_dequeue(unit);
73 } 76 }
74 zfcp_port_dequeue(port); 77 zfcp_port_dequeue(port);
75 } 78 }
76 zfcp_adapter_wait(adapter); 79 wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
77 zfcp_adapter_dequeue(adapter); 80 zfcp_adapter_dequeue(adapter);
78 81
79 up(&zfcp_data.config_sema); 82 up(&zfcp_data.config_sema);
@@ -156,15 +159,18 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
156 159
157 switch (event) { 160 switch (event) {
158 case CIO_GONE: 161 case CIO_GONE:
159 dev_warn(&adapter->ccw_device->dev, "device gone\n"); 162 dev_warn(&adapter->ccw_device->dev,
163 "The FCP device has been detached\n");
160 zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); 164 zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
161 break; 165 break;
162 case CIO_NO_PATH: 166 case CIO_NO_PATH:
163 dev_warn(&adapter->ccw_device->dev, "no path\n"); 167 dev_warn(&adapter->ccw_device->dev,
168 "The CHPID for the FCP device is offline\n");
164 zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); 169 zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
165 break; 170 break;
166 case CIO_OPER: 171 case CIO_OPER:
167 dev_info(&adapter->ccw_device->dev, "operational again\n"); 172 dev_info(&adapter->ccw_device->dev,
173 "The FCP device is operational again\n");
168 zfcp_erp_modify_adapter_status(adapter, 11, NULL, 174 zfcp_erp_modify_adapter_status(adapter, 11, NULL,
169 ZFCP_STATUS_COMMON_RUNNING, 175 ZFCP_STATUS_COMMON_RUNNING,
170 ZFCP_SET); 176 ZFCP_SET);
@@ -220,3 +226,20 @@ int __init zfcp_ccw_register(void)
220{ 226{
221 return ccw_driver_register(&zfcp_ccw_driver); 227 return ccw_driver_register(&zfcp_ccw_driver);
222} 228}
229
230/**
231 * zfcp_get_adapter_by_busid - find zfcp_adapter struct
232 * @busid: bus id string of zfcp adapter to find
233 */
234struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid)
235{
236 struct ccw_device *ccw_device;
237 struct zfcp_adapter *adapter = NULL;
238
239 ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
240 if (ccw_device) {
241 adapter = dev_get_drvdata(&ccw_device->dev);
242 put_device(&ccw_device->dev);
243 }
244 return adapter;
245}