Sergey,

Thank you very much for your comments... enclosed is a patch with you suggestions corrected.
I gave it a try just now..

Mike

Attachment: usbnet.patch.6_29
Description: Binary data


On Jun 29, 2005, at 11:04 AM, Sergey Vlasov wrote:

On Wed, Jun 29, 2005 at 09:23:01AM -0700, C Michael Sundius wrote:
--- a/drivers/usb/net/usbnet.c  2005-06-14 20:44:17.000000000 -0700
+++ b/drivers/usb/net/usbnet.c  2005-06-23 04:05:39.000000000 -0700
@@ -1176,20 +1176,62 @@
 static const struct driver_info        cdc_info = {
        .description =  "CDC Ethernet Device",
        .flags =        FLAG_ETHER,
        // .check_connect = cdc_check_connect,
        .bind =         cdc_bind,
        .unbind =       cdc_unbind,
 };

 #endif /* CONFIG_USB_CDCETHER */

+#ifdef        CONFIG_USB_CENTILLIUM
+/ *--------------------------------------------------------------------- ----
+ *
+ * Centillium Palladia P300, P400, A100.
+ *
+ *--------------------------------------------------------------------- ----*/
+struct ctlm_tx_fix_s {

Maybe "struct ctlm_tx_header"?

+       unsigned short id;
+       unsigned short len;
+};

This structure specifies the packet header format for the hardware.
When dealing with hardware or network protocols, you must care about
the endianness - in this case the hardware probably expects
little-endian data, therefore for 2.6.x kernels you must mark these
fields as little-endian:

        __le16 id;
        __le16 len;

Then you need to use byte swapping functions (see below).

Also __attribute__((__packed__)) should be added to this declaration
(however, in this particular case it does not seem likely that the
compiler will insert any padding to the structure)

+typedef struct ctlm_tx_fix_s ctlm_tx_fix_t;

Typedefs for structures should not be used in the kernel code - just
use "struct ctlm_tx_header".

+
+static struct sk_buff *
+ctlm_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
+{
+       struct sk_buff *skb2;
+       ctlm_tx_fix_t  *ctlm_tx_fix_p;
+       int            headroom;
+       int            len;
+
+       len = skb->len;
+       headroom = skb_headroom (skb);
+
+       if (headroom < 4) {
+               skb2 = skb_copy_expand (skb, 0x10, 0, flags);
+               dev_kfree_skb_any (skb);
+               skb = skb2;

skb_copy_expand() may fail and return NULL - this must be checked (the
convenient place is here - even in the failure case you must free the
old skb).

+       }
+       ctlm_tx_fix_p = (ctlm_tx_fix_t *)skb_push(skb, 4);
+       ctlm_tx_fix_p->id = 0;
+       ctlm_tx_fix_p->len = len;

This should be

        ctlm_tx_fix_p->len = cpu_to_le16(len);

(cpu_to_le16 is a noop on a little-endian architecture like i386, but
it swaps bytes on big-endian architectures).

+
+       return skb;
+}
[skip]

C Michael Sundius
Brown Bear Realty
303 Cortland Ave
San Francisco, CA 94110
(415)608-0121
[EMAIL PROTECTED]

Reply via email to