vserver 2.0 rc7
[linux-2.6.git] / drivers / pci / hotplug / cpqphp_core.c
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  * Jan 12, 2003 -       Added 66/100/133MHz PCI-X support,
28  *                      Torben Mathiasen <torben.mathiasen@hp.com>
29  *
30  */
31
32 #include <linux/config.h>
33 #include <linux/module.h>
34 #include <linux/moduleparam.h>
35 #include <linux/kernel.h>
36 #include <linux/types.h>
37 #include <linux/proc_fs.h>
38 #include <linux/slab.h>
39 #include <linux/workqueue.h>
40 #include <linux/pci.h>
41 #include <linux/init.h>
42 #include <linux/interrupt.h>
43
44 #include <asm/uaccess.h>
45
46 #include "cpqphp.h"
47 #include "cpqphp_nvram.h"
48 #include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */
49
50
51 /* Global variables */
52 int cpqhp_debug;
53 int cpqhp_legacy_mode;
54 struct controller *cpqhp_ctrl_list;     /* = NULL */
55 struct pci_func *cpqhp_slot_list[256];
56
57 /* local variables */
58 static void __iomem *smbios_table;
59 static void __iomem *smbios_start;
60 static void __iomem *cpqhp_rom_start;
61 static int power_mode;
62 static int debug;
63
64 #define DRIVER_VERSION  "0.9.8"
65 #define DRIVER_AUTHOR   "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
66 #define DRIVER_DESC     "Compaq Hot Plug PCI Controller Driver"
67
68 MODULE_AUTHOR(DRIVER_AUTHOR);
69 MODULE_DESCRIPTION(DRIVER_DESC);
70 MODULE_LICENSE("GPL");
71
72 module_param(power_mode, bool, 0644);
73 MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
74
75 module_param(debug, bool, 0644);
76 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
77
78 #define CPQHPC_MODULE_MINOR 208
79
80 static int one_time_init        (void);
81 static int set_attention_status (struct hotplug_slot *slot, u8 value);
82 static int process_SI           (struct hotplug_slot *slot);
83 static int process_SS           (struct hotplug_slot *slot);
84 static int hardware_test        (struct hotplug_slot *slot, u32 value);
85 static int get_power_status     (struct hotplug_slot *slot, u8 *value);
86 static int get_attention_status (struct hotplug_slot *slot, u8 *value);
87 static int get_latch_status     (struct hotplug_slot *slot, u8 *value);
88 static int get_adapter_status   (struct hotplug_slot *slot, u8 *value);
89 static int get_max_bus_speed    (struct hotplug_slot *slot, enum pci_bus_speed *value);
90 static int get_cur_bus_speed    (struct hotplug_slot *slot, enum pci_bus_speed *value);
91
92 static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
93         .owner =                THIS_MODULE,
94         .set_attention_status = set_attention_status,
95         .enable_slot =          process_SI,
96         .disable_slot =         process_SS,
97         .hardware_test =        hardware_test,
98         .get_power_status =     get_power_status,
99         .get_attention_status = get_attention_status,
100         .get_latch_status =     get_latch_status,
101         .get_adapter_status =   get_adapter_status,
102         .get_max_bus_speed =    get_max_bus_speed,
103         .get_cur_bus_speed =    get_cur_bus_speed,
104 };
105
106
107 static inline int is_slot64bit(struct slot *slot)
108 {
109         return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
110 }
111
112 static inline int is_slot66mhz(struct slot *slot)
113 {
114         return (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E) ? 1 : 0;
115 }
116
117 /**
118  * detect_SMBIOS_pointer - find the System Management BIOS Table in mem region.
119  *
120  * @begin: begin pointer for region to be scanned.
121  * @end: end pointer for region to be scanned.
122  *
123  * Returns pointer to the head of the SMBIOS tables (or NULL)
124  *
125  */
126 static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
127 {
128         void __iomem *fp;
129         void __iomem *endp;
130         u8 temp1, temp2, temp3, temp4;
131         int status = 0;
132
133         endp = (end - sizeof(u32) + 1);
134
135         for (fp = begin; fp <= endp; fp += 16) {
136                 temp1 = readb(fp);
137                 temp2 = readb(fp+1);
138                 temp3 = readb(fp+2);
139                 temp4 = readb(fp+3);
140                 if (temp1 == '_' &&
141                     temp2 == 'S' &&
142                     temp3 == 'M' &&
143                     temp4 == '_') {
144                         status = 1;
145                         break;
146                 }
147         }
148         
149         if (!status)
150                 fp = NULL;
151
152         dbg("Discovered SMBIOS Entry point at %p\n", fp);
153
154         return fp;
155 }
156
157 /**
158  * init_SERR - Initializes the per slot SERR generation.
159  *
160  * For unexpected switch opens
161  *
162  */
163 static int init_SERR(struct controller * ctrl)
164 {
165         u32 tempdword;
166         u32 number_of_slots;
167         u8 physical_slot;
168
169         if (!ctrl)
170                 return 1;
171
172         tempdword = ctrl->first_slot;
173
174         number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
175         // Loop through slots
176         while (number_of_slots) {
177                 physical_slot = tempdword;
178                 writeb(0, ctrl->hpc_reg + SLOT_SERR);
179                 tempdword++;
180                 number_of_slots--;
181         }
182
183         return 0;
184 }
185
186
187 /* nice debugging output */
188 static int pci_print_IRQ_route (void)
189 {
190         struct irq_routing_table *routing_table;
191         int len;
192         int loop;
193
194         u8 tbus, tdevice, tslot;
195
196         routing_table = pcibios_get_irq_routing_table();
197         if (routing_table == NULL) {
198                 err("No BIOS Routing Table??? Not good\n");
199                 return -ENOMEM;
200         }
201
202         len = (routing_table->size - sizeof(struct irq_routing_table)) /
203                         sizeof(struct irq_info);
204         // Make sure I got at least one entry
205         if (len == 0) {
206                 kfree(routing_table);
207                 return -1;
208         }
209
210         dbg("bus dev func slot\n");
211
212         for (loop = 0; loop < len; ++loop) {
213                 tbus = routing_table->slots[loop].bus;
214                 tdevice = routing_table->slots[loop].devfn;
215                 tslot = routing_table->slots[loop].slot;
216                 dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
217
218         }
219         kfree(routing_table);
220         return 0;
221 }
222
223
224 /**
225  * get_subsequent_smbios_entry: get the next entry from bios table.
226  *
227  * Gets the first entry if previous == NULL
228  * Otherwise, returns the next entry
229  * Uses global SMBIOS Table pointer
230  *
231  * @curr: %NULL or pointer to previously returned structure
232  *
233  * returns a pointer to an SMBIOS structure or NULL if none found
234  */
235 static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
236                                                 void __iomem *smbios_table,
237                                                 void __iomem *curr)
238 {
239         u8 bail = 0;
240         u8 previous_byte = 1;
241         void __iomem *p_temp;
242         void __iomem *p_max;
243
244         if (!smbios_table || !curr)
245                 return(NULL);
246
247         // set p_max to the end of the table
248         p_max = smbios_start + readw(smbios_table + ST_LENGTH);
249
250         p_temp = curr;
251         p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
252
253         while ((p_temp < p_max) && !bail) {
254                 /* Look for the double NULL terminator
255                  * The first condition is the previous byte
256                  * and the second is the curr */
257                 if (!previous_byte && !(readb(p_temp))) {
258                         bail = 1;
259                 }
260
261                 previous_byte = readb(p_temp);
262                 p_temp++;
263         }
264
265         if (p_temp < p_max) {
266                 return p_temp;
267         } else {
268                 return NULL;
269         }
270 }
271
272
273 /**
274  * get_SMBIOS_entry
275  *
276  * @type:SMBIOS structure type to be returned
277  * @previous: %NULL or pointer to previously returned structure
278  *
279  * Gets the first entry of the specified type if previous == NULL
280  * Otherwise, returns the next entry of the given type.
281  * Uses global SMBIOS Table pointer
282  * Uses get_subsequent_smbios_entry
283  *
284  * returns a pointer to an SMBIOS structure or %NULL if none found
285  */
286 static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
287                                         void __iomem *smbios_table,
288                                         u8 type,
289                                         void __iomem *previous)
290 {
291         if (!smbios_table)
292                 return NULL;
293
294         if (!previous) {                  
295                 previous = smbios_start;
296         } else {
297                 previous = get_subsequent_smbios_entry(smbios_start,
298                                         smbios_table, previous);
299         }
300
301         while (previous) {
302                 if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
303                         previous = get_subsequent_smbios_entry(smbios_start,
304                                                 smbios_table, previous);
305                 } else {
306                         break;
307                 }
308         }
309
310         return previous;
311 }
312
313 static void release_slot(struct hotplug_slot *hotplug_slot)
314 {
315         struct slot *slot = hotplug_slot->private;
316
317         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
318
319         kfree(slot->hotplug_slot->info);
320         kfree(slot->hotplug_slot->name);
321         kfree(slot->hotplug_slot);
322         kfree(slot);
323 }
324
325 static int ctrl_slot_setup(struct controller *ctrl,
326                         void __iomem *smbios_start,
327                         void __iomem *smbios_table)
328 {
329         struct slot *new_slot;
330         u8 number_of_slots;
331         u8 slot_device;
332         u8 slot_number;
333         u8 ctrl_slot;
334         u32 tempdword;
335         void __iomem *slot_entry= NULL;
336         int result = -ENOMEM;
337
338         dbg("%s\n", __FUNCTION__);
339
340         tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
341
342         number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
343         slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
344         slot_number = ctrl->first_slot;
345
346         while (number_of_slots) {
347                 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
348                 if (!new_slot)
349                         goto error;
350
351                 memset(new_slot, 0, sizeof(struct slot));
352                 new_slot->hotplug_slot = kmalloc(sizeof(*(new_slot->hotplug_slot)),
353                                                 GFP_KERNEL);
354                 if (!new_slot->hotplug_slot)
355                         goto error_slot;
356                 memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
357
358                 new_slot->hotplug_slot->info =
359                                 kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
360                                                         GFP_KERNEL);
361                 if (!new_slot->hotplug_slot->info)
362                         goto error_hpslot;
363                 memset(new_slot->hotplug_slot->info, 0,
364                                 sizeof(struct hotplug_slot_info));
365                 new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
366                 if (!new_slot->hotplug_slot->name)
367                         goto error_info;
368
369                 new_slot->ctrl = ctrl;
370                 new_slot->bus = ctrl->bus;
371                 new_slot->device = slot_device;
372                 new_slot->number = slot_number;
373                 dbg("slot->number = %d\n",new_slot->number);
374
375                 slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
376                                         slot_entry);
377
378                 while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
379                         slot_entry = get_SMBIOS_entry(smbios_start,
380                                                 smbios_table, 9, slot_entry);
381                 }
382
383                 new_slot->p_sm_slot = slot_entry;
384
385                 init_timer(&new_slot->task_event);
386                 new_slot->task_event.expires = jiffies + 5 * HZ;
387                 new_slot->task_event.function = cpqhp_pushbutton_thread;
388
389                 //FIXME: these capabilities aren't used but if they are
390                 //       they need to be correctly implemented
391                 new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
392                 new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
393
394                 if (is_slot64bit(new_slot))
395                         new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
396                 if (is_slot66mhz(new_slot))
397                         new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
398                 if (ctrl->speed == PCI_SPEED_66MHz)
399                         new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
400
401                 ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
402
403                 // Check presence
404                 new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
405                 // Check the switch state
406                 new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
407                 // Check the slot enable
408                 new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
409
410                 /* register this slot with the hotplug pci core */
411                 new_slot->hotplug_slot->release = &release_slot;
412                 new_slot->hotplug_slot->private = new_slot;
413                 make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
414                 new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
415                 
416                 new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
417                 new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
418                 new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
419                 new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
420                 
421                 dbg ("registering bus %d, dev %d, number %d, "
422                                 "ctrl->slot_device_offset %d, slot %d\n",
423                                 new_slot->bus, new_slot->device,
424                                 new_slot->number, ctrl->slot_device_offset,
425                                 slot_number);
426                 result = pci_hp_register (new_slot->hotplug_slot);
427                 if (result) {
428                         err ("pci_hp_register failed with error %d\n", result);
429                         goto error_name;
430                 }
431                 
432                 new_slot->next = ctrl->slot;
433                 ctrl->slot = new_slot;
434
435                 number_of_slots--;
436                 slot_device++;
437                 slot_number++;
438         }
439
440         return 0;
441
442 error_name:
443         kfree(new_slot->hotplug_slot->name);
444 error_info:
445         kfree(new_slot->hotplug_slot->info);
446 error_hpslot:
447         kfree(new_slot->hotplug_slot);
448 error_slot:
449         kfree(new_slot);
450 error:
451         return result;
452 }
453
454 static int ctrl_slot_cleanup (struct controller * ctrl)
455 {
456         struct slot *old_slot, *next_slot;
457
458         old_slot = ctrl->slot;
459         ctrl->slot = NULL;
460
461         while (old_slot) {
462                 /* memory will be freed by the release_slot callback */
463                 next_slot = old_slot->next;
464                 pci_hp_deregister (old_slot->hotplug_slot);
465                 old_slot = next_slot;
466         }
467
468         //Free IRQ associated with hot plug device
469         free_irq(ctrl->interrupt, ctrl);
470         //Unmap the memory
471         iounmap(ctrl->hpc_reg);
472         //Finally reclaim PCI mem
473         release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
474                            pci_resource_len(ctrl->pci_dev, 0));
475
476         return(0);
477 }
478
479
480 //============================================================================
481 // function:    get_slot_mapping
482 //
483 // Description: Attempts to determine a logical slot mapping for a PCI
484 //              device.  Won't work for more than one PCI-PCI bridge
485 //              in a slot.
486 //
487 // Input:       u8 bus_num - bus number of PCI device
488 //              u8 dev_num - device number of PCI device
489 //              u8 *slot - Pointer to u8 where slot number will
490 //                      be returned
491 //
492 // Output:      SUCCESS or FAILURE
493 //=============================================================================
494 static int
495 get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
496 {
497         struct irq_routing_table *PCIIRQRoutingInfoLength;
498         u32 work;
499         long len;
500         long loop;
501
502         u8 tbus, tdevice, tslot, bridgeSlot;
503
504         dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
505
506         bridgeSlot = 0xFF;
507
508         PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
509         if (!PCIIRQRoutingInfoLength)
510                 return -1;
511
512         len = (PCIIRQRoutingInfoLength->size -
513                sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
514         // Make sure I got at least one entry
515         if (len == 0) {
516                 kfree(PCIIRQRoutingInfoLength);
517                 return -1;
518         }
519
520         for (loop = 0; loop < len; ++loop) {
521                 tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
522                 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
523                 tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
524
525                 if ((tbus == bus_num) && (tdevice == dev_num)) {
526                         *slot = tslot;
527                         kfree(PCIIRQRoutingInfoLength);
528                         return 0;
529                 } else {
530                         /* Did not get a match on the target PCI device. Check
531                          * if the current IRQ table entry is a PCI-to-PCI bridge
532                          * device.  If so, and it's secondary bus matches the
533                          * bus number for the target device, I need to save the
534                          * bridge's slot number.  If I can not find an entry for
535                          * the target device, I will have to assume it's on the
536                          * other side of the bridge, and assign it the bridge's
537                          * slot. */
538                         bus->number = tbus;
539                         pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
540                                                 PCI_REVISION_ID, &work);
541
542                         if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
543                                 pci_bus_read_config_dword(bus,
544                                                         PCI_DEVFN(tdevice, 0),
545                                                         PCI_PRIMARY_BUS, &work);
546                                 // See if bridge's secondary bus matches target bus.
547                                 if (((work >> 8) & 0x000000FF) == (long) bus_num) {
548                                         bridgeSlot = tslot;
549                                 }
550                         }
551                 }
552
553         }
554
555         // If we got here, we didn't find an entry in the IRQ mapping table 
556         // for the target PCI device.  If we did determine that the target 
557         // device is on the other side of a PCI-to-PCI bridge, return the 
558         // slot number for the bridge.
559         if (bridgeSlot != 0xFF) {
560                 *slot = bridgeSlot;
561                 kfree(PCIIRQRoutingInfoLength);
562                 return 0;
563         }
564         kfree(PCIIRQRoutingInfoLength);
565         // Couldn't find an entry in the routing table for this PCI device
566         return -1;
567 }
568
569
570 /**
571  * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
572  *
573  */
574 static int
575 cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
576                                 u32 status)
577 {
578         u8 hp_slot;
579
580         if (func == NULL)
581                 return(1);
582
583         hp_slot = func->device - ctrl->slot_device_offset;
584
585         // Wait for exclusive access to hardware
586         down(&ctrl->crit_sect);
587
588         if (status == 1) {
589                 amber_LED_on (ctrl, hp_slot);
590         } else if (status == 0) {
591                 amber_LED_off (ctrl, hp_slot);
592         } else {
593                 // Done with exclusive hardware access
594                 up(&ctrl->crit_sect);
595                 return(1);
596         }
597
598         set_SOGO(ctrl);
599
600         // Wait for SOBS to be unset
601         wait_for_ctrl_irq (ctrl);
602
603         // Done with exclusive hardware access
604         up(&ctrl->crit_sect);
605
606         return(0);
607 }
608
609
610 /**
611  * set_attention_status - Turns the Amber LED for a slot on or off
612  *
613  */
614 static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
615 {
616         struct pci_func *slot_func;
617         struct slot *slot = hotplug_slot->private;
618         struct controller *ctrl = slot->ctrl;
619         u8 bus;
620         u8 devfn;
621         u8 device;
622         u8 function;
623
624         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
625
626         if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
627                 return -ENODEV;
628
629         device = devfn >> 3;
630         function = devfn & 0x7;
631         dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
632
633         slot_func = cpqhp_slot_find(bus, device, function);
634         if (!slot_func)
635                 return -ENODEV;
636
637         return cpqhp_set_attention_status(ctrl, slot_func, status);
638 }
639
640
641 static int process_SI(struct hotplug_slot *hotplug_slot)
642 {
643         struct pci_func *slot_func;
644         struct slot *slot = hotplug_slot->private;
645         struct controller *ctrl = slot->ctrl;
646         u8 bus;
647         u8 devfn;
648         u8 device;
649         u8 function;
650
651         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
652
653         if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
654                 return -ENODEV;
655
656         device = devfn >> 3;
657         function = devfn & 0x7;
658         dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
659
660         slot_func = cpqhp_slot_find(bus, device, function);
661         if (!slot_func)
662                 return -ENODEV;
663
664         slot_func->bus = bus;
665         slot_func->device = device;
666         slot_func->function = function;
667         slot_func->configured = 0;
668         dbg("board_added(%p, %p)\n", slot_func, ctrl);
669         return cpqhp_process_SI(ctrl, slot_func);
670 }
671
672
673 static int process_SS(struct hotplug_slot *hotplug_slot)
674 {
675         struct pci_func *slot_func;
676         struct slot *slot = hotplug_slot->private;
677         struct controller *ctrl = slot->ctrl;
678         u8 bus;
679         u8 devfn;
680         u8 device;
681         u8 function;
682
683         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
684
685         if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
686                 return -ENODEV;
687
688         device = devfn >> 3;
689         function = devfn & 0x7;
690         dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
691
692         slot_func = cpqhp_slot_find(bus, device, function);
693         if (!slot_func)
694                 return -ENODEV;
695
696         dbg("In %s, slot_func = %p, ctrl = %p\n", __FUNCTION__, slot_func, ctrl);
697         return cpqhp_process_SS(ctrl, slot_func);
698 }
699
700
701 static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
702 {
703         struct slot *slot = hotplug_slot->private;
704         struct controller *ctrl = slot->ctrl;
705
706         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
707
708         return cpqhp_hardware_test(ctrl, value);        
709 }
710
711
712 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
713 {
714         struct slot *slot = hotplug_slot->private;
715         struct controller *ctrl = slot->ctrl;
716
717         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
718
719         *value = get_slot_enabled(ctrl, slot);
720         return 0;
721 }
722
723 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
724 {
725         struct slot *slot = hotplug_slot->private;
726         struct controller *ctrl = slot->ctrl;
727         
728         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
729
730         *value = cpq_get_attention_status(ctrl, slot);
731         return 0;
732 }
733
734 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
735 {
736         struct slot *slot = hotplug_slot->private;
737         struct controller *ctrl = slot->ctrl;
738
739         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
740
741         *value = cpq_get_latch_status(ctrl, slot);
742
743         return 0;
744 }
745
746 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
747 {
748         struct slot *slot = hotplug_slot->private;
749         struct controller *ctrl = slot->ctrl;
750
751         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
752
753         *value = get_presence_status(ctrl, slot);
754
755         return 0;
756 }
757
758 static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
759 {
760         struct slot *slot = hotplug_slot->private;
761         struct controller *ctrl = slot->ctrl;
762
763         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
764
765         *value = ctrl->speed_capability;
766
767         return 0;
768 }
769
770 static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
771 {
772         struct slot *slot = hotplug_slot->private;
773         struct controller *ctrl = slot->ctrl;
774
775         dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
776
777         *value = ctrl->speed;
778
779         return 0;
780 }
781
782 static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
783 {
784         u8 num_of_slots = 0;
785         u8 hp_slot = 0;
786         u8 device;
787         u8 rev;
788         u8 bus_cap;
789         u16 temp_word;
790         u16 vendor_id;
791         u16 subsystem_vid;
792         u16 subsystem_deviceid;
793         u32 rc;
794         struct controller *ctrl;
795         struct pci_func *func;
796
797         // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
798         rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
799         if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
800                 err(msg_HPC_non_compaq_or_intel);
801                 return -ENODEV;
802         }
803         dbg("Vendor ID: %x\n", vendor_id);
804
805         rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
806         dbg("revision: %d\n", rev);
807         if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
808                 err(msg_HPC_rev_error);
809                 return -ENODEV;
810         }
811
812         /* Check for the proper subsytem ID's
813          * Intel uses a different SSID programming model than Compaq.  
814          * For Intel, each SSID bit identifies a PHP capability.
815          * Also Intel HPC's may have RID=0.
816          */
817         if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
818                 // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
819                 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
820                 if (rc) {
821                         err("%s : pci_read_config_word failed\n", __FUNCTION__);
822                         return rc;
823                 }
824                 dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
825                 if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
826                         err(msg_HPC_non_compaq_or_intel);
827                         return -ENODEV;
828                 }
829
830                 ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
831                 if (!ctrl) {
832                         err("%s : out of memory\n", __FUNCTION__);
833                         return -ENOMEM;
834                 }
835                 memset(ctrl, 0, sizeof(struct controller));
836
837                 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
838                 if (rc) {
839                         err("%s : pci_read_config_word failed\n", __FUNCTION__);
840                         goto err_free_ctrl;
841                 }
842
843                 info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
844
845                 /* Set Vendor ID, so it can be accessed later from other functions */
846                 ctrl->vendor_id = vendor_id;
847
848                 switch (subsystem_vid) {
849                         case PCI_VENDOR_ID_COMPAQ:
850                                 if (rev >= 0x13) { /* CIOBX */
851                                         ctrl->push_flag = 1;
852                                         ctrl->slot_switch_type = 1;
853                                         ctrl->push_button = 1;
854                                         ctrl->pci_config_space = 1;
855                                         ctrl->defeature_PHP = 1;
856                                         ctrl->pcix_support = 1;
857                                         ctrl->pcix_speed_capability = 1;
858                                         pci_read_config_byte(pdev, 0x41, &bus_cap);
859                                         if (bus_cap & 0x80) {
860                                                 dbg("bus max supports 133MHz PCI-X\n");
861                                                 ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
862                                                 break;
863                                         }
864                                         if (bus_cap & 0x40) {
865                                                 dbg("bus max supports 100MHz PCI-X\n");
866                                                 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
867                                                 break;
868                                         }
869                                         if (bus_cap & 20) {
870                                                 dbg("bus max supports 66MHz PCI-X\n");
871                                                 ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
872                                                 break;
873                                         }
874                                         if (bus_cap & 10) {
875                                                 dbg("bus max supports 66MHz PCI\n");
876                                                 ctrl->speed_capability = PCI_SPEED_66MHz;
877                                                 break;
878                                         }
879
880                                         break;
881                                 }
882
883                                 switch (subsystem_deviceid) {
884                                         case PCI_SUB_HPC_ID:
885                                                 /* Original 6500/7000 implementation */
886                                                 ctrl->slot_switch_type = 1;
887                                                 ctrl->speed_capability = PCI_SPEED_33MHz;
888                                                 ctrl->push_button = 0;
889                                                 ctrl->pci_config_space = 1;
890                                                 ctrl->defeature_PHP = 1;
891                                                 ctrl->pcix_support = 0;
892                                                 ctrl->pcix_speed_capability = 0;
893                                                 break;
894                                         case PCI_SUB_HPC_ID2:
895                                                 /* First Pushbutton implementation */
896                                                 ctrl->push_flag = 1;
897                                                 ctrl->slot_switch_type = 1;
898                                                 ctrl->speed_capability = PCI_SPEED_33MHz;
899                                                 ctrl->push_button = 1;
900                                                 ctrl->pci_config_space = 1;
901                                                 ctrl->defeature_PHP = 1;
902                                                 ctrl->pcix_support = 0;
903                                                 ctrl->pcix_speed_capability = 0;
904                                                 break;
905                                         case PCI_SUB_HPC_ID_INTC:
906                                                 /* Third party (6500/7000) */
907                                                 ctrl->slot_switch_type = 1;
908                                                 ctrl->speed_capability = PCI_SPEED_33MHz;
909                                                 ctrl->push_button = 0;
910                                                 ctrl->pci_config_space = 1;
911                                                 ctrl->defeature_PHP = 1;
912                                                 ctrl->pcix_support = 0;
913                                                 ctrl->pcix_speed_capability = 0;
914                                                 break;
915                                         case PCI_SUB_HPC_ID3:
916                                                 /* First 66 Mhz implementation */
917                                                 ctrl->push_flag = 1;
918                                                 ctrl->slot_switch_type = 1;
919                                                 ctrl->speed_capability = PCI_SPEED_66MHz;
920                                                 ctrl->push_button = 1;
921                                                 ctrl->pci_config_space = 1;
922                                                 ctrl->defeature_PHP = 1;
923                                                 ctrl->pcix_support = 0;
924                                                 ctrl->pcix_speed_capability = 0;
925                                                 break;
926                                         case PCI_SUB_HPC_ID4:
927                                                 /* First PCI-X implementation, 100MHz */
928                                                 ctrl->push_flag = 1;
929                                                 ctrl->slot_switch_type = 1;
930                                                 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
931                                                 ctrl->push_button = 1;
932                                                 ctrl->pci_config_space = 1;
933                                                 ctrl->defeature_PHP = 1;
934                                                 ctrl->pcix_support = 1;
935                                                 ctrl->pcix_speed_capability = 0;        
936                                                 break;
937                                         default:
938                                                 err(msg_HPC_not_supported);
939                                                 rc = -ENODEV;
940                                                 goto err_free_ctrl;
941                                 }
942                                 break;
943
944                         case PCI_VENDOR_ID_INTEL:
945                                 /* Check for speed capability (0=33, 1=66) */
946                                 if (subsystem_deviceid & 0x0001) {
947                                         ctrl->speed_capability = PCI_SPEED_66MHz;
948                                 } else {
949                                         ctrl->speed_capability = PCI_SPEED_33MHz;
950                                 }
951
952                                 /* Check for push button */
953                                 if (subsystem_deviceid & 0x0002) {
954                                         /* no push button */
955                                         ctrl->push_button = 0;
956                                 } else {
957                                         /* push button supported */
958                                         ctrl->push_button = 1;
959                                 }
960
961                                 /* Check for slot switch type (0=mechanical, 1=not mechanical) */
962                                 if (subsystem_deviceid & 0x0004) {
963                                         /* no switch */
964                                         ctrl->slot_switch_type = 0;
965                                 } else {
966                                         /* switch */
967                                         ctrl->slot_switch_type = 1;
968                                 }
969
970                                 /* PHP Status (0=De-feature PHP, 1=Normal operation) */
971                                 if (subsystem_deviceid & 0x0008) {
972                                         ctrl->defeature_PHP = 1;        // PHP supported
973                                 } else {
974                                         ctrl->defeature_PHP = 0;        // PHP not supported
975                                 }
976
977                                 /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
978                                 if (subsystem_deviceid & 0x0010) {
979                                         ctrl->alternate_base_address = 1;       // supported
980                                 } else {
981                                         ctrl->alternate_base_address = 0;       // not supported
982                                 }
983
984                                 /* PCI Config Space Index (0=not supported, 1=supported) */
985                                 if (subsystem_deviceid & 0x0020) {
986                                         ctrl->pci_config_space = 1;             // supported
987                                 } else {
988                                         ctrl->pci_config_space = 0;             // not supported
989                                 }
990
991                                 /* PCI-X support */
992                                 if (subsystem_deviceid & 0x0080) {
993                                         /* PCI-X capable */
994                                         ctrl->pcix_support = 1;
995                                         /* Frequency of operation in PCI-X mode */
996                                         if (subsystem_deviceid & 0x0040) {
997                                                 /* 133MHz PCI-X if bit 7 is 1 */
998                                                 ctrl->pcix_speed_capability = 1;
999                                         } else {
1000                                                 /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
1001                                                 /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
1002                                                 ctrl->pcix_speed_capability = 0;
1003                                         }
1004                                 } else {
1005                                         /* Conventional PCI */
1006                                         ctrl->pcix_support = 0;
1007                                         ctrl->pcix_speed_capability = 0;
1008                                 }
1009                                 break;
1010
1011                         default:
1012                                 err(msg_HPC_not_supported);
1013                                 rc = -ENODEV;
1014                                 goto err_free_ctrl;
1015                 }
1016
1017         } else {
1018                 err(msg_HPC_not_supported);
1019                 return -ENODEV;
1020         }
1021
1022         // Tell the user that we found one.
1023         info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
1024                                         pdev->bus->number);
1025
1026         dbg("Hotplug controller capabilities:\n");
1027         dbg("    speed_capability       %d\n", ctrl->speed_capability);
1028         dbg("    slot_switch_type       %s\n", ctrl->slot_switch_type ?
1029                                         "switch present" : "no switch");
1030         dbg("    defeature_PHP          %s\n", ctrl->defeature_PHP ?
1031                                         "PHP supported" : "PHP not supported");
1032         dbg("    alternate_base_address %s\n", ctrl->alternate_base_address ?
1033                                         "supported" : "not supported");
1034         dbg("    pci_config_space       %s\n", ctrl->pci_config_space ?
1035                                         "supported" : "not supported");
1036         dbg("    pcix_speed_capability  %s\n", ctrl->pcix_speed_capability ?
1037                                         "supported" : "not supported");
1038         dbg("    pcix_support           %s\n", ctrl->pcix_support ?
1039                                         "supported" : "not supported");
1040
1041         ctrl->pci_dev = pdev;
1042         pci_set_drvdata(pdev, ctrl);
1043
1044         /* make our own copy of the pci bus structure,
1045          * as we like tweaking it a lot */
1046         ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
1047         if (!ctrl->pci_bus) {
1048                 err("out of memory\n");
1049                 rc = -ENOMEM;
1050                 goto err_free_ctrl;
1051         }
1052         memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus));
1053
1054         ctrl->bus = pdev->bus->number;
1055         ctrl->rev = rev;
1056         dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
1057                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
1058
1059         init_MUTEX(&ctrl->crit_sect);
1060         init_waitqueue_head(&ctrl->queue);
1061
1062         /* initialize our threads if they haven't already been started up */
1063         rc = one_time_init();
1064         if (rc) {
1065                 goto err_free_bus;
1066         }
1067         
1068         dbg("pdev = %p\n", pdev);
1069         dbg("pci resource start %lx\n", pci_resource_start(pdev, 0));
1070         dbg("pci resource len %lx\n", pci_resource_len(pdev, 0));
1071
1072         if (!request_mem_region(pci_resource_start(pdev, 0),
1073                                 pci_resource_len(pdev, 0), MY_NAME)) {
1074                 err("cannot reserve MMIO region\n");
1075                 rc = -ENOMEM;
1076                 goto err_free_bus;
1077         }
1078
1079         ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0),
1080                                         pci_resource_len(pdev, 0));
1081         if (!ctrl->hpc_reg) {
1082                 err("cannot remap MMIO region %lx @ %lx\n",
1083                                 pci_resource_len(pdev, 0),
1084                                 pci_resource_start(pdev, 0));
1085                 rc = -ENODEV;
1086                 goto err_free_mem_region;
1087         }
1088
1089         // Check for 66Mhz operation
1090         ctrl->speed = get_controller_speed(ctrl);
1091
1092
1093         /********************************************************
1094          *
1095          *              Save configuration headers for this and
1096          *              subordinate PCI buses
1097          *
1098          ********************************************************/
1099
1100         // find the physical slot number of the first hot plug slot
1101
1102         /* Get slot won't work for devices behind bridges, but
1103          * in this case it will always be called for the "base"
1104          * bus/dev/func of a slot.
1105          * CS: this is leveraging the PCIIRQ routing code from the kernel
1106          * (pci-pc.c: get_irq_routing_table) */
1107         rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number,
1108                                 (readb(ctrl->hpc_reg + SLOT_MASK) >> 4),
1109                                 &(ctrl->first_slot));
1110         dbg("get_slot_mapping: first_slot = %d, returned = %d\n",
1111                                 ctrl->first_slot, rc);
1112         if (rc) {
1113                 err(msg_initialization_err, rc);
1114                 goto err_iounmap;
1115         }
1116
1117         // Store PCI Config Space for all devices on this bus
1118         rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
1119         if (rc) {
1120                 err("%s: unable to save PCI configuration data, error %d\n",
1121                                 __FUNCTION__, rc);
1122                 goto err_iounmap;
1123         }
1124
1125         /*
1126          * Get IO, memory, and IRQ resources for new devices
1127          */
1128         // The next line is required for cpqhp_find_available_resources
1129         ctrl->interrupt = pdev->irq;
1130         if (ctrl->interrupt < 0x10) {
1131                 cpqhp_legacy_mode = 1;
1132                 dbg("System seems to be configured for Full Table Mapped MPS mode\n");
1133         }
1134
1135         ctrl->cfgspc_irq = 0;
1136         pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
1137
1138         rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
1139         ctrl->add_support = !rc;
1140         if (rc) {
1141                 dbg("cpqhp_find_available_resources = 0x%x\n", rc);
1142                 err("unable to locate PCI configuration resources for hot plug add.\n");
1143                 goto err_iounmap;
1144         }
1145
1146         /*
1147          * Finish setting up the hot plug ctrl device
1148          */
1149         ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1150         dbg("NumSlots %d \n", ctrl->slot_device_offset);
1151
1152         ctrl->next_event = 0;
1153
1154         /* Setup the slot information structures */
1155         rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
1156         if (rc) {
1157                 err(msg_initialization_err, 6);
1158                 err("%s: unable to save PCI configuration data, error %d\n",
1159                         __FUNCTION__, rc);
1160                 goto err_iounmap;
1161         }
1162         
1163         /* Mask all general input interrupts */
1164         writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
1165
1166         /* set up the interrupt */
1167         dbg("HPC interrupt = %d \n", ctrl->interrupt);
1168         if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
1169                         SA_SHIRQ, MY_NAME, ctrl)) {
1170                 err("Can't get irq %d for the hotplug pci controller\n",
1171                         ctrl->interrupt);
1172                 rc = -ENODEV;
1173                 goto err_iounmap;
1174         }
1175
1176         /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
1177         temp_word = readw(ctrl->hpc_reg + MISC);
1178         temp_word |= 0x4006;
1179         writew(temp_word, ctrl->hpc_reg + MISC);
1180
1181         // Changed 05/05/97 to clear all interrupts at start
1182         writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
1183
1184         ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
1185
1186         writel(0x0L, ctrl->hpc_reg + INT_MASK);
1187
1188         if (!cpqhp_ctrl_list) {
1189                 cpqhp_ctrl_list = ctrl;
1190                 ctrl->next = NULL;
1191         } else {
1192                 ctrl->next = cpqhp_ctrl_list;
1193                 cpqhp_ctrl_list = ctrl;
1194         }
1195
1196         // turn off empty slots here unless command line option "ON" set
1197         // Wait for exclusive access to hardware
1198         down(&ctrl->crit_sect);
1199
1200         num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
1201
1202         // find first device number for the ctrl
1203         device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1204
1205         while (num_of_slots) {
1206                 dbg("num_of_slots: %d\n", num_of_slots);
1207                 func = cpqhp_slot_find(ctrl->bus, device, 0);
1208                 if (!func)
1209                         break;
1210
1211                 hp_slot = func->device - ctrl->slot_device_offset;
1212                 dbg("hp_slot: %d\n", hp_slot);
1213
1214                 // We have to save the presence info for these slots
1215                 temp_word = ctrl->ctrl_int_comp >> 16;
1216                 func->presence_save = (temp_word >> hp_slot) & 0x01;
1217                 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
1218
1219                 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
1220                         func->switch_save = 0;
1221                 } else {
1222                         func->switch_save = 0x10;
1223                 }
1224
1225                 if (!power_mode) {
1226                         if (!func->is_a_board) {
1227                                 green_LED_off(ctrl, hp_slot);
1228                                 slot_disable(ctrl, hp_slot);
1229                         }
1230                 }
1231
1232                 device++;
1233                 num_of_slots--;
1234         }
1235
1236         if (!power_mode) {
1237                 set_SOGO(ctrl);
1238                 // Wait for SOBS to be unset
1239                 wait_for_ctrl_irq(ctrl);
1240         }
1241
1242         rc = init_SERR(ctrl);
1243         if (rc) {
1244                 err("init_SERR failed\n");
1245                 up(&ctrl->crit_sect);
1246                 goto err_free_irq;
1247         }
1248
1249         // Done with exclusive hardware access
1250         up(&ctrl->crit_sect);
1251
1252         cpqhp_create_ctrl_files(ctrl);
1253
1254         return 0;
1255
1256 err_free_irq:
1257         free_irq(ctrl->interrupt, ctrl);
1258 err_iounmap:
1259         iounmap(ctrl->hpc_reg);
1260 err_free_mem_region:
1261         release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
1262 err_free_bus:
1263         kfree(ctrl->pci_bus);
1264 err_free_ctrl:
1265         kfree(ctrl);
1266         return rc;
1267 }
1268
1269
1270 static int one_time_init(void)
1271 {
1272         int loop;
1273         int retval = 0;
1274         static int initialized = 0;
1275
1276         if (initialized)
1277                 return 0;
1278
1279         power_mode = 0;
1280
1281         retval = pci_print_IRQ_route();
1282         if (retval)
1283                 goto error;
1284
1285         dbg("Initialize + Start the notification mechanism \n");
1286
1287         retval = cpqhp_event_start_thread();
1288         if (retval)
1289                 goto error;
1290
1291         dbg("Initialize slot lists\n");
1292         for (loop = 0; loop < 256; loop++) {
1293                 cpqhp_slot_list[loop] = NULL;
1294         }
1295
1296         // FIXME: We also need to hook the NMI handler eventually.
1297         // this also needs to be worked with Christoph
1298         // register_NMI_handler();
1299
1300         // Map rom address
1301         cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
1302         if (!cpqhp_rom_start) {
1303                 err ("Could not ioremap memory region for ROM\n");
1304                 retval = -EIO;
1305                 goto error;
1306         }
1307         
1308         /* Now, map the int15 entry point if we are on compaq specific hardware */
1309         compaq_nvram_init(cpqhp_rom_start);
1310         
1311         /* Map smbios table entry point structure */
1312         smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
1313                                         cpqhp_rom_start + ROM_PHY_LEN);
1314         if (!smbios_table) {
1315                 err ("Could not find the SMBIOS pointer in memory\n");
1316                 retval = -EIO;
1317                 goto error_rom_start;
1318         }
1319
1320         smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
1321                                         readw(smbios_table + ST_LENGTH));
1322         if (!smbios_start) {
1323                 err ("Could not ioremap memory region taken from SMBIOS values\n");
1324                 retval = -EIO;
1325                 goto error_smbios_start;
1326         }
1327
1328         initialized = 1;
1329
1330         return retval;
1331
1332 error_smbios_start:
1333         iounmap(smbios_start);
1334 error_rom_start:
1335         iounmap(cpqhp_rom_start);
1336 error:
1337         return retval;
1338 }
1339
1340
1341 static void __exit unload_cpqphpd(void)
1342 {
1343         struct pci_func *next;
1344         struct pci_func *TempSlot;
1345         int loop;
1346         u32 rc;
1347         struct controller *ctrl;
1348         struct controller *tctrl;
1349         struct pci_resource *res;
1350         struct pci_resource *tres;
1351
1352         rc = compaq_nvram_store(cpqhp_rom_start);
1353
1354         ctrl = cpqhp_ctrl_list;
1355
1356         while (ctrl) {
1357                 if (ctrl->hpc_reg) {
1358                         u16 misc;
1359                         rc = read_slot_enable (ctrl);
1360                         
1361                         writeb(0, ctrl->hpc_reg + SLOT_SERR);
1362                         writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
1363                         
1364                         misc = readw(ctrl->hpc_reg + MISC);
1365                         misc &= 0xFFFD;
1366                         writew(misc, ctrl->hpc_reg + MISC);
1367                 }
1368
1369                 ctrl_slot_cleanup(ctrl);
1370
1371                 res = ctrl->io_head;
1372                 while (res) {
1373                         tres = res;
1374                         res = res->next;
1375                         kfree(tres);
1376                 }
1377
1378                 res = ctrl->mem_head;
1379                 while (res) {
1380                         tres = res;
1381                         res = res->next;
1382                         kfree(tres);
1383                 }
1384
1385                 res = ctrl->p_mem_head;
1386                 while (res) {
1387                         tres = res;
1388                         res = res->next;
1389                         kfree(tres);
1390                 }
1391
1392                 res = ctrl->bus_head;
1393                 while (res) {
1394                         tres = res;
1395                         res = res->next;
1396                         kfree(tres);
1397                 }
1398
1399                 kfree (ctrl->pci_bus);
1400
1401                 tctrl = ctrl;
1402                 ctrl = ctrl->next;
1403                 kfree(tctrl);
1404         }
1405
1406         for (loop = 0; loop < 256; loop++) {
1407                 next = cpqhp_slot_list[loop];
1408                 while (next != NULL) {
1409                         res = next->io_head;
1410                         while (res) {
1411                                 tres = res;
1412                                 res = res->next;
1413                                 kfree(tres);
1414                         }
1415
1416                         res = next->mem_head;
1417                         while (res) {
1418                                 tres = res;
1419                                 res = res->next;
1420                                 kfree(tres);
1421                         }
1422
1423                         res = next->p_mem_head;
1424                         while (res) {
1425                                 tres = res;
1426                                 res = res->next;
1427                                 kfree(tres);
1428                         }
1429
1430                         res = next->bus_head;
1431                         while (res) {
1432                                 tres = res;
1433                                 res = res->next;
1434                                 kfree(tres);
1435                         }
1436
1437                         TempSlot = next;
1438                         next = next->next;
1439                         kfree(TempSlot);
1440                 }
1441         }
1442
1443         // Stop the notification mechanism
1444         cpqhp_event_stop_thread();
1445
1446         //unmap the rom address
1447         if (cpqhp_rom_start)
1448                 iounmap(cpqhp_rom_start);
1449         if (smbios_start)
1450                 iounmap(smbios_start);
1451 }
1452
1453
1454
1455 static struct pci_device_id hpcd_pci_tbl[] = {
1456         {
1457         /* handle any PCI Hotplug controller */
1458         .class =        ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1459         .class_mask =   ~0,
1460         
1461         /* no matter who makes it */
1462         .vendor =       PCI_ANY_ID,
1463         .device =       PCI_ANY_ID,
1464         .subvendor =    PCI_ANY_ID,
1465         .subdevice =    PCI_ANY_ID,
1466         
1467         }, { /* end: all zeroes */ }
1468 };
1469
1470 MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
1471
1472
1473
1474 static struct pci_driver cpqhpc_driver = {
1475         .name =         "compaq_pci_hotplug",
1476         .id_table =     hpcd_pci_tbl,
1477         .probe =        cpqhpc_probe,
1478         /* remove:      cpqhpc_remove_one, */
1479 };
1480
1481
1482
1483 static int __init cpqhpc_init(void)
1484 {
1485         int result;
1486
1487         cpqhp_debug = debug;
1488
1489         info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
1490         result = pci_register_driver(&cpqhpc_driver);
1491         dbg("pci_register_driver = %d\n", result);
1492         return result;
1493 }
1494
1495
1496 static void __exit cpqhpc_cleanup(void)
1497 {
1498         dbg("unload_cpqphpd()\n");
1499         unload_cpqphpd();
1500
1501         dbg("pci_unregister_driver\n");
1502         pci_unregister_driver(&cpqhpc_driver);
1503 }
1504
1505
1506 module_init(cpqhpc_init);
1507 module_exit(cpqhpc_cleanup);
1508
1509