summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/anatol/smart.go/nvme_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/anatol/smart.go/nvme_linux.go')
-rw-r--r--vendor/github.com/anatol/smart.go/nvme_linux.go60
1 files changed, 56 insertions, 4 deletions
diff --git a/vendor/github.com/anatol/smart.go/nvme_linux.go b/vendor/github.com/anatol/smart.go/nvme_linux.go
index eeb2f12..592a3fe 100644
--- a/vendor/github.com/anatol/smart.go/nvme_linux.go
+++ b/vendor/github.com/anatol/smart.go/nvme_linux.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
+ "syscall"
"unsafe"
"golang.org/x/sys/unix"
@@ -38,6 +39,29 @@ type nvmePassthruCmd64 struct {
result uint64
}
+var nvmeIoctlAdminCmd = iowr('N', 0x41, unsafe.Sizeof(nvmePassthruCmd{}))
+
+type nvmePassthruCmd struct {
+ opcode uint8
+ flags uint8
+ _ uint16
+ nsid uint32
+ cdw2 uint32
+ cdw3 uint32
+ metadata uint64
+ addr uint64
+ metadataLen uint32
+ dataLen uint32
+ cdw10 uint32
+ cdw11 uint32
+ cdw12 uint32
+ cdw13 uint32
+ cdw14 uint32
+ cdw15 uint32
+ timeoutMs uint32
+ result uint32
+}
+
type NVMeDevice struct {
fd int
}
@@ -78,7 +102,21 @@ func nvmeReadLogPage(fd int, logID uint8, buf []byte) error {
return fmt.Errorf("invalid buffer size")
}
- cmd := nvmePassthruCmd64{
+ cmd64 := nvmePassthruCmd64{
+ opcode: nvmeAdminGetLogPage,
+ nsid: 0xffffffff, // controller-level SMART info
+ addr: uint64(uintptr(unsafe.Pointer(&buf[0]))),
+ dataLen: uint32(bufLen),
+ cdw10: uint32(logID) | (((uint32(bufLen) / 4) - 1) << 16),
+ }
+
+ err := ioctl(uintptr(fd), nvmeIoctlAdmin64Cmd, uintptr(unsafe.Pointer(&cmd64)))
+ if err != syscall.ENOTTY {
+ return err
+ }
+
+ // fallback to legacy 32bit struct
+ cmd := nvmePassthruCmd{
opcode: nvmeAdminGetLogPage,
nsid: 0xffffffff, // controller-level SMART info
addr: uint64(uintptr(unsafe.Pointer(&buf[0]))),
@@ -86,11 +124,25 @@ func nvmeReadLogPage(fd int, logID uint8, buf []byte) error {
cdw10: uint32(logID) | (((uint32(bufLen) / 4) - 1) << 16),
}
- return ioctl(uintptr(fd), nvmeIoctlAdmin64Cmd, uintptr(unsafe.Pointer(&cmd)))
+ return ioctl(uintptr(fd), nvmeIoctlAdminCmd, uintptr(unsafe.Pointer(&cmd)))
}
func (d *NVMeDevice) readIdentifyData(nsid, cns int, data []byte) error {
- cmd := nvmePassthruCmd64{
+ cmd64 := nvmePassthruCmd64{
+ opcode: nvmeAdminIdentify,
+ nsid: uint32(nsid),
+ addr: uint64(uintptr(unsafe.Pointer(&data[0]))),
+ dataLen: uint32(len(data)),
+ cdw10: uint32(cns),
+ }
+
+ err := ioctl(uintptr(d.fd), nvmeIoctlAdmin64Cmd, uintptr(unsafe.Pointer(&cmd64)))
+ if err != syscall.ENOTTY {
+ return err
+ }
+
+ // fallback to legacy 32bit struct
+ cmd := nvmePassthruCmd{
opcode: nvmeAdminIdentify,
nsid: uint32(nsid),
addr: uint64(uintptr(unsafe.Pointer(&data[0]))),
@@ -98,7 +150,7 @@ func (d *NVMeDevice) readIdentifyData(nsid, cns int, data []byte) error {
cdw10: uint32(cns),
}
- return ioctl(uintptr(d.fd), nvmeIoctlAdmin64Cmd, uintptr(unsafe.Pointer(&cmd)))
+ return ioctl(uintptr(d.fd), nvmeIoctlAdminCmd, uintptr(unsafe.Pointer(&cmd)))
}
func (d *NVMeDevice) readControllerIdentifyData() (*NvmeIdentController, error) {