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