static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { char buf[80]; struct ahd_softc *ahd; ahd_dev_softc_t pci; struct ahd_pci_identity *entry; char *name; int error; pci = pdev; entry = ahd_find_pci_device(pci); if (entry == NULL) return (-ENODEV); /* * Allocate a softc for this card and * set it up for attachment by our * common detect routine. */ sprintf(buf, "ahd_pci:%d:%d:%d", ahd_get_pci_bus(pci), ahd_get_pci_slot(pci), ahd_get_pci_function(pci)); name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); if (name == NULL) return (-ENOMEM); strcpy(name, buf); ahd = ahd_alloc(NULL, name); if (ahd == NULL) return (-ENOMEM); if (pci_enable_device(pdev)) { ahd_free(ahd); return (-ENODEV); } pci_set_master(pdev); if (sizeof(dma_addr_t) > 4) { uint64_t memsize; const uint64_t mask_39bit = 0x7FFFFFFFFFULL; memsize = ahd_linux_get_memsize(); if (memsize >= 0x8000000000ULL && pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { ahd->flags |= AHD_64BIT_ADDRESSING; } else if (memsize > 0x80000000 && pci_set_dma_mask(pdev, mask_39bit) == 0) { ahd->flags |= AHD_39BIT_ADDRESSING; } } else { pci_set_dma_mask(pdev, DMA_32BIT_MASK); } ahd->dev_softc = pci; error = ahd_pci_config(ahd, entry); if (error != 0) { ahd_free(ahd); return (-error); } /* * Second Function PCI devices need to inherit some * * settings from function 0. */ if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0) ahd_linux_pci_inherit_flags(ahd); pci_set_drvdata(pdev, ahd); ahd_linux_register_host(ahd, &aic79xx_driver_template); return (0); }
int ahd_pci_map_registers(struct ahd_softc *ahd) { uint32_t command; u_long base; uint8_t __iomem *maddr; int error; /* * If its allowed, we prefer memory mapped access. */ command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4); command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); base = 0; maddr = NULL; error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr); if (error == 0) { ahd->platform_data->mem_busaddr = base; ahd->tags[0] = BUS_SPACE_MEMIO; ahd->bshs[0].maddr = maddr; ahd->tags[1] = BUS_SPACE_MEMIO; ahd->bshs[1].maddr = maddr + 0x100; ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command | PCIM_CMD_MEMEN, 4); if (ahd_pci_test_register_access(ahd) != 0) { printf("aic79xx: PCI Device %d:%d:%d " "failed memory mapped test. Using PIO.\n", ahd_get_pci_bus(ahd->dev_softc), ahd_get_pci_slot(ahd->dev_softc), ahd_get_pci_function(ahd->dev_softc)); iounmap(maddr); release_mem_region(ahd->platform_data->mem_busaddr, 0x1000); ahd->bshs[0].maddr = NULL; maddr = NULL; } else command |= PCIM_CMD_MEMEN; } else if (bootverbose) { printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx " "unavailable. Cannot memory map device.\n", ahd_get_pci_bus(ahd->dev_softc), ahd_get_pci_slot(ahd->dev_softc), ahd_get_pci_function(ahd->dev_softc), base); } if (maddr == NULL) { u_long base2; error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2); if (error == 0) { ahd->tags[0] = BUS_SPACE_PIO; ahd->tags[1] = BUS_SPACE_PIO; ahd->bshs[0].ioport = base; ahd->bshs[1].ioport = base2; command |= PCIM_CMD_PORTEN; } else { printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx" "unavailable. Cannot map device.\n", ahd_get_pci_bus(ahd->dev_softc), ahd_get_pci_slot(ahd->dev_softc), ahd_get_pci_function(ahd->dev_softc), base, base2); } } ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4); return (error); }
static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { char buf[80]; struct ahd_softc *ahd; ahd_dev_softc_t pci; const struct ahd_pci_identity *entry; char *name; int error; struct device *dev = &pdev->dev; pci = pdev; entry = ahd_find_pci_device(pci); if (entry == NULL) return (-ENODEV); /* * Allocate a softc for this card and * set it up for attachment by our * common detect routine. */ sprintf(buf, "ahd_pci:%d:%d:%d", ahd_get_pci_bus(pci), ahd_get_pci_slot(pci), ahd_get_pci_function(pci)); name = kmalloc(strlen(buf) + 1, GFP_ATOMIC); if (name == NULL) return (-ENOMEM); strcpy(name, buf); ahd = ahd_alloc(NULL, name); if (ahd == NULL) return (-ENOMEM); if (pci_enable_device(pdev)) { ahd_free(ahd); return (-ENODEV); } pci_set_master(pdev); if (sizeof(dma_addr_t) > 4) { const u64 required_mask = dma_get_required_mask(dev); if (required_mask > DMA_BIT_MASK(39) && dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) ahd->flags |= AHD_64BIT_ADDRESSING; else if (required_mask > DMA_BIT_MASK(32) && dma_set_mask(dev, DMA_BIT_MASK(39)) == 0) ahd->flags |= AHD_39BIT_ADDRESSING; else dma_set_mask(dev, DMA_BIT_MASK(32)); } else { dma_set_mask(dev, DMA_BIT_MASK(32)); } ahd->dev_softc = pci; error = ahd_pci_config(ahd, entry); if (error != 0) { ahd_free(ahd); return (-error); } /* * Second Function PCI devices need to inherit some * * settings from function 0. */ if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0) ahd_linux_pci_inherit_flags(ahd); pci_set_drvdata(pdev, ahd); ahd_linux_register_host(ahd, &aic79xx_driver_template); return (0); }