Skip to content

Commit 05bc1be

Browse files
Pierre MorelVasily Gorbik
authored andcommitted
s390/pci: create zPCI bus
The zPCI bus is in charge to handle common zPCI resources for zPCI devices. Creating the zPCI bus, the PCI bus, the zPCI devices and the PCI devices and hotplug slots done in a specific order: - PCI hotplug slot creation needs a PCI bus - PCI bus needs a PCI domain which is reported by the pci_domain_nr() when setting up the host bridge - PCI domain is set from the zPCI with devfn 0 this is necessary to have a reproducible enumeration Therefore we can not create devices or hotplug slots for any PCI device associated with a zPCI device before having discovered the function zero of the bus. The discovery and initialization of devices can be done at several points in the code: - On Events, serialized in a thread context - On initialization, in the kernel init thread context - When powering on the hotplug slot, in a user thread context The removal of devices and their parent bus may also be done on events or for devices when powering down the slot. To guarantee the existence of the bus and devices until they are no more needed we use kref in zPCI bus and introduce a reference count in the zPCI devices. In this patch the zPCI bus still only accept a device with a devfn 0. Signed-off-by: Pierre Morel <[email protected]> Reviewed-by: Niklas Schnelle <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent c9a1752 commit 05bc1be

File tree

8 files changed

+287
-118
lines changed

8 files changed

+287
-118
lines changed

arch/s390/include/asm/pci.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ int pci_proc_domain(struct pci_bus *);
2828
#define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS
2929
#define ZPCI_DOMAIN_BITMAP_SIZE (1 << 16)
3030

31+
#ifdef PCI
32+
#if (ZPCI_NR_DEVICES > ZPCI_DOMAIN_BITMAP_SIZE)
33+
# error ZPCI_NR_DEVICES can not be bigger than ZPCI_DOMAIN_BITMAP_SIZE
34+
#endif
35+
#endif /* PCI */
36+
3137
/* PCI Function Controls */
3238
#define ZPCI_FC_FN_ENABLED 0x80
3339
#define ZPCI_FC_ERROR 0x40
@@ -94,10 +100,23 @@ struct zpci_bar_struct {
94100

95101
struct s390_domain;
96102

103+
#define ZPCI_FUNCTIONS_PER_BUS 256
104+
struct zpci_bus {
105+
struct kref kref;
106+
struct pci_bus *bus;
107+
struct zpci_dev *function[ZPCI_FUNCTIONS_PER_BUS];
108+
struct list_head resources;
109+
struct list_head bus_next;
110+
int pchid;
111+
int domain_nr;
112+
enum pci_bus_speed max_bus_speed;
113+
};
114+
97115
/* Private data per function */
98116
struct zpci_dev {
99-
struct pci_bus *bus;
117+
struct zpci_bus *zbus;
100118
struct list_head entry; /* list of all zpci_devices, needed for hotplug, etc. */
119+
struct kref kref;
101120
struct hotplug_slot hotplug_slot;
102121

103122
enum zpci_state state;
@@ -107,7 +126,6 @@ struct zpci_dev {
107126
u16 pchid; /* physical channel ID */
108127
u8 pfgid; /* function group ID */
109128
u8 pft; /* pci function type */
110-
u16 domain;
111129
u8 port;
112130
u8 rid_available : 1;
113131
u8 reserved : 7;
@@ -232,7 +250,9 @@ static inline void zpci_exit_slot(struct zpci_dev *zdev) {}
232250
/* Helpers */
233251
static inline struct zpci_dev *to_zpci(struct pci_dev *pdev)
234252
{
235-
return pdev->sysdata;
253+
struct zpci_bus *zbus = pdev->sysdata;
254+
255+
return zbus->function[ZPCI_DEVFN];
236256
}
237257

238258
static inline struct zpci_dev *to_zpci_dev(struct device *dev)

arch/s390/pci/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
#
55

66
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \
7-
pci_event.o pci_debug.o pci_insn.o pci_mmio.o
7+
pci_event.o pci_debug.o pci_insn.o pci_mmio.o \
8+
pci_bus.o

arch/s390/pci/pci.c

Lines changed: 69 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@
3636
#include <asm/pci_clp.h>
3737
#include <asm/pci_dma.h>
3838

39+
#include "pci_bus.h"
40+
3941
/* list of all detected zpci devices */
4042
static LIST_HEAD(zpci_list);
4143
static DEFINE_SPINLOCK(zpci_list_lock);
4244

4345
static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE);
4446
static DEFINE_SPINLOCK(zpci_domain_lock);
45-
static unsigned int zpci_num_domains_allocated;
4647

4748
#define ZPCI_IOMAP_ENTRIES \
4849
min(((unsigned long) ZPCI_NR_DEVICES * PCI_STD_NUM_BARS / 2), \
@@ -90,17 +91,12 @@ void zpci_remove_reserved_devices(void)
9091
spin_unlock(&zpci_list_lock);
9192

9293
list_for_each_entry_safe(zdev, tmp, &remove, entry)
93-
zpci_remove_device(zdev);
94-
}
95-
96-
static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus)
97-
{
98-
return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL;
94+
zpci_zdev_put(zdev);
9995
}
10096

10197
int pci_domain_nr(struct pci_bus *bus)
10298
{
103-
return ((struct zpci_dev *) bus->sysdata)->domain;
99+
return ((struct zpci_bus *) bus->sysdata)->domain_nr;
104100
}
105101
EXPORT_SYMBOL_GPL(pci_domain_nr);
106102

@@ -508,15 +504,15 @@ static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start,
508504
return r;
509505
}
510506

