Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / net / wireless / wavelan_cs.c
index 0579717..f7724eb 100644 (file)
 /* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
 #include "wavelan_cs.p.h"              /* Private header */
 
+#ifdef WAVELAN_ROAMING
+static void wl_cell_expiry(unsigned long data);
+static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp);
+static void wv_nwid_filter(unsigned char mode, net_local *lp);
+#endif  /*  WAVELAN_ROAMING  */
+
 /************************* MISC SUBROUTINES **************************/
 /*
  * Subroutines which won't fit in one of the following category
@@ -136,7 +142,8 @@ psa_read(struct net_device *        dev,
         u_char *       b,      /* buffer to fill */
         int            n)      /* size to read */
 {
-  u_char *     ptr = ((u_char *)dev->mem_start) + PSA_ADDR + (o << 1);
+  net_local *lp = netdev_priv(dev);
+  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
 
   while(n-- > 0)
     {
@@ -160,12 +167,13 @@ psa_write(struct net_device *     dev,
          u_char *      b,      /* Buffer in memory */
          int           n)      /* Length of buffer */
 {
-  u_char *     ptr = ((u_char *) dev->mem_start) + PSA_ADDR + (o << 1);
+  net_local *lp = netdev_priv(dev);
+  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
   int          count = 0;
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   /* As there seem to have no flag PSA_BUSY as in the ISA model, we are
    * oblige to verify this address to know when the PSA is ready... */
-  volatile u_char *    verify = ((u_char *) dev->mem_start) + PSA_ADDR +
+  volatile u_char __iomem *verify = lp->mem + PSA_ADDR +
     (psaoff(0, psa_comp_number) << 1);
 
   /* Authorize writting to PSA */
@@ -407,7 +415,6 @@ fee_read(u_long             base,   /* i/o port of the card */
     }
 }
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -492,15 +499,14 @@ fee_write(u_long  base,   /* i/o port of the card */
   fee_wait(base, 10, 100);
 #endif /* EEPROM_IS_PROTECTED */
 }
-#endif /* WIRELESS_EXT */
 
 /******************* WaveLAN Roaming routines... ********************/
 
 #ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */
 
-unsigned char WAVELAN_BEACON_ADDRESS[]= {0x09,0x00,0x0e,0x20,0x03,0x00};
+static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00};
   
-void wv_roam_init(struct net_device *dev)
+static void wv_roam_init(struct net_device *dev)
 {
   net_local  *lp= netdev_priv(dev);
 
@@ -529,7 +535,7 @@ void wv_roam_init(struct net_device *dev)
   printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
 }
  
-void wv_roam_cleanup(struct net_device *dev)
+static void wv_roam_cleanup(struct net_device *dev)
 {
   wavepoint_history *ptr,*old_ptr;
   net_local *lp= netdev_priv(dev);
@@ -548,7 +554,7 @@ void wv_roam_cleanup(struct net_device *dev)
 }
 
 /* Enable/Disable NWID promiscuous mode on a given device */
-void wv_nwid_filter(unsigned char mode, net_local *lp)
+static void wv_nwid_filter(unsigned char mode, net_local *lp)
 {
   mm_t                  m;
   unsigned long         flags;
@@ -573,7 +579,7 @@ void wv_nwid_filter(unsigned char mode, net_local *lp)
 }
 
 /* Find a record in the WavePoint table matching a given NWID */
-wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
+static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
 {
   wavepoint_history    *ptr=lp->wavepoint_table.head;
   
@@ -586,7 +592,7 @@ wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
 }
 
 /* Create a new wavepoint table entry */
-wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
+static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
 {
   wavepoint_history *new_wavepoint;
 
@@ -622,7 +628,7 @@ wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_
 }
 
 /* Remove a wavepoint entry from WavePoint table */
-void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
+static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
 {
   if(wavepoint==NULL)
     return;
@@ -644,7 +650,7 @@ void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
 }
 
 /* Timer callback function - checks WavePoint table for stale entries */ 
-void wl_cell_expiry(unsigned long data)
+static void wl_cell_expiry(unsigned long data)
 {
   net_local *lp=(net_local *)data;
   wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
@@ -684,7 +690,7 @@ void wl_cell_expiry(unsigned long data)
 }
 
 /* Update SNR history of a wavepoint */
-void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq) 
+static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)  
 {
   int i=0,num_missed=0,ptr=0;
   int average_fast=0,average_slow=0;
@@ -721,9 +727,9 @@ void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsi
 }
 
 /* Perform a handover to a new WavePoint */
