diff options
Diffstat (limited to 'arch/s390/pci/pci.c')
| -rw-r--r-- | arch/s390/pci/pci.c | 153 | 
1 files changed, 61 insertions, 92 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 27b4c17855b..e6f15b5d8b7 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -99,9 +99,6 @@ static int __read_mostly aisb_max;  static struct kmem_cache *zdev_irq_cache;  static struct kmem_cache *zdev_fmb_cache; -debug_info_t *pci_debug_msg_id; -debug_info_t *pci_debug_err_id; -  static inline int irq_to_msi_nr(unsigned int irq)  {  	return irq & ZPCI_MSI_MASK; @@ -179,7 +176,7 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb,  	fib->aisb = (u64) bucket->aisb + aisb / 8;  	fib->aisbo = aisb & ZPCI_MSI_MASK; -	rc = mpcifc_instr(req, fib); +	rc = s390pci_mod_fc(req, fib);  	pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi);  	free_page((unsigned long) fib); @@ -209,7 +206,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args  	fib->iota = args->iota;  	fib->fmb_addr = args->fmb_addr; -	rc = mpcifc_instr(req, fib); +	rc = s390pci_mod_fc(req, fib);  	free_page((unsigned long) fib);  	return rc;  } @@ -249,10 +246,9 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)  	if (zdev->fmb)  		return -EINVAL; -	zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL); +	zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL);  	if (!zdev->fmb)  		return -ENOMEM; -	memset(zdev->fmb, 0, sizeof(*zdev->fmb));  	WARN_ON((u64) zdev->fmb & 0xf);  	args.fmb_addr = virt_to_phys(zdev->fmb); @@ -284,12 +280,12 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)  	u64 data;  	int rc; -	rc = pcilg_instr(&data, req, offset); -	data = data << ((8 - len) * 8); -	data = le64_to_cpu(data); -	if (!rc) +	rc = s390pci_load(&data, req, offset); +	if (!rc) { +		data = data << ((8 - len) * 8); +		data = le64_to_cpu(data);  		*val = (u32) data; -	else +	} else  		*val = 0xffffffff;  	return rc;  } @@ -302,7 +298,7 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)  	data = cpu_to_le64(data);  	data = data >> ((8 - len) * 8); -	rc = pcistg_instr(data, req, offset); +	rc = s390pci_store(data, req, offset);  	return rc;  } @@ -409,20 +405,28 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,  		    int size, u32 *val)  {  	struct zpci_dev *zdev = get_zdev_by_bus(bus); +	int ret;  	if (!zdev || devfn != ZPCI_DEVFN) -		return 0; -	return zpci_cfg_load(zdev, where, val, size); +		ret = -ENODEV; +	else +		ret = zpci_cfg_load(zdev, where, val, size); + +	return ret;  }  static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,  		     int size, u32 val)  {  	struct zpci_dev *zdev = get_zdev_by_bus(bus); +	int ret;  	if (!zdev || devfn != ZPCI_DEVFN) -		return 0; -	return zpci_cfg_store(zdev, where, val, size); +		ret = -ENODEV; +	else +		ret = zpci_cfg_store(zdev, where, val, size); + +	return ret;  }  static struct pci_ops pci_root_ops = { @@ -474,7 +478,7 @@ scan:  	}  	/* enable interrupts again */ -	sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); +	set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);  	/* check again to not lose initiative */  	rmb(); @@ -596,19 +600,6 @@ static void zpci_map_resources(struct zpci_dev *zdev)  	}  }; -static void zpci_unmap_resources(struct pci_dev *pdev) -{ -	resource_size_t len; -	int i; - -	for (i = 0; i < PCI_BAR_COUNT; i++) { -		len = pci_resource_len(pdev, i); -		if (!len) -			continue; -		pci_iounmap(pdev, (void *) pdev->resource[i].start); -	} -}; -  struct zpci_dev *zpci_alloc_device(void)  {  	struct zpci_dev *zdev; @@ -636,32 +627,6 @@ void zpci_free_device(struct zpci_dev *zdev)  	kfree(zdev);  } -/* Called on removal of pci_dev, leaves zpci and bus device */ -static void zpci_remove_device(struct pci_dev *pdev) -{ -	struct zpci_dev *zdev = get_zdev(pdev); - -	dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); -	zdev->state = ZPCI_FN_STATE_CONFIGURED; -	zpci_dma_exit_device(zdev); -	zpci_fmb_disable_device(zdev); -	zpci_sysfs_remove_device(&pdev->dev); -	zpci_unmap_resources(pdev); -	list_del(&zdev->entry);		/* can be called from init */ -	zdev->pdev = NULL; -} - -static void zpci_scan_devices(void) -{ -	struct zpci_dev *zdev; - -	mutex_lock(&zpci_list_lock); -	list_for_each_entry(zdev, &zpci_list, entry) -		if (zdev->state == ZPCI_FN_STATE_CONFIGURED) -			zpci_scan_device(zdev); -	mutex_unlock(&zpci_list_lock); -} -  /*   * Too late for any s390 specific setup, since interrupts must be set up   * already which requires DMA setup too and the pci scan will access the @@ -688,12 +653,6 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask)  	return 0;  } -void pcibios_disable_device(struct pci_dev *pdev) -{ -	zpci_remove_device(pdev); -	pdev->sysdata = NULL; -} -  int pcibios_add_platform_entries(struct pci_dev *pdev)  {  	return zpci_sysfs_add_device(&pdev->dev); @@ -789,7 +748,7 @@ static int __init zpci_irq_init(void)  	spin_lock_init(&bucket->lock);  	/* set summary to 1 to be called every time for the ISC */  	*zpci_irq_si = 1; -	sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); +	set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);  	return 0;  out_ai: @@ -872,7 +831,19 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry)  	spin_unlock(&zpci_iomap_lock);  } -static int zpci_create_device_bus(struct zpci_dev *zdev) +int pcibios_add_device(struct pci_dev *pdev) +{ +	struct zpci_dev *zdev = get_zdev(pdev); + +	zdev->pdev = pdev; +	zpci_debug_init_device(zdev); +	zpci_fmb_enable_device(zdev); +	zpci_map_resources(zdev); + +	return 0; +} + +static int zpci_scan_bus(struct zpci_dev *zdev)  {  	struct resource *res;  	LIST_HEAD(resources); @@ -909,8 +880,8 @@ static int zpci_create_device_bus(struct zpci_dev *zdev)  		pci_add_resource(&resources, res);  	} -	zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, -					zdev, &resources); +	zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, +				      zdev, &resources);  	if (!zdev->bus)  		return -EIO; @@ -959,6 +930,13 @@ out:  }  EXPORT_SYMBOL_GPL(zpci_enable_device); +int zpci_disable_device(struct zpci_dev *zdev) +{ +	zpci_dma_exit_device(zdev); +	return clp_disable_fh(zdev); +} +EXPORT_SYMBOL_GPL(zpci_disable_device); +  int zpci_create_device(struct zpci_dev *zdev)  {  	int rc; @@ -967,9 +945,16 @@ int zpci_create_device(struct zpci_dev *zdev)  	if (rc)  		goto out; -	rc = zpci_create_device_bus(zdev); +	if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { +		rc = zpci_enable_device(zdev); +		if (rc) +			goto out_free; + +		zdev->state = ZPCI_FN_STATE_ONLINE; +	} +	rc = zpci_scan_bus(zdev);  	if (rc) -		goto out_bus; +		goto out_disable;  	mutex_lock(&zpci_list_lock);  	list_add_tail(&zdev->entry, &zpci_list); @@ -977,21 +962,12 @@ int zpci_create_device(struct zpci_dev *zdev)  		hotplug_ops->create_slot(zdev);  	mutex_unlock(&zpci_list_lock); -	if (zdev->state == ZPCI_FN_STATE_STANDBY) -		return 0; - -	rc = zpci_enable_device(zdev); -	if (rc) -		goto out_start;  	return 0; -out_start: -	mutex_lock(&zpci_list_lock); -	list_del(&zdev->entry); -	if (hotplug_ops) -		hotplug_ops->remove_slot(zdev); -	mutex_unlock(&zpci_list_lock); -out_bus: +out_disable: +	if (zdev->state == ZPCI_FN_STATE_ONLINE) +		zpci_disable_device(zdev); +out_free:  	zpci_free_domain(zdev);  out:  	return rc; @@ -1016,15 +992,9 @@ int zpci_scan_device(struct zpci_dev *zdev)  		goto out;  	} -	zpci_debug_init_device(zdev); -	zpci_fmb_enable_device(zdev); -	zpci_map_resources(zdev);  	pci_bus_add_devices(zdev->bus); -	/* now that pdev was added to the bus mark it as used */ -	zdev->state = ZPCI_FN_STATE_ONLINE;  	return 0; -  out:  	zpci_dma_exit_device(zdev);  	clp_disable_fh(zdev); @@ -1087,13 +1057,13 @@ void zpci_deregister_hp_ops(void)  }  EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); -unsigned int s390_pci_probe = 1; +unsigned int s390_pci_probe;  EXPORT_SYMBOL_GPL(s390_pci_probe);  char * __init pcibios_setup(char *str)  { -	if (!strcmp(str, "off")) { -		s390_pci_probe = 0; +	if (!strcmp(str, "on")) { +		s390_pci_probe = 1;  		return NULL;  	}  	return str; @@ -1138,7 +1108,6 @@ static int __init pci_base_init(void)  	if (rc)  		goto out_find; -	zpci_scan_devices();  	return 0;  out_find:  |