Commit 0fcdd5d3 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

driver core: removed drivers/base/fs/*, drivers/base/intf.c and drivers/base/hotplug.c

These files are no longer needed due to class changes.
parent d9dfbbac
/*
* drivers/base/fs.c - driver model interface to driverfs
*
* Copyright (c) 2002 Patrick Mochel
* 2002 Open Source Development Lab
*/
#undef DEBUG
#include <linux/device.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/stat.h>
#include <linux/limits.h>
int get_devpath_length(struct device * dev)
{
int length = 1;
struct device * parent = dev;
/* walk up the ancestors until we hit the root.
* Add 1 to strlen for leading '/' of each level.
*/
do {
length += strlen(parent->bus_id) + 1;
parent = parent->parent;
} while (parent);
return length;
}
void fill_devpath(struct device * dev, char * path, int length)
{
struct device * parent;
--length;
for (parent = dev; parent; parent = parent->parent) {
int cur = strlen(parent->bus_id);
/* back up enough to print this bus id with '/' */
length -= cur;
strncpy(path + length,parent->bus_id,cur);
*(path + --length) = '/';
}
pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
}
int get_devpath_length(struct device * dev);
void fill_devpath(struct device * dev, char * path, int length);
/*
* drivers/base/hotplug.c - hotplug call code
*
* Copyright (c) 2000-2001 David Brownell
* Copyright (c) 2002-2003 Greg Kroah-Hartman
* Copyright (c) 2002-2003 IBM Corp.
*
* Based off of drivers/usb/core/usb.c:call_agent(), which was
* written by David Brownell.
*
*/
#undef DEBUG
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include "base.h"
#include "fs/fs.h"
/*
* hotplugging invokes what /proc/sys/kernel/hotplug says (normally
* /sbin/hotplug) when devices or classes get added or removed.
*
* This invokes a user mode policy agent, typically helping to load driver
* or other modules, configure the device, and more. Drivers can provide
* a MODULE_DEVICE_TABLE to help with module loading subtasks.
*
* See the documentation at http://linux-hotplug.sf.net for more info.
*
*/
#define BUFFER_SIZE 1024 /* should be enough memory for the env */
#define NUM_ENVP 32 /* number of env pointers */
static char prefix [] = "devices"; /* /sys/devices/... */
static int do_hotplug (struct device *dev, char *argv1, const char *action,
int (* hotplug) (struct device *, char **, int, char *, int))
{
char *argv [3], **envp, *buffer, *scratch;
char *dev_path;
int retval;
int i = 0;
int dev_length;
pr_debug ("%s\n", __FUNCTION__);
if (!hotplug_path [0])
return -ENODEV;
envp = (char **) kmalloc (NUM_ENVP * sizeof (char *), GFP_KERNEL);
if (!envp)
return -ENOMEM;
memset (envp, 0x00, NUM_ENVP * sizeof (char *));
buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
if (!buffer) {
kfree (envp);
return -ENOMEM;
}
dev_length = get_devpath_length (dev);
dev_length += strlen(prefix);
dev_path = kmalloc (dev_length, GFP_KERNEL);
if (!dev_path) {
kfree (buffer);
kfree (envp);
return -ENOMEM;
}
memset (dev_path, 0x00, dev_length);
strcpy (dev_path, prefix);
fill_devpath (dev, dev_path, dev_length);
argv [0] = hotplug_path;
argv [1] = argv1;
argv [2] = 0;
/* minimal command environment */
envp [i++] = "HOME=/";
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
scratch = buffer;
envp [i++] = scratch;
scratch += sprintf (scratch, "ACTION=%s", action) + 1;
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", dev_path) + 1;
if (hotplug) {
/* have the bus specific function add its stuff */
retval = hotplug (dev, &envp[i], NUM_ENVP - i, scratch,
BUFFER_SIZE - (scratch - buffer));
if (retval) {
pr_debug ("%s - hotplug() returned %d\n",
__FUNCTION__, retval);
goto exit;
}
}
pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv [0], argv[1],
envp[0], envp[1], envp[2], envp[3]);
retval = call_usermodehelper (argv [0], argv, envp, 0);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
__FUNCTION__, retval);
exit:
kfree (dev_path);
kfree (buffer);
kfree (envp);
return retval;
}
/*
* class_hotplug - called when a class is added or removed from a device
*/
int class_hotplug (struct device *dev, const char *action)
{
struct device_class * cls;
int retval;
pr_debug ("%s\n", __FUNCTION__);
if (!dev)
return -ENODEV;
if (!dev->bus)
return -ENODEV;
cls = get_devclass(dev->driver->devclass);
if (!cls)
return -ENODEV;
retval = do_hotplug (dev, cls->name, action, cls->hotplug);
put_devclass(cls);
return retval;
}
/*
* intf.c - class-specific interface management
*/
#undef DEBUG
#include <linux/device.h>
#include <linux/module.h>
#include <linux/string.h>
#include "base.h"
#define to_intf(node) container_of(node,struct device_interface,kset.kobj.entry)
#define to_dev(d) container_of(d,struct device,class_list)
/**
* intf_dev_link - create sysfs symlink for interface.
* @intf: interface.
* @dev: device.
*
* Create a symlink 'phys' in the interface's directory to
*/
static int intf_dev_link(struct device_interface * intf, struct device * dev)
{
return sysfs_create_link(&intf->kset.kobj,&dev->kobj,dev->bus_id);
}
/**
* intf_dev_unlink - remove symlink for interface.
* @intf: interface.
* @dev: device.
*
*/
static void intf_dev_unlink(struct device_interface * intf, struct device * dev)
{
sysfs_remove_link(&intf->kset.kobj,dev->bus_id);
}
/**
* add - attach device to interface
* @intf: interface.
* @dev: device.
*
* This is just a simple helper. Check the interface's interface
* helper and call it. This is called when adding an interface
* the class's devices, or a device to the class's interfaces.
*/
static int add(struct device_interface * intf, struct device * dev)
{
int error = 0;
if (intf->add_device) {
if (!(error = intf->add_device(dev)))
intf_dev_link(intf,dev);
}
pr_debug(" -> %s (%d)\n",dev->bus_id,error);
return error;
}
/**
* del - detach device from interface.
* @intf: interface.
* @dev: device.
*/
static void del(struct device_interface * intf, struct device * dev)
{
pr_debug(" -> %s ",intf->name);
if (intf->remove_device)
intf->remove_device(dev);
intf_dev_unlink(intf,dev);
}
/**
* add_intf - add class's devices to interface.
* @intf: interface.
*
* Loop over the devices registered with the class, and call
* the interface's add_device() method for each.
*
* On an error, we won't break, but we will print debugging info.
*/
static void add_intf(struct device_interface * intf)
{
struct device_class * cls = intf->devclass;
struct list_head * entry;
list_for_each(entry,&cls->devices.list)
add(intf,to_dev(entry));
}
/**
* interface_register - register an interface with a device class.
* @intf: interface.
*
* An interface may be loaded after drivers and devices have been
* added to the class. So, we must add each device already known to
* the class to the interface as its registered.
*/
int interface_register(struct device_interface * intf)
{
struct device_class * cls = get_devclass(intf->devclass);
down(&devclass_sem);
if (cls) {
pr_debug("register interface '%s' with class '%s'\n",
intf->name,cls->name);
strncpy(intf->kset.kobj.name,intf->name,KOBJ_NAME_LEN);
kset_set_kset_s(intf,cls->subsys);
kset_register(&intf->kset);
add_intf(intf);
}
up(&devclass_sem);
return 0;
}
/**
* del_intf - remove devices from interface.
* @intf: interface being unloaded.
*
* This loops over the devices registered with a class and
* calls the interface's remove_device() method for each.
* This is called when an interface is being unregistered.
*/
static void del_intf(struct device_interface * intf)
{
struct device_class * cls = intf->devclass;
struct list_head * entry;
list_for_each(entry,&cls->devices.list) {
struct device * dev = to_dev(entry);
del(intf,dev);
}
}
/**
* interface_unregister - remove interface from class.
* @intf: interface.
*
* This is called when an interface in unloaded, giving it a
* chance to remove itself from devicse that have been added to
* it.
*/
void interface_unregister(struct device_interface * intf)
{
struct device_class * cls = intf->devclass;
down(&devclass_sem);
if (cls) {
pr_debug("unregistering interface '%s' from class '%s'\n",
intf->name,cls->name);
del_intf(intf);
kset_unregister(&intf->kset);
put_devclass(cls);
}
up(&devclass_sem);
}
/**
* interface_add_dev - add device to interfaces.
* @dev: device.
*
* This is a helper for the class driver core. When a
* device is being added to a class, this is called to add
* the device to all the interfaces in the class.
*
* The operation is simple enough: loop over the interfaces
* and call add() [above] for each. The class rwsem is assumed
* to be held.
*/
int interface_add_dev(struct device * dev)
{
struct device_class * cls = dev->driver->devclass;
struct list_head * node;
pr_debug("interfaces: adding device %s\n",dev->name);
list_for_each(node,&cls->subsys.kset.list) {
struct device_interface * intf = to_intf(node);
add(intf,dev);
}
return 0;
}
/**
* interface_remove_dev - remove device from interfaces.
* @dev: device.
*
* This is another helper for the class driver core, and called
* when the device is being removed from the class.
*
* We iterate over the list of the class's devices and call del()
* [above] for each. Again, the class's rwsem is _not_ held, but
* the devclass_sem is (see class.c).
*/
void interface_remove_dev(struct device * dev)
{
struct list_head * entry, * next;
struct device_class * cls = dev->driver->devclass;
pr_debug("interfaces: removing device %s\n",dev->name);
list_for_each_safe(entry,next,&cls->subsys.kset.list) {
struct device_interface * intf = to_intf(entry);
del(intf,dev);
}
}
EXPORT_SYMBOL(interface_register);
EXPORT_SYMBOL(interface_unregister);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment