Hi John, Can you please take a look at this patch? drivers/net/wireless/wavelan_cs.c has unusually large number of static inline functions - 27. I looked through them and 20 of them do not seem to warrant inlining. Some are really big; others call mdelay(1) or busy-wait for a bit to be set in a hardware register - it's pointless to optimize such functions for speed. This patch removes "inline" from these static function (regardless of number of callsites - gcc nowadays auto-inlines statics with one callsite). Size difference for 32bit x86: text data bss dec hex filename 17020 372 8 17400 43f8 linux-2.6-ALLYES/drivers/net/wireless/wavelan_cs.o 14032 356 8 14396 383c linux-2.6.inline-ALLYES/drivers/net/wireless/wavelan_cs.o Signed-off-by: Denys Vlasenko <vda.linux@xxxxxxxxxxxxxx> -- vda
diff -urp -U 10 linux-2.6/drivers/net/wireless/wavelan_cs.c linux-2.6.inline/drivers/net/wireless/wavelan_cs.c --- linux-2.6/drivers/net/wireless/wavelan_cs.c 2008-03-30 03:27:46.000000000 +0200 +++ linux-2.6.inline/drivers/net/wireless/wavelan_cs.c 2008-04-01 02:34:14.000000000 +0200 @@ -95,21 +95,21 @@ hacr_write(u_long base, u_char hacr) { outb(hacr, HACR(base)); } /* hacr_write */ /*------------------------------------------------------------------*/ /* * Write to card's Host Adapter Command Register. Include a delay for * those times when it is needed. */ -static inline void +static void hacr_write_slow(u_long base, u_char hacr) { hacr_write(base, hacr); /* delay might only be needed sometimes */ mdelay(1); } /* hacr_write_slow */ /*------------------------------------------------------------------*/ /* @@ -248,59 +248,59 @@ update_psa_checksum(struct net_device * if(crc != 0) printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name); #endif /* DEBUG_IOCTL_INFO */ #endif /* SET_PSA_CRC */ } /* update_psa_checksum */ /*------------------------------------------------------------------*/ /* * Write 1 byte to the MMC. */ -static inline void +static void mmc_out(u_long base, u_short o, u_char d) { int count = 0; /* Wait for MMC to go idle */ while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY)) udelay(10); outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base)); outb(d, MMD(base)); } /*------------------------------------------------------------------*/ /* * Routine to write bytes to the Modem Management Controller. * We start by the end because it is the way it should be ! */ -static inline void +static void mmc_write(u_long base, u_char o, u_char * b, int n) { o += n; b += n; while(n-- > 0 ) mmc_out(base, --o, *(--b)); } /* mmc_write */ /*------------------------------------------------------------------*/ /* * Read 1 byte from the MMC. * Optimised version for 1 byte, avoid using memory... */ -static inline u_char +static u_char mmc_in(u_long base, u_short o) { int count = 0; while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY)) udelay(10); outb(o << 1, MMR(base)); /* Set the read address */ outb(0, MMD(base)); /* Required dummy write */ @@ -311,21 +311,21 @@ mmc_in(u_long base, } /*------------------------------------------------------------------*/ /* * Routine to read bytes from the Modem Management Controller. * The implementation is complicated by a lack of address lines, * which prevents decoding of the low-order bit. * (code has just been moved in the above function) * We start by the end because it is the way it should be ! */ -static inline void +static void mmc_read(u_long base, u_char o, u_char * b, int n) { o += n; b += n; while(n-- > 0) *(--b) = mmc_in(base, --o); @@ -343,23 +343,22 @@ mmc_encr(u_long base) /* i/o port of th temp = mmc_in(base, mmroff(0, mmr_des_avail)); if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES)) return 0; else return temp; } /*------------------------------------------------------------------*/ /* * Wait for the frequency EEprom to complete a command... - * I hope this one will be optimally inlined... */ -static inline void +static void fee_wait(u_long base, /* i/o port of the card */ int delay, /* Base delay to wait for */ int number) /* Number of time to wait */ { int count = 0; /* Wait only a limited time */ while((count++ < number) && (mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY)) udelay(delay); } @@ -731,23 +730,23 @@ static void wv_roam_handover(wavepoint_h mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2); /* ReEnable interrupts & restore flags */ spin_unlock_irqrestore(&lp->spinlock, flags); wv_nwid_filter(!NWID_PROMISC,lp); lp->curr_point=wavepoint; } /* Called when a WavePoint beacon is received */ -static inline void wl_roam_gather(struct net_device * dev, - u_char * hdr, /* Beacon header */ - u_char * stats) /* SNR, Signal quality +static void wl_roam_gather(struct net_device * dev, + u_char * hdr, /* Beacon header */ + u_char * stats) /* SNR, Signal quality of packet */ { wavepoint_beacon *beacon= (wavepoint_beacon *)hdr; /* Rcvd. Beacon */ unsigned short nwid=ntohs(beacon->nwid); unsigned short sigqual=stats[2] & MMR_SGNL_QUAL; /* SNR of beacon */ wavepoint_history *wavepoint=NULL; /* WavePoint table entry */ net_local *lp = netdev_priv(dev); /* Device info */ #ifdef I_NEED_THIS_FEATURE /* Some people don't need this, some other may need it */ @@ -787,21 +786,21 @@ static inline void wl_roam_gather(struct wv_nwid_filter(!NWID_PROMISC,lp); out: lp->wavepoint_table.locked=0; /* </MUTEX> :-) */ } /* Test this MAC frame a WavePoint beacon */ static inline int WAVELAN_BEACON(unsigned char *data) { wavepoint_beacon *beacon= (wavepoint_beacon *)data; - static wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00}; + static const wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00}; if(memcmp(beacon,&beacon_template,9)==0) return 1; else return 0; } #endif /* WAVELAN_ROAMING */ /************************ I82593 SUBROUTINES *************************/ /* @@ -973,21 +972,21 @@ read_ringbuf(struct net_device * dev, /*------------------------------------------------------------------*/ /* * Reconfigure the i82593, or at least ask for it... * Because wv_82593_config use the transmission buffer, we must do it * when we are sure that there is no transmission, so we do it now * or in wavelan_packet_xmit() (I can't find any better place, * wavelan_interrupt is not an option...), so you may experience * some delay sometime... */ -static inline void +static void wv_82593_reconfig(struct net_device * dev) { net_local * lp = netdev_priv(dev); struct pcmcia_device * link = lp->link; unsigned long flags; /* Arm the flag, will be cleard in wv_82593_config() */ lp->reconfig_82593 = TRUE; /* Check if we can do it now ! */ @@ -1226,21 +1225,21 @@ wv_local_show(struct net_device * dev) */ printk("\n"); } /* wv_local_show */ #endif /* DEBUG_DEVICE_SHOW */ #if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) /*------------------------------------------------------------------*/ /* * Dump packet header (and content if necessary) on the screen */ -static inline void +static void wv_packet_info(u_char * p, /* Packet to dump */ int length, /* Length of the packet */ char * msg1, /* Name of the device */ char * msg2) /* Name of the function */ { int i; int maxi; DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "%s: %s(): dest %s, length %d\n", @@ -1265,21 +1264,21 @@ wv_packet_info(u_char * p, /* Packet t printk(KERN_DEBUG "\n"); #endif /* DEBUG_PACKET_DUMP */ } #endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */ /*------------------------------------------------------------------*/ /* * This is the information which is displayed by the driver at startup * There is a lot of flag to configure it at your will... */ -static inline void +static void wv_init_info(struct net_device * dev) { unsigned int base = dev->base_addr; psa_t psa; DECLARE_MAC_BUF(mac); /* Read the parameter storage area */ psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); #ifdef DEBUG_PSA_SHOW @@ -1502,21 +1501,21 @@ wavelan_set_mac_address(struct net_devic return 0; } #endif /* SET_MAC_ADDRESS */ /*------------------------------------------------------------------*/ /* * Frequency setting (for hardware able of it) * It's a bit complicated and you don't really want to look into it... */ -static inline int +static int wv_set_frequency(u_long base, /* i/o port of the card */ iw_freq * frequency) { const int BAND_NUM = 10; /* Number of bands */ long freq = 0L; /* offset to 2.4 GHz in .5 MHz */ #ifdef DEBUG_IOCTL_INFO int i; #endif /* Setting by frequency */ @@ -1699,21 +1698,21 @@ wv_set_frequency(u_long base, /* i/o po return 0; } else return -EINVAL; /* Bah, never get there... */ } /*------------------------------------------------------------------*/ /* * Give the list of available frequencies */ -static inline int +static int wv_frequency_list(u_long base, /* i/o port of the card */ iw_freq * list, /* List of frequency to fill */ int max) /* Maximum number of frequencies */ { u_short table[10]; /* Authorized frequency table */ long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */ int i; /* index in the table */ const int BAND_NUM = 10; /* Number of bands */ int c = 0; /* Channel number */ @@ -2752,21 +2751,21 @@ wavelan_get_wireless_stats(struct net_de * The interrupt handler get an interrupt when a packet has been * successfully received and called this part... */ /*------------------------------------------------------------------*/ /* * Calculate the starting address of the frame pointed to by the receive * frame pointer and verify that the frame seem correct * (called by wv_packet_rcv()) */ -static inline int +static int wv_start_of_frame(struct net_device * dev, int rfp, /* end of frame */ int wrap) /* start of buffer */ { unsigned int base = dev->base_addr; int rp; int len; rp = (rfp - 5 + RX_SIZE) % RX_SIZE; outb(rp & 0xff, PIORL(base)); @@ -2814,21 +2813,21 @@ wv_start_of_frame(struct net_device * de * header structure) from the WaveLAN card to an sk_buff chain that * will be passed up to the network interface layer. NOTE: We * currently don't handle trailer protocols (neither does the rest of * the network interface), so if that is needed, it will (at least in * part) be added here. The contents of the receive ring buffer are * copied to a message chain that is then passed to the kernel. * * Note: if any errors occur, the packet is "dropped on the floor" * (called by wv_packet_rcv()) */ -static inline void +static void wv_packet_read(struct net_device * dev, int fd_p, int sksize) { net_local * lp = netdev_priv(dev); struct sk_buff * skb; #ifdef DEBUG_RX_TRACE printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n", dev->name, fd_p, sksize); @@ -2915,21 +2914,21 @@ wv_packet_read(struct net_device * dev, /* * This routine is called by the interrupt handler to initiate a * packet transfer from the card to the network interface layer above * this driver. This routine checks if a buffer has been successfully * received by the WaveLAN card. If so, the routine wv_packet_read is * called to do the actual transfer of the card's data including the * ethernet header into a packet consisting of an sk_buff chain. * (called by wavelan_interrupt()) * Note : the spinlock is already grabbed for us and irq are disabled. */ -static inline void +static void wv_packet_rcv(struct net_device * dev) { unsigned int base = dev->base_addr; net_local * lp = netdev_priv(dev); int newrfp; int rp; int len; int f_start; int status; int i593_rfp; @@ -3049,21 +3048,21 @@ wv_packet_rcv(struct net_device * dev) * checked in wavelan_interrupt() */ /*------------------------------------------------------------------*/ /* * This routine fills in the appropriate registers and memory * locations on the WaveLAN card and starts the card off on * the transmit. * (called in wavelan_packet_xmit()) */ -static inline void +static void wv_packet_write(struct net_device * dev, void * buf, short length) { net_local * lp = netdev_priv(dev); unsigned int base = dev->base_addr; unsigned long flags; int clen = length; register u_short xmtdata_base = TX_BASE; @@ -3173,21 +3172,21 @@ wavelan_packet_xmit(struct sk_buff * skb /********************** HARDWARE CONFIGURATION **********************/ /* * This part do the real job of starting and configuring the hardware. */ /*------------------------------------------------------------------*/ /* * Routine to initialize the Modem Management Controller. * (called by wv_hw_config()) */ -static inline int +static int wv_mmc_init(struct net_device * dev) { unsigned int base = dev->base_addr; psa_t psa; mmw_t m; int configured; int i; /* Loop counter */ #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name); @@ -3692,21 +3691,21 @@ wv_82593_config(struct net_device * dev) /*------------------------------------------------------------------*/ /* * Read the Access Configuration Register, perform a software reset, * and then re-enable the card's software. * * If I understand correctly : reset the pcmcia interface of the * wavelan. * (called by wv_config()) */ -static inline int +static int wv_pcmcia_reset(struct net_device * dev) { int i; conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 }; 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 @@ -3857,21 +3856,21 @@ wv_hw_config(struct net_device * dev) } /*------------------------------------------------------------------*/ /* * Totally reset the wavelan and restart it. * Performs the following actions: * 1. Call wv_hw_config() * 2. Start the LAN controller's receive unit * (called by wavelan_event(), wavelan_watchdog() and wavelan_open()) */ -static inline void +static void wv_hw_reset(struct net_device * dev) { net_local * lp = netdev_priv(dev); #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name); #endif lp->nresets++; lp->configured = 0; @@ -3888,21 +3887,21 @@ wv_hw_reset(struct net_device * dev) #endif } /*------------------------------------------------------------------*/ /* * wv_pcmcia_config() is called after a CARD_INSERTION event is * received, to configure the PCMCIA socket, and to make the ethernet * device available to the system. * (called by wavelan_event()) */ -static inline int +static int wv_pcmcia_config(struct pcmcia_device * link) { struct net_device * dev = (struct net_device *) link->priv; int i; win_req_t req; memreq_t mem; net_local * lp = netdev_priv(dev); #ifdef DEBUG_CONFIG_TRACE diff -urp -U 10 linux-2.6/drivers/net/wireless/wavelan_cs.p.h linux-2.6.inline/drivers/net/wireless/wavelan_cs.p.h --- linux-2.6/drivers/net/wireless/wavelan_cs.p.h 2008-03-30 03:27:46.000000000 +0200 +++ linux-2.6.inline/drivers/net/wireless/wavelan_cs.p.h 2008-04-01 02:46:19.000000000 +0200 @@ -630,46 +630,46 @@ struct net_local wavepoint_history * curr_point; /* Current wavepoint */ int cell_search; /* Searching for new cell? */ struct timer_list cell_timer; /* Garbage collection */ #endif /* WAVELAN_ROAMING */ void __iomem *mem; }; /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ static inline u_char /* data */ hasr_read(u_long); /* Read the host interface : base address */ -static inline void +static void hacr_write(u_long, /* Write to host interface : base address */ u_char), /* data */ hacr_write_slow(u_long, u_char); static void psa_read(struct net_device *, /* Read the Parameter Storage Area */ int, /* offset in PSA */ u_char *, /* buffer to fill */ int), /* size to read */ psa_write(struct net_device *, /* Write to the PSA */ int, /* Offset in psa */ u_char *, /* Buffer in memory */ int); /* Length of buffer */ -static inline void +static void mmc_out(u_long, /* Write 1 byte to the Modem Manag Control */ u_short, u_char), mmc_write(u_long, /* Write n bytes to the MMC */ u_char, u_char *, int); -static inline u_char /* Read 1 byte from the MMC */ +static u_char /* Read 1 byte from the MMC */ mmc_in(u_long, u_short); -static inline void +static void mmc_read(u_long, /* Read n bytes from the MMC */ u_char, u_char *, int), fee_wait(u_long, /* Wait for frequency EEprom : base address */ int, /* Base delay to wait for */ int); /* Number of time to wait */ static void fee_read(u_long, /* Read the frequency EEprom : base address */ u_short, /* destination offset */ @@ -681,63 +681,63 @@ static int char *, int, int); static inline int wv_diag(struct net_device *); /* Diagnostique the i82593 */ static int read_ringbuf(struct net_device *, /* Read a receive buffer */ int, char *, int); -static inline void +static void wv_82593_reconfig(struct net_device *); /* Reconfigure the controller */ /* ------------------- DEBUG & INFO SUBROUTINES ------------------- */ -static inline void +static void wv_init_info(struct net_device *); /* display startup info */ /* ------------------- IOCTL, STATS & RECONFIG ------------------- */ static en_stats * wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */ static iw_stats * wavelan_get_wireless_stats(struct net_device *); /* ----------------------- PACKET RECEPTION ----------------------- */ -static inline int +static int wv_start_of_frame(struct net_device *, /* Seek beggining of current frame */ int, /* end of frame */ int); /* start of buffer */ -static inline void +static void wv_packet_read(struct net_device *, /* Read a packet from a frame */ int, int), wv_packet_rcv(struct net_device *); /* Read all packets waiting */ /* --------------------- PACKET TRANSMISSION --------------------- */ -static inline void +static void wv_packet_write(struct net_device *, /* Write a packet to the Tx buffer */ void *, short); static int wavelan_packet_xmit(struct sk_buff *, /* Send a packet */ struct net_device *); /* -------------------- HARDWARE CONFIGURATION -------------------- */ -static inline int +static int wv_mmc_init(struct net_device *); /* Initialize the modem */ static int wv_ru_stop(struct net_device *), /* Stop the i82593 receiver unit */ wv_ru_start(struct net_device *); /* Start the i82593 receiver unit */ static int wv_82593_config(struct net_device *); /* Configure the i82593 */ -static inline int +static int wv_pcmcia_reset(struct net_device *); /* Reset the pcmcia interface */ static int wv_hw_config(struct net_device *); /* Reset & configure the whole hardware */ -static inline void +static void wv_hw_reset(struct net_device *); /* Same, + start receiver unit */ -static inline int +static int wv_pcmcia_config(struct pcmcia_device *); /* Configure the pcmcia interface */ static void wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */ /* ---------------------- INTERRUPT HANDLING ---------------------- */ static irqreturn_t wavelan_interrupt(int, /* Interrupt handler */ void *); static void wavelan_watchdog(struct net_device *); /* Transmission watchdog */ /* ------------------- CONFIGURATION CALLBACKS ------------------- */