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