Skip to content

Commit 126034f

Browse files
niklas88hcahca
authored andcommitted
s390/pci: Use topology ID for multi-function devices
The newly introduced topology ID (TID) field in the CLP Query PCI Function explicitly identifies groups of PCI functions whose RIDs belong to the same (sub-)topology. When available use the TID instead of the PCHID to match zPCI busses/domains for multi-function devices. Note that currently only a single PCI bus per TID is supported. This change is required because in future machines the PCHID will not identify a PCI card but a specific port in the case of some multi-port NICs while from a PCI point of view the entire card is a subtopology. Reviewed-by: Gerd Bayer <[email protected]> Signed-off-by: Niklas Schnelle <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent 0467cdd commit 126034f

File tree

4 files changed

+24
-13
lines changed

4 files changed

+24
-13
lines changed

arch/s390/include/asm/pci.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,10 @@ struct zpci_bus {
107107
struct list_head resources;
108108
struct list_head bus_next;
109109
struct resource bus_resource;
110-
int pchid;
110+
int topo; /* TID if topo_is_tid, PCHID otherwise */
111111
int domain_nr;
112-
bool multifunction;
112+
u8 multifunction : 1;
113+
u8 topo_is_tid : 1;
113114
enum pci_bus_speed max_bus_speed;
114115
};
115116

@@ -131,6 +132,7 @@ struct zpci_dev {
131132
u16 pchid; /* physical channel ID */
132133
u16 maxstbl; /* Maximum store block size */
133134
u16 rid; /* RID as supplied by firmware */
135+
u16 tid; /* Topology for which RID is valid */
134136
u8 pfgid; /* function group ID */
135137
u8 pft; /* pci function type */
136138
u8 port;
@@ -141,7 +143,8 @@ struct zpci_dev {
141143
u8 is_physfn : 1;
142144
u8 util_str_avail : 1;
143145
u8 irqs_registered : 1;
144-
u8 reserved : 2;
146+
u8 tid_avail : 1;
147+
u8 reserved : 1;
145148
unsigned int devfn; /* DEVFN part of the RID*/
146149

147150
u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */

arch/s390/include/asm/pci_clp.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ struct clp_req_query_pci {
110110
struct clp_rsp_query_pci {
111111
struct clp_rsp_hdr hdr;
112112
u16 vfn; /* virtual fn number */
113-
u16 : 3;
113+
u16 : 2;
114+
u16 tid_avail : 1;
114115
u16 rid_avail : 1;
115116
u16 is_physfn : 1;
116117
u16 reserved1 : 1;
@@ -130,8 +131,9 @@ struct clp_rsp_query_pci {
130131
u64 edma; /* end dma as */
131132
#define ZPCI_RID_MASK_DEVFN 0x00ff
132133
u16 rid; /* BUS/DEVFN PCI address */
133-
u16 reserved0;
134-
u32 reserved[10];
134+
u32 reserved0;
135+
u16 tid;
136+
u32 reserved[9];
135137
u32 uid; /* user defined id */
136138
u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */
137139
u32 reserved2[16];

arch/s390/pci/pci_bus.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,13 @@ static void zpci_bus_put(struct zpci_bus *zbus)
232232
kref_put(&zbus->kref, zpci_bus_release);
233233
}
234234

235-
static struct zpci_bus *zpci_bus_get(int pchid)
235+
static struct zpci_bus *zpci_bus_get(int topo, bool topo_is_tid)
236236
{
237237
struct zpci_bus *zbus;
238238

239239
mutex_lock(&zbus_list_lock);
240240
list_for_each_entry(zbus, &zbus_list, bus_next) {
241-
if (pchid == zbus->pchid) {
241+
if (topo_is_tid == zbus->topo_is_tid && topo == zbus->topo) {
242242
kref_get(&zbus->kref);
243243
goto out_unlock;
244244
}
@@ -249,15 +249,16 @@ static struct zpci_bus *zpci_bus_get(int pchid)
249249
return zbus;
250250
}
251251

252-
static struct zpci_bus *zpci_bus_alloc(int pchid)
252+
static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid)
253253
{
254254
struct zpci_bus *zbus;
255255

256256
zbus = kzalloc(sizeof(*zbus), GFP_KERNEL);
257257
if (!zbus)
258258
return NULL;
259259

260-
zbus->pchid = pchid;
260+
zbus->topo = topo;
261+
zbus->topo_is_tid = topo_is_tid;
261262
INIT_LIST_HEAD(&zbus->bus_next);
262263
mutex_lock(&zbus_list_lock);
263264
list_add_tail(&zbus->bus_next, &zbus_list);
@@ -321,8 +322,9 @@ static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)
321322

322323
int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
323324
{
325+
bool topo_is_tid = zdev->tid_avail;
324326
struct zpci_bus *zbus = NULL;
325-
int rc = -EBADF;
327+
int topo, rc = -EBADF;
326328

327329
if (zpci_nb_devices == ZPCI_NR_DEVICES) {
328330
pr_warn("Adding PCI function %08x failed because the configured limit of %d is reached\n",
@@ -333,11 +335,12 @@ int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
333335
if (zdev->devfn >= ZPCI_FUNCTIONS_PER_BUS)
334336
return -EINVAL;
335337

338+
topo = topo_is_tid ? zdev->tid : zdev->pchid;
336339
if (!s390_pci_no_rid && zdev->rid_available)
337-
zbus = zpci_bus_get(zdev->pchid);
340+
zbus = zpci_bus_get(topo, topo_is_tid);
338341

339342
if (!zbus) {
340-
zbus = zpci_bus_alloc(zdev->pchid);
343+
zbus = zpci_bus_alloc(topo, topo_is_tid);
341344
if (!zbus)
342345
return -ENOMEM;
343346
}

arch/s390/pci/pci_clp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ static int clp_store_query_pci_fn(struct zpci_dev *zdev,
170170
zdev->rid = response->rid;
171171
if (!s390_pci_no_rid && zdev->rid_available)
172172
zdev->devfn = response->rid & ZPCI_RID_MASK_DEVFN;
173+
zdev->tid_avail = response->tid_avail;
174+
if (zdev->tid_avail)
175+
zdev->tid = response->tid;
173176

174177
memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip));
175178
if (response->util_str_avail) {

0 commit comments

Comments
 (0)