On Wed, Jan 18, 2023 at 08:35:51PM -0500, Tianfei Zhang wrote: > To reprogram an PCIe-based FPGA card, a new image is > burned into FLASH on the card and then the card BMC is > triggered to reboot the card and load the new image. > > Two new operation callbacks are defined in hotplug_slot_ops > to trigger the reprogramming of an FPGA-based PCIe card: > > - available_images: Optional: available FPGA images > - image_load: Optional: trigger the FPGA to load a new image > > Signed-off-by: Tianfei Zhang <tianfei.zhang@xxxxxxxxx> > Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx> > --- > drivers/pci/hotplug/pci_hotplug_core.c | 88 ++++++++++++++++++++++++++ > include/linux/pci_hotplug.h | 5 ++ > 2 files changed, 93 insertions(+) > > diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c > index 058d5937d8a9..2b14b6513a03 100644 > --- a/drivers/pci/hotplug/pci_hotplug_core.c > +++ b/drivers/pci/hotplug/pci_hotplug_core.c > @@ -231,6 +231,52 @@ static struct pci_slot_attribute hotplug_slot_attr_test = { > .store = test_write_file > }; > > +static ssize_t available_images_read_file(struct pci_slot *pci_slot, char *buf) > +{ > + struct hotplug_slot *slot = pci_slot->hotplug; > + ssize_t count = 0; > + > + if (!try_module_get(slot->owner)) > + return -ENODEV; > + > + if (slot->ops->available_images(slot, buf)) > + count = slot->ops->available_images(slot, buf); > + > + module_put(slot->owner); > + > + return count; > +} > + > +static struct pci_slot_attribute hotplug_slot_attr_available_images = { > + .attr = { .name = "available_images", .mode = 0444 }, > + .show = available_images_read_file, If you name things properly, you can use the correct macros and not have to open-code any of this :( > +static ssize_t image_load_write_file(struct pci_slot *pci_slot, > + const char *buf, size_t count) > +{ > + struct hotplug_slot *slot = pci_slot->hotplug; > + int retval = 0; > + > + if (!try_module_get(slot->owner)) > + return -ENODEV; > + > + if (slot->ops->image_load) > + retval = slot->ops->image_load(slot, buf); > + > + module_put(slot->owner); > + > + if (retval) > + return retval; > + > + return count; > +} > + > +static struct pci_slot_attribute hotplug_slot_attr_image_load = { > + .attr = { .name = "image_load", .mode = 0644 }, > + .store = image_load_write_file, Same here, don't open-code this. > +}; > + > static bool has_power_file(struct pci_slot *pci_slot) > { > struct hotplug_slot *slot = pci_slot->hotplug; > @@ -289,6 +335,20 @@ static bool has_test_file(struct pci_slot *pci_slot) > return false; > } > > +static bool has_available_images_file(struct pci_slot *pci_slot) > +{ > + struct hotplug_slot *slot = pci_slot->hotplug; > + > + return slot && slot->ops && slot->ops->available_images; > +} > + > +static bool has_image_load_file(struct pci_slot *pci_slot) > +{ > + struct hotplug_slot *slot = pci_slot->hotplug; > + > + return slot && slot->ops && slot->ops->image_load; > +} > + > static int fs_add_slot(struct pci_slot *pci_slot) > { > int retval = 0; > @@ -331,8 +391,30 @@ static int fs_add_slot(struct pci_slot *pci_slot) > goto exit_test; > } > > + if (has_available_images_file(pci_slot)) { > + retval = sysfs_create_file(&pci_slot->kobj, > + &hotplug_slot_attr_available_images.attr); > + if (retval) > + goto exit_available_images; > + } > + > + if (has_image_load_file(pci_slot)) { > + retval = sysfs_create_file(&pci_slot->kobj, > + &hotplug_slot_attr_image_load.attr); > + if (retval) > + goto exit_image_load; > + } > + > goto exit; > > +exit_image_load: > + if (has_adapter_file(pci_slot)) > + sysfs_remove_file(&pci_slot->kobj, > + &hotplug_slot_attr_available_images.attr); > +exit_available_images: > + if (has_adapter_file(pci_slot)) > + sysfs_remove_file(&pci_slot->kobj, > + &hotplug_slot_attr_test.attr); > exit_test: > if (has_adapter_file(pci_slot)) > sysfs_remove_file(&pci_slot->kobj, > @@ -372,6 +454,12 @@ static void fs_remove_slot(struct pci_slot *pci_slot) > if (has_test_file(pci_slot)) > sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_test.attr); > > + if (has_available_images_file(pci_slot)) > + sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_available_images.attr); > + > + if (has_image_load_file(pci_slot)) > + sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_image_load.attr); > + Ick no, please just make this an attribute group that properly shows or does not show, the attribute when created. Do not manually add individual sysfs files. Yes, I know the existing code does this, so it's not really your fault, but let's not persist in making this code even messier. Convert to a group first and then your new files will be added automagically without having to care about anything here at all. thanks, greg k-h