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_alua.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c72
2 files changed, 56 insertions, 18 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 42fe52902add..6fec9fe5dc39 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -782,7 +782,7 @@ static int alua_bus_attach(struct scsi_device *sdev)
782 h->sdev = sdev; 782 h->sdev = sdev;
783 783
784 err = alua_initialize(sdev, h); 784 err = alua_initialize(sdev, h);
785 if (err != SCSI_DH_OK) 785 if ((err != SCSI_DH_OK) && (err != SCSI_DH_DEV_OFFLINED))
786 goto failed; 786 goto failed;
787 787
788 if (!try_module_get(THIS_MODULE)) 788 if (!try_module_get(THIS_MODULE))
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 293c183dfe6d..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 {
@@ -458,25 +472,33 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
458 int err; 472 int err;
459 struct c9_inquiry *inqp; 473 struct c9_inquiry *inqp;
460 474
461 h->lun_state = RDAC_LUN_UNOWNED;
462 h->state = RDAC_STATE_ACTIVE; 475 h->state = RDAC_STATE_ACTIVE;
463 err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h); 476 err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
464 if (err == SCSI_DH_OK) { 477 if (err == SCSI_DH_OK) {
465 inqp = &h->inq.c9; 478 inqp = &h->inq.c9;
466 if ((inqp->avte_cvp >> 7) == 0x1) { 479 /* detect the operating mode */
467 /* LUN in AVT mode */ 480 if ((inqp->avte_cvp >> 5) & 0x1)
468 sdev_printk(KERN_NOTICE, sdev, 481 h->mode = RDAC_MODE_IOSHIP; /* LUN in IOSHIP mode */
469 "%s: AVT mode detected\n", 482 else if (inqp->avte_cvp >> 7)
470 RDAC_NAME); 483 h->mode = RDAC_MODE_AVT; /* LUN in AVT mode */
471 h->lun_state = RDAC_LUN_AVT; 484 else
472 } else if ((inqp->avte_cvp & 0x1) != 0) { 485 h->mode = RDAC_MODE; /* LUN in RDAC mode */
473 /* LUN was owned by the controller */ 486
487 /* Update ownership */
488 if (inqp->avte_cvp & 0x1)
474 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;
475 } 494 }
476 }
477 495
478 if (h->lun_state == RDAC_LUN_UNOWNED) 496 /* Update path prio*/
479 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 }
480 502
481 return err; 503 return err;
482} 504}
@@ -648,12 +670,27 @@ static int rdac_activate(struct scsi_device *sdev,
648{ 670{
649 struct rdac_dh_data *h = get_rdac_data(sdev); 671 struct rdac_dh_data *h = get_rdac_data(sdev);
650 int err = SCSI_DH_OK; 672 int err = SCSI_DH_OK;
673 int act = 0;
651 674
652 err = check_ownership(sdev, h); 675 err = check_ownership(sdev, h);
653 if (err != SCSI_DH_OK) 676 if (err != SCSI_DH_OK)
654 goto done; 677 goto done;
655 678
656 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) {
657 err = queue_mode_select(sdev, fn, data); 694 err = queue_mode_select(sdev, fn, data);
658 if (err == SCSI_DH_OK) 695 if (err == SCSI_DH_OK)
659 return 0; 696 return 0;
@@ -836,8 +873,9 @@ static int rdac_bus_attach(struct scsi_device *sdev)
836 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); 873 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
837 874
838 sdev_printk(KERN_NOTICE, sdev, 875 sdev_printk(KERN_NOTICE, sdev,
839 "%s: LUN %d (%s)\n", 876 "%s: LUN %d (%s) (%s)\n",
840 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]);
841 879
842 return 0; 880 return 0;
843 881