Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Apr 1998 15:42:54 -0700
From:      Parag Patel <parag@cgt.com>
To:        <freebsd-current@FreeBSD.ORG>
Cc:        "Thomas J. Merritt" <tjm@codegen.com>
Subject:   Re: Questions for PCI-IDE driver owner
Message-ID:  <199804092241.PAA17868@mail1.sirius.com>

next in thread | raw e-mail | index | archive | help
Well, since I haven't gotten any responses, I went ahead and changed some 
IDE files the way I thought they should have been done.  Anyone feel like 
trying them out to see if I broke anything, and then hopefully merging 
them into the main sources?  Thanks in advance.

The three files changed are pci/ide_pci.c, i386/isa/wdreg.h, and 
i386/isa/wd.c.  The changes are small but necessary for the CMD646 
controller to work in DMA mode.  The diffs are relative to the current 
release, ie the latest checked-in code.  If there's a preferred format 
for the diffs, please let me know - I just ran "cvs diff -c <file>".


     -- Parag Patel <parag@cgt.com>


Index: ide_pci.c
===================================================================
RCS file: /src/freebsd/src/sys/pci/ide_pci.c,v
retrieving revision 1.9
diff -c -r1.9 ide_pci.c
*** ide_pci.c	1998/02/06 12:14:06	1.9
--- ide_pci.c	1998/04/09 22:19:37
***************
*** 61,66 ****
--- 61,67 ----
  #endif
  
  #define PROMISE_ULTRA33 0x4d33105a
+ #define CMD_PCI646U2_ID	0x06461095
  
  struct ide_pci_cookie;  /* structs vendor_fns, ide_pci_cookie are 
recursive */
  
***************
*** 150,156 ****
  
  
  static void ide_pci_attach(pcici_t tag, int unit);
! static void *ide_pci_candma(int, int);
  static int ide_pci_dmainit(void *, 
  	struct wdparams *, 
  	int (*)(int, void *),
--- 151,157 ----
  
  
  static void ide_pci_attach(pcici_t tag, int unit);
! static void *ide_pci_candma(int, int, int);
  static int ide_pci_dmainit(void *, 
  	struct wdparams *, 
  	int (*)(int, void *),
***************
*** 537,542 ****
--- 538,632 ----
      promise_status
  };
  
+ static void
+ cmd646_status(struct ide_pci_cookie *cookie)
+ {
+ 	int iobase_bm = cookie->iobase_bm;
+ 	pcici_t tag = cookie->tag;
+ 	int i;
+ 
+ 	printf("cmd646_status: %d:%d register dump:\n",
+ 			cookie->ctlr, cookie->unit);
+ 
+ 	for (i = 0; i < 0x80; i += 16)
+ 	{
+ 		printf("    %2x:%8x %8x %8x %8x\n",
+ 				i, pci_conf_read(tag, i), pci_conf_read(tag, i + 4),
+ 				pci_conf_read(tag, i + 8), pci_conf_read(tag, i + 12));
+ 	}
+ }
+ 
+ static int
+ cmd646_dmainit(struct ide_pci_cookie *cookie, 
+ 		struct wdparams *wp, 
+ 		int(*wdcmd)(int, void *),
+ 		void *wdinfo)
+ {
+ 	int iobase_bm = cookie->iobase_bm;
+ 	int ctlr = cookie->ctlr;
+ 	int unit = cookie->unit;
+ 	int mrdmode, bmista, udidetcr, r;
+ 	#define	BMRDMODE	1
+ 	#define	BUDIDETCR	3
+ 
+ 	if (udma_mode(wp) >= 2)
+ 	{
+ 		mrdmode = inb(iobase_bm + BMRDMODE);
+ 		udidetcr = inb(iobase_bm + BUDIDETCR);
+ 		bmista = inb(iobase_bm + BMISTA_PORT);
+ 
+ 		outb(iobase_bm + BMRDMODE, mrdmode | 0x08C);
+ 		outb(iobase_bm + BUDIDETCR, udidetcr | (unit ? 0x2 : 0x1));
+ 		outb(iobase_bm + BMISTA_PORT,
+ 				bmista | (unit ? BMISTA_DMA1CAP : BMISTA_DMA0CAP) |
+ 						BMISTA_DMA_ERROR);
+ 
+ 		if (bootverbose)
+ 			cmd646_status(cookie);
+ 
+ 		/* set the drive to Ultra-DMA mode */
+ 		r = wdcmd(WDDMA_UDMA2, wdinfo);
+ 
+ 		if (!r)
+ 		{
+ 			printf("cmd646_dmainit: setting DMA mode failed\n");
+ 			return 0;
+ 		}
+ 
+ 		return 1;
+ 	}
+ 
+ 	if (pio_mode(wp) >= 4 && mwdma_mode(wp) >= 2)
+ 	{
+ 		bmista = inb(iobase_bm + BMISTA_PORT);
+ 		outb(iobase_bm + BMISTA_PORT,
+ 				bmista | (unit ? BMISTA_DMA1CAP : BMISTA_DMA0CAP) |
+ 						BMISTA_DMA_ERROR);
+ 
+ 		if (bootverbose)
+ 			cmd646_status(cookie);
+ 
+ 		/* set the drive to DMA mode */
+ 		r = wdcmd(WDDMA_MDMA2, wdinfo);
+ 
+ 		if (!r)
+ 		{
+ 			printf("cmd646_dmainit: setting DMA mode failed\n");
+ 			return 0;
+ 		}
+ 
+ 		return 1;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static struct vendor_fns vs_cmd646 = 
+ {
+     cmd646_dmainit, 
+     cmd646_status
+ };
+ 
  /* Intel PIIX, PIIX3, and PIIX4 IDE controller subfunctions */
  static void
  intel_piix_dump_drive(char *ctlr,
***************
*** 916,921 ****
--- 1006,1013 ----
  	    		return ("Promise Ultra/33 IDE controller");
  		if (type == 0x05711106)
  			return ("VIA 82C586x (Apollo) Bus-master IDE controller");
+ 		if (type == CMD_PCI646U2_ID)
+ 	    		return "CMD PCI646U2 Ultra/33 IDE controller";
  		if (data & 0x8000)
  			return ("PCI IDE controller (busmaster capable)");
  #ifndef CMD640
***************
*** 947,953 ****
  	/* set up vendor-specific stuff */
  	type = pci_conf_read(tag, PCI_ID_REG);
  
! 	if (type != PROMISE_ULTRA33) {
  	/* is it busmaster capable?  bail if not */
  		class = pci_conf_read(tag, PCI_CLASS_REG);
  		if (!(class & 0x8000)) {
--- 1039,1045 ----
  	/* set up vendor-specific stuff */
  	type = pci_conf_read(tag, PCI_ID_REG);
  
! 	if (type != PROMISE_ULTRA33 && type != CMD_PCI646U2_ID) {
  	/* is it busmaster capable?  bail if not */
  		class = pci_conf_read(tag, PCI_CLASS_REG);
  		if (!(class & 0x8000)) {
***************
*** 979,991 ****
  		vp = &vs_promise;
  		break;
  
  	default:
  		/* everybody else */
  		vp = &vs_generic;
  		break;
  	}
  
! 	if (type != PROMISE_ULTRA33) {
  		if ((class & 0x100) == 0) {
  			iobase_wd_1 = IO_WD1;
  			altiobase_wd_1 = iobase_wd_1 + wd_altsts;
--- 1071,1088 ----
  		vp = &vs_promise;
  		break;
  
+ 	case CMD_PCI646U2_ID:
+ 		/* CMD PCI646U2-based controllers */
+ 		vp = &vs_cmd646;
+ 		break;
+ 
  	default:
  		/* everybody else */
  		vp = &vs_generic;
  		break;
  	}
  
! 	if (type != PROMISE_ULTRA33 && type != CMD_PCI646U2_ID) {
  		if ((class & 0x100) == 0) {
  			iobase_wd_1 = IO_WD1;
  			altiobase_wd_1 = iobase_wd_1 + wd_altsts;
***************
*** 1187,1199 ****
   * Return a cookie if we can do DMA on the specified (iobase_wd, unit).
   */
  static void *
! ide_pci_candma(int iobase_wd, int unit)
  {
  	struct ide_pci_cookie *cp;
  
  	cp = softc.cookies.lh_first;
  	while(cp) {
! 		if (cp->ctlr == unit &&
  			((iobase_wd == 0) || (cp->iobase_wd == iobase_wd)))
  			break;
  		cp = cp->le.le_next;
--- 1284,1296 ----
   * Return a cookie if we can do DMA on the specified (iobase_wd, unit).
   */
  static void *
! ide_pci_candma(int iobase_wd, int ctlr, int unit)
  {
  	struct ide_pci_cookie *cp;
  
  	cp = softc.cookies.lh_first;
  	while(cp) {
! 		if (cp->ctlr == ctlr && cp->unit == unit &&
  			((iobase_wd == 0) || (cp->iobase_wd == iobase_wd)))
  			break;
  		cp = cp->le.le_next;
***************
*** 1214,1225 ****
  		void *wdinfo)
  {
  	struct ide_pci_cookie *cp = cookie;
  	/* 
  	 * If the controller status indicates that DMA is configured already,
  	 * we flounce happily away
  	 */
! 	if (inb(cp->iobase_bm + BMISTA_PORT) & 
! 	    ((cp->unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP))
  		return 1;
      
  	/* We take a stab at it with device-dependent code */
--- 1311,1325 ----
  		void *wdinfo)
  {
  	struct ide_pci_cookie *cp = cookie;
+ 
  	/* 
  	 * If the controller status indicates that DMA is configured already,
  	 * we flounce happily away
+ 	 * [CMD 646 part should always be initialized]
  	 */
! 	if (cp->type != CMD_PCI646U2_ID &&
! 		inb(cp->iobase_bm + BMISTA_PORT) & 
! 			((cp->unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP))
  		return 1;
      
  	/* We take a stab at it with device-dependent code */
Index: wdreg.h
===================================================================
RCS file: /src/freebsd/src/sys/i386/isa/wdreg.h,v
retrieving revision 1.21
diff -c -r1.21 wdreg.h
*** wdreg.h	1998/01/14 08:08:42	1.21
--- wdreg.h	1998/04/09 22:18:29
***************
*** 261,267 ****
   */
  struct wddma {
  	void	*(*wdd_candma)		/* returns a cookie if PCI */
! 		__P((int ctlr, int drive));
  	int	(*wdd_dmaverify)	/* verify that request is DMA-able */
  		__P((void *cookie, char *vaddr, u_long len, int direction));
  	int	(*wdd_dmaprep)		/* prepare DMA hardware */
--- 261,267 ----
   */
  struct wddma {
  	void	*(*wdd_candma)		/* returns a cookie if PCI */
! 		__P((int iobase, int ctlr, int drive));
  	int	(*wdd_dmaverify)	/* verify that request is DMA-able */
  		__P((void *cookie, char *vaddr, u_long len, int direction));
  	int	(*wdd_dmaprep)		/* prepare DMA hardware */
Index: wd.c
===================================================================
RCS file: /src/freebsd/src/sys/i386/isa/wd.c,v
retrieving revision 1.152
diff -c -r1.152 wd.c
*** wd.c	1998/04/02 02:10:47	1.152
--- wd.c	1998/04/09 22:18:52
***************
*** 297,303 ****
  	du->dk_interface = interface;
  #if !defined(DISABLE_PCI_IDE) && (NPCI > 0)
  	if (wddma[interface].wdd_candma) {
! 		du->dk_dmacookie = wddma[interface].wdd_candma(dvp->id_iobase, 
du->dk_ctrlr);
  		du->dk_port = dvp->id_iobase;
  		du->dk_altport = wddma[interface].wdd_altiobase(du->dk_dmacookie);
  	} else {
--- 297,304 ----
  	du->dk_interface = interface;
  #if !defined(DISABLE_PCI_IDE) && (NPCI > 0)
  	if (wddma[interface].wdd_candma) {
! 		du->dk_dmacookie = wddma[interface].wdd_candma(dvp->id_iobase,
! 				du->dk_ctrlr, unit);
  		du->dk_port = dvp->id_iobase;
  		du->dk_altport = wddma[interface].wdd_altiobase(du->dk_dmacookie);
  	} else {
***************
*** 1070,1076 ****
  	du = wddrives[dkunit(bp->b_dev)];
  
  	/* finish off DMA */
! 	if (du->dk_flags & (DKFL_DMA|DKFL_USEDMA)) {
  		/* XXX SMP boxes sometimes generate an early intr.  Why? */
  		if ((wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie) & 
WDDS_INTERRUPT)
  		    == 0)
--- 1071,1077 ----
  	du = wddrives[dkunit(bp->b_dev)];
  
  	/* finish off DMA */
! 	if (du->dk_flags & DKFL_DMA) {
  		/* XXX SMP boxes sometimes generate an early intr.  Why? */
  		if ((wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie) & 
WDDS_INTERRUPT)
  		    == 0)
***************
*** 1861,1867 ****
  	 * check drive's DMA capability
  	 */
  	if (wddma[du->dk_interface].wdd_candma) {
! 		du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(du->dk_port, 
du->dk_ctrlr);
  	/* does user want this? */
  		if ((du->cfg_flags & WDOPT_DMA) &&
  	    /* have we got a DMA controller? */
--- 1862,1869 ----
  	 * check drive's DMA capability
  	 */
  	if (wddma[du->dk_interface].wdd_candma) {
! 		du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(du->dk_port,
! 				du->dk_ctrlr, du->dk_unit);
  	/* does user want this? */
  		if ((du->cfg_flags & WDOPT_DMA) &&
  	    /* have we got a DMA controller? */

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804092241.PAA17868>