ChangeSet 1.784, 2002/12/05 14:20:39-08:00, [EMAIL PROTECTED]

[PATCH] USB: pegasus: the kmalloc/kfree crap removed from [get|set]_registers();



diff -Nru a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c
--- a/drivers/usb/pegasus.c     Thu Dec  5 14:48:39 2002
+++ b/drivers/usb/pegasus.c     Thu Dec  5 14:48:39 2002
@@ -42,10 +42,12 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.26 (2002/03/21)"
+#define DRIVER_VERSION "v0.4.27 (2002/11/19)"
 #define DRIVER_AUTHOR "Petko Manolov <[EMAIL PROTECTED]>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
+static const char driver_name[] = "pegasus";
+
 #define        PEGASUS_USE_INTR
 #define        PEGASUS_WRITE_EEPROM
 #define        BMSR_MEDIA      (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
@@ -110,20 +112,13 @@
        wake_up(&pegasus->ctrl_wait);
 }
 
-static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
+static int get_registers(pegasus_t * pegasus, u16 indx, u16 size,
                         void *data)
 {
        int ret;
-       unsigned char *buffer;
+       unsigned char buffer[256];
        DECLARE_WAITQUEUE(wait, current);
 
-       buffer = kmalloc(size, GFP_KERNEL);
-       if (!buffer) {
-               err("unable to allocate memory for configuration descriptors");
-               return 0;
-       }
-       memcpy(buffer, data, size);
-
        add_wait_queue(&pegasus->ctrl_wait, &wait);
        set_current_state(TASK_UNINTERRUPTIBLE);
        while (pegasus->flags & ETH_REGS_CHANGED)
@@ -155,23 +150,17 @@
 out:
        remove_wait_queue(&pegasus->ctrl_wait, &wait);
        memcpy(data, buffer, size);
-       kfree(buffer);
 
        return ret;
 }
 
-static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
+static int set_registers(pegasus_t * pegasus, u16 indx, u16 size,
                         void *data)
 {
        int ret;
-       unsigned char *buffer;
+       unsigned char buffer[256];
        DECLARE_WAITQUEUE(wait, current);
 
-       buffer = kmalloc(size, GFP_KERNEL);
-       if (!buffer) {
-               err("unable to allocate memory for configuration descriptors");
-               return 0;
-       }
        memcpy(buffer, data, size);
 
        add_wait_queue(&pegasus->ctrl_wait, &wait);
@@ -204,25 +193,16 @@
        schedule();
 out:
        remove_wait_queue(&pegasus->ctrl_wait, &wait);
-       kfree(buffer);
 
        return ret;
 }
 
-static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
+static int set_register(pegasus_t * pegasus, u16 indx, u8 data)
 {
        int ret;
-       unsigned char *buffer;
-       __u16 dat = data;
+       u16 tmp = data;
        DECLARE_WAITQUEUE(wait, current);
 
-       buffer = kmalloc(1, GFP_KERNEL);
-       if (!buffer) {
-               err("unable to allocate memory for configuration descriptors");
-               return 0;
-       }
-       memcpy(buffer, &data, 1);
-
        add_wait_queue(&pegasus->ctrl_wait, &wait);
        set_current_state(TASK_UNINTERRUPTIBLE);
        while (pegasus->flags & ETH_REGS_CHANGED)
@@ -232,7 +212,7 @@
 
        pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
        pegasus->dr.bRequest = PEGASUS_REQ_SET_REG;
-       pegasus->dr.wValue = cpu_to_le16p(&dat);
+       pegasus->dr.wValue = cpu_to_le16p(&tmp);
        pegasus->dr.wIndex = cpu_to_le16p(&indx);
        pegasus->dr.wLength = cpu_to_le16(1);
        pegasus->ctrl_urb->transfer_buffer_length = 1;
@@ -240,7 +220,7 @@
        FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb,
                         usb_sndctrlpipe(pegasus->usb, 0),
                         (char *) &pegasus->dr,
-                        buffer, 1, ctrl_callback, pegasus);
+                        &data, 1, ctrl_callback, pegasus);
 
        add_wait_queue(&pegasus->ctrl_wait, &wait);
        set_current_state(TASK_UNINTERRUPTIBLE);
