📄 ibmphp_ebda.c
字号:
bus_info_ptr1->slot_count += 1; bus_info_ptr1->busno = slot_ptr->slot_bus_num; bus_info_ptr1->index = bus_index++; bus_info_ptr1->current_speed = 0xff; bus_info_ptr1->current_bus_mode = 0xff; bus_info_ptr1->controller_id = hpc_ptr->ctlr_id; list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head); } else { bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num); bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num); bus_info_ptr2->slot_count += 1; } // end of creating the bus_info linked list slot_ptr++; addr_slot += 1; } /* init bus structure */ bus_ptr = hpc_ptr->buses; for (bus = 0; bus < bus_num; bus++) { bus_ptr->bus_num = readb (io_mem + addr_bus + bus); bus_ptr->slots_at_33_conv = readb (io_mem + addr_bus + bus_num + 8 * bus); bus_ptr->slots_at_66_conv = readb (io_mem + addr_bus + bus_num + 8 * bus + 1); bus_ptr->slots_at_66_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 2); bus_ptr->slots_at_100_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 3); bus_ptr->slots_at_133_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 4); bus_info_ptr2 = ibmphp_find_same_bus_num (bus_ptr->bus_num); if (bus_info_ptr2) { bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv; bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv; bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix; bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix; bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix; } bus_ptr++; } hpc_ptr->ctlr_type = temp; switch (hpc_ptr->ctlr_type) { case 1: hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr); hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1); hpc_ptr->irq = readb (io_mem + addr + 2); addr += 3; debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq); break; case 0: hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr); hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2); if (!request_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp")) { rc = -ENODEV; goto error_no_hp_slot; } hpc_ptr->irq = readb (io_mem + addr + 4); addr += 5; break; case 2: case 4: hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr); hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4); hpc_ptr->irq = readb (io_mem + addr + 5); addr += 6; break; default: rc = -ENODEV; goto error_no_hp_slot; } //reorganize chassis' linked list combine_wpg_for_chassis (); combine_wpg_for_expansion (); hpc_ptr->revision = 0xff; hpc_ptr->options = 0xff; hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num; hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num; // register slots with hpc core as well as create linked list of ibm slot for (index = 0; index < hpc_ptr->slot_count; index++) { hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL); if (!hp_slot_ptr) { rc = -ENOMEM; goto error_no_hp_slot; } memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr)); hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL); if (!hp_slot_ptr->info) { rc = -ENOMEM; goto error_no_hp_info; } memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info)); hp_slot_ptr->name = kmalloc(30, GFP_KERNEL); if (!hp_slot_ptr->name) { rc = -ENOMEM; goto error_no_hp_name; } tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL); if (!tmp_slot) { rc = -ENOMEM; goto error_no_slot; } memset(tmp_slot, 0, sizeof(*tmp_slot)); tmp_slot->flag = TRUE; tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap; if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX) tmp_slot->supported_speed = 3; else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX) tmp_slot->supported_speed = 2; else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX) tmp_slot->supported_speed = 1; if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP) tmp_slot->supported_bus_mode = 1; else tmp_slot->supported_bus_mode = 0; tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num; bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num); if (!bus_info_ptr1) { rc = -ENODEV; goto error; } tmp_slot->bus_on = bus_info_ptr1; bus_info_ptr1 = NULL; tmp_slot->ctrl = hpc_ptr; tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index; tmp_slot->number = hpc_ptr->slots[index].slot_num; tmp_slot->hotplug_slot = hp_slot_ptr; hp_slot_ptr->private = tmp_slot; hp_slot_ptr->release = release_slot; rc = fillslotinfo(hp_slot_ptr); if (rc) goto error; rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private); if (rc) goto error; hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops; // end of registering ibm slot with hotplug core list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head); } print_bus_info (); list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head ); } /* each hpc */ list_for_each (list, &ibmphp_slot_head) { tmp_slot = list_entry (list, struct slot, ibm_slot_list); snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot)); pci_hp_register (tmp_slot->hotplug_slot); } print_ebda_hpc (); print_ibm_slot (); return 0;error: kfree (hp_slot_ptr->private);error_no_slot: kfree (hp_slot_ptr->name);error_no_hp_name: kfree (hp_slot_ptr->info);error_no_hp_info: kfree (hp_slot_ptr);error_no_hp_slot: free_ebda_hpc (hpc_ptr);error_no_hpc: iounmap (io_mem); return rc;}/* * map info (bus, devfun, start addr, end addr..) of i/o, memory, * pfm from the physical addr to a list of resource. */static int __init ebda_rsrc_rsrc (void){ u16 addr; short rsrc; u8 type, rsrc_type; struct ebda_pci_rsrc *rsrc_ptr; addr = rsrc_list_ptr->phys_addr; debug ("now entering rsrc land\n"); debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr); for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) { type = readb (io_mem + addr); addr += 1; rsrc_type = type & EBDA_RSRC_TYPE_MASK; if (rsrc_type == EBDA_IO_RSRC_TYPE) { rsrc_ptr = alloc_ebda_pci_rsrc (); if (!rsrc_ptr) { iounmap (io_mem); return -ENOMEM; } rsrc_ptr->rsrc_type = type; rsrc_ptr->bus_num = readb (io_mem + addr); rsrc_ptr->dev_fun = readb (io_mem + addr + 1); rsrc_ptr->start_addr = readw (io_mem + addr + 2); rsrc_ptr->end_addr = readw (io_mem + addr + 4); addr += 6; debug ("rsrc from io type ----\n"); debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr); list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); } if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) { rsrc_ptr = alloc_ebda_pci_rsrc (); if (!rsrc_ptr ) { iounmap (io_mem); return -ENOMEM; } rsrc_ptr->rsrc_type = type; rsrc_ptr->bus_num = readb (io_mem + addr); rsrc_ptr->dev_fun = readb (io_mem + addr + 1); rsrc_ptr->start_addr = readl (io_mem + addr + 2); rsrc_ptr->end_addr = readl (io_mem + addr + 6); addr += 10; debug ("rsrc from mem or pfm ---\n"); debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr); list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); } } kfree (rsrc_list_ptr); rsrc_list_ptr = NULL; print_ebda_pci_rsrc (); return 0;}u16 ibmphp_get_total_controllers (void){ return hpc_list_ptr->num_ctlrs;}struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num){ struct slot *slot; struct list_head *list; list_for_each (list, &ibmphp_slot_head) { slot = list_entry (list, struct slot, ibm_slot_list); if (slot->number == physical_num) return slot; } return NULL;}/* To find: * - the smallest slot number * - the largest slot number * - the total number of the slots based on each bus * (if only one slot per bus slot_min = slot_max ) */struct bus_info *ibmphp_find_same_bus_num (u32 num){ struct bus_info *ptr; struct list_head *ptr1; list_for_each (ptr1, &bus_info_head) { ptr = list_entry (ptr1, struct bus_info, bus_info_list); if (ptr->busno == num) return ptr; } return NULL;}/* Finding relative bus number, in order to map corresponding * bus register */int ibmphp_get_bus_index (u8 num){ struct bus_info *ptr; struct list_head *ptr1; list_for_each (ptr1, &bus_info_head) { ptr = list_entry (ptr1, struct bus_info, bus_info_list); if (ptr->busno == num) return ptr->index; } return -ENODEV;}void ibmphp_free_bus_info_queue (void){ struct bus_info *bus_info; struct list_head *list; struct list_head *next; list_for_each_safe (list, next, &bus_info_head ) { bus_info = list_entry (list, struct bus_info, bus_info_list); kfree (bus_info); }}void ibmphp_free_ebda_hpc_queue (void){ struct controller *controller = NULL; struct list_head *list; struct list_head *next; int pci_flag = 0; list_for_each_safe (list, next, &ebda_hpc_head) { controller = list_entry (list, struct controller, ebda_hpc_list); if (controller->ctlr_type == 0) release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1)); else if ((controller->ctlr_type == 1) && (!pci_flag)) { ++pci_flag; pci_unregister_driver (&ibmphp_driver); } free_ebda_hpc (controller); }}void ibmphp_free_ebda_pci_rsrc_queue (void){ struct ebda_pci_rsrc *resource; struct list_head *list; struct list_head *next; list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) { resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list); kfree (resource); resource = NULL; }}static struct pci_device_id id_table[] = { { .vendor = PCI_VENDOR_ID_IBM, .device = HPC_DEVICE_ID, .subvendor = PCI_VENDOR_ID_IBM, .subdevice = HPC_SUBSYSTEM_ID, .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00), }, {}}; MODULE_DEVICE_TABLE(pci, id_table);static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);static struct pci_driver ibmphp_driver = { .name = "ibmphp", .id_table = id_table, .probe = ibmphp_probe,};int ibmphp_register_pci (void){ struct controller *ctrl; struct list_head *tmp; int rc = 0; list_for_each (tmp, &ebda_hpc_head) { ctrl = list_entry (tmp, struct controller, ebda_hpc_list); if (ctrl->ctlr_type == 1) { rc = pci_module_init (&ibmphp_driver); break; } } return rc;}static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids){ struct controller *ctrl; struct list_head *tmp; debug ("inside ibmphp_probe\n"); list_for_each (tmp, &ebda_hpc_head) { ctrl = list_entry (tmp, struct controller, ebda_hpc_list); if (ctrl->ctlr_type == 1) { if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) { ctrl->ctrl_dev = dev; debug ("found device!!!\n"); debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device); return 0; } } } return -ENODEV;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -