aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/device_handler')
-rw-r--r--drivers/scsi/device_handler/scsi_dh.c130
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c87
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_hp_sw.c7
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c100
5 files changed, 177 insertions, 149 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index 6fae3d285ae7..0119b8147797 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -25,16 +25,9 @@
25#include <scsi/scsi_dh.h> 25#include <scsi/scsi_dh.h>
26#include "../scsi_priv.h" 26#include "../scsi_priv.h"
27 27
28struct scsi_dh_devinfo_list {
29 struct list_head node;
30 char vendor[9];
31 char model[17];
32 struct scsi_device_handler *handler;
33};
34
35static DEFINE_SPINLOCK(list_lock); 28static DEFINE_SPINLOCK(list_lock);
36static LIST_HEAD(scsi_dh_list); 29static LIST_HEAD(scsi_dh_list);
37static LIST_HEAD(scsi_dh_dev_list); 30static int scsi_dh_list_idx = 1;
38 31
39static struct scsi_device_handler *get_device_handler(const char *name) 32static struct scsi_device_handler *get_device_handler(const char *name)
40{ 33{
@@ -51,40 +44,18 @@ static struct scsi_device_handler *get_device_handler(const char *name)
51 return found; 44 return found;
52} 45}
53 46
54 47static struct scsi_device_handler *get_device_handler_by_idx(int idx)
55static struct scsi_device_handler *
56scsi_dh_cache_lookup(struct scsi_device *sdev)
57{ 48{
58 struct scsi_dh_devinfo_list *tmp; 49 struct scsi_device_handler *tmp, *found = NULL;
59 struct scsi_device_handler *found_dh = NULL;
60 50
61 spin_lock(&list_lock); 51 spin_lock(&list_lock);
62 list_for_each_entry(tmp, &scsi_dh_dev_list, node) { 52 list_for_each_entry(tmp, &scsi_dh_list, list) {
63 if (!strncmp(sdev->vendor, tmp->vendor, strlen(tmp->vendor)) && 53 if (tmp->idx == idx) {
64 !strncmp(sdev->model, tmp->model, strlen(tmp->model))) { 54 found = tmp;
65 found_dh = tmp->handler;
66 break; 55 break;
67 } 56 }
68 } 57 }
69 spin_unlock(&list_lock); 58 spin_unlock(&list_lock);
70
71 return found_dh;
72}
73
74static int scsi_dh_handler_lookup(struct scsi_device_handler *scsi_dh,
75 struct scsi_device *sdev)
76{
77 int i, found = 0;
78
79 for(i = 0; scsi_dh->devlist[i].vendor; i++) {
80 if (!strncmp(sdev->vendor, scsi_dh->devlist[i].vendor,
81 strlen(scsi_dh->devlist[i].vendor)) &&
82 !strncmp(sdev->model, scsi_dh->devlist[i].model,
83 strlen(scsi_dh->devlist[i].model))) {
84 found = 1;
85 break;
86 }
87 }
88 return found; 59 return found;
89} 60}
90 61
@@ -102,41 +73,14 @@ device_handler_match(struct scsi_device_handler *scsi_dh,
102 struct scsi_device *sdev) 73 struct scsi_device *sdev)
103{ 74{
104 struct scsi_device_handler *found_dh = NULL; 75 struct scsi_device_handler *found_dh = NULL;
105 struct scsi_dh_devinfo_list *tmp; 76 int idx;
106 77
107 found_dh = scsi_dh_cache_lookup(sdev); 78 idx = scsi_get_device_flags_keyed(sdev, sdev->vendor, sdev->model,
108 if (found_dh) 79 SCSI_DEVINFO_DH);
109 return found_dh; 80 found_dh = get_device_handler_by_idx(idx);
110 81
111 if (scsi_dh) { 82 if (scsi_dh && found_dh != scsi_dh)
112 if (scsi_dh_handler_lookup(scsi_dh, sdev)) 83 found_dh = NULL;
113 found_dh = scsi_dh;
114 } else {
115 struct scsi_device_handler *tmp_dh;
116
117 spin_lock(&list_lock);
118 list_for_each_entry(tmp_dh, &scsi_dh_list, list) {
119 if (scsi_dh_handler_lookup(tmp_dh, sdev))
120 found_dh = tmp_dh;
121 }
122 spin_unlock(&list_lock);
123 }
124
125 if (found_dh) { /* If device is found, add it to the cache */
126 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
127 if (tmp) {
128 strncpy(tmp->vendor, sdev->vendor, 8);
129 strncpy(tmp->model, sdev->model, 16);
130 tmp->vendor[8] = '\0';
131 tmp->model[16] = '\0';
132 tmp->handler = found_dh;
133 spin_lock(&list_lock);
134 list_add(&tmp->node, &scsi_dh_dev_list);
135 spin_unlock(&list_lock);
136 } else {
137 found_dh = NULL;
138 }
139 }
140 84
141 return found_dh; 85 return found_dh;
142} 86}
@@ -373,12 +317,25 @@ static int scsi_dh_notifier_remove(struct device *dev, void *data)
373 */ 317 */
374int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) 318int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
375{ 319{
320 int i;
321
376 if (get_device_handler(scsi_dh->name)) 322 if (get_device_handler(scsi_dh->name))
377 return -EBUSY; 323 return -EBUSY;
378 324
379 spin_lock(&list_lock); 325 spin_lock(&list_lock);
326 scsi_dh->idx = scsi_dh_list_idx++;
380 list_add(&scsi_dh->list, &scsi_dh_list); 327 list_add(&scsi_dh->list, &scsi_dh_list);
381 spin_unlock(&list_lock); 328 spin_unlock(&list_lock);
329
330 for (i = 0; scsi_dh->devlist[i].vendor; i++) {
331 scsi_dev_info_list_add_keyed(0,
332 scsi_dh->devlist[i].vendor,
333 scsi_dh->devlist[i].model,
334 NULL,
335 scsi_dh->idx,
336 SCSI_DEVINFO_DH);
337 }
338
382 bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); 339 bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add);
383 printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); 340 printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name);
384 341
@@ -395,7 +352,7 @@ EXPORT_SYMBOL_GPL(scsi_register_device_handler);
395 */ 352 */
396int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) 353int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
397{ 354{
398 struct scsi_dh_devinfo_list *tmp, *pos; 355 int i;
399 356
400 if (!get_device_handler(scsi_dh->name)) 357 if (!get_device_handler(scsi_dh->name))
401 return -ENODEV; 358 return -ENODEV;
@@ -403,14 +360,14 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
403 bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, 360 bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh,
404 scsi_dh_notifier_remove); 361 scsi_dh_notifier_remove);
405 362
363 for (i = 0; scsi_dh->devlist[i].vendor; i++) {
364 scsi_dev_info_list_del_keyed(scsi_dh->devlist[i].vendor,
365 scsi_dh->devlist[i].model,
366 SCSI_DEVINFO_DH);
367 }
368
406 spin_lock(&list_lock); 369 spin_lock(&list_lock);
407 list_del(&scsi_dh->list); 370 list_del(&scsi_dh->list);
408 list_for_each_entry_safe(pos, tmp, &scsi_dh_dev_list, node) {
409 if (pos->handler == scsi_dh) {
410 list_del(&pos->node);
411 kfree(pos);
412 }
413 }
414 spin_unlock(&list_lock); 371 spin_unlock(&list_lock);
415 printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name); 372 printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name);
416 373
@@ -437,21 +394,31 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
437 unsigned long flags; 394 unsigned long flags;
438 struct scsi_device *sdev; 395 struct scsi_device *sdev;
439 struct scsi_device_handler *scsi_dh = NULL; 396 struct scsi_device_handler *scsi_dh = NULL;
397 struct device *dev = NULL;
440 398
441 spin_lock_irqsave(q->queue_lock, flags); 399 spin_lock_irqsave(q->queue_lock, flags);
442 sdev = q->queuedata; 400 sdev = q->queuedata;
443 if (sdev && sdev->scsi_dh_data) 401 if (sdev && sdev->scsi_dh_data)
444 scsi_dh = sdev->scsi_dh_data->scsi_dh; 402 scsi_dh = sdev->scsi_dh_data->scsi_dh;
445 if (!scsi_dh || !get_device(&sdev->sdev_gendev)) 403 dev = get_device(&sdev->sdev_gendev);
404 if (!scsi_dh || !dev ||
405 sdev->sdev_state == SDEV_CANCEL ||
406 sdev->sdev_state == SDEV_DEL)
446 err = SCSI_DH_NOSYS; 407 err = SCSI_DH_NOSYS;
408 if (sdev->sdev_state == SDEV_OFFLINE)
409 err = SCSI_DH_DEV_OFFLINED;
447 spin_unlock_irqrestore(q->queue_lock, flags); 410 spin_unlock_irqrestore(q->queue_lock, flags);
448 411
449 if (err) 412 if (err) {
450 return err; 413 if (fn)
414 fn(data, err);
415 goto out;
416 }
451 417
452 if (scsi_dh->activate) 418 if (scsi_dh->activate)
453 err = scsi_dh->activate(sdev, fn, data); 419 err = scsi_dh->activate(sdev, fn, data);
454 put_device(&sdev->sdev_gendev); 420out:
421 put_device(dev);
455 return err; 422 return err;
456} 423}
457EXPORT_SYMBOL_GPL(scsi_dh_activate); 424EXPORT_SYMBOL_GPL(scsi_dh_activate);
@@ -569,6 +536,10 @@ static int __init scsi_dh_init(void)
569{ 536{
570 int r; 537 int r;
571 538
539 r = scsi_dev_info_add_list(SCSI_DEVINFO_DH, "SCSI Device Handler");
540 if (r)
541 return r;
542
572 r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb); 543 r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb);
573 544
574 if (!r) 545 if (!r)
@@ -583,6 +554,7 @@ static void __exit scsi_dh_exit(void)
583 bus_for_each_dev(&scsi_bus_type, NULL, NULL, 554 bus_for_each_dev(&scsi_bus_type, NULL, NULL,
584 scsi_dh_sysfs_attr_remove); 555 scsi_dh_sysfs_attr_remove);
585 bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb); 556 bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb);
557 scsi_dev_info_remove_list(SCSI_DEVINFO_DH);
586} 558}
587 559
588module_init(scsi_dh_init); 560module_init(scsi_dh_init);
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 1a970a76b1b9..6fec9fe5dc39 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Generic SCSI-3 ALUA SCSI Device Handler 2 * Generic SCSI-3 ALUA SCSI Device Handler
3 * 3 *
4 * Copyright (C) 2007, 2008 Hannes Reinecke, SUSE Linux Products GmbH. 4 * Copyright (C) 2007-2010 Hannes Reinecke, SUSE Linux Products GmbH.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -20,17 +20,19 @@
20 * 20 *
21 */ 21 */
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/delay.h>
23#include <scsi/scsi.h> 24#include <scsi/scsi.h>
24#include <scsi/scsi_eh.h> 25#include <scsi/scsi_eh.h>
25#include <scsi/scsi_dh.h> 26#include <scsi/scsi_dh.h>
26 27
27#define ALUA_DH_NAME "alua" 28#define ALUA_DH_NAME "alua"
28#define ALUA_DH_VER "1.2" 29#define ALUA_DH_VER "1.3"
29 30
30#define TPGS_STATE_OPTIMIZED 0x0 31#define TPGS_STATE_OPTIMIZED 0x0
31#define TPGS_STATE_NONOPTIMIZED 0x1 32#define TPGS_STATE_NONOPTIMIZED 0x1
32#define TPGS_STATE_STANDBY 0x2 33#define TPGS_STATE_STANDBY 0x2
33#define TPGS_STATE_UNAVAILABLE 0x3 34#define TPGS_STATE_UNAVAILABLE 0x3
35#define TPGS_STATE_LBA_DEPENDENT 0x4
34#define TPGS_STATE_OFFLINE 0xe 36#define TPGS_STATE_OFFLINE 0xe
35#define TPGS_STATE_TRANSITIONING 0xf 37#define TPGS_STATE_TRANSITIONING 0xf
36 38
@@ -39,6 +41,7 @@
39#define TPGS_SUPPORT_NONOPTIMIZED 0x02 41#define TPGS_SUPPORT_NONOPTIMIZED 0x02
40#define TPGS_SUPPORT_STANDBY 0x04 42#define TPGS_SUPPORT_STANDBY 0x04
41#define TPGS_SUPPORT_UNAVAILABLE 0x08 43#define TPGS_SUPPORT_UNAVAILABLE 0x08
44#define TPGS_SUPPORT_LBA_DEPENDENT 0x10
42#define TPGS_SUPPORT_OFFLINE 0x40 45#define TPGS_SUPPORT_OFFLINE 0x40
43#define TPGS_SUPPORT_TRANSITION 0x80 46#define TPGS_SUPPORT_TRANSITION 0x80
44 47
@@ -250,13 +253,15 @@ static void stpg_endio(struct request *req, int error)
250{ 253{
251 struct alua_dh_data *h = req->end_io_data; 254 struct alua_dh_data *h = req->end_io_data;
252 struct scsi_sense_hdr sense_hdr; 255 struct scsi_sense_hdr sense_hdr;
253 unsigned err = SCSI_DH_IO; 256 unsigned err = SCSI_DH_OK;
254 257
255 if (error || host_byte(req->errors) != DID_OK || 258 if (error || host_byte(req->errors) != DID_OK ||
256 msg_byte(req->errors) != COMMAND_COMPLETE) 259 msg_byte(req->errors) != COMMAND_COMPLETE) {
260 err = SCSI_DH_IO;
257 goto done; 261 goto done;
262 }
258 263
259 if (err == SCSI_DH_IO && h->senselen > 0) { 264 if (h->senselen > 0) {
260 err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, 265 err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
261 &sense_hdr); 266 &sense_hdr);
262 if (!err) { 267 if (!err) {
@@ -282,7 +287,8 @@ static void stpg_endio(struct request *req, int error)
282 print_alua_state(h->state)); 287 print_alua_state(h->state));
283 } 288 }
284done: 289done:
285 blk_put_request(req); 290 req->end_io_data = NULL;
291 __blk_put_request(req->q, req);
286 if (h->callback_fn) { 292 if (h->callback_fn) {
287 h->callback_fn(h->callback_data, err); 293 h->callback_fn(h->callback_data, err);
288 h->callback_fn = h->callback_data = NULL; 294 h->callback_fn = h->callback_data = NULL;
@@ -300,7 +306,6 @@ done:
300static unsigned submit_stpg(struct alua_dh_data *h) 306static unsigned submit_stpg(struct alua_dh_data *h)
301{ 307{
302 struct request *rq; 308 struct request *rq;
303 int err = SCSI_DH_RES_TEMP_UNAVAIL;
304 int stpg_len = 8; 309 int stpg_len = 8;
305 struct scsi_device *sdev = h->sdev; 310 struct scsi_device *sdev = h->sdev;
306 311
@@ -329,7 +334,7 @@ static unsigned submit_stpg(struct alua_dh_data *h)
329 rq->end_io_data = h; 334 rq->end_io_data = h;
330 335
331 blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio); 336 blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
332 return err; 337 return SCSI_DH_OK;
333} 338}
334 339
335/* 340/*
@@ -460,6 +465,8 @@ static char print_alua_state(int state)
460 return 'S'; 465 return 'S';
461 case TPGS_STATE_UNAVAILABLE: 466 case TPGS_STATE_UNAVAILABLE:
462 return 'U'; 467 return 'U';
468 case TPGS_STATE_LBA_DEPENDENT:
469 return 'L';
463 case TPGS_STATE_OFFLINE: 470 case TPGS_STATE_OFFLINE:
464 return 'O'; 471 return 'O';
465 case TPGS_STATE_TRANSITIONING: 472 case TPGS_STATE_TRANSITIONING:
@@ -534,7 +541,7 @@ static int alua_check_sense(struct scsi_device *sdev,
534 * 541 *
535 * Evaluate the Target Port Group State. 542 * Evaluate the Target Port Group State.
536 * Returns SCSI_DH_DEV_OFFLINED if the path is 543 * Returns SCSI_DH_DEV_OFFLINED if the path is
537 * found to be unuseable. 544 * found to be unusable.
538 */ 545 */
539static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) 546static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
540{ 547{
@@ -542,7 +549,9 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
542 int len, k, off, valid_states = 0; 549 int len, k, off, valid_states = 0;
543 char *ucp; 550 char *ucp;
544 unsigned err; 551 unsigned err;
552 unsigned long expiry, interval = 10;
545 553
554 expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT);
546 retry: 555 retry:
547 err = submit_rtpg(sdev, h); 556 err = submit_rtpg(sdev, h);
548 557
@@ -553,7 +562,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
553 return SCSI_DH_IO; 562 return SCSI_DH_IO;
554 563
555 err = alua_check_sense(sdev, &sense_hdr); 564 err = alua_check_sense(sdev, &sense_hdr);
556 if (err == ADD_TO_MLQUEUE) 565 if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry))
557 goto retry; 566 goto retry;
558 sdev_printk(KERN_INFO, sdev, 567 sdev_printk(KERN_INFO, sdev,
559 "%s: rtpg sense code %02x/%02x/%02x\n", 568 "%s: rtpg sense code %02x/%02x/%02x\n",
@@ -587,38 +596,37 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
587 } 596 }
588 597
589 sdev_printk(KERN_INFO, sdev, 598 sdev_printk(KERN_INFO, sdev,
590 "%s: port group %02x state %c supports %c%c%c%c%c%c\n", 599 "%s: port group %02x state %c supports %c%c%c%c%c%c%c\n",
591 ALUA_DH_NAME, h->group_id, print_alua_state(h->state), 600 ALUA_DH_NAME, h->group_id, print_alua_state(h->state),
592 valid_states&TPGS_SUPPORT_TRANSITION?'T':'t', 601 valid_states&TPGS_SUPPORT_TRANSITION?'T':'t',
593 valid_states&TPGS_SUPPORT_OFFLINE?'O':'o', 602 valid_states&TPGS_SUPPORT_OFFLINE?'O':'o',
603 valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l',
594 valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u', 604 valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u',
595 valid_states&TPGS_SUPPORT_STANDBY?'S':'s', 605 valid_states&TPGS_SUPPORT_STANDBY?'S':'s',
596 valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n', 606 valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n',
597 valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a'); 607 valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a');
598 608
599 if (h->tpgs & TPGS_MODE_EXPLICIT) { 609 switch (h->state) {
600 switch (h->state) { 610 case TPGS_STATE_TRANSITIONING:
601 case TPGS_STATE_TRANSITIONING: 611 if (time_before(jiffies, expiry)) {
602 /* State transition, retry */ 612 /* State transition, retry */
613 interval *= 10;
614 msleep(interval);
603 goto retry; 615 goto retry;
604 break;
605 case TPGS_STATE_OFFLINE:
606 /* Path is offline, fail */
607 err = SCSI_DH_DEV_OFFLINED;
608 break;
609 default:
610 break;
611 } 616 }
612 } else { 617 /* Transitioning time exceeded, set port to standby */
613 /* Only Implicit ALUA support */ 618 err = SCSI_DH_RETRY;
614 if (h->state == TPGS_STATE_OPTIMIZED || 619 h->state = TPGS_STATE_STANDBY;
615 h->state == TPGS_STATE_NONOPTIMIZED || 620 break;
616 h->state == TPGS_STATE_STANDBY) 621 case TPGS_STATE_OFFLINE:
617 /* Useable path if active */ 622 case TPGS_STATE_UNAVAILABLE:
618 err = SCSI_DH_OK; 623 /* Path unusable for unavailable/offline */
619 else 624 err = SCSI_DH_DEV_OFFLINED;
620 /* Path unuseable for unavailable/offline */ 625 break;
621 err = SCSI_DH_DEV_OFFLINED; 626 default:
627 /* Useable path if active */
628 err = SCSI_DH_OK;
629 break;
622 } 630 }
623 return err; 631 return err;
624} 632}
@@ -672,7 +680,9 @@ static int alua_activate(struct scsi_device *sdev,
672 goto out; 680 goto out;
673 } 681 }
674 682
675 if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED) { 683 if (h->tpgs & TPGS_MODE_EXPLICIT &&
684 h->state != TPGS_STATE_OPTIMIZED &&
685 h->state != TPGS_STATE_LBA_DEPENDENT) {
676 h->callback_fn = fn; 686 h->callback_fn = fn;
677 h->callback_data = data; 687 h->callback_data = data;
678 err = submit_stpg(h); 688 err = submit_stpg(h);
@@ -698,8 +708,11 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
698 struct alua_dh_data *h = get_alua_data(sdev); 708 struct alua_dh_data *h = get_alua_data(sdev);
699 int ret = BLKPREP_OK; 709 int ret = BLKPREP_OK;
700 710
701 if (h->state != TPGS_STATE_OPTIMIZED && 711 if (h->state == TPGS_STATE_TRANSITIONING)
702 h->state != TPGS_STATE_NONOPTIMIZED) { 712 ret = BLKPREP_DEFER;
713 else if (h->state != TPGS_STATE_OPTIMIZED &&
714 h->state != TPGS_STATE_NONOPTIMIZED &&
715 h->state != TPGS_STATE_LBA_DEPENDENT) {
703 ret = BLKPREP_KILL; 716 ret = BLKPREP_KILL;
704 req->cmd_flags |= REQ_QUIET; 717 req->cmd_flags |= REQ_QUIET;
705 } 718 }
@@ -719,7 +732,9 @@ static const struct scsi_dh_devlist alua_dev_list[] = {
719 {"Pillar", "Axiom" }, 732 {"Pillar", "Axiom" },
720 {"Intel", "Multi-Flex"}, 733 {"Intel", "Multi-Flex"},
721 {"NETAPP", "LUN"}, 734 {"NETAPP", "LUN"},
735 {"NETAPP", "LUN C-Mode"},
722 {"AIX", "NVDISK"}, 736 {"AIX", "NVDISK"},
737 {"Promise", "VTrak"},
723 {NULL, NULL} 738 {NULL, NULL}
724}; 739};
725 740
@@ -748,7 +763,7 @@ static int alua_bus_attach(struct scsi_device *sdev)
748 unsigned long flags; 763 unsigned long flags;
749 int err = SCSI_DH_OK; 764 int err = SCSI_DH_OK;
750 765
751 scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) 766 scsi_dh_data = kzalloc(sizeof(*scsi_dh_data)
752 + sizeof(*h) , GFP_KERNEL); 767 + sizeof(*h) , GFP_KERNEL);
753 if (!scsi_dh_data) { 768 if (!scsi_dh_data) {
754 sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", 769 sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n",
@@ -767,7 +782,7 @@ static int alua_bus_attach(struct scsi_device *sdev)
767 h->sdev = sdev; 782 h->sdev = sdev;
768 783
769 err = alua_initialize(sdev, h); 784 err = alua_initialize(sdev, h);
770 if (err != SCSI_DH_OK) 785 if ((err != SCSI_DH_OK) && (err != SCSI_DH_DEV_OFFLINED))
771 goto failed; 786 goto failed;
772 787
773 if (!try_module_get(THIS_MODULE)) 788 if (!try_module_get(THIS_MODULE))
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 6faf472f7537..48441f6908a4 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -650,7 +650,7 @@ static int clariion_bus_attach(struct scsi_device *sdev)
650 unsigned long flags; 650 unsigned long flags;
651 int err; 651 int err;
652 652
653 scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) 653 scsi_dh_data = kzalloc(sizeof(*scsi_dh_data)
654 + sizeof(*h) , GFP_KERNEL); 654 + sizeof(*h) , GFP_KERNEL);
655 if (!scsi_dh_data) { 655 if (!scsi_dh_data) {
656 sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", 656 sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n",
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index e3916641e627..b479f1eef968 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -225,7 +225,8 @@ static void start_stop_endio(struct request *req, int error)
225 } 225 }
226 } 226 }
227done: 227done:
228 blk_put_request(req); 228 req->end_io_data = NULL;
229 __blk_put_request(req->q, req);
229 if (h->callback_fn) { 230 if (h->callback_fn) {
230 h->callback_fn(h->callback_data, err); 231 h->callback_fn(h->callback_data, err);
231 h->callback_fn = h->callback_data = NULL; 232 h->callback_fn = h->callback_data = NULL;
@@ -338,8 +339,8 @@ static int hp_sw_bus_attach(struct scsi_device *sdev)
338 unsigned long flags; 339 unsigned long flags;
339 int ret; 340 int ret;
340 341
341 scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) 342 scsi_dh_data = kzalloc(sizeof(*scsi_dh_data)
342 + sizeof(struct hp_sw_dh_data) , GFP_KERNEL); 343 + sizeof(*h) , GFP_KERNEL);
343 if (!scsi_dh_data) { 344 if (!scsi_dh_data) {
344 sdev_printk(KERN_ERR, sdev, "%s: Attach Failed\n", 345 sdev_printk(KERN_ERR, sdev, "%s: Attach Failed\n",
345 HP_SW_NAME); 346 HP_SW_NAME);
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index b9bcfa4c7d26..e7fc70d6b478 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -182,14 +182,24 @@ struct rdac_dh_data {
182 struct rdac_controller *ctlr; 182 struct rdac_controller *ctlr;
183#define UNINITIALIZED_LUN (1 << 8) 183#define UNINITIALIZED_LUN (1 << 8)
184 unsigned lun; 184 unsigned lun;
185
186#define RDAC_MODE 0
187#define RDAC_MODE_AVT 1
188#define RDAC_MODE_IOSHIP 2
189 unsigned char mode;
190
185#define RDAC_STATE_ACTIVE 0 191#define RDAC_STATE_ACTIVE 0
186#define RDAC_STATE_PASSIVE 1 192#define RDAC_STATE_PASSIVE 1
187 unsigned char state; 193 unsigned char state;
188 194
189#define RDAC_LUN_UNOWNED 0 195#define RDAC_LUN_UNOWNED 0
190#define RDAC_LUN_OWNED 1 196#define RDAC_LUN_OWNED 1
191#define RDAC_LUN_AVT 2
192 char lun_state; 197 char lun_state;
198
199#define RDAC_PREFERRED 0
200#define RDAC_NON_PREFERRED 1
201 char preferred;
202
193 unsigned char sense[SCSI_SENSE_BUFFERSIZE]; 203 unsigned char sense[SCSI_SENSE_BUFFERSIZE];
194 union { 204 union {
195 struct c2_inquiry c2; 205 struct c2_inquiry c2;
@@ -199,11 +209,15 @@ struct rdac_dh_data {
199 } inq; 209 } inq;
200}; 210};
201 211
212static const char *mode[] = {
213 "RDAC",
214 "AVT",
215 "IOSHIP",
216};
202static const char *lun_state[] = 217static const char *lun_state[] =
203{ 218{
204 "unowned", 219 "unowned",
205 "owned", 220 "owned",
206 "owned (AVT mode)",
207}; 221};
208 222
209struct rdac_queue_data { 223struct rdac_queue_data {
@@ -281,11 +295,13 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
281} 295}
282 296
283static struct request *rdac_failover_get(struct scsi_device *sdev, 297static struct request *rdac_failover_get(struct scsi_device *sdev,
284 struct rdac_dh_data *h) 298 struct rdac_dh_data *h, struct list_head *list)
285{ 299{
286 struct request *rq; 300 struct request *rq;
287 struct rdac_mode_common *common; 301 struct rdac_mode_common *common;
288 unsigned data_size; 302 unsigned data_size;
303 struct rdac_queue_data *qdata;
304 u8 *lun_table;
289 305
290 if (h->ctlr->use_ms10) { 306 if (h->ctlr->use_ms10) {
291 struct rdac_pg_expanded *rdac_pg; 307 struct rdac_pg_expanded *rdac_pg;
@@ -298,6 +314,7 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
298 rdac_pg->subpage_code = 0x1; 314 rdac_pg->subpage_code = 0x1;
299 rdac_pg->page_len[0] = 0x01; 315 rdac_pg->page_len[0] = 0x01;
300 rdac_pg->page_len[1] = 0x28; 316 rdac_pg->page_len[1] = 0x28;
317 lun_table = rdac_pg->lun_table;
301 } else { 318 } else {
302 struct rdac_pg_legacy *rdac_pg; 319 struct rdac_pg_legacy *rdac_pg;
303 320
@@ -307,11 +324,16 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
307 common = &rdac_pg->common; 324 common = &rdac_pg->common;
308 rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER; 325 rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
309 rdac_pg->page_len = 0x68; 326 rdac_pg->page_len = 0x68;
327 lun_table = rdac_pg->lun_table;
310 } 328 }
311 common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS; 329 common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
312 common->quiescence_timeout = RDAC_QUIESCENCE_TIME; 330 common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
313 common->rdac_options = RDAC_FORCED_QUIESENCE; 331 common->rdac_options = RDAC_FORCED_QUIESENCE;
314 332
333 list_for_each_entry(qdata, list, entry) {
334 lun_table[qdata->h->lun] = 0x81;
335 }
336
315 /* get request for block layer packet command */ 337 /* get request for block layer packet command */
316 rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE); 338 rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE);
317 if (!rq) 339 if (!rq)
@@ -450,25 +472,33 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
450 int err; 472 int err;
451 struct c9_inquiry *inqp; 473 struct c9_inquiry *inqp;
452 474
453 h->lun_state = RDAC_LUN_UNOWNED;
454 h->state = RDAC_STATE_ACTIVE; 475 h->state = RDAC_STATE_ACTIVE;
455 err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h); 476 err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
456 if (err == SCSI_DH_OK) { 477 if (err == SCSI_DH_OK) {
457 inqp = &h->inq.c9; 478 inqp = &h->inq.c9;
458 if ((inqp->avte_cvp >> 7) == 0x1) { 479 /* detect the operating mode */
459 /* LUN in AVT mode */ 480 if ((inqp->avte_cvp >> 5) & 0x1)
460 sdev_printk(KERN_NOTICE, sdev, 481 h->mode = RDAC_MODE_IOSHIP; /* LUN in IOSHIP mode */
461 "%s: AVT mode detected\n", 482 else if (inqp->avte_cvp >> 7)
462 RDAC_NAME); 483 h->mode = RDAC_MODE_AVT; /* LUN in AVT mode */
463 h->lun_state = RDAC_LUN_AVT; 484 else
464 } else if ((inqp->avte_cvp & 0x1) != 0) { 485 h->mode = RDAC_MODE; /* LUN in RDAC mode */
465 /* LUN was owned by the controller */ 486
487 /* Update ownership */
488 if (inqp->avte_cvp & 0x1)
466 h->lun_state = RDAC_LUN_OWNED; 489 h->lun_state = RDAC_LUN_OWNED;
490 else {
491 h->lun_state = RDAC_LUN_UNOWNED;
492 if (h->mode == RDAC_MODE)
493 h->state = RDAC_STATE_PASSIVE;
467 } 494 }
468 }
469 495
470 if (h->lun_state == RDAC_LUN_UNOWNED) 496 /* Update path prio*/
471 h->state = RDAC_STATE_PASSIVE; 497 if (inqp->path_prio & 0x1)
498 h->preferred = RDAC_PREFERRED;
499 else
500 h->preferred = RDAC_NON_PREFERRED;
501 }
472 502
473 return err; 503 return err;
474} 504}
@@ -565,7 +595,6 @@ static void send_mode_select(struct work_struct *work)
565 int err, retry_cnt = RDAC_RETRY_COUNT; 595 int err, retry_cnt = RDAC_RETRY_COUNT;
566 struct rdac_queue_data *tmp, *qdata; 596 struct rdac_queue_data *tmp, *qdata;
567 LIST_HEAD(list); 597 LIST_HEAD(list);
568 u8 *lun_table;
569 598
570 spin_lock(&ctlr->ms_lock); 599 spin_lock(&ctlr->ms_lock);
571 list_splice_init(&ctlr->ms_head, &list); 600 list_splice_init(&ctlr->ms_head, &list);
@@ -573,21 +602,12 @@ static void send_mode_select(struct work_struct *work)
573 ctlr->ms_sdev = NULL; 602 ctlr->ms_sdev = NULL;
574 spin_unlock(&ctlr->ms_lock); 603 spin_unlock(&ctlr->ms_lock);
575 604
576 if (ctlr->use_ms10)
577 lun_table = ctlr->mode_select.expanded.lun_table;
578 else
579 lun_table = ctlr->mode_select.legacy.lun_table;
580
581retry: 605retry:
582 err = SCSI_DH_RES_TEMP_UNAVAIL; 606 err = SCSI_DH_RES_TEMP_UNAVAIL;
583 rq = rdac_failover_get(sdev, h); 607 rq = rdac_failover_get(sdev, h, &list);
584 if (!rq) 608 if (!rq)
585 goto done; 609 goto done;
586 610
587 list_for_each_entry(qdata, &list, entry) {
588 lun_table[qdata->h->lun] = 0x81;
589 }
590
591 RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, " 611 RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
592 "%s MODE_SELECT command", 612 "%s MODE_SELECT command",
593 (char *) h->ctlr->array_name, h->ctlr->index, 613 (char *) h->ctlr->array_name, h->ctlr->index,
@@ -650,12 +670,27 @@ static int rdac_activate(struct scsi_device *sdev,
650{ 670{
651 struct rdac_dh_data *h = get_rdac_data(sdev); 671 struct rdac_dh_data *h = get_rdac_data(sdev);
652 int err = SCSI_DH_OK; 672 int err = SCSI_DH_OK;
673 int act = 0;
653 674
654 err = check_ownership(sdev, h); 675 err = check_ownership(sdev, h);
655 if (err != SCSI_DH_OK) 676 if (err != SCSI_DH_OK)
656 goto done; 677 goto done;
657 678
658 if (h->lun_state == RDAC_LUN_UNOWNED) { 679 switch (h->mode) {
680 case RDAC_MODE:
681 if (h->lun_state == RDAC_LUN_UNOWNED)
682 act = 1;
683 break;
684 case RDAC_MODE_IOSHIP:
685 if ((h->lun_state == RDAC_LUN_UNOWNED) &&
686 (h->preferred == RDAC_PREFERRED))
687 act = 1;
688 break;
689 default:
690 break;
691 }
692
693 if (act) {
659 err = queue_mode_select(sdev, fn, data); 694 err = queue_mode_select(sdev, fn, data);
660 if (err == SCSI_DH_OK) 695 if (err == SCSI_DH_OK)
661 return 0; 696 return 0;
@@ -769,10 +804,13 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
769 {"DELL", "MD32xx"}, 804 {"DELL", "MD32xx"},
770 {"DELL", "MD32xxi"}, 805 {"DELL", "MD32xxi"},
771 {"DELL", "MD36xxi"}, 806 {"DELL", "MD36xxi"},
807 {"DELL", "MD36xxf"},
772 {"LSI", "INF-01-00"}, 808 {"LSI", "INF-01-00"},
773 {"ENGENIO", "INF-01-00"}, 809 {"ENGENIO", "INF-01-00"},
774 {"STK", "FLEXLINE 380"}, 810 {"STK", "FLEXLINE 380"},
775 {"SUN", "CSM100_R_FC"}, 811 {"SUN", "CSM100_R_FC"},
812 {"SUN", "STK6580_6780"},
813 {"SUN", "SUN_6180"},
776 {NULL, NULL}, 814 {NULL, NULL},
777}; 815};
778 816
@@ -798,7 +836,7 @@ static int rdac_bus_attach(struct scsi_device *sdev)
798 int err; 836 int err;
799 char array_name[ARRAY_LABEL_LEN]; 837 char array_name[ARRAY_LABEL_LEN];
800 838
801 scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) 839 scsi_dh_data = kzalloc(sizeof(*scsi_dh_data)
802 + sizeof(*h) , GFP_KERNEL); 840 + sizeof(*h) , GFP_KERNEL);
803 if (!scsi_dh_data) { 841 if (!scsi_dh_data) {
804 sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", 842 sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n",
@@ -835,8 +873,9 @@ static int rdac_bus_attach(struct scsi_device *sdev)
835 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); 873 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
836 874
837 sdev_printk(KERN_NOTICE, sdev, 875 sdev_printk(KERN_NOTICE, sdev,
838 "%s: LUN %d (%s)\n", 876 "%s: LUN %d (%s) (%s)\n",
839 RDAC_NAME, h->lun, lun_state[(int)h->lun_state]); 877 RDAC_NAME, h->lun, mode[(int)h->mode],
878 lun_state[(int)h->lun_state]);
840 879
841 return 0; 880 return 0;
842 881
@@ -904,4 +943,5 @@ module_exit(rdac_exit);
904 943
905MODULE_DESCRIPTION("Multipath LSI/Engenio RDAC driver"); 944MODULE_DESCRIPTION("Multipath LSI/Engenio RDAC driver");
906MODULE_AUTHOR("Mike Christie, Chandra Seetharaman"); 945MODULE_AUTHOR("Mike Christie, Chandra Seetharaman");
946MODULE_VERSION("01.00.0000.0000");
907MODULE_LICENSE("GPL"); 947MODULE_LICENSE("GPL");