diff options
author | James Bottomley <JBottomley@Odin.com> | 2015-11-12 07:06:18 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-11-12 07:06:18 -0500 |
commit | febdfbd2137a5727f70dfbf920105c07e6c2a21e (patch) | |
tree | 9483a5493ad3e08626e1f53ded594f88a6f4e710 /drivers/scsi/mpt3sas/mpt3sas_scsih.c | |
parent | 0da39687a15403251bdfd1c6fb18025c0607326b (diff) | |
parent | 2c5d16d6a9e7218e57b716e4fd9d77c776d21471 (diff) |
Merge tag '4.4-scsi-mkp' into misc
SCSI queue for 4.4.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1555 |
1 files changed, 1081 insertions, 474 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 8ccef38523fa..d95206b7e116 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -54,14 +54,10 @@ | |||
54 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
55 | #include <linux/aer.h> | 55 | #include <linux/aer.h> |
56 | #include <linux/raid_class.h> | 56 | #include <linux/raid_class.h> |
57 | #include <asm/unaligned.h> | ||
57 | 58 | ||
58 | #include "mpt3sas_base.h" | 59 | #include "mpt3sas_base.h" |
59 | 60 | ||
60 | MODULE_AUTHOR(MPT3SAS_AUTHOR); | ||
61 | MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION); | ||
62 | MODULE_LICENSE("GPL"); | ||
63 | MODULE_VERSION(MPT3SAS_DRIVER_VERSION); | ||
64 | |||
65 | #define RAID_CHANNEL 1 | 61 | #define RAID_CHANNEL 1 |
66 | /* forward proto's */ | 62 | /* forward proto's */ |
67 | static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, | 63 | static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, |
@@ -75,11 +71,16 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |||
75 | 71 | ||
76 | static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid); | 72 | static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid); |
77 | 73 | ||
78 | static void _scsih_scan_start(struct Scsi_Host *shost); | ||
79 | static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time); | ||
80 | |||
81 | /* global parameters */ | 74 | /* global parameters */ |
82 | LIST_HEAD(mpt3sas_ioc_list); | 75 | LIST_HEAD(mpt3sas_ioc_list); |
76 | /* global ioc lock for list operations */ | ||
77 | DEFINE_SPINLOCK(gioc_lock); | ||
78 | |||
79 | MODULE_AUTHOR(MPT3SAS_AUTHOR); | ||
80 | MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION); | ||
81 | MODULE_LICENSE("GPL"); | ||
82 | MODULE_VERSION(MPT3SAS_DRIVER_VERSION); | ||
83 | MODULE_ALIAS("mpt2sas"); | ||
83 | 84 | ||
84 | /* local parameters */ | 85 | /* local parameters */ |
85 | static u8 scsi_io_cb_idx = -1; | 86 | static u8 scsi_io_cb_idx = -1; |
@@ -90,7 +91,8 @@ static u8 port_enable_cb_idx = -1; | |||
90 | static u8 transport_cb_idx = -1; | 91 | static u8 transport_cb_idx = -1; |
91 | static u8 scsih_cb_idx = -1; | 92 | static u8 scsih_cb_idx = -1; |
92 | static u8 config_cb_idx = -1; | 93 | static u8 config_cb_idx = -1; |
93 | static int mpt_ids; | 94 | static int mpt2_ids; |
95 | static int mpt3_ids; | ||
94 | 96 | ||
95 | static u8 tm_tr_cb_idx = -1 ; | 97 | static u8 tm_tr_cb_idx = -1 ; |
96 | static u8 tm_tr_volume_cb_idx = -1 ; | 98 | static u8 tm_tr_volume_cb_idx = -1 ; |
@@ -117,8 +119,12 @@ static u64 max_lun = MPT3SAS_MAX_LUN; | |||
117 | module_param(max_lun, ullong, 0); | 119 | module_param(max_lun, ullong, 0); |
118 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | 120 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); |
119 | 121 | ||
120 | 122 | static ushort hbas_to_enumerate; | |
121 | 123 | module_param(hbas_to_enumerate, ushort, 0); | |
124 | MODULE_PARM_DESC(hbas_to_enumerate, | ||
125 | " 0 - enumerates both SAS 2.0 & SAS 3.0 generation HBAs\n \ | ||
126 | 1 - enumerates only SAS 2.0 generation HBAs\n \ | ||
127 | 2 - enumerates only SAS 3.0 generation HBAs (default=0)"); | ||
122 | 128 | ||
123 | /* diag_buffer_enable is bitwise | 129 | /* diag_buffer_enable is bitwise |
124 | * bit 0 set = TRACE | 130 | * bit 0 set = TRACE |
@@ -143,8 +149,8 @@ MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 "); | |||
143 | 149 | ||
144 | 150 | ||
145 | /* raid transport support */ | 151 | /* raid transport support */ |
146 | 152 | struct raid_template *mpt3sas_raid_template; | |
147 | static struct raid_template *mpt3sas_raid_template; | 153 | struct raid_template *mpt2sas_raid_template; |
148 | 154 | ||
149 | 155 | ||
150 | /** | 156 | /** |
@@ -191,11 +197,36 @@ struct fw_event_work { | |||
191 | u8 VP_ID; | 197 | u8 VP_ID; |
192 | u8 ignore; | 198 | u8 ignore; |
193 | u16 event; | 199 | u16 event; |
200 | struct kref refcount; | ||
194 | char event_data[0] __aligned(4); | 201 | char event_data[0] __aligned(4); |
195 | }; | 202 | }; |
196 | 203 | ||
197 | /* raid transport support */ | 204 | static void fw_event_work_free(struct kref *r) |
198 | static struct raid_template *mpt3sas_raid_template; | 205 | { |
206 | kfree(container_of(r, struct fw_event_work, refcount)); | ||
207 | } | ||
208 | |||
209 | static void fw_event_work_get(struct fw_event_work *fw_work) | ||
210 | { | ||
211 | kref_get(&fw_work->refcount); | ||
212 | } | ||
213 | |||
214 | static void fw_event_work_put(struct fw_event_work *fw_work) | ||
215 | { | ||
216 | kref_put(&fw_work->refcount, fw_event_work_free); | ||
217 | } | ||
218 | |||
219 | static struct fw_event_work *alloc_fw_event_work(int len) | ||
220 | { | ||
221 | struct fw_event_work *fw_event; | ||
222 | |||
223 | fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC); | ||
224 | if (!fw_event) | ||
225 | return NULL; | ||
226 | |||
227 | kref_init(&fw_event->refcount); | ||
228 | return fw_event; | ||
229 | } | ||
199 | 230 | ||
200 | /** | 231 | /** |
201 | * struct _scsi_io_transfer - scsi io transfer | 232 | * struct _scsi_io_transfer - scsi io transfer |
@@ -245,28 +276,6 @@ struct _scsi_io_transfer { | |||
245 | u32 transfer_length; | 276 | u32 transfer_length; |
246 | }; | 277 | }; |
247 | 278 | ||
248 | /* | ||
249 | * The pci device ids are defined in mpi/mpi2_cnfg.h. | ||
250 | */ | ||
251 | static const struct pci_device_id scsih_pci_table[] = { | ||
252 | /* Fury ~ 3004 and 3008 */ | ||
253 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004, | ||
254 | PCI_ANY_ID, PCI_ANY_ID }, | ||
255 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008, | ||
256 | PCI_ANY_ID, PCI_ANY_ID }, | ||
257 | /* Invader ~ 3108 */ | ||
258 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1, | ||
259 | PCI_ANY_ID, PCI_ANY_ID }, | ||
260 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2, | ||
261 | PCI_ANY_ID, PCI_ANY_ID }, | ||
262 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5, | ||
263 | PCI_ANY_ID, PCI_ANY_ID }, | ||
264 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6, | ||
265 | PCI_ANY_ID, PCI_ANY_ID }, | ||
266 | {0} /* Terminating entry */ | ||
267 | }; | ||
268 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); | ||
269 | |||
270 | /** | 279 | /** |
271 | * _scsih_set_debug_level - global setting of ioc->logging_level. | 280 | * _scsih_set_debug_level - global setting of ioc->logging_level. |
272 | * | 281 | * |
@@ -282,8 +291,10 @@ _scsih_set_debug_level(const char *val, struct kernel_param *kp) | |||
282 | return ret; | 291 | return ret; |
283 | 292 | ||
284 | pr_info("setting logging_level(0x%08x)\n", logging_level); | 293 | pr_info("setting logging_level(0x%08x)\n", logging_level); |
294 | spin_lock(&gioc_lock); | ||
285 | list_for_each_entry(ioc, &mpt3sas_ioc_list, list) | 295 | list_for_each_entry(ioc, &mpt3sas_ioc_list, list) |
286 | ioc->logging_level = logging_level; | 296 | ioc->logging_level = logging_level; |
297 | spin_unlock(&gioc_lock); | ||
287 | return 0; | 298 | return 0; |
288 | } | 299 | } |
289 | module_param_call(logging_level, _scsih_set_debug_level, param_get_int, | 300 | module_param_call(logging_level, _scsih_set_debug_level, param_get_int, |
@@ -518,8 +529,61 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | |||
518 | } | 529 | } |
519 | } | 530 | } |
520 | 531 | ||
532 | static struct _sas_device * | ||
533 | __mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, | ||
534 | struct MPT3SAS_TARGET *tgt_priv) | ||
535 | { | ||
536 | struct _sas_device *ret; | ||
537 | |||
538 | assert_spin_locked(&ioc->sas_device_lock); | ||
539 | |||
540 | ret = tgt_priv->sdev; | ||
541 | if (ret) | ||
542 | sas_device_get(ret); | ||
543 | |||
544 | return ret; | ||
545 | } | ||
546 | |||
547 | static struct _sas_device * | ||
548 | mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, | ||
549 | struct MPT3SAS_TARGET *tgt_priv) | ||
550 | { | ||
551 | struct _sas_device *ret; | ||
552 | unsigned long flags; | ||
553 | |||
554 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
555 | ret = __mpt3sas_get_sdev_from_target(ioc, tgt_priv); | ||
556 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
557 | |||
558 | return ret; | ||
559 | } | ||
560 | |||
561 | |||
562 | struct _sas_device * | ||
563 | __mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, | ||
564 | u64 sas_address) | ||
565 | { | ||
566 | struct _sas_device *sas_device; | ||
567 | |||
568 | assert_spin_locked(&ioc->sas_device_lock); | ||
569 | |||
570 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) | ||
571 | if (sas_device->sas_address == sas_address) | ||
572 | goto found_device; | ||
573 | |||
574 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) | ||
575 | if (sas_device->sas_address == sas_address) | ||
576 | goto found_device; | ||
577 | |||
578 | return NULL; | ||
579 | |||
580 | found_device: | ||
581 | sas_device_get(sas_device); | ||
582 | return sas_device; | ||
583 | } | ||
584 | |||
521 | /** | 585 | /** |
522 | * mpt3sas_scsih_sas_device_find_by_sas_address - sas device search | 586 | * mpt3sas_get_sdev_by_addr - sas device search |
523 | * @ioc: per adapter object | 587 | * @ioc: per adapter object |
524 | * @sas_address: sas address | 588 | * @sas_address: sas address |
525 | * Context: Calling function should acquire ioc->sas_device_lock | 589 | * Context: Calling function should acquire ioc->sas_device_lock |
@@ -528,24 +592,44 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | |||
528 | * object. | 592 | * object. |
529 | */ | 593 | */ |
530 | struct _sas_device * | 594 | struct _sas_device * |
531 | mpt3sas_scsih_sas_device_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, | 595 | mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, |
532 | u64 sas_address) | 596 | u64 sas_address) |
533 | { | 597 | { |
534 | struct _sas_device *sas_device; | 598 | struct _sas_device *sas_device; |
599 | unsigned long flags; | ||
600 | |||
601 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
602 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, | ||
603 | sas_address); | ||
604 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
605 | |||
606 | return sas_device; | ||
607 | } | ||
608 | |||
609 | static struct _sas_device * | ||
610 | __mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) | ||
611 | { | ||
612 | struct _sas_device *sas_device; | ||
613 | |||
614 | assert_spin_locked(&ioc->sas_device_lock); | ||
535 | 615 | ||
536 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) | 616 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) |
537 | if (sas_device->sas_address == sas_address) | 617 | if (sas_device->handle == handle) |
538 | return sas_device; | 618 | goto found_device; |
539 | 619 | ||
540 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) | 620 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) |
541 | if (sas_device->sas_address == sas_address) | 621 | if (sas_device->handle == handle) |
542 | return sas_device; | 622 | goto found_device; |
543 | 623 | ||
544 | return NULL; | 624 | return NULL; |
625 | |||
626 | found_device: | ||
627 | sas_device_get(sas_device); | ||
628 | return sas_device; | ||
545 | } | 629 | } |
546 | 630 | ||
547 | /** | 631 | /** |
548 | * _scsih_sas_device_find_by_handle - sas device search | 632 | * mpt3sas_get_sdev_by_handle - sas device search |
549 | * @ioc: per adapter object | 633 | * @ioc: per adapter object |
550 | * @handle: sas device handle (assigned by firmware) | 634 | * @handle: sas device handle (assigned by firmware) |
551 | * Context: Calling function should acquire ioc->sas_device_lock | 635 | * Context: Calling function should acquire ioc->sas_device_lock |
@@ -554,19 +638,16 @@ mpt3sas_scsih_sas_device_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, | |||
554 | * object. | 638 | * object. |
555 | */ | 639 | */ |
556 | static struct _sas_device * | 640 | static struct _sas_device * |
557 | _scsih_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) | 641 | mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) |
558 | { | 642 | { |
559 | struct _sas_device *sas_device; | 643 | struct _sas_device *sas_device; |
644 | unsigned long flags; | ||
560 | 645 | ||
561 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) | 646 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
562 | if (sas_device->handle == handle) | 647 | sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); |
563 | return sas_device; | 648 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
564 | |||
565 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) | ||
566 | if (sas_device->handle == handle) | ||
567 | return sas_device; | ||
568 | 649 | ||
569 | return NULL; | 650 | return sas_device; |
570 | } | 651 | } |
571 | 652 | ||
572 | /** | 653 | /** |
@@ -575,7 +656,7 @@ _scsih_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
575 | * @sas_device: the sas_device object | 656 | * @sas_device: the sas_device object |
576 | * Context: This function will acquire ioc->sas_device_lock. | 657 | * Context: This function will acquire ioc->sas_device_lock. |
577 | * | 658 | * |
578 | * Removing object and freeing associated memory from the ioc->sas_device_list. | 659 | * If sas_device is on the list, remove it and decrement its reference count. |
579 | */ | 660 | */ |
580 | static void | 661 | static void |
581 | _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc, | 662 | _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc, |
@@ -602,9 +683,15 @@ _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc, | |||
602 | ioc->name, sas_device->enclosure_level, | 683 | ioc->name, sas_device->enclosure_level, |
603 | sas_device->connector_name); | 684 | sas_device->connector_name); |
604 | 685 | ||
686 | /* | ||
687 | * The lock serializes access to the list, but we still need to verify | ||
688 | * that nobody removed the entry while we were waiting on the lock. | ||
689 | */ | ||
605 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 690 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
606 | list_del(&sas_device->list); | 691 | if (!list_empty(&sas_device->list)) { |
607 | kfree(sas_device); | 692 | list_del_init(&sas_device->list); |
693 | sas_device_put(sas_device); | ||
694 | } | ||
608 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 695 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
609 | } | 696 | } |
610 | 697 | ||
@@ -625,12 +712,16 @@ _scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
625 | return; | 712 | return; |
626 | 713 | ||
627 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 714 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
628 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 715 | sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); |
629 | if (sas_device) | 716 | if (sas_device) { |
630 | list_del(&sas_device->list); | 717 | list_del_init(&sas_device->list); |
718 | sas_device_put(sas_device); | ||
719 | } | ||
631 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 720 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
632 | if (sas_device) | 721 | if (sas_device) { |
633 | _scsih_remove_device(ioc, sas_device); | 722 | _scsih_remove_device(ioc, sas_device); |
723 | sas_device_put(sas_device); | ||
724 | } | ||
634 | } | 725 | } |
635 | 726 | ||
636 | /** | 727 | /** |
@@ -651,13 +742,16 @@ mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, | |||
651 | return; | 742 | return; |
652 | 743 | ||
653 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 744 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
654 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 745 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address); |
655 | sas_address); | 746 | if (sas_device) { |
656 | if (sas_device) | 747 | list_del_init(&sas_device->list); |
657 | list_del(&sas_device->list); | 748 | sas_device_put(sas_device); |
749 | } | ||
658 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 750 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
659 | if (sas_device) | 751 | if (sas_device) { |
660 | _scsih_remove_device(ioc, sas_device); | 752 | _scsih_remove_device(ioc, sas_device); |
753 | sas_device_put(sas_device); | ||
754 | } | ||
661 | } | 755 | } |
662 | 756 | ||
663 | /** | 757 | /** |
@@ -692,6 +786,7 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, | |||
692 | sas_device->enclosure_level, sas_device->connector_name)); | 786 | sas_device->enclosure_level, sas_device->connector_name)); |
693 | 787 | ||
694 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 788 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
789 | sas_device_get(sas_device); | ||
695 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | 790 | list_add_tail(&sas_device->list, &ioc->sas_device_list); |
696 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 791 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
697 | 792 | ||
@@ -745,6 +840,7 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc, | |||
745 | sas_device->connector_name)); | 840 | sas_device->connector_name)); |
746 | 841 | ||
747 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 842 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
843 | sas_device_get(sas_device); | ||
748 | list_add_tail(&sas_device->list, &ioc->sas_device_init_list); | 844 | list_add_tail(&sas_device->list, &ioc->sas_device_init_list); |
749 | _scsih_determine_boot_device(ioc, sas_device, 0); | 845 | _scsih_determine_boot_device(ioc, sas_device, 0); |
750 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 846 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
@@ -778,7 +874,7 @@ _scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel) | |||
778 | } | 874 | } |
779 | 875 | ||
780 | /** | 876 | /** |
781 | * _scsih_raid_device_find_by_handle - raid device search | 877 | * mpt3sas_raid_device_find_by_handle - raid device search |
782 | * @ioc: per adapter object | 878 | * @ioc: per adapter object |
783 | * @handle: sas device handle (assigned by firmware) | 879 | * @handle: sas device handle (assigned by firmware) |
784 | * Context: Calling function should acquire ioc->raid_device_lock | 880 | * Context: Calling function should acquire ioc->raid_device_lock |
@@ -786,8 +882,8 @@ _scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel) | |||
786 | * This searches for raid_device based on handle, then return raid_device | 882 | * This searches for raid_device based on handle, then return raid_device |
787 | * object. | 883 | * object. |
788 | */ | 884 | */ |
789 | static struct _raid_device * | 885 | struct _raid_device * |
790 | _scsih_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) | 886 | mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) |
791 | { | 887 | { |
792 | struct _raid_device *raid_device, *r; | 888 | struct _raid_device *raid_device, *r; |
793 | 889 | ||
@@ -1095,14 +1191,14 @@ _scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id, | |||
1095 | } | 1191 | } |
1096 | 1192 | ||
1097 | /** | 1193 | /** |
1098 | * _scsih_change_queue_depth - setting device queue depth | 1194 | * scsih_change_queue_depth - setting device queue depth |
1099 | * @sdev: scsi device struct | 1195 | * @sdev: scsi device struct |
1100 | * @qdepth: requested queue depth | 1196 | * @qdepth: requested queue depth |
1101 | * | 1197 | * |
1102 | * Returns queue depth. | 1198 | * Returns queue depth. |
1103 | */ | 1199 | */ |
1104 | static int | 1200 | int |
1105 | _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | 1201 | scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) |
1106 | { | 1202 | { |
1107 | struct Scsi_Host *shost = sdev->host; | 1203 | struct Scsi_Host *shost = sdev->host; |
1108 | int max_depth; | 1204 | int max_depth; |
@@ -1123,12 +1219,15 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | |||
1123 | goto not_sata; | 1219 | goto not_sata; |
1124 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) | 1220 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) |
1125 | goto not_sata; | 1221 | goto not_sata; |
1222 | |||
1126 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1223 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1127 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 1224 | sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data); |
1128 | sas_device_priv_data->sas_target->sas_address); | 1225 | if (sas_device) { |
1129 | if (sas_device && sas_device->device_info & | 1226 | if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) |
1130 | MPI2_SAS_DEVICE_INFO_SATA_DEVICE) | 1227 | max_depth = MPT3SAS_SATA_QUEUE_DEPTH; |
1131 | max_depth = MPT3SAS_SATA_QUEUE_DEPTH; | 1228 | |
1229 | sas_device_put(sas_device); | ||
1230 | } | ||
1132 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1231 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1133 | 1232 | ||
1134 | not_sata: | 1233 | not_sata: |
@@ -1141,14 +1240,14 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | |||
1141 | } | 1240 | } |
1142 | 1241 | ||
1143 | /** | 1242 | /** |
1144 | * _scsih_target_alloc - target add routine | 1243 | * scsih_target_alloc - target add routine |
1145 | * @starget: scsi target struct | 1244 | * @starget: scsi target struct |
1146 | * | 1245 | * |
1147 | * Returns 0 if ok. Any other return is assumed to be an error and | 1246 | * Returns 0 if ok. Any other return is assumed to be an error and |
1148 | * the device is ignored. | 1247 | * the device is ignored. |
1149 | */ | 1248 | */ |
1150 | static int | 1249 | int |
1151 | _scsih_target_alloc(struct scsi_target *starget) | 1250 | scsih_target_alloc(struct scsi_target *starget) |
1152 | { | 1251 | { |
1153 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | 1252 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); |
1154 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 1253 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -1176,7 +1275,9 @@ _scsih_target_alloc(struct scsi_target *starget) | |||
1176 | sas_target_priv_data->handle = raid_device->handle; | 1275 | sas_target_priv_data->handle = raid_device->handle; |
1177 | sas_target_priv_data->sas_address = raid_device->wwid; | 1276 | sas_target_priv_data->sas_address = raid_device->wwid; |
1178 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; | 1277 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; |
1179 | raid_device->starget = starget; | 1278 | sas_target_priv_data->raid_device = raid_device; |
1279 | if (ioc->is_warpdrive) | ||
1280 | raid_device->starget = starget; | ||
1180 | } | 1281 | } |
1181 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1282 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1182 | return 0; | 1283 | return 0; |
@@ -1185,12 +1286,13 @@ _scsih_target_alloc(struct scsi_target *starget) | |||
1185 | /* sas/sata devices */ | 1286 | /* sas/sata devices */ |
1186 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1287 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1187 | rphy = dev_to_rphy(starget->dev.parent); | 1288 | rphy = dev_to_rphy(starget->dev.parent); |
1188 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 1289 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
1189 | rphy->identify.sas_address); | 1290 | rphy->identify.sas_address); |
1190 | 1291 | ||
1191 | if (sas_device) { | 1292 | if (sas_device) { |
1192 | sas_target_priv_data->handle = sas_device->handle; | 1293 | sas_target_priv_data->handle = sas_device->handle; |
1193 | sas_target_priv_data->sas_address = sas_device->sas_address; | 1294 | sas_target_priv_data->sas_address = sas_device->sas_address; |
1295 | sas_target_priv_data->sdev = sas_device; | ||
1194 | sas_device->starget = starget; | 1296 | sas_device->starget = starget; |
1195 | sas_device->id = starget->id; | 1297 | sas_device->id = starget->id; |
1196 | sas_device->channel = starget->channel; | 1298 | sas_device->channel = starget->channel; |
@@ -1206,13 +1308,13 @@ _scsih_target_alloc(struct scsi_target *starget) | |||
1206 | } | 1308 | } |
1207 | 1309 | ||
1208 | /** | 1310 | /** |
1209 | * _scsih_target_destroy - target destroy routine | 1311 | * scsih_target_destroy - target destroy routine |
1210 | * @starget: scsi target struct | 1312 | * @starget: scsi target struct |
1211 | * | 1313 | * |
1212 | * Returns nothing. | 1314 | * Returns nothing. |
1213 | */ | 1315 | */ |
1214 | static void | 1316 | void |
1215 | _scsih_target_destroy(struct scsi_target *starget) | 1317 | scsih_target_destroy(struct scsi_target *starget) |
1216 | { | 1318 | { |
1217 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | 1319 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); |
1218 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 1320 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -1240,13 +1342,21 @@ _scsih_target_destroy(struct scsi_target *starget) | |||
1240 | 1342 | ||
1241 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1343 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1242 | rphy = dev_to_rphy(starget->dev.parent); | 1344 | rphy = dev_to_rphy(starget->dev.parent); |
1243 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 1345 | sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data); |
1244 | rphy->identify.sas_address); | ||
1245 | if (sas_device && (sas_device->starget == starget) && | 1346 | if (sas_device && (sas_device->starget == starget) && |
1246 | (sas_device->id == starget->id) && | 1347 | (sas_device->id == starget->id) && |
1247 | (sas_device->channel == starget->channel)) | 1348 | (sas_device->channel == starget->channel)) |
1248 | sas_device->starget = NULL; | 1349 | sas_device->starget = NULL; |
1249 | 1350 | ||
1351 | if (sas_device) { | ||
1352 | /* | ||
1353 | * Corresponding get() is in _scsih_target_alloc() | ||
1354 | */ | ||
1355 | sas_target_priv_data->sdev = NULL; | ||
1356 | sas_device_put(sas_device); | ||
1357 | |||
1358 | sas_device_put(sas_device); | ||
1359 | } | ||
1250 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1360 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1251 | 1361 | ||
1252 | out: | 1362 | out: |
@@ -1255,14 +1365,14 @@ _scsih_target_destroy(struct scsi_target *starget) | |||
1255 | } | 1365 | } |
1256 | 1366 | ||
1257 | /** | 1367 | /** |
1258 | * _scsih_slave_alloc - device add routine | 1368 | * scsih_slave_alloc - device add routine |
1259 | * @sdev: scsi device struct | 1369 | * @sdev: scsi device struct |
1260 | * | 1370 | * |
1261 | * Returns 0 if ok. Any other return is assumed to be an error and | 1371 | * Returns 0 if ok. Any other return is assumed to be an error and |
1262 | * the device is ignored. | 1372 | * the device is ignored. |
1263 | */ | 1373 | */ |
1264 | static int | 1374 | int |
1265 | _scsih_slave_alloc(struct scsi_device *sdev) | 1375 | scsih_slave_alloc(struct scsi_device *sdev) |
1266 | { | 1376 | { |
1267 | struct Scsi_Host *shost; | 1377 | struct Scsi_Host *shost; |
1268 | struct MPT3SAS_ADAPTER *ioc; | 1378 | struct MPT3SAS_ADAPTER *ioc; |
@@ -1302,14 +1412,18 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1302 | 1412 | ||
1303 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | 1413 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { |
1304 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1414 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1305 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 1415 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
1306 | sas_target_priv_data->sas_address); | 1416 | sas_target_priv_data->sas_address); |
1307 | if (sas_device && (sas_device->starget == NULL)) { | 1417 | if (sas_device && (sas_device->starget == NULL)) { |
1308 | sdev_printk(KERN_INFO, sdev, | 1418 | sdev_printk(KERN_INFO, sdev, |
1309 | "%s : sas_device->starget set to starget @ %d\n", | 1419 | "%s : sas_device->starget set to starget @ %d\n", |
1310 | __func__, __LINE__); | 1420 | __func__, __LINE__); |
1311 | sas_device->starget = starget; | 1421 | sas_device->starget = starget; |
1312 | } | 1422 | } |
1423 | |||
1424 | if (sas_device) | ||
1425 | sas_device_put(sas_device); | ||
1426 | |||
1313 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1427 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1314 | } | 1428 | } |
1315 | 1429 | ||
@@ -1317,13 +1431,13 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1317 | } | 1431 | } |
1318 | 1432 | ||
1319 | /** | 1433 | /** |
1320 | * _scsih_slave_destroy - device destroy routine | 1434 | * scsih_slave_destroy - device destroy routine |
1321 | * @sdev: scsi device struct | 1435 | * @sdev: scsi device struct |
1322 | * | 1436 | * |
1323 | * Returns nothing. | 1437 | * Returns nothing. |
1324 | */ | 1438 | */ |
1325 | static void | 1439 | void |
1326 | _scsih_slave_destroy(struct scsi_device *sdev) | 1440 | scsih_slave_destroy(struct scsi_device *sdev) |
1327 | { | 1441 | { |
1328 | struct MPT3SAS_TARGET *sas_target_priv_data; | 1442 | struct MPT3SAS_TARGET *sas_target_priv_data; |
1329 | struct scsi_target *starget; | 1443 | struct scsi_target *starget; |
@@ -1344,10 +1458,13 @@ _scsih_slave_destroy(struct scsi_device *sdev) | |||
1344 | 1458 | ||
1345 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | 1459 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { |
1346 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1460 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1347 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 1461 | sas_device = __mpt3sas_get_sdev_from_target(ioc, |
1348 | sas_target_priv_data->sas_address); | 1462 | sas_target_priv_data); |
1349 | if (sas_device && !sas_target_priv_data->num_luns) | 1463 | if (sas_device && !sas_target_priv_data->num_luns) |
1350 | sas_device->starget = NULL; | 1464 | sas_device->starget = NULL; |
1465 | |||
1466 | if (sas_device) | ||
1467 | sas_device_put(sas_device); | ||
1351 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1468 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1352 | } | 1469 | } |
1353 | 1470 | ||
@@ -1409,23 +1526,26 @@ _scsih_display_sata_capabilities(struct MPT3SAS_ADAPTER *ioc, | |||
1409 | */ | 1526 | */ |
1410 | 1527 | ||
1411 | /** | 1528 | /** |
1412 | * _scsih_is_raid - return boolean indicating device is raid volume | 1529 | * scsih_is_raid - return boolean indicating device is raid volume |
1413 | * @dev the device struct object | 1530 | * @dev the device struct object |
1414 | */ | 1531 | */ |
1415 | static int | 1532 | int |
1416 | _scsih_is_raid(struct device *dev) | 1533 | scsih_is_raid(struct device *dev) |
1417 | { | 1534 | { |
1418 | struct scsi_device *sdev = to_scsi_device(dev); | 1535 | struct scsi_device *sdev = to_scsi_device(dev); |
1536 | struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
1419 | 1537 | ||
1538 | if (ioc->is_warpdrive) | ||
1539 | return 0; | ||
1420 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; | 1540 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; |
1421 | } | 1541 | } |
1422 | 1542 | ||
1423 | /** | 1543 | /** |
1424 | * _scsih_get_resync - get raid volume resync percent complete | 1544 | * scsih_get_resync - get raid volume resync percent complete |
1425 | * @dev the device struct object | 1545 | * @dev the device struct object |
1426 | */ | 1546 | */ |
1427 | static void | 1547 | void |
1428 | _scsih_get_resync(struct device *dev) | 1548 | scsih_get_resync(struct device *dev) |
1429 | { | 1549 | { |
1430 | struct scsi_device *sdev = to_scsi_device(dev); | 1550 | struct scsi_device *sdev = to_scsi_device(dev); |
1431 | struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); | 1551 | struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); |
@@ -1439,6 +1559,9 @@ _scsih_get_resync(struct device *dev) | |||
1439 | 1559 | ||
1440 | percent_complete = 0; | 1560 | percent_complete = 0; |
1441 | handle = 0; | 1561 | handle = 0; |
1562 | if (ioc->is_warpdrive) | ||
1563 | goto out; | ||
1564 | |||
1442 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 1565 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
1443 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, | 1566 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, |
1444 | sdev->channel); | 1567 | sdev->channel); |
@@ -1466,15 +1589,18 @@ _scsih_get_resync(struct device *dev) | |||
1466 | percent_complete = 0; | 1589 | percent_complete = 0; |
1467 | 1590 | ||
1468 | out: | 1591 | out: |
1469 | raid_set_resync(mpt3sas_raid_template, dev, percent_complete); | 1592 | if (ioc->hba_mpi_version_belonged == MPI2_VERSION) |
1593 | raid_set_resync(mpt2sas_raid_template, dev, percent_complete); | ||
1594 | if (ioc->hba_mpi_version_belonged == MPI25_VERSION) | ||
1595 | raid_set_resync(mpt3sas_raid_template, dev, percent_complete); | ||
1470 | } | 1596 | } |
1471 | 1597 | ||
1472 | /** | 1598 | /** |
1473 | * _scsih_get_state - get raid volume level | 1599 | * scsih_get_state - get raid volume level |
1474 | * @dev the device struct object | 1600 | * @dev the device struct object |
1475 | */ | 1601 | */ |
1476 | static void | 1602 | void |
1477 | _scsih_get_state(struct device *dev) | 1603 | scsih_get_state(struct device *dev) |
1478 | { | 1604 | { |
1479 | struct scsi_device *sdev = to_scsi_device(dev); | 1605 | struct scsi_device *sdev = to_scsi_device(dev); |
1480 | struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); | 1606 | struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); |
@@ -1524,7 +1650,10 @@ _scsih_get_state(struct device *dev) | |||
1524 | break; | 1650 | break; |
1525 | } | 1651 | } |
1526 | out: | 1652 | out: |
1527 | raid_set_state(mpt3sas_raid_template, dev, state); | 1653 | if (ioc->hba_mpi_version_belonged == MPI2_VERSION) |
1654 | raid_set_state(mpt2sas_raid_template, dev, state); | ||
1655 | if (ioc->hba_mpi_version_belonged == MPI25_VERSION) | ||
1656 | raid_set_state(mpt3sas_raid_template, dev, state); | ||
1528 | } | 1657 | } |
1529 | 1658 | ||
1530 | /** | 1659 | /** |
@@ -1533,7 +1662,8 @@ _scsih_get_state(struct device *dev) | |||
1533 | * @volume_type: volume type | 1662 | * @volume_type: volume type |
1534 | */ | 1663 | */ |
1535 | static void | 1664 | static void |
1536 | _scsih_set_level(struct scsi_device *sdev, u8 volume_type) | 1665 | _scsih_set_level(struct MPT3SAS_ADAPTER *ioc, |
1666 | struct scsi_device *sdev, u8 volume_type) | ||
1537 | { | 1667 | { |
1538 | enum raid_level level = RAID_LEVEL_UNKNOWN; | 1668 | enum raid_level level = RAID_LEVEL_UNKNOWN; |
1539 | 1669 | ||
@@ -1552,7 +1682,12 @@ _scsih_set_level(struct scsi_device *sdev, u8 volume_type) | |||
1552 | break; | 1682 | break; |
1553 | } | 1683 | } |
1554 | 1684 | ||
1555 | raid_set_level(mpt3sas_raid_template, &sdev->sdev_gendev, level); | 1685 | if (ioc->hba_mpi_version_belonged == MPI2_VERSION) |
1686 | raid_set_level(mpt2sas_raid_template, | ||
1687 | &sdev->sdev_gendev, level); | ||
1688 | if (ioc->hba_mpi_version_belonged == MPI25_VERSION) | ||
1689 | raid_set_level(mpt3sas_raid_template, | ||
1690 | &sdev->sdev_gendev, level); | ||
1556 | } | 1691 | } |
1557 | 1692 | ||
1558 | 1693 | ||
@@ -1622,8 +1757,6 @@ _scsih_get_volume_capabilities(struct MPT3SAS_ADAPTER *ioc, | |||
1622 | return 0; | 1757 | return 0; |
1623 | } | 1758 | } |
1624 | 1759 | ||
1625 | |||
1626 | |||
1627 | /** | 1760 | /** |
1628 | * _scsih_enable_tlr - setting TLR flags | 1761 | * _scsih_enable_tlr - setting TLR flags |
1629 | * @ioc: per adapter object | 1762 | * @ioc: per adapter object |
@@ -1652,14 +1785,14 @@ _scsih_enable_tlr(struct MPT3SAS_ADAPTER *ioc, struct scsi_device *sdev) | |||
1652 | } | 1785 | } |
1653 | 1786 | ||
1654 | /** | 1787 | /** |
1655 | * _scsih_slave_configure - device configure routine. | 1788 | * scsih_slave_configure - device configure routine. |
1656 | * @sdev: scsi device struct | 1789 | * @sdev: scsi device struct |
1657 | * | 1790 | * |
1658 | * Returns 0 if ok. Any other return is assumed to be an error and | 1791 | * Returns 0 if ok. Any other return is assumed to be an error and |
1659 | * the device is ignored. | 1792 | * the device is ignored. |
1660 | */ | 1793 | */ |
1661 | static int | 1794 | int |
1662 | _scsih_slave_configure(struct scsi_device *sdev) | 1795 | scsih_slave_configure(struct scsi_device *sdev) |
1663 | { | 1796 | { |
1664 | struct Scsi_Host *shost = sdev->host; | 1797 | struct Scsi_Host *shost = sdev->host; |
1665 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 1798 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -1686,7 +1819,7 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1686 | if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) { | 1819 | if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) { |
1687 | 1820 | ||
1688 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 1821 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
1689 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 1822 | raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle); |
1690 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1823 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1691 | if (!raid_device) { | 1824 | if (!raid_device) { |
1692 | dfailprintk(ioc, pr_warn(MPT3SAS_FMT | 1825 | dfailprintk(ioc, pr_warn(MPT3SAS_FMT |
@@ -1702,6 +1835,10 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1702 | return 1; | 1835 | return 1; |
1703 | } | 1836 | } |
1704 | 1837 | ||
1838 | /* | ||
1839 | * WARPDRIVE: Initialize the required data for Direct IO | ||
1840 | */ | ||
1841 | mpt3sas_init_warpdrive_properties(ioc, raid_device); | ||
1705 | 1842 | ||
1706 | /* RAID Queue Depth Support | 1843 | /* RAID Queue Depth Support |
1707 | * IS volume = underlying qdepth of drive type, either | 1844 | * IS volume = underlying qdepth of drive type, either |
@@ -1750,17 +1887,19 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1750 | break; | 1887 | break; |
1751 | } | 1888 | } |
1752 | 1889 | ||
1753 | sdev_printk(KERN_INFO, sdev, | 1890 | if (!ioc->hide_ir_msg) |
1754 | "%s: handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n", | 1891 | sdev_printk(KERN_INFO, sdev, |
1755 | r_level, raid_device->handle, | 1892 | "%s: handle(0x%04x), wwid(0x%016llx)," |
1756 | (unsigned long long)raid_device->wwid, | 1893 | " pd_count(%d), type(%s)\n", |
1757 | raid_device->num_pds, ds); | 1894 | r_level, raid_device->handle, |
1758 | 1895 | (unsigned long long)raid_device->wwid, | |
1896 | raid_device->num_pds, ds); | ||
1759 | 1897 | ||
1760 | _scsih_change_queue_depth(sdev, qdepth); | 1898 | scsih_change_queue_depth(sdev, qdepth); |
1761 | 1899 | ||
1762 | /* raid transport support */ | 1900 | /* raid transport support */ |
1763 | _scsih_set_level(sdev, raid_device->volume_type); | 1901 | if (!ioc->is_warpdrive) |
1902 | _scsih_set_level(ioc, sdev, raid_device->volume_type); | ||
1764 | return 0; | 1903 | return 0; |
1765 | } | 1904 | } |
1766 | 1905 | ||
@@ -1783,7 +1922,7 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1783 | } | 1922 | } |
1784 | 1923 | ||
1785 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1924 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1786 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 1925 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
1787 | sas_device_priv_data->sas_target->sas_address); | 1926 | sas_device_priv_data->sas_target->sas_address); |
1788 | if (!sas_device) { | 1927 | if (!sas_device) { |
1789 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1928 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
@@ -1823,13 +1962,14 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1823 | ds, sas_device->enclosure_level, | 1962 | ds, sas_device->enclosure_level, |
1824 | sas_device->connector_name); | 1963 | sas_device->connector_name); |
1825 | 1964 | ||
1965 | sas_device_put(sas_device); | ||
1826 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1966 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1827 | 1967 | ||
1828 | if (!ssp_target) | 1968 | if (!ssp_target) |
1829 | _scsih_display_sata_capabilities(ioc, handle, sdev); | 1969 | _scsih_display_sata_capabilities(ioc, handle, sdev); |
1830 | 1970 | ||
1831 | 1971 | ||
1832 | _scsih_change_queue_depth(sdev, qdepth); | 1972 | scsih_change_queue_depth(sdev, qdepth); |
1833 | 1973 | ||
1834 | if (ssp_target) { | 1974 | if (ssp_target) { |
1835 | sas_read_port_mode_page(sdev); | 1975 | sas_read_port_mode_page(sdev); |
@@ -1840,7 +1980,7 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1840 | } | 1980 | } |
1841 | 1981 | ||
1842 | /** | 1982 | /** |
1843 | * _scsih_bios_param - fetch head, sector, cylinder info for a disk | 1983 | * scsih_bios_param - fetch head, sector, cylinder info for a disk |
1844 | * @sdev: scsi device struct | 1984 | * @sdev: scsi device struct |
1845 | * @bdev: pointer to block device context | 1985 | * @bdev: pointer to block device context |
1846 | * @capacity: device size (in 512 byte sectors) | 1986 | * @capacity: device size (in 512 byte sectors) |
@@ -1851,8 +1991,8 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1851 | * | 1991 | * |
1852 | * Return nothing. | 1992 | * Return nothing. |
1853 | */ | 1993 | */ |
1854 | static int | 1994 | int |
1855 | _scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev, | 1995 | scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev, |
1856 | sector_t capacity, int params[]) | 1996 | sector_t capacity, int params[]) |
1857 | { | 1997 | { |
1858 | int heads; | 1998 | int heads; |
@@ -2209,7 +2349,10 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2209 | 2349 | ||
2210 | if (!priv_target) | 2350 | if (!priv_target) |
2211 | return; | 2351 | return; |
2212 | device_str = "volume"; | 2352 | if (ioc->hide_ir_msg) |
2353 | device_str = "WarpDrive"; | ||
2354 | else | ||
2355 | device_str = "volume"; | ||
2213 | 2356 | ||
2214 | scsi_print_command(scmd); | 2357 | scsi_print_command(scmd); |
2215 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { | 2358 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { |
@@ -2219,8 +2362,7 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2219 | device_str, (unsigned long long)priv_target->sas_address); | 2362 | device_str, (unsigned long long)priv_target->sas_address); |
2220 | } else { | 2363 | } else { |
2221 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2364 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2222 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 2365 | sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target); |
2223 | priv_target->sas_address); | ||
2224 | if (sas_device) { | 2366 | if (sas_device) { |
2225 | if (priv_target->flags & | 2367 | if (priv_target->flags & |
2226 | MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2368 | MPT_TARGET_FLAGS_RAID_COMPONENT) { |
@@ -2246,19 +2388,21 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2246 | "enclosure level(0x%04x),connector name(%s)\n", | 2388 | "enclosure level(0x%04x),connector name(%s)\n", |
2247 | sas_device->enclosure_level, | 2389 | sas_device->enclosure_level, |
2248 | sas_device->connector_name); | 2390 | sas_device->connector_name); |
2391 | |||
2392 | sas_device_put(sas_device); | ||
2249 | } | 2393 | } |
2250 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2394 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2251 | } | 2395 | } |
2252 | } | 2396 | } |
2253 | 2397 | ||
2254 | /** | 2398 | /** |
2255 | * _scsih_abort - eh threads main abort routine | 2399 | * scsih_abort - eh threads main abort routine |
2256 | * @scmd: pointer to scsi command object | 2400 | * @scmd: pointer to scsi command object |
2257 | * | 2401 | * |
2258 | * Returns SUCCESS if command aborted else FAILED | 2402 | * Returns SUCCESS if command aborted else FAILED |
2259 | */ | 2403 | */ |
2260 | static int | 2404 | int |
2261 | _scsih_abort(struct scsi_cmnd *scmd) | 2405 | scsih_abort(struct scsi_cmnd *scmd) |
2262 | { | 2406 | { |
2263 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 2407 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
2264 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 2408 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
@@ -2311,21 +2455,23 @@ _scsih_abort(struct scsi_cmnd *scmd) | |||
2311 | } | 2455 | } |
2312 | 2456 | ||
2313 | /** | 2457 | /** |
2314 | * _scsih_dev_reset - eh threads main device reset routine | 2458 | * scsih_dev_reset - eh threads main device reset routine |
2315 | * @scmd: pointer to scsi command object | 2459 | * @scmd: pointer to scsi command object |
2316 | * | 2460 | * |
2317 | * Returns SUCCESS if command aborted else FAILED | 2461 | * Returns SUCCESS if command aborted else FAILED |
2318 | */ | 2462 | */ |
2319 | static int | 2463 | int |
2320 | _scsih_dev_reset(struct scsi_cmnd *scmd) | 2464 | scsih_dev_reset(struct scsi_cmnd *scmd) |
2321 | { | 2465 | { |
2322 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 2466 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
2323 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 2467 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
2324 | struct _sas_device *sas_device; | 2468 | struct _sas_device *sas_device = NULL; |
2325 | unsigned long flags; | ||
2326 | u16 handle; | 2469 | u16 handle; |
2327 | int r; | 2470 | int r; |
2328 | 2471 | ||
2472 | struct scsi_target *starget = scmd->device->sdev_target; | ||
2473 | struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; | ||
2474 | |||
2329 | sdev_printk(KERN_INFO, scmd->device, | 2475 | sdev_printk(KERN_INFO, scmd->device, |
2330 | "attempting device reset! scmd(%p)\n", scmd); | 2476 | "attempting device reset! scmd(%p)\n", scmd); |
2331 | _scsih_tm_display_info(ioc, scmd); | 2477 | _scsih_tm_display_info(ioc, scmd); |
@@ -2344,12 +2490,10 @@ _scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2344 | handle = 0; | 2490 | handle = 0; |
2345 | if (sas_device_priv_data->sas_target->flags & | 2491 | if (sas_device_priv_data->sas_target->flags & |
2346 | MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2492 | MPT_TARGET_FLAGS_RAID_COMPONENT) { |
2347 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2493 | sas_device = mpt3sas_get_sdev_from_target(ioc, |
2348 | sas_device = _scsih_sas_device_find_by_handle(ioc, | 2494 | target_priv_data); |
2349 | sas_device_priv_data->sas_target->handle); | ||
2350 | if (sas_device) | 2495 | if (sas_device) |
2351 | handle = sas_device->volume_handle; | 2496 | handle = sas_device->volume_handle; |
2352 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2353 | } else | 2497 | } else |
2354 | handle = sas_device_priv_data->sas_target->handle; | 2498 | handle = sas_device_priv_data->sas_target->handle; |
2355 | 2499 | ||
@@ -2366,25 +2510,29 @@ _scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2366 | out: | 2510 | out: |
2367 | sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", | 2511 | sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", |
2368 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); | 2512 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); |
2513 | |||
2514 | if (sas_device) | ||
2515 | sas_device_put(sas_device); | ||
2516 | |||
2369 | return r; | 2517 | return r; |
2370 | } | 2518 | } |
2371 | 2519 | ||
2372 | /** | 2520 | /** |
2373 | * _scsih_target_reset - eh threads main target reset routine | 2521 | * scsih_target_reset - eh threads main target reset routine |
2374 | * @scmd: pointer to scsi command object | 2522 | * @scmd: pointer to scsi command object |
2375 | * | 2523 | * |
2376 | * Returns SUCCESS if command aborted else FAILED | 2524 | * Returns SUCCESS if command aborted else FAILED |
2377 | */ | 2525 | */ |
2378 | static int | 2526 | int |
2379 | _scsih_target_reset(struct scsi_cmnd *scmd) | 2527 | scsih_target_reset(struct scsi_cmnd *scmd) |
2380 | { | 2528 | { |
2381 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 2529 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
2382 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 2530 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
2383 | struct _sas_device *sas_device; | 2531 | struct _sas_device *sas_device = NULL; |
2384 | unsigned long flags; | ||
2385 | u16 handle; | 2532 | u16 handle; |
2386 | int r; | 2533 | int r; |
2387 | struct scsi_target *starget = scmd->device->sdev_target; | 2534 | struct scsi_target *starget = scmd->device->sdev_target; |
2535 | struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; | ||
2388 | 2536 | ||
2389 | starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n", | 2537 | starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n", |
2390 | scmd); | 2538 | scmd); |
@@ -2404,12 +2552,10 @@ _scsih_target_reset(struct scsi_cmnd *scmd) | |||
2404 | handle = 0; | 2552 | handle = 0; |
2405 | if (sas_device_priv_data->sas_target->flags & | 2553 | if (sas_device_priv_data->sas_target->flags & |
2406 | MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2554 | MPT_TARGET_FLAGS_RAID_COMPONENT) { |
2407 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2555 | sas_device = mpt3sas_get_sdev_from_target(ioc, |
2408 | sas_device = _scsih_sas_device_find_by_handle(ioc, | 2556 | target_priv_data); |
2409 | sas_device_priv_data->sas_target->handle); | ||
2410 | if (sas_device) | 2557 | if (sas_device) |
2411 | handle = sas_device->volume_handle; | 2558 | handle = sas_device->volume_handle; |
2412 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2413 | } else | 2559 | } else |
2414 | handle = sas_device_priv_data->sas_target->handle; | 2560 | handle = sas_device_priv_data->sas_target->handle; |
2415 | 2561 | ||
@@ -2426,18 +2572,22 @@ _scsih_target_reset(struct scsi_cmnd *scmd) | |||
2426 | out: | 2572 | out: |
2427 | starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", | 2573 | starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", |
2428 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); | 2574 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); |
2575 | |||
2576 | if (sas_device) | ||
2577 | sas_device_put(sas_device); | ||
2578 | |||
2429 | return r; | 2579 | return r; |
2430 | } | 2580 | } |
2431 | 2581 | ||
2432 | 2582 | ||
2433 | /** | 2583 | /** |
2434 | * _scsih_host_reset - eh threads main host reset routine | 2584 | * scsih_host_reset - eh threads main host reset routine |
2435 | * @scmd: pointer to scsi command object | 2585 | * @scmd: pointer to scsi command object |
2436 | * | 2586 | * |
2437 | * Returns SUCCESS if command aborted else FAILED | 2587 | * Returns SUCCESS if command aborted else FAILED |
2438 | */ | 2588 | */ |
2439 | static int | 2589 | int |
2440 | _scsih_host_reset(struct scsi_cmnd *scmd) | 2590 | scsih_host_reset(struct scsi_cmnd *scmd) |
2441 | { | 2591 | { |
2442 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 2592 | struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
2443 | int r, retval; | 2593 | int r, retval; |
@@ -2483,32 +2633,36 @@ _scsih_fw_event_add(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) | |||
2483 | return; | 2633 | return; |
2484 | 2634 | ||
2485 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 2635 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
2636 | fw_event_work_get(fw_event); | ||
2486 | INIT_LIST_HEAD(&fw_event->list); | 2637 | INIT_LIST_HEAD(&fw_event->list); |
2487 | list_add_tail(&fw_event->list, &ioc->fw_event_list); | 2638 | list_add_tail(&fw_event->list, &ioc->fw_event_list); |
2488 | INIT_WORK(&fw_event->work, _firmware_event_work); | 2639 | INIT_WORK(&fw_event->work, _firmware_event_work); |
2640 | fw_event_work_get(fw_event); | ||
2489 | queue_work(ioc->firmware_event_thread, &fw_event->work); | 2641 | queue_work(ioc->firmware_event_thread, &fw_event->work); |
2490 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 2642 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
2491 | } | 2643 | } |
2492 | 2644 | ||
2493 | /** | 2645 | /** |
2494 | * _scsih_fw_event_free - delete fw_event | 2646 | * _scsih_fw_event_del_from_list - delete fw_event from the list |
2495 | * @ioc: per adapter object | 2647 | * @ioc: per adapter object |
2496 | * @fw_event: object describing the event | 2648 | * @fw_event: object describing the event |
2497 | * Context: This function will acquire ioc->fw_event_lock. | 2649 | * Context: This function will acquire ioc->fw_event_lock. |
2498 | * | 2650 | * |
2499 | * This removes firmware event object from link list, frees associated memory. | 2651 | * If the fw_event is on the fw_event_list, remove it and do a put. |
2500 | * | 2652 | * |
2501 | * Return nothing. | 2653 | * Return nothing. |
2502 | */ | 2654 | */ |
2503 | static void | 2655 | static void |
2504 | _scsih_fw_event_free(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work | 2656 | _scsih_fw_event_del_from_list(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work |
2505 | *fw_event) | 2657 | *fw_event) |
2506 | { | 2658 | { |
2507 | unsigned long flags; | 2659 | unsigned long flags; |
2508 | 2660 | ||
2509 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 2661 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
2510 | list_del(&fw_event->list); | 2662 | if (!list_empty(&fw_event->list)) { |
2511 | kfree(fw_event); | 2663 | list_del_init(&fw_event->list); |
2664 | fw_event_work_put(fw_event); | ||
2665 | } | ||
2512 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 2666 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
2513 | } | 2667 | } |
2514 | 2668 | ||
@@ -2525,17 +2679,19 @@ mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, | |||
2525 | struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) | 2679 | struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) |
2526 | { | 2680 | { |
2527 | struct fw_event_work *fw_event; | 2681 | struct fw_event_work *fw_event; |
2682 | u16 sz; | ||
2528 | 2683 | ||
2529 | if (ioc->is_driver_loading) | 2684 | if (ioc->is_driver_loading) |
2530 | return; | 2685 | return; |
2531 | fw_event = kzalloc(sizeof(*fw_event) + sizeof(*event_data), | 2686 | sz = sizeof(*event_data); |
2532 | GFP_ATOMIC); | 2687 | fw_event = alloc_fw_event_work(sz); |
2533 | if (!fw_event) | 2688 | if (!fw_event) |
2534 | return; | 2689 | return; |
2535 | fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG; | 2690 | fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG; |
2536 | fw_event->ioc = ioc; | 2691 | fw_event->ioc = ioc; |
2537 | memcpy(fw_event->event_data, event_data, sizeof(*event_data)); | 2692 | memcpy(fw_event->event_data, event_data, sizeof(*event_data)); |
2538 | _scsih_fw_event_add(ioc, fw_event); | 2693 | _scsih_fw_event_add(ioc, fw_event); |
2694 | fw_event_work_put(fw_event); | ||
2539 | } | 2695 | } |
2540 | 2696 | ||
2541 | /** | 2697 | /** |
@@ -2551,12 +2707,13 @@ _scsih_error_recovery_delete_devices(struct MPT3SAS_ADAPTER *ioc) | |||
2551 | 2707 | ||
2552 | if (ioc->is_driver_loading) | 2708 | if (ioc->is_driver_loading) |
2553 | return; | 2709 | return; |
2554 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 2710 | fw_event = alloc_fw_event_work(0); |
2555 | if (!fw_event) | 2711 | if (!fw_event) |
2556 | return; | 2712 | return; |
2557 | fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES; | 2713 | fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES; |
2558 | fw_event->ioc = ioc; | 2714 | fw_event->ioc = ioc; |
2559 | _scsih_fw_event_add(ioc, fw_event); | 2715 | _scsih_fw_event_add(ioc, fw_event); |
2716 | fw_event_work_put(fw_event); | ||
2560 | } | 2717 | } |
2561 | 2718 | ||
2562 | /** | 2719 | /** |
@@ -2570,12 +2727,29 @@ mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc) | |||
2570 | { | 2727 | { |
2571 | struct fw_event_work *fw_event; | 2728 | struct fw_event_work *fw_event; |
2572 | 2729 | ||
2573 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 2730 | fw_event = alloc_fw_event_work(0); |
2574 | if (!fw_event) | 2731 | if (!fw_event) |
2575 | return; | 2732 | return; |
2576 | fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE; | 2733 | fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE; |
2577 | fw_event->ioc = ioc; | 2734 | fw_event->ioc = ioc; |
2578 | _scsih_fw_event_add(ioc, fw_event); | 2735 | _scsih_fw_event_add(ioc, fw_event); |
2736 | fw_event_work_put(fw_event); | ||
2737 | } | ||
2738 | |||
2739 | static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc) | ||
2740 | { | ||
2741 | unsigned long flags; | ||
2742 | struct fw_event_work *fw_event = NULL; | ||
2743 | |||
2744 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | ||
2745 | if (!list_empty(&ioc->fw_event_list)) { | ||
2746 | fw_event = list_first_entry(&ioc->fw_event_list, | ||
2747 | struct fw_event_work, list); | ||
2748 | list_del_init(&fw_event->list); | ||
2749 | } | ||
2750 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | ||
2751 | |||
2752 | return fw_event; | ||
2579 | } | 2753 | } |
2580 | 2754 | ||
2581 | /** | 2755 | /** |
@@ -2590,17 +2764,25 @@ mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc) | |||
2590 | static void | 2764 | static void |
2591 | _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) | 2765 | _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) |
2592 | { | 2766 | { |
2593 | struct fw_event_work *fw_event, *next; | 2767 | struct fw_event_work *fw_event; |
2594 | 2768 | ||
2595 | if (list_empty(&ioc->fw_event_list) || | 2769 | if (list_empty(&ioc->fw_event_list) || |
2596 | !ioc->firmware_event_thread || in_interrupt()) | 2770 | !ioc->firmware_event_thread || in_interrupt()) |
2597 | return; | 2771 | return; |
2598 | 2772 | ||
2599 | list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) { | 2773 | while ((fw_event = dequeue_next_fw_event(ioc))) { |
2600 | if (cancel_delayed_work_sync(&fw_event->delayed_work)) { | 2774 | /* |
2601 | _scsih_fw_event_free(ioc, fw_event); | 2775 | * Wait on the fw_event to complete. If this returns 1, then |
2602 | continue; | 2776 | * the event was never executed, and we need a put for the |
2603 | } | 2777 | * reference the delayed_work had on the fw_event. |
2778 | * | ||
2779 | * If it did execute, we wait for it to finish, and the put will | ||
2780 | * happen from _firmware_event_work() | ||
2781 | */ | ||
2782 | if (cancel_delayed_work_sync(&fw_event->delayed_work)) | ||
2783 | fw_event_work_put(fw_event); | ||
2784 | |||
2785 | fw_event_work_put(fw_event); | ||
2604 | } | 2786 | } |
2605 | } | 2787 | } |
2606 | 2788 | ||
@@ -2763,7 +2945,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2763 | struct scsi_device *sdev; | 2945 | struct scsi_device *sdev; |
2764 | struct _sas_device *sas_device; | 2946 | struct _sas_device *sas_device; |
2765 | 2947 | ||
2766 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 2948 | sas_device = mpt3sas_get_sdev_by_handle(ioc, handle); |
2767 | if (!sas_device) | 2949 | if (!sas_device) |
2768 | return; | 2950 | return; |
2769 | 2951 | ||
@@ -2779,6 +2961,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2779 | continue; | 2961 | continue; |
2780 | _scsih_internal_device_block(sdev, sas_device_priv_data); | 2962 | _scsih_internal_device_block(sdev, sas_device_priv_data); |
2781 | } | 2963 | } |
2964 | |||
2965 | sas_device_put(sas_device); | ||
2782 | } | 2966 | } |
2783 | 2967 | ||
2784 | /** | 2968 | /** |
@@ -2807,12 +2991,13 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc, | |||
2807 | if (mpt3sas_port->remote_identify.device_type == | 2991 | if (mpt3sas_port->remote_identify.device_type == |
2808 | SAS_END_DEVICE) { | 2992 | SAS_END_DEVICE) { |
2809 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2993 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2810 | sas_device = | 2994 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
2811 | mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 2995 | mpt3sas_port->remote_identify.sas_address); |
2812 | mpt3sas_port->remote_identify.sas_address); | 2996 | if (sas_device) { |
2813 | if (sas_device) | ||
2814 | set_bit(sas_device->handle, | 2997 | set_bit(sas_device->handle, |
2815 | ioc->blocking_handles); | 2998 | ioc->blocking_handles); |
2999 | sas_device_put(sas_device); | ||
3000 | } | ||
2816 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 3001 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2817 | } | 3002 | } |
2818 | } | 3003 | } |
@@ -2880,7 +3065,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2880 | { | 3065 | { |
2881 | Mpi2SCSITaskManagementRequest_t *mpi_request; | 3066 | Mpi2SCSITaskManagementRequest_t *mpi_request; |
2882 | u16 smid; | 3067 | u16 smid; |
2883 | struct _sas_device *sas_device; | 3068 | struct _sas_device *sas_device = NULL; |
2884 | struct MPT3SAS_TARGET *sas_target_priv_data = NULL; | 3069 | struct MPT3SAS_TARGET *sas_target_priv_data = NULL; |
2885 | u64 sas_address = 0; | 3070 | u64 sas_address = 0; |
2886 | unsigned long flags; | 3071 | unsigned long flags; |
@@ -2913,7 +3098,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2913 | return; | 3098 | return; |
2914 | 3099 | ||
2915 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 3100 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2916 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 3101 | sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); |
2917 | if (sas_device && sas_device->starget && | 3102 | if (sas_device && sas_device->starget && |
2918 | sas_device->starget->hostdata) { | 3103 | sas_device->starget->hostdata) { |
2919 | sas_target_priv_data = sas_device->starget->hostdata; | 3104 | sas_target_priv_data = sas_device->starget->hostdata; |
@@ -2947,14 +3132,14 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2947 | if (!smid) { | 3132 | if (!smid) { |
2948 | delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); | 3133 | delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); |
2949 | if (!delayed_tr) | 3134 | if (!delayed_tr) |
2950 | return; | 3135 | goto out; |
2951 | INIT_LIST_HEAD(&delayed_tr->list); | 3136 | INIT_LIST_HEAD(&delayed_tr->list); |
2952 | delayed_tr->handle = handle; | 3137 | delayed_tr->handle = handle; |
2953 | list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); | 3138 | list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); |
2954 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 3139 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
2955 | "DELAYED:tr:handle(0x%04x), (open)\n", | 3140 | "DELAYED:tr:handle(0x%04x), (open)\n", |
2956 | ioc->name, handle)); | 3141 | ioc->name, handle)); |
2957 | return; | 3142 | goto out; |
2958 | } | 3143 | } |
2959 | 3144 | ||
2960 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 3145 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
@@ -2968,6 +3153,10 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2968 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | 3153 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; |
2969 | mpt3sas_base_put_smid_hi_priority(ioc, smid); | 3154 | mpt3sas_base_put_smid_hi_priority(ioc, smid); |
2970 | mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); | 3155 | mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); |
3156 | |||
3157 | out: | ||
3158 | if (sas_device) | ||
3159 | sas_device_put(sas_device); | ||
2971 | } | 3160 | } |
2972 | 3161 | ||
2973 | /** | 3162 | /** |
@@ -3337,7 +3526,7 @@ _scsih_set_volume_delete_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
3337 | unsigned long flags; | 3526 | unsigned long flags; |
3338 | 3527 | ||
3339 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 3528 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
3340 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 3529 | raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle); |
3341 | if (raid_device && raid_device->starget && | 3530 | if (raid_device && raid_device->starget && |
3342 | raid_device->starget->hostdata) { | 3531 | raid_device->starget->hostdata) { |
3343 | sas_target_priv_data = | 3532 | sas_target_priv_data = |
@@ -3398,6 +3587,9 @@ _scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc, | |||
3398 | a = 0; | 3587 | a = 0; |
3399 | b = 0; | 3588 | b = 0; |
3400 | 3589 | ||
3590 | if (ioc->is_warpdrive) | ||
3591 | return; | ||
3592 | |||
3401 | /* Volume Resets for Deleted or Removed */ | 3593 | /* Volume Resets for Deleted or Removed */ |
3402 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 3594 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
3403 | for (i = 0; i < event_data->NumElements; i++, element++) { | 3595 | for (i = 0; i < event_data->NumElements; i++, element++) { |
@@ -3634,8 +3826,9 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) | |||
3634 | } | 3826 | } |
3635 | 3827 | ||
3636 | 3828 | ||
3829 | |||
3637 | /** | 3830 | /** |
3638 | * _scsih_qcmd - main scsi request entry point | 3831 | * scsih_qcmd - main scsi request entry point |
3639 | * @scmd: pointer to scsi command object | 3832 | * @scmd: pointer to scsi command object |
3640 | * @done: function pointer to be invoked on completion | 3833 | * @done: function pointer to be invoked on completion |
3641 | * | 3834 | * |
@@ -3645,21 +3838,20 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) | |||
3645 | * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or | 3838 | * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or |
3646 | * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full | 3839 | * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full |
3647 | */ | 3840 | */ |
3648 | static int | 3841 | int |
3649 | _scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | 3842 | scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) |
3650 | { | 3843 | { |
3651 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 3844 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
3652 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 3845 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
3653 | struct MPT3SAS_TARGET *sas_target_priv_data; | 3846 | struct MPT3SAS_TARGET *sas_target_priv_data; |
3847 | struct _raid_device *raid_device; | ||
3654 | Mpi2SCSIIORequest_t *mpi_request; | 3848 | Mpi2SCSIIORequest_t *mpi_request; |
3655 | u32 mpi_control; | 3849 | u32 mpi_control; |
3656 | u16 smid; | 3850 | u16 smid; |
3657 | u16 handle; | 3851 | u16 handle; |
3658 | 3852 | ||
3659 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
3660 | if (ioc->logging_level & MPT_DEBUG_SCSI) | 3853 | if (ioc->logging_level & MPT_DEBUG_SCSI) |
3661 | scsi_print_command(scmd); | 3854 | scsi_print_command(scmd); |
3662 | #endif | ||
3663 | 3855 | ||
3664 | sas_device_priv_data = scmd->device->hostdata; | 3856 | sas_device_priv_data = scmd->device->hostdata; |
3665 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 3857 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { |
@@ -3709,7 +3901,11 @@ _scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
3709 | /* set tags */ | 3901 | /* set tags */ |
3710 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3902 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
3711 | 3903 | ||
3712 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | 3904 | /* Make sure Device is not raid volume. |
3905 | * We do not expose raid functionality to upper layer for warpdrive. | ||
3906 | */ | ||
3907 | if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev) | ||
3908 | && (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | ||
3713 | scmd->cmd_len != 32) | 3909 | scmd->cmd_len != 32) |
3714 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3910 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
3715 | 3911 | ||
@@ -3752,13 +3948,19 @@ _scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
3752 | } else | 3948 | } else |
3753 | ioc->build_zero_len_sge(ioc, &mpi_request->SGL); | 3949 | ioc->build_zero_len_sge(ioc, &mpi_request->SGL); |
3754 | 3950 | ||
3951 | raid_device = sas_target_priv_data->raid_device; | ||
3952 | if (raid_device && raid_device->direct_io_enabled) | ||
3953 | mpt3sas_setup_direct_io(ioc, scmd, raid_device, mpi_request, | ||
3954 | smid); | ||
3955 | |||
3755 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) { | 3956 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) { |
3756 | if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { | 3957 | if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { |
3757 | mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | | 3958 | mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | |
3758 | MPI25_SCSIIO_IOFLAGS_FAST_PATH); | 3959 | MPI25_SCSIIO_IOFLAGS_FAST_PATH); |
3759 | mpt3sas_base_put_smid_fast_path(ioc, smid, handle); | 3960 | mpt3sas_base_put_smid_fast_path(ioc, smid, handle); |
3760 | } else | 3961 | } else |
3761 | mpt3sas_base_put_smid_scsi_io(ioc, smid, handle); | 3962 | mpt3sas_base_put_smid_scsi_io(ioc, smid, |
3963 | le16_to_cpu(mpi_request->DevHandle)); | ||
3762 | } else | 3964 | } else |
3763 | mpt3sas_base_put_smid_default(ioc, smid); | 3965 | mpt3sas_base_put_smid_default(ioc, smid); |
3764 | return 0; | 3966 | return 0; |
@@ -3790,7 +3992,6 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data) | |||
3790 | } | 3992 | } |
3791 | } | 3993 | } |
3792 | 3994 | ||
3793 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
3794 | /** | 3995 | /** |
3795 | * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request | 3996 | * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request |
3796 | * @ioc: per adapter object | 3997 | * @ioc: per adapter object |
@@ -3818,14 +4019,16 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3818 | char *desc_scsi_state = ioc->tmp_string; | 4019 | char *desc_scsi_state = ioc->tmp_string; |
3819 | u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); | 4020 | u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); |
3820 | struct _sas_device *sas_device = NULL; | 4021 | struct _sas_device *sas_device = NULL; |
3821 | unsigned long flags; | ||
3822 | struct scsi_target *starget = scmd->device->sdev_target; | 4022 | struct scsi_target *starget = scmd->device->sdev_target; |
3823 | struct MPT3SAS_TARGET *priv_target = starget->hostdata; | 4023 | struct MPT3SAS_TARGET *priv_target = starget->hostdata; |
3824 | char *device_str = NULL; | 4024 | char *device_str = NULL; |
3825 | 4025 | ||
3826 | if (!priv_target) | 4026 | if (!priv_target) |
3827 | return; | 4027 | return; |
3828 | device_str = "volume"; | 4028 | if (ioc->hide_ir_msg) |
4029 | device_str = "WarpDrive"; | ||
4030 | else | ||
4031 | device_str = "volume"; | ||
3829 | 4032 | ||
3830 | if (log_info == 0x31170000) | 4033 | if (log_info == 0x31170000) |
3831 | return; | 4034 | return; |
@@ -3946,9 +4149,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3946 | pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name, | 4149 | pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name, |
3947 | device_str, (unsigned long long)priv_target->sas_address); | 4150 | device_str, (unsigned long long)priv_target->sas_address); |
3948 | } else { | 4151 | } else { |
3949 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4152 | sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target); |
3950 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | ||
3951 | priv_target->sas_address); | ||
3952 | if (sas_device) { | 4153 | if (sas_device) { |
3953 | pr_warn(MPT3SAS_FMT | 4154 | pr_warn(MPT3SAS_FMT |
3954 | "\tsas_address(0x%016llx), phy(%d)\n", | 4155 | "\tsas_address(0x%016llx), phy(%d)\n", |
@@ -3967,8 +4168,9 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3967 | " connector name( %s)\n", ioc->name, | 4168 | " connector name( %s)\n", ioc->name, |
3968 | sas_device->enclosure_level, | 4169 | sas_device->enclosure_level, |
3969 | sas_device->connector_name); | 4170 | sas_device->connector_name); |
4171 | |||
4172 | sas_device_put(sas_device); | ||
3970 | } | 4173 | } |
3971 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
3972 | } | 4174 | } |
3973 | 4175 | ||
3974 | pr_warn(MPT3SAS_FMT | 4176 | pr_warn(MPT3SAS_FMT |
@@ -4003,7 +4205,6 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
4003 | _scsih_response_code(ioc, response_bytes[0]); | 4205 | _scsih_response_code(ioc, response_bytes[0]); |
4004 | } | 4206 | } |
4005 | } | 4207 | } |
4006 | #endif | ||
4007 | 4208 | ||
4008 | /** | 4209 | /** |
4009 | * _scsih_turn_on_pfa_led - illuminate PFA LED | 4210 | * _scsih_turn_on_pfa_led - illuminate PFA LED |
@@ -4020,7 +4221,7 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4020 | Mpi2SepRequest_t mpi_request; | 4221 | Mpi2SepRequest_t mpi_request; |
4021 | struct _sas_device *sas_device; | 4222 | struct _sas_device *sas_device; |
4022 | 4223 | ||
4023 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4224 | sas_device = mpt3sas_get_sdev_by_handle(ioc, handle); |
4024 | if (!sas_device) | 4225 | if (!sas_device) |
4025 | return; | 4226 | return; |
4026 | 4227 | ||
@@ -4035,7 +4236,7 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4035 | &mpi_request)) != 0) { | 4236 | &mpi_request)) != 0) { |
4036 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, | 4237 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, |
4037 | __FILE__, __LINE__, __func__); | 4238 | __FILE__, __LINE__, __func__); |
4038 | return; | 4239 | goto out; |
4039 | } | 4240 | } |
4040 | sas_device->pfa_led_on = 1; | 4241 | sas_device->pfa_led_on = 1; |
4041 | 4242 | ||
@@ -4044,9 +4245,12 @@ _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4044 | "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", | 4245 | "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", |
4045 | ioc->name, le16_to_cpu(mpi_reply.IOCStatus), | 4246 | ioc->name, le16_to_cpu(mpi_reply.IOCStatus), |
4046 | le32_to_cpu(mpi_reply.IOCLogInfo))); | 4247 | le32_to_cpu(mpi_reply.IOCLogInfo))); |
4047 | return; | 4248 | goto out; |
4048 | } | 4249 | } |
4250 | out: | ||
4251 | sas_device_put(sas_device); | ||
4049 | } | 4252 | } |
4253 | |||
4050 | /** | 4254 | /** |
4051 | * _scsih_turn_off_pfa_led - turn off Fault LED | 4255 | * _scsih_turn_off_pfa_led - turn off Fault LED |
4052 | * @ioc: per adapter object | 4256 | * @ioc: per adapter object |
@@ -4085,6 +4289,7 @@ _scsih_turn_off_pfa_led(struct MPT3SAS_ADAPTER *ioc, | |||
4085 | return; | 4289 | return; |
4086 | } | 4290 | } |
4087 | } | 4291 | } |
4292 | |||
4088 | /** | 4293 | /** |
4089 | * _scsih_send_event_to_turn_on_pfa_led - fire delayed event | 4294 | * _scsih_send_event_to_turn_on_pfa_led - fire delayed event |
4090 | * @ioc: per adapter object | 4295 | * @ioc: per adapter object |
@@ -4098,13 +4303,14 @@ _scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4098 | { | 4303 | { |
4099 | struct fw_event_work *fw_event; | 4304 | struct fw_event_work *fw_event; |
4100 | 4305 | ||
4101 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 4306 | fw_event = alloc_fw_event_work(0); |
4102 | if (!fw_event) | 4307 | if (!fw_event) |
4103 | return; | 4308 | return; |
4104 | fw_event->event = MPT3SAS_TURN_ON_PFA_LED; | 4309 | fw_event->event = MPT3SAS_TURN_ON_PFA_LED; |
4105 | fw_event->device_handle = handle; | 4310 | fw_event->device_handle = handle; |
4106 | fw_event->ioc = ioc; | 4311 | fw_event->ioc = ioc; |
4107 | _scsih_fw_event_add(ioc, fw_event); | 4312 | _scsih_fw_event_add(ioc, fw_event); |
4313 | fw_event_work_put(fw_event); | ||
4108 | } | 4314 | } |
4109 | 4315 | ||
4110 | /** | 4316 | /** |
@@ -4128,19 +4334,17 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4128 | 4334 | ||
4129 | /* only handle non-raid devices */ | 4335 | /* only handle non-raid devices */ |
4130 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4336 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
4131 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4337 | sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); |
4132 | if (!sas_device) { | 4338 | if (!sas_device) |
4133 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4339 | goto out_unlock; |
4134 | return; | 4340 | |
4135 | } | ||
4136 | starget = sas_device->starget; | 4341 | starget = sas_device->starget; |
4137 | sas_target_priv_data = starget->hostdata; | 4342 | sas_target_priv_data = starget->hostdata; |
4138 | 4343 | ||
4139 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) || | 4344 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) || |
4140 | ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) { | 4345 | ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) |
4141 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4346 | goto out_unlock; |
4142 | return; | 4347 | |
4143 | } | ||
4144 | if (sas_device->enclosure_handle != 0) | 4348 | if (sas_device->enclosure_handle != 0) |
4145 | starget_printk(KERN_INFO, starget, "predicted fault, " | 4349 | starget_printk(KERN_INFO, starget, "predicted fault, " |
4146 | "enclosure logical id(0x%016llx), slot(%d)\n", | 4350 | "enclosure logical id(0x%016llx), slot(%d)\n", |
@@ -4163,7 +4367,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4163 | if (!event_reply) { | 4367 | if (!event_reply) { |
4164 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 4368 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
4165 | ioc->name, __FILE__, __LINE__, __func__); | 4369 | ioc->name, __FILE__, __LINE__, __func__); |
4166 | return; | 4370 | goto out; |
4167 | } | 4371 | } |
4168 | 4372 | ||
4169 | event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; | 4373 | event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; |
@@ -4180,6 +4384,14 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
4180 | event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); | 4384 | event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); |
4181 | mpt3sas_ctl_add_to_event_log(ioc, event_reply); | 4385 | mpt3sas_ctl_add_to_event_log(ioc, event_reply); |
4182 | kfree(event_reply); | 4386 | kfree(event_reply); |
4387 | out: | ||
4388 | if (sas_device) | ||
4389 | sas_device_put(sas_device); | ||
4390 | return; | ||
4391 | |||
4392 | out_unlock: | ||
4393 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
4394 | goto out; | ||
4183 | } | 4395 | } |
4184 | 4396 | ||
4185 | /** | 4397 | /** |
@@ -4207,6 +4419,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4207 | u32 log_info; | 4419 | u32 log_info; |
4208 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 4420 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
4209 | u32 response_code = 0; | 4421 | u32 response_code = 0; |
4422 | unsigned long flags; | ||
4210 | 4423 | ||
4211 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); | 4424 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); |
4212 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); | 4425 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
@@ -4228,6 +4441,24 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4228 | } | 4441 | } |
4229 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus); | 4442 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus); |
4230 | 4443 | ||
4444 | /* | ||
4445 | * WARPDRIVE: If direct_io is set then it is directIO, | ||
4446 | * the failed direct I/O should be redirected to volume | ||
4447 | */ | ||
4448 | if (mpt3sas_scsi_direct_io_get(ioc, smid) && | ||
4449 | ((ioc_status & MPI2_IOCSTATUS_MASK) | ||
4450 | != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) { | ||
4451 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
4452 | ioc->scsi_lookup[smid - 1].scmd = scmd; | ||
4453 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
4454 | mpt3sas_scsi_direct_io_set(ioc, smid, 0); | ||
4455 | memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); | ||
4456 | mpi_request->DevHandle = | ||
4457 | cpu_to_le16(sas_device_priv_data->sas_target->handle); | ||
4458 | mpt3sas_base_put_smid_scsi_io(ioc, smid, | ||
4459 | sas_device_priv_data->sas_target->handle); | ||
4460 | return 0; | ||
4461 | } | ||
4231 | /* turning off TLR */ | 4462 | /* turning off TLR */ |
4232 | scsi_state = mpi_reply->SCSIState; | 4463 | scsi_state = mpi_reply->SCSIState; |
4233 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) | 4464 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) |
@@ -4235,10 +4466,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4235 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | 4466 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; |
4236 | if (!sas_device_priv_data->tlr_snoop_check) { | 4467 | if (!sas_device_priv_data->tlr_snoop_check) { |
4237 | sas_device_priv_data->tlr_snoop_check++; | 4468 | sas_device_priv_data->tlr_snoop_check++; |
4238 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | 4469 | if (!ioc->is_warpdrive && |
4239 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) | 4470 | !scsih_is_raid(&scmd->device->sdev_gendev) && |
4240 | sas_device_priv_data->flags &= | 4471 | sas_is_tlr_enabled(scmd->device) && |
4241 | ~MPT_DEVICE_TLR_ON; | 4472 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { |
4473 | sas_disable_tlr(scmd->device); | ||
4474 | sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); | ||
4475 | } | ||
4242 | } | 4476 | } |
4243 | 4477 | ||
4244 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); | 4478 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); |
@@ -4271,13 +4505,11 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4271 | le16_to_cpu(mpi_reply->DevHandle)); | 4505 | le16_to_cpu(mpi_reply->DevHandle)); |
4272 | mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); | 4506 | mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); |
4273 | 4507 | ||
4274 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
4275 | if (!(ioc->logging_level & MPT_DEBUG_REPLY) && | 4508 | if (!(ioc->logging_level & MPT_DEBUG_REPLY) && |
4276 | ((scmd->sense_buffer[2] == UNIT_ATTENTION) || | 4509 | ((scmd->sense_buffer[2] == UNIT_ATTENTION) || |
4277 | (scmd->sense_buffer[2] == MEDIUM_ERROR) || | 4510 | (scmd->sense_buffer[2] == MEDIUM_ERROR) || |
4278 | (scmd->sense_buffer[2] == HARDWARE_ERROR))) | 4511 | (scmd->sense_buffer[2] == HARDWARE_ERROR))) |
4279 | _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid); | 4512 | _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid); |
4280 | #endif | ||
4281 | } | 4513 | } |
4282 | switch (ioc_status) { | 4514 | switch (ioc_status) { |
4283 | case MPI2_IOCSTATUS_BUSY: | 4515 | case MPI2_IOCSTATUS_BUSY: |
@@ -4384,10 +4616,8 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4384 | 4616 | ||
4385 | } | 4617 | } |
4386 | 4618 | ||
4387 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
4388 | if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY)) | 4619 | if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY)) |
4389 | _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid); | 4620 | _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid); |
4390 | #endif | ||
4391 | 4621 | ||
4392 | out: | 4622 | out: |
4393 | 4623 | ||
@@ -4933,13 +5163,11 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc, | |||
4933 | 5163 | ||
4934 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5164 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
4935 | sas_address = le64_to_cpu(sas_device_pg0.SASAddress); | 5165 | sas_address = le64_to_cpu(sas_device_pg0.SASAddress); |
4936 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 5166 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
4937 | sas_address); | 5167 | sas_address); |
4938 | 5168 | ||
4939 | if (!sas_device) { | 5169 | if (!sas_device) |
4940 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5170 | goto out_unlock; |
4941 | return; | ||
4942 | } | ||
4943 | 5171 | ||
4944 | if (unlikely(sas_device->handle != handle)) { | 5172 | if (unlikely(sas_device->handle != handle)) { |
4945 | starget = sas_device->starget; | 5173 | starget = sas_device->starget; |
@@ -4967,20 +5195,25 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc, | |||
4967 | pr_err(MPT3SAS_FMT | 5195 | pr_err(MPT3SAS_FMT |
4968 | "device is not present handle(0x%04x), flags!!!\n", | 5196 | "device is not present handle(0x%04x), flags!!!\n", |
4969 | ioc->name, handle); | 5197 | ioc->name, handle); |
4970 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5198 | goto out_unlock; |
4971 | return; | ||
4972 | } | 5199 | } |
4973 | 5200 | ||
4974 | /* check if there were any issues with discovery */ | 5201 | /* check if there were any issues with discovery */ |
4975 | if (_scsih_check_access_status(ioc, sas_address, handle, | 5202 | if (_scsih_check_access_status(ioc, sas_address, handle, |
4976 | sas_device_pg0.AccessStatus)) { | 5203 | sas_device_pg0.AccessStatus)) |
4977 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5204 | goto out_unlock; |
4978 | return; | ||
4979 | } | ||
4980 | 5205 | ||
4981 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5206 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4982 | _scsih_ublock_io_device(ioc, sas_address); | 5207 | _scsih_ublock_io_device(ioc, sas_address); |
4983 | 5208 | ||
5209 | if (sas_device) | ||
5210 | sas_device_put(sas_device); | ||
5211 | return; | ||
5212 | |||
5213 | out_unlock: | ||
5214 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5215 | if (sas_device) | ||
5216 | sas_device_put(sas_device); | ||
4984 | } | 5217 | } |
4985 | 5218 | ||
4986 | /** | 5219 | /** |
@@ -5005,7 +5238,6 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, | |||
5005 | u32 ioc_status; | 5238 | u32 ioc_status; |
5006 | u64 sas_address; | 5239 | u64 sas_address; |
5007 | u32 device_info; | 5240 | u32 device_info; |
5008 | unsigned long flags; | ||
5009 | 5241 | ||
5010 | if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | 5242 | if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, |
5011 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | 5243 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { |
@@ -5041,13 +5273,12 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, | |||
5041 | sas_device_pg0.AccessStatus)) | 5273 | sas_device_pg0.AccessStatus)) |
5042 | return -1; | 5274 | return -1; |
5043 | 5275 | ||
5044 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5276 | sas_device = mpt3sas_get_sdev_by_addr(ioc, |
5045 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 5277 | sas_address); |
5046 | sas_address); | 5278 | if (sas_device) { |
5047 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5279 | sas_device_put(sas_device); |
5048 | |||
5049 | if (sas_device) | ||
5050 | return -1; | 5280 | return -1; |
5281 | } | ||
5051 | 5282 | ||
5052 | sas_device = kzalloc(sizeof(struct _sas_device), | 5283 | sas_device = kzalloc(sizeof(struct _sas_device), |
5053 | GFP_KERNEL); | 5284 | GFP_KERNEL); |
@@ -5057,6 +5288,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, | |||
5057 | return 0; | 5288 | return 0; |
5058 | } | 5289 | } |
5059 | 5290 | ||
5291 | kref_init(&sas_device->refcount); | ||
5060 | sas_device->handle = handle; | 5292 | sas_device->handle = handle; |
5061 | if (_scsih_get_sas_address(ioc, | 5293 | if (_scsih_get_sas_address(ioc, |
5062 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | 5294 | le16_to_cpu(sas_device_pg0.ParentDevHandle), |
@@ -5098,6 +5330,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, | |||
5098 | else | 5330 | else |
5099 | _scsih_sas_device_add(ioc, sas_device); | 5331 | _scsih_sas_device_add(ioc, sas_device); |
5100 | 5332 | ||
5333 | sas_device_put(sas_device); | ||
5101 | return 0; | 5334 | return 0; |
5102 | } | 5335 | } |
5103 | 5336 | ||
@@ -5144,7 +5377,9 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, | |||
5144 | sas_target_priv_data->handle = | 5377 | sas_target_priv_data->handle = |
5145 | MPT3SAS_INVALID_DEVICE_HANDLE; | 5378 | MPT3SAS_INVALID_DEVICE_HANDLE; |
5146 | } | 5379 | } |
5147 | mpt3sas_transport_port_remove(ioc, | 5380 | |
5381 | if (!ioc->hide_drives) | ||
5382 | mpt3sas_transport_port_remove(ioc, | ||
5148 | sas_device->sas_address, | 5383 | sas_device->sas_address, |
5149 | sas_device->sas_address_parent); | 5384 | sas_device->sas_address_parent); |
5150 | 5385 | ||
@@ -5180,11 +5415,8 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, | |||
5180 | "%s: exit: enclosure level(0x%04x), connector name(%s)\n", | 5415 | "%s: exit: enclosure level(0x%04x), connector name(%s)\n", |
5181 | ioc->name, __func__, sas_device->enclosure_level, | 5416 | ioc->name, __func__, sas_device->enclosure_level, |
5182 | sas_device->connector_name)); | 5417 | sas_device->connector_name)); |
5183 | |||
5184 | kfree(sas_device); | ||
5185 | } | 5418 | } |
5186 | 5419 | ||
5187 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5188 | /** | 5420 | /** |
5189 | * _scsih_sas_topology_change_event_debug - debug for topology event | 5421 | * _scsih_sas_topology_change_event_debug - debug for topology event |
5190 | * @ioc: per adapter object | 5422 | * @ioc: per adapter object |
@@ -5262,7 +5494,6 @@ _scsih_sas_topology_change_event_debug(struct MPT3SAS_ADAPTER *ioc, | |||
5262 | 5494 | ||
5263 | } | 5495 | } |
5264 | } | 5496 | } |
5265 | #endif | ||
5266 | 5497 | ||
5267 | /** | 5498 | /** |
5268 | * _scsih_sas_topology_change_event - handle topology changes | 5499 | * _scsih_sas_topology_change_event - handle topology changes |
@@ -5287,10 +5518,8 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
5287 | (Mpi2EventDataSasTopologyChangeList_t *) | 5518 | (Mpi2EventDataSasTopologyChangeList_t *) |
5288 | fw_event->event_data; | 5519 | fw_event->event_data; |
5289 | 5520 | ||
5290 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5291 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5521 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
5292 | _scsih_sas_topology_change_event_debug(ioc, event_data); | 5522 | _scsih_sas_topology_change_event_debug(ioc, event_data); |
5293 | #endif | ||
5294 | 5523 | ||
5295 | if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) | 5524 | if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) |
5296 | return 0; | 5525 | return 0; |
@@ -5396,7 +5625,6 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
5396 | return 0; | 5625 | return 0; |
5397 | } | 5626 | } |
5398 | 5627 | ||
5399 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5400 | /** | 5628 | /** |
5401 | * _scsih_sas_device_status_change_event_debug - debug for device event | 5629 | * _scsih_sas_device_status_change_event_debug - debug for device event |
5402 | * @event_data: event data payload | 5630 | * @event_data: event data payload |
@@ -5464,7 +5692,6 @@ _scsih_sas_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc, | |||
5464 | event_data->ASC, event_data->ASCQ); | 5692 | event_data->ASC, event_data->ASCQ); |
5465 | pr_info("\n"); | 5693 | pr_info("\n"); |
5466 | } | 5694 | } |
5467 | #endif | ||
5468 | 5695 | ||
5469 | /** | 5696 | /** |
5470 | * _scsih_sas_device_status_change_event - handle device status change | 5697 | * _scsih_sas_device_status_change_event - handle device status change |
@@ -5486,11 +5713,9 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
5486 | (Mpi2EventDataSasDeviceStatusChange_t *) | 5713 | (Mpi2EventDataSasDeviceStatusChange_t *) |
5487 | fw_event->event_data; | 5714 | fw_event->event_data; |
5488 | 5715 | ||
5489 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5490 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5716 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
5491 | _scsih_sas_device_status_change_event_debug(ioc, | 5717 | _scsih_sas_device_status_change_event_debug(ioc, |
5492 | event_data); | 5718 | event_data); |
5493 | #endif | ||
5494 | 5719 | ||
5495 | /* In MPI Revision K (0xC), the internal device reset complete was | 5720 | /* In MPI Revision K (0xC), the internal device reset complete was |
5496 | * implemented, so avoid setting tm_busy flag for older firmware. | 5721 | * implemented, so avoid setting tm_busy flag for older firmware. |
@@ -5506,29 +5731,30 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
5506 | 5731 | ||
5507 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5732 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5508 | sas_address = le64_to_cpu(event_data->SASAddress); | 5733 | sas_address = le64_to_cpu(event_data->SASAddress); |
5509 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | 5734 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
5510 | sas_address); | 5735 | sas_address); |
5511 | 5736 | ||
5512 | if (!sas_device || !sas_device->starget) { | 5737 | if (!sas_device || !sas_device->starget) |
5513 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5738 | goto out; |
5514 | return; | ||
5515 | } | ||
5516 | 5739 | ||
5517 | target_priv_data = sas_device->starget->hostdata; | 5740 | target_priv_data = sas_device->starget->hostdata; |
5518 | if (!target_priv_data) { | 5741 | if (!target_priv_data) |
5519 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5742 | goto out; |
5520 | return; | ||
5521 | } | ||
5522 | 5743 | ||
5523 | if (event_data->ReasonCode == | 5744 | if (event_data->ReasonCode == |
5524 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) | 5745 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) |
5525 | target_priv_data->tm_busy = 1; | 5746 | target_priv_data->tm_busy = 1; |
5526 | else | 5747 | else |
5527 | target_priv_data->tm_busy = 0; | 5748 | target_priv_data->tm_busy = 0; |
5749 | |||
5750 | out: | ||
5751 | if (sas_device) | ||
5752 | sas_device_put(sas_device); | ||
5753 | |||
5528 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5754 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5755 | |||
5529 | } | 5756 | } |
5530 | 5757 | ||
5531 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5532 | /** | 5758 | /** |
5533 | * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure | 5759 | * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure |
5534 | * event | 5760 | * event |
@@ -5563,7 +5789,6 @@ _scsih_sas_enclosure_dev_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc, | |||
5563 | (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID), | 5789 | (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID), |
5564 | le16_to_cpu(event_data->StartSlot)); | 5790 | le16_to_cpu(event_data->StartSlot)); |
5565 | } | 5791 | } |
5566 | #endif | ||
5567 | 5792 | ||
5568 | /** | 5793 | /** |
5569 | * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events | 5794 | * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events |
@@ -5577,12 +5802,10 @@ static void | |||
5577 | _scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc, | 5802 | _scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc, |
5578 | struct fw_event_work *fw_event) | 5803 | struct fw_event_work *fw_event) |
5579 | { | 5804 | { |
5580 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5581 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5805 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
5582 | _scsih_sas_enclosure_dev_status_change_event_debug(ioc, | 5806 | _scsih_sas_enclosure_dev_status_change_event_debug(ioc, |
5583 | (Mpi2EventDataSasEnclDevStatusChange_t *) | 5807 | (Mpi2EventDataSasEnclDevStatusChange_t *) |
5584 | fw_event->event_data); | 5808 | fw_event->event_data); |
5585 | #endif | ||
5586 | } | 5809 | } |
5587 | 5810 | ||
5588 | /** | 5811 | /** |
@@ -5762,17 +5985,15 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc, | |||
5762 | Mpi2EventDataSasDiscovery_t *event_data = | 5985 | Mpi2EventDataSasDiscovery_t *event_data = |
5763 | (Mpi2EventDataSasDiscovery_t *) fw_event->event_data; | 5986 | (Mpi2EventDataSasDiscovery_t *) fw_event->event_data; |
5764 | 5987 | ||
5765 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
5766 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { | 5988 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { |
5767 | pr_info(MPT3SAS_FMT "discovery event: (%s)", ioc->name, | 5989 | pr_info(MPT3SAS_FMT "discovery event: (%s)", ioc->name, |
5768 | (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? | 5990 | (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? |
5769 | "start" : "stop"); | 5991 | "start" : "stop"); |
5770 | if (event_data->DiscoveryStatus) | 5992 | if (event_data->DiscoveryStatus) |
5771 | pr_info("discovery_status(0x%08x)", | 5993 | pr_info("discovery_status(0x%08x)", |
5772 | le32_to_cpu(event_data->DiscoveryStatus)); | 5994 | le32_to_cpu(event_data->DiscoveryStatus)); |
5773 | pr_info("\n"); | 5995 | pr_info("\n"); |
5774 | } | 5996 | } |
5775 | #endif | ||
5776 | 5997 | ||
5777 | if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED && | 5998 | if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED && |
5778 | !ioc->sas_hba.num_phys) { | 5999 | !ioc->sas_hba.num_phys) { |
@@ -5804,6 +6025,8 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num) | |||
5804 | u16 ioc_status; | 6025 | u16 ioc_status; |
5805 | u32 log_info; | 6026 | u32 log_info; |
5806 | 6027 | ||
6028 | if (ioc->hba_mpi_version_belonged == MPI2_VERSION) | ||
6029 | return rc; | ||
5807 | 6030 | ||
5808 | mutex_lock(&ioc->scsih_cmds.mutex); | 6031 | mutex_lock(&ioc->scsih_cmds.mutex); |
5809 | 6032 | ||
@@ -5971,7 +6194,7 @@ _scsih_sas_volume_delete(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
5971 | struct scsi_target *starget = NULL; | 6194 | struct scsi_target *starget = NULL; |
5972 | 6195 | ||
5973 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 6196 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
5974 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 6197 | raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle); |
5975 | if (raid_device) { | 6198 | if (raid_device) { |
5976 | if (raid_device->starget) { | 6199 | if (raid_device->starget) { |
5977 | starget = raid_device->starget; | 6200 | starget = raid_device->starget; |
@@ -6008,7 +6231,7 @@ _scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc, | |||
6008 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); | 6231 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); |
6009 | 6232 | ||
6010 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6233 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6011 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6234 | sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); |
6012 | if (sas_device) { | 6235 | if (sas_device) { |
6013 | sas_device->volume_handle = 0; | 6236 | sas_device->volume_handle = 0; |
6014 | sas_device->volume_wwid = 0; | 6237 | sas_device->volume_wwid = 0; |
@@ -6027,6 +6250,8 @@ _scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc, | |||
6027 | /* exposing raid component */ | 6250 | /* exposing raid component */ |
6028 | if (starget) | 6251 | if (starget) |
6029 | starget_for_each_device(starget, NULL, _scsih_reprobe_lun); | 6252 | starget_for_each_device(starget, NULL, _scsih_reprobe_lun); |
6253 | |||
6254 | sas_device_put(sas_device); | ||
6030 | } | 6255 | } |
6031 | 6256 | ||
6032 | /** | 6257 | /** |
@@ -6055,7 +6280,7 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc, | |||
6055 | &volume_wwid); | 6280 | &volume_wwid); |
6056 | 6281 | ||
6057 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6282 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6058 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6283 | sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); |
6059 | if (sas_device) { | 6284 | if (sas_device) { |
6060 | set_bit(handle, ioc->pd_handles); | 6285 | set_bit(handle, ioc->pd_handles); |
6061 | if (sas_device->starget && sas_device->starget->hostdata) { | 6286 | if (sas_device->starget && sas_device->starget->hostdata) { |
@@ -6073,8 +6298,11 @@ _scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc, | |||
6073 | 6298 | ||
6074 | /* hiding raid component */ | 6299 | /* hiding raid component */ |
6075 | _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); | 6300 | _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); |
6301 | |||
6076 | if (starget) | 6302 | if (starget) |
6077 | starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); | 6303 | starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); |
6304 | |||
6305 | sas_device_put(sas_device); | ||
6078 | } | 6306 | } |
6079 | 6307 | ||
6080 | /** | 6308 | /** |
@@ -6107,7 +6335,6 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, | |||
6107 | Mpi2EventIrConfigElement_t *element) | 6335 | Mpi2EventIrConfigElement_t *element) |
6108 | { | 6336 | { |
6109 | struct _sas_device *sas_device; | 6337 | struct _sas_device *sas_device; |
6110 | unsigned long flags; | ||
6111 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); | 6338 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); |
6112 | Mpi2ConfigReply_t mpi_reply; | 6339 | Mpi2ConfigReply_t mpi_reply; |
6113 | Mpi2SasDevicePage0_t sas_device_pg0; | 6340 | Mpi2SasDevicePage0_t sas_device_pg0; |
@@ -6117,11 +6344,10 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, | |||
6117 | 6344 | ||
6118 | set_bit(handle, ioc->pd_handles); | 6345 | set_bit(handle, ioc->pd_handles); |
6119 | 6346 | ||
6120 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6347 | sas_device = mpt3sas_get_sdev_by_handle(ioc, handle); |
6121 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
6122 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
6123 | if (sas_device) { | 6348 | if (sas_device) { |
6124 | _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); | 6349 | _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); |
6350 | sas_device_put(sas_device); | ||
6125 | return; | 6351 | return; |
6126 | } | 6352 | } |
6127 | 6353 | ||
@@ -6149,7 +6375,6 @@ _scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, | |||
6149 | _scsih_add_device(ioc, handle, 0, 1); | 6375 | _scsih_add_device(ioc, handle, 0, 1); |
6150 | } | 6376 | } |
6151 | 6377 | ||
6152 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
6153 | /** | 6378 | /** |
6154 | * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events | 6379 | * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events |
6155 | * @ioc: per adapter object | 6380 | * @ioc: per adapter object |
@@ -6229,7 +6454,6 @@ _scsih_sas_ir_config_change_event_debug(struct MPT3SAS_ADAPTER *ioc, | |||
6229 | element->PhysDiskNum); | 6454 | element->PhysDiskNum); |
6230 | } | 6455 | } |
6231 | } | 6456 | } |
6232 | #endif | ||
6233 | 6457 | ||
6234 | /** | 6458 | /** |
6235 | * _scsih_sas_ir_config_change_event - handle ir configuration change events | 6459 | * _scsih_sas_ir_config_change_event - handle ir configuration change events |
@@ -6250,18 +6474,16 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
6250 | (Mpi2EventDataIrConfigChangeList_t *) | 6474 | (Mpi2EventDataIrConfigChangeList_t *) |
6251 | fw_event->event_data; | 6475 | fw_event->event_data; |
6252 | 6476 | ||
6253 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | 6477 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && |
6254 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 6478 | (!ioc->hide_ir_msg)) |
6255 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); | 6479 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); |
6256 | 6480 | ||
6257 | #endif | ||
6258 | |||
6259 | foreign_config = (le32_to_cpu(event_data->Flags) & | 6481 | foreign_config = (le32_to_cpu(event_data->Flags) & |
6260 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; | 6482 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; |
6261 | 6483 | ||
6262 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 6484 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
6263 | if (ioc->shost_recovery) { | 6485 | if (ioc->shost_recovery && |
6264 | 6486 | ioc->hba_mpi_version_belonged != MPI2_VERSION) { | |
6265 | for (i = 0; i < event_data->NumElements; i++, element++) { | 6487 | for (i = 0; i < event_data->NumElements; i++, element++) { |
6266 | if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE) | 6488 | if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE) |
6267 | _scsih_ir_fastpath(ioc, | 6489 | _scsih_ir_fastpath(ioc, |
@@ -6270,6 +6492,7 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
6270 | } | 6492 | } |
6271 | return; | 6493 | return; |
6272 | } | 6494 | } |
6495 | |||
6273 | for (i = 0; i < event_data->NumElements; i++, element++) { | 6496 | for (i = 0; i < event_data->NumElements; i++, element++) { |
6274 | 6497 | ||
6275 | switch (element->ReasonCode) { | 6498 | switch (element->ReasonCode) { |
@@ -6285,16 +6508,20 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
6285 | le16_to_cpu(element->VolDevHandle)); | 6508 | le16_to_cpu(element->VolDevHandle)); |
6286 | break; | 6509 | break; |
6287 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: | 6510 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: |
6288 | _scsih_sas_pd_hide(ioc, element); | 6511 | if (!ioc->is_warpdrive) |
6512 | _scsih_sas_pd_hide(ioc, element); | ||
6289 | break; | 6513 | break; |
6290 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: | 6514 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: |
6291 | _scsih_sas_pd_expose(ioc, element); | 6515 | if (!ioc->is_warpdrive) |
6516 | _scsih_sas_pd_expose(ioc, element); | ||
6292 | break; | 6517 | break; |
6293 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: | 6518 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: |
6294 | _scsih_sas_pd_add(ioc, element); | 6519 | if (!ioc->is_warpdrive) |
6520 | _scsih_sas_pd_add(ioc, element); | ||
6295 | break; | 6521 | break; |
6296 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: | 6522 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: |
6297 | _scsih_sas_pd_delete(ioc, element); | 6523 | if (!ioc->is_warpdrive) |
6524 | _scsih_sas_pd_delete(ioc, element); | ||
6298 | break; | 6525 | break; |
6299 | } | 6526 | } |
6300 | } | 6527 | } |
@@ -6329,10 +6556,11 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc, | |||
6329 | 6556 | ||
6330 | handle = le16_to_cpu(event_data->VolDevHandle); | 6557 | handle = le16_to_cpu(event_data->VolDevHandle); |
6331 | state = le32_to_cpu(event_data->NewValue); | 6558 | state = le32_to_cpu(event_data->NewValue); |
6332 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 6559 | if (!ioc->hide_ir_msg) |
6333 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", | 6560 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
6334 | ioc->name, __func__, handle, | 6561 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", |
6335 | le32_to_cpu(event_data->PreviousValue), state)); | 6562 | ioc->name, __func__, handle, |
6563 | le32_to_cpu(event_data->PreviousValue), state)); | ||
6336 | switch (state) { | 6564 | switch (state) { |
6337 | case MPI2_RAID_VOL_STATE_MISSING: | 6565 | case MPI2_RAID_VOL_STATE_MISSING: |
6338 | case MPI2_RAID_VOL_STATE_FAILED: | 6566 | case MPI2_RAID_VOL_STATE_FAILED: |
@@ -6344,7 +6572,7 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc, | |||
6344 | case MPI2_RAID_VOL_STATE_OPTIMAL: | 6572 | case MPI2_RAID_VOL_STATE_OPTIMAL: |
6345 | 6573 | ||
6346 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 6574 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
6347 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 6575 | raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle); |
6348 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 6576 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
6349 | 6577 | ||
6350 | if (raid_device) | 6578 | if (raid_device) |
@@ -6398,7 +6626,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, | |||
6398 | u16 handle, parent_handle; | 6626 | u16 handle, parent_handle; |
6399 | u32 state; | 6627 | u32 state; |
6400 | struct _sas_device *sas_device; | 6628 | struct _sas_device *sas_device; |
6401 | unsigned long flags; | ||
6402 | Mpi2ConfigReply_t mpi_reply; | 6629 | Mpi2ConfigReply_t mpi_reply; |
6403 | Mpi2SasDevicePage0_t sas_device_pg0; | 6630 | Mpi2SasDevicePage0_t sas_device_pg0; |
6404 | u32 ioc_status; | 6631 | u32 ioc_status; |
@@ -6415,10 +6642,12 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, | |||
6415 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); | 6642 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); |
6416 | state = le32_to_cpu(event_data->NewValue); | 6643 | state = le32_to_cpu(event_data->NewValue); |
6417 | 6644 | ||
6418 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 6645 | if (!ioc->hide_ir_msg) |
6419 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", | 6646 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
6420 | ioc->name, __func__, handle, | 6647 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", |
6648 | ioc->name, __func__, handle, | ||
6421 | le32_to_cpu(event_data->PreviousValue), state)); | 6649 | le32_to_cpu(event_data->PreviousValue), state)); |
6650 | |||
6422 | switch (state) { | 6651 | switch (state) { |
6423 | case MPI2_RAID_PD_STATE_ONLINE: | 6652 | case MPI2_RAID_PD_STATE_ONLINE: |
6424 | case MPI2_RAID_PD_STATE_DEGRADED: | 6653 | case MPI2_RAID_PD_STATE_DEGRADED: |
@@ -6426,13 +6655,14 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, | |||
6426 | case MPI2_RAID_PD_STATE_OPTIMAL: | 6655 | case MPI2_RAID_PD_STATE_OPTIMAL: |
6427 | case MPI2_RAID_PD_STATE_HOT_SPARE: | 6656 | case MPI2_RAID_PD_STATE_HOT_SPARE: |
6428 | 6657 | ||
6429 | set_bit(handle, ioc->pd_handles); | 6658 | if (!ioc->is_warpdrive) |
6430 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6659 | set_bit(handle, ioc->pd_handles); |
6431 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
6432 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
6433 | 6660 | ||
6434 | if (sas_device) | 6661 | sas_device = mpt3sas_get_sdev_by_handle(ioc, handle); |
6662 | if (sas_device) { | ||
6663 | sas_device_put(sas_device); | ||
6435 | return; | 6664 | return; |
6665 | } | ||
6436 | 6666 | ||
6437 | if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, | 6667 | if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, |
6438 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, | 6668 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, |
@@ -6467,7 +6697,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, | |||
6467 | } | 6697 | } |
6468 | } | 6698 | } |
6469 | 6699 | ||
6470 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
6471 | /** | 6700 | /** |
6472 | * _scsih_sas_ir_operation_status_event_debug - debug for IR op event | 6701 | * _scsih_sas_ir_operation_status_event_debug - debug for IR op event |
6473 | * @ioc: per adapter object | 6702 | * @ioc: per adapter object |
@@ -6509,7 +6738,6 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT3SAS_ADAPTER *ioc, | |||
6509 | le16_to_cpu(event_data->VolDevHandle), | 6738 | le16_to_cpu(event_data->VolDevHandle), |
6510 | event_data->PercentComplete); | 6739 | event_data->PercentComplete); |
6511 | } | 6740 | } |
6512 | #endif | ||
6513 | 6741 | ||
6514 | /** | 6742 | /** |
6515 | * _scsih_sas_ir_operation_status_event - handle RAID operation events | 6743 | * _scsih_sas_ir_operation_status_event - handle RAID operation events |
@@ -6530,18 +6758,17 @@ _scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc, | |||
6530 | unsigned long flags; | 6758 | unsigned long flags; |
6531 | u16 handle; | 6759 | u16 handle; |
6532 | 6760 | ||
6533 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | 6761 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && |
6534 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 6762 | (!ioc->hide_ir_msg)) |
6535 | _scsih_sas_ir_operation_status_event_debug(ioc, | 6763 | _scsih_sas_ir_operation_status_event_debug(ioc, |
6536 | event_data); | 6764 | event_data); |
6537 | #endif | ||
6538 | 6765 | ||
6539 | /* code added for raid transport support */ | 6766 | /* code added for raid transport support */ |
6540 | if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { | 6767 | if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { |
6541 | 6768 | ||
6542 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 6769 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
6543 | handle = le16_to_cpu(event_data->VolDevHandle); | 6770 | handle = le16_to_cpu(event_data->VolDevHandle); |
6544 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 6771 | raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle); |
6545 | if (raid_device) | 6772 | if (raid_device) |
6546 | raid_device->percent_complete = | 6773 | raid_device->percent_complete = |
6547 | event_data->PercentComplete; | 6774 | event_data->PercentComplete; |
@@ -6703,7 +6930,7 @@ static void | |||
6703 | _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, | 6930 | _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, |
6704 | u16 handle) | 6931 | u16 handle) |
6705 | { | 6932 | { |
6706 | struct MPT3SAS_TARGET *sas_target_priv_data; | 6933 | struct MPT3SAS_TARGET *sas_target_priv_data = NULL; |
6707 | struct scsi_target *starget; | 6934 | struct scsi_target *starget; |
6708 | struct _raid_device *raid_device; | 6935 | struct _raid_device *raid_device; |
6709 | unsigned long flags; | 6936 | unsigned long flags; |
@@ -6722,6 +6949,13 @@ _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, | |||
6722 | starget_printk(KERN_INFO, raid_device->starget, | 6949 | starget_printk(KERN_INFO, raid_device->starget, |
6723 | "handle(0x%04x), wwid(0x%016llx)\n", handle, | 6950 | "handle(0x%04x), wwid(0x%016llx)\n", handle, |
6724 | (unsigned long long)raid_device->wwid); | 6951 | (unsigned long long)raid_device->wwid); |
6952 | |||
6953 | /* | ||
6954 | * WARPDRIVE: The handles of the PDs might have changed | ||
6955 | * across the host reset so re-initialize the | ||
6956 | * required data for Direct IO | ||
6957 | */ | ||
6958 | mpt3sas_init_warpdrive_properties(ioc, raid_device); | ||
6725 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 6959 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
6726 | if (raid_device->handle == handle) { | 6960 | if (raid_device->handle == handle) { |
6727 | spin_unlock_irqrestore(&ioc->raid_device_lock, | 6961 | spin_unlock_irqrestore(&ioc->raid_device_lock, |
@@ -6791,6 +7025,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6791 | } | 7025 | } |
6792 | 7026 | ||
6793 | /* refresh the pd_handles */ | 7027 | /* refresh the pd_handles */ |
7028 | if (!ioc->is_warpdrive) { | ||
6794 | phys_disk_num = 0xFF; | 7029 | phys_disk_num = 0xFF; |
6795 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); | 7030 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); |
6796 | while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | 7031 | while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply, |
@@ -6804,6 +7039,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6804 | handle = le16_to_cpu(pd_pg0.DevHandle); | 7039 | handle = le16_to_cpu(pd_pg0.DevHandle); |
6805 | set_bit(handle, ioc->pd_handles); | 7040 | set_bit(handle, ioc->pd_handles); |
6806 | } | 7041 | } |
7042 | } | ||
6807 | out: | 7043 | out: |
6808 | pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n", | 7044 | pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n", |
6809 | ioc->name); | 7045 | ioc->name); |
@@ -6906,6 +7142,7 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6906 | struct _raid_device *raid_device, *raid_device_next; | 7142 | struct _raid_device *raid_device, *raid_device_next; |
6907 | struct list_head tmp_list; | 7143 | struct list_head tmp_list; |
6908 | unsigned long flags; | 7144 | unsigned long flags; |
7145 | LIST_HEAD(head); | ||
6909 | 7146 | ||
6910 | pr_info(MPT3SAS_FMT "removing unresponding devices: start\n", | 7147 | pr_info(MPT3SAS_FMT "removing unresponding devices: start\n", |
6911 | ioc->name); | 7148 | ioc->name); |
@@ -6913,14 +7150,28 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6913 | /* removing unresponding end devices */ | 7150 | /* removing unresponding end devices */ |
6914 | pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n", | 7151 | pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n", |
6915 | ioc->name); | 7152 | ioc->name); |
7153 | /* | ||
7154 | * Iterate, pulling off devices marked as non-responding. We become the | ||
7155 | * owner for the reference the list had on any object we prune. | ||
7156 | */ | ||
7157 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
6916 | list_for_each_entry_safe(sas_device, sas_device_next, | 7158 | list_for_each_entry_safe(sas_device, sas_device_next, |
6917 | &ioc->sas_device_list, list) { | 7159 | &ioc->sas_device_list, list) { |
6918 | if (!sas_device->responding) | 7160 | if (!sas_device->responding) |
6919 | mpt3sas_device_remove_by_sas_address(ioc, | 7161 | list_move_tail(&sas_device->list, &head); |
6920 | sas_device->sas_address); | ||
6921 | else | 7162 | else |
6922 | sas_device->responding = 0; | 7163 | sas_device->responding = 0; |
6923 | } | 7164 | } |
7165 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
7166 | |||
7167 | /* | ||
7168 | * Now, uninitialize and remove the unresponding devices we pruned. | ||
7169 | */ | ||
7170 | list_for_each_entry_safe(sas_device, sas_device_next, &head, list) { | ||
7171 | _scsih_remove_device(ioc, sas_device); | ||
7172 | list_del_init(&sas_device->list); | ||
7173 | sas_device_put(sas_device); | ||
7174 | } | ||
6924 | 7175 | ||
6925 | /* removing unresponding volumes */ | 7176 | /* removing unresponding volumes */ |
6926 | if (ioc->ir_firmware) { | 7177 | if (ioc->ir_firmware) { |
@@ -7074,11 +7325,11 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) | |||
7074 | } | 7325 | } |
7075 | phys_disk_num = pd_pg0.PhysDiskNum; | 7326 | phys_disk_num = pd_pg0.PhysDiskNum; |
7076 | handle = le16_to_cpu(pd_pg0.DevHandle); | 7327 | handle = le16_to_cpu(pd_pg0.DevHandle); |
7077 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 7328 | sas_device = mpt3sas_get_sdev_by_handle(ioc, handle); |
7078 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 7329 | if (sas_device) { |
7079 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7330 | sas_device_put(sas_device); |
7080 | if (sas_device) | ||
7081 | continue; | 7331 | continue; |
7332 | } | ||
7082 | if (mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, | 7333 | if (mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, |
7083 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, | 7334 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, |
7084 | handle) != 0) | 7335 | handle) != 0) |
@@ -7199,12 +7450,12 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) | |||
7199 | if (!(_scsih_is_end_device( | 7450 | if (!(_scsih_is_end_device( |
7200 | le32_to_cpu(sas_device_pg0.DeviceInfo)))) | 7451 | le32_to_cpu(sas_device_pg0.DeviceInfo)))) |
7201 | continue; | 7452 | continue; |
7202 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 7453 | sas_device = mpt3sas_get_sdev_by_addr(ioc, |
7203 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | ||
7204 | le64_to_cpu(sas_device_pg0.SASAddress)); | 7454 | le64_to_cpu(sas_device_pg0.SASAddress)); |
7205 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7455 | if (sas_device) { |
7206 | if (sas_device) | 7456 | sas_device_put(sas_device); |
7207 | continue; | 7457 | continue; |
7458 | } | ||
7208 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); | 7459 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); |
7209 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { | 7460 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { |
7210 | pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \ | 7461 | pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \ |
@@ -7296,10 +7547,11 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) | |||
7296 | static void | 7547 | static void |
7297 | _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) | 7548 | _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) |
7298 | { | 7549 | { |
7550 | _scsih_fw_event_del_from_list(ioc, fw_event); | ||
7551 | |||
7299 | /* the queue is being flushed so ignore this event */ | 7552 | /* the queue is being flushed so ignore this event */ |
7300 | if (ioc->remove_host || | 7553 | if (ioc->remove_host || ioc->pci_error_recovery) { |
7301 | ioc->pci_error_recovery) { | 7554 | fw_event_work_put(fw_event); |
7302 | _scsih_fw_event_free(ioc, fw_event); | ||
7303 | return; | 7555 | return; |
7304 | } | 7556 | } |
7305 | 7557 | ||
@@ -7310,8 +7562,16 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) | |||
7310 | fw_event->event_data); | 7562 | fw_event->event_data); |
7311 | break; | 7563 | break; |
7312 | case MPT3SAS_REMOVE_UNRESPONDING_DEVICES: | 7564 | case MPT3SAS_REMOVE_UNRESPONDING_DEVICES: |
7313 | while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery) | 7565 | while (scsi_host_in_recovery(ioc->shost) || |
7566 | ioc->shost_recovery) { | ||
7567 | /* | ||
7568 | * If we're unloading, bail. Otherwise, this can become | ||
7569 | * an infinite loop. | ||
7570 | */ | ||
7571 | if (ioc->remove_host) | ||
7572 | goto out; | ||
7314 | ssleep(1); | 7573 | ssleep(1); |
7574 | } | ||
7315 | _scsih_remove_unresponding_sas_devices(ioc); | 7575 | _scsih_remove_unresponding_sas_devices(ioc); |
7316 | _scsih_scan_for_devices_after_reset(ioc); | 7576 | _scsih_scan_for_devices_after_reset(ioc); |
7317 | break; | 7577 | break; |
@@ -7356,7 +7616,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) | |||
7356 | _scsih_sas_ir_operation_status_event(ioc, fw_event); | 7616 | _scsih_sas_ir_operation_status_event(ioc, fw_event); |
7357 | break; | 7617 | break; |
7358 | } | 7618 | } |
7359 | _scsih_fw_event_free(ioc, fw_event); | 7619 | out: |
7620 | fw_event_work_put(fw_event); | ||
7360 | } | 7621 | } |
7361 | 7622 | ||
7362 | /** | 7623 | /** |
@@ -7453,7 +7714,53 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, | |||
7453 | (Mpi2EventDataIrVolume_t *) | 7714 | (Mpi2EventDataIrVolume_t *) |
7454 | mpi_reply->EventData); | 7715 | mpi_reply->EventData); |
7455 | break; | 7716 | break; |
7717 | case MPI2_EVENT_LOG_ENTRY_ADDED: | ||
7718 | { | ||
7719 | Mpi2EventDataLogEntryAdded_t *log_entry; | ||
7720 | u32 *log_code; | ||
7721 | |||
7722 | if (!ioc->is_warpdrive) | ||
7723 | break; | ||
7724 | |||
7725 | log_entry = (Mpi2EventDataLogEntryAdded_t *) | ||
7726 | mpi_reply->EventData; | ||
7727 | log_code = (u32 *)log_entry->LogData; | ||
7456 | 7728 | ||
7729 | if (le16_to_cpu(log_entry->LogEntryQualifier) | ||
7730 | != MPT2_WARPDRIVE_LOGENTRY) | ||
7731 | break; | ||
7732 | |||
7733 | switch (le32_to_cpu(*log_code)) { | ||
7734 | case MPT2_WARPDRIVE_LC_SSDT: | ||
7735 | pr_warn(MPT3SAS_FMT "WarpDrive Warning: " | ||
7736 | "IO Throttling has occurred in the WarpDrive " | ||
7737 | "subsystem. Check WarpDrive documentation for " | ||
7738 | "additional details.\n", ioc->name); | ||
7739 | break; | ||
7740 | case MPT2_WARPDRIVE_LC_SSDLW: | ||
7741 | pr_warn(MPT3SAS_FMT "WarpDrive Warning: " | ||
7742 | "Program/Erase Cycles for the WarpDrive subsystem " | ||
7743 | "in degraded range. Check WarpDrive documentation " | ||
7744 | "for additional details.\n", ioc->name); | ||
7745 | break; | ||
7746 | case MPT2_WARPDRIVE_LC_SSDLF: | ||
7747 | pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " | ||
7748 | "There are no Program/Erase Cycles for the " | ||
7749 | "WarpDrive subsystem. The storage device will be " | ||
7750 | "in read-only mode. Check WarpDrive documentation " | ||
7751 | "for additional details.\n", ioc->name); | ||
7752 | break; | ||
7753 | case MPT2_WARPDRIVE_LC_BRMF: | ||
7754 | pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " | ||
7755 | "The Backup Rail Monitor has failed on the " | ||
7756 | "WarpDrive subsystem. Check WarpDrive " | ||
7757 | "documentation for additional details.\n", | ||
7758 | ioc->name); | ||
7759 | break; | ||
7760 | } | ||
7761 | |||
7762 | break; | ||
7763 | } | ||
7457 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | 7764 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: |
7458 | case MPI2_EVENT_IR_OPERATION_STATUS: | 7765 | case MPI2_EVENT_IR_OPERATION_STATUS: |
7459 | case MPI2_EVENT_SAS_DISCOVERY: | 7766 | case MPI2_EVENT_SAS_DISCOVERY: |
@@ -7472,7 +7779,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, | |||
7472 | } | 7779 | } |
7473 | 7780 | ||
7474 | sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; | 7781 | sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; |
7475 | fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC); | 7782 | fw_event = alloc_fw_event_work(sz); |
7476 | if (!fw_event) { | 7783 | if (!fw_event) { |
7477 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 7784 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
7478 | ioc->name, __FILE__, __LINE__, __func__); | 7785 | ioc->name, __FILE__, __LINE__, __func__); |
@@ -7485,39 +7792,10 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, | |||
7485 | fw_event->VP_ID = mpi_reply->VP_ID; | 7792 | fw_event->VP_ID = mpi_reply->VP_ID; |
7486 | fw_event->event = event; | 7793 | fw_event->event = event; |
7487 | _scsih_fw_event_add(ioc, fw_event); | 7794 | _scsih_fw_event_add(ioc, fw_event); |
7795 | fw_event_work_put(fw_event); | ||
7488 | return 1; | 7796 | return 1; |
7489 | } | 7797 | } |
7490 | 7798 | ||
7491 | /* shost template */ | ||
7492 | static struct scsi_host_template scsih_driver_template = { | ||
7493 | .module = THIS_MODULE, | ||
7494 | .name = "Fusion MPT SAS Host", | ||
7495 | .proc_name = MPT3SAS_DRIVER_NAME, | ||
7496 | .queuecommand = _scsih_qcmd, | ||
7497 | .target_alloc = _scsih_target_alloc, | ||
7498 | .slave_alloc = _scsih_slave_alloc, | ||
7499 | .slave_configure = _scsih_slave_configure, | ||
7500 | .target_destroy = _scsih_target_destroy, | ||
7501 | .slave_destroy = _scsih_slave_destroy, | ||
7502 | .scan_finished = _scsih_scan_finished, | ||
7503 | .scan_start = _scsih_scan_start, | ||
7504 | .change_queue_depth = _scsih_change_queue_depth, | ||
7505 | .eh_abort_handler = _scsih_abort, | ||
7506 | .eh_device_reset_handler = _scsih_dev_reset, | ||
7507 | .eh_target_reset_handler = _scsih_target_reset, | ||
7508 | .eh_host_reset_handler = _scsih_host_reset, | ||
7509 | .bios_param = _scsih_bios_param, | ||
7510 | .can_queue = 1, | ||
7511 | .this_id = -1, | ||
7512 | .sg_tablesize = MPT3SAS_SG_DEPTH, | ||
7513 | .max_sectors = 32767, | ||
7514 | .cmd_per_lun = 7, | ||
7515 | .use_clustering = ENABLE_CLUSTERING, | ||
7516 | .shost_attrs = mpt3sas_host_attrs, | ||
7517 | .sdev_attrs = mpt3sas_dev_attrs, | ||
7518 | .track_queue_depth = 1, | ||
7519 | }; | ||
7520 | |||
7521 | /** | 7799 | /** |
7522 | * _scsih_expander_node_remove - removing expander device from list. | 7800 | * _scsih_expander_node_remove - removing expander device from list. |
7523 | * @ioc: per adapter object | 7801 | * @ioc: per adapter object |
@@ -7613,7 +7891,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) | |||
7613 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; | 7891 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; |
7614 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; | 7892 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; |
7615 | 7893 | ||
7616 | pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); | 7894 | if (!ioc->hide_ir_msg) |
7895 | pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); | ||
7617 | init_completion(&ioc->scsih_cmds.done); | 7896 | init_completion(&ioc->scsih_cmds.done); |
7618 | mpt3sas_base_put_smid_default(ioc, smid); | 7897 | mpt3sas_base_put_smid_default(ioc, smid); |
7619 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | 7898 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); |
@@ -7626,10 +7905,11 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) | |||
7626 | 7905 | ||
7627 | if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { | 7906 | if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { |
7628 | mpi_reply = ioc->scsih_cmds.reply; | 7907 | mpi_reply = ioc->scsih_cmds.reply; |
7629 | pr_info(MPT3SAS_FMT | 7908 | if (!ioc->hide_ir_msg) |
7630 | "IR shutdown (complete): ioc_status(0x%04x), loginfo(0x%08x)\n", | 7909 | pr_info(MPT3SAS_FMT "IR shutdown " |
7631 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), | 7910 | "(complete): ioc_status(0x%04x), loginfo(0x%08x)\n", |
7632 | le32_to_cpu(mpi_reply->IOCLogInfo)); | 7911 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), |
7912 | le32_to_cpu(mpi_reply->IOCLogInfo)); | ||
7633 | } | 7913 | } |
7634 | 7914 | ||
7635 | out: | 7915 | out: |
@@ -7638,13 +7918,13 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) | |||
7638 | } | 7918 | } |
7639 | 7919 | ||
7640 | /** | 7920 | /** |
7641 | * _scsih_remove - detach and remove add host | 7921 | * scsih_remove - detach and remove add host |
7642 | * @pdev: PCI device struct | 7922 | * @pdev: PCI device struct |
7643 | * | 7923 | * |
7644 | * Routine called when unloading the driver. | 7924 | * Routine called when unloading the driver. |
7645 | * Return nothing. | 7925 | * Return nothing. |
7646 | */ | 7926 | */ |
7647 | static void _scsih_remove(struct pci_dev *pdev) | 7927 | void scsih_remove(struct pci_dev *pdev) |
7648 | { | 7928 | { |
7649 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 7929 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
7650 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 7930 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -7705,18 +7985,20 @@ static void _scsih_remove(struct pci_dev *pdev) | |||
7705 | sas_remove_host(shost); | 7985 | sas_remove_host(shost); |
7706 | scsi_remove_host(shost); | 7986 | scsi_remove_host(shost); |
7707 | mpt3sas_base_detach(ioc); | 7987 | mpt3sas_base_detach(ioc); |
7988 | spin_lock(&gioc_lock); | ||
7708 | list_del(&ioc->list); | 7989 | list_del(&ioc->list); |
7990 | spin_unlock(&gioc_lock); | ||
7709 | scsi_host_put(shost); | 7991 | scsi_host_put(shost); |
7710 | } | 7992 | } |
7711 | 7993 | ||
7712 | /** | 7994 | /** |
7713 | * _scsih_shutdown - routine call during system shutdown | 7995 | * scsih_shutdown - routine call during system shutdown |
7714 | * @pdev: PCI device struct | 7996 | * @pdev: PCI device struct |
7715 | * | 7997 | * |
7716 | * Return nothing. | 7998 | * Return nothing. |
7717 | */ | 7999 | */ |
7718 | static void | 8000 | void |
7719 | _scsih_shutdown(struct pci_dev *pdev) | 8001 | scsih_shutdown(struct pci_dev *pdev) |
7720 | { | 8002 | { |
7721 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8003 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
7722 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8004 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -7794,6 +8076,8 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) | |||
7794 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 8076 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
7795 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 8077 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
7796 | 8078 | ||
8079 | if (ioc->hide_drives) | ||
8080 | return; | ||
7797 | if (!mpt3sas_transport_port_add(ioc, handle, | 8081 | if (!mpt3sas_transport_port_add(ioc, handle, |
7798 | sas_address_parent)) { | 8082 | sas_address_parent)) { |
7799 | _scsih_sas_device_remove(ioc, sas_device); | 8083 | _scsih_sas_device_remove(ioc, sas_device); |
@@ -7831,6 +8115,48 @@ _scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc) | |||
7831 | } | 8115 | } |
7832 | } | 8116 | } |
7833 | 8117 | ||
8118 | static struct _sas_device *get_next_sas_device(struct MPT3SAS_ADAPTER *ioc) | ||
8119 | { | ||
8120 | struct _sas_device *sas_device = NULL; | ||
8121 | unsigned long flags; | ||
8122 | |||
8123 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
8124 | if (!list_empty(&ioc->sas_device_init_list)) { | ||
8125 | sas_device = list_first_entry(&ioc->sas_device_init_list, | ||
8126 | struct _sas_device, list); | ||
8127 | sas_device_get(sas_device); | ||
8128 | } | ||
8129 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
8130 | |||
8131 | return sas_device; | ||
8132 | } | ||
8133 | |||
8134 | static void sas_device_make_active(struct MPT3SAS_ADAPTER *ioc, | ||
8135 | struct _sas_device *sas_device) | ||
8136 | { | ||
8137 | unsigned long flags; | ||
8138 | |||
8139 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
8140 | |||
8141 | /* | ||
8142 | * Since we dropped the lock during the call to port_add(), we need to | ||
8143 | * be careful here that somebody else didn't move or delete this item | ||
8144 | * while we were busy with other things. | ||
8145 | * | ||
8146 | * If it was on the list, we need a put() for the reference the list | ||
8147 | * had. Either way, we need a get() for the destination list. | ||
8148 | */ | ||
8149 | if (!list_empty(&sas_device->list)) { | ||
8150 | list_del_init(&sas_device->list); | ||
8151 | sas_device_put(sas_device); | ||
8152 | } | ||
8153 | |||
8154 | sas_device_get(sas_device); | ||
8155 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | ||
8156 | |||
8157 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
8158 | } | ||
8159 | |||
7834 | /** | 8160 | /** |
7835 | * _scsih_probe_sas - reporting sas devices to sas transport | 8161 | * _scsih_probe_sas - reporting sas devices to sas transport |
7836 | * @ioc: per adapter object | 8162 | * @ioc: per adapter object |
@@ -7840,17 +8166,16 @@ _scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc) | |||
7840 | static void | 8166 | static void |
7841 | _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) | 8167 | _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) |
7842 | { | 8168 | { |
7843 | struct _sas_device *sas_device, *next; | 8169 | struct _sas_device *sas_device; |
7844 | unsigned long flags; | ||
7845 | 8170 | ||
7846 | /* SAS Device List */ | 8171 | if (ioc->hide_drives) |
7847 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, | 8172 | return; |
7848 | list) { | ||
7849 | 8173 | ||
8174 | while ((sas_device = get_next_sas_device(ioc))) { | ||
7850 | if (!mpt3sas_transport_port_add(ioc, sas_device->handle, | 8175 | if (!mpt3sas_transport_port_add(ioc, sas_device->handle, |
7851 | sas_device->sas_address_parent)) { | 8176 | sas_device->sas_address_parent)) { |
7852 | list_del(&sas_device->list); | 8177 | _scsih_sas_device_remove(ioc, sas_device); |
7853 | kfree(sas_device); | 8178 | sas_device_put(sas_device); |
7854 | continue; | 8179 | continue; |
7855 | } else if (!sas_device->starget) { | 8180 | } else if (!sas_device->starget) { |
7856 | /* | 8181 | /* |
@@ -7863,15 +8188,13 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) | |||
7863 | mpt3sas_transport_port_remove(ioc, | 8188 | mpt3sas_transport_port_remove(ioc, |
7864 | sas_device->sas_address, | 8189 | sas_device->sas_address, |
7865 | sas_device->sas_address_parent); | 8190 | sas_device->sas_address_parent); |
7866 | list_del(&sas_device->list); | 8191 | _scsih_sas_device_remove(ioc, sas_device); |
7867 | kfree(sas_device); | 8192 | sas_device_put(sas_device); |
7868 | continue; | 8193 | continue; |
7869 | } | 8194 | } |
7870 | } | 8195 | } |
7871 | 8196 | sas_device_make_active(ioc, sas_device); | |
7872 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 8197 | sas_device_put(sas_device); |
7873 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | ||
7874 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
7875 | } | 8198 | } |
7876 | } | 8199 | } |
7877 | 8200 | ||
@@ -7908,15 +8231,15 @@ _scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc) | |||
7908 | } | 8231 | } |
7909 | 8232 | ||
7910 | /** | 8233 | /** |
7911 | * _scsih_scan_start - scsi lld callback for .scan_start | 8234 | * scsih_scan_start - scsi lld callback for .scan_start |
7912 | * @shost: SCSI host pointer | 8235 | * @shost: SCSI host pointer |
7913 | * | 8236 | * |
7914 | * The shost has the ability to discover targets on its own instead | 8237 | * The shost has the ability to discover targets on its own instead |
7915 | * of scanning the entire bus. In our implemention, we will kick off | 8238 | * of scanning the entire bus. In our implemention, we will kick off |
7916 | * firmware discovery. | 8239 | * firmware discovery. |
7917 | */ | 8240 | */ |
7918 | static void | 8241 | void |
7919 | _scsih_scan_start(struct Scsi_Host *shost) | 8242 | scsih_scan_start(struct Scsi_Host *shost) |
7920 | { | 8243 | { |
7921 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8244 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
7922 | int rc; | 8245 | int rc; |
@@ -7934,7 +8257,7 @@ _scsih_scan_start(struct Scsi_Host *shost) | |||
7934 | } | 8257 | } |
7935 | 8258 | ||
7936 | /** | 8259 | /** |
7937 | * _scsih_scan_finished - scsi lld callback for .scan_finished | 8260 | * scsih_scan_finished - scsi lld callback for .scan_finished |
7938 | * @shost: SCSI host pointer | 8261 | * @shost: SCSI host pointer |
7939 | * @time: elapsed time of the scan in jiffies | 8262 | * @time: elapsed time of the scan in jiffies |
7940 | * | 8263 | * |
@@ -7942,8 +8265,8 @@ _scsih_scan_start(struct Scsi_Host *shost) | |||
7942 | * scsi_host and the elapsed time of the scan in jiffies. In our implemention, | 8265 | * scsi_host and the elapsed time of the scan in jiffies. In our implemention, |
7943 | * we wait for firmware discovery to complete, then return 1. | 8266 | * we wait for firmware discovery to complete, then return 1. |
7944 | */ | 8267 | */ |
7945 | static int | 8268 | int |
7946 | _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time) | 8269 | scsih_scan_finished(struct Scsi_Host *shost, unsigned long time) |
7947 | { | 8270 | { |
7948 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8271 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
7949 | 8272 | ||
@@ -7987,6 +8310,124 @@ _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time) | |||
7987 | return 1; | 8310 | return 1; |
7988 | } | 8311 | } |
7989 | 8312 | ||
8313 | /* shost template for SAS 2.0 HBA devices */ | ||
8314 | static struct scsi_host_template mpt2sas_driver_template = { | ||
8315 | .module = THIS_MODULE, | ||
8316 | .name = "Fusion MPT SAS Host", | ||
8317 | .proc_name = MPT2SAS_DRIVER_NAME, | ||
8318 | .queuecommand = scsih_qcmd, | ||
8319 | .target_alloc = scsih_target_alloc, | ||
8320 | .slave_alloc = scsih_slave_alloc, | ||
8321 | .slave_configure = scsih_slave_configure, | ||
8322 | .target_destroy = scsih_target_destroy, | ||
8323 | .slave_destroy = scsih_slave_destroy, | ||
8324 | .scan_finished = scsih_scan_finished, | ||
8325 | .scan_start = scsih_scan_start, | ||
8326 | .change_queue_depth = scsih_change_queue_depth, | ||
8327 | .eh_abort_handler = scsih_abort, | ||
8328 | .eh_device_reset_handler = scsih_dev_reset, | ||
8329 | .eh_target_reset_handler = scsih_target_reset, | ||
8330 | .eh_host_reset_handler = scsih_host_reset, | ||
8331 | .bios_param = scsih_bios_param, | ||
8332 | .can_queue = 1, | ||
8333 | .this_id = -1, | ||
8334 | .sg_tablesize = MPT2SAS_SG_DEPTH, | ||
8335 | .max_sectors = 32767, | ||
8336 | .cmd_per_lun = 7, | ||
8337 | .use_clustering = ENABLE_CLUSTERING, | ||
8338 | .shost_attrs = mpt3sas_host_attrs, | ||
8339 | .sdev_attrs = mpt3sas_dev_attrs, | ||
8340 | .track_queue_depth = 1, | ||
8341 | }; | ||
8342 | |||
8343 | /* raid transport support for SAS 2.0 HBA devices */ | ||
8344 | static struct raid_function_template mpt2sas_raid_functions = { | ||
8345 | .cookie = &mpt2sas_driver_template, | ||
8346 | .is_raid = scsih_is_raid, | ||
8347 | .get_resync = scsih_get_resync, | ||
8348 | .get_state = scsih_get_state, | ||
8349 | }; | ||
8350 | |||
8351 | /* shost template for SAS 3.0 HBA devices */ | ||
8352 | static struct scsi_host_template mpt3sas_driver_template = { | ||
8353 | .module = THIS_MODULE, | ||
8354 | .name = "Fusion MPT SAS Host", | ||
8355 | .proc_name = MPT3SAS_DRIVER_NAME, | ||
8356 | .queuecommand = scsih_qcmd, | ||
8357 | .target_alloc = scsih_target_alloc, | ||
8358 | .slave_alloc = scsih_slave_alloc, | ||
8359 | .slave_configure = scsih_slave_configure, | ||
8360 | .target_destroy = scsih_target_destroy, | ||
8361 | .slave_destroy = scsih_slave_destroy, | ||
8362 | .scan_finished = scsih_scan_finished, | ||
8363 | .scan_start = scsih_scan_start, | ||
8364 | .change_queue_depth = scsih_change_queue_depth, | ||
8365 | .eh_abort_handler = scsih_abort, | ||
8366 | .eh_device_reset_handler = scsih_dev_reset, | ||
8367 | .eh_target_reset_handler = scsih_target_reset, | ||
8368 | .eh_host_reset_handler = scsih_host_reset, | ||
8369 | .bios_param = scsih_bios_param, | ||
8370 | .can_queue = 1, | ||
8371 | .this_id = -1, | ||
8372 | .sg_tablesize = MPT3SAS_SG_DEPTH, | ||
8373 | .max_sectors = 32767, | ||
8374 | .cmd_per_lun = 7, | ||
8375 | .use_clustering = ENABLE_CLUSTERING, | ||
8376 | .shost_attrs = mpt3sas_host_attrs, | ||
8377 | .sdev_attrs = mpt3sas_dev_attrs, | ||
8378 | .track_queue_depth = 1, | ||
8379 | }; | ||
8380 | |||
8381 | /* raid transport support for SAS 3.0 HBA devices */ | ||
8382 | static struct raid_function_template mpt3sas_raid_functions = { | ||
8383 | .cookie = &mpt3sas_driver_template, | ||
8384 | .is_raid = scsih_is_raid, | ||
8385 | .get_resync = scsih_get_resync, | ||
8386 | .get_state = scsih_get_state, | ||
8387 | }; | ||
8388 | |||
8389 | /** | ||
8390 | * _scsih_determine_hba_mpi_version - determine in which MPI version class | ||
8391 | * this device belongs to. | ||
8392 | * @pdev: PCI device struct | ||
8393 | * | ||
8394 | * return MPI2_VERSION for SAS 2.0 HBA devices, | ||
8395 | * MPI25_VERSION for SAS 3.0 HBA devices. | ||
8396 | */ | ||
8397 | u16 | ||
8398 | _scsih_determine_hba_mpi_version(struct pci_dev *pdev) | ||
8399 | { | ||
8400 | |||
8401 | switch (pdev->device) { | ||
8402 | case MPI2_MFGPAGE_DEVID_SSS6200: | ||
8403 | case MPI2_MFGPAGE_DEVID_SAS2004: | ||
8404 | case MPI2_MFGPAGE_DEVID_SAS2008: | ||
8405 | case MPI2_MFGPAGE_DEVID_SAS2108_1: | ||
8406 | case MPI2_MFGPAGE_DEVID_SAS2108_2: | ||
8407 | case MPI2_MFGPAGE_DEVID_SAS2108_3: | ||
8408 | case MPI2_MFGPAGE_DEVID_SAS2116_1: | ||
8409 | case MPI2_MFGPAGE_DEVID_SAS2116_2: | ||
8410 | case MPI2_MFGPAGE_DEVID_SAS2208_1: | ||
8411 | case MPI2_MFGPAGE_DEVID_SAS2208_2: | ||
8412 | case MPI2_MFGPAGE_DEVID_SAS2208_3: | ||
8413 | case MPI2_MFGPAGE_DEVID_SAS2208_4: | ||
8414 | case MPI2_MFGPAGE_DEVID_SAS2208_5: | ||
8415 | case MPI2_MFGPAGE_DEVID_SAS2208_6: | ||
8416 | case MPI2_MFGPAGE_DEVID_SAS2308_1: | ||
8417 | case MPI2_MFGPAGE_DEVID_SAS2308_2: | ||
8418 | case MPI2_MFGPAGE_DEVID_SAS2308_3: | ||
8419 | return MPI2_VERSION; | ||
8420 | case MPI25_MFGPAGE_DEVID_SAS3004: | ||
8421 | case MPI25_MFGPAGE_DEVID_SAS3008: | ||
8422 | case MPI25_MFGPAGE_DEVID_SAS3108_1: | ||
8423 | case MPI25_MFGPAGE_DEVID_SAS3108_2: | ||
8424 | case MPI25_MFGPAGE_DEVID_SAS3108_5: | ||
8425 | case MPI25_MFGPAGE_DEVID_SAS3108_6: | ||
8426 | return MPI25_VERSION; | ||
8427 | } | ||
8428 | return 0; | ||
8429 | } | ||
8430 | |||
7990 | /** | 8431 | /** |
7991 | * _scsih_probe - attach and add scsi host | 8432 | * _scsih_probe - attach and add scsi host |
7992 | * @pdev: PCI device struct | 8433 | * @pdev: PCI device struct |
@@ -7994,26 +8435,72 @@ _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time) | |||
7994 | * | 8435 | * |
7995 | * Returns 0 success, anything else error. | 8436 | * Returns 0 success, anything else error. |
7996 | */ | 8437 | */ |
7997 | static int | 8438 | int |
7998 | _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 8439 | _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
7999 | { | 8440 | { |
8000 | struct MPT3SAS_ADAPTER *ioc; | 8441 | struct MPT3SAS_ADAPTER *ioc; |
8001 | struct Scsi_Host *shost; | 8442 | struct Scsi_Host *shost = NULL; |
8002 | int rv; | 8443 | int rv; |
8444 | u16 hba_mpi_version; | ||
8003 | 8445 | ||
8004 | shost = scsi_host_alloc(&scsih_driver_template, | 8446 | /* Determine in which MPI version class this pci device belongs */ |
8005 | sizeof(struct MPT3SAS_ADAPTER)); | 8447 | hba_mpi_version = _scsih_determine_hba_mpi_version(pdev); |
8006 | if (!shost) | 8448 | if (hba_mpi_version == 0) |
8007 | return -ENODEV; | 8449 | return -ENODEV; |
8008 | 8450 | ||
8009 | /* init local params */ | 8451 | /* Enumerate only SAS 2.0 HBA's if hbas_to_enumerate is one, |
8010 | ioc = shost_priv(shost); | 8452 | * for other generation HBA's return with -ENODEV |
8011 | memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); | 8453 | */ |
8454 | if ((hbas_to_enumerate == 1) && (hba_mpi_version != MPI2_VERSION)) | ||
8455 | return -ENODEV; | ||
8456 | |||
8457 | /* Enumerate only SAS 3.0 HBA's if hbas_to_enumerate is two, | ||
8458 | * for other generation HBA's return with -ENODEV | ||
8459 | */ | ||
8460 | if ((hbas_to_enumerate == 2) && (hba_mpi_version != MPI25_VERSION)) | ||
8461 | return -ENODEV; | ||
8462 | |||
8463 | switch (hba_mpi_version) { | ||
8464 | case MPI2_VERSION: | ||
8465 | /* Use mpt2sas driver host template for SAS 2.0 HBA's */ | ||
8466 | shost = scsi_host_alloc(&mpt2sas_driver_template, | ||
8467 | sizeof(struct MPT3SAS_ADAPTER)); | ||
8468 | if (!shost) | ||
8469 | return -ENODEV; | ||
8470 | ioc = shost_priv(shost); | ||
8471 | memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); | ||
8472 | ioc->hba_mpi_version_belonged = hba_mpi_version; | ||
8473 | ioc->id = mpt2_ids++; | ||
8474 | sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME); | ||
8475 | if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) { | ||
8476 | ioc->is_warpdrive = 1; | ||
8477 | ioc->hide_ir_msg = 1; | ||
8478 | } else | ||
8479 | ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; | ||
8480 | break; | ||
8481 | case MPI25_VERSION: | ||
8482 | /* Use mpt3sas driver host template for SAS 3.0 HBA's */ | ||
8483 | shost = scsi_host_alloc(&mpt3sas_driver_template, | ||
8484 | sizeof(struct MPT3SAS_ADAPTER)); | ||
8485 | if (!shost) | ||
8486 | return -ENODEV; | ||
8487 | ioc = shost_priv(shost); | ||
8488 | memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); | ||
8489 | ioc->hba_mpi_version_belonged = hba_mpi_version; | ||
8490 | ioc->id = mpt3_ids++; | ||
8491 | sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME); | ||
8492 | if (pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) | ||
8493 | ioc->msix96_vector = 1; | ||
8494 | break; | ||
8495 | default: | ||
8496 | return -ENODEV; | ||
8497 | } | ||
8498 | |||
8012 | INIT_LIST_HEAD(&ioc->list); | 8499 | INIT_LIST_HEAD(&ioc->list); |
8500 | spin_lock(&gioc_lock); | ||
8013 | list_add_tail(&ioc->list, &mpt3sas_ioc_list); | 8501 | list_add_tail(&ioc->list, &mpt3sas_ioc_list); |
8502 | spin_unlock(&gioc_lock); | ||
8014 | ioc->shost = shost; | 8503 | ioc->shost = shost; |
8015 | ioc->id = mpt_ids++; | ||
8016 | sprintf(ioc->name, "%s%d", MPT3SAS_DRIVER_NAME, ioc->id); | ||
8017 | ioc->pdev = pdev; | 8504 | ioc->pdev = pdev; |
8018 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; | 8505 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; |
8019 | ioc->tm_cb_idx = tm_cb_idx; | 8506 | ioc->tm_cb_idx = tm_cb_idx; |
@@ -8030,6 +8517,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8030 | ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; | 8517 | ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; |
8031 | /* misc semaphores and spin locks */ | 8518 | /* misc semaphores and spin locks */ |
8032 | mutex_init(&ioc->reset_in_progress_mutex); | 8519 | mutex_init(&ioc->reset_in_progress_mutex); |
8520 | /* initializing pci_access_mutex lock */ | ||
8521 | mutex_init(&ioc->pci_access_mutex); | ||
8033 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); | 8522 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); |
8034 | spin_lock_init(&ioc->scsi_lookup_lock); | 8523 | spin_lock_init(&ioc->scsi_lookup_lock); |
8035 | spin_lock_init(&ioc->sas_device_lock); | 8524 | spin_lock_init(&ioc->sas_device_lock); |
@@ -8048,6 +8537,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8048 | INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); | 8537 | INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); |
8049 | INIT_LIST_HEAD(&ioc->reply_queue_list); | 8538 | INIT_LIST_HEAD(&ioc->reply_queue_list); |
8050 | 8539 | ||
8540 | sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id); | ||
8541 | |||
8051 | /* init shost parameters */ | 8542 | /* init shost parameters */ |
8052 | shost->max_cmd_len = 32; | 8543 | shost->max_cmd_len = 32; |
8053 | shost->max_lun = max_lun; | 8544 | shost->max_lun = max_lun; |
@@ -8086,7 +8577,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8086 | 8577 | ||
8087 | /* event thread */ | 8578 | /* event thread */ |
8088 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), | 8579 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), |
8089 | "fw_event%d", ioc->id); | 8580 | "fw_event_%s%d", ioc->driver_name, ioc->id); |
8090 | ioc->firmware_event_thread = alloc_ordered_workqueue( | 8581 | ioc->firmware_event_thread = alloc_ordered_workqueue( |
8091 | ioc->firmware_event_name, WQ_MEM_RECLAIM); | 8582 | ioc->firmware_event_name, WQ_MEM_RECLAIM); |
8092 | if (!ioc->firmware_event_thread) { | 8583 | if (!ioc->firmware_event_thread) { |
@@ -8103,6 +8594,21 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8103 | rv = -ENODEV; | 8594 | rv = -ENODEV; |
8104 | goto out_attach_fail; | 8595 | goto out_attach_fail; |
8105 | } | 8596 | } |
8597 | |||
8598 | if (ioc->is_warpdrive) { | ||
8599 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) | ||
8600 | ioc->hide_drives = 0; | ||
8601 | else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS) | ||
8602 | ioc->hide_drives = 1; | ||
8603 | else { | ||
8604 | if (mpt3sas_get_num_volumes(ioc)) | ||
8605 | ioc->hide_drives = 1; | ||
8606 | else | ||
8607 | ioc->hide_drives = 0; | ||
8608 | } | ||
8609 | } else | ||
8610 | ioc->hide_drives = 0; | ||
8611 | |||
8106 | rv = scsi_add_host(shost, &pdev->dev); | 8612 | rv = scsi_add_host(shost, &pdev->dev); |
8107 | if (rv) { | 8613 | if (rv) { |
8108 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 8614 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
@@ -8117,21 +8623,23 @@ out_add_shost_fail: | |||
8117 | out_attach_fail: | 8623 | out_attach_fail: |
8118 | destroy_workqueue(ioc->firmware_event_thread); | 8624 | destroy_workqueue(ioc->firmware_event_thread); |
8119 | out_thread_fail: | 8625 | out_thread_fail: |
8626 | spin_lock(&gioc_lock); | ||
8120 | list_del(&ioc->list); | 8627 | list_del(&ioc->list); |
8628 | spin_unlock(&gioc_lock); | ||
8121 | scsi_host_put(shost); | 8629 | scsi_host_put(shost); |
8122 | return rv; | 8630 | return rv; |
8123 | } | 8631 | } |
8124 | 8632 | ||
8125 | #ifdef CONFIG_PM | 8633 | #ifdef CONFIG_PM |
8126 | /** | 8634 | /** |
8127 | * _scsih_suspend - power management suspend main entry point | 8635 | * scsih_suspend - power management suspend main entry point |
8128 | * @pdev: PCI device struct | 8636 | * @pdev: PCI device struct |
8129 | * @state: PM state change to (usually PCI_D3) | 8637 | * @state: PM state change to (usually PCI_D3) |
8130 | * | 8638 | * |
8131 | * Returns 0 success, anything else error. | 8639 | * Returns 0 success, anything else error. |
8132 | */ | 8640 | */ |
8133 | static int | 8641 | int |
8134 | _scsih_suspend(struct pci_dev *pdev, pm_message_t state) | 8642 | scsih_suspend(struct pci_dev *pdev, pm_message_t state) |
8135 | { | 8643 | { |
8136 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8644 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8137 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8645 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -8152,13 +8660,13 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) | |||
8152 | } | 8660 | } |
8153 | 8661 | ||
8154 | /** | 8662 | /** |
8155 | * _scsih_resume - power management resume main entry point | 8663 | * scsih_resume - power management resume main entry point |
8156 | * @pdev: PCI device struct | 8664 | * @pdev: PCI device struct |
8157 | * | 8665 | * |
8158 | * Returns 0 success, anything else error. | 8666 | * Returns 0 success, anything else error. |
8159 | */ | 8667 | */ |
8160 | static int | 8668 | int |
8161 | _scsih_resume(struct pci_dev *pdev) | 8669 | scsih_resume(struct pci_dev *pdev) |
8162 | { | 8670 | { |
8163 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8671 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8164 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8672 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -8185,7 +8693,7 @@ _scsih_resume(struct pci_dev *pdev) | |||
8185 | #endif /* CONFIG_PM */ | 8693 | #endif /* CONFIG_PM */ |
8186 | 8694 | ||
8187 | /** | 8695 | /** |
8188 | * _scsih_pci_error_detected - Called when a PCI error is detected. | 8696 | * scsih_pci_error_detected - Called when a PCI error is detected. |
8189 | * @pdev: PCI device struct | 8697 | * @pdev: PCI device struct |
8190 | * @state: PCI channel state | 8698 | * @state: PCI channel state |
8191 | * | 8699 | * |
@@ -8194,8 +8702,8 @@ _scsih_resume(struct pci_dev *pdev) | |||
8194 | * Return value: | 8702 | * Return value: |
8195 | * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT | 8703 | * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT |
8196 | */ | 8704 | */ |
8197 | static pci_ers_result_t | 8705 | pci_ers_result_t |
8198 | _scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | 8706 | scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
8199 | { | 8707 | { |
8200 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8708 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8201 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8709 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -8224,15 +8732,15 @@ _scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | |||
8224 | } | 8732 | } |
8225 | 8733 | ||
8226 | /** | 8734 | /** |
8227 | * _scsih_pci_slot_reset - Called when PCI slot has been reset. | 8735 | * scsih_pci_slot_reset - Called when PCI slot has been reset. |
8228 | * @pdev: PCI device struct | 8736 | * @pdev: PCI device struct |
8229 | * | 8737 | * |
8230 | * Description: This routine is called by the pci error recovery | 8738 | * Description: This routine is called by the pci error recovery |
8231 | * code after the PCI slot has been reset, just before we | 8739 | * code after the PCI slot has been reset, just before we |
8232 | * should resume normal operations. | 8740 | * should resume normal operations. |
8233 | */ | 8741 | */ |
8234 | static pci_ers_result_t | 8742 | pci_ers_result_t |
8235 | _scsih_pci_slot_reset(struct pci_dev *pdev) | 8743 | scsih_pci_slot_reset(struct pci_dev *pdev) |
8236 | { | 8744 | { |
8237 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8745 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8238 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8746 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -8261,15 +8769,15 @@ _scsih_pci_slot_reset(struct pci_dev *pdev) | |||
8261 | } | 8769 | } |
8262 | 8770 | ||
8263 | /** | 8771 | /** |
8264 | * _scsih_pci_resume() - resume normal ops after PCI reset | 8772 | * scsih_pci_resume() - resume normal ops after PCI reset |
8265 | * @pdev: pointer to PCI device | 8773 | * @pdev: pointer to PCI device |
8266 | * | 8774 | * |
8267 | * Called when the error recovery driver tells us that its | 8775 | * Called when the error recovery driver tells us that its |
8268 | * OK to resume normal operation. Use completion to allow | 8776 | * OK to resume normal operation. Use completion to allow |
8269 | * halted scsi ops to resume. | 8777 | * halted scsi ops to resume. |
8270 | */ | 8778 | */ |
8271 | static void | 8779 | void |
8272 | _scsih_pci_resume(struct pci_dev *pdev) | 8780 | scsih_pci_resume(struct pci_dev *pdev) |
8273 | { | 8781 | { |
8274 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8782 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8275 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8783 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -8282,11 +8790,11 @@ _scsih_pci_resume(struct pci_dev *pdev) | |||
8282 | } | 8790 | } |
8283 | 8791 | ||
8284 | /** | 8792 | /** |
8285 | * _scsih_pci_mmio_enabled - Enable MMIO and dump debug registers | 8793 | * scsih_pci_mmio_enabled - Enable MMIO and dump debug registers |
8286 | * @pdev: pointer to PCI device | 8794 | * @pdev: pointer to PCI device |
8287 | */ | 8795 | */ |
8288 | static pci_ers_result_t | 8796 | pci_ers_result_t |
8289 | _scsih_pci_mmio_enabled(struct pci_dev *pdev) | 8797 | scsih_pci_mmio_enabled(struct pci_dev *pdev) |
8290 | { | 8798 | { |
8291 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 8799 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8292 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 8800 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
@@ -8300,61 +8808,99 @@ _scsih_pci_mmio_enabled(struct pci_dev *pdev) | |||
8300 | return PCI_ERS_RESULT_NEED_RESET; | 8808 | return PCI_ERS_RESULT_NEED_RESET; |
8301 | } | 8809 | } |
8302 | 8810 | ||
8303 | /* raid transport support */ | 8811 | /* |
8304 | static struct raid_function_template mpt3sas_raid_functions = { | 8812 | * The pci device ids are defined in mpi/mpi2_cnfg.h. |
8305 | .cookie = &scsih_driver_template, | 8813 | */ |
8306 | .is_raid = _scsih_is_raid, | 8814 | static const struct pci_device_id mpt3sas_pci_table[] = { |
8307 | .get_resync = _scsih_get_resync, | 8815 | /* Spitfire ~ 2004 */ |
8308 | .get_state = _scsih_get_state, | 8816 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004, |
8817 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8818 | /* Falcon ~ 2008 */ | ||
8819 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008, | ||
8820 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8821 | /* Liberator ~ 2108 */ | ||
8822 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1, | ||
8823 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8824 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2, | ||
8825 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8826 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, | ||
8827 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8828 | /* Meteor ~ 2116 */ | ||
8829 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, | ||
8830 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8831 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, | ||
8832 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8833 | /* Thunderbolt ~ 2208 */ | ||
8834 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1, | ||
8835 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8836 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2, | ||
8837 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8838 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3, | ||
8839 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8840 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4, | ||
8841 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8842 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5, | ||
8843 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8844 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6, | ||
8845 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8846 | /* Mustang ~ 2308 */ | ||
8847 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1, | ||
8848 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8849 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2, | ||
8850 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8851 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, | ||
8852 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8853 | /* SSS6200 */ | ||
8854 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, | ||
8855 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8856 | /* Fury ~ 3004 and 3008 */ | ||
8857 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004, | ||
8858 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8859 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008, | ||
8860 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8861 | /* Invader ~ 3108 */ | ||
8862 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1, | ||
8863 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8864 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2, | ||
8865 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8866 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5, | ||
8867 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8868 | { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6, | ||
8869 | PCI_ANY_ID, PCI_ANY_ID }, | ||
8870 | {0} /* Terminating entry */ | ||
8309 | }; | 8871 | }; |
8872 | MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table); | ||
8310 | 8873 | ||
8311 | static struct pci_error_handlers _scsih_err_handler = { | 8874 | static struct pci_error_handlers _mpt3sas_err_handler = { |
8312 | .error_detected = _scsih_pci_error_detected, | 8875 | .error_detected = scsih_pci_error_detected, |
8313 | .mmio_enabled = _scsih_pci_mmio_enabled, | 8876 | .mmio_enabled = scsih_pci_mmio_enabled, |
8314 | .slot_reset = _scsih_pci_slot_reset, | 8877 | .slot_reset = scsih_pci_slot_reset, |
8315 | .resume = _scsih_pci_resume, | 8878 | .resume = scsih_pci_resume, |
8316 | }; | 8879 | }; |
8317 | 8880 | ||
8318 | static struct pci_driver scsih_driver = { | 8881 | static struct pci_driver mpt3sas_driver = { |
8319 | .name = MPT3SAS_DRIVER_NAME, | 8882 | .name = MPT3SAS_DRIVER_NAME, |
8320 | .id_table = scsih_pci_table, | 8883 | .id_table = mpt3sas_pci_table, |
8321 | .probe = _scsih_probe, | 8884 | .probe = _scsih_probe, |
8322 | .remove = _scsih_remove, | 8885 | .remove = scsih_remove, |
8323 | .shutdown = _scsih_shutdown, | 8886 | .shutdown = scsih_shutdown, |
8324 | .err_handler = &_scsih_err_handler, | 8887 | .err_handler = &_mpt3sas_err_handler, |
8325 | #ifdef CONFIG_PM | 8888 | #ifdef CONFIG_PM |
8326 | .suspend = _scsih_suspend, | 8889 | .suspend = scsih_suspend, |
8327 | .resume = _scsih_resume, | 8890 | .resume = scsih_resume, |
8328 | #endif | 8891 | #endif |
8329 | }; | 8892 | }; |
8330 | 8893 | ||
8331 | |||
8332 | /** | 8894 | /** |
8333 | * _scsih_init - main entry point for this driver. | 8895 | * scsih_init - main entry point for this driver. |
8334 | * | 8896 | * |
8335 | * Returns 0 success, anything else error. | 8897 | * Returns 0 success, anything else error. |
8336 | */ | 8898 | */ |
8337 | static int __init | 8899 | int |
8338 | _scsih_init(void) | 8900 | scsih_init(void) |
8339 | { | 8901 | { |
8340 | int error; | 8902 | mpt2_ids = 0; |
8341 | 8903 | mpt3_ids = 0; | |
8342 | mpt_ids = 0; | ||
8343 | |||
8344 | pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME, | ||
8345 | MPT3SAS_DRIVER_VERSION); | ||
8346 | |||
8347 | mpt3sas_transport_template = | ||
8348 | sas_attach_transport(&mpt3sas_transport_functions); | ||
8349 | if (!mpt3sas_transport_template) | ||
8350 | return -ENODEV; | ||
8351 | |||
8352 | /* raid transport support */ | ||
8353 | mpt3sas_raid_template = raid_class_attach(&mpt3sas_raid_functions); | ||
8354 | if (!mpt3sas_raid_template) { | ||
8355 | sas_release_transport(mpt3sas_transport_template); | ||
8356 | return -ENODEV; | ||
8357 | } | ||
8358 | 8904 | ||
8359 | mpt3sas_base_initialize_callback_handler(); | 8905 | mpt3sas_base_initialize_callback_handler(); |
8360 | 8906 | ||
@@ -8392,33 +8938,17 @@ _scsih_init(void) | |||
8392 | tm_sas_control_cb_idx = mpt3sas_base_register_callback_handler( | 8938 | tm_sas_control_cb_idx = mpt3sas_base_register_callback_handler( |
8393 | _scsih_sas_control_complete); | 8939 | _scsih_sas_control_complete); |
8394 | 8940 | ||
8395 | mpt3sas_ctl_init(); | 8941 | return 0; |
8396 | |||
8397 | error = pci_register_driver(&scsih_driver); | ||
8398 | if (error) { | ||
8399 | /* raid transport support */ | ||
8400 | raid_class_release(mpt3sas_raid_template); | ||
8401 | sas_release_transport(mpt3sas_transport_template); | ||
8402 | } | ||
8403 | |||
8404 | return error; | ||
8405 | } | 8942 | } |
8406 | 8943 | ||
8407 | /** | 8944 | /** |
8408 | * _scsih_exit - exit point for this driver (when it is a module). | 8945 | * scsih_exit - exit point for this driver (when it is a module). |
8409 | * | 8946 | * |
8410 | * Returns 0 success, anything else error. | 8947 | * Returns 0 success, anything else error. |
8411 | */ | 8948 | */ |
8412 | static void __exit | 8949 | void |
8413 | _scsih_exit(void) | 8950 | scsih_exit(void) |
8414 | { | 8951 | { |
8415 | pr_info("mpt3sas version %s unloading\n", | ||
8416 | MPT3SAS_DRIVER_VERSION); | ||
8417 | |||
8418 | mpt3sas_ctl_exit(); | ||
8419 | |||
8420 | pci_unregister_driver(&scsih_driver); | ||
8421 | |||
8422 | 8952 | ||
8423 | mpt3sas_base_release_callback_handler(scsi_io_cb_idx); | 8953 | mpt3sas_base_release_callback_handler(scsi_io_cb_idx); |
8424 | mpt3sas_base_release_callback_handler(tm_cb_idx); | 8954 | mpt3sas_base_release_callback_handler(tm_cb_idx); |
@@ -8434,9 +8964,86 @@ _scsih_exit(void) | |||
8434 | mpt3sas_base_release_callback_handler(tm_sas_control_cb_idx); | 8964 | mpt3sas_base_release_callback_handler(tm_sas_control_cb_idx); |
8435 | 8965 | ||
8436 | /* raid transport support */ | 8966 | /* raid transport support */ |
8437 | raid_class_release(mpt3sas_raid_template); | 8967 | if (hbas_to_enumerate != 1) |
8968 | raid_class_release(mpt3sas_raid_template); | ||
8969 | if (hbas_to_enumerate != 2) | ||
8970 | raid_class_release(mpt2sas_raid_template); | ||
8438 | sas_release_transport(mpt3sas_transport_template); | 8971 | sas_release_transport(mpt3sas_transport_template); |
8439 | } | 8972 | } |
8440 | 8973 | ||
8441 | module_init(_scsih_init); | 8974 | /** |
8442 | module_exit(_scsih_exit); | 8975 | * _mpt3sas_init - main entry point for this driver. |
8976 | * | ||
8977 | * Returns 0 success, anything else error. | ||
8978 | */ | ||
8979 | static int __init | ||
8980 | _mpt3sas_init(void) | ||
8981 | { | ||
8982 | int error; | ||
8983 | |||
8984 | pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME, | ||
8985 | MPT3SAS_DRIVER_VERSION); | ||
8986 | |||
8987 | mpt3sas_transport_template = | ||
8988 | sas_attach_transport(&mpt3sas_transport_functions); | ||
8989 | if (!mpt3sas_transport_template) | ||
8990 | return -ENODEV; | ||
8991 | |||
8992 | /* No need attach mpt3sas raid functions template | ||
8993 | * if hbas_to_enumarate value is one. | ||
8994 | */ | ||
8995 | if (hbas_to_enumerate != 1) { | ||
8996 | mpt3sas_raid_template = | ||
8997 | raid_class_attach(&mpt3sas_raid_functions); | ||
8998 | if (!mpt3sas_raid_template) { | ||
8999 | sas_release_transport(mpt3sas_transport_template); | ||
9000 | return -ENODEV; | ||
9001 | } | ||
9002 | } | ||
9003 | |||
9004 | /* No need to attach mpt2sas raid functions template | ||
9005 | * if hbas_to_enumarate value is two | ||
9006 | */ | ||
9007 | if (hbas_to_enumerate != 2) { | ||
9008 | mpt2sas_raid_template = | ||
9009 | raid_class_attach(&mpt2sas_raid_functions); | ||
9010 | if (!mpt2sas_raid_template) { | ||
9011 | sas_release_transport(mpt3sas_transport_template); | ||
9012 | return -ENODEV; | ||
9013 | } | ||
9014 | } | ||
9015 | |||
9016 | error = scsih_init(); | ||
9017 | if (error) { | ||
9018 | scsih_exit(); | ||
9019 | return error; | ||
9020 | } | ||
9021 | |||
9022 | mpt3sas_ctl_init(hbas_to_enumerate); | ||
9023 | |||
9024 | error = pci_register_driver(&mpt3sas_driver); | ||
9025 | if (error) | ||
9026 | scsih_exit(); | ||
9027 | |||
9028 | return error; | ||
9029 | } | ||
9030 | |||
9031 | /** | ||
9032 | * _mpt3sas_exit - exit point for this driver (when it is a module). | ||
9033 | * | ||
9034 | */ | ||
9035 | static void __exit | ||
9036 | _mpt3sas_exit(void) | ||
9037 | { | ||
9038 | pr_info("mpt3sas version %s unloading\n", | ||
9039 | MPT3SAS_DRIVER_VERSION); | ||
9040 | |||
9041 | pci_unregister_driver(&mpt3sas_driver); | ||
9042 | |||
9043 | mpt3sas_ctl_exit(hbas_to_enumerate); | ||
9044 | |||
9045 | scsih_exit(); | ||
9046 | } | ||
9047 | |||
9048 | module_init(_mpt3sas_init); | ||
9049 | module_exit(_mpt3sas_exit); | ||