mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 14:30:50 +00:00 
			
		
		
		
	 1da177e4c3
			
		
	
	
		1da177e4c3
		
	
	
	
	
		
			
			Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
		
			
				
	
	
		
			130 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
 | |
| Device Interfaces
 | |
| 
 | |
| Introduction
 | |
| ~~~~~~~~~~~~
 | |
| 
 | |
| Device interfaces are the logical interfaces of device classes that correlate
 | |
| directly to userspace interfaces, like device nodes. 
 | |
|    
 | |
| Each device class may have multiple interfaces through which you can 
 | |
| access the same device. An input device may support the mouse interface, 
 | |
| the 'evdev' interface, and the touchscreen interface. A SCSI disk would 
 | |
| support the disk interface, the SCSI generic interface, and possibly a raw 
 | |
| device interface. 
 | |
| 
 | |
| Device interfaces are registered with the class they belong to. As devices
 | |
| are added to the class, they are added to each interface registered with
 | |
| the class. The interface is responsible for determining whether the device
 | |
| supports the interface or not. 
 | |
| 
 | |
| 
 | |
| Programming Interface
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| struct device_interface {
 | |
| 	char			* name;
 | |
| 	rwlock_t		lock;
 | |
| 	u32			devnum;
 | |
| 	struct device_class	* devclass;
 | |
| 
 | |
| 	struct list_head	node;
 | |
| 	struct driver_dir_entry	dir;
 | |
| 
 | |
| 	int (*add_device)(struct device *);
 | |
| 	int (*add_device)(struct intf_data *);
 | |
| };
 | |
| 
 | |
| int interface_register(struct device_interface *);
 | |
| void interface_unregister(struct device_interface *);
 | |
| 
 | |
| 
 | |
| An interface must specify the device class it belongs to. It is added
 | |
| to that class's list of interfaces on registration.
 | |
| 
 | |
| 
 | |
| Interfaces can be added to a device class at any time. Whenever it is
 | |
| added, each device in the class is passed to the interface's
 | |
| add_device callback. When an interface is removed, each device is
 | |
| removed from the interface.
 | |
| 
 | |
| 
 | |
| Devices
 | |
| ~~~~~~~
 | |
| Once a device is added to a device class, it is added to each
 | |
| interface that is registered with the device class. The class
 | |
| is expected to place a class-specific data structure in 
 | |
| struct device::class_data. The interface can use that (along with
 | |
| other fields of struct device) to determine whether or not the driver
 | |
| and/or device support that particular interface.
 | |
| 
 | |
| 
 | |
| Data
 | |
| ~~~~
 | |
| 
 | |
| struct intf_data {
 | |
| 	struct list_head	node;
 | |
| 	struct device_interface	* intf;
 | |
| 	struct device 		* dev;
 | |
| 	u32			intf_num;
 | |
| };
 | |
| 
 | |
| int interface_add_data(struct interface_data *);
 | |
| 
 | |
| The interface is responsible for allocating and initializing a struct 
 | |
| intf_data and calling interface_add_data() to add it to the device's list
 | |
| of interfaces it belongs to. This list will be iterated over when the device
 | |
| is removed from the class (instead of all possible interfaces for a class).
 | |
| This structure should probably be embedded in whatever per-device data 
 | |
| structure the interface is allocating anyway.
 | |
|    
 | |
| Devices are enumerated within the interface. This happens in interface_add_data()
 | |
| and the enumerated value is stored in the struct intf_data for that device. 
 | |
| 
 | |
| sysfs
 | |
| ~~~~~
 | |
| Each interface is given a directory in the directory of the device
 | |
| class it belongs to:
 | |
| 
 | |
| Interfaces get a directory in the class's directory as well:
 | |
| 
 | |
|    class/
 | |
|    `-- input
 | |
|        |-- devices
 | |
|        |-- drivers
 | |
|        |-- mouse
 | |
|        `-- evdev
 | |
| 
 | |
| When a device is added to the interface, a symlink is created that points 
 | |
| to the device's directory in the physical hierarchy:
 | |
| 
 | |
|    class/
 | |
|    `-- input
 | |
|        |-- devices
 | |
|        |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
 | |
|        |-- drivers
 | |
|        |   `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/
 | |
|        |-- mouse
 | |
|        |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
 | |
|        `-- evdev
 | |
|            `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
 | |
| 
 | |
| 
 | |
| Future Plans
 | |
| ~~~~~~~~~~~~
 | |
| A device interface is correlated directly with a userspace interface
 | |
| for a device, specifically a device node. For instance, a SCSI disk
 | |
| exposes at least two interfaces to userspace: the standard SCSI disk
 | |
| interface and the SCSI generic interface. It might also export a raw
 | |
| device interface. 
 | |
| 
 | |
| Many interfaces have a major number associated with them and each
 | |
| device gets a minor number. Or, multiple interfaces might share one
 | |
| major number, and each will receive a range of minor numbers (like in
 | |
| the case of input devices).
 | |
| 
 | |
| These major and minor numbers could be stored in the interface
 | |
| structure. Major and minor allocations could happen when the interface
 | |
| is registered with the class, or via a helper function. 
 | |
| 
 |