···11-#include <linux/init.h>22-#include <linux/module.h>33-#include <linux/fs.h>44-#include <linux/cdev.h>55-#include <linux/kdev_t.h>66-#include <linux/semaphore.h>77-#include <linux/mm.h>88-#include <linux/poll.h>99-#include <linux/wait.h>1010-#include <linux/ioctl.h>1111-#include <linux/ioport.h>1212-#include <linux/io.h>1313-#include <linux/interrupt.h>1414-#include <linux/pagemap.h>1515-#include <linux/pci.h>1616-#include <linux/firmware.h>1717-#include <linux/sched.h>11+/*22+ * rar_register.c - An Intel Restricted Access Region register driver33+ *44+ * Copyright(c) 2009 Intel Corporation. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or77+ * modify it under the terms of the GNU General Public License as88+ * published by the Free Software Foundation; either version 2 of the99+ * License, or (at your option) any later version.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1414+ * General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA1919+ * 02111-1307, USA.2020+ *2121+ * -------------------------------------------------------------------2222+ * 20091204 Mark Allyn <mark.a.allyn@intel.com>2323+ * Ossama Othman <ossama.othman@intel.com>2424+ * Cleanup per feedback from Alan Cox and Arjan Van De Ven2525+ *2626+ * 20090806 Ossama Othman <ossama.othman@intel.com>2727+ * Return zero high address if upper 22 bits is zero.2828+ * Cleaned up checkpatch errors.2929+ * Clarified that driver is dealing with bus addresses.3030+ *3131+ * 20090702 Ossama Othman <ossama.othman@intel.com>3232+ * Removed unnecessary include directives3333+ * Cleaned up spinlocks.3434+ * Cleaned up logging.3535+ * Improved invalid parameter checks.3636+ * Fixed and simplified RAR address retrieval and RAR locking3737+ * code.3838+ *3939+ * 20090626 Mark Allyn <mark.a.allyn@intel.com>4040+ * Initial publish4141+ */4242+4343+#define DEBUG 14444+1845#include "rar_register.h"19462020-/* The following defines are for the IPC process to retrieve RAR in */4747+#include <linux/module.h>4848+#include <linux/pci.h>4949+#include <linux/spinlock.h>5050+#include <linux/device.h>5151+#include <linux/kernel.h>21522253/* === Lincroft Message Bus Interface === */2354/* Message Control Register */2455#define LNC_MCR_OFFSET 0xD025565757+/* Maximum number of clients (other drivers using this driver) */5858+#define MAX_RAR_CLIENTS 105959+2660/* Message Data Register */2761#define LNC_MDR_OFFSET 0xD428622963/* Message Opcodes */3030-#define LNC_MESSAGE_READ_OPCODE 0xD06464+#define LNC_MESSAGE_READ_OPCODE 0xD03165#define LNC_MESSAGE_WRITE_OPCODE 0xE032663367/* Message Write Byte Enables */···7137#define LNC_BUNIT_PORT 0x372387339/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */7474-#define LNC_BRAR0L 0x107575-#define LNC_BRAR0H 0x117676-#define LNC_BRAR1L 0x127777-#define LNC_BRAR1H 0x134040+#define LNC_BRAR0L 0x104141+#define LNC_BRAR0H 0x114242+#define LNC_BRAR1L 0x124343+#define LNC_BRAR1H 0x1378447945/* Reserved for SeP */8080-#define LNC_BRAR2L 0x148181-#define LNC_BRAR2H 0x158282-8383-8484-/* This structure is only used during module initialization. */8585-struct RAR_offsets {8686- int low; /* Register offset for low RAR physical address. */8787- int high; /* Register offset for high RAR physical address. */8888-};8989-9090-struct pci_dev *rar_dev;9191-static uint32_t registered;4646+#define LNC_BRAR2L 0x144747+#define LNC_BRAR2H 0x1592489349/* Moorestown supports three restricted access regions. */9450#define MRST_NUM_RAR 395519696-struct RAR_address_struct rar_addr[MRST_NUM_RAR];97529898-/* prototype for init */9999-static int __init rar_init_handler(void);100100-static void __exit rar_exit_handler(void);101101-102102-/*103103- function that is activated on the successfull probe of the RAR device104104-*/105105-static int __devinit rar_probe(struct pci_dev *pdev,106106- const struct pci_device_id *ent);107107-108108-static const struct pci_device_id rar_pci_id_tbl[] = {109109- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },110110- { 0 }5353+/* RAR Bus Address Range */5454+struct RAR_address_range {5555+ dma_addr_t low;5656+ dma_addr_t high;11157};11258113113-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);114114-115115-/* field for registering driver to PCI device */116116-static struct pci_driver rar_pci_driver = {117117- .name = "rar_driver",118118- .id_table = rar_pci_id_tbl,119119- .probe = rar_probe5959+/* Structure containing low and high RAR register offsets. */6060+struct RAR_offsets {6161+ u32 low; /* Register offset for low RAR bus address. */6262+ u32 high; /* Register offset for high RAR bus address. */12063};12164122122-/* This function is used to retrieved RAR info using the IPC message123123- bus interface */124124-static int memrar_get_rar_addr(struct pci_dev *pdev,125125- int offset,126126- u32 *addr)127127-{128128- /*129129- * ======== The Lincroft Message Bus Interface ========130130- * Lincroft registers may be obtained from the PCI131131- * (the Host Bridge) using the Lincroft Message Bus132132- * Interface. That message bus interface is generally133133- * comprised of two registers: a control register (MCR, 0xDO)134134- * and a data register (MDR, 0xD4).135135- *136136- * The MCR (message control register) format is the following:137137- * 1. [31:24]: Opcode138138- * 2. [23:16]: Port139139- * 3. [15:8]: Register Offset140140- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits141141- * to 1)142142- * 5. [3:0]: reserved143143- *144144- * Read (0xD0) and write (0xE0) opcodes are written to the145145- * control register when reading and writing to Lincroft146146- * registers, respectively.147147- *148148- * We're interested in registers found in the Lincroft149149- * B-unit. The B-unit port is 0x3.150150- *151151- * The six B-unit RAR register offsets we use are listed152152- * earlier in this file.153153- *154154- * Lastly writing to the MCR register requires the "Byte155155- * enables" bits to be set to 1. This may be achieved by156156- * writing 0xF at bit 4.157157- *158158- * The MDR (message data register) format is the following:159159- * 1. [31:0]: Read/Write Data160160- *161161- * Data being read from this register is only available after162162- * writing the appropriate control message to the MCR163163- * register.164164- *165165- * Data being written to this register must be written before166166- * writing the appropriate control message to the MCR167167- * register.168168- */169169-170170- int result = 0; /* result */171171- /* Construct control message */172172- u32 const message =173173- (LNC_MESSAGE_READ_OPCODE << 24)174174- | (LNC_BUNIT_PORT << 16)175175- | (offset << 8)176176- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);177177-178178- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset);179179-180180- if (addr == 0)181181- return -EINVAL;182182-183183- /* Send the control message */184184- result = pci_write_config_dword(pdev,185185- LNC_MCR_OFFSET,186186- message);187187-188188- printk(KERN_WARNING "rar- result from send ctl register is %x\n",189189- result);190190-191191- if (!result)192192- result = pci_read_config_dword(pdev,193193- LNC_MDR_OFFSET,194194- addr);195195-196196- printk(KERN_WARNING "rar- result from read data register is %x\n",197197- result);198198-199199- printk(KERN_WARNING "rar- value read from data register is %x\n",200200- *addr);201201-202202- if (result)203203- return -1;204204- else205205- return 0;206206-}207207-208208-static int memrar_set_rar_addr(struct pci_dev *pdev,209209- int offset,210210- u32 addr)211211-{212212- /*213213- * ======== The Lincroft Message Bus Interface ========214214- * Lincroft registers may be obtained from the PCI215215- * (the Host Bridge) using the Lincroft Message Bus216216- * Interface. That message bus interface is generally217217- * comprised of two registers: a control register (MCR, 0xDO)218218- * and a data register (MDR, 0xD4).219219- *220220- * The MCR (message control register) format is the following:221221- * 1. [31:24]: Opcode222222- * 2. [23:16]: Port223223- * 3. [15:8]: Register Offset224224- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits225225- * to 1)226226- * 5. [3:0]: reserved227227- *228228- * Read (0xD0) and write (0xE0) opcodes are written to the229229- * control register when reading and writing to Lincroft230230- * registers, respectively.231231- *232232- * We're interested in registers found in the Lincroft233233- * B-unit. The B-unit port is 0x3.234234- *235235- * The six B-unit RAR register offsets we use are listed236236- * earlier in this file.237237- *238238- * Lastly writing to the MCR register requires the "Byte239239- * enables" bits to be set to 1. This may be achieved by240240- * writing 0xF at bit 4.241241- *242242- * The MDR (message data register) format is the following:243243- * 1. [31:0]: Read/Write Data244244- *245245- * Data being read from this register is only available after246246- * writing the appropriate control message to the MCR247247- * register.248248- *249249- * Data being written to this register must be written before250250- * writing the appropriate control message to the MCR251251- * register.252252- */253253-254254- int result = 0; /* result */255255-256256- /* Construct control message */257257- u32 const message =258258- (LNC_MESSAGE_WRITE_OPCODE << 24)259259- | (LNC_BUNIT_PORT << 16)260260- | (offset << 8)261261- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);262262-263263- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset);264264-265265- if (addr == 0)266266- return -EINVAL;267267-268268- /* Send the control message */269269- result = pci_write_config_dword(pdev,270270- LNC_MDR_OFFSET,271271- addr);272272-273273- printk(KERN_WARNING "rar- result from send ctl register is %x\n",274274- result);275275-276276- if (!result)277277- result = pci_write_config_dword(pdev,278278- LNC_MCR_OFFSET,279279- message);280280-281281- printk(KERN_WARNING "rar- result from write data register is %x\n",282282- result);283283-284284- printk(KERN_WARNING "rar- value read to data register is %x\n",285285- addr);286286-287287- if (result)288288- return -1;289289- else290290- return 0;291291-}292292-293293-/*294294-295295- * Initialize RAR parameters, such as physical addresses, etc.296296-297297- */298298-static int memrar_init_rar_params(struct pci_dev *pdev)299299-{300300- struct RAR_offsets const offsets[] = {301301- { LNC_BRAR0L, LNC_BRAR0H },302302- { LNC_BRAR1L, LNC_BRAR1H },303303- { LNC_BRAR2L, LNC_BRAR2H }6565+struct client {6666+ int (*client_callback)(void *client_data);6767+ void *customer_data;6868+ int client_called;30469 };30570306306- size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);307307- struct RAR_offsets const *end = offsets + num_offsets;308308- struct RAR_offsets const *i;309309- unsigned int n = 0;310310- int result = 0;7171+static DEFINE_MUTEX(rar_mutex);7272+static DEFINE_MUTEX(lnc_reg_mutex);31173312312- /* Retrieve RAR start and end physical addresses. */7474+struct RAR_device {7575+ struct RAR_offsets const rar_offsets[MRST_NUM_RAR];7676+ struct RAR_address_range rar_addr[MRST_NUM_RAR];7777+ struct pci_dev *rar_dev;7878+ bool registered;7979+ };313808181+/* this platform has only one rar_device for 3 rar regions */8282+static struct RAR_device my_rar_device = {8383+ .rar_offsets = {8484+ [0].low = LNC_BRAR0L,8585+ [0].high = LNC_BRAR0H,8686+ [1].low = LNC_BRAR1L,8787+ [1].high = LNC_BRAR1H,8888+ [2].low = LNC_BRAR2L,8989+ [2].high = LNC_BRAR2H9090+ }9191+};9292+9393+/* this data is for handling requests from other drivers which arrive9494+ * prior to this driver initializing9595+ */9696+9797+static struct client clients[MAX_RAR_CLIENTS];9898+static int num_clients;9999+100100+/*101101+ * This function is used to retrieved RAR info using the Lincroft102102+ * message bus interface.103103+ */104104+static int retrieve_rar_addr(struct pci_dev *pdev,105105+ int offset,106106+ dma_addr_t *addr)107107+{314108 /*315315- * Access the RAR registers through the Lincroft Message Bus316316- * Interface on PCI device: 00:00.0 Host bridge.317317- */109109+ * ======== The Lincroft Message Bus Interface ========110110+ * Lincroft registers may be obtained from the PCI111111+ * (the Host Bridge) using the Lincroft Message Bus112112+ * Interface. That message bus interface is generally113113+ * comprised of two registers: a control register (MCR, 0xDO)114114+ * and a data register (MDR, 0xD4).115115+ *116116+ * The MCR (message control register) format is the following:117117+ * 1. [31:24]: Opcode118118+ * 2. [23:16]: Port119119+ * 3. [15:8]: Register Offset120120+ * 4. [7:4]: Byte Enables (use 0xF to set all of these bits121121+ * to 1)122122+ * 5. [3:0]: reserved123123+ *124124+ * Read (0xD0) and write (0xE0) opcodes are written to the125125+ * control register when reading and writing to Lincroft126126+ * registers, respectively.127127+ *128128+ * We're interested in registers found in the Lincroft129129+ * B-unit. The B-unit port is 0x3.130130+ *131131+ * The six B-unit RAR register offsets we use are listed132132+ * earlier in this file.133133+ *134134+ * Lastly writing to the MCR register requires the "Byte135135+ * enables" bits to be set to 1. This may be achieved by136136+ * writing 0xF at bit 4.137137+ *138138+ * The MDR (message data register) format is the following:139139+ * 1. [31:0]: Read/Write Data140140+ *141141+ * Data being read from this register is only available after142142+ * writing the appropriate control message to the MCR143143+ * register.144144+ *145145+ * Data being written to this register must be written before146146+ * writing the appropriate control message to the MCR147147+ * register.148148+ */318149319319- /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */150150+ int result;320151321321- if (pdev == NULL)322322- return -ENODEV;152152+ /* Construct control message */153153+ u32 const message =154154+ (LNC_MESSAGE_READ_OPCODE << 24)155155+ | (LNC_BUNIT_PORT << 16)156156+ | (offset << 8)157157+ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);323158324324- for (i = offsets; i != end; ++i, ++n) {325325- if (memrar_get_rar_addr(pdev,326326- (*i).low,327327- &(rar_addr[n].low)) != 0328328- || memrar_get_rar_addr(pdev,329329- (*i).high,330330- &(rar_addr[n].high)) != 0) {331331- result = -1;332332- break;333333- }159159+ dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);160160+161161+ if (addr == 0) {162162+ WARN_ON(1);163163+ return -EINVAL;334164 }335165166166+ /*167167+ * We synchronize access to the Lincroft MCR and MDR registers168168+ * until BOTH the command is issued through the MCR register169169+ * and the corresponding data is read from the MDR register.170170+ * Otherwise a race condition would exist between accesses to171171+ * both registers.172172+ */173173+174174+ mutex_lock(&lnc_reg_mutex);175175+176176+ /* Send the control message */177177+ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);178178+179179+ dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result);180180+181181+ if (!result) {182182+ result = pci_read_config_dword(pdev, LNC_MDR_OFFSET,183183+ (u32 *)addr);184184+ dev_dbg(&pdev->dev,185185+ "Result from read data register is %x\n", result);186186+187187+ dev_dbg(&pdev->dev,188188+ "Value read from data register is %lx\n",189189+ (unsigned long)*addr);190190+ }191191+192192+ mutex_unlock(&lnc_reg_mutex);193193+194194+ return result;195195+}196196+197197+static int set_rar_address(struct pci_dev *pdev,198198+ int offset,199199+ dma_addr_t addr)200200+{201201+ /*202202+ * Data being written to this register must be written before203203+ * writing the appropriate control message to the MCR204204+ * register.205205+ * @note See rar_get_address() for a description of the206206+ * message bus interface being used here.207207+ */208208+209209+ int result = 0;210210+211211+ /* Construct control message */212212+ u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24)213213+ | (LNC_BUNIT_PORT << 16)214214+ | (offset << 8)215215+ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);216216+217217+ if (addr == 0) {218218+ WARN_ON(1);219219+ return -EINVAL;220220+ }221221+222222+ dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset);223223+224224+ /*225225+ * We synchronize access to the Lincroft MCR and MDR registers226226+ * until BOTH the command is issued through the MCR register227227+ * and the corresponding data is read from the MDR register.228228+ * Otherwise a race condition would exist between accesses to229229+ * both registers.230230+ */231231+232232+ mutex_lock(&lnc_reg_mutex);233233+234234+ /* Send the control message */235235+ result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr);236236+237237+ dev_dbg(&pdev->dev, "Result from write data register is %x\n", result);238238+239239+ if (!result) {240240+ dev_dbg(&pdev->dev,241241+ "Value written to data register is %lx\n",242242+ (unsigned long)addr);243243+244244+ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);245245+246246+ dev_dbg(&pdev->dev, "Result from send ctl register is %x\n",247247+ result);248248+ }249249+250250+ mutex_unlock(&lnc_reg_mutex);251251+252252+ return result;253253+}254254+255255+/*256256+* Initialize RAR parameters, such as bus addresses, etc.257257+*/258258+static int init_rar_params(struct pci_dev *pdev)259259+{260260+ unsigned int i;261261+ int result = 0;262262+263263+ /* Retrieve RAR start and end bus addresses.264264+ * Access the RAR registers through the Lincroft Message Bus265265+ * Interface on PCI device: 00:00.0 Host bridge.266266+ */267267+268268+ for (i = 0; i < MRST_NUM_RAR; ++i) {269269+ struct RAR_offsets const *offset =270270+ &my_rar_device.rar_offsets[i];271271+ struct RAR_address_range *addr = &my_rar_device.rar_addr[i];272272+273273+ if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0)274274+ || (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) {275275+ result = -1;276276+ break;277277+ }278278+279279+ /*280280+ * Only the upper 22 bits of the RAR addresses are281281+ * stored in their corresponding RAR registers so we282282+ * must set the lower 10 bits accordingly.283283+284284+ * The low address has its lower 10 bits cleared, and285285+ * the high address has all its lower 10 bits set,286286+ * e.g.:287287+ * low = 0x2ffffc00288288+ */289289+290290+ addr->low &= (dma_addr_t)0xfffffc00u;291291+292292+ /*293293+ * Set bits 9:0 on uppser address if bits 31:10 are non294294+ * zero; otherwize clear all bits295295+ */296296+297297+ if ((addr->high & 0xfffffc00u) == 0)298298+ addr->high = 0;299299+ else300300+ addr->high |= 0x3ffu;301301+ }336302 /* Done accessing the device. */337337- /* pci_dev_put(pdev); */338303339304 if (result == 0) {340340- if (1) {341341- size_t z;342342- for (z = 0; z != MRST_NUM_RAR; ++z) {343343- printk(KERN_WARNING344344- "rar - BRAR[%Zd] physical address low\n"345345- "\tlow: 0x%08x\n"346346- "\thigh: 0x%08x\n",347347- z,348348- rar_addr[z].low,349349- rar_addr[z].high);350350- }305305+ int z;306306+ for (z = 0; z != MRST_NUM_RAR; ++z) {307307+ /*308308+ * "BRAR" refers to the RAR registers in the309309+ * Lincroft B-unit.310310+ */311311+ dev_info(&pdev->dev, "BRAR[%u] bus address range = "312312+ "[%lx, %lx]\n", z,313313+ (unsigned long)my_rar_device.rar_addr[z].low,314314+ (unsigned long)my_rar_device.rar_addr[z].high);351315 }352316 }353317···353321}354322355323/*356356- function that is activated on the successfull probe of the RAR device357357-*/358358-static int __devinit rar_probe(struct pci_dev *pdev,359359- const struct pci_device_id *ent)324324+ * The rar_get_address function is used by other device drivers325325+ * to obtain RAR address information on a RAR. It takes three326326+ * parameters:327327+ *328328+ * int rar_index329329+ * The rar_index is an index to the rar for which you wish to retrieve330330+ * the address information.331331+ * Values can be 0,1, or 2.332332+ *333333+ * The function returns a 0 upon success or a -1 if there is no RAR334334+ * facility on this system.335335+ */336336+int rar_get_address(int rar_index,337337+ dma_addr_t *start_address,338338+ dma_addr_t *end_address)360339{361361- /* error */340340+ int result = -ENODEV;341341+342342+ if (my_rar_device.registered) {343343+ if (start_address == 0 || end_address == 0344344+ || rar_index >= MRST_NUM_RAR || rar_index < 0) {345345+ result = -EINVAL;346346+ } else {347347+ *start_address =348348+ my_rar_device.rar_addr[rar_index].low;349349+ *end_address =350350+ my_rar_device.rar_addr[rar_index].high;351351+352352+ result = 0;353353+ }354354+ }355355+356356+ return result;357357+}358358+EXPORT_SYMBOL(rar_get_address);359359+360360+/*361361+ * The rar_lock function is ued by other device drivers to lock an RAR.362362+ * once an RAR is locked, it stays locked until the next system reboot.363363+ * The function takes one parameter:364364+ *365365+ * int rar_index366366+ * The rar_index is an index to the rar that you want to lock.367367+ * Values can be 0,1, or 2.368368+ *369369+ * The function returns a 0 upon success or a -1 if there is no RAR370370+ * facility on this system.371371+ */372372+int rar_lock(int rar_index)373373+{374374+ int result = -ENODEV;375375+376376+ if (rar_index >= MRST_NUM_RAR || rar_index < 0) {377377+ result = -EINVAL;378378+ return result;379379+ }380380+381381+ dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n");382382+ mutex_lock(&rar_mutex);383383+384384+ if (my_rar_device.registered) {385385+386386+ dma_addr_t low = my_rar_device.rar_addr[rar_index].low &387387+ 0xfffffc00u;388388+389389+ dma_addr_t high = my_rar_device.rar_addr[rar_index].high &390390+ 0xfffffc00u;391391+392392+ /*393393+ * Only allow I/O from the graphics and Langwell;394394+ * Not from the x96 processor395395+ */396396+ if (rar_index == (int)RAR_TYPE_VIDEO) {397397+ low |= 0x00000009;398398+ high |= 0x00000015;399399+ }400400+401401+ else if (rar_index == (int)RAR_TYPE_AUDIO) {402402+ /* Only allow I/O from Langwell; nothing from x86 */403403+ low |= 0x00000008;404404+ high |= 0x00000018;405405+ }406406+407407+ else408408+ /* Read-only from all agents */409409+ high |= 0x00000018;410410+411411+ /*412412+ * Now program the register using the Lincroft message413413+ * bus interface.414414+ */415415+ result = set_rar_address(my_rar_device.rar_dev,416416+ my_rar_device.rar_offsets[rar_index].low,417417+ low);418418+419419+ if (result == 0)420420+ result = set_rar_address(421421+ my_rar_device.rar_dev,422422+ my_rar_device.rar_offsets[rar_index].high,423423+ high);424424+ }425425+426426+ dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n");427427+ mutex_unlock(&rar_mutex);428428+ return result;429429+}430430+EXPORT_SYMBOL(rar_lock);431431+432432+/* The register_rar function is to used by other device drivers433433+ * to ensure that this driver is ready. As we cannot be sure of434434+ * the compile/execute order of dirvers in ther kernel, it is435435+ * best to give this driver a callback function to call when436436+ * it is ready to give out addresses. The callback function437437+ * would have those steps that continue the initialization of438438+ * a driver that do require a valid RAR address. One of those439439+ * steps would be to call rar_get_address()440440+ * This function return 0 on success an -1 on failure.441441+*/442442+int register_rar(int (*callback)(void *yourparameter), void *yourparameter)443443+{444444+445445+ int result = -ENODEV;446446+447447+ if (callback == NULL)448448+ return -EINVAL;449449+450450+ mutex_lock(&rar_mutex);451451+452452+ if (my_rar_device.registered) {453453+454454+ mutex_unlock(&rar_mutex);455455+ /*456456+ * if the driver already registered, then we can simply457457+ * call the callback right now458458+ */459459+460460+ return (*callback)(yourparameter);461461+ }462462+463463+ if (num_clients < MRST_NUM_RAR) {464464+465465+ clients[num_clients].client_callback = callback;466466+ clients[num_clients].customer_data = yourparameter;467467+ num_clients += 1;468468+ result = 0;469469+ }470470+471471+ mutex_unlock(&rar_mutex);472472+ return result;473473+474474+}475475+EXPORT_SYMBOL(register_rar);476476+477477+/*478478+ * This function registers the driver with the device subsystem (479479+ * either PCI, USB, etc).480480+ * Function that is activaed on the succesful probe of the RAR device481481+ * (Moorestown host controller).482482+ */483483+static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)484484+{362485 int error;486486+ int counter;363487364364- /*------------------------365365- CODE366366- ---------------------------*/367367-368368- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,369369- "Rar pci probe starting\n");370370- error = 0;488488+ dev_dbg(&dev->dev, "PCI probe starting\n");371489372490 /* enable the device */373373- error = pci_enable_device(pdev);491491+ error = pci_enable_device(dev);374492 if (error) {375375- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,376376- "error enabling pci device\n");493493+ dev_err(&dev->dev,494494+ "Error enabling RAR register PCI device\n");377495 goto end_function;378496 }379497380380- rar_dev = pdev;381381- registered = 1;498498+ /* we have only one device; fill in the rar_device structure */499499+ my_rar_device.rar_dev = dev;382500383383- /* Initialize the RAR parameters, which have to be retrieved */384384- /* via the message bus service */385385- error = memrar_init_rar_params(rar_dev);386386-501501+ /*502502+ * Initialize the RAR parameters, which have to be retrieved503503+ * via the message bus interface.504504+ */505505+ error = init_rar_params(dev);387506 if (error) {388388- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,389389- "error getting RAR addresses device\n");390390- registered = 0;507507+ pci_disable_device(dev);508508+509509+ dev_err(&dev->dev,510510+ "Error retrieving RAR addresses\n");511511+391512 goto end_function;513513+ }514514+515515+ dev_dbg(&dev->dev, "PCI probe locking\n");516516+ mutex_lock(&rar_mutex);517517+ my_rar_device.registered = 1;518518+519519+ /* now call anyone who has registered (using callbacks) */520520+ for (counter = 0; counter < num_clients; counter += 1) {521521+ if (clients[counter].client_callback) {522522+ error = (*clients[counter].client_callback)(523523+ clients[counter].customer_data);524524+ /* set callback to NULL to indicate it has been done */525525+ clients[counter].client_callback = NULL;526526+ dev_dbg(&my_rar_device.rar_dev->dev,527527+ "Callback called for %d\n",528528+ counter);392529 }530530+ }531531+532532+ dev_dbg(&dev->dev, "PCI probe unlocking\n");533533+ mutex_unlock(&rar_mutex);393534394535end_function:395536396537 return error;397538}398539399399-/*400400- this function registers the driver to401401- the device subsystem (either PCI, USB, etc)402402-*/540540+const struct pci_device_id rar_pci_id_tbl[] = {541541+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) },542542+ { 0 }543543+};544544+545545+MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);546546+547547+const struct pci_device_id *my_id_table = rar_pci_id_tbl;548548+549549+/* field for registering driver to PCI device */550550+static struct pci_driver rar_pci_driver = {551551+ .name = "rar_register_driver",552552+ .id_table = rar_pci_id_tbl,553553+ .probe = rar_probe554554+};555555+403556static int __init rar_init_handler(void)404557{405558 return pci_register_driver(&rar_pci_driver);···599382module_exit(rar_exit_handler);600383601384MODULE_LICENSE("GPL");602602-603603-604604-/* The get_rar_address function is used by other device drivers605605- * to obtain RAR address information on a RAR. It takes two606606- * parameter:607607- *608608- * int rar_index609609- * The rar_index is an index to the rar for which you wish to retrieve610610- * the address information.611611- * Values can be 0,1, or 2.612612- *613613- * struct RAR_address_struct is a pointer to a place to which the function614614- * can return the address structure for the RAR.615615- *616616- * The function returns a 0 upon success or a -1 if there is no RAR617617- * facility on this system.618618- */619619-int get_rar_address(int rar_index, struct RAR_address_struct *addresses)620620-{621621- if (registered && (rar_index < 3) && (rar_index >= 0)) {622622- *addresses = rar_addr[rar_index];623623- /* strip off lock bit information */624624- addresses->low = addresses->low & 0xfffffff0;625625- addresses->high = addresses->high & 0xfffffff0;626626- return 0;627627- } else628628- return -ENODEV;629629-}630630-EXPORT_SYMBOL(get_rar_address);631631-632632-/* The lock_rar function is used by other device drivers to lock an RAR.633633- * once an RAR is locked, it stays locked until the next system reboot.634634- * The function takes one parameter:635635- *636636- * int rar_index637637- * The rar_index is an index to the rar that you want to lock.638638- * Values can be 0,1, or 2.639639- *640640- * The function returns a 0 upon success or a -1 if there is no RAR641641- * facility on this system.642642- */643643-int lock_rar(int rar_index)644644-{645645- u32 working_addr;646646- int result;647647-648648- if (registered && (rar_index < 3) && (rar_index >= 0)) {649649- /* first make sure that lock bits are clear (this does lock) */650650- working_addr = rar_addr[rar_index].low & 0xfffffff0;651651-652652- /* now send that value to the register using the IPC */653653- result = memrar_set_rar_addr(rar_dev, rar_index, working_addr);654654- return result;655655- } else656656- return -ENODEV;657657-}385385+MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");