Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Intel MIC Platform Software Stack (MPSS)
  4 *
  5 * Copyright(c) 2014 Intel Corporation.
  6 *
  7 * Intel SCIF driver.
  8 */
  9#include <linux/idr.h>
 10
 11#include "scif_main.h"
 12
 13#define SCIF_PORT_COUNT	0x10000	/* Ports available */
 14
 15struct idr scif_ports;
 16
 17/*
 18 * struct scif_port - SCIF port information
 19 *
 20 * @ref_cnt - Reference count since there can be multiple endpoints
 21 *		created via scif_accept(..) simultaneously using a port.
 22 */
 23struct scif_port {
 24	int ref_cnt;
 25};
 26
 27/**
 28 * __scif_get_port - Reserve a specified port # for SCIF and add it
 29 * to the global list.
 30 * @port : port # to be reserved.
 31 *
 32 * @return : Allocated SCIF port #, or -ENOSPC if port unavailable.
 33 *		On memory allocation failure, returns -ENOMEM.
 34 */
 35static int __scif_get_port(int start, int end)
 36{
 37	int id;
 38	struct scif_port *port = kzalloc(sizeof(*port), GFP_ATOMIC);
 39
 40	if (!port)
 41		return -ENOMEM;
 42	spin_lock(&scif_info.port_lock);
 43	id = idr_alloc(&scif_ports, port, start, end, GFP_ATOMIC);
 44	if (id >= 0)
 45		port->ref_cnt++;
 46	spin_unlock(&scif_info.port_lock);
 47	return id;
 48}
 49
 50/**
 51 * scif_rsrv_port - Reserve a specified port # for SCIF.
 52 * @port : port # to be reserved.
 53 *
 54 * @return : Allocated SCIF port #, or -ENOSPC if port unavailable.
 55 *		On memory allocation failure, returns -ENOMEM.
 56 */
 57int scif_rsrv_port(u16 port)
 58{
 59	return __scif_get_port(port, port + 1);
 60}
 61
 62/**
 63 * scif_get_new_port - Get and reserve any port # for SCIF in the range
 64 *			SCIF_PORT_RSVD + 1 to SCIF_PORT_COUNT - 1.
 65 *
 66 * @return : Allocated SCIF port #, or -ENOSPC if no ports available.
 67 *		On memory allocation failure, returns -ENOMEM.
 68 */
 69int scif_get_new_port(void)
 70{
 71	return __scif_get_port(SCIF_PORT_RSVD + 1, SCIF_PORT_COUNT);
 72}
 73
 74/**
 75 * scif_get_port - Increment the reference count for a SCIF port
 76 * @id : SCIF port
 77 *
 78 * @return : None
 79 */
 80void scif_get_port(u16 id)
 81{
 82	struct scif_port *port;
 83
 84	if (!id)
 85		return;
 86	spin_lock(&scif_info.port_lock);
 87	port = idr_find(&scif_ports, id);
 88	if (port)
 89		port->ref_cnt++;
 90	spin_unlock(&scif_info.port_lock);
 91}
 92
 93/**
 94 * scif_put_port - Release a reserved SCIF port
 95 * @id : SCIF port to be released.
 96 *
 97 * @return : None
 98 */
 99void scif_put_port(u16 id)
100{
101	struct scif_port *port;
102
103	if (!id)
104		return;
105	spin_lock(&scif_info.port_lock);
106	port = idr_find(&scif_ports, id);
107	if (port) {
108		port->ref_cnt--;
109		if (!port->ref_cnt) {
110			idr_remove(&scif_ports, id);
111			kfree(port);
112		}
113	}
114	spin_unlock(&scif_info.port_lock);
115}