squashed proto wip
Change-Id: Iff1e1d5afda995b0251f5c42cd92ed59952fca45
diff --git a/system/dev/audio/intel-hda/controller/intel-hda-dsp.cpp b/system/dev/audio/intel-hda/controller/intel-hda-dsp.cpp
index 7225814..0f1adc3 100644
--- a/system/dev/audio/intel-hda/controller/intel-hda-dsp.cpp
+++ b/system/dev/audio/intel-hda/controller/intel-hda-dsp.cpp
@@ -75,10 +75,10 @@
ZX_DEBUG_ASSERT(ctx);
DEV->Disable();
},
- .irq_enable = [](void* ctx, ihda_dsp_irq_callback_t* callback, void* cookie) -> zx_status_t
+ .irq_enable = [](void* ctx, const ihda_dsp_irq_t* callback) -> zx_status_t
{
ZX_DEBUG_ASSERT(ctx);
- return DEV->IrqEnable(callback, cookie);
+ return DEV->IrqEnable(callback);
},
.irq_disable = [](void* ctx)
{
@@ -163,16 +163,16 @@
if (pp_regs() == nullptr) {
return;
}
- if (irq_callback_ == nullptr) {
+ if (irq_callback_.callback == nullptr) {
return;
}
- ZX_DEBUG_ASSERT(irq_cookie_ != nullptr);
+ ZX_DEBUG_ASSERT(irq_callback_.ctx != nullptr);
ZX_DEBUG_ASSERT(pp_regs() != nullptr);
uint32_t ppsts = REG_RD(&pp_regs()->ppsts);
if (!(ppsts & HDA_PPSTS_PIS)) {
return;
}
- irq_callback_(irq_cookie_);
+ irq_callback_.callback(irq_callback_.ctx);
}
zx_status_t IntelHDADSP::DeviceGetProtocol(uint32_t proto_id, void* protocol) {
@@ -282,15 +282,14 @@
REG_WR(&pp_regs()->ppctl, 0u);
}
-zx_status_t IntelHDADSP::IrqEnable(ihda_dsp_irq_callback_t* callback, void* cookie) {
+zx_status_t IntelHDADSP::IrqEnable(const ihda_dsp_irq_t* callback) {
fbl::AutoLock dsp_lock(&dsp_lock_);
- if (irq_callback_ != nullptr) {
+ if (irq_callback_.callback != nullptr) {
return ZX_ERR_ALREADY_EXISTS;
}
- ZX_DEBUG_ASSERT(irq_cookie_ == nullptr);
+ ZX_DEBUG_ASSERT(irq_callback_.ctx == nullptr);
- irq_callback_ = callback;
- irq_cookie_ = cookie;
+ irq_callback_ = *callback;
REG_SET_BITS<uint32_t>(&pp_regs()->ppctl, HDA_PPCTL_PIE);
@@ -300,8 +299,8 @@
void IntelHDADSP::IrqDisable() {
fbl::AutoLock dsp_lock(&dsp_lock_);
REG_CLR_BITS<uint32_t>(&pp_regs()->ppctl, HDA_PPCTL_PIE);
- irq_callback_ = nullptr;
- irq_cookie_ = nullptr;
+ irq_callback_.callback = nullptr;
+ irq_callback_.ctx = nullptr;
}
zx_status_t IntelHDADSP::CodecGetDispatcherChannel(zx_handle_t* remote_endpoint_out) {
diff --git a/system/dev/audio/intel-hda/controller/intel-hda-dsp.h b/system/dev/audio/intel-hda/controller/intel-hda-dsp.h
index 059d4ef..da18b2b 100644
--- a/system/dev/audio/intel-hda/controller/intel-hda-dsp.h
+++ b/system/dev/audio/intel-hda/controller/intel-hda-dsp.h
@@ -67,7 +67,7 @@
zx_status_t GetBti(zx_handle_t* out_handle);
void Enable();
void Disable();
- zx_status_t IrqEnable(ihda_dsp_irq_callback_t* callback, void* cookie);
+ zx_status_t IrqEnable(const ihda_dsp_irq_t* callback);
void IrqDisable();
// ZX_PROTOCOL_IHDA_CODEC Interface
@@ -87,8 +87,7 @@
IntelHDAController& controller_;
fbl::Mutex dsp_lock_;
- ihda_dsp_irq_callback_t* irq_callback_ TA_GUARDED(dsp_lock_) = nullptr;
- void* irq_cookie_ TA_GUARDED(dsp_lock_) = nullptr;
+ ihda_dsp_irq_t irq_callback_ TA_GUARDED(dsp_lock_) = {nullptr, nullptr};
// Driver connection state
fbl::Mutex codec_driver_channel_lock_;
diff --git a/system/dev/audio/intel-hda/dsp/intel-audio-dsp.cpp b/system/dev/audio/intel-hda/dsp/intel-audio-dsp.cpp
index 1b03fa7..6b81bf5 100644
--- a/system/dev/audio/intel-hda/dsp/intel-audio-dsp.cpp
+++ b/system/dev/audio/intel-hda/dsp/intel-audio-dsp.cpp
@@ -164,11 +164,15 @@
// Set IRQ handler and enable HDA interrupt.
// Interrupts are still masked at the DSP level.
- res = ihda_dsp_irq_enable(&ihda_dsp_,
- [](void* cookie) {
- auto thiz = static_cast<IntelAudioDsp*>(cookie);
- thiz->ProcessIrq();
- }, this);
+
+ ihda_dsp_irq_t callback = {
+ [](void* cookie) {
+ auto thiz = static_cast<IntelAudioDsp*>(cookie);
+ thiz->ProcessIrq();
+ },
+ this,
+ };
+ res = ihda_dsp_irq_enable(&ihda_dsp_, &callback);
if (res != ZX_OK) {
LOG(ERROR, "Failed to set DSP interrupt callback (res %d)\n", res);
return res;
@@ -179,7 +183,8 @@
zx_status_t IntelAudioDsp::ParseNhlt() {
size_t size = 0;
- zx_status_t res = device_get_metadata(codec_device(), MD_KEY_NHLT,
+ zx_status_t res = device_get_metadata(codec_device(),
+ *reinterpret_cast<const uint32_t*>(MD_KEY_NHLT),
nhlt_buf_, sizeof(nhlt_buf_), &size);
if (res != ZX_OK) {
LOG(ERROR, "Failed to fetch NHLT (res %d)\n", res);
diff --git a/system/dev/block/ahci/ahci.c b/system/dev/block/ahci/ahci.c
index c5c1776..703a5dc 100644
--- a/system/dev/block/ahci/ahci.c
+++ b/system/dev/block/ahci/ahci.c
@@ -9,8 +9,10 @@
#include <ddk/io-buffer.h>
#include <ddk/phys-iter.h>
#include <ddk/protocol/pci.h>
+#include <ddk/protocol/pci-lib.h>
#include <assert.h>
+#include <hw/pci.h>
#include <zircon/listnode.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
diff --git a/system/dev/block/aml-sd-emmc/aml-sd-emmc.c b/system/dev/block/aml-sd-emmc/aml-sd-emmc.c
index 478c5ef..70168a8 100644
--- a/system/dev/block/aml-sd-emmc/aml-sd-emmc.c
+++ b/system/dev/block/aml-sd-emmc/aml-sd-emmc.c
@@ -211,7 +211,7 @@
return ZX_OK;
}
-static zx_status_t aml_sd_emmc_set_bus_width(void* ctx, uint32_t bw) {
+static zx_status_t aml_sd_emmc_set_bus_width(void* ctx, sdmmc_bus_width_t bw) {
aml_sd_emmc_t* dev = (aml_sd_emmc_t*)ctx;
mtx_lock(&dev->mtx);
@@ -219,15 +219,15 @@
uint32_t config = regs->sd_emmc_cfg;
switch (bw) {
- case SDMMC_BUS_WIDTH_1:
+ case SDMMC_BUS_WIDTH_ONE:
update_bits(&config, AML_SD_EMMC_CFG_BUS_WIDTH_MASK, AML_SD_EMMC_CFG_BUS_WIDTH_LOC,
AML_SD_EMMC_CFG_BUS_WIDTH_1BIT);
break;
- case SDMMC_BUS_WIDTH_4:
+ case SDMMC_BUS_WIDTH_FOUR:
update_bits(&config, AML_SD_EMMC_CFG_BUS_WIDTH_MASK, AML_SD_EMMC_CFG_BUS_WIDTH_LOC,
AML_SD_EMMC_CFG_BUS_WIDTH_4BIT);
break;
- case SDMMC_BUS_WIDTH_8:
+ case SDMMC_BUS_WIDTH_EIGHT:
update_bits(&config, AML_SD_EMMC_CFG_BUS_WIDTH_MASK, AML_SD_EMMC_CFG_BUS_WIDTH_LOC,
AML_SD_EMMC_CFG_BUS_WIDTH_8BIT);
break;
@@ -250,7 +250,8 @@
.blockcount = 1,
.blocksize = blk_pattern_size,
.use_dma = false,
- .virt = tuning_res,
+ .virt_buffer = tuning_res,
+ .virt_size = blk_pattern_size,
};
return aml_sd_emmc_request(dev, &tuning_req);
}
@@ -614,7 +615,7 @@
goto complete;
}
uint32_t data_copied = 0;
- uint32_t* dest = (uint32_t*)req->virt;
+ uint32_t* dest = (uint32_t*)req->virt_buffer;
volatile uint32_t* src = (volatile uint32_t*)(io_buffer_virt(&dev->mmio) +
AML_SD_EMMC_PING_BUFFER_BASE);
while (length) {
@@ -804,7 +805,7 @@
desc->cmd_info |= AML_SD_EMMC_CMD_INFO_DATA_WR;
uint32_t data_copied = 0;
uint32_t data_remaining = length;
- uint32_t* src = (uint32_t*)req->virt;
+ uint32_t* src = (uint32_t*)req->virt_buffer;
volatile uint32_t* dest = (volatile uint32_t*)(io_buffer_virt(&dev->mmio) +
AML_SD_EMMC_PING_BUFFER_BASE);
while (data_remaining) {
diff --git a/system/dev/block/imx-sdhci/imx-sdhci.c b/system/dev/block/imx-sdhci/imx-sdhci.c
index 53bc8f3..df2b877 100644
--- a/system/dev/block/imx-sdhci/imx-sdhci.c
+++ b/system/dev/block/imx-sdhci/imx-sdhci.c
@@ -356,7 +356,7 @@
// Sequentially read each block
for (size_t byteid = 0; byteid < req->blocksize; byteid += 4) {
const size_t offset = dev->data_blockid * req->blocksize + byteid;
- uint32_t* wrd = req->virt + offset;
+ uint32_t* wrd = req->virt_buffer + offset;
*wrd = dev->regs->data_buff_acc_port; //TODO: Can't read this if DMA is enabled!
}
dev->data_blockid += 1;
@@ -375,7 +375,7 @@
// Sequentially write each block
for (size_t byteid = 0; byteid < req->blocksize; byteid += 4) {
const size_t offset = dev->data_blockid * req->blocksize + byteid;
- uint32_t* wrd = req->virt + offset;
+ uint32_t* wrd = req->virt_buffer + offset;
dev->regs->data_buff_acc_port = *wrd; //TODO: Can't write if DMA is enabled
}
dev->data_blockid += 1;
@@ -778,7 +778,7 @@
}
/* SDMMC PROTOCOL Implementations: set_bus_width */
-static zx_status_t imx_sdhci_set_bus_width(void* ctx, uint32_t bus_width) {
+static zx_status_t imx_sdhci_set_bus_width(void* ctx, sdmmc_bus_width_t bus_width) {
SDHCI_FUNC_ENTRY_LOG;
if (bus_width >= SDMMC_BUS_WIDTH_MAX) {
return ZX_ERR_INVALID_ARGS;
@@ -788,22 +788,22 @@
mtx_lock(&dev->mtx);
- if ((bus_width == SDMMC_BUS_WIDTH_8) && !(dev->info.caps & SDMMC_HOST_CAP_BUS_WIDTH_8)) {
+ if ((bus_width == SDMMC_BUS_WIDTH_EIGHT) && !(dev->info.caps & SDMMC_HOST_CAP_BUS_WIDTH_8)) {
SDHCI_ERROR("8-bit bus width not supported\n");
status = ZX_ERR_NOT_SUPPORTED;
goto unlock;
}
switch (bus_width) {
- case SDMMC_BUS_WIDTH_1:
+ case SDMMC_BUS_WIDTH_ONE:
dev->regs->prot_ctrl &= ~IMX_SDHC_PROT_CTRL_DTW_MASK;
dev->regs->prot_ctrl |= IMX_SDHC_PROT_CTRL_DTW_1;
break;
- case SDMMC_BUS_WIDTH_4:
+ case SDMMC_BUS_WIDTH_FOUR:
dev->regs->prot_ctrl &= ~IMX_SDHC_PROT_CTRL_DTW_MASK;
dev->regs->prot_ctrl |= IMX_SDHC_PROT_CTRL_DTW_4;
break;
- case SDMMC_BUS_WIDTH_8:
+ case SDMMC_BUS_WIDTH_EIGHT:
dev->regs->prot_ctrl &= ~IMX_SDHC_PROT_CTRL_DTW_MASK;
dev->regs->prot_ctrl |= IMX_SDHC_PROT_CTRL_DTW_8;
break;
@@ -985,7 +985,7 @@
// enable clocks
mtx_unlock(&dev->mtx);
imx_sdhci_set_bus_freq(dev, SD_FREQ_SETUP_HZ);
- imx_sdhci_set_bus_width(dev, SDMMC_BUS_WIDTH_1);
+ imx_sdhci_set_bus_width(dev, SDMMC_BUS_WIDTH_ONE);
}
/* SDMMC PROTOCOL Implementations: request */
diff --git a/system/dev/block/pci-sdhci/pci-sdhci.c b/system/dev/block/pci-sdhci/pci-sdhci.c
index c903f7b..d1d72b5 100644
--- a/system/dev/block/pci-sdhci/pci-sdhci.c
+++ b/system/dev/block/pci-sdhci/pci-sdhci.c
@@ -50,7 +50,7 @@
}
}
-static zx_status_t pci_sdhci_get_mmio(void* ctx, volatile sdhci_regs_t** out) {
+static zx_status_t pci_sdhci_get_mmio(void* ctx, zx_handle_t* out) {
pci_sdhci_device_t* dev = ctx;
if (dev->regs == NULL) {
zx_status_t status = pci_map_bar(&dev->pci, 0u, ZX_CACHE_POLICY_UNCACHED_DEVICE,
@@ -60,8 +60,7 @@
return status;
}
}
- *out = dev->regs;
- return ZX_OK;
+ return zx_vmo_clone(dev->regs_handle, ZX_RIGHT_SAME_RIGHTS, 0, dev->regs_size, out);
}
static zx_status_t pci_sdhci_get_bti(void* ctx, uint32_t index, zx_handle_t* out_handle) {
diff --git a/system/dev/block/sdhci/sdhci.c b/system/dev/block/sdhci/sdhci.c
index 8644588..705d708 100644
--- a/system/dev/block/sdhci/sdhci.c
+++ b/system/dev/block/sdhci/sdhci.c
@@ -29,6 +29,7 @@
#include <hw/sdmmc.h>
// Zircon Includes
+#include <zircon/process.h>
#include <zircon/threads.h>
#include <zircon/assert.h>
#include <lib/sync/completion.h>
@@ -76,6 +77,7 @@
zx_handle_t irq_handle;
thrd_t irq_thread;
+ zx_handle_t regs_handle;
volatile sdhci_regs_t* regs;
sdhci_protocol_t sdhci;
@@ -146,7 +148,7 @@
static bool sdhci_supports_adma2_64bit(sdhci_device_t* dev) {
return (dev->info.caps & SDMMC_HOST_CAP_ADMA2) &&
- (dev->info.caps & SDMMC_HOST_CAP_64BIT) &&
+ (dev->info.caps & SDMMC_HOST_CAP_SIXTY_FOUR_BIT) &&
!(dev->quirks & SDHCI_QUIRK_NO_DMA);
}
@@ -281,7 +283,7 @@
// Sequentially read each block.
for (size_t byteid = 0; byteid < req->blocksize; byteid += 4) {
const size_t offset = dev->data_blockid * req->blocksize + byteid;
- uint32_t* wrd = req->virt + offset;
+ uint32_t* wrd = req->virt_buffer + offset;
*wrd = dev->regs->data;
}
dev->data_blockid += 1;
@@ -301,7 +303,7 @@
// Sequentially write each block.
for (size_t byteid = 0; byteid < req->blocksize; byteid += 4) {
const size_t offset = dev->data_blockid * req->blocksize + byteid;
- uint32_t* wrd = req->virt + offset;
+ uint32_t* wrd = req->virt_buffer + offset;
dev->regs->data = *wrd;
}
dev->data_blockid += 1;
@@ -614,7 +616,7 @@
mtx_lock(&dev->mtx);
// Validate the controller supports the requested voltage
- if ((voltage == SDMMC_VOLTAGE_330) && !(dev->info.caps & SDMMC_HOST_CAP_VOLTAGE_330)) {
+ if ((voltage == SDMMC_VOLTAGE_V330) && !(dev->info.caps & SDMMC_HOST_CAP_VOLTAGE_330)) {
zxlogf(TRACE, "sdhci: 3.3V signal voltage not supported\n");
st = ZX_ERR_NOT_SUPPORTED;
goto unlock;
@@ -625,7 +627,7 @@
zx_nanosleep(zx_deadline_after(ZX_MSEC(2)));
switch (voltage) {
- case SDMMC_VOLTAGE_180: {
+ case SDMMC_VOLTAGE_V180: {
regs->ctrl2 |= SDHCI_HOSTCTRL2_1P8V_SIGNALLING_ENA;
// 1.8V regulator out should be stable within 5ms
zx_nanosleep(zx_deadline_after(ZX_MSEC(5)));
@@ -638,7 +640,7 @@
}
break;
}
- case SDMMC_VOLTAGE_330: {
+ case SDMMC_VOLTAGE_V330: {
regs->ctrl2 &= ~SDHCI_HOSTCTRL2_1P8V_SIGNALLING_ENA;
// 3.3V regulator out should be stable within 5ms
zx_nanosleep(zx_deadline_after(ZX_MSEC(5)));
@@ -658,10 +660,10 @@
// Make sure our changes are acknolwedged.
uint32_t expected_mask = SDHCI_PWRCTRL_SD_BUS_POWER;
switch (voltage) {
- case SDMMC_VOLTAGE_180:
+ case SDMMC_VOLTAGE_V180:
expected_mask |= SDHCI_PWRCTRL_SD_BUS_VOLTAGE_1P8V;
break;
- case SDMMC_VOLTAGE_330:
+ case SDMMC_VOLTAGE_V330:
expected_mask |= SDHCI_PWRCTRL_SD_BUS_VOLTAGE_3P3V;
break;
default:
@@ -685,7 +687,7 @@
return st;
}
-static zx_status_t sdhci_set_bus_width(void* ctx, uint32_t bus_width) {
+static zx_status_t sdhci_set_bus_width(void* ctx, sdmmc_bus_width_t bus_width) {
if (bus_width >= SDMMC_BUS_WIDTH_MAX) {
return ZX_ERR_INVALID_ARGS;
}
@@ -695,22 +697,22 @@
mtx_lock(&dev->mtx);
- if ((bus_width == SDMMC_BUS_WIDTH_8) && !(dev->info.caps & SDMMC_HOST_CAP_BUS_WIDTH_8)) {
+ if ((bus_width == SDMMC_BUS_WIDTH_EIGHT) && !(dev->info.caps & SDMMC_HOST_CAP_BUS_WIDTH_8)) {
zxlogf(TRACE, "sdhci: 8-bit bus width not supported\n");
st = ZX_ERR_NOT_SUPPORTED;
goto unlock;
}
switch (bus_width) {
- case SDMMC_BUS_WIDTH_1:
+ case SDMMC_BUS_WIDTH_ONE:
dev->regs->ctrl0 &= ~SDHCI_HOSTCTRL_EXT_DATA_WIDTH;
dev->regs->ctrl0 &= ~SDHCI_HOSTCTRL_FOUR_BIT_BUS_WIDTH;
break;
- case SDMMC_BUS_WIDTH_4:
+ case SDMMC_BUS_WIDTH_FOUR:
dev->regs->ctrl0 &= ~SDHCI_HOSTCTRL_EXT_DATA_WIDTH;
dev->regs->ctrl0 |= SDHCI_HOSTCTRL_FOUR_BIT_BUS_WIDTH;
break;
- case SDMMC_BUS_WIDTH_8:
+ case SDMMC_BUS_WIDTH_EIGHT:
dev->regs->ctrl0 |= SDHCI_HOSTCTRL_EXT_DATA_WIDTH;
break;
default:
@@ -808,11 +810,11 @@
return st;
}
-static void sdhci_hw_reset(void* ctx) {
+static void sdhci_hw_reset2(void* ctx) {
sdhci_device_t* dev = ctx;
mtx_lock(&dev->mtx);
if (dev->sdhci.ops->hw_reset) {
- dev->sdhci.ops->hw_reset(dev->sdhci.ctx);
+ sdhci_hw_reset(&dev->sdhci);
}
mtx_unlock(&dev->mtx);
}
@@ -902,7 +904,7 @@
.set_bus_width = sdhci_set_bus_width,
.set_bus_freq = sdhci_set_bus_freq,
.set_timing = sdhci_set_timing,
- .hw_reset = sdhci_hw_reset,
+ .hw_reset = sdhci_hw_reset2,
.perform_tuning = sdhci_perform_tuning,
.request = sdhci_request,
};
@@ -919,6 +921,8 @@
static void sdhci_release(void* ctx) {
sdhci_device_t* dev = ctx;
+ zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)dev->regs, sizeof(dev->regs));
+ zx_handle_close(dev->regs_handle);
zx_handle_close(dev->irq_handle);
zx_handle_close(dev->bti_handle);
zx_handle_close(dev->iobuf.vmo_handle);
@@ -1053,12 +1057,18 @@
}
// Map the Device Registers so that we can perform MMIO against the device.
- status = dev->sdhci.ops->get_mmio(dev->sdhci.ctx, &dev->regs);
+ status = dev->sdhci.ops->get_mmio(dev->sdhci.ctx, &dev->regs_handle);
if (status != ZX_OK) {
zxlogf(ERROR, "sdhci: error %d in get_mmio\n", status);
goto fail;
}
-
+ status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0,
+ dev->regs_handle, 0, ROUNDUP(sizeof(dev->regs), PAGE_SIZE),
+ (uintptr_t*)&dev->regs);
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "sdhci: error %d in zx_vmar_map\n", status);
+ goto fail;
+ }
status = dev->sdhci.ops->get_bti(dev->sdhci.ctx, 0, &dev->bti_handle);
if (status != ZX_OK) {
zxlogf(ERROR, "sdhci: error %d in get_bti\n", status);
@@ -1108,7 +1118,7 @@
dev->info.caps |= SDMMC_HOST_CAP_ADMA2;
}
if (caps0 & SDHCI_CORECFG_64BIT_SUPPORT) {
- dev->info.caps |= SDMMC_HOST_CAP_64BIT;
+ dev->info.caps |= SDMMC_HOST_CAP_SIXTY_FOUR_BIT;
}
if (caps0 & SDHCI_CORECFG_3P3_VOLT_SUPPORT) {
dev->info.caps |= SDMMC_HOST_CAP_VOLTAGE_330;
diff --git a/system/dev/block/sdmmc/mmc.c b/system/dev/block/sdmmc/mmc.c
index 1d54c25..ee04178 100644
--- a/system/dev/block/sdmmc/mmc.c
+++ b/system/dev/block/sdmmc/mmc.c
@@ -71,9 +71,9 @@
static uint8_t mmc_select_bus_width(sdmmc_device_t* dev) {
// TODO verify host 8-bit support
- uint8_t bus_widths[] = { SDMMC_BUS_WIDTH_8, MMC_EXT_CSD_BUS_WIDTH_8,
- SDMMC_BUS_WIDTH_4, MMC_EXT_CSD_BUS_WIDTH_4,
- SDMMC_BUS_WIDTH_1, MMC_EXT_CSD_BUS_WIDTH_1 };
+ uint8_t bus_widths[] = { SDMMC_BUS_WIDTH_EIGHT, MMC_EXT_CSD_BUS_WIDTH_8,
+ SDMMC_BUS_WIDTH_FOUR, MMC_EXT_CSD_BUS_WIDTH_4,
+ SDMMC_BUS_WIDTH_ONE, MMC_EXT_CSD_BUS_WIDTH_1 };
for (unsigned i = 0; i < (sizeof(bus_widths)/sizeof(uint8_t)); i += 2) {
if (mmc_set_bus_width(dev, bus_widths[i], bus_widths[i+1]) == ZX_OK) {
break;
@@ -270,13 +270,13 @@
}
dev->type = SDMMC_TYPE_MMC;
- dev->bus_width = SDMMC_BUS_WIDTH_1;
- dev->signal_voltage = SDMMC_VOLTAGE_330;
+ dev->bus_width = SDMMC_BUS_WIDTH_ONE;
+ dev->signal_voltage = SDMMC_VOLTAGE_V330;
// Switch to high-speed timing
if (mmc_supports_hs(dev) || mmc_supports_hsddr(dev) || mmc_supports_hs200(dev)) {
// Switch to 1.8V signal voltage
- sdmmc_voltage_t new_voltage = SDMMC_VOLTAGE_180;
+ sdmmc_voltage_t new_voltage = SDMMC_VOLTAGE_V180;
if ((st = sdmmc_set_signal_voltage(&dev->host, new_voltage)) != ZX_OK) {
zxlogf(ERROR, "mmc: failed to switch to 1.8V signalling, retcode = %d\n", st);
goto err;
@@ -286,7 +286,7 @@
mmc_select_bus_width(dev);
// Must perform tuning at HS200 first if HS400 is supported
- if (mmc_supports_hs200(dev) && dev->bus_width != SDMMC_BUS_WIDTH_1 &&
+ if (mmc_supports_hs200(dev) && dev->bus_width != SDMMC_BUS_WIDTH_ONE &&
!(dev->host_info.prefs & SDMMC_HOST_PREFS_DISABLE_HS200)) {
if ((st = mmc_switch_timing(dev, SDMMC_TIMING_HS200)) != ZX_OK) {
goto err;
@@ -301,7 +301,7 @@
goto err;
}
- if (mmc_supports_hs400(dev) && dev->bus_width == SDMMC_BUS_WIDTH_8 &&
+ if (mmc_supports_hs400(dev) && dev->bus_width == SDMMC_BUS_WIDTH_EIGHT &&
!(dev->host_info.prefs & SDMMC_HOST_PREFS_DISABLE_HS400)) {
if ((st = mmc_switch_timing(dev, SDMMC_TIMING_HS)) != ZX_OK) {
goto err;
@@ -311,7 +311,7 @@
goto err;
}
- if ((st = mmc_set_bus_width(dev, SDMMC_BUS_WIDTH_8,
+ if ((st = mmc_set_bus_width(dev, SDMMC_BUS_WIDTH_EIGHT,
MMC_EXT_CSD_BUS_WIDTH_8_DDR)) != ZX_OK) {
goto err;
}
@@ -329,12 +329,12 @@
goto err;
}
- if (mmc_supports_hsddr(dev) && (dev->bus_width != SDMMC_BUS_WIDTH_1)) {
+ if (mmc_supports_hsddr(dev) && (dev->bus_width != SDMMC_BUS_WIDTH_ONE)) {
if ((st = mmc_switch_timing(dev, SDMMC_TIMING_HSDDR)) != ZX_OK) {
goto err;
}
- uint8_t mmc_bus_width = (dev->bus_width == SDMMC_BUS_WIDTH_4) ?
+ uint8_t mmc_bus_width = (dev->bus_width == SDMMC_BUS_WIDTH_FOUR) ?
MMC_EXT_CSD_BUS_WIDTH_4_DDR :
MMC_EXT_CSD_BUS_WIDTH_8_DDR;
if ((st = mmc_set_bus_width(dev, dev->bus_width, mmc_bus_width)) != ZX_OK) {
diff --git a/system/dev/block/sdmmc/ops.c b/system/dev/block/sdmmc/ops.c
index d15c559..314401d 100644
--- a/system/dev/block/sdmmc/ops.c
+++ b/system/dev/block/sdmmc/ops.c
@@ -120,7 +120,7 @@
.use_dma = sdmmc_use_dma(dev),
};
- if (dev->signal_voltage == SDMMC_VOLTAGE_180) {
+ if (dev->signal_voltage == SDMMC_VOLTAGE_V180) {
return ZX_OK;
}
@@ -131,7 +131,7 @@
}
zx_nanosleep(zx_deadline_after(ZX_MSEC(20)));
//TODO: clock gating while switching voltage
- st = sdmmc_set_signal_voltage(&dev->host, SDMMC_VOLTAGE_180);
+ st = sdmmc_set_signal_voltage(&dev->host, SDMMC_VOLTAGE_V180);
if (st != ZX_OK) {
zxlogf(TRACE, "sd: SD_VOLTAGE_SWITCH failed, retcode = %d\n", st);
return st;
@@ -239,11 +239,12 @@
};
if (use_dma) {
- req.virt = NULL;
+ req.virt_buffer = NULL;
req.dma_vmo = dma_vmo;
req.buf_offset = buf_offset;
} else {
- req.virt = buf + buf_offset;
+ req.virt_buffer = buf + buf_offset;
+ req.virt_size = blk_size;
}
req.use_dma = use_dma;
@@ -334,7 +335,8 @@
.blockcount = 1,
.blocksize = 512,
.use_dma = false,
- .virt = ext_csd,
+ .virt_buffer = ext_csd,
+ .virt_size = 512,
.cmd_flags = MMC_SEND_EXT_CSD_FLAGS,
};
zx_status_t st = sdmmc_request(&dev->host, &req);
diff --git a/system/dev/block/sdmmc/sdio.c b/system/dev/block/sdmmc/sdio.c
index 841afaa..000dc25 100644
--- a/system/dev/block/sdmmc/sdio.c
+++ b/system/dev/block/sdmmc/sdio.c
@@ -14,6 +14,7 @@
#include <ddk/protocol/sdmmc.h>
#include <ddk/protocol/sdio.h>
+#include <hw/sdio.h>
#include <zircon/process.h>
#include <zircon/threads.h>
@@ -53,7 +54,7 @@
// Use io_rw_direct whenever possible.
if (!use_dma && data_size == 1) {
return sdio_rw_byte(dev, txn->write, fn_idx, addr,
- *(uintptr_t*)(txn->virt), txn->virt);
+ *(uintptr_t*)(txn->virt_buffer), txn->virt_buffer);
}
if ((data_size % 4) != 0) {
@@ -64,7 +65,7 @@
return ZX_ERR_NOT_SUPPORTED;
}
bool dma_supported = sdmmc_use_dma(dev);
- void *buf = use_dma ? NULL : txn->virt;
+ void *buf = use_dma ? NULL : txn->virt_buffer;
zx_handle_t dma_vmo = use_dma ? txn->dma_vmo : ZX_HANDLE_INVALID;
uint64_t buf_offset = txn->buf_offset;
@@ -130,7 +131,8 @@
sdio_rw_txn_t txn;
txn.addr = addr;
txn.write = false;
- txn.virt = dword;
+ txn.virt_buffer = dword;
+ txn.virt_size = 4;
txn.data_size = 4;
txn.incr = true;
txn.use_dma = false;
@@ -143,7 +145,8 @@
sdio_rw_txn_t txn;
txn.addr = addr;
txn.write = true;
- txn.virt = (void *)&dword;
+ txn.virt_buffer = (void *)&dword;
+ txn.virt_size = 4;
txn.data_size = 4;
txn.incr = true;
txn.use_dma = false;
@@ -241,7 +244,7 @@
dev->sdio_dev.hw_info.caps |= SDIO_CARD_LOW_SPEED;
}
if (card_caps & SDIO_CIA_CCCR_CARD_CAP_4BLS) {
- dev->sdio_dev.hw_info.caps |= SDIO_CARD_4BIT_BUS;
+ dev->sdio_dev.hw_info.caps |= SDIO_CARD_FOUR_BIT_BUS;
}
//speed
@@ -278,13 +281,13 @@
return status;
}
if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTA) {
- dev->sdio_dev.hw_info.caps |= SDIO_DRIVER_TYPE_A;
+ dev->sdio_dev.hw_info.caps |= SDIO_CARD_TYPE_A;
}
if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTB) {
- dev->sdio_dev.hw_info.caps |= SDIO_DRIVER_TYPE_B;
+ dev->sdio_dev.hw_info.caps |= SDIO_CARD_TYPE_B;
}
if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTD) {
- dev->sdio_dev.hw_info.caps |= SDIO_DRIVER_TYPE_D;
+ dev->sdio_dev.hw_info.caps |= SDIO_CARD_TYPE_D;
}
return status;
}
@@ -518,7 +521,7 @@
static zx_status_t sdio_enable_4bit_bus(sdmmc_device_t *dev) {
zx_status_t st = ZX_OK;
if ((dev->sdio_dev.hw_info.caps & SDIO_CARD_LOW_SPEED) &&
- !(dev->sdio_dev.hw_info.caps & SDIO_CARD_4BIT_BUS)) {
+ !(dev->sdio_dev.hw_info.caps & SDIO_CARD_FOUR_BIT_BUS)) {
zxlogf(ERROR, "sdio: Switching to 4-bit bus unsupported\n");
return ZX_ERR_NOT_SUPPORTED;
}
@@ -535,13 +538,13 @@
zxlogf(ERROR, "sdio: Error while switching the bus width\n");
return st;
}
- if ((st = sdmmc_set_bus_width(&dev->host, SDMMC_BUS_WIDTH_4)) != ZX_OK) {
+ if ((st = sdmmc_set_bus_width(&dev->host, SDMMC_BUS_WIDTH_FOUR)) != ZX_OK) {
zxlogf(ERROR, "sdio: failed to switch the host bus width to %d, retcode = %d\n",
- SDMMC_BUS_WIDTH_4, st);
+ SDMMC_BUS_WIDTH_FOUR, st);
return ZX_ERR_INTERNAL;
}
- dev->bus_width = SDMMC_BUS_WIDTH_4;
+ dev->bus_width = SDMMC_BUS_WIDTH_FOUR;
return ZX_OK;
}
@@ -773,7 +776,7 @@
return ZX_ERR_NOT_SUPPORTED;
}
dev->type = SDMMC_TYPE_SDIO;
- dev->signal_voltage = SDMMC_VOLTAGE_180;
+ dev->signal_voltage = SDMMC_VOLTAGE_V180;
dev->sdio_dev.hw_info.num_funcs = get_bits(ocr, SDIO_SEND_OP_COND_RESP_NUM_FUNC_MASK,
SDIO_SEND_OP_COND_RESP_NUM_FUNC_LOC);
uint16_t addr = 0;
diff --git a/system/dev/block/sdmmc/sdio.h b/system/dev/block/sdmmc/sdio.h
index ecd3095..061d36a 100644
--- a/system/dev/block/sdmmc/sdio.h
+++ b/system/dev/block/sdmmc/sdio.h
@@ -25,6 +25,9 @@
sdio_function_t funcs[SDIO_MAX_FUNCS];
} sdio_device_t;
+static inline bool sdio_fn_idx_valid(uint8_t fn_idx) {
+ return (fn_idx < SDIO_MAX_FUNCS);
+}
static inline bool sdio_is_uhs_supported(uint32_t hw_caps) {
return ((hw_caps & SDIO_CARD_UHS_SDR50) || (hw_caps & SDIO_CARD_UHS_SDR104) ||
diff --git a/system/dev/block/sdmmc/sdmmc.c b/system/dev/block/sdmmc/sdmmc.c
index 7b5d354..b1910c2 100644
--- a/system/dev/block/sdmmc/sdmmc.c
+++ b/system/dev/block/sdmmc/sdmmc.c
@@ -385,7 +385,7 @@
zx_status_t st = ZX_OK;
if (sdmmc_use_dma(dev)) {
req->use_dma = true;
- req->virt = NULL;
+ req->virt_buffer = NULL;
req->pmt = ZX_HANDLE_INVALID;
req->dma_vmo = txn->bop.rw.vmo;
req->buf_offset = txn->bop.rw.offset_vmo;
@@ -393,12 +393,13 @@
req->use_dma = false;
st = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
0, txn->bop.rw.vmo, txn->bop.rw.offset_vmo, txn->bop.rw.length,
- (uintptr_t*)&req->virt);
+ (uintptr_t*)&req->virt_buffer);
if (st != ZX_OK) {
zxlogf(TRACE, "sdmmc: do_txn vmo map error %d\n", st);
block_complete(&txn->bop, st, dev);
return;
}
+ req->virt_size = txn->bop.rw.length;
}
st = sdmmc_request(&dev->host, req);
@@ -417,7 +418,7 @@
}
exit:
if (!req->use_dma) {
- zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)req->virt, txn->bop.rw.length);
+ zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)req->virt_buffer, req->virt_size);
}
block_complete(&txn->bop, st, dev);
zxlogf(TRACE, "sdmmc: do_txn complete\n");
diff --git a/system/dev/block/sdmmc/sdmmc.h b/system/dev/block/sdmmc/sdmmc.h
index 23da68e..fff443b 100644
--- a/system/dev/block/sdmmc/sdmmc.h
+++ b/system/dev/block/sdmmc/sdmmc.h
@@ -92,7 +92,7 @@
} sdmmc_device_t;
static inline bool sdmmc_use_dma(sdmmc_device_t* dev) {
- return (dev->host_info.caps & (SDMMC_HOST_CAP_ADMA2 | SDMMC_HOST_CAP_64BIT));
+ return (dev->host_info.caps & (SDMMC_HOST_CAP_ADMA2 | SDMMC_HOST_CAP_SIXTY_FOUR_BIT));
}
// SD/MMC shared ops
diff --git a/system/dev/bluetooth/bt-hci-broadcom/bt-hci-broadcom.c b/system/dev/bluetooth/bt-hci-broadcom/bt-hci-broadcom.c
index 3fb4cf2..4ff9aea 100644
--- a/system/dev/bluetooth/bt-hci-broadcom/bt-hci-broadcom.c
+++ b/system/dev/bluetooth/bt-hci-broadcom/bt-hci-broadcom.c
@@ -15,6 +15,7 @@
#include <string.h>
#include <threads.h>
#include <zircon/device/bt-hci.h>
+#include <zircon/device/serial.h>
#include <zircon/status.h>
#include <zircon/threads.h>
diff --git a/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c b/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c
index 5d75698..091eab0 100644
--- a/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c
+++ b/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c
@@ -10,6 +10,7 @@
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/serial.h>
#include <zircon/device/bt-hci.h>
+#include <zircon/device/serial.h>
#include <zircon/status.h>
#include <assert.h>
diff --git a/system/dev/board/astro/astro-bluetooth.c b/system/dev/board/astro/astro-bluetooth.c
index d4799f1..acaebf5 100644
--- a/system/dev/board/astro/astro-bluetooth.c
+++ b/system/dev/board/astro/astro-bluetooth.c
@@ -14,6 +14,7 @@
#include <hw/reg.h>
#include <soc/aml-s905d2/s905d2-gpio.h>
#include <soc/aml-s905d2/s905d2-hw.h>
+#include <zircon/device/serial.h>
#include "astro.h"
diff --git a/system/dev/board/vim/vim-uart.c b/system/dev/board/vim/vim-uart.c
index e47780b..9a0827e 100644
--- a/system/dev/board/vim/vim-uart.c
+++ b/system/dev/board/vim/vim-uart.c
@@ -14,6 +14,7 @@
#include <soc/aml-s912/s912-gpio.h>
#include <soc/aml-s912/s912-hw.h>
#include <unistd.h>
+#include <zircon/device/serial.h>
#include "vim.h"
diff --git a/system/dev/bus/pci/kpci.c b/system/dev/bus/pci/kpci.c
index 3fa33f5..0904eff 100644
--- a/system/dev/bus/pci/kpci.c
+++ b/system/dev/bus/pci/kpci.c
@@ -84,11 +84,11 @@
snprintf(args, sizeof(args), "%s,%02x:%02x:%02x", req->data,
device->info.bus_id, device->info.dev_id, device->info.func_id);
- uint32_t actual;
+ size_t actual;
pci_msg_t resp = {};
zx_status_t st = pciroot_get_auxdata(&device->pciroot, args, resp.data, req->outlen, &actual);
if (st == ZX_OK) {
- resp.datalen = actual;
+ resp.datalen = (uint32_t)actual;
}
return pci_rpc_reply(ch, st, 0, req, &resp);
diff --git a/system/dev/bus/pci/proxy.c b/system/dev/bus/pci/proxy.c
index f4863f6..a0c68b5 100644
--- a/system/dev/bus/pci/proxy.c
+++ b/system/dev/bus/pci/proxy.c
@@ -242,7 +242,7 @@
return status;
}
-static zx_status_t pci_op_map_interrupt(void* ctx, int which_irq, zx_handle_t* out_handle) {
+static zx_status_t pci_op_map_interrupt(void* ctx, int32_t which_irq, zx_handle_t* out_handle) {
if (!out_handle) {
return ZX_ERR_INVALID_ARGS;
}
@@ -316,7 +316,7 @@
}
static zx_status_t pci_op_get_auxdata(void* ctx, const char* args, void* data,
- uint32_t bytes, uint32_t* actual) {
+ size_t bytes, size_t* actual) {
kpci_device_t* dev = ctx;
size_t arglen = strlen(args);
if (arglen > PCI_MAX_DATA) {
diff --git a/system/dev/bus/platform/platform-bus.cpp b/system/dev/bus/platform/platform-bus.cpp
index b229e6d..eccbb7b 100644
--- a/system/dev/bus/platform/platform-bus.cpp
+++ b/system/dev/bus/platform/platform-bus.cpp
@@ -36,7 +36,8 @@
return ZX_OK;
}
-zx_status_t PlatformBus::GetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle) {
+zx_status_t PlatformBus::IommuGetBti(uint32_t iommu_index, uint32_t bti_id,
+ zx_handle_t* out_handle) {
if (iommu_index != 0) {
return ZX_ERR_OUT_OF_RANGE;
}
@@ -243,7 +244,7 @@
// return default implementation
auto proto = static_cast<iommu_protocol_t*>(out);
proto->ctx = this;
- proto->ops = &iommu_proto_ops_;
+ proto->ops = &iommu_protocol_ops_;
return ZX_OK;
}
break;
diff --git a/system/dev/bus/platform/platform-bus.h b/system/dev/bus/platform/platform-bus.h
index 3cb3ca1..2ad3bb7 100644
--- a/system/dev/bus/platform/platform-bus.h
+++ b/system/dev/bus/platform/platform-bus.h
@@ -54,7 +54,7 @@
zx_status_t SetBoardInfo(const pbus_board_info_t* info);
// IOMMU protocol implementation.
- zx_status_t GetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle);
+ zx_status_t IommuGetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle);
// Returns the resource handle to be used for creating MMIO regions and IRQs.
// Currently this just returns the root resource, but we may change this to a more
diff --git a/system/dev/bus/platform/platform-device.cpp b/system/dev/bus/platform/platform-device.cpp
index 5cd9dd0..a050f09 100644
--- a/system/dev/bus/platform/platform-device.cpp
+++ b/system/dev/bus/platform/platform-device.cpp
@@ -123,7 +123,7 @@
const pbus_bti_t& bti = dr->bti(index);
- zx_status_t status = bus_->GetBti(bti.iommu_index, bti.bti_id, out_handle);
+ zx_status_t status = bus_->IommuGetBti(bti.iommu_index, bti.bti_id, out_handle);
if (status == ZX_OK) {
*out_handle_count = 1;
diff --git a/system/dev/bus/platform/platform-protocol-device.cpp b/system/dev/bus/platform/platform-protocol-device.cpp
index 6857e4a..dc28512 100644
--- a/system/dev/bus/platform/platform-protocol-device.cpp
+++ b/system/dev/bus/platform/platform-protocol-device.cpp
@@ -140,7 +140,7 @@
const pbus_bti_t& bti = resources_.bti(index);
- return bus_->GetBti(bti.iommu_index, bti.bti_id, out_handle);
+ return bus_->IommuGetBti(bti.iommu_index, bti.bti_id, out_handle);
}
zx_status_t ProtocolDevice::GetDeviceInfo(pdev_device_info_t* out_info) {
diff --git a/system/dev/bus/virtio/backends/backend.h b/system/dev/bus/virtio/backends/backend.h
index 37c02b6..939e105 100644
--- a/system/dev/bus/virtio/backends/backend.h
+++ b/system/dev/bus/virtio/backends/backend.h
@@ -4,6 +4,7 @@
#pragma once
#include <ddk/protocol/pci.h>
+#include <ddk/protocol/pci-lib.h>
#include <fbl/mutex.h>
#include <fbl/unique_ptr.h>
#include <virtio/virtio.h>
diff --git a/system/dev/bus/virtio/backends/pci_modern.cpp b/system/dev/bus/virtio/backends/pci_modern.cpp
index 6b8c932..92415b3 100644
--- a/system/dev/bus/virtio/backends/pci_modern.cpp
+++ b/system/dev/bus/virtio/backends/pci_modern.cpp
@@ -94,9 +94,9 @@
fbl::AutoLock lock(&lock_);
// try to parse capabilities
- for (uint8_t off = pci_get_first_capability(&pci_, kPciCapIdVendor);
+ for (uint8_t off = pci_get_first_capability(&pci_, PCI_CAP_ID_VENDOR);
off != 0;
- off = pci_get_next_capability(&pci_, off, kPciCapIdVendor)) {
+ off = pci_get_next_capability(&pci_, off, PCI_CAP_ID_VENDOR)) {
virtio_pci_cap_t cap;
ReadVirtioCap(&pci_, off, cap);
diff --git a/system/dev/bus/virtio/ethernet.cpp b/system/dev/bus/virtio/ethernet.cpp
index bacf78a..941b017 100644
--- a/system/dev/bus/virtio/ethernet.cpp
+++ b/system/dev/bus/virtio/ethernet.cpp
@@ -96,9 +96,9 @@
eth->Stop();
}
-zx_status_t virtio_net_start(void* ctx, ethmac_ifc_t* ifc, void* cookie) {
+zx_status_t virtio_net_start(void* ctx, const ethmac_ifc_t* ifc) {
virtio::EthernetDevice* eth = static_cast<virtio::EthernetDevice*>(ctx);
- return eth->Start(ifc, cookie);
+ return eth->Start(ifc);
}
zx_status_t virtio_net_queue_tx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
@@ -106,7 +106,8 @@
return eth->QueueTx(options, netbuf);
}
-static zx_status_t virtio_set_param(void* ctx, uint32_t param, int32_t value, void* data) {
+static zx_status_t virtio_set_param(void* ctx, uint32_t param, int32_t value, const void* data,
+ size_t data_size) {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -183,7 +184,7 @@
EthernetDevice::EthernetDevice(zx_device_t* bus_device, zx::bti bti, fbl::unique_ptr<Backend> backend)
: Device(bus_device, fbl::move(bti), fbl::move(backend)), rx_(this), tx_(this), bufs_(nullptr),
- unkicked_(0), ifc_(nullptr), cookie_(nullptr) {
+ unkicked_(0), ifc_({nullptr, nullptr}) {
}
EthernetDevice::~EthernetDevice() {
@@ -296,7 +297,7 @@
}
void EthernetDevice::ReleaseLocked() {
- ifc_ = nullptr;
+ ifc_.ops = nullptr;
ReleaseBuffers(fbl::move(bufs_));
Device::Release();
}
@@ -306,7 +307,7 @@
// Lock to prevent changes to ifc_.
{
fbl::AutoLock lock(&state_lock_);
- if (!ifc_) {
+ if (!ifc_.ops) {
return;
}
// Ring::IrqRingUpdate will call this lambda on each rx buffer filled by
@@ -325,7 +326,7 @@
LTRACE_DO(hexdump8_ex(data, len, 0));
// Pass the data up the stack to the generic Ethernet driver
- ifc_->recv(cookie_, data, len, 0);
+ ethmac_ifc_recv(&ifc_, data, len, 0);
assert((desc->flags & VRING_DESC_F_NEXT) == 0);
LTRACE_DO(virtio_dump_desc(desc));
rx_.FreeDesc(id);
@@ -352,13 +353,13 @@
void EthernetDevice::IrqConfigChange() {
LTRACE_ENTRY;
fbl::AutoLock lock(&state_lock_);
- if (!ifc_) {
+ if (!ifc_.ops) {
return;
}
// Re-read our configuration
CopyDeviceConfig(&config_, sizeof(config_));
- ifc_->status(cookie_, (config_.status & VIRTIO_NET_S_LINK_UP) ? ETH_STATUS_ONLINE : 0);
+ ethmac_ifc_status(&ifc_, (config_.status & VIRTIO_NET_S_LINK_UP) ? ETH_STATUS_ONLINE : 0);
}
zx_status_t EthernetDevice::Query(uint32_t options, ethmac_info_t* info) {
@@ -378,28 +379,27 @@
void EthernetDevice::Stop() {
LTRACE_ENTRY;
fbl::AutoLock lock(&state_lock_);
- ifc_ = nullptr;
+ ifc_.ops = nullptr;
}
-zx_status_t EthernetDevice::Start(ethmac_ifc_t* ifc, void* cookie) {
+zx_status_t EthernetDevice::Start(const ethmac_ifc_t* ifc) {
LTRACE_ENTRY;
if (!ifc) {
return ZX_ERR_INVALID_ARGS;
}
fbl::AutoLock lock(&state_lock_);
- if (!bufs_ || ifc_) {
+ if (!bufs_ || ifc_.ops) {
return ZX_ERR_BAD_STATE;
}
- ifc_ = ifc;
- cookie_ = cookie;
- ifc_->status(cookie_, (config_.status & VIRTIO_NET_S_LINK_UP) ? ETH_STATUS_ONLINE : 0);
+ ifc_ = *ifc;
+ ethmac_ifc_status(&ifc_, (config_.status & VIRTIO_NET_S_LINK_UP) ? ETH_STATUS_ONLINE : 0);
return ZX_OK;
}
zx_status_t EthernetDevice::QueueTx(uint32_t options, ethmac_netbuf_t* netbuf) {
LTRACE_ENTRY;
- void* data = netbuf->data;
- size_t length = netbuf->len;
+ void* data = netbuf->data_buffer;
+ size_t length = netbuf->data_size;
// First, validate the packet
if (!data || length > virtio_hdr_len_ + kVirtioMtu) {
LTRACEF("dropping packet; invalid packet\n");
diff --git a/system/dev/bus/virtio/ethernet.h b/system/dev/bus/virtio/ethernet.h
index 592df49..ae3e2ce 100644
--- a/system/dev/bus/virtio/ethernet.h
+++ b/system/dev/bus/virtio/ethernet.h
@@ -38,7 +38,7 @@
// DDK protocol hooks; see ddk/protocol/ethernet.h
zx_status_t Query(uint32_t options, ethmac_info_t* info) TA_EXCL(state_lock_);
void Stop() TA_EXCL(state_lock_);
- zx_status_t Start(ethmac_ifc_t* ifc, void* cookie) TA_EXCL(state_lock_);
+ zx_status_t Start(const ethmac_ifc_t* ifc) TA_EXCL(state_lock_);
zx_status_t QueueTx(uint32_t options, ethmac_netbuf_t* netbuf) TA_EXCL(state_lock_);
const char* tag() const override { return "virtio-net"; }
@@ -67,8 +67,7 @@
size_t virtio_hdr_len_;
// Ethmac callback interface; see ddk/protocol/ethernet.h
- ethmac_ifc_t* ifc_ TA_GUARDED(state_lock_);
- void* cookie_;
+ ethmac_ifc_t ifc_ TA_GUARDED(state_lock_);
};
} // namespace virtio
diff --git a/system/dev/bus/virtio/gpu.cpp b/system/dev/bus/virtio/gpu.cpp
index a18129e..7fbbdf9 100644
--- a/system/dev/bus/virtio/gpu.cpp
+++ b/system/dev/bus/virtio/gpu.cpp
@@ -43,13 +43,12 @@
zx::pmt pmt;
} imported_image_t;
-void GpuDevice::virtio_gpu_set_display_controller_cb(void* ctx, void* cb_ctx,
- display_controller_cb_t* cb) {
+void GpuDevice::virtio_gpu_set_display_controller_interface(
+ void* ctx, const display_controller_interface_t* intf) {
GpuDevice* gd = static_cast<GpuDevice*>(ctx);
{
fbl::AutoLock al(&gd->flush_lock_);
- gd->dc_cb_ = cb;
- gd->dc_cb_ctx_ = cb_ctx;
+ gd->dc_intf_ = *intf;
}
added_display_args_t args = {};
@@ -60,9 +59,10 @@
.height = gd->pmode_.r.height,
.refresh_rate_e2 = kRefreshRateHz * 100,
},
- args.pixel_formats = &gd->supported_formats_,
+ args.pixel_format_list = &gd->supported_formats_,
args.pixel_format_count = 1,
- cb->on_displays_changed(cb_ctx, &args, 1, nullptr, 0);
+ display_controller_interface_on_displays_changed(intf, &args, 1, nullptr, 0,
+ nullptr, 0, nullptr);
}
zx_status_t GpuDevice::virtio_gpu_import_vmo_image(void* ctx, image_t* image,
@@ -100,7 +100,7 @@
return status;
}
- image->handle = import_data.release();
+ image->handle = reinterpret_cast<uint64_t>(import_data.release());
return ZX_OK;
}
@@ -109,26 +109,26 @@
delete reinterpret_cast<imported_image_t*>(image->handle);
}
-void GpuDevice::virtio_gpu_check_configuration(void* ctx,
- const display_config_t** display_configs,
- uint32_t* display_cfg_result,
- uint32_t** layer_cfg_results,
- uint32_t display_count) {
+uint32_t GpuDevice::virtio_gpu_check_configuration(void* ctx,
+ const display_config_t** display_configs,
+ size_t display_count,
+ uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count) {
GpuDevice* gd = static_cast<GpuDevice*>(ctx);
if (display_count != 1) {
ZX_DEBUG_ASSERT(display_count == 0);
- return;
+ return CONFIG_DISPLAY_OK;
}
ZX_DEBUG_ASSERT(display_configs[0]->display_id == kDisplayId);
bool success;
if (display_configs[0]->layer_count != 1) {
success = display_configs[0]->layer_count == 0;
} else {
- primary_layer_t* layer = &display_configs[0]->layers[0]->cfg.primary;
+ primary_layer_t* layer = &display_configs[0]->layer_list[0]->cfg.primary;
frame_t frame = {
.x_pos = 0, .y_pos = 0, .width = gd->pmode_.r.width, .height = gd->pmode_.r.height,
};
- success = display_configs[0]->layers[0]->type == LAYER_PRIMARY
+ success = display_configs[0]->layer_list[0]->type == LAYER_TYPE_PRIMARY
&& layer->transform_mode == FRAME_TRANSFORM_IDENTITY
&& layer->image.width == gd->pmode_.r.width
&& layer->image.height == gd->pmode_.r.height
@@ -142,14 +142,16 @@
for (unsigned i = 1; i < display_configs[0]->layer_count; i++) {
layer_cfg_results[0][i] = CLIENT_MERGE_SRC;
}
+ layer_cfg_result_count[0] = display_configs[0]->layer_count;
}
+ return CONFIG_DISPLAY_OK;
}
void GpuDevice::virtio_gpu_apply_configuration(void* ctx, const display_config_t** display_configs,
- uint32_t display_count) {
+ size_t display_count) {
GpuDevice* gd = static_cast<GpuDevice*>(ctx);
- void* handle = display_count == 0 || display_configs[0]->layer_count == 0
- ? nullptr : display_configs[0]->layers[0]->cfg.primary.image.handle;
+ uint64_t handle = display_count == 0 || display_configs[0]->layer_count == 0
+ ? 0 : display_configs[0]->layer_list[0]->cfg.primary.image.handle;
{
fbl::AutoLock al(&gd->flush_lock_);
@@ -416,10 +418,10 @@
{
fbl::AutoLock al(&flush_lock_);
- if (dc_cb_) {
- void* handles[] = { static_cast<void*>(displayed_fb_) };
- dc_cb_->on_display_vsync(dc_cb_ctx_, kDisplayId,
- next_deadline, handles, displayed_fb_ != nullptr);
+ if (dc_intf_.ops) {
+ uint64_t handles[] = { reinterpret_cast<uint64_t>(displayed_fb_) };
+ display_controller_interface_on_display_vsync(
+ &dc_intf_, kDisplayId, next_deadline, handles, displayed_fb_ != nullptr);
}
}
next_deadline = zx_time_add_duration(next_deadline, period);
@@ -456,7 +458,8 @@
LTRACEF("publishing device\n");
- display_proto_ops_.set_display_controller_cb = virtio_gpu_set_display_controller_cb;
+ display_proto_ops_.set_display_controller_interface =
+ virtio_gpu_set_display_controller_interface;
display_proto_ops_.import_vmo_image = virtio_gpu_import_vmo_image;
display_proto_ops_.release_image = virtio_gpu_release_image;
display_proto_ops_.check_configuration = virtio_gpu_check_configuration;
diff --git a/system/dev/bus/virtio/gpu.h b/system/dev/bus/virtio/gpu.h
index d8b2953..2dc384e 100644
--- a/system/dev/bus/virtio/gpu.h
+++ b/system/dev/bus/virtio/gpu.h
@@ -9,6 +9,7 @@
#include <ddk/protocol/display-controller.h>
#include <fbl/unique_ptr.h>
+#include <zircon/pixelformat.h>
#include <zircon/compiler.h>
#include "device.h"
@@ -37,17 +38,16 @@
private:
// DDK driver hooks
- static void virtio_gpu_set_display_controller_cb(
- void* ctx, void* cb_ctx, display_controller_cb_t* cb);
+ static void virtio_gpu_set_display_controller_interface(
+ void* ctx, const display_controller_interface_t* intf);
static zx_status_t virtio_gpu_import_vmo_image(
void* ctx, image_t* image, zx_handle_t vmo, size_t offset);
static void virtio_gpu_release_image(void* ctx, image_t* image);
- static void virtio_gpu_check_configuration(
- void* ctx, const display_config_t** display_configs,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count);
+ static uint32_t virtio_gpu_check_configuration(
+ void* ctx, const display_config_t** display_configs, size_t display_count,
+ uint32_t** layer_cfg_results, size_t* layer_cfg_result_count);
static void virtio_gpu_apply_configuration(
- void* ctx, const display_config_t** display_configs, uint32_t display_count);
+ void* ctx, const display_config_t** display_configs, size_t display_count);
static uint32_t virtio_gpu_compute_linear_stride(
void* ctx, uint32_t width, zx_pixel_format_t format);
static zx_status_t virtio_gpu_allocate_vmo(void* ctx, uint64_t size, zx_handle_t* vmo_out);
@@ -93,8 +93,7 @@
cnd_t flush_cond_ = {};
bool flush_pending_ = false;
- display_controller_cb_t* dc_cb_;
- void* dc_cb_ctx_;
+ display_controller_interface_t dc_intf_;
struct imported_image* current_fb_;
struct imported_image* displayed_fb_;
diff --git a/system/dev/bus/virtio/input.cpp b/system/dev/bus/virtio/input.cpp
index 86348ef..432dbf1 100644
--- a/system/dev/bus/virtio/input.cpp
+++ b/system/dev/bus/virtio/input.cpp
@@ -178,7 +178,7 @@
}
zx_status_t InputDevice::virtio_input_set_report(void* ctx, uint8_t rpt_type, uint8_t rpt_id,
- void* data, size_t len) {
+ const void* data, size_t len) {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -198,9 +198,9 @@
return ZX_OK;
}
-zx_status_t InputDevice::virtio_input_start(void* ctx, hidbus_ifc_t* ifc, void* cookie) {
+zx_status_t InputDevice::virtio_input_start(void* ctx, const hidbus_ifc_t* ifc) {
virtio::InputDevice* inp = static_cast<virtio::InputDevice*>(ctx);
- return inp->Start(ifc, cookie);
+ return inp->Start(ifc);
}
void InputDevice::virtio_input_stop(void* ctx) {
@@ -247,10 +247,10 @@
// keyboard.
if (cfg_rel_size > 0 || cfg_abs_size > 0) {
// Pointer
- dev_class_ = HID_DEV_CLASS_POINTER;
+ dev_class_ = HID_DEVICE_CLASS_POINTER;
} else if (cfg_key_size > 0) {
// Keyboard
- dev_class_ = HID_DEV_CLASS_KBD;
+ dev_class_ = HID_DEVICE_CLASS_KBD;
} else {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -315,7 +315,7 @@
hidbus_ops_.get_protocol = virtio_input_get_protocol;
hidbus_ops_.set_protocol = virtio_input_set_protocol;
- hidbus_ifc_ = nullptr;
+ hidbus_ifc_.ops = nullptr;
device_add_args_t args = {};
args.version = DEVICE_ADD_ARGS_VERSION;
@@ -337,26 +337,23 @@
return ZX_OK;
}
-zx_status_t InputDevice::Start(hidbus_ifc_t* ifc, void* cookie) {
+zx_status_t InputDevice::Start(const hidbus_ifc_t* ifc) {
fbl::AutoLock lock(&lock_);
- if (hidbus_ifc_ != nullptr) {
+ if (hidbus_ifc_.ops != nullptr) {
return ZX_ERR_ALREADY_BOUND;
}
- hidbus_ifc_ = ifc;
- hidbus_cookie_ = cookie;
+ hidbus_ifc_ = *ifc;
return ZX_OK;
}
void InputDevice::Stop() {
fbl::AutoLock lock(&lock_);
- hidbus_ifc_ = nullptr;
- hidbus_cookie_ = nullptr;
+ hidbus_ifc_.ops = nullptr;
}
void InputDevice::Release() {
fbl::AutoLock lock(&lock_);
- hidbus_ifc_ = nullptr;
- hidbus_cookie_ = nullptr;
+ hidbus_ifc_.ops = nullptr;
for (size_t i = 0; i < kEventCount; ++i) {
if (io_buffer_is_valid(&buffers_[i])) {
io_buffer_release(&buffers_[i]);
@@ -366,7 +363,7 @@
zx_status_t InputDevice::Query(uint32_t options, hid_info_t* info) {
info->dev_num = dev_class_; // Use type for dev_num for now.
- info->dev_class = dev_class_;
+ info->device_class = dev_class_;
info->boot_device = true;
return ZX_OK;
}
@@ -376,7 +373,7 @@
return ZX_ERR_INVALID_ARGS;
}
- if (desc_type != HID_DESC_TYPE_REPORT) {
+ if (desc_type != HID_DESCRIPTION_TYPE_REPORT) {
return ZX_ERR_NOT_FOUND;
}
const uint8_t* buf = nullptr;
@@ -450,10 +447,10 @@
}
} else if (event->type == VIRTIO_INPUT_EV_SYN) {
fbl::AutoLock lock(&lock_);
- if (hidbus_ifc_) {
- hidbus_ifc_->io_queue(hidbus_cookie_,
- reinterpret_cast<const uint8_t*>(&report_),
- sizeof(report_));
+ if (hidbus_ifc_.ops) {
+ hidbus_ifc_io_queue(&hidbus_ifc_,
+ reinterpret_cast<const uint8_t*>(&report_),
+ sizeof(report_));
}
}
}
diff --git a/system/dev/bus/virtio/input.h b/system/dev/bus/virtio/input.h
index cbca217..bdcf8fe 100644
--- a/system/dev/bus/virtio/input.h
+++ b/system/dev/bus/virtio/input.h
@@ -32,20 +32,20 @@
static void virtio_input_release(void* ctx);
static zx_status_t virtio_input_query(void* ctx, uint32_t options, hid_info_t* info);
- static zx_status_t virtio_input_start(void* ctx, hidbus_ifc_t* ifc, void* cookie);
+ static zx_status_t virtio_input_start(void* ctx, const hidbus_ifc_t* ifc);
static void virtio_input_stop(void* ctx);
static zx_status_t virtio_input_get_descriptor(void* ctx, uint8_t desc_type,
void** data, size_t* len);
static zx_status_t virtio_input_get_report(void* ctx, uint8_t rpt_type, uint8_t rpt_id,
void* data, size_t len, size_t* out_len);
static zx_status_t virtio_input_set_report(void* ctx, uint8_t rpt_type, uint8_t rpt_id,
- void* data, size_t len);
+ const void* data, size_t len);
static zx_status_t virtio_input_get_idle(void* ctx, uint8_t rpt_type, uint8_t* duration);
static zx_status_t virtio_input_set_idle(void* ctx, uint8_t rpt_type, uint8_t duration);
static zx_status_t virtio_input_get_protocol(void* ctx, uint8_t* protocol);
static zx_status_t virtio_input_set_protocol(void* ctx, uint8_t protocol);
- zx_status_t Start(hidbus_ifc_t* ifc, void* cookie);
+ zx_status_t Start(const hidbus_ifc_t* ifc);
void Stop();
zx_status_t Query(uint32_t options, hid_info_t* info);
zx_status_t GetDescriptor(uint8_t desc_type, void** data, size_t* len);
@@ -65,7 +65,7 @@
uint8_t dev_class_;
hidbus_protocol_ops_t hidbus_ops_;
- hidbus_ifc_t* hidbus_ifc_;
+ hidbus_ifc_t hidbus_ifc_;
void* hidbus_cookie_;
boot_kbd_report_t report_;
diff --git a/system/dev/bus/virtio/virtio_driver.cpp b/system/dev/bus/virtio/virtio_driver.cpp
index 20b8f59..a7d7f96 100644
--- a/system/dev/bus/virtio/virtio_driver.cpp
+++ b/system/dev/bus/virtio/virtio_driver.cpp
@@ -16,6 +16,7 @@
#include <fbl/unique_ptr.h>
#include <zircon/compiler.h>
+#include <zircon/pixelformat.h>
#include <zircon/types.h>
#include "backends/pci.h"
@@ -53,7 +54,7 @@
// If no vendor capabilities are found then we will default to the legacy
// interface.
fbl::unique_ptr<virtio::Backend> backend = nullptr;
- if (pci_get_first_capability(&pci, kPciCapIdVendor) != 0) {
+ if (pci_get_first_capability(&pci, PCI_CAP_ID_VENDOR) != 0) {
zxlogf(SPEW, "virtio %02x:%02x.%1x using modern PCI backend\n", info.bus_id, info.dev_id, info.func_id);
backend.reset(new virtio::PciModernBackend(pci, info));
} else {
diff --git a/system/dev/display/aml-canvas/aml-canvas-proxy-client.c b/system/dev/display/aml-canvas/aml-canvas-proxy-client.c
index dea38ad..c6e8a83 100644
--- a/system/dev/display/aml-canvas/aml-canvas-proxy-client.c
+++ b/system/dev/display/aml-canvas/aml-canvas-proxy-client.c
@@ -23,7 +23,7 @@
#include "aml-canvas.h"
static zx_status_t aml_canvas_proxy_config(void* ctx, zx_handle_t vmo,
- size_t offset, canvas_info_t* info,
+ size_t offset, const canvas_info_t* info,
uint8_t* canvas_idx) {
aml_canvas_proxy_t* proxy = ctx;
rpc_canvas_req_t req = {
diff --git a/system/dev/display/aml-canvas/aml-canvas.c b/system/dev/display/aml-canvas/aml-canvas.c
index 4b8cff5..12a4669 100644
--- a/system/dev/display/aml-canvas/aml-canvas.c
+++ b/system/dev/display/aml-canvas/aml-canvas.c
@@ -34,7 +34,7 @@
}
static zx_status_t aml_canvas_config(void* ctx, zx_handle_t vmo,
- size_t offset, canvas_info_t* info,
+ size_t offset, const canvas_info_t* info,
uint8_t* canvas_idx) {
aml_canvas_t* canvas = ctx;
zx_status_t status = ZX_OK;
diff --git a/system/dev/display/astro-display/astro-display.cpp b/system/dev/display/astro-display/astro-display.cpp
index ad36288..eff8dcc 100644
--- a/system/dev/display/astro-display/astro-display.cpp
+++ b/system/dev/display/astro-display/astro-display.cpp
@@ -8,7 +8,7 @@
namespace {
// List of supported pixel formats
-const zx_pixel_format_t kSupportedPixelFormats = { ZX_PIXEL_FORMAT_RGB_x888 };
+zx_pixel_format_t kSupportedPixelFormats[] = { ZX_PIXEL_FORMAT_RGB_x888 };
constexpr uint64_t kDisplayId = PANEL_DISPLAY_ID;
@@ -75,30 +75,32 @@
args->panel.params.height = height_;
args->panel.params.width = width_;
args->panel.params.refresh_rate_e2 = 3000; // Just guess that it's 30fps
- args->pixel_formats = &kSupportedPixelFormats;
- args->pixel_format_count = sizeof(kSupportedPixelFormats) / sizeof(zx_pixel_format_t);
+ args->pixel_format_list = kSupportedPixelFormats;
+ args->pixel_format_count = countof(kSupportedPixelFormats);
args->cursor_info_count = 0;
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-uint32_t AstroDisplay::ComputeLinearStride(uint32_t width, zx_pixel_format_t format) {
+uint32_t AstroDisplay::DisplayControllerComputeLinearStride(uint32_t width,
+ zx_pixel_format_t format) {
// The astro display controller needs buffers with a stride that is an even
// multiple of 32.
return ROUNDUP(width, 32 / ZX_PIXEL_FORMAT_BYTES(format));
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-void AstroDisplay::SetDisplayControllerCb(void* cb_ctx, display_controller_cb_t* cb) {
+void AstroDisplay::DisplayControllerSetDisplayControllerInterface(
+ const display_controller_interface_t* intf) {
fbl::AutoLock lock(&display_lock_);
- dc_cb_ = cb;
- dc_cb_ctx_ = cb_ctx;
+ dc_intf_ = ddk::DisplayControllerInterfaceProxy(intf);
added_display_args_t args;
PopulateAddedDisplayArgs(&args);
- dc_cb_->on_displays_changed(dc_cb_ctx_, &args, 1, NULL, 0);
+ dc_intf_.OnDisplaysChanged(&args, 1, nullptr, 0, nullptr, 0, nullptr);
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-zx_status_t AstroDisplay::ImportVmoImage(image_t* image, const zx::vmo& vmo, size_t offset) {
+zx_status_t AstroDisplay::DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo,
+ size_t offset) {
zx_status_t status = ZX_OK;
fbl::AutoLock lock(&image_lock_);
@@ -107,7 +109,7 @@
return status;
}
- uint32_t stride = ComputeLinearStride(image->width, image->pixel_format);
+ uint32_t stride = DisplayControllerComputeLinearStride(image->width, image->pixel_format);
canvas_info_t canvas_info;
canvas_info.height = image->height;
@@ -117,7 +119,7 @@
canvas_info.endianness = 0;
zx_handle_t dup_vmo;
- status = zx_handle_duplicate(vmo.get(), ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
+ status = zx_handle_duplicate(vmo, ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
if (status != ZX_OK) {
return status;
}
@@ -134,13 +136,13 @@
DISP_INFO("Reusing previously allocated canvas (index = %d)\n", local_canvas_idx);
}
imported_images_.SetOne(local_canvas_idx);
- image->handle = reinterpret_cast<void*>(local_canvas_idx);;
+ image->handle = local_canvas_idx;
return status;
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-void AstroDisplay::ReleaseImage(image_t* image) {
+void AstroDisplay::DisplayControllerReleaseImage(image_t* image) {
fbl::AutoLock lock(&image_lock_);
size_t local_canvas_idx = (size_t)image->handle;
if (imported_images_.GetOne(local_canvas_idx)) {
@@ -150,14 +152,13 @@
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-void AstroDisplay::CheckConfiguration(const display_config_t** display_configs,
- uint32_t* display_cfg_result,
- uint32_t** layer_cfg_results,
- uint32_t display_count) {
- *display_cfg_result = CONFIG_DISPLAY_OK;
+uint32_t AstroDisplay::DisplayControllerCheckConfiguration(
+ const display_config_t** display_configs, size_t display_count, uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count) {
+
if (display_count != 1) {
ZX_DEBUG_ASSERT(display_count == 0);
- return;
+ return CONFIG_DISPLAY_OK;
}
ZX_DEBUG_ASSERT(display_configs[0]->display_id == PANEL_DISPLAY_ID);
@@ -167,11 +168,11 @@
if (display_configs[0]->layer_count != 1) {
success = display_configs[0]->layer_count == 0;
} else {
- const primary_layer_t& layer = display_configs[0]->layers[0]->cfg.primary;
+ const primary_layer_t& layer = display_configs[0]->layer_list[0]->cfg.primary;
frame_t frame = {
.x_pos = 0, .y_pos = 0, .width = width_, .height = height_,
};
- success = display_configs[0]->layers[0]->type == LAYER_PRIMARY
+ success = display_configs[0]->layer_list[0]->type == LAYER_TYPE_PRIMARY
&& layer.transform_mode == FRAME_TRANSFORM_IDENTITY
&& layer.image.width == width_
&& layer.image.height == height_
@@ -185,12 +186,14 @@
for (unsigned i = 1; i < display_configs[0]->layer_count; i++) {
layer_cfg_results[0][i] = CLIENT_MERGE_SRC;
}
+ layer_cfg_result_count[0] = display_configs[0]->layer_count;
}
+ return CONFIG_DISPLAY_OK;
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-void AstroDisplay::ApplyConfiguration(const display_config_t** display_configs,
- uint32_t display_count) {
+void AstroDisplay::DisplayControllerApplyConfiguration( const display_config_t** display_configs,
+ size_t display_count) {
ZX_DEBUG_ASSERT(display_configs);
fbl::AutoLock lock(&display_lock_);
@@ -199,7 +202,7 @@
if (display_count == 1 && display_configs[0]->layer_count) {
// Since Astro does not support plug'n play (fixed display), there is no way
// a checked configuration could be invalid at this point.
- addr = (uint8_t) (uint64_t) display_configs[0]->layers[0]->cfg.primary.image.handle;
+ addr = (uint8_t) (uint64_t) display_configs[0]->layer_list[0]->cfg.primary.image.handle;
current_image_valid_= true;
current_image_ = addr;
osd_->Flip(addr);
@@ -210,7 +213,7 @@
}
// part of ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL ops
-zx_status_t AstroDisplay::AllocateVmo(uint64_t size, zx_handle_t* vmo_out) {
+zx_status_t AstroDisplay::DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* vmo_out) {
return zx_vmo_create_contiguous(bti_.get(), size, 0, vmo_out);
}
@@ -274,7 +277,7 @@
}
format_ = ZX_PIXEL_FORMAT_RGB_x888;
- stride_ = ComputeLinearStride(width_, format_);
+ stride_ = DisplayControllerComputeLinearStride(width_, format_);
if (!skip_disp_init_) {
// Ensure Max Bit Rate / pixel clock ~= 8 (8.xxx). This is because the clock calculation
@@ -363,10 +366,10 @@
imported_images_.Reset(kMaxImportedImages);
}
- if (dc_cb_) {
+ if (dc_intf_.is_valid()) {
added_display_args_t args;
PopulateAddedDisplayArgs(&args);
- dc_cb_->on_displays_changed(dc_cb_ctx_, &args, 1,nullptr, 0);
+ dc_intf_.OnDisplaysChanged(&args, 1, nullptr, 0, nullptr, 0, nullptr);
}
return ZX_OK;
@@ -381,11 +384,11 @@
break;
}
fbl::AutoLock lock(&display_lock_);
- void* live = reinterpret_cast<void*>(current_image_);
+ uint64_t live[] = { current_image_ };
bool current_image_valid = current_image_valid_;
- if (dc_cb_) {
- dc_cb_->on_display_vsync(dc_cb_ctx_, kDisplayId, zx_clock_get(ZX_CLOCK_MONOTONIC),
- &live, current_image_valid);
+ if (dc_intf_.is_valid()) {
+ dc_intf_.OnDisplayVsync(kDisplayId, zx_clock_get(ZX_CLOCK_MONOTONIC),
+ live, current_image_valid);
}
}
diff --git a/system/dev/display/astro-display/astro-display.h b/system/dev/display/astro-display/astro-display.h
index a28b5ea..d846f53 100644
--- a/system/dev/display/astro-display/astro-display.h
+++ b/system/dev/display/astro-display/astro-display.h
@@ -7,6 +7,7 @@
#include <unistd.h>
#include <zircon/compiler.h>
+#include <zircon/pixelformat.h>
#include <zircon/thread_annotations.h>
#include <lib/zx/interrupt.h>
#include <lib/zx/bti.h>
@@ -18,6 +19,7 @@
#include <ddk/debug.h>
#include <ddktl/protocol/display-controller.h>
+#include <ddktl/protocol/empty-protocol.h>
#include <ddktl/device.h>
#include <fbl/unique_ptr.h>
@@ -44,7 +46,8 @@
using DeviceType = ddk::Device<AstroDisplay, ddk::Unbindable>;
class AstroDisplay : public DeviceType,
- public ddk::DisplayControllerProtocol<AstroDisplay> {
+ public ddk::DisplayControllerProtocol<AstroDisplay>,
+ public ddk::EmptyProtocol<ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL> {
public:
AstroDisplay(zx_device_t* parent, uint32_t width, uint32_t height)
: DeviceType(parent), width_(width), height_(height) {}
@@ -53,15 +56,16 @@
zx_status_t Bind();
// Required functions needed to implement Display Controller Protocol
- void SetDisplayControllerCb(void* cb_ctx, display_controller_cb_t* cb);
- zx_status_t ImportVmoImage(image_t* image, const zx::vmo& vmo, size_t offset);
- void ReleaseImage(image_t* image);
- void CheckConfiguration(const display_config_t** display_config,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count);
- void ApplyConfiguration(const display_config_t** display_config, uint32_t display_count);
- uint32_t ComputeLinearStride(uint32_t width, zx_pixel_format_t format);
- zx_status_t AllocateVmo(uint64_t size, zx_handle_t* vmo_out);
+ void DisplayControllerSetDisplayControllerInterface(const display_controller_interface_t* intf);
+ zx_status_t DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset);
+ void DisplayControllerReleaseImage(image_t* image);
+ uint32_t DisplayControllerCheckConfiguration(const display_config_t** display_configs,
+ size_t display_count, uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count);
+ void DisplayControllerApplyConfiguration(const display_config_t** display_config,
+ size_t display_count);
+ uint32_t DisplayControllerComputeLinearStride(uint32_t width, zx_pixel_format_t format);
+ zx_status_t DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* vmo_out);
// Required functions for DeviceType
void DdkUnbind();
@@ -124,11 +128,10 @@
DisplaySetting disp_setting_;
// Display controller related data
- display_controller_cb_t* dc_cb_ TA_GUARDED(display_lock_);
- void* dc_cb_ctx_ TA_GUARDED(display_lock_);
+ ddk::DisplayControllerInterfaceProxy dc_intf_ TA_GUARDED(display_lock_);
// Simple hashtable
- ImportedImageBitmap imported_images_ TA_GUARDED(image_lock_);;
+ ImportedImageBitmap imported_images_ TA_GUARDED(image_lock_);;
// Objects
fbl::unique_ptr<astro_display::Osd> osd_;
diff --git a/system/dev/display/display/client.cpp b/system/dev/display/display/client.cpp
index f9a2e77..c95a5c9 100644
--- a/system/dev/display/display/client.cpp
+++ b/system/dev/display/display/client.cpp
@@ -10,11 +10,11 @@
#include <lib/fidl/cpp/message.h>
#include <lib/async/cpp/task.h>
#include <math.h>
+#include <zircon/pixelformat.h>
#include <zircon/device/display-controller.h>
#include "client.h"
-#define DC_IMPL_CALL(fn, ...) controller_->ops()->fn(controller_->ops_ctx(), __VA_ARGS__)
#define SELECT_TABLE_CASE(NAME) case NAME ## Ordinal: table = &NAME ## RequestTable; break
#define HANDLE_REQUEST_CASE(NAME) \
case fuchsia_display_Controller ## NAME ## Ordinal: { \
@@ -211,13 +211,13 @@
dc_image.planes[i].bytes_per_row = req->image_config.planes[i].bytes_per_row;
}
- resp->res = DC_IMPL_CALL(import_vmo_image, &dc_image, vmo.get(), req->offset);
+ resp->res = controller_->dc()->ImportVmoImage(&dc_image, vmo.get(), req->offset);
if (resp->res == ZX_OK) {
fbl::AllocChecker ac;
auto image = fbl::AdoptRef(new (&ac) Image(controller_, dc_image, fbl::move(vmo)));
if (!ac.check()) {
- DC_IMPL_CALL(release_image, &dc_image);
+ controller_->dc()->ReleaseImage(&dc_image);
resp->res = ZX_ERR_NO_MEMORY;
return;
@@ -434,7 +434,7 @@
return;
}
- layer->pending_layer_.type = LAYER_PRIMARY;
+ layer->pending_layer_.type = LAYER_TYPE_PRIMARY;
primary_layer_t* primary_layer = &layer->pending_layer_.cfg.primary;
populate_image(req->image_config, &primary_layer->image);
@@ -459,7 +459,7 @@
const fuchsia_display_ControllerSetLayerPrimaryPositionRequest* req,
fidl::Builder* resp_builder, const fidl_type_t** resp_table) {
auto layer = layers_.find(req->layer_id);
- if (!layer.IsValid() || layer->pending_layer_.type != LAYER_PRIMARY) {
+ if (!layer.IsValid() || layer->pending_layer_.type != LAYER_TYPE_PRIMARY) {
zxlogf(ERROR, "SetLayerPrimaryPosition on invalid layer\n");
TearDown();
return;
@@ -493,7 +493,7 @@
const fuchsia_display_ControllerSetLayerPrimaryAlphaRequest* req,
fidl::Builder* resp_builder, const fidl_type_t** resp_table) {
auto layer = layers_.find(req->layer_id);
- if (!layer.IsValid() || layer->pending_layer_.type != LAYER_PRIMARY) {
+ if (!layer.IsValid() || layer->pending_layer_.type != LAYER_TYPE_PRIMARY) {
zxlogf(ERROR, "SetLayerPrimaryAlpha on invalid layer\n");
TearDown();
return;
@@ -529,7 +529,7 @@
return;
}
- layer->pending_layer_.type = LAYER_CURSOR;
+ layer->pending_layer_.type = LAYER_TYPE_CURSOR;
layer->pending_cursor_x_ = layer->pending_cursor_y_ = 0;
@@ -546,7 +546,7 @@
const fuchsia_display_ControllerSetLayerCursorPositionRequest* req,
fidl::Builder* resp_builder, const fidl_type_t** resp_table) {
auto layer = layers_.find(req->layer_id);
- if (!layer.IsValid() || layer->pending_layer_.type != LAYER_CURSOR) {
+ if (!layer.IsValid() || layer->pending_layer_.type != LAYER_TYPE_CURSOR) {
zxlogf(ERROR, "SetLayerCursorPosition on invalid layer\n");
TearDown();
return;
@@ -575,7 +575,7 @@
// Increase the size of the static array when large color formats are introduced
ZX_ASSERT(req->color_bytes.count <= sizeof(layer->pending_color_bytes_));
- layer->pending_layer_.type = LAYER_COLOR;
+ layer->pending_layer_.type = LAYER_TYPE_COLOR;
color_layer_t* color_layer = &layer->pending_layer_.cfg.color;
color_layer->format = req->pixel_format;
@@ -589,7 +589,7 @@
void Client::HandleSetLayerImage(const fuchsia_display_ControllerSetLayerImageRequest* req,
fidl::Builder* resp_builder, const fidl_type_t** resp_table) {
auto layer = layers_.find(req->layer_id);
- if (!layer.IsValid() || layer->pending_layer_.type == LAYER_COLOR) {
+ if (!layer.IsValid() || layer->pending_layer_.type == LAYER_TYPE_COLOR) {
zxlogf(ERROR, "SetLayerImage ordinal with invalid layer\n");
TearDown();
return;
@@ -601,9 +601,9 @@
return;
}
// Only primary or cursor layers can have images
- ZX_ASSERT(layer->pending_layer_.type == LAYER_PRIMARY
- || layer->pending_layer_.type == LAYER_CURSOR);
- image_t* cur_image = layer->pending_layer_.type == LAYER_PRIMARY ?
+ ZX_ASSERT(layer->pending_layer_.type == LAYER_TYPE_PRIMARY
+ || layer->pending_layer_.type == LAYER_TYPE_CURSOR);
+ image_t* cur_image = layer->pending_layer_.type == LAYER_TYPE_PRIMARY ?
&layer->pending_layer_.cfg.primary.image : &layer->pending_layer_.cfg.cursor.image;
if (!image->HasSameConfig(*cur_image)) {
zxlogf(ERROR, "SetLayerImage with mismatch layer config\n");
@@ -769,9 +769,9 @@
layer->config_change_ = false;
image_t* new_image_config = nullptr;
- if (layer->current_layer_.type == LAYER_PRIMARY) {
+ if (layer->current_layer_.type == LAYER_TYPE_PRIMARY) {
new_image_config = &layer->current_layer_.cfg.primary.image;
- } else if (layer->current_layer_.type == LAYER_CURSOR) {
+ } else if (layer->current_layer_.type == LAYER_TYPE_CURSOR) {
new_image_config = &layer->current_layer_.cfg.cursor.image;
layer->current_cursor_x_ = layer->pending_cursor_x_;
@@ -786,10 +786,11 @@
fbl::clamp(layer->current_cursor_y_,
-static_cast<int32_t>(new_image_config->height) + 1,
static_cast<int32_t>(mode->v_addressable) - 1);
- } else if (layer->current_layer_.type == LAYER_COLOR) {
+ } else if (layer->current_layer_.type == LAYER_TYPE_COLOR) {
memcpy(layer->current_color_bytes_, layer->pending_color_bytes_,
sizeof(layer->current_color_bytes_));
- layer->current_layer_.cfg.color.color = layer->current_color_bytes_;
+ layer->current_layer_.cfg.color.color_list = layer->current_color_bytes_;
+ layer->current_layer_.cfg.color.color_count = 4;
} else {
// type is validated in ::CheckConfig, so something must be very wrong.
ZX_ASSERT(false);
@@ -829,7 +830,7 @@
fidl::Builder* resp_builder, const fidl_type_t** resp_table) {
auto resp = resp_builder->New<fuchsia_display_ControllerComputeLinearImageStrideResponse>();
*resp_table = &fuchsia_display_ControllerComputeLinearImageStrideResponseTable;
- resp->stride = DC_IMPL_CALL(compute_linear_stride, req->width, req->pixel_format);
+ resp->stride = controller_->dc()->ComputeLinearStride(req->width, req->pixel_format);
}
void Client::HandleAllocateVmo(const fuchsia_display_ControllerAllocateVmoRequest* req,
@@ -839,7 +840,7 @@
auto resp = resp_builder->New<fuchsia_display_ControllerAllocateVmoResponse>();
*resp_table = &fuchsia_display_ControllerAllocateVmoResponseTable;
- resp->res = DC_IMPL_CALL(allocate_vmo, req->size, handle_out);
+ resp->res = controller_->dc()->AllocateVmo(req->size, handle_out);
*has_handle_out = resp->res == ZX_OK;
resp->vmo = *has_handle_out ? FIDL_HANDLE_PRESENT : FIDL_HANDLE_ABSENT;
}
@@ -874,7 +875,7 @@
display_layer_cfg_results[config_idx++] = layer_cfg_results + layer_idx;
// Create this display's compact layer_t* array
- display_config.pending_.layers = layers + layer_idx;
+ display_config.pending_.layer_list = layers + layer_idx;
// Frame used for checking that each layer's dest_frame lies entirely
// within the composed output.
@@ -891,7 +892,7 @@
layers[layer_idx++] = &layer_node.layer->pending_layer_;
bool invalid = false;
- if (layer_node.layer->pending_layer_.type == LAYER_PRIMARY) {
+ if (layer_node.layer->pending_layer_.type == LAYER_TYPE_PRIMARY) {
primary_layer_t* layer = &layer_node.layer->pending_layer_.cfg.primary;
// Frame for checking that the layer's src_frame lies entirely
// within the source image.
@@ -901,13 +902,14 @@
};
invalid = (!frame_contains(image_frame, layer->src_frame)
|| !frame_contains(display_frame, layer->dest_frame));
- } else if (layer_node.layer->pending_layer_.type == LAYER_CURSOR) {
+ } else if (layer_node.layer->pending_layer_.type == LAYER_TYPE_CURSOR) {
// The image is already set, so nothing to do here, and there's
// nothing that could make this invald.
- } else if (layer_node.layer->pending_layer_.type == LAYER_COLOR) {
+ } else if (layer_node.layer->pending_layer_.type == LAYER_TYPE_COLOR) {
// There aren't any API constraints on valid colors.
- layer_node.layer->pending_layer_.cfg.color.color =
+ layer_node.layer->pending_layer_.cfg.color.color_list =
layer_node.layer->pending_color_bytes_;
+ layer_node.layer->pending_layer_.cfg.color.color_count = 4;
} else {
invalid = true;
}
@@ -928,9 +930,10 @@
return false;
}
- uint32_t display_cfg_result = CONFIG_DISPLAY_OK;
- DC_IMPL_CALL(check_configuration, configs, &display_cfg_result,
- display_layer_cfg_results, config_idx);
+ size_t layer_cfg_results_count;
+ uint32_t display_cfg_result =
+ controller_->dc()->CheckConfiguration(configs, config_idx, display_layer_cfg_results,
+ &layer_cfg_results_count);
if (display_cfg_result != CONFIG_DISPLAY_OK) {
if (resp) {
@@ -1020,7 +1023,7 @@
int layer_idx = 0;
for (auto& display_config : configs_) {
display_config.current_.layer_count = 0;
- display_config.current_.layers = layers + layer_idx;
+ display_config.current_.layer_list = layers + layer_idx;
display_config.vsync_layer_count_ = 0;
// Displays with no current layers are filtered out in Controller::ApplyConfig,
@@ -1049,10 +1052,10 @@
layer->displayed_image_ = fbl::move(node->self);
list_remove_head(&layer->waiting_images_);
- void* handle = layer->displayed_image_->info().handle;
- if (layer->current_layer_.type == LAYER_PRIMARY) {
+ uint64_t handle = layer->displayed_image_->info().handle;
+ if (layer->current_layer_.type == LAYER_TYPE_PRIMARY) {
layer->current_layer_.cfg.primary.image.handle = handle;
- } else if (layer->current_layer_.type == LAYER_CURSOR) {
+ } else if (layer->current_layer_.type == LAYER_TYPE_CURSOR) {
layer->current_layer_.cfg.cursor.image.handle = handle;
} else {
// type is validated in ::CheckConfig, so something must be very wrong.
@@ -1069,8 +1072,8 @@
console_fb_display_id_ = display_config.id;
auto fb = layer->displayed_image_;
- uint32_t stride = DC_IMPL_CALL(compute_linear_stride,
- fb->info().width, fb->info().pixel_format);
+ uint32_t stride = controller_->dc()->ComputeLinearStride(
+ fb->info().width, fb->info().pixel_format);
uint32_t size = fb->info().height *
ZX_PIXEL_FORMAT_BYTES(fb->info().pixel_format) * stride;
zx_framebuffer_set_range(get_root_resource(),
@@ -1087,7 +1090,7 @@
display_config.current_.layer_count++;
layers[layer_idx++] = &layer->current_layer_;
- if (layer->current_layer_.type != LAYER_COLOR) {
+ if (layer->current_layer_.type != LAYER_TYPE_COLOR) {
display_config.vsync_layer_count_++;
if (layer->displayed_image_ == nullptr) {
config_missing_image = true;
@@ -1123,8 +1126,8 @@
ApplyConfig();
}
-void Client::OnDisplaysChanged(const uint64_t* displays_added, uint32_t added_count,
- const uint64_t* displays_removed, uint32_t removed_count) {
+void Client::OnDisplaysChanged(const uint64_t* displays_added, size_t added_count,
+ const uint64_t* displays_removed, size_t removed_count) {
ZX_DEBUG_ASSERT(controller_->current_thread_is_loop());
ZX_DEBUG_ASSERT(mtx_trylock(controller_->mtx()) == thrd_busy);
@@ -1177,7 +1180,7 @@
req->added.count++;
config->current_.display_id = config->id;
- config->current_.layers = nullptr;
+ config->current_.layer_list = nullptr;
config->current_.layer_count = 0;
if (edid_timings) {
@@ -1443,8 +1446,8 @@
}
void ClientProxy::OnDisplaysChanged(const uint64_t* displays_added,
- uint32_t added_count, const uint64_t* displays_removed,
- uint32_t removed_count) {
+ size_t added_count, const uint64_t* displays_removed,
+ size_t removed_count) {
handler_.OnDisplaysChanged(displays_added, added_count, displays_removed, removed_count);
}
@@ -1469,7 +1472,7 @@
}
void ClientProxy::OnDisplayVsync(uint64_t display_id, zx_time_t timestamp,
- uint64_t* image_ids, uint32_t count) {
+ uint64_t* image_ids, size_t count) {
ZX_DEBUG_ASSERT(mtx_trylock(controller_->mtx()) == thrd_busy);
if (!enable_vsync_) {
diff --git a/system/dev/display/display/client.h b/system/dev/display/display/client.h
index 5a05ba6..42a6d4b 100644
--- a/system/dev/display/display/client.h
+++ b/system/dev/display/display/client.h
@@ -130,9 +130,9 @@
zx_status_t Init(zx_handle_t server_handle);
void OnDisplaysChanged(const uint64_t* displays_added,
- uint32_t added_count,
+ size_t added_count,
const uint64_t* displays_removed,
- uint32_t removed_count);
+ size_t removed_count);
void SetOwnership(bool is_owner);
void ApplyConfig();
@@ -255,9 +255,9 @@
// Requires holding controller_->mtx() lock
void OnDisplayVsync(uint64_t display_id, zx_time_t timestamp,
- uint64_t* image_ids, uint32_t count);
- void OnDisplaysChanged(const uint64_t* displays_added, uint32_t added_count,
- const uint64_t* displays_removed, uint32_t removed_count);
+ uint64_t* image_ids, size_t count);
+ void OnDisplaysChanged(const uint64_t* displays_added, size_t added_count,
+ const uint64_t* displays_removed, size_t removed_count);
void SetOwnership(bool is_owner);
void ReapplyConfig();
diff --git a/system/dev/display/display/controller.cpp b/system/dev/display/display/controller.cpp
index d74059c..ef550cc 100644
--- a/system/dev/display/display/controller.cpp
+++ b/system/dev/display/display/controller.cpp
@@ -14,29 +14,6 @@
namespace {
-void on_displays_changed(void* ctx, added_display_args_t* displays_added, uint32_t added_count,
- uint64_t* displays_removed, uint32_t removed_count) {
- static_cast<display::Controller*>(ctx)->OnDisplaysChanged(
- displays_added, added_count, displays_removed, removed_count);
-}
-
-void on_display_vsync(void* ctx, uint64_t display, zx_time_t timestamp,
- void** handles, uint32_t handle_count) {
- static_cast<display::Controller*>(ctx)->OnDisplayVsync(display, timestamp,
- handles, handle_count);
-}
-
-zx_status_t get_audio_format(void* ctx, uint64_t display_id, uint32_t fmt_idx,
- audio_stream_format_range_t* fmt_out) {
- return static_cast<display::Controller*>(ctx)->GetAudioFormat(display_id, fmt_idx, fmt_out);
-}
-
-display_controller_cb_t dc_cb = {
- .on_displays_changed = on_displays_changed,
- .on_display_vsync = on_display_vsync,
- .get_audio_format = get_audio_format,
-};
-
typedef struct i2c_bus {
i2c_impl_protocol_t* i2c;
uint32_t bus_id;
@@ -89,14 +66,12 @@
// Go through all the display mode timings and record whether or not
// a basic layer configuration is acceptable.
layer_t test_layer = {};
- layer_t* test_layers[] = { &test_layer };
- test_layer.cfg.primary.image.pixel_format = info->pixel_formats_[0];
-
+ layer_t* test_layers[] = { &test_layer }; test_layer.cfg.primary.image.pixel_format = info->pixel_formats_[0];
display_config_t test_config;
const display_config_t* test_configs[] = { &test_config };
test_config.display_id = info->id;
test_config.layer_count = 1;
- test_config.layers = test_layers;
+ test_config.layer_list = test_layers;
for (auto timing = edid::timing_iterator(&info->edid); timing.is_valid(); ++timing) {
uint32_t width = timing->horizontal_addressable;
@@ -121,9 +96,10 @@
uint32_t display_cfg_result;
uint32_t layer_result = 0;
+ size_t display_layer_results_count;
uint32_t* display_layer_results[] = { &layer_result };
- ops_.ops->check_configuration(ops_.ctx, test_configs, &display_cfg_result,
- display_layer_results, 1);
+ display_cfg_result = dc_.CheckConfiguration(test_configs, 1, display_layer_results,
+ &display_layer_results_count);
if (display_cfg_result == CONFIG_DISPLAY_OK) {
fbl::AllocChecker ac;
info->edid_timings.push_back(*timing, &ac);
@@ -237,8 +213,14 @@
}
}
-void Controller::OnDisplaysChanged(added_display_args_t* displays_added, uint32_t added_count,
- uint64_t* displays_removed, uint32_t removed_count) {
+void Controller::DisplayControllerInterfaceOnDisplaysChanged(
+ const added_display_args_t* displays_added, size_t added_count,
+ const uint64_t* displays_removed, size_t removed_count,
+ added_display_info_t* out_display_info_list, size_t display_info_count,
+ size_t* display_info_actual) {
+
+ ZX_DEBUG_ASSERT(!out_display_info_list || added_count == display_info_count);
+
fbl::unique_ptr<fbl::RefPtr<DisplayInfo>[]> added_success;
fbl::unique_ptr<uint64_t[]> removed;
fbl::unique_ptr<async::Task> task;
@@ -294,6 +276,7 @@
info->vsync_layer_count = 0;
auto& display_params = displays_added[i];
+ auto* display_info = out_display_info_list ? &out_display_info_list[i] : nullptr;
info->id = display_params.display_id;
@@ -307,9 +290,9 @@
zxlogf(INFO, "Out of memory when processing display hotplug\n");
break;
}
- memcpy(info->pixel_formats_.get(), display_params.pixel_formats,
+ memcpy(info->pixel_formats_.get(), display_params.pixel_format_list,
display_params.pixel_format_count * sizeof(zx_pixel_format_t));
- memcpy(info->cursor_infos_.get(), display_params.cursor_infos,
+ memcpy(info->cursor_infos_.get(), display_params.cursor_info_list,
display_params.cursor_info_count * sizeof(cursor_info_t));
info->has_edid = display_params.edid_present;
@@ -353,18 +336,19 @@
}
}
- display_params.is_hdmi_out = info->edid.is_hdmi();
- display_params.is_standard_srgb_out = info->edid.is_standard_rgb();
- display_params.audio_format_count = static_cast<uint32_t>(info->edid_audio_.size());
+ if (display_info) {
+ display_info->is_hdmi_out = info->edid.is_hdmi();
+ display_info->is_standard_srgb_out = info->edid.is_standard_rgb();
+ display_info->audio_format_count = static_cast<uint32_t>(info->edid_audio_.size());
- static_assert(sizeof(display_params.monitor_name) ==
- sizeof(edid::Descriptor::Monitor::data) + 1, "Possible overflow");
- static_assert(sizeof(display_params.monitor_name) ==
- sizeof(edid::Descriptor::Monitor::data) + 1, "Possible overflow");
- strcpy(display_params.monitor_name, info->edid.monitor_name());
- strcpy(display_params.monitor_serial, info->edid.monitor_serial());
- display_params.manufacturer_name = info->edid.manufacturer_name();
-
+ static_assert(sizeof(display_info->monitor_name) ==
+ sizeof(edid::Descriptor::Monitor::data) + 1, "Possible overflow");
+ static_assert(sizeof(display_info->monitor_name) ==
+ sizeof(edid::Descriptor::Monitor::data) + 1, "Possible overflow");
+ strcpy(display_info->monitor_name, info->edid.monitor_name());
+ strcpy(display_info->monitor_serial, info->edid.monitor_serial());
+ display_info->manufacturer_name = info->edid.manufacturer_name();
+ }
if (zxlog_level_enabled_etc(DDK_LOG_TRACE)) {
zxlogf(TRACE, "Manufacturer \"%s\", product %d, name \"%s\", serial \"%s\"\n",
info->edid.manufacturer_name(), info->edid.product_code(),
@@ -381,6 +365,8 @@
zxlogf(INFO, "Ignoring duplicate display\n");
}
}
+ if (display_info_actual)
+ *display_info_actual = added_success_count;
task->set_handler([this,
added_ptr = added_success.release(), removed_ptr = removed.release(),
@@ -426,8 +412,9 @@
task.release()->Post(loop_.dispatcher());
}
-void Controller::OnDisplayVsync(uint64_t display_id, zx_time_t timestamp,
- void** handles, uint32_t handle_count) {
+void Controller::DisplayControllerInterfaceOnDisplayVsync(uint64_t display_id, zx_time_t timestamp,
+ const uint64_t* handles,
+ size_t handle_count) {
fbl::AutoLock lock(&mtx_);
DisplayInfo* info = nullptr;
for (auto& display_config : displays_) {
@@ -459,7 +446,7 @@
// Otherwise the change is done when the last handle_count==info->layer_count
// images match the handles in the correct order.
auto node = list_peek_tail_type(&info->images, image_node_t, link);
- int32_t handle_idx = handle_count - 1;
+ ssize_t handle_idx = handle_count - 1;
while (handle_idx >= 0 && node != nullptr) {
if (handles[handle_idx] != node->self->info().handle) {
break;
@@ -541,8 +528,8 @@
}
}
-zx_status_t Controller::GetAudioFormat(uint64_t display_id, uint32_t fmt_idx,
- audio_stream_format_range_t* fmt_out) {
+zx_status_t Controller::DisplayControllerInterfaceGetAudioFormat(
+ uint64_t display_id, uint32_t fmt_idx, audio_stream_format_range_t* fmt_out) {
fbl::AutoLock lock(&mtx_);
auto display = displays_.find(display_id);
if (!display.IsValid()) {
@@ -650,11 +637,11 @@
applied_stamp_ = client_stamp;
}
- ops_.ops->apply_configuration(ops_.ctx, display_configs, display_count);
+ dc_.ApplyConfiguration(display_configs, display_count);
}
void Controller::ReleaseImage(Image* image) {
- ops_.ops->release_image(ops_.ctx, &image->info());
+ dc_.ReleaseImage(&image->info());
}
void Controller::SetVcMode(uint8_t vc_mode) {
@@ -816,10 +803,12 @@
zx_status_t Controller::Bind(fbl::unique_ptr<display::Controller>* device_ptr) {
zx_status_t status;
- if (device_get_protocol(parent_, ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL, &ops_)) {
+ display_controller_protocol_t dc_proto;
+ if (device_get_protocol(parent_, ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL, &dc_proto)) {
ZX_DEBUG_ASSERT_MSG(false, "Display controller bind mismatch");
return ZX_ERR_NOT_SUPPORTED;
}
+ dc_ = ddk::DisplayControllerProtocolProxy(&dc_proto);
if (device_get_protocol(parent_, ZX_PROTOCOL_I2C_IMPL, &i2c_ops_) == ZX_OK) {
has_i2c_ops_ = true;
@@ -839,7 +828,8 @@
}
__UNUSED auto ptr = device_ptr->release();
- ops_.ops->set_display_controller_cb(ops_.ctx, this, &dc_cb);
+ display_controller_interface_t intf = {&display_controller_interface_ops_, this};
+ dc_.SetDisplayControllerInterface(&intf);
return ZX_OK;
}
diff --git a/system/dev/display/display/controller.h b/system/dev/display/display/controller.h
index 04b38c5..78d3bb3 100644
--- a/system/dev/display/display/controller.h
+++ b/system/dev/display/display/controller.h
@@ -7,6 +7,7 @@
#if __cplusplus
#include <ddktl/device.h>
+#include <ddktl/protocol/display-controller.h>
#include <ddktl/protocol/empty-protocol.h>
#include <ddk/protocol/display-controller.h>
#include <ddk/protocol/i2c-impl.h>
@@ -67,6 +68,7 @@
using ControllerParent = ddk::Device<Controller, ddk::Unbindable, ddk::Openable, ddk::OpenAtable>;
class Controller : public ControllerParent,
+ public ddk::DisplayControllerInterface<Controller>,
public ddk::EmptyProtocol<ZX_PROTOCOL_DISPLAY_CONTROLLER> {
public:
Controller(zx_device_t* parent);
@@ -79,12 +81,18 @@
void DdkRelease();
zx_status_t Bind(fbl::unique_ptr<display::Controller>* device_ptr);
- void OnDisplaysChanged(added_display_args_t* displays_added, uint32_t added_count,
- uint64_t* displays_removed, uint32_t removed_count);
- void OnDisplayVsync(uint64_t display_id, zx_time_t timestamp,
- void** handles, uint32_t handle_count);
- zx_status_t GetAudioFormat(uint64_t display_id, uint32_t fmt_idx,
- audio_stream_format_range_t* fmt_out);
+ void DisplayControllerInterfaceOnDisplaysChanged(const added_display_args_t* displays_added,
+ size_t added_count,
+ const uint64_t* displays_removed,
+ size_t removed_count,
+ added_display_info_t* out_display_info_list,
+ size_t display_info_count,
+ size_t* display_info_actual);
+ void DisplayControllerInterfaceOnDisplayVsync(uint64_t display_id, zx_time_t timestamp,
+ const uint64_t* handles, size_t handle_count);
+ zx_status_t DisplayControllerInterfaceGetAudioFormat(uint64_t display_id, uint32_t fmt_idx,
+ audio_stream_format_range_t* fmt_out);
+
void OnClientDead(ClientProxy* client);
void SetVcMode(uint8_t mode);
void ShowActiveDisplay();
@@ -105,8 +113,7 @@
bool GetCursorInfo(uint64_t display_id, fbl::Array<cursor_info_t>* cursor_info_out)
__TA_NO_THREAD_SAFETY_ANALYSIS;
- display_controller_protocol_ops_t* ops() { return ops_.ops; }
- void* ops_ctx() { return ops_.ctx; }
+ ddk::DisplayControllerProtocolProxy* dc() { return &dc_; }
async::Loop& loop() { return loop_; }
bool current_thread_is_loop() { return thrd_current() == loop_thread_; }
mtx_t* mtx() { return &mtx_; }
@@ -131,7 +138,7 @@
async::Loop loop_;
thrd_t loop_thread_;
- display_controller_protocol_t ops_;
+ ddk::DisplayControllerProtocolProxy dc_;
i2c_impl_protocol_t i2c_ops_;
bool has_i2c_ops_;
};
diff --git a/system/dev/display/imx8m-display/imx8m-display.c b/system/dev/display/imx8m-display/imx8m-display.c
index e1b69e1..3222dbe 100644
--- a/system/dev/display/imx8m-display/imx8m-display.c
+++ b/system/dev/display/imx8m-display/imx8m-display.c
@@ -18,13 +18,14 @@
#include <string.h>
#include <unistd.h>
#include <zircon/assert.h>
+#include <zircon/pixelformat.h>
#include <zircon/syscalls.h>
#define PANEL_DISPLAY_ID 1
#define DISPLAY_WIDTH 1920
#define DISPLAY_HEIGHT 1080
#define DISPLAY_FORMAT ZX_PIXEL_FORMAT_RGB_x888
-static const zx_pixel_format_t supported_pixel_formats = { DISPLAY_FORMAT };
+static zx_pixel_format_t supported_pixel_formats[] = { DISPLAY_FORMAT };
typedef struct image_info {
zx_handle_t pmt;
@@ -44,24 +45,25 @@
args->panel.params.height = DISPLAY_HEIGHT;
args->panel.params.width = DISPLAY_WIDTH;
args->panel.params.refresh_rate_e2 = 3000; // Just guess that it's 30fps
- args->pixel_formats = &supported_pixel_formats;
- args->pixel_format_count = sizeof(supported_pixel_formats) / sizeof(zx_pixel_format_t);
+ args->pixel_format_list = supported_pixel_formats;
+ args->pixel_format_count = countof(supported_pixel_formats);
args->cursor_info_count = 0;
}
-static void imx8m_set_display_controller_cb(void* ctx, void* cb_ctx, display_controller_cb_t* cb) {
+static void imx8m_set_display_controller_interface(void* ctx,
+ const display_controller_interface_t* intf) {
imx8m_display_t* display = ctx;
mtx_lock(&display->display_lock);
bool notify_display = io_buffer_is_valid(&display->fbuffer);
- display->dc_cb = cb;
- display->dc_cb_ctx = cb_ctx;
+ display->dc_intf = *intf;
added_display_args_t args;
populate_added_display_args(display, &args);
if (notify_display) {
- display->dc_cb->on_displays_changed(display->dc_cb_ctx, &args, 1, NULL, 0);
+ display_controller_interface_on_displays_changed(&display->dc_intf, &args, 1, NULL, 0,
+ NULL, 0, NULL);
}
mtx_unlock(&display->display_lock);
}
@@ -96,7 +98,7 @@
import_info->paddr = paddr[0];
list_add_head(&display->imported_images, &import_info->node);
- image->handle = (void*) paddr[0];
+ image->handle = paddr[0];
mtx_unlock(&display->image_lock);
@@ -117,7 +119,7 @@
image_info_t* info;
list_for_every_entry(&display->imported_images, info, image_info_t, node) {
- if ((void*) info->paddr == image->handle) {
+ if (info->paddr == image->handle) {
list_delete(&info->node);
break;
}
@@ -131,15 +133,14 @@
}
}
-static void imx8m_check_configuration(void* ctx,
- const display_config_t** display_configs,
- uint32_t* display_cfg_result,
- uint32_t** layer_cfg_results,
- uint32_t display_count) {
- *display_cfg_result = CONFIG_DISPLAY_OK;
+static uint32_t imx8m_check_configuration(void* ctx,
+ const display_config_t** display_configs,
+ size_t display_count,
+ uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count) {
if (display_count != 1) {
ZX_DEBUG_ASSERT(display_count == 0);
- return;
+ return CONFIG_DISPLAY_OK;
}
ZX_DEBUG_ASSERT(display_configs[0]->display_id == PANEL_DISPLAY_ID);
@@ -150,11 +151,11 @@
if (display_configs[0]->layer_count != 1) {
success = display_configs[0]->layer_count == 0;
} else {
- primary_layer_t* layer = &display_configs[0]->layers[0]->cfg.primary;
+ primary_layer_t* layer = &display_configs[0]->layer_list[0]->cfg.primary;
frame_t frame = {
.x_pos = 0, .y_pos = 0, .width = DISPLAY_WIDTH, .height = DISPLAY_HEIGHT,
};
- success = display_configs[0]->layers[0]->type == LAYER_PRIMARY
+ success = display_configs[0]->layer_list[0]->type == LAYER_TYPE_PRIMARY
&& layer->transform_mode == FRAME_TRANSFORM_IDENTITY
&& layer->image.width == DISPLAY_WIDTH
&& layer->image.height == DISPLAY_HEIGHT
@@ -168,18 +169,20 @@
for (unsigned i = 1; i < display_configs[0]->layer_count; i++) {
layer_cfg_results[0][i] = CLIENT_MERGE_SRC;
}
+ layer_cfg_result_count[0] = display_configs[0]->layer_count;
}
mtx_unlock(&display->display_lock);
+ return CONFIG_DISPLAY_OK;
}
static void imx8m_apply_configuration(void* ctx, const display_config_t** display_configs,
- uint32_t display_count) {
+ size_t display_count) {
imx8m_display_t* display = ctx;
mtx_lock(&display->display_lock);
zx_paddr_t addr;
if (display_count == 1 && display_configs[0]->layer_count) {
- addr = (zx_paddr_t) display_configs[0]->layers[0]->cfg.primary.image.handle;
+ addr = (zx_paddr_t) display_configs[0]->layer_list[0]->cfg.primary.image.handle;
} else {
addr = 0;
}
@@ -195,7 +198,7 @@
}
static display_controller_protocol_ops_t display_controller_ops = {
- .set_display_controller_cb = imx8m_set_display_controller_cb,
+ .set_display_controller_interface = imx8m_set_display_controller_interface,
.import_vmo_image = imx8m_import_vmo_image,
.release_image = imx8m_release_image,
.check_configuration = imx8m_check_configuration,
@@ -246,10 +249,11 @@
writel(io_buffer_phys(&display->fbuffer), io_buffer_virt(&display->mmio_dc) + 0x80c0);
- if (display->dc_cb) {
+ if (display->dc_intf.ops) {
added_display_args_t args;
populate_added_display_args(display, &args);
- display->dc_cb->on_displays_changed(display->dc_cb_ctx, &args, 1, NULL, 0);
+ display_controller_interface_on_displays_changed(&display->dc_intf, &args, 1, NULL, 0,
+ NULL, 0, NULL);
}
mtx_unlock(&display->display_lock);
diff --git a/system/dev/display/imx8m-display/imx8m-display.h b/system/dev/display/imx8m-display/imx8m-display.h
index e8e60fa..32dfcea 100644
--- a/system/dev/display/imx8m-display/imx8m-display.h
+++ b/system/dev/display/imx8m-display/imx8m-display.h
@@ -37,7 +37,6 @@
io_buffer_t mmio_dc;
io_buffer_t fbuffer;
- display_controller_cb_t* dc_cb;
- void* dc_cb_ctx;
+ display_controller_interface_t dc_intf;
list_node_t imported_images;
} imx8m_display_t;
diff --git a/system/dev/display/intel-i915/intel-i915.cpp b/system/dev/display/intel-i915/intel-i915.cpp
index e8e16d5..6ab5b36 100644
--- a/system/dev/display/intel-i915/intel-i915.cpp
+++ b/system/dev/display/intel-i915/intel-i915.cpp
@@ -252,7 +252,7 @@
}
}
- if (dc_cb_ && (added_device || display_removed != INVALID_DISPLAY_ID)) {
+ if (dc_intf_.is_valid() && (added_device || display_removed != INVALID_DISPLAY_ID)) {
CallOnDisplaysChanged(&added_device, added_device != nullptr ? 1 : 0,
&display_removed, display_removed != INVALID_DISPLAY_ID);
}
@@ -261,7 +261,7 @@
void Controller::HandlePipeVsync(registers::Pipe pipe, zx_time_t timestamp) {
fbl::AutoLock lock(&display_lock_);
- if (!dc_cb_) {
+ if (!dc_intf_.is_valid()) {
return;
}
@@ -291,7 +291,7 @@
}
if (id != INVALID_DISPLAY_ID && handle_count) {
- dc_cb_->on_display_vsync(dc_cb_ctx_, id, timestamp, handles, handle_count);
+ dc_intf_.OnDisplayVsync(id, timestamp, handles, handle_count);
}
}
@@ -768,9 +768,11 @@
return ZX_OK;
}
-void Controller::CallOnDisplaysChanged(DisplayDevice** added, uint32_t added_count,
- uint64_t* removed, uint32_t removed_count) {
+void Controller::CallOnDisplaysChanged(DisplayDevice** added, size_t added_count,
+ uint64_t* removed, size_t removed_count) {
added_display_args_t added_args[added_count];
+ added_display_info_t added_info[added_count];
+ size_t added_actual;
for (unsigned i = 0; i < added_count; i++) {
added_args[i].display_id = added[i]->id();
added_args[i].edid_present = true;
@@ -780,18 +782,21 @@
added_args[i].cursor_infos = cursor_infos;
added_args[i].cursor_info_count = static_cast<uint32_t>(fbl::count_of(cursor_infos));
}
- dc_cb_->on_displays_changed(dc_cb_ctx_, added_args, added_count, removed, removed_count);
- for (unsigned i = 0; i < added_count; i++) {
- added[i]->set_is_hdmi(added_args[i].is_hdmi_out);
+ dc_intf_->OnDisplayChanged(added_args, added_count, removed, removed_count,
+ added_info, added_count, &added_actual);
+ ZX_DEBUG_ASSERT(added_count == added_actual);
+ for (unsigned i = 0; i < added_actual; i++) {
+ added[i]->set_is_hdmi(added_info[i].is_hdmi_out);
}
}
// DisplayController methods
-void Controller::SetDisplayControllerCb(void* cb_ctx, display_controller_cb_t* cb) {
+void Controller::DisplayControllerSetDisplayControllerInterface(
+ const display_controller_interface_t* intf) {
+
fbl::AutoLock lock(&display_lock_);
- dc_cb_ctx_ = cb_ctx;
- dc_cb_ = cb;
+ dc_intf_ = ddk::DisplayControllerInterfaceProxy(intf);
if (ready_for_callback_ && display_devices_.size()) {
DisplayDevice* added_displays[registers::kDdiCount];
@@ -803,7 +808,8 @@
}
}
-zx_status_t Controller::ImportVmoImage(image_t* image, const zx::vmo& vmo, size_t offset) {
+zx_status_t Controller::DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo,
+ size_t offset) {
if (!(image->type == IMAGE_TYPE_SIMPLE || image->type == IMAGE_TYPE_X_TILED
|| image->type == IMAGE_TYPE_Y_LEGACY_TILED
|| image->type == IMAGE_TYPE_YF_TILED)) {
@@ -848,7 +854,7 @@
gtt_region = fbl::move(alt_gtt_region);
}
- status = gtt_region->PopulateRegion(vmo.get(), offset / PAGE_SIZE, length);
+ status = gtt_region->PopulateRegion(vmo, offset / PAGE_SIZE, length);
if (status != ZX_OK) {
return status;
}
@@ -858,7 +864,7 @@
return ZX_OK;
}
-void Controller::ReleaseImage(image_t* image) {
+void Controller::DisplayControllerReleaseImage(image_t* image) {
fbl::AutoLock lock(>t_lock_);
for (unsigned i = 0; i < imported_images_.size(); i++) {
if (imported_images_[i]->base() == reinterpret_cast<uint64_t>(image->handle)) {
@@ -868,7 +874,7 @@
}
}
-const fbl::unique_ptr<GttRegion>& Controller::GetGttRegion(void* handle) {
+const fbl::unique_ptr<GttRegion>& Controller::DisplayControllerGetGttRegion(void* handle) {
fbl::AutoLock lock(>t_lock_);
for (auto& region : imported_images_) {
if (region->base() == reinterpret_cast<uint64_t>(handle)) {
@@ -1314,29 +1320,26 @@
return true;
}
-void Controller::CheckConfiguration(const display_config_t** display_config,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count) {
+uint32_t Controller::DisplayControllerCheckConfiguration(const display_config_t** display_config,
+ size_t display_count,
+ uint32_t** layer_cfg_result,
+ size_t* layer_cfg_result_count) {
fbl::AutoLock lock(&display_lock_);
if (display_count == 0) {
// All displays off is supported
- *display_cfg_result = CONFIG_DISPLAY_OK;
- return;
+ return CONFIG_DISPLAY_OK;
}
uint64_t pipe_alloc[registers::kPipeCount];
if (!CalculatePipeAllocation(display_config, display_count, pipe_alloc)) {
- *display_cfg_result = CONFIG_DISPLAY_TOO_MANY;
- return;
+ return CONFIG_DISPLAY_TOO_MANY;
}
if (!CheckDisplayLimits(display_config, display_count, layer_cfg_result)) {
- *display_cfg_result = CONFIG_DISPLAY_UNSUPPORTED_MODES;
- return;
+ return CONFIG_DISPLAY_UNSUPPORTED_MODES;
}
- *display_cfg_result = CONFIG_DISPLAY_OK;
for (unsigned i = 0; i < display_count; i++) {
auto* config = display_config[i];
DisplayDevice* display = nullptr;
@@ -1509,6 +1512,8 @@
}
}
}
+
+ return CONFIG_DISPLAY_OK;
}
bool Controller::CalculatePipeAllocation(const display_config_t** display_config,
@@ -1612,20 +1617,21 @@
}
}
- if (dc_cb_) {
+ if (dc_intf_.is_valid) {
zx_time_t now = fake_vsync_count ? zx_clock_get(ZX_CLOCK_MONOTONIC) : 0;
for (unsigned i = 0; i < fake_vsync_count; i++) {
- dc_cb_->on_display_vsync(dc_cb_ctx_, fake_vsyncs[i], now, nullptr, 0);
+ dc_intf_.OnDisplayVsync(fake_vsyncs[i], now, nullptr, 0);
}
}
}
-uint32_t Controller::ComputeLinearStride(uint32_t width, zx_pixel_format_t format) {
+uint32_t Controller::DisplayControllerComputeLinearStride(uint32_t width,
+ zx_pixel_format_t format) {
return fbl::round_up(width,
get_tile_byte_width(IMAGE_TYPE_SIMPLE, format) / ZX_PIXEL_FORMAT_BYTES(format));
}
-zx_status_t Controller::AllocateVmo(uint64_t size, zx_handle_t* vmo_out) {
+zx_status_t Controller::DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* vmo_out) {
return zx_vmo_create(size, 0, vmo_out);
}
@@ -1931,7 +1937,7 @@
{
fbl::AutoLock lock(&display_lock_);
uint32_t size = static_cast<uint32_t>(display_devices_.size());
- if (size && dc_cb_) {
+ if (size && dc_intf_.is_valid()) {
DisplayDevice* added_displays[registers::kDdiCount];
for (unsigned i = 0; i < size; i++) {
added_displays[i] = display_devices_[i].get();
diff --git a/system/dev/display/intel-i915/intel-i915.h b/system/dev/display/intel-i915/intel-i915.h
index 952ecc6..bb5c24b 100644
--- a/system/dev/display/intel-i915/intel-i915.h
+++ b/system/dev/display/intel-i915/intel-i915.h
@@ -10,6 +10,7 @@
#include <ddk/protocol/pci.h>
#include <ddk/protocol/i2c-impl.h>
#include <ddktl/protocol/display-controller.h>
+#include <ddktl/protocol/empty-protocol.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
@@ -57,7 +58,9 @@
using DeviceType = ddk::Device<Controller, ddk::Unbindable,
ddk::Suspendable, ddk::Resumable, ddk::GetProtocolable>;
-class Controller : public DeviceType, public ddk::DisplayControllerProtocol<Controller> {
+class Controller : public DeviceType,
+ public ddk::DisplayControllerProtocol<Controller>,
+ public ddk::EmptyProtocol<ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL> {
public:
Controller(zx_device_t* parent);
~Controller();
@@ -73,15 +76,16 @@
zx_status_t Bind(fbl::unique_ptr<i915::Controller>* controller_ptr);
// display controller protocol ops
- void SetDisplayControllerCb(void* cb_ctx, display_controller_cb_t* cb);
- zx_status_t ImportVmoImage(image_t* image, const zx::vmo& vmo, size_t offset);
- void ReleaseImage(image_t* image);
- void CheckConfiguration(const display_config_t** display_config,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count);
- void ApplyConfiguration(const display_config_t** display_config, uint32_t display_count);
- uint32_t ComputeLinearStride(uint32_t width, zx_pixel_format_t format);
- zx_status_t AllocateVmo(uint64_t size, zx_handle_t* vmo_out);
+ void DisplayControllerSetDisplayControllerInterface(const display_controller_interface* intf);
+ zx_status_t DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset);
+ void DisplayControllerReleaseImage(image_t* image);
+ uint32_t DisplayControllerCheckConfiguration(const display_config_t** display_config,
+ size_t display_count, uint32_t** layer_cfg_result,
+ size_t* layer_cfg_result_count);
+ void DisplayControllerApplyConfiguration(const display_config_t** display_config,
+ size_t display_count);
+ uint32_t DisplayControllerComputeLinearStride(uint32_t width, zx_pixel_format_t format);
+ zx_status_t DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* vmo_out);
// gpu core ops
zx_status_t ReadPciConfig16(uint16_t addr, uint16_t* value_out);
@@ -185,8 +189,7 @@
bool gpu_released_ = false;
bool display_released_ = false;
- void* dc_cb_ctx_ __TA_GUARDED(display_lock_);
- display_controller_cb_t* dc_cb_ __TA_GUARDED(display_lock_) = nullptr;
+ ddk::DisplayControllerInterfaceProxy dc_intf_ __TA_GUARDED(display_lock_) = nullptr;
bool ready_for_callback_ __TA_GUARDED(display_lock_) = false;
Gtt gtt_ __TA_GUARDED(gtt_lock_);
diff --git a/system/dev/display/simple/simple-bochs.c b/system/dev/display/simple/simple-bochs.c
index 7692167..f40ec46 100644
--- a/system/dev/display/simple/simple-bochs.c
+++ b/system/dev/display/simple/simple-bochs.c
@@ -7,6 +7,8 @@
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/pci.h>
+#include <ddk/protocol/pci-lib.h>
+#include <hw/pci.h>
#include <zircon/pixelformat.h>
#include <zircon/process.h>
diff --git a/system/dev/display/simple/simple-display.cpp b/system/dev/display/simple/simple-display.cpp
index 19e32e9..64c1c37 100644
--- a/system/dev/display/simple/simple-display.cpp
+++ b/system/dev/display/simple/simple-display.cpp
@@ -10,6 +10,7 @@
#include <hw/pci.h>
#include <assert.h>
+#include <zircon/pixelformat.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
@@ -23,11 +24,11 @@
// implement display controller protocol
static constexpr uint64_t kDisplayId = 1;
-static void* const kImageHandle = reinterpret_cast<void*>(0xdecafc0ffee);
+static constexpr uint64_t kImageHandle = 0xdecafc0ffee;
-void SimpleDisplay::SetDisplayControllerCb(void* cb_ctx, display_controller_cb_t* cb) {
- cb_ctx_ = cb_ctx;
- cb_ = cb;
+void SimpleDisplay::DisplayControllerSetDisplayControllerInterface(
+ const display_controller_interface_t* intf) {
+ intf_ = ddk::DisplayControllerInterfaceProxy(intf);
added_display_args_t args = {};
args.display_id = kDisplayId;
@@ -35,17 +36,19 @@
args.panel.params.height = height_;
args.panel.params.width = width_;
args.panel.params.refresh_rate_e2 = 3000; // Just guess that it's 30fps
- args.pixel_formats = &format_;
+ args.pixel_format_list = &format_;
args.pixel_format_count = 1;
- cb->on_displays_changed(cb_ctx, &args, 1, nullptr, 0);
+ intf_.OnDisplaysChanged(&args, 1, nullptr, 0, nullptr, 0, nullptr);
}
-zx_status_t SimpleDisplay::ImportVmoImage(image_t* image, const zx::vmo& vmo, size_t offset) {
+zx_status_t SimpleDisplay::DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo,
+ size_t offset) {
zx_info_handle_basic_t import_info;
size_t actual, avail;
- zx_status_t status = vmo.get_info(ZX_INFO_HANDLE_BASIC,
- &import_info, sizeof(import_info), &actual, &avail);
+ zx_status_t status = zx::unowned_vmo(vmo)->get_info(ZX_INFO_HANDLE_BASIC,
+ &import_info, sizeof(import_info), &actual,
+ &avail);
if (status != ZX_OK) {
return status;
}
@@ -60,29 +63,28 @@
return ZX_OK;
}
-void SimpleDisplay::ReleaseImage(image_t* image) {
+void SimpleDisplay::DisplayControllerReleaseImage(image_t* image) {
// noop
}
-void SimpleDisplay::CheckConfiguration(const display_config_t** display_configs,
- uint32_t* display_cfg_result,
- uint32_t** layer_cfg_results,
- uint32_t display_count) {
- *display_cfg_result = CONFIG_DISPLAY_OK;
+uint32_t SimpleDisplay::DisplayControllerCheckConfiguration(
+ const display_config_t** display_configs, size_t display_count, uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count) {
+
if (display_count != 1) {
ZX_DEBUG_ASSERT(display_count == 0);
- return;
+ return CONFIG_DISPLAY_OK;
}
ZX_DEBUG_ASSERT(display_configs[0]->display_id == kDisplayId);
bool success;
if (display_configs[0]->layer_count != 1) {
success = false;
} else {
- primary_layer_t* layer = &display_configs[0]->layers[0]->cfg.primary;
+ primary_layer_t* layer = &display_configs[0]->layer_list[0]->cfg.primary;
frame_t frame = {
.x_pos = 0, .y_pos = 0, .width = width_, .height = height_,
};
- success = display_configs[0]->layers[0]->type == LAYER_PRIMARY
+ success = display_configs[0]->layer_list[0]->type == LAYER_TYPE_PRIMARY
&& layer->transform_mode == FRAME_TRANSFORM_IDENTITY
&& layer->image.width == width_
&& layer->image.height == height_
@@ -96,24 +98,26 @@
for (unsigned i = 1; i < display_configs[0]->layer_count; i++) {
layer_cfg_results[0][i] = CLIENT_MERGE_SRC;
}
+ layer_cfg_result_count[0] = display_configs[0]->layer_count;
}
+ return CONFIG_DISPLAY_OK;
}
-void SimpleDisplay::ApplyConfiguration(const display_config_t** display_config,
- uint32_t display_count) {
+void SimpleDisplay::DisplayControllerApplyConfiguration(const display_config_t** display_config,
+ size_t display_count) {
bool has_image = display_count != 0 && display_config[0]->layer_count != 0;
- void* handles[] = { kImageHandle };
- if (cb_) {
- cb_->on_display_vsync(cb_ctx_, kDisplayId, zx_clock_get(ZX_CLOCK_MONOTONIC),
- handles, has_image);
+ uint64_t handles[] = { kImageHandle };
+ if (intf_.is_valid()) {
+ intf_.OnDisplayVsync(kDisplayId, zx_clock_get(ZX_CLOCK_MONOTONIC), handles, has_image);
}
}
-uint32_t SimpleDisplay::ComputeLinearStride(uint32_t width, zx_pixel_format_t format) {
+uint32_t SimpleDisplay::DisplayControllerComputeLinearStride(uint32_t width,
+ zx_pixel_format_t format) {
return (width == width_ && format == format_) ? stride_ : 0;
}
-zx_status_t SimpleDisplay::AllocateVmo(uint64_t size, zx_handle_t* vmo_out) {
+zx_status_t SimpleDisplay::DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* vmo_out) {
zx_info_handle_count handle_count;
size_t actual, avail;
zx_status_t status = framebuffer_handle_.get_info(ZX_INFO_HANDLE_COUNT, &handle_count,
diff --git a/system/dev/display/simple/simple-display.h b/system/dev/display/simple/simple-display.h
index 3de2165..913b3d1 100644
--- a/system/dev/display/simple/simple-display.h
+++ b/system/dev/display/simple/simple-display.h
@@ -12,6 +12,7 @@
#include <ddktl/device.h>
#include <ddktl/protocol/display-controller.h>
+#include <ddktl/protocol/empty-protocol.h>
#include <fbl/unique_ptr.h>
#include <lib/zx/vmo.h>
@@ -19,7 +20,8 @@
using DeviceType = ddk::Device<SimpleDisplay, ddk::Unbindable>;
class SimpleDisplay : public DeviceType,
- public ddk::DisplayControllerProtocol<SimpleDisplay> {
+ public ddk::DisplayControllerProtocol<SimpleDisplay>,
+ public ddk::EmptyProtocol<ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL> {
public:
SimpleDisplay(zx_device_t* parent, zx_handle_t vmo,
uintptr_t framebuffer, uint64_t framebuffer_size,
@@ -31,15 +33,16 @@
void DdkRelease();
zx_status_t Bind(const char* name, fbl::unique_ptr<SimpleDisplay>* controller_ptr);
- void SetDisplayControllerCb(void* cb_ctx, display_controller_cb_t* cb);
- zx_status_t ImportVmoImage(image_t* image, const zx::vmo& vmo, size_t offset);
- void ReleaseImage(image_t* image);
- void CheckConfiguration(const display_config_t** display_config,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count);
- void ApplyConfiguration(const display_config_t** display_config, uint32_t display_count);
- uint32_t ComputeLinearStride(uint32_t width, zx_pixel_format_t format);
- zx_status_t AllocateVmo(uint64_t size, zx_handle_t* vmo_out);
+ void DisplayControllerSetDisplayControllerInterface(const display_controller_interface_t* intf);
+ zx_status_t DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset);
+ void DisplayControllerReleaseImage(image_t* image);
+ uint32_t DisplayControllerCheckConfiguration(const display_config_t** display_configs,
+ size_t display_count, uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count);
+ void DisplayControllerApplyConfiguration(const display_config_t** display_config,
+ size_t display_count);
+ uint32_t DisplayControllerComputeLinearStride(uint32_t width, zx_pixel_format_t format);
+ zx_status_t DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* vmo_out);
private:
zx::vmo framebuffer_handle_;
@@ -52,8 +55,7 @@
uint32_t stride_;
zx_pixel_format_t format_;
- display_controller_cb_t* cb_;
- void* cb_ctx_;
+ ddk::DisplayControllerInterfaceProxy intf_;
};
#endif // __cplusplus
diff --git a/system/dev/display/simple/simple-nv.c b/system/dev/display/simple/simple-nv.c
index a944464..81d7438d 100644
--- a/system/dev/display/simple/simple-nv.c
+++ b/system/dev/display/simple/simple-nv.c
@@ -5,7 +5,7 @@
#include <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
-#include <ddk/protocol/pci.h>
+#include <hw/pci.h>
#include "simple-display.h"
diff --git a/system/dev/display/vim-display/vim-display.cpp b/system/dev/display/vim-display/vim-display.cpp
index 5f42625..20b38c5 100644
--- a/system/dev/display/vim-display/vim-display.cpp
+++ b/system/dev/display/vim-display/vim-display.cpp
@@ -26,13 +26,14 @@
#include <string.h>
#include <unistd.h>
#include <zircon/assert.h>
+#include <zircon/pixelformat.h>
#include <zircon/syscalls.h>
/* Default formats */
static const uint8_t _ginput_color_format = HDMI_COLOR_FORMAT_444;
static const uint8_t _gcolor_depth = HDMI_COLOR_DEPTH_24B;
-static const zx_pixel_format_t _gsupported_pixel_formats = { ZX_PIXEL_FORMAT_RGB_x888 };
+static zx_pixel_format_t _gsupported_pixel_formats[] = { ZX_PIXEL_FORMAT_RGB_x888 };
typedef struct image_info {
zx_handle_t pmt;
@@ -46,8 +47,8 @@
args->display_id = display->display_id;
args->edid_present = true;
args->panel.i2c_bus_id = 0;
- args->pixel_formats = &_gsupported_pixel_formats;
- args->pixel_format_count = sizeof(_gsupported_pixel_formats) / sizeof(zx_pixel_format_t);
+ args->pixel_format_list = _gsupported_pixel_formats;
+ args->pixel_format_count = countof(_gsupported_pixel_formats);
args->cursor_info_count = 0;
}
@@ -57,19 +58,21 @@
return ROUNDUP(width, 32 / ZX_PIXEL_FORMAT_BYTES(format));
}
-static void vim_set_display_controller_cb(void* ctx, void* cb_ctx, display_controller_cb_t* cb) {
+static void vim_set_display_controller_interface(void* ctx,
+ const display_controller_interface_t* intf) {
vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
mtx_lock(&display->display_lock);
- display->dc_cb = cb;
- display->dc_cb_ctx = cb_ctx;
+ display->dc_intf = *intf;
if (display->display_attached) {
added_display_args_t args;
+ added_display_info_t info;
populate_added_display_args(display, &args);
- display->dc_cb->on_displays_changed(display->dc_cb_ctx, &args, 1, NULL, 0);
+ display_controller_interface_on_displays_changed(&display->dc_intf, &args, 1, NULL, 0,
+ &info, 1, NULL);
- if (args.is_standard_srgb_out) {
+ if (info.is_standard_srgb_out) {
display->output_color_format = HDMI_COLOR_FORMAT_RGB;
} else {
display->output_color_format = HDMI_COLOR_FORMAT_444;
@@ -117,7 +120,7 @@
if (status != ZX_OK) {
return ZX_ERR_NO_RESOURCES;
}
- image->handle = (void*)(uint64_t)import_info->canvas_idx[0];
+ image->handle = import_info->canvas_idx[0];
} else if (image->pixel_format == ZX_PIXEL_FORMAT_NV12) {
if (image->height % 2 != 0) {
return ZX_ERR_INVALID_ARGS;
@@ -164,8 +167,8 @@
return ZX_ERR_NO_RESOURCES;
}
// The handle used by hardware is VVUUYY, so the UV plane is included twice.
- image->handle = (void*)(((uint64_t)import_info->canvas_idx[1] << 16) |
- (import_info->canvas_idx[1] << 8) | import_info->canvas_idx[0]);
+ image->handle = (((uint64_t)import_info->canvas_idx[1] << 16) |
+ (import_info->canvas_idx[1] << 8) | import_info->canvas_idx[0]);
} else {
return ZX_ERR_INVALID_ARGS;
}
@@ -199,20 +202,19 @@
}
}
-static void vim_check_configuration(void* ctx,
- const display_config_t** display_configs,
- uint32_t* display_cfg_result,
- uint32_t** layer_cfg_results,
- uint32_t display_count) {
- *display_cfg_result = CONFIG_DISPLAY_OK;
+static uint32_t vim_check_configuration(void* ctx,
+ const display_config_t** display_configs,
+ size_t display_count,
+ uint32_t** layer_cfg_results,
+ size_t* layer_cfg_result_count) {
if (display_count != 1) {
if (display_count > 1) {
// The core display driver should never see a configuration with more
// than 1 display, so this is a bug in the core driver.
ZX_DEBUG_ASSERT(false);
- *display_cfg_result = CONFIG_DISPLAY_TOO_MANY;
+ return CONFIG_DISPLAY_TOO_MANY;
}
- return;
+ return CONFIG_DISPLAY_OK;
}
vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
mtx_lock(&display->display_lock);
@@ -220,7 +222,7 @@
// no-op, just wait for the client to try a new config
if (!display->display_attached || display_configs[0]->display_id != display->display_id) {
mtx_unlock(&display->display_lock);
- return;
+ return CONFIG_DISPLAY_OK;
}
struct hdmi_param p;
@@ -228,8 +230,7 @@
&& get_vic(&display_configs[0]->mode, &p) != ZX_OK)
|| (display_configs[0]->mode.v_addressable % 8)) {
mtx_unlock(&display->display_lock);
- *display_cfg_result = CONFIG_DISPLAY_UNSUPPORTED_MODES;
- return;
+ return CONFIG_DISPLAY_UNSUPPORTED_MODES;
}
bool success;
@@ -238,7 +239,7 @@
} else {
uint32_t width = display_configs[0]->mode.h_addressable;
uint32_t height = display_configs[0]->mode.v_addressable;
- primary_layer_t* layer = &display_configs[0]->layers[0]->cfg.primary;
+ primary_layer_t* layer = &display_configs[0]->layer_list[0]->cfg.primary;
frame_t frame = {
.x_pos = 0, .y_pos = 0, .width = width, .height = height,
};
@@ -246,7 +247,7 @@
layer->image.width,
layer->image.pixel_format)
* ZX_PIXEL_FORMAT_BYTES(layer->image.pixel_format);
- success = display_configs[0]->layers[0]->type == LAYER_PRIMARY
+ success = display_configs[0]->layer_list[0]->type == LAYER_TYPE_PRIMARY
&& layer->transform_mode == FRAME_TRANSFORM_IDENTITY
&& layer->image.width == width
&& layer->image.height == height
@@ -263,13 +264,15 @@
for (unsigned i = 1; i < display_configs[0]->layer_count; i++) {
layer_cfg_results[0][i] = CLIENT_MERGE_SRC;
}
+ layer_cfg_result_count[0] = display_configs[0]->layer_count;
}
mtx_unlock(&display->display_lock);
+ return CONFIG_DISPLAY_OK;
}
static void vim_apply_configuration(void* ctx,
const display_config_t** display_configs,
- uint32_t display_count) {
+ size_t display_count) {
vim2_display_t* display = static_cast<vim2_display_t*>(ctx);
mtx_lock(&display->display_lock);
@@ -296,14 +299,14 @@
mtx_unlock(&display->display_lock);
return;
}
- if (display_configs[0]->layers[0]->cfg.primary.image.pixel_format == ZX_PIXEL_FORMAT_NV12) {
+ if (display_configs[0]->layer_list[0]->cfg.primary.image.pixel_format == ZX_PIXEL_FORMAT_NV12) {
uint32_t addr =
- (uint32_t)(uint64_t)display_configs[0]->layers[0]->cfg.primary.image.handle;
+ (uint32_t)(uint64_t)display_configs[0]->layer_list[0]->cfg.primary.image.handle;
flip_vd(display, 0, addr);
disable_osd(display, 1);
} else {
uint8_t addr;
- addr = (uint8_t)(uint64_t)display_configs[0]->layers[0]->cfg.primary.image.handle;
+ addr = (uint8_t)(uint64_t)display_configs[0]->layer_list[0]->cfg.primary.image.handle;
flip_osd(display, 1, addr);
disable_vd(display, 0);
}
@@ -325,7 +328,7 @@
}
static display_controller_protocol_ops_t display_controller_ops = {
- .set_display_controller_cb = vim_set_display_controller_cb,
+ .set_display_controller_interface = vim_set_display_controller_interface,
.import_vmo_image = vim_import_vmo_image,
.release_image = vim_release_image,
.check_configuration = vim_check_configuration,
@@ -513,6 +516,7 @@
bool display_added = false;
added_display_args_t args;
+ added_display_info_t info;
uint64_t display_removed = INVALID_DISPLAY_ID;
if (hpd && !display->display_attached) {
DISP_ERROR("Display is connected\n");
@@ -533,27 +537,30 @@
gpio_set_polarity(&display->gpio, 0, GPIO_POLARITY_HIGH);
}
- if (display->dc_cb &&
+ if (display->dc_intf.ops &&
(display_removed != INVALID_DISPLAY_ID || display_added)) {
- display->dc_cb->on_displays_changed(display->dc_cb_ctx,
- &args,
- display_added ? 1 : 0,
- &display_removed,
- display_removed != INVALID_DISPLAY_ID);
+ display_controller_interface_on_displays_changed(&display->dc_intf,
+ &args,
+ display_added ? 1 : 0,
+ &display_removed,
+ display_removed != INVALID_DISPLAY_ID,
+ &info,
+ display_added ? 1 : 0,
+ NULL);
if (display_added) {
// See if we need to change output color to RGB
- if (args.is_standard_srgb_out) {
+ if (info.is_standard_srgb_out) {
display->output_color_format = HDMI_COLOR_FORMAT_RGB;
} else {
display->output_color_format = HDMI_COLOR_FORMAT_444;
}
- display->audio_format_count = args.audio_format_count;
+ display->audio_format_count = info.audio_format_count;
- display->manufacturer_name = args.manufacturer_name;
- memcpy(display->monitor_name, args.monitor_name, sizeof(args.monitor_name));
- memcpy(display->monitor_serial, args.monitor_serial, sizeof(args.monitor_serial));
- static_assert(sizeof(display->monitor_name) == sizeof(args.monitor_name), "");
- static_assert(sizeof(display->monitor_serial) == sizeof(args.monitor_serial), "");
+ display->manufacturer_name = info.manufacturer_name;
+ memcpy(display->monitor_name, info.monitor_name, sizeof(info.monitor_name));
+ memcpy(display->monitor_serial, info.monitor_serial, sizeof(info.monitor_serial));
+ static_assert(sizeof(display->monitor_name) == sizeof(info.monitor_name), "");
+ static_assert(sizeof(display->monitor_serial) == sizeof(info.monitor_serial), "");
}
}
@@ -563,7 +570,7 @@
vim2_audio_on_display_removed(display, display_removed);
}
- if (display_added && args.audio_format_count) {
+ if (display_added && info.audio_format_count) {
vim2_audio_on_display_added(display, display->display_id);
}
}
@@ -586,18 +593,18 @@
uint64_t display_id = display->display_id;
bool attached = display->display_attached;
- void* live[2] = {};
+ uint64_t live[2] = {};
uint32_t current_image_count = 0;
if (display->current_image_valid) {
- live[current_image_count++] = (void*)(uint64_t)display->current_image;
+ live[current_image_count++] = display->current_image;
}
if (display->vd1_image_valid) {
- live[current_image_count++] = (void*)(uint64_t)display->vd1_image;
+ live[current_image_count++] = display->vd1_image;
}
- if (display->dc_cb && attached) {
- display->dc_cb->on_display_vsync(display->dc_cb_ctx, display_id, timestamp, live,
- current_image_count);
+ if (display->dc_intf.ops && attached) {
+ display_controller_interface_on_display_vsync(&display->dc_intf, display_id, timestamp,
+ live, current_image_count);
}
mtx_unlock(&display->display_lock);
}
diff --git a/system/dev/display/vim-display/vim-display.h b/system/dev/display/vim-display/vim-display.h
index 366089b..bd51ea0 100644
--- a/system/dev/display/vim-display/vim-display.h
+++ b/system/dev/display/vim-display/vim-display.h
@@ -103,8 +103,7 @@
struct hdmi_param* p;
display_mode_t cur_display_mode;
- display_controller_cb_t* dc_cb;
- void* dc_cb_ctx;
+ display_controller_interface_t dc_intf;
list_node_t imported_images;
// A reference to the object which controls the VIM2 DAIs used to feed audio
diff --git a/system/dev/display/vim-display/vim-spdif-audio-stream.cpp b/system/dev/display/vim-display/vim-spdif-audio-stream.cpp
index 1e50256..ff712ed 100644
--- a/system/dev/display/vim-display/vim-spdif-audio-stream.cpp
+++ b/system/dev/display/vim-display/vim-spdif-audio-stream.cpp
@@ -328,8 +328,8 @@
// generate clock rates up to 192KHz, and can generate 16, 20, and 24 bit audio.
for (unsigned i = 0; i < display_->audio_format_count; i++) {
audio_stream_format_range_t range;
- zx_status_t status = display_->dc_cb->get_audio_format(
- display_->dc_cb_ctx, display_->display_id, i, &range);
+ zx_status_t status = display_controller_interface_get_audio_format(
+ &display_->dc_intf, display_->display_id, i, &range);
ZX_ASSERT(status == ZX_OK);
constexpr uint32_t SUPPORTED_FORMATS = AUDIO_SAMPLE_FORMAT_16BIT |
diff --git a/system/dev/ethernet/aml-dwmac/aml-dwmac.cpp b/system/dev/ethernet/aml-dwmac/aml-dwmac.cpp
index 430575d..d10bf6a 100644
--- a/system/dev/ethernet/aml-dwmac/aml-dwmac.cpp
+++ b/system/dev/ethernet/aml-dwmac/aml-dwmac.cpp
@@ -15,6 +15,7 @@
#include <lib/fzl/vmar-manager.h>
#include <soc/aml-s912/s912-hw.h>
#include <zircon/compiler.h>
+#include <zircon/device/ethernet.h>
#include <stdio.h>
#include <string.h>
@@ -484,14 +485,14 @@
ethmac_proxy_.reset();
}
-zx_status_t AmlDWMacDevice::EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy) {
+zx_status_t AmlDWMacDevice::EthmacStart(const ethmac_ifc_t* ifc) {
fbl::AutoLock lock(&lock_);
if (ethmac_proxy_ != nullptr) {
zxlogf(ERROR, "aml_dwmac: Already bound!!!");
return ZX_ERR_ALREADY_BOUND;
} else {
- ethmac_proxy_ = fbl::move(proxy);
+ ethmac_proxy_ = fbl::make_unique<ddk::EthmacIfcProxy>(ifc);
UpdateLinkStatus();
zxlogf(INFO, "aml_dwmac: Started\n");
}
@@ -599,7 +600,7 @@
}
}
- if (netbuf->len > kTxnBufSize) {
+ if (netbuf->data_size > kTxnBufSize) {
return ZX_ERR_INVALID_ARGS;
}
if (tx_descriptors_[curr_tx_buf_].txrx_status & DESC_TXSTS_OWNBYDMA) {
@@ -608,10 +609,10 @@
}
uint8_t* temptr = &tx_buffer_[curr_tx_buf_ * kTxnBufSize];
- memcpy(temptr, netbuf->data, netbuf->len);
+ memcpy(temptr, netbuf->data_buffer, netbuf->data_size);
hw_mb();
- zx_cache_flush(temptr, netbuf->len, ZX_CACHE_FLUSH_DATA);
+ zx_cache_flush(temptr, netbuf->data_size, ZX_CACHE_FLUSH_DATA);
//Descriptors are pre-iniitialized with the paddr of their corresponding
// buffers, only need to setup the control and status fields.
@@ -620,7 +621,7 @@
DESC_TXCTRL_TXLAST |
DESC_TXCTRL_TXFIRST |
DESC_TXCTRL_TXCHAIN |
- (netbuf->len & DESC_TXCTRL_SIZE1MASK);
+ ((uint32_t)netbuf->data_size & DESC_TXCTRL_SIZE1MASK);
tx_descriptors_[curr_tx_buf_].txrx_status = DESC_TXSTS_OWNBYDMA;
curr_tx_buf_ = (curr_tx_buf_ + 1) % kNumDesc;
@@ -631,7 +632,8 @@
return ZX_OK;
}
-zx_status_t AmlDWMacDevice::EthmacSetParam(uint32_t param, int32_t value, void* data) {
+zx_status_t AmlDWMacDevice::EthmacSetParam(uint32_t param, int32_t value, const void* data,
+ size_t data_size) {
zxlogf(INFO, "SetParam called %x %x\n", param, value);
return ZX_OK;
}
diff --git a/system/dev/ethernet/aml-dwmac/aml-dwmac.h b/system/dev/ethernet/aml-dwmac/aml-dwmac.h
index f9e4bcd..94fcf4e 100644
--- a/system/dev/ethernet/aml-dwmac/aml-dwmac.h
+++ b/system/dev/ethernet/aml-dwmac/aml-dwmac.h
@@ -92,9 +92,9 @@
zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* info);
void EthmacStop() __TA_EXCLUDES(lock_);
- zx_status_t EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy) __TA_EXCLUDES(lock_);
+ zx_status_t EthmacStart(const ethmac_ifc_t* ifc) __TA_EXCLUDES(lock_);
zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf) __TA_EXCLUDES(lock_);
- zx_status_t EthmacSetParam(uint32_t param, int32_t value, void* data);
+ zx_status_t EthmacSetParam(uint32_t param, int32_t value, const void* data, size_t data_size);
zx_status_t MDIOWrite(uint32_t reg, uint32_t val);
zx_status_t MDIORead(uint32_t reg, uint32_t* val);
zx_handle_t EthmacGetBti();
diff --git a/system/dev/ethernet/asix-88179/asix-88179.c b/system/dev/ethernet/asix-88179/asix-88179.c
index 5a8f3ae..1fc2fc2 100644
--- a/system/dev/ethernet/asix-88179/asix-88179.c
+++ b/system/dev/ethernet/asix-88179/asix-88179.c
@@ -85,8 +85,7 @@
uint64_t rx_endpoint_delay; // wait time between 2 recv requests
uint64_t tx_endpoint_delay; // wait time between 2 transmit requests
// callback interface to attached ethernet layer
- ethmac_ifc_t* ifc;
- void* cookie;
+ ethmac_ifc_t ifc;
thrd_t thread;
mtx_t mutex;
@@ -297,7 +296,7 @@
}
if (!drop) {
zxlogf(SPEW, "offset = %zd\n", offset);
- eth->ifc->recv(eth->cookie, read_data + offset + 2, pkt_len - 2, 0);
+ ethmac_ifc_recv(ð->ifc, read_data + offset + 2, pkt_len - 2, 0);
}
// Advance past this packet in the completed read
@@ -327,7 +326,7 @@
eth->rx_endpoint_delay += ETHMAC_RECV_DELAY;
}
usb_reset_endpoint(ð->usb, eth->bulk_in_addr);
- } else if ((request->response.status == ZX_OK) && eth->ifc) {
+ } else if ((request->response.status == ZX_OK) && eth->ifc.ops) {
ax88179_recv(eth, request);
}
@@ -343,15 +342,15 @@
static zx_status_t ax88179_append_to_tx_req(usb_protocol_t* usb, usb_request_t* req,
ethmac_netbuf_t* netbuf) {
zx_off_t offset = ALIGN(req->header.length, 4);
- if (offset + sizeof(ax88179_tx_hdr_t) + netbuf->len > USB_BUF_SIZE) {
+ if (offset + sizeof(ax88179_tx_hdr_t) + netbuf->data_size > USB_BUF_SIZE) {
return ZX_ERR_BUFFER_TOO_SMALL;
}
ax88179_tx_hdr_t hdr = {
- .tx_len = htole16(netbuf->len),
+ .tx_len = htole16(netbuf->data_size),
};
usb_req_copy_to(usb, req, &hdr, sizeof(hdr), offset);
- usb_req_copy_to(usb, req, netbuf->data, netbuf->len, offset + sizeof(hdr));
- req->header.length = offset + sizeof(hdr) + netbuf->len;
+ usb_req_copy_to(usb, req, netbuf->data_buffer, netbuf->data_size, offset + sizeof(hdr));
+ req->header.length = offset + sizeof(hdr) + netbuf->data_size;
return ZX_OK;
}
@@ -376,8 +375,8 @@
next_netbuf) == ZX_OK) {
list_remove_head_type(ð->pending_netbuf, ethmac_netbuf_t, node);
mtx_lock(ð->mutex);
- if (eth->ifc) {
- eth->ifc->complete_tx(eth->cookie, next_netbuf, ZX_OK);
+ if (eth->ifc.ops) {
+ ethmac_ifc_complete_tx(ð->ifc, next_netbuf, ZX_OK);
}
mtx_unlock(ð->mutex);
next_netbuf = list_peek_head_type(ð->pending_netbuf, ethmac_netbuf_t, node);
@@ -442,13 +441,13 @@
usb_request_queue(ð->usb, req);
}
zxlogf(TRACE, "ax88179 now online\n");
- if (eth->ifc) {
- eth->ifc->status(eth->cookie, ETH_STATUS_ONLINE);
+ if (eth->ifc.ops) {
+ ethmac_ifc_status(ð->ifc, ETH_STATUS_ONLINE);
}
} else if (!online && was_online) {
zxlogf(TRACE, "ax88179 now offline\n");
- if (eth->ifc) {
- eth->ifc->status(eth->cookie, 0);
+ if (eth->ifc.ops) {
+ ethmac_ifc_status(ð->ifc, 0);
}
}
}
@@ -458,7 +457,7 @@
}
static zx_status_t ax88179_queue_tx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
- size_t length = netbuf->len;
+ size_t length = netbuf->data_size;
if (length > (AX88179_MTU + MAX_ETH_HDRS)) {
zxlogf(ERROR, "ax88179: unsupported packet length %zu\n", length);
@@ -589,21 +588,20 @@
static void ax88179_stop(void* ctx) {
ax88179_t* eth = ctx;
mtx_lock(ð->mutex);
- eth->ifc = NULL;
+ eth->ifc.ops = NULL;
mtx_unlock(ð->mutex);
}
-static zx_status_t ax88179_start(void* ctx, ethmac_ifc_t* ifc, void* cookie) {
+static zx_status_t ax88179_start(void* ctx, const ethmac_ifc_t* ifc) {
ax88179_t* eth = ctx;
zx_status_t status = ZX_OK;
mtx_lock(ð->mutex);
- if (eth->ifc) {
+ if (eth->ifc.ops) {
status = ZX_ERR_BAD_STATE;
} else {
- eth->ifc = ifc;
- eth->cookie = cookie;
- eth->ifc->status(eth->cookie, eth->online ? ETH_STATUS_ONLINE : 0);
+ eth->ifc = *ifc;
+ ethmac_ifc_status(ð->ifc, eth->online ? ETH_STATUS_ONLINE : 0);
}
mtx_unlock(ð->mutex);
@@ -648,7 +646,7 @@
}
static zx_status_t ax88179_set_multicast_filter(ax88179_t* eth, int32_t n_addresses,
- uint8_t* address_bytes) {
+ const uint8_t* address_bytes, size_t address_size) {
zx_status_t status = ZX_OK;
eth->multicast_filter_overflow = (n_addresses == ETHMAC_MULTICAST_FILTER_OVERFLOW) ||
(n_addresses > MAX_MULTICAST_FILTER_ADDRS);
@@ -656,6 +654,8 @@
status = ax88179_set_multicast_promisc(eth, true);
return status;
}
+ if (address_size < n_addresses * ETH_MAC_SIZE)
+ return ZX_ERR_OUT_OF_RANGE;
uint8_t filter[MULTICAST_FILTER_NBYTES];
memset(filter, 0, MULTICAST_FILTER_NBYTES);
@@ -671,7 +671,8 @@
}
static void ax88179_dump_regs(ax88179_t* eth);
-static zx_status_t ax88179_set_param(void *ctx, uint32_t param, int32_t value, void* data) {
+static zx_status_t ax88179_set_param(void *ctx, uint32_t param, int32_t value, const void* data,
+ size_t data_size) {
ax88179_t* eth = ctx;
zx_status_t status = ZX_OK;
@@ -685,7 +686,7 @@
status = ax88179_set_multicast_promisc(eth, (bool)value);
break;
case ETHMAC_SETPARAM_MULTICAST_FILTER:
- status = ax88179_set_multicast_filter(eth, value, (uint8_t*)data);
+ status = ax88179_set_multicast_filter(eth, value, (const uint8_t*)data, data_size);
break;
case ETHMAC_SETPARAM_DUMP_REGS:
ax88179_dump_regs(eth);
diff --git a/system/dev/ethernet/asix-88772b/asix-88772b.c b/system/dev/ethernet/asix-88772b/asix-88772b.c
index 885da38..28af44c 100644
--- a/system/dev/ethernet/asix-88772b/asix-88772b.c
+++ b/system/dev/ethernet/asix-88772b/asix-88772b.c
@@ -65,8 +65,7 @@
uint64_t tx_endpoint_delay; // wait time between 2 transmit requests
// callback interface to attached ethernet layer
- ethmac_ifc_t* ifc;
- void* cookie;
+ ethmac_ifc_t ifc;
mtx_t mutex;
} ax88772b_t;
@@ -177,7 +176,7 @@
return;
}
- eth->ifc->recv(eth->cookie, pkt, length1, 0);
+ ethmac_ifc_recv(ð->ifc, pkt, length1, 0);
pkt += length1;
len -= length1;
@@ -194,7 +193,7 @@
// Send a netbuf to the USB interface using the provided request
static zx_status_t ax88772b_send(ax88772b_t* eth, usb_request_t* request, ethmac_netbuf_t* netbuf) {
- size_t length = netbuf->len;
+ size_t length = netbuf->data_size;
if (length + ETH_HEADER_SIZE > USB_BUF_OUT_SIZE) {
zxlogf(ERROR, "ax88772b: unsupported packet length %zu\n", length);
@@ -211,7 +210,7 @@
header[3] = hi ^ 0xFF;
usb_req_copy_to(ð->usb, request, header, ETH_HEADER_SIZE, 0);
- usb_req_copy_to(ð->usb, request, netbuf->data, length, ETH_HEADER_SIZE);
+ usb_req_copy_to(ð->usb, request, netbuf->data_buffer, length, ETH_HEADER_SIZE);
request->header.length = length + ETH_HEADER_SIZE;
zx_nanosleep(zx_deadline_after(ZX_USEC(eth->tx_endpoint_delay)));
@@ -238,7 +237,7 @@
eth->rx_endpoint_delay += ETHMAC_RECV_DELAY;
}
usb_reset_endpoint(ð->usb, eth->bulk_in_addr);
- } else if ((request->response.status == ZX_OK) && eth->ifc) {
+ } else if ((request->response.status == ZX_OK) && eth->ifc.ops) {
ax88772b_recv(eth, request);
}
@@ -265,8 +264,8 @@
ethmac_netbuf_t* netbuf = list_remove_head_type(ð->pending_netbufs, ethmac_netbuf_t,
node);
zx_status_t send_result = ax88772b_send(eth, request, netbuf);
- if (eth->ifc) {
- eth->ifc->complete_tx(eth->cookie, netbuf, send_result);
+ if (eth->ifc.ops) {
+ ethmac_ifc_complete_tx(ð->ifc, netbuf, send_result);
}
} else {
list_add_tail(ð->free_write_reqs, &request->node);
@@ -310,8 +309,8 @@
bool was_online = eth->online;
eth->online = online;
if (online && !was_online) {
- if (eth->ifc) {
- eth->ifc->status(eth->cookie, ETH_STATUS_ONLINE);
+ if (eth->ifc.ops) {
+ ethmac_ifc_status(ð->ifc, ETH_STATUS_ONLINE);
}
// Now that we are online, queue all our read requests
@@ -322,8 +321,8 @@
usb_request_queue(ð->usb, req);
}
} else if (!online && was_online) {
- if (eth->ifc) {
- eth->ifc->status(eth->cookie, 0);
+ if (eth->ifc.ops) {
+ ethmac_ifc_status(ð->ifc, 0);
}
}
}
@@ -415,21 +414,20 @@
static void ax88772b_stop(void* ctx) {
ax88772b_t* eth = ctx;
mtx_lock(ð->mutex);
- eth->ifc = NULL;
+ eth->ifc.ops = NULL;
mtx_unlock(ð->mutex);
}
-static zx_status_t ax88772b_start(void* ctx, ethmac_ifc_t* ifc, void* cookie) {
+static zx_status_t ax88772b_start(void* ctx, const ethmac_ifc_t* ifc) {
ax88772b_t* eth = ctx;
zx_status_t status = ZX_OK;
mtx_lock(ð->mutex);
- if (eth->ifc) {
+ if (eth->ifc.ops) {
status = ZX_ERR_BAD_STATE;
} else {
- eth->ifc = ifc;
- eth->cookie = cookie;
- eth->ifc->status(eth->cookie, eth->online ? ETH_STATUS_ONLINE : 0);
+ eth->ifc = *ifc;
+ ethmac_ifc_status(ð->ifc, eth->online ? ETH_STATUS_ONLINE : 0);
}
mtx_unlock(ð->mutex);
@@ -456,7 +454,8 @@
return status;
}
-static zx_status_t ax88772b_set_param(void *ctx, uint32_t param, int32_t value, void* data) {
+static zx_status_t ax88772b_set_param(void *ctx, uint32_t param, int32_t value, const void* data,
+ size_t data_size) {
ax88772b_t* eth = ctx;
zx_status_t status = ZX_OK;
diff --git a/system/dev/ethernet/ethernet/ethernet.c b/system/dev/ethernet/ethernet/ethernet.c
index 97e19ab..4bedecc 100644
--- a/system/dev/ethernet/ethernet/ethernet.c
+++ b/system/dev/ethernet/ethernet/ethernet.c
@@ -155,7 +155,7 @@
(*requesters_count)++;
edev->state |= state_bit;
if (*requesters_count == 1) {
- status = edev0->mac.ops->set_param(edev0->mac.ctx, param_id, true, NULL);
+ status = ethmac_set_param(&edev0->mac, param_id, true, NULL, 0);
if (status != ZX_OK) {
(*requesters_count)--;
edev->state &= ~state_bit;
@@ -165,7 +165,7 @@
(*requesters_count)--;
edev->state &= ~state_bit;
if (*requesters_count == 0) {
- status = edev0->mac.ops->set_param(edev0->mac.ctx, param_id, false, NULL);
+ status = ethmac_set_param(&edev0->mac, param_id, false, NULL, 0);
if (status != ZX_OK) {
(*requesters_count)++;
edev->state |= state_bit;
@@ -195,15 +195,15 @@
list_for_every_entry(&edev0->list_active, edev_i, ethdev_t, node) {
for (uint32_t i = 0; i < edev_i->n_multicast; i++) {
if (n_multicast == MULTICAST_LIST_LIMIT) {
- return edev0->mac.ops->set_param(edev0->mac.ctx, ETHMAC_SETPARAM_MULTICAST_FILTER,
- ETHMAC_MULTICAST_FILTER_OVERFLOW, NULL);
+ return ethmac_set_param(&edev0->mac, ETHMAC_SETPARAM_MULTICAST_FILTER,
+ ETHMAC_MULTICAST_FILTER_OVERFLOW, NULL, 0);
}
memcpy(multicast[n_multicast], edev_i->multicast[i], ETH_MAC_SIZE);
n_multicast++;
}
}
- return edev0->mac.ops->set_param(edev0->mac.ctx, ETHMAC_SETPARAM_MULTICAST_FILTER,
- n_multicast, multicast);
+ return ethmac_set_param(&edev0->mac, ETHMAC_SETPARAM_MULTICAST_FILTER, n_multicast, multicast,
+ n_multicast * ETH_MAC_SIZE);
}
static int eth_multicast_addr_index(ethdev_t* edev, uint8_t* mac) {
@@ -228,8 +228,8 @@
return eth_rebuild_multicast_filter_locked(edev);
} else {
ethdev0_t* edev0 = edev->edev0;
- return edev0->mac.ops->set_param(edev0->mac.ctx, ETHMAC_SETPARAM_MULTICAST_FILTER,
- ETHMAC_MULTICAST_FILTER_OVERFLOW, NULL);
+ return ethmac_set_param(&edev0->mac, ETHMAC_SETPARAM_MULTICAST_FILTER,
+ ETHMAC_MULTICAST_FILTER_OVERFLOW, NULL, 0);
}
return ZX_OK;
}
@@ -272,8 +272,7 @@
"MULTICAST_TEST_FILTER invoked. Turning multicast-promisc off unconditionally.\n");
return eth_test_clear_multicast_promisc_locked(edev);
case ETH_MULTICAST_DUMP_REGS:
- return edev->edev0->mac.ops->set_param(edev->edev0->mac.ctx,
- ETHMAC_SETPARAM_DUMP_REGS, 0, NULL);
+ return ethmac_set_param(&edev->edev0->mac, ETHMAC_SETPARAM_DUMP_REGS, 0, NULL, 0);
default:
return ZX_ERR_INVALID_ARGS;
}
@@ -362,7 +361,7 @@
// TODO: I think if this arrives at the wrong time during teardown we
// can deadlock with the ethermac device
-static void eth0_recv(void* cookie, void* data, size_t len, uint32_t flags) {
+static void eth0_recv(void* cookie, const void* data, size_t len, uint32_t flags) {
ethdev0_t* edev0 = cookie;
ethdev_t* edev;
@@ -394,8 +393,8 @@
static void eth0_complete_tx(void* cookie, ethmac_netbuf_t* netbuf, zx_status_t status) {
tx_info_t* tx_info = containerof(netbuf, tx_info_t, netbuf);
ethdev_t* edev = tx_info->edev;
- eth_fifo_entry_t entry = {.offset = netbuf->data - edev->io_buf,
- .length = netbuf->len,
+ eth_fifo_entry_t entry = {.offset = netbuf->data_buffer - edev->io_buf,
+ .length = netbuf->data_size,
.flags = status == ZX_OK ? ETH_FIFO_TX_OK : 0,
.cookie = tx_info->fifo_cookie};
@@ -407,7 +406,7 @@
tx_fifo_write(edev, &entry, 1);
}
-static ethmac_ifc_t ethmac_ifc = {
+static ethmac_ifc_ops_t ethmac_ifc = {
.status = eth0_status,
.recv = eth0_recv,
.complete_tx = eth0_complete_tx,
@@ -480,14 +479,14 @@
if (opts) {
zxlogf(SPEW, "setting OPT_MORE (%u packets to go)\n", count);
}
- tx_info->netbuf.data = edev->io_buf + e->offset;
+ tx_info->netbuf.data_buffer = edev->io_buf + e->offset;
if (edev0->info.features & ETHMAC_FEATURE_DMA) {
tx_info->netbuf.phys = edev->paddr_map[e->offset / PAGE_SIZE] +
(e->offset & PAGE_MASK);
}
- tx_info->netbuf.len = e->length;
+ tx_info->netbuf.data_size = e->length;
tx_info->fifo_cookie = e->cookie;
- status = edev0->mac.ops->queue_tx(edev0->mac.ctx, opts, &tx_info->netbuf);
+ status = ethmac_queue_tx(&edev0->mac, opts, &tx_info->netbuf);
if (edev->state & ETHDEV_TX_LOOPBACK) {
eth_tx_echo(edev0, edev->io_buf + e->offset, e->length);
}
@@ -630,7 +629,7 @@
status = ZX_ERR_NO_MEMORY;
goto fail;
}
- zx_handle_t bti = edev->edev0->mac.ops->get_bti(edev->edev0->mac.ctx);
+ zx_handle_t bti = ethmac_get_bti(&edev->edev0->mac);
if ((status = zx_bti_pin(bti, ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE,
vmo, 0, size, edev->paddr_map, pages, &edev->pmt)) != ZX_OK) {
zxlogf(ERROR, "eth [%s]: bti_pin failed, can't pin vmo: %d\n",
@@ -692,7 +691,7 @@
// Re-acquire lock afterwards. Set busy to prevent problems with other ioctls.
edev0->state |= ETHDEV0_BUSY;
mtx_unlock(&edev0->lock);
- status = edev0->mac.ops->start(edev0->mac.ctx, ðmac_ifc, edev0);
+ status = ethmac_start(&edev->edev0->mac, &(ethmac_ifc_t){ðmac_ifc, edev0});
mtx_lock(&edev0->lock);
edev0->state &= ~ETHDEV0_BUSY;
} else {
@@ -733,7 +732,7 @@
// Re-acquire lock afterwards. Set busy to prevent problems with other ioctls.
edev0->state |= ETHDEV0_BUSY;
mtx_unlock(&edev0->lock);
- edev0->mac.ops->stop(edev0->mac.ctx);
+ ethmac_stop(&edev->edev0->mac);
mtx_lock(&edev0->lock);
edev0->state &= ~ETHDEV0_BUSY;
}
@@ -1130,7 +1129,7 @@
goto fail;
}
- if ((status = edev0->mac.ops->query(edev0->mac.ctx, 0, &edev0->info)) < 0) {
+ if ((status = ethmac_query(&edev0->mac, 0, &edev0->info)) < 0) {
zxlogf(ERROR, "eth: bind: ethermac query failed: %d\n", status);
goto fail;
}
diff --git a/system/dev/ethernet/ethertap/ethertap.cpp b/system/dev/ethernet/ethertap/ethertap.cpp
index 5cbe84b..915522c 100644
--- a/system/dev/ethernet/ethertap/ethertap.cpp
+++ b/system/dev/ethernet/ethertap/ethertap.cpp
@@ -9,6 +9,7 @@
#include <fbl/type_support.h>
#include <pretty/hexdump.h>
#include <zircon/compiler.h>
+#include <zircon/device/ethernet.h>
#include <stdio.h>
#include <string.h>
@@ -124,13 +125,13 @@
ethmac_proxy_.reset();
}
-zx_status_t TapDevice::EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy) {
+zx_status_t TapDevice::EthmacStart(const ethmac_ifc_t* ifc) {
ethertap_trace("EthmacStart\n");
fbl::AutoLock lock(&lock_);
if (ethmac_proxy_ != nullptr) {
return ZX_ERR_ALREADY_BOUND;
} else {
- ethmac_proxy_.swap(proxy);
+ ethmac_proxy_ = fbl::make_unique<ddk::EthmacIfcProxy>(ifc);
ethmac_proxy_->Status(online_ ? ETH_STATUS_ONLINE : 0u);
}
return ZX_OK;
@@ -144,9 +145,9 @@
uint8_t temp_buf[ETHERTAP_MAX_MTU + sizeof(ethertap_socket_header_t)];
auto header = reinterpret_cast<ethertap_socket_header*>(temp_buf);
uint8_t* data = temp_buf + sizeof(ethertap_socket_header_t);
- size_t length = netbuf->len;
+ size_t length = netbuf->data_size;
ZX_DEBUG_ASSERT(length <= mtu_);
- memcpy(data, netbuf->data, length);
+ memcpy(data, netbuf->data_buffer, length);
header->type = ETHERTAP_MSG_PACKET;
if (unlikely(options_ & ETHERTAP_OPT_TRACE_PACKETS)) {
@@ -162,7 +163,8 @@
return status == ZX_ERR_SHOULD_WAIT ? ZX_ERR_UNAVAILABLE : status;
}
-zx_status_t TapDevice::EthmacSetParam(uint32_t param, int32_t value, void* data) {
+zx_status_t TapDevice::EthmacSetParam(uint32_t param, int32_t value, const void* data,
+ size_t data_size) {
fbl::AutoLock lock(&lock_);
if (!(options_ & ETHERTAP_OPT_REPORT_PARAM) || dead_) {
return ZX_ERR_NOT_SUPPORTED;
@@ -185,7 +187,7 @@
// Send the final byte of each address, sorted lowest-to-highest.
uint32_t i;
for (i = 0; i < static_cast<uint32_t>(value) && i < sizeof(send_buf.report.data); i++) {
- send_buf.report.data[i] = static_cast<uint8_t*>(data)[i * ETH_MAC_SIZE + 5];
+ send_buf.report.data[i] = static_cast<const uint8_t*>(data)[i * ETH_MAC_SIZE + 5];
}
send_buf.report.data_length = i;
qsort(send_buf.report.data, send_buf.report.data_length, 1,
diff --git a/system/dev/ethernet/ethertap/ethertap.h b/system/dev/ethernet/ethertap/ethertap.h
index a111f55..b675e3a 100644
--- a/system/dev/ethernet/ethertap/ethertap.h
+++ b/system/dev/ethernet/ethertap/ethertap.h
@@ -38,9 +38,10 @@
zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* info);
void EthmacStop();
- zx_status_t EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy);
+ zx_status_t EthmacStart(const ethmac_ifc_t* ifc);
zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf);
- zx_status_t EthmacSetParam(uint32_t param, int32_t value, void* data);
+ zx_status_t EthmacSetParam(uint32_t param, int32_t value, const void* data,
+ size_t data_size);
// No DMA capability, so return invalid handle for get_bti
zx_handle_t EthmacGetBti();
int Thread();
diff --git a/system/dev/ethernet/rndis/rndishost.c b/system/dev/ethernet/rndis/rndishost.c
index 50b4895..5d99305 100644
--- a/system/dev/ethernet/rndis/rndishost.c
+++ b/system/dev/ethernet/rndis/rndishost.c
@@ -11,6 +11,7 @@
#include <ddk/protocol/ethernet.h>
#include <ddk/protocol/usb.h>
#include <ddk/usb/usb.h>
+#include <zircon/device/ethernet.h>
#include <zircon/hw/usb-cdc.h>
#include <zircon/hw/usb.h>
#include <zircon/listnode.h>
@@ -53,8 +54,7 @@
uint64_t tx_endpoint_delay; // wait time between 2 transmit requests
// Interface to the ethernet layer.
- ethmac_ifc_t* ifc;
- void* cookie;
+ ethmac_ifc_t ifc;
mtx_t mutex;
} rndishost_t;
@@ -136,7 +136,7 @@
}
usb_reset_endpoint(ð->usb, eth->bulk_in_addr);
}
- if ((request->response.status == ZX_OK) && eth->ifc) {
+ if ((request->response.status == ZX_OK) && eth->ifc.ops) {
size_t len = request->response.actual;
uint8_t* read_data;
@@ -147,7 +147,7 @@
return;
}
- eth->ifc->recv(eth->cookie, read_data, len, 0);
+ ethmac_ifc_recv(ð->ifc, read_data, len, 0);
}
// TODO: Only usb_request_queue if the device is online.
@@ -216,22 +216,21 @@
static void rndishost_stop(void* ctx) {
rndishost_t* eth = (rndishost_t*)ctx;
mtx_lock(ð->mutex);
- eth->ifc = NULL;
+ eth->ifc.ops = NULL;
mtx_unlock(ð->mutex);
}
-static zx_status_t rndishost_start(void* ctx, ethmac_ifc_t* ifc, void* cookie) {
+static zx_status_t rndishost_start(void* ctx, const ethmac_ifc_t* ifc) {
rndishost_t* eth = (rndishost_t*)ctx;
zx_status_t status = ZX_OK;
mtx_lock(ð->mutex);
- if (eth->ifc) {
+ if (eth->ifc.ops) {
status = ZX_ERR_ALREADY_BOUND;
} else {
- eth->ifc = ifc;
- eth->cookie = cookie;
+ eth->ifc = *ifc;
// TODO: Check that the device is online before sending ETH_STATUS_ONLINE.
- eth->ifc->status(eth->cookie, ETH_STATUS_ONLINE);
+ ethmac_ifc_status(ð->ifc, ETH_STATUS_ONLINE);
}
mtx_unlock(ð->mutex);
@@ -239,9 +238,9 @@
}
static zx_status_t rndishost_queue_tx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
- size_t length = netbuf->len;
+ size_t length = netbuf->data_size;
rndishost_t* eth = (rndishost_t*)ctx;
- uint8_t* byte_data = netbuf->data;
+ uint8_t* byte_data = netbuf->data_buffer;
zx_status_t status = ZX_OK;
mtx_lock(ð->mutex);
@@ -292,7 +291,8 @@
rndishost_free(eth);
}
-static zx_status_t rndishost_set_param(void *ctx, uint32_t param, int32_t value, void* data) {
+static zx_status_t rndishost_set_param(void *ctx, uint32_t param, int32_t value, const void* data,
+ size_t data_size) {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -509,7 +509,7 @@
eth->bulk_in_addr = bulk_in_addr;
eth->bulk_out_addr = bulk_out_addr;
eth->intr_addr = intr_addr;
- eth->ifc = NULL;
+ eth->ifc.ops = NULL;
memcpy(ð->usb, &usb, sizeof(eth->usb));
for (int i = 0; i < READ_REQ_COUNT; i++) {
diff --git a/system/dev/ethernet/usb-cdc-ecm/usb-cdc-ecm.c b/system/dev/ethernet/usb-cdc-ecm/usb-cdc-ecm.c
index d224113..e7e999e 100644
--- a/system/dev/ethernet/usb-cdc-ecm/usb-cdc-ecm.c
+++ b/system/dev/ethernet/usb-cdc-ecm/usb-cdc-ecm.c
@@ -9,6 +9,7 @@
#include <ddk/protocol/ethernet.h>
#include <ddk/protocol/usb.h>
#include <ddk/usb/usb.h>
+#include <zircon/device/ethernet.h>
#include <zircon/hw/usb-cdc.h>
#include <lib/sync/completion.h>
@@ -44,8 +45,7 @@
usb_protocol_t usb;
mtx_t ethmac_mutex;
- ethmac_ifc_t* ethmac_ifc;
- void* ethmac_cookie;
+ ethmac_ifc_t ethmac_ifc;
// Device attributes
uint8_t mac_addr[ETH_MAC_SIZE];
@@ -81,11 +81,11 @@
mtx_lock(&ctx->tx_mutex);
ctx->unbound = true;
- if (ctx->ethmac_ifc) {
+ if (ctx->ethmac_ifc.ops) {
ethmac_netbuf_t* netbuf;
while ((netbuf = list_remove_head_type(&ctx->tx_pending_infos, ethmac_netbuf_t, node)) !=
NULL) {
- ctx->ethmac_ifc->complete_tx(ctx->ethmac_cookie, netbuf, ZX_ERR_PEER_CLOSED);
+ ethmac_ifc_complete_tx(&ctx->ethmac_ifc, netbuf, ZX_ERR_PEER_CLOSED);
}
}
mtx_unlock(&ctx->tx_mutex);
@@ -130,16 +130,16 @@
if (is_online) {
zxlogf(INFO, "%s: connected to network\n", module_name);
ctx->online = true;
- if (ctx->ethmac_ifc) {
- ctx->ethmac_ifc->status(ctx->ethmac_cookie, ETH_STATUS_ONLINE);
+ if (ctx->ethmac_ifc.ops) {
+ ethmac_ifc_status(&ctx->ethmac_ifc, ETH_STATUS_ONLINE);
} else {
zxlogf(ERROR, "%s: not connected to ethermac interface\n", module_name);
}
} else {
zxlogf(INFO, "%s: no connection to network\n", module_name);
ctx->online = false;
- if (ctx->ethmac_ifc) {
- ctx->ethmac_ifc->status(ctx->ethmac_cookie, 0);
+ if (ctx->ethmac_ifc.ops) {
+ ethmac_ifc_status(&ctx->ethmac_ifc, 0);
}
}
@@ -147,14 +147,15 @@
mtx_unlock(&ctx->ethmac_mutex);
}
-static zx_status_t ethmac_query(void* ctx, uint32_t options, ethmac_info_t* info) {
+static zx_status_t ecm_ethmac_query(void* ctx, uint32_t options, ethmac_info_t* info) {
ecm_ctx_t* eth = ctx;
zxlogf(TRACE, "%s: %s called\n", module_name, __FUNCTION__);
// No options are supported
if (options) {
- zxlogf(ERROR, "%s: unexpected options (0x%"PRIx32") to ethmac_query\n", module_name, options);
+ zxlogf(ERROR, "%s: unexpected options (0x%"PRIx32") to ecm_ethmac_query\n", module_name,
+ options);
return ZX_ERR_INVALID_ARGS;
}
@@ -165,26 +166,25 @@
return ZX_OK;
}
-static void ethmac_stop(void* cookie) {
+static void ecm_ethmac_stop(void* cookie) {
zxlogf(TRACE, "%s: %s called\n", module_name, __FUNCTION__);
ecm_ctx_t* ctx = cookie;
mtx_lock(&ctx->ethmac_mutex);
- ctx->ethmac_ifc = NULL;
+ ctx->ethmac_ifc.ops = NULL;
mtx_unlock(&ctx->ethmac_mutex);
}
-static zx_status_t ethmac_start(void* ctx_cookie, ethmac_ifc_t* ifc, void* ethmac_cookie) {
+static zx_status_t ecm_ethmac_start(void* ctx_cookie, const ethmac_ifc_t* ifc) {
zxlogf(TRACE, "%s: %s called\n", module_name, __FUNCTION__);
ecm_ctx_t* ctx = ctx_cookie;
zx_status_t status = ZX_OK;
mtx_lock(&ctx->ethmac_mutex);
- if (ctx->ethmac_ifc) {
+ if (ctx->ethmac_ifc.ops) {
status = ZX_ERR_ALREADY_BOUND;
} else {
- ctx->ethmac_ifc = ifc;
- ctx->ethmac_cookie = ethmac_cookie;
- ctx->ethmac_ifc->status(ethmac_cookie, ctx->online ? ETH_STATUS_ONLINE : 0);
+ ctx->ethmac_ifc = *ifc;
+ ethmac_ifc_status(&ctx->ethmac_ifc, ctx->online ? ETH_STATUS_ONLINE : 0);
}
mtx_unlock(&ctx->ethmac_mutex);
@@ -203,8 +203,8 @@
}
static zx_status_t send_locked(ecm_ctx_t* ctx, ethmac_netbuf_t* netbuf) {
- uint8_t* byte_data = netbuf->data;
- size_t length = netbuf->len;
+ uint8_t* byte_data = netbuf->data_buffer;
+ size_t length = netbuf->data_size;
// Make sure that we can get all of the tx buffers we need to use
usb_request_t* tx_req = list_remove_head_type(&ctx->tx_txn_bufs, usb_request_t, node);
@@ -264,8 +264,8 @@
mtx_unlock(&ctx->tx_mutex);
mtx_lock(&ctx->ethmac_mutex);
- if (additional_tx_queued && ctx->ethmac_ifc) {
- ctx->ethmac_ifc->complete_tx(ctx->ethmac_cookie, netbuf, send_status);
+ if (additional_tx_queued && ctx->ethmac_ifc.ops) {
+ ethmac_ifc_complete_tx(&ctx->ethmac_ifc, netbuf, send_status);
}
mtx_unlock(&ctx->ethmac_mutex);
@@ -287,8 +287,8 @@
}
mtx_lock(&ctx->ethmac_mutex);
- if (ctx->ethmac_ifc) {
- ctx->ethmac_ifc->recv(ctx->ethmac_cookie, read_data, len, 0);
+ if (ctx->ethmac_ifc.ops) {
+ ethmac_ifc_recv(&ctx->ethmac_ifc, read_data, len, 0);
}
mtx_unlock(&ctx->ethmac_mutex);
}
@@ -325,9 +325,9 @@
usb_request_queue(&ctx->usb, request);
}
-static zx_status_t ethmac_queue_tx(void* cookie, uint32_t options, ethmac_netbuf_t* netbuf) {
+static zx_status_t ecm_ethmac_queue_tx(void* cookie, uint32_t options, ethmac_netbuf_t* netbuf) {
ecm_ctx_t* ctx = cookie;
- size_t length = netbuf->len;
+ size_t length = netbuf->data_size;
zx_status_t status;
if (length > ctx->mtu || length == 0) {
@@ -352,16 +352,17 @@
return status;
}
-static zx_status_t ethmac_set_param(void *cookie, uint32_t param, int32_t value, void* data) {
+static zx_status_t ecm_ethmac_set_param(void *cookie, uint32_t param, int32_t value,
+ const void* data, size_t data_size) {
return ZX_ERR_NOT_SUPPORTED;
}
static ethmac_protocol_ops_t ethmac_ops = {
- .query = ethmac_query,
- .stop = ethmac_stop,
- .start = ethmac_start,
- .queue_tx = ethmac_queue_tx,
- .set_param = ethmac_set_param,
+ .query = ecm_ethmac_query,
+ .stop = ecm_ethmac_stop,
+ .start = ecm_ethmac_start,
+ .queue_tx = ecm_ethmac_queue_tx,
+ .set_param = ecm_ethmac_set_param,
};
static void ecm_interrupt_complete(usb_request_t* request, void* cookie) {
diff --git a/system/dev/ethernet/usb-cdc-function/cdc-eth-function.c b/system/dev/ethernet/usb-cdc-function/cdc-eth-function.c
index 6f1dd09..647ff8c 100644
--- a/system/dev/ethernet/usb-cdc-function/cdc-eth-function.c
+++ b/system/dev/ethernet/usb-cdc-function/cdc-eth-function.c
@@ -21,6 +21,7 @@
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/device/usb-peripheral.h>
+#include <zircon/device/ethernet.h>
#include <zircon/hw/usb-cdc.h>
#define BULK_REQ_SIZE 2048
@@ -45,8 +46,7 @@
uint8_t mac_addr[ETH_MAC_SIZE];
mtx_t ethmac_mutex;
- ethmac_ifc_t* ethmac_ifc;
- void* ethmac_cookie;
+ ethmac_ifc_t ethmac_ifc;
bool online;
mtx_t tx_mutex;
@@ -187,22 +187,21 @@
zxlogf(TRACE, "%s:\n", __FUNCTION__);
usb_cdc_t* cdc = cookie;
mtx_lock(&cdc->ethmac_mutex);
- cdc->ethmac_ifc = NULL;
+ cdc->ethmac_ifc.ops = NULL;
mtx_unlock(&cdc->ethmac_mutex);
}
-static zx_status_t cdc_ethmac_start(void* ctx_cookie, ethmac_ifc_t* ifc, void* ethmac_cookie) {
+static zx_status_t cdc_ethmac_start(void* ctx_cookie, const ethmac_ifc_t* ifc) {
zxlogf(TRACE, "%s:\n", __FUNCTION__);
usb_cdc_t* cdc = ctx_cookie;
zx_status_t status = ZX_OK;
mtx_lock(&cdc->ethmac_mutex);
- if (cdc->ethmac_ifc) {
+ if (cdc->ethmac_ifc.ops) {
status = ZX_ERR_ALREADY_BOUND;
} else {
- cdc->ethmac_ifc = ifc;
- cdc->ethmac_cookie = ethmac_cookie;
- cdc->ethmac_ifc->status(ethmac_cookie, cdc->online ? ETH_STATUS_ONLINE : 0);
+ cdc->ethmac_ifc = *ifc;
+ ethmac_ifc_status(&cdc->ethmac_ifc, cdc->online ? ETH_STATUS_ONLINE : 0);
}
mtx_unlock(&cdc->ethmac_mutex);
@@ -210,8 +209,8 @@
}
static zx_status_t cdc_send_locked(usb_cdc_t* cdc, ethmac_netbuf_t* netbuf) {
- uint8_t* byte_data = netbuf->data;
- size_t length = netbuf->len;
+ uint8_t* byte_data = netbuf->data_buffer;
+ size_t length = netbuf->data_size;
// Make sure that we can get all of the tx buffers we need to use
usb_request_t* tx_req = list_remove_head_type(&cdc->bulk_in_reqs, usb_request_t, node);
@@ -237,7 +236,7 @@
static zx_status_t cdc_ethmac_queue_tx(void* cookie, uint32_t options, ethmac_netbuf_t* netbuf) {
usb_cdc_t* cdc = cookie;
- size_t length = netbuf->len;
+ size_t length = netbuf->data_size;
zx_status_t status;
if (!cdc->online || length > ETH_MTU || length == 0) {
@@ -261,7 +260,8 @@
return status;
}
-static zx_status_t ethmac_set_param(void *cookie, uint32_t param, int32_t value, void* data) {
+static zx_status_t cdc_ethmac_set_param(void *cookie, uint32_t param, int32_t value,
+ const void* data, size_t data_size) {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -270,7 +270,7 @@
.stop = cdc_ethmac_stop,
.start = cdc_ethmac_start,
.queue_tx = cdc_ethmac_queue_tx,
- .set_param = ethmac_set_param,
+ .set_param = cdc_ethmac_set_param,
};
static void cdc_intr_complete(usb_request_t* req, void* cookie) {
@@ -355,10 +355,10 @@
if (req->response.status == ZX_OK) {
mtx_lock(&cdc->ethmac_mutex);
- if (cdc->ethmac_ifc) {
+ if (cdc->ethmac_ifc.ops) {
uint8_t* data = NULL;
usb_function_req_mmap(&cdc->function, req, (void*)&data);
- cdc->ethmac_ifc->recv(cdc->ethmac_cookie, data, req->response.actual, 0);
+ ethmac_ifc_recv(&cdc->ethmac_ifc, data, req->response.actual, 0);
}
mtx_unlock(&cdc->ethmac_mutex);
}
@@ -387,8 +387,8 @@
if (additional_tx_queued) {
mtx_lock(&cdc->ethmac_mutex);
- if (cdc->ethmac_ifc) {
- cdc->ethmac_ifc->complete_tx(cdc->ethmac_cookie, netbuf, send_status);
+ if (cdc->ethmac_ifc.ops) {
+ ethmac_ifc_complete_tx(&cdc->ethmac_ifc, netbuf, send_status);
}
mtx_unlock(&cdc->ethmac_mutex);
}
@@ -423,8 +423,8 @@
mtx_lock(&cdc->ethmac_mutex);
cdc->online = false;
- if (cdc->ethmac_ifc) {
- cdc->ethmac_ifc->status(cdc->ethmac_cookie, 0);
+ if (cdc->ethmac_ifc.ops) {
+ ethmac_ifc_status(&cdc->ethmac_ifc, 0);
}
mtx_unlock(&cdc->ethmac_mutex);
@@ -484,8 +484,8 @@
mtx_lock(&cdc->ethmac_mutex);
cdc->online = online;
- if (cdc->ethmac_ifc) {
- cdc->ethmac_ifc->status(cdc->ethmac_cookie, online ? ETH_STATUS_ONLINE : 0);
+ if (cdc->ethmac_ifc.ops) {
+ ethmac_ifc_status(&cdc->ethmac_ifc, online ? ETH_STATUS_ONLINE : 0);
}
mtx_unlock(&cdc->ethmac_mutex);
@@ -505,11 +505,11 @@
mtx_lock(&cdc->tx_mutex);
cdc->unbound = true;
- if (cdc->ethmac_ifc) {
+ if (cdc->ethmac_ifc.ops) {
ethmac_netbuf_t* netbuf;
while ((netbuf = list_remove_head_type(&cdc->tx_pending_infos, ethmac_netbuf_t, node)) !=
NULL) {
- cdc->ethmac_ifc->complete_tx(cdc->ethmac_cookie, netbuf, ZX_ERR_PEER_CLOSED);
+ ethmac_ifc_complete_tx(&cdc->ethmac_ifc, netbuf, ZX_ERR_PEER_CLOSED);
}
}
mtx_unlock(&cdc->tx_mutex);
diff --git a/system/dev/i2c/intel-i2c/intel-i2c-controller.c b/system/dev/i2c/intel-i2c/intel-i2c-controller.c
index 6745f68..cc7e048 100644
--- a/system/dev/i2c/intel-i2c/intel-i2c-controller.c
+++ b/system/dev/i2c/intel-i2c/intel-i2c-controller.c
@@ -6,7 +6,9 @@
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
+#include <ddk/protocol/auxdata.h>
#include <ddk/protocol/pci.h>
+#include <ddk/protocol/pci-lib.h>
#include <hw/reg.h>
#include <errno.h>
#include <fcntl.h>
@@ -741,17 +743,16 @@
pci_protocol_t* pci) {
// get child info from aux data, max 4
// TODO: this seems nonstandard to device model
- uint8_t childdata[sizeof(auxdata_i2c_device_t) * 4];
+ auxdata_i2c_device_t childdata[4];
memset(childdata, 0, sizeof(childdata));
- uint32_t actual;
- zx_status_t status = pci_get_auxdata(pci, "i2c-child", childdata, sizeof(childdata),
- &actual);
+ size_t actual;
+ zx_status_t status = pci_get_auxdata(pci, "i2c-child", childdata, sizeof(childdata), &actual);
if (status != ZX_OK) {
return;
}
- auxdata_i2c_device_t* child = (auxdata_i2c_device_t*)childdata;
+ auxdata_i2c_device_t* child = &childdata[0];
uint32_t count = actual / sizeof(auxdata_i2c_device_t);
uint32_t bus_speed = 0;
while (count--) {
diff --git a/system/dev/input/focaltech/ft3x27.cpp b/system/dev/input/focaltech/ft3x27.cpp
index 3badb17..4dd1651 100644
--- a/system/dev/input/focaltech/ft3x27.cpp
+++ b/system/dev/input/focaltech/ft3x27.cpp
@@ -52,7 +52,7 @@
for (uint i = 0; i < kMaxPoints; i++) {
ParseReport(&ft_rpt_.fingers[i], &i2c_buf[i * kFingerRptSize + 1]);
}
- if (proxy_.is_valid()) {
+ if (true /*proxy_.is_valid()*/) {
proxy_.IoQueue(reinterpret_cast<uint8_t*>(&ft_rpt_), sizeof(ft3x27_touch_t));
}
} else {
@@ -125,12 +125,12 @@
return ZX_OK;
}
-zx_status_t Ft3x27Device::HidBusQuery(uint32_t options, hid_info_t* info) {
+zx_status_t Ft3x27Device::HidbusQuery(uint32_t options, hid_info_t* info) {
if (!info) {
return ZX_ERR_INVALID_ARGS;
}
info->dev_num = 0;
- info->dev_class = HID_DEV_CLASS_OTHER;
+ info->device_class = HID_DEVICE_CLASS_OTHER;
info->boot_device = false;
return ZX_OK;
@@ -151,12 +151,12 @@
thrd_join(thread_, NULL);
{
fbl::AutoLock lock(&proxy_lock_);
- proxy_.clear();
+ //proxy_.clear();
}
return ZX_OK;
}
-zx_status_t Ft3x27Device::HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len) {
+zx_status_t Ft3x27Device::HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len) {
const uint8_t* desc_ptr;
uint8_t* buf;
@@ -171,43 +171,44 @@
return ZX_OK;
}
-zx_status_t Ft3x27Device::HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+zx_status_t Ft3x27Device::HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
size_t len, size_t* out_len) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Ft3x27Device::HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+zx_status_t Ft3x27Device::HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data,
size_t len) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Ft3x27Device::HidBusGetIdle(uint8_t rpt_id, uint8_t* duration) {
+zx_status_t Ft3x27Device::HidbusGetIdle(uint8_t rpt_id, uint8_t* duration) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Ft3x27Device::HidBusSetIdle(uint8_t rpt_id, uint8_t duration) {
+zx_status_t Ft3x27Device::HidbusSetIdle(uint8_t rpt_id, uint8_t duration) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Ft3x27Device::HidBusGetProtocol(uint8_t* protocol) {
+zx_status_t Ft3x27Device::HidbusGetProtocol(uint8_t* protocol) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Ft3x27Device::HidBusSetProtocol(uint8_t protocol) {
+zx_status_t Ft3x27Device::HidbusSetProtocol(uint8_t protocol) {
return ZX_OK;
}
-void Ft3x27Device::HidBusStop() {
+void Ft3x27Device::HidbusStop() {
fbl::AutoLock lock(&proxy_lock_);
- proxy_.clear();
+ //proxy_.clear();
}
-zx_status_t Ft3x27Device::HidBusStart(ddk::HidBusIfcProxy proxy) {
+zx_status_t Ft3x27Device::HidbusStart(const hidbus_ifc_t* ifc) {
fbl::AutoLock lock(&proxy_lock_);
- if (proxy_.is_valid()) {
+ if (true /*proxy_.is_valid()*/) {
zxlogf(ERROR, "ft3x27: Already bound!\n");
return ZX_ERR_ALREADY_BOUND;
} else {
+ ddk::HidbusIfcProxy proxy(ifc);
proxy_ = proxy;
zxlogf(INFO, "ft3x27: started\n");
}
@@ -235,4 +236,4 @@
extern "C" zx_status_t ft3x27_bind(void* ctx, zx_device_t* device, void** cookie) {
return ft::Ft3x27Device::Create(device);
-}
\ No newline at end of file
+}
diff --git a/system/dev/input/focaltech/ft3x27.h b/system/dev/input/focaltech/ft3x27.h
index 6c3ffb3..13461ef 100644
--- a/system/dev/input/focaltech/ft3x27.h
+++ b/system/dev/input/focaltech/ft3x27.h
@@ -56,7 +56,7 @@
namespace ft {
class Ft3x27Device : public ddk::Device<Ft3x27Device, ddk::Unbindable>,
- public ddk::HidBusProtocol<Ft3x27Device> {
+ public ddk::HidbusProtocol<Ft3x27Device> {
public:
Ft3x27Device(zx_device_t* device);
@@ -65,19 +65,19 @@
void DdkRelease();
void DdkUnbind() __TA_EXCLUDES(proxy_lock_);
- // HidBus required methods
- void HidBusStop();
- zx_status_t HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
- zx_status_t HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+ // Hidbus required methods
+ void HidbusStop();
+ zx_status_t HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
+ zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
size_t len, size_t* out_len);
- zx_status_t HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+ zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data,
size_t len);
- zx_status_t HidBusGetIdle(uint8_t rpt_id, uint8_t* duration);
- zx_status_t HidBusSetIdle(uint8_t rpt_id, uint8_t duration);
- zx_status_t HidBusGetProtocol(uint8_t* protocol);
- zx_status_t HidBusSetProtocol(uint8_t protocol);
- zx_status_t HidBusStart(ddk::HidBusIfcProxy proxy) __TA_EXCLUDES(proxy_lock_);
- zx_status_t HidBusQuery(uint32_t options, hid_info_t* info) __TA_EXCLUDES(proxy_lock_);
+ zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration);
+ zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration);
+ zx_status_t HidbusGetProtocol(uint8_t* protocol);
+ zx_status_t HidbusSetProtocol(uint8_t protocol);
+ zx_status_t HidbusStart(const hidbus_ifc_t* ifc) __TA_EXCLUDES(proxy_lock_);
+ zx_status_t HidbusQuery(uint32_t options, hid_info_t* info) __TA_EXCLUDES(proxy_lock_);
private:
//Only one I2c channel is passed to this driver, so index should always
@@ -114,6 +114,6 @@
fbl::atomic<bool> running_;
fbl::Mutex proxy_lock_;
- ddk::HidBusIfcProxy proxy_ __TA_GUARDED(proxy_lock_);
+ ddk::HidbusIfcProxy proxy_ __TA_GUARDED(proxy_lock_);
};
-}
\ No newline at end of file
+}
diff --git a/system/dev/input/hid/hid.c b/system/dev/input/hid/hid.c
index 9b73b46..25b78ad 100644
--- a/system/dev/input/hid/hid.c
+++ b/system/dev/input/hid/hid.c
@@ -90,43 +90,43 @@
return hid->hid.ops->query(hid->hid.ctx, options, info);
}
-static inline zx_status_t hid_op_start(hid_device_t* hid, hidbus_ifc_t* ifc, void* cookie) {
- return hid->hid.ops->start(hid->hid.ctx, ifc, cookie);
+static inline zx_status_t hid_op_start(hid_device_t* hid, const hidbus_ifc_t* ifc) {
+ return hidbus_start(&hid->hid, ifc);
}
static inline void hid_op_stop(hid_device_t* hid) {
- hid->hid.ops->stop(hid->hid.ctx);
+ hidbus_stop(&hid->hid);
}
static inline zx_status_t hid_op_get_descriptor(hid_device_t* hid, uint8_t desc_type,
void** data, size_t* len) {
- return hid->hid.ops->get_descriptor(hid->hid.ctx, desc_type, data, len);
+ return hidbus_get_descriptor(&hid->hid, desc_type, data, len);
}
static inline zx_status_t hid_op_get_report(hid_device_t* hid, uint8_t rpt_type, uint8_t rpt_id,
void* data, size_t len, size_t* out_len) {
- return hid->hid.ops->get_report(hid->hid.ctx, rpt_type, rpt_id, data, len, out_len);
+ return hidbus_get_report(&hid->hid, rpt_type, rpt_id, data, len, out_len);
}
static inline zx_status_t hid_op_set_report(hid_device_t* hid, uint8_t rpt_type, uint8_t rpt_id,
void* data, size_t len) {
- return hid->hid.ops->set_report(hid->hid.ctx, rpt_type, rpt_id, data, len);
+ return hidbus_set_report(&hid->hid, rpt_type, rpt_id, data, len);
}
static inline zx_status_t hid_op_get_idle(hid_device_t* hid, uint8_t rpt_id, uint8_t* duration) {
- return hid->hid.ops->get_idle(hid->hid.ctx, rpt_id, duration);
+ return hidbus_get_idle(&hid->hid, rpt_id, duration);
}
static inline zx_status_t hid_op_set_idle(hid_device_t* hid, uint8_t rpt_id, uint8_t duration) {
- return hid->hid.ops->set_idle(hid->hid.ctx, rpt_id, duration);
+ return hidbus_set_idle(&hid->hid, rpt_id, duration);
}
static inline zx_status_t hid_op_get_protocol(hid_device_t* hid, uint8_t* protocol) {
- return hid->hid.ops->get_protocol(hid->hid.ctx, protocol);
+ return hidbus_get_protocol(&hid->hid, protocol);
}
static inline zx_status_t hid_op_set_protocol(hid_device_t* hid, uint8_t protocol) {
- return hid->hid.ops->set_protocol(hid->hid.ctx, protocol);
+ return hidbus_set_protocol(&hid->hid, protocol);
}
@@ -155,9 +155,10 @@
int* reply = out_buf;
*reply = INPUT_PROTO_NONE;
- if (hid->info.dev_class == HID_DEV_CLASS_KBD || hid->info.dev_class == HID_DEV_CLASS_KBD_POINTER) {
+ if (hid->info.device_class == HID_DEVICE_CLASS_KBD ||
+ hid->info.device_class == HID_DEVICE_CLASS_KBD_POINTER) {
*reply = INPUT_PROTO_KBD;
- } else if (hid->info.dev_class == HID_DEV_CLASS_POINTER) {
+ } else if (hid->info.device_class == HID_DEVICE_CLASS_POINTER) {
*reply = INPUT_PROTO_MOUSE;
}
*out_actual = sizeof(*reply);
@@ -586,7 +587,7 @@
#if BOOT_MOUSE_HACK
// Ignore the HID report descriptor from the device, since we're putting
// the device into boot protocol mode.
- if (dev->info.dev_class == HID_DEV_CLASS_POINTER) {
+ if (dev->info.device_class == HID_DEVICE_CLASS_POINTER) {
if (dev->info.boot_device) {
zxlogf(INFO, "hid: boot mouse hack for \"%s\": "
"report count (%zu->1), "
@@ -729,7 +730,8 @@
.release = hid_release_device,
};
-void hid_io_queue(void* cookie, const uint8_t* buf, size_t len) {
+void hid_io_queue(void* cookie, const void* _buf, size_t len) {
+ const uint8_t* buf = _buf;
hid_device_t* hid = cookie;
mtx_lock(&hid->instance_lock);
@@ -825,7 +827,7 @@
mtx_unlock(&hid->instance_lock);
}
-hidbus_ifc_t hid_ifc = {
+hidbus_ifc_ops_t hid_ifc_ops = {
.io_queue = hid_io_queue,
};
@@ -861,14 +863,14 @@
}
// Disable numlock
- if (hiddev->info.dev_class == HID_DEV_CLASS_KBD) {
+ if (hiddev->info.device_class == HID_DEVICE_CLASS_KBD) {
uint8_t zero = 0;
hid_op_set_report(hiddev, HID_REPORT_TYPE_OUTPUT, 0, &zero, sizeof(zero));
// ignore failure for now
}
}
- status = hid_op_get_descriptor(hiddev, HID_DESC_TYPE_REPORT,
+ status = hid_op_get_descriptor(hiddev, HID_DESCRIPTION_TYPE_REPORT,
(void**)&hiddev->hid_report_desc, &hiddev->hid_report_desc_len);
if (status != ZX_OK) {
zxlogf(ERROR, "hid: could not retrieve HID report descriptor: %d\n", status);
@@ -903,7 +905,7 @@
}
// TODO: delay calling start until we've been opened by someone
- status = hid_op_start(hiddev, &hid_ifc, hiddev);
+ status = hid_op_start(hiddev, &(hidbus_ifc_t){&hid_ifc_ops, hiddev});
if (status != ZX_OK) {
zxlogf(ERROR, "hid: could not start hid device: %d\n", status);
device_remove(hiddev->zxdev);
diff --git a/system/dev/input/hidctl/hidctl.cpp b/system/dev/input/hidctl/hidctl.cpp
index a7f9aba..0cf1ea3 100644
--- a/system/dev/input/hidctl/hidctl.cpp
+++ b/system/dev/input/hidctl/hidctl.cpp
@@ -35,7 +35,7 @@
return ZX_ERR_INVALID_ARGS;
}
- if (config->dev_class > HID_DEV_CLASS_LAST) {
+ if (config->dev_class > HID_DEVICE_CLASS_LAST) {
return ZX_ERR_INVALID_ARGS;
}
@@ -104,41 +104,41 @@
// The thread will call DdkRemove when it exits the loop.
}
-zx_status_t HidDevice::HidBusQuery(uint32_t options, hid_info_t* info) {
+zx_status_t HidDevice::HidbusQuery(uint32_t options, hid_info_t* info) {
zxlogf(TRACE, "hidctl: query\n");
info->dev_num = 0;
- info->dev_class = dev_class_;
+ info->device_class = dev_class_;
info->boot_device = boot_device_;
return ZX_OK;
}
-zx_status_t HidDevice::HidBusStart(ddk::HidBusIfcProxy proxy) {
+zx_status_t HidDevice::HidbusStart(const hidbus_ifc_t* ifc) {
zxlogf(TRACE, "hidctl: start\n");
fbl::AutoLock lock(&lock_);
if (proxy_.is_valid()) {
return ZX_ERR_ALREADY_BOUND;
}
- proxy_ = proxy;
+ proxy_ = ddk::HidbusIfcProxy(ifc);
return ZX_OK;
}
-void HidDevice::HidBusStop() {
+void HidDevice::HidbusStop() {
zxlogf(TRACE, "hidctl: stop\n");
fbl::AutoLock lock(&lock_);
proxy_.clear();
}
-zx_status_t HidDevice::HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len) {
+zx_status_t HidDevice::HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len) {
zxlogf(TRACE, "hidctl: get descriptor %u\n", desc_type);
if (data == nullptr || len == nullptr) {
return ZX_ERR_INVALID_ARGS;
}
- if (desc_type != HID_DESC_TYPE_REPORT) {
+ if (desc_type != HID_DESCRIPTION_TYPE_REPORT) {
return ZX_ERR_NOT_FOUND;
}
@@ -151,8 +151,8 @@
return ZX_OK;
}
-zx_status_t HidDevice::HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
- size_t* out_len) {
+zx_status_t HidDevice::HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id,
+ void* data, size_t len, size_t* out_len) {
zxlogf(TRACE, "hidctl: get report type=%u id=%u\n", rpt_type, rpt_id);
if (out_len == nullptr) {
@@ -163,35 +163,36 @@
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t HidDevice::HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len) {
+zx_status_t HidDevice::HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id,
+ const void* data, size_t len) {
zxlogf(TRACE, "hidctl: set report type=%u id=%u\n", rpt_type, rpt_id);
// TODO: send set report message over socket
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t HidDevice::HidBusGetIdle(uint8_t rpt_id, uint8_t* duration) {
+zx_status_t HidDevice::HidbusGetIdle(uint8_t rpt_id, uint8_t* duration) {
zxlogf(TRACE, "hidctl: get idle\n");
// TODO: send get idle message over socket
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t HidDevice::HidBusSetIdle(uint8_t rpt_id, uint8_t duration) {
+zx_status_t HidDevice::HidbusSetIdle(uint8_t rpt_id, uint8_t duration) {
zxlogf(TRACE, "hidctl: set idle\n");
// TODO: send set idle message over socket
return ZX_OK;
}
-zx_status_t HidDevice::HidBusGetProtocol(uint8_t* protocol) {
+zx_status_t HidDevice::HidbusGetProtocol(uint8_t* protocol) {
zxlogf(TRACE, "hidctl: get protocol\n");
// TODO: send get protocol message over socket
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t HidDevice::HidBusSetProtocol(uint8_t protocol) {
+zx_status_t HidDevice::HidbusSetProtocol(uint8_t protocol) {
zxlogf(TRACE, "hidctl: set protocol\n");
// TODO: send set protocol message over socket
diff --git a/system/dev/input/hidctl/hidctl.h b/system/dev/input/hidctl/hidctl.h
index a3d7b94..7714d14 100644
--- a/system/dev/input/hidctl/hidctl.h
+++ b/system/dev/input/hidctl/hidctl.h
@@ -27,24 +27,24 @@
};
class HidDevice : public ddk::Device<HidDevice, ddk::Unbindable>,
- public ddk::HidBusProtocol<HidDevice> {
+ public ddk::HidbusProtocol<HidDevice> {
public:
HidDevice(zx_device_t* device, const hid_ioctl_config* config, zx::socket data);
void DdkRelease();
void DdkUnbind();
- zx_status_t HidBusQuery(uint32_t options, hid_info_t* info);
- zx_status_t HidBusStart(ddk::HidBusIfcProxy proxy);
- void HidBusStop();
- zx_status_t HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
- zx_status_t HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
+ zx_status_t HidbusQuery(uint32_t options, hid_info_t* info);
+ zx_status_t HidbusStart(const hidbus_ifc_t* ifc);
+ void HidbusStop();
+ zx_status_t HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
+ zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
size_t* out_len);
- zx_status_t HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len);
- zx_status_t HidBusGetIdle(uint8_t rpt_id, uint8_t* duration);
- zx_status_t HidBusSetIdle(uint8_t rpt_id, uint8_t duration);
- zx_status_t HidBusGetProtocol(uint8_t* protocol);
- zx_status_t HidBusSetProtocol(uint8_t protocol);
+ zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data, size_t len);
+ zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration);
+ zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration);
+ zx_status_t HidbusGetProtocol(uint8_t* protocol);
+ zx_status_t HidbusSetProtocol(uint8_t protocol);
int Thread();
void Shutdown();
@@ -59,7 +59,7 @@
uint32_t mtu_ = 256; // TODO: set this based on report_desc_
fbl::Mutex lock_;
- ddk::HidBusIfcProxy proxy_ __TA_GUARDED(lock_);
+ ddk::HidbusIfcProxy proxy_ __TA_GUARDED(lock_);
zx::socket data_;
thrd_t thread_;
};
diff --git a/system/dev/input/i2c-hid/i2c-hid.c b/system/dev/input/i2c-hid/i2c-hid.c
index 283fe60..17178e2 100644
--- a/system/dev/input/i2c-hid/i2c-hid.c
+++ b/system/dev/input/i2c-hid/i2c-hid.c
@@ -47,7 +47,7 @@
zx_device_t* i2cdev;
mtx_t ifc_lock;
- hidbus_ifc_t* ifc;
+ hidbus_ifc_t ifc;
void* cookie;
i2c_hid_desc_t* hiddesc;
@@ -114,20 +114,19 @@
return ZX_ERR_INVALID_ARGS;
}
info->dev_num = 0;
- info->dev_class = HID_DEV_CLASS_OTHER;
+ info->device_class = HID_DEVICE_CLASS_OTHER;
info->boot_device = false;
return ZX_OK;
}
-static zx_status_t i2c_hid_start(void* ctx, hidbus_ifc_t* ifc, void* cookie) {
+static zx_status_t i2c_hid_start(void* ctx, const hidbus_ifc_t* ifc) {
i2c_hid_device_t* hid = ctx;
mtx_lock(&hid->ifc_lock);
- if (hid->ifc) {
+ if (hid->ifc.ops) {
mtx_unlock(&hid->ifc_lock);
return ZX_ERR_ALREADY_BOUND;
}
- hid->ifc = ifc;
- hid->cookie = cookie;
+ hid->ifc = *ifc;
mtx_unlock(&hid->ifc_lock);
return ZX_OK;
}
@@ -135,14 +134,13 @@
static void i2c_hid_stop(void* ctx) {
i2c_hid_device_t* hid = ctx;
mtx_lock(&hid->ifc_lock);
- hid->ifc = NULL;
- hid->cookie = NULL;
+ hid->ifc.ops = NULL;
mtx_unlock(&hid->ifc_lock);
}
static zx_status_t i2c_hid_get_descriptor(void* ctx, uint8_t desc_type,
void** data, size_t* len) {
- if (desc_type != HID_DESC_TYPE_REPORT) {
+ if (desc_type != HID_DESCRIPTION_TYPE_REPORT) {
return ZX_ERR_NOT_FOUND;
}
@@ -183,7 +181,7 @@
}
static zx_status_t i2c_hid_set_report(void* ctx, uint8_t rpt_type, uint8_t rpt_id,
- void* data, size_t len) {
+ const void* data, size_t len) {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -310,8 +308,8 @@
}
mtx_lock(&dev->ifc_lock);
- if (dev->ifc) {
- dev->ifc->io_queue(dev->cookie, buf + 2, report_len - 2);
+ if (dev->ifc.ops) {
+ hidbus_ifc_io_queue(&dev->ifc, buf + 2, report_len - 2);
}
mtx_unlock(&dev->ifc_lock);
@@ -403,8 +401,8 @@
mtx_unlock(&dev->i2c_lock);
mtx_lock(&dev->ifc_lock);
- if (dev->ifc) {
- dev->ifc->io_queue(dev->cookie, buf + 2, report_len - 2);
+ if (dev->ifc.ops) {
+ hidbus_ifc_io_queue(&dev->ifc, buf + 2, report_len - 2);
}
mtx_unlock(&dev->ifc_lock);
}
diff --git a/system/dev/input/usb-hid/usb-hid.c b/system/dev/input/usb-hid/usb-hid.c
index 57cf161..e017974 100644
--- a/system/dev/input/usb-hid/usb-hid.c
+++ b/system/dev/input/usb-hid/usb-hid.c
@@ -35,7 +35,7 @@
bool req_queued;
mtx_t lock;
- hidbus_ifc_t* ifc;
+ hidbus_ifc_t ifc;
void* cookie;
uint8_t interface;
@@ -63,8 +63,8 @@
break;
case ZX_OK:
mtx_lock(&hid->lock);
- if (hid->ifc) {
- hid->ifc->io_queue(hid->cookie, buffer, req->response.actual);
+ if (hid->ifc.ops) {
+ hidbus_ifc_io_queue(&hid->ifc, buffer, req->response.actual);
}
mtx_unlock(&hid->lock);
break;
@@ -88,20 +88,19 @@
}
usb_hid_device_t* hid = ctx;
info->dev_num = hid->info.dev_num;
- info->dev_class = hid->info.dev_class;
+ info->device_class = hid->info.device_class;
info->boot_device = hid->info.boot_device;
return ZX_OK;
}
-static zx_status_t usb_hid_start(void* ctx, hidbus_ifc_t* ifc, void* cookie) {
+static zx_status_t usb_hid_start(void* ctx, const hidbus_ifc_t* ifc) {
usb_hid_device_t* hid = ctx;
mtx_lock(&hid->lock);
- if (hid->ifc) {
+ if (hid->ifc.ops) {
mtx_unlock(&hid->lock);
return ZX_ERR_ALREADY_BOUND;
}
- hid->ifc = ifc;
- hid->cookie = cookie;
+ hid->ifc = *ifc;
if (!hid->req_queued) {
hid->req_queued = true;
usb_request_queue(&hid->usb, hid->req);
@@ -115,8 +114,7 @@
// this callback
usb_hid_device_t* hid = ctx;
mtx_lock(&hid->lock);
- hid->ifc = NULL;
- hid->cookie = NULL;
+ hid->ifc.ops = NULL;
mtx_unlock(&hid->lock);
}
@@ -173,11 +171,11 @@
}
static zx_status_t usb_hid_set_report(void* ctx, uint8_t rpt_type, uint8_t rpt_id,
- void* data, size_t len) {
+ const void* data, size_t len) {
usb_hid_device_t* hid = ctx;
return usb_hid_control(hid, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
USB_HID_SET_REPORT, (rpt_type << 8 | rpt_id),
- hid->interface, data, len, NULL);
+ hid->interface, (void*)data, len, NULL);
}
static zx_status_t usb_hid_get_idle(void* ctx, uint8_t rpt_id, uint8_t* duration) {
@@ -298,11 +296,11 @@
usbhid->hid_desc = hid_desc;
usbhid->info.boot_device = intf->bInterfaceSubClass == USB_HID_SUBCLASS_BOOT;
- usbhid->info.dev_class = HID_DEV_CLASS_OTHER;
+ usbhid->info.device_class = HID_DEVICE_CLASS_OTHER;
if (intf->bInterfaceProtocol == USB_HID_PROTOCOL_KBD) {
- usbhid->info.dev_class = HID_DEV_CLASS_KBD;
+ usbhid->info.device_class = HID_DEVICE_CLASS_KBD;
} else if (intf->bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE) {
- usbhid->info.dev_class = HID_DEV_CLASS_POINTER;
+ usbhid->info.device_class = HID_DEVICE_CLASS_POINTER;
}
status = usb_req_alloc(&usb, &usbhid->req, usb_ep_max_packet(endpt),
diff --git a/system/dev/light/ams-light/tcs3400.cpp b/system/dev/light/ams-light/tcs3400.cpp
index e845463..c5d0bc3 100644
--- a/system/dev/light/ams-light/tcs3400.cpp
+++ b/system/dev/light/ams-light/tcs3400.cpp
@@ -152,13 +152,11 @@
if (input_rpt_.illuminance > threshold_high) {
input_rpt_.event =
HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_VAL;
- proxy_.IoQueue(reinterpret_cast<uint8_t*>(&input_rpt_),
- sizeof(ambient_light_input_rpt_t));
+ proxy_.IoQueue(&input_rpt_, sizeof(ambient_light_input_rpt_t));
} else if (input_rpt_.illuminance < threshold_low) {
input_rpt_.event =
HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_VAL;
- proxy_.IoQueue(reinterpret_cast<uint8_t*>(&input_rpt_),
- sizeof(ambient_light_input_rpt_t));
+ proxy_.IoQueue(&input_rpt_, sizeof(ambient_light_input_rpt_t));
}
}
// If report could not be filled, we do not ioqueue
@@ -185,8 +183,7 @@
if (proxy_.is_valid()) {
FillInputRpt(); // We ioqueue even if report filling failed reporting bad state
input_rpt_.event = HID_USAGE_SENSOR_EVENT_PERIOD_EXCEEDED_VAL;
- proxy_.IoQueue(reinterpret_cast<uint8_t*>(&input_rpt_),
- sizeof(ambient_light_input_rpt_t));
+ proxy_.IoQueue(&input_rpt_, sizeof(ambient_light_input_rpt_t));
}
}
{
@@ -236,31 +233,31 @@
return ZX_OK;
}
-zx_status_t Tcs3400Device::HidBusStart(ddk::HidBusIfcProxy proxy) {
+zx_status_t Tcs3400Device::HidbusStart(const hidbus_ifc_t* ifc) {
fbl::AutoLock lock(&proxy_input_lock_);
if (proxy_.is_valid()) {
return ZX_ERR_ALREADY_BOUND;
} else {
- proxy_ = proxy;
+ proxy_ = ddk::HidbusIfcProxy(ifc);
}
return ZX_OK;
}
-zx_status_t Tcs3400Device::HidBusQuery(uint32_t options, hid_info_t* info) {
+zx_status_t Tcs3400Device::HidbusQuery(uint32_t options, hid_info_t* info) {
if (!info) {
return ZX_ERR_INVALID_ARGS;
}
info->dev_num = 0;
- info->dev_class = HID_DEV_CLASS_OTHER;
+ info->device_class = HID_DEVICE_CLASS_OTHER;
info->boot_device = false;
return ZX_OK;
}
-void Tcs3400Device::HidBusStop() {
+void Tcs3400Device::HidbusStop() {
}
-zx_status_t Tcs3400Device::HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len) {
+zx_status_t Tcs3400Device::HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len) {
const uint8_t* desc_ptr;
uint8_t* buf;
*len = get_ambient_light_report_desc(&desc_ptr);
@@ -274,7 +271,7 @@
return ZX_OK;
}
-zx_status_t Tcs3400Device::HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+zx_status_t Tcs3400Device::HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
size_t len, size_t* out_len) {
if (rpt_id != AMBIENT_LIGHT_RPT_ID_INPUT && rpt_id != AMBIENT_LIGHT_RPT_ID_FEATURE) {
return ZX_ERR_NOT_SUPPORTED;
@@ -297,7 +294,7 @@
return ZX_OK;
}
-zx_status_t Tcs3400Device::HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+zx_status_t Tcs3400Device::HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data,
size_t len) {
if (rpt_id != AMBIENT_LIGHT_RPT_ID_FEATURE) {
return ZX_ERR_NOT_SUPPORTED;
@@ -307,32 +304,32 @@
}
{
fbl::AutoLock lock(&feature_lock_);
- ambient_light_feature_rpt_t* out = static_cast<ambient_light_feature_rpt_t*>(data);
+ auto* out = static_cast<const ambient_light_feature_rpt_t*>(data);
feature_rpt_ = *out; // TA doesn't work on a memcpy taking an address as in &feature_rpt_
}
zx_port_packet packet = {TCS_CONFIGURE, ZX_PKT_TYPE_USER, ZX_OK, {}};
zx_status_t status = zx_port_queue(port_handle_, &packet);
if (status != ZX_OK) {
- zxlogf(ERROR, "Tcs3400Device::HidBusSetReport: zx_port_queue failed: %d\n", status);
+ zxlogf(ERROR, "Tcs3400Device::HidbusSetReport: zx_port_queue failed: %d\n", status);
return ZX_ERR_INTERNAL;
}
return ZX_OK;
}
-zx_status_t Tcs3400Device::HidBusGetIdle(uint8_t rpt_id, uint8_t* duration) {
+zx_status_t Tcs3400Device::HidbusGetIdle(uint8_t rpt_id, uint8_t* duration) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Tcs3400Device::HidBusSetIdle(uint8_t rpt_id, uint8_t duration) {
+zx_status_t Tcs3400Device::HidbusSetIdle(uint8_t rpt_id, uint8_t duration) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Tcs3400Device::HidBusGetProtocol(uint8_t* protocol) {
+zx_status_t Tcs3400Device::HidbusGetProtocol(uint8_t* protocol) {
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t Tcs3400Device::HidBusSetProtocol(uint8_t protocol) {
+zx_status_t Tcs3400Device::HidbusSetProtocol(uint8_t protocol) {
return ZX_OK;
}
diff --git a/system/dev/light/ams-light/tcs3400.h b/system/dev/light/ams-light/tcs3400.h
index e15147d..a848633 100644
--- a/system/dev/light/ams-light/tcs3400.h
+++ b/system/dev/light/ams-light/tcs3400.h
@@ -30,7 +30,7 @@
// complies with a HID descriptor that was manually scripted (i.e. - not
// reported by the device iteself).
class Tcs3400Device : public DeviceType,
- public ddk::HidBusProtocol<Tcs3400Device> {
+ public ddk::HidbusProtocol<Tcs3400Device> {
public:
Tcs3400Device(zx_device_t* device)
: DeviceType(device) {}
@@ -40,19 +40,19 @@
// Methods required by the ddk mixins
zx_status_t DdkRead(void* buf, size_t count, zx_off_t off, size_t* actual);
- zx_status_t HidBusStart(ddk::HidBusIfcProxy proxy) TA_EXCL(proxy_input_lock_);
- zx_status_t HidBusQuery(uint32_t options, hid_info_t* info);
- void HidBusStop();
- zx_status_t HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
- zx_status_t HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+ zx_status_t HidbusStart(const hidbus_ifc_t* ifc) TA_EXCL(proxy_input_lock_);
+ zx_status_t HidbusQuery(uint32_t options, hid_info_t* info);
+ void HidbusStop();
+ zx_status_t HidbusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
+ zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
size_t len, size_t* out_len)
TA_EXCL(proxy_input_lock_, feature_lock_);
- zx_status_t HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data,
+ zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data,
size_t len) TA_EXCL(feature_lock_);
- zx_status_t HidBusGetIdle(uint8_t rpt_id, uint8_t* duration);
- zx_status_t HidBusSetIdle(uint8_t rpt_id, uint8_t duration);
- zx_status_t HidBusGetProtocol(uint8_t* protocol);
- zx_status_t HidBusSetProtocol(uint8_t protocol);
+ zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration);
+ zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration);
+ zx_status_t HidbusGetProtocol(uint8_t* protocol);
+ zx_status_t HidbusSetProtocol(uint8_t protocol);
void DdkUnbind();
void DdkRelease();
@@ -68,7 +68,7 @@
fbl::Mutex proxy_input_lock_ TA_ACQ_BEFORE(i2c_lock_);
fbl::Mutex feature_lock_;
fbl::Mutex i2c_lock_;
- ddk::HidBusIfcProxy proxy_ TA_GUARDED(proxy_input_lock_);
+ ddk::HidbusIfcProxy proxy_ TA_GUARDED(proxy_input_lock_);
ambient_light_input_rpt_t input_rpt_ TA_GUARDED(proxy_input_lock_);
ambient_light_feature_rpt_t feature_rpt_ TA_GUARDED(feature_lock_);
zx_status_t FillInputRpt() TA_REQ(proxy_input_lock_);
diff --git a/system/dev/misc/test/test.c b/system/dev/misc/test/test.c
index 4061bb8..8a6c791 100644
--- a/system/dev/misc/test/test.c
+++ b/system/dev/misc/test/test.c
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <zircon/device/test.h>
#include <zircon/listnode.h>
typedef struct test_device {
@@ -17,7 +18,6 @@
zx_handle_t output;
zx_handle_t control;
test_func_t test_func;
- void* cookie;
} test_device_t;
typedef struct test_root {
@@ -50,16 +50,16 @@
return device->control;
}
-static void test_device_set_test_func(void* ctx, test_func_t func, void* cookie) {
+static void test_device_set_test_func(void* ctx, const test_func_t* func) {
test_device_t* device = ctx;
- device->test_func = func;
- device->cookie = cookie;
+ device->test_func = *func;
}
-static zx_status_t test_device_run_tests(void *ctx, test_report_t* report, const void* arg, size_t arglen) {
+static zx_status_t test_device_run_tests(void *ctx, const void* arg, size_t arglen,
+ test_report_t* report) {
test_device_t* device = ctx;
- if (device->test_func != NULL) {
- return device->test_func(device->cookie, report, arg, arglen);
+ if (device->test_func.callback != NULL) {
+ return device->test_func.callback(device->test_func.ctx, arg, arglen, report);
} else {
return ZX_ERR_NOT_SUPPORTED;
}
@@ -102,7 +102,7 @@
if (outlen != sizeof(test_report_t)) {
return ZX_ERR_BUFFER_TOO_SMALL;
}
- zx_status_t status = test_device_run_tests(dev, (test_report_t*)out, in, inlen);
+ zx_status_t status = test_device_run_tests(dev, in, inlen, (test_report_t*)out);
*out_actual = sizeof(test_report_t);
return status;
diff --git a/system/dev/nand/aml-rawnand/aml-rawnand.c b/system/dev/nand/aml-rawnand/aml-rawnand.c
index 68592f1..ad0a54f 100644
--- a/system/dev/nand/aml-rawnand/aml-rawnand.c
+++ b/system/dev/nand/aml-rawnand/aml-rawnand.c
@@ -445,9 +445,13 @@
}
static zx_status_t aml_read_page_hwecc(void* ctx,
- void* data,
- void* oob,
uint32_t nand_page,
+ void* data,
+ size_t data_size,
+ size_t* data_actual,
+ void* oob,
+ size_t oob_size,
+ size_t* oob_actual,
int* ecc_correct) {
aml_raw_nand_t* raw_nand = (aml_raw_nand_t*)ctx;
uint32_t cmd;
@@ -540,7 +544,9 @@
*/
static zx_status_t aml_write_page_hwecc(void* ctx,
const void* data,
+ size_t data_size,
const void* oob,
+ size_t oob_size,
uint32_t nand_page)
{
aml_raw_nand_t *raw_nand = (aml_raw_nand_t*)ctx;
@@ -807,7 +813,9 @@
static zx_status_t aml_read_page0(aml_raw_nand_t* raw_nand,
void* data,
+ size_t data_size,
void* oob,
+ size_t oob_size,
uint32_t nand_page,
int* ecc_correct,
int retries) {
@@ -815,8 +823,8 @@
retries++;
do {
- status = aml_read_page_hwecc(raw_nand, data, oob,
- nand_page, ecc_correct);
+ status = aml_read_page_hwecc(raw_nand, nand_page, data, data_size, NULL, oob, oob_size,
+ NULL, ecc_correct);
} while (status != ZX_OK && --retries > 0);
if (status != ZX_OK)
zxlogf(ERROR, "%s: Read error\n", __func__);
@@ -843,7 +851,7 @@
* starting at Page 0. Read the first we can.
*/
for (uint32_t i = 0; i < 7; i++) {
- status = aml_read_page0(raw_nand, data, NULL, i * 128,
+ status = aml_read_page0(raw_nand, data, raw_nand->writesize, NULL, 0, i * 128,
&ecc_correct, 3);
if (status == ZX_OK)
break;
diff --git a/system/dev/nand/nand/nand.c b/system/dev/nand/nand/nand.c
index 25af02f..3075a44 100644
--- a/system/dev/nand/nand/nand.c
+++ b/system/dev/nand/nand/nand.c
@@ -34,8 +34,8 @@
#define NAND_READ_RETRIES 3
-static void nand_io_complete(nand_op_t* nand_op, zx_status_t status) {
- nand_op->completion_cb(nand_op, status);
+static void nand_io_complete(nand_io_t* io, zx_status_t status) {
+ io->completion_cb(io->cookie, status, &io->nand_op);
}
// Calls controller specific read function.
@@ -49,7 +49,8 @@
zx_status_t status;
do {
- status = raw_nand_read_page_hwecc(&dev->host, data, oob, nand_page, corrected_bits);
+ status = raw_nand_read_page_hwecc(&dev->host, nand_page, data, dev->nand_info.page_size,
+ NULL, oob, dev->nand_info.oob_size, NULL, corrected_bits);
if (status != ZX_OK) {
zxlogf(ERROR, "%s: Retrying Read@%u\n", __func__, nand_page);
}
@@ -64,7 +65,8 @@
// data, oob: pointers to user oob/data buffers.
// nand_page : NAND page address to read.
zx_status_t nand_write_page(nand_device_t* dev, void* data, void* oob, uint32_t nand_page) {
- return raw_nand_write_page_hwecc(&dev->host, data, oob, nand_page);
+ return raw_nand_write_page_hwecc(&dev->host, data, dev->nand_info.page_size, oob,
+ dev->nand_info.oob_size, nand_page);
}
// Calls controller specific erase function.
@@ -73,7 +75,7 @@
return raw_nand_erase_block(&dev->host, nand_page);
}
-zx_status_t nand_erase_op(nand_device_t* dev, nand_op_t* nand_op) {
+zx_status_t nand_erase_op(nand_device_t* dev, nand_operation_t* nand_op) {
uint32_t nand_page;
for (uint32_t i = 0; i < nand_op->erase.num_blocks; i++) {
@@ -87,7 +89,7 @@
return ZX_OK;
}
-static zx_status_t nand_read_op(nand_device_t* dev, nand_op_t* nand_op) {
+static zx_status_t nand_read_op(nand_device_t* dev, nand_operation_t* nand_op) {
uint8_t *aligned_vaddr_data = NULL;
uint8_t *aligned_vaddr_oob = NULL;
uint8_t *vaddr_data = NULL;
@@ -175,7 +177,7 @@
return status;
}
-static zx_status_t nand_write_op(nand_device_t* dev, nand_op_t* nand_op) {
+static zx_status_t nand_write_op(nand_device_t* dev, nand_operation_t* nand_op) {
uint8_t *aligned_vaddr_data = NULL;
uint8_t *aligned_vaddr_oob = NULL;
uint8_t *vaddr_data = NULL;
@@ -258,7 +260,7 @@
static void nand_do_io(nand_device_t* dev, nand_io_t* io) {
zx_status_t status = ZX_OK;
- nand_op_t* nand_op = &io->nand_op;
+ nand_operation_t* nand_op = &io->nand_op;
ZX_DEBUG_ASSERT(dev != NULL);
ZX_DEBUG_ASSERT(io != NULL);
@@ -275,7 +277,7 @@
default:
ZX_DEBUG_ASSERT(false); // Unexpected.
}
- nand_io_complete(nand_op, status);
+ nand_io_complete(io, status);
}
// Initialization is complete by the time the thread starts.
@@ -315,34 +317,38 @@
return ZX_OK;
}
-static void nand_query(void* ctx, nand_info_t* info_out, size_t* nand_op_size_out) {
+static void _nand_query(void* ctx, nand_info_t* info_out, size_t* nand_op_size_out) {
nand_device_t* dev = (nand_device_t*)ctx;
memcpy(info_out, &dev->nand_info, sizeof(*info_out));
*nand_op_size_out = sizeof(nand_io_t);
}
-static void nand_queue(void* ctx, nand_op_t* op) {
+static void _nand_queue(void* ctx, nand_operation_t* op, nand_queue_callback completion_cb,
+ void* cookie) {
nand_device_t* dev = (nand_device_t*)ctx;
nand_io_t* io = containerof(op, nand_io_t, nand_op);
- if (op->completion_cb == NULL) {
+ if (completion_cb == NULL) {
zxlogf(TRACE, "nand: nand op %p completion_cb unset!\n", op);
zxlogf(TRACE, "nand: cannot queue command!\n");
return;
}
+ io->completion_cb = completion_cb;
+ io->cookie = cookie;
+
switch (op->command) {
case NAND_OP_READ:
case NAND_OP_WRITE: {
if (op->rw.offset_nand >= dev->num_nand_pages || !op->rw.length ||
(dev->num_nand_pages - op->rw.offset_nand) < op->rw.length) {
- op->completion_cb(op, ZX_ERR_OUT_OF_RANGE);
+ completion_cb(cookie, ZX_ERR_OUT_OF_RANGE, op);
return;
}
if (op->rw.data_vmo == ZX_HANDLE_INVALID &&
op->rw.oob_vmo == ZX_HANDLE_INVALID) {
- op->completion_cb(op, ZX_ERR_BAD_HANDLE);
+ completion_cb(cookie, ZX_ERR_BAD_HANDLE, op);
return;
}
break;
@@ -351,13 +357,13 @@
if (!op->erase.num_blocks ||
op->erase.first_block >= dev->nand_info.num_blocks ||
(op->erase.num_blocks > (dev->nand_info.num_blocks - op->erase.first_block))) {
- op->completion_cb(op, ZX_ERR_OUT_OF_RANGE);
+ completion_cb(cookie, ZX_ERR_OUT_OF_RANGE, op);
return;
}
break;
default:
- op->completion_cb(op, ZX_ERR_NOT_SUPPORTED);
+ completion_cb(cookie, ZX_ERR_NOT_SUPPORTED, op);
return;
}
@@ -370,18 +376,18 @@
mtx_unlock(&dev->lock);
}
-static zx_status_t nand_get_factory_bad_block_list(void* ctx, uint32_t* bad_blocks,
- uint32_t bad_block_len,
- uint32_t* num_bad_blocks) {
+static zx_status_t _nand_get_factory_bad_block_list(void* ctx, uint32_t* bad_blocks,
+ size_t bad_block_len,
+ size_t* num_bad_blocks) {
*num_bad_blocks = 0;
return ZX_ERR_NOT_SUPPORTED;
}
// Nand protocol.
static nand_protocol_ops_t nand_proto = {
- .query = nand_query,
- .queue = nand_queue,
- .get_factory_bad_block_list = nand_get_factory_bad_block_list,
+ .query = _nand_query,
+ .queue = _nand_queue,
+ .get_factory_bad_block_list = _nand_get_factory_bad_block_list,
};
static void nand_unbind(void* ctx) {
@@ -401,7 +407,7 @@
nand_io_t* io = NULL;
list_for_every_entry (&dev->io_list, io, nand_io_t, node) {
mtx_unlock(&dev->lock);
- nand_io_complete(&io->nand_op, ZX_ERR_BAD_STATE);
+ nand_io_complete(io, ZX_ERR_BAD_STATE);
mtx_lock(&dev->lock);
}
mtx_unlock(&dev->lock);
@@ -471,7 +477,7 @@
zxlogf(ERROR, "nand: failed to get nand info, function does not exist\n");
goto fail;
}
- st = raw_nand_get_info(&dev->host, &dev->nand_info);
+ st = raw_nand_get_nand_info(&dev->host, &dev->nand_info);
if (st != ZX_OK) {
zxlogf(ERROR, "nand: get_nand_info returned error %d\n", st);
goto fail;
diff --git a/system/dev/nand/nand/nand.h b/system/dev/nand/nand/nand.h
index 666dfab..b163668 100644
--- a/system/dev/nand/nand/nand.h
+++ b/system/dev/nand/nand/nand.h
@@ -31,7 +31,9 @@
// Nand io transactions. One per client request.
typedef struct nand_io {
- nand_op_t nand_op;
+ nand_operation_t nand_op;
+ nand_queue_callback completion_cb;
+ void* cookie;
list_node_t node;
} nand_io_t;
diff --git a/system/dev/nand/nand/nand_driver_test.c b/system/dev/nand/nand/nand_driver_test.c
index dc98da7..6afa0e8 100644
--- a/system/dev/nand/nand/nand_driver_test.c
+++ b/system/dev/nand/nand/nand_driver_test.c
@@ -21,9 +21,9 @@
// The code in this file is only used for testing, the ioctl() is the entry
// point into this code, called by the nand driver's unit test.
-static void nandtest_complete(nand_op_t* nand_op, zx_status_t status) {
+static void nandtest_complete(void* cookie, zx_status_t status, nand_operation_t* nand_op) {
nand_op->command = status;
- sync_completion_signal((sync_completion_t*)nand_op->cookie);
+ sync_completion_signal((sync_completion_t*)cookie);
}
static zx_status_t nand_test_get_info(nand_device_t* dev, void* reply, size_t max,
@@ -50,7 +50,7 @@
nand_info_t nand_info;
size_t nand_op_size_out;
nand_io_t nand_io;
- nand_op_t* nand_op = &nand_io.nand_op;
+ nand_operation_t* nand_op = &nand_io.nand_op;
nandtest_rw_page_data_oob_t* cmd_read_page;
nandtest_resp_t resp_hdr;
zx_handle_t vmo_data;
@@ -98,11 +98,8 @@
nand_op->rw.data_vmo = do_data ? vmo_data : ZX_HANDLE_INVALID;
nand_op->rw.oob_vmo = do_oob ? vmo_oob : ZX_HANDLE_INVALID;
- nand_op->completion_cb = nandtest_complete;
- nand_op->cookie = &completion;
-
// Queue the data read op and wait for response.
- dev->nand_proto.ops->queue(dev, nand_op);
+ dev->nand_proto.ops->queue(dev, nand_op, nandtest_complete, &completion);
sync_completion_wait(&completion, ZX_TIME_INFINITE);
resp_hdr.status = nand_op->command; // Status stored here by callback.
@@ -123,7 +120,7 @@
nand_info_t nand_info;
size_t nand_op_size_out;
nand_io_t nand_io;
- nand_op_t* nand_op = &nand_io.nand_op;
+ nand_operation_t* nand_op = &nand_io.nand_op;
nandtest_rw_page_data_oob_t* cmd_write_page;
nandtest_resp_t resp_hdr;
zx_handle_t vmo_data, vmo_oob;
@@ -176,11 +173,8 @@
nand_op->rw.data_vmo = do_data ? vmo_data : ZX_HANDLE_INVALID;
nand_op->rw.oob_vmo = do_oob ? vmo_oob : ZX_HANDLE_INVALID;
- nand_op->completion_cb = nandtest_complete;
- nand_op->cookie = &completion;
-
// Queue the data read op and wait for response.
- dev->nand_proto.ops->queue(dev, nand_op);
+ dev->nand_proto.ops->queue(dev, nand_op, nandtest_complete, &completion);
sync_completion_wait(&completion, ZX_TIME_INFINITE);
resp_hdr.status = nand_op->command; // Status stored here by callback.
@@ -206,7 +200,7 @@
nand_info_t nand_info;
size_t nand_op_size_out;
nand_io_t nand_io;
- nand_op_t* nand_op = &nand_io.nand_op;
+ nand_operation_t* nand_op = &nand_io.nand_op;
nandtest_cmd_erase_block_t* cmd_erase_block;
nandtest_resp_t resp_hdr;
@@ -228,11 +222,9 @@
nand_op->command = NAND_OP_ERASE;
nand_op->erase.first_block = cmd_erase_block->nandblock;
nand_op->erase.num_blocks = 1;
- nand_op->completion_cb = nandtest_complete;
- nand_op->cookie = &completion;
// Queue the data read op and wait for response.
- dev->nand_proto.ops->queue(dev, nand_op);
+ dev->nand_proto.ops->queue(dev, nand_op, nandtest_complete, &completion);
sync_completion_wait(&completion, ZX_TIME_INFINITE);
resp_hdr.status = nand_op->command; // Status stored here by callback.
diff --git a/system/dev/nand/nandpart/aml-bad-block.cpp b/system/dev/nand/nandpart/aml-bad-block.cpp
index 5a1fbbe..1c848fe 100644
--- a/system/dev/nand/nandpart/aml-bad-block.cpp
+++ b/system/dev/nand/nandpart/aml-bad-block.cpp
@@ -30,8 +30,8 @@
zx_status_t status;
};
-void CompletionCallback(nand_op_t* op, zx_status_t status) {
- auto* ctx = static_cast<BlockOperationContext*>(op->cookie);
+void CompletionCallback(void* cookie, zx_status_t status, nand_operation_t* op) {
+ auto* ctx = static_cast<BlockOperationContext*>(cookie);
zxlogf(TRACE, "Completion status: %d\n", status);
ctx->status = status;
@@ -42,7 +42,7 @@
} // namespace
zx_status_t AmlBadBlock::Create(Config config, fbl::RefPtr<BadBlock>* out) {
- // Query parent to get its nand_info_t and size for nand_op_t.
+ // Query parent to get its nand_info_t and size for nand_operation_t.
nand_info_t nand_info;
size_t parent_op_size;
config.nand_proto.ops->query(config.nand_proto.ctx, &nand_info, &parent_op_size);
@@ -104,13 +104,11 @@
sync_completion_t completion;
BlockOperationContext op_ctx = {.completion_event = &completion,
.status = ZX_ERR_INTERNAL};
- auto* nand_op = reinterpret_cast<nand_op_t*>(nand_op_.get());
+ auto* nand_op = reinterpret_cast<nand_operation_t*>(nand_op_.get());
nand_op->erase.command = NAND_OP_ERASE;
nand_op->erase.first_block = block;
nand_op->erase.num_blocks = 1;
- nand_op->completion_cb = CompletionCallback;
- nand_op->cookie = &op_ctx;
- nand_.Queue(nand_op);
+ nand_.Queue(nand_op, CompletionCallback, &op_ctx);
// Wait on completion.
sync_completion_wait(&completion, ZX_TIME_INFINITE);
@@ -166,7 +164,7 @@
BlockOperationContext op_ctx = {.completion_event = &completion,
.status = ZX_ERR_INTERNAL};
- auto* nand_op = reinterpret_cast<nand_op_t*>(nand_op_.get());
+ auto* nand_op = reinterpret_cast<nand_operation_t*>(nand_op_.get());
nand_op->rw.command = NAND_OP_WRITE;
nand_op->rw.data_vmo = data_vmo_.get();
nand_op->rw.oob_vmo = oob_vmo_.get();
@@ -174,9 +172,7 @@
nand_op->rw.offset_nand = nand_page;
nand_op->rw.offset_data_vmo = 0;
nand_op->rw.offset_oob_vmo = 0;
- nand_op->completion_cb = CompletionCallback;
- nand_op->cookie = &op_ctx;
- nand_.Queue(nand_op);
+ nand_.Queue(nand_op, CompletionCallback, &op_ctx);
// Wait on completion.
sync_completion_wait(&completion, ZX_TIME_INFINITE);
@@ -230,7 +226,7 @@
sync_completion_t completion;
BlockOperationContext op_ctx = {.completion_event = &completion,
.status = ZX_ERR_INTERNAL};
- auto* nand_op = reinterpret_cast<nand_op_t*>(nand_op_.get());
+ auto* nand_op = reinterpret_cast<nand_operation_t*>(nand_op_.get());
nand_op->rw.command = NAND_OP_READ;
nand_op->rw.data_vmo = data_vmo_.get();
nand_op->rw.oob_vmo = oob_vmo_.get();
@@ -238,9 +234,7 @@
nand_op->rw.offset_nand = nand_page;
nand_op->rw.offset_data_vmo = 0;
nand_op->rw.offset_oob_vmo = 0;
- nand_op->completion_cb = CompletionCallback;
- nand_op->cookie = &op_ctx;
- nand_.Queue(nand_op);
+ nand_.Queue(nand_op, CompletionCallback, &op_ctx);
// Wait on completion.
sync_completion_wait(&completion, ZX_TIME_INFINITE);
diff --git a/system/dev/nand/nandpart/nandpart.cpp b/system/dev/nand/nandpart/nandpart.cpp
index e6a403a..fb99240 100644
--- a/system/dev/nand/nandpart/nandpart.cpp
+++ b/system/dev/nand/nandpart/nandpart.cpp
@@ -30,10 +30,17 @@
constexpr uint8_t fvm_guid[] = GUID_FVM_VALUE;
+struct NandPartOp {
+ nand_operation_t translated_op;
+ nand_queue_callback completion_cb;
+ void* cookie;
+};
+
// Shim for calling sub-partition's callback.
-void CompletionCallback(nand_op_t* op, zx_status_t status) {
- op = static_cast<nand_op_t*>(op->cookie);
- op->completion_cb(op, status);
+void CompletionCallback(void* cookie, zx_status_t status, nand_operation_t* op) {
+ auto* nandpart_op = reinterpret_cast<NandPartOp*>(op);
+ nandpart_op->completion_cb(nandpart_op->cookie, status,
+ static_cast<nand_operation_t*>(cookie));
}
} // namespace
@@ -48,7 +55,7 @@
return ZX_ERR_NOT_SUPPORTED;
}
- // Query parent to get its nand_info_t and size for nand_op_t.
+ // Query parent to get its nand_info_t and size for nand_operation_t.
nand_info_t nand_info;
size_t parent_op_size;
nand_proto.ops->query(nand_proto.ctx, &nand_info, &parent_op_size);
@@ -186,15 +193,17 @@
return ZX_OK;
}
-void NandPartDevice::Query(nand_info_t* info_out, size_t* nand_op_size_out) {
+void NandPartDevice::NandQuery(nand_info_t* info_out, size_t* nand_op_size_out) {
memcpy(info_out, &nand_info_, sizeof(*info_out));
// Add size of translated_op.
- *nand_op_size_out = parent_op_size_ + sizeof(nand_op_t);
+ *nand_op_size_out = parent_op_size_ + sizeof(NandPartOp);
}
-void NandPartDevice::Queue(nand_op_t* op) {
- auto* translated_op =
- reinterpret_cast<nand_op_t*>(reinterpret_cast<uintptr_t>(op) + parent_op_size_);
+void NandPartDevice::NandQueue(nand_operation_t* op, nand_queue_callback completion_cb,
+ void* cookie) {
+ auto* nandpart_op =
+ reinterpret_cast<NandPartOp*>(reinterpret_cast<uintptr_t>(op) + parent_op_size_);
+ auto* translated_op = &nandpart_op->translated_op;
uint32_t command = op->command;
// Copy client's op to translated op
@@ -210,26 +219,26 @@
translated_op->erase.first_block += erase_block_start_;
break;
default:
- op->completion_cb(op, ZX_ERR_NOT_SUPPORTED);
+ completion_cb(cookie, ZX_ERR_NOT_SUPPORTED, op);
return;
}
- translated_op->completion_cb = CompletionCallback;
- translated_op->cookie = op;
+ nandpart_op->completion_cb = completion_cb;
+ nandpart_op->cookie = cookie;
// Call parent's queue
- nand_.Queue(translated_op);
+ nand_.Queue(translated_op, CompletionCallback, op);
}
-zx_status_t NandPartDevice::GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
- uint32_t* num_bad_blocks) {
+zx_status_t NandPartDevice::NandGetFactoryBadBlockList(uint32_t* bad_blocks, size_t bad_block_len,
+ size_t* num_bad_blocks) {
// TODO implement this.
*num_bad_blocks = 0;
return ZX_ERR_NOT_SUPPORTED;
}
-zx_status_t NandPartDevice::GetBadBlockList(uint32_t* bad_block_list, uint32_t bad_block_list_len,
- uint32_t* bad_block_count) {
+zx_status_t NandPartDevice::BadBlockGetBadBlockList(
+ uint32_t* bad_block_list, size_t bad_block_list_len, size_t* bad_block_count) {
if (!bad_block_list_) {
const zx_status_t status = bad_block_->GetBadBlockList(
@@ -242,8 +251,8 @@
}
}
- *bad_block_count = static_cast<uint32_t>(bad_block_list_.size());
- zxlogf(TRACE, "nandpart: %s: Bad block count: %u\n", name(), *bad_block_count);
+ *bad_block_count = bad_block_list_.size();
+ zxlogf(TRACE, "nandpart: %s: Bad block count: %zu\n", name(), *bad_block_count);
if (bad_block_list_len == 0 || bad_block_list_.size() == 0) {
return ZX_OK;
@@ -257,7 +266,7 @@
return ZX_OK;
}
-zx_status_t NandPartDevice::MarkBlockBad(uint32_t block) {
+zx_status_t NandPartDevice::BadBlockMarkBlockBad(uint32_t block) {
if (block >= nand_info_.num_blocks) {
return ZX_ERR_OUT_OF_RANGE;
}
@@ -275,10 +284,10 @@
proto->ctx = this;
switch (proto_id) {
case ZX_PROTOCOL_NAND:
- proto->ops = &nand_proto_ops_;
+ proto->ops = &ops_;
break;
case ZX_PROTOCOL_BAD_BLOCK:
- proto->ops = &bad_block_proto_ops_;
+ proto->ops = &bad_block_protocol_ops_;
break;
default:
return ZX_ERR_NOT_SUPPORTED;
diff --git a/system/dev/nand/nandpart/nandpart.h b/system/dev/nand/nandpart/nandpart.h
index 12aa6f7..406cabe 100644
--- a/system/dev/nand/nandpart/nandpart.h
+++ b/system/dev/nand/nandpart/nandpart.h
@@ -25,7 +25,7 @@
class NandPartDevice : public DeviceType,
public ddk::NandProtocol<NandPartDevice>,
- public ddk::BadBlockable<NandPartDevice> {
+ public ddk::BadBlockProtocol<NandPartDevice> {
public:
// Spawns device nodes based on parent node.
static zx_status_t Create(zx_device_t* parent);
@@ -43,15 +43,15 @@
void DdkRelease() { delete this; }
// nand protocol implementation.
- void Query(nand_info_t* info_out, size_t* nand_op_size_out);
- void Queue(nand_op_t* op);
- zx_status_t GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
- uint32_t* num_bad_blocks);
+ void NandQuery(nand_info_t* info_out, size_t* nand_op_size_out);
+ void NandQueue(nand_operation_t* op, nand_queue_callback completion_cb, void* cookie);
+ zx_status_t NandGetFactoryBadBlockList(uint32_t* bad_blocks, size_t bad_block_len,
+ size_t* num_bad_blocks);
// Bad block protocol implementation.
- zx_status_t GetBadBlockList(uint32_t* bad_block_list, uint32_t bad_block_list_len,
- uint32_t* bad_block_count);
- zx_status_t MarkBlockBad(uint32_t block);
+ zx_status_t BadBlockGetBadBlockList(uint32_t* bad_block_list, size_t bad_block_list_len,
+ size_t* bad_block_count);
+ zx_status_t BadBlockMarkBlockBad(uint32_t block);
private:
explicit NandPartDevice(zx_device_t* parent, const nand_protocol_t& nand_proto,
diff --git a/system/dev/nand/nandpart/test/aml-bad-block-test.cpp b/system/dev/nand/nandpart/test/aml-bad-block-test.cpp
index e5b931b..901b027 100644
--- a/system/dev/nand/nandpart/test/aml-bad-block-test.cpp
+++ b/system/dev/nand/nandpart/test/aml-bad-block-test.cpp
@@ -77,10 +77,11 @@
void MockQuery(void* ctx, nand_info_t* info_out, size_t* nand_op_size_out) {
memcpy(info_out, &kNandInfo, sizeof(kNandInfo));
- *nand_op_size_out = sizeof(nand_op_t);
+ *nand_op_size_out = sizeof(nand_operation_t);
}
-void MockQueue(void* ctx, nand_op_t* op) {
+void MockQueue(void* ctx, nand_operation_t* op, nand_queue_callback completion_cb,
+ void* cookie) {
auto* context = static_cast<Context*>(ctx);
switch (op->command) {
@@ -93,7 +94,7 @@
op->erase.first_block + op->erase.num_blocks >= kNumBlocks) {
unittest_printf("Trying to write to a page that is out of range!\n");
- op->completion_cb(op, ZX_ERR_OUT_OF_RANGE);
+ completion_cb(cookie, ZX_ERR_OUT_OF_RANGE, op);
return;
}
const NandPage start_page = op->erase.first_block * kPagesPerBlock;
@@ -101,11 +102,11 @@
for (NandPage page = start_page; page < end_page; page++) {
context->table_entries.erase(page);
}
- op->completion_cb(op, ZX_OK);
+ completion_cb(cookie, ZX_OK, op);
return;
}
default:
- op->completion_cb(op, ZX_ERR_NOT_SUPPORTED);
+ completion_cb(cookie, ZX_ERR_NOT_SUPPORTED, op);
return;
}
@@ -119,7 +120,7 @@
&data_buf);
__UNUSED auto unused = data_vmo.release();
if (status != ZX_OK) {
- op->completion_cb(op, status);
+ completion_cb(cookie, status, op);
return;
}
auto data_unmapper = fbl::MakeAutoCall([&]() {
@@ -132,7 +133,7 @@
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, &oob_buf);
__UNUSED auto __ = oob_vmo.release();
if (status != ZX_OK) {
- op->completion_cb(op, status);
+ completion_cb(cookie, status, op);
return;
}
auto oob_unmapper = fbl::MakeAutoCall([&]() {
@@ -147,7 +148,7 @@
auto it = context->table_entries.find(op->rw.offset_nand + i);
if (it != context->table_entries.end()) {
if (!it->valid_) {
- op->completion_cb(op, ZX_ERR_IO);
+ completion_cb(cookie, ZX_ERR_IO, op);
return;
}
memset(data + (i * kPageSize), 0, kPageSize);
@@ -162,7 +163,7 @@
memset(oob + i, 0xFF, sizeof(*oob));
}
}
- op->completion_cb(op, ZX_OK);
+ completion_cb(cookie, ZX_OK, op);
break;
case NAND_OP_WRITE:
@@ -181,10 +182,10 @@
break;
}
}
- op->completion_cb(op, status);
+ completion_cb(cookie, status, op);
break;
default:
- op->completion_cb(op, ZX_ERR_NOT_SUPPORTED);
+ completion_cb(cookie, ZX_ERR_NOT_SUPPORTED, op);
break;
}
}
diff --git a/system/dev/nand/ram-nand/ram-nand.cpp b/system/dev/nand/ram-nand/ram-nand.cpp
index c3cd04e..5e1bab7 100644
--- a/system/dev/nand/ram-nand/ram-nand.cpp
+++ b/system/dev/nand/ram-nand/ram-nand.cpp
@@ -23,7 +23,9 @@
namespace {
struct RamNandOp {
- nand_op_t op;
+ nand_operation_t op;
+ nand_queue_callback completion_cb;
+ void* cookie;
list_node_t node;
};
@@ -45,8 +47,7 @@
if (!nand_op) {
break;
}
- nand_op_t* operation = &nand_op->op;
- operation->completion_cb(operation, ZX_ERR_BAD_STATE);
+ nand_op->completion_cb(nand_op->cookie, ZX_ERR_BAD_STATE, &nand_op->op);
}
}
@@ -178,24 +179,25 @@
}
}
-void NandDevice::Query(nand_info_t* info_out, size_t* nand_op_size_out) {
+void NandDevice::NandQuery(nand_info_t* info_out, size_t* nand_op_size_out) {
*info_out = params_;
*nand_op_size_out = sizeof(RamNandOp);
}
-void NandDevice::Queue(nand_op_t* operation) {
+void NandDevice::NandQueue(nand_operation_t* operation, nand_queue_callback completion_cb,
+ void* cookie) {
uint32_t max_pages = params_.NumPages();
switch (operation->command) {
case NAND_OP_READ:
case NAND_OP_WRITE: {
if (operation->rw.offset_nand >= max_pages || !operation->rw.length ||
(max_pages - operation->rw.offset_nand) < operation->rw.length) {
- operation->completion_cb(operation, ZX_ERR_OUT_OF_RANGE);
+ completion_cb(cookie, ZX_ERR_OUT_OF_RANGE, operation);
return;
}
if (operation->rw.data_vmo == ZX_HANDLE_INVALID &&
operation->rw.oob_vmo == ZX_HANDLE_INVALID) {
- operation->completion_cb(operation, ZX_ERR_BAD_HANDLE);
+ completion_cb(cookie, ZX_ERR_BAD_HANDLE, operation);
return;
}
break;
@@ -204,25 +206,25 @@
if (!operation->erase.num_blocks ||
operation->erase.first_block >= params_.num_blocks ||
params_.num_blocks - operation->erase.first_block < operation->erase.num_blocks) {
- operation->completion_cb(operation, ZX_ERR_OUT_OF_RANGE);
+ completion_cb(cookie, ZX_ERR_OUT_OF_RANGE, operation);
return;
}
break;
default:
- operation->completion_cb(operation, ZX_ERR_NOT_SUPPORTED);
+ completion_cb(cookie, ZX_ERR_NOT_SUPPORTED, operation);
return;
}
- if (AddToList(operation)) {
+ if (AddToList(operation, completion_cb, cookie)) {
sync_completion_signal(&wake_signal_);
} else {
- operation->completion_cb(operation, ZX_ERR_BAD_STATE);
+ completion_cb(cookie, ZX_ERR_BAD_STATE, operation);
}
}
-zx_status_t NandDevice::GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
- uint32_t* num_bad_blocks) {
+zx_status_t NandDevice::NandGetFactoryBadBlockList(uint32_t* bad_blocks, size_t bad_block_len,
+ size_t* num_bad_blocks) {
*num_bad_blocks = 0;
return ZX_OK;
}
@@ -232,29 +234,32 @@
dead_ = true;
}
-bool NandDevice::AddToList(nand_op_t* operation) {
+bool NandDevice::AddToList(nand_operation_t* operation, nand_queue_callback completion_cb,
+ void* cookie) {
fbl::AutoLock lock(&lock_);
bool is_dead = dead_;
if (!dead_) {
RamNandOp* nand_op = reinterpret_cast<RamNandOp*>(operation);
+ nand_op->completion_cb = completion_cb;
+ nand_op->cookie = cookie;
list_add_tail(&txn_list_, &nand_op->node);
}
return !is_dead;
}
-bool NandDevice::RemoveFromList(nand_op_t** operation) {
+bool NandDevice::RemoveFromList(nand_operation_t** operation) {
fbl::AutoLock lock(&lock_);
bool is_dead = dead_;
if (!dead_) {
RamNandOp* nand_op = list_remove_head_type(&txn_list_, RamNandOp, node);
- *operation = reinterpret_cast<nand_op_t*>(nand_op);
+ *operation = reinterpret_cast<nand_operation_t*>(nand_op);
}
return !is_dead;
}
int NandDevice::WorkerThread() {
for (;;) {
- nand_op_t* operation;
+ nand_operation_t* operation;
for (;;) {
if (!RemoveFromList(&operation)) {
return 0;
@@ -286,7 +291,8 @@
ZX_DEBUG_ASSERT(false); // Unexpected.
}
- operation->completion_cb(operation, status);
+ auto *op = reinterpret_cast<RamNandOp*>(operation);
+ op->completion_cb(op->cookie, status, operation);
}
}
@@ -295,7 +301,7 @@
return device->WorkerThread();
}
-zx_status_t NandDevice::ReadWriteData(nand_op_t* operation) {
+zx_status_t NandDevice::ReadWriteData(nand_operation_t* operation) {
if (operation->rw.data_vmo == ZX_HANDLE_INVALID) {
return ZX_OK;
}
@@ -323,7 +329,7 @@
return zx_vmo_read(operation->rw.data_vmo, addr, vmo_addr, length);
}
-zx_status_t NandDevice::ReadWriteOob(nand_op_t* operation) {
+zx_status_t NandDevice::ReadWriteOob(nand_operation_t* operation) {
if (operation->rw.oob_vmo == ZX_HANDLE_INVALID) {
return ZX_OK;
}
@@ -342,7 +348,7 @@
return zx_vmo_read(operation->rw.oob_vmo, addr, vmo_addr, length);
}
-zx_status_t NandDevice::Erase(nand_op_t* operation) {
+zx_status_t NandDevice::Erase(nand_operation_t* operation) {
ZX_DEBUG_ASSERT(operation->command == NAND_OP_ERASE);
uint32_t block_size = params_.page_size * params_.pages_per_block;
diff --git a/system/dev/nand/ram-nand/ram-nand.h b/system/dev/nand/ram-nand/ram-nand.h
index 09c630e..32ee47c 100644
--- a/system/dev/nand/ram-nand/ram-nand.h
+++ b/system/dev/nand/ram-nand/ram-nand.h
@@ -67,23 +67,25 @@
void* out_buf, size_t out_len, size_t* out_actual);
// NAND protocol implementation.
- void Query(nand_info_t* info_out, size_t* nand_op_size_out);
- void Queue(nand_op_t* operation);
- zx_status_t GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
- uint32_t* num_bad_blocks);
+ void NandQuery(nand_info_t* info_out, size_t* nand_op_size_out);
+ void NandQueue(nand_operation_t* operation, nand_queue_callback completion_cb,
+ void* cookie);
+ zx_status_t NandGetFactoryBadBlockList(uint32_t* bad_blocks, size_t bad_block_len,
+ size_t* num_bad_blocks);
private:
void Kill();
- bool AddToList(nand_op_t* operation);
- bool RemoveFromList(nand_op_t** operation);
+ bool AddToList(nand_operation_t* operation, nand_queue_callback completion_cb,
+ void* cookie);
+ bool RemoveFromList(nand_operation_t** operation);
int WorkerThread();
static int WorkerThreadStub(void* arg);
uint32_t MainDataSize() const { return params_.NumPages() * params_.page_size; }
// Implementation of the actual commands.
- zx_status_t ReadWriteData(nand_op_t* operation);
- zx_status_t ReadWriteOob(nand_op_t* operation);
- zx_status_t Erase(nand_op_t* operation);
+ zx_status_t ReadWriteData(nand_operation_t* operation);
+ zx_status_t ReadWriteOob(nand_operation_t* operation);
+ zx_status_t Erase(nand_operation_t* operation);
uintptr_t mapped_addr_ = 0;
zx::vmo vmo_;
diff --git a/system/dev/nand/ram-nand/test/ram-nand.cpp b/system/dev/nand/ram-nand/test/ram-nand.cpp
index 563aa29..9c26f93 100644
--- a/system/dev/nand/ram-nand/test/ram-nand.cpp
+++ b/system/dev/nand/ram-nand/test/ram-nand.cpp
@@ -79,7 +79,7 @@
if (operation_size) {
nand_info_t info;
- device->Query(&info, operation_size);
+ device->NandQuery(&info, operation_size);
}
char name[NAME_MAX];
@@ -126,9 +126,9 @@
nand_info_t info;
size_t operation_size;
- device.Query(&info, &operation_size);
+ device.NandQuery(&info, &operation_size);
ASSERT_EQ(0, memcmp(&info, ¶ms, sizeof(info)));
- ASSERT_GT(operation_size, sizeof(nand_op_t));
+ ASSERT_GT(operation_size, sizeof(nand_operation_t));
END_TEST;
}
@@ -144,19 +144,19 @@
nullptr, 0, nullptr));
uint32_t result[4];
- uint32_t num_bad_blocks;
- device->GetFactoryBadBlockList(result, sizeof(result), &num_bad_blocks);
+ size_t num_bad_blocks;
+ device->NandGetFactoryBadBlockList(result, sizeof(result), &num_bad_blocks);
ASSERT_EQ(0, num_bad_blocks);
END_TEST;
}
-// Data to be pre-pended to a nand_op_t issued to the device.
+// Data to be pre-pended to a nand_operation_t issued to the device.
struct OpHeader {
class Operation* operation;
class NandTest* test;
};
-// Wrapper for a nand_op_t.
+// Wrapper for a nand_operation_t.
class Operation {
public:
explicit Operation(size_t op_size, NandTest* test = 0)
@@ -172,11 +172,11 @@
size_t buffer_size() const { return buffer_size_; }
char* buffer() const { return mapped_addr_; }
- // Creates a vmo and sets the handle on the nand_op_t.
+ // Creates a vmo and sets the handle on the nand_operation_t.
bool SetDataVmo();
bool SetOobVmo();
- nand_op_t* GetOperation();
+ nand_operation_t* GetOperation();
void OnCompletion(zx_status_t status) {
status_ = status;
@@ -202,7 +202,7 @@
};
bool Operation::SetDataVmo() {
- nand_op_t* operation = GetOperation();
+ nand_operation_t* operation = GetOperation();
if (!operation) {
return false;
}
@@ -211,7 +211,7 @@
}
bool Operation::SetOobVmo() {
- nand_op_t* operation = GetOperation();
+ nand_operation_t* operation = GetOperation();
if (!operation) {
return false;
}
@@ -219,11 +219,11 @@
return operation->rw.oob_vmo != ZX_HANDLE_INVALID;
}
-nand_op_t* Operation::GetOperation() {
+nand_operation_t* Operation::GetOperation() {
if (!raw_buffer_) {
CreateOperation();
}
- return reinterpret_cast<nand_op_t*>(raw_buffer_.get() + sizeof(OpHeader));
+ return reinterpret_cast<nand_operation_t*>(raw_buffer_.get() + sizeof(OpHeader));
}
zx_handle_t Operation::GetVmo() {
@@ -266,7 +266,7 @@
NandTest() {}
~NandTest() {}
- static void CompletionCb(nand_op_t* op, zx_status_t status) {
+ static void CompletionCb(void* cookie, zx_status_t status, nand_operation_t* op) {
OpHeader* header =
reinterpret_cast<OpHeader*>(reinterpret_cast<char*>(op) - sizeof(OpHeader));
@@ -307,30 +307,29 @@
NandTest test;
Operation operation(op_size, &test);
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
ASSERT_TRUE(op);
op->rw.command = NAND_OP_WRITE;
- op->completion_cb = &NandTest::CompletionCb;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
op->rw.length = 1;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_BAD_HANDLE, operation.status());
op->rw.offset_nand = kNumPages;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
ASSERT_TRUE(operation.SetDataVmo());
op->rw.offset_nand = kNumPages - 1;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
@@ -351,20 +350,18 @@
// Prepares the operation to write num_pages starting at offset.
void SetForWrite(int offset, int num_pages, Operation* operation) {
- nand_op_t* op = operation->GetOperation();
+ nand_operation_t* op = operation->GetOperation();
op->rw.command = NAND_OP_WRITE;
op->rw.length = num_pages;
op->rw.offset_nand = offset;
- op->completion_cb = &NandTest::CompletionCb;
}
// Prepares the operation to read num_pages starting at offset.
void SetForRead(int offset, int num_pages, Operation* operation) {
- nand_op_t* op = operation->GetOperation();
+ nand_operation_t* op = operation->GetOperation();
op->rw.command = NAND_OP_READ;
op->rw.length = num_pages;
op->rw.offset_nand = offset;
- op->completion_cb = &NandTest::CompletionCb;
}
bool ReadWriteTest() {
@@ -379,11 +376,11 @@
ASSERT_TRUE(operation.SetDataVmo());
memset(operation.buffer(), 0x55, operation.buffer_size());
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->rw.corrected_bit_flips = 125;
SetForWrite(4, 4, &operation);
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
@@ -392,7 +389,7 @@
op->rw.command = NAND_OP_READ;
memset(operation.buffer(), 0, operation.buffer_size());
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
ASSERT_EQ(0, op->rw.corrected_bit_flips);
@@ -415,12 +412,12 @@
ASSERT_TRUE(operation.SetOobVmo());
memset(operation.buffer(), 0x55, operation.buffer_size());
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->rw.corrected_bit_flips = 125;
SetForRead(0, kNumPages, &operation);
op->rw.offset_oob_vmo = kNumPages;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
@@ -468,8 +465,8 @@
SetForRead(0, 2, operations[9].get());
for (const auto& operation : operations) {
- nand_op_t* op = operation->GetOperation();
- device->Queue(op);
+ nand_operation_t* op = operation->GetOperation();
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
}
ASSERT_TRUE(test.WaitFor(10));
@@ -507,33 +504,32 @@
NandTest test;
Operation operation(op_size, &test);
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->rw.command = NAND_OP_READ;
- op->completion_cb = &NandTest::CompletionCb;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
op->rw.length = 1;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_BAD_HANDLE, operation.status());
op->rw.offset_nand = kNumPages;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
ASSERT_TRUE(operation.SetOobVmo());
op->rw.offset_nand = kNumPages - 1;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
op->rw.length = 5;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
@@ -554,11 +550,11 @@
const char desired[kOobSize] = { 'a', 'b', 'c', 'd' };
memcpy(operation.buffer(), desired, kOobSize);
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->rw.corrected_bit_flips = 125;
SetForWrite(2, 1, &operation);
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
@@ -569,7 +565,7 @@
op->rw.offset_nand = 1;
memset(operation.buffer(), 0, kOobSize * 2);
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
ASSERT_EQ(0, op->rw.corrected_bit_flips);
@@ -595,12 +591,12 @@
memset(operation.buffer(), 0x55, kPageSize * 2);
memset(operation.buffer() + kPageSize * 2, 0xaa, kOobSize * 2);
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->rw.corrected_bit_flips = 125;
SetForWrite(2, 2, &operation);
op->rw.offset_oob_vmo = 2; // OOB is right after data.
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
@@ -609,7 +605,7 @@
op->rw.command = NAND_OP_READ;
memset(operation.buffer(), 0, kPageSize * 4);
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
ASSERT_EQ(0, op->rw.corrected_bit_flips);
@@ -635,23 +631,22 @@
Operation operation(op_size, &test);
ASSERT_TRUE(operation.SetDataVmo());
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->erase.command = NAND_OP_ERASE;
- op->completion_cb = &NandTest::CompletionCb;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
op->erase.first_block = 5;
op->erase.num_blocks = 1;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
op->erase.first_block = 4;
op->erase.num_blocks = 2;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, operation.status());
@@ -668,13 +663,12 @@
NandTest test;
Operation operation(op_size, &test);
- nand_op_t* op = operation.GetOperation();
+ nand_operation_t* op = operation.GetOperation();
op->erase.command = NAND_OP_ERASE;
op->erase.first_block = 3;
op->erase.num_blocks = 2;
- op->completion_cb = &NandTest::CompletionCb;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
@@ -683,7 +677,7 @@
ASSERT_TRUE(operation.SetDataVmo());
ASSERT_TRUE(operation.SetOobVmo());
op->rw.offset_oob_vmo = kNumPages;
- device->Queue(op);
+ device->NandQueue(op, &NandTest::CompletionCb, nullptr);
ASSERT_TRUE(test.Wait());
ASSERT_EQ(ZX_OK, operation.status());
diff --git a/system/dev/nand/skip-block/skip-block.cpp b/system/dev/nand/skip-block/skip-block.cpp
index 42f6e3b..a9f65ea 100644
--- a/system/dev/nand/skip-block/skip-block.cpp
+++ b/system/dev/nand/skip-block/skip-block.cpp
@@ -37,8 +37,8 @@
// Called when all page reads in a block finish. If another block still needs
// to be read, it queues it up as another operation.
-void ReadCompletionCallback(nand_op_t* op, zx_status_t status) {
- auto* ctx = static_cast<BlockOperationContext*>(op->cookie);
+void ReadCompletionCallback(void* cookie, zx_status_t status, nand_operation_t* op) {
+ auto* ctx = static_cast<BlockOperationContext*>(cookie);
if (status != ZX_OK || ctx->current_block + 1 == ctx->op.block + ctx->op.block_count) {
ctx->status = status;
ctx->mark_bad = false;
@@ -57,16 +57,16 @@
op->rw.offset_nand = ctx->physical_block * ctx->nand_info->pages_per_block;
op->rw.offset_data_vmo += ctx->nand_info->pages_per_block;
- ctx->nand->Queue(op);
+ ctx->nand->Queue(op, ReadCompletionCallback, cookie);
return;
}
-void EraseCompletionCallback(nand_op_t* op, zx_status_t status);
+void EraseCompletionCallback(void* cookie, zx_status_t status, nand_operation_t* op);
// Called when all page writes in a block finish. If another block still needs
// to be written, it queues up an erase.
-void WriteCompletionCallback(nand_op_t* op, zx_status_t status) {
- auto* ctx = static_cast<BlockOperationContext*>(op->cookie);
+void WriteCompletionCallback(void* cookie, zx_status_t status, nand_operation_t* op) {
+ auto* ctx = static_cast<BlockOperationContext*>(cookie);
if (status != ZX_OK || ctx->current_block + 1 == ctx->op.block + ctx->op.block_count) {
ctx->status = status;
@@ -87,15 +87,14 @@
op->erase.command = NAND_OP_ERASE;
op->erase.first_block = ctx->physical_block;
op->erase.num_blocks = 1;
- op->completion_cb = EraseCompletionCallback;
- ctx->nand->Queue(op);
+ ctx->nand->Queue(op, EraseCompletionCallback, cookie);
return;
}
// Called when a block erase operation finishes. Subsequently queues up writes
// to the block.
-void EraseCompletionCallback(nand_op_t* op, zx_status_t status) {
- auto* ctx = static_cast<BlockOperationContext*>(op->cookie);
+void EraseCompletionCallback(void* cookie, zx_status_t status, nand_operation_t* op) {
+ auto* ctx = static_cast<BlockOperationContext*>(cookie);
if (status != ZX_OK) {
ctx->status = status;
@@ -109,9 +108,8 @@
op->rw.length = ctx->nand_info->pages_per_block;
op->rw.offset_nand = ctx->physical_block * ctx->nand_info->pages_per_block;
op->rw.offset_data_vmo = ctx->op.vmo_offset;
- op->rw.pages = nullptr;
- op->completion_cb = WriteCompletionCallback;
- ctx->nand->Queue(op);
+ op->rw.page_list = nullptr;
+ ctx->nand->Queue(op, WriteCompletionCallback, cookie);
return;
}
@@ -167,7 +165,7 @@
}
zx_status_t SkipBlockDevice::GetBadBlockList(fbl::Array<uint32_t>* bad_blocks) {
- uint32_t bad_block_count;
+ size_t bad_block_count;
zx_status_t status = bad_block_.GetBadBlockList(nullptr, 0, &bad_block_count);
if (status != ZX_OK) {
return status;
@@ -176,7 +174,7 @@
bad_blocks->reset();
return ZX_OK;
}
- const uint32_t bad_block_list_len = bad_block_count;
+ const size_t bad_block_list_len = bad_block_count;
fbl::unique_ptr<uint32_t[]> bad_block_list(new uint32_t[bad_block_count]);
status = bad_block_.GetBadBlockList(bad_block_list.get(), bad_block_list_len, &bad_block_count);
if (status != ZX_OK) {
@@ -194,9 +192,9 @@
fbl::AutoLock al(&lock_);
- if (sizeof(nand_op_t) > parent_op_size_) {
+ if (sizeof(nand_operation_t) > parent_op_size_) {
zxlogf(ERROR, "skip-block: parent op size, %zu, is smaller than minimum op size: %zu\n",
- sizeof(nand_op_t), parent_op_size_);
+ sizeof(nand_operation_t), parent_op_size_);
return ZX_ERR_INTERNAL;
}
@@ -276,7 +274,7 @@
.mark_bad = false,
};
- auto* nand_op = reinterpret_cast<nand_op_t*>(nand_op_.get());
+ auto* nand_op = reinterpret_cast<nand_operation_t*>(nand_op_.get());
nand_op->rw.command = NAND_OP_READ;
nand_op->rw.data_vmo = op.vmo;
nand_op->rw.oob_vmo = ZX_HANDLE_INVALID;
@@ -284,9 +282,7 @@
nand_op->rw.offset_nand = physical_block * nand_info_.pages_per_block;
nand_op->rw.offset_data_vmo = op.vmo_offset;
// The read callback will enqueue subsequent reads.
- nand_op->completion_cb = ReadCompletionCallback;
- nand_op->cookie = &op_context;
- nand_.Queue(nand_op);
+ nand_.Queue(nand_op, ReadCompletionCallback, &op_context);
// Wait on completion.
sync_completion_wait(&completion, ZX_TIME_INFINITE);
@@ -323,14 +319,12 @@
.mark_bad = false,
};
- auto* nand_op = reinterpret_cast<nand_op_t*>(nand_op_.get());
+ auto* nand_op = reinterpret_cast<nand_operation_t*>(nand_op_.get());
nand_op->erase.command = NAND_OP_ERASE;
nand_op->erase.first_block = physical_block;
nand_op->erase.num_blocks = 1;
// The erase callback will enqueue subsequent writes and erases.
- nand_op->completion_cb = EraseCompletionCallback;
- nand_op->cookie = &op_context;
- nand_.Queue(nand_op);
+ nand_.Queue(nand_op, EraseCompletionCallback, &op_context);
// Wait on completion.
sync_completion_wait(&completion, ZX_TIME_INFINITE);
diff --git a/system/dev/scpi/aml-scpi-s912/aml-mailbox.c b/system/dev/scpi/aml-scpi-s912/aml-mailbox.c
index d272769..22990de 100644
--- a/system/dev/scpi/aml-scpi-s912/aml-mailbox.c
+++ b/system/dev/scpi/aml-scpi-s912/aml-mailbox.c
@@ -34,8 +34,8 @@
}
static zx_status_t aml_mailbox_send_cmd(void* ctx,
- mailbox_channel_t* channel,
- mailbox_data_buf_t* mdata) {
+ const mailbox_channel_t* channel,
+ const mailbox_data_buf_t* mdata) {
aml_mailbox_t* mailbox = ctx;
int rx_mailbox_id;
if (!channel || !mdata) {
@@ -53,7 +53,7 @@
if (mdata->tx_size != 0) {
uint32_t num = GET_NUM_WORDS(mdata->tx_size);
- uint32_t* tx_payload = (uint32_t*)(mdata->tx_buf);
+ uint32_t* tx_payload = (uint32_t*)(mdata->tx_buffer);
for (uint32_t i = 0; i < num; i++) {
// AP writes parameters to Payload
WRITE32_MAILBOX_PL_REG(tx_mailbox->payload_offset + i, tx_payload[i]);
@@ -73,7 +73,7 @@
// AP reads the Payload to get requested information
if (channel->rx_size != 0) {
uint32_t num = GET_NUM_WORDS(channel->rx_size);
- uint32_t* rx_payload = (uint32_t*)(channel->rx_buf);
+ uint32_t* rx_payload = (uint32_t*)(channel->rx_buffer);
for (uint32_t i = 0; i < num; i++) {
rx_payload[i] = READ32_MAILBOX_PL_REG(rx_mailbox->payload_offset + i);
}
@@ -103,7 +103,7 @@
};
static mailbox_protocol_ops_t mailbox_ops = {
- .send_cmd = aml_mailbox_send_cmd,
+ .send_command = aml_mailbox_send_cmd,
};
static zx_status_t aml_mailbox_bind(void* ctx, zx_device_t* parent) {
diff --git a/system/dev/scpi/aml-scpi-s912/aml-scpi.c b/system/dev/scpi/aml-scpi-s912/aml-scpi.c
index 4bb83ce..3d43e75 100644
--- a/system/dev/scpi/aml-scpi-s912/aml-scpi.c
+++ b/system/dev/scpi/aml-scpi-s912/aml-scpi.c
@@ -56,7 +56,7 @@
uint32_t mailbox_status = 0;
mailbox_data_buf_t mdata;
mdata.cmd = PACK_SCPI_CMD(cmd, client_id, 0);
- mdata.tx_buf = tx_buf;
+ mdata.tx_buffer = tx_buf;
mdata.tx_size = tx_size;
mailbox_channel_t channel;
@@ -66,15 +66,15 @@
return status;
}
- channel.rx_buf = rx_buf;
+ channel.rx_buffer = rx_buf;
channel.rx_size = rx_size;
- status = mailbox_send_cmd(&scpi->mailbox, &channel, &mdata);
+ status = mailbox_send_command(&scpi->mailbox, &channel, &mdata);
if (rx_buf) {
mailbox_status = *(uint32_t*)(rx_buf);
}
if (status != ZX_OK || mailbox_status != 0) {
- SCPI_ERROR("mailbox_send_cmd failed - error status %d\n", status);
+ SCPI_ERROR("mailbox_send_command failed - error status %d\n", status);
return status;
}
return ZX_OK;
diff --git a/system/dev/serial/aml-uart/aml-uart.cpp b/system/dev/serial/aml-uart/aml-uart.cpp
index a333f87..1408eaf 100644
--- a/system/dev/serial/aml-uart/aml-uart.cpp
+++ b/system/dev/serial/aml-uart/aml-uart.cpp
@@ -20,6 +20,7 @@
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <hwreg/mmio.h>
+#include <zircon/device/serial.h>
#include <zircon/threads.h>
#include <zircon/types.h>
@@ -69,7 +70,7 @@
constexpr uint32_t kDefaultBaudRate = 115200;
constexpr uint32_t kDefaultConfig =
SERIAL_DATA_BITS_8 | SERIAL_STOP_BITS_1 | SERIAL_PARITY_NONE;
- uart->Config(kDefaultBaudRate, kDefaultConfig);
+ uart->SerialImplConfig(kDefaultBaudRate, kDefaultConfig);
status = uart->DdkAdd("aml-uart");
if (status != ZX_OK) {
@@ -121,12 +122,12 @@
return 0;
}
-zx_status_t AmlUart::GetInfo(serial_port_info_t* info) {
+zx_status_t AmlUart::SerialImplGetInfo(serial_port_info_t* info) {
memcpy(info, &serial_port_info_, sizeof(*info));
return ZX_OK;
}
-zx_status_t AmlUart::Config(uint32_t baud_rate, uint32_t flags) {
+zx_status_t AmlUart::SerialImplConfig(uint32_t baud_rate, uint32_t flags) {
hwreg::RegisterIo mmio(io_buffer_virt(&mmio_));
// Control register is determined completely by this logic, so start with a clean slate.
@@ -261,7 +262,7 @@
}
}
-zx_status_t AmlUart::Enable(bool enable) {
+zx_status_t AmlUart::SerialImplEnable(bool enable) {
fbl::AutoLock al(&enable_lock_);
if (enable && !enabled_) {
@@ -289,7 +290,7 @@
return ZX_OK;
}
-zx_status_t AmlUart::Read(void* buf, size_t length, size_t* out_actual) {
+zx_status_t AmlUart::SerialImplRead(void* buf, size_t length, size_t* out_actual) {
hwreg::RegisterIo mmio(io_buffer_virt(&mmio_));
auto* bufptr = static_cast<uint8_t*>(buf);
@@ -307,7 +308,7 @@
return ZX_OK;
}
-zx_status_t AmlUart::Write(const void* buf, size_t length, size_t* out_actual) {
+zx_status_t AmlUart::SerialImplWrite(const void* buf, size_t length, size_t* out_actual) {
hwreg::RegisterIo mmio(io_buffer_virt(&mmio_));
const auto* bufptr = static_cast<const uint8_t*>(buf);
@@ -324,7 +325,7 @@
return ZX_OK;
}
-zx_status_t AmlUart::SetNotifyCallback(serial_notify_cb cb, void* cookie) {
+zx_status_t AmlUart::SerialImplSetNotifyCallback(const serial_notify_t* cb) {
{
fbl::AutoLock al(&enable_lock_);
@@ -334,7 +335,8 @@
}
fbl::AutoLock al2(&status_lock_);
- notify_cb_ = [=](uint32_t state) { cb(state, cookie); };
+ serial_notify_t notify_cb = *cb;
+ notify_cb_ = [=](uint32_t state) { notify_cb.callback(notify_cb.ctx, state); };
}
// This will trigger notifying current state.
diff --git a/system/dev/serial/aml-uart/aml-uart.h b/system/dev/serial/aml-uart/aml-uart.h
index 33eff7d..33e5001 100644
--- a/system/dev/serial/aml-uart/aml-uart.h
+++ b/system/dev/serial/aml-uart/aml-uart.h
@@ -33,18 +33,18 @@
DdkRemove();
}
void DdkRelease() {
- Enable(false);
+ SerialImplEnable(false);
io_buffer_release(&mmio_);
delete this;
}
// Serial protocol implementation.
- zx_status_t GetInfo(serial_port_info_t* info);
- zx_status_t Config(uint32_t baud_rate, uint32_t flags);
- zx_status_t Enable(bool enable);
- zx_status_t Read(void* buf, size_t length, size_t* out_actual);
- zx_status_t Write(const void* buf, size_t length, size_t* out_actual);
- zx_status_t SetNotifyCallback(serial_notify_cb cb, void* cookie);
+ zx_status_t SerialImplGetInfo(serial_port_info_t* info);
+ zx_status_t SerialImplConfig(uint32_t baud_rate, uint32_t flags);
+ zx_status_t SerialImplEnable(bool enable);
+ zx_status_t SerialImplRead(void* buf, size_t length, size_t* out_actual);
+ zx_status_t SerialImplWrite(const void* buf, size_t length, size_t* out_actual);
+ zx_status_t SerialImplSetNotifyCallback(const serial_notify_t* cb);
private:
using Callback = fbl::Function<void(uint32_t)>;
diff --git a/system/dev/serial/ftdi/ftdi.c b/system/dev/serial/ftdi/ftdi.c
index 28d429a..8f5fe67 100644
--- a/system/dev/serial/ftdi/ftdi.c
+++ b/system/dev/serial/ftdi/ftdi.c
@@ -9,6 +9,7 @@
#include <ddk/protocol/serial-impl.h>
#include <ddk/protocol/usb.h>
#include <ddk/usb/usb.h>
+#include <zircon/device/serial.h>
#include <zircon/listnode.h>
#include <zircon/hw/usb.h>
@@ -45,8 +46,7 @@
serial_port_info_t serial_port_info;
serial_impl_protocol_t serial;
- serial_notify_cb notify_cb;
- void* notify_cb_cookie;
+ serial_notify_t notify_cb;
bool enabled;
uint32_t state;
// pool of free USB requests
@@ -68,8 +68,8 @@
if (state != ftdi->state) {
ftdi->state = state;
- if (ftdi->notify_cb) {
- ftdi->notify_cb(state, ftdi->notify_cb_cookie);
+ if (ftdi->notify_cb.callback) {
+ ftdi->notify_cb.callback(ftdi->notify_cb.ctx, state);
}
}
return state;
@@ -278,15 +278,14 @@
return ZX_OK;
}
-static zx_status_t ftdi_set_notify_callback(void* ctx, serial_notify_cb cb, void* cookie) {
+static zx_status_t ftdi_set_notify_callback(void* ctx, const serial_notify_t* cb) {
ftdi_t* ftdi = ctx;
if (ftdi->enabled) {
return ZX_ERR_BAD_STATE;
}
- ftdi->notify_cb = cb;
- ftdi->notify_cb_cookie = cookie;
+ ftdi->notify_cb = *cb;
mtx_lock(&ftdi->mutex);
ftdi_check_state(ftdi);
@@ -295,7 +294,7 @@
return ZX_OK;
}
-static serial_impl_ops_t ftdi_serial_ops = {
+static serial_impl_protocol_ops_t ftdi_serial_ops = {
.get_info = ftdi_serial_get_info,
.config = ftdi_serial_config,
.enable = ftdi_serial_enable,
diff --git a/system/dev/serial/serial/serial.c b/system/dev/serial/serial/serial.c
index a2e5546..7b1ff8d 100644
--- a/system/dev/serial/serial/serial.c
+++ b/system/dev/serial/serial/serial.c
@@ -37,6 +37,8 @@
#define EVENT_WRITABLE_SIGNAL ZX_USER_SIGNAL_1
#define EVENT_CANCEL_SIGNAL ZX_USER_SIGNAL_2
+const serial_notify_t kNoCallback = {NULL, NULL};
+
// This thread handles data transfer in both directions
static int platform_serial_thread(void* arg) {
serial_port_t* port = arg;
@@ -136,7 +138,7 @@
}
serial_impl_enable(&port->serial, false);
- serial_impl_set_notify_callback(&port->serial, NULL, NULL);
+ serial_impl_set_notify_callback(&port->serial, &kNoCallback);
zx_handle_close(port->event);
zx_handle_close(port->socket);
@@ -149,7 +151,7 @@
return 0;
}
-static void platform_serial_state_cb(uint32_t state, void* cookie) {
+static void platform_serial_state_cb(void* cookie, uint32_t state) {
serial_port_t* port = cookie;
// update our event handle signals with latest state from the serial driver
@@ -213,7 +215,7 @@
goto fail;
}
- serial_impl_set_notify_callback(&port->serial, platform_serial_state_cb, port);
+ serial_impl_set_notify_callback(&port->serial, &(serial_notify_t){platform_serial_state_cb, port});
status = serial_impl_enable(&port->serial, true);
if (status != ZX_OK) {
@@ -255,7 +257,7 @@
return ZX_ERR_ALREADY_BOUND;
}
- serial_impl_set_notify_callback(&port->serial, platform_serial_state_cb, port);
+ serial_impl_set_notify_callback(&port->serial, &(serial_notify_t){platform_serial_state_cb, port});
zx_status_t status = serial_impl_enable(&port->serial, true);
if (status == ZX_OK) {
@@ -272,7 +274,7 @@
mtx_lock(&port->lock);
if (port->open) {
- serial_impl_set_notify_callback(&port->serial, NULL, NULL);
+ serial_impl_set_notify_callback(&port->serial, &kNoCallback);
serial_impl_enable(&port->serial, false);
port->open = false;
mtx_unlock(&port->lock);
@@ -333,7 +335,7 @@
serial_port_t* port = ctx;
serial_impl_enable(&port->serial, false);
- serial_impl_set_notify_callback(&port->serial, NULL, NULL);
+ serial_impl_set_notify_callback(&port->serial, &kNoCallback);
zx_handle_close(port->event);
zx_handle_close(port->socket);
free(port);
diff --git a/system/dev/test/ddk-test/ddk-test.c b/system/dev/test/ddk-test/ddk-test.c
index 10afe69..c35b0b6 100644
--- a/system/dev/test/ddk-test/ddk-test.c
+++ b/system/dev/test/ddk-test/ddk-test.c
@@ -34,7 +34,7 @@
}
}
-static zx_status_t ddk_test_func(void* cookie, test_report_t* report, const void* arg, size_t arglen) {
+static zx_status_t ddk_test_func(void* cookie, const void* arg, size_t arglen, test_report_t* report) {
zx_device_t* dev = (zx_device_t*)cookie;
test_protocol_t proto;
@@ -62,6 +62,6 @@
}
ddk_test_dev = parent;
- proto.ops->set_test_func(proto.ctx, ddk_test_func, parent);
+ proto.ops->set_test_func(proto.ctx, &(test_func_t){ddk_test_func, parent});
return ZX_OK;
}
diff --git a/system/fidl/ddk/protocols/acpi.fidl b/system/fidl/ddk/protocols/acpi.fidl
new file mode 100644
index 0000000..75cb1eb
--- /dev/null
+++ b/system/fidl/ddk/protocols/acpi.fidl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.acpi;
+
+using zx;
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface Acpi {
+ 1: MapResource(uint32 resource_id, uint32 cache_policy) -> (zx.status s, vector<void>? vaddr,
+ handle<resource> @handle);
+ 2: MapInterrupt(int64 irq_id) -> (zx.status s, handle<interrupt> @handle);
+};
diff --git a/system/fidl/ddk/protocols/amlogic-canvas.fidl b/system/fidl/ddk/protocols/amlogic-canvas.fidl
new file mode 100644
index 0000000..93d7f67
--- /dev/null
+++ b/system/fidl/ddk/protocols/amlogic-canvas.fidl
@@ -0,0 +1,24 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.amlogic_canvas;
+
+using zx;
+
+struct CanvasInfo {
+ uint32 height;
+ uint32 stride_bytes;
+ uint32 wrap;
+ uint32 blkmode;
+ uint32 endianness;
+};
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface Canvas {
+ /// Configures a canvas.
+ /// Adds a framebuffer to the canvas lookup table.
+ 1: Config(handle<vmo> vmo, usize offset, CanvasInfo info) -> (zx.status s, uint8 canvas_idx);
+ /// Frees up a canvas.
+ 2: Free(uint8 canvas_idx) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/bad-block.fidl b/system/fidl/ddk/protocols/bad-block.fidl
new file mode 100644
index 0000000..5fbe9a4
--- /dev/null
+++ b/system/fidl/ddk/protocols/bad-block.fidl
@@ -0,0 +1,20 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.bad_block;
+
+using zx;
+
+[Layout="ddk-protocol"]
+interface BadBlock {
+ /// Fills in |bad_blocks| with a list of bad blocks, up until
+ /// |bad_blocks_count|. The order of blocks is undefined.
+ /// |bad_blocks_actual| will be filled in with the actual number of bad
+ /// blocks. It is recommended to first make call with |bad_blocks_count|
+ /// equal to 0 in order to determine how large the |bad_blocks| is.
+ 1: GetBadBlockList() -> (zx.status s, vector<uint32> bad_blocks);
+
+ /// Sets |block| as bad. If block is already marked bad, it has no effect.
+ 2: MarkBlockBad(uint32 block) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/block.fidl b/system/fidl/ddk/protocols/block.fidl
new file mode 100644
index 0000000..c825f9b
--- /dev/null
+++ b/system/fidl/ddk/protocols/block.fidl
@@ -0,0 +1,92 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.block;
+
+using zircon.device.block;
+using zx;
+
+struct BlockReadWrite {
+ /// Command and flags.
+ uint32 command;
+ /// Available for temporary use.
+ uint32 extra;
+ /// VMO of data to read or write.
+ handle<vmo> vmo;
+ /// Transfer length in blocks (0 is invalid).
+ uint32 length;
+ /// Device offset in blocks.
+ uint64 offset_dev;
+ /// VMO offset in blocks.
+ uint64 offset_vmo;
+ /// Optional physical page list.
+ vector<uint64>? page;
+};
+
+struct BlockTrim {
+ /// Command and flags.
+ uint32 command;
+ // ???
+};
+
+union BlockOp {
+ /// All Commands
+ uint32 command;
+ /// `BLOCK_OP_READ`, `BLOCK_OP_WRITE`
+ BlockReadWrite rw;
+ /// `BLOCK_OP_TRIM`
+ BlockTrim trim;
+};
+
+/// Read and Write ops use rw for parameters.
+///
+/// If rw.pages is not NULL, the VMO is already appropriately pinned
+/// for IO and pages is an array of the physical addresses covering
+/// offset_vmo * block_size through (offset_vmo + length + 1U) * block_size.
+///
+/// The number of entries in this array is always
+/// ((rw.length + 1U * block_size + PAGE_SIZE - 1) / PAGE_SIZE)
+const uint32 BLOCK_OP_READ = 0x00000001;
+const uint32 BLOCK_OP_WRITE = 0x00000002;
+
+/// Write any controller or device cached data to nonvolatile storage.
+/// This operation always implies BARRIER_BEFORE and BARRIER_AFTER,
+/// meaning that previous operations will complete before it starts
+/// and later operations will not start until it is done.
+const uint32 BLOCK_OP_FLUSH = 0x00000003;
+
+// TBD
+const uint32 BLOCK_OP_TRIM = 0x00000004;
+const uint32 BLOCK_OP_MASK = 0x000000FF;
+
+/// Mark this operation as "Force Unit Access" (FUA), indicating that
+/// it should not complete until the data is written to the non-volatile
+/// medium (write), and that reads should bypass any on-device caches.
+const uint32 BLOCK_FL_FORCE_ACCESS = 0x00001000;
+
+/// Require that this operation will not begin until all previous
+/// operations have completed.
+///
+/// Prevents earlier operations from being reordered after this one.
+const uint32 BLOCK_FL_BARRIER_BEFORE = 0x00000100;
+
+/// Require that this operation complete before any subsequent
+/// operations are started.
+///
+/// Prevents later operations from being reordered before this one.
+const uint32 BLOCK_FL_BARRIER_AFTER = 0x00000200;
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface Block {
+ /// Obtain the parameters of the block device (block_info_t) and
+ /// the required size of block_txn_t. The block_txn_t's submitted
+ /// via queue() must have block_op_size_out - sizeof(block_op_t) bytes
+ /// available at the end of the structure for the use of the driver.
+ 1: Query() -> (zircon.device.block.BlockInfo info, usize block_op_size);
+ /// Submit an IO request for processing. Success or failure will
+ /// be reported via the completion_cb() in the block_op_t. This
+ /// callback may be called before the queue() method returns.
+ [Async]
+ 2: Queue(BlockOp? txn) -> (zx.status status, BlockOp op);
+};
diff --git a/system/fidl/ddk/protocols/bt-gatt-svc.fidl b/system/fidl/ddk/protocols/bt-gatt-svc.fidl
new file mode 100644
index 0000000..43b6935
--- /dev/null
+++ b/system/fidl/ddk/protocols/bt-gatt-svc.fidl
@@ -0,0 +1,132 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.bt_gatt_svc;
+
+using zx;
+
+//using BtGattId = uint64;
+enum BtGattId : uint64 {};
+
+struct BtGattUuid {
+ array<uint8>:16 bytes;
+};
+
+/// ATT protocol error codes.
+enum BtGattErr : uint8 {
+ NO_ERROR = 0x00;
+ INVALID_HANDLE = 0x01;
+ READ_NOT_PERMITTED = 0x02;
+ WRITE_NOT_PERMITTED = 0x03;
+ INVALID_PDU = 0x04;
+ INSUFFICIENT_AUTHENTICATION = 0x05;
+ REQUEST_NOT_SUPPORTED = 0x06;
+ INVALID_OFFSET = 0x07;
+ INSUFFICIENT_AUTHORIZATION = 0x08;
+ PREPARE_QUEUE_FULL = 0x09;
+ ATTRIBUTE_NOT_FOUND = 0x0A;
+ ATTRIBUTENOTLONG = 0x0B;
+ INSUFFICIENT_ENCRYPTION_KEY_SIZE = 0x0C;
+ INVALID_ATTRIBUTE_VALUE_LENGTH = 0x0D;
+ UNLIKELY_ERROR = 0x0E;
+ INSUFFICIENT_ENCRYPTION = 0x0F;
+ UNSUPPORTED_GROUP_TYPE = 0x10;
+ INSUFFICIENT_RESOURCES = 0x11;
+};
+
+/// Represents the status of a GATT operation.
+struct BtGattStatus {
+ /// Represents errors reported by the host (i.e. not over ATT).
+ zx.status status;
+
+ /// ATT protocol error.
+ BtGattErr att_ecode;
+};
+
+//inline bool bt_gatt_status_is_success(bt_gatt_status_t* status) {
+// return (status->status == ZX_OK) &&
+// (status->att_ecode == BT_GATT_ERR_NO_ERROR);
+//}
+
+/// Possible values for the characteristic properties bitfield.
+enum BtGattChrPropr : uint8 {
+ BROADCAST = 0x01;
+ READ = 0x02;
+ WRITE_WITHOUT_RESPONSE = 0x04;
+ WRITE = 0x08;
+ NOTIFY = 0x10;
+ INDICATE = 0x20;
+ AUTHENTICATED_SIGNED_WRITES = 0x40;
+ EXTENDED_PROPERTIES = 0x80;
+};
+
+enum BtGattChrExtProp : uint16 {
+ RELIABLE_WRITE = 0x0100;
+ WRITABLE_AUXILIARIES = 0x0200;
+};
+
+/// Represents a GATT characteristic descriptor.
+struct BtGattDescriptor {
+ BtGattId id;
+ BtGattUuid type;
+};
+
+/// Represents a GATT characteristic.
+struct BtGattChr {
+ BtGattId id;
+ BtGattUuid type;
+
+ /// The bitmask of characteristic properties. The |extended_properties| field
+ /// is populated if the "Characteristic Extended Properties" descriptor is
+ /// present.
+ ///
+ /// See enums |BtGattChrProp| and |BtGattChrExtProp| for possible bit values.
+ uint8 properties;
+ uint16 extended_properties;
+
+ vector<BtGattDescriptor> descriptor;
+};
+
+/// Value change notification callback of the |EnableNotifications| function.
+[Layout="ddk-callback"]
+interface BtGattNotificationValue {
+ 1: Callback(BtGattId id, vector<void> value) -> ();
+};
+
+[Layout="ddk-protocol"]
+interface BtGattSvc {
+ /// Connects to and starts characteristic discovery on the remote service.
+ ///
+ /// |status| will contain the result of the characteristic discovery procedure if it was
+ /// initiated by |connect|. The service will be ready to receive further requests once this
+ /// has been called successfully and the |status| callback has been called with success.
+ [Async]
+ 1: Connect() -> (BtGattStatus status, vector<BtGattChr> characteristic);
+
+ /// Stops this service and unregisters previously registered callbacks.
+ 2: Stop() -> ();
+
+ /// Reads the value of the characteristic with the given ID.
+ [Async]
+ 3: ReadCharacteristic(BtGattId id) -> (BtGattStatus status, BtGattId id, vector<void> value);
+
+ /// Reads the long value of the characteristic with the given ID.
+ [Async]
+ 4: ReadLongCharacteristic(BtGattId id, uint16 offset, usize max_bytes)
+ -> (BtGattStatus status, BtGattId id, vector<void> value);
+
+ [Async]
+ 5: WriteCharacteristic(BtGattId id, vector<void> buf) -> (BtGattStatus status, BtGattId id);
+
+ /// Enables notifications from the characteristic with the given ID. Returns
+ /// `ZX_ERR_BAD_STATE` if the service has not been started yet.
+ ///
+ /// Returns `ZX_ERR_SHOULD_WAIT` if this request is already in progress.
+ ///
+ /// The async callback will be called to asynchronously report the result
+ /// of this operation.
+ [Async]
+ 6: EnableNotifications(BtGattId id, BtGattNotificationValue value_cb)
+ -> (BtGattStatus status, BtGattId id);
+};
diff --git a/system/fidl/ddk/protocols/bt-hci.fidl b/system/fidl/ddk/protocols/bt-hci.fidl
new file mode 100644
index 0000000..25174c8
--- /dev/null
+++ b/system/fidl/ddk/protocols/bt-hci.fidl
@@ -0,0 +1,26 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.bt_hci;
+
+using zx;
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface BtHci {
+ /// Open the two-way HCI command channel for sending HCI commands and
+ /// receiving event packets. Returns ZX_ERR_ALREADY_BOUND if the channel
+ /// is already open.
+ 1: OpenCommandChannel() -> (zx.status s, handle<channel> channel);
+ /// Open the two-way HCI ACL data channel.
+ /// Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+ 2: OpenAclDataChannel() -> (zx.status s, handle<channel> channel);
+ /// Open an output-only channel for monitoring HCI traffic.
+ /// The format of each message is: [1-octet flags] [n-octet payload]
+ /// The flags octet is a bitfield with the following values defined:
+ /// - 0x00: The payload represents a command packet sent from the host to the
+ /// controller.
+ /// - 0x01: The payload represents an event packet sent by the controller.
+ /// Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+ 3: OpenSnoopChannel() -> (zx.status s, handle<channel> channel);
+};
diff --git a/system/fidl/ddk/protocols/clk.fidl b/system/fidl/ddk/protocols/clk.fidl
new file mode 100644
index 0000000..2b2c0f0
--- /dev/null
+++ b/system/fidl/ddk/protocols/clk.fidl
@@ -0,0 +1,13 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.clk;
+
+using zx;
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface Clk {
+ 1: Enable(uint32 index) -> (zx.status s);
+ 2: Disable(uint32 index) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/display-controller.fidl b/system/fidl/ddk/protocols/display-controller.fidl
new file mode 100644
index 0000000..349d6b6
--- /dev/null
+++ b/system/fidl/ddk/protocols/display-controller.fidl
@@ -0,0 +1,390 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.display_controller;
+
+using zircon.device.audio;
+using zx;
+
+//using ZxPixelFormat = uint32;
+enum ZxPixelFormat : uint32 {};
+
+/// The image is linear and VMO backed.
+const uint32 IMAGE_TYPE_SIMPLE = 0;
+
+/// A structure containing information about each plane of an image.
+struct ImagePlane {
+ uint32 byte_offset;
+ uint32 bytes_per_row;
+};
+
+/// A structure containing information about an image.
+struct Image {
+ /// The width and height of the image in pixels.
+ uint32 width;
+ uint32 height;
+
+ /// The pixel format of the image.
+ ZxPixelFormat pixel_format;
+
+ /// The type conveys information about what is providing the pixel data. If this is not
+ /// IMAGE_FORMAT_SIMPLE, it is up to the driver and buffer producer to agree on the meaning
+ /// of the value through some mechanism outside the scope of this API.
+ uint32 type;
+
+ array<ImagePlane>:4 planes;
+
+ /// A driver-defined handle to the image. Each handle must be unique.
+ uint64 @handle;
+};
+
+const uint32 INVALID_DISPLAY_ID = 0;
+
+/// A fallback structure to convey display information without an edid.
+struct DisplayParams {
+ uint32 width;
+ uint32 height;
+ uint32 refresh_rate_e2;
+};
+
+/// Info about valid cursor configuratoins.
+struct CursorInfo {
+ /// The width and height of the cursor configuration, in pixels.
+ uint32 width;
+ uint32 height;
+ ZxPixelFormat format;
+};
+
+union Panel {
+ /// The bus_id to use to read this display's edid from the device's i2c protocol.
+ uint32 i2c_bus_id;
+ /// The display's parameters if an edid is not present.
+ DisplayParams params;
+};
+
+/// A structure containing information a connected display.
+struct AddedDisplayArgs {
+ uint64 display_id;
+
+ /// A flag indicating whether or not the display has a valid edid.
+ ///
+ /// If true, the device should expose an ZX_PROTOCOL_I2C_IMPL device through get_protocol, in
+ /// addition to the ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL protocol. Note that the i2c device
+ /// will be called from the on_displays_changed callback, so care should be taken to avoid
+ /// deadlocks or double-locking.
+ ///
+ /// If no edid is present, then the meaning of display_config's mode structure is
+ /// undefined, and drivers should ignore it in check_configuration and apply_configuration.
+ bool edid_present;
+ Panel panel;
+
+ /// A list of pixel formats supported by the display. The first entry is the
+ /// preferred pixel format.
+ vector<ZxPixelFormat> pixel_format;
+
+ /// A list of cursor configurations most likely to be accepted by the driver. Can
+ /// be null if cursor_count is 0.
+ ///
+ /// The driver may reject some of these configurations in some circumstances, and
+ /// it may accept other configurations, but at least one of these configurations
+ /// should be valid at most times.
+ vector<CursorInfo> cursor_info;
+};
+
+/// Out parameters will be populated before on_displays_changed returns.
+struct AddedDisplayInfo {
+ bool is_hdmi_out;
+ bool is_standard_srgb_out;
+
+ uint32 audio_format_count;
+
+ string manufacturer_name;
+ /// null-terminated
+ string:14 monitor_name;
+ /// null-terminated
+ string:14 monitor_serial;
+};
+
+/// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device
+/// during these callbacks.
+[Layout="ddk-interface"]
+interface DisplayControllerInterface {
+ /// Callbacks which are invoked when displays are added or removed. |added_display_list| and
+ /// |removed_display_list| point to arrays of the display ids which were added and removed. If
+ /// |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
+ ///
+ /// The driver must be done accessing any images which were on the removed displays.
+ ///
+ /// The driver should call this function when the callback is registered if any displays
+ /// are present.
+ 1: OnDisplaysChanged(vector<AddedDisplayArgs> added_display,
+ vector<uint64> removed_display) -> (vector<AddedDisplayInfo> display_info);
+
+ /// |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
+ /// |handles| points to an array of image handles of each framebuffer being
+ /// displayed, in increasing z-order.
+ 2: OnDisplayVsync(uint64 display_id, zx.time timestamp, vector<uint64> @handle) -> ();
+
+ 3: GetAudioFormat(uint64 display_id, uint32 fmt_idx)
+ -> (zx.status s, zircon.device.audio.AudioStreamFormatRange fmt);
+};
+
+enum Alpha : uint8 {
+ DISABLE = 0;
+ PREMULTIPLIED = 1;
+ HW_MULTIPLY = 2;
+};
+
+/// Rotations are applied counter-clockwise, and are applied before reflections.
+enum FrameTransform : uint32 {
+ IDENTITY = 0;
+ REFLECT_X = 1;
+ REFLECT_Y = 2;
+ ROT_90 = 3;
+ ROT_180 = 4;
+ ROT_270 = 5;
+ ROT_90_REFLECT_X = 6;
+ ROT_90_REFLECT_Y = 7;
+};
+
+struct Frame {
+ /// (|x_pos|, |y_pos|) specifies the position of the upper-left corner
+ /// of the frame.
+ uint32 x_pos;
+ uint32 y_pos;
+ uint32 width;
+ uint32 height;
+};
+
+struct PrimaryLayer {
+ Image image;
+
+ /// An ALPHA_* constant.
+ ///
+ /// If |alpha_mode| == `ALPHA_DISABLED`, the layer is opaque and alpha_layer_val is ignored.
+ ///
+ /// If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is NaN, the alpha
+ /// used when blending is determined by the per-pixel alpha channel.
+ ///
+ /// If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is not NaN, the
+ /// alpha used when blending is the product of alpha_layer_val and any per-pixel alpha.
+ /// Additionally, if alpha_mode == PREMULTIPLIED, then the hardware must premultiply the color
+ /// channel with alpha_layer_val before blending.
+ ///
+ /// If alpha_layer_val is not NaN, it will be in the range [0, 1].
+ Alpha alpha_mode;
+ float32 alpha_layer_val;
+
+ FrameTransform transform_mode;
+
+ /// The source frame, where (0,0) is the top-left corner of the image. The
+ /// client guarantees that src_frame lies entirely within the image.
+ Frame src_frame;
+
+ /// The destination frame, where (0,0) is the top-left corner of the
+ /// composed output. The client guarantees that dest_frame lies entirely
+ /// within the composed output.
+ Frame dest_frame;
+};
+
+struct CursorLayer {
+ Image image;
+
+ /// The position of the top-left corner of the cursor's image. When being
+ /// applied to a display, the cursor is guaranteed to have at least one
+ /// pixel of overlap with the display.
+ int32 x_pos;
+ int32 y_pos;
+};
+
+struct ColorLayer {
+ ZxPixelFormat format;
+ /// The color to use for the layer. The color is little-endian, and is
+ /// guaranteed to be of the appropriate size.
+ vector<uint8> color;
+};
+
+/// Types of layers.
+
+enum LayerType : uint32 {
+ PRIMARY = 0;
+ CURSOR = 1;
+ COLOR = 2;
+};
+
+union LayerConfig {
+ PrimaryLayer primary;
+ CursorLayer cursor;
+ ColorLayer color;
+};
+
+struct Layer {
+ LayerType type;
+ /// z_index of the layer. See |check_configuration| and |apply_configuration|.
+ uint32 z_index;
+ LayerConfig cfg;
+};
+
+/// constants for display_config's mode_flags field
+enum ModeFlag : uint32 {
+ VSYNC_POSITIVE = 0x1;
+ HSYNC_POSITIVE = 0x2;
+ INTERLACED = 0x4;
+ ALTERNATING_VBLANK = 0x8;
+ DOUBLE_CLOCKED = 0x10;
+};
+
+/// The video parameters which specify the display mode.
+struct DisplayMode {
+ uint32 pixel_clock_10khz;
+ uint32 h_addressable;
+ uint32 h_front_porch;
+ uint32 h_sync_pulse;
+ uint32 h_blanking;
+ uint32 v_addressable;
+ uint32 v_front_porch;
+ uint32 v_sync_pulse;
+ uint32 v_blanking;
+ /// A bitmask of MODE_FLAG_* values
+ uint32 flags;
+};
+
+enum ColorConversion : uint32 {
+ /// If set, use the 0 vector for the color conversion preoffset
+ PREOFFSET = 0x1;
+ /// If set, use the identity matrix for the color conversion coefficients
+ COEFFICIENTS = 0x2;
+ /// If set, use the 0 vector for the color conversion postoffset
+ POSTOFFSET = 0x4;
+};
+
+struct DisplayConfig {
+ /// the display id to which the configuration applies
+ uint64 display_id;
+
+ DisplayMode mode;
+
+ /// Bitmask of COLOR_CONVERSION_* flags
+ uint32 cc_flags;
+ /// Color conversion is applied to each pixel according to the formula:
+ ///
+ /// (cc_coefficients * (pixel + cc_preoffsets)) + cc_postoffsets
+ ///
+ /// where pixel is a column vector consiting of the pixel's 3 components.
+ array<float32>:3 cc_preoffsets;
+ array<array<float32>:3>:3 cc_coefficients;
+ array<float32>:3 cc_postoffsets;
+
+ vector<Layer?> layer;
+};
+
+enum ConfigDisplay : uint32 {
+ /// The display mode configuration is valid. Note that this is distinct from
+ /// whether or not the layer configuration is valid.
+ OK = 0;
+ /// Error indicating that the hardware cannot simultaniously support the
+ /// requested number of displays.
+ TOO_MANY = 1;
+ /// Error indicating that the hardware cannot simultaniously support the given
+ /// set of display modes. To support a mode, the display must be able to display
+ /// a single layer with width and height equal to the requested mode and the
+ /// preferred pixel format.
+ UNSUPPORTED_MODES = 2;
+};
+
+enum Client : uint32 {
+ /// The client should convert the corresponding layer to a primary layer.
+ USE_PRIMARY = 0x1;
+ /// The client should compose all layers with MERGE_BASE and MERGE_SRC into a new,
+ /// single primary layer at the MERGE_BASE layer's z-order. The driver must accept
+ /// a fullscreen layer with the default pixel format, but may accept other layer
+ /// parameters.
+ ///
+ /// MERGE_BASE should only be set on one layer per display. If it is set on multiple
+ /// layers, the client will arbitrarily pick one and change the rest to MERGE_SRC.
+ MERGE_BASE = 0x2;
+ MERGE_SRC = 0x4;
+ /// The client should pre-scale the image so that src_frame's dimensions are equal
+ /// to dest_frame's dimensions.
+ FRAME_SCALE = 0x8;
+ /// The client should pre-clip the image so that src_frame's dimensions are equal to
+ /// the image's dimensions.
+ SRC_FRAME = 0x10;
+ /// The client should pre-apply the transformation so TRANSFORM_IDENTITY can be used.
+ TRANSFORM = 0x20;
+ /// The client should apply the color conversion.
+ COLOR_CONVERSION = 0x40;
+ /// The client should apply the alpha transformation itself.
+ ALPHA = 0x80;
+};
+
+/// The client guarantees that check_configuration and apply_configuration are always
+/// made from a single thread. The client makes no other threading guarantees.
+[Layout="ddk-protocol"]
+interface DisplayController {
+ /// The function will only be called once, and it will be called before any other
+ /// functions are called.
+ 1: SetDisplayControllerInterface(DisplayControllerInterface intf) -> ();
+
+ /// Imports a VMO backed image into the driver. The driver should set image->handle. The
+ /// driver does not own the vmo handle passed to this function.
+ 2: ImportVmoImage(Image? image, handle<vmo> vmo, usize offset) -> (zx.status s);
+
+ /// Releases any driver state associated with the given image. The client guarantees that
+ /// any images passed to apply_config will not be released until a vsync occurs with a
+ /// more recent image.
+ 3: ReleaseImage(Image? image) -> ();
+
+ /// Validates the given configuration.
+ ///
+ /// The configuration may not include all displays. Omiteed displays should be treated as
+ /// whichever of off or displaying a blank screen results in a more premissive validation.
+ ///
+ /// All displays in a configuration will have at least one layer. The layers will be
+ /// arranged in increasing z-order, and their z_index fields will be set consecutively.
+ ///
+ /// Whether or not the driver can accept the configuration cannot depend on the
+ /// particular image handles, as it must always be possible to present a new image in
+ /// place of another image with a matching configuration. It also cannot depend on the
+ /// cursor position, as that can be updated without another call to check_configuration.
+ ///
+ /// display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
+ /// display modes is not supported.
+ ///
+ /// layer_cfg_result points to an array of arrays. The primary length is display_count, the
+ /// secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
+ /// is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
+ /// flag in the corresponding layer_cfg_result entry.
+ ///
+ /// The driver must not retain references to the configuration after this function returns.
+ /// TODO: Fix me...
+ 4: CheckConfiguration(vector<DisplayConfig?> display_config)
+ -> (uint32 display_cfg_result, vector<uint32>? layer_cfg_result);
+
+ /// Applies the configuration.
+ ///
+ /// All configurations passed to this function will be derived from configurations which
+ /// have been succesfully validated, with the only differences either being omitted layers
+ /// or different image handles. To account for any layers which are not present, the driver
+ /// must use the z_index values of the present layers to configure them as if the whole
+ /// configuration was present.
+ ///
+ /// Unlike with check_configuration, displays included in the configuration are not
+ /// guaranteed to include any layers. Both omitted displays and displays with no layers
+ /// can either be turned off or set to display a blank screen, but for displays with no
+ /// layers there is a strong preference to display a blank screen instead of turn them off.
+ /// In either case, the driver must drop all references to old images and invoke the vsync
+ /// callback after doing so.
+ ///
+ /// The driver must not retain references to the configuration after this function returns.
+ 5: ApplyConfiguration(vector<DisplayConfig?> display_config) -> ();
+
+ /// Computes the stride (in pixels) necessary for a linear image with the given width
+ /// and pixel format. Returns 0 on error.
+ 6: ComputeLinearStride(uint32 width, ZxPixelFormat pixel_format) -> (uint32 s);
+
+ /// Allocates a VMO of the requested size which can be used for images.
+ // TODO: move this functionallity into a seperate video buffer management system.
+ 7: AllocateVmo(uint64 size) -> (zx.status s, handle<vmo> vmo);
+};
diff --git a/system/fidl/ddk/protocols/ethernet.fidl b/system/fidl/ddk/protocols/ethernet.fidl
new file mode 100644
index 0000000..35f3911
--- /dev/null
+++ b/system/fidl/ddk/protocols/ethernet.fidl
@@ -0,0 +1,149 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.ethernet;
+
+using zircon.listnode;
+using zx;
+
+const uint32 ETH_MAC_SIZE = 6; // bytes
+const uint32 ETH_MTU_SIZE = 1500; // bytes
+const uint32 ETH_FRAME_MAX_HDR_SIZE = 18; // bytes. MAC Dest(6) + MAC Src(6) + 802.1Q tag(4) + Ethertype(2)
+const uint32 ETH_FRAME_MAX_SIZE = 1518;
+
+/// The ethermac interface supports both synchronous and asynchronous transmissions using the
+/// proto->queue_tx() and ifc->complete_tx() methods.
+///
+/// Receive operations are supported with the ifc->recv() interface.
+// TODO: implement netbuf-based receive operations by implementing proto->queue_rx() and
+// ifc->complete_rx()
+///
+/// The FEATURE_WLAN flag indicates a device that supports wlan operations.
+///
+/// The FEATURE_SYNTH flag indicates a device that is not backed by hardware.
+///
+/// The FEATURE_DMA flag indicates that the device can copy the buffer data using DMA and will ensure
+/// that physical addresses are provided in netbufs.
+
+enum EthmacFeature : uint32 {
+ WLAN = 0x1;
+ SYNTH = 0x2;
+ DMA = 0x4;
+};
+
+struct EthmacInfo {
+ uint32 features;
+ uint32 mtu;
+ array<uint8>:ETH_MAC_SIZE mac;
+ array<uint8>:2 reserved0;
+ array<uint32>:4 reserved1;
+};
+
+union Internal {
+ uint64 val;
+ vector<void> ptr;
+};
+
+struct EthmacNetbuf {
+ /// Provided by the generic ethernet driver.
+ vector<void> data;
+ /// Only used if ETHMAC_FEATURE_DMA is available.
+ zx.paddr phys;
+ uint16 reserved;
+ uint32 flags;
+
+ /// Shared between the generic ethernet and ethmac drivers.
+ zircon.listnode.ListNode node;
+
+ /// For use by the ethmac driver.
+ Internal u;
+};
+
+[Layout="ddk-interface"]
+interface EthmacIfc {
+ 1: Status(uint32 status) -> ();
+
+ 2: Recv(vector<void> data, uint32 flags) -> ();
+
+ /// complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
+ /// Return status indicates queue state:
+ /// ZX_OK: Packet has been enqueued.
+ /// Other: Packet could not be enqueued.
+ /// Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
+ /// the completion state of the transmission itself.
+ 3: CompleteTx(EthmacNetbuf? netbuf, zx.status status) -> ();
+};
+
+/// Indicates that additional data is available to be sent after this call finishes. Allows a ethmac
+/// driver to batch tx to hardware if possible.
+const uint32 ETHMAC_TX_OPT_MORE = 1;
+
+/// SETPARAM_ values identify the parameter to set. Each call to set_param()
+/// takes an int32_t |value| and void* |data| which have meaning specific to
+/// the parameter being set.
+
+/// |value| is bool. |data| is unused.
+const uint32 ETHMAC_SETPARAM_PROMISC = 1;
+
+/// |value| is bool. |data| is unused.
+const uint32 ETHMAC_SETPARAM_MULTICAST_PROMISC = 2;
+
+const int32 ETHMAC_MULTICAST_FILTER_OVERFLOW = -1;
+
+/// |value| is number of addresses, or ETHMAC_MULTICAST_FILTER_OVERFLOW for "too many to count."
+/// |data| is |value|*6 bytes of MAC addresses. Caller retains ownership.
+/// If |value| is _OVERFLOW, |data| is ignored.
+const uint32 ETHMAC_SETPARAM_MULTICAST_FILTER = 3;
+
+const uint32 ETHMAC_SETPARAM_DUMP_REGS = 4;
+
+/// The ethernet midlayer will never call ethermac_protocol
+/// methods from multiple threads simultaneously, but it
+/// can call send() methods at the same time as non-send
+/// methods.
+[Layout="ddk-protocol"]
+interface Ethmac {
+ /// Obtain information about the ethermac device and supported features
+ /// Safe to call at any time.
+ 1: Query(uint32 options) -> (zx.status s, EthmacInfo info);
+
+ /// Shut down a running ethermac
+ /// Safe to call if the ethermac is already stopped.
+ 2: Stop() -> ();
+
+ /// Start ethermac running with ifc_virt
+ /// Callbacks on ifc may be invoked from now until stop() is called
+ 3: Start(EthmacIfc ifc) -> (zx.status s);
+
+ /// Request transmission of the packet in netbuf. Return status indicates queue state:
+ /// ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
+ /// ZX_OK: Packet has been enqueued.
+ /// Other: Packet could not be enqueued.
+ ///
+ /// In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
+ /// to return it once the enqueue is complete. complete_tx() may be used to return the packet
+ /// before transmission itself completes, but MUST NOT be called from within the queue_tx()
+ /// implementation.
+ ///
+ /// queue_tx() may be called at any time after start() is called including from multiple threads
+ /// simultaneously.
+ 4: QueueTx(uint32 options, EthmacNetbuf? netbuf) -> (zx.status s);
+
+ /// Request a settings change for the driver. Return status indicates disposition:
+ /// ZX_OK: Request has been handled.
+ /// ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
+ /// Other: Error trying to support this request.
+ ///
+ /// |value| and |data| usage are defined for each |param|; see comments above.
+ ///
+ /// set_param() may be called at any time after start() is called including from multiple threads
+ /// simultaneously.
+ 5: SetParam(uint32 param, int32 value, vector<void> data) -> (zx.status s);
+
+ /// Get the BTI handle (needed to pin DMA memory) for this device.
+ /// This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
+ /// The caller does *not* take ownership of the BTI handle and must never close
+ /// the handle.
+ 6: GetBti() -> (handle<bti> bti);
+};
diff --git a/system/fidl/ddk/protocols/gpio.fidl b/system/fidl/ddk/protocols/gpio.fidl
new file mode 100644
index 0000000..4f207ee
--- /dev/null
+++ b/system/fidl/ddk/protocols/gpio.fidl
@@ -0,0 +1,45 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.gpio;
+
+using zx;
+
+
+/// Flags for `ConfigIn`.
+const uint32 GPIO_PULL_DOWN = 0x0;
+const uint32 GPIO_PULL_UP = 0x10;
+const uint32 GPIO_NO_PULL = 0x20;
+const uint32 GPIO_PULL_MASK = 0x30;
+
+/// Values for `SetPolarity`.
+enum GpioPolarity : uint32 {
+ LOW = 0x0;
+ HIGH = 0x1;
+};
+
+/// In the functions below, the GPIO index is relative to the list of GPIOs for the device.
+/// For example, the list of GPIOs a platform device has access to would likely be a small
+/// subset of the total number of GPIOs, while a platform bus implementation driver would
+/// have access to the complete set of GPIOs.
+[Layout="ddk-protocol"]
+interface Gpio {
+ /// Configures a GPIO for input.
+ 1: ConfigIn(uint32 index, uint32 flags) -> (zx.status s);
+ /// Configures a GPIO for output.
+ 2: ConfigOut(uint32 index, uint8 initial_value) -> (zx.status s);
+ /// Configures the GPIO pin for an alternate function (I2C, SPI, etc)
+ /// the interpretation of "function" is platform dependent.
+ 3: SetAltFunction(uint32 index, uint64 function) -> (zx.status s);
+ /// Reads the current value of a GPIO (0 or 1).
+ 4: Read(uint32 index) -> (zx.status s, uint8 value);
+ /// Sets the current value of the GPIO (any non-zero value maps to 1).
+ 5: Write(uint32 index, uint8 value) -> (zx.status s);
+ /// Gets an interrupt object pertaining to a particular GPIO pin.
+ 6: GetInterrupt(uint32 index, uint32 flags) -> (zx.status s, handle<interrupt> irq);
+ /// Release the interrupt.
+ 7: ReleaseInterrupt(uint32 index) -> (zx.status s);
+ /// Set GPIO polarity.
+ 8: SetPolarity(uint32 index, GpioPolarity polarity) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/hidbus.fidl b/system/fidl/ddk/protocols/hidbus.fidl
new file mode 100644
index 0000000..d246ca9
--- /dev/null
+++ b/system/fidl/ddk/protocols/hidbus.fidl
@@ -0,0 +1,66 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.hidbus;
+
+using zx;
+
+enum HidDescriptionType : uint8 {
+ REPORT = 0x22;
+};
+
+enum HidReportType : uint8 {
+ INPUT = 1;
+ OUTPUT = 2;
+ FEATURE = 3;
+};
+
+enum HidProtocol : uint8 {
+ BOOT = 0;
+ REPORT = 0;
+};
+
+enum HidDeviceClass : uint8 {
+ OTHER = 0;
+ KBD = 1;
+ POINTER = 2;
+ KBD_POINTER = 3;
+
+ FIRST = 0;
+ LAST = 3;
+};
+
+struct HidInfo {
+ uint8 dev_num;
+ HidDeviceClass device_class;
+ bool boot_device;
+};
+
+[Layout="ddk-interface"]
+interface HidbusIfc {
+ /// Queues a report received by the hidbus device.
+ 1: IoQueue(vector<void> buf) -> ();
+};
+
+[Layout="ddk-protocol"]
+interface Hidbus {
+ /// Obtain information about the hidbus device and supported features.
+ /// Safe to call at any time.
+ 1: Query(uint32 options) -> (zx.status s, HidInfo info);
+ /// Start the hidbus device. The device may begin queueing hid reports via
+ /// ifc->io_queue before this function returns. It is an error to start an
+ /// already-started hidbus device.
+ 2: Start(HidbusIfc ifc) -> (zx.status s);
+ /// Stop the hidbus device. Safe to call if the hidbus is already stopped.
+ 3: Stop() -> ();
+ /// What are the ownership semantics with regards to the data buffer passed back?
+ /// is len an input and output parameter?
+ 4: GetDescriptor(HidDescriptionType desc_type) -> (zx.status s, vector<void>? data);
+ 5: GetReport(HidReportType rpt_type, uint8 rpt_id) -> (zx.status s, vector<void> data);
+ 6: SetReport(HidReportType rpt_type, uint8 rpt_id, vector<void> data) -> (zx.status s);
+ 7: GetIdle(uint8 rpt_id) -> (zx.status s, uint8 duration);
+ 8: SetIdle(uint8 rpt_id, uint8 duration) -> (zx.status s);
+ 9: GetProtocol() -> (zx.status s, HidProtocol protocol);
+ 10: SetProtocol(HidProtocol protocol) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/i2c-impl.fidl b/system/fidl/ddk/protocols/i2c-impl.fidl
new file mode 100644
index 0000000..dc13058
--- /dev/null
+++ b/system/fidl/ddk/protocols/i2c-impl.fidl
@@ -0,0 +1,18 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.i2c;
+
+using zx;
+
+/// Low-level protocol for i2c drivers.
+[Layout="ddk-protocol"]
+interface I2cImpl {
+ 1: GetBusCount() -> (uint32 count);
+ 2: GetMaxTransferSize(uint32 bus_id) -> (zx.status s, usize size);
+ /// Sets the bitrate for the i2c bus in KHz units.
+ 3: SetBitrate(uint32 bus_id, uint32 bitrate) -> (zx.status s);
+ [Async]
+ 4: Transact(uint32 bus_id, uint16 address, vector<void> write) -> (vector<void> read);
+};
diff --git a/system/fidl/ddk/protocols/i2c.fidl b/system/fidl/ddk/protocols/i2c.fidl
new file mode 100644
index 0000000..166a389
--- /dev/null
+++ b/system/fidl/ddk/protocols/i2c.fidl
@@ -0,0 +1,25 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.i2c;
+
+using zx;
+
+const uint32 I2C_10_BIT_ADDR_MASK = 0xF000;
+
+[Layout="ddk-protocol"]
+interface I2c {
+ /// Writes and reads data on an i2c channel. If both write_length and read_length
+ /// are greater than zero, this call will perform a write operation immediately followed
+ /// by a read operation with no other traffic occuring on the bus in between.
+ /// If read_length is zero, then i2c_transact will only perform a write operation,
+ /// and if write_length is zero, then it will only perform a read operation.
+ /// The results of the operation are returned asynchronously via the complete_cb.
+ /// The cookie parameter can be used to pass your own private data to the complete_cb callback.
+ [Async]
+ 1: Transact(uint32 index, vector<void> write, usize read_length) -> (zx.status status,
+ vector<void> read);
+ /// Returns the maximum transfer size for read and write operations on the channel.
+ 2: GetMaxTransferSize(uint32 index) -> (zx.status s, usize size);
+};
diff --git a/system/fidl/ddk/protocols/intel-gpu-core.fidl b/system/fidl/ddk/protocols/intel-gpu-core.fidl
new file mode 100644
index 0000000..84278c5
--- /dev/null
+++ b/system/fidl/ddk/protocols/intel-gpu-core.fidl
@@ -0,0 +1,58 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.intel_gpu_core;
+
+using zx;
+
+const uint32 IMAGE_TYPE_X_TILED = 1;
+const uint32 IMAGE_TYPE_Y_LEGACY_TILED = 2;
+const uint32 IMAGE_TYPE_YF_TILED = 3;
+
+[Layout="ddk-callback"]
+interface ZxIntelGpuCoreInterrupt {
+ 1: Callback(uint32 master_interrupt_control) -> ();
+};
+
+[Layout="ddk-protocol"]
+interface ZxIntelGpuCore {
+ /// Reads 16 bits from pci config space; returned in |value_out|.
+ 1: ReadPciConfig16(uint16 addr) -> (zx.status s, uint16 value);
+
+ /// Maps the given |pci_bar|; address returned in |addr_out|, size in bytes returned in
+ /// |size_out|.
+ 2: MapPciMmio(uint32 pci_bar) -> (zx.status s, vector<void>? buf);
+
+ /// Unmaps the given |pci_bar|.
+ 3: UnmapPciMmio(uint32 pci_bar) -> (zx.status s);
+
+ /// Returns a bus transaction initiator.
+ 4: GetPciBti(uint32 index) -> (zx.status s, handle<bti> bti);
+
+ /// Registers the given |callback| to be invoked with parameter |data| when an interrupt occurs
+ /// matching |interrupt_mask|.
+ 5: RegisterInterruptCallback(ZxIntelGpuCoreInterrupt callback,
+ uint32 interrupt_mask) -> (zx.status s);
+
+ /// Un-registers a previously registered interrupt callback.
+ 6: UnregisterInterruptCallback() -> (zx.status s);
+
+ /// Returns the size of the GTT (global translation table) in bytes.
+ 7: GttGetSize() -> (uint64 size);
+
+ /// Allocates a region of the GTT of the given |page_count|, returning the page-aligned virtual
+ /// address in |addr_out|.
+ 8: GttAlloc(uint64 page_count) -> (zx.status s, uint64 addr);
+
+ /// Frees the GTT allocation given by |addr|.
+ 9: GttFree(uint64 addr) -> (zx.status s);
+
+ /// Clears the page table entries for the GTT allocation given by |addr|.
+ 10: GttClear(uint64 addr) -> (zx.status s);
+
+ /// Inserts page tables entries for the GTT allocation given by |addr| for the vmo represented by
+ /// handle |buffer|, at the given |page_offset| and |page_count|. Takes ownership of |buffer|.
+ 11: GttInsert(uint64 addr, handle<vmo> buffer, uint64 page_offset,
+ uint64 page_count) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/intel-hda-codec.fidl b/system/fidl/ddk/protocols/intel-hda-codec.fidl
new file mode 100644
index 0000000..bc55657
--- /dev/null
+++ b/system/fidl/ddk/protocols/intel-hda-codec.fidl
@@ -0,0 +1,13 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.intel_hda_codec;
+
+using zx;
+
+[Layout="ddk-protocol"]
+interface IhdaCodec {
+ /// Fetch a zx_handle_t to a channel which can be used to communicate with the codec device.
+ 1: GetDriverChannel() -> (zx.status s, handle<channel> channel);
+};
diff --git a/system/fidl/ddk/protocols/intel-hda-dsp.fidl b/system/fidl/ddk/protocols/intel-hda-dsp.fidl
new file mode 100644
index 0000000..2bcc44b
--- /dev/null
+++ b/system/fidl/ddk/protocols/intel-hda-dsp.fidl
@@ -0,0 +1,42 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.intel_hda_dsp;
+
+using zx;
+
+const string MD_KEY_NHLT = "NHLT";
+
+struct ZxPcieDeviceInfo {};
+
+[Layout="ddk-callback"]
+interface IhdaDspIrq {
+ 1: Callback() -> ();
+};
+
+[Layout="ddk-protocol"]
+interface IhdaDsp {
+ /// Fetch the parent HDA controller's PCI device info.
+ 1: GetDevInfo() -> (ZxPcieDeviceInfo? out);
+
+ /// Fetch a VMO that represents the BAR holding the Audio DSP registers.
+ 2: GetMmio() -> (zx.status s, handle<vmo> vmo, usize size);
+
+ /// Fetch a handle to our bus transaction initiator.
+ 3: GetBti() -> (zx.status s, handle<bti> bti);
+
+ /// Enables DSP
+ 4: Enable() -> ();
+
+ /// Disable DSP
+ 5: Disable() -> ();
+
+ /// Enables DSP interrupts and set a callback to be invoked when an interrupt is
+ /// raised.
+ /// Returns `ZX_ERR_ALREADY_EXISTS` if a callback is already set.
+ 6: IrqEnable(IhdaDspIrq callback) -> (zx.status s);
+
+ /// Disable DSP interrupts and clears the callback.
+ 7: IrqDisable() -> ();
+};
diff --git a/system/fidl/ddk/protocols/iommu.fidl b/system/fidl/ddk/protocols/iommu.fidl
new file mode 100644
index 0000000..199e189
--- /dev/null
+++ b/system/fidl/ddk/protocols/iommu.fidl
@@ -0,0 +1,13 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.iommu;
+
+using zx;
+
+[Layout="ddk-protocol"]
+interface Iommu {
+ 1: GetBti(uint32 iommu_index, uint32 bti_id) -> (zx.status s, handle<bti> @handle);
+};
+
diff --git a/system/fidl/ddk/protocols/libs/audio.fidl b/system/fidl/ddk/protocols/libs/audio.fidl
new file mode 100644
index 0000000..f1f6bdc
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/audio.fidl
@@ -0,0 +1,31 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.device.audio;
+
+enum AudioSampleFormat : uint32 {
+ BITSTREAM = 0x1;
+ @8BIT = 0x2;
+ @16BIT = 0x4;
+ @20BIT_PACKED = 0x8;
+ @24BIT_PACKED = 0x10;
+ @20BIT_IN32 = 0x20;
+ @24BIT_IN32 = 0x40;
+ @32BIT = 0x80;
+ @32BIT_FLOAT = 0x100;
+
+ FLAG_UNSIGNED = 0x4000;
+ FLAG_INVERT_ENDIAN = 0x8000;
+ FLAG_MASK = 0xC000;
+};
+
+[repr="C", Packed]
+struct AudioStreamFormatRange {
+ AudioSampleFormat sample_formats;
+ uint32 min_frames_per_second;
+ uint32 max_frames_per_second;
+ uint8 min_channels;
+ uint8 max_channels;
+ uint16 flags;
+};
diff --git a/system/fidl/ddk/protocols/libs/block.fidl b/system/fidl/ddk/protocols/libs/block.fidl
new file mode 100644
index 0000000..3d34c46
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/block.fidl
@@ -0,0 +1,19 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.device.block;
+
+[repr="C"]
+struct BlockInfo {
+ /// The number of blocks in this block device.
+ uint64 block_count;
+ /// The size of a single block.
+ uint32 block_size;
+ /// Max size in bytes per transfer.
+ /// May be BLOCK_MAXRANSFER_UNBOUNDED if there
+ /// is no restriction.
+ uint32 max_transfer_size;
+ uint32 flags;
+ uint32 reserved;
+};
diff --git a/system/fidl/ddk/protocols/libs/listnode.fidl b/system/fidl/ddk/protocols/libs/listnode.fidl
new file mode 100644
index 0000000..f67863b
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/listnode.fidl
@@ -0,0 +1,11 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.listnode;
+
+[repr="C"]
+struct ListNode {
+ ListNode? prev;
+ ListNode? next;
+};
diff --git a/system/fidl/ddk/protocols/libs/nand.fidl b/system/fidl/ddk/protocols/libs/nand.fidl
new file mode 100644
index 0000000..86d40a9
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/nand.fidl
@@ -0,0 +1,23 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.device.nand;
+
+[repr="C"]
+struct NandInfo {
+ /// Read/write unit size, in bytes.
+ uint32 page_size;
+ /// Erase block size, in pages.
+ uint32 pages_per_block;
+ /// Device size, in erase blocks.
+ uint32 num_blocks;
+ /// Number of ECC bits (correctable bit flips), per correction chunk.
+ uint32 ecc_bits;
+ /// Available out of band bytes per page.
+ uint32 oob_size;
+ /// NAND_CLASS_PARTMAP, NAND_CLASS_FTL or NAND_CLASS_RAW.
+ uint32 nand_class;
+ /// Partition type GUID from partition map.
+ array<uint8>:16 partition_guid;
+};
diff --git a/system/fidl/ddk/protocols/libs/pci.fidl b/system/fidl/ddk/protocols/libs/pci.fidl
new file mode 100644
index 0000000..64db00d
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/pci.fidl
@@ -0,0 +1,42 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.syscalls.pci;
+
+[repr="C"]
+union PciField {
+ usize addr;
+ handle<vmo> @handle;
+};
+
+[repr="C"]
+struct ZxPciBar {
+ uint32 id;
+ uint32 type;
+ usize size;
+ PciField u;
+};
+
+[repr="C"]
+enum ZxPciIrqMode : uint8 {
+ DISABLED = 0;
+ LEGACY = 1;
+ MSI = 2;
+ MSI_X = 3;
+};
+
+[repr="C"]
+struct ZxPcieDeviceInfo {
+ uint16 vendor_id;
+ uint16 device_id;
+
+ uint8 base_class;
+ uint8 sub_class;
+ uint8 program_interface;
+ uint8 revision_id;
+
+ uint8 bus_id;
+ uint8 dev_id;
+ uint8 func_id;
+};
diff --git a/system/fidl/ddk/protocols/libs/phys-iter.fidl b/system/fidl/ddk/protocols/libs/phys-iter.fidl
new file mode 100644
index 0000000..d0fc808
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/phys-iter.fidl
@@ -0,0 +1,35 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.phys_iter;
+
+using zx;
+
+/// Specifies the buffer to iterate over.
+[repr="C"]
+struct PhysIterBuffer {
+ /// List of physical addresses backing the buffer starting at vmo_offset.
+ zx.paddr? phys;
+ /// Number of entries in phys list.
+ uint64 phys_count;
+ /// Length of the buffer starting at vmo_offset.
+ usize length;
+ /// Offset into first page to start iterating on.
+ uint64 vmo_offset;
+};
+
+/// Used to iterate over contiguous buffer ranges in the physical address space.
+[repr="C"]
+struct PhysIter {
+ PhysIterBuffer buf;
+
+ /// Current offset in the txn (relative to buffer vmo_offset)
+ zx.off offset;
+ /// Max length to be returned by phys_iter_next()
+ usize max_length;
+ /// index of page in buf->phys that contains offset
+ uint64 page;
+ /// last valid page index in buf->phys
+ uint64 last_page;
+};
diff --git a/system/fidl/ddk/protocols/libs/sdhci.fidl b/system/fidl/ddk/protocols/libs/sdhci.fidl
new file mode 100644
index 0000000..76b7ba9
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/sdhci.fidl
@@ -0,0 +1,38 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library hw.sdhci;
+
+[Packed, repr="C"]
+struct SdhciRegs {
+ uint32 arg2; // 00h
+ uint32 blkcntsiz; // 04h
+ uint32 arg1; // 08h
+ uint32 cmd; // 0Ch
+ uint32 resp0; // 10h
+ uint32 resp1; // 14h
+ uint32 resp2; // 18h
+ uint32 resp3; // 1Ch
+ uint32 data; // 20h
+ uint32 state; // 24h
+ uint32 ctrl0; // 28h
+ uint32 ctrl1; // 2Ch
+ uint32 irq; // 30h
+ uint32 irqmsk; // 34h
+ uint32 irqen; // 38h
+ uint32 ctrl2; // 3Ch
+ uint32 caps0; // 40h
+ uint32 caps1; // 44h
+ uint32 maxcaps0; // 48h
+ uint32 maxcaps1; // 4Ch
+ uint32 forceirq; // 50h
+ uint32 admaerr; // 54h
+ uint32 admaaddr0; // 58h
+ uint32 admaaddr1; // 5Ch
+ array<uint32>:4 preset; // 60h
+ array<uint8>:112 resvd;
+ uint32 busctl;
+ array<uint8>:24 reserved_4;
+ uint32 slotirqversion;
+};
diff --git a/system/fidl/ddk/protocols/libs/usb-device.fidl b/system/fidl/ddk/protocols/libs/usb-device.fidl
new file mode 100644
index 0000000..337e695
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/usb-device.fidl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.device.usb_device;
+
+[repr="C"]
+enum UsbMode : uint32 {
+ NONE = 0;
+ HOST = 1;
+ DEVICE = 2;
+ OTG = 3;
+};
+
diff --git a/system/fidl/ddk/protocols/libs/usb-hub.fidl b/system/fidl/ddk/protocols/libs/usb-hub.fidl
new file mode 100644
index 0000000..71dcbff
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/usb-hub.fidl
@@ -0,0 +1,39 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.hw.usb_hub;
+
+[Packed, repr="C"]
+struct UsbHighSpeed {
+ // variable length depending on number of ports
+ array<uint8>:4 DeviceRemovable;
+ array<uint8>:4 PortPwrCtrlMask;
+};
+
+[Packed, repr="C"]
+struct UsbSuperSpeed {
+ uint8 bHubHdrDecLat;
+ uint16 wHubDelay;
+ uint16 DeviceRemovable;
+};
+
+[Packed, repr="C"]
+union UsbGen {
+ /// USB 2.0
+ UsbHighSpeed hs;
+ /// USB 3.0
+ UsbSuperSpeed ss;
+};
+
+[Packed, repr="C"]
+struct UsbHubDescriptor {
+ uint8 bDescLength;
+ uint8 bDescriptorType;
+ uint8 bNbrPorts;
+ uint16 wHubCharacteristics;
+ uint8 bPowerOn2PwrGood;
+ uint8 bHubContrCurrent;
+ UsbGen u;
+};
+
diff --git a/system/fidl/ddk/protocols/libs/usb.fidl b/system/fidl/ddk/protocols/libs/usb.fidl
new file mode 100644
index 0000000..c200c99
--- /dev/null
+++ b/system/fidl/ddk/protocols/libs/usb.fidl
@@ -0,0 +1,79 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library zircon.hw.usb;
+
+[repr="C"]
+enum UsbSpeed : uint8 {
+ UNDEFINED = 0;
+ FULL = 1;
+ LOW = 2;
+ HIGH = 3;
+ SUPER = 4;
+};
+
+[Packed, repr="C"]
+struct UsbSetup {
+ uint8 bmRequestType;
+ uint8 bRequest;
+ uint16 wValue;
+ uint16 wIndex;
+ uint16 wLength;
+};
+
+[Packed, repr="C"]
+struct UsbDescriptorHeader {
+ uint8 bLength;
+ uint8 bDescriptorType;
+};
+
+[Packed, repr="C"]
+struct UsbDeviceDescriptor {
+ uint8 bLength;
+ uint8 bDescriptorType;
+ uint16 bcdUSB;
+ uint8 bDeviceClass;
+ uint8 bDeviceSubClass;
+ uint8 bDeviceProtocol;
+ uint8 bMaxPacketSize0;
+ uint16 idVendor;
+ uint16 idProduct;
+ uint16 bcdDevice;
+ uint8 iManufacturer;
+ uint8 iProduct;
+ uint8 iSerialNumber;
+ uint8 bNumConfigurations;
+};
+
+[Packed, repr="C"]
+struct UsbInterfaceDescriptor {
+ uint8 bLength;
+ uint8 bDescriptorType;
+ uint8 bInterfaceNumber;
+ uint8 bAlternateSetting;
+ uint8 bNumEndpoints;
+ uint8 bInterfaceClass;
+ uint8 bInterfaceSubClass;
+ uint8 bInterfaceProtocol;
+ uint8 iInterface;
+};
+
+[Packed, repr="C"]
+struct UsbEndpointDescriptor {
+ uint8 bLength;
+ uint8 bDescriptorType;
+ uint8 bEndpointAddress;
+ uint8 bmAttributes;
+ uint16 wMaxPacketSize;
+ uint8 bInterval;
+};
+
+[Packed, repr="C"]
+struct UsbSsEpCompDescriptor {
+ uint8 bLength;
+ uint8 bDescriptorType;
+ uint8 bMaxBurst;
+ uint8 bmAttributes;
+ uint16 wBytesPerInterval;
+};
diff --git a/system/fidl/ddk/protocols/mailbox.fidl b/system/fidl/ddk/protocols/mailbox.fidl
new file mode 100644
index 0000000..b1b608e
--- /dev/null
+++ b/system/fidl/ddk/protocols/mailbox.fidl
@@ -0,0 +1,22 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.mailbox;
+
+using zx;
+
+struct MailboxDataBuf {
+ uint32 cmd;
+ vector<void> tx;
+};
+
+struct MailboxChannel {
+ uint32 mailbox;
+ vector<void> rx;
+};
+
+[Layout="ddk-protocol"]
+interface Mailbox {
+ 1: SendCommand(MailboxChannel channel, MailboxDataBuf mdata) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/makefile b/system/fidl/ddk/protocols/makefile
new file mode 100644
index 0000000..3a536b7
--- /dev/null
+++ b/system/fidl/ddk/protocols/makefile
@@ -0,0 +1,152 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
+FIDLC := ../../../../build-arm64/tools/fidlc
+
+CLANG_FORMAT := clang-format --style="{Language: Cpp, ColumnLimit: 100, UseTab: Never, IndentWidth: 4, IndentCaseLabels: false, AlignAfterOpenBracket: Align, SpacesBeforeTrailingComments: 1, BreakBeforeBraces: Attach, AccessModifierOffset: -4, DerivePointerAlignment: false, PointerAlignment: Left, AllowShortFunctionsOnASingleLine: Inline, AllowShortIfStatementsOnASingleLine: false, KeepEmptyLinesAtTheStartOfBlocks: true, AlignEscapedNewlinesLeft: false, ForEachMacros: ['list_for_every_entry','list_for_every_entry_safe'], AlwaysBreakTemplateDeclarations: true}"
+
+define run-fidl =
+$(FIDLC) --ddk-header ddk/protocols/$@.h $(patsubst %.fidl,--files %.fidl, $^) \
+ --files $(LOCAL_DIR)/$@.fidl
+$(FIDLC) --ddktl-header ddktl/protocols/$@.h $(patsubst %.fidl,--files %.fidl, $^) \
+ --files $(LOCAL_DIR)/$@.fidl
+$(CLANG_FORMAT) ddk/protocols/$@.h > ddk/protocols/$@.formatted.h
+$(CLANG_FORMAT) ddktl/protocols/$@.h > ddktl/protocols/$@.formatted.h
+$(CLANG_FORMAT) ddktl/protocols/$@-internal.h > ddktl/protocols/$@-internal.formatted.h
+cp -f ddk/protocols/$@.formatted.h ../../../ulib/ddk/include/ddk/protocol/$@.h
+cp -f ddktl/protocols/$@.formatted.h ../../../ulib/ddktl/include/ddktl/protocol/$@.h
+cp -f ddktl/protocols/$@-internal.formatted.h ../../../ulib/ddktl/include/ddktl/protocol/$@-internal.h
+endef
+
+acpi:
+ $(run-fidl)
+
+amlogic-canvas:
+ $(run-fidl)
+
+bad-block:
+ $(run-fidl)
+
+block: $(LOCAL_DIR)/libs/block.fidl
+ $(run-fidl)
+
+bt-gatt-svc:
+ $(run-fidl)
+
+bt-hci:
+ $(run-fidl)
+
+clk:
+ $(run-fidl)
+
+display-controller: $(LOCAL_DIR)/libs/audio.fidl
+ $(run-fidl)
+
+ethernet: $(LOCAL_DIR)/libs/listnode.fidl
+ $(run-fidl)
+
+gpio:
+ $(run-fidl)
+
+hidbus:
+ $(run-fidl)
+
+i2c-impl:
+ $(run-fidl)
+
+i2c:
+ $(run-fidl)
+
+intel-gpu-core:
+ $(run-fidl)
+
+intel-hda-codec:
+ $(run-fidl)
+
+intel-hda-dsp:
+ $(run-fidl)
+
+iommu:
+ $(run-fidl)
+
+mailbox:
+ $(run-fidl)
+
+nand: $(LOCAL_DIR)/libs/nand.fidl
+ $(run-fidl)
+
+pci: $(LOCAL_DIR)/libs/pci.fidl
+ $(run-fidl)
+
+pciroot:
+ $(run-fidl)
+
+platform-bus:
+ $(run-fidl)
+
+platform-device:
+ $(run-fidl)
+
+platform-proxy:
+ $(run-fidl)
+
+rawnand: $(LOCAL_DIR)/libs/nand.fidl
+ $(run-fidl)
+
+scpi:
+ $(run-fidl)
+
+sdhci: $(LOCAL_DIR)/libs/sdhci.fidl
+ $(run-fidl)
+
+sdio:
+ $(run-fidl)
+
+sdmmc: $(LOCAL_DIR)/libs/listnode.fidl $(LOCAL_DIR)/libs/block.fidl $(LOCAL_DIR)/block.fidl
+ $(run-fidl)
+
+serial-impl: $(LOCAL_DIR)/serial.fidl
+ $(run-fidl)
+
+serial:
+ $(run-fidl)
+
+test:
+ $(run-fidl)
+
+usb-bus: $(LOCAL_DIR)/libs/usb.fidl $(LOCAL_DIR)/libs/usb-hub.fidl $(LOCAL_DIR)/usb-hub.fidl
+ $(run-fidl)
+
+usb-dci: $(LOCAL_DIR)/libs/listnode.fidl $(LOCAL_DIR)/libs/phys-iter.fidl \
+ $(LOCAL_DIR)/libs/usb.fidl $(LOCAL_DIR)/libs/usb-hub.fidl $(LOCAL_DIR)/usb.fidl
+ $(run-fidl)
+
+usb-function: $(LOCAL_DIR)/libs/listnode.fidl $(LOCAL_DIR)/libs/phys-iter.fidl \
+ $(LOCAL_DIR)/libs/usb.fidl $(LOCAL_DIR)/libs/usb-hub.fidl $(LOCAL_DIR)/usb.fidl
+ $(run-fidl)
+
+usb-hci: $(LOCAL_DIR)/libs/listnode.fidl $(LOCAL_DIR)/libs/phys-iter.fidl \
+ $(LOCAL_DIR)/libs/usb.fidl $(LOCAL_DIR)/libs/usb-hub.fidl $(LOCAL_DIR)/usb.fidl \
+ $(LOCAL_DIR)/usb-hub.fidl $(LOCAL_DIR)/usb-bus.fidl
+ $(run-fidl)
+
+usb-hub: $(LOCAL_DIR)/libs/usb-hub.fidl
+ $(run-fidl)
+
+usb-mode-switch: $(LOCAL_DIR)/libs/usb-device.fidl $(LOCAL_DIR)/hidbus.fidl
+ $(run-fidl)
+
+usb: $(LOCAL_DIR)/libs/listnode.fidl $(LOCAL_DIR)/libs/phys-iter.fidl \
+ $(LOCAL_DIR)/libs/usb.fidl $(LOCAL_DIR)/libs/usb-hub.fidl
+ $(run-fidl)
+
+all: acpi amlogic-canvas bad-block block bt-gatt-svc bt-hci clk display-controller ethernet gpio \
+ hidbus i2c-impl i2c intel-gpu-core intel-hda-codec intel-hda-dsp iommu mailbox nand pci \
+ pciroot platform-bus platform-device platform-proxy rawnand scpi sdhci sdio sdmmc \
+ serial-impl serial test usb-bus usb-dci usb-function usb-hci usb-hub usb-mode-switch usb
+
+clean:
+ rm -rf ddk
+ rm -rf ddktl
diff --git a/system/fidl/ddk/protocols/nand.fidl b/system/fidl/ddk/protocols/nand.fidl
new file mode 100644
index 0000000..cf5ab31
--- /dev/null
+++ b/system/fidl/ddk/protocols/nand.fidl
@@ -0,0 +1,127 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.nand;
+
+using zircon.device.nand;
+using zx;
+
+/// NandOperation's are submitted for processing via the queue() method of the
+/// Nand Protocol. Once submitted, the contents of the NandOperation may be modified
+/// while it's being processed.
+///
+/// The completion_cb() must eventually be called upon success or failure and
+/// at that point the cookie field must contain whatever value was in it when
+/// the NandOperation was originally queued.
+///
+/// Any mention of "in pages" in this file means nand pages, as reported by
+/// nand_info.page_size, as opposed to physical memory pages (RAM). That's true
+/// even for vmo-related values.
+///
+/// corrected_bit_flips are always related to nand_info.ecc_bits, so it is
+/// possible to obtain a value that is larger than what is being read (in the oob
+/// case). On the other hand, if errors cannot be corrected, the operation will
+/// fail, and corrected_bit_flips will be undefined.
+
+/// NOTE: The protocol can be extended with barriers to support controllers that
+/// may issue multiple simultaneous request to the IO chips.
+
+enum NandOp : uint32 {
+ READ = 0x1;
+ WRITE = 0x2;
+ ERASE = 0x3;
+};
+
+/// A single operation can read or write an arbitrary number of pages,
+/// including out of band (OOB) data for each page. If either regular
+/// data or OOB is not required, the relevant VMO handle should be set to
+/// ZX_HANDLE_INVALID.
+///
+/// Note that length dictates the number of pages to access, regardless
+/// of the type of data requested: regular data, OOB or both.
+///
+/// The OOB data will be copied to (and from) a contiguous memory range
+/// starting at the given offset. Note that said offset is given in nand
+/// pages even though OOB is just a handful of bytes per page. In other
+/// words, after said offset, the OOB data for each page is located
+/// nand_info.oob_size bytes apart.
+///
+/// For example, to read 5 pages worth of data + OOB, with page size of
+/// 2 kB and 16 bytes of OOB per page, setting:
+///
+/// data_vmo = oob_vmo = vmo_handle
+/// length = 5
+/// offset_nand = 20
+/// offset_data_vmo = 0
+/// offset_oob_vmo = 5
+///
+/// will transfer pages [20, 24] to the first 2048 * 5 bytes of the vmo,
+/// followed by 16 * 5 bytes of OOB data starting at offset 2048 * 5.
+struct NandReadWrite {
+ /// Command.
+ NandOp command;
+ /// vmo of data to read or write.
+ handle<vmo> data_vmo;
+ /// vmo of OOB data to read or write.
+ handle<vmo> oob_vmo;
+ /// Number of pages to access.
+ /// (0 is invalid).
+ uint32 length;
+ /// Offset into nand, in pages.
+ uint32 offset_nand;
+ /// Data vmo offset in (nand) pages.
+ uint64 offset_data_vmo;
+ /// OOB vmo offset in (nand) pages.
+ uint64 offset_oob_vmo;
+ /// Optional physical page list.
+ vector<uint64>? page;
+ /// Return value from READ_DATA, max corrected bit flips in any
+ /// underlying ECC chunk read. The caller can compare this value
+ /// against ecc_bits to decide whether the nand erase block needs to
+ /// be recycled.
+ uint32 corrected_bit_flips;
+};
+
+struct NandErase {
+ /// Command.
+ NandOp command;
+ /// Offset into nand, in erase blocks.
+ uint32 first_block;
+ /// Number of blocks to erase.
+ /// (0 is invalid).
+ uint32 num_blocks;
+};
+
+union NandOperation {
+ /// All Commands.
+ NandOp command;
+ /// NAND_OP_READ, NAND_OP_WRITE.
+ NandReadWrite rw;
+ /// NAND_OP_ERASE.
+ NandErase erase;
+};
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface Nand {
+ /// Obtains the parameters of the nand device (nand_info_t) and the required
+ /// size of nand_op_t. The nand_op_t's submitted via queue() must have
+ /// nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
+ /// structure for the use of the driver.
+ 1: Query() -> (zircon.device.nand.NandInfo info, usize nand_op_size);
+
+ /// Submits an IO request for processing. Success or failure will be reported
+ /// via the completion_cb() in the nand_op_t. The callback may be called
+ /// before the queue() method returns.
+ [Async]
+ 2: Queue(NandOperation? op) -> (zx.status s, NandOperation? op);
+
+ /// Gets the list of bad erase blocks, as reported by the nand manufacturer.
+ /// The caller must allocate a table large enough to hold the expected number
+ /// of entries, and pass the size of that table on |bad_block_len|.
+ /// On return, |num_bad_blocks| contains the number of bad blocks found.
+ /// This should only be called before writing any data to the nand, and the
+ /// returned data should be saved somewhere else, along blocks that become
+ /// bad after they've been in use.
+ 3: GetFactoryBadBlockList() -> (zx.status s, vector<uint32> bad_blocks);
+};
diff --git a/system/fidl/ddk/protocols/pci.fidl b/system/fidl/ddk/protocols/pci.fidl
new file mode 100644
index 0000000..6d9c702
--- /dev/null
+++ b/system/fidl/ddk/protocols/pci.fidl
@@ -0,0 +1,68 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.pci;
+
+using zircon.syscalls.pci;
+using zx;
+
+enum PciCfg : uint16 {
+ VENDOR_ID = 0x00;
+ DEVICE_ID = 0x02;
+ REVISION_ID = 0x08;
+ CLASS_CODE = 0x09;
+ SUBSYSTEM_VENDOR_ID = 0x2C;
+ SUBSYSTEM_ID = 0x2E;
+ CAPABILITIES_PTR = 0x34;
+};
+
+enum PciCapId : uint8 {
+ NULL = 0x00;
+ PCI_PWR_MGMT = 0x01;
+ AGP = 0x02;
+ VPD = 0x03;
+ MSI = 0x05;
+ PCIX = 0x07;
+ HYPERTRANSPORT = 0x08;
+ VENDOR = 0x09;
+ DEBUG_PORT = 0x0A;
+ COMPACT_PCI_CRC = 0x0B;
+ PCI_HOT_PLUG = 0x0C;
+ PCI_BRIDGE_SUBSYSTEM_VID = 0x0D;
+ AGP8X = 0x0E;
+ SECURE_DEVICE = 0x0F;
+ PCI_EXPRESS = 0x10;
+ MSIX = 0x11;
+ SATA_DATA_NDX_CFG = 0x12;
+ ADVANCED_FEATURES = 0x13;
+ ENHANCED_ALLOCATION = 0x14;
+};
+
+[Layout="ddk-protocol"]
+interface Pci {
+ 1: GetBar(uint32 bar_id) -> (zx.status s, zircon.syscalls.pci.ZxPciBar res);
+ 2: MapBar(uint32 bar_id, uint32 cache_policy) -> (zx.status s, vector<void>? vaddr,
+ handle<vmo> @handle);
+ 3: EnableBusMaster(bool enable) -> (zx.status s);
+ 4: ResetDevice() -> (zx.status s);
+ 5: MapInterrupt(int32 which_irq) -> (zx.status s, handle<interrupt> @handle);
+ 6: QueryIrqMode(zircon.syscalls.pci.ZxPciIrqMode mode) -> (zx.status s, uint32 max_irqs);
+ 7: SetIrqMode(zircon.syscalls.pci.ZxPciIrqMode mode, uint32 requested_irq_count) -> (zx.status s);
+ 8: GetDeviceInfo() -> (zx.status s, zircon.syscalls.pci.ZxPcieDeviceInfo into);
+ 9: ConfigRead(uint16 offset, usize width) -> (zx.status s, uint32 value);
+ 10: ConfigWrite(uint16 offset, usize width, uint32 value) -> (zx.status s);
+ 11: GetNextCapability(uint8 type, uint8 offset) -> (uint8 cap);
+ 12: GetAuxdata(string args) -> (zx.status s, vector<void> data);
+ 13: GetBti(uint32 index) -> (zx.status s, handle<bti> bti);
+};
+
+// TODO: Implement the following.
+//static inline uint8_t pci_get_first_capability(const pci_protocol_t* pci, uint8_t type) {
+// return pci_get_next_capability(pci, kPciCfgCapabilitiesPtr - 1u, type);
+//}
+//static inline zx_status_t pci_get_auxdata(const pci_protocol_t* pci,
+// const char* args, void* data,
+// uint32_t bytes, uint32_t* actual) {
+// return pci->ops->get_auxdata(pci->ctx, args, data, bytes, actual);
+//}
diff --git a/system/fidl/ddk/protocols/pciroot.fidl b/system/fidl/ddk/protocols/pciroot.fidl
new file mode 100644
index 0000000..e04481d
--- /dev/null
+++ b/system/fidl/ddk/protocols/pciroot.fidl
@@ -0,0 +1,13 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.pciroot;
+
+using zx;
+
+[Layout="ddk-protocol"]
+interface Pciroot {
+ 1: GetAuxdata(string args) -> (zx.status s, vector<void> data);
+ 2: GetBti(uint32 bdf, uint32 index) -> (zx.status s, handle<bti> bti);
+};
diff --git a/system/fidl/ddk/protocols/platform-bus.fidl b/system/fidl/ddk/protocols/platform-bus.fidl
new file mode 100644
index 0000000..278e199
--- /dev/null
+++ b/system/fidl/ddk/protocols/platform-bus.fidl
@@ -0,0 +1,120 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.platform_bus;
+
+using zx;
+
+struct PbusMmio {
+ /// Physical address of MMIO region.
+ /// Does not need to be page aligned.
+ zx.paddr base;
+ /// Length of MMIO region in bytes.
+ /// Does not need to be page aligned.
+ usize length;
+};
+
+struct PbusIrq {
+ uint32 irq;
+ /// `ZX_INTERRUPT_MODE_*` flags
+ uint32 mode;
+};
+
+struct PbusGpio {
+ uint32 gpio;
+};
+
+struct PbusI2cChannel{
+ uint32 bus_id;
+ uint16 address;
+};
+
+struct PbusClk {
+ uint32 clk;
+};
+
+struct PbusBti {
+ uint32 iommu_index;
+ uint32 bti_id;
+};
+
+/// Device metadata.
+struct PbusMetadata {
+ /// Metadata type.
+ uint32 type;
+ /// Pointer to metadata.
+ vector<void> data;
+};
+
+/// Device metadata to be passed from bootloader via a ZBI record.
+struct PbusBootMetadata {
+ /// Metadata type (matches `zbi_header_t.type` for bootloader metadata).
+ uint32 zbi_type;
+ /// Matches `zbi_header_t.extra` for bootloader metadata.
+ /// Used in cases where bootloader provides multiple metadata records of the same type.
+ uint32 zbi_extra;
+};
+
+struct PbusDev {
+ string name;
+ /// `BIND_PLATFORM_DEV_VID`
+ uint32 vid;
+ /// `BIND_PLATFORM_DEV_PID`
+ uint32 pid;
+ /// `BIND_PLATFORM_DEV_DID`
+ uint32 did;
+ vector<PbusMmio> mmio;
+ vector<PbusIrq> irq;
+ vector<PbusGpio> gpio;
+ vector<PbusI2cChannel> i2c_channel;
+ vector<PbusClk> clk;
+ vector<PbusBti> bti;
+ vector<PbusMetadata> metadata;
+ vector<PbusBootMetadata> boot_metadata;
+ /// List of this device's child devices.
+ /// This is only used in cases where children of a platform device also need to access
+ /// platform bus resources.
+ vector<PbusDev?> children;
+ /// Extra protocols to be provided to this platform device and its children.
+ /// These fields are only used for the top level `pbus_dev_t`.
+ vector<uint32> protocol;
+};
+
+/// Subset of pdev_board_info_t to be set by the board driver.
+struct PbusBoardInfo {
+ /// Board specific revision number.
+ uint32 board_revision;
+};
+
+[Layout="ddk-callback"]
+interface PlatformProxyCb {
+ 1: Callback(vector<void> req, vector<handle> req_handle) -> (zx.status s, vector<void> resp,
+ vector<handle> resp_handle);
+};
+
+[Layout="ddk-protocol"]
+interface PlatformDevice {
+ /// Adds a new platform device to the bus, using configuration provided by |dev|.
+ /// Platform devices are created in their own separate devhosts.
+ 1: DeviceAdd(PbusDev dev) -> (zx.status s);
+ /// Adds a device for binding a protocol implementation driver.
+ /// These devices are added in the same devhost as the platform bus.
+ /// After the driver binds to the device it calls `pbus_register_protocol()`
+ /// to register its protocol with the platform bus.
+ /// `pbus_protocol_device_add()` blocks until the protocol implementation driver
+ /// registers its protocol (or times out).
+ 2: ProtocolDeviceAdd(uint32 proto_id, PbusDev dev) -> (zx.status s);
+ /// Called by protocol implementation drivers to register their protocol
+ /// with the platform bus.
+ 3: RegisterProtocol(uint32 proto_id, vector<void> protocol, PlatformProxyCb proxy_cb)
+ -> (zx.status s);
+ /// Returns the board name for the underlying hardware.
+ /// Board drivers may use this to differentiate between multiple boards that they support.
+ 4: GetBoardName() -> (string name);
+ /// Board drivers may use this to set information about the board
+ /// (like the board revision number).
+ /// Platform device drivers can access this via `pdev_get_board_info()`.
+ 5: SetBoardInfo(PbusBoardInfo info) -> (zx.status s);
+};
+
diff --git a/system/fidl/ddk/protocols/platform-device.fidl b/system/fidl/ddk/protocols/platform-device.fidl
new file mode 100644
index 0000000..723e4d3
--- /dev/null
+++ b/system/fidl/ddk/protocols/platform-device.fidl
@@ -0,0 +1,50 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.platform_device;
+
+using zx;
+
+// TODO: Not need this anymore.
+[repr="C"]
+struct ZxDevice {};
+[repr="C"]
+struct DeviceAddArgs {};
+
+struct PdevDeviceInfo {
+ uint32 vid;
+ uint32 pid;
+ uint32 did;
+ uint32 mmio_count;
+ uint32 irq_count;
+ uint32 gpio_count;
+ uint32 i2c_channel_count;
+ uint32 clk_count;
+ uint32 bti_count;
+ uint32 metadata_count;
+ array<uint32>:8 reserved;
+ string:32 name;
+};
+
+struct PdevBoardInfo {
+ /// Vendor ID for the board.
+ uint32 vid;
+ /// Product ID for the board.
+ uint32 pid;
+ /// Board name from the boot image platform ID record.
+ string:32 board_name;
+ /// Board specific revision number.
+ uint32 board_revision;
+};
+
+[Layout="ddk-protocol"]
+interface PlatformDevice {
+ 1: MapMmio(uint32 index, uint32 cache_policy) -> (zx.status s, vector<void>? vaddr,
+ zx.paddr paddr, handle<vmo> @handle);
+ 2: MapInterrupt(uint32 index, uint32 flags) -> (zx.status s, handle<interrupt> irq);
+ 3: GetBti(uint32 index) -> (zx.status s, handle<bti> bti);
+ 4: GetDeviceInfo() -> (zx.status s, PdevDeviceInfo info);
+ 5: GetBoardInfo() -> (zx.status s, PdevBoardInfo info);
+ 6: DeviceAdd (uint32 index, DeviceAddArgs args) -> (zx.status s, ZxDevice? out);
+};
diff --git a/system/fidl/ddk/protocols/platform-proxy.fidl b/system/fidl/ddk/protocols/platform-proxy.fidl
new file mode 100644
index 0000000..ee74653
--- /dev/null
+++ b/system/fidl/ddk/protocols/platform-proxy.fidl
@@ -0,0 +1,38 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.platform_proxy;
+
+using zx;
+
+struct ZxTxid {};
+
+const uint32 PLATFORM_PROXY_MAX_DATA = 4096;
+
+/// Header for RPC requests.
+struct PlatformProxyReq {
+ ZxTxid txid;
+ uint32 device_id;
+ uint32 proto_id;
+ uint32 op;
+};
+
+/// Header for RPC responses.
+struct PlatformProxyRsp {
+ ZxTxid txid;
+ zx.status status;
+};
+
+[Layout="ddk-protocol"]
+interface PlatformProxy {
+ /// Used by protocol client drivers to register their local protocol implementation
+ /// with the platform proxy driver.
+ 1: RegisterProtocol(uint32 proto_id, vector<void> protocol) -> (zx.status s);
+ /// Used by protocol client drivers to proxy a protocol call to the protocol implementation
+ /// driver in the platform bus driver's devhost.
+ 2: Proxy(vector<void> req, vector<handle> req_handle) -> (zx.status s, vector<void> resp,
+ vector<handle> resp_handle);
+};
+
+
diff --git a/system/fidl/ddk/protocols/rawnand.fidl b/system/fidl/ddk/protocols/rawnand.fidl
new file mode 100644
index 0000000..b2b4c48
--- /dev/null
+++ b/system/fidl/ddk/protocols/rawnand.fidl
@@ -0,0 +1,29 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.rawnand;
+
+using zircon.device.nand;
+using zx;
+
+[Layout="ddk-protocol"]
+interface RawNand {
+ /// Read one nand page with hwecc.
+ 1: ReadPageHwecc(uint32 nandpage) -> (zx.status s, vector<void> data, vector<void> oob,
+ int32 ecc_correct);
+
+ /// Write one nand page with hwecc.
+ 2: WritePageHwecc(vector<void> data, vector<void> oob, uint32 nandpage) -> (zx.status s);
+
+ /// Erase nand block.
+ 3: EraseBlock(uint32 nandpage) -> (zx.status s);
+
+ 4: GetNandInfo() -> (zx.status s, zircon.device.nand.NandInfo info);
+
+ /// Send ONFI command down to controller.
+ 5: CmdCtrl(int32 cmd, uint32 ctrl) -> ();
+
+ /// Read byte (used to read status as well as other info, such as ID).
+ 6: ReadByte() -> (uint8 byte);
+};
diff --git a/system/fidl/ddk/protocols/scpi.fidl b/system/fidl/ddk/protocols/scpi.fidl
new file mode 100644
index 0000000..37cedda
--- /dev/null
+++ b/system/fidl/ddk/protocols/scpi.fidl
@@ -0,0 +1,32 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.scpi;
+
+using zx;
+
+const uint32 MAX_DVFS_OPPS = 16;
+
+[Layout="Packed"]
+struct ScpiOppEntry {
+ uint32 freq_hz;
+ uint32 volt_mv;
+};
+
+[Layout="Packed"]
+struct ScpiOpp {
+ array<ScpiOppEntry>:MAX_DVFS_OPPS opp;
+ /// In usecs.
+ uint32 latency;
+ uint32 count;
+};
+
+[Layout="ddk-protocol"]
+interface Scpi {
+ 1: GetSensor(string name) -> (zx.status s, uint32 sensor_id);
+ 2: GetSensorValue(uint32 sensor_id) -> (zx.status s, uint32 sensor_value);
+ 3: GetDvfsInfo(uint8 power_domain) -> (zx.status s, ScpiOpp opps);
+ 4: GetDvfsIdx(uint8 power_domain) -> (zx.status s, uint16 index);
+ 5: SetDvfsIdx(uint8 power_domain, uint16 index) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/sdhci.fidl b/system/fidl/ddk/protocols/sdhci.fidl
new file mode 100644
index 0000000..90d2632
--- /dev/null
+++ b/system/fidl/ddk/protocols/sdhci.fidl
@@ -0,0 +1,45 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.sdhci;
+
+using hw.sdhci;
+using zx;
+
+enum SdhciQuirk : uint64 {
+ /// This is a BCM28xx specific quirk. The bottom 8 bits of the 136
+ /// bit response are normally filled by 7 CRC bits and 1 reserved bit.
+ /// The BCM controller checks the CRC for us and strips it off in the
+ /// process.
+ /// The higher level stack expects 136B responses to be packed in a
+ /// certain way so we shift all the fields back to their proper offsets.
+ STRIP_RESPONSE_CRC = 0x1;
+ /// BCM28xx quirk: The BCM28xx appears to use its internal DMA engine to
+ /// perform transfers against the SD card. Normally we would use SDMA or
+ /// ADMA (if the part supported it). Since this part doesn't appear to
+ /// support either, we just use PIO.
+ NO_DMA = 0x2;
+ /// The bottom 8 bits of the 136 bit response are normally filled by 7 CRC bits
+ /// and 1 reserved bit. Some controllers strip off the CRC.
+ /// The higher level stack expects 136B responses to be packed in a certain way
+ /// so we shift all the fields back to their proper offsets.
+ STRIP_RESPONSE_CRC_PRESERVE_ORDER = 0x4;
+};
+
+[Layout="ddk-protocol"]
+interface Sdhci {
+ // TODO: should be replaced with a generic busdev mechanism
+ 1: GetInterrupt() -> (zx.status s, handle<interrupt> irq);
+ 2: GetMmio() -> (zx.status s, handle<vmo> mmio);
+ /// Gets a handle to the bus transaction initiator for the device. The caller
+ /// receives ownership of the handle.
+ 3: GetBti(uint32 index) -> (zx.status s, handle<bti> bti);
+
+ 4: GetBaseClock() -> (uint32 clock);
+
+ /// returns device quirks
+ 5: GetQuirks() -> (uint64 clock);
+ /// platform specific HW reset
+ 6: HwReset() -> ();
+};
diff --git a/system/fidl/ddk/protocols/sdio.fidl b/system/fidl/ddk/protocols/sdio.fidl
new file mode 100644
index 0000000..e4b1578
--- /dev/null
+++ b/system/fidl/ddk/protocols/sdio.fidl
@@ -0,0 +1,83 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.sdio;
+
+using zx;
+
+const uint8 SDIO_FN_0 = 0;
+const uint8 SDIO_FN_1 = 0;
+const uint8 SDIO_FN_2 = 0;
+/// Including func 0
+const uint8 SDIO_MAX_FUNCS = 8;
+
+struct SdioFuncHwInfo {
+ uint32 manufacturer_id;
+ uint32 product_id;
+ uint32 max_blk_size;
+ uint32 max_tran_speed;
+ uint8 fn_intf_code;
+};
+
+enum SDIO_CARD : uint32 {
+ MULTI_BLOCK = 0x1;
+ SRW = 0x2;
+ DIRECT_COMMAND = 0x4;
+ SUSPEND_RESUME = 0x8;
+ LOW_SPEED = 0x10;
+ HIGH_SPEED = 0x20;
+ HIGH_POWER = 0x40;
+ FOUR_BIT_BUS = 0x80;
+ HS_SDR12 = 0x100;
+ HS_SDR25 = 0x200;
+ UHS_SDR50 = 0x400;
+ UHS_SDR104 = 0x800;
+ UHS_DDR50 = 0x1000;
+ TYPE_A = 0x2000;
+ TYPE_B = 0x4000;
+ TYPE_C = 0x8000;
+ TYPE_D = 0x10000;
+};
+
+struct SdioDeviceHwInfo {
+ /// number of sdio funcs
+ uint32 num_funcs;
+ uint32 sdio_vsn;
+ uint32 cccr_vsn;
+ uint32 caps;
+};
+
+struct SdioHwInfo {
+ SdioDeviceHwInfo dev_hw_info;
+ array<SdioFuncHwInfo>:SDIO_MAX_FUNCS funcs_hw_info;
+ uint32 host_max_transfer_size;
+};
+
+struct SdioRwTxn {
+ uint32 addr;
+ uint32 data_size;
+ bool incr;
+ bool fifo;
+ bool write;
+ bool use_dma;
+ /// Used if use_dma is true
+ handle<vmo> dma_vmo;
+ /// Used if use_dma is false
+ vector<void> virt;
+ /// offset into dma_vmo or virt
+ uint64 buf_offset;
+};
+
+[Layout="ddk-protocol"]
+interface Sdio {
+ 1: GetDevHwInfo() -> (zx.status s, SdioHwInfo hw_info);
+ 3: EnableFn(uint8 fn_idx) -> (zx.status s);
+ 4: DisableFn(uint8 fn_idx) -> (zx.status s);
+ 5: EnableFnIntr(uint8 fn_idx) -> (zx.status s);
+ 6: DisableFnIntr(uint8 fn_idx) -> (zx.status s);
+ 7: UpdateBlockSize(uint8 fn_idx, uint16 blk_sz, bool deflt) -> (zx.status s);
+ 8: GetBlockSize(uint8 fn_idx) -> (zx.status s, uint16 cur_blk_size);
+ 9: DoRwTxn(uint8 fn_idx, SdioRwTxn? txn) -> (zx.status s);
+};
+
diff --git a/system/fidl/ddk/protocols/sdmmc.fidl b/system/fidl/ddk/protocols/sdmmc.fidl
new file mode 100644
index 0000000..4801832
--- /dev/null
+++ b/system/fidl/ddk/protocols/sdmmc.fidl
@@ -0,0 +1,115 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.sdmmc;
+
+using ddk.protocol.block;
+using zircon.listnode;
+using zx;
+
+enum SdmmcVoltage : uint8 {
+ V330 = 0;
+ V180 = 1;
+ MAX = 2;
+};
+
+enum SdmmcBusWidth : uint8 {
+ ONE = 0;
+ FOUR = 1;
+ EIGHT = 2;
+ MAX = 3;
+};
+
+enum SdmmcTiming : uint8 {
+ LEGACY = 0;
+ HS = 1;
+ HSDDR = 2;
+ HS200 = 3;
+ HS400 = 4;
+ SDR12 = 5;
+ SDR25 = 6;
+ SDR50 = 7;
+ SDR104 = 8;
+ DDR50 = 9;
+ MAX = 10;
+};
+
+/// block io transactions. one per client request
+struct SdmmcTxn {
+ ddk.protocol.block.BlockOp bop;
+ zircon.listnode.ListNode node;
+};
+
+/// number of pages per request - 2M per request
+/// matches DMA_DESC_COUNT in dev/block/sdhci
+/// (PAGE_SIZE / sizeof(zx_paddr_t))
+const uint64 SDMMC_PAGES_COUNT = 512;
+
+/// sdmmc requests. one per command
+struct SdmmcReq {
+ uint32 cmd_idx;
+ uint32 cmd_flags;
+ uint32 arg;
+
+ /// data command parameters
+ uint16 blockcount;
+ uint16 blocksize;
+ bool use_dma;
+ /// Used if use_dma is true
+ handle<vmo> dma_vmo;
+ /// Used if use_dma is false
+ vector<void> virt;
+ /// offset into dma_vmo or virt
+ uint64 buf_offset;
+ handle pmt;
+
+ /// response data
+ array<uint32>:4 response;
+
+ /// status
+ zx.status status;
+};
+
+enum SdmmcHostCap : uint64 {
+ BUS_WIDTH_8 = 0x1;
+ ADMA2 = 0x2;
+ SIXTY_FOUR_BIT = 0x4;
+ VOLTAGE_330 = 0x8;
+ AUTO_CMD12 = 0x10;
+};
+
+enum SdmmcHostPrefs : uint64 {
+ DISABLE_HS400 = 0x1;
+ DISABLE_HS200 = 0x2;
+};
+
+struct SdmmcHostInfo {
+ /// Controller capabilities
+ uint64 caps;
+ /// Maximum data request size
+ uint64 max_transfer_size;
+ uint64 max_transfer_size_non_dma;
+ /// Host specific preferences
+ uint64 prefs;
+};
+
+[Layout="ddk-protocol"]
+interface Sdmmc {
+ /// Get host info.
+ 1: HostInfo() -> (zx.status s, SdmmcHostInfo info);
+ /// Set signal voltage.
+ 2: SetSignalVoltage(SdmmcVoltage voltage) -> (zx.status s);
+ /// Set bus width.
+ 3: SetBusWidth(SdmmcBusWidth bus_width) -> (zx.status s);
+ /// Set bus frequency.
+ 4: SetBusFreq(uint32 bus_freq) -> (zx.status s);
+ /// Set mmc timing.
+ 5: SetTiming(SdmmcTiming timing) -> (zx.status s);
+ /// Issue a hw reset.
+ 6: HwReset() -> ();
+ /// Perform tuning.
+ 7: PerformTuning(uint32 cmd_idx) -> (zx.status s);
+ /// Issue a request.
+ 8: Request(SdmmcReq? req) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/serial-impl.fidl b/system/fidl/ddk/protocols/serial-impl.fidl
new file mode 100644
index 0000000..8933fba
--- /dev/null
+++ b/system/fidl/ddk/protocols/serial-impl.fidl
@@ -0,0 +1,33 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.serial_impl;
+
+using zx;
+using ddk.protocol.serial;
+
+enum SerialState : uint32 {
+ READABLE = 0x1;
+ WRITABLE = 0x2;
+};
+
+/// Callback for notification of readable/writeable state changes
+/// This may be called from an interrupt thread it should just signal another thread
+/// and return as soon as possible. In particular, it may not be safe to make protocol calls
+/// from these callbacks.
+[Layout="ddk-callback"]
+interface SerialNotify {
+ 1: Callback(SerialState state) -> ();
+};
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface SerialImpl {
+ 1: GetInfo() -> (zx.status s, ddk.protocol.serial.SerialPortInfo info);
+ /// Configures the given serial port.
+ 2: Config(uint32 baud_rate, uint32 flags) -> (zx.status s);
+ 3: Enable(bool enable) -> (zx.status s);
+ 4: Read() -> (zx.status s, vector<void> buf);
+ 5: Write(vector<void> buf) -> (zx.status s, usize actual);
+ 6: SetNotifyCallback(SerialNotify cb) -> (zx.status s);
+};
diff --git a/system/fidl/ddk/protocols/serial.fidl b/system/fidl/ddk/protocols/serial.fidl
new file mode 100644
index 0000000..36c8261
--- /dev/null
+++ b/system/fidl/ddk/protocols/serial.fidl
@@ -0,0 +1,29 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.serial;
+
+using zx;
+
+struct SerialPortInfo {
+ uint32 serial_class;
+ /// Vendor and product ID of hardware attached to this serial port,
+ /// or zero if not applicable.
+ uint32 serial_vid;
+ uint32 serial_pid;
+};
+
+/// High level serial protocol for use by client drivers.
+/// When used with the platform device protocol, "port" will be relative to
+/// the list of serial ports assigned to your device rather than the global
+/// list of serial ports.
+[Layout="ddk-protocol", DefaultProtocol]
+interface Serial {
+ 1: GetInfo() -> (zx.status s, SerialPortInfo info);
+ /// Configures the given serial port.
+ 2: Config(uint32 baud_rate, uint32 flags) -> (zx.status s);
+ /// Returns a socket that can be used for reading and writing data
+ /// from the given serial port.
+ 3: OpenSocket() -> (zx.status s, handle<socket> @handle);
+};
diff --git a/system/fidl/ddk/protocols/skip-block.fidl b/system/fidl/ddk/protocols/skip-block.fidl
new file mode 100644
index 0000000..c2a2cad
--- /dev/null
+++ b/system/fidl/ddk/protocols/skip-block.fidl
@@ -0,0 +1,8 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.skip_block;
+
+[Layout="ddk-protocol", DefaultProtocol]
+interface SkipBlock {};
diff --git a/system/fidl/ddk/protocols/test.fidl b/system/fidl/ddk/protocols/test.fidl
new file mode 100644
index 0000000..83e1977
--- /dev/null
+++ b/system/fidl/ddk/protocols/test.fidl
@@ -0,0 +1,42 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.test;
+
+using zx;
+
+struct TestReport {
+ uint64 n_tests;
+ uint64 n_success;
+ uint64 n_failed;
+};
+
+[Layout="ddk-callback"]
+interface TestFunc {
+ 1: Callback(vector<void> arg) -> (zx.status s, TestReport report);
+};
+
+[Layout="ddk-protocol"]
+interface Test {
+ /// Sets test output socket.
+ 1: SetOutputSocket(handle<socket> @handle) -> ();
+
+ /// Gets test output socket.
+ 2: GetOutputSocket() -> (handle<socket> h);
+
+ /// Sets control channel.
+ 3: SetControlChannel(handle<channel> @handle) -> ();
+
+ /// Gets control channel.
+ 4: GetControlChannel() -> (handle<channel> @handle);
+
+ /// Sets test function.
+ 5: SetTestFunc(TestFunc func) -> ();
+
+ /// Run tests, calls the function set in |SetTestFunc|.
+ 6: RunTests(vector<void> arg) -> (zx.status s, TestReport report);
+
+ /// Calls `device_remove()`.
+ 7: Destroy() -> ();
+};
diff --git a/system/fidl/ddk/protocols/usb-bus.fidl b/system/fidl/ddk/protocols/usb-bus.fidl
new file mode 100644
index 0000000..3c4bc77
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb-bus.fidl
@@ -0,0 +1,33 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb_bus;
+
+using ddk.protocol.usb_hub;
+using zircon.hw.usb;
+using zircon.hw.usb_hub;
+using zx;
+
+// TODO: Not need this anymore.
+[repr="C"]
+struct ZxDevice {};
+
+[Layout="ddk-protocol"]
+interface UsbBus {
+ /// Hub support.
+ 1: ConfigureHub(ZxDevice? hub_device, zircon.hw.usb.UsbSpeed speed,
+ zircon.hw.usb_hub.UsbHubDescriptor descriptor) -> (zx.status s);
+ 2: HubDeviceAdded(ZxDevice? hub_device, int64 port, zircon.hw.usb.UsbSpeed speed)
+ -> (zx.status s);
+ 3: HubDeviceRemoved(ZxDevice? hub_device, int64 port) -> (zx.status s);
+ 4: SetHubInterface(ZxDevice? usb_device, ddk.protocol.usb_hub.UsbHub hub) -> (zx.status s);
+};
+
+/// Interface for use by the HCI controller to use to notify when devices are added and removed.
+[Layout="ddk-interface"]
+interface UsbBusInterface {
+ 1: AddDevice(uint32 device_id, uint32 hub_id, zircon.hw.usb.UsbSpeed speed) -> (zx.status s);
+ 2: RemoveDevice(uint32 device_id) -> ();
+ 3: ResetHubPort(uint32 hub_id, uint32 port) -> ();
+};
diff --git a/system/fidl/ddk/protocols/usb-dci.fidl b/system/fidl/ddk/protocols/usb-dci.fidl
new file mode 100644
index 0000000..2d11e04
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb-dci.fidl
@@ -0,0 +1,35 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb_dci;
+
+using ddk.protocol.usb;
+using zircon.hw.usb;
+using zx;
+
+/// This protocol is used for USB peripheral controller drivers.
+///
+/// Callbacks implemented by the USB device driver.
+[Layout="ddk-interface"]
+interface UsbDciInterface {
+ /// callback for handling ep0 control requests
+ 1: Control(zircon.hw.usb.UsbSetup setup) -> (zx.status status, vector<void> buffer,
+ usize actual);
+ 2: SetConnected(bool connected) -> ();
+ 3: SetSpeed(zircon.hw.usb.UsbSpeed speed) -> ();
+};
+
+[Layout="ddk-protocol"]
+interface UsbDci {
+ 1: RequestQueue(ddk.protocol.usb.UsbRequest? req) -> ();
+ /// Registers callback interface with the controller driver.
+ 2: SetInterface(UsbDciInterface @interface) -> (zx.status s);
+ 3: ConfigEp(zircon.hw.usb.UsbEndpointDescriptor ep_desc,
+ zircon.hw.usb.UsbSsEpCompDescriptor ss_comp_desc) -> (zx.status s);
+ 4: DisableEp(uint8 ep_address) -> (zx.status s);
+ 5: EpSetStall(uint8 ep_address) -> (zx.status s);
+ 6: EpClearStall(uint8 ep_address) -> (zx.status s);
+ /// Shares a copy of the DCI driver's BTI handle.
+ 7: GetBti() -> (zx.status s, handle<bti> bti);
+};
diff --git a/system/fidl/ddk/protocols/usb-function.fidl b/system/fidl/ddk/protocols/usb-function.fidl
new file mode 100644
index 0000000..1a16441
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb-function.fidl
@@ -0,0 +1,81 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb_function;
+
+using ddk.protocol.usb;
+using ddk.phys_iter;
+using zircon.hw.usb;
+using zx;
+
+/// This protocol is used for USB peripheral function functions.
+/// Callbacks implemented by the function driver.
+[Layout="ddk-interface"]
+interface UsbFunctionInterface {
+ /// Callback for handling ep0 control requests.
+ /// Return the descriptor list for the function. Callee retains ownership of descriptors.
+ // TODO(voydanoff) - descriptors will likely vary (different max packet sizes, etc)
+ // depending on whether we are in low/full, high or super speed mode.
+ // We will need to add a usb_speed_t argument to this callback.
+ 1: GetDescriptors() -> (vector<zircon.hw.usb.UsbDescriptorHeader>? descriptor);
+
+ /// Callback for handling ep0 control requests.
+ 2: Control(zircon.hw.usb.UsbSetup setup) -> (zx.status s, vector<void> buffer, usize actual);
+
+ /// Called to inform the function driver when the USB device configured state changes.
+ /// Called with configured == true in response to a SET_CONFIGURATION control request
+ /// that selects a configuration that contains this function. In this case, the function driver
+ /// should call usb_function_config_ep() to configure its endpoints.
+ /// Called with configured == false when configuration is disabled or USB is disconnected.
+ /// The function driver should then call usb_function_disable_ep() to disable its endpoints.
+ 3: SetConfigured(bool configured, zircon.hw.usb.UsbSpeed speed) -> (zx.status s);
+
+ /// Called to set an alternate setting for an interface due to a SET_INTERFACE control request.
+ /// The function driver should call usb_function_config_ep() and/or usb_function_config_ep()
+ /// to configure or disable the interface's endpoints as appropriate.
+ 4: SetInterface(uint64 @interface, uint64 alt_setting) -> (zx.status s);
+};
+
+[Layout="ddk-protocol"]
+interface UsbDciInterface {
+ 1: ReqAlloc(uint64 data_size, uint8 ep_address) -> (zx.status s, ddk.protocol.usb.UsbRequest? req);
+ 2: ReqAllocVmo(handle<vmo> vmo, uint64 vmo_offset, uint64 length,
+ uint8 ep_address) -> (zx.status s, ddk.protocol.usb.UsbRequest? req);
+ 3: ReqInit(ddk.protocol.usb.UsbRequest? req, handle<vmo> vmo, uint64 vmo_offset, uint64 length,
+ uint8 ep_address) -> (zx.status s);
+ 4: ReqCopyFrom(ddk.protocol.usb.UsbRequest? req, usize offset) -> (vector<void> data);
+ 5: ReqCopyTo(ddk.protocol.usb.UsbRequest req, vector<void> data, usize offset) -> (isize len);
+ 6: ReqMmap(ddk.protocol.usb.UsbRequest? req) -> (zx.status s, vector<void>? data);
+ 7: ReqCacheop(ddk.protocol.usb.UsbRequest? req, uint32 op, usize offset, usize length) -> (zx.status s);
+ 8: ReqCacheFlush(ddk.protocol.usb.UsbRequest? req, usize offset, usize length) -> (zx.status s);
+ 9: ReqCacheFlushInvalidate(ddk.protocol.usb.UsbRequest? req, usize offset, usize length) -> (zx.status s);
+ 10: ReqPhysmap(ddk.protocol.usb.UsbRequest? req) -> (zx.status s);
+ 11: ReqRelease(ddk.protocol.usb.UsbRequest? req) -> ();
+ 12: ReqComplete(ddk.protocol.usb.UsbRequest? req, zx.status status, usize actual) -> ();
+ 13: ReqPhysIterInit(ddk.protocol.usb.UsbRequest? req, usize actual, usize max_length)
+ -> (ddk.phys_iter.PhysIter iter);
+ /// Registers the function driver's callback interface.
+ 14: RegisterFunc(UsbFunctionInterface intf) -> (zx.status s);
+ /// Allocates a unique interface descriptor number.
+ 15: AllocInterface() -> (zx.status s, uint8 intf_num);
+ /// Allocates a unique endpoint descriptor number.
+ /// Direction should be either `USB_DIR_OUT` or `USB_DIR_IN`.
+ 16: AllocEp(uint8 direction) -> (zx.status s, uint8 address);
+ /// Configures an endpoint based on the provided usb_endpoint_descriptor_t and
+ /// usb_ss_ep_comp_descriptor_t descriptors.
+ 17: ConfigEp(zircon.hw.usb.UsbEndpointDescriptor? ep_desc,
+ zircon.hw.usb.UsbSsEpCompDescriptor? ss_comp_desc) -> (zx.status s);
+ /// Disables an endpoint. called when the device is no longer configured or an alternate interface
+ /// is selected.
+ 18: DisableEp(uint8 ep_addr) -> (zx.status s);
+ /// Adds a string descriptor to the device configuration.
+ 19: AllocStringDesc(string @string) -> (zx.status s, uint8 index);
+ /// Helper for queueing a usb request on an endpoint.
+ 20: Queue(ddk.protocol.usb.UsbRequest? req) -> ();
+ /// Stalls an endpoint.
+ 21: EpSetStall(uint8 ep_address) -> (zx.status s);
+ /// Clears endpoint stall state.
+ 22: EpClearStall(uint8 ep_address) -> (zx.status s);
+};
+
diff --git a/system/fidl/ddk/protocols/usb-hci.fidl b/system/fidl/ddk/protocols/usb-hci.fidl
new file mode 100644
index 0000000..6a88dd7
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb-hci.fidl
@@ -0,0 +1,34 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb_hci;
+
+using ddk.protocol.usb;
+using ddk.protocol.usb_bus;
+using zircon.hw.usb;
+using zircon.hw.usb_hub;
+using zx;
+
+[Layout="ddk-protocol"]
+interface UsbHci {
+ 1: RequestQueue(ddk.protocol.usb.UsbRequest? usb_request) -> ();
+ 2: SetBusInterface(ddk.protocol.usb_bus.UsbBusInterface bus_intf) -> ();
+ 3: GetMaxDeviceCount() -> (usize count);
+ /// Enables or disables an endpoint using parameters derived from |ep_desc|.
+ 4: EnableEndpoint(uint32 device_id, zircon.hw.usb.UsbEndpointDescriptor? ep_desc,
+ zircon.hw.usb.UsbSsEpCompDescriptor? ss_com_desc, bool enable) -> (zx.status s);
+
+ /// Returns the current frame (in milliseconds), used for isochronous transfers.
+ 5: GetCurrentFrame() -> (uint64 frame);
+
+ /// Hub support.
+ 6: ConfigureHub(uint32 device_id, zircon.hw.usb.UsbSpeed speed,
+ zircon.hw.usb_hub.UsbHubDescriptor descriptor) -> (zx.status s);
+ 7: HubDeviceAdded(uint32 device_id, int64 port, zircon.hw.usb.UsbSpeed speed) -> (zx.status s);
+ 8: HubDeviceRemoved(uint32 device_id, int64 port) -> (zx.status s);
+ 9: ResetEndpoint(uint32 device_id, uint8 ep_address) -> (zx.status s);
+ 10: GetMaxTransferSize(uint32 device_id, uint8 ep_address) -> (usize size);
+ 11: CancelAll(uint32 device_id, uint8 ep_address) -> (usize size);
+ 12: GetBti() -> (handle<bti> bti);
+};
diff --git a/system/fidl/ddk/protocols/usb-hub.fidl b/system/fidl/ddk/protocols/usb-hub.fidl
new file mode 100644
index 0000000..4aa43d5
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb-hub.fidl
@@ -0,0 +1,11 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb_hub;
+
+/// Interface for use by the usb-bus to talk to the hub driver.
+[Layout="ddk-protocol"]
+interface UsbHub {
+ 1: ResetPort(uint32 port) -> ();
+};
diff --git a/system/fidl/ddk/protocols/usb-mode-switch.fidl b/system/fidl/ddk/protocols/usb-mode-switch.fidl
new file mode 100644
index 0000000..8c209c3
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb-mode-switch.fidl
@@ -0,0 +1,15 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb_mode_switch;
+
+using ddk.protocol.hidbus;
+using zircon.device.usb_device;
+using zx;
+
+[Layout="ddk-protocol"]
+interface UsbModeSwitch {
+ 1: SetMode(zircon.device.usb_device.UsbMode mode) -> (zx.status s,
+ ddk.protocol.hidbus.HidInfo info);
+};
diff --git a/system/fidl/ddk/protocols/usb.fidl b/system/fidl/ddk/protocols/usb.fidl
new file mode 100644
index 0000000..e3106a3
--- /dev/null
+++ b/system/fidl/ddk/protocols/usb.fidl
@@ -0,0 +1,164 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library ddk.protocol.usb;
+
+using ddk.phys_iter;
+using zircon.hw.usb;
+using zircon.hw.usb_hub;
+using zircon.listnode;
+using zx;
+
+//using UsbSpeed = uint8;
+enum UsbSpeed : uint8 {};
+
+[Layout="ddk-callback"]
+interface UsbRequestComplete {
+ 1: Callback(UsbRequest? req) -> ();
+};
+
+[Layout="ddk-callback"]
+interface UsbRequestRelease {
+ 1: Callback(UsbRequest? req) -> ();
+};
+
+/// Should be set by the requestor.
+struct UsbHeader {
+ /// Frame number for scheduling isochronous transfers.
+ uint64 frame;
+ uint32 device_id;
+ /// bEndpointAddress from endpoint descriptor.
+ uint8 ep_address;
+ /// Number of bytes to transfer.
+ zx.off length;
+ /// Send zero length packet if length is multiple of max packet size.
+ bool send_zlp;
+};
+
+/// Response data.
+/// (Filled in by processor before |UsbRequestComplete()| is called)
+struct UsbResponse {
+ /// Status of transaction.
+ zx.status status;
+ /// Number of bytes actually transferred (on success).
+ zx.off actual;
+};
+
+struct UsbRequest {
+ UsbHeader header;
+
+ /// For control transactions.
+ zircon.hw.usb.UsbSetup setup;
+
+ /// VMO handle for payload.
+ handle<vmo> vmo_handle;
+ handle<bti> bti_handle;
+ usize size;
+ /// Offset of the start of data from first page address of the vmo.
+ zx.off offset;
+ /// Mapped address of the first page of the vmo.
+ /// Add offset to get actual data.
+ vector<void> virt;
+
+ handle pmt;
+ /// Phys addresses of the payload.
+ vector<zx.paddr> phys_list;
+
+ /// The |complete.callback()| callback is set by the requestor and is
+ /// invoked by the 'complete' ops method when it is called by
+ /// the processor upon completion of the usb request.
+ /// The saved_complete_cb field can be used to temporarily save
+ /// the original callback and overwrite it with the desired intermediate
+ /// callback.
+ UsbRequestComplete? complete;
+
+ /// Set by the requestor for opting out of the complete_cb()
+ /// callback for successfully completed requests. The callback
+ /// will still be invoked if an error is encountered.
+ /// This is useful for isochronous requests, where the requestor
+ /// may not care about most callbacks. They will still have to request
+ /// callbacks at a regular interval to queue more data, and free or
+ /// reuse previously silently completed requests.
+ bool cb_on_error_only;
+
+ /// The current 'owner' of the usb request may save the original
+ /// complete callback and cookie, allowing them to insert an
+ /// intermediate callback.
+ UsbRequestComplete? saved_complete;
+
+ UsbResponse response;
+
+ /// list node and context
+ /// the current "owner" of the usb_request may use these however desired
+ /// (eg, the requestor may use node to hold the usb_request on a free list
+ /// and when it's queued the processor may use node to hold the usb_request
+ /// in a transaction queue)
+ zircon.listnode.ListNode node;
+
+ vector<void> context;
+
+ /// The release.callback() callback is set by the allocator and is
+ /// invoked by the 'usb_request_release' method when it is called
+ /// by the requestor.
+ UsbRequestRelease? release;
+};
+
+[Layout="ddk-protocol"]
+interface Usb {
+ 1: ReqAlloc(uint64 data_size, uint8 ep_address) -> (zx.status s, UsbRequest? req);
+ 2: ReqAllocVmo(handle<vmo> vmo, uint64 vmo_offset, uint64 length,
+ uint8 ep_address) -> (zx.status s, UsbRequest? req);
+ 3: ReqInit(UsbRequest? req, handle<vmo> vmo, uint64 vmo_offset, uint64 length,
+ uint8 ep_address) -> (zx.status s);
+ 4: ReqCopyFrom(UsbRequest? req, usize offset) -> (isize s, vector<void> data);
+ 5: ReqCopyTo(UsbRequest? req, vector<void> data, usize offset) -> (isize s);
+ 6: ReqMmap(UsbRequest? req) -> (zx.status s, vector<void>? data);
+ 7: ReqCacheop(UsbRequest? req, uint32 op, usize offset, usize length) -> (zx.status s);
+ 8: ReqCacheFlush(UsbRequest? req, usize offset, usize length) -> (zx.status s);
+ 9: ReqCacheFlushInvalidate(UsbRequest? req, zx.off offset, usize length) -> (zx.status s);
+ 10: ReqPhysmap(UsbRequest? req) -> (zx.status s);
+ 11: ReqRelease(UsbRequest? req) -> ();
+ 12: ReqComplete(UsbRequest? req, zx.status status, zx.off actual) -> ();
+ 13: ReqPhysIterInit(UsbRequest? req, usize max_length) -> (ddk.phys_iter.PhysIter iter);
+ 14: Control(uint8 request_type, uint8 @request, uint16 value, uint16 index,
+ vector<void> data, zx.time timeout) -> (zx.status s, usize length);
+ /// queues a USB request
+ 15: RequestQueue(UsbRequest? req) -> ();
+ 16: GetSpeed() -> (UsbSpeed s);
+ 17: SetInterface(int64 interface_number, int64 alt_setting) -> (zx.status s);
+ 18: SetConfiguration(int64 configuration) -> (zx.status s);
+ /// Resets an endpoint that is in a halted or error state.
+ /// Endpoints will be halted if the device returns a STALL in response to a USB transaction.
+ /// When that occurs, the transaction will fail with ERR_IO_REFUSED.
+ /// usb_reset_endpoint() the endpoint to normal running state.
+ 19: ResetEndpoint(uint8 ep_address) -> (zx.status s);
+ /// returns the maximum amount of data that can be transferred on an endpoint in a single
+ /// transaction.
+ 20: GetMaxTransferSize(uint8 ep_address) -> (usize s);
+ 21: GetDeviceId() -> (uint32 dev_id);
+ 22: GetDeviceDescriptor() -> (zircon.hw.usb.UsbDeviceDescriptor desc);
+ /// returns the USB descriptors for the USB device or interface
+ /// the returned value is de-allocated with free()
+ 23: GetDescriptorList() -> (vector<void>? descriptors);
+ /// returns the USB descriptors following the interface's existing descriptors
+ /// the returned value is de-allocated with free()
+ 24: GetAdditionalDescriptorList() -> (vector<void>? descriptors);
+ /// Fetch the descriptor using the provided descriptor ID and language ID. If
+ /// the language ID requested is not available, the first entry of the language
+ /// ID table will be used instead and be provided in the updated version of the
+ /// parameter.
+ ///
+ /// The string will be encoded using UTF-8, and will be truncated to fit the
+ /// space provided by the buflen parameter. buflen will be updated to indicate
+ /// the amount of space needed to hold the actual UTF-8 encoded string lenth, and
+ /// may be larger than the original value passed. Embedded nulls may be present
+ /// in the string, and the result may not be null terminated if the string
+ /// occupies the entire provided buffer.
+ 25: GetStringDescriptor(uint8 desc_id, uint16 lang_id) -> (zx.status s, uint16 lang_id,
+ vector<void> buf);
+ /// marks the interface as claimed and appends the interface descriptor to the
+ /// interface's existing descriptor
+ 26: ClaimInterface(zircon.hw.usb.UsbInterfaceDescriptor? intf, usize length) -> (zx.status s);
+ 27: CancelAll(uint8 ep_address) -> (zx.status s);
+};
diff --git a/system/public/zircon/device/display-controller.h b/system/public/zircon/device/display-controller.h
index edb4653..049d958 100644
--- a/system/public/zircon/device/display-controller.h
+++ b/system/public/zircon/device/display-controller.h
@@ -15,5 +15,5 @@
IOCTL_WRAPPER_OUT(ioctl_display_controller_get_handle,
IOCTL_DISPLAY_CONTROLLER_GET_HANDLE, zx_handle_t);
-#define IMAGE_TYPE_SIMPLE 0
+#define IMAGE_TYPE_SIMPLE UINT32_C(0)
#define INVALID_ID 0
diff --git a/system/ulib/ddk/include/ddk/protocol/acpi.h b/system/ulib/ddk/include/ddk/protocol/acpi.h
index a113c1b..9ab9364 100644
--- a/system/ulib/ddk/include/ddk/protocol/acpi.h
+++ b/system/ulib/ddk/include/ddk/protocol/acpi.h
@@ -1,7 +1,9 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,26 +11,33 @@
__BEGIN_CDECLS;
+// Forward declarations
+
+typedef struct acpi_protocol acpi_protocol_t;
+
+// Declarations
+
typedef struct acpi_protocol_ops {
- zx_status_t (*map_resource)(void* ctx, uint32_t res_id, uint32_t cache_policy,
- void** vaddr, size_t* size, zx_handle_t* out_handle);
- zx_status_t (*map_interrupt)(void* ctx, int which_irq, zx_handle_t* out_handle);
+ zx_status_t (*map_resource)(void* ctx, uint32_t resource_id, uint32_t cache_policy,
+ void** out_vaddr_buffer, size_t* vaddr_size,
+ zx_handle_t* out_handle);
+ zx_status_t (*map_interrupt)(void* ctx, int64_t irq_id, zx_handle_t* out_handle);
} acpi_protocol_ops_t;
-typedef struct acpi_protocol {
+struct acpi_protocol {
acpi_protocol_ops_t* ops;
void* ctx;
-} acpi_protocol_t;
+};
-static inline zx_status_t acpi_map_resource(acpi_protocol_t* acpi, uint32_t res_id,
- uint32_t cache_policy, void** vaddr, size_t* size,
- zx_handle_t* out_handle) {
- return acpi->ops->map_resource(acpi->ctx, res_id, cache_policy, vaddr, size, out_handle);
+static inline zx_status_t acpi_map_resource(const acpi_protocol_t* proto, uint32_t resource_id,
+ uint32_t cache_policy, void** out_vaddr_buffer,
+ size_t* vaddr_size, zx_handle_t* out_handle) {
+ return proto->ops->map_resource(proto->ctx, resource_id, cache_policy, out_vaddr_buffer,
+ vaddr_size, out_handle);
}
-
-static inline zx_status_t acpi_map_interrupt(acpi_protocol_t* acpi, int which_irq,
- zx_handle_t* out_handle) {
- return acpi->ops->map_interrupt(acpi->ctx, which_irq, out_handle);
+static inline zx_status_t acpi_map_interrupt(const acpi_protocol_t* proto, int64_t irq_id,
+ zx_handle_t* out_handle) {
+ return proto->ops->map_interrupt(proto->ctx, irq_id, out_handle);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/amlogic-canvas.h b/system/ulib/ddk/include/ddk/protocol/amlogic-canvas.h
index 5c8835b..ed73d59 100644
--- a/system/ulib/ddk/include/ddk/protocol/amlogic-canvas.h
+++ b/system/ulib/ddk/include/ddk/protocol/amlogic-canvas.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,37 +11,42 @@
__BEGIN_CDECLS;
-typedef struct {
+// Forward declarations
+
+typedef struct canvas_info canvas_info_t;
+typedef struct canvas_protocol canvas_protocol_t;
+
+// Declarations
+
+struct canvas_info {
uint32_t height;
uint32_t stride_bytes;
uint32_t wrap;
uint32_t blkmode;
uint32_t endianness;
-} canvas_info_t;
+};
-typedef struct {
- zx_status_t (*config)(void* ctx, zx_handle_t vmo,
- size_t offset, canvas_info_t* info,
- uint8_t* canvas_idx);
+typedef struct canvas_protocol_ops {
+ zx_status_t (*config)(void* ctx, zx_handle_t vmo, size_t offset, const canvas_info_t* info,
+ uint8_t* out_canvas_idx);
zx_status_t (*free)(void* ctx, uint8_t canvas_idx);
} canvas_protocol_ops_t;
-typedef struct {
+struct canvas_protocol {
canvas_protocol_ops_t* ops;
void* ctx;
-} canvas_protocol_t;
+};
-// Configures a canvas
-// Adds a framebuffer to the canvas lookup table
-static inline zx_status_t canvas_config(canvas_protocol_t* canvas, zx_handle_t vmo,
- size_t offset, canvas_info_t* info,
- uint8_t* canvas_idx) {
- return canvas->ops->config(canvas->ctx, vmo, offset,
- info, canvas_idx);
+// Configures a canvas.
+// Adds a framebuffer to the canvas lookup table.
+static inline zx_status_t canvas_config(const canvas_protocol_t* proto, zx_handle_t vmo,
+ size_t offset, const canvas_info_t* info,
+ uint8_t* out_canvas_idx) {
+ return proto->ops->config(proto->ctx, vmo, offset, info, out_canvas_idx);
+}
+// Frees up a canvas.
+static inline zx_status_t canvas_free(const canvas_protocol_t* proto, uint8_t canvas_idx) {
+ return proto->ops->free(proto->ctx, canvas_idx);
}
-// Frees up a canvas
-static inline zx_status_t canvas_free(canvas_protocol_t* canvas, uint8_t canvas_idx) {
- return canvas->ops->free(canvas->ctx, canvas_idx);
-}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/bad-block.h b/system/ulib/ddk/include/ddk/protocol/bad-block.h
index e68298d..46e3655 100644
--- a/system/ulib/ddk/include/ddk/protocol/bad-block.h
+++ b/system/ulib/ddk/include/ddk/protocol/bad-block.h
@@ -2,39 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <assert.h>
-#include <stdint.h>
-
+#include <zircon/compiler.h>
#include <zircon/types.h>
+__BEGIN_CDECLS;
+
+// Forward declarations
+
+typedef struct bad_block_protocol bad_block_protocol_t;
+
+// Declarations
+
typedef struct bad_block_protocol_ops {
- // Fills in |bad_block_list| with a list of bad blocks, up until
- // |bad_block_list_len|. The order of blocks is undefined.
- // |bad_block_count| will be filled in with the actual number of bad
- // blocks. It is recommended to first make call with |bad_block_list_len|
- // equal to 0 in order to determine how large the |bad_block_list| is.
- zx_status_t (*get_bad_block_list)(void* ctx, uint32_t* bad_block_list,
- uint32_t bad_block_list_len, uint32_t* bad_block_count);
-
- // Sets |block| as bad. If block is already marked bad, it has no effect.
+ zx_status_t (*get_bad_block_list)(void* ctx, uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count, size_t* out_bad_blocks_actual);
zx_status_t (*mark_block_bad)(void* ctx, uint32_t block);
-
} bad_block_protocol_ops_t;
-typedef struct bad_block_protocol {
+struct bad_block_protocol {
bad_block_protocol_ops_t* ops;
void* ctx;
-} bad_block_protocol_t;
+};
-static inline zx_status_t bad_block_get_bad_block_list(
- bad_block_protocol_t* proto, uint32_t* bad_block_list, uint32_t bad_block_list_len,
- uint32_t* bad_block_count) {
- return proto->ops->get_bad_block_list(proto->ctx, bad_block_list, bad_block_list_len,
- bad_block_count);
+// Fills in |bad_blocks| with a list of bad blocks, up until
+// |bad_blocks_count|. The order of blocks is undefined.
+// |bad_blocks_actual| will be filled in with the actual number of bad
+// blocks. It is recommended to first make call with |bad_blocks_count|
+// equal to 0 in order to determine how large the |bad_blocks| is.
+static inline zx_status_t bad_block_get_bad_block_list(const bad_block_protocol_t* proto,
+ uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual) {
+ return proto->ops->get_bad_block_list(proto->ctx, out_bad_blocks_list, bad_blocks_count,
+ out_bad_blocks_actual);
}
-
-static inline zx_status_t bad_block_mark_block_bad(bad_block_protocol_t* proto, uint32_t block) {
+// Sets |block| as bad. If block is already marked bad, it has no effect.
+static inline zx_status_t bad_block_mark_block_bad(const bad_block_protocol_t* proto,
+ uint32_t block) {
return proto->ops->mark_block_bad(proto->ctx, block);
}
+
+__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/bt-hci.h b/system/ulib/ddk/include/ddk/protocol/bt-hci.h
index dd386d2..a8902ec 100644
--- a/system/ulib/ddk/include/ddk/protocol/bt-hci.h
+++ b/system/ulib/ddk/include/ddk/protocol/bt-hci.h
@@ -1,7 +1,9 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,44 +11,46 @@
__BEGIN_CDECLS;
-typedef struct {
- // Open the two-way HCI command channel for sending HCI commands and
- // receiving event packets. Returns ZX_ERR_ALREADY_BOUND if the channel
- // is already open.
+// Forward declarations
+
+typedef struct bt_hci_protocol bt_hci_protocol_t;
+
+// Declarations
+
+typedef struct bt_hci_protocol_ops {
zx_status_t (*open_command_channel)(void* ctx, zx_handle_t* out_channel);
-
- // Open the two-way HCI ACL data channel.
- // Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
zx_status_t (*open_acl_data_channel)(void* ctx, zx_handle_t* out_channel);
-
- // Open an output-only channel for monitoring HCI traffic.
- // The format of each message is: [1-octet flags] [n-octet payload]
- // The flags octet is a bitfield with the following values defined:
- // - 0x00: The payload represents a command packet sent from the host to the
- // controller.
- // - 0x01: The payload represents an event packet sent by the controller.
- // Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
zx_status_t (*open_snoop_channel)(void* ctx, zx_handle_t* out_channel);
} bt_hci_protocol_ops_t;
-typedef struct {
+struct bt_hci_protocol {
bt_hci_protocol_ops_t* ops;
void* ctx;
-} bt_hci_protocol_t;
+};
-static inline zx_status_t bt_hci_open_command_channel(bt_hci_protocol_t* bt_hci,
+// Open the two-way HCI command channel for sending HCI commands and
+// receiving event packets. Returns ZX_ERR_ALREADY_BOUND if the channel
+// is already open.
+static inline zx_status_t bt_hci_open_command_channel(const bt_hci_protocol_t* proto,
zx_handle_t* out_channel) {
- return bt_hci->ops->open_command_channel(bt_hci->ctx, out_channel);
+ return proto->ops->open_command_channel(proto->ctx, out_channel);
}
-
-static inline zx_status_t bt_hci_open_acl_data_channel(bt_hci_protocol_t* bt_hci,
+// Open the two-way HCI ACL data channel.
+// Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+static inline zx_status_t bt_hci_open_acl_data_channel(const bt_hci_protocol_t* proto,
zx_handle_t* out_channel) {
- return bt_hci->ops->open_acl_data_channel(bt_hci->ctx, out_channel);
+ return proto->ops->open_acl_data_channel(proto->ctx, out_channel);
}
-
-static inline zx_status_t bt_hci_open_snoop_channel(bt_hci_protocol_t* bt_hci,
+// Open an output-only channel for monitoring HCI traffic.
+// The format of each message is: [1-octet flags] [n-octet payload]
+// The flags octet is a bitfield with the following values defined:
+// - 0x00: The payload represents a command packet sent from the host to the
+// controller.
+// - 0x01: The payload represents an event packet sent by the controller.
+// Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+static inline zx_status_t bt_hci_open_snoop_channel(const bt_hci_protocol_t* proto,
zx_handle_t* out_channel) {
- return bt_hci->ops->open_snoop_channel(bt_hci->ctx, out_channel);
+ return proto->ops->open_snoop_channel(proto->ctx, out_channel);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/clk.h b/system/ulib/ddk/include/ddk/protocol/clk.h
index 195442f..9e40e8f 100644
--- a/system/ulib/ddk/include/ddk/protocol/clk.h
+++ b/system/ulib/ddk/include/ddk/protocol/clk.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,22 +11,27 @@
__BEGIN_CDECLS;
+// Forward declarations
+
+typedef struct clk_protocol clk_protocol_t;
+
+// Declarations
+
typedef struct clk_protocol_ops {
zx_status_t (*enable)(void* ctx, uint32_t index);
zx_status_t (*disable)(void* ctx, uint32_t index);
} clk_protocol_ops_t;
-typedef struct {
+struct clk_protocol {
clk_protocol_ops_t* ops;
void* ctx;
-} clk_protocol_t;
+};
-static inline zx_status_t clk_enable(clk_protocol_t * clk, const uint32_t index) {
- return clk->ops->enable(clk->ctx, index);
+static inline zx_status_t clk_enable(const clk_protocol_t* proto, uint32_t index) {
+ return proto->ops->enable(proto->ctx, index);
+}
+static inline zx_status_t clk_disable(const clk_protocol_t* proto, uint32_t index) {
+ return proto->ops->disable(proto->ctx, index);
}
-static inline zx_status_t clk_disable(clk_protocol_t * clk, const uint32_t index) {
- return clk->ops->disable(clk->ctx, index);
-}
-
-__END_CDECLS;
\ No newline at end of file
+__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/display-controller.h b/system/ulib/ddk/include/ddk/protocol/display-controller.h
index 5e9b4a9..aa81069 100644
--- a/system/ulib/ddk/include/ddk/protocol/display-controller.h
+++ b/system/ulib/ddk/include/ddk/protocol/display-controller.h
@@ -2,234 +2,126 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
#include <zircon/device/audio.h>
#include <zircon/types.h>
-#include <zircon/pixelformat.h>
__BEGIN_CDECLS;
-/**
- * protocol/display-controller.h - display controller protocol definitions
- */
+// Forward declarations
-// The image is linear and VMO backed.
-#define IMAGE_TYPE_SIMPLE 0
+typedef struct image_plane image_plane_t;
+typedef uint32_t client_t;
+// The client should convert the corresponding layer to a primary layer.
+#define CLIENT_USE_PRIMARY UINT32_C(1)
+// The client should compose all layers with MERGE_BASE and MERGE_SRC into a new,
+// single primary layer at the MERGE_BASE layer's z-order. The driver must accept
+// a fullscreen layer with the default pixel format, but may accept other layer
+// parameters.
+// MERGE_BASE should only be set on one layer per display. If it is set on multiple
+// layers, the client will arbitrarily pick one and change the rest to MERGE_SRC.
+#define CLIENT_MERGE_BASE UINT32_C(2)
+#define CLIENT_MERGE_SRC UINT32_C(4)
+// The client should pre-scale the image so that src_frame's dimensions are equal
+// to dest_frame's dimensions.
+#define CLIENT_FRAME_SCALE UINT32_C(8)
+// The client should pre-clip the image so that src_frame's dimensions are equal to
+// the image's dimensions.
+#define CLIENT_SRC_FRAME UINT32_C(16)
+// The client should pre-apply the transformation so TRANSFORM_IDENTITY can be used.
+#define CLIENT_TRANSFORM UINT32_C(32)
+// The client should apply the color conversion.
+#define CLIENT_COLOR_CONVERSION UINT32_C(64)
+// The client should apply the alpha transformation itself.
+#define CLIENT_ALPHA UINT32_C(128)
-// a structure containing information about each plane of an image.
-typedef struct image_plane {
- uint32_t byte_offset;
- uint32_t bytes_per_row;
-} image_plane_t;
+typedef uint32_t config_display_t;
+// The display mode configuration is valid. Note that this is distinct from
+// whether or not the layer configuration is valid.
+#define CONFIG_DISPLAY_OK UINT32_C(0)
+// Error indicating that the hardware cannot simultaniously support the
+// requested number of displays.
+#define CONFIG_DISPLAY_TOO_MANY UINT32_C(1)
+// Error indicating that the hardware cannot simultaniously support the given
+// set of display modes. To support a mode, the display must be able to display
+// a single layer with width and height equal to the requested mode and the
+// preferred pixel format.
+#define CONFIG_DISPLAY_UNSUPPORTED_MODES UINT32_C(2)
-// a structure containing information about an image
-typedef struct image {
- // the width and height of the image in pixels
- uint32_t width;
- uint32_t height;
-
- // the pixel format of the image
- zx_pixel_format_t pixel_format;
-
- // The type conveys information about what is providing the pixel data. If this is not
- // IMAGE_FORMAT_SIMPLE, it is up to the driver and buffer producer to agree on the meaning
- // of the value through some mechanism outside the scope of this API.
- uint32_t type;
-
- image_plane_t planes[4];
-
- // A driver-defined handle to the image. Each handle must be unique.
- void* handle;
-} image_t;
-
-#define INVALID_DISPLAY_ID 0
-
-// a fallback structure to convey display information without an edid
-typedef struct display_params {
- uint32_t width;
- uint32_t height;
- uint32_t refresh_rate_e2;
-} display_params_t;
-
-// Info about valid cursor configuratoins.
-typedef struct cursor_info {
- // The width and height of the cursor configuration, in pixels.
- uint32_t width;
- uint32_t height;
- zx_pixel_format_t format;
-} cursor_info_t;
-
-// a structure containing information a connected display
-typedef struct added_display_args {
- uint64_t display_id;
-
- // A flag indicating whether or not the display has a valid edid.
- //
- // If true, the device should expose an ZX_PROTOCOL_I2C_IMPL device through get_protocol, in
- // addition to the ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL protocol. Note that the i2c device
- // will be called from the on_displays_changed callback, so care should be taken to avoid
- // deadlocks or double-locking.
- //
- // If no edid is present, then the meaning of display_config's mode structure is
- // undefined, and drivers should ignore it in check_configuration and apply_configuration.
- bool edid_present;
- union {
- // the bus_id to use to read this display's edid from the device's i2c protocol
- uint32_t i2c_bus_id;
- // the display's parameters if an edid is not present
- display_params_t params;
- } panel;
-
- // A list of pixel formats supported by the display. The first entry is the
- // preferred pixel format.
- const zx_pixel_format_t* pixel_formats;
- uint32_t pixel_format_count;
-
- // A list of cursor configurations most likely to be accepted by the driver. Can
- // be null if cursor_count is 0.
- //
- // The driver may reject some of these configurations in some circumstances, and
- // it may accept other configurations, but at least one of these configurations
- // should be valid at most times.
- const cursor_info_t* cursor_infos;
- uint32_t cursor_info_count;
-
- // Out parameters will be populated before on_displays_changed returns.
- bool is_hdmi_out;
- bool is_standard_srgb_out;
-
- uint32_t audio_format_count;
-
- const char* manufacturer_name;
- char monitor_name[14]; // null-terminated
- char monitor_serial[14]; // null-terminated
-} added_display_args_t;
-
-// The client will not make any ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL calls into the device
-// during these callbacks.
-typedef struct display_controller_cb {
- // Callbacks which are invoked when displays are added or removed. |displays_added| and
- // |displays_removed| point to arrays of the display ids which were added and removed. If
- // |added_count| or |removed_count| is 0, the corresponding array can be NULL.
- //
- // The driver must be done accessing any images which were on the removed displays.
- //
- // The driver should call this function when the callback is registered if any displays
- // are present.
- void (*on_displays_changed)(void* ctx,
- added_display_args_t* added_displays, uint32_t added_count,
- uint64_t* removed_displays, uint32_t removed_count);
-
- // |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
- // |handles| points to an array of image handles of each framebuffer being
- // displayed, in increasing z-order.
- void (*on_display_vsync)(void* ctx, uint64_t display_id, zx_time_t timestamp,
- void** handles, uint32_t handle_count);
-
- zx_status_t (*get_audio_format)(void* ctx, uint64_t display_id, uint32_t fmt_idx,
- audio_stream_format_range_t* fmt_out);
-} display_controller_cb_t;
-
-#define ALPHA_DISABLE 0
-#define ALPHA_PREMULTIPLIED 1
-#define ALPHA_HW_MULTIPLY 2
-
-// Rotations are applied counter-clockwise, and are applied before reflections.
-#define FRAME_TRANSFORM_IDENTITY 0
-#define FRAME_TRANSFORM_REFLECT_X 1
-#define FRAME_TRANSFORM_REFLECT_Y 2
-#define FRAME_TRANSFORM_ROT_90 3
-#define FRAME_TRANSFORM_ROT_180 4
-#define FRAME_TRANSFORM_ROT_270 5
-#define FRAME_TRANSFORM_ROT_90_REFLECT_X 6
-#define FRAME_TRANSFORM_ROT_90_REFLECT_Y 7
-
-typedef struct frame {
- // (x_pos, y_pos) specifies the position of the upper-left corner
- // of the frame.
- uint32_t x_pos;
- uint32_t y_pos;
- uint32_t width;
- uint32_t height;
-} frame_t;
-
-typedef struct primary_layer {
- image_t image;
-
- // An ALPHA_* constant.
- //
- // If alpha_mode == ALPHA_DISABLED, the layer is opaque and alpha_layer_val is ignored.
- //
- // If alpha_mode == PREMULTIPLIED or HW_MULTIPLY and alpha_layer_val is NaN, the alpha
- // used when blending is determined by the per-pixel alpha channel.
- //
- // If alpha_mode == PREMULTIPLIED or HW_MULTIPLY and alpha_layer_val is not NaN, the
- // alpha used when blending is the product of alpha_layer_val and any per-pixel alpha.
- // Additionally, if alpha_mode == PREMULTIPLIED, then the hardware must premultiply the color
- // channel with alpha_layer_val before blending.
- //
- // If alpha_layer_val is not NaN, it will be in the range [0, 1].
- uint32_t alpha_mode;
- float alpha_layer_val;
-
- uint32_t transform_mode;
-
- // The source frame, where (0,0) is the top-left corner of the image. The
- // client guarantees that src_frame lies entirely within the image.
- frame_t src_frame;
-
- // The destination frame, where (0,0) is the top-left corner of the
- // composed output. The client guarantees that dest_frame lies entirely
- // within the composed output.
- frame_t dest_frame;
-} primary_layer_t;
-
-typedef struct cursor_layer {
- image_t image;
-
- // The position of the top-left corner of the cursor's image. When being
- // applied to a display, the cursor is guaranteed to have at least one
- // pixel of overlap with the display.
- int32_t x_pos;
- int32_t y_pos;
-} cursor_layer_t;
-
-typedef struct color_layer {
- zx_pixel_format_t format;
- // The color to use for the layer. The color is little-endian, and is
- // guaranteed to be of the appropriate size.
- uint8_t* color;
-} color_layer_t;
-
-// Types of layers.
-
-#define LAYER_PRIMARY 0
-#define LAYER_CURSOR 1
-#define LAYER_COLOR 2
-
-typedef struct layer {
- // One of the LAYER_* flags.
- uint32_t type;
- // z_index of the layer. See |check_configuration| and |apply_configuration|.
- uint32_t z_index;
- union {
- primary_layer_t primary;
- cursor_layer_t cursor;
- color_layer_t color;
- } cfg;
-} layer_t;
+typedef uint32_t color_conversion_t;
+// If set, use the 0 vector for the color conversion preoffset
+#define COLOR_CONVERSION_PREOFFSET UINT32_C(1)
+// If set, use the identity matrix for the color conversion coefficients
+#define COLOR_CONVERSION_COEFFICIENTS UINT32_C(2)
+// If set, use the 0 vector for the color conversion postoffset
+#define COLOR_CONVERSION_POSTOFFSET UINT32_C(4)
// constants for display_config's mode_flags field
-#define MODE_FLAG_VSYNC_POSITIVE (1 << 0)
-#define MODE_FLAG_HSYNC_POSITIVE (1 << 1)
-#define MODE_FLAG_INTERLACED (1 << 2)
-#define MODE_FLAG_ALTERNATING_VBLANK (1 << 3)
-#define MODE_FLAG_DOUBLE_CLOCKED (1 << 4)
+typedef uint32_t mode_flag_t;
+#define MODE_FLAG_VSYNC_POSITIVE UINT32_C(1)
+#define MODE_FLAG_HSYNC_POSITIVE UINT32_C(2)
+#define MODE_FLAG_INTERLACED UINT32_C(4)
+#define MODE_FLAG_ALTERNATING_VBLANK UINT32_C(8)
+#define MODE_FLAG_DOUBLE_CLOCKED UINT32_C(16)
+
+typedef struct display_mode display_mode_t;
+typedef struct display_config display_config_t;
+// Types of layers.
+typedef uint32_t layer_type_t;
+#define LAYER_TYPE_PRIMARY UINT32_C(0)
+#define LAYER_TYPE_CURSOR UINT32_C(1)
+#define LAYER_TYPE_COLOR UINT32_C(2)
+
+// Rotations are applied counter-clockwise, and are applied before reflections.
+typedef uint32_t frame_transform_t;
+#define FRAME_TRANSFORM_IDENTITY UINT32_C(0)
+#define FRAME_TRANSFORM_REFLECT_X UINT32_C(1)
+#define FRAME_TRANSFORM_REFLECT_Y UINT32_C(2)
+#define FRAME_TRANSFORM_ROT_90 UINT32_C(3)
+#define FRAME_TRANSFORM_ROT_180 UINT32_C(4)
+#define FRAME_TRANSFORM_ROT_270 UINT32_C(5)
+#define FRAME_TRANSFORM_ROT_90_REFLECT_X UINT32_C(6)
+#define FRAME_TRANSFORM_ROT_90_REFLECT_Y UINT32_C(7)
+
+typedef struct frame frame_t;
+typedef struct added_display_info added_display_info_t;
+typedef uint32_t zx_pixel_format_t;
+
+typedef struct cursor_info cursor_info_t;
+typedef struct color_layer color_layer_t;
+typedef struct image image_t;
+typedef struct cursor_layer cursor_layer_t;
+typedef uint8_t alpha_t;
+#define ALPHA_DISABLE UINT8_C(0)
+#define ALPHA_PREMULTIPLIED UINT8_C(1)
+#define ALPHA_HW_MULTIPLY UINT8_C(2)
+
+typedef struct primary_layer primary_layer_t;
+typedef union layer_config layer_config_t;
+typedef struct layer layer_t;
+typedef struct display_params display_params_t;
+typedef union panel panel_t;
+typedef struct added_display_args added_display_args_t;
+typedef struct display_controller_interface display_controller_interface_t;
+typedef struct display_controller_protocol display_controller_protocol_t;
+
+// Declarations
+
+// The image is linear and VMO backed.
+#define IMAGE_TYPE_SIMPLE UINT32_C(0)
+
+// A structure containing information about each plane of an image.
+struct image_plane {
+ uint32_t byte_offset;
+ uint32_t bytes_per_row;
+};
// The video parameters which specify the display mode.
-typedef struct display_mode {
+struct display_mode {
uint32_t pixel_clock_10khz;
uint32_t h_addressable;
uint32_t h_front_porch;
@@ -239,146 +131,312 @@
uint32_t v_front_porch;
uint32_t v_sync_pulse;
uint32_t v_blanking;
- uint32_t flags; // A bitmask of MODE_FLAG_* values
-} display_mode_t;
+ // A bitmask of MODE_FLAG_* values
+ uint32_t flags;
+};
-// If set, use the 0 vector for the color conversion preoffset
-#define COLOR_CONVERSION_PREOFFSET (1 << 0)
-// If set, use the identity matrix for the color conversion coefficients
-#define COLOR_CONVERSION_COEFFICIENTS (1 << 1)
-// If set, use the 0 vector for the color conversion postoffset
-#define COLOR_CONVERSION_POSTOFFSET (1 << 2)
-
-typedef struct display_config {
+struct display_config {
// the display id to which the configuration applies
uint64_t display_id;
-
display_mode_t mode;
-
// Bitmask of COLOR_CONVERSION_* flags
uint32_t cc_flags;
// Color conversion is applied to each pixel according to the formula:
- //
// (cc_coefficients * (pixel + cc_preoffsets)) + cc_postoffsets
- //
// where pixel is a column vector consiting of the pixel's 3 components.
float cc_preoffsets[3];
float cc_coefficients[3][3];
float cc_postoffsets[3];
+ layer_t** layer_list;
+ size_t layer_count;
+};
- uint32_t layer_count;
- layer_t** layers;
-} display_config_t;
+struct frame {
+ // (|x_pos|, |y_pos|) specifies the position of the upper-left corner
+ // of the frame.
+ uint32_t x_pos;
+ uint32_t y_pos;
+ uint32_t width;
+ uint32_t height;
+};
-// The display mode configuration is valid. Note that this is distinct from
-// whether or not the layer configuration is valid.
-#define CONFIG_DISPLAY_OK 0
-// Error indicating that the hardware cannot simultaniously support the
-// requested number of displays.
-#define CONFIG_DISPLAY_TOO_MANY 1
-// Error indicating that the hardware cannot simultaniously support the given
-// set of display modes. To support a mode, the display must be able to display
-// a single layer with width and height equal to the requested mode and the
-// preferred pixel format.
-#define CONFIG_DISPLAY_UNSUPPORTED_MODES 2
+// Out parameters will be populated before on_displays_changed returns.
+struct added_display_info {
+ bool is_hdmi_out;
+ bool is_standard_srgb_out;
+ uint32_t audio_format_count;
+ const char* manufacturer_name;
+ // null-terminated
+ char monitor_name[14];
+ // null-terminated
+ char monitor_serial[14];
+};
-// The client should convert the corresponding layer to a primary layer.
-#define CLIENT_USE_PRIMARY (1 << 0)
-// The client should compose all layers with MERGE_BASE and MERGE_SRC into a new,
-// single primary layer at the MERGE_BASE layer's z-order. The driver must accept
-// a fullscreen layer with the default pixel format, but may accept other layer
-// parameters.
-//
-// MERGE_BASE should only be set on one layer per display. If it is set on multiple
-// layers, the client will arbitrarily pick one and change the rest to MERGE_SRC.
-#define CLIENT_MERGE_BASE (1 << 1)
-#define CLIENT_MERGE_SRC (1 << 2)
-// The client should pre-scale the image so that src_frame's dimensions are equal
-// to dest_frame's dimensions.
-#define CLIENT_FRAME_SCALE (1 << 3)
-// The client should pre-clip the image so that src_frame's dimensions are equal to
-// the image's dimensions.
-#define CLIENT_SRC_FRAME (1 << 4)
-// The client should pre-apply the transformation so TRANSFORM_IDENTITY can be used.
-#define CLIENT_TRANSFORM (1 << 5)
-// The client should apply the color conversion.
-#define CLIENT_COLOR_CONVERSION (1 << 6)
-// The client should apply the alpha transformation itself.
-#define CLIENT_ALPHA (1 << 7)
+// Info about valid cursor configuratoins.
+struct cursor_info {
+ // The width and height of the cursor configuration, in pixels.
+ uint32_t width;
+ uint32_t height;
+ zx_pixel_format_t format;
+};
+
+struct color_layer {
+ zx_pixel_format_t format;
+ // The color to use for the layer. The color is little-endian, and is
+ // guaranteed to be of the appropriate size.
+ uint8_t* color_list;
+ size_t color_count;
+};
+
+// A structure containing information about an image.
+struct image {
+ // The width and height of the image in pixels.
+ uint32_t width;
+ uint32_t height;
+ // The pixel format of the image.
+ zx_pixel_format_t pixel_format;
+ // The type conveys information about what is providing the pixel data. If this is not
+ // IMAGE_FORMAT_SIMPLE, it is up to the driver and buffer producer to agree on the meaning
+ // of the value through some mechanism outside the scope of this API.
+ uint32_t type;
+ image_plane_t planes[4];
+ // A driver-defined handle to the image. Each handle must be unique.
+ uint64_t handle;
+};
+
+struct cursor_layer {
+ image_t image;
+ // The position of the top-left corner of the cursor's image. When being
+ // applied to a display, the cursor is guaranteed to have at least one
+ // pixel of overlap with the display.
+ zx_status_t x_pos;
+ zx_status_t y_pos;
+};
+
+#define INVALID_DISPLAY_ID UINT32_C(0)
+
+struct primary_layer {
+ image_t image;
+ // An ALPHA_* constant.
+ // If |alpha_mode| == `ALPHA_DISABLED`, the layer is opaque and alpha_layer_val is ignored.
+ // If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is NaN, the alpha
+ // used when blending is determined by the per-pixel alpha channel.
+ // If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is not NaN, the
+ // alpha used when blending is the product of alpha_layer_val and any per-pixel alpha.
+ // Additionally, if alpha_mode == PREMULTIPLIED, then the hardware must premultiply the color
+ // channel with alpha_layer_val before blending.
+ // If alpha_layer_val is not NaN, it will be in the range [0, 1].
+ alpha_t alpha_mode;
+ float alpha_layer_val;
+ frame_transform_t transform_mode;
+ // The source frame, where (0,0) is the top-left corner of the image. The
+ // client guarantees that src_frame lies entirely within the image.
+ frame_t src_frame;
+ // The destination frame, where (0,0) is the top-left corner of the
+ // composed output. The client guarantees that dest_frame lies entirely
+ // within the composed output.
+ frame_t dest_frame;
+};
+
+union layer_config {
+ primary_layer_t primary;
+ cursor_layer_t cursor;
+ color_layer_t color;
+};
+
+struct layer {
+ layer_type_t type;
+ // z_index of the layer. See |check_configuration| and |apply_configuration|.
+ uint32_t z_index;
+ layer_config_t cfg;
+};
+
+// A fallback structure to convey display information without an edid.
+struct display_params {
+ uint32_t width;
+ uint32_t height;
+ uint32_t refresh_rate_e2;
+};
+
+union panel {
+ // The bus_id to use to read this display's edid from the device's i2c protocol.
+ uint32_t i2c_bus_id;
+ // The display's parameters if an edid is not present.
+ display_params_t params;
+};
+
+// A structure containing information a connected display.
+struct added_display_args {
+ uint64_t display_id;
+ // A flag indicating whether or not the display has a valid edid.
+ // If true, the device should expose an ZX_PROTOCOL_I2C_IMPL device through get_protocol, in
+ // addition to the ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL protocol. Note that the i2c device
+ // will be called from the on_displays_changed callback, so care should be taken to avoid
+ // deadlocks or double-locking.
+ // If no edid is present, then the meaning of display_config's mode structure is
+ // undefined, and drivers should ignore it in check_configuration and apply_configuration.
+ bool edid_present;
+ panel_t panel;
+ // A list of pixel formats supported by the display. The first entry is the
+ // preferred pixel format.
+ zx_pixel_format_t* pixel_format_list;
+ size_t pixel_format_count;
+ // A list of cursor configurations most likely to be accepted by the driver. Can
+ // be null if cursor_count is 0.
+ // The driver may reject some of these configurations in some circumstances, and
+ // it may accept other configurations, but at least one of these configurations
+ // should be valid at most times.
+ cursor_info_t* cursor_info_list;
+ size_t cursor_info_count;
+};
+
+typedef struct display_controller_interface_ops {
+ void (*on_displays_changed)(void* ctx, const added_display_args_t* added_display_list,
+ size_t added_display_count, const uint64_t* removed_display_list,
+ size_t removed_display_count,
+ added_display_info_t* out_display_info_list,
+ size_t display_info_count, size_t* out_display_info_actual);
+ void (*on_display_vsync)(void* ctx, uint64_t display_id, int64_t timestamp,
+ const uint64_t* handle_list, size_t handle_count);
+ zx_status_t (*get_audio_format)(void* ctx, uint64_t display_id, uint32_t fmt_idx,
+ audio_stream_format_range_t* out_fmt);
+} display_controller_interface_ops_t;
+
+// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device
+// during these callbacks.
+struct display_controller_interface {
+ display_controller_interface_ops_t* ops;
+ void* ctx;
+};
+
+// Callbacks which are invoked when displays are added or removed. |added_display_list| and
+// |removed_display_list| point to arrays of the display ids which were added and removed. If
+// |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
+// The driver must be done accessing any images which were on the removed displays.
+// The driver should call this function when the callback is registered if any displays
+// are present.
+static inline void display_controller_interface_on_displays_changed(
+ const display_controller_interface_t* proto, const added_display_args_t* added_display_list,
+ size_t added_display_count, const uint64_t* removed_display_list, size_t removed_display_count,
+ added_display_info_t* out_display_info_list, size_t display_info_count,
+ size_t* out_display_info_actual) {
+ proto->ops->on_displays_changed(
+ proto->ctx, added_display_list, added_display_count, removed_display_list,
+ removed_display_count, out_display_info_list, display_info_count, out_display_info_actual);
+}
+// |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
+// |handles| points to an array of image handles of each framebuffer being
+// displayed, in increasing z-order.
+static inline void
+display_controller_interface_on_display_vsync(const display_controller_interface_t* proto,
+ uint64_t display_id, int64_t timestamp,
+ const uint64_t* handle_list, size_t handle_count) {
+ proto->ops->on_display_vsync(proto->ctx, display_id, timestamp, handle_list, handle_count);
+}
+static inline zx_status_t
+display_controller_interface_get_audio_format(const display_controller_interface_t* proto,
+ uint64_t display_id, uint32_t fmt_idx,
+ audio_stream_format_range_t* out_fmt) {
+ return proto->ops->get_audio_format(proto->ctx, display_id, fmt_idx, out_fmt);
+}
+
+typedef struct display_controller_protocol_ops {
+ void (*set_display_controller_interface)(void* ctx, const display_controller_interface_t* intf);
+ zx_status_t (*import_vmo_image)(void* ctx, image_t* image, zx_handle_t vmo, size_t offset);
+ void (*release_image)(void* ctx, image_t* image);
+ uint32_t (*check_configuration)(void* ctx, const display_config_t** display_config_list,
+ size_t display_config_count,
+ uint32_t** out_layer_cfg_result_list,
+ size_t* layer_cfg_result_count);
+ void (*apply_configuration)(void* ctx, const display_config_t** display_config_list,
+ size_t display_config_count);
+ uint32_t (*compute_linear_stride)(void* ctx, uint32_t width, zx_pixel_format_t pixel_format);
+ zx_status_t (*allocate_vmo)(void* ctx, uint64_t size, zx_handle_t* out_vmo);
+} display_controller_protocol_ops_t;
// The client guarantees that check_configuration and apply_configuration are always
// made from a single thread. The client makes no other threading guarantees.
-typedef struct display_controller_protocol_ops {
- // The function will only be called once, and it will be called before any other
- // functions are called.
- void (*set_display_controller_cb)(void* ctx, void* cb_ctx, display_controller_cb_t* cb);
-
- // Imports a VMO backed image into the driver. The driver should set image->handle. The
- // driver does not own the vmo handle passed to this function.
- zx_status_t (*import_vmo_image)(void* ctx, image_t* image,
- zx_handle_t vmo, size_t offset);
-
- // Releases any driver state associated with the given image. The client guarantees that
- // any images passed to apply_config will not be released until a vsync occurs with a
- // more recent image.
- void (*release_image)(void* ctx, image_t* image);
-
- // Validates the given configuration.
- //
- // The configuration may not include all displays. Omiteed displays should be treated as
- // whichever of off or displaying a blank screen results in a more premissive validation.
- //
- // All displays in a configuration will have at least one layer. The layers will be
- // arranged in increasing z-order, and their z_index fields will be set consecutively.
- //
- // Whether or not the driver can accept the configuration cannot depend on the
- // particular image handles, as it must always be possible to present a new image in
- // place of another image with a matching configuration. It also cannot depend on the
- // cursor position, as that can be updated without another call to check_configuration.
- //
- // display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
- // display modes is not supported.
- //
- // layer_cfg_result points to an array of arrays. The primary length is display_count, the
- // secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
- // is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
- // flag in the corresponding layer_cfg_result entry.
- //
- // The driver must not retain references to the configuration after this function returns.
- void (*check_configuration)(void* ctx, const display_config_t** display_config,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count);
-
- // Applies the configuration.
- //
- // All configurations passed to this function will be derived from configurations which
- // have been succesfully validated, with the only differences either being omitted layers
- // or different image handles. To account for any layers which are not present, the driver
- // must use the z_index values of the present layers to configure them as if the whole
- // configuration was present.
- //
- // Unlike with check_configuration, displays included in the configuration are not
- // guaranteed to include any layers. Both omitted displays and displays with no layers
- // can either be turned off or set to display a blank screen, but for displays with no
- // layers there is a strong preference to display a blank screen instead of turn them off.
- // In either case, the driver must drop all references to old images and invoke the vsync
- // callback after doing so.
- //
- // The driver must not retain references to the configuration after this function returns.
- void (*apply_configuration)(void* ctx,
- const display_config_t** display_configs, uint32_t display_count);
-
- // Computes the stride (in pixels) necessary for a linear image with the given width
- // and pixel format. Returns 0 on error.
- uint32_t (*compute_linear_stride)(void* ctx, uint32_t width, zx_pixel_format_t pixel_format);
-
- // Allocates a VMO of the requested size which can be used for images.
- // TODO: move this functionallity into a seperate video buffer management system.
- zx_status_t (*allocate_vmo)(void* ctx, uint64_t size, zx_handle_t* vmo_out);
-} display_controller_protocol_ops_t;
-
-typedef struct zx_display_controller_protocol {
+struct display_controller_protocol {
display_controller_protocol_ops_t* ops;
void* ctx;
-} display_controller_protocol_t;
+};
+
+// The function will only be called once, and it will be called before any other
+// functions are called.
+static inline void
+display_controller_set_display_controller_interface(const display_controller_protocol_t* proto,
+ const display_controller_interface_t* intf) {
+ proto->ops->set_display_controller_interface(proto->ctx, intf);
+}
+// Imports a VMO backed image into the driver. The driver should set image->handle. The
+// driver does not own the vmo handle passed to this function.
+static inline zx_status_t
+display_controller_import_vmo_image(const display_controller_protocol_t* proto, image_t* image,
+ zx_handle_t vmo, size_t offset) {
+ return proto->ops->import_vmo_image(proto->ctx, image, vmo, offset);
+}
+// Releases any driver state associated with the given image. The client guarantees that
+// any images passed to apply_config will not be released until a vsync occurs with a
+// more recent image.
+static inline void display_controller_release_image(const display_controller_protocol_t* proto,
+ image_t* image) {
+ proto->ops->release_image(proto->ctx, image);
+}
+// Validates the given configuration.
+// The configuration may not include all displays. Omiteed displays should be treated as
+// whichever of off or displaying a blank screen results in a more premissive validation.
+// All displays in a configuration will have at least one layer. The layers will be
+// arranged in increasing z-order, and their z_index fields will be set consecutively.
+// Whether or not the driver can accept the configuration cannot depend on the
+// particular image handles, as it must always be possible to present a new image in
+// place of another image with a matching configuration. It also cannot depend on the
+// cursor position, as that can be updated without another call to check_configuration.
+// display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
+// display modes is not supported.
+// layer_cfg_result points to an array of arrays. The primary length is display_count, the
+// secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
+// is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
+// flag in the corresponding layer_cfg_result entry.
+// The driver must not retain references to the configuration after this function returns.
+// TODO: Fix me...
+static inline uint32_t display_controller_check_configuration(
+ const display_controller_protocol_t* proto, const display_config_t** display_config_list,
+ size_t display_config_count, uint32_t** out_layer_cfg_result_list,
+ size_t* layer_cfg_result_count) {
+ return proto->ops->check_configuration(proto->ctx, display_config_list, display_config_count,
+ out_layer_cfg_result_list, layer_cfg_result_count);
+}
+// Applies the configuration.
+// All configurations passed to this function will be derived from configurations which
+// have been succesfully validated, with the only differences either being omitted layers
+// or different image handles. To account for any layers which are not present, the driver
+// must use the z_index values of the present layers to configure them as if the whole
+// configuration was present.
+// Unlike with check_configuration, displays included in the configuration are not
+// guaranteed to include any layers. Both omitted displays and displays with no layers
+// can either be turned off or set to display a blank screen, but for displays with no
+// layers there is a strong preference to display a blank screen instead of turn them off.
+// In either case, the driver must drop all references to old images and invoke the vsync
+// callback after doing so.
+// The driver must not retain references to the configuration after this function returns.
+static inline void
+display_controller_apply_configuration(const display_controller_protocol_t* proto,
+ const display_config_t** display_config_list,
+ size_t display_config_count) {
+ proto->ops->apply_configuration(proto->ctx, display_config_list, display_config_count);
+}
+// Computes the stride (in pixels) necessary for a linear image with the given width
+// and pixel format. Returns 0 on error.
+static inline uint32_t
+display_controller_compute_linear_stride(const display_controller_protocol_t* proto, uint32_t width,
+ zx_pixel_format_t pixel_format) {
+ return proto->ops->compute_linear_stride(proto->ctx, width, pixel_format);
+}
+// Allocates a VMO of the requested size which can be used for images.
+static inline zx_status_t
+display_controller_allocate_vmo(const display_controller_protocol_t* proto, uint64_t size,
+ zx_handle_t* out_vmo) {
+ return proto->ops->allocate_vmo(proto->ctx, size, out_vmo);
+}
+
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/ethernet.h b/system/ulib/ddk/include/ddk/protocol/ethernet.h
index 20d3358..bcbeddc 100644
--- a/system/ulib/ddk/include/ddk/protocol/ethernet.h
+++ b/system/ulib/ddk/include/ddk/protocol/ethernet.h
@@ -1,154 +1,193 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
-#include <zircon/device/ethernet.h>
#include <zircon/listnode.h>
#include <zircon/types.h>
__BEGIN_CDECLS;
-#define ETH_MAC_SIZE (6) // bytes
-#define ETH_MTU_SIZE (1500) // bytes
-#define ETH_FRAME_MAX_HDR_SIZE (18) // bytes. MAC Dest(6) + MAC Src(6) + 802.1Q tag(4) + Ethertype(2)
-#define ETH_FRAME_MAX_SIZE (ETH_MTU_SIZE + ETH_FRAME_MAX_HDR_SIZE)
+// Forward declarations
+typedef union internal internal_t;
// The ethermac interface supports both synchronous and asynchronous transmissions using the
// proto->queue_tx() and ifc->complete_tx() methods.
-//
// Receive operations are supported with the ifc->recv() interface.
-// TODO: implement netbuf-based receive operations by implementing proto->queue_rx() and
-// ifc->complete_rx()
-//
// The FEATURE_WLAN flag indicates a device that supports wlan operations.
-//
// The FEATURE_SYNTH flag indicates a device that is not backed by hardware.
-//
// The FEATURE_DMA flag indicates that the device can copy the buffer data using DMA and will ensure
// that physical addresses are provided in netbufs.
+typedef uint32_t ethmac_feature_t;
+#define ETHMAC_FEATURE_WLAN UINT32_C(1)
+#define ETHMAC_FEATURE_SYNTH UINT32_C(2)
+#define ETHMAC_FEATURE_DMA UINT32_C(4)
-#define ETHMAC_FEATURE_WLAN (1u)
-#define ETHMAC_FEATURE_SYNTH (2u)
-#define ETHMAC_FEATURE_DMA (4u)
+typedef struct ethmac_info ethmac_info_t;
+typedef struct ethmac_netbuf ethmac_netbuf_t;
+typedef struct ethmac_ifc ethmac_ifc_t;
+typedef struct ethmac_protocol ethmac_protocol_t;
-typedef struct ethmac_info {
- uint32_t features;
- uint32_t mtu;
- uint8_t mac[ETH_MAC_SIZE];
- uint8_t reserved0[2];
- uint32_t reserved1[4];
-} ethmac_info_t;
+// Declarations
-typedef struct ethmac_netbuf {
- // Provided by the generic ethernet driver
- void* data;
- zx_paddr_t phys; // Only used if ETHMAC_FEATURE_DMA is available
- uint16_t len;
- uint16_t reserved;
- uint32_t flags;
+union internal {
+ uint64_t val;
+ void* ptr_buffer;
+ size_t ptr_size;
+};
- // Shared between the generic ethernet and ethmac drivers
- list_node_t node;
-
- // For use by the ethmac driver
- union {
- uint64_t val;
- void* ptr;
- };
-} ethmac_netbuf_t;
-
-typedef struct ethmac_ifc_virt {
- void (*status)(void* cookie, uint32_t status);
-
- void (*recv)(void* cookie, void* data, size_t length, uint32_t flags);
-
- // complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
- // Return status indicates queue state:
- // ZX_OK: Packet has been enqueued.
- // Other: Packet could not be enqueued.
- // Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
- // the completion state of the transmission itself.
- void (*complete_tx)(void* cookie, ethmac_netbuf_t* netbuf, zx_status_t status);
-} ethmac_ifc_t;
-
-// Indicates that additional data is available to be sent after this call finishes. Allows a ethmac
-// driver to batch tx to hardware if possible.
-#define ETHMAC_TX_OPT_MORE (1u)
-
-// SETPARAM_ values identify the parameter to set. Each call to set_param()
-// takes an int32_t |value| and void* |data| which have meaning specific to
-// the parameter being set.
-
-// |value| is bool. |data| is unused.
-#define ETHMAC_SETPARAM_PROMISC (1u)
-
-// |value| is bool. |data| is unused.
-#define ETHMAC_SETPARAM_MULTICAST_PROMISC (2u)
-
-#define ETHMAC_MULTICAST_FILTER_OVERFLOW -1
+#define ETHMAC_SETPARAM_DUMP_REGS UINT32_C(4)
// |value| is number of addresses, or ETHMAC_MULTICAST_FILTER_OVERFLOW for "too many to count."
// |data| is |value|*6 bytes of MAC addresses. Caller retains ownership.
// If |value| is _OVERFLOW, |data| is ignored.
-#define ETHMAC_SETPARAM_MULTICAST_FILTER (3u)
+#define ETHMAC_SETPARAM_MULTICAST_FILTER UINT32_C(3)
-#define ETHMAC_SETPARAM_DUMP_REGS (4u)
+#define ETHMAC_MULTICAST_FILTER_OVERFLOW INT32_C(-1)
+
+// |value| is bool. |data| is unused.
+#define ETHMAC_SETPARAM_MULTICAST_PROMISC UINT32_C(2)
+
+// Indicates that additional data is available to be sent after this call finishes. Allows a ethmac
+// driver to batch tx to hardware if possible.
+#define ETHMAC_TX_OPT_MORE UINT32_C(1)
+
+struct ethmac_info {
+ uint32_t features;
+ uint32_t mtu;
+ uint8_t mac[6];
+ uint8_t reserved0[2];
+ uint32_t reserved1[4];
+};
+
+// SETPARAM_ values identify the parameter to set. Each call to set_param()
+// takes an int32_t |value| and void* |data| which have meaning specific to
+// the parameter being set.
+// |value| is bool. |data| is unused.
+#define ETHMAC_SETPARAM_PROMISC UINT32_C(1)
+
+#define ETH_FRAME_MAX_SIZE UINT32_C(1518)
+
+#define ETH_FRAME_MAX_HDR_SIZE UINT32_C(18)
+
+#define ETH_MTU_SIZE UINT32_C(1500)
+
+#define ETH_MAC_SIZE UINT32_C(6)
+
+struct ethmac_netbuf {
+ // Provided by the generic ethernet driver.
+ void* data_buffer;
+ size_t data_size;
+ // Only used if ETHMAC_FEATURE_DMA is available.
+ uint64_t phys;
+ uint16_t reserved;
+ uint32_t flags;
+ // Shared between the generic ethernet and ethmac drivers.
+ list_node_t node;
+ // For use by the ethmac driver.
+ internal_t u;
+};
+
+typedef struct ethmac_ifc_ops {
+ void (*status)(void* ctx, uint32_t status);
+ void (*recv)(void* ctx, const void* data_buffer, size_t data_size, uint32_t flags);
+ void (*complete_tx)(void* ctx, ethmac_netbuf_t* netbuf, zx_status_t status);
+} ethmac_ifc_ops_t;
+
+struct ethmac_ifc {
+ ethmac_ifc_ops_t* ops;
+ void* ctx;
+};
+
+static inline void ethmac_ifc_status(const ethmac_ifc_t* proto, uint32_t status) {
+ proto->ops->status(proto->ctx, status);
+}
+static inline void ethmac_ifc_recv(const ethmac_ifc_t* proto, const void* data_buffer,
+ size_t data_size, uint32_t flags) {
+ proto->ops->recv(proto->ctx, data_buffer, data_size, flags);
+}
+// complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
+// Return status indicates queue state:
+// ZX_OK: Packet has been enqueued.
+// Other: Packet could not be enqueued.
+// Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
+// the completion state of the transmission itself.
+static inline void ethmac_ifc_complete_tx(const ethmac_ifc_t* proto, ethmac_netbuf_t* netbuf,
+ zx_status_t status) {
+ proto->ops->complete_tx(proto->ctx, netbuf, status);
+}
+
+typedef struct ethmac_protocol_ops {
+ zx_status_t (*query)(void* ctx, uint32_t options, ethmac_info_t* out_info);
+ void (*stop)(void* ctx);
+ zx_status_t (*start)(void* ctx, const ethmac_ifc_t* ifc);
+ zx_status_t (*queue_tx)(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf);
+ zx_status_t (*set_param)(void* ctx, uint32_t param, zx_status_t value, const void* data_buffer,
+ size_t data_size);
+ zx_handle_t (*get_bti)(void* ctx);
+} ethmac_protocol_ops_t;
// The ethernet midlayer will never call ethermac_protocol
// methods from multiple threads simultaneously, but it
// can call send() methods at the same time as non-send
// methods.
-typedef struct ethmac_protocol_ops {
- // Obtain information about the ethermac device and supported features
- // Safe to call at any time.
- zx_status_t (*query)(void* ctx, uint32_t options, ethmac_info_t* info);
-
- // Shut down a running ethermac
- // Safe to call if the ethermac is already stopped.
- void (*stop)(void* ctx);
-
- // Start ethermac running with ifc_virt
- // Callbacks on ifc may be invoked from now until stop() is called
- zx_status_t (*start)(void* ctx, ethmac_ifc_t* ifc, void* cookie);
-
- // Request transmission of the packet in netbuf. Return status indicates queue state:
- // ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
- // ZX_OK: Packet has been enqueued.
- // Other: Packet could not be enqueued.
- //
- // In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
- // to return it once the enqueue is complete. complete_tx() may be used to return the packet
- // before transmission itself completes, but MUST NOT be called from within the queue_tx()
- // implementation.
- //
- // queue_tx() may be called at any time after start() is called including from multiple threads
- // simultaneously.
- zx_status_t (*queue_tx)(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf);
-
- // Request a settings change for the driver. Return status indicates disposition:
- // ZX_OK: Request has been handled.
- // ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
- // Other: Error trying to support this request.
- //
- // |value| and |data| usage are defined for each |param|; see comments above.
- //
- // set_param() may be called at any time after start() is called including from multiple threads
- // simultaneously.
- zx_status_t (*set_param)(void* ctx, uint32_t param, int32_t value, void* data);
-
- // Get the BTI handle (needed to pin DMA memory) for this device.
- // This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
- // The caller does *not* take ownership of the BTI handle and must never close
- // the handle.
- zx_handle_t (*get_bti)(void* ctx);
-} ethmac_protocol_ops_t;
-
-typedef struct ethmac_protocol {
+struct ethmac_protocol {
ethmac_protocol_ops_t* ops;
void* ctx;
-} ethmac_protocol_t;
+};
+
+// Obtain information about the ethermac device and supported features
+// Safe to call at any time.
+static inline zx_status_t ethmac_query(const ethmac_protocol_t* proto, uint32_t options,
+ ethmac_info_t* out_info) {
+ return proto->ops->query(proto->ctx, options, out_info);
+}
+// Shut down a running ethermac
+// Safe to call if the ethermac is already stopped.
+static inline void ethmac_stop(const ethmac_protocol_t* proto) {
+ proto->ops->stop(proto->ctx);
+}
+// Start ethermac running with ifc_virt
+// Callbacks on ifc may be invoked from now until stop() is called
+static inline zx_status_t ethmac_start(const ethmac_protocol_t* proto, const ethmac_ifc_t* ifc) {
+ return proto->ops->start(proto->ctx, ifc);
+}
+// Request transmission of the packet in netbuf. Return status indicates queue state:
+// ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
+// ZX_OK: Packet has been enqueued.
+// Other: Packet could not be enqueued.
+// In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
+// to return it once the enqueue is complete. complete_tx() may be used to return the packet
+// before transmission itself completes, but MUST NOT be called from within the queue_tx()
+// implementation.
+// queue_tx() may be called at any time after start() is called including from multiple threads
+// simultaneously.
+static inline zx_status_t ethmac_queue_tx(const ethmac_protocol_t* proto, uint32_t options,
+ ethmac_netbuf_t* netbuf) {
+ return proto->ops->queue_tx(proto->ctx, options, netbuf);
+}
+// Request a settings change for the driver. Return status indicates disposition:
+// ZX_OK: Request has been handled.
+// ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
+// Other: Error trying to support this request.
+// |value| and |data| usage are defined for each |param|; see comments above.
+// set_param() may be called at any time after start() is called including from multiple threads
+// simultaneously.
+static inline zx_status_t ethmac_set_param(const ethmac_protocol_t* proto, uint32_t param,
+ zx_status_t value, const void* data_buffer,
+ size_t data_size) {
+ return proto->ops->set_param(proto->ctx, param, value, data_buffer, data_size);
+}
+// Get the BTI handle (needed to pin DMA memory) for this device.
+// This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
+// The caller does *not* take ownership of the BTI handle and must never close
+// the handle.
+static inline zx_handle_t ethmac_get_bti(const ethmac_protocol_t* proto) {
+ return proto->ops->get_bti(proto->ctx);
+}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/gpio.h b/system/ulib/ddk/include/ddk/protocol/gpio.h
index b50f6ed..8d15afa 100644
--- a/system/ulib/ddk/include/ddk/protocol/gpio.h
+++ b/system/ulib/ddk/include/ddk/protocol/gpio.h
@@ -1,7 +1,9 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,81 +11,84 @@
__BEGIN_CDECLS;
-// flags for gpio_config_in()
-#define GPIO_PULL_DOWN (0 << 0)
-#define GPIO_PULL_UP (1 << 0)
-#define GPIO_NO_PULL (2 << 0)
-#define GPIO_PULL_MASK (3 << 0)
+// Forward declarations
-// Values for gpio_set_polarity()
-#define GPIO_POLARITY_LOW 0
-#define GPIO_POLARITY_HIGH 1
+// Values for `SetPolarity`.
+typedef uint32_t gpio_polarity_t;
+#define GPIO_POLARITY_LOW UINT32_C(0)
+#define GPIO_POLARITY_HIGH UINT32_C(1)
-// In the functions below, the GPIO index is relative to the list of GPIOs for the device.
-// For example, the list of GPIOs a platform device has access to would likely be a small
-// subset of the total number of GPIOs, while a platform bus implementation driver would
-// have access to the complete set of GPIOs.
+typedef struct gpio_protocol gpio_protocol_t;
-typedef struct {
+// Declarations
+
+// Flags for `ConfigIn`.
+#define GPIO_PULL_DOWN UINT32_C(0x0)
+
+#define GPIO_PULL_UP UINT32_C(0x10)
+
+#define GPIO_PULL_MASK UINT32_C(0x30)
+
+#define GPIO_NO_PULL UINT32_C(0x20)
+
+typedef struct gpio_protocol_ops {
zx_status_t (*config_in)(void* ctx, uint32_t index, uint32_t flags);
zx_status_t (*config_out)(void* ctx, uint32_t index, uint8_t initial_value);
zx_status_t (*set_alt_function)(void* ctx, uint32_t index, uint64_t function);
zx_status_t (*read)(void* ctx, uint32_t index, uint8_t* out_value);
zx_status_t (*write)(void* ctx, uint32_t index, uint8_t value);
- zx_status_t (*get_interrupt)(void* ctx, uint32_t pin, uint32_t flags, zx_handle_t* out_handle);
- zx_status_t (*release_interrupt)(void* ctx, uint32_t pin);
- zx_status_t (*set_polarity)(void* ctx, uint32_t pin, uint32_t polarity);
+ zx_status_t (*get_interrupt)(void* ctx, uint32_t index, uint32_t flags, zx_handle_t* out_irq);
+ zx_status_t (*release_interrupt)(void* ctx, uint32_t index);
+ zx_status_t (*set_polarity)(void* ctx, uint32_t index, gpio_polarity_t polarity);
} gpio_protocol_ops_t;
-typedef struct {
+// In the functions below, the GPIO index is relative to the list of GPIOs for the device.
+// For example, the list of GPIOs a platform device has access to would likely be a small
+// subset of the total number of GPIOs, while a platform bus implementation driver would
+// have access to the complete set of GPIOs.
+struct gpio_protocol {
gpio_protocol_ops_t* ops;
void* ctx;
-} gpio_protocol_t;
+};
-// configures a GPIO for input
-static inline zx_status_t gpio_config_in(const gpio_protocol_t* gpio, uint32_t index,
+// Configures a GPIO for input.
+static inline zx_status_t gpio_config_in(const gpio_protocol_t* proto, uint32_t index,
uint32_t flags) {
- return gpio->ops->config_in(gpio->ctx, index, flags);
+ return proto->ops->config_in(proto->ctx, index, flags);
}
-
-// configures a GPIO for output
-static inline zx_status_t gpio_config_out(const gpio_protocol_t* gpio, uint32_t index,
+// Configures a GPIO for output.
+static inline zx_status_t gpio_config_out(const gpio_protocol_t* proto, uint32_t index,
uint8_t initial_value) {
- return gpio->ops->config_out(gpio->ctx, index, initial_value);
+ return proto->ops->config_out(proto->ctx, index, initial_value);
}
-
-// configures the GPIO pin for an alternate function (I2C, SPI, etc)
-// the interpretation of "function" is platform dependent
-static inline zx_status_t gpio_set_alt_function(const gpio_protocol_t* gpio, uint32_t index,
+// Configures the GPIO pin for an alternate function (I2C, SPI, etc)
+// the interpretation of "function" is platform dependent.
+static inline zx_status_t gpio_set_alt_function(const gpio_protocol_t* proto, uint32_t index,
uint64_t function) {
- return gpio->ops->set_alt_function(gpio->ctx, index, function);
+ return proto->ops->set_alt_function(proto->ctx, index, function);
}
-
-// reads the current value of a GPIO (0 or 1)
-static inline zx_status_t gpio_read(const gpio_protocol_t* gpio, uint32_t index,
+// Reads the current value of a GPIO (0 or 1).
+static inline zx_status_t gpio_read(const gpio_protocol_t* proto, uint32_t index,
uint8_t* out_value) {
- return gpio->ops->read(gpio->ctx, index, out_value);
+ return proto->ops->read(proto->ctx, index, out_value);
+}
+// Sets the current value of the GPIO (any non-zero value maps to 1).
+static inline zx_status_t gpio_write(const gpio_protocol_t* proto, uint32_t index, uint8_t value) {
+ return proto->ops->write(proto->ctx, index, value);
+}
+// Gets an interrupt object pertaining to a particular GPIO pin.
+static inline zx_status_t gpio_get_interrupt(const gpio_protocol_t* proto, uint32_t index,
+ uint32_t flags, zx_handle_t* out_irq) {
+ return proto->ops->get_interrupt(proto->ctx, index, flags, out_irq);
+}
+// Release the interrupt.
+static inline zx_status_t gpio_release_interrupt(const gpio_protocol_t* proto, uint32_t index) {
+ return proto->ops->release_interrupt(proto->ctx, index);
+}
+// Set GPIO polarity.
+static inline zx_status_t gpio_set_polarity(const gpio_protocol_t* proto, uint32_t index,
+ gpio_polarity_t polarity) {
+ return proto->ops->set_polarity(proto->ctx, index, polarity);
}
-// sets the current value of the GPIO (any non-zero value maps to 1)
-static inline zx_status_t gpio_write(const gpio_protocol_t* gpio, uint32_t index, uint8_t value) {
- return gpio->ops->write(gpio->ctx, index, value);
-}
-
-// gets an interrupt object pertaining to a particular GPIO pin
-static inline zx_status_t gpio_get_interrupt(const gpio_protocol_t* gpio, uint32_t index,
- uint32_t flags, zx_handle_t* out_handle) {
- return gpio->ops->get_interrupt(gpio->ctx, index, flags, out_handle);
-}
-
-// release the interrupt
-static inline zx_status_t gpio_release_interrupt(const gpio_protocol_t* gpio, uint32_t pin) {
- return gpio->ops->release_interrupt(gpio->ctx, pin);
-}
-
-// Set GPIO polarity
-static inline zx_status_t gpio_set_polarity(const gpio_protocol_t* gpio, uint32_t pin,
- uint32_t polarity) {
- return gpio->ops->set_polarity(gpio->ctx, pin, polarity);
-}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/hidbus.h b/system/ulib/ddk/include/ddk/protocol/hidbus.h
index d690b1a..909ed6d 100644
--- a/system/ulib/ddk/include/ddk/protocol/hidbus.h
+++ b/system/ulib/ddk/include/ddk/protocol/hidbus.h
@@ -1,7 +1,9 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,69 +11,126 @@
__BEGIN_CDECLS;
-enum {
- HID_DESC_TYPE_REPORT = 0x22,
-};
+// Forward declarations
-enum {
- HID_REPORT_TYPE_INPUT = 1,
- HID_REPORT_TYPE_OUTPUT = 2,
- HID_REPORT_TYPE_FEATURE = 3,
-};
+typedef uint8_t hid_device_class_t;
+#define HID_DEVICE_CLASS_OTHER UINT8_C(0)
+#define HID_DEVICE_CLASS_KBD UINT8_C(1)
+#define HID_DEVICE_CLASS_POINTER UINT8_C(2)
+#define HID_DEVICE_CLASS_KBD_POINTER UINT8_C(3)
+#define HID_DEVICE_CLASS_FIRST UINT8_C(0)
+#define HID_DEVICE_CLASS_LAST UINT8_C(3)
-enum {
- HID_PROTOCOL_BOOT = 0,
- HID_PROTOCOL_REPORT = 1,
-};
+typedef struct hid_info hid_info_t;
+typedef uint8_t hid_description_type_t;
+#define HID_DESCRIPTION_TYPE_REPORT UINT8_C(34)
-enum {
- HID_DEV_CLASS_OTHER = 0,
- HID_DEV_CLASS_KBD = 1,
- HID_DEV_CLASS_POINTER = 2,
- HID_DEV_CLASS_KBD_POINTER = 3,
+typedef uint8_t hid_report_type_t;
+#define HID_REPORT_TYPE_INPUT UINT8_C(1)
+#define HID_REPORT_TYPE_OUTPUT UINT8_C(2)
+#define HID_REPORT_TYPE_FEATURE UINT8_C(3)
- HID_DEV_CLASS_FIRST = HID_DEV_CLASS_OTHER,
- HID_DEV_CLASS_LAST = HID_DEV_CLASS_KBD_POINTER,
-};
+typedef struct hidbus_ifc hidbus_ifc_t;
+typedef uint8_t hid_protocol_t;
+#define HID_PROTOCOL_BOOT UINT8_C(0)
+#define HID_PROTOCOL_REPORT UINT8_C(0)
-typedef struct hid_info {
+typedef struct hidbus_protocol hidbus_protocol_t;
+
+// Declarations
+
+struct hid_info {
uint8_t dev_num;
- uint8_t dev_class;
+ hid_device_class_t device_class;
bool boot_device;
-} hid_info_t;
+};
-typedef struct hidbus_ifc {
- // Queues a report received by the hidbus device.
- void (*io_queue)(void* cookie, const uint8_t* buf, size_t len);
-} hidbus_ifc_t;
+typedef struct hidbus_ifc_ops {
+ void (*io_queue)(void* ctx, const void* buf_buffer, size_t buf_size);
+} hidbus_ifc_ops_t;
+
+struct hidbus_ifc {
+ hidbus_ifc_ops_t* ops;
+ void* ctx;
+};
+
+// Queues a report received by the hidbus device.
+static inline void hidbus_ifc_io_queue(const hidbus_ifc_t* proto, const void* buf_buffer,
+ size_t buf_size) {
+ proto->ops->io_queue(proto->ctx, buf_buffer, buf_size);
+}
typedef struct hidbus_protocol_ops {
- // Obtain information about the hidbus device and supported features.
- // Safe to call at any time.
- zx_status_t (*query)(void* ctx, uint32_t options, hid_info_t* info);
-
- // Start the hidbus device. The device may begin queueing hid reports via
- // ifc->io_queue before this function returns. It is an error to start an
- // already-started hidbus device.
- zx_status_t (*start)(void* ctx, hidbus_ifc_t* ifc, void* cookie);
-
- // Stop the hidbus device. Safe to call if the hidbus is already stopped.
+ zx_status_t (*query)(void* ctx, uint32_t options, hid_info_t* out_info);
+ zx_status_t (*start)(void* ctx, const hidbus_ifc_t* ifc);
void (*stop)(void* ctx);
-
- // HID operations. See Device Class Definition for HID for details.
- zx_status_t (*get_descriptor)(void* ctx, uint8_t desc_type, void** data, size_t* len);
- zx_status_t (*get_report)(void* ctx, uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
- size_t* out_len);
- zx_status_t (*set_report)(void* ctx, uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len);
- zx_status_t (*get_idle)(void* ctx, uint8_t rpt_id, uint8_t* duration);
+ zx_status_t (*get_descriptor)(void* ctx, hid_description_type_t desc_type,
+ void** out_data_buffer, size_t* data_size);
+ zx_status_t (*get_report)(void* ctx, hid_report_type_t rpt_type, uint8_t rpt_id,
+ void* out_data_buffer, size_t data_size, size_t* out_data_actual);
+ zx_status_t (*set_report)(void* ctx, hid_report_type_t rpt_type, uint8_t rpt_id,
+ const void* data_buffer, size_t data_size);
+ zx_status_t (*get_idle)(void* ctx, uint8_t rpt_id, uint8_t* out_duration);
zx_status_t (*set_idle)(void* ctx, uint8_t rpt_id, uint8_t duration);
- zx_status_t (*get_protocol)(void* ctx, uint8_t* protocol);
- zx_status_t (*set_protocol)(void* ctx, uint8_t protocol);
+ zx_status_t (*get_protocol)(void* ctx, hid_protocol_t* out_protocol);
+ zx_status_t (*set_protocol)(void* ctx, hid_protocol_t protocol);
} hidbus_protocol_ops_t;
-typedef struct hidbus_protocol {
+struct hidbus_protocol {
hidbus_protocol_ops_t* ops;
void* ctx;
-} hidbus_protocol_t;
+};
+
+// Obtain information about the hidbus device and supported features.
+// Safe to call at any time.
+static inline zx_status_t hidbus_query(const hidbus_protocol_t* proto, uint32_t options,
+ hid_info_t* out_info) {
+ return proto->ops->query(proto->ctx, options, out_info);
+}
+// Start the hidbus device. The device may begin queueing hid reports via
+// ifc->io_queue before this function returns. It is an error to start an
+// already-started hidbus device.
+static inline zx_status_t hidbus_start(const hidbus_protocol_t* proto, const hidbus_ifc_t* ifc) {
+ return proto->ops->start(proto->ctx, ifc);
+}
+// Stop the hidbus device. Safe to call if the hidbus is already stopped.
+static inline void hidbus_stop(const hidbus_protocol_t* proto) {
+ proto->ops->stop(proto->ctx);
+}
+// What are the ownership semantics with regards to the data buffer passed back?
+// is len an input and output parameter?
+static inline zx_status_t hidbus_get_descriptor(const hidbus_protocol_t* proto,
+ hid_description_type_t desc_type,
+ void** out_data_buffer, size_t* data_size) {
+ return proto->ops->get_descriptor(proto->ctx, desc_type, out_data_buffer, data_size);
+}
+static inline zx_status_t hidbus_get_report(const hidbus_protocol_t* proto,
+ hid_report_type_t rpt_type, uint8_t rpt_id,
+ void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual) {
+ return proto->ops->get_report(proto->ctx, rpt_type, rpt_id, out_data_buffer, data_size,
+ out_data_actual);
+}
+static inline zx_status_t hidbus_set_report(const hidbus_protocol_t* proto,
+ hid_report_type_t rpt_type, uint8_t rpt_id,
+ const void* data_buffer, size_t data_size) {
+ return proto->ops->set_report(proto->ctx, rpt_type, rpt_id, data_buffer, data_size);
+}
+static inline zx_status_t hidbus_get_idle(const hidbus_protocol_t* proto, uint8_t rpt_id,
+ uint8_t* out_duration) {
+ return proto->ops->get_idle(proto->ctx, rpt_id, out_duration);
+}
+static inline zx_status_t hidbus_set_idle(const hidbus_protocol_t* proto, uint8_t rpt_id,
+ uint8_t duration) {
+ return proto->ops->set_idle(proto->ctx, rpt_id, duration);
+}
+static inline zx_status_t hidbus_get_protocol(const hidbus_protocol_t* proto,
+ hid_protocol_t* out_protocol) {
+ return proto->ops->get_protocol(proto->ctx, out_protocol);
+}
+static inline zx_status_t hidbus_set_protocol(const hidbus_protocol_t* proto,
+ hid_protocol_t protocol) {
+ return proto->ops->set_protocol(proto->ctx, protocol);
+}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/intel-gpu-core.h b/system/ulib/ddk/include/ddk/protocol/intel-gpu-core.h
index 6cdd6e5..6a38a34 100644
--- a/system/ulib/ddk/include/ddk/protocol/intel-gpu-core.h
+++ b/system/ulib/ddk/include/ddk/protocol/intel-gpu-core.h
@@ -1,7 +1,9 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,59 +11,109 @@
__BEGIN_CDECLS;
-#define IMAGE_TYPE_X_TILED 1
-#define IMAGE_TYPE_Y_LEGACY_TILED 2
-#define IMAGE_TYPE_YF_TILED 3
+// Forward declarations
-typedef void (*zx_intel_gpu_core_interrupt_callback_t)(void* data,
- uint32_t master_interrupt_control);
+typedef struct zx_intel_gpu_core_interrupt zx_intel_gpu_core_interrupt_t;
+typedef struct zx_intel_gpu_core_protocol zx_intel_gpu_core_protocol_t;
+
+// Declarations
+
+#define IMAGE_TYPE_X_TILED UINT32_C(1)
+
+struct zx_intel_gpu_core_interrupt {
+ void (*callback)(void* ctx, uint32_t master_interrupt_control);
+ void* ctx;
+};
typedef struct zx_intel_gpu_core_protocol_ops {
- // Reads 16 bits from pci config space; returned in |value_out|.
- zx_status_t (*read_pci_config_16)(void* ctx, uint16_t addr, uint16_t* value_out);
-
- // Maps the given |pci_bar|; address returned in |addr_out|, size in bytes returned in
- // |size_out|.
- zx_status_t (*map_pci_mmio)(void* ctx, uint32_t pci_bar, void** addr_out, uint64_t* size_out);
-
- // Unmaps the given |pci_bar|.
+ zx_status_t (*read_pci_config16)(void* ctx, uint16_t addr, uint16_t* out_value);
+ zx_status_t (*map_pci_mmio)(void* ctx, uint32_t pci_bar, void** out_buf_buffer,
+ size_t* buf_size);
zx_status_t (*unmap_pci_mmio)(void* ctx, uint32_t pci_bar);
-
- // Returns a bus transaction initiator.
- zx_status_t (*get_pci_bti)(void* ctx, uint32_t index, zx_handle_t* bti_out);
-
- // Registers the given |callback| to be invoked with parameter |data| when an interrupt occurs
- // matching |interrupt_mask|.
+ zx_status_t (*get_pci_bti)(void* ctx, uint32_t index, zx_handle_t* out_bti);
zx_status_t (*register_interrupt_callback)(void* ctx,
- zx_intel_gpu_core_interrupt_callback_t callback,
- void* data, uint32_t interrupt_mask);
-
- // Un-registers a previously registered interrupt callback.
+ const zx_intel_gpu_core_interrupt_t* callback,
+ uint32_t interrupt_mask);
zx_status_t (*unregister_interrupt_callback)(void* ctx);
-
- // Returns the size of the GTT (global translation table) in bytes.
uint64_t (*gtt_get_size)(void* ctx);
-
- // Allocates a region of the GTT of the given |page_count|, returning the page-aligned virtual
- // address in |addr_out|.
- zx_status_t (*gtt_alloc)(void* ctx, uint64_t page_count, uint64_t* addr_out);
-
- // Frees the GTT allocation given by |addr|.
+ zx_status_t (*gtt_alloc)(void* ctx, uint64_t page_count, uint64_t* out_addr);
zx_status_t (*gtt_free)(void* ctx, uint64_t addr);
-
- // Clears the page table entries for the GTT allocation given by |addr|.
zx_status_t (*gtt_clear)(void* ctx, uint64_t addr);
-
- // Inserts page tables entries for the GTT allocation given by |addr| for the vmo represented by
- // handle |buffer|, at the given |page_offset| and |page_count|. Takes ownership of |buffer|.
zx_status_t (*gtt_insert)(void* ctx, uint64_t addr, zx_handle_t buffer, uint64_t page_offset,
uint64_t page_count);
-
} zx_intel_gpu_core_protocol_ops_t;
-typedef struct zx_intel_gpu_core_protocol {
+struct zx_intel_gpu_core_protocol {
zx_intel_gpu_core_protocol_ops_t* ops;
void* ctx;
-} zx_intel_gpu_core_protocol_t;
+};
+
+// Reads 16 bits from pci config space; returned in |value_out|.
+static inline zx_status_t
+zx_intel_gpu_core_read_pci_config16(const zx_intel_gpu_core_protocol_t* proto, uint16_t addr,
+ uint16_t* out_value) {
+ return proto->ops->read_pci_config16(proto->ctx, addr, out_value);
+}
+// Maps the given |pci_bar|; address returned in |addr_out|, size in bytes returned in
+// |size_out|.
+static inline zx_status_t zx_intel_gpu_core_map_pci_mmio(const zx_intel_gpu_core_protocol_t* proto,
+ uint32_t pci_bar, void** out_buf_buffer,
+ size_t* buf_size) {
+ return proto->ops->map_pci_mmio(proto->ctx, pci_bar, out_buf_buffer, buf_size);
+}
+// Unmaps the given |pci_bar|.
+static inline zx_status_t
+zx_intel_gpu_core_unmap_pci_mmio(const zx_intel_gpu_core_protocol_t* proto, uint32_t pci_bar) {
+ return proto->ops->unmap_pci_mmio(proto->ctx, pci_bar);
+}
+// Returns a bus transaction initiator.
+static inline zx_status_t zx_intel_gpu_core_get_pci_bti(const zx_intel_gpu_core_protocol_t* proto,
+ uint32_t index, zx_handle_t* out_bti) {
+ return proto->ops->get_pci_bti(proto->ctx, index, out_bti);
+}
+// Registers the given |callback| to be invoked with parameter |data| when an interrupt occurs
+// matching |interrupt_mask|.
+static inline zx_status_t
+zx_intel_gpu_core_register_interrupt_callback(const zx_intel_gpu_core_protocol_t* proto,
+ const zx_intel_gpu_core_interrupt_t* callback,
+ uint32_t interrupt_mask) {
+ return proto->ops->register_interrupt_callback(proto->ctx, callback, interrupt_mask);
+}
+// Un-registers a previously registered interrupt callback.
+static inline zx_status_t
+zx_intel_gpu_core_unregister_interrupt_callback(const zx_intel_gpu_core_protocol_t* proto) {
+ return proto->ops->unregister_interrupt_callback(proto->ctx);
+}
+// Returns the size of the GTT (global translation table) in bytes.
+static inline uint64_t zx_intel_gpu_core_gtt_get_size(const zx_intel_gpu_core_protocol_t* proto) {
+ return proto->ops->gtt_get_size(proto->ctx);
+}
+// Allocates a region of the GTT of the given |page_count|, returning the page-aligned virtual
+// address in |addr_out|.
+static inline zx_status_t zx_intel_gpu_core_gtt_alloc(const zx_intel_gpu_core_protocol_t* proto,
+ uint64_t page_count, uint64_t* out_addr) {
+ return proto->ops->gtt_alloc(proto->ctx, page_count, out_addr);
+}
+// Frees the GTT allocation given by |addr|.
+static inline zx_status_t zx_intel_gpu_core_gtt_free(const zx_intel_gpu_core_protocol_t* proto,
+ uint64_t addr) {
+ return proto->ops->gtt_free(proto->ctx, addr);
+}
+// Clears the page table entries for the GTT allocation given by |addr|.
+static inline zx_status_t zx_intel_gpu_core_gtt_clear(const zx_intel_gpu_core_protocol_t* proto,
+ uint64_t addr) {
+ return proto->ops->gtt_clear(proto->ctx, addr);
+}
+// Inserts page tables entries for the GTT allocation given by |addr| for the vmo represented by
+// handle |buffer|, at the given |page_offset| and |page_count|. Takes ownership of |buffer|.
+static inline zx_status_t zx_intel_gpu_core_gtt_insert(const zx_intel_gpu_core_protocol_t* proto,
+ uint64_t addr, zx_handle_t buffer,
+ uint64_t page_offset, uint64_t page_count) {
+ return proto->ops->gtt_insert(proto->ctx, addr, buffer, page_offset, page_count);
+}
+
+#define IMAGE_TYPE_YF_TILED UINT32_C(3)
+
+#define IMAGE_TYPE_Y_LEGACY_TILED UINT32_C(2)
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/intel-hda-codec.h b/system/ulib/ddk/include/ddk/protocol/intel-hda-codec.h
index d786a0d..6155275 100644
--- a/system/ulib/ddk/include/ddk/protocol/intel-hda-codec.h
+++ b/system/ulib/ddk/include/ddk/protocol/intel-hda-codec.h
@@ -1,7 +1,9 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
@@ -9,15 +11,25 @@
__BEGIN_CDECLS;
+// Forward declarations
+
+typedef struct ihda_codec_protocol ihda_codec_protocol_t;
+
+// Declarations
+
typedef struct ihda_codec_protocol_ops {
- // Fetch a zx_handle_t to a channel which can be used to communicate with the codec device.
- zx_status_t (*get_driver_channel)(void* ctx, zx_handle_t* channel_out);
+ zx_status_t (*get_driver_channel)(void* ctx, zx_handle_t* out_channel);
} ihda_codec_protocol_ops_t;
-typedef struct ihda_codec_protocol {
+struct ihda_codec_protocol {
ihda_codec_protocol_ops_t* ops;
void* ctx;
-} ihda_codec_protocol_t;
+};
+
+// Fetch a zx_handle_t to a channel which can be used to communicate with the codec device.
+static inline zx_status_t ihda_codec_get_driver_channel(const ihda_codec_protocol_t* proto,
+ zx_handle_t* out_channel) {
+ return proto->ops->get_driver_channel(proto->ctx, out_channel);
+}
__END_CDECLS;
-
diff --git a/system/ulib/ddk/include/ddk/protocol/intel-hda-dsp.h b/system/ulib/ddk/include/ddk/protocol/intel-hda-dsp.h
index 5793931..0fca5c8 100644
--- a/system/ulib/ddk/include/ddk/protocol/intel-hda-dsp.h
+++ b/system/ulib/ddk/include/ddk/protocol/intel-hda-dsp.h
@@ -2,81 +2,76 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
#include <zircon/types.h>
-#include <zircon/syscalls/pci.h>
__BEGIN_CDECLS;
-// Key to get NHLT metadata
-#define MD_KEY_NHLT 'NHLT'
+// Forward declarations
-typedef void (ihda_dsp_irq_callback_t)(void* cookie);
+typedef struct ihda_dsp_irq ihda_dsp_irq_t;
+typedef struct ihda_dsp_protocol ihda_dsp_protocol_t;
+
+// Declarations
+
+#define MD_KEY_NHLT "NHLT"
+
+struct ihda_dsp_irq {
+ void (*callback)(void* ctx);
+ void* ctx;
+};
typedef struct ihda_dsp_protocol_ops {
- // Fetch the parent HDA controller's PCI device info
- void (*get_dev_info)(void* ctx, zx_pcie_device_info_t* out_info);
-
- // Fetch a VMO that represents the BAR holding the Audio DSP registers.
+ void (*get_dev_info)(void* ctx, zx_pcie_device_info_t* out_out);
zx_status_t (*get_mmio)(void* ctx, zx_handle_t* out_vmo, size_t* out_size);
-
- // Fetch a handle to our bus transaction initiator.
- zx_status_t (*get_bti)(void* ctx, zx_handle_t* out_handle);
-
- // Enables DSP
+ zx_status_t (*get_bti)(void* ctx, zx_handle_t* out_bti);
void (*enable)(void* ctx);
-
- // Disable DSP
void (*disable)(void* ctx);
-
- // Enables DSP interrupts and set a callback to be invoked when an interrupt is
- // raised.
- // Returns ZX_ERR_ALREADY_EXISTS if a callback is already set.
- zx_status_t (*irq_enable)(void* ctx, ihda_dsp_irq_callback_t* callback, void* cookie);
-
- // Disable DSP interrupts and clears the callback.
+ zx_status_t (*irq_enable)(void* ctx, const ihda_dsp_irq_t* callback);
void (*irq_disable)(void* ctx);
} ihda_dsp_protocol_ops_t;
-typedef struct ihda_dsp_protocol {
+struct ihda_dsp_protocol {
ihda_dsp_protocol_ops_t* ops;
void* ctx;
-} ihda_dsp_protocol_t;
+};
-static inline void ihda_dsp_get_dev_info(const ihda_dsp_protocol_t* ihda_dsp,
- zx_pcie_device_info_t* out_info) {
- ihda_dsp->ops->get_dev_info(ihda_dsp->ctx, out_info);
+// Fetch the parent HDA controller's PCI device info.
+static inline void ihda_dsp_get_dev_info(const ihda_dsp_protocol_t* proto,
+ zx_pcie_device_info_t* out_out) {
+ proto->ops->get_dev_info(proto->ctx, out_out);
}
-
-static inline zx_status_t ihda_dsp_get_mmio(const ihda_dsp_protocol_t* ihda_dsp,
- zx_handle_t* out_vmo,
+// Fetch a VMO that represents the BAR holding the Audio DSP registers.
+static inline zx_status_t ihda_dsp_get_mmio(const ihda_dsp_protocol_t* proto, zx_handle_t* out_vmo,
size_t* out_size) {
- return ihda_dsp->ops->get_mmio(ihda_dsp->ctx, out_vmo, out_size);
+ return proto->ops->get_mmio(proto->ctx, out_vmo, out_size);
}
-
-static inline zx_status_t ihda_dsp_get_bti(const ihda_dsp_protocol_t* ihda_dsp,
- zx_handle_t* out_handle) {
- return ihda_dsp->ops->get_bti(ihda_dsp->ctx, out_handle);
+// Fetch a handle to our bus transaction initiator.
+static inline zx_status_t ihda_dsp_get_bti(const ihda_dsp_protocol_t* proto, zx_handle_t* out_bti) {
+ return proto->ops->get_bti(proto->ctx, out_bti);
}
-
-static inline void ihda_dsp_enable(const ihda_dsp_protocol_t* ihda_dsp) {
- return ihda_dsp->ops->enable(ihda_dsp->ctx);
+// Enables DSP
+static inline void ihda_dsp_enable(const ihda_dsp_protocol_t* proto) {
+ proto->ops->enable(proto->ctx);
}
-
-static inline void ihda_dsp_disable(const ihda_dsp_protocol_t* ihda_dsp) {
- return ihda_dsp->ops->disable(ihda_dsp->ctx);
+// Disable DSP
+static inline void ihda_dsp_disable(const ihda_dsp_protocol_t* proto) {
+ proto->ops->disable(proto->ctx);
}
-
-static inline zx_status_t ihda_dsp_irq_enable(const ihda_dsp_protocol_t* ihda_dsp,
- ihda_dsp_irq_callback_t* callback,
- void* cookie) {
- return ihda_dsp->ops->irq_enable(ihda_dsp->ctx, callback, cookie);
+// Enables DSP interrupts and set a callback to be invoked when an interrupt is
+// raised.
+// Returns `ZX_ERR_ALREADY_EXISTS` if a callback is already set.
+static inline zx_status_t ihda_dsp_irq_enable(const ihda_dsp_protocol_t* proto,
+ const ihda_dsp_irq_t* callback) {
+ return proto->ops->irq_enable(proto->ctx, callback);
}
-
-static inline void ihda_dsp_irq_disable(const ihda_dsp_protocol_t* ihda_dsp) {
- ihda_dsp->ops->irq_disable(ihda_dsp->ctx);
+// Disable DSP interrupts and clears the callback.
+static inline void ihda_dsp_irq_disable(const ihda_dsp_protocol_t* proto) {
+ proto->ops->irq_disable(proto->ctx);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/iommu.h b/system/ulib/ddk/include/ddk/protocol/iommu.h
index decb994..c9ab1f6 100644
--- a/system/ulib/ddk/include/ddk/protocol/iommu.h
+++ b/system/ulib/ddk/include/ddk/protocol/iommu.h
@@ -2,30 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
#include <zircon/types.h>
-#include <lib/sync/completion.h>
-
-#include <string.h>
__BEGIN_CDECLS;
-typedef struct {
+// Forward declarations
+
+typedef struct iommu_protocol iommu_protocol_t;
+
+// Declarations
+
+typedef struct iommu_protocol_ops {
zx_status_t (*get_bti)(void* ctx, uint32_t iommu_index, uint32_t bti_id,
zx_handle_t* out_handle);
} iommu_protocol_ops_t;
-typedef struct {
+struct iommu_protocol {
iommu_protocol_ops_t* ops;
void* ctx;
-} iommu_protocol_t;
+};
-// Returns a bus transaction initiator handle for the given index
-static inline zx_status_t iommu_get_bti(iommu_protocol_t* iommu, uint32_t iommu_index,
+static inline zx_status_t iommu_get_bti(const iommu_protocol_t* proto, uint32_t iommu_index,
uint32_t bti_id, zx_handle_t* out_handle) {
- return iommu->ops->get_bti(iommu->ctx, iommu_index, bti_id, out_handle);
+ return proto->ops->get_bti(proto->ctx, iommu_index, bti_id, out_handle);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/mailbox.h b/system/ulib/ddk/include/ddk/protocol/mailbox.h
index 445f7d4..12d61db 100644
--- a/system/ulib/ddk/include/ddk/protocol/mailbox.h
+++ b/system/ulib/ddk/include/ddk/protocol/mailbox.h
@@ -2,38 +2,49 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
#include <zircon/types.h>
__BEGIN_CDECLS;
-typedef struct {
- uint32_t cmd;
- uint32_t tx_size;
- void* tx_buf;
-} mailbox_data_buf_t;
-typedef struct {
- uint32_t mailbox;
- uint32_t rx_size;
- void * rx_buf;
-} mailbox_channel_t;
+// Forward declarations
-typedef struct {
- zx_status_t (*send_cmd)(void* ctx, mailbox_channel_t* channel,
- mailbox_data_buf_t* mdata);
+typedef struct mailbox_data_buf mailbox_data_buf_t;
+typedef struct mailbox_channel mailbox_channel_t;
+typedef struct mailbox_protocol mailbox_protocol_t;
+
+// Declarations
+
+struct mailbox_data_buf {
+ uint32_t cmd;
+ void* tx_buffer;
+ size_t tx_size;
+};
+
+struct mailbox_channel {
+ uint32_t mailbox;
+ void* rx_buffer;
+ size_t rx_size;
+};
+
+typedef struct mailbox_protocol_ops {
+ zx_status_t (*send_command)(void* ctx, const mailbox_channel_t* channel,
+ const mailbox_data_buf_t* mdata);
} mailbox_protocol_ops_t;
-typedef struct {
+struct mailbox_protocol {
mailbox_protocol_ops_t* ops;
void* ctx;
-} mailbox_protocol_t;
+};
-// sends a command via the mailbox
-static inline zx_status_t mailbox_send_cmd(mailbox_protocol_t* mailbox,
- mailbox_channel_t* channel,
- mailbox_data_buf_t* mdata) {
- return mailbox->ops->send_cmd(mailbox->ctx, channel, mdata);
+static inline zx_status_t mailbox_send_command(const mailbox_protocol_t* proto,
+ const mailbox_channel_t* channel,
+ const mailbox_data_buf_t* mdata) {
+ return proto->ops->send_command(proto->ctx, channel, mdata);
}
+
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/nand.h b/system/ulib/ddk/include/ddk/protocol/nand.h
index 227699d..bccb103 100644
--- a/system/ulib/ddk/include/ddk/protocol/nand.h
+++ b/system/ulib/ddk/include/ddk/protocol/nand.h
@@ -2,131 +2,152 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <assert.h>
-#include <stdint.h>
-
+#include <zircon/compiler.h>
#include <zircon/device/nand.h>
#include <zircon/types.h>
-// nand_op_t's are submitted for processing via the queue() method of the
-// nand_protocol. Once submitted, the contents of the nand_op_t may be modified
+__BEGIN_CDECLS;
+
+// Forward declarations
+
+// NandOperation's are submitted for processing via the queue() method of the
+// Nand Protocol. Once submitted, the contents of the NandOperation may be modified
// while it's being processed.
-//
// The completion_cb() must eventually be called upon success or failure and
// at that point the cookie field must contain whatever value was in it when
-// the nand_op_t was originally queued.
-//
+// the NandOperation was originally queued.
// Any mention of "in pages" in this file means nand pages, as reported by
// nand_info.page_size, as opposed to physical memory pages (RAM). That's true
// even for vmo-related values.
-//
// corrected_bit_flips are always related to nand_info.ecc_bits, so it is
// possible to obtain a value that is larger than what is being read (in the oob
// case). On the other hand, if errors cannot be corrected, the operation will
// fail, and corrected_bit_flips will be undefined.
-
// NOTE: The protocol can be extended with barriers to support controllers that
// may issue multiple simultaneous request to the IO chips.
+typedef uint32_t nand_op_t;
+#define NAND_OP_READ UINT32_C(1)
+#define NAND_OP_WRITE UINT32_C(2)
+#define NAND_OP_ERASE UINT32_C(3)
-#define NAND_OP_READ 0x00000001
-#define NAND_OP_WRITE 0x00000002
-#define NAND_OP_ERASE 0x00000003
+typedef struct nand_read_write nand_read_write_t;
+typedef struct nand_erase nand_erase_t;
+typedef union nand_operation nand_operation_t;
+typedef struct nand_protocol nand_protocol_t;
+typedef void (*nand_queue_callback)(void* ctx, zx_status_t s, nand_operation_t* op);
-typedef struct nand_op nand_op_t;
+// Declarations
-struct nand_op {
- union {
- // All Commands.
- uint32_t command; // Command.
+// A single operation can read or write an arbitrary number of pages,
+// including out of band (OOB) data for each page. If either regular
+// data or OOB is not required, the relevant VMO handle should be set to
+// ZX_HANDLE_INVALID.
+// Note that length dictates the number of pages to access, regardless
+// of the type of data requested: regular data, OOB or both.
+// The OOB data will be copied to (and from) a contiguous memory range
+// starting at the given offset. Note that said offset is given in nand
+// pages even though OOB is just a handful of bytes per page. In other
+// words, after said offset, the OOB data for each page is located
+// nand_info.oob_size bytes apart.
+// For example, to read 5 pages worth of data + OOB, with page size of
+// 2 kB and 16 bytes of OOB per page, setting:
+// data_vmo = oob_vmo = vmo_handle
+// length = 5
+// offset_nand = 20
+// offset_data_vmo = 0
+// offset_oob_vmo = 5
+// will transfer pages [20, 24] to the first 2048 * 5 bytes of the vmo,
+// followed by 16 * 5 bytes of OOB data starting at offset 2048 * 5.
+struct nand_read_write {
+ // Command.
+ nand_op_t command;
+ // vmo of data to read or write.
+ zx_handle_t data_vmo;
+ // vmo of OOB data to read or write.
+ zx_handle_t oob_vmo;
+ // Number of pages to access.
+ // (0 is invalid).
+ uint32_t length;
+ // Offset into nand, in pages.
+ uint32_t offset_nand;
+ // Data vmo offset in (nand) pages.
+ uint64_t offset_data_vmo;
+ // OOB vmo offset in (nand) pages.
+ uint64_t offset_oob_vmo;
+ // Optional physical page list.
+ uint64_t* page_list;
+ size_t page_count;
+ // Return value from READ_DATA, max corrected bit flips in any
+ // underlying ECC chunk read. The caller can compare this value
+ // against ecc_bits to decide whether the nand erase block needs to
+ // be recycled.
+ uint32_t corrected_bit_flips;
+};
- // NAND_OP_READ, NAND_OP_WRITE.
- //
- // A single operation can read or write an arbitrary number of pages,
- // including out of band (OOB) data for each page. If either regular
- // data or OOB is not required, the relevant VMO handle should be set to
- // ZX_HANDLE_INVALID.
- //
- // Note that length dictates the number of pages to access, regardless
- // of the type of data requested: regular data, OOB or both.
- //
- // The OOB data will be copied to (and from) a contiguous memory range
- // starting at the given offset. Note that said offset is given in nand
- // pages even though OOB is just a handful of bytes per page. In other
- // words, after said offset, the OOB data for each page is located
- // nand_info.oob_size bytes apart.
- //
- // For example, to read 5 pages worth of data + OOB, with page size of
- // 2 kB and 16 bytes of OOB per page, setting:
- //
- // data_vmo = oob_vmo = vmo_handle
- // length = 5
- // offset_nand = 20
- // offset_data_vmo = 0
- // offset_oob_vmo = 5
- //
- // will transfer pages [20, 24] to the first 2048 * 5 bytes of the vmo,
- // followed by 16 * 5 bytes of OOB data starting at offset 2048 * 5.
- //
- struct {
- uint32_t command; // Command.
- zx_handle_t data_vmo; // vmo of data to read or write.
- zx_handle_t oob_vmo; // vmo of OOB data to read or write.
- uint32_t length; // Number of pages to access.
- // (0 is invalid).
- uint32_t offset_nand; // Offset into nand, in pages.
- uint64_t offset_data_vmo; // Data vmo offset in (nand) pages.
- uint64_t offset_oob_vmo; // OOB vmo offset in (nand) pages.
- uint64_t* pages; // Optional physical page list.
- // Return value from READ_DATA, max corrected bit flips in any
- // underlying ECC chunk read. The caller can compare this value
- // against ecc_bits to decide whether the nand erase block needs to
- // be recycled.
- uint32_t corrected_bit_flips;
- } rw;
+struct nand_erase {
+ // Command.
+ nand_op_t command;
+ // Offset into nand, in erase blocks.
+ uint32_t first_block;
+ // Number of blocks to erase.
+ // (0 is invalid).
+ uint32_t num_blocks;
+};
- // NAND_OP_ERASE.
- struct {
- uint32_t command; // Command.
- uint32_t first_block; // Offset into nand, in erase blocks.
- uint32_t num_blocks; // Number of blocks to erase.
- // (0 is invalid).
- } erase;
- };
-
- // The completion_cb() will be called when the nand operation succeeds or
- // fails.
- void (*completion_cb)(nand_op_t* op, zx_status_t status);
-
- // This is a caller-owned field that is not modified by the driver stack.
- void *cookie;
+union nand_operation {
+ // All Commands.
+ nand_op_t command;
+ // NAND_OP_READ, NAND_OP_WRITE.
+ nand_read_write_t rw;
+ // NAND_OP_ERASE.
+ nand_erase_t erase;
};
typedef struct nand_protocol_ops {
- // Obtains the parameters of the nand device (nand_info_t) and the required
- // size of nand_op_t. The nand_op_t's submitted via queue() must have
- // nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
- // structure for the use of the driver.
- void (*query)(void* ctx, nand_info_t* info_out, size_t* nand_op_size_out);
-
- // Submits an IO request for processing. Success or failure will be reported
- // via the completion_cb() in the nand_op_t. The callback may be called
- // before the queue() method returns.
- void (*queue)(void* ctx, nand_op_t* op);
-
- // Gets the list of bad erase blocks, as reported by the nand manufacturer.
- // The caller must allocate a table large enough to hold the expected number
- // of entries, and pass the size of that table on |bad_block_len|.
- // On return, |num_bad_blocks| contains the number of bad blocks found.
- // This should only be called before writing any data to the nand, and the
- // returned data should be saved somewhere else, along blocks that become
- // bad after they've been in use.
- zx_status_t (*get_factory_bad_block_list)(void* ctx, uint32_t* bad_blocks,
- uint32_t bad_block_len, uint32_t* num_bad_blocks);
+ void (*query)(void* ctx, nand_info_t* out_info, size_t* out_nand_op_size);
+ void (*queue)(void* ctx, nand_operation_t* op, nand_queue_callback callback, void* cookie);
+ zx_status_t (*get_factory_bad_block_list)(void* ctx, uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual);
} nand_protocol_ops_t;
-typedef struct nand_protocol {
+struct nand_protocol {
nand_protocol_ops_t* ops;
void* ctx;
-} nand_protocol_t;
+};
+
+// Obtains the parameters of the nand device (nand_info_t) and the required
+// size of nand_op_t. The nand_op_t's submitted via queue() must have
+// nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
+// structure for the use of the driver.
+static inline void nand_query(const nand_protocol_t* proto, nand_info_t* out_info,
+ size_t* out_nand_op_size) {
+ proto->ops->query(proto->ctx, out_info, out_nand_op_size);
+}
+// Submits an IO request for processing. Success or failure will be reported
+// via the completion_cb() in the nand_op_t. The callback may be called
+// before the queue() method returns.
+static inline void nand_queue(const nand_protocol_t* proto, nand_operation_t* op,
+ nand_queue_callback callback, void* cookie) {
+ proto->ops->queue(proto->ctx, op, callback, cookie);
+}
+// Gets the list of bad erase blocks, as reported by the nand manufacturer.
+// The caller must allocate a table large enough to hold the expected number
+// of entries, and pass the size of that table on |bad_block_len|.
+// On return, |num_bad_blocks| contains the number of bad blocks found.
+// This should only be called before writing any data to the nand, and the
+// returned data should be saved somewhere else, along blocks that become
+// bad after they've been in use.
+static inline zx_status_t nand_get_factory_bad_block_list(const nand_protocol_t* proto,
+ uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual) {
+ return proto->ops->get_factory_bad_block_list(proto->ctx, out_bad_blocks_list, bad_blocks_count,
+ out_bad_blocks_actual);
+}
+
+__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/pci-lib.h b/system/ulib/ddk/include/ddk/protocol/pci-lib.h
new file mode 100644
index 0000000..7069ede
--- /dev/null
+++ b/system/ulib/ddk/include/ddk/protocol/pci-lib.h
@@ -0,0 +1,54 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <ddk/protocol/pci.h>
+
+__BEGIN_CDECLS;
+
+static inline zx_status_t pci_config_read8(const pci_protocol_t* pci,
+ uint16_t offset, uint8_t* value) {
+ uint32_t value_;
+ zx_status_t st = pci->ops->config_read(pci->ctx, offset, sizeof(uint8_t), &value_);
+ *value = value_ & UINT8_MAX;
+ return st;
+}
+
+static inline zx_status_t pci_config_read16(const pci_protocol_t* pci,
+ uint16_t offset, uint16_t* value) {
+ uint32_t value_;
+ zx_status_t st = pci->ops->config_read(pci->ctx, offset, sizeof(uint16_t), &value_);
+ *value = value_ & UINT16_MAX;
+ return st;
+}
+
+static inline zx_status_t pci_config_read32(const pci_protocol_t* pci,
+ uint16_t offset, uint32_t* value) {
+ return pci->ops->config_read(pci->ctx, offset, sizeof(uint32_t), value);
+}
+
+static inline zx_status_t pci_config_write8(const pci_protocol_t* pci,
+ uint16_t offset, uint8_t value) {
+ return pci->ops->config_write(pci->ctx, offset, sizeof(uint8_t), value);
+}
+
+static inline zx_status_t pci_config_write16(const pci_protocol_t* pci,
+ uint16_t offset, uint16_t value) {
+ return pci->ops->config_write(pci->ctx, offset, sizeof(uint16_t), value);
+}
+
+static inline zx_status_t pci_config_write32(const pci_protocol_t* pci,
+ uint16_t offset, uint32_t value) {
+ return pci->ops->config_write(pci->ctx, offset, sizeof(uint32_t), value);
+}
+
+static inline uint8_t pci_get_first_capability(const pci_protocol_t* pci, uint8_t type) {
+ // the next_capability method will always look at the second byte next
+ // pointer to fetch the next capability. By offsetting the CapPtr field
+ // by -1 we can pretend we're working with a normal capability entry
+ return pci_get_next_capability(pci, PCI_CFG_CAPABILITIES_PTR - 1u, type);
+}
+
+__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/pci.h b/system/ulib/ddk/include/ddk/protocol/pci.h
index 36dd50a..5f8c8c0 100644
--- a/system/ulib/ddk/include/ddk/protocol/pci.h
+++ b/system/ulib/ddk/include/ddk/protocol/pci.h
@@ -1,174 +1,127 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/protocol/auxdata.h>
-#include <hw/pci.h>
#include <zircon/compiler.h>
#include <zircon/syscalls/pci.h>
#include <zircon/types.h>
__BEGIN_CDECLS;
-/**
- * protocols/pci.h - PCI protocol definitions
- *
- * The PCI host driver publishes zx_device_t's with its config set to a pci_device_config_t.
- */
+// Forward declarations
-enum pci_header_fields {
- kPciCfgVendorId = 0x00,
- kPciCfgDeviceId = 0x02,
- kPciCfgRevisionId = 0x08,
- kPciCfgClassCode = 0x09,
- kPciCfgSubsystemVendorId = 0x2C,
- kPciCfgSubsystemId = 0x2E,
- kPciCfgCapabilitiesPtr = 0x34,
-};
+typedef struct pci_protocol pci_protocol_t;
+typedef uint16_t pci_cfg_t;
+#define PCI_CFG_VENDOR_ID UINT16_C(0)
+#define PCI_CFG_DEVICE_ID UINT16_C(2)
+#define PCI_CFG_REVISION_ID UINT16_C(8)
+#define PCI_CFG_CLASS_CODE UINT16_C(9)
+#define PCI_CFG_SUBSYSTEM_VENDOR_ID UINT16_C(44)
+#define PCI_CFG_SUBSYSTEM_ID UINT16_C(46)
+#define PCI_CFG_CAPABILITIES_PTR UINT16_C(52)
-enum pci_cap_types {
- kPciCapIdNull = 0x00,
- kPciCapIdPciPwrMgmt = 0x01,
- kPciCapIdAgp = 0x02,
- kPciCapIdVpd = 0x03,
- kPciCapIdMsi = 0x05,
- kPciCapIdPcix = 0x07,
- kPciCapIdHypertransport = 0x08,
- kPciCapIdVendor = 0x09,
- kPciCapIdDebugPort = 0x0A,
- kPciCapIdCompactPciCrc = 0x0B,
- kPciCapIdPciHotplug = 0x0C,
- kPciCapIdPciBridgeSubsystemVid = 0x0D,
- kPciCapIdAgp8x = 0x0E,
- kPciCapIdSecureDevice = 0x0F,
- kPciCapIdPciExpress = 0x10,
- kPciCapIdMsix = 0x11,
- kPciCapIdSataDataNdxCfg = 0x12,
- kPciCapIdAdvancedFeatures = 0x13,
- kPciCapIdEnhancedAllocation = 0x14,
-};
+typedef uint8_t pci_cap_id_t;
+#define PCI_CAP_ID_NULL UINT8_C(0)
+#define PCI_CAP_ID_PCI_PWR_MGMT UINT8_C(1)
+#define PCI_CAP_ID_AGP UINT8_C(2)
+#define PCI_CAP_ID_VPD UINT8_C(3)
+#define PCI_CAP_ID_MSI UINT8_C(5)
+#define PCI_CAP_ID_PCIX UINT8_C(7)
+#define PCI_CAP_ID_HYPERTRANSPORT UINT8_C(8)
+#define PCI_CAP_ID_VENDOR UINT8_C(9)
+#define PCI_CAP_ID_DEBUG_PORT UINT8_C(10)
+#define PCI_CAP_ID_COMPACT_PCI_CRC UINT8_C(11)
+#define PCI_CAP_ID_PCI_HOT_PLUG UINT8_C(12)
+#define PCI_CAP_ID_PCI_BRIDGE_SUBSYSTEM_VID UINT8_C(13)
+#define PCI_CAP_ID_AGP8X UINT8_C(14)
+#define PCI_CAP_ID_SECURE_DEVICE UINT8_C(15)
+#define PCI_CAP_ID_PCI_EXPRESS UINT8_C(16)
+#define PCI_CAP_ID_MSIX UINT8_C(17)
+#define PCI_CAP_ID_SATA_DATA_NDX_CFG UINT8_C(18)
+#define PCI_CAP_ID_ADVANCED_FEATURES UINT8_C(19)
+#define PCI_CAP_ID_ENHANCED_ALLOCATION UINT8_C(20)
+// Declarations
typedef struct pci_protocol_ops {
- zx_status_t (*get_bar)(void* ctx, uint32_t bar_id, zx_pci_bar_t* out_res);
+ zx_status_t (*get_bar)(void* ctx, uint32_t bar_id, zx_pci_bar_t* out_res);
zx_status_t (*map_bar)(void* ctx, uint32_t bar_id, uint32_t cache_policy,
- void** vaddr, size_t* size, zx_handle_t* out_handle);
+ void** out_vaddr_buffer, size_t* vaddr_size, zx_handle_t* out_handle);
zx_status_t (*enable_bus_master)(void* ctx, bool enable);
zx_status_t (*reset_device)(void* ctx);
- zx_status_t (*map_interrupt)(void* ctx, int which_irq, zx_handle_t* out_handle);
- zx_status_t (*query_irq_mode)(void* ctx, zx_pci_irq_mode_t mode,
- uint32_t* out_max_irqs);
- zx_status_t (*set_irq_mode)(void* ctx, zx_pci_irq_mode_t mode,
- uint32_t requested_irq_count);
- zx_status_t (*get_device_info)(void* ctx, zx_pcie_device_info_t* out_info);
- zx_status_t (*config_read)(void* ctx, uint16_t offset, size_t width, uint32_t* value);
+ zx_status_t (*map_interrupt)(void* ctx, zx_status_t which_irq, zx_handle_t* out_handle);
+ zx_status_t (*query_irq_mode)(void* ctx, zx_pci_irq_mode_t mode, uint32_t* out_max_irqs);
+ zx_status_t (*set_irq_mode)(void* ctx, zx_pci_irq_mode_t mode, uint32_t requested_irq_count);
+ zx_status_t (*get_device_info)(void* ctx, zx_pcie_device_info_t* out_into);
+ zx_status_t (*config_read)(void* ctx, uint16_t offset, size_t width, uint32_t* out_value);
zx_status_t (*config_write)(void* ctx, uint16_t offset, size_t width, uint32_t value);
- uint8_t (*get_next_capability)(void* ctx, uint8_t type, uint8_t offset);
- zx_status_t (*get_auxdata)(void* ctx, const char* args,
- void* data, uint32_t bytes, uint32_t* actual);
- zx_status_t (*get_bti)(void* ctx, uint32_t index, zx_handle_t* out_handle);
+ uint8_t (*get_next_capability)(void* ctx, uint8_t type, uint8_t offset);
+ zx_status_t (*get_auxdata)(void* ctx, const char* args, void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual);
+ zx_status_t (*get_bti)(void* ctx, uint32_t index, zx_handle_t* out_bti);
} pci_protocol_ops_t;
-typedef struct pci_protocol {
+
+struct pci_protocol {
pci_protocol_ops_t* ops;
void* ctx;
-} pci_protocol_t;
+};
-static inline zx_status_t pci_get_bar(const pci_protocol_t* pci, uint32_t res_id,
- zx_pci_bar_t* out_info) {
- return pci->ops->get_bar(pci->ctx, res_id, out_info);
+static inline zx_status_t pci_get_bar(const pci_protocol_t* proto, uint32_t bar_id,
+ zx_pci_bar_t* out_res) {
+ return proto->ops->get_bar(proto->ctx, bar_id, out_res);
}
-
-static inline zx_status_t pci_map_bar(const pci_protocol_t* pci, uint32_t bar_id,
- uint32_t cache_policy, void** vaddr, size_t* size,
- zx_handle_t* out_handle) {
- return pci->ops->map_bar(pci->ctx, bar_id, cache_policy, vaddr, size, out_handle);
+static inline zx_status_t pci_map_bar(const pci_protocol_t* proto, uint32_t bar_id,
+ uint32_t cache_policy, void** out_vaddr_buffer,
+ size_t* vaddr_size, zx_handle_t* out_handle) {
+ return proto->ops->map_bar(proto->ctx, bar_id, cache_policy, out_vaddr_buffer, vaddr_size,
+ out_handle);
}
-
-static inline zx_status_t pci_enable_bus_master(const pci_protocol_t* pci, bool enable) {
- return pci->ops->enable_bus_master(pci->ctx, enable);
+static inline zx_status_t pci_enable_bus_master(const pci_protocol_t* proto, bool enable) {
+ return proto->ops->enable_bus_master(proto->ctx, enable);
}
-
-static inline zx_status_t pci_get_bti(const pci_protocol_t* pci, uint32_t index, zx_handle_t* bti) {
- return pci->ops->get_bti(pci->ctx, index, bti);
+static inline zx_status_t pci_reset_device(const pci_protocol_t* proto) {
+ return proto->ops->reset_device(proto->ctx);
}
-
-static inline zx_status_t pci_reset_device(const pci_protocol_t* pci) {
- return pci->ops->reset_device(pci->ctx);
-}
-
-static inline zx_status_t pci_map_interrupt(const pci_protocol_t* pci, int which_irq,
+static inline zx_status_t pci_map_interrupt(const pci_protocol_t* proto, zx_status_t which_irq,
zx_handle_t* out_handle) {
- return pci->ops->map_interrupt(pci->ctx, which_irq, out_handle);
+ return proto->ops->map_interrupt(proto->ctx, which_irq, out_handle);
}
-
-static inline zx_status_t pci_query_irq_mode(const pci_protocol_t* pci, zx_pci_irq_mode_t mode,
+static inline zx_status_t pci_query_irq_mode(const pci_protocol_t* proto, zx_pci_irq_mode_t mode,
uint32_t* out_max_irqs) {
- return pci->ops->query_irq_mode(pci->ctx, mode, out_max_irqs);
+ return proto->ops->query_irq_mode(proto->ctx, mode, out_max_irqs);
}
-
-static inline zx_status_t pci_set_irq_mode(const pci_protocol_t* pci, zx_pci_irq_mode_t mode,
+static inline zx_status_t pci_set_irq_mode(const pci_protocol_t* proto, zx_pci_irq_mode_t mode,
uint32_t requested_irq_count) {
- return pci->ops->set_irq_mode(pci->ctx, mode, requested_irq_count);
+ return proto->ops->set_irq_mode(proto->ctx, mode, requested_irq_count);
}
-
-static inline zx_status_t pci_get_device_info(const pci_protocol_t* pci,
- zx_pcie_device_info_t* out_info) {
- return pci->ops->get_device_info(pci->ctx, out_info);
+static inline zx_status_t pci_get_device_info(const pci_protocol_t* proto,
+ zx_pcie_device_info_t* out_into) {
+ return proto->ops->get_device_info(proto->ctx, out_into);
}
-
-static inline zx_status_t pci_config_read8(const pci_protocol_t* pci,
- uint16_t offset, uint8_t* value) {
- uint32_t value_;
- zx_status_t st = pci->ops->config_read(pci->ctx, offset, sizeof(uint8_t), &value_);
- *value = value_ & UINT8_MAX;
- return st;
+static inline zx_status_t pci_config_read(const pci_protocol_t* proto, uint16_t offset,
+ size_t width, uint32_t* out_value) {
+ return proto->ops->config_read(proto->ctx, offset, width, out_value);
}
-
-static inline zx_status_t pci_config_read16(const pci_protocol_t* pci,
- uint16_t offset, uint16_t* value) {
- uint32_t value_;
- zx_status_t st = pci->ops->config_read(pci->ctx, offset, sizeof(uint16_t), &value_);
- *value = value_ & UINT16_MAX;
- return st;
+static inline zx_status_t pci_config_write(const pci_protocol_t* proto, uint16_t offset,
+ size_t width, uint32_t value) {
+ return proto->ops->config_write(proto->ctx, offset, width, value);
}
-
-static inline zx_status_t pci_config_read32(const pci_protocol_t* pci,
- uint16_t offset, uint32_t* value) {
- return pci->ops->config_read(pci->ctx, offset, sizeof(uint32_t), value);
+static inline uint8_t pci_get_next_capability(const pci_protocol_t* proto, uint8_t type,
+ uint8_t offset) {
+ return proto->ops->get_next_capability(proto->ctx, type, offset);
}
-
-static inline zx_status_t pci_config_write8(const pci_protocol_t* pci,
- uint16_t offset, uint8_t value) {
- return pci->ops->config_write(pci->ctx, offset, sizeof(uint8_t), value);
+static inline zx_status_t pci_get_auxdata(const pci_protocol_t* proto, const char* args,
+ void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual) {
+ return proto->ops->get_auxdata(proto->ctx, args, out_data_buffer, data_size, out_data_actual);
}
-
-static inline zx_status_t pci_config_write16(const pci_protocol_t* pci,
- uint16_t offset, uint16_t value) {
- return pci->ops->config_write(pci->ctx, offset, sizeof(uint16_t), value);
-}
-
-static inline zx_status_t pci_config_write32(const pci_protocol_t* pci,
- uint16_t offset, uint32_t value) {
- return pci->ops->config_write(pci->ctx, offset, sizeof(uint32_t), value);
-}
-
-static inline uint8_t pci_get_next_capability(const pci_protocol_t* pci,
- uint8_t type, uint8_t offset) {
- return pci->ops->get_next_capability(pci->ctx, type, offset);
-}
-
-static inline uint8_t pci_get_first_capability(const pci_protocol_t* pci, uint8_t type) {
- // the next_capability method will always look at the second byte next
- // pointer to fetch the next capability. By offsetting the CapPtr field
- // by -1 we can pretend we're working with a normal capability entry
- return pci_get_next_capability(pci, kPciCfgCapabilitiesPtr - 1u, type);
-}
-
-static inline zx_status_t pci_get_auxdata(const pci_protocol_t* pci,
- const char* args, void* data,
- uint32_t bytes, uint32_t* actual) {
- return pci->ops->get_auxdata(pci->ctx, args, data, bytes, actual);
+static inline zx_status_t pci_get_bti(const pci_protocol_t* proto, uint32_t index,
+ zx_handle_t* out_bti) {
+ return proto->ops->get_bti(proto->ctx, index, out_bti);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/pciroot.h b/system/ulib/ddk/include/ddk/protocol/pciroot.h
index e57b815..3d3c163 100644
--- a/system/ulib/ddk/include/ddk/protocol/pciroot.h
+++ b/system/ulib/ddk/include/ddk/protocol/pciroot.h
@@ -1,35 +1,41 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/protocol/auxdata.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
__BEGIN_CDECLS;
+// Forward declarations
+
+typedef struct pciroot_protocol pciroot_protocol_t;
+
+// Declarations
+
typedef struct pciroot_protocol_ops {
- zx_status_t (*get_auxdata)(void* ctx, const char* args, void* data,
- uint32_t bytes, uint32_t* actual);
- zx_status_t (*get_bti)(void* ctx, uint32_t bdf, uint32_t index, zx_handle_t* bti);
+ zx_status_t (*get_auxdata)(void* ctx, const char* args, void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual);
+ zx_status_t (*get_bti)(void* ctx, uint32_t bdf, uint32_t index, zx_handle_t* out_bti);
} pciroot_protocol_ops_t;
-typedef struct pciroot_protocol {
+struct pciroot_protocol {
pciroot_protocol_ops_t* ops;
void* ctx;
-} pciroot_protocol_t;
+};
-static inline zx_status_t pciroot_get_auxdata(pciroot_protocol_t* pciroot,
- const char* args, void* data,
- uint32_t bytes, uint32_t* actual) {
- return pciroot->ops->get_auxdata(pciroot->ctx, args, data, bytes, actual);
+static inline zx_status_t pciroot_get_auxdata(const pciroot_protocol_t* proto, const char* args,
+ void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual) {
+ return proto->ops->get_auxdata(proto->ctx, args, out_data_buffer, data_size, out_data_actual);
}
-
-static inline zx_status_t pciroot_get_bti(pciroot_protocol_t* pciroot,
- uint32_t bdf, uint32_t index, zx_handle_t* bti) {
- return pciroot->ops->get_bti(pciroot->ctx, bdf, index, bti);
+static inline zx_status_t pciroot_get_bti(const pciroot_protocol_t* proto, uint32_t bdf,
+ uint32_t index, zx_handle_t* out_bti) {
+ return proto->ops->get_bti(proto->ctx, bdf, index, out_bti);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/rawnand.h b/system/ulib/ddk/include/ddk/protocol/rawnand.h
index b67e5fa..7422e9f 100644
--- a/system/ulib/ddk/include/ddk/protocol/rawnand.h
+++ b/system/ulib/ddk/include/ddk/protocol/rawnand.h
@@ -2,77 +2,74 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <assert.h>
-#include <stdint.h>
-
#include <zircon/compiler.h>
-#include <zircon/listnode.h>
-
-#include <ddk/protocol/nand.h>
+#include <zircon/device/nand.h>
+#include <zircon/types.h>
__BEGIN_CDECLS;
+// Forward declarations
+
+typedef struct raw_nand_protocol raw_nand_protocol_t;
+
+// Declarations
+
typedef struct raw_nand_protocol_ops {
- // Read one nand page with hwecc.
- zx_status_t (*read_page_hwecc)(void* ctx, void *data, void *oob,
- uint32_t nandpage, int *ecc_correct);
- // Write one nand page with hwecc.
- zx_status_t (*write_page_hwecc)(void* ctx, const void* data, const void* oob,
- uint32_t nandpage);
- // Erase nand block.
+ zx_status_t (*read_page_hwecc)(void* ctx, uint32_t nandpage, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual, void* out_oob_buffer,
+ size_t oob_size, size_t* out_oob_actual,
+ zx_status_t* out_ecc_correct);
+ zx_status_t (*write_page_hwecc)(void* ctx, const void* data_buffer, size_t data_size,
+ const void* oob_buffer, size_t oob_size, uint32_t nandpage);
zx_status_t (*erase_block)(void* ctx, uint32_t nandpage);
- zx_status_t (*get_nand_info)(void *ctx, struct nand_info *info);
- // Send ONFI command down to controller.
- void (*cmd_ctrl)(void *ctx, int32_t cmd, uint32_t ctrl);
- // Read byte (used to read status as well as other info, such as ID).
- uint8_t (*read_byte)(void *ctx);
+ zx_status_t (*get_nand_info)(void* ctx, nand_info_t* out_info);
+ void (*cmd_ctrl)(void* ctx, zx_status_t cmd, uint32_t ctrl);
+ uint8_t (*read_byte)(void* ctx);
} raw_nand_protocol_ops_t;
-typedef struct raw_nand_protocol {
- raw_nand_protocol_ops_t *ops;
- void *ctx;
-} raw_nand_protocol_t;
+struct raw_nand_protocol {
+ raw_nand_protocol_ops_t* ops;
+ void* ctx;
+};
-static inline zx_status_t raw_nand_read_page_hwecc(raw_nand_protocol_t *raw_nand,
- void *data, void *oob,
- uint32_t nand_page,
- int *ecc_correct)
-{
- return raw_nand->ops->read_page_hwecc(raw_nand->ctx, data, oob, nand_page,
- ecc_correct);
+// Read one nand page with hwecc.
+static inline zx_status_t
+raw_nand_read_page_hwecc(const raw_nand_protocol_t* proto, uint32_t nandpage, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual, void* out_oob_buffer,
+ size_t oob_size, size_t* out_oob_actual, zx_status_t* out_ecc_correct) {
+ return proto->ops->read_page_hwecc(proto->ctx, nandpage, out_data_buffer, data_size,
+ out_data_actual, out_oob_buffer, oob_size, out_oob_actual,
+ out_ecc_correct);
}
-
-static inline zx_status_t raw_nand_write_page_hwecc(raw_nand_protocol_t* raw_nand,
- const void* data, const void* oob,
- uint32_t nand_page)
-{
- return raw_nand->ops->write_page_hwecc(raw_nand->ctx, data, oob, nand_page);
+// Write one nand page with hwecc.
+static inline zx_status_t raw_nand_write_page_hwecc(const raw_nand_protocol_t* proto,
+ const void* data_buffer, size_t data_size,
+ const void* oob_buffer, size_t oob_size,
+ uint32_t nandpage) {
+ return proto->ops->write_page_hwecc(proto->ctx, data_buffer, data_size, oob_buffer, oob_size,
+ nandpage);
}
-
-static inline zx_status_t raw_nand_erase_block(raw_nand_protocol_t *raw_nand,
- uint32_t nand_page)
-{
- return raw_nand->ops->erase_block(raw_nand->ctx, nand_page);
+// Erase nand block.
+static inline zx_status_t raw_nand_erase_block(const raw_nand_protocol_t* proto,
+ uint32_t nandpage) {
+ return proto->ops->erase_block(proto->ctx, nandpage);
}
-
-static inline zx_status_t raw_nand_get_info(raw_nand_protocol_t *raw_nand,
- struct nand_info *info)
-{
- return raw_nand->ops->get_nand_info(raw_nand->ctx, info);
+static inline zx_status_t raw_nand_get_nand_info(const raw_nand_protocol_t* proto,
+ nand_info_t* out_info) {
+ return proto->ops->get_nand_info(proto->ctx, out_info);
}
-
-static inline void raw_nand_cmd_ctrl(raw_nand_protocol_t *raw_nand,
- int32_t cmd, uint32_t ctrl)
-{
- raw_nand->ops->cmd_ctrl(raw_nand->ctx, cmd, ctrl);
+// Send ONFI command down to controller.
+static inline void raw_nand_cmd_ctrl(const raw_nand_protocol_t* proto, zx_status_t cmd,
+ uint32_t ctrl) {
+ proto->ops->cmd_ctrl(proto->ctx, cmd, ctrl);
}
-
-static inline uint8_t raw_nand_read_byte(raw_nand_protocol_t *raw_nand)
-{
- return raw_nand->ops->read_byte(raw_nand->ctx);
+// Read byte (used to read status as well as other info, such as ID).
+static inline uint8_t raw_nand_read_byte(const raw_nand_protocol_t* proto) {
+ return proto->ops->read_byte(proto->ctx);
}
__END_CDECLS;
-
diff --git a/system/ulib/ddk/include/ddk/protocol/scpi.h b/system/ulib/ddk/include/ddk/protocol/scpi.h
index 951acad..cd4c150 100644
--- a/system/ulib/ddk/include/ddk/protocol/scpi.h
+++ b/system/ulib/ddk/include/ddk/protocol/scpi.h
@@ -2,66 +2,69 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
#include <zircon/types.h>
-#define MAX_DVFS_OPPS 16
-
__BEGIN_CDECLS;
-typedef struct {
+// Forward declarations
+
+typedef struct scpi_opp_entry scpi_opp_entry_t;
+typedef struct scpi_opp scpi_opp_t;
+typedef struct scpi_protocol scpi_protocol_t;
+
+// Declarations
+
+struct scpi_opp_entry {
uint32_t freq_hz;
uint32_t volt_mv;
-} __PACKED scpi_opp_entry_t;
+};
-typedef struct {
- scpi_opp_entry_t opp[MAX_DVFS_OPPS];
- uint32_t latency; /* in usecs */
+struct scpi_opp {
+ scpi_opp_entry_t opp[16];
+ // In usecs.
+ uint32_t latency;
uint32_t count;
-} __PACKED scpi_opp_t;
+};
-typedef struct {
- zx_status_t (*get_sensor)(void* ctx, const char* name, uint32_t* sensor_value);
- zx_status_t (*get_sensor_value)(void* ctx, uint32_t sensor_id, uint32_t* sensor_value);
- zx_status_t (*get_dvfs_info)(void* ctx, uint8_t power_domain, scpi_opp_t* opps);
- zx_status_t (*get_dvfs_idx)(void* ctx, uint8_t power_domain, uint16_t* idx);
- zx_status_t (*set_dvfs_idx)(void* ctx, uint8_t power_domain, uint16_t idx);
+typedef struct scpi_protocol_ops {
+ zx_status_t (*get_sensor)(void* ctx, const char* name, uint32_t* out_sensor_id);
+ zx_status_t (*get_sensor_value)(void* ctx, uint32_t sensor_id, uint32_t* out_sensor_value);
+ zx_status_t (*get_dvfs_info)(void* ctx, uint8_t power_domain, scpi_opp_t* out_opps);
+ zx_status_t (*get_dvfs_idx)(void* ctx, uint8_t power_domain, uint16_t* out_index);
+ zx_status_t (*set_dvfs_idx)(void* ctx, uint8_t power_domain, uint16_t index);
} scpi_protocol_ops_t;
-typedef struct {
+struct scpi_protocol {
scpi_protocol_ops_t* ops;
void* ctx;
-} scpi_protocol_t;
+};
-// Get the sensor id
-static inline zx_status_t scpi_get_sensor(scpi_protocol_t* scpi, const char* name,
- uint32_t* sensor_value) {
- return scpi->ops->get_sensor(scpi->ctx, name, sensor_value);
+static inline zx_status_t scpi_get_sensor(const scpi_protocol_t* proto, const char* name,
+ uint32_t* out_sensor_id) {
+ return proto->ops->get_sensor(proto->ctx, name, out_sensor_id);
+}
+static inline zx_status_t scpi_get_sensor_value(const scpi_protocol_t* proto, uint32_t sensor_id,
+ uint32_t* out_sensor_value) {
+ return proto->ops->get_sensor_value(proto->ctx, sensor_id, out_sensor_value);
+}
+static inline zx_status_t scpi_get_dvfs_info(const scpi_protocol_t* proto, uint8_t power_domain,
+ scpi_opp_t* out_opps) {
+ return proto->ops->get_dvfs_info(proto->ctx, power_domain, out_opps);
+}
+static inline zx_status_t scpi_get_dvfs_idx(const scpi_protocol_t* proto, uint8_t power_domain,
+ uint16_t* out_index) {
+ return proto->ops->get_dvfs_idx(proto->ctx, power_domain, out_index);
+}
+static inline zx_status_t scpi_set_dvfs_idx(const scpi_protocol_t* proto, uint8_t power_domain,
+ uint16_t index) {
+ return proto->ops->set_dvfs_idx(proto->ctx, power_domain, index);
}
-// Get the sensor id's value
-static inline zx_status_t scpi_get_sensor_value(scpi_protocol_t* scpi, uint32_t sensor_id,
- uint32_t* sensor_value) {
- return scpi->ops->get_sensor_value(scpi->ctx, sensor_id, sensor_value);
-}
+#define MAX_DVFS_OPPS UINT32_C(16)
-// Get the DVFS info
-static inline zx_status_t scpi_get_dvfs_info(scpi_protocol_t* scpi, uint8_t power_domain,
- scpi_opp_t* opps) {
- return scpi->ops->get_dvfs_info(scpi->ctx, power_domain, opps);
-}
-
-// Get the current operating point from DVFS table
-static inline zx_status_t scpi_get_dvfs_idx(scpi_protocol_t* scpi, uint8_t power_domain,
- uint16_t* idx) {
- return scpi->ops->get_dvfs_idx(scpi->ctx, power_domain, idx);
-}
-
-// Set a new operating point from the DVFS table
-static inline zx_status_t scpi_set_dvfs_idx(scpi_protocol_t* scpi, uint8_t power_domain,
- uint16_t idx) {
- return scpi->ops->set_dvfs_idx(scpi->ctx, power_domain, idx);
-}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/sdhci.h b/system/ulib/ddk/include/ddk/protocol/sdhci.h
index 7d5985b..f011dbb 100644
--- a/system/ulib/ddk/include/ddk/protocol/sdhci.h
+++ b/system/ulib/ddk/include/ddk/protocol/sdhci.h
@@ -1,7 +1,9 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <hw/sdhci.h>
@@ -10,44 +12,66 @@
__BEGIN_CDECLS;
-typedef struct sdhci_protocol_ops {
- // TODO: should be replaced with a generic busdev mechanism
- zx_status_t (*get_interrupt)(void* ctx, zx_handle_t* handle_out);
- zx_status_t (*get_mmio)(void* ctx, volatile sdhci_regs_t** out);
- // Gets a handle to the bus transaction initiator for the device. The caller
- // receives ownership of the handle.
- zx_status_t (*get_bti)(void* ctx, uint32_t index, zx_handle_t* out_handle);
+// Forward declarations
- uint32_t (*get_base_clock)(void* ctx);
-
- // returns device quirks
- uint64_t (*get_quirks)(void* ctx);
- // platform specific HW reset
- void (*hw_reset)(void* ctx);
-} sdhci_protocol_ops_t;
-
+typedef struct sdhci_protocol sdhci_protocol_t;
+typedef uint64_t sdhci_quirk_t;
// This is a BCM28xx specific quirk. The bottom 8 bits of the 136
// bit response are normally filled by 7 CRC bits and 1 reserved bit.
// The BCM controller checks the CRC for us and strips it off in the
// process.
// The higher level stack expects 136B responses to be packed in a
// certain way so we shift all the fields back to their proper offsets.
-#define SDHCI_QUIRK_STRIP_RESPONSE_CRC (1 << 0)
+#define SDHCI_QUIRK_STRIP_RESPONSE_CRC UINT64_C(1)
// BCM28xx quirk: The BCM28xx appears to use its internal DMA engine to
// perform transfers against the SD card. Normally we would use SDMA or
// ADMA (if the part supported it). Since this part doesn't appear to
// support either, we just use PIO.
-#define SDHCI_QUIRK_NO_DMA (1 << 1)
+#define SDHCI_QUIRK_NO_DMA UINT64_C(2)
// The bottom 8 bits of the 136 bit response are normally filled by 7 CRC bits
// and 1 reserved bit. Some controllers strip off the CRC.
// The higher level stack expects 136B responses to be packed in a certain way
// so we shift all the fields back to their proper offsets.
-#define SDHCI_QUIRK_STRIP_RESPONSE_CRC_PRESERVE_ORDER (1 << 2)
+#define SDHCI_QUIRK_STRIP_RESPONSE_CRC_PRESERVE_ORDER UINT64_C(4)
+// Declarations
-typedef struct sdhci_protocol {
+typedef struct sdhci_protocol_ops {
+ zx_status_t (*get_interrupt)(void* ctx, zx_handle_t* out_irq);
+ zx_status_t (*get_mmio)(void* ctx, zx_handle_t* out_mmio);
+ zx_status_t (*get_bti)(void* ctx, uint32_t index, zx_handle_t* out_bti);
+ uint32_t (*get_base_clock)(void* ctx);
+ uint64_t (*get_quirks)(void* ctx);
+ void (*hw_reset)(void* ctx);
+} sdhci_protocol_ops_t;
+
+struct sdhci_protocol {
sdhci_protocol_ops_t* ops;
void* ctx;
-} sdhci_protocol_t;
+};
+
+static inline zx_status_t sdhci_get_interrupt(const sdhci_protocol_t* proto, zx_handle_t* out_irq) {
+ return proto->ops->get_interrupt(proto->ctx, out_irq);
+}
+static inline zx_status_t sdhci_get_mmio(const sdhci_protocol_t* proto, zx_handle_t* out_mmio) {
+ return proto->ops->get_mmio(proto->ctx, out_mmio);
+}
+// Gets a handle to the bus transaction initiator for the device. The caller
+// receives ownership of the handle.
+static inline zx_status_t sdhci_get_bti(const sdhci_protocol_t* proto, uint32_t index,
+ zx_handle_t* out_bti) {
+ return proto->ops->get_bti(proto->ctx, index, out_bti);
+}
+static inline uint32_t sdhci_get_base_clock(const sdhci_protocol_t* proto) {
+ return proto->ops->get_base_clock(proto->ctx);
+}
+// returns device quirks
+static inline uint64_t sdhci_get_quirks(const sdhci_protocol_t* proto) {
+ return proto->ops->get_quirks(proto->ctx);
+}
+// platform specific HW reset
+static inline void sdhci_hw_reset(const sdhci_protocol_t* proto) {
+ proto->ops->hw_reset(proto->ctx);
+}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/sdio.h b/system/ulib/ddk/include/ddk/protocol/sdio.h
index c16e251..0bbe9cc 100644
--- a/system/ulib/ddk/include/ddk/protocol/sdio.h
+++ b/system/ulib/ddk/include/ddk/protocol/sdio.h
@@ -1,120 +1,135 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
-#include <zircon/listnode.h>
-#include <hw/sdio.h>
+#include <zircon/types.h>
-#define SDIO_FN_0 0
-#define SDIO_FN_1 1
-#define SDIO_FN_2 2
-#define SDIO_MAX_FUNCS 8 // Including func 0
+__BEGIN_CDECLS;
-typedef struct sdio_func_hw_info {
+// Forward declarations
+
+typedef struct sdio_func_hw_info sdio_func_hw_info_t;
+typedef uint32_t sdio_card_t;
+#define SDIO_CARD_MULTI_BLOCK UINT32_C(1)
+#define SDIO_CARD_SRW UINT32_C(2)
+#define SDIO_CARD_DIRECT_COMMAND UINT32_C(4)
+#define SDIO_CARD_SUSPEND_RESUME UINT32_C(8)
+#define SDIO_CARD_LOW_SPEED UINT32_C(16)
+#define SDIO_CARD_HIGH_SPEED UINT32_C(32)
+#define SDIO_CARD_HIGH_POWER UINT32_C(64)
+#define SDIO_CARD_FOUR_BIT_BUS UINT32_C(128)
+#define SDIO_CARD_HS_SDR12 UINT32_C(256)
+#define SDIO_CARD_HS_SDR25 UINT32_C(512)
+#define SDIO_CARD_UHS_SDR50 UINT32_C(1024)
+#define SDIO_CARD_UHS_SDR104 UINT32_C(2048)
+#define SDIO_CARD_UHS_DDR50 UINT32_C(4096)
+#define SDIO_CARD_TYPE_A UINT32_C(8192)
+#define SDIO_CARD_TYPE_B UINT32_C(16384)
+#define SDIO_CARD_TYPE_C UINT32_C(32768)
+#define SDIO_CARD_TYPE_D UINT32_C(65536)
+
+typedef struct sdio_device_hw_info sdio_device_hw_info_t;
+typedef struct sdio_hw_info sdio_hw_info_t;
+typedef struct sdio_rw_txn sdio_rw_txn_t;
+typedef struct sdio_protocol sdio_protocol_t;
+
+// Declarations
+
+struct sdio_func_hw_info {
uint32_t manufacturer_id;
uint32_t product_id;
uint32_t max_blk_size;
uint32_t max_tran_speed;
- uint8_t fn_intf_code;
-} sdio_func_hw_info_t;
+ uint8_t fn_intf_code;
+};
-typedef struct sdio_device_hw_info {
- uint32_t num_funcs; // number of sdio funcs
- uint32_t sdio_vsn;
- uint32_t cccr_vsn;
- uint32_t caps;
-#define SDIO_CARD_MULTI_BLOCK (1 << 0)
-#define SDIO_CARD_SRW (1 << 1)
-#define SDIO_CARD_DIRECT_COMMAND (1 << 2)
-#define SDIO_CARD_SUSPEND_RESUME (1 << 3)
-#define SDIO_CARD_LOW_SPEED (1 << 4)
-#define SDIO_CARD_HIGH_SPEED (1 << 5)
-#define SDIO_CARD_HIGH_POWER (1 << 6)
-#define SDIO_CARD_4BIT_BUS (1 << 7)
-#define SDIO_CARD_HS_SDR12 (1 << 8)
-#define SDIO_CARD_HS_SDR25 (1 << 9)
-#define SDIO_CARD_UHS_SDR50 (1 << 10)
-#define SDIO_CARD_UHS_SDR104 (1 << 11)
-#define SDIO_CARD_UHS_DDR50 (1 << 12)
-#define SDIO_DRIVER_TYPE_A (1 << 13)
-#define SDIO_DRIVER_TYPE_B (1 << 14)
-#define SDIO_DRIVER_TYPE_C (1 << 15)
-#define SDIO_DRIVER_TYPE_D (1 << 16)
-} sdio_device_hw_info_t;
+// Including func 0
+#define SDIO_MAX_FUNCS UINT8_C(8)
-typedef struct sdio_hw_info {
+#define SDIO_FN_2 UINT8_C(0)
+
+#define SDIO_FN_1 UINT8_C(0)
+
+#define SDIO_FN_0 UINT8_C(0)
+
+struct sdio_device_hw_info {
+ // number of sdio funcs
+ uint32_t num_funcs;
+ uint32_t sdio_vsn;
+ uint32_t cccr_vsn;
+ uint32_t caps;
+};
+
+struct sdio_hw_info {
sdio_device_hw_info_t dev_hw_info;
- sdio_func_hw_info_t funcs_hw_info[SDIO_MAX_FUNCS];
+ sdio_func_hw_info_t funcs_hw_info[8];
uint32_t host_max_transfer_size;
-} sdio_hw_info_t;
+};
-typedef struct sdio_rw_txn {
+struct sdio_rw_txn {
uint32_t addr;
uint32_t data_size;
bool incr;
bool fifo;
bool write;
bool use_dma;
- zx_handle_t dma_vmo; // Used if use_dma is true
- void* virt; // Used if use_dma is false
- uint64_t buf_offset; // offset into dma_vmo or virt
-} sdio_rw_txn_t;
+ // Used if use_dma is true
+ zx_handle_t dma_vmo;
+ // Used if use_dma is false
+ void* virt_buffer;
+ size_t virt_size;
+ // offset into dma_vmo or virt
+ uint64_t buf_offset;
+};
typedef struct sdio_protocol_ops {
- zx_status_t (*get_dev_hw_info)(void* ctx, sdio_hw_info_t *hw_info);
- zx_status_t (*enable_fn)(void *ctx, uint8_t fn_idx);
- zx_status_t (*disable_fn)(void *ctx, uint8_t fn_idx);
- zx_status_t (*enable_fn_intr)(void *ctx, uint8_t fn_idx);
- zx_status_t (*disable_fn_intr)(void *ctx, uint8_t fn_idx);
- zx_status_t (*update_block_size)(void *ctx, uint8_t fn_idx, uint16_t blk_sz, bool deflt);
- zx_status_t (*get_block_size)(void *ctx, uint8_t fn_idx, uint16_t *cur_blk_size);
- zx_status_t (*do_rw_txn)(void *ctx, uint8_t fn_idx, sdio_rw_txn_t *txn);
+ zx_status_t (*get_dev_hw_info)(void* ctx, sdio_hw_info_t* out_hw_info);
+ zx_status_t (*enable_fn)(void* ctx, uint8_t fn_idx);
+ zx_status_t (*disable_fn)(void* ctx, uint8_t fn_idx);
+ zx_status_t (*enable_fn_intr)(void* ctx, uint8_t fn_idx);
+ zx_status_t (*disable_fn_intr)(void* ctx, uint8_t fn_idx);
+ zx_status_t (*update_block_size)(void* ctx, uint8_t fn_idx, uint16_t blk_sz, bool deflt);
+ zx_status_t (*get_block_size)(void* ctx, uint8_t fn_idx, uint16_t* out_cur_blk_size);
+ zx_status_t (*do_rw_txn)(void* ctx, uint8_t fn_idx, sdio_rw_txn_t* txn);
} sdio_protocol_ops_t;
-typedef struct sdio_protocol {
+struct sdio_protocol {
sdio_protocol_ops_t* ops;
void* ctx;
-} sdio_protocol_t;
+};
-static inline bool sdio_fn_idx_valid(uint8_t fn_idx) {
- return (fn_idx < SDIO_MAX_FUNCS);
+static inline zx_status_t sdio_get_dev_hw_info(const sdio_protocol_t* proto,
+ sdio_hw_info_t* out_hw_info) {
+ return proto->ops->get_dev_hw_info(proto->ctx, out_hw_info);
}
-
-static inline zx_status_t sdio_enable_fn(sdio_protocol_t* sdio, uint8_t fn_idx) {
- return sdio->ops->enable_fn(sdio->ctx, fn_idx);
+static inline zx_status_t sdio_enable_fn(const sdio_protocol_t* proto, uint8_t fn_idx) {
+ return proto->ops->enable_fn(proto->ctx, fn_idx);
}
-
-static inline zx_status_t sdio_disable_fn(sdio_protocol_t* sdio, uint8_t fn_idx) {
- return sdio->ops->disable_fn(sdio->ctx, fn_idx);
+static inline zx_status_t sdio_disable_fn(const sdio_protocol_t* proto, uint8_t fn_idx) {
+ return proto->ops->disable_fn(proto->ctx, fn_idx);
}
-
-static inline zx_status_t sdio_enable_fn_intr(sdio_protocol_t* sdio, uint8_t fn_idx) {
- return sdio->ops->enable_fn_intr(sdio->ctx, fn_idx);
+static inline zx_status_t sdio_enable_fn_intr(const sdio_protocol_t* proto, uint8_t fn_idx) {
+ return proto->ops->enable_fn_intr(proto->ctx, fn_idx);
}
-
-static inline zx_status_t sdio_disable_fn_intr(sdio_protocol_t* sdio, uint8_t fn_idx) {
- return sdio->ops->disable_fn_intr(sdio->ctx, fn_idx);
+static inline zx_status_t sdio_disable_fn_intr(const sdio_protocol_t* proto, uint8_t fn_idx) {
+ return proto->ops->disable_fn_intr(proto->ctx, fn_idx);
}
-
-static inline zx_status_t sdio_update_block_size(sdio_protocol_t* sdio, uint8_t fn_idx,
+static inline zx_status_t sdio_update_block_size(const sdio_protocol_t* proto, uint8_t fn_idx,
uint16_t blk_sz, bool deflt) {
- return sdio->ops->update_block_size(sdio->ctx, fn_idx, blk_sz, deflt);
+ return proto->ops->update_block_size(proto->ctx, fn_idx, blk_sz, deflt);
+}
+static inline zx_status_t sdio_get_block_size(const sdio_protocol_t* proto, uint8_t fn_idx,
+ uint16_t* out_cur_blk_size) {
+ return proto->ops->get_block_size(proto->ctx, fn_idx, out_cur_blk_size);
+}
+static inline zx_status_t sdio_do_rw_txn(const sdio_protocol_t* proto, uint8_t fn_idx,
+ sdio_rw_txn_t* txn) {
+ return proto->ops->do_rw_txn(proto->ctx, fn_idx, txn);
}
-static inline zx_status_t sdio_get_block_size(sdio_protocol_t* sdio, uint8_t fn_idx,
- uint16_t *cur_blk_size) {
- return sdio->ops->get_block_size(sdio->ctx, fn_idx, cur_blk_size);
-}
-
-static inline zx_status_t sdio_do_rw_txn(sdio_protocol_t* sdio, uint8_t fn_idx,
- sdio_rw_txn_t *txn) {
- return sdio->ops->do_rw_txn(sdio->ctx, fn_idx, txn);
-}
-
-static inline zx_status_t sdio_get_dev_hw_info(sdio_protocol_t* sdio,
- sdio_hw_info_t *dev_info) {
- return sdio->ops->get_dev_hw_info(sdio->ctx, dev_info);
-}
+__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/sdmmc.h b/system/ulib/ddk/include/ddk/protocol/sdmmc.h
index d3f0b34..1b7fd7c 100644
--- a/system/ulib/ddk/include/ddk/protocol/sdmmc.h
+++ b/system/ulib/ddk/include/ddk/protocol/sdmmc.h
@@ -1,151 +1,156 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/block.h>
#include <zircon/compiler.h>
#include <zircon/listnode.h>
-
-#include <ddk/protocol/block.h>
+#include <zircon/types.h>
__BEGIN_CDECLS;
-typedef enum sdmmc_voltage {
- SDMMC_VOLTAGE_330,
- SDMMC_VOLTAGE_180,
- SDMMC_VOLTAGE_MAX,
-} sdmmc_voltage_t;
+// Forward declarations
-typedef enum sdmmc_bus_width {
- SDMMC_BUS_WIDTH_1,
- SDMMC_BUS_WIDTH_4,
- SDMMC_BUS_WIDTH_8,
- SDMMC_BUS_WIDTH_MAX,
-} sdmmc_bus_width_t;
-
-typedef enum sdmmc_timing {
- SDMMC_TIMING_LEGACY,
- SDMMC_TIMING_HS,
- SDMMC_TIMING_HSDDR,
- SDMMC_TIMING_HS200,
- SDMMC_TIMING_HS400,
- SDMMC_TIMING_SDR12,
- SDMMC_TIMING_SDR25,
- SDMMC_TIMING_SDR50,
- SDMMC_TIMING_SDR104,
- SDMMC_TIMING_DDR50,
- SDMMC_TIMING_MAX,
-} sdmmc_timing_t;
-
-// block io transactions. one per client request
-typedef struct sdmmc_txn {
- block_op_t bop;
- list_node_t node;
-} sdmmc_txn_t;
+typedef uint64_t sdmmc_host_prefs_t;
+#define SDMMC_HOST_PREFS_DISABLE_HS400 UINT64_C(1)
+#define SDMMC_HOST_PREFS_DISABLE_HS200 UINT64_C(2)
typedef struct sdmmc_req sdmmc_req_t;
+typedef struct sdmmc_host_info sdmmc_host_info_t;
+typedef uint8_t sdmmc_voltage_t;
+#define SDMMC_VOLTAGE_V330 UINT8_C(0)
+#define SDMMC_VOLTAGE_V180 UINT8_C(1)
+#define SDMMC_VOLTAGE_MAX UINT8_C(2)
-// number of pages per request - 2M per request
-// matches DMA_DESC_COUNT in dev/block/sdhci
-#define SDMMC_PAGES_COUNT (PAGE_SIZE / sizeof(zx_paddr_t))
+typedef uint64_t sdmmc_host_cap_t;
+#define SDMMC_HOST_CAP_BUS_WIDTH_8 UINT64_C(1)
+#define SDMMC_HOST_CAP_ADMA2 UINT64_C(2)
+#define SDMMC_HOST_CAP_SIXTY_FOUR_BIT UINT64_C(4)
+#define SDMMC_HOST_CAP_VOLTAGE_330 UINT64_C(8)
+#define SDMMC_HOST_CAP_AUTO_CMD12 UINT64_C(16)
+
+typedef uint8_t sdmmc_timing_t;
+#define SDMMC_TIMING_LEGACY UINT8_C(0)
+#define SDMMC_TIMING_HS UINT8_C(1)
+#define SDMMC_TIMING_HSDDR UINT8_C(2)
+#define SDMMC_TIMING_HS200 UINT8_C(3)
+#define SDMMC_TIMING_HS400 UINT8_C(4)
+#define SDMMC_TIMING_SDR12 UINT8_C(5)
+#define SDMMC_TIMING_SDR25 UINT8_C(6)
+#define SDMMC_TIMING_SDR50 UINT8_C(7)
+#define SDMMC_TIMING_SDR104 UINT8_C(8)
+#define SDMMC_TIMING_DDR50 UINT8_C(9)
+#define SDMMC_TIMING_MAX UINT8_C(10)
+
+typedef uint8_t sdmmc_bus_width_t;
+#define SDMMC_BUS_WIDTH_ONE UINT8_C(0)
+#define SDMMC_BUS_WIDTH_FOUR UINT8_C(1)
+#define SDMMC_BUS_WIDTH_EIGHT UINT8_C(2)
+#define SDMMC_BUS_WIDTH_MAX UINT8_C(3)
+
+typedef struct sdmmc_protocol sdmmc_protocol_t;
+typedef struct sdmmc_txn sdmmc_txn_t;
+
+// Declarations
// sdmmc requests. one per command
struct sdmmc_req {
uint32_t cmd_idx;
uint32_t cmd_flags;
uint32_t arg;
-
// data command parameters
uint16_t blockcount;
uint16_t blocksize;
bool use_dma;
- zx_handle_t dma_vmo; // Used if use_dma is true
- void* virt; // Used if use_dma is false
- uint64_t buf_offset; // offset into dma_vmo or virt
+ // Used if use_dma is true
+ zx_handle_t dma_vmo;
+ // Used if use_dma is false
+ void* virt_buffer;
+ size_t virt_size;
+ // offset into dma_vmo or virt
+ uint64_t buf_offset;
zx_handle_t pmt;
-
// response data
uint32_t response[4];
-
// status
zx_status_t status;
};
-typedef struct sdmmc_host_info {
+struct sdmmc_host_info {
// Controller capabilities
uint64_t caps;
-#define SDMMC_HOST_CAP_BUS_WIDTH_8 (1 << 0)
-#define SDMMC_HOST_CAP_ADMA2 (1 << 1)
-#define SDMMC_HOST_CAP_64BIT (1 << 2)
-#define SDMMC_HOST_CAP_VOLTAGE_330 (1 << 3)
-#define SDMMC_HOST_CAP_AUTO_CMD12 (1 << 4)
// Maximum data request size
uint64_t max_transfer_size;
uint64_t max_transfer_size_non_dma;
// Host specific preferences
uint64_t prefs;
-#define SDMMC_HOST_PREFS_DISABLE_HS400 (1 << 0)
-#define SDMMC_HOST_PREFS_DISABLE_HS200 (1 << 1)
+};
-} sdmmc_host_info_t;
+// number of pages per request - 2M per request
+// matches DMA_DESC_COUNT in dev/block/sdhci
+// (PAGE_SIZE / sizeof(zx_paddr_t))
+#define SDMMC_PAGES_COUNT UINT64_C(512)
typedef struct sdmmc_protocol_ops {
- // get host info
- zx_status_t (*host_info)(void* ctx, sdmmc_host_info_t* info);
- // set signal voltage
+ zx_status_t (*host_info)(void* ctx, sdmmc_host_info_t* out_info);
zx_status_t (*set_signal_voltage)(void* ctx, sdmmc_voltage_t voltage);
- // set bus width
zx_status_t (*set_bus_width)(void* ctx, sdmmc_bus_width_t bus_width);
- // set bus frequency
zx_status_t (*set_bus_freq)(void* ctx, uint32_t bus_freq);
- // set mmc timing
zx_status_t (*set_timing)(void* ctx, sdmmc_timing_t timing);
- // issue a hw reset
void (*hw_reset)(void* ctx);
- // perform tuning
zx_status_t (*perform_tuning)(void* ctx, uint32_t cmd_idx);
- // issue a request
zx_status_t (*request)(void* ctx, sdmmc_req_t* req);
} sdmmc_protocol_ops_t;
-typedef struct sdmmc_protocol {
+struct sdmmc_protocol {
sdmmc_protocol_ops_t* ops;
void* ctx;
-} sdmmc_protocol_t;
+};
-static inline zx_status_t sdmmc_host_info(sdmmc_protocol_t* sdmmc, sdmmc_host_info_t* info) {
- return sdmmc->ops->host_info(sdmmc->ctx, info);
+// Get host info.
+static inline zx_status_t sdmmc_host_info(const sdmmc_protocol_t* proto,
+ sdmmc_host_info_t* out_info) {
+ return proto->ops->host_info(proto->ctx, out_info);
}
-
-static inline zx_status_t sdmmc_set_signal_voltage(sdmmc_protocol_t* sdmmc,
+// Set signal voltage.
+static inline zx_status_t sdmmc_set_signal_voltage(const sdmmc_protocol_t* proto,
sdmmc_voltage_t voltage) {
- return sdmmc->ops->set_signal_voltage(sdmmc->ctx, voltage);
+ return proto->ops->set_signal_voltage(proto->ctx, voltage);
}
-
-static inline zx_status_t sdmmc_set_bus_width(sdmmc_protocol_t* sdmmc,
+// Set bus width.
+static inline zx_status_t sdmmc_set_bus_width(const sdmmc_protocol_t* proto,
sdmmc_bus_width_t bus_width) {
- return sdmmc->ops->set_bus_width(sdmmc->ctx, bus_width);
+ return proto->ops->set_bus_width(proto->ctx, bus_width);
+}
+// Set bus frequency.
+static inline zx_status_t sdmmc_set_bus_freq(const sdmmc_protocol_t* proto, uint32_t bus_freq) {
+ return proto->ops->set_bus_freq(proto->ctx, bus_freq);
+}
+// Set mmc timing.
+static inline zx_status_t sdmmc_set_timing(const sdmmc_protocol_t* proto, sdmmc_timing_t timing) {
+ return proto->ops->set_timing(proto->ctx, timing);
+}
+// Issue a hw reset.
+static inline void sdmmc_hw_reset(const sdmmc_protocol_t* proto) {
+ proto->ops->hw_reset(proto->ctx);
+}
+// Perform tuning.
+static inline zx_status_t sdmmc_perform_tuning(const sdmmc_protocol_t* proto, uint32_t cmd_idx) {
+ return proto->ops->perform_tuning(proto->ctx, cmd_idx);
+}
+// Issue a request.
+static inline zx_status_t sdmmc_request(const sdmmc_protocol_t* proto, sdmmc_req_t* req) {
+ return proto->ops->request(proto->ctx, req);
}
-static inline zx_status_t sdmmc_set_bus_freq(sdmmc_protocol_t* sdmmc, uint32_t bus_freq) {
- return sdmmc->ops->set_bus_freq(sdmmc->ctx, bus_freq);
-}
-
-static inline zx_status_t sdmmc_set_timing(sdmmc_protocol_t* sdmmc, sdmmc_timing_t timing) {
- return sdmmc->ops->set_timing(sdmmc->ctx, timing);
-}
-
-static inline void sdmmc_hw_reset(sdmmc_protocol_t* sdmmc) {
- sdmmc->ops->hw_reset(sdmmc->ctx);
-}
-
-static inline zx_status_t sdmmc_perform_tuning(sdmmc_protocol_t* sdmmc, uint32_t cmd_idx) {
- return sdmmc->ops->perform_tuning(sdmmc->ctx, cmd_idx);
-}
-
-static inline zx_status_t sdmmc_request(sdmmc_protocol_t* sdmmc, sdmmc_req_t* req) {
- return sdmmc->ops->request(sdmmc->ctx, req);
-}
+// block io transactions. one per client request
+struct sdmmc_txn {
+ block_op_t bop;
+ list_node_t node;
+};
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/serial-impl.h b/system/ulib/ddk/include/ddk/protocol/serial-impl.h
index 32f658e..af0dd36 100644
--- a/system/ulib/ddk/include/ddk/protocol/serial-impl.h
+++ b/system/ulib/ddk/include/ddk/protocol/serial-impl.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/serial.h>
@@ -10,76 +12,61 @@
__BEGIN_CDECLS;
-// Low level serial protocol to be implemented by serial drivers
-// This is only used by bus drivers like platform bus
+// Forward declarations
-// state flags for serial_notify_cb
-enum {
- SERIAL_STATE_READABLE = (1 << 0),
- SERIAL_STATE_WRITABLE = (1 << 1),
+typedef uint32_t serial_state_t;
+#define SERIAL_STATE_READABLE UINT32_C(1)
+#define SERIAL_STATE_WRITABLE UINT32_C(2)
+
+typedef struct serial_notify serial_notify_t;
+typedef struct serial_impl_protocol serial_impl_protocol_t;
+
+// Declarations
+
+struct serial_notify {
+ void (*callback)(void* ctx, serial_state_t state);
+ void* ctx;
};
-// Callback for notification of readable/writeable state changes
-// This may be called from an interrupt thread it should just signal another thread
-// and return as soon as possible. In particular, it may not be safe to make protocol calls
-// from these callbacks.
-typedef void (*serial_notify_cb)(uint32_t state, void* cookie);
-
-typedef struct {
- zx_status_t (*get_info)(void* ctx, serial_port_info_t* info);
+typedef struct serial_impl_protocol_ops {
+ zx_status_t (*get_info)(void* ctx, serial_port_info_t* out_info);
zx_status_t (*config)(void* ctx, uint32_t baud_rate, uint32_t flags);
zx_status_t (*enable)(void* ctx, bool enable);
- zx_status_t (*read)(void* ctx, void* buf, size_t length, size_t* out_actual);
- zx_status_t (*write)(void* ctx, const void* buf, size_t length,
- size_t* out_actual);
- zx_status_t (*set_notify_callback)(void* ctx, serial_notify_cb cb,
- void* cookie);
-} serial_impl_ops_t;
+ zx_status_t (*read)(void* ctx, void* out_buf_buffer, size_t buf_size, size_t* out_buf_actual);
+ zx_status_t (*write)(void* ctx, const void* buf_buffer, size_t buf_size, size_t* out_actual);
+ zx_status_t (*set_notify_callback)(void* ctx, const serial_notify_t* cb);
+} serial_impl_protocol_ops_t;
-typedef struct {
- serial_impl_ops_t* ops;
+struct serial_impl_protocol {
+ serial_impl_protocol_ops_t* ops;
void* ctx;
-} serial_impl_protocol_t;
+};
-static inline zx_status_t serial_impl_get_info(serial_impl_protocol_t* serial,
- serial_port_info_t* info) {
- return serial->ops->get_info(serial->ctx, info);
+static inline zx_status_t serial_impl_get_info(const serial_impl_protocol_t* proto,
+ serial_port_info_t* out_info) {
+ return proto->ops->get_info(proto->ctx, out_info);
}
-
-// Configures the given serial port
-static inline zx_status_t serial_impl_config(serial_impl_protocol_t* serial, uint32_t baud_rate,
- uint32_t flags) {
- return serial->ops->config(serial->ctx, baud_rate, flags);
+// Configures the given serial port.
+static inline zx_status_t serial_impl_config(const serial_impl_protocol_t* proto,
+ uint32_t baud_rate, uint32_t flags) {
+ return proto->ops->config(proto->ctx, baud_rate, flags);
}
-
-// Enables or disables the given serial port
-static inline zx_status_t serial_impl_enable(serial_impl_protocol_t* serial, bool enable) {
- return serial->ops->enable(serial->ctx, enable);
+static inline zx_status_t serial_impl_enable(const serial_impl_protocol_t* proto, bool enable) {
+ return proto->ops->enable(proto->ctx, enable);
}
-
-// Reads data from the given serial port
-// Returns ZX_ERR_SHOULD_WAIT if no data is available to read
-static inline zx_status_t serial_impl_read(serial_impl_protocol_t* serial, void* buf, size_t length,
- size_t* out_actual) {
- return serial->ops->read(serial->ctx, buf, length, out_actual);
+static inline zx_status_t serial_impl_read(const serial_impl_protocol_t* proto,
+ void* out_buf_buffer, size_t buf_size,
+ size_t* out_buf_actual) {
+ return proto->ops->read(proto->ctx, out_buf_buffer, buf_size, out_buf_actual);
}
-
-// Reads data from the given serial port
-// Returns ZX_ERR_SHOULD_WAIT if transmit buffer is full and writing is not possible
-static inline zx_status_t serial_impl_write(serial_impl_protocol_t* serial, const void* buf,
- size_t length, size_t* out_actual) {
- return serial->ops->write(serial->ctx, buf, length, out_actual);
+static inline zx_status_t serial_impl_write(const serial_impl_protocol_t* proto,
+ const void* buf_buffer, size_t buf_size,
+ size_t* out_actual) {
+ return proto->ops->write(proto->ctx, buf_buffer, buf_size, out_actual);
}
-
-// Sets a callback to be called when the port's readable and writeble state changes
-// Pass NULL to clear previously installed callback
-// The callback may be called from an interrupt thread it should just signal another thread
-// and return as soon as possible. In particular, it may not be safe to make protocol calls
-// from the callback.
-// Returns ZX_ERR_BAD_STATE called while the driver is in enabled state.
-static inline zx_status_t serial_impl_set_notify_callback(serial_impl_protocol_t* serial,
- serial_notify_cb cb, void* cookie) {
- return serial->ops->set_notify_callback(serial->ctx, cb, cookie);
+static inline zx_status_t serial_impl_set_notify_callback(const serial_impl_protocol_t* proto,
+ const serial_notify_t* cb) {
+ return proto->ops->set_notify_callback(proto->ctx, cb);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/serial.h b/system/ulib/ddk/include/ddk/protocol/serial.h
index ada9f9b..d44cc3a 100644
--- a/system/ulib/ddk/include/ddk/protocol/serial.h
+++ b/system/ulib/ddk/include/ddk/protocol/serial.h
@@ -2,51 +2,59 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <zircon/compiler.h>
-#include <zircon/device/serial.h>
#include <zircon/types.h>
__BEGIN_CDECLS;
-typedef struct {
+// Forward declarations
+
+typedef struct serial_port_info serial_port_info_t;
+typedef struct serial_protocol serial_protocol_t;
+
+// Declarations
+
+struct serial_port_info {
uint32_t serial_class;
- // vendor and product ID of hardware attached to this serial port,
- // or zero if not applicable
+ // Vendor and product ID of hardware attached to this serial port,
+ // or zero if not applicable.
uint32_t serial_vid;
uint32_t serial_pid;
-} serial_port_info_t;
+};
-// High level serial protocol for use by client drivers
-// When used with the platform device protocol, "port" will be relative to
-// the list of serial ports assigned to your device rather than the global
-// list of serial ports.
-typedef struct {
- zx_status_t (*get_info)(void* ctx, serial_port_info_t* info);
+typedef struct serial_protocol_ops {
+ zx_status_t (*get_info)(void* ctx, serial_port_info_t* out_info);
zx_status_t (*config)(void* ctx, uint32_t baud_rate, uint32_t flags);
zx_status_t (*open_socket)(void* ctx, zx_handle_t* out_handle);
} serial_protocol_ops_t;
-typedef struct {
+// High level serial protocol for use by client drivers.
+// When used with the platform device protocol, "port" will be relative to
+// the list of serial ports assigned to your device rather than the global
+// list of serial ports.
+struct serial_protocol {
serial_protocol_ops_t* ops;
void* ctx;
-} serial_protocol_t;
+};
-static inline zx_status_t serial_get_info(serial_protocol_t* serial, serial_port_info_t* info) {
- return serial->ops->get_info(serial->ctx, info);
+static inline zx_status_t serial_get_info(const serial_protocol_t* proto,
+ serial_port_info_t* out_info) {
+ return proto->ops->get_info(proto->ctx, out_info);
}
-
-// configures the given serial port
-static inline zx_status_t serial_config(serial_protocol_t* serial, uint32_t baud_rate,
+// Configures the given serial port.
+static inline zx_status_t serial_config(const serial_protocol_t* proto, uint32_t baud_rate,
uint32_t flags) {
- return serial->ops->config(serial->ctx, baud_rate, flags);
+ return proto->ops->config(proto->ctx, baud_rate, flags);
}
-
-// returns a socket that can be used for reading and writing data
-// from the given serial port
-static inline zx_status_t serial_open_socket(serial_protocol_t* serial, zx_handle_t* out_handle) {
- return serial->ops->open_socket(serial->ctx, out_handle);
+// Returns a socket that can be used for reading and writing data
+// from the given serial port.
+static inline zx_status_t serial_open_socket(const serial_protocol_t* proto,
+ zx_handle_t* out_handle) {
+ return proto->ops->open_socket(proto->ctx, out_handle);
}
__END_CDECLS;
diff --git a/system/ulib/ddk/include/ddk/protocol/test.h b/system/ulib/ddk/include/ddk/protocol/test.h
index 092cd52..1628b1d 100644
--- a/system/ulib/ddk/include/ddk/protocol/test.h
+++ b/system/ulib/ddk/include/ddk/protocol/test.h
@@ -1,39 +1,80 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <zircon/device/test.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
-typedef test_ioctl_test_report_t test_report_t;
+__BEGIN_CDECLS;
-typedef zx_status_t (*test_func_t)(void* cookie, test_report_t* report, const void* arg, size_t arglen);
+// Forward declarations
+
+typedef struct test_report test_report_t;
+typedef struct test_func test_func_t;
+typedef struct test_protocol test_protocol_t;
+
+// Declarations
+
+struct test_report {
+ uint64_t n_tests;
+ uint64_t n_success;
+ uint64_t n_failed;
+};
+
+struct test_func {
+ zx_status_t (*callback)(void* ctx, const void* arg_buffer, size_t arg_size,
+ test_report_t* out_report);
+ void* ctx;
+};
typedef struct test_protocol_ops {
- // sets test output socket
void (*set_output_socket)(void* ctx, zx_handle_t handle);
-
- // gets test output socket
zx_handle_t (*get_output_socket)(void* ctx);
-
- // sets control channel
void (*set_control_channel)(void* ctx, zx_handle_t handle);
-
- // gets control channel
zx_handle_t (*get_control_channel)(void* ctx);
-
- // sets test function
- void (*set_test_func)(void* ctx, test_func_t func, void* cookie);
-
- // run tests, calls the function set in set_test_func
- zx_status_t (*run_tests)(void* ctx, test_report_t* report, const void* arg, size_t arglen);
-
- // calls device_remove()
+ void (*set_test_func)(void* ctx, const test_func_t* func);
+ zx_status_t (*run_tests)(void* ctx, const void* arg_buffer, size_t arg_size,
+ test_report_t* out_report);
void (*destroy)(void* ctx);
} test_protocol_ops_t;
-typedef struct test_protocol {
+struct test_protocol {
test_protocol_ops_t* ops;
void* ctx;
-} test_protocol_t;
+};
+
+// Sets test output socket.
+static inline void test_set_output_socket(const test_protocol_t* proto, zx_handle_t handle) {
+ proto->ops->set_output_socket(proto->ctx, handle);
+}
+// Gets test output socket.
+static inline zx_handle_t test_get_output_socket(const test_protocol_t* proto) {
+ return proto->ops->get_output_socket(proto->ctx);
+}
+// Sets control channel.
+static inline void test_set_control_channel(const test_protocol_t* proto, zx_handle_t handle) {
+ proto->ops->set_control_channel(proto->ctx, handle);
+}
+// Gets control channel.
+static inline zx_handle_t test_get_control_channel(const test_protocol_t* proto) {
+ return proto->ops->get_control_channel(proto->ctx);
+}
+// Sets test function.
+static inline void test_set_test_func(const test_protocol_t* proto, const test_func_t* func) {
+ proto->ops->set_test_func(proto->ctx, func);
+}
+// Run tests, calls the function set in |SetTestFunc|.
+static inline zx_status_t test_run_tests(const test_protocol_t* proto, const void* arg_buffer,
+ size_t arg_size, test_report_t* out_report) {
+ return proto->ops->run_tests(proto->ctx, arg_buffer, arg_size, out_report);
+}
+// Calls `device_remove()`.
+static inline void test_destroy(const test_protocol_t* proto) {
+ proto->ops->destroy(proto->ctx);
+}
+
+__END_CDECLS;
diff --git a/system/ulib/ddktl/include/ddktl/protocol/acpi-internal.h b/system/ulib/ddktl/include/ddktl/protocol/acpi-internal.h
new file mode 100644
index 0000000..f1e8660
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/acpi-internal.h
@@ -0,0 +1,34 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/acpi.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_acpi_protocol_map_resource, AcpiMapResource,
+ zx_status_t (C::*)(uint32_t resource_id, uint32_t cache_policy,
+ void** out_vaddr_buffer, size_t* vaddr_size,
+ zx_handle_t* out_handle));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_acpi_protocol_map_interrupt, AcpiMapInterrupt,
+ zx_status_t (C::*)(int64_t irq_id, zx_handle_t* out_handle));
+
+template <typename D>
+constexpr void CheckAcpiProtocolSubclass() {
+ static_assert(internal::has_acpi_protocol_map_resource<D>::value,
+ "AcpiProtocol subclasses must implement "
+ "zx_status_t AcpiMapResource(uint32_t resource_id, uint32_t cache_policy, void** "
+ "out_vaddr_buffer, size_t* vaddr_size, zx_handle_t* out_handle");
+ static_assert(internal::has_acpi_protocol_map_interrupt<D>::value,
+ "AcpiProtocol subclasses must implement "
+ "zx_status_t AcpiMapInterrupt(int64_t irq_id, zx_handle_t* out_handle");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/acpi.h b/system/ulib/ddktl/include/ddktl/protocol/acpi.h
new file mode 100644
index 0000000..9e41a66
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/acpi.h
@@ -0,0 +1,108 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/acpi.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "acpi-internal.h"
+
+// DDK acpi-protocol support
+//
+// :: Proxies ::
+//
+// ddk::AcpiProtocolProxy is a simple wrapper around
+// acpi_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::AcpiProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the acpi protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_ACPI device.
+// class AcpiDevice {
+// using AcpiDeviceType = ddk::Device<AcpiDevice, /* ddk mixins */>;
+//
+// class AcpiDevice : public AcpiDeviceType,
+// public ddk::AcpiProtocol<AcpiDevice> {
+// public:
+// AcpiDevice(zx_device_t* parent)
+// : AcpiDeviceType("my-acpi-protocol-device", parent) {}
+//
+// zx_status_t AcpiMapResource(uint32_t resource_id, uint32_t cache_policy, void**
+// out_vaddr_buffer, size_t* vaddr_size, zx_handle_t* out_handle);
+//
+// zx_status_t AcpiMapInterrupt(int64_t irq_id, zx_handle_t* out_handle);
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class AcpiProtocol : public internal::base_protocol {
+public:
+ AcpiProtocol() {
+ internal::CheckAcpiProtocolSubclass<D>();
+ ops_.map_resource = AcpiMapResource;
+ ops_.map_interrupt = AcpiMapInterrupt;
+
+ // Can only inherit from one base_protocol implementation.
+ ZX_ASSERT(ddk_proto_id_ = 0);
+ ddk_proto_id_ = ZX_PROTOCOL_ACPI;
+ ddk_proto_ops_ = &ops_;
+ }
+
+protected:
+ acpi_protocol_ops_t ops_ = {};
+
+private:
+ static zx_status_t AcpiMapResource(void* ctx, uint32_t resource_id, uint32_t cache_policy,
+ void** out_vaddr_buffer, size_t* vaddr_size,
+ zx_handle_t* out_handle) {
+ return static_cast<D*>(ctx)->AcpiMapResource(resource_id, cache_policy, out_vaddr_buffer,
+ vaddr_size, out_handle);
+ }
+ static zx_status_t AcpiMapInterrupt(void* ctx, int64_t irq_id, zx_handle_t* out_handle) {
+ return static_cast<D*>(ctx)->AcpiMapInterrupt(irq_id, out_handle);
+ }
+};
+
+class AcpiProtocolProxy {
+public:
+ AcpiProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ AcpiProtocolProxy(const acpi_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(acpi_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t MapResource(uint32_t resource_id, uint32_t cache_policy, void** out_vaddr_buffer,
+ size_t* vaddr_size, zx_handle_t* out_handle) {
+ return ops_->map_resource(ctx_, resource_id, cache_policy, out_vaddr_buffer, vaddr_size,
+ out_handle);
+ }
+ zx_status_t MapInterrupt(int64_t irq_id, zx_handle_t* out_handle) {
+ return ops_->map_interrupt(ctx_, irq_id, out_handle);
+ }
+
+private:
+ acpi_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas-internal.h b/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas-internal.h
index 292b1b3..2f69399 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas-internal.h
@@ -2,28 +2,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/amlogic-canvas.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_canvas_config, CanvasConfig,
- zx_status_t (C::*)(zx_handle_t, size_t, canvas_info_t*, uint8_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_canvas_free, CanvasFree,
- zx_status_t (C::*)(uint8_t));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_canvas_protocol_config, CanvasConfig,
+ zx_status_t (C::*)(zx_handle_t vmo, size_t offset,
+ const canvas_info_t* info,
+ uint8_t* out_canvas_idx));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_canvas_protocol_free, CanvasFree,
+ zx_status_t (C::*)(uint8_t canvas_idx));
template <typename D>
constexpr void CheckCanvasProtocolSubclass() {
- static_assert(internal::has_canvas_config<D>::value,
+ static_assert(internal::has_canvas_protocol_config<D>::value,
"CanvasProtocol subclasses must implement "
- "CanvasConfig(zx_handle_t vmo, size_t offset, canvas_info_t* info, "
- "uint8_t* canvas_idx)");
- static_assert(internal::has_canvas_free<D>::value,
+ "zx_status_t CanvasConfig(zx_handle_t vmo, size_t offset, const canvas_info_t* "
+ "info, uint8_t* out_canvas_idx");
+ static_assert(internal::has_canvas_protocol_free<D>::value,
"CanvasProtocol subclasses must implement "
- "CanvasFree(uint8_t canvas_idx)");
- }
+ "zx_status_t CanvasFree(uint8_t canvas_idx");
+}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas.h b/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas.h
index b5158fb..49e7f67 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/amlogic-canvas.h
@@ -2,42 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/amlogic-canvas.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "amlogic-canvas-internal.h"
-// DDK canvas protocol support.
+// DDK canvas-protocol support
//
// :: Proxies ::
//
-// ddk::CanvasProtocolProxy is a simple wrappers around canvas_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::CanvasProtocolProxy is a simple wrapper around
+// canvas_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::CanvasProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the canvas protocol.
+// ddk::CanvasProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the canvas protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
-// // A driver that implements a ZX_PROTOCOL_AMLOGIC_CANVAS device.
-// class CanvasDevice;
+// // A driver that implements a ZX_PROTOCOL_CANVAS device.
+// class CanvasDevice {
// using CanvasDeviceType = ddk::Device<CanvasDevice, /* ddk mixins */>;
//
// class CanvasDevice : public CanvasDeviceType,
// public ddk::CanvasProtocol<CanvasDevice> {
// public:
// CanvasDevice(zx_device_t* parent)
-// : CanvasDeviceType("my-canvas-device", parent) {}
+// : CanvasDeviceType("my-canvas-protocol-device", parent) {}
//
-// zx_status_t CanvasConfig(zx_handle_t vmo, size_t offset, canvas_info_t* info,
-// uint8_t* canvas_idx);
-// zx_status_t CanvasFree(uint8_t canvas_idx);
+// zx_status_t CanvasConfig(zx_handle_t vmo, size_t offset, const canvas_info_t* info, uint8_t*
+// out_canvas_idx);
+//
+// zx_status_t CanvasFree(uint8_t canvas_idx);
+//
// ...
// };
@@ -51,9 +56,9 @@
ops_.config = CanvasConfig;
ops_.free = CanvasFree;
- // Can only inherit from one base_protocol implemenation
- ZX_ASSERT(ddk_proto_id_ == 0);
- ddk_proto_id_ = ZX_PROTOCOL_AMLOGIC_CANVAS;
+ // Can only inherit from one base_protocol implementation.
+ ZX_ASSERT(ddk_proto_id_ = 0);
+ ddk_proto_id_ = ZX_PROTOCOL_CANVAS;
ddk_proto_ops_ = &ops_;
}
@@ -61,10 +66,13 @@
canvas_protocol_ops_t ops_ = {};
private:
- static zx_status_t CanvasConfig(void* ctx, zx_handle_t vmo, size_t offset, canvas_info_t* info,
- uint8_t* canvas_idx) {
- return static_cast<D*>(ctx)->CanvasConfig(vmo, offset, info, canvas_idx);
+ // Configures a canvas.
+ // Adds a framebuffer to the canvas lookup table.
+ static zx_status_t CanvasConfig(void* ctx, zx_handle_t vmo, size_t offset,
+ const canvas_info_t* info, uint8_t* out_canvas_idx) {
+ return static_cast<D*>(ctx)->CanvasConfig(vmo, offset, info, out_canvas_idx);
}
+ // Frees up a canvas.
static zx_status_t CanvasFree(void* ctx, uint8_t canvas_idx) {
return static_cast<D*>(ctx)->CanvasFree(canvas_idx);
}
@@ -72,21 +80,26 @@
class CanvasProtocolProxy {
public:
- CanvasProtocolProxy(canvas_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ CanvasProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ CanvasProtocolProxy(const canvas_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(canvas_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
-
- zx_status_t Config(zx_handle_t vmo, size_t offset, canvas_info_t* info,
- uint8_t* canvas_idx) {
- return ops_->config(ctx_, vmo, offset, info, canvas_idx);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
- zx_status_t Free(uint8_t canvas_idx) {
- return ops_->free(ctx_, canvas_idx);
+ // Configures a canvas.
+ // Adds a framebuffer to the canvas lookup table.
+ zx_status_t Config(zx_handle_t vmo, size_t offset, const canvas_info_t* info,
+ uint8_t* out_canvas_idx) {
+ return ops_->config(ctx_, vmo, offset, info, out_canvas_idx);
}
+ // Frees up a canvas.
+ zx_status_t Free(uint8_t canvas_idx) { return ops_->free(ctx_, canvas_idx); }
private:
canvas_protocol_ops_t* ops_;
diff --git a/system/ulib/ddktl/include/ddktl/protocol/bad-block-internal.h b/system/ulib/ddktl/include/ddktl/protocol/bad-block-internal.h
index 51f3d63..f8acf21 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/bad-block-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/bad-block-internal.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/bad-block.h>
@@ -10,21 +12,23 @@
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_get_bad_block_list2, GetBadBlockList,
- zx_status_t (C::*)(uint32_t*, uint32_t, uint32_t*));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_mark_block_bad, MarkBlockBad,
- zx_status_t (C::*)(uint32_t));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_bad_block_protocol_get_bad_block_list,
+ BadBlockGetBadBlockList,
+ zx_status_t (C::*)(uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_bad_block_protocol_mark_block_bad, BadBlockMarkBlockBad,
+ zx_status_t (C::*)(uint32_t block));
template <typename D>
-constexpr void CheckBadBlockable() {
- static_assert(internal::has_get_bad_block_list2<D>::value,
+constexpr void CheckBadBlockProtocolSubclass() {
+ static_assert(internal::has_bad_block_protocol_get_bad_block_list<D>::value,
"BadBlockProtocol subclasses must implement "
- "GetBadBlockList(uint32_t* bad_blocks, "
- "uint32_t bad_block_len, uint32_t* num_bad_blocks)");
- static_assert(internal::has_mark_block_bad<D>::value,
+ "zx_status_t BadBlockGetBadBlockList(uint32_t* out_bad_blocks_list, size_t "
+ "bad_blocks_count, size_t* out_bad_blocks_actual");
+ static_assert(internal::has_bad_block_protocol_mark_block_bad<D>::value,
"BadBlockProtocol subclasses must implement "
- "MarkBlockBad(uint32_t block)");
+ "zx_status_t BadBlockMarkBlockBad(uint32_t block");
}
} // namespace internal
diff --git a/system/ulib/ddktl/include/ddktl/protocol/bad-block.h b/system/ulib/ddktl/include/ddktl/protocol/bad-block.h
index a423ec7..3107e1a 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/bad-block.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/bad-block.h
@@ -2,41 +2,46 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/bad-block.h>
#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "bad-block-internal.h"
-// DDK bad-block protocol support.
+// DDK bad-block-protocol support
//
// :: Proxies ::
//
-// ddk::BadBlockProtocolProxy is a simple wrappers around bad_block_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::BadBlockProtocolProxy is a simple wrapper around
+// bad_block_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::BadBlockable is a mixin class that simplifies writing DDK drivers that
-// implement the bad-block protocol. It does not set the base protocol.
+// ddk::BadBlockProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the bad-block protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_BAD_BLOCK device.
-// class BadBlockDevice;
+// class BadBlockDevice {
// using BadBlockDeviceType = ddk::Device<BadBlockDevice, /* ddk mixins */>;
//
// class BadBlockDevice : public BadBlockDeviceType,
-// public ddk::BadBlockable<BadBlockDevice> {
+// public ddk::BadBlockProtocol<BadBlockDevice> {
// public:
// BadBlockDevice(zx_device_t* parent)
-// : BadBlockDeviceType("my-bad-block-device", parent) {}
+// : BadBlockDeviceType("my-bad-block-protocol-device", parent) {}
//
-// zx_status_t GetBadBlockList(uint32_t* bad_block_list, uint32_t bad_block_list_len,
-// uint32_t* bad_block_count);
-// zx_status_t IsBlockBad(uint32_t block, bool* is_bad);
-// zx_status_t MarkBlockBad(uint32_t block);
+// zx_status_t BadBlockGetBadBlockList(uint32_t* out_bad_blocks_list, size_t bad_blocks_count,
+// size_t* out_bad_blocks_actual);
+//
+// zx_status_t BadBlockMarkBlockBad(uint32_t block);
//
// ...
// };
@@ -44,42 +49,61 @@
namespace ddk {
template <typename D>
-class BadBlockable : public internal::base_mixin {
+class BadBlockProtocol : public internal::base_mixin {
public:
- BadBlockable() {
- internal::CheckBadBlockable<D>();
- bad_block_proto_ops_.get_bad_block_list = GetBadBlockList;
- bad_block_proto_ops_.mark_block_bad = MarkBlockBad;
+ BadBlockProtocol() {
+ internal::CheckBadBlockProtocolSubclass<D>();
+ bad_block_protocol_ops_.get_bad_block_list = BadBlockGetBadBlockList;
+ bad_block_protocol_ops_.mark_block_bad = BadBlockMarkBlockBad;
}
protected:
- bad_block_protocol_ops_t bad_block_proto_ops_ = {};
+ bad_block_protocol_ops_t bad_block_protocol_ops_ = {};
private:
- static zx_status_t GetBadBlockList(void* ctx, uint32_t* bad_block_list,
- uint32_t bad_block_list_len, uint32_t* bad_block_count) {
- return static_cast<D*>(ctx)->GetBadBlockList(bad_block_list, bad_block_list_len,
- bad_block_count);
+ // Fills in |bad_blocks| with a list of bad blocks, up until
+ // |bad_blocks_count|. The order of blocks is undefined.
+ // |bad_blocks_actual| will be filled in with the actual number of bad
+ // blocks. It is recommended to first make call with |bad_blocks_count|
+ // equal to 0 in order to determine how large the |bad_blocks| is.
+ static zx_status_t BadBlockGetBadBlockList(void* ctx, uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual) {
+ return static_cast<D*>(ctx)->BadBlockGetBadBlockList(out_bad_blocks_list, bad_blocks_count,
+ out_bad_blocks_actual);
}
-
- static zx_status_t MarkBlockBad(void* ctx, uint32_t block) {
- return static_cast<D*>(ctx)->MarkBlockBad(block);
+ // Sets |block| as bad. If block is already marked bad, it has no effect.
+ static zx_status_t BadBlockMarkBlockBad(void* ctx, uint32_t block) {
+ return static_cast<D*>(ctx)->BadBlockMarkBlockBad(block);
}
};
class BadBlockProtocolProxy {
public:
- BadBlockProtocolProxy(bad_block_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ BadBlockProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ BadBlockProtocolProxy(const bad_block_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
- zx_status_t GetBadBlockList(uint32_t* bad_block_list, uint32_t bad_block_list_len,
- uint32_t* bad_block_count) {
- return ops_->get_bad_block_list(ctx_, bad_block_list, bad_block_list_len, bad_block_count);
+ void GetProto(bad_block_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
-
- zx_status_t MarkBlockBad(uint32_t block) {
- return ops_->mark_block_bad(ctx_, block);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
+ // Fills in |bad_blocks| with a list of bad blocks, up until
+ // |bad_blocks_count|. The order of blocks is undefined.
+ // |bad_blocks_actual| will be filled in with the actual number of bad
+ // blocks. It is recommended to first make call with |bad_blocks_count|
+ // equal to 0 in order to determine how large the |bad_blocks| is.
+ zx_status_t GetBadBlockList(uint32_t* out_bad_blocks_list, size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual) {
+ return ops_->get_bad_block_list(ctx_, out_bad_blocks_list, bad_blocks_count,
+ out_bad_blocks_actual);
+ }
+ // Sets |block| as bad. If block is already marked bad, it has no effect.
+ zx_status_t MarkBlockBad(uint32_t block) { return ops_->mark_block_bad(ctx_, block); }
private:
bad_block_protocol_ops_t* ops_;
diff --git a/system/ulib/ddktl/include/ddktl/protocol/bt-hci-internal.h b/system/ulib/ddktl/include/ddktl/protocol/bt-hci-internal.h
new file mode 100644
index 0000000..9f415b8
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/bt-hci-internal.h
@@ -0,0 +1,38 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/bt-hci.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_bt_hci_protocol_open_command_channel,
+ BtHciOpenCommandChannel,
+ zx_status_t (C::*)(zx_handle_t* out_channel));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_bt_hci_protocol_open_acl_data_channel,
+ BtHciOpenAclDataChannel,
+ zx_status_t (C::*)(zx_handle_t* out_channel));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_bt_hci_protocol_open_snoop_channel, BtHciOpenSnoopChannel,
+ zx_status_t (C::*)(zx_handle_t* out_channel));
+
+template <typename D>
+constexpr void CheckBtHciProtocolSubclass() {
+ static_assert(internal::has_bt_hci_protocol_open_command_channel<D>::value,
+ "BtHciProtocol subclasses must implement "
+ "zx_status_t BtHciOpenCommandChannel(zx_handle_t* out_channel");
+ static_assert(internal::has_bt_hci_protocol_open_acl_data_channel<D>::value,
+ "BtHciProtocol subclasses must implement "
+ "zx_status_t BtHciOpenAclDataChannel(zx_handle_t* out_channel");
+ static_assert(internal::has_bt_hci_protocol_open_snoop_channel<D>::value,
+ "BtHciProtocol subclasses must implement "
+ "zx_status_t BtHciOpenSnoopChannel(zx_handle_t* out_channel");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/bt-hci.h b/system/ulib/ddktl/include/ddktl/protocol/bt-hci.h
index a7505fa..897e254 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/bt-hci.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/bt-hci.h
@@ -1,48 +1,51 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
+#include <ddk/protocol/bt-hci.h>
#include <ddktl/device-internal.h>
-#include <fbl/type_support.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
-// DDK bt-hci protocol support
+#include "bt-hci-internal.h"
+
+// DDK bt-hci-protocol support
+//
+// :: Proxies ::
+//
+// ddk::BtHciProtocolProxy is a simple wrapper around
+// bt_hci_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::BtHciProtocol enables writing DDK drivers that implement the bt-hci
-// protocol. The bt-hci protocol is currently empty, being a protocol that is
-// implemented entirely through ioctls.
+// ddk::BtHciProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the bt-hci protocol. It doesn't set the base protocol.
//
-// :: Example ::
+// :: Examples ::
//
-// // A driver that implements a ZX_PROTOCOL_BT_HCI device
-// class BtHciDevice;
-// using BtHciDeviceType = ddk::Device<BtHciDevice, ddk::Ioctlable,
-// /* other ddk mixins */>;
+// // A driver that implements a ZX_PROTOCOL_BT_HCI device.
+// class BtHciDevice {
+// using BtHciDeviceType = ddk::Device<BtHciDevice, /* ddk mixins */>;
//
// class BtHciDevice : public BtHciDeviceType,
// public ddk::BtHciProtocol<BtHciDevice> {
// public:
// BtHciDevice(zx_device_t* parent)
-// : BtHciDeviceType(parent) {}
+// : BtHciDeviceType("my-bt-hci-protocol-device", parent) {}
//
-// zx_status_t Bind() {
-// return DdkAdd("my-bt-hci-device");
-// }
+// zx_status_t BtHciOpenCommandChannel(zx_handle_t* out_channel);
//
-// void DdkRelease() {
-// // Clean up
-// }
+// zx_status_t BtHciOpenAclDataChannel(zx_handle_t* out_channel);
//
-// zx_status_t DdkIoctl(uint32_t op, const void *in_buf ... ) {
-// // Handle IOCTL_BT_HCI_*
-// }
+// zx_status_t BtHciOpenSnoopChannel(zx_handle_t* out_channel);
+//
+// ...
// };
-//
namespace ddk {
@@ -50,10 +53,83 @@
class BtHciProtocol : public internal::base_protocol {
public:
BtHciProtocol() {
- // Can only inherit from one base_protocol implementation
- ZX_ASSERT(this->ddk_proto_id_ == 0);
+ internal::CheckBtHciProtocolSubclass<D>();
+ ops_.open_command_channel = BtHciOpenCommandChannel;
+ ops_.open_acl_data_channel = BtHciOpenAclDataChannel;
+ ops_.open_snoop_channel = BtHciOpenSnoopChannel;
+
+ // Can only inherit from one base_protocol implementation.
+ ZX_ASSERT(ddk_proto_id_ = 0);
ddk_proto_id_ = ZX_PROTOCOL_BT_HCI;
+ ddk_proto_ops_ = &ops_;
}
+
+protected:
+ bt_hci_protocol_ops_t ops_ = {};
+
+private:
+ // Open the two-way HCI command channel for sending HCI commands and
+ // receiving event packets. Returns ZX_ERR_ALREADY_BOUND if the channel
+ // is already open.
+ static zx_status_t BtHciOpenCommandChannel(void* ctx, zx_handle_t* out_channel) {
+ return static_cast<D*>(ctx)->BtHciOpenCommandChannel(out_channel);
+ }
+ // Open the two-way HCI ACL data channel.
+ // Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+ static zx_status_t BtHciOpenAclDataChannel(void* ctx, zx_handle_t* out_channel) {
+ return static_cast<D*>(ctx)->BtHciOpenAclDataChannel(out_channel);
+ }
+ // Open an output-only channel for monitoring HCI traffic.
+ // The format of each message is: [1-octet flags] [n-octet payload]
+ // The flags octet is a bitfield with the following values defined:
+ // - 0x00: The payload represents a command packet sent from the host to the
+ // controller.
+ // - 0x01: The payload represents an event packet sent by the controller.
+ // Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+ static zx_status_t BtHciOpenSnoopChannel(void* ctx, zx_handle_t* out_channel) {
+ return static_cast<D*>(ctx)->BtHciOpenSnoopChannel(out_channel);
+ }
+};
+
+class BtHciProtocolProxy {
+public:
+ BtHciProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ BtHciProtocolProxy(const bt_hci_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(bt_hci_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Open the two-way HCI command channel for sending HCI commands and
+ // receiving event packets. Returns ZX_ERR_ALREADY_BOUND if the channel
+ // is already open.
+ zx_status_t OpenCommandChannel(zx_handle_t* out_channel) {
+ return ops_->open_command_channel(ctx_, out_channel);
+ }
+ // Open the two-way HCI ACL data channel.
+ // Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+ zx_status_t OpenAclDataChannel(zx_handle_t* out_channel) {
+ return ops_->open_acl_data_channel(ctx_, out_channel);
+ }
+ // Open an output-only channel for monitoring HCI traffic.
+ // The format of each message is: [1-octet flags] [n-octet payload]
+ // The flags octet is a bitfield with the following values defined:
+ // - 0x00: The payload represents a command packet sent from the host to the
+ // controller.
+ // - 0x01: The payload represents an event packet sent by the controller.
+ // Returns ZX_ERR_ALREADY_BOUND if the channel is already open.
+ zx_status_t OpenSnoopChannel(zx_handle_t* out_channel) {
+ return ops_->open_snoop_channel(ctx_, out_channel);
+ }
+
+private:
+ bt_hci_protocol_ops_t* ops_;
+ void* ctx_;
};
} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/clk-internal.h b/system/ulib/ddktl/include/ddktl/protocol/clk-internal.h
index c901463..5d1b195 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/clk-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/clk-internal.h
@@ -2,27 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/clk.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_clk_enable, ClkEnable,
- zx_status_t (C::*)(uint32_t));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_clk_disable, ClkDisable,
- zx_status_t (C::*)(uint32_t));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_clk_protocol_enable, ClkEnable,
+ zx_status_t (C::*)(uint32_t index));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_clk_protocol_disable, ClkDisable,
+ zx_status_t (C::*)(uint32_t index));
template <typename D>
constexpr void CheckClkProtocolSubclass() {
- static_assert(internal::has_clk_enable<D>::value,
+ static_assert(internal::has_clk_protocol_enable<D>::value,
"ClkProtocol subclasses must implement "
- "ClkEnable(uint32_t index)");
- static_assert(internal::has_clk_disable<D>::value,
+ "zx_status_t ClkEnable(uint32_t index");
+ static_assert(internal::has_clk_protocol_disable<D>::value,
"ClkProtocol subclasses must implement "
- "ClkDisable(uint32_t index)");
- }
+ "zx_status_t ClkDisable(uint32_t index");
+}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/clk.h b/system/ulib/ddktl/include/ddktl/protocol/clk.h
index d5a7c70..ba950cb 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/clk.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/clk.h
@@ -2,40 +2,46 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/clk.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
-#include <ddk/driver.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
#include "clk-internal.h"
-// DDK clock protocol support.
+// DDK clk-protocol support
//
// :: Proxies ::
//
-// ddk::ClkProtocolProxy is a simple wrappers around clk_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::ClkProtocolProxy is a simple wrapper around
+// clk_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::ClkProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the clock protocol.
+// ddk::ClkProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the clk protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_CLK device.
-// class ClkDevice;
+// class ClkDevice {
// using ClkDeviceType = ddk::Device<ClkDevice, /* ddk mixins */>;
//
// class ClkDevice : public ClkDeviceType,
// public ddk::ClkProtocol<ClkDevice> {
// public:
// ClkDevice(zx_device_t* parent)
-// : ClkDeviceType("my-clk-device", parent) {}
+// : ClkDeviceType("my-clk-protocol-device", parent) {}
//
-// zx_status_t ClkEnable(uint32_t index);
-// zx_status_t ClkDisable(uint32_t index);
+// zx_status_t ClkEnable(uint32_t index);
+//
+// zx_status_t ClkDisable(uint32_t index);
+//
// ...
// };
@@ -49,8 +55,8 @@
ops_.enable = ClkEnable;
ops_.disable = ClkDisable;
- // Can only inherit from one base_protocol implemenation
- ZX_ASSERT(ddk_proto_id_ == 0);
+ // Can only inherit from one base_protocol implementation.
+ ZX_ASSERT(ddk_proto_id_ = 0);
ddk_proto_id_ = ZX_PROTOCOL_CLK;
ddk_proto_ops_ = &ops_;
}
@@ -69,20 +75,20 @@
class ClkProtocolProxy {
public:
- ClkProtocolProxy(clk_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ ClkProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ ClkProtocolProxy(const clk_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(clk_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
-
- zx_status_t Enable(uint32_t index) {
- return ops_->enable(ctx_, index);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
- zx_status_t Disable(uint32_t index) {
- return ops_->disable(ctx_, index);
- }
+ zx_status_t Enable(uint32_t index) { return ops_->enable(ctx_, index); }
+ zx_status_t Disable(uint32_t index) { return ops_->disable(ctx_, index); }
private:
clk_protocol_ops_t* ops_;
diff --git a/system/ulib/ddktl/include/ddktl/protocol/display-controller-internal.h b/system/ulib/ddktl/include/ddktl/protocol/display-controller-internal.h
new file mode 100644
index 0000000..cd4190b
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/display-controller-internal.h
@@ -0,0 +1,109 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/display-controller.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(
+ has_display_controller_interface_on_displays_changed,
+ DisplayControllerInterfaceOnDisplaysChanged,
+ void (C::*)(const added_display_args_t* added_display_list, size_t added_display_count,
+ const uint64_t* removed_display_list, size_t removed_display_count,
+ added_display_info_t* out_display_info_list, size_t display_info_count,
+ size_t* out_display_info_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_interface_on_display_vsync,
+ DisplayControllerInterfaceOnDisplayVsync,
+ void (C::*)(uint64_t display_id, int64_t timestamp,
+ const uint64_t* handle_list, size_t handle_count));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_interface_get_audio_format,
+ DisplayControllerInterfaceGetAudioFormat,
+ zx_status_t (C::*)(uint64_t display_id, uint32_t fmt_idx,
+ audio_stream_format_range_t* out_fmt));
+
+template <typename D>
+constexpr void CheckDisplayControllerInterfaceSubclass() {
+ static_assert(
+ internal::has_display_controller_interface_on_displays_changed<D>::value,
+ "DisplayControllerInterface subclasses must implement "
+ "void DisplayControllerInterfaceOnDisplaysChanged(const added_display_args_t* "
+ "added_display_list, size_t added_display_count, const uint64_t* removed_display_list, "
+ "size_t removed_display_count, added_display_info_t* out_display_info_list, size_t "
+ "display_info_count, size_t* out_display_info_actual");
+ static_assert(internal::has_display_controller_interface_on_display_vsync<D>::value,
+ "DisplayControllerInterface subclasses must implement "
+ "void DisplayControllerInterfaceOnDisplayVsync(uint64_t display_id, int64_t "
+ "timestamp, const uint64_t* handle_list, size_t handle_count");
+ static_assert(internal::has_display_controller_interface_get_audio_format<D>::value,
+ "DisplayControllerInterface subclasses must implement "
+ "zx_status_t DisplayControllerInterfaceGetAudioFormat(uint64_t display_id, "
+ "uint32_t fmt_idx, audio_stream_format_range_t* out_fmt");
+}
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(
+ has_display_controller_protocol_set_display_controller_interface,
+ DisplayControllerSetDisplayControllerInterface,
+ void (C::*)(const display_controller_interface_t* intf));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_protocol_import_vmo_image,
+ DisplayControllerImportVmoImage,
+ zx_status_t (C::*)(image_t* image, zx_handle_t vmo,
+ size_t offset));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_protocol_release_image,
+ DisplayControllerReleaseImage, void (C::*)(image_t* image));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(
+ has_display_controller_protocol_check_configuration, DisplayControllerCheckConfiguration,
+ uint32_t (C::*)(const display_config_t** display_config_list, size_t display_config_count,
+ uint32_t** out_layer_cfg_result_list, size_t* layer_cfg_result_count));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_protocol_apply_configuration,
+ DisplayControllerApplyConfiguration,
+ void (C::*)(const display_config_t** display_config_list,
+ size_t display_config_count));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_protocol_compute_linear_stride,
+ DisplayControllerComputeLinearStride,
+ uint32_t (C::*)(uint32_t width,
+ zx_pixel_format_t pixel_format));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_display_controller_protocol_allocate_vmo,
+ DisplayControllerAllocateVmo,
+ zx_status_t (C::*)(uint64_t size, zx_handle_t* out_vmo));
+
+template <typename D>
+constexpr void CheckDisplayControllerProtocolSubclass() {
+ static_assert(
+ internal::has_display_controller_protocol_set_display_controller_interface<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "void DisplayControllerSetDisplayControllerInterface(const display_controller_interface_t* "
+ "intf");
+ static_assert(internal::has_display_controller_protocol_import_vmo_image<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "zx_status_t DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo, "
+ "size_t offset");
+ static_assert(internal::has_display_controller_protocol_release_image<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "void DisplayControllerReleaseImage(image_t* image");
+ static_assert(internal::has_display_controller_protocol_check_configuration<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "uint32_t DisplayControllerCheckConfiguration(const display_config_t** "
+ "display_config_list, size_t display_config_count, uint32_t** "
+ "out_layer_cfg_result_list, size_t* layer_cfg_result_count");
+ static_assert(internal::has_display_controller_protocol_apply_configuration<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "void DisplayControllerApplyConfiguration(const display_config_t** "
+ "display_config_list, size_t display_config_count");
+ static_assert(internal::has_display_controller_protocol_compute_linear_stride<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "uint32_t DisplayControllerComputeLinearStride(uint32_t width, zx_pixel_format_t "
+ "pixel_format");
+ static_assert(internal::has_display_controller_protocol_allocate_vmo<D>::value,
+ "DisplayControllerProtocol subclasses must implement "
+ "zx_status_t DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* out_vmo");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/display-controller.h b/system/ulib/ddktl/include/ddktl/protocol/display-controller.h
index 47303e1..becbbb3 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/display-controller.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/display-controller.h
@@ -2,69 +2,346 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/display-controller.h>
#include <ddktl/device-internal.h>
-#include <lib/zx/vmo.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/device/audio.h>
+#include <zircon/types.h>
+
+#include "display-controller-internal.h"
+
+// DDK display-controller-protocol support
+//
+// :: Proxies ::
+//
+// ddk::DisplayControllerProtocolProxy is a simple wrapper around
+// display_controller_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::DisplayControllerProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the display-controller protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_DISPLAY_CONTROLLER device.
+// class DisplayControllerDevice {
+// using DisplayControllerDeviceType = ddk::Device<DisplayControllerDevice, /* ddk mixins */>;
+//
+// class DisplayControllerDevice : public DisplayControllerDeviceType,
+// public ddk::DisplayControllerProtocol<DisplayControllerDevice> {
+// public:
+// DisplayControllerDevice(zx_device_t* parent)
+// : DisplayControllerDeviceType("my-display-controller-protocol-device", parent) {}
+//
+// void DisplayControllerSetDisplayControllerInterface(const display_controller_interface_t*
+// intf);
+//
+// zx_status_t DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset);
+//
+// void DisplayControllerReleaseImage(image_t* image);
+//
+// uint32_t DisplayControllerCheckConfiguration(const display_config_t** display_config_list,
+// size_t display_config_count, uint32_t** out_layer_cfg_result_list, size_t*
+// layer_cfg_result_count);
+//
+// void DisplayControllerApplyConfiguration(const display_config_t** display_config_list, size_t
+// display_config_count);
+//
+// uint32_t DisplayControllerComputeLinearStride(uint32_t width, zx_pixel_format_t
+// pixel_format);
+//
+// zx_status_t DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* out_vmo);
+//
+// ...
+// };
namespace ddk {
+// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device
+// during these callbacks.
template <typename D>
-class DisplayControllerProtocol : public internal::base_protocol {
- public:
- DisplayControllerProtocol() {
- // TODO(stevensd): Add subclass check once API is stabilized
- ops_.set_display_controller_cb = SetDisplayControllerCb;
- ops_.import_vmo_image = ImportVmoImage;
- ops_.release_image = ReleaseImage;
- ops_.check_configuration = CheckConfiguration;
- ops_.apply_configuration = ApplyConfiguration;
- ops_.compute_linear_stride = ComputeLinearStride;
- ops_.allocate_vmo = AllocateVmo;
-
- // Can only inherit from one base_protocol implemenation
- ZX_ASSERT(ddk_proto_id_ == 0);
- ddk_proto_id_ = ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL;
- ddk_proto_ops_ = &ops_;
+class DisplayControllerInterface : public internal::base_mixin {
+public:
+ DisplayControllerInterface() {
+ internal::CheckDisplayControllerInterfaceSubclass<D>();
+ display_controller_interface_ops_.on_displays_changed =
+ DisplayControllerInterfaceOnDisplaysChanged;
+ display_controller_interface_ops_.on_display_vsync =
+ DisplayControllerInterfaceOnDisplayVsync;
+ display_controller_interface_ops_.get_audio_format =
+ DisplayControllerInterfaceGetAudioFormat;
}
- private:
- static void SetDisplayControllerCb(void* ctx, void* cb_ctx, display_controller_cb_t* cb) {
- static_cast<D*>(ctx)->SetDisplayControllerCb(cb_ctx, cb);
- }
+protected:
+ display_controller_interface_ops_t display_controller_interface_ops_ = {};
- static zx_status_t ImportVmoImage(void* ctx, image_t* image, zx_handle_t vmo, size_t offset) {
- return static_cast<D*>(ctx)->ImportVmoImage(image, *zx::unowned_vmo(vmo), offset);
+private:
+ // Callbacks which are invoked when displays are added or removed. |added_display_list| and
+ // |removed_display_list| point to arrays of the display ids which were added and removed. If
+ // |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
+ // The driver must be done accessing any images which were on the removed displays.
+ // The driver should call this function when the callback is registered if any displays
+ // are present.
+ static void DisplayControllerInterfaceOnDisplaysChanged(
+ void* ctx, const added_display_args_t* added_display_list, size_t added_display_count,
+ const uint64_t* removed_display_list, size_t removed_display_count,
+ added_display_info_t* out_display_info_list, size_t display_info_count,
+ size_t* out_display_info_actual) {
+ static_cast<D*>(ctx)->DisplayControllerInterfaceOnDisplaysChanged(
+ added_display_list, added_display_count, removed_display_list, removed_display_count,
+ out_display_info_list, display_info_count, out_display_info_actual);
}
-
- static void ReleaseImage(void* ctx, image_t* image) {
- static_cast<D*>(ctx)->ReleaseImage(image);
+ // |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
+ // |handles| points to an array of image handles of each framebuffer being
+ // displayed, in increasing z-order.
+ static void DisplayControllerInterfaceOnDisplayVsync(void* ctx, uint64_t display_id,
+ int64_t timestamp,
+ const uint64_t* handle_list,
+ size_t handle_count) {
+ static_cast<D*>(ctx)->DisplayControllerInterfaceOnDisplayVsync(display_id, timestamp,
+ handle_list, handle_count);
}
-
- static void CheckConfiguration(void* ctx, const display_config_t** display_config,
- uint32_t* display_cfg_result, uint32_t** layer_cfg_result,
- uint32_t display_count) {
- static_cast<D*>(ctx)->CheckConfiguration(display_config, display_cfg_result,
- layer_cfg_result, display_count);
+ static zx_status_t
+ DisplayControllerInterfaceGetAudioFormat(void* ctx, uint64_t display_id, uint32_t fmt_idx,
+ audio_stream_format_range_t* out_fmt) {
+ return static_cast<D*>(ctx)->DisplayControllerInterfaceGetAudioFormat(display_id, fmt_idx,
+ out_fmt);
}
-
- static void ApplyConfiguration(void* ctx, const display_config_t** display_config,
- uint32_t display_count) {
- static_cast<D*>(ctx)->ApplyConfiguration(display_config, display_count);
- }
-
- static uint32_t ComputeLinearStride(void* ctx, uint32_t width, zx_pixel_format_t format) {
- return static_cast<D*>(ctx)->ComputeLinearStride(width, format);
- }
-
- static zx_status_t AllocateVmo(void* ctx, uint64_t size, zx_handle_t* vmo_out) {
- return static_cast<D*>(ctx)->AllocateVmo(size, vmo_out);
- }
-
- display_controller_protocol_ops_t ops_ = {};
};
-}
+class DisplayControllerInterfaceProxy {
+public:
+ DisplayControllerInterfaceProxy() : ops_(nullptr), ctx_(nullptr) {}
+ DisplayControllerInterfaceProxy(const display_controller_interface_t* proto)
+ : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(display_controller_interface_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Callbacks which are invoked when displays are added or removed. |added_display_list| and
+ // |removed_display_list| point to arrays of the display ids which were added and removed. If
+ // |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
+ // The driver must be done accessing any images which were on the removed displays.
+ // The driver should call this function when the callback is registered if any displays
+ // are present.
+ void OnDisplaysChanged(const added_display_args_t* added_display_list,
+ size_t added_display_count, const uint64_t* removed_display_list,
+ size_t removed_display_count,
+ added_display_info_t* out_display_info_list, size_t display_info_count,
+ size_t* out_display_info_actual) {
+ ops_->on_displays_changed(ctx_, added_display_list, added_display_count,
+ removed_display_list, removed_display_count,
+ out_display_info_list, display_info_count,
+ out_display_info_actual);
+ }
+ // |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
+ // |handles| points to an array of image handles of each framebuffer being
+ // displayed, in increasing z-order.
+ void OnDisplayVsync(uint64_t display_id, int64_t timestamp, const uint64_t* handle_list,
+ size_t handle_count) {
+ ops_->on_display_vsync(ctx_, display_id, timestamp, handle_list, handle_count);
+ }
+ zx_status_t GetAudioFormat(uint64_t display_id, uint32_t fmt_idx,
+ audio_stream_format_range_t* out_fmt) {
+ return ops_->get_audio_format(ctx_, display_id, fmt_idx, out_fmt);
+ }
+
+private:
+ display_controller_interface_ops_t* ops_;
+ void* ctx_;
+};
+
+// The client guarantees that check_configuration and apply_configuration are always
+// made from a single thread. The client makes no other threading guarantees.
+template <typename D>
+class DisplayControllerProtocol : public internal::base_mixin {
+public:
+ DisplayControllerProtocol() {
+ internal::CheckDisplayControllerProtocolSubclass<D>();
+ display_controller_protocol_ops_.set_display_controller_interface =
+ DisplayControllerSetDisplayControllerInterface;
+ display_controller_protocol_ops_.import_vmo_image = DisplayControllerImportVmoImage;
+ display_controller_protocol_ops_.release_image = DisplayControllerReleaseImage;
+ display_controller_protocol_ops_.check_configuration = DisplayControllerCheckConfiguration;
+ display_controller_protocol_ops_.apply_configuration = DisplayControllerApplyConfiguration;
+ display_controller_protocol_ops_.compute_linear_stride =
+ DisplayControllerComputeLinearStride;
+ display_controller_protocol_ops_.allocate_vmo = DisplayControllerAllocateVmo;
+ }
+
+protected:
+ display_controller_protocol_ops_t display_controller_protocol_ops_ = {};
+
+private:
+ // The function will only be called once, and it will be called before any other
+ // functions are called.
+ static void
+ DisplayControllerSetDisplayControllerInterface(void* ctx,
+ const display_controller_interface_t* intf) {
+ static_cast<D*>(ctx)->DisplayControllerSetDisplayControllerInterface(intf);
+ }
+ // Imports a VMO backed image into the driver. The driver should set image->handle. The
+ // driver does not own the vmo handle passed to this function.
+ static zx_status_t DisplayControllerImportVmoImage(void* ctx, image_t* image, zx_handle_t vmo,
+ size_t offset) {
+ return static_cast<D*>(ctx)->DisplayControllerImportVmoImage(image, vmo, offset);
+ }
+ // Releases any driver state associated with the given image. The client guarantees that
+ // any images passed to apply_config will not be released until a vsync occurs with a
+ // more recent image.
+ static void DisplayControllerReleaseImage(void* ctx, image_t* image) {
+ static_cast<D*>(ctx)->DisplayControllerReleaseImage(image);
+ }
+ // Validates the given configuration.
+ // The configuration may not include all displays. Omiteed displays should be treated as
+ // whichever of off or displaying a blank screen results in a more premissive validation.
+ // All displays in a configuration will have at least one layer. The layers will be
+ // arranged in increasing z-order, and their z_index fields will be set consecutively.
+ // Whether or not the driver can accept the configuration cannot depend on the
+ // particular image handles, as it must always be possible to present a new image in
+ // place of another image with a matching configuration. It also cannot depend on the
+ // cursor position, as that can be updated without another call to check_configuration.
+ // display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
+ // display modes is not supported.
+ // layer_cfg_result points to an array of arrays. The primary length is display_count, the
+ // secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
+ // is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
+ // flag in the corresponding layer_cfg_result entry.
+ // The driver must not retain references to the configuration after this function returns.
+ // TODO: Fix me...
+ static uint32_t DisplayControllerCheckConfiguration(
+ void* ctx, const display_config_t** display_config_list, size_t display_config_count,
+ uint32_t** out_layer_cfg_result_list, size_t* layer_cfg_result_count) {
+ return static_cast<D*>(ctx)->DisplayControllerCheckConfiguration(
+ display_config_list, display_config_count, out_layer_cfg_result_list,
+ layer_cfg_result_count);
+ }
+ // Applies the configuration.
+ // All configurations passed to this function will be derived from configurations which
+ // have been succesfully validated, with the only differences either being omitted layers
+ // or different image handles. To account for any layers which are not present, the driver
+ // must use the z_index values of the present layers to configure them as if the whole
+ // configuration was present.
+ // Unlike with check_configuration, displays included in the configuration are not
+ // guaranteed to include any layers. Both omitted displays and displays with no layers
+ // can either be turned off or set to display a blank screen, but for displays with no
+ // layers there is a strong preference to display a blank screen instead of turn them off.
+ // In either case, the driver must drop all references to old images and invoke the vsync
+ // callback after doing so.
+ // The driver must not retain references to the configuration after this function returns.
+ static void DisplayControllerApplyConfiguration(void* ctx,
+ const display_config_t** display_config_list,
+ size_t display_config_count) {
+ static_cast<D*>(ctx)->DisplayControllerApplyConfiguration(display_config_list,
+ display_config_count);
+ }
+ // Computes the stride (in pixels) necessary for a linear image with the given width
+ // and pixel format. Returns 0 on error.
+ static uint32_t DisplayControllerComputeLinearStride(void* ctx, uint32_t width,
+ zx_pixel_format_t pixel_format) {
+ return static_cast<D*>(ctx)->DisplayControllerComputeLinearStride(width, pixel_format);
+ }
+ // Allocates a VMO of the requested size which can be used for images.
+ static zx_status_t DisplayControllerAllocateVmo(void* ctx, uint64_t size,
+ zx_handle_t* out_vmo) {
+ return static_cast<D*>(ctx)->DisplayControllerAllocateVmo(size, out_vmo);
+ }
+};
+
+class DisplayControllerProtocolProxy {
+public:
+ DisplayControllerProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ DisplayControllerProtocolProxy(const display_controller_protocol_t* proto)
+ : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(display_controller_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // The function will only be called once, and it will be called before any other
+ // functions are called.
+ void SetDisplayControllerInterface(const display_controller_interface_t* intf) {
+ ops_->set_display_controller_interface(ctx_, intf);
+ }
+ // Imports a VMO backed image into the driver. The driver should set image->handle. The
+ // driver does not own the vmo handle passed to this function.
+ zx_status_t ImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset) {
+ return ops_->import_vmo_image(ctx_, image, vmo, offset);
+ }
+ // Releases any driver state associated with the given image. The client guarantees that
+ // any images passed to apply_config will not be released until a vsync occurs with a
+ // more recent image.
+ void ReleaseImage(image_t* image) { ops_->release_image(ctx_, image); }
+ // Validates the given configuration.
+ // The configuration may not include all displays. Omiteed displays should be treated as
+ // whichever of off or displaying a blank screen results in a more premissive validation.
+ // All displays in a configuration will have at least one layer. The layers will be
+ // arranged in increasing z-order, and their z_index fields will be set consecutively.
+ // Whether or not the driver can accept the configuration cannot depend on the
+ // particular image handles, as it must always be possible to present a new image in
+ // place of another image with a matching configuration. It also cannot depend on the
+ // cursor position, as that can be updated without another call to check_configuration.
+ // display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
+ // display modes is not supported.
+ // layer_cfg_result points to an array of arrays. The primary length is display_count, the
+ // secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
+ // is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
+ // flag in the corresponding layer_cfg_result entry.
+ // The driver must not retain references to the configuration after this function returns.
+ // TODO: Fix me...
+ uint32_t CheckConfiguration(const display_config_t** display_config_list,
+ size_t display_config_count, uint32_t** out_layer_cfg_result_list,
+ size_t* layer_cfg_result_count) {
+ return ops_->check_configuration(ctx_, display_config_list, display_config_count,
+ out_layer_cfg_result_list, layer_cfg_result_count);
+ }
+ // Applies the configuration.
+ // All configurations passed to this function will be derived from configurations which
+ // have been succesfully validated, with the only differences either being omitted layers
+ // or different image handles. To account for any layers which are not present, the driver
+ // must use the z_index values of the present layers to configure them as if the whole
+ // configuration was present.
+ // Unlike with check_configuration, displays included in the configuration are not
+ // guaranteed to include any layers. Both omitted displays and displays with no layers
+ // can either be turned off or set to display a blank screen, but for displays with no
+ // layers there is a strong preference to display a blank screen instead of turn them off.
+ // In either case, the driver must drop all references to old images and invoke the vsync
+ // callback after doing so.
+ // The driver must not retain references to the configuration after this function returns.
+ void ApplyConfiguration(const display_config_t** display_config_list,
+ size_t display_config_count) {
+ ops_->apply_configuration(ctx_, display_config_list, display_config_count);
+ }
+ // Computes the stride (in pixels) necessary for a linear image with the given width
+ // and pixel format. Returns 0 on error.
+ uint32_t ComputeLinearStride(uint32_t width, zx_pixel_format_t pixel_format) {
+ return ops_->compute_linear_stride(ctx_, width, pixel_format);
+ }
+ // Allocates a VMO of the requested size which can be used for images.
+ zx_status_t AllocateVmo(uint64_t size, zx_handle_t* out_vmo) {
+ return ops_->allocate_vmo(ctx_, size, out_vmo);
+ }
+
+private:
+ display_controller_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/ethernet-internal.h b/system/ulib/ddktl/include/ddktl/protocol/ethernet-internal.h
index 449b74f..8416fba 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/ethernet-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/ethernet-internal.h
@@ -1,108 +1,73 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddktl/device-internal.h>
-#include <zircon/types.h>
+#include <ddk/protocol/ethernet.h>
#include <fbl/type_support.h>
-#include <fbl/unique_ptr.h>
-
-#include <stdint.h>
namespace ddk {
-
-class EthmacIfcProxy;
-
namespace internal {
-DECLARE_HAS_MEMBER_FN(has_ethmac_status, EthmacStatus);
-DECLARE_HAS_MEMBER_FN(has_ethmac_recv, EthmacRecv);
-DECLARE_HAS_MEMBER_FN(has_ethmac_complete_tx, EthmacCompleteTx);
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_ifc_status, EthmacIfcStatus,
+ void (C::*)(uint32_t status));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_ifc_recv, EthmacIfcRecv,
+ void (C::*)(const void* data_buffer, size_t data_size,
+ uint32_t flags));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_ifc_complete_tx, EthmacIfcCompleteTx,
+ void (C::*)(ethmac_netbuf_t* netbuf, zx_status_t status));
template <typename D>
-constexpr void CheckEthmacIfc() {
- static_assert(internal::has_ethmac_status<D>::value,
- "EthmacIfc subclasses must implement EthmacStatus");
- static_assert(fbl::is_same<decltype(&D::EthmacStatus),
- void (D::*)(uint32_t)>::value,
- "EthmacStatus must be a non-static member function with signature "
- "'void EthmacStatus(uint32_t)', and be visible to ddk::EthmacIfc<D> "
- "(either because they are public, or because of friendship).");
- static_assert(internal::has_ethmac_recv<D>::value,
- "EthmacIfc subclasses must implement EthmacRecv");
- static_assert(fbl::is_same<decltype(&D::EthmacRecv),
- void (D::*)(void*, size_t, uint32_t)>::value,
- "EthmacQuery must be a non-static member function with signature "
- "'void EthmacRecv(void*, size_t, uint32_t)', and be visible to "
- "ddk::EthmacIfc<D> (either because they are public, or because of "
- "friendship).");
- static_assert(internal::has_ethmac_complete_tx<D>::value,
- "EthmacIfc subclasses must implement EthmacCompleteTx");
- static_assert(fbl::is_same<decltype(&D::EthmacCompleteTx),
- void (D::*)(ethmac_netbuf_t*, zx_status_t)>::value,
- "EthmacCompleteTx must be a non-static member function with signature "
- "'void EthmacCompleteTx(ethmac_netbuf_t*, zx_status_t)', and be visible to "
- "ddk::EthmacIfc<D> (either because they are public, or because of friendship).");
+constexpr void CheckEthmacIfcSubclass() {
+ static_assert(internal::has_ethmac_ifc_status<D>::value,
+ "EthmacIfc subclasses must implement "
+ "void EthmacIfcStatus(uint32_t status");
+ static_assert(internal::has_ethmac_ifc_recv<D>::value,
+ "EthmacIfc subclasses must implement "
+ "void EthmacIfcRecv(const void* data_buffer, size_t data_size, uint32_t flags");
+ static_assert(internal::has_ethmac_ifc_complete_tx<D>::value,
+ "EthmacIfc subclasses must implement "
+ "void EthmacIfcCompleteTx(ethmac_netbuf_t* netbuf, zx_status_t status");
}
-DECLARE_HAS_MEMBER_FN(has_ethmac_query, EthmacQuery);
-DECLARE_HAS_MEMBER_FN(has_ethmac_stop, EthmacStop);
-DECLARE_HAS_MEMBER_FN(has_ethmac_start, EthmacStart);
-DECLARE_HAS_MEMBER_FN(has_ethmac_queue_tx, EthmacQueueTx);
-DECLARE_HAS_MEMBER_FN(has_ethmac_set_param, EthmacSetParam);
-DECLARE_HAS_MEMBER_FN(has_ethmac_get_bti, EthmacGetBti);
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_protocol_query, EthmacQuery,
+ zx_status_t (C::*)(uint32_t options, ethmac_info_t* out_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_protocol_stop, EthmacStop, void (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_protocol_start, EthmacStart,
+ zx_status_t (C::*)(const ethmac_ifc_t* ifc));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_protocol_queue_tx, EthmacQueueTx,
+ zx_status_t (C::*)(uint32_t options, ethmac_netbuf_t* netbuf));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_protocol_set_param, EthmacSetParam,
+ zx_status_t (C::*)(uint32_t param, zx_status_t value,
+ const void* data_buffer, size_t data_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ethmac_protocol_get_bti, EthmacGetBti,
+ zx_handle_t (C::*)());
template <typename D>
constexpr void CheckEthmacProtocolSubclass() {
- static_assert(internal::has_ethmac_query<D>::value,
- "EthmacProtocol subclasses must implement EthmacQuery");
- static_assert(fbl::is_same<decltype(&D::EthmacQuery),
- zx_status_t (D::*)(uint32_t, ethmac_info_t*)>::value,
- "EthmacQuery must be a non-static member function with signature "
- "'zx_status_t EthmacQuery(uint32_t, ethmac_info_t*)', and be visible to "
- "ddk::EthmacProtocol<D> (either because they are public, or because of "
- "friendship).");
- static_assert(internal::has_ethmac_stop<D>::value,
- "EthmacProtocol subclasses must implement EthmacStop");
- static_assert(fbl::is_same<decltype(&D::EthmacStop),
- void (D::*)()>::value,
- "EthmacStop must be a non-static member function with signature "
- "'void EthmacStop()', and be visible to ddk::EthmacProtocol<D> (either "
- "because they are public, or because of friendship).");
- static_assert(internal::has_ethmac_start<D>::value,
- "EthmacProtocol subclasses must implement EthmacStart");
- static_assert(fbl::is_same<decltype(&D::EthmacStart),
- zx_status_t (D::*)(fbl::unique_ptr<EthmacIfcProxy>)>::value,
- "EthmacStart must be a non-static member function with signature "
- "'zx_status_t EthmacStart(fbl::unique_ptr<EthmacIfcProxy>)', and be visible "
- "to ddk::EthmacProtocol<D> (either because they are public, or because of "
- "friendship).");
- static_assert(internal::has_ethmac_queue_tx<D>::value,
- "EthmacProtocol subclasses must implement EthmacQueueTx");
- static_assert(fbl::is_same<decltype(&D::EthmacQueueTx),
- zx_status_t (D::*)(uint32_t, ethmac_netbuf_t*)>::value,
- "EthmacQueueTx must be a non-static member function with signature "
- "'zx_status_t EthmacQueueTx(uint32_t, ethmac_netbuf_t*)', and be visible to "
- "ddk::EthmacProtocol<D> (either because they are public, or because of "
- "friendship).");
- static_assert(internal::has_ethmac_set_param<D>::value,
- "EthmacProtocol subclasses must implement EthmacSetParam");
- static_assert(fbl::is_same<decltype(&D::EthmacSetParam),
- zx_status_t (D::*)(uint32_t, int32_t, void*)>::value,
- "EthmacSetParam must be a non-static member function with signature "
- "'zx_status_t EthmacSetParam(uint32_t, int32_t, void*)', and be visible to "
- "ddk::EthmacProtocol<D> (either because they are public, or because of "
- "friendship).");
- static_assert(internal::has_ethmac_get_bti<D>::value,
- "EthmacProtocol subclasses must implement EthmacGetBti");
- static_assert(fbl::is_same<decltype(&D::EthmacGetBti),
- zx_handle_t (D::*)()>::value,
- "EthmacGetBti must be a non-static member function with signature "
- "'zx_handle_t EthmacGetBti()', and be visible to ddk::EthmacProtocol<D> "
- "(either because they are public, or because of friendship).");
+ static_assert(internal::has_ethmac_protocol_query<D>::value,
+ "EthmacProtocol subclasses must implement "
+ "zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* out_info");
+ static_assert(internal::has_ethmac_protocol_stop<D>::value,
+ "EthmacProtocol subclasses must implement "
+ "void EthmacStop(");
+ static_assert(internal::has_ethmac_protocol_start<D>::value,
+ "EthmacProtocol subclasses must implement "
+ "zx_status_t EthmacStart(const ethmac_ifc_t* ifc");
+ static_assert(internal::has_ethmac_protocol_queue_tx<D>::value,
+ "EthmacProtocol subclasses must implement "
+ "zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf");
+ static_assert(internal::has_ethmac_protocol_set_param<D>::value,
+ "EthmacProtocol subclasses must implement "
+ "zx_status_t EthmacSetParam(uint32_t param, zx_status_t value, const void* "
+ "data_buffer, size_t data_size");
+ static_assert(internal::has_ethmac_protocol_get_bti<D>::value,
+ "EthmacProtocol subclasses must implement "
+ "zx_handle_t EthmacGetBti(");
}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/ethernet.h b/system/ulib/ddktl/include/ddktl/protocol/ethernet.h
index e1dc9a7..f464584 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/ethernet.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/ethernet.h
@@ -1,250 +1,246 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/ethernet.h>
-#include <ddktl/protocol/ethernet-internal.h>
-#include <fbl/type_support.h>
-#include <fbl/unique_ptr.h>
+#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/listnode.h>
+#include <zircon/types.h>
-// DDK ethernet protocol support
+#include "ethernet-internal.h"
+
+// DDK ethmac-protocol support
//
// :: Proxies ::
//
-// ddk::EthmacIfcProxy and ddk::EthmacProtocolProxy are simple wrappers around ethmac_ifc_t and
-// ethmac_protocol_t, respectively. They do not own the pointers passed to them.
+// ddk::EthmacProtocolProxy is a simple wrapper around
+// ethmac_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::EthmacIfc and ddk::EthmacProtocol are mixin classes that simplify writing DDK drivers that
-// interact with the ethernet protocol. They take care of implementing the function pointer tables
-// and calling into the object that wraps them.
+// ddk::EthmacProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the ethmac protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
-// // A driver that communicates with a ZX_PROTOCOL_ETHERNET_IMPL device as a ethmac_ifc_t
-// class EthDevice;
-// using EthDeviceType = ddk::Device<EthDevice, /* ddk mixins */>;
-//
-// class EthDevice : public EthDeviceType,
-// public ddk::EthmacIfc<EthDevice> {
-// public:
-// EthDevice(zx_device_t* parent)
-// : EthDeviceType("my-eth-device"),
-// parent_(parent) {}
-//
-// zx_status_t Bind() {
-// ethmac_protocol_t* ops;
-// auto status = get_device_protocol(parent_, ZX_PROTOCOL_ETHERNET_IMPL,
-// reinterpret_cast<void**>(&ops));
-// if (status != ZX_OK) {
-// return status;
-// }
-// proxy_.reset(new ddk::EthmacProtocolProxy(ops, parent_));
-// status = proxy_->Start(this);
-// if (status != ZX_OK) {
-// return status;
-// }
-// return device_add(ddk_device(), parent_);
-// }
-//
-// void DdkRelease() {
-// // Clean up
-// }
-//
-// void EthmacStatus(uint32_t status) {
-// // Report status
-// }
-//
-// void EthmacRecv(void* buf, size_t length, uint32_t flags) {
-// // Receive data buffer from ethmac device
-// }
-//
-// private:
-// zx_device_t* parent_;
-// fbl::unique_ptr<ddk::EthmacProtocolProxy> proxy_;
-// };
-//
-//
-// // A driver that implements a ZX_PROTOCOL_ETHERNET_IMPL device
-// class EthmacDevice;
+// // A driver that implements a ZX_PROTOCOL_ETHMAC device.
+// class EthmacDevice {
// using EthmacDeviceType = ddk::Device<EthmacDevice, /* ddk mixins */>;
//
// class EthmacDevice : public EthmacDeviceType,
// public ddk::EthmacProtocol<EthmacDevice> {
// public:
// EthmacDevice(zx_device_t* parent)
-// : EthmacDeviceType("my-ethmac-device"),
-// parent_(parent) {}
+// : EthmacDeviceType("my-ethmac-protocol-device", parent) {}
//
-// zx_status_t Bind() {
-// return device_add(ddk_device(), parent_);
-// }
+// zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* out_info);
//
-// void DdkRelease() {
-// // Clean up
-// }
+// void EthmacStop();
//
-// zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* info) {
-// // Fill out the ethmac info
-// return ZX_OK;
-// }
+// zx_status_t EthmacStart(const ethmac_ifc_t* ifc);
//
-// void EthmacStop() {
-// // Device should stop
-// }
+// zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf);
//
-// zx_status_t EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy) {
-// // Start ethmac operation
-// proxy_.swap(proxy);
-// return ZX_OK;
-// }
+// zx_status_t EthmacSetParam(uint32_t param, zx_status_t value, const void* data_buffer, size_t
+// data_size);
//
-// zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf) {
-// // Send the data
-// return ZX_OK;
-// }
+// zx_handle_t EthmacGetBti();
//
-// zx_status_t EthmacSetParam(uint32_t param, int32_t value, void* data) {
-// // Set the parameter
-// return ZX_OK;
-// }
-//
-// private:
-// zx_device_t* parent_;
-// fbl::unique_ptr<ddk::EthmacIfcProxy> proxy_;
+// ...
// };
namespace ddk {
template <typename D>
-class EthmacIfc {
+class EthmacIfc : public internal::base_mixin {
public:
EthmacIfc() {
- internal::CheckEthmacIfc<D>();
- ifc_.status = Status;
- ifc_.recv = Recv;
- ifc_.complete_tx = CompleteTx;
+ internal::CheckEthmacIfcSubclass<D>();
+ ethmac_ifc_ops_.status = EthmacIfcStatus;
+ ethmac_ifc_ops_.recv = EthmacIfcRecv;
+ ethmac_ifc_ops_.complete_tx = EthmacIfcCompleteTx;
}
- ethmac_ifc_t* ethmac_ifc() { return &ifc_; }
+protected:
+ ethmac_ifc_ops_t ethmac_ifc_ops_ = {};
private:
- static void Status(void* cookie, uint32_t status) {
- static_cast<D*>(cookie)->EthmacStatus(status);
+ static void EthmacIfcStatus(void* ctx, uint32_t status) {
+ static_cast<D*>(ctx)->EthmacIfcStatus(status);
}
-
- static void Recv(void* cookie, void* data, size_t length, uint32_t flags) {
- static_cast<D*>(cookie)->EthmacRecv(data, length, flags);
+ static void EthmacIfcRecv(void* ctx, const void* data_buffer, size_t data_size,
+ uint32_t flags) {
+ static_cast<D*>(ctx)->EthmacIfcRecv(data_buffer, data_size, flags);
}
-
- static void CompleteTx(void* cookie, ethmac_netbuf_t* netbuf, zx_status_t status) {
- static_cast<D*>(cookie)->EthmacCompleteTx(netbuf, status);
+ // complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
+ // Return status indicates queue state:
+ // ZX_OK: Packet has been enqueued.
+ // Other: Packet could not be enqueued.
+ // Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
+ // the completion state of the transmission itself.
+ static void EthmacIfcCompleteTx(void* ctx, ethmac_netbuf_t* netbuf, zx_status_t status) {
+ static_cast<D*>(ctx)->EthmacIfcCompleteTx(netbuf, status);
}
-
- ethmac_ifc_t ifc_ = {};
};
class EthmacIfcProxy {
public:
- EthmacIfcProxy(ethmac_ifc_t* ifc, void* cookie)
- : ifc_(ifc), cookie_(cookie) {}
+ EthmacIfcProxy() : ops_(nullptr), ctx_(nullptr) {}
+ EthmacIfcProxy(const ethmac_ifc_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
- void Status(uint32_t status) {
- ifc_->status(cookie_, status);
+ void GetProto(ethmac_ifc_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
-
- void Recv(void* data, size_t length, uint32_t flags) {
- ifc_->recv(cookie_, data, length, flags);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
-
+ void Status(uint32_t status) { ops_->status(ctx_, status); }
+ void Recv(const void* data_buffer, size_t data_size, uint32_t flags) {
+ ops_->recv(ctx_, data_buffer, data_size, flags);
+ }
+ // complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
+ // Return status indicates queue state:
+ // ZX_OK: Packet has been enqueued.
+ // Other: Packet could not be enqueued.
+ // Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
+ // the completion state of the transmission itself.
void CompleteTx(ethmac_netbuf_t* netbuf, zx_status_t status) {
- ifc_->complete_tx(cookie_, netbuf, status);
+ ops_->complete_tx(ctx_, netbuf, status);
}
private:
- ethmac_ifc_t* ifc_;
- void* cookie_;
+ ethmac_ifc_ops_t* ops_;
+ void* ctx_;
};
+// The ethernet midlayer will never call ethermac_protocol
+// methods from multiple threads simultaneously, but it
+// can call send() methods at the same time as non-send
+// methods.
template <typename D>
-class EthmacProtocol : public internal::base_protocol {
+class EthmacProtocol : public internal::base_mixin {
public:
EthmacProtocol() {
internal::CheckEthmacProtocolSubclass<D>();
- ops_.query = Query;
- ops_.stop = Stop;
- ops_.start = Start;
- ops_.queue_tx = QueueTx;
- ops_.set_param = SetParam;
- ops_.get_bti = GetBti;
-
- // Can only inherit from one base_protocol implemenation
- ZX_ASSERT(ddk_proto_id_ == 0);
- ddk_proto_id_ = ZX_PROTOCOL_ETHERNET_IMPL;
- ddk_proto_ops_ = &ops_;
+ ethmac_protocol_ops_.query = EthmacQuery;
+ ethmac_protocol_ops_.stop = EthmacStop;
+ ethmac_protocol_ops_.start = EthmacStart;
+ ethmac_protocol_ops_.queue_tx = EthmacQueueTx;
+ ethmac_protocol_ops_.set_param = EthmacSetParam;
+ ethmac_protocol_ops_.get_bti = EthmacGetBti;
}
+protected:
+ ethmac_protocol_ops_t ethmac_protocol_ops_ = {};
+
private:
- static zx_status_t Query(void* ctx, uint32_t options, ethmac_info_t* info) {
- return static_cast<D*>(ctx)->EthmacQuery(options, info);
+ // Obtain information about the ethermac device and supported features
+ // Safe to call at any time.
+ static zx_status_t EthmacQuery(void* ctx, uint32_t options, ethmac_info_t* out_info) {
+ return static_cast<D*>(ctx)->EthmacQuery(options, out_info);
}
-
- static void Stop(void* ctx) {
- static_cast<D*>(ctx)->EthmacStop();
+ // Shut down a running ethermac
+ // Safe to call if the ethermac is already stopped.
+ static void EthmacStop(void* ctx) { static_cast<D*>(ctx)->EthmacStop(); }
+ // Start ethermac running with ifc_virt
+ // Callbacks on ifc may be invoked from now until stop() is called
+ static zx_status_t EthmacStart(void* ctx, const ethmac_ifc_t* ifc) {
+ return static_cast<D*>(ctx)->EthmacStart(ifc);
}
-
- static zx_status_t Start(void* ctx, ethmac_ifc_t* ifc, void* cookie) {
- auto ifc_proxy = fbl::unique_ptr<EthmacIfcProxy>(new EthmacIfcProxy(ifc, cookie));
- return static_cast<D*>(ctx)->EthmacStart(fbl::move(ifc_proxy));
- }
-
- static zx_status_t QueueTx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
+ // Request transmission of the packet in netbuf. Return status indicates queue state:
+ // ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
+ // ZX_OK: Packet has been enqueued.
+ // Other: Packet could not be enqueued.
+ // In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
+ // to return it once the enqueue is complete. complete_tx() may be used to return the packet
+ // before transmission itself completes, but MUST NOT be called from within the queue_tx()
+ // implementation.
+ // queue_tx() may be called at any time after start() is called including from multiple threads
+ // simultaneously.
+ static zx_status_t EthmacQueueTx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
return static_cast<D*>(ctx)->EthmacQueueTx(options, netbuf);
}
-
- static zx_status_t SetParam(void* ctx, uint32_t param, int32_t value, void* data) {
- return static_cast<D*>(ctx)->EthmacSetParam(param, value, data);
+ // Request a settings change for the driver. Return status indicates disposition:
+ // ZX_OK: Request has been handled.
+ // ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
+ // Other: Error trying to support this request.
+ // |value| and |data| usage are defined for each |param|; see comments above.
+ // set_param() may be called at any time after start() is called including from multiple threads
+ // simultaneously.
+ static zx_status_t EthmacSetParam(void* ctx, uint32_t param, zx_status_t value,
+ const void* data_buffer, size_t data_size) {
+ return static_cast<D*>(ctx)->EthmacSetParam(param, value, data_buffer, data_size);
}
-
- static zx_handle_t GetBti(void* ctx) {
- return static_cast<D*>(ctx)->EthmacGetBti();
- }
-
- ethmac_protocol_ops_t ops_ = {};
+ // Get the BTI handle (needed to pin DMA memory) for this device.
+ // This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
+ // The caller does *not* take ownership of the BTI handle and must never close
+ // the handle.
+ static zx_handle_t EthmacGetBti(void* ctx) { return static_cast<D*>(ctx)->EthmacGetBti(); }
};
class EthmacProtocolProxy {
public:
- EthmacProtocolProxy(ethmac_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ EthmacProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ EthmacProtocolProxy(const ethmac_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
- zx_status_t Query(uint32_t options, ethmac_info_t* info) {
- return ops_->query(ctx_, options, info);
+ void GetProto(ethmac_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
-
- template <typename D>
- zx_status_t Start(D* ifc) {
- static_assert(fbl::is_base_of<EthmacIfc<D>, D>::value,
- "Start must be called with a subclass of EthmacIfc");
- return ops_->start(ctx_, ifc->ethmac_ifc(), ifc);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
-
- void Stop() {
- ops_->stop(ctx_);
+ // Obtain information about the ethermac device and supported features
+ // Safe to call at any time.
+ zx_status_t Query(uint32_t options, ethmac_info_t* out_info) {
+ return ops_->query(ctx_, options, out_info);
}
-
+ // Shut down a running ethermac
+ // Safe to call if the ethermac is already stopped.
+ void Stop() { ops_->stop(ctx_); }
+ // Start ethermac running with ifc_virt
+ // Callbacks on ifc may be invoked from now until stop() is called
+ zx_status_t Start(const ethmac_ifc_t* ifc) { return ops_->start(ctx_, ifc); }
+ // Request transmission of the packet in netbuf. Return status indicates queue state:
+ // ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
+ // ZX_OK: Packet has been enqueued.
+ // Other: Packet could not be enqueued.
+ // In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
+ // to return it once the enqueue is complete. complete_tx() may be used to return the packet
+ // before transmission itself completes, but MUST NOT be called from within the queue_tx()
+ // implementation.
+ // queue_tx() may be called at any time after start() is called including from multiple threads
+ // simultaneously.
zx_status_t QueueTx(uint32_t options, ethmac_netbuf_t* netbuf) {
return ops_->queue_tx(ctx_, options, netbuf);
}
-
- zx_status_t SetParam(uint32_t param, int32_t value, void* data) {
- return ops_->set_param(ctx_, param, value, data);
+ // Request a settings change for the driver. Return status indicates disposition:
+ // ZX_OK: Request has been handled.
+ // ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
+ // Other: Error trying to support this request.
+ // |value| and |data| usage are defined for each |param|; see comments above.
+ // set_param() may be called at any time after start() is called including from multiple threads
+ // simultaneously.
+ zx_status_t SetParam(uint32_t param, zx_status_t value, const void* data_buffer,
+ size_t data_size) {
+ return ops_->set_param(ctx_, param, value, data_buffer, data_size);
}
+ // Get the BTI handle (needed to pin DMA memory) for this device.
+ // This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
+ // The caller does *not* take ownership of the BTI handle and must never close
+ // the handle.
+ zx_handle_t GetBti() { return ops_->get_bti(ctx_); }
private:
ethmac_protocol_ops_t* ops_;
diff --git a/system/ulib/ddktl/include/ddktl/protocol/gpio-internal.h b/system/ulib/ddktl/include/ddktl/protocol/gpio-internal.h
index a4c0d43..293e333 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/gpio-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/gpio-internal.h
@@ -2,57 +2,62 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/gpio.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_config_in, GpioConfigIn,
- zx_status_t (C::*)(uint32_t, uint32_t));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_config_out, GpioConfigOut,
- zx_status_t (C::*)(uint32_t, uint8_t));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_set_alt_function, GpioSetAltFunction,
- zx_status_t (C::*)(uint32_t, uint64_t));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_read, GpioRead,
- zx_status_t (C::*)(uint32_t, uint8_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_write, GpioWrite,
- zx_status_t (C::*)(uint32_t, uint8_t));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_get_interrupt, GpioGetInterrupt,
- zx_status_t (C::*)(uint32_t, uint32_t, zx_handle_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_release_interrupt, GpioReleaseInterrupt,
- zx_status_t (C::*)(uint32_t));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_set_polarity, GpioSetPolarity,
- zx_status_t (C::*)(uint32_t, uint32_t));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_config_in, GpioConfigIn,
+ zx_status_t (C::*)(uint32_t index, uint32_t flags));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_config_out, GpioConfigOut,
+ zx_status_t (C::*)(uint32_t index, uint8_t initial_value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_set_alt_function, GpioSetAltFunction,
+ zx_status_t (C::*)(uint32_t index, uint64_t function));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_read, GpioRead,
+ zx_status_t (C::*)(uint32_t index, uint8_t* out_value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_write, GpioWrite,
+ zx_status_t (C::*)(uint32_t index, uint8_t value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_get_interrupt, GpioGetInterrupt,
+ zx_status_t (C::*)(uint32_t index, uint32_t flags,
+ zx_handle_t* out_irq));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_release_interrupt, GpioReleaseInterrupt,
+ zx_status_t (C::*)(uint32_t index));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_gpio_protocol_set_polarity, GpioSetPolarity,
+ zx_status_t (C::*)(uint32_t index, gpio_polarity_t polarity));
template <typename D>
constexpr void CheckGpioProtocolSubclass() {
- static_assert(internal::has_gpio_config_in<D>::value,
+ static_assert(internal::has_gpio_protocol_config_in<D>::value,
"GpioProtocol subclasses must implement "
- "GpioConfigIn(uint32_t index, uint32_t flags)");
- static_assert(internal::has_gpio_config_out<D>::value,
+ "zx_status_t GpioConfigIn(uint32_t index, uint32_t flags");
+ static_assert(internal::has_gpio_protocol_config_out<D>::value,
"GpioProtocol subclasses must implement "
- "GpioConfigOut(uint32_t index, uint8_t initial_value)");
- static_assert(internal::has_gpio_set_alt_function<D>::value,
+ "zx_status_t GpioConfigOut(uint32_t index, uint8_t initial_value");
+ static_assert(internal::has_gpio_protocol_set_alt_function<D>::value,
"GpioProtocol subclasses must implement "
- "GpioSetAltFunction(uint32_t index, uint64_t function)");
- static_assert(internal::has_gpio_read<D>::value,
+ "zx_status_t GpioSetAltFunction(uint32_t index, uint64_t function");
+ static_assert(internal::has_gpio_protocol_read<D>::value,
"GpioProtocol subclasses must implement "
- "GpioRead(uint32_t index, uint8_t* out_value)");
- static_assert(internal::has_gpio_write<D>::value,
+ "zx_status_t GpioRead(uint32_t index, uint8_t* out_value");
+ static_assert(internal::has_gpio_protocol_write<D>::value,
"GpioProtocol subclasses must implement "
- "GpioWrite(uint32_t index, uint8_t value)");
- static_assert(internal::has_gpio_get_interrupt<D>::value,
+ "zx_status_t GpioWrite(uint32_t index, uint8_t value");
+ static_assert(
+ internal::has_gpio_protocol_get_interrupt<D>::value,
+ "GpioProtocol subclasses must implement "
+ "zx_status_t GpioGetInterrupt(uint32_t index, uint32_t flags, zx_handle_t* out_irq");
+ static_assert(internal::has_gpio_protocol_release_interrupt<D>::value,
"GpioProtocol subclasses must implement "
- "GpioGetInterrupt(uint32_t index, uint32_t flags, zx_handle_t* out_handle)");
- static_assert(internal::has_gpio_release_interrupt<D>::value,
+ "zx_status_t GpioReleaseInterrupt(uint32_t index");
+ static_assert(internal::has_gpio_protocol_set_polarity<D>::value,
"GpioProtocol subclasses must implement "
- "GpioReleaseInterrupt(uint32_t index)");
- static_assert(internal::has_gpio_set_polarity<D>::value,
- "GpioProtocol subclasses must implement "
- "GpioSetPolarity(uint32_t index, uint32_t polarity)");
- }
+ "zx_status_t GpioSetPolarity(uint32_t index, gpio_polarity_t polarity");
+}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/gpio.h b/system/ulib/ddktl/include/ddktl/protocol/gpio.h
index 6c5ae88..853228a 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/gpio.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/gpio.h
@@ -2,135 +2,163 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/gpio.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "gpio-internal.h"
-// DDK GPIO protocol support.
+// DDK gpio-protocol support
//
// :: Proxies ::
//
-// ddk::GpioProtocolProxy is a simple wrappers around gpio_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::GpioProtocolProxy is a simple wrapper around
+// gpio_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::GpioProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the GPIO protocol.
+// ddk::GpioProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the gpio protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_GPIO device.
-// class GpioDevice;
+// class GpioDevice {
// using GpioDeviceType = ddk::Device<GpioDevice, /* ddk mixins */>;
//
// class GpioDevice : public GpioDeviceType,
// public ddk::GpioProtocol<GpioDevice> {
// public:
// GpioDevice(zx_device_t* parent)
-// : GpioDeviceType("my-gpio-device", parent) {}
+// : GpioDeviceType("my-gpio-protocol-device", parent) {}
//
// zx_status_t GpioConfigIn(uint32_t index, uint32_t flags);
+//
// zx_status_t GpioConfigOut(uint32_t index, uint8_t initial_value);
+//
// zx_status_t GpioSetAltFunction(uint32_t index, uint64_t function);
+//
// zx_status_t GpioRead(uint32_t index, uint8_t* out_value);
+//
// zx_status_t GpioWrite(uint32_t index, uint8_t value);
-// zx_status_t GpioGetInterrupt(uint32_t index, uint32_t flags, zx_handle_t *out_handle);
+//
+// zx_status_t GpioGetInterrupt(uint32_t index, uint32_t flags, zx_handle_t* out_irq);
+//
// zx_status_t GpioReleaseInterrupt(uint32_t index);
-// zx_status_t GpioSetPolarity(uint32_t index, uint32_t polarity);
+//
+// zx_status_t GpioSetPolarity(uint32_t index, gpio_polarity_t polarity);
+//
// ...
// };
namespace ddk {
+// In the functions below, the GPIO index is relative to the list of GPIOs for the device.
+// For example, the list of GPIOs a platform device has access to would likely be a small
+// subset of the total number of GPIOs, while a platform bus implementation driver would
+// have access to the complete set of GPIOs.
template <typename D>
-class GpioProtocol : public internal::base_protocol {
+class GpioProtocol : public internal::base_mixin {
public:
GpioProtocol() {
internal::CheckGpioProtocolSubclass<D>();
- ops_.config_in = GpioConfigIn;
- ops_.config_out = GpioConfigOut;
- ops_.set_alt_function = GpioSetAltFunction;
- ops_.read = GpioRead;
- ops_.write = GpioWrite;
- ops_.get_interrupt = GpioGetInterrupt;
- ops_.release_interrupt = GpioReleaseInterrupt;
- ops_.set_polarity = GpioSetPolarity;
-
- // Can only inherit from one base_protocol implemenation
- ZX_ASSERT(ddk_proto_id_ == 0);
- ddk_proto_id_ = ZX_PROTOCOL_GPIO;
- ddk_proto_ops_ = &ops_;
+ gpio_protocol_ops_.config_in = GpioConfigIn;
+ gpio_protocol_ops_.config_out = GpioConfigOut;
+ gpio_protocol_ops_.set_alt_function = GpioSetAltFunction;
+ gpio_protocol_ops_.read = GpioRead;
+ gpio_protocol_ops_.write = GpioWrite;
+ gpio_protocol_ops_.get_interrupt = GpioGetInterrupt;
+ gpio_protocol_ops_.release_interrupt = GpioReleaseInterrupt;
+ gpio_protocol_ops_.set_polarity = GpioSetPolarity;
}
protected:
- gpio_protocol_ops_t ops_ = {};
+ gpio_protocol_ops_t gpio_protocol_ops_ = {};
private:
+ // Configures a GPIO for input.
static zx_status_t GpioConfigIn(void* ctx, uint32_t index, uint32_t flags) {
return static_cast<D*>(ctx)->GpioConfigIn(index, flags);
}
+ // Configures a GPIO for output.
static zx_status_t GpioConfigOut(void* ctx, uint32_t index, uint8_t initial_value) {
return static_cast<D*>(ctx)->GpioConfigOut(index, initial_value);
}
+ // Configures the GPIO pin for an alternate function (I2C, SPI, etc)
+ // the interpretation of "function" is platform dependent.
static zx_status_t GpioSetAltFunction(void* ctx, uint32_t index, uint64_t function) {
return static_cast<D*>(ctx)->GpioSetAltFunction(index, function);
}
+ // Reads the current value of a GPIO (0 or 1).
static zx_status_t GpioRead(void* ctx, uint32_t index, uint8_t* out_value) {
return static_cast<D*>(ctx)->GpioRead(index, out_value);
}
+ // Sets the current value of the GPIO (any non-zero value maps to 1).
static zx_status_t GpioWrite(void* ctx, uint32_t index, uint8_t value) {
return static_cast<D*>(ctx)->GpioWrite(index, value);
}
+ // Gets an interrupt object pertaining to a particular GPIO pin.
static zx_status_t GpioGetInterrupt(void* ctx, uint32_t index, uint32_t flags,
- zx_handle_t* out_handle) {
- return static_cast<D*>(ctx)->GpioGetInterrupt(index, flags, out_handle);
+ zx_handle_t* out_irq) {
+ return static_cast<D*>(ctx)->GpioGetInterrupt(index, flags, out_irq);
}
+ // Release the interrupt.
static zx_status_t GpioReleaseInterrupt(void* ctx, uint32_t index) {
return static_cast<D*>(ctx)->GpioReleaseInterrupt(index);
}
- static zx_status_t GpioSetPolarity(void* ctx, uint32_t index, uint32_t polarity) {
+ // Set GPIO polarity.
+ static zx_status_t GpioSetPolarity(void* ctx, uint32_t index, gpio_polarity_t polarity) {
return static_cast<D*>(ctx)->GpioSetPolarity(index, polarity);
}
};
class GpioProtocolProxy {
public:
- GpioProtocolProxy(gpio_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ GpioProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ GpioProtocolProxy(const gpio_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(gpio_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
-
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Configures a GPIO for input.
zx_status_t ConfigIn(uint32_t index, uint32_t flags) {
return ops_->config_in(ctx_, index, flags);
}
+ // Configures a GPIO for output.
zx_status_t ConfigOut(uint32_t index, uint8_t initial_value) {
return ops_->config_out(ctx_, index, initial_value);
}
+ // Configures the GPIO pin for an alternate function (I2C, SPI, etc)
+ // the interpretation of "function" is platform dependent.
zx_status_t SetAltFunction(uint32_t index, uint64_t function) {
return ops_->set_alt_function(ctx_, index, function);
}
+ // Reads the current value of a GPIO (0 or 1).
zx_status_t Read(uint32_t index, uint8_t* out_value) {
return ops_->read(ctx_, index, out_value);
}
- zx_status_t Write(uint32_t index, uint8_t value) {
- return ops_->write(ctx_, index, value);
+ // Sets the current value of the GPIO (any non-zero value maps to 1).
+ zx_status_t Write(uint32_t index, uint8_t value) { return ops_->write(ctx_, index, value); }
+ // Gets an interrupt object pertaining to a particular GPIO pin.
+ zx_status_t GetInterrupt(uint32_t index, uint32_t flags, zx_handle_t* out_irq) {
+ return ops_->get_interrupt(ctx_, index, flags, out_irq);
}
- zx_status_t GetInterrupt(uint32_t index, uint32_t flags, zx_handle_t* out_handle) {
- return ops_->get_interrupt(ctx_, index, flags, out_handle);
- }
- zx_status_t ReleaseInterrupt(uint32_t index) {
- return ops_->release_interrupt(ctx_, index);
- }
- zx_status_t SetPolarity(uint32_t index, uint32_t polarity) {
+ // Release the interrupt.
+ zx_status_t ReleaseInterrupt(uint32_t index) { return ops_->release_interrupt(ctx_, index); }
+ // Set GPIO polarity.
+ zx_status_t SetPolarity(uint32_t index, gpio_polarity_t polarity) {
return ops_->set_polarity(ctx_, index, polarity);
}
diff --git a/system/ulib/ddktl/include/ddktl/protocol/hidbus-internal.h b/system/ulib/ddktl/include/ddktl/protocol/hidbus-internal.h
index e995637..71a45c3 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/hidbus-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/hidbus-internal.h
@@ -1,125 +1,87 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddktl/device-internal.h>
-#include <zircon/types.h>
+#include <ddk/protocol/hidbus.h>
#include <fbl/type_support.h>
-#include <fbl/unique_ptr.h>
-
-#include <stdint.h>
namespace ddk {
-
-class HidBusIfcProxy;
-
namespace internal {
-DECLARE_HAS_MEMBER_FN(has_hidbus_query, HidBusQuery);
-DECLARE_HAS_MEMBER_FN(has_hidbus_start, HidBusStart);
-DECLARE_HAS_MEMBER_FN(has_hidbus_stop, HidBusStop);
-DECLARE_HAS_MEMBER_FN(has_hidbus_get_descriptor, HidBusGetDescriptor);
-DECLARE_HAS_MEMBER_FN(has_hidbus_get_report, HidBusGetReport);
-DECLARE_HAS_MEMBER_FN(has_hidbus_set_report, HidBusSetReport);
-DECLARE_HAS_MEMBER_FN(has_hidbus_get_idle, HidBusGetIdle);
-DECLARE_HAS_MEMBER_FN(has_hidbus_set_idle, HidBusSetIdle);
-DECLARE_HAS_MEMBER_FN(has_hidbus_get_protocol, HidBusGetProtocol);
-DECLARE_HAS_MEMBER_FN(has_hidbus_set_protocol, HidBusSetProtocol);
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_ifc_io_queue, HidbusIfcIoQueue,
+ void (C::*)(const void* buf_buffer, size_t buf_size));
template <typename D>
-constexpr void CheckHidBusProtocolSubclass() {
- static_assert(internal::has_hidbus_query<D>::value,
- "HidBusProtocol subclasses must implement HidBusQuery");
- static_assert(fbl::is_same<decltype(&D::HidBusQuery),
- zx_status_t (D::*)(uint32_t options, hid_info_t* info)>::value,
- "HidBusQuery must be a non-static member function with signature "
- "'zx_status_t HidBusQuery(uint32_t options, hid_info_t* info)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_start<D>::value,
- "HidBusProtocol subclasses must implement HidBusStart");
- static_assert(fbl::is_same<decltype(&D::HidBusStart),
- zx_status_t (D::*)(HidBusIfcProxy proxy)>::value,
- "HidBusStart must be a non-static member function with signature "
- "'zx_status_t HidBusStart(HidBusIfcProxy proxy)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_stop<D>::value,
- "HidBusProtocol subclasses must implement HidBusStop");
- static_assert(fbl::is_same<decltype(&D::HidBusStop),
- void (D::*)()>::value,
- "HidBusStop must be a non-static member function with signature "
- "'void HidBusStop()', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_get_descriptor<D>::value,
- "HidBusProtocol subclasses must implement HidBusGetDescriptor");
- static_assert(fbl::is_same<decltype(&D::HidBusGetDescriptor),
- zx_status_t (D::*)(uint8_t desc_type, void** data, size_t* len)>::value,
- "HidBusGetDescriptor must be a non-static member function with signature "
- "'zx_status_t HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_get_report<D>::value,
- "HidBusProtocol subclasses must implement HidBusGetReport");
- static_assert(fbl::is_same<decltype(&D::HidBusGetReport),
- zx_status_t (D::*)(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len, size_t* out_len)>::value,
- "HidBusGetReport must be a non-static member function with signature "
- "'zx_status_t HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len, size_t* out_len)',"
- " and be visible to ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_set_report<D>::value,
- "HidBusProtocol subclasses must implement HidBusSetReport");
- static_assert(fbl::is_same<decltype(&D::HidBusSetReport),
- zx_status_t (D::*)(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len)>::value,
- "HidBusSetReport must be a non-static member function with signature "
- "'zx_status_t HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_get_idle<D>::value,
- "HidBusProtocol subclasses must implement HidBusGetIdle");
- static_assert(fbl::is_same<decltype(&D::HidBusGetIdle),
- zx_status_t (D::*)(uint8_t rpt_id, uint8_t* duration)>::value,
- "HidBusGetIdle must be a non-static member function with signature "
- "'zx_status_t HidBusGetIdle(uint8_t rpt_id, uint8_t* duration)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_set_idle<D>::value,
- "HidBusProtocol subclasses must implement HidBusSetIdle");
- static_assert(fbl::is_same<decltype(&D::HidBusSetIdle),
- zx_status_t (D::*)(uint8_t rpt_id, uint8_t duration)>::value,
- "HidBusSetIdle must be a non-static member function with signature "
- "'zx_status_t HidBusSetIdle(uint8_t rpt_id, uint8_t duration)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_get_protocol<D>::value,
- "HidBusProtocol subclasses must implement HidBusGetProtocol");
- static_assert(fbl::is_same<decltype(&D::HidBusGetProtocol),
- zx_status_t (D::*)(uint8_t* protocol)>::value,
- "HidBusGetProtocol must be a non-static member function with signature "
- "'zx_status_t HidBusGetProtocol(uint8_t* protocol)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
-
- static_assert(internal::has_hidbus_set_protocol<D>::value,
- "HidBusProtocol subclasses must implement HidBusSetProtocol");
- static_assert(fbl::is_same<decltype(&D::HidBusSetProtocol),
- zx_status_t (D::*)(uint8_t protocol)>::value,
- "HidBusSetProtocol must be a non-static member function with signature "
- "'zx_status_t HidBusSetProtocol(uint8_t protocol)', and be visible to "
- "ddk::HidBusProtocol<D> (either because they are public, or because of "
- "friendship).");
+constexpr void CheckHidbusIfcSubclass() {
+ static_assert(internal::has_hidbus_ifc_io_queue<D>::value,
+ "HidbusIfc subclasses must implement "
+ "void HidbusIfcIoQueue(const void* buf_buffer, size_t buf_size");
}
-} // namespace internal
-} // namespace ddk
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_query, HidbusQuery,
+ zx_status_t (C::*)(uint32_t options, hid_info_t* out_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_start, HidbusStart,
+ zx_status_t (C::*)(const hidbus_ifc_t* ifc));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_stop, HidbusStop, void (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_get_descriptor, HidbusGetDescriptor,
+ zx_status_t (C::*)(hid_description_type_t desc_type,
+ void** out_data_buffer, size_t* data_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_get_report, HidbusGetReport,
+ zx_status_t (C::*)(hid_report_type_t rpt_type, uint8_t rpt_id,
+ void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_set_report, HidbusSetReport,
+ zx_status_t (C::*)(hid_report_type_t rpt_type, uint8_t rpt_id,
+ const void* data_buffer, size_t data_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_get_idle, HidbusGetIdle,
+ zx_status_t (C::*)(uint8_t rpt_id, uint8_t* out_duration));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_set_idle, HidbusSetIdle,
+ zx_status_t (C::*)(uint8_t rpt_id, uint8_t duration));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_get_protocol, HidbusGetProtocol,
+ zx_status_t (C::*)(hid_protocol_t* out_protocol));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_hidbus_protocol_set_protocol, HidbusSetProtocol,
+ zx_status_t (C::*)(hid_protocol_t protocol));
+
+template <typename D>
+constexpr void CheckHidbusProtocolSubclass() {
+ static_assert(internal::has_hidbus_protocol_query<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusQuery(uint32_t options, hid_info_t* out_info");
+ static_assert(internal::has_hidbus_protocol_start<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusStart(const hidbus_ifc_t* ifc");
+ static_assert(internal::has_hidbus_protocol_stop<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "void HidbusStop(");
+ static_assert(internal::has_hidbus_protocol_get_descriptor<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusGetDescriptor(hid_description_type_t desc_type, void** "
+ "out_data_buffer, size_t* data_size");
+ static_assert(internal::has_hidbus_protocol_get_report<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusGetReport(hid_report_type_t rpt_type, uint8_t rpt_id, void* "
+ "out_data_buffer, size_t data_size, size_t* out_data_actual");
+ static_assert(internal::has_hidbus_protocol_set_report<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusSetReport(hid_report_type_t rpt_type, uint8_t rpt_id, const "
+ "void* data_buffer, size_t data_size");
+ static_assert(internal::has_hidbus_protocol_get_idle<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* out_duration");
+ static_assert(internal::has_hidbus_protocol_set_idle<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration");
+ static_assert(internal::has_hidbus_protocol_get_protocol<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusGetProtocol(hid_protocol_t* out_protocol");
+ static_assert(internal::has_hidbus_protocol_set_protocol<D>::value,
+ "HidbusProtocol subclasses must implement "
+ "zx_status_t HidbusSetProtocol(hid_protocol_t protocol");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/hidbus.h b/system/ulib/ddktl/include/ddktl/protocol/hidbus.h
index a7a5336..2d29ce4 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/hidbus.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/hidbus.h
@@ -1,160 +1,231 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/hidbus.h>
-#include <ddktl/protocol/hidbus-internal.h>
-#include <fbl/type_support.h>
-#include <fbl/unique_ptr.h>
+#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
-// DDK hidbus protocol support
+#include "hidbus-internal.h"
+
+// DDK hidbus-protocol support
//
// :: Proxies ::
//
-// ddk::HidBusIfcProxy is simple wrappers around hidbus_ifc_t. It does not own the pointers passed
-// to it.
+// ddk::HidbusProtocolProxy is a simple wrapper around
+// hidbus_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::HidBusProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the hidbus protocol. They take care of implementing the function pointer tables
-// and calling into the object that wraps them.
+// ddk::HidbusProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the hidbus protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
-// // A driver that implements a ZX_PROTOCOL_HIDBUS device
-// class HidBusDevice;
-// using HidBusDeviceType = ddk::Device<HidBusDevice, /* ddk mixins */>;
+// // A driver that implements a ZX_PROTOCOL_HIDBUS device.
+// class HidbusDevice {
+// using HidbusDeviceType = ddk::Device<HidbusDevice, /* ddk mixins */>;
//
-// class HidBusDevice : public HidBusDeviceType,
-// public ddk::HidBusProtocol<HidBusDevice> {
+// class HidbusDevice : public HidbusDeviceType,
+// public ddk::HidbusProtocol<HidbusDevice> {
// public:
-// HidBusDevice(zx_device_t* parent)
-// : HidBusDeviceType(parent) {}
+// HidbusDevice(zx_device_t* parent)
+// : HidbusDeviceType("my-hidbus-protocol-device", parent) {}
//
-// zx_status_t Bind() {
-// DdkAdd();
-// }
+// zx_status_t HidbusQuery(uint32_t options, hid_info_t* out_info);
//
-// void DdkRelease() {
-// // Clean up
-// }
+// zx_status_t HidbusStart(const hidbus_ifc_t* ifc);
//
-// zx_status_t HidBusStart(ddk::HidBusIfcProxy proxy) {
-// // Start hidbus operation
-// proxy_ = proxy;
-// return ZX_OK;
-// }
+// void HidbusStop();
//
-// zx_status_t HidBusQuery(uint32_t options, hid_info_t* info) {
-// ...
-// }
+// zx_status_t HidbusGetDescriptor(hid_description_type_t desc_type, void** out_data_buffer,
+// size_t* data_size);
//
-// ...
-// private:
-// ddk::HidBusIfcProxy proxy_;
+// zx_status_t HidbusGetReport(hid_report_type_t rpt_type, uint8_t rpt_id, void*
+// out_data_buffer, size_t data_size, size_t* out_data_actual);
+//
+// zx_status_t HidbusSetReport(hid_report_type_t rpt_type, uint8_t rpt_id, const void*
+// data_buffer, size_t data_size);
+//
+// zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* out_duration);
+//
+// zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration);
+//
+// zx_status_t HidbusGetProtocol(hid_protocol_t* out_protocol);
+//
+// zx_status_t HidbusSetProtocol(hid_protocol_t protocol);
+//
// ...
// };
namespace ddk {
-class HidBusIfcProxy {
+template <typename D>
+class HidbusIfc : public internal::base_mixin {
public:
- HidBusIfcProxy()
- : ifc_(nullptr), cookie_(nullptr) {}
-
- HidBusIfcProxy(hidbus_ifc_t* ifc, void* cookie)
- : ifc_(ifc), cookie_(cookie) {}
-
- void IoQueue(const uint8_t* buf, size_t len) {
- ifc_->io_queue(cookie_, buf, len);
+ HidbusIfc() {
+ internal::CheckHidbusIfcSubclass<D>();
+ hidbus_ifc_ops_.io_queue = HidbusIfcIoQueue;
}
- bool is_valid() const {
- return ifc_ != nullptr;
- }
+protected:
+ hidbus_ifc_ops_t hidbus_ifc_ops_ = {};
+private:
+ // Queues a report received by the hidbus device.
+ static void HidbusIfcIoQueue(void* ctx, const void* buf_buffer, size_t buf_size) {
+ static_cast<D*>(ctx)->HidbusIfcIoQueue(buf_buffer, buf_size);
+ }
+};
+
+class HidbusIfcProxy {
+public:
+ HidbusIfcProxy() : ops_(nullptr), ctx_(nullptr) {}
+ HidbusIfcProxy(const hidbus_ifc_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(hidbus_ifc_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
void clear() {
- ifc_ = nullptr;
- cookie_ = nullptr;
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Queues a report received by the hidbus device.
+ void IoQueue(const void* buf_buffer, size_t buf_size) {
+ ops_->io_queue(ctx_, buf_buffer, buf_size);
}
private:
- hidbus_ifc_t* ifc_;
- void* cookie_;
+ hidbus_ifc_ops_t* ops_;
+ void* ctx_;
};
template <typename D>
-class HidBusProtocol : public internal::base_protocol {
+class HidbusProtocol : public internal::base_mixin {
public:
- HidBusProtocol() {
- internal::CheckHidBusProtocolSubclass<D>();
- ops_.query = Query;
- ops_.start = Start;
- ops_.stop = Stop;
- ops_.get_descriptor = GetDescriptor;
- ops_.get_report = GetReport;
- ops_.set_report = SetReport;
- ops_.get_idle = GetIdle;
- ops_.set_idle = SetIdle;
- ops_.get_protocol = GetProtocol;
- ops_.set_protocol = SetProtocol;
-
- // Can only inherit from one base_protocol implemenation
- ZX_ASSERT(ddk_proto_id_ == 0);
- ddk_proto_id_ = ZX_PROTOCOL_HIDBUS;
- ddk_proto_ops_ = &ops_;
+ HidbusProtocol() {
+ internal::CheckHidbusProtocolSubclass<D>();
+ hidbus_protocol_ops_.query = HidbusQuery;
+ hidbus_protocol_ops_.start = HidbusStart;
+ hidbus_protocol_ops_.stop = HidbusStop;
+ hidbus_protocol_ops_.get_descriptor = HidbusGetDescriptor;
+ hidbus_protocol_ops_.get_report = HidbusGetReport;
+ hidbus_protocol_ops_.set_report = HidbusSetReport;
+ hidbus_protocol_ops_.get_idle = HidbusGetIdle;
+ hidbus_protocol_ops_.set_idle = HidbusSetIdle;
+ hidbus_protocol_ops_.get_protocol = HidbusGetProtocol;
+ hidbus_protocol_ops_.set_protocol = HidbusSetProtocol;
}
+protected:
+ hidbus_protocol_ops_t hidbus_protocol_ops_ = {};
+
private:
- static zx_status_t Query(void* ctx, uint32_t options, hid_info_t* info) {
- return static_cast<D*>(ctx)->HidBusQuery(options, info);
+ // Obtain information about the hidbus device and supported features.
+ // Safe to call at any time.
+ static zx_status_t HidbusQuery(void* ctx, uint32_t options, hid_info_t* out_info) {
+ return static_cast<D*>(ctx)->HidbusQuery(options, out_info);
}
-
- static zx_status_t Start(void* ctx, hidbus_ifc_t* ifc, void* cookie) {
- HidBusIfcProxy proxy(ifc, cookie);
- return static_cast<D*>(ctx)->HidBusStart(proxy);
+ // Start the hidbus device. The device may begin queueing hid reports via
+ // ifc->io_queue before this function returns. It is an error to start an
+ // already-started hidbus device.
+ static zx_status_t HidbusStart(void* ctx, const hidbus_ifc_t* ifc) {
+ return static_cast<D*>(ctx)->HidbusStart(ifc);
}
-
- static void Stop(void* ctx) {
- static_cast<D*>(ctx)->HidBusStop();
+ // Stop the hidbus device. Safe to call if the hidbus is already stopped.
+ static void HidbusStop(void* ctx) { static_cast<D*>(ctx)->HidbusStop(); }
+ // What are the ownership semantics with regards to the data buffer passed back?
+ // is len an input and output parameter?
+ static zx_status_t HidbusGetDescriptor(void* ctx, hid_description_type_t desc_type,
+ void** out_data_buffer, size_t* data_size) {
+ return static_cast<D*>(ctx)->HidbusGetDescriptor(desc_type, out_data_buffer, data_size);
}
-
- static zx_status_t GetDescriptor(void* ctx, uint8_t desc_type, void** data, size_t* len) {
- return static_cast<D*>(ctx)->HidBusGetDescriptor(desc_type, data, len);
+ static zx_status_t HidbusGetReport(void* ctx, hid_report_type_t rpt_type, uint8_t rpt_id,
+ void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual) {
+ return static_cast<D*>(ctx)->HidbusGetReport(rpt_type, rpt_id, out_data_buffer, data_size,
+ out_data_actual);
}
-
- static zx_status_t GetReport(void* ctx, uint8_t rpt_type, uint8_t rpt_id, void* data,
- size_t len, size_t* out_len) {
- return static_cast<D*>(ctx)->HidBusGetReport(rpt_type, rpt_id, data, len, out_len);
+ static zx_status_t HidbusSetReport(void* ctx, hid_report_type_t rpt_type, uint8_t rpt_id,
+ const void* data_buffer, size_t data_size) {
+ return static_cast<D*>(ctx)->HidbusSetReport(rpt_type, rpt_id, data_buffer, data_size);
}
-
- static zx_status_t SetReport(void* ctx, uint8_t rpt_type, uint8_t rpt_id, void* data,
- size_t len) {
- return static_cast<D*>(ctx)->HidBusSetReport(rpt_type, rpt_id, data, len);
+ static zx_status_t HidbusGetIdle(void* ctx, uint8_t rpt_id, uint8_t* out_duration) {
+ return static_cast<D*>(ctx)->HidbusGetIdle(rpt_id, out_duration);
}
-
- static zx_status_t GetIdle(void* ctx, uint8_t rpt_id, uint8_t* duration) {
- return static_cast<D*>(ctx)->HidBusGetIdle(rpt_id, duration);
+ static zx_status_t HidbusSetIdle(void* ctx, uint8_t rpt_id, uint8_t duration) {
+ return static_cast<D*>(ctx)->HidbusSetIdle(rpt_id, duration);
}
-
- static zx_status_t SetIdle(void* ctx, uint8_t rpt_id, uint8_t duration) {
- return static_cast<D*>(ctx)->HidBusSetIdle(rpt_id, duration);
+ static zx_status_t HidbusGetProtocol(void* ctx, hid_protocol_t* out_protocol) {
+ return static_cast<D*>(ctx)->HidbusGetProtocol(out_protocol);
}
-
- static zx_status_t GetProtocol(void* ctx, uint8_t* protocol) {
- return static_cast<D*>(ctx)->HidBusGetProtocol(protocol);
+ static zx_status_t HidbusSetProtocol(void* ctx, hid_protocol_t protocol) {
+ return static_cast<D*>(ctx)->HidbusSetProtocol(protocol);
}
+};
- static zx_status_t SetProtocol(void* ctx, uint8_t protocol) {
- return static_cast<D*>(ctx)->HidBusSetProtocol(protocol);
+class HidbusProtocolProxy {
+public:
+ HidbusProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ HidbusProtocolProxy(const hidbus_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(hidbus_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Obtain information about the hidbus device and supported features.
+ // Safe to call at any time.
+ zx_status_t Query(uint32_t options, hid_info_t* out_info) {
+ return ops_->query(ctx_, options, out_info);
+ }
+ // Start the hidbus device. The device may begin queueing hid reports via
+ // ifc->io_queue before this function returns. It is an error to start an
+ // already-started hidbus device.
+ zx_status_t Start(const hidbus_ifc_t* ifc) { return ops_->start(ctx_, ifc); }
+ // Stop the hidbus device. Safe to call if the hidbus is already stopped.
+ void Stop() { ops_->stop(ctx_); }
+ // What are the ownership semantics with regards to the data buffer passed back?
+ // is len an input and output parameter?
+ zx_status_t GetDescriptor(hid_description_type_t desc_type, void** out_data_buffer,
+ size_t* data_size) {
+ return ops_->get_descriptor(ctx_, desc_type, out_data_buffer, data_size);
+ }
+ zx_status_t GetReport(hid_report_type_t rpt_type, uint8_t rpt_id, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual) {
+ return ops_->get_report(ctx_, rpt_type, rpt_id, out_data_buffer, data_size,
+ out_data_actual);
+ }
+ zx_status_t SetReport(hid_report_type_t rpt_type, uint8_t rpt_id, const void* data_buffer,
+ size_t data_size) {
+ return ops_->set_report(ctx_, rpt_type, rpt_id, data_buffer, data_size);
+ }
+ zx_status_t GetIdle(uint8_t rpt_id, uint8_t* out_duration) {
+ return ops_->get_idle(ctx_, rpt_id, out_duration);
+ }
+ zx_status_t SetIdle(uint8_t rpt_id, uint8_t duration) {
+ return ops_->set_idle(ctx_, rpt_id, duration);
+ }
+ zx_status_t GetProtocol(hid_protocol_t* out_protocol) {
+ return ops_->get_protocol(ctx_, out_protocol);
+ }
+ zx_status_t SetProtocol(hid_protocol_t protocol) { return ops_->set_protocol(ctx_, protocol); }
- hidbus_protocol_ops_t ops_ = {};
+private:
+ hidbus_protocol_ops_t* ops_;
+ void* ctx_;
};
} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/intel-gpu-core-internal.h b/system/ulib/ddktl/include/ddktl/protocol/intel-gpu-core-internal.h
new file mode 100644
index 0000000..a3dc5d2
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/intel-gpu-core-internal.h
@@ -0,0 +1,90 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/intel-gpu-core.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_read_pci_config16,
+ ZxIntelGpuCoreReadPciConfig16,
+ zx_status_t (C::*)(uint16_t addr, uint16_t* out_value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_map_pci_mmio,
+ ZxIntelGpuCoreMapPciMmio,
+ zx_status_t (C::*)(uint32_t pci_bar, void** out_buf_buffer,
+ size_t* buf_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_unmap_pci_mmio,
+ ZxIntelGpuCoreUnmapPciMmio,
+ zx_status_t (C::*)(uint32_t pci_bar));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_get_pci_bti,
+ ZxIntelGpuCoreGetPciBti,
+ zx_status_t (C::*)(uint32_t index, zx_handle_t* out_bti));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(
+ has_zx_intel_gpu_core_protocol_register_interrupt_callback,
+ ZxIntelGpuCoreRegisterInterruptCallback,
+ zx_status_t (C::*)(const zx_intel_gpu_core_interrupt_t* callback, uint32_t interrupt_mask));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_unregister_interrupt_callback,
+ ZxIntelGpuCoreUnregisterInterruptCallback,
+ zx_status_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_gtt_get_size,
+ ZxIntelGpuCoreGttGetSize, uint64_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_gtt_alloc,
+ ZxIntelGpuCoreGttAlloc,
+ zx_status_t (C::*)(uint64_t page_count, uint64_t* out_addr));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_gtt_free, ZxIntelGpuCoreGttFree,
+ zx_status_t (C::*)(uint64_t addr));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_gtt_clear,
+ ZxIntelGpuCoreGttClear, zx_status_t (C::*)(uint64_t addr));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_zx_intel_gpu_core_protocol_gtt_insert,
+ ZxIntelGpuCoreGttInsert,
+ zx_status_t (C::*)(uint64_t addr, zx_handle_t buffer,
+ uint64_t page_offset, uint64_t page_count));
+
+template <typename D>
+constexpr void CheckZxIntelGpuCoreProtocolSubclass() {
+ static_assert(internal::has_zx_intel_gpu_core_protocol_read_pci_config16<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreReadPciConfig16(uint16_t addr, uint16_t* out_value");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_map_pci_mmio<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreMapPciMmio(uint32_t pci_bar, void** out_buf_buffer, "
+ "size_t* buf_size");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_unmap_pci_mmio<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreUnmapPciMmio(uint32_t pci_bar");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_get_pci_bti<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreGetPciBti(uint32_t index, zx_handle_t* out_bti");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_register_interrupt_callback<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreRegisterInterruptCallback(const "
+ "zx_intel_gpu_core_interrupt_t* callback, uint32_t interrupt_mask");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_unregister_interrupt_callback<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreUnregisterInterruptCallback(");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_gtt_get_size<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "uint64_t ZxIntelGpuCoreGttGetSize(");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_gtt_alloc<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreGttAlloc(uint64_t page_count, uint64_t* out_addr");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_gtt_free<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreGttFree(uint64_t addr");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_gtt_clear<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreGttClear(uint64_t addr");
+ static_assert(internal::has_zx_intel_gpu_core_protocol_gtt_insert<D>::value,
+ "ZxIntelGpuCoreProtocol subclasses must implement "
+ "zx_status_t ZxIntelGpuCoreGttInsert(uint64_t addr, zx_handle_t buffer, uint64_t "
+ "page_offset, uint64_t page_count");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/intel-gpu-core.h b/system/ulib/ddktl/include/ddktl/protocol/intel-gpu-core.h
new file mode 100644
index 0000000..f3476f5
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/intel-gpu-core.h
@@ -0,0 +1,211 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/intel-gpu-core.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "intel-gpu-core-internal.h"
+
+// DDK zx-intel-gpu-core-protocol support
+//
+// :: Proxies ::
+//
+// ddk::ZxIntelGpuCoreProtocolProxy is a simple wrapper around
+// zx_intel_gpu_core_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::ZxIntelGpuCoreProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the zx-intel-gpu-core protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_ZX_INTEL_GPU_CORE device.
+// class ZxIntelGpuCoreDevice {
+// using ZxIntelGpuCoreDeviceType = ddk::Device<ZxIntelGpuCoreDevice, /* ddk mixins */>;
+//
+// class ZxIntelGpuCoreDevice : public ZxIntelGpuCoreDeviceType,
+// public ddk::ZxIntelGpuCoreProtocol<ZxIntelGpuCoreDevice> {
+// public:
+// ZxIntelGpuCoreDevice(zx_device_t* parent)
+// : ZxIntelGpuCoreDeviceType("my-zx-intel-gpu-core-protocol-device", parent) {}
+//
+// zx_status_t ZxIntelGpuCoreReadPciConfig16(uint16_t addr, uint16_t* out_value);
+//
+// zx_status_t ZxIntelGpuCoreMapPciMmio(uint32_t pci_bar, void** out_buf_buffer, size_t*
+// buf_size);
+//
+// zx_status_t ZxIntelGpuCoreUnmapPciMmio(uint32_t pci_bar);
+//
+// zx_status_t ZxIntelGpuCoreGetPciBti(uint32_t index, zx_handle_t* out_bti);
+//
+// zx_status_t ZxIntelGpuCoreRegisterInterruptCallback(const zx_intel_gpu_core_interrupt_t*
+// callback, uint32_t interrupt_mask);
+//
+// zx_status_t ZxIntelGpuCoreUnregisterInterruptCallback();
+//
+// uint64_t ZxIntelGpuCoreGttGetSize();
+//
+// zx_status_t ZxIntelGpuCoreGttAlloc(uint64_t page_count, uint64_t* out_addr);
+//
+// zx_status_t ZxIntelGpuCoreGttFree(uint64_t addr);
+//
+// zx_status_t ZxIntelGpuCoreGttClear(uint64_t addr);
+//
+// zx_status_t ZxIntelGpuCoreGttInsert(uint64_t addr, zx_handle_t buffer, uint64_t page_offset,
+// uint64_t page_count);
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class ZxIntelGpuCoreProtocol : public internal::base_mixin {
+public:
+ ZxIntelGpuCoreProtocol() {
+ internal::CheckZxIntelGpuCoreProtocolSubclass<D>();
+ zx_intel_gpu_core_protocol_ops_.read_pci_config16 = ZxIntelGpuCoreReadPciConfig16;
+ zx_intel_gpu_core_protocol_ops_.map_pci_mmio = ZxIntelGpuCoreMapPciMmio;
+ zx_intel_gpu_core_protocol_ops_.unmap_pci_mmio = ZxIntelGpuCoreUnmapPciMmio;
+ zx_intel_gpu_core_protocol_ops_.get_pci_bti = ZxIntelGpuCoreGetPciBti;
+ zx_intel_gpu_core_protocol_ops_.register_interrupt_callback =
+ ZxIntelGpuCoreRegisterInterruptCallback;
+ zx_intel_gpu_core_protocol_ops_.unregister_interrupt_callback =
+ ZxIntelGpuCoreUnregisterInterruptCallback;
+ zx_intel_gpu_core_protocol_ops_.gtt_get_size = ZxIntelGpuCoreGttGetSize;
+ zx_intel_gpu_core_protocol_ops_.gtt_alloc = ZxIntelGpuCoreGttAlloc;
+ zx_intel_gpu_core_protocol_ops_.gtt_free = ZxIntelGpuCoreGttFree;
+ zx_intel_gpu_core_protocol_ops_.gtt_clear = ZxIntelGpuCoreGttClear;
+ zx_intel_gpu_core_protocol_ops_.gtt_insert = ZxIntelGpuCoreGttInsert;
+ }
+
+protected:
+ zx_intel_gpu_core_protocol_ops_t zx_intel_gpu_core_protocol_ops_ = {};
+
+private:
+ // Reads 16 bits from pci config space; returned in |value_out|.
+ static zx_status_t ZxIntelGpuCoreReadPciConfig16(void* ctx, uint16_t addr,
+ uint16_t* out_value) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreReadPciConfig16(addr, out_value);
+ }
+ // Maps the given |pci_bar|; address returned in |addr_out|, size in bytes returned in
+ // |size_out|.
+ static zx_status_t ZxIntelGpuCoreMapPciMmio(void* ctx, uint32_t pci_bar, void** out_buf_buffer,
+ size_t* buf_size) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreMapPciMmio(pci_bar, out_buf_buffer, buf_size);
+ }
+ // Unmaps the given |pci_bar|.
+ static zx_status_t ZxIntelGpuCoreUnmapPciMmio(void* ctx, uint32_t pci_bar) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreUnmapPciMmio(pci_bar);
+ }
+ // Returns a bus transaction initiator.
+ static zx_status_t ZxIntelGpuCoreGetPciBti(void* ctx, uint32_t index, zx_handle_t* out_bti) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreGetPciBti(index, out_bti);
+ }
+ // Registers the given |callback| to be invoked with parameter |data| when an interrupt occurs
+ // matching |interrupt_mask|.
+ static zx_status_t ZxIntelGpuCoreRegisterInterruptCallback(
+ void* ctx, const zx_intel_gpu_core_interrupt_t* callback, uint32_t interrupt_mask) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreRegisterInterruptCallback(callback,
+ interrupt_mask);
+ }
+ // Un-registers a previously registered interrupt callback.
+ static zx_status_t ZxIntelGpuCoreUnregisterInterruptCallback(void* ctx) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreUnregisterInterruptCallback();
+ }
+ // Returns the size of the GTT (global translation table) in bytes.
+ static uint64_t ZxIntelGpuCoreGttGetSize(void* ctx) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreGttGetSize();
+ }
+ // Allocates a region of the GTT of the given |page_count|, returning the page-aligned virtual
+ // address in |addr_out|.
+ static zx_status_t ZxIntelGpuCoreGttAlloc(void* ctx, uint64_t page_count, uint64_t* out_addr) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreGttAlloc(page_count, out_addr);
+ }
+ // Frees the GTT allocation given by |addr|.
+ static zx_status_t ZxIntelGpuCoreGttFree(void* ctx, uint64_t addr) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreGttFree(addr);
+ }
+ // Clears the page table entries for the GTT allocation given by |addr|.
+ static zx_status_t ZxIntelGpuCoreGttClear(void* ctx, uint64_t addr) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreGttClear(addr);
+ }
+ // Inserts page tables entries for the GTT allocation given by |addr| for the vmo represented by
+ // handle |buffer|, at the given |page_offset| and |page_count|. Takes ownership of |buffer|.
+ static zx_status_t ZxIntelGpuCoreGttInsert(void* ctx, uint64_t addr, zx_handle_t buffer,
+ uint64_t page_offset, uint64_t page_count) {
+ return static_cast<D*>(ctx)->ZxIntelGpuCoreGttInsert(addr, buffer, page_offset, page_count);
+ }
+};
+
+class ZxIntelGpuCoreProtocolProxy {
+public:
+ ZxIntelGpuCoreProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ ZxIntelGpuCoreProtocolProxy(const zx_intel_gpu_core_protocol_t* proto)
+ : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(zx_intel_gpu_core_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Reads 16 bits from pci config space; returned in |value_out|.
+ zx_status_t ReadPciConfig16(uint16_t addr, uint16_t* out_value) {
+ return ops_->read_pci_config16(ctx_, addr, out_value);
+ }
+ // Maps the given |pci_bar|; address returned in |addr_out|, size in bytes returned in
+ // |size_out|.
+ zx_status_t MapPciMmio(uint32_t pci_bar, void** out_buf_buffer, size_t* buf_size) {
+ return ops_->map_pci_mmio(ctx_, pci_bar, out_buf_buffer, buf_size);
+ }
+ // Unmaps the given |pci_bar|.
+ zx_status_t UnmapPciMmio(uint32_t pci_bar) { return ops_->unmap_pci_mmio(ctx_, pci_bar); }
+ // Returns a bus transaction initiator.
+ zx_status_t GetPciBti(uint32_t index, zx_handle_t* out_bti) {
+ return ops_->get_pci_bti(ctx_, index, out_bti);
+ }
+ // Registers the given |callback| to be invoked with parameter |data| when an interrupt occurs
+ // matching |interrupt_mask|.
+ zx_status_t RegisterInterruptCallback(const zx_intel_gpu_core_interrupt_t* callback,
+ uint32_t interrupt_mask) {
+ return ops_->register_interrupt_callback(ctx_, callback, interrupt_mask);
+ }
+ // Un-registers a previously registered interrupt callback.
+ zx_status_t UnregisterInterruptCallback() { return ops_->unregister_interrupt_callback(ctx_); }
+ // Returns the size of the GTT (global translation table) in bytes.
+ uint64_t GttGetSize() { return ops_->gtt_get_size(ctx_); }
+ // Allocates a region of the GTT of the given |page_count|, returning the page-aligned virtual
+ // address in |addr_out|.
+ zx_status_t GttAlloc(uint64_t page_count, uint64_t* out_addr) {
+ return ops_->gtt_alloc(ctx_, page_count, out_addr);
+ }
+ // Frees the GTT allocation given by |addr|.
+ zx_status_t GttFree(uint64_t addr) { return ops_->gtt_free(ctx_, addr); }
+ // Clears the page table entries for the GTT allocation given by |addr|.
+ zx_status_t GttClear(uint64_t addr) { return ops_->gtt_clear(ctx_, addr); }
+ // Inserts page tables entries for the GTT allocation given by |addr| for the vmo represented by
+ // handle |buffer|, at the given |page_offset| and |page_count|. Takes ownership of |buffer|.
+ zx_status_t GttInsert(uint64_t addr, zx_handle_t buffer, uint64_t page_offset,
+ uint64_t page_count) {
+ return ops_->gtt_insert(ctx_, addr, buffer, page_offset, page_count);
+ }
+
+private:
+ zx_intel_gpu_core_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/intel-hda-codec-internal.h b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-codec-internal.h
new file mode 100644
index 0000000..a9c51ef
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-codec-internal.h
@@ -0,0 +1,27 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/intel-hda-codec.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_codec_protocol_get_driver_channel,
+ IhdaCodecGetDriverChannel,
+ zx_status_t (C::*)(zx_handle_t* out_channel));
+
+template <typename D>
+constexpr void CheckIhdaCodecProtocolSubclass() {
+ static_assert(internal::has_ihda_codec_protocol_get_driver_channel<D>::value,
+ "IhdaCodecProtocol subclasses must implement "
+ "zx_status_t IhdaCodecGetDriverChannel(zx_handle_t* out_channel");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/intel-hda-codec.h b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-codec.h
new file mode 100644
index 0000000..6d5aea2
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-codec.h
@@ -0,0 +1,91 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/intel-hda-codec.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "intel-hda-codec-internal.h"
+
+// DDK ihda-codec-protocol support
+//
+// :: Proxies ::
+//
+// ddk::IhdaCodecProtocolProxy is a simple wrapper around
+// ihda_codec_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::IhdaCodecProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the ihda-codec protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_IHDA_CODEC device.
+// class IhdaCodecDevice {
+// using IhdaCodecDeviceType = ddk::Device<IhdaCodecDevice, /* ddk mixins */>;
+//
+// class IhdaCodecDevice : public IhdaCodecDeviceType,
+// public ddk::IhdaCodecProtocol<IhdaCodecDevice> {
+// public:
+// IhdaCodecDevice(zx_device_t* parent)
+// : IhdaCodecDeviceType("my-ihda-codec-protocol-device", parent) {}
+//
+// zx_status_t IhdaCodecGetDriverChannel(zx_handle_t* out_channel);
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class IhdaCodecProtocol : public internal::base_mixin {
+public:
+ IhdaCodecProtocol() {
+ internal::CheckIhdaCodecProtocolSubclass<D>();
+ ihda_codec_protocol_ops_.get_driver_channel = IhdaCodecGetDriverChannel;
+ }
+
+protected:
+ ihda_codec_protocol_ops_t ihda_codec_protocol_ops_ = {};
+
+private:
+ // Fetch a zx_handle_t to a channel which can be used to communicate with the codec device.
+ static zx_status_t IhdaCodecGetDriverChannel(void* ctx, zx_handle_t* out_channel) {
+ return static_cast<D*>(ctx)->IhdaCodecGetDriverChannel(out_channel);
+ }
+};
+
+class IhdaCodecProtocolProxy {
+public:
+ IhdaCodecProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ IhdaCodecProtocolProxy(const ihda_codec_protocol_t* proto)
+ : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(ihda_codec_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Fetch a zx_handle_t to a channel which can be used to communicate with the codec device.
+ zx_status_t GetDriverChannel(zx_handle_t* out_channel) {
+ return ops_->get_driver_channel(ctx_, out_channel);
+ }
+
+private:
+ ihda_codec_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/intel-hda-dsp-internal.h b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-dsp-internal.h
new file mode 100644
index 0000000..cc64901
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-dsp-internal.h
@@ -0,0 +1,54 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/intel-hda-dsp.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_get_dev_info, IhdaDspGetDevInfo,
+ void (C::*)(zx_pcie_device_info_t* out_out));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_get_mmio, IhdaDspGetMmio,
+ zx_status_t (C::*)(zx_handle_t* out_vmo, size_t* out_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_get_bti, IhdaDspGetBti,
+ zx_status_t (C::*)(zx_handle_t* out_bti));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_enable, IhdaDspEnable, void (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_disable, IhdaDspDisable, void (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_irq_enable, IhdaDspIrqEnable,
+ zx_status_t (C::*)(const ihda_dsp_irq_t* callback));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_ihda_dsp_protocol_irq_disable, IhdaDspIrqDisable,
+ void (C::*)());
+
+template <typename D>
+constexpr void CheckIhdaDspProtocolSubclass() {
+ static_assert(internal::has_ihda_dsp_protocol_get_dev_info<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "void IhdaDspGetDevInfo(zx_pcie_device_info_t* out_out");
+ static_assert(internal::has_ihda_dsp_protocol_get_mmio<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "zx_status_t IhdaDspGetMmio(zx_handle_t* out_vmo, size_t* out_size");
+ static_assert(internal::has_ihda_dsp_protocol_get_bti<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "zx_status_t IhdaDspGetBti(zx_handle_t* out_bti");
+ static_assert(internal::has_ihda_dsp_protocol_enable<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "void IhdaDspEnable(");
+ static_assert(internal::has_ihda_dsp_protocol_disable<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "void IhdaDspDisable(");
+ static_assert(internal::has_ihda_dsp_protocol_irq_enable<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "zx_status_t IhdaDspIrqEnable(const ihda_dsp_irq_t* callback");
+ static_assert(internal::has_ihda_dsp_protocol_irq_disable<D>::value,
+ "IhdaDspProtocol subclasses must implement "
+ "void IhdaDspIrqDisable(");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/intel-hda-dsp.h b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-dsp.h
new file mode 100644
index 0000000..1417c23
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/intel-hda-dsp.h
@@ -0,0 +1,144 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/intel-hda-dsp.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "intel-hda-dsp-internal.h"
+
+// DDK ihda-dsp-protocol support
+//
+// :: Proxies ::
+//
+// ddk::IhdaDspProtocolProxy is a simple wrapper around
+// ihda_dsp_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::IhdaDspProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the ihda-dsp protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_IHDA_DSP device.
+// class IhdaDspDevice {
+// using IhdaDspDeviceType = ddk::Device<IhdaDspDevice, /* ddk mixins */>;
+//
+// class IhdaDspDevice : public IhdaDspDeviceType,
+// public ddk::IhdaDspProtocol<IhdaDspDevice> {
+// public:
+// IhdaDspDevice(zx_device_t* parent)
+// : IhdaDspDeviceType("my-ihda-dsp-protocol-device", parent) {}
+//
+// void IhdaDspGetDevInfo(zx_pcie_device_info_t* out_out);
+//
+// zx_status_t IhdaDspGetMmio(zx_handle_t* out_vmo, size_t* out_size);
+//
+// zx_status_t IhdaDspGetBti(zx_handle_t* out_bti);
+//
+// void IhdaDspEnable();
+//
+// void IhdaDspDisable();
+//
+// zx_status_t IhdaDspIrqEnable(const ihda_dsp_irq_t* callback);
+//
+// void IhdaDspIrqDisable();
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class IhdaDspProtocol : public internal::base_mixin {
+public:
+ IhdaDspProtocol() {
+ internal::CheckIhdaDspProtocolSubclass<D>();
+ ihda_dsp_protocol_ops_.get_dev_info = IhdaDspGetDevInfo;
+ ihda_dsp_protocol_ops_.get_mmio = IhdaDspGetMmio;
+ ihda_dsp_protocol_ops_.get_bti = IhdaDspGetBti;
+ ihda_dsp_protocol_ops_.enable = IhdaDspEnable;
+ ihda_dsp_protocol_ops_.disable = IhdaDspDisable;
+ ihda_dsp_protocol_ops_.irq_enable = IhdaDspIrqEnable;
+ ihda_dsp_protocol_ops_.irq_disable = IhdaDspIrqDisable;
+ }
+
+protected:
+ ihda_dsp_protocol_ops_t ihda_dsp_protocol_ops_ = {};
+
+private:
+ // Fetch the parent HDA controller's PCI device info.
+ static void IhdaDspGetDevInfo(void* ctx, zx_pcie_device_info_t* out_out) {
+ static_cast<D*>(ctx)->IhdaDspGetDevInfo(out_out);
+ }
+ // Fetch a VMO that represents the BAR holding the Audio DSP registers.
+ static zx_status_t IhdaDspGetMmio(void* ctx, zx_handle_t* out_vmo, size_t* out_size) {
+ return static_cast<D*>(ctx)->IhdaDspGetMmio(out_vmo, out_size);
+ }
+ // Fetch a handle to our bus transaction initiator.
+ static zx_status_t IhdaDspGetBti(void* ctx, zx_handle_t* out_bti) {
+ return static_cast<D*>(ctx)->IhdaDspGetBti(out_bti);
+ }
+ // Enables DSP
+ static void IhdaDspEnable(void* ctx) { static_cast<D*>(ctx)->IhdaDspEnable(); }
+ // Disable DSP
+ static void IhdaDspDisable(void* ctx) { static_cast<D*>(ctx)->IhdaDspDisable(); }
+ // Enables DSP interrupts and set a callback to be invoked when an interrupt is
+ // raised.
+ // Returns `ZX_ERR_ALREADY_EXISTS` if a callback is already set.
+ static zx_status_t IhdaDspIrqEnable(void* ctx, const ihda_dsp_irq_t* callback) {
+ return static_cast<D*>(ctx)->IhdaDspIrqEnable(callback);
+ }
+ // Disable DSP interrupts and clears the callback.
+ static void IhdaDspIrqDisable(void* ctx) { static_cast<D*>(ctx)->IhdaDspIrqDisable(); }
+};
+
+class IhdaDspProtocolProxy {
+public:
+ IhdaDspProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ IhdaDspProtocolProxy(const ihda_dsp_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(ihda_dsp_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Fetch the parent HDA controller's PCI device info.
+ void GetDevInfo(zx_pcie_device_info_t* out_out) { ops_->get_dev_info(ctx_, out_out); }
+ // Fetch a VMO that represents the BAR holding the Audio DSP registers.
+ zx_status_t GetMmio(zx_handle_t* out_vmo, size_t* out_size) {
+ return ops_->get_mmio(ctx_, out_vmo, out_size);
+ }
+ // Fetch a handle to our bus transaction initiator.
+ zx_status_t GetBti(zx_handle_t* out_bti) { return ops_->get_bti(ctx_, out_bti); }
+ // Enables DSP
+ void Enable() { ops_->enable(ctx_); }
+ // Disable DSP
+ void Disable() { ops_->disable(ctx_); }
+ // Enables DSP interrupts and set a callback to be invoked when an interrupt is
+ // raised.
+ // Returns `ZX_ERR_ALREADY_EXISTS` if a callback is already set.
+ zx_status_t IrqEnable(const ihda_dsp_irq_t* callback) {
+ return ops_->irq_enable(ctx_, callback);
+ }
+ // Disable DSP interrupts and clears the callback.
+ void IrqDisable() { ops_->irq_disable(ctx_); }
+
+private:
+ ihda_dsp_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/iommu-internal.h b/system/ulib/ddktl/include/ddktl/protocol/iommu-internal.h
index 073c442..2b4baaa 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/iommu-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/iommu-internal.h
@@ -2,22 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/iommu.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_get_bti, GetBti,
- zx_status_t (C::*)(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_iommu_protocol_get_bti, IommuGetBti,
+ zx_status_t (C::*)(uint32_t iommu_index, uint32_t bti_id,
+ zx_handle_t* out_handle));
template <typename D>
constexpr void CheckIommuProtocolSubclass() {
- static_assert(internal::has_get_bti<D>::value,
- "IommuProtocol subclasses must implement "
- "GetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle)");
- }
+ static_assert(
+ internal::has_iommu_protocol_get_bti<D>::value,
+ "IommuProtocol subclasses must implement "
+ "zx_status_t IommuGetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle");
+}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/iommu.h b/system/ulib/ddktl/include/ddktl/protocol/iommu.h
index a85dff1..bec135a 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/iommu.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/iommu.h
@@ -2,72 +2,81 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/iommu.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "iommu-internal.h"
-// DDK IOMMU protocol support.
+// DDK iommu-protocol support
//
// :: Proxies ::
//
-// ddk::IommuProtocolProxy is a simple wrappers around iommu_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::IommuProtocolProxy is a simple wrapper around
+// iommu_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::IommuProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the platform bus protocol.
+// ddk::IommuProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the iommu protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_IOMMU device.
-// class IommuDevice;
+// class IommuDevice {
// using IommuDeviceType = ddk::Device<IommuDevice, /* ddk mixins */>;
//
// class IommuDevice : public IommuDeviceType,
// public ddk::IommuProtocol<IommuDevice> {
// public:
// IommuDevice(zx_device_t* parent)
-// : IommuDeviceType("my-iommu-device", parent) {}
+// : IommuDeviceType("my-iommu-protocol-device", parent) {}
//
-// zx_status_t GetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle);
+// zx_status_t IommuGetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle);
+//
// ...
// };
namespace ddk {
template <typename D>
-class IommuProtocol {
+class IommuProtocol : public internal::base_mixin {
public:
IommuProtocol() {
internal::CheckIommuProtocolSubclass<D>();
- iommu_proto_ops_.get_bti = GetBti;
+ iommu_protocol_ops_.get_bti = IommuGetBti;
}
protected:
- iommu_protocol_ops_t iommu_proto_ops_ = {};
+ iommu_protocol_ops_t iommu_protocol_ops_ = {};
private:
- static zx_status_t GetBti(void* ctx, uint32_t iommu_index, uint32_t bti_id,
- zx_handle_t* out_handle) {
- return static_cast<D*>(ctx)->GetBti(iommu_index, bti_id, out_handle);
+ static zx_status_t IommuGetBti(void* ctx, uint32_t iommu_index, uint32_t bti_id,
+ zx_handle_t* out_handle) {
+ return static_cast<D*>(ctx)->IommuGetBti(iommu_index, bti_id, out_handle);
}
};
class IommuProtocolProxy {
public:
- IommuProtocolProxy(iommu_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ IommuProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ IommuProtocolProxy(const iommu_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(iommu_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
-
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
zx_status_t GetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle) {
return ops_->get_bti(ctx_, iommu_index, bti_id, out_handle);
}
diff --git a/system/ulib/ddktl/include/ddktl/protocol/mailbox-internal.h b/system/ulib/ddktl/include/ddktl/protocol/mailbox-internal.h
index 72bac82..41c43cc 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/mailbox-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/mailbox-internal.h
@@ -2,22 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/mailbox.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_mailbox_send_cmd, MailboxSendCmd,
- zx_status_t (C::*)(mailbox_channel_t*, mailbox_data_buf_t*));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_mailbox_protocol_send_command, MailboxSendCommand,
+ zx_status_t (C::*)(const mailbox_channel_t* channel,
+ const mailbox_data_buf_t* mdata));
template <typename D>
constexpr void CheckMailboxProtocolSubclass() {
- static_assert(internal::has_mailbox_send_cmd<D>::value,
+ static_assert(internal::has_mailbox_protocol_send_command<D>::value,
"MailboxProtocol subclasses must implement "
- "MailboxSendCmd(mailbox_channel_t* channel, mailbox_data_buf_t* mdata)");
- }
+ "zx_status_t MailboxSendCommand(const mailbox_channel_t* channel, const "
+ "mailbox_data_buf_t* mdata");
+}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/mailbox.h b/system/ulib/ddktl/include/ddktl/protocol/mailbox.h
index 6111052..8d4d7d3 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/mailbox.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/mailbox.h
@@ -2,74 +2,84 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/mailbox.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "mailbox-internal.h"
-// DDK mailbox protocol support.
+// DDK mailbox-protocol support
//
// :: Proxies ::
//
-// ddk::MailboxProtocolProxy is a simple wrappers around mailbox_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::MailboxProtocolProxy is a simple wrapper around
+// mailbox_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::MailboxProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the mailbox protocol.
+// ddk::MailboxProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the mailbox protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_MAILBOX device.
-// class MailboxDevice;
+// class MailboxDevice {
// using MailboxDeviceType = ddk::Device<MailboxDevice, /* ddk mixins */>;
//
// class MailboxDevice : public MailboxDeviceType,
-// public ddk::MailboxProtocol<MailboxDevice> {
+// public ddk::MailboxProtocol<MailboxDevice> {
// public:
// MailboxDevice(zx_device_t* parent)
-// : MailboxDeviceType("my-mailbox-device", parent) {}
+// : MailboxDeviceType("my-mailbox-protocol-device", parent) {}
//
-// zx_status_t MailboxSendCmd(mailbox_channel_t* channel, mailbox_data_buf_t* mdata);
+// zx_status_t MailboxSendCommand(const mailbox_channel_t* channel, const mailbox_data_buf_t*
+// mdata);
+//
// ...
// };
namespace ddk {
template <typename D>
-class MailboxProtocol {
+class MailboxProtocol : public internal::base_mixin {
public:
MailboxProtocol() {
internal::CheckMailboxProtocolSubclass<D>();
- mailbox_proto_ops_.send_cmd = MailboxSendCmd;
+ mailbox_protocol_ops_.send_command = MailboxSendCommand;
}
protected:
- mailbox_protocol_ops_t mailbox_proto_ops_ = {};
+ mailbox_protocol_ops_t mailbox_protocol_ops_ = {};
private:
- static zx_status_t MailboxSendCmd(void* ctx, mailbox_channel_t* channel,
- mailbox_data_buf_t* mdata) {
- return static_cast<D*>(ctx)->MailboxSendCmd(channel, mdata);
+ static zx_status_t MailboxSendCommand(void* ctx, const mailbox_channel_t* channel,
+ const mailbox_data_buf_t* mdata) {
+ return static_cast<D*>(ctx)->MailboxSendCommand(channel, mdata);
}
};
class MailboxProtocolProxy {
public:
- MailboxProtocolProxy(mailbox_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ MailboxProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ MailboxProtocolProxy(const mailbox_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(mailbox_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
-
- zx_status_t SendCmd(mailbox_channel_t* channel, mailbox_data_buf_t* mdata) {
- return ops_->send_cmd(ctx_, channel, mdata);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t SendCommand(const mailbox_channel_t* channel, const mailbox_data_buf_t* mdata) {
+ return ops_->send_command(ctx_, channel, mdata);
}
private:
diff --git a/system/ulib/ddktl/include/ddktl/protocol/nand-internal.h b/system/ulib/ddktl/include/ddktl/protocol/nand-internal.h
index 9e9e1be..d5c0255 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/nand-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/nand-internal.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/nand.h>
@@ -10,27 +12,31 @@
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_query, Query,
- void (C::*)(nand_info_t*, size_t*));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_queue, Queue, void (C::*)(nand_op_t*));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_get_factory_bad_block_list, GetFactoryBadBlockList,
- zx_status_t (C::*)(uint32_t* , uint32_t , uint32_t*));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_nand_protocol_query, NandQuery,
+ void (C::*)(nand_info_t* out_info, size_t* out_nand_op_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_nand_protocol_queue, NandQueue,
+ void (C::*)(nand_operation_t* op, nand_queue_callback callback,
+ void* cookie));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_nand_protocol_get_factory_bad_block_list,
+ NandGetFactoryBadBlockList,
+ zx_status_t (C::*)(uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual));
template <typename D>
constexpr void CheckNandProtocolSubclass() {
- static_assert(internal::has_query<D>::value,
+ static_assert(internal::has_nand_protocol_query<D>::value,
"NandProtocol subclasses must implement "
- "Query(nand_info_t* info_out, size_t* nand_op_size_out)");
- static_assert(internal::has_queue<D>::value,
+ "void NandQuery(nand_info_t* out_info, size_t* out_nand_op_size");
+ static_assert(
+ internal::has_nand_protocol_queue<D>::value,
+ "NandProtocol subclasses must implement "
+ "void NandQueue(nand_operation_t* op, nand_queue_callback callback, void* cookie");
+ static_assert(internal::has_nand_protocol_get_factory_bad_block_list<D>::value,
"NandProtocol subclasses must implement "
- "Queue(nand_op_t* operation)");
- static_assert(internal::has_get_factory_bad_block_list<D>::value,
- "NandProtocol subclasses must implement "
- "GetFactoryBadBlockList(uint32_t* bad_blocks, "
- "uint32_t bad_block_len, uint32_t* num_bad_blocks)");
+ "zx_status_t NandGetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t "
+ "bad_blocks_count, size_t* out_bad_blocks_actual");
}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/nand.h b/system/ulib/ddktl/include/ddktl/protocol/nand.h
index 6245670..405bf4c 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/nand.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/nand.h
@@ -2,43 +2,50 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/nand.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/device/nand.h>
+#include <zircon/types.h>
#include "nand-internal.h"
-// DDK nand protocol support.
+// DDK nand-protocol support
//
// :: Proxies ::
//
-// ddk::NandProtocolProxy is a simple wrappers around nand_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::NandProtocolProxy is a simple wrapper around
+// nand_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::NandProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the nand protocol.
+// ddk::NandProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the nand protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_NAND device.
-// class NandDevice;
+// class NandDevice {
// using NandDeviceType = ddk::Device<NandDevice, /* ddk mixins */>;
//
// class NandDevice : public NandDeviceType,
// public ddk::NandProtocol<NandDevice> {
// public:
// NandDevice(zx_device_t* parent)
-// : NandDeviceType("my-nand-device", parent) {}
+// : NandDeviceType("my-nand-protocol-device", parent) {}
//
-// void Query(nand_info_t* info_out, size_t* nand_op_size_out);
-// void Queue(nand_op_t* operation);
-// zx_status_t GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
-// uint32_t* num_bad_blocks);
+// void NandQuery(nand_info_t* out_info, size_t* out_nand_op_size);
+//
+// void NandQueue(nand_operation_t* op, nand_queue_callback callback, void* cookie);
+//
+// zx_status_t NandGetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t
+// bad_blocks_count, size_t* out_bad_blocks_actual);
+//
// ...
// };
@@ -49,51 +56,87 @@
public:
NandProtocol() {
internal::CheckNandProtocolSubclass<D>();
- nand_proto_ops_.query = Query;
- nand_proto_ops_.queue = Queue;
- nand_proto_ops_.get_factory_bad_block_list = GetFactoryBadBlockList;
+ ops_.query = NandQuery;
+ ops_.queue = NandQueue;
+ ops_.get_factory_bad_block_list = NandGetFactoryBadBlockList;
// Can only inherit from one base_protocol implementation.
- ZX_ASSERT(ddk_proto_id_ == 0);
+ ZX_ASSERT(ddk_proto_id_ = 0);
ddk_proto_id_ = ZX_PROTOCOL_NAND;
- ddk_proto_ops_ = &nand_proto_ops_;
+ ddk_proto_ops_ = &ops_;
}
protected:
- nand_protocol_ops_t nand_proto_ops_ = {};
+ nand_protocol_ops_t ops_ = {};
private:
- static void Query(void* ctx, nand_info_t* info_out, size_t* nand_op_size_out) {
- static_cast<D*>(ctx)->Query(info_out, nand_op_size_out);
+ // Obtains the parameters of the nand device (nand_info_t) and the required
+ // size of nand_op_t. The nand_op_t's submitted via queue() must have
+ // nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
+ // structure for the use of the driver.
+ static void NandQuery(void* ctx, nand_info_t* out_info, size_t* out_nand_op_size) {
+ static_cast<D*>(ctx)->NandQuery(out_info, out_nand_op_size);
}
-
- static void Queue(void* ctx, nand_op_t* operation) {
- static_cast<D*>(ctx)->Queue(operation);
+ // Submits an IO request for processing. Success or failure will be reported
+ // via the completion_cb() in the nand_op_t. The callback may be called
+ // before the queue() method returns.
+ static void NandQueue(void* ctx, nand_operation_t* op, nand_queue_callback callback,
+ void* cookie) {
+ static_cast<D*>(ctx)->NandQueue(op, callback, cookie);
}
-
- static zx_status_t GetFactoryBadBlockList(void* ctx, uint32_t* bad_blocks,
- uint32_t bad_block_len, uint32_t* num_bad_blocks) {
- return static_cast<D*>(ctx)->GetFactoryBadBlockList(bad_blocks, bad_block_len,
- num_bad_blocks);
+ // Gets the list of bad erase blocks, as reported by the nand manufacturer.
+ // The caller must allocate a table large enough to hold the expected number
+ // of entries, and pass the size of that table on |bad_block_len|.
+ // On return, |num_bad_blocks| contains the number of bad blocks found.
+ // This should only be called before writing any data to the nand, and the
+ // returned data should be saved somewhere else, along blocks that become
+ // bad after they've been in use.
+ static zx_status_t NandGetFactoryBadBlockList(void* ctx, uint32_t* out_bad_blocks_list,
+ size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual) {
+ return static_cast<D*>(ctx)->NandGetFactoryBadBlockList(
+ out_bad_blocks_list, bad_blocks_count, out_bad_blocks_actual);
}
};
class NandProtocolProxy {
public:
- NandProtocolProxy(nand_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ NandProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ NandProtocolProxy(const nand_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
- void Query(nand_info_t* info_out, size_t* nand_op_size_out) {
- ops_->query(ctx_, info_out, nand_op_size_out);
+ void GetProto(nand_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
-
- void Queue(nand_op_t* operation) {
- ops_->queue(ctx_, operation);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
-
- zx_status_t GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
- uint32_t* num_bad_blocks) {
- return ops_->get_factory_bad_block_list(ctx_, bad_blocks, bad_block_len, num_bad_blocks);
+ // Obtains the parameters of the nand device (nand_info_t) and the required
+ // size of nand_op_t. The nand_op_t's submitted via queue() must have
+ // nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
+ // structure for the use of the driver.
+ void Query(nand_info_t* out_info, size_t* out_nand_op_size) {
+ ops_->query(ctx_, out_info, out_nand_op_size);
+ }
+ // Submits an IO request for processing. Success or failure will be reported
+ // via the completion_cb() in the nand_op_t. The callback may be called
+ // before the queue() method returns.
+ void Queue(nand_operation_t* op, nand_queue_callback callback, void* cookie) {
+ ops_->queue(ctx_, op, callback, cookie);
+ }
+ // Gets the list of bad erase blocks, as reported by the nand manufacturer.
+ // The caller must allocate a table large enough to hold the expected number
+ // of entries, and pass the size of that table on |bad_block_len|.
+ // On return, |num_bad_blocks| contains the number of bad blocks found.
+ // This should only be called before writing any data to the nand, and the
+ // returned data should be saved somewhere else, along blocks that become
+ // bad after they've been in use.
+ zx_status_t GetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t bad_blocks_count,
+ size_t* out_bad_blocks_actual) {
+ return ops_->get_factory_bad_block_list(ctx_, out_bad_blocks_list, bad_blocks_count,
+ out_bad_blocks_actual);
}
private:
diff --git a/system/ulib/ddktl/include/ddktl/protocol/pci-internal.h b/system/ulib/ddktl/include/ddktl/protocol/pci-internal.h
new file mode 100644
index 0000000..4f37e57
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/pci-internal.h
@@ -0,0 +1,96 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/pci.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_get_bar, PciGetBar,
+ zx_status_t (C::*)(uint32_t bar_id, zx_pci_bar_t* out_res));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_map_bar, PciMapBar,
+ zx_status_t (C::*)(uint32_t bar_id, uint32_t cache_policy,
+ void** out_vaddr_buffer, size_t* vaddr_size,
+ zx_handle_t* out_handle));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_enable_bus_master, PciEnableBusMaster,
+ zx_status_t (C::*)(bool enable));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_reset_device, PciResetDevice,
+ zx_status_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_map_interrupt, PciMapInterrupt,
+ zx_status_t (C::*)(zx_status_t which_irq,
+ zx_handle_t* out_handle));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_query_irq_mode, PciQueryIrqMode,
+ zx_status_t (C::*)(zx_pci_irq_mode_t mode,
+ uint32_t* out_max_irqs));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_set_irq_mode, PciSetIrqMode,
+ zx_status_t (C::*)(zx_pci_irq_mode_t mode,
+ uint32_t requested_irq_count));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_get_device_info, PciGetDeviceInfo,
+ zx_status_t (C::*)(zx_pcie_device_info_t* out_into));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_config_read, PciConfigRead,
+ zx_status_t (C::*)(uint16_t offset, size_t width,
+ uint32_t* out_value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_config_write, PciConfigWrite,
+ zx_status_t (C::*)(uint16_t offset, size_t width,
+ uint32_t value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_get_next_capability, PciGetNextCapability,
+ uint8_t (C::*)(uint8_t type, uint8_t offset));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_get_auxdata, PciGetAuxdata,
+ zx_status_t (C::*)(const char* args, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pci_protocol_get_bti, PciGetBti,
+ zx_status_t (C::*)(uint32_t index, zx_handle_t* out_bti));
+
+template <typename D>
+constexpr void CheckPciProtocolSubclass() {
+ static_assert(internal::has_pci_protocol_get_bar<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciGetBar(uint32_t bar_id, zx_pci_bar_t* out_res");
+ static_assert(internal::has_pci_protocol_map_bar<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciMapBar(uint32_t bar_id, uint32_t cache_policy, void** "
+ "out_vaddr_buffer, size_t* vaddr_size, zx_handle_t* out_handle");
+ static_assert(internal::has_pci_protocol_enable_bus_master<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciEnableBusMaster(bool enable");
+ static_assert(internal::has_pci_protocol_reset_device<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciResetDevice(");
+ static_assert(internal::has_pci_protocol_map_interrupt<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciMapInterrupt(zx_status_t which_irq, zx_handle_t* out_handle");
+ static_assert(internal::has_pci_protocol_query_irq_mode<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciQueryIrqMode(zx_pci_irq_mode_t mode, uint32_t* out_max_irqs");
+ static_assert(internal::has_pci_protocol_set_irq_mode<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciSetIrqMode(zx_pci_irq_mode_t mode, uint32_t requested_irq_count");
+ static_assert(internal::has_pci_protocol_get_device_info<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciGetDeviceInfo(zx_pcie_device_info_t* out_into");
+ static_assert(internal::has_pci_protocol_config_read<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciConfigRead(uint16_t offset, size_t width, uint32_t* out_value");
+ static_assert(internal::has_pci_protocol_config_write<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciConfigWrite(uint16_t offset, size_t width, uint32_t value");
+ static_assert(internal::has_pci_protocol_get_next_capability<D>::value,
+ "PciProtocol subclasses must implement "
+ "uint8_t PciGetNextCapability(uint8_t type, uint8_t offset");
+ static_assert(internal::has_pci_protocol_get_auxdata<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciGetAuxdata(const char* args, void* out_data_buffer, size_t "
+ "data_size, size_t* out_data_actual");
+ static_assert(internal::has_pci_protocol_get_bti<D>::value,
+ "PciProtocol subclasses must implement "
+ "zx_status_t PciGetBti(uint32_t index, zx_handle_t* out_bti");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/pci.h b/system/ulib/ddktl/include/ddktl/protocol/pci.h
index 4c9ba37..2683497 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/pci.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/pci.h
@@ -1,130 +1,202 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/pci.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/syscalls/pci.h>
+#include <zircon/types.h>
-// DDK PCI protocol support
+#include "pci-internal.h"
+
+// DDK pci-protocol support
//
-// :: Proxy ::
+// :: Proxies ::
//
-// ddk::PciProtocolProxy is a simple wrapper around pci_protocol_t. It does not own the pointers
-// passed to it.
+// ddk::PciProtocolProxy is a simple wrapper around
+// pci_protocol_t. It does not own the pointers passed to it
//
-// :: Mixin ::
+// :: Mixins ::
//
-// No mixins are defined, as it is not expected that there will be multiple implementations of the
-// pci protocol.
+// ddk::PciProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the pci protocol. It doesn't set the base protocol.
//
-// :: Example ::
+// :: Examples ::
//
-// // A driver that communicates with a ZX_PROTOCOL_PCI device
-// class MyDevice;
-// using MyDeviceType = ddk::Device<MyDevice, /* ddk mixins */>;
+// // A driver that implements a ZX_PROTOCOL_PCI device.
+// class PciDevice {
+// using PciDeviceType = ddk::Device<PciDevice, /* ddk mixins */>;
//
-// class MyDevice : public MyDeviceType {
+// class PciDevice : public PciDeviceType,
+// public ddk::PciProtocol<PciDevice> {
// public:
-// MyDevice(zx_device_t* parent)
-// : MyDeviceType(parent) {}
+// PciDevice(zx_device_t* parent)
+// : PciDeviceType("my-pci-protocol-device", parent) {}
//
-// void DdkRelease() {
-// // Clean up
-// delete this;
-// }
+// zx_status_t PciGetBar(uint32_t bar_id, zx_pci_bar_t* out_res);
//
-// zx_status_t Bind() {
-// pci_protocol_t* ops;
-// auto status = get_device_protocol(parent_, ZX_PROTOCOL_PCI,
-// reinterpret_cast<void**>(&ops));
-// if (status != ZX_OK) {
-// return status;
-// }
-// pci_.reset(new ddk::PciProtocolProxy(ops));
+// zx_status_t PciMapBar(uint32_t bar_id, uint32_t cache_policy, void** out_vaddr_buffer,
+// size_t* vaddr_size, zx_handle_t* out_handle);
//
-// // Query interrupt capabilities, etc.
-// uint32_t irq_count = 0;
-// if (pci_.QueryIrqModeCaps(ZX_PCIE_IRQ_MODE_MSI, &irq_count) == ZX_OK) {
-// // etc
-// }
-
-// return DdkAdd("my-device");
-// }
+// zx_status_t PciEnableBusMaster(bool enable);
//
-// private:
-// fbl::unique_ptr<ddk::PciProtocolProxy> pci_;
+// zx_status_t PciResetDevice();
+//
+// zx_status_t PciMapInterrupt(zx_status_t which_irq, zx_handle_t* out_handle);
+//
+// zx_status_t PciQueryIrqMode(zx_pci_irq_mode_t mode, uint32_t* out_max_irqs);
+//
+// zx_status_t PciSetIrqMode(zx_pci_irq_mode_t mode, uint32_t requested_irq_count);
+//
+// zx_status_t PciGetDeviceInfo(zx_pcie_device_info_t* out_into);
+//
+// zx_status_t PciConfigRead(uint16_t offset, size_t width, uint32_t* out_value);
+//
+// zx_status_t PciConfigWrite(uint16_t offset, size_t width, uint32_t value);
+//
+// uint8_t PciGetNextCapability(uint8_t type, uint8_t offset);
+//
+// zx_status_t PciGetAuxdata(const char* args, void* out_data_buffer, size_t data_size, size_t*
+// out_data_actual);
+//
+// zx_status_t PciGetBti(uint32_t index, zx_handle_t* out_bti);
+//
+// ...
// };
namespace ddk {
+template <typename D>
+class PciProtocol : public internal::base_mixin {
+public:
+ PciProtocol() {
+ internal::CheckPciProtocolSubclass<D>();
+ pci_protocol_ops_.get_bar = PciGetBar;
+ pci_protocol_ops_.map_bar = PciMapBar;
+ pci_protocol_ops_.enable_bus_master = PciEnableBusMaster;
+ pci_protocol_ops_.reset_device = PciResetDevice;
+ pci_protocol_ops_.map_interrupt = PciMapInterrupt;
+ pci_protocol_ops_.query_irq_mode = PciQueryIrqMode;
+ pci_protocol_ops_.set_irq_mode = PciSetIrqMode;
+ pci_protocol_ops_.get_device_info = PciGetDeviceInfo;
+ pci_protocol_ops_.config_read = PciConfigRead;
+ pci_protocol_ops_.config_write = PciConfigWrite;
+ pci_protocol_ops_.get_next_capability = PciGetNextCapability;
+ pci_protocol_ops_.get_auxdata = PciGetAuxdata;
+ pci_protocol_ops_.get_bti = PciGetBti;
+ }
+
+protected:
+ pci_protocol_ops_t pci_protocol_ops_ = {};
+
+private:
+ static zx_status_t PciGetBar(void* ctx, uint32_t bar_id, zx_pci_bar_t* out_res) {
+ return static_cast<D*>(ctx)->PciGetBar(bar_id, out_res);
+ }
+ static zx_status_t PciMapBar(void* ctx, uint32_t bar_id, uint32_t cache_policy,
+ void** out_vaddr_buffer, size_t* vaddr_size,
+ zx_handle_t* out_handle) {
+ return static_cast<D*>(ctx)->PciMapBar(bar_id, cache_policy, out_vaddr_buffer, vaddr_size,
+ out_handle);
+ }
+ static zx_status_t PciEnableBusMaster(void* ctx, bool enable) {
+ return static_cast<D*>(ctx)->PciEnableBusMaster(enable);
+ }
+ static zx_status_t PciResetDevice(void* ctx) { return static_cast<D*>(ctx)->PciResetDevice(); }
+ static zx_status_t PciMapInterrupt(void* ctx, zx_status_t which_irq, zx_handle_t* out_handle) {
+ return static_cast<D*>(ctx)->PciMapInterrupt(which_irq, out_handle);
+ }
+ static zx_status_t PciQueryIrqMode(void* ctx, zx_pci_irq_mode_t mode, uint32_t* out_max_irqs) {
+ return static_cast<D*>(ctx)->PciQueryIrqMode(mode, out_max_irqs);
+ }
+ static zx_status_t PciSetIrqMode(void* ctx, zx_pci_irq_mode_t mode,
+ uint32_t requested_irq_count) {
+ return static_cast<D*>(ctx)->PciSetIrqMode(mode, requested_irq_count);
+ }
+ static zx_status_t PciGetDeviceInfo(void* ctx, zx_pcie_device_info_t* out_into) {
+ return static_cast<D*>(ctx)->PciGetDeviceInfo(out_into);
+ }
+ static zx_status_t PciConfigRead(void* ctx, uint16_t offset, size_t width,
+ uint32_t* out_value) {
+ return static_cast<D*>(ctx)->PciConfigRead(offset, width, out_value);
+ }
+ static zx_status_t PciConfigWrite(void* ctx, uint16_t offset, size_t width, uint32_t value) {
+ return static_cast<D*>(ctx)->PciConfigWrite(offset, width, value);
+ }
+ static uint8_t PciGetNextCapability(void* ctx, uint8_t type, uint8_t offset) {
+ return static_cast<D*>(ctx)->PciGetNextCapability(type, offset);
+ }
+ static zx_status_t PciGetAuxdata(void* ctx, const char* args, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual) {
+ return static_cast<D*>(ctx)->PciGetAuxdata(args, out_data_buffer, data_size,
+ out_data_actual);
+ }
+ static zx_status_t PciGetBti(void* ctx, uint32_t index, zx_handle_t* out_bti) {
+ return static_cast<D*>(ctx)->PciGetBti(index, out_bti);
+ }
+};
+
class PciProtocolProxy {
- public:
- PciProtocolProxy(pci_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+public:
+ PciProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ PciProtocolProxy(const pci_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
- zx_status_t GetResource(uint32_t res_id, zx_pci_bar_t* out_res) {
- return ops_->get_resource(ctx_, res_id, out_res);
+ void GetProto(pci_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
-
- zx_status_t MapResource(uint32_t res_id, uint32_t cache_policy, void** vaddr, size_t* size,
- zx_handle_t* out_handle) {
- return ops_->map_resource(ctx_, res_id, cache_policy, vaddr, size, out_handle);
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
}
-
- zx_status_t EnableBusMaster(bool enable) {
- return ops_->enable_bus_master(ctx_, enable);
+ zx_status_t GetBar(uint32_t bar_id, zx_pci_bar_t* out_res) {
+ return ops_->get_bar(ctx_, bar_id, out_res);
}
-
- zx_status_t ResetDevice() {
- return ops_->reset_device(ctx_);
+ zx_status_t MapBar(uint32_t bar_id, uint32_t cache_policy, void** out_vaddr_buffer,
+ size_t* vaddr_size, zx_handle_t* out_handle) {
+ return ops_->map_bar(ctx_, bar_id, cache_policy, out_vaddr_buffer, vaddr_size, out_handle);
}
-
- zx_status_t MapInterrupt(int which_irq, zx_handle_t* out_handle) {
+ zx_status_t EnableBusMaster(bool enable) { return ops_->enable_bus_master(ctx_, enable); }
+ zx_status_t ResetDevice() { return ops_->reset_device(ctx_); }
+ zx_status_t MapInterrupt(zx_status_t which_irq, zx_handle_t* out_handle) {
return ops_->map_interrupt(ctx_, which_irq, out_handle);
}
-
- zx_status_t QueryIrqModeCaps(zx_pci_irq_mode_t mode, uint32_t* out_max_irqs) {
+ zx_status_t QueryIrqMode(zx_pci_irq_mode_t mode, uint32_t* out_max_irqs) {
return ops_->query_irq_mode(ctx_, mode, out_max_irqs);
}
-
zx_status_t SetIrqMode(zx_pci_irq_mode_t mode, uint32_t requested_irq_count) {
return ops_->set_irq_mode(ctx_, mode, requested_irq_count);
}
-
- zx_status_t GetDeviceInfo(zx_pcie_device_info_t* out_info) {
- return ops_->get_device_info(ctx_, out_info);
+ zx_status_t GetDeviceInfo(zx_pcie_device_info_t* out_into) {
+ return ops_->get_device_info(ctx_, out_into);
}
-
- zx_status_t ConfigRead(uint8_t offset, size_t width, uint32_t *value) {
- return ops_->config_read(ctx_, offset, width, value);
+ zx_status_t ConfigRead(uint16_t offset, size_t width, uint32_t* out_value) {
+ return ops_->config_read(ctx_, offset, width, out_value);
}
-
- zx_status_t ConfigRead8(uint8_t offset, uint8_t *value) {
- uint32_t val;
- zx_status_t status = ConfigRead(offset, 8, &val);
- *value = val & 0xff;
- return status;
+ zx_status_t ConfigWrite(uint16_t offset, size_t width, uint32_t value) {
+ return ops_->config_write(ctx_, offset, width, value);
}
-
- zx_status_t ConfigRead16(uint8_t offset, uint16_t *value) {
- uint32_t val;
- zx_status_t status = ConfigRead(offset, 16, &val);
- *value = val & 0xffff;
- return status;
- }
-
uint8_t GetNextCapability(uint8_t type, uint8_t offset) {
return ops_->get_next_capability(ctx_, type, offset);
}
-
- uint8_t GetFirstCapability(uint8_t type) {
- return GetNextCapability(kPciCfgCapabilitiesPtr - 1u, type);
+ zx_status_t GetAuxdata(const char* args, void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual) {
+ return ops_->get_auxdata(ctx_, args, out_data_buffer, data_size, out_data_actual);
+ }
+ zx_status_t GetBti(uint32_t index, zx_handle_t* out_bti) {
+ return ops_->get_bti(ctx_, index, out_bti);
}
- private:
+private:
pci_protocol_ops_t* ops_;
void* ctx_;
};
-} // namespace ddk
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/pciroot-internal.h b/system/ulib/ddktl/include/ddktl/protocol/pciroot-internal.h
new file mode 100644
index 0000000..ea96ab0
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/pciroot-internal.h
@@ -0,0 +1,34 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/pciroot.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pciroot_protocol_get_auxdata, PcirootGetAuxdata,
+ zx_status_t (C::*)(const char* args, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_pciroot_protocol_get_bti, PcirootGetBti,
+ zx_status_t (C::*)(uint32_t bdf, uint32_t index,
+ zx_handle_t* out_bti));
+
+template <typename D>
+constexpr void CheckPcirootProtocolSubclass() {
+ static_assert(internal::has_pciroot_protocol_get_auxdata<D>::value,
+ "PcirootProtocol subclasses must implement "
+ "zx_status_t PcirootGetAuxdata(const char* args, void* out_data_buffer, size_t "
+ "data_size, size_t* out_data_actual");
+ static_assert(internal::has_pciroot_protocol_get_bti<D>::value,
+ "PcirootProtocol subclasses must implement "
+ "zx_status_t PcirootGetBti(uint32_t bdf, uint32_t index, zx_handle_t* out_bti");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/pciroot.h b/system/ulib/ddktl/include/ddktl/protocol/pciroot.h
new file mode 100644
index 0000000..bf97bd1
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/pciroot.h
@@ -0,0 +1,102 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/pciroot.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "pciroot-internal.h"
+
+// DDK pciroot-protocol support
+//
+// :: Proxies ::
+//
+// ddk::PcirootProtocolProxy is a simple wrapper around
+// pciroot_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::PcirootProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the pciroot protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_PCIROOT device.
+// class PcirootDevice {
+// using PcirootDeviceType = ddk::Device<PcirootDevice, /* ddk mixins */>;
+//
+// class PcirootDevice : public PcirootDeviceType,
+// public ddk::PcirootProtocol<PcirootDevice> {
+// public:
+// PcirootDevice(zx_device_t* parent)
+// : PcirootDeviceType("my-pciroot-protocol-device", parent) {}
+//
+// zx_status_t PcirootGetAuxdata(const char* args, void* out_data_buffer, size_t data_size,
+// size_t* out_data_actual);
+//
+// zx_status_t PcirootGetBti(uint32_t bdf, uint32_t index, zx_handle_t* out_bti);
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class PcirootProtocol : public internal::base_mixin {
+public:
+ PcirootProtocol() {
+ internal::CheckPcirootProtocolSubclass<D>();
+ pciroot_protocol_ops_.get_auxdata = PcirootGetAuxdata;
+ pciroot_protocol_ops_.get_bti = PcirootGetBti;
+ }
+
+protected:
+ pciroot_protocol_ops_t pciroot_protocol_ops_ = {};
+
+private:
+ static zx_status_t PcirootGetAuxdata(void* ctx, const char* args, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual) {
+ return static_cast<D*>(ctx)->PcirootGetAuxdata(args, out_data_buffer, data_size,
+ out_data_actual);
+ }
+ static zx_status_t PcirootGetBti(void* ctx, uint32_t bdf, uint32_t index,
+ zx_handle_t* out_bti) {
+ return static_cast<D*>(ctx)->PcirootGetBti(bdf, index, out_bti);
+ }
+};
+
+class PcirootProtocolProxy {
+public:
+ PcirootProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ PcirootProtocolProxy(const pciroot_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(pciroot_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t GetAuxdata(const char* args, void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual) {
+ return ops_->get_auxdata(ctx_, args, out_data_buffer, data_size, out_data_actual);
+ }
+ zx_status_t GetBti(uint32_t bdf, uint32_t index, zx_handle_t* out_bti) {
+ return ops_->get_bti(ctx_, bdf, index, out_bti);
+ }
+
+private:
+ pciroot_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/rawnand-internal.h b/system/ulib/ddktl/include/ddktl/protocol/rawnand-internal.h
new file mode 100644
index 0000000..dd07e28
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/rawnand-internal.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/rawnand.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_raw_nand_protocol_read_page_hwecc, RawNandReadPageHwecc,
+ zx_status_t (C::*)(uint32_t nandpage, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual,
+ void* out_oob_buffer, size_t oob_size,
+ size_t* out_oob_actual,
+ zx_status_t* out_ecc_correct));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_raw_nand_protocol_write_page_hwecc, RawNandWritePageHwecc,
+ zx_status_t (C::*)(const void* data_buffer, size_t data_size,
+ const void* oob_buffer, size_t oob_size,
+ uint32_t nandpage));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_raw_nand_protocol_erase_block, RawNandEraseBlock,
+ zx_status_t (C::*)(uint32_t nandpage));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_raw_nand_protocol_get_nand_info, RawNandGetNandInfo,
+ zx_status_t (C::*)(nand_info_t* out_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_raw_nand_protocol_cmd_ctrl, RawNandCmdCtrl,
+ void (C::*)(zx_status_t cmd, uint32_t ctrl));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_raw_nand_protocol_read_byte, RawNandReadByte,
+ uint8_t (C::*)());
+
+template <typename D>
+constexpr void CheckRawNandProtocolSubclass() {
+ static_assert(internal::has_raw_nand_protocol_read_page_hwecc<D>::value,
+ "RawNandProtocol subclasses must implement "
+ "zx_status_t RawNandReadPageHwecc(uint32_t nandpage, void* out_data_buffer, "
+ "size_t data_size, size_t* out_data_actual, void* out_oob_buffer, size_t "
+ "oob_size, size_t* out_oob_actual, zx_status_t* out_ecc_correct");
+ static_assert(internal::has_raw_nand_protocol_write_page_hwecc<D>::value,
+ "RawNandProtocol subclasses must implement "
+ "zx_status_t RawNandWritePageHwecc(const void* data_buffer, size_t data_size, "
+ "const void* oob_buffer, size_t oob_size, uint32_t nandpage");
+ static_assert(internal::has_raw_nand_protocol_erase_block<D>::value,
+ "RawNandProtocol subclasses must implement "
+ "zx_status_t RawNandEraseBlock(uint32_t nandpage");
+ static_assert(internal::has_raw_nand_protocol_get_nand_info<D>::value,
+ "RawNandProtocol subclasses must implement "
+ "zx_status_t RawNandGetNandInfo(nand_info_t* out_info");
+ static_assert(internal::has_raw_nand_protocol_cmd_ctrl<D>::value,
+ "RawNandProtocol subclasses must implement "
+ "void RawNandCmdCtrl(zx_status_t cmd, uint32_t ctrl");
+ static_assert(internal::has_raw_nand_protocol_read_byte<D>::value,
+ "RawNandProtocol subclasses must implement "
+ "uint8_t RawNandReadByte(");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/rawnand.h b/system/ulib/ddktl/include/ddktl/protocol/rawnand.h
new file mode 100644
index 0000000..8455044
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/rawnand.h
@@ -0,0 +1,149 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/rawnand.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/device/nand.h>
+#include <zircon/types.h>
+
+#include "rawnand-internal.h"
+
+// DDK raw-nand-protocol support
+//
+// :: Proxies ::
+//
+// ddk::RawNandProtocolProxy is a simple wrapper around
+// raw_nand_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::RawNandProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the raw-nand protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_RAW_NAND device.
+// class RawNandDevice {
+// using RawNandDeviceType = ddk::Device<RawNandDevice, /* ddk mixins */>;
+//
+// class RawNandDevice : public RawNandDeviceType,
+// public ddk::RawNandProtocol<RawNandDevice> {
+// public:
+// RawNandDevice(zx_device_t* parent)
+// : RawNandDeviceType("my-raw-nand-protocol-device", parent) {}
+//
+// zx_status_t RawNandReadPageHwecc(uint32_t nandpage, void* out_data_buffer, size_t data_size,
+// size_t* out_data_actual, void* out_oob_buffer, size_t oob_size, size_t* out_oob_actual,
+// zx_status_t* out_ecc_correct);
+//
+// zx_status_t RawNandWritePageHwecc(const void* data_buffer, size_t data_size, const void*
+// oob_buffer, size_t oob_size, uint32_t nandpage);
+//
+// zx_status_t RawNandEraseBlock(uint32_t nandpage);
+//
+// zx_status_t RawNandGetNandInfo(nand_info_t* out_info);
+//
+// void RawNandCmdCtrl(zx_status_t cmd, uint32_t ctrl);
+//
+// uint8_t RawNandReadByte();
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class RawNandProtocol : public internal::base_mixin {
+public:
+ RawNandProtocol() {
+ internal::CheckRawNandProtocolSubclass<D>();
+ raw_nand_protocol_ops_.read_page_hwecc = RawNandReadPageHwecc;
+ raw_nand_protocol_ops_.write_page_hwecc = RawNandWritePageHwecc;
+ raw_nand_protocol_ops_.erase_block = RawNandEraseBlock;
+ raw_nand_protocol_ops_.get_nand_info = RawNandGetNandInfo;
+ raw_nand_protocol_ops_.cmd_ctrl = RawNandCmdCtrl;
+ raw_nand_protocol_ops_.read_byte = RawNandReadByte;
+ }
+
+protected:
+ raw_nand_protocol_ops_t raw_nand_protocol_ops_ = {};
+
+private:
+ // Read one nand page with hwecc.
+ static zx_status_t RawNandReadPageHwecc(void* ctx, uint32_t nandpage, void* out_data_buffer,
+ size_t data_size, size_t* out_data_actual,
+ void* out_oob_buffer, size_t oob_size,
+ size_t* out_oob_actual, zx_status_t* out_ecc_correct) {
+ return static_cast<D*>(ctx)->RawNandReadPageHwecc(nandpage, out_data_buffer, data_size,
+ out_data_actual, out_oob_buffer, oob_size,
+ out_oob_actual, out_ecc_correct);
+ }
+ // Write one nand page with hwecc.
+ static zx_status_t RawNandWritePageHwecc(void* ctx, const void* data_buffer, size_t data_size,
+ const void* oob_buffer, size_t oob_size,
+ uint32_t nandpage) {
+ return static_cast<D*>(ctx)->RawNandWritePageHwecc(data_buffer, data_size, oob_buffer,
+ oob_size, nandpage);
+ }
+ // Erase nand block.
+ static zx_status_t RawNandEraseBlock(void* ctx, uint32_t nandpage) {
+ return static_cast<D*>(ctx)->RawNandEraseBlock(nandpage);
+ }
+ static zx_status_t RawNandGetNandInfo(void* ctx, nand_info_t* out_info) {
+ return static_cast<D*>(ctx)->RawNandGetNandInfo(out_info);
+ }
+ // Send ONFI command down to controller.
+ static void RawNandCmdCtrl(void* ctx, zx_status_t cmd, uint32_t ctrl) {
+ static_cast<D*>(ctx)->RawNandCmdCtrl(cmd, ctrl);
+ }
+ // Read byte (used to read status as well as other info, such as ID).
+ static uint8_t RawNandReadByte(void* ctx) { return static_cast<D*>(ctx)->RawNandReadByte(); }
+};
+
+class RawNandProtocolProxy {
+public:
+ RawNandProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ RawNandProtocolProxy(const raw_nand_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(raw_nand_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Read one nand page with hwecc.
+ zx_status_t ReadPageHwecc(uint32_t nandpage, void* out_data_buffer, size_t data_size,
+ size_t* out_data_actual, void* out_oob_buffer, size_t oob_size,
+ size_t* out_oob_actual, zx_status_t* out_ecc_correct) {
+ return ops_->read_page_hwecc(ctx_, nandpage, out_data_buffer, data_size, out_data_actual,
+ out_oob_buffer, oob_size, out_oob_actual, out_ecc_correct);
+ }
+ // Write one nand page with hwecc.
+ zx_status_t WritePageHwecc(const void* data_buffer, size_t data_size, const void* oob_buffer,
+ size_t oob_size, uint32_t nandpage) {
+ return ops_->write_page_hwecc(ctx_, data_buffer, data_size, oob_buffer, oob_size, nandpage);
+ }
+ // Erase nand block.
+ zx_status_t EraseBlock(uint32_t nandpage) { return ops_->erase_block(ctx_, nandpage); }
+ zx_status_t GetNandInfo(nand_info_t* out_info) { return ops_->get_nand_info(ctx_, out_info); }
+ // Send ONFI command down to controller.
+ void CmdCtrl(zx_status_t cmd, uint32_t ctrl) { ops_->cmd_ctrl(ctx_, cmd, ctrl); }
+ // Read byte (used to read status as well as other info, such as ID).
+ uint8_t ReadByte() { return ops_->read_byte(ctx_); }
+
+private:
+ raw_nand_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/scpi-internal.h b/system/ulib/ddktl/include/ddktl/protocol/scpi-internal.h
index c44f04a..0cbd632 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/scpi-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/scpi-internal.h
@@ -2,42 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
+#include <ddk/protocol/scpi.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_get_sensor, ScpiGetSensor,
- zx_status_t (C::*)(const char*, uint32_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_get_sensor_value, ScpiGetSensorValue,
- zx_status_t (C::*)(uint32_t, uint32_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_get_dvfs_info, ScpiGetDvfsInfo,
- zx_status_t (C::*)(uint8_t, scpi_opp_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_get_dvfs_idx, ScpiGetDvfsIdx,
- zx_status_t (C::*)(uint8_t, uint16_t*));
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_set_dvfs_idx, ScpiSetDvfsIdx,
- zx_status_t (C::*)(uint8_t, uint16_t));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_protocol_get_sensor, ScpiGetSensor,
+ zx_status_t (C::*)(const char* name, uint32_t* out_sensor_id));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_protocol_get_sensor_value, ScpiGetSensorValue,
+ zx_status_t (C::*)(uint32_t sensor_id,
+ uint32_t* out_sensor_value));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_protocol_get_dvfs_info, ScpiGetDvfsInfo,
+ zx_status_t (C::*)(uint8_t power_domain,
+ scpi_opp_t* out_opps));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_protocol_get_dvfs_idx, ScpiGetDvfsIdx,
+ zx_status_t (C::*)(uint8_t power_domain, uint16_t* out_index));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_scpi_protocol_set_dvfs_idx, ScpiSetDvfsIdx,
+ zx_status_t (C::*)(uint8_t power_domain, uint16_t index));
template <typename D>
constexpr void CheckScpiProtocolSubclass() {
- static_assert(internal::has_scpi_get_sensor<D>::value,
+ static_assert(internal::has_scpi_protocol_get_sensor<D>::value,
"ScpiProtocol subclasses must implement "
- "ScpiGetSensor(const char* name, uint32_t* sensor_id)");
- static_assert(internal::has_scpi_get_sensor_value<D>::value,
+ "zx_status_t ScpiGetSensor(const char* name, uint32_t* out_sensor_id");
+ static_assert(internal::has_scpi_protocol_get_sensor_value<D>::value,
"ScpiProtocol subclasses must implement "
- "ScpiGetSensorValue(uint32_t sensor_id, uint32_t* sensor_value)");
- static_assert(internal::has_scpi_get_dvfs_info<D>::value,
+ "zx_status_t ScpiGetSensorValue(uint32_t sensor_id, uint32_t* out_sensor_value");
+ static_assert(internal::has_scpi_protocol_get_dvfs_info<D>::value,
"ScpiProtocol subclasses must implement "
- "ScpiGetDvfsInfo(uint8_t power_domain, scpi_opp_t* opps)");
- static_assert(internal::has_scpi_get_dvfs_idx<D>::value,
+ "zx_status_t ScpiGetDvfsInfo(uint8_t power_domain, scpi_opp_t* out_opps");
+ static_assert(internal::has_scpi_protocol_get_dvfs_idx<D>::value,
"ScpiProtocol subclasses must implement "
- "ScpiGetDvfsIdx(uint8_t power_domain, uint16_t* idx)");
- static_assert(internal::has_scpi_set_dvfs_idx<D>::value,
+ "zx_status_t ScpiGetDvfsIdx(uint8_t power_domain, uint16_t* out_index");
+ static_assert(internal::has_scpi_protocol_set_dvfs_idx<D>::value,
"ScpiProtocol subclasses must implement "
- "ScpiSetDvfsIdx(uint8_t power_domain, uint16_t idx)");
- }
+ "zx_status_t ScpiSetDvfsIdx(uint8_t power_domain, uint16_t index");
+}
-} // namespace internal
-} // namespace ddk
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/scpi.h b/system/ulib/ddktl/include/ddktl/protocol/scpi.h
index 13d6e23..b89cbe7 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/scpi.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/scpi.h
@@ -2,107 +2,121 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/scpi.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "scpi-internal.h"
-// DDK SCPI protocol support.
+// DDK scpi-protocol support
//
// :: Proxies ::
//
-// ddk::ScpiProtocolProxy is a simple wrappers around scpi_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::ScpiProtocolProxy is a simple wrapper around
+// scpi_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::ScpiProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the SCPI protocol.
+// ddk::ScpiProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the scpi protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_SCPI device.
-// class ScpiDevice;
+// class ScpiDevice {
// using ScpiDeviceType = ddk::Device<ScpiDevice, /* ddk mixins */>;
//
// class ScpiDevice : public ScpiDeviceType,
// public ddk::ScpiProtocol<ScpiDevice> {
// public:
// ScpiDevice(zx_device_t* parent)
-// : ScpiDeviceType("my-scpi-device", parent) {}
+// : ScpiDeviceType("my-scpi-protocol-device", parent) {}
//
-// zx_status_t ScpiGetSensor(const char* name, uint32_t* sensor_id);
-// zx_status_t ScpiGetSensorValue(uint32_t sensor_id, uint32_t* sensor_value);
-// zx_status_t ScpiGetDvfsInfo(uint8_t power_domain, scpi_opp_t* opps);
-// zx_status_t ScpiGetDvfsIdx(uint8_t power_domain, uint16_t* idx);
-// zx_status_t ScpiSetDvfsIdx(uint8_t power_domain, uint16_t idx);
+// zx_status_t ScpiGetSensor(const char* name, uint32_t* out_sensor_id);
+//
+// zx_status_t ScpiGetSensorValue(uint32_t sensor_id, uint32_t* out_sensor_value);
+//
+// zx_status_t ScpiGetDvfsInfo(uint8_t power_domain, scpi_opp_t* out_opps);
+//
+// zx_status_t ScpiGetDvfsIdx(uint8_t power_domain, uint16_t* out_index);
+//
+// zx_status_t ScpiSetDvfsIdx(uint8_t power_domain, uint16_t index);
+//
// ...
// };
namespace ddk {
template <typename D>
-class ScpiProtocol {
+class ScpiProtocol : public internal::base_mixin {
public:
ScpiProtocol() {
internal::CheckScpiProtocolSubclass<D>();
- scpi_proto_ops_.get_sensor = ScpiGetSensor;
- scpi_proto_ops_.get_sensor_value = ScpiGetSensorValue;
- scpi_proto_ops_.get_dvfs_info = ScpiGetDvfsInfo;
- scpi_proto_ops_.get_dvfs_idx = ScpiGetDvfsIdx;
- scpi_proto_ops_.set_dvfs_idx = ScpiSetDvfsIdx;
+ scpi_protocol_ops_.get_sensor = ScpiGetSensor;
+ scpi_protocol_ops_.get_sensor_value = ScpiGetSensorValue;
+ scpi_protocol_ops_.get_dvfs_info = ScpiGetDvfsInfo;
+ scpi_protocol_ops_.get_dvfs_idx = ScpiGetDvfsIdx;
+ scpi_protocol_ops_.set_dvfs_idx = ScpiSetDvfsIdx;
}
protected:
- scpi_protocol_ops_t scpi_proto_ops_ = {};
+ scpi_protocol_ops_t scpi_protocol_ops_ = {};
private:
- static zx_status_t ScpiGetSensor(void* ctx, const char* name, uint32_t* sensor_id) {
- return static_cast<D*>(ctx)->ScpiGetSensor(name, sensor_id);
+ static zx_status_t ScpiGetSensor(void* ctx, const char* name, uint32_t* out_sensor_id) {
+ return static_cast<D*>(ctx)->ScpiGetSensor(name, out_sensor_id);
}
- static zx_status_t ScpiGetSensorValue(void* ctx, uint32_t sensor_id, uint32_t* sensor_value) {
- return static_cast<D*>(ctx)->ScpiGetSensorValue(sensor_id, sensor_value);
+ static zx_status_t ScpiGetSensorValue(void* ctx, uint32_t sensor_id,
+ uint32_t* out_sensor_value) {
+ return static_cast<D*>(ctx)->ScpiGetSensorValue(sensor_id, out_sensor_value);
}
- static zx_status_t ScpiGetDvfsInfo(void* ctx, uint8_t power_domain, scpi_opp_t* opps) {
- return static_cast<D*>(ctx)->ScpiGetDvfsInfo(power_domain, opps);
+ static zx_status_t ScpiGetDvfsInfo(void* ctx, uint8_t power_domain, scpi_opp_t* out_opps) {
+ return static_cast<D*>(ctx)->ScpiGetDvfsInfo(power_domain, out_opps);
}
- static zx_status_t ScpiGetDvfsIdx(void* ctx, uint8_t power_domain, uint16_t* idx) {
- return static_cast<D*>(ctx)->ScpiGetDvfsIdx(power_domain, idx);
+ static zx_status_t ScpiGetDvfsIdx(void* ctx, uint8_t power_domain, uint16_t* out_index) {
+ return static_cast<D*>(ctx)->ScpiGetDvfsIdx(power_domain, out_index);
}
- static zx_status_t ScpiSetDvfsIdx(void* ctx, uint8_t power_domain, uint16_t idx) {
- return static_cast<D*>(ctx)->ScpiSetDvfsIdx(power_domain, idx);
+ static zx_status_t ScpiSetDvfsIdx(void* ctx, uint8_t power_domain, uint16_t index) {
+ return static_cast<D*>(ctx)->ScpiSetDvfsIdx(power_domain, index);
}
};
class ScpiProtocolProxy {
public:
- ScpiProtocolProxy(scpi_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
+ ScpiProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ ScpiProtocolProxy(const scpi_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(scpi_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t GetSensor(const char* name, uint32_t* out_sensor_id) {
+ return ops_->get_sensor(ctx_, name, out_sensor_id);
+ }
+ zx_status_t GetSensorValue(uint32_t sensor_id, uint32_t* out_sensor_value) {
+ return ops_->get_sensor_value(ctx_, sensor_id, out_sensor_value);
+ }
+ zx_status_t GetDvfsInfo(uint8_t power_domain, scpi_opp_t* out_opps) {
+ return ops_->get_dvfs_info(ctx_, power_domain, out_opps);
+ }
+ zx_status_t GetDvfsIdx(uint8_t power_domain, uint16_t* out_index) {
+ return ops_->get_dvfs_idx(ctx_, power_domain, out_index);
+ }
+ zx_status_t SetDvfsIdx(uint8_t power_domain, uint16_t index) {
+ return ops_->set_dvfs_idx(ctx_, power_domain, index);
+ }
- zx_status_t GetSensor(const char* name, uint32_t* sensor_id) {
- return ops_->get_sensor(ctx_, name, sensor_id);
- }
- zx_status_t GetSensorValue(uint32_t sensor_id, uint32_t* sensor_value) {
- return ops_->get_sensor_value(ctx_, sensor_id, sensor_value);
- }
- zx_status_t GetDvfsInfo(uint8_t power_domain, scpi_opp_t* opps) {
- return ops_->get_dvfs_info(ctx_, power_domain, opps);
- }
- zx_status_t GetDvfsIdx(uint8_t power_domain, uint16_t* idx) {
- return ops_->get_dvfs_idx(ctx_, power_domain, idx);
- }
- zx_status_t SetDvfsIdx(uint8_t power_domain, uint16_t idx) {
- return ops_->set_dvfs_idx(ctx_, power_domain, idx);
- }
-\
private:
scpi_protocol_ops_t* ops_;
void* ctx_;
diff --git a/system/ulib/ddktl/include/ddktl/protocol/sdhci-internal.h b/system/ulib/ddktl/include/ddktl/protocol/sdhci-internal.h
new file mode 100644
index 0000000..f54dac9
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/sdhci-internal.h
@@ -0,0 +1,50 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/sdhci.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdhci_protocol_get_interrupt, SdhciGetInterrupt,
+ zx_status_t (C::*)(zx_handle_t* out_irq));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdhci_protocol_get_mmio, SdhciGetMmio,
+ zx_status_t (C::*)(zx_handle_t* out_mmio));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdhci_protocol_get_bti, SdhciGetBti,
+ zx_status_t (C::*)(uint32_t index, zx_handle_t* out_bti));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdhci_protocol_get_base_clock, SdhciGetBaseClock,
+ uint32_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdhci_protocol_get_quirks, SdhciGetQuirks,
+ uint64_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdhci_protocol_hw_reset, SdhciHwReset, void (C::*)());
+
+template <typename D>
+constexpr void CheckSdhciProtocolSubclass() {
+ static_assert(internal::has_sdhci_protocol_get_interrupt<D>::value,
+ "SdhciProtocol subclasses must implement "
+ "zx_status_t SdhciGetInterrupt(zx_handle_t* out_irq");
+ static_assert(internal::has_sdhci_protocol_get_mmio<D>::value,
+ "SdhciProtocol subclasses must implement "
+ "zx_status_t SdhciGetMmio(zx_handle_t* out_mmio");
+ static_assert(internal::has_sdhci_protocol_get_bti<D>::value,
+ "SdhciProtocol subclasses must implement "
+ "zx_status_t SdhciGetBti(uint32_t index, zx_handle_t* out_bti");
+ static_assert(internal::has_sdhci_protocol_get_base_clock<D>::value,
+ "SdhciProtocol subclasses must implement "
+ "uint32_t SdhciGetBaseClock(");
+ static_assert(internal::has_sdhci_protocol_get_quirks<D>::value,
+ "SdhciProtocol subclasses must implement "
+ "uint64_t SdhciGetQuirks(");
+ static_assert(internal::has_sdhci_protocol_hw_reset<D>::value,
+ "SdhciProtocol subclasses must implement "
+ "void SdhciHwReset(");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/sdhci.h b/system/ulib/ddktl/include/ddktl/protocol/sdhci.h
new file mode 100644
index 0000000..fd03b50
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/sdhci.h
@@ -0,0 +1,128 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/sdhci.h>
+#include <ddktl/device-internal.h>
+#include <hw/sdhci.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "sdhci-internal.h"
+
+// DDK sdhci-protocol support
+//
+// :: Proxies ::
+//
+// ddk::SdhciProtocolProxy is a simple wrapper around
+// sdhci_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::SdhciProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the sdhci protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_SDHCI device.
+// class SdhciDevice {
+// using SdhciDeviceType = ddk::Device<SdhciDevice, /* ddk mixins */>;
+//
+// class SdhciDevice : public SdhciDeviceType,
+// public ddk::SdhciProtocol<SdhciDevice> {
+// public:
+// SdhciDevice(zx_device_t* parent)
+// : SdhciDeviceType("my-sdhci-protocol-device", parent) {}
+//
+// zx_status_t SdhciGetInterrupt(zx_handle_t* out_irq);
+//
+// zx_status_t SdhciGetMmio(zx_handle_t* out_mmio);
+//
+// zx_status_t SdhciGetBti(uint32_t index, zx_handle_t* out_bti);
+//
+// uint32_t SdhciGetBaseClock();
+//
+// uint64_t SdhciGetQuirks();
+//
+// void SdhciHwReset();
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class SdhciProtocol : public internal::base_mixin {
+public:
+ SdhciProtocol() {
+ internal::CheckSdhciProtocolSubclass<D>();
+ sdhci_protocol_ops_.get_interrupt = SdhciGetInterrupt;
+ sdhci_protocol_ops_.get_mmio = SdhciGetMmio;
+ sdhci_protocol_ops_.get_bti = SdhciGetBti;
+ sdhci_protocol_ops_.get_base_clock = SdhciGetBaseClock;
+ sdhci_protocol_ops_.get_quirks = SdhciGetQuirks;
+ sdhci_protocol_ops_.hw_reset = SdhciHwReset;
+ }
+
+protected:
+ sdhci_protocol_ops_t sdhci_protocol_ops_ = {};
+
+private:
+ static zx_status_t SdhciGetInterrupt(void* ctx, zx_handle_t* out_irq) {
+ return static_cast<D*>(ctx)->SdhciGetInterrupt(out_irq);
+ }
+ static zx_status_t SdhciGetMmio(void* ctx, zx_handle_t* out_mmio) {
+ return static_cast<D*>(ctx)->SdhciGetMmio(out_mmio);
+ }
+ // Gets a handle to the bus transaction initiator for the device. The caller
+ // receives ownership of the handle.
+ static zx_status_t SdhciGetBti(void* ctx, uint32_t index, zx_handle_t* out_bti) {
+ return static_cast<D*>(ctx)->SdhciGetBti(index, out_bti);
+ }
+ static uint32_t SdhciGetBaseClock(void* ctx) {
+ return static_cast<D*>(ctx)->SdhciGetBaseClock();
+ }
+ // returns device quirks
+ static uint64_t SdhciGetQuirks(void* ctx) { return static_cast<D*>(ctx)->SdhciGetQuirks(); }
+ // platform specific HW reset
+ static void SdhciHwReset(void* ctx) { static_cast<D*>(ctx)->SdhciHwReset(); }
+};
+
+class SdhciProtocolProxy {
+public:
+ SdhciProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ SdhciProtocolProxy(const sdhci_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(sdhci_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t GetInterrupt(zx_handle_t* out_irq) { return ops_->get_interrupt(ctx_, out_irq); }
+ zx_status_t GetMmio(zx_handle_t* out_mmio) { return ops_->get_mmio(ctx_, out_mmio); }
+ // Gets a handle to the bus transaction initiator for the device. The caller
+ // receives ownership of the handle.
+ zx_status_t GetBti(uint32_t index, zx_handle_t* out_bti) {
+ return ops_->get_bti(ctx_, index, out_bti);
+ }
+ uint32_t GetBaseClock() { return ops_->get_base_clock(ctx_); }
+ // returns device quirks
+ uint64_t GetQuirks() { return ops_->get_quirks(ctx_); }
+ // platform specific HW reset
+ void HwReset() { ops_->hw_reset(ctx_); }
+
+private:
+ sdhci_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/sdio-internal.h b/system/ulib/ddktl/include/ddktl/protocol/sdio-internal.h
new file mode 100644
index 0000000..3c78159
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/sdio-internal.h
@@ -0,0 +1,63 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/sdio.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_get_dev_hw_info, SdioGetDevHwInfo,
+ zx_status_t (C::*)(sdio_hw_info_t* out_hw_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_enable_fn, SdioEnableFn,
+ zx_status_t (C::*)(uint8_t fn_idx));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_disable_fn, SdioDisableFn,
+ zx_status_t (C::*)(uint8_t fn_idx));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_enable_fn_intr, SdioEnableFnIntr,
+ zx_status_t (C::*)(uint8_t fn_idx));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_disable_fn_intr, SdioDisableFnIntr,
+ zx_status_t (C::*)(uint8_t fn_idx));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_update_block_size, SdioUpdateBlockSize,
+ zx_status_t (C::*)(uint8_t fn_idx, uint16_t blk_sz,
+ bool deflt));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_get_block_size, SdioGetBlockSize,
+ zx_status_t (C::*)(uint8_t fn_idx,
+ uint16_t* out_cur_blk_size));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdio_protocol_do_rw_txn, SdioDoRwTxn,
+ zx_status_t (C::*)(uint8_t fn_idx, sdio_rw_txn_t* txn));
+
+template <typename D>
+constexpr void CheckSdioProtocolSubclass() {
+ static_assert(internal::has_sdio_protocol_get_dev_hw_info<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioGetDevHwInfo(sdio_hw_info_t* out_hw_info");
+ static_assert(internal::has_sdio_protocol_enable_fn<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioEnableFn(uint8_t fn_idx");
+ static_assert(internal::has_sdio_protocol_disable_fn<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioDisableFn(uint8_t fn_idx");
+ static_assert(internal::has_sdio_protocol_enable_fn_intr<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioEnableFnIntr(uint8_t fn_idx");
+ static_assert(internal::has_sdio_protocol_disable_fn_intr<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioDisableFnIntr(uint8_t fn_idx");
+ static_assert(internal::has_sdio_protocol_update_block_size<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioUpdateBlockSize(uint8_t fn_idx, uint16_t blk_sz, bool deflt");
+ static_assert(internal::has_sdio_protocol_get_block_size<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioGetBlockSize(uint8_t fn_idx, uint16_t* out_cur_blk_size");
+ static_assert(internal::has_sdio_protocol_do_rw_txn<D>::value,
+ "SdioProtocol subclasses must implement "
+ "zx_status_t SdioDoRwTxn(uint8_t fn_idx, sdio_rw_txn_t* txn");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/sdio.h b/system/ulib/ddktl/include/ddktl/protocol/sdio.h
new file mode 100644
index 0000000..bfcb348
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/sdio.h
@@ -0,0 +1,143 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/sdio.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "sdio-internal.h"
+
+// DDK sdio-protocol support
+//
+// :: Proxies ::
+//
+// ddk::SdioProtocolProxy is a simple wrapper around
+// sdio_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::SdioProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the sdio protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_SDIO device.
+// class SdioDevice {
+// using SdioDeviceType = ddk::Device<SdioDevice, /* ddk mixins */>;
+//
+// class SdioDevice : public SdioDeviceType,
+// public ddk::SdioProtocol<SdioDevice> {
+// public:
+// SdioDevice(zx_device_t* parent)
+// : SdioDeviceType("my-sdio-protocol-device", parent) {}
+//
+// zx_status_t SdioGetDevHwInfo(sdio_hw_info_t* out_hw_info);
+//
+// zx_status_t SdioEnableFn(uint8_t fn_idx);
+//
+// zx_status_t SdioDisableFn(uint8_t fn_idx);
+//
+// zx_status_t SdioEnableFnIntr(uint8_t fn_idx);
+//
+// zx_status_t SdioDisableFnIntr(uint8_t fn_idx);
+//
+// zx_status_t SdioUpdateBlockSize(uint8_t fn_idx, uint16_t blk_sz, bool deflt);
+//
+// zx_status_t SdioGetBlockSize(uint8_t fn_idx, uint16_t* out_cur_blk_size);
+//
+// zx_status_t SdioDoRwTxn(uint8_t fn_idx, sdio_rw_txn_t* txn);
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class SdioProtocol : public internal::base_mixin {
+public:
+ SdioProtocol() {
+ internal::CheckSdioProtocolSubclass<D>();
+ sdio_protocol_ops_.get_dev_hw_info = SdioGetDevHwInfo;
+ sdio_protocol_ops_.enable_fn = SdioEnableFn;
+ sdio_protocol_ops_.disable_fn = SdioDisableFn;
+ sdio_protocol_ops_.enable_fn_intr = SdioEnableFnIntr;
+ sdio_protocol_ops_.disable_fn_intr = SdioDisableFnIntr;
+ sdio_protocol_ops_.update_block_size = SdioUpdateBlockSize;
+ sdio_protocol_ops_.get_block_size = SdioGetBlockSize;
+ sdio_protocol_ops_.do_rw_txn = SdioDoRwTxn;
+ }
+
+protected:
+ sdio_protocol_ops_t sdio_protocol_ops_ = {};
+
+private:
+ static zx_status_t SdioGetDevHwInfo(void* ctx, sdio_hw_info_t* out_hw_info) {
+ return static_cast<D*>(ctx)->SdioGetDevHwInfo(out_hw_info);
+ }
+ static zx_status_t SdioEnableFn(void* ctx, uint8_t fn_idx) {
+ return static_cast<D*>(ctx)->SdioEnableFn(fn_idx);
+ }
+ static zx_status_t SdioDisableFn(void* ctx, uint8_t fn_idx) {
+ return static_cast<D*>(ctx)->SdioDisableFn(fn_idx);
+ }
+ static zx_status_t SdioEnableFnIntr(void* ctx, uint8_t fn_idx) {
+ return static_cast<D*>(ctx)->SdioEnableFnIntr(fn_idx);
+ }
+ static zx_status_t SdioDisableFnIntr(void* ctx, uint8_t fn_idx) {
+ return static_cast<D*>(ctx)->SdioDisableFnIntr(fn_idx);
+ }
+ static zx_status_t SdioUpdateBlockSize(void* ctx, uint8_t fn_idx, uint16_t blk_sz, bool deflt) {
+ return static_cast<D*>(ctx)->SdioUpdateBlockSize(fn_idx, blk_sz, deflt);
+ }
+ static zx_status_t SdioGetBlockSize(void* ctx, uint8_t fn_idx, uint16_t* out_cur_blk_size) {
+ return static_cast<D*>(ctx)->SdioGetBlockSize(fn_idx, out_cur_blk_size);
+ }
+ static zx_status_t SdioDoRwTxn(void* ctx, uint8_t fn_idx, sdio_rw_txn_t* txn) {
+ return static_cast<D*>(ctx)->SdioDoRwTxn(fn_idx, txn);
+ }
+};
+
+class SdioProtocolProxy {
+public:
+ SdioProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ SdioProtocolProxy(const sdio_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(sdio_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t GetDevHwInfo(sdio_hw_info_t* out_hw_info) {
+ return ops_->get_dev_hw_info(ctx_, out_hw_info);
+ }
+ zx_status_t EnableFn(uint8_t fn_idx) { return ops_->enable_fn(ctx_, fn_idx); }
+ zx_status_t DisableFn(uint8_t fn_idx) { return ops_->disable_fn(ctx_, fn_idx); }
+ zx_status_t EnableFnIntr(uint8_t fn_idx) { return ops_->enable_fn_intr(ctx_, fn_idx); }
+ zx_status_t DisableFnIntr(uint8_t fn_idx) { return ops_->disable_fn_intr(ctx_, fn_idx); }
+ zx_status_t UpdateBlockSize(uint8_t fn_idx, uint16_t blk_sz, bool deflt) {
+ return ops_->update_block_size(ctx_, fn_idx, blk_sz, deflt);
+ }
+ zx_status_t GetBlockSize(uint8_t fn_idx, uint16_t* out_cur_blk_size) {
+ return ops_->get_block_size(ctx_, fn_idx, out_cur_blk_size);
+ }
+ zx_status_t DoRwTxn(uint8_t fn_idx, sdio_rw_txn_t* txn) {
+ return ops_->do_rw_txn(ctx_, fn_idx, txn);
+ }
+
+private:
+ sdio_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/sdmmc-internal.h b/system/ulib/ddktl/include/ddktl/protocol/sdmmc-internal.h
new file mode 100644
index 0000000..1f73322
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/sdmmc-internal.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/sdmmc.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_host_info, SdmmcHostInfo,
+ zx_status_t (C::*)(sdmmc_host_info_t* out_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_set_signal_voltage, SdmmcSetSignalVoltage,
+ zx_status_t (C::*)(sdmmc_voltage_t voltage));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_set_bus_width, SdmmcSetBusWidth,
+ zx_status_t (C::*)(sdmmc_bus_width_t bus_width));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_set_bus_freq, SdmmcSetBusFreq,
+ zx_status_t (C::*)(uint32_t bus_freq));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_set_timing, SdmmcSetTiming,
+ zx_status_t (C::*)(sdmmc_timing_t timing));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_hw_reset, SdmmcHwReset, void (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_perform_tuning, SdmmcPerformTuning,
+ zx_status_t (C::*)(uint32_t cmd_idx));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_sdmmc_protocol_request, SdmmcRequest,
+ zx_status_t (C::*)(sdmmc_req_t* req));
+
+template <typename D>
+constexpr void CheckSdmmcProtocolSubclass() {
+ static_assert(internal::has_sdmmc_protocol_host_info<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcHostInfo(sdmmc_host_info_t* out_info");
+ static_assert(internal::has_sdmmc_protocol_set_signal_voltage<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcSetSignalVoltage(sdmmc_voltage_t voltage");
+ static_assert(internal::has_sdmmc_protocol_set_bus_width<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcSetBusWidth(sdmmc_bus_width_t bus_width");
+ static_assert(internal::has_sdmmc_protocol_set_bus_freq<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcSetBusFreq(uint32_t bus_freq");
+ static_assert(internal::has_sdmmc_protocol_set_timing<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcSetTiming(sdmmc_timing_t timing");
+ static_assert(internal::has_sdmmc_protocol_hw_reset<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "void SdmmcHwReset(");
+ static_assert(internal::has_sdmmc_protocol_perform_tuning<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcPerformTuning(uint32_t cmd_idx");
+ static_assert(internal::has_sdmmc_protocol_request<D>::value,
+ "SdmmcProtocol subclasses must implement "
+ "zx_status_t SdmmcRequest(sdmmc_req_t* req");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/sdmmc.h b/system/ulib/ddktl/include/ddktl/protocol/sdmmc.h
new file mode 100644
index 0000000..7188087
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/sdmmc.h
@@ -0,0 +1,155 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/block.h>
+#include <ddk/protocol/sdmmc.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/listnode.h>
+#include <zircon/types.h>
+
+#include "sdmmc-internal.h"
+
+// DDK sdmmc-protocol support
+//
+// :: Proxies ::
+//
+// ddk::SdmmcProtocolProxy is a simple wrapper around
+// sdmmc_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::SdmmcProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the sdmmc protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_SDMMC device.
+// class SdmmcDevice {
+// using SdmmcDeviceType = ddk::Device<SdmmcDevice, /* ddk mixins */>;
+//
+// class SdmmcDevice : public SdmmcDeviceType,
+// public ddk::SdmmcProtocol<SdmmcDevice> {
+// public:
+// SdmmcDevice(zx_device_t* parent)
+// : SdmmcDeviceType("my-sdmmc-protocol-device", parent) {}
+//
+// zx_status_t SdmmcHostInfo(sdmmc_host_info_t* out_info);
+//
+// zx_status_t SdmmcSetSignalVoltage(sdmmc_voltage_t voltage);
+//
+// zx_status_t SdmmcSetBusWidth(sdmmc_bus_width_t bus_width);
+//
+// zx_status_t SdmmcSetBusFreq(uint32_t bus_freq);
+//
+// zx_status_t SdmmcSetTiming(sdmmc_timing_t timing);
+//
+// void SdmmcHwReset();
+//
+// zx_status_t SdmmcPerformTuning(uint32_t cmd_idx);
+//
+// zx_status_t SdmmcRequest(sdmmc_req_t* req);
+//
+// ...
+// };
+
+namespace ddk {
+
+template <typename D>
+class SdmmcProtocol : public internal::base_mixin {
+public:
+ SdmmcProtocol() {
+ internal::CheckSdmmcProtocolSubclass<D>();
+ sdmmc_protocol_ops_.host_info = SdmmcHostInfo;
+ sdmmc_protocol_ops_.set_signal_voltage = SdmmcSetSignalVoltage;
+ sdmmc_protocol_ops_.set_bus_width = SdmmcSetBusWidth;
+ sdmmc_protocol_ops_.set_bus_freq = SdmmcSetBusFreq;
+ sdmmc_protocol_ops_.set_timing = SdmmcSetTiming;
+ sdmmc_protocol_ops_.hw_reset = SdmmcHwReset;
+ sdmmc_protocol_ops_.perform_tuning = SdmmcPerformTuning;
+ sdmmc_protocol_ops_.request = SdmmcRequest;
+ }
+
+protected:
+ sdmmc_protocol_ops_t sdmmc_protocol_ops_ = {};
+
+private:
+ // Get host info.
+ static zx_status_t SdmmcHostInfo(void* ctx, sdmmc_host_info_t* out_info) {
+ return static_cast<D*>(ctx)->SdmmcHostInfo(out_info);
+ }
+ // Set signal voltage.
+ static zx_status_t SdmmcSetSignalVoltage(void* ctx, sdmmc_voltage_t voltage) {
+ return static_cast<D*>(ctx)->SdmmcSetSignalVoltage(voltage);
+ }
+ // Set bus width.
+ static zx_status_t SdmmcSetBusWidth(void* ctx, sdmmc_bus_width_t bus_width) {
+ return static_cast<D*>(ctx)->SdmmcSetBusWidth(bus_width);
+ }
+ // Set bus frequency.
+ static zx_status_t SdmmcSetBusFreq(void* ctx, uint32_t bus_freq) {
+ return static_cast<D*>(ctx)->SdmmcSetBusFreq(bus_freq);
+ }
+ // Set mmc timing.
+ static zx_status_t SdmmcSetTiming(void* ctx, sdmmc_timing_t timing) {
+ return static_cast<D*>(ctx)->SdmmcSetTiming(timing);
+ }
+ // Issue a hw reset.
+ static void SdmmcHwReset(void* ctx) { static_cast<D*>(ctx)->SdmmcHwReset(); }
+ // Perform tuning.
+ static zx_status_t SdmmcPerformTuning(void* ctx, uint32_t cmd_idx) {
+ return static_cast<D*>(ctx)->SdmmcPerformTuning(cmd_idx);
+ }
+ // Issue a request.
+ static zx_status_t SdmmcRequest(void* ctx, sdmmc_req_t* req) {
+ return static_cast<D*>(ctx)->SdmmcRequest(req);
+ }
+};
+
+class SdmmcProtocolProxy {
+public:
+ SdmmcProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ SdmmcProtocolProxy(const sdmmc_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(sdmmc_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Get host info.
+ zx_status_t HostInfo(sdmmc_host_info_t* out_info) { return ops_->host_info(ctx_, out_info); }
+ // Set signal voltage.
+ zx_status_t SetSignalVoltage(sdmmc_voltage_t voltage) {
+ return ops_->set_signal_voltage(ctx_, voltage);
+ }
+ // Set bus width.
+ zx_status_t SetBusWidth(sdmmc_bus_width_t bus_width) {
+ return ops_->set_bus_width(ctx_, bus_width);
+ }
+ // Set bus frequency.
+ zx_status_t SetBusFreq(uint32_t bus_freq) { return ops_->set_bus_freq(ctx_, bus_freq); }
+ // Set mmc timing.
+ zx_status_t SetTiming(sdmmc_timing_t timing) { return ops_->set_timing(ctx_, timing); }
+ // Issue a hw reset.
+ void HwReset() { ops_->hw_reset(ctx_); }
+ // Perform tuning.
+ zx_status_t PerformTuning(uint32_t cmd_idx) { return ops_->perform_tuning(ctx_, cmd_idx); }
+ // Issue a request.
+ zx_status_t Request(sdmmc_req_t* req) { return ops_->request(ctx_, req); }
+
+private:
+ sdmmc_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/serial-impl-internal.h b/system/ulib/ddktl/include/ddktl/protocol/serial-impl-internal.h
index a02c8a3..7e81fe9 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/serial-impl-internal.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/serial-impl-internal.h
@@ -2,52 +2,54 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/protocol/serial.h>
+#include <ddk/protocol/serial-impl.h>
#include <fbl/type_support.h>
namespace ddk {
namespace internal {
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(serial_has_get_info, GetInfo,
- zx_status_t (C::*)(serial_port_info_t*));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(serial_has_config, Config,
- zx_status_t (C::*)(uint32_t, uint32_t));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(serial_has_enable, Enable,
- zx_status_t (C::*)(bool));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(serial_has_read, Read,
- zx_status_t (C::*)(void*, size_t, size_t*));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(serial_has_write, Write,
- zx_status_t (C::*)(const void*, size_t, size_t*));
-
-DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(serial_has_set_notify_callback, SetNotifyCallback,
- zx_status_t (C::*)(serial_notify_cb, void*));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_impl_protocol_get_info, SerialImplGetInfo,
+ zx_status_t (C::*)(serial_port_info_t* out_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_impl_protocol_config, SerialImplConfig,
+ zx_status_t (C::*)(uint32_t baud_rate, uint32_t flags));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_impl_protocol_enable, SerialImplEnable,
+ zx_status_t (C::*)(bool enable));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_impl_protocol_read, SerialImplRead,
+ zx_status_t (C::*)(void* out_buf_buffer, size_t buf_size,
+ size_t* out_buf_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_impl_protocol_write, SerialImplWrite,
+ zx_status_t (C::*)(const void* buf_buffer, size_t buf_size,
+ size_t* out_actual));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_impl_protocol_set_notify_callback,
+ SerialImplSetNotifyCallback,
+ zx_status_t (C::*)(const serial_notify_t* cb));
template <typename D>
constexpr void CheckSerialImplProtocolSubclass() {
- static_assert(internal::serial_has_get_info<D>::value,
+ static_assert(internal::has_serial_impl_protocol_get_info<D>::value,
"SerialImplProtocol subclasses must implement "
- "zx_status_t GetInfo(serial_port_info_t* info)");
- static_assert(internal::serial_has_config<D>::value,
+ "zx_status_t SerialImplGetInfo(serial_port_info_t* out_info");
+ static_assert(internal::has_serial_impl_protocol_config<D>::value,
"SerialImplProtocol subclasses must implement "
- "zx_status_t Config(uint32_t baud_rate, uint32_t flags)");
- static_assert(internal::serial_has_enable<D>::value,
+ "zx_status_t SerialImplConfig(uint32_t baud_rate, uint32_t flags");
+ static_assert(internal::has_serial_impl_protocol_enable<D>::value,
"SerialImplProtocol subclasses must implement "
- "zx_status_t Enable(bool enable)");
- static_assert(internal::serial_has_read<D>::value,
+ "zx_status_t SerialImplEnable(bool enable");
+ static_assert(
+ internal::has_serial_impl_protocol_read<D>::value,
+ "SerialImplProtocol subclasses must implement "
+ "zx_status_t SerialImplRead(void* out_buf_buffer, size_t buf_size, size_t* out_buf_actual");
+ static_assert(
+ internal::has_serial_impl_protocol_write<D>::value,
+ "SerialImplProtocol subclasses must implement "
+ "zx_status_t SerialImplWrite(const void* buf_buffer, size_t buf_size, size_t* out_actual");
+ static_assert(internal::has_serial_impl_protocol_set_notify_callback<D>::value,
"SerialImplProtocol subclasses must implement "
- "zx_status_t Read(void* buf, size_t length, size_t* out_actual)");
- static_assert(internal::serial_has_write<D>::value,
- "SerialImplProtocol subclasses must implement "
- "zx_status_t Write(const void* buf, size_t length, size_t* out_actual)");
- static_assert(internal::serial_has_set_notify_callback<D>::value,
- "SerialImplProtocol subclasses must implement "
- "zx_status_t SetNotifyCallback(serial_notify_cb cb, void* cookie)");
+ "zx_status_t SerialImplSetNotifyCallback(const serial_notify_t* cb");
}
} // namespace internal
diff --git a/system/ulib/ddktl/include/ddktl/protocol/serial-impl.h b/system/ulib/ddktl/include/ddktl/protocol/serial-impl.h
index bbfbe7e..6cdafea 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/serial-impl.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/serial-impl.h
@@ -2,43 +2,55 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
-#include <ddk/driver.h>
#include <ddk/protocol/serial-impl.h>
+#include <ddk/protocol/serial.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
#include "serial-impl-internal.h"
-// DDK serial-impl protocol support.
+// DDK serial-impl-protocol support
//
// :: Proxies ::
//
-// ddk::SerialImplProtocolProxy is a simple wrappers around serial_protocol_t. It does
-// not own the pointers passed to it.
+// ddk::SerialImplProtocolProxy is a simple wrapper around
+// serial_impl_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
-// ddk::SerialImplProtocol is a mixin class that simplifies writing DDK drivers that
-// implement the serial protocol.
+// ddk::SerialImplProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the serial-impl protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
-// // A driver that implements a ZX_PROTOCOL_NAND device.
-// class SerialImplDevice;
+// // A driver that implements a ZX_PROTOCOL_SERIAL_IMPL device.
+// class SerialImplDevice {
// using SerialImplDeviceType = ddk::Device<SerialImplDevice, /* ddk mixins */>;
//
-// class SerialImplDevice : public SerialDeviceType,
+// class SerialImplDevice : public SerialImplDeviceType,
// public ddk::SerialImplProtocol<SerialImplDevice> {
// public:
// SerialImplDevice(zx_device_t* parent)
-// : SerialImplDeviceType("my-serial-device", parent) {}
+// : SerialImplDeviceType("my-serial-impl-protocol-device", parent) {}
//
-// void Query(serial_info_t* info_out, size_t* serial_op_size_out);
-// void Queue(serial_op_t* operation);
-// zx_status_t GetFactoryBadBlockList(uint32_t* bad_blocks, uint32_t bad_block_len,
-// uint32_t* num_bad_blocks);
+// zx_status_t SerialImplGetInfo(serial_port_info_t* out_info);
+//
+// zx_status_t SerialImplConfig(uint32_t baud_rate, uint32_t flags);
+//
+// zx_status_t SerialImplEnable(bool enable);
+//
+// zx_status_t SerialImplRead(void* out_buf_buffer, size_t buf_size, size_t* out_buf_actual);
+//
+// zx_status_t SerialImplWrite(const void* buf_buffer, size_t buf_size, size_t* out_actual);
+//
+// zx_status_t SerialImplSetNotifyCallback(const serial_notify_t* cb);
+//
// ...
// };
@@ -49,79 +61,79 @@
public:
SerialImplProtocol() {
internal::CheckSerialImplProtocolSubclass<D>();
- serial_proto_ops_.get_info = GetInfo;
- serial_proto_ops_.config = Config;
- serial_proto_ops_.enable = Enable;
- serial_proto_ops_.read = Read;
- serial_proto_ops_.write = Write;
- serial_proto_ops_.set_notify_callback = SetNotifyCallback;
+ ops_.get_info = SerialImplGetInfo;
+ ops_.config = SerialImplConfig;
+ ops_.enable = SerialImplEnable;
+ ops_.read = SerialImplRead;
+ ops_.write = SerialImplWrite;
+ ops_.set_notify_callback = SerialImplSetNotifyCallback;
// Can only inherit from one base_protocol implementation.
- ZX_ASSERT(ddk_proto_id_ == 0);
+ ZX_ASSERT(ddk_proto_id_ = 0);
ddk_proto_id_ = ZX_PROTOCOL_SERIAL_IMPL;
- ddk_proto_ops_ = &serial_proto_ops_;
+ ddk_proto_ops_ = &ops_;
}
protected:
- serial_impl_ops_t serial_proto_ops_ = {};
+ serial_impl_protocol_ops_t ops_ = {};
private:
- static zx_status_t GetInfo(void* ctx, serial_port_info_t* info) {
- return static_cast<D*>(ctx)->GetInfo(info);
+ static zx_status_t SerialImplGetInfo(void* ctx, serial_port_info_t* out_info) {
+ return static_cast<D*>(ctx)->SerialImplGetInfo(out_info);
}
-
- static zx_status_t Config(void* ctx, uint32_t baud_rate, uint32_t flags) {
- return static_cast<D*>(ctx)->Config(baud_rate, flags);
+ // Configures the given serial port.
+ static zx_status_t SerialImplConfig(void* ctx, uint32_t baud_rate, uint32_t flags) {
+ return static_cast<D*>(ctx)->SerialImplConfig(baud_rate, flags);
}
-
- static zx_status_t Enable(void* ctx, bool enable) {
- return static_cast<D*>(ctx)->Enable(enable);
+ static zx_status_t SerialImplEnable(void* ctx, bool enable) {
+ return static_cast<D*>(ctx)->SerialImplEnable(enable);
}
-
- static zx_status_t Read(void* ctx, void* buf, size_t length, size_t* out_actual) {
- return static_cast<D*>(ctx)->Read(buf, length, out_actual);
+ static zx_status_t SerialImplRead(void* ctx, void* out_buf_buffer, size_t buf_size,
+ size_t* out_buf_actual) {
+ return static_cast<D*>(ctx)->SerialImplRead(out_buf_buffer, buf_size, out_buf_actual);
}
-
- static zx_status_t Write(void* ctx, const void* buf, size_t length, size_t* out_actual) {
- return static_cast<D*>(ctx)->Write(buf, length, out_actual);
+ static zx_status_t SerialImplWrite(void* ctx, const void* buf_buffer, size_t buf_size,
+ size_t* out_actual) {
+ return static_cast<D*>(ctx)->SerialImplWrite(buf_buffer, buf_size, out_actual);
}
-
- static zx_status_t SetNotifyCallback(void* ctx, serial_notify_cb cb, void* cookie) {
- return static_cast<D*>(ctx)->SetNotifyCallback(cb, cookie);
+ static zx_status_t SerialImplSetNotifyCallback(void* ctx, const serial_notify_t* cb) {
+ return static_cast<D*>(ctx)->SerialImplSetNotifyCallback(cb);
}
};
class SerialImplProtocolProxy {
public:
- SerialImplProtocolProxy(serial_impl_protocol_t* proto)
+ SerialImplProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ SerialImplProtocolProxy(const serial_impl_protocol_t* proto)
: ops_(proto->ops), ctx_(proto->ctx) {}
- zx_status_t GetInfo(serial_port_info_t* info) {
- return ops_->get_info(ctx_, info);
+ void GetProto(serial_impl_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
}
-
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t GetInfo(serial_port_info_t* out_info) { return ops_->get_info(ctx_, out_info); }
+ // Configures the given serial port.
zx_status_t Config(uint32_t baud_rate, uint32_t flags) {
return ops_->config(ctx_, baud_rate, flags);
}
-
- zx_status_t Enable(bool enable) {
- return ops_->enable(ctx_, enable);
+ zx_status_t Enable(bool enable) { return ops_->enable(ctx_, enable); }
+ zx_status_t Read(void* out_buf_buffer, size_t buf_size, size_t* out_buf_actual) {
+ return ops_->read(ctx_, out_buf_buffer, buf_size, out_buf_actual);
}
-
- zx_status_t Read(void* buf, size_t length, size_t* out_actual) {
- return ops_->read(ctx_, buf, length, out_actual);
+ zx_status_t Write(const void* buf_buffer, size_t buf_size, size_t* out_actual) {
+ return ops_->write(ctx_, buf_buffer, buf_size, out_actual);
}
-
- zx_status_t Write(const void* buf, size_t length, size_t* out_actual) {
- return ops_->write(ctx_, buf, length, out_actual);
- }
-
- zx_status_t SetNotifyCallback(serial_notify_cb cb, void* cookie) {
- return ops_->set_notify_callback(ctx_, cb, cookie);
+ zx_status_t SetNotifyCallback(const serial_notify_t* cb) {
+ return ops_->set_notify_callback(ctx_, cb);
}
private:
- serial_impl_ops_t* ops_;
+ serial_impl_protocol_ops_t* ops_;
void* ctx_;
};
diff --git a/system/ulib/ddktl/include/ddktl/protocol/serial-internal.h b/system/ulib/ddktl/include/ddktl/protocol/serial-internal.h
new file mode 100644
index 0000000..5582a83
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/serial-internal.h
@@ -0,0 +1,36 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/serial.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_protocol_get_info, SerialGetInfo,
+ zx_status_t (C::*)(serial_port_info_t* out_info));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_protocol_config, SerialConfig,
+ zx_status_t (C::*)(uint32_t baud_rate, uint32_t flags));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_serial_protocol_open_socket, SerialOpenSocket,
+ zx_status_t (C::*)(zx_handle_t* out_handle));
+
+template <typename D>
+constexpr void CheckSerialProtocolSubclass() {
+ static_assert(internal::has_serial_protocol_get_info<D>::value,
+ "SerialProtocol subclasses must implement "
+ "zx_status_t SerialGetInfo(serial_port_info_t* out_info");
+ static_assert(internal::has_serial_protocol_config<D>::value,
+ "SerialProtocol subclasses must implement "
+ "zx_status_t SerialConfig(uint32_t baud_rate, uint32_t flags");
+ static_assert(internal::has_serial_protocol_open_socket<D>::value,
+ "SerialProtocol subclasses must implement "
+ "zx_status_t SerialOpenSocket(zx_handle_t* out_handle");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/serial.h b/system/ulib/ddktl/include/ddktl/protocol/serial.h
new file mode 100644
index 0000000..a07f210
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/serial.h
@@ -0,0 +1,117 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/serial.h>
+#include <ddktl/device-internal.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include "serial-internal.h"
+
+// DDK serial-protocol support
+//
+// :: Proxies ::
+//
+// ddk::SerialProtocolProxy is a simple wrapper around
+// serial_protocol_t. It does not own the pointers passed to it
+//
+// :: Mixins ::
+//
+// ddk::SerialProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the serial protocol. It doesn't set the base protocol.
+//
+// :: Examples ::
+//
+// // A driver that implements a ZX_PROTOCOL_SERIAL device.
+// class SerialDevice {
+// using SerialDeviceType = ddk::Device<SerialDevice, /* ddk mixins */>;
+//
+// class SerialDevice : public SerialDeviceType,
+// public ddk::SerialProtocol<SerialDevice> {
+// public:
+// SerialDevice(zx_device_t* parent)
+// : SerialDeviceType("my-serial-protocol-device", parent) {}
+//
+// zx_status_t SerialGetInfo(serial_port_info_t* out_info);
+//
+// zx_status_t SerialConfig(uint32_t baud_rate, uint32_t flags);
+//
+// zx_status_t SerialOpenSocket(zx_handle_t* out_handle);
+//
+// ...
+// };
+
+namespace ddk {
+
+// High level serial protocol for use by client drivers.
+// When used with the platform device protocol, "port" will be relative to
+// the list of serial ports assigned to your device rather than the global
+// list of serial ports.
+template <typename D>
+class SerialProtocol : public internal::base_protocol {
+public:
+ SerialProtocol() {
+ internal::CheckSerialProtocolSubclass<D>();
+ ops_.get_info = SerialGetInfo;
+ ops_.config = SerialConfig;
+ ops_.open_socket = SerialOpenSocket;
+
+ // Can only inherit from one base_protocol implementation.
+ ZX_ASSERT(ddk_proto_id_ = 0);
+ ddk_proto_id_ = ZX_PROTOCOL_SERIAL;
+ ddk_proto_ops_ = &ops_;
+ }
+
+protected:
+ serial_protocol_ops_t ops_ = {};
+
+private:
+ static zx_status_t SerialGetInfo(void* ctx, serial_port_info_t* out_info) {
+ return static_cast<D*>(ctx)->SerialGetInfo(out_info);
+ }
+ // Configures the given serial port.
+ static zx_status_t SerialConfig(void* ctx, uint32_t baud_rate, uint32_t flags) {
+ return static_cast<D*>(ctx)->SerialConfig(baud_rate, flags);
+ }
+ // Returns a socket that can be used for reading and writing data
+ // from the given serial port.
+ static zx_status_t SerialOpenSocket(void* ctx, zx_handle_t* out_handle) {
+ return static_cast<D*>(ctx)->SerialOpenSocket(out_handle);
+ }
+};
+
+class SerialProtocolProxy {
+public:
+ SerialProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ SerialProtocolProxy(const serial_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(serial_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ zx_status_t GetInfo(serial_port_info_t* out_info) { return ops_->get_info(ctx_, out_info); }
+ // Configures the given serial port.
+ zx_status_t Config(uint32_t baud_rate, uint32_t flags) {
+ return ops_->config(ctx_, baud_rate, flags);
+ }
+ // Returns a socket that can be used for reading and writing data
+ // from the given serial port.
+ zx_status_t OpenSocket(zx_handle_t* out_handle) { return ops_->open_socket(ctx_, out_handle); }
+
+private:
+ serial_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/test-internal.h b/system/ulib/ddktl/include/ddktl/protocol/test-internal.h
new file mode 100644
index 0000000..8821ea1
--- /dev/null
+++ b/system/ulib/ddktl/include/ddktl/protocol/test-internal.h
@@ -0,0 +1,57 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// WARNING: This file is machine generated by fidlc.
+
+#pragma once
+
+#include <ddk/protocol/test.h>
+#include <fbl/type_support.h>
+
+namespace ddk {
+namespace internal {
+
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_set_output_socket, TestSetOutputSocket,
+ void (C::*)(zx_handle_t handle));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_get_output_socket, TestGetOutputSocket,
+ zx_handle_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_set_control_channel, TestSetControlChannel,
+ void (C::*)(zx_handle_t handle));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_get_control_channel, TestGetControlChannel,
+ zx_handle_t (C::*)());
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_set_test_func, TestSetTestFunc,
+ void (C::*)(const test_func_t* func));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_run_tests, TestRunTests,
+ zx_status_t (C::*)(const void* arg_buffer, size_t arg_size,
+ test_report_t* out_report));
+DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_test_protocol_destroy, TestDestroy, void (C::*)());
+
+template <typename D>
+constexpr void CheckTestProtocolSubclass() {
+ static_assert(internal::has_test_protocol_set_output_socket<D>::value,
+ "TestProtocol subclasses must implement "
+ "void TestSetOutputSocket(zx_handle_t handle");
+ static_assert(internal::has_test_protocol_get_output_socket<D>::value,
+ "TestProtocol subclasses must implement "
+ "zx_handle_t TestGetOutputSocket(");
+ static_assert(internal::has_test_protocol_set_control_channel<D>::value,
+ "TestProtocol subclasses must implement "
+ "void TestSetControlChannel(zx_handle_t handle");
+ static_assert(internal::has_test_protocol_get_control_channel<D>::value,
+ "TestProtocol subclasses must implement "
+ "zx_handle_t TestGetControlChannel(");
+ static_assert(internal::has_test_protocol_set_test_func<D>::value,
+ "TestProtocol subclasses must implement "
+ "void TestSetTestFunc(const test_func_t* func");
+ static_assert(internal::has_test_protocol_run_tests<D>::value,
+ "TestProtocol subclasses must implement "
+ "zx_status_t TestRunTests(const void* arg_buffer, size_t arg_size, "
+ "test_report_t* out_report");
+ static_assert(internal::has_test_protocol_destroy<D>::value,
+ "TestProtocol subclasses must implement "
+ "void TestDestroy(");
+}
+
+} // namespace internal
+} // namespace ddk
diff --git a/system/ulib/ddktl/include/ddktl/protocol/test.h b/system/ulib/ddktl/include/ddktl/protocol/test.h
index 3d1601c..416522d 100644
--- a/system/ulib/ddktl/include/ddktl/protocol/test.h
+++ b/system/ulib/ddktl/include/ddktl/protocol/test.h
@@ -1,106 +1,143 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// WARNING: This file is machine generated by fidlc.
+
#pragma once
#include <ddk/protocol/test.h>
+#include <ddktl/device-internal.h>
#include <zircon/assert.h>
-#include <lib/zx/channel.h>
-#include <lib/zx/socket.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
-// DDK test protocol support
+#include "test-internal.h"
+
+// DDK test-protocol support
//
-// :: Proxy ::
+// :: Proxies ::
//
-// ddk::TestProtocolProxy is a simple wrapper around test_protocol_t. It does not own the pointers
-// passed to it.
+// ddk::TestProtocolProxy is a simple wrapper around
+// test_protocol_t. It does not own the pointers passed to it
//
-// :: Mixin ::
+// :: Mixins ::
//
-// No mixins are defined, as it is not expected that there will be multiple implementations of the
-// test protocol.
+// ddk::TestProtocol is a mixin class that simplifies writing DDK drivers
+// that implement the test protocol. It doesn't set the base protocol.
//
-// :: Example ::
+// :: Examples ::
//
-// // A driver that communicates with a ZX_PROTOCOL_TEST device
-// class MyDevice;
-// using MyDeviceType = ddk::Device<MyDevice, /* ddk mixins */>;
+// // A driver that implements a ZX_PROTOCOL_TEST device.
+// class TestDevice {
+// using TestDeviceType = ddk::Device<TestDevice, /* ddk mixins */>;
//
-// static zx_status_t my_test_func(void* cookie, test_report_t* report, const void* arg,
-// size_t arglen) {
-// auto dev = static_cast<MyDevice*>(cookie);
-// // run tests and set up report
-// return ZX_OK;
-// }
-//
-// class MyDevice : public MyDeviceType {
+// class TestDevice : public TestDeviceType,
+// public ddk::TestProtocol<TestDevice> {
// public:
-// MyDevice(zx_device_t* parent)
-// : MyDeviceType("my-device"),
-// parent_(parent) {}
+// TestDevice(zx_device_t* parent)
+// : TestDeviceType("my-test-protocol-device", parent) {}
//
-// void DdkRelease() {
-// // Clean up
-// }
+// void TestSetOutputSocket(zx_handle_t handle);
//
-// zx_status_t Bind() {
-// test_protocol_t* ops;
-// auto status = get_device_protocol(parent_, ZX_PROTOCOL_TEST,
-// reinterpret_cast<void**>(&ops));
-// if (status != ZX_OK) {
-// return status;
-// }
-// proxy_.reset(new ddk::TestProtocolProxy(ops, parent_));
+// zx_handle_t TestGetOutputSocket();
//
-// // Set up the test
-// proxy_->SetTestFunc(my_test_func, this);
-// return Add(parent_);
-// }
+// void TestSetControlChannel(zx_handle_t handle);
//
-// private:
-// fbl::unique_ptr<ddk::TestProtocolProxy> proxy_;
+// zx_handle_t TestGetControlChannel();
+//
+// void TestSetTestFunc(const test_func_t* func);
+//
+// zx_status_t TestRunTests(const void* arg_buffer, size_t arg_size, test_report_t* out_report);
+//
+// void TestDestroy();
+//
+// ...
// };
namespace ddk {
-class TestProtocolProxy {
- public:
- TestProtocolProxy(test_protocol_t* proto)
- : ops_(proto->ops), ctx_(proto->ctx) {}
-
- void SetOutputSocket(zx::socket socket) {
- ops_->set_output_socket(ctx_, socket.release());
+template <typename D>
+class TestProtocol : public internal::base_mixin {
+public:
+ TestProtocol() {
+ internal::CheckTestProtocolSubclass<D>();
+ test_protocol_ops_.set_output_socket = TestSetOutputSocket;
+ test_protocol_ops_.get_output_socket = TestGetOutputSocket;
+ test_protocol_ops_.set_control_channel = TestSetControlChannel;
+ test_protocol_ops_.get_control_channel = TestGetControlChannel;
+ test_protocol_ops_.set_test_func = TestSetTestFunc;
+ test_protocol_ops_.run_tests = TestRunTests;
+ test_protocol_ops_.destroy = TestDestroy;
}
- zx::socket GetOutputSocket() {
- return zx::socket(ops_->get_output_socket(ctx_));
+protected:
+ test_protocol_ops_t test_protocol_ops_ = {};
+
+private:
+ // Sets test output socket.
+ static void TestSetOutputSocket(void* ctx, zx_handle_t handle) {
+ static_cast<D*>(ctx)->TestSetOutputSocket(handle);
}
-
- void SetControlChannel(zx::channel chan) {
- ops_->set_control_channel(ctx_, chan.release());
+ // Gets test output socket.
+ static zx_handle_t TestGetOutputSocket(void* ctx) {
+ return static_cast<D*>(ctx)->TestGetOutputSocket();
}
-
- zx::channel GetControlChannel() {
- return zx::channel(ops_->get_control_channel(ctx_));
+ // Sets control channel.
+ static void TestSetControlChannel(void* ctx, zx_handle_t handle) {
+ static_cast<D*>(ctx)->TestSetControlChannel(handle);
}
-
- void SetTestFunc(test_func_t func, void* cookie) {
- ops_->set_test_func(ctx_, func, cookie);
+ // Gets control channel.
+ static zx_handle_t TestGetControlChannel(void* ctx) {
+ return static_cast<D*>(ctx)->TestGetControlChannel();
}
-
- zx_status_t RunTests(test_report_t* report, const void* arg, size_t arglen) {
- return ops_->run_tests(ctx_, report, arg, arglen);
+ // Sets test function.
+ static void TestSetTestFunc(void* ctx, const test_func_t* func) {
+ static_cast<D*>(ctx)->TestSetTestFunc(func);
}
-
- void Destroy() {
- ops_->destroy(ctx_);
+ // Run tests, calls the function set in |SetTestFunc|.
+ static zx_status_t TestRunTests(void* ctx, const void* arg_buffer, size_t arg_size,
+ test_report_t* out_report) {
+ return static_cast<D*>(ctx)->TestRunTests(arg_buffer, arg_size, out_report);
}
-
- private:
- test_protocol_ops_t* ops_;
- void* ctx_;
-
+ // Calls `device_remove()`.
+ static void TestDestroy(void* ctx) { static_cast<D*>(ctx)->TestDestroy(); }
};
-} // namespace ddk
+class TestProtocolProxy {
+public:
+ TestProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
+ TestProtocolProxy(const test_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
+
+ void GetProto(test_protocol_t* proto) {
+ proto->ctx = ctx_;
+ proto->ops = ops_;
+ }
+ bool is_valid() { return ops_ != nullptr; }
+ void clear() {
+ ctx_ = nullptr;
+ ops_ = nullptr;
+ }
+ // Sets test output socket.
+ void SetOutputSocket(zx_handle_t handle) { ops_->set_output_socket(ctx_, handle); }
+ // Gets test output socket.
+ zx_handle_t GetOutputSocket() { return ops_->get_output_socket(ctx_); }
+ // Sets control channel.
+ void SetControlChannel(zx_handle_t handle) { ops_->set_control_channel(ctx_, handle); }
+ // Gets control channel.
+ zx_handle_t GetControlChannel() { return ops_->get_control_channel(ctx_); }
+ // Sets test function.
+ void SetTestFunc(const test_func_t* func) { ops_->set_test_func(ctx_, func); }
+ // Run tests, calls the function set in |SetTestFunc|.
+ zx_status_t RunTests(const void* arg_buffer, size_t arg_size, test_report_t* out_report) {
+ return ops_->run_tests(ctx_, arg_buffer, arg_size, out_report);
+ }
+ // Calls `device_remove()`.
+ void Destroy() { ops_->destroy(ctx_); }
+
+private:
+ test_protocol_ops_t* ops_;
+ void* ctx_;
+};
+
+} // namespace ddk
diff --git a/system/ulib/ddktl/test/ddktl-test.cpp b/system/ulib/ddktl/test/ddktl-test.cpp
index 65e812b..f2de174 100644
--- a/system/ulib/ddktl/test/ddktl-test.cpp
+++ b/system/ulib/ddktl/test/ddktl-test.cpp
@@ -38,7 +38,7 @@
}
}
-zx_status_t ddktl_test_func(void* cookie, test_report_t* report, const void* arg, size_t arglen) {
+zx_status_t ddktl_test_func(void* cookie, const void* arg, size_t arglen, test_report_t* report) {
auto dev = static_cast<zx_device_t*>(cookie);
test_protocol_t proto;
@@ -69,7 +69,8 @@
return status;
}
- proto.ops->set_test_func(proto.ctx, ddktl_test_func, parent);
+ const test_func_t test = {ddktl_test_func, parent};
+ proto.ops->set_test_func(proto.ctx, &test);
return ZX_OK;
}
diff --git a/system/ulib/ddktl/test/ethernet-tests.cpp b/system/ulib/ddktl/test/ethernet-tests.cpp
index 3482313..9e9b47a 100644
--- a/system/ulib/ddktl/test/ethernet-tests.cpp
+++ b/system/ulib/ddktl/test/ethernet-tests.cpp
@@ -26,17 +26,17 @@
void DdkRelease() {}
- void EthmacStatus(uint32_t status) {
+ void EthmacIfcStatus(uint32_t status) {
status_this_ = get_this();
status_called_ = true;
}
- void EthmacRecv(void* data, size_t length, uint32_t flags) {
+ void EthmacIfcRecv(const void* data, size_t length, uint32_t flags) {
recv_this_ = get_this();
recv_called_ = true;
}
- void EthmacCompleteTx(ethmac_netbuf_t* netbuf, zx_status_t status) {
+ void EthmacIfcCompleteTx(ethmac_netbuf_t* netbuf, zx_status_t status) {
complete_tx_this_ = get_this();
complete_tx_called_ = true;
}
@@ -52,8 +52,11 @@
END_HELPER;
}
+ ethmac_ifc_t ethmac_ifc() { return {ðmac_ifc_ops_, this}; }
+
zx_status_t StartProtocol(ddk::EthmacProtocolProxy* proxy) {
- return proxy->Start(this);
+ const ethmac_ifc_t ifc = ethmac_ifc();
+ return proxy->Start(&ifc);
}
private:
@@ -77,7 +80,7 @@
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out) {
if (proto_id != ZX_PROTOCOL_ETHERNET_IMPL) return ZX_ERR_INVALID_ARGS;
ddk::AnyProtocol* proto = static_cast<ddk::AnyProtocol*>(out);
- proto->ops = ddk_proto_ops_;
+ proto->ops = ðmac_protocol_ops_;
proto->ctx = this;
return ZX_OK;
}
@@ -95,9 +98,9 @@
stop_called_ = true;
}
- zx_status_t EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy) {
+ zx_status_t EthmacStart(const ethmac_ifc_t* ifc) {
start_this_ = get_this();
- proxy_.swap(proxy);
+ proxy_ = fbl::make_unique<ddk::EthmacIfcProxy>(ifc);
start_called_ = true;
return ZX_OK;
}
@@ -108,7 +111,7 @@
return ZX_OK;
}
- zx_status_t EthmacSetParam(uint32_t param, int32_t value, void* data) {
+ zx_status_t EthmacSetParam(uint32_t param, int32_t value, const void* data, size_t data_size) {
set_param_this_ = get_this();
set_param_called_ = true;
return ZX_OK;
@@ -162,9 +165,9 @@
TestEthmacIfc dev;
auto ifc = dev.ethmac_ifc();
- ifc->status(&dev, 0);
- ifc->recv(&dev, nullptr, 0, 0);
- ifc->complete_tx(&dev, nullptr, ZX_OK);
+ ethmac_ifc_status(&ifc, 0);
+ ethmac_ifc_recv(&ifc, nullptr, 0, 0);
+ ethmac_ifc_complete_tx(&ifc, nullptr, ZX_OK);
EXPECT_TRUE(dev.VerifyCalls(), "");
@@ -175,7 +178,8 @@
BEGIN_TEST;
TestEthmacIfc dev;
- ddk::EthmacIfcProxy proxy(dev.ethmac_ifc(), &dev);
+ const ethmac_ifc_t ifc = dev.ethmac_ifc();
+ ddk::EthmacIfcProxy proxy(&ifc);
proxy.Status(0);
proxy.Recv(nullptr, 0, 0);
@@ -200,12 +204,13 @@
status = dev.DdkGetProtocol(ZX_PROTOCOL_ETHERNET_IMPL, reinterpret_cast<void*>(&proto));
EXPECT_EQ(ZX_OK, status, "");
- EXPECT_EQ(ZX_OK, proto.ops->query(proto.ctx, 0, nullptr), "");
+ EXPECT_EQ(ZX_OK, ethmac_query(&proto, 0, nullptr), "");
proto.ops->stop(proto.ctx);
- EXPECT_EQ(ZX_OK, proto.ops->start(proto.ctx, nullptr, nullptr), "");
+ ethmac_ifc_t ifc = {nullptr, nullptr};
+ EXPECT_EQ(ZX_OK, ethmac_start(&proto, &ifc), "");
ethmac_netbuf_t netbuf = {};
- EXPECT_EQ(ZX_OK, proto.ops->queue_tx(proto.ctx, 0, &netbuf), "");
- EXPECT_EQ(ZX_OK, proto.ops->set_param(proto.ctx, 0, 0, nullptr), "");
+ EXPECT_EQ(ZX_OK, ethmac_queue_tx(&proto, 0, &netbuf), "");
+ EXPECT_EQ(ZX_OK, ethmac_set_param(&proto, 0, 0, nullptr, 0), "");
EXPECT_TRUE(dev.VerifyCalls(), "");
@@ -227,13 +232,14 @@
ddk::EthmacProtocolProxy proxy(&proto);
// The EthmacIfc to hand to the parent device.
TestEthmacIfc ifc_dev;
+ ethmac_ifc_t ifc = ifc_dev.ethmac_ifc();
EXPECT_EQ(ZX_OK, proxy.Query(0, nullptr), "");
proxy.Stop();
- EXPECT_EQ(ZX_OK, proxy.Start(&ifc_dev), "");
+ EXPECT_EQ(ZX_OK, proxy.Start(&ifc), "");
ethmac_netbuf_t netbuf = {};
EXPECT_EQ(ZX_OK, proxy.QueueTx(0, &netbuf), "");
- EXPECT_EQ(ZX_OK, proxy.SetParam(0, 0, nullptr));
+ EXPECT_EQ(ZX_OK, proxy.SetParam(0, 0, nullptr, 0));
EXPECT_TRUE(protocol_dev.VerifyCalls(), "");