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