1

I'm writing an experimental kernel-mode program to test some things. I want to do IO to and from a SATA disk attached to an AHCI controller. I have a C driver that previously worked on another similar project that ran on another PC I no longer have. The PC I have now is an HP laptop with the ICH9 chipset. All reads and writes are 2 sectors in size and happen one at a time, so it issues normal LBA48 DMA read/write commands (No NCQ) and gets an interrupt to signal completion. Reading works perfectly as expected, but writing fails 100% of the time. PxSERR remains zero, but the TFES bit lights in PxIS. The device shows 0x84 in the error register (Interface CRC error, command aborted) and 0x51 in the status register (Error, seek complete, device ready). This seems to point to a cabling issue or similar hardware issue, but Linux has no issues reading or writing to the same partition on the same device and the BIOS built-in disk tests report the disk working properly. Sending the device a SET FEATURES command specifying a lower DMA mode makes no difference, and Linux reports putting the device in UDMA/133 mode anyway. (Is this even relevant to SATA?) Anyway, can anyone think of something I'm missing?

user541686
  • 205,094
  • 128
  • 528
  • 886
  • Dumb question, but is there a CRC field that you're not setting? Also, can Linux write to the same *position* on the disk (not just the same partition)? (This sector doesn't happen to be a bad sector, right?) – user541686 Dec 11 '16 at 22:22
  • Linux can write there, in fact Linux wrote a pre-created partition image there that the kernel mode program is expected to interact with. As far as any CRC field, there is none visible that I can find in the SATA spec. – Daniel Seagraves Dec 11 '16 at 22:33
  • Weird. What happens if you try to send the exact same kind of request as a pass-through request on an actual OS (hopefully to a different drive that you don't care about, rather than the one the OS booted from)? Does it work there? On Windows this would be `IOCTL_ATA_PASS_THROUGH[_DIRECT]`; on Linux I'm not sure what the equivalent is. – user541686 Dec 11 '16 at 23:04

0 Answers0