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