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