Date: Mon, 25 Jan 1999 07:02:08 -0600 From: "Richard Seaman, Jr." <dick@tar.com> To: grog@lemis.com Cc: Bruce Evans <bde@zeta.org.au>, lcremean@tidalwave.net, current@FreeBSD.ORG Subject: Re: IDE DMA works, I'll be a... Message-ID: <19990125070208.C445@tar.com> In-Reply-To: <199901250608.RAA24912@godzilla.zeta.org.au>; from Bruce Evans on Mon, Jan 25, 1999 at 05:08:19PM %2B1100 References: <199901250608.RAA24912@godzilla.zeta.org.au>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Mon, Jan 25, 1999 at 05:08:19PM +1100, Bruce Evans wrote:
> >> Can you find out what chipset is in this guy? There's support for anything
> >> Intel or VIA, Promise UDMA cards, Cyrix MediaGX, and Acer Aladdin IV/V right
> >> now.
> >
> >See kern/9550. The driver *used* to support my SiS chipset, but it no
> >longer does when both master and slave drive are present since I
> >updated about a week ago. Possibly the same bug is biting Matt.
>
> The driver doesn't have any special support for SiS. It uses generic
> support in some cases, apparently including your case. Recent fixes
> made it actually initialize DMA on the correct drive, but the
> initialization in generic_dmainit() is buggy (it assumes multi-word
> DMA mode 2 but your IDE timing is apparently incompatible with this).
I also experienced breakage with a SiS chip set. The following lines of
code in generic_dmainit in ide_pci.c are the problem:
/* If we're here, then this controller is most likely not set
for UDMA, even if the drive may be. Make the drive wise
up. */
if(!wdcmd(WDDMA_MDMA2, wdinfo))
printf("generic_dmainit: could not set multiword DMA mode!\n");
You can try the attached patch if you want. It seems to work here.
--
Richard Seamman, Jr. email: dick@tar.com
5182 N. Maple Lane phone: 414-367-5450
Chenequa WI 53058 fax: 414-367-5852
[-- Attachment #2 --]
Index: ide_pci.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/ide_pci.c,v
retrieving revision 1.28
diff -c -r1.28 ide_pci.c
*** ide_pci.c 1999/01/17 05:46:25 1.28
--- ide_pci.c 1999/01/20 18:06:54
***************
*** 110,115 ****
--- 110,124 ----
static void
generic_status(struct ide_pci_cookie *cookie);
+ static int
+ sis_dmainit(struct ide_pci_cookie *cookie,
+ struct wdparams *wp,
+ int (*wdcmd)(int, void *),
+ void *wdinfo);
+
+ static void
+ sis_status(struct ide_pci_cookie *cookie);
+
static void
via_571_status(struct ide_pci_cookie *cookie);
***************
*** 279,285 ****
/* If we're here, then this controller is most likely not set
for UDMA, even if the drive may be. Make the drive wise
up. */
!
if(!wdcmd(WDDMA_MDMA2, wdinfo))
printf("generic_dmainit: could not set multiword DMA mode!\n");
return 1;
--- 288,294 ----
/* If we're here, then this controller is most likely not set
for UDMA, even if the drive may be. Make the drive wise
up. */
!
if(!wdcmd(WDDMA_MDMA2, wdinfo))
printf("generic_dmainit: could not set multiword DMA mode!\n");
return 1;
***************
*** 303,308 ****
--- 312,527 ----
generic_status
};
+ /* SiS 5591 */
+
+ static int
+ sis_dmainit(struct ide_pci_cookie *cookie,
+ struct wdparams *wp,
+ int(*wdcmd)(int, void *),
+ void *wdinfo)
+ {
+ int r;
+ unsigned int workword, new, mask;
+ int ctlr, unit;
+ int iobase_bm;
+ pcici_t tag;
+ int unitno;
+
+ unit = cookie->unit;
+ ctlr = cookie->ctlr;
+ iobase_bm = cookie->iobase_bm;
+ tag = cookie->tag;
+
+ unitno = ctlr * 2 + unit;
+
+ if (udma_mode(wp) >= 2) {
+ workword = pci_conf_read(tag, ctlr * 4 + 0x40);
+
+ /* These settings are a little arbitrary. They're taken from my
+ * system, where the BIOS has already set the values, but where
+ * we don't detect that we're initialized because the
+ * BMISTA_DMA?CAP values aren't set by the BIOS.
+ * 0x8000 turns on UDMA
+ * 0x2000 sets UDMA cycle time to 2 PCI clocks for data out
+ * 0x0300 sets DATC to 3 PCI clocks
+ * 0x0001 sets DRTC to 1 PCI clock
+ */
+ if (unit) {
+ mask = 0x0000ffff;
+ new = 0xa3010000;
+ } else {
+ mask = 0xffff0000;
+ new = 0x0000a301;
+ }
+
+ workword &= mask;
+ workword |= new;
+
+ pci_conf_write(tag, ctlr * 4 + 0x40, workword);
+
+ outb(iobase_bm + BMISTA_PORT,
+ (inb(iobase_bm + BMISTA_PORT) | ((unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP)));
+
+ if (bootverbose)
+ printf("SiS 5591 dmainit: %s drive %d setting ultra DMA mode 2\n",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1);
+ r = wdcmd(WDDMA_UDMA2, wdinfo);
+ if (!r) {
+ printf("SiS 5591 dmainit: %s drive %d setting DMA mode failed\n",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1);
+ return 0;
+ }
+
+ if (bootverbose)
+ sis_status(cookie);
+
+ return 1;
+
+ }
+
+ /* otherwise, try and program it for MW DMA mode 2 */
+ else if (mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4) {
+ workword = pci_conf_read(tag, ctlr * 4 + 0x40);
+
+ /* These settings are a little arbitrary. They're taken from my
+ * system, where the BIOS has already set the values, but where
+ * we don't detect that we're initialized because the
+ * BMISTA_DMA?CAP values aren't set by the BIOS.
+ * 0x0300 sets DATC to 3 PCI clocks
+ * 0x0001 sets DRTC to 1 PCI clock
+ */
+ if (unit) {
+ mask = 0x0000ffff;
+ new = 0x03010000;
+ } else {
+ mask = 0xffff0000;
+ new = 0x00000301;
+ }
+
+ workword &= mask;
+ workword |= new;
+
+ pci_conf_write(tag, ctlr * 4 + 0x40, workword);
+
+ outb(iobase_bm + BMISTA_PORT,
+ (inb(iobase_bm + BMISTA_PORT) | ((unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP)));
+
+ /* Set multiword DMA mode 2 on drive */
+ if (bootverbose)
+ printf("SiS 5591 dmainit: %s drive %d setting multiword DMA mode 2\n",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1);
+ r = wdcmd(WDDMA_MDMA2, wdinfo);
+ if (!r) {
+ printf("SiS 5591 dmainit: %s drive %d setting DMA mode failed\n",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1);
+ return 0;
+ }
+
+ if (bootverbose)
+ sis_status(cookie);
+
+ return 1;
+
+ }
+ return 0;
+ }
+
+ static void
+ sis_status(struct ide_pci_cookie *cookie)
+ {
+ int iobase_wd;
+ int ctlr, unit;
+ int iobase_bm;
+ pcici_t tag;
+ pcidi_t type;
+ u_int word40[5];
+ int i, unitno;
+ int DRTC, DATC;
+ int val;
+
+ iobase_wd = cookie->iobase_wd;
+ unit = cookie->unit;
+ ctlr = cookie->ctlr;
+ iobase_bm = cookie->iobase_bm;
+ tag = cookie->tag;
+ type = cookie->type;
+
+ unitno = ctlr * 2 + unit;
+
+ for (i=0; i<5; i++) {
+ word40[i] = pci_conf_read(tag, i * 4 + 0x40);
+ }
+
+ DRTC = word40[ctlr] >> (16 * unit);
+ DATC = word40[ctlr] >> (8 + 16*unit);
+
+ if (unitno == 0) {
+ if ((word40[4] & 0x80000) == 0) {
+ val = word40[2] & 0xf;
+ if (val == 0)
+ val = 12;
+ else if (val > 11)
+ val++;
+ printf ("SiS 5591 status: CRTC %d PCICLK, ", val);
+ val = (word40[2] >> 8) & 0x7;
+ if (val == 0)
+ val = 8 ;
+ else if (val > 6)
+ val = 12;
+ printf ("CATC %d PCICLK, applies to all IDE devices\n", val);
+ } else {
+ printf ("SiS 5591 status: CRTC and CATC timings are per device, taken from DRTC and DATC\n");
+ }
+ printf ("SiS 5591 status: burst cycles %s, fast post write control %s\n",
+ ((word40[2] >> 16) & 0x80) ? "enabled" : "disabled",
+ ((word40[2] >> 16) & 0x20) ? "enabled" : "disabled");
+
+ }
+ val = DRTC & 0xf;
+ if (val == 0)
+ val = 12;
+ else if (val > 11)
+ val++;
+ printf ("SiS 5591 status: %s drive %d DRTC %d PCICLK,",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1,
+ val);
+ val = DATC & 0x7;
+ if (val == 0)
+ val = 8 ;
+ else if (val > 6)
+ val = 12;
+ printf (" DATC %d PCICLK\n", val);
+ printf ("SiS 5591 status: %s drive %d Ultra DMA %s",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1,
+ (DATC & 0x80) ? "enabled" : "disabled\n");
+ if (DATC & 0x80)
+ printf (", %d PCICLK data out\n", ((DATC >> 5) & 0x3) + 1);
+ printf ("SiS 5591 status: %s drive %d postwrite %s, prefetch %s prefetch count is %d\n",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1,
+ ((word40[2] >> (28 + unitno)) & 1) ? "enabled" : "disabled",
+ ((word40[2] >> (24 + unitno)) & 1) ? "enabled" : "disabled",
+ (word40[3] >> (16 * ctlr)) & 0xffff);
+ printf ("SiS 5591 status: %s drive %d has%s been configured for DMA\n",
+ unitno < 2 ? "primary" : "secondary",
+ unitno & 1,
+ (inb(iobase_bm + BMISTA_PORT) & ((unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP)) ?
+ " " : " not");
+ }
+
+ static struct vendor_fns vs_sis =
+ {
+ sis_dmainit,
+ sis_status
+ };
+
+
/* VIA Technologies "82C571" PCI-IDE controller core */
static void
***************
*** 1169,1174 ****
--- 1388,1395 ----
return ("Cyrix 5530 Bus-master IDE controller");
if (type == 0x522910b9)
return ("Acer Aladdin IV/V (M5229) Bus-master IDE controller");
+ if (type == 0x55131039)
+ return ("SiS 5591 Bus-master IDE Controller");
if (data & 0x8000)
return ("PCI IDE controller (busmaster capable)");
#ifndef CMD640
***************
*** 1238,1243 ****
--- 1459,1467 ----
break;
case 0x522910B9: /* Acer Aladdin IV/V (M5229) */
vp = &vs_acer;
+ break;
+ case 0x55131039: /* SiS 5591 */
+ vp = &vs_sis;
break;
default:
/* everybody else */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990125070208.C445>
