public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <James.Bottomley@SteelEye.com>
To: SCSI Mailing List <linux-scsi@vger.kernel.org>
Subject: Re: [PATCH] add target and host to transport classes
Date: 10 Sep 2004 11:03:44 -0400	[thread overview]
Message-ID: <1094828630.1974.2.camel@mulgrave> (raw)
In-Reply-To: <1094577840.2069.118.camel@mulgrave>

On Tue, 2004-09-07 at 13:23, James Bottomley wrote:
> OK, I've polished this up quite a bit, and actually got the
> implementation to work in the SPI transport classes.  It still needs to
> be commented and have all the failure cases sorted out, but this should
> be ready to play with. (Obviously, you need the target patch before this
> will apply.)

When I tried to use the host part, several problems turned up in it, so
this is an updated version with (hopefully) all the host issues fixed.

James

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/09/09 16:17:17-05:00 jejb@raven.il.steeleye.com 
#   Add host and target transport class abstractions
#   
#   This patch makes a transport class be composed of up to three individual
#   device classes representing potential interfaces on the scsi_device,
#   scsi_target and Scsi_Host.  A class only has to implement at least one
#   of these, but may optionally implement more.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsi_scan.c
#   2004/09/09 16:16:26-05:00 jejb@raven.il.steeleye.com +15 -40
#   Add host and target transport class abstractions
# 
# drivers/scsi/scsi_priv.h
#   2004/09/09 16:16:26-05:00 jejb@raven.il.steeleye.com +0 -16
#   Add host and target transport class abstractions
# 
# drivers/scsi/hosts.c
#   2004/09/09 16:16:26-05:00 jejb@raven.il.steeleye.com +15 -1
#   Add host and target transport class abstractions
# 
# include/scsi/scsi_device.h
#   2004/09/09 16:16:25-05:00 jejb@raven.il.steeleye.com +26 -1
#   Add host and target transport class abstractions
# 
# drivers/scsi/scsi_transport_spi.c
#   2004/09/09 16:16:25-05:00 jejb@raven.il.steeleye.com +8 -8
#   Add host and target transport class abstractions
# 
# drivers/scsi/scsi_transport_fc.c
#   2004/09/09 16:16:25-05:00 jejb@raven.il.steeleye.com +5 -5
#   Add host and target transport class abstractions
# 
# drivers/scsi/scsi_sysfs.c
#   2004/09/09 16:16:25-05:00 jejb@raven.il.steeleye.com +112 -25
#   Add host and target transport class abstractions
# 
# include/scsi/scsi_transport_spi.h
#   2004/09/09 16:16:24-05:00 jejb@raven.il.steeleye.com +10 -10
#   Add host and target transport class abstractions
# 
# include/scsi/scsi_transport_fc.h
#   2004/09/09 16:16:24-05:00 jejb@raven.il.steeleye.com +3 -3
#   Add host and target transport class abstractions
# 
# include/scsi/scsi_transport.h
#   2004/09/09 16:16:24-05:00 jejb@raven.il.steeleye.com +16 -7
#   Add host and target transport class abstractions
# 
# include/scsi/scsi_host.h
#   2004/09/09 16:16:24-05:00 jejb@raven.il.steeleye.com +10 -0
#   Add host and target transport class abstractions
# 
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	2004-09-10 07:44:30 +00:00
+++ b/drivers/scsi/hosts.c	2004-09-10 07:44:30 +00:00
@@ -82,6 +82,8 @@
 	set_bit(SHOST_DEL, &shost->shost_state);
 
 	class_device_unregister(&shost->shost_classdev);
+	if (shost->transport_classdev.class)
+		class_device_unregister(&shost->transport_classdev);
 	device_del(&shost->shost_gendev);
 }
 
@@ -154,6 +156,7 @@
 
 	scsi_proc_hostdir_rm(shost->hostt);
 	scsi_destroy_command_freelist(shost);
