mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-19 21:00:29 +07:00
1802d0beec
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license version 2 as published by the free software foundation this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 655 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Reviewed-by: Richard Fontana <rfontana@redhat.com> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070034.575739538@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
116 lines
2.4 KiB
C
116 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Intel MIC Platform Software Stack (MPSS)
|
|
*
|
|
* Copyright(c) 2014 Intel Corporation.
|
|
*
|
|
* Intel SCIF driver.
|
|
*/
|
|
#include <linux/idr.h>
|
|
|
|
#include "scif_main.h"
|
|
|
|
#define SCIF_PORT_COUNT 0x10000 /* Ports available */
|
|
|
|
struct idr scif_ports;
|
|
|
|
/*
|
|
* struct scif_port - SCIF port information
|
|
*
|
|
* @ref_cnt - Reference count since there can be multiple endpoints
|
|
* created via scif_accept(..) simultaneously using a port.
|
|
*/
|
|
struct scif_port {
|
|
int ref_cnt;
|
|
};
|
|
|
|
/**
|
|
* __scif_get_port - Reserve a specified port # for SCIF and add it
|
|
* to the global list.
|
|
* @port : port # to be reserved.
|
|
*
|
|
* @return : Allocated SCIF port #, or -ENOSPC if port unavailable.
|
|
* On memory allocation failure, returns -ENOMEM.
|
|
*/
|
|
static int __scif_get_port(int start, int end)
|
|
{
|
|
int id;
|
|
struct scif_port *port = kzalloc(sizeof(*port), GFP_ATOMIC);
|
|
|
|
if (!port)
|
|
return -ENOMEM;
|
|
spin_lock(&scif_info.port_lock);
|
|
id = idr_alloc(&scif_ports, port, start, end, GFP_ATOMIC);
|
|
if (id >= 0)
|
|
port->ref_cnt++;
|
|
spin_unlock(&scif_info.port_lock);
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* scif_rsrv_port - Reserve a specified port # for SCIF.
|
|
* @port : port # to be reserved.
|
|
*
|
|
* @return : Allocated SCIF port #, or -ENOSPC if port unavailable.
|
|
* On memory allocation failure, returns -ENOMEM.
|
|
*/
|
|
int scif_rsrv_port(u16 port)
|
|
{
|
|
return __scif_get_port(port, port + 1);
|
|
}
|
|
|
|
/**
|
|
* scif_get_new_port - Get and reserve any port # for SCIF in the range
|
|
* SCIF_PORT_RSVD + 1 to SCIF_PORT_COUNT - 1.
|
|
*
|
|
* @return : Allocated SCIF port #, or -ENOSPC if no ports available.
|
|
* On memory allocation failure, returns -ENOMEM.
|
|
*/
|
|
int scif_get_new_port(void)
|
|
{
|
|
return __scif_get_port(SCIF_PORT_RSVD + 1, SCIF_PORT_COUNT);
|
|
}
|
|
|
|
/**
|
|
* scif_get_port - Increment the reference count for a SCIF port
|
|
* @id : SCIF port
|
|
*
|
|
* @return : None
|
|
*/
|
|
void scif_get_port(u16 id)
|
|
{
|
|
struct scif_port *port;
|
|
|
|
if (!id)
|
|
return;
|
|
spin_lock(&scif_info.port_lock);
|
|
port = idr_find(&scif_ports, id);
|
|
if (port)
|
|
port->ref_cnt++;
|
|
spin_unlock(&scif_info.port_lock);
|
|
}
|
|
|
|
/**
|
|
* scif_put_port - Release a reserved SCIF port
|
|
* @id : SCIF port to be released.
|
|
*
|
|
* @return : None
|
|
*/
|
|
void scif_put_port(u16 id)
|
|
{
|
|
struct scif_port *port;
|
|
|
|
if (!id)
|
|
return;
|
|
spin_lock(&scif_info.port_lock);
|
|
port = idr_find(&scif_ports, id);
|
|
if (port) {
|
|
port->ref_cnt--;
|
|
if (!port->ref_cnt) {
|
|
idr_remove(&scif_ports, id);
|
|
kfree(port);
|
|
}
|
|
}
|
|
spin_unlock(&scif_info.port_lock);
|
|
}
|