Merge branch 'x86/apic' into irq/numa
[linux-2.6] / drivers / pci / hotplug / ibmphp_core.c
1 /*
2  * IBM Hot Plug Controller Driver
3  *
4  * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
5  *
6  * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7  * Copyright (C) 2001-2003 IBM Corp.
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or (at
14  * your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19  * NON INFRINGEMENT.  See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  * Send feedback to <gregkh@us.ibm.com>
27  *
28  */
29
30 #include <linux/init.h>
31 #include <linux/module.h>
32 #include <linux/slab.h>
33 #include <linux/pci.h>
34 #include <linux/interrupt.h>
35 #include <linux/delay.h>
36 #include <linux/wait.h>
37 #include "../pci.h"
38 #include <asm/pci_x86.h>                /* for struct irq_routing_table */
39 #include "ibmphp.h"
40
41 #define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
42 #define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
43 #define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
44 #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
45 #define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
46
47 #define DRIVER_VERSION  "0.6"
48 #define DRIVER_DESC     "IBM Hot Plug PCI Controller Driver"
49
50 int ibmphp_debug;
51
52 static int debug;
53 module_param(debug, bool, S_IRUGO | S_IWUSR);
54 MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
55 MODULE_LICENSE ("GPL");
56 MODULE_DESCRIPTION (DRIVER_DESC);
57
58 struct pci_bus *ibmphp_pci_bus;
59 static int max_slots;
60
61 static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS
62                          * tables don't provide default info for empty slots */
63
64 static int init_flag;
65
66 /*
67 static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
68
69 static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
70 {
71         return get_max_adapter_speed_1 (hs, value, 1);
72 }
73 */
74 static inline int get_cur_bus_info(struct slot **sl) 
75 {
76         int rc = 1;
77         struct slot * slot_cur = *sl;
78
79         debug("options = %x\n", slot_cur->ctrl->options);
80         debug("revision = %x\n", slot_cur->ctrl->revision);     
81
82         if (READ_BUS_STATUS(slot_cur->ctrl)) 
83                 rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
84         
85         if (rc) 
86                 return rc;
87           
88         slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
89         if (READ_BUS_MODE(slot_cur->ctrl))
90                 slot_cur->bus_on->current_bus_mode =
91                                 CURRENT_BUS_MODE(slot_cur->busstatus);
92         else
93                 slot_cur->bus_on->current_bus_mode = 0xFF;
94
95         debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
96                         slot_cur->busstatus,
97                         slot_cur->bus_on->current_speed,
98                         slot_cur->bus_on->current_bus_mode);
99         
100         *sl = slot_cur;
101         return 0;
102 }
103
104 static inline int slot_update(struct slot **sl)
105 {
106         int rc;
107         rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
108         if (rc) 
109                 return rc;
110         if (!init_flag)
111                 rc = get_cur_bus_info(sl);
112         return rc;
113 }
114
115 static int __init get_max_slots (void)
116 {
117         struct slot * slot_cur;
118         struct list_head * tmp;
119         u8 slot_count = 0;
120
121         list_for_each(tmp, &ibmphp_slot_head) {
122                 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
123                 /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
124                 slot_count = max(slot_count, slot_cur->number);
125         }
126         return slot_count;
127 }
128
129 /* This routine will put the correct slot->device information per slot.  It's
130  * called from initialization of the slot structures. It will also assign
131  * interrupt numbers per each slot.
132  * Parameters: struct slot
133  * Returns 0 or errors
134  */
135 int ibmphp_init_devno(struct slot **cur_slot)
136 {
137         struct irq_routing_table *rtable;
138         int len;
139         int loop;
140         int i;
141
142         rtable = pcibios_get_irq_routing_table();
143         if (!rtable) {
144                 err("no BIOS routing table...\n");
145                 return -ENOMEM;
146         }
147
148         len = (rtable->size - sizeof(struct irq_routing_table)) /
149                         sizeof(struct irq_info);
150
151         if (!len) {
152                 kfree(rtable);
153                 return -1;
154         }
155         for (loop = 0; loop < len; loop++) {
156                 if ((*cur_slot)->number == rtable->slots[loop].slot &&
157                     (*cur_slot)->bus == rtable->slots[loop].bus) {
158                         int ioapic = -1, ioapic_pin = -1;
159                         int triggering, polarity;
160
161                         (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
162                         for (i = 0; i < 4; i++)
163                                 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
164                                                 (int) (*cur_slot)->device, i.
165                                                 &ioapic, &ioapic_pin,
166                                                 &triggering, &polarity);
167
168                         debug("(*cur_slot)->irq[0] = %x\n",
169                                         (*cur_slot)->irq[0]);
170                         debug("(*cur_slot)->irq[1] = %x\n",
171                                         (*cur_slot)->irq[1]);
172                         debug("(*cur_slot)->irq[2] = %x\n",
173                                         (*cur_slot)->irq[2]);
174                         debug("(*cur_slot)->irq[3] = %x\n",
175                                         (*cur_slot)->irq[3]);
176
177                         debug("rtable->exlusive_irqs = %x\n",
178                                         rtable->exclusive_irqs);
179                         debug("rtable->slots[loop].irq[0].bitmap = %x\n",
180                                         rtable->slots[loop].irq[0].bitmap);
181                         debug("rtable->slots[loop].irq[1].bitmap = %x\n",
182                                         rtable->slots[loop].irq[1].bitmap);
183                         debug("rtable->slots[loop].irq[2].bitmap = %x\n",
184                                         rtable->slots[loop].irq[2].bitmap);
185                         debug("rtable->slots[loop].irq[3].bitmap = %x\n",
186                                         rtable->slots[loop].irq[3].bitmap);
187
188                         debug("rtable->slots[loop].irq[0].link = %x\n",
189                                         rtable->slots[loop].irq[0].link);
190                         debug("rtable->slots[loop].irq[1].link = %x\n",
191                                         rtable->slots[loop].irq[1].link);
192                         debug("rtable->slots[loop].irq[2].link = %x\n",
193                                         rtable->slots[loop].irq[2].link);
194                         debug("rtable->slots[loop].irq[3].link = %x\n",
195                                         rtable->slots[loop].irq[3].link);
196                         debug("end of init_devno\n");
197                         kfree(rtable);
198                         return 0;
199                 }
200         }
201
202         kfree(rtable);
203         return -1;
204 }
205
206 static inline int power_on(struct slot *slot_cur)
207 {
208         u8 cmd = HPC_SLOT_ON;
209         int retval;
210
211         retval = ibmphp_hpc_writeslot(slot_cur, cmd);
212         if (retval) {
213                 err("power on failed\n");
214                 return retval;
215         }
216         if (CTLR_RESULT(slot_cur->ctrl->status)) {
217                 err("command not completed successfully in power_on\n");
218                 return -EIO;
219         }
220         msleep(3000);   /* For ServeRAID cards, and some 66 PCI */
221         return 0;
222 }
223
224 static inline int power_off(struct slot *slot_cur)
225 {
226         u8 cmd = HPC_SLOT_OFF;
227         int retval;
228
229         retval = ibmphp_hpc_writeslot(slot_cur, cmd);
230         if (retval) {
231                 err("power off failed\n");
232                 return retval;
233         }
234         if (CTLR_RESULT(slot_cur->ctrl->status)) {
235                 err("command not completed successfully in power_off\n");
236                 retval = -EIO;
237         }
238         return retval;
239 }
240
241 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
242 {
243         int rc = 0;
244         struct slot *pslot;
245         u8 cmd = 0x00;     /* avoid compiler warning */
246
247         debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
248                         (ulong) hotplug_slot, value);
249         ibmphp_lock_operations();
250
251
252         if (hotplug_slot) {
253                 switch (value) {
254                 case HPC_SLOT_ATTN_OFF:
255                         cmd = HPC_SLOT_ATTNOFF;
256                         break;
257                 case HPC_SLOT_ATTN_ON:
258                         cmd = HPC_SLOT_ATTNON;
259                         break;
260                 case HPC_SLOT_ATTN_BLINK:
261                         cmd = HPC_SLOT_BLINKLED;
262                         break;
263                 default:
264                         rc = -ENODEV;
265                         err("set_attention_status - Error : invalid input [%x]\n",
266                                         value);
267                         break;
268                 }
269                 if (rc == 0) {
270                         pslot = hotplug_slot->private;
271                         if (pslot)
272                                 rc = ibmphp_hpc_writeslot(pslot, cmd);
273                         else
274                                 rc = -ENODEV;
275                 }
276         } else  
277                 rc = -ENODEV;
278
279         ibmphp_unlock_operations();
280
281         debug("set_attention_status - Exit rc[%d]\n", rc);
282         return rc;
283 }
284
285 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
286 {
287         int rc = -ENODEV;
288         struct slot *pslot;
289         struct slot myslot;
290
291         debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
292                                         (ulong) hotplug_slot, (ulong) value);
293         
294         ibmphp_lock_operations();
295         if (hotplug_slot) {
296                 pslot = hotplug_slot->private;
297                 if (pslot) {
298                         memcpy(&myslot, pslot, sizeof(struct slot));
299                         rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
300                                                 &(myslot.status));
301                         if (!rc)
302                                 rc = ibmphp_hpc_readslot(pslot,
303                                                 READ_EXTSLOTSTATUS,
304                                                 &(myslot.ext_status));
305                         if (!rc)
306                                 *value = SLOT_ATTN(myslot.status,
307                                                 myslot.ext_status);
308                 }
309         }
310
311         ibmphp_unlock_operations();
312         debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
313         return rc;
314 }
315
316 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
317 {
318         int rc = -ENODEV;
319         struct slot *pslot;
320         struct slot myslot;
321
322         debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
323                                         (ulong) hotplug_slot, (ulong) value);
324         ibmphp_lock_operations();
325         if (hotplug_slot) {
326                 pslot = hotplug_slot->private;
327                 if (pslot) {
328                         memcpy(&myslot, pslot, sizeof(struct slot));
329                         rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
330                                                 &(myslot.status));
331                         if (!rc)
332                                 *value = SLOT_LATCH(myslot.status);
333                 }
334         }
335
336         ibmphp_unlock_operations();
337         debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
338                         rc, rc, *value);
339         return rc;
340 }
341
342
343 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
344 {
345         int rc = -ENODEV;
346         struct slot *pslot;
347         struct slot myslot;
348
349         debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
350                                         (ulong) hotplug_slot, (ulong) value);
351         ibmphp_lock_operations();
352         if (hotplug_slot) {
353                 pslot = hotplug_slot->private;
354                 if (pslot) {
355                         memcpy(&myslot, pslot, sizeof(struct slot));
356                         rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
357                                                 &(myslot.status));
358                         if (!rc)
359                                 *value = SLOT_PWRGD(myslot.status);
360                 }
361         }
362
363         ibmphp_unlock_operations();
364         debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
365                         rc, rc, *value);
366         return rc;
367 }
368
369 static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
370 {
371         int rc = -ENODEV;
372         struct slot *pslot;
373         u8 present;
374         struct slot myslot;
375
376         debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
377                                         (ulong) hotplug_slot, (ulong) value);
378         ibmphp_lock_operations();
379         if (hotplug_slot) {
380                 pslot = hotplug_slot->private;
381                 if (pslot) {
382                         memcpy(&myslot, pslot, sizeof(struct slot));
383                         rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
384                                                 &(myslot.status));
385                         if (!rc) {
386                                 present = SLOT_PRESENT(myslot.status);
387                                 if (present == HPC_SLOT_EMPTY)
388                                         *value = 0;
389                                 else
390                                         *value = 1;
391                         }
392                 }
393         }
394
395         ibmphp_unlock_operations();
396         debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
397         return rc;
398 }
399
400 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
401 {
402         int rc = -ENODEV;
403         struct slot *pslot;
404         u8 mode = 0;
405
406         debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
407                 hotplug_slot, value);
408
409         ibmphp_lock_operations();
410
411         if (hotplug_slot) {
412                 pslot = hotplug_slot->private;
413                 if (pslot) {
414                         rc = 0;
415                         mode = pslot->supported_bus_mode;
416                         *value = pslot->supported_speed; 
417                         switch (*value) {
418                         case BUS_SPEED_33:
419                                 break;
420                         case BUS_SPEED_66:
421                                 if (mode == BUS_MODE_PCIX) 
422                                         *value += 0x01;
423                                 break;
424                         case BUS_SPEED_100:
425                         case BUS_SPEED_133:
426                                 *value = pslot->supported_speed + 0x01;
427                                 break;
428                         default:
429                                 /* Note (will need to change): there would be soon 256, 512 also */
430                                 rc = -ENODEV;
431                         }
432                 }
433         }
434
435         ibmphp_unlock_operations();
436         debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
437         return rc;
438 }
439
440 static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
441 {
442         int rc = -ENODEV;
443         struct slot *pslot;
444         u8 mode = 0;
445
446         debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
447                 hotplug_slot, value);
448
449         ibmphp_lock_operations();
450
451         if (hotplug_slot) {
452                 pslot = hotplug_slot->private;
453                 if (pslot) {
454                         rc = get_cur_bus_info(&pslot);
455                         if (!rc) {
456                                 mode = pslot->bus_on->current_bus_mode;
457                                 *value = pslot->bus_on->current_speed;
458                                 switch (*value) {
459                                 case BUS_SPEED_33:
460                                         break;
461                                 case BUS_SPEED_66:
462                                         if (mode == BUS_MODE_PCIX) 
463                                                 *value += 0x01;
464                                         else if (mode == BUS_MODE_PCI)
465                                                 ;
466                                         else
467                                                 *value = PCI_SPEED_UNKNOWN;
468                                         break;
469                                 case BUS_SPEED_100:
470                                 case BUS_SPEED_133:
471                                         *value += 0x01;
472                                         break;
473                                 default:
474                                         /* Note of change: there would also be 256, 512 soon */
475                                         rc = -ENODEV;
476                                 }
477                         }
478                 }
479         }
480
481         ibmphp_unlock_operations();
482         debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
483         return rc;
484 }
485
486 /*
487 static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
488 {
489         int rc = -ENODEV;
490         struct slot *pslot;
491         struct slot myslot;
492
493         debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
494                                                 (ulong)hotplug_slot, (ulong) value);
495
496         if (flag)
497                 ibmphp_lock_operations();
498
499         if (hotplug_slot && value) {
500                 pslot = hotplug_slot->private;
501                 if (pslot) {
502                         memcpy(&myslot, pslot, sizeof(struct slot));
503                         rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
504                                                 &(myslot.status));
505
506                         if (!(SLOT_LATCH (myslot.status)) &&
507                                         (SLOT_PRESENT (myslot.status))) {
508                                 rc = ibmphp_hpc_readslot(pslot,
509                                                 READ_EXTSLOTSTATUS,
510                                                 &(myslot.ext_status));
511                                 if (!rc)
512                                         *value = SLOT_SPEED(myslot.ext_status);
513                         } else
514                                 *value = MAX_ADAPTER_NONE;
515                 }
516         }
517
518         if (flag)
519                 ibmphp_unlock_operations();
520
521         debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
522         return rc;
523 }
524
525 static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
526 {
527         int rc = -ENODEV;
528         struct slot *pslot = NULL;
529
530         debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
531
532         ibmphp_lock_operations();
533
534         if (hotplug_slot) {
535                 pslot = hotplug_slot->private;
536                 if (pslot) {
537                         rc = 0;
538                         snprintf(value, 100, "Bus %x", pslot->bus);
539                 }
540         } else
541                 rc = -ENODEV;
542
543         ibmphp_unlock_operations();
544         debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
545         return rc;
546 }
547 */
548
549 /****************************************************************************
550  * This routine will initialize the ops data structure used in the validate
551  * function. It will also power off empty slots that are powered on since BIOS
552  * leaves those on, albeit disconnected
553  ****************************************************************************/
554 static int __init init_ops(void)
555 {
556         struct slot *slot_cur;
557         struct list_head *tmp;
558         int retval;
559         int rc;
560
561         list_for_each(tmp, &ibmphp_slot_head) {
562                 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
563
564                 if (!slot_cur)
565                         return -ENODEV;
566
567                 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
568                                                         slot_cur->number);
569                 if (slot_cur->ctrl->revision == 0xFF) 
570                         if (get_ctrl_revision(slot_cur,
571                                                 &slot_cur->ctrl->revision))
572                                 return -1;
573
574                 if (slot_cur->bus_on->current_speed == 0xFF) 
575                         if (get_cur_bus_info(&slot_cur)) 
576                                 return -1;
577
578                 if (slot_cur->ctrl->options == 0xFF)
579                         if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
580                                 return -1;
581
582                 retval = slot_update(&slot_cur);
583                 if (retval)
584                         return retval;
585
586                 debug("status = %x\n", slot_cur->status);
587                 debug("ext_status = %x\n", slot_cur->ext_status);
588                 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
589                 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
590                 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
591
592                 if ((SLOT_PWRGD(slot_cur->status)) && 
593                     !(SLOT_PRESENT(slot_cur->status)) && 
594                     !(SLOT_LATCH(slot_cur->status))) {
595                         debug("BEFORE POWER OFF COMMAND\n");
596                                 rc = power_off(slot_cur);
597                                 if (rc)
598                                         return rc;
599
600         /*              retval = slot_update(&slot_cur);
601          *              if (retval)
602          *                      return retval;
603          *              ibmphp_update_slot_info(slot_cur);
604          */
605                 }
606         }
607         init_flag = 0;
608         return 0;
609 }
610
611 /* This operation will check whether the slot is within the bounds and
612  * the operation is valid to perform on that slot
613  * Parameters: slot, operation
614  * Returns: 0 or error codes
615  */
616 static int validate(struct slot *slot_cur, int opn)
617 {
618         int number;
619         int retval;
620
621         if (!slot_cur)
622                 return -ENODEV;
623         number = slot_cur->number;
624         if ((number > max_slots) || (number < 0))
625                 return -EBADSLT;
626         debug("slot_number in validate is %d\n", slot_cur->number);
627
628         retval = slot_update(&slot_cur);
629         if (retval)
630                 return retval;
631
632         switch (opn) {
633                 case ENABLE:
634                         if (!(SLOT_PWRGD(slot_cur->status)) && 
635                              (SLOT_PRESENT(slot_cur->status)) && 
636                              !(SLOT_LATCH(slot_cur->status)))
637                                 return 0;
638                         break;
639                 case DISABLE:
640                         if ((SLOT_PWRGD(slot_cur->status)) && 
641                             (SLOT_PRESENT(slot_cur->status)) &&
642                             !(SLOT_LATCH(slot_cur->status)))
643                                 return 0;
644                         break;
645                 default:
646                         break;
647         }
648         err("validate failed....\n");
649         return -EINVAL;
650 }
651
652 /****************************************************************************
653  * This routine is for updating the data structures in the hotplug core
654  * Parameters: struct slot
655  * Returns: 0 or error
656  ****************************************************************************/
657 int ibmphp_update_slot_info(struct slot *slot_cur)
658 {
659         struct hotplug_slot_info *info;
660         int rc;
661         u8 bus_speed;
662         u8 mode;
663
664         info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
665         if (!info) {
666                 err("out of system memory\n");
667                 return -ENOMEM;
668         }
669         
670         info->power_status = SLOT_PWRGD(slot_cur->status);
671         info->attention_status = SLOT_ATTN(slot_cur->status,
672                                                 slot_cur->ext_status);
673         info->latch_status = SLOT_LATCH(slot_cur->status);
674         if (!SLOT_PRESENT(slot_cur->status)) {
675                 info->adapter_status = 0;
676 /*              info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
677         } else {
678                 info->adapter_status = 1;
679 /*              get_max_adapter_speed_1(slot_cur->hotplug_slot,
680                                         &info->max_adapter_speed_status, 0); */
681         }
682
683         bus_speed = slot_cur->bus_on->current_speed;
684         mode = slot_cur->bus_on->current_bus_mode;
685
686         switch (bus_speed) {
687                 case BUS_SPEED_33:
688                         break;
689                 case BUS_SPEED_66:
690                         if (mode == BUS_MODE_PCIX) 
691                                 bus_speed += 0x01;
692                         else if (mode == BUS_MODE_PCI)
693                                 ;
694                         else
695                                 bus_speed = PCI_SPEED_UNKNOWN;
696                         break;
697                 case BUS_SPEED_100:
698                 case BUS_SPEED_133:
699                         bus_speed += 0x01;
700                         break;
701                 default:
702                         bus_speed = PCI_SPEED_UNKNOWN;
703         }
704
705         info->cur_bus_speed = bus_speed;
706         info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
707         // To do: bus_names 
708         
709         rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
710         kfree(info);
711         return rc;
712 }
713
714
715 /******************************************************************************
716  * This function will return the pci_func, given bus and devfunc, or NULL.  It
717  * is called from visit routines
718  ******************************************************************************/
719
720 static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
721 {
722         struct pci_func *func_cur;
723         struct slot *slot_cur;
724         struct list_head * tmp;
725         list_for_each(tmp, &ibmphp_slot_head) {
726                 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
727                 if (slot_cur->func) {
728                         func_cur = slot_cur->func;
729                         while (func_cur) {
730                                 if ((func_cur->busno == busno) &&
731                                                 (func_cur->device == device) &&
732                                                 (func_cur->function == function))
733                                         return func_cur;
734                                 func_cur = func_cur->next;
735                         }
736                 }
737         }
738         return NULL;
739 }
740
741 /*************************************************************
742  * This routine frees up memory used by struct slot, including
743  * the pointers to pci_func, bus, hotplug_slot, controller,
744  * and deregistering from the hotplug core
745  *************************************************************/
746 static void free_slots(void)
747 {
748         struct slot *slot_cur;
749         struct list_head * tmp;
750         struct list_head * next;
751
752         debug("%s -- enter\n", __func__);
753
754         list_for_each_safe(tmp, next, &ibmphp_slot_head) {
755                 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
756                 pci_hp_deregister(slot_cur->hotplug_slot);
757         }
758         debug("%s -- exit\n", __func__);
759 }
760
761 static void ibm_unconfigure_device(struct pci_func *func)
762 {
763         struct pci_dev *temp;
764         u8 j;
765
766         debug("inside %s\n", __func__);
767         debug("func->device = %x, func->function = %x\n",
768                                         func->device, func->function);
769         debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
770
771         for (j = 0; j < 0x08; j++) {
772                 temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
773                 if (temp) {
774                         pci_remove_bus_device(temp);
775                         pci_dev_put(temp);
776                 }
777         }
778         pci_dev_put(func->dev);
779 }
780
781 /*
782  * The following function is to fix kernel bug regarding 
783  * getting bus entries, here we manually add those primary 
784  * bus entries to kernel bus structure whenever apply
785  */
786 static u8 bus_structure_fixup(u8 busno)
787 {
788         struct pci_bus *bus;
789         struct pci_dev *dev;
790         u16 l;
791
792         if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
793                 return 1;
794
795         bus = kmalloc(sizeof(*bus), GFP_KERNEL);
796         if (!bus) {
797                 err("%s - out of memory\n", __func__);
798                 return 1;
799         }
800         dev = kmalloc(sizeof(*dev), GFP_KERNEL);
801         if (!dev) {
802                 kfree(bus);
803                 err("%s - out of memory\n", __func__);
804                 return 1;
805         }
806
807         bus->number = busno;
808         bus->ops = ibmphp_pci_bus->ops;
809         dev->bus = bus;
810         for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
811                 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
812                                         (l != 0x0000) && (l != 0xffff)) {
813                         debug("%s - Inside bus_struture_fixup()\n",
814                                                         __func__);
815                         pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
816                         break;
817                 }
818         }
819
820         kfree(dev);
821         kfree(bus);
822
823         return 0;
824 }
825
826 static int ibm_configure_device(struct pci_func *func)
827 {
828         unsigned char bus;
829         struct pci_bus *child;
830         int num;
831         int flag = 0;   /* this is to make sure we don't double scan the bus,
832                                         for bridged devices primarily */
833
834         if (!(bus_structure_fixup(func->busno)))
835                 flag = 1;
836         if (func->dev == NULL)
837                 func->dev = pci_get_bus_and_slot(func->busno,
838                                 PCI_DEVFN(func->device, func->function));
839
840         if (func->dev == NULL) {
841                 struct pci_bus *bus = pci_find_bus(0, func->busno);
842                 if (!bus)
843                         return 0;
844
845                 num = pci_scan_slot(bus,
846                                 PCI_DEVFN(func->device, func->function));
847                 if (num)
848                         pci_bus_add_devices(bus);
849
850                 func->dev = pci_get_bus_and_slot(func->busno,
851                                 PCI_DEVFN(func->device, func->function));
852                 if (func->dev == NULL) {
853                         err("ERROR... : pci_dev still NULL\n");
854                         return 0;
855                 }
856         }
857         if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
858                 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
859                 child = pci_add_new_bus(func->dev->bus, func->dev, bus);
860                 pci_do_scan_bus(child);
861         }
862
863         return 0;
864 }
865
866 /*******************************************************
867  * Returns whether the bus is empty or not 
868  *******************************************************/
869 static int is_bus_empty(struct slot * slot_cur)
870 {
871         int rc;
872         struct slot * tmp_slot;
873         u8 i = slot_cur->bus_on->slot_min;
874
875         while (i <= slot_cur->bus_on->slot_max) {
876                 if (i == slot_cur->number) {
877                         i++;
878                         continue;
879                 }
880                 tmp_slot = ibmphp_get_slot_from_physical_num(i);
881                 if (!tmp_slot)
882                         return 0;
883                 rc = slot_update(&tmp_slot);
884                 if (rc)
885                         return 0;
886                 if (SLOT_PRESENT(tmp_slot->status) &&
887                                         SLOT_PWRGD(tmp_slot->status))
888                         return 0;
889                 i++;
890         }
891         return 1;
892 }
893
894 /***********************************************************
895  * If the HPC permits and the bus currently empty, tries to set the 
896  * bus speed and mode at the maximum card and bus capability
897  * Parameters: slot
898  * Returns: bus is set (0) or error code
899  ***********************************************************/
900 static int set_bus(struct slot * slot_cur)
901 {
902         int rc;
903         u8 speed;
904         u8 cmd = 0x0;
905         int retval;
906         static struct pci_device_id ciobx[] = {
907                 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
908                 { },
909         };      
910
911         debug("%s - entry slot # %d\n", __func__, slot_cur->number);
912         if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
913                 rc = slot_update(&slot_cur);
914                 if (rc)
915                         return rc;
916                 speed = SLOT_SPEED(slot_cur->ext_status);
917                 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
918                 switch (speed) {
919                 case HPC_SLOT_SPEED_33:
920                         cmd = HPC_BUS_33CONVMODE;
921                         break;
922                 case HPC_SLOT_SPEED_66:
923                         if (SLOT_PCIX(slot_cur->ext_status)) {
924                                 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
925                                                 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
926                                         cmd = HPC_BUS_66PCIXMODE;
927                                 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
928                                         /* if max slot/bus capability is 66 pci
929                                         and there's no bus mode mismatch, then
930                                         the adapter supports 66 pci */ 
931                                         cmd = HPC_BUS_66CONVMODE;
932                                 else
933                                         cmd = HPC_BUS_33CONVMODE;
934                         } else {
935                                 if (slot_cur->supported_speed >= BUS_SPEED_66)
936                                         cmd = HPC_BUS_66CONVMODE;
937                                 else
938                                         cmd = HPC_BUS_33CONVMODE;
939                         }
940                         break;
941                 case HPC_SLOT_SPEED_133:
942                         switch (slot_cur->supported_speed) {
943                         case BUS_SPEED_33:
944                                 cmd = HPC_BUS_33CONVMODE;
945                                 break;
946                         case BUS_SPEED_66:
947                                 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
948                                         cmd = HPC_BUS_66PCIXMODE;
949                                 else
950                                         cmd = HPC_BUS_66CONVMODE;
951                                 break;
952                         case BUS_SPEED_100:
953                                 cmd = HPC_BUS_100PCIXMODE;
954                                 break;
955                         case BUS_SPEED_133:
956                                 /* This is to take care of the bug in CIOBX chip */
957                                 if (pci_dev_present(ciobx))
958                                         ibmphp_hpc_writeslot(slot_cur,
959                                                         HPC_BUS_100PCIXMODE);
960                                 cmd = HPC_BUS_133PCIXMODE;
961                                 break;
962                         default:
963                                 err("Wrong bus speed\n");
964                                 return -ENODEV;
965                         }
966                         break;
967                 default:
968                         err("wrong slot speed\n");
969                         return -ENODEV;
970                 }
971                 debug("setting bus speed for slot %d, cmd %x\n",
972                                                 slot_cur->number, cmd);
973                 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
974                 if (retval) {
975                         err("setting bus speed failed\n");
976                         return retval;
977                 }
978                 if (CTLR_RESULT(slot_cur->ctrl->status)) {
979                         err("command not completed successfully in set_bus\n");
980                         return -EIO;
981                 }
982         }
983         /* This is for x440, once Brandon fixes the firmware, 
984         will not need this delay */
985         msleep(1000);
986         debug("%s -Exit\n", __func__);
987         return 0;
988 }
989
990 /* This routine checks the bus limitations that the slot is on from the BIOS.
991  * This is used in deciding whether or not to power up the slot.  
992  * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
993  * same bus) 
994  * Parameters: slot
995  * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
996  */
997 static int check_limitations(struct slot *slot_cur)
998 {
999         u8 i;
1000         struct slot * tmp_slot;
1001         u8 count = 0;
1002         u8 limitation = 0;
1003
1004         for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
1005                 tmp_slot = ibmphp_get_slot_from_physical_num(i);
1006                 if (!tmp_slot)
1007                         return -ENODEV;
1008                 if ((SLOT_PWRGD(tmp_slot->status)) &&
1009                                         !(SLOT_CONNECT(tmp_slot->status)))
1010                         count++;
1011         }
1012         get_cur_bus_info(&slot_cur);
1013         switch (slot_cur->bus_on->current_speed) {
1014         case BUS_SPEED_33:
1015                 limitation = slot_cur->bus_on->slots_at_33_conv;
1016                 break;
1017         case BUS_SPEED_66:
1018                 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1019                         limitation = slot_cur->bus_on->slots_at_66_pcix;
1020                 else
1021                         limitation = slot_cur->bus_on->slots_at_66_conv;
1022                 break;
1023         case BUS_SPEED_100:
1024                 limitation = slot_cur->bus_on->slots_at_100_pcix;
1025                 break;
1026         case BUS_SPEED_133:
1027                 limitation = slot_cur->bus_on->slots_at_133_pcix;
1028                 break;
1029         }
1030
1031         if ((count + 1) > limitation)
1032                 return -EINVAL;
1033         return 0;
1034 }
1035
1036 static inline void print_card_capability(struct slot *slot_cur)
1037 {
1038         info("capability of the card is ");
1039         if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
1040                 info("   133 MHz PCI-X\n");
1041         else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1042                 info("    66 MHz PCI-X\n");
1043         else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1044                 info("    66 MHz PCI\n");
1045         else
1046                 info("    33 MHz PCI\n");
1047
1048 }
1049
1050 /* This routine will power on the slot, configure the device(s) and find the
1051  * drivers for them.
1052  * Parameters: hotplug_slot
1053  * Returns: 0 or failure codes
1054  */
1055 static int enable_slot(struct hotplug_slot *hs)
1056 {
1057         int rc, i, rcpr;
1058         struct slot *slot_cur;
1059         u8 function;
1060         struct pci_func *tmp_func;
1061
1062         ibmphp_lock_operations();
1063
1064         debug("ENABLING SLOT........\n");
1065         slot_cur = hs->private;
1066
1067         if ((rc = validate(slot_cur, ENABLE))) {
1068                 err("validate function failed\n");
1069                 goto error_nopower;
1070         }
1071
1072         attn_LED_blink(slot_cur);
1073         
1074         rc = set_bus(slot_cur);
1075         if (rc) {
1076                 err("was not able to set the bus\n");
1077                 goto error_nopower;
1078         }
1079
1080         /*-----------------debugging------------------------------*/
1081         get_cur_bus_info(&slot_cur);
1082         debug("the current bus speed right after set_bus = %x\n",
1083                                         slot_cur->bus_on->current_speed);
1084         /*----------------------------------------------------------*/
1085
1086         rc = check_limitations(slot_cur);
1087         if (rc) {
1088                 err("Adding this card exceeds the limitations of this bus.\n");
1089                 err("(i.e., >1 133MHz cards running on same bus, or "
1090                      ">2 66 PCI cards running on same bus.\n");
1091                 err("Try hot-adding into another bus\n");
1092                 rc = -EINVAL;
1093                 goto error_nopower;
1094         }
1095
1096         rc = power_on(slot_cur);
1097
1098         if (rc) {
1099                 err("something wrong when powering up... please see below for details\n");
1100                 /* need to turn off before on, otherwise, blinking overwrites */
1101                 attn_off(slot_cur);
1102                 attn_on(slot_cur);
1103                 if (slot_update(&slot_cur)) {
1104                         attn_off(slot_cur);
1105                         attn_on(slot_cur);
1106                         rc = -ENODEV;
1107                         goto exit;
1108                 }
1109                 /* Check to see the error of why it failed */
1110                 if ((SLOT_POWER(slot_cur->status)) &&
1111                                         !(SLOT_PWRGD(slot_cur->status)))
1112                         err("power fault occurred trying to power up\n");
1113                 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1114                         err("bus speed mismatch occurred.  please check "
1115                                 "current bus speed and card capability\n");
1116                         print_card_capability(slot_cur);
1117                 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1118                         err("bus mode mismatch occurred.  please check "
1119                                 "current bus mode and card capability\n");
1120                         print_card_capability(slot_cur);
1121                 }
1122                 ibmphp_update_slot_info(slot_cur);
1123                 goto exit;
1124         }
1125         debug("after power_on\n");
1126         /*-----------------------debugging---------------------------*/
1127         get_cur_bus_info(&slot_cur);
1128         debug("the current bus speed right after power_on = %x\n",
1129                                         slot_cur->bus_on->current_speed);
1130         /*----------------------------------------------------------*/
1131
1132         rc = slot_update(&slot_cur);
1133         if (rc)
1134                 goto error_power;
1135         
1136         rc = -EINVAL;
1137         if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1138                 err("power fault occurred trying to power up...\n");
1139                 goto error_power;
1140         }
1141         if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1142                 err("bus speed mismatch occurred.  please check current bus "
1143                                         "speed and card capability\n");
1144                 print_card_capability(slot_cur);
1145                 goto error_power;
1146         } 
1147         /* Don't think this case will happen after above checks...
1148          * but just in case, for paranoia sake */
1149         if (!(SLOT_POWER(slot_cur->status))) {
1150                 err("power on failed...\n");
1151                 goto error_power;
1152         }
1153
1154         slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1155         if (!slot_cur->func) {
1156                 /* We cannot do update_slot_info here, since no memory for
1157                  * kmalloc n.e.ways, and update_slot_info allocates some */
1158                 err("out of system memory\n");
1159                 rc = -ENOMEM;
1160                 goto error_power;
1161         }
1162         slot_cur->func->busno = slot_cur->bus;
1163         slot_cur->func->device = slot_cur->device;
1164         for (i = 0; i < 4; i++)
1165                 slot_cur->func->irq[i] = slot_cur->irq[i];
1166
1167         debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1168                                         slot_cur->bus, slot_cur->device);
1169
1170         if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1171                 err("configure_card was unsuccessful...\n");
1172                 /* true because don't need to actually deallocate resources,
1173                  * just remove references */
1174                 ibmphp_unconfigure_card(&slot_cur, 1);
1175                 debug("after unconfigure_card\n");
1176                 slot_cur->func = NULL;
1177                 rc = -ENOMEM;
1178                 goto error_power;
1179         }
1180
1181         function = 0x00;
1182         do {
1183                 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1184                                                         function++);
1185                 if (tmp_func && !(tmp_func->dev))
1186                         ibm_configure_device(tmp_func);
1187         } while (tmp_func);
1188
1189         attn_off(slot_cur);
1190         if (slot_update(&slot_cur)) {
1191                 rc = -EFAULT;
1192                 goto exit;
1193         }
1194         ibmphp_print_test();
1195         rc = ibmphp_update_slot_info(slot_cur);
1196 exit:
1197         ibmphp_unlock_operations(); 
1198         return rc;
1199
1200 error_nopower:
1201         attn_off(slot_cur);     /* need to turn off if was blinking b4 */
1202         attn_on(slot_cur);
1203 error_cont:
1204         rcpr = slot_update(&slot_cur);
1205         if (rcpr) {
1206                 rc = rcpr;
1207                 goto exit;
1208         }
1209         ibmphp_update_slot_info(slot_cur);
1210         goto exit;
1211
1212 error_power:
1213         attn_off(slot_cur);     /* need to turn off if was blinking b4 */
1214         attn_on(slot_cur);
1215         rcpr = power_off(slot_cur);
1216         if (rcpr) {
1217                 rc = rcpr;
1218                 goto exit;
1219         }
1220         goto error_cont;
1221 }
1222
1223 /**************************************************************
1224 * HOT REMOVING ADAPTER CARD                                   *
1225 * INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
1226 * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
1227           DISABLE POWER ,                                    *
1228 **************************************************************/
1229 static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1230 {
1231         struct slot *slot = hotplug_slot->private;
1232         int rc;
1233         
1234         ibmphp_lock_operations();
1235         rc = ibmphp_do_disable_slot(slot);
1236         ibmphp_unlock_operations();
1237         return rc;
1238 }
1239
1240 int ibmphp_do_disable_slot(struct slot *slot_cur)
1241 {
1242         int rc;
1243         u8 flag;
1244
1245         debug("DISABLING SLOT...\n"); 
1246                 
1247         if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1248                 return -ENODEV;
1249         }
1250         
1251         flag = slot_cur->flag;
1252         slot_cur->flag = 1;
1253
1254         if (flag == 1) {
1255                 rc = validate(slot_cur, DISABLE);
1256                         /* checking if powered off already & valid slot # */
1257                 if (rc)
1258                         goto error;
1259         }
1260         attn_LED_blink(slot_cur);
1261
1262         if (slot_cur->func == NULL) {
1263                 /* We need this for fncs's that were there on bootup */
1264                 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1265                 if (!slot_cur->func) {
1266                         err("out of system memory\n");
1267                         rc = -ENOMEM;
1268                         goto error;
1269                 }
1270                 slot_cur->func->busno = slot_cur->bus;
1271                 slot_cur->func->device = slot_cur->device;
1272         }
1273
1274         ibm_unconfigure_device(slot_cur->func);
1275         
1276         /* If we got here from latch suddenly opening on operating card or 
1277         a power fault, there's no power to the card, so cannot
1278         read from it to determine what resources it occupied.  This operation
1279         is forbidden anyhow.  The best we can do is remove it from kernel
1280         lists at least */
1281
1282         if (!flag) {
1283                 attn_off(slot_cur);
1284                 return 0;
1285         }
1286
1287         rc = ibmphp_unconfigure_card(&slot_cur, 0);
1288         slot_cur->func = NULL;
1289         debug("in disable_slot. after unconfigure_card\n");
1290         if (rc) {
1291                 err("could not unconfigure card.\n");
1292                 goto error;
1293         }
1294
1295         rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1296         if (rc)
1297                 goto error;
1298
1299         attn_off(slot_cur);
1300         rc = slot_update(&slot_cur);
1301         if (rc)
1302                 goto exit;
1303
1304         rc = ibmphp_update_slot_info(slot_cur);
1305         ibmphp_print_test();
1306 exit:
1307         return rc;
1308
1309 error:
1310         /*  Need to turn off if was blinking b4 */
1311         attn_off(slot_cur);
1312         attn_on(slot_cur);
1313         if (slot_update(&slot_cur)) {
1314                 rc = -EFAULT;
1315                 goto exit;
1316         }
1317         if (flag)               
1318                 ibmphp_update_slot_info(slot_cur);
1319         goto exit;
1320 }
1321
1322 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1323         .owner =                        THIS_MODULE,
1324         .set_attention_status =         set_attention_status,
1325         .enable_slot =                  enable_slot,
1326         .disable_slot =                 ibmphp_disable_slot,
1327         .hardware_test =                NULL,
1328         .get_power_status =             get_power_status,
1329         .get_attention_status =         get_attention_status,
1330         .get_latch_status =             get_latch_status,
1331         .get_adapter_status =           get_adapter_present,
1332         .get_max_bus_speed =            get_max_bus_speed,
1333         .get_cur_bus_speed =            get_cur_bus_speed,
1334 /*      .get_max_adapter_speed =        get_max_adapter_speed,
1335         .get_bus_name_status =          get_bus_name,
1336 */
1337 };
1338
1339 static void ibmphp_unload(void)
1340 {
1341         free_slots();
1342         debug("after slots\n");
1343         ibmphp_free_resources();
1344         debug("after resources\n");
1345         ibmphp_free_bus_info_queue();
1346         debug("after bus info\n");
1347         ibmphp_free_ebda_hpc_queue();
1348         debug("after ebda hpc\n");
1349         ibmphp_free_ebda_pci_rsrc_queue();
1350         debug("after ebda pci rsrc\n");
1351         kfree(ibmphp_pci_bus);
1352 }
1353
1354 static int __init ibmphp_init(void)
1355 {
1356         struct pci_bus *bus;
1357         int i = 0;
1358         int rc = 0;
1359
1360         init_flag = 1;
1361
1362         info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1363
1364         ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1365         if (!ibmphp_pci_bus) {
1366                 err("out of memory\n");
1367                 rc = -ENOMEM;
1368                 goto exit;
1369         }
1370
1371         bus = pci_find_bus(0, 0);
1372         if (!bus) {
1373                 err("Can't find the root pci bus, can not continue\n");
1374                 rc = -ENODEV;
1375                 goto error;
1376         }
1377         memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1378
1379         ibmphp_debug = debug;
1380
1381         ibmphp_hpc_initvars();
1382
1383         for (i = 0; i < 16; i++)
1384                 irqs[i] = 0;
1385
1386         if ((rc = ibmphp_access_ebda()))
1387                 goto error;
1388         debug("after ibmphp_access_ebda()\n");
1389
1390         if ((rc = ibmphp_rsrc_init()))
1391                 goto error;
1392         debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1393
1394         max_slots = get_max_slots();
1395         
1396         if ((rc = ibmphp_register_pci()))
1397                 goto error;
1398
1399         if (init_ops()) {
1400                 rc = -ENODEV;
1401                 goto error;
1402         }
1403
1404         ibmphp_print_test();
1405         if ((rc = ibmphp_hpc_start_poll_thread())) {
1406                 goto error;
1407         }
1408
1409 exit:
1410         return rc;
1411
1412 error:
1413         ibmphp_unload();
1414         goto exit;
1415 }
1416
1417 static void __exit ibmphp_exit(void)
1418 {
1419         ibmphp_hpc_stop_poll_thread();
1420         debug("after polling\n");
1421         ibmphp_unload();
1422         debug("done\n");
1423 }
1424
1425 module_init(ibmphp_init);