0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/init.h>
0017 #include <linux/module.h>
0018 #include <linux/slab.h>
0019 #include <linux/pci.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/delay.h>
0022 #include <linux/wait.h>
0023 #include "../pci.h"
0024 #include <asm/pci_x86.h> /* for struct irq_routing_table */
0025 #include <asm/io_apic.h>
0026 #include "ibmphp.h"
0027
0028 #define attn_on(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_ATTNON)
0029 #define attn_off(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_ATTNOFF)
0030 #define attn_LED_blink(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_BLINKLED)
0031 #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot(sl, READ_REVLEVEL, rev)
0032 #define get_hpc_options(sl, opt) ibmphp_hpc_readslot(sl, READ_HPCOPTIONS, opt)
0033
0034 #define DRIVER_VERSION "0.6"
0035 #define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
0036
0037 int ibmphp_debug;
0038
0039 static bool debug;
0040 module_param(debug, bool, S_IRUGO | S_IWUSR);
0041 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
0042 MODULE_LICENSE("GPL");
0043 MODULE_DESCRIPTION(DRIVER_DESC);
0044
0045 struct pci_bus *ibmphp_pci_bus;
0046 static int max_slots;
0047
0048 static int irqs[16];
0049
0050
0051 static int init_flag;
0052
0053 static inline int get_cur_bus_info(struct slot **sl)
0054 {
0055 int rc = 1;
0056 struct slot *slot_cur = *sl;
0057
0058 debug("options = %x\n", slot_cur->ctrl->options);
0059 debug("revision = %x\n", slot_cur->ctrl->revision);
0060
0061 if (READ_BUS_STATUS(slot_cur->ctrl))
0062 rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
0063
0064 if (rc)
0065 return rc;
0066
0067 slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
0068 if (READ_BUS_MODE(slot_cur->ctrl))
0069 slot_cur->bus_on->current_bus_mode =
0070 CURRENT_BUS_MODE(slot_cur->busstatus);
0071 else
0072 slot_cur->bus_on->current_bus_mode = 0xFF;
0073
0074 debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
0075 slot_cur->busstatus,
0076 slot_cur->bus_on->current_speed,
0077 slot_cur->bus_on->current_bus_mode);
0078
0079 *sl = slot_cur;
0080 return 0;
0081 }
0082
0083 static inline int slot_update(struct slot **sl)
0084 {
0085 int rc;
0086 rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
0087 if (rc)
0088 return rc;
0089 if (!init_flag)
0090 rc = get_cur_bus_info(sl);
0091 return rc;
0092 }
0093
0094 static int __init get_max_slots(void)
0095 {
0096 struct slot *slot_cur;
0097 u8 slot_count = 0;
0098
0099 list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
0100
0101 slot_count = max(slot_count, slot_cur->number);
0102 }
0103 return slot_count;
0104 }
0105
0106
0107
0108
0109
0110
0111
0112 int ibmphp_init_devno(struct slot **cur_slot)
0113 {
0114 struct irq_routing_table *rtable;
0115 int len;
0116 int loop;
0117 int i;
0118
0119 rtable = pcibios_get_irq_routing_table();
0120 if (!rtable) {
0121 err("no BIOS routing table...\n");
0122 return -ENOMEM;
0123 }
0124
0125 len = (rtable->size - sizeof(struct irq_routing_table)) /
0126 sizeof(struct irq_info);
0127
0128 if (!len) {
0129 kfree(rtable);
0130 return -1;
0131 }
0132 for (loop = 0; loop < len; loop++) {
0133 if ((*cur_slot)->number == rtable->slots[loop].slot &&
0134 (*cur_slot)->bus == rtable->slots[loop].bus) {
0135 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
0136 for (i = 0; i < 4; i++)
0137 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
0138 (int) (*cur_slot)->device, i);
0139
0140 debug("(*cur_slot)->irq[0] = %x\n",
0141 (*cur_slot)->irq[0]);
0142 debug("(*cur_slot)->irq[1] = %x\n",
0143 (*cur_slot)->irq[1]);
0144 debug("(*cur_slot)->irq[2] = %x\n",
0145 (*cur_slot)->irq[2]);
0146 debug("(*cur_slot)->irq[3] = %x\n",
0147 (*cur_slot)->irq[3]);
0148
0149 debug("rtable->exclusive_irqs = %x\n",
0150 rtable->exclusive_irqs);
0151 debug("rtable->slots[loop].irq[0].bitmap = %x\n",
0152 rtable->slots[loop].irq[0].bitmap);
0153 debug("rtable->slots[loop].irq[1].bitmap = %x\n",
0154 rtable->slots[loop].irq[1].bitmap);
0155 debug("rtable->slots[loop].irq[2].bitmap = %x\n",
0156 rtable->slots[loop].irq[2].bitmap);
0157 debug("rtable->slots[loop].irq[3].bitmap = %x\n",
0158 rtable->slots[loop].irq[3].bitmap);
0159
0160 debug("rtable->slots[loop].irq[0].link = %x\n",
0161 rtable->slots[loop].irq[0].link);
0162 debug("rtable->slots[loop].irq[1].link = %x\n",
0163 rtable->slots[loop].irq[1].link);
0164 debug("rtable->slots[loop].irq[2].link = %x\n",
0165 rtable->slots[loop].irq[2].link);
0166 debug("rtable->slots[loop].irq[3].link = %x\n",
0167 rtable->slots[loop].irq[3].link);
0168 debug("end of init_devno\n");
0169 kfree(rtable);
0170 return 0;
0171 }
0172 }
0173
0174 kfree(rtable);
0175 return -1;
0176 }
0177
0178 static inline int power_on(struct slot *slot_cur)
0179 {
0180 u8 cmd = HPC_SLOT_ON;
0181 int retval;
0182
0183 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
0184 if (retval) {
0185 err("power on failed\n");
0186 return retval;
0187 }
0188 if (CTLR_RESULT(slot_cur->ctrl->status)) {
0189 err("command not completed successfully in power_on\n");
0190 return -EIO;
0191 }
0192 msleep(3000);
0193 return 0;
0194 }
0195
0196 static inline int power_off(struct slot *slot_cur)
0197 {
0198 u8 cmd = HPC_SLOT_OFF;
0199 int retval;
0200
0201 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
0202 if (retval) {
0203 err("power off failed\n");
0204 return retval;
0205 }
0206 if (CTLR_RESULT(slot_cur->ctrl->status)) {
0207 err("command not completed successfully in power_off\n");
0208 retval = -EIO;
0209 }
0210 return retval;
0211 }
0212
0213 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
0214 {
0215 int rc = 0;
0216 struct slot *pslot;
0217 u8 cmd = 0x00;
0218
0219 debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
0220 (ulong) hotplug_slot, value);
0221 ibmphp_lock_operations();
0222
0223
0224 if (hotplug_slot) {
0225 switch (value) {
0226 case HPC_SLOT_ATTN_OFF:
0227 cmd = HPC_SLOT_ATTNOFF;
0228 break;
0229 case HPC_SLOT_ATTN_ON:
0230 cmd = HPC_SLOT_ATTNON;
0231 break;
0232 case HPC_SLOT_ATTN_BLINK:
0233 cmd = HPC_SLOT_BLINKLED;
0234 break;
0235 default:
0236 rc = -ENODEV;
0237 err("set_attention_status - Error : invalid input [%x]\n",
0238 value);
0239 break;
0240 }
0241 if (rc == 0) {
0242 pslot = to_slot(hotplug_slot);
0243 rc = ibmphp_hpc_writeslot(pslot, cmd);
0244 }
0245 } else
0246 rc = -ENODEV;
0247
0248 ibmphp_unlock_operations();
0249
0250 debug("set_attention_status - Exit rc[%d]\n", rc);
0251 return rc;
0252 }
0253
0254 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
0255 {
0256 int rc = -ENODEV;
0257 struct slot *pslot;
0258 struct slot myslot;
0259
0260 debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
0261 (ulong) hotplug_slot, (ulong) value);
0262
0263 ibmphp_lock_operations();
0264 if (hotplug_slot) {
0265 pslot = to_slot(hotplug_slot);
0266 memcpy(&myslot, pslot, sizeof(struct slot));
0267 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
0268 &myslot.status);
0269 if (!rc)
0270 rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS,
0271 &myslot.ext_status);
0272 if (!rc)
0273 *value = SLOT_ATTN(myslot.status, myslot.ext_status);
0274 }
0275
0276 ibmphp_unlock_operations();
0277 debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
0278 return rc;
0279 }
0280
0281 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
0282 {
0283 int rc = -ENODEV;
0284 struct slot *pslot;
0285 struct slot myslot;
0286
0287 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
0288 (ulong) hotplug_slot, (ulong) value);
0289 ibmphp_lock_operations();
0290 if (hotplug_slot) {
0291 pslot = to_slot(hotplug_slot);
0292 memcpy(&myslot, pslot, sizeof(struct slot));
0293 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
0294 &myslot.status);
0295 if (!rc)
0296 *value = SLOT_LATCH(myslot.status);
0297 }
0298
0299 ibmphp_unlock_operations();
0300 debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
0301 rc, rc, *value);
0302 return rc;
0303 }
0304
0305
0306 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
0307 {
0308 int rc = -ENODEV;
0309 struct slot *pslot;
0310 struct slot myslot;
0311
0312 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
0313 (ulong) hotplug_slot, (ulong) value);
0314 ibmphp_lock_operations();
0315 if (hotplug_slot) {
0316 pslot = to_slot(hotplug_slot);
0317 memcpy(&myslot, pslot, sizeof(struct slot));
0318 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
0319 &myslot.status);
0320 if (!rc)
0321 *value = SLOT_PWRGD(myslot.status);
0322 }
0323
0324 ibmphp_unlock_operations();
0325 debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
0326 rc, rc, *value);
0327 return rc;
0328 }
0329
0330 static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value)
0331 {
0332 int rc = -ENODEV;
0333 struct slot *pslot;
0334 u8 present;
0335 struct slot myslot;
0336
0337 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
0338 (ulong) hotplug_slot, (ulong) value);
0339 ibmphp_lock_operations();
0340 if (hotplug_slot) {
0341 pslot = to_slot(hotplug_slot);
0342 memcpy(&myslot, pslot, sizeof(struct slot));
0343 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
0344 &myslot.status);
0345 if (!rc) {
0346 present = SLOT_PRESENT(myslot.status);
0347 if (present == HPC_SLOT_EMPTY)
0348 *value = 0;
0349 else
0350 *value = 1;
0351 }
0352 }
0353
0354 ibmphp_unlock_operations();
0355 debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
0356 return rc;
0357 }
0358
0359 static int get_max_bus_speed(struct slot *slot)
0360 {
0361 int rc = 0;
0362 u8 mode = 0;
0363 enum pci_bus_speed speed;
0364 struct pci_bus *bus = slot->hotplug_slot.pci_slot->bus;
0365
0366 debug("%s - Entry slot[%p]\n", __func__, slot);
0367
0368 ibmphp_lock_operations();
0369 mode = slot->supported_bus_mode;
0370 speed = slot->supported_speed;
0371 ibmphp_unlock_operations();
0372
0373 switch (speed) {
0374 case BUS_SPEED_33:
0375 break;
0376 case BUS_SPEED_66:
0377 if (mode == BUS_MODE_PCIX)
0378 speed += 0x01;
0379 break;
0380 case BUS_SPEED_100:
0381 case BUS_SPEED_133:
0382 speed += 0x01;
0383 break;
0384 default:
0385
0386 rc = -ENODEV;
0387 }
0388
0389 if (!rc)
0390 bus->max_bus_speed = speed;
0391
0392 debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed);
0393 return rc;
0394 }
0395
0396
0397
0398
0399
0400
0401 static int __init init_ops(void)
0402 {
0403 struct slot *slot_cur;
0404 int retval;
0405 int rc;
0406
0407 list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
0408 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
0409 slot_cur->number);
0410 if (slot_cur->ctrl->revision == 0xFF)
0411 if (get_ctrl_revision(slot_cur,
0412 &slot_cur->ctrl->revision))
0413 return -1;
0414
0415 if (slot_cur->bus_on->current_speed == 0xFF)
0416 if (get_cur_bus_info(&slot_cur))
0417 return -1;
0418 get_max_bus_speed(slot_cur);
0419
0420 if (slot_cur->ctrl->options == 0xFF)
0421 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
0422 return -1;
0423
0424 retval = slot_update(&slot_cur);
0425 if (retval)
0426 return retval;
0427
0428 debug("status = %x\n", slot_cur->status);
0429 debug("ext_status = %x\n", slot_cur->ext_status);
0430 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
0431 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
0432 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
0433
0434 if ((SLOT_PWRGD(slot_cur->status)) &&
0435 !(SLOT_PRESENT(slot_cur->status)) &&
0436 !(SLOT_LATCH(slot_cur->status))) {
0437 debug("BEFORE POWER OFF COMMAND\n");
0438 rc = power_off(slot_cur);
0439 if (rc)
0440 return rc;
0441
0442
0443
0444
0445
0446
0447 }
0448 }
0449 init_flag = 0;
0450 return 0;
0451 }
0452
0453
0454
0455
0456
0457
0458 static int validate(struct slot *slot_cur, int opn)
0459 {
0460 int number;
0461 int retval;
0462
0463 if (!slot_cur)
0464 return -ENODEV;
0465 number = slot_cur->number;
0466 if ((number > max_slots) || (number < 0))
0467 return -EBADSLT;
0468 debug("slot_number in validate is %d\n", slot_cur->number);
0469
0470 retval = slot_update(&slot_cur);
0471 if (retval)
0472 return retval;
0473
0474 switch (opn) {
0475 case ENABLE:
0476 if (!(SLOT_PWRGD(slot_cur->status)) &&
0477 (SLOT_PRESENT(slot_cur->status)) &&
0478 !(SLOT_LATCH(slot_cur->status)))
0479 return 0;
0480 break;
0481 case DISABLE:
0482 if ((SLOT_PWRGD(slot_cur->status)) &&
0483 (SLOT_PRESENT(slot_cur->status)) &&
0484 !(SLOT_LATCH(slot_cur->status)))
0485 return 0;
0486 break;
0487 default:
0488 break;
0489 }
0490 err("validate failed....\n");
0491 return -EINVAL;
0492 }
0493
0494
0495
0496
0497
0498
0499 int ibmphp_update_slot_info(struct slot *slot_cur)
0500 {
0501 struct pci_bus *bus = slot_cur->hotplug_slot.pci_slot->bus;
0502 u8 bus_speed;
0503 u8 mode;
0504
0505 bus_speed = slot_cur->bus_on->current_speed;
0506 mode = slot_cur->bus_on->current_bus_mode;
0507
0508 switch (bus_speed) {
0509 case BUS_SPEED_33:
0510 break;
0511 case BUS_SPEED_66:
0512 if (mode == BUS_MODE_PCIX)
0513 bus_speed += 0x01;
0514 else if (mode == BUS_MODE_PCI)
0515 ;
0516 else
0517 bus_speed = PCI_SPEED_UNKNOWN;
0518 break;
0519 case BUS_SPEED_100:
0520 case BUS_SPEED_133:
0521 bus_speed += 0x01;
0522 break;
0523 default:
0524 bus_speed = PCI_SPEED_UNKNOWN;
0525 }
0526
0527 bus->cur_bus_speed = bus_speed;
0528
0529
0530 return 0;
0531 }
0532
0533
0534
0535
0536
0537
0538
0539 static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
0540 {
0541 struct pci_func *func_cur;
0542 struct slot *slot_cur;
0543 list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
0544 if (slot_cur->func) {
0545 func_cur = slot_cur->func;
0546 while (func_cur) {
0547 if ((func_cur->busno == busno) &&
0548 (func_cur->device == device) &&
0549 (func_cur->function == function))
0550 return func_cur;
0551 func_cur = func_cur->next;
0552 }
0553 }
0554 }
0555 return NULL;
0556 }
0557
0558
0559
0560
0561
0562
0563 static void free_slots(void)
0564 {
0565 struct slot *slot_cur, *next;
0566
0567 debug("%s -- enter\n", __func__);
0568
0569 list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head,
0570 ibm_slot_list) {
0571 pci_hp_del(&slot_cur->hotplug_slot);
0572 slot_cur->ctrl = NULL;
0573 slot_cur->bus_on = NULL;
0574
0575
0576
0577
0578
0579 ibmphp_unconfigure_card(&slot_cur, -1);
0580
0581 pci_hp_destroy(&slot_cur->hotplug_slot);
0582 kfree(slot_cur);
0583 }
0584 debug("%s -- exit\n", __func__);
0585 }
0586
0587 static void ibm_unconfigure_device(struct pci_func *func)
0588 {
0589 struct pci_dev *temp;
0590 u8 j;
0591
0592 debug("inside %s\n", __func__);
0593 debug("func->device = %x, func->function = %x\n",
0594 func->device, func->function);
0595 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
0596
0597 pci_lock_rescan_remove();
0598
0599 for (j = 0; j < 0x08; j++) {
0600 temp = pci_get_domain_bus_and_slot(0, func->busno,
0601 (func->device << 3) | j);
0602 if (temp) {
0603 pci_stop_and_remove_bus_device(temp);
0604 pci_dev_put(temp);
0605 }
0606 }
0607
0608 pci_dev_put(func->dev);
0609
0610 pci_unlock_rescan_remove();
0611 }
0612
0613
0614
0615
0616
0617
0618 static u8 bus_structure_fixup(u8 busno)
0619 {
0620 struct pci_bus *bus, *b;
0621 struct pci_dev *dev;
0622 u16 l;
0623
0624 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
0625 return 1;
0626
0627 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
0628 if (!bus)
0629 return 1;
0630
0631 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
0632 if (!dev) {
0633 kfree(bus);
0634 return 1;
0635 }
0636
0637 bus->number = busno;
0638 bus->ops = ibmphp_pci_bus->ops;
0639 dev->bus = bus;
0640 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
0641 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
0642 (l != 0x0000) && (l != 0xffff)) {
0643 debug("%s - Inside bus_structure_fixup()\n",
0644 __func__);
0645 b = pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
0646 if (!b)
0647 continue;
0648
0649 pci_bus_add_devices(b);
0650 break;
0651 }
0652 }
0653
0654 kfree(dev);
0655 kfree(bus);
0656
0657 return 0;
0658 }
0659
0660 static int ibm_configure_device(struct pci_func *func)
0661 {
0662 struct pci_bus *child;
0663 int num;
0664 int flag = 0;
0665
0666
0667 pci_lock_rescan_remove();
0668
0669 if (!(bus_structure_fixup(func->busno)))
0670 flag = 1;
0671 if (func->dev == NULL)
0672 func->dev = pci_get_domain_bus_and_slot(0, func->busno,
0673 PCI_DEVFN(func->device, func->function));
0674
0675 if (func->dev == NULL) {
0676 struct pci_bus *bus = pci_find_bus(0, func->busno);
0677 if (!bus)
0678 goto out;
0679
0680 num = pci_scan_slot(bus,
0681 PCI_DEVFN(func->device, func->function));
0682 if (num)
0683 pci_bus_add_devices(bus);
0684
0685 func->dev = pci_get_domain_bus_and_slot(0, func->busno,
0686 PCI_DEVFN(func->device, func->function));
0687 if (func->dev == NULL) {
0688 err("ERROR... : pci_dev still NULL\n");
0689 goto out;
0690 }
0691 }
0692 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
0693 pci_hp_add_bridge(func->dev);
0694 child = func->dev->subordinate;
0695 if (child)
0696 pci_bus_add_devices(child);
0697 }
0698
0699 out:
0700 pci_unlock_rescan_remove();
0701 return 0;
0702 }
0703
0704
0705
0706
0707 static int is_bus_empty(struct slot *slot_cur)
0708 {
0709 int rc;
0710 struct slot *tmp_slot;
0711 u8 i = slot_cur->bus_on->slot_min;
0712
0713 while (i <= slot_cur->bus_on->slot_max) {
0714 if (i == slot_cur->number) {
0715 i++;
0716 continue;
0717 }
0718 tmp_slot = ibmphp_get_slot_from_physical_num(i);
0719 if (!tmp_slot)
0720 return 0;
0721 rc = slot_update(&tmp_slot);
0722 if (rc)
0723 return 0;
0724 if (SLOT_PRESENT(tmp_slot->status) &&
0725 SLOT_PWRGD(tmp_slot->status))
0726 return 0;
0727 i++;
0728 }
0729 return 1;
0730 }
0731
0732
0733
0734
0735
0736
0737
0738 static int set_bus(struct slot *slot_cur)
0739 {
0740 int rc;
0741 u8 speed;
0742 u8 cmd = 0x0;
0743 int retval;
0744 static const struct pci_device_id ciobx[] = {
0745 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
0746 { },
0747 };
0748
0749 debug("%s - entry slot # %d\n", __func__, slot_cur->number);
0750 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
0751 rc = slot_update(&slot_cur);
0752 if (rc)
0753 return rc;
0754 speed = SLOT_SPEED(slot_cur->ext_status);
0755 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
0756 switch (speed) {
0757 case HPC_SLOT_SPEED_33:
0758 cmd = HPC_BUS_33CONVMODE;
0759 break;
0760 case HPC_SLOT_SPEED_66:
0761 if (SLOT_PCIX(slot_cur->ext_status)) {
0762 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
0763 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
0764 cmd = HPC_BUS_66PCIXMODE;
0765 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
0766
0767
0768
0769 cmd = HPC_BUS_66CONVMODE;
0770 else
0771 cmd = HPC_BUS_33CONVMODE;
0772 } else {
0773 if (slot_cur->supported_speed >= BUS_SPEED_66)
0774 cmd = HPC_BUS_66CONVMODE;
0775 else
0776 cmd = HPC_BUS_33CONVMODE;
0777 }
0778 break;
0779 case HPC_SLOT_SPEED_133:
0780 switch (slot_cur->supported_speed) {
0781 case BUS_SPEED_33:
0782 cmd = HPC_BUS_33CONVMODE;
0783 break;
0784 case BUS_SPEED_66:
0785 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
0786 cmd = HPC_BUS_66PCIXMODE;
0787 else
0788 cmd = HPC_BUS_66CONVMODE;
0789 break;
0790 case BUS_SPEED_100:
0791 cmd = HPC_BUS_100PCIXMODE;
0792 break;
0793 case BUS_SPEED_133:
0794
0795 if (pci_dev_present(ciobx))
0796 ibmphp_hpc_writeslot(slot_cur,
0797 HPC_BUS_100PCIXMODE);
0798 cmd = HPC_BUS_133PCIXMODE;
0799 break;
0800 default:
0801 err("Wrong bus speed\n");
0802 return -ENODEV;
0803 }
0804 break;
0805 default:
0806 err("wrong slot speed\n");
0807 return -ENODEV;
0808 }
0809 debug("setting bus speed for slot %d, cmd %x\n",
0810 slot_cur->number, cmd);
0811 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
0812 if (retval) {
0813 err("setting bus speed failed\n");
0814 return retval;
0815 }
0816 if (CTLR_RESULT(slot_cur->ctrl->status)) {
0817 err("command not completed successfully in set_bus\n");
0818 return -EIO;
0819 }
0820 }
0821
0822
0823 msleep(1000);
0824 debug("%s -Exit\n", __func__);
0825 return 0;
0826 }
0827
0828
0829
0830
0831
0832
0833
0834
0835 static int check_limitations(struct slot *slot_cur)
0836 {
0837 u8 i;
0838 struct slot *tmp_slot;
0839 u8 count = 0;
0840 u8 limitation = 0;
0841
0842 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
0843 tmp_slot = ibmphp_get_slot_from_physical_num(i);
0844 if (!tmp_slot)
0845 return -ENODEV;
0846 if ((SLOT_PWRGD(tmp_slot->status)) &&
0847 !(SLOT_CONNECT(tmp_slot->status)))
0848 count++;
0849 }
0850 get_cur_bus_info(&slot_cur);
0851 switch (slot_cur->bus_on->current_speed) {
0852 case BUS_SPEED_33:
0853 limitation = slot_cur->bus_on->slots_at_33_conv;
0854 break;
0855 case BUS_SPEED_66:
0856 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
0857 limitation = slot_cur->bus_on->slots_at_66_pcix;
0858 else
0859 limitation = slot_cur->bus_on->slots_at_66_conv;
0860 break;
0861 case BUS_SPEED_100:
0862 limitation = slot_cur->bus_on->slots_at_100_pcix;
0863 break;
0864 case BUS_SPEED_133:
0865 limitation = slot_cur->bus_on->slots_at_133_pcix;
0866 break;
0867 }
0868
0869 if ((count + 1) > limitation)
0870 return -EINVAL;
0871 return 0;
0872 }
0873
0874 static inline void print_card_capability(struct slot *slot_cur)
0875 {
0876 info("capability of the card is ");
0877 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
0878 info(" 133 MHz PCI-X\n");
0879 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
0880 info(" 66 MHz PCI-X\n");
0881 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
0882 info(" 66 MHz PCI\n");
0883 else
0884 info(" 33 MHz PCI\n");
0885
0886 }
0887
0888
0889
0890
0891
0892
0893 static int enable_slot(struct hotplug_slot *hs)
0894 {
0895 int rc, i, rcpr;
0896 struct slot *slot_cur;
0897 u8 function;
0898 struct pci_func *tmp_func;
0899
0900 ibmphp_lock_operations();
0901
0902 debug("ENABLING SLOT........\n");
0903 slot_cur = to_slot(hs);
0904
0905 rc = validate(slot_cur, ENABLE);
0906 if (rc) {
0907 err("validate function failed\n");
0908 goto error_nopower;
0909 }
0910
0911 attn_LED_blink(slot_cur);
0912
0913 rc = set_bus(slot_cur);
0914 if (rc) {
0915 err("was not able to set the bus\n");
0916 goto error_nopower;
0917 }
0918
0919
0920 get_cur_bus_info(&slot_cur);
0921 debug("the current bus speed right after set_bus = %x\n",
0922 slot_cur->bus_on->current_speed);
0923
0924
0925 rc = check_limitations(slot_cur);
0926 if (rc) {
0927 err("Adding this card exceeds the limitations of this bus.\n");
0928 err("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus.\n");
0929 err("Try hot-adding into another bus\n");
0930 rc = -EINVAL;
0931 goto error_nopower;
0932 }
0933
0934 rc = power_on(slot_cur);
0935
0936 if (rc) {
0937 err("something wrong when powering up... please see below for details\n");
0938
0939 attn_off(slot_cur);
0940 attn_on(slot_cur);
0941 if (slot_update(&slot_cur)) {
0942 attn_off(slot_cur);
0943 attn_on(slot_cur);
0944 rc = -ENODEV;
0945 goto exit;
0946 }
0947
0948 if ((SLOT_POWER(slot_cur->status)) &&
0949 !(SLOT_PWRGD(slot_cur->status)))
0950 err("power fault occurred trying to power up\n");
0951 else if (SLOT_BUS_SPEED(slot_cur->status)) {
0952 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
0953 print_card_capability(slot_cur);
0954 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
0955 err("bus mode mismatch occurred. please check current bus mode and card capability\n");
0956 print_card_capability(slot_cur);
0957 }
0958 ibmphp_update_slot_info(slot_cur);
0959 goto exit;
0960 }
0961 debug("after power_on\n");
0962
0963 get_cur_bus_info(&slot_cur);
0964 debug("the current bus speed right after power_on = %x\n",
0965 slot_cur->bus_on->current_speed);
0966
0967
0968 rc = slot_update(&slot_cur);
0969 if (rc)
0970 goto error_power;
0971
0972 rc = -EINVAL;
0973 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
0974 err("power fault occurred trying to power up...\n");
0975 goto error_power;
0976 }
0977 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
0978 err("bus speed mismatch occurred. please check current bus speed and card capability\n");
0979 print_card_capability(slot_cur);
0980 goto error_power;
0981 }
0982
0983
0984 if (!(SLOT_POWER(slot_cur->status))) {
0985 err("power on failed...\n");
0986 goto error_power;
0987 }
0988
0989 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
0990 if (!slot_cur->func) {
0991
0992 rc = -ENOMEM;
0993 goto error_power;
0994 }
0995 slot_cur->func->busno = slot_cur->bus;
0996 slot_cur->func->device = slot_cur->device;
0997 for (i = 0; i < 4; i++)
0998 slot_cur->func->irq[i] = slot_cur->irq[i];
0999
1000 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1001 slot_cur->bus, slot_cur->device);
1002
1003 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1004 err("configure_card was unsuccessful...\n");
1005
1006
1007 ibmphp_unconfigure_card(&slot_cur, 1);
1008 debug("after unconfigure_card\n");
1009 slot_cur->func = NULL;
1010 rc = -ENOMEM;
1011 goto error_power;
1012 }
1013
1014 function = 0x00;
1015 do {
1016 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1017 function++);
1018 if (tmp_func && !(tmp_func->dev))
1019 ibm_configure_device(tmp_func);
1020 } while (tmp_func);
1021
1022 attn_off(slot_cur);
1023 if (slot_update(&slot_cur)) {
1024 rc = -EFAULT;
1025 goto exit;
1026 }
1027 ibmphp_print_test();
1028 rc = ibmphp_update_slot_info(slot_cur);
1029 exit:
1030 ibmphp_unlock_operations();
1031 return rc;
1032
1033 error_nopower:
1034 attn_off(slot_cur);
1035 attn_on(slot_cur);
1036 error_cont:
1037 rcpr = slot_update(&slot_cur);
1038 if (rcpr) {
1039 rc = rcpr;
1040 goto exit;
1041 }
1042 ibmphp_update_slot_info(slot_cur);
1043 goto exit;
1044
1045 error_power:
1046 attn_off(slot_cur);
1047 attn_on(slot_cur);
1048 rcpr = power_off(slot_cur);
1049 if (rcpr) {
1050 rc = rcpr;
1051 goto exit;
1052 }
1053 goto error_cont;
1054 }
1055
1056
1057
1058
1059
1060
1061
1062 static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1063 {
1064 struct slot *slot = to_slot(hotplug_slot);
1065 int rc;
1066
1067 ibmphp_lock_operations();
1068 rc = ibmphp_do_disable_slot(slot);
1069 ibmphp_unlock_operations();
1070 return rc;
1071 }
1072
1073 int ibmphp_do_disable_slot(struct slot *slot_cur)
1074 {
1075 int rc;
1076 u8 flag;
1077
1078 debug("DISABLING SLOT...\n");
1079
1080 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL))
1081 return -ENODEV;
1082
1083 flag = slot_cur->flag;
1084 slot_cur->flag = 1;
1085
1086 if (flag == 1) {
1087 rc = validate(slot_cur, DISABLE);
1088
1089 if (rc)
1090 goto error;
1091 }
1092 attn_LED_blink(slot_cur);
1093
1094 if (slot_cur->func == NULL) {
1095
1096 slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1097 if (!slot_cur->func) {
1098 rc = -ENOMEM;
1099 goto error;
1100 }
1101 slot_cur->func->busno = slot_cur->bus;
1102 slot_cur->func->device = slot_cur->device;
1103 }
1104
1105 ibm_unconfigure_device(slot_cur->func);
1106
1107
1108
1109
1110
1111
1112
1113
1114 if (!flag) {
1115 attn_off(slot_cur);
1116 return 0;
1117 }
1118
1119 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1120 slot_cur->func = NULL;
1121 debug("in disable_slot. after unconfigure_card\n");
1122 if (rc) {
1123 err("could not unconfigure card.\n");
1124 goto error;
1125 }
1126
1127 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1128 if (rc)
1129 goto error;
1130
1131 attn_off(slot_cur);
1132 rc = slot_update(&slot_cur);
1133 if (rc)
1134 goto exit;
1135
1136 rc = ibmphp_update_slot_info(slot_cur);
1137 ibmphp_print_test();
1138 exit:
1139 return rc;
1140
1141 error:
1142
1143 attn_off(slot_cur);
1144 attn_on(slot_cur);
1145 if (slot_update(&slot_cur)) {
1146 rc = -EFAULT;
1147 goto exit;
1148 }
1149 if (flag)
1150 ibmphp_update_slot_info(slot_cur);
1151 goto exit;
1152 }
1153
1154 const struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1155 .set_attention_status = set_attention_status,
1156 .enable_slot = enable_slot,
1157 .disable_slot = ibmphp_disable_slot,
1158 .hardware_test = NULL,
1159 .get_power_status = get_power_status,
1160 .get_attention_status = get_attention_status,
1161 .get_latch_status = get_latch_status,
1162 .get_adapter_status = get_adapter_present,
1163 };
1164
1165 static void ibmphp_unload(void)
1166 {
1167 free_slots();
1168 debug("after slots\n");
1169 ibmphp_free_resources();
1170 debug("after resources\n");
1171 ibmphp_free_bus_info_queue();
1172 debug("after bus info\n");
1173 ibmphp_free_ebda_hpc_queue();
1174 debug("after ebda hpc\n");
1175 ibmphp_free_ebda_pci_rsrc_queue();
1176 debug("after ebda pci rsrc\n");
1177 kfree(ibmphp_pci_bus);
1178 }
1179
1180 static int __init ibmphp_init(void)
1181 {
1182 struct pci_bus *bus;
1183 int i = 0;
1184 int rc = 0;
1185
1186 init_flag = 1;
1187
1188 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1189
1190 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1191 if (!ibmphp_pci_bus) {
1192 rc = -ENOMEM;
1193 goto exit;
1194 }
1195
1196 bus = pci_find_bus(0, 0);
1197 if (!bus) {
1198 err("Can't find the root pci bus, can not continue\n");
1199 rc = -ENODEV;
1200 goto error;
1201 }
1202 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1203
1204 ibmphp_debug = debug;
1205
1206 for (i = 0; i < 16; i++)
1207 irqs[i] = 0;
1208
1209 rc = ibmphp_access_ebda();
1210 if (rc)
1211 goto error;
1212 debug("after ibmphp_access_ebda()\n");
1213
1214 rc = ibmphp_rsrc_init();
1215 if (rc)
1216 goto error;
1217 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1218
1219 max_slots = get_max_slots();
1220
1221 rc = ibmphp_register_pci();
1222 if (rc)
1223 goto error;
1224
1225 if (init_ops()) {
1226 rc = -ENODEV;
1227 goto error;
1228 }
1229
1230 ibmphp_print_test();
1231 rc = ibmphp_hpc_start_poll_thread();
1232 if (rc)
1233 goto error;
1234
1235 exit:
1236 return rc;
1237
1238 error:
1239 ibmphp_unload();
1240 goto exit;
1241 }
1242
1243 static void __exit ibmphp_exit(void)
1244 {
1245 ibmphp_hpc_stop_poll_thread();
1246 debug("after polling\n");
1247 ibmphp_unload();
1248 debug("done\n");
1249 }
1250
1251 module_init(ibmphp_init);
1252 module_exit(ibmphp_exit);