aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_alias.c
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2009-12-07 06:51:53 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2009-12-07 06:51:35 -0500
commitf4ac1d0255748fe0f8e128a26b1c29490cae5c08 (patch)
tree2e5e9c31f32194c1042440bce54301e86125f142 /drivers/s390/block/dasd_alias.c
parentb8ed5dd54895647c2690575aad6f07748c2c618a (diff)
[S390] dasd: let device initialization wait for LCU setup
The first DASD that is set online for a specific logical control unit has to do certain setup steps on the storage server to make full use of it, for example it will enable PAV. The features and characteristics reported by the storage server will depend on this setup, so all other devices on the same LCU will need to wait for the setup to be finished. Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_alias.c')
-rw-r--r--drivers/s390/block/dasd_alias.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index cdc6c049c353..fd1231738ef4 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -152,6 +152,7 @@ static struct alias_lcu *_allocate_lcu(struct dasd_uid *uid)
152 INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work); 152 INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
153 INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work); 153 INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
154 spin_lock_init(&lcu->lock); 154 spin_lock_init(&lcu->lock);
155 init_completion(&lcu->lcu_setup);
155 return lcu; 156 return lcu;
156 157
157out_err4: 158out_err4:
@@ -240,6 +241,67 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
240} 241}
241 242
242/* 243/*
244 * The first device to be registered on an LCU will have to do
245 * some additional setup steps to configure that LCU on the
246 * storage server. All further devices should wait with their
247 * initialization until the first device is done.
248 * To synchronize this work, the first device will call
249 * dasd_alias_lcu_setup_complete when it is done, and all
250 * other devices will wait for it with dasd_alias_wait_for_lcu_setup.
251 */
252void dasd_alias_lcu_setup_complete(struct dasd_device *device)
253{
254 struct dasd_eckd_private *private;
255 unsigned long flags;
256 struct alias_server *server;
257 struct alias_lcu *lcu;
258 struct dasd_uid *uid;
259
260 private = (struct dasd_eckd_private *) device->private;
261 uid = &private->uid;
262 lcu = NULL;
263 spin_lock_irqsave(&aliastree.lock, flags);
264 server = _find_server(uid);
265 if (server)
266 lcu = _find_lcu(server, uid);
267 spin_unlock_irqrestore(&aliastree.lock, flags);
268 if (!lcu) {
269 DBF_EVENT_DEVID(DBF_ERR, device->cdev,
270 "could not find lcu for %04x %02x",
271 uid->ssid, uid->real_unit_addr);
272 WARN_ON(1);
273 return;
274 }
275 complete_all(&lcu->lcu_setup);
276}
277
278void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
279{
280 struct dasd_eckd_private *private;
281 unsigned long flags;
282 struct alias_server *server;
283 struct alias_lcu *lcu;
284 struct dasd_uid *uid;
285
286 private = (struct dasd_eckd_private *) device->private;
287 uid = &private->uid;
288 lcu = NULL;
289 spin_lock_irqsave(&aliastree.lock, flags);
290 server = _find_server(uid);
291 if (server)
292 lcu = _find_lcu(server, uid);
293 spin_unlock_irqrestore(&aliastree.lock, flags);
294 if (!lcu) {
295 DBF_EVENT_DEVID(DBF_ERR, device->cdev,
296 "could not find lcu for %04x %02x",
297 uid->ssid, uid->real_unit_addr);
298 WARN_ON(1);
299 return;
300 }
301 wait_for_completion(&lcu->lcu_setup);
302}
303
304/*
243 * This function removes a device from the scope of alias management. 305 * This function removes a device from the scope of alias management.
244 * The complicated part is to make sure that it is not in use by 306 * The complicated part is to make sure that it is not in use by
245 * any of the workers. If necessary cancel the work. 307 * any of the workers. If necessary cancel the work.