[PATCH] transport API for tmscsim

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi

Here's an attempt of a SCSI transport API implementation for tmscsim. 
Please, comment.

Test booted with 3 sync devices on the bus, tried to changed period from 
100ns to 150ns (148 was set), read throughput fell from 7900000 to 5900000 
bytes/sec (measured with dd). Is it about the expected drop?

Not sure if I chose a good place for spi_display_xfer_agreement() - it now 
happens 8 times (!) per target...

Thanks
Guennadi
---
Guennadi Liakhovetski

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@xxxxxx>

Index: linux-2.6.13/drivers/scsi/tmscsim.c
===================================================================
RCS file: /usr/src/cvs/linux-2_6/drivers/scsi/tmscsim.c,v
retrieving revision 1.1.1.9
diff -u -p -r1.1.1.9 tmscsim.c
--- linux-2.6.13/drivers/scsi/tmscsim.c	2 Sep 2005 19:16:29 -0000	1.1.1.9
+++ linux-2.6.13/drivers/scsi/tmscsim.c	9 Sep 2005 20:04:25 -0000
@@ -243,7 +243,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsicam.h>
 #include <scsi/scsi_tcq.h>
-
+#include <scsi/scsi_transport_spi.h>
 
 #define DC390_BANNER "Tekram DC390/AM53C974"
 #define DC390_VERSION "2.1d 2004-05-27"
