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