static int __init ebda_rsrc_controller()

in hotplug/ibmphp_ebda.c [681:913]


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 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;
	char name[SLOT_NAME_SIZE];

	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) {
			return -ENOMEM;
		}
		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 structure ---\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 = kzalloc(sizeof(struct bus_info), GFP_KERNEL);
				if (!bus_info_ptr1) {
					rc = -ENOMEM;
					goto error_no_slot;
				}
				bus_info_ptr1->slot_min = slot_ptr->slot_num;
				bus_info_ptr1->slot_max = slot_ptr->slot_num;
				bus_info_ptr1->slot_count += 1;
				bus_info_ptr1->busno = slot_ptr->slot_bus_num;
				bus_info_ptr1->index = bus_index++;
				bus_info_ptr1->current_speed = 0xff;
				bus_info_ptr1->current_bus_mode = 0xff;

				bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;

				list_add_tail(&bus_info_ptr1->bus_info_list, &bus_info_head);

			} else {
				bus_info_ptr2->slot_min = min(bus_info_ptr2->slot_min, slot_ptr->slot_num);
				bus_info_ptr2->slot_max = max(bus_info_ptr2->slot_max, slot_ptr->slot_num);
				bus_info_ptr2->slot_count += 1;

			}

			// end of creating the bus_info linked list

			slot_ptr++;
			addr_slot += 1;
		}

		/* init bus structure */
		bus_ptr = hpc_ptr->buses;
		for (bus = 0; bus < bus_num; bus++) {
			bus_ptr->bus_num = readb(io_mem + addr_bus + bus);
			bus_ptr->slots_at_33_conv = readb(io_mem + addr_bus + bus_num + 8 * bus);
			bus_ptr->slots_at_66_conv = readb(io_mem + addr_bus + bus_num + 8 * bus + 1);

			bus_ptr->slots_at_66_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 2);

			bus_ptr->slots_at_100_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 3);

			bus_ptr->slots_at_133_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 4);

			bus_info_ptr2 = ibmphp_find_same_bus_num(bus_ptr->bus_num);
			if (bus_info_ptr2) {
				bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
				bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
				bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;
				bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix;
				bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix;
			}
			bus_ptr++;
		}

		hpc_ptr->ctlr_type = temp;

		switch (hpc_ptr->ctlr_type) {
			case 1:
				hpc_ptr->u.pci_ctlr.bus = readb(io_mem + addr);
				hpc_ptr->u.pci_ctlr.dev_fun = readb(io_mem + addr + 1);
				hpc_ptr->irq = readb(io_mem + addr + 2);
				addr += 3;
				debug("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",
					hpc_ptr->u.pci_ctlr.bus,
					hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
				break;

			case 0:
				hpc_ptr->u.isa_ctlr.io_start = readw(io_mem + addr);
				hpc_ptr->u.isa_ctlr.io_end = readw(io_mem + addr + 2);
				if (!request_region(hpc_ptr->u.isa_ctlr.io_start,
						     (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
						     "ibmphp")) {
					rc = -ENODEV;
					goto error_no_slot;
				}
				hpc_ptr->irq = readb(io_mem + addr + 4);
				addr += 5;
				break;

			case 2:
			case 4:
				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl(io_mem + addr);
				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb(io_mem + addr + 4);
				hpc_ptr->irq = readb(io_mem + addr + 5);
				addr += 6;
				break;
			default:
				rc = -ENODEV;
				goto error_no_slot;
		}

		//reorganize chassis' linked list
		combine_wpg_for_chassis();
		combine_wpg_for_expansion();
		hpc_ptr->revision = 0xff;
		hpc_ptr->options = 0xff;
		hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
		hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num;

		// register slots with hpc core as well as create linked list of ibm slot
		for (index = 0; index < hpc_ptr->slot_count; index++) {
			tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
			if (!tmp_slot) {
				rc = -ENOMEM;
				goto error_no_slot;
			}

			tmp_slot->flag = 1;

			tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
				tmp_slot->supported_speed =  3;
			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
				tmp_slot->supported_speed =  2;
			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
				tmp_slot->supported_speed =  1;

			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
				tmp_slot->supported_bus_mode = 1;
			else
				tmp_slot->supported_bus_mode = 0;


			tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;

			bus_info_ptr1 = ibmphp_find_same_bus_num(hpc_ptr->slots[index].slot_bus_num);
			if (!bus_info_ptr1) {
				rc = -ENODEV;
				goto error;
			}
			tmp_slot->bus_on = bus_info_ptr1;
			bus_info_ptr1 = NULL;
			tmp_slot->ctrl = hpc_ptr;

			tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
			tmp_slot->number = hpc_ptr->slots[index].slot_num;

			rc = fillslotinfo(&tmp_slot->hotplug_slot);
			if (rc)
				goto error;

			rc = ibmphp_init_devno(&tmp_slot);
			if (rc)
				goto error;
			tmp_slot->hotplug_slot.ops = &ibmphp_hotplug_slot_ops;

			// end of registering ibm slot with hotplug core

			list_add(&tmp_slot->ibm_slot_list, &ibmphp_slot_head);
		}

		print_bus_info();
		list_add(&hpc_ptr->ebda_hpc_list, &ebda_hpc_head);

	}			/* each hpc  */

	list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
		snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot));
		pci_hp_register(&tmp_slot->hotplug_slot,
			pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
	}

	print_ebda_hpc();
	print_ibm_slot();
	return 0;

error:
	kfree(tmp_slot);
error_no_slot:
	free_ebda_hpc(hpc_ptr);
	return rc;
}