patch-2.3.99-pre1 linux/drivers/scsi/sym53c8xx.c

Next file: linux/drivers/scsi/sym53c8xx_comm.h
Previous file: linux/drivers/scsi/st_options.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.51/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
@@ -55,7 +55,7 @@
 */
 
 /*
-**	February 20 2000, sym53c8xx 1.5j
+**	March 6 2000, sym53c8xx 1.5k
 **
 **	Supported SCSI features:
 **	    Synchronous data transfers
@@ -84,7 +84,7 @@
 /*
 **	Name and version of the driver
 */
-#define SCSI_NCR_DRIVER_NAME	"sym53c8xx - version 1.5j"
+#define SCSI_NCR_DRIVER_NAME	"sym53c8xx - version 1.5k"
 
 /* #define DEBUG_896R1 */
 #define SCSI_NCR_OPTIMIZE_896
@@ -174,6 +174,9 @@
 
 #include "sym53c8xx.h"
 
+#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
+#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
+
 /*
 **	Hmmm... What complex some PCI-HOST bridges actually are, 
 **	despite the fact that the PCI specifications are looking 
@@ -1000,8 +1003,9 @@
 			++mp->nump;
 			return vp;
 		}
+		else
+			__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
 	}
-	__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
 	return 0;
 }
 
@@ -1253,7 +1257,7 @@
 #define	SCSI_DATA_READ		2
 #define	SCSI_DATA_NONE		3
 
-static __inline__ scsi_data_direction(Scsi_Cmnd *cmd)
+static __inline__ int scsi_data_direction(Scsi_Cmnd *cmd)
 {
 	int direction;
 
@@ -2043,7 +2047,7 @@
 #define HF_ACT_PM	(1u<<2)
 #define HF_DP_SAVED	(1u<<3)
 #define HF_AUTO_SENSE	(1u<<4)
-#define HF_DATA_ST	(1u<<5)
+#define HF_DATA_IN	(1u<<5)
 #define HF_PM_TO_C	(1u<<6)
 
 #ifdef SCSI_NCR_IARB_SUPPORT
@@ -2051,6 +2055,11 @@
 #endif
 
 /*
+**	This one is stolen from QU_REG.:)
+*/
+#define HF_DATA_ST	(1u<<7)
+
+/*
 **	First four bytes (script)
 */
 #define  xerr_st       header.scr_st[0]
@@ -2568,8 +2577,12 @@
 	ncrcmd  data_in2	[  4];
 	ncrcmd  data_out	[MAX_SCATTER * SCR_SG_SIZE];
 	ncrcmd  data_out2	[  4];
-	ncrcmd  pm0_data	[ 16];
-	ncrcmd  pm1_data	[ 16];
+	ncrcmd  pm0_data	[ 12];
+	ncrcmd  pm0_data_out	[  6];
+	ncrcmd  pm0_data_end	[  6];
+	ncrcmd  pm1_data	[ 12];
+	ncrcmd  pm1_data_out	[  6];
+	ncrcmd  pm1_data_end	[  6];
 };
 
 /*
@@ -2607,7 +2620,7 @@
 	ncrcmd	sdata_in	[  6];
 	ncrcmd  data_io		[  2];
 	ncrcmd  data_io_com	[  8];
-	ncrcmd  data_io_out	[ 10];
+	ncrcmd  data_io_out	[ 12];
 	ncrcmd	bad_identify	[ 12];
 	ncrcmd	bad_i_t_l	[  4];
 	ncrcmd	bad_i_t_l_q	[  4];
@@ -3146,12 +3159,11 @@
 
 }/*-------------------------< DATAPHASE >------------------*/,{
 #ifdef SCSI_NCR_PROFILE_SUPPORT
-	SCR_REG_REG (HF_REG, SCR_OR, HF_DATA_ST),
+	SCR_REG_REG (QU_REG, SCR_OR, HF_DATA_ST),
 		0,
 #endif
 	SCR_RETURN,
- 		0,
-
+		0,
 }/*-------------------------< MSG_IN >--------------------*/,{
 	/*
 	**	Get the first byte of the message.
@@ -3390,7 +3402,7 @@
 	*/
 	SCR_LOAD_REL (scratcha, 4),
 		offsetof (struct ccb, phys.num_disc),
-	SCR_FROM_REG (HF_REG),
+	SCR_FROM_REG (QU_REG),
 		0,
 	SCR_JUMPR ^ IFTRUE (MASK (HF_DATA_ST, HF_DATA_ST)),
 		8,
@@ -3692,26 +3704,57 @@
 
 }/*-------------------------< PM0_DATA >--------------------*/,{
 	/*
-	**	Keep track we are executing the PM0 DATA 
-	**	mini-script.
+	**	Read our host flags to SFBR, so we will be able 
+	**	to check against the data direction we expect.
+	*/
+	SCR_FROM_REG (HF_REG),
+		0,
+	/*
+	**	Check against actual DATA PHASE.
+	*/
+	SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
+		PADDR (pm0_data_out),
+	/*
+	**	Actual phase is DATA IN.
+	**	Check against expected direction.
+	*/
+	SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),
+		PADDRH (no_data),
+	/*
+	**	Keep track we are moving data from the 
+	**	PM0 DATA mini-script.
 	*/
 	SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),
 		0,
 	/*
-	**	MOVE the data according to the actual 
-	**	DATA direction.
+	**	Move the data to memory.
 	*/
