static int mptspi_target_alloc()

in fusion/mptspi.c [397:454]


static int mptspi_target_alloc(struct scsi_target *starget)
{
	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
	VirtTarget		*vtarget;
	MPT_ADAPTER *ioc;

	if (hd == NULL)
		return -ENODEV;

	ioc = hd->ioc;
	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
	if (!vtarget)
		return -ENOMEM;

	vtarget->ioc_id = ioc->id;
	vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
	vtarget->id = (u8)starget->id;
	vtarget->channel = (u8)starget->channel;
	vtarget->starget = starget;
	starget->hostdata = vtarget;

	if (starget->channel == 1) {
		if (mptscsih_is_phys_disk(ioc, 0, starget->id) == 0)
			return 0;
		vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
		/* The real channel for this device is zero */
		vtarget->channel = 0;
		/* The actual physdisknum (for RAID passthrough) */
		vtarget->id = mptscsih_raid_id_to_num(ioc, 0,
		    starget->id);
	}

	if (starget->channel == 0 &&
	    mptspi_is_raid(hd, starget->id)) {
		vtarget->raidVolume = 1;
		ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
		    "RAID Volume @ channel=%d id=%d\n", ioc->name, starget->channel,
		    starget->id));
	}

	if (ioc->spi_data.nvram &&
	    ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
		u32 nvram = ioc->spi_data.nvram[starget->id];
		spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
		spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
	} else {
		spi_min_period(starget) = ioc->spi_data.minSyncFactor;
		spi_max_width(starget) = ioc->spi_data.maxBusWidth;
	}
	spi_max_offset(starget) = ioc->spi_data.maxSyncOffset;

	spi_offset(starget) = 0;
	spi_period(starget) = 0xFF;
	mptspi_write_width(starget, 0);

	return 0;
}