socsvn commit: r257328 - soc2013/zcore/head/usr.sbin/bhyve

zcore at FreeBSD.org zcore at FreeBSD.org
Sat Sep 14 15:53:53 UTC 2013


Author: zcore
Date: Sat Sep 14 15:53:52 2013
New Revision: 257328
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257328

Log:
  ATA_ATA_IDENTIFY: abort if ATAPI or prdtl is wrong

Modified:
  soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c

Modified: soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Sat Sep 14 13:12:13 2013	(r257327)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Sat Sep 14 15:53:52 2013	(r257328)
@@ -433,19 +433,21 @@
 }
 
 static void
-handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis)
+handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
 {
+	struct ahci_cmd_hdr *hdr;
 	struct pci_ahci_softc *sc = p->pr_sc;
-	struct ahci_prdt_entry *prdt = (struct ahci_prdt_entry *)(cfis + 0x80);
 
-	switch(cfis[2]) {
-	case ATA_ATA_IDENTIFY:
-	{
+	hdr = p->cmd_lst + slot * AHCI_CL_SIZE;
+	if (p->atapi || hdr->prdtl == 0) {
+		p->tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR;
+		p->is |= AHCI_P_IX_TFE;
+	} else {
 		uint16_t buf[256];
 		uint64_t sectors;
 		int i, len;
 		void *from;
-		struct ahci_cmd_hdr *hdr;
+		struct ahci_prdt_entry *prdt;
 
 		sectors = blockif_size(p->bctx) / blockif_sectsz(p->bctx);
 		memset(buf, 0, sizeof(buf));
@@ -489,13 +491,9 @@
 		buf[101] = (sectors >> 16);
 		buf[102] = (sectors >> 32);
 		buf[103] = (sectors >> 48);
-		hdr = p->cmd_lst + slot * AHCI_CL_SIZE;
-		if (hdr->prdtl == 0) {
-			WPRINTF(("wrong prdtl\n"));
-			return;
-		}
 		len = sizeof(buf);
 		from = buf;
+		prdt = (struct ahci_prdt_entry *)(cfis + 0x80);
 		for (i = 0; i < hdr->prdtl && len; i++) {
 			uint8_t *p = paddr_guest2host(ahci_ctx(sc),
 					prdt->dba, prdt->dbc + 1);
@@ -507,10 +505,18 @@
 		hdr->prdbc = sizeof(buf) - len;
 		p->tfd = ATA_S_DSC | ATA_S_READY;
 		p->is |= AHCI_P_IX_DP;
-		p->ci &= ~(1 << slot);
-		ahci_generate_intr(sc);
-		break;
 	}
+	p->ci &= ~(1 << slot);
+	ahci_generate_intr(sc);
+}
+
+static void
+handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis)
+{
+	switch(cfis[2]) {
+	case ATA_ATA_IDENTIFY:
+		handle_identify(p, slot, cfis);
+		break;
 	case ATA_SETFEATURES:
 	{
 		switch (cfis[3]) {
@@ -541,7 +547,7 @@
 		}
 		p->is |= AHCI_P_IX_DP;
 		p->ci &= ~(1 << slot);
-		ahci_generate_intr(sc);
+		ahci_generate_intr(p->pr_sc);
 		break;
 	}
 	case ATA_SET_MULTI:
@@ -555,7 +561,7 @@
 		}
 		p->is |= AHCI_P_IX_DP;
 		p->ci &= ~(1 << slot);
-		ahci_generate_intr(sc);
+		ahci_generate_intr(p->pr_sc);
 		break;
 	case ATA_READ_DMA:
 	case ATA_WRITE_DMA:
@@ -581,7 +587,7 @@
 		p->tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR;
 		p->is |= AHCI_P_IX_TFE;
 		p->ci &= ~(1 << slot);
-		ahci_generate_intr(sc);
+		ahci_generate_intr(p->pr_sc);
 		break;
 	}
 }


More information about the svn-soc-all mailing list