162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Linux driver attachment glue for PCI based U320 controllers. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2000-2001 Adaptec Inc. 562306a36Sopenharmony_ci * All rights reserved. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 862306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 962306a36Sopenharmony_ci * are met: 1062306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 1162306a36Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 1262306a36Sopenharmony_ci * without modification. 1362306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1462306a36Sopenharmony_ci * substantially similar to the "NO WARRANTY" disclaimer below 1562306a36Sopenharmony_ci * ("Disclaimer") and any redistribution must be conditioned upon 1662306a36Sopenharmony_ci * including a substantially similar Disclaimer requirement for further 1762306a36Sopenharmony_ci * binary redistribution. 1862306a36Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names 1962306a36Sopenharmony_ci * of any contributors may be used to endorse or promote products derived 2062306a36Sopenharmony_ci * from this software without specific prior written permission. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 2362306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 2462306a36Sopenharmony_ci * Software Foundation. 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * NO WARRANTY 2762306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2862306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2962306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3062306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3162306a36Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3262306a36Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3362306a36Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3462306a36Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3562306a36Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3662306a36Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3762306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES. 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#25 $ 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#include "aic79xx_osm.h" 4362306a36Sopenharmony_ci#include "aic79xx_inline.h" 4462306a36Sopenharmony_ci#include "aic79xx_pci.h" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* Define the macro locally since it's different for different class of chips. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci#define ID(x) \ 4962306a36Sopenharmony_ci ID2C(x), \ 5062306a36Sopenharmony_ci ID2C(IDIROC(x)) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic const struct pci_device_id ahd_linux_pci_id_table[] = { 5362306a36Sopenharmony_ci /* aic7901 based controllers */ 5462306a36Sopenharmony_ci ID(ID_AHA_29320A), 5562306a36Sopenharmony_ci ID(ID_AHA_29320ALP), 5662306a36Sopenharmony_ci ID(ID_AHA_29320LPE), 5762306a36Sopenharmony_ci /* aic7902 based controllers */ 5862306a36Sopenharmony_ci ID(ID_AHA_29320), 5962306a36Sopenharmony_ci ID(ID_AHA_29320B), 6062306a36Sopenharmony_ci ID(ID_AHA_29320LP), 6162306a36Sopenharmony_ci ID(ID_AHA_39320), 6262306a36Sopenharmony_ci ID(ID_AHA_39320_B), 6362306a36Sopenharmony_ci ID(ID_AHA_39320A), 6462306a36Sopenharmony_ci ID(ID_AHA_39320D), 6562306a36Sopenharmony_ci ID(ID_AHA_39320D_HP), 6662306a36Sopenharmony_ci ID(ID_AHA_39320D_B), 6762306a36Sopenharmony_ci ID(ID_AHA_39320D_B_HP), 6862306a36Sopenharmony_ci /* Generic chip probes for devices we don't know exactly. */ 6962306a36Sopenharmony_ci ID16(ID_AIC7901 & ID_9005_GENERIC_MASK), 7062306a36Sopenharmony_ci ID(ID_AIC7901A & ID_DEV_VENDOR_MASK), 7162306a36Sopenharmony_ci ID16(ID_AIC7902 & ID_9005_GENERIC_MASK), 7262306a36Sopenharmony_ci { 0 } 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic int __maybe_unused 7862306a36Sopenharmony_ciahd_linux_pci_dev_suspend(struct device *dev) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci struct ahd_softc *ahd = dev_get_drvdata(dev); 8162306a36Sopenharmony_ci int rc; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci if ((rc = ahd_suspend(ahd))) 8462306a36Sopenharmony_ci return rc; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci ahd_pci_suspend(ahd); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci return rc; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic int __maybe_unused 9262306a36Sopenharmony_ciahd_linux_pci_dev_resume(struct device *dev) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci struct ahd_softc *ahd = dev_get_drvdata(dev); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci ahd_pci_resume(ahd); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci ahd_resume(ahd); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci return 0; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistatic void 10462306a36Sopenharmony_ciahd_linux_pci_dev_remove(struct pci_dev *pdev) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci struct ahd_softc *ahd = pci_get_drvdata(pdev); 10762306a36Sopenharmony_ci u_long s; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci if (ahd->platform_data && ahd->platform_data->host) 11062306a36Sopenharmony_ci scsi_remove_host(ahd->platform_data->host); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci ahd_lock(ahd, &s); 11362306a36Sopenharmony_ci ahd_intr_enable(ahd, FALSE); 11462306a36Sopenharmony_ci ahd_unlock(ahd, &s); 11562306a36Sopenharmony_ci ahd_free(ahd); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic void 11962306a36Sopenharmony_ciahd_linux_pci_inherit_flags(struct ahd_softc *ahd) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci struct pci_dev *pdev = ahd->dev_softc, *master_pdev; 12262306a36Sopenharmony_ci unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci master_pdev = pci_get_slot(pdev->bus, master_devfn); 12562306a36Sopenharmony_ci if (master_pdev) { 12662306a36Sopenharmony_ci struct ahd_softc *master = pci_get_drvdata(master_pdev); 12762306a36Sopenharmony_ci if (master) { 12862306a36Sopenharmony_ci ahd->flags &= ~AHD_BIOS_ENABLED; 12962306a36Sopenharmony_ci ahd->flags |= master->flags & AHD_BIOS_ENABLED; 13062306a36Sopenharmony_ci } else 13162306a36Sopenharmony_ci printk(KERN_ERR "aic79xx: no multichannel peer found!\n"); 13262306a36Sopenharmony_ci pci_dev_put(master_pdev); 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic int 13762306a36Sopenharmony_ciahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci char buf[80]; 14062306a36Sopenharmony_ci struct ahd_softc *ahd; 14162306a36Sopenharmony_ci ahd_dev_softc_t pci; 14262306a36Sopenharmony_ci const struct ahd_pci_identity *entry; 14362306a36Sopenharmony_ci char *name; 14462306a36Sopenharmony_ci int error; 14562306a36Sopenharmony_ci struct device *dev = &pdev->dev; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci pci = pdev; 14862306a36Sopenharmony_ci entry = ahd_find_pci_device(pci); 14962306a36Sopenharmony_ci if (entry == NULL) 15062306a36Sopenharmony_ci return (-ENODEV); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci /* 15362306a36Sopenharmony_ci * Allocate a softc for this card and 15462306a36Sopenharmony_ci * set it up for attachment by our 15562306a36Sopenharmony_ci * common detect routine. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_ci sprintf(buf, "ahd_pci:%d:%d:%d", 15862306a36Sopenharmony_ci ahd_get_pci_bus(pci), 15962306a36Sopenharmony_ci ahd_get_pci_slot(pci), 16062306a36Sopenharmony_ci ahd_get_pci_function(pci)); 16162306a36Sopenharmony_ci name = kstrdup(buf, GFP_ATOMIC); 16262306a36Sopenharmony_ci if (name == NULL) 16362306a36Sopenharmony_ci return (-ENOMEM); 16462306a36Sopenharmony_ci ahd = ahd_alloc(NULL, name); 16562306a36Sopenharmony_ci if (ahd == NULL) 16662306a36Sopenharmony_ci return (-ENOMEM); 16762306a36Sopenharmony_ci if (pci_enable_device(pdev)) { 16862306a36Sopenharmony_ci ahd_free(ahd); 16962306a36Sopenharmony_ci return (-ENODEV); 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci pci_set_master(pdev); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci if (sizeof(dma_addr_t) > 4) { 17462306a36Sopenharmony_ci const u64 required_mask = dma_get_required_mask(dev); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci if (required_mask > DMA_BIT_MASK(39) && 17762306a36Sopenharmony_ci dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) 17862306a36Sopenharmony_ci ahd->flags |= AHD_64BIT_ADDRESSING; 17962306a36Sopenharmony_ci else if (required_mask > DMA_BIT_MASK(32) && 18062306a36Sopenharmony_ci dma_set_mask(dev, DMA_BIT_MASK(39)) == 0) 18162306a36Sopenharmony_ci ahd->flags |= AHD_39BIT_ADDRESSING; 18262306a36Sopenharmony_ci else 18362306a36Sopenharmony_ci dma_set_mask(dev, DMA_BIT_MASK(32)); 18462306a36Sopenharmony_ci } else { 18562306a36Sopenharmony_ci dma_set_mask(dev, DMA_BIT_MASK(32)); 18662306a36Sopenharmony_ci } 18762306a36Sopenharmony_ci ahd->dev_softc = pci; 18862306a36Sopenharmony_ci error = ahd_pci_config(ahd, entry); 18962306a36Sopenharmony_ci if (error != 0) { 19062306a36Sopenharmony_ci ahd_free(ahd); 19162306a36Sopenharmony_ci return (-error); 19262306a36Sopenharmony_ci } 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci /* 19562306a36Sopenharmony_ci * Second Function PCI devices need to inherit some 19662306a36Sopenharmony_ci * * settings from function 0. 19762306a36Sopenharmony_ci */ 19862306a36Sopenharmony_ci if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0) 19962306a36Sopenharmony_ci ahd_linux_pci_inherit_flags(ahd); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci pci_set_drvdata(pdev, ahd); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci ahd_linux_register_host(ahd, &aic79xx_driver_template); 20462306a36Sopenharmony_ci return (0); 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(ahd_linux_pci_dev_pm_ops, 20862306a36Sopenharmony_ci ahd_linux_pci_dev_suspend, 20962306a36Sopenharmony_ci ahd_linux_pci_dev_resume); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic struct pci_driver aic79xx_pci_driver = { 21262306a36Sopenharmony_ci .name = "aic79xx", 21362306a36Sopenharmony_ci .probe = ahd_linux_pci_dev_probe, 21462306a36Sopenharmony_ci .driver.pm = &ahd_linux_pci_dev_pm_ops, 21562306a36Sopenharmony_ci .remove = ahd_linux_pci_dev_remove, 21662306a36Sopenharmony_ci .id_table = ahd_linux_pci_id_table 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ciint 22062306a36Sopenharmony_ciahd_linux_pci_init(void) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci return pci_register_driver(&aic79xx_pci_driver); 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_civoid 22662306a36Sopenharmony_ciahd_linux_pci_exit(void) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci pci_unregister_driver(&aic79xx_pci_driver); 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic int 23262306a36Sopenharmony_ciahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, resource_size_t *base, 23362306a36Sopenharmony_ci resource_size_t *base2) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci *base = pci_resource_start(ahd->dev_softc, 0); 23662306a36Sopenharmony_ci /* 23762306a36Sopenharmony_ci * This is really the 3rd bar and should be at index 2, 23862306a36Sopenharmony_ci * but the Linux PCI code doesn't know how to "count" 64bit 23962306a36Sopenharmony_ci * bars. 24062306a36Sopenharmony_ci */ 24162306a36Sopenharmony_ci *base2 = pci_resource_start(ahd->dev_softc, 3); 24262306a36Sopenharmony_ci if (*base == 0 || *base2 == 0) 24362306a36Sopenharmony_ci return (ENOMEM); 24462306a36Sopenharmony_ci if (!request_region(*base, 256, "aic79xx")) 24562306a36Sopenharmony_ci return (ENOMEM); 24662306a36Sopenharmony_ci if (!request_region(*base2, 256, "aic79xx")) { 24762306a36Sopenharmony_ci release_region(*base, 256); 24862306a36Sopenharmony_ci return (ENOMEM); 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci return (0); 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic int 25462306a36Sopenharmony_ciahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, 25562306a36Sopenharmony_ci resource_size_t *bus_addr, 25662306a36Sopenharmony_ci uint8_t __iomem **maddr) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci resource_size_t start; 25962306a36Sopenharmony_ci resource_size_t base_page; 26062306a36Sopenharmony_ci u_long base_offset; 26162306a36Sopenharmony_ci int error = 0; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (aic79xx_allow_memio == 0) 26462306a36Sopenharmony_ci return (ENOMEM); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0) 26762306a36Sopenharmony_ci return (ENOMEM); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci start = pci_resource_start(ahd->dev_softc, 1); 27062306a36Sopenharmony_ci base_page = start & PAGE_MASK; 27162306a36Sopenharmony_ci base_offset = start - base_page; 27262306a36Sopenharmony_ci if (start != 0) { 27362306a36Sopenharmony_ci *bus_addr = start; 27462306a36Sopenharmony_ci if (!request_mem_region(start, 0x1000, "aic79xx")) 27562306a36Sopenharmony_ci error = ENOMEM; 27662306a36Sopenharmony_ci if (!error) { 27762306a36Sopenharmony_ci *maddr = ioremap(base_page, base_offset + 512); 27862306a36Sopenharmony_ci if (*maddr == NULL) { 27962306a36Sopenharmony_ci error = ENOMEM; 28062306a36Sopenharmony_ci release_mem_region(start, 0x1000); 28162306a36Sopenharmony_ci } else 28262306a36Sopenharmony_ci *maddr += base_offset; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci } else 28562306a36Sopenharmony_ci error = ENOMEM; 28662306a36Sopenharmony_ci return (error); 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ciint 29062306a36Sopenharmony_ciahd_pci_map_registers(struct ahd_softc *ahd) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci uint32_t command; 29362306a36Sopenharmony_ci resource_size_t base; 29462306a36Sopenharmony_ci uint8_t __iomem *maddr; 29562306a36Sopenharmony_ci int error; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* 29862306a36Sopenharmony_ci * If its allowed, we prefer memory mapped access. 29962306a36Sopenharmony_ci */ 30062306a36Sopenharmony_ci command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4); 30162306a36Sopenharmony_ci command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); 30262306a36Sopenharmony_ci base = 0; 30362306a36Sopenharmony_ci maddr = NULL; 30462306a36Sopenharmony_ci error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr); 30562306a36Sopenharmony_ci if (error == 0) { 30662306a36Sopenharmony_ci ahd->platform_data->mem_busaddr = base; 30762306a36Sopenharmony_ci ahd->tags[0] = BUS_SPACE_MEMIO; 30862306a36Sopenharmony_ci ahd->bshs[0].maddr = maddr; 30962306a36Sopenharmony_ci ahd->tags[1] = BUS_SPACE_MEMIO; 31062306a36Sopenharmony_ci ahd->bshs[1].maddr = maddr + 0x100; 31162306a36Sopenharmony_ci ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, 31262306a36Sopenharmony_ci command | PCIM_CMD_MEMEN, 4); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (ahd_pci_test_register_access(ahd) != 0) { 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci printk("aic79xx: PCI Device %d:%d:%d " 31762306a36Sopenharmony_ci "failed memory mapped test. Using PIO.\n", 31862306a36Sopenharmony_ci ahd_get_pci_bus(ahd->dev_softc), 31962306a36Sopenharmony_ci ahd_get_pci_slot(ahd->dev_softc), 32062306a36Sopenharmony_ci ahd_get_pci_function(ahd->dev_softc)); 32162306a36Sopenharmony_ci iounmap(maddr); 32262306a36Sopenharmony_ci release_mem_region(ahd->platform_data->mem_busaddr, 32362306a36Sopenharmony_ci 0x1000); 32462306a36Sopenharmony_ci ahd->bshs[0].maddr = NULL; 32562306a36Sopenharmony_ci maddr = NULL; 32662306a36Sopenharmony_ci } else 32762306a36Sopenharmony_ci command |= PCIM_CMD_MEMEN; 32862306a36Sopenharmony_ci } else if (bootverbose) { 32962306a36Sopenharmony_ci printk("aic79xx: PCI%d:%d:%d MEM region 0x%llx " 33062306a36Sopenharmony_ci "unavailable. Cannot memory map device.\n", 33162306a36Sopenharmony_ci ahd_get_pci_bus(ahd->dev_softc), 33262306a36Sopenharmony_ci ahd_get_pci_slot(ahd->dev_softc), 33362306a36Sopenharmony_ci ahd_get_pci_function(ahd->dev_softc), 33462306a36Sopenharmony_ci (unsigned long long)base); 33562306a36Sopenharmony_ci } 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci if (maddr == NULL) { 33862306a36Sopenharmony_ci resource_size_t base2; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2); 34162306a36Sopenharmony_ci if (error == 0) { 34262306a36Sopenharmony_ci ahd->tags[0] = BUS_SPACE_PIO; 34362306a36Sopenharmony_ci ahd->tags[1] = BUS_SPACE_PIO; 34462306a36Sopenharmony_ci ahd->bshs[0].ioport = (u_long)base; 34562306a36Sopenharmony_ci ahd->bshs[1].ioport = (u_long)base2; 34662306a36Sopenharmony_ci command |= PCIM_CMD_PORTEN; 34762306a36Sopenharmony_ci } else { 34862306a36Sopenharmony_ci printk("aic79xx: PCI%d:%d:%d IO regions 0x%llx and " 34962306a36Sopenharmony_ci "0x%llx unavailable. Cannot map device.\n", 35062306a36Sopenharmony_ci ahd_get_pci_bus(ahd->dev_softc), 35162306a36Sopenharmony_ci ahd_get_pci_slot(ahd->dev_softc), 35262306a36Sopenharmony_ci ahd_get_pci_function(ahd->dev_softc), 35362306a36Sopenharmony_ci (unsigned long long)base, 35462306a36Sopenharmony_ci (unsigned long long)base2); 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci } 35762306a36Sopenharmony_ci ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); 35862306a36Sopenharmony_ci return (error); 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ciint 36262306a36Sopenharmony_ciahd_pci_map_int(struct ahd_softc *ahd) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci int error; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci error = request_irq(ahd->dev_softc->irq, ahd_linux_isr, 36762306a36Sopenharmony_ci IRQF_SHARED, "aic79xx", ahd); 36862306a36Sopenharmony_ci if (!error) 36962306a36Sopenharmony_ci ahd->platform_data->irq = ahd->dev_softc->irq; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci return (-error); 37262306a36Sopenharmony_ci} 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_civoid 37562306a36Sopenharmony_ciahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci pci_set_power_state(ahd->dev_softc, new_state); 37862306a36Sopenharmony_ci} 379