Skip site navigation (1)Skip section navigation (2)
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>