* [PATCH] PNP: handle sysfs errors @ 2006-10-11 21:51 Jeff Garzik 2006-10-11 22:45 ` Andrew Morton 0 siblings, 1 reply; 3+ messages in thread From: Jeff Garzik @ 2006-10-11 21:51 UTC (permalink / raw) To: ambx1, Andrew Morton, LKML Signed-off-by: Jeff Garzik <jeff@garzik.org> --- drivers/pnp/card.c | 30 +++++++++++++++++++++--------- drivers/pnp/interface.c | 17 ++++++++++++++--- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index 227600c..91c047a 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -164,9 +164,17 @@ static DEVICE_ATTR(card_id,S_IRUGO,pnp_s static int pnp_interface_attach_card(struct pnp_card *card) { - device_create_file(&card->dev,&dev_attr_name); - device_create_file(&card->dev,&dev_attr_card_id); + int rc = device_create_file(&card->dev,&dev_attr_name); + if (rc) return rc; + + rc = device_create_file(&card->dev,&dev_attr_card_id); + if (rc) goto err_name; + return 0; + +err_name: + device_remove_file(&card->dev,&dev_attr_name); + return rc; } /** @@ -306,16 +314,20 @@ found: down_write(&dev->dev.bus->subsys.rwsem); dev->card_link = clink; dev->dev.driver = &drv->link.driver; - if (pnp_bus_type.probe(&dev->dev)) { - dev->dev.driver = NULL; - dev->card_link = NULL; - up_write(&dev->dev.bus->subsys.rwsem); - return NULL; - } - device_bind_driver(&dev->dev); + if (pnp_bus_type.probe(&dev->dev)) + goto err_out; + if (device_bind_driver(&dev->dev)) + goto err_out; + up_write(&dev->dev.bus->subsys.rwsem); return dev; + +err_out: + dev->dev.driver = NULL; + dev->card_link = NULL; + up_write(&dev->dev.bus->subsys.rwsem); + return NULL; } /** diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 9d8b415..ac9fcd4 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -461,8 +461,19 @@ static DEVICE_ATTR(id,S_IRUGO,pnp_show_c int pnp_interface_attach_device(struct pnp_dev *dev) { - device_create_file(&dev->dev,&dev_attr_options); - device_create_file(&dev->dev,&dev_attr_resources); - device_create_file(&dev->dev,&dev_attr_id); + int rc = device_create_file(&dev->dev,&dev_attr_options); + if (rc) goto err; + rc = device_create_file(&dev->dev,&dev_attr_resources); + if (rc) goto err_opt; + rc = device_create_file(&dev->dev,&dev_attr_id); + if (rc) goto err_res; + return 0; + +err_res: + device_remove_file(&dev->dev,&dev_attr_resources); +err_opt: + device_remove_file(&dev->dev,&dev_attr_options); +err: + return rc; } ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] PNP: handle sysfs errors 2006-10-11 21:51 [PATCH] PNP: handle sysfs errors Jeff Garzik @ 2006-10-11 22:45 ` Andrew Morton 2006-10-12 3:54 ` Dmitry Torokhov 0 siblings, 1 reply; 3+ messages in thread From: Andrew Morton @ 2006-10-11 22:45 UTC (permalink / raw) To: Jeff Garzik; +Cc: ambx1, LKML On Wed, 11 Oct 2006 17:51:09 -0400 Jeff Garzik <jeff@garzik.org> wrote: > + int rc = device_create_file(&dev->dev,&dev_attr_options); > + if (rc) goto err; > + rc = device_create_file(&dev->dev,&dev_attr_resources); > + if (rc) goto err_opt; > + rc = device_create_file(&dev->dev,&dev_attr_id); > + if (rc) goto err_res; > + > return 0; > + > +err_res: > + device_remove_file(&dev->dev,&dev_attr_resources); > +err_opt: > + device_remove_file(&dev->dev,&dev_attr_options); > +err: > + return rc; That's a common pattern, isn't it? I wonder if we could create some sort of automatic-unwinding engine: int pnp_interface_attach_device(struct pnp_dev *dev) { struct unwind_engine *u = NULL; int err; u = UNWINDABLE(u, err, device_create_file(&dev->dev,&dev_attr_options), device_remove_file, &dev->dev, &dev_attr_options); u = UNWINDABLE(u, err, device_create_file(&dev->dev,&dev_attr_id) device_remove_file, &dev->dev, &dev_attr_options); u = UNWINDABLE(u, err, device_create_file(&dev->dev,&dev_attr_id), device_remove_file, &dev->dev, &dev_attr_id); err = unwind(err, u); return err; } and, umm, #define UNWINDABLE(u, err, expr, undo_fn, arg1, arg2) if (err == 0) { err = (expr); if (err == 0) u = add_unwind(u, undo_fn, arg1, arg2); } u; int unwind(int err, struct unwind_engine *u) { if (err == 0) return 0; for (all entries in u in opposite order) { u->fn(u->arg0, u>arg1); kfree(u); } return err; } I dunno - probably too crappy to live, but it'd encourage/help people to dtrt. ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] PNP: handle sysfs errors 2006-10-11 22:45 ` Andrew Morton @ 2006-10-12 3:54 ` Dmitry Torokhov 0 siblings, 0 replies; 3+ messages in thread From: Dmitry Torokhov @ 2006-10-12 3:54 UTC (permalink / raw) To: Andrew Morton; +Cc: Jeff Garzik, ambx1, LKML On Wednesday 11 October 2006 18:45, Andrew Morton wrote: > On Wed, 11 Oct 2006 17:51:09 -0400 > Jeff Garzik <jeff@garzik.org> wrote: > > > + int rc = device_create_file(&dev->dev,&dev_attr_options); > > + if (rc) goto err; > > + rc = device_create_file(&dev->dev,&dev_attr_resources); > > + if (rc) goto err_opt; > > + rc = device_create_file(&dev->dev,&dev_attr_id); > > + if (rc) goto err_res; > > + > > return 0; > > + > > +err_res: > > + device_remove_file(&dev->dev,&dev_attr_resources); > > +err_opt: > > + device_remove_file(&dev->dev,&dev_attr_options); > > +err: > > + return rc; > > That's a common pattern, isn't it? > > I wonder if we could create some sort of automatic-unwinding engine: > > int pnp_interface_attach_device(struct pnp_dev *dev) > { > struct unwind_engine *u = NULL; > int err; > > u = UNWINDABLE(u, err, device_create_file(&dev->dev,&dev_attr_options), > device_remove_file, &dev->dev, &dev_attr_options); > u = UNWINDABLE(u, err, device_create_file(&dev->dev,&dev_attr_id) > device_remove_file, &dev->dev, &dev_attr_options); > u = UNWINDABLE(u, err, device_create_file(&dev->dev,&dev_attr_id), > device_remove_file, &dev->dev, &dev_attr_id); > err = unwind(err, u); > return err; > } > > and, umm, > > #define UNWINDABLE(u, err, expr, undo_fn, arg1, arg2) > if (err == 0) { > err = (expr); > if (err == 0) > u = add_unwind(u, undo_fn, arg1, arg2); > } > u; > > int unwind(int err, struct unwind_engine *u) > { > if (err == 0) > return 0; > for (all entries in u in opposite order) { > u->fn(u->arg0, u>arg1); > kfree(u); > } > return err; > } > > > I dunno - probably too crappy to live, but it'd encourage/help people to > dtrt. The best solution is to switch drivers with more than 2 attributes to use arribute groups which collapses unwinding nicely. -- Dmitry ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-10-12 3:54 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-10-11 21:51 [PATCH] PNP: handle sysfs errors Jeff Garzik 2006-10-11 22:45 ` Andrew Morton 2006-10-12 3:54 ` Dmitry Torokhov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox