pci.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Vojtech Horky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         /* See UHCI design guide for these values p.45,
00149          * write all WC bits in USB legacy register */
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 /*----------------------------------------------------------------------------*/

Generated on Thu Jun 2 07:45:43 2011 for HelenOS/USB by  doxygen 1.4.7