+	kfree(shost->shost_data);
 
 	/*
 	 * Some drivers (eg aha1542) do scsi_register()/scsi_unregister()
@@ -278,15 +281,26 @@
 	snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
 		  shost->host_no);
 
+	if (shost->transportt->host_size &&
+	    (shost->shost_data = kmalloc(shost->transportt->host_size,
+					 GFP_KERNEL)) == NULL)
+		goto fail_destroy_freelist;
+
+	if (shost->transportt->host_setup)
+		shost->transportt->host_setup(shost);
+
 	shost->eh_notify = &complete;
 	rval = kernel_thread(scsi_error_handler, shost, 0);
 	if (rval < 0)
-		goto fail_destroy_freelist;
+		goto fail_free_shost_data;
 	wait_for_completion(&complete);
 	shost->eh_notify = NULL;
+
 	scsi_proc_hostdir_add(shost->hostt);
 	return shost;
 
+ fail_free_shost_data:
+	kfree(shost->shost_data);
  fail_destroy_freelist:
 	scsi_destroy_command_freelist(shost);
  fail_kfree:
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h	2004-09-10 07:44:30 +00:00
+++ b/drivers/scsi/scsi_priv.h	2004-09-10 07:44:30 +00:00
@@ -58,22 +58,6 @@
  */
 #define SCAN_WILD_CARD	~0
 
-/*
- * scsi_target: representation of a scsi target, for now, this is only
- * used for single_lun devices. If no one has active IO to the target,
- * starget_sdev_user is NULL, else it points to the active sdev.
- */
-struct scsi_target {
-	struct scsi_device	*starget_sdev_user;
-	struct device		dev;
-};
-
-#define to_scsi_target(d)	container_of(d, struct scsi_target, dev)
-static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
-{
-	return to_scsi_target(sdev->sdev_gendev.parent);
-}
-
 /* hosts.c */
 extern int scsi_init_hosts(void);
 extern void scsi_exit_hosts(void);
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	2004-09-10 07:44:30 +00:00
+++ b/drivers/scsi/scsi_scan.c	2004-09-10 07:44:30 +00:00
@@ -202,10 +202,11 @@
 static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
 	       	uint channel, uint id, uint lun, void *hostdata)
 {
-	struct scsi_device *sdev, *device;
+	struct scsi_device *sdev;
 	unsigned long flags;
 
-	sdev = kmalloc(sizeof(*sdev) + shost->transportt->size, GFP_ATOMIC);
+	sdev = kmalloc(sizeof(*sdev) + shost->transportt->device_size,
+		       GFP_ATOMIC);
 	if (!sdev)
 		goto out;
 
@@ -256,45 +257,28 @@
 			goto out_free_queue;
 	}
 
-	if (shost->transportt->setup) {
-		if (shost->transportt->setup(sdev))
+	if (shost->transportt->device_setup) {
+		if (shost->transportt->device_setup(sdev))
 			goto out_cleanup_slave;
 	}
 
 	if (get_device(&sdev->host->shost_gendev) == NULL ||
 	    scsi_sysfs_device_initialize(sdev) != 0)
-		goto out_cleanup_transport;
+		goto out_cleanup_slave;
 
-	/*
-	 * If there are any same target siblings, add this to the
-	 * sibling list
-	 */
-	spin_lock_irqsave(shost->host_lock, flags);
-	list_for_each_entry(device, &shost->__devices, siblings) {
-		if (device->id == sdev->id &&
-		    device->channel == sdev->channel) {
-			list_add_tail(&sdev->same_target_siblings,
-				      &device->same_target_siblings);
-			sdev->scsi_level = device->scsi_level;
-			break;
-		}
-	}
 
-	/*
-	 * If there wasn't another lun already configured at this
-	 * target, then default this device to SCSI_2 until we
-	 * know better
-	 */
-	if (!sdev->scsi_level)
-		sdev->scsi_level = SCSI_2;
+	/* NOTE: this target initialisation code depends critically on
+	 * lun scanning being sequential. */
+	if (scsi_sysfs_target_initialize(sdev))
+		goto out_remove_siblings;
 
-	list_add_tail(&sdev->siblings, &shost->__devices);
-	spin_unlock_irqrestore(shost->host_lock, flags);
 	return sdev;
 
-out_cleanup_transport:
-	if (shost->transportt->cleanup)
-		shost->transportt->cleanup(sdev);
+out_remove_siblings:
+	spin_lock_irqsave(shost->host_lock, flags);
+	list_del(&sdev->siblings);
+	list_del(&sdev->same_target_siblings);
+	spin_unlock_irqrestore(shost->host_lock, flags);
 out_cleanup_slave:
 	if (shost->hostt->slave_destroy)
 		shost->hostt->slave_destroy(sdev);
@@ -586,11 +570,6 @@
 	if (*bflags & BLIST_NOSTARTONADD)
 		sdev->no_start_on_add = 1;
 
-	/* NOTE: this target initialisation code depends critically on
-	 * lun scanning being sequential. */
-	if(scsi_sysfs_target_initialize(sdev))
-		return SCSI_SCAN_NO_RESPONSE;
-
 	if (*bflags & BLIST_SINGLELUN)
 		sdev->single_lun = 1;
 
@@ -733,8 +712,6 @@
 	} else {
 		if (sdev->host->hostt->slave_destroy)
 			sdev->host->hostt->slave_destroy(sdev);
-		if (sdev->host->transportt->cleanup)
-			sdev->host->transportt->cleanup(sdev);
 		put_device(&sdev->sdev_gendev);
 	}
  out:
