1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright (C) 2005-2006 Intel Corporation
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
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
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
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"
29 * Start/stop scanning in a radio controller
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
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.
42 int uwb_rc_scan(struct uwb_rc
*rc
,
43 unsigned channel
, enum uwb_scan_type type
,
47 struct uwb_rc_cmd_scan
*cmd
;
48 struct uwb_rc_evt_confirm reply
;
51 cmd
= kzalloc(sizeof(*cmd
), GFP_KERNEL
);
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
));
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
);
73 rc
->scanning
= channel
;
76 mutex_unlock(&rc
->uwb_dev
.mutex
);
83 * Print scanning state
85 static ssize_t
uwb_rc_scan_show(struct device
*dev
,
86 struct device_attribute
*attr
, char *buf
)
88 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
89 struct uwb_rc
*rc
= uwb_dev
->rc
;
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
);
101 static ssize_t
uwb_rc_scan_store(struct device
*dev
,
102 struct device_attribute
*attr
,
103 const char *buf
, size_t size
)
105 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
106 struct uwb_rc
*rc
= uwb_dev
->rc
;
109 unsigned bpst_offset
= 0;
110 ssize_t result
= -EINVAL
;
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
);
116 return result
< 0 ? result
: size
;
119 /** Radio Control sysfs interface (declaration) */
120 DEVICE_ATTR(scan
, S_IRUGO
| S_IWUSR
, uwb_rc_scan_show
, uwb_rc_scan_store
);