@@ -253,7 +233,6 @@
        schedule();
 out:
        remove_wait_queue(&pegasus->ctrl_wait, &wait);
-       kfree(buffer);
 
        return ret;
 }
@@ -281,11 +260,11 @@
        return ret;
 }
 
-static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
+static int read_mii_word(pegasus_t * pegasus, u8 phy, u8 indx, u16 * regd)
 {
        int i;
-       __u8 data[4] = { phy, 0, 0, indx };
-       __u16 regdi;
+       u8 data[4] = { phy, 0, 0, indx };
+       u16 regdi;
 
        set_register(pegasus, PhyCtrl, 0);
        set_registers(pegasus, PhyAddr, sizeof(data), data);
@@ -305,10 +284,19 @@
        return 1;
 }
 
-static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
+static int mdio_read(struct net_device *dev, int phy_id, int loc)
+{
+       pegasus_t *pegasus = (pegasus_t *) dev->priv;
+       int res;
+
+       read_mii_word(pegasus, phy_id, loc, (u16 *) & res);
+       return res & 0xffff;
+}
+
+static int write_mii_word(pegasus_t * pegasus, u8 phy, u8 indx, u16 regd)
 {
        int i;
-       __u8 data[4] = { phy, 0, 0, indx };
+       u8 data[4] = { phy, 0, 0, indx };
 
        *(data + 1) = cpu_to_le16p(&regd);
        set_register(pegasus, PhyCtrl, 0);
@@ -326,11 +314,18 @@
        return 1;
 }
 
-static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
+static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
+{
+       pegasus_t *pegasus = (pegasus_t *) dev->priv;
+
+       write_mii_word(pegasus, phy_id, loc, val);
+}
+
+static int read_eprom_word(pegasus_t * pegasus, u8 index, u16 * retdata)
 {
        int i;
-       __u8 tmp;
-       __u16 retdatai;
+       u8 tmp;
+       u16 retdatai;
 
        set_register(pegasus, EpromCtrl, 0);
        set_register(pegasus, EpromOffset, index);
@@ -354,7 +349,7 @@
 #ifdef PEGASUS_WRITE_EEPROM
 static inline void enable_eprom_write(pegasus_t * pegasus)
 {
-       __u8 tmp;
+       u8 tmp;
 
        get_registers(pegasus, EthCtrl2, 1, &tmp);
        set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
@@ -362,17 +357,17 @@
 
 static inline void disable_eprom_write(pegasus_t * pegasus)
 {
-       __u8 tmp;
+       u8 tmp;
 
        get_registers(pegasus, EthCtrl2, 1, &tmp);
        set_register(pegasus, EpromCtrl, 0);
        set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
 }
 
-static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
+static int write_eprom_word(pegasus_t * pegasus, u8 index, u16 data)
 {
        int i, tmp;
-       __u8 d[4] = { 0x3f, 0, 0, EPROM_WRITE };
+       u8 d[4] = { 0x3f, 0, 0, EPROM_WRITE };
 
        set_registers(pegasus, EpromOffset, 4, d);
        enable_eprom_write(pegasus);
@@ -393,20 +388,20 @@
 }
 #endif                         /* PEGASUS_WRITE_EEPROM */
 
-static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
+static inline void get_node_id(pegasus_t * pegasus, u8 * id)
 {
        int i;
-       __u16 w16;
+       u16 w16;
 
        for (i = 0; i < 3; i++) {
                read_eprom_word(pegasus, i, &w16);
-               ((__u16 *) id)[i] = cpu_to_le16p(&w16);
+               ((u16 *) id)[i] = cpu_to_le16p(&w16);
        }
 }
 
 static void set_ethernet_addr(pegasus_t * pegasus)
 {
-       __u8 node_id[6];
+       u8 node_id[6];
 
        get_node_id(pegasus, node_id);
        set_registers(pegasus, EthID, sizeof(node_id), node_id);
@@ -415,7 +410,7 @@
 
 static inline int reset_mac(pegasus_t * pegasus)
 {
-       __u8 data = 0x8;
+       u8 data = 0x8;
        int i;
 
        set_register(pegasus, EthCtrl1, data);
@@ -438,13 +433,13 @@
 
        if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
            usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
-               __u16 auxmode;
+               u16 auxmode;
 
                read_mii_word(pegasus, 1, 0x1b, &auxmode);
                write_mii_word(pegasus, 1, 0x1b, auxmode | 4);
        }
        if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
-               __u16 auxmode;
+               u16 auxmode;
                read_mii_word(pegasus, 3, 0x1b, &auxmode);
                write_mii_word(pegasus, 3, 0x1b, auxmode | 4);
        }
@@ -453,8 +448,8 @@
 
 static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
 {
-       __u16 linkpart, bmsr;
-       __u8 data[4];
+       u16 linkpart, bmsr;
+       u8 data[4];
        pegasus_t *pegasus = dev->priv;
 
        /* read twice 'cos this is a latch bit */
@@ -487,7 +482,7 @@
        int count = urb->actual_length, res;
        int rx_status;
        struct sk_buff *skb;
-       __u16 pkt_len;
+       u16 pkt_len;
 
        if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING))
                return;
@@ -531,7 +526,12 @@
                goto goon;
        }
 
-       pkt_len = (rx_status & 0xfff) - 8;
+       if (pegasus->chip == 0x8513) {
+               pkt_len = le32_to_cpu(*(int *)pegasus->rx_buff);
+               pkt_len &= 0x0fff;
+       } else {
+               pkt_len = (rx_status & 0x0fff) - 8;
+       }
 
        if (!(skb = dev_alloc_skb(pkt_len + 2)))
                goto goon;
@@ -541,6 +541,10 @@
        eth_copy_and_sum(skb, pegasus->rx_buff, pkt_len, 0);
        skb_put(skb, pkt_len);
 
+       if (pegasus->chip == 0x8513) {
+               skb->data += 2;
+       }
+
        skb->protocol = eth_type_trans(skb, net);
        netif_rx(skb);
        pegasus->stats.rx_packets++;
@@ -578,7 +582,7 @@
 {
        pegasus_t *pegasus = urb->context;
        struct net_device *net;
-       __u8 *d;
+       u8 *d;
 
        if (!pegasus)
                return;
@@ -626,11 +630,11 @@
        pegasus_t *pegasus = net->priv;
        int count = ((skb->len + 2) & 0x3f) ? skb->len + 2 : skb->len + 3;
        int res;
-       __u16 l16 = skb->len;
+       u16 l16 = skb->len;
 
        netif_stop_queue(net);
 
-       ((__u16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16);
+       ((u16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16);
        memcpy(pegasus->tx_buff + 2, skb->data, skb->len);
        FILL_BULK_URB(pegasus->tx_urb, pegasus->usb,
                      usb_sndbulkpipe(pegasus->usb, 2),
@@ -666,15 +670,15 @@
 
 static inline void get_interrupt_interval(pegasus_t * pegasus)
 {
-       __u8 data[2];
+       u8 data[2];
 
-       read_eprom_word(pegasus, 4, (__u16 *) data);
+       read_eprom_word(pegasus, 4, (u16 *) data);
        if (data[1] < 0x80) {
                info("intr interval will be changed from %ums to %ums",
                     data[1], 0x80);
                data[1] = 0x80;
 #ifdef PEGASUS_WRITE_EEPROM
-               write_eprom_word(pegasus, 4, *(__u16 *) data);
+               write_eprom_word(pegasus, 4, *(u16 *) data);
 #endif
        }
        pegasus->intr_interval = data[1];
@@ -750,7 +754,82 @@
 
        return 0;
 }
+#if CONFIG_MII
+static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+
+       u32 ethcmd;
+       pegasus_t *pegasus = dev->priv;
+
+       if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
+               return -EFAULT;
+
+       switch (ethcmd) {
+       /* get driver-specific version/etc. info */
+       case ETHTOOL_GDRVINFO:{
+                       struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+                       strncpy(info.driver, driver_name,
+                               sizeof (info.driver) - 1);
+                       strncpy(info.version, DRIVER_VERSION,
+                               sizeof (info.version) - 1);
+                       if (copy_to_user(useraddr, &info, sizeof (info)))
+                               return -EFAULT;
+                       return 0;
+               }
 
+       /* get settings */
+       case ETHTOOL_GSET:{
+                       struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+                       mii_ethtool_gset(&pegasus->mii, &ecmd);
+                       if (copy_to_user(useraddr, &ecmd, sizeof (ecmd)))
+                               return -EFAULT;
+                       return 0;
+               }
+       /* set settings */
+       case ETHTOOL_SSET:{
+                       int r;
+                       struct ethtool_cmd ecmd;
+                       if (copy_from_user(&ecmd, useraddr, sizeof (ecmd)))
+                               return -EFAULT;
+                       r = mii_ethtool_sset(&pegasus->mii, &ecmd);
+                       return r;
+               }
+       /* restart autonegotiation */
+       case ETHTOOL_NWAY_RST:{
+                       return mii_nway_restart(&pegasus->mii);
+               }
+
+       /* get link status */
+       case ETHTOOL_GLINK:{
+                       struct ethtool_value edata = { ETHTOOL_GLINK };
+                       edata.data = mii_link_ok(&pegasus->mii);
+                       if (copy_to_user(useraddr, &edata, sizeof (edata)))
+                               return -EFAULT;
+                       return 0;
+               }
+       /* get message-level */
+       case ETHTOOL_GMSGLVL:{
+                       struct ethtool_value edata = { ETHTOOL_GMSGLVL };
+                       /* edata.data = pegasus->msg_enable; FIXME */
+                       if (copy_to_user(useraddr, &edata, sizeof (edata)))
+                               return -EFAULT;
+                       return 0;
+               }
+       /* set message-level */
+       case ETHTOOL_SMSGLVL:{
+                       struct ethtool_value edata;
+                       if (copy_from_user(&edata, useraddr, sizeof (edata)))
+                               return -EFAULT;
+                       /* sp->msg_enable = edata.data; FIXME */
+                       return 0;
+               }
+
+       }
+
+       return -EOPNOTSUPP;
+
+}
+#else
 static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
 {
        pegasus_t *pegasus;
@@ -826,10 +905,10 @@
                return -EOPNOTSUPP;
        }
 }
-
+#endif
 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
-       __u16 *data = (__u16 *) & rq->ifr_data;
+       u16 *data = (u16 *) & rq->ifr_data;
        pegasus_t *pegasus = net->priv;
        int res;
 
@@ -885,10 +964,10 @@
        netif_wake_queue(net);
 }
 
-static __u8 mii_phy_probe(pegasus_t * pegasus)
+static u8 mii_phy_probe(pegasus_t * pegasus)
 {
        int i;
-       __u16 tmp;
+       u16 tmp;
 
        for (i = 0; i < 32; i++) {
                read_mii_word(pegasus, i, MII_BMSR, &tmp);
@@ -903,9 +982,27 @@
 
 static inline void setup_pegasus_II(pegasus_t * pegasus)
 {
+       u16 data = 0xa5;
+       
        set_register(pegasus, Reg1d, 0);
+       set_register(pegasus, Reg7b, 1);
+       mdelay(100);
        set_register(pegasus, Reg7b, 2);
-       if (pegasus->features & HAS_HOME_PNA && mii_mode)
+       
+       set_register(pegasus, 0x83, data);
+       get_registers(pegasus, 0x83, 1, &data);
+       
+       if (data & 0xa5) {
+               pegasus->chip = 0x8513;
+       } else {
+               pegasus->chip = 0;
+       }
+       
+       set_register( pegasus, 0x80, 0xc0 );
+       set_register( pegasus, 0x83, 0xff );
+       set_register( pegasus, 0x84, 0x01 );
+       
+       if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
                set_register(pegasus, Reg81, 6);
        else
                set_register(pegasus, Reg81, 2);
@@ -984,6 +1081,11 @@
        net->set_multicast_list = pegasus_set_multicast;
        net->get_stats = pegasus_netdev_stats;
        net->mtu = PEGASUS_MTU;
+       pegasus->mii.dev = net;
+       pegasus->mii.mdio_read = mdio_read;
+       pegasus->mii.mdio_write = mdio_write;
+       pegasus->mii.phy_id_mask = 0x1f;
+       pegasus->mii.reg_num_mask = 0x1f;
 
        pegasus->features = usb_dev_id[dev_index].private;
 #ifdef PEGASUS_USE_INTR
@@ -1015,9 +1117,9 @@
                warn("can't locate MII phy, using default");
                pegasus->phy = 1;
        }
-
 exit:
        up(&pegasus->sem);
+       
        return pegasus;
 }
 
@@ -1047,7 +1149,7 @@
 }
 
 static struct usb_driver pegasus_driver = {
-       name:           "pegasus",
+       name:           driver_name,
        probe:          pegasus_probe,
        disconnect:     pegasus_disconnect,
        id_table:       pegasus_ids,
diff -Nru a/drivers/usb/pegasus.h b/drivers/usb/pegasus.h
--- a/drivers/usb/pegasus.h     Thu Dec  5 14:48:39 2002
+++ b/drivers/usb/pegasus.h     Thu Dec  5 14:48:39 2002
@@ -85,6 +85,7 @@
        struct usb_device       *usb;
        struct net_device       *net;
        struct net_device_stats stats;
+       struct mii_if_info      mii;
        unsigned                flags;
        unsigned                features;
        int                     dev_index;
@@ -93,6 +94,7 @@
        struct usb_ctrlrequest  dr;
        wait_queue_head_t       ctrl_wait;
        struct semaphore        sem;
+       int                     chip;
        unsigned char           rx_buff[PEGASUS_MAX_MTU];
        unsigned char           tx_buff[PEGASUS_MAX_MTU];
        unsigned char           intr_buff[8];
@@ -128,11 +130,11 @@
 #define        VENDOR_LANEED           0x056e
 #define        VENDOR_LINKSYS          0x066b
 #define        VENDOR_MELCO            0x0411
+#define VENDOR_NETGEAR         0x0846
 #define        VENDOR_SMARTBRIDGES     0x08d1
 #define        VENDOR_SMC              0x0707
 #define        VENDOR_SOHOWARE         0x15e8
 #define        VENDOR_SIEMENS          0x067c
-#define        VENDOR_JTEC             0x11ad
 
 #else  /* PEGASUS_DEV */
 
@@ -165,7 +167,10 @@
 PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
                VENDOR_ADMTEK, 0x8511,
                DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
+PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
+               VENDOR_ADMTEK, 0x8513,
+               DEFAULT_GPIO_RESET | PEGASUS_II )       
+PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
                VENDOR_ADMTEK, 0x0986,
                DEFAULT_GPIO_RESET | HAS_HOME_PNA )
 PEGASUS_DEV( "ADMtek AN986A USB MAC", VENDOR_ADMTEK, 0x1986,
@@ -188,7 +193,7 @@
                DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004,
                DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Corega FEter", VENDOR_COREGA, 0x000d,
+PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d,
                DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
                LINKSYS_GPIO_RESET )
@@ -242,6 +247,8 @@
                DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
                DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "NETGEAR FA101", VENDOR_MELCO, 0x1020,
+               DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
                DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
@@ -253,8 +260,6 @@
 PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
                DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
-               DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "FA8101 USB To ETHERNET", VENDOR_JTEC, 0x8101,
                DEFAULT_GPIO_RESET | PEGASUS_II )
 
 #endif /* PEGASUS_DEV */


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to