zircon设备ops

#设备协议

设备驱动程序实现了一组 hook(方法)来支持可以在他们发布的设备上执行的操作。

这些描述如下,包括每个 hook使用的通过默认实现采取的行动(如果驱动程序不提供自己的实现)。

##version
该字段必须设置为“DEVICE_OPS_VERSION”
```
uint64_t version;
```

##open
通过设备文件系统打开设备时调用open hook,或克隆现有的设备开放连接时(例如,当设备fd与另一个进程共享时)。如果驱动程序没有实现一个,默认的open hook只需返回** ZX_OK **。

驱动程序可能希望实现open以禁止同时访问(通过如果设备已经打开则失败),或者返回一个新的**设备实例**代替。

可选的* dev_out *参数允许设备创建并返回一个**设备实例**子设备,可用于管理每个实例状态而不是与设备本身交互的所有客户端连接。作为实例**创建的子项必须使用在** device_add()**的参数中设置** DEVICE_ADD_INSTANCE **标志。

```
zx_status_t (*open)(void* ctx, zx_device_t** dev_out, uint32_t flags);
```

## open_at
弃用:见ZX-3277。
如果是设备的开放路径,则调用open_at hook包含设备名称后面的段。例如,如果是设备存在于`/dev/misc/foo`并尝试`open(“/dev/misc/foo/bar”,...)`,open_at hook将被调用“bar”的*path*。

默认的open_at实现返回** ZX_ERR_NOT_SUPPORTED **

```
zx_status_t (*open_at)(void* ctx, zx_device_t** dev_out, const char* path, uint32_t flags);
```

## close
关闭设备连接时会调用关闭 hook。这些通话将平衡对open或open_at的调用。

**注意:**如果open或open_at返回**设备实例**,则平衡关闭被调用的 hook是**实例**上的关闭 hook,而不是父实例。

默认关闭实现返回** ZX_OK **。

```
zx_status_t (*close)(void* ctx, uint32_t flags);
```


## unbind
当删除此设备的父设备时,将调用unbind hook(热插拔,致命错误等)。在调用unbind时,它不是可能会发生进一步的open或open_at调用,但是io操作等等可能会继续,直到这些客户端连接关闭。

驱动程序应该避免对其父设备的进一步的方法调用或协议获取,并期望任何进一步的此类调用将返回错误。

驱动程序应调整其状态以鼓励其客户端连接关闭(导致IO错误输出等),并在准备好时自行调用** device_remove()**。

驱动程序必须继续处理所有设备 hook,直到**释放** hook被调用。

```
void (*unbind)(void* ctx);
```

## release
在** device_remove()移除此设备,且所有打开的客户端连接都已关闭,且所有子设备都已关闭删除并释放,后调用释放 hook。

在调用释放点时,驱动程序将不再接收任何进一步的调用并且绝对不能使用** zx_device_t **相关变量或从该设备获得的任何协议。

驱动程序必须释放所有内存并释放与此设备相关的所有资源。
```
void (*release)(void* ctx);
```

##read
读取 hook是尝试执行非阻塞读取操作。

成功时* actual *必须设置为读取的字节数(可能比* count *中请求的数量更少),并返回** ZX_OK **。

成功读取0字节通常被视为文件结束通知由客户。

如果现在没有数据可用,则必须返回** ZX_ERR_SHOULD_WAIT **,当数据变得可用`device_state_set(DEVICE_STATE_READABLE)`可用于向等待客户端发送信号。

这个 hook**一定不能阻塞**。

默认的读取实现返回** ZX_ERR_NOT_SUPPORTED **。


```
zx_status_t (*read)(void* ctx, void* buf, size_t count,
                    zx_off_t off, size_t* actual);
```

##write
写 hook是尝试执行非阻塞写操作。

成功时* actual *必须设置为写入的字节数(可能是小于* count *中请求的数量),并且应返回** ZX_OK **。

如果目前无法写入数据,必须返回** ZX_ERR_SHOULD_WAIT **。当再次可以写,`device_state_set(DEVICE_STATE_WRITABLE)`可用于向等待的客户端发送信号。

这个 hook**一定不能阻塞**。

默认写入实现返回** ZX_ERR_NOT_SUPPORTED **。
```
zx_status_t (*write)(void* ctx, const void* buf, size_t count,
                     zx_off_t off, size_t* actual);
```
## get_size
如果设备是seekable,则get_size hook应返回设备的大小。

这是不再可能进行读取或写入的偏移量。

默认实现返回0。
```
zx_off_t (*get_size)(void* ctx);
```

## ioctl
ioctl hook允许支持特定于设备的操作。

这些,如读和写,不能阻塞。

成功时,必须返回** ZX_OK **并且必须设置* out_actual *提供的输出字节数(如果没有,则为0)。

默认的ioctl实现返回** ZX_ERR_NOT_SUPPORTED **。
```
zx_status_t (*ioctl)(void* ctx, uint32_t op,
                     const void* in_buf, size_t in_len,
                     void* out_buf, size_t out_len, size_t* out_actual);
```

## rxrpc
只被总线设备调用。
当busdev的“影子”发送rpc消息时,被阴影的设备会被rxrpc op通知,并且它应该尝试在提供的channel上读取并回复单个消息。

从此方法返回的任何错误都将导致通道被关闭,远程“影子”失去联系。

当一个新客户连接时,通过ZX_HANDLE_INVALID为通道调用此方法 - 此时任何一个以前的客户端的状态都应该销毁。
```
zx_status_t (*rxrpc)(void* ctx, zx_handle_t channel);
```


## message
处理FIDL rpc消息。这用于处理类或特定于设备的消息fuchsia.io.{Node,File,Device}是由devhost本身的句柄。

整个信息成为驱动的responsibility,包括句柄。

提供响应消息的txn仅在message()调用期间有效。它不能被缓存并在以后使用。

如果此方法返回除ZX_OK之外的任何内容,则为底层连接已关闭。
```
zx_status_t (*message)(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn);
```

####设备状态位
```
#define DEV_STATE_READABLE DEVICE_SIGNAL_READABLE
#define DEV_STATE_WRITABLE DEVICE_SIGNAL_WRITABLE
#define DEV_STATE_ERROR DEVICE_SIGNAL_ERROR
#define DEV_STATE_HANGUP DEVICE_SIGNAL_HANGUP
#define DEV_STATE_OOB DEVICE_SIGNAL_OOB
```

#### device_state_set
```
void device_state_set(zx_device_t* dev, zx_signals_t stateflag);
```
 

你可能感兴趣的:(fuchsia)