diff options
author | Suganath Prabu Subramani <suganath-prabu.subramani@broadcom.com> | 2017-10-31 08:32:27 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-11-03 12:20:52 -0400 |
commit | d88e1eaba6eee7bfe10480e575b33ab8a3a68e77 (patch) | |
tree | 4acf7532d2b1fe9b838a48ddf13d1fd6de0a489b | |
parent | b5c5d0adf75cd4c0fb037ba2ca0ed80ae9ba3d05 (diff) |
scsi: mpt3sas: Add nvme device support in slave alloc, target alloc and probe
1) Added support for probing pcie device and adding NVMe drives to SML
and driver's internal list pcie_device_list.
2) Added support for determing NVMe as boot device.
3) Added nvme device support for call back functions scan_finished
target_alloc,slave_alloc,target destroy and slave destroy.
a) During scan, pcie devices are probed and added to SML to drivers
internal list.
b) target_alloc & slave alloc API's allocates resources for
(MPT3SAS_TARGET & MPT3SAS_DEVICE) private datas and holds information
like handle, target_id etc.
c) slave_destroy & target_destroy are called when driver unregisters
or removes device. Also frees allocated resources and info.
Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.h | 110 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_scsih.c | 430 |
2 files changed, 506 insertions, 34 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 0fe3969dd8e7..bafa90ab916c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -161,6 +161,7 @@ | |||
161 | #define MPT_TARGET_FLAGS_VOLUME 0x02 | 161 | #define MPT_TARGET_FLAGS_VOLUME 0x02 |
162 | #define MPT_TARGET_FLAGS_DELETED 0x04 | 162 | #define MPT_TARGET_FLAGS_DELETED 0x04 |
163 | #define MPT_TARGET_FASTPATH_IO 0x08 | 163 | #define MPT_TARGET_FASTPATH_IO 0x08 |
164 | #define MPT_TARGET_FLAGS_PCIE_DEVICE 0x10 | ||
164 | 165 | ||
165 | #define SAS2_PCI_DEVICE_B0_REVISION (0x01) | 166 | #define SAS2_PCI_DEVICE_B0_REVISION (0x01) |
166 | #define SAS3_PCI_DEVICE_C0_REVISION (0x02) | 167 | #define SAS3_PCI_DEVICE_C0_REVISION (0x02) |
@@ -359,7 +360,8 @@ struct Mpi2ManufacturingPage11_t { | |||
359 | * @flags: MPT_TARGET_FLAGS_XXX flags | 360 | * @flags: MPT_TARGET_FLAGS_XXX flags |
360 | * @deleted: target flaged for deletion | 361 | * @deleted: target flaged for deletion |
361 | * @tm_busy: target is busy with TM request. | 362 | * @tm_busy: target is busy with TM request. |
362 | * @sdev: The sas_device associated with this target | 363 | * @sas_dev: The sas_device associated with this target |
364 | * @pcie_dev: The pcie device associated with this target | ||
363 | */ | 365 | */ |
364 | struct MPT3SAS_TARGET { | 366 | struct MPT3SAS_TARGET { |
365 | struct scsi_target *starget; | 367 | struct scsi_target *starget; |
@@ -370,7 +372,8 @@ struct MPT3SAS_TARGET { | |||
370 | u32 flags; | 372 | u32 flags; |
371 | u8 deleted; | 373 | u8 deleted; |
372 | u8 tm_busy; | 374 | u8 tm_busy; |
373 | struct _sas_device *sdev; | 375 | struct _sas_device *sas_dev; |
376 | struct _pcie_device *pcie_dev; | ||
374 | }; | 377 | }; |
375 | 378 | ||
376 | 379 | ||
@@ -514,6 +517,89 @@ static inline void sas_device_put(struct _sas_device *s) | |||
514 | kref_put(&s->refcount, sas_device_free); | 517 | kref_put(&s->refcount, sas_device_free); |
515 | } | 518 | } |
516 | 519 | ||
520 | /* | ||
521 | * struct _pcie_device - attached PCIe device information | ||
522 | * @list: pcie device list | ||
523 | * @starget: starget object | ||
524 | * @wwid: device WWID | ||
525 | * @handle: device handle | ||
526 | * @device_info: bitfield provides detailed info about the device | ||
527 | * @id: target id | ||
528 | * @channel: target channel | ||
529 | * @slot: slot number | ||
530 | * @port_num: port number | ||
531 | * @responding: used in _scsih_pcie_device_mark_responding | ||
532 | * @fast_path: fast path feature enable bit | ||
533 | * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for | ||
534 | * NVMe device only | ||
535 | * @enclosure_handle: enclosure handle | ||
536 | * @enclosure_logical_id: enclosure logical identifier | ||
537 | * @enclosure_level: The level of device's enclosure from the controller | ||
538 | * @connector_name: ASCII value of the Connector's name | ||
539 | * @serial_number: pointer of serial number string allocated runtime | ||
540 | * @refcount: reference count for deletion | ||
541 | */ | ||
542 | struct _pcie_device { | ||
543 | struct list_head list; | ||
544 | struct scsi_target *starget; | ||
545 | u64 wwid; | ||
546 | u16 handle; | ||
547 | u32 device_info; | ||
548 | int id; | ||
549 | int channel; | ||
550 | u16 slot; | ||
551 | u8 port_num; | ||
552 | u8 responding; | ||
553 | u8 fast_path; | ||
554 | u32 nvme_mdts; | ||
555 | u16 enclosure_handle; | ||
556 | u64 enclosure_logical_id; | ||
557 | u8 enclosure_level; | ||
558 | u8 connector_name[4]; | ||
559 | u8 *serial_number; | ||
560 | struct kref refcount; | ||
561 | }; | ||
562 | /** | ||
563 | * pcie_device_get - Increment the pcie device reference count | ||
564 | * | ||
565 | * @p: pcie_device object | ||
566 | * | ||
567 | * When ever this function called it will increment the | ||
568 | * reference count of the pcie device for which this function called. | ||
569 | * | ||
570 | */ | ||
571 | static inline void pcie_device_get(struct _pcie_device *p) | ||
572 | { | ||
573 | kref_get(&p->refcount); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * pcie_device_free - Release the pcie device object | ||
578 | * @r - kref object | ||
579 | * | ||
580 | * Free's the pcie device object. It will be called when reference count | ||
581 | * reaches to zero. | ||
582 | */ | ||
583 | static inline void pcie_device_free(struct kref *r) | ||
584 | { | ||
585 | kfree(container_of(r, struct _pcie_device, refcount)); | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * pcie_device_put - Decrement the pcie device reference count | ||
590 | * | ||
591 | * @p: pcie_device object | ||
592 | * | ||
593 | * When ever this function called it will decrement the | ||
594 | * reference count of the pcie device for which this function called. | ||
595 | * | ||
596 | * When refernce count reaches to Zero, this will call pcie_device_free to the | ||
597 | * pcie_device object. | ||
598 | */ | ||
599 | static inline void pcie_device_put(struct _pcie_device *p) | ||
600 | { | ||
601 | kref_put(&p->refcount, pcie_device_free); | ||
602 | } | ||
517 | /** | 603 | /** |
518 | * struct _raid_device - raid volume link list | 604 | * struct _raid_device - raid volume link list |
519 | * @list: sas device list | 605 | * @list: sas device list |
@@ -562,12 +648,13 @@ struct _raid_device { | |||
562 | 648 | ||
563 | /** | 649 | /** |
564 | * struct _boot_device - boot device info | 650 | * struct _boot_device - boot device info |
565 | * @is_raid: flag to indicate whether this is volume | 651 | * |
566 | * @device: holds pointer for either struct _sas_device or | 652 | * @channel: sas, raid, or pcie channel |
567 | * struct _raid_device | 653 | * @device: holds pointer for struct _sas_device, struct _raid_device or |
654 | * struct _pcie_device | ||
568 | */ | 655 | */ |
569 | struct _boot_device { | 656 | struct _boot_device { |
570 | u8 is_raid; | 657 | int channel; |
571 | void *device; | 658 | void *device; |
572 | }; | 659 | }; |
573 | 660 | ||
@@ -831,6 +918,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); | |||
831 | * @bars: bitmask of BAR's that must be configured | 918 | * @bars: bitmask of BAR's that must be configured |
832 | * @mask_interrupts: ignore interrupt | 919 | * @mask_interrupts: ignore interrupt |
833 | * @dma_mask: used to set the consistent dma mask | 920 | * @dma_mask: used to set the consistent dma mask |
921 | * @pci_access_mutex: Mutex to synchronize ioctl, sysfs show path and | ||
922 | * pci resource handling | ||
834 | * @fault_reset_work_q_name: fw fault work queue | 923 | * @fault_reset_work_q_name: fw fault work queue |
835 | * @fault_reset_work_q: "" | 924 | * @fault_reset_work_q: "" |
836 | * @fault_reset_work: "" | 925 | * @fault_reset_work: "" |
@@ -894,9 +983,13 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); | |||
894 | * @sas_device_list: sas device object list | 983 | * @sas_device_list: sas device object list |
895 | * @sas_device_init_list: sas device object list (used only at init time) | 984 | * @sas_device_init_list: sas device object list (used only at init time) |
896 | * @sas_device_lock: | 985 | * @sas_device_lock: |
986 | * @pcie_device_list: pcie device object list | ||
987 | * @pcie_device_init_list: pcie device object list (used only at init time) | ||
988 | * @pcie_device_lock: | ||
897 | * @io_missing_delay: time for IO completed by fw when PDR enabled | 989 | * @io_missing_delay: time for IO completed by fw when PDR enabled |
898 | * @device_missing_delay: time for device missing by fw when PDR enabled | 990 | * @device_missing_delay: time for device missing by fw when PDR enabled |
899 | * @sas_id : used for setting volume target IDs | 991 | * @sas_id : used for setting volume target IDs |
992 | * @pcie_target_id: used for setting pcie target IDs | ||
900 | * @blocking_handles: bitmask used to identify which devices need blocking | 993 | * @blocking_handles: bitmask used to identify which devices need blocking |
901 | * @pd_handles : bitmask for PD handles | 994 | * @pd_handles : bitmask for PD handles |
902 | * @pd_handles_sz : size of pd_handle bitmask | 995 | * @pd_handles_sz : size of pd_handle bitmask |
@@ -1092,11 +1185,16 @@ struct MPT3SAS_ADAPTER { | |||
1092 | struct list_head sas_device_list; | 1185 | struct list_head sas_device_list; |
1093 | struct list_head sas_device_init_list; | 1186 | struct list_head sas_device_init_list; |
1094 | spinlock_t sas_device_lock; | 1187 | spinlock_t sas_device_lock; |
1188 | struct list_head pcie_device_list; | ||
1189 | struct list_head pcie_device_init_list; | ||
1190 | spinlock_t pcie_device_lock; | ||
1191 | |||
1095 | struct list_head raid_device_list; | 1192 | struct list_head raid_device_list; |
1096 | spinlock_t raid_device_lock; | 1193 | spinlock_t raid_device_lock; |
1097 | u8 io_missing_delay; | 1194 | u8 io_missing_delay; |
1098 | u16 device_missing_delay; | 1195 | u16 device_missing_delay; |
1099 | int sas_id; | 1196 | int sas_id; |
1197 | int pcie_target_id; | ||
1100 | 1198 | ||
1101 | void *blocking_handles; | 1199 | void *blocking_handles; |
1102 | void *pd_handles; | 1200 | void *pd_handles; |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index dee83082b5a6..c86399759705 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -60,6 +60,9 @@ | |||
60 | #include "mpt3sas_base.h" | 60 | #include "mpt3sas_base.h" |
61 | 61 | ||
62 | #define RAID_CHANNEL 1 | 62 | #define RAID_CHANNEL 1 |
63 | |||
64 | #define PCIE_CHANNEL 2 | ||
65 | |||
63 | /* forward proto's */ | 66 | /* forward proto's */ |
64 | static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, | 67 | static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, |
65 | struct _sas_node *sas_expander); | 68 | struct _sas_node *sas_expander); |
@@ -442,21 +445,22 @@ _scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |||
442 | /** | 445 | /** |
443 | * _scsih_determine_boot_device - determine boot device. | 446 | * _scsih_determine_boot_device - determine boot device. |
444 | * @ioc: per adapter object | 447 | * @ioc: per adapter object |
445 | * @device: either sas_device or raid_device object | 448 | * @device: sas_device or pcie_device object |
446 | * @is_raid: [flag] 1 = raid object, 0 = sas object | 449 | * @channel: SAS or PCIe channel |
447 | * | 450 | * |
448 | * Determines whether this device should be first reported device to | 451 | * Determines whether this device should be first reported device to |
449 | * to scsi-ml or sas transport, this purpose is for persistent boot device. | 452 | * to scsi-ml or sas transport, this purpose is for persistent boot device. |
450 | * There are primary, alternate, and current entries in bios page 2. The order | 453 | * There are primary, alternate, and current entries in bios page 2. The order |
451 | * priority is primary, alternate, then current. This routine saves | 454 | * priority is primary, alternate, then current. This routine saves |
452 | * the corresponding device object and is_raid flag in the ioc object. | 455 | * the corresponding device object. |
453 | * The saved data to be used later in _scsih_probe_boot_devices(). | 456 | * The saved data to be used later in _scsih_probe_boot_devices(). |
454 | */ | 457 | */ |
455 | static void | 458 | static void |
456 | _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | 459 | _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, void *device, |
457 | void *device, u8 is_raid) | 460 | u32 channel) |
458 | { | 461 | { |
459 | struct _sas_device *sas_device; | 462 | struct _sas_device *sas_device; |
463 | struct _pcie_device *pcie_device; | ||
460 | struct _raid_device *raid_device; | 464 | struct _raid_device *raid_device; |
461 | u64 sas_address; | 465 | u64 sas_address; |
462 | u64 device_name; | 466 | u64 device_name; |
@@ -471,18 +475,24 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | |||
471 | if (!ioc->bios_pg3.BiosVersion) | 475 | if (!ioc->bios_pg3.BiosVersion) |
472 | return; | 476 | return; |
473 | 477 | ||
474 | if (!is_raid) { | 478 | if (channel == RAID_CHANNEL) { |
475 | sas_device = device; | ||
476 | sas_address = sas_device->sas_address; | ||
477 | device_name = sas_device->device_name; | ||
478 | enclosure_logical_id = sas_device->enclosure_logical_id; | ||
479 | slot = sas_device->slot; | ||
480 | } else { | ||
481 | raid_device = device; | 479 | raid_device = device; |
482 | sas_address = raid_device->wwid; | 480 | sas_address = raid_device->wwid; |
483 | device_name = 0; | 481 | device_name = 0; |
484 | enclosure_logical_id = 0; | 482 | enclosure_logical_id = 0; |
485 | slot = 0; | 483 | slot = 0; |
484 | } else if (channel == PCIE_CHANNEL) { | ||
485 | pcie_device = device; | ||
486 | sas_address = pcie_device->wwid; | ||
487 | device_name = 0; | ||
488 | enclosure_logical_id = 0; | ||
489 | slot = 0; | ||
490 | } else { | ||
491 | sas_device = device; | ||
492 | sas_address = sas_device->sas_address; | ||
493 | device_name = sas_device->device_name; | ||
494 | enclosure_logical_id = sas_device->enclosure_logical_id; | ||
495 | slot = sas_device->slot; | ||
486 | } | 496 | } |
487 | 497 | ||
488 | if (!ioc->req_boot_device.device) { | 498 | if (!ioc->req_boot_device.device) { |
@@ -496,7 +506,7 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | |||
496 | ioc->name, __func__, | 506 | ioc->name, __func__, |
497 | (unsigned long long)sas_address)); | 507 | (unsigned long long)sas_address)); |
498 | ioc->req_boot_device.device = device; | 508 | ioc->req_boot_device.device = device; |
499 | ioc->req_boot_device.is_raid = is_raid; | 509 | ioc->req_boot_device.channel = channel; |
500 | } | 510 | } |
501 | } | 511 | } |
502 | 512 | ||
@@ -511,7 +521,7 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | |||
511 | ioc->name, __func__, | 521 | ioc->name, __func__, |
512 | (unsigned long long)sas_address)); | 522 | (unsigned long long)sas_address)); |
513 | ioc->req_alt_boot_device.device = device; | 523 | ioc->req_alt_boot_device.device = device; |
514 | ioc->req_alt_boot_device.is_raid = is_raid; | 524 | ioc->req_alt_boot_device.channel = channel; |
515 | } | 525 | } |
516 | } | 526 | } |
517 | 527 | ||
@@ -526,7 +536,7 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, | |||
526 | ioc->name, __func__, | 536 | ioc->name, __func__, |
527 | (unsigned long long)sas_address)); | 537 | (unsigned long long)sas_address)); |
528 | ioc->current_boot_device.device = device; | 538 | ioc->current_boot_device.device = device; |
529 | ioc->current_boot_device.is_raid = is_raid; | 539 | ioc->current_boot_device.channel = channel; |
530 | } | 540 | } |
531 | } | 541 | } |
532 | } | 542 | } |
@@ -539,7 +549,7 @@ __mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, | |||
539 | 549 | ||
540 | assert_spin_locked(&ioc->sas_device_lock); | 550 | assert_spin_locked(&ioc->sas_device_lock); |
541 | 551 | ||
542 | ret = tgt_priv->sdev; | 552 | ret = tgt_priv->sas_dev; |
543 | if (ret) | 553 | if (ret) |
544 | sas_device_get(ret); | 554 | sas_device_get(ret); |
545 | 555 | ||
@@ -560,6 +570,44 @@ mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, | |||
560 | return ret; | 570 | return ret; |
561 | } | 571 | } |
562 | 572 | ||
573 | static struct _pcie_device * | ||
574 | __mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc, | ||
575 | struct MPT3SAS_TARGET *tgt_priv) | ||
576 | { | ||
577 | struct _pcie_device *ret; | ||
578 | |||
579 | assert_spin_locked(&ioc->pcie_device_lock); | ||
580 | |||
581 | ret = tgt_priv->pcie_dev; | ||
582 | if (ret) | ||
583 | pcie_device_get(ret); | ||
584 | |||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * mpt3sas_get_pdev_from_target - pcie device search | ||
590 | * @ioc: per adapter object | ||
591 | * @tgt_priv: starget private object | ||
592 | * | ||
593 | * Context: This function will acquire ioc->pcie_device_lock and will release | ||
594 | * before returning the pcie_device object. | ||
595 | * | ||
596 | * This searches for pcie_device from target, then return pcie_device object. | ||
597 | */ | ||
598 | struct _pcie_device * | ||
599 | mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc, | ||
600 | struct MPT3SAS_TARGET *tgt_priv) | ||
601 | { | ||
602 | struct _pcie_device *ret; | ||
603 | unsigned long flags; | ||
604 | |||
605 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
606 | ret = __mpt3sas_get_pdev_from_target(ioc, tgt_priv); | ||
607 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
608 | |||
609 | return ret; | ||
610 | } | ||
563 | 611 | ||
564 | struct _sas_device * | 612 | struct _sas_device * |
565 | __mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, | 613 | __mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, |
@@ -889,6 +937,146 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc, | |||
889 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 937 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
890 | } | 938 | } |
891 | 939 | ||
940 | |||
941 | struct _pcie_device * | ||
942 | __mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid) | ||
943 | { | ||
944 | struct _pcie_device *pcie_device; | ||
945 | |||
946 | assert_spin_locked(&ioc->pcie_device_lock); | ||
947 | |||
948 | list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) | ||
949 | if (pcie_device->wwid == wwid) | ||
950 | goto found_device; | ||
951 | |||
952 | list_for_each_entry(pcie_device, &ioc->pcie_device_init_list, list) | ||
953 | if (pcie_device->wwid == wwid) | ||
954 | goto found_device; | ||
955 | |||
956 | return NULL; | ||
957 | |||
958 | found_device: | ||
959 | pcie_device_get(pcie_device); | ||
960 | return pcie_device; | ||
961 | } | ||
962 | |||
963 | |||
964 | /** | ||
965 | * mpt3sas_get_pdev_by_wwid - pcie device search | ||
966 | * @ioc: per adapter object | ||
967 | * @wwid: wwid | ||
968 | * | ||
969 | * Context: This function will acquire ioc->pcie_device_lock and will release | ||
970 | * before returning the pcie_device object. | ||
971 | * | ||
972 | * This searches for pcie_device based on wwid, then return pcie_device object. | ||
973 | */ | ||
974 | struct _pcie_device * | ||
975 | mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid) | ||
976 | { | ||
977 | struct _pcie_device *pcie_device; | ||
978 | unsigned long flags; | ||
979 | |||
980 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
981 | pcie_device = __mpt3sas_get_pdev_by_wwid(ioc, wwid); | ||
982 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
983 | |||
984 | return pcie_device; | ||
985 | } | ||
986 | |||
987 | |||
988 | struct _pcie_device * | ||
989 | __mpt3sas_get_pdev_by_idchannel(struct MPT3SAS_ADAPTER *ioc, int id, | ||
990 | int channel) | ||
991 | { | ||
992 | struct _pcie_device *pcie_device; | ||
993 | |||
994 | assert_spin_locked(&ioc->pcie_device_lock); | ||
995 | |||
996 | list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) | ||
997 | if (pcie_device->id == id && pcie_device->channel == channel) | ||
998 | goto found_device; | ||
999 | |||
1000 | list_for_each_entry(pcie_device, &ioc->pcie_device_init_list, list) | ||
1001 | if (pcie_device->id == id && pcie_device->channel == channel) | ||
1002 | goto found_device; | ||
1003 | |||
1004 | return NULL; | ||
1005 | |||
1006 | found_device: | ||
1007 | pcie_device_get(pcie_device); | ||
1008 | return pcie_device; | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | /** | ||
1013 | * mpt3sas_get_pdev_by_idchannel - pcie device search | ||
1014 | * @ioc: per adapter object | ||
1015 | * @id: Target ID | ||
1016 | * @channel: Channel ID | ||
1017 | * | ||
1018 | * Context: This function will acquire ioc->pcie_device_lock and will release | ||
1019 | * before returning the pcie_device object. | ||
1020 | * | ||
1021 | * This searches for pcie_device based on id and channel, then return | ||
1022 | * pcie_device object. | ||
1023 | */ | ||
1024 | struct _pcie_device * | ||
1025 | mpt3sas_get_pdev_by_idchannel(struct MPT3SAS_ADAPTER *ioc, int id, int channel) | ||
1026 | { | ||
1027 | struct _pcie_device *pcie_device; | ||
1028 | unsigned long flags; | ||
1029 | |||
1030 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
1031 | pcie_device = __mpt3sas_get_pdev_by_idchannel(ioc, id, channel); | ||
1032 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
1033 | |||
1034 | return pcie_device; | ||
1035 | } | ||
1036 | /** | ||
1037 | * _scsih_pcie_device_remove - remove pcie_device from list. | ||
1038 | * @ioc: per adapter object | ||
1039 | * @pcie_device: the pcie_device object | ||
1040 | * Context: This function will acquire ioc->pcie_device_lock. | ||
1041 | * | ||
1042 | * If pcie_device is on the list, remove it and decrement its reference count. | ||
1043 | */ | ||
1044 | static void | ||
1045 | _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc, | ||
1046 | struct _pcie_device *pcie_device) | ||
1047 | { | ||
1048 | unsigned long flags; | ||
1049 | int was_on_pcie_device_list = 0; | ||
1050 | |||
1051 | if (!pcie_device) | ||
1052 | return; | ||
1053 | pr_info(MPT3SAS_FMT | ||
1054 | "removing handle(0x%04x), wwid(0x%016llx)\n", | ||
1055 | ioc->name, pcie_device->handle, | ||
1056 | (unsigned long long) pcie_device->wwid); | ||
1057 | if (pcie_device->enclosure_handle != 0) | ||
1058 | pr_info(MPT3SAS_FMT | ||
1059 | "removing enclosure logical id(0x%016llx), slot(%d)\n", | ||
1060 | ioc->name, | ||
1061 | (unsigned long long)pcie_device->enclosure_logical_id, | ||
1062 | pcie_device->slot); | ||
1063 | if (pcie_device->connector_name[0] != '\0') | ||
1064 | pr_info(MPT3SAS_FMT | ||
1065 | "removing enclosure level(0x%04x), connector name( %s)\n", | ||
1066 | ioc->name, pcie_device->enclosure_level, | ||
1067 | pcie_device->connector_name); | ||
1068 | |||
1069 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
1070 | if (!list_empty(&pcie_device->list)) { | ||
1071 | list_del_init(&pcie_device->list); | ||
1072 | was_on_pcie_device_list = 1; | ||
1073 | } | ||
1074 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
1075 | if (was_on_pcie_device_list) { | ||
1076 | kfree(pcie_device->serial_number); | ||
1077 | pcie_device_put(pcie_device); | ||
1078 | } | ||
1079 | } | ||
892 | /** | 1080 | /** |
893 | * _scsih_raid_device_find_by_id - raid device search | 1081 | * _scsih_raid_device_find_by_id - raid device search |
894 | * @ioc: per adapter object | 1082 | * @ioc: per adapter object |
@@ -1316,6 +1504,7 @@ scsih_target_alloc(struct scsi_target *starget) | |||
1316 | struct MPT3SAS_TARGET *sas_target_priv_data; | 1504 | struct MPT3SAS_TARGET *sas_target_priv_data; |
1317 | struct _sas_device *sas_device; | 1505 | struct _sas_device *sas_device; |
1318 | struct _raid_device *raid_device; | 1506 | struct _raid_device *raid_device; |
1507 | struct _pcie_device *pcie_device; | ||
1319 | unsigned long flags; | 1508 | unsigned long flags; |
1320 | struct sas_rphy *rphy; | 1509 | struct sas_rphy *rphy; |
1321 | 1510 | ||
@@ -1345,6 +1534,28 @@ scsih_target_alloc(struct scsi_target *starget) | |||
1345 | return 0; | 1534 | return 0; |
1346 | } | 1535 | } |
1347 | 1536 | ||
1537 | /* PCIe devices */ | ||
1538 | if (starget->channel == PCIE_CHANNEL) { | ||
1539 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
1540 | pcie_device = __mpt3sas_get_pdev_by_idchannel(ioc, starget->id, | ||
1541 | starget->channel); | ||
1542 | if (pcie_device) { | ||
1543 | sas_target_priv_data->handle = pcie_device->handle; | ||
1544 | sas_target_priv_data->sas_address = pcie_device->wwid; | ||
1545 | sas_target_priv_data->pcie_dev = pcie_device; | ||
1546 | pcie_device->starget = starget; | ||
1547 | pcie_device->id = starget->id; | ||
1548 | pcie_device->channel = starget->channel; | ||
1549 | sas_target_priv_data->flags |= | ||
1550 | MPT_TARGET_FLAGS_PCIE_DEVICE; | ||
1551 | if (pcie_device->fast_path) | ||
1552 | sas_target_priv_data->flags |= | ||
1553 | MPT_TARGET_FASTPATH_IO; | ||
1554 | } | ||
1555 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
1556 | return 0; | ||
1557 | } | ||
1558 | |||
1348 | /* sas/sata devices */ | 1559 | /* sas/sata devices */ |
1349 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1560 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1350 | rphy = dev_to_rphy(starget->dev.parent); | 1561 | rphy = dev_to_rphy(starget->dev.parent); |
@@ -1354,7 +1565,7 @@ scsih_target_alloc(struct scsi_target *starget) | |||
1354 | if (sas_device) { | 1565 | if (sas_device) { |
1355 | sas_target_priv_data->handle = sas_device->handle; | 1566 | sas_target_priv_data->handle = sas_device->handle; |
1356 | sas_target_priv_data->sas_address = sas_device->sas_address; | 1567 | sas_target_priv_data->sas_address = sas_device->sas_address; |
1357 | sas_target_priv_data->sdev = sas_device; | 1568 | sas_target_priv_data->sas_dev = sas_device; |
1358 | sas_device->starget = starget; | 1569 | sas_device->starget = starget; |
1359 | sas_device->id = starget->id; | 1570 | sas_device->id = starget->id; |
1360 | sas_device->channel = starget->channel; | 1571 | sas_device->channel = starget->channel; |
@@ -1362,7 +1573,8 @@ scsih_target_alloc(struct scsi_target *starget) | |||
1362 | sas_target_priv_data->flags |= | 1573 | sas_target_priv_data->flags |= |
1363 | MPT_TARGET_FLAGS_RAID_COMPONENT; | 1574 | MPT_TARGET_FLAGS_RAID_COMPONENT; |
1364 | if (sas_device->fast_path) | 1575 | if (sas_device->fast_path) |
1365 | sas_target_priv_data->flags |= MPT_TARGET_FASTPATH_IO; | 1576 | sas_target_priv_data->flags |= |
1577 | MPT_TARGET_FASTPATH_IO; | ||
1366 | } | 1578 | } |
1367 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1579 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1368 | 1580 | ||
@@ -1383,7 +1595,9 @@ scsih_target_destroy(struct scsi_target *starget) | |||
1383 | struct MPT3SAS_TARGET *sas_target_priv_data; | 1595 | struct MPT3SAS_TARGET *sas_target_priv_data; |
1384 | struct _sas_device *sas_device; | 1596 | struct _sas_device *sas_device; |
1385 | struct _raid_device *raid_device; | 1597 | struct _raid_device *raid_device; |
1598 | struct _pcie_device *pcie_device; | ||
1386 | unsigned long flags; | 1599 | unsigned long flags; |
1600 | struct sas_rphy *rphy; | ||
1387 | 1601 | ||
1388 | sas_target_priv_data = starget->hostdata; | 1602 | sas_target_priv_data = starget->hostdata; |
1389 | if (!sas_target_priv_data) | 1603 | if (!sas_target_priv_data) |
@@ -1401,7 +1615,29 @@ scsih_target_destroy(struct scsi_target *starget) | |||
1401 | goto out; | 1615 | goto out; |
1402 | } | 1616 | } |
1403 | 1617 | ||
1618 | if (starget->channel == PCIE_CHANNEL) { | ||
1619 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
1620 | pcie_device = __mpt3sas_get_pdev_from_target(ioc, | ||
1621 | sas_target_priv_data); | ||
1622 | if (pcie_device && (pcie_device->starget == starget) && | ||
1623 | (pcie_device->id == starget->id) && | ||
1624 | (pcie_device->channel == starget->channel)) | ||
1625 | pcie_device->starget = NULL; | ||
1626 | |||
1627 | if (pcie_device) { | ||
1628 | /* | ||
1629 | * Corresponding get() is in _scsih_target_alloc() | ||
1630 | */ | ||
1631 | sas_target_priv_data->pcie_dev = NULL; | ||
1632 | pcie_device_put(pcie_device); | ||
1633 | pcie_device_put(pcie_device); | ||
1634 | } | ||
1635 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
1636 | goto out; | ||
1637 | } | ||
1638 | |||
1404 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1639 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1640 | rphy = dev_to_rphy(starget->dev.parent); | ||
1405 | sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data); | 1641 | sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data); |
1406 | if (sas_device && (sas_device->starget == starget) && | 1642 | if (sas_device && (sas_device->starget == starget) && |
1407 | (sas_device->id == starget->id) && | 1643 | (sas_device->id == starget->id) && |
@@ -1412,7 +1648,7 @@ scsih_target_destroy(struct scsi_target *starget) | |||
1412 | /* | 1648 | /* |
1413 | * Corresponding get() is in _scsih_target_alloc() | 1649 | * Corresponding get() is in _scsih_target_alloc() |
1414 | */ | 1650 | */ |
1415 | sas_target_priv_data->sdev = NULL; | 1651 | sas_target_priv_data->sas_dev = NULL; |
1416 | sas_device_put(sas_device); | 1652 | sas_device_put(sas_device); |
1417 | 1653 | ||
1418 | sas_device_put(sas_device); | 1654 | sas_device_put(sas_device); |
@@ -1441,6 +1677,7 @@ scsih_slave_alloc(struct scsi_device *sdev) | |||
1441 | struct scsi_target *starget; | 1677 | struct scsi_target *starget; |
1442 | struct _raid_device *raid_device; | 1678 | struct _raid_device *raid_device; |
1443 | struct _sas_device *sas_device; | 1679 | struct _sas_device *sas_device; |
1680 | struct _pcie_device *pcie_device; | ||
1444 | unsigned long flags; | 1681 | unsigned long flags; |
1445 | 1682 | ||
1446 | sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data), | 1683 | sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data), |
@@ -1469,8 +1706,22 @@ scsih_slave_alloc(struct scsi_device *sdev) | |||
1469 | raid_device->sdev = sdev; /* raid is single lun */ | 1706 | raid_device->sdev = sdev; /* raid is single lun */ |
1470 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1707 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1471 | } | 1708 | } |
1709 | if (starget->channel == PCIE_CHANNEL) { | ||
1710 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
1711 | pcie_device = __mpt3sas_get_pdev_by_wwid(ioc, | ||
1712 | sas_target_priv_data->sas_address); | ||
1713 | if (pcie_device && (pcie_device->starget == NULL)) { | ||
1714 | sdev_printk(KERN_INFO, sdev, | ||
1715 | "%s : pcie_device->starget set to starget @ %d\n", | ||
1716 | __func__, __LINE__); | ||
1717 | pcie_device->starget = starget; | ||
1718 | } | ||
1719 | |||
1720 | if (pcie_device) | ||
1721 | pcie_device_put(pcie_device); | ||
1722 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
1472 | 1723 | ||
1473 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | 1724 | } else if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { |
1474 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1725 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1475 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, | 1726 | sas_device = __mpt3sas_get_sdev_by_addr(ioc, |
1476 | sas_target_priv_data->sas_address); | 1727 | sas_target_priv_data->sas_address); |
@@ -1504,6 +1755,7 @@ scsih_slave_destroy(struct scsi_device *sdev) | |||
1504 | struct Scsi_Host *shost; | 1755 | struct Scsi_Host *shost; |
1505 | struct MPT3SAS_ADAPTER *ioc; | 1756 | struct MPT3SAS_ADAPTER *ioc; |
1506 | struct _sas_device *sas_device; | 1757 | struct _sas_device *sas_device; |
1758 | struct _pcie_device *pcie_device; | ||
1507 | unsigned long flags; | 1759 | unsigned long flags; |
1508 | 1760 | ||
1509 | if (!sdev->hostdata) | 1761 | if (!sdev->hostdata) |
@@ -1516,7 +1768,19 @@ scsih_slave_destroy(struct scsi_device *sdev) | |||
1516 | shost = dev_to_shost(&starget->dev); | 1768 | shost = dev_to_shost(&starget->dev); |
1517 | ioc = shost_priv(shost); | 1769 | ioc = shost_priv(shost); |
1518 | 1770 | ||
1519 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | 1771 | if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) { |
1772 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
1773 | pcie_device = __mpt3sas_get_pdev_from_target(ioc, | ||
1774 | sas_target_priv_data); | ||
1775 | if (pcie_device && !sas_target_priv_data->num_luns) | ||
1776 | pcie_device->starget = NULL; | ||
1777 | |||
1778 | if (pcie_device) | ||
1779 | pcie_device_put(pcie_device); | ||
1780 | |||
1781 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
1782 | |||
1783 | } else if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | ||
1520 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1784 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1521 | sas_device = __mpt3sas_get_sdev_from_target(ioc, | 1785 | sas_device = __mpt3sas_get_sdev_from_target(ioc, |
1522 | sas_target_priv_data); | 1786 | sas_target_priv_data); |
@@ -8398,42 +8662,52 @@ scsih_shutdown(struct pci_dev *pdev) | |||
8398 | static void | 8662 | static void |
8399 | _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) | 8663 | _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) |
8400 | { | 8664 | { |
8401 | u8 is_raid; | 8665 | u32 channel; |
8402 | void *device; | 8666 | void *device; |
8403 | struct _sas_device *sas_device; | 8667 | struct _sas_device *sas_device; |
8404 | struct _raid_device *raid_device; | 8668 | struct _raid_device *raid_device; |
8669 | struct _pcie_device *pcie_device; | ||
8405 | u16 handle; | 8670 | u16 handle; |
8406 | u64 sas_address_parent; | 8671 | u64 sas_address_parent; |
8407 | u64 sas_address; | 8672 | u64 sas_address; |
8408 | unsigned long flags; | 8673 | unsigned long flags; |
8409 | int rc; | 8674 | int rc; |
8675 | int tid; | ||
8410 | 8676 | ||
8411 | /* no Bios, return immediately */ | 8677 | /* no Bios, return immediately */ |
8412 | if (!ioc->bios_pg3.BiosVersion) | 8678 | if (!ioc->bios_pg3.BiosVersion) |
8413 | return; | 8679 | return; |
8414 | 8680 | ||
8415 | device = NULL; | 8681 | device = NULL; |
8416 | is_raid = 0; | ||
8417 | if (ioc->req_boot_device.device) { | 8682 | if (ioc->req_boot_device.device) { |
8418 | device = ioc->req_boot_device.device; | 8683 | device = ioc->req_boot_device.device; |
8419 | is_raid = ioc->req_boot_device.is_raid; | 8684 | channel = ioc->req_boot_device.channel; |
8420 | } else if (ioc->req_alt_boot_device.device) { | 8685 | } else if (ioc->req_alt_boot_device.device) { |
8421 | device = ioc->req_alt_boot_device.device; | 8686 | device = ioc->req_alt_boot_device.device; |
8422 | is_raid = ioc->req_alt_boot_device.is_raid; | 8687 | channel = ioc->req_alt_boot_device.channel; |
8423 | } else if (ioc->current_boot_device.device) { | 8688 | } else if (ioc->current_boot_device.device) { |
8424 | device = ioc->current_boot_device.device; | 8689 | device = ioc->current_boot_device.device; |
8425 | is_raid = ioc->current_boot_device.is_raid; | 8690 | channel = ioc->current_boot_device.channel; |
8426 | } | 8691 | } |
8427 | 8692 | ||
8428 | if (!device) | 8693 | if (!device) |
8429 | return; | 8694 | return; |
8430 | 8695 | ||
8431 | if (is_raid) { | 8696 | if (channel == RAID_CHANNEL) { |
8432 | raid_device = device; | 8697 | raid_device = device; |
8433 | rc = scsi_add_device(ioc->shost, RAID_CHANNEL, | 8698 | rc = scsi_add_device(ioc->shost, RAID_CHANNEL, |
8434 | raid_device->id, 0); | 8699 | raid_device->id, 0); |
8435 | if (rc) | 8700 | if (rc) |
8436 | _scsih_raid_device_remove(ioc, raid_device); | 8701 | _scsih_raid_device_remove(ioc, raid_device); |
8702 | } else if (channel == PCIE_CHANNEL) { | ||
8703 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
8704 | pcie_device = device; | ||
8705 | tid = pcie_device->id; | ||
8706 | list_move_tail(&pcie_device->list, &ioc->pcie_device_list); | ||
8707 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
8708 | rc = scsi_add_device(ioc->shost, PCIE_CHANNEL, tid, 0); | ||
8709 | if (rc) | ||
8710 | _scsih_pcie_device_remove(ioc, pcie_device); | ||
8437 | } else { | 8711 | } else { |
8438 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 8712 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
8439 | sas_device = device; | 8713 | sas_device = device; |
@@ -8566,6 +8840,101 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) | |||
8566 | } | 8840 | } |
8567 | 8841 | ||
8568 | /** | 8842 | /** |
8843 | * get_next_pcie_device - Get the next pcie device | ||
8844 | * @ioc: per adapter object | ||
8845 | * | ||
8846 | * Get the next pcie device from pcie_device_init_list list. | ||
8847 | * | ||
8848 | * Returns pcie device structure if pcie_device_init_list list is not empty | ||
8849 | * otherwise returns NULL | ||
8850 | */ | ||
8851 | static struct _pcie_device *get_next_pcie_device(struct MPT3SAS_ADAPTER *ioc) | ||
8852 | { | ||
8853 | struct _pcie_device *pcie_device = NULL; | ||
8854 | unsigned long flags; | ||
8855 | |||
8856 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
8857 | if (!list_empty(&ioc->pcie_device_init_list)) { | ||
8858 | pcie_device = list_first_entry(&ioc->pcie_device_init_list, | ||
8859 | struct _pcie_device, list); | ||
8860 | pcie_device_get(pcie_device); | ||
8861 | } | ||
8862 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
8863 | |||
8864 | return pcie_device; | ||
8865 | } | ||
8866 | |||
8867 | /** | ||
8868 | * pcie_device_make_active - Add pcie device to pcie_device_list list | ||
8869 | * @ioc: per adapter object | ||
8870 | * @pcie_device: pcie device object | ||
8871 | * | ||
8872 | * Add the pcie device which has registered with SCSI Transport Later to | ||
8873 | * pcie_device_list list | ||
8874 | */ | ||
8875 | static void pcie_device_make_active(struct MPT3SAS_ADAPTER *ioc, | ||
8876 | struct _pcie_device *pcie_device) | ||
8877 | { | ||
8878 | unsigned long flags; | ||
8879 | |||
8880 | spin_lock_irqsave(&ioc->pcie_device_lock, flags); | ||
8881 | |||
8882 | if (!list_empty(&pcie_device->list)) { | ||
8883 | list_del_init(&pcie_device->list); | ||
8884 | pcie_device_put(pcie_device); | ||
8885 | } | ||
8886 | pcie_device_get(pcie_device); | ||
8887 | list_add_tail(&pcie_device->list, &ioc->pcie_device_list); | ||
8888 | |||
8889 | spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); | ||
8890 | } | ||
8891 | |||
8892 | /** | ||
8893 | * _scsih_probe_pcie - reporting PCIe devices to scsi-ml | ||
8894 | * @ioc: per adapter object | ||
8895 | * | ||
8896 | * Called during initial loading of the driver. | ||
8897 | */ | ||
8898 | static void | ||
8899 | _scsih_probe_pcie(struct MPT3SAS_ADAPTER *ioc) | ||
8900 | { | ||
8901 | struct _pcie_device *pcie_device; | ||
8902 | int rc; | ||
8903 | |||
8904 | /* PCIe Device List */ | ||
8905 | while ((pcie_device = get_next_pcie_device(ioc))) { | ||
8906 | if (pcie_device->starget) { | ||
8907 | pcie_device_put(pcie_device); | ||
8908 | continue; | ||
8909 | } | ||
8910 | rc = scsi_add_device(ioc->shost, PCIE_CHANNEL, | ||
8911 | pcie_device->id, 0); | ||
8912 | if (rc) { | ||
8913 | _scsih_pcie_device_remove(ioc, pcie_device); | ||
8914 | pcie_device_put(pcie_device); | ||
8915 | continue; | ||
8916 | } else if (!pcie_device->starget) { | ||
8917 | /* | ||
8918 | * When async scanning is enabled, its not possible to | ||
8919 | * remove devices while scanning is turned on due to an | ||
8920 | * oops in scsi_sysfs_add_sdev()->add_device()-> | ||
8921 | * sysfs_addrm_start() | ||
8922 | */ | ||
8923 | if (!ioc->is_driver_loading) { | ||
8924 | /* TODO-- Need to find out whether this condition will | ||
8925 | * occur or not | ||
8926 | */ | ||
8927 | _scsih_pcie_device_remove(ioc, pcie_device); | ||
8928 | pcie_device_put(pcie_device); | ||
8929 | continue; | ||
8930 | } | ||
8931 | } | ||
8932 | pcie_device_make_active(ioc, pcie_device); | ||
8933 | pcie_device_put(pcie_device); | ||
8934 | } | ||
8935 | } | ||
8936 | |||
8937 | /** | ||
8569 | * _scsih_probe_devices - probing for devices | 8938 | * _scsih_probe_devices - probing for devices |
8570 | * @ioc: per adapter object | 8939 | * @ioc: per adapter object |
8571 | * | 8940 | * |
@@ -8593,8 +8962,10 @@ _scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc) | |||
8593 | _scsih_probe_sas(ioc); | 8962 | _scsih_probe_sas(ioc); |
8594 | _scsih_probe_raid(ioc); | 8963 | _scsih_probe_raid(ioc); |
8595 | } | 8964 | } |
8596 | } else | 8965 | } else { |
8597 | _scsih_probe_sas(ioc); | 8966 | _scsih_probe_sas(ioc); |
8967 | _scsih_probe_pcie(ioc); | ||
8968 | } | ||
8598 | } | 8969 | } |
8599 | 8970 | ||
8600 | /** | 8971 | /** |
@@ -8937,11 +9308,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8937 | spin_lock_init(&ioc->sas_node_lock); | 9308 | spin_lock_init(&ioc->sas_node_lock); |
8938 | spin_lock_init(&ioc->fw_event_lock); | 9309 | spin_lock_init(&ioc->fw_event_lock); |
8939 | spin_lock_init(&ioc->raid_device_lock); | 9310 | spin_lock_init(&ioc->raid_device_lock); |
9311 | spin_lock_init(&ioc->pcie_device_lock); | ||
8940 | spin_lock_init(&ioc->diag_trigger_lock); | 9312 | spin_lock_init(&ioc->diag_trigger_lock); |
8941 | 9313 | ||
8942 | INIT_LIST_HEAD(&ioc->sas_device_list); | 9314 | INIT_LIST_HEAD(&ioc->sas_device_list); |
8943 | INIT_LIST_HEAD(&ioc->sas_device_init_list); | 9315 | INIT_LIST_HEAD(&ioc->sas_device_init_list); |
8944 | INIT_LIST_HEAD(&ioc->sas_expander_list); | 9316 | INIT_LIST_HEAD(&ioc->sas_expander_list); |
9317 | INIT_LIST_HEAD(&ioc->pcie_device_list); | ||
9318 | INIT_LIST_HEAD(&ioc->pcie_device_init_list); | ||
8945 | INIT_LIST_HEAD(&ioc->fw_event_list); | 9319 | INIT_LIST_HEAD(&ioc->fw_event_list); |
8946 | INIT_LIST_HEAD(&ioc->raid_device_list); | 9320 | INIT_LIST_HEAD(&ioc->raid_device_list); |
8947 | INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); | 9321 | INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); |