^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * IBM Hot Plug Controller Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written By: Tong Yu, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2001-2003 IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Send feedback to <gregkh@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "ibmphp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * POST builds data blocks(in this data block definition, a char-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * byte, short(or word)-2 byte, long(dword)-4 byte) in the Extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * BIOS Data Area which describe the configuration of the hot-plug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * controllers and resources used by the PCI Hot-Plug devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * This file walks EBDA, maps data block from physical addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * reconstruct linked lists about all system resource(MEM, PFM, IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * already assigned by POST, as well as linked lists about hot plug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * controllers (ctlr#, slot#, bus&slot features...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Global lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) LIST_HEAD(ibmphp_ebda_pci_rsrc_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) LIST_HEAD(ibmphp_slot_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Local variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static struct ebda_hpc_list *hpc_list_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static struct ebda_rsrc_list *rsrc_list_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct rio_table_hdr *rio_table_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static LIST_HEAD(ebda_hpc_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static LIST_HEAD(bus_info_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static LIST_HEAD(rio_vg_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static LIST_HEAD(rio_lo_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static LIST_HEAD(opt_vg_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static LIST_HEAD(opt_lo_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void __iomem *io_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Local functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int ebda_rsrc_controller(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int ebda_rsrc_rsrc(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int ebda_rio_table(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static struct ebda_hpc_list * __init alloc_ebda_hpc_list(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return kzalloc(sizeof(struct ebda_hpc_list), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static struct controller *alloc_ebda_hpc(u32 slot_count, u32 bus_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct controller *controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct ebda_hpc_slot *slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct ebda_hpc_bus *buses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) controller = kzalloc(sizeof(struct controller), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!controller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) slots = kcalloc(slot_count, sizeof(struct ebda_hpc_slot), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) goto error_contr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) controller->slots = slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) buses = kcalloc(bus_count, sizeof(struct ebda_hpc_bus), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!buses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) goto error_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) controller->buses = buses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) error_slots:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) kfree(controller->slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) error_contr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) kfree(controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void free_ebda_hpc(struct controller *controller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) kfree(controller->slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) kfree(controller->buses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) kfree(controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return kzalloc(sizeof(struct ebda_rsrc_list), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return kzalloc(sizeof(struct ebda_pci_rsrc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void __init print_bus_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct bus_info *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) debug("%s - slot_min = %x\n", __func__, ptr->slot_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) debug("%s - slot_max = %x\n", __func__, ptr->slot_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) debug("%s - slot_count = %x\n", __func__, ptr->slot_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) debug("%s - bus# = %x\n", __func__, ptr->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) debug("%s - current_speed = %x\n", __func__, ptr->current_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) debug("%s - controller_id = %x\n", __func__, ptr->controller_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) debug("%s - slots_at_33_conv = %x\n", __func__, ptr->slots_at_33_conv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) debug("%s - slots_at_66_conv = %x\n", __func__, ptr->slots_at_66_conv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) debug("%s - slots_at_66_pcix = %x\n", __func__, ptr->slots_at_66_pcix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) debug("%s - slots_at_100_pcix = %x\n", __func__, ptr->slots_at_100_pcix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) debug("%s - slots_at_133_pcix = %x\n", __func__, ptr->slots_at_133_pcix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void print_lo_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct rio_detail *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) debug("print_lo_info ----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) debug("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) debug("%s - rio_type = %x\n", __func__, ptr->rio_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) debug("%s - owner_id = %x\n", __func__, ptr->owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) debug("%s - first_slot_num = %x\n", __func__, ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) debug("%s - wpindex = %x\n", __func__, ptr->wpindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) debug("%s - chassis_num = %x\n", __func__, ptr->chassis_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void print_vg_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct rio_detail *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) debug("%s ---\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) debug("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) debug("%s - rio_type = %x\n", __func__, ptr->rio_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) debug("%s - owner_id = %x\n", __func__, ptr->owner_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) debug("%s - first_slot_num = %x\n", __func__, ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) debug("%s - wpindex = %x\n", __func__, ptr->wpindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) debug("%s - chassis_num = %x\n", __func__, ptr->chassis_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void __init print_ebda_pci_rsrc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct ebda_pci_rsrc *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) debug("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) __func__, ptr->rsrc_type, ptr->bus_num, ptr->dev_fun, ptr->start_addr, ptr->end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void __init print_ibm_slot(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct slot *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) debug("%s - slot_number: %x\n", __func__, ptr->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void __init print_opt_vg(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct opt_rio *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) debug("%s ---\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) debug("%s - rio_type %x\n", __func__, ptr->rio_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) debug("%s - chassis_num: %x\n", __func__, ptr->chassis_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) debug("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) debug("%s - middle_num: %x\n", __func__, ptr->middle_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void __init print_ebda_hpc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct controller *hpc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) for (index = 0; index < hpc_ptr->slot_count; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) debug("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) debug("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) debug("%s - index into ctlr addr: %x\n", __func__, hpc_ptr->slots[index].ctl_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) debug("%s - cap of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (index = 0; index < hpc_ptr->bus_count; index++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) debug("%s - bus# of each bus controlled by this ctlr: %x\n", __func__, hpc_ptr->buses[index].bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) debug("%s - type of hpc: %x\n", __func__, hpc_ptr->ctlr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) switch (hpc_ptr->ctlr_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) debug("%s - bus: %x\n", __func__, hpc_ptr->u.pci_ctlr.bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) debug("%s - dev_fun: %x\n", __func__, hpc_ptr->u.pci_ctlr.dev_fun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) debug("%s - irq: %x\n", __func__, hpc_ptr->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) debug("%s - io_start: %x\n", __func__, hpc_ptr->u.isa_ctlr.io_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) debug("%s - io_end: %x\n", __func__, hpc_ptr->u.isa_ctlr.io_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) debug("%s - irq: %x\n", __func__, hpc_ptr->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) debug("%s - wpegbbar: %lx\n", __func__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) debug("%s - i2c_addr: %x\n", __func__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) debug("%s - irq: %x\n", __func__, hpc_ptr->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int __init ibmphp_access_ebda(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) rio_complete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) hs_complete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) io_mem = ioremap((0x40 << 4) + 0x0e, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!io_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ebda_seg = readw(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) iounmap(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) debug("returned ebda segment: %x\n", ebda_seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) io_mem = ioremap(ebda_seg<<4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!io_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ebda_sz = readb(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) iounmap(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) debug("ebda size: %d(KiB)\n", ebda_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (ebda_sz == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!io_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) next_offset = 0x180;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) offset = next_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* Make sure what we read is still in the mapped section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (WARN(offset > (ebda_sz * 1024 - 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) "ibmphp_ebda: next read is beyond ebda_sz\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) next_offset = readw(io_mem + offset); /* offset of next blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) offset += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (next_offset == 0) /* 0 indicate it's last blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) blk_id = readw(io_mem + offset); /* this blk id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) offset += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* check if it is hot swap block or rio block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (blk_id != 0x4853 && blk_id != 0x4752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* found hs table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (blk_id == 0x4853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) debug("now enter hot swap block---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) debug("hot blk id: %x\n", blk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) format = readb(io_mem + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) offset += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (format != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) goto error_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) debug("hot blk format: %x\n", format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* hot swap sub blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) base = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sub_addr = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) re = readw(io_mem + sub_addr); /* next sub blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) sub_addr += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) rc_id = readw(io_mem + sub_addr); /* sub blk id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sub_addr += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (rc_id != 0x5243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto error_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* rc sub blk signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) num_ctlrs = readb(io_mem + sub_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) sub_addr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) hpc_list_ptr = alloc_ebda_hpc_list();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!hpc_list_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) hpc_list_ptr->format = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) hpc_list_ptr->num_ctlrs = num_ctlrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) hpc_list_ptr->phys_addr = sub_addr; /* offset of RSRC_CONTROLLER blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) debug("info about hpc descriptor---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) debug("hot blk format: %x\n", format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) debug("num of controller: %x\n", num_ctlrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) debug("offset of hpc data structure entries: %x\n ", sub_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) sub_addr = base + re; /* re sub blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* FIXME: rc is never used/checked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) rc = readw(io_mem + sub_addr); /* next sub blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) sub_addr += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) re_id = readw(io_mem + sub_addr); /* sub blk id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sub_addr += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (re_id != 0x5245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) goto error_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* signature of re */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) num_entries = readw(io_mem + sub_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) sub_addr += 2; /* offset of RSRC_ENTRIES blk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) rsrc_list_ptr = alloc_ebda_rsrc_list();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!rsrc_list_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rsrc_list_ptr->format = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) rsrc_list_ptr->num_entries = num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rsrc_list_ptr->phys_addr = sub_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) debug("info about rsrc descriptor---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) debug("format: %x\n", format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) debug("num of rsrc: %x\n", num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) debug("offset of rsrc data structure entries: %x\n ", sub_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) hs_complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* found rio table, blk_id == 0x4752 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) debug("now enter io table ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) debug("rio blk id: %x\n", blk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (!rio_table_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) rio_table_ptr->ver_num = readb(io_mem + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) rio_table_ptr->scal_count = readb(io_mem + offset + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) rio_table_ptr->riodev_count = readb(io_mem + offset + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) rio_table_ptr->offset = offset + 3 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) debug("info about rio table hdr ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) debug("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rio_table_ptr->ver_num, rio_table_ptr->scal_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) rio_table_ptr->riodev_count, rio_table_ptr->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) rio_complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!hs_complete && !rio_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto error_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (rio_table_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (rio_complete && rio_table_ptr->ver_num == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) rc = ebda_rio_table();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) rc = ebda_rsrc_controller();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) rc = ebda_rsrc_rsrc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) error_nodev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) iounmap(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * map info of scalability details and rio details from physical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int __init ebda_rio_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct rio_detail *rio_detail_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) offset = rio_table_ptr->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) offset += 12 * rio_table_ptr->scal_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) // we do concern about rio details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) for (i = 0; i < rio_table_ptr->riodev_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) rio_detail_ptr = kzalloc(sizeof(struct rio_detail), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (!rio_detail_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) rio_detail_ptr->rio_node_id = readb(io_mem + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) rio_detail_ptr->bbar = readl(io_mem + offset + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rio_detail_ptr->rio_type = readb(io_mem + offset + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) rio_detail_ptr->owner_id = readb(io_mem + offset + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) rio_detail_ptr->port0_node_connect = readb(io_mem + offset + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) rio_detail_ptr->port0_port_connect = readb(io_mem + offset + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rio_detail_ptr->port1_node_connect = readb(io_mem + offset + 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rio_detail_ptr->port1_port_connect = readb(io_mem + offset + 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) rio_detail_ptr->first_slot_num = readb(io_mem + offset + 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) rio_detail_ptr->status = readb(io_mem + offset + 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) rio_detail_ptr->wpindex = readb(io_mem + offset + 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) rio_detail_ptr->chassis_num = readb(io_mem + offset + 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) // 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);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) //create linked list of chassis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) list_add(&rio_detail_ptr->rio_detail_list, &rio_vg_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) //create linked list of expansion box
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) list_add(&rio_detail_ptr->rio_detail_list, &rio_lo_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) // not in my concern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) kfree(rio_detail_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) offset += 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) print_lo_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) print_vg_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * reorganizing linked list of chassis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static struct opt_rio *search_opt_vg(u8 chassis_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct opt_rio *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (ptr->chassis_num == chassis_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int __init combine_wpg_for_chassis(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct opt_rio *opt_rio_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct rio_detail *rio_detail_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) opt_rio_ptr = search_opt_vg(rio_detail_ptr->chassis_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!opt_rio_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!opt_rio_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) list_add(&opt_rio_ptr->opt_rio_list, &opt_vg_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) opt_rio_ptr->first_slot_num = min(opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) opt_rio_ptr->middle_num = max(opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) print_opt_vg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * reorganizing linked list of expansion box
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static struct opt_rio_lo *search_opt_lo(u8 chassis_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct opt_rio_lo *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ptr->chassis_num == chassis_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int combine_wpg_for_expansion(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct opt_rio_lo *opt_rio_lo_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct rio_detail *rio_detail_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) opt_rio_lo_ptr = search_opt_lo(rio_detail_ptr->chassis_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!opt_rio_lo_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!opt_rio_lo_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) opt_rio_lo_ptr->pack_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) list_add(&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) opt_rio_lo_ptr->first_slot_num = min(opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) opt_rio_lo_ptr->middle_num = max(opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) opt_rio_lo_ptr->pack_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* Since we don't know the max slot number per each chassis, hence go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * through the list of all chassis to find out the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * Arguments: slot_num, 1st slot number of the chassis we think we are on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * var (0 = chassis, 1 = expansion box)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int first_slot_num(u8 slot_num, u8 first_slot, u8 var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct opt_rio *opt_vg_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct opt_rio_lo *opt_lo_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!var) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static struct opt_rio_lo *find_rxe_num(u8 slot_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct opt_rio_lo *opt_lo_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) //check to see if this slot_num belongs to expansion box
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num(slot_num, opt_lo_ptr->first_slot_num, 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return opt_lo_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static struct opt_rio *find_chassis_num(u8 slot_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct opt_rio *opt_vg_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) //check to see if this slot_num belongs to chassis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num(slot_num, opt_vg_ptr->first_slot_num, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return opt_vg_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* This routine will find out how many slots are in the chassis, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static u8 calculate_first_slot(u8 slot_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u8 first_slot = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct slot *slot_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (slot_cur->ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) first_slot = slot_cur->ctrl->ending_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return first_slot + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #define SLOT_NAME_SIZE 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static char *create_file_name(struct slot *slot_cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct opt_rio *opt_vg_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct opt_rio_lo *opt_lo_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static char str[SLOT_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int which = 0; /* rxe = 1, chassis = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) u8 number = 1; /* either chassis or rxe # */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) u8 first_slot = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u8 slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) u8 flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!slot_cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) err("Structure passed is empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) slot_num = slot_cur->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) memset(str, 0, sizeof(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (rio_table_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (rio_table_ptr->ver_num == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) opt_vg_ptr = find_chassis_num(slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) opt_lo_ptr = find_rxe_num(slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (opt_vg_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (opt_lo_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) number = opt_lo_ptr->chassis_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) first_slot = opt_lo_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) which = 1; /* it is RXE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) first_slot = opt_vg_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) number = opt_vg_ptr->chassis_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) which = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) first_slot = opt_vg_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) number = opt_vg_ptr->chassis_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) which = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ++flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) } else if (opt_lo_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) number = opt_lo_ptr->chassis_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) first_slot = opt_lo_ptr->first_slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) which = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ++flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) } else if (rio_table_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (rio_table_ptr->ver_num == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* if both NULL and we DO have correct RIO table in BIOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (!flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (slot_cur->ctrl->ctlr_type == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) first_slot = calculate_first_slot(slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) which = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) which = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sprintf(str, "%s%dslot%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) which == 0 ? "chassis" : "rxe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) number, slot_num - first_slot + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static int fillslotinfo(struct hotplug_slot *hotplug_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct slot *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) slot = to_slot(hotplug_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct pci_driver ibmphp_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * each hpc from physical address to a list of hot plug controllers based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * hpc descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int __init ebda_rsrc_controller(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) u16 addr, addr_slot, addr_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) u8 ctlr_id, temp, bus_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) u16 ctlr, slot, bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) u16 slot_num, bus_num, index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct controller *hpc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct ebda_hpc_bus *bus_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct ebda_hpc_slot *slot_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct bus_info *bus_info_ptr1, *bus_info_ptr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct slot *tmp_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) char name[SLOT_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) addr = hpc_list_ptr->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) bus_index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ctlr_id = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) addr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) slot_num = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) addr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) addr_slot = addr; /* offset of slot structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) addr += (slot_num * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) bus_num = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) addr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) addr_bus = addr; /* offset of bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) addr += (bus_num * 9); /* offset of ctlr_type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) temp = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) addr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* init hpc structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) hpc_ptr = alloc_ebda_hpc(slot_num, bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!hpc_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) hpc_ptr->ctlr_id = ctlr_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) hpc_ptr->ctlr_relative_id = ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) hpc_ptr->slot_count = slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) hpc_ptr->bus_count = bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) debug("now enter ctlr data structure ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) debug("ctlr id: %x\n", ctlr_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) debug("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) debug("count of slots controlled by this ctlr: %x\n", slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) debug("count of buses controlled by this ctlr: %x\n", bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* init slot structure, fetch slot, bus, cap... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) slot_ptr = hpc_ptr->slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) for (slot = 0; slot < slot_num; slot++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) slot_ptr->slot_num = readb(io_mem + addr_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) slot_ptr->slot_bus_num = readb(io_mem + addr_slot + slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) slot_ptr->ctl_index = readb(io_mem + addr_slot + 2*slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) slot_ptr->slot_cap = readb(io_mem + addr_slot + 3*slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) // create bus_info lined list --- if only one slot per bus: slot_min = slot_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) bus_info_ptr2 = ibmphp_find_same_bus_num(slot_ptr->slot_bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!bus_info_ptr2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (!bus_info_ptr1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) goto error_no_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) bus_info_ptr1->slot_min = slot_ptr->slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) bus_info_ptr1->slot_max = slot_ptr->slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) bus_info_ptr1->slot_count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) bus_info_ptr1->busno = slot_ptr->slot_bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) bus_info_ptr1->index = bus_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) bus_info_ptr1->current_speed = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) bus_info_ptr1->current_bus_mode = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) list_add_tail(&bus_info_ptr1->bus_info_list, &bus_info_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) bus_info_ptr2->slot_min = min(bus_info_ptr2->slot_min, slot_ptr->slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) bus_info_ptr2->slot_max = max(bus_info_ptr2->slot_max, slot_ptr->slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) bus_info_ptr2->slot_count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) // end of creating the bus_info linked list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) slot_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) addr_slot += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* init bus structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) bus_ptr = hpc_ptr->buses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) for (bus = 0; bus < bus_num; bus++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) bus_ptr->bus_num = readb(io_mem + addr_bus + bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) bus_ptr->slots_at_33_conv = readb(io_mem + addr_bus + bus_num + 8 * bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) bus_ptr->slots_at_66_conv = readb(io_mem + addr_bus + bus_num + 8 * bus + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) bus_ptr->slots_at_66_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) bus_ptr->slots_at_100_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) bus_ptr->slots_at_133_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) bus_info_ptr2 = ibmphp_find_same_bus_num(bus_ptr->bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (bus_info_ptr2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) bus_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) hpc_ptr->ctlr_type = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) switch (hpc_ptr->ctlr_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) hpc_ptr->u.pci_ctlr.bus = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) hpc_ptr->u.pci_ctlr.dev_fun = readb(io_mem + addr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) hpc_ptr->irq = readb(io_mem + addr + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) addr += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) debug("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) hpc_ptr->u.pci_ctlr.bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) hpc_ptr->u.isa_ctlr.io_start = readw(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) hpc_ptr->u.isa_ctlr.io_end = readw(io_mem + addr + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (!request_region(hpc_ptr->u.isa_ctlr.io_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) "ibmphp")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) goto error_no_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) hpc_ptr->irq = readb(io_mem + addr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) addr += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) hpc_ptr->u.wpeg_ctlr.wpegbbar = readl(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) hpc_ptr->u.wpeg_ctlr.i2c_addr = readb(io_mem + addr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) hpc_ptr->irq = readb(io_mem + addr + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) addr += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) goto error_no_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) //reorganize chassis' linked list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) combine_wpg_for_chassis();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) combine_wpg_for_expansion();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) hpc_ptr->revision = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) hpc_ptr->options = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) // register slots with hpc core as well as create linked list of ibm slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) for (index = 0; index < hpc_ptr->slot_count; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!tmp_slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto error_no_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) tmp_slot->flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) tmp_slot->supported_speed = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) tmp_slot->supported_speed = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) tmp_slot->supported_speed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) tmp_slot->supported_bus_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) tmp_slot->supported_bus_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) bus_info_ptr1 = ibmphp_find_same_bus_num(hpc_ptr->slots[index].slot_bus_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!bus_info_ptr1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) tmp_slot->bus_on = bus_info_ptr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) bus_info_ptr1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) tmp_slot->ctrl = hpc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) tmp_slot->number = hpc_ptr->slots[index].slot_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) rc = fillslotinfo(&tmp_slot->hotplug_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) rc = ibmphp_init_devno(&tmp_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) tmp_slot->hotplug_slot.ops = &ibmphp_hotplug_slot_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) // end of registering ibm slot with hotplug core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) list_add(&tmp_slot->ibm_slot_list, &ibmphp_slot_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) print_bus_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) list_add(&hpc_ptr->ebda_hpc_list, &ebda_hpc_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) } /* each hpc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) pci_hp_register(&tmp_slot->hotplug_slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) print_ebda_hpc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) print_ibm_slot();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) kfree(tmp_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) error_no_slot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) free_ebda_hpc(hpc_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * map info (bus, devfun, start addr, end addr..) of i/o, memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * pfm from the physical addr to a list of resource.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static int __init ebda_rsrc_rsrc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) u16 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) short rsrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) u8 type, rsrc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct ebda_pci_rsrc *rsrc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) addr = rsrc_list_ptr->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) debug("now entering rsrc land\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) debug("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) type = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) addr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) rsrc_type = type & EBDA_RSRC_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (rsrc_type == EBDA_IO_RSRC_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) rsrc_ptr = alloc_ebda_pci_rsrc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (!rsrc_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) iounmap(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) rsrc_ptr->rsrc_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) rsrc_ptr->bus_num = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) rsrc_ptr->dev_fun = readb(io_mem + addr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) rsrc_ptr->start_addr = readw(io_mem + addr + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) rsrc_ptr->end_addr = readw(io_mem + addr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) addr += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) debug("rsrc from io type ----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) debug("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) list_add(&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) rsrc_ptr = alloc_ebda_pci_rsrc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (!rsrc_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) iounmap(io_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) rsrc_ptr->rsrc_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) rsrc_ptr->bus_num = readb(io_mem + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) rsrc_ptr->dev_fun = readb(io_mem + addr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) rsrc_ptr->start_addr = readl(io_mem + addr + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) rsrc_ptr->end_addr = readl(io_mem + addr + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) addr += 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) debug("rsrc from mem or pfm ---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) debug("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) list_add(&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) kfree(rsrc_list_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) rsrc_list_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) print_ebda_pci_rsrc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) u16 ibmphp_get_total_controllers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return hpc_list_ptr->num_ctlrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct slot *ibmphp_get_slot_from_physical_num(u8 physical_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct slot *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) list_for_each_entry(slot, &ibmphp_slot_head, ibm_slot_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (slot->number == physical_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /* To find:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * - the smallest slot number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * - the largest slot number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * - the total number of the slots based on each bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * (if only one slot per bus slot_min = slot_max )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct bus_info *ibmphp_find_same_bus_num(u32 num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct bus_info *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (ptr->busno == num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* Finding relative bus number, in order to map corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * bus register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int ibmphp_get_bus_index(u8 num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct bus_info *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (ptr->busno == num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return ptr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) void ibmphp_free_bus_info_queue(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct bus_info *bus_info, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) list_for_each_entry_safe(bus_info, next, &bus_info_head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) bus_info_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) kfree (bus_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) void ibmphp_free_ebda_hpc_queue(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct controller *controller = NULL, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) int pci_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) list_for_each_entry_safe(controller, next, &ebda_hpc_head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ebda_hpc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (controller->ctlr_type == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) release_region(controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) else if ((controller->ctlr_type == 1) && (!pci_flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ++pci_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) pci_unregister_driver(&ibmphp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) free_ebda_hpc(controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) void ibmphp_free_ebda_pci_rsrc_queue(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct ebda_pci_rsrc *resource, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) list_for_each_entry_safe(resource, next, &ibmphp_ebda_pci_rsrc_head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ebda_pci_rsrc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) kfree (resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) resource = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static const struct pci_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .vendor = PCI_VENDOR_ID_IBM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) .device = HPC_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) .subvendor = PCI_VENDOR_ID_IBM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) .subdevice = HPC_SUBSYSTEM_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }, {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) MODULE_DEVICE_TABLE(pci, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) static int ibmphp_probe(struct pci_dev *, const struct pci_device_id *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static struct pci_driver ibmphp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .name = "ibmphp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .probe = ibmphp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) int ibmphp_register_pci(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct controller *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (ctrl->ctlr_type == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) rc = pci_register_driver(&ibmphp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static int ibmphp_probe(struct pci_dev *dev, const struct pci_device_id *ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct controller *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) debug("inside ibmphp_probe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (ctrl->ctlr_type == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) ctrl->ctrl_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) debug("found device!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) debug("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }