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