@@ -768,6 +768,57 @@ static void __init dmar_acpi_insert_dev_scope(u8 device_number,
768768 device_number , dev_name (& adev -> dev ));
769769}
770770
771+ /* Return: > 0 if match found, 0 if no match found */
772+ bool dmar_rmrr_acpi_insert_dev_scope (u8 device_number , struct acpi_device * adev , void * start ,
773+ void * end , struct dmar_dev_scope * devices , int devices_cnt )
774+ {
775+ struct acpi_dmar_device_scope * scope ;
776+ struct device * tmp ;
777+ int i ;
778+ struct acpi_dmar_pci_path * path ;
779+
780+ for (; start < end ; start += scope -> length ) {
781+ scope = start ;
782+ if (scope -> entry_type != ACPI_DMAR_SCOPE_TYPE_NAMESPACE )
783+ continue ;
784+ if (scope -> enumeration_id != device_number )
785+ continue ;
786+ path = (void * )(scope + 1 );
787+ pr_info ("ACPI device \"%s\" under DMAR as %02x:%02x.%d\n" , dev_name (& adev -> dev ),
788+ scope -> bus , path -> device , path -> function );
789+ for_each_dev_scope (devices , devices_cnt , i , tmp )
790+ if (tmp == NULL ) {
791+ devices [i ].bus = scope -> bus ;
792+ devices [i ].devfn = PCI_DEVFN (path -> device , path -> function );
793+ rcu_assign_pointer (devices [i ].dev , get_device (& adev -> dev ));
794+ return true;
795+ }
796+ WARN_ON (i >= devices_cnt );
797+ }
798+
799+ return false;
800+ }
801+
802+ static int dmar_acpi_bus_add_dev (u8 device_number , struct acpi_device * adev )
803+ {
804+ struct dmar_drhd_unit * dmaru ;
805+ struct acpi_dmar_hardware_unit * drhd ;
806+ int ret ;
807+
808+ for_each_drhd_unit (dmaru ) {
809+ drhd = container_of (dmaru -> hdr , struct acpi_dmar_hardware_unit , header );
810+ ret = dmar_rmrr_acpi_insert_dev_scope (device_number , adev , (void * )(drhd + 1 ),
811+ ((void * )drhd )+ drhd -> header .length ,
812+ dmaru -> devices , dmaru -> devices_cnt );
813+ if (ret )
814+ break ;
815+ }
816+ if (ret > 0 )
817+ ret = dmar_rmrr_add_acpi_dev (device_number , adev );
818+
819+ return ret ;
820+ }
821+
771822static int __init dmar_acpi_dev_scope_init (void )
772823{
773824 struct acpi_dmar_andd * andd ;
@@ -795,7 +846,11 @@ static int __init dmar_acpi_dev_scope_init(void)
795846 andd -> device_name );
796847 continue ;
797848 }
798- dmar_acpi_insert_dev_scope (andd -> device_number , adev );
849+
850+ if (apply_zhaoxin_dmar_acpi_a_behavior ())
851+ dmar_acpi_bus_add_dev (andd -> device_number , adev );
852+ else
853+ dmar_acpi_insert_dev_scope (andd -> device_number , adev );
799854 }
800855 }
801856 return 0 ;
0 commit comments