Date: Sun, 2 Feb 1997 16:30:46 +0100 (MET) From: Wolfgang Helbig <helbig@MX.BA-Stuttgart.De> To: hackers@freebsd.org Subject: CMD640b flaw workaround Message-ID: <199702021530.QAA00202@helbig.informatik.ba-stuttgart.de>
next in thread | raw e-mail | index | archive | help
Hi,
This is a patch for wd.c to make the broken CMD640b work with both
IDE channels under FreeBSD.
I tested it with ATAPI-CDROM - HD's on both channels and also with
HD's an both channels.
You have to put
options "CMD640"
in your kernel configuration file to enable the needed serialization
for the CMD640. Sorry Jörg, I know I should have used the driver flags,
but this is a snapshot anyway. I guess the best way to enable this code
is to use the pci-probing. It does recognize the CMD640.
Please test this patch and tell about the results.
Wolfgang Helbig
Index: wd.c
===================================================================
RCS file: /usr/cvsroot/src/sys/i386/isa/wd.c,v
retrieving revision 1.122
diff -r1.122 wd.c
130a131,132
> #define PRIMARY 0
>
239a242,245
> #ifdef CMD640
> static int wdcports[NWDC];
> static int atapictrlr;
> #endif
362a369,372
> #ifdef CMD640
> if (dvp->id_unit == PRIMARY)
> TAILQ_INIT( &wdtab[PRIMARY].controller_queue);
> #else
363a374
> #endif
385a397,399
> #ifdef CMD640
> wdcports[du->dk_ctrlr] = du->dk_port;
> #endif
470c484,490
< atapi_attach (dvp->id_unit, unit, dvp->id_iobase);
---
> if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase)) {
> #ifdef CMD640
> wdcports[unit] = dvp->id_iobase;
> atapictrlr = dvp->id_unit;
> printf("wd: atapictrlr = %d\n", atapictrlr);
> #endif
> }
476a497,499
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 2;
> #else
477a501
> #endif
551a576,578
> #ifdef CMD640
> if (wdtab[PRIMARY].b_active == 0)
> #else
552a580
> #endif
613a642,644
> #ifdef CMD640
> TAILQ_INSERT_TAIL( &wdtab[PRIMARY].controller_queue, bp, b_act);
> #else
614a646
> #endif
639a672,677
> #ifdef CMD640
> if (wdtab[PRIMARY].b_active == 2)
> wdtab[PRIMARY].b_active = 0;
> if (wdtab[PRIMARY].b_active)
> return;
> #else
644d681
< #endif
645a683,687
> #endif
> #endif
> #ifdef CMD640
> bp = wdtab[PRIMARY].controller_queue.tqh_first;
> #else
646a689
> #endif
648a692,694
> #ifdef CMD640
> if (atapi_start && atapi_start (atapictrlr))
> #else
649a696
> #endif
650a698,700
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 3;
> #else
652a703
> #endif
707a759,761
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 1; /* mark controller active */
> #else
708a763
> #endif
719a775,777
> #ifdef CDM640
> if (wdtab[PRIMARY].b_errcnt && (bp->b_flags & B_READ) == 0)
> #else
720a779
> #endif
866c925,929
<
---
> #ifdef CMD640
> if (wdtab[PRIMARY].b_active == 2)
> return; /* intr in wdflushirq() */
> if (!wdtab[PRIMARY].b_active) {
> #else
869a933
> #endif
880a945,947
> #ifdef CMD640
> if (wdtab[PRIMARY].b_active == 3) {
> #else
881a949
> #endif
886a955,957
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 0;
> #else
887a959
> #endif
891a964,966
> #ifdef CMD640
> bp = wdtab[PRIMARY].controller_queue.tqh_first;
> #else
892a968
> #endif
902a979,981
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 0;
> #else
903a983
> #endif
944a1025,1028
> #ifdef CMD640
> if (++wdtab[PRIMARY].b_errcnt < RETRIES) {
> wdtab[PRIMARY].b_active = 0;
> #else
946a1031
> #endif
959a1045,1047
> #ifdef CMD640
> && wdtab[PRIMARY].b_active) {
> #else
960a1049
> #endif
1001a1091,1093
> #ifdef CMD640
> if (wdtab[PRIMARY].b_active) {
> #else
1002a1095
> #endif
1004a1098,1102
> #ifdef CMD640
> if (wdtab[PRIMARY].b_errcnt)
> wderror(bp, du, "soft error");
> wdtab[PRIMARY].b_errcnt = 0;
> #else
1007a1106
> #endif
1012a1112,1114
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 0;
> #else
1013a1116
> #endif
1023a1127,1129
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 0;
> #else
1024a1131
> #endif
1032a1140,1143
> #ifdef CMD640
> TAILQ_REMOVE(&wdtab[PRIMARY].controller_queue, bp, b_act);
> wdtab[PRIMARY].b_errcnt = 0;
> #else
1034a1146
> #endif
1046a1159,1161
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 0;
> #else
1047a1163
> #endif
1053a1170,1172
> #ifdef CMD640
> if (wdtab[PRIMARY].controller_queue.tqh_first)
> #else
1054a1174
> #endif
1076a1197,1200
> #ifdef CMD640
> if (wdtab[PRIMARY].b_active == 2)
> wdtab[PRIMARY].b_active = 0;
> #else
1078a1203
> #endif
1247a1373,1375
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 1;
> #else
1248a1377
> #endif
1261a1391,1393
> #ifdef CMD640
> if (++wdtab[PRIMARY].b_errcnt < RETRIES)
> #else
1262a1395
> #endif
1267a1401,1403
> #ifdef CMD640
> wdtab[PRIMARY].b_errcnt = 0;
> #else
1268a1405
> #endif
1375a1513,1515
> #ifdef CMD640
> wdtab[PRIMARY].b_errcnt += RETRIES;
> #else
1376a1517
> #endif
1753,1756d1893
< #if 0
< /* Mark controller active for if we panic during the dump. */
< wdtab[du->dk_ctrlr].b_active = 1;
< #endif
1902a2040,2045
> #ifdef CMD640
> wdtab[PRIMARY].b_active = 2;
> splx(old_ipl);
> (void)splbio();
> wdtab[PRIMARY].b_active = 0;
> #else
1906a2050
> #endif
1945a2090,2093
> #ifdef CMD640
> while (wdtab[PRIMARY].b_active)
> tsleep((caddr_t)&wdtab[PRIMARY].b_active, PZERO - 1, wmesg, 1);
> #else
1947a2096
> #endif
2022a2172,2201
> #ifdef CMD640
> int
> cmd640_wait(int port)
> {
> int port2;
> int timeout;
> u_char status;
>
> return (0);
> if (NWDC == 1)
> return (0);
>
> if (wdcports[0] == port)
> port2 = wdcports[1];
> else
> port2 = wdcports[0];
> if (port2 == 0)
> return (0);
> for (timeout = TIMEOUT; timeout > 0; timeout--) {
> status = inb(port2 + wd_status);
> if (!(status & WDCS_BUSY))
> return (0);
> DELAY (1000);
> printf("called by port %x\n",port);
> }
> printf("wd: timeout on port %x\n", port2);
> return (-1);
> }
> #endif
>
2032a2212,2216
>
> #ifdef CMD640
> if (cmd640_wait(wdc) != 0)
> return (-1);
> #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702021530.QAA00202>
