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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Compaq Hot Plug Controller Driver
  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/proc_fs.h>
  33. #include <linux/miscdevice.h>
  34. #include <linux/slab.h>
  35. #include <linux/pci.h>
  36. #include <linux/init.h>
  37. #include <asm/uaccess.h>
  38. #include "cpqphp.h"
  39. #include "cpqphp_nvram.h"
  40. #include "../../arch/i386/kernel/pci-i386.h" /* horrible hack showing how processor dependant we are... */
  41. /* Global variables */
  42. int cpqhp_debug;
  43. struct controller *cpqhp_ctrl_list; /* = NULL */
  44. struct pci_func *cpqhp_slot_list[256];
  45. /* local variables */
  46. static void *smbios_table;
  47. static void *smbios_start;
  48. static void *cpqhp_rom_start;
  49. static u8 power_mode;
  50. static int debug;
  51. #define DRIVER_VERSION "0.9.6"
  52. #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
  53. #define DRIVER_DESC "Compaq Hot Plug PCI Controller Driver"
  54. MODULE_AUTHOR(DRIVER_AUTHOR);
  55. MODULE_DESCRIPTION(DRIVER_DESC);
  56. MODULE_LICENSE("GPL");
  57. MODULE_PARM(power_mode, "b");
  58. MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
  59. MODULE_PARM(debug, "i");
  60. MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
  61. #define CPQHPC_MODULE_MINOR 208
  62. static int one_time_init (void);
  63. static int set_attention_status (struct hotplug_slot *slot, u8 value);
  64. static int process_SI (struct hotplug_slot *slot);
  65. static int process_SS (struct hotplug_slot *slot);
  66. static int hardware_test (struct hotplug_slot *slot, u32 value);
  67. static int get_power_status (struct hotplug_slot *slot, u8 *value);
  68. static int get_attention_status (struct hotplug_slot *slot, u8 *value);
  69. static int get_latch_status (struct hotplug_slot *slot, u8 *value);
  70. static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
  71. static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
  72. owner: THIS_MODULE,
  73. set_attention_status: set_attention_status,
  74. enable_slot: process_SI,
  75. disable_slot: process_SS,
  76. hardware_test: hardware_test,
  77. get_power_status: get_power_status,
  78. get_attention_status: get_attention_status,
  79. get_latch_status: get_latch_status,
  80. get_adapter_status: get_adapter_status,
  81. };
  82. static inline int is_slot64bit (struct slot *slot)
  83. {
  84. if (!slot || !slot->p_sm_slot)
  85. return 0;
  86. if (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06)
  87. return 1;
  88. return 0;
  89. }
  90. static inline int is_slot66mhz (struct slot *slot)
  91. {
  92. if (!slot || !slot->p_sm_slot)
  93. return 0;
  94. if (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E)
  95. return 1;
  96. return 0;
  97. }
  98. /**
  99.  * detect_SMBIOS_pointer - find the system Management BIOS Table in the specified region of memory.
  100.  *
  101.  * @begin: begin pointer for region to be scanned.
  102.  * @end: end pointer for region to be scanned.
  103.  *
  104.  * Returns pointer to the head of the SMBIOS tables (or NULL)
  105.  *
  106.  */
  107. static void * detect_SMBIOS_pointer(void *begin, void *end)
  108. {
  109. void *fp;
  110. void *endp;
  111. u8 temp1, temp2, temp3, temp4;
  112. int status = 0;
  113. endp = (end - sizeof(u32) + 1);
  114. for (fp = begin; fp <= endp; fp += 16) {
  115. temp1 = readb(fp);
  116. temp2 = readb(fp+1);
  117. temp3 = readb(fp+2);
  118. temp4 = readb(fp+3);
  119. if (temp1 == '_' &&
  120.     temp2 == 'S' &&
  121.     temp3 == 'M' &&
  122.     temp4 == '_') {
  123. status = 1;
  124. break;
  125. }
  126. }
  127. if (!status)
  128. fp = NULL;
  129. dbg("Discovered SMBIOS Entry point at %pn", fp);
  130. return fp;
  131. }
  132. /**
  133.  * init_SERR - Initializes the per slot SERR generation.
  134.  *
  135.  * For unexpected switch opens
  136.  *
  137.  */
  138. static int init_SERR(struct controller * ctrl)
  139. {
  140. u32 tempdword;
  141. u32 number_of_slots;
  142. u8 physical_slot;
  143. if (!ctrl)
  144. return 1;
  145. tempdword = ctrl->first_slot;
  146. number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
  147. // Loop through slots
  148. while (number_of_slots) {
  149. physical_slot = tempdword;
  150. writeb(0, ctrl->hpc_reg + SLOT_SERR);
  151. tempdword++;
  152. number_of_slots--;
  153. }
  154. return 0;
  155. }
  156. /* nice debugging output */
  157. static int pci_print_IRQ_route (void)
  158. {
  159. struct irq_routing_table *routing_table;
  160. int len;
  161. int loop;
  162. u8 tbus, tdevice, tslot;
  163. routing_table = pcibios_get_irq_routing_table();
  164. if (routing_table == NULL) {
  165. err("No BIOS Routing Table??? Not goodn");
  166. return -ENOMEM;
  167. }
  168. len = (routing_table->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
  169. // Make sure I got at least one entry
  170. if (len == 0) {
  171. kfree(routing_table);
  172. return -1;
  173. }
  174. dbg("bus dev func slotn");
  175. for (loop = 0; loop < len; ++loop) {
  176. tbus = routing_table->slots[loop].bus;
  177. tdevice = routing_table->slots[loop].devfn;
  178. tslot = routing_table->slots[loop].slot;
  179. dbg("%d %d %d %dn", tbus, tdevice >> 3, tdevice & 0x7, tslot);
  180. }
  181. kfree(routing_table);
  182. return 0;
  183. }
  184. /*
  185.  * get_subsequent_smbios_entry
  186.  *
  187.  * Gets the first entry if previous == NULL
  188.  * Otherwise, returns the next entry
  189.  * Uses global SMBIOS Table pointer
  190.  *
  191.  * @curr: %NULL or pointer to previously returned structure
  192.  *
  193.  * returns a pointer to an SMBIOS structure or NULL if none found
  194.  */
  195. static void * get_subsequent_smbios_entry(void *smbios_start, void *smbios_table, void *curr)
  196. {
  197. u8 bail = 0;
  198. u8 previous_byte = 1;
  199. void *p_temp;
  200. void *p_max;
  201. if (!smbios_table || !curr)
  202. return(NULL);
  203. // set p_max to the end of the table
  204. p_max = smbios_start + readw(smbios_table + ST_LENGTH);
  205. p_temp = curr;
  206. p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
  207. while ((p_temp < p_max) && !bail) {
  208. // Look for the double NULL terminator
  209. // The first condition is the previous byte and the second is the curr
  210. if (!previous_byte && !(readb(p_temp))) {
  211. bail = 1;
  212. }
  213. previous_byte = readb(p_temp);
  214. p_temp++;
  215. }
  216. if (p_temp < p_max) {
  217. return p_temp;
  218. } else {
  219. return NULL;
  220. }
  221. }
  222. /**
  223.  * get_SMBIOS_entry
  224.  *
  225.  * @type:SMBIOS structure type to be returned
  226.  * @previous: %NULL or pointer to previously returned structure
  227.  *
  228.  * Gets the first entry of the specified type if previous == NULL
  229.  * Otherwise, returns the next entry of the given type.
  230.  * Uses global SMBIOS Table pointer
  231.  * Uses get_subsequent_smbios_entry
  232.  *
  233.  * returns a pointer to an SMBIOS structure or %NULL if none found
  234.  */
  235. static void *get_SMBIOS_entry (void *smbios_start, void *smbios_table, u8 type, void * previous)
  236. {
  237. if (!smbios_table)
  238. return NULL;
  239. if (!previous) {   
  240. previous = smbios_start;
  241. } else {
  242. previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
  243. }
  244. while (previous) {
  245.         if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
  246. previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
  247. } else {
  248. break;
  249. }
  250. }
  251. return previous;
  252. }
  253. static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *smbios_table)
  254. {
  255. struct slot *new_slot;
  256. u8 number_of_slots;
  257. u8 slot_device;
  258. u8 slot_number;
  259. u8 ctrl_slot;
  260. u32 tempdword;
  261. void *slot_entry= NULL;
  262. int result;
  263. dbg(__FUNCTION__"n");
  264. tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
  265. number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
  266. slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
  267. slot_number = ctrl->first_slot;
  268. while (number_of_slots) {
  269. new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
  270. if (!new_slot)
  271. return -ENOMEM;
  272. memset(new_slot, 0, sizeof(struct slot));
  273. new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
  274. if (!new_slot->hotplug_slot) {
  275. kfree (new_slot);
  276. return -ENOMEM;
  277. }
  278. memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
  279. new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
  280. if (!new_slot->hotplug_slot->info) {
  281. kfree (new_slot->hotplug_slot);
  282. kfree (new_slot);
  283. return -ENOMEM;
  284. }
  285. memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
  286. new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
  287. if (!new_slot->hotplug_slot->name) {
  288. kfree (new_slot->hotplug_slot->info);
  289. kfree (new_slot->hotplug_slot);
  290. kfree (new_slot);
  291. return -ENOMEM;
  292. }
  293. new_slot->magic = SLOT_MAGIC;
  294. new_slot->ctrl = ctrl;
  295. new_slot->bus = ctrl->bus;
  296. new_slot->device = slot_device;
  297. new_slot->number = slot_number;
  298. dbg("slot->number = %dn",new_slot->number);
  299. slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
  300. while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
  301. slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
  302. }
  303. new_slot->p_sm_slot = slot_entry;
  304. init_timer(&new_slot->task_event);
  305. new_slot->task_event.expires = jiffies + 5 * HZ;
  306. new_slot->task_event.function = cpqhp_pushbutton_thread;
  307. //FIXME: these capabilities aren't used but if they are
  308. //       they need to be correctly implemented
  309. new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
  310. new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
  311. if (is_slot64bit(new_slot))
  312. new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
  313. if (is_slot66mhz(new_slot))
  314. new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
  315. if (ctrl->speed == 1)
  316. new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
  317. ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
  318. // Check presence
  319. new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
  320. // Check the switch state
  321. new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
  322. // Check the slot enable
  323. new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
  324. /* register this slot with the hotplug pci core */
  325. new_slot->hotplug_slot->private = new_slot;
  326. make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
  327. new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
  328. new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
  329. new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
  330. new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
  331. new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
  332. dbg ("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %dn", 
  333.      new_slot->bus, new_slot->device, new_slot->number, ctrl->slot_device_offset, slot_number);
  334. result = pci_hp_register (new_slot->hotplug_slot);
  335. if (result) {
  336. err ("pci_hp_register failed with error %dn", result);
  337. kfree (new_slot->hotplug_slot->info);
  338. kfree (new_slot->hotplug_slot->name);
  339. kfree (new_slot->hotplug_slot);
  340. kfree (new_slot);
  341. return result;
  342. }
  343. new_slot->next = ctrl->slot;
  344. ctrl->slot = new_slot;
  345. number_of_slots--;
  346. slot_device++;
  347. slot_number++;
  348. }
  349. return(0);
  350. }
  351. static int ctrl_slot_cleanup (struct controller * ctrl)
  352. {
  353. struct slot *old_slot, *next_slot;
  354. old_slot = ctrl->slot;
  355. ctrl->slot = NULL;
  356. while (old_slot) {
  357. next_slot = old_slot->next;
  358. pci_hp_deregister (old_slot->hotplug_slot);
  359. kfree(old_slot->hotplug_slot->info);
  360. kfree(old_slot->hotplug_slot->name);
  361. kfree(old_slot->hotplug_slot);
  362. kfree(old_slot);
  363. old_slot = next_slot;
  364. }
  365. //Free IRQ associated with hot plug device
  366. free_irq(ctrl->interrupt, ctrl);
  367. //Unmap the memory
  368. iounmap(ctrl->hpc_reg);
  369. //Finally reclaim PCI mem
  370. release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
  371.    pci_resource_len(ctrl->pci_dev, 0));
  372. return(0);
  373. }
  374. //============================================================================
  375. // function: get_slot_mapping
  376. //
  377. // Description: Attempts to determine a logical slot mapping for a PCI
  378. // device.  Won't work for more than one PCI-PCI bridge
  379. // in a slot.
  380. //
  381. // Input: u8 bus_num - bus number of PCI device
  382. // u8 dev_num - device number of PCI device
  383. // u8 *slot - Pointer to u8 where slot number will
  384. // be returned
  385. //
  386. // Output: SUCCESS or FAILURE
  387. //=============================================================================
  388. static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *slot)
  389. {
  390. struct irq_routing_table *PCIIRQRoutingInfoLength;
  391. u32 work;
  392. long len;
  393. long loop;
  394. u8 tbus, tdevice, tslot, bridgeSlot;
  395. dbg(__FUNCTION__" %p, %d, %d, %pn", ops, bus_num, dev_num, slot);
  396. bridgeSlot = 0xFF;
  397. PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
  398. len = (PCIIRQRoutingInfoLength->size -
  399.        sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
  400. // Make sure I got at least one entry
  401. if (len == 0) {
  402. if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
  403. return -1;
  404. }
  405. for (loop = 0; loop < len; ++loop) {
  406. tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
  407. tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
  408. tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
  409. if ((tbus == bus_num) && (tdevice == dev_num)) {
  410. *slot = tslot;
  411. if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
  412. return 0;
  413. } else {
  414. // Didn't get a match on the target PCI device. Check if the
  415. // current IRQ table entry is a PCI-to-PCI bridge device.  If so,
  416. // and it's secondary bus matches the bus number for the target 
  417. // device, I need to save the bridge's slot number.  If I can't 
  418. // find an entry for the target device, I will have to assume it's 
  419. // on the other side of the bridge, and assign it the bridge's slot.
  420. pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_REVISION_ID, &work);
  421. if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
  422. pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_PRIMARY_BUS, &work);
  423. // See if bridge's secondary bus matches target bus.
  424. if (((work >> 8) & 0x000000FF) == (long) bus_num) {
  425. bridgeSlot = tslot;
  426. }
  427. }
  428. }
  429. }
  430. // If we got here, we didn't find an entry in the IRQ mapping table 
  431. // for the target PCI device.  If we did determine that the target 
  432. // device is on the other side of a PCI-to-PCI bridge, return the 
  433. // slot number for the bridge.
  434. if (bridgeSlot != 0xFF) {
  435. *slot = bridgeSlot;
  436. if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
  437. return 0;
  438. }
  439. if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
  440. // Couldn't find an entry in the routing table for this PCI device
  441. return -1;
  442. }
  443. /**
  444.  * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
  445.  *
  446.  */
  447. static int cpqhp_set_attention_status (struct controller *ctrl, struct pci_func *func, u32 status)
  448. {
  449. u8 hp_slot;
  450. hp_slot = func->device - ctrl->slot_device_offset;
  451. if (func == NULL)
  452. return(1);
  453. // Wait for exclusive access to hardware
  454. down(&ctrl->crit_sect);
  455. if (status == 1) {
  456. amber_LED_on (ctrl, hp_slot);
  457. } else if (status == 0) {
  458. amber_LED_off (ctrl, hp_slot);
  459. } else {
  460. // Done with exclusive hardware access
  461. up(&ctrl->crit_sect);
  462. return(1);
  463. }
  464. set_SOGO(ctrl);
  465. // Wait for SOBS to be unset
  466. wait_for_ctrl_irq (ctrl);
  467. // Done with exclusive hardware access
  468. up(&ctrl->crit_sect);
  469. return(0);
  470. }
  471. /**
  472.  * set_attention_status - Turns the Amber LED for a slot on or off
  473.  *
  474.  */
  475. static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
  476. {
  477. struct pci_func *slot_func;
  478. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  479. struct controller *ctrl;
  480. u8 bus;
  481. u8 devfn;
  482. u8 device;
  483. u8 function;
  484. if (slot == NULL)
  485. return -ENODEV;
  486. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  487. ctrl = slot->ctrl;
  488. if (ctrl == NULL)
  489. return -ENODEV;
  490. if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
  491. return -ENODEV;
  492. device = devfn >> 3;
  493. function = devfn & 0x7;
  494. dbg("bus, dev, fn = %d, %d, %dn", bus, device, function);
  495. slot_func = cpqhp_slot_find(bus, device, function);
  496. if (!slot_func) {
  497. return -ENODEV;
  498. }
  499. return cpqhp_set_attention_status(ctrl, slot_func, status);
  500. }
  501. static int process_SI (struct hotplug_slot *hotplug_slot)
  502. {
  503. struct pci_func *slot_func;
  504. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  505. struct controller *ctrl;
  506. u8 bus;
  507. u8 devfn;
  508. u8 device;
  509. u8 function;
  510. if (slot == NULL)
  511. return -ENODEV;
  512. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  513. ctrl = slot->ctrl;
  514. if (ctrl == NULL)
  515. return -ENODEV;
  516. if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
  517. return -ENODEV;
  518. device = devfn >> 3;
  519. function = devfn & 0x7;
  520. dbg("bus, dev, fn = %d, %d, %dn", bus, device, function);
  521. slot_func = cpqhp_slot_find(bus, device, function);
  522. if (!slot_func) {
  523. return -ENODEV;
  524. }
  525. slot_func->bus = bus;
  526. slot_func->device = device;
  527. slot_func->function = function;
  528. slot_func->configured = 0;
  529. dbg("board_added(%p, %p)n", slot_func, ctrl);
  530. return cpqhp_process_SI(ctrl, slot_func);
  531. }
  532. static int process_SS (struct hotplug_slot *hotplug_slot)
  533. {
  534. struct pci_func *slot_func;
  535. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  536. struct controller *ctrl;
  537. u8 bus;
  538. u8 devfn;
  539. u8 device;
  540. u8 function;
  541. if (slot == NULL)
  542. return -ENODEV;
  543. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  544. ctrl = slot->ctrl;
  545. if (ctrl == NULL)
  546. return -ENODEV;
  547. if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
  548. return -ENODEV;
  549. device = devfn >> 3;
  550. function = devfn & 0x7;
  551. dbg("bus, dev, fn = %d, %d, %dn", bus, device, function);
  552. slot_func = cpqhp_slot_find(bus, device, function);
  553. if (!slot_func) {
  554. return -ENODEV;
  555. }
  556. dbg("In power_down_board, slot_func = %p, ctrl = %pn", slot_func, ctrl);
  557. return cpqhp_process_SS(ctrl, slot_func);
  558. }
  559. static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
  560. {
  561. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  562. struct controller *ctrl;
  563. dbg(__FUNCTION__"n");
  564. if (slot == NULL)
  565. return -ENODEV;
  566. ctrl = slot->ctrl;
  567. if (ctrl == NULL)
  568. return -ENODEV;
  569. return cpqhp_hardware_test (ctrl, value);
  570. }
  571. static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
  572. {
  573. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  574. struct controller *ctrl;
  575. if (slot == NULL)
  576. return -ENODEV;
  577. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  578. ctrl = slot->ctrl;
  579. if (ctrl == NULL)
  580. return -ENODEV;
  581. *value = get_slot_enabled(ctrl, slot);
  582. return 0;
  583. }
  584. static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
  585. {
  586. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  587. struct controller *ctrl;
  588. if (slot == NULL)
  589. return -ENODEV;
  590. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  591. ctrl = slot->ctrl;
  592. if (ctrl == NULL)
  593. return -ENODEV;
  594. *value = cpq_get_attention_status(ctrl, slot);
  595. return 0;
  596. }
  597. static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
  598. {
  599. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  600. struct controller *ctrl;
  601. if (slot == NULL)
  602. return -ENODEV;
  603. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  604. ctrl = slot->ctrl;
  605. if (ctrl == NULL)
  606. return -ENODEV;
  607. *value = cpq_get_latch_status (ctrl, slot);
  608. return 0;
  609. }
  610. static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
  611. {
  612. struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
  613. struct controller *ctrl;
  614. if (slot == NULL)
  615. return -ENODEV;
  616. dbg(__FUNCTION__" - physical_slot = %sn", hotplug_slot->name);
  617. ctrl = slot->ctrl;
  618. if (ctrl == NULL)
  619. return -ENODEV;
  620. *value = get_presence_status (ctrl, slot);
  621. return 0;
  622. }
  623. static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  624. {
  625. u8 num_of_slots = 0;
  626. u8 hp_slot = 0;
  627. u8 device;
  628. u8 rev;
  629. u16 temp_word;
  630. u16 vendor_id;
  631. u16 subsystem_vid;
  632. u16 subsystem_deviceid;
  633. u32 rc;
  634. struct controller *ctrl;
  635. struct pci_func *func;
  636. // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
  637. rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
  638. if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
  639. err(msg_HPC_non_compaq_or_intel);
  640. return -ENODEV;
  641. }
  642. dbg("Vendor ID: %xn", vendor_id);
  643. rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
  644. dbg("revision: %dn", rev);
  645. if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
  646. err(msg_HPC_rev_error);
  647. return -ENODEV;
  648. }
  649. /* Check for the proper subsytem ID's
  650.  * Intel uses a different SSID programming model than Compaq.  
  651.  * For Intel, each SSID bit identifies a PHP capability.
  652.  * Also Intel HPC's may have RID=0.
  653.  */
  654. if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
  655. // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
  656. rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
  657. if (rc) {
  658. err(__FUNCTION__" : pci_read_config_word failedn");
  659. return rc;
  660. }
  661. dbg("Subsystem Vendor ID: %xn", subsystem_vid);
  662. if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
  663. err(msg_HPC_non_compaq_or_intel);
  664. return -ENODEV;
  665. }
  666. ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
  667. if (!ctrl) {
  668. err(__FUNCTION__" : out of memoryn");
  669. return -ENOMEM;
  670. }
  671. memset(ctrl, 0, sizeof(struct controller));
  672. rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
  673. if (rc) {
  674. err(__FUNCTION__" : pci_read_config_word failedn");
  675. goto err_free_ctrl;
  676. }
  677. info("Hot Plug Subsystem Device ID: %xn", subsystem_deviceid);
  678. /* Set Vendor ID, so it can be accessed later from other functions */
  679. ctrl->vendor_id = vendor_id;
  680. switch (subsystem_vid) {
  681. case PCI_VENDOR_ID_COMPAQ:
  682. switch (subsystem_deviceid) {
  683. case PCI_SUB_HPC_ID:
  684. /* Original 6500/7000 implementation */
  685. ctrl->slot_switch_type = 1; // Switch is present
  686. ctrl->speed_capability = CTRL_SPEED_33MHz;
  687. ctrl->push_button = 0; // No pushbutton
  688. ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported
  689. ctrl->defeature_PHP = 1; // PHP is supported
  690. ctrl->pcix_support = 0; // PCI-X not supported
  691. ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported
  692. break;
  693. case PCI_SUB_HPC_ID2:
  694. /* First Pushbutton implementation */
  695. ctrl->push_flag = 1;
  696. ctrl->slot_switch_type = 1; // Switch is present
  697. ctrl->speed_capability = CTRL_SPEED_33MHz;
  698. ctrl->push_button = 1; // Pushbutton is present
  699. ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported
  700. ctrl->defeature_PHP = 1; // PHP is supported
  701. ctrl->pcix_support = 0; // PCI-X not supported
  702. ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported
  703. break;
  704. case PCI_SUB_HPC_ID_INTC:
  705. /* Third party (6500/7000) */
  706. ctrl->slot_switch_type = 1; // Switch is present
  707. ctrl->speed_capability = CTRL_SPEED_33MHz;
  708. ctrl->push_button = 0; // No pushbutton
  709. ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported
  710. ctrl->defeature_PHP = 1; // PHP is supported
  711. ctrl->pcix_support = 0; // PCI-X not supported
  712. ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported
  713. break;
  714. case PCI_SUB_HPC_ID3:
  715. /* First 66 Mhz implementation */
  716. ctrl->push_flag = 1;
  717. ctrl->slot_switch_type = 1; // Switch is present
  718. ctrl->speed_capability = CTRL_SPEED_66MHz;
  719. ctrl->push_button = 1; // Pushbutton is present
  720. ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported
  721. ctrl->defeature_PHP = 1; // PHP is supported
  722. ctrl->pcix_support = 0; // PCI-X not supported
  723. ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported
  724. break;
  725. default:
  726. // TODO: Add SSIDs for CPQ systems that support PCI-X
  727. err(msg_HPC_not_supported);
  728. rc = -ENODEV;
  729. goto err_free_ctrl;
  730. }
  731. break;
  732. case PCI_VENDOR_ID_INTEL:
  733. /* Check for speed capability (0=33, 1=66) */
  734. if (subsystem_deviceid & 0x0001) {
  735. ctrl->speed_capability = CTRL_SPEED_66MHz;
  736. } else {
  737. ctrl->speed_capability = CTRL_SPEED_33MHz;
  738. }
  739. /* Check for push button */
  740. if (subsystem_deviceid & 0x0002) {
  741. /* no push button */
  742. ctrl->push_button = 0;
  743. } else {
  744. /* push button supported */
  745. ctrl->push_button = 1;
  746. }
  747. /* Check for slot switch type (0=mechanical, 1=not mechanical) */
  748. if (subsystem_deviceid & 0x0004) {
  749. /* no switch */
  750. ctrl->slot_switch_type = 0;
  751. } else {
  752. /* switch */
  753. ctrl->slot_switch_type = 1;
  754. }
  755. /* PHP Status (0=De-feature PHP, 1=Normal operation) */
  756. if (subsystem_deviceid & 0x0008) {
  757. ctrl->defeature_PHP = 1; // PHP supported
  758. } else {
  759. ctrl->defeature_PHP = 0; // PHP not supported
  760. }
  761. /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
  762. if (subsystem_deviceid & 0x0010) {
  763. ctrl->alternate_base_address = 1; // supported
  764. } else {
  765. ctrl->alternate_base_address = 0; // not supported
  766. }
  767. /* PCI Config Space Index (0=not supported, 1=supported) */
  768. if (subsystem_deviceid & 0x0020) {
  769. ctrl->pci_config_space = 1; // supported
  770. } else {
  771. ctrl->pci_config_space = 0; // not supported
  772. }
  773. /* PCI-X support */
  774. if (subsystem_deviceid & 0x0080) {
  775. /* PCI-X capable */
  776. ctrl->pcix_support = 1;
  777. /* Frequency of operation in PCI-X mode */
  778. if (subsystem_deviceid & 0x0040) {
  779. /* 133MHz PCI-X if bit 7 is 1 */
  780. ctrl->pcix_speed_capability = 1;
  781. } else {
  782. /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
  783. /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
  784. ctrl->pcix_speed_capability = 0;
  785. }
  786. } else {
  787. /* Conventional PCI */
  788. ctrl->pcix_support = 0;
  789. ctrl->pcix_speed_capability = 0;
  790. }
  791. break;
  792. default:
  793. err(msg_HPC_not_supported);
  794. rc = -ENODEV;
  795. goto err_free_ctrl;
  796. }
  797. } else {
  798. err(msg_HPC_not_supported);
  799. return -ENODEV;
  800. }
  801. // Tell the user that we found one.
  802. info("Initializing the PCI hot plug controller residing on PCI bus %dn", pdev->bus->number);
  803. dbg ("Hotplug controller capabilities:n");
  804. dbg ("    speed_capability       %sn", ctrl->speed_capability == CTRL_SPEED_33MHz ? "33MHz" : "66Mhz");
  805. dbg ("    slot_switch_type       %sn", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
  806. dbg ("    defeature_PHP          %sn", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
  807. dbg ("    alternate_base_address %sn", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
  808. dbg ("    pci_config_space       %sn", ctrl->pci_config_space == 0 ? "not supported" : "supported");
  809. dbg ("    pcix_speed_capability  %sn", ctrl->pcix_speed_capability == 0 ? "not supported" : "supported");
  810. dbg ("    pcix_support           %sn", ctrl->pcix_support == 0 ? "not supported" : "supported");
  811. ctrl->pci_dev = pdev;
  812. ctrl->pci_ops = pdev->bus->ops;
  813. ctrl->bus = pdev->bus->number;
  814. ctrl->device = PCI_SLOT(pdev->devfn);
  815. ctrl->function = PCI_FUNC(pdev->devfn);
  816. ctrl->rev = rev;
  817. dbg("bus device function rev: %d %d %d %dn", ctrl->bus, ctrl->device, ctrl->function, ctrl->rev);
  818. init_MUTEX(&ctrl->crit_sect);
  819. init_waitqueue_head(&ctrl->queue);
  820. /* initialize our threads if they haven't already been started up */
  821. rc = one_time_init();
  822. if (rc) {
  823. goto err_free_ctrl;
  824. }
  825. dbg("pdev = %pn", pdev);
  826. dbg("pci resource start %lxn", pci_resource_start(pdev, 0));
  827. dbg("pci resource len %lxn", pci_resource_len(pdev, 0));
  828. if (!request_mem_region(pci_resource_start(pdev, 0),
  829. pci_resource_len(pdev, 0), MY_NAME)) {
  830. err("cannot reserve MMIO regionn");
  831. rc = -ENOMEM;
  832. goto err_free_ctrl;
  833. }
  834. ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
  835. if (!ctrl->hpc_reg) {
  836. err("cannot remap MMIO region %lx @ %lxn", pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
  837. rc = -ENODEV;
  838. goto err_free_mem_region;
  839. }
  840. // Check for 66Mhz operation
  841. // TODO: Add PCI-X support
  842. ctrl->speed = get_controller_speed(ctrl);
  843. //**************************************************
  844. //
  845. //              Save configuration headers for this and
  846. //              subordinate PCI buses
  847. //
  848. //**************************************************
  849. // find the physical slot number of the first hot plug slot
  850. // Get slot won't work for devices behind bridges, but
  851. // in this case it will always be called for the "base"
  852. // bus/dev/func of a slot.
  853. // CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table)
  854. rc = get_slot_mapping(ctrl->pci_ops, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot));
  855. dbg("get_slot_mapping: first_slot = %d, returned = %dn", ctrl->first_slot, rc);
  856. if (rc) {
  857. err(msg_initialization_err, rc);
  858. goto err_iounmap;
  859. }
  860. // Store PCI Config Space for all devices on this bus
  861. rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
  862. if (rc) {
  863. err(__FUNCTION__": unable to save PCI configuration data, error %dn", rc);
  864. goto err_iounmap;
  865. }
  866. /*
  867.  * Get IO, memory, and IRQ resources for new devices
  868.  */
  869. rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
  870. ctrl->add_support = !rc;
  871. if (rc) {
  872. dbg("cpqhp_find_available_resources = 0x%xn", rc);
  873. err("unable to locate PCI configuration resources for hot plug add.n");
  874. goto err_iounmap;
  875. }
  876. /*
  877.  * Finish setting up the hot plug ctrl device
  878.  */
  879. ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
  880. dbg("NumSlots %d n", ctrl->slot_device_offset);
  881. ctrl->next_event = 0;
  882. /* Setup the slot information structures */
  883. rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
  884. if (rc) {
  885. err(msg_initialization_err, 6);
  886. err(__FUNCTION__": unable to save PCI configuration data, error %dn", rc);
  887. goto err_iounmap;
  888. }
  889. /* Mask all general input interrupts */
  890. writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
  891. /* set up the interrupt */
  892. ctrl->interrupt = pdev->irq;
  893. dbg("HPC interrupt = %d n", ctrl->interrupt);
  894. if (request_irq(ctrl->interrupt,
  895. (void (*)(int, void *, struct pt_regs *)) &cpqhp_ctrl_intr,
  896. SA_SHIRQ, MY_NAME, ctrl)) {
  897. err("Can't get irq %d for the hotplug pci controllern", ctrl->interrupt);
  898. rc = -ENODEV;
  899. goto err_iounmap;
  900. }
  901. /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
  902. temp_word = readw(ctrl->hpc_reg + MISC);
  903. temp_word |= 0x4006;
  904. writew(temp_word, ctrl->hpc_reg + MISC);
  905. // Changed 05/05/97 to clear all interrupts at start
  906. writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
  907. ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
  908. writel(0x0L, ctrl->hpc_reg + INT_MASK);
  909. if (!cpqhp_ctrl_list) {
  910. cpqhp_ctrl_list = ctrl;
  911. ctrl->next = NULL;
  912. } else {
  913. ctrl->next = cpqhp_ctrl_list;
  914. cpqhp_ctrl_list = ctrl;
  915. }
  916. // turn off empty slots here unless command line option "ON" set
  917. // Wait for exclusive access to hardware
  918. down(&ctrl->crit_sect);
  919. num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
  920. // find first device number for the ctrl
  921. device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
  922. while (num_of_slots) {
  923. dbg("num_of_slots: %dn", num_of_slots);
  924. func = cpqhp_slot_find(ctrl->bus, device, 0);
  925. if (!func)
  926. break;
  927. hp_slot = func->device - ctrl->slot_device_offset;
  928. dbg("hp_slot: %dn", hp_slot);
  929. // We have to save the presence info for these slots
  930. temp_word = ctrl->ctrl_int_comp >> 16;
  931. func->presence_save = (temp_word >> hp_slot) & 0x01;
  932. func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
  933. if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
  934. func->switch_save = 0;
  935. } else {
  936. func->switch_save = 0x10;
  937. }
  938. if (!power_mode) {
  939. if (!func->is_a_board) {
  940. green_LED_off (ctrl, hp_slot);
  941. slot_disable (ctrl, hp_slot);
  942. }
  943. }
  944. device++;
  945. num_of_slots--;
  946. }
  947. if (!power_mode) {
  948. set_SOGO(ctrl);
  949. // Wait for SOBS to be unset
  950. wait_for_ctrl_irq (ctrl);
  951. }
  952. rc = init_SERR(ctrl);
  953. if (rc) {
  954. err("init_SERR failedn");
  955. up(&ctrl->crit_sect);
  956. goto err_free_irq;
  957. }
  958. // Done with exclusive hardware access
  959. up(&ctrl->crit_sect);
  960. rc = cpqhp_proc_create_ctrl (ctrl);
  961. if (rc) {
  962. err("cpqhp_proc_create_ctrl failedn");
  963. goto err_free_irq;
  964. }
  965. return 0;
  966. err_free_irq:
  967. free_irq(ctrl->interrupt, ctrl);
  968. err_iounmap:
  969. iounmap(ctrl->hpc_reg);
  970. err_free_mem_region:
  971. release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
  972. err_free_ctrl:
  973. kfree(ctrl);
  974. return rc;
  975. }
  976. static int one_time_init(void)
  977. {
  978. int loop;
  979. int retval = 0;
  980. static int initialized = 0;
  981. if (initialized)
  982. return 0;
  983. power_mode = 0;
  984. retval = pci_print_IRQ_route();
  985. if (retval)
  986. goto error;
  987. dbg("Initialize + Start the notification mechanism n");
  988. retval = cpqhp_event_start_thread();
  989. if (retval)
  990. goto error;
  991. dbg("Initialize slot listsn");
  992. for (loop = 0; loop < 256; loop++) {
  993. cpqhp_slot_list[loop] = NULL;
  994. }
  995. // FIXME: We also need to hook the NMI handler eventually.
  996. // this also needs to be worked with Christoph
  997. // register_NMI_handler();
  998. // Map rom address
  999. cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
  1000. if (!cpqhp_rom_start) {
  1001. err ("Could not ioremap memory region for ROMn");
  1002. retval = -EIO;;
  1003. goto error;
  1004. }
  1005. /* Now, map the int15 entry point if we are on compaq specific hardware */
  1006. compaq_nvram_init(cpqhp_rom_start);
  1007. /* Map smbios table entry point structure */
  1008. smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start, cpqhp_rom_start + ROM_PHY_LEN);
  1009. if (!smbios_table) {
  1010. err ("Could not find the SMBIOS pointer in memoryn");
  1011. retval = -EIO;;
  1012. goto error;
  1013. }
  1014. smbios_start = ioremap(readl(smbios_table + ST_ADDRESS), readw(smbios_table + ST_LENGTH));
  1015. if (!smbios_start) {
  1016. err ("Could not ioremap memory region taken from SMBIOS valuesn");
  1017. retval = -EIO;;
  1018. goto error;
  1019. }
  1020. retval = cpqhp_proc_init_ctrl();
  1021. if (retval)
  1022. goto error;
  1023. initialized = 1;
  1024. return retval;
  1025. error:
  1026. if (cpqhp_rom_start)
  1027. iounmap(cpqhp_rom_start);
  1028. if (smbios_start)
  1029. iounmap(smbios_start);
  1030. return retval;
  1031. }
  1032. static void unload_cpqphpd(void)
  1033. {
  1034. struct pci_func *next;
  1035. struct pci_func *TempSlot;
  1036. int loop;
  1037. u32 rc;
  1038. struct controller *ctrl;
  1039. struct controller *tctrl;
  1040. struct pci_resource *res;
  1041. struct pci_resource *tres;
  1042. rc = compaq_nvram_store(cpqhp_rom_start);
  1043. ctrl = cpqhp_ctrl_list;
  1044. while (ctrl) {
  1045. cpqhp_proc_remove_ctrl (ctrl);
  1046. if (ctrl->hpc_reg) {
  1047. u16 misc;
  1048. rc = read_slot_enable (ctrl);
  1049. writeb(0, ctrl->hpc_reg + SLOT_SERR);
  1050. writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
  1051. misc = readw(ctrl->hpc_reg + MISC);
  1052. misc &= 0xFFFD;
  1053. writew(misc, ctrl->hpc_reg + MISC);
  1054. }
  1055. ctrl_slot_cleanup(ctrl);
  1056. res = ctrl->io_head;
  1057. while (res) {
  1058. tres = res;
  1059. res = res->next;
  1060. kfree(tres);
  1061. }
  1062. res = ctrl->mem_head;
  1063. while (res) {
  1064. tres = res;
  1065. res = res->next;
  1066. kfree(tres);
  1067. }
  1068. res = ctrl->p_mem_head;
  1069. while (res) {
  1070. tres = res;
  1071. res = res->next;
  1072. kfree(tres);
  1073. }
  1074. res = ctrl->bus_head;
  1075. while (res) {
  1076. tres = res;
  1077. res = res->next;
  1078. kfree(tres);
  1079. }
  1080. tctrl = ctrl;
  1081. ctrl = ctrl->next;
  1082. kfree(tctrl);
  1083. }
  1084. for (loop = 0; loop < 256; loop++) {
  1085. next = cpqhp_slot_list[loop];
  1086. while (next != NULL) {
  1087. res = next->io_head;
  1088. while (res) {
  1089. tres = res;
  1090. res = res->next;
  1091. kfree(tres);
  1092. }
  1093. res = next->mem_head;
  1094. while (res) {
  1095. tres = res;
  1096. res = res->next;
  1097. kfree(tres);
  1098. }
  1099. res = next->p_mem_head;
  1100. while (res) {
  1101. tres = res;
  1102. res = res->next;
  1103. kfree(tres);
  1104. }
  1105. res = next->bus_head;
  1106. while (res) {
  1107. tres = res;
  1108. res = res->next;
  1109. kfree(tres);
  1110. }
  1111. TempSlot = next;
  1112. next = next->next;
  1113. kfree(TempSlot);
  1114. }
  1115. }
  1116. remove_proc_entry("hpc", 0);
  1117. // Stop the notification mechanism
  1118. cpqhp_event_stop_thread();
  1119. //unmap the rom address
  1120. if (cpqhp_rom_start)
  1121. iounmap(cpqhp_rom_start);
  1122. if (smbios_start)
  1123. iounmap(smbios_start);
  1124. }
  1125. static struct pci_device_id hpcd_pci_tbl[] __devinitdata = {
  1126. {
  1127. /* handle any PCI Hotplug controller */
  1128. class:          ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
  1129. class_mask:     ~0,
  1130. /* no matter who makes it */
  1131. vendor:         PCI_ANY_ID,
  1132. device:         PCI_ANY_ID,
  1133. subvendor:      PCI_ANY_ID,
  1134. subdevice:      PCI_ANY_ID,
  1135. }, { /* end: all zeroes */ }
  1136. };
  1137. MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
  1138. static struct pci_driver cpqhpc_driver = {
  1139. name: "pci_hotplug",
  1140. id_table: hpcd_pci_tbl,
  1141. probe: cpqhpc_probe,
  1142. /* remove: cpqhpc_remove_one, */
  1143. };
  1144. static int __init cpqhpc_init(void)
  1145. {
  1146. int result;
  1147. cpqhp_debug = debug;
  1148. result = pci_module_init(&cpqhpc_driver);
  1149. dbg("pci_module_init = %dn", result);
  1150. if (result)
  1151. return result;
  1152. info (DRIVER_DESC " version: " DRIVER_VERSION "n");
  1153. return 0;
  1154. }
  1155. static void __exit cpqhpc_cleanup(void)
  1156. {
  1157. dbg("cleaning up proc entriesn");
  1158. cpqhp_proc_destroy_ctrl();
  1159. dbg("unload_cpqphpd()n");
  1160. unload_cpqphpd();
  1161. dbg("pci_unregister_drivern");
  1162. pci_unregister_driver(&cpqhpc_driver);
  1163. }
  1164. module_init(cpqhpc_init);
  1165. module_exit(cpqhpc_cleanup);