Subject: Re: ncr53c8xx driver
To: None <aris@PADL.COM>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-macppc
Date: 12/05/1999 10:18:07
On Sun, 5 Dec 1999 23:37:34 +1100 
 Aris Theocharides <aris@PADL.COM> wrote:

 > Anyone willing to spend some time merging in the OpenBSD ncr53c8xx
 > driver into NetBSD? (The task is a little beyond my ability).

Well, you wouldn't want to merge their driver, since it contains bugs
that the NetBSD driver does not contain.

However, it took all of about 15 minutes to add the byte order changes
that Per Foglestrom made to the OpenBSD version.

 > OpenBSD's driver is based on the current NetBSD one, with additional
 > work in supporting big endian systems.

It's actually not based on the current NetBSD version, but an older one.

 > If there is any way that I can help, please let me know.

Well, here are the diffs.  I can commit them (no affect on little-endian
systems, and I've verified it compiles, at leat :-), but I can't make
any PowerPC boot floppies or anything...

        -- Jason R. Thorpe <thorpej@nas.nasa.gov>

Index: ncr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/ncr.c,v
retrieving revision 1.87
diff -c -r1.87 ncr.c
*** ncr.c	1999/10/08 20:43:45	1.87
--- ncr.c	1999/12/05 18:12:27
***************
*** 337,351 ****
      bus_space_write_4 (np->sc_st, np->sc_sh, (o), (val))
  
  #define	READSCRIPT_OFF(base, off) \
!     (base ? *((INT32 *)((char *)base + (off))) : \
      bus_space_read_4 (np->ram_tag, np->ram_handle, off))
  
  #define	WRITESCRIPT_OFF(base, off, val) \
      do {								\
      	if (base)							\
!     		*((INT32 *)((char *)base + (off))) = (val); 		\
      	else								\
!     		bus_space_write_4 (np->ram_tag, np->ram_handle, off, val); \
      } while (0)
  
  #define	READSCRIPT(r) \
--- 337,351 ----
      bus_space_write_4 (np->sc_st, np->sc_sh, (o), (val))
  
  #define	READSCRIPT_OFF(base, off) \
!     SCR_BO(base ? *((INT32 *)((char *)base + (off))) : \
      bus_space_read_4 (np->ram_tag, np->ram_handle, off))
  
  #define	WRITESCRIPT_OFF(base, off, val) \
      do {								\
      	if (base)							\
!     		*((INT32 *)((char *)base + (off))) = (SCR_BO(val));	\
      	else								\
!     		bus_space_write_4 (np->ram_tag, np->ram_handle, off, SCR_BO(val)); \
      } while (0)
  
  #define	READSCRIPT(r) \
***************
*** 4274,4281 ****
  	**	init data structure
  	*/
  
! 	np->ncb_dma->jump_tcb.l_cmd	= SCR_JUMP;
! 	np->ncb_dma->jump_tcb.l_paddr	= NCB_SCRIPTH_PHYS (np, abort);
  
  	/*
  	**  Get SCSI addr of host adapter (set by bios?).
--- 4274,4281 ----
  	**	init data structure
  	*/
  
! 	np->ncb_dma->jump_tcb.l_cmd	= SCR_BO(SCR_JUMP);
! 	np->ncb_dma->jump_tcb.l_paddr	= SCR_BO(NCB_SCRIPTH_PHYS (np, abort));
  
  	/*
  	**  Get SCSI addr of host adapter (set by bios?).
***************
*** 4838,4850 ****
  	*/
  
  	if (flags & XS_CTL_DATA_IN) {
! 		cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_in);
! 		cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16;
  	} else if (flags & XS_CTL_DATA_OUT) {
! 		cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_out);
! 		cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16;
  	} else {
! 		cp->phys.header.savep = NCB_SCRIPT_PHYS (np, no_data);
  		cp->phys.header.goalp = cp->phys.header.savep;
  	};
  	cp->phys.header.lastp = cp->phys.header.savep;
--- 4838,4852 ----
  	*/
  
  	if (flags & XS_CTL_DATA_IN) {
! 		bus_addr_t sp = NCB_SCRIPT_PHYS (np, data_in);
! 		cp->phys.header.savep = SCR_BO(sp);
! 		cp->phys.header.goalp = SCR_BO(sp + 20 + segments * 16);
  	} else if (flags & XS_CTL_DATA_OUT) {
! 		bus_addr_t sp = NCB_SCRIPT_PHYS (np, data_out);
! 		cp->phys.header.savep = SCR_BO(sp);
! 		cp->phys.header.goalp = SCR_BO(sp + 20 + segments * 16);
  	} else {
! 		cp->phys.header.savep = SCR_BO(NCB_SCRIPT_PHYS (np, no_data));
  		cp->phys.header.goalp = cp->phys.header.savep;
  	};
  	cp->phys.header.lastp = cp->phys.header.savep;
***************
*** 4873,4880 ****
  	/*
  	**	Startqueue
  	*/
! 	cp->phys.header.launch.l_paddr	= NCB_SCRIPT_PHYS (np, select);
! 	cp->phys.header.launch.l_cmd	= SCR_JUMP;
  	/*
  	**	select
  	*/
--- 4875,4882 ----
  	/*
  	**	Startqueue
  	*/
! 	cp->phys.header.launch.l_paddr	= SCR_BO(NCB_SCRIPT_PHYS (np, select));
! 	cp->phys.header.launch.l_cmd	= SCR_BO(SCR_JUMP);
  	/*
  	**	select
  	*/
***************
*** 4884,4904 ****
  	/*
  	**	message
  	*/
! 	cp->phys.smsg.addr		= CCB_PHYS (cp, scsi_smsg);
! 	cp->phys.smsg.size		= msglen;
  
! 	cp->phys.smsg2.addr		= CCB_PHYS (cp, scsi_smsg2);
! 	cp->phys.smsg2.size		= msglen2;
  	/*
  	**	command
  	*/
! 	cp->phys.cmd.addr		= CCB_PHYS (cp, scsi_cmd);
! 	cp->phys.cmd.size		= xp->cmdlen;
  	/*
  	**	sense command
  	*/
! 	cp->phys.scmd.addr		= CCB_PHYS (cp, sensecmd);
! 	cp->phys.scmd.size		= 6;
  	/*
  	**	patch requested size into sense command
  	*/
--- 4886,4906 ----
  	/*
  	**	message
  	*/
! 	cp->phys.smsg.addr		= SCR_BO(CCB_PHYS (cp, scsi_smsg));
! 	cp->phys.smsg.size		= SCR_BO(msglen);
  
! 	cp->phys.smsg2.addr		= SCR_BO(CCB_PHYS (cp, scsi_smsg2));
! 	cp->phys.smsg2.size		= SCR_BO(msglen2);
  	/*
  	**	command
  	*/
! 	cp->phys.cmd.addr		= SCR_BO(CCB_PHYS (cp, scsi_cmd));
! 	cp->phys.cmd.size		= SCR_BO(xp->cmdlen);
  	/*
  	**	sense command
  	*/
! 	cp->phys.scmd.addr		= SCR_BO(CCB_PHYS (cp, sensecmd));
! 	cp->phys.scmd.size		= SCR_BO(6);
  	/*
  	**	patch requested size into sense command
  	*/
***************
*** 4910,4917 ****
  	/*
  	**	sense data
  	*/
! 	cp->phys.sense.addr		= CCB_PHYS (cp, sense_data);
! 	cp->phys.sense.size		= sizeof(struct scsipi_sense_data);
  	/*
  	**	status
  	*/
--- 4912,4919 ----
  	/*
  	**	sense data
  	*/
! 	cp->phys.sense.addr		= SCR_BO(CCB_PHYS (cp, sense_data));
! 	cp->phys.sense.size		= SCR_BO(sizeof(struct scsipi_sense_data));
  	/*
  	**	status
  	*/
***************
*** 4936,4942 ****
  	**	reselect pattern and activate this job.
  	*/
  
! 	cp->jump_ccb.l_cmd	= (SCR_JUMP ^ IFFALSE (DATA (cp->tag)));
  #ifdef __NetBSD__
  	cp->tlimit		= mono_time.tv_sec + xp->timeout / 1000 + 2;
  #else
--- 4938,4944 ----
  	**	reselect pattern and activate this job.
  	*/
  
! 	cp->jump_ccb.l_cmd	= SCR_BO((SCR_JUMP ^ IFFALSE (DATA (cp->tag))));
  #ifdef __NetBSD__
  	cp->tlimit		= mono_time.tv_sec + xp->timeout / 1000 + 2;
  #else
***************
*** 4950,4957 ****
  
  	qidx = np->squeueput + 1;
  	if (qidx >= MAX_START) qidx=0;
! 	np->ncb_dma->squeue [qidx	 ] = NCB_SCRIPT_PHYS (np, idle);
! 	np->ncb_dma->squeue [np->squeueput] = CCB_PHYS (cp, phys);
  	np->squeueput = qidx;
  
  	if(DEBUG_FLAGS & DEBUG_QUEUE)
--- 4952,4959 ----
  
  	qidx = np->squeueput + 1;
  	if (qidx >= MAX_START) qidx=0;
! 	np->ncb_dma->squeue [qidx	  ] = SCR_BO(NCB_SCRIPT_PHYS (np, idle));
! 	np->ncb_dma->squeue [np->squeueput] = SCR_BO(CCB_PHYS (cp, phys));
  	np->squeueput = qidx;
  
  	if(DEBUG_FLAGS & DEBUG_QUEUE)
***************
*** 5062,5073 ****
  	/*
  	**	No Reselect anymore.
  	*/
! 	cp->jump_ccb.l_cmd = (SCR_JUMP);
  
  	/*
  	**	No starting.
  	*/
! 	cp->phys.header.launch.l_paddr= NCB_SCRIPT_PHYS (np, idle);
  
  	/*
  	**	timestamp
--- 5064,5075 ----
  	/*
  	**	No Reselect anymore.
  	*/
! 	cp->jump_ccb.l_cmd = SCR_BO((SCR_JUMP));
  
  	/*
  	**	No starting.
  	*/
! 	cp->phys.header.launch.l_paddr= SCR_BO(NCB_SCRIPT_PHYS (np, idle));
  
  	/*
  	**	timestamp
***************
*** 5389,5395 ****
  	*/
  
  	for (i=0;i<MAX_START;i++)
! 		np -> ncb_dma -> squeue [i] = NCB_SCRIPT_PHYS (np, idle);
  
  	/*
  	**	Start at first entry.
--- 5391,5397 ----
  	*/
  
  	for (i=0;i<MAX_START;i++)
! 		np -> ncb_dma -> squeue [i] = SCR_BO(NCB_SCRIPT_PHYS (np, idle));
  
  	/*
  	**	Start at first entry.
***************
*** 5992,6004 ****
  			**	Disable reselect.
  			**      Remove it from startqueue.
  			*/
! 			cp->jump_ccb.l_cmd = (SCR_JUMP);
  			if (cp->phys.header.launch.l_paddr ==
! 				NCB_SCRIPT_PHYS (np, select)) {
  				printf ("%s: timeout ccb=%p (skip)\n",
  					ncr_name (np), cp);
  				cp->phys.header.launch.l_paddr
! 				= NCB_SCRIPT_PHYS (np, skip);
  			};
  
  			switch (cp->host_status) {
--- 5994,6006 ----
  			**	Disable reselect.
  			**      Remove it from startqueue.
  			*/
! 			cp->jump_ccb.l_cmd = SCR_BO((SCR_JUMP));
  			if (cp->phys.header.launch.l_paddr ==
! 				SCR_BO(NCB_SCRIPT_PHYS (np, select))) {
  				printf ("%s: timeout ccb=%p (skip)\n",
  					ncr_name (np), cp);
  				cp->phys.header.launch.l_paddr
! 				= SCR_BO(NCB_SCRIPT_PHYS (np, skip));
  			};
  
  			switch (cp->host_status) {
***************
*** 6009,6015 ****
  				** still in start queue ?
  				*/
  				if (cp->phys.header.launch.l_paddr ==
! 					NCB_SCRIPT_PHYS (np, skip))
  					continue;
  
  				/* fall through */
--- 6011,6017 ----
  				** still in start queue ?
  				*/
  				if (cp->phys.header.launch.l_paddr ==
! 					SCR_BO(NCB_SCRIPT_PHYS (np, skip)))
  					continue;
  
  				/* fall through */
***************
*** 6603,6610 ****
  
  	if (cmd & 0x10) {	/* Table indirect */
  		tblp = (u_int32_t *) ((char*) &cp->phys + oadr);
! 		olen = tblp[0];
! 		oadr = tblp[1];
  	} else {
  		tblp = (u_int32_t *) 0;
  		olen = READSCRIPT_OFF(vdsp_base, vdsp_off) & 0xffffff;
--- 6605,6612 ----
  
  	if (cmd & 0x10) {	/* Table indirect */
  		tblp = (u_int32_t *) ((char*) &cp->phys + oadr);
! 		olen = SCR_BO(tblp[0]);
! 		oadr = SCR_BO(tblp[1]);
  	} else {
  		tblp = (u_int32_t *) 0;
  		olen = READSCRIPT_OFF(vdsp_base, vdsp_off) & 0xffffff;
***************
*** 6646,6661 ****
  	*/
  
  	newcmd = cp->patch;
! 	if (cp->phys.header.savep == vtophys (newcmd)) newcmd+=4;
  
  	/*
  	**	fillin the commands
  	*/
  
! 	newcmd[0] = ((cmd & 0x0f) << 24) | rest;
! 	newcmd[1] = oadr + olen - rest;
! 	newcmd[2] = SCR_JUMP;
! 	newcmd[3] = nxtdsp;
  
  	if (DEBUG_FLAGS & DEBUG_PHASE) {
  		PRINT_ADDR(cp->xfer);
--- 6648,6663 ----
  	*/
  
  	newcmd = cp->patch;
! 	if (cp->phys.header.savep == SCR_BO(vtophys (newcmd))) newcmd+=4;
  
  	/*
  	**	fillin the commands
  	*/
  
! 	newcmd[0] = SCR_BO(((cmd & 0x0f) << 24) | rest);
! 	newcmd[1] = SCR_BO(oadr + olen - rest);
! 	newcmd[2] = SCR_BO(SCR_JUMP);
! 	newcmd[3] = SCR_BO(nxtdsp);
  
  	if (DEBUG_FLAGS & DEBUG_PHASE) {
  		PRINT_ADDR(cp->xfer);
***************
*** 7203,7210 ****
  		printf ("M_DISCONNECT received, but datapointer not saved:\n"
  			"\tdata=%x save=%x goal=%x.\n",
  			(unsigned) INL (nc_temp),
! 			(unsigned) np->ncb_dma->header.savep,
! 			(unsigned) np->ncb_dma->header.goalp);
  		break;
  
  /*--------------------------------------------------------------------
--- 7205,7212 ----
  		printf ("M_DISCONNECT received, but datapointer not saved:\n"
  			"\tdata=%x save=%x goal=%x.\n",
  			(unsigned) INL (nc_temp),
! 			SCR_BO((unsigned) np->ncb_dma->header.savep),
! 			SCR_BO((unsigned) np->ncb_dma->header.goalp));
  		break;
  
  /*--------------------------------------------------------------------
***************
*** 7428,7456 ****
  		/*
  		**	initialize it.
  		*/
! 		tp->jump_tcb.l_cmd   = (SCR_JUMP^IFFALSE (DATA (0x80 + target)));
  		tp->jump_tcb.l_paddr = np->ncb_dma->jump_tcb.l_paddr;
  
  		tp->getscr[0] =
! 			(np->features & FE_PFEN)? SCR_COPY(1) : SCR_COPY_F(1);
! 		tp->getscr[1] = vtophys (&tp->sval);
! 		tp->getscr[2] = np->paddr + offsetof (struct ncr_reg, nc_sxfer);
! 		tp->getscr[3] =
! 			(np->features & FE_PFEN)? SCR_COPY(1) : SCR_COPY_F(1);
! 		tp->getscr[4] = vtophys (&tp->wval);
! 		tp->getscr[5] = np->paddr + offsetof (struct ncr_reg, nc_scntl3);
  
  		assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
  			offsetof(struct tcb    , sval    )) &3) == 0);
  		assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
  			offsetof(struct tcb    , wval    )) &3) == 0);
  
! 		tp->call_lun.l_cmd   = (SCR_CALL);
! 		tp->call_lun.l_paddr = NCB_SCRIPT_PHYS (np, resel_lun);
  
! 		tp->jump_lcb.l_cmd   = (SCR_JUMP);
! 		tp->jump_lcb.l_paddr = NCB_SCRIPTH_PHYS (np, abort);
! 		np->ncb_dma->jump_tcb.l_paddr = vtophys (&tp->jump_tcb);
  
  		tp->usrtags = SCSI_NCR_DFLT_TAGS;
  		ncr_setmaxtags (tp, tp->usrtags);
--- 7430,7457 ----
  		/*
  		**	initialize it.
  		*/
! 		tp->jump_tcb.l_cmd   = SCR_BO((SCR_JUMP^IFFALSE (DATA (0x80 + target))));
  		tp->jump_tcb.l_paddr = np->ncb_dma->jump_tcb.l_paddr;
  
  		tp->getscr[0] =
! 			(np->features & FE_PFEN)? SCR_BO(SCR_COPY(1)) : SCR_BO(SCR_COPY_F(1));
! 		tp->getscr[1] = SCR_BO(vtophys (&tp->sval));
! 		tp->getscr[2] = SCR_BO(np->paddr + offsetof (struct ncr_reg, nc_sxfer));
! 		tp->getscr[3] = tp->getscr[0];
! 		tp->getscr[4] = SCR_BO(vtophys (&tp->wval));
! 		tp->getscr[5] = SCR_BO(np->paddr + offsetof (struct ncr_reg, nc_scntl3));
  
  		assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
  			offsetof(struct tcb    , sval    )) &3) == 0);
  		assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
  			offsetof(struct tcb    , wval    )) &3) == 0);
  
! 		tp->call_lun.l_cmd   = SCR_BO((SCR_CALL));
! 		tp->call_lun.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, resel_lun));
  
! 		tp->jump_lcb.l_cmd   = SCR_BO((SCR_JUMP));
! 		tp->jump_lcb.l_paddr = SCR_BO(NCB_SCRIPTH_PHYS (np, abort));
! 		np->ncb_dma->jump_tcb.l_paddr = SCR_BO(vtophys (&tp->jump_tcb));
  
  		tp->usrtags = SCSI_NCR_DFLT_TAGS;
  		ncr_setmaxtags (tp, tp->usrtags);
***************
*** 7471,7491 ****
  		**	Initialize it
  		*/
  		bzero (lp, sizeof (*lp));
! 		lp->jump_lcb.l_cmd   = (SCR_JUMP ^ IFFALSE (DATA (lun)));
  		lp->jump_lcb.l_paddr = tp->jump_lcb.l_paddr;
  
! 		lp->call_tag.l_cmd   = (SCR_CALL);
! 		lp->call_tag.l_paddr = NCB_SCRIPT_PHYS (np, resel_tag);
  
! 		lp->jump_ccb.l_cmd   = (SCR_JUMP);
! 		lp->jump_ccb.l_paddr = NCB_SCRIPTH_PHYS (np, aborttag);
  
  		lp->actlink = 1;
  
  		/*
  		**   Chain into LUN list
  		*/
! 		tp->jump_lcb.l_paddr = vtophys (&lp->jump_lcb);
  		tp->lp[lun] = lp;
  
  	}
--- 7472,7492 ----
  		**	Initialize it
  		*/
  		bzero (lp, sizeof (*lp));
! 		lp->jump_lcb.l_cmd   = SCR_BO((SCR_JUMP ^ IFFALSE (DATA (lun))));
  		lp->jump_lcb.l_paddr = tp->jump_lcb.l_paddr;
  
! 		lp->call_tag.l_cmd   = SCR_BO((SCR_CALL));
! 		lp->call_tag.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, resel_tag));
  
! 		lp->jump_ccb.l_cmd   = SCR_BO((SCR_JUMP));
! 		lp->jump_ccb.l_paddr = SCR_BO(NCB_SCRIPTH_PHYS (np, aborttag));
  
  		lp->actlink = 1;
  
  		/*
  		**   Chain into LUN list
  		*/
! 		tp->jump_lcb.l_paddr = SCR_BO(vtophys (&lp->jump_lcb));
  		tp->lp[lun] = lp;
  
  	}
***************
*** 7538,7548 ****
  	/*
  	**	Chain into reselect list
  	*/
! 	cp->jump_ccb.l_cmd   = SCR_JUMP;
  	cp->jump_ccb.l_paddr = lp->jump_ccb.l_paddr;
! 	lp->jump_ccb.l_paddr = CCB_PHYS (cp, jump_ccb);
! 	cp->call_tmp.l_cmd   = SCR_CALL;
! 	cp->call_tmp.l_paddr = NCB_SCRIPT_PHYS (np, resel_tmp);
  
  	/*
  	**	Chain into wakeup list
--- 7539,7549 ----
  	/*
  	**	Chain into reselect list
  	*/
! 	cp->jump_ccb.l_cmd   = SCR_BO(SCR_JUMP);
  	cp->jump_ccb.l_paddr = lp->jump_ccb.l_paddr;
! 	lp->jump_ccb.l_paddr = SCR_BO(CCB_PHYS (cp, jump_ccb));
! 	cp->call_tmp.l_cmd   = SCR_BO(SCR_CALL);
! 	cp->call_tmp.l_paddr = SCR_BO(NCB_SCRIPT_PHYS (np, resel_tmp));
  
  	/*
  	**	Chain into wakeup list
***************
*** 7745,7752 ****
  			(unsigned) segsize,
  			(unsigned) datalen);
  
! 		phys->data[segment].addr = segaddr;
! 		phys->data[segment].size = segsize;
  		segment++;
  	}
  
--- 7746,7753 ----
  			(unsigned) segsize,
  			(unsigned) datalen);
  
! 		phys->data[segment].addr = SCR_BO(segaddr);
! 		phys->data[segment].size = SCR_BO(segsize);
  		segment++;
  	}
  
***************
*** 7820,7826 ****
  	**	Set memory and register.
  	*/
  	ncr_cache = host_wr;
! 	OUTL (nc_temp, ncr_wr);
  	/*
  	**	Start script (exchange values)
  	*/
--- 7821,7827 ----
  	**	Set memory and register.
  	*/
  	ncr_cache = host_wr;
! 	OUTL (nc_temp, SCR_BO(ncr_wr));
  	/*
  	**	Start script (exchange values)
  	*/
***************
*** 7839,7846 ****
  	**	Read memory and register.
  	*/
  	host_rd = ncr_cache;
! 	ncr_rd  = INL (nc_scratcha);
! 	ncr_bk  = INL (nc_temp);
  	/*
  	**	Reset ncr chip
  	*/
--- 7840,7847 ----
  	**	Read memory and register.
  	*/
  	host_rd = ncr_cache;
! 	ncr_rd  = SCR_BO(INL (nc_scratcha));
! 	ncr_bk  = SCR_BO(INL (nc_temp));
  	/*
  	**	Reset ncr chip
  	*/
Index: ncrreg.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/ncrreg.h,v
retrieving revision 1.14
diff -c -r1.14 ncrreg.h
*** ncrreg.h	1997/09/23 02:27:46	1.14
--- ncrreg.h	1999/12/05 18:12:27
***************
*** 293,298 ****
--- 293,305 ----
  
  typedef U_INT32 ncrcmd;
  
+ #if BYTE_ORDER == BIG_ENDIAN
+ #define	SCR_BO(x)	(((x) >> 24) | (((x) >> 8) & 0xff00) | \
+ 			 ((x) << 24) | (((x) & 0xff00) << 8))
+ #else
+ #define	SCR_BO(x)	(x)
+ #endif
+ 
  /*-----------------------------------------------------------
  **
  **	SCSI phases