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 = hotplug_slot->private;
251 if (pslot)
252 rc = ibmphp_hpc_writeslot(pslot, cmd);
253 else
254 rc = -ENODEV;
255 }
256 } else
257 rc = -ENODEV;
258
259 ibmphp_unlock_operations();
260
261 debug("set_attention_status - Exit rc[%d]\n", rc);
262 return rc;
263}
264
265static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
266{
267 int rc = -ENODEV;
268 struct slot *pslot;
269 struct slot myslot;
270
271 debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
272 (ulong) hotplug_slot, (ulong) value);
273
274 ibmphp_lock_operations();
275 if (hotplug_slot) {
276 pslot = hotplug_slot->private;
277 if (pslot) {
278 memcpy(&myslot, pslot, sizeof(struct slot));
279 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
280 &(myslot.status));
281 if (!rc)
282 rc = ibmphp_hpc_readslot(pslot,
283 READ_EXTSLOTSTATUS,
284 &(myslot.ext_status));
285 if (!rc)
286 *value = SLOT_ATTN(myslot.status,
287 myslot.ext_status);
288 }
289 }
290
291 ibmphp_unlock_operations();
292 debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
293 return rc;
294}
295
296static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
297{
298 int rc = -ENODEV;
299 struct slot *pslot;
300 struct slot myslot;
301
302 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
303 (ulong) hotplug_slot, (ulong) value);
304 ibmphp_lock_operations();
305 if (hotplug_slot) {
306 pslot = hotplug_slot->private;
307 if (pslot) {
308 memcpy(&myslot, pslot, sizeof(struct slot));
309 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
310 &(myslot.status));
311 if (!rc)
312 *value = SLOT_LATCH(myslot.status);
313 }
314 }
315
316 ibmphp_unlock_operations();
317 debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
318 rc, rc, *value);
319 return rc;
320}
321
322
323static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
324{
325 int rc = -ENODEV;
326 struct slot *pslot;
327 struct slot myslot;
328
329 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
330 (ulong) hotplug_slot, (ulong) value);
331 ibmphp_lock_operations();
332 if (hotplug_slot) {
333 pslot = hotplug_slot->private;
334 if (pslot) {
335 memcpy(&myslot, pslot, sizeof(struct slot));
336 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
337 &(myslot.status));
338 if (!rc)
339 *value = SLOT_PWRGD(myslot.status);
340 }
341 }
342
343 ibmphp_unlock_operations();
344 debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
345 rc, rc, *value);
346 return rc;
347}
348
349static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value)
350{
351 int rc = -ENODEV;
352 struct slot *pslot;
353 u8 present;
354 struct slot myslot;
355
356 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
357 (ulong) hotplug_slot, (ulong) value);
358 ibmphp_lock_operations();
359 if (hotplug_slot) {
360 pslot = hotplug_slot->private;
361 if (pslot) {
362 memcpy(&myslot, pslot, sizeof(struct slot));
363 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
364 &(myslot.status));
365 if (!rc) {
366 present = SLOT_PRESENT(myslot.status);
367 if (present == HPC_SLOT_EMPTY)
368 *value = 0;
369 else
370 *value = 1;
371 }
372 }
373 }
374
375 ibmphp_unlock_operations();
376 debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
377 return rc;
378}
379
380static int get_max_bus_speed(struct slot *slot)
381{
382 int rc = 0;
383 u8 mode = 0;
384 enum pci_bus_speed speed;
385 struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus;
386
387 debug("%s - Entry slot[%p]\n", __func__, slot);
388
389 ibmphp_lock_operations();
390 mode = slot->supported_bus_mode;
391 speed = slot->supported_speed;
392 ibmphp_unlock_operations();
393
394 switch (speed) {
395 case BUS_SPEED_33:
396 break;
397 case BUS_SPEED_66:
398 if (mode == BUS_MODE_PCIX)
399 speed += 0x01;
400 break;
401 case BUS_SPEED_100:
402 case BUS_SPEED_133:
403 speed += 0x01;
404 break;
405 default:
406
407 rc = -ENODEV;
408 }
409
410 if (!rc)
411 bus->max_bus_speed = speed;
412
413 debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed);
414 return rc;
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
472
473
474
475
476
477
478
479
480
481
482
483
484
485static int __init init_ops(void)
486{
487 struct slot *slot_cur;
488 int retval;
489 int rc;
490
491 list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
492 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
493 slot_cur->number);
494 if (slot_cur->ctrl->revision == 0xFF)
495 if (get_ctrl_revision(slot_cur,
496 &slot_cur->ctrl->revision))
497 return -1;
498
499 if (slot_cur->bus_on->current_speed == 0xFF)
500 if (get_cur_bus_info(&slot_cur))
501 return -1;
502 get_max_bus_speed(slot_cur);
503
504 if (slot_cur->ctrl->options == 0xFF)
505 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
506 return -1;
507
508 retval = slot_update(&slot_cur);
509 if (retval)
510 return retval;
511
512 debug("status = %x\n", slot_cur->status);
513 debug("ext_status = %x\n", slot_cur->ext_status);
514 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
515 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
516 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
517
518 if ((SLOT_PWRGD(slot_cur->status)) &&
519 !(SLOT_PRESENT(slot_cur->status)) &&
520 !(SLOT_LATCH(slot_cur->status))) {
521 debug("BEFORE POWER OFF COMMAND\n");
522 rc = power_off(slot_cur);
523 if (rc)
524 return rc;
525
526
527
528
529
530
531 }
532 }
533 init_flag = 0;
534 return 0;
535}
536
537
538
539
540
541
542static int validate(struct slot *slot_cur, int opn)
543{
544 int number;
545 int retval;
546
547 if (!slot_cur)
548 return -ENODEV;
549 number = slot_cur->number;
550 if ((number > max_slots) || (number < 0))
551 return -EBADSLT;
552 debug("slot_number in validate is %d\n", slot_cur->number);
553
554 retval = slot_update(&slot_cur);
555 if (retval)
556 return retval;
557
558 switch (opn) {
559 case ENABLE:
560 if (!(SLOT_PWRGD(slot_cur->status)) &&
561 (SLOT_PRESENT(slot_cur->status)) &&
562 !(SLOT_LATCH(slot_cur->status)))
563 return 0;
564 break;
565 case DISABLE:
566 if ((SLOT_PWRGD(slot_cur->status)) &&
567 (SLOT_PRESENT(slot_cur->status)) &&
568 !(SLOT_LATCH(slot_cur->status)))
569 return 0;
570 break;
571 default:
572 break;
573 }
574 err("validate failed....\n");
575 return -EINVAL;
576}
577
578
579
580
581
582
583int ibmphp_update_slot_info(struct slot *slot_cur)
584{
585 struct hotplug_slot_info *info;
586 struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus;
587 int rc;
588 u8 bus_speed;
589 u8 mode;
590
591 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
592 if (!info)
593 return -ENOMEM;
594
595 info->power_status = SLOT_PWRGD(slot_cur->status);
596 info->attention_status = SLOT_ATTN(slot_cur->status,
597 slot_cur->ext_status);
598 info->latch_status = SLOT_LATCH(slot_cur->status);
599 if (!SLOT_PRESENT(slot_cur->status)) {
600 info->adapter_status = 0;
601
602 } else {
603 info->adapter_status = 1;
604
605
606 }
607
608 bus_speed = slot_cur->bus_on->current_speed;
609 mode = slot_cur->bus_on->current_bus_mode;
610
611 switch (bus_speed) {
612 case BUS_SPEED_33:
613 break;
614 case BUS_SPEED_66:
615 if (mode == BUS_MODE_PCIX)
616 bus_speed += 0x01;
617 else if (mode == BUS_MODE_PCI)
618 ;
619 else
620 bus_speed = PCI_SPEED_UNKNOWN;
621 break;
622 case BUS_SPEED_100:
623 case BUS_SPEED_133:
624 bus_speed += 0x01;
625 break;
626 default:
627 bus_speed = PCI_SPEED_UNKNOWN;
628 }
629
630 bus->cur_bus_speed = bus_speed;
631
632
633 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
634 kfree(info);
635 return rc;
636}
637
638
639
640
641
642
643
644static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
645{
646 struct pci_func *func_cur;
647 struct slot *slot_cur;
648 list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
649 if (slot_cur->func) {
650 func_cur = slot_cur->func;
651 while (func_cur) {
652 if ((func_cur->busno == busno) &&
653 (func_cur->device == device) &&
654 (func_cur->function == function))
655 return func_cur;
656 func_cur = func_cur->next;
657 }
658 }
659 }
660 return NULL;
661}
662
663
664
665
666
667
668static void free_slots(void)
669{
670 struct slot *slot_cur, *next;
671
672 debug("%s -- enter\n", __func__);
673
674 list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head,
675 ibm_slot_list) {
676 pci_hp_del(slot_cur->hotplug_slot);
677 slot_cur->ctrl = NULL;
678 slot_cur->bus_on = NULL;
679
680
681
682
683
684 ibmphp_unconfigure_card(&slot_cur, -1);
685
686 pci_hp_destroy(slot_cur->hotplug_slot);
687 kfree(slot_cur->hotplug_slot->info);
688 kfree(slot_cur->hotplug_slot);
689 kfree(slot_cur);
690 }
691 debug("%s -- exit\n", __func__);
692}
693
694static void ibm_unconfigure_device(struct pci_func *func)
695{
696 struct pci_dev *temp;
697 u8 j;
698
699 debug("inside %s\n", __func__);
700 debug("func->device = %x, func->function = %x\n",
701 func->device, func->function);
702 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
703
704 pci_lock_rescan_remove();
705
706 for (j = 0; j < 0x08; j++) {
707 temp = pci_get_domain_bus_and_slot(0, func->busno,
708 (func->device << 3) | j);
709 if (temp) {
710 pci_stop_and_remove_bus_device(temp);
711 pci_dev_put(temp);
712 }
713 }
714
715 pci_dev_put(func->dev);
716
717 pci_unlock_rescan_remove();
718}
719
720
721
722
723
724
725static u8 bus_structure_fixup(u8 busno)
726{
727 struct pci_bus *bus, *b;
728 struct pci_dev *dev;
729 u16 l;
730
731 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
732 return 1;
733
734 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
735 if (!bus)
736 return 1;
737
738 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
739 if (!dev) {
740 kfree(bus);
741 return 1;
742 }
743
744 bus->number = busno;
745 bus->ops = ibmphp_pci_bus->ops;
746 dev->bus = bus;
747 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
748 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
749 (l != 0x0000) && (l != 0xffff)) {
750 debug("%s - Inside bus_structure_fixup()\n",
751 __func__);
752 b = pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
753 if (!b)
754 continue;
755
756 pci_bus_add_devices(b);
757 break;
758 }
759 }
760
761 kfree(dev);
762 kfree(bus);
763
764 return 0;
765}
766
767static int ibm_configure_device(struct pci_func *func)
768{
769 struct pci_bus *child;
770 int num;
771 int flag = 0;
772
773
774 pci_lock_rescan_remove();
775
776 if (!(bus_structure_fixup(func->busno)))
777 flag = 1;
778 if (func->dev == NULL)
779 func->dev = pci_get_domain_bus_and_slot(0, func->busno,
780 PCI_DEVFN(func->device, func->function));
781
782 if (func->dev == NULL) {
783 struct pci_bus *bus = pci_find_bus(0, func->busno);
784 if (!bus)
785 goto out;
786
787 num = pci_scan_slot(bus,
788 PCI_DEVFN(func->device, func->function));
789 if (num)
790 pci_bus_add_devices(bus);
791
792 func->dev = pci_get_domain_bus_and_slot(0, func->busno,
793 PCI_DEVFN(func->device, func->function));
794 if (func->dev == NULL) {
795 err("ERROR... : pci_dev still NULL\n");
796 goto out;
797 }
798 }
799 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
800 pci_hp_add_bridge(func->dev);
801 child = func->dev->subordinate;
802 if (child)
803 pci_bus_add_devices(child);
804 }
805
806 out:
807 pci_unlock_rescan_remove();
808 return 0;
809}
810
811
812
813
814static int is_bus_empty(struct slot *slot_cur)
815{
816 int rc;
817 struct slot *tmp_slot;
818 u8 i = slot_cur->bus_on->slot_min;
819
820 while (i <= slot_cur->bus_on->slot_max) {
821 if (i == slot_cur->number) {
822 i++;
823 continue;
824 }
825 tmp_slot = ibmphp_get_slot_from_physical_num(i);
826 if (!tmp_slot)
827 return 0;
828 rc = slot_update(&tmp_slot);
829 if (rc)
830 return 0;
831 if (SLOT_PRESENT(tmp_slot->status) &&
832 SLOT_PWRGD(tmp_slot->status))
833 return 0;
834 i++;
835 }
836 return 1;
837}
838
839
840
841
842
843
844
845static int set_bus(struct slot *slot_cur)
846{
847 int rc;
848 u8 speed;
849 u8 cmd = 0x0;
850 int retval;
851 static const struct pci_device_id ciobx[] = {
852 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
853 { },
854 };
855
856 debug("%s - entry slot # %d\n", __func__, slot_cur->number);
857 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
858 rc = slot_update(&slot_cur);
859 if (rc)
860 return rc;
861 speed = SLOT_SPEED(slot_cur->ext_status);
862 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
863 switch (speed) {
864 case HPC_SLOT_SPEED_33:
865 cmd = HPC_BUS_33CONVMODE;
866 break;
867 case HPC_SLOT_SPEED_66:
868 if (SLOT_PCIX(slot_cur->ext_status)) {
869 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
870 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
871 cmd = HPC_BUS_66PCIXMODE;
872 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
873
874
875
876 cmd = HPC_BUS_66CONVMODE;
877 else
878 cmd = HPC_BUS_33CONVMODE;
879 } else {
880 if (slot_cur->supported_speed >= BUS_SPEED_66)
881 cmd = HPC_BUS_66CONVMODE;
882 else
883 cmd = HPC_BUS_33CONVMODE;
884 }
885 break;
886 case HPC_SLOT_SPEED_133:
887 switch (slot_cur->supported_speed) {
888 case BUS_SPEED_33:
889 cmd = HPC_BUS_33CONVMODE;
890 break;
891 case BUS_SPEED_66:
892 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
893 cmd = HPC_BUS_66PCIXMODE;
894 else
895 cmd = HPC_BUS_66CONVMODE;
896 break;
897 case BUS_SPEED_100:
898 cmd = HPC_BUS_100PCIXMODE;
899 break;
900 case BUS_SPEED_133:
901
902 if (pci_dev_present(ciobx))
903 ibmphp_hpc_writeslot(slot_cur,
904 HPC_BUS_100PCIXMODE);
905 cmd = HPC_BUS_133PCIXMODE;
906 break;
907 default:
908 err("Wrong bus speed\n");
909 return -ENODEV;
910 }
911 break;
912 default:
913 err("wrong slot speed\n");
914 return -ENODEV;
915 }
916 debug("setting bus speed for slot %d, cmd %x\n",
917 slot_cur->number, cmd);
918 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
919 if (retval) {
920 err("setting bus speed failed\n");
921 return retval;
922 }
923 if (CTLR_RESULT(slot_cur->ctrl->status)) {
924 err("command not completed successfully in set_bus\n");
925 return -EIO;
926 }
927 }
928
929
930 msleep(1000);
931 debug("%s -Exit\n", __func__);
932 return 0;
933}
934
935
936
937
938
939
940
941
942static int check_limitations(struct slot *slot_cur)
943{
944 u8 i;
945 struct slot *tmp_slot;
946 u8 count = 0;
947 u8 limitation = 0;
948
949 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
950 tmp_slot = ibmphp_get_slot_from_physical_num(i);
951 if (!tmp_slot)
952 return -ENODEV;
953 if ((SLOT_PWRGD(tmp_slot->status)) &&
954 !(SLOT_CONNECT(tmp_slot->status)))
955 count++;
956 }
957 get_cur_bus_info(&slot_cur);
958 switch (slot_cur->bus_on->current_speed) {
959 case BUS_SPEED_33:
960 limitation = slot_cur->bus_on->slots_at_33_conv;
961 break;
962 case BUS_SPEED_66:
963 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
964 limitation = slot_cur->bus_on->slots_at_66_pcix;
965 else
966 limitation = slot_cur->bus_on->slots_at_66_conv;
967 break;
968 case BUS_SPEED_100:
969 limitation = slot_cur->bus_on->slots_at_100_pcix;
970 break;
971 case BUS_SPEED_133:
972 limitation = slot_cur->bus_on->slots_at_133_pcix;
973 break;
974 }
975
976 if ((count + 1) > limitation)
977 return -EINVAL;
978 return 0;
979}
980
981static inline void print_card_capability(struct slot *slot_cur)
982{
983 info("capability of the card is ");
984 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
985 info(" 133 MHz PCI-X\n");
986 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
987 info(" 66 MHz PCI-X\n");
988 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
989 info(" 66 MHz PCI\n");
990 else
991 info(" 33 MHz PCI\n");
992
993}
994
995
996
997
998
999
1000static int enable_slot(struct hotplug_slot *hs)
1001{
1002 int rc, i, rcpr;
1003 struct slot *slot_cur;
1004 u8 function;
1005 struct pci_func *tmp_func;
1006
1007 ibmphp_lock_operations();
1008
1009 debug("ENABLING SLOT........\n");
1010 slot_cur = hs->private;
1011
1012 rc = validate(slot_cur, ENABLE);
1013 if (rc) {
1014 err("validate function failed\n");
1015 goto error_nopower;
1016 }
1017
1018 attn_LED_blink(slot_cur);
1019
1020 rc = set_bus(slot_cur);
1021 if (rc) {
1022 err("was not able to set the bus\n");
1023 goto error_nopower;
1024 }
1025
1026
1027 get_cur_bus_info(&slot_cur);
1028 debug("the current bus speed right after set_bus = %x\n",
1029 slot_cur->bus_on->current_speed);
1030
1031
1032 rc = check_limitations(slot_cur);
1033 if (rc) {
1034 err("Adding this card exceeds the limitations of this bus.\n");
1035 err("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus.\n");
1036 err("Try hot-adding into another bus\n");
1037 rc = -EINVAL;
1038 goto error_nopower;
1039 }
1040
1041 rc = power_on(slot_cur);
1042
1043 if (rc) {
1044 err("something wrong when powering up... please see below for details\n");
1045
1046 attn_off(slot_cur);
1047 attn_on(slot_cur);
1048 if (slot_update(&slot_cur)) {
1049 attn_off(slot_cur);
1050 attn_on(slot_cur);
1051 rc = -ENODEV;
1052 goto exit;
1053 }
1054
1055 if ((SLOT_POWER(slot_cur->status)) &&
1056 !(SLOT_PWRGD(slot_cur->status)))
1057 err("power fault occurred trying to power up\n");
1058 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1059 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
1060 print_card_capability(slot_cur);
1061 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1062 err("bus mode mismatch occurred. please check current bus mode and card capability\n");
1063 print_card_capability(slot_cur);
1064 }
1065 ibmphp_update_slot_info(slot_cur);
1066 goto exit;
1067 }
1068 debug("after power_on\n");
1069
1070 get_cur_bus_info(&slot_cur);
1071 debug("the current bus speed right after power_on = %x\n",
1072 slot_cur->bus_on->current_speed);
1073
1074
1075 rc = slot_update(&slot_cur);
1076 if (rc)
1077 goto error_power;
1078
1079 rc = -EINVAL;
1080 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1081 err("power fault occurred trying to power up...\n");
1082 goto error_power;
1083 }
1084 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1085 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
1086 print_card_capability(slot_cur);
1087 goto error_power;
1088 }
1089
1090
1091 if (!(SLOT_POWER(slot_cur->status))) {
1092 err("power on failed...\n");
1093 goto error_power;
1094 }
1095
1096 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1097 if (!slot_cur->func) {
1098
1099
1100 rc = -ENOMEM;
1101 goto error_power;
1102 }
1103 slot_cur->func->busno = slot_cur->bus;
1104 slot_cur->func->device = slot_cur->device;
1105 for (i = 0; i < 4; i++)
1106 slot_cur->func->irq[i] = slot_cur->irq[i];
1107
1108 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1109 slot_cur->bus, slot_cur->device);
1110
1111 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1112 err("configure_card was unsuccessful...\n");
1113
1114
1115 ibmphp_unconfigure_card(&slot_cur, 1);
1116 debug("after unconfigure_card\n");
1117 slot_cur->func = NULL;
1118 rc = -ENOMEM;
1119 goto error_power;
1120 }
1121
1122 function = 0x00;
1123 do {
1124 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1125 function++);
1126 if (tmp_func && !(tmp_func->dev))
1127 ibm_configure_device(tmp_func);
1128 } while (tmp_func);
1129
1130 attn_off(slot_cur);
1131 if (slot_update(&slot_cur)) {
1132 rc = -EFAULT;
1133 goto exit;
1134 }
1135 ibmphp_print_test();
1136 rc = ibmphp_update_slot_info(slot_cur);
1137exit:
1138 ibmphp_unlock_operations();
1139 return rc;
1140
1141error_nopower:
1142 attn_off(slot_cur);
1143 attn_on(slot_cur);
1144error_cont:
1145 rcpr = slot_update(&slot_cur);
1146 if (rcpr) {
1147 rc = rcpr;
1148 goto exit;
1149 }
1150 ibmphp_update_slot_info(slot_cur);
1151 goto exit;
1152
1153error_power:
1154 attn_off(slot_cur);
1155 attn_on(slot_cur);
1156 rcpr = power_off(slot_cur);
1157 if (rcpr) {
1158 rc = rcpr;
1159 goto exit;
1160 }
1161 goto error_cont;
1162}
1163
1164
1165
1166
1167
1168
1169
1170static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1171{
1172 struct slot *slot = hotplug_slot->private;
1173 int rc;
1174
1175 ibmphp_lock_operations();
1176 rc = ibmphp_do_disable_slot(slot);
1177 ibmphp_unlock_operations();
1178 return rc;
1179}
1180
1181int ibmphp_do_disable_slot(struct slot *slot_cur)
1182{
1183 int rc;
1184 u8 flag;
1185
1186 debug("DISABLING SLOT...\n");
1187
1188 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL))
1189 return -ENODEV;
1190
1191 flag = slot_cur->flag;
1192 slot_cur->flag = 1;
1193
1194 if (flag == 1) {
1195 rc = validate(slot_cur, DISABLE);
1196
1197 if (rc)
1198 goto error;
1199 }
1200 attn_LED_blink(slot_cur);
1201
1202 if (slot_cur->func == NULL) {
1203
1204 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1205 if (!slot_cur->func) {
1206 rc = -ENOMEM;
1207 goto error;
1208 }
1209 slot_cur->func->busno = slot_cur->bus;
1210 slot_cur->func->device = slot_cur->device;
1211 }
1212
1213 ibm_unconfigure_device(slot_cur->func);
1214
1215
1216
1217
1218
1219
1220
1221
1222 if (!flag) {
1223 attn_off(slot_cur);
1224 return 0;
1225 }
1226
1227 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1228 slot_cur->func = NULL;
1229 debug("in disable_slot. after unconfigure_card\n");
1230 if (rc) {
1231 err("could not unconfigure card.\n");
1232 goto error;
1233 }
1234
1235 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1236 if (rc)
1237 goto error;
1238
1239 attn_off(slot_cur);
1240 rc = slot_update(&slot_cur);
1241 if (rc)
1242 goto exit;
1243
1244 rc = ibmphp_update_slot_info(slot_cur);
1245 ibmphp_print_test();
1246exit:
1247 return rc;
1248
1249error:
1250
1251 attn_off(slot_cur);
1252 attn_on(slot_cur);
1253 if (slot_update(&slot_cur)) {
1254 rc = -EFAULT;
1255 goto exit;
1256 }
1257 if (flag)
1258 ibmphp_update_slot_info(slot_cur);
1259 goto exit;
1260}
1261
1262struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1263 .set_attention_status = set_attention_status,
1264 .enable_slot = enable_slot,
1265 .disable_slot = ibmphp_disable_slot,
1266 .hardware_test = NULL,
1267 .get_power_status = get_power_status,
1268 .get_attention_status = get_attention_status,
1269 .get_latch_status = get_latch_status,
1270 .get_adapter_status = get_adapter_present,
1271
1272
1273
1274};
1275
1276static void ibmphp_unload(void)
1277{
1278 free_slots();
1279 debug("after slots\n");
1280 ibmphp_free_resources();
1281 debug("after resources\n");
1282 ibmphp_free_bus_info_queue();
1283 debug("after bus info\n");
1284 ibmphp_free_ebda_hpc_queue();
1285 debug("after ebda hpc\n");
1286 ibmphp_free_ebda_pci_rsrc_queue();
1287 debug("after ebda pci rsrc\n");
1288 kfree(ibmphp_pci_bus);
1289}
1290
1291static int __init ibmphp_init(void)
1292{
1293 struct pci_bus *bus;
1294 int i = 0;
1295 int rc = 0;
1296
1297 init_flag = 1;
1298
1299 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1300
1301 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1302 if (!ibmphp_pci_bus) {
1303 rc = -ENOMEM;
1304 goto exit;
1305 }
1306
1307 bus = pci_find_bus(0, 0);
1308 if (!bus) {
1309 err("Can't find the root pci bus, can not continue\n");
1310 rc = -ENODEV;
1311 goto error;
1312 }
1313 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1314
1315 ibmphp_debug = debug;
1316
1317 ibmphp_hpc_initvars();
1318
1319 for (i = 0; i < 16; i++)
1320 irqs[i] = 0;
1321
1322 rc = ibmphp_access_ebda();
1323 if (rc)
1324 goto error;
1325 debug("after ibmphp_access_ebda()\n");
1326
1327 rc = ibmphp_rsrc_init();
1328 if (rc)
1329 goto error;
1330 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1331
1332 max_slots = get_max_slots();
1333
1334 rc = ibmphp_register_pci();
1335 if (rc)
1336 goto error;
1337
1338 if (init_ops()) {
1339 rc = -ENODEV;
1340 goto error;
1341 }
1342
1343 ibmphp_print_test();
1344 rc = ibmphp_hpc_start_poll_thread();
1345 if (rc)
1346 goto error;
1347
1348exit:
1349 return rc;
1350
1351error:
1352 ibmphp_unload();
1353 goto exit;
1354}
1355
1356static void __exit ibmphp_exit(void)
1357{
1358 ibmphp_hpc_stop_poll_thread();
1359 debug("after polling\n");
1360 ibmphp_unload();
1361 debug("done\n");
1362}
1363
1364module_init(ibmphp_init);
1365module_exit(ibmphp_exit);
1366