Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6

+178 -70
+14 -14
Documentation/filesystems/sysfs.txt
··· 90 90 91 91 It also defines this helper for defining device attributes: 92 92 93 - #define DEVICE_ATTR(_name,_mode,_show,_store) \ 93 + #define DEVICE_ATTR(_name, _mode, _show, _store) \ 94 94 struct device_attribute dev_attr_##_name = { \ 95 95 .attr = {.name = __stringify(_name) , .mode = _mode }, \ 96 96 .show = _show, \ ··· 99 99 100 100 For example, declaring 101 101 102 - static DEVICE_ATTR(foo,0644,show_foo,store_foo); 102 + static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo); 103 103 104 104 is equivalent to doing: 105 105 106 106 static struct device_attribute dev_attr_foo = { 107 107 .attr = { 108 108 .name = "foo", 109 - .mode = 0644, 109 + .mode = S_IWUSR | S_IRUGO, 110 110 }, 111 111 .show = show_foo, 112 112 .store = store_foo, ··· 121 121 show and store methods of the attribute owners. 122 122 123 123 struct sysfs_ops { 124 - ssize_t (*show)(struct kobject *, struct attribute *,char *); 125 - ssize_t (*store)(struct kobject *,struct attribute *,const char *); 124 + ssize_t (*show)(struct kobject *, struct attribute *, char *); 125 + ssize_t (*store)(struct kobject *, struct attribute *, const char *); 126 126 }; 127 127 128 128 [ Subsystems should have already defined a struct kobj_type as a ··· 137 137 138 138 To illustrate: 139 139 140 - #define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr) 140 + #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 141 141 #define to_dev(d) container_of(d, struct device, kobj) 142 142 143 143 static ssize_t ··· 148 148 ssize_t ret = 0; 149 149 150 150 if (dev_attr->show) 151 - ret = dev_attr->show(dev,buf); 151 + ret = dev_attr->show(dev, buf); 152 152 return ret; 153 153 } 154 154 ··· 216 216 217 217 static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) 218 218 { 219 - return sprintf(buf,"%s\n",dev->name); 219 + return snprintf(buf, PAGE_SIZE, "%s\n", dev->name); 220 220 } 221 221 222 222 static ssize_t store_name(struct device * dev, const char * buf) 223 223 { 224 - sscanf(buf,"%20s",dev->name); 225 - return strlen(buf); 224 + sscanf(buf, "%20s", dev->name); 225 + return strnlen(buf, PAGE_SIZE); 226 226 } 227 227 228 - static DEVICE_ATTR(name,S_IRUGO,show_name,store_name); 228 + static DEVICE_ATTR(name, S_IRUGO, show_name, store_name); 229 229 230 230 231 231 (Note that the real implementation doesn't allow userspace to set the ··· 290 290 291 291 Declaring: 292 292 293 - DEVICE_ATTR(_name,_str,_mode,_show,_store); 293 + DEVICE_ATTR(_name, _str, _mode, _show, _store); 294 294 295 295 Creation/Removal: 296 296 ··· 310 310 311 311 Declaring: 312 312 313 - BUS_ATTR(_name,_mode,_show,_store) 313 + BUS_ATTR(_name, _mode, _show, _store) 314 314 315 315 Creation/Removal: 316 316 ··· 331 331 332 332 Declaring: 333 333 334 - DRIVER_ATTR(_name,_mode,_show,_store) 334 + DRIVER_ATTR(_name, _mode, _show, _store) 335 335 336 336 Creation/Removal: 337 337
+5 -3
drivers/base/bus.c
··· 156 156 device_release_driver(dev); 157 157 err = count; 158 158 } 159 - return err; 159 + if (err) 160 + return err; 161 + return count; 160 162 } 161 163 static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 162 164 ··· 360 358 if (bus) { 361 359 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); 362 360 device_attach(dev); 363 - klist_add_tail(&bus->klist_devices, &dev->knode_bus); 361 + klist_add_tail(&dev->knode_bus, &bus->klist_devices); 364 362 error = device_add_attrs(bus, dev); 365 363 if (!error) { 366 364 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); ··· 448 446 } 449 447 450 448 driver_attach(drv); 451 - klist_add_tail(&bus->klist_drivers, &drv->knode_bus); 449 + klist_add_tail(&drv->knode_bus, &bus->klist_drivers); 452 450 module_add_driver(drv->owner, drv); 453 451 454 452 driver_add_attrs(bus, drv);
+33 -6
drivers/base/class.c
··· 299 299 300 300 pr_debug("device class '%s': release.\n", cd->class_id); 301 301 302 - if (cd->devt_attr) { 303 - kfree(cd->devt_attr); 304 - cd->devt_attr = NULL; 305 - } 302 + kfree(cd->devt_attr); 303 + cd->devt_attr = NULL; 306 304 307 305 if (cls->release) 308 306 cls->release(cd); ··· 450 452 INIT_LIST_HEAD(&class_dev->node); 451 453 } 452 454 455 + static char *make_class_name(struct class_device *class_dev) 456 + { 457 + char *name; 458 + int size; 459 + 460 + size = strlen(class_dev->class->name) + 461 + strlen(kobject_name(&class_dev->kobj)) + 2; 462 + 463 + name = kmalloc(size, GFP_KERNEL); 464 + if (!name) 465 + return ERR_PTR(-ENOMEM); 466 + 467 + strcpy(name, class_dev->class->name); 468 + strcat(name, ":"); 469 + strcat(name, kobject_name(&class_dev->kobj)); 470 + return name; 471 + } 472 + 453 473 int class_device_add(struct class_device *class_dev) 454 474 { 455 475 struct class * parent = NULL; 456 476 struct class_interface * class_intf; 477 + char *class_name = NULL; 457 478 int error; 458 479 459 480 class_dev = class_device_get(class_dev); ··· 517 500 } 518 501 519 502 class_device_add_attrs(class_dev); 520 - if (class_dev->dev) 503 + if (class_dev->dev) { 504 + class_name = make_class_name(class_dev); 521 505 sysfs_create_link(&class_dev->kobj, 522 506 &class_dev->dev->kobj, "device"); 507 + sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 508 + class_name); 509 + } 523 510 524 511 /* notify any interfaces this device is now here */ 525 512 if (parent) { ··· 540 519 if (error && parent) 541 520 class_put(parent); 542 521 class_device_put(class_dev); 522 + kfree(class_name); 543 523 return error; 544 524 } 545 525 ··· 606 584 { 607 585 struct class * parent = class_dev->class; 608 586 struct class_interface * class_intf; 587 + char *class_name = NULL; 609 588 610 589 if (parent) { 611 590 down(&parent->sem); ··· 617 594 up(&parent->sem); 618 595 } 619 596 620 - if (class_dev->dev) 597 + if (class_dev->dev) { 598 + class_name = make_class_name(class_dev); 621 599 sysfs_remove_link(&class_dev->kobj, "device"); 600 + sysfs_remove_link(&class_dev->dev->kobj, class_name); 601 + } 622 602 if (class_dev->devt_attr) 623 603 class_device_remove_file(class_dev, class_dev->devt_attr); 624 604 class_device_remove_attrs(class_dev); ··· 631 605 632 606 if (parent) 633 607 class_put(parent); 608 + kfree(class_name); 634 609 } 635 610 636 611 void class_device_unregister(struct class_device *class_dev)
+1 -1
drivers/base/core.c
··· 249 249 if ((error = bus_add_device(dev))) 250 250 goto BusError; 251 251 if (parent) 252 - klist_add_tail(&parent->klist_children, &dev->knode_parent); 252 + klist_add_tail(&dev->knode_parent, &parent->klist_children); 253 253 254 254 /* notify platform of device entry */ 255 255 if (platform_notify)
+1 -1
drivers/base/dd.c
··· 42 42 { 43 43 pr_debug("bound device '%s' to driver '%s'\n", 44 44 dev->bus_id, dev->driver->name); 45 - klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver); 45 + klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); 46 46 sysfs_create_link(&dev->driver->kobj, &dev->kobj, 47 47 kobject_name(&dev->kobj)); 48 48 sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+85 -25
drivers/base/sys.c
··· 288 288 up(&sysdev_drivers_lock); 289 289 } 290 290 291 + static void __sysdev_resume(struct sys_device *dev) 292 + { 293 + struct sysdev_class *cls = dev->cls; 294 + struct sysdev_driver *drv; 295 + 296 + /* First, call the class-specific one */ 297 + if (cls->resume) 298 + cls->resume(dev); 299 + 300 + /* Call auxillary drivers next. */ 301 + list_for_each_entry(drv, &cls->drivers, entry) { 302 + if (drv->resume) 303 + drv->resume(dev); 304 + } 305 + 306 + /* Call global drivers. */ 307 + list_for_each_entry(drv, &sysdev_drivers, entry) { 308 + if (drv->resume) 309 + drv->resume(dev); 310 + } 311 + } 291 312 292 313 /** 293 314 * sysdev_suspend - Suspend all system devices. ··· 326 305 int sysdev_suspend(pm_message_t state) 327 306 { 328 307 struct sysdev_class * cls; 308 + struct sys_device *sysdev, *err_dev; 309 + struct sysdev_driver *drv, *err_drv; 310 + int ret; 329 311 330 312 pr_debug("Suspending System Devices\n"); 331 313 332 314 list_for_each_entry_reverse(cls, &system_subsys.kset.list, 333 315 kset.kobj.entry) { 334 - struct sys_device * sysdev; 335 316 336 317 pr_debug("Suspending type '%s':\n", 337 318 kobject_name(&cls->kset.kobj)); 338 319 339 320 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { 340 - struct sysdev_driver * drv; 341 321 pr_debug(" %s\n", kobject_name(&sysdev->kobj)); 342 322 343 323 /* Call global drivers first. */ 344 324 list_for_each_entry(drv, &sysdev_drivers, entry) { 345 - if (drv->suspend) 346 - drv->suspend(sysdev, state); 325 + if (drv->suspend) { 326 + ret = drv->suspend(sysdev, state); 327 + if (ret) 328 + goto gbl_driver; 329 + } 347 330 } 348 331 349 332 /* Call auxillary drivers next. */ 350 333 list_for_each_entry(drv, &cls->drivers, entry) { 351 - if (drv->suspend) 352 - drv->suspend(sysdev, state); 334 + if (drv->suspend) { 335 + ret = drv->suspend(sysdev, state); 336 + if (ret) 337 + goto aux_driver; 338 + } 353 339 } 354 340 355 341 /* Now call the generic one */ 356 - if (cls->suspend) 357 - cls->suspend(sysdev, state); 342 + if (cls->suspend) { 343 + ret = cls->suspend(sysdev, state); 344 + if (ret) 345 + goto cls_driver; 346 + } 358 347 } 359 348 } 360 349 return 0; 350 + /* resume current sysdev */ 351 + cls_driver: 352 + drv = NULL; 353 + printk(KERN_ERR "Class suspend failed for %s\n", 354 + kobject_name(&sysdev->kobj)); 355 + 356 + aux_driver: 357 + if (drv) 358 + printk(KERN_ERR "Class driver suspend failed for %s\n", 359 + kobject_name(&sysdev->kobj)); 360 + list_for_each_entry(err_drv, &cls->drivers, entry) { 361 + if (err_drv == drv) 362 + break; 363 + if (err_drv->resume) 364 + err_drv->resume(sysdev); 365 + } 366 + drv = NULL; 367 + 368 + gbl_driver: 369 + if (drv) 370 + printk(KERN_ERR "sysdev driver suspend failed for %s\n", 371 + kobject_name(&sysdev->kobj)); 372 + list_for_each_entry(err_drv, &sysdev_drivers, entry) { 373 + if (err_drv == drv) 374 + break; 375 + if (err_drv->resume) 376 + err_drv->resume(sysdev); 377 + } 378 + /* resume other sysdevs in current class */ 379 + list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { 380 + if (err_dev == sysdev) 381 + break; 382 + pr_debug(" %s\n", kobject_name(&err_dev->kobj)); 383 + __sysdev_resume(err_dev); 384 + } 385 + 386 + /* resume other classes */ 387 + list_for_each_entry_continue(cls, &system_subsys.kset.list, 388 + kset.kobj.entry) { 389 + list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { 390 + pr_debug(" %s\n", kobject_name(&err_dev->kobj)); 391 + __sysdev_resume(err_dev); 392 + } 393 + } 394 + return ret; 361 395 } 362 396 363 397 ··· 438 362 kobject_name(&cls->kset.kobj)); 439 363 440 364 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { 441 - struct sysdev_driver * drv; 442 365 pr_debug(" %s\n", kobject_name(&sysdev->kobj)); 443 366 444 - /* First, call the class-specific one */ 445 - if (cls->resume) 446 - cls->resume(sysdev); 447 - 448 - /* Call auxillary drivers next. */ 449 - list_for_each_entry(drv, &cls->drivers, entry) { 450 - if (drv->resume) 451 - drv->resume(sysdev); 452 - } 453 - 454 - /* Call global drivers. */ 455 - list_for_each_entry(drv, &sysdev_drivers, entry) { 456 - if (drv->resume) 457 - drv->resume(sysdev); 458 - } 459 - 367 + __sysdev_resume(sysdev); 460 368 } 461 369 } 462 370 return 0;
+28 -13
drivers/block/floppy.c
··· 493 493 494 494 static sector_t floppy_sizes[256]; 495 495 496 + static char floppy_device_name[] = "floppy"; 497 + 496 498 /* 497 499 * The driver is trying to determine the correct media format 498 500 * while probing is set. rw_interrupt() clears it after a ··· 4193 4191 4194 4192 static int have_no_fdc = -ENODEV; 4195 4193 4194 + static ssize_t floppy_cmos_show(struct device *dev, 4195 + struct device_attribute *attr, char *buf) 4196 + { 4197 + struct platform_device *p; 4198 + int drive; 4199 + 4200 + p = container_of(dev, struct platform_device,dev); 4201 + drive = p->id; 4202 + return sprintf(buf, "%X\n", UDP->cmos); 4203 + } 4204 + DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL); 4205 + 4196 4206 static void floppy_device_release(struct device *dev) 4197 4207 { 4198 4208 complete(&device_release); 4199 4209 } 4200 4210 4201 - static struct platform_device floppy_device = { 4202 - .name = "floppy", 4203 - .id = 0, 4204 - .dev = { 4205 - .release = floppy_device_release, 4206 - } 4207 - }; 4211 + static struct platform_device floppy_device[N_DRIVE]; 4208 4212 4209 4213 static struct kobject *floppy_find(dev_t dev, int *part, void *data) 4210 4214 { ··· 4378 4370 goto out_flush_work; 4379 4371 } 4380 4372 4381 - err = platform_device_register(&floppy_device); 4382 - if (err) 4383 - goto out_flush_work; 4384 - 4385 4373 for (drive = 0; drive < N_DRIVE; drive++) { 4386 4374 if (!(allowed_drive_mask & (1 << drive))) 4387 4375 continue; 4388 4376 if (fdc_state[FDC(drive)].version == FDC_NONE) 4389 4377 continue; 4378 + 4379 + floppy_device[drive].name = floppy_device_name; 4380 + floppy_device[drive].id = drive; 4381 + floppy_device[drive].dev.release = floppy_device_release; 4382 + 4383 + err = platform_device_register(&floppy_device[drive]); 4384 + if (err) 4385 + goto out_flush_work; 4386 + 4387 + device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); 4390 4388 /* to be cleaned up... */ 4391 4389 disks[drive]->private_data = (void *)(long)drive; 4392 4390 disks[drive]->queue = floppy_queue; 4393 4391 disks[drive]->flags |= GENHD_FL_REMOVABLE; 4394 - disks[drive]->driverfs_dev = &floppy_device.dev; 4392 + disks[drive]->driverfs_dev = &floppy_device[drive].dev; 4395 4393 add_disk(disks[drive]); 4396 4394 } 4397 4395 ··· 4617 4603 fdc_state[FDC(drive)].version != FDC_NONE) { 4618 4604 del_gendisk(disks[drive]); 4619 4605 unregister_devfs_entries(drive); 4606 + device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); 4607 + platform_device_unregister(&floppy_device[drive]); 4620 4608 } 4621 4609 put_disk(disks[drive]); 4622 4610 } 4623 - platform_device_unregister(&floppy_device); 4624 4611 devfs_remove("floppy"); 4625 4612 4626 4613 del_timer_sync(&fd_timeout);
+1 -1
drivers/usb/core/hcd.c
··· 782 782 return -E2BIG; 783 783 } 784 784 785 - bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum); 785 + bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb_host%d", busnum); 786 786 if (IS_ERR(bus->class_dev)) { 787 787 clear_bit(busnum, busmap.busmap); 788 788 up(&usb_bus_list_lock);
+6 -2
include/linux/klist.h
··· 9 9 * This file is rleased under the GPL v2. 10 10 */ 11 11 12 + #ifndef _LINUX_KLIST_H 13 + #define _LINUX_KLIST_H 14 + 12 15 #include <linux/spinlock.h> 13 16 #include <linux/completion.h> 14 17 #include <linux/kref.h> ··· 34 31 struct completion n_removed; 35 32 }; 36 33 37 - extern void klist_add_tail(struct klist * k, struct klist_node * n); 38 - extern void klist_add_head(struct klist * k, struct klist_node * n); 34 + extern void klist_add_tail(struct klist_node * n, struct klist * k); 35 + extern void klist_add_head(struct klist_node * n, struct klist * k); 39 36 40 37 extern void klist_del(struct klist_node * n); 41 38 extern void klist_remove(struct klist_node * n); ··· 56 53 extern void klist_iter_exit(struct klist_iter * i); 57 54 extern struct klist_node * klist_next(struct klist_iter * i); 58 55 56 + #endif
+4 -4
lib/klist.c
··· 79 79 80 80 /** 81 81 * klist_add_head - Initialize a klist_node and add it to front. 82 - * @k: klist it's going on. 83 82 * @n: node we're adding. 83 + * @k: klist it's going on. 84 84 */ 85 85 86 - void klist_add_head(struct klist * k, struct klist_node * n) 86 + void klist_add_head(struct klist_node * n, struct klist * k) 87 87 { 88 88 klist_node_init(k, n); 89 89 add_head(k, n); ··· 94 94 95 95 /** 96 96 * klist_add_tail - Initialize a klist_node and add it to back. 97 - * @k: klist it's going on. 98 97 * @n: node we're adding. 98 + * @k: klist it's going on. 99 99 */ 100 100 101 - void klist_add_tail(struct klist * k, struct klist_node * n) 101 + void klist_add_tail(struct klist_node * n, struct klist * k) 102 102 { 103 103 klist_node_init(k, n); 104 104 add_tail(k, n);