Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Ultra Wide Band
  4 * Scanning management
  5 *
  6 * Copyright (C) 2005-2006 Intel Corporation
  7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  8 *
  9 * FIXME: docs
 10 * FIXME: there are issues here on how BEACON and SCAN on USB RCI deal
 11 *        with each other. Currently seems that START_BEACON while
 12 *        SCAN_ONLY will cancel the scan, so we need to update the
 13 *        state here. Clarification request sent by email on
 14 *        10/05/2005.
 15 *        10/28/2005 No clear answer heard--maybe we'll hack the API
 16 *                   so that when we start beaconing, if the HC is
 17 *                   scanning in a mode not compatible with beaconing
 18 *                   we just fail.
 19 */
 20
 21#include <linux/device.h>
 22#include <linux/err.h>
 23#include <linux/slab.h>
 24#include <linux/stat.h>
 25#include "uwb-internal.h"
 26
 27
 28/**
 29 * Start/stop scanning in a radio controller
 30 *
 31 * @rc:      UWB Radio Controller
 32 * @channel: Channel to scan; encodings in WUSB1.0[Table 5.12]
 33 * @type:    Type of scanning to do.
 34 * @bpst_offset: value at which to start scanning (if type ==
 35 *                UWB_SCAN_ONLY_STARTTIME)
 36 * @returns: 0 if ok, < 0 errno code on error
 37 *
 38 * We put the command on kmalloc'ed memory as some arches cannot do
 39 * USB from the stack. The reply event is copied from an stage buffer,
 40 * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
 41 */
 42int uwb_rc_scan(struct uwb_rc *rc,
 43		unsigned channel, enum uwb_scan_type type,
 44		unsigned bpst_offset)
 45{
 46	int result;
 47	struct uwb_rc_cmd_scan *cmd;
 48	struct uwb_rc_evt_confirm reply;
 49
 50	result = -ENOMEM;
 51	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 52	if (cmd == NULL)
 53		goto error_kzalloc;
 54	mutex_lock(&rc->uwb_dev.mutex);
 55	cmd->rccb.bCommandType = UWB_RC_CET_GENERAL;
 56	cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SCAN);
 57	cmd->bChannelNumber = channel;
 58	cmd->bScanState = type;
 59	cmd->wStartTime = cpu_to_le16(bpst_offset);
 60	reply.rceb.bEventType = UWB_RC_CET_GENERAL;
 61	reply.rceb.wEvent = UWB_RC_CMD_SCAN;
 62	result = uwb_rc_cmd(rc, "SCAN", &cmd->rccb, sizeof(*cmd),
 63			    &reply.rceb, sizeof(reply));
 64	if (result < 0)
 65		goto error_cmd;
 66	if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
 67		dev_err(&rc->uwb_dev.dev,
 68			"SCAN: command execution failed: %s (%d)\n",
 69			uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
 70		result = -EIO;
 71		goto error_cmd;
 72	}
 73	rc->scanning = channel;
 74	rc->scan_type = type;
 75error_cmd:
 76	mutex_unlock(&rc->uwb_dev.mutex);
 77	kfree(cmd);
 78error_kzalloc:
 79	return result;
 80}
 81
 82/*
 83 * Print scanning state
 84 */
 85static ssize_t uwb_rc_scan_show(struct device *dev,
 86				struct device_attribute *attr, char *buf)
 87{
 88	struct uwb_dev *uwb_dev = to_uwb_dev(dev);
 89	struct uwb_rc *rc = uwb_dev->rc;
 90	ssize_t result;
 91
 92	mutex_lock(&rc->uwb_dev.mutex);
 93	result = sprintf(buf, "%d %d\n", rc->scanning, rc->scan_type);
 94	mutex_unlock(&rc->uwb_dev.mutex);
 95	return result;
 96}
 97
 98/*
 99 *
100 */
101static ssize_t uwb_rc_scan_store(struct device *dev,
102				 struct device_attribute *attr,
103				 const char *buf, size_t size)
104{
105	struct uwb_dev *uwb_dev = to_uwb_dev(dev);
106	struct uwb_rc *rc = uwb_dev->rc;
107	unsigned channel;
108	unsigned type;
109	unsigned bpst_offset = 0;
110	ssize_t result = -EINVAL;
111
112	result = sscanf(buf, "%u %u %u\n", &channel, &type, &bpst_offset);
113	if (result >= 2 && type < UWB_SCAN_TOP)
114		result = uwb_rc_scan(rc, channel, type, bpst_offset);
115
116	return result < 0 ? result : size;
117}
118
119/** Radio Control sysfs interface (declaration) */
120DEVICE_ATTR(scan, S_IRUGO | S_IWUSR, uwb_rc_scan_show, uwb_rc_scan_store);