blob: 59392946c2bd350b0605877eaf4ae42af0ea81b3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
51int ibmphp_debug;
52
53static int debug;
54module_param(debug, bool, S_IRUGO | S_IWUSR);
55MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
56MODULE_LICENSE ("GPL");
57MODULE_DESCRIPTION (DRIVER_DESC);
58
59struct pci_bus *ibmphp_pci_bus;
60static int max_slots;
61
62static 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
65static int init_flag;
66
67/*
68static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
69
70static 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*/
75static 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
105static 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
116static 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 */
136int 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
199static 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
217static 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
234static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
235{
236 int rc = 0;
237 struct slot *pslot;
Pavel Machek072888f2006-01-08 20:11:59 +0100238 u8 cmd = 0x00; /* avoid compiler warning */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
240 debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
241 (ulong) hotplug_slot, value);
242 ibmphp_lock_operations();
Pavel Machek072888f2006-01-08 20:11:59 +0100243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244
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
278static 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();
Eric Sesterhenn9df7fde2006-06-01 11:41:44 +0200288 if (hotplug_slot) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 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
309static 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();
Eric Sesterhenn9df7fde2006-06-01 11:41:44 +0200318 if (hotplug_slot) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 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
336static 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();
Eric Sesterhenn9df7fde2006-06-01 11:41:44 +0200345 if (hotplug_slot) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 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
362static 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();
Eric Sesterhenn9df7fde2006-06-01 11:41:44 +0200372 if (hotplug_slot) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 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
393static 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
Eric Sesterhenn9df7fde2006-06-01 11:41:44 +0200404 if (hotplug_slot) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 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
433static 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
Eric Sesterhenn9df7fde2006-06-01 11:41:44 +0200444 if (hotplug_slot) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 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/*
480static 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
518static 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 ****************************************************************************/
547static 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 */
609static 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 ****************************************************************************/
650int 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
713static 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 *************************************************************/
739static 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
754static 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 */
776static 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
816static 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 *******************************************************/
859static 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 ***********************************************************/
890static 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 */
987static 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
1026static 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 */
1045static 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 "
Jean Delvare3fa63c72005-10-30 15:02:23 -08001080 ">2 66 PCI cards running on same bus.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 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
Eric Sesterhennf5afe802006-02-28 15:34:49 +01001144 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 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);
1186exit:
1187 ibmphp_unlock_operations();
1188 return rc;
1189
1190error_nopower:
1191 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1192 attn_on(slot_cur);
1193error_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
1202error_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**************************************************************/
1219static 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
1230int 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;
Kristen Accardidc6712d2006-03-14 16:24:47 -08001242 slot_cur->flag = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Kristen Accardidc6712d2006-03-14 16:24:47 -08001244 if (flag == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 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 */
Eric Sesterhennf5afe802006-02-28 15:34:49 +01001254 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 if (!slot_cur->func) {
1256 err("out of system memory\n");
1257 rc = -ENOMEM;
1258 goto error;
1259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 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();
1296exit:
1297 return rc;
1298
1299error:
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
1312struct 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
1329static 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
1344static 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
1403exit:
1404 return rc;
1405
1406error:
1407 ibmphp_unload();
1408 goto exit;
1409}
1410
1411static 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
1419module_init(ibmphp_init);
1420module_exit(ibmphp_exit);