All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] 2.4 sym53c8xx driver residual problem
@ 2006-10-05 19:50 Jeremy Linton
  0 siblings, 0 replies; only message in thread
From: Jeremy Linton @ 2006-10-05 19:50 UTC (permalink / raw)
  To: linux-scsi; +Cc: groudier

[-- Attachment #1: Type: text/plain, Size: 1229 bytes --]

Hello all,
	I've got an application that depends on the residual data information in 
order to send it to another application.  The basic problem is that if a 
single SCSI transfer size is greater than a single scatter gather region 
(generally ~32k), then the residual length is based on the size of the 
scatter gather regions and not the request size. When the two differ, and 
there is a residual data condition the application computes the transfer size 
incorrectly. 
	The attached patch is against the sym53c8xx.c driver in the 2.4 tree, I 
haven't tested the 2.6 sym53c8xx_2 driver, but a quick glance at the code 
seems to indicate it has the same problem. When I get a chance, I will test 
the 2.6 driver as well, for the same problem. The patch basically saves the 
original request length into a new member in the ccb structure called 
orig_data_len. Then, when the residual len is being computed, it adjusts it 
for the original data request size. 

	BTW: We are using the old sym53c8xx driver instead of the new one, because it 
passes more of our validation tests in 2.4 than the sym53c8xx_2 driver does. 
Our tests use the sg interface exclusively, so I'm not sure about behavior 
with other drivers (st,sd). 




[-- Attachment #2: sym53c.patch --]
[-- Type: text/x-diff, Size: 2431 bytes --]

--- sym53c8xx.c.orig	2006-10-04 18:40:39.132184101 -0500
+++ sym53c8xx.c	2006-10-05 12:20:48.252759592 -0500
@@ -1990,6 +1990,9 @@
 	int		ext_sg;		/* Extreme data pointer, used	*/
 	int		ext_ofs;	/*  to calculate the residual.	*/
 	int		resid;
+	int             orig_data_len;  /* used to calculate the correct*/
+	                                /* resid based on the original  */
+                                        /* data len, not the scatter len*/
 };
 
 #define CCB_PHYS(cp,lbl)	(cp->p_ccb + offsetof(struct ccb, lbl))
@@ -10666,8 +10669,8 @@
 	**	unknown), then no data transfer should have 
 	**	taken place.
 	*/
-	if (cp->phys.header.lastp == NCB_SCRIPTH_PHYS (np, data_io))
-		return cp->data_len;
+	if (cp->phys.header.lastp == NCB_SCRIPTH_PHYS (np, data_io)) 
+		return cp->orig_data_len;
 
 	/*
 	**	If no data transfer occurs, or if the data
@@ -10676,7 +10679,7 @@
 	if (cp->startp == cp->phys.header.lastp ||
 	    ncr_evaluate_dp(np, cp, scr_to_cpu(cp->phys.header.lastp),
 			    &dp_ofs) < 0) {
-		return cp->data_len;
+		return cp->orig_data_len;
 	}
 
 	/*
@@ -10685,14 +10688,13 @@
 	*/
 	dp_sgmin = MAX_SCATTER - cp->segments;
 	resid = -cp->ext_ofs;
-	for (dp_sg = cp->ext_sg; dp_sg < MAX_SCATTER; ++dp_sg) {
+	for (dp_sg = cp->ext_sg; dp_sg < MAX_SCATTER; ++dp_sg) 	{
 		tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
 		resid += (tmp & 0xffffff);
 	}
-
-	/*
-	**	Hopefully, the result is not too wrong.
-	*/
+	
+	/* adjust based on original data length */
+	resid=cp->orig_data_len-(cp->data_len-resid);
 	return resid;
 }
 
@@ -12096,6 +12098,7 @@
 	int segment;
 
 	cp->data_len = cmd->request_bufflen;
+	cp->orig_data_len = cmd->request_bufflen;
 
 	if (cmd->request_bufflen) {
 		dma_addr_t baddr = map_scsi_single_data(np, cmd);
@@ -12136,6 +12139,7 @@
 	int use_sg = (int) cmd->use_sg;
 
 	cp->data_len = 0;
+	cp->orig_data_len = cmd->request_bufflen;
 
 	if (!use_sg)
 		segn = ncr_scatter_no_sglist(np, cp, cmd);
@@ -12175,6 +12179,7 @@
 	int use_sg = (int) cmd->use_sg;
 
 	cp->data_len = 0;
+	cp->orig_data_len = cmd->request_bufflen;
 
 	if (!use_sg)
 		segment = ncr_scatter_no_sglist(np, cp, cmd);
@@ -12191,9 +12196,7 @@
 			dma_addr_t baddr = scsi_sg_dma_address(&scatter[segment]);
 			unsigned int len = scsi_sg_dma_len(&scatter[segment]);
 
-			SCATTER_ONE(&data[segment],
-				    baddr,
-				    len);
+			SCATTER_ONE(&data[segment], baddr, len);
 			cp->data_len += len;
 		}
 	}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-10-05 19:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-05 19:50 [PATCH] 2.4 sym53c8xx driver residual problem Jeremy Linton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.