bool amdgpu_read_bios(struct amdgpu_device *adev) { uint8_t __iomem *bios, val[2]; size_t size; adev->bios = NULL; /* XXX: some cards may return 0 for rom size? ddx has a workaround */ bios = pci_map_rom(adev->pdev, &size); if (!bios) { return false; } val[0] = readb(&bios[0]); val[1] = readb(&bios[1]); if (size == 0 || !AMD_IS_VALID_VBIOS(val)) { pci_unmap_rom(adev->pdev, bios); return false; } adev->bios = kzalloc(size, GFP_KERNEL); if (adev->bios == NULL) { pci_unmap_rom(adev->pdev, bios); return false; } adev->bios_size = size; memcpy_fromio(adev->bios, bios, size); pci_unmap_rom(adev->pdev, bios); return true; }
static bool radeon_read_bios(struct radeon_device *rdev) { uint8_t __iomem *bios; size_t size; rdev->bios = NULL; /* XXX: some cards may return 0 for rom size? ddx has a workaround */ bios = pci_map_rom(rdev->pdev, &size); if (!bios) { return false; } if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { pci_unmap_rom(rdev->pdev, bios); return false; } rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) { pci_unmap_rom(rdev->pdev, bios); return false; } memcpy(rdev->bios, bios, size); pci_unmap_rom(rdev->pdev, bios); return true; }
bool amdgpu_read_bios(struct amdgpu_device *adev) { uint8_t __iomem *bios, val1, val2; size_t size; adev->bios = NULL; /* XXX: some cards may return 0 for rom size? ddx has a workaround */ bios = pci_map_rom(adev->pdev, &size); if (!bios) { return false; } val1 = readb(&bios[0]); val2 = readb(&bios[1]); if (size == 0 || val1 != 0x55 || val2 != 0xaa) { pci_unmap_rom(adev->pdev, bios); return false; } adev->bios = kzalloc(size, GFP_KERNEL); if (adev->bios == NULL) { pci_unmap_rom(adev->pdev, bios); return false; } memcpy_fromio(adev->bios, bios, size); pci_unmap_rom(adev->pdev, bios); return true; }
/** * psb_intel_init_bios - initialize VBIOS settings & find VBT * @dev: DRM device * * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers * to appropriate values. * * VBT existence is a sanity check that is relied on by other i830_bios.c code. * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may * feed an updated VBT back through that, compared to what we'll fetch using * this method of groping around in the BIOS data. * * Returns 0 on success, nonzero on failure. */ int psb_intel_init_bios(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct pci_dev *pdev = dev->pdev; struct vbt_header *vbt = NULL; struct bdb_header *bdb = NULL; u8 __iomem *bios = NULL; size_t size; int i; dev_priv->panel_type = 0xff; /* XXX Should this validation be moved to intel_opregion.c? */ if (dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", vbt->signature); bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); } else dev_priv->opregion.vbt = NULL; } if (bdb == NULL) { bios = pci_map_rom(pdev, &size); if (!bios) return -1; /* Scour memory looking for the VBT signature */ for (i = 0; i + 4 < size; i++) { if (!memcmp(bios + i, "$VBT", 4)) { vbt = (struct vbt_header *)(bios + i); break; } } if (!vbt) { dev_err(dev->dev, "VBT signature missing\n"); pci_unmap_rom(pdev, bios); return -1; } bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); } /* Grab useful general dxefinitions */ parse_general_features(dev_priv, bdb); parse_driver_features(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); parse_device_mapping(dev_priv, bdb); parse_backlight_data(dev_priv, bdb); parse_edp(dev_priv, bdb); if (bios) pci_unmap_rom(pdev, bios); return 0; }
static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { int err; unsigned int addr_offset; int ret; ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(container_of(kobj, struct device, kobj)); ret = mutex_lock_interruptible(&pch_phub_mutex); if (ret) return -ERESTARTSYS; if (off > PCH_PHUB_OROM_SIZE) { addr_offset = 0; goto return_ok; } if (count > PCH_PHUB_OROM_SIZE) { addr_offset = 0; goto return_ok; } chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); if (!chip->pch_phub_extrom_base_address) { err = -ENOMEM; goto exrom_map_err; } for (addr_offset = 0; addr_offset < count; addr_offset++) { if (PCH_PHUB_OROM_SIZE < off + addr_offset) goto return_ok; ret = pch_phub_write_serial_rom(chip, chip->pch_opt_rom_start_address + addr_offset + off, buf[addr_offset]); if (ret) { err = ret; goto return_err; } } return_ok: pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); mutex_unlock(&pch_phub_mutex); return addr_offset; return_err: pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); exrom_map_err: mutex_unlock(&pch_phub_mutex); return err; }
static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, char *buf) { u8 mac[8]; struct pch_phub_reg *chip = dev_get_drvdata(dev); ssize_t rom_size; chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); if (!chip->pch_phub_extrom_base_address) return -ENOMEM; pch_phub_read_gbe_mac_addr(chip, mac); pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); return sprintf(buf, "%pM\n", mac); }
/** * intel_init_bios - initialize VBIOS settings & find VBT * @dev: DRM device * * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers * to appropriate values. * * VBT existence is a sanity check that is relied on by other i830_bios.c code. * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may * feed an updated VBT back through that, compared to what we'll fetch using * this method of groping around in the BIOS data. * * Returns 0 on success, nonzero on failure. */ bool intel_init_bios(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct pci_dev *pdev = dev->pdev; struct vbt_header *vbt = NULL; struct bdb_header *bdb; u8 __iomem *bios; size_t size; int i; bios = pci_map_rom(pdev, &size); if (!bios) return -1; /* Scour memory looking for the VBT signature */ for (i = 0; i + 4 < size; i++) { if (!memcmp(bios + i, "$VBT", 4)) { vbt = (struct vbt_header *)(bios + i); break; } } if (!vbt) { DRM_ERROR("VBT signature missing\n"); pci_unmap_rom(pdev, bios); return -1; } bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); /* Grab useful general definitions */ parse_general_features(dev_priv, bdb); parse_general_definitions(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); pci_unmap_rom(pdev, bios); return 0; }
static void nouveau_bios_shadow_pci(struct nouveau_bios *bios) { struct pci_dev *pdev = nv_device(bios)->pdev; size_t size; if (!pci_enable_rom(pdev)) { void __iomem *rom = pci_map_rom(pdev, &size); if (rom && size) { bios->data = kmalloc(size, GFP_KERNEL); if (bios->data) { memcpy_fromio(bios->data, rom, size); bios->size = size; } } if (rom) pci_unmap_rom(pdev, rom); pci_disable_rom(pdev); } }
static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u8 mac[ETH_ALEN]; ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(dev); int ret; if (!mac_pton(buf, mac)) return -EINVAL; chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); if (!chip->pch_phub_extrom_base_address) return -ENOMEM; ret = pch_phub_write_gbe_mac_addr(chip, mac); pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); if (ret) return ret; return count; }
/** * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy * @dev: pointer to pci device struct * @size: pointer to receive size of pci window over ROM * @return: kernel virtual pointer to image of ROM * * Map a PCI ROM into kernel space. If ROM is boot video ROM, * the shadow BIOS copy will be returned instead of the * actual ROM. */ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) { struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; void __iomem *rom; rom = pci_map_rom(pdev, size); if (!rom) return NULL; if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW)) return rom; res->start = (unsigned long)kmalloc(*size, GFP_KERNEL); if (!res->start) return rom; res->end = res->start + *size; memcpy_fromio((void*)res->start, rom, *size); pci_unmap_rom(pdev, rom); res->flags |= IORESOURCE_ROM_COPY; return (void __iomem *)res->start; }
static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u8 mac[6]; ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(dev); if (count != 18) return -EINVAL; sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], (u32 *)&mac[4], (u32 *)&mac[5]); chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); if (!chip->pch_phub_extrom_base_address) return -ENOMEM; pch_phub_write_gbe_mac_addr(chip, mac); pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); return count; }
static bool radeon_read_bios(struct radeon_device *rdev) { uint8_t __iomem *bios; size_t size; rdev->bios = NULL; /* */ bios = pci_map_rom(rdev->pdev, &size); if (!bios) { return false; } if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { pci_unmap_rom(rdev->pdev, bios); return false; } rdev->bios = kmemdup(bios, size, GFP_KERNEL); if (rdev->bios == NULL) { pci_unmap_rom(rdev->pdev, bios); return false; } pci_unmap_rom(rdev->pdev, bios); return true; }
static int __devinit pch_phub_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int retval; int ret; ssize_t rom_size; struct pch_phub_reg *chip; chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); if (chip == NULL) return -ENOMEM; ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s : pci_enable_device FAILED(ret=%d)", __func__, ret); goto err_pci_enable_dev; } dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__, ret); ret = pci_request_regions(pdev, KBUILD_MODNAME); if (ret) { dev_err(&pdev->dev, "%s : pci_request_regions FAILED(ret=%d)", __func__, ret); goto err_req_regions; } dev_dbg(&pdev->dev, "%s : " "pci_request_regions returns %d\n", __func__, ret); chip->pch_phub_base_address = pci_iomap(pdev, 1, 0); if (chip->pch_phub_base_address == 0) { dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); ret = -ENOMEM; goto err_pci_iomap; } dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " "in pch_phub_base_address variable is %p\n", __func__, chip->pch_phub_base_address); chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size); if (chip->pch_phub_extrom_base_address == 0) { dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__); ret = -ENOMEM; goto err_pci_map; } dev_dbg(&pdev->dev, "%s : " "pci_map_rom SUCCESS and value in " "pch_phub_extrom_base_address variable is %p\n", __func__, chip->pch_phub_extrom_base_address); pci_set_drvdata(pdev, chip); retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); if (retval) goto err_sysfs_create; retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); if (retval) goto exit_bin_attr; pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET, CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK); /* set the prefech value */ iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); /* set the interrupt delay value */ iowrite32(0x25, chip->pch_phub_base_address + 0x44); return 0; exit_bin_attr: sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); err_sysfs_create: pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); err_pci_map: pci_iounmap(pdev, chip->pch_phub_base_address); err_pci_iomap: pci_release_regions(pdev); err_req_regions: pci_disable_device(pdev); err_pci_enable_dev: kfree(chip); dev_err(&pdev->dev, "%s returns %d\n", __func__, ret); return ret; }
/** * intel_parse_bios - find VBT and initialize settings from the BIOS * @dev: DRM device * * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers * to appropriate values. * * Returns 0 on success, nonzero on failure. */ bool intel_parse_bios(struct drm_device *dev) { extern struct drm_device *i915; struct drm_i915_private *dev_priv = i915->dev_private; extern struct drm_device *i915; struct pci_dev *pdev = i915->pdev; struct bdb_header *bdb = NULL; u8 __iomem *bios = NULL; init_vbt_defaults(dev_priv); /* XXX Should this validation be moved to intel_opregion.c? */ if (!0 && dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { fprintf(stderr, "Using VBT from OpRegion: %20s\n", vbt->signature); bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); } else dev_priv->opregion.vbt = NULL; } if (bdb == NULL) { struct vbt_header *vbt = NULL; size_t size; int i; bios = pci_map_rom(pdev, &size); if (!bios) return -1; /* Scour memory looking for the VBT signature */ for (i = 0; i + 4 < size; i++) { if (!memcmp(bios + i, "$VBT", 4)) { vbt = (struct vbt_header *)(bios + i); break; } } if (!vbt) { fprintf(stderr, "VBT signature missing\n"); pci_unmap_rom(pdev, bios); return -1; } bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); } /* Grab useful general definitions */ parse_general_features(dev_priv, bdb); parse_general_definitions(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); parse_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); if (bios) pci_unmap_rom(pdev, bios); return 0; }
static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { unsigned int rom_signature; unsigned char rom_length; unsigned int tmp; unsigned int addr_offset; unsigned int orom_size; int ret; int err; ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(container_of(kobj, struct device, kobj)); ret = mutex_lock_interruptible(&pch_phub_mutex); if (ret) { err = -ERESTARTSYS; goto return_err_nomutex; } /* Get Rom signature */ chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); if (!chip->pch_phub_extrom_base_address) goto exrom_map_err; pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, (unsigned char *)&rom_signature); rom_signature &= 0xff; pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1, (unsigned char *)&tmp); rom_signature |= (tmp & 0xff) << 8; if (rom_signature == 0xAA55) { pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 2, &rom_length); orom_size = rom_length * 512; if (orom_size < off) { addr_offset = 0; goto return_ok; } if (orom_size < count) { addr_offset = 0; goto return_ok; } for (addr_offset = 0; addr_offset < count; addr_offset++) { pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + addr_offset + off, &buf[addr_offset]); } } else { err = -ENODATA; goto return_err; } return_ok: pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); mutex_unlock(&pch_phub_mutex); return addr_offset; return_err: pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); exrom_map_err: mutex_unlock(&pch_phub_mutex); return_err_nomutex: return err; }
/** * intel_parse_bios - find VBT and initialize settings from the BIOS * @dev: DRM device * * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers * to appropriate values. * * Returns 0 on success, nonzero on failure. */ int intel_parse_bios(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct pci_dev *pdev = dev->pdev; struct bdb_header *bdb = NULL; u8 __iomem *bios = NULL; if (HAS_PCH_NOP(dev)) return -ENODEV; init_vbt_defaults(dev_priv); /* XXX Should this validation be moved to intel_opregion.c? */ if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", vbt->signature); bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); } else dev_priv->opregion.vbt = NULL; } if (bdb == NULL) { struct vbt_header *vbt = NULL; size_t size; int i; bios = pci_map_rom(pdev, &size); if (!bios) return -1; /* Scour memory looking for the VBT signature */ for (i = 0; i + 4 < size; i++) { if (!memcmp(bios + i, "$VBT", 4)) { vbt = (struct vbt_header *)(bios + i); break; } } if (!vbt) { DRM_DEBUG_DRIVER("VBT signature missing\n"); pci_unmap_rom(pdev, bios); return -1; } bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); } /* Grab useful general definitions */ parse_general_features(dev_priv, bdb); parse_general_definitions(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb); parse_lfp_backlight(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); parse_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); parse_mipi(dev_priv, bdb); parse_ddi_ports(dev_priv, bdb); if (bios) pci_unmap_rom(pdev, bios); return 0; }
/* * MMIO BAR access * We handle two excluded ranges here as well, if the user tries to read * the ROM beyond what PCI tells us is available or the MSI-X table region, * we return 0xFF and writes are dropped. */ ssize_t vfio_pci_mem_readwrite(struct vfio_pci_device *vdev, char __user *buf, size_t count, loff_t *ppos, bool iswrite) { struct pci_dev *pdev = vdev->pdev; loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK; int bar = VFIO_PCI_OFFSET_TO_INDEX(*ppos); void __iomem *io; resource_size_t end; size_t done = 0; size_t x_start = 0, x_end = 0; /* excluded range */ if (!pci_resource_start(pdev, bar)) return -EINVAL; end = pci_resource_len(pdev, bar); if (pos > end) return -EINVAL; if (pos == end) return 0; if (pos + count > end) count = end - pos; if (bar == PCI_ROM_RESOURCE) { io = pci_map_rom(pdev, &x_start); x_end = end; } else { if (!vdev->barmap[bar]) { int ret; ret = pci_request_selected_regions(pdev, 1 << bar, "vfio"); if (ret) return ret; vdev->barmap[bar] = pci_iomap(pdev, bar, 0); if (!vdev->barmap[bar]) { pci_release_selected_regions(pdev, 1 << bar); return -EINVAL; } } io = vdev->barmap[bar]; if (bar == vdev->msix_bar) { x_start = vdev->msix_offset; x_end = vdev->msix_offset + vdev->msix_size; } } if (!io) return -EINVAL; while (count) { size_t fillable, filled; if (pos < x_start) fillable = x_start - pos; else if (pos >= x_end) fillable = end - pos; else fillable = 0; if (fillable >= 4 && !(pos % 4) && (count >= 4)) { __le32 val; if (iswrite) { if (copy_from_user(&val, buf, 4)) goto out; iowrite32(le32_to_cpu(val), io + pos); } else { val = cpu_to_le32(ioread32(io + pos)); if (copy_to_user(buf, &val, 4)) goto out; } filled = 4; } else if (fillable >= 2 && !(pos % 2) && (count >= 2)) { __le16 val; if (iswrite) { if (copy_from_user(&val, buf, 2)) goto out; iowrite16(le16_to_cpu(val), io + pos); } else { val = cpu_to_le16(ioread16(io + pos)); if (copy_to_user(buf, &val, 2)) goto out; } filled = 2; } else if (fillable) { u8 val; if (iswrite) { if (copy_from_user(&val, buf, 1)) goto out; iowrite8(val, io + pos); } else { val = ioread8(io + pos); if (copy_to_user(buf, &val, 1)) goto out; } filled = 1; } else { /* Drop writes, fill reads with FF */ if (!iswrite) { char val = 0xFF; size_t i; for (i = 0; i < x_end - pos; i++) { if (put_user(val, buf + i)) goto out; } } filled = x_end - pos; } count -= filled; done += filled; buf += filled; pos += filled; } *ppos += done; out: if (bar == PCI_ROM_RESOURCE) pci_unmap_rom(pdev, io); return count ? -EFAULT : done; }
bool intel_parse_bios(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct pci_dev *pdev = dev->pdev; struct bdb_header *bdb = NULL; u8 __iomem *bios = NULL; init_vbt_defaults(dev_priv); if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", vbt->signature); bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); } else dev_priv->opregion.vbt = NULL; } if (bdb == NULL) { struct vbt_header *vbt = NULL; size_t size; int i; bios = pci_map_rom(pdev, &size); if (!bios) return -1; for (i = 0; i + 4 < size; i++) { if (!memcmp(bios + i, "$VBT", 4)) { vbt = (struct vbt_header *)(bios + i); break; } } if (!vbt) { DRM_DEBUG_DRIVER("VBT signature missing\n"); pci_unmap_rom(pdev, bios); return -1; } bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); } parse_general_features(dev_priv, bdb); parse_general_definitions(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); parse_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); if (bios) pci_unmap_rom(pdev, bios); return 0; }
static int __devinit pch_phub_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int retval; int ret; ssize_t rom_size; struct pch_phub_reg *chip; chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); if (chip == NULL) return -ENOMEM; ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s : pci_enable_device FAILED(ret=%d)", __func__, ret); goto err_pci_enable_dev; } dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__, ret); ret = pci_request_regions(pdev, KBUILD_MODNAME); if (ret) { dev_err(&pdev->dev, "%s : pci_request_regions FAILED(ret=%d)", __func__, ret); goto err_req_regions; } dev_dbg(&pdev->dev, "%s : " "pci_request_regions returns %d\n", __func__, ret); chip->pch_phub_base_address = pci_iomap(pdev, 1, 0); if (chip->pch_phub_base_address == 0) { dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); ret = -ENOMEM; goto err_pci_iomap; } dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " "in pch_phub_base_address variable is %p\n", __func__, chip->pch_phub_base_address); chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size); if (chip->pch_phub_extrom_base_address == 0) { dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__); ret = -ENOMEM; goto err_pci_map; } dev_dbg(&pdev->dev, "%s : " "pci_map_rom SUCCESS and value in " "pch_phub_extrom_base_address variable is %p\n", __func__, chip->pch_phub_extrom_base_address); if (id->driver_data == 1) { retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); if (retval) goto err_sysfs_create; retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); if (retval) goto exit_bin_attr; pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET, CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK); /* quirk for CM-iTC board */ if (strstr(dmi_get_system_info(DMI_BOARD_NAME), "CM-iTC")) pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET, CLKCFG_UART_48MHZ | CLKCFG_BAUDDIV | CLKCFG_PLL2VCO | CLKCFG_UARTCLKSEL, CLKCFG_UART_MASK); /* set the prefech value */ iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); /* set the interrupt delay value */ iowrite32(0x25, chip->pch_phub_base_address + 0x44); } else if (id->driver_data == 2) { retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); if (retval) goto err_sysfs_create; /* set the prefech value * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a * Device4(SDIO #0,1,2):f * Device6(SATA 2):f * Device8(USB OHCI #0/ USB EHCI #0):a */ iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); } pci_set_drvdata(pdev, chip); return 0; exit_bin_attr: sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); err_sysfs_create: pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); err_pci_map: pci_iounmap(pdev, chip->pch_phub_base_address); err_pci_iomap: pci_release_regions(pdev); err_req_regions: pci_disable_device(pdev); err_pci_enable_dev: kfree(chip); dev_err(&pdev->dev, "%s returns %d\n", __func__, ret); return ret; }