diff options
Diffstat (limited to 'drivers/w1')
-rw-r--r-- | drivers/w1/w1.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 48da17596d43..0e6ccd46af0e 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -59,6 +59,19 @@ static pid_t control_thread; | |||
59 | static int control_needs_exit; | 59 | static int control_needs_exit; |
60 | static DECLARE_COMPLETION(w1_control_complete); | 60 | static DECLARE_COMPLETION(w1_control_complete); |
61 | 61 | ||
62 | /* stuff for the default family */ | ||
63 | static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf) | ||
64 | { | ||
65 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | ||
66 | return(sprintf(buf, "%s\n", sl->name)); | ||
67 | } | ||
68 | static struct w1_family_ops w1_default_fops = { | ||
69 | .rname = &w1_famdefault_read_name, | ||
70 | }; | ||
71 | static struct w1_family w1_default_family = { | ||
72 | .fops = &w1_default_fops, | ||
73 | }; | ||
74 | |||
62 | static int w1_master_match(struct device *dev, struct device_driver *drv) | 75 | static int w1_master_match(struct device *dev, struct device_driver *drv) |
63 | { | 76 | { |
64 | return 1; | 77 | return 1; |
@@ -360,14 +373,16 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
360 | return err; | 373 | return err; |
361 | } | 374 | } |
362 | 375 | ||
363 | err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin); | 376 | if ( sl->attr_bin.read ) { |
364 | if (err < 0) { | 377 | err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin); |
365 | dev_err(&sl->dev, | 378 | if (err < 0) { |
366 | "sysfs file creation for [%s] failed. err=%d\n", | 379 | dev_err(&sl->dev, |
367 | sl->dev.bus_id, err); | 380 | "sysfs file creation for [%s] failed. err=%d\n", |
368 | device_remove_file(&sl->dev, &sl->attr_name); | 381 | sl->dev.bus_id, err); |
369 | device_unregister(&sl->dev); | 382 | device_remove_file(&sl->dev, &sl->attr_name); |
370 | return err; | 383 | device_unregister(&sl->dev); |
384 | return err; | ||
385 | } | ||
371 | } | 386 | } |
372 | 387 | ||
373 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); | 388 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); |
@@ -403,12 +418,10 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
403 | spin_lock(&w1_flock); | 418 | spin_lock(&w1_flock); |
404 | f = w1_family_registered(rn->family); | 419 | f = w1_family_registered(rn->family); |
405 | if (!f) { | 420 | if (!f) { |
406 | spin_unlock(&w1_flock); | 421 | f= &w1_default_family; |
407 | dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n", | 422 | dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n", |
408 | rn->family, rn->family, | 423 | rn->family, rn->family, |
409 | (unsigned long long)rn->id, rn->crc); | 424 | (unsigned long long)rn->id, rn->crc); |
410 | kfree(sl); | ||
411 | return -ENODEV; | ||
412 | } | 425 | } |
413 | __w1_family_get(f); | 426 | __w1_family_get(f); |
414 | spin_unlock(&w1_flock); | 427 | spin_unlock(&w1_flock); |
@@ -449,7 +462,9 @@ static void w1_slave_detach(struct w1_slave *sl) | |||
449 | flush_signals(current); | 462 | flush_signals(current); |
450 | } | 463 | } |
451 | 464 | ||
452 | sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin); | 465 | if ( sl->attr_bin.read ) { |
466 | sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin); | ||
467 | } | ||
453 | device_remove_file(&sl->dev, &sl->attr_name); | 468 | device_remove_file(&sl->dev, &sl->attr_name); |
454 | device_unregister(&sl->dev); | 469 | device_unregister(&sl->dev); |
455 | w1_family_put(sl->family); | 470 | w1_family_put(sl->family); |