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