diff options
Diffstat (limited to 'drivers/scsi/device_handler')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 2 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_rdac.c | 72 |
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 | ||
212 | static const char *mode[] = { | ||
213 | "RDAC", | ||
214 | "AVT", | ||
215 | "IOSHIP", | ||
216 | }; | ||
202 | static const char *lun_state[] = | 217 | static const char *lun_state[] = |
203 | { | 218 | { |
204 | "unowned", | 219 | "unowned", |
205 | "owned", | 220 | "owned", |
206 | "owned (AVT mode)", | ||
207 | }; | 221 | }; |
208 | 222 | ||
209 | struct rdac_queue_data { | 223 | struct 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 | ||