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