Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a283bd37 authored by James Bottomley's avatar James Bottomley Committed by James Bottomley
Browse files

[SCSI] Add target alloc/destroy callbacks to the host template



This gives the HBA driver notice when a target is created and
destroyed to allow it to manage its own target based allocations
accordingly.

This is a much reduced verson of the original patch sent in by
James.Smart@Emulex.com

Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 631e8a13
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -293,6 +293,10 @@ static void scsi_target_dev_release(struct device *dev)
{
	struct device *parent = dev->parent;
	struct scsi_target *starget = to_scsi_target(dev);
	struct Scsi_Host *shost = dev_to_shost(parent);

	if (shost->hostt->target_destroy)
		shost->hostt->target_destroy(starget);
	kfree(starget);
	put_device(parent);
}
@@ -360,9 +364,23 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
	list_add_tail(&starget->siblings, &shost->__targets);
	spin_unlock_irqrestore(shost->host_lock, flags);
	/* allocate and add */
	transport_setup_device(&starget->dev);
	device_add(&starget->dev);
	transport_add_device(&starget->dev);
	transport_setup_device(dev);
	device_add(dev);
	transport_add_device(dev);
	if (shost->hostt->target_alloc) {
		int error = shost->hostt->target_alloc(starget);

		if(error) {
			dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);
			/* don't want scsi_target_reap to do the final
			 * put because it will be under the host lock */
			get_device(dev);
			scsi_target_reap(starget);
			put_device(dev);
			return NULL;
		}
	}

	return starget;

 found:
+3 −1
Original line number Diff line number Diff line
@@ -154,7 +154,9 @@ struct scsi_target {
	unsigned int		id; /* target id ... replace
				     * scsi_device.id eventually */
	unsigned long		create:1; /* signal that it needs to be added */
	unsigned long		starget_data[0];
	void 			*hostdata; /* available to low-level driver */
	unsigned long		starget_data[0]; /* for the transport */
	/* starget_data must be the last element!!!! */
} __attribute__((aligned(sizeof(unsigned long))));

#define to_scsi_target(d)	container_of(d, struct scsi_target, dev)
+25 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ struct block_device;
struct module;
struct scsi_cmnd;
struct scsi_device;
struct scsi_target;
struct Scsi_Host;
struct scsi_host_cmd_pool;
struct scsi_transport_template;
@@ -227,6 +228,30 @@ struct scsi_host_template {
	 */
	void (* slave_destroy)(struct scsi_device *);

	/*
	 * Before the mid layer attempts to scan for a new device attached
	 * to a target where no target currently exists, it will call this
	 * entry in your driver.  Should your driver need to allocate any
	 * structs or perform any other init items in order to send commands
	 * to a currently unused target, then this is where you can perform
	 * those allocations.
	 *
	 * Return values: 0 on success, non-0 on failure
	 *
	 * Status: OPTIONAL
	 */
	int (* target_alloc)(struct scsi_target *);

	/*
	 * Immediately prior to deallocating the target structure, and
	 * after all activity to attached scsi devices has ceased, the
	 * midlayer calls this point so that the driver may deallocate
	 * and terminate any references to the target.
	 *
	 * Status: OPTIONAL
	 */
	void (* target_destroy)(struct scsi_target *);

	/*
	 * fill in this function to allow the queue depth of this host
	 * to be changeable (on a per device basis).  returns either