-	SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)),
-		16,
 	SCR_CHMOV_TBL ^ SCR_DATA_IN,
 		offsetof (struct ccb, phys.pm0.sg),
-	SCR_JUMPR,
-		8,
+	SCR_JUMP,
+		PADDR (pm0_data_end),
+}/*-------------------------< PM0_DATA_OUT >----------------*/,{
+	/*
+	**	Actual phase is DATA OUT.
+	**	Check against expected direction.
+	*/
+	SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),
+		PADDRH (no_data),
+	/*
+	**	Keep track we are moving data from the 
+	**	PM0 DATA mini-script.
+	*/
+	SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),
+		0,
+	/*
+	**	Move the data from memory.
+	*/
 	SCR_CHMOV_TBL ^ SCR_DATA_OUT,
 		offsetof (struct ccb, phys.pm0.sg),
+}/*-------------------------< PM0_DATA_END >----------------*/,{
 	/*
-	**	Clear the flag that told we were in 
-	**	the PM0 DATA mini-script.
+	**	Clear the flag that told we were moving  
+	**	data from the PM0 DATA mini-script.
 	*/
 	SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)),
 		0,
@@ -3726,26 +3769,57 @@
 		0,
 }/*-------------------------< PM1_DATA >--------------------*/,{
 	/*
-	**	Keep track we are executing the PM1 DATA 
-	**	mini-script.
+	**	Read our host flags to SFBR, so we will be able 
+	**	to check against the data direction we expect.
+	*/
+	SCR_FROM_REG (HF_REG),
+		0,
+	/*
+	**	Check against actual DATA PHASE.
+	*/
+	SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
+		PADDR (pm1_data_out),
+	/*
+	**	Actual phase is DATA IN.
+	**	Check against expected direction.
+	*/
+	SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),
+		PADDRH (no_data),
+	/*
+	**	Keep track we are moving data from the 
+	**	PM1 DATA mini-script.
 	*/
 	SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),
 		0,
 	/*
-	**	MOVE the data according to the actual 
-	**	DATA direction.
+	**	Move the data to memory.
 	*/
-	SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)),
-		16,
 	SCR_CHMOV_TBL ^ SCR_DATA_IN,
 		offsetof (struct ccb, phys.pm1.sg),
-	SCR_JUMPR,
-		8,
+	SCR_JUMP,
+		PADDR (pm1_data_end),
+}/*-------------------------< PM1_DATA_OUT >----------------*/,{
+	/*
+	**	Actual phase is DATA OUT.
+	**	Check against expected direction.
+	*/
+	SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),
+		PADDRH (no_data),
+	/*
+	**	Keep track we are moving data from the 
+	**	PM1 DATA mini-script.
+	*/
+	SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),
+		0,
+	/*
+	**	Move the data from memory.
+	*/
 	SCR_CHMOV_TBL ^ SCR_DATA_OUT,
 		offsetof (struct ccb, phys.pm1.sg),
+}/*-------------------------< PM1_DATA_END >----------------*/,{
 	/*
-	**	Clear the flag that told we were in 
-	**	the PM1 DATA mini-script.
+	**	Clear the flag that told we were moving  
+	**	data from the PM1 DATA mini-script.
 	*/
 	SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)),
 		0,
@@ -4193,6 +4267,8 @@
 	/*
 	**	Direction is DATA OUT.
 	*/
+	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
+		0,
 	SCR_LOAD_REL  (scratcha, 4),
 		offsetof (struct ccb, phys.header.wlastp),
 	SCR_STORE_REL (scratcha, 4),
@@ -5550,7 +5626,7 @@
 		goto attach_error;
 	NCR_INIT_LOCK_NCB(np);
 	np->pdev  = device->pdev;
-	np->p_ncb = __vtobus(device->pdev, np);
+	np->p_ncb = vtobus(np);
 	host_data->ncb = np;
 
 	/*
@@ -6119,18 +6195,18 @@
 */
 static inline void ncr_queue_done_cmd(ncb_p np, Scsi_Cmnd *cmd)
 {
+	unmap_scsi_data(np, cmd);
 	cmd->host_scribble = (char *) np->done_list;
 	np->done_list = cmd;
 }
 
-static inline void ncr_flush_done_cmds(pcidev_t pdev, Scsi_Cmnd *lcmd)
+static inline void ncr_flush_done_cmds(Scsi_Cmnd *lcmd)
 {
 	Scsi_Cmnd *cmd;
 
 	while (lcmd) {
 		cmd = lcmd;
 		lcmd = (Scsi_Cmnd *) cmd->host_scribble;
-		__unmap_scsi_data(pdev, cmd);
 		cmd->scsi_done(cmd);
 	}
 }
