kobject和sysfs

sysfs调用kobject

home/disk1t/sprdroidp_trunk_k414_dev/kernel$ grep -nr kobject drivers/usb/
drivers/usb/core/sysfs.c:822:static umode_t dev_string_attrs_are_visible(struct kobject *kobj,
drivers/usb/core/sysfs.c:855:read_descriptors(struct file *filp, struct kobject *kobj,
drivers/usb/core/sysfs.c:1086:static umode_t intf_assoc_attrs_are_visible(struct kobject *kobj,




函数使用

/* Binary descriptors */

static ssize_t
read_descriptors(struct file *filp, struct kobject *kobj,
                struct bin_attribute *attr,
                char *buf, loff_t off, size_t count)
{
        struct device *dev = container_of(kobj, struct device, kobj);
        struct usb_device *udev = to_usb_device(dev);
        size_t nleft = count;
        size_t srclen, n;
        int cfgno;
        void *src;

        /* The binary attribute begins with the device descriptor.
         * Following that are the raw descriptor entries for all the
         * configurations (config plus subsidiary descriptors).
         */
        for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations &&
                        nleft > 0; ++cfgno) {
                if (cfgno < 0) {
                        src = &udev->descriptor;
                        srclen = sizeof(struct usb_device_descriptor);
                } else {
                        src = udev->rawdescriptors[cfgno];
                        srclen = __le16_to_cpu(udev->config[cfgno].desc.
                                        wTotalLength);
                }
                if (off < srclen) {
                        n = min(nleft, srclen - (size_t) off);
                        memcpy(buf, src + off, n);
                        nleft -= n;
                        buf += n;
                        off = 0;
                } else {
                        off -= srclen;
                }
        }
        return count - nleft;
}

device_create_bin_file调用例子:

static struct bin_attribute dev_bin_attr_descriptors = {
        .attr = {.name = "descriptors", .mode = 0444},
        .read = read_descriptors,
        .size = 18 + 65535,     /* dev descr + max-size raw descriptor */
};


int usb_create_sysfs_dev_files(struct usb_device *udev)
{
        struct device *dev = &udev->dev;
        int retval;

        retval = device_create_bin_file(dev, &dev_bin_attr_descriptors);
        if (retval)
                goto error;

        retval = add_persist_attributes(dev);
        if (retval)
                goto error;

        retval = add_power_attributes(dev);
        if (retval)
                goto error;
        return retval;
error:
        usb_remove_sysfs_dev_files(udev);
        return retval;
}


/**
 * device_create_bin_file - create sysfs binary attribute file for device.
 * @dev: device.
 * @attr: device binary attribute descriptor.
 */
int device_create_bin_file(struct device *dev,
                           const struct bin_attribute *attr)
{
        int error = -EINVAL;
        if (dev)
                error = sysfs_create_bin_file(&dev->kobj, attr);
        return error;
}
EXPORT_SYMBOL_GPL(device_create_bin_file);

/**
 *      sysfs_create_bin_file - create binary file for object.
 *      @kobj:  object.
 *      @attr:  attribute descriptor.
 */
int sysfs_create_bin_file(struct kobject *kobj,
                          const struct bin_attribute *attr)
{
        BUG_ON(!kobj || !kobj->sd || !attr);

        return sysfs_add_file(kobj->sd, &attr->attr, true);
}
EXPORT_SYMBOL_GPL(sysfs_create_bin_file);


int sysfs_add_file(struct kernfs_node *parent, const struct attribute *attr,
                   bool is_bin)
{
        return sysfs_add_file_mode_ns(parent, attr, is_bin, attr->mode, NULL);
}


int sysfs_add_file_mode_ns(struct kernfs_node *parent,
                           const struct attribute *attr, bool is_bin,
                           umode_t mode, const void *ns)
{
        struct lock_class_key *key = NULL;
        const struct kernfs_ops *ops;
        struct kernfs_node *kn;
        loff_t size;

        if (!is_bin) {
                struct kobject *kobj = parent->priv;
                const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;

                /* every kobject with an attribute needs a ktype assigned */
                if (WARN(!sysfs_ops, KERN_ERR
                         "missing sysfs attribute operations for kobject: %s\n",
                         kobject_name(kobj)))
                        return -EINVAL;

                if (sysfs_ops->show && sysfs_ops->store) {
                        if (mode & SYSFS_PREALLOC)
                                ops = &sysfs_prealloc_kfops_rw;
                        else
                                ops = &sysfs_file_kfops_rw;
                } else if (sysfs_ops->show) {
                        if (mode & SYSFS_PREALLOC)
                                ops = &sysfs_prealloc_kfops_ro;
                        else
                                ops = &sysfs_file_kfops_ro;
                } else if (sysfs_ops->store) {
                        if (mode & SYSFS_PREALLOC)
                                ops = &sysfs_prealloc_kfops_wo;
                        else
                                ops = &sysfs_file_kfops_wo;
                } else
                        ops = &sysfs_file_kfops_empty;

                size = PAGE_SIZE;
        } else {
                struct bin_attribute *battr = (void *)attr;

                if (battr->mmap)
                        ops = &sysfs_bin_kfops_mmap;
                else if (battr->read && battr->write)
                        ops = &sysfs_bin_kfops_rw;
                else if (battr->read)
                        ops = &sysfs_bin_kfops_ro;
                else if (battr->write)
                        ops = &sysfs_bin_kfops_wo;
                else
                        ops = &sysfs_file_kfops_empty;

                size = battr->size;
        }

#ifdef CONFIG_DEBUG_LOCK_ALLOC
        if (!attr->ignore_lockdep)
                key = attr->key ?: (struct lock_class_key *)&attr->skey;
#endif
        kn = __kernfs_create_file(parent, attr->name, mode & 0777, size, ops,
                                  (void *)attr, ns, key);
        if (IS_ERR(kn)) {
                if (PTR_ERR(kn) == -EEXIST)
                        sysfs_warn_dup(parent, attr->name);
                return PTR_ERR(kn);
        }
        return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值