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>