diff options
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 29 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 59 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_emc.c | 58 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_hp_sw.c | 54 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_rdac.c | 53 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 2 |
6 files changed, 88 insertions, 167 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index d8a8aac2c3db..1dba62c5cf6a 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c | |||
@@ -98,7 +98,7 @@ device_handler_match(struct scsi_device_handler *scsi_dh, | |||
98 | static int scsi_dh_handler_attach(struct scsi_device *sdev, | 98 | static int scsi_dh_handler_attach(struct scsi_device *sdev, |
99 | struct scsi_device_handler *scsi_dh) | 99 | struct scsi_device_handler *scsi_dh) |
100 | { | 100 | { |
101 | int err = 0; | 101 | struct scsi_dh_data *d; |
102 | 102 | ||
103 | if (sdev->scsi_dh_data) { | 103 | if (sdev->scsi_dh_data) { |
104 | if (sdev->scsi_dh_data->scsi_dh != scsi_dh) | 104 | if (sdev->scsi_dh_data->scsi_dh != scsi_dh) |
@@ -111,15 +111,22 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev, | |||
111 | if (!try_module_get(scsi_dh->module)) | 111 | if (!try_module_get(scsi_dh->module)) |
112 | return -EINVAL; | 112 | return -EINVAL; |
113 | 113 | ||
114 | err = scsi_dh->attach(sdev); | 114 | d = scsi_dh->attach(sdev); |
115 | if (err) { | 115 | if (IS_ERR(d)) { |
116 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%ld)\n", | ||
117 | scsi_dh->name, PTR_ERR(d)); | ||
116 | module_put(scsi_dh->module); | 118 | module_put(scsi_dh->module); |
117 | return err; | 119 | return PTR_ERR(d); |
118 | } | 120 | } |
119 | 121 | ||
120 | kref_init(&sdev->scsi_dh_data->kref); | 122 | d->scsi_dh = scsi_dh; |
121 | sdev->scsi_dh_data->sdev = sdev; | 123 | kref_init(&d->kref); |
122 | return err; | 124 | d->sdev = sdev; |
125 | |||
126 | spin_lock_irq(sdev->request_queue->queue_lock); | ||
127 | sdev->scsi_dh_data = d; | ||
128 | spin_unlock_irq(sdev->request_queue->queue_lock); | ||
129 | return 0; | ||
123 | } | 130 | } |
124 | 131 | ||
125 | static void __detach_handler (struct kref *kref) | 132 | static void __detach_handler (struct kref *kref) |
@@ -127,8 +134,14 @@ static void __detach_handler (struct kref *kref) | |||
127 | struct scsi_dh_data *scsi_dh_data = | 134 | struct scsi_dh_data *scsi_dh_data = |
128 | container_of(kref, struct scsi_dh_data, kref); | 135 | container_of(kref, struct scsi_dh_data, kref); |
129 | struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh; | 136 | struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh; |
137 | struct scsi_device *sdev = scsi_dh_data->sdev; | ||
138 | |||
139 | spin_lock_irq(sdev->request_queue->queue_lock); | ||
140 | sdev->scsi_dh_data = NULL; | ||
141 | spin_unlock_irq(sdev->request_queue->queue_lock); | ||
130 | 142 | ||
131 | scsi_dh->detach(scsi_dh_data->sdev); | 143 | scsi_dh->detach(sdev); |
144 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", scsi_dh->name); | ||
132 | module_put(scsi_dh->module); | 145 | module_put(scsi_dh->module); |
133 | } | 146 | } |
134 | 147 | ||
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index d9781045c4ee..854b568b9931 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -824,39 +824,18 @@ static bool alua_match(struct scsi_device *sdev) | |||
824 | return (scsi_device_tpgs(sdev) != 0); | 824 | return (scsi_device_tpgs(sdev) != 0); |
825 | } | 825 | } |
826 | 826 | ||
827 | static int alua_bus_attach(struct scsi_device *sdev); | ||
828 | static void alua_bus_detach(struct scsi_device *sdev); | ||
829 | |||
830 | static struct scsi_device_handler alua_dh = { | ||
831 | .name = ALUA_DH_NAME, | ||
832 | .module = THIS_MODULE, | ||
833 | .attach = alua_bus_attach, | ||
834 | .detach = alua_bus_detach, | ||
835 | .prep_fn = alua_prep_fn, | ||
836 | .check_sense = alua_check_sense, | ||
837 | .activate = alua_activate, | ||
838 | .set_params = alua_set_params, | ||
839 | .match = alua_match, | ||
840 | }; | ||
841 | |||
842 | /* | 827 | /* |
843 | * alua_bus_attach - Attach device handler | 828 | * alua_bus_attach - Attach device handler |
844 | * @sdev: device to be attached to | 829 | * @sdev: device to be attached to |
845 | */ | 830 | */ |
846 | static int alua_bus_attach(struct scsi_device *sdev) | 831 | static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev) |
847 | { | 832 | { |
848 | struct alua_dh_data *h; | 833 | struct alua_dh_data *h; |
849 | unsigned long flags; | 834 | int err; |
850 | int err = SCSI_DH_OK; | ||
851 | 835 | ||
852 | h = kzalloc(sizeof(*h) , GFP_KERNEL); | 836 | h = kzalloc(sizeof(*h) , GFP_KERNEL); |
853 | if (!h) { | 837 | if (!h) |
854 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", | 838 | return ERR_PTR(-ENOMEM); |
855 | ALUA_DH_NAME); | ||
856 | return -ENOMEM; | ||
857 | } | ||
858 | |||
859 | h->dh_data.scsi_dh = &alua_dh; | ||
860 | h->tpgs = TPGS_MODE_UNINITIALIZED; | 839 | h->tpgs = TPGS_MODE_UNINITIALIZED; |
861 | h->state = TPGS_STATE_OPTIMIZED; | 840 | h->state = TPGS_STATE_OPTIMIZED; |
862 | h->group_id = -1; | 841 | h->group_id = -1; |
@@ -866,20 +845,14 @@ static int alua_bus_attach(struct scsi_device *sdev) | |||
866 | h->sdev = sdev; | 845 | h->sdev = sdev; |
867 | 846 | ||
868 | err = alua_initialize(sdev, h); | 847 | err = alua_initialize(sdev, h); |
869 | if ((err != SCSI_DH_OK) && (err != SCSI_DH_DEV_OFFLINED)) | 848 | if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED) |
870 | goto failed; | 849 | goto failed; |
871 | 850 | ||
872 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
873 | sdev->scsi_dh_data = &h->dh_data; | ||
874 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
875 | sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME); | 851 | sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME); |
876 | 852 | return &h->dh_data; | |
877 | return 0; | ||
878 | |||
879 | failed: | 853 | failed: |
880 | kfree(h); | 854 | kfree(h); |
881 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", ALUA_DH_NAME); | 855 | return ERR_PTR(-EINVAL); |
882 | return -EINVAL; | ||
883 | } | 856 | } |
884 | 857 | ||
885 | /* | 858 | /* |
@@ -889,18 +862,24 @@ failed: | |||
889 | static void alua_bus_detach(struct scsi_device *sdev) | 862 | static void alua_bus_detach(struct scsi_device *sdev) |
890 | { | 863 | { |
891 | struct alua_dh_data *h = get_alua_data(sdev); | 864 | struct alua_dh_data *h = get_alua_data(sdev); |
892 | unsigned long flags; | ||
893 | |||
894 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
895 | sdev->scsi_dh_data = NULL; | ||
896 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
897 | 865 | ||
898 | if (h->buff && h->inq != h->buff) | 866 | if (h->buff && h->inq != h->buff) |
899 | kfree(h->buff); | 867 | kfree(h->buff); |
900 | kfree(h); | 868 | kfree(h); |
901 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", ALUA_DH_NAME); | ||
902 | } | 869 | } |
903 | 870 | ||
871 | static struct scsi_device_handler alua_dh = { | ||
872 | .name = ALUA_DH_NAME, | ||
873 | .module = THIS_MODULE, | ||
874 | .attach = alua_bus_attach, | ||
875 | .detach = alua_bus_detach, | ||
876 | .prep_fn = alua_prep_fn, | ||
877 | .check_sense = alua_check_sense, | ||
878 | .activate = alua_activate, | ||
879 | .set_params = alua_set_params, | ||
880 | .match = alua_match, | ||
881 | }; | ||
882 | |||
904 | static int __init alua_init(void) | 883 | static int __init alua_init(void) |
905 | { | 884 | { |
906 | int r; | 885 | int r; |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 800deb75a111..6ed1caadbc6a 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -650,35 +650,14 @@ static bool clariion_match(struct scsi_device *sdev) | |||
650 | return false; | 650 | return false; |
651 | } | 651 | } |
652 | 652 | ||
653 | static int clariion_bus_attach(struct scsi_device *sdev); | 653 | static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev) |
654 | static void clariion_bus_detach(struct scsi_device *sdev); | ||
655 | |||
656 | static struct scsi_device_handler clariion_dh = { | ||
657 | .name = CLARIION_NAME, | ||
658 | .module = THIS_MODULE, | ||
659 | .attach = clariion_bus_attach, | ||
660 | .detach = clariion_bus_detach, | ||
661 | .check_sense = clariion_check_sense, | ||
662 | .activate = clariion_activate, | ||
663 | .prep_fn = clariion_prep_fn, | ||
664 | .set_params = clariion_set_params, | ||
665 | .match = clariion_match, | ||
666 | }; | ||
667 | |||
668 | static int clariion_bus_attach(struct scsi_device *sdev) | ||
669 | { | 654 | { |
670 | struct clariion_dh_data *h; | 655 | struct clariion_dh_data *h; |
671 | unsigned long flags; | ||
672 | int err; | 656 | int err; |
673 | 657 | ||
674 | h = kzalloc(sizeof(*h) , GFP_KERNEL); | 658 | h = kzalloc(sizeof(*h) , GFP_KERNEL); |
675 | if (!h) { | 659 | if (!h) |
676 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", | 660 | return ERR_PTR(-ENOMEM); |
677 | CLARIION_NAME); | ||
678 | return -ENOMEM; | ||
679 | } | ||
680 | |||
681 | h->dh_data.scsi_dh = &clariion_dh; | ||
682 | h->lun_state = CLARIION_LUN_UNINITIALIZED; | 661 | h->lun_state = CLARIION_LUN_UNINITIALIZED; |
683 | h->default_sp = CLARIION_UNBOUND_LU; | 662 | h->default_sp = CLARIION_UNBOUND_LU; |
684 | h->current_sp = CLARIION_UNBOUND_LU; | 663 | h->current_sp = CLARIION_UNBOUND_LU; |
@@ -691,40 +670,37 @@ static int clariion_bus_attach(struct scsi_device *sdev) | |||
691 | if (err != SCSI_DH_OK) | 670 | if (err != SCSI_DH_OK) |
692 | goto failed; | 671 | goto failed; |
693 | 672 | ||
694 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
695 | sdev->scsi_dh_data = &h->dh_data; | ||
696 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
697 | |||
698 | sdev_printk(KERN_INFO, sdev, | 673 | sdev_printk(KERN_INFO, sdev, |
699 | "%s: connected to SP %c Port %d (%s, default SP %c)\n", | 674 | "%s: connected to SP %c Port %d (%s, default SP %c)\n", |
700 | CLARIION_NAME, h->current_sp + 'A', | 675 | CLARIION_NAME, h->current_sp + 'A', |
701 | h->port, lun_state[h->lun_state], | 676 | h->port, lun_state[h->lun_state], |
702 | h->default_sp + 'A'); | 677 | h->default_sp + 'A'); |
703 | 678 | return &h->dh_data; | |
704 | return 0; | ||
705 | 679 | ||
706 | failed: | 680 | failed: |
707 | kfree(h); | 681 | kfree(h); |
708 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", | 682 | return ERR_PTR(-EINVAL); |
709 | CLARIION_NAME); | ||
710 | return -EINVAL; | ||
711 | } | 683 | } |
712 | 684 | ||
713 | static void clariion_bus_detach(struct scsi_device *sdev) | 685 | static void clariion_bus_detach(struct scsi_device *sdev) |
714 | { | 686 | { |
715 | struct clariion_dh_data *h = get_clariion_data(sdev); | 687 | struct clariion_dh_data *h = get_clariion_data(sdev); |
716 | unsigned long flags; | ||
717 | |||
718 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
719 | sdev->scsi_dh_data = NULL; | ||
720 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
721 | |||
722 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", | ||
723 | CLARIION_NAME); | ||
724 | 688 | ||
725 | kfree(h); | 689 | kfree(h); |
726 | } | 690 | } |
727 | 691 | ||
692 | static struct scsi_device_handler clariion_dh = { | ||
693 | .name = CLARIION_NAME, | ||
694 | .module = THIS_MODULE, | ||
695 | .attach = clariion_bus_attach, | ||
696 | .detach = clariion_bus_detach, | ||
697 | .check_sense = clariion_check_sense, | ||
698 | .activate = clariion_activate, | ||
699 | .prep_fn = clariion_prep_fn, | ||
700 | .set_params = clariion_set_params, | ||
701 | .match = clariion_match, | ||
702 | }; | ||
703 | |||
728 | static int __init clariion_init(void) | 704 | static int __init clariion_init(void) |
729 | { | 705 | { |
730 | int r; | 706 | int r; |
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 471ffd19f2c5..485d99544a15 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -340,33 +340,14 @@ static bool hp_sw_match(struct scsi_device *sdev) | |||
340 | return false; | 340 | return false; |
341 | } | 341 | } |
342 | 342 | ||
343 | static int hp_sw_bus_attach(struct scsi_device *sdev); | 343 | static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev) |
344 | static void hp_sw_bus_detach(struct scsi_device *sdev); | ||
345 | |||
346 | static struct scsi_device_handler hp_sw_dh = { | ||
347 | .name = HP_SW_NAME, | ||
348 | .module = THIS_MODULE, | ||
349 | .attach = hp_sw_bus_attach, | ||
350 | .detach = hp_sw_bus_detach, | ||
351 | .activate = hp_sw_activate, | ||
352 | .prep_fn = hp_sw_prep_fn, | ||
353 | .match = hp_sw_match, | ||
354 | }; | ||
355 | |||
356 | static int hp_sw_bus_attach(struct scsi_device *sdev) | ||
357 | { | 344 | { |
358 | struct hp_sw_dh_data *h; | 345 | struct hp_sw_dh_data *h; |
359 | unsigned long flags; | ||
360 | int ret; | 346 | int ret; |
361 | 347 | ||
362 | h = kzalloc(sizeof(*h), GFP_KERNEL); | 348 | h = kzalloc(sizeof(*h), GFP_KERNEL); |
363 | if (!h) { | 349 | if (!h) |
364 | sdev_printk(KERN_ERR, sdev, "%s: Attach Failed\n", | 350 | return ERR_PTR(-ENOMEM); |
365 | HP_SW_NAME); | ||
366 | return -ENOMEM; | ||
367 | } | ||
368 | |||
369 | h->dh_data.scsi_dh = &hp_sw_dh; | ||
370 | h->path_state = HP_SW_PATH_UNINITIALIZED; | 351 | h->path_state = HP_SW_PATH_UNINITIALIZED; |
371 | h->retries = HP_SW_RETRIES; | 352 | h->retries = HP_SW_RETRIES; |
372 | h->sdev = sdev; | 353 | h->sdev = sdev; |
@@ -375,37 +356,32 @@ static int hp_sw_bus_attach(struct scsi_device *sdev) | |||
375 | if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED) | 356 | if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED) |
376 | goto failed; | 357 | goto failed; |
377 | 358 | ||
378 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
379 | sdev->scsi_dh_data = &h->dh_data; | ||
380 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
381 | |||
382 | sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n", | 359 | sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n", |
383 | HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE? | 360 | HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE? |
384 | "active":"passive"); | 361 | "active":"passive"); |
385 | 362 | return &h->dh_data; | |
386 | return 0; | ||
387 | |||
388 | failed: | 363 | failed: |
389 | kfree(h); | 364 | kfree(h); |
390 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", | 365 | return ERR_PTR(-EINVAL); |
391 | HP_SW_NAME); | ||
392 | return -EINVAL; | ||
393 | } | 366 | } |
394 | 367 | ||
395 | static void hp_sw_bus_detach( struct scsi_device *sdev ) | 368 | static void hp_sw_bus_detach( struct scsi_device *sdev ) |
396 | { | 369 | { |
397 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | 370 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); |
398 | unsigned long flags; | ||
399 | |||
400 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
401 | sdev->scsi_dh_data = NULL; | ||
402 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
403 | |||
404 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", HP_SW_NAME); | ||
405 | 371 | ||
406 | kfree(h); | 372 | kfree(h); |
407 | } | 373 | } |
408 | 374 | ||
375 | static struct scsi_device_handler hp_sw_dh = { | ||
376 | .name = HP_SW_NAME, | ||
377 | .module = THIS_MODULE, | ||
378 | .attach = hp_sw_bus_attach, | ||
379 | .detach = hp_sw_bus_detach, | ||
380 | .activate = hp_sw_activate, | ||
381 | .prep_fn = hp_sw_prep_fn, | ||
382 | .match = hp_sw_match, | ||
383 | }; | ||
384 | |||
409 | static int __init hp_sw_init(void) | 385 | static int __init hp_sw_init(void) |
410 | { | 386 | { |
411 | return scsi_register_device_handler(&hp_sw_dh); | 387 | return scsi_register_device_handler(&hp_sw_dh); |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 8b09528613d2..b46ace3d4bf0 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -827,36 +827,16 @@ static bool rdac_match(struct scsi_device *sdev) | |||
827 | return false; | 827 | return false; |
828 | } | 828 | } |
829 | 829 | ||
830 | static int rdac_bus_attach(struct scsi_device *sdev); | 830 | static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev) |
831 | static void rdac_bus_detach(struct scsi_device *sdev); | ||
832 | |||
833 | static struct scsi_device_handler rdac_dh = { | ||
834 | .name = RDAC_NAME, | ||
835 | .module = THIS_MODULE, | ||
836 | .prep_fn = rdac_prep_fn, | ||
837 | .check_sense = rdac_check_sense, | ||
838 | .attach = rdac_bus_attach, | ||
839 | .detach = rdac_bus_detach, | ||
840 | .activate = rdac_activate, | ||
841 | .match = rdac_match, | ||
842 | }; | ||
843 | |||
844 | static int rdac_bus_attach(struct scsi_device *sdev) | ||
845 | { | 831 | { |
846 | struct rdac_dh_data *h; | 832 | struct rdac_dh_data *h; |
847 | unsigned long flags; | ||
848 | int err; | 833 | int err; |
849 | char array_name[ARRAY_LABEL_LEN]; | 834 | char array_name[ARRAY_LABEL_LEN]; |
850 | char array_id[UNIQUE_ID_LEN]; | 835 | char array_id[UNIQUE_ID_LEN]; |
851 | 836 | ||
852 | h = kzalloc(sizeof(*h) , GFP_KERNEL); | 837 | h = kzalloc(sizeof(*h) , GFP_KERNEL); |
853 | if (!h) { | 838 | if (!h) |
854 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", | 839 | return ERR_PTR(-ENOMEM); |
855 | RDAC_NAME); | ||
856 | return -ENOMEM; | ||
857 | } | ||
858 | |||
859 | h->dh_data.scsi_dh = &rdac_dh; | ||
860 | h->lun = UNINITIALIZED_LUN; | 840 | h->lun = UNINITIALIZED_LUN; |
861 | h->state = RDAC_STATE_ACTIVE; | 841 | h->state = RDAC_STATE_ACTIVE; |
862 | 842 | ||
@@ -876,16 +856,12 @@ static int rdac_bus_attach(struct scsi_device *sdev) | |||
876 | if (err != SCSI_DH_OK) | 856 | if (err != SCSI_DH_OK) |
877 | goto clean_ctlr; | 857 | goto clean_ctlr; |
878 | 858 | ||
879 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
880 | sdev->scsi_dh_data = &h->dh_data; | ||
881 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
882 | |||
883 | sdev_printk(KERN_NOTICE, sdev, | 859 | sdev_printk(KERN_NOTICE, sdev, |
884 | "%s: LUN %d (%s) (%s)\n", | 860 | "%s: LUN %d (%s) (%s)\n", |
885 | RDAC_NAME, h->lun, mode[(int)h->mode], | 861 | RDAC_NAME, h->lun, mode[(int)h->mode], |
886 | lun_state[(int)h->lun_state]); | 862 | lun_state[(int)h->lun_state]); |
887 | 863 | ||
888 | return 0; | 864 | return &h->dh_data; |
889 | 865 | ||
890 | clean_ctlr: | 866 | clean_ctlr: |
891 | spin_lock(&list_lock); | 867 | spin_lock(&list_lock); |
@@ -894,32 +870,33 @@ clean_ctlr: | |||
894 | 870 | ||
895 | failed: | 871 | failed: |
896 | kfree(h); | 872 | kfree(h); |
897 | sdev_printk(KERN_ERR, sdev, "%s: not attached\n", | 873 | return ERR_PTR(-EINVAL); |
898 | RDAC_NAME); | ||
899 | return -EINVAL; | ||
900 | } | 874 | } |
901 | 875 | ||
902 | static void rdac_bus_detach( struct scsi_device *sdev ) | 876 | static void rdac_bus_detach( struct scsi_device *sdev ) |
903 | { | 877 | { |
904 | struct rdac_dh_data *h = get_rdac_data(sdev); | 878 | struct rdac_dh_data *h = get_rdac_data(sdev); |
905 | unsigned long flags; | ||
906 | 879 | ||
907 | if (h->ctlr && h->ctlr->ms_queued) | 880 | if (h->ctlr && h->ctlr->ms_queued) |
908 | flush_workqueue(kmpath_rdacd); | 881 | flush_workqueue(kmpath_rdacd); |
909 | 882 | ||
910 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | ||
911 | sdev->scsi_dh_data = NULL; | ||
912 | spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); | ||
913 | |||
914 | spin_lock(&list_lock); | 883 | spin_lock(&list_lock); |
915 | if (h->ctlr) | 884 | if (h->ctlr) |
916 | kref_put(&h->ctlr->kref, release_controller); | 885 | kref_put(&h->ctlr->kref, release_controller); |
917 | spin_unlock(&list_lock); | 886 | spin_unlock(&list_lock); |
918 | kfree(h); | 887 | kfree(h); |
919 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME); | ||
920 | } | 888 | } |
921 | 889 | ||
922 | 890 | static struct scsi_device_handler rdac_dh = { | |
891 | .name = RDAC_NAME, | ||
892 | .module = THIS_MODULE, | ||
893 | .prep_fn = rdac_prep_fn, | ||
894 | .check_sense = rdac_check_sense, | ||
895 | .attach = rdac_bus_attach, | ||
896 | .detach = rdac_bus_detach, | ||
897 | .activate = rdac_activate, | ||
898 | .match = rdac_match, | ||
899 | }; | ||
923 | 900 | ||
924 | static int __init rdac_init(void) | 901 | static int __init rdac_init(void) |
925 | { | 902 | { |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 2601c97fd8b9..50d47e6e89d1 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -210,7 +210,7 @@ struct scsi_device_handler { | |||
210 | struct module *module; | 210 | struct module *module; |
211 | const char *name; | 211 | const char *name; |
212 | int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); | 212 | int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); |
213 | int (*attach)(struct scsi_device *); | 213 | struct scsi_dh_data *(*attach)(struct scsi_device *); |
214 | void (*detach)(struct scsi_device *); | 214 | void (*detach)(struct scsi_device *); |
215 | int (*activate)(struct scsi_device *, activate_complete, void *); | 215 | int (*activate)(struct scsi_device *, activate_complete, void *); |
216 | int (*prep_fn)(struct scsi_device *, struct request *); | 216 | int (*prep_fn)(struct scsi_device *, struct request *); |