aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
ModeNameSize
-rw-r--r--Kconfig8232logstatsplainblame
-rw-r--r--Makefile2681logstatsplainblame
-rw-r--r--at91_cf.c9721logstatsplainblame
-rw-r--r--au1000_db1x00.c7339logstatsplainblame
-rw-r--r--au1000_generic.c14080logstatsplainblame
-rw-r--r--au1000_generic.h4288logstatsplainblame
-rw-r--r--au1000_pb1x00.c9346logstatsplainblame
-rw-r--r--au1000_xxs1500.c4349logstatsplainblame
-rw-r--r--cardbus.c6387logstatsplainblame
-rw-r--r--cirrus.h5392logstatsplainblame
-rw-r--r--cistpl.c38901logstatsplainblame
-rw-r--r--cs.c22113logstatsplainblame
-rw-r--r--cs_internal.h4717logstatsplainblame
-rw-r--r--ds.c32526logstatsplainblame
-rw-r--r--ds_internal.h1025logstatsplainblame
-rw-r--r--hd64465_ss.c24842logstatsplainblame
-rw-r--r--i82092.c18225logstatsplainblame
-rw-r--r--i82092aa.h1220logstatsplainblame
-rw-r--r--i82365.c38355logstatsplainblame
-rw-r--r--i82365.h4988logstatsplainblame
-rw-r--r--m32r_cfc.c21114logstatsplainblame
-rw-r--r--m32r_cfc.h1903logstatsplainblame
-rw-r--r--m32r_pcc.c17124logstatsplainblame
-rw-r--r--m32r_pcc.h1321logstatsplainblame
-rw-r--r--m8xx_pcmcia.c33313logstatsplainblame
-rw-r--r--o2micro.h5887logstatsplainblame
-rw-r--r--omap_cf.c8899logstatsplainblame
-rw-r--r--pcmcia_ioctl.c20044logstatsplainblame
-rw-r--r--pcmcia_resource.c25632logstatsplainblame
-rw-r--r--pd6729.c19529logstatsplainblame
-rw-r--r--pd6729.h721logstatsplainblame
-rw-r--r--pxa2xx_base.c6389logstatsplainblame
-rw-r--r--pxa2xx_base.h78logstatsplainblame
-rw-r--r--pxa2xx_lubbock.c6109logstatsplainblame
-rw-r--r--pxa2xx_mainstone.c4982logstatsplainblame
-rw-r--r--pxa2xx_sharpsl.c7682logstatsplainblame
-rw-r--r--ricoh.h6891logstatsplainblame
-rw-r--r--rsrc_mgr.c6278logstatsplainblame
-rw-r--r--rsrc_nonstatic.c26093logstatsplainblame
-rw-r--r--sa1100_assabet.c3347logstatsplainblame
-rw-r--r--sa1100_badge4.c4201logstatsplainblame
-rw-r--r--sa1100_cerf.c2477logstatsplainblame
-rw-r--r--sa1100_generic.c3660logstatsplainblame
-rw-r--r--sa1100_generic.h995logstatsplainblame
-rw-r--r--sa1100_h3600.c3546logstatsplainblame
-rw-r--r--sa1100_jornada720.c2828logstatsplainblame
-rw-r--r--sa1100_neponset.c3521logstatsplainblame
-rw-r--r--sa1100_shannon.c3297logstatsplainblame
-rw-r--r--sa1100_simpad.c2991logstatsplainblame
-rw-r--r--sa1111_generic.c5015logstatsplainblame
-rw-r--r--sa1111_generic.h711logstatsplainblame
-rw-r--r--sa11xx_base.c5938logstatsplainblame
-rw-r--r--sa11xx_base.h4737logstatsplainblame
-rw-r--r--soc_common.c21723logstatsplainblame
-rw-r--r--soc_common.h5370logstatsplainblame
-rw-r--r--socket_sysfs.c9711logstatsplainblame
-rw-r--r--tcic.c24320logstatsplainblame
-rw-r--r--tcic.h8206logstatsplainblame
-rw-r--r--ti113x.h27887logstatsplainblame
-rw-r--r--topic.h5323logstatsplainblame
-rw-r--r--vg468.h4227logstatsplainblame
-rw-r--r--vrc4171_card.c18247logstatsplainblame
-rw-r--r--vrc4173_cardu.c15271logstatsplainblame
-rw-r--r--vrc4173_cardu.h6656logstatsplainblame
-rw-r--r--yenta_socket.c36541logstatsplainblame
-rw-r--r--yenta_socket.h4887logstatsplainblame
ause it can be triggered through a race: * something inserts a STA (on one CPU) without holding the RTNL * and another CPU turns off the net device. */ if (unlikely(!netif_running(sdata->dev))) { err = -ENETDOWN; goto out_free; } if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 || is_multicast_ether_addr(sta->sta.addr))) { err = -EINVAL; goto out_free; } spin_lock_irqsave(&local->sta_lock, flags); /* check if STA exists already */ if (sta_info_get(local, sta->sta.addr)) { spin_unlock_irqrestore(&local->sta_lock, flags); err = -EEXIST; goto out_free; } list_add(&sta->list, &local->sta_list); local->num_sta++; sta_info_hash_add(local, sta); /* notify driver */ if (local->ops->sta_notify) { if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); local->ops->sta_notify(local_to_hw(local), &sdata->vif, STA_NOTIFY_ADD, &sta->sta); } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG printk(KERN_DEBUG "%s: Inserted STA %pM\n", wiphy_name(local->hw.wiphy), sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ spin_unlock_irqrestore(&local->sta_lock, flags); #ifdef CONFIG_MAC80211_DEBUGFS /* * Debugfs entry adding might sleep, so schedule process * context task for adding entry for STAs that do not yet * have one. * NOTE: due to auto-freeing semantics this may only be done * if the insertion is successful! */ schedule_work(&local->sta_debugfs_add); #endif if (ieee80211_vif_is_mesh(&sdata->vif)) mesh_accept_plinks_update(sdata); return 0; out_free: BUG_ON(!err); __sta_info_free(local, sta); return err; } static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) { /* * This format has been mandated by the IEEE specifications, * so this line may not be changed to use the __set_bit() format. */ bss->tim[aid / 8] |= (1 << (aid % 8)); } static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) { /* * This format has been mandated by the IEEE specifications, * so this line may not be changed to use the __clear_bit() format. */ bss->tim[aid / 8] &= ~(1 << (aid % 8)); } static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, struct sta_info *sta) { BUG_ON(!bss); __bss_tim_set(bss, sta->sta.aid); if (sta->local->ops->set_tim) { sta->local->tim_in_locked_section = true; sta->local->ops->set_tim(local_to_hw(sta->local), &sta->sta, true); sta->local->tim_in_locked_section = false; } } void sta_info_set_tim_bit(struct sta_info *sta) { unsigned long flags; BUG_ON(!sta->sdata->bss); spin_lock_irqsave(&sta->local->sta_lock, flags); __sta_info_set_tim_bit(sta->sdata->bss, sta); spin_unlock_irqrestore(&sta->local->sta_lock, flags); } static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, struct sta_info *sta) { BUG_ON(!bss); __bss_tim_clear(bss, sta->sta.aid); if (sta->local->ops->set_tim) { sta->local->tim_in_locked_section = true; sta->local->ops->set_tim(local_to_hw(sta->local), &sta->sta, false); sta->local->tim_in_locked_section = false; } } void sta_info_clear_tim_bit(struct sta_info *sta) { unsigned long flags; BUG_ON(!sta->sdata->bss); spin_lock_irqsave(&sta->local->sta_lock, flags); __sta_info_clear_tim_bit(sta->sdata->bss, sta); spin_unlock_irqrestore(&sta->local->sta_lock, flags); } static void __sta_info_unlink(struct sta_info **sta) { struct ieee80211_local *local = (*sta)->local; struct ieee80211_sub_if_data *sdata = (*sta)->sdata; /* * pull caller's reference if we're already gone. */ if (sta_info_hash_del(local, *sta)) { *sta = NULL; return; } if ((*sta)->key) { ieee80211_key_free((*sta)->key); WARN_ON((*sta)->key); } list_del(&(*sta)->list); if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { BUG_ON(!sdata->bss); atomic_dec(&sdata->bss->num_sta_ps); __sta_info_clear_tim_bit(sdata->bss, *sta); } local->num_sta--; if (local->ops->sta_notify) { if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); local->ops->sta_notify(local_to_hw(local), &sdata->vif, STA_NOTIFY_REMOVE, &(*sta)->sta); } if (ieee80211_vif_is_mesh(&sdata->vif)) { mesh_accept_plinks_update(sdata); #ifdef CONFIG_MAC80211_MESH del_timer(&(*sta)->plink_timer); #endif } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG printk(KERN_DEBUG "%s: Removed STA %pM\n", wiphy_name(local->hw.wiphy), (*sta)->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ /* * Finally, pull caller's reference if the STA is pinned by the * task that is adding the debugfs entries. In that case, we * leave the STA "to be freed". * * The rules are not trivial, but not too complex either: * (1) pin_status is only modified under the sta_lock * (2) STAs may only be pinned under the RTNL so that * sta_info_flush() is guaranteed to actually destroy * all STAs that are active for a given interface, this * is required for correctness because otherwise we * could notify a driver that an interface is going * away and only after that (!) notify it about a STA * on that interface going away. * (3) sta_info_debugfs_add_work() will set the status * to PINNED when it found an item that needs a new * debugfs directory created. In that case, that item * must not be freed although all *RCU* users are done * with it. Hence, we tell the caller of _unlink() * that the item is already gone (as can happen when * two tasks try to unlink/destroy at the same time) * (4) We set the pin_status to DESTROY here when we * find such an item. * (5) sta_info_debugfs_add_work() will reset the pin_status * from PINNED to NORMAL when it is done with the item, * but will check for DESTROY before resetting it in * which case it will free the item. */ if ((*sta)->pin_status == STA_INFO_PIN_STAT_PINNED) { (*sta)->pin_status = STA_INFO_PIN_STAT_DESTROY; *sta = NULL; return; } } void sta_info_unlink(struct sta_info **sta) { struct ieee80211_local *local = (*sta)->local; unsigned long flags; spin_lock_irqsave(&local->sta_lock, flags); __sta_info_unlink(sta); spin_unlock_irqrestore(&local->sta_lock, flags); } static inline int sta_info_buffer_expired(struct ieee80211_local *local, struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_tx_info *info; int timeout; if (!skb) return 0; info = IEEE80211_SKB_CB(skb); /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 15625) * HZ; if (timeout < STA_TX_BUFFER_EXPIRE) timeout = STA_TX_BUFFER_EXPIRE; return time_after(jiffies, info->control.jiffies + timeout); } static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, struct sta_info *sta) { unsigned long flags; struct sk_buff *skb; struct ieee80211_sub_if_data *sdata; if (skb_queue_empty(&sta->ps_tx_buf)) return; for (;;) { spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); skb = skb_peek(&sta->ps_tx_buf); if (sta_info_buffer_expired(local, sta, skb)) skb = __skb_dequeue(&sta->ps_tx_buf); else skb = NULL; spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); if (!skb) break; sdata = sta->sdata; local->total_ps_buffered--; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", sta->sta.addr); #endif dev_kfree_skb(skb); if (skb_queue_empty(&sta->ps_tx_buf)) sta_info_clear_tim_bit(sta); } } static void sta_info_cleanup(unsigned long data) { struct ieee80211_local *local = (struct ieee80211_local *) data; struct sta_info *sta; rcu_read_lock(); list_for_each_entry_rcu(sta, &local->sta_list, list) sta_info_cleanup_expire_buffered(local, sta); rcu_read_unlock(); local->sta_cleanup.expires = round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); add_timer(&local->sta_cleanup); } #ifdef CONFIG_MAC80211_DEBUGFS /* * See comment in __sta_info_unlink, * caller must hold local->sta_lock. */ static void __sta_info_pin(struct sta_info *sta) { WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_NORMAL); sta->pin_status = STA_INFO_PIN_STAT_PINNED; } /* * See comment in __sta_info_unlink, returns sta if it * needs to be destroyed. */ static struct sta_info *__sta_info_unpin(struct sta_info *sta) { struct sta_info *ret = NULL; unsigned long flags; spin_lock_irqsave(&sta->local->sta_lock, flags); WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY && sta->pin_status != STA_INFO_PIN_STAT_PINNED); if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY) ret = sta; sta->pin_status = STA_INFO_PIN_STAT_NORMAL; spin_unlock_irqrestore(&sta->local->sta_lock, flags); return ret; } static void sta_info_debugfs_add_work(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, sta_debugfs_add); struct sta_info *sta, *tmp; unsigned long flags; /* We need to keep the RTNL across the whole pinned status. */ rtnl_lock(); while (1) { sta = NULL; spin_lock_irqsave(&local->sta_lock, flags); list_for_each_entry(tmp, &local->sta_list, list) { /* * debugfs.add_has_run will be set by * ieee80211_sta_debugfs_add regardless * of what else it does. */ if (!tmp->debugfs.add_has_run) { sta = tmp; __sta_info_pin(sta); break; } } spin_unlock_irqrestore(&local->sta_lock, flags); if (!sta) break; ieee80211_sta_debugfs_add(sta); rate_control_add_sta_debugfs(sta); sta = __sta_info_unpin(sta); sta_info_destroy(sta); } rtnl_unlock(); } #endif static void __ieee80211_run_pending_flush(struct ieee80211_local *local) { struct sta_info *sta; unsigned long flags; ASSERT_RTNL(); spin_lock_irqsave(&local->sta_lock, flags); while (!list_empty(&local->sta_flush_list)) { sta = list_first_entry(&local->sta_flush_list, struct sta_info, list); list_del(&sta->list); spin_unlock_irqrestore(&local->sta_lock, flags); sta_info_destroy(sta); spin_lock_irqsave(&local->sta_lock, flags); } spin_unlock_irqrestore(&local->sta_lock, flags); } static void ieee80211_sta_flush_work(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, sta_flush_work); rtnl_lock(); __ieee80211_run_pending_flush(local); rtnl_unlock(); } void sta_info_init(struct ieee80211_local *local) {