2  * Linux driver attachment glue for PCI based U320 controllers.
 
   4  * Copyright (c) 2000-2001 Adaptec Inc.
 
   7  * Redistribution and use in source and binary forms, with or without
 
   8  * modification, are permitted provided that the following conditions
 
  10  * 1. Redistributions of source code must retain the above copyright
 
  11  *    notice, this list of conditions, and the following disclaimer,
 
  12  *    without modification.
 
  13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 
  14  *    substantially similar to the "NO WARRANTY" disclaimer below
 
  15  *    ("Disclaimer") and any redistribution must be conditioned upon
 
  16  *    including a substantially similar Disclaimer requirement for further
 
  17  *    binary redistribution.
 
  18  * 3. Neither the names of the above-listed copyright holders nor the names
 
  19  *    of any contributors may be used to endorse or promote products derived
 
  20  *    from this software without specific prior written permission.
 
  22  * Alternatively, this software may be distributed under the terms of the
 
  23  * GNU General Public License ("GPL") version 2 as published by the Free
 
  24  * Software Foundation.
 
  27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
  28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
  29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 
  30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
  31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
  32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
  33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
  34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
  35  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 
  36  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
  37  * POSSIBILITY OF SUCH DAMAGES.
 
  39  * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#25 $
 
  42 #include "aic79xx_osm.h"
 
  43 #include "aic79xx_inline.h"
 
  44 #include "aic79xx_pci.h"
 
  46 static int      ahd_linux_pci_dev_probe(struct pci_dev *pdev,
 
  47                                         const struct pci_device_id *ent);
 
  48 static int      ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
 
  49                                                  u_long *base, u_long *base2);
 
  50 static int      ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
 
  52                                                  uint8_t __iomem **maddr);
 
  53 static void     ahd_linux_pci_dev_remove(struct pci_dev *pdev);
 
  55 /* Define the macro locally since it's different for different class of chips.
 
  61 static struct pci_device_id ahd_linux_pci_id_table[] = {
 
  62         /* aic7901 based controllers */
 
  65         /* aic7902 based controllers */
 
  75         ID(ID_AHA_39320D_B_HP),
 
  76         /* Generic chip probes for devices we don't know exactly. */
 
  77         ID16(ID_AIC7901 & ID_9005_GENERIC_MASK),
 
  78         ID(ID_AIC7901A & ID_DEV_VENDOR_MASK),
 
  79         ID16(ID_AIC7902 & ID_9005_GENERIC_MASK),
 
  83 MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table);
 
  85 struct pci_driver aic79xx_pci_driver = {
 
  87         .probe          = ahd_linux_pci_dev_probe,
 
  88         .remove         = ahd_linux_pci_dev_remove,
 
  89         .id_table       = ahd_linux_pci_id_table
 
  93 ahd_linux_pci_dev_remove(struct pci_dev *pdev)
 
  95         struct ahd_softc *ahd = pci_get_drvdata(pdev);
 
  98         if (ahd->platform_data && ahd->platform_data->host)
 
  99                         scsi_remove_host(ahd->platform_data->host);
 
 102         ahd_intr_enable(ahd, FALSE);
 
 108 ahd_linux_pci_inherit_flags(struct ahd_softc *ahd)
 
 110         struct pci_dev *pdev = ahd->dev_softc, *master_pdev;
 
 111         unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
 
 113         master_pdev = pci_get_slot(pdev->bus, master_devfn);
 
 115                 struct ahd_softc *master = pci_get_drvdata(master_pdev);
 
 117                         ahd->flags &= ~AHD_BIOS_ENABLED;
 
 118                         ahd->flags |= master->flags & AHD_BIOS_ENABLED;
 
 120                         printk(KERN_ERR "aic79xx: no multichannel peer found!\n");
 
 121                 pci_dev_put(master_pdev);
 
 126 ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 129         struct           ahd_softc *ahd;
 
 131         struct           ahd_pci_identity *entry;
 
 136         entry = ahd_find_pci_device(pci);
 
 141          * Allocate a softc for this card and
 
 142          * set it up for attachment by our
 
 143          * common detect routine.
 
 145         sprintf(buf, "ahd_pci:%d:%d:%d",
 
 146                 ahd_get_pci_bus(pci),
 
 147                 ahd_get_pci_slot(pci),
 
 148                 ahd_get_pci_function(pci));
 
 149         name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
 
 153         ahd = ahd_alloc(NULL, name);
 
 156         if (pci_enable_device(pdev)) {
 
 160         pci_set_master(pdev);
 
 162         if (sizeof(dma_addr_t) > 4) {
 
 164                 const uint64_t mask_39bit = 0x7FFFFFFFFFULL;
 
 166                 memsize = ahd_linux_get_memsize();
 
 168                 if (memsize >= 0x8000000000ULL
 
 169                  && pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
 
 170                         ahd->flags |= AHD_64BIT_ADDRESSING;
 
 171                 } else if (memsize > 0x80000000
 
 172                         && pci_set_dma_mask(pdev, mask_39bit) == 0) {
 
 173                         ahd->flags |= AHD_39BIT_ADDRESSING;
 
 176                 pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 
 178         ahd->dev_softc = pci;
 
 179         error = ahd_pci_config(ahd, entry);
 
 186          * Second Function PCI devices need to inherit some
 
 187          * * settings from function 0.
 
 189         if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0)
 
 190                 ahd_linux_pci_inherit_flags(ahd);
 
 192         pci_set_drvdata(pdev, ahd);
 
 194         ahd_linux_register_host(ahd, &aic79xx_driver_template);
 
 199 ahd_linux_pci_init(void)
 
 201         return (pci_module_init(&aic79xx_pci_driver));
 
 205 ahd_linux_pci_exit(void)
 
 207         pci_unregister_driver(&aic79xx_pci_driver);
 
 211 ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
 
 214         *base = pci_resource_start(ahd->dev_softc, 0);
 
 216          * This is really the 3rd bar and should be at index 2,
 
 217          * but the Linux PCI code doesn't know how to "count" 64bit
 
 220         *base2 = pci_resource_start(ahd->dev_softc, 3);
 
 221         if (*base == 0 || *base2 == 0)
 
 223         if (!request_region(*base, 256, "aic79xx"))
 
 225         if (!request_region(*base2, 256, "aic79xx")) {
 
 226                 release_region(*base, 256);
 
 233 ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
 
 235                                  uint8_t __iomem **maddr)
 
 242         if (aic79xx_allow_memio == 0)
 
 245         if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0)
 
 248         start = pci_resource_start(ahd->dev_softc, 1);
 
 249         base_page = start & PAGE_MASK;
 
 250         base_offset = start - base_page;
 
 253                 if (!request_mem_region(start, 0x1000, "aic79xx"))
 
 256                         *maddr = ioremap_nocache(base_page, base_offset + 512);
 
 257                         if (*maddr == NULL) {
 
 259                                 release_mem_region(start, 0x1000);
 
 261                                 *maddr += base_offset;
 
 269 ahd_pci_map_registers(struct ahd_softc *ahd)
 
 273         uint8_t __iomem *maddr;
 
 277          * If its allowed, we prefer memory mapped access.
 
 279         command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4);
 
 280         command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
 
 283         error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr);
 
 285                 ahd->platform_data->mem_busaddr = base;
 
 286                 ahd->tags[0] = BUS_SPACE_MEMIO;
 
 287                 ahd->bshs[0].maddr = maddr;
 
 288                 ahd->tags[1] = BUS_SPACE_MEMIO;
 
 289                 ahd->bshs[1].maddr = maddr + 0x100;
 
 290                 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
 
 291                                      command | PCIM_CMD_MEMEN, 4);
 
 293                 if (ahd_pci_test_register_access(ahd) != 0) {
 
 295                         printf("aic79xx: PCI Device %d:%d:%d "
 
 296                                "failed memory mapped test.  Using PIO.\n",
 
 297                                ahd_get_pci_bus(ahd->dev_softc),
 
 298                                ahd_get_pci_slot(ahd->dev_softc),
 
 299                                ahd_get_pci_function(ahd->dev_softc));
 
 301                         release_mem_region(ahd->platform_data->mem_busaddr,
 
 303                         ahd->bshs[0].maddr = NULL;
 
 306                         command |= PCIM_CMD_MEMEN;
 
 307         } else if (bootverbose) {
 
 308                 printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx "
 
 309                        "unavailable. Cannot memory map device.\n",
 
 310                        ahd_get_pci_bus(ahd->dev_softc),
 
 311                        ahd_get_pci_slot(ahd->dev_softc),
 
 312                        ahd_get_pci_function(ahd->dev_softc),
 
 319                 error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2);
 
 321                         ahd->tags[0] = BUS_SPACE_PIO;
 
 322                         ahd->tags[1] = BUS_SPACE_PIO;
 
 323                         ahd->bshs[0].ioport = base;
 
 324                         ahd->bshs[1].ioport = base2;
 
 325                         command |= PCIM_CMD_PORTEN;
 
 327                         printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx"
 
 328                                "unavailable. Cannot map device.\n",
 
 329                                ahd_get_pci_bus(ahd->dev_softc),
 
 330                                ahd_get_pci_slot(ahd->dev_softc),
 
 331                                ahd_get_pci_function(ahd->dev_softc),
 
 335         ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4);
 
 340 ahd_pci_map_int(struct ahd_softc *ahd)
 
 344         error = request_irq(ahd->dev_softc->irq, ahd_linux_isr,
 
 345                             SA_SHIRQ, "aic79xx", ahd);
 
 347                 ahd->platform_data->irq = ahd->dev_softc->irq;
 
 353 ahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state)
 
 355         pci_set_power_state(ahd->dev_softc, new_state);