2020-03-23 10:45:43 +01:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright IBM Corp . 2020
*
* Author ( s ) :
* Pierre Morel < pmorel @ linux . ibm . com >
*
*/
# define KMSG_COMPONENT "zpci"
# define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/err.h>
# include <linux/export.h>
# include <linux/delay.h>
# include <linux/seq_file.h>
# include <linux/jump_label.h>
# include <linux/pci.h>
# include <linux/printk.h>
# include <asm/pci_clp.h>
# include <asm/pci_dma.h>
# include "pci_bus.h"
2020-08-17 10:29:23 +02:00
# include "pci_iov.h"
2020-03-23 10:45:43 +01:00
static LIST_HEAD ( zbus_list ) ;
2021-02-12 10:16:46 +01:00
static DEFINE_MUTEX ( zbus_list_lock ) ;
2020-03-23 10:45:43 +01:00
static int zpci_nb_devices ;
2021-02-12 14:19:31 +01:00
/* zpci_bus_prepare_device - Prepare a zPCI function for scanning
* @ zdev : the zPCI function to be prepared
*
* The PCI resources for the function are set up and added to its zbus and the
* function is enabled . The function must be added to a zbus which must have
* a PCI bus created . If an error occurs the zPCI function is not enabled .
*
* Return : 0 on success , an error code otherwise
*/
static int zpci_bus_prepare_device ( struct zpci_dev * zdev )
{
struct resource_entry * window , * n ;
struct resource * res ;
int rc ;
if ( ! zdev_enabled ( zdev ) ) {
rc = zpci_enable_device ( zdev ) ;
if ( rc )
return rc ;
2021-07-16 11:53:37 +02:00
rc = zpci_dma_init_device ( zdev ) ;
if ( rc ) {
zpci_disable_device ( zdev ) ;
return rc ;
}
2021-02-12 14:19:31 +01:00
}
if ( ! zdev - > has_resources ) {
zpci_setup_bus_resources ( zdev , & zdev - > zbus - > resources ) ;
resource_list_for_each_entry_safe ( window , n , & zdev - > zbus - > resources ) {
res = window - > res ;
pci_bus_add_resource ( zdev - > zbus - > bus , res , 0 ) ;
}
}
return 0 ;
}
2021-02-11 14:20:03 +01:00
/* zpci_bus_scan_device - Scan a single device adding it to the PCI core
* @ zdev : the zdev to be scanned
*
* Scans the PCI function making it available to the common PCI code .
*
* Return : 0 on success , an error value otherwise
*/
int zpci_bus_scan_device ( struct zpci_dev * zdev )
{
struct pci_dev * pdev ;
2021-02-12 14:19:31 +01:00
int rc ;
rc = zpci_bus_prepare_device ( zdev ) ;
if ( rc )
return rc ;
2021-02-11 14:20:03 +01:00
pdev = pci_scan_single_device ( zdev - > zbus - > bus , zdev - > devfn ) ;
if ( ! pdev )
return - ENODEV ;
pci_lock_rescan_remove ( ) ;
2023-03-06 16:10:12 +01:00
pci_bus_add_device ( pdev ) ;
2021-02-11 14:20:03 +01:00
pci_unlock_rescan_remove ( ) ;
return 0 ;
}
2021-01-26 13:58:28 +01:00
/* zpci_bus_remove_device - Removes the given zdev from the PCI core
* @ zdev : the zdev to be removed from the PCI core
* @ set_error : if true the device ' s error state is set to permanent failure
*
* Sets a zPCI device to a configured but offline state ; the zPCI
* device is still accessible through its hotplug slot and the zPCI
* API but is removed from the common code PCI bus , making it
* no longer available to drivers .
*/
void zpci_bus_remove_device ( struct zpci_dev * zdev , bool set_error )
{
struct zpci_bus * zbus = zdev - > zbus ;
struct pci_dev * pdev ;
if ( ! zdev - > zbus - > bus )
return ;
pdev = pci_get_slot ( zbus - > bus , zdev - > devfn ) ;
if ( pdev ) {
if ( set_error )
pdev - > error_state = pci_channel_io_perm_failure ;
if ( pdev - > is_virtfn ) {
zpci_iov_remove_virtfn ( pdev , zdev - > vfn ) ;
/* balance pci_get_slot */
pci_dev_put ( pdev ) ;
return ;
}
pci_stop_and_remove_bus_device_locked ( pdev ) ;
/* balance pci_get_slot */
pci_dev_put ( pdev ) ;
}
}
2021-02-12 14:19:31 +01:00
/* zpci_bus_scan_bus - Scan all configured zPCI functions on the bus
* @ zbus : the zbus to be scanned
*
* Enables and scans all PCI functions on the bus making them available to the
* common PCI code . If there is no function 0 on the zbus nothing is scanned . If
* a function does not have a slot yet because it was added to the zbus before
* function 0 the slot is created . If a PCI function fails to be initialized
* an error will be returned but attempts will still be made for all other
* functions on the bus .
*
* Return : 0 on success , an error value otherwise
*/
int zpci_bus_scan_bus ( struct zpci_bus * zbus )
{
struct zpci_dev * zdev ;
int devfn , rc , ret = 0 ;
for ( devfn = 0 ; devfn < ZPCI_FUNCTIONS_PER_BUS ; devfn + + ) {
zdev = zbus - > function [ devfn ] ;
if ( zdev & & zdev - > state = = ZPCI_FN_STATE_CONFIGURED ) {
rc = zpci_bus_prepare_device ( zdev ) ;
if ( rc )
ret = - EIO ;
}
}
pci_lock_rescan_remove ( ) ;
pci_scan_child_bus ( zbus - > bus ) ;
pci_bus_add_devices ( zbus - > bus ) ;
pci_unlock_rescan_remove ( ) ;
return ret ;
}
2021-02-12 11:57:58 +01:00
/* zpci_bus_scan_busses - Scan all registered busses
*
* Scan all available zbusses
*
*/
void zpci_bus_scan_busses ( void )
{
struct zpci_bus * zbus = NULL ;
mutex_lock ( & zbus_list_lock ) ;
list_for_each_entry ( zbus , & zbus_list , bus_next ) {
zpci_bus_scan_bus ( zbus ) ;
cond_resched ( ) ;
}
mutex_unlock ( & zbus_list_lock ) ;
}
2021-02-12 14:19:31 +01:00
/* zpci_bus_create_pci_bus - Create the PCI bus associated with this zbus
2020-03-23 10:45:43 +01:00
* @ zbus : the zbus holding the zdevices
2022-06-28 16:31:00 +02:00
* @ fr : PCI root function that will determine the bus ' s domain , and bus speeed
2020-03-23 10:45:43 +01:00
* @ ops : the pci operations
*
2022-06-28 16:31:00 +02:00
* The PCI function @ fr determines the domain ( its UID ) , multifunction property
* and maximum bus speed of the entire bus .
2021-02-12 12:17:53 +01:00
*
* Return : 0 on success , an error code otherwise
2020-03-23 10:45:43 +01:00
*/
2022-06-28 16:31:00 +02:00
static int zpci_bus_create_pci_bus ( struct zpci_bus * zbus , struct zpci_dev * fr , struct pci_ops * ops )
2020-03-23 10:45:43 +01:00
{
struct pci_bus * bus ;
2021-02-12 12:17:53 +01:00
int domain ;
2020-03-23 10:45:43 +01:00
2022-06-28 16:31:00 +02:00
domain = zpci_alloc_domain ( ( u16 ) fr - > uid ) ;
2021-02-12 12:17:53 +01:00
if ( domain < 0 )
return domain ;
2020-03-23 10:45:43 +01:00
2021-02-12 12:17:53 +01:00
zbus - > domain_nr = domain ;
2022-06-28 16:31:00 +02:00
zbus - > multifunction = fr - > rid_available ;
zbus - > max_bus_speed = fr - > max_bus_speed ;
2021-02-12 12:17:53 +01:00
/*
* Note that the zbus - > resources are taken over and zbus - > resources
* is empty after a successful call
*/
2021-02-12 14:19:31 +01:00
bus = pci_create_root_bus ( NULL , ZPCI_BUS_NR , ops , zbus , & zbus - > resources ) ;
2020-03-23 10:45:43 +01:00
if ( ! bus ) {
zpci_free_domain ( zbus - > domain_nr ) ;
return - EFAULT ;
}
zbus - > bus = bus ;
2021-02-12 14:19:31 +01:00
2020-03-23 10:45:43 +01:00
return 0 ;
}
static void zpci_bus_release ( struct kref * kref )
{
struct zpci_bus * zbus = container_of ( kref , struct zpci_bus , kref ) ;
2020-04-22 15:15:23 +02:00
if ( zbus - > bus ) {
pci_lock_rescan_remove ( ) ;
pci_stop_root_bus ( zbus - > bus ) ;
2020-03-23 10:45:43 +01:00
2020-04-22 15:15:23 +02:00
zpci_free_domain ( zbus - > domain_nr ) ;
pci_free_resource_list ( & zbus - > resources ) ;
2020-03-23 10:45:43 +01:00
2020-04-22 15:15:23 +02:00
pci_remove_root_bus ( zbus - > bus ) ;
pci_unlock_rescan_remove ( ) ;
}
2020-03-23 10:45:43 +01:00
2021-02-12 10:16:46 +01:00
mutex_lock ( & zbus_list_lock ) ;
2020-03-23 10:45:43 +01:00
list_del ( & zbus - > bus_next ) ;
2021-02-12 10:16:46 +01:00
mutex_unlock ( & zbus_list_lock ) ;
2020-03-23 10:45:43 +01:00
kfree ( zbus ) ;
}
static void zpci_bus_put ( struct zpci_bus * zbus )
{
kref_put ( & zbus - > kref , zpci_bus_release ) ;
}
2020-04-22 15:15:23 +02:00
static struct zpci_bus * zpci_bus_get ( int pchid )
{
struct zpci_bus * zbus ;
2021-02-12 10:16:46 +01:00
mutex_lock ( & zbus_list_lock ) ;
2020-04-22 15:15:23 +02:00
list_for_each_entry ( zbus , & zbus_list , bus_next ) {
if ( pchid = = zbus - > pchid ) {
kref_get ( & zbus - > kref ) ;
goto out_unlock ;
}
}
zbus = NULL ;
out_unlock :
2021-02-12 10:16:46 +01:00
mutex_unlock ( & zbus_list_lock ) ;
2020-04-22 15:15:23 +02:00
return zbus ;
}
2020-03-23 10:45:43 +01:00
static struct zpci_bus * zpci_bus_alloc ( int pchid )
{
struct zpci_bus * zbus ;
zbus = kzalloc ( sizeof ( * zbus ) , GFP_KERNEL ) ;
if ( ! zbus )
return NULL ;
zbus - > pchid = pchid ;
INIT_LIST_HEAD ( & zbus - > bus_next ) ;
2021-02-12 10:16:46 +01:00
mutex_lock ( & zbus_list_lock ) ;
2020-03-23 10:45:43 +01:00
list_add_tail ( & zbus - > bus_next , & zbus_list ) ;
2021-02-12 10:16:46 +01:00
mutex_unlock ( & zbus_list_lock ) ;
2020-03-23 10:45:43 +01:00
kref_init ( & zbus - > kref ) ;
INIT_LIST_HEAD ( & zbus - > resources ) ;
2020-03-23 12:29:37 +01:00
zbus - > bus_resource . start = 0 ;
zbus - > bus_resource . end = ZPCI_BUS_NR ;
zbus - > bus_resource . flags = IORESOURCE_BUS ;
pci_add_resource ( & zbus - > resources , & zbus - > bus_resource ) ;
2020-03-23 10:45:43 +01:00
return zbus ;
}
2020-08-03 17:58:10 +02:00
void pcibios_bus_add_device ( struct pci_dev * pdev )
{
struct zpci_dev * zdev = to_zpci ( pdev ) ;
/*
* With pdev - > no_vf_scan the common PCI probing code does not
* perform PF / VF linking .
*/
2020-09-10 10:59:56 -04:00
if ( zdev - > vfn ) {
2020-08-17 10:29:23 +02:00
zpci_iov_setup_virtfn ( zdev - > zbus , pdev , zdev - > vfn ) ;
2020-09-10 10:59:56 -04:00
pdev - > no_command_memory = 1 ;
}
2020-08-03 17:58:10 +02:00
}
2021-02-12 14:19:31 +01:00
static int zpci_bus_add_device ( struct zpci_bus * zbus , struct zpci_dev * zdev )
2020-04-22 15:15:23 +02:00
{
2021-02-12 14:19:31 +01:00
int rc = - EINVAL ;
if ( zbus - > function [ zdev - > devfn ] ) {
pr_err ( " devfn %04x is already assigned \n " , zdev - > devfn ) ;
return rc ;
}
2022-06-28 16:31:00 +02:00
2021-08-06 12:12:11 +02:00
zdev - > zbus = zbus ;
2021-02-12 14:19:31 +01:00
zbus - > function [ zdev - > devfn ] = zdev ;
zpci_nb_devices + + ;
2022-06-28 16:31:00 +02:00
if ( zbus - > multifunction & & ! zdev - > rid_available ) {
WARN_ONCE ( 1 , " rid_available not set for multifunction \n " ) ;
goto error ;
2021-02-12 14:19:31 +01:00
}
2022-06-28 16:31:00 +02:00
rc = zpci_init_slot ( zdev ) ;
if ( rc )
goto error ;
zdev - > has_hp_slot = 1 ;
2020-04-22 15:15:23 +02:00
2021-02-12 14:19:31 +01:00
return 0 ;
error :
zbus - > function [ zdev - > devfn ] = NULL ;
2021-08-06 12:12:11 +02:00
zdev - > zbus = NULL ;
2021-02-12 14:19:31 +01:00
zpci_nb_devices - - ;
return rc ;
2020-04-22 15:15:23 +02:00
}
int zpci_bus_device_register ( struct zpci_dev * zdev , struct pci_ops * ops )
{
struct zpci_bus * zbus = NULL ;
int rc = - EBADF ;
2020-03-23 10:45:43 +01:00
if ( zpci_nb_devices = = ZPCI_NR_DEVICES ) {
pr_warn ( " Adding PCI function %08x failed because the configured limit of %d is reached \n " ,
zdev - > fid , ZPCI_NR_DEVICES ) ;
return - ENOSPC ;
}
2020-04-22 15:15:23 +02:00
if ( zdev - > devfn > = ZPCI_FUNCTIONS_PER_BUS )
2020-03-23 10:45:43 +01:00
return - EINVAL ;
2020-04-22 15:15:23 +02:00
if ( ! s390_pci_no_rid & & zdev - > rid_available )
zbus = zpci_bus_get ( zdev - > pchid ) ;
if ( ! zbus ) {
zbus = zpci_bus_alloc ( zdev - > pchid ) ;
if ( ! zbus )
return - ENOMEM ;
}
2020-03-23 10:45:43 +01:00
2022-06-28 16:31:00 +02:00
if ( ! zbus - > bus ) {
/* The UID of the first PCI function registered with a zpci_bus
* is used as the domain number for that bus . Currently there
* is exactly one zpci_bus per domain .
*/
2021-02-12 14:19:31 +01:00
rc = zpci_bus_create_pci_bus ( zbus , zdev , ops ) ;
if ( rc )
goto error ;
2020-04-22 15:15:23 +02:00
}
2020-03-23 10:45:43 +01:00
2021-02-12 14:19:31 +01:00
rc = zpci_bus_add_device ( zbus , zdev ) ;
if ( rc )
goto error ;
2020-03-23 10:45:43 +01:00
2020-04-22 15:15:23 +02:00
return 0 ;
error :
2020-03-23 10:45:43 +01:00
pr_err ( " Adding PCI function %08x failed \n " , zdev - > fid ) ;
zpci_bus_put ( zbus ) ;
return rc ;
}
void zpci_bus_device_unregister ( struct zpci_dev * zdev )
{
struct zpci_bus * zbus = zdev - > zbus ;
zpci_nb_devices - - ;
2020-04-22 15:15:23 +02:00
zbus - > function [ zdev - > devfn ] = NULL ;
2020-03-23 10:45:43 +01:00
zpci_bus_put ( zbus ) ;
}