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