linux/drivers/s390/block/dasd_alias.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * PAV alias management for the DASD ECKD discipline
   4 *
   5 * Copyright IBM Corp. 2007
   6 * Author(s): Stefan Weinhuber <wein@de.ibm.com>
   7 */
   8
   9#define KMSG_COMPONENT "dasd-eckd"
  10
  11#include <linux/list.h>
  12#include <linux/slab.h>
  13#include <asm/ebcdic.h>
  14#include "dasd_int.h"
  15#include "dasd_eckd.h"
  16
  17#ifdef PRINTK_HEADER
  18#undef PRINTK_HEADER
  19#endif                          /* PRINTK_HEADER */
  20#define PRINTK_HEADER "dasd(eckd):"
  21
  22
  23/*
  24 * General concept of alias management:
  25 * - PAV and DASD alias management is specific to the eckd discipline.
  26 * - A device is connected to an lcu as long as the device exists.
  27 *   dasd_alias_make_device_known_to_lcu will be called wenn the
  28 *   device is checked by the eckd discipline and
  29 *   dasd_alias_disconnect_device_from_lcu will be called
  30 *   before the device is deleted.
  31 * - The dasd_alias_add_device / dasd_alias_remove_device
  32 *   functions mark the point when a device is 'ready for service'.
  33 * - A summary unit check is a rare occasion, but it is mandatory to
  34 *   support it. It requires some complex recovery actions before the
  35 *   devices can be used again (see dasd_alias_handle_summary_unit_check).
  36 * - dasd_alias_get_start_dev will find an alias device that can be used
  37 *   instead of the base device and does some (very simple) load balancing.
  38 *   This is the function that gets called for each I/O, so when improving
  39 *   something, this function should get faster or better, the rest has just
  40 *   to be correct.
  41 */
  42
  43
  44static void summary_unit_check_handling_work(struct work_struct *);
  45static void lcu_update_work(struct work_struct *);
  46static int _schedule_lcu_update(struct alias_lcu *, struct dasd_device *);
  47
  48static struct alias_root aliastree = {
  49        .serverlist = LIST_HEAD_INIT(aliastree.serverlist),
  50        .lock = __SPIN_LOCK_UNLOCKED(aliastree.lock),
  51};
  52
  53static struct alias_server *_find_server(struct dasd_uid *uid)
  54{
  55        struct alias_server *pos;
  56        list_for_each_entry(pos, &aliastree.serverlist, server) {
  57                if (!strncmp(pos->uid.vendor, uid->vendor,
  58                             sizeof(uid->vendor))
  59                    && !strncmp(pos->uid.serial, uid->serial,
  60                                sizeof(uid->serial)))
  61                        return pos;
  62        }
  63        return NULL;
  64}
  65
  66static struct alias_lcu *_find_lcu(struct alias_server *server,
  67                                   struct dasd_uid *uid)
  68{
  69        struct alias_lcu *pos;
  70        list_for_each_entry(pos, &server->lculist, lcu) {
  71                if (pos->uid.ssid == uid->ssid)
  72                        return pos;
  73        }
  74        return NULL;
  75}
  76
  77static struct alias_pav_group *_find_group(struct alias_lcu *lcu,
  78                                           struct dasd_uid *uid)
  79{
  80        struct alias_pav_group *pos;
  81        __u8 search_unit_addr;
  82
  83        /* for hyper pav there is only one group */
  84        if (lcu->pav == HYPER_PAV) {
  85                if (list_empty(&lcu->grouplist))
  86                        return NULL;
  87                else
  88                        return list_first_entry(&lcu->grouplist,
  89                                                struct alias_pav_group, group);
  90        }
  91
  92        /* for base pav we have to find the group that matches the base */
  93        if (uid->type == UA_BASE_DEVICE)
  94                search_unit_addr = uid->real_unit_addr;
  95        else
  96                search_unit_addr = uid->base_unit_addr;
  97        list_for_each_entry(pos, &lcu->grouplist, group) {
  98                if (pos->uid.base_unit_addr == search_unit_addr &&
  99                    !strncmp(pos->uid.vduit, uid->vduit, sizeof(uid->vduit)))
 100                        return pos;
 101        }
 102        return NULL;
 103}
 104
 105static struct alias_server *_allocate_server(struct dasd_uid *uid)
 106{
 107        struct alias_server *server;
 108
 109        server = kzalloc(sizeof(*server), GFP_KERNEL);
 110        if (!server)
 111                return ERR_PTR(-ENOMEM);
 112        memcpy(server->uid.vendor, uid->vendor, sizeof(uid->vendor));
 113        memcpy(server->uid.serial, uid->serial, sizeof(uid->serial));
 114        INIT_LIST_HEAD(&server->server);
 115        INIT_LIST_HEAD(&server->lculist);
 116        return server;
 117}
 118
 119static void _free_server(struct alias_server *server)
 120{
 121        kfree(server);
 122}
 123
 124static struct alias_lcu *_allocate_lcu(struct dasd_uid *uid)
 125{
 126        struct alias_lcu *lcu;
 127
 128        lcu = kzalloc(sizeof(*lcu), GFP_KERNEL);
 129        if (!lcu)
 130                return ERR_PTR(-ENOMEM);
 131        lcu->uac = kzalloc(sizeof(*(lcu->uac)), GFP_KERNEL | GFP_DMA);
 132        if (!lcu->uac)
 133                goto out_err1;
 134        lcu->rsu_cqr = kzalloc(sizeof(*lcu->rsu_cqr), GFP_KERNEL | GFP_DMA);
 135        if (!lcu->rsu_cqr)
 136                goto out_err2;
 137        lcu->rsu_cqr->cpaddr = kzalloc(sizeof(struct ccw1),
 138                                       GFP_KERNEL | GFP_DMA);
 139        if (!lcu->rsu_cqr->cpaddr)
 140                goto out_err3;
 141        lcu->rsu_cqr->data = kzalloc(16, GFP_KERNEL | GFP_DMA);
 142        if (!lcu->rsu_cqr->data)
 143                goto out_err4;
 144
 145        memcpy(lcu->uid.vendor, uid->vendor, sizeof(uid->vendor));
 146        memcpy(lcu->uid.serial, uid->serial, sizeof(uid->serial));
 147        lcu->uid.ssid = uid->ssid;
 148        lcu->pav = NO_PAV;
 149        lcu->flags = NEED_UAC_UPDATE | UPDATE_PENDING;
 150        INIT_LIST_HEAD(&lcu->lcu);
 151        INIT_LIST_HEAD(&lcu->inactive_devices);
 152        INIT_LIST_HEAD(&lcu->active_devices);
 153        INIT_LIST_HEAD(&lcu->grouplist);
 154        INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
 155        INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
 156        spin_lock_init(&lcu->lock);
 157        init_completion(&lcu->lcu_setup);
 158        return lcu;
 159
 160out_err4:
 161        kfree(lcu->rsu_cqr->cpaddr);
 162out_err3:
 163        kfree(lcu->rsu_cqr);
 164out_err2:
 165        kfree(lcu->uac);
 166out_err1:
 167        kfree(lcu);
 168        return ERR_PTR(-ENOMEM);
 169}
 170
 171static void _free_lcu(struct alias_lcu *lcu)
 172{
 173        kfree(lcu->rsu_cqr->data);
 174        kfree(lcu->rsu_cqr->cpaddr);
 175        kfree(lcu->rsu_cqr);
 176        kfree(lcu->uac);
 177        kfree(lcu);
 178}
 179
 180/*
 181 * This is the function that will allocate all the server and lcu data,
 182 * so this function must be called first for a new device.
 183 * If the return value is 1, the lcu was already known before, if it
 184 * is 0, this is a new lcu.
 185 * Negative return code indicates that something went wrong (e.g. -ENOMEM)
 186 */
 187int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
 188{
 189        struct dasd_eckd_private *private = device->private;
 190        unsigned long flags;
 191        struct alias_server *server, *newserver;
 192        struct alias_lcu *lcu, *newlcu;
 193        struct dasd_uid uid;
 194
 195        device->discipline->get_uid(device, &uid);
 196        spin_lock_irqsave(&aliastree.lock, flags);
 197        server = _find_server(&uid);
 198        if (!server) {
 199                spin_unlock_irqrestore(&aliastree.lock, flags);
 200                newserver = _allocate_server(&uid);
 201                if (IS_ERR(newserver))
 202                        return PTR_ERR(newserver);
 203                spin_lock_irqsave(&aliastree.lock, flags);
 204                server = _find_server(&uid);
 205                if (!server) {
 206                        list_add(&newserver->server, &aliastree.serverlist);
 207                        server = newserver;
 208                } else {
 209                        /* someone was faster */
 210                        _free_server(newserver);
 211                }
 212        }
 213
 214        lcu = _find_lcu(server, &uid);
 215        if (!lcu) {
 216                spin_unlock_irqrestore(&aliastree.lock, flags);
 217                newlcu = _allocate_lcu(&uid);
 218                if (IS_ERR(newlcu))
 219                        return PTR_ERR(newlcu);
 220                spin_lock_irqsave(&aliastree.lock, flags);
 221                lcu = _find_lcu(server, &uid);
 222                if (!lcu) {
 223                        list_add(&newlcu->lcu, &server->lculist);
 224                        lcu = newlcu;
 225                } else {
 226                        /* someone was faster */
 227                        _free_lcu(newlcu);
 228                }
 229        }
 230        spin_lock(&lcu->lock);
 231        list_add(&device->alias_list, &lcu->inactive_devices);
 232        private->lcu = lcu;
 233        spin_unlock(&lcu->lock);
 234        spin_unlock_irqrestore(&aliastree.lock, flags);
 235
 236        return 0;
 237}
 238
 239/*
 240 * This function removes a device from the scope of alias management.
 241 * The complicated part is to make sure that it is not in use by
 242 * any of the workers. If necessary cancel the work.
 243 */
 244void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
 245{
 246        struct dasd_eckd_private *private = device->private;
 247        unsigned long flags;
 248        struct alias_lcu *lcu;
 249        struct alias_server *server;
 250        int was_pending;
 251        struct dasd_uid uid;
 252
 253        lcu = private->lcu;
 254        /* nothing to do if already disconnected */
 255        if (!lcu)
 256                return;
 257        device->discipline->get_uid(device, &uid);
 258        spin_lock_irqsave(&lcu->lock, flags);
 259        list_del_init(&device->alias_list);
 260        /* make sure that the workers don't use this device */
 261        if (device == lcu->suc_data.device) {
 262                spin_unlock_irqrestore(&lcu->lock, flags);
 263                cancel_work_sync(&lcu->suc_data.worker);
 264                spin_lock_irqsave(&lcu->lock, flags);
 265                if (device == lcu->suc_data.device) {
 266                        dasd_put_device(device);
 267                        lcu->suc_data.device = NULL;
 268                }
 269        }
 270        was_pending = 0;
 271        if (device == lcu->ruac_data.device) {
 272                spin_unlock_irqrestore(&lcu->lock, flags);
 273                was_pending = 1;
 274                cancel_delayed_work_sync(&lcu->ruac_data.dwork);
 275                spin_lock_irqsave(&lcu->lock, flags);
 276                if (device == lcu->ruac_data.device) {
 277                        dasd_put_device(device);
 278                        lcu->ruac_data.device = NULL;
 279                }
 280        }
 281        private->lcu = NULL;
 282        spin_unlock_irqrestore(&lcu->lock, flags);
 283
 284        spin_lock_irqsave(&aliastree.lock, flags);
 285        spin_lock(&lcu->lock);
 286        if (list_empty(&lcu->grouplist) &&
 287            list_empty(&lcu->active_devices) &&
 288            list_empty(&lcu->inactive_devices)) {
 289                list_del(&lcu->lcu);
 290                spin_unlock(&lcu->lock);
 291                _free_lcu(lcu);
 292                lcu = NULL;
 293        } else {
 294                if (was_pending)
 295                        _schedule_lcu_update(lcu, NULL);
 296                spin_unlock(&lcu->lock);
 297        }
 298        server = _find_server(&uid);
 299        if (server && list_empty(&server->lculist)) {
 300                list_del(&server->server);
 301                _free_server(server);
 302        }
 303        spin_unlock_irqrestore(&aliastree.lock, flags);
 304}
 305
 306/*
 307 * This function assumes that the unit address configuration stored
 308 * in the lcu is up to date and will update the device uid before
 309 * adding it to a pav group.
 310 */
 311
 312static int _add_device_to_lcu(struct alias_lcu *lcu,
 313                              struct dasd_device *device,
 314                              struct dasd_device *pos)
 315{
 316
 317        struct dasd_eckd_private *private = device->private;
 318        struct alias_pav_group *group;
 319        struct dasd_uid uid;
 320
 321        spin_lock(get_ccwdev_lock(device->cdev));
 322        private->uid.type = lcu->uac->unit[private->uid.real_unit_addr].ua_type;
 323        private->uid.base_unit_addr =
 324                lcu->uac->unit[private->uid.real_unit_addr].base_ua;
 325        uid = private->uid;
 326        spin_unlock(get_ccwdev_lock(device->cdev));
 327        /* if we have no PAV anyway, we don't need to bother with PAV groups */
 328        if (lcu->pav == NO_PAV) {
 329                list_move(&device->alias_list, &lcu->active_devices);
 330                return 0;
 331        }
 332        group = _find_group(lcu, &uid);
 333        if (!group) {
 334                group = kzalloc(sizeof(*group), GFP_ATOMIC);
 335                if (!group)
 336                        return -ENOMEM;
 337                memcpy(group->uid.vendor, uid.vendor, sizeof(uid.vendor));
 338                memcpy(group->uid.serial, uid.serial, sizeof(uid.serial));
 339                group->uid.ssid = uid.ssid;
 340                if (uid.type == UA_BASE_DEVICE)
 341                        group->uid.base_unit_addr = uid.real_unit_addr;
 342                else
 343                        group->uid.base_unit_addr = uid.base_unit_addr;
 344                memcpy(group->uid.vduit, uid.vduit, sizeof(uid.vduit));
 345                INIT_LIST_HEAD(&group->group);
 346                INIT_LIST_HEAD(&group->baselist);
 347                INIT_LIST_HEAD(&group->aliaslist);
 348                list_add(&group->group, &lcu->grouplist);
 349        }
 350        if (uid.type == UA_BASE_DEVICE)
 351                list_move(&device->alias_list, &group->baselist);
 352        else
 353                list_move(&device->alias_list, &group->aliaslist);
 354        private->pavgroup = group;
 355        return 0;
 356};
 357
 358static void _remove_device_from_lcu(struct alias_lcu *lcu,
 359                                    struct dasd_device *device)
 360{
 361        struct dasd_eckd_private *private = device->private;
 362        struct alias_pav_group *group;
 363
 364        list_move(&device->alias_list, &lcu->inactive_devices);
 365        group = private->pavgroup;
 366        if (!group)
 367                return;
 368        private->pavgroup = NULL;
 369        if (list_empty(&group->baselist) && list_empty(&group->aliaslist)) {
 370                list_del(&group->group);
 371                kfree(group);
 372                return;
 373        }
 374        if (group->next == device)
 375                group->next = NULL;
 376};
 377
 378static int
 379suborder_not_supported(struct dasd_ccw_req *cqr)
 380{
 381        char *sense;
 382        char reason;
 383        char msg_format;
 384        char msg_no;
 385
 386        /*
 387         * intrc values ENODEV, ENOLINK and EPERM
 388         * will be optained from sleep_on to indicate that no
 389         * IO operation can be started
 390         */
 391        if (cqr->intrc == -ENODEV)
 392                return 1;
 393
 394        if (cqr->intrc == -ENOLINK)
 395                return 1;
 396
 397        if (cqr->intrc == -EPERM)
 398                return 1;
 399
 400        sense = dasd_get_sense(&cqr->irb);
 401        if (!sense)
 402                return 0;
 403
 404        reason = sense[0];
 405        msg_format = (sense[7] & 0xF0);
 406        msg_no = (sense[7] & 0x0F);
 407
 408        /* command reject, Format 0 MSG 4 - invalid parameter */
 409        if ((reason == 0x80) && (msg_format == 0x00) && (msg_no == 0x04))
 410                return 1;
 411
 412        return 0;
 413}
 414
 415static int read_unit_address_configuration(struct dasd_device *device,
 416                                           struct alias_lcu *lcu)
 417{
 418        struct dasd_psf_prssd_data *prssdp;
 419        struct dasd_ccw_req *cqr;
 420        struct ccw1 *ccw;
 421        int rc;
 422        unsigned long flags;
 423
 424        cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,
 425                                   (sizeof(struct dasd_psf_prssd_data)),
 426                                   device, NULL);
 427        if (IS_ERR(cqr))
 428                return PTR_ERR(cqr);
 429        cqr->startdev = device;
 430        cqr->memdev = device;
 431        clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 432        cqr->retries = 10;
 433        cqr->expires = 20 * HZ;
 434
 435        /* Prepare for Read Subsystem Data */
 436        prssdp = (struct dasd_psf_prssd_data *) cqr->data;
 437        memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
 438        prssdp->order = PSF_ORDER_PRSSD;
 439        prssdp->suborder = 0x0e;        /* Read unit address configuration */
 440        /* all other bytes of prssdp must be zero */
 441
 442        ccw = cqr->cpaddr;
 443        ccw->cmd_code = DASD_ECKD_CCW_PSF;
 444        ccw->count = sizeof(struct dasd_psf_prssd_data);
 445        ccw->flags |= CCW_FLAG_CC;
 446        ccw->cda = (__u32)(addr_t) prssdp;
 447
 448        /* Read Subsystem Data - feature codes */
 449        memset(lcu->uac, 0, sizeof(*(lcu->uac)));
 450
 451        ccw++;
 452        ccw->cmd_code = DASD_ECKD_CCW_RSSD;
 453        ccw->count = sizeof(*(lcu->uac));
 454        ccw->cda = (__u32)(addr_t) lcu->uac;
 455
 456        cqr->buildclk = get_tod_clock();
 457        cqr->status = DASD_CQR_FILLED;
 458
 459        /* need to unset flag here to detect race with summary unit check */
 460        spin_lock_irqsave(&lcu->lock, flags);
 461        lcu->flags &= ~NEED_UAC_UPDATE;
 462        spin_unlock_irqrestore(&lcu->lock, flags);
 463
 464        rc = dasd_sleep_on(cqr);
 465        if (rc && !suborder_not_supported(cqr)) {
 466                spin_lock_irqsave(&lcu->lock, flags);
 467                lcu->flags |= NEED_UAC_UPDATE;
 468                spin_unlock_irqrestore(&lcu->lock, flags);
 469        }
 470        dasd_sfree_request(cqr, cqr->memdev);
 471        return rc;
 472}
 473
 474static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu)
 475{
 476        unsigned long flags;
 477        struct alias_pav_group *pavgroup, *tempgroup;
 478        struct dasd_device *device, *tempdev;
 479        int i, rc;
 480        struct dasd_eckd_private *private;
 481
 482        spin_lock_irqsave(&lcu->lock, flags);
 483        list_for_each_entry_safe(pavgroup, tempgroup, &lcu->grouplist, group) {
 484                list_for_each_entry_safe(device, tempdev, &pavgroup->baselist,
 485                                         alias_list) {
 486                        list_move(&device->alias_list, &lcu->active_devices);
 487                        private = device->private;
 488                        private->pavgroup = NULL;
 489                }
 490                list_for_each_entry_safe(device, tempdev, &pavgroup->aliaslist,
 491                                         alias_list) {
 492                        list_move(&device->alias_list, &lcu->active_devices);
 493                        private = device->private;
 494                        private->pavgroup = NULL;
 495                }
 496                list_del(&pavgroup->group);
 497                kfree(pavgroup);
 498        }
 499        spin_unlock_irqrestore(&lcu->lock, flags);
 500
 501        rc = read_unit_address_configuration(refdev, lcu);
 502        if (rc)
 503                return rc;
 504
 505        spin_lock_irqsave(&lcu->lock, flags);
 506        lcu->pav = NO_PAV;
 507        for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) {
 508                switch (lcu->uac->unit[i].ua_type) {
 509                case UA_BASE_PAV_ALIAS:
 510                        lcu->pav = BASE_PAV;
 511                        break;
 512                case UA_HYPER_PAV_ALIAS:
 513                        lcu->pav = HYPER_PAV;
 514                        break;
 515                }
 516                if (lcu->pav != NO_PAV)
 517                        break;
 518        }
 519
 520        list_for_each_entry_safe(device, tempdev, &lcu->active_devices,
 521                                 alias_list) {
 522                _add_device_to_lcu(lcu, device, refdev);
 523        }
 524        spin_unlock_irqrestore(&lcu->lock, flags);
 525        return 0;
 526}
 527
 528static void lcu_update_work(struct work_struct *work)
 529{
 530        struct alias_lcu *lcu;
 531        struct read_uac_work_data *ruac_data;
 532        struct dasd_device *device;
 533        unsigned long flags;
 534        int rc;
 535
 536        ruac_data = container_of(work, struct read_uac_work_data, dwork.work);
 537        lcu = container_of(ruac_data, struct alias_lcu, ruac_data);
 538        device = ruac_data->device;
 539        rc = _lcu_update(device, lcu);
 540        /*
 541         * Need to check flags again, as there could have been another
 542         * prepare_update or a new device a new device while we were still
 543         * processing the data
 544         */
 545        spin_lock_irqsave(&lcu->lock, flags);
 546        if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
 547                DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 548                            " alias data in lcu (rc = %d), retry later", rc);
 549                if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
 550                        dasd_put_device(device);
 551        } else {
 552                dasd_put_device(device);
 553                lcu->ruac_data.device = NULL;
 554                lcu->flags &= ~UPDATE_PENDING;
 555        }
 556        spin_unlock_irqrestore(&lcu->lock, flags);
 557}
 558
 559static int _schedule_lcu_update(struct alias_lcu *lcu,
 560                                struct dasd_device *device)
 561{
 562        struct dasd_device *usedev = NULL;
 563        struct alias_pav_group *group;
 564
 565        lcu->flags |= NEED_UAC_UPDATE;
 566        if (lcu->ruac_data.device) {
 567                /* already scheduled or running */
 568                return 0;
 569        }
 570        if (device && !list_empty(&device->alias_list))
 571                usedev = device;
 572
 573        if (!usedev && !list_empty(&lcu->grouplist)) {
 574                group = list_first_entry(&lcu->grouplist,
 575                                         struct alias_pav_group, group);
 576                if (!list_empty(&group->baselist))
 577                        usedev = list_first_entry(&group->baselist,
 578                                                  struct dasd_device,
 579                                                  alias_list);
 580                else if (!list_empty(&group->aliaslist))
 581                        usedev = list_first_entry(&group->aliaslist,
 582                                                  struct dasd_device,
 583                                                  alias_list);
 584        }
 585        if (!usedev && !list_empty(&lcu->active_devices)) {
 586                usedev = list_first_entry(&lcu->active_devices,
 587                                          struct dasd_device, alias_list);
 588        }
 589        /*
 590         * if we haven't found a proper device yet, give up for now, the next
 591         * device that will be set active will trigger an lcu update
 592         */
 593        if (!usedev)
 594                return -EINVAL;
 595        dasd_get_device(usedev);
 596        lcu->ruac_data.device = usedev;
 597        if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
 598                dasd_put_device(usedev);
 599        return 0;
 600}
 601
 602int dasd_alias_add_device(struct dasd_device *device)
 603{
 604        struct dasd_eckd_private *private = device->private;
 605        __u8 uaddr = private->uid.real_unit_addr;
 606        struct alias_lcu *lcu = private->lcu;
 607        unsigned long flags;
 608        int rc;
 609
 610        rc = 0;
 611        spin_lock_irqsave(&lcu->lock, flags);
 612        /*
 613         * Check if device and lcu type differ. If so, the uac data may be
 614         * outdated and needs to be updated.
 615         */
 616        if (private->uid.type !=  lcu->uac->unit[uaddr].ua_type) {
 617                lcu->flags |= UPDATE_PENDING;
 618                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 619                              "uid type mismatch - trigger rescan");
 620        }
 621        if (!(lcu->flags & UPDATE_PENDING)) {
 622                rc = _add_device_to_lcu(lcu, device, device);
 623                if (rc)
 624                        lcu->flags |= UPDATE_PENDING;
 625        }
 626        if (lcu->flags & UPDATE_PENDING) {
 627                list_move(&device->alias_list, &lcu->active_devices);
 628                _schedule_lcu_update(lcu, device);
 629        }
 630        spin_unlock_irqrestore(&lcu->lock, flags);
 631        return rc;
 632}
 633
 634int dasd_alias_update_add_device(struct dasd_device *device)
 635{
 636        struct dasd_eckd_private *private = device->private;
 637
 638        private->lcu->flags |= UPDATE_PENDING;
 639        return dasd_alias_add_device(device);
 640}
 641
 642int dasd_alias_remove_device(struct dasd_device *device)
 643{
 644        struct dasd_eckd_private *private = device->private;
 645        struct alias_lcu *lcu = private->lcu;
 646        unsigned long flags;
 647
 648        /* nothing to do if already removed */
 649        if (!lcu)
 650                return 0;
 651        spin_lock_irqsave(&lcu->lock, flags);
 652        _remove_device_from_lcu(lcu, device);
 653        spin_unlock_irqrestore(&lcu->lock, flags);
 654        return 0;
 655}
 656
 657struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
 658{
 659        struct dasd_eckd_private *alias_priv, *private = base_device->private;
 660        struct alias_pav_group *group = private->pavgroup;
 661        struct alias_lcu *lcu = private->lcu;
 662        struct dasd_device *alias_device;
 663        unsigned long flags;
 664
 665        if (!group || !lcu)
 666                return NULL;
 667        if (lcu->pav == NO_PAV ||
 668            lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
 669                return NULL;
 670        if (unlikely(!(private->features.feature[8] & 0x01))) {
 671                /*
 672                 * PAV enabled but prefix not, very unlikely
 673                 * seems to be a lost pathgroup
 674                 * use base device to do IO
 675                 */
 676                DBF_DEV_EVENT(DBF_ERR, base_device, "%s",
 677                              "Prefix not enabled with PAV enabled\n");
 678                return NULL;
 679        }
 680
 681        spin_lock_irqsave(&lcu->lock, flags);
 682        alias_device = group->next;
 683        if (!alias_device) {
 684                if (list_empty(&group->aliaslist)) {
 685                        spin_unlock_irqrestore(&lcu->lock, flags);
 686                        return NULL;
 687                } else {
 688                        alias_device = list_first_entry(&group->aliaslist,
 689                                                        struct dasd_device,
 690                                                        alias_list);
 691                }
 692        }
 693        if (list_is_last(&alias_device->alias_list, &group->aliaslist))
 694                group->next = list_first_entry(&group->aliaslist,
 695                                               struct dasd_device, alias_list);
 696        else
 697                group->next = list_first_entry(&alias_device->alias_list,
 698                                               struct dasd_device, alias_list);
 699        spin_unlock_irqrestore(&lcu->lock, flags);
 700        alias_priv = alias_device->private;
 701        if ((alias_priv->count < private->count) && !alias_device->stopped &&
 702            !test_bit(DASD_FLAG_OFFLINE, &alias_device->flags))
 703                return alias_device;
 704        else
 705                return NULL;
 706}
 707
 708/*
 709 * Summary unit check handling depends on the way alias devices
 710 * are handled so it is done here rather then in dasd_eckd.c
 711 */
 712static int reset_summary_unit_check(struct alias_lcu *lcu,
 713                                    struct dasd_device *device,
 714                                    char reason)
 715{
 716        struct dasd_ccw_req *cqr;
 717        int rc = 0;
 718        struct ccw1 *ccw;
 719
 720        cqr = lcu->rsu_cqr;
 721        memcpy((char *) &cqr->magic, "ECKD", 4);
 722        ASCEBC((char *) &cqr->magic, 4);
 723        ccw = cqr->cpaddr;
 724        ccw->cmd_code = DASD_ECKD_CCW_RSCK;
 725        ccw->flags = CCW_FLAG_SLI;
 726        ccw->count = 16;
 727        ccw->cda = (__u32)(addr_t) cqr->data;
 728        ((char *)cqr->data)[0] = reason;
 729
 730        clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 731        cqr->retries = 255;     /* set retry counter to enable basic ERP */
 732        cqr->startdev = device;
 733        cqr->memdev = device;
 734        cqr->block = NULL;
 735        cqr->expires = 5 * HZ;
 736        cqr->buildclk = get_tod_clock();
 737        cqr->status = DASD_CQR_FILLED;
 738
 739        rc = dasd_sleep_on_immediatly(cqr);
 740        return rc;
 741}
 742
 743static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu)
 744{
 745        struct alias_pav_group *pavgroup;
 746        struct dasd_device *device;
 747        struct dasd_eckd_private *private;
 748
 749        /* active and inactive list can contain alias as well as base devices */
 750        list_for_each_entry(device, &lcu->active_devices, alias_list) {
 751                private = device->private;
 752                if (private->uid.type != UA_BASE_DEVICE)
 753                        continue;
 754                dasd_schedule_block_bh(device->block);
 755                dasd_schedule_device_bh(device);
 756        }
 757        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 758                private = device->private;
 759                if (private->uid.type != UA_BASE_DEVICE)
 760                        continue;
 761                dasd_schedule_block_bh(device->block);
 762                dasd_schedule_device_bh(device);
 763        }
 764        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 765                list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 766                        dasd_schedule_block_bh(device->block);
 767                        dasd_schedule_device_bh(device);
 768                }
 769        }
 770}
 771
 772static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu)
 773{
 774        struct alias_pav_group *pavgroup;
 775        struct dasd_device *device, *temp;
 776        struct dasd_eckd_private *private;
 777        unsigned long flags;
 778        LIST_HEAD(active);
 779
 780        /*
 781         * Problem here ist that dasd_flush_device_queue may wait
 782         * for termination of a request to complete. We can't keep
 783         * the lcu lock during that time, so we must assume that
 784         * the lists may have changed.
 785         * Idea: first gather all active alias devices in a separate list,
 786         * then flush the first element of this list unlocked, and afterwards
 787         * check if it is still on the list before moving it to the
 788         * active_devices list.
 789         */
 790
 791        spin_lock_irqsave(&lcu->lock, flags);
 792        list_for_each_entry_safe(device, temp, &lcu->active_devices,
 793                                 alias_list) {
 794                private = device->private;
 795                if (private->uid.type == UA_BASE_DEVICE)
 796                        continue;
 797                list_move(&device->alias_list, &active);
 798        }
 799
 800        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 801                list_splice_init(&pavgroup->aliaslist, &active);
 802        }
 803        while (!list_empty(&active)) {
 804                device = list_first_entry(&active, struct dasd_device,
 805                                          alias_list);
 806                spin_unlock_irqrestore(&lcu->lock, flags);
 807                dasd_flush_device_queue(device);
 808                spin_lock_irqsave(&lcu->lock, flags);
 809                /*
 810                 * only move device around if it wasn't moved away while we
 811                 * were waiting for the flush
 812                 */
 813                if (device == list_first_entry(&active,
 814                                               struct dasd_device, alias_list)) {
 815                        list_move(&device->alias_list, &lcu->active_devices);
 816                        private = device->private;
 817                        private->pavgroup = NULL;
 818                }
 819        }
 820        spin_unlock_irqrestore(&lcu->lock, flags);
 821}
 822
 823static void _stop_all_devices_on_lcu(struct alias_lcu *lcu)
 824{
 825        struct alias_pav_group *pavgroup;
 826        struct dasd_device *device;
 827
 828        list_for_each_entry(device, &lcu->active_devices, alias_list) {
 829                spin_lock(get_ccwdev_lock(device->cdev));
 830                dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 831                spin_unlock(get_ccwdev_lock(device->cdev));
 832        }
 833        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 834                spin_lock(get_ccwdev_lock(device->cdev));
 835                dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 836                spin_unlock(get_ccwdev_lock(device->cdev));
 837        }
 838        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 839                list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 840                        spin_lock(get_ccwdev_lock(device->cdev));
 841                        dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 842                        spin_unlock(get_ccwdev_lock(device->cdev));
 843                }
 844                list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 845                        spin_lock(get_ccwdev_lock(device->cdev));
 846                        dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 847                        spin_unlock(get_ccwdev_lock(device->cdev));
 848                }
 849        }
 850}
 851
 852static void _unstop_all_devices_on_lcu(struct alias_lcu *lcu)
 853{
 854        struct alias_pav_group *pavgroup;
 855        struct dasd_device *device;
 856
 857        list_for_each_entry(device, &lcu->active_devices, alias_list) {
 858                spin_lock(get_ccwdev_lock(device->cdev));
 859                dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 860                spin_unlock(get_ccwdev_lock(device->cdev));
 861        }
 862        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 863                spin_lock(get_ccwdev_lock(device->cdev));
 864                dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 865                spin_unlock(get_ccwdev_lock(device->cdev));
 866        }
 867        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 868                list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 869                        spin_lock(get_ccwdev_lock(device->cdev));
 870                        dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 871                        spin_unlock(get_ccwdev_lock(device->cdev));
 872                }
 873                list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 874                        spin_lock(get_ccwdev_lock(device->cdev));
 875                        dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 876                        spin_unlock(get_ccwdev_lock(device->cdev));
 877                }
 878        }
 879}
 880
 881static void summary_unit_check_handling_work(struct work_struct *work)
 882{
 883        struct alias_lcu *lcu;
 884        struct summary_unit_check_work_data *suc_data;
 885        unsigned long flags;
 886        struct dasd_device *device;
 887
 888        suc_data = container_of(work, struct summary_unit_check_work_data,
 889                                worker);
 890        lcu = container_of(suc_data, struct alias_lcu, suc_data);
 891        device = suc_data->device;
 892
 893        /* 1. flush alias devices */
 894        flush_all_alias_devices_on_lcu(lcu);
 895
 896        /* 2. reset summary unit check */
 897        spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 898        dasd_device_remove_stop_bits(device,
 899                                     (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
 900        spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 901        reset_summary_unit_check(lcu, device, suc_data->reason);
 902
 903        spin_lock_irqsave(&lcu->lock, flags);
 904        _unstop_all_devices_on_lcu(lcu);
 905        _restart_all_base_devices_on_lcu(lcu);
 906        /* 3. read new alias configuration */
 907        _schedule_lcu_update(lcu, device);
 908        lcu->suc_data.device = NULL;
 909        dasd_put_device(device);
 910        spin_unlock_irqrestore(&lcu->lock, flags);
 911}
 912
 913void dasd_alias_handle_summary_unit_check(struct work_struct *work)
 914{
 915        struct dasd_device *device = container_of(work, struct dasd_device,
 916                                                  suc_work);
 917        struct dasd_eckd_private *private = device->private;
 918        struct alias_lcu *lcu;
 919        unsigned long flags;
 920
 921        lcu = private->lcu;
 922        if (!lcu) {
 923                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 924                            "device not ready to handle summary"
 925                            " unit check (no lcu structure)");
 926                goto out;
 927        }
 928        spin_lock_irqsave(&lcu->lock, flags);
 929        /* If this device is about to be removed just return and wait for
 930         * the next interrupt on a different device
 931         */
 932        if (list_empty(&device->alias_list)) {
 933                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 934                            "device is in offline processing,"
 935                            " don't do summary unit check handling");
 936                goto out_unlock;
 937        }
 938        if (lcu->suc_data.device) {
 939                /* already scheduled or running */
 940                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 941                            "previous instance of summary unit check worker"
 942                            " still pending");
 943                goto out_unlock;
 944        }
 945        _stop_all_devices_on_lcu(lcu);
 946        /* prepare for lcu_update */
 947        lcu->flags |= NEED_UAC_UPDATE | UPDATE_PENDING;
 948        lcu->suc_data.reason = private->suc_reason;
 949        lcu->suc_data.device = device;
 950        dasd_get_device(device);
 951        if (!schedule_work(&lcu->suc_data.worker))
 952                dasd_put_device(device);
 953out_unlock:
 954        spin_unlock_irqrestore(&lcu->lock, flags);
 955out:
 956        clear_bit(DASD_FLAG_SUC, &device->flags);
 957        dasd_put_device(device);
 958};
 959