diff options
Diffstat (limited to 'arch/s390/pci/pci.c')
-rw-r--r-- | arch/s390/pci/pci.c | 153 |
1 files changed, 61 insertions, 92 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 27b4c17855b9..e6f15b5d8b7d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -99,9 +99,6 @@ static int __read_mostly aisb_max; | |||
99 | static struct kmem_cache *zdev_irq_cache; | 99 | static struct kmem_cache *zdev_irq_cache; |
100 | static struct kmem_cache *zdev_fmb_cache; | 100 | static struct kmem_cache *zdev_fmb_cache; |
101 | 101 | ||
102 | debug_info_t *pci_debug_msg_id; | ||
103 | debug_info_t *pci_debug_err_id; | ||
104 | |||
105 | static inline int irq_to_msi_nr(unsigned int irq) | 102 | static inline int irq_to_msi_nr(unsigned int irq) |
106 | { | 103 | { |
107 | return irq & ZPCI_MSI_MASK; | 104 | return irq & ZPCI_MSI_MASK; |
@@ -179,7 +176,7 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, | |||
179 | fib->aisb = (u64) bucket->aisb + aisb / 8; | 176 | fib->aisb = (u64) bucket->aisb + aisb / 8; |
180 | fib->aisbo = aisb & ZPCI_MSI_MASK; | 177 | fib->aisbo = aisb & ZPCI_MSI_MASK; |
181 | 178 | ||
182 | rc = mpcifc_instr(req, fib); | 179 | rc = s390pci_mod_fc(req, fib); |
183 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); | 180 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); |
184 | 181 | ||
185 | free_page((unsigned long) fib); | 182 | free_page((unsigned long) fib); |
@@ -209,7 +206,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args | |||
209 | fib->iota = args->iota; | 206 | fib->iota = args->iota; |
210 | fib->fmb_addr = args->fmb_addr; | 207 | fib->fmb_addr = args->fmb_addr; |
211 | 208 | ||
212 | rc = mpcifc_instr(req, fib); | 209 | rc = s390pci_mod_fc(req, fib); |
213 | free_page((unsigned long) fib); | 210 | free_page((unsigned long) fib); |
214 | return rc; | 211 | return rc; |
215 | } | 212 | } |
@@ -249,10 +246,9 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) | |||
249 | if (zdev->fmb) | 246 | if (zdev->fmb) |
250 | return -EINVAL; | 247 | return -EINVAL; |
251 | 248 | ||
252 | zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL); | 249 | zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL); |
253 | if (!zdev->fmb) | 250 | if (!zdev->fmb) |
254 | return -ENOMEM; | 251 | return -ENOMEM; |
255 | memset(zdev->fmb, 0, sizeof(*zdev->fmb)); | ||
256 | WARN_ON((u64) zdev->fmb & 0xf); | 252 | WARN_ON((u64) zdev->fmb & 0xf); |
257 | 253 | ||
258 | args.fmb_addr = virt_to_phys(zdev->fmb); | 254 | args.fmb_addr = virt_to_phys(zdev->fmb); |
@@ -284,12 +280,12 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) | |||
284 | u64 data; | 280 | u64 data; |
285 | int rc; | 281 | int rc; |
286 | 282 | ||
287 | rc = pcilg_instr(&data, req, offset); | 283 | rc = s390pci_load(&data, req, offset); |
288 | data = data << ((8 - len) * 8); | 284 | if (!rc) { |
289 | data = le64_to_cpu(data); | 285 | data = data << ((8 - len) * 8); |
290 | if (!rc) | 286 | data = le64_to_cpu(data); |
291 | *val = (u32) data; | 287 | *val = (u32) data; |
292 | else | 288 | } else |
293 | *val = 0xffffffff; | 289 | *val = 0xffffffff; |
294 | return rc; | 290 | return rc; |
295 | } | 291 | } |
@@ -302,7 +298,7 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
302 | 298 | ||
303 | data = cpu_to_le64(data); | 299 | data = cpu_to_le64(data); |
304 | data = data >> ((8 - len) * 8); | 300 | data = data >> ((8 - len) * 8); |
305 | rc = pcistg_instr(data, req, offset); | 301 | rc = s390pci_store(data, req, offset); |
306 | return rc; | 302 | return rc; |
307 | } | 303 | } |
308 | 304 | ||
@@ -409,20 +405,28 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
409 | int size, u32 *val) | 405 | int size, u32 *val) |
410 | { | 406 | { |
411 | struct zpci_dev *zdev = get_zdev_by_bus(bus); | 407 | struct zpci_dev *zdev = get_zdev_by_bus(bus); |
408 | int ret; | ||
412 | 409 | ||
413 | if (!zdev || devfn != ZPCI_DEVFN) | 410 | if (!zdev || devfn != ZPCI_DEVFN) |
414 | return 0; | 411 | ret = -ENODEV; |
415 | return zpci_cfg_load(zdev, where, val, size); | 412 | else |
413 | ret = zpci_cfg_load(zdev, where, val, size); | ||
414 | |||
415 | return ret; | ||
416 | } | 416 | } |
417 | 417 | ||
418 | static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, | 418 | static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, |
419 | int size, u32 val) | 419 | int size, u32 val) |
420 | { | 420 | { |
421 | struct zpci_dev *zdev = get_zdev_by_bus(bus); | 421 | struct zpci_dev *zdev = get_zdev_by_bus(bus); |
422 | int ret; | ||
422 | 423 | ||
423 | if (!zdev || devfn != ZPCI_DEVFN) | 424 | if (!zdev || devfn != ZPCI_DEVFN) |
424 | return 0; | 425 | ret = -ENODEV; |
425 | return zpci_cfg_store(zdev, where, val, size); | 426 | else |
427 | ret = zpci_cfg_store(zdev, where, val, size); | ||
428 | |||
429 | return ret; | ||
426 | } | 430 | } |
427 | 431 | ||
428 | static struct pci_ops pci_root_ops = { | 432 | static struct pci_ops pci_root_ops = { |
@@ -474,7 +478,7 @@ scan: | |||
474 | } | 478 | } |
475 | 479 | ||
476 | /* enable interrupts again */ | 480 | /* enable interrupts again */ |
477 | sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | 481 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); |
478 | 482 | ||
479 | /* check again to not lose initiative */ | 483 | /* check again to not lose initiative */ |
480 | rmb(); | 484 | rmb(); |
@@ -596,19 +600,6 @@ static void zpci_map_resources(struct zpci_dev *zdev) | |||
596 | } | 600 | } |
597 | }; | 601 | }; |
598 | 602 | ||
599 | static void zpci_unmap_resources(struct pci_dev *pdev) | ||
600 | { | ||
601 | resource_size_t len; | ||
602 | int i; | ||
603 | |||
604 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
605 | len = pci_resource_len(pdev, i); | ||
606 | if (!len) | ||
607 | continue; | ||
608 | pci_iounmap(pdev, (void *) pdev->resource[i].start); | ||
609 | } | ||
610 | }; | ||
611 | |||
612 | struct zpci_dev *zpci_alloc_device(void) | 603 | struct zpci_dev *zpci_alloc_device(void) |
613 | { | 604 | { |
614 | struct zpci_dev *zdev; | 605 | struct zpci_dev *zdev; |
@@ -636,32 +627,6 @@ void zpci_free_device(struct zpci_dev *zdev) | |||
636 | kfree(zdev); | 627 | kfree(zdev); |
637 | } | 628 | } |
638 | 629 | ||
639 | /* Called on removal of pci_dev, leaves zpci and bus device */ | ||
640 | static void zpci_remove_device(struct pci_dev *pdev) | ||
641 | { | ||
642 | struct zpci_dev *zdev = get_zdev(pdev); | ||
643 | |||
644 | dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); | ||
645 | zdev->state = ZPCI_FN_STATE_CONFIGURED; | ||
646 | zpci_dma_exit_device(zdev); | ||
647 | zpci_fmb_disable_device(zdev); | ||
648 | zpci_sysfs_remove_device(&pdev->dev); | ||
649 | zpci_unmap_resources(pdev); | ||
650 | list_del(&zdev->entry); /* can be called from init */ | ||
651 | zdev->pdev = NULL; | ||
652 | } | ||
653 | |||
654 | static void zpci_scan_devices(void) | ||
655 | { | ||
656 | struct zpci_dev *zdev; | ||
657 | |||
658 | mutex_lock(&zpci_list_lock); | ||
659 | list_for_each_entry(zdev, &zpci_list, entry) | ||
660 | if (zdev->state == ZPCI_FN_STATE_CONFIGURED) | ||
661 | zpci_scan_device(zdev); | ||
662 | mutex_unlock(&zpci_list_lock); | ||
663 | } | ||
664 | |||
665 | /* | 630 | /* |
666 | * Too late for any s390 specific setup, since interrupts must be set up | 631 | * Too late for any s390 specific setup, since interrupts must be set up |
667 | * already which requires DMA setup too and the pci scan will access the | 632 | * already which requires DMA setup too and the pci scan will access the |
@@ -688,12 +653,6 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) | |||
688 | return 0; | 653 | return 0; |
689 | } | 654 | } |
690 | 655 | ||
691 | void pcibios_disable_device(struct pci_dev *pdev) | ||
692 | { | ||
693 | zpci_remove_device(pdev); | ||
694 | pdev->sysdata = NULL; | ||
695 | } | ||
696 | |||
697 | int pcibios_add_platform_entries(struct pci_dev *pdev) | 656 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
698 | { | 657 | { |
699 | return zpci_sysfs_add_device(&pdev->dev); | 658 | return zpci_sysfs_add_device(&pdev->dev); |
@@ -789,7 +748,7 @@ static int __init zpci_irq_init(void) | |||
789 | spin_lock_init(&bucket->lock); | 748 | spin_lock_init(&bucket->lock); |
790 | /* set summary to 1 to be called every time for the ISC */ | 749 | /* set summary to 1 to be called every time for the ISC */ |
791 | *zpci_irq_si = 1; | 750 | *zpci_irq_si = 1; |
792 | sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | 751 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); |
793 | return 0; | 752 | return 0; |
794 | 753 | ||
795 | out_ai: | 754 | out_ai: |
@@ -872,7 +831,19 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) | |||
872 | spin_unlock(&zpci_iomap_lock); | 831 | spin_unlock(&zpci_iomap_lock); |
873 | } | 832 | } |
874 | 833 | ||
875 | static int zpci_create_device_bus(struct zpci_dev *zdev) | 834 | int pcibios_add_device(struct pci_dev *pdev) |
835 | { | ||
836 | struct zpci_dev *zdev = get_zdev(pdev); | ||
837 | |||
838 | zdev->pdev = pdev; | ||
839 | zpci_debug_init_device(zdev); | ||
840 | zpci_fmb_enable_device(zdev); | ||
841 | zpci_map_resources(zdev); | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | static int zpci_scan_bus(struct zpci_dev *zdev) | ||
876 | { | 847 | { |
877 | struct resource *res; | 848 | struct resource *res; |
878 | LIST_HEAD(resources); | 849 | LIST_HEAD(resources); |
@@ -909,8 +880,8 @@ static int zpci_create_device_bus(struct zpci_dev *zdev) | |||
909 | pci_add_resource(&resources, res); | 880 | pci_add_resource(&resources, res); |
910 | } | 881 | } |
911 | 882 | ||
912 | zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, | 883 | zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, |
913 | zdev, &resources); | 884 | zdev, &resources); |
914 | if (!zdev->bus) | 885 | if (!zdev->bus) |
915 | return -EIO; | 886 | return -EIO; |
916 | 887 | ||
@@ -959,6 +930,13 @@ out: | |||
959 | } | 930 | } |
960 | EXPORT_SYMBOL_GPL(zpci_enable_device); | 931 | EXPORT_SYMBOL_GPL(zpci_enable_device); |
961 | 932 | ||
933 | int zpci_disable_device(struct zpci_dev *zdev) | ||
934 | { | ||
935 | zpci_dma_exit_device(zdev); | ||
936 | return clp_disable_fh(zdev); | ||
937 | } | ||
938 | EXPORT_SYMBOL_GPL(zpci_disable_device); | ||
939 | |||
962 | int zpci_create_device(struct zpci_dev *zdev) | 940 | int zpci_create_device(struct zpci_dev *zdev) |
963 | { | 941 | { |
964 | int rc; | 942 | int rc; |
@@ -967,9 +945,16 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
967 | if (rc) | 945 | if (rc) |
968 | goto out; | 946 | goto out; |
969 | 947 | ||
970 | rc = zpci_create_device_bus(zdev); | 948 | if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { |
949 | rc = zpci_enable_device(zdev); | ||
950 | if (rc) | ||
951 | goto out_free; | ||
952 | |||
953 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
954 | } | ||
955 | rc = zpci_scan_bus(zdev); | ||
971 | if (rc) | 956 | if (rc) |
972 | goto out_bus; | 957 | goto out_disable; |
973 | 958 | ||
974 | mutex_lock(&zpci_list_lock); | 959 | mutex_lock(&zpci_list_lock); |
975 | list_add_tail(&zdev->entry, &zpci_list); | 960 | list_add_tail(&zdev->entry, &zpci_list); |
@@ -977,21 +962,12 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
977 | hotplug_ops->create_slot(zdev); | 962 | hotplug_ops->create_slot(zdev); |
978 | mutex_unlock(&zpci_list_lock); | 963 | mutex_unlock(&zpci_list_lock); |
979 | 964 | ||
980 | if (zdev->state == ZPCI_FN_STATE_STANDBY) | ||
981 | return 0; | ||
982 | |||
983 | rc = zpci_enable_device(zdev); | ||
984 | if (rc) | ||
985 | goto out_start; | ||
986 | return 0; | 965 | return 0; |
987 | 966 | ||
988 | out_start: | 967 | out_disable: |
989 | mutex_lock(&zpci_list_lock); | 968 | if (zdev->state == ZPCI_FN_STATE_ONLINE) |
990 | list_del(&zdev->entry); | 969 | zpci_disable_device(zdev); |
991 | if (hotplug_ops) | 970 | out_free: |
992 | hotplug_ops->remove_slot(zdev); | ||
993 | mutex_unlock(&zpci_list_lock); | ||
994 | out_bus: | ||
995 | zpci_free_domain(zdev); | 971 | zpci_free_domain(zdev); |
996 | out: | 972 | out: |
997 | return rc; | 973 | return rc; |
@@ -1016,15 +992,9 @@ int zpci_scan_device(struct zpci_dev *zdev) | |||
1016 | goto out; | 992 | goto out; |
1017 | } | 993 | } |
1018 | 994 | ||
1019 | zpci_debug_init_device(zdev); | ||
1020 | zpci_fmb_enable_device(zdev); | ||
1021 | zpci_map_resources(zdev); | ||
1022 | pci_bus_add_devices(zdev->bus); | 995 | pci_bus_add_devices(zdev->bus); |
1023 | 996 | ||
1024 | /* now that pdev was added to the bus mark it as used */ | ||
1025 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
1026 | return 0; | 997 | return 0; |
1027 | |||
1028 | out: | 998 | out: |
1029 | zpci_dma_exit_device(zdev); | 999 | zpci_dma_exit_device(zdev); |
1030 | clp_disable_fh(zdev); | 1000 | clp_disable_fh(zdev); |
@@ -1087,13 +1057,13 @@ void zpci_deregister_hp_ops(void) | |||
1087 | } | 1057 | } |
1088 | EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); | 1058 | EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); |
1089 | 1059 | ||
1090 | unsigned int s390_pci_probe = 1; | 1060 | unsigned int s390_pci_probe; |
1091 | EXPORT_SYMBOL_GPL(s390_pci_probe); | 1061 | EXPORT_SYMBOL_GPL(s390_pci_probe); |
1092 | 1062 | ||
1093 | char * __init pcibios_setup(char *str) | 1063 | char * __init pcibios_setup(char *str) |
1094 | { | 1064 | { |
1095 | if (!strcmp(str, "off")) { | 1065 | if (!strcmp(str, "on")) { |
1096 | s390_pci_probe = 0; | 1066 | s390_pci_probe = 1; |
1097 | return NULL; | 1067 | return NULL; |
1098 | } | 1068 | } |
1099 | return str; | 1069 | return str; |
@@ -1138,7 +1108,6 @@ static int __init pci_base_init(void) | |||
1138 | if (rc) | 1108 | if (rc) |
1139 | goto out_find; | 1109 | goto out_find; |
1140 | 1110 | ||
1141 | zpci_scan_devices(); | ||
1142 | return 0; | 1111 | return 0; |
1143 | 1112 | ||
1144 | out_find: | 1113 | out_find: |