0001
0002
0003
0004
0005
0006
0007
0008
0009 #define KMSG_COMPONENT "dasd-eckd"
0010
0011 #include <linux/list.h>
0012 #include <linux/slab.h>
0013 #include <asm/ebcdic.h>
0014 #include "dasd_int.h"
0015 #include "dasd_eckd.h"
0016
0017 #ifdef PRINTK_HEADER
0018 #undef PRINTK_HEADER
0019 #endif
0020 #define PRINTK_HEADER "dasd(eckd):"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 static void summary_unit_check_handling_work(struct work_struct *);
0045 static void lcu_update_work(struct work_struct *);
0046 static int _schedule_lcu_update(struct alias_lcu *, struct dasd_device *);
0047
0048 static struct alias_root aliastree = {
0049 .serverlist = LIST_HEAD_INIT(aliastree.serverlist),
0050 .lock = __SPIN_LOCK_UNLOCKED(aliastree.lock),
0051 };
0052
0053 static struct alias_server *_find_server(struct dasd_uid *uid)
0054 {
0055 struct alias_server *pos;
0056 list_for_each_entry(pos, &aliastree.serverlist, server) {
0057 if (!strncmp(pos->uid.vendor, uid->vendor,
0058 sizeof(uid->vendor))
0059 && !strncmp(pos->uid.serial, uid->serial,
0060 sizeof(uid->serial)))
0061 return pos;
0062 }
0063 return NULL;
0064 }
0065
0066 static struct alias_lcu *_find_lcu(struct alias_server *server,
0067 struct dasd_uid *uid)
0068 {
0069 struct alias_lcu *pos;
0070 list_for_each_entry(pos, &server->lculist, lcu) {
0071 if (pos->uid.ssid == uid->ssid)
0072 return pos;
0073 }
0074 return NULL;
0075 }
0076
0077 static struct alias_pav_group *_find_group(struct alias_lcu *lcu,
0078 struct dasd_uid *uid)
0079 {
0080 struct alias_pav_group *pos;
0081 __u8 search_unit_addr;
0082
0083
0084 if (lcu->pav == HYPER_PAV) {
0085 if (list_empty(&lcu->grouplist))
0086 return NULL;
0087 else
0088 return list_first_entry(&lcu->grouplist,
0089 struct alias_pav_group, group);
0090 }
0091
0092
0093 if (uid->type == UA_BASE_DEVICE)
0094 search_unit_addr = uid->real_unit_addr;
0095 else
0096 search_unit_addr = uid->base_unit_addr;
0097 list_for_each_entry(pos, &lcu->grouplist, group) {
0098 if (pos->uid.base_unit_addr == search_unit_addr &&
0099 !strncmp(pos->uid.vduit, uid->vduit, sizeof(uid->vduit)))
0100 return pos;
0101 }
0102 return NULL;
0103 }
0104
0105 static struct alias_server *_allocate_server(struct dasd_uid *uid)
0106 {
0107 struct alias_server *server;
0108
0109 server = kzalloc(sizeof(*server), GFP_KERNEL);
0110 if (!server)
0111 return ERR_PTR(-ENOMEM);
0112 memcpy(server->uid.vendor, uid->vendor, sizeof(uid->vendor));
0113 memcpy(server->uid.serial, uid->serial, sizeof(uid->serial));
0114 INIT_LIST_HEAD(&server->server);
0115 INIT_LIST_HEAD(&server->lculist);
0116 return server;
0117 }
0118
0119 static void _free_server(struct alias_server *server)
0120 {
0121 kfree(server);
0122 }
0123
0124 static struct alias_lcu *_allocate_lcu(struct dasd_uid *uid)
0125 {
0126 struct alias_lcu *lcu;
0127
0128 lcu = kzalloc(sizeof(*lcu), GFP_KERNEL);
0129 if (!lcu)
0130 return ERR_PTR(-ENOMEM);
0131 lcu->uac = kzalloc(sizeof(*(lcu->uac)), GFP_KERNEL | GFP_DMA);
0132 if (!lcu->uac)
0133 goto out_err1;
0134 lcu->rsu_cqr = kzalloc(sizeof(*lcu->rsu_cqr), GFP_KERNEL | GFP_DMA);
0135 if (!lcu->rsu_cqr)
0136 goto out_err2;
0137 lcu->rsu_cqr->cpaddr = kzalloc(sizeof(struct ccw1),
0138 GFP_KERNEL | GFP_DMA);
0139 if (!lcu->rsu_cqr->cpaddr)
0140 goto out_err3;
0141 lcu->rsu_cqr->data = kzalloc(16, GFP_KERNEL | GFP_DMA);
0142 if (!lcu->rsu_cqr->data)
0143 goto out_err4;
0144
0145 memcpy(lcu->uid.vendor, uid->vendor, sizeof(uid->vendor));
0146 memcpy(lcu->uid.serial, uid->serial, sizeof(uid->serial));
0147 lcu->uid.ssid = uid->ssid;
0148 lcu->pav = NO_PAV;
0149 lcu->flags = NEED_UAC_UPDATE | UPDATE_PENDING;
0150 INIT_LIST_HEAD(&lcu->lcu);
0151 INIT_LIST_HEAD(&lcu->inactive_devices);
0152 INIT_LIST_HEAD(&lcu->active_devices);
0153 INIT_LIST_HEAD(&lcu->grouplist);
0154 INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
0155 INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
0156 spin_lock_init(&lcu->lock);
0157 init_completion(&lcu->lcu_setup);
0158 return lcu;
0159
0160 out_err4:
0161 kfree(lcu->rsu_cqr->cpaddr);
0162 out_err3:
0163 kfree(lcu->rsu_cqr);
0164 out_err2:
0165 kfree(lcu->uac);
0166 out_err1:
0167 kfree(lcu);
0168 return ERR_PTR(-ENOMEM);
0169 }
0170
0171 static void _free_lcu(struct alias_lcu *lcu)
0172 {
0173 kfree(lcu->rsu_cqr->data);
0174 kfree(lcu->rsu_cqr->cpaddr);
0175 kfree(lcu->rsu_cqr);
0176 kfree(lcu->uac);
0177 kfree(lcu);
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187 int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
0188 {
0189 struct dasd_eckd_private *private = device->private;
0190 unsigned long flags;
0191 struct alias_server *server, *newserver;
0192 struct alias_lcu *lcu, *newlcu;
0193 struct dasd_uid uid;
0194
0195 device->discipline->get_uid(device, &uid);
0196 spin_lock_irqsave(&aliastree.lock, flags);
0197 server = _find_server(&uid);
0198 if (!server) {
0199 spin_unlock_irqrestore(&aliastree.lock, flags);
0200 newserver = _allocate_server(&uid);
0201 if (IS_ERR(newserver))
0202 return PTR_ERR(newserver);
0203 spin_lock_irqsave(&aliastree.lock, flags);
0204 server = _find_server(&uid);
0205 if (!server) {
0206 list_add(&newserver->server, &aliastree.serverlist);
0207 server = newserver;
0208 } else {
0209
0210 _free_server(newserver);
0211 }
0212 }
0213
0214 lcu = _find_lcu(server, &uid);
0215 if (!lcu) {
0216 spin_unlock_irqrestore(&aliastree.lock, flags);
0217 newlcu = _allocate_lcu(&uid);
0218 if (IS_ERR(newlcu))
0219 return PTR_ERR(newlcu);
0220 spin_lock_irqsave(&aliastree.lock, flags);
0221 lcu = _find_lcu(server, &uid);
0222 if (!lcu) {
0223 list_add(&newlcu->lcu, &server->lculist);
0224 lcu = newlcu;
0225 } else {
0226
0227 _free_lcu(newlcu);
0228 }
0229 }
0230 spin_lock(&lcu->lock);
0231 list_add(&device->alias_list, &lcu->inactive_devices);
0232 private->lcu = lcu;
0233 spin_unlock(&lcu->lock);
0234 spin_unlock_irqrestore(&aliastree.lock, flags);
0235
0236 return 0;
0237 }
0238
0239
0240
0241
0242
0243
0244 void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
0245 {
0246 struct dasd_eckd_private *private = device->private;
0247 unsigned long flags;
0248 struct alias_lcu *lcu;
0249 struct alias_server *server;
0250 int was_pending;
0251 struct dasd_uid uid;
0252
0253 lcu = private->lcu;
0254
0255 if (!lcu)
0256 return;
0257 device->discipline->get_uid(device, &uid);
0258 spin_lock_irqsave(&lcu->lock, flags);
0259
0260 if (device == lcu->suc_data.device) {
0261 spin_unlock_irqrestore(&lcu->lock, flags);
0262 cancel_work_sync(&lcu->suc_data.worker);
0263 spin_lock_irqsave(&lcu->lock, flags);
0264 if (device == lcu->suc_data.device) {
0265 dasd_put_device(device);
0266 lcu->suc_data.device = NULL;
0267 }
0268 }
0269 was_pending = 0;
0270 if (device == lcu->ruac_data.device) {
0271 spin_unlock_irqrestore(&lcu->lock, flags);
0272 was_pending = 1;
0273 cancel_delayed_work_sync(&lcu->ruac_data.dwork);
0274 spin_lock_irqsave(&lcu->lock, flags);
0275 if (device == lcu->ruac_data.device) {
0276 dasd_put_device(device);
0277 lcu->ruac_data.device = NULL;
0278 }
0279 }
0280 private->lcu = NULL;
0281 spin_unlock_irqrestore(&lcu->lock, flags);
0282
0283 spin_lock_irqsave(&aliastree.lock, flags);
0284 spin_lock(&lcu->lock);
0285 list_del_init(&device->alias_list);
0286 if (list_empty(&lcu->grouplist) &&
0287 list_empty(&lcu->active_devices) &&
0288 list_empty(&lcu->inactive_devices)) {
0289 list_del(&lcu->lcu);
0290 spin_unlock(&lcu->lock);
0291 _free_lcu(lcu);
0292 lcu = NULL;
0293 } else {
0294 if (was_pending)
0295 _schedule_lcu_update(lcu, NULL);
0296 spin_unlock(&lcu->lock);
0297 }
0298 server = _find_server(&uid);
0299 if (server && list_empty(&server->lculist)) {
0300 list_del(&server->server);
0301 _free_server(server);
0302 }
0303 spin_unlock_irqrestore(&aliastree.lock, flags);
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 static int _add_device_to_lcu(struct alias_lcu *lcu,
0313 struct dasd_device *device,
0314 struct dasd_device *pos)
0315 {
0316
0317 struct dasd_eckd_private *private = device->private;
0318 struct alias_pav_group *group;
0319 struct dasd_uid uid;
0320
0321 spin_lock(get_ccwdev_lock(device->cdev));
0322 private->uid.type = lcu->uac->unit[private->uid.real_unit_addr].ua_type;
0323 private->uid.base_unit_addr =
0324 lcu->uac->unit[private->uid.real_unit_addr].base_ua;
0325 uid = private->uid;
0326 spin_unlock(get_ccwdev_lock(device->cdev));
0327
0328 if (lcu->pav == NO_PAV) {
0329 list_move(&device->alias_list, &lcu->active_devices);
0330 return 0;
0331 }
0332 group = _find_group(lcu, &uid);
0333 if (!group) {
0334 group = kzalloc(sizeof(*group), GFP_ATOMIC);
0335 if (!group)
0336 return -ENOMEM;
0337 memcpy(group->uid.vendor, uid.vendor, sizeof(uid.vendor));
0338 memcpy(group->uid.serial, uid.serial, sizeof(uid.serial));
0339 group->uid.ssid = uid.ssid;
0340 if (uid.type == UA_BASE_DEVICE)
0341 group->uid.base_unit_addr = uid.real_unit_addr;
0342 else
0343 group->uid.base_unit_addr = uid.base_unit_addr;
0344 memcpy(group->uid.vduit, uid.vduit, sizeof(uid.vduit));
0345 INIT_LIST_HEAD(&group->group);
0346 INIT_LIST_HEAD(&group->baselist);
0347 INIT_LIST_HEAD(&group->aliaslist);
0348 list_add(&group->group, &lcu->grouplist);
0349 }
0350 if (uid.type == UA_BASE_DEVICE)
0351 list_move(&device->alias_list, &group->baselist);
0352 else
0353 list_move(&device->alias_list, &group->aliaslist);
0354 private->pavgroup = group;
0355 return 0;
0356 };
0357
0358 static void _remove_device_from_lcu(struct alias_lcu *lcu,
0359 struct dasd_device *device)
0360 {
0361 struct dasd_eckd_private *private = device->private;
0362 struct alias_pav_group *group;
0363
0364 list_move(&device->alias_list, &lcu->inactive_devices);
0365 group = private->pavgroup;
0366 if (!group)
0367 return;
0368 private->pavgroup = NULL;
0369 if (list_empty(&group->baselist) && list_empty(&group->aliaslist)) {
0370 list_del(&group->group);
0371 kfree(group);
0372 return;
0373 }
0374 if (group->next == device)
0375 group->next = NULL;
0376 };
0377
0378 static int
0379 suborder_not_supported(struct dasd_ccw_req *cqr)
0380 {
0381 char *sense;
0382 char reason;
0383 char msg_format;
0384 char msg_no;
0385
0386
0387
0388
0389
0390
0391 if (cqr->intrc == -ENODEV)
0392 return 1;
0393
0394 if (cqr->intrc == -ENOLINK)
0395 return 1;
0396
0397 if (cqr->intrc == -EPERM)
0398 return 1;
0399
0400 sense = dasd_get_sense(&cqr->irb);
0401 if (!sense)
0402 return 0;
0403
0404 reason = sense[0];
0405 msg_format = (sense[7] & 0xF0);
0406 msg_no = (sense[7] & 0x0F);
0407
0408
0409 if ((reason == 0x80) && (msg_format == 0x00) && (msg_no == 0x04))
0410 return 1;
0411
0412 return 0;
0413 }
0414
0415 static int read_unit_address_configuration(struct dasd_device *device,
0416 struct alias_lcu *lcu)
0417 {
0418 struct dasd_psf_prssd_data *prssdp;
0419 struct dasd_ccw_req *cqr;
0420 struct ccw1 *ccw;
0421 int rc;
0422 unsigned long flags;
0423
0424 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 + 1 ,
0425 (sizeof(struct dasd_psf_prssd_data)),
0426 device, NULL);
0427 if (IS_ERR(cqr))
0428 return PTR_ERR(cqr);
0429 cqr->startdev = device;
0430 cqr->memdev = device;
0431 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
0432 cqr->retries = 10;
0433 cqr->expires = 20 * HZ;
0434
0435
0436 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
0437 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
0438 prssdp->order = PSF_ORDER_PRSSD;
0439 prssdp->suborder = 0x0e;
0440
0441
0442 ccw = cqr->cpaddr;
0443 ccw->cmd_code = DASD_ECKD_CCW_PSF;
0444 ccw->count = sizeof(struct dasd_psf_prssd_data);
0445 ccw->flags |= CCW_FLAG_CC;
0446 ccw->cda = (__u32)(addr_t) prssdp;
0447
0448
0449 memset(lcu->uac, 0, sizeof(*(lcu->uac)));
0450
0451 ccw++;
0452 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
0453 ccw->count = sizeof(*(lcu->uac));
0454 ccw->cda = (__u32)(addr_t) lcu->uac;
0455
0456 cqr->buildclk = get_tod_clock();
0457 cqr->status = DASD_CQR_FILLED;
0458
0459
0460 spin_lock_irqsave(&lcu->lock, flags);
0461 lcu->flags &= ~NEED_UAC_UPDATE;
0462 spin_unlock_irqrestore(&lcu->lock, flags);
0463
0464 rc = dasd_sleep_on(cqr);
0465 if (!rc)
0466 goto out;
0467
0468 if (suborder_not_supported(cqr)) {
0469
0470 rc = -EOPNOTSUPP;
0471 } else {
0472
0473 spin_lock_irqsave(&lcu->lock, flags);
0474 lcu->flags |= NEED_UAC_UPDATE;
0475 spin_unlock_irqrestore(&lcu->lock, flags);
0476 }
0477 out:
0478 dasd_sfree_request(cqr, cqr->memdev);
0479 return rc;
0480 }
0481
0482 static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu)
0483 {
0484 unsigned long flags;
0485 struct alias_pav_group *pavgroup, *tempgroup;
0486 struct dasd_device *device, *tempdev;
0487 int i, rc;
0488 struct dasd_eckd_private *private;
0489
0490 spin_lock_irqsave(&lcu->lock, flags);
0491 list_for_each_entry_safe(pavgroup, tempgroup, &lcu->grouplist, group) {
0492 list_for_each_entry_safe(device, tempdev, &pavgroup->baselist,
0493 alias_list) {
0494 list_move(&device->alias_list, &lcu->active_devices);
0495 private = device->private;
0496 private->pavgroup = NULL;
0497 }
0498 list_for_each_entry_safe(device, tempdev, &pavgroup->aliaslist,
0499 alias_list) {
0500 list_move(&device->alias_list, &lcu->active_devices);
0501 private = device->private;
0502 private->pavgroup = NULL;
0503 }
0504 list_del(&pavgroup->group);
0505 kfree(pavgroup);
0506 }
0507 spin_unlock_irqrestore(&lcu->lock, flags);
0508
0509 rc = read_unit_address_configuration(refdev, lcu);
0510 if (rc)
0511 return rc;
0512
0513 spin_lock_irqsave(&lcu->lock, flags);
0514
0515
0516
0517
0518
0519
0520 if (lcu->flags & NEED_UAC_UPDATE)
0521 goto out;
0522 lcu->pav = NO_PAV;
0523 for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) {
0524 switch (lcu->uac->unit[i].ua_type) {
0525 case UA_BASE_PAV_ALIAS:
0526 lcu->pav = BASE_PAV;
0527 break;
0528 case UA_HYPER_PAV_ALIAS:
0529 lcu->pav = HYPER_PAV;
0530 break;
0531 }
0532 if (lcu->pav != NO_PAV)
0533 break;
0534 }
0535
0536 list_for_each_entry_safe(device, tempdev, &lcu->active_devices,
0537 alias_list) {
0538 _add_device_to_lcu(lcu, device, refdev);
0539 }
0540 out:
0541 spin_unlock_irqrestore(&lcu->lock, flags);
0542 return 0;
0543 }
0544
0545 static void lcu_update_work(struct work_struct *work)
0546 {
0547 struct alias_lcu *lcu;
0548 struct read_uac_work_data *ruac_data;
0549 struct dasd_device *device;
0550 unsigned long flags;
0551 int rc;
0552
0553 ruac_data = container_of(work, struct read_uac_work_data, dwork.work);
0554 lcu = container_of(ruac_data, struct alias_lcu, ruac_data);
0555 device = ruac_data->device;
0556 rc = _lcu_update(device, lcu);
0557
0558
0559
0560
0561
0562 spin_lock_irqsave(&lcu->lock, flags);
0563 if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
0564 DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
0565 " alias data in lcu (rc = %d), retry later", rc);
0566 if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
0567 dasd_put_device(device);
0568 } else {
0569 dasd_put_device(device);
0570 lcu->ruac_data.device = NULL;
0571 lcu->flags &= ~UPDATE_PENDING;
0572 }
0573 spin_unlock_irqrestore(&lcu->lock, flags);
0574 }
0575
0576 static int _schedule_lcu_update(struct alias_lcu *lcu,
0577 struct dasd_device *device)
0578 {
0579 struct dasd_device *usedev = NULL;
0580 struct alias_pav_group *group;
0581
0582 lcu->flags |= NEED_UAC_UPDATE;
0583 if (lcu->ruac_data.device) {
0584
0585 return 0;
0586 }
0587 if (device && !list_empty(&device->alias_list))
0588 usedev = device;
0589
0590 if (!usedev && !list_empty(&lcu->grouplist)) {
0591 group = list_first_entry(&lcu->grouplist,
0592 struct alias_pav_group, group);
0593 if (!list_empty(&group->baselist))
0594 usedev = list_first_entry(&group->baselist,
0595 struct dasd_device,
0596 alias_list);
0597 else if (!list_empty(&group->aliaslist))
0598 usedev = list_first_entry(&group->aliaslist,
0599 struct dasd_device,
0600 alias_list);
0601 }
0602 if (!usedev && !list_empty(&lcu->active_devices)) {
0603 usedev = list_first_entry(&lcu->active_devices,
0604 struct dasd_device, alias_list);
0605 }
0606
0607
0608
0609
0610 if (!usedev)
0611 return -EINVAL;
0612 dasd_get_device(usedev);
0613 lcu->ruac_data.device = usedev;
0614 if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
0615 dasd_put_device(usedev);
0616 return 0;
0617 }
0618
0619 int dasd_alias_add_device(struct dasd_device *device)
0620 {
0621 struct dasd_eckd_private *private = device->private;
0622 __u8 uaddr = private->uid.real_unit_addr;
0623 struct alias_lcu *lcu = private->lcu;
0624 unsigned long flags;
0625 int rc;
0626
0627 rc = 0;
0628 spin_lock_irqsave(&lcu->lock, flags);
0629
0630
0631
0632
0633 if (private->uid.type != lcu->uac->unit[uaddr].ua_type) {
0634 lcu->flags |= UPDATE_PENDING;
0635 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
0636 "uid type mismatch - trigger rescan");
0637 }
0638 if (!(lcu->flags & UPDATE_PENDING)) {
0639 rc = _add_device_to_lcu(lcu, device, device);
0640 if (rc)
0641 lcu->flags |= UPDATE_PENDING;
0642 }
0643 if (lcu->flags & UPDATE_PENDING) {
0644 list_move(&device->alias_list, &lcu->active_devices);
0645 private->pavgroup = NULL;
0646 _schedule_lcu_update(lcu, device);
0647 }
0648 spin_unlock_irqrestore(&lcu->lock, flags);
0649 return rc;
0650 }
0651
0652 int dasd_alias_update_add_device(struct dasd_device *device)
0653 {
0654 struct dasd_eckd_private *private = device->private;
0655
0656 private->lcu->flags |= UPDATE_PENDING;
0657 return dasd_alias_add_device(device);
0658 }
0659
0660 int dasd_alias_remove_device(struct dasd_device *device)
0661 {
0662 struct dasd_eckd_private *private = device->private;
0663 struct alias_lcu *lcu = private->lcu;
0664 unsigned long flags;
0665
0666
0667 if (!lcu)
0668 return 0;
0669 spin_lock_irqsave(&lcu->lock, flags);
0670 _remove_device_from_lcu(lcu, device);
0671 spin_unlock_irqrestore(&lcu->lock, flags);
0672 return 0;
0673 }
0674
0675 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
0676 {
0677 struct dasd_eckd_private *alias_priv, *private = base_device->private;
0678 struct alias_lcu *lcu = private->lcu;
0679 struct dasd_device *alias_device;
0680 struct alias_pav_group *group;
0681 unsigned long flags;
0682
0683 if (!lcu)
0684 return NULL;
0685 if (lcu->pav == NO_PAV ||
0686 lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
0687 return NULL;
0688 if (unlikely(!(private->features.feature[8] & 0x01))) {
0689
0690
0691
0692
0693
0694 DBF_DEV_EVENT(DBF_ERR, base_device, "%s",
0695 "Prefix not enabled with PAV enabled\n");
0696 return NULL;
0697 }
0698
0699 spin_lock_irqsave(&lcu->lock, flags);
0700 group = private->pavgroup;
0701 if (!group) {
0702 spin_unlock_irqrestore(&lcu->lock, flags);
0703 return NULL;
0704 }
0705 alias_device = group->next;
0706 if (!alias_device) {
0707 if (list_empty(&group->aliaslist)) {
0708 spin_unlock_irqrestore(&lcu->lock, flags);
0709 return NULL;
0710 } else {
0711 alias_device = list_first_entry(&group->aliaslist,
0712 struct dasd_device,
0713 alias_list);
0714 }
0715 }
0716 if (list_is_last(&alias_device->alias_list, &group->aliaslist))
0717 group->next = list_first_entry(&group->aliaslist,
0718 struct dasd_device, alias_list);
0719 else
0720 group->next = list_first_entry(&alias_device->alias_list,
0721 struct dasd_device, alias_list);
0722 spin_unlock_irqrestore(&lcu->lock, flags);
0723 alias_priv = alias_device->private;
0724 if ((alias_priv->count < private->count) && !alias_device->stopped &&
0725 !test_bit(DASD_FLAG_OFFLINE, &alias_device->flags))
0726 return alias_device;
0727 else
0728 return NULL;
0729 }
0730
0731
0732
0733
0734
0735 static int reset_summary_unit_check(struct alias_lcu *lcu,
0736 struct dasd_device *device,
0737 char reason)
0738 {
0739 struct dasd_ccw_req *cqr;
0740 int rc = 0;
0741 struct ccw1 *ccw;
0742
0743 cqr = lcu->rsu_cqr;
0744 memcpy((char *) &cqr->magic, "ECKD", 4);
0745 ASCEBC((char *) &cqr->magic, 4);
0746 ccw = cqr->cpaddr;
0747 ccw->cmd_code = DASD_ECKD_CCW_RSCK;
0748 ccw->flags = CCW_FLAG_SLI;
0749 ccw->count = 16;
0750 ccw->cda = (__u32)(addr_t) cqr->data;
0751 ((char *)cqr->data)[0] = reason;
0752
0753 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
0754 cqr->retries = 255;
0755 cqr->startdev = device;
0756 cqr->memdev = device;
0757 cqr->block = NULL;
0758 cqr->expires = 5 * HZ;
0759 cqr->buildclk = get_tod_clock();
0760 cqr->status = DASD_CQR_FILLED;
0761
0762 rc = dasd_sleep_on_immediatly(cqr);
0763 return rc;
0764 }
0765
0766 static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu)
0767 {
0768 struct alias_pav_group *pavgroup;
0769 struct dasd_device *device;
0770 struct dasd_eckd_private *private;
0771
0772
0773 list_for_each_entry(device, &lcu->active_devices, alias_list) {
0774 private = device->private;
0775 if (private->uid.type != UA_BASE_DEVICE)
0776 continue;
0777 dasd_schedule_block_bh(device->block);
0778 dasd_schedule_device_bh(device);
0779 }
0780 list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
0781 private = device->private;
0782 if (private->uid.type != UA_BASE_DEVICE)
0783 continue;
0784 dasd_schedule_block_bh(device->block);
0785 dasd_schedule_device_bh(device);
0786 }
0787 list_for_each_entry(pavgroup, &lcu->grouplist, group) {
0788 list_for_each_entry(device, &pavgroup->baselist, alias_list) {
0789 dasd_schedule_block_bh(device->block);
0790 dasd_schedule_device_bh(device);
0791 }
0792 }
0793 }
0794
0795 static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu)
0796 {
0797 struct alias_pav_group *pavgroup;
0798 struct dasd_device *device, *temp;
0799 struct dasd_eckd_private *private;
0800 unsigned long flags;
0801 LIST_HEAD(active);
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814 spin_lock_irqsave(&lcu->lock, flags);
0815 list_for_each_entry_safe(device, temp, &lcu->active_devices,
0816 alias_list) {
0817 private = device->private;
0818 if (private->uid.type == UA_BASE_DEVICE)
0819 continue;
0820 list_move(&device->alias_list, &active);
0821 }
0822
0823 list_for_each_entry(pavgroup, &lcu->grouplist, group) {
0824 list_splice_init(&pavgroup->aliaslist, &active);
0825 }
0826 while (!list_empty(&active)) {
0827 device = list_first_entry(&active, struct dasd_device,
0828 alias_list);
0829 spin_unlock_irqrestore(&lcu->lock, flags);
0830 dasd_flush_device_queue(device);
0831 spin_lock_irqsave(&lcu->lock, flags);
0832
0833
0834
0835
0836 if (device == list_first_entry(&active,
0837 struct dasd_device, alias_list)) {
0838 list_move(&device->alias_list, &lcu->active_devices);
0839 private = device->private;
0840 private->pavgroup = NULL;
0841 }
0842 }
0843 spin_unlock_irqrestore(&lcu->lock, flags);
0844 }
0845
0846 static void _stop_all_devices_on_lcu(struct alias_lcu *lcu)
0847 {
0848 struct alias_pav_group *pavgroup;
0849 struct dasd_device *device;
0850
0851 list_for_each_entry(device, &lcu->active_devices, alias_list) {
0852 spin_lock(get_ccwdev_lock(device->cdev));
0853 dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
0854 spin_unlock(get_ccwdev_lock(device->cdev));
0855 }
0856 list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
0857 spin_lock(get_ccwdev_lock(device->cdev));
0858 dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
0859 spin_unlock(get_ccwdev_lock(device->cdev));
0860 }
0861 list_for_each_entry(pavgroup, &lcu->grouplist, group) {
0862 list_for_each_entry(device, &pavgroup->baselist, alias_list) {
0863 spin_lock(get_ccwdev_lock(device->cdev));
0864 dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
0865 spin_unlock(get_ccwdev_lock(device->cdev));
0866 }
0867 list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
0868 spin_lock(get_ccwdev_lock(device->cdev));
0869 dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
0870 spin_unlock(get_ccwdev_lock(device->cdev));
0871 }
0872 }
0873 }
0874
0875 static void _unstop_all_devices_on_lcu(struct alias_lcu *lcu)
0876 {
0877 struct alias_pav_group *pavgroup;
0878 struct dasd_device *device;
0879
0880 list_for_each_entry(device, &lcu->active_devices, alias_list) {
0881 spin_lock(get_ccwdev_lock(device->cdev));
0882 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
0883 spin_unlock(get_ccwdev_lock(device->cdev));
0884 }
0885 list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
0886 spin_lock(get_ccwdev_lock(device->cdev));
0887 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
0888 spin_unlock(get_ccwdev_lock(device->cdev));
0889 }
0890 list_for_each_entry(pavgroup, &lcu->grouplist, group) {
0891 list_for_each_entry(device, &pavgroup->baselist, alias_list) {
0892 spin_lock(get_ccwdev_lock(device->cdev));
0893 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
0894 spin_unlock(get_ccwdev_lock(device->cdev));
0895 }
0896 list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
0897 spin_lock(get_ccwdev_lock(device->cdev));
0898 dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
0899 spin_unlock(get_ccwdev_lock(device->cdev));
0900 }
0901 }
0902 }
0903
0904 static void summary_unit_check_handling_work(struct work_struct *work)
0905 {
0906 struct alias_lcu *lcu;
0907 struct summary_unit_check_work_data *suc_data;
0908 unsigned long flags;
0909 struct dasd_device *device;
0910
0911 suc_data = container_of(work, struct summary_unit_check_work_data,
0912 worker);
0913 lcu = container_of(suc_data, struct alias_lcu, suc_data);
0914 device = suc_data->device;
0915
0916
0917 flush_all_alias_devices_on_lcu(lcu);
0918
0919
0920 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
0921 dasd_device_remove_stop_bits(device,
0922 (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
0923 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
0924 reset_summary_unit_check(lcu, device, suc_data->reason);
0925
0926 spin_lock_irqsave(&lcu->lock, flags);
0927 _unstop_all_devices_on_lcu(lcu);
0928 _restart_all_base_devices_on_lcu(lcu);
0929
0930 _schedule_lcu_update(lcu, device);
0931 lcu->suc_data.device = NULL;
0932 dasd_put_device(device);
0933 spin_unlock_irqrestore(&lcu->lock, flags);
0934 }
0935
0936 void dasd_alias_handle_summary_unit_check(struct work_struct *work)
0937 {
0938 struct dasd_device *device = container_of(work, struct dasd_device,
0939 suc_work);
0940 struct dasd_eckd_private *private = device->private;
0941 struct alias_lcu *lcu;
0942 unsigned long flags;
0943
0944 lcu = private->lcu;
0945 if (!lcu) {
0946 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
0947 "device not ready to handle summary"
0948 " unit check (no lcu structure)");
0949 goto out;
0950 }
0951 spin_lock_irqsave(&lcu->lock, flags);
0952
0953
0954
0955 if (list_empty(&device->alias_list)) {
0956 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
0957 "device is in offline processing,"
0958 " don't do summary unit check handling");
0959 goto out_unlock;
0960 }
0961 if (lcu->suc_data.device) {
0962
0963 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
0964 "previous instance of summary unit check worker"
0965 " still pending");
0966 goto out_unlock;
0967 }
0968 _stop_all_devices_on_lcu(lcu);
0969
0970 lcu->flags |= NEED_UAC_UPDATE | UPDATE_PENDING;
0971 lcu->suc_data.reason = private->suc_reason;
0972 lcu->suc_data.device = device;
0973 dasd_get_device(device);
0974 if (!schedule_work(&lcu->suc_data.worker))
0975 dasd_put_device(device);
0976 out_unlock:
0977 spin_unlock_irqrestore(&lcu->lock, flags);
0978 out:
0979 clear_bit(DASD_FLAG_SUC, &device->flags);
0980 dasd_put_device(device);
0981 };