Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PAV alias management for the DASD ECKD discipline
0004  *
0005  * Copyright IBM Corp. 2007
0006  * Author(s): Stefan Weinhuber <wein@de.ibm.com>
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              /* PRINTK_HEADER */
0020 #define PRINTK_HEADER "dasd(eckd):"
0021 
0022 
0023 /*
0024  * General concept of alias management:
0025  * - PAV and DASD alias management is specific to the eckd discipline.
0026  * - A device is connected to an lcu as long as the device exists.
0027  *   dasd_alias_make_device_known_to_lcu will be called wenn the
0028  *   device is checked by the eckd discipline and
0029  *   dasd_alias_disconnect_device_from_lcu will be called
0030  *   before the device is deleted.
0031  * - The dasd_alias_add_device / dasd_alias_remove_device
0032  *   functions mark the point when a device is 'ready for service'.
0033  * - A summary unit check is a rare occasion, but it is mandatory to
0034  *   support it. It requires some complex recovery actions before the
0035  *   devices can be used again (see dasd_alias_handle_summary_unit_check).
0036  * - dasd_alias_get_start_dev will find an alias device that can be used
0037  *   instead of the base device and does some (very simple) load balancing.
0038  *   This is the function that gets called for each I/O, so when improving
0039  *   something, this function should get faster or better, the rest has just
0040  *   to be correct.
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     /* for hyper pav there is only one group */
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     /* for base pav we have to find the group that matches the base */
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  * This is the function that will allocate all the server and lcu data,
0182  * so this function must be called first for a new device.
0183  * If the return value is 1, the lcu was already known before, if it
0184  * is 0, this is a new lcu.
0185  * Negative return code indicates that something went wrong (e.g. -ENOMEM)
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             /* someone was faster */
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             /* someone was faster */
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  * This function removes a device from the scope of alias management.
0241  * The complicated part is to make sure that it is not in use by
0242  * any of the workers. If necessary cancel the work.
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     /* nothing to do if already disconnected */
0255     if (!lcu)
0256         return;
0257     device->discipline->get_uid(device, &uid);
0258     spin_lock_irqsave(&lcu->lock, flags);
0259     /* make sure that the workers don't use this device */
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  * This function assumes that the unit address configuration stored
0308  * in the lcu is up to date and will update the device uid before
0309  * adding it to a pav group.
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     /* if we have no PAV anyway, we don't need to bother with PAV groups */
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      * intrc values ENODEV, ENOLINK and EPERM
0388      * will be optained from sleep_on to indicate that no
0389      * IO operation can be started
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     /* command reject, Format 0 MSG 4 - invalid parameter */
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 /* PSF */ + 1 /* RSSD */,
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     /* Prepare for Read Subsystem Data */
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;    /* Read unit address configuration */
0440     /* all other bytes of prssdp must be zero */
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     /* Read Subsystem Data - feature codes */
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     /* need to unset flag here to detect race with summary unit check */
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         /* suborder not supported or device unusable for IO */
0470         rc = -EOPNOTSUPP;
0471     } else {
0472         /* IO failed but should be retried */
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      * there is another update needed skip the remaining handling
0516      * the data might already be outdated
0517      * but especially do not add the device to an LCU with pending
0518      * update
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      * Need to check flags again, as there could have been another
0559      * prepare_update or a new device a new device while we were still
0560      * processing the data
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         /* already scheduled or running */
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      * if we haven't found a proper device yet, give up for now, the next
0608      * device that will be set active will trigger an lcu update
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      * Check if device and lcu type differ. If so, the uac data may be
0631      * outdated and needs to be updated.
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     /* nothing to do if already removed */
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          * PAV enabled but prefix not, very unlikely
0691          * seems to be a lost pathgroup
0692          * use base device to do IO
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  * Summary unit check handling depends on the way alias devices
0733  * are handled so it is done here rather then in dasd_eckd.c
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; /* set retry counter to enable basic ERP */
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     /* active and inactive list can contain alias as well as base devices */
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      * Problem here ist that dasd_flush_device_queue may wait
0805      * for termination of a request to complete. We can't keep
0806      * the lcu lock during that time, so we must assume that
0807      * the lists may have changed.
0808      * Idea: first gather all active alias devices in a separate list,
0809      * then flush the first element of this list unlocked, and afterwards
0810      * check if it is still on the list before moving it to the
0811      * active_devices list.
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          * only move device around if it wasn't moved away while we
0834          * were waiting for the flush
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     /* 1. flush alias devices */
0917     flush_all_alias_devices_on_lcu(lcu);
0918 
0919     /* 2. reset summary unit check */
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     /* 3. read new alias configuration */
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     /* If this device is about to be removed just return and wait for
0953      * the next interrupt on a different device
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         /* already scheduled or running */
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     /* prepare for lcu_update */
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 };