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 * @start: lowest port # to be reserved (inclusive).
 31 * @end:   highest port # to be reserved (exclusive).
 32 *
 33 * @return : Allocated SCIF port #, or -ENOSPC if port unavailable.
 34 *		On memory allocation failure, returns -ENOMEM.
 35 */
 36static int __scif_get_port(int start, int end)
 37{
 38	int id;
 39	struct scif_port *port = kzalloc(sizeof(*port), GFP_ATOMIC);
 40
 41	if (!port)
 42		return -ENOMEM;
 43	spin_lock(&scif_info.port_lock);
 44	id = idr_alloc(&scif_ports, port, start, end, GFP_ATOMIC);
 45	if (id >= 0)
 46		port->ref_cnt++;
 47	spin_unlock(&scif_info.port_lock);
 48	return id;
 49}
 50
 51/**
 52 * scif_rsrv_port - Reserve a specified port # for SCIF.
 53 * @port : port # to be reserved.
 54 *
 55 * @return : Allocated SCIF port #, or -ENOSPC if port unavailable.
 56 *		On memory allocation failure, returns -ENOMEM.
 57 */
 58int scif_rsrv_port(u16 port)
 59{
 60	return __scif_get_port(port, port + 1);
 61}
 62
 63/**
 64 * scif_get_new_port - Get and reserve any port # for SCIF in the range
 65 *			SCIF_PORT_RSVD + 1 to SCIF_PORT_COUNT - 1.
 66 *
 67 * @return : Allocated SCIF port #, or -ENOSPC if no ports available.
 68 *		On memory allocation failure, returns -ENOMEM.
 69 */
 70int scif_get_new_port(void)
 71{
 72	return __scif_get_port(SCIF_PORT_RSVD + 1, SCIF_PORT_COUNT);
 73}
 74
 75/**
 76 * scif_get_port - Increment the reference count for a SCIF port
 77 * @id : SCIF port
 78 *
 79 * @return : None
 80 */
 81void scif_get_port(u16 id)
 82{
 83	struct scif_port *port;
 84
 85	if (!id)
 86		return;
 87	spin_lock(&scif_info.port_lock);
 88	port = idr_find(&scif_ports, id);
 89	if (port)
 90		port->ref_cnt++;
 91	spin_unlock(&scif_info.port_lock);
 92}
 93
 94/**
 95 * scif_put_port - Release a reserved SCIF port
 96 * @id : SCIF port to be released.
 97 *
 98 * @return : None
 99 */
100void scif_put_port(u16 id)
101{
102	struct scif_port *port;
103
104	if (!id)
105		return;
106	spin_lock(&scif_info.port_lock);
107	port = idr_find(&scif_ports, id);
108	if (port) {
109		port->ref_cnt--;
110		if (!port->ref_cnt) {
111			idr_remove(&scif_ports, id);
112			kfree(port);
113		}
114	}
115	spin_unlock(&scif_info.port_lock);
116}