Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}