summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2017-04-16 06:00:14 +0000
committermav <mav@FreeBSD.org>2017-04-16 06:00:14 +0000
commit02b48f26241fda00a1af61c6bc72d80c6cd73afb (patch)
tree1afd9a5e60ab8000b49ce1a55bcc93e22b0cd09d /usr.sbin
parentc528c5d843b9318758a4242230444f4a584f2686 (diff)
downloadFreeBSD-src-02b48f26241fda00a1af61c6bc72d80c6cd73afb.zip
FreeBSD-src-02b48f26241fda00a1af61c6bc72d80c6cd73afb.tar.gz
MFC r316427, r316428: Add Log directory and SATA NCQ Send and Receive Log.
Those are used at least by Linux guests to detect queued TRIM support.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/pci_ahci.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c
index 1cc9594..1bc1736 100644
--- a/usr.sbin/bhyve/pci_ahci.c
+++ b/usr.sbin/bhyve/pci_ahci.c
@@ -936,19 +936,36 @@ static void
ahci_handle_read_log(struct ahci_port *p, int slot, uint8_t *cfis)
{
struct ahci_cmd_hdr *hdr;
- uint8_t buf[512];
+ uint32_t buf[128];
+ uint8_t *buf8 = (uint8_t *)buf;
+ uint16_t *buf16 = (uint16_t *)buf;
hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE);
- if (p->atapi || hdr->prdtl == 0 || cfis[4] != 0x10 ||
- cfis[5] != 0 || cfis[9] != 0 || cfis[12] != 1 || cfis[13] != 0) {
+ if (p->atapi || hdr->prdtl == 0 || cfis[5] != 0 ||
+ cfis[9] != 0 || cfis[12] != 1 || cfis[13] != 0) {
ahci_write_fis_d2h(p, slot, cfis,
(ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR);
return;
}
memset(buf, 0, sizeof(buf));
- memcpy(buf, p->err_cfis, sizeof(p->err_cfis));
- ahci_checksum(buf, sizeof(buf));
+ if (cfis[4] == 0x00) { /* Log directory */
+ buf16[0x00] = 1; /* Version -- 1 */
+ buf16[0x10] = 1; /* NCQ Command Error Log -- 1 page */
+ buf16[0x13] = 1; /* SATA NCQ Send and Receive Log -- 1 page */
+ } else if (cfis[4] == 0x10) { /* NCQ Command Error Log */
+ memcpy(buf8, p->err_cfis, sizeof(p->err_cfis));
+ ahci_checksum(buf8, sizeof(buf));
+ } else if (cfis[4] == 0x13) { /* SATA NCQ Send and Receive Log */
+ if (blockif_candelete(p->bctx) && !blockif_is_ro(p->bctx)) {
+ buf[0x00] = 1; /* SFQ DSM supported */
+ buf[0x01] = 1; /* SFQ DSM TRIM supported */
+ }
+ } else {
+ ahci_write_fis_d2h(p, slot, cfis,
+ (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR);
+ return;
+ }
if (cfis[2] == ATA_READ_LOG_EXT)
ahci_write_fis_piosetup(p);
OpenPOWER on IntegriCloud