#ifndef LINUX_DEVREG_H #define LINUX_DEVREG_H /* * This file contains the devreg kernel API. Please note that all functions * can only be used in a user context as they may sleep. */ #include #include #include #include #include /* * Describes position of device. */ enum devreg_location{ DEVREG_LOCATION_INTERNAL = 0, DEVREG_LOCATION_EXTERNAL = 1, DEVREG_LOCATION_VIRTUAL = 2, DEVREG_LOCATION_UNKNOWN = 3 }; /* * Describes position and indentation in the /proc/devreg file * for extension callbacks. */ struct devreg_buffer_position { char *buf; size_t write_left; loff_t skip_left; unsigned int indent_level; }; #ifdef CONFIG_DEVREG /** * devreg_register_physical_device - registers a physical device * @key: pointer that can be used to find the device, for example the * struct pci_dev for PCI devices. The exact meaning of the key is * bus-specific. If %NULL the function will do nothing. * @parent_key: pointer key of the parent device, or %NULL * @superdevice_key: pointer key of the superdevice device, or %NULL * @bus: name of the bus * @type: type of the device, can be %NULL if unknown; will be copied * @deviceid: the id of the device without serial num and trailing '/' * (bus-specific format); will be copied * @deviceidsernum: the serial-num of the device (device specific format, * can be %NULL); will be copied * @model: the model name of the device (presented to users) * @vendor: the vendor name or %NULL (presented to users) * @location_desc: description of the location (presented to users, should * be language neutral if possible, use abbrevations and * numbers/letters like USB, PCI or COM2) * @location: if the bus/driver knows whether the device internal or * external it should set the flag accordingly, otherwise use * %DEVREG_LOCATION_UNKNOWN * * Registers a physical device. All argument strings but deviceid * and deviceidsernum must be valid as long as the device is registered, * devreg will keep the pointers. The arguments deviceic and deviceidsernum * will be copied (because each device has its own deviceid), so they can * be invalidated after the registration. */ void devreg_register_physical_device(void *key, void *parent_key, void *superdevice_key, const char *bus, const char *type, const char *deviceid, const char *deviceidsernum, const char *model, const char *vendor, const char *location_desc, enum devreg_location location); /** * devreg_get_physical_device - retrieves values of phycial device * @key: the key to search * @parent_key: if not %NULL the key of the parent will be written here * @superdevice_key: if not %NULL the key of the superdevice will be * written here * @bus: if not %NULL the bus name will be written here * @type: if not %NULL the type will be written here * @deviceid: if not %NULL the deviceid without serial number will be written * here * @deviceidsernum: if not %NULL the serial number will be written here * @model: if not %NULL the model will be written here * @vendor: if not %NULL the vendor will be written here * @location_desc: if not %NULL the location descriptor will be written here * @location: if not %NULL the location will be written here * * Retrieves the values of the physical device with the given key. * Returns true (non-zero) if the device was found, false otherwise. */ int devreg_get_physical_device(void *key, void **parent_key, void **superdevice_key, const char **bus, const char **type, const char **deviceid, const char **deviceidsernum, const char **model, const char **vendor, const char **location_desc, enum devreg_location *location); /** * devreg_unregister_physical_device - unregisters physical device * @key: the key of the device to unregister. If %NULL will do nothing. * * Unregisters device, removes all subdevices and children * recursively. */ void devreg_unregister_physical_device(void *key); /** * devreg_set_device_type - sets the type of a device * @key: key of the device. If %NULL will do nothing. * @type: the new type of the device, string will be copied. Can be %NULL. * * Sets the type of the device. This can be used by a driver to change * the device type set by the bus subsystem. * If the device is a subdevice and its parent's type is %NULL the superdevice's * type will be set, too. */ void devreg_set_device_type(void *key, const char *type); /** * devreg_set_device_serial_number - sets the serial number of a device * @key: key of the device. If %NULL will do nothing. * @serial_num: the new serial number of the device, string will be copied * * Sets the serial number of the device id. Can be used by a driver to * set the serial number of a device if the bus was not able to do this. */ void devreg_set_device_serial_number(void *key, const char *serial_num); /** * devreg_set_superdevice - sets the superdevice * @key: key of the device. If %NULL will do nothing. * @superdevice_key: the superdevice's key, or %NULL of not a subdevice * * Changes the superdevice of the device. */ void devreg_set_superdevice(void *key, void *superdevice_key); /** * devreg_register_extension - adds an extension to the device's directory * @key: key of the device. Can be %NULL, the function will return immediately * then * @name: the name of the new directory * @register_files: this callback functions receives a handle to a dynamic * directory and should add its own files to the extension * dir * @private_data: pointer that will be given to register_files * @enter_cb: optional proc_ov callback that is invoked before any other * callback in the extension direcotry is invoked. Can be %NULL. * @leave_cb: optional proc_ov callback that is invoked after a callback in * the extension direcotry has been invoked. Can be %NULL. * @context: the context of the files in the extension directory. This will * also be used for enter_cb and leave_cb. * * Registers a extension for the proc output. This gives you a new directory * that can contain driver-specific files. The directory will only appear * for those devices you have registered it for. Its location is * /proc/devreg//. All files that you want to add * must be added by the register_files callback that you provide (to be * atomic). register_files gets a struct proc_dir_entry pointer that can be * used to add new files and directories using the proc_ov_* functions. * DO NOT USE REGULAR PROC FUNCTIONS to add files because the directory is * dynamic. If register_files returns false an error is assumed and all files * in the directory are deleted automatically. */ void devreg_register_extension(void *key, const char *name, int (*register_files) (struct proc_dir_entry *dir, void *data), void *private_data, proc_ov_dir_enter_t enter_cb, proc_ov_dir_leave_t leave_cb, void *context); /** * devreg_unregister_extension - unregisters an extension * @key: key of the device. If %NULL will do nothing. * @name: the name of the directory * * Unregisters the given extension. This is usually not neccessary as it happens * automatically when the device is unregistered. */ void devreg_unregister_extension(void *key, const char *name); /* * Initialization function for init/main.c */ void devreg_init(void); #else /* CONFIG_DEVREG */ inline static void devreg_register_physical_device(void *key, void *parent_key, void *superdevice_key, const char *bus, const char *type, const char *deviceid, const char *deviceidsernum, const char *model, const char *vendor, const char *location_desc, enum devreg_location location) {} inline static void devreg_unregister_physical_device(void *key) {} inline static void devreg_set_device_type(void *key, const char *type) {} inline static void devreg_set_device_serial_number(void *key, const char *serial_num) {} inline static void devreg_set_superdevice(void *key, void *superdevice_key) {} inline static void devreg_register_extension(void *key, int (*extra_xml_cb) ( struct devreg_buffer_position *pos, void *private_data), void *private_data) inline static void devreg_register_extension(void *key, const char *name, int (*register_files) (struct proc_dir_entry *dir, void *data), void *private_data, proc_ov_dir_enter_t enter_cb, proc_ov_dir_leave_t leave_cb, void *context) {} inline static void devreg_unregister_extension(void *key, const char *name) {} inline static int devreg_get_physical_device(void *key, void **parent_key, void **superdevice_key, const char **bus, const char **type, const char **deviceid, const char **deviceidsernum, const char **model, const char **vendor, const char **location_desc, enum devreg_location *location) { return 0; } #endif /* CONFIG_DEVREG */ #endif