00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00036 #include <errno.h>
00037 #include <assert.h>
00038 #include <devman.h>
00039 #include <device/hw_res.h>
00040
00041 #include <usb/debug.h>
00042 #include <pci_dev_iface.h>
00043
00044 #include "pci.h"
00045
00054 int pci_get_my_registers(const ddf_dev_t *dev,
00055 uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
00056 {
00057 assert(dev);
00058 assert(io_reg_address);
00059 assert(io_reg_size);
00060 assert(irq_no);
00061
00062 int parent_phone =
00063 devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);
00064 if (parent_phone < 0) {
00065 return parent_phone;
00066 }
00067
00068 hw_resource_list_t hw_resources;
00069 int rc = hw_res_get_resource_list(parent_phone, &hw_resources);
00070 if (rc != EOK) {
00071 async_hangup(parent_phone);
00072 return rc;
00073 }
00074
00075 uintptr_t io_address = 0;
00076 size_t io_size = 0;
00077 bool io_found = false;
00078
00079 int irq = 0;
00080 bool irq_found = false;
00081
00082 size_t i;
00083 for (i = 0; i < hw_resources.count; i++) {
00084 const hw_resource_t *res = &hw_resources.resources[i];
00085 switch (res->type)
00086 {
00087 case INTERRUPT:
00088 irq = res->res.interrupt.irq;
00089 irq_found = true;
00090 usb_log_debug2("Found interrupt: %d.\n", irq);
00091 break;
00092
00093 case IO_RANGE:
00094 io_address = res->res.io_range.address;
00095 io_size = res->res.io_range.size;
00096 usb_log_debug2("Found io: %" PRIx64" %zu.\n",
00097 res->res.io_range.address, res->res.io_range.size);
00098 io_found = true;
00099 break;
00100
00101 default:
00102 break;
00103 }
00104 }
00105 async_hangup(parent_phone);
00106
00107 if (!io_found || !irq_found)
00108 return ENOENT;
00109
00110 *io_reg_address = io_address;
00111 *io_reg_size = io_size;
00112 *irq_no = irq;
00113
00114 return EOK;
00115 }
00116
00122 int pci_enable_interrupts(const ddf_dev_t *device)
00123 {
00124 const int parent_phone =
00125 devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
00126 if (parent_phone < 0) {
00127 return parent_phone;
00128 }
00129 const bool enabled = hw_res_enable_interrupt(parent_phone);
00130 async_hangup(parent_phone);
00131 return enabled ? EOK : EIO;
00132 }
00133
00139 int pci_disable_legacy(const ddf_dev_t *device)
00140 {
00141 assert(device);
00142 const int parent_phone =
00143 devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
00144 if (parent_phone < 0) {
00145 return parent_phone;
00146 }
00147
00148
00149
00150 const sysarg_t address = 0xc0;
00151 const sysarg_t value = 0xaf00;
00152
00153 const int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
00154 IPC_M_CONFIG_SPACE_WRITE_16, address, value);
00155 async_hangup(parent_phone);
00156
00157 return rc;
00158 }
00159