Subject: Re: Endian bugs in 1.4_ALPHA ep driver
To: Jonathan Stone <jonathan@DSG.Stanford.EDU>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 04/13/1999 12:54:47
On Tue, 13 Apr 1999 12:40:26 -0700 
 Jonathan Stone <jonathan@DSG.Stanford.EDU> wrote:

 > The changelog in Hayakawa-san's CardBus patches state that, in 1.3I,
 > the elink3 driver (ep) has an endian bug on macppc.

Right.  It's obvious if you think about it :-)

 > Tsubai-san's fix is to use bus_space_{read,write}_multi_stream_{2,4}
 > when doing PIO to move packets on and off the card (see below) But
 > while those methods exist on macppc, they aren't't a defined part of
 > the bus_space(9) API.

Not "officially".  There are lots of other drivers in our tree that use this
change, including the NE2000 driver (which works on the BeBox, for example).

 > Is the patch below from Tsubai-san a good way to fix this for 1.4?  If
 > not, what's a better way?

Yes, it is.

 > And, where is the endian-ness of a bus_space_{read,write}_multi_N
 > operation defined? :->.

"In the spec for the bus."  Basically, on a big-endian machine writing to a
a natively little-endian bus (like ISA or PCI), non-stream methods must
ensure the the appropriate byte-swapping occurs.  Post-1.4, the API spec
for bus_space(9) will be updated to formally include the stream methods,
and a few other things.

 > 
 > 
 > 
 > Index: sys/dev/ic/elink3.c
 > diff -c sys/dev/ic/elink3.c:1.1.1.1 sys/dev/ic/elink3.c:1.1.1.1.4.1
 > *** sys/dev/ic/elink3.c:1.1.1.1	Wed Jan 20 22:27:51 1999
 > --- sys/dev/ic/elink3.c	Mon Mar 22 23:44:55 1999
 > ***************
 > *** 128,133 ****
 > --- 128,140 ----
 >   int epdebug = 0;
 >   #endif
 >   
 > + #ifndef __BUS_SPACE_HAS_STREAM_METHODS
 > + #define bus_space_read_multi_stream_2	bus_space_read_multi_2
 > + #define bus_space_read_multi_stream_4	bus_space_read_multi_4
 > + #define bus_space_write_multi_stream_2	bus_space_write_multi_2
 > + #define bus_space_write_multi_stream_4	bus_space_write_multi_4
 > + #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
 > + 
 >   /*
 >    * Structure to map media-present bits in boards to ifmedia codes and
 >    * printable media names. Used for table-driven ifmedia initialization.
 > ***************
 > *** 1118,1124 ****
 >   					    (void *)(mtod(m, u_long) + count);
 >   					m->m_len -= count;
 >   				}
 > ! 				bus_space_write_multi_4(iot, ioh,
 >   				    txreg, mtod(m, u_int32_t *), m->m_len >> 2);
 >   				m->m_data = (void *)(mtod(m, u_long) +
 >   					(u_long)(m->m_len & ~3));
 > --- 1125,1131 ----
 >   					    (void *)(mtod(m, u_long) + count);
 >   					m->m_len -= count;
 >   				}
 > ! 				bus_space_write_multi_stream_4(iot, ioh,
 >   				    txreg, mtod(m, u_int32_t *), m->m_len >> 2);
 >   				m->m_data = (void *)(mtod(m, u_long) +
 >   					(u_long)(m->m_len & ~3));
 > ***************
 > *** 1141,1147 ****
 >   					    (void *)(mtod(m, u_long) + 1);
 >   					m->m_len -= 1;
 >   				}
 > ! 				bus_space_write_multi_2(iot, ioh,
 >   				    txreg, mtod(m, u_int16_t *),
 >   				    m->m_len >> 1);
 >   			}
 > --- 1148,1154 ----
 >   					    (void *)(mtod(m, u_long) + 1);
 >   					m->m_len -= 1;
 >   				}
 > ! 				bus_space_write_multi_stream_2(iot, ioh,
 >   				    txreg, mtod(m, u_int16_t *),
 >   				    m->m_len >> 1);
 >   			}
 > ***************
 > *** 1602,1608 ****
 >   				remaining -= count;
 >   			}
 >   			if (remaining > 3) {
 > ! 				bus_space_read_multi_4(iot, ioh,
 >   				    rxreg, (u_int32_t *) offset,
 >   				    remaining >> 2);
 >   				offset += remaining & ~3;
 > --- 1609,1615 ----
 >   				remaining -= count;
 >   			}
 >   			if (remaining > 3) {
 > ! 				bus_space_read_multi_stream_4(iot, ioh,
 >   				    rxreg, (u_int32_t *) offset,
 >   				    remaining >> 2);
 >   				offset += remaining & ~3;
 > ***************
 > *** 1621,1627 ****
 >   				offset += 1;
 >   			}
 >   			if (remaining > 1) {
 > ! 				bus_space_read_multi_2(iot, ioh,
 >   				    rxreg, (u_int16_t *) offset,
 >   				    remaining >> 1);
 >   				offset += remaining & ~1;
 > --- 1628,1634 ----
 >   				offset += 1;
 >   			}
 >   			if (remaining > 1) {
 > ! 				bus_space_read_multi_stream_2(iot, ioh,
 >   				    rxreg, (u_int16_t *) offset,
 >   				    remaining >> 1);
 >   				offset += remaining & ~1;
 > 

        -- Jason R. Thorpe <thorpej@nas.nasa.gov>