socsvn commit: r257083 - soc2013/zcore/head/usr.sbin/bhyve
zcore at FreeBSD.org
zcore at FreeBSD.org
Sat Sep 7 16:08:00 UTC 2013
Author: zcore
Date: Sat Sep 7 16:08:00 2013
New Revision: 257083
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257083
Log:
support ATA_FLUSHCACHE and ATA_FLUSHCACHE48
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 7 16:07:01 2013 (r257082)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c Sat Sep 7 16:08:00 2013 (r257083)
@@ -54,6 +54,8 @@
#include "ahci.h"
#include "block_if.h"
+#define MAX_PORTS 6 /* Intel Cougar Point AHCI support 6 ports*/
+
#define PxSIG_ATA 0x00000101 /* ATA drive */
#define PxSIG_ATAPI 0xeb140101 /* ATAPI drive */
@@ -82,8 +84,6 @@
STAILQ_ENTRY(ahci_ioreq) io_list;
uint8_t *cfis;
int slot;
- uint8_t status;
- uint8_t error;
};
struct ahci_port {
@@ -94,8 +94,10 @@
int atapi;
int reset;
int mult_sectors;
+ int flush_pending;
uint32_t unhandled_read;
uint32_t unhandled_write;
+ pthread_cond_t flush_cond;
uint8_t xfermode;
uint32_t clb;
@@ -154,7 +156,7 @@
uint32_t em_ctl;
uint32_t cap2;
uint32_t bohc;
- struct ahci_port port[AHCI_MAX_PORTS];
+ struct ahci_port port[MAX_PORTS];
};
#define ahci_ctx(sc) ((sc)->asc_pi->pi_vmctx)
@@ -215,16 +217,18 @@
}
}
-static void ahci_write_fis_d2h(struct ahci_port *p, struct ahci_ioreq *aior)
+static void ahci_write_fis_d2h(struct ahci_port *p, int slot,
+ uint8_t *cfis, uint32_t tfd)
{
uint8_t fis[20];
- uint8_t *cfis = aior->cfis;
+ uint8_t error;
+ error = (tfd >> 8) & 0xff;
memset(fis, 0, sizeof(fis));
fis[0] = FIS_TYPE_REGD2H;
fis[1] = (1 << 6);
- fis[2] = aior->status;
- fis[3] = aior->error;
+ fis[2] = tfd & 0xff;
+ fis[3] = error;
fis[4] = cfis[4];
fis[5] = cfis[5];
fis[6] = cfis[6];
@@ -235,10 +239,10 @@
fis[11] = cfis[11];
fis[12] = cfis[12];
fis[13] = cfis[13];
- if (aior->error & ATA_S_ERROR)
+ if (error & ATA_S_ERROR)
p->is |= AHCI_P_IX_TFE;
- p->tfd = (aior->error << 8) | aior->status;
- p->ci &= ~(1 << aior->slot);
+ p->tfd = tfd;
+ p->ci &= ~(1 << slot);
ahci_write_fis(p, FIS_TYPE_REGD2H, fis);
}
@@ -386,6 +390,19 @@
}
static void
+handle_flush(struct ahci_port *p, int slot, uint8_t *cfis)
+{
+ struct pci_ahci_softc *sc = p->pr_sc;
+
+ if (p->unhandled_write) {
+ p->flush_pending = 1;
+ pthread_cond_wait(&p->flush_cond, &sc->mtx);
+ p->flush_pending = 0;
+ }
+ ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC);
+}
+
+static void
handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis)
{
struct pci_ahci_softc *sc = p->pr_sc;
@@ -516,6 +533,10 @@
case ATA_WRITE_DMA48:
handle_dma(p, slot, cfis);
break;
+ case ATA_FLUSHCACHE:
+ case ATA_FLUSHCACHE48:
+ handle_flush(p, slot, cfis);
+ break;
default:
break;
}
@@ -596,6 +617,7 @@
struct ahci_port *p;
struct pci_ahci_softc *sc;
struct ahci_ioreq *aior;
+ uint32_t tfd;
aior = br->br_param;
p = aior->io_pr;
@@ -604,14 +626,11 @@
DPRINTF(("ahci_ioreq_cb %d\n", err));
pthread_mutex_lock(&sc->mtx);
- if (err) {
- aior->status = ATA_S_READY | ATA_S_ERROR;
- aior->error = ATA_E_ABORT;
- } else {
- aior->status = ATA_S_READY | ATA_S_DSC;
- aior->error = 0;
- }
- ahci_write_fis_d2h(p, aior);
+ if (err)
+ tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR;
+ else
+ tfd = ATA_S_READY | ATA_S_DSC;
+ ahci_write_fis_d2h(p, aior->slot, aior->cfis, tfd);
/*
* Move the blockif request back to the free list
@@ -636,6 +655,8 @@
}
p->unhandled_read &= unhandled;
p->unhandled_write &= unhandled;
+ if (!p->unhandled_write && p->flush_pending)
+ pthread_cond_signal(&p->flush_cond);
}
pthread_mutex_unlock(&sc->mtx);
@@ -700,20 +721,22 @@
sc->port[0].bctx = bctxt;
- for (i = 0; i < AHCI_MAX_PORTS; i++) {
+ sc->ports = MAX_PORTS;
+ for (i = 0; i < sc->ports; i++) {
+ if (!sc->port[i].bctx)
+ continue;
sc->port[i].pr_sc = sc;
+ pthread_cond_init(&sc->port[i].flush_cond, NULL);
/*
* Allocate blockif request structures and add them
* to the free list
*/
- if (sc->port[i].bctx)
- pci_ahci_ioreq_init(&sc->port[i]);
+ pci_ahci_ioreq_init(&sc->port[i]);
}
pthread_mutex_init(&sc->mtx, NULL);
/* Intel Cougar Point AHCI */
- sc->ports = 6;
sc->cap = AHCI_CAP_64BIT | AHCI_CAP_SNCQ | AHCI_CAP_SSNTF |
AHCI_CAP_SMPS | AHCI_CAP_SSS | AHCI_CAP_SALP |
AHCI_CAP_SAL | AHCI_CAP_SCLO | (0x3 << AHCI_CAP_ISS_SHIFT)|
More information about the svn-soc-all
mailing list