public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add transport class and domain validation to ncr53c8xx
@ 2004-10-05 16:00 James Bottomley
  2004-10-05 19:31 ` Guennadi Liakhovetski
  0 siblings, 1 reply; 2+ messages in thread
From: James Bottomley @ 2004-10-05 16:00 UTC (permalink / raw)
  To: SCSI Mailing List

This basically drags the driver up to date.  The patch applies agains
scsi-target-2.6.

James

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/10/05 10:50:10-05:00 jejb@pashleys.(none) 
#   ncr53c8xx: Convert to using transport classes
#   
#   Convert the driver to export period offset and width.  Pick up
#   domain validation on targets for free
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/zalon.c
#   2004/10/05 10:49:58-05:00 jejb@pashleys.(none) +6 -1
#   ncr53c8xx: Convert to using transport classes
# 
# drivers/scsi/ncr53c8xx.h
#   2004/10/05 10:49:58-05:00 jejb@pashleys.(none) +2 -0
#   ncr53c8xx: Convert to using transport classes
# 
# drivers/scsi/ncr53c8xx.c
#   2004/10/05 10:49:58-05:00 jejb@pashleys.(none) +124 -31
#   ncr53c8xx: Convert to using transport classes
# 
# drivers/scsi/NCR_Q720.c
#   2004/10/05 10:49:58-05:00 jejb@pashleys.(none) +7 -1
#   ncr53c8xx: Convert to using transport classes
# 
# drivers/scsi/Kconfig
#   2004/10/05 10:49:58-05:00 jejb@pashleys.(none) +2 -0
#   ncr53c8xx: Convert to using transport classes
# 
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	2004-10-05 10:51:04 -05:00
+++ b/drivers/scsi/Kconfig	2004-10-05 10:51:04 -05:00
@@ -1028,6 +1028,7 @@
 config SCSI_ZALON
 	tristate "Zalon SCSI support"
 	depends on GSC && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  The Zalon is a GSC/HSC bus interface chip that sits between the
 	  PA-RISC processor and the NCR 53c720 SCSI controller on C100,
@@ -1038,6 +1039,7 @@
 config SCSI_NCR_Q720
 	tristate "NCR Quad 720 MCA SCSI support"
 	depends on MCA && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is a driver for the MicroChannel Quad 720 card produced by
 	  NCR and commonly used in 345x/35xx/4100 class machines.  It always
diff -Nru a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c
--- a/drivers/scsi/NCR_Q720.c	2004-10-05 10:51:04 -05:00
+++ b/drivers/scsi/NCR_Q720.c	2004-10-05 10:51:04 -05:00
@@ -358,13 +358,19 @@
 static int __init
 NCR_Q720_init(void)
 {
-	return mca_register_driver(&NCR_Q720_driver);
+	int ret = ncr53c8xx_init();
+	if (!ret)
+		ret = mca_register_driver(&NCR_Q720_driver);
+	if (ret)
+		ncr53c8xx_exit();
+	return ret;
 }
 
 static void __exit
 NCR_Q720_exit(void)
 {
 	mca_unregister_driver(&NCR_Q720_driver);
+	ncr53c8xx_exit();
 }
 
 module_init(NCR_Q720_init);
diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
--- a/drivers/scsi/ncr53c8xx.c	2004-10-05 10:51:04 -05:00
+++ b/drivers/scsi/ncr53c8xx.c	2004-10-05 10:51:04 -05:00
@@ -123,6 +123,8 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
 
 #include "ncr53c8xx.h"
 
@@ -412,6 +414,8 @@
 **==========================================================
 */
 
+static struct scsi_transport_template *ncr53c8xx_transport_template = NULL;
+
 struct tcb;
 struct lcb;
 struct ccb;
@@ -532,7 +536,7 @@
 	u_char	usrwide;
 	u_char	usrtags;
 	u_char	usrflag;
-	struct scsi_device *sdev;
+	struct scsi_target *starget;
 };
 
 /*========================================================================
@@ -1212,7 +1216,7 @@
 static	void	ncr_init_ccb	(struct ncb *np, struct ccb *cp);
 static	void	ncr_init_tcb	(struct ncb *np, u_char tn);
 static	struct lcb *	ncr_alloc_lcb	(struct ncb *np, u_char tn, u_char ln);
-static	struct lcb *	ncr_setup_lcb	(struct ncb *np, u_char tn, u_char ln);
+static	struct lcb *	ncr_setup_lcb	(struct ncb *np, struct scsi_device *sdev);
 static	void	ncr_getclock	(struct ncb *np, int mult);
 static	void	ncr_selectclock	(struct ncb *np, u_char scntl3);
 static	struct ccb *ncr_get_ccb	(struct ncb *np, u_char tn, u_char ln);
@@ -1232,7 +1236,7 @@
 static	int	ncr_scatter	(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd);
 static	void	ncr_getsync	(struct ncb *np, u_char sfac, u_char *fakp, u_char *scntl3p);
 static	void	ncr_setsync	(struct ncb *np, struct ccb *cp, u_char scntl3, u_char sxfer);
-static	void	ncr_setup_tags	(struct ncb *np, u_char tn, u_char ln);
+static	void	ncr_setup_tags	(struct ncb *np, struct scsi_device *sdev);
 static	void	ncr_setwide	(struct ncb *np, struct ccb *cp, u_char wide, u_char ack);
 static	int	ncr_show_msg	(u_char * msg);
 static  void    ncr_print_msg   (struct ccb *cp, char *label, u_char *msg);
@@ -3363,16 +3367,16 @@
 	struct tcb *tp = &np->target[cp->target];
 	int msglen = 0;
 	int nego = 0;
-	struct scsi_device *sdev = tp->sdev;
+	struct scsi_target *starget = tp->starget;
 
-	if (likely(sdev)) {
+	if (likely(starget)) {
 
 		/*
 		**	negotiate wide transfers ?
 		*/
 
 		if (!tp->widedone) {
-			if (sdev->wdtr) {
+			if (spi_support_wide(starget)) {
 				nego = NS_WIDE;
 			} else
 				tp->widedone=1;
@@ -3384,7 +3388,7 @@
 		*/
 
 		if (!nego && !tp->period) {
-			if (sdev->sdtr) {
+			if (spi_support_sync(starget)) {
 				nego = NS_SYNC;
 			} else {
 				tp->period  =0xffff;
@@ -4273,7 +4277,7 @@
 			if (lp->num_good >= 1000) {
 				lp->num_good = 0;
 				++lp->numtags;
-				ncr_setup_tags (np, cmd->device->id, cmd->device->lun);
+				ncr_setup_tags (np, cmd->device);
 			}
 		}
 	} else if ((cp->host_status == HS_COMPLETE)
@@ -4723,8 +4727,11 @@
 	if (minsync > np->maxsync)
 		minsync = 255;
 
+	if (tp->maxoffs > np->maxoffs)
+		tp->maxoffs = np->maxoffs;
+
 	tp->minsync = minsync;
-	tp->maxoffs = (minsync<255 ? np->maxoffs : 0);
+	tp->maxoffs = (minsync<255 ? tp->maxoffs : 0);
 
 	/*
 	**	period=0: has to negotiate sync transfer
@@ -4978,12 +4985,12 @@
 **==========================================================
 */
 
-static void ncr_setup_tags (struct ncb *np, u_char tn, u_char ln)
+static void ncr_setup_tags (struct ncb *np, struct scsi_device *sdev)
 {
+	unsigned char tn = sdev->id, ln = sdev->lun;
 	struct tcb *tp = &np->target[tn];
 	struct lcb *lp = tp->lp[ln];
 	u_char   reqtags, maxdepth;
-	struct scsi_device *sdev = tp->sdev;
 
 	/*
 	**	Just in case ...
@@ -5939,7 +5946,7 @@
 		if (disc_cnt < lp->numtags) {
 			lp->numtags	= disc_cnt > 2 ? disc_cnt : 2;
 			lp->num_good	= 0;
-			ncr_setup_tags (np, cmd->device->id, cmd->device->lun);
+			ncr_setup_tags (np, cmd->device);
 		}
 		/*
 		**	Requeue the command to the start queue.
@@ -6078,6 +6085,7 @@
 	u_long	dsa    = INL (nc_dsa);
 	u_char	target = INB (nc_sdid) & 0x0f;
 	struct tcb *tp     = &np->target[target];
+	struct scsi_target *starget = tp->starget;
 
 	if (DEBUG_FLAGS & DEBUG_TINY) printk ("I#%d", num);
 
@@ -6235,10 +6243,13 @@
 
 		case NS_SYNC:
 			ncr_setsync (np, cp, 0, 0xe0);
+			spi_period(starget) = 0;
+			spi_offset(starget) = 0;
 			break;
 
 		case NS_WIDE:
 			ncr_setwide (np, cp, 0, 0);
+			spi_width(starget) = 0;
 			break;
 
 		};
@@ -6273,8 +6284,8 @@
 		**	      it CAN transfer synch.
 		*/
 
-		if (ofs && tp->sdev)
-			tp->sdev->sdtr = 1;
+		if (ofs && tp->starget)
+			spi_support_sync(tp->starget) = 1;
 
 		/*
 		**	check values against driver limits.
@@ -6325,18 +6336,23 @@
 					**	Answer wasn't acceptable.
 					*/
 					ncr_setsync (np, cp, 0, 0xe0);
+					spi_period(starget) = 0;
+					spi_offset(starget) = 0;
 					OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
 				} else {
 					/*
 					**	Answer is ok.
 					*/
 					ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
+					spi_period(starget) = per;
+					spi_offset(starget) = ofs;
 					OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
 				};
 				return;
 
 			case NS_WIDE:
 				ncr_setwide (np, cp, 0, 0);
+				spi_width(starget) = 0;
 				break;
 			};
 		};
@@ -6347,6 +6363,8 @@
 		*/
 
 		ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
+		spi_period(starget) = per;
+		spi_offset(starget) = ofs;
 
 		np->msgout[0] = M_EXTENDED;
 		np->msgout[1] = 3;
@@ -6394,8 +6412,8 @@
 		**	      it CAN transfer wide.
 		*/
 
-		if (wide && tp->sdev)
-			tp->sdev->wdtr = 1;
+		if (wide && tp->starget)
+			spi_support_wide(tp->starget) = 1;
 
 		/*
 		**	check values against driver limits.
@@ -6422,18 +6440,22 @@
 					**	Answer wasn't acceptable.
 					*/
 					ncr_setwide (np, cp, 0, 1);
+					spi_width(starget) = 0;
 					OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
 				} else {
 					/*
 					**	Answer is ok.
 					*/
 					ncr_setwide (np, cp, wide, 1);
+					spi_width(starget) = wide;
 					OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
 				};
 				return;
 
 			case NS_SYNC:
 				ncr_setsync (np, cp, 0, 0xe0);
+				spi_period(starget) = 0;
+				spi_offset(starget) = 0;
 				break;
 			};
 		};
@@ -6444,6 +6466,7 @@
 		*/
 
 		ncr_setwide (np, cp, wide, 1);
+		spi_width(starget) = wide;
 
 		np->msgout[0] = M_EXTENDED;
 		np->msgout[1] = 2;
@@ -6573,13 +6596,6 @@
 			ncr_alloc_ccb(np, tn, ln);
 
 		/*
-		**	Tune tag mode if asked by user.
-		*/
-		if (lp->queuedepth != lp->numtags) {
-			ncr_setup_tags(np, tn, ln);
-		}
-			
-		/*
 		**	Look for free CCB
 		*/
 		qp = ncr_list_pop(&lp->free_ccbq);
@@ -6796,7 +6812,6 @@
 	np->ccb->link_ccb = cp;
 
 	list_add(&cp->link_ccbq, &lp->free_ccbq);
-	ncr_setup_tags (np, tn, ln);
 }
 
 /*==========================================================
@@ -6994,11 +7009,12 @@
 **	will play with CHANGE DEFINITION commands. :-)
 **------------------------------------------------------------------------
 */
-static struct lcb *ncr_setup_lcb (struct ncb *np, u_char tn, u_char ln)
+static struct lcb *ncr_setup_lcb (struct ncb *np, struct scsi_device *sdev)
 {
+	unsigned char tn = sdev->id, ln = sdev->lun;
 	struct tcb *tp = &np->target[tn];
 	struct lcb *lp = tp->lp[ln];
-	struct scsi_device *sdev = tp->sdev;
+	struct scsi_target *starget = tp->starget;
 
 	/*
 	**	If no lcb, try to allocate it.
@@ -7009,7 +7025,7 @@
 	/*
 	**	Prepare negotiation
 	*/
-	if (sdev->wdtr || sdev->sdtr)
+	if (spi_support_wide(starget) || spi_support_sync(starget))
 		ncr_negotiate(np, tp);
 
 	/*
@@ -7031,7 +7047,7 @@
 			lp->cb_tags[i] = i;
 		lp->maxnxs = MAX_TAGS;
 		lp->tags_stime = ktime_get(3*HZ);
-		ncr_setup_tags (np, tn, ln);
+		ncr_setup_tags (np, sdev);
 	}
 

@@ -7416,9 +7432,9 @@
 	struct lcb *lp = tp->lp[device->lun];
 	int numtags, depth_to_use;
 
-	tp->sdev = device;
+	tp->starget = device->sdev_target;
 
-	ncr_setup_lcb(np, device->id, device->lun);
+	ncr_setup_lcb(np, device);
 
 	/*
 	**	Select queue depth from driver setup.
@@ -7455,13 +7471,16 @@
 		lp->numtags = lp->maxtags = numtags;
 		lp->scdev_depth = depth_to_use;
 	}
-	ncr_setup_tags (np, device->id, device->lun);
+	ncr_setup_tags (np, device);
 
 #ifdef DEBUG_NCR53C8XX
 	printk("ncr53c8xx_select_queue_depth: host=%d, id=%d, lun=%d, depth=%d\n",
 	       np->unit, device->id, device->lun, depth_to_use);
 #endif
 
+	if (spi_support_sync(device->sdev_target) &&
+	    !spi_initial_dv(device->sdev_target))
+		spi_dv_device(device);
 	return 0;
 }
 
@@ -7856,6 +7875,10 @@
 	instance->dma_channel	= 0;
 	instance->cmd_per_lun	= MAX_TAGS;
 	instance->can_queue	= (MAX_START-4);
+	/* This can happen if you forget to call ncr53c8xx_init from
+	 * your module_init */
+	BUG_ON(!ncr53c8xx_transport_template);
+	instance->transportt	= ncr53c8xx_transport_template;
 	scsi_set_device(instance, device->dev);
 
 	/* Patch script to physical addresses */
@@ -7983,4 +8006,74 @@
 	if (host_data && host_data->ncb)
 		ncr_detach(host_data->ncb);
 	return 1;
+}
+
+static void ncr53c8xx_set_period(struct scsi_target *starget, int period)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ncb *np = ((struct host_data *)shost->hostdata)->ncb;
+	struct tcb *tp = &np->target[starget->id];
+
+	if (period > np->maxsync)
+		period = np->maxsync;
+	else if (period < np->minsync)
+		period = np->minsync;
+
+	tp->usrsync = period;
+
+	ncr_negotiate(np, tp);
+}
+
+static void ncr53c8xx_set_offset(struct scsi_target *starget, int offset)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ncb *np = ((struct host_data *)shost->hostdata)->ncb;
+	struct tcb *tp = &np->target[starget->id];
+
+	if (offset > np->maxoffs)
+		offset = np->maxoffs;
+	else if (offset < 0)
+		offset = 0;
+
+	tp->maxoffs = offset;
+
+	ncr_negotiate(np, tp);
+}
+
+static void ncr53c8xx_set_width(struct scsi_target *starget, int width)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ncb *np = ((struct host_data *)shost->hostdata)->ncb;
+	struct tcb *tp = &np->target[starget->id];
+
+	if (width > np->maxwide)
+		width = np->maxwide;
+	else if (width < 0)
+		width = 0;
+
+	tp->usrwide = width;
+
+	ncr_negotiate(np, tp);
+}
+
+static struct spi_function_template ncr53c8xx_transport_functions =  {
+	.set_period	= ncr53c8xx_set_period,
+	.show_period	= 1,
+	.set_offset	= ncr53c8xx_set_offset,
+	.show_offset	= 1,
+	.set_width	= ncr53c8xx_set_width,
+	.show_width	= 1,
+};
+
+int __init ncr53c8xx_init(void)
+{
+	ncr53c8xx_transport_template = spi_attach_transport(&ncr53c8xx_transport_functions);
+	if (!ncr53c8xx_transport_template)
+		return -ENODEV;
+	return 0;
+}
+
+void ncr53c8xx_exit(void)
+{
+	spi_release_transport(ncr53c8xx_transport_template);
 }
diff -Nru a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h
--- a/drivers/scsi/ncr53c8xx.h	2004-10-05 10:51:04 -05:00
+++ b/drivers/scsi/ncr53c8xx.h	2004-10-05 10:51:04 -05:00
@@ -95,5 +95,7 @@
 extern struct Scsi_Host *ncr_attach(struct scsi_host_template *tpnt, int unit, struct ncr_device *device);
 extern int ncr53c8xx_release(struct Scsi_Host *host);
 irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
+extern int ncr53c8xx_init(void);
+extern void ncr53c8xx_exit(void);
 
 #endif /* NCR53C8XX_H */
diff -Nru a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
--- a/drivers/scsi/zalon.c	2004-10-05 10:51:04 -05:00
+++ b/drivers/scsi/zalon.c	2004-10-05 10:51:04 -05:00
@@ -190,7 +190,12 @@
 
 static int __init zalon7xx_init(void)
 {
-	return register_parisc_driver(&zalon_driver);
+	int ret = ncr53c8xx_init();
+	if (!ret)
+		ret = register_parisc_driver(&zalon_driver);
+	if (ret)
+		ncr53c8xx_exit();
+	return ret;
 }
 
 static void __exit zalon7xx_exit(void)


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Add transport class and domain validation to ncr53c8xx
  2004-10-05 16:00 [PATCH] Add transport class and domain validation to ncr53c8xx James Bottomley
@ 2004-10-05 19:31 ` Guennadi Liakhovetski
  0 siblings, 0 replies; 2+ messages in thread
From: Guennadi Liakhovetski @ 2004-10-05 19:31 UTC (permalink / raw)
  To: James Bottomley; +Cc: SCSI Mailing List

On Tue, 5 Oct 2004, James Bottomley wrote:

> @@ -6235,10 +6243,13 @@
>  
>  		case NS_SYNC:
>  			ncr_setsync (np, cp, 0, 0xe0);
> +			spi_period(starget) = 0;
> +			spi_offset(starget) = 0;

Documentation/CodingStyle:

<quote>
Things to avoid when using macros:

....

3) macros with arguments that are used as l-values: FOO(x) = y; will
bite you if somebody e.g. turns FOO into an inline function.
</quote>

A trivial alternative would be to
#define spi_set_period(st, val) spi_period(st) = (val)
#define spi_set_offset(st, val) spi_offset(st) = (val)
....

Not too important, but, looks a bit nicer:

> +			spi_set_period(starget, 0);
> +			spi_set_offset(starget, 0);

Thanks
Guennadi
---
Guennadi Liakhovetski


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-10-05 20:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-05 16:00 [PATCH] Add transport class and domain validation to ncr53c8xx James Bottomley
2004-10-05 19:31 ` Guennadi Liakhovetski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox