pci_hotplug_util.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:12k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * PCI HotPlug Utility functions
  3.  *
  4.  * Copyright (c) 1995,2001 Compaq Computer Corporation
  5.  * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
  6.  * Copyright (c) 2001 IBM Corp.
  7.  *
  8.  * All rights reserved.
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or (at
  13.  * your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful, but
  16.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  18.  * NON INFRINGEMENT.  See the GNU General Public License for more
  19.  * details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  *
  25.  * Send feedback to <greg@kroah.com>
  26.  *
  27.  */
  28. #include <linux/config.h>
  29. #include <linux/module.h>
  30. #include <linux/kernel.h>
  31. #include <linux/types.h>
  32. #include <linux/slab.h>
  33. #include <linux/pci.h>
  34. #include "pci_hotplug.h"
  35. #if !defined(CONFIG_HOTPLUG_PCI_MODULE)
  36. #define MY_NAME "pci_hotplug"
  37. #else
  38. #define MY_NAME THIS_MODULE->name
  39. #endif
  40. #define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: "__FUNCTION__": " fmt , MY_NAME , ## arg); } while (0)
  41. #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
  42. #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
  43. #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
  44. /* local variables */
  45. static int debug;
  46. static int build_dev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, struct pci_dev **pci_dev)
  47. {
  48. struct pci_dev *my_dev;
  49. struct pci_bus *my_bus;
  50. /* Some validity checks. */
  51. if ((function > 7) ||
  52.     (slot > 31) ||
  53.     (pci_dev == NULL) ||
  54.     (ops == NULL))
  55. return -ENODEV;
  56. my_dev = kmalloc (sizeof (struct pci_dev), GFP_KERNEL);
  57. if (!my_dev)
  58. return -ENOMEM;
  59. my_bus = kmalloc (sizeof (struct pci_bus), GFP_KERNEL);
  60. if (!my_bus) {
  61. kfree (my_dev);
  62. return -ENOMEM;
  63. }
  64. memset(my_dev, 0, sizeof(struct pci_dev));
  65. memset(my_bus, 0, sizeof(struct pci_bus));
  66. my_bus->number = bus;
  67. my_bus->ops = ops;
  68. my_dev->devfn = PCI_DEVFN(slot, function);
  69. my_dev->bus = my_bus;
  70. *pci_dev = my_dev;
  71. return 0;
  72. }
  73. /**
  74.  * pci_read_config_byte_nodev - read a byte from a pci device
  75.  * @ops: pointer to a &struct pci_ops that will be used to read from the pci device
  76.  * @bus: the bus of the pci device to read from
  77.  * @slot: the pci slot number of the pci device to read from
  78.  * @function: the function of the pci device to read from
  79.  * @where: the location on the pci address space to read from
  80.  * @value: pointer to where to place the data read
  81.  *
  82.  * Like pci_read_config_byte() but works for pci devices that do not have a
  83.  * pci_dev structure set up yet.
  84.  * Returns 0 on success.
  85.  */
  86. int pci_read_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u8 *value)
  87. {
  88. struct pci_dev *dev = NULL;
  89. int result;
  90. dbg("%p, %d, %d, %d, %d, %pn", ops, bus, slot, function, where, value);
  91. dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
  92. if (dev) {
  93. dbg("using native pci_devn");
  94. return pci_read_config_byte (dev, where, value);
  95. }
  96. result = build_dev (ops, bus, slot, function, &dev);
  97. if (result)
  98. return result;
  99. result = pci_read_config_byte(dev, where, value);
  100. kfree (dev->bus);
  101. kfree (dev);
  102. return result;
  103. }
  104. /**
  105.  * pci_read_config_word_nodev - read a word from a pci device
  106.  * @ops: pointer to a &struct pci_ops that will be used to read from the pci device
  107.  * @bus: the bus of the pci device to read from
  108.  * @slot: the pci slot number of the pci device to read from
  109.  * @function: the function of the pci device to read from
  110.  * @where: the location on the pci address space to read from
  111.  * @value: pointer to where to place the data read
  112.  *
  113.  * Like pci_read_config_word() but works for pci devices that do not have a
  114.  * pci_dev structure set up yet. 
  115.  * Returns 0 on success.
  116.  */
  117. int pci_read_config_word_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u16 *value)
  118. {
  119. struct pci_dev *dev = NULL;
  120. int result;
  121. dbg("%p, %d, %d, %d, %d, %pn", ops, bus, slot, function, where, value);
  122. dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
  123. if (dev) {
  124. dbg("using native pci_devn");
  125. return pci_read_config_word (dev, where, value);
  126. }
  127. result = build_dev (ops, bus, slot, function, &dev);
  128. if (result)
  129. return result;
  130. result = pci_read_config_word(dev, where, value);
  131. kfree (dev->bus);
  132. kfree (dev);
  133. return result;
  134. }
  135. /**
  136.  * pci_read_config_dword_nodev - read a dword from a pci device
  137.  * @ops: pointer to a &struct pci_ops that will be used to read from the pci
  138.  * device
  139.  * @bus: the bus of the pci device to read from
  140.  * @slot: the pci slot number of the pci device to read from
  141.  * @function: the function of the pci device to read from
  142.  * @where: the location on the pci address space to read from
  143.  * @value: pointer to where to place the data read
  144.  *
  145.  * Like pci_read_config_dword() but works for pci devices that do not have a
  146.  * pci_dev structure set up yet. 
  147.  * Returns 0 on success.
  148.  */
  149. int pci_read_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u32 *value)
  150. {
  151. struct pci_dev *dev = NULL;
  152. int result;
  153. dbg("%p, %d, %d, %d, %d, %pn", ops, bus, slot, function, where, value);
  154. dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
  155. if (dev) {
  156. dbg("using native pci_devn");
  157. return pci_read_config_dword (dev, where, value);
  158. }
  159. result = build_dev (ops, bus, slot, function, &dev);
  160. if (result)
  161. return result;
  162. result = pci_read_config_dword(dev, where, value);
  163. kfree (dev->bus);
  164. kfree (dev);
  165. return result;
  166. }
  167. /**
  168.  * pci_write_config_byte_nodev - write a byte to a pci device
  169.  * @ops: pointer to a &struct pci_ops that will be used to write to the pci
  170.  * device
  171.  * @bus: the bus of the pci device to write to
  172.  * @slot: the pci slot number of the pci device to write to
  173.  * @function: the function of the pci device to write to
  174.  * @where: the location on the pci address space to write to
  175.  * @value: the value to write to the pci device
  176.  *
  177.  * Like pci_write_config_byte() but works for pci devices that do not have a
  178.  * pci_dev structure set up yet. 
  179.  * Returns 0 on success.
  180.  */
  181. int pci_write_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u8 value)
  182. {
  183. struct pci_dev *dev = NULL;
  184. int result;
  185. dbg("%p, %d, %d, %d, %d, %dn", ops, bus, slot, function, where, value);
  186. dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
  187. if (dev) {
  188. dbg("using native pci_devn");
  189. return pci_write_config_byte (dev, where, value);
  190. }
  191. result = build_dev (ops, bus, slot, function, &dev);
  192. if (result)
  193. return result;
  194. result = pci_write_config_byte(dev, where, value);
  195. kfree (dev->bus);
  196. kfree (dev);
  197. return result;
  198. }
  199. /**
  200.  * pci_write_config_word_nodev - write a word to a pci device
  201.  * @ops: pointer to a &struct pci_ops that will be used to write to the pci
  202.  * device
  203.  * @bus: the bus of the pci device to write to
  204.  * @slot: the pci slot number of the pci device to write to
  205.  * @function: the function of the pci device to write to
  206.  * @where: the location on the pci address space to write to
  207.  * @value: the value to write to the pci device
  208.  *
  209.  * Like pci_write_config_word() but works for pci devices that do not have a
  210.  * pci_dev structure set up yet. 
  211.  * Returns 0 on success.
  212.  */
  213. int pci_write_config_word_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u16 value)
  214. {
  215. struct pci_dev *dev = NULL;
  216. int result;
  217. dbg("%p, %d, %d, %d, %d, %dn", ops, bus, slot, function, where, value);
  218. dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
  219. if (dev) {
  220. dbg("using native pci_devn");
  221. return pci_write_config_word (dev, where, value);
  222. }
  223. result = build_dev (ops, bus, slot, function, &dev);
  224. if (result)
  225. return result;
  226. result = pci_write_config_word(dev, where, value);
  227. kfree (dev->bus);
  228. kfree (dev);
  229. return result;
  230. }
  231. /**
  232.  * pci_write_config_dword_nodev - write a dword to a pci device
  233.  * @ops: pointer to a &struct pci_ops that will be used to write to the pci
  234.  * device
  235.  * @bus: the bus of the pci device to write to
  236.  * @slot: the pci slot number of the pci device to write to
  237.  * @function: the function of the pci device to write to
  238.  * @where: the location on the pci address space to write to
  239.  * @value: the value to write to the pci device
  240.  *
  241.  * Like pci_write_config_dword() but works for pci devices that do not have a
  242.  * pci_dev structure set up yet. 
  243.  * Returns 0 on success.
  244.  */
  245. int pci_write_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u32 value)
  246. {
  247. struct pci_dev *dev = NULL;
  248. int result;
  249. dbg("%p, %d, %d, %d, %d, %dn", ops, bus, slot, function, where, value);
  250. dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
  251. if (dev) {
  252. dbg("using native pci_devn");
  253. return pci_write_config_dword (dev, where, value);
  254. }
  255. result = build_dev (ops, bus, slot, function, &dev);
  256. if (result)
  257. return result;
  258. result = pci_write_config_dword(dev, where, value);
  259. kfree (dev->bus);
  260. kfree (dev);
  261. return result;
  262. }
  263. /*
  264.  * This is code that scans the pci buses.
  265.  * Every bus and every function is presented to a custom
  266.  * function that can act upon it.
  267.  */
  268. static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
  269. {
  270. struct list_head *ln;
  271. struct pci_dev *dev;
  272. struct pci_dev_wrapped wrapped_dev;
  273. int result = 0;
  274. dbg("scanning bus %02xn", wrapped_bus->bus->number);
  275. if (fn->pre_visit_pci_bus) {
  276. result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
  277. if (result)
  278. return result;
  279. }
  280. ln = wrapped_bus->bus->devices.next; 
  281. while (ln != &wrapped_bus->bus->devices) {
  282. dev = pci_dev_b(ln);
  283. ln = ln->next;
  284. memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
  285. wrapped_dev.dev = dev;
  286. result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
  287. if (result)
  288. return result;
  289. }
  290. if (fn->post_visit_pci_bus)
  291. result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
  292. return result;
  293. }
  294. static int pci_visit_bridge (struct pci_visit * fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent)
  295. {
  296. struct pci_bus *bus = wrapped_dev->dev->subordinate;
  297. struct pci_bus_wrapped wrapped_bus;
  298. int result;
  299. memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
  300. wrapped_bus.bus = bus;
  301. dbg("scanning bridge %02x, %02xn", wrapped_dev->dev->devfn >> 3,
  302.     wrapped_dev->dev->devfn & 0x7);
  303. if (fn->visit_pci_dev) {
  304. result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
  305. if (result)
  306. return result;
  307. }
  308. result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
  309. return result;
  310. }
  311. int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent)
  312. {
  313. struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
  314. int result = 0;
  315. if (!dev)
  316. return 0;
  317. if (fn->pre_visit_pci_dev) {
  318. result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
  319. if (result)
  320. return result;
  321. }
  322. switch (dev->class >> 8) {
  323. case PCI_CLASS_BRIDGE_PCI:
  324. result = pci_visit_bridge(fn, wrapped_dev,
  325.   wrapped_parent);
  326. if (result)
  327. return result;
  328. break;
  329. default:
  330. dbg("scanning device %02x, %02xn",
  331.     PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
  332. if (fn->visit_pci_dev) {
  333. result = fn->visit_pci_dev (wrapped_dev,
  334.     wrapped_parent);
  335. if (result)
  336. return result;
  337. }
  338. }
  339. if (fn->post_visit_pci_dev)
  340. result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
  341. return result;
  342. }
  343. EXPORT_SYMBOL(pci_visit_dev);
  344. EXPORT_SYMBOL(pci_read_config_byte_nodev);
  345. EXPORT_SYMBOL(pci_read_config_word_nodev);
  346. EXPORT_SYMBOL(pci_read_config_dword_nodev);
  347. EXPORT_SYMBOL(pci_write_config_byte_nodev);
  348. EXPORT_SYMBOL(pci_write_config_word_nodev);
  349. EXPORT_SYMBOL(pci_write_config_dword_nodev);