On Tue, Nov 06, 2007 at 02:33:53AM -0800, akpm@linux-foundation.org wrote:
[mmotm.git] / drivers / staging / rar / rar_driver.c
blob9805d74bd3411a168d97f02931251f662576f93d
1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/fs.h>
4 #include <linux/cdev.h>
5 #include <linux/kdev_t.h>
6 #include <linux/semaphore.h>
7 #include <linux/mm.h>
8 #include <linux/poll.h>
9 #include <linux/wait.h>
10 #include <linux/ioctl.h>
11 #include <linux/ioport.h>
12 #include <linux/io.h>
13 #include <linux/interrupt.h>
14 #include <linux/pagemap.h>
15 #include <linux/pci.h>
16 #include <linux/firmware.h>
17 #include <linux/sched.h>
18 #include "rar_driver.h"
20 /* The following defines are for the IPC process to retrieve RAR in */
22 /* === Lincroft Message Bus Interface === */
23 /* Message Control Register */
24 #define LNC_MCR_OFFSET 0xD0
26 /* Message Data Register */
27 #define LNC_MDR_OFFSET 0xD4
29 /* Message Opcodes */
30 #define LNC_MESSAGE_READ_OPCODE 0xD0
31 #define LNC_MESSAGE_WRITE_OPCODE 0xE0
33 /* Message Write Byte Enables */
34 #define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
36 /* B-unit Port */
37 #define LNC_BUNIT_PORT 0x3
39 /* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
40 #define LNC_BRAR0L 0x10
41 #define LNC_BRAR0H 0x11
42 #define LNC_BRAR1L 0x12
43 #define LNC_BRAR1H 0x13
45 /* Reserved for SeP */
46 #define LNC_BRAR2L 0x14
47 #define LNC_BRAR2H 0x15
50 /* This structure is only used during module initialization. */
51 struct RAR_offsets {
52 int low; /* Register offset for low RAR physical address. */
53 int high; /* Register offset for high RAR physical address. */
56 struct pci_dev *rar_dev;
57 static uint32_t registered;
59 /* Moorestown supports three restricted access regions. */
60 #define MRST_NUM_RAR 3
62 struct RAR_address_struct rar_addr[MRST_NUM_RAR];
64 /* prototype for init */
65 static int __init rar_init_handler(void);
66 static void __exit rar_exit_handler(void);
69 function that is activated on the succesfull probe of the RAR device
71 static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
73 static struct pci_device_id rar_pci_id_tbl[] = {
74 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },
75 { 0 }
78 MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
80 /* field for registering driver to PCI device */
81 static struct pci_driver rar_pci_driver = {
82 .name = "rar_driver",
83 .id_table = rar_pci_id_tbl,
84 .probe = rar_probe
87 /* This function is used to retrieved RAR info using the IPC message
88 bus interface */
89 static int memrar_get_rar_addr(struct pci_dev* pdev,
90 int offset,
91 u32 *addr)
94 * ======== The Lincroft Message Bus Interface ========
95 * Lincroft registers may be obtained from the PCI
96 * (the Host Bridge) using the Lincroft Message Bus
97 * Interface. That message bus interface is generally
98 * comprised of two registers: a control register (MCR, 0xDO)
99 * and a data register (MDR, 0xD4).
101 * The MCR (message control register) format is the following:
102 * 1. [31:24]: Opcode
103 * 2. [23:16]: Port
104 * 3. [15:8]: Register Offset
105 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
106 * to 1)
107 * 5. [3:0]: reserved
109 * Read (0xD0) and write (0xE0) opcodes are written to the
110 * control register when reading and writing to Lincroft
111 * registers, respectively.
113 * We're interested in registers found in the Lincroft
114 * B-unit. The B-unit port is 0x3.
116 * The six B-unit RAR register offsets we use are listed
117 * earlier in this file.
119 * Lastly writing to the MCR register requires the "Byte
120 * enables" bits to be set to 1. This may be achieved by
121 * writing 0xF at bit 4.
123 * The MDR (message data register) format is the following:
124 * 1. [31:0]: Read/Write Data
126 * Data being read from this register is only available after
127 * writing the appropriate control message to the MCR
128 * register.
130 * Data being written to this register must be written before
131 * writing the appropriate control message to the MCR
132 * register.
135 int result = 0; /* result */
136 /* Construct control message */
137 u32 const message =
138 (LNC_MESSAGE_READ_OPCODE << 24)
139 | (LNC_BUNIT_PORT << 16)
140 | (offset << 8)
141 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
143 printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
145 if (addr == 0)
146 return -EINVAL;
148 /* Send the control message */
149 result = pci_write_config_dword(pdev,
150 LNC_MCR_OFFSET,
151 message);
153 printk(KERN_WARNING "rar- result from send ctl register is %x\n"
154 ,result);
156 if (!result)
157 result = pci_read_config_dword(pdev,
158 LNC_MDR_OFFSET,
159 addr);
161 printk(KERN_WARNING "rar- result from read data register is %x\n",
162 result);
164 printk(KERN_WARNING "rar- value read from data register is %x\n",
165 *addr);
167 if (result)
168 return -1;
169 else
170 return 0;
173 static int memrar_set_rar_addr(struct pci_dev* pdev,
174 int offset,
175 u32 addr)
178 * ======== The Lincroft Message Bus Interface ========
179 * Lincroft registers may be obtained from the PCI
180 * (the Host Bridge) using the Lincroft Message Bus
181 * Interface. That message bus interface is generally
182 * comprised of two registers: a control register (MCR, 0xDO)
183 * and a data register (MDR, 0xD4).
185 * The MCR (message control register) format is the following:
186 * 1. [31:24]: Opcode
187 * 2. [23:16]: Port
188 * 3. [15:8]: Register Offset
189 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
190 * to 1)
191 * 5. [3:0]: reserved
193 * Read (0xD0) and write (0xE0) opcodes are written to the
194 * control register when reading and writing to Lincroft
195 * registers, respectively.
197 * We're interested in registers found in the Lincroft
198 * B-unit. The B-unit port is 0x3.
200 * The six B-unit RAR register offsets we use are listed
201 * earlier in this file.
203 * Lastly writing to the MCR register requires the "Byte
204 * enables" bits to be set to 1. This may be achieved by
205 * writing 0xF at bit 4.
207 * The MDR (message data register) format is the following:
208 * 1. [31:0]: Read/Write Data
210 * Data being read from this register is only available after
211 * writing the appropriate control message to the MCR
212 * register.
214 * Data being written to this register must be written before
215 * writing the appropriate control message to the MCR
216 * register.
219 int result = 0; /* result */
221 /* Construct control message */
222 u32 const message =
223 (LNC_MESSAGE_WRITE_OPCODE << 24)
224 | (LNC_BUNIT_PORT << 16)
225 | (offset << 8)
226 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
228 printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
230 if (addr == 0)
231 return -EINVAL;
233 /* Send the control message */
234 result = pci_write_config_dword(pdev,
235 LNC_MDR_OFFSET,
236 addr);
238 printk(KERN_WARNING "rar- result from send ctl register is %x\n"
239 ,result);
241 if (!result)
242 result = pci_write_config_dword(pdev,
243 LNC_MCR_OFFSET,
244 message);
246 printk(KERN_WARNING "rar- result from write data register is %x\n",
247 result);
249 printk(KERN_WARNING "rar- value read to data register is %x\n",
250 addr);
252 if (result)
253 return -1;
254 else
255 return 0;
260 * Initialize RAR parameters, such as physical addresses, etc.
263 static int memrar_init_rar_params(struct pci_dev *pdev)
265 struct RAR_offsets const offsets[] = {
266 { LNC_BRAR0L, LNC_BRAR0H },
267 { LNC_BRAR1L, LNC_BRAR1H },
268 { LNC_BRAR2L, LNC_BRAR2H }
271 size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);
272 struct RAR_offsets const *end = offsets + num_offsets;
273 struct RAR_offsets const *i;
274 unsigned int n = 0;
275 int result = 0;
277 /* Retrieve RAR start and end physical addresses. */
280 * Access the RAR registers through the Lincroft Message Bus
281 * Interface on PCI device: 00:00.0 Host bridge.
284 /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
286 if (pdev == NULL)
287 return -ENODEV;
289 for (i = offsets; i != end; ++i, ++n) {
290 if (memrar_get_rar_addr (pdev,
291 (*i).low,
292 &(rar_addr[n].low)) != 0
293 || memrar_get_rar_addr (pdev,
294 (*i).high,
295 &(rar_addr[n].high)) != 0) {
296 result = -1;
297 break;
301 /* Done accessing the device. */
302 /* pci_dev_put(pdev); */
304 if (result == 0) {
305 if(1) {
306 size_t z;
307 for (z = 0; z != MRST_NUM_RAR; ++z) {
308 printk(KERN_WARNING "rar - BRAR[%Zd] physical address low\n"
309 "\tlow: 0x%08x\n"
310 "\thigh: 0x%08x\n",
312 rar_addr[z].low,
313 rar_addr[z].high);
318 return result;
322 function that is activaed on the succesfull probe of the RAR device
324 static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
326 /* error */
327 int error;
329 /*------------------------
330 CODE
331 ---------------------------*/
333 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
334 "Rar pci probe starting\n");
335 error = 0;
337 /* enable the device */
338 error = pci_enable_device(pdev);
339 if (error) {
340 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
341 "error enabling pci device\n");
342 goto end_function;
345 rar_dev = pdev;
346 registered = 1;
348 /* Initialize the RAR parameters, which have to be retrieved */
349 /* via the message bus service */
350 error=memrar_init_rar_params(rar_dev);
352 if (error) {
353 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
354 "error getting RAR addresses device\n");
355 registered = 0;
356 goto end_function;
359 end_function:
361 return error;
365 this function registers th driver to
366 the device subsystem( either PCI, USB, etc)
368 static int __init rar_init_handler(void)
370 return pci_register_driver(&rar_pci_driver);
373 static void __exit rar_exit_handler(void)
375 pci_unregister_driver(&rar_pci_driver);
378 module_init(rar_init_handler);
379 module_exit(rar_exit_handler);
381 MODULE_LICENSE("GPL");
384 /* The get_rar_address function is used by other device drivers
385 * to obtain RAR address information on a RAR. It takes two
386 * parameter:
388 * int rar_index
389 * The rar_index is an index to the rar for which you wish to retrieve
390 * the address information.
391 * Values can be 0,1, or 2.
393 * struct RAR_address_struct is a pointer to a place to which the function
394 * can return the address structure for the RAR.
396 * The function returns a 0 upon success or a -1 if there is no RAR
397 * facility on this system.
399 int get_rar_address(int rar_index,struct RAR_address_struct *addresses)
401 if (registered && (rar_index < 3) && (rar_index >= 0)) {
402 *addresses=rar_addr[rar_index];
403 /* strip off lock bit information */
404 addresses->low = addresses->low & 0xfffffff0;
405 addresses->high = addresses->high & 0xfffffff0;
406 return 0;
409 else {
410 return -ENODEV;
415 EXPORT_SYMBOL(get_rar_address);
417 /* The lock_rar function is ued by other device drivers to lock an RAR.
418 * once an RAR is locked, it stays locked until the next system reboot.
419 * The function takes one parameter:
421 * int rar_index
422 * The rar_index is an index to the rar that you want to lock.
423 * Values can be 0,1, or 2.
425 * The function returns a 0 upon success or a -1 if there is no RAR
426 * facility on this system.
428 int lock_rar(int rar_index)
430 u32 working_addr;
431 int result;
432 if (registered && (rar_index < 3) && (rar_index >= 0)) {
433 /* first make sure that lock bits are clear (this does lock) */
434 working_addr=rar_addr[rar_index].low & 0xfffffff0;
436 /* now send that value to the register using the IPC */
437 result=memrar_set_rar_addr(rar_dev,rar_index,working_addr);
438 return result;
441 else {
442 return -ENODEV;