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(port, &adapter->port_list, list) {
 128                write_lock(&port->unit_list_lock);
 129                list_splice_init(&port->unit_list, &unit_remove_lh);
 130                write_unlock(&port->unit_list_lock);
 131        }
 132        list_splice_init(&adapter->port_list, &port_remove_lh);
 133        write_unlock_irq(&adapter->port_list_lock);
 134        zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
 135
 136        list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
 137                device_unregister(&unit->dev);
 138
 139        list_for_each_entry_safe(port, p, &port_remove_lh, list)
 140                device_unregister(&port->dev);
 141
 142        zfcp_adapter_unregister(adapter);
 143}
 144
 145/**
 146 * zfcp_ccw_set_online - set_online function of zfcp driver
 147 * @cdev: pointer to belonging ccw device
 148 *
 149 * This function gets called by the common i/o layer and sets an
 150 * adapter into state online.  The first call will allocate all
 151 * adapter resources that will be retained until the device is removed
 152 * via zfcp_ccw_remove.
 153 *
 154 * Setting an fcp device online means that it will be registered with
 155 * the SCSI stack, that the QDIO queues will be set up and that the
 156 * adapter will be opened.
 157 */
 158static int zfcp_ccw_set_online(struct ccw_device *cdev)
 159{
 160        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 161
 162        if (!adapter) {
 163                adapter = zfcp_adapter_enqueue(cdev);
 164
 165                if (IS_ERR(adapter)) {
 166                        dev_err(&cdev->dev,
 167                                "Setting up data structures for the "
 168                                "FCP adapter failed\n");
 169                        return PTR_ERR(adapter);
 170                }
 171                kref_get(&adapter->ref);
 172        }
 173
 174        /* initialize request counter */
 175        BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
 176        adapter->req_no = 0;
 177
 178        zfcp_ccw_activate(cdev, 0, "ccsonl1");
 179
 180        /*
 181         * We want to scan ports here, always, with some random delay and
 182         * without rate limit - basically what zfcp_ccw_activate() has
 183         * achieved for us. Not quite! That port scan depended on
 184         * !no_auto_port_rescan. So let's cover the no_auto_port_rescan
 185         * case here to make sure a port scan is done unconditionally.
 186         * Since zfcp_ccw_activate() has waited the desired random time,
 187         * we can immediately schedule and flush a port scan for the
 188         * remaining cases.
 189         */
 190        zfcp_fc_inverse_conditional_port_scan(adapter);
 191        flush_delayed_work(&adapter->scan_work);
 192        zfcp_ccw_adapter_put(adapter);
 193        return 0;
 194}
 195
 196/**
 197 * zfcp_ccw_set_offline - set_offline function of zfcp driver
 198 * @cdev: pointer to belonging ccw device
 199 *
 200 * This function gets called by the common i/o layer and sets an adapter
 201 * into state offline.
 202 */
 203static int zfcp_ccw_set_offline(struct ccw_device *cdev)
 204{
 205        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 206
 207        if (!adapter)
 208                return 0;
 209
 210        zfcp_erp_set_adapter_status(adapter, 0);
 211        zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
 212        zfcp_erp_wait(adapter);
 213
 214        zfcp_ccw_adapter_put(adapter);
 215        return 0;
 216}
 217
 218/**
 219 * zfcp_ccw_notify - ccw notify function
 220 * @cdev: pointer to belonging ccw device
 221 * @event: indicates if adapter was detached or attached
 222 *
 223 * This function gets called by the common i/o layer if an adapter has gone
 224 * or reappeared.
 225 */
 226static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
 227{
 228        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 229
 230        if (!adapter)
 231                return 1;
 232
 233        switch (event) {
 234        case CIO_GONE:
 235                dev_warn(&cdev->dev, "The FCP device has been detached\n");
 236                zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
 237                break;
 238        case CIO_NO_PATH:
 239                dev_warn(&cdev->dev,
 240                         "The CHPID for the FCP device is offline\n");
 241                zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
 242                break;
 243        case CIO_OPER:
 244                dev_info(&cdev->dev, "The FCP device is operational again\n");
 245                zfcp_erp_set_adapter_status(adapter,
 246                                            ZFCP_STATUS_COMMON_RUNNING);
 247                zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 248                                        "ccnoti4");
 249                break;
 250        case CIO_BOXED:
 251                dev_warn(&cdev->dev, "The FCP device did not respond within "
 252                                     "the specified time\n");
 253                zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
 254                break;
 255        }
 256
 257        zfcp_ccw_adapter_put(adapter);
 258        return 1;
 259}
 260
 261/**
 262 * zfcp_ccw_shutdown - handle shutdown from cio
 263 * @cdev: device for adapter to shutdown.
 264 */
 265static void zfcp_ccw_shutdown(struct ccw_device *cdev)
 266{
 267        struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 268
 269        if (!adapter)
 270                return;
 271
 272        zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
 273        zfcp_erp_wait(adapter);
 274        zfcp_erp_thread_kill(adapter);
 275
 276        zfcp_ccw_adapter_put(adapter);
 277}
 278
 279struct ccw_driver zfcp_ccw_driver = {
 280        .driver = {
 281                .owner  = THIS_MODULE,
 282                .name   = "zfcp",
 283        },
 284        .ids         = zfcp_ccw_device_id,
 285        .probe       = zfcp_ccw_probe,
 286        .remove      = zfcp_ccw_remove,
 287        .set_online  = zfcp_ccw_set_online,
 288        .set_offline = zfcp_ccw_set_offline,
 289        .notify      = zfcp_ccw_notify,
 290        .shutdown    = zfcp_ccw_shutdown,
 291};
 292