# gizhw:block

NVMe controllers through the kernel's passthrough ioctls (NVME_IOCTL_ADMIN_CMD and NVME_IOCTL_IO_CMD on the controller's node, /dev/nvmeN): Identify (the controller), the SMART health log, and a read of blocks by passthrough. The command is struct nvme_admin_cmd or nvme_passthru_cmd (72 bytes, the same layout), and the ioctls are the kernel's (linux/nvme_ioctl.h, checked against it). Every call is on a Handle of gizhw:device.

```gizlang
import * as Block from "gizhw:block";
```

## Types

### `Controller`

```gizlang
type Controller = { vendor: i64; serial: string; model: string; firmware: string; capacity: i64; namespaces: i64; }
```

The controller's identity: vendor id, serial, model, firmware, total capacity in bytes, namespace count.

- `vendor`: `i64`
- `serial`: `string`
- `model`: `string`
- `firmware`: `string`
- `capacity`: `i64`
- `namespaces`: `i64`

### `Smart`

```gizlang
type Smart = { warning: i64; temperature: i64; spare: i64; percentUsed: i64; dataUnitsRead: i64; dataUnitsWritten: i64; powerOnHours: i64; unsafeShutdowns: i64; mediaErrors: i64; }
```

The SMART / health log: warning bits, temperature in degrees C, spare percent, percent used, data units (512,000 bytes
each) read and written, power-on hours, unsafe shutdowns, and media errors.

- `warning`: `i64`
- `temperature`: `i64`
- `spare`: `i64`
- `percentUsed`: `i64`
- `dataUnitsRead`: `i64`
- `dataUnitsWritten`: `i64`
- `powerOnHours`: `i64`
- `unsafeShutdowns`: `i64`
- `mediaErrors`: `i64`

## Functions

### `command`

```gizlang
function command(opcode: i64, nsid: u64, addr: u64, length: i64, dwords: Vec<i64>): bytes
```

A passthrough command: the opcode, the namespace, the data buffer (`addr`, `length` bytes), and up to six command
dwords (cdw10 to cdw15).

Effects: fail.

### `parseController`

```gizlang
function parseController(data: bytes): Controller
```

The controller from the Identify reply (4096 bytes): vendor id, serial (bytes 4 to 24), model (24 to 64), firmware
(64 to 72), total capacity (the low 8 bytes at 280) and the namespace count (516).

Effects: fail.

### `parseSmart`

```gizlang
function parseSmart(data: bytes): Smart
```

The SMART log from its reply (512 bytes). The temperature is the composite one, in Kelvin in the log.

Effects: fail.

### `controller`

```gizlang
function controller(h: Device.Handle): Controller throws string
```

The controller behind `h`: Identify with CNS 1.

Effects: fail, io.

### `smart`

```gizlang
function smart(h: Device.Handle): Smart throws string
```

The SMART / health log of the controller behind `h` (all namespaces).

Effects: fail, io.

### `read`

```gizlang
function read(h: Device.Handle, nsid: u64, lba: i64, blocks: i64, blockBytes: i64): bytes throws string
```

`blocks` blocks of `blockBytes` each, from block `lba` of namespace `nsid`, by IO passthrough (a read).

Effects: fail, io.

### `open`

```gizlang
function open(sys: System, node: string): Device.Handle throws string
```

The handle on the controller's node (read-write, which the passthrough ioctls need).

Effects: fail, io.

### `controllers`

```gizlang
function controllers(sys: System): Vec<Device.Device> throws IoError
```

The NVMe controllers of the nvme class, with their nodes.

Effects: fail, io.

