linux_dsm_epyc7002/drivers/misc/mic/scif/scif_ports.c
Thomas Gleixner 1802d0beec treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174
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>
2019-05-30 11:26:41 -07:00

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);
}