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 <asm/io_apic.h>
40#include "ibmphp.h"
41
42#define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
43#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
44#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
45#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
46#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
47
48#define DRIVER_VERSION "0.6"
49#define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
50
51int ibmphp_debug;
52
53static bool debug;
54module_param(debug, bool, S_IRUGO | S_IWUSR);
55MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
56MODULE_LICENSE ("GPL");
57MODULE_DESCRIPTION (DRIVER_DESC);
58
59struct pci_bus *ibmphp_pci_bus;
60static int max_slots;
61
62static int irqs[16];
63
64
65static int init_flag;
66
67
68
69
70
71
72
73
74
75static inline int get_cur_bus_info(struct slot **sl)
76{
77 int rc = 1;
78 struct slot *slot_cur = *sl;
79
80 debug("options = %x\n", slot_cur->ctrl->options);
81 debug("revision = %x\n", slot_cur->ctrl->revision);
82
83 if (READ_BUS_STATUS(slot_cur->ctrl))
84 rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
85
86 if (rc)
87 return rc;
88
89 slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
90 if (READ_BUS_MODE(slot_cur->ctrl))
91 slot_cur->bus_on->current_bus_mode =
92 CURRENT_BUS_MODE(slot_cur->busstatus);
93 else
94 slot_cur->bus_on->current_bus_mode = 0xFF;
95
96 debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
97 slot_cur->busstatus,
98 slot_cur->bus_on->current_speed,
99 slot_cur->bus_on->current_bus_mode);
100
101 *sl = slot_cur;
102 return 0;
103}
104
105static inline int slot_update(struct slot **sl)
106{
107 int rc;
108 rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
109 if (rc)
110 return rc;
111 if (!init_flag)
112 rc = get_cur_bus_info(sl);
113 return rc;
114}
115
116static int __init get_max_slots (void)
117{
118 struct slot *slot_cur;
119 struct list_head *tmp;
120 u8 slot_count = 0;
121
122 list_for_each(tmp, &ibmphp_slot_head) {
123 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
124
125 slot_count = max(slot_count, slot_cur->number);
126 }
127 return slot_count;
128}
129
130
131
132
133
134
135
136int ibmphp_init_devno(struct slot **cur_slot)
137{
138 struct irq_routing_table *rtable;
139 int len;
140 int loop;
141 int i;
142
143 rtable = pcibios_get_irq_routing_table();
144 if (!rtable) {
145 err("no BIOS routing table...\n");
146 return -ENOMEM;
147 }
148
149 len = (rtable->size - sizeof(struct irq_routing_table)) /
150 sizeof(struct irq_info);
151
152 if (!len) {
153 kfree(rtable);
154 return -1;
155 }
156 for (loop = 0; loop < len; loop++) {
157 if ((*cur_slot)->number == rtable->slots[loop].slot &&
158 (*cur_slot)->bus == rtable->slots[loop].bus) {
159 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
160 for (i = 0; i < 4; i++)
161 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
162 (int) (*cur_slot)->device, i);
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 struct list_head *tmp;
505 int retval;
506 int rc;
507
508 list_for_each(tmp, &ibmphp_slot_head) {
509 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
510
511 if (!slot_cur)
512 return -ENODEV;
513
514 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
515 slot_cur->number);
516 if (slot_cur->ctrl->revision == 0xFF)
517 if (get_ctrl_revision(slot_cur,
518 &slot_cur->ctrl->revision))
519 return -1;
520
521 if (slot_cur->bus_on->current_speed == 0xFF)
522 if (get_cur_bus_info(&slot_cur))
523 return -1;
524 get_max_bus_speed(slot_cur);
525
526 if (slot_cur->ctrl->options == 0xFF)
527 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
528 return -1;
529
530 retval = slot_update(&slot_cur);
531 if (retval)
532 return retval;
533
534 debug("status = %x\n", slot_cur->status);
535 debug("ext_status = %x\n", slot_cur->ext_status);
536 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
537 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
538 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
539
540 if ((SLOT_PWRGD(slot_cur->status)) &&
541 !(SLOT_PRESENT(slot_cur->status)) &&
542 !(SLOT_LATCH(slot_cur->status))) {
543 debug("BEFORE POWER OFF COMMAND\n");
544 rc = power_off(slot_cur);
545 if (rc)
546 return rc;
547
548
549
550
551
552
553 }
554 }
555 init_flag = 0;
556 return 0;
557}
558
559
560
561
562
563
564static int validate(struct slot *slot_cur, int opn)
565{
566 int number;
567 int retval;
568
569 if (!slot_cur)
570 return -ENODEV;
571 number = slot_cur->number;
572 if ((number > max_slots) || (number < 0))
573 return -EBADSLT;
574 debug("slot_number in validate is %d\n", slot_cur->number);
575
576 retval = slot_update(&slot_cur);
577 if (retval)
578 return retval;
579
580 switch (opn) {
581 case ENABLE:
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 case DISABLE:
588 if ((SLOT_PWRGD(slot_cur->status)) &&
589 (SLOT_PRESENT(slot_cur->status)) &&
590 !(SLOT_LATCH(slot_cur->status)))
591 return 0;
592 break;
593 default:
594 break;
595 }
596 err("validate failed....\n");
597 return -EINVAL;
598}
599
600
601
602
603
604
605int ibmphp_update_slot_info(struct slot *slot_cur)
606{
607 struct hotplug_slot_info *info;
608 struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus;
609 int rc;
610 u8 bus_speed;
611 u8 mode;
612
613 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
614 if (!info) {
615 err("out of system memory\n");
616 return -ENOMEM;
617 }
618
619 info->power_status = SLOT_PWRGD(slot_cur->status);
620 info->attention_status = SLOT_ATTN(slot_cur->status,
621 slot_cur->ext_status);
622 info->latch_status = SLOT_LATCH(slot_cur->status);
623 if (!SLOT_PRESENT(slot_cur->status)) {
624 info->adapter_status = 0;
625
626 } else {
627 info->adapter_status = 1;
628
629
630 }
631
632 bus_speed = slot_cur->bus_on->current_speed;
633 mode = slot_cur->bus_on->current_bus_mode;
634
635 switch (bus_speed) {
636 case BUS_SPEED_33:
637 break;
638 case BUS_SPEED_66:
639 if (mode == BUS_MODE_PCIX)
640 bus_speed += 0x01;
641 else if (mode == BUS_MODE_PCI)
642 ;
643 else
644 bus_speed = PCI_SPEED_UNKNOWN;
645 break;
646 case BUS_SPEED_100:
647 case BUS_SPEED_133:
648 bus_speed += 0x01;
649 break;
650 default:
651 bus_speed = PCI_SPEED_UNKNOWN;
652 }
653
654 bus->cur_bus_speed = bus_speed;
655
656
657 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
658 kfree(info);
659 return rc;
660}
661
662
663
664
665
666
667
668static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
669{
670 struct pci_func *func_cur;
671 struct slot *slot_cur;
672 struct list_head *tmp;
673 list_for_each(tmp, &ibmphp_slot_head) {
674 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
675 if (slot_cur->func) {
676 func_cur = slot_cur->func;
677 while (func_cur) {
678 if ((func_cur->busno == busno) &&
679 (func_cur->device == device) &&
680 (func_cur->function == function))
681 return func_cur;
682 func_cur = func_cur->next;
683 }
684 }
685 }
686 return NULL;
687}
688
689
690
691
692
693
694static void free_slots(void)
695{
696 struct slot *slot_cur;
697 struct list_head *tmp;
698 struct list_head *next;
699
700 debug("%s -- enter\n", __func__);
701
702 list_for_each_safe(tmp, next, &ibmphp_slot_head) {
703 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
704 pci_hp_deregister(slot_cur->hotplug_slot);
705 }
706 debug("%s -- exit\n", __func__);
707}
708
709static void ibm_unconfigure_device(struct pci_func *func)
710{
711 struct pci_dev *temp;
712 u8 j;
713
714 debug("inside %s\n", __func__);
715 debug("func->device = %x, func->function = %x\n",
716 func->device, func->function);
717 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
718
719 pci_lock_rescan_remove();
720
721 for (j = 0; j < 0x08; j++) {
722 temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
723 if (temp) {
724 pci_stop_and_remove_bus_device(temp);
725 pci_dev_put(temp);
726 }
727 }
728
729 pci_dev_put(func->dev);
730
731 pci_unlock_rescan_remove();
732}
733
734
735
736
737
738
739static u8 bus_structure_fixup(u8 busno)
740{
741 struct pci_bus *bus, *b;
742 struct pci_dev *dev;
743 u16 l;
744
745 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
746 return 1;
747
748 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
749 if (!bus) {
750 err("%s - out of memory\n", __func__);
751 return 1;
752 }
753 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
754 if (!dev) {
755 kfree(bus);
756 err("%s - out of memory\n", __func__);
757 return 1;
758 }
759
760 bus->number = busno;
761 bus->ops = ibmphp_pci_bus->ops;
762 dev->bus = bus;
763 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
764 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
765 (l != 0x0000) && (l != 0xffff)) {
766 debug("%s - Inside bus_structure_fixup()\n",
767 __func__);
768 b = pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
769 if (!b)
770 continue;
771
772 pci_bus_add_devices(b);
773 break;
774 }
775 }
776
777 kfree(dev);
778 kfree(bus);
779
780 return 0;
781}
782
783static int ibm_configure_device(struct pci_func *func)
784{
785 struct pci_bus *child;
786 int num;
787 int flag = 0;
788
789
790 pci_lock_rescan_remove();
791
792 if (!(bus_structure_fixup(func->busno)))
793 flag = 1;
794 if (func->dev == NULL)
795 func->dev = pci_get_bus_and_slot(func->busno,
796 PCI_DEVFN(func->device, func->function));
797
798 if (func->dev == NULL) {
799 struct pci_bus *bus = pci_find_bus(0, func->busno);
800 if (!bus)
801 goto out;
802
803 num = pci_scan_slot(bus,
804 PCI_DEVFN(func->device, func->function));
805 if (num)
806 pci_bus_add_devices(bus);
807
808 func->dev = pci_get_bus_and_slot(func->busno,
809 PCI_DEVFN(func->device, func->function));
810 if (func->dev == NULL) {
811 err("ERROR... : pci_dev still NULL\n");
812 goto out;
813 }
814 }
815 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
816 pci_hp_add_bridge(func->dev);
817 child = func->dev->subordinate;
818 if (child)
819 pci_bus_add_devices(child);
820 }
821
822 out:
823 pci_unlock_rescan_remove();
824 return 0;
825}
826
827
828
829
830static int is_bus_empty(struct slot *slot_cur)
831{
832 int rc;
833 struct slot *tmp_slot;
834 u8 i = slot_cur->bus_on->slot_min;
835
836 while (i <= slot_cur->bus_on->slot_max) {
837 if (i == slot_cur->number) {
838 i++;
839 continue;
840 }
841 tmp_slot = ibmphp_get_slot_from_physical_num(i);
842 if (!tmp_slot)
843 return 0;
844 rc = slot_update(&tmp_slot);
845 if (rc)
846 return 0;
847 if (SLOT_PRESENT(tmp_slot->status) &&
848 SLOT_PWRGD(tmp_slot->status))
849 return 0;
850 i++;
851 }
852 return 1;
853}
854
855
856
857
858
859
860
861static int set_bus(struct slot *slot_cur)
862{
863 int rc;
864 u8 speed;
865 u8 cmd = 0x0;
866 int retval;
867 static struct pci_device_id ciobx[] = {
868 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
869 { },
870 };
871
872 debug("%s - entry slot # %d\n", __func__, slot_cur->number);
873 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
874 rc = slot_update(&slot_cur);
875 if (rc)
876 return rc;
877 speed = SLOT_SPEED(slot_cur->ext_status);
878 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
879 switch (speed) {
880 case HPC_SLOT_SPEED_33:
881 cmd = HPC_BUS_33CONVMODE;
882 break;
883 case HPC_SLOT_SPEED_66:
884 if (SLOT_PCIX(slot_cur->ext_status)) {
885 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
886 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
887 cmd = HPC_BUS_66PCIXMODE;
888 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
889
890
891
892 cmd = HPC_BUS_66CONVMODE;
893 else
894 cmd = HPC_BUS_33CONVMODE;
895 } else {
896 if (slot_cur->supported_speed >= BUS_SPEED_66)
897 cmd = HPC_BUS_66CONVMODE;
898 else
899 cmd = HPC_BUS_33CONVMODE;
900 }
901 break;
902 case HPC_SLOT_SPEED_133:
903 switch (slot_cur->supported_speed) {
904 case BUS_SPEED_33:
905 cmd = HPC_BUS_33CONVMODE;
906 break;
907 case BUS_SPEED_66:
908 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
909 cmd = HPC_BUS_66PCIXMODE;
910 else
911 cmd = HPC_BUS_66CONVMODE;
912 break;
913 case BUS_SPEED_100:
914 cmd = HPC_BUS_100PCIXMODE;
915 break;
916 case BUS_SPEED_133:
917
918 if (pci_dev_present(ciobx))
919 ibmphp_hpc_writeslot(slot_cur,
920 HPC_BUS_100PCIXMODE);
921 cmd = HPC_BUS_133PCIXMODE;
922 break;
923 default:
924 err("Wrong bus speed\n");
925 return -ENODEV;
926 }
927 break;
928 default:
929 err("wrong slot speed\n");
930 return -ENODEV;
931 }
932 debug("setting bus speed for slot %d, cmd %x\n",
933 slot_cur->number, cmd);
934 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
935 if (retval) {
936 err("setting bus speed failed\n");
937 return retval;
938 }
939 if (CTLR_RESULT(slot_cur->ctrl->status)) {
940 err("command not completed successfully in set_bus\n");
941 return -EIO;
942 }
943 }
944
945
946 msleep(1000);
947 debug("%s -Exit\n", __func__);
948 return 0;
949}
950
951
952
953
954
955
956
957
958static int check_limitations(struct slot *slot_cur)
959{
960 u8 i;
961 struct slot *tmp_slot;
962 u8 count = 0;
963 u8 limitation = 0;
964
965 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
966 tmp_slot = ibmphp_get_slot_from_physical_num(i);
967 if (!tmp_slot)
968 return -ENODEV;
969 if ((SLOT_PWRGD(tmp_slot->status)) &&
970 !(SLOT_CONNECT(tmp_slot->status)))
971 count++;
972 }
973 get_cur_bus_info(&slot_cur);
974 switch (slot_cur->bus_on->current_speed) {
975 case BUS_SPEED_33:
976 limitation = slot_cur->bus_on->slots_at_33_conv;
977 break;
978 case BUS_SPEED_66:
979 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
980 limitation = slot_cur->bus_on->slots_at_66_pcix;
981 else
982 limitation = slot_cur->bus_on->slots_at_66_conv;
983 break;
984 case BUS_SPEED_100:
985 limitation = slot_cur->bus_on->slots_at_100_pcix;
986 break;
987 case BUS_SPEED_133:
988 limitation = slot_cur->bus_on->slots_at_133_pcix;
989 break;
990 }
991
992 if ((count + 1) > limitation)
993 return -EINVAL;
994 return 0;
995}
996
997static inline void print_card_capability(struct slot *slot_cur)
998{
999 info("capability of the card is ");
1000 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
1001 info(" 133 MHz PCI-X\n");
1002 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1003 info(" 66 MHz PCI-X\n");
1004 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1005 info(" 66 MHz PCI\n");
1006 else
1007 info(" 33 MHz PCI\n");
1008
1009}
1010
1011
1012
1013
1014
1015
1016static int enable_slot(struct hotplug_slot *hs)
1017{
1018 int rc, i, rcpr;
1019 struct slot *slot_cur;
1020 u8 function;
1021 struct pci_func *tmp_func;
1022
1023 ibmphp_lock_operations();
1024
1025 debug("ENABLING SLOT........\n");
1026 slot_cur = hs->private;
1027
1028 rc = validate(slot_cur, ENABLE);
1029 if (rc) {
1030 err("validate function failed\n");
1031 goto error_nopower;
1032 }
1033
1034 attn_LED_blink(slot_cur);
1035
1036 rc = set_bus(slot_cur);
1037 if (rc) {
1038 err("was not able to set the bus\n");
1039 goto error_nopower;
1040 }
1041
1042
1043 get_cur_bus_info(&slot_cur);
1044 debug("the current bus speed right after set_bus = %x\n",
1045 slot_cur->bus_on->current_speed);
1046
1047
1048 rc = check_limitations(slot_cur);
1049 if (rc) {
1050 err("Adding this card exceeds the limitations of this bus.\n");
1051 err("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus.\n");
1052 err("Try hot-adding into another bus\n");
1053 rc = -EINVAL;
1054 goto error_nopower;
1055 }
1056
1057 rc = power_on(slot_cur);
1058
1059 if (rc) {
1060 err("something wrong when powering up... please see below for details\n");
1061
1062 attn_off(slot_cur);
1063 attn_on(slot_cur);
1064 if (slot_update(&slot_cur)) {
1065 attn_off(slot_cur);
1066 attn_on(slot_cur);
1067 rc = -ENODEV;
1068 goto exit;
1069 }
1070
1071 if ((SLOT_POWER(slot_cur->status)) &&
1072 !(SLOT_PWRGD(slot_cur->status)))
1073 err("power fault occurred trying to power up\n");
1074 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1075 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
1076 print_card_capability(slot_cur);
1077 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1078 err("bus mode mismatch occurred. please check current bus mode and card capability\n");
1079 print_card_capability(slot_cur);
1080 }
1081 ibmphp_update_slot_info(slot_cur);
1082 goto exit;
1083 }
1084 debug("after power_on\n");
1085
1086 get_cur_bus_info(&slot_cur);
1087 debug("the current bus speed right after power_on = %x\n",
1088 slot_cur->bus_on->current_speed);
1089
1090
1091 rc = slot_update(&slot_cur);
1092 if (rc)
1093 goto error_power;
1094
1095 rc = -EINVAL;
1096 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1097 err("power fault occurred trying to power up...\n");
1098 goto error_power;
1099 }
1100 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1101 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
1102 print_card_capability(slot_cur);
1103 goto error_power;
1104 }
1105
1106
1107 if (!(SLOT_POWER(slot_cur->status))) {
1108 err("power on failed...\n");
1109 goto error_power;
1110 }
1111
1112 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1113 if (!slot_cur->func) {
1114
1115
1116 err("out of system memory\n");
1117 rc = -ENOMEM;
1118 goto error_power;
1119 }
1120 slot_cur->func->busno = slot_cur->bus;
1121 slot_cur->func->device = slot_cur->device;
1122 for (i = 0; i < 4; i++)
1123 slot_cur->func->irq[i] = slot_cur->irq[i];
1124
1125 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1126 slot_cur->bus, slot_cur->device);
1127
1128 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1129 err("configure_card was unsuccessful...\n");
1130
1131
1132 ibmphp_unconfigure_card(&slot_cur, 1);
1133 debug("after unconfigure_card\n");
1134 slot_cur->func = NULL;
1135 rc = -ENOMEM;
1136 goto error_power;
1137 }
1138
1139 function = 0x00;
1140 do {
1141 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1142 function++);
1143 if (tmp_func && !(tmp_func->dev))
1144 ibm_configure_device(tmp_func);
1145 } while (tmp_func);
1146
1147 attn_off(slot_cur);
1148 if (slot_update(&slot_cur)) {
1149 rc = -EFAULT;
1150 goto exit;
1151 }
1152 ibmphp_print_test();
1153 rc = ibmphp_update_slot_info(slot_cur);
1154exit:
1155 ibmphp_unlock_operations();
1156 return rc;
1157
1158error_nopower:
1159 attn_off(slot_cur);
1160 attn_on(slot_cur);
1161error_cont:
1162 rcpr = slot_update(&slot_cur);
1163 if (rcpr) {
1164 rc = rcpr;
1165 goto exit;
1166 }
1167 ibmphp_update_slot_info(slot_cur);
1168 goto exit;
1169
1170error_power:
1171 attn_off(slot_cur);
1172 attn_on(slot_cur);
1173 rcpr = power_off(slot_cur);
1174 if (rcpr) {
1175 rc = rcpr;
1176 goto exit;
1177 }
1178 goto error_cont;
1179}
1180
1181
1182
1183
1184
1185
1186
1187static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1188{
1189 struct slot *slot = hotplug_slot->private;
1190 int rc;
1191
1192 ibmphp_lock_operations();
1193 rc = ibmphp_do_disable_slot(slot);
1194 ibmphp_unlock_operations();
1195 return rc;
1196}
1197
1198int ibmphp_do_disable_slot(struct slot *slot_cur)
1199{
1200 int rc;
1201 u8 flag;
1202
1203 debug("DISABLING SLOT...\n");
1204
1205 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL))
1206 return -ENODEV;
1207
1208 flag = slot_cur->flag;
1209 slot_cur->flag = 1;
1210
1211 if (flag == 1) {
1212 rc = validate(slot_cur, DISABLE);
1213
1214 if (rc)
1215 goto error;
1216 }
1217 attn_LED_blink(slot_cur);
1218
1219 if (slot_cur->func == NULL) {
1220
1221 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1222 if (!slot_cur->func) {
1223 err("out of system memory\n");
1224 rc = -ENOMEM;
1225 goto error;
1226 }
1227 slot_cur->func->busno = slot_cur->bus;
1228 slot_cur->func->device = slot_cur->device;
1229 }
1230
1231 ibm_unconfigure_device(slot_cur->func);
1232
1233
1234
1235
1236
1237
1238
1239
1240 if (!flag) {
1241 attn_off(slot_cur);
1242 return 0;
1243 }
1244
1245 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1246 slot_cur->func = NULL;
1247 debug("in disable_slot. after unconfigure_card\n");
1248 if (rc) {
1249 err("could not unconfigure card.\n");
1250 goto error;
1251 }
1252
1253 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1254 if (rc)
1255 goto error;
1256
1257 attn_off(slot_cur);
1258 rc = slot_update(&slot_cur);
1259 if (rc)
1260 goto exit;
1261
1262 rc = ibmphp_update_slot_info(slot_cur);
1263 ibmphp_print_test();
1264exit:
1265 return rc;
1266
1267error:
1268
1269 attn_off(slot_cur);
1270 attn_on(slot_cur);
1271 if (slot_update(&slot_cur)) {
1272 rc = -EFAULT;
1273 goto exit;
1274 }
1275 if (flag)
1276 ibmphp_update_slot_info(slot_cur);
1277 goto exit;
1278}
1279
1280struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1281 .set_attention_status = set_attention_status,
1282 .enable_slot = enable_slot,
1283 .disable_slot = ibmphp_disable_slot,
1284 .hardware_test = NULL,
1285 .get_power_status = get_power_status,
1286 .get_attention_status = get_attention_status,
1287 .get_latch_status = get_latch_status,
1288 .get_adapter_status = get_adapter_present,
1289
1290
1291
1292};
1293
1294static void ibmphp_unload(void)
1295{
1296 free_slots();
1297 debug("after slots\n");
1298 ibmphp_free_resources();
1299 debug("after resources\n");
1300 ibmphp_free_bus_info_queue();
1301 debug("after bus info\n");
1302 ibmphp_free_ebda_hpc_queue();
1303 debug("after ebda hpc\n");
1304 ibmphp_free_ebda_pci_rsrc_queue();
1305 debug("after ebda pci rsrc\n");
1306 kfree(ibmphp_pci_bus);
1307}
1308
1309static int __init ibmphp_init(void)
1310{
1311 struct pci_bus *bus;
1312 int i = 0;
1313 int rc = 0;
1314
1315 init_flag = 1;
1316
1317 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1318
1319 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1320 if (!ibmphp_pci_bus) {
1321 err("out of memory\n");
1322 rc = -ENOMEM;
1323 goto exit;
1324 }
1325
1326 bus = pci_find_bus(0, 0);
1327 if (!bus) {
1328 err("Can't find the root pci bus, can not continue\n");
1329 rc = -ENODEV;
1330 goto error;
1331 }
1332 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1333
1334 ibmphp_debug = debug;
1335
1336 ibmphp_hpc_initvars();
1337
1338 for (i = 0; i < 16; i++)
1339 irqs[i] = 0;
1340
1341 rc = ibmphp_access_ebda();
1342 if (rc)
1343 goto error;
1344 debug("after ibmphp_access_ebda()\n");
1345
1346 rc = ibmphp_rsrc_init();
1347 if (rc)
1348 goto error;
1349 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1350
1351 max_slots = get_max_slots();
1352
1353 rc = ibmphp_register_pci();
1354 if (rc)
1355 goto error;
1356
1357 if (init_ops()) {
1358 rc = -ENODEV;
1359 goto error;
1360 }
1361
1362 ibmphp_print_test();
1363 rc = ibmphp_hpc_start_poll_thread();
1364 if (rc)
1365 goto error;
1366
1367exit:
1368 return rc;
1369
1370error:
1371 ibmphp_unload();
1372 goto exit;
1373}
1374
1375static void __exit ibmphp_exit(void)
1376{
1377 ibmphp_hpc_stop_poll_thread();
1378 debug("after polling\n");
1379 ibmphp_unload();
1380 debug("done\n");
1381}
1382
1383module_init(ibmphp_init);
1384module_exit(ibmphp_exit);
1385