@@ -1293,7 +1270,5 @@
 
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
-	if (sdev->host->transportt->cleanup)
-		sdev->host->transportt->cleanup(sdev);
 	put_device(&sdev->sdev_gendev);
 }
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	2004-09-10 07:44:30 +00:00
+++ b/drivers/scsi/scsi_sysfs.c	2004-09-10 07:44:30 +00:00
@@ -160,14 +160,19 @@
 
 	spin_lock_irqsave(sdev->host->host_lock, flags);
 	/* If we're the last LUN on the target, destroy the target */
-	delete = (list_empty(&sdev->same_target_siblings) && parent);
+	delete = list_empty(&sdev->same_target_siblings);
 	list_del(&sdev->siblings);
 	list_del(&sdev->same_target_siblings);
 	list_del(&sdev->starved_entry);
 	spin_unlock_irqrestore(sdev->host->host_lock, flags);
 
 	if (delete) {
-		device_del(parent);
+		struct scsi_target *starget = to_scsi_target(parent);
+		if (!starget->create) {
+			device_del(parent);
+			if (starget->transport_classdev.class)
+				class_device_unregister(&starget->transport_classdev);
+		}
 		put_device(parent);
 	}
 	if (sdev->request_queue)
@@ -454,7 +459,48 @@
 int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 {
 	struct class_device_attribute **attrs;
-	int error, i;
+	struct scsi_target *starget = sdev->sdev_target;
+	struct Scsi_Host *shost = sdev->host;
+	int error, i, create;
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	create = starget->create;
+	starget->create = 0;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+
+	if (create) {
+		error = device_add(&starget->dev);
+		if (error) {
+			printk(KERN_ERR "Target device_add failed\n");
+			return error;
+		}
+		if (starget->transport_classdev.class) {
+			int i;
+			struct class_device_attribute **attrs =
+				sdev->host->transportt->target_attrs;
+
+			error = class_device_add(&starget->transport_classdev);
+			if (error) {
+				dev_printk(KERN_ERR, &starget->dev,
+					   "Target transport add failed\n");
+				return error;
+			}
+
+			/* take a reference for the transport_classdev; this
+			 * is released by the transport_class .release */
+			get_device(&starget->dev);
+			for (i = 0; attrs[i]; i++) {
+				error = class_device_create_file(&starget->transport_classdev,
+								 attrs[i]);
+				if (error) {
+					dev_printk(KERN_ERR, &starget->dev,
+						   "Target transport attr add failed\n");
+					return error;
+				}
+			}
+		}
+	}
 
 	if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0)
 		return error;
@@ -474,7 +520,6 @@
 	/* take a reference for the sdev_classdev; this is
 	 * released by the sdev_class .release */
 	get_device(&sdev->sdev_gendev);
-
 	if (sdev->transport_classdev.class) {
 		error = class_device_add(&sdev->transport_classdev);
 		if (error)
@@ -509,7 +554,7 @@
 	}
 
  	if (sdev->transport_classdev.class) {
- 		attrs = sdev->host->transportt->attrs;
+ 		attrs = sdev->host->transportt->device_attrs;
  		for (i = 0; attrs[i]; i++) {
  			error = class_device_create_file(&sdev->transport_classdev,
  							 attrs[i]);
@@ -553,8 +598,6 @@
 	scsi_device_set_state(sdev, SDEV_DEL);
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
-	if (sdev->host->transportt->cleanup)
-		sdev->host->transportt->cleanup(sdev);
 	put_device(&sdev->sdev_gendev);
 
 out:
@@ -641,6 +684,29 @@
 		}
 	}
 
+	class_device_initialize(&shost->transport_classdev);
+	shost->transport_classdev.class = shost->transportt->host_class;
+	shost->transport_classdev.dev = &shost->shost_gendev;
+	snprintf(shost->transport_classdev.class_id, BUS_ID_SIZE,
+		 "host%d", shost->host_no);
+
+	if (shost->transport_classdev.class) {
+		struct class_device_attribute **attrs =
+			shost->transportt->host_attrs;
+		error = class_device_add(&shost->transport_classdev);
+		if (error)
+			return error;
+		/* take a reference for the transport_classdev; this
+		 * is released by the transport_class .release */
+		get_device(&shost->shost_gendev);
+		for (i = 0; attrs[i]; i++) {
+ 			error = class_device_create_file(&shost->transport_classdev,
+ 							 attrs[i]);
+ 			if (error)
+				return error;
+ 		}
+ 	}
+
 	return 0;
 }
 
@@ -662,7 +728,7 @@
 
 	class_device_initialize(&sdev->transport_classdev);
 	sdev->transport_classdev.dev = &sdev->sdev_gendev;
-	sdev->transport_classdev.class = sdev->host->transportt->class;
+	sdev->transport_classdev.class = sdev->host->transportt->device_class;
 	snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE,
 		 "%d:%d:%d:%d", sdev->host->host_no,
 		 sdev->channel, sdev->id, sdev->lun);
