static int __devinit asd_map_ha(struct asd_ha_struct *asd_ha) { int err; u16 cmd_reg; err = pci_read_config_word(asd_ha->pcidev, PCI_COMMAND, &cmd_reg); if (err) { asd_printk("couldn't read command register of %s\n", pci_name(asd_ha->pcidev)); goto Err; } err = -ENODEV; if (cmd_reg & PCI_COMMAND_MEMORY) { if ((err = asd_map_memio(asd_ha))) goto Err; } else if (cmd_reg & PCI_COMMAND_IO) { if ((err = asd_map_ioport(asd_ha))) goto Err; asd_printk("%s ioport mapped -- upgrade your hardware\n", pci_name(asd_ha->pcidev)); } else { asd_printk("no proper device access to %s\n", pci_name(asd_ha->pcidev)); goto Err; } return 0; Err: return err; }
static int asd_map_memio(struct asd_ha_struct *asd_ha) { int err, i; struct asd_ha_addrspace *io_handle; asd_ha->iospace = 0; for (i = 0; i < 3; i += 2) { io_handle = &asd_ha->io_handle[i==0?0:1]; io_handle->start = pci_resource_start(asd_ha->pcidev, i); io_handle->len = pci_resource_len(asd_ha->pcidev, i); io_handle->flags = pci_resource_flags(asd_ha->pcidev, i); err = -ENODEV; if (!io_handle->start || !io_handle->len) { asd_printk("MBAR%d start or length for %s is 0.\n", i==0?0:1, pci_name(asd_ha->pcidev)); goto Err; } err = pci_request_region(asd_ha->pcidev, i, ASD_DRIVER_NAME); if (err) { asd_printk("couldn't reserve memory region for %s\n", pci_name(asd_ha->pcidev)); goto Err; } if (io_handle->flags & IORESOURCE_CACHEABLE) io_handle->addr = ioremap(io_handle->start, io_handle->len); else io_handle->addr = ioremap_nocache(io_handle->start, io_handle->len); if (!io_handle->addr) { asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1, pci_name(asd_ha->pcidev)); err = -ENOMEM; goto Err_unreq; } } return 0; Err_unreq: pci_release_region(asd_ha->pcidev, i); Err: if (i > 0) { io_handle = &asd_ha->io_handle[0]; iounmap(io_handle->addr); pci_release_region(asd_ha->pcidev, 0); } return err; }
static int asd_common_setup(struct asd_ha_struct *asd_ha) { int err, i; asd_ha->revision_id = asd_ha->pcidev->revision; err = -ENODEV; if (asd_ha->revision_id < AIC9410_DEV_REV_B0) { asd_printk("%s is revision %s (%X), which is not supported\n", pci_name(asd_ha->pcidev), asd_dev_rev[asd_ha->revision_id], asd_ha->revision_id); goto Err; } /* Provide some sane default values. */ asd_ha->hw_prof.max_scbs = 512; asd_ha->hw_prof.max_ddbs = ASD_MAX_DDBS; asd_ha->hw_prof.num_phys = ASD_MAX_PHYS; /* All phys are enabled, by default. */ asd_ha->hw_prof.enabled_phys = 0xFF; for (i = 0; i < ASD_MAX_PHYS; i++) { asd_ha->hw_prof.phy_desc[i].max_sas_lrate = SAS_LINK_RATE_3_0_GBPS; asd_ha->hw_prof.phy_desc[i].min_sas_lrate = SAS_LINK_RATE_1_5_GBPS; asd_ha->hw_prof.phy_desc[i].max_sata_lrate = SAS_LINK_RATE_1_5_GBPS; asd_ha->hw_prof.phy_desc[i].min_sata_lrate = SAS_LINK_RATE_1_5_GBPS; } return 0; Err: return err; }
static int __devinit asd_map_ioport(struct asd_ha_struct *asd_ha) { int i = PCI_IOBAR_OFFSET, err; struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; asd_ha->iospace = 1; io_handle->start = pci_resource_start(asd_ha->pcidev, i); io_handle->len = pci_resource_len(asd_ha->pcidev, i); io_handle->flags = pci_resource_flags(asd_ha->pcidev, i); io_handle->addr = (void __iomem *) io_handle->start; if (!io_handle->start || !io_handle->len) { asd_printk("couldn't get IO ports for %s\n", pci_name(asd_ha->pcidev)); return -ENODEV; } err = pci_request_region(asd_ha->pcidev, i, ASD_DRIVER_NAME); if (err) { asd_printk("couldn't reserve io space for %s\n", pci_name(asd_ha->pcidev)); } return err; }
static ssize_t asd_store_update_bios(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev); char *cmd_ptr, *filename_ptr; struct bios_file_header header, *hdr_ptr; int res, i; u32 csum = 0; int flash_command = FLASH_CMD_NONE; int err = 0; cmd_ptr = kcalloc(count, 2, GFP_KERNEL); if (!cmd_ptr) { err = FAIL_OUT_MEMORY; goto out; } filename_ptr = cmd_ptr + count; res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr); if (res != 2) { err = FAIL_PARAMETERS; goto out1; } for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) { if (!memcmp(flash_command_table[i].command, cmd_ptr, strlen(cmd_ptr))) { flash_command = flash_command_table[i].code; break; } } if (flash_command == FLASH_CMD_NONE) { err = FAIL_PARAMETERS; goto out1; } if (asd_ha->bios_status == FLASH_IN_PROGRESS) { err = FLASH_IN_PROGRESS; goto out1; } err = request_firmware(&asd_ha->bios_image, filename_ptr, &asd_ha->pcidev->dev); if (err) { asd_printk("Failed to load bios image file %s, error %d\n", filename_ptr, err); err = FAIL_OPEN_BIOS_FILE; goto out1; } hdr_ptr = (struct bios_file_header *)asd_ha->bios_image->data; if ((hdr_ptr->contrl_id.vendor != asd_ha->pcidev->vendor || hdr_ptr->contrl_id.device != asd_ha->pcidev->device) && (hdr_ptr->contrl_id.sub_vendor != asd_ha->pcidev->vendor || hdr_ptr->contrl_id.sub_device != asd_ha->pcidev->device)) { ASD_DPRINTK("The PCI vendor or device id does not match\n"); ASD_DPRINTK("vendor=%x dev=%x sub_vendor=%x sub_dev=%x" " pci vendor=%x pci dev=%x\n", hdr_ptr->contrl_id.vendor, hdr_ptr->contrl_id.device, hdr_ptr->contrl_id.sub_vendor, hdr_ptr->contrl_id.sub_device, asd_ha->pcidev->vendor, asd_ha->pcidev->device); err = FAIL_CHECK_PCI_ID; goto out2; } if (hdr_ptr->filelen != asd_ha->bios_image->size) { err = FAIL_FILE_SIZE; goto out2; } /* calculate checksum */ for (i = 0; i < hdr_ptr->filelen; i++) csum += asd_ha->bios_image->data[i]; if ((csum & 0x0000ffff) != hdr_ptr->checksum) { ASD_DPRINTK("BIOS file checksum mismatch\n"); err = FAIL_CHECK_SUM; goto out2; } if (flash_command == FLASH_CMD_UPDATE) { asd_ha->bios_status = FLASH_IN_PROGRESS; err = asd_write_flash_seg(asd_ha, &asd_ha->bios_image->data[sizeof(*hdr_ptr)], 0, hdr_ptr->filelen-sizeof(*hdr_ptr)); if (!err) err = asd_verify_flash_seg(asd_ha, &asd_ha->bios_image->data[sizeof(*hdr_ptr)], 0, hdr_ptr->filelen-sizeof(*hdr_ptr)); } else { asd_ha->bios_status = FLASH_IN_PROGRESS; err = asd_verify_flash_seg(asd_ha, &asd_ha->bios_image->data[sizeof(header)], 0, hdr_ptr->filelen-sizeof(header)); } out2: release_firmware(asd_ha->bios_image); out1: kfree(cmd_ptr); out: asd_ha->bios_status = err; if (!err) return count; else return -err; }