Commit | Line | Data |
---|---|---|
433e63c6 MA |
1 | /* |
2 | * rar_register.c - An Intel Restricted Access Region register driver | |
3 | * | |
4 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License as | |
8 | * published by the Free Software Foundation; either version 2 of the | |
9 | * License, or (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 | * 02111-1307, USA. | |
20 | * | |
21 | * ------------------------------------------------------------------- | |
22 | * 20091204 Mark Allyn <mark.a.allyn@intel.com> | |
23 | * Ossama Othman <ossama.othman@intel.com> | |
24 | * Cleanup per feedback from Alan Cox and Arjan Van De Ven | |
25 | * | |
26 | * 20090806 Ossama Othman <ossama.othman@intel.com> | |
27 | * Return zero high address if upper 22 bits is zero. | |
28 | * Cleaned up checkpatch errors. | |
29 | * Clarified that driver is dealing with bus addresses. | |
30 | * | |
31 | * 20090702 Ossama Othman <ossama.othman@intel.com> | |
32 | * Removed unnecessary include directives | |
33 | * Cleaned up spinlocks. | |
34 | * Cleaned up logging. | |
35 | * Improved invalid parameter checks. | |
36 | * Fixed and simplified RAR address retrieval and RAR locking | |
37 | * code. | |
38 | * | |
39 | * 20090626 Mark Allyn <mark.a.allyn@intel.com> | |
40 | * Initial publish | |
41 | */ | |
42 | ||
43 | #define DEBUG 1 | |
44 | ||
ee7dfb7e | 45 | #include "rar_register.h" |
542385ee | 46 | |
433e63c6 MA |
47 | #include <linux/module.h> |
48 | #include <linux/pci.h> | |
49 | #include <linux/spinlock.h> | |
50 | #include <linux/device.h> | |
51 | #include <linux/kernel.h> | |
542385ee AC |
52 | |
53 | /* === Lincroft Message Bus Interface === */ | |
375d65db AC |
54 | #define LNC_MCR_OFFSET 0xD0 /* Message Control Register */ |
55 | #define LNC_MDR_OFFSET 0xD4 /* Message Data Register */ | |
542385ee AC |
56 | |
57 | /* Message Opcodes */ | |
375d65db | 58 | #define LNC_MESSAGE_READ_OPCODE 0xD0 |
542385ee AC |
59 | #define LNC_MESSAGE_WRITE_OPCODE 0xE0 |
60 | ||
61 | /* Message Write Byte Enables */ | |
375d65db | 62 | #define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF |
542385ee AC |
63 | |
64 | /* B-unit Port */ | |
375d65db | 65 | #define LNC_BUNIT_PORT 0x3 |
542385ee AC |
66 | |
67 | /* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ | |
375d65db AC |
68 | #define LNC_BRAR0L 0x10 |
69 | #define LNC_BRAR0H 0x11 | |
70 | #define LNC_BRAR1L 0x12 | |
71 | #define LNC_BRAR1H 0x13 | |
542385ee | 72 | /* Reserved for SeP */ |
375d65db AC |
73 | #define LNC_BRAR2L 0x14 |
74 | #define LNC_BRAR2H 0x15 | |
542385ee | 75 | |
433e63c6 MA |
76 | /* Moorestown supports three restricted access regions. */ |
77 | #define MRST_NUM_RAR 3 | |
542385ee | 78 | |
433e63c6 | 79 | /* RAR Bus Address Range */ |
375d65db | 80 | struct rar_addr { |
433e63c6 MA |
81 | dma_addr_t low; |
82 | dma_addr_t high; | |
83 | }; | |
542385ee | 84 | |
375d65db AC |
85 | /* |
86 | * We create one of these for each RAR | |
87 | */ | |
433e63c6 | 88 | struct client { |
375d65db AC |
89 | int (*callback)(unsigned long data); |
90 | unsigned long driver_priv; | |
91 | bool busy; | |
92 | }; | |
542385ee | 93 | |
433e63c6 MA |
94 | static DEFINE_MUTEX(rar_mutex); |
95 | static DEFINE_MUTEX(lnc_reg_mutex); | |
542385ee | 96 | |
375d65db AC |
97 | /* |
98 | * One per RAR device (currently only one device) | |
99 | */ | |
100 | struct rar_device { | |
101 | struct rar_addr rar_addr[MRST_NUM_RAR]; | |
433e63c6 MA |
102 | struct pci_dev *rar_dev; |
103 | bool registered; | |
375d65db AC |
104 | bool allocated; |
105 | struct client client[MRST_NUM_RAR]; | |
542385ee AC |
106 | }; |
107 | ||
375d65db AC |
108 | /* Current platforms have only one rar_device for 3 rar regions */ |
109 | static struct rar_device my_rar_device; | |
110 | ||
111 | /* | |
112 | * Abstract out multiple device support. Current platforms only | |
113 | * have a single RAR device. | |
433e63c6 | 114 | */ |
542385ee | 115 | |
375d65db AC |
116 | /** |
117 | * alloc_rar_device - return a new RAR structure | |
118 | * | |
119 | * Return a new (but not yet ready) RAR device object | |
120 | */ | |
121 | static struct rar_device *alloc_rar_device(void) | |
122 | { | |
123 | if (my_rar_device.allocated) | |
124 | return NULL; | |
125 | my_rar_device.allocated = 1; | |
126 | return &my_rar_device; | |
127 | } | |
542385ee | 128 | |
375d65db AC |
129 | /** |
130 | * free_rar_device - free a RAR object | |
131 | * @rar: the RAR device being freed | |
132 | * | |
133 | * Release a RAR object and any attached resources | |
433e63c6 | 134 | */ |
375d65db AC |
135 | static void free_rar_device(struct rar_device *rar) |
136 | { | |
137 | pci_dev_put(rar->rar_dev); | |
138 | rar->allocated = 0; | |
139 | } | |
140 | ||
141 | /** | |
142 | * _rar_to_device - return the device handling this RAR | |
143 | * @rar: RAR number | |
144 | * @off: returned offset | |
145 | * | |
146 | * Internal helper for looking up RAR devices. This and alloc are the | |
147 | * two functions that need touching to go to multiple RAR devices. | |
148 | */ | |
149 | static struct rar_device *_rar_to_device(int rar, int *off) | |
150 | { | |
151 | if (rar >= 0 && rar <= 3) { | |
152 | *off = rar; | |
153 | return &my_rar_device; | |
154 | } | |
155 | return NULL; | |
156 | } | |
157 | ||
158 | ||
159 | /** | |
160 | * rar_to_device - return the device handling this RAR | |
161 | * @rar: RAR number | |
162 | * @off: returned offset | |
163 | * | |
164 | * Return the device this RAR maps to if one is present, otherwise | |
165 | * returns NULL. Reports the offset relative to the base of this | |
166 | * RAR device in off. | |
167 | */ | |
168 | static struct rar_device *rar_to_device(int rar, int *off) | |
169 | { | |
170 | struct rar_device *rar_dev = _rar_to_device(rar, off); | |
171 | if (rar_dev == NULL || !rar_dev->registered) | |
172 | return NULL; | |
173 | return rar_dev; | |
174 | } | |
175 | ||
176 | /** | |
177 | * rar_to_client - return the client handling this RAR | |
178 | * @rar: RAR number | |
179 | * | |
180 | * Return the client this RAR maps to if a mapping is known, otherwise | |
181 | * returns NULL. | |
182 | */ | |
183 | static struct client *rar_to_client(int rar) | |
184 | { | |
185 | int idx; | |
186 | struct rar_device *r = _rar_to_device(rar, &idx); | |
187 | if (r != NULL) | |
188 | return &r->client[idx]; | |
189 | return NULL; | |
190 | } | |
191 | ||
192 | /** | |
193 | * rar_read_addr - retrieve a RAR mapping | |
194 | * @pdev: PCI device for the RAR | |
195 | * @offset: offset for message | |
196 | * @addr: returned address | |
197 | * | |
198 | * Reads the address of a given RAR register. Returns 0 on success | |
199 | * or an error code on failure. | |
200 | */ | |
201 | static int rar_read_addr(struct pci_dev *pdev, int offset, dma_addr_t *addr) | |
542385ee AC |
202 | { |
203 | /* | |
204 | * ======== The Lincroft Message Bus Interface ======== | |
375d65db AC |
205 | * Lincroft registers may be obtained via PCI from |
206 | * the host bridge using the Lincroft Message Bus | |
542385ee AC |
207 | * Interface. That message bus interface is generally |
208 | * comprised of two registers: a control register (MCR, 0xDO) | |
209 | * and a data register (MDR, 0xD4). | |
210 | * | |
211 | * The MCR (message control register) format is the following: | |
212 | * 1. [31:24]: Opcode | |
213 | * 2. [23:16]: Port | |
214 | * 3. [15:8]: Register Offset | |
215 | * 4. [7:4]: Byte Enables (use 0xF to set all of these bits | |
216 | * to 1) | |
217 | * 5. [3:0]: reserved | |
218 | * | |
219 | * Read (0xD0) and write (0xE0) opcodes are written to the | |
220 | * control register when reading and writing to Lincroft | |
221 | * registers, respectively. | |
222 | * | |
223 | * We're interested in registers found in the Lincroft | |
224 | * B-unit. The B-unit port is 0x3. | |
225 | * | |
226 | * The six B-unit RAR register offsets we use are listed | |
227 | * earlier in this file. | |
228 | * | |
229 | * Lastly writing to the MCR register requires the "Byte | |
230 | * enables" bits to be set to 1. This may be achieved by | |
231 | * writing 0xF at bit 4. | |
232 | * | |
233 | * The MDR (message data register) format is the following: | |
234 | * 1. [31:0]: Read/Write Data | |
235 | * | |
236 | * Data being read from this register is only available after | |
237 | * writing the appropriate control message to the MCR | |
238 | * register. | |
239 | * | |
240 | * Data being written to this register must be written before | |
241 | * writing the appropriate control message to the MCR | |
242 | * register. | |
433e63c6 MA |
243 | */ |
244 | ||
245 | int result; | |
375d65db | 246 | u32 addr32; |
542385ee | 247 | |
542385ee AC |
248 | /* Construct control message */ |
249 | u32 const message = | |
433e63c6 MA |
250 | (LNC_MESSAGE_READ_OPCODE << 24) |
251 | | (LNC_BUNIT_PORT << 16) | |
252 | | (offset << 8) | |
253 | | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); | |
542385ee | 254 | |
433e63c6 | 255 | dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset); |
542385ee | 256 | |
433e63c6 MA |
257 | /* |
258 | * We synchronize access to the Lincroft MCR and MDR registers | |
259 | * until BOTH the command is issued through the MCR register | |
260 | * and the corresponding data is read from the MDR register. | |
261 | * Otherwise a race condition would exist between accesses to | |
262 | * both registers. | |
263 | */ | |
264 | ||
265 | mutex_lock(&lnc_reg_mutex); | |
542385ee AC |
266 | |
267 | /* Send the control message */ | |
433e63c6 | 268 | result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); |
433e63c6 | 269 | if (!result) { |
375d65db AC |
270 | /* Read back the address as a 32bit value */ |
271 | result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, &addr32); | |
272 | *addr = (dma_addr_t)addr32; | |
433e63c6 | 273 | } |
433e63c6 | 274 | mutex_unlock(&lnc_reg_mutex); |
433e63c6 | 275 | return result; |
542385ee AC |
276 | } |
277 | ||
375d65db AC |
278 | /** |
279 | * rar_set_addr - Set a RAR mapping | |
280 | * @pdev: PCI device for the RAR | |
281 | * @offset: offset for message | |
282 | * @addr: address to set | |
283 | * | |
284 | * Sets the address of a given RAR register. Returns 0 on success | |
285 | * or an error code on failure. | |
286 | */ | |
287 | static int rar_set_addr(struct pci_dev *pdev, | |
433e63c6 MA |
288 | int offset, |
289 | dma_addr_t addr) | |
542385ee AC |
290 | { |
291 | /* | |
433e63c6 MA |
292 | * Data being written to this register must be written before |
293 | * writing the appropriate control message to the MCR | |
294 | * register. | |
375d65db | 295 | * See rar_get_addrs() for a description of the |
433e63c6 MA |
296 | * message bus interface being used here. |
297 | */ | |
542385ee | 298 | |
375d65db | 299 | int result; |
542385ee AC |
300 | |
301 | /* Construct control message */ | |
433e63c6 MA |
302 | u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24) |
303 | | (LNC_BUNIT_PORT << 16) | |
304 | | (offset << 8) | |
305 | | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); | |
542385ee | 306 | |
433e63c6 MA |
307 | /* |
308 | * We synchronize access to the Lincroft MCR and MDR registers | |
309 | * until BOTH the command is issued through the MCR register | |
310 | * and the corresponding data is read from the MDR register. | |
311 | * Otherwise a race condition would exist between accesses to | |
312 | * both registers. | |
313 | */ | |
314 | ||
315 | mutex_lock(&lnc_reg_mutex); | |
542385ee AC |
316 | |
317 | /* Send the control message */ | |
433e63c6 | 318 | result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr); |
375d65db AC |
319 | if (!result) |
320 | /* And address */ | |
433e63c6 MA |
321 | result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); |
322 | ||
433e63c6 | 323 | mutex_unlock(&lnc_reg_mutex); |
433e63c6 | 324 | return result; |
542385ee AC |
325 | } |
326 | ||
327 | /* | |
375d65db AC |
328 | * rar_init_params - Initialize RAR parameters |
329 | * @rar: RAR device to initialise | |
330 | * | |
331 | * Initialize RAR parameters, such as bus addresses, etc. Returns 0 | |
332 | * on success, or an error code on failure. | |
333 | */ | |
334 | static int init_rar_params(struct rar_device *rar) | |
542385ee | 335 | { |
375d65db | 336 | struct pci_dev *pdev = rar->rar_dev; |
433e63c6 | 337 | unsigned int i; |
542385ee | 338 | int result = 0; |
375d65db | 339 | int offset = 0x10; /* RAR 0 to 2 in order low/high/low/high/... */ |
542385ee | 340 | |
433e63c6 MA |
341 | /* Retrieve RAR start and end bus addresses. |
342 | * Access the RAR registers through the Lincroft Message Bus | |
343 | * Interface on PCI device: 00:00.0 Host bridge. | |
344 | */ | |
542385ee | 345 | |
433e63c6 | 346 | for (i = 0; i < MRST_NUM_RAR; ++i) { |
375d65db AC |
347 | struct rar_addr *addr = &rar->rar_addr[i]; |
348 | ||
349 | result = rar_read_addr(pdev, offset++, &addr->low); | |
350 | if (result != 0) | |
351 | return result; | |
352 | ||
353 | result = rar_read_addr(pdev, offset++, &addr->high); | |
354 | if (result != 0) | |
355 | return result; | |
356 | ||
542385ee | 357 | |
433e63c6 MA |
358 | /* |
359 | * Only the upper 22 bits of the RAR addresses are | |
360 | * stored in their corresponding RAR registers so we | |
361 | * must set the lower 10 bits accordingly. | |
362 | ||
363 | * The low address has its lower 10 bits cleared, and | |
364 | * the high address has all its lower 10 bits set, | |
365 | * e.g.: | |
366 | * low = 0x2ffffc00 | |
367 | */ | |
368 | ||
369 | addr->low &= (dma_addr_t)0xfffffc00u; | |
370 | ||
371 | /* | |
372 | * Set bits 9:0 on uppser address if bits 31:10 are non | |
373 | * zero; otherwize clear all bits | |
374 | */ | |
375 | ||
376 | if ((addr->high & 0xfffffc00u) == 0) | |
377 | addr->high = 0; | |
378 | else | |
379 | addr->high |= 0x3ffu; | |
380 | } | |
542385ee | 381 | /* Done accessing the device. */ |
542385ee AC |
382 | |
383 | if (result == 0) { | |
375d65db | 384 | for (i = 0; i != MRST_NUM_RAR; ++i) { |
433e63c6 MA |
385 | /* |
386 | * "BRAR" refers to the RAR registers in the | |
387 | * Lincroft B-unit. | |
388 | */ | |
389 | dev_info(&pdev->dev, "BRAR[%u] bus address range = " | |
375d65db AC |
390 | "[%lx, %lx]\n", i, |
391 | (unsigned long)rar->rar_addr[i].low, | |
392 | (unsigned long)rar->rar_addr[i].high); | |
433e63c6 MA |
393 | } |
394 | } | |
433e63c6 MA |
395 | return result; |
396 | } | |
397 | ||
375d65db AC |
398 | /** |
399 | * rar_get_address - get the bus address in a RAR | |
400 | * @start: return value of start address of block | |
401 | * @end: return value of end address of block | |
433e63c6 | 402 | * |
375d65db AC |
403 | * The rar_get_address function is used by other device drivers |
404 | * to obtain RAR address information on a RAR. It takes three | |
405 | * parameters: | |
433e63c6 | 406 | * |
375d65db AC |
407 | * The function returns a 0 upon success or an error if there is no RAR |
408 | * facility on this system. | |
433e63c6 | 409 | */ |
375d65db | 410 | int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end) |
433e63c6 | 411 | { |
375d65db AC |
412 | int idx; |
413 | struct rar_device *rar = rar_to_device(rar_index, &idx); | |
414 | ||
415 | if (rar == NULL) { | |
416 | WARN_ON(1); | |
417 | return -ENODEV; | |
542385ee AC |
418 | } |
419 | ||
375d65db AC |
420 | *start = rar->rar_addr[idx].low; |
421 | *end = rar->rar_addr[idx].high; | |
422 | return 0; | |
542385ee | 423 | } |
433e63c6 | 424 | EXPORT_SYMBOL(rar_get_address); |
542385ee | 425 | |
375d65db AC |
426 | /** |
427 | * rar_lock - lock a RAR register | |
428 | * @rar_index: RAR to lock (0-2) | |
433e63c6 | 429 | * |
375d65db AC |
430 | * The rar_lock function is ued by other device drivers to lock an RAR. |
431 | * once a RAR is locked, it stays locked until the next system reboot. | |
433e63c6 | 432 | * |
375d65db AC |
433 | * The function returns a 0 upon success or an error if there is no RAR |
434 | * facility on this system, or the locking fails | |
433e63c6 MA |
435 | */ |
436 | int rar_lock(int rar_index) | |
437 | { | |
375d65db AC |
438 | struct rar_device *rar; |
439 | int result; | |
440 | int idx; | |
441 | dma_addr_t low, high; | |
433e63c6 | 442 | |
375d65db | 443 | rar = rar_to_device(rar_index, &idx); |
433e63c6 | 444 | |
375d65db AC |
445 | if (rar == NULL) { |
446 | WARN_ON(1); | |
447 | return -EINVAL; | |
448 | } | |
433e63c6 | 449 | |
375d65db AC |
450 | low = rar->rar_addr[idx].low & 0xfffffc00u; |
451 | high = rar->rar_addr[idx].high & 0xfffffc00u; | |
433e63c6 | 452 | |
375d65db AC |
453 | /* |
454 | * Only allow I/O from the graphics and Langwell; | |
455 | * not from the x86 processor | |
456 | */ | |
433e63c6 | 457 | |
375d65db AC |
458 | if (rar_index == RAR_TYPE_VIDEO) { |
459 | low |= 0x00000009; | |
460 | high |= 0x00000015; | |
461 | } else if (rar_index == RAR_TYPE_AUDIO) { | |
462 | /* Only allow I/O from Langwell; nothing from x86 */ | |
463 | low |= 0x00000008; | |
464 | high |= 0x00000018; | |
465 | } else | |
466 | /* Read-only from all agents */ | |
467 | high |= 0x00000018; | |
433e63c6 | 468 | |
375d65db AC |
469 | /* |
470 | * Now program the register using the Lincroft message | |
471 | * bus interface. | |
472 | */ | |
473 | result = rar_set_addr(rar->rar_dev, | |
474 | 2 * idx, low); | |
433e63c6 | 475 | |
375d65db AC |
476 | if (result == 0) |
477 | result = rar_set_addr(rar->rar_dev, | |
478 | 2 * idx + 1, high); | |
433e63c6 | 479 | |
433e63c6 MA |
480 | return result; |
481 | } | |
482 | EXPORT_SYMBOL(rar_lock); | |
483 | ||
375d65db AC |
484 | /** |
485 | * register_rar - register a RAR handler | |
486 | * @num: RAR we wish to register for | |
487 | * @callback: function to call when RAR support is available | |
488 | * @data: data to pass to this function | |
489 | * | |
490 | * The register_rar function is to used by other device drivers | |
491 | * to ensure that this driver is ready. As we cannot be sure of | |
492 | * the compile/execute order of drivers in ther kernel, it is | |
493 | * best to give this driver a callback function to call when | |
494 | * it is ready to give out addresses. The callback function | |
495 | * would have those steps that continue the initialization of | |
496 | * a driver that do require a valid RAR address. One of those | |
497 | * steps would be to call rar_get_address() | |
498 | * | |
499 | * This function return 0 on success an error code on failure. | |
500 | */ | |
501 | int register_rar(int num, int (*callback)(unsigned long data), | |
502 | unsigned long data) | |
542385ee | 503 | { |
375d65db AC |
504 | /* For now we hardcode a single RAR device */ |
505 | struct rar_device *rar; | |
506 | struct client *c; | |
507 | int idx; | |
508 | int retval = 0; | |
433e63c6 MA |
509 | |
510 | mutex_lock(&rar_mutex); | |
511 | ||
375d65db AC |
512 | /* Do we have a client mapping for this RAR number ? */ |
513 | c = rar_to_client(num); | |
514 | if (c == NULL) { | |
515 | retval = -ERANGE; | |
516 | goto done; | |
517 | } | |
518 | /* Is it claimed ? */ | |
519 | if (c->busy) { | |
520 | retval = -EBUSY; | |
521 | goto done; | |
522 | } | |
523 | c->busy = 1; | |
524 | ||
525 | /* See if we have a handler for this RAR yet, if we do then fire it */ | |
526 | rar = rar_to_device(num, &idx); | |
433e63c6 | 527 | |
375d65db | 528 | if (rar) { |
433e63c6 MA |
529 | /* |
530 | * if the driver already registered, then we can simply | |
531 | * call the callback right now | |
532 | */ | |
375d65db AC |
533 | (*callback)(data); |
534 | goto done; | |
433e63c6 MA |
535 | } |
536 | ||
375d65db AC |
537 | /* Arrange to be called back when the hardware is found */ |
538 | c->callback = callback; | |
539 | c->driver_priv = data; | |
540 | done: | |
433e63c6 | 541 | mutex_unlock(&rar_mutex); |
375d65db | 542 | return retval; |
433e63c6 MA |
543 | } |
544 | EXPORT_SYMBOL(register_rar); | |
545 | ||
375d65db AC |
546 | /** |
547 | * unregister_rar - release a RAR allocation | |
548 | * @num: RAR number | |
549 | * | |
550 | * Releases a RAR allocation, or pending allocation. If a callback is | |
551 | * pending then this function will either complete before the unregister | |
552 | * returns or not at all. | |
553 | */ | |
554 | ||
555 | void unregister_rar(int num) | |
3913add4 | 556 | { |
375d65db AC |
557 | struct client *c; |
558 | ||
559 | mutex_lock(&rar_mutex); | |
560 | c = rar_to_client(num); | |
561 | if (c == NULL || !c->busy) | |
562 | WARN_ON(1); | |
563 | else | |
564 | c->busy = 0; | |
565 | mutex_unlock(&rar_mutex); | |
3913add4 | 566 | } |
375d65db | 567 | EXPORT_SYMBOL(unregister_rar); |
3913add4 | 568 | |
375d65db AC |
569 | /** |
570 | * rar_callback - Process callbacks | |
571 | * @rar: new RAR device | |
572 | * | |
573 | * Process the callbacks for a newly found RAR device. | |
574 | */ | |
575 | ||
576 | static void rar_callback(struct rar_device *rar) | |
3913add4 | 577 | { |
375d65db AC |
578 | struct client *c = &rar->client[0]; |
579 | int i; | |
580 | ||
581 | mutex_lock(&rar_mutex); | |
582 | ||
583 | rar->registered = 1; /* Ensure no more callbacks queue */ | |
584 | ||
585 | for (i = 0; i < MRST_NUM_RAR; i++) { | |
586 | if (c->callback && c->busy) { | |
587 | c->callback(c->driver_priv); | |
588 | c->callback = NULL; | |
589 | } | |
590 | c++; | |
591 | } | |
592 | mutex_unlock(&rar_mutex); | |
3913add4 MA |
593 | } |
594 | ||
375d65db AC |
595 | /** |
596 | * rar_probe - PCI probe callback | |
597 | * @dev: PCI device | |
598 | * @id: matching entry in the match table | |
599 | * | |
600 | * A RAR device has been discovered. Initialise it and if successful | |
601 | * process any pending callbacks that can now be completed. | |
433e63c6 MA |
602 | */ |
603 | static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id) | |
604 | { | |
605 | int error; | |
375d65db | 606 | struct rar_device *rar; |
433e63c6 MA |
607 | |
608 | dev_dbg(&dev->dev, "PCI probe starting\n"); | |
542385ee | 609 | |
375d65db AC |
610 | rar = alloc_rar_device(); |
611 | if (rar == NULL) | |
612 | return -EBUSY; | |
613 | ||
614 | /* Enable the device */ | |
433e63c6 | 615 | error = pci_enable_device(dev); |
542385ee | 616 | if (error) { |
433e63c6 MA |
617 | dev_err(&dev->dev, |
618 | "Error enabling RAR register PCI device\n"); | |
542385ee AC |
619 | goto end_function; |
620 | } | |
621 | ||
375d65db AC |
622 | /* Fill in the rar_device structure */ |
623 | rar->rar_dev = pci_dev_get(dev); | |
624 | pci_set_drvdata(dev, rar); | |
542385ee | 625 | |
433e63c6 | 626 | /* |
375d65db AC |
627 | * Initialize the RAR parameters, which have to be retrieved |
628 | * via the message bus interface. | |
629 | */ | |
630 | error = init_rar_params(rar); | |
542385ee | 631 | if (error) { |
433e63c6 | 632 | pci_disable_device(dev); |
375d65db | 633 | dev_err(&dev->dev, "Error retrieving RAR addresses\n"); |
542385ee | 634 | goto end_function; |
433e63c6 | 635 | } |
433e63c6 | 636 | /* now call anyone who has registered (using callbacks) */ |
375d65db AC |
637 | rar_callback(rar); |
638 | return 0; | |
542385ee | 639 | end_function: |
375d65db | 640 | free_rar_device(rar); |
542385ee AC |
641 | return error; |
642 | } | |
643 | ||
433e63c6 | 644 | const struct pci_device_id rar_pci_id_tbl[] = { |
375d65db | 645 | { PCI_VDEVICE(INTEL, 0x4110) }, |
433e63c6 MA |
646 | { 0 } |
647 | }; | |
648 | ||
649 | MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); | |
650 | ||
651 | const struct pci_device_id *my_id_table = rar_pci_id_tbl; | |
652 | ||
653 | /* field for registering driver to PCI device */ | |
654 | static struct pci_driver rar_pci_driver = { | |
655 | .name = "rar_register_driver", | |
656 | .id_table = rar_pci_id_tbl, | |
3913add4 | 657 | .probe = rar_probe, |
375d65db | 658 | /* Cannot be unplugged - no remove */ |
433e63c6 MA |
659 | }; |
660 | ||
542385ee AC |
661 | static int __init rar_init_handler(void) |
662 | { | |
663 | return pci_register_driver(&rar_pci_driver); | |
664 | } | |
665 | ||
666 | static void __exit rar_exit_handler(void) | |
667 | { | |
668 | pci_unregister_driver(&rar_pci_driver); | |
669 | } | |
670 | ||
671 | module_init(rar_init_handler); | |
672 | module_exit(rar_exit_handler); | |
673 | ||
674 | MODULE_LICENSE("GPL"); | |
433e63c6 | 675 | MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver"); |