Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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: Irene Zubarev, 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 Greg Kroah-Hartman (greg@kroah.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (C) 2001,2002 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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "ibmphp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) static int configure_device(struct pci_func *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) static int configure_bridge(struct pci_func **, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) static int add_new_bus(struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) static u8 find_sec_number(u8 primary_busno, u8 slotno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * NOTE..... If BIOS doesn't provide default routing, we assign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * 9 for SCSI, 10 for LAN adapters, and 11 for everything else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  * If adapter is bridged, then we assign 11 to it and devices behind it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * We also assign the same irq numbers for multi function devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) static void assign_alt_irq(struct pci_func *cur_func, u8 class_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	for (j = 0; j < 4; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 		if (cur_func->irq[j] == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 			switch (class_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 				case PCI_BASE_CLASS_STORAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 					cur_func->irq[j] = SCSI_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 				case PCI_BASE_CLASS_NETWORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 					cur_func->irq[j] = LAN_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 					cur_func->irq[j] = OTHER_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  * Configures the device to be added (will allocate needed resources if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)  * can), the device can be a bridge or a regular pci device, can also be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59)  * multi-functional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)  * Input: function to be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63)  * TO DO:  The error case with Multifunction device or multi function bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  * if there is an error, will need to go through all previous functions and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  * unconfigure....or can add some code into unconfigure_card....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) int ibmphp_configure_card(struct pci_func *func, u8 slotno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	u16 vendor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	u32 class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	u8 class_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	u8 hdr_type, device, sec_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	u8 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	struct pci_func *newfunc;	/* for multi devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	struct pci_func *cur_func, *prev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	int rc, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	int cleanup_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	u8 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	debug("inside configure_card, func->busno = %x\n", func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	device = func->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	cur_func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	/* We only get bus and device from IRQ routing table.  So at this point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	 * func->busno is correct, and func->device contains only device (at the 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	 * highest bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	/* For every function on the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	for (function = 0x00; function < 0x08; function++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		unsigned int devfn = PCI_DEVFN(device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		ibmphp_pci_bus->number = cur_func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		cur_func->function = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		debug("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->function = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 			cur_func->busno, cur_func->device, cur_func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		debug("vendor_id is %x\n", vendor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 			/* found correct device!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 			debug("found valid device, vendor_id = %x\n", vendor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 			++valid_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 			/* header: x x x x x x x x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 			 *         |_=> 0 = single function device, 1 = multi-function device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 			pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 			pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 			class_code = class >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 			debug("hrd_type = %x, class = %x, class_code %x\n", hdr_type, class, class_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 				err("The device %x is VGA compatible and as is not supported for hot plugging. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 				     "Please choose another device.\n", cur_func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 				return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 			} else if (class == PCI_CLASS_DISPLAY_VGA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 				err("The device %x is not supported for hot plugging. Please choose another device.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 				     cur_func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 				return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 			switch (hdr_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 				case PCI_HEADER_TYPE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 					debug("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 					assign_alt_irq(cur_func, class_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 					rc = configure_device(cur_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 					if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 						/* We need to do this in case some other BARs were properly inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 						err("was not able to configure devfunc %x on bus %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 						     cur_func->device, cur_func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 						cleanup_count = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 						goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 					cur_func->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 					function = 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 				case PCI_HEADER_TYPE_MULTIDEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 					assign_alt_irq(cur_func, class_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 					rc = configure_device(cur_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 					if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 						/* We need to do this in case some other BARs were properly inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 						err("was not able to configure devfunc %x on bus %x...bailing out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 						     cur_func->device, cur_func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 						cleanup_count = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 						goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 					newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 					if (!newfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 						return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 					newfunc->busno = cur_func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 					newfunc->device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 					cur_func->next = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 					cur_func = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 					for (j = 0; j < 4; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 						newfunc->irq[j] = cur_func->irq[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 				case PCI_HEADER_TYPE_MULTIBRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 					class >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 					if (class != PCI_CLASS_BRIDGE_PCI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 						err("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 						     cur_func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 						return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 					assign_alt_irq(cur_func, class_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 					rc = configure_bridge(&cur_func, slotno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 					if (rc == -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 						err("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 						err("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 					if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 						/* We need to do this in case some other BARs were properly inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 						err("was not able to hot-add PPB properly.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 						cleanup_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 						goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 					pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 					flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 					for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 						if (func->devices[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 							newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 							if (!newfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 								return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 							newfunc->busno = sec_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 							newfunc->device = (u8) i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 							for (j = 0; j < 4; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 								newfunc->irq[j] = cur_func->irq[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 							if (flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 								prev_func->next = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 							} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 								cur_func->next = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 							rc = ibmphp_configure_card(newfunc, slotno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 							/* This could only happen if kmalloc failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 							if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 								/* We need to do this in case bridge itself got configured properly, but devices behind it failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 								cleanup_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 								goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 							}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 							flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 					newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 					if (!newfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 						return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 					newfunc->busno = cur_func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 					newfunc->device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 					for (j = 0; j < 4; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 						newfunc->irq[j] = cur_func->irq[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 					for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 					prev_func->next = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 					cur_func = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 				case PCI_HEADER_TYPE_BRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 					class >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 					debug("class now is %x\n", class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 					if (class != PCI_CLASS_BRIDGE_PCI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 						err("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 						     cur_func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 						return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 					assign_alt_irq(cur_func, class_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 					debug("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 					rc = configure_bridge(&cur_func, slotno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 					if (rc == -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 						err("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 						err("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 					if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 						/* We need to do this in case some other BARs were properly inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 						err("was not able to hot-add PPB properly.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 						cleanup_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 						goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 					debug("cur_func->busno = %x, device = %x, function = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 						cur_func->busno, device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 					pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 					debug("after configuring bridge..., sec_number = %x\n", sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 					flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 					for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 						if (func->devices[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 							debug("inside for loop, device is %x\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 							newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 							if (!newfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 								return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 							newfunc->busno = sec_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 							newfunc->device = (u8) i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 							for (j = 0; j < 4; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 								newfunc->irq[j] = cur_func->irq[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 							if (flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 								prev_func->next = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 							} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 								cur_func->next = newfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 							rc = ibmphp_configure_card(newfunc, slotno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 							/* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 							if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 								/* We need to do this in case some other BARs were properly inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 								cleanup_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 								goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 							}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 							flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 					function = 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 					err("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 					return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			}	/* end of switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		}	/* end of valid device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	}	/* end of for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	if (!valid_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		err("Cannot find any valid devices on the card.  Or unable to read from card.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	for (i = 0; i < cleanup_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		if (cur_func->io[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			ibmphp_remove_resource(cur_func->io[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			cur_func->io[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		} else if (cur_func->pfmem[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			ibmphp_remove_resource(cur_func->pfmem[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			cur_func->pfmem[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		} else if (cur_func->mem[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 			ibmphp_remove_resource(cur_func->mem[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			cur_func->mem[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326)  * This function configures the pci BARs of a single device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327)  * Input: pointer to the pci_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328)  * Output: configured PCI, 0, or error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) static int configure_device(struct pci_func *func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	u32 bar[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	u32 address[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		PCI_BASE_ADDRESS_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		PCI_BASE_ADDRESS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		PCI_BASE_ADDRESS_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		PCI_BASE_ADDRESS_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		PCI_BASE_ADDRESS_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		PCI_BASE_ADDRESS_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	u8 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	int len[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	struct resource_node *io[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	struct resource_node *mem[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	struct resource_node *mem_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	struct resource_node *pfmem[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	debug("%s - inside\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	devfn = PCI_DEVFN(func->device, func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	ibmphp_pci_bus->number = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	for (count = 0; address[count]; count++) {	/* for 6 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		/* not sure if i need this.  per scott, said maybe need * something like this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		   if devices don't adhere 100% to the spec, so don't want to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		   to the reserved bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		pcibios_read_config_byte(cur_func->busno, cur_func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		PCI_BASE_ADDRESS_0 + 4 * count, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		if (tmp & 0x01) // IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 			pcibios_write_config_dword(cur_func->busno, cur_func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		else  // Memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			pcibios_write_config_dword(cur_func->busno, cur_func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		if (!bar[count])	/* This BAR is not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		debug("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			/* This is IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 			debug("inside IO SPACE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 			len[count] = bar[count] & 0xFFFFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			debug("len[count] in IO %x, count %d\n", len[count], count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 			io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 			if (!io[count])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 			io[count]->type = IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 			io[count]->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 			io[count]->devfunc = PCI_DEVFN(func->device, func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			io[count]->len = len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			if (ibmphp_check_resource(io[count], 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 				ibmphp_add_resource(io[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 				func->io[count] = io[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 				err("cannot allocate requested io for bus %x device %x function %x len %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 				     func->busno, func->device, func->function, len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 				kfree(io[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 				return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			/* _______________This is for debugging purposes only_____________________ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			debug("b4 writing, the IO address is %x\n", func->io[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 			debug("after writing.... the start address is %x\n", bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 			/* _________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 			/* This is Memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 				/* pfmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 				debug("PFMEM SPACE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				len[count] = bar[count] & 0xFFFFFFF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 				len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				debug("len[count] in PFMEM %x, count %d\n", len[count], count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 				pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 				if (!pfmem[count])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				pfmem[count]->type = PFMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 				pfmem[count]->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				pfmem[count]->devfunc = PCI_DEVFN(func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 							func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 				pfmem[count]->len = len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				pfmem[count]->fromMem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 				if (ibmphp_check_resource(pfmem[count], 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 					ibmphp_add_resource(pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 					func->pfmem[count] = pfmem[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 					mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 					if (!mem_tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 						kfree(pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 						return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 					mem_tmp->type = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 					mem_tmp->busno = pfmem[count]->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 					mem_tmp->devfunc = pfmem[count]->devfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 					mem_tmp->len = pfmem[count]->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 					debug("there's no pfmem... going into mem.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 					if (ibmphp_check_resource(mem_tmp, 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 						ibmphp_add_resource(mem_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 						pfmem[count]->fromMem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 						pfmem[count]->rangeno = mem_tmp->rangeno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 						pfmem[count]->start = mem_tmp->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 						pfmem[count]->end = mem_tmp->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 						ibmphp_add_pfmem_from_mem(pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 						func->pfmem[count] = pfmem[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 					} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 						err("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 						     func->busno, func->device, len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 						kfree(mem_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 						kfree(pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 						return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 				/*_______________This is for debugging purposes only______________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 				debug("b4 writing, start address is %x\n", func->pfmem[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 				pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 				debug("after writing, start address is %x\n", bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 				/*_________________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 					debug("inside the mem 64 case, count %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 					count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 					pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				/* regular memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 				debug("REGULAR MEM SPACE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				len[count] = bar[count] & 0xFFFFFFF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				debug("len[count] in Mem %x, count %d\n", len[count], count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 				mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 				if (!mem[count])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 				mem[count]->type = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 				mem[count]->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 				mem[count]->devfunc = PCI_DEVFN(func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 							func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 				mem[count]->len = len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 				if (ibmphp_check_resource(mem[count], 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 					ibmphp_add_resource(mem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 					func->mem[count] = mem[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 					err("cannot allocate requested mem for bus %x, device %x, len %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 					     func->busno, func->device, len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 					kfree(mem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 					return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 				pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 				/* _______________________This is for debugging purposes only _______________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 				debug("b4 writing, start address is %x\n", func->mem[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 				pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 				debug("after writing, the address is %x\n", bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 				/* __________________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 					/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 					debug("inside mem 64 case, reg. mem, count %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 					count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 					pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
^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) 		}		/* end of mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	}			/* end of for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	func->bus = 0;		/* To indicate that this is not a PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	if ((irq > 0x00) && (irq < 0x05))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	pci_bus_write_config_dword(ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) }
^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)  * This routine configures a PCI-2-PCI bridge and the functions behind it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  * Parameters: pci_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) static int configure_bridge(struct pci_func **func_passed, u8 slotno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	u8 sec_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	u8 io_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	u16 pfmem_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	u32 bar[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	u32 len[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	u8 flag_io = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	u8 flag_mem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	u8 flag_pfmem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	u8 need_io_upper = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	u8 need_pfmem_upper = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	struct res_needed *amount_needed = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	struct resource_node *io = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	struct resource_node *bus_io[2] = {NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	struct resource_node *mem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	struct resource_node *bus_mem[2] = {NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	struct resource_node *mem_tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	struct resource_node *pfmem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	struct resource_node *bus_pfmem[2] = {NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	struct bus_node *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	u32 address[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		PCI_BASE_ADDRESS_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		PCI_BASE_ADDRESS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	struct pci_func *func = *func_passed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	u8 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	debug("%s - enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	devfn = PCI_DEVFN(func->function, func->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	ibmphp_pci_bus->number = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	/* Configuring necessary info for the bridge so that we could see the devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	 * behind it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	/* _____________________For debugging purposes only __________________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	pci_bus_config_byte(ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	debug("primary # written into the bridge is %x\n", pri_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	 ___________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	/* in EBDA, only get allocated 1 additional bus # per slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	sec_number = find_sec_number(func->busno, slotno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	if (sec_number == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		err("cannot allocate secondary bus number for the bridged device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	debug("after find_sec_number, the number we got is %x\n", sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	debug("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	/* __________________For debugging purposes only __________________________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	debug("sec_number after write/read is %x\n", sec_number);
^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) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	/* __________________For debugging purposes only ____________________________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	debug("subordinate number after write/read is %x\n", sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	 __________________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	debug("func->busno is %x\n", func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	debug("sec_number after writing is %x\n", sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	/* First we need to allocate mem/io for the bridge itself in case it needs it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	for (count = 0; address[count]; count++) {	/* for 2 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		if (!bar[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			/* This BAR is not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			debug("so we come here then, eh?, count = %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		//  tmp_bar = bar[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		debug("Bar %d wants %x\n", count, bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			/* This is IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			len[count] = bar[count] & 0xFFFFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			debug("len[count] in IO = %x\n", len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			if (!bus_io[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 				retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			bus_io[count]->type = IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			bus_io[count]->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			bus_io[count]->devfunc = PCI_DEVFN(func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 							func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			bus_io[count]->len = len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			if (ibmphp_check_resource(bus_io[count], 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 				ibmphp_add_resource(bus_io[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 				func->io[count] = bus_io[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 				err("cannot allocate requested io for bus %x, device %x, len %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 				     func->busno, func->device, len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				kfree(bus_io[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			/* This is Memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 				/* pfmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 				len[count] = bar[count] & 0xFFFFFFF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 				len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 				debug("len[count] in PFMEM = %x\n", len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 				bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 				if (!bus_pfmem[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 					retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 					goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 				bus_pfmem[count]->type = PFMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 				bus_pfmem[count]->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 				bus_pfmem[count]->devfunc = PCI_DEVFN(func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 							func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 				bus_pfmem[count]->len = len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 				bus_pfmem[count]->fromMem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 				if (ibmphp_check_resource(bus_pfmem[count], 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 					ibmphp_add_resource(bus_pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 					func->pfmem[count] = bus_pfmem[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 					mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 					if (!mem_tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 						retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 						goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 					mem_tmp->type = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 					mem_tmp->busno = bus_pfmem[count]->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 					mem_tmp->devfunc = bus_pfmem[count]->devfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 					mem_tmp->len = bus_pfmem[count]->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 					if (ibmphp_check_resource(mem_tmp, 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 						ibmphp_add_resource(mem_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 						bus_pfmem[count]->fromMem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 						bus_pfmem[count]->rangeno = mem_tmp->rangeno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 						ibmphp_add_pfmem_from_mem(bus_pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 						func->pfmem[count] = bus_pfmem[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 					} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 						err("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 						     func->busno, func->device, len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 						kfree(mem_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 						kfree(bus_pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 						return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 				pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 					/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 					count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 					pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 				/* regular memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				len[count] = bar[count] & 0xFFFFFFF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 				len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 				debug("len[count] in Memory is %x\n", len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 				bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 				if (!bus_mem[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 					retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 					goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 				bus_mem[count]->type = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 				bus_mem[count]->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 				bus_mem[count]->devfunc = PCI_DEVFN(func->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 							func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 				bus_mem[count]->len = len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 				if (ibmphp_check_resource(bus_mem[count], 0) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 					ibmphp_add_resource(bus_mem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 					func->mem[count] = bus_mem[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 					err("cannot allocate requested mem for bus %x, device %x, len %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 					     func->busno, func->device, len[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 					kfree(bus_mem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 					return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 				pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 					/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 					count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 					pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		}		/* end of mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	}			/* end of for  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	/* Now need to see how much space the devices behind the bridge needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	amount_needed = scan_behind_bridge(func, sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	if (amount_needed == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	ibmphp_pci_bus->number = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	debug("after coming back from scan_behind_bridge\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	debug("amount_needed->not_correct = %x\n", amount_needed->not_correct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	debug("amount_needed->io = %x\n", amount_needed->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	debug("amount_needed->mem = %x\n", amount_needed->mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	debug("amount_needed->pfmem =  %x\n", amount_needed->pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	if (amount_needed->not_correct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		debug("amount_needed is not correct\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		for (count = 0; address[count]; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 			/* for 2 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 			if (bus_io[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 				ibmphp_remove_resource(bus_io[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 				func->io[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			} else if (bus_pfmem[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 				ibmphp_remove_resource(bus_pfmem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 				func->pfmem[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			} else if (bus_mem[count]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 				ibmphp_remove_resource(bus_mem[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 				func->mem[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		kfree(amount_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	if (!amount_needed->io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		debug("it doesn't want IO?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		flag_io = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		debug("it wants %x IO behind the bridge\n", amount_needed->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		io = kzalloc(sizeof(*io), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		if (!io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		io->type = IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		io->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		io->devfunc = PCI_DEVFN(func->device, func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		io->len = amount_needed->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		if (ibmphp_check_resource(io, 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			debug("were we able to add io\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			ibmphp_add_resource(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			flag_io = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	if (!amount_needed->mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		debug("it doesn't want n.e.memory?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		flag_mem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		debug("it wants %x memory behind the bridge\n", amount_needed->mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		if (!mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		mem->type = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		mem->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		mem->devfunc = PCI_DEVFN(func->device, func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		mem->len = amount_needed->mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		if (ibmphp_check_resource(mem, 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			ibmphp_add_resource(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			flag_mem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			debug("were we able to add mem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	if (!amount_needed->pfmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		debug("it doesn't want n.e.pfmem mem?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		flag_pfmem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		debug("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		if (!pfmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		pfmem->type = PFMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		pfmem->busno = func->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		pfmem->devfunc = PCI_DEVFN(func->device, func->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		pfmem->len = amount_needed->pfmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		pfmem->fromMem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		if (ibmphp_check_resource(pfmem, 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			ibmphp_add_resource(pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			flag_pfmem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			if (!mem_tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 				retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			mem_tmp->type = MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			mem_tmp->busno = pfmem->busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			mem_tmp->devfunc = pfmem->devfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			mem_tmp->len = pfmem->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			if (ibmphp_check_resource(mem_tmp, 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 				ibmphp_add_resource(mem_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 				pfmem->fromMem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				pfmem->rangeno = mem_tmp->rangeno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 				ibmphp_add_pfmem_from_mem(pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 				flag_pfmem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	debug("b4 if (flag_io && flag_mem && flag_pfmem)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	debug("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	if (flag_io && flag_mem && flag_pfmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		/* If on bootup, there was a bridged card in this slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		 * then card was removed and ibmphp got unloaded and loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		 * back again, there's no way for us to remove the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		 * struct, so no need to kmalloc, can use existing node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		bus = ibmphp_find_res_bus(sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			bus = kzalloc(sizeof(*bus), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 				retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 			bus->busno = sec_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 			debug("b4 adding new bus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			rc = add_new_bus(bus, io, mem, pfmem, func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		} else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			rc = add_new_bus(bus, io, mem, pfmem, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 			err("expected bus structure not empty?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 			if (rc == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 				ibmphp_remove_bus(bus, func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 				kfree(amount_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			retval = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 			debug("io 32\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 			need_io_upper = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		if ((pfmem_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			debug("pfmem 64\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			need_pfmem_upper = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		if (bus->noIORanges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			/* _______________This is for debugging purposes only ____________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			debug("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 			pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			debug("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			 ________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			if (need_io_upper) {	/* since can't support n.e.ways */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 				pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 				pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 			pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 			pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		if (bus->noMemRanges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 			/* ____________________This is for debugging purposes only ________________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			debug("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 			pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 			debug("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			 __________________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		if (bus->noPFMemRanges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			/* __________________________This is for debugging purposes only _______________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			debug("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			debug("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			 ______________________________________________________________________________________*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 			if (need_pfmem_upper) {	/* since can't support n.e.ways */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 				pci_bus_write_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 				pci_bus_write_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 			pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		debug("b4 writing control information\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		if ((irq > 0x00) && (irq < 0x05))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 			pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			if (amount_needed->devices[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 				debug("device where devices[i] is 1 = %x\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 				func->devices[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		func->bus = 1;	/* For unconfiguring, to indicate it's PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		func_passed = &func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		debug("func->busno b4 returning is %x\n", func->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		debug("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		kfree(amount_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		err("Configuring bridge was unsuccessful...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		mem_tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	kfree(amount_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (pfmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		ibmphp_remove_resource(pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		ibmphp_remove_resource(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	if (mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		ibmphp_remove_resource(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	for (i = 0; i < 2; i++) {	/* for 2 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		if (bus_io[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 			ibmphp_remove_resource(bus_io[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			func->io[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		} else if (bus_pfmem[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 			ibmphp_remove_resource(bus_pfmem[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			func->pfmem[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		} else if (bus_mem[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			ibmphp_remove_resource(bus_mem[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			func->mem[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	return retval;
^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) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)  * This function adds up the amount of resources needed behind the PPB bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)  * and passes it to the configure_bridge function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)  * Input: bridge function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)  * Output: amount of resources needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)  *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static struct res_needed *scan_behind_bridge(struct pci_func *func, u8 busno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	int count, len[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	u16 vendor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	u8 hdr_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	u8 device, function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	int howmany = 0;	/*this is to see if there are any devices behind the bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	u32 bar[6], class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	u32 address[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		PCI_BASE_ADDRESS_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		PCI_BASE_ADDRESS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		PCI_BASE_ADDRESS_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		PCI_BASE_ADDRESS_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		PCI_BASE_ADDRESS_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		PCI_BASE_ADDRESS_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	struct res_needed *amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	amount = kzalloc(sizeof(*amount), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	if (amount == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	ibmphp_pci_bus->number = busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	debug("the bus_no behind the bridge is %x\n", busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	debug("scanning devices behind the bridge...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	for (device = 0; device < 32; device++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		amount->devices[device] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		for (function = 0; function < 8; function++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			devfn = PCI_DEVFN(device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 				/* found correct device!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 				howmany++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 				pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 				pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 				debug("hdr_type behind the bridge is %x\n", hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 				if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 					err("embedded bridges not supported for hot-plugging.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 					amount->not_correct = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 					return amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 				class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 				if (class == PCI_CLASS_NOT_DEFINED_VGA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 					err("The device %x is VGA compatible and as is not supported for hot plugging.  Please choose another device.\n", device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 					amount->not_correct = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 					return amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 				} else if (class == PCI_CLASS_DISPLAY_VGA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 					err("The device %x is not supported for hot plugging.  Please choose another device.\n", device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 					amount->not_correct = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 					return amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 				amount->devices[device] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 				for (count = 0; address[count]; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 					/* for 6 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 					pci_bus_read_config_byte(ibmphp_pci_bus, devfn, address[count], &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 					if (tmp & 0x01) // IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 						pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 					else // MEMORY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 						pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 					*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 					pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 					pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 					debug("what is bar[count]? %x, count = %d\n", bar[count], count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 					if (!bar[count])	/* This BAR is not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 						continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 					//tmp_bar = bar[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 					debug("count %d device %x function %x wants %x resources\n", count, device, function, bar[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 					if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 						/* This is IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 						len[count] = bar[count] & 0xFFFFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 						len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 						amount->io += len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 					} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 						/* This is Memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 						if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 							/* pfmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 							len[count] = bar[count] & 0xFFFFFFF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 							len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 							amount->pfmem += len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 								/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 								count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 						} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 							/* regular memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 							len[count] = bar[count] & 0xFFFFFFF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 							len[count] = ~len[count] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 							amount->mem += len[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 								/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 								count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 							}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 				}	/* end for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 			}	/* end if (valid) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		}	/* end for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	}	/* end for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	if (!howmany)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		amount->not_correct = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 		amount->not_correct = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	if ((amount->io) && (amount->io < IOBRIDGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		amount->io = IOBRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	if ((amount->mem) && (amount->mem < MEMBRIDGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		amount->mem = MEMBRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	if ((amount->pfmem) && (amount->pfmem < MEMBRIDGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		amount->pfmem = MEMBRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	return amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* The following 3 unconfigure_boot_ routines deal with the case when we had the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)  * upon bootup in the system, since we don't allocate func to such case, we need to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)  * the start addresses from pci config space and then find the corresponding entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)  * our resource lists.  The functions return either 0, -ENODEV, or -1 (general failure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)  * Change: we also call these functions even if we configured the card ourselves (i.e., not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)  * the bootup case), since it should work same way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static int unconfigure_boot_device(u8 busno, u8 device, u8 function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	u32 start_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	u32 address[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		PCI_BASE_ADDRESS_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		PCI_BASE_ADDRESS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		PCI_BASE_ADDRESS_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		PCI_BASE_ADDRESS_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		PCI_BASE_ADDRESS_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		PCI_BASE_ADDRESS_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	struct resource_node *io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	struct resource_node *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	struct resource_node *pfmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	struct bus_node *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	u32 end_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	u32 temp_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	u32 tmp_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	debug("%s - enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	bus = ibmphp_find_res_bus(busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		debug("cannot find corresponding bus.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	devfn = PCI_DEVFN(device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	ibmphp_pci_bus->number = busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	for (count = 0; address[count]; count++) {	/* for 6 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &start_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		/* We can do this here, b/c by that time the device driver of the card has been stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], start_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		debug("start_address is %x\n", start_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		debug("busno, device, function %x %x %x\n", busno, device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		if (!size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			/* This BAR is not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			debug("is this bar no implemented?, count = %d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		tmp_address = start_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			/* This is IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			start_address &= PCI_BASE_ADDRESS_IO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			size = size & 0xFFFFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 			size = ~size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 			end_address = start_address + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			if (ibmphp_find_resource(bus, start_address, &io, IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 				goto report_search_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 			debug("io->start = %x\n", io->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 			temp_end = io->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 			start_address = io->end + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 			ibmphp_remove_resource(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 			/* This is needed b/c of the old I/O restrictions in the BIOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 			while (temp_end < end_address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 				if (ibmphp_find_resource(bus, start_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 							 &io, IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 					goto report_search_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 				debug("io->start = %x\n", io->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 				temp_end = io->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 				start_address = io->end + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 				ibmphp_remove_resource(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			/* This is Memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 				/* pfmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 				debug("start address of pfmem is %x\n", start_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 				if (ibmphp_find_resource(bus, start_address, &pfmem, PFMEM) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 					err("cannot find corresponding PFMEM resource to remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 					return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 				if (pfmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 					debug("pfmem->start = %x\n", pfmem->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 					ibmphp_remove_resource(pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 				/* regular memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 				debug("start address of mem is %x\n", start_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 				if (ibmphp_find_resource(bus, start_address, &mem, MEM) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 					err("cannot find corresponding MEM resource to remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 					return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 				if (mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 					debug("mem->start = %x\n", mem->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 					ibmphp_remove_resource(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 			if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 				/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 				count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		}	/* end of mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	}	/* end of for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) report_search_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	err("cannot find corresponding IO resource to remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) static int unconfigure_boot_bridge(u8 busno, u8 device, u8 function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	int bus_no, pri_no, sub_no, sec_no = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	u32 start_address, tmp_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	u8 sec_number, sub_number, pri_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	struct resource_node *io = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	struct resource_node *mem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	struct resource_node *pfmem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	struct bus_node *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	u32 address[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		PCI_BASE_ADDRESS_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		PCI_BASE_ADDRESS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	devfn = PCI_DEVFN(device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	ibmphp_pci_bus->number = busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	bus_no = (int) busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	debug("busno is %x\n", busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	debug("%s - busno = %x, primary_number = %x\n", __func__, busno, pri_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	debug("sec_number is %x\n", sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	sec_no = (int) sec_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	pri_no = (int) pri_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	if (pri_no != bus_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		err("primary numbers in our structures and pci config space don't match.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	sub_no = (int) sub_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	debug("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	if (sec_no != sub_number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		err("there're more buses behind this bridge.  Hot removal is not supported.  Please choose another card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	bus = ibmphp_find_res_bus(sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		err("cannot find Bus structure for the bridged device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	debug("bus->busno is %x\n", bus->busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	debug("sec_number is %x\n", sec_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	ibmphp_remove_bus(bus, busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	for (count = 0; address[count]; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		/* for 2 BARs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &start_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		if (!start_address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			/* This BAR is not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		tmp_address = start_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 			/* This is IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 			start_address &= PCI_BASE_ADDRESS_IO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 			if (ibmphp_find_resource(bus, start_address, &io, IO) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 				err("cannot find corresponding IO resource to remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 				return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 			if (io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 				debug("io->start = %x\n", io->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 			ibmphp_remove_resource(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 			/* This is Memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 				/* pfmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 				if (ibmphp_find_resource(bus, start_address, &pfmem, PFMEM) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 					err("cannot find corresponding PFMEM resource to remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 				if (pfmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 					debug("pfmem->start = %x\n", pfmem->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 					ibmphp_remove_resource(pfmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 				/* regular memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 				if (ibmphp_find_resource(bus, start_address, &mem, MEM) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 					err("cannot find corresponding MEM resource to remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 				if (mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 					debug("mem->start = %x\n", mem->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 					ibmphp_remove_resource(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 			if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 				/* takes up another dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 				count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		}	/* end of mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	}	/* end of for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	debug("%s - exiting, returning success\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static int unconfigure_boot_card(struct slot *slot_cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	u16 vendor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	u32 class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	u8 hdr_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	u8 device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	u8 busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	u8 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	debug("%s - enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	device = slot_cur->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	busno = slot_cur->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	debug("b4 for loop, device is %x\n", device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	/* For every function on the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	for (function = 0x0; function < 0x08; function++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		devfn = PCI_DEVFN(device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		ibmphp_pci_bus->number = busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 			/* found correct device!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 			++valid_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 			debug("%s - found correct device\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			/* header: x x x x x x x x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 			 *         |_=> 0 = single function device, 1 = multi-function device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 			pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 			pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 			debug("hdr_type %x, class %x\n", hdr_type, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 				err("The device %x function %x is VGA compatible and is not supported for hot removing.  Please choose another device.\n", device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 				return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 			} else if (class == PCI_CLASS_DISPLAY_VGA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 				err("The device %x function %x is not supported for hot removing.  Please choose another device.\n", device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 				return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 			switch (hdr_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 				case PCI_HEADER_TYPE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 					rc = unconfigure_boot_device(busno, device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 					if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 						err("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 						     device, function, busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 					function = 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 				case PCI_HEADER_TYPE_MULTIDEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 					rc = unconfigure_boot_device(busno, device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 					if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 						err("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 						     device, function, busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 				case PCI_HEADER_TYPE_BRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 					class >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 					if (class != PCI_CLASS_BRIDGE_PCI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 						err("This device %x function %x is not PCI-to-PCI bridge, and is not supported for hot-removing.  Please try another card.\n", device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 						return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 					rc = unconfigure_boot_bridge(busno, device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 					if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 						err("was not able to hot-remove PPB properly.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 					function = 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 				case PCI_HEADER_TYPE_MULTIBRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 					class >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 					if (class != PCI_CLASS_BRIDGE_PCI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 						err("This device %x function %x is not PCI-to-PCI bridge,  and is not supported for hot-removing.  Please try another card.\n", device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 						return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 					rc = unconfigure_boot_bridge(busno, device, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 					if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 						err("was not able to hot-remove PPB properly.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 					err("MAJOR PROBLEM!!!! Cannot read device's header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 					return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			}	/* end of switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		}	/* end of valid device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	}	/* end of for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	if (!valid_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		err("Could not find device to unconfigure.  Or could not read the card.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)  * free the resources of the card (multi, single, or bridged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)  * Parameters: slot, flag to say if this is for removing entire module or just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)  * unconfiguring the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)  * TO DO:  will probably need to add some code in case there was some resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)  * to remove it... this is from when we have errors in the configure_card...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)  *			!!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)  * Returns: 0, -1, -ENODEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) int ibmphp_unconfigure_card(struct slot **slot_cur, int the_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	struct slot *sl = *slot_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	struct pci_func *cur_func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	struct pci_func *temp_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	debug("%s - enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	if (!the_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		/* Need to unconfigure the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		rc = unconfigure_boot_card(sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 			/* In all other cases, will still need to get rid of func structure if it exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	if (sl->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		cur_func = sl->func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		while (cur_func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 			/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 			if (cur_func->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 				/* in other words, it's a PPB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 				count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 				count = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 			for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 				if (cur_func->io[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 					debug("io[%d] exists\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 					if (the_end > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 						ibmphp_remove_resource(cur_func->io[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 					cur_func->io[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 				if (cur_func->mem[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 					debug("mem[%d] exists\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 					if (the_end > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 						ibmphp_remove_resource(cur_func->mem[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 					cur_func->mem[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 				if (cur_func->pfmem[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 					debug("pfmem[%d] exists\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 					if (the_end > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 						ibmphp_remove_resource(cur_func->pfmem[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 					cur_func->pfmem[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 			temp_func = cur_func->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 			kfree(cur_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 			cur_func = temp_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	sl->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	*slot_cur = sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	debug("%s - exit\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)  * add a new bus resulting from hot-plugging a PPB bridge with devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)  * Input: bus and the amount of resources needed (we know we can assign those,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)  *        since they've been checked already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)  * Output: bus added to the correct spot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)  *         0, -1, error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	struct range_node *io_range = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	struct range_node *mem_range = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	struct range_node *pfmem_range = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	struct bus_node *cur_bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	/* Trying to find the parent bus number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	if (parent_busno != 0xFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 		cur_bus	= ibmphp_find_res_bus(parent_busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 		if (!cur_bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 			err("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 		list_add(&bus->bus_list, &cur_bus->bus_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	if (io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 		io_range = kzalloc(sizeof(*io_range), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		if (!io_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		io_range->start = io->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		io_range->end = io->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		io_range->rangeno = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		bus->noIORanges = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		bus->rangeIO = io_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	if (mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		if (!mem_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		mem_range->start = mem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		mem_range->end = mem->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		mem_range->rangeno = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		bus->noMemRanges = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 		bus->rangeMem = mem_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	if (pfmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		if (!pfmem_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		pfmem_range->start = pfmem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 		pfmem_range->end = pfmem->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		pfmem_range->rangeno = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		bus->noPFMemRanges = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 		bus->rangePFMem = pfmem_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)  * find the 1st available bus number for PPB to set as its secondary bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)  * Parameters: bus_number of the primary bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)  * Returns: bus_number of the secondary bus or 0xff in case of failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) static u8 find_sec_number(u8 primary_busno, u8 slotno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	int min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	u8 busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	struct bus_info *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	struct bus_node *bus_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	bus = ibmphp_find_same_bus_num(primary_busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	if (!bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		err("cannot get slot range of the bus from the BIOS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		return 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	max = bus->slot_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	min = bus->slot_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	if ((slotno > max) || (slotno < min)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		err("got the wrong range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		return 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	busno = (u8) (slotno - (u8) min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	busno += primary_busno + 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	bus_cur = ibmphp_find_res_bus(busno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	/* either there is no such bus number, or there are no ranges, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	 * can only happen if we removed the bridged device in previous load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	 * of the driver, and now only have the skeleton bus struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		return busno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	return 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }