Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
[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 "../../../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_find_slot(func->busno, (func->device << 3) | j);
765                 if (temp)
766                         pci_remove_bus_device(temp);
767         }
768 }
769
770 /*
771  * The following function is to fix kernel bug regarding 
772  * getting bus entries, here we manually add those primary 
773  * bus entries to kernel bus structure whenever apply
774  */
775 static u8 bus_structure_fixup(u8 busno)
776 {
777         struct pci_bus *bus;
778         struct pci_dev *dev;
779         u16 l;
780
781         if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
782                 return 1;
783
784         bus = kmalloc(sizeof(*bus), GFP_KERNEL);
785         if (!bus) {
786                 err("%s - out of memory\n", __FUNCTION__);
787                 return 1;
788         }
789         dev = kmalloc(sizeof(*dev), GFP_KERNEL);
790         if (!dev) {
791                 kfree(bus);
792                 err("%s - out of memory\n", __FUNCTION__);
793                 return 1;
794         }
795
796         bus->number = busno;
797         bus->ops = ibmphp_pci_bus->ops;
798         dev->bus = bus;
799         for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
800                 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
801                                         (l != 0x0000) && (l != 0xffff)) {
802                         debug("%s - Inside bus_struture_fixup()\n",
803                                                         __FUNCTION__);
804                         pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
805                         break;
806                 }
807         }
808
809         kfree(dev);
810         kfree(bus);
811
812         return 0;
813 }
814
815 static int ibm_configure_device(struct pci_func *func)
816 {
817         unsigned char bus;
818         struct pci_bus *child;
819         int num;
820         int flag = 0;   /* this is to make sure we don't double scan the bus,
821                                         for bridged devices primarily */
822
823         if (!(bus_structure_fixup(func->busno)))
824                 flag = 1;
825         if (func->dev == NULL)
826                 func->dev = pci_find_slot(func->busno,
827                                 PCI_DEVFN(func->device, func->function));
828
829         if (func->dev == NULL) {
830                 struct pci_bus *bus = pci_find_bus(0, func->busno);
831                 if (!bus)
832                         return 0;
833
834                 num = pci_scan_slot(bus,
835                                 PCI_DEVFN(func->device, func->function));
836                 if (num)
837                         pci_bus_add_devices(bus);
838
839                 func->dev = pci_find_slot(func->busno,
840                                 PCI_DEVFN(func->device, func->function));
841                 if (func->dev == NULL) {
842                         err("ERROR... : pci_dev still NULL\n");
843                         return 0;
844                 }
845         }
846         if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
847                 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
848                 child = pci_add_new_bus(func->dev->bus, func->dev, bus);
849                 pci_do_scan_bus(child);
850         }
851
852         return 0;
853 }
854
855 /*******************************************************
856  * Returns whether the bus is empty or not 
857  *******************************************************/
858 static int is_bus_empty(struct slot * slot_cur)
859 {
860         int rc;
861         struct slot * tmp_slot;
862         u8 i = slot_cur->bus_on->slot_min;
863
864         while (i <= slot_cur->bus_on->slot_max) {
865                 if (i == slot_cur->number) {
866                         i++;
867                         continue;
868                 }
869                 tmp_slot = ibmphp_get_slot_from_physical_num(i);
870                 if (!tmp_slot)
871                         return 0;
872                 rc = slot_update(&tmp_slot);
873                 if (rc)
874                         return 0;
875                 if (SLOT_PRESENT(tmp_slot->status) &&
876                                         SLOT_PWRGD(tmp_slot->status))
877                         return 0;
878                 i++;
879         }
880         return 1;
881 }
882
883 /***********************************************************
884  * If the HPC permits and the bus currently empty, tries to set the 
885  * bus speed and mode at the maximum card and bus capability
886  * Parameters: slot
887  * Returns: bus is set (0) or error code
888  ***********************************************************/
889 static int set_bus(struct slot * slot_cur)
890 {
891         int rc;
892         u8 speed;
893         u8 cmd = 0x0;
894         int retval;
895         static struct pci_device_id ciobx[] = {
896                 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
897                 { },
898         };      
899
900         debug("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
901         if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
902                 rc = slot_update(&slot_cur);
903                 if (rc)
904                         return rc;
905                 speed = SLOT_SPEED(slot_cur->ext_status);
906                 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
907                 switch (speed) {
908                 case HPC_SLOT_SPEED_33:
909                         cmd = HPC_BUS_33CONVMODE;
910                         break;
911                 case HPC_SLOT_SPEED_66:
912                         if (SLOT_PCIX(slot_cur->ext_status)) {
913                                 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
914                                                 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
915                                         cmd = HPC_BUS_66PCIXMODE;
916                                 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
917                                         /* if max slot/bus capability is 66 pci
918                                         and there's no bus mode mismatch, then
919                                         the adapter supports 66 pci */ 
920                                         cmd = HPC_BUS_66CONVMODE;
921                                 else
922                                         cmd = HPC_BUS_33CONVMODE;
923                         } else {
924                                 if (slot_cur->supported_speed >= BUS_SPEED_66)
925                                         cmd = HPC_BUS_66CONVMODE;
926                                 else
927                                         cmd = HPC_BUS_33CONVMODE;
928                         }
929                         break;
930                 case HPC_SLOT_SPEED_133:
931                         switch (slot_cur->supported_speed) {
932                         case BUS_SPEED_33:
933                                 cmd = HPC_BUS_33CONVMODE;
934                                 break;
935                         case BUS_SPEED_66:
936                                 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
937                                         cmd = HPC_BUS_66PCIXMODE;
938                                 else
939                                         cmd = HPC_BUS_66CONVMODE;
940                                 break;
941                         case BUS_SPEED_100:
942                                 cmd = HPC_BUS_100PCIXMODE;
943                                 break;
944                         case BUS_SPEED_133:
945                                 /* This is to take care of the bug in CIOBX chip */
946                                 if (pci_dev_present(ciobx))
947                                         ibmphp_hpc_writeslot(slot_cur,
948                                                         HPC_BUS_100PCIXMODE);
949                                 cmd = HPC_BUS_133PCIXMODE;
950                                 break;
951                         default:
952                                 err("Wrong bus speed\n");
953                                 return -ENODEV;
954                         }
955                         break;
956                 default:
957                         err("wrong slot speed\n");
958                         return -ENODEV;
959                 }
960                 debug("setting bus speed for slot %d, cmd %x\n",
961                                                 slot_cur->number, cmd);
962                 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
963                 if (retval) {
964                         err("setting bus speed failed\n");
965                         return retval;
966                 }
967                 if (CTLR_RESULT(slot_cur->ctrl->status)) {
968                         err("command not completed successfully in set_bus\n");
969                         return -EIO;
970                 }
971         }
972         /* This is for x440, once Brandon fixes the firmware, 
973         will not need this delay */
974         msleep(1000);
975         debug("%s -Exit\n", __FUNCTION__);
976         return 0;
977 }
978
979 /* This routine checks the bus limitations that the slot is on from the BIOS.
980  * This is used in deciding whether or not to power up the slot.  
981  * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
982  * same bus) 
983  * Parameters: slot
984  * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
985  */
986 static int check_limitations(struct slot *slot_cur)
987 {
988         u8 i;
989         struct slot * tmp_slot;
990         u8 count = 0;
991         u8 limitation = 0;
992
993         for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
994                 tmp_slot = ibmphp_get_slot_from_physical_num(i);
995                 if (!tmp_slot)
996                         return -ENODEV;
997                 if ((SLOT_PWRGD(tmp_slot->status)) &&
998                                         !(SLOT_CONNECT(tmp_slot->status)))
999                         count++;
1000         }
1001         get_cur_bus_info(&slot_cur);
1002         switch (slot_cur->bus_on->current_speed) {
1003         case BUS_SPEED_33:
1004                 limitation = slot_cur->bus_on->slots_at_33_conv;
1005                 break;
1006         case BUS_SPEED_66:
1007                 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1008                         limitation = slot_cur->bus_on->slots_at_66_pcix;
1009                 else
1010                         limitation = slot_cur->bus_on->slots_at_66_conv;
1011                 break;
1012         case BUS_SPEED_100:
1013                 limitation = slot_cur->bus_on->slots_at_100_pcix;
1014                 break;
1015         case BUS_SPEED_133:
1016                 limitation = slot_cur->bus_on->slots_at_133_pcix;
1017                 break;
1018         }
1019
1020         if ((count + 1) > limitation)
1021                 return -EINVAL;
1022         return 0;
1023 }
1024
1025 static inline void print_card_capability(struct slot *slot_cur)
1026 {
1027         info("capability of the card is ");
1028         if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
1029                 info("   133 MHz PCI-X\n");
1030         else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1031                 info("    66 MHz PCI-X\n");
1032         else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1033                 info("    66 MHz PCI\n");
1034         else
1035                 info("    33 MHz PCI\n");
1036
1037 }
1038
1039 /* This routine will power on the slot, configure the device(s) and find the
1040  * drivers for them.
1041  * Parameters: hotplug_slot
1042  * Returns: 0 or failure codes
1043  */
1044 static int enable_slot(struct hotplug_slot *hs)
1045 {
1046         int rc, i, rcpr;
1047         struct slot *slot_cur;
1048         u8 function;
1049         struct pci_func *tmp_func;
1050
1051         ibmphp_lock_operations();
1052
1053         debug("ENABLING SLOT........\n");
1054         slot_cur = hs->private;
1055
1056         if ((rc = validate(slot_cur, ENABLE))) {
1057                 err("validate function failed\n");
1058                 goto error_nopower;
1059         }
1060
1061         attn_LED_blink(slot_cur);
1062         
1063         rc = set_bus(slot_cur);
1064         if (rc) {
1065                 err("was not able to set the bus\n");
1066                 goto error_nopower;
1067         }
1068
1069         /*-----------------debugging------------------------------*/
1070         get_cur_bus_info(&slot_cur);
1071         debug("the current bus speed right after set_bus = %x\n",
1072                                         slot_cur->bus_on->current_speed);
1073         /*----------------------------------------------------------*/
1074
1075         rc = check_limitations(slot_cur);
1076         if (rc) {
1077                 err("Adding this card exceeds the limitations of this bus.\n");
1078                 err("(i.e., >1 133MHz cards running on same bus, or "
1079                      ">2 66 PCI cards running on same bus.\n");
1080                 err("Try hot-adding into another bus\n");
1081                 rc = -EINVAL;
1082                 goto error_nopower;
1083         }
1084
1085         rc = power_on(slot_cur);
1086
1087         if (rc) {
1088                 err("something wrong when powering up... please see below for details\n");
1089                 /* need to turn off before on, otherwise, blinking overwrites */
1090                 attn_off(slot_cur);
1091                 attn_on(slot_cur);
1092                 if (slot_update(&slot_cur)) {
1093                         attn_off(slot_cur);
1094                         attn_on(slot_cur);
1095                         rc = -ENODEV;
1096                         goto exit;
1097                 }
1098                 /* Check to see the error of why it failed */
1099                 if ((SLOT_POWER(slot_cur->status)) &&
1100                                         !(SLOT_PWRGD(slot_cur->status)))
1101                         err("power fault occurred trying to power up\n");
1102                 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1103                         err("bus speed mismatch occurred.  please check "
1104                                 "current bus speed and card capability\n");
1105                         print_card_capability(slot_cur);
1106                 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1107                         err("bus mode mismatch occurred.  please check "
1108                                 "current bus mode and card capability\n");
1109                         print_card_capability(slot_cur);
1110                 }
1111                 ibmphp_update_slot_info(slot_cur);
1112                 goto exit;
1113         }
1114         debug("after power_on\n");
1115         /*-----------------------debugging---------------------------*/
1116         get_cur_bus_info(&slot_cur);
1117         debug("the current bus speed right after power_on = %x\n",
1118                                         slot_cur->bus_on->current_speed);
1119         /*----------------------------------------------------------*/
1120
1121         rc = slot_update(&slot_cur);
1122         if (rc)
1123                 goto error_power;
1124         
1125         rc = -EINVAL;
1126         if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1127                 err("power fault occurred trying to power up...\n");
1128                 goto error_power;
1129         }
1130         if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1131                 err("bus speed mismatch occurred.  please check current bus "
1132                                         "speed and card capability\n");
1133                 print_card_capability(slot_cur);
1134                 goto error_power;
1135         } 
1136         /* Don't think this case will happen after above checks...
1137          * but just in case, for paranoia sake */
1138         if (!(SLOT_POWER(slot_cur->status))) {
1139                 err("power on failed...\n");
1140                 goto error_power;
1141         }
1142
1143         slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1144         if (!slot_cur->func) {
1145                 /* We cannot do update_slot_info here, since no memory for
1146                  * kmalloc n.e.ways, and update_slot_info allocates some */
1147                 err("out of system memory\n");
1148                 rc = -ENOMEM;
1149                 goto error_power;
1150         }
1151         slot_cur->func->busno = slot_cur->bus;
1152         slot_cur->func->device = slot_cur->device;
1153         for (i = 0; i < 4; i++)
1154                 slot_cur->func->irq[i] = slot_cur->irq[i];
1155
1156         debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1157                                         slot_cur->bus, slot_cur->device);
1158
1159         if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1160                 err("configure_card was unsuccessful...\n");
1161                 /* true because don't need to actually deallocate resources,
1162                  * just remove references */
1163                 ibmphp_unconfigure_card(&slot_cur, 1);
1164                 debug("after unconfigure_card\n");
1165                 slot_cur->func = NULL;
1166                 rc = -ENOMEM;
1167                 goto error_power;
1168         }
1169
1170         function = 0x00;
1171         do {
1172                 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1173                                                         function++);
1174                 if (tmp_func && !(tmp_func->dev))
1175                         ibm_configure_device(tmp_func);
1176         } while (tmp_func);
1177
1178         attn_off(slot_cur);
1179         if (slot_update(&slot_cur)) {
1180                 rc = -EFAULT;
1181                 goto exit;
1182         }
1183         ibmphp_print_test();
1184         rc = ibmphp_update_slot_info(slot_cur);
1185 exit:
1186         ibmphp_unlock_operations(); 
1187         return rc;
1188
1189 error_nopower:
1190         attn_off(slot_cur);     /* need to turn off if was blinking b4 */
1191         attn_on(slot_cur);
1192 error_cont:
1193         rcpr = slot_update(&slot_cur);
1194         if (rcpr) {
1195                 rc = rcpr;
1196                 goto exit;
1197         }
1198         ibmphp_update_slot_info(slot_cur);
1199         goto exit;
1200
1201 error_power:
1202         attn_off(slot_cur);     /* need to turn off if was blinking b4 */
1203         attn_on(slot_cur);
1204         rcpr = power_off(slot_cur);
1205         if (rcpr) {
1206                 rc = rcpr;
1207                 goto exit;
1208         }
1209         goto error_cont;
1210 }
1211
1212 /**************************************************************
1213 * HOT REMOVING ADAPTER CARD                                   *
1214 * INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
1215 * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
1216           DISABLE POWER ,                                    *
1217 **************************************************************/
1218 static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1219 {
1220         struct slot *slot = hotplug_slot->private;
1221         int rc;
1222         
1223         ibmphp_lock_operations();
1224         rc = ibmphp_do_disable_slot(slot);
1225         ibmphp_unlock_operations();
1226         return rc;
1227 }
1228
1229 int ibmphp_do_disable_slot(struct slot *slot_cur)
1230 {
1231         int rc;
1232         u8 flag;
1233
1234         debug("DISABLING SLOT...\n"); 
1235                 
1236         if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1237                 return -ENODEV;
1238         }
1239         
1240         flag = slot_cur->flag;
1241         slot_cur->flag = 1;
1242
1243         if (flag == 1) {
1244                 rc = validate(slot_cur, DISABLE);
1245                         /* checking if powered off already & valid slot # */
1246                 if (rc)
1247                         goto error;
1248         }
1249         attn_LED_blink(slot_cur);
1250
1251         if (slot_cur->func == NULL) {
1252                 /* We need this for fncs's that were there on bootup */
1253                 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1254                 if (!slot_cur->func) {
1255                         err("out of system memory\n");
1256                         rc = -ENOMEM;
1257                         goto error;
1258                 }
1259                 slot_cur->func->busno = slot_cur->bus;
1260                 slot_cur->func->device = slot_cur->device;
1261         }
1262
1263         ibm_unconfigure_device(slot_cur->func);
1264         
1265         /* If we got here from latch suddenly opening on operating card or 
1266         a power fault, there's no power to the card, so cannot
1267         read from it to determine what resources it occupied.  This operation
1268         is forbidden anyhow.  The best we can do is remove it from kernel
1269         lists at least */
1270
1271         if (!flag) {
1272                 attn_off(slot_cur);
1273                 return 0;
1274         }
1275
1276         rc = ibmphp_unconfigure_card(&slot_cur, 0);
1277         slot_cur->func = NULL;
1278         debug("in disable_slot. after unconfigure_card\n");
1279         if (rc) {
1280                 err("could not unconfigure card.\n");
1281                 goto error;
1282         }
1283
1284         rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1285         if (rc)
1286                 goto error;
1287
1288         attn_off(slot_cur);
1289         rc = slot_update(&slot_cur);
1290         if (rc)
1291                 goto exit;
1292
1293         rc = ibmphp_update_slot_info(slot_cur);
1294         ibmphp_print_test();
1295 exit:
1296         return rc;
1297
1298 error:
1299         /*  Need to turn off if was blinking b4 */
1300         attn_off(slot_cur);
1301         attn_on(slot_cur);
1302         if (slot_update(&slot_cur)) {
1303                 rc = -EFAULT;
1304                 goto exit;
1305         }
1306         if (flag)               
1307                 ibmphp_update_slot_info(slot_cur);
1308         goto exit;
1309 }
1310
1311 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1312         .owner =                        THIS_MODULE,
1313         .set_attention_status =         set_attention_status,
1314         .enable_slot =                  enable_slot,
1315         .disable_slot =                 ibmphp_disable_slot,
1316         .hardware_test =                NULL,
1317         .get_power_status =             get_power_status,
1318         .get_attention_status =         get_attention_status,
1319         .get_latch_status =             get_latch_status,
1320         .get_adapter_status =           get_adapter_present,
1321         .get_max_bus_speed =            get_max_bus_speed,
1322         .get_cur_bus_speed =            get_cur_bus_speed,
1323 /*      .get_max_adapter_speed =        get_max_adapter_speed,
1324         .get_bus_name_status =          get_bus_name,
1325 */
1326 };
1327
1328 static void ibmphp_unload(void)
1329 {
1330         free_slots();
1331         debug("after slots\n");
1332         ibmphp_free_resources();
1333         debug("after resources\n");
1334         ibmphp_free_bus_info_queue();
1335         debug("after bus info\n");
1336         ibmphp_free_ebda_hpc_queue();
1337         debug("after ebda hpc\n");
1338         ibmphp_free_ebda_pci_rsrc_queue();
1339         debug("after ebda pci rsrc\n");
1340         kfree(ibmphp_pci_bus);
1341 }
1342
1343 static int __init ibmphp_init(void)
1344 {
1345         struct pci_bus *bus;
1346         int i = 0;
1347         int rc = 0;
1348
1349         init_flag = 1;
1350
1351         info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1352
1353         ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1354         if (!ibmphp_pci_bus) {
1355                 err("out of memory\n");
1356                 rc = -ENOMEM;
1357                 goto exit;
1358         }
1359
1360         bus = pci_find_bus(0, 0);
1361         if (!bus) {
1362                 err("Can't find the root pci bus, can not continue\n");
1363                 rc = -ENODEV;
1364                 goto error;
1365         }
1366         memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1367
1368         ibmphp_debug = debug;
1369
1370         ibmphp_hpc_initvars();
1371
1372         for (i = 0; i < 16; i++)
1373                 irqs[i] = 0;
1374
1375         if ((rc = ibmphp_access_ebda()))
1376                 goto error;
1377         debug("after ibmphp_access_ebda()\n");
1378
1379         if ((rc = ibmphp_rsrc_init()))
1380                 goto error;
1381         debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1382
1383         max_slots = get_max_slots();
1384         
1385         if ((rc = ibmphp_register_pci()))
1386                 goto error;
1387
1388         if (init_ops()) {
1389                 rc = -ENODEV;
1390                 goto error;
1391         }
1392
1393         ibmphp_print_test();
1394         if ((rc = ibmphp_hpc_start_poll_thread())) {
1395                 goto error;
1396         }
1397
1398         /* lock ourselves into memory with a module 
1399          * count of -1 so that no one can unload us. */
1400         module_put(THIS_MODULE);
1401
1402 exit:
1403         return rc;
1404
1405 error:
1406         ibmphp_unload();
1407         goto exit;
1408 }
1409
1410 static void __exit ibmphp_exit(void)
1411 {
1412         ibmphp_hpc_stop_poll_thread();
1413         debug("after polling\n");
1414         ibmphp_unload();
1415         debug("done\n");
1416 }
1417
1418 module_init(ibmphp_init);
1419 module_exit(ibmphp_exit);