1 2 3#include <linux/device.h> 4#include <linux/err.h> 5#include <linux/slab.h> 6#include "uwb-internal.h" 7 8 9/** 10 * Start/stop scanning in a radio controller 11 * 12 * @rc: UWB Radio Controlller 13 * @channel: Channel to scan; encodings in WUSB1.0[Table 5.12] 14 * @type: Type of scanning to do. 15 * @bpst_offset: value at which to start scanning (if type == 16 * UWB_SCAN_ONLY_STARTTIME) 17 * @returns: 0 if ok, < 0 errno code on error 18 * 19 * We put the command on kmalloc'ed memory as some arches cannot do 20 * USB from the stack. The reply event is copied from an stage buffer, 21 * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details. 22 */ 23int uwb_rc_scan(struct uwb_rc *rc, 24 unsigned channel, enum uwb_scan_type type, 25 unsigned bpst_offset) 26{ 27 int result; 28 struct uwb_rc_cmd_scan *cmd; 29 struct uwb_rc_evt_confirm reply; 30 31 result = -ENOMEM; 32 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 33 if (cmd == NULL) 34 goto error_kzalloc; 35 mutex_lock(&rc->uwb_dev.mutex); 36 cmd->rccb.bCommandType = UWB_RC_CET_GENERAL; 37 cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SCAN); 38 cmd->bChannelNumber = channel; 39 cmd->bScanState = type; 40 cmd->wStartTime = cpu_to_le16(bpst_offset); 41 reply.rceb.bEventType = UWB_RC_CET_GENERAL; 42 reply.rceb.wEvent = UWB_RC_CMD_SCAN; 43 result = uwb_rc_cmd(rc, "SCAN", &cmd->rccb, sizeof(*cmd), 44 &reply.rceb, sizeof(reply)); 45 if (result < 0) 46 goto error_cmd; 47 if (reply.bResultCode != UWB_RC_RES_SUCCESS) { 48 dev_err(&rc->uwb_dev.dev, 49 "SCAN: command execution failed: %s (%d)\n", 50 uwb_rc_strerror(reply.bResultCode), reply.bResultCode); 51 result = -EIO; 52 goto error_cmd; 53 } 54 rc->scanning = channel; 55 rc->scan_type = type; 56error_cmd: 57 mutex_unlock(&rc->uwb_dev.mutex); 58 kfree(cmd); 59error_kzalloc: 60 return result; 61} 62 63/* 64 * Print scanning state 65 */ 66static ssize_t uwb_rc_scan_show(struct device *dev, 67 struct device_attribute *attr, char *buf) 68{ 69 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 70 struct uwb_rc *rc = uwb_dev->rc; 71 ssize_t result; 72 73 mutex_lock(&rc->uwb_dev.mutex); 74 result = sprintf(buf, "%d %d\n", rc->scanning, rc->scan_type); 75 mutex_unlock(&rc->uwb_dev.mutex); 76 return result; 77} 78 79/* 80 * 81 */ 82static ssize_t uwb_rc_scan_store(struct device *dev, 83 struct device_attribute *attr, 84 const char *buf, size_t size) 85{ 86 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 87 struct uwb_rc *rc = uwb_dev->rc; 88 unsigned channel; 89 unsigned type; 90 unsigned bpst_offset = 0; 91 ssize_t result = -EINVAL; 92 93 result = sscanf(buf, "%u %u %u\n", &channel, &type, &bpst_offset); 94 if (result >= 2 && type < UWB_SCAN_TOP) 95 result = uwb_rc_scan(rc, channel, type, bpst_offset); 96 97 return result < 0 ? result : size; 98} 99 100/** Radio Control sysfs interface (declaration) */ 101DEVICE_ATTR(scan, S_IRUGO | S_IWUSR, uwb_rc_scan_show, uwb_rc_scan_store); 102