-void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
+static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
 {
-  ioaddr_t              base = lp->dev->base_addr;  
+  kio_addr_t           base = lp->dev->base_addr;
   mm_t                  m;
   unsigned long         flags;
 
@@ -836,7 +842,7 @@ wv_82593_cmd(struct net_device *    dev,
             int        cmd,
             int        result)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   int          status;
   int          wait_completed;
   long         spin;
@@ -944,16 +950,8 @@ wv_82593_cmd(struct net_device *   dev,
 static inline int
 wv_diag(struct net_device *    dev)
 {
-  int          ret = FALSE;
-
-  if(wv_82593_cmd(dev, "wv_diag(): diagnose",
-                 OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED))
-    ret = TRUE;
-
-#ifdef DEBUG_CONFIG_ERROR
-  printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n");
-#endif
-  return(ret);
+  return(wv_82593_cmd(dev, "wv_diag(): diagnose",
+                     OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED));
 } /* wv_diag */
 
 /*------------------------------------------------------------------*/
@@ -968,7 +966,7 @@ read_ringbuf(struct net_device *    dev,
             char *     buf,
             int        len)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   int          ring_ptr = addr;
   int          chunk_len;
   char *       buf_ptr = buf;
@@ -1007,7 +1005,7 @@ static inline void
 wv_82593_reconfig(struct net_device *  dev)
 {
   net_local *          lp = netdev_priv(dev);
-  dev_link_t *         link = lp->link;
+  struct pcmcia_device *               link = lp->link;
   unsigned long                flags;
 
   /* Arm the flag, will be cleard in wv_82593_config() */
@@ -1134,7 +1132,7 @@ wv_psa_show(psa_t *       p)
 static void
 wv_mmc_show(struct net_device *        dev)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   mmr_t                m;
 
@@ -1153,10 +1151,8 @@ wv_mmc_show(struct net_device *  dev)
   mmc_read(base, 0, (u_char *)&m, sizeof(m));
   mmc_out(base, mmwoff(0, mmw_freeze), 0);
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
   /* Don't forget to update statistics */
   lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif /* WIRELESS_EXT */
 
   spin_unlock_irqrestore(&lp->spinlock, flags);
 
@@ -1314,7 +1310,7 @@ wv_packet_info(u_char *           p,              /* Packet to dump */
 static inline void
 wv_init_info(struct net_device *       dev)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   psa_t                psa;
   int          i;
 
@@ -1333,7 +1329,7 @@ wv_init_info(struct net_device *  dev)
 
 #ifdef DEBUG_BASIC_SHOW
   /* Now, let's go for the basic stuff */
-  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr",
+  printk(KERN_NOTICE "%s: WaveLAN: port %#lx, irq %d, hw_addr",
         dev->name, base, dev->irq);
   for(i = 0; i < WAVELAN_ADDR_SIZE; i++)
     printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]);
@@ -1542,7 +1538,6 @@ wavelan_set_mac_address(struct net_device *       dev,
 }
 #endif /* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -1868,7 +1863,7 @@ static int wavelan_set_nwid(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        mm_t m;
@@ -1958,7 +1953,7 @@ static int wavelan_set_freq(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        unsigned long flags;
        int ret;
@@ -1988,7 +1983,7 @@ static int wavelan_get_freq(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2034,7 +2029,7 @@ static int wavelan_set_sens(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2100,7 +2095,7 @@ static int wavelan_set_encode(struct net_device *dev,
                              union iwreq_data *wrqu,
                              char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        unsigned long flags;
        psa_t psa;
@@ -2170,7 +2165,7 @@ static int wavelan_get_encode(struct net_device *dev,
                              union iwreq_data *wrqu,
                              char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2277,7 +2272,7 @@ static int wavelan_get_essid(struct net_device *dev,
        extra[IW_ESSID_MAX_SIZE] = '\0';
 
        /* Set the length */
-       wrqu->data.length = strlen(extra) + 1;
+       wrqu->data.length = strlen(extra);
 
        return 0;
 }
@@ -2389,7 +2384,7 @@ static int wavelan_get_range(struct net_device *dev,
                             union iwreq_data *wrqu,
                             char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        struct iw_range *range = (struct iw_range *) extra;
        unsigned long flags;
@@ -2465,7 +2460,7 @@ static int wavelan_set_qthr(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       ioaddr_t base = dev->base_addr;
+       kio_addr_t base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2741,7 +2736,7 @@ static const struct iw_handler_def        wavelan_handler_def =
 static iw_stats *
 wavelan_get_wireless_stats(struct net_device * dev)
 {
-  ioaddr_t             base = dev->base_addr;
+  kio_addr_t           base = dev->base_addr;
   net_local *          lp = netdev_priv(dev);
   mmr_t                        m;
   iw_stats *           wstats;
@@ -2785,7 +2780,6 @@ wavelan_get_wireless_stats(struct net_device *    dev)
 #endif
   return &lp->wstats;
 }
-#endif /* WIRELESS_EXT */
 
 /************************* PACKET RECEPTION *************************/
 /*
@@ -2805,7 +2799,7 @@ wv_start_of_frame(struct net_device *     dev,
                  int           rfp,    /* end of frame */
                  int           wrap)   /* start of buffer */
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   int          rp;
   int          len;
 
@@ -2968,7 +2962,7 @@ wv_packet_read(struct net_device *                dev,
 static inline void
 wv_packet_rcv(struct net_device *      dev)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   int          newrfp;
   int          rp;
@@ -3105,7 +3099,7 @@ wv_packet_write(struct net_device *       dev,
                short           length)
 {
   net_local *          lp = netdev_priv(dev);
-  ioaddr_t             base = dev->base_addr;
+  kio_addr_t           base = dev->base_addr;
   unsigned long                flags;
   int                  clen = length;
   register u_short     xmtdata_base = TX_BASE;
@@ -3229,7 +3223,7 @@ wavelan_packet_xmit(struct sk_buff *      skb,
 static inline int
 wv_mmc_init(struct net_device *        dev)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   psa_t                psa;
   mmw_t                m;
   int          configured;
@@ -3423,7 +3417,7 @@ wv_mmc_init(struct net_device *   dev)
 static int
 wv_ru_stop(struct net_device * dev)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   unsigned long        flags;
   int          status;
@@ -3463,7 +3457,7 @@ wv_ru_stop(struct net_device *    dev)
   /* If there was a problem */
   if(spin <= 0)
     {
-#ifdef DEBUG_CONFIG_ERROR
+#ifdef DEBUG_CONFIG_ERRORS
       printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
             dev->name);
 #endif
@@ -3486,7 +3480,7 @@ wv_ru_stop(struct net_device *    dev)
 static int
 wv_ru_start(struct net_device *        dev)
 {
-  ioaddr_t     base = dev->base_addr;
+  kio_addr_t   base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   unsigned long        flags;
 
@@ -3574,7 +3568,7 @@ wv_ru_start(struct net_device *   dev)
 static int
 wv_82593_config(struct net_device *    dev)
 {
-  ioaddr_t                     base = dev->base_addr;
+  kio_addr_t                   base = dev->base_addr;
   net_local *                  lp = netdev_priv(dev);
   struct i82593_conf_block     cfblk;
   int                          ret = TRUE;
@@ -3602,8 +3596,8 @@ wv_82593_config(struct net_device *       dev)
   cfblk.lin_prio = 0;          /* conform to 802.3 backoff algoritm */
   cfblk.exp_prio = 5;          /* conform to 802.3 backoff algoritm */
   cfblk.bof_met = 1;           /* conform to 802.3 backoff algoritm */
-  cfblk.ifrm_spc = 0x20;       /* 32 bit times interframe spacing */
-  cfblk.slottim_low = 0x20;    /* 32 bit times slot time */
+  cfblk.ifrm_spc = 0x20 >> 4;  /* 32 bit times interframe spacing */
+  cfblk.slottim_low = 0x20 >> 5;       /* 32 bit times slot time */
   cfblk.slottim_hi = 0x0;
   cfblk.max_retr = 15;
   cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE);    /* Promiscuous mode */
@@ -3750,16 +3744,16 @@ wv_pcmcia_reset(struct net_device *     dev)
 {
   int          i;
   conf_reg_t   reg = { 0, CS_READ, CISREG_COR, 0 };
-  dev_link_t * link = ((net_local *)netdev_priv(dev))->link;
+  struct pcmcia_device *       link = ((net_local *)netdev_priv(dev))->link;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name);
 #endif
 
-  i = pcmcia_access_configuration_register(link->handle, &reg);
+  i = pcmcia_access_configuration_register(link, &reg);
   if(i != CS_SUCCESS)
     {
-      cs_error(link->handle, AccessConfigurationRegister, i);
+      cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
     }
       
@@ -3770,19 +3764,19 @@ wv_pcmcia_reset(struct net_device *     dev)
 
   reg.Action = CS_WRITE;
   reg.Value = reg.Value | COR_SW_RESET;
-  i = pcmcia_access_configuration_register(link->handle, &reg);
+  i = pcmcia_access_configuration_register(link, &reg);
   if(i != CS_SUCCESS)
     {
-      cs_error(link->handle, AccessConfigurationRegister, i);
+      cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
     }
       
   reg.Action = CS_WRITE;
   reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
-  i = pcmcia_access_configuration_register(link->handle, &reg);
+  i = pcmcia_access_configuration_register(link, &reg);
   if(i != CS_SUCCESS)
     {
-      cs_error(link->handle, AccessConfigurationRegister, i);
+      cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
     }
 
@@ -3811,7 +3805,7 @@ static int
 wv_hw_config(struct net_device *       dev)
 {
   net_local *          lp = netdev_priv(dev);
-  ioaddr_t             base = dev->base_addr;
+  kio_addr_t           base = dev->base_addr;
   unsigned long                flags;
   int                  ret = FALSE;
 
@@ -3946,19 +3940,17 @@ wv_hw_reset(struct net_device * dev)
  * (called by wavelan_event())
  */
 static inline int
-wv_pcmcia_config(dev_link_t *  link)
+wv_pcmcia_config(struct pcmcia_device *        link)
 {
-  client_handle_t      handle;
   tuple_t              tuple;
   cisparse_t           parse;
-  struct net_device *  dev;
+  struct net_device *  dev = (struct net_device *) link->priv;
   int                  i;
   u_char               buf[64];
   win_req_t            req;
   memreq_t             mem;
+  net_local *          lp = netdev_priv(dev);
 
-  handle = link->handle;
-  dev = (struct net_device *) link->priv;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
@@ -3972,16 +3964,16 @@ wv_pcmcia_config(dev_link_t *   link)
     {
       tuple.Attributes = 0;
       tuple.DesiredTuple = CISTPL_CONFIG;
-      i = pcmcia_get_first_tuple(handle, &tuple);
+      i = pcmcia_get_first_tuple(link, &tuple);
       if(i != CS_SUCCESS)
        break;
       tuple.TupleData = (cisdata_t *)buf;
       tuple.TupleDataMax = 64;
       tuple.TupleOffset = 0;
-      i = pcmcia_get_tuple_data(handle, &tuple);
+      i = pcmcia_get_tuple_data(link, &tuple);
       if(i != CS_SUCCESS)
        break;
-      i = pcmcia_parse_tuple(handle, &tuple, &parse);
+      i = pcmcia_parse_tuple(link, &tuple, &parse);
       if(i != CS_SUCCESS)
        break;
       link->conf.ConfigBase = parse.config.base;
@@ -3990,19 +3982,16 @@ wv_pcmcia_config(dev_link_t *   link)
   while(0);
   if(i != CS_SUCCESS)
     {
-      cs_error(link->handle, ParseTuple, i);
-      link->state &= ~DEV_CONFIG_PENDING;
+      cs_error(link, ParseTuple, i);
       return FALSE;
     }
-    
-  /* Configure card */
-  link->state |= DEV_CONFIG;
+
   do
     {
-      i = pcmcia_request_io(link->handle, &link->io);
+      i = pcmcia_request_io(link, &link->io);
       if(i != CS_SUCCESS)
        {
-         cs_error(link->handle, RequestIO, i);
+         cs_error(link, RequestIO, i);
          break;
        }
 
@@ -4010,10 +3999,10 @@ wv_pcmcia_config(dev_link_t *   link)
        * Now allocate an interrupt line.  Note that this does not
        * actually assign a handler to the interrupt.
        */
-      i = pcmcia_request_irq(link->handle, &link->irq);
+      i = pcmcia_request_irq(link, &link->irq);
       if(i != CS_SUCCESS)
        {
-         cs_error(link->handle, RequestIRQ, i);
+         cs_error(link, RequestIRQ, i);
          break;
        }
 
@@ -4022,15 +4011,15 @@ wv_pcmcia_config(dev_link_t *   link)
        * the I/O windows and the interrupt mapping.
        */
       link->conf.ConfigIndex = 1;
-      i = pcmcia_request_configuration(link->handle, &link->conf);
+      i = pcmcia_request_configuration(link, &link->conf);
       if(i != CS_SUCCESS)
        {
-         cs_error(link->handle, RequestConfiguration, i);
+         cs_error(link, RequestConfiguration, i);
          break;
        }
 
       /*
-       * Allocate a small memory window.  Note that the dev_link_t
+       * Allocate a small memory window.  Note that the struct pcmcia_device
        * structure provides space for one window handle -- if your
        * device needs several windows, you'll need to keep track of
        * the handles in your private data structure, link->priv.
@@ -4038,21 +4027,22 @@ wv_pcmcia_config(dev_link_t *   link)
       req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
       req.Base = req.Size = 0;
       req.AccessSpeed = mem_speed;
-      i = pcmcia_request_window(&link->handle, &req, &link->win);
+      i = pcmcia_request_window(&link, &req, &link->win);
       if(i != CS_SUCCESS)
        {
-         cs_error(link->handle, RequestWindow, i);
+         cs_error(link, RequestWindow, i);
          break;
        }
 
-      dev->mem_start = (u_long)ioremap(req.Base, req.Size);
+      lp->mem = ioremap(req.Base, req.Size);
+      dev->mem_start = (u_long)lp->mem;
       dev->mem_end = dev->mem_start + req.Size;
 
       mem.CardOffset = 0; mem.Page = 0;
       i = pcmcia_map_mem_page(link->win, &mem);
       if(i != CS_SUCCESS)
        {
-         cs_error(link->handle, MapMemPage, i);
+         cs_error(link, MapMemPage, i);
          break;
        }
 
@@ -4062,10 +4052,11 @@ wv_pcmcia_config(dev_link_t *   link)
       netif_start_queue(dev);
 
 #ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART 0x%x IRQ %d IOPORT 0x%x\n",
-            (u_int) dev->mem_start, dev->irq, (u_int) dev->base_addr);
+      printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n",
+            lp->mem, dev->irq, (u_int) dev->base_addr);
 #endif
 
+      SET_NETDEV_DEV(dev, &handle_to_dev(link));
       i = register_netdev(dev);
       if(i != 0)
        {
@@ -4077,7 +4068,6 @@ wv_pcmcia_config(dev_link_t *     link)
     }
   while(0);            /* Humm... Disguised goto !!! */
 
-  link->state &= ~DEV_CONFIG_PENDING;
   /* If any step failed, release any partially configured state */
   if(i != 0)
     {
@@ -4086,7 +4076,7 @@ wv_pcmcia_config(dev_link_t *     link)
     }
 
   strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
-  link->dev = &((net_local *) netdev_priv(dev))->node;
+  link->dev_node = &((net_local *) netdev_priv(dev))->node;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
@@ -4101,25 +4091,20 @@ wv_pcmcia_config(dev_link_t *   link)
  * still open, this will be postponed until it is closed.
  */
 static void
-wv_pcmcia_release(dev_link_t *link)
+wv_pcmcia_release(struct pcmcia_device *link)
 {
-  struct net_device *  dev = (struct net_device *) link->priv;
+       struct net_device *     dev = (struct net_device *) link->priv;
+       net_local *             lp = netdev_priv(dev);
 
 #ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
+       printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
 #endif
 
-  /* Don't bother checking to see if these succeed or not */
-  iounmap((u_char *)dev->mem_start);
-  pcmcia_release_window(link->win);
-  pcmcia_release_configuration(link->handle);
-  pcmcia_release_io(link->handle, &link->io);
-  pcmcia_release_irq(link->handle, &link->irq);
-
-  link->state &= ~DEV_CONFIG;
+       iounmap(lp->mem);
+       pcmcia_disable_device(link);
 
 #ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
+       printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
 #endif
 }
 
@@ -4140,7 +4125,7 @@ wavelan_interrupt(int             irq,
 {
   struct net_device *  dev;
   net_local *  lp;
-  ioaddr_t     base;
+  kio_addr_t   base;
   int          status0;
   u_int                tx_status;
 
@@ -4408,7 +4393,7 @@ static void
 wavelan_watchdog(struct net_device *   dev)
 {
   net_local *          lp = netdev_priv(dev);
-  ioaddr_t             base = dev->base_addr;
+  kio_addr_t           base = dev->base_addr;
   unsigned long                flags;
   int                  aborted = FALSE;
 
@@ -4483,8 +4468,8 @@ static int
 wavelan_open(struct net_device *       dev)
 {
   net_local *  lp = netdev_priv(dev);
-  dev_link_t * link = lp->link;
-  ioaddr_t     base = dev->base_addr;
+  struct pcmcia_device *       link = lp->link;
+  kio_addr_t   base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
@@ -4537,8 +4522,8 @@ wavelan_open(struct net_device *  dev)
 static int
 wavelan_close(struct net_device *      dev)
 {
-  dev_link_t * link = ((net_local *)netdev_priv(dev))->link;
-  ioaddr_t     base = dev->base_addr;
+  struct pcmcia_device *       link = ((net_local *)netdev_priv(dev))->link;
+  kio_addr_t   base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
@@ -4590,55 +4575,37 @@ wavelan_close(struct net_device *       dev)
  * configure the card at this point -- we wait until we receive a
  * card insertion event.
  */
-static dev_link_t *
-wavelan_attach(void)
+static int
+wavelan_probe(struct pcmcia_device *p_dev)
 {
-  client_reg_t client_reg;     /* Register with cardmgr */
-  dev_link_t * link;           /* Info for cardmgr */
   struct net_device *  dev;            /* Interface generic data */
   net_local *  lp;             /* Interface specific data */
-  int          i, ret;
+  int ret;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_attach()\n");
 #endif
 
-  /* Initialize the dev_link_t structure */
-  link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-  if (!link) return NULL;
-  memset(link, 0, sizeof(struct dev_link_t));
-
   /* The io structure describes IO port mapping */
-  link->io.NumPorts1 = 8;
-  link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-  link->io.IOAddrLines = 3;
+  p_dev->io.NumPorts1 = 8;
+  p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+  p_dev->io.IOAddrLines = 3;
 
   /* Interrupt setup */
-  link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-  link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-  if (irq_list[0] == -1)
-    link->irq.IRQInfo2 = irq_mask;
-  else
-    for (i = 0; i < 4; i++)
-      link->irq.IRQInfo2 |= 1 << irq_list[i];
-  link->irq.Handler = wavelan_interrupt;
+  p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+  p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+  p_dev->irq.Handler = wavelan_interrupt;
 
   /* General socket configuration */
-  link->conf.Attributes = CONF_ENABLE_IRQ;
-  link->conf.Vcc = 50;
-  link->conf.IntType = INT_MEMORY_AND_IO;
-
-  /* Chain drivers */
-  link->next = dev_list;
-  dev_list = link;
+  p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+  p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
   /* Allocate the generic data structure */
   dev = alloc_etherdev(sizeof(net_local));
-  if (!dev) {
-      kfree(link);
-      return NULL;
-  }
-  link->priv = link->irq.Instance = dev;
+  if (!dev)
+      return -ENOMEM;
+
+  p_dev->priv = p_dev->irq.Instance = dev;
 
   lp = netdev_priv(dev);
 
@@ -4655,7 +4622,6 @@ wavelan_attach(void)
   spin_lock_init(&lp->spinlock);
 
   /* back links */
-  lp->link = link;
   lp->dev = dev;
 
   /* wavelan NET3 callbacks */
@@ -4674,44 +4640,31 @@ wavelan_attach(void)
   dev->watchdog_timeo  = WATCHDOG_JIFFIES;
   SET_ETHTOOL_OPS(dev, &ops);
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
   dev->wireless_handlers = &wavelan_handler_def;
   lp->wireless_data.spy_data = &lp->spy_data;
   dev->wireless_data = &lp->wireless_data;
-#endif
 
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
 
-  /* Register with Card Services */
-  client_reg.dev_info = &dev_info;
-  client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-  client_reg.EventMask = 
-    CS_EVENT_REGISTRATION_COMPLETE |
-    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-  client_reg.event_handler = &wavelan_event;
-  client_reg.Version = 0x0210;
-  client_reg.event_callback_args.client_data = link;
+  ret = wv_pcmcia_config(p_dev);
+  if (ret)
+         return ret;
 
-#ifdef DEBUG_CONFIG_INFO
-  printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n");
-#endif
+  ret = wv_hw_config(dev);
+  if (ret) {
+         dev->irq = 0;
+         pcmcia_disable_device(p_dev);
+         return ret;
+  }
 
-  ret = pcmcia_register_client(&link->handle, &client_reg);
-  if(ret != 0)
-    {
-      cs_error(link->handle, RegisterClient, ret);
-      wavelan_detach(link);
-      return NULL;
-    }
+  wv_init_info(dev);
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "<- wavelan_attach()\n");
 #endif
 
-  return link;
+  return 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -4722,48 +4675,14 @@ wavelan_attach(void)
  * is released.
  */
 static void
-wavelan_detach(dev_link_t *    link)
+wavelan_detach(struct pcmcia_device *link)
 {
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
 #endif
 
-  /*
-   * If the device is currently configured and active, we won't
-   * actually delete it yet.  Instead, it is marked so that when the
-   * release() function is called, that will trigger a proper
-   * detach().
-   */
-  if(link->state & DEV_CONFIG)
-    {
-      /* Some others haven't done their job : give them another chance */
-      wv_pcmcia_release(link);
-    }
-
-  /* Break the link with Card Services */
-  if(link->handle)
-    pcmcia_deregister_client(link->handle);
-    
-  /* Remove the interface data from the linked list */
-  if(dev_list == link)
-    dev_list = link->next;
-  else
-    {
-      dev_link_t *     prev = dev_list;
-
-      while((prev != (dev_link_t *) NULL) && (prev->next != link))
-       prev = prev->next;
-
-      if(prev == (dev_link_t *) NULL)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
-#endif
-         return;
-       }
-
-      prev->next = link->next;
-    }
+  /* Some others haven't done their job : give them another chance */
+  wv_pcmcia_release(link);
 
   /* Free pieces */
   if(link->priv)
@@ -4772,79 +4691,23 @@ wavelan_detach(dev_link_t *     link)
 
       /* Remove ourselves from the kernel list of ethernet devices */
       /* Warning : can't be called from interrupt, timer or wavelan_close() */
-      if (link->dev)
+      if (link->dev_node)
        unregister_netdev(dev);
-      link->dev = NULL;
+      link->dev_node = NULL;
       ((net_local *)netdev_priv(dev))->link = NULL;
       ((net_local *)netdev_priv(dev))->dev = NULL;
       free_netdev(dev);
     }
-  kfree(link);
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "<- wavelan_detach()\n");
 #endif
 }
 
-/*------------------------------------------------------------------*/
-/*
- * The card status event handler. Mostly, this schedules other stuff
- * to run after an event is received. A CARD_REMOVAL event also sets
- * some flags to discourage the net drivers from trying to talk to the
- * card any more.
- */
-static int
-wavelan_event(event_t          event,          /* The event received */
-             int               priority,
-             event_callback_args_t *   args)
+static int wavelan_suspend(struct pcmcia_device *link)
 {
-  dev_link_t * link = (dev_link_t *) args->client_data;
-  struct net_device *  dev = (struct net_device *) link->priv;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "->wavelan_event(): %s\n",
-        ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
-         ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
-          ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
-           ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
-            ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
-             ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
-              ((event == CS_EVENT_CARD_RESET) ? "card reset" :
-               "unknown"))))))));
-#endif
-
-    switch(event)
-      {
-      case CS_EVENT_REGISTRATION_COMPLETE:
-#ifdef DEBUG_CONFIG_INFO
-       printk(KERN_DEBUG "wavelan_cs: registration complete\n");
-#endif
-       break;
+       struct net_device *     dev = (struct net_device *) link->priv;
 
-      case CS_EVENT_CARD_REMOVAL:
-       /* Oups ! The card is no more there */
-       link->state &= ~DEV_PRESENT;
-       if(link->state & DEV_CONFIG)
-         {
-           /* Accept no more transmissions */
-           netif_device_detach(dev);
-
-           /* Release the card */
-           wv_pcmcia_release(link);
-         }
-       break;
-
-      case CS_EVENT_CARD_INSERTION:
-       /* Reset and configure the card */
-       link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-       if(wv_pcmcia_config(link) &&
-          wv_hw_config(dev))
-         wv_init_info(dev);
-       else
-         dev->irq = 0;
-       break;
-
-      case CS_EVENT_PM_SUSPEND:
        /* NB: wavelan_close will be called, but too late, so we are
         * obliged to close nicely the wavelan here. David, could you
         * close the device before suspending them ? And, by the way,
@@ -4854,50 +4717,47 @@ wavelan_event(event_t           event,          /* The event received */
        /* Stop receiving new messages and wait end of transmission */
        wv_ru_stop(dev);
 
+       if (link->open)
+               netif_device_detach(dev);
+
        /* Power down the module */
        hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
 
-       /* The card is now suspended */
-       link->state |= DEV_SUSPEND;
-       /* Fall through... */
-      case CS_EVENT_RESET_PHYSICAL:
-       if(link->state & DEV_CONFIG)
-         {
-           if(link->open)
-             netif_device_detach(dev);
-           pcmcia_release_configuration(link->handle);
-         }
-       break;
+       return 0;
+}
 
-      case CS_EVENT_PM_RESUME:
-       link->state &= ~DEV_SUSPEND;
-       /* Fall through... */
-      case CS_EVENT_CARD_RESET:
-       if(link->state & DEV_CONFIG)
-         {
-           pcmcia_request_configuration(link->handle, &link->conf);
-           if(link->open)      /* If RESET -> True, If RESUME -> False ? */
-             {
+static int wavelan_resume(struct pcmcia_device *link)
+{
+       struct net_device *     dev = (struct net_device *) link->priv;
+
+       if (link->open) {
                wv_hw_reset(dev);
                netif_device_attach(dev);
-             }
-         }
-       break;
-    }
+       }
 
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<-wavelan_event()\n");
-#endif
-  return 0;
+       return 0;
 }
 
+
+static struct pcmcia_device_id wavelan_ids[] = {
+       PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
+       PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
+       PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/PCMCIA", 0x23eb9949, 0x1bc50975),
+       PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/PCMCIA", 0x24358cd4, 0x1bc50975),
+       PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, wavelan_ids);
+
 static struct pcmcia_driver wavelan_driver = {
        .owner          = THIS_MODULE,
        .drv            = {
                .name   = "wavelan_cs",
        },
-       .attach         = wavelan_attach,
-       .detach         = wavelan_detach,
+       .probe          = wavelan_probe,
+       .remove         = wavelan_detach,
+       .id_table       = wavelan_ids,
+       .suspend        = wavelan_suspend,
+       .resume         = wavelan_resume,
 };
 
 static int __init