Date: Tue, 11 Nov 1997 04:12:51 +1100 From: Bruce Evans <bde@zeta.org.au> To: dg@root.com, nnd@itfs.nsk.su Cc: bde@FreeBSD.ORG, hackers@FreeBSD.ORG Subject: Re: Cyclades :( Message-ID: <199711101712.EAA23391@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
> You're right - it appears the Bruce messed up the offsets when he "fixed" >the style/indentation. I don't have a -current machine here with the Cyclom-Y >in it, so I didn't notice the brokeness. Bruce? Oops. Fixed. >>> >--- cy.c.ORIG Sat Nov 1 13:33:19 1997 >>> >+++ cy.c Sat Nov 1 13:36:55 1997 >>> >@@ -410,7 +404,7 @@ >>> > #endif >>> > >>> > static int cy_chip_offset[] = { >>> >- 0x0000, 0x0200, 0x0400, 0x0600, 0x0100, 0x0300, 0x0500, 0x0700, >>> >+ 0x0000, 0x0400, 0x0800, 0x0c00, 0x0200, 0x0600, 0x0a00, 0x0e00 >>> > }; >>> > static int cy_nr_cd1400s[NCY]; >>> > static int cy_total_devices; This is correct. I haven't tested it, but it must be correct since it restores the known good table from rev.1.52. >>> > Partial "correctnes proof" for this patch can be found >>> >in (working) Linux 'cy' (or 'cz') driver which uses the same >>> >chip_offset addresses as in "patched" driver, but not as in >>> >original FreeBSD's 'cy' driver. The Linux driver is obfuscation for obfuscation compatible here :-). I fixed one of the obfuscations so I need a different table, but I shouldn't have committed the changed values. >>> If you look at the cy_inb/cy_outb functions in cyreg.h, you'll see that >>> the offset is adjusted (shifted left by one bit) for the PCI card, making >>> the appropriate adjustment. The above change (which has the left shift built >>> in to the numbers) would effectively double this shift. What I'm saying is >>> that unless I'm really missing something, the patch can't be correct. There are two independent shifts involved. For cy_inb/cy_outb, the cd1400 register numbers are shifted left by log2(bus_width_in_bytes) to get a partial offset. The shift is implemented as (log2(bus_width_in_bytes) - 1) in cy_align and 1 hard-coded in the macros, except in my version the entire shift is in cy_align. For the chip offsets, there should have been no shifts involved. However, old Cyclades boards wasted lots of address space (almost a factor of 4 even after a 2:1 wastage for mapping bytes to the bus width), so the address space had to be squeezed to make room for 32 ports, and the address space had to be stirred so that at least the first 16 of the 32 ports work with old drivers. In the PCI case, the shift to implement the squeezing is 1, and in the ISA case, the shift to implement null squeezing is 0, so the shift to implement squeezing just happens to be (log2(bus_width_in_bytes) - 1) in all cases. The driver exploits this to save a few cycles. This gives a confusing offset table in the PCI case (offsets are shifted right by 1). In my version, this gives a confusing offset table in all cases. >>[1.53 commit] >> Here you can see (unexplained in the commitlog) >>"division by 2" operation on the 'cy_chip_offset' array >>elements. I hope the above explains it in enough detail :-). I have another 30K of patches that I haven't worked on for a long time. They are mainly to save a few i/o instructions in the interrupt handler by not preserving the CAR (Channel Access Register) across interrupts. This brings the efficiency of the (default) Poll_Mode configuration closer to that of the (unavailable except on 8-port boards) svcack configuration. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711101712.EAA23391>