static int mptspi_write_spi_device_pg1()

in fusion/mptspi.c [849:932]


static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
			       struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1)
{
	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
	struct _MPT_ADAPTER *ioc = hd->ioc;
	struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1;
	dma_addr_t pg1_dma;
	int size;
	struct _x_config_parms cfg;
	struct _CONFIG_PAGE_HEADER hdr;
	int err = -EBUSY;
	u32 nego_parms;
	u32 period;
	struct scsi_device *sdev;
	int i;

	/* don't allow updating nego parameters on RAID devices */
	if (starget->channel == 0 &&
	    mptspi_is_raid(hd, starget->id))
		return -1;

	size = ioc->spi_data.sdp1length * 4;

	pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL);
	if (pg1 == NULL) {
		starget_printk(KERN_ERR, starget, MYIOC_s_FMT
		    "dma_alloc_coherent for parameters failed\n", ioc->name);
		return -EINVAL;
	}

	memset(&hdr, 0, sizeof(hdr));

	hdr.PageVersion = ioc->spi_data.sdp1version;
	hdr.PageLength = ioc->spi_data.sdp1length;
	hdr.PageNumber = 1;
	hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;

	memset(&cfg, 0, sizeof(cfg));

	cfg.cfghdr.hdr = &hdr;
	cfg.physAddr = pg1_dma;
	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
	cfg.dir = 1;
	cfg.pageAddr = starget->id;

	memcpy(pg1, pass_pg1, size);

	pg1->Header.PageVersion = hdr.PageVersion;
	pg1->Header.PageLength = hdr.PageLength;
	pg1->Header.PageNumber = hdr.PageNumber;
	pg1->Header.PageType = hdr.PageType;

	nego_parms = le32_to_cpu(pg1->RequestedParameters);
	period = (nego_parms & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK) >>
		MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
	if (period == 8) {
		/* Turn on inline data padding for TAPE when running U320 */
		for (i = 0 ; i < 16; i++) {
			sdev = scsi_device_lookup_by_target(starget, i);
			if (sdev && sdev->type == TYPE_TAPE) {
				sdev_printk(KERN_DEBUG, sdev, MYIOC_s_FMT
					    "IDP:ON\n", ioc->name);
				nego_parms |= MPI_SCSIDEVPAGE1_RP_IDP;
				pg1->RequestedParameters =
				    cpu_to_le32(nego_parms);
				break;
			}
		}
	}

	mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters));

	if (mpt_config(ioc, &cfg)) {
		starget_printk(KERN_ERR, starget, MYIOC_s_FMT
		    "mpt_config failed\n", ioc->name);
		goto out_free;
	}
	err = 0;

 out_free:
	dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma);
	return err;
}