Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 May 2000 10:46:37 -0700
From:      kachun@pathlink.com (Kachun Lee)
To:        freebsd-questions@freebsd.org
Cc:        tom@schottle.net
Subject:   Re: Promise Ultra66 and wdc2/wdc3
Message-ID:  <200005261746.KAA11583@pathlink.net>
In-Reply-To: <392D8D5A.32584CA5@schottle.net>
References:  <392D8D5A.32584CA5@schottle.net>

next in thread | previous in thread | raw e-mail | index | archive | help
In article <392D8D5A.32584CA5@schottle.net>, you say...
>
> [snip]
>
>P.S.  Anybody ever use the Promise FastTrak66.  Does it work under
>FreeBSD?  Does it work as advertised?
>
>P.P.S.  Forgot the particulars:
>3.4-STABLE (cvsup(1) last night.  I know, I know.  4.0-STABLE.)
>Pentium 233MHz MMX, 64MB
>Tyan S1571
>Western Digital Caviar 22100 (only a test drive)
>

If you really do not want to upgrade to 4.0-S/ata, you can try the patch below. 
The wd drive depends on the Promise BIOS to initialize the DMA mode. For BIOS 
v1.02 and later, that did not seem working very reliablity. I had to add code 
to explicitly set the DMA xfer mode since I posted it several months ago.

*** pci/ide_pci.c.00    Sun Aug 29 09:31:32 1999
--- pci/ide_pci.c       Fri May 26 10:11:21 2000
***************
*** 61,66 ****
--- 61,67 ----
  #endif
  
  #define PROMISE_ULTRA33 0x4d33105a
+ #define PROMISE_ULTRA66       0x4d38105a
  
  struct ide_pci_cookie;  /* structs vendor_fns, ide_pci_cookie are recursive 
*/
  
***************
*** 243,248 ****
--- 244,253 ----
  udma_mode(struct wdparams *wp)
  {
        if ((wp->wdp_atavalid & 4) == 4) {
+               if ((wp->wdp_reserved92[1] & 0x2000) == 0x2000) {
+                       if((wp->wdp_udmamode & 0x10) == 0x10) return 4;
+                       if((wp->wdp_udmamode & 0x08) == 0x08) return 3;
+               }
                if ((wp->wdp_udmamode & 4) == 4) return 2;
                if ((wp->wdp_udmamode & 2) == 2) return 1;
                if ((wp->wdp_udmamode & 1) == 1) return 0;
***************
*** 785,796 ****
--- 790,868 ----
      }
  }
  
+ /*
+  * Most of these are defined in wdreg.h... just reenter to be completed.
+  */
+ #define       XFER_PIO0       0x08
+ #define       XFER_PIO1       0x09
+ #define       XFER_PIO2       0x0a
+ #define       XFER_PIO3       0x0b
+ #define       XFER_PIO4       0x0c
+ 
+ #define XFER_SDMA0    0x10
+ #define XFER_SDMA1    0x11
+ #define XFER_SDMA2    0x12
+ 
+ #define       XFER_MDMA0      0x20
+ #define       XFER_MDMA1      0x21
+ #define       XFER_MDMA2      0x22
+ 
+ #define       XFER_UDMA0      0x40
+ #define       XFER_UDMA1      0x41
+ #define       XFER_UDMA2      0x42
+ #define       XFER_UDMA3      0x43
+ #define       XFER_UDMA4      0x44
+ 
+ static int pio_xfer [] = {
+       XFER_PIO0, XFER_PIO1, XFER_PIO2, XFER_PIO3, XFER_PIO4
+ };
+ 
+ static int
+ promise_dmainit(struct        ide_pci_cookie *cookie, 
+       struct  wdparams *wp, 
+       int     (*wdcmd)(int, void *),
+       void    *wdinfo)
+ {
+       int xfer;
+ 
+       if(udma_mode(wp) >= 4) {
+               xfer = XFER_UDMA4;
+       }
+       else if(udma_mode(wp) >= 2) {
+               xfer = XFER_UDMA2;
+       }
+       else if(pio_mode(wp) >= 4 && mwdma_mode(wp) >= 2) {
+               xfer = XFER_MDMA2;
+       }
+       else if(pio_mode(wp) <=4) {
+               xfer = pio_xfer[pio_mode(wp)];
+       }
+       else {
+               printf("promise_dmainit: bad pio_mode: %d\n", pio_mode(wp));
+               return 0;
+       }
+ 
+       if(!wdcmd(xfer, wdinfo)) {
+               printf("promise_dmainit: setting xfer mode failed\n");
+               return 0;
+       }
+ 
+       return 1;
+ }
+ 
+ static struct vendor_fns vs_promise_u66 = 
+ { 
+     promise_dmainit, 
+     promise_status
+ };
+ 
  static struct vendor_fns vs_promise = 
  { 
      generic_dmainit, 
      promise_status
  };
  
+ 
  /* Intel PIIX, PIIX3, and PIIX4 IDE controller subfunctions */
  static void
  intel_piix_dump_drive(char *ctlr,
***************
*** 1217,1222 ****
--- 1289,1295 ----
  
        if ((data & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE &&
            ((data & PCI_SUBCLASS_MASK) == 0x00010000 ||
+               ((data & PCI_SUBCLASS_MASK) == 0x00800000) ||
            ((data & PCI_SUBCLASS_MASK) == 0x00040000))) {
                if (type == 0x71118086)
                        return ("Intel PIIX4 Bus-master IDE controller");
***************
*** 1226,1231 ****
--- 1299,1306 ----
                        return ("Intel PIIX Bus-master IDE controller");
                if (type == PROMISE_ULTRA33)
                        return ("Promise Ultra/33 IDE controller");
+               if (type == PROMISE_ULTRA66)
+                       return ("Promise Ultra/66 IDE controller");
                if (type == 0x05711106)
                      return ("VIA 82C586x (Apollo) Bus-master IDE 
controller");
                if (type == 0x01021078)
***************
*** 1263,1269 ****
        /* 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)) {
--- 1338,1350 ----
        /* set up vendor-specific stuff */
        type = pci_conf_read(tag, PCI_ID_REG);
  
!       switch(type)
!       {
!       case PROMISE_ULTRA33:
!       case PROMISE_ULTRA66:
!               break;
! 
!       default:
        /* is it busmaster capable?  bail if not */
                class = pci_conf_read(tag, PCI_CLASS_REG);
                if (!(class & 0x8000)) {
***************
*** 1290,1300 ****
                vp = &vs_via_571;
                break;
  
        case PROMISE_ULTRA33:
-               /* Promise controllers */
                vp = &vs_promise;
                break;
  
        case 0x01021078: /* cyrix 5530 */
                printf("cyrix 5530\n");
                vp = &vs_cyrix_5530;
--- 1371,1385 ----
                vp = &vs_via_571;
                break;
  
+       /* Promise controllers */
        case PROMISE_ULTRA33:
                vp = &vs_promise;
                break;
  
+       case PROMISE_ULTRA66:
+               vp = &vs_promise_u66;
+               break;
+ 
        case 0x01021078: /* cyrix 5530 */
                printf("cyrix 5530\n");
                vp = &vs_cyrix_5530;
***************
*** 1308,1314 ****
                break;
        }
  
!       if (type != PROMISE_ULTRA33) {
                if ((class & 0x100) == 0) {
                        iobase_wd_1 = IO_WD1;
                        altiobase_wd_1 = iobase_wd_1 + wd_altsts;
--- 1393,1400 ----
                break;
        }
  
!       switch(type) {
!       default:
                if ((class & 0x100) == 0) {
                        iobase_wd_1 = IO_WD1;
                        altiobase_wd_1 = iobase_wd_1 + wd_altsts;
***************
*** 1324,1330 ****
                        iobase_wd_2 = pci_conf_read(tag, 0x18) & 0xfffc;
                        altiobase_wd_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
                }
!       } else {
                iobase_wd_1 = pci_conf_read(tag, 0x10) & 0xfffc;
                altiobase_wd_1 = pci_conf_read(tag, 0x14) & 0xfffc;
                iobase_wd_2 = pci_conf_read(tag, 0x18) & 0xfffc;
--- 1410,1418 ----
                        iobase_wd_2 = pci_conf_read(tag, 0x18) & 0xfffc;
                        altiobase_wd_2 = pci_conf_read(tag, 0x1c) & 0xfffc;
                }
!               break;
!       case PROMISE_ULTRA33:
!       case PROMISE_ULTRA66:
                iobase_wd_1 = pci_conf_read(tag, 0x10) & 0xfffc;
                altiobase_wd_1 = pci_conf_read(tag, 0x14) & 0xfffc;
                iobase_wd_2 = pci_conf_read(tag, 0x18) & 0xfffc;

*******************************************************************
If option ATAPI is set, the wd.c needs to be patched also:

*** i386/isa/wd.c.00    Sun Aug 29 09:07:34 1999
--- i386/isa/wd.c       Tue Feb 22 14:51:41 2000
***************
*** 2302,2310 ****
--- 2302,2312 ----
  #ifdef ATAPI
        if (wdwait(du, 0, TIMEOUT) != 0)
                err = 1;                /* no IDE drive found */
+ #if 0 /* Promise Ultra's would not pass this */
        du->dk_error = inb(du->dk_port + wd_error);
        if (du->dk_error != 0x01)
                err = 1;                /* the drive is incompatible */
+ #endif
  #else
        if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0) {
                printf("wdreset: error1: 0x%x\n", du->dk_error);



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




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