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        /* make sure that the workers don't use this device */
 260        if (device == lcu->suc_data.device) {
 261                spin_unlock_irqrestore(&lcu->lock, flags);
 262                cancel_work_sync(&lcu->suc_data.worker);
 263                spin_lock_irqsave(&lcu->lock, flags);
 264                if (device == lcu->suc_data.device) {
 265                        dasd_put_device(device);
 266                        lcu->suc_data.device = NULL;
 267                }
 268        }
 269        was_pending = 0;
 270        if (device == lcu->ruac_data.device) {
 271                spin_unlock_irqrestore(&lcu->lock, flags);
 272                was_pending = 1;
 273                cancel_delayed_work_sync(&lcu->ruac_data.dwork);
 274                spin_lock_irqsave(&lcu->lock, flags);
 275                if (device == lcu->ruac_data.device) {
 276                        dasd_put_device(device);
 277                        lcu->ruac_data.device = NULL;
 278                }
 279        }
 280        private->lcu = NULL;
 281        spin_unlock_irqrestore(&lcu->lock, flags);
 282
 283        spin_lock_irqsave(&aliastree.lock, flags);
 284        spin_lock(&lcu->lock);
 285        list_del_init(&device->alias_list);
 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)
 466                goto out;
 467
 468        if (suborder_not_supported(cqr)) {
 469                /* suborder not supported or device unusable for IO */
 470                rc = -EOPNOTSUPP;
 471        } else {
 472                /* IO failed but should be retried */
 473                spin_lock_irqsave(&lcu->lock, flags);
 474                lcu->flags |= NEED_UAC_UPDATE;
 475                spin_unlock_irqrestore(&lcu->lock, flags);
 476        }
 477out:
 478        dasd_sfree_request(cqr, cqr->memdev);
 479        return rc;
 480}
 481
 482static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu)
 483{
 484        unsigned long flags;
 485        struct alias_pav_group *pavgroup, *tempgroup;
 486        struct dasd_device *device, *tempdev;
 487        int i, rc;
 488        struct dasd_eckd_private *private;
 489
 490        spin_lock_irqsave(&lcu->lock, flags);
 491        list_for_each_entry_safe(pavgroup, tempgroup, &lcu->grouplist, group) {
 492                list_for_each_entry_safe(device, tempdev, &pavgroup->baselist,
 493                                         alias_list) {
 494                        list_move(&device->alias_list, &lcu->active_devices);
 495                        private = device->private;
 496                        private->pavgroup = NULL;
 497                }
 498                list_for_each_entry_safe(device, tempdev, &pavgroup->aliaslist,
 499                                         alias_list) {
 500                        list_move(&device->alias_list, &lcu->active_devices);
 501                        private = device->private;
 502                        private->pavgroup = NULL;
 503                }
 504                list_del(&pavgroup->group);
 505                kfree(pavgroup);
 506        }
 507        spin_unlock_irqrestore(&lcu->lock, flags);
 508
 509        rc = read_unit_address_configuration(refdev, lcu);
 510        if (rc)
 511                return rc;
 512
 513        spin_lock_irqsave(&lcu->lock, flags);
 514        /*
 515         * there is another update needed skip the remaining handling
 516         * the data might already be outdated
 517         * but especially do not add the device to an LCU with pending
 518         * update
 519         */
 520        if (lcu->flags & NEED_UAC_UPDATE)
 521                goto out;
 522        lcu->pav = NO_PAV;
 523        for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) {
 524                switch (lcu->uac->unit[i].ua_type) {
 525                case UA_BASE_PAV_ALIAS:
 526                        lcu->pav = BASE_PAV;
 527                        break;
 528                case UA_HYPER_PAV_ALIAS:
 529                        lcu->pav = HYPER_PAV;
 530                        break;
 531                }
 532                if (lcu->pav != NO_PAV)
 533                        break;
 534        }
 535
 536        list_for_each_entry_safe(device, tempdev, &lcu->active_devices,
 537                                 alias_list) {
 538                _add_device_to_lcu(lcu, device, refdev);
 539        }
 540out:
 541        spin_unlock_irqrestore(&lcu->lock, flags);
 542        return 0;
 543}
 544
 545static void lcu_update_work(struct work_struct *work)
 546{
 547        struct alias_lcu *lcu;
 548        struct read_uac_work_data *ruac_data;
 549        struct dasd_device *device;
 550        unsigned long flags;
 551        int rc;
 552
 553        ruac_data = container_of(work, struct read_uac_work_data, dwork.work);
 554        lcu = container_of(ruac_data, struct alias_lcu, ruac_data);
 555        device = ruac_data->device;
 556        rc = _lcu_update(device, lcu);
 557        /*
 558         * Need to check flags again, as there could have been another
 559         * prepare_update or a new device a new device while we were still
 560         * processing the data
 561         */
 562        spin_lock_irqsave(&lcu->lock, flags);
 563        if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
 564                DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 565                            " alias data in lcu (rc = %d), retry later", rc);
 566                if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
 567                        dasd_put_device(device);
 568        } else {
 569                dasd_put_device(device);
 570                lcu->ruac_data.device = NULL;
 571                lcu->flags &= ~UPDATE_PENDING;
 572        }
 573        spin_unlock_irqrestore(&lcu->lock, flags);
 574}
 575
 576static int _schedule_lcu_update(struct alias_lcu *lcu,
 577                                struct dasd_device *device)
 578{
 579        struct dasd_device *usedev = NULL;
 580        struct alias_pav_group *group;
 581
 582        lcu->flags |= NEED_UAC_UPDATE;
 583        if (lcu->ruac_data.device) {
 584                /* already scheduled or running */
 585                return 0;
 586        }
 587        if (device && !list_empty(&device->alias_list))
 588                usedev = device;
 589
 590        if (!usedev && !list_empty(&lcu->grouplist)) {
 591                group = list_first_entry(&lcu->grouplist,
 592                                         struct alias_pav_group, group);
 593                if (!list_empty(&group->baselist))
 594                        usedev = list_first_entry(&group->baselist,
 595                                                  struct dasd_device,
 596                                                  alias_list);
 597                else if (!list_empty(&group->aliaslist))
 598                        usedev = list_first_entry(&group->aliaslist,
 599                                                  struct dasd_device,
 600                                                  alias_list);
 601        }
 602        if (!usedev && !list_empty(&lcu->active_devices)) {
 603                usedev = list_first_entry(&lcu->active_devices,
 604                                          struct dasd_device, alias_list);
 605        }
 606        /*
 607         * if we haven't found a proper device yet, give up for now, the next
 608         * device that will be set active will trigger an lcu update
 609         */
 610        if (!usedev)
 611                return -EINVAL;
 612        dasd_get_device(usedev);
 613        lcu->ruac_data.device = usedev;
 614        if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
 615                dasd_put_device(usedev);
 616        return 0;
 617}
 618
 619int dasd_alias_add_device(struct dasd_device *device)
 620{
 621        struct dasd_eckd_private *private = device->private;
 622        __u8 uaddr = private->uid.real_unit_addr;
 623        struct alias_lcu *lcu = private->lcu;
 624        unsigned long flags;
 625        int rc;
 626
 627        rc = 0;
 628        spin_lock_irqsave(&lcu->lock, flags);
 629        /*
 630         * Check if device and lcu type differ. If so, the uac data may be
 631         * outdated and needs to be updated.
 632         */
 633        if (private->uid.type !=  lcu->uac->unit[uaddr].ua_type) {
 634                lcu->flags |= UPDATE_PENDING;
 635                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 636                              "uid type mismatch - trigger rescan");
 637        }
 638        if (!(lcu->flags & UPDATE_PENDING)) {
 639                rc = _add_device_to_lcu(lcu, device, device);
 640                if (rc)
 641                        lcu->flags |= UPDATE_PENDING;
 642        }
 643        if (lcu->flags & UPDATE_PENDING) {
 644                list_move(&device->alias_list, &lcu->active_devices);
 645                private->pavgroup = NULL;
 646                _schedule_lcu_update(lcu, device);
 647        }
 648        spin_unlock_irqrestore(&lcu->lock, flags);
 649        return rc;
 650}
 651
 652int dasd_alias_update_add_device(struct dasd_device *device)
 653{
 654        struct dasd_eckd_private *private = device->private;
 655
 656        private->lcu->flags |= UPDATE_PENDING;
 657        return dasd_alias_add_device(device);
 658}
 659
 660int dasd_alias_remove_device(struct dasd_device *device)
 661{
 662        struct dasd_eckd_private *private = device->private;
 663        struct alias_lcu *lcu = private->lcu;
 664        unsigned long flags;
 665
 666        /* nothing to do if already removed */
 667        if (!lcu)
 668                return 0;
 669        spin_lock_irqsave(&lcu->lock, flags);
 670        _remove_device_from_lcu(lcu, device);
 671        spin_unlock_irqrestore(&lcu->lock, flags);
 672        return 0;
 673}
 674
 675struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
 676{
 677        struct dasd_eckd_private *alias_priv, *private = base_device->private;
 678        struct alias_pav_group *group = private->pavgroup;
 679        struct alias_lcu *lcu = private->lcu;
 680        struct dasd_device *alias_device;
 681        unsigned long flags;
 682
 683        if (!group || !lcu)
 684                return NULL;
 685        if (lcu->pav == NO_PAV ||
 686            lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
 687                return NULL;
 688        if (unlikely(!(private->features.feature[8] & 0x01))) {
 689                /*
 690                 * PAV enabled but prefix not, very unlikely
 691                 * seems to be a lost pathgroup
 692                 * use base device to do IO
 693                 */
 694                DBF_DEV_EVENT(DBF_ERR, base_device, "%s",
 695                              "Prefix not enabled with PAV enabled\n");
 696                return NULL;
 697        }
 698
 699        spin_lock_irqsave(&lcu->lock, flags);
 700        alias_device = group->next;
 701        if (!alias_device) {
 702                if (list_empty(&group->aliaslist)) {
 703                        spin_unlock_irqrestore(&lcu->lock, flags);
 704                        return NULL;
 705                } else {
 706                        alias_device = list_first_entry(&group->aliaslist,
 707                                                        struct dasd_device,
 708                                                        alias_list);
 709                }
 710        }
 711        if (list_is_last(&alias_device->alias_list, &group->aliaslist))
 712                group->next = list_first_entry(&group->aliaslist,
 713                                               struct dasd_device, alias_list);
 714        else
 715                group->next = list_first_entry(&alias_device->alias_list,
 716                                               struct dasd_device, alias_list);
 717        spin_unlock_irqrestore(&lcu->lock, flags);
 718        alias_priv = alias_device->private;
 719        if ((alias_priv->count < private->count) && !alias_device->stopped &&
 720            !test_bit(DASD_FLAG_OFFLINE, &alias_device->flags))
 721                return alias_device;
 722        else
 723                return NULL;
 724}
 725
 726/*
 727 * Summary unit check handling depends on the way alias devices
 728 * are handled so it is done here rather then in dasd_eckd.c
 729 */
 730static int reset_summary_unit_check(struct alias_lcu *lcu,
 731                                    struct dasd_device *device,
 732                                    char reason)
 733{
 734        struct dasd_ccw_req *cqr;
 735        int rc = 0;
 736        struct ccw1 *ccw;
 737
 738        cqr = lcu->rsu_cqr;
 739        memcpy((char *) &cqr->magic, "ECKD", 4);
 740        ASCEBC((char *) &cqr->magic, 4);
 741        ccw = cqr->cpaddr;
 742        ccw->cmd_code = DASD_ECKD_CCW_RSCK;
 743        ccw->flags = CCW_FLAG_SLI;
 744        ccw->count = 16;
 745        ccw->cda = (__u32)(addr_t) cqr->data;
 746        ((char *)cqr->data)[0] = reason;
 747
 748        clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 749        cqr->retries = 255;     /* set retry counter to enable basic ERP */
 750        cqr->startdev = device;
 751        cqr->memdev = device;
 752        cqr->block = NULL;
 753        cqr->expires = 5 * HZ;
 754        cqr->buildclk = get_tod_clock();
 755        cqr->status = DASD_CQR_FILLED;
 756
 757        rc = dasd_sleep_on_immediatly(cqr);
 758        return rc;
 759}
 760
 761static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu)
 762{
 763        struct alias_pav_group *pavgroup;
 764        struct dasd_device *device;
 765        struct dasd_eckd_private *private;
 766
 767        /* active and inactive list can contain alias as well as base devices */
 768        list_for_each_entry(device, &lcu->active_devices, alias_list) {
 769                private = device->private;
 770                if (private->uid.type != UA_BASE_DEVICE)
 771                        continue;
 772                dasd_schedule_block_bh(device->block);
 773                dasd_schedule_device_bh(device);
 774        }
 775        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 776                private = device->private;
 777                if (private->uid.type != UA_BASE_DEVICE)
 778                        continue;
 779                dasd_schedule_block_bh(device->block);
 780                dasd_schedule_device_bh(device);
 781        }
 782        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 783                list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 784                        dasd_schedule_block_bh(device->block);
 785                        dasd_schedule_device_bh(device);
 786                }
 787        }
 788}
 789
 790static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu)
 791{
 792        struct alias_pav_group *pavgroup;
 793        struct dasd_device *device, *temp;
 794        struct dasd_eckd_private *private;
 795        unsigned long flags;
 796        LIST_HEAD(active);
 797
 798        /*
 799         * Problem here ist that dasd_flush_device_queue may wait
 800         * for termination of a request to complete. We can't keep
 801         * the lcu lock during that time, so we must assume that
 802         * the lists may have changed.
 803         * Idea: first gather all active alias devices in a separate list,
 804         * then flush the first element of this list unlocked, and afterwards
 805         * check if it is still on the list before moving it to the
 806         * active_devices list.
 807         */
 808
 809        spin_lock_irqsave(&lcu->lock, flags);
 810        list_for_each_entry_safe(device, temp, &lcu->active_devices,
 811                                 alias_list) {
 812                private = device->private;
 813                if (private->uid.type == UA_BASE_DEVICE)
 814                        continue;
 815                list_move(&device->alias_list, &active);
 816        }
 817
 818        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 819                list_splice_init(&pavgroup->aliaslist, &active);
 820        }
 821        while (!list_empty(&active)) {
 822                device = list_first_entry(&active, struct dasd_device,
 823                                          alias_list);
 824                spin_unlock_irqrestore(&lcu->lock, flags);
 825                dasd_flush_device_queue(device);
 826                spin_lock_irqsave(&lcu->lock, flags);
 827                /*
 828                 * only move device around if it wasn't moved away while we
 829                 * were waiting for the flush
 830                 */
 831                if (device == list_first_entry(&active,
 832                                               struct dasd_device, alias_list)) {
 833                        list_move(&device->alias_list, &lcu->active_devices);
 834                        private = device->private;
 835                        private->pavgroup = NULL;
 836                }
 837        }
 838        spin_unlock_irqrestore(&lcu->lock, flags);
 839}
 840
 841static void _stop_all_devices_on_lcu(struct alias_lcu *lcu)
 842{
 843        struct alias_pav_group *pavgroup;
 844        struct dasd_device *device;
 845
 846        list_for_each_entry(device, &lcu->active_devices, alias_list) {
 847                spin_lock(get_ccwdev_lock(device->cdev));
 848                dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 849                spin_unlock(get_ccwdev_lock(device->cdev));
 850        }
 851        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 852                spin_lock(get_ccwdev_lock(device->cdev));
 853                dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 854                spin_unlock(get_ccwdev_lock(device->cdev));
 855        }
 856        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 857                list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 858                        spin_lock(get_ccwdev_lock(device->cdev));
 859                        dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 860                        spin_unlock(get_ccwdev_lock(device->cdev));
 861                }
 862                list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 863                        spin_lock(get_ccwdev_lock(device->cdev));
 864                        dasd_device_set_stop_bits(device, DASD_STOPPED_SU);
 865                        spin_unlock(get_ccwdev_lock(device->cdev));
 866                }
 867        }
 868}
 869
 870static void _unstop_all_devices_on_lcu(struct alias_lcu *lcu)
 871{
 872        struct alias_pav_group *pavgroup;
 873        struct dasd_device *device;
 874
 875        list_for_each_entry(device, &lcu->active_devices, alias_list) {
 876                spin_lock(get_ccwdev_lock(device->cdev));
 877                dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 878                spin_unlock(get_ccwdev_lock(device->cdev));
 879        }
 880        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 881                spin_lock(get_ccwdev_lock(device->cdev));
 882                dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 883                spin_unlock(get_ccwdev_lock(device->cdev));
 884        }
 885        list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 886                list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 887                        spin_lock(get_ccwdev_lock(device->cdev));
 888                        dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 889                        spin_unlock(get_ccwdev_lock(device->cdev));
 890                }
 891                list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 892                        spin_lock(get_ccwdev_lock(device->cdev));
 893                        dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 894                        spin_unlock(get_ccwdev_lock(device->cdev));
 895                }
 896        }
 897}
 898
 899static void summary_unit_check_handling_work(struct work_struct *work)
 900{
 901        struct alias_lcu *lcu;
 902        struct summary_unit_check_work_data *suc_data;
 903        unsigned long flags;
 904        struct dasd_device *device;
 905
 906        suc_data = container_of(work, struct summary_unit_check_work_data,
 907                                worker);
 908        lcu = container_of(suc_data, struct alias_lcu, suc_data);
 909        device = suc_data->device;
 910
 911        /* 1. flush alias devices */
 912        flush_all_alias_devices_on_lcu(lcu);
 913
 914        /* 2. reset summary unit check */
 915        spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 916        dasd_device_remove_stop_bits(device,
 917                                     (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
 918        spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 919        reset_summary_unit_check(lcu, device, suc_data->reason);
 920
 921        spin_lock_irqsave(&lcu->lock, flags);
 922        _unstop_all_devices_on_lcu(lcu);
 923        _restart_all_base_devices_on_lcu(lcu);
 924        /* 3. read new alias configuration */
 925        _schedule_lcu_update(lcu, device);
 926        lcu->suc_data.device = NULL;
 927        dasd_put_device(device);
 928        spin_unlock_irqrestore(&lcu->lock, flags);
 929}
 930
 931void dasd_alias_handle_summary_unit_check(struct work_struct *work)
 932{
 933        struct dasd_device *device = container_of(work, struct dasd_device,
 934                                                  suc_work);
 935        struct dasd_eckd_private *private = device->private;
 936        struct alias_lcu *lcu;
 937        unsigned long flags;
 938
 939        lcu = private->lcu;
 940        if (!lcu) {
 941                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 942                            "device not ready to handle summary"
 943                            " unit check (no lcu structure)");
 944                goto out;
 945        }
 946        spin_lock_irqsave(&lcu->lock, flags);
 947        /* If this device is about to be removed just return and wait for
 948         * the next interrupt on a different device
 949         */
 950        if (list_empty(&device->alias_list)) {
 951                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 952                            "device is in offline processing,"
 953                            " don't do summary unit check handling");
 954                goto out_unlock;
 955        }
 956        if (lcu->suc_data.device) {
 957                /* already scheduled or running */
 958                DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 959                            "previous instance of summary unit check worker"
 960                            " still pending");
 961                goto out_unlock;
 962        }
 963        _stop_all_devices_on_lcu(lcu);
 964        /* prepare for lcu_update */
 965        lcu->flags |= NEED_UAC_UPDATE | UPDATE_PENDING;
 966        lcu->suc_data.reason = private->suc_reason;
 967        lcu->suc_data.device = device;
 968        dasd_get_device(device);
 969        if (!schedule_work(&lcu->suc_data.worker))
 970                dasd_put_device(device);
 971out_unlock:
 972        spin_unlock_irqrestore(&lcu->lock, flags);
 973out:
 974        clear_bit(DASD_FLAG_SUC, &device->flags);
 975        dasd_put_device(device);
 976};
 977