diff options
Diffstat (limited to 'drivers/staging/most/core.c')
-rw-r--r-- | drivers/staging/most/core.c | 305 |
1 files changed, 136 insertions, 169 deletions
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 18936cdb1083..86a8545c8d97 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -272,19 +272,6 @@ static ssize_t set_number_of_buffers_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.num_buffers); } -static ssize_t set_number_of_buffers_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct most_channel *c = to_channel(dev); - int ret = kstrtou16(buf, 0, &c->cfg.num_buffers); - - if (ret) - return ret; - return count; -} - static ssize_t set_buffer_size_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -294,19 +281,6 @@ static ssize_t set_buffer_size_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.buffer_size); } -static ssize_t set_buffer_size_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct most_channel *c = to_channel(dev); - int ret = kstrtou16(buf, 0, &c->cfg.buffer_size); - - if (ret) - return ret; - return count; -} - static ssize_t set_direction_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -320,28 +294,6 @@ static ssize_t set_direction_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "unconfigured\n"); } -static ssize_t set_direction_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct most_channel *c = to_channel(dev); - - if (!strcmp(buf, "dir_rx\n")) { - c->cfg.direction = MOST_CH_RX; - } else if (!strcmp(buf, "rx\n")) { - c->cfg.direction = MOST_CH_RX; - } else if (!strcmp(buf, "dir_tx\n")) { - c->cfg.direction = MOST_CH_TX; - } else if (!strcmp(buf, "tx\n")) { - c->cfg.direction = MOST_CH_TX; - } else { - pr_info("WARN: invalid attribute settings\n"); - return -EINVAL; - } - return count; -} - static ssize_t set_datatype_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -356,28 +308,6 @@ static ssize_t set_datatype_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "unconfigured\n"); } -static ssize_t set_datatype_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - int i; - struct most_channel *c = to_channel(dev); - - for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { - if (!strcmp(buf, ch_data_type[i].name)) { - c->cfg.data_type = ch_data_type[i].most_ch_data_type; - break; - } - } - - if (i == ARRAY_SIZE(ch_data_type)) { - pr_info("WARN: invalid attribute settings\n"); - return -EINVAL; - } - return count; -} - static ssize_t set_subbuffer_size_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -387,19 +317,6 @@ static ssize_t set_subbuffer_size_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.subbuffer_size); } -static ssize_t set_subbuffer_size_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct most_channel *c = to_channel(dev); - int ret = kstrtou16(buf, 0, &c->cfg.subbuffer_size); - - if (ret) - return ret; - return count; -} - static ssize_t set_packets_per_xact_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -409,19 +326,6 @@ static ssize_t set_packets_per_xact_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.packets_per_xact); } -static ssize_t set_packets_per_xact_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct most_channel *c = to_channel(dev); - int ret = kstrtou16(buf, 0, &c->cfg.packets_per_xact); - - if (ret) - return ret; - return count; -} - static ssize_t set_dbr_size_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -430,18 +334,6 @@ static ssize_t set_dbr_size_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.dbr_size); } -static ssize_t set_dbr_size_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct most_channel *c = to_channel(dev); - int ret = kstrtou16(buf, 0, &c->cfg.dbr_size); - - if (ret) - return ret; - return count; -} - #define to_dev_attr(a) container_of(a, struct device_attribute, attr) static umode_t channel_attr_is_visible(struct kobject *kobj, struct attribute *attr, int index) @@ -469,13 +361,13 @@ static DEVICE_ATTR_RO(number_of_stream_buffers); static DEVICE_ATTR_RO(size_of_stream_buffer); static DEVICE_ATTR_RO(size_of_packet_buffer); static DEVICE_ATTR_RO(channel_starving); -static DEVICE_ATTR_RW(set_buffer_size); -static DEVICE_ATTR_RW(set_number_of_buffers); -static DEVICE_ATTR_RW(set_direction); -static DEVICE_ATTR_RW(set_datatype); -static DEVICE_ATTR_RW(set_subbuffer_size); -static DEVICE_ATTR_RW(set_packets_per_xact); -static DEVICE_ATTR_RW(set_dbr_size); +static DEVICE_ATTR_RO(set_buffer_size); +static DEVICE_ATTR_RO(set_number_of_buffers); +static DEVICE_ATTR_RO(set_direction); +static DEVICE_ATTR_RO(set_datatype); +static DEVICE_ATTR_RO(set_subbuffer_size); +static DEVICE_ATTR_RO(set_packets_per_xact); +static DEVICE_ATTR_RO(set_dbr_size); static struct attribute *channel_attrs[] = { DEV_ATTR(available_directions), @@ -701,6 +593,7 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch) static inline int link_channel_to_component(struct most_channel *c, struct core_component *comp, + char *name, char *comp_param) { int ret; @@ -714,7 +607,8 @@ inline int link_channel_to_component(struct most_channel *c, return -ENOSPC; *comp_ptr = comp; - ret = comp->probe_channel(c->iface, c->channel_id, &c->cfg, comp_param); + ret = comp->probe_channel(c->iface, c->channel_id, &c->cfg, name, + comp_param); if (ret) { *comp_ptr = NULL; return ret; @@ -722,65 +616,118 @@ inline int link_channel_to_component(struct most_channel *c, return 0; } -/** - * add_link_store - store function for add_link attribute - * @drv: device driver - * @buf: buffer - * @len: buffer length - * - * This parses the string given by buf and splits it into - * four substrings. Note: last substring is optional. In case a cdev - * component is loaded the optional 4th substring will make up the name of - * device node in the /dev directory. If omitted, the device node will - * inherit the channel's name within sysfs. - * - * Searches for (device, channel) pair and probes the component - * - * Example: - * (1) echo "mdev0:ch6:cdev:my_rxchannel" >add_link - * (2) echo "mdev1:ep81:cdev" >add_link - * - * (1) would create the device node /dev/my_rxchannel - * (2) would create the device node /dev/mdev1-ep81 - */ -static ssize_t add_link_store(struct device_driver *drv, - const char *buf, - size_t len) +int most_set_cfg_buffer_size(char *mdev, char *mdev_ch, u16 val) { - struct most_channel *c; - struct core_component *comp; - char buffer[STRING_SIZE]; - char *mdev; - char *mdev_ch; - char *comp_name; - char *comp_param; - char devnod_buf[STRING_SIZE]; - int ret; - size_t max_len = min_t(size_t, len + 1, STRING_SIZE); + struct most_channel *c = get_channel(mdev, mdev_ch); - strlcpy(buffer, buf, max_len); - ret = split_string(buffer, &mdev, &mdev_ch, &comp_name, &comp_param); - if (ret) - return ret; - comp = match_component(comp_name); - if (!comp) + if (!c) return -ENODEV; - if (!comp_param || *comp_param == 0) { - snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev, - mdev_ch); - comp_param = devnod_buf; + c->cfg.buffer_size = val; + return 0; +} + +int most_set_cfg_subbuffer_size(char *mdev, char *mdev_ch, u16 val) +{ + struct most_channel *c = get_channel(mdev, mdev_ch); + + if (!c) + return -ENODEV; + c->cfg.subbuffer_size = val; + return 0; +} + +int most_set_cfg_dbr_size(char *mdev, char *mdev_ch, u16 val) +{ + struct most_channel *c = get_channel(mdev, mdev_ch); + + if (!c) + return -ENODEV; + c->cfg.dbr_size = val; + return 0; +} + +int most_set_cfg_num_buffers(char *mdev, char *mdev_ch, u16 val) +{ + struct most_channel *c = get_channel(mdev, mdev_ch); + + if (!c) + return -ENODEV; + c->cfg.num_buffers = val; + return 0; +} + +int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf) +{ + int i; + struct most_channel *c = get_channel(mdev, mdev_ch); + + if (!c) + return -ENODEV; + for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { + if (!strcmp(buf, ch_data_type[i].name)) { + c->cfg.data_type = ch_data_type[i].most_ch_data_type; + break; + } } - c = get_channel(mdev, mdev_ch); + if (i == ARRAY_SIZE(ch_data_type)) + pr_info("WARN: invalid attribute settings\n"); + return 0; +} + +int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf) +{ + struct most_channel *c = get_channel(mdev, mdev_ch); + + if (!c) + return -ENODEV; + if (!strcmp(buf, "dir_rx\n")) { + c->cfg.direction = MOST_CH_RX; + } else if (!strcmp(buf, "rx\n")) { + c->cfg.direction = MOST_CH_RX; + } else if (!strcmp(buf, "dir_tx\n")) { + c->cfg.direction = MOST_CH_TX; + } else if (!strcmp(buf, "tx\n")) { + c->cfg.direction = MOST_CH_TX; + } else { + pr_info("Invalid direction\n"); + return -ENODATA; + } + return 0; +} + +int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val) +{ + struct most_channel *c = get_channel(mdev, mdev_ch); + if (!c) return -ENODEV; + c->cfg.packets_per_xact = val; + return 0; +} + +int most_cfg_complete(char *comp_name) +{ + struct core_component *comp; + + comp = match_component(comp_name); + if (!comp) + return -ENODEV; - ret = link_channel_to_component(c, comp, comp_param); - if (ret) - return ret; - return len; + return comp->cfg_complete(); } +int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name, + char *comp_param) +{ + struct most_channel *c = get_channel(mdev, mdev_ch); + struct core_component *comp = match_component(comp_name); + + if (!c || !comp) + return -ENODEV; + + return link_channel_to_component(c, comp, link_name, comp_param); +} /** * remove_link_store - store function for remove_link attribute * @drv: device driver @@ -823,17 +770,36 @@ static ssize_t remove_link_store(struct device_driver *drv, return len; } +int most_remove_link(char *mdev, char *mdev_ch, char *comp_name) +{ + struct most_channel *c; + struct core_component *comp; + + comp = match_component(comp_name); + if (!comp) + return -ENODEV; + c = get_channel(mdev, mdev_ch); + if (!c) + return -ENODEV; + + if (comp->disconnect_channel(c->iface, c->channel_id)) + return -EIO; + if (c->pipe0.comp == comp) + c->pipe0.comp = NULL; + if (c->pipe1.comp == comp) + c->pipe1.comp = NULL; + return 0; +} + #define DRV_ATTR(_name) (&driver_attr_##_name.attr) static DRIVER_ATTR_RO(links); static DRIVER_ATTR_RO(components); -static DRIVER_ATTR_WO(add_link); static DRIVER_ATTR_WO(remove_link); static struct attribute *mc_attrs[] = { DRV_ATTR(links), DRV_ATTR(components), - DRV_ATTR(add_link), DRV_ATTR(remove_link), NULL, }; @@ -1431,7 +1397,7 @@ int most_register_interface(struct most_interface *iface) INIT_LIST_HEAD(&iface->p->channel_list); iface->p->dev_id = id; - snprintf(iface->p->name, STRING_SIZE, "mdev%d", id); + strscpy(iface->p->name, iface->description, sizeof(iface->p->name)); iface->dev.init_name = iface->p->name; iface->dev.bus = &mc.bus; iface->dev.parent = &mc.dev; @@ -1487,6 +1453,7 @@ int most_register_interface(struct most_interface *iface) } pr_info("registered new device mdev%d (%s)\n", id, iface->description); + most_interface_register_notify(iface->description); return 0; err_free_most_channel: @@ -1621,7 +1588,7 @@ static int __init most_init(void) err = -ENOMEM; goto err_unregister_driver; } - + configfs_init(); return 0; err_unregister_driver: |