📄 ibmphp_ebda.c
字号:
error_nodev: rc = -ENODEV;out: iounmap (io_mem); return rc;}/* * map info of scalability details and rio details from physical address */static int __init ebda_rio_table (void){ u16 offset; u8 i; struct rio_detail *rio_detail_ptr; offset = rio_table_ptr->offset; offset += 12 * rio_table_ptr->scal_count; // we do concern about rio details for (i = 0; i < rio_table_ptr->riodev_count; i++) { rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL); if (!rio_detail_ptr) return -ENOMEM; memset (rio_detail_ptr, 0, sizeof (struct rio_detail)); rio_detail_ptr->rio_node_id = readb (io_mem + offset); rio_detail_ptr->bbar = readl (io_mem + offset + 1); rio_detail_ptr->rio_type = readb (io_mem + offset + 5); rio_detail_ptr->owner_id = readb (io_mem + offset + 6); rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7); rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8); rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9); rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10); rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11); rio_detail_ptr->status = readb (io_mem + offset + 12); rio_detail_ptr->wpindex = readb (io_mem + offset + 13); rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);// debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status); //create linked list of chassis if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5) list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head); //create linked list of expansion box else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7) list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head); else // not in my concern kfree (rio_detail_ptr); offset += 15; } print_lo_info (); print_vg_info (); return 0;}/* * reorganizing linked list of chassis */static struct opt_rio *search_opt_vg (u8 chassis_num){ struct opt_rio *ptr; struct list_head *ptr1; list_for_each (ptr1, &opt_vg_head) { ptr = list_entry (ptr1, struct opt_rio, opt_rio_list); if (ptr->chassis_num == chassis_num) return ptr; } return NULL;}static int __init combine_wpg_for_chassis (void){ struct opt_rio *opt_rio_ptr = NULL; struct rio_detail *rio_detail_ptr = NULL; struct list_head *list_head_ptr = NULL; list_for_each (list_head_ptr, &rio_vg_head) { rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num); if (!opt_rio_ptr) { opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL); if (!opt_rio_ptr) return -ENOMEM; memset (opt_rio_ptr, 0, sizeof (struct opt_rio)); opt_rio_ptr->rio_type = rio_detail_ptr->rio_type; opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num; opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num; opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num; list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head); } else { opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num); opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num); } } print_opt_vg (); return 0; } /* * reorgnizing linked list of expansion box */static struct opt_rio_lo *search_opt_lo (u8 chassis_num){ struct opt_rio_lo *ptr; struct list_head *ptr1; list_for_each (ptr1, &opt_lo_head) { ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list); if (ptr->chassis_num == chassis_num) return ptr; } return NULL;}static int combine_wpg_for_expansion (void){ struct opt_rio_lo *opt_rio_lo_ptr = NULL; struct rio_detail *rio_detail_ptr = NULL; struct list_head *list_head_ptr = NULL; list_for_each (list_head_ptr, &rio_lo_head) { rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num); if (!opt_rio_lo_ptr) { opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL); if (!opt_rio_lo_ptr) return -ENOMEM; memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo)); opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type; opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num; opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num; opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num; opt_rio_lo_ptr->pack_count = 1; list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head); } else { opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num); opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num); opt_rio_lo_ptr->pack_count = 2; } } return 0; } /* Since we don't know the max slot number per each chassis, hence go * through the list of all chassis to find out the range * Arguments: slot_num, 1st slot number of the chassis we think we are on, * var (0 = chassis, 1 = expansion box) */static int first_slot_num (u8 slot_num, u8 first_slot, u8 var){ struct opt_rio *opt_vg_ptr = NULL; struct opt_rio_lo *opt_lo_ptr = NULL; struct list_head *ptr = NULL; int rc = 0; if (!var) { list_for_each (ptr, &opt_vg_head) { opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list); if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { rc = -ENODEV; break; } } } else { list_for_each (ptr, &opt_lo_head) { opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list); if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) { rc = -ENODEV; break; } } } return rc;}static struct opt_rio_lo * find_rxe_num (u8 slot_num){ struct opt_rio_lo *opt_lo_ptr; struct list_head *ptr; list_for_each (ptr, &opt_lo_head) { opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list); //check to see if this slot_num belongs to expansion box if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) return opt_lo_ptr; } return NULL;}static struct opt_rio * find_chassis_num (u8 slot_num){ struct opt_rio *opt_vg_ptr; struct list_head *ptr; list_for_each (ptr, &opt_vg_head) { opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list); //check to see if this slot_num belongs to chassis if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) return opt_vg_ptr; } return NULL;}/* This routine will find out how many slots are in the chassis, so that * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc */static u8 calculate_first_slot (u8 slot_num){ u8 first_slot = 1; struct list_head * list; struct slot * slot_cur; list_for_each (list, &ibmphp_slot_head) { slot_cur = list_entry (list, struct slot, ibm_slot_list); if (slot_cur->ctrl) { if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) first_slot = slot_cur->ctrl->ending_slot_num; } } return first_slot + 1;}static char *create_file_name (struct slot * slot_cur){ struct opt_rio *opt_vg_ptr = NULL; struct opt_rio_lo *opt_lo_ptr = NULL; static char str[30]; int which = 0; /* rxe = 1, chassis = 0 */ u8 number = 1; /* either chassis or rxe # */ u8 first_slot = 1; u8 slot_num; u8 flag = 0; if (!slot_cur) { err ("Structure passed is empty\n"); return NULL; } slot_num = slot_cur->number; memset (str, 0, sizeof(str)); if (rio_table_ptr) { if (rio_table_ptr->ver_num == 3) { opt_vg_ptr = find_chassis_num (slot_num); opt_lo_ptr = find_rxe_num (slot_num); } } if (opt_vg_ptr) { if (opt_lo_ptr) { if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) { number = opt_lo_ptr->chassis_num; first_slot = opt_lo_ptr->first_slot_num; which = 1; /* it is RXE */ } else { first_slot = opt_vg_ptr->first_slot_num; number = opt_vg_ptr->chassis_num; which = 0; } } else { first_slot = opt_vg_ptr->first_slot_num; number = opt_vg_ptr->chassis_num; which = 0; } ++flag; } else if (opt_lo_ptr) { number = opt_lo_ptr->chassis_num; first_slot = opt_lo_ptr->first_slot_num; which = 1; ++flag; } else if (rio_table_ptr) { if (rio_table_ptr->ver_num == 3) { /* if both NULL and we DO have correct RIO table in BIOS */ return NULL; } } if (!flag) { if (slot_cur->ctrl->ctlr_type == 4) { first_slot = calculate_first_slot (slot_num); which = 1; } else { which = 0; } } sprintf(str, "%s%dslot%d", which == 0 ? "chassis" : "rxe", number, slot_num - first_slot + 1); return str;}static int fillslotinfo(struct hotplug_slot *hotplug_slot){ struct slot *slot; int rc = 0; if (!hotplug_slot || !hotplug_slot->private) return -EINVAL; slot = hotplug_slot->private; rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL); if (rc) return rc; // power - enabled:1 not:0 hotplug_slot->info->power_status = SLOT_POWER(slot->status); // attention - off:0, on:1, blinking:2 hotplug_slot->info->attention_status = SLOT_ATTN(slot->status, slot->ext_status); // latch - open:1 closed:0 hotplug_slot->info->latch_status = SLOT_LATCH(slot->status); // pci board - present:1 not:0 if (SLOT_PRESENT (slot->status)) hotplug_slot->info->adapter_status = 1; else hotplug_slot->info->adapter_status = 0;/* if (slot->bus_on->supported_bus_mode && (slot->bus_on->supported_speed == BUS_SPEED_66)) hotplug_slot->info->max_bus_speed_status = BUS_SPEED_66PCIX; else hotplug_slot->info->max_bus_speed_status = slot->bus_on->supported_speed;*/ return rc;}static void release_slot(struct hotplug_slot *hotplug_slot){ struct slot *slot; if (!hotplug_slot || !hotplug_slot->private) return; slot = hotplug_slot->private; kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); slot->ctrl = NULL; slot->bus_on = NULL; /* we don't want to actually remove the resources, since free_resources will do just that */ ibmphp_unconfigure_card(&slot, -1); kfree (slot);}static struct pci_driver ibmphp_driver;/* * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of * each hpc from physical address to a list of hot plug controllers based on * hpc descriptors. */static int __init ebda_rsrc_controller (void){ u16 addr, addr_slot, addr_bus; u8 ctlr_id, temp, bus_index; u16 ctlr, slot, bus; u16 slot_num, bus_num, index; struct hotplug_slot *hp_slot_ptr; struct controller *hpc_ptr; struct ebda_hpc_bus *bus_ptr; struct ebda_hpc_slot *slot_ptr; struct bus_info *bus_info_ptr1, *bus_info_ptr2; int rc; struct slot *tmp_slot; struct list_head *list; addr = hpc_list_ptr->phys_addr; for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) { bus_index = 1; ctlr_id = readb (io_mem + addr); addr += 1; slot_num = readb (io_mem + addr); addr += 1; addr_slot = addr; /* offset of slot structure */ addr += (slot_num * 4); bus_num = readb (io_mem + addr); addr += 1; addr_bus = addr; /* offset of bus */ addr += (bus_num * 9); /* offset of ctlr_type */ temp = readb (io_mem + addr); addr += 1; /* init hpc structure */ hpc_ptr = alloc_ebda_hpc (slot_num, bus_num); if (!hpc_ptr ) { rc = -ENOMEM; goto error_no_hpc; } hpc_ptr->ctlr_id = ctlr_id; hpc_ptr->ctlr_relative_id = ctlr; hpc_ptr->slot_count = slot_num; hpc_ptr->bus_count = bus_num; debug ("now enter ctlr data struture ---\n"); debug ("ctlr id: %x\n", ctlr_id); debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id); debug ("count of slots controlled by this ctlr: %x\n", slot_num); debug ("count of buses controlled by this ctlr: %x\n", bus_num); /* init slot structure, fetch slot, bus, cap... */ slot_ptr = hpc_ptr->slots; for (slot = 0; slot < slot_num; slot++) { slot_ptr->slot_num = readb (io_mem + addr_slot); slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num); slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num); slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num); // create bus_info lined list --- if only one slot per bus: slot_min = slot_max bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num); if (!bus_info_ptr2) { bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL); if (!bus_info_ptr1) { rc = -ENOMEM; goto error_no_hp_slot; } memset (bus_info_ptr1, 0, sizeof (struct bus_info)); bus_info_ptr1->slot_min = slot_ptr->slot_num; bus_info_ptr1->slot_max = slot_ptr->slot_num;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -