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