rtl8187: Add USB ID for Netgear WG111V3
[safe/jmp/linux-2.6] / drivers / net / wireless / ray_cs.c
index 319180c..963960d 100644 (file)
  * 
 =============================================================================*/
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -45,6 +45,7 @@
 #include <linux/ioport.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
+#include <linux/ieee80211.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -53,8 +54,8 @@
 #include <pcmcia/ds.h>
 #include <pcmcia/mem_op.h>
 
-#include <net/ieee80211.h>
 #include <linux/wireless.h>
+#include <net/iw_handler.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -90,8 +91,8 @@ module_param(pc_debug, int, 0);
 #define DEBUG(n, args...)
 #endif
 /** Prototypes based on PCMCIA skeleton driver *******************************/
-static void ray_config(dev_link_t *link);
-static void ray_release(dev_link_t *link);
+static int ray_config(struct pcmcia_device *link);
+static void ray_release(struct pcmcia_device *link);
 static void ray_detach(struct pcmcia_device *p_dev);
 
 /***** Prototypes indicated by device structure ******************************/
@@ -100,7 +101,7 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map);
 static struct net_device_stats *ray_get_stats(struct net_device *dev);
 static int ray_dev_init(struct net_device *dev);
 
-static struct ethtool_ops netdev_ethtool_ops;
+static const struct ethtool_ops netdev_ethtool_ops;
 
 static int ray_open(struct net_device *dev);
 static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -131,7 +132,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, i
 static void verify_dl_startup(u_long);
 
 /* Prototypes for interrpt time functions **********************************/
-static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ray_interrupt (int reg, void *dev_id);
 static void clear_interrupt(ray_dev_t *local);
 static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, 
                        unsigned int pkt_addr, int rx_len);
@@ -190,20 +191,17 @@ static int bc;
 static char *phy_addr = NULL;
 
 
-/* A linked list of "instances" of the ray device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-*/
-static dev_link_t *dev_list = NULL;
-
-/* A dev_link_t structure has fields for most things that are needed
+/* A struct pcmcia_device structure has fields for most things that are needed
    to keep track of a socket, but there will usually be some device
    specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
+   'priv' pointer in a struct pcmcia_device structure can be used to point to
    a device-specific private data structure, like this.
 */
 static unsigned int ray_mem_speed = 500;
 
+/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */
+static struct pcmcia_device *this_device = NULL;
+
 MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
 MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
 MODULE_LICENSE("GPL");
@@ -306,56 +304,45 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
     configure the card at this point -- we wait until we receive a
     card insertion event.
 =============================================================================*/
-static int ray_attach(struct pcmcia_device *p_dev)
+static int ray_probe(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link;
     ray_dev_t *local;
     struct net_device *dev;
-    
-    DEBUG(1, "ray_attach()\n");
-
-    /* Initialize the dev_link_t structure */
-    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 
-    if (!link)
-           return -ENOMEM;
+    DEBUG(1, "ray_attach()\n");
 
     /* Allocate space for private device-specific data */
     dev = alloc_etherdev(sizeof(ray_dev_t));
-
     if (!dev)
            goto fail_alloc_dev;
 
-    local = dev->priv;
-
-    memset(link, 0, sizeof(struct dev_link_t));
+    local = netdev_priv(dev);
+    local->finder = p_dev;
 
     /* The io structure describes IO port mapping. None used here */
-    link->io.NumPorts1 = 0;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.IOAddrLines = 5;
+    p_dev->io.NumPorts1 = 0;
+    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+    p_dev->io.IOAddrLines = 5;
 
     /* Interrupt setup. For PCMCIA, driver takes what's given */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &ray_interrupt;
+    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    p_dev->irq.Handler = &ray_interrupt;
 
     /* General socket configuration */
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.Vcc = 50;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 1;
-    link->conf.Present = PRESENT_OPTION;
-
-    link->priv = dev;
-    link->irq.Instance = dev;
+    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+    p_dev->conf.IntType = INT_MEMORY_AND_IO;
+    p_dev->conf.ConfigIndex = 1;
+
+    p_dev->priv = dev;
+    p_dev->irq.Instance = dev;
     
-    local->finder = link;
+    local->finder = p_dev;
     local->card_status = CARD_INSERTED;
     local->authentication_state = UNAUTHENTICATED;
     local->num_multi = 0;
-    DEBUG(2,"ray_attach link = %p,  dev = %p,  local = %p, intr = %p\n",
-          link,dev,local,&ray_interrupt);
+    DEBUG(2,"ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
+          p_dev,dev,local,&ray_interrupt);
 
     /* Raylink entries in the device structure */
     dev->hard_start_xmit = &ray_dev_start_xmit;
@@ -371,7 +358,6 @@ static int ray_attach(struct pcmcia_device *p_dev)
     dev->set_multicast_list = &set_multicast_list;
 
     DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
-    SET_MODULE_OWNER(dev);
     dev->init = &ray_dev_init;
     dev->open = &ray_open;
     dev->stop = &ray_dev_close;
@@ -379,16 +365,10 @@ static int ray_attach(struct pcmcia_device *p_dev)
 
     init_timer(&local->timer);
 
-    link->handle = p_dev;
-    p_dev->instance = link;
-
-    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-    ray_config(link);
-
-    return 0;
+    this_device = p_dev;
+    return ray_config(p_dev);
 
 fail_alloc_dev:
-    kfree(link);
     return -ENOMEM;
 } /* ray_attach */
 /*=============================================================================
@@ -397,37 +377,25 @@ fail_alloc_dev:
     structures are freed.  Otherwise, the structures will be freed
     when the device is released.
 =============================================================================*/
-static void ray_detach(struct pcmcia_device *p_dev)
+static void ray_detach(struct pcmcia_device *link)
 {
-    dev_link_t *link = dev_to_instance(p_dev);
-    dev_link_t **linkp;
     struct net_device *dev;
     ray_dev_t *local;
 
     DEBUG(1, "ray_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
 
+    this_device = NULL;
     dev = link->priv;
 
-    if (link->state & DEV_CONFIG) {
-           ray_release(link);
+    ray_release(link);
 
-           local = (ray_dev_t *)dev->priv;
-            del_timer(&local->timer);
-    }
+    local = netdev_priv(dev);
+    del_timer(&local->timer);
 
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
     if (link->priv) {
-       if (link->dev) unregister_netdev(dev);
+       if (link->dev_node) unregister_netdev(dev);
         free_netdev(dev);
     }
-    kfree(link);
     DEBUG(2,"ray_cs ray_detach ending\n");
 } /* ray_detach */
 /*=============================================================================
@@ -438,65 +406,42 @@ static void ray_detach(struct pcmcia_device *p_dev)
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 #define MAX_TUPLE_SIZE 128
-static void ray_config(dev_link_t *link)
+static int ray_config(struct pcmcia_device *link)
 {
-    client_handle_t handle = link->handle;
-    tuple_t tuple;
-    cisparse_t parse;
     int last_fn = 0, last_ret = 0;
     int i;
-    u_char buf[MAX_TUPLE_SIZE];
     win_req_t req;
     memreq_t mem;
     struct net_device *dev = (struct net_device *)link->priv;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
+    DECLARE_MAC_BUF(mac);
 
     DEBUG(1, "ray_config(0x%p)\n", link);
 
-    /* This reads the card's CONFIG tuple to find its configuration regs */
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = MAX_TUPLE_SIZE;
-    tuple.TupleOffset = 0;
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
-    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
-    link->conf.ConfigBase = parse.config.base;
-    link->conf.Present = parse.config.rmask[0];
-
     /* Determine card type and firmware version */
-    buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
-    tuple.DesiredTuple = CISTPL_VERS_1;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = MAX_TUPLE_SIZE;
-    tuple.TupleOffset = 2;
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
-
-    for (i=0; i<tuple.TupleDataLen - 4; i++) 
-        if (buf[i] == 0) buf[i] = ' ';
-    printk(KERN_INFO "ray_cs Detected: %s\n",buf);
-
-    /* Configure card */
-    link->state |= DEV_CONFIG;
+    printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
+          link->prod_id[0] ? link->prod_id[0] : " ",
+          link->prod_id[1] ? link->prod_id[1] : " ",
+          link->prod_id[2] ? link->prod_id[2] : " ",
+          link->prod_id[3] ? link->prod_id[3] : " ");
 
     /* Now allocate an interrupt line.  Note that this does not
        actually assign a handler to the interrupt.
     */
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
     dev->irq = link->irq.AssignedIRQ;
     
     /* This actually configures the PCMCIA socket -- setting up
        the I/O windows and the interrupt mapping.
     */
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 
 /*** Set up 32k window for shared memory (transmit and control) ************/
     req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
     req.Base = 0;
     req.Size = 0x8000;
     req.AccessSpeed = ray_mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
+    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
     mem.CardOffset = 0x0000; mem.Page = 0;
     CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
     local->sram = ioremap(req.Base,req.Size);
@@ -506,7 +451,7 @@ static void ray_config(dev_link_t *link)
     req.Base = 0;
     req.Size = 0x4000;
     req.AccessSpeed = ray_mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle));
+    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle));
     mem.CardOffset = 0x8000; mem.Page = 0;
     CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
     local->rmem = ioremap(req.Base,req.Size);
@@ -516,7 +461,7 @@ static void ray_config(dev_link_t *link)
     req.Base = 0;
     req.Size = 0x1000;
     req.AccessSpeed = ray_mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle));
+    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle));
     mem.CardOffset = 0x0000; mem.Page = 0;
     CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
     local->amem = ioremap(req.Base,req.Size);
@@ -526,32 +471,30 @@ static void ray_config(dev_link_t *link)
     DEBUG(3,"ray_config amem=%p\n",local->amem);
     if (ray_init(dev) < 0) {
         ray_release(link);
-        return;
+        return -ENODEV;
     }
 
-    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+    SET_NETDEV_DEV(dev, &handle_to_dev(link));
     i = register_netdev(dev);
     if (i != 0) {
         printk("ray_config register_netdev() failed\n");
         ray_release(link);
-        return;
+        return i;
     }
 
     strcpy(local->node.dev_name, dev->name);
-    link->dev = &local->node;
+    link->dev_node = &local->node;
 
-    link->state &= ~DEV_CONFIG_PENDING;
-    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
-       dev->name, dev->irq);
-    for (i = 0; i < 6; i++)
-    printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
+    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %s\n",
+       dev->name, dev->irq, print_mac(mac, dev->dev_addr));
 
-    return;
+    return 0;
 
 cs_failed:
-    cs_error(link->handle, last_fn, last_ret);
+    cs_error(link, last_fn, last_ret);
 
     ray_release(link);
+    return -ENODEV;
 } /* ray_config */
 
 static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
@@ -577,10 +520,10 @@ static int ray_init(struct net_device *dev)
     int i;
     UCHAR *p;
     struct ccs __iomem *pccs;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
     DEBUG(1, "ray_init(0x%p)\n", dev);
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(0,"ray_init - device not present\n");
         return -1;
     }
@@ -638,12 +581,12 @@ static int ray_init(struct net_device *dev)
 static int dl_startup_params(struct net_device *dev)
 {
     int ccsindex;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
     struct ccs __iomem *pccs;
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
 
     DEBUG(1,"dl_startup_params entered\n");
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs dl_startup_params - device not present\n");
         return -1;
     }
@@ -747,9 +690,9 @@ static void verify_dl_startup(u_long data)
     ray_dev_t *local = (ray_dev_t *)data;
     struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
     UCHAR status;
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
         return;
     }
@@ -787,8 +730,8 @@ static void start_net(u_long data)
     ray_dev_t *local = (ray_dev_t *)data;
     struct ccs __iomem *pccs;
     int ccsindex;
-    dev_link_t *link = local->finder;
-    if (!(link->state & DEV_PRESENT)) {
+    struct pcmcia_device *link = local->finder;
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs start_net - device not present\n");
         return;
     }
@@ -814,9 +757,9 @@ static void join_net(u_long data)
 
     struct ccs __iomem *pccs;
     int ccsindex;
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
     
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs join_net - device not present\n");
         return;
     }
@@ -840,65 +783,47 @@ static void join_net(u_long data)
     device, and release the PCMCIA configuration.  If the device is
     still open, this will be postponed until it is closed.
 =============================================================================*/
-static void ray_release(dev_link_t *link)
+static void ray_release(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv; 
-    ray_dev_t *local = dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
     int i;
     
     DEBUG(1, "ray_release(0x%p)\n", link);
 
     del_timer(&local->timer);
-    link->state &= ~DEV_CONFIG;
 
     iounmap(local->sram);
     iounmap(local->rmem);
     iounmap(local->amem);
     /* Do bother checking to see if these succeed or not */
-    i = pcmcia_release_window(link->win);
-    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);
     i = pcmcia_release_window(local->amem_handle);
     if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
     i = pcmcia_release_window(local->rmem_handle);
     if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
-    i = pcmcia_release_configuration(link->handle);
-    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);
-    i = pcmcia_release_irq(link->handle, &link->irq);
-    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
+    pcmcia_disable_device(link);
 
     DEBUG(2,"ray_release ending\n");
 }
 
-static int ray_suspend(struct pcmcia_device *p_dev)
+static int ray_suspend(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *dev = link->priv;
 
-       link->state |= DEV_SUSPEND;
-        if (link->state & DEV_CONFIG) {
-               if (link->open)
-                       netif_device_detach(dev);
-
-               pcmcia_release_configuration(link->handle);
-        }
-
+       if (link->open)
+               netif_device_detach(dev);
 
        return 0;
 }
 
-static int ray_resume(struct pcmcia_device *p_dev)
+static int ray_resume(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *dev = link->priv;
 
-       link->state &= ~DEV_SUSPEND;
-        if (link->state & DEV_CONFIG) {
-               pcmcia_request_configuration(link->handle, &link->conf);
-               if (link->open) {
-                       ray_reset(dev);
-                       netif_device_attach(dev);
-               }
-        }
+       if (link->open) {
+               ray_reset(dev);
+               netif_device_attach(dev);
+       }
 
        return 0;
 }
@@ -909,11 +834,11 @@ int ray_dev_init(struct net_device *dev)
 #ifdef RAY_IMMEDIATE_INIT
     int i;
 #endif /* RAY_IMMEDIATE_INIT */
-    ray_dev_t *local = dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
 
     DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_dev_init - device not present\n");
         return -1;
     }
@@ -943,11 +868,11 @@ int ray_dev_init(struct net_device *dev)
 /*===========================================================================*/
 static int ray_dev_config(struct net_device *dev, struct ifmap *map)
 {
-    ray_dev_t *local = dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
     /* Dummy routine to satisfy device structure */
     DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_dev_config - device not present\n");
         return -1;
     }
@@ -957,11 +882,11 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map)
 /*===========================================================================*/
 static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-    ray_dev_t *local = dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
     short length = skb->len;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_dev_start_xmit - device not present\n");
         return -1;
     }
@@ -977,8 +902,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
     if (length < ETH_ZLEN)
     {
-       skb = skb_padto(skb, ETH_ZLEN);
-       if (skb == NULL)
+       if (skb_padto(skb, ETH_ZLEN))
                return 0;
        length = ETH_ZLEN;
     }
@@ -1001,7 +925,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, 
                 UCHAR msg_type)
 {
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
     struct ccs __iomem *pccs;
     int ccsindex;
     int offset;
@@ -1075,13 +999,13 @@ static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
 static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
                     int len)
 {
-    unsigned short int proto = ((struct ethhdr *)data)->h_proto;
+    __be16 proto = ((struct ethhdr *)data)->h_proto;
     if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
         DEBUG(3,"ray_cs translate_frame DIX II\n");
         /* Copy LLC header to card buffer */
         memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
         memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
-        if ((proto == 0xf380) || (proto == 0x3781)) {
+        if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
             /* This is the selective translation table, only 2 entries */
             writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
         }
@@ -1092,7 +1016,7 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigne
     }
     else { /* already  802 type, and proto is length */
         DEBUG(3,"ray_cs translate_frame 802\n");
-        if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */
+        if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
         DEBUG(3,"ray_cs translate_frame evil IPX\n");
             memcpy_toio(&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);
             return 0 - ETH_HLEN;
@@ -1147,7 +1071,7 @@ static void netdev_get_drvinfo(struct net_device *dev,
        strcpy(info->driver, "ray_cs");
 }
 
-static struct ethtool_ops netdev_ethtool_ops = {
+static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
 };
 
@@ -1175,7 +1099,7 @@ static int ray_set_freq(struct net_device *dev,
                        struct iw_freq *fwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
        int err = -EINPROGRESS;         /* Call commit handler */
 
        /* Reject if card is already initialised */
@@ -1200,7 +1124,7 @@ static int ray_get_freq(struct net_device *dev,
                        struct iw_freq *fwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        fwrq->m = local->sparm.b5.a_hop_pattern;
        fwrq->e = 0;
@@ -1216,7 +1140,7 @@ static int ray_set_essid(struct net_device *dev,
                         struct iw_point *dwrq,
                         char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        /* Reject if card is already initialised */
        if(local->card_status != CARD_AWAITING_PARAM)
@@ -1228,7 +1152,7 @@ static int ray_set_essid(struct net_device *dev,
                return -EOPNOTSUPP;
        } else {
                /* Check the size of the string */
-               if(dwrq->length > IW_ESSID_MAX_SIZE + 1) {
+               if(dwrq->length > IW_ESSID_MAX_SIZE) {
                        return -E2BIG;
                }
 
@@ -1249,14 +1173,13 @@ static int ray_get_essid(struct net_device *dev,
                         struct iw_point *dwrq,
                         char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        /* Get the essid that was set */
        memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
-       extra[IW_ESSID_MAX_SIZE] = '\0';
 
        /* Push it out ! */
-       dwrq->length = strlen(extra) + 1;
+       dwrq->length = strlen(extra);
        dwrq->flags = 1; /* active */
 
        return 0;
@@ -1271,7 +1194,7 @@ static int ray_get_wap(struct net_device *dev,
                        struct sockaddr *awrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        memcpy(awrq->sa_data, local->bss_id, ETH_ALEN);
        awrq->sa_family = ARPHRD_ETHER;
@@ -1288,7 +1211,7 @@ static int ray_set_rate(struct net_device *dev,
                        struct iw_param *vwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        /* Reject if card is already initialised */
        if(local->card_status != CARD_AWAITING_PARAM)
@@ -1317,7 +1240,7 @@ static int ray_get_rate(struct net_device *dev,
                        struct iw_param *vwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        if(local->net_default_tx_rate == 3)
                vwrq->value = 2000000;          /* Hum... */
@@ -1337,7 +1260,7 @@ static int ray_set_rts(struct net_device *dev,
                       struct iw_param *vwrq,
                       char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
        int rthr = vwrq->value;
 
        /* Reject if card is already initialised */
@@ -1367,7 +1290,7 @@ static int ray_get_rts(struct net_device *dev,
                       struct iw_param *vwrq,
                       char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8)
                + local->sparm.b5.a_rts_threshold[1];
@@ -1386,7 +1309,7 @@ static int ray_set_frag(struct net_device *dev,
                        struct iw_param *vwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
        int fthr = vwrq->value;
 
        /* Reject if card is already initialised */
@@ -1415,7 +1338,7 @@ static int ray_get_frag(struct net_device *dev,
                        struct iw_param *vwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8)
                + local->sparm.b5.a_frag_threshold[1];
@@ -1434,7 +1357,7 @@ static int ray_set_mode(struct net_device *dev,
                        __u32 *uwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
        int err = -EINPROGRESS;         /* Call commit handler */
        char card_mode = 1;
 
@@ -1466,7 +1389,7 @@ static int ray_get_mode(struct net_device *dev,
                        __u32 *uwrq,
                        char *extra)
 {
-       ray_dev_t *local = (ray_dev_t *)dev->priv;
+       ray_dev_t *local = netdev_priv(dev);
 
        if(local->sparm.b5.a_network_type)
                *uwrq = IW_MODE_INFRA;
@@ -1569,8 +1492,8 @@ static int ray_commit(struct net_device *dev,
  */
 static iw_stats * ray_get_wireless_stats(struct net_device *   dev)
 {
-  ray_dev_t *  local = (ray_dev_t *) dev->priv;
-  dev_link_t *link = local->finder;
+  ray_dev_t *  local = netdev_priv(dev);
+  struct pcmcia_device *link = local->finder;
   struct status __iomem *p = local->sram + STATUS_BASE;
 
   if(local == (ray_dev_t *) NULL)
@@ -1588,7 +1511,7 @@ static iw_stats * ray_get_wireless_stats(struct net_device *      dev)
     }
 #endif /* WIRELESS_SPY */
 
-  if((link->state & DEV_PRESENT)) {
+  if(pcmcia_dev_present(link)) {
     local->wstats.qual.noise = readb(&p->rxnoise);
     local->wstats.qual.updated |= 4;
   }
@@ -1645,9 +1568,9 @@ static const struct iw_priv_args  ray_private_args[] = {
 
 static const struct iw_handler_def     ray_handler_def =
 {
-       .num_standard   = sizeof(ray_handler)/sizeof(iw_handler),
-       .num_private    = sizeof(ray_private_handler)/sizeof(iw_handler),
-       .num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args),
+       .num_standard   = ARRAY_SIZE(ray_handler),
+       .num_private    = ARRAY_SIZE(ray_private_handler),
+       .num_private_args = ARRAY_SIZE(ray_private_args),
        .standard       = ray_handler,
        .private        = ray_private_handler,
        .private_args   = ray_private_args,
@@ -1657,18 +1580,14 @@ static const struct iw_handler_def      ray_handler_def =
 /*===========================================================================*/
 static int ray_open(struct net_device *dev)
 {
-    dev_link_t *link;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link;
+    link = local->finder;
     
     DEBUG(1, "ray_open('%s')\n", dev->name);
 
-    for (link = dev_list; link; link = link->next)
-        if (link->priv == dev) break;
-    if (!DEV_OK(link)) {
-        return -ENODEV;
-    }
-
-    if (link->open == 0) local->num_multi = 0;
+    if (link->open == 0)
+           local->num_multi = 0;
     link->open++;
 
     /* If the card is not started, time to start it ! - Jean II */
@@ -1695,15 +1614,12 @@ static int ray_open(struct net_device *dev)
 /*===========================================================================*/
 static int ray_dev_close(struct net_device *dev)
 {
-    dev_link_t *link;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link;
+    link = local->finder;
 
     DEBUG(1, "ray_dev_close('%s')\n", dev->name);
 
-    for (link = dev_list; link; link = link->next)
-        if (link->priv == dev) break;
-    if (link == NULL)
-        return -ENODEV;
-
     link->open--;
     netif_stop_queue(dev);
 
@@ -1725,9 +1641,9 @@ static void ray_reset(struct net_device *dev) {
 static int interrupt_ecf(ray_dev_t *local, int ccs)
 {
     int i = 50;
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
         return -1;
     }
@@ -1752,9 +1668,9 @@ static int get_free_tx_ccs(ray_dev_t *local)
 {
     int i;
     struct ccs __iomem *pccs = ccs_base(local);
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
         return ECARDGONE;
     }
@@ -1783,9 +1699,9 @@ static int get_free_ccs(ray_dev_t *local)
 {
     int i;
     struct ccs __iomem *pccs = ccs_base(local);
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs get_free_ccs - device not present\n");
         return ECARDGONE;
     }
@@ -1857,28 +1773,28 @@ static int parse_addr(char *in_str, UCHAR *out)
 /*===========================================================================*/
 static struct net_device_stats *ray_get_stats(struct net_device *dev)
 {
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
     struct status __iomem *p = local->sram + STATUS_BASE;
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs net_device_stats - device not present\n");
         return &local->stats;
     }
     if (readb(&p->mrx_overflow_for_host))
     {
-        local->stats.rx_over_errors += ntohs(readb(&p->mrx_overflow));
+        local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
         writeb(0,&p->mrx_overflow);
         writeb(0,&p->mrx_overflow_for_host);
     }
     if (readb(&p->mrx_checksum_error_for_host))
     {
-        local->stats.rx_crc_errors += ntohs(readb(&p->mrx_checksum_error));
+        local->stats.rx_crc_errors += swab16(readw(&p->mrx_checksum_error));
         writeb(0,&p->mrx_checksum_error);
         writeb(0,&p->mrx_checksum_error_for_host);
     }
     if (readb(&p->rx_hec_error_for_host))
     {
-        local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error));
+        local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
         writeb(0,&p->rx_hec_error);
         writeb(0,&p->rx_hec_error_for_host);
     }
@@ -1887,13 +1803,13 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev)
 /*===========================================================================*/
 static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
 {
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
     int ccsindex;
     int i;
     struct ccs __iomem *pccs;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_update_parm - device not present\n");
         return;
     }
@@ -1924,11 +1840,11 @@ static void ray_update_multi_list(struct net_device *dev, int all)
     int ccsindex;
     struct ccs __iomem *pccs;
     int i = 0;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
-    dev_link_t *link = local->finder;
+    ray_dev_t *local = netdev_priv(dev);
+    struct pcmcia_device *link = local->finder;
     void __iomem *p = local->sram + HOST_TO_ECF_BASE;
 
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_update_multi_list - device not present\n");
         return;
     }
@@ -1968,7 +1884,7 @@ static void ray_update_multi_list(struct net_device *dev, int all)
 /*===========================================================================*/
 static void set_multicast_list(struct net_device *dev)
 {
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
     UCHAR promisc;
 
     DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev);
@@ -2002,10 +1918,10 @@ static void set_multicast_list(struct net_device *dev)
 /*=============================================================================
  * All routines below here are run at interrupt time.
 =============================================================================*/
-static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ray_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *)dev_id;
-    dev_link_t *link;
+    struct pcmcia_device *link;
     ray_dev_t *local;
     struct ccs __iomem *pccs;
     struct rcs __iomem *prcs;
@@ -2019,9 +1935,9 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 
     DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
 
-    local = (ray_dev_t *)dev->priv;
-    link = (dev_link_t *)local->finder;
-    if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
+    local = netdev_priv(dev);
+    link = (struct pcmcia_device *)local->finder;
+    if (!pcmcia_dev_present(link)) {
         DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
         return IRQ_NONE;
     }
@@ -2249,7 +2165,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
 {
     struct sk_buff *skb = NULL;
     struct rcs __iomem *prcslink = prcs;
-    ray_dev_t *local = dev->priv;
+    ray_dev_t *local = netdev_priv(dev);
     UCHAR *rx_ptr;
     int total_len;
     int tmp;
@@ -2316,7 +2232,6 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
         return;
     }
     skb_reserve( skb, 2);   /* Align IP on 16 byte (TBD check this)*/
-    skb->dev = dev;
 
     DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
 
@@ -2327,7 +2242,8 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
     rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
     /* Get source address */
 #ifdef WIRELESS_SPY
-    memcpy(linksrcaddr, ((struct mac_header *)skb->data)->addr_2, ETH_ALEN);
+    skb_copy_from_linear_data_offset(skb, offsetof(struct mac_header, addr_2),
+                                    linksrcaddr, ETH_ALEN);
 #endif
     /* Now, deal with encapsulation/translation/sniffer */
     if (!sniffer) {
@@ -2402,32 +2318,17 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
 static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
 {
     snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
-    struct mac_header *pmac = (struct mac_header *)skb->data;
-    unsigned short type = *(unsigned short *)psnap->ethertype;
-    unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff;
-    unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff;
+    struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
+    __be16 type = *(__be16 *)psnap->ethertype;
     int delta;
     struct ethhdr *peth;
     UCHAR srcaddr[ADDRLEN];
     UCHAR destaddr[ADDRLEN];
+    static UCHAR org_bridge[3] = {0, 0, 0xf8};
+    static UCHAR org_1042[3] = {0, 0, 0};
 
-    if (pmac->frame_ctl_2 & FC2_FROM_DS) {
-       if (pmac->frame_ctl_2 & FC2_TO_DS) { /* AP to AP */
-           memcpy(destaddr, pmac->addr_3, ADDRLEN);
-           memcpy(srcaddr, ((unsigned char *)pmac->addr_3) + ADDRLEN, ADDRLEN);
-       } else { /* AP to terminal */
-           memcpy(destaddr, pmac->addr_1, ADDRLEN);
-           memcpy(srcaddr, pmac->addr_3, ADDRLEN); 
-       }
-    } else { /* Terminal to AP */
-       if (pmac->frame_ctl_2 & FC2_TO_DS) {
-           memcpy(destaddr, pmac->addr_3, ADDRLEN);
-           memcpy(srcaddr, pmac->addr_2, ADDRLEN); 
-       } else { /* Adhoc */
-           memcpy(destaddr, pmac->addr_1, ADDRLEN);
-           memcpy(srcaddr, pmac->addr_2, ADDRLEN); 
-       }
-    }
+    memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
+    memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
 
 #ifdef PCMCIA_DEBUG
     if (pc_debug > 3) {
@@ -2435,33 +2336,34 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
     printk(KERN_DEBUG "skb->data before untranslate");
     for (i=0;i<64;i++) 
         printk("%02x ",skb->data[i]);
-    printk("\n" KERN_DEBUG "type = %08x, xsap = %08x, org = %08x\n",
-           type,xsap,org);
+    printk("\n" KERN_DEBUG "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
+           ntohs(type),
+          psnap->dsap, psnap->ssap, psnap->ctrl,
+          psnap->org[0], psnap->org[1], psnap->org[2]);
     printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
     }
 #endif
 
-    if ( xsap != SNAP_ID) {
+    if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
         /* not a snap type so leave it alone */
-        DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff);
+        DEBUG(3,"ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+               psnap->dsap, psnap->ssap, psnap->ctrl);
 
         delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
         peth = (struct ethhdr *)(skb->data + delta);
         peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
     }
     else { /* Its a SNAP */
-        if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC  */
+        if (memcmp(psnap->org, org_bridge, 3) == 0) { /* EtherII and nuke the LLC  */
         DEBUG(3,"ray_cs untranslate Bridge encap\n");
             delta = RX_MAC_HEADER_LENGTH 
                 + sizeof(struct snaphdr_t) - ETH_HLEN;
             peth = (struct ethhdr *)(skb->data + delta);
             peth->h_proto = type;
-        }
-        else {
-            if (org == RFC1042_ENCAP) {
-                switch (type) {
-                case RAY_IPX_TYPE:
-                case APPLEARP_TYPE:
+       } else if (memcmp(psnap->org, org_1042, 3) == 0) {
+                switch (ntohs(type)) {
+                case ETH_P_IPX:
+                case ETH_P_AARP:
                     DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
                     delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
                     peth = (struct ethhdr *)(skb->data + delta);
@@ -2475,14 +2377,12 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
                     peth->h_proto = type;
                     break;
                 }
-            }
-            else {
+       } else {
                 printk("ray_cs untranslate very confused by packet\n");
                 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
                 peth = (struct ethhdr *)(skb->data + delta);
                 peth->h_proto = type;
-            }
-        }
+       }
     }
 /* TBD reserve  skb_reserve(skb, delta); */
     skb_pull(skb, delta);
@@ -2540,9 +2440,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
 /*===========================================================================*/
 static void authenticate(ray_dev_t *local)
 {
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
     DEBUG(0,"ray_cs Starting authentication.\n");
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs authenticate - device not present\n");
         return;
     }
@@ -2606,10 +2506,10 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
 static void associate(ray_dev_t *local)
 {
     struct ccs __iomem *pccs;
-    dev_link_t *link = local->finder;
+    struct pcmcia_device *link = local->finder;
     struct net_device *dev = link->priv;
     int ccsindex;
-    if (!(link->state & DEV_PRESENT)) {
+    if (!(pcmcia_dev_present(link))) {
         DEBUG(2,"ray_cs associate - device not present\n");
         return;
     }
@@ -2683,107 +2583,117 @@ static char *nettype[] = {"Adhoc", "Infra "};
 static char *framing[] = {"Encapsulation", "Translation"}
 ;
 /*===========================================================================*/
-static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
+static int ray_cs_proc_show(struct seq_file *m, void *v)
 {
 /* Print current values which are not available via other means
  * eg ifconfig 
  */
     int i;
-    dev_link_t *link;
+    struct pcmcia_device *link;
     struct net_device *dev;
     ray_dev_t *local;
     UCHAR *p;
     struct freq_hop_element *pfh;
     UCHAR c[33];
+    DECLARE_MAC_BUF(mac);
 
-    link = dev_list;
+    link = this_device;
     if (!link)
        return 0;
     dev = (struct net_device *)link->priv;
     if (!dev)
        return 0;
-    local = (ray_dev_t *)dev->priv;
+    local = netdev_priv(dev);
     if (!local)
        return 0;
 
-    len = 0;
-
-    len += sprintf(buf + len, "Raylink Wireless LAN driver status\n");
-    len += sprintf(buf + len, "%s\n", rcsid);
+    seq_puts(m, "Raylink Wireless LAN driver status\n");
+    seq_printf(m, "%s\n", rcsid);
     /* build 4 does not report version, and field is 0x55 after memtest */
-    len += sprintf(buf + len, "Firmware version     = ");
+    seq_puts(m, "Firmware version     = ");
     if (local->fw_ver == 0x55)
-        len += sprintf(buf + len, "4 - Use dump_cis for more details\n");
+        seq_puts(m, "4 - Use dump_cis for more details\n");
     else
-        len += sprintf(buf + len, "%2d.%02d.%02d\n",
+        seq_printf(m, "%2d.%02d.%02d\n",
                    local->fw_ver, local->fw_bld, local->fw_var);
 
     for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
     c[32] = 0;
-    len += sprintf(buf + len, "%s network ESSID = \"%s\"\n", 
+    seq_printf(m, "%s network ESSID = \"%s\"\n",
                    nettype[local->sparm.b5.a_network_type], c);
 
     p = local->bss_id;
-    len += sprintf(buf + len, 
-                   "BSSID                = %02x:%02x:%02x:%02x:%02x:%02x\n",
-                   p[0],p[1],p[2],p[3],p[4],p[5]);
+    seq_printf(m, "BSSID                = %s\n",
+                   print_mac(mac, p));
 
-    len += sprintf(buf + len, "Country code         = %d\n", 
+    seq_printf(m, "Country code         = %d\n",
                    local->sparm.b5.a_curr_country_code);
 
     i = local->card_status;
     if (i < 0) i = 10;
     if (i > 16) i = 10;
-    len += sprintf(buf + len, "Card status          = %s\n", card_status[i]);
+    seq_printf(m, "Card status          = %s\n", card_status[i]);
 
-    len += sprintf(buf + len, "Framing mode         = %s\n",framing[translate]);
+    seq_printf(m, "Framing mode         = %s\n",framing[translate]);
 
-    len += sprintf(buf + len, "Last pkt signal lvl  = %d\n", local->last_rsl);
+    seq_printf(m, "Last pkt signal lvl  = %d\n", local->last_rsl);
 
     if (local->beacon_rxed) {
        /* Pull some fields out of last beacon received */
-       len += sprintf(buf + len, "Beacon Interval      = %d Kus\n", 
+       seq_printf(m, "Beacon Interval      = %d Kus\n",
                       local->last_bcn.beacon_intvl[0]
                       + 256 * local->last_bcn.beacon_intvl[1]);
     
     p = local->last_bcn.elements;
     if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
     else {
-        len += sprintf(buf + len, "Parse beacon failed at essid element id = %d\n",p[0]);
-        return len;
+        seq_printf(m, "Parse beacon failed at essid element id = %d\n",p[0]);
+        return 0;
     }
 
     if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
-        len += sprintf(buf + len, "Supported rate codes = ");
+        seq_puts(m, "Supported rate codes = ");
         for (i=2; i<p[1] + 2; i++) 
-            len += sprintf(buf + len, "0x%02x ", p[i]);
-        len += sprintf(buf + len, "\n");
+            seq_printf(m, "0x%02x ", p[i]);
+        seq_putc(m, '\n');
         p += p[1] + 2;
     }
     else {
-        len += sprintf(buf + len, "Parse beacon failed at rates element\n");
-        return len;
+        seq_puts(m, "Parse beacon failed at rates element\n");
+        return 0;
     }
 
        if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
            pfh = (struct freq_hop_element *)p;
-           len += sprintf(buf + len, "Hop dwell            = %d Kus\n",
+           seq_printf(m, "Hop dwell            = %d Kus\n",
                           pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
-           len += sprintf(buf + len, "Hop set              = %d \n", pfh->hop_set);
-           len += sprintf(buf + len, "Hop pattern          = %d \n", pfh->hop_pattern);
-           len += sprintf(buf + len, "Hop index            = %d \n", pfh->hop_index);
+           seq_printf(m, "Hop set              = %d \n", pfh->hop_set);
+           seq_printf(m, "Hop pattern          = %d \n", pfh->hop_pattern);
+           seq_printf(m, "Hop index            = %d \n", pfh->hop_index);
            p += p[1] + 2;
        }
        else {
-           len += sprintf(buf + len, "Parse beacon failed at FH param element\n");
-           return len;
+           seq_puts(m, "Parse beacon failed at FH param element\n");
+           return 0;
        }
     } else {
-       len += sprintf(buf + len, "No beacons received\n");
+       seq_puts(m, "No beacons received\n");
     }
-    return len;
+    return 0;
 }
 
+static int ray_cs_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ray_cs_proc_show, NULL);
+}
+
+static const struct file_operations ray_cs_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = ray_cs_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif
 /*===========================================================================*/
 static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
@@ -2898,7 +2808,7 @@ static struct pcmcia_driver ray_driver = {
        .drv            = {
                .name   = "ray_cs",
        },
-       .probe          = ray_attach,
+       .probe          = ray_probe,
        .remove         = ray_detach,
        .id_table       = ray_ids,
        .suspend        = ray_suspend,
@@ -2916,7 +2826,7 @@ static int __init init_ray_cs(void)
 #ifdef CONFIG_PROC_FS
     proc_mkdir("driver/ray_cs", NULL);
 
-    create_proc_info_entry("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_read);
+    proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
     raycs_write("driver/ray_cs/essid", write_essid, NULL);
     raycs_write("driver/ray_cs/net_type", write_int, &net_type);
     raycs_write("driver/ray_cs/translate", write_int, &translate);
@@ -2940,7 +2850,6 @@ static void __exit exit_ray_cs(void)
 #endif
 
     pcmcia_unregister_driver(&ray_driver);
-    BUG_ON(dev_list != NULL);
 } /* exit_ray_cs */
 
 module_init(init_ray_cs);