Hi Amey and Shanker, [...] > +static ssize_t reset_method_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct pci_dev *pdev = to_pci_dev(dev); > + ssize_t len = 0; > + int i, prio; > + > + for (prio = PCI_RESET_METHODS_NUM; prio; prio--) { > + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) { > + if (prio == pdev->reset_methods[i]) { > + len += sysfs_emit_at(buf, len, "%s%s", > + len ? "," : "", > + pci_reset_fn_methods[i].name); > + break; > + } > + } > + > + if (i == PCI_RESET_METHODS_NUM) > + break; > + } > + > + return len; > +} Make sure to include trailing newline when exposing values through the sysfs object to the userspace in the above show() function. [...] > +static ssize_t reset_method_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) [...] > + > + while ((name = strsep((char **)&buf, ",")) != NULL) { [...] This is something that I wonder could benefit from the following: char *options, *end; if (count >= (PAGE_SIZE - 1)) return -EINVAL; options = kstrndup(buf, count, GFP_KERNEL); if (!options) return -ENOMEM; while ((name = strsep(&options, ",")) != NULL) { ... } ... kfree(options); Why? To avoid changing the string buffer that has been passed to reset_method_store() as strsep() while parsing will update the content of the buffer. The cast to (char **), aside of most definitely allowing to suppress the probable compiler warning, will also allow for what should be a technically a constant string (to which we got a pointer to) to be modified. I am not sure how much could this be of a problem, but I would try not to do it, if possible. [...] > +set_reset_methods: > + memcpy(pdev->reset_methods, reset_methods, sizeof(reset_methods)); > + return count; > +} > + > +static DEVICE_ATTR_RW(reset_method); A small nitpikc: customary there is no space (a newline) between the function and the macro, the macro follows immediately after. Krzysztof