@@ -672,45 +738,66 @@
 int scsi_sysfs_target_initialize(struct scsi_device *sdev)
 {
 	struct scsi_target *starget = NULL;
-	struct scsi_device *sdev_sibling;
+	struct Scsi_Host *shost = sdev->host;
+	struct scsi_device *device;
 	struct device *dev = NULL;
-	int error;
 	unsigned long flags;
+	int create = 0;
 
-	spin_lock_irqsave(sdev->host->host_lock, flags);
+	spin_lock_irqsave(shost->host_lock, flags);
 	/*
 	 * Search for an existing target for this sdev.
 	 */
-	list_for_each_entry(sdev_sibling, &sdev->same_target_siblings,
-			    same_target_siblings) {
-		if (sdev_sibling->sdev_gendev.parent != NULL) {
-			starget = scsi_target(sdev_sibling);
+	list_for_each_entry(device, &shost->__devices, siblings) {
+		if (device->id == sdev->id &&
+		    device->channel == sdev->channel) {
+			list_add_tail(&sdev->same_target_siblings,
+				      &device->same_target_siblings);
+			sdev->scsi_level = device->scsi_level;
+			starget = device->sdev_target;
 			break;
 		}
 	}
+			
 	if (!starget) {
-		starget = kmalloc(sizeof(*starget), GFP_ATOMIC);
+		const int size = sizeof(*starget) +
+			shost->transportt->target_size;
+		starget = kmalloc(size, GFP_ATOMIC);
 		if (!starget) {
 			printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
-			spin_unlock_irqrestore(sdev->host->host_lock,
+			spin_unlock_irqrestore(shost->host_lock,
 					       flags);
 			return -ENOMEM;
 		}
-		memset(starget, 0, sizeof(*starget));
+		memset(starget, 0, size);
 		dev = &starget->dev;
 		device_initialize(dev);
-		dev->parent = &sdev->host->shost_gendev;
+		dev->parent = &shost->shost_gendev;
 		dev->release = scsi_target_dev_release;
 		sprintf(dev->bus_id, "target%d:%d:%d",
-			sdev->host->host_no, sdev->channel, sdev->id);
+			shost->host_no, sdev->channel, sdev->id);
+		class_device_initialize(&starget->transport_classdev);
+		starget->transport_classdev.dev = &starget->dev;
+		starget->transport_classdev.class = shost->transportt->target_class;
+		snprintf(starget->transport_classdev.class_id, BUS_ID_SIZE,
+			 "target%d:%d:%d",
+			 shost->host_no, sdev->channel, sdev->id);
+		starget->id = sdev->id;
+		create = starget->create = 1;
+		/*
+		 * If there wasn't another lun already configured at
+		 * this target, then default this device to SCSI_2
+		 * until we know better
+		 */
+		sdev->scsi_level = SCSI_2;
 	}
 	get_device(&starget->dev);
 	sdev->sdev_gendev.parent = &starget->dev;
-	spin_unlock_irqrestore(sdev->host->host_lock, flags);
-	if (dev && (error = device_add(dev))) {
-		printk(KERN_ERR "Target device_add failed\n");
-		return error;
-	}
+	sdev->sdev_target = starget;
+	list_add_tail(&sdev->siblings, &shost->__devices);
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	if (create && shost->transportt->target_setup)
+		shost->transportt->target_setup(starget);
 	return 0;
 }
 
diff -Nru a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
--- a/drivers/scsi/scsi_transport_fc.c	2004-09-10 07:44:30 +00:00
+++ b/drivers/scsi/scsi_transport_fc.c	2004-09-10 07:44:30 +00:00
@@ -84,7 +84,7 @@
 	struct scsi_device *sdev = transport_class_to_sdev(cdev);	\
 	struct fc_transport_attrs *tp;					\
 	struct fc_internal *i = to_fc_internal(sdev->host->transportt);	\
-	tp = (struct fc_transport_attrs *)&sdev->transport_data;	\
+	tp = (struct fc_transport_attrs *)&sdev->sdev_data;		\
 	if (i->f->get_##field)						\
 		i->f->get_##field(sdev);				\
 	return snprintf(buf, 20, format_string, cast tp->field);	\
@@ -156,10 +156,10 @@
 
 	memset(i, 0, sizeof(struct fc_internal));
 
-	i->t.attrs = &i->attrs[0];
-	i->t.class = &fc_transport_class;
-	i->t.setup = &fc_setup_transport_attrs;
-	i->t.size = sizeof(struct fc_transport_attrs);
+	i->t.device_attrs = &i->attrs[0];
+	i->t.device_class = &fc_transport_class;
+	i->t.device_setup = &fc_setup_transport_attrs;
+	i->t.device_size = sizeof(struct fc_transport_attrs);
 	i->f = ft;
 
 	SETUP_ATTRIBUTE_RD(port_id);
diff -Nru a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
--- a/drivers/scsi/scsi_transport_spi.c	2004-09-10 07:44:30 +00:00
+++ b/drivers/scsi/scsi_transport_spi.c	2004-09-10 07:44:30 +00:00
@@ -44,8 +44,8 @@
 #define SPI_MAX_ECHO_BUFFER_SIZE	4096
 
 /* Private data accessors (keep these out of the header file) */
-#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_pending)
-#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_sem)
+#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->sdev_data)->dv_pending)
+#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->sdev_data)->dv_sem)
 
 struct spi_internal {
 	struct scsi_transport_template t;
@@ -127,7 +127,7 @@
 	struct scsi_device *sdev = transport_class_to_sdev(cdev);	\
 	struct spi_transport_attrs *tp;					\
 	struct spi_internal *i = to_spi_internal(sdev->host->transportt); \
-	tp = (struct spi_transport_attrs *)&sdev->transport_data;	\
+	tp = (struct spi_transport_attrs *)&sdev->sdev_data;		\
 	if (i->f->get_##field)						\
 		i->f->get_##field(sdev);				\
 	return snprintf(buf, 20, format_string, tp->field);		\
@@ -185,7 +185,7 @@
 	const char *str;
 	struct spi_internal *i = to_spi_internal(sdev->host->transportt);
 
-	tp = (struct spi_transport_attrs *)&sdev->transport_data;
+	tp = (struct spi_transport_attrs *)&sdev->sdev_data;
 
 	if (i->f->get_period)
 		i->f->get_period(sdev);
@@ -666,10 +666,10 @@
 	memset(i, 0, sizeof(struct spi_internal));
 

-	i->t.attrs = &i->attrs[0];
-	i->t.class = &spi_transport_class;
-	i->t.setup = &spi_setup_transport_attrs;
-	i->t.size = sizeof(struct spi_transport_attrs);
+	i->t.device_attrs = &i->attrs[0];
+	i->t.device_class = &spi_transport_class;
+	i->t.device_setup = &spi_setup_transport_attrs;
+	i->t.device_size = sizeof(struct spi_transport_attrs);
 	i->f = ft;
 
 	SETUP_ATTRIBUTE(period);
diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- a/include/scsi/scsi_device.h	2004-09-10 07:44:30 +00:00
+++ b/include/scsi/scsi_device.h	2004-09-10 07:44:30 +00:00
@@ -120,7 +120,7 @@
 	struct class_device	transport_classdev;
 
 	enum scsi_device_state sdev_state;
-	unsigned long		transport_data[0];
+	unsigned long		sdev_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
 #define	to_scsi_device(d)	\
 	container_of(d, struct scsi_device, sdev_gendev)
@@ -129,6 +129,29 @@
 #define transport_class_to_sdev(class_dev) \
 	container_of(class_dev, struct scsi_device, transport_classdev)
 
+/*
+ * scsi_target: representation of a scsi target, for now, this is only
+ * used for single_lun devices. If no one has active IO to the target,
+ * starget_sdev_user is NULL, else it points to the active sdev.
+ */
+struct scsi_target {
+	struct scsi_device	*starget_sdev_user;
+	struct device		dev;
+	unsigned int		id; /* target id ... replace
+				     * scsi_device.id eventually */
+	struct class_device	transport_classdev;
+	unsigned long		create:1; /* signal that it needs to be added */
+	unsigned long		starget_data[0];
+} __attribute__((aligned(sizeof(unsigned long))));
+
+#define to_scsi_target(d)	container_of(d, struct scsi_target, dev)
+static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
+{
+	return to_scsi_target(sdev->sdev_gendev.parent);
+}
+#define transport_class_to_starget(class_dev) \
+	container_of(class_dev, struct scsi_target, transport_classdev)
+
 extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
 		uint, uint, uint, void *hostdata);
 #define scsi_add_device(host, channel, target, lun) \
@@ -191,6 +214,8 @@
 				 enum scsi_device_state state);
 extern int scsi_device_quiesce(struct scsi_device *sdev);
 extern void scsi_device_resume(struct scsi_device *sdev);
+extern void scsi_target_quiesce(struct scsi_target *);
+extern void scsi_target_resume(struct scsi_target *);
 extern const char *scsi_device_state_name(enum scsi_device_state);
 static inline int scsi_device_online(struct scsi_device *sdev)
 {
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- a/include/scsi/scsi_host.h	2004-09-10 07:44:30 +00:00
+++ b/include/scsi/scsi_host.h	2004-09-10 07:44:30 +00:00
@@ -511,6 +511,13 @@
 	struct list_head sht_legacy_list;
 
 	/*
+	 * Points to the transport data (if any) which is allocated
+	 * separately
+	 */
+	void *shost_data;
+	struct class_device transport_classdev;
+
+	/*
 	 * We should ensure that this is aligned, both for better performance
 	 * and also because some compilers (m68k) don't automatically force
 	 * alignment to a long boundary.
@@ -522,6 +529,9 @@
 	container_of(d, struct Scsi_Host, shost_gendev)
 #define		class_to_shost(d)	\
 	container_of(d, struct Scsi_Host, shost_classdev)
+#define		transport_class_to_shost(class_dev) \
+	container_of(class_dev, struct Scsi_Host, transport_classdev)
+
 
 extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
 extern int scsi_add_host(struct Scsi_Host *, struct device *);
diff -Nru a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
--- a/include/scsi/scsi_transport.h	2004-09-10 07:44:30 +00:00
+++ b/include/scsi/scsi_transport.h	2004-09-10 07:44:30 +00:00
@@ -24,18 +24,27 @@
 	/* The NULL terminated list of transport attributes
 	 * that should be exported.
 	 */
-	struct class_device_attribute **attrs;
+	struct class_device_attribute **device_attrs;
+	struct class_device_attribute **target_attrs;
+	struct class_device_attribute **host_attrs;
+
 
 	/* The transport class that the device is in */
-	struct class *class;
+	struct class *device_class;
+	struct class *target_class;
+	struct class *host_class;
+
+	/* Constructor functions */
+	int (*device_setup)(struct scsi_device *);
+	int (*target_setup)(struct scsi_target *);
+	int (*host_setup)(struct Scsi_Host *);
 
-	/* Constructor/Destructor functions */
-	int (* setup)(struct scsi_device *);
-	void (* cleanup)(struct scsi_device *);
 	/* The size of the specific transport attribute structure (a
 	 * space of this size will be left at the end of the
-	 * scsi_device structure */
-	int	size;
+	 * scsi_* structure */
+	int	device_size;
+	int	target_size;
+	int	host_size;
 };
 
 #endif /* SCSI_TRANSPORT_H */
diff -Nru a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
--- a/include/scsi/scsi_transport_fc.h	2004-09-10 07:44:30 +00:00
+++ b/include/scsi/scsi_transport_fc.h	2004-09-10 07:44:30 +00:00
@@ -31,9 +31,9 @@
 };
 
 /* accessor functions */
-#define fc_port_id(x)	(((struct fc_transport_attrs *)&(x)->transport_data)->port_id)
-#define fc_node_name(x)	(((struct fc_transport_attrs *)&(x)->transport_data)->node_name)
-#define fc_port_name(x)	(((struct fc_transport_attrs *)&(x)->transport_data)->port_name)
+#define fc_port_id(x)	(((struct fc_transport_attrs *)&(x)->sdev_data)->port_id)
+#define fc_node_name(x)	(((struct fc_transport_attrs *)&(x)->sdev_data)->node_name)
+#define fc_port_name(x)	(((struct fc_transport_attrs *)&(x)->sdev_data)->port_name)
 
 /* The functions by which the transport class and the driver communicate */
 struct fc_function_template {
diff -Nru a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
--- a/include/scsi/scsi_transport_spi.h	2004-09-10 07:44:30 +00:00
+++ b/include/scsi/scsi_transport_spi.h	2004-09-10 07:44:30 +00:00
@@ -41,16 +41,16 @@
 };
 
 /* accessor functions */
-#define spi_period(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->period)
-#define spi_offset(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->offset)
-#define spi_width(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->width)
-#define spi_iu(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->iu)
-#define spi_dt(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->dt)
-#define spi_qas(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->qas)
-#define spi_wr_flow(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->wr_flow)
-#define spi_rd_strm(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->rd_strm)
-#define spi_rti(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->rti)
-#define spi_pcomp_en(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->pcomp_en)
+#define spi_period(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->period)
+#define spi_offset(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->offset)
+#define spi_width(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->width)
+#define spi_iu(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->iu)
+#define spi_dt(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->dt)
+#define spi_qas(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->qas)
+#define spi_wr_flow(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->wr_flow)
+#define spi_rd_strm(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->rd_strm)
+#define spi_rti(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->rti)
+#define spi_pcomp_en(x)	(((struct spi_transport_attrs *)&(x)->sdev_data)->pcomp_en)
 
 /* The functions by which the transport class and the driver communicate */
 struct spi_function_template {


      reply	other threads:[~2004-09-10 15:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-07 17:23 [PATCH] add target and host to transport classes James Bottomley
2004-09-10 15:03 ` James Bottomley [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1094828630.1974.2.camel@mulgrave \
    --to=james.bottomley@steeleye.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox