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