Intel (HPE) SSD reports 0 bytes on Intel C232 AHCI but reports full size on any other controller

djzort

Renowned Member
Aug 8, 2013
30
1
68
This is not proxmox specific but it is happening on my proxmox server(s) so I am hoping maybe someone has had the same experience.

Short version: the SSD is fine. On my ASUS P10S-I the onboard Intel C232 AHCI controller gets an IDENTIFY DEVICE response back with the capacity words zeroed, so Proxmox sees a 0 B disk that can't be used for anything. The same drive reports the full 480 GB on every other controller I've tried. A PCIe-to-SATA adapter (JMicron JMB585) fixes it, and both drives are running on it now.

I am using the add in controller as a workaround. I don't know why the controller does this, and that's what I'd like any help with.

The hardware​


Two HPE LK0480GFJSK drives. They're Intel drives with HPE branding and HPE firmware on them, not HPE silicon: HPE option kit 832414-B21, spare 832454-001, assembly 804612-006. HPE's own tooling identifies the underlying part as "Haleyville 3", which is the Intel DC S3610. 480 GB, eMLC, Mixed Use, 3 DWPD, 512 bytes per sector, SATA 6 Gb/s.

unit Aunit B
serialBTHC719101G0480MGNBTHC719106X7480MGN
LU WWN5 5cd2e4 14dc2c4835 5cd2e4 14dc2f030
firmware4IHVHPG64IHVHPG6

Failing host: ASUS P10S-I, Intel C232 AHCI at PCI 00:17.0 (ID 8086:a102), Proxmox VE kernel 7.0.6-2-pve, BIOS 4602, link 6.0 Gb/s. Working host: Intel Cougar Point 6-series, FreeBSD 15.1, link 3.0 Gb/s. The same two drives, physically moved between hosts:

unit Aunit B
Cougar Point (FreeBSD)480,103,981,056 bytes480,103,981,056 bytes
C232 (Proxmox)0 bytes0 bytes

The symptom​


lsblk on the failing host. Match on serial or WWN, the /dev/sd* names move around depending on which controller is present.

Code:
sdg                               8:96      0B sata   LK0480GFJSK        BTHC719106X7480MGN

dmesg for the same drive:

Code:
[Sat Oct 17 21:11:12 2026] ata6.00: ATA-10: LK0480GFJSK, 4IHVHPG6, max UDMA/100
[Sat Oct 17 21:11:12 2026] ata6.00: 0 sectors, multi 1: LBA NCQ (depth 32), AA
[Sat Oct 17 21:11:12 2026] ata6.00: configured for UDMA/100

blockdev --getsize64 /dev/sdg returns 0.

The drive itself is healthy. Same drive, same host, same boot, only the controller differs. On the C232:

Code:
Device Model:     LK0480GFJSK
Serial Number:    BTHC719106X7480MGN
LU WWN Device Id: 5 5cd2e4 14dc2f030
Firmware Version: 4IHVHPG6
Rotation Rate:    Solid State Device

On the JMB585 two lines appear and the capacity comes back:

Code:
Device Model:     LK0480GFJSK
Serial Number:    BTHC719106X7480MGN
LU WWN Device Id: 5 5cd2e4 14dc2f030
Firmware Version: 4IHVHPG6
User Capacity:    480,103,981,056 bytes [480 GB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    Solid State Device

SMART on the failing controller is clean too:

Code:
SMART overall-health self-assessment test result: PASSED

Code:
SMART Error Log Version: 1
No Errors Logged

Code:
0x04  =====  =               =  ===  == General Errors Statistics (rev 1) ==
0x04  0x008  4               0  ---  Number of Reported Uncorrectable Errors
0x04  0x010  4               0  ---  Resets Between Cmd Acceptance and Completion

Code:
0x07  0x008  1               0  ---  Percentage Used Endurance Indicator

READ CAPACITY(10) and (16) on the failing controller, unit B, both come back with the last LBA field saturated, which is how a drive says it can't tell you its capacity:

Code:
SCSI Status: Good 

Received 8 bytes of data:
 00     ff ff ff ff 00 00 02 00                             ........

Code:
SCSI Status: Good 

Received 16 bytes of data:
 00     ff ff ff ff ff ff ff ff  00 00 02 00 00 03 80 00    ................

libata clamps that against the capacity the drive advertised in IDENTIFY, which is zero, so the block device comes up empty and can't be used for a VM, a container or a ZFS pool.

Checking whether you have this​


If a disk shows up as 0 B but is otherwise healthy, dump IDENTIFY DEVICE and look at the capacity words:

Code:
smartctl -d sat --identify=wb /dev/sdX | grep -E "^ *(60-61|100-103)"

Healthy, unit B on the JMB585. The grep matches two lines in the dump, here is the first:

Code:
  60-61   .     0xffff:0fff  (268435455)

and the second, further down the same dump:

Code:
 100-103  .     0x36b0:37e4:0000:0000  (937703088)

Broken, the same drive on the C232:

Code:
  60-61   -     0x00...  User addressable sectors for 28-bit commands (DWord)

and the second match in that dump:

Code:
 100-103  -     0x00...  User addressable sectors for 48-bit commands (QWord)

If you get zero there while SMART is clean, and the same drive reports full size on another controller, you've got this. Don't RMA the drive, it's fine.

What I ruled out​


  • The drive. Both units report the full 480 GB on the other host. SMART is clean on both controllers, including the failing one.
  • The OS. The fault reproduces in P10S-I POST and in UEFI setup, before any OS has loaded.
  • HPA or DCO. HPA is unsupported, IDENTIFY word 82 bit 10 reads 0 on all three controllers. DCO is implemented but isn't a capacity mask: hdparm --dco-identify reports "Real max sectors: 1" on the failing controller and on the working one alike.
  • State on the drive. It answers differently per controller, so any stored state would have to travel with it.
  • Port, cable, BIOS, other drives on the same C232, firmware. All reproduced or ruled out. The JMB585 also runs at 6.0 Gb/s and reports full size.
  • READ NATIVE MAX ADDRESS. Fails on both hosts including the working one, so it doesn't discriminate.

What actually differs​


IDENTIFY DEVICE returns the 512 byte identity block. Words 60-61 carry LBA28 capacity, words 100-103 carry LBA48 capacity. Dumping all 256 words on both controllers with the same drive, only the capacity words change: words 0-58, 62-76, 78-99, 102-119 and 121-254 are byte identical, and so are the serial, model, firmware and WWN strings. The words that change are 59, 60, 61, 77, 100, 101, 120 and 255.

Full byte-level diff, unit B, Cougar Point versus C232. This is my analysis of the two dumps rather than tool output, but the bytes are the ones captured above:

Code:
 byte  word   change          what it is
    119   59  9d -> 81        sanitize feature set bits (word 59)
    120   60  ff -> 00        \
    121   60  ff -> 00         |  LBA28 user addressable sectors
    122   61  ff -> 00         |  0xFFFF0FFF -> 0
    123   61  0f -> 00        /   268435455 -> 0
    154   77  04 -> 06        negotiated link speed, 3 -> 6 Gb/s
    200  100  b0 -> 00        \
    201  100  36 -> 00         |  LBA48 user addressable sectors
    202  101  e4 -> 00         |  0x36B037E4 -> 0
    203  101  37 -> 00        /   937703088 -> 0
    240  120  1c -> 5c        sense data reporting (bit 6)
    511  255  7a -> 61        IDENTIFY checksum byte

And the modified response is checksum-valid. IDENTIFY DEVICE ends with a signature byte 0xA5 and a checksum byte, and the sum of all 512 bytes must be 0 mod 256 (T13/1699-D). Both dumps pass that on their own. What matters more is that the C232's changed bytes cancel each other out. My arithmetic on the dumps, not tool output:

Code:
sum of the 11 changed data bytes (Cougar Point -> C232):   +25 mod 256
IDENTIFY checksum byte change (Cougar Point -> C232):      -25 mod 256
                                                             ------
total:                                                        0 mod 256

A controller doesn't recompute the IDENTIFY checksum, so the altered response was produced at the source rather than corrupted on the way through. That rules out bit corruption on the wire.

The work around...​


A JMicron JMB585 PCIe-to-SATA card (PCI 06:00.0, ID 197b:0585) in the PCIe slot. Two ordinary AHCI SATA ports, nothing changes in Proxmox.

The test that settled it: one drive on the adapter, the other still on the C232, same boot, same host, same cables. Unit B on the C232:

Code:
[    3.020305] ata5: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[    3.021913] ata5.00: ATA-10: LK0480GFJSK, 4IHVHPG6, max UDMA/100
[    3.022356] ata5.00: 0 sectors, multi 1: LBA NCQ (depth 32), AA
[    3.023726] ata5.00: configured for UDMA/100

Unit A on the JMB585, same boot:

Code:
[    3.821982] ata8: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[    3.823047] ata8.00: ATA-10: LK0480GFJSK, 4IHVHPG6, max UDMA/100
[    3.824375] ata8.00: 937703088 sectors, multi 1: LBA48 NCQ (depth 32), AA
[    3.826616] ata8.00: configured for UDMA/100

Two physically distinct drives, same model, same firmware, same machine, same boot, same cables. The only difference is which controller they are attached to. Both units are on the add-in adapter now and both report 480,103,981,056 bytes.

The open question​


One thing lines up: the C232 advertises 64-bit DMA, the add-in card gets forced to 32-bit by the kernel, and the Cougar Point that works has no 64-bit DMA at all. There's a known class of this in mainline, SATA controllers that falsely advertise S64A, and the kernel already ships 32-bit DMA quirks for the JMicron JMB582/JMB585 and ASMedia ASM1061/ASM1161.

I dropped that theory for two reasons. IDENTIFY DEVICE is a PIO command, so the capacity words come back over the PIO data lines, not through the HBA's DMA engine. And the fault reproduces in POST and UEFI setup, where there is no kernel IOMMU and no DMA masking, so intel_iommu=off isn't a test that can work.

What I'm left with is the odd part. The response is internally consistent: the 11 changed bytes and the checksum byte cancel out exactly, which doesn't happen by accident and isn't what corruption on the wire looks like. From the drive's side it looks like the drive decided to report that it has no sectors. The same drive also reports a reduced feature set in word 59 on the C232, three bits cleared, the sanitize feature set, commands-during-sanitize and the antifreeze lock:

Code:
  59      -     0x8101   Sanitize Device - READ/WRITE MULTIPLE support
  59     15          1   BLOCK ERASE EXT supported
  59     14          0   OVERWRITE EXT supported
  59     13          0   CRYPTO SCRAMBLE EXT supported
  59     12          0   Sanitize Device feature set supported
  59     11          0   Cmds during sanitize are as specified by ACS-3
  59     10          0   SANITIZE ANTIFREEZE LOCK EXT supported

Code:
  59      -     0x9d01   Sanitize Device - READ/WRITE MULTIPLE support
  59     15          1   BLOCK ERASE EXT supported
  59     14          0   OVERWRITE EXT supported
  59     13          0   CRYPTO SCRAMBLE EXT supported
  59     12          1   Sanitize Device feature set supported
  59     11          1   Cmds during sanitize are as specified by ACS-3
  59     10          1   SANITIZE ANTIFREEZE LOCK EXT supported

The question​


Has anyone else seen an enterprise SSD report zero capacity on an Intel 100-series/C230 AHCI controller while working fine on another controller? I couldn't find a prior report searching by part number, firmware string and symptom. The "0 byte SSD" hits are all NVMe.

Full 256 word IDENTIFY dumps for both units on all three controllers, plus the capture script, available on request.