[NET]: Undo code bloat in hot paths due to print_mac().
[safe/jmp/linux-2.6] / drivers / net / wireless / wavelan_cs.c
index 7e2039f..06eea6a 100644 (file)
@@ -71,27 +71,6 @@ static void wv_nwid_filter(unsigned char mode, net_local *lp);
  * (wavelan modem or i82593)
  */
 
-#ifdef STRUCT_CHECK
-/*------------------------------------------------------------------*/
-/*
- * Sanity routine to verify the sizes of the various WaveLAN interface
- * structures.
- */
-static char *
-wv_structuct_check(void)
-{
-#define        SC(t,s,n)       if (sizeof(t) != s) return(n);
-
-  SC(psa_t, PSA_SIZE, "psa_t");
-  SC(mmw_t, MMW_SIZE, "mmw_t");
-  SC(mmr_t, MMR_SIZE, "mmr_t");
-
-#undef SC
-
-  return((char *) NULL);
-} /* wv_structuct_check */
-#endif /* STRUCT_CHECK */
-
 /******************* MODEM MANAGEMENT SUBROUTINES *******************/
 /*
  * Useful subroutines to manage the modem of the wavelan
@@ -170,13 +149,13 @@ psa_write(struct net_device *     dev,
   net_local *lp = netdev_priv(dev);
   u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
   int          count = 0;
-  kio_addr_t   base = dev->base_addr;
+  unsigned int 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 __iomem *verify = lp->mem + PSA_ADDR +
     (psaoff(0, psa_comp_number) << 1);
 
-  /* Authorize writting to PSA */
+  /* Authorize writing to PSA */
   hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN);
 
   while(n-- > 0)
@@ -603,7 +582,7 @@ static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char se
   if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
     return NULL;
   
-  new_wavepoint=(wavepoint_history *) kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
+  new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
   if(new_wavepoint==NULL)
     return NULL;
   
@@ -729,7 +708,7 @@ static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqua
 /* Perform a handover to a new WavePoint */
 static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
 {
-  kio_addr_t           base = lp->dev->base_addr;
+  unsigned int         base = lp->dev->base_addr;
   mm_t                  m;
   unsigned long         flags;
 
@@ -842,7 +821,7 @@ wv_82593_cmd(struct net_device *    dev,
             int        cmd,
             int        result)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   int          status;
   int          wait_completed;
   long         spin;
@@ -950,16 +929,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_ERRORS
-  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 */
 
 /*------------------------------------------------------------------*/
@@ -974,7 +945,7 @@ read_ringbuf(struct net_device *    dev,
             char *     buf,
             int        len)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   int          ring_ptr = addr;
   int          chunk_len;
   char *       buf_ptr = buf;
@@ -1013,7 +984,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() */
@@ -1050,6 +1021,7 @@ wv_82593_reconfig(struct net_device *     dev)
 static void
 wv_psa_show(psa_t *    p)
 {
+  DECLARE_MAC_BUF(mac);
   printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
   printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
         p->psa_io_base_addr_1,
@@ -1063,29 +1035,13 @@ wv_psa_show(psa_t *     p)
   printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
   printk("psa_int_req_no: %d\n", p->psa_int_req_no);
 #ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-        p->psa_unused0[0],
-        p->psa_unused0[1],
-        p->psa_unused0[2],
-        p->psa_unused0[3],
-        p->psa_unused0[4],
-        p->psa_unused0[5],
-        p->psa_unused0[6]);
+  printk(KERN_DEBUG "psa_unused0[]: %s\n",
+        print_mac(mac, p->psa_unused0));
 #endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",
-        p->psa_univ_mac_addr[0],
-        p->psa_univ_mac_addr[1],
-        p->psa_univ_mac_addr[2],
-        p->psa_univ_mac_addr[3],
-        p->psa_univ_mac_addr[4],
-        p->psa_univ_mac_addr[5]);
-  printk(KERN_DEBUG "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",
-        p->psa_local_mac_addr[0],
-        p->psa_local_mac_addr[1],
-        p->psa_local_mac_addr[2],
-        p->psa_local_mac_addr[3],
-        p->psa_local_mac_addr[4],
-        p->psa_local_mac_addr[5]);
+  printk(KERN_DEBUG "psa_univ_mac_addr[]: %s\n",
+        print_mac(mac, p->psa_univ_mac_addr));
+  printk(KERN_DEBUG "psa_local_mac_addr[]: %s\n",
+        print_mac(mac, p->psa_local_mac_addr));
   printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
   printk("psa_comp_number: %d, ", p->psa_comp_number);
   printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
@@ -1140,7 +1096,7 @@ wv_psa_show(psa_t *       p)
 static void
 wv_mmc_show(struct net_device *        dev)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   mmr_t                m;
 
@@ -1176,7 +1132,7 @@ wv_mmc_show(struct net_device *   dev)
         m.mmr_unused0[6],
         m.mmr_unused0[7]);
 #endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "Encryption algorythm: %02X - Status: %02X\n",
+  printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
         m.mmr_des_avail, m.mmr_des_status);
 #ifdef DEBUG_SHOW_UNUSED
   printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
@@ -1285,11 +1241,12 @@ wv_packet_info(u_char *         p,              /* Packet to dump */
 {
   int          i;
   int          maxi;
+  DECLARE_MAC_BUF(mac);
 
-  printk(KERN_DEBUG "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n",
-        msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length);
-  printk(KERN_DEBUG "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n",
-        msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13]);
+  printk(KERN_DEBUG "%s: %s(): dest %s, length %d\n",
+        msg1, msg2, print_mac(mac, p), length);
+  printk(KERN_DEBUG "%s: %s(): src %s, type 0x%02X%02X\n",
+        msg1, msg2, print_mac(mac, &p[6]), p[12], p[13]);
 
 #ifdef DEBUG_PACKET_DUMP
 
@@ -1318,9 +1275,9 @@ wv_packet_info(u_char *           p,              /* Packet to dump */
 static inline void
 wv_init_info(struct net_device *       dev)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   psa_t                psa;
-  int          i;
+  DECLARE_MAC_BUF(mac);
 
   /* Read the parameter storage area */
   psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
@@ -1337,10 +1294,10 @@ 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 %#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]);
+  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, "
+        "hw_addr %s",
+        dev->name, base, dev->irq,
+        print_mac(mac, dev->dev_addr));
 
   /* Print current network id */
   if(psa.psa_nwid_select)
@@ -1684,7 +1641,7 @@ wv_set_frequency(u_long           base,   /* i/o port of the card */
       fee_write(base, 0x60,
                dac, 2);
 
-      /* We now should verify here that the EEprom writting was ok */
+      /* We now should verify here that the EEprom writing was ok */
 
       /* ReRead the first area */
       fee_read(base, 0x00,
@@ -1845,7 +1802,7 @@ static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
        strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1);
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
        .get_drvinfo = wl_get_drvinfo
 };
 
@@ -1871,7 +1828,7 @@ static int wavelan_set_nwid(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        mm_t m;
@@ -1961,7 +1918,7 @@ static int wavelan_set_freq(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        unsigned long flags;
        int ret;
@@ -1991,7 +1948,7 @@ static int wavelan_get_freq(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2037,7 +1994,7 @@ static int wavelan_set_sens(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2103,7 +2060,7 @@ static int wavelan_set_encode(struct net_device *dev,
                              union iwreq_data *wrqu,
                              char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        unsigned long flags;
        psa_t psa;
@@ -2173,7 +2130,7 @@ static int wavelan_get_encode(struct net_device *dev,
                              union iwreq_data *wrqu,
                              char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2280,7 +2237,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;
 }
@@ -2392,7 +2349,7 @@ static int wavelan_get_range(struct net_device *dev,
                             union iwreq_data *wrqu,
                             char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        struct iw_range *range = (struct iw_range *) extra;
        unsigned long flags;
@@ -2468,7 +2425,7 @@ static int wavelan_set_qthr(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       kio_addr_t base = dev->base_addr;
+       unsigned int base = dev->base_addr;
        net_local *lp = netdev_priv(dev);
        psa_t psa;
        unsigned long flags;
@@ -2727,9 +2684,9 @@ static const iw_handler           wavelan_private_handler[] =
 
 static const struct iw_handler_def     wavelan_handler_def =
 {
-       .num_standard   = sizeof(wavelan_handler)/sizeof(iw_handler),
-       .num_private    = sizeof(wavelan_private_handler)/sizeof(iw_handler),
-       .num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+       .num_standard   = ARRAY_SIZE(wavelan_handler),
+       .num_private    = ARRAY_SIZE(wavelan_private_handler),
+       .num_private_args = ARRAY_SIZE(wavelan_private_args),
        .standard       = wavelan_handler,
        .private        = wavelan_private_handler,
        .private_args   = wavelan_private_args,
@@ -2744,7 +2701,7 @@ static const struct iw_handler_def        wavelan_handler_def =
 static iw_stats *
 wavelan_get_wireless_stats(struct net_device * dev)
 {
-  kio_addr_t           base = dev->base_addr;
+  unsigned int         base = dev->base_addr;
   net_local *          lp = netdev_priv(dev);
   mmr_t                        m;
   iw_stats *           wstats;
@@ -2807,7 +2764,7 @@ wv_start_of_frame(struct net_device *     dev,
                  int           rfp,    /* end of frame */
                  int           wrap)   /* start of buffer */
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   int          rp;
   int          len;
 
@@ -2892,14 +2849,12 @@ wv_packet_read(struct net_device *              dev,
       return;
     }
 
-  skb->dev = dev;
-
   skb_reserve(skb, 2);
   fd_p = read_ringbuf(dev, fd_p, (char *) skb_put(skb, sksize), sksize);
   skb->protocol = eth_type_trans(skb, dev);
 
 #ifdef DEBUG_RX_INFO
-  wv_packet_info(skb->mac.raw, sksize, dev->name, "wv_packet_read");
+  wv_packet_info(skb_mac_header(skb), sksize, dev->name, "wv_packet_read");
 #endif /* DEBUG_RX_INFO */
      
   /* Statistics gathering & stuff associated.
@@ -2933,7 +2888,7 @@ wv_packet_read(struct net_device *                dev,
 #endif /* WAVELAN_ROAMING */
          
 #ifdef WIRELESS_SPY
-      wl_spy_gather(dev, skb->mac.raw + WAVELAN_ADDR_SIZE, stats);
+      wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE, stats);
 #endif /* WIRELESS_SPY */
 #ifdef HISTOGRAM
       wl_his_gather(dev, stats);
@@ -2970,7 +2925,7 @@ wv_packet_read(struct net_device *                dev,
 static inline void
 wv_packet_rcv(struct net_device *      dev)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   int          newrfp;
   int          rp;
@@ -3107,7 +3062,7 @@ wv_packet_write(struct net_device *       dev,
                short           length)
 {
   net_local *          lp = netdev_priv(dev);
-  kio_addr_t           base = dev->base_addr;
+  unsigned int         base = dev->base_addr;
   unsigned long                flags;
   int                  clen = length;
   register u_short     xmtdata_base = TX_BASE;
@@ -3202,11 +3157,8 @@ wavelan_packet_xmit(struct sk_buff *     skb,
         * and we don't have the Ethernet specific requirement of beeing
         * able to detect collisions, therefore in theory we don't really
         * need to pad. Jean II */
-       if (skb->len < ETH_ZLEN) {
-               skb = skb_padto(skb, ETH_ZLEN);
-               if (skb == NULL)
-                       return 0;
-       }
+       if (skb_padto(skb, ETH_ZLEN))
+               return 0;
 
   wv_packet_write(dev, skb->data, skb->len);
 
@@ -3231,7 +3183,7 @@ wavelan_packet_xmit(struct sk_buff *      skb,
 static inline int
 wv_mmc_init(struct net_device *        dev)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   psa_t                psa;
   mmw_t                m;
   int          configured;
@@ -3250,14 +3202,14 @@ wv_mmc_init(struct net_device * dev)
    * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on
    * how to configure your card...
    */
-  for(i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
-    if((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
-       (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
-       (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
+  for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
+    if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
+        (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
+        (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
       break;
 
   /* If we have not found it... */
-  if(i == (sizeof(MAC_ADDRESSES) / sizeof(char) / 3))
+  if (i == ARRAY_SIZE(MAC_ADDRESSES))
     {
 #ifdef DEBUG_CONFIG_ERRORS
       printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
@@ -3425,7 +3377,7 @@ wv_mmc_init(struct net_device *   dev)
 static int
 wv_ru_stop(struct net_device * dev)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   unsigned long        flags;
   int          status;
@@ -3488,7 +3440,7 @@ wv_ru_stop(struct net_device *    dev)
 static int
 wv_ru_start(struct net_device *        dev)
 {
-  kio_addr_t   base = dev->base_addr;
+  unsigned int base = dev->base_addr;
   net_local *  lp = netdev_priv(dev);
   unsigned long        flags;
 
@@ -3576,7 +3528,7 @@ wv_ru_start(struct net_device *   dev)
 static int
 wv_82593_config(struct net_device *    dev)
 {
-  kio_addr_t                   base = dev->base_addr;
+  unsigned int                 base = dev->base_addr;
   net_local *                  lp = netdev_priv(dev);
   struct i82593_conf_block     cfblk;
   int                          ret = TRUE;
@@ -3601,11 +3553,11 @@ wv_82593_config(struct net_device *     dev)
   cfblk.acloc = TRUE;           /* Disable source addr insertion by i82593 */
   cfblk.preamb_len = 0;         /* 2 bytes preamble (SFD) */
   cfblk.loopback = FALSE;
-  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.lin_prio = 0;          /* conform to 802.3 backoff algorithm */
+  cfblk.exp_prio = 5;          /* conform to 802.3 backoff algorithm */
+  cfblk.bof_met = 1;           /* conform to 802.3 backoff algorithm */
+  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 */
@@ -3704,12 +3656,12 @@ wv_82593_config(struct net_device *     dev)
       int                      addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
 
 #ifdef DEBUG_CONFIG_INFO
+      DECLARE_MAC_BUF(mac);
       printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
             dev->name, lp->mc_count);
       for(dmi=dev->mc_list; dmi; dmi=dmi->next)
-       printk(KERN_DEBUG " %02x:%02x:%02x:%02x:%02x:%02x\n",
-              dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
-              dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5] );
+       printk(KERN_DEBUG " %s\n",
+              print_mac(mac, dmi->dmi_addr));
 #endif
 
       /* Initialize adapter's ethernet multicast addresses */
@@ -3752,16 +3704,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;
     }
       
@@ -3772,19 +3724,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;
     }
 
@@ -3813,7 +3765,7 @@ static int
 wv_hw_config(struct net_device *       dev)
 {
   net_local *          lp = netdev_priv(dev);
-  kio_addr_t           base = dev->base_addr;
+  unsigned int         base = dev->base_addr;
   unsigned long                flags;
   int                  ret = FALSE;
 
@@ -3821,14 +3773,10 @@ wv_hw_config(struct net_device *        dev)
   printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
 #endif
 
-#ifdef STRUCT_CHECK
-  if(wv_structuct_check() != (char *) NULL)
-    {
-      printk(KERN_WARNING "%s: wv_hw_config: structure/compiler botch: \"%s\"\n",
-            dev->name, wv_structuct_check());
-      return FALSE;
-    }
-#endif /* STRUCT_CHECK == 1 */
+  /* compile-time check the sizes of structures */
+  BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
+  BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
+  BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
 
   /* Reset the pcmcia interface */
   if(wv_pcmcia_reset(dev) == FALSE)
@@ -3948,14 +3896,10 @@ 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 = link->handle;
-  tuple_t              tuple;
-  cisparse_t           parse;
   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);
@@ -3965,45 +3909,12 @@ wv_pcmcia_config(dev_link_t *   link)
   printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
 #endif
 
-  /*
-   * This reads the card's CONFIG tuple to find its configuration
-   * registers.
-   */
   do
     {
-      tuple.Attributes = 0;
-      tuple.DesiredTuple = CISTPL_CONFIG;
-      i = pcmcia_get_first_tuple(handle, &tuple);
-      if(i != CS_SUCCESS)
-       break;
-      tuple.TupleData = (cisdata_t *)buf;
-      tuple.TupleDataMax = 64;
-      tuple.TupleOffset = 0;
-      i = pcmcia_get_tuple_data(handle, &tuple);
-      if(i != CS_SUCCESS)
-       break;
-      i = pcmcia_parse_tuple(handle, &tuple, &parse);
-      if(i != CS_SUCCESS)
-       break;
-      link->conf.ConfigBase = parse.config.base;
-      link->conf.Present = parse.config.rmask[0];
-    }
-  while(0);
-  if(i != CS_SUCCESS)
-    {
-      cs_error(link->handle, ParseTuple, i);
-      link->state &= ~DEV_CONFIG_PENDING;
-      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;
        }
 
@@ -4011,10 +3922,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;
        }
 
@@ -4023,15 +3934,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.
@@ -4039,10 +3950,10 @@ 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;
        }
 
@@ -4054,7 +3965,7 @@ wv_pcmcia_config(dev_link_t *     link)
       i = pcmcia_map_mem_page(link->win, &mem);
       if(i != CS_SUCCESS)
        {
-         cs_error(link->handle, MapMemPage, i);
+         cs_error(link, MapMemPage, i);
          break;
        }
 
@@ -4068,7 +3979,7 @@ wv_pcmcia_config(dev_link_t *     link)
             lp->mem, dev->irq, (u_int) dev->base_addr);
 #endif
 
-      SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+      SET_NETDEV_DEV(dev, &handle_to_dev(link));
       i = register_netdev(dev);
       if(i != 0)
        {
@@ -4080,7 +3991,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)
     {
@@ -4089,7 +3999,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");
@@ -4104,26 +4014,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;
-  net_local *          lp = netdev_priv(dev);
+       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(lp->mem);
-  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
 }
 
@@ -4139,24 +4043,14 @@ wv_pcmcia_release(dev_link_t *link)
  */
 static irqreturn_t
 wavelan_interrupt(int          irq,
-                 void *        dev_id,
-                 struct pt_regs * regs)
+                 void *        dev_id)
 {
-  struct net_device *  dev;
+  struct net_device *  dev = dev_id;
   net_local *  lp;
-  kio_addr_t   base;
+  unsigned int base;
   int          status0;
   u_int                tx_status;
 
-  if ((dev = dev_id) == NULL)
-    {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n",
-            irq);
-#endif
-      return IRQ_NONE;
-    }
-
 #ifdef DEBUG_INTERRUPT_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
 #endif
@@ -4412,7 +4306,7 @@ static void
 wavelan_watchdog(struct net_device *   dev)
 {
   net_local *          lp = netdev_priv(dev);
-  kio_addr_t           base = dev->base_addr;
+  unsigned int         base = dev->base_addr;
   unsigned long                flags;
   int                  aborted = FALSE;
 
@@ -4487,8 +4381,8 @@ static int
 wavelan_open(struct net_device *       dev)
 {
   net_local *  lp = netdev_priv(dev);
-  dev_link_t * link = lp->link;
-  kio_addr_t   base = dev->base_addr;
+  struct pcmcia_device *       link = lp->link;
+  unsigned int base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
@@ -4541,8 +4435,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;
-  kio_addr_t   base = dev->base_addr;
+  struct pcmcia_device *       link = ((net_local *)netdev_priv(dev))->link;
+  unsigned int base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
@@ -4595,45 +4489,36 @@ wavelan_close(struct net_device *       dev)
  * card insertion event.
  */
 static int
-wavelan_attach(struct pcmcia_device *p_dev)
+wavelan_probe(struct pcmcia_device *p_dev)
 {
-  dev_link_t * link;           /* Info for cardmgr */
   struct net_device *  dev;            /* Interface generic data */
   net_local *  lp;             /* Interface specific data */
+  int ret;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_attach()\n");
 #endif
 
-  /* Initialize the dev_link_t structure */
-  link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-  if (!link) return -ENOMEM;
-
   /* 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_LEVEL_ID;
-  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 = NULL;
+  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);
+  if (!dev)
       return -ENOMEM;
-  }
-  link->priv = link->irq.Instance = dev;
+
+  p_dev->priv = p_dev->irq.Instance = dev;
 
   lp = netdev_priv(dev);
 
@@ -4650,11 +4535,9 @@ wavelan_attach(struct pcmcia_device *p_dev)
   spin_lock_init(&lp->spinlock);
 
   /* back links */
-  lp->link = link;
   lp->dev = dev;
 
   /* wavelan NET3 callbacks */
-  SET_MODULE_OWNER(dev);
   dev->open = &wavelan_open;
   dev->stop = &wavelan_close;
   dev->hard_start_xmit = &wavelan_packet_xmit;
@@ -4676,15 +4559,18 @@ wavelan_attach(struct pcmcia_device *p_dev)
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
 
-  link->handle = p_dev;
-  p_dev->instance = link;
+  ret = wv_pcmcia_config(p_dev);
+  if (ret)
+         return ret;
 
-  link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-  if(wv_pcmcia_config(link) &&
-     wv_hw_config(dev))
-         wv_init_info(dev);
-  else
+  ret = wv_hw_config(dev);
+  if (ret) {
          dev->irq = 0;
+         pcmcia_disable_device(p_dev);
+         return ret;
+  }
+
+  wv_init_info(dev);
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "<- wavelan_attach()\n");
@@ -4701,25 +4587,14 @@ wavelan_attach(struct pcmcia_device *p_dev)
  * is released.
  */
 static void
-wavelan_detach(struct pcmcia_device *p_dev)
+wavelan_detach(struct pcmcia_device *link)
 {
-   dev_link_t *link = dev_to_instance(p_dev);
-
 #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);
-    }
+  /* Some others haven't done their job : give them another chance */
+  wv_pcmcia_release(link);
 
   /* Free pieces */
   if(link->priv)
@@ -4728,23 +4603,21 @@ wavelan_detach(struct pcmcia_device *p_dev)
 
       /* 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
 }
 
-static int wavelan_suspend(struct pcmcia_device *p_dev)
+static int wavelan_suspend(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *     dev = (struct net_device *) link->priv;
 
        /* NB: wavelan_close will be called, but too late, so we are
@@ -4756,36 +4629,22 @@ static int wavelan_suspend(struct pcmcia_device *p_dev)
        /* 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;
-
-       if(link->state & DEV_CONFIG)
-       {
-               if(link->open)
-                       netif_device_detach(dev);
-               pcmcia_release_configuration(link->handle);
-       }
-
        return 0;
 }
 
-static int wavelan_resume(struct pcmcia_device *p_dev)
+static int wavelan_resume(struct pcmcia_device *link)
 {
-       dev_link_t *link = dev_to_instance(p_dev);
        struct net_device *     dev = (struct net_device *) link->priv;
 
-       link->state &= ~DEV_SUSPEND;
-       if(link->state & DEV_CONFIG)
-       {
-               pcmcia_request_configuration(link->handle, &link->conf);
-               if(link->open)  /* If RESET -> True, If RESUME -> False ? */
-               {
-                       wv_hw_reset(dev);
-                       netif_device_attach(dev);
-               }
+       if (link->open) {
+               wv_hw_reset(dev);
+               netif_device_attach(dev);
        }
 
        return 0;
@@ -4806,7 +4665,7 @@ static struct pcmcia_driver wavelan_driver = {
        .drv            = {
                .name   = "wavelan_cs",
        },
-       .probe          = wavelan_attach,
+       .probe          = wavelan_probe,
        .remove         = wavelan_detach,
        .id_table       = wavelan_ids,
        .suspend        = wavelan_suspend,