TheBasic Device Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~
See the kerneldoc for the struct device.
ProgrammingInterface
~~~~~~~~~~~~~~~~~~~~~
檢測到設備的總線驅動使用如下函數將設備註冊到內核:
int device_register(struct device * dev);
總線負責初始化device結構的下列域:
- parent
- name
- bus_id
- bus
當設備的reference count變爲0時,會從內核中移除. 使用下列函數調整reference count
struct device * get_device(struct device * dev);
void put_device(struct device * dev);
如果reference count還不是0(如果正好處於移除的過程中),get_device()會返回指向傳遞給它的struct device的指針.
驅動可以使用下列函數訪問device結構中的lock:
void lock_device(struct device * dev);
void unlock_device(struct device * dev);
Attributes
~~~~~~~~~~
struct device_attribute {
structattribute attr;
ssize_t(*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev,struct device_attribute *attr, const char *buf, size_t count);
};
驅動可以使用一個類似於procfs(sysfs)的接口來導出設備的屬性。有關sysfs如何工作的內容,請參考Documentation/filesystems/sysfs.txt.
設備屬性可以通過宏DEVICE_ATTR聲明:
#define DEVICE_ATTR(name,mode,show,store)
Example:
DEVICE_ATTR(power,0644,show_power,store_power);
這個宏聲明瞭一個名爲'dev_attr_power'的device_attribute結構. 通過下列函數可以將屬性添加/移除到設備在/sysfs的目錄:
int device_create_file(struct device *device, structdevice_attribute * entry);
void device_remove_file(struct device * dev, structdevice_attribute * attr);
Example:
device_create_file(dev,&dev_attr_power);
device_remove_file(dev,&dev_attr_power);
該文件的名字是'power' ,訪問權限爲0644 (-rw-r--r--).
警告: 無論何時,當內核允許對一個設備調用device_create_file()和
device_remove_file(), 用戶空間對設備屬性何時被創建有嚴格的期望. 當一個新設備註冊到內核,會產生一個uevent以提示用戶空間(比如udev)有新設備可用. 如果屬性在設備註冊之後才添加,用戶空間則無從瞭解這個屬性.
對於設備驅動而言,在探測(probe)設備時要做的一項重要工作是爲設備發佈額外的屬性. 如果設備驅動只是簡單地對傳遞給它的device結構調用device_create_file(), 那麼用戶空間永遠無法獲得新屬性的通知. 相反地,設備驅動或許應當在模塊入口函數modules_init()中使用class_create() 和 class->dev_attrs創建一個屬性列表,而後在
.probe()中使用device_create()創建一個設備,作爲被探測到的設備的子設備. 這個新的設備會產生uevent並將新的屬性發布到用戶空間.
舉例來說,如果一個驅動想要增添如下屬性:
struct device_attribute mydriver_attribs[] = {
__ATTR(port_count,0444, port_count_show),
__ATTR(serial_number,0444, serial_number_show),
NULL
};
在模塊入口函數中應該做:
mydriver_class= class_create(THIS_MODULE, "my_attrs");
mydriver_class.dev_attr= mydriver_attribs;
假設'dev' 是傳遞到probe()的參數,設備驅動的probe函數則要做:
device_create(&mydriver_class,dev, chrdev, &private_data, "my_name");