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;
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_deregister(slot_cur->hotplug_slot);
677 }
678 debug("%s -- exit\n", __func__);
679}
680
681static void ibm_unconfigure_device(struct pci_func *func)
682{
683 struct pci_dev *temp;
684 u8 j;
685
686 debug("inside %s\n", __func__);
687 debug("func->device = %x, func->function = %x\n",
688 func->device, func->function);
689 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
690
691 pci_lock_rescan_remove();
692
693 for (j = 0; j < 0x08; j++) {
694 temp = pci_get_domain_bus_and_slot(0, func->busno,
695 (func->device << 3) | j);
696 if (temp) {
697 pci_stop_and_remove_bus_device(temp);
698 pci_dev_put(temp);
699 }
700 }
701
702 pci_dev_put(func->dev);
703
704 pci_unlock_rescan_remove();
705}
706
707
708
709
710
711
712static u8 bus_structure_fixup(u8 busno)
713{
714 struct pci_bus *bus, *b;
715 struct pci_dev *dev;
716 u16 l;
717
718 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
719 return 1;
720
721 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
722 if (!bus)
723 return 1;
724
725 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
726 if (!dev) {
727 kfree(bus);
728 return 1;
729 }
730
731 bus->number = busno;
732 bus->ops = ibmphp_pci_bus->ops;
733 dev->bus = bus;
734 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
735 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
736 (l != 0x0000) && (l != 0xffff)) {
737 debug("%s - Inside bus_structure_fixup()\n",
738 __func__);
739 b = pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
740 if (!b)
741 continue;
742
743 pci_bus_add_devices(b);
744 break;
745 }
746 }
747
748 kfree(dev);
749 kfree(bus);
750
751 return 0;
752}
753
754static int ibm_configure_device(struct pci_func *func)
755{
756 struct pci_bus *child;
757 int num;
758 int flag = 0;
759
760
761 pci_lock_rescan_remove();
762
763 if (!(bus_structure_fixup(func->busno)))
764 flag = 1;
765 if (func->dev == NULL)
766 func->dev = pci_get_domain_bus_and_slot(0, func->busno,
767 PCI_DEVFN(func->device, func->function));
768
769 if (func->dev == NULL) {
770 struct pci_bus *bus = pci_find_bus(0, func->busno);
771 if (!bus)
772 goto out;
773
774 num = pci_scan_slot(bus,
775 PCI_DEVFN(func->device, func->function));
776 if (num)
777 pci_bus_add_devices(bus);
778
779 func->dev = pci_get_domain_bus_and_slot(0, func->busno,
780 PCI_DEVFN(func->device, func->function));
781 if (func->dev == NULL) {
782 err("ERROR... : pci_dev still NULL\n");
783 goto out;
784 }
785 }
786 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
787 pci_hp_add_bridge(func->dev);
788 child = func->dev->subordinate;
789 if (child)
790 pci_bus_add_devices(child);
791 }
792
793 out:
794 pci_unlock_rescan_remove();
795 return 0;
796}
797
798
799
800
801static int is_bus_empty(struct slot *slot_cur)
802{
803 int rc;
804 struct slot *tmp_slot;
805 u8 i = slot_cur->bus_on->slot_min;
806
807 while (i <= slot_cur->bus_on->slot_max) {
808 if (i == slot_cur->number) {
809 i++;
810 continue;
811 }
812 tmp_slot = ibmphp_get_slot_from_physical_num(i);
813 if (!tmp_slot)
814 return 0;
815 rc = slot_update(&tmp_slot);
816 if (rc)
817 return 0;
818 if (SLOT_PRESENT(tmp_slot->status) &&
819 SLOT_PWRGD(tmp_slot->status))
820 return 0;
821 i++;
822 }
823 return 1;
824}
825
826
827
828
829
830
831
832static int set_bus(struct slot *slot_cur)
833{
834 int rc;
835 u8 speed;
836 u8 cmd = 0x0;
837 int retval;
838 static const struct pci_device_id ciobx[] = {
839 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
840 { },
841 };
842
843 debug("%s - entry slot # %d\n", __func__, slot_cur->number);
844 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
845 rc = slot_update(&slot_cur);
846 if (rc)
847 return rc;
848 speed = SLOT_SPEED(slot_cur->ext_status);
849 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
850 switch (speed) {
851 case HPC_SLOT_SPEED_33:
852 cmd = HPC_BUS_33CONVMODE;
853 break;
854 case HPC_SLOT_SPEED_66:
855 if (SLOT_PCIX(slot_cur->ext_status)) {
856 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
857 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
858 cmd = HPC_BUS_66PCIXMODE;
859 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
860
861
862
863 cmd = HPC_BUS_66CONVMODE;
864 else
865 cmd = HPC_BUS_33CONVMODE;
866 } else {
867 if (slot_cur->supported_speed >= BUS_SPEED_66)
868 cmd = HPC_BUS_66CONVMODE;
869 else
870 cmd = HPC_BUS_33CONVMODE;
871 }
872 break;
873 case HPC_SLOT_SPEED_133:
874 switch (slot_cur->supported_speed) {
875 case BUS_SPEED_33:
876 cmd = HPC_BUS_33CONVMODE;
877 break;
878 case BUS_SPEED_66:
879 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
880 cmd = HPC_BUS_66PCIXMODE;
881 else
882 cmd = HPC_BUS_66CONVMODE;
883 break;
884 case BUS_SPEED_100:
885 cmd = HPC_BUS_100PCIXMODE;
886 break;
887 case BUS_SPEED_133:
888
889 if (pci_dev_present(ciobx))
890 ibmphp_hpc_writeslot(slot_cur,
891 HPC_BUS_100PCIXMODE);
892 cmd = HPC_BUS_133PCIXMODE;
893 break;
894 default:
895 err("Wrong bus speed\n");
896 return -ENODEV;
897 }
898 break;
899 default:
900 err("wrong slot speed\n");
901 return -ENODEV;
902 }
903 debug("setting bus speed for slot %d, cmd %x\n",
904 slot_cur->number, cmd);
905 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
906 if (retval) {
907 err("setting bus speed failed\n");
908 return retval;
909 }
910 if (CTLR_RESULT(slot_cur->ctrl->status)) {
911 err("command not completed successfully in set_bus\n");
912 return -EIO;
913 }
914 }
915
916
917 msleep(1000);
918 debug("%s -Exit\n", __func__);
919 return 0;
920}
921
922
923
924
925
926
927
928
929static int check_limitations(struct slot *slot_cur)
930{
931 u8 i;
932 struct slot *tmp_slot;
933 u8 count = 0;
934 u8 limitation = 0;
935
936 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
937 tmp_slot = ibmphp_get_slot_from_physical_num(i);
938 if (!tmp_slot)
939 return -ENODEV;
940 if ((SLOT_PWRGD(tmp_slot->status)) &&
941 !(SLOT_CONNECT(tmp_slot->status)))
942 count++;
943 }
944 get_cur_bus_info(&slot_cur);
945 switch (slot_cur->bus_on->current_speed) {
946 case BUS_SPEED_33:
947 limitation = slot_cur->bus_on->slots_at_33_conv;
948 break;
949 case BUS_SPEED_66:
950 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
951 limitation = slot_cur->bus_on->slots_at_66_pcix;
952 else
953 limitation = slot_cur->bus_on->slots_at_66_conv;
954 break;
955 case BUS_SPEED_100:
956 limitation = slot_cur->bus_on->slots_at_100_pcix;
957 break;
958 case BUS_SPEED_133:
959 limitation = slot_cur->bus_on->slots_at_133_pcix;
960 break;
961 }
962
963 if ((count + 1) > limitation)
964 return -EINVAL;
965 return 0;
966}
967
968static inline void print_card_capability(struct slot *slot_cur)
969{
970 info("capability of the card is ");
971 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
972 info(" 133 MHz PCI-X\n");
973 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
974 info(" 66 MHz PCI-X\n");
975 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
976 info(" 66 MHz PCI\n");
977 else
978 info(" 33 MHz PCI\n");
979
980}
981
982
983
984
985
986
987static int enable_slot(struct hotplug_slot *hs)
988{
989 int rc, i, rcpr;
990 struct slot *slot_cur;
991 u8 function;
992 struct pci_func *tmp_func;
993
994 ibmphp_lock_operations();
995
996 debug("ENABLING SLOT........\n");
997 slot_cur = hs->private;
998
999 rc = validate(slot_cur, ENABLE);
1000 if (rc) {
1001 err("validate function failed\n");
1002 goto error_nopower;
1003 }
1004
1005 attn_LED_blink(slot_cur);
1006
1007 rc = set_bus(slot_cur);
1008 if (rc) {
1009 err("was not able to set the bus\n");
1010 goto error_nopower;
1011 }
1012
1013
1014 get_cur_bus_info(&slot_cur);
1015 debug("the current bus speed right after set_bus = %x\n",
1016 slot_cur->bus_on->current_speed);
1017
1018
1019 rc = check_limitations(slot_cur);
1020 if (rc) {
1021 err("Adding this card exceeds the limitations of this bus.\n");
1022 err("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus.\n");
1023 err("Try hot-adding into another bus\n");
1024 rc = -EINVAL;
1025 goto error_nopower;
1026 }
1027
1028 rc = power_on(slot_cur);
1029
1030 if (rc) {
1031 err("something wrong when powering up... please see below for details\n");
1032
1033 attn_off(slot_cur);
1034 attn_on(slot_cur);
1035 if (slot_update(&slot_cur)) {
1036 attn_off(slot_cur);
1037 attn_on(slot_cur);
1038 rc = -ENODEV;
1039 goto exit;
1040 }
1041
1042 if ((SLOT_POWER(slot_cur->status)) &&
1043 !(SLOT_PWRGD(slot_cur->status)))
1044 err("power fault occurred trying to power up\n");
1045 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1046 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
1047 print_card_capability(slot_cur);
1048 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1049 err("bus mode mismatch occurred. please check current bus mode and card capability\n");
1050 print_card_capability(slot_cur);
1051 }
1052 ibmphp_update_slot_info(slot_cur);
1053 goto exit;
1054 }
1055 debug("after power_on\n");
1056
1057 get_cur_bus_info(&slot_cur);
1058 debug("the current bus speed right after power_on = %x\n",
1059 slot_cur->bus_on->current_speed);
1060
1061
1062 rc = slot_update(&slot_cur);
1063 if (rc)
1064 goto error_power;
1065
1066 rc = -EINVAL;
1067 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1068 err("power fault occurred trying to power up...\n");
1069 goto error_power;
1070 }
1071 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1072 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
1073 print_card_capability(slot_cur);
1074 goto error_power;
1075 }
1076
1077
1078 if (!(SLOT_POWER(slot_cur->status))) {
1079 err("power on failed...\n");
1080 goto error_power;
1081 }
1082
1083 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1084 if (!slot_cur->func) {
1085
1086
1087 rc = -ENOMEM;
1088 goto error_power;
1089 }
1090 slot_cur->func->busno = slot_cur->bus;
1091 slot_cur->func->device = slot_cur->device;
1092 for (i = 0; i < 4; i++)
1093 slot_cur->func->irq[i] = slot_cur->irq[i];
1094
1095 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1096 slot_cur->bus, slot_cur->device);
1097
1098 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1099 err("configure_card was unsuccessful...\n");
1100
1101
1102 ibmphp_unconfigure_card(&slot_cur, 1);
1103 debug("after unconfigure_card\n");
1104 slot_cur->func = NULL;
1105 rc = -ENOMEM;
1106 goto error_power;
1107 }
1108
1109 function = 0x00;
1110 do {
1111 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1112 function++);
1113 if (tmp_func && !(tmp_func->dev))
1114 ibm_configure_device(tmp_func);
1115 } while (tmp_func);
1116
1117 attn_off(slot_cur);
1118 if (slot_update(&slot_cur)) {
1119 rc = -EFAULT;
1120 goto exit;
1121 }
1122 ibmphp_print_test();
1123 rc = ibmphp_update_slot_info(slot_cur);
1124exit:
1125 ibmphp_unlock_operations();
1126 return rc;
1127
1128error_nopower:
1129 attn_off(slot_cur);
1130 attn_on(slot_cur);
1131error_cont:
1132 rcpr = slot_update(&slot_cur);
1133 if (rcpr) {
1134 rc = rcpr;
1135 goto exit;
1136 }
1137 ibmphp_update_slot_info(slot_cur);
1138 goto exit;
1139
1140error_power:
1141 attn_off(slot_cur);
1142 attn_on(slot_cur);
1143 rcpr = power_off(slot_cur);
1144 if (rcpr) {
1145 rc = rcpr;
1146 goto exit;
1147 }
1148 goto error_cont;
1149}
1150
1151
1152
1153
1154
1155
1156
1157static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1158{
1159 struct slot *slot = hotplug_slot->private;
1160 int rc;
1161
1162 ibmphp_lock_operations();
1163 rc = ibmphp_do_disable_slot(slot);
1164 ibmphp_unlock_operations();
1165 return rc;
1166}
1167
1168int ibmphp_do_disable_slot(struct slot *slot_cur)
1169{
1170 int rc;
1171 u8 flag;
1172
1173 debug("DISABLING SLOT...\n");
1174
1175 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL))
1176 return -ENODEV;
1177
1178 flag = slot_cur->flag;
1179 slot_cur->flag = 1;
1180
1181 if (flag == 1) {
1182 rc = validate(slot_cur, DISABLE);
1183
1184 if (rc)
1185 goto error;
1186 }
1187 attn_LED_blink(slot_cur);
1188
1189 if (slot_cur->func == NULL) {
1190
1191 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1192 if (!slot_cur->func) {
1193 rc = -ENOMEM;
1194 goto error;
1195 }
1196 slot_cur->func->busno = slot_cur->bus;
1197 slot_cur->func->device = slot_cur->device;
1198 }
1199
1200 ibm_unconfigure_device(slot_cur->func);
1201
1202
1203
1204
1205
1206
1207
1208
1209 if (!flag) {
1210 attn_off(slot_cur);
1211 return 0;
1212 }
1213
1214 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1215 slot_cur->func = NULL;
1216 debug("in disable_slot. after unconfigure_card\n");
1217 if (rc) {
1218 err("could not unconfigure card.\n");
1219 goto error;
1220 }
1221
1222 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1223 if (rc)
1224 goto error;
1225
1226 attn_off(slot_cur);
1227 rc = slot_update(&slot_cur);
1228 if (rc)
1229 goto exit;
1230
1231 rc = ibmphp_update_slot_info(slot_cur);
1232 ibmphp_print_test();
1233exit:
1234 return rc;
1235
1236error:
1237
1238 attn_off(slot_cur);
1239 attn_on(slot_cur);
1240 if (slot_update(&slot_cur)) {
1241 rc = -EFAULT;
1242 goto exit;
1243 }
1244 if (flag)
1245 ibmphp_update_slot_info(slot_cur);
1246 goto exit;
1247}
1248
1249struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1250 .set_attention_status = set_attention_status,
1251 .enable_slot = enable_slot,
1252 .disable_slot = ibmphp_disable_slot,
1253 .hardware_test = NULL,
1254 .get_power_status = get_power_status,
1255 .get_attention_status = get_attention_status,
1256 .get_latch_status = get_latch_status,
1257 .get_adapter_status = get_adapter_present,
1258
1259
1260
1261};
1262
1263static void ibmphp_unload(void)
1264{
1265 free_slots();
1266 debug("after slots\n");
1267 ibmphp_free_resources();
1268 debug("after resources\n");
1269 ibmphp_free_bus_info_queue();
1270 debug("after bus info\n");
1271 ibmphp_free_ebda_hpc_queue();
1272 debug("after ebda hpc\n");
1273 ibmphp_free_ebda_pci_rsrc_queue();
1274 debug("after ebda pci rsrc\n");
1275 kfree(ibmphp_pci_bus);
1276}
1277
1278static int __init ibmphp_init(void)
1279{
1280 struct pci_bus *bus;
1281 int i = 0;
1282 int rc = 0;
1283
1284 init_flag = 1;
1285
1286 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1287
1288 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1289 if (!ibmphp_pci_bus) {
1290 rc = -ENOMEM;
1291 goto exit;
1292 }
1293
1294 bus = pci_find_bus(0, 0);
1295 if (!bus) {
1296 err("Can't find the root pci bus, can not continue\n");
1297 rc = -ENODEV;
1298 goto error;
1299 }
1300 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1301
1302 ibmphp_debug = debug;
1303
1304 ibmphp_hpc_initvars();
1305
1306 for (i = 0; i < 16; i++)
1307 irqs[i] = 0;
1308
1309 rc = ibmphp_access_ebda();
1310 if (rc)
1311 goto error;
1312 debug("after ibmphp_access_ebda()\n");
1313
1314 rc = ibmphp_rsrc_init();
1315 if (rc)
1316 goto error;
1317 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1318
1319 max_slots = get_max_slots();
1320
1321 rc = ibmphp_register_pci();
1322 if (rc)
1323 goto error;
1324
1325 if (init_ops()) {
1326 rc = -ENODEV;
1327 goto error;
1328 }
1329
1330 ibmphp_print_test();
1331 rc = ibmphp_hpc_start_poll_thread();
1332 if (rc)
1333 goto error;
1334
1335exit:
1336 return rc;
1337
1338error:
1339 ibmphp_unload();
1340 goto exit;
1341}
1342
1343static void __exit ibmphp_exit(void)
1344{
1345 ibmphp_hpc_stop_poll_thread();
1346 debug("after polling\n");
1347 ibmphp_unload();
1348 debug("done\n");
1349}
1350
1351module_init(ibmphp_init);
1352module_exit(ibmphp_exit);
1353