Skip to contentSkip to conversation

attach aic7xxx to the spi transport class.

PATCH In review James Bottomley 2 participants 3 messages Apr 10, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 attach aic7xxx to the spi transport class.

This patch is the beginning of the long process to see if we can make this driver play better.

The first step is simply to attach it to the transport class so you can view and set the transfer parameters.

Next, I intend to plug it into the generic domain validation routines (thus killing the separate ahc dv thread)

Some time later will be killing the internal queueing, since really only the DV state machine uses it and finally plumbing it into the generic tag infrastructure.

If anyone has a 79xx card and wants to play too, this should be a simple cut and paste, doing s/ahc_/ahd_/ in all my functions. The 79xx will also need QAS, IU and all the other ultra320 transport properties ...

James

===== drivers/scsi/aic7xxx/aic7xxx_osm.c 1.63 vs edited =====

drivers/scsi/aic7xxx/aic7xxx_osm.c +163 -0
@@ -122,6 +122,10 @@
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include <scsi/scsicam.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
+
+static struct scsi_transport_template *ahc_linux_transport_template = NULL;
 
 /*
  * Include aiclib.c as part of our
@@ -1728,6 +1732,8 @@
 	ahc_linux_start_dv(ahc);
 	ahc_unlock(ahc, &s);
 
+	host->transportt = ahc_linux_transport_template;
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 	scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
 	scsi_scan_host(host);
@@ -4990,13 +4996,169 @@
 
 static void ahc_linux_exit(void);
 
+static void ahc_linux_get_period(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	spi_period(starget) = tinfo->curr.period;
+}
+
+static void ahc_linux_set_period(struct scsi_target *starget, int period)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	struct ahc_devinfo devinfo;
+	unsigned int ppr_options = tinfo->curr.ppr_options;
+	unsigned long flags;
+	struct ahc_syncrate *syncrate;
+
+	ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+			    starget->channel + 'A', ROLE_INITIATOR);
+	syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
+	ahc_lock(ahc, &flags);
+	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+			 ppr_options, AHC_TRANS_GOAL, FALSE);
+	ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_offset(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	spi_offset(starget) = tinfo->curr.offset;
+}
+
+static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	struct ahc_devinfo devinfo;
+	unsigned int ppr_options = tinfo->curr.ppr_options;
+	unsigned int period = tinfo->curr.period;
+	unsigned long flags;
+	struct ahc_syncrate *syncrate;
+
+	ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+			    starget->channel + 'A', ROLE_INITIATOR);
+	syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
+	ahc_lock(ahc, &flags);
+	ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
+			 ppr_options, AHC_TRANS_GOAL, FALSE);
+	ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_width(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	spi_width(starget) = tinfo->curr.width;
+}
+
+static void ahc_linux_set_width(struct scsi_target *starget, int width)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_devinfo devinfo;
+	unsigned long flags;
+
+	ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+			    starget->channel + 'A', ROLE_INITIATOR);
+	ahc_lock(ahc, &flags);
+	ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
+	ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_dt(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
+}
+
+static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+	struct ahc_tmode_tstate *tstate;
+	struct ahc_initiator_tinfo *tinfo 
+		= ahc_fetch_transinfo(ahc,
+				      starget->channel + 'A',
+				      shost->this_id, starget->id, &tstate);
+	struct ahc_devinfo devinfo;
+	unsigned int ppr_options = tinfo->curr.ppr_options
+		& ~MSG_EXT_PPR_DT_REQ;
+	unsigned int period = tinfo->curr.period;
+	unsigned long flags;
+	struct ahc_syncrate *syncrate;
+
+	ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+			    starget->channel + 'A', ROLE_INITIATOR);
+	syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+				     dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
+	ahc_lock(ahc, &flags);
+	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+			 ppr_options, AHC_TRANS_GOAL, FALSE);
+	ahc_unlock(ahc, &flags);
+}
+
+static struct spi_function_template ahc_linux_transport_functions = {
+	.get_offset	= ahc_linux_get_offset,
+	.set_offset	= ahc_linux_set_offset,
+	.show_offset	= 1,
+	.get_period	= ahc_linux_get_period,
+	.set_period	= ahc_linux_set_period,
+	.show_period	= 1,
+	.get_width	= ahc_linux_get_width,
+	.set_width	= ahc_linux_set_width,
+	.show_width	= 1,
+	.get_dt		= ahc_linux_get_dt,
+	.set_dt		= ahc_linux_set_dt,
+	.show_dt	= 1,
+};
+
+
+
 static int __init
 ahc_linux_init(void)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions);
+	if (!ahc_linux_transport_template)
+		return -ENODEV;
 	int rc = ahc_linux_detect(&aic7xxx_driver_template);
 	if (rc)
 		return rc;
+	spi_release_transport(ahc_linux_transport_template);
 	ahc_linux_exit();
 	return -ENODEV;
 #else
@@ -5037,6 +5199,7 @@
 #endif
 	ahc_linux_pci_exit();
 	ahc_linux_eisa_exit();
+	spi_release_transport(ahc_linux_transport_template);
 }
 
 module_init(ahc_linux_init);
#1 lore raw
Quoted 3 lines · James Bottomley

If anyone has a 79xx card and wants to play too, this should be a simple cut and paste, doing s/ahc_/ahd_/ in all my functions. The 79xx will also need QAS, IU and all the other ultra320 transport properties ...

I thought QAS and IU were also U160 properties since the sym1010 supports them. We just haven't found any drives yet that're willing to negotiate them ...

Signature · 6 lines
"Next the statesmen will invent cheap lies, putting the blame upon 
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince 
himself that the war is just, and will thank God for the better sleep 
he enjoys after this process of grotesque self-deception." -- Mark Twain
#2 lore raw
Quoted 3 lines · Matthew Wilcox

I thought QAS and IU were also U160 properties since the sym1010 supports them. We just haven't found any drives yet that're willing to negotiate them ...

Theoretically, they are (and the 7xxx has support for them). What I find is that even when I have ultra320 drives willing to do QAS and IU, they refuse to negotiate them except at u320 speeds ... I can put them in, I just don't know how useful they actually are.

James