kernel - Change callout in struct ccb_hdr * Change the callout declaration in struct ccb_hdr from an embedded structure to a pointer, add padding to get the whole structure to its original size (prior to the recent callout patch). * This removes an improper ABI dependency on the kernel struct callout structure which was causing 'camcontrol', and 'smartctl' (from smartmontools) to fail. Testing: dillon, tuxillo
ahci - Adjust a few things * These changes have no effect on known AHCI devices but are a good idea. * As suggested in the AHCI spec 10.1.2, zero out the memory pointed to by the FB and CL port dma addresses. * Write to FB before FBU, and to CLB before CLBU, just in case hardware clears the upper bits on a write to the lower bits (no known AHCI hardware does this but its something that is commonly implemented in other hw so...). * Improved I/O error reporting.
ahci: Print "Serial ATA Additional capabilities" The 7th bit of this field indicates whether SEND FPDMA QUEUED and RECEIVE FPDMA QUEUED are supported or not. SEND FPDMA QUEUED could be used to support NCQ TRIM. If this bit is set, following steps are needed to determine whether NCQ TRIM could be used or not: READ LOG EXT (0x00, General Purpose Log Directory Log) if (!log8[0x26]) { no NCQ TRIM support return } READ LOG EXT (0x13, NCQ Send and Receive Log) if ((log32[0] & 0x1) == 0) { no NCQ TRIM support return } if ((log32[1] & 0x1) == 0) { no NCQ TRIM support return } /* NCQ TRIM is supported */
ahci(4)/sili(4): Fix for drives >2TB. CAM will issue the 16 byte version of the READ CAPACITY command when maxsector is 0xffffffff: ----- scsi_da.c ----- if (maxsector == 0xffffffff) { softc->state = DA_STATE_PROBE2; kfree(rdcap, M_SCSIDA); xpt_release_ccb(done_ccb); xpt_schedule(periph, /*priority*/5); return; } --------------------- However, we are subtracting 1 from it (presumably because it's a "last sector on the device" value starting at 0) so in CAM, it ended up being 0xfffffffe, resulting in disks attached via ahci(4) and sili(4) to be limited to 2TB. To fix, set the local var to 0 in this case, so that after subtracting 1 from the value (cast to 32 bit) CAM gets 0xffffffff. Fix-by: dillon
kernel - Fix another AHCI bug * Remove the unlock/lock sequences around the xpt_done() calls. These temporary unlocks create a gap which can allow another interrupt to squeeze in and interfere with the interrupt thread that is already running, resulting in corruption. This bug occurs under very heavy loads, and typically required multiple concurrent ops to a SSD to trigger. * Add additional assertions to catch issues and reorder one of the chiploads. * This is a bit non-optimal, be on the lookout for deadlocks in case it turns out that holding the lock is a bad idea.
kernel - make adjustments to the AHCI driver to try to locate some races * Change the timeout handling to ensure that the expire mask is properly cleared and the timeout has completed processing. * Panic upon reporting an unknown xa->state. Reported-by: masterblaster / randy_
kernel - Fix CAM tag reservation for AHCI and SILI driver * These drivers were adjusting the number of available tags upward using the wrong CAM call, which resulted in CAM not actually queueing multiple tags. Use the correct call. * With the issue fix and verified up to a combined 31 read and write requests can now be queued in parallel to a SATA drive via the AHCI driver. It does appear to make a difference.
kernel - Run AHCI and SILI disk drivers MPSAFE * These drivers now pass a port-disk-port lock in the cam sim registration, which should result in CAM callbacks being MPSAFE. * Add a separate signalling interlock for the port threads. * The devices were otherwise already MPSAFE, with per-port locking.
AHCI/SILI - More adjustments to last commit * Use the ultradma field instead of the legacy field. All SATA devices must support DMA so don't bother with the other legacy fields. If the ultradma field is not initialized (on future devices) then presumably we do not have to SETXFER at all. * Note that SATA hard drives do report this field. * Fix mode calculation.
AHCI/SILI - Send dummy SETXFER mode even though it is SATA * If the identify structure contains a non-zero/non-FFFF dmamode field we send a dummy SETXFER mode command to the device. * Most SATA DISK devices set this field to 0 or FFFF and in this case no SETXFER mode command is sent. SETXFER is non-applicable to SATA in general. Most ATAPI devices still initialize the dmamode field and some ATAPI devices still require SETXFER to be sent even though they are native SATA. SATA->PATA converters may require a SETXFER to be passed through before the PATA devices will operate properly. In this case the dmamode field will likely be initialized.
AHCI - zero-pad ATAPI commands * ATAPI commands sent via the SCSI layer which are less then 16 bytes are now zero-padded to 16 bytes. The SATA protocol itself just sends the whole FIS, so no more or less data is being sent. But extra bytes will not be sent as zero. Discussed-with: "Alex Hornung" <ahornung@gmail.com>
ahci(4) - Add support for ATA passthrough * Add support for ATA_PASS_{12,16} cam commands to pass through an ATA command directly to the device. Incidentally, this will make smartmontools work again when used with device type 'sat'. Dragonfly-bug: http://bugs.dragonflybsd.org/issue1412 Reported-By: Hasso Tepper