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