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