/* * Store a new CHID. * * - Write an all zeros CHID and it will stop the controller * - Write a non-zero CHID and it will start it. * * See wusbhc_chid_set() for more info. */ static ssize_t wusb_chid_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); struct wusb_ckhdid chid; ssize_t result; result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx " "%02hhx %02hhx %02hhx %02hhx " "%02hhx %02hhx %02hhx %02hhx " "%02hhx %02hhx %02hhx %02hhx\n", &chid.data[0] , &chid.data[1] , &chid.data[2] , &chid.data[3] , &chid.data[4] , &chid.data[5] , &chid.data[6] , &chid.data[7] , &chid.data[8] , &chid.data[9] , &chid.data[10], &chid.data[11], &chid.data[12], &chid.data[13], &chid.data[14], &chid.data[15]); if (result != 16) { dev_err(dev, "Unrecognized CHID (need 16 8-bit hex digits): " "%d\n", (int)result); return -EINVAL; } result = wusbhc_chid_set(wusbhc, &chid); return result < 0 ? result : size; }
/* * Show & store the current WUSB trust timeout * * We don't do locking--it is an 'atomic' value. * * The units that we store/show are always MILLISECONDS. However, the * value of trust_timeout is jiffies. */ static ssize_t wusb_trust_timeout_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); return scnprintf(buf, PAGE_SIZE, "%u\n", wusbhc->trust_timeout); }
static ssize_t wusb_phy_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); return sprintf(buf, "%d\n", wusbhc->phy_rate); }
static ssize_t wusb_retry_count_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); return sprintf(buf, "%d\n", wusbhc->retry_count); }
static ssize_t wusb_dnts_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); return sprintf(buf, "num slots: %d\ninterval: %dms\n", wusbhc->dnts_num_slots, wusbhc->dnts_interval); }
/* * Show the current WUSB CHID. */ static ssize_t wusb_chid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); const struct wusb_ckhdid *chid; ssize_t result = 0; if (wusbhc->wuie_host_info != NULL) chid = &wusbhc->wuie_host_info->CHID; else chid = &wusb_ckhdid_zero; result += ckhdid_printf(buf, PAGE_SIZE, chid); result += sprintf(buf + result, "\n"); return result; }
static ssize_t wusb_phy_rate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); uint8_t phy_rate; ssize_t result; result = sscanf(buf, "%hhu", &phy_rate); if (result != 1) return -EINVAL; if (phy_rate >= UWB_PHY_RATE_INVALID) return -EINVAL; wusbhc->phy_rate = phy_rate; return size; }
static ssize_t wusb_retry_count_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); uint8_t retry_count; ssize_t result; result = sscanf(buf, "%hhu", &retry_count); if (result != 1) return -EINVAL; wusbhc->retry_count = max_t(uint8_t, retry_count, WUSB_RETRY_COUNT_MAX); return size; }
static ssize_t wusb_dnts_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); uint8_t num_slots, interval; ssize_t result; result = sscanf(buf, "%hhu %hhu", &num_slots, &interval); if (result != 2) return -EINVAL; wusbhc->dnts_num_slots = num_slots; wusbhc->dnts_interval = interval; return size; }
static ssize_t wusb_trust_timeout_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); ssize_t result = -ENOSYS; unsigned trust_timeout; result = sscanf(buf, "%u", &trust_timeout); if (result != 1) { result = -EINVAL; goto out; } wusbhc->trust_timeout = min_t(unsigned, trust_timeout, 500); cancel_delayed_work(&wusbhc->keep_alive_timer); flush_workqueue(wusbd); queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, msecs_to_jiffies(wusbhc->trust_timeout / 2)); out: return result < 0 ? result : size; }
static ssize_t wusb_trust_timeout_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); ssize_t result = -ENOSYS; unsigned trust_timeout; result = sscanf(buf, "%u", &trust_timeout); if (result != 1) { result = -EINVAL; goto out; } /* FIXME: maybe we should check for range validity? */ wusbhc->trust_timeout = trust_timeout; cancel_delayed_work(&wusbhc->keep_alive_timer); flush_workqueue(wusbd); queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, (trust_timeout * CONFIG_HZ)/1000/2); out: return result < 0 ? result : size; }