import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / 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 Greg Kroah-Hartman (greg@kroah.com)
7  * Copyright (C) 2001,2002 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 "../../arch/i386/kernel/pci-i386.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_PARM (debug, "i");
54 MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
55 MODULE_LICENSE ("GPL");
56 MODULE_DESCRIPTION (DRIVER_DESC);
57
58 static int *ops[MAX_OPS + 1];
59 struct pci_ops *ibmphp_pci_root_ops;
60 static int max_slots;
61
62 static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS 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 = CURRENT_BUS_MODE (slot_cur->busstatus);
91         else
92                 slot_cur->bus_on->current_bus_mode = 0xFF;
93
94         debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
95         
96         *sl = slot_cur;
97         return 0;
98 }
99
100 static inline int slot_update (struct slot **sl)
101 {
102         int rc;
103         rc = ibmphp_hpc_readslot (*sl, READ_ALLSTAT, NULL);
104         if (rc) 
105                 return rc;
106         if (!init_flag)
107                 return get_cur_bus_info (sl);
108         return rc;
109 }
110
111 static int __init get_max_slots (void)
112 {
113         struct slot * slot_cur;
114         struct list_head * tmp;
115         u8 slot_count = 0;
116
117         list_for_each (tmp, &ibmphp_slot_head) {
118                 slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
119                 /* sometimes the hot-pluggable slots start with 4 (not always from 1 */
120                 slot_count = max (slot_count, slot_cur->number);
121         }
122         return slot_count;
123 }
124
125 /* This routine will put the correct slot->device information per slot.  It's
126  * called from initialization of the slot structures. It will also assign
127  * interrupt numbers per each slot.
128  * Parameters: struct slot
129  * Returns 0 or errors
130  */
131 int ibmphp_init_devno (struct slot **cur_slot)
132 {
133         struct irq_routing_table *rtable;
134         int len;
135         int loop;
136         int i;
137
138         rtable = pcibios_get_irq_routing_table ();
139         if (!rtable) {
140                 err ("no BIOS routing table...\n");
141                 return -ENOMEM;
142         }
143
144         len = (rtable->size - sizeof (struct irq_routing_table)) / sizeof (struct irq_info);
145
146         if (!len)
147                 return -1;
148         for (loop = 0; loop < len; loop++) {
149                 if ((*cur_slot)->number == rtable->slots[loop].slot) {
150                 if ((*cur_slot)->bus == rtable->slots[loop].bus) {
151                         (*cur_slot)->device = PCI_SLOT (rtable->slots[loop].devfn);
152                         for (i = 0; i < 4; i++)
153                                 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector ((int) (*cur_slot)->bus, (int) (*cur_slot)->device, i);
154
155                                 debug ("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]);
156                                 debug ("(*cur_slot)->irq[1] = %x\n", (*cur_slot)->irq[1]);
157                                 debug ("(*cur_slot)->irq[2] = %x\n", (*cur_slot)->irq[2]);
158                                 debug ("(*cur_slot)->irq[3] = %x\n", (*cur_slot)->irq[3]);
159
160                                 debug ("rtable->exlusive_irqs = %x\n", rtable->exclusive_irqs);
161                                 debug ("rtable->slots[loop].irq[0].bitmap = %x\n", rtable->slots[loop].irq[0].bitmap);
162                                 debug ("rtable->slots[loop].irq[1].bitmap = %x\n", rtable->slots[loop].irq[1].bitmap);
163                                 debug ("rtable->slots[loop].irq[2].bitmap = %x\n", rtable->slots[loop].irq[2].bitmap);
164                                 debug ("rtable->slots[loop].irq[3].bitmap = %x\n", rtable->slots[loop].irq[3].bitmap);
165
166                                 debug ("rtable->slots[loop].irq[0].link= %x\n", rtable->slots[loop].irq[0].link);
167                                 debug ("rtable->slots[loop].irq[1].link = %x\n", rtable->slots[loop].irq[1].link);
168                                 debug ("rtable->slots[loop].irq[2].link = %x\n", rtable->slots[loop].irq[2].link);
169                                 debug ("rtable->slots[loop].irq[3].link = %x\n", rtable->slots[loop].irq[3].link);
170                                 debug ("end of init_devno\n");
171                                 return 0;
172                         }
173                 }
174         }
175
176         return -1;
177 }
178
179 static inline int power_on (struct slot *slot_cur)
180 {
181         u8 cmd = HPC_SLOT_ON;
182         int retval;
183
184         retval = ibmphp_hpc_writeslot (slot_cur, cmd);
185         if (retval) {
186                 err ("power on failed\n");
187                 return retval;
188         }
189         if (CTLR_RESULT (slot_cur->ctrl->status)) {
190                 err ("command not completed successfully in power_on \n");
191                 return -EIO;
192         }
193         long_delay (3 * HZ); /* For ServeRAID cards, and some 66 PCI */
194         return 0;
195 }
196
197 static inline int power_off (struct slot *slot_cur)
198 {
199         u8 cmd = HPC_SLOT_OFF;
200         int retval;
201
202         retval = ibmphp_hpc_writeslot (slot_cur, cmd);
203         if (retval) {
204                 err ("power off failed \n");
205                 return retval;
206         }
207         if (CTLR_RESULT (slot_cur->ctrl->status)) {
208                 err ("command not completed successfully in power_off \n");
209                 return -EIO;
210         }
211         return 0;
212 }
213
214 static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 value)
215 {
216         int rc = 0;
217         struct slot *pslot;
218         u8 cmd;
219         int hpcrc = 0;
220
221         debug ("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value);
222         ibmphp_lock_operations ();
223         cmd = 0x00;     // avoid compiler warning
224
225         if (hotplug_slot) {
226                 switch (value) {
227                 case HPC_SLOT_ATTN_OFF:
228                         cmd = HPC_SLOT_ATTNOFF;
229                         break;
230                 case HPC_SLOT_ATTN_ON:
231                         cmd = HPC_SLOT_ATTNON;
232                         break;
233                 case HPC_SLOT_ATTN_BLINK:
234                         cmd = HPC_SLOT_BLINKLED;
235                         break;
236                 default:
237                         rc = -ENODEV;
238                         err ("set_attention_status - Error : invalid input [%x]\n", value);
239                         break;
240                 }
241                 if (rc == 0) {
242                         pslot = (struct slot *) hotplug_slot->private;
243                         if (pslot)
244                                 hpcrc = ibmphp_hpc_writeslot (pslot, cmd);
245                         else
246                                 rc = -ENODEV;
247                 }
248         } else  
249                 rc = -ENODEV;
250
251         if (hpcrc)
252                 rc = hpcrc;
253
254         ibmphp_unlock_operations ();
255
256         debug ("set_attention_status - Exit rc[%d]\n", rc);
257         return rc;
258 }
259
260 static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 * value)
261 {
262         int rc = -ENODEV;
263         struct slot *pslot;
264         int hpcrc = 0;
265         struct slot myslot;
266
267         debug ("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
268         
269         ibmphp_lock_operations ();
270         if (hotplug_slot && value) {
271                 pslot = (struct slot *) hotplug_slot->private;
272                 if (pslot) {
273                         memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
274                         hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
275                         if (!hpcrc)
276                                 hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
277                         if (!hpcrc) {
278                                 *value = SLOT_ATTN (myslot.status, myslot.ext_status);
279                                 rc = 0;
280                         }
281                 }
282         } else
283                 rc = -ENODEV;
284
285         if (hpcrc)
286                 rc = hpcrc;
287
288         ibmphp_unlock_operations ();
289         debug ("get_attention_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
290         return rc;
291 }
292
293 static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 * value)
294 {
295         int rc = -ENODEV;
296         struct slot *pslot;
297         int hpcrc = 0;
298         struct slot myslot;
299
300         debug ("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
301         ibmphp_lock_operations ();
302         if (hotplug_slot && value) {
303                 pslot = (struct slot *) hotplug_slot->private;
304                 if (pslot) {
305                         memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
306                         hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
307                         if (!hpcrc) {
308                                 *value = SLOT_LATCH (myslot.status);
309                                 rc = 0;
310                         }
311                 }
312         } else
313                 rc = -ENODEV;
314
315         if (hpcrc)
316                 rc = hpcrc;
317
318         ibmphp_unlock_operations ();
319         debug ("get_latch_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
320         return rc;
321 }
322
323
324 static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
325 {
326         int rc = -ENODEV;
327         struct slot *pslot;
328         int hpcrc = 0;
329         struct slot myslot;
330
331         debug ("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
332         ibmphp_lock_operations ();
333         if (hotplug_slot && value) {
334                 pslot = (struct slot *) hotplug_slot->private;
335                 if (pslot) {
336                         memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
337                         hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
338                         if (!hpcrc) {
339                                 *value = SLOT_PWRGD (myslot.status);
340                                 rc = 0;
341                         }
342                 }
343         } else
344                 rc = -ENODEV;
345
346         if (hpcrc)
347                 rc = hpcrc;
348
349         ibmphp_unlock_operations ();
350         debug ("get_power_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
351         return rc;
352 }
353
354 static int get_adapter_present (struct hotplug_slot *hotplug_slot, u8 * value)
355 {
356         int rc = -ENODEV;
357         struct slot *pslot;
358         u8 present;
359         int hpcrc = 0;
360         struct slot myslot;
361
362         debug ("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
363         ibmphp_lock_operations ();
364         if (hotplug_slot && value) {
365                 pslot = (struct slot *) hotplug_slot->private;
366                 if (pslot) {
367                         memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
368                         hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
369                         if (!hpcrc) {
370                                 present = SLOT_PRESENT (myslot.status);
371                                 if (present == HPC_SLOT_EMPTY)
372                                         *value = 0;
373                                 else
374                                         *value = 1;
375                                 rc = 0;
376                         }
377                 }
378         } else
379                 rc = -ENODEV;
380         if (hpcrc)
381                 rc = hpcrc;
382
383         ibmphp_unlock_operations ();
384         debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
385         return rc;
386 }
387
388 static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
389 {
390         int rc = -ENODEV;
391         struct slot *pslot;
392         u8 mode = 0;
393
394         debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
395                 hotplug_slot, value);
396
397         ibmphp_lock_operations ();
398
399         if (hotplug_slot && value) {
400                 pslot = (struct slot *) hotplug_slot->private;
401                 if (pslot) {
402                         rc = 0;
403                         mode = pslot->supported_bus_mode;
404                         *value = pslot->supported_speed; 
405                         switch (*value) {
406                         case BUS_SPEED_33:
407                                 break;
408                         case BUS_SPEED_66:
409                                 if (mode == BUS_MODE_PCIX) 
410                                         *value += 0x01;
411                                 break;
412                         case BUS_SPEED_100:
413                         case BUS_SPEED_133:
414                                 *value = pslot->supported_speed + 0x01;
415                                 break;
416                         default:
417                                 /* Note (will need to change): there would be soon 256, 512 also */
418                                 rc = -ENODEV;
419                         }
420                 }
421         } else
422                 rc = -ENODEV;
423
424         ibmphp_unlock_operations ();
425         debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
426         return rc;
427 }
428
429 static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
430 {
431         int rc = -ENODEV;
432         struct slot *pslot;
433         u8 mode = 0;
434
435         debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
436                 hotplug_slot, value);
437
438         ibmphp_lock_operations ();
439
440         if (hotplug_slot && value) {
441                 pslot = (struct slot *) hotplug_slot->private;
442                 if (pslot) {
443                         rc = get_cur_bus_info (&pslot);
444                         if (!rc) {
445                                 mode = pslot->bus_on->current_bus_mode;
446                                 *value = pslot->bus_on->current_speed;
447                                 switch (*value) {
448                                 case BUS_SPEED_33:
449                                         break;
450                                 case BUS_SPEED_66:
451                                         if (mode == BUS_MODE_PCIX) 
452                                                 *value += 0x01;
453                                         else if (mode == BUS_MODE_PCI)
454                                                 ;
455                                         else
456                                                 *value = PCI_SPEED_UNKNOWN;
457                                         break;
458                                 case BUS_SPEED_100:
459                                 case BUS_SPEED_133:
460                                         *value += 0x01;
461                                         break;
462                                 default:
463                                         /* Note of change: there would also be 256, 512 soon */
464                                         rc = -ENODEV;
465                                 }
466                         }
467                 }
468         } else
469                 rc = -ENODEV;
470
471         ibmphp_unlock_operations ();
472         debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
473         return rc;
474 }
475 /*
476 static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
477 {
478         int rc = -ENODEV;
479         struct slot *pslot;
480         int hpcrc = 0;
481         struct slot myslot;
482
483         debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
484
485         if (flag)
486                 ibmphp_lock_operations ();
487
488         if (hotplug_slot && value) {
489                 pslot = (struct slot *) hotplug_slot->private;
490                 if (pslot) {
491                         memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
492                         hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
493
494                         if (!(SLOT_LATCH (myslot.status)) && (SLOT_PRESENT (myslot.status))) {
495                                 hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
496                                 if (!hpcrc) {
497                                         *value = SLOT_SPEED (myslot.ext_status);
498                                         rc = 0;
499                                 }
500                         } else {
501                                 *value = MAX_ADAPTER_NONE;
502                                 rc = 0;
503                         }
504                 }
505         } else
506                 rc = -ENODEV;
507
508         if (hpcrc)
509                 rc = hpcrc;
510
511         if (flag)
512                 ibmphp_unlock_operations ();
513
514         debug ("get_max_adapter_speed_1 - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *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 = (struct slot *) 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         int j;
554
555         for (j = 0; j < MAX_OPS; j++) {
556                 ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
557                 memset (ops[j], 0, (max_slots + 1) * sizeof (int));
558                 if (!ops[j]) {
559                         err ("out of system memory \n");
560                         return -ENOMEM;
561                 }
562         }
563
564         ops[ADD][0] = 0;
565         ops[REMOVE][0] = 0;
566         ops[DETAIL][0] = 0;
567
568         list_for_each (tmp, &ibmphp_slot_head) {
569                 slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
570
571                 if (!slot_cur)
572                         return -ENODEV;
573
574                 debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
575                 if (slot_cur->ctrl->revision == 0xFF) 
576                         if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
577                                 return -1;
578
579                 if (slot_cur->bus_on->current_speed == 0xFF) 
580                         if (get_cur_bus_info (&slot_cur)) 
581                                 return -1;
582
583                 if (slot_cur->ctrl->options == 0xFF)
584                         if (get_hpc_options (slot_cur, &slot_cur->ctrl->options))
585                                 return -1;
586
587                 retval = slot_update (&slot_cur);
588                 if (retval)
589                         return retval;
590
591                 debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
592                 debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
593
594                 if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
595                         /* No power, adapter, and latch closed */
596                         ops[ADD][slot_cur->number] = 1;
597                 else
598                         ops[ADD][slot_cur->number] = 0;
599
600                 ops[DETAIL][slot_cur->number] = 1;
601
602                 if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
603                         /*Power,adapter,latch closed */
604                         ops[REMOVE][slot_cur->number] = 1;
605                 else
606                         ops[REMOVE][slot_cur->number] = 0;
607
608                 if ((SLOT_PWRGD (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
609                         debug ("BEFORE POWER OFF COMMAND\n");
610                                 rc = power_off (slot_cur);
611                                 if (rc)
612                                         return rc;
613
614         /*              retval = slot_update (&slot_cur);
615          *              if (retval)
616          *                      return retval;
617          *              ibmphp_update_slot_info (slot_cur);
618          */
619                 }
620         }
621         init_flag = 0;
622         return 0;
623 }
624
625 /* This operation will check whether the slot is within the bounds and
626  * the operation is valid to perform on that slot
627  * Parameters: slot, operation
628  * Returns: 0 or error codes
629  */
630 static int validate (struct slot *slot_cur, int opn)
631 {
632         int number;
633         int retval;
634
635         if (!slot_cur)
636                 return -ENODEV;
637         number = slot_cur->number;
638         if ((number > max_slots) || (number < 0))
639                 return -EBADSLT;
640         debug ("slot_number in validate is %d\n", slot_cur->number);
641
642         retval = slot_update (&slot_cur);
643         if (retval)
644                 return retval;
645
646         if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
647             && !(SLOT_LATCH (slot_cur->status)))
648                 ops[ADD][number] = 1;
649         else
650                 ops[ADD][number] = 0;
651
652         ops[DETAIL][number] = 1;
653
654         if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
655             && !(SLOT_LATCH (slot_cur->status)))
656                 ops[REMOVE][number] = 1;
657         else
658                 ops[REMOVE][number] = 0;
659
660         switch (opn) {
661                 case ENABLE:
662                         if (ops[ADD][number])
663                                 return 0;
664                         break;
665                 case DISABLE:
666                         if (ops[REMOVE][number])
667                                 return 0;
668                         break;
669                 case DETAIL:
670                         if (ops[DETAIL][number])
671                                 return 0;
672                         break;
673                 default:
674                         return -EINVAL;
675                         break;
676         }
677         err ("validate failed....\n");
678         return -EINVAL;
679 }
680
681 /********************************************************************************
682  * This routine is for updating the data structures in the hotplug core
683  * Parameters: struct slot
684  * Returns: 0 or error
685  *******************************************************************************/
686 int ibmphp_update_slot_info (struct slot *slot_cur)
687 {
688         struct hotplug_slot_info *info;
689         char buffer[30];
690         int rc;
691         u8 bus_speed;
692         u8 mode;
693
694         info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
695         if (!info) {
696                 err ("out of system memory \n");
697                 return -ENOMEM;
698         }
699         
700         strncpy (buffer, slot_cur->hotplug_slot->name, 30);
701         info->power_status = SLOT_PWRGD (slot_cur->status);
702         info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
703         info->latch_status = SLOT_LATCH (slot_cur->status);
704         if (!SLOT_PRESENT (slot_cur->status)) {
705                 info->adapter_status = 0;
706 //              info->max_adapter_speed_status = MAX_ADAPTER_NONE;
707         } else {
708                 info->adapter_status = 1;
709 //              get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
710         }
711
712         bus_speed = slot_cur->bus_on->current_speed;
713         mode = slot_cur->bus_on->current_bus_mode;
714
715         switch (bus_speed) {
716         case BUS_SPEED_33:
717                 break;
718         case BUS_SPEED_66:
719                 if (mode == BUS_MODE_PCIX) 
720                         bus_speed += 0x01;
721                 else if (mode == BUS_MODE_PCI)
722                         ;
723                 else
724                         bus_speed = PCI_SPEED_UNKNOWN;
725                 break;
726         case BUS_SPEED_100:
727         case BUS_SPEED_133:
728                 bus_speed += 0x01;
729                 break;
730         default:
731                 bus_speed = PCI_SPEED_UNKNOWN;
732         }
733
734         info->cur_bus_speed = bus_speed;
735         info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
736         // To do: bus_names 
737         
738         rc = pci_hp_change_slot_info (buffer, info);
739         kfree (info);
740         return rc;
741 }
742
743
744 /******************************************************************************
745  * This function will return the pci_func, given bus and devfunc, or NULL.  It
746  * is called from visit routines
747  ******************************************************************************/
748
749 static struct pci_func *ibm_slot_find (u8 busno, u8 device, u8 function)
750 {
751         struct pci_func *func_cur;
752         struct slot *slot_cur;
753         struct list_head * tmp;
754         list_for_each (tmp, &ibmphp_slot_head) {
755                 slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
756                 if (slot_cur->func) {
757                         func_cur = slot_cur->func;
758                         while (func_cur) {
759                                 if ((func_cur->busno == busno) && (func_cur->device == device) && (func_cur->function == function))
760                                         return func_cur;
761                                 func_cur = func_cur->next;
762                         }
763                 }
764         }
765         return NULL;
766 }
767
768 /* This routine is to find the pci_bus from kernel structures.
769  * Parameters: bus number
770  * Returns : pci_bus *  or NULL if not found
771  */
772 static struct pci_bus *find_bus (u8 busno)
773 {
774         const struct list_head *tmp;
775         struct pci_bus *bus;
776         debug ("inside find_bus, busno = %x \n", busno);
777
778         list_for_each (tmp, &pci_root_buses) {
779                 bus = (struct pci_bus *) pci_bus_b (tmp);
780                 if (bus)
781                         if (bus->number == busno)
782                                 return bus;
783         }
784         return NULL;
785 }
786
787 /******************************************************************
788  * This function is here because we can no longer use pci_root_ops
789  ******************************************************************/
790 static struct pci_ops *get_root_pci_ops (void)
791 {
792         struct pci_bus * bus;
793
794         if ((bus = find_bus (0)))
795                 return bus->ops;
796         return NULL;
797 }
798
799 /*************************************************************
800  * This routine frees up memory used by struct slot, including
801  * the pointers to pci_func, bus, hotplug_slot, controller,
802  * and deregistering from the hotplug core
803  *************************************************************/
804 static void free_slots (void)
805 {
806         struct slot *slot_cur;
807         struct list_head * tmp;
808         struct list_head * next;
809
810         debug ("%s -- enter\n", __FUNCTION__);
811
812         list_for_each_safe (tmp, next, &ibmphp_slot_head) {
813         
814                 slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
815
816                 pci_hp_deregister (slot_cur->hotplug_slot);
817
818                 if (slot_cur->hotplug_slot) {
819                         kfree (slot_cur->hotplug_slot);
820                         slot_cur->hotplug_slot = NULL;
821                 }
822
823                 if (slot_cur->ctrl) 
824                         slot_cur->ctrl = NULL;
825                 
826                 if (slot_cur->bus_on) 
827                         slot_cur->bus_on = NULL;
828
829                 ibmphp_unconfigure_card (&slot_cur, -1);  /* we don't want to actually remove the resources, since free_resources will do just that */
830
831                 kfree (slot_cur);
832                 slot_cur = NULL;
833         }
834         debug ("%s -- exit\n", __FUNCTION__);
835 }
836
837 static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
838 {
839         int i = 0;
840         int inuse = 0;
841
842         if (dev->driver)
843                 return 1;
844
845         for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
846
847                 if (!pci_resource_start (dev, i))
848                         continue;
849
850                 if (pci_resource_flags (dev, i) & IORESOURCE_IO)
851                         inuse = check_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
852
853                 else if (pci_resource_flags (dev, i) & IORESOURCE_MEM)
854                         inuse = check_mem_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
855         }
856
857         return inuse;
858 }
859
860 static int ibm_pci_hp_remove_device (struct pci_dev *dev)
861 {
862         if (ibm_is_pci_dev_in_use (dev)) {
863                 err ("***Cannot safely power down device -- it appears to be in use***\n");
864                 return -EBUSY;
865         }
866         pci_remove_device (dev);
867         return 0;
868 }
869
870 static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
871 {
872         struct pci_dev *dev = wrapped_dev->dev;
873         struct pci_func *temp_func;
874         int i = 0;
875
876         do {
877                 temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
878         } while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
879
880         if (dev) {
881                 if (ibm_pci_hp_remove_device (dev) == 0)
882                         kfree (dev);    /* Now, remove */
883                 else
884                         return -1;
885         }
886
887         if (temp_func)
888                 temp_func->dev = NULL;
889         else
890                 debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
891
892         return 0;
893 }
894
895 static int ibm_unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
896 {
897         struct pci_bus *bus = wrapped_bus->bus;
898
899         pci_proc_detach_bus (bus);
900         /* The cleanup code should live in the kernel... */
901         bus->self->subordinate = NULL;
902         /* unlink from parent bus */
903         list_del (&bus->node);
904
905         /* Now, remove */
906         if (bus)
907                 kfree (bus);
908
909         return 0;
910 }
911
912 static int ibm_unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
913 {
914         struct pci_dev *dev = wrapped_dev->dev;
915
916         debug ("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT (dev->devfn), PCI_FUNC (dev->devfn));
917
918         /* Now, remove the Linux Driver Representation */
919         if (dev->driver) {
920                 debug ("is there a driver?\n");
921                 if (dev->driver->remove) {
922                         dev->driver->remove (dev);
923                         debug ("driver was properly removed\n");
924                 }
925                 dev->driver = NULL;
926         }
927
928         return ibm_is_pci_dev_in_use (dev);
929 }
930
931 static struct pci_visit ibm_unconfigure_functions_phase1 = {
932         .post_visit_pci_dev =   ibm_unconfigure_visit_pci_dev_phase1,
933 };
934
935 static struct pci_visit ibm_unconfigure_functions_phase2 = {
936         .post_visit_pci_bus =   ibm_unconfigure_visit_pci_bus_phase2,
937         .post_visit_pci_dev =   ibm_unconfigure_visit_pci_dev_phase2,
938 };
939
940 static int ibm_unconfigure_device (struct pci_func *func)
941 {
942         int rc = 0;
943         struct pci_dev_wrapped wrapped_dev;
944         struct pci_bus_wrapped wrapped_bus;
945         struct pci_dev *temp;
946         u8 j;
947
948         memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
949         memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
950
951         debug ("inside ibm_unconfigure_device\n");
952         debug ("func->device = %x, func->function = %x\n", func->device, func->function);
953         debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
954
955         for (j = 0; j < 0x08; j++) {
956                 temp = pci_find_slot (func->busno, (func->device << 3) | j);
957                 if (temp) {
958                         wrapped_dev.dev = temp;
959                         wrapped_bus.bus = temp->bus;
960                         rc = pci_visit_dev (&ibm_unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
961                         if (rc)
962                                 break;
963
964                         rc = pci_visit_dev (&ibm_unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
965                         if (rc)
966                                 break;
967                 }
968         }
969         debug ("rc in ibm_unconfigure_device b4 returning is %d \n", rc);
970         return rc;
971 }
972
973 static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
974 {
975         //      struct pci_bus *bus = wrapped_bus->bus; /* We don't need this, since we don't create in the else statement */
976         struct pci_dev *dev = wrapped_dev->dev;
977         struct pci_func *temp_func;
978         int i = 0;
979
980         do {
981                 temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
982         } while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
983
984         if (temp_func)
985                 temp_func->dev = dev;
986         else {
987                 /* This should not really happen, since we create functions
988                    first and then call to configure */
989                 debug (" We shouldn't come here \n");
990         }
991
992         if (temp_func->dev) {
993                 pci_proc_attach_device (temp_func->dev);
994                 pci_announce_device_to_drivers (temp_func->dev);
995         }
996
997         return 0;
998 }
999
1000 static struct pci_visit configure_functions = {
1001         .visit_pci_dev =configure_visit_pci_dev,
1002 };
1003
1004
1005 /*
1006  * The following function is to fix kernel bug regarding 
1007  * getting bus entries, here we manually add those primary 
1008  * bus entries to kernel bus structure whenever apply
1009  */
1010
1011 static u8 bus_structure_fixup (u8 busno)
1012 {
1013         struct pci_bus bus_t;
1014         struct pci_dev dev_t;
1015         u16 l;
1016
1017         if (find_bus (busno) || !(ibmphp_find_same_bus_num (busno)))
1018                 return 1;
1019         bus_t.number = busno;
1020         bus_t.ops = ibmphp_pci_root_ops;
1021         dev_t.bus = &bus_t;
1022         for (dev_t.devfn=0; dev_t.devfn<256; dev_t.devfn += 8) {
1023                 if (!pci_read_config_word (&dev_t, PCI_VENDOR_ID, &l) &&  l != 0x0000 && l != 0xffff) {
1024                         debug ("%s - Inside bus_struture_fixup() \n", __FUNCTION__);
1025                         pci_scan_bus (busno, ibmphp_pci_root_ops, NULL);
1026                         break;
1027                 }
1028         }
1029         return 0;
1030 }
1031
1032 static int ibm_configure_device (struct pci_func *func)
1033 {
1034         unsigned char bus;
1035         struct pci_dev dev0;
1036         struct pci_bus *child;
1037         struct pci_dev *temp;
1038         int rc = 0;
1039         int flag = 0;   /* this is to make sure we don't double scan the bus, for bridged devices primarily */
1040
1041         struct pci_dev_wrapped wrapped_dev;
1042         struct pci_bus_wrapped wrapped_bus;
1043
1044         memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
1045         memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
1046         memset (&dev0, 0, sizeof (struct pci_dev));
1047
1048         if (!(bus_structure_fixup (func->busno)))
1049                 flag = 1;
1050         if (func->dev == NULL)
1051                 func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7));
1052
1053         if (func->dev == NULL) {
1054                 dev0.bus = find_bus (func->busno);
1055                 dev0.devfn = ((func->device << 3) + (func->function & 0x7));
1056                 dev0.sysdata = dev0.bus->sysdata;
1057
1058                 func->dev = pci_scan_slot (&dev0);
1059
1060                 if (func->dev == NULL) {
1061                         err ("ERROR... : pci_dev still NULL \n");
1062                         return 0;
1063                 }
1064         }
1065         if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
1066                 pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
1067                 child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
1068                 pci_do_scan_bus (child);
1069         }
1070
1071         temp = func->dev;
1072         if (temp) {
1073                 wrapped_dev.dev = temp;
1074                 wrapped_bus.bus = temp->bus;
1075                 rc = pci_visit_dev (&configure_functions, &wrapped_dev, &wrapped_bus);
1076         }
1077         return rc;
1078 }
1079
1080 /*******************************************************
1081  * Returns whether the bus is empty or not 
1082  *******************************************************/
1083 static int is_bus_empty (struct slot * slot_cur)
1084 {
1085         int rc;
1086         struct slot * tmp_slot;
1087         u8 i = slot_cur->bus_on->slot_min;
1088
1089         while (i <= slot_cur->bus_on->slot_max) {
1090                 if (i == slot_cur->number) {
1091                         i++;
1092                         continue;
1093                 }
1094                 tmp_slot = ibmphp_get_slot_from_physical_num (i);
1095                 rc = slot_update (&tmp_slot);
1096                 if (rc)
1097                         return 0;
1098                 if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
1099                         return 0;
1100                 i++;
1101         }
1102         return 1;
1103 }
1104
1105 /***********************************************************
1106  * If the HPC permits and the bus currently empty, tries to set the 
1107  * bus speed and mode at the maximum card and bus capability
1108  * Parameters: slot
1109  * Returns: bus is set (0) or error code
1110  ***********************************************************/
1111 static int set_bus (struct slot * slot_cur)
1112 {
1113         int rc;
1114         u8 speed;
1115         u8 cmd = 0x0;
1116         const struct list_head *tmp;
1117         struct pci_dev * dev;
1118         int retval;
1119
1120         debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
1121         if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
1122                 rc = slot_update (&slot_cur);
1123                 if (rc)
1124                         return rc;
1125                 speed = SLOT_SPEED (slot_cur->ext_status);
1126                 debug ("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
1127                 switch (speed) {
1128                 case HPC_SLOT_SPEED_33:
1129                         cmd = HPC_BUS_33CONVMODE;
1130                         break;
1131                 case HPC_SLOT_SPEED_66:
1132                         if (SLOT_PCIX (slot_cur->ext_status)) {
1133                                 if ((slot_cur->supported_speed >= BUS_SPEED_66) && (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
1134                                         cmd = HPC_BUS_66PCIXMODE;
1135                                 else if (!SLOT_BUS_MODE (slot_cur->ext_status))
1136                                         /* if max slot/bus capability is 66 pci
1137                                         and there's no bus mode mismatch, then
1138                                         the adapter supports 66 pci */ 
1139                                         cmd = HPC_BUS_66CONVMODE;
1140                                 else
1141                                         cmd = HPC_BUS_33CONVMODE;
1142                         } else {
1143                                 if (slot_cur->supported_speed >= BUS_SPEED_66)
1144                                         cmd = HPC_BUS_66CONVMODE;
1145                                 else
1146                                         cmd = HPC_BUS_33CONVMODE;
1147                         }
1148                         break;
1149                 case HPC_SLOT_SPEED_133:
1150                         switch (slot_cur->supported_speed) {
1151                         case BUS_SPEED_33:
1152                                 cmd = HPC_BUS_33CONVMODE;
1153                                 break;
1154                         case BUS_SPEED_66:
1155                                 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
1156                                         cmd = HPC_BUS_66PCIXMODE;
1157                                 else
1158                                         cmd = HPC_BUS_66CONVMODE;
1159                                 break;
1160                         case BUS_SPEED_100:
1161                                 cmd = HPC_BUS_100PCIXMODE;
1162                                 break;
1163                         case BUS_SPEED_133:
1164                                 /* This is to take care of the bug in CIOBX chip*/
1165                                 list_for_each (tmp, &pci_devices) {
1166                                         dev = (struct pci_dev *) pci_dev_g (tmp);
1167                                         if (dev) {
1168                                                 if ((dev->vendor == 0x1166) && (dev->device == 0x0101))
1169                                                         ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
1170                                         }
1171                                 }
1172                                 cmd = HPC_BUS_133PCIXMODE;
1173                                 break;
1174                         default:
1175                                 err ("Wrong bus speed \n");
1176                                 return -ENODEV;
1177                         }
1178                         break;
1179                 default:
1180                         err ("wrong slot speed \n");
1181                         return -ENODEV;
1182                 }
1183                 debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
1184                 retval = ibmphp_hpc_writeslot (slot_cur, cmd);
1185                 if (retval) {
1186                         err ("setting bus speed failed\n");
1187                         return retval;
1188                 }
1189                 if (CTLR_RESULT (slot_cur->ctrl->status)) {
1190                         err ("command not completed successfully in set_bus \n");
1191                         return -EIO;
1192                 }
1193         }
1194         /* This is for x440, once Brandon fixes the firmware, 
1195         will not need this delay */
1196         long_delay (1 * HZ);
1197         debug ("%s -Exit \n", __FUNCTION__);
1198         return 0;
1199 }
1200
1201 /* This routine checks the bus limitations that the slot is on from the BIOS.
1202  * This is used in deciding whether or not to power up the slot.  
1203  * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
1204  * same bus) 
1205  * Parameters: slot
1206  * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
1207  */
1208 static int check_limitations (struct slot *slot_cur)
1209 {
1210         u8 i;
1211         struct slot * tmp_slot;
1212         u8 count = 0;
1213         u8 limitation = 0;
1214
1215         for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
1216                 tmp_slot = ibmphp_get_slot_from_physical_num (i);
1217                 if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
1218                         count++;
1219         }
1220         get_cur_bus_info (&slot_cur);
1221         switch (slot_cur->bus_on->current_speed) {
1222         case BUS_SPEED_33:
1223                 limitation = slot_cur->bus_on->slots_at_33_conv;
1224                 break;
1225         case BUS_SPEED_66:
1226                 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1227                         limitation = slot_cur->bus_on->slots_at_66_pcix;
1228                 else
1229                         limitation = slot_cur->bus_on->slots_at_66_conv;
1230                 break;
1231         case BUS_SPEED_100:
1232                 limitation = slot_cur->bus_on->slots_at_100_pcix;
1233                 break;
1234         case BUS_SPEED_133:
1235                 limitation = slot_cur->bus_on->slots_at_133_pcix;
1236                 break;
1237         }
1238
1239         if ((count + 1) > limitation)
1240                 return -EINVAL;
1241         return 0;
1242 }
1243
1244 static inline void print_card_capability (struct slot *slot_cur)
1245 {
1246         info ("capability of the card is ");
1247         if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
1248                 info ("   133 MHz PCI-X \n");
1249         else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1250                 info ("    66 MHz PCI-X \n");
1251         else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1252                 info ("    66 MHz PCI \n");
1253         else
1254                 info ("    33 MHz PCI \n");
1255
1256 }
1257
1258 /* This routine will power on the slot, configure the device(s) and find the
1259  * drivers for them.
1260  * Parameters: hotplug_slot
1261  * Returns: 0 or failure codes
1262  */
1263 static int enable_slot (struct hotplug_slot *hs)
1264 {
1265         int rc, i, rcpr;
1266         struct slot *slot_cur;
1267         u8 function;
1268         u8 faulted = 0;
1269         struct pci_func *tmp_func;
1270
1271         ibmphp_lock_operations ();
1272
1273         debug ("ENABLING SLOT........ \n");
1274         slot_cur = (struct slot *) hs->private;
1275
1276         if ((rc = validate (slot_cur, ENABLE))) {
1277                 err ("validate function failed \n");
1278                 attn_off (slot_cur);    /* need to turn off if was blinking b4 */
1279                 attn_on (slot_cur);
1280                 rc = slot_update (&slot_cur);
1281                 if (rc) {
1282                         ibmphp_unlock_operations();
1283                         return rc;
1284                 }
1285                 ibmphp_update_slot_info (slot_cur);
1286                 ibmphp_unlock_operations ();
1287                 return rc;
1288         }
1289
1290         attn_LED_blink (slot_cur);
1291         
1292         rc = set_bus (slot_cur);
1293         if (rc) {
1294                 err ("was not able to set the bus \n");
1295                 attn_off (slot_cur);
1296                 attn_on (slot_cur);
1297                 ibmphp_unlock_operations ();
1298                 return -ENODEV;
1299         }
1300
1301         /*-----------------debugging------------------------------*/
1302         get_cur_bus_info (&slot_cur);
1303         debug ("the current bus speed right after set_bus = %x \n", slot_cur->bus_on->current_speed); 
1304         /*----------------------------------------------------------*/
1305
1306         rc = check_limitations (slot_cur);
1307         if (rc) {
1308                 err ("Adding this card exceeds the limitations of this bus. \n");
1309                 err ("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus \n. Try hot-adding into another bus \n");
1310                 attn_off (slot_cur);
1311                 attn_on (slot_cur);
1312
1313                 if (slot_update (&slot_cur)) {
1314                         ibmphp_unlock_operations ();
1315                         return -ENODEV;
1316                 }
1317                 ibmphp_update_slot_info (slot_cur);
1318                 ibmphp_unlock_operations ();
1319                 return -EINVAL;
1320         }
1321
1322         rc = power_on (slot_cur);
1323
1324         if (rc) {
1325                 err ("something wrong when powering up... please see below for details\n");
1326                 /* need to turn off before on, otherwise, blinking overwrites */
1327                 attn_off(slot_cur);
1328                 attn_on (slot_cur);
1329                 if (slot_update (&slot_cur)) {
1330                         attn_off (slot_cur);
1331                         attn_on (slot_cur);
1332                         ibmphp_unlock_operations ();
1333                         return -ENODEV;
1334                 }
1335                 /* Check to see the error of why it failed */
1336                 if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status)))
1337                         err ("power fault occured trying to power up \n");
1338                 else if (SLOT_BUS_SPEED (slot_cur->status)) {
1339                         err ("bus speed mismatch occured.  please check current bus speed and card capability \n");
1340                         print_card_capability (slot_cur);
1341                 } else if (SLOT_BUS_MODE (slot_cur->ext_status)) {
1342                         err ("bus mode mismatch occured.  please check current bus mode and card capability \n");
1343                         print_card_capability (slot_cur);
1344                 }
1345                 ibmphp_update_slot_info (slot_cur);
1346                 ibmphp_unlock_operations ();
1347                 return rc;
1348         }
1349         debug ("after power_on\n");
1350         /*-----------------------debugging---------------------------*/
1351         get_cur_bus_info (&slot_cur);
1352         debug ("the current bus speed right after power_on = %x \n", slot_cur->bus_on->current_speed);
1353         /*----------------------------------------------------------*/
1354
1355         rc = slot_update (&slot_cur);
1356         if (rc) {
1357                 attn_off (slot_cur);
1358                 attn_on (slot_cur);
1359                 rcpr = power_off (slot_cur);
1360                 if (rcpr) {
1361                         ibmphp_unlock_operations ();
1362                         return rcpr;
1363                 }
1364                 ibmphp_unlock_operations ();
1365                 return rc;
1366         }
1367         
1368         if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
1369                 faulted = 1;
1370                 err ("power fault occured trying to power up... \n");
1371         } else if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
1372                 faulted = 1;
1373                 err ("bus speed mismatch occured.  please check current bus speed and card capability \n");
1374                 print_card_capability (slot_cur);
1375         } 
1376         /* Don't think this case will happen after above checks... but just in case, for paranoia sake */
1377         else if (!(SLOT_POWER (slot_cur->status))) {
1378                 err ("power on failed... \n");
1379                 faulted = 1;
1380         }
1381         if (faulted) {
1382                 attn_off (slot_cur);    /* need to turn off b4 on */
1383                 attn_on (slot_cur);
1384                 rcpr = power_off (slot_cur);
1385                 if (rcpr) {
1386                         ibmphp_unlock_operations ();
1387                         return rcpr;
1388                 }
1389                         
1390                 if (slot_update (&slot_cur)) {                      
1391                         ibmphp_unlock_operations ();    
1392                         return -ENODEV;
1393                 }
1394                 ibmphp_update_slot_info (slot_cur);
1395                 ibmphp_unlock_operations ();
1396                 return -EINVAL;
1397         }
1398
1399         slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
1400         if (!slot_cur->func) { /* We cannot do update_slot_info here, since no memory for kmalloc n.e.ways, and update_slot_info allocates some */
1401                 err ("out of system memory \n");
1402                 attn_off (slot_cur);
1403                 attn_on (slot_cur);
1404                 rcpr = power_off (slot_cur);
1405                 if (rcpr) {
1406                         ibmphp_unlock_operations ();
1407                         return rcpr;
1408                 }
1409                 ibmphp_unlock_operations ();
1410                 return -ENOMEM;
1411         }
1412         memset (slot_cur->func, 0, sizeof (struct pci_func));
1413         slot_cur->func->busno = slot_cur->bus;
1414         slot_cur->func->device = slot_cur->device;
1415         for (i = 0; i < 4; i++)
1416                 slot_cur->func->irq[i] = slot_cur->irq[i];
1417
1418         debug ("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n", slot_cur->bus, slot_cur->device);
1419
1420         if (ibmphp_configure_card (slot_cur->func, slot_cur->number)) {
1421                 err ("configure_card was unsuccessful... \n");
1422                 ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
1423                 debug ("after unconfigure_card\n");
1424                 slot_cur->func = NULL;
1425                 attn_off (slot_cur);    /* need to turn off in case was blinking */
1426                 attn_on (slot_cur);
1427                 rcpr = power_off (slot_cur);
1428                 if (rcpr) {
1429                         ibmphp_unlock_operations ();
1430                         return rcpr;
1431                 }
1432                 if (slot_update (&slot_cur)) {
1433                         ibmphp_unlock_operations();
1434                         return -ENODEV;
1435                 }
1436                 ibmphp_update_slot_info (slot_cur);
1437                 ibmphp_unlock_operations ();
1438                 return -ENOMEM;
1439         }
1440         function = 0x00;
1441         do {
1442                 tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
1443                 if (tmp_func && !(tmp_func->dev))
1444                         ibm_configure_device (tmp_func);
1445         } while (tmp_func);
1446
1447         attn_off (slot_cur);
1448         if (slot_update (&slot_cur)) {
1449                 ibmphp_unlock_operations ();
1450                 return -EFAULT;
1451         }
1452         ibmphp_print_test ();
1453         rc = ibmphp_update_slot_info (slot_cur);
1454         ibmphp_unlock_operations(); 
1455         return rc;
1456 }
1457
1458 /**************************************************************
1459 * HOT REMOVING ADAPTER CARD                                   *
1460 * INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
1461 * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
1462           DISABLE POWER ,                                    *
1463 **************************************************************/
1464 int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
1465 {
1466         int rc;
1467         struct slot *slot_cur = (struct slot *) hotplug_slot->private;
1468         u8 flag;
1469         int parm = 0;
1470
1471         debug ("DISABLING SLOT... \n"); 
1472                 
1473         if (slot_cur == NULL) {
1474                 ibmphp_unlock_operations (); 
1475                 return -ENODEV;
1476         }
1477         
1478         if (slot_cur->ctrl == NULL) {
1479                 ibmphp_unlock_operations ();
1480                 return -ENODEV;
1481         }
1482         
1483         flag = slot_cur->flag;  /* to see if got here from polling */
1484         
1485         if (flag)
1486                 ibmphp_lock_operations ();
1487         
1488         slot_cur->flag = TRUE;
1489
1490         if (flag == TRUE) {
1491                 rc = validate (slot_cur, DISABLE);      /* checking if powered off already & valid slot # */
1492                 if (rc) {
1493                         /*  Need to turn off if was blinking b4 */
1494                         attn_off (slot_cur);
1495                         attn_on (slot_cur);
1496                         if (slot_update (&slot_cur)) {
1497                                 ibmphp_unlock_operations ();
1498                                 return -EFAULT;
1499                         }
1500                 
1501                         ibmphp_update_slot_info (slot_cur);
1502                         ibmphp_unlock_operations ();
1503                         return rc;
1504                 }
1505         }
1506         attn_LED_blink (slot_cur);
1507
1508         if (slot_cur->func == NULL) {
1509                 /* We need this for fncs's that were there on bootup */
1510                 slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
1511                 if (!slot_cur->func) {
1512                         err ("out of system memory \n");
1513                         attn_off (slot_cur);
1514                         attn_on (slot_cur);
1515                         ibmphp_unlock_operations ();
1516                         return -ENOMEM;
1517                 }
1518                 memset (slot_cur->func, 0, sizeof (struct pci_func));
1519                 slot_cur->func->busno = slot_cur->bus;
1520                 slot_cur->func->device = slot_cur->device;
1521         }
1522
1523         if ((rc = ibm_unconfigure_device (slot_cur->func))) {
1524                 err ("removing from kernel failed... \n");
1525                 err ("Please check to see if it was statically linked or is in use otherwise. (perhaps the driver is not 'hot-removable')\n");
1526                 attn_off (slot_cur);
1527                 attn_on (slot_cur);
1528                 ibmphp_unlock_operations ();
1529                 return rc;
1530         }
1531         
1532         /* If we got here from latch suddenly opening on operating card or 
1533         a power fault, there's no power to the card, so cannot
1534         read from it to determine what resources it occupied.  This operation
1535         is forbidden anyhow.  The best we can do is remove it from kernel
1536         lists at least */
1537
1538         if (!flag) {
1539                 attn_off (slot_cur);
1540                 return 0;
1541         }
1542
1543         rc = ibmphp_unconfigure_card (&slot_cur, parm);
1544         slot_cur->func = NULL;
1545         debug ("in disable_slot. after unconfigure_card\n");
1546         if (rc) {
1547                 err ("could not unconfigure card.\n");
1548                 attn_off (slot_cur);    /* need to turn off if was blinking b4 */
1549                 attn_on (slot_cur);
1550
1551                 if (slot_update (&slot_cur)) {
1552                         ibmphp_unlock_operations ();
1553                         return -EFAULT;
1554                 }
1555
1556                 if (flag)
1557                         ibmphp_update_slot_info (slot_cur);
1558                 ibmphp_unlock_operations ();
1559                 return -EFAULT;
1560         }
1561
1562         rc = ibmphp_hpc_writeslot (hotplug_slot->private, HPC_SLOT_OFF);
1563         if (rc) {
1564                 attn_off (slot_cur);
1565                 attn_on (slot_cur);
1566                 if (slot_update (&slot_cur)) {
1567                         ibmphp_unlock_operations ();
1568                         return -EFAULT;
1569                 }
1570
1571                 ibmphp_update_slot_info (slot_cur);
1572                 ibmphp_unlock_operations ();
1573                 return rc;
1574         }
1575
1576         attn_off (slot_cur);
1577         if (slot_update (&slot_cur)) {
1578                 ibmphp_unlock_operations ();
1579                 return -EFAULT;
1580         }
1581         rc = ibmphp_update_slot_info (slot_cur);
1582         ibmphp_print_test ();
1583         ibmphp_unlock_operations();
1584         return rc;
1585 }
1586
1587 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1588         .owner =                        THIS_MODULE,
1589         .set_attention_status =         set_attention_status,
1590         .enable_slot =                  enable_slot,
1591         .disable_slot =                 ibmphp_disable_slot,
1592         .hardware_test =                NULL,
1593         .get_power_status =             get_power_status,
1594         .get_attention_status =         get_attention_status,
1595         .get_latch_status =             get_latch_status,
1596         .get_adapter_status =           get_adapter_present,
1597         .get_max_bus_speed =            get_max_bus_speed,
1598         .get_cur_bus_speed =            get_cur_bus_speed,
1599 /*      .get_max_adapter_speed =        get_max_adapter_speed,
1600         .get_bus_name_status =          get_bus_name,
1601 */
1602 };
1603
1604 static void ibmphp_unload (void)
1605 {
1606         free_slots ();
1607         debug ("after slots \n");
1608         ibmphp_free_resources ();
1609         debug ("after resources \n");
1610         ibmphp_free_bus_info_queue ();
1611         debug ("after bus info \n");
1612         ibmphp_free_ebda_hpc_queue ();
1613         debug ("after ebda hpc \n");
1614         ibmphp_free_ebda_pci_rsrc_queue ();
1615         debug ("after ebda pci rsrc \n");
1616 }
1617
1618 static int __init ibmphp_init (void)
1619 {
1620         int i = 0;
1621         int rc = 0;
1622
1623         init_flag = 1;
1624
1625         info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
1626
1627         ibmphp_pci_root_ops = get_root_pci_ops ();
1628         if (ibmphp_pci_root_ops == NULL) {
1629                 err ("cannot read bus operations... will not be able to read the cards.  Please check your system\n");
1630                 return -ENODEV; 
1631         }
1632
1633         ibmphp_debug = debug;
1634
1635         ibmphp_hpc_initvars ();
1636
1637         for (i = 0; i < 16; i++)
1638                 irqs[i] = 0;
1639
1640         if ((rc = ibmphp_access_ebda ())) {
1641                 ibmphp_unload ();
1642                 return rc;
1643         }
1644         debug ("after ibmphp_access_ebda ()\n");
1645
1646         if ((rc = ibmphp_rsrc_init ())) {
1647                 ibmphp_unload ();
1648                 return rc;
1649         }
1650         debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
1651
1652         max_slots = get_max_slots ();
1653         
1654         if ((rc = ibmphp_register_pci ())) {
1655                 ibmphp_unload ();
1656                 return rc;
1657         }
1658
1659         if (init_ops ()) {
1660                 ibmphp_unload ();
1661                 return -ENODEV;
1662         }
1663         ibmphp_print_test ();
1664         if ((rc = ibmphp_hpc_start_poll_thread ())) {
1665                 ibmphp_unload ();
1666                 return -ENODEV;
1667         }
1668
1669         /* if no NVRAM module selected, lock ourselves into memory with a 
1670          * module count of -1 so that no one can unload us. */
1671         MOD_DEC_USE_COUNT;
1672         return 0;
1673 }
1674
1675 static void __exit ibmphp_exit (void)
1676 {
1677         ibmphp_hpc_stop_poll_thread ();
1678         debug ("after polling\n");
1679         ibmphp_unload ();
1680         debug ("done\n");
1681 }
1682
1683 module_init (ibmphp_init);
1684 module_exit (ibmphp_exit);