linux/drivers/scsi/device_handler/scsi_dh_alua.c
<<
>>
Prefs
   1/*
   2 * Generic SCSI-3 ALUA SCSI Device Handler
   3 *
   4 * Copyright (C) 2007-2010 Hannes Reinecke, SUSE Linux Products GmbH.
   5 * All rights reserved.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20 *
  21 */
  22#include <linux/slab.h>
  23#include <linux/delay.h>
  24#include <scsi/scsi.h>
  25#include <scsi/scsi_eh.h>
  26#include <scsi/scsi_dh.h>
  27
  28#define ALUA_DH_NAME "alua"
  29#define ALUA_DH_VER "1.3"
  30
  31#define TPGS_STATE_OPTIMIZED            0x0
  32#define TPGS_STATE_NONOPTIMIZED         0x1
  33#define TPGS_STATE_STANDBY              0x2
  34#define TPGS_STATE_UNAVAILABLE          0x3
  35#define TPGS_STATE_LBA_DEPENDENT        0x4
  36#define TPGS_STATE_OFFLINE              0xe
  37#define TPGS_STATE_TRANSITIONING        0xf
  38
  39#define TPGS_SUPPORT_NONE               0x00
  40#define TPGS_SUPPORT_OPTIMIZED          0x01
  41#define TPGS_SUPPORT_NONOPTIMIZED       0x02
  42#define TPGS_SUPPORT_STANDBY            0x04
  43#define TPGS_SUPPORT_UNAVAILABLE        0x08
  44#define TPGS_SUPPORT_LBA_DEPENDENT      0x10
  45#define TPGS_SUPPORT_OFFLINE            0x40
  46#define TPGS_SUPPORT_TRANSITION         0x80
  47
  48#define TPGS_MODE_UNINITIALIZED          -1
  49#define TPGS_MODE_NONE                  0x0
  50#define TPGS_MODE_IMPLICIT              0x1
  51#define TPGS_MODE_EXPLICIT              0x2
  52
  53#define ALUA_INQUIRY_SIZE               36
  54#define ALUA_FAILOVER_TIMEOUT           (60 * HZ)
  55#define ALUA_FAILOVER_RETRIES           5
  56
  57struct alua_dh_data {
  58        int                     group_id;
  59        int                     rel_port;
  60        int                     tpgs;
  61        int                     state;
  62        unsigned char           inq[ALUA_INQUIRY_SIZE];
  63        unsigned char           *buff;
  64        int                     bufflen;
  65        unsigned char           sense[SCSI_SENSE_BUFFERSIZE];
  66        int                     senselen;
  67        struct scsi_device      *sdev;
  68        activate_complete       callback_fn;
  69        void                    *callback_data;
  70};
  71
  72#define ALUA_POLICY_SWITCH_CURRENT      0
  73#define ALUA_POLICY_SWITCH_ALL          1
  74
  75static char print_alua_state(int);
  76static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
  77
  78static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev)
  79{
  80        struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
  81        BUG_ON(scsi_dh_data == NULL);
  82        return ((struct alua_dh_data *) scsi_dh_data->buf);
  83}
  84
  85static int realloc_buffer(struct alua_dh_data *h, unsigned len)
  86{
  87        if (h->buff && h->buff != h->inq)
  88                kfree(h->buff);
  89
  90        h->buff = kmalloc(len, GFP_NOIO);
  91        if (!h->buff) {
  92                h->buff = h->inq;
  93                h->bufflen = ALUA_INQUIRY_SIZE;
  94                return 1;
  95        }
  96        h->bufflen = len;
  97        return 0;
  98}
  99
 100static struct request *get_alua_req(struct scsi_device *sdev,
 101                                    void *buffer, unsigned buflen, int rw)
 102{
 103        struct request *rq;
 104        struct request_queue *q = sdev->request_queue;
 105
 106        rq = blk_get_request(q, rw, GFP_NOIO);
 107
 108        if (!rq) {
 109                sdev_printk(KERN_INFO, sdev,
 110                            "%s: blk_get_request failed\n", __func__);
 111                return NULL;
 112        }
 113
 114        if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
 115                blk_put_request(rq);
 116                sdev_printk(KERN_INFO, sdev,
 117                            "%s: blk_rq_map_kern failed\n", __func__);
 118                return NULL;
 119        }
 120
 121        rq->cmd_type = REQ_TYPE_BLOCK_PC;
 122        rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
 123                         REQ_FAILFAST_DRIVER;
 124        rq->retries = ALUA_FAILOVER_RETRIES;
 125        rq->timeout = ALUA_FAILOVER_TIMEOUT;
 126
 127        return rq;
 128}
 129
 130/*
 131 * submit_std_inquiry - Issue a standard INQUIRY command
 132 * @sdev: sdev the command should be send to
 133 */
 134static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
 135{
 136        struct request *rq;
 137        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 138
 139        rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ);
 140        if (!rq)
 141                goto done;
 142
 143        /* Prepare the command. */
 144        rq->cmd[0] = INQUIRY;
 145        rq->cmd[1] = 0;
 146        rq->cmd[2] = 0;
 147        rq->cmd[4] = ALUA_INQUIRY_SIZE;
 148        rq->cmd_len = COMMAND_SIZE(INQUIRY);
 149
 150        rq->sense = h->sense;
 151        memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
 152        rq->sense_len = h->senselen = 0;
 153
 154        err = blk_execute_rq(rq->q, NULL, rq, 1);
 155        if (err == -EIO) {
 156                sdev_printk(KERN_INFO, sdev,
 157                            "%s: std inquiry failed with %x\n",
 158                            ALUA_DH_NAME, rq->errors);
 159                h->senselen = rq->sense_len;
 160                err = SCSI_DH_IO;
 161        }
 162        blk_put_request(rq);
 163done:
 164        return err;
 165}
 166
 167/*
 168 * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
 169 * @sdev: sdev the command should be sent to
 170 */
 171static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
 172{
 173        struct request *rq;
 174        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 175
 176        rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
 177        if (!rq)
 178                goto done;
 179
 180        /* Prepare the command. */
 181        rq->cmd[0] = INQUIRY;
 182        rq->cmd[1] = 1;
 183        rq->cmd[2] = 0x83;
 184        rq->cmd[4] = h->bufflen;
 185        rq->cmd_len = COMMAND_SIZE(INQUIRY);
 186
 187        rq->sense = h->sense;
 188        memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
 189        rq->sense_len = h->senselen = 0;
 190
 191        err = blk_execute_rq(rq->q, NULL, rq, 1);
 192        if (err == -EIO) {
 193                sdev_printk(KERN_INFO, sdev,
 194                            "%s: evpd inquiry failed with %x\n",
 195                            ALUA_DH_NAME, rq->errors);
 196                h->senselen = rq->sense_len;
 197                err = SCSI_DH_IO;
 198        }
 199        blk_put_request(rq);
 200done:
 201        return err;
 202}
 203
 204/*
 205 * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
 206 * @sdev: sdev the command should be sent to
 207 */
 208static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
 209{
 210        struct request *rq;
 211        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 212
 213        rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
 214        if (!rq)
 215                goto done;
 216
 217        /* Prepare the command. */
 218        rq->cmd[0] = MAINTENANCE_IN;
 219        rq->cmd[1] = MI_REPORT_TARGET_PGS;
 220        rq->cmd[6] = (h->bufflen >> 24) & 0xff;
 221        rq->cmd[7] = (h->bufflen >> 16) & 0xff;
 222        rq->cmd[8] = (h->bufflen >>  8) & 0xff;
 223        rq->cmd[9] = h->bufflen & 0xff;
 224        rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
 225
 226        rq->sense = h->sense;
 227        memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
 228        rq->sense_len = h->senselen = 0;
 229
 230        err = blk_execute_rq(rq->q, NULL, rq, 1);
 231        if (err == -EIO) {
 232                sdev_printk(KERN_INFO, sdev,
 233                            "%s: rtpg failed with %x\n",
 234                            ALUA_DH_NAME, rq->errors);
 235                h->senselen = rq->sense_len;
 236                err = SCSI_DH_IO;
 237        }
 238        blk_put_request(rq);
 239done:
 240        return err;
 241}
 242
 243/*
 244 * alua_stpg - Evaluate SET TARGET GROUP STATES
 245 * @sdev: the device to be evaluated
 246 * @state: the new target group state
 247 *
 248 * Send a SET TARGET GROUP STATES command to the device.
 249 * We only have to test here if we should resubmit the command;
 250 * any other error is assumed as a failure.
 251 */
 252static void stpg_endio(struct request *req, int error)
 253{
 254        struct alua_dh_data *h = req->end_io_data;
 255        struct scsi_sense_hdr sense_hdr;
 256        unsigned err = SCSI_DH_IO;
 257
 258        if (error || host_byte(req->errors) != DID_OK ||
 259                        msg_byte(req->errors) != COMMAND_COMPLETE)
 260                goto done;
 261
 262        if (err == SCSI_DH_IO && h->senselen > 0) {
 263                err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
 264                                           &sense_hdr);
 265                if (!err) {
 266                        err = SCSI_DH_IO;
 267                        goto done;
 268                }
 269                err = alua_check_sense(h->sdev, &sense_hdr);
 270                if (err == ADD_TO_MLQUEUE) {
 271                        err = SCSI_DH_RETRY;
 272                        goto done;
 273                }
 274                sdev_printk(KERN_INFO, h->sdev,
 275                            "%s: stpg sense code: %02x/%02x/%02x\n",
 276                            ALUA_DH_NAME, sense_hdr.sense_key,
 277                            sense_hdr.asc, sense_hdr.ascq);
 278                err = SCSI_DH_IO;
 279        }
 280        if (err == SCSI_DH_OK) {
 281                h->state = TPGS_STATE_OPTIMIZED;
 282                sdev_printk(KERN_INFO, h->sdev,
 283                            "%s: port group %02x switched to state %c\n",
 284                            ALUA_DH_NAME, h->group_id,
 285                            print_alua_state(h->state));
 286        }
 287done:
 288        blk_put_request(req);
 289        if (h->callback_fn) {
 290                h->callback_fn(h->callback_data, err);
 291                h->callback_fn = h->callback_data = NULL;
 292        }
 293        return;
 294}
 295
 296/*
 297 * submit_stpg - Issue a SET TARGET GROUP STATES command
 298 *
 299 * Currently we're only setting the current target port group state
 300 * to 'active/optimized' and let the array firmware figure out
 301 * the states of the remaining groups.
 302 */
 303static unsigned submit_stpg(struct alua_dh_data *h)
 304{
 305        struct request *rq;
 306        int err = SCSI_DH_RES_TEMP_UNAVAIL;
 307        int stpg_len = 8;
 308        struct scsi_device *sdev = h->sdev;
 309
 310        /* Prepare the data buffer */
 311        memset(h->buff, 0, stpg_len);
 312        h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f;
 313        h->buff[6] = (h->group_id >> 8) & 0xff;
 314        h->buff[7] = h->group_id & 0xff;
 315
 316        rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
 317        if (!rq)
 318                return SCSI_DH_RES_TEMP_UNAVAIL;
 319
 320        /* Prepare the command. */
 321        rq->cmd[0] = MAINTENANCE_OUT;
 322        rq->cmd[1] = MO_SET_TARGET_PGS;
 323        rq->cmd[6] = (stpg_len >> 24) & 0xff;
 324        rq->cmd[7] = (stpg_len >> 16) & 0xff;
 325        rq->cmd[8] = (stpg_len >>  8) & 0xff;
 326        rq->cmd[9] = stpg_len & 0xff;
 327        rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
 328
 329        rq->sense = h->sense;
 330        memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
 331        rq->sense_len = h->senselen = 0;
 332        rq->end_io_data = h;
 333
 334        blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
 335        return err;
 336}
 337
 338/*
 339 * alua_std_inquiry - Evaluate standard INQUIRY command
 340 * @sdev: device to be checked
 341 *
 342 * Just extract the TPGS setting to find out if ALUA
 343 * is supported.
 344 */
 345static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
 346{
 347        int err;
 348
 349        err = submit_std_inquiry(sdev, h);
 350
 351        if (err != SCSI_DH_OK)
 352                return err;
 353
 354        /* Check TPGS setting */
 355        h->tpgs = (h->inq[5] >> 4) & 0x3;
 356        switch (h->tpgs) {
 357        case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
 358                sdev_printk(KERN_INFO, sdev,
 359                            "%s: supports implicit and explicit TPGS\n",
 360                            ALUA_DH_NAME);
 361                break;
 362        case TPGS_MODE_EXPLICIT:
 363                sdev_printk(KERN_INFO, sdev, "%s: supports explicit TPGS\n",
 364                            ALUA_DH_NAME);
 365                break;
 366        case TPGS_MODE_IMPLICIT:
 367                sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n",
 368                            ALUA_DH_NAME);
 369                break;
 370        default:
 371                h->tpgs = TPGS_MODE_NONE;
 372                sdev_printk(KERN_INFO, sdev, "%s: not supported\n",
 373                            ALUA_DH_NAME);
 374                err = SCSI_DH_DEV_UNSUPP;
 375                break;
 376        }
 377
 378        return err;
 379}
 380
 381/*
 382 * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83
 383 * @sdev: device to be checked
 384 *
 385 * Extract the relative target port and the target port group
 386 * descriptor from the list of identificators.
 387 */
 388static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
 389{
 390        int len;
 391        unsigned err;
 392        unsigned char *d;
 393
 394 retry:
 395        err = submit_vpd_inquiry(sdev, h);
 396
 397        if (err != SCSI_DH_OK)
 398                return err;
 399
 400        /* Check if vpd page exceeds initial buffer */
 401        len = (h->buff[2] << 8) + h->buff[3] + 4;
 402        if (len > h->bufflen) {
 403                /* Resubmit with the correct length */
 404                if (realloc_buffer(h, len)) {
 405                        sdev_printk(KERN_WARNING, sdev,
 406                                    "%s: kmalloc buffer failed\n",
 407                                    ALUA_DH_NAME);
 408                        /* Temporary failure, bypass */
 409                        return SCSI_DH_DEV_TEMP_BUSY;
 410                }
 411                goto retry;
 412        }
 413
 414        /*
 415         * Now look for the correct descriptor.
 416         */
 417        d = h->buff + 4;
 418        while (d < h->buff + len) {
 419                switch (d[1] & 0xf) {
 420                case 0x4:
 421                        /* Relative target port */
 422                        h->rel_port = (d[6] << 8) + d[7];
 423                        break;
 424                case 0x5:
 425                        /* Target port group */
 426                        h->group_id = (d[6] << 8) + d[7];
 427                        break;
 428                default:
 429                        break;
 430                }
 431                d += d[3] + 4;
 432        }
 433
 434        if (h->group_id == -1) {
 435                /*
 436                 * Internal error; TPGS supported but required
 437                 * VPD identification descriptors not present.
 438                 * Disable ALUA support
 439                 */
 440                sdev_printk(KERN_INFO, sdev,
 441                            "%s: No target port descriptors found\n",
 442                            ALUA_DH_NAME);
 443                h->state = TPGS_STATE_OPTIMIZED;
 444                h->tpgs = TPGS_MODE_NONE;
 445                err = SCSI_DH_DEV_UNSUPP;
 446        } else {
 447                sdev_printk(KERN_INFO, sdev,
 448                            "%s: port group %02x rel port %02x\n",
 449                            ALUA_DH_NAME, h->group_id, h->rel_port);
 450        }
 451
 452        return err;
 453}
 454
 455static char print_alua_state(int state)
 456{
 457        switch (state) {
 458        case TPGS_STATE_OPTIMIZED:
 459                return 'A';
 460        case TPGS_STATE_NONOPTIMIZED:
 461                return 'N';
 462        case TPGS_STATE_STANDBY:
 463                return 'S';
 464        case TPGS_STATE_UNAVAILABLE:
 465                return 'U';
 466        case TPGS_STATE_LBA_DEPENDENT:
 467                return 'L';
 468        case TPGS_STATE_OFFLINE:
 469                return 'O';
 470        case TPGS_STATE_TRANSITIONING:
 471                return 'T';
 472        default:
 473                return 'X';
 474        }
 475}
 476
 477static int alua_check_sense(struct scsi_device *sdev,
 478                            struct scsi_sense_hdr *sense_hdr)
 479{
 480        switch (sense_hdr->sense_key) {
 481        case NOT_READY:
 482                if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a)
 483                        /*
 484                         * LUN Not Accessible - ALUA state transition
 485                         */
 486                        return ADD_TO_MLQUEUE;
 487                if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
 488                        /*
 489                         * LUN Not Accessible -- Target port in standby state
 490                         */
 491                        return SUCCESS;
 492                if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c)
 493                        /*
 494                         * LUN Not Accessible -- Target port in unavailable state
 495                         */
 496                        return SUCCESS;
 497                if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12)
 498                        /*
 499                         * LUN Not Ready -- Offline
 500                         */
 501                        return SUCCESS;
 502                break;
 503        case UNIT_ATTENTION:
 504                if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
 505                        /*
 506                         * Power On, Reset, or Bus Device Reset, just retry.
 507                         */
 508                        return ADD_TO_MLQUEUE;
 509                if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
 510                        /*
 511                         * ALUA state changed
 512                         */
 513                        return ADD_TO_MLQUEUE;
 514                }
 515                if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
 516                        /*
 517                         * Implicit ALUA state transition failed
 518                         */
 519                        return ADD_TO_MLQUEUE;
 520                }
 521                if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e) {
 522                        /*
 523                         * REPORTED_LUNS_DATA_HAS_CHANGED is reported
 524                         * when switching controllers on targets like
 525                         * Intel Multi-Flex. We can just retry.
 526                         */
 527                        return ADD_TO_MLQUEUE;
 528                }
 529
 530                break;
 531        }
 532
 533        return SCSI_RETURN_NOT_HANDLED;
 534}
 535
 536/*
 537 * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
 538 * @sdev: the device to be evaluated.
 539 *
 540 * Evaluate the Target Port Group State.
 541 * Returns SCSI_DH_DEV_OFFLINED if the path is
 542 * found to be unuseable.
 543 */
 544static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
 545{
 546        struct scsi_sense_hdr sense_hdr;
 547        int len, k, off, valid_states = 0;
 548        char *ucp;
 549        unsigned err;
 550        unsigned long expiry, interval = 10;
 551
 552        expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT);
 553 retry:
 554        err = submit_rtpg(sdev, h);
 555
 556        if (err == SCSI_DH_IO && h->senselen > 0) {
 557                err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
 558                                           &sense_hdr);
 559                if (!err)
 560                        return SCSI_DH_IO;
 561
 562                err = alua_check_sense(sdev, &sense_hdr);
 563                if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry))
 564                        goto retry;
 565                sdev_printk(KERN_INFO, sdev,
 566                            "%s: rtpg sense code %02x/%02x/%02x\n",
 567                            ALUA_DH_NAME, sense_hdr.sense_key,
 568                            sense_hdr.asc, sense_hdr.ascq);
 569                err = SCSI_DH_IO;
 570        }
 571        if (err != SCSI_DH_OK)
 572                return err;
 573
 574        len = (h->buff[0] << 24) + (h->buff[1] << 16) +
 575                (h->buff[2] << 8) + h->buff[3] + 4;
 576
 577        if (len > h->bufflen) {
 578                /* Resubmit with the correct length */
 579                if (realloc_buffer(h, len)) {
 580                        sdev_printk(KERN_WARNING, sdev,
 581                                    "%s: kmalloc buffer failed\n",__func__);
 582                        /* Temporary failure, bypass */
 583                        return SCSI_DH_DEV_TEMP_BUSY;
 584                }
 585                goto retry;
 586        }
 587
 588        for (k = 4, ucp = h->buff + 4; k < len; k += off, ucp += off) {
 589                if (h->group_id == (ucp[2] << 8) + ucp[3]) {
 590                        h->state = ucp[0] & 0x0f;
 591                        valid_states = ucp[1];
 592                }
 593                off = 8 + (ucp[7] * 4);
 594        }
 595
 596        sdev_printk(KERN_INFO, sdev,
 597                    "%s: port group %02x state %c supports %c%c%c%c%c%c%c\n",
 598                    ALUA_DH_NAME, h->group_id, print_alua_state(h->state),
 599                    valid_states&TPGS_SUPPORT_TRANSITION?'T':'t',
 600                    valid_states&TPGS_SUPPORT_OFFLINE?'O':'o',
 601                    valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l',
 602                    valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u',
 603                    valid_states&TPGS_SUPPORT_STANDBY?'S':'s',
 604                    valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n',
 605                    valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a');
 606
 607        switch (h->state) {
 608        case TPGS_STATE_TRANSITIONING:
 609                if (time_before(jiffies, expiry)) {
 610                        /* State transition, retry */
 611                        interval *= 10;
 612                        msleep(interval);
 613                        goto retry;
 614                }
 615                /* Transitioning time exceeded, set port to standby */
 616                err = SCSI_DH_RETRY;
 617                h->state = TPGS_STATE_STANDBY;
 618                break;
 619        case TPGS_STATE_OFFLINE:
 620        case TPGS_STATE_UNAVAILABLE:
 621                /* Path unuseable for unavailable/offline */
 622                err = SCSI_DH_DEV_OFFLINED;
 623                break;
 624        default:
 625                /* Useable path if active */
 626                err = SCSI_DH_OK;
 627                break;
 628        }
 629        return err;
 630}
 631
 632/*
 633 * alua_initialize - Initialize ALUA state
 634 * @sdev: the device to be initialized
 635 *
 636 * For the prep_fn to work correctly we have
 637 * to initialize the ALUA state for the device.
 638 */
 639static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
 640{
 641        int err;
 642
 643        err = alua_std_inquiry(sdev, h);
 644        if (err != SCSI_DH_OK)
 645                goto out;
 646
 647        err = alua_vpd_inquiry(sdev, h);
 648        if (err != SCSI_DH_OK)
 649                goto out;
 650
 651        err = alua_rtpg(sdev, h);
 652        if (err != SCSI_DH_OK)
 653                goto out;
 654
 655out:
 656        return err;
 657}
 658
 659/*
 660 * alua_activate - activate a path
 661 * @sdev: device on the path to be activated
 662 *
 663 * We're currently switching the port group to be activated only and
 664 * let the array figure out the rest.
 665 * There may be other arrays which require us to switch all port groups
 666 * based on a certain policy. But until we actually encounter them it
 667 * should be okay.
 668 */
 669static int alua_activate(struct scsi_device *sdev,
 670                        activate_complete fn, void *data)
 671{
 672        struct alua_dh_data *h = get_alua_data(sdev);
 673        int err = SCSI_DH_OK;
 674
 675        if (h->group_id != -1) {
 676                err = alua_rtpg(sdev, h);
 677                if (err != SCSI_DH_OK)
 678                        goto out;
 679        }
 680
 681        if (h->tpgs & TPGS_MODE_EXPLICIT &&
 682            h->state != TPGS_STATE_OPTIMIZED &&
 683            h->state != TPGS_STATE_LBA_DEPENDENT) {
 684                h->callback_fn = fn;
 685                h->callback_data = data;
 686                err = submit_stpg(h);
 687                if (err == SCSI_DH_OK)
 688                        return 0;
 689                h->callback_fn = h->callback_data = NULL;
 690        }
 691
 692out:
 693        if (fn)
 694                fn(data, err);
 695        return 0;
 696}
 697
 698/*
 699 * alua_prep_fn - request callback
 700 *
 701 * Fail I/O to all paths not in state
 702 * active/optimized or active/non-optimized.
 703 */
 704static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
 705{
 706        struct alua_dh_data *h = get_alua_data(sdev);
 707        int ret = BLKPREP_OK;
 708
 709        if (h->state == TPGS_STATE_TRANSITIONING)
 710                ret = BLKPREP_DEFER;
 711        else if (h->state != TPGS_STATE_OPTIMIZED &&
 712                 h->state != TPGS_STATE_NONOPTIMIZED &&
 713                 h->state != TPGS_STATE_LBA_DEPENDENT) {
 714                ret = BLKPREP_KILL;
 715                req->cmd_flags |= REQ_QUIET;
 716        }
 717        return ret;
 718
 719}
 720
 721static const struct scsi_dh_devlist alua_dev_list[] = {
 722        {"HP", "MSA VOLUME" },
 723        {"HP", "HSV101" },
 724        {"HP", "HSV111" },
 725        {"HP", "HSV200" },
 726        {"HP", "HSV210" },
 727        {"HP", "HSV300" },
 728        {"IBM", "2107900" },
 729        {"IBM", "2145" },
 730        {"Pillar", "Axiom" },
 731        {"Intel", "Multi-Flex"},
 732        {"NETAPP", "LUN"},
 733        {"AIX", "NVDISK"},
 734        {NULL, NULL}
 735};
 736
 737static int alua_bus_attach(struct scsi_device *sdev);
 738static void alua_bus_detach(struct scsi_device *sdev);
 739
 740static struct scsi_device_handler alua_dh = {
 741        .name = ALUA_DH_NAME,
 742        .module = THIS_MODULE,
 743        .devlist = alua_dev_list,
 744        .attach = alua_bus_attach,
 745        .detach = alua_bus_detach,
 746        .prep_fn = alua_prep_fn,
 747        .check_sense = alua_check_sense,
 748        .activate = alua_activate,
 749};
 750
 751/*
 752 * alua_bus_attach - Attach device handler
 753 * @sdev: device to be attached to
 754 */
 755static int alua_bus_attach(struct scsi_device *sdev)
 756{
 757        struct scsi_dh_data *scsi_dh_data;
 758        struct alua_dh_data *h;
 759        unsigned long flags;
 760        int err = SCSI_DH_OK;
 761
 762        scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
 763                               + sizeof(*h) , GFP_KERNEL);
 764        if (!scsi_dh_data) {
 765                sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n",
 766                            ALUA_DH_NAME);
 767                return -ENOMEM;
 768        }
 769
 770        scsi_dh_data->scsi_dh = &alua_dh;
 771        h = (struct alua_dh_data *) scsi_dh_data->buf;
 772        h->tpgs = TPGS_MODE_UNINITIALIZED;
 773        h->state = TPGS_STATE_OPTIMIZED;
 774        h->group_id = -1;
 775        h->rel_port = -1;
 776        h->buff = h->inq;
 777        h->bufflen = ALUA_INQUIRY_SIZE;
 778        h->sdev = sdev;
 779
 780        err = alua_initialize(sdev, h);
 781        if (err != SCSI_DH_OK)
 782                goto failed;
 783
 784        if (!try_module_get(THIS_MODULE))
 785                goto failed;
 786
 787        spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
 788        sdev->scsi_dh_data = scsi_dh_data;
 789        spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
 790
 791        return 0;
 792
 793failed:
 794        kfree(scsi_dh_data);
 795        sdev_printk(KERN_ERR, sdev, "%s: not attached\n", ALUA_DH_NAME);
 796        return -EINVAL;
 797}
 798
 799/*
 800 * alua_bus_detach - Detach device handler
 801 * @sdev: device to be detached from
 802 */
 803static void alua_bus_detach(struct scsi_device *sdev)
 804{
 805        struct scsi_dh_data *scsi_dh_data;
 806        struct alua_dh_data *h;
 807        unsigned long flags;
 808
 809        spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
 810        scsi_dh_data = sdev->scsi_dh_data;
 811        sdev->scsi_dh_data = NULL;
 812        spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
 813
 814        h = (struct alua_dh_data *) scsi_dh_data->buf;
 815        if (h->buff && h->inq != h->buff)
 816                kfree(h->buff);
 817        kfree(scsi_dh_data);
 818        module_put(THIS_MODULE);
 819        sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", ALUA_DH_NAME);
 820}
 821
 822static int __init alua_init(void)
 823{
 824        int r;
 825
 826        r = scsi_register_device_handler(&alua_dh);
 827        if (r != 0)
 828                printk(KERN_ERR "%s: Failed to register scsi device handler",
 829                        ALUA_DH_NAME);
 830        return r;
 831}
 832
 833static void __exit alua_exit(void)
 834{
 835        scsi_unregister_device_handler(&alua_dh);
 836}
 837
 838module_init(alua_init);
 839module_exit(alua_exit);
 840
 841MODULE_DESCRIPTION("DM Multipath ALUA support");
 842MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>");
 843MODULE_LICENSE("GPL");
 844MODULE_VERSION(ALUA_DH_VER);
 845