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