@@ -277,6 +277,8 @@ static void dc390_EnableMsgOut_Abort(str
 static void dc390_dumpinfo(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB);
 static void dc390_ResetDevParam(struct dc390_acb* pACB);
 
+static struct scsi_transport_template *dc390_transport_template;
+
 static u32	dc390_laststatus = 0;
 static u8	dc390_adapterCnt = 0;
 
@@ -519,7 +521,7 @@ dc390_StartSCSI( struct dc390_acb* pACB,
     /* TODO: error handling */
     DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
     DC390_write8 (Sync_Period, pDCB->SyncPeriod);
-    DC390_write8 (Sync_Offset, pDCB->SyncOffset);
+    DC390_write8 (Sync_Offset, spi_offset(pDCB->starget));
     DC390_write8 (CtrlReg1, pDCB->CtrlR1);
     DC390_write8 (CtrlReg3, pDCB->CtrlR3);
     DC390_write8 (CtrlReg4, pDCB->CtrlR4);
@@ -565,7 +567,7 @@ dc390_StartSCSI( struct dc390_acb* pACB,
 
     if (try_sync_nego)
       { 
-	u8 Sync_Off = pDCB->SyncOffset;
+	u8 Sync_Off = spi_offset(pDCB->starget);
         DEBUG0(printk (KERN_INFO "DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN));
 	pSRB->MsgOutBuf[0] = EXTENDED_MESSAGE;
 	pSRB->MsgOutBuf[1] = 3;
@@ -1038,10 +1040,11 @@ static void __inline__
 dc390_reprog (struct dc390_acb* pACB, struct dc390_dcb* pDCB)
 {
   DC390_write8 (Sync_Period, pDCB->SyncPeriod);
-  DC390_write8 (Sync_Offset, pDCB->SyncOffset);
+  DC390_write8 (Sync_Offset, spi_offset(pDCB->starget));
   DC390_write8 (CtrlReg3, pDCB->CtrlR3);
   DC390_write8 (CtrlReg4, pDCB->CtrlR4);
   dc390_SetXferRate (pACB, pDCB);
+  spi_display_xfer_agreement(pDCB->starget);
 }
 
 
@@ -1123,7 +1126,8 @@ dc390_MsgIn_set_async (struct dc390_acb*
   pSRB->SRBState &= ~DO_SYNC_NEGO;
   pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
   pDCB->SyncPeriod = 0;
-  pDCB->SyncOffset = 0;
+  spi_period(pDCB->starget) = 0;
+  spi_offset(pDCB->starget) = 0;
   //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
   pDCB->CtrlR3 = FAST_CLK;	/* fast clock / normal scsi */
   pDCB->CtrlR4 &= 0x3f;
@@ -1139,7 +1143,7 @@ dc390_MsgIn_set_sync (struct dc390_acb* 
   u16 wval, wval1;
   struct dc390_dcb* pDCB = pSRB->pSRBDCB;
   u8 oldsyncperiod = pDCB->SyncPeriod;
-  u8 oldsyncoffset = pDCB->SyncOffset;
+  u8 oldsyncoffset = spi_offset(pDCB->starget);
   
   if (!(pSRB->SRBState & DO_SYNC_NEGO))
     {
@@ -1168,8 +1172,8 @@ dc390_MsgIn_set_sync (struct dc390_acb* 
 
   pSRB->SRBState &= ~DO_SYNC_NEGO;
   pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
-  pDCB->SyncOffset &= 0x0f0;
-  pDCB->SyncOffset |= pSRB->MsgInBuf[4];
+  spi_offset(pDCB->starget) &= 0xf0;
+  spi_offset(pDCB->starget) |= pSRB->MsgInBuf[4];
   pDCB->NegoPeriod = pSRB->MsgInBuf[3];
 
   wval = (u16) pSRB->MsgInBuf[3];
@@ -1193,14 +1197,15 @@ dc390_MsgIn_set_sync (struct dc390_acb* 
 
   pDCB->CtrlR3 = bval;
   pDCB->SyncPeriod = (u8)wval1;
-  
-  if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
+  spi_period(pDCB->starget) = pSRB->MsgInBuf[3];
+  if ((oldsyncperiod != wval1 || oldsyncoffset != spi_offset(pDCB->starget)) &&
+      pDCB->TargetLUN == 0)
     {
       if (! (bval & FAST_SCSI)) wval1++;
       printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->TargetID, 
-	      40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
+	      40/wval1, ((40%wval1)*10+wval1/2)/wval1, spi_offset(pDCB->starget) & 0x0f);
     }
-  
+ 
   dc390_reprog (pACB, pDCB);
 }
 
@@ -1529,8 +1534,8 @@ mop1:
 	DC390_write8 (ScsiFifo, 3);	/*    ;length of extended msg */
 	DC390_write8 (ScsiFifo, EXTENDED_SDTR);	/*    ; sync nego */
 	DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
-	if (pDCB->SyncOffset & 0x0f)
-		    DC390_write8 (ScsiFifo, pDCB->SyncOffset);
+	if (spi_offset(pDCB->starget) & 0x0f)
+		    DC390_write8 (ScsiFifo, spi_offset(pDCB->starget));
 	else
 		    DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);		    
 	pSRB->SRBState |= DO_SYNC_NEGO;
@@ -1580,7 +1585,8 @@ dc390_SetXferRate( struct dc390_acb* pAC
 		if( ptr->TargetID == bval )
 		{
 		    ptr->SyncPeriod = pDCB->SyncPeriod;
-		    ptr->SyncOffset = pDCB->SyncOffset;
+		    spi_period(ptr->starget) = spi_period(pDCB->starget);
+		    spi_offset(ptr->starget) = spi_offset(pDCB->starget);
 		    ptr->CtrlR3 = pDCB->CtrlR3;
 		    ptr->CtrlR4 = pDCB->CtrlR4;
 		    ptr->SyncMode = pDCB->SyncMode;
@@ -1738,7 +1744,7 @@ dc390_Reselect( struct dc390_acb* pACB )
     pSRB->ScsiPhase = SCSI_NOP0;
     DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
     DC390_write8 (Sync_Period, pDCB->SyncPeriod);
-    DC390_write8 (Sync_Offset, pDCB->SyncOffset);
+    DC390_write8 (Sync_Offset, spi_offset(pDCB->starget));
     DC390_write8 (CtrlReg1, pDCB->CtrlR1);
     DC390_write8 (CtrlReg3, pDCB->CtrlR3);
     DC390_write8 (CtrlReg4, pDCB->CtrlR4);	/* ; Glitch eater */
@@ -2103,7 +2109,8 @@ static void dc390_ResetDevParam( struct 
     {
 	pDCB->SyncMode &= ~SYNC_NEGO_DONE;
 	pDCB->SyncPeriod = 0;
-	pDCB->SyncOffset = 0;
+	spi_period(pDCB->starget) = 0;
+	spi_offset(pDCB->starget) = 0;
 	pDCB->TagMask = 0;
 	pDCB->CtrlR3 = FAST_CLK;
 	pDCB->CtrlR4 &= NEGATE_REQACKDATA | CTRL4_RESERVED | NEGATE_REQACK;
@@ -2180,6 +2187,10 @@ static int dc390_slave_alloc(struct scsi
 	pDCB->pDCBACB = pACB;
 	pDCB->TargetID = id;
 	pDCB->TargetLUN = lun;
+	pDCB->starget = scsi_device->sdev_target;
+
+	spi_width(pDCB->starget) = 0;
+	spi_max_width(pDCB->starget) = 0;
 
 	/*
 	 * Some values are for all LUNs: Copy them 
@@ -2189,9 +2200,10 @@ static int dc390_slave_alloc(struct scsi
 		pDCB->DevMode = pDCB2->DevMode;
 		pDCB->SyncMode = pDCB2->SyncMode & SYNC_NEGO_DONE;
 		pDCB->SyncPeriod = pDCB2->SyncPeriod;
-		pDCB->SyncOffset = pDCB2->SyncOffset;
+		spi_period(pDCB->starget) = spi_period(pDCB2->starget);
+		spi_offset(pDCB->starget) = spi_offset(pDCB2->starget);
 		pDCB->NegoPeriod = pDCB2->NegoPeriod;
-      
+
 		pDCB->CtrlR3 = pDCB2->CtrlR3;
 		pDCB->CtrlR4 = pDCB2->CtrlR4;
 	} else {
@@ -2211,7 +2223,7 @@ static int dc390_slave_alloc(struct scsi
 		pDCB->SyncMode |= SYNC_ENABLE;
 	else {
 		pDCB->SyncMode = 0;
-		pDCB->SyncOffset &= ~0x0f;
+		spi_offset(pDCB->starget) &= ~0x0f;
 	}
 
 	pDCB->CtrlR1 = pACB->pScsiHost->this_id;
@@ -2275,6 +2287,9 @@ static int dc390_slave_configure(struct 
 		scsi_activate_tcq(sdev, acb->TagMaxNum);
 	}
 
+	if (!spi_initial_dv(sdev->sdev_target))
+		spi_dv_device(sdev);
+
 	return 0;
 }
 
@@ -2537,7 +2552,8 @@ static int __devinit dc390_probe_one(str
 	shost->base = io_port;
 	shost->unique_id = io_port;
 	shost->last_reset = jiffies;
-	
+	shost->transportt = dc390_transport_template;
+
 	pACB->pScsiHost = shost;
 	pACB->IOPortBase = (u16) io_port;
 	pACB->IRQLevel = pdev->irq;
@@ -2592,6 +2608,8 @@ static int __devinit dc390_probe_one(str
 	error = scsi_add_host(shost, &pdev->dev);
 	if (error)
 		goto out_free_irq;
+
+	spi_signalling(shost) = SPI_SIGNAL_SE;
 	scsi_scan_host(shost);
 	return 0;
 
@@ -2637,6 +2655,60 @@ static void __devexit dc390_remove_one(s
 	pci_set_drvdata(dev, NULL);
 }
 
+static void dc390_set_offset(struct scsi_target *starget, int offset)
+{
+	if (!spi_period(starget))
+		return;
+
+	if (offset > 15)
+		offset = 15;
+	else if (offset < 0)
+		offset = 0;
+
+	spi_offset(starget) = offset;
+}
+
+static void dc390_set_period(struct scsi_target *starget, int period)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct dc390_acb *pACB = (struct dc390_acb *)shost->hostdata;
+	struct dc390_dcb *pDCB = pACB->pLinkDCB;
+	u16 wval;
+
+	if (!spi_period(starget))
+		return;
+
+	if (!pDCB)
+		return;
+
+	while (pDCB->starget != starget) {
+		pDCB = pDCB->pNextDCB;
+		if (pDCB == pACB->pLinkDCB)
+			return;
+	}
+
+	if (period < pDCB->NegoPeriod)
+		period = pDCB->NegoPeriod;
+
+	/* See calculations in dc390_MsgIn_set_sync() for reference */
+	wval = (period << 2) - 3;
+	wval = ((wval + 24) / 25);
+
+	if (wval >= 8)
+		wval--;
+
+	spi_period(starget) = period;
+	pDCB->SyncPeriod = (u8)wval;
+}
+
+static struct spi_function_template dc390_transport_functions = {
+	.set_offset	= dc390_set_offset,
+	.show_offset	= 1,
+	.set_period	= dc390_set_period,
+	.show_period	= 1,
+	.show_width	= 1,
+};
+
 static struct pci_device_id tmscsim_pci_tbl[] = {
 	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
@@ -2653,6 +2725,8 @@ static struct pci_driver dc390_driver = 
 
 static int __init dc390_module_init(void)
 {
+	int err;
+
 	if (tmscsim[0] == -1 || tmscsim[0] > 15) {
 		tmscsim[0] = 7;
 		tmscsim[1] = 4;
@@ -2663,12 +2737,22 @@ static int __init dc390_module_init(void
 		printk (KERN_INFO "DC390: Using safe settings.\n");
 	}
 
-	return pci_module_init(&dc390_driver);
+	dc390_transport_template = spi_attach_transport(&dc390_transport_functions);
+	if (!dc390_transport_template)
+		return -ENODEV;
+
+	err = pci_register_driver(&dc390_driver);
+
+	if (err)
+		spi_release_transport(dc390_transport_template);
+
+	return err;
 }
 
 static void __exit dc390_module_exit(void)
 {
 	pci_unregister_driver(&dc390_driver);
+	spi_release_transport(dc390_transport_template);
 }
 
 module_init(dc390_module_init);
Index: linux-2.6.13/drivers/scsi/tmscsim.h
===================================================================
RCS file: /usr/src/cvs/linux-2_6/drivers/scsi/tmscsim.h,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 tmscsim.h
--- linux-2.6.13/drivers/scsi/tmscsim.h	13 Jan 2005 21:10:01 -0000	1.1.1.6
+++ linux-2.6.13/drivers/scsi/tmscsim.h	8 Sep 2005 20:51:00 -0000
@@ -82,6 +82,7 @@ struct dc390_dcb
 {
 struct dc390_dcb	*pNextDCB;
 struct dc390_acb	*pDCBACB;
+struct scsi_target	*starget;
 
 /* Queued SRBs */
 struct dc390_srb	*pGoingSRB;
@@ -103,7 +104,6 @@ u8		CtrlR4;
 u8		SyncMode;	/*; 0:async mode */
 u8		NegoPeriod;	/*;for nego. */
 u8		SyncPeriod;	/*;for reg. */
-u8		SyncOffset;	/*;for reg. and nego.(low nibble) */
 };
 
 
-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux