* [PATCH 03/21] orinoco: remove underscores from little-endian field names
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Sparse is much better at finding endianess issues than such visual cues.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/spectrum_cs.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 0b0bce7..58c153a 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -120,8 +120,8 @@ #define TEXT_END 0x1A /* End of text he
* Each block has the following structure.
*/
struct dblock {
- __le32 _addr; /* adapter address where to write the block */
- __le16 _len; /* length of the data only, in bytes */
+ __le32 addr; /* adapter address where to write the block */
+ __le16 len; /* length of the data only, in bytes */
char data[0]; /* data to be written */
} __attribute__ ((packed));
@@ -131,9 +131,9 @@ struct dblock {
* items with matching ID should be written.
*/
struct pdr {
- __le32 _id; /* record ID */
- __le32 _addr; /* adapter address where to write the data */
- __le32 _len; /* expected length of the data, in bytes */
+ __le32 id; /* record ID */
+ __le32 addr; /* adapter address where to write the data */
+ __le32 len; /* expected length of the data, in bytes */
char next[0]; /* next PDR starts here */
} __attribute__ ((packed));
@@ -144,8 +144,8 @@ struct pdr {
* be plugged into the secondary firmware.
*/
struct pdi {
- __le16 _len; /* length of ID and data, in words */
- __le16 _id; /* record ID */
+ __le16 len; /* length of ID and data, in words */
+ __le16 id; /* record ID */
char data[0]; /* plug data */
} __attribute__ ((packed));
@@ -154,44 +154,44 @@ struct pdi {
static inline u32
dblock_addr(const struct dblock *blk)
{
- return le32_to_cpu(blk->_addr);
+ return le32_to_cpu(blk->addr);
}
static inline u32
dblock_len(const struct dblock *blk)
{
- return le16_to_cpu(blk->_len);
+ return le16_to_cpu(blk->len);
}
static inline u32
pdr_id(const struct pdr *pdr)
{
- return le32_to_cpu(pdr->_id);
+ return le32_to_cpu(pdr->id);
}
static inline u32
pdr_addr(const struct pdr *pdr)
{
- return le32_to_cpu(pdr->_addr);
+ return le32_to_cpu(pdr->addr);
}
static inline u32
pdr_len(const struct pdr *pdr)
{
- return le32_to_cpu(pdr->_len);
+ return le32_to_cpu(pdr->len);
}
static inline u32
pdi_id(const struct pdi *pdi)
{
- return le16_to_cpu(pdi->_id);
+ return le16_to_cpu(pdi->id);
}
/* Return length of the data only, in bytes */
static inline u32
pdi_len(const struct pdi *pdi)
{
- return 2 * (le16_to_cpu(pdi->_len) - 1);
+ return 2 * (le16_to_cpu(pdi->len) - 1);
}
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 04/21] orinoco: fix truncating commsquality RID with the latest Symbol firmware
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Symbol firmware F3.91-71 has an additional word in the commsquality RID.
Extend the receiving buffer by one word to accomodate it.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8dfdfbd..06523e2 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -390,7 +390,7 @@ static struct iw_statistics *orinoco_get
}
} else {
struct {
- __le16 qual, signal, noise;
+ __le16 qual, signal, noise, unused;
} __attribute__ ((packed)) cq;
err = HERMES_READ_RECORD(hw, USER_BAP,
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 05/21] orinoco: remove tracing code, it's unused
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 83 ----------------------------------------
drivers/net/wireless/orinoco.h | 3 -
2 files changed, 0 insertions(+), 86 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 06523e2..9550bf3 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -456,26 +456,21 @@ static int orinoco_xmit(struct sk_buff *
struct hermes_tx_descriptor desc;
unsigned long flags;
- TRACE_ENTER(dev->name);
-
if (! netif_running(dev)) {
printk(KERN_ERR "%s: Tx on stopped device!\n",
dev->name);
- TRACE_EXIT(dev->name);
return 1;
}
if (netif_queue_stopped(dev)) {
printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
dev->name);
- TRACE_EXIT(dev->name);
return 1;
}
if (orinoco_lock(priv, &flags) != 0) {
printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
dev->name);
- TRACE_EXIT(dev->name);
return 1;
}
@@ -486,7 +481,6 @@ static int orinoco_xmit(struct sk_buff *
stats->tx_errors++;
orinoco_unlock(priv, &flags);
dev_kfree_skb(skb);
- TRACE_EXIT(dev->name);
return 0;
}
@@ -585,12 +579,9 @@ static int orinoco_xmit(struct sk_buff *
orinoco_unlock(priv, &flags);
dev_kfree_skb(skb);
-
- TRACE_EXIT(dev->name);
return 0;
fail:
- TRACE_EXIT(dev->name);
orinoco_unlock(priv, &flags);
return err;
@@ -2274,8 +2265,6 @@ static int orinoco_init(struct net_devic
u16 reclen;
int len;
- TRACE_ENTER(dev->name);
-
/* No need to lock, the hw_unavailable flag is already set in
* alloc_orinocodev() */
priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
@@ -2429,7 +2418,6 @@ static int orinoco_init(struct net_devic
printk(KERN_DEBUG "%s: ready\n", dev->name);
out:
- TRACE_EXIT(dev->name);
return err;
}
@@ -2796,8 +2784,6 @@ static int orinoco_ioctl_getiwrange(stru
struct iw_range *range = (struct iw_range *) extra;
int numrates;
int i, k;
-
- TRACE_ENTER(dev->name);
rrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
@@ -2888,8 +2874,6 @@ static int orinoco_ioctl_getiwrange(stru
IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
- TRACE_EXIT(dev->name);
-
return 0;
}
@@ -3070,8 +3054,6 @@ static int orinoco_ioctl_getessid(struct
int active;
int err = 0;
unsigned long flags;
-
- TRACE_ENTER(dev->name);
if (netif_running(dev)) {
err = orinoco_hw_get_essid(priv, &active, essidbuf);
@@ -3087,8 +3069,6 @@ static int orinoco_ioctl_getessid(struct
erq->flags = 1;
erq->length = strlen(essidbuf) + 1;
- TRACE_EXIT(dev->name);
-
return 0;
}
@@ -4347,69 +4327,6 @@ static struct ethtool_ops orinoco_ethtoo
.get_drvinfo = orinoco_get_drvinfo,
.get_link = ethtool_op_get_link,
};
-
-/********************************************************************/
-/* Debugging */
-/********************************************************************/
-
-#if 0
-static void show_rx_frame(struct orinoco_rxframe_hdr *frame)
-{
- printk(KERN_DEBUG "RX descriptor:\n");
- printk(KERN_DEBUG " status = 0x%04x\n", frame->desc.status);
- printk(KERN_DEBUG " time = 0x%08x\n", frame->desc.time);
- printk(KERN_DEBUG " silence = 0x%02x\n", frame->desc.silence);
- printk(KERN_DEBUG " signal = 0x%02x\n", frame->desc.signal);
- printk(KERN_DEBUG " rate = 0x%02x\n", frame->desc.rate);
- printk(KERN_DEBUG " rxflow = 0x%02x\n", frame->desc.rxflow);
- printk(KERN_DEBUG " reserved = 0x%08x\n", frame->desc.reserved);
-
- printk(KERN_DEBUG "IEEE 802.11 header:\n");
- printk(KERN_DEBUG " frame_ctl = 0x%04x\n",
- frame->p80211.frame_ctl);
- printk(KERN_DEBUG " duration_id = 0x%04x\n",
- frame->p80211.duration_id);
- printk(KERN_DEBUG " addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n",
- frame->p80211.addr1[0], frame->p80211.addr1[1],
- frame->p80211.addr1[2], frame->p80211.addr1[3],
- frame->p80211.addr1[4], frame->p80211.addr1[5]);
- printk(KERN_DEBUG " addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n",
- frame->p80211.addr2[0], frame->p80211.addr2[1],
- frame->p80211.addr2[2], frame->p80211.addr2[3],
- frame->p80211.addr2[4], frame->p80211.addr2[5]);
- printk(KERN_DEBUG " addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n",
- frame->p80211.addr3[0], frame->p80211.addr3[1],
- frame->p80211.addr3[2], frame->p80211.addr3[3],
- frame->p80211.addr3[4], frame->p80211.addr3[5]);
- printk(KERN_DEBUG " seq_ctl = 0x%04x\n",
- frame->p80211.seq_ctl);
- printk(KERN_DEBUG " addr4 = %02x:%02x:%02x:%02x:%02x:%02x\n",
- frame->p80211.addr4[0], frame->p80211.addr4[1],
- frame->p80211.addr4[2], frame->p80211.addr4[3],
- frame->p80211.addr4[4], frame->p80211.addr4[5]);
- printk(KERN_DEBUG " data_len = 0x%04x\n",
- frame->p80211.data_len);
-
- printk(KERN_DEBUG "IEEE 802.3 header:\n");
- printk(KERN_DEBUG " dest = %02x:%02x:%02x:%02x:%02x:%02x\n",
- frame->p8023.h_dest[0], frame->p8023.h_dest[1],
- frame->p8023.h_dest[2], frame->p8023.h_dest[3],
- frame->p8023.h_dest[4], frame->p8023.h_dest[5]);
- printk(KERN_DEBUG " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
- frame->p8023.h_source[0], frame->p8023.h_source[1],
- frame->p8023.h_source[2], frame->p8023.h_source[3],
- frame->p8023.h_source[4], frame->p8023.h_source[5]);
- printk(KERN_DEBUG " len = 0x%04x\n", frame->p8023.h_proto);
-
- printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");
- printk(KERN_DEBUG " DSAP = 0x%02x\n", frame->p8022.dsap);
- printk(KERN_DEBUG " SSAP = 0x%02x\n", frame->p8022.ssap);
- printk(KERN_DEBUG " ctrl = 0x%02x\n", frame->p8022.ctrl);
- printk(KERN_DEBUG " OUI = %02x:%02x:%02x\n",
- frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
- printk(KERN_DEBUG " ethertype = 0x%04x\n", frame->ethertype);
-}
-#endif /* 0 */
/********************************************************************/
/* Module initialization */
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index f5d856d..c6922a7 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -132,9 +132,6 @@ #else
#define DEBUG(n, args...) do { } while (0)
#endif /* ORINOCO_DEBUG */
-#define TRACE_ENTER(devname) DEBUG(2, "%s: -> %s()\n", devname, __FUNCTION__);
-#define TRACE_EXIT(devname) DEBUG(2, "%s: <- %s()\n", devname, __FUNCTION__);
-
/********************************************************************/
/* Exported prototypes */
/********************************************************************/
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 06/21] orinoco: remove debug buffer code and userspace include support
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/hermes.c | 19 -------------------
drivers/net/wireless/hermes.h | 34 ----------------------------------
2 files changed, 0 insertions(+), 53 deletions(-)
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 346c6fe..456d934 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -121,12 +121,6 @@ void hermes_struct_init(hermes_t *hw, vo
hw->iobase = address;
hw->reg_spacing = reg_spacing;
hw->inten = 0x0;
-
-#ifdef HERMES_DEBUG_BUFFER
- hw->dbufp = 0;
- memset(&hw->dbuf, 0xff, sizeof(hw->dbuf));
- memset(&hw->profile, 0, sizeof(hw->profile));
-#endif
}
int hermes_init(hermes_t *hw)
@@ -345,20 +339,7 @@ static int hermes_bap_seek(hermes_t *hw,
k--;
udelay(1);
reg = hermes_read_reg(hw, oreg);
- }
-
-#ifdef HERMES_DEBUG_BUFFER
- hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++;
-
- if (k < HERMES_BAP_BUSY_TIMEOUT) {
- struct hermes_debug_entry *e =
- &hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE];
- e->bap = bap;
- e->id = id;
- e->offset = offset;
- e->cycles = HERMES_BAP_BUSY_TIMEOUT - k;
}
-#endif
if (reg & HERMES_OFFSET_BUSY)
return -ETIMEDOUT;
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index 7644f72..34ccba2 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -328,16 +328,6 @@ struct hermes_multicast {
u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
} __attribute__ ((packed));
-// #define HERMES_DEBUG_BUFFER 1
-#define HERMES_DEBUG_BUFSIZE 4096
-struct hermes_debug_entry {
- int bap;
- u16 id, offset;
- int cycles;
-};
-
-#ifdef __KERNEL__
-
/* Timeouts */
#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
@@ -347,14 +337,7 @@ typedef struct hermes {
int reg_spacing;
#define HERMES_16BIT_REGSPACING 0
#define HERMES_32BIT_REGSPACING 1
-
u16 inten; /* Which interrupts should be enabled? */
-
-#ifdef HERMES_DEBUG_BUFFER
- struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
- unsigned long dbufp;
- unsigned long profile[HERMES_BAP_BUSY_TIMEOUT+1];
-#endif
} hermes_t;
/* Register access convenience macros */
@@ -461,22 +444,5 @@ static inline int hermes_write_wordrec(h
__le16 rec = cpu_to_le16(word);
return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
}
-
-#else /* ! __KERNEL__ */
-
-/* These are provided for the benefit of userspace drivers and testing programs
- which use ioperm() or iopl() */
-
-#define hermes_read_reg(base, off) (inw((base) + (off)))
-#define hermes_write_reg(base, off, val) (outw((val), (base) + (off)))
-
-#define hermes_read_regn(base, name) (hermes_read_reg((base), HERMES_##name))
-#define hermes_write_regn(base, name, val) (hermes_write_reg((base), HERMES_##name, (val)))
-
-/* Note that for the next two, the count is in 16-bit words, not bytes */
-#define hermes_read_data(base, off, buf, count) (insw((base) + (off), (buf), (count)))
-#define hermes_write_data(base, off, buf, count) (outsw((base) + (off), (buf), (count)))
-
-#endif /* ! __KERNEL__ */
#endif /* _HERMES_H */
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 07/21] orinoco: Symbol card supported by spectrum_cs is LA4137, not LA4100
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/spectrum_cs.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 58c153a..14f4daa 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -1,6 +1,6 @@
/*
* Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
- * Symbol Wireless Networker LA4100, CompactFlash cards by Socket
+ * Symbol Wireless Networker LA4137, CompactFlash cards by Socket
* Communications and Intel PRO/Wireless 2011B.
*
* The driver implements Symbol firmware download. The rest is handled
@@ -958,7 +958,7 @@ static char version[] __initdata = DRIVE
" David Gibson <hermes-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>, et al)";
static struct pcmcia_device_id spectrum_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
+ PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
PCMCIA_DEVICE_NULL,
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 08/21] orinoco: optimize Tx exception handling in orinoco
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
When processing Tx exception, only read data until addr1. Rename
hermes_tx_descriptor_802_11 to hermes_txexc_data since it's only used to
Tx exceptions. Reuse existing hermes_tx_descriptor structure. Remove
fields after addr1 - they are not read from the card.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 42 ++++++----------------------------------
1 files changed, 6 insertions(+), 36 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 9550bf3..ceea494 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -201,41 +201,12 @@ #define BITRATE_TABLE_SIZE ARRAY_SIZE(bi
/* Data types */
/********************************************************************/
-/* Used in Event handling.
- * We avoid nested structures as they break on ARM -- Moustafa */
-struct hermes_tx_descriptor_802_11 {
- /* hermes_tx_descriptor */
- __le16 status;
- __le16 reserved1;
- __le16 reserved2;
- __le32 sw_support;
- u8 retry_count;
- u8 tx_rate;
- __le16 tx_control;
-
- /* ieee80211_hdr */
+/* Beginning of the Tx descriptor, used in TxExc handling */
+struct hermes_txexc_data {
+ struct hermes_tx_descriptor desc;
__le16 frame_ctl;
__le16 duration_id;
u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
- u8 addr4[ETH_ALEN];
-
- __le16 data_len;
-
- /* ethhdr */
- u8 h_dest[ETH_ALEN]; /* destination eth addr */
- u8 h_source[ETH_ALEN]; /* source ether addr */
- __be16 h_proto; /* packet type ID field */
-
- /* p8022_hdr */
- u8 dsap;
- u8 ssap;
- u8 ctrl;
- u8 oui[3];
-
- __be16 ethertype;
} __attribute__ ((packed));
/* Rx frame header except compatibility 802.3 header */
@@ -620,7 +591,7 @@ static void __orinoco_ev_txexc(struct ne
struct net_device_stats *stats = &priv->stats;
u16 fid = hermes_read_regn(hw, TXCOMPLFID);
u16 status;
- struct hermes_tx_descriptor_802_11 hdr;
+ struct hermes_txexc_data hdr;
int err = 0;
if (fid == DUMMY_FID)
@@ -628,8 +599,7 @@ static void __orinoco_ev_txexc(struct ne
/* Read part of the frame header - we need status and addr1 */
err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
- offsetof(struct hermes_tx_descriptor_802_11,
- addr2),
+ sizeof(struct hermes_txexc_data),
fid, 0);
hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@@ -649,7 +619,7 @@ static void __orinoco_ev_txexc(struct ne
* exceeded, because that's the only status that really mean
* that this particular node went away.
* Other errors means that *we* screwed up. - Jean II */
- status = le16_to_cpu(hdr.status);
+ status = le16_to_cpu(hdr.desc.status);
if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
union iwreq_data wrqu;
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 09/21] orinoco: orinoco_xmit() should only return valid symbolic constants
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Don't ever return -errno from orinoco_xmit() - the network layer doesn't
expect it.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index ceea494..173e9e4 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -430,19 +430,19 @@ static int orinoco_xmit(struct sk_buff *
if (! netif_running(dev)) {
printk(KERN_ERR "%s: Tx on stopped device!\n",
dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
if (netif_queue_stopped(dev)) {
printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
if (orinoco_lock(priv, &flags) != 0) {
printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
@@ -452,7 +452,7 @@ static int orinoco_xmit(struct sk_buff *
stats->tx_errors++;
orinoco_unlock(priv, &flags);
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
/* Length of the packet body */
@@ -551,11 +551,11 @@ static int orinoco_xmit(struct sk_buff *
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
fail:
orinoco_unlock(priv, &flags);
- return err;
+ return NETDEV_TX_BUSY;
}
static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 10/21] orinoco replace hermes_write_words() with hermes_write_bytes()
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
The new function can write an odd number of bytes, thus making padding
unnecessary.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/hermes.c | 17 ++++++++---------
drivers/net/wireless/hermes.h | 7 +++++--
drivers/net/wireless/spectrum_cs.c | 7 +++----
3 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 456d934..be24f01 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -400,8 +400,7 @@ int hermes_bap_pread(hermes_t *hw, int b
}
/* Write a block of data to the chip's buffer, via the
- * BAP. Synchronization/serialization is the caller's problem. len
- * must be even.
+ * BAP. Synchronization/serialization is the caller's problem.
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
@@ -411,7 +410,7 @@ int hermes_bap_pwrite(hermes_t *hw, int
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
- if ( (len < 0) || (len % 2) )
+ if (len < 0)
return -EINVAL;
err = hermes_bap_seek(hw, bap, id, offset);
@@ -419,7 +418,7 @@ int hermes_bap_pwrite(hermes_t *hw, int
goto out;
/* Actually do the transfer */
- hermes_write_words(hw, dreg, buf, len/2);
+ hermes_write_bytes(hw, dreg, buf, len);
out:
return err;
@@ -427,7 +426,7 @@ int hermes_bap_pwrite(hermes_t *hw, int
/* Write a block of data to the chip's buffer with padding if
* neccessary, via the BAP. Synchronization/serialization is the
- * caller's problem. len must be even.
+ * caller's problem.
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
@@ -437,7 +436,7 @@ int hermes_bap_pwrite_pad(hermes_t *hw,
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
- if (len < 0 || len % 2 || data_len > len)
+ if (len < 0 || data_len > len)
return -EINVAL;
err = hermes_bap_seek(hw, bap, id, offset);
@@ -445,13 +444,13 @@ int hermes_bap_pwrite_pad(hermes_t *hw,
goto out;
/* Transfer all the complete words of data */
- hermes_write_words(hw, dreg, buf, data_len/2);
+ hermes_write_bytes(hw, dreg, buf, data_len);
/* If there is an odd byte left over pad and transfer it */
if (data_len & 1) {
u8 end[2];
end[1] = 0;
end[0] = ((unsigned char *)buf)[data_len - 1];
- hermes_write_words(hw, dreg, end, 1);
+ hermes_write_bytes(hw, dreg, end, 2);
data_len ++;
}
/* Now send zeros for the padding */
@@ -534,7 +533,7 @@ int hermes_write_ltv(hermes_t *hw, int b
count = length - 1;
- hermes_write_words(hw, dreg, value, count);
+ hermes_write_bytes(hw, dreg, value, count << 1);
err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
rid, NULL);
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index 34ccba2..e1b279e 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -408,10 +408,13 @@ static inline void hermes_read_words(str
ioread16_rep(hw->iobase + off, buf, count);
}
-static inline void hermes_write_words(struct hermes *hw, int off, const void *buf, unsigned count)
+static inline void hermes_write_bytes(struct hermes *hw, int off,
+ const char *buf, unsigned count)
{
off = off << hw->reg_spacing;
- iowrite16_rep(hw->iobase + off, buf, count);
+ iowrite16_rep(hw->iobase + off, buf, count >> 1);
+ if (unlikely(count & 1))
+ iowrite8(buf[count - 1], hw->iobase + off);
}
static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 14f4daa..c13a5b6 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -343,8 +343,7 @@ spectrum_plug_pdi(hermes_t *hw, struct p
/* do the actual plugging */
spectrum_aux_setaddr(hw, pdr_addr(pdr));
- hermes_write_words(hw, HERMES_AUXDATA, pdi->data,
- pdi_len(pdi) / 2);
+ hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
return 0;
}
@@ -424,8 +423,8 @@ spectrum_load_blocks(hermes_t *hw, const
while (dblock_addr(blk) != BLOCK_END) {
spectrum_aux_setaddr(hw, blkaddr);
- hermes_write_words(hw, HERMES_AUXDATA, blk->data,
- blklen / 2);
+ hermes_write_bytes(hw, HERMES_AUXDATA, blk->data,
+ blklen);
blk = (struct dblock *) &blk->data[blklen];
blkaddr = dblock_addr(blk);
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 11/21] orinoco: don't use any padding for Tx frames
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
hermes_bap_pwrite() supports odd-sized packets now. There is no
minimal packet size for 802.11. Also, hermes_bap_pwrite() supports
odd-sized packets now. This removes all reasons to pad the Tx data.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/hermes.c | 38 --------------------------------------
drivers/net/wireless/hermes.h | 2 --
drivers/net/wireless/orinoco.c | 25 +++++++------------------
3 files changed, 7 insertions(+), 58 deletions(-)
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index be24f01..2aa2f38 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -424,43 +424,6 @@ int hermes_bap_pwrite(hermes_t *hw, int
return err;
}
-/* Write a block of data to the chip's buffer with padding if
- * neccessary, via the BAP. Synchronization/serialization is the
- * caller's problem.
- *
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
- */
-int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, int len,
- u16 id, u16 offset)
-{
- int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
- int err = 0;
-
- if (len < 0 || data_len > len)
- return -EINVAL;
-
- err = hermes_bap_seek(hw, bap, id, offset);
- if (err)
- goto out;
-
- /* Transfer all the complete words of data */
- hermes_write_bytes(hw, dreg, buf, data_len);
- /* If there is an odd byte left over pad and transfer it */
- if (data_len & 1) {
- u8 end[2];
- end[1] = 0;
- end[0] = ((unsigned char *)buf)[data_len - 1];
- hermes_write_bytes(hw, dreg, end, 2);
- data_len ++;
- }
- /* Now send zeros for the padding */
- if (data_len < len)
- hermes_clear_words(hw, dreg, (len - data_len) / 2);
- /* Complete */
- out:
- return err;
-}
-
/* Read a Length-Type-Value record from the card.
*
* If length is NULL, we ignore the length read from the card, and
@@ -548,7 +511,6 @@ EXPORT_SYMBOL(hermes_allocate);
EXPORT_SYMBOL(hermes_bap_pread);
EXPORT_SYMBOL(hermes_bap_pwrite);
-EXPORT_SYMBOL(hermes_bap_pwrite_pad);
EXPORT_SYMBOL(hermes_read_ltv);
EXPORT_SYMBOL(hermes_write_ltv);
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index e1b279e..8e3f0e3 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -359,8 +359,6 @@ int hermes_bap_pread(hermes_t *hw, int b
u16 id, u16 offset);
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset);
-int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
- unsigned data_len, int len, u16 id, u16 offset);
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
u16 *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 173e9e4..9fde17b 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -423,7 +423,7 @@ static int orinoco_xmit(struct sk_buff *
u16 txfid = priv->txfid;
char *p;
struct ethhdr *eh;
- int len, data_len, data_off;
+ int data_len, data_off;
struct hermes_tx_descriptor desc;
unsigned long flags;
@@ -455,13 +455,10 @@ static int orinoco_xmit(struct sk_buff *
return NETDEV_TX_OK;
}
- /* Length of the packet body */
- /* FIXME: what if the skb is smaller than this? */
- len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
- skb = skb_padto(skb, len);
- if (skb == NULL)
+ /* Check packet length */
+ data_len = skb->len;
+ if (data_len < ETH_HLEN)
goto fail;
- len -= ETH_HLEN;
eh = (struct ethhdr *)skb->data;
@@ -485,7 +482,7 @@ static int orinoco_xmit(struct sk_buff *
/* Encapsulate Ethernet-II frames */
if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
struct header_struct hdr;
- data_len = len;
+ data_len = skb->len - ETH_HLEN;
data_off = HERMES_802_3_OFFSET + sizeof(hdr);
p = skb->data + ETH_HLEN;
@@ -507,21 +504,13 @@ static int orinoco_xmit(struct sk_buff *
stats->tx_errors++;
goto fail;
}
- /* Actual xfer length - allow for padding */
- len = ALIGN(data_len, 2);
- if (len < ETH_ZLEN - ETH_HLEN)
- len = ETH_ZLEN - ETH_HLEN;
} else { /* IEEE 802.3 frame */
- data_len = len + ETH_HLEN;
+ data_len = skb->len;
data_off = HERMES_802_3_OFFSET;
p = skb->data;
- /* Actual xfer length - round up for odd length packets */
- len = ALIGN(data_len, 2);
- if (len < ETH_ZLEN)
- len = ETH_ZLEN;
}
- err = hermes_bap_pwrite_pad(hw, USER_BAP, p, data_len, len,
+ err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
txfid, data_off);
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 12/21] orinoco: refactor and clean up Tx error handling
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
The result of orinoco_xmit() can be OK, dropped packet and busy
transmitter. Rename labels accordingly. Increment stats->tx_errors in
one place. Increment stats->tx_dropped - nobody is doing it for us.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 29 +++++++++++++----------------
1 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 9fde17b..e7d06b9 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -449,16 +449,13 @@ static int orinoco_xmit(struct sk_buff *
/* Oops, the firmware hasn't established a connection,
silently drop the packet (this seems to be the
safest approach). */
- stats->tx_errors++;
- orinoco_unlock(priv, &flags);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+ goto drop;
}
/* Check packet length */
data_len = skb->len;
if (data_len < ETH_HLEN)
- goto fail;
+ goto drop;
eh = (struct ethhdr *)skb->data;
@@ -469,8 +466,7 @@ static int orinoco_xmit(struct sk_buff *
if (net_ratelimit())
printk(KERN_ERR "%s: Error %d writing Tx descriptor "
"to BAP\n", dev->name, err);
- stats->tx_errors++;
- goto fail;
+ goto busy;
}
/* Clear the 802.11 header and data length fields - some
@@ -501,8 +497,7 @@ static int orinoco_xmit(struct sk_buff *
if (net_ratelimit())
printk(KERN_ERR "%s: Error %d writing packet "
"header to BAP\n", dev->name, err);
- stats->tx_errors++;
- goto fail;
+ goto busy;
}
} else { /* IEEE 802.3 frame */
data_len = skb->len;
@@ -515,8 +510,7 @@ static int orinoco_xmit(struct sk_buff *
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
dev->name, err);
- stats->tx_errors++;
- goto fail;
+ goto busy;
}
/* Finally, we actually initiate the send */
@@ -529,20 +523,23 @@ static int orinoco_xmit(struct sk_buff *
if (net_ratelimit())
printk(KERN_ERR "%s: Error %d transmitting packet\n",
dev->name, err);
- stats->tx_errors++;
- goto fail;
+ goto busy;
}
dev->trans_start = jiffies;
stats->tx_bytes += data_off + data_len;
+ goto ok;
- orinoco_unlock(priv, &flags);
+ drop:
+ stats->tx_errors++;
+ stats->tx_dropped++;
+ ok:
+ orinoco_unlock(priv, &flags);
dev_kfree_skb(skb);
-
return NETDEV_TX_OK;
- fail:
+ busy:
orinoco_unlock(priv, &flags);
return NETDEV_TX_BUSY;
}
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 13/21] orinoco: simplify 802.3 encapsulation code
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Use skb_pull() to strip the addresses from the original packet. Don't
strip protocol bytes.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 44 ++++++++++++++++++----------------------
drivers/net/wireless/orinoco.h | 14 -------------
2 files changed, 20 insertions(+), 38 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index e7d06b9..4d63738 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -421,9 +421,8 @@ static int orinoco_xmit(struct sk_buff *
hermes_t *hw = &priv->hw;
int err = 0;
u16 txfid = priv->txfid;
- char *p;
struct ethhdr *eh;
- int data_len, data_off;
+ int data_off;
struct hermes_tx_descriptor desc;
unsigned long flags;
@@ -453,8 +452,7 @@ static int orinoco_xmit(struct sk_buff *
}
/* Check packet length */
- data_len = skb->len;
- if (data_len < ETH_HLEN)
+ if (skb->len < ETH_HLEN)
goto drop;
eh = (struct ethhdr *)skb->data;
@@ -477,22 +475,22 @@ static int orinoco_xmit(struct sk_buff *
/* Encapsulate Ethernet-II frames */
if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
- struct header_struct hdr;
- data_len = skb->len - ETH_HLEN;
- data_off = HERMES_802_3_OFFSET + sizeof(hdr);
- p = skb->data + ETH_HLEN;
-
- /* 802.3 header */
- memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
- memcpy(hdr.src, eh->h_source, ETH_ALEN);
- hdr.len = htons(data_len + ENCAPS_OVERHEAD);
-
- /* 802.2 header */
- memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
-
- hdr.ethertype = eh->h_proto;
- err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
- txfid, HERMES_802_3_OFFSET);
+ struct header_struct {
+ struct ethhdr eth; /* 802.3 header */
+ u8 encap[6]; /* 802.2 header */
+ } __attribute__ ((packed)) hdr;
+
+ /* Strip destination and source from the data */
+ skb_pull(skb, 2 * ETH_ALEN);
+ data_off = HERMES_802_2_OFFSET + sizeof(encaps_hdr);
+
+ /* And move them to a separate header */
+ memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
+ hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
+ memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
+
+ err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
+ txfid, HERMES_802_3_OFFSET);
if (err) {
if (net_ratelimit())
printk(KERN_ERR "%s: Error %d writing packet "
@@ -500,12 +498,10 @@ static int orinoco_xmit(struct sk_buff *
goto busy;
}
} else { /* IEEE 802.3 frame */
- data_len = skb->len;
data_off = HERMES_802_3_OFFSET;
- p = skb->data;
}
- err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
+ err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
txfid, data_off);
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
@@ -527,7 +523,7 @@ static int orinoco_xmit(struct sk_buff *
}
dev->trans_start = jiffies;
- stats->tx_bytes += data_off + data_len;
+ stats->tx_bytes += data_off + skb->len;
goto ok;
drop:
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index c6922a7..ca01e45 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -30,20 +30,6 @@ struct orinoco_key {
char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed));
-struct header_struct {
- /* 802.3 */
- u8 dest[ETH_ALEN];
- u8 src[ETH_ALEN];
- __be16 len;
- /* 802.2 */
- u8 dsap;
- u8 ssap;
- u8 ctrl;
- /* SNAP */
- u8 oui[3];
- unsigned short ethertype;
-} __attribute__ ((packed));
-
typedef enum {
FIRMWARE_TYPE_AGERE,
FIRMWARE_TYPE_INTERSIL,
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 14/21] orinoco: fix BAP0 offset error after several days of operation
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Jiri Benc <jbenc-AlSwsSmVLrQ@public.gmane.org>
After several days of operation of Netgear MA311 card, the card becomes
to seek improperly and needs reset. This patch tries to reset the card
when this situation occurs.
Mar 9 06:45:16 berkeley kernel: wlan0: Error -5 writing packet to BAP
Mar 9 06:45:16 berkeley kernel: hermes @ f992a000: BAP0 offset error: reg=0x4044 id=0x128 offset=0x44
Mar 9 06:45:16 berkeley kernel: wlan0: Error -5 writing packet to BAP
Mar 9 06:45:16 berkeley kernel: hermes @ f992a000: BAP0 offset error: reg=0x4044 id=0x128 offset=0x44
(etc.)
A more detailed description of the problem can be found at
https://bugzilla.novell.com/show_bug.cgi?id=154773
The same problem with different card is reported at
http://sourceforge.net/mailarchive/message.php?msg_id=14597046
Signed-off-by: Jiri Benc <jbenc-AlSwsSmVLrQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 4d63738..80cf6fb 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -536,6 +536,8 @@ static int orinoco_xmit(struct sk_buff *
return NETDEV_TX_OK;
busy:
+ if (err == -EIO)
+ schedule_work(&priv->reset_work);
orinoco_unlock(priv, &flags);
return NETDEV_TX_BUSY;
}
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 15/21] orinoco: delay FID allocation after firmware initialization
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
This is needed to identify the card before possible allocation problems,
so that the user at least can report the firmware version that fails.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.c | 28 ++++++++++++++++++++++------
1 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 80cf6fb..d4c13ff 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1345,15 +1345,11 @@ int __orinoco_down(struct net_device *de
return 0;
}
-int orinoco_reinit_firmware(struct net_device *dev)
+static int orinoco_allocate_fid(struct net_device *dev)
{
struct orinoco_private *priv = netdev_priv(dev);
struct hermes *hw = &priv->hw;
int err;
-
- err = hermes_init(hw);
- if (err)
- return err;
err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
@@ -1372,7 +1368,20 @@ int orinoco_reinit_firmware(struct net_d
return err;
}
+
+int orinoco_reinit_firmware(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+ err = hermes_init(hw);
+ if (!err)
+ err = orinoco_allocate_fid(dev);
+
+ return err;
+}
+
static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
{
hermes_t *hw = &priv->hw;
@@ -2224,7 +2233,7 @@ static int orinoco_init(struct net_devic
priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
/* Initialize the firmware */
- err = orinoco_reinit_firmware(dev);
+ err = hermes_init(hw);
if (err != 0) {
printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
dev->name, err);
@@ -2281,6 +2290,13 @@ static int orinoco_init(struct net_devic
priv->nick[len] = '\0';
printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+
+ err = orinoco_allocate_fid(dev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
+ dev->name);
+ goto out;
+ }
/* Get allowed channels */
err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 16/21] orinoco_pci: disable device and free IRQ when suspending
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco_pci.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 5362c21..e57e92b 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -304,7 +304,9 @@ static int orinoco_pci_suspend(struct pc
orinoco_unlock(priv, &flags);
+ free_irq(pdev->irq, dev);
pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@@ -320,7 +322,16 @@ static int orinoco_pci_resume(struct pci
printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name);
pci_set_power_state(pdev, 0);
+ pci_enable_device(pdev);
pci_restore_state(pdev);
+
+ err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
+ dev->name, dev);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot re-allocate IRQ\n", dev->name);
+ pci_disable_device(pdev);
+ return -EBUSY;
+ }
err = orinoco_reinit_firmware(dev);
if (err) {
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 17/21] orinoco_pci: use pci_iomap() for resources
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco_pci.c | 15 ++++++---------
1 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index e57e92b..75df90f 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -170,9 +170,7 @@ static int orinoco_pci_init_one(struct p
const struct pci_device_id *ent)
{
int err = 0;
- unsigned long pci_iorange;
- u16 __iomem *pci_ioaddr = NULL;
- unsigned long pci_iolen;
+ void __iomem *pci_ioaddr = NULL;
struct orinoco_private *priv = NULL;
struct orinoco_pci_card *card;
struct net_device *dev = NULL;
@@ -190,10 +188,9 @@ static int orinoco_pci_init_one(struct p
}
/* Resource 0 is mapped to the hermes registers */
- pci_iorange = pci_resource_start(pdev, 0);
- pci_iolen = pci_resource_len(pdev, 0);
- pci_ioaddr = ioremap(pci_iorange, pci_iolen);
- if (!pci_iorange) {
+ pci_ioaddr = pci_iomap(pdev, 0, 0);
+ if (!pci_ioaddr) {
+ err = -EIO;
printk(KERN_ERR PFX "Cannot remap hardware registers\n");
goto fail_map;
}
@@ -208,8 +205,8 @@ static int orinoco_pci_init_one(struct p
priv = netdev_priv(dev);
card = priv->card;
card->pci_ioaddr = pci_ioaddr;
- dev->mem_start = pci_iorange;
- dev->mem_end = pci_iorange + pci_iolen - 1;
+ dev->mem_start = pci_resource_start(pdev, 0);
+ dev->mem_end = dev->mem_start + pci_resource_len(pdev, 0) - 1;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 18/21] orinoco: support PCI suspend/resume for Nortel, PLX and TMD adaptors
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Copy PCI suspend/resume functions from orinoco_pci.c.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco_nortel.c | 87 +++++++++++++++++++++++++++++++--
drivers/net/wireless/orinoco_plx.c | 79 ++++++++++++++++++++++++++++++
drivers/net/wireless/orinoco_tmd.c | 79 ++++++++++++++++++++++++++++++
3 files changed, 241 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index d1a670b..3fff013 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -263,6 +263,83 @@ static void __devexit nortel_pci_remove_
pci_disable_device(pdev);
}
+static int orinoco_nortel_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ err = orinoco_lock(priv, &flags);
+ if (err) {
+ printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
+ dev->name);
+ return err;
+ }
+
+ err = __orinoco_down(dev);
+ if (err)
+ printk(KERN_WARNING "%s: error %d bringing interface down "
+ "for suspend\n", dev->name, err);
+
+ netif_device_detach(dev);
+
+ priv->hw_unavailable++;
+
+ orinoco_unlock(priv, &flags);
+
+ free_irq(pdev->irq, dev);
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int orinoco_nortel_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ pci_set_power_state(pdev, 0);
+ pci_enable_device(pdev);
+ pci_restore_state(pdev);
+
+ err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
+ dev->name, dev);
+ if (err) {
+ printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
+ dev->name);
+ pci_disable_device(pdev);
+ return -EBUSY;
+ }
+
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: error %d re-initializing firmware "
+ "on resume\n", dev->name, err);
+ return err;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ netif_device_attach(dev);
+
+ priv->hw_unavailable--;
+
+ if (priv->open && (! priv->hw_unavailable)) {
+ err = __orinoco_up(dev);
+ if (err)
+ printk(KERN_ERR "%s: Error %d restarting card on resume\n",
+ dev->name, err);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
static struct pci_device_id nortel_pci_id_table[] = {
/* Nortel emobility PCI */
@@ -275,10 +352,12 @@ static struct pci_device_id nortel_pci_i
MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);
static struct pci_driver nortel_pci_driver = {
- .name = DRIVER_NAME,
- .id_table = nortel_pci_id_table,
- .probe = nortel_pci_init_one,
- .remove = __devexit_p(nortel_pci_remove_one),
+ .name = DRIVER_NAME,
+ .id_table = nortel_pci_id_table,
+ .probe = nortel_pci_init_one,
+ .remove = __devexit_p(nortel_pci_remove_one),
+ .suspend = orinoco_nortel_suspend,
+ .resume = orinoco_nortel_resume,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 210e737..3fe7a2f 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -343,6 +343,83 @@ static void __devexit orinoco_plx_remove
pci_disable_device(pdev);
}
+static int orinoco_plx_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ err = orinoco_lock(priv, &flags);
+ if (err) {
+ printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
+ dev->name);
+ return err;
+ }
+
+ err = __orinoco_down(dev);
+ if (err)
+ printk(KERN_WARNING "%s: error %d bringing interface down "
+ "for suspend\n", dev->name, err);
+
+ netif_device_detach(dev);
+
+ priv->hw_unavailable++;
+
+ orinoco_unlock(priv, &flags);
+
+ free_irq(pdev->irq, dev);
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int orinoco_plx_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ pci_set_power_state(pdev, 0);
+ pci_enable_device(pdev);
+ pci_restore_state(pdev);
+
+ err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
+ dev->name, dev);
+ if (err) {
+ printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
+ dev->name);
+ pci_disable_device(pdev);
+ return -EBUSY;
+ }
+
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: error %d re-initializing firmware "
+ "on resume\n", dev->name, err);
+ return err;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ netif_device_attach(dev);
+
+ priv->hw_unavailable--;
+
+ if (priv->open && (! priv->hw_unavailable)) {
+ err = __orinoco_up(dev);
+ if (err)
+ printk(KERN_ERR "%s: Error %d restarting card on resume\n",
+ dev->name, err);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
static struct pci_device_id orinoco_plx_pci_id_table[] = {
{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */
@@ -369,6 +446,8 @@ static struct pci_driver orinoco_plx_dri
.id_table = orinoco_plx_pci_id_table,
.probe = orinoco_plx_init_one,
.remove = __devexit_p(orinoco_plx_remove_one),
+ .suspend = orinoco_plx_suspend,
+ .resume = orinoco_plx_resume,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index 5e68b70..b74807d 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -215,6 +215,83 @@ static void __devexit orinoco_tmd_remove
pci_disable_device(pdev);
}
+static int orinoco_tmd_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ err = orinoco_lock(priv, &flags);
+ if (err) {
+ printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
+ dev->name);
+ return err;
+ }
+
+ err = __orinoco_down(dev);
+ if (err)
+ printk(KERN_WARNING "%s: error %d bringing interface down "
+ "for suspend\n", dev->name, err);
+
+ netif_device_detach(dev);
+
+ priv->hw_unavailable++;
+
+ orinoco_unlock(priv, &flags);
+
+ free_irq(pdev->irq, dev);
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int orinoco_tmd_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ pci_set_power_state(pdev, 0);
+ pci_enable_device(pdev);
+ pci_restore_state(pdev);
+
+ err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
+ dev->name, dev);
+ if (err) {
+ printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
+ dev->name);
+ pci_disable_device(pdev);
+ return -EBUSY;
+ }
+
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: error %d re-initializing firmware "
+ "on resume\n", dev->name, err);
+ return err;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ netif_device_attach(dev);
+
+ priv->hw_unavailable--;
+
+ if (priv->open && (! priv->hw_unavailable)) {
+ err = __orinoco_up(dev);
+ if (err)
+ printk(KERN_ERR "%s: Error %d restarting card on resume\n",
+ dev->name, err);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
static struct pci_device_id orinoco_tmd_pci_id_table[] = {
{0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */
@@ -228,6 +305,8 @@ static struct pci_driver orinoco_tmd_dri
.id_table = orinoco_tmd_pci_id_table,
.probe = orinoco_tmd_init_one,
.remove = __devexit_p(orinoco_tmd_remove_one),
+ .suspend = orinoco_tmd_suspend,
+ .resume = orinoco_tmd_resume,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 19/21] orinoco: reduce differences between PCI drivers, create orinoco_pci.h
From: Pavel Roskin @ 2006-04-07 8:10 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Make all Orinoco PCI drivers (orinoco_pci, orinoco_plx, orinoco_tmd and
orinoco_nortel) as similar as possible. Use the best implementation of
error handling, the best error messages, the best comments.
Put common code to orinoco_pci.h. For now, it's suspend and resume
functions and function for registering the network device.
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco_nortel.c | 240 +++++++++++--------------------
drivers/net/wireless/orinoco_pci.c | 144 +++---------------
drivers/net/wireless/orinoco_pci.h | 125 ++++++++++++++++
drivers/net/wireless/orinoco_plx.c | 259 +++++++++++----------------------
drivers/net/wireless/orinoco_tmd.c | 165 +++++----------------
5 files changed, 368 insertions(+), 565 deletions(-)
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index 3fff013..deb22fb 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -1,5 +1,5 @@
/* orinoco_nortel.c
- *
+ *
* Driver for Prism II devices which would usually be driven by orinoco_cs,
* but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in
* Nortel emobility, Symbol LA-4113 and Symbol LA-4123.
@@ -50,16 +50,11 @@ #include <linux/pci.h>
#include <pcmcia/cisreg.h>
#include "orinoco.h"
+#include "orinoco_pci.h"
#define COR_OFFSET (0xe0) /* COR attribute offset of Prism2 PC card */
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
-
-/* Nortel specific data */
-struct nortel_pci_card {
- unsigned long iobase1;
- unsigned long iobase2;
-};
/*
* Do a soft reset of the PCI card using the Configuration Option Register
@@ -69,48 +64,48 @@ struct nortel_pci_card {
* Note bis : Don't try to access HERMES_CMD during the reset phase.
* It just won't work !
*/
-static int nortel_pci_cor_reset(struct orinoco_private *priv)
+static int orinoco_nortel_cor_reset(struct orinoco_private *priv)
{
- struct nortel_pci_card *card = priv->card;
+ struct orinoco_pci_card *card = priv->card;
/* Assert the reset until the card notice */
- outw_p(8, card->iobase1 + 2);
- inw(card->iobase2 + COR_OFFSET);
- outw_p(0x80, card->iobase2 + COR_OFFSET);
+ iowrite16(8, card->bridge_io + 2);
+ ioread16(card->attr_io + COR_OFFSET);
+ iowrite16(0x80, card->attr_io + COR_OFFSET);
mdelay(1);
/* Give time for the card to recover from this hard effort */
- outw_p(0, card->iobase2 + COR_OFFSET);
- outw_p(0, card->iobase2 + COR_OFFSET);
+ iowrite16(0, card->attr_io + COR_OFFSET);
+ iowrite16(0, card->attr_io + COR_OFFSET);
mdelay(1);
- /* set COR as usual */
- outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
- outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
+ /* Set COR as usual */
+ iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
+ iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
mdelay(1);
- outw_p(0x228, card->iobase1 + 2);
+ iowrite16(0x228, card->bridge_io + 2);
return 0;
}
-static int nortel_pci_hw_init(struct nortel_pci_card *card)
+static int orinoco_nortel_hw_init(struct orinoco_pci_card *card)
{
int i;
u32 reg;
- /* setup bridge */
- if (inw(card->iobase1) & 1) {
+ /* Setup bridge */
+ if (ioread16(card->bridge_io) & 1) {
printk(KERN_ERR PFX "brg1 answer1 wrong\n");
return -EBUSY;
}
- outw_p(0x118, card->iobase1 + 2);
- outw_p(0x108, card->iobase1 + 2);
+ iowrite16(0x118, card->bridge_io + 2);
+ iowrite16(0x108, card->bridge_io + 2);
mdelay(30);
- outw_p(0x8, card->iobase1 + 2);
+ iowrite16(0x8, card->bridge_io + 2);
for (i = 0; i < 30; i++) {
mdelay(30);
- if (inw(card->iobase1) & 0x10) {
+ if (ioread16(card->bridge_io) & 0x10) {
break;
}
}
@@ -118,42 +113,42 @@ static int nortel_pci_hw_init(struct nor
printk(KERN_ERR PFX "brg1 timed out\n");
return -EBUSY;
}
- if (inw(card->iobase2 + 0xe0) & 1) {
+ if (ioread16(card->attr_io + COR_OFFSET) & 1) {
printk(KERN_ERR PFX "brg2 answer1 wrong\n");
return -EBUSY;
}
- if (inw(card->iobase2 + 0xe2) & 1) {
+ if (ioread16(card->attr_io + COR_OFFSET + 2) & 1) {
printk(KERN_ERR PFX "brg2 answer2 wrong\n");
return -EBUSY;
}
- if (inw(card->iobase2 + 0xe4) & 1) {
+ if (ioread16(card->attr_io + COR_OFFSET + 4) & 1) {
printk(KERN_ERR PFX "brg2 answer3 wrong\n");
return -EBUSY;
}
- /* set the PCMCIA COR-Register */
- outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
+ /* Set the PCMCIA COR-Register */
+ iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
mdelay(1);
- reg = inw(card->iobase2 + COR_OFFSET);
+ reg = ioread16(card->attr_io + COR_OFFSET);
if (reg != COR_VALUE) {
printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
reg);
return -EBUSY;
}
- /* set leds */
- outw_p(1, card->iobase1 + 10);
+ /* Set LEDs */
+ iowrite16(1, card->bridge_io + 10);
return 0;
}
-static int nortel_pci_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int orinoco_nortel_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
int err;
struct orinoco_private *priv;
- struct nortel_pci_card *card;
+ struct orinoco_pci_card *card;
struct net_device *dev;
- void __iomem *iomem;
+ void __iomem *hermes_io, *bridge_io, *attr_io;
err = pci_enable_device(pdev);
if (err) {
@@ -162,19 +157,34 @@ static int nortel_pci_init_one(struct pc
}
err = pci_request_regions(pdev, DRIVER_NAME);
- if (err != 0) {
+ if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
goto fail_resources;
}
- iomem = pci_iomap(pdev, 2, 0);
- if (!iomem) {
- err = -ENOMEM;
- goto fail_map_io;
+ bridge_io = pci_iomap(pdev, 0, 0);
+ if (!bridge_io) {
+ printk(KERN_ERR PFX "Cannot map bridge registers\n");
+ err = -EIO;
+ goto fail_map_bridge;
+ }
+
+ attr_io = pci_iomap(pdev, 1, 0);
+ if (!attr_io) {
+ printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
+ err = -EIO;
+ goto fail_map_attr;
+ }
+
+ hermes_io = pci_iomap(pdev, 2, 0);
+ if (!hermes_io) {
+ printk(KERN_ERR PFX "Cannot map chipset registers\n");
+ err = -EIO;
+ goto fail_map_hermes;
}
/* Allocate network device */
- dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset);
+ dev = alloc_orinocodev(sizeof(*card), orinoco_nortel_cor_reset);
if (!dev) {
printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
@@ -183,16 +193,12 @@ static int nortel_pci_init_one(struct pc
priv = netdev_priv(dev);
card = priv->card;
- card->iobase1 = pci_resource_start(pdev, 0);
- card->iobase2 = pci_resource_start(pdev, 1);
- dev->base_addr = pci_resource_start(pdev, 2);
+ card->bridge_io = bridge_io;
+ card->attr_io = attr_io;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
-
- hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING);
- printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, "
- "io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr);
+ hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
@@ -201,21 +207,20 @@ static int nortel_pci_init_one(struct pc
err = -EBUSY;
goto fail_irq;
}
- dev->irq = pdev->irq;
+ orinoco_pci_setup_netdev(dev, pdev, 2);
- err = nortel_pci_hw_init(card);
+ err = orinoco_nortel_hw_init(card);
if (err) {
printk(KERN_ERR PFX "Hardware initialization failed\n");
goto fail;
}
- err = nortel_pci_cor_reset(priv);
+ err = orinoco_nortel_cor_reset(priv);
if (err) {
printk(KERN_ERR PFX "Initial reset failed\n");
goto fail;
}
-
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "Cannot register network device\n");
@@ -234,9 +239,15 @@ static int nortel_pci_init_one(struct pc
free_orinocodev(dev);
fail_alloc:
- pci_iounmap(pdev, iomem);
+ pci_iounmap(pdev, hermes_io);
+
+ fail_map_hermes:
+ pci_iounmap(pdev, attr_io);
+
+ fail_map_attr:
+ pci_iounmap(pdev, bridge_io);
- fail_map_io:
+ fail_map_bridge:
pci_release_regions(pdev);
fail_resources:
@@ -245,103 +256,27 @@ static int nortel_pci_init_one(struct pc
return err;
}
-static void __devexit nortel_pci_remove_one(struct pci_dev *pdev)
+static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = netdev_priv(dev);
- struct nortel_pci_card *card = priv->card;
+ struct orinoco_pci_card *card = priv->card;
- /* clear leds */
- outw_p(0, card->iobase1 + 10);
+ /* Clear LEDs */
+ iowrite16(0, card->bridge_io + 10);
unregister_netdev(dev);
free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
pci_iounmap(pdev, priv->hw.iobase);
+ pci_iounmap(pdev, card->attr_io);
+ pci_iounmap(pdev, card->bridge_io);
pci_release_regions(pdev);
pci_disable_device(pdev);
-}
-
-static int orinoco_nortel_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- err = orinoco_lock(priv, &flags);
- if (err) {
- printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
- dev->name);
- return err;
- }
-
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: error %d bringing interface down "
- "for suspend\n", dev->name, err);
-
- netif_device_detach(dev);
-
- priv->hw_unavailable++;
-
- orinoco_unlock(priv, &flags);
-
- free_irq(pdev->irq, dev);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int orinoco_nortel_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- pci_set_power_state(pdev, 0);
- pci_enable_device(pdev);
- pci_restore_state(pdev);
-
- err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
- dev->name, dev);
- if (err) {
- printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
- dev->name);
- pci_disable_device(pdev);
- return -EBUSY;
- }
-
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: error %d re-initializing firmware "
- "on resume\n", dev->name, err);
- return err;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- netif_device_attach(dev);
-
- priv->hw_unavailable--;
-
- if (priv->open && (! priv->hw_unavailable)) {
- err = __orinoco_up(dev);
- if (err)
- printk(KERN_ERR "%s: Error %d restarting card on resume\n",
- dev->name, err);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
}
-static struct pci_device_id nortel_pci_id_table[] = {
+static struct pci_device_id orinoco_nortel_id_table[] = {
/* Nortel emobility PCI */
{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
/* Symbol LA-4123 PCI */
@@ -349,15 +284,15 @@ static struct pci_device_id nortel_pci_i
{0,},
};
-MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);
+MODULE_DEVICE_TABLE(pci, orinoco_nortel_id_table);
-static struct pci_driver nortel_pci_driver = {
+static struct pci_driver orinoco_nortel_driver = {
.name = DRIVER_NAME,
- .id_table = nortel_pci_id_table,
- .probe = nortel_pci_init_one,
- .remove = __devexit_p(nortel_pci_remove_one),
- .suspend = orinoco_nortel_suspend,
- .resume = orinoco_nortel_resume,
+ .id_table = orinoco_nortel_id_table,
+ .probe = orinoco_nortel_init_one,
+ .remove = __devexit_p(orinoco_nortel_remove_one),
+ .suspend = orinoco_pci_suspend,
+ .resume = orinoco_pci_resume,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
@@ -367,20 +302,19 @@ MODULE_DESCRIPTION
("Driver for wireless LAN cards using the Nortel PCI bridge");
MODULE_LICENSE("Dual MPL/GPL");
-static int __init nortel_pci_init(void)
+static int __init orinoco_nortel_init(void)
{
printk(KERN_DEBUG "%s\n", version);
- return pci_module_init(&nortel_pci_driver);
+ return pci_module_init(&orinoco_nortel_driver);
}
-static void __exit nortel_pci_exit(void)
+static void __exit orinoco_nortel_exit(void)
{
- pci_unregister_driver(&nortel_pci_driver);
- ssleep(1);
+ pci_unregister_driver(&orinoco_nortel_driver);
}
-module_init(nortel_pci_init);
-module_exit(nortel_pci_exit);
+module_init(orinoco_nortel_init);
+module_exit(orinoco_nortel_exit);
/*
* Local variables:
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 75df90f..41efac2 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -100,6 +100,7 @@ #include <linux/delay.h>
#include <linux/pci.h>
#include "orinoco.h"
+#include "orinoco_pci.h"
/* All the magic there is from wlan-ng */
/* Magic offset of the reset register of the PCI card */
@@ -113,11 +114,6 @@ #define HERMES_PCI_COR_ONT (250) /* ms
#define HERMES_PCI_COR_OFFT (500) /* ms */
#define HERMES_PCI_COR_BUSYT (500) /* ms */
-/* Orinoco PCI specific data */
-struct orinoco_pci_card {
- void __iomem *pci_ioaddr;
-};
-
/*
* Do a soft reset of the PCI card using the Configuration Option Register
* We need this to get going...
@@ -131,12 +127,11 @@ struct orinoco_pci_card {
* Note bis : Don't try to access HERMES_CMD during the reset phase.
* It just won't work !
*/
-static int
-orinoco_pci_cor_reset(struct orinoco_private *priv)
+static int orinoco_pci_cor_reset(struct orinoco_private *priv)
{
hermes_t *hw = &priv->hw;
- unsigned long timeout;
- u16 reg;
+ unsigned long timeout;
+ u16 reg;
/* Assert the reset until the card notice */
hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
@@ -163,17 +158,14 @@ orinoco_pci_cor_reset(struct orinoco_pri
return 0;
}
-/*
- * Initialise a card. Mostly similar to PLX code.
- */
static int orinoco_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int err = 0;
- void __iomem *pci_ioaddr = NULL;
- struct orinoco_private *priv = NULL;
+ int err;
+ struct orinoco_private *priv;
struct orinoco_pci_card *card;
- struct net_device *dev = NULL;
+ struct net_device *dev;
+ void __iomem *hermes_io;
err = pci_enable_device(pdev);
if (err) {
@@ -182,39 +174,33 @@ static int orinoco_pci_init_one(struct p
}
err = pci_request_regions(pdev, DRIVER_NAME);
- if (err != 0) {
+ if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
goto fail_resources;
}
- /* Resource 0 is mapped to the hermes registers */
- pci_ioaddr = pci_iomap(pdev, 0, 0);
- if (!pci_ioaddr) {
+ hermes_io = pci_iomap(pdev, 0, 0);
+ if (!hermes_io) {
+ printk(KERN_ERR PFX "Cannot remap chipset registers\n");
err = -EIO;
- printk(KERN_ERR PFX "Cannot remap hardware registers\n");
- goto fail_map;
+ goto fail_map_hermes;
}
/* Allocate network device */
dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset);
- if (! dev) {
+ if (!dev) {
+ printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
goto fail_alloc;
}
priv = netdev_priv(dev);
card = priv->card;
- card->pci_ioaddr = pci_ioaddr;
- dev->mem_start = pci_resource_start(pdev, 0);
- dev->mem_end = dev->mem_start + pci_resource_len(pdev, 0) - 1;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
- hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING);
+ hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);
- printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n",
- pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq);
-
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
if (err) {
@@ -222,9 +208,8 @@ static int orinoco_pci_init_one(struct p
err = -EBUSY;
goto fail_irq;
}
- dev->irq = pdev->irq;
+ orinoco_pci_setup_netdev(dev, pdev, 0);
- /* Perform a COR reset to start the card */
err = orinoco_pci_cor_reset(priv);
if (err) {
printk(KERN_ERR PFX "Initial reset failed\n");
@@ -233,7 +218,7 @@ static int orinoco_pci_init_one(struct p
err = register_netdev(dev);
if (err) {
- printk(KERN_ERR PFX "Failed to register net device\n");
+ printk(KERN_ERR PFX "Cannot register network device\n");
goto fail;
}
@@ -249,9 +234,9 @@ static int orinoco_pci_init_one(struct p
free_orinocodev(dev);
fail_alloc:
- iounmap(pci_ioaddr);
+ pci_iounmap(pdev, hermes_io);
- fail_map:
+ fail_map_hermes:
pci_release_regions(pdev);
fail_resources:
@@ -264,98 +249,17 @@ static void __devexit orinoco_pci_remove
{
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = netdev_priv(dev);
- struct orinoco_pci_card *card = priv->card;
unregister_netdev(dev);
free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
- iounmap(card->pci_ioaddr);
+ pci_iounmap(pdev, priv->hw.iobase);
pci_release_regions(pdev);
- pci_disable_device(pdev);
-}
-
-static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
-
- err = orinoco_lock(priv, &flags);
- if (err) {
- printk(KERN_ERR "%s: hw_unavailable on orinoco_pci_suspend\n",
- dev->name);
- return err;
- }
-
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: orinoco_pci_suspend(): Error %d downing interface\n",
- dev->name, err);
-
- netif_device_detach(dev);
-
- priv->hw_unavailable++;
-
- orinoco_unlock(priv, &flags);
-
- free_irq(pdev->irq, dev);
- pci_save_state(pdev);
pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int orinoco_pci_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name);
-
- pci_set_power_state(pdev, 0);
- pci_enable_device(pdev);
- pci_restore_state(pdev);
-
- err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
- dev->name, dev);
- if (err) {
- printk(KERN_ERR "%s: Cannot re-allocate IRQ\n", dev->name);
- pci_disable_device(pdev);
- return -EBUSY;
- }
-
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: Error %d re-initializing firmware on orinoco_pci_resume()\n",
- dev->name, err);
- return err;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- netif_device_attach(dev);
-
- priv->hw_unavailable--;
-
- if (priv->open && (! priv->hw_unavailable)) {
- err = __orinoco_up(dev);
- if (err)
- printk(KERN_ERR "%s: Error %d restarting card on orinoco_pci_resume()\n",
- dev->name, err);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
}
-static struct pci_device_id orinoco_pci_pci_id_table[] = {
+static struct pci_device_id orinoco_pci_id_table[] = {
/* Intersil Prism 3 */
{0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
/* Intersil Prism 2.5 */
@@ -365,11 +269,11 @@ static struct pci_device_id orinoco_pci_
{0,},
};
-MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table);
+MODULE_DEVICE_TABLE(pci, orinoco_pci_id_table);
static struct pci_driver orinoco_pci_driver = {
.name = DRIVER_NAME,
- .id_table = orinoco_pci_pci_id_table,
+ .id_table = orinoco_pci_id_table,
.probe = orinoco_pci_init_one,
.remove = __devexit_p(orinoco_pci_remove_one),
.suspend = orinoco_pci_suspend,
diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco_pci.h
new file mode 100644
index 0000000..b05a9a5
--- /dev/null
+++ b/drivers/net/wireless/orinoco_pci.h
@@ -0,0 +1,125 @@
+/* orinoco_pci.h
+ *
+ * Common code for all Orinoco drivers for PCI devices, including
+ * both native PCI and PCMCIA-to-PCI bridges.
+ *
+ * Copyright (C) 2005, Pavel Roskin.
+ * See orinoco.c for license.
+ */
+
+#ifndef _ORINOCO_PCI_H
+#define _ORINOCO_PCI_H
+
+#include <linux/netdevice.h>
+
+/* Driver specific data */
+struct orinoco_pci_card {
+ void __iomem *bridge_io;
+ void __iomem *attr_io;
+};
+
+/* Set base address or memory range of the network device based on
+ * the PCI device it's using. Specify BAR of the "main" resource.
+ * To be used after request_irq(). */
+static inline void orinoco_pci_setup_netdev(struct net_device *dev,
+ struct pci_dev *pdev, int bar)
+{
+ char *range_type;
+ unsigned long start = pci_resource_start(pdev, bar);
+ unsigned long len = pci_resource_len(pdev, bar);
+ unsigned long flags = pci_resource_flags(pdev, bar);
+ unsigned long end = start + len - 1;
+
+ dev->irq = pdev->irq;
+ if (flags & IORESOURCE_IO) {
+ dev->base_addr = start;
+ range_type = "ports";
+ } else {
+ dev->mem_start = start;
+ dev->mem_end = end;
+ range_type = "memory";
+ }
+
+ printk(KERN_DEBUG PFX "%s: irq %d, %s 0x%lx-0x%lx\n",
+ pci_name(pdev), pdev->irq, range_type, start, end);
+}
+
+static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ err = orinoco_lock(priv, &flags);
+ if (err) {
+ printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
+ dev->name);
+ return err;
+ }
+
+ err = __orinoco_down(dev);
+ if (err)
+ printk(KERN_WARNING "%s: error %d bringing interface down "
+ "for suspend\n", dev->name, err);
+
+ netif_device_detach(dev);
+
+ priv->hw_unavailable++;
+
+ orinoco_unlock(priv, &flags);
+
+ free_irq(pdev->irq, dev);
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int orinoco_pci_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ pci_set_power_state(pdev, 0);
+ pci_enable_device(pdev);
+ pci_restore_state(pdev);
+
+ err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
+ dev->name, dev);
+ if (err) {
+ printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
+ dev->name);
+ pci_disable_device(pdev);
+ return -EBUSY;
+ }
+
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: error %d re-initializing firmware "
+ "on resume\n", dev->name, err);
+ return err;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ netif_device_attach(dev);
+
+ priv->hw_unavailable--;
+
+ if (priv->open && (! priv->hw_unavailable)) {
+ err = __orinoco_up(dev);
+ if (err)
+ printk(KERN_ERR "%s: Error %d restarting card on resume\n",
+ dev->name, err);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+#endif /* _ORINOCO_PCI_H */
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 3fe7a2f..c00388e 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -33,7 +33,7 @@
* Caution: this is experimental and probably buggy. For success and
* failure reports for different cards and adaptors, see
- * orinoco_plx_pci_id_table near the end of the file. If you have a
+ * orinoco_plx_id_table near the end of the file. If you have a
* card we don't have the PCI id for, and looks like it should work,
* drop me mail with the id and "it works"/"it doesn't work".
*
@@ -125,6 +125,7 @@ #include <linux/pci.h>
#include <pcmcia/cisreg.h>
#include "orinoco.h"
+#include "orinoco_pci.h"
#define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
@@ -134,30 +135,20 @@ #define PLX_RESET_TIME (500) /* millisec
#define PLX_INTCSR 0x4c /* Interrupt Control & Status Register */
#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
-static const u8 cis_magic[] = {
- 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
-};
-
-/* Orinoco PLX specific data */
-struct orinoco_plx_card {
- void __iomem *attr_mem;
-};
-
/*
* Do a soft reset of the card using the Configuration Option Register
*/
static int orinoco_plx_cor_reset(struct orinoco_private *priv)
{
hermes_t *hw = &priv->hw;
- struct orinoco_plx_card *card = priv->card;
- u8 __iomem *attr_mem = card->attr_mem;
+ struct orinoco_pci_card *card = priv->card;
unsigned long timeout;
u16 reg;
- writeb(COR_VALUE | COR_RESET, attr_mem + COR_OFFSET);
+ iowrite8(COR_VALUE | COR_RESET, card->attr_io + COR_OFFSET);
mdelay(1);
- writeb(COR_VALUE, attr_mem + COR_OFFSET);
+ iowrite8(COR_VALUE, card->attr_io + COR_OFFSET);
mdelay(1);
/* Just in case, wait more until the card is no longer busy */
@@ -168,7 +159,7 @@ static int orinoco_plx_cor_reset(struct
reg = hermes_read_regn(hw, CMD);
}
- /* Did we timeout ? */
+ /* Still busy? */
if (reg & HERMES_CMD_BUSY) {
printk(KERN_ERR PFX "Busy timeout\n");
return -ETIMEDOUT;
@@ -176,21 +167,56 @@ static int orinoco_plx_cor_reset(struct
return 0;
}
+
+static int orinoco_plx_hw_init(struct orinoco_pci_card *card)
+{
+ int i;
+ u32 csr_reg;
+ static const u8 cis_magic[] = {
+ 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
+ };
+
+ printk(KERN_DEBUG PFX "CIS: ");
+ for (i = 0; i < 16; i++) {
+ printk("%02X:", ioread8(card->attr_io + (i << 1)));
+ }
+ printk("\n");
+
+ /* Verify whether a supported PC card is present */
+ /* FIXME: we probably need to be smarted about this */
+ for (i = 0; i < sizeof(cis_magic); i++) {
+ if (cis_magic[i] != ioread8(card->attr_io + (i << 1))) {
+ printk(KERN_ERR PFX "The CIS value of Prism2 PC "
+ "card is unexpected\n");
+ return -ENODEV;
+ }
+ }
+
+ /* bjoern: We need to tell the card to enable interrupts, in
+ case the serial eprom didn't do this already. See the
+ PLX9052 data book, p8-1 and 8-24 for reference. */
+ csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
+ if (!(csr_reg & PLX_INTCSR_INTEN)) {
+ csr_reg |= PLX_INTCSR_INTEN;
+ iowrite32(csr_reg, card->bridge_io + PLX_INTCSR);
+ csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
+ if (!(csr_reg & PLX_INTCSR_INTEN)) {
+ printk(KERN_ERR PFX "Cannot enable interrupts\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
static int orinoco_plx_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int err = 0;
- u8 __iomem *attr_mem = NULL;
- u32 csr_reg, plx_addr;
- struct orinoco_private *priv = NULL;
- struct orinoco_plx_card *card;
- unsigned long pccard_ioaddr = 0;
- unsigned long pccard_iolen = 0;
- struct net_device *dev = NULL;
- void __iomem *mem;
- int i;
+ int err;
+ struct orinoco_private *priv;
+ struct orinoco_pci_card *card;
+ struct net_device *dev;
+ void __iomem *hermes_io, *attr_io, *bridge_io;
err = pci_enable_device(pdev);
if (err) {
@@ -199,30 +225,30 @@ static int orinoco_plx_init_one(struct p
}
err = pci_request_regions(pdev, DRIVER_NAME);
- if (err != 0) {
+ if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
goto fail_resources;
}
- /* Resource 1 is mapped to PLX-specific registers */
- plx_addr = pci_resource_start(pdev, 1);
+ bridge_io = pci_iomap(pdev, 1, 0);
+ if (!bridge_io) {
+ printk(KERN_ERR PFX "Cannot map bridge registers\n");
+ err = -EIO;
+ goto fail_map_bridge;
+ }
- /* Resource 2 is mapped to the PCMCIA attribute memory */
- attr_mem = ioremap(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
- if (!attr_mem) {
- printk(KERN_ERR PFX "Cannot remap PCMCIA space\n");
+ attr_io = pci_iomap(pdev, 2, 0);
+ if (!attr_io) {
+ printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
+ err = -EIO;
goto fail_map_attr;
}
- /* Resource 3 is mapped to the PCMCIA I/O address space */
- pccard_ioaddr = pci_resource_start(pdev, 3);
- pccard_iolen = pci_resource_len(pdev, 3);
-
- mem = pci_iomap(pdev, 3, 0);
- if (!mem) {
- err = -ENOMEM;
- goto fail_map_io;
+ hermes_io = pci_iomap(pdev, 3, 0);
+ if (!hermes_io) {
+ printk(KERN_ERR PFX "Cannot map chipset registers\n");
+ err = -EIO;
+ goto fail_map_hermes;
}
/* Allocate network device */
@@ -235,16 +261,12 @@ static int orinoco_plx_init_one(struct p
priv = netdev_priv(dev);
card = priv->card;
- card->attr_mem = attr_mem;
- dev->base_addr = pccard_ioaddr;
+ card->bridge_io = bridge_io;
+ card->attr_io = attr_io;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
-
- hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
- printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device "
- "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
- pccard_ioaddr);
+ hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
@@ -253,45 +275,20 @@ static int orinoco_plx_init_one(struct p
err = -EBUSY;
goto fail_irq;
}
- dev->irq = pdev->irq;
+ orinoco_pci_setup_netdev(dev, pdev, 2);
- /* bjoern: We need to tell the card to enable interrupts, in
- case the serial eprom didn't do this already. See the
- PLX9052 data book, p8-1 and 8-24 for reference. */
- csr_reg = inl(plx_addr + PLX_INTCSR);
- if (!(csr_reg & PLX_INTCSR_INTEN)) {
- csr_reg |= PLX_INTCSR_INTEN;
- outl(csr_reg, plx_addr + PLX_INTCSR);
- csr_reg = inl(plx_addr + PLX_INTCSR);
- if (!(csr_reg & PLX_INTCSR_INTEN)) {
- printk(KERN_ERR PFX "Cannot enable interrupts\n");
- goto fail;
- }
+ err = orinoco_plx_hw_init(card);
+ if (err) {
+ printk(KERN_ERR PFX "Hardware initialization failed\n");
+ goto fail;
}
err = orinoco_plx_cor_reset(priv);
if (err) {
printk(KERN_ERR PFX "Initial reset failed\n");
goto fail;
- }
-
- printk(KERN_DEBUG PFX "CIS: ");
- for (i = 0; i < 16; i++) {
- printk("%02X:", readb(attr_mem + 2*i));
}
- printk("\n");
- /* Verify whether a supported PC card is present */
- /* FIXME: we probably need to be smarted about this */
- for (i = 0; i < sizeof(cis_magic); i++) {
- if (cis_magic[i] != readb(attr_mem +2*i)) {
- printk(KERN_ERR PFX "The CIS value of Prism2 PC "
- "card is unexpected\n");
- err = -EIO;
- goto fail;
- }
- }
-
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "Cannot register network device\n");
@@ -310,12 +307,15 @@ static int orinoco_plx_init_one(struct p
free_orinocodev(dev);
fail_alloc:
- pci_iounmap(pdev, mem);
+ pci_iounmap(pdev, hermes_io);
- fail_map_io:
- iounmap(attr_mem);
+ fail_map_hermes:
+ pci_iounmap(pdev, attr_io);
fail_map_attr:
+ pci_iounmap(pdev, bridge_io);
+
+ fail_map_bridge:
pci_release_regions(pdev);
fail_resources:
@@ -328,100 +328,20 @@ static void __devexit orinoco_plx_remove
{
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = netdev_priv(dev);
- struct orinoco_plx_card *card = priv->card;
- u8 __iomem *attr_mem = card->attr_mem;
-
- BUG_ON(! dev);
+ struct orinoco_pci_card *card = priv->card;
unregister_netdev(dev);
free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
pci_iounmap(pdev, priv->hw.iobase);
- iounmap(attr_mem);
+ pci_iounmap(pdev, card->attr_io);
+ pci_iounmap(pdev, card->bridge_io);
pci_release_regions(pdev);
- pci_disable_device(pdev);
-}
-
-static int orinoco_plx_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- err = orinoco_lock(priv, &flags);
- if (err) {
- printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
- dev->name);
- return err;
- }
-
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: error %d bringing interface down "
- "for suspend\n", dev->name, err);
-
- netif_device_detach(dev);
-
- priv->hw_unavailable++;
-
- orinoco_unlock(priv, &flags);
-
- free_irq(pdev->irq, dev);
- pci_save_state(pdev);
pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int orinoco_plx_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- pci_set_power_state(pdev, 0);
- pci_enable_device(pdev);
- pci_restore_state(pdev);
-
- err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
- dev->name, dev);
- if (err) {
- printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
- dev->name);
- pci_disable_device(pdev);
- return -EBUSY;
- }
-
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: error %d re-initializing firmware "
- "on resume\n", dev->name, err);
- return err;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- netif_device_attach(dev);
-
- priv->hw_unavailable--;
-
- if (priv->open && (! priv->hw_unavailable)) {
- err = __orinoco_up(dev);
- if (err)
- printk(KERN_ERR "%s: Error %d restarting card on resume\n",
- dev->name, err);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
}
-static struct pci_device_id orinoco_plx_pci_id_table[] = {
+static struct pci_device_id orinoco_plx_id_table[] = {
{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */
{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */
{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */
@@ -439,15 +359,15 @@ static struct pci_device_id orinoco_plx_
{0,},
};
-MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table);
+MODULE_DEVICE_TABLE(pci, orinoco_plx_id_table);
static struct pci_driver orinoco_plx_driver = {
.name = DRIVER_NAME,
- .id_table = orinoco_plx_pci_id_table,
+ .id_table = orinoco_plx_id_table,
.probe = orinoco_plx_init_one,
.remove = __devexit_p(orinoco_plx_remove_one),
- .suspend = orinoco_plx_suspend,
- .resume = orinoco_plx_resume,
+ .suspend = orinoco_pci_suspend,
+ .resume = orinoco_pci_resume,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
@@ -467,7 +387,6 @@ static int __init orinoco_plx_init(void)
static void __exit orinoco_plx_exit(void)
{
pci_unregister_driver(&orinoco_plx_driver);
- ssleep(1);
}
module_init(orinoco_plx_init);
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index b74807d..438fe54 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -1,5 +1,5 @@
/* orinoco_tmd.c
- *
+ *
* Driver for Prism II devices which would usually be driven by orinoco_cs,
* but are connected to the PCI bus by a TMD7160.
*
@@ -29,14 +29,14 @@
* Caution: this is experimental and probably buggy. For success and
* failure reports for different cards and adaptors, see
- * orinoco_tmd_pci_id_table near the end of the file. If you have a
+ * orinoco_tmd_id_table near the end of the file. If you have a
* card we don't have the PCI id for, and looks like it should work,
* drop me mail with the id and "it works"/"it doesn't work".
*
* Note: if everything gets detected fine but it doesn't actually send
- * or receive packets, your first port of call should probably be to
+ * or receive packets, your first port of call should probably be to
* try newer firmware in the card. Especially if you're doing Ad-Hoc
- * modes
+ * modes.
*
* The actual driving is done by orinoco.c, this is just resource
* allocation stuff.
@@ -61,16 +61,11 @@ #include <linux/pci.h>
#include <pcmcia/cisreg.h>
#include "orinoco.h"
+#include "orinoco_pci.h"
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
#define COR_RESET (0x80) /* reset bit in the COR register */
#define TMD_RESET_TIME (500) /* milliseconds */
-
-/* Orinoco TMD specific data */
-struct orinoco_tmd_card {
- u32 tmd_io;
-};
-
/*
* Do a soft reset of the card using the Configuration Option Register
@@ -78,15 +73,14 @@ struct orinoco_tmd_card {
static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
{
hermes_t *hw = &priv->hw;
- struct orinoco_tmd_card *card = priv->card;
- u32 addr = card->tmd_io;
+ struct orinoco_pci_card *card = priv->card;
unsigned long timeout;
u16 reg;
- outb(COR_VALUE | COR_RESET, addr);
+ iowrite8(COR_VALUE | COR_RESET, card->bridge_io);
mdelay(1);
- outb(COR_VALUE, addr);
+ iowrite8(COR_VALUE, card->bridge_io);
mdelay(1);
/* Just in case, wait more until the card is no longer busy */
@@ -97,7 +91,7 @@ static int orinoco_tmd_cor_reset(struct
reg = hermes_read_regn(hw, CMD);
}
- /* Did we timeout ? */
+ /* Still busy? */
if (reg & HERMES_CMD_BUSY) {
printk(KERN_ERR PFX "Busy timeout\n");
return -ETIMEDOUT;
@@ -110,11 +104,11 @@ static int orinoco_tmd_cor_reset(struct
static int orinoco_tmd_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int err = 0;
- struct orinoco_private *priv = NULL;
- struct orinoco_tmd_card *card;
- struct net_device *dev = NULL;
- void __iomem *mem;
+ int err;
+ struct orinoco_private *priv;
+ struct orinoco_pci_card *card;
+ struct net_device *dev;
+ void __iomem *hermes_io, *bridge_io;
err = pci_enable_device(pdev);
if (err) {
@@ -123,20 +117,28 @@ static int orinoco_tmd_init_one(struct p
}
err = pci_request_regions(pdev, DRIVER_NAME);
- if (err != 0) {
+ if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
goto fail_resources;
}
- mem = pci_iomap(pdev, 2, 0);
- if (! mem) {
- err = -ENOMEM;
- goto fail_iomap;
+ bridge_io = pci_iomap(pdev, 1, 0);
+ if (!bridge_io) {
+ printk(KERN_ERR PFX "Cannot map bridge registers\n");
+ err = -EIO;
+ goto fail_map_bridge;
}
+ hermes_io = pci_iomap(pdev, 2, 0);
+ if (!hermes_io) {
+ printk(KERN_ERR PFX "Cannot map chipset registers\n");
+ err = -EIO;
+ goto fail_map_hermes;
+ }
+
/* Allocate network device */
dev = alloc_orinocodev(sizeof(*card), orinoco_tmd_cor_reset);
- if (! dev) {
+ if (!dev) {
printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
goto fail_alloc;
@@ -144,16 +146,11 @@ static int orinoco_tmd_init_one(struct p
priv = netdev_priv(dev);
card = priv->card;
- card->tmd_io = pci_resource_start(pdev, 1);
- dev->base_addr = pci_resource_start(pdev, 2);
+ card->bridge_io = bridge_io;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
-
- hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
- printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device "
- "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
- dev->base_addr);
+ hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
@@ -162,7 +159,7 @@ static int orinoco_tmd_init_one(struct p
err = -EBUSY;
goto fail_irq;
}
- dev->irq = pdev->irq;
+ orinoco_pci_setup_netdev(dev, pdev, 2);
err = orinoco_tmd_cor_reset(priv);
if (err) {
@@ -188,9 +185,12 @@ static int orinoco_tmd_init_one(struct p
free_orinocodev(dev);
fail_alloc:
- pci_iounmap(pdev, mem);
+ pci_iounmap(pdev, hermes_io);
- fail_iomap:
+ fail_map_hermes:
+ pci_iounmap(pdev, bridge_io);
+
+ fail_map_bridge:
pci_release_regions(pdev);
fail_resources:
@@ -203,110 +203,32 @@ static void __devexit orinoco_tmd_remove
{
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = dev->priv;
-
- BUG_ON(! dev);
+ struct orinoco_pci_card *card = priv->card;
unregister_netdev(dev);
free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
pci_iounmap(pdev, priv->hw.iobase);
+ pci_iounmap(pdev, card->bridge_io);
pci_release_regions(pdev);
- pci_disable_device(pdev);
-}
-
-static int orinoco_tmd_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- err = orinoco_lock(priv, &flags);
- if (err) {
- printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
- dev->name);
- return err;
- }
-
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: error %d bringing interface down "
- "for suspend\n", dev->name, err);
-
- netif_device_detach(dev);
-
- priv->hw_unavailable++;
-
- orinoco_unlock(priv, &flags);
-
- free_irq(pdev->irq, dev);
- pci_save_state(pdev);
pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int orinoco_tmd_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- pci_set_power_state(pdev, 0);
- pci_enable_device(pdev);
- pci_restore_state(pdev);
-
- err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
- dev->name, dev);
- if (err) {
- printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
- dev->name);
- pci_disable_device(pdev);
- return -EBUSY;
- }
-
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: error %d re-initializing firmware "
- "on resume\n", dev->name, err);
- return err;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- netif_device_attach(dev);
-
- priv->hw_unavailable--;
-
- if (priv->open && (! priv->hw_unavailable)) {
- err = __orinoco_up(dev);
- if (err)
- printk(KERN_ERR "%s: Error %d restarting card on resume\n",
- dev->name, err);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
}
-static struct pci_device_id orinoco_tmd_pci_id_table[] = {
+static struct pci_device_id orinoco_tmd_id_table[] = {
{0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */
{0,},
};
-MODULE_DEVICE_TABLE(pci, orinoco_tmd_pci_id_table);
+MODULE_DEVICE_TABLE(pci, orinoco_tmd_id_table);
static struct pci_driver orinoco_tmd_driver = {
.name = DRIVER_NAME,
- .id_table = orinoco_tmd_pci_id_table,
+ .id_table = orinoco_tmd_id_table,
.probe = orinoco_tmd_init_one,
.remove = __devexit_p(orinoco_tmd_remove_one),
- .suspend = orinoco_tmd_suspend,
- .resume = orinoco_tmd_resume,
+ .suspend = orinoco_pci_suspend,
+ .resume = orinoco_pci_resume,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
@@ -324,7 +246,6 @@ static int __init orinoco_tmd_init(void)
static void __exit orinoco_tmd_exit(void)
{
pci_unregister_driver(&orinoco_tmd_driver);
- ssleep(1);
}
module_init(orinoco_tmd_init);
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 20/21] orinoco: further comment cleanup in the PCI drivers
From: Pavel Roskin @ 2006-04-07 8:11 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco_nortel.c | 7 +--
drivers/net/wireless/orinoco_pci.c | 69 +++++----------------------------
drivers/net/wireless/orinoco_plx.c | 42 +++-----------------
drivers/net/wireless/orinoco_tmd.c | 16 +-------
4 files changed, 22 insertions(+), 112 deletions(-)
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index deb22fb..1596182 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -3,7 +3,6 @@
* Driver for Prism II devices which would usually be driven by orinoco_cs,
* but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in
* Nortel emobility, Symbol LA-4113 and Symbol LA-4123.
- * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter.
*
* Copyright (C) 2002 Tobias Hoffmann
* (C) 2003 Christoph Jungegger <disdos-Bv35esvkf38b1SvskN2V4Q@public.gmane.org>
@@ -57,7 +56,7 @@ #define COR_VALUE (COR_LEVEL_REQ | C
/*
- * Do a soft reset of the PCI card using the Configuration Option Register
+ * Do a soft reset of the card using the Configuration Option Register
* We need this to get going...
* This is the part of the code that is strongly inspired from wlan-ng
*
@@ -68,7 +67,7 @@ static int orinoco_nortel_cor_reset(stru
{
struct orinoco_pci_card *card = priv->card;
- /* Assert the reset until the card notice */
+ /* Assert the reset until the card notices */
iowrite16(8, card->bridge_io + 2);
ioread16(card->attr_io + COR_OFFSET);
iowrite16(0x80, card->attr_io + COR_OFFSET);
@@ -126,7 +125,7 @@ static int orinoco_nortel_hw_init(struct
return -EBUSY;
}
- /* Set the PCMCIA COR-Register */
+ /* Set the PCMCIA COR register */
iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
mdelay(1);
reg = ioread16(card->attr_io + COR_OFFSET);
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 41efac2..df37b95 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -1,11 +1,11 @@
/* orinoco_pci.c
*
- * Driver for Prism II devices that have a direct PCI interface
- * (i.e., not in a Pcmcia or PLX bridge)
- *
- * Specifically here we're talking about the Linksys WMP11
+ * Driver for Prism 2.5/3 devices that have a direct PCI interface
+ * (i.e. these are not PCMCIA cards in a PCMCIA-to-PCI bridge).
+ * The card contains only one PCI region, which contains all the usual
+ * hermes registers, as well as the COR register.
*
- * Current maintainers (as of 29 September 2003) are:
+ * Current maintainers are:
* Pavel Roskin <proski AT gnu.org>
* and David Gibson <hermes AT gibson.dropbear.id.au>
*
@@ -39,54 +39,6 @@
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
- */
-
-/*
- * Theory of operation...
- * -------------------
- * Maybe you had a look in orinoco_plx. Well, this is totally different...
- *
- * The card contains only one PCI region, which contains all the usual
- * hermes registers.
- *
- * The driver will memory map this region in normal memory. Because
- * the hermes registers are mapped in normal memory and not in ISA I/O
- * post space, we can't use the usual inw/outw macros and we need to
- * use readw/writew.
- * This slight difference force us to compile our own version of
- * hermes.c with the register access macro changed. That's a bit
- * hackish but works fine.
- *
- * Note that the PCI region is pretty big (4K). That's much more than
- * the usual set of hermes register (0x0 -> 0x3E). I've got a strong
- * suspicion that the whole memory space of the adapter is in fact in
- * this region. Accessing directly the adapter memory instead of going
- * through the usual register would speed up significantely the
- * operations...
- *
- * Finally, the card looks like this :
------------------------
- Bus 0, device 14, function 0:
- Network controller: PCI device 1260:3873 (Harris Semiconductor) (rev 1).
- IRQ 11.
- Master Capable. Latency=248.
- Prefetchable 32 bit memory at 0xffbcc000 [0xffbccfff].
------------------------
-00:0e.0 Network controller: Harris Semiconductor: Unknown device 3873 (rev 01)
- Subsystem: Unknown device 1737:3874
- Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
- Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
- Latency: 248 set, cache line size 08
- Interrupt: pin A routed to IRQ 11
- Region 0: Memory at ffbcc000 (32-bit, prefetchable) [size=4K]
- Capabilities: [dc] Power Management version 2
- Flags: PMEClk- AuxPwr- DSI- D1+ D2+ PME+
- Status: D0 PME-Enable- DSel=0 DScale=0 PME-
------------------------
- *
- * That's all..
- *
- * Jean II
*/
#define DRIVER_NAME "orinoco_pci"
@@ -102,11 +54,12 @@ #include <linux/pci.h>
#include "orinoco.h"
#include "orinoco_pci.h"
-/* All the magic there is from wlan-ng */
-/* Magic offset of the reset register of the PCI card */
+/* Offset of the COR register of the PCI card */
#define HERMES_PCI_COR (0x26)
-/* Magic bitmask to reset the card */
+
+/* Bitmask to reset the card */
#define HERMES_PCI_COR_MASK (0x0080)
+
/* Magic timeouts for doing the reset.
* Those times are straight from wlan-ng, and it is claimed that they
* are necessary. Alan will kill me. Take your time and grab a coffee. */
@@ -115,7 +68,7 @@ #define HERMES_PCI_COR_OFFT (500) /* ms
#define HERMES_PCI_COR_BUSYT (500) /* ms */
/*
- * Do a soft reset of the PCI card using the Configuration Option Register
+ * Do a soft reset of the card using the Configuration Option Register
* We need this to get going...
* This is the part of the code that is strongly inspired from wlan-ng
*
@@ -133,7 +86,7 @@ static int orinoco_pci_cor_reset(struct
unsigned long timeout;
u16 reg;
- /* Assert the reset until the card notice */
+ /* Assert the reset until the card notices */
hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
mdelay(HERMES_PCI_COR_ONT);
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index c00388e..7b94050 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -3,7 +3,7 @@
* Driver for Prism II devices which would usually be driven by orinoco_cs,
* but are connected to the PCI bus by a PLX9052.
*
- * Current maintainers (as of 29 September 2003) are:
+ * Current maintainers are:
* Pavel Roskin <proski AT gnu.org>
* and David Gibson <hermes AT gibson.dropbear.id.au>
*
@@ -30,38 +30,18 @@
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
-
- * Caution: this is experimental and probably buggy. For success and
- * failure reports for different cards and adaptors, see
- * orinoco_plx_id_table near the end of the file. If you have a
- * card we don't have the PCI id for, and looks like it should work,
- * drop me mail with the id and "it works"/"it doesn't work".
- *
- * Note: if everything gets detected fine but it doesn't actually send
- * or receive packets, your first port of call should probably be to
- * try newer firmware in the card. Especially if you're doing Ad-Hoc
- * modes.
- *
- * The actual driving is done by orinoco.c, this is just resource
- * allocation stuff. The explanation below is courtesy of Ryan Niemi
- * on the linux-wlan-ng list at
- * http://archives.neohapsis.com/archives/dev/linux-wlan/2001-q1/0026.html
*
- * The PLX9052-based cards (WL11000 and several others) are a
- * different beast than the usual PCMCIA-based PRISM2 configuration
- * expected by wlan-ng. Here's the general details on how the WL11000
- * PCI adapter works:
+ * Here's the general details on how the PLX9052 adapter works:
*
* - Two PCI I/O address spaces, one 0x80 long which contains the
* PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA
* slot I/O address space.
*
- * - One PCI memory address space, mapped to the PCMCIA memory space
+ * - One PCI memory address space, mapped to the PCMCIA attribute space
* (containing the CIS).
*
- * After identifying the I/O and memory space, you can read through
- * the memory space to confirm the CIS's device ID or manufacturer ID
- * to make sure it's the expected card. qKeep in mind that the PCMCIA
+ * Using the later, you can read through the CIS data to make sure the
+ * card is compatible with the driver. Keep in mind that the PCMCIA
* spec specifies the CIS as the lower 8 bits of each word read from
* the CIS, so to read the bytes of the CIS, read every other byte
* (0,2,4,...). Passing that test, you need to enable the I/O address
@@ -71,7 +51,7 @@
* within the PCI memory space. Write 0x41 to the COR register to
* enable I/O mode and to select level triggered interrupts. To
* confirm you actually succeeded, read the COR register back and make
- * sure it actually got set to 0x41, incase you have an unexpected
+ * sure it actually got set to 0x41, in case you have an unexpected
* card inserted.
*
* Following that, you can treat the second PCI I/O address space (the
@@ -101,16 +81,6 @@
* that, I've hot-swapped a number of times during debugging and
* driver development for various reasons (stuck WAIT# line after the
* radio card's firmware locks up).
- *
- * Hope this is enough info for someone to add PLX9052 support to the
- * wlan-ng card. In the case of the WL11000, the PCI ID's are
- * 0x1639/0x0200, with matching subsystem ID's. Other PLX9052-based
- * manufacturers other than Eumitcom (or on cards other than the
- * WL11000) may have different PCI ID's.
- *
- * If anyone needs any more specific info, let me know. I haven't had
- * time to implement support myself yet, and with the way things are
- * going, might not have time for a while..
*/
#define DRIVER_NAME "orinoco_plx"
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index 438fe54..0496663 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -26,25 +26,13 @@
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
-
- * Caution: this is experimental and probably buggy. For success and
- * failure reports for different cards and adaptors, see
- * orinoco_tmd_id_table near the end of the file. If you have a
- * card we don't have the PCI id for, and looks like it should work,
- * drop me mail with the id and "it works"/"it doesn't work".
- *
- * Note: if everything gets detected fine but it doesn't actually send
- * or receive packets, your first port of call should probably be to
- * try newer firmware in the card. Especially if you're doing Ad-Hoc
- * modes.
*
* The actual driving is done by orinoco.c, this is just resource
* allocation stuff.
*
* This driver is modeled after the orinoco_plx driver. The main
- * difference is that the TMD chip has only IO port ranges and no
- * memory space, i.e. no access to the CIS. Compared to the PLX chip,
- * the io range functionalities are exchanged.
+ * difference is that the TMD chip has only IO port ranges and doesn't
+ * provide access to the PCMCIA attribute space.
*
* Pheecom sells cards with the TMD chip as "ASIC version"
*/
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* [PATCH 21/21] orinoco: bump version to 0.15
From: Pavel Roskin @ 2006-04-07 8:11 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: orinoco-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060407081019.16107.67672.stgit-fdEtzkpK75rby3iVrkZq2A@public.gmane.org>
From: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
---
drivers/net/wireless/orinoco.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index ca01e45..16db3e1 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -7,7 +7,7 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H
-#define DRIVER_VERSION "0.15rc3"
+#define DRIVER_VERSION "0.15"
#include <linux/netdevice.h>
#include <linux/wireless.h>
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply related
* Re: Problem of "JFFS2 summary"
From: Sascha Hauer @ 2006-04-07 8:12 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-mtd
In-Reply-To: <200604070828.33546.h.schurig@mn-solutions.de>
On Fri, Apr 07, 2006 at 08:28:33AM +0200, Holger Schurig wrote:
> > jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at
> > 0x00080000: 0x00b0 instead jffs2_scan_eraseblock(): Magic bitmask
> > 0x1985 not found at 0x00080004: 0x00b0 instead
>
> I got similar problems with stock kernel 2.6.16.1 and sumtool from
> mtd-utils, CVSDATE 2006-02-23.
>
> After this, I thought "nice idea", recompiled my kernel without
> CONFIG_JFFS2_SUMMARY and flashed the normal jffs2 image to get a
> working system.
Just for the sake of completeness: I too tried it yesterday with
2.6.16-git and sumtool from mtd cvs and got the same errors.
Continued to work without summary support then.
Sascha
^ permalink raw reply
* Re: [2.6.16 PATCH] Filessytem Events Reporter V2
From: Yi Yang @ 2006-04-07 8:13 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: LKML, Andrew Morton, Matt Helsley
In-Reply-To: <20060407062428.GA31351@2ka.mipt.ru>
Evgeniy Polyakov wrote:
> On Wed, Apr 05, 2006 at 09:21:26PM +0800, Yi Yang (yang.y.yi@gmail.com) wrote:
>
>> Compared with Filesystem Events Reporter v1, the following changes are done:
>> - Use workqueue/keventd instead of kfseventd.
>> - fsevent_mask can be set by sysctl and proc
>> interface.
>> - Add missed spinlock
>> - Ensure fsevent sequence number is uniqe
>>
>> This patch implements a filsystem events report facitily, Filesystem Events
>> Reporter, the user can monitor filesystem activities via it, currently, it
>> can monitor access, attribute change, open, create, modify, delete,
>> move and close of any file or directory as well as mount/umount.
>>
>
> Comments below.
>
> ...
>
>> +
>> +static int fsevent_ack(enum fsevent_type type, pid_t pid, u32 seq)
>> +{
>> + struct fsevent *event;
>> + unsigned int size;
>> + struct sk_buff * skb = NULL;
>> + struct nlmsghdr * nlhdr = NULL;
>> +
>> + size = NLMSG_SPACE(sizeof(struct fsevent));
>> +
>> + skb = alloc_skb(size, GFP_KERNEL);
>> + if (!skb)
>> + return -ENOMEM;
>> +
>> + nlhdr = NLMSG_PUT(skb, 0, seq, NLMSG_DONE, size - sizeof(*nlhdr));
>> + event = NLMSG_DATA(nlhdr);
>> +
>> + ktime_get_ts(&event->timestamp);
>> + event->cpu = -1;
>> + event->type = type;
>> + event->pid = 0;
>> + event->uid = 0;
>> + event->gid = 0;
>> + event->len = 0;
>> + event->pname_len = 0;
>> + event->fname_len = 0;
>> + event->new_fname_len = 0;
>> + event->err = 0;
>> +
>> + NETLINK_CB(skb).dst_group = 0;
>> + NETLINK_CB(skb).dst_pid = pid;
>> + NETLINK_CB(skb).pid = 0;
>> +
>> + return (netlink_unicast(fsevent_sock, skb, pid, MSG_DONTWAIT));
>>
>
> netlink_unicast() uses boolean value but ont MSG_* flags for nonblocking,
> so this should be netlink_unicast(fsevent_sock, skb, pid, 0);
>
a example invocation in file net/netlink/af_netlink.c:
netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
so, it hasn't any problem.
>
>> +nlmsg_failure:
>> + kfree_skb(skb);
>> + return -1;
>> +}
>>
>
> ...
>
>
>> +static void fsevent_recv(struct sock *sk, int len)
>> +{
>> + struct sk_buff *skb = NULL;
>> + struct nlmsghdr *nlhdr = NULL;
>> + struct fsevent_filter * filter = NULL;
>> + pid_t pid;
>> +
>> + while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
>> + skb_get(skb);
>> + if (skb->len >= FSEVENT_FILTER_MSGSIZE) {
>> + nlhdr = (struct nlmsghdr *)skb->data;
>> + filter = NLMSG_DATA(nlhdr);
>> + pid = NETLINK_CREDS(skb)->pid;
>> + if (find_fsevent_listener(pid) == NULL)
>> + atomic_inc(&fsevent_listener_num);
>> + set_fsevent_filter(filter, pid);
>>
>
> What is the logic behind this steps?
> If there are no listeners you increment it's number no matter if it will
> or not be added in set_fsevent_filter().
>
fsevent_recv is used to receive listener's commands, a listener must
send commands in order to get fsevents it
interests, so this is the best point to increment number of listeners.
set_fsevent_filter will add listener to listener
list, so it is OK.
>
>> + }
>> + kfree_skb(skb);
>> + }
>> +}
>> +
>> +#define DEFINE_FILTER_MATCH_FUNC(filtertype, key) \
>> + static int match_##filtertype(listener * p, \
>> + struct fsevent * event, \
>> + struct sk_buff * skb) \
>> + { \
>> + int ret = 0; \
>> + filtertype * xfilter = NULL; \
>> + struct sk_buff * skb2 = NULL; \
>> + struct list_head * head = &(p->key##_filter_list_head); \
>> + list_for_each_entry(xfilter, head, list) { \
>> + if (xfilter->key != event->key) \
>> + continue; \
>> + ret = filter_fsevent(xfilter->mask, event->type); \
>> + if ( ret != 0) \
>> + return -1; \
>> + skb2 = skb_clone(skb, GFP_KERNEL); \
>> + if (skb2 == NULL) \
>> + return -ENOMEM; \
>> + NETLINK_CB(skb2).dst_group = 0; \
>> + NETLINK_CB(skb2).dst_pid = p->pid; \
>> + NETLINK_CB(skb2).pid = 0; \
>> + return (netlink_unicast(fsevent_sock, skb2, \
>> + p->pid, MSG_DONTWAIT)); \
>>
>
> The same issue about nonblocking sending.
>
>
>> + } \
>> + return -ENODEV; \
>> + } \
>> +
>> +DEFINE_FILTER_MATCH_FUNC(pid_filter, pid)
>> +
>> +DEFINE_FILTER_MATCH_FUNC(uid_filter, uid)
>> +
>> +DEFINE_FILTER_MATCH_FUNC(gid_filter, gid)
>> +
>> +#define MATCH_XID(key, listenerp, event, skb) \
>> + ret = match_##key##_filter(listenerp, event, skb); \
>> + if (ret == 0) { \
>> + kfree_skb(skb); \
>> + continue; \
>> + } \
>> + do {} while (0) \
>> +
>> +static int fsevent_send_to_process(struct sk_buff * skb)
>> +{
>> + listener * p = NULL, * q = NULL;
>> + struct fsevent * event = NULL;
>> + struct sk_buff * skb2 = NULL;
>> + int ret = 0;
>> +
>> + event = (struct fsevent *)(skb->data + sizeof(struct nlmsghdr));
>> + spin_lock(&listener_list_lock);
>> + list_for_each_entry_safe(p, q, &listener_list_head, list) {
>> + MATCH_XID(pid, p, event, skb);
>> + MATCH_XID(uid, p, event, skb);
>> + MATCH_XID(gid, p, event, skb);
>> +
>> + if (filter_fsevent(p->mask, event->type) == 0) {
>> + skb2 = skb_clone(skb, GFP_KERNEL);
>> + if (skb2 == NULL)
>> + return -ENOMEM;
>> + NETLINK_CB(skb2).dst_group = 0;
>> + NETLINK_CB(skb2).dst_pid = p->pid;
>> + NETLINK_CB(skb2).pid = 0;
>> + ret = netlink_unicast(fsevent_sock, skb2,
>> + p->pid, MSG_DONTWAIT);
>> + if (ret == -ECONNREFUSED) {
>> + atomic_dec(&fsevent_listener_num);
>> + cleanup_dead_listener(p);
>> + }
>> + }
>> + }
>> + spin_unlock(&listener_list_lock);
>> + return ret;
>> +}
>> +
>> +static void fsevent_commit(void * unused)
>> +{
>> + struct sk_buff * skb = NULL;
>> +
>> + while((skb = skb_dequeue(&get_cpu_var(fsevent_send_queue)))
>> + != NULL) {
>> + fsevent_send_to_process(skb);
>> + put_cpu_var(fsevent_send_queue);
>> + }
>> +}
>>
>
> Really strange mix of per-cpu variables for optimized performance and
> global spin locking.
> Consider using RCU for list of listeners.
>
per cpu queue is used to avoid raise_fsevent to contend spinlock, but
listener_list_lock just is used
to synchronize the operations of userspace applications(listener) on
listener list, it just protect listener
list.
Of course, your advice is good, RCU will be better, I'm considering
substitute spinlock with RCU,
maybe list*_rcu functions can help me.
> You use unicast delivery for netlink messages.
> According to my investigation [1], it's performance is better only when
> there is only one listener (or maybe two in some cases), but then it is
> noticebly slower than broadcasting.
>
> 1. http://marc.theaimsgroup.com/?l=linux-netdev&m=114424884216006&w=2
>
Because fsevent has to deliver different events to different listeners,
so I must use netlink_unicast,
in fact, netlink_broadcast also must send skb to every member of the
group, so in my opinion,
they haven't big difference.
Can you explain why there is such a big difference between
netlink_unicast and netlink_broadcast?
>
>> +static struct ctl_table fsevent_mask_sysctl[] = {
>> + {
>> + .ctl_name = FSEVENT_MASK_CTL_NAME,
>> + .procname = "fsevent_mask",
>> + .data = &fsevents_mask,
>> + .maxlen = sizeof(u32),
>> + .mode = 0644,
>> + .proc_handler = &proc_dointvec,
>> + },
>> + { .ctl_name = 0 }
>> +};
>> +
>> +static struct ctl_table fs_root_sysctl[] = {
>> + {
>> + .ctl_name = CTL_FS,
>> + .procname = "fs",
>> + .mode = 0555,
>> + .child = fsevent_mask_sysctl,
>> + },
>> + { .ctl_name = 0 }
>> +};
>> +
>> +static int __init fsevent_init(void)
>> +{
>> + int cpu;
>> + struct sk_buff_head * listptr;
>> + struct work_struct * workptr;
>> +
>> + fsevent_sock = netlink_kernel_create(NETLINK_FSEVENT, 0,
>> + fsevent_recv, THIS_MODULE);
>> + if (!fsevent_sock)
>> + return -EIO;
>> + for_each_cpu(cpu) {
>> + listptr = &per_cpu(fsevent_send_queue, cpu);
>> + skb_queue_head_init(listptr);
>> + workptr = &per_cpu(fsevent_work, cpu);
>> + INIT_WORK(workptr, fsevent_commit, NULL);
>> + }
>>
>
> Btw, you need some rebalancing of the per-cpu queues, probably in
> keventd, since CPUs can go offline and your messages will stuck foreve
> there.
>
Does keventd not do it? if so, keventd should be modified.
>
>> + if (register_sysctl_table(fs_root_sysctl, 0) == NULL)
>> + return -ENOMEM;
>> +
>> + return 0;
>> +}
>> +
>> +static void __exit fsevent_exit(void)
>> +{
>> + listener * p = NULL, * q = NULL;
>> + sock_release(fsevent_sock->sk_socket);
>> + spin_lock(&listener_list_lock);
>> + list_for_each_entry_safe(p, q, &listener_list_head, list) {
>> + cleanup_dead_listener(p);
>> + }
>> + spin_unlock(&listener_list_lock);
>>
>
> Broken. Your work can be pending on this stage, but you already removed
> and freed resources.
>
Sorry, I don't consider it, I will add it, thank you very much.
>
>> +}
>> +
>> +module_init(fsevent_init);
>> +module_exit(fsevent_exit);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Yi Yang <yang.y.yi@gmail.com>");
>> +MODULE_DESCRIPTION("File System Events Reporter");
>>
>>
>
>
^ permalink raw reply
* [patch] ipv4: initialize arp_tbl rw lock
From: Heiko Carstens @ 2006-04-07 8:15 UTC (permalink / raw)
To: Jeff Garzik, Andrew Morton; +Cc: netdev, linux-kernel, Frank Pavlic
From: Heiko Carstens <heiko.carstens@de.ibm.com>
The qeth driver makes use of the arp_tbl rw lock. CONFIG_DEBUG_SPINLOCK
detects that this lock is not initialized as it is supposed to be.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
net/ipv4/arp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 041dadd..ea54216 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -202,6 +202,7 @@ struct neigh_table arp_tbl = {
.gc_thresh1 = 128,
.gc_thresh2 = 512,
.gc_thresh3 = 1024,
+ .lock = RW_LOCK_UNLOCKED,
};
int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir)
^ permalink raw reply related
* Re: [BUG ALSA 2.6.17-rc1] Oops when Gaim tries to play sound
From: Erik Mouw @ 2006-04-07 8:15 UTC (permalink / raw)
To: Lee Revell; +Cc: linux-kernel, alsa-devel
In-Reply-To: <1144338706.2866.62.camel@mindpipe>
On Thu, Apr 06, 2006 at 11:51:45AM -0400, Lee Revell wrote:
> On Thu, 2006-04-06 at 15:20 +0200, Erik Mouw wrote:
> > Could be a locking error or an ALSA error, so message posted to lkml
> > and alsa-devel lists. Feel free to ask for more information.
>
> Already reported (several times) to both LKML and alsa-devel.
>
> See kernel bugzilla #6329
Rene Herman pointed it out in private. I applied
http://bugzilla.kernel.org/attachment.cgi?id=7779&action=view and
everything seems to work again.
Erik
--
+-- Erik Mouw -- www.harddisk-recovery.com -- +31 70 370 12 90 --
| Lab address: Delftechpark 26, 2628 XH, Delft, The Netherlands
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply
* Re: [Alsa-devel] [BUG ALSA 2.6.17-rc1] Oops when Gaim tries to play sound
From: Erik Mouw @ 2006-04-07 8:15 UTC (permalink / raw)
To: Lee Revell; +Cc: linux-kernel, alsa-devel
In-Reply-To: <1144338706.2866.62.camel@mindpipe>
On Thu, Apr 06, 2006 at 11:51:45AM -0400, Lee Revell wrote:
> On Thu, 2006-04-06 at 15:20 +0200, Erik Mouw wrote:
> > Could be a locking error or an ALSA error, so message posted to lkml
> > and alsa-devel lists. Feel free to ask for more information.
>
> Already reported (several times) to both LKML and alsa-devel.
>
> See kernel bugzilla #6329
Rene Herman pointed it out in private. I applied
http://bugzilla.kernel.org/attachment.cgi?id=7779&action=view and
everything seems to work again.
Erik
--
+-- Erik Mouw -- www.harddisk-recovery.com -- +31 70 370 12 90 --
| Lab address: Delftechpark 26, 2628 XH, Delft, The Netherlands
^ permalink raw reply
* Re: Cygwin can't handle huge packfiles?
From: Junio C Hamano @ 2006-04-07 8:15 UTC (permalink / raw)
To: git; +Cc: Kees-Jan Dijkzeul, Linus Torvalds
In-Reply-To: <Pine.LNX.4.64.0604030734440.3781@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> On Mon, 3 Apr 2006, Linus Torvalds wrote:
>>
>> That said, I think git _does_ have problems with large pack-files. We have
>> some 32-bit issues etc
>
> I should clarify that. git _itself_ shouldn't have any 32-bit issues, but
> the packfile data structure does. The index has 32-bit offsets into
> individual pack-files.
>
> That's not hugely fundamental,...
Linus _does_ understand what he means, but let me clarify and
outline a possible future direction.
* pack-*.pack file has the following format:
- The header appears at the beginning and consists of the following:
4-byte signature
4-byte version number (network byte order)
4-byte number of objects contained in the pack (network byte order)
Observation: we cannot have more than 4G versions ;-) and
more than 4G objects in a pack.
- The header is followed by number of object entries, each of
which looks like this:
(undeltified representation)
n-byte type and length (4-bit type, (n-1)*7+4-bit length)
compressed data
(deltified representation)
n-byte type and length (4-bit type, (n-1)*7+4-bit length)
20-byte base object name
compressed delta data
Observation: length of each object is encoded in a variable
length format and is not constrained to 32-bit or anything.
- The trailer records 20-byte SHA1 checksum of all of the above.
* pack-*.idx file has the following format:
- The header consists of 256 4-byte network byte order
integers. N-th entry of this table records the number of
objects in the corresponding pack, the first byte of whose
object name are smaller than N.
Observation: we would need to extend this to an array of
8-byte integers to go beyond 4G objects per pack, but it is
not strictly necessary.
- The header is followed by sorted 28-byte entries, one entry
per object in the pack. Each entry is:
4-byte network byte order integer, recording where the
object is stored in the packfile as the offset from the
beginning.
20-byte object name.
Observation: we would definitely need to extend this to
8-byte integer plus 20-byte object name to handle a packfile
that is larger than 4GB.
- The file is concluded with a trailer:
A copy of the 20-byte SHA1 checksum at the end of
corresponding packfile.
20-byte SHA1-checksum of all of the above.
This is not fundamental, in that pack idx file is something we
can regenerate from a packfile. The push/fetch transfer over
git native protocols does not even transfer pack idx file;
instead, the recipient uses git-index-pack to generate pack idx.
git-index-pack would need to be updated to update the necessary
fields to 8-byte integers, without breaking existing packfiles.
The code to read idx file currently has a sanity check logic to
make sure that the size of the idx file is consistent with
24-byte entries (the last entry in the header matches the number
of objects recorded in the pack). So we could reliably tell
between the current 24-byte version and 28-byte "beyond 4GB"
version, and support both formats at the same time.
Even after we start supporting the 28-byte "beyond 4GB" format,
we can and we should continue writing the current 24-byte
version of pack idx file when the packfile offset can be
expressed with 32-bit.
Having said that, I have to warn that this is not for weak of
heart. The necessary changes would be somewhat involved.
----------------------------------------------------------------
Pack idx file
idx
+--------------------------------+
| fanout[0] = 2 |-.
+--------------------------------+ |
| fanout[1] | |
+--------------------------------+ |
| fanout[2] | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| fanout[255] | |
+--------------------------------+ |
main | offset | |
index | object name 00XXXXXXXXXXXXXXXX | |
table +--------------------------------+ |
| offset | |
| object name 00XXXXXXXXXXXXXXXX | |
+--------------------------------+ |
.-| offset |<+
| | object name 01XXXXXXXXXXXXXXXX |
| +--------------------------------+
| | offset |
| | object name 01XXXXXXXXXXXXXXXX |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | offset |
| | object name FFXXXXXXXXXXXXXXXX |
| +--------------------------------+
trailer | | packfile checksum |
| +--------------------------------+
| | idxfile checksum |
| +--------------------------------+
.-------.
|
Pack file entry: <+
packed object header:
1-byte type (bit 4-6)
size0 (bit 0-3)
end-of-length (bit 7)
n-byte sizeN (as long as MSB is set, each 7-bit)
size0..sizeN form 4+7+7+..+7 bit integer, size0
is the most significant part.
packed object data:
If it is not DELTA, then deflated bytes (the size above
is the size before compression).
If it is DELTA, then
20-byte base object name SHA1 (the size above is the
size of the delta data that follows).
delta data, deflated.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.