static void __init zfcp_init_device_setup(char *devstr) { char *token; char *str; char busid[ZFCP_BUS_ID_SIZE]; u64 wwpn, lun; /* duplicate devstr and keep the original for sysfs presentation*/ str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); if (!str) return; strcpy(str, devstr); token = strsep(&str, ","); if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE) goto err_out; strncpy(busid, token, ZFCP_BUS_ID_SIZE); token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, (unsigned long long *) &wwpn)) goto err_out; token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) goto err_out; kfree(str); zfcp_init_device_configure(busid, wwpn, lun); return; err_out: kfree(str); pr_err("%s is not a valid SCSI device\n", devstr); }
/** * strict_strtoll - convert a string to a long long strictly * @cp: The string to be converted * @base: The number base to use * @res: The converted result value * * strict_strtoll is similiar to strict_strtoull, but it allows the first * character of a string is '-'. * * It returns 0 if conversion is successful and *res is set to the converted * value, otherwise it returns -EINVAL and *res is set to 0. */ int strict_strtoll(const char *cp, unsigned int base, long long *res) { int ret; if (*cp == '-') { ret = strict_strtoull(cp + 1, base, (unsigned long long *)res); if (!ret) *res = -(*res); } else { ret = strict_strtoull(cp, base, (unsigned long long *)res); } return ret; }
static ssize_t ieee80211_if_parse_tsf( struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) { struct ieee80211_local *local = sdata->local; unsigned long long tsf; int ret; if (strncmp(buf, "reset", 5) == 0) { if (local->ops->reset_tsf) { drv_reset_tsf(local, sdata); wiphy_info(local->hw.wiphy, "debugfs reset TSF\n"); } } else { ret = strict_strtoull(buf, 10, &tsf); if (ret < 0) return -EINVAL; if (local->ops->set_tsf) { drv_set_tsf(local, sdata, tsf); wiphy_info(local->hw.wiphy, "debugfs set TSF to %#018llx\n", tsf); } } return buflen; }
/** * debug_window_fwrite - Write function for "window" debugfs entry * @filp: The active open file structure for the debugfs "file" * @ubuf: The user buffer that contains the value to write * @cnt: The maximum number of bytes to write to "file" * @ppos: The current position in the debugfs "file" * * This function provides a write implementation for the "window" debufds * interface to the hardware latency detetector. The window is the total time * in us that will be considered one sample period. Conceptually, windows * occur back-to-back and contain a sample width period during which * actual sampling occurs. Can be used to write a new total window size. It * is enfoced that any value written must be greater than the sample width * size, or an error results. */ static ssize_t debug_window_fwrite(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[U64STR_SIZE]; int csize = min(cnt, sizeof(buf)); u64 val = 0; int err = 0; memset(buf, '\0', sizeof(buf)); if (copy_from_user(buf, ubuf, csize)) return -EFAULT; buf[U64STR_SIZE-1] = '\0'; /* just in case */ err = strict_strtoull(buf, 10, &val); if (0 != err) return -EINVAL; mutex_lock(&data.lock); if (data.sample_width < val) data.sample_window = val; else { mutex_unlock(&data.lock); return -EINVAL; } mutex_unlock(&data.lock); return csize; }
static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ccw_device *cdev = to_ccwdev(dev); struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); struct zfcp_port *port; u64 wwpn; int retval = -EINVAL; if (!adapter) return -ENODEV; if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) goto out; port = zfcp_get_port_by_wwpn(adapter, wwpn); if (!port) goto out; else retval = 0; write_lock_irq(&adapter->port_list_lock); list_del(&port->list); write_unlock_irq(&adapter->port_list_lock); put_device(&port->dev); zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL); zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); out: zfcp_ccw_adapter_put(adapter); return retval ? retval : (ssize_t) count; }
static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); struct zfcp_unit *unit; u64 fcp_lun; int retval = -EINVAL; if (!(port && get_device(&port->dev))) return -EBUSY; if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) goto out; unit = zfcp_unit_enqueue(port, fcp_lun); if (IS_ERR(unit)) goto out; else retval = 0; zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); zfcp_erp_wait(unit->port->adapter); zfcp_scsi_scan(unit); out: put_device(&port->dev); return retval ? retval : (ssize_t) count; }
static void dummy_proc_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { char line[64]; while (!snd_info_get_line(buffer, line, sizeof(line))) { char item[20]; const char *ptr; unsigned long long val; int i; ptr = snd_info_get_str(item, line, sizeof(item)); for (i = 0; i < ARRAY_SIZE(fields); i++) { if (!strcmp(item, fields[i].name)) break; } if (i >= ARRAY_SIZE(fields)) continue; snd_info_get_str(item, ptr, sizeof(item)); if (strict_strtoull(item, 0, &val)) continue; if (fields[i].size == sizeof(int)) *get_dummy_int_ptr(fields[i].offset) = val; else *get_dummy_ll_ptr(fields[i].offset) = val; } }
static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = dev_get_drvdata(dev); struct zfcp_unit *unit; u64 fcp_lun; int retval = -EINVAL; mutex_lock(&zfcp_data.config_mutex); if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { retval = -EBUSY; goto out; } if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) goto out; unit = zfcp_unit_enqueue(port, fcp_lun); if (IS_ERR(unit)) goto out; retval = 0; zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); zfcp_erp_wait(unit->port->adapter); flush_work(&unit->scsi_work); zfcp_unit_put(unit); out: mutex_unlock(&zfcp_data.config_mutex); return retval ? retval : (ssize_t) count; }
static ssize_t pool_set_type_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret; struct xzram *xzram = dev_to_xzram(dev); u64 type; if (xzram->init_done) { pr_info("Cannot set pool type for initialized device\n"); return -EBUSY; } ret = strict_strtoull(buf, 10, &type); if((type > 1) || (type < 0)) { pr_info("Warnning type can be only assign to 0(internal) or 1(external), default set to internal\n"); xzram->pool_info[set_pool_id].type = 0; } else { if(type == 0) xzram->pool_info[set_pool_id].type = 0; // internal pool with limited size else xzram->pool_info[set_pool_id].type = 1; // external pool with limited size } return len; }
static ssize_t pool_set_id_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret; u64 id; struct xzram *xzram = dev_to_xzram(dev); down_write(&xzram->lock); ret = strict_strtoull(buf, 10, &id); set_pool_id = (u32) id; if(id == 0) { pr_info("Pool id 0 is default set to internal, do not change it\n"); up_write(&xzram->lock); return -EINVAL; } xzram->pool_info[set_pool_id].pool_id = set_pool_id; pr_info("Change set pool id to %d\n", set_pool_id); if ( set_pool_id > MAX_POOL_NUM ) { pr_info("Warnning max pool id is = %d!!\n", MAX_POOL_NUM); up_write(&xzram->lock); return -EINVAL; } up_write(&xzram->lock); return len; }
static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = dev_get_drvdata(dev); struct zfcp_unit *unit; fcp_lun_t fcp_lun; int retval = -EINVAL; down(&zfcp_data.config_sema); if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { retval = -EBUSY; goto out; } if (strict_strtoull(buf, 0, &fcp_lun)) goto out; unit = zfcp_unit_enqueue(port, fcp_lun); if (IS_ERR(unit)) goto out; retval = 0; zfcp_erp_unit_reopen(unit, 0, 94, NULL); zfcp_erp_wait(unit->port->adapter); zfcp_unit_put(unit); out: up(&zfcp_data.config_sema); return retval ? retval : (ssize_t) count; }
static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = dev_get_drvdata(dev); struct zfcp_unit *unit; u64 fcp_lun; LIST_HEAD(unit_remove_lh); struct scsi_device *sdev; mutex_lock(&zfcp_data.config_mutex); if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { mutex_unlock(&zfcp_data.config_mutex); return -EBUSY; } if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) { mutex_unlock(&zfcp_data.config_mutex); return -EINVAL; } read_lock_irq(&zfcp_data.config_lock); unit = zfcp_get_unit_by_lun(port, fcp_lun); read_unlock_irq(&zfcp_data.config_lock); if (!unit) { mutex_unlock(&zfcp_data.config_mutex); return -ENXIO; } zfcp_unit_get(unit); mutex_unlock(&zfcp_data.config_mutex); sdev = scsi_device_lookup(port->adapter->scsi_host, 0, port->starget_id, scsilun_to_int((struct scsi_lun *)&fcp_lun)); if (sdev) { scsi_remove_device(sdev); scsi_device_put(sdev); } mutex_lock(&zfcp_data.config_mutex); zfcp_unit_put(unit); if (atomic_read(&unit->refcount)) { mutex_unlock(&zfcp_data.config_mutex); return -ENXIO; } write_lock_irq(&zfcp_data.config_lock); atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); list_move(&unit->list, &unit_remove_lh); write_unlock_irq(&zfcp_data.config_lock); mutex_unlock(&zfcp_data.config_mutex); zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); zfcp_erp_wait(unit->port->adapter); zfcp_unit_dequeue(unit); return (ssize_t)count; }
static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = dev_get_drvdata(dev); struct zfcp_unit *unit; u64 fcp_lun; int retval = 0; LIST_HEAD(unit_remove_lh); mutex_lock(&zfcp_data.config_mutex); if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { retval = -EBUSY; goto out; } if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) { retval = -EINVAL; goto out; } write_lock_irq(&zfcp_data.config_lock); unit = zfcp_get_unit_by_lun(port, fcp_lun); if (unit) { write_unlock_irq(&zfcp_data.config_lock); flush_work(&unit->scsi_work); write_lock_irq(&zfcp_data.config_lock); if (atomic_read(&unit->refcount) == 0) { zfcp_unit_get(unit); atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); list_move(&unit->list, &unit_remove_lh); } else { unit = NULL; } } write_unlock_irq(&zfcp_data.config_lock); if (!unit) { retval = -ENXIO; goto out; } zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); zfcp_erp_wait(unit->port->adapter); zfcp_unit_put(unit); zfcp_unit_dequeue(unit); out: mutex_unlock(&zfcp_data.config_mutex); return retval ? retval : (ssize_t) count; }
static int __init zfcp_device_setup(char *devstr) { char *token; char *str; if (!devstr) return 0; /* duplicate devstr and keep the original for sysfs presentation*/ str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); if (!str) return 0; strcpy(str, devstr); token = strsep(&str, ","); if (!token || strlen(token) >= BUS_ID_SIZE) goto err_out; strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE); token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, (unsigned long long *) &zfcp_data.init_wwpn)) goto err_out; token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, (unsigned long long *) &zfcp_data.init_fcp_lun)) goto err_out; kfree(str); return 1; err_out: kfree(str); pr_err("zfcp: %s is not a valid SCSI device\n", devstr); return 0; }
static int __init zfcp_device_setup(char *devstr) { char *token; char *str; if (!devstr) return 0; /* duplicate devstr and keep the original for sysfs presentation*/ str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); if (!str) return 0; strcpy(str, devstr); token = strsep(&str, ","); if (!token || strlen(token) >= BUS_ID_SIZE) goto err_out; strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE); token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, &zfcp_data.init_wwpn)) goto err_out; token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, &zfcp_data.init_fcp_lun)) goto err_out; kfree(str); return 1; err_out: kfree(str); pr_err("zfcp: Parse error for device parameter string %s, " "device not attached.\n", devstr); return 0; }
/* Forcibly offline a page, including killing processes. */ static ssize_t store_hard_offline_page(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int ret; u64 pfn; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (strict_strtoull(buf, 0, &pfn) < 0) return -EINVAL; pfn >>= PAGE_SHIFT; ret = __memory_failure(pfn, 0, 0); return ret ? ret : count; }
static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); u64 fcp_lun; if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) return -EINVAL; if (zfcp_unit_remove(port, fcp_lun)) return -EINVAL; return count; }
/* * cf. linux/lib/parser.c and cmdline.c * gave up calling memparse() since it uses simple_strtoull() instead of * strict_...(). */ static int au_match_ull(substring_t *s, unsigned long long *result) { int err; unsigned int len; char a[32]; err = -ERANGE; len = s->to - s->from; if (len + 1 <= sizeof(a)) { memcpy(a, s->from, len); a[len] = '\0'; err = strict_strtoull(a, 0, result); } return err; }
static ssize_t pool_set_ba_start_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret; struct xzram *xzram = dev_to_xzram(dev); if (xzram->init_done) { pr_info("Cannot set bus address for initialized device\n"); return -EBUSY; } ret = strict_strtoull(buf, 10, &xzram->pool_info[set_pool_id].ext_ba_start); return len; }
/* Soft offline a page */ static ssize_t store_soft_offline_page(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int ret; u64 pfn; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (strict_strtoull(buf, 0, &pfn) < 0) return -EINVAL; pfn >>= PAGE_SHIFT; if (!pfn_valid(pfn)) return -ENXIO; ret = soft_offline_page(pfn_to_page(pfn), 0); return ret == 0 ? count : ret; }
static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_adapter *adapter = dev_get_drvdata(dev); struct zfcp_port *port; u64 wwpn; int retval = 0; LIST_HEAD(port_remove_lh); mutex_lock(&zfcp_data.config_mutex); if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { retval = -EBUSY; goto out; } if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) { retval = -EINVAL; goto out; } write_lock_irq(&zfcp_data.config_lock); port = zfcp_get_port_by_wwpn(adapter, wwpn); if (port && (atomic_read(&port->refcount) == 0)) { zfcp_port_get(port); atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); list_move(&port->list, &port_remove_lh); } else port = NULL; write_unlock_irq(&zfcp_data.config_lock); if (!port) { retval = -ENXIO; goto out; } zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL); zfcp_erp_wait(adapter); zfcp_port_put(port); zfcp_port_dequeue(port); out: mutex_unlock(&zfcp_data.config_mutex); return retval ? retval : (ssize_t) count; }
static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = dev_get_drvdata(dev); struct zfcp_unit *unit; fcp_lun_t fcp_lun; int retval = 0; down(&zfcp_data.config_sema); if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { retval = -EBUSY; goto out; } if (strict_strtoull(buf, 0, &fcp_lun)) { retval = -EINVAL; goto out; } write_lock_irq(&zfcp_data.config_lock); unit = zfcp_get_unit_by_lun(port, fcp_lun); if (unit && (atomic_read(&unit->refcount) == 0)) { zfcp_unit_get(unit); atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); list_move(&unit->list, &port->unit_remove_lh); } else unit = NULL; write_unlock_irq(&zfcp_data.config_lock); if (!unit) { retval = -ENXIO; goto out; } zfcp_erp_unit_shutdown(unit, 0, 95, NULL); zfcp_erp_wait(unit->port->adapter); zfcp_unit_put(unit); zfcp_unit_dequeue(unit); out: up(&zfcp_data.config_sema); return retval ? retval : (ssize_t) count; }
static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ccw_device *cdev = to_ccwdev(dev); struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); struct zfcp_port *port; u64 wwpn; int retval = -EINVAL; if (!adapter) return -ENODEV; if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) goto out; port = zfcp_get_port_by_wwpn(adapter, wwpn); if (!port) goto out; else retval = 0; mutex_lock(&zfcp_sysfs_port_units_mutex); if (atomic_read(&port->units) > 0) { retval = -EBUSY; mutex_unlock(&zfcp_sysfs_port_units_mutex); goto out; } /* port is about to be removed, so no more unit_add */ atomic_set(&port->units, -1); mutex_unlock(&zfcp_sysfs_port_units_mutex); write_lock_irq(&adapter->port_list_lock); list_del(&port->list); write_unlock_irq(&adapter->port_list_lock); put_device(&port->dev); zfcp_erp_port_shutdown(port, 0, "syprs_1"); zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); out: zfcp_ccw_adapter_put(adapter); return retval ? retval : (ssize_t) count; }
static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); struct zfcp_unit *unit; u64 fcp_lun; int retval = -EINVAL; struct scsi_device *sdev; if (!(port && get_device(&port->dev))) return -EBUSY; if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) goto out; unit = zfcp_get_unit_by_lun(port, fcp_lun); if (!unit) goto out; else retval = 0; sdev = scsi_device_lookup(port->adapter->scsi_host, 0, port->starget_id, scsilun_to_int((struct scsi_lun *)&fcp_lun)); if (sdev) { scsi_remove_device(sdev); scsi_device_put(sdev); } write_lock_irq(&port->unit_list_lock); list_del(&unit->list); write_unlock_irq(&port->unit_list_lock); put_device(&unit->dev); zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); out: put_device(&port->dev); return retval ? retval : (ssize_t) count; }
static ssize_t disksize_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret; struct zram *zram = dev_to_zram(dev); if (zram->init_done) { pr_info("Cannot change disksize for initialized device\n"); return -EBUSY; } ret = strict_strtoull(buf, 10, &zram->disksize); if (ret) return ret; zram->disksize = PAGE_ALIGN(zram->disksize); set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); return len; }
static ssize_t pool_set_activate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret; struct xzram *xzram = dev_to_xzram(dev); u64 activate; if (xzram->init_done) { pr_info("Cannot set pool size for initialized device\n"); return -EBUSY; } ret = strict_strtoull(buf, 10, &activate); if(activate ==1) { xzram->pool_info[set_pool_id].activate = (u8) 1; } return len; }
static ssize_t pool_set_migrate_stat_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret; struct xzram *xzram = dev_to_xzram(dev); int val; if (!xzram->init_done) { pr_info("Cannot set migration store while device is not ready\n"); return -EBUSY; } ret = strict_strtoull(buf, 10, &val); down_write(&xzram->lock); if(val != MIGRATION_STAT_NO_JOB) { pr_info("Only value 0 is acceptable \n"); up_write(&xzram->lock); return len; } if(xzram->pool_migration_stat == MIGRATION_STAT_ONGO) { pr_info("migration is on process!! \n"); up_write(&xzram->lock); return len; } if((xzram->pool_migration_stat == MIGRATION_STAT_DONE)|| (xzram->pool_migration_stat == MIGRATION_STAT_FAIL)) { xzram->pool_migration_stat = MIGRATION_STAT_NO_JOB; } up_write(&xzram->lock); return len; }
/* * accept a hex value and store it into the virtual error register file, field: * nbeal and nbeah. Assume virtual error values have already been set for: NBSL, * NBSH and NBCFG. Then proceed to map the error values to a MC, CSROW and * CHANNEL */ static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data, size_t count) { struct amd64_pvt *pvt = mci->pvt_info; unsigned long long value; int ret = 0; ret = strict_strtoull(data, 16, &value); if (ret != -EINVAL) { debugf0("received NBEA= 0x%llx\n", value); /* place the value into the virtual error packet */ pvt->ctl_error_info.nbeal = (u32) value; value >>= 32; pvt->ctl_error_info.nbeah = (u32) value; /* Process the Mapping request */ /* TODO: Add race prevention */ amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1); return count; }
/* * simple_data_write - Wrapper write function for global state debugfs entries * @filp: The active open file structure for the debugfs "file" * @ubuf: The userspace provided buffer to write value from * @cnt: The maximum number of bytes to write * @ppos: The current "file" position * @entry: The entry to write to * * This function provides a generic write implementation for the global state * "data" structure debugfs filesystem entries. It would be nice to use * simple_attr_write directly, but we need to make sure that the data.lock * spinlock is held during the actual write (even though we likely won't ever * actually race here as the updater runs under a stop_machine context). */ static ssize_t simple_data_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u64 *entry) { char buf[U64STR_SIZE]; int csize = min(cnt, sizeof(buf)); u64 val = 0; int err = 0; memset(buf, '\0', sizeof(buf)); if (copy_from_user(buf, ubuf, csize)) return -EFAULT; buf[U64STR_SIZE-1] = '\0'; /* just in case */ err = strict_strtoull(buf, 10, &val); if (err) return -EINVAL; mutex_lock(&data.lock); *entry = val; mutex_unlock(&data.lock); return csize; }
static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); struct i2c_client *client = to_i2c_client(dev); char *endp; u64 val; __le32 val_le; int rc; dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name); /* Decode input */ val = strict_strtoull(buf, &endp, 0); if (buf == endp) { dev_dbg(dev, "input string not a number\n"); return -EINVAL; } /* Special case: the 32 bit regs are time values with 1/4s * resolution, scale input down to quarter-seconds */ if (sattr->nr == 4) do_div(val, 250); /* write out the value */ val_le = cpu_to_le32(val); rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr, (u8 *) &val_le); if (rc < 0) { dev_err(dev, "register write failed; reg=0x%x, size=%i\n", sattr->index, sattr->nr); return -EIO; } return count; }