@@ -6411,6 +6487,7 @@
 		cp->phys.header.wlastp	= cpu_to_scr(lastp);
 		/* fall through */
 	case SCSI_DATA_READ:
+		cp->host_flags |= HF_DATA_IN;
 		goalp = NCB_SCRIPT_PHYS (np, data_in2) + 8;
 		lastp = goalp - 8 - (segments * (SCR_SG_SIZE*4));
 		break;
@@ -6488,7 +6565,7 @@
 	/*
 	**	command
 	*/
-	memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);
+	memcpy(cp->cdb_buf, cmd->cmnd, MIN(cmd->cmd_len, sizeof(cp->cdb_buf)));
 	cp->phys.cmd.addr	= cpu_to_scr(CCB_PHYS (cp, cdb_buf[0]));
 	cp->phys.cmd.size	= cpu_to_scr(cmd->cmd_len);
 
@@ -9154,7 +9231,7 @@
 		cp->scsi_status 	= S_ILLEGAL;
 		cp->xerr_status		= 0;
 		cp->phys.extra_bytes	= 0;
-		cp->host_flags		&= HF_PM_TO_C;
+		cp->host_flags		&= (HF_PM_TO_C|HF_DATA_IN);
 
 		break;
 
@@ -9221,7 +9298,7 @@
 		*/
 		cp->sensecmd[0]		= 0x03;
 		cp->sensecmd[1]		= cp->lun << 5;
-		cp->sensecmd[4]		= sizeof(cmd->sense_buffer);
+		cp->sensecmd[4]		= sizeof(cp->sense_buf);
 
 		/*
 		**	sense data
@@ -9243,7 +9320,7 @@
 
 		cp->host_status	= cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
 		cp->scsi_status = S_ILLEGAL;
-		cp->host_flags	= HF_AUTO_SENSE;
+		cp->host_flags	= (HF_AUTO_SENSE|HF_DATA_IN);
 
 		cp->phys.header.go.start =
 			cpu_to_scr(NCB_SCRIPT_PHYS (np, select));
@@ -12616,8 +12693,10 @@
 
      NCR_UNLOCK_NCB(np, flags);
 
-     if (sts != DID_OK)
+     if (sts != DID_OK) {
+          unmap_scsi_data(np, cmd);
           done(cmd);
+     }
 
      return sts;
 }
@@ -12635,7 +12714,6 @@
      unsigned long flags;
      ncb_p np = (ncb_p) dev_id;
      Scsi_Cmnd *done_list;
-     pcidev_t pdev;
 
 #ifdef DEBUG_SYM53C8XX
      printk("sym53c8xx : interrupt received\n");
@@ -12645,7 +12723,6 @@
 
      NCR_LOCK_NCB(np, flags);
      ncr_exception(np);
-     pdev = np->pdev;
      done_list     = np->done_list;
      np->done_list = 0;
      NCR_UNLOCK_NCB(np, flags);
@@ -12654,7 +12731,7 @@
 
      if (done_list) {
           NCR_LOCK_SCSI_DONE(np, flags);
-          ncr_flush_done_cmds(pdev, done_list);
+          ncr_flush_done_cmds(done_list);
           NCR_UNLOCK_SCSI_DONE(np, flags);
      }
 }
@@ -12667,19 +12744,17 @@
 {
      ncb_p np = (ncb_p) npref;
      unsigned long flags;
-     pcidev_t pdev;
      Scsi_Cmnd *done_list;
 
      NCR_LOCK_NCB(np, flags);
      ncr_timeout((ncb_p) np);
-     pdev = np->pdev;
      done_list     = np->done_list;
      np->done_list = 0;
      NCR_UNLOCK_NCB(np, flags);
 
      if (done_list) {
           NCR_LOCK_SCSI_DONE(np, flags);
-          ncr_flush_done_cmds(pdev, done_list);
+          ncr_flush_done_cmds(done_list);
           NCR_UNLOCK_SCSI_DONE(np, flags);
      }
 }
@@ -12697,7 +12772,6 @@
 	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
-	pcidev_t pdev;
 	Scsi_Cmnd *done_list;
 
 #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
@@ -12742,12 +12816,11 @@
 #endif
 
 out:
-	pdev = np->pdev;
 	done_list     = np->done_list;
 	np->done_list = 0;
 	NCR_UNLOCK_NCB(np, flags);
 
-	ncr_flush_done_cmds(pdev, done_list);
+	ncr_flush_done_cmds(done_list);
 
 	return sts;
 }
@@ -12761,7 +12834,6 @@
 	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
-	pcidev_t pdev;
 	Scsi_Cmnd *done_list;
 
 #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
@@ -12785,12 +12857,11 @@
 
 	sts = ncr_abort_command(np, cmd);
 out:
-	pdev = np->pdev;
 	done_list     = np->done_list;
 	np->done_list = 0;
 	NCR_UNLOCK_NCB(np, flags);
 
-	ncr_flush_done_cmds(pdev, done_list);
+	ncr_flush_done_cmds(done_list);
 
 	return sts;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)