linux/drivers/s390/scsi/zfcp_ccw.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * zfcp device driver
   4 *
   5 * Registration and callback for the s390 common I/O layer.
   6 *
   7 * Copyright IBM Corp. 2002, 2010
   8 */
   9
  10#define KMSG_COMPONENT "zfcp"
  11#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  12
  13#include <linux/module.h>
  14#include "zfcp_ext.h"
  15#include "zfcp_reqlist.h"
  16
  17#define ZFCP_MODEL_PRIV 0x4
  18
  19static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
  20
  21struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
  22{
  23        struct zfcp_adapter *adapter;
  24        unsigned long flags;
  25
  26        spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
  27        adapter = dev_get_drvdata(&cdev->dev);
  28        if (adapter)
  29                kref_get(&adapter->ref);
  30        spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
  31        return adapter;
  32}
  33
  34void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
  35{
  36        unsigned long flags;
  37
  38        spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
  39        kref_put(&adapter->ref, zfcp_adapter_release);
  40        spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
  41}
  42
  43/**
  44 * zfcp_ccw_activate - activate adapter and wait for it to finish
  45 * @cdev: pointer to belonging ccw device
  46 * @clear: Status flags to clear.
  47 * @tag: s390dbf trace record tag
  48 */
  49static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
  50{
  51        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  52
  53        if (!adapter)
  54                return 0;
  55
  56        zfcp_erp_clear_adapter_status(adapter, clear);
  57        zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
  58        zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
  59                                tag);
  60
  61        /*
  62         * We want to scan ports here, with some random backoff and without
  63         * rate limit. Recovery has already scheduled a port scan for us,
  64         * but with both random delay and rate limit. Nevertheless we get
  65         * what we want here by flushing the scheduled work after sleeping
  66         * an equivalent random time.
  67         * Let the port scan random delay elapse first. If recovery finishes
  68         * up to that point in time, that would be perfect for both recovery
  69         * and port scan. If not, i.e. recovery takes ages, there was no
  70         * point in waiting a random delay on top of the time consumed by
  71         * recovery.
  72         */
  73        msleep(zfcp_fc_port_scan_backoff());
  74        zfcp_erp_wait(adapter);
  75        flush_delayed_work(&adapter->scan_work);
  76
  77        zfcp_ccw_adapter_put(adapter);
  78
  79        return 0;
  80}
  81
  82static struct ccw_device_id zfcp_ccw_device_id[] = {
  83        { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
  84        { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
  85        {},
  86};
  87MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
  88
  89/**
  90 * zfcp_ccw_probe - probe function of zfcp driver
  91 * @cdev: pointer to belonging ccw device
  92 *
  93 * This function gets called by the common i/o layer for each FCP
  94 * device found on the current system. This is only a stub to make cio
  95 * work: To only allocate adapter resources for devices actually used,
  96 * the allocation is deferred to the first call to ccw_set_online.
  97 */
  98static int zfcp_ccw_probe(struct ccw_device *cdev)
  99{
 100        return 0;
 101}
 102
 103/**
 104 * zfcp_ccw_remove - remove function of zfcp driver
 105 * @cdev: pointer to belonging ccw device
 106 *
 107 * This function gets called by the common i/o layer and removes an adapter
 108 * from the system. Task of this function is to get rid of all units and
 109 * ports that belong to this adapter. And in addition all resources of this
 110 * adapter will be freed too.
 111 */
 112static void zfcp_ccw_remove(struct ccw_device *cdev)
 113{
 114        struct zfcp_adapter *adapter;
 115        struct zfcp_port *port, *p;
 116        struct zfcp_unit *unit, *u;
 117        LIST_HEAD(unit_remove_lh);
 118        LIST_HEAD(port_remove_lh);
 119
 120        ccw_device_set_offline(cdev);
 121
 122        adapter = zfcp_ccw_adapter_by_cdev(cdev);
 123        if (!adapter)
 124                return;
 125
 126        write_lock_irq(&adapter->port_list_lock);
 127        list_for_each_entry_safe(port, p, &adapter->port_list, list) {
 128                write_lock(&port->unit_list_lock);
 129                list_for_each_entry_safe(unit, u, &port->unit_list, list)
 130                        list_move(&unit->list, &unit_remove_lh);
 131                write_unlock(&port->unit_list_lock);
 132                list_move(&port->list, &port_remove_lh);
 133        }
 134        write_unlock_irq(&adapter->port_list_lock);
 135        zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
 136
 137        list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
 138                device_unregister(&unit->dev);
 139
 140        list_for_each_entry_safe(port, p, &port_remove_lh, list)
 141                device_unregister(&port->dev);
 142
 143        zfcp_adapter_unregister(adapter);
 144}
 145
 146/**
 147 * zfcp_ccw_set_online - set_online function of zfcp driver
 148 * @cdev: pointer to belonging ccw device
 149 *
 150 * This function gets called by the common i/o layer and sets an
 151 * adapter into state online.  The first call will allocate all
 152 * adapter resources that will be retained until the device is removed
 153 * via zfcp_ccw_remove.
 154 *
 155 * Setting an fcp device online means that it will be registered with
 156 * the SCSI stack, that the QDIO queues will be set up and that the
 157 * adapter will be opened.
 158 */
 159static int zfcp_ccw_set_online(struct ccw_device *cdev)
 160{
 161        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 162
 163        if (!adapter) {
 164                adapter = zfcp_adapter_enqueue(cdev);
 165
 166                if (IS_ERR(adapter)) {
 167                        dev_err(&cdev->dev,
 168                                "Setting up data structures for the "
 169                                "FCP adapter failed\n");
 170                        return PTR_ERR(adapter);
 171                }
 172                kref_get(&adapter->ref);
 173        }
 174
 175        /* initialize request counter */
 176        BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
 177        adapter->req_no = 0;
 178
 179        zfcp_ccw_activate(cdev, 0, "ccsonl1");
 180
 181        /*
 182         * We want to scan ports here, always, with some random delay and
 183         * without rate limit - basically what zfcp_ccw_activate() has
 184         * achieved for us. Not quite! That port scan depended on
 185         * !no_auto_port_rescan. So let's cover the no_auto_port_rescan
 186         * case here to make sure a port scan is done unconditionally.
 187         * Since zfcp_ccw_activate() has waited the desired random time,
 188         * we can immediately schedule and flush a port scan for the
 189         * remaining cases.
 190         */
 191        zfcp_fc_inverse_conditional_port_scan(adapter);
 192        flush_delayed_work(&adapter->scan_work);
 193        zfcp_ccw_adapter_put(adapter);
 194        return 0;
 195}
 196
 197/**
 198 * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
 199 * @cdev: pointer to belonging ccw device
 200 * @set: Status flags to set.
 201 * @tag: s390dbf trace record tag
 202 *
 203 * This function gets called by the common i/o layer and sets an adapter
 204 * into state offline.
 205 */
 206static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
 207{
 208        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 209
 210        if (!adapter)
 211                return 0;
 212
 213        zfcp_erp_set_adapter_status(adapter, set);
 214        zfcp_erp_adapter_shutdown(adapter, 0, tag);
 215        zfcp_erp_wait(adapter);
 216
 217        zfcp_ccw_adapter_put(adapter);
 218        return 0;
 219}
 220
 221/**
 222 * zfcp_ccw_set_offline - set_offline function of zfcp driver
 223 * @cdev: pointer to belonging ccw device
 224 *
 225 * This function gets called by the common i/o layer and sets an adapter
 226 * into state offline.
 227 */
 228static int zfcp_ccw_set_offline(struct ccw_device *cdev)
 229{
 230        return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
 231}
 232
 233/**
 234 * zfcp_ccw_notify - ccw notify function
 235 * @cdev: pointer to belonging ccw device
 236 * @event: indicates if adapter was detached or attached
 237 *
 238 * This function gets called by the common i/o layer if an adapter has gone
 239 * or reappeared.
 240 */
 241static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
 242{
 243        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 244
 245        if (!adapter)
 246                return 1;
 247
 248        switch (event) {
 249        case CIO_GONE:
 250                if (atomic_read(&adapter->status) &
 251                    ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
 252                        zfcp_dbf_hba_basic("ccnigo1", adapter);
 253                        break;
 254                }
 255                dev_warn(&cdev->dev, "The FCP device has been detached\n");
 256                zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
 257                break;
 258        case CIO_NO_PATH:
 259                dev_warn(&cdev->dev,
 260                         "The CHPID for the FCP device is offline\n");
 261                zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
 262                break;
 263        case CIO_OPER:
 264                if (atomic_read(&adapter->status) &
 265                    ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
 266                        zfcp_dbf_hba_basic("ccniop1", adapter);
 267                        break;
 268                }
 269                dev_info(&cdev->dev, "The FCP device is operational again\n");
 270                zfcp_erp_set_adapter_status(adapter,
 271                                            ZFCP_STATUS_COMMON_RUNNING);
 272                zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 273                                        "ccnoti4");
 274                break;
 275        case CIO_BOXED:
 276                dev_warn(&cdev->dev, "The FCP device did not respond within "
 277                                     "the specified time\n");
 278                zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
 279                break;
 280        }
 281
 282        zfcp_ccw_adapter_put(adapter);
 283        return 1;
 284}
 285
 286/**
 287 * zfcp_ccw_shutdown - handle shutdown from cio
 288 * @cdev: device for adapter to shutdown.
 289 */
 290static void zfcp_ccw_shutdown(struct ccw_device *cdev)
 291{
 292        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 293
 294        if (!adapter)
 295                return;
 296
 297        zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
 298        zfcp_erp_wait(adapter);
 299        zfcp_erp_thread_kill(adapter);
 300
 301        zfcp_ccw_adapter_put(adapter);
 302}
 303
 304static int zfcp_ccw_suspend(struct ccw_device *cdev)
 305{
 306        zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
 307        return 0;
 308}
 309
 310static int zfcp_ccw_thaw(struct ccw_device *cdev)
 311{
 312        /* trace records for thaw and final shutdown during suspend
 313           can only be found in system dump until the end of suspend
 314           but not after resume because it's based on the memory image
 315           right after the very first suspend (freeze) callback */
 316        zfcp_ccw_activate(cdev, 0, "ccthaw1");
 317        return 0;
 318}
 319
 320static int zfcp_ccw_resume(struct ccw_device *cdev)
 321{
 322        zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
 323        return 0;
 324}
 325
 326struct ccw_driver zfcp_ccw_driver = {
 327        .driver = {
 328                .owner  = THIS_MODULE,
 329                .name   = "zfcp",
 330        },
 331        .ids         = zfcp_ccw_device_id,
 332        .probe       = zfcp_ccw_probe,
 333        .remove      = zfcp_ccw_remove,
 334        .set_online  = zfcp_ccw_set_online,
 335        .set_offline = zfcp_ccw_set_offline,
 336        .notify      = zfcp_ccw_notify,
 337        .shutdown    = zfcp_ccw_shutdown,
 338        .freeze      = zfcp_ccw_suspend,
 339        .thaw        = zfcp_ccw_thaw,
 340        .restore     = zfcp_ccw_resume,
 341};
 342