cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rpaphp_pci.c (2798B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
      4 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
      5 *
      6 * All rights reserved.
      7 *
      8 * Send feedback to <lxie@us.ibm.com>
      9 *
     10 */
     11#include <linux/of.h>
     12#include <linux/pci.h>
     13#include <linux/string.h>
     14
     15#include <asm/pci-bridge.h>
     16#include <asm/rtas.h>
     17#include <asm/machdep.h>
     18
     19#include "../pci.h"		/* for pci_add_new_bus */
     20#include "rpaphp.h"
     21
     22int rpaphp_get_sensor_state(struct slot *slot, int *state)
     23{
     24	int rc;
     25	int setlevel;
     26
     27	rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state);
     28
     29	if (rc < 0) {
     30		if (rc == -EFAULT || rc == -EEXIST) {
     31			dbg("%s: slot must be power up to get sensor-state\n",
     32			    __func__);
     33
     34			/* some slots have to be powered up
     35			 * before get-sensor will succeed.
     36			 */
     37			rc = rtas_set_power_level(slot->power_domain, POWER_ON,
     38						  &setlevel);
     39			if (rc < 0) {
     40				dbg("%s: power on slot[%s] failed rc=%d.\n",
     41				    __func__, slot->name, rc);
     42			} else {
     43				rc = rtas_get_sensor(DR_ENTITY_SENSE,
     44						     slot->index, state);
     45			}
     46		} else if (rc == -ENODEV)
     47			info("%s: slot is unusable\n", __func__);
     48		else
     49			err("%s failed to get sensor state\n", __func__);
     50	}
     51	return rc;
     52}
     53
     54/**
     55 * rpaphp_enable_slot - record slot state, config pci device
     56 * @slot: target &slot
     57 *
     58 * Initialize values in the slot structure to indicate if there is a pci card
     59 * plugged into the slot. If the slot is not empty, run the pcibios routine
     60 * to get pcibios stuff correctly set up.
     61 */
     62int rpaphp_enable_slot(struct slot *slot)
     63{
     64	int rc, level, state;
     65	struct pci_bus *bus;
     66
     67	slot->state = EMPTY;
     68
     69	/* Find out if the power is turned on for the slot */
     70	rc = rtas_get_power_level(slot->power_domain, &level);
     71	if (rc)
     72		return rc;
     73
     74	/* Figure out if there is an adapter in the slot */
     75	rc = rpaphp_get_sensor_state(slot, &state);
     76	if (rc)
     77		return rc;
     78
     79	bus = pci_find_bus_by_node(slot->dn);
     80	if (!bus) {
     81		err("%s: no pci_bus for dn %pOF\n", __func__, slot->dn);
     82		return -EINVAL;
     83	}
     84
     85	slot->bus = bus;
     86	slot->pci_devs = &bus->devices;
     87
     88	/* if there's an adapter in the slot, go add the pci devices */
     89	if (state == PRESENT) {
     90		slot->state = NOT_CONFIGURED;
     91
     92		/* non-empty slot has to have child */
     93		if (!slot->dn->child) {
     94			err("%s: slot[%s]'s device_node doesn't have child for adapter\n",
     95			    __func__, slot->name);
     96			return -EINVAL;
     97		}
     98
     99		if (list_empty(&bus->devices)) {
    100			pseries_eeh_init_edev_recursive(PCI_DN(slot->dn));
    101			pci_hp_add_devices(bus);
    102		}
    103
    104		if (!list_empty(&bus->devices)) {
    105			slot->state = CONFIGURED;
    106		}
    107
    108		if (rpaphp_debug) {
    109			struct pci_dev *dev;
    110			dbg("%s: pci_devs of slot[%pOF]\n", __func__, slot->dn);
    111			list_for_each_entry(dev, &bus->devices, bus_list)
    112				dbg("\t%s\n", pci_name(dev));
    113		}
    114	}
    115
    116	return 0;
    117}