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 int 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->exlusive_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 hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
399{
400 int rc = -ENODEV;
401 struct slot *pslot;
402 u8 mode = 0;
403
404 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
405 hotplug_slot, value);
406
407 ibmphp_lock_operations();
408
409 if (hotplug_slot) {
410 pslot = hotplug_slot->private;
411 if (pslot) {
412 rc = 0;
413 mode = pslot->supported_bus_mode;
414 *value = pslot->supported_speed;
415 switch (*value) {
416 case BUS_SPEED_33:
417 break;
418 case BUS_SPEED_66:
419 if (mode == BUS_MODE_PCIX)
420 *value += 0x01;
421 break;
422 case BUS_SPEED_100:
423 case BUS_SPEED_133:
424 *value = pslot->supported_speed + 0x01;
425 break;
426 default:
427
428 rc = -ENODEV;
429 }
430 }
431 }
432
433 ibmphp_unlock_operations();
434 debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
435 return rc;
436}
437
438static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
439{
440 int rc = -ENODEV;
441 struct slot *pslot;
442 u8 mode = 0;
443
444 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
445 hotplug_slot, value);
446
447 ibmphp_lock_operations();
448
449 if (hotplug_slot) {
450 pslot = hotplug_slot->private;
451 if (pslot) {
452 rc = get_cur_bus_info(&pslot);
453 if (!rc) {
454 mode = pslot->bus_on->current_bus_mode;
455 *value = pslot->bus_on->current_speed;
456 switch (*value) {
457 case BUS_SPEED_33:
458 break;
459 case BUS_SPEED_66:
460 if (mode == BUS_MODE_PCIX)
461 *value += 0x01;
462 else if (mode == BUS_MODE_PCI)
463 ;
464 else
465 *value = PCI_SPEED_UNKNOWN;
466 break;
467 case BUS_SPEED_100:
468 case BUS_SPEED_133:
469 *value += 0x01;
470 break;
471 default:
472
473 rc = -ENODEV;
474 }
475 }
476 }
477 }
478
479 ibmphp_unlock_operations();
480 debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
481 return rc;
482}
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552static int __init init_ops(void)
553{
554 struct slot *slot_cur;
555 struct list_head *tmp;
556 int retval;
557 int rc;
558
559 list_for_each(tmp, &ibmphp_slot_head) {
560 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
561
562 if (!slot_cur)
563 return -ENODEV;
564
565 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
566 slot_cur->number);
567 if (slot_cur->ctrl->revision == 0xFF)
568 if (get_ctrl_revision(slot_cur,
569 &slot_cur->ctrl->revision))
570 return -1;
571
572 if (slot_cur->bus_on->current_speed == 0xFF)
573 if (get_cur_bus_info(&slot_cur))
574 return -1;
575
576 if (slot_cur->ctrl->options == 0xFF)
577 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
578 return -1;
579
580 retval = slot_update(&slot_cur);
581 if (retval)
582 return retval;
583
584 debug("status = %x\n", slot_cur->status);
585 debug("ext_status = %x\n", slot_cur->ext_status);
586 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
587 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
588 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
589
590 if ((SLOT_PWRGD(slot_cur->status)) &&
591 !(SLOT_PRESENT(slot_cur->status)) &&
592 !(SLOT_LATCH(slot_cur->status))) {
593 debug("BEFORE POWER OFF COMMAND\n");
594 rc = power_off(slot_cur);
595 if (rc)
596 return rc;
597
598
599
600
601
602
603 }
604 }
605 init_flag = 0;
606 return 0;
607}
608
609
610
611
612
613
614static int validate(struct slot *slot_cur, int opn)
615{
616 int number;
617 int retval;
618
619 if (!slot_cur)
620 return -ENODEV;
621 number = slot_cur->number;
622 if ((number > max_slots) || (number < 0))
623 return -EBADSLT;
624 debug("slot_number in validate is %d\n", slot_cur->number);
625
626 retval = slot_update(&slot_cur);
627 if (retval)
628 return retval;
629
630 switch (opn) {
631 case ENABLE:
632 if (!(SLOT_PWRGD(slot_cur->status)) &&
633 (SLOT_PRESENT(slot_cur->status)) &&
634 !(SLOT_LATCH(slot_cur->status)))
635 return 0;
636 break;
637 case DISABLE:
638 if ((SLOT_PWRGD(slot_cur->status)) &&
639 (SLOT_PRESENT(slot_cur->status)) &&
640 !(SLOT_LATCH(slot_cur->status)))
641 return 0;
642 break;
643 default:
644 break;
645 }
646 err("validate failed....\n");
647 return -EINVAL;
648}
649
650
651
652
653
654
655int ibmphp_update_slot_info(struct slot *slot_cur)
656{
657 struct hotplug_slot_info *info;
658 int rc;
659 u8 bus_speed;
660 u8 mode;
661
662 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
663 if (!info) {
664 err("out of system memory\n");
665 return -ENOMEM;
666 }
667
668 info->power_status = SLOT_PWRGD(slot_cur->status);
669 info->attention_status = SLOT_ATTN(slot_cur->status,
670 slot_cur->ext_status);
671 info->latch_status = SLOT_LATCH(slot_cur->status);
672 if (!SLOT_PRESENT(slot_cur->status)) {
673 info->adapter_status = 0;
674
675 } else {
676 info->adapter_status = 1;
677
678
679 }
680
681 bus_speed = slot_cur->bus_on->current_speed;
682 mode = slot_cur->bus_on->current_bus_mode;
683
684 switch (bus_speed) {
685 case BUS_SPEED_33:
686 break;
687 case BUS_SPEED_66:
688 if (mode == BUS_MODE_PCIX)
689 bus_speed += 0x01;
690 else if (mode == BUS_MODE_PCI)
691 ;
692 else
693 bus_speed = PCI_SPEED_UNKNOWN;
694 break;
695 case BUS_SPEED_100:
696 case BUS_SPEED_133:
697 bus_speed += 0x01;
698 break;
699 default:
700 bus_speed = PCI_SPEED_UNKNOWN;
701 }
702
703 info->cur_bus_speed = bus_speed;
704 info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
705
706
707 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
708 kfree(info);
709 return rc;
710}
711
712
713
714
715
716
717
718static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
719{
720 struct pci_func *func_cur;
721 struct slot *slot_cur;
722 struct list_head * tmp;
723 list_for_each(tmp, &ibmphp_slot_head) {
724 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
725 if (slot_cur->func) {
726 func_cur = slot_cur->func;
727 while (func_cur) {
728 if ((func_cur->busno == busno) &&
729 (func_cur->device == device) &&
730 (func_cur->function == function))
731 return func_cur;
732 func_cur = func_cur->next;
733 }
734 }
735 }
736 return NULL;
737}
738
739
740
741
742
743
744static void free_slots(void)
745{
746 struct slot *slot_cur;
747 struct list_head * tmp;
748 struct list_head * next;
749
750 debug("%s -- enter\n", __func__);
751
752 list_for_each_safe(tmp, next, &ibmphp_slot_head) {
753 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
754 pci_hp_deregister(slot_cur->hotplug_slot);
755 }
756 debug("%s -- exit\n", __func__);
757}
758
759static void ibm_unconfigure_device(struct pci_func *func)
760{
761 struct pci_dev *temp;
762 u8 j;
763
764 debug("inside %s\n", __func__);
765 debug("func->device = %x, func->function = %x\n",
766 func->device, func->function);
767 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
768
769 for (j = 0; j < 0x08; j++) {
770 temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
771 if (temp) {
772 pci_remove_bus_device(temp);
773 pci_dev_put(temp);
774 }
775 }
776 pci_dev_put(func->dev);
777}
778
779
780
781
782
783
784static u8 bus_structure_fixup(u8 busno)
785{
786 struct pci_bus *bus;
787 struct pci_dev *dev;
788 u16 l;
789
790 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
791 return 1;
792
793 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
794 if (!bus) {
795 err("%s - out of memory\n", __func__);
796 return 1;
797 }
798 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
799 if (!dev) {
800 kfree(bus);
801 err("%s - out of memory\n", __func__);
802 return 1;
803 }
804
805 bus->number = busno;
806 bus->ops = ibmphp_pci_bus->ops;
807 dev->bus = bus;
808 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
809 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
810 (l != 0x0000) && (l != 0xffff)) {
811 debug("%s - Inside bus_struture_fixup()\n",
812 __func__);
813 pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
814 break;
815 }
816 }
817
818 kfree(dev);
819 kfree(bus);
820
821 return 0;
822}
823
824static int ibm_configure_device(struct pci_func *func)
825{
826 unsigned char bus;
827 struct pci_bus *child;
828 int num;
829 int flag = 0;
830
831
832 if (!(bus_structure_fixup(func->busno)))
833 flag = 1;
834 if (func->dev == NULL)
835 func->dev = pci_get_bus_and_slot(func->busno,
836 PCI_DEVFN(func->device, func->function));
837
838 if (func->dev == NULL) {
839 struct pci_bus *bus = pci_find_bus(0, func->busno);
840 if (!bus)
841 return 0;
842
843 num = pci_scan_slot(bus,
844 PCI_DEVFN(func->device, func->function));
845 if (num)
846 pci_bus_add_devices(bus);
847
848 func->dev = pci_get_bus_and_slot(func->busno,
849 PCI_DEVFN(func->device, func->function));
850 if (func->dev == NULL) {
851 err("ERROR... : pci_dev still NULL\n");
852 return 0;
853 }
854 }
855 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
856 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
857 child = pci_add_new_bus(func->dev->bus, func->dev, bus);
858 pci_do_scan_bus(child);
859 }
860
861 return 0;
862}
863
864
865
866
867static int is_bus_empty(struct slot * slot_cur)
868{
869 int rc;
870 struct slot * tmp_slot;
871 u8 i = slot_cur->bus_on->slot_min;
872
873 while (i <= slot_cur->bus_on->slot_max) {
874 if (i == slot_cur->number) {
875 i++;
876 continue;
877 }
878 tmp_slot = ibmphp_get_slot_from_physical_num(i);
879 if (!tmp_slot)
880 return 0;
881 rc = slot_update(&tmp_slot);
882 if (rc)
883 return 0;
884 if (SLOT_PRESENT(tmp_slot->status) &&
885 SLOT_PWRGD(tmp_slot->status))
886 return 0;
887 i++;
888 }
889 return 1;
890}
891
892
893
894
895
896
897
898static int set_bus(struct slot * slot_cur)
899{
900 int rc;
901 u8 speed;
902 u8 cmd = 0x0;
903 int retval;
904 static struct pci_device_id ciobx[] = {
905 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
906 { },
907 };
908
909 debug("%s - entry slot # %d\n", __func__, slot_cur->number);
910 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
911 rc = slot_update(&slot_cur);
912 if (rc)
913 return rc;
914 speed = SLOT_SPEED(slot_cur->ext_status);
915 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
916 switch (speed) {
917 case HPC_SLOT_SPEED_33:
918 cmd = HPC_BUS_33CONVMODE;
919 break;
920 case HPC_SLOT_SPEED_66:
921 if (SLOT_PCIX(slot_cur->ext_status)) {
922 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
923 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
924 cmd = HPC_BUS_66PCIXMODE;
925 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
926
927
928
929 cmd = HPC_BUS_66CONVMODE;
930 else
931 cmd = HPC_BUS_33CONVMODE;
932 } else {
933 if (slot_cur->supported_speed >= BUS_SPEED_66)
934 cmd = HPC_BUS_66CONVMODE;
935 else
936 cmd = HPC_BUS_33CONVMODE;
937 }
938 break;
939 case HPC_SLOT_SPEED_133:
940 switch (slot_cur->supported_speed) {
941 case BUS_SPEED_33:
942 cmd = HPC_BUS_33CONVMODE;
943 break;
944 case BUS_SPEED_66:
945 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
946 cmd = HPC_BUS_66PCIXMODE;
947 else
948 cmd = HPC_BUS_66CONVMODE;
949 break;
950 case BUS_SPEED_100:
951 cmd = HPC_BUS_100PCIXMODE;
952 break;
953 case BUS_SPEED_133:
954
955 if (pci_dev_present(ciobx))
956 ibmphp_hpc_writeslot(slot_cur,
957 HPC_BUS_100PCIXMODE);
958 cmd = HPC_BUS_133PCIXMODE;
959 break;
960 default:
961 err("Wrong bus speed\n");
962 return -ENODEV;
963 }
964 break;
965 default:
966 err("wrong slot speed\n");
967 return -ENODEV;
968 }
969 debug("setting bus speed for slot %d, cmd %x\n",
970 slot_cur->number, cmd);
971 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
972 if (retval) {
973 err("setting bus speed failed\n");
974 return retval;
975 }
976 if (CTLR_RESULT(slot_cur->ctrl->status)) {
977 err("command not completed successfully in set_bus\n");
978 return -EIO;
979 }
980 }
981
982
983 msleep(1000);
984 debug("%s -Exit\n", __func__);
985 return 0;
986}
987
988
989
990
991
992
993
994
995static int check_limitations(struct slot *slot_cur)
996{
997 u8 i;
998 struct slot * tmp_slot;
999 u8 count = 0;
1000 u8 limitation = 0;
1001
1002 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
1003 tmp_slot = ibmphp_get_slot_from_physical_num(i);
1004 if (!tmp_slot)
1005 return -ENODEV;
1006 if ((SLOT_PWRGD(tmp_slot->status)) &&
1007 !(SLOT_CONNECT(tmp_slot->status)))
1008 count++;
1009 }
1010 get_cur_bus_info(&slot_cur);
1011 switch (slot_cur->bus_on->current_speed) {
1012 case BUS_SPEED_33:
1013 limitation = slot_cur->bus_on->slots_at_33_conv;
1014 break;
1015 case BUS_SPEED_66:
1016 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1017 limitation = slot_cur->bus_on->slots_at_66_pcix;
1018 else
1019 limitation = slot_cur->bus_on->slots_at_66_conv;
1020 break;
1021 case BUS_SPEED_100:
1022 limitation = slot_cur->bus_on->slots_at_100_pcix;
1023 break;
1024 case BUS_SPEED_133:
1025 limitation = slot_cur->bus_on->slots_at_133_pcix;
1026 break;
1027 }
1028
1029 if ((count + 1) > limitation)
1030 return -EINVAL;
1031 return 0;
1032}
1033
1034static inline void print_card_capability(struct slot *slot_cur)
1035{
1036 info("capability of the card is ");
1037 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
1038 info(" 133 MHz PCI-X\n");
1039 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1040 info(" 66 MHz PCI-X\n");
1041 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1042 info(" 66 MHz PCI\n");
1043 else
1044 info(" 33 MHz PCI\n");
1045
1046}
1047
1048
1049
1050
1051
1052
1053static int enable_slot(struct hotplug_slot *hs)
1054{
1055 int rc, i, rcpr;
1056 struct slot *slot_cur;
1057 u8 function;
1058 struct pci_func *tmp_func;
1059
1060 ibmphp_lock_operations();
1061
1062 debug("ENABLING SLOT........\n");
1063 slot_cur = hs->private;
1064
1065 if ((rc = validate(slot_cur, ENABLE))) {
1066 err("validate function failed\n");
1067 goto error_nopower;
1068 }
1069
1070 attn_LED_blink(slot_cur);
1071
1072 rc = set_bus(slot_cur);
1073 if (rc) {
1074 err("was not able to set the bus\n");
1075 goto error_nopower;
1076 }
1077
1078
1079 get_cur_bus_info(&slot_cur);
1080 debug("the current bus speed right after set_bus = %x\n",
1081 slot_cur->bus_on->current_speed);
1082
1083
1084 rc = check_limitations(slot_cur);
1085 if (rc) {
1086 err("Adding this card exceeds the limitations of this bus.\n");
1087 err("(i.e., >1 133MHz cards running on same bus, or "
1088 ">2 66 PCI cards running on same bus.\n");
1089 err("Try hot-adding into another bus\n");
1090 rc = -EINVAL;
1091 goto error_nopower;
1092 }
1093
1094 rc = power_on(slot_cur);
1095
1096 if (rc) {
1097 err("something wrong when powering up... please see below for details\n");
1098
1099 attn_off(slot_cur);
1100 attn_on(slot_cur);
1101 if (slot_update(&slot_cur)) {
1102 attn_off(slot_cur);
1103 attn_on(slot_cur);
1104 rc = -ENODEV;
1105 goto exit;
1106 }
1107
1108 if ((SLOT_POWER(slot_cur->status)) &&
1109 !(SLOT_PWRGD(slot_cur->status)))
1110 err("power fault occurred trying to power up\n");
1111 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1112 err("bus speed mismatch occurred. please check "
1113 "current bus speed and card capability\n");
1114 print_card_capability(slot_cur);
1115 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1116 err("bus mode mismatch occurred. please check "
1117 "current bus mode and card capability\n");
1118 print_card_capability(slot_cur);
1119 }
1120 ibmphp_update_slot_info(slot_cur);
1121 goto exit;
1122 }
1123 debug("after power_on\n");
1124
1125 get_cur_bus_info(&slot_cur);
1126 debug("the current bus speed right after power_on = %x\n",
1127 slot_cur->bus_on->current_speed);
1128
1129
1130 rc = slot_update(&slot_cur);
1131 if (rc)
1132 goto error_power;
1133
1134 rc = -EINVAL;
1135 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1136 err("power fault occurred trying to power up...\n");
1137 goto error_power;
1138 }
1139 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1140 err("bus speed mismatch occurred. please check current bus "
1141 "speed and card capability\n");
1142 print_card_capability(slot_cur);
1143 goto error_power;
1144 }
1145
1146
1147 if (!(SLOT_POWER(slot_cur->status))) {
1148 err("power on failed...\n");
1149 goto error_power;
1150 }
1151
1152 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1153 if (!slot_cur->func) {
1154
1155
1156 err("out of system memory\n");
1157 rc = -ENOMEM;
1158 goto error_power;
1159 }
1160 slot_cur->func->busno = slot_cur->bus;
1161 slot_cur->func->device = slot_cur->device;
1162 for (i = 0; i < 4; i++)
1163 slot_cur->func->irq[i] = slot_cur->irq[i];
1164
1165 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1166 slot_cur->bus, slot_cur->device);
1167
1168 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1169 err("configure_card was unsuccessful...\n");
1170
1171
1172 ibmphp_unconfigure_card(&slot_cur, 1);
1173 debug("after unconfigure_card\n");
1174 slot_cur->func = NULL;
1175 rc = -ENOMEM;
1176 goto error_power;
1177 }
1178
1179 function = 0x00;
1180 do {
1181 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1182 function++);
1183 if (tmp_func && !(tmp_func->dev))
1184 ibm_configure_device(tmp_func);
1185 } while (tmp_func);
1186
1187 attn_off(slot_cur);
1188 if (slot_update(&slot_cur)) {
1189 rc = -EFAULT;
1190 goto exit;
1191 }
1192 ibmphp_print_test();
1193 rc = ibmphp_update_slot_info(slot_cur);
1194exit:
1195 ibmphp_unlock_operations();
1196 return rc;
1197
1198error_nopower:
1199 attn_off(slot_cur);
1200 attn_on(slot_cur);
1201error_cont:
1202 rcpr = slot_update(&slot_cur);
1203 if (rcpr) {
1204 rc = rcpr;
1205 goto exit;
1206 }
1207 ibmphp_update_slot_info(slot_cur);
1208 goto exit;
1209
1210error_power:
1211 attn_off(slot_cur);
1212 attn_on(slot_cur);
1213 rcpr = power_off(slot_cur);
1214 if (rcpr) {
1215 rc = rcpr;
1216 goto exit;
1217 }
1218 goto error_cont;
1219}
1220
1221
1222
1223
1224
1225
1226
1227static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1228{
1229 struct slot *slot = hotplug_slot->private;
1230 int rc;
1231
1232 ibmphp_lock_operations();
1233 rc = ibmphp_do_disable_slot(slot);
1234 ibmphp_unlock_operations();
1235 return rc;
1236}
1237
1238int ibmphp_do_disable_slot(struct slot *slot_cur)
1239{
1240 int rc;
1241 u8 flag;
1242
1243 debug("DISABLING SLOT...\n");
1244
1245 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1246 return -ENODEV;
1247 }
1248
1249 flag = slot_cur->flag;
1250 slot_cur->flag = 1;
1251
1252 if (flag == 1) {
1253 rc = validate(slot_cur, DISABLE);
1254
1255 if (rc)
1256 goto error;
1257 }
1258 attn_LED_blink(slot_cur);
1259
1260 if (slot_cur->func == NULL) {
1261
1262 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1263 if (!slot_cur->func) {
1264 err("out of system memory\n");
1265 rc = -ENOMEM;
1266 goto error;
1267 }
1268 slot_cur->func->busno = slot_cur->bus;
1269 slot_cur->func->device = slot_cur->device;
1270 }
1271
1272 ibm_unconfigure_device(slot_cur->func);
1273
1274
1275
1276
1277
1278
1279
1280 if (!flag) {
1281 attn_off(slot_cur);
1282 return 0;
1283 }
1284
1285 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1286 slot_cur->func = NULL;
1287 debug("in disable_slot. after unconfigure_card\n");
1288 if (rc) {
1289 err("could not unconfigure card.\n");
1290 goto error;
1291 }
1292
1293 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1294 if (rc)
1295 goto error;
1296
1297 attn_off(slot_cur);
1298 rc = slot_update(&slot_cur);
1299 if (rc)
1300 goto exit;
1301
1302 rc = ibmphp_update_slot_info(slot_cur);
1303 ibmphp_print_test();
1304exit:
1305 return rc;
1306
1307error:
1308
1309 attn_off(slot_cur);
1310 attn_on(slot_cur);
1311 if (slot_update(&slot_cur)) {
1312 rc = -EFAULT;
1313 goto exit;
1314 }
1315 if (flag)
1316 ibmphp_update_slot_info(slot_cur);
1317 goto exit;
1318}
1319
1320struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1321 .set_attention_status = set_attention_status,
1322 .enable_slot = enable_slot,
1323 .disable_slot = ibmphp_disable_slot,
1324 .hardware_test = NULL,
1325 .get_power_status = get_power_status,
1326 .get_attention_status = get_attention_status,
1327 .get_latch_status = get_latch_status,
1328 .get_adapter_status = get_adapter_present,
1329 .get_max_bus_speed = get_max_bus_speed,
1330 .get_cur_bus_speed = get_cur_bus_speed,
1331
1332
1333
1334};
1335
1336static void ibmphp_unload(void)
1337{
1338 free_slots();
1339 debug("after slots\n");
1340 ibmphp_free_resources();
1341 debug("after resources\n");
1342 ibmphp_free_bus_info_queue();
1343 debug("after bus info\n");
1344 ibmphp_free_ebda_hpc_queue();
1345 debug("after ebda hpc\n");
1346 ibmphp_free_ebda_pci_rsrc_queue();
1347 debug("after ebda pci rsrc\n");
1348 kfree(ibmphp_pci_bus);
1349}
1350
1351static int __init ibmphp_init(void)
1352{
1353 struct pci_bus *bus;
1354 int i = 0;
1355 int rc = 0;
1356
1357 init_flag = 1;
1358
1359 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1360
1361 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1362 if (!ibmphp_pci_bus) {
1363 err("out of memory\n");
1364 rc = -ENOMEM;
1365 goto exit;
1366 }
1367
1368 bus = pci_find_bus(0, 0);
1369 if (!bus) {
1370 err("Can't find the root pci bus, can not continue\n");
1371 rc = -ENODEV;
1372 goto error;
1373 }
1374 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1375
1376 ibmphp_debug = debug;
1377
1378 ibmphp_hpc_initvars();
1379
1380 for (i = 0; i < 16; i++)
1381 irqs[i] = 0;
1382
1383 if ((rc = ibmphp_access_ebda()))
1384 goto error;
1385 debug("after ibmphp_access_ebda()\n");
1386
1387 if ((rc = ibmphp_rsrc_init()))
1388 goto error;
1389 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1390
1391 max_slots = get_max_slots();
1392
1393 if ((rc = ibmphp_register_pci()))
1394 goto error;
1395
1396 if (init_ops()) {
1397 rc = -ENODEV;
1398 goto error;
1399 }
1400
1401 ibmphp_print_test();
1402 if ((rc = ibmphp_hpc_start_poll_thread())) {
1403 goto error;
1404 }
1405
1406exit:
1407 return rc;
1408
1409error:
1410 ibmphp_unload();
1411 goto exit;
1412}
1413
1414static void __exit ibmphp_exit(void)
1415{
1416 ibmphp_hpc_stop_poll_thread();
1417 debug("after polling\n");
1418 ibmphp_unload();
1419 debug("done\n");
1420}
1421
1422module_init(ibmphp_init);
1423module_exit(ibmphp_exit);
1424