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