511-
static int zpci_setup_bus_resources(struct zpci_dev *zdev,
512-
struct list_head *resources)
507+
int zpci_setup_bus_resources(struct zpci_dev *zdev,
508+
struct list_head *resources)
513509
{
514510
unsigned long addr, size, flags;
515511
struct resource *res;
516512
int i, entry;
517513

518514
snprintf(zdev->res_name, sizeof(zdev->res_name),
519-
"PCI Bus %04x:%02x", zdev->domain, ZPCI_BUS_NR);
515+
"PCI Bus %04x:%02x", zdev->uid, ZPCI_BUS_NR);
520516

521517
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
522518
if (!zdev->bars[i].size)
@@ -610,98 +606,53 @@ void pcibios_disable_device(struct pci_dev *pdev)
610606
zpci_debug_exit_device(zdev);
611607
}
612608

613-
static int zpci_alloc_domain(struct zpci_dev *zdev)
609+
static int __zpci_register_domain(int domain)
614610
{
615611
spin_lock(&zpci_domain_lock);
616-
if (zpci_num_domains_allocated > (ZPCI_NR_DEVICES - 1)) {
612+
if (test_bit(domain, zpci_domain)) {
617613
spin_unlock(&zpci_domain_lock);
618-
pr_err("Adding PCI function %08x failed because the configured limit of %d is reached\n",
619-
zdev->fid, ZPCI_NR_DEVICES);
620-
return -ENOSPC;
614+
pr_err("Domain %04x is already assigned\n", domain);
615+
return -EEXIST;
621616
}
617+
set_bit(domain, zpci_domain);
618+
spin_unlock(&zpci_domain_lock);
619+
return domain;
620+
}
622621

623-
if (zpci_unique_uid) {
624-
zdev->domain = (u16) zdev->uid;
625-
if (zdev->domain == 0) {
626-
pr_warn("UID checking is active but no UID is set for PCI function %08x, so automatic domain allocation is used instead\n",
627-
zdev->fid);
628-
update_uid_checking(false);
629-
goto auto_allocate;
630-
}
622+
static int __zpci_alloc_domain(void)
623+
{
624+
int domain;
631625

632-
if (test_bit(zdev->domain, zpci_domain)) {
633-
spin_unlock(&zpci_domain_lock);
634-
pr_err("Adding PCI function %08x failed because domain %04x is already assigned\n",
635-
zdev->fid, zdev->domain);
636-
return -EEXIST;
637-
}
638-
set_bit(zdev->domain, zpci_domain);
639-
zpci_num_domains_allocated++;
640-
spin_unlock(&zpci_domain_lock);
641-
return 0;
642-
}
643-
auto_allocate:
626+
spin_lock(&zpci_domain_lock);
644627
/*
645628
* We can always auto allocate domains below ZPCI_NR_DEVICES.
646629
* There is either a free domain or we have reached the maximum in
647630
* which case we would have bailed earlier.
648631
*/
649-
zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
650-
set_bit(zdev->domain, zpci_domain);
651-
zpci_num_domains_allocated++;
632+
domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
633+
set_bit(domain, zpci_domain);
652634
spin_unlock(&zpci_domain_lock);
653-
return 0;
635+
return domain;
654636
}
655637

656-
static void zpci_free_domain(struct zpci_dev *zdev)
638+
int zpci_alloc_domain(int domain)
657639
{
658-
spin_lock(&zpci_domain_lock);
659-
clear_bit(zdev->domain, zpci_domain);
660-
zpci_num_domains_allocated--;
661-
spin_unlock(&zpci_domain_lock);
640+
if (zpci_unique_uid) {
641+
if (domain)
642+
return __zpci_register_domain(domain);
643+
pr_warn("UID checking was active but no UID is provided: switching to automatic domain allocation\n");
644+
update_uid_checking(false);
645+
}
646+
return __zpci_alloc_domain();
662647
}
663648

664-
void pcibios_remove_bus(struct pci_bus *bus)
649+
void zpci_free_domain(int domain)
665650
{
666-
struct zpci_dev *zdev = get_zdev_by_bus(bus);
667-
668-
zpci_exit_slot(zdev);
669-
zpci_cleanup_bus_resources(zdev);
670-
zpci_destroy_iommu(zdev);
671-
zpci_free_domain(zdev);
672-
673-
spin_lock(&zpci_list_lock);
674-
list_del(&zdev->entry);
675-
spin_unlock(&zpci_list_lock);
676-
677-
zpci_dbg(3, "rem fid:%x\n", zdev->fid);
678-
kfree(zdev);
651+
spin_lock(&zpci_domain_lock);
652+
clear_bit(domain, zpci_domain);
653+
spin_unlock(&zpci_domain_lock);
679654
}
680655

681-
static int zpci_scan_bus(struct zpci_dev *zdev)
682-
{
683-
LIST_HEAD(resources);
684-
int ret;
685-
686-
ret = zpci_setup_bus_resources(zdev, &resources);
687-
if (ret)
688-
goto error;
689-
690-
zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
691-
zdev, &resources);
692-
if (!zdev->bus) {
693-
ret = -EIO;
694-
goto error;
695-
}
696-
zdev->bus->max_bus_speed = zdev->max_bus_speed;
697-
pci_bus_add_devices(zdev->bus);
698-
return 0;
699-
700-
error:
701-
zpci_cleanup_bus_resources(zdev);
702-
pci_free_resource_list(&resources);
703-
return ret;
704-
}
705656

706657
int zpci_enable_device(struct zpci_dev *zdev)
707658
{
@@ -736,50 +687,68 @@ int zpci_create_device(struct zpci_dev *zdev)
736687
{
737688
int rc;
738689

739-
rc = zpci_alloc_domain(zdev);
740-
if (rc)
741-
goto out;
690+
kref_init(&zdev->kref);
691+
692+
spin_lock(&zpci_list_lock);
693+
list_add_tail(&zdev->entry, &zpci_list);
694+
spin_unlock(&zpci_list_lock);
742695

743696
rc = zpci_init_iommu(zdev);
744697
if (rc)
745-
goto out_free;
698+
goto out;
746699

747700
mutex_init(&zdev->lock);
748701
if (zdev->state == ZPCI_FN_STATE_CONFIGURED) {
749702
rc = zpci_enable_device(zdev);
750703
if (rc)
751704
goto out_destroy_iommu;
752705
}
753-
rc = zpci_scan_bus(zdev);
706+
707+
rc = zpci_bus_device_register(zdev, &pci_root_ops);
754708
if (rc)
755709
goto out_disable;
756710

757-
spin_lock(&zpci_list_lock);
758-
list_add_tail(&zdev->entry, &zpci_list);
759-
spin_unlock(&zpci_list_lock);
760-
761711
zpci_init_slot(zdev);
762-
763712
return 0;
764713

765714
out_disable:
766715
if (zdev->state == ZPCI_FN_STATE_ONLINE)
767716
zpci_disable_device(zdev);
768717
out_destroy_iommu:
769718
zpci_destroy_iommu(zdev);
770-
out_free:
771-
zpci_free_domain(zdev);
772719
out:
720+
spin_lock(&zpci_list_lock);
721+
list_del(&zdev->entry);
722+
spin_unlock(&zpci_list_lock);
773723
return rc;
774724
}
775725

776-
void zpci_remove_device(struct zpci_dev *zdev)
726+
void zpci_release_device(struct kref *kref)
777727
{
778-
if (!zdev->bus)
779-
return;
728+
struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
729+
730+
switch (zdev->state) {
731+
case ZPCI_FN_STATE_ONLINE:
732+
case ZPCI_FN_STATE_CONFIGURED:
733+
zpci_disable_device(zdev);
734+
fallthrough;
735+
case ZPCI_FN_STATE_STANDBY:
736+
if (zdev->zbus) {
737+
zpci_exit_slot(zdev);
738+
zpci_cleanup_bus_resources(zdev);
739+
zpci_bus_device_unregister(zdev);
740+
zpci_destroy_iommu(zdev);
741+
}
742+
fallthrough;
743+
default:
744+
break;
745+
}
780746

781-
pci_stop_root_bus(zdev->bus);
782-
pci_remove_root_bus(zdev->bus);
747+
spin_lock(&zpci_list_lock);
748+
list_del(&zdev->entry);
749+
spin_unlock(&zpci_list_lock);
750+
zpci_dbg(3, "rem fid:%x\n", zdev->fid);
751+
kfree(zdev);
783752
}
784753

785754
int zpci_report_error(struct pci_dev *pdev,

0 commit comments

Comments
 (0)