1/* 2 * Copyright 2022, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef _OBSD_COMPAT_DEV_PCI_PCIVAR_H_ 6#define _OBSD_COMPAT_DEV_PCI_PCIVAR_H_ 7 8 9#include_next <dev/pci/pcivar.h> 10#include <dev/pci/pcireg.h> 11 12#include <sys/rman.h> 13 14 15typedef u_int32_t pcireg_t; 16 17 18struct pci_matchid { 19 pci_vendor_id_t pm_vid; 20 pci_product_id_t pm_pid; 21}; 22 23typedef struct { 24 int rid; 25} pci_intr_handle_t; 26 27 28#define pci_conf_read(pct, pcitag, reg) \ 29 pci_read_config(SC_DEV_FOR_PCI, reg, sizeof(pcireg_t)) 30#define pci_conf_write(pct, pcitag, reg, val) \ 31 pci_write_config(SC_DEV_FOR_PCI, reg, val, sizeof(pcireg_t)) 32#define pci_get_capability(pct, pcitag, capability, offset, value) \ 33 pci_get_capability_openbsd(SC_DEV_FOR_PCI, capability, offset, value) 34#define pci_mapreg_type(pct, pcitag, reg) \ 35 pci_mapreg_type_openbsd(SC_DEV_FOR_PCI, reg) 36#define pci_mapreg_map(pa, reg, type, flags, tagp, handlep, basep, sizep, maxsize) \ 37 pci_mapreg_map_openbsd(SC_DEV_FOR_PCI, reg, type, flags, tagp, handlep, basep, sizep, maxsize) 38#define pci_intr_establish(pa, ih, level, func, arg, what) \ 39 pci_intr_establish_openbsd(SC_DEV_FOR_PCI, ih, level, func, arg, what) 40 41#define pci_intr_string(...) NULL 42 43static int 44pci_get_capability_openbsd(device_t dev, int capability, int* offset, pcireg_t* value) 45{ 46 int res = pci_find_cap(dev, capability, offset); 47 if (res != 0) 48 return 0; 49 50 if (value) 51 *value = pci_read_config(dev, *offset, sizeof(pcireg_t)); 52 return 1; 53} 54 55static pcireg_t 56pci_mapreg_type_openbsd(device_t dev, int reg) 57{ 58 return (_PCI_MAPREG_TYPEBITS(pci_read_config(dev, reg, sizeof(pcireg_t)))); 59} 60 61static int 62pci_mapreg_map_openbsd(device_t dev, int reg, pcireg_t type, int flags, 63 bus_space_tag_t* tagp, bus_space_handle_t* handlep, bus_addr_t* basep, 64 bus_size_t* sizep, bus_size_t maxsize) 65{ 66 struct resource* res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, ®, RF_ACTIVE); 67 if (res == NULL) 68 return -1; 69 70 *tagp = rman_get_bustag(res); 71 *handlep = rman_get_bushandle(res); 72 if (basep != NULL) 73 *basep = rman_get_start(res); 74 if (sizep != NULL) 75 *sizep = rman_get_size(res); 76 return 0; 77} 78 79static int 80pci_intr_map_msix(device_t dev, int vec, pci_intr_handle_t* ihp) 81{ 82 if (vec != 0) 83 return -1; 84 85 int count = 1; 86 ihp->rid = 1; 87 return pci_alloc_msix(dev, &count); 88} 89 90static int 91pci_intr_map_msi(device_t dev, pci_intr_handle_t* ihp) 92{ 93 int count = 1; 94 ihp->rid = 1; 95 return pci_alloc_msi(dev, &count); 96} 97 98static int 99pci_intr_map(device_t dev, pci_intr_handle_t* ihp) 100{ 101 // No need to map legacy interrupts. 102 ihp->rid = 0; 103 return 0; 104} 105 106static void* 107pci_intr_establish_openbsd(device_t dev, pci_intr_handle_t ih, int level, 108 int(*func)(void*), void* arg, const char* what) 109{ 110 struct resource* irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &ih.rid, 111 RF_ACTIVE | (ih.rid != 0 ? 0 : RF_SHAREABLE)); 112 if (irq == NULL) 113 return NULL; 114 115 int flags = INTR_TYPE_NET; 116 if ((level & IPL_MPSAFE) != 0) 117 flags |= INTR_MPSAFE; 118 119 void* ihp = NULL; 120 bus_setup_intr(dev, irq, flags, NULL, func, arg, &ihp); 121 return ihp; 122} 123 124 125#endif /* _OBSD_COMPAT_DEV_PCI_PCIVAR_H_ */ 126