[pci] Refactor pci-lib

Move ConfigReadX and ConfigWriteX to protocol methods to make
testing and migration from kpci to upci easier.

ZX-3146 #comment

Change-Id: Iff77a7e32ff60d6b66d659995a33422b25d22b38
diff --git a/zircon/system/banjo/ddk.protocol.pci/pci.banjo b/zircon/system/banjo/ddk.protocol.pci/pci.banjo
index 6635662..9ace3d8 100644
--- a/zircon/system/banjo/ddk.protocol.pci/pci.banjo
+++ b/zircon/system/banjo/ddk.protocol.pci/pci.banjo
@@ -48,17 +48,14 @@
     QueryIrqMode(zircon.syscalls.pci.ZxPciIrqMode mode) -> (zx.status s, uint32 max_irqs);
     SetIrqMode(zircon.syscalls.pci.ZxPciIrqMode mode, uint32 requested_irq_count) -> (zx.status s);
     GetDeviceInfo() -> (zx.status s, zircon.syscalls.pci.ZxPcieDeviceInfo into);
-    ConfigRead(uint16 offset, usize width) -> (zx.status s, uint32 value);
-    ConfigWrite(uint16 offset, usize width, uint32 value) -> (zx.status s);
+    ConfigRead8(uint16 offset) -> (zx.status s, uint8 value);
+    ConfigRead16(uint16 offset) -> (zx.status s, uint16 value);
+    ConfigRead32(uint16 offset) -> (zx.status s, uint32 value);
+    ConfigWrite8(uint16 offset, uint8 value) -> (zx.status s);
+    ConfigWrite16(uint16 offset, uint16 value) -> (zx.status s);
+    ConfigWrite32(uint16 offset, uint32 value) -> (zx.status s);
     GetNextCapability(uint8 id, uint8 offset) -> (zx.status s, uint8 offset);
     GetFirstCapability(uint8 id) -> (zx.status s, uint8 offset);
     GetAuxdata(string args) -> (zx.status s, vector<voidptr> data);
     GetBti(uint32 index) -> (zx.status s, handle<bti> bti);
 };
-
-// TODO: Implement the following.
-//static inline zx_status_t pci_get_auxdata(const pci_protocol_t* pci,
-//                                          const char* args, voidptr* data,
-//                                          uint32_t bytes, uint32_t* actual) {
-//    return pci->ops->get_auxdata(pci->ctx, args, data, bytes, actual);
-//}
diff --git a/zircon/system/dev/bus/pci/device.h b/zircon/system/dev/bus/pci/device.h
index b57f03e..7af4b21 100644
--- a/zircon/system/dev/bus/pci/device.h
+++ b/zircon/system/dev/bus/pci/device.h
@@ -100,8 +100,12 @@
     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);
+    zx_status_t PciConfigRead8(uint16_t offset, uint8_t* out_value);
+    zx_status_t PciConfigRead16(uint16_t offset, uint16_t* out_value);
+    zx_status_t PciConfigRead32(uint16_t offset, uint32_t* out_value);
+    zx_status_t PciConfigWrite8(uint16_t offset, uint8_t value);
+    zx_status_t PciConfigWrite16(uint16_t offset, uint16_t value);
+    zx_status_t PciConfigWrite32(uint16_t offset, uint32_t value);
     zx_status_t PciGetNextCapability(uint8_t type, uint8_t offset, uint8_t* out_offset);
     zx_status_t PciGetFirstCapability(uint8_t type, uint8_t* out_offset);
     zx_status_t PciGetAuxdata(const char* args,
diff --git a/zircon/system/dev/bus/pci/kpci/proxy.c b/zircon/system/dev/bus/pci/kpci/proxy.c
index 38aeefc..a254bf0 100644
--- a/zircon/system/dev/bus/pci/kpci/proxy.c
+++ b/zircon/system/dev/bus/pci/kpci/proxy.c
@@ -109,6 +109,24 @@
     return st;
 }
 
+static zx_status_t pci_op_config_read8(void* ctx, uint16_t offset, uint8_t* val) {
+    uint32_t tmp;
+    zx_status_t st = pci_op_config_read(ctx, offset, sizeof(*val), &tmp);
+    *val = tmp & UINT8_MAX;
+    return st;
+}
+
+static zx_status_t pci_op_config_read16(void* ctx, uint16_t offset, uint16_t* val) {
+    uint32_t tmp;
+    zx_status_t st = pci_op_config_read(ctx, offset, sizeof(*val), &tmp);
+    *val = tmp & UINT16_MAX;
+    return st;
+}
+
+static zx_status_t pci_op_config_read32(void* ctx, uint16_t offset, uint32_t* val) {
+    return pci_op_config_read(ctx, offset, sizeof(uint32_t), val);
+}
+
 // These reads are proxied directly over to the device's PciConfig object so the validity of the
 // widths and offsets will be validated on that end and then trickle back to this level of the
 // protocol.
@@ -129,6 +147,18 @@
     return pci_rpc_request(dev, PCI_OP_CONFIG_WRITE, NULL, &req, &resp);
 }
 
+static zx_status_t pci_op_config_write8(void* ctx, uint16_t offset, uint8_t val) {
+    return pci_op_config_write(ctx, offset, sizeof(uint8_t), val);
+}
+
+static zx_status_t pci_op_config_write16(void* ctx, uint16_t offset, uint16_t val) {
+    return pci_op_config_write(ctx, offset, sizeof(uint16_t), val);
+}
+
+static zx_status_t pci_op_config_write32(void* ctx, uint16_t offset, uint32_t val) {
+    return pci_op_config_write(ctx, offset, sizeof(uint32_t), val);
+}
+
 static zx_status_t pci_op_get_next_capability(void* ctx, uint8_t type, uint8_t in_offset,
                                               uint8_t* out_offset) {
     uint32_t cap_offset = 0;
@@ -318,8 +348,12 @@
     .query_irq_mode = pci_op_query_irq_mode,
     .set_irq_mode = pci_op_set_irq_mode,
     .get_device_info = pci_op_get_device_info,
-    .config_read = pci_op_config_read,
-    .config_write = pci_op_config_write,
+    .config_read8 = pci_op_config_read8,
+    .config_read16 = pci_op_config_read16,
+    .config_read32 = pci_op_config_read32,
+    .config_write8 = pci_op_config_write8,
+    .config_write16 = pci_op_config_write16,
+    .config_write32 = pci_op_config_write32,
     .get_next_capability = pci_op_get_next_capability,
     .get_first_capability = pci_op_get_first_capability,
     .get_auxdata = pci_op_get_auxdata,
diff --git a/zircon/system/dev/bus/pci/protocol.cpp b/zircon/system/dev/bus/pci/protocol.cpp
index 9d0f8f3..15936ca 100644
--- a/zircon/system/dev/bus/pci/protocol.cpp
+++ b/zircon/system/dev/bus/pci/protocol.cpp
@@ -31,19 +31,36 @@
     return ZX_ERR_NOT_SUPPORTED;
 }
 
-zx_status_t Device::PciConfigRead(uint16_t offset, size_t width, uint32_t* out_value) {
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t Device::PciConfigWrite(uint16_t offset, size_t width, uint32_t value) {
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
 zx_status_t Device::PciGetFirstCapability(uint8_t type, uint8_t* out_offset) {
     return ZX_ERR_NOT_SUPPORTED;
 }
 
-zx_status_t Device::PciGetNextCapability(uint8_t type, uint8_t offset, uint8_t* out_offset) {
+zx_status_t Device::PciConfigRead8(uint16_t offset, uint8_t* out_value) {
+	return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Device::PciConfigRead16(uint16_t offset, uint16_t* out_value) {
+	return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Device::PciConfigRead32(uint16_t offset, uint32_t* out_value) {
+	return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Device::PciConfigWrite8(uint16_t offset, uint8_t value) {
+	return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Device::PciConfigWrite16(uint16_t offset, uint16_t value) {
+	return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Device::PciConfigWrite32(uint16_t offset, uint32_t value) {
+	return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Device::Device::PciGetNextCapability(uint8_t type, uint8_t offset,
+                                                 uint8_t* out_offset) {
     return ZX_ERR_NOT_SUPPORTED;
 }
 
diff --git a/zircon/system/ulib/ddk/include/ddk/protocol/pci-lib.h b/zircon/system/ulib/ddk/include/ddk/protocol/pci-lib.h
index c9cf4fb..1aac9aa 100644
--- a/zircon/system/ulib/ddk/include/ddk/protocol/pci-lib.h
+++ b/zircon/system/ulib/ddk/include/ddk/protocol/pci-lib.h
@@ -5,63 +5,34 @@
 #ifndef DDK_PROTOCOL_PCI_LIB_H_
 #define DDK_PROTOCOL_PCI_LIB_H_
 
-#include <ddk/protocol/pci.h>
 #include <ddk/mmio-buffer.h>
+#include <ddk/protocol/pci.h>
+#include <stdio.h>
+#include <zircon/syscalls.h>
 
 __BEGIN_CDECLS
 
 static inline zx_status_t pci_map_bar_buffer(const pci_protocol_t* pci, uint32_t bar_id,
-                                      uint32_t cache_policy, mmio_buffer_t* buffer) {
-
+                                             uint32_t cache_policy, mmio_buffer_t* buffer) {
     zx_pci_bar_t bar;
-
-    zx_status_t status = pci->ops->get_bar(pci->ctx, bar_id, &bar);
-    if (status != ZX_OK) {
-        return status;
+    zx_status_t st = pci->ops->get_bar(pci->ctx, bar_id, &bar);
+    if (st != ZX_OK) {
+        return st;
     }
     // TODO(cja): PIO may be mappable on non-x86 architectures
     if (bar.type == ZX_PCI_BAR_TYPE_PIO || bar.handle == ZX_HANDLE_INVALID) {
         return ZX_ERR_WRONG_TYPE;
     }
-    return mmio_buffer_init(buffer, 0, bar.size, bar.handle, cache_policy);
-}
 
-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;
-}
+    size_t vmo_size;
+    st = zx_vmo_get_size(bar.handle, &vmo_size);
+    if (st != ZX_OK) {
+        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);
+    return  mmio_buffer_init(buffer, 0, vmo_size, bar.handle, cache_policy);
 }
 
 __END_CDECLS
 
-#endif  // DDK_PROTOCOL_PCI_LIB_H_
+#endif // DDK_PROTOCOL_PCI_LIB_H_