Purpose of rules file: This rules file provides nonvolatile, unique names (in the form of symlinks) for input devices that cooperate. Description of rules: This file starts off with a few rules that make Udev skip the entire file if the current uevent is not input related. If ACTION is not "add", or SUBSYSTEM is not "input", or KERNEL (the device node) matches "input[0-9]*", then Udev will GOTO the LABEL named "persistent_input_end", which is the last rule in this file. (input[0-9]* uevents are skipped because they do not create device nodes.) This type of "skip this list of rules if X" operation is done in both the persistent input and persistent storage rules files. The reason is efficiency -- if Udev had to go run the usb_id and/or path_id programs for non-input and non-storage rules, those rules would take much longer to process for no good reason. First in this file is a set of rules for by-ID style symlinks. These attempt to uniquely identify a device based on its serial number, but there are some issues with this. Many USB manufacturers do not provide a unique serial number for each device -- for instance, my Microsoft Intellimouse Optical has a USB serial number of "Microsoft_Microsoft_IntelliMouse_Optical". This kind of nonsensical "serial number" means that if you plug in two Intellimouse Optical devices, they will both get the same by-id symlink, and the device that the symlink points to will be random. This defeats the purpose of by-ID symlinks. (However, I believe this behavior is technically valid according to the USB standard. I believe it is not recommended, though.) Anyway, first in the by-ID rules, we have a rule that runs for any (input) device hanging anywhere off a USB bus. It uses the IMPORT{program} option to run the "/lib/udev/usb_id -x" program. usb_id looks at the environment to find out which device to look at, generates a list of environment-variable VAR=value pairs, and prints them. Udev stores this output away while the process is running. After the process exits, Udev modifies the current environment to include the VARs that usb_id printed. (It assigns the "value"s that usb_id printed to each of those VARs.) Specifically, usb_id prints ID_VENDOR, ID_MODEL, ID_REVISION, ID_SERIAL, ID_TYPE, and ID_BUS (at least in the case of the aforementioned USB optical mouse). These variable names will all be set in the environment. Then, we have a set of rules to set ID_CLASS for various types of devices. The rules first check for a "usb"-bus device that has a "bInterfaceClass" of 03 and a "bInterfaceProtocol" of 01. If the interface class is 03, this is an HID device. If the protocol is 01, it's a keyboard device. So we set ID_CLASS to "kbd". The next rule checks whether the interface protocol is 02, and if so, sets ID_CLASS to "mouse" (HID devices with a protocol of 02 are mice). Any input device that the "pcspkr" driver claims must be a speaker. Any input device that the "atkbd" driver claims must be a keyboard. Any input device that the "psmouse" driver claims must be a mouse. If there's a sysfs attribute named "name", whose contents contain "dvb", "DVB", or " IR ", then we set ID_CLASS to "ir". Then, we have a rule to search the tree and find the first parent that has a modalias. If that modalias matches the big long ugly string in the rules file, we assume this is a joystick device, and set ID_CLASS appropriately. (This parent should be the kobject for the joystick device itself. The reason we search the tree is that the current uevent is for a device node, not the physical joystick device.) Once the ID_CLASS variable is set properly, we have one more modification to perform: if the ID_SERIAL variable was not set at all by the usb_id program, we set it to "noserial". Now that all the environment variables are set up properly, we start generating the by-ID symlinks in /dev/input/by-id/. If the current device node's name starts with "event", we add "event" into the symlink name. Otherwise, we don't add anything for mice. (Other device types don't get a persistent by-ID symlink.) Next, we create by-path symlinks. The /lib/udev/path_id program takes the path of the device as an argument, and prints out "ID_PATH=string", where "string" is the "shortest physical path" to the device. We import this value into the environment. If the path is non-empty, and the device node name starts with "mouse" or "event", we add a by-path symlink based on the path and the device class (and we also add "event" if it's an event device). This symlink should be stable as long as the device never moves to a different port.