Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ac5ccb22
Commit
ac5ccb22
authored
Mar 28, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/jgarzik/irda-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
7b455189
887ac0a0
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
533 additions
and
427 deletions
+533
-427
drivers/net/irda/irda-usb.c
drivers/net/irda/irda-usb.c
+70
-61
drivers/net/irda/sir_dev.c
drivers/net/irda/sir_dev.c
+22
-17
include/net/irda/af_irda.h
include/net/irda/af_irda.h
+3
-3
include/net/irda/discovery.h
include/net/irda/discovery.h
+23
-14
include/net/irda/irlan_client.h
include/net/irda/irlan_client.h
+1
-1
include/net/irda/irlmp.h
include/net/irda/irlmp.h
+12
-10
net/irda/af_irda.c
net/irda/af_irda.c
+32
-34
net/irda/discovery.c
net/irda/discovery.c
+113
-69
net/irda/ircomm/ircomm_tty_attach.c
net/irda/ircomm/ircomm_tty_attach.c
+2
-2
net/irda/irlan/irlan_client.c
net/irda/irlan/irlan_client.c
+1
-1
net/irda/irlap_event.c
net/irda/irlap_event.c
+88
-15
net/irda/irlap_frame.c
net/irda/irlap_frame.c
+27
-26
net/irda/irlmp.c
net/irda/irlmp.c
+89
-127
net/irda/irnet/irnet.h
net/irda/irnet/irnet.h
+5
-0
net/irda/irnet/irnet_irda.c
net/irda/irnet/irnet_irda.c
+21
-25
net/irda/irnet/irnet_irda.h
net/irda/irnet/irnet_irda.h
+4
-3
net/irda/irnet/irnet_ppp.c
net/irda/irnet/irnet_ppp.c
+12
-10
net/irda/irnet/irnet_ppp.h
net/irda/irnet/irnet_ppp.h
+1
-0
net/irda/timer.c
net/irda/timer.c
+7
-9
No files found.
drivers/net/irda/irda-usb.c
View file @
ac5ccb22
...
...
@@ -402,7 +402,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
usb_fill_bulk_urb
(
urb
,
self
->
usbdev
,
usb_sndbulkpipe
(
self
->
usbdev
,
self
->
bulk_out_ep
),
skb
->
data
,
IRDA_
US
B_MAX_MTU
,
skb
->
data
,
IRDA_
SK
B_MAX_MTU
,
write_bulk_callback
,
skb
);
urb
->
transfer_buffer_length
=
skb
->
len
;
/* Note : unlink *must* be Asynchronous because of the code in
...
...
@@ -442,6 +442,9 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
* would be lost in the noise - Jean II */
diff
+=
IU_USB_MIN_RTT
;
#endif
/* IU_USB_MIN_RTT */
/* If the usec counter did wraparound, the diff will
* go negative (tv_usec is a long), so we need to
* correct it by one second. Jean II */
if
(
diff
<
0
)
diff
+=
1000000
;
...
...
@@ -701,30 +704,11 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc
IRDA_DEBUG
(
2
,
"%s()
\n
"
,
__FUNCTION__
);
/* Check that we have an urb */
if
(
!
urb
)
{
WARNING
(
"%s(), Bug : urb == NULL
\n
"
,
__FUNCTION__
);
return
;
}
/* This should never happen */
ASSERT
(
skb
!=
NULL
,
return
;);
ASSERT
(
urb
!=
NULL
,
return
;);
/* Allocate new skb if it has not been recycled */
if
(
!
skb
)
{
skb
=
dev_alloc_skb
(
IRDA_USB_MAX_MTU
+
1
);
if
(
!
skb
)
{
/* If this ever happen, we are in deep s***.
* Basically, the Rx path will stop... */
WARNING
(
"%s(), Failed to allocate Rx skb
\n
"
,
__FUNCTION__
);
return
;
}
}
else
{
/* Reset recycled skb */
skb
->
data
=
skb
->
tail
=
skb
->
head
;
skb
->
len
=
0
;
}
/* Make sure IP header get aligned (IrDA header is 5 bytes ) */
skb_reserve
(
skb
,
1
);
/* Save ourselves */
/* Save ourselves in the skb */
cb
=
(
struct
irda_skb_cb
*
)
skb
->
cb
;
cb
->
context
=
self
;
...
...
@@ -758,8 +742,10 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs)
struct
sk_buff
*
skb
=
(
struct
sk_buff
*
)
urb
->
context
;
struct
irda_usb_cb
*
self
;
struct
irda_skb_cb
*
cb
;
struct
sk_buff
*
new
;
struct
sk_buff
*
newskb
;
struct
sk_buff
*
dataskb
;
int
docopy
;
IRDA_DEBUG
(
2
,
"%s(), len=%d
\n
"
,
__FUNCTION__
,
urb
->
actual_length
);
/* Find ourselves */
...
...
@@ -808,39 +794,56 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs)
*/
do_gettimeofday
(
&
self
->
stamp
);
/* Fix skb, and remove USB-IrDA header */
skb_put
(
skb
,
urb
->
actual_length
);
skb_pull
(
skb
,
USB_IRDA_HEADER
);
/* Check if we need to copy the data to a new skb or not.
* For most frames, we use ZeroCopy and pass the already
* allocated skb up the stack.
* If the frame is small, it is more efficient to copy it
* to save memory (copy will be fast anyway - that's
* called Rx-copy-break). Jean II */
docopy
=
(
urb
->
actual_length
<
IRDA_RX_COPY_THRESHOLD
);
/* Allocate a new skb */
newskb
=
dev_alloc_skb
(
docopy
?
urb
->
actual_length
:
IRDA_SKB_MAX_MTU
);
if
(
!
newskb
)
{
self
->
stats
.
rx_dropped
++
;
/* We could deliver the current skb, but this would stall
* the Rx path. Better drop the packet... Jean II */
goto
done
;
}
/* Don't waste a lot of memory on small IrDA frames */
if
(
skb
->
len
<
RX_COPY_THRESHOLD
)
{
new
=
dev_alloc_skb
(
skb
->
len
+
1
);
if
(
!
new
)
{
self
->
stats
.
rx_dropped
++
;
goto
done
;
}
/* Make sure IP header get aligned (IrDA header is 5 bytes) */
/* But IrDA-USB header is 1 byte. Jean II */
//skb_reserve(newskb, USB_IRDA_HEADER - 1);
/* Make sure IP header get aligned (IrDA header is 5 bytes) */
skb_reserve
(
new
,
1
);
if
(
docopy
)
{
/* Copy packet, so we can recycle the original */
memcpy
(
skb_put
(
new
,
skb
->
len
),
skb
->
data
,
skb
->
len
);
/* We will cleanup the skb in irda_usb_submit() */
memcpy
(
newskb
->
data
,
skb
->
data
,
urb
->
actual_length
);
/* Deliver this new skb */
dataskb
=
newskb
;
/* And hook the old skb to the URB
* Note : we don't need to "clean up" the old skb,
* as we never touched it. Jean II */
}
else
{
/* Deliver the original skb */
new
=
skb
;
skb
=
NULL
;
/* We are using ZeroCopy. Deliver old skb */
dataskb
=
skb
;
/* And hook the new skb to the URB */
skb
=
newskb
;
}
self
->
stats
.
rx_bytes
+=
new
->
len
;
self
->
stats
.
rx_packets
++
;
/* Set proper length on skb & remove USB-IrDA header */
skb_put
(
dataskb
,
urb
->
actual_length
);
skb_pull
(
dataskb
,
USB_IRDA_HEADER
);
/* Ask the networking layer to queue the packet for the IrDA stack */
new
->
dev
=
self
->
netdev
;
new
->
mac
.
raw
=
new
->
data
;
new
->
protocol
=
htons
(
ETH_P_IRDA
);
netif_rx
(
new
);
self
->
netdev
->
last_rx
=
jiffies
;
dataskb
->
dev
=
self
->
netdev
;
dataskb
->
mac
.
raw
=
dataskb
->
data
;
dataskb
->
protocol
=
htons
(
ETH_P_IRDA
);
netif_rx
(
dataskb
);
/* Keep stats up to date */
self
->
stats
.
rx_bytes
+=
dataskb
->
len
;
self
->
stats
.
rx_packets
++
;
self
->
netdev
->
last_rx
=
jiffies
;
done:
/* Note : at this point, the URB we've just received (urb)
...
...
@@ -973,8 +976,17 @@ static int irda_usb_net_open(struct net_device *netdev)
/* Now that we can pass data to IrLAP, allow the USB layer
* to send us some data... */
for
(
i
=
0
;
i
<
IU_MAX_ACTIVE_RX_URBS
;
i
++
)
irda_usb_submit
(
self
,
NULL
,
self
->
rx_urb
[
i
]);
for
(
i
=
0
;
i
<
IU_MAX_ACTIVE_RX_URBS
;
i
++
)
{
struct
sk_buff
*
skb
=
dev_alloc_skb
(
IRDA_SKB_MAX_MTU
);
if
(
!
skb
)
{
/* If this ever happen, we are in deep s***.
* Basically, we can't start the Rx path... */
WARNING
(
"%s(), Failed to allocate Rx skb
\n
"
,
__FUNCTION__
);
return
-
1
;
}
//skb_reserve(newskb, USB_IRDA_HEADER - 1);
irda_usb_submit
(
self
,
skb
,
self
->
rx_urb
[
i
]);
}
/* Ready to play !!! */
return
0
;
...
...
@@ -1167,9 +1179,6 @@ static inline int irda_usb_open(struct irda_usb_cb *self)
spin_lock_init
(
&
self
->
lock
);
irda_usb_init_qos
(
self
);
/* Initialise list of skb beeing curently transmitted */
self
->
tx_list
=
hashbin_new
(
HB_NOLOCK
);
/* unused */
/* Allocate the buffer for speed changes */
/* Don't change this buffer size and allocation without doing
...
...
@@ -1228,8 +1237,6 @@ static inline int irda_usb_close(struct irda_usb_cb *self)
self
->
netdev
=
NULL
;
rtnl_unlock
();
}
/* Delete all pending skbs */
hashbin_delete
(
self
->
tx_list
,
(
FREE_FUNC
)
&
dev_kfree_skb_any
);
/* Remove the speed buffer */
if
(
self
->
speed_buff
!=
NULL
)
{
kfree
(
self
->
speed_buff
);
...
...
@@ -1492,8 +1499,10 @@ static int irda_usb_probe(struct usb_interface *intf,
case
0
:
break
;
case
-
EPIPE
:
/* -EPIPE = -32 */
usb_clear_halt
(
dev
,
usb_sndctrlpipe
(
dev
,
0
));
IRDA_DEBUG
(
0
,
"%s(), Clearing stall on control interface
\n
"
,
__FUNCTION__
);
/* Martin Diehl says if we get a -EPIPE we should
* be fine and we don't need to do a usb_clear_halt().
* - Jean II */
IRDA_DEBUG
(
0
,
"%s(), Received -EPIPE, ignoring...
\n
"
,
__FUNCTION__
);
break
;
default:
IRDA_DEBUG
(
0
,
"%s(), Unknown error %d
\n
"
,
__FUNCTION__
,
ret
);
...
...
drivers/net/irda/sir_dev.c
View file @
ac5ccb22
...
...
@@ -223,25 +223,24 @@ int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count)
}
/* Read the characters into the buffer */
while
(
count
--
)
{
if
(
likely
(
atomic_read
(
&
dev
->
enable_rx
)))
{
if
(
likely
(
atomic_read
(
&
dev
->
enable_rx
))
)
{
while
(
count
--
)
/* Unwrap and destuff one byte */
async_unwrap_char
(
dev
->
netdev
,
&
dev
->
stats
,
&
dev
->
rx_buff
,
*
cp
++
);
}
else
{
&
dev
->
rx_buff
,
*
cp
++
);
}
else
{
while
(
count
--
)
{
/* rx not enabled: save the raw bytes and never
* trigger any netif_rx. The received bytes are flushed
* later when we re-enable rx but might be read meanwhile
* by the dongle driver.
*/
dev
->
rx_buff
.
data
[
dev
->
rx_buff
.
len
++
]
=
*
cp
++
;
}
/* What should we do when the buffer is full? */
if
(
unlikely
(
dev
->
rx_buff
.
len
==
dev
->
rx_buff
.
truesize
))
dev
->
rx_buff
.
len
=
0
;
/* What should we do when the buffer is full? */
if
(
unlikely
(
dev
->
rx_buff
.
len
==
dev
->
rx_buff
.
truesize
))
dev
->
rx_buff
.
len
=
0
;
}
}
return
0
;
...
...
@@ -423,19 +422,24 @@ static int sirdev_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
static
int
sirdev_alloc_buffers
(
struct
sir_dev
*
dev
)
{
dev
->
rx_buff
.
truesize
=
SIRBUF_ALLOCSIZE
;
dev
->
tx_buff
.
truesize
=
SIRBUF_ALLOCSIZE
;
dev
->
rx_buff
.
truesize
=
IRDA_SKB_MAX_MTU
;
dev
->
rx_buff
.
head
=
kmalloc
(
dev
->
rx_buff
.
truesize
,
GFP_KERNEL
);
if
(
dev
->
rx_buff
.
head
==
NULL
)
/* Bootstrap ZeroCopy Rx */
dev
->
rx_buff
.
skb
=
__dev_alloc_skb
(
dev
->
rx_buff
.
truesize
,
GFP_KERNEL
);
if
(
dev
->
rx_buff
.
skb
==
NULL
)
return
-
ENOMEM
;
memset
(
dev
->
rx_buff
.
head
,
0
,
dev
->
rx_buff
.
truesize
);
skb_reserve
(
dev
->
rx_buff
.
skb
,
1
);
dev
->
rx_buff
.
head
=
dev
->
rx_buff
.
skb
->
data
;
/* No need to memset the buffer, unless you are really pedantic */
dev
->
tx_buff
.
head
=
kmalloc
(
dev
->
tx_buff
.
truesize
,
GFP_KERNEL
);
if
(
dev
->
tx_buff
.
head
==
NULL
)
{
kfree
(
dev
->
rx_buff
.
head
);
kfree_skb
(
dev
->
rx_buff
.
skb
);
dev
->
rx_buff
.
skb
=
NULL
;
dev
->
rx_buff
.
head
=
NULL
;
return
-
ENOMEM
;
/* Hu ??? This should not be here, Martin ? */
memset
(
dev
->
tx_buff
.
head
,
0
,
dev
->
tx_buff
.
truesize
);
}
...
...
@@ -451,11 +455,12 @@ static int sirdev_alloc_buffers(struct sir_dev *dev)
static
void
sirdev_free_buffers
(
struct
sir_dev
*
dev
)
{
if
(
dev
->
rx_buff
.
head
)
kfree
(
dev
->
rx_buff
.
head
);
if
(
dev
->
rx_buff
.
skb
)
kfree
_skb
(
dev
->
rx_buff
.
skb
);
if
(
dev
->
tx_buff
.
head
)
kfree
(
dev
->
tx_buff
.
head
);
dev
->
rx_buff
.
head
=
dev
->
tx_buff
.
head
=
NULL
;
dev
->
rx_buff
.
skb
=
NULL
;
}
static
int
sirdev_open
(
struct
net_device
*
ndev
)
...
...
include/net/irda/af_irda.h
View file @
ac5ccb22
...
...
@@ -52,8 +52,8 @@ struct irda_sock {
__u8
max_header_size
;
struct
qos_info
qos_tx
;
__u16
mask
;
/* Hint bits mask */
__u16
hints
;
/* Hint bits */
__u16
_host_order
mask
;
/* Hint bits mask */
__u16
_host_order
hints
;
/* Hint bits */
void
*
ckey
;
/* IrLMP client handle */
void
*
skey
;
/* IrLMP service handle */
...
...
@@ -63,7 +63,7 @@ struct irda_sock {
struct
ias_value
*
ias_result
;
/* Result of remote IAS query */
hashbin_t
*
cachelog
;
/* Result of discovery query */
struct
discovery_t
*
cachediscovery
;
/* Result of selective discovery query */
__u32
cachedaddr
;
/* Result of selective discovery query */
int
nslots
;
/* Number of slots to use for discovery */
...
...
include/net/irda/discovery.h
View file @
ac5ccb22
...
...
@@ -46,12 +46,20 @@
* little endian format. A little endian machine stores MSB of word in
* byte[1] and LSB in byte[0]. A big endian machine stores MSB in byte[0]
* and LSB in byte[1].
*
* This structure is used in the code for things that are endian neutral
* but that fit in a word so that we can manipulate them efficiently.
* By endian neutral, I mean things that are really an array of bytes,
* and always used as such, for example the hint bits. Jean II
*/
typedef
union
{
__u16
word
;
__u8
byte
[
2
];
}
__u16_host_order
;
/* Same purpose, different application */
#define u16ho(array) (* ((__u16 *) array))
/* Types of discovery */
typedef
enum
{
DISCOVERY_LOG
,
/* What's in our discovery log */
...
...
@@ -62,30 +70,31 @@ typedef enum {
#define NICKNAME_MAX_LEN 21
/* Basic discovery information about a peer */
typedef
struct
irda_device_info
discinfo_t
;
/* linux/irda.h */
/*
* The DISCOVERY structure is used for both discovery requests and responses
*/
typedef
struct
discovery_t
{
irda_queue_t
q
;
/* Must be first! */
__u32
saddr
;
/* Which link the device was discovered */
__u32
daddr
;
/* Remote device address */
LAP_REASON
condition
;
/* More info about the discovery */
irda_queue_t
q
;
/* Must be first! */
__u16_host_order
hints
;
/* Discovery hint bits */
__u8
charset
;
/* Encoding of nickname */
char
nickname
[
22
];
/* The name of the device (21 bytes + \0) */
int
name_len
;
/* Lenght of nickname */
discinfo_t
data
;
/* Basic discovery information */
int
name_len
;
/* Lenght of nickname */
int
gen_addr_bit
;
/* Need to generate a new device address? */
int
nslots
;
/* Number of slots to use when discovering */
unsigned
long
timestamp
;
/* Time discovered */
unsigned
long
first_timestamp
;
/* First time discovered */
LAP_REASON
condition
;
/* More info about the discovery */
int
gen_addr_bit
;
/* Need to generate a new device
* address? */
int
nslots
;
/* Number of slots to use when
* discovering */
unsigned
long
timestamp
;
/* Last time discovered */
unsigned
long
firststamp
;
/* First time discovered */
}
discovery_t
;
void
irlmp_add_discovery
(
hashbin_t
*
cachelog
,
discovery_t
*
discovery
);
void
irlmp_add_discovery_log
(
hashbin_t
*
cachelog
,
hashbin_t
*
log
);
void
irlmp_expire_discoveries
(
hashbin_t
*
log
,
__u32
saddr
,
int
force
);
struct
irda_device_info
*
irlmp_copy_discoveries
(
hashbin_t
*
log
,
int
*
pn
,
__u16
mask
);
struct
irda_device_info
*
irlmp_copy_discoveries
(
hashbin_t
*
log
,
int
*
pn
,
__u16
mask
,
int
old_entries
);
#endif
include/net/irda/irlan_client.h
View file @
ac5ccb22
...
...
@@ -34,7 +34,7 @@
#include <net/irda/irlan_event.h>
void
irlan_client_start_kick_timer
(
struct
irlan_cb
*
self
,
int
timeout
);
void
irlan_client_discovery_indication
(
disc
overy
_t
*
,
DISCOVERY_MODE
,
void
*
);
void
irlan_client_discovery_indication
(
disc
info
_t
*
,
DISCOVERY_MODE
,
void
*
);
void
irlan_client_wakeup
(
struct
irlan_cb
*
self
,
__u32
saddr
,
__u32
daddr
);
void
irlan_client_open_ctrl_tsap
(
struct
irlan_cb
*
self
);
...
...
include/net/irda/irlmp.h
View file @
ac5ccb22
...
...
@@ -58,7 +58,7 @@
#define LM_IDLE_TIMEOUT 2*HZ
/* 2 seconds for now */
typedef
enum
{
S_PNP
,
S_PNP
=
0
,
S_PDA
,
S_COMPUTER
,
S_PRINTER
,
...
...
@@ -72,22 +72,24 @@ typedef enum {
S_END
,
}
SERVICE
;
typedef
void
(
*
DISCOVERY_CALLBACK1
)
(
discovery_t
*
,
DISCOVERY_MODE
,
void
*
);
typedef
void
(
*
DISCOVERY_CALLBACK2
)
(
hashbin_t
*
,
void
*
);
/* For selective discovery */
typedef
void
(
*
DISCOVERY_CALLBACK1
)
(
discinfo_t
*
,
DISCOVERY_MODE
,
void
*
);
/* For expiry (the same) */
typedef
void
(
*
DISCOVERY_CALLBACK2
)
(
discinfo_t
*
,
DISCOVERY_MODE
,
void
*
);
typedef
struct
{
irda_queue_t
queue
;
/* Must be first */
__u16
hints
;
/* Hint bits */
__u16
_host_order
hints
;
/* Hint bits */
}
irlmp_service_t
;
typedef
struct
{
irda_queue_t
queue
;
/* Must be first */
__u16
hint_mask
;
__u16
_host_order
hint_mask
;
DISCOVERY_CALLBACK1
disco_callback
;
/* Selective discovery */
DISCOVERY_CALLBACK
1
expir_callback
;
/* Selective expiration */
DISCOVERY_CALLBACK
2
expir_callback
;
/* Selective expiration */
void
*
priv
;
/* Used to identify client */
}
irlmp_client_t
;
...
...
@@ -199,11 +201,11 @@ __u16 irlmp_service_to_hint(int service);
void
*
irlmp_register_service
(
__u16
hints
);
int
irlmp_unregister_service
(
void
*
handle
);
void
*
irlmp_register_client
(
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK
1
expir_clb
,
void
*
priv
);
DISCOVERY_CALLBACK
2
expir_clb
,
void
*
priv
);
int
irlmp_unregister_client
(
void
*
handle
);
int
irlmp_update_client
(
void
*
handle
,
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK
1
expir_clb
,
void
*
priv
);
DISCOVERY_CALLBACK
2
expir_clb
,
void
*
priv
);
void
irlmp_register_link
(
struct
irlap_cb
*
,
__u32
saddr
,
notify_t
*
);
void
irlmp_unregister_link
(
__u32
saddr
);
...
...
@@ -222,11 +224,11 @@ int irlmp_disconnect_request(struct lsap_cb *, struct sk_buff *userdata);
void
irlmp_discovery_confirm
(
hashbin_t
*
discovery_log
,
DISCOVERY_MODE
mode
);
void
irlmp_discovery_request
(
int
nslots
);
struct
irda_device_info
*
irlmp_get_discoveries
(
int
*
pn
,
__u16
mask
,
int
nslots
);
discinfo_t
*
irlmp_get_discoveries
(
int
*
pn
,
__u16
mask
,
int
nslots
);
void
irlmp_do_expiry
(
void
);
void
irlmp_do_discovery
(
int
nslots
);
discovery_t
*
irlmp_get_discovery_response
(
void
);
void
irlmp_discovery_expiry
(
disc
overy_t
*
expiry
);
void
irlmp_discovery_expiry
(
disc
info_t
*
expiry
,
int
number
);
int
irlmp_data_request
(
struct
lsap_cb
*
,
struct
sk_buff
*
);
void
irlmp_data_indication
(
struct
lsap_cb
*
,
struct
sk_buff
*
);
...
...
net/irda/af_irda.c
View file @
ac5ccb22
...
...
@@ -401,11 +401,10 @@ static void irda_getvalue_confirm(int result, __u16 obj_id,
*
* Got a selective discovery indication from IrLMP.
*
* IrLMP is telling us that this node is matching our hint bit
* filter. Check if it's a newly discovered node (or if node changed its
* hint bits), and then wake up any process waiting for answer...
* IrLMP is telling us that this node is new and matching our hint bit
* filter. Wake up any process waiting for answer...
*/
static
void
irda_selective_discovery_indication
(
disc
overy
_t
*
discovery
,
static
void
irda_selective_discovery_indication
(
disc
info
_t
*
discovery
,
DISCOVERY_MODE
mode
,
void
*
priv
)
{
...
...
@@ -419,18 +418,8 @@ static void irda_selective_discovery_indication(discovery_t *discovery,
return
;
}
/* Check if node is discovered is a new one or an old one.
* We check when how long ago this node was discovered, with a
* coarse timeout (we may miss some discovery events or be delayed).
* Note : by doing this test here, we avoid waking up a process ;-)
*/
if
((
jiffies
-
discovery
->
first_timestamp
)
>
(
sysctl_discovery_timeout
*
HZ
))
{
return
;
/* Too old, not interesting -> goodbye */
}
/* Pass parameter to the caller */
self
->
cached
iscovery
=
discovery
;
self
->
cached
addr
=
discovery
->
daddr
;
/* Wake up process if its waiting for device to be discovered */
wake_up_interruptible
(
&
self
->
query_wait
);
...
...
@@ -455,7 +444,7 @@ static void irda_discovery_timeout(u_long priv)
/* Nothing for the caller */
self
->
cachelog
=
NULL
;
self
->
cached
iscovery
=
NULL
;
self
->
cached
addr
=
0
;
self
->
errno
=
-
ETIME
;
/* Wake up process if its still waiting... */
...
...
@@ -627,7 +616,7 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name)
*/
static
int
irda_discover_daddr_and_lsap_sel
(
struct
irda_sock
*
self
,
char
*
name
)
{
struct
irda_device_info
*
discoveries
;
/* Copy of the discovery log */
discinfo_t
*
discoveries
;
/* Copy of the discovery log */
int
number
;
/* Number of nodes in the log */
int
i
;
int
err
=
-
ENETUNREACH
;
...
...
@@ -642,7 +631,8 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
* Note : we have to use irlmp_get_discoveries(), as opposed
* to play with the cachelog directly, because while we are
* making our ias query, le log might change... */
discoveries
=
irlmp_get_discoveries
(
&
number
,
self
->
mask
,
self
->
nslots
);
discoveries
=
irlmp_get_discoveries
(
&
number
,
self
->
mask
.
word
,
self
->
nslots
);
/* Check if the we got some results */
if
(
discoveries
==
NULL
)
return
-
ENETUNREACH
;
/* No nodes discovered */
...
...
@@ -1137,7 +1127,7 @@ static int irda_create(struct socket *sock, int protocol)
/* Register as a client with IrLMP */
self
->
ckey
=
irlmp_register_client
(
0
,
NULL
,
NULL
,
NULL
);
self
->
mask
=
0xffff
;
self
->
mask
.
word
=
0xffff
;
self
->
rx_flow
=
self
->
tx_flow
=
FLOW_START
;
self
->
nslots
=
DISCOVERY_DEFAULT_SLOTS
;
self
->
daddr
=
DEV_ADDR_ANY
;
/* Until we get connected */
...
...
@@ -1997,6 +1987,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
if
(
optlen
<
sizeof
(
int
))
return
-
EINVAL
;
/* The input is really a (__u8 hints[2]), easier as an int */
if
(
get_user
(
opt
,
(
int
*
)
optval
))
return
-
EFAULT
;
...
...
@@ -2015,16 +2006,17 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
if
(
optlen
<
sizeof
(
int
))
return
-
EINVAL
;
/* The input is really a (__u8 hints[2]), easier as an int */
if
(
get_user
(
opt
,
(
int
*
)
optval
))
return
-
EFAULT
;
/* Set the new hint mask */
self
->
mask
=
(
__u16
)
opt
;
self
->
mask
.
word
=
(
__u16
)
opt
;
/* Mask out extension bits */
self
->
mask
&=
0x7f7f
;
self
->
mask
.
word
&=
0x7f7f
;
/* Check if no bits */
if
(
!
self
->
mask
)
self
->
mask
=
0xFFFF
;
if
(
!
self
->
mask
.
word
)
self
->
mask
.
word
=
0xFFFF
;
break
;
default:
...
...
@@ -2115,7 +2107,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
switch
(
optname
)
{
case
IRLMP_ENUMDEVICES
:
/* Ask lmp for the current discovery log */
discoveries
=
irlmp_get_discoveries
(
&
list
.
len
,
self
->
mask
,
discoveries
=
irlmp_get_discoveries
(
&
list
.
len
,
self
->
mask
.
word
,
self
->
nslots
);
/* Check if the we got some results */
if
(
discoveries
==
NULL
)
...
...
@@ -2347,7 +2339,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
return
-
EFAULT
;
/* Tell IrLMP we want to be notified */
irlmp_update_client
(
self
->
ckey
,
self
->
mask
,
irlmp_update_client
(
self
->
ckey
,
self
->
mask
.
word
,
irda_selective_discovery_indication
,
NULL
,
(
void
*
)
self
);
...
...
@@ -2355,7 +2347,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
irlmp_discovery_request
(
self
->
nslots
);
/* Wait until a node is discovered */
if
(
!
self
->
cached
iscovery
)
{
if
(
!
self
->
cached
addr
)
{
int
ret
=
0
;
IRDA_DEBUG
(
1
,
"%s(), nothing discovered yet, going to sleep...
\n
"
,
__FUNCTION__
);
...
...
@@ -2370,7 +2362,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
/* Wait for IR-LMP to call us back */
__wait_event_interruptible
(
self
->
query_wait
,
(
self
->
cachediscovery
!=
NULL
||
self
->
errno
==
-
ETIME
),
(
self
->
cachedaddr
!=
0
||
self
->
errno
==
-
ETIME
),
ret
);
/* If watchdog is still activated, kill it! */
...
...
@@ -2387,19 +2379,25 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
__FUNCTION__
);
/* Tell IrLMP that we have been notified */
irlmp_update_client
(
self
->
ckey
,
self
->
mask
,
NULL
,
NULL
,
NULL
);
irlmp_update_client
(
self
->
ckey
,
self
->
mask
.
word
,
NULL
,
NULL
,
NULL
);
/* Check if the we got some results */
if
(
!
self
->
cached
iscovery
)
if
(
!
self
->
cached
addr
)
return
-
EAGAIN
;
/* Didn't find any devices */
daddr
=
self
->
cachedaddr
;
/* Cleanup */
self
->
cached
iscovery
=
NULL
;
self
->
cached
addr
=
0
;
/* Note : We don't return anything to the user.
* We could return the device that triggered the wake up,
* but it's probably better to force the user to query
* the whole discovery log and let him pick one device...
/* We return the daddr of the device that trigger the
* wakeup. As irlmp pass us only the new devices, we
* are sure that it's not an old device.
* If the user want more details, he should query
* the whole discovery log and pick one device...
*/
if
(
put_user
(
daddr
,
(
int
*
)
optval
))
return
-
EFAULT
;
break
;
default:
return
-
ENOPROTOOPT
;
...
...
net/irda/discovery.c
View file @
ac5ccb22
...
...
@@ -59,7 +59,7 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
unsigned
long
flags
;
/* Set time of first discovery if node is new (see below) */
new
->
first
_time
stamp
=
new
->
timestamp
;
new
->
firststamp
=
new
->
timestamp
;
spin_lock_irqsave
(
&
cachelog
->
hb_spinlock
,
flags
);
...
...
@@ -76,24 +76,24 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
/* Be sure to stay one item ahead */
discovery
=
(
discovery_t
*
)
hashbin_get_next
(
cachelog
);
if
((
node
->
saddr
==
new
->
saddr
)
&&
((
node
->
da
ddr
==
new
->
daddr
)
||
(
strcmp
(
node
->
nickname
,
new
->
nickname
)
==
0
)))
if
((
node
->
data
.
saddr
==
new
->
data
.
saddr
)
&&
((
node
->
da
ta
.
daddr
==
new
->
data
.
daddr
)
||
(
strcmp
(
node
->
data
.
info
,
new
->
data
.
info
)
==
0
)))
{
/* This discovery is a previous discovery
* from the same device, so just remove it
*/
hashbin_remove_this
(
cachelog
,
(
irda_queue_t
*
)
node
);
/* Check if hints bits
have
changed */
if
(
node
->
hints
.
word
==
new
->
hints
.
word
)
/* Check if hints bits
are un
changed */
if
(
u16ho
(
node
->
data
.
hints
)
==
u16ho
(
new
->
data
.
hints
)
)
/* Set time of first discovery for this node */
new
->
first
_timestamp
=
node
->
first_time
stamp
;
new
->
first
stamp
=
node
->
first
stamp
;
kfree
(
node
);
}
}
/* Insert the new and updated version */
hashbin_insert
(
cachelog
,
(
irda_queue_t
*
)
new
,
new
->
daddr
,
NULL
);
hashbin_insert
(
cachelog
,
(
irda_queue_t
*
)
new
,
new
->
da
ta
.
da
ddr
,
NULL
);
spin_unlock_irqrestore
(
&
cachelog
->
hb_spinlock
,
flags
);
}
...
...
@@ -147,27 +147,50 @@ void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log)
*/
void
irlmp_expire_discoveries
(
hashbin_t
*
log
,
__u32
saddr
,
int
force
)
{
discovery_t
*
discovery
,
*
curr
;
unsigned
long
flags
;
discovery_t
*
discovery
;
discovery_t
*
curr
;
unsigned
long
flags
;
discinfo_t
*
buffer
=
NULL
;
int
n
;
/* Size of the full log */
int
i
=
0
;
/* How many we expired */
ASSERT
(
log
!=
NULL
,
return
;);
IRDA_DEBUG
(
4
,
"%s()
\n
"
,
__FUNCTION__
);
spin_lock_irqsave
(
&
log
->
hb_spinlock
,
flags
);
discovery
=
(
discovery_t
*
)
hashbin_get_first
(
log
);
while
(
discovery
!=
NULL
)
{
curr
=
discovery
;
/* Be sure to be one item ahead */
curr
=
discovery
;
discovery
=
(
discovery_t
*
)
hashbin_get_next
(
log
);
/* Test if it's time to expire this discovery */
if
((
curr
->
saddr
==
saddr
)
&&
if
((
curr
->
data
.
saddr
==
saddr
)
&&
(
force
||
((
jiffies
-
curr
->
timestamp
)
>
DISCOVERY_EXPIRE_TIMEOUT
)))
{
/* Tell IrLMP and registered clients about it */
irlmp_discovery_expiry
(
curr
);
/* Create buffer as needed.
* As this function get called a lot and most time
* we don't have anything to put in the log (we are
* quite picky), we can save a lot of overhead
* by not calling kmalloc. Jean II */
if
(
buffer
==
NULL
)
{
/* Create the client specific buffer */
n
=
HASHBIN_GET_SIZE
(
log
);
buffer
=
kmalloc
(
n
*
sizeof
(
struct
irda_device_info
),
GFP_ATOMIC
);
if
(
buffer
==
NULL
)
{
spin_unlock_irqrestore
(
&
log
->
hb_spinlock
,
flags
);
return
;
}
}
/* Copy discovery information */
memcpy
(
&
(
buffer
[
i
]),
&
(
curr
->
data
),
sizeof
(
discinfo_t
));
i
++
;
/* Remove it from the log */
curr
=
hashbin_remove_this
(
log
,
(
irda_queue_t
*
)
curr
);
if
(
curr
)
...
...
@@ -175,9 +198,23 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
}
}
/* Drop the spinlock before calling the higher layers, as
* we can't guarantee they won't call us back and create a
* deadlock. We will work on our own private data, so we
* don't care to be interupted. - Jean II */
spin_unlock_irqrestore
(
&
log
->
hb_spinlock
,
flags
);
if
(
buffer
==
NULL
)
return
;
/* Tell IrLMP and registered clients about it */
irlmp_discovery_expiry
(
buffer
,
i
);
/* Free up our buffer */
kfree
(
buffer
);
}
#if 0
/*
* Function irlmp_dump_discoveries (log)
*
...
...
@@ -193,13 +230,14 @@ void irlmp_dump_discoveries(hashbin_t *log)
discovery = (discovery_t *) hashbin_get_first(log);
while (discovery != NULL) {
IRDA_DEBUG(0, "Discovery:\n");
IRDA_DEBUG
(
0
,
" daddr=%08x
\n
"
,
discovery
->
daddr
);
IRDA_DEBUG
(
0
,
" saddr=%08x
\n
"
,
discovery
->
saddr
);
IRDA_DEBUG
(
0
,
" nickname=%s
\n
"
,
discovery
->
nickname
);
IRDA_DEBUG(0, " daddr=%08x\n", discovery->da
ta.da
ddr);
IRDA_DEBUG(0, " saddr=%08x\n", discovery->
data.
saddr);
IRDA_DEBUG(0, " nickname=%s\n", discovery->
data.info
);
discovery = (discovery_t *) hashbin_get_next(log);
}
}
#endif
/*
* Function irlmp_copy_discoveries (log, pn, mask)
...
...
@@ -221,43 +259,49 @@ void irlmp_dump_discoveries(hashbin_t *log)
* Note : the client must kfree himself() the log...
* Jean II
*/
struct
irda_device_info
*
irlmp_copy_discoveries
(
hashbin_t
*
log
,
int
*
pn
,
__u16
mask
)
struct
irda_device_info
*
irlmp_copy_discoveries
(
hashbin_t
*
log
,
int
*
pn
,
__u16
mask
,
int
old_entries
)
{
discovery_t
*
discovery
;
unsigned
long
flags
;
struct
irda_device_info
*
buffer
;
int
i
=
0
;
int
n
;
discovery_t
*
discovery
;
unsigned
long
flags
;
discinfo_t
*
buffer
=
NULL
;
int
j_timeout
=
(
sysctl_discovery_timeout
*
HZ
);
int
n
;
/* Size of the full log */
int
i
=
0
;
/* How many we picked */
ASSERT
(
pn
!=
NULL
,
return
NULL
;);
ASSERT
(
log
!=
NULL
,
return
NULL
;);
/* Check if log is empty */
if
(
log
==
NULL
)
return
NULL
;
/* Save spin lock - spinlock should be discovery specific */
/* Save spin lock */
spin_lock_irqsave
(
&
log
->
hb_spinlock
,
flags
);
/* Create the client specific buffer */
n
=
HASHBIN_GET_SIZE
(
log
);
buffer
=
kmalloc
(
n
*
sizeof
(
struct
irda_device_info
),
GFP_ATOMIC
);
if
(
buffer
==
NULL
)
{
spin_unlock_irqrestore
(
&
log
->
hb_spinlock
,
flags
);
return
NULL
;
}
discovery
=
(
discovery_t
*
)
hashbin_get_first
(
log
);
while
((
discovery
!=
NULL
)
&&
(
i
<
n
))
{
/* Mask out the ones we don't want */
if
(
discovery
->
hints
.
word
&
mask
)
{
while
(
discovery
!=
NULL
)
{
/* Mask out the ones we don't want :
* We want to match the discovery mask, and to get only
* the most recent one (unless we want old ones) */
if
((
u16ho
(
discovery
->
data
.
hints
)
&
mask
)
&&
((
old_entries
)
||
((
jiffies
-
discovery
->
firststamp
)
<
j_timeout
))
)
{
/* Create buffer as needed.
* As this function get called a lot and most time
* we don't have anything to put in the log (we are
* quite picky), we can save a lot of overhead
* by not calling kmalloc. Jean II */
if
(
buffer
==
NULL
)
{
/* Create the client specific buffer */
n
=
HASHBIN_GET_SIZE
(
log
);
buffer
=
kmalloc
(
n
*
sizeof
(
struct
irda_device_info
),
GFP_ATOMIC
);
if
(
buffer
==
NULL
)
{
spin_unlock_irqrestore
(
&
log
->
hb_spinlock
,
flags
);
return
NULL
;
}
}
/* Copy discovery information */
buffer
[
i
].
saddr
=
discovery
->
saddr
;
buffer
[
i
].
daddr
=
discovery
->
daddr
;
buffer
[
i
].
charset
=
discovery
->
charset
;
buffer
[
i
].
hints
[
0
]
=
discovery
->
hints
.
byte
[
0
];
buffer
[
i
].
hints
[
1
]
=
discovery
->
hints
.
byte
[
1
];
strncpy
(
buffer
[
i
].
info
,
discovery
->
nickname
,
NICKNAME_MAX_LEN
);
memcpy
(
&
(
buffer
[
i
]),
&
(
discovery
->
data
),
sizeof
(
discinfo_t
));
i
++
;
}
discovery
=
(
discovery_t
*
)
hashbin_get_next
(
log
);
...
...
@@ -288,14 +332,14 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr)
d
=
(
discovery_t
*
)
hashbin_get_first
(
cachelog
);
while
(
d
!=
NULL
)
{
IRDA_DEBUG
(
1
,
"Discovery:
\n
"
);
IRDA_DEBUG
(
1
,
" daddr=%08x
\n
"
,
d
->
daddr
);
IRDA_DEBUG
(
1
,
" nickname=%s
\n
"
,
d
->
nickname
);
if
(
strcmp
(
name
,
d
->
nickname
)
==
0
)
{
*
saddr
=
d
->
saddr
;
IRDA_DEBUG
(
1
,
" daddr=%08x
\n
"
,
d
->
da
ta
.
da
ddr
);
IRDA_DEBUG
(
1
,
" nickname=%s
\n
"
,
d
->
data
.
info
);
if
(
strcmp
(
name
,
d
->
data
.
info
)
==
0
)
{
*
saddr
=
d
->
data
.
saddr
;
spin_unlock_irqrestore
(
&
cachelog
->
hb_spinlock
,
flags
);
return
d
->
daddr
;
return
d
->
da
ta
.
da
ddr
;
}
d
=
(
discovery_t
*
)
hashbin_get_next
(
cachelog
);
}
...
...
@@ -328,41 +372,41 @@ int discovery_proc_read(char *buf, char **start, off_t offset, int length,
discovery
=
(
discovery_t
*
)
hashbin_get_first
(
cachelog
);
while
((
discovery
!=
NULL
)
&&
(
len
<
length
))
{
len
+=
sprintf
(
buf
+
len
,
"nickname: %s,"
,
discovery
->
nickname
);
len
+=
sprintf
(
buf
+
len
,
"nickname: %s,"
,
discovery
->
data
.
info
);
len
+=
sprintf
(
buf
+
len
,
" hint: 0x%02x%02x"
,
discovery
->
hints
.
byte
[
0
],
discovery
->
hints
.
byte
[
1
]);
discovery
->
data
.
hints
[
0
],
discovery
->
data
.
hints
[
1
]);
#if 0
if ( discovery->
hints.byte
[0] & HINT_PNP)
if ( discovery->
data.hints
[0] & HINT_PNP)
len += sprintf( buf+len, "PnP Compatible ");
if ( discovery->
hints.byte
[0] & HINT_PDA)
if ( discovery->
data.hints
[0] & HINT_PDA)
len += sprintf( buf+len, "PDA/Palmtop ");
if ( discovery->
hints.byte
[0] & HINT_COMPUTER)
if ( discovery->
data.hints
[0] & HINT_COMPUTER)
len += sprintf( buf+len, "Computer ");
if ( discovery->
hints.byte
[0] & HINT_PRINTER)
if ( discovery->
data.hints
[0] & HINT_PRINTER)
len += sprintf( buf+len, "Printer ");
if ( discovery->
hints.byte
[0] & HINT_MODEM)
if ( discovery->
data.hints
[0] & HINT_MODEM)
len += sprintf( buf+len, "Modem ");
if ( discovery->
hints.byte
[0] & HINT_FAX)
if ( discovery->
data.hints
[0] & HINT_FAX)
len += sprintf( buf+len, "Fax ");
if ( discovery->
hints.byte
[0] & HINT_LAN)
if ( discovery->
data.hints
[0] & HINT_LAN)
len += sprintf( buf+len, "LAN Access ");
if ( discovery->
hints.byte
[1] & HINT_TELEPHONY)
if ( discovery->
data.hints
[1] & HINT_TELEPHONY)
len += sprintf( buf+len, "Telephony ");
if ( discovery->
hints.byte
[1] & HINT_FILE_SERVER)
if ( discovery->
data.hints
[1] & HINT_FILE_SERVER)
len += sprintf( buf+len, "File Server ");
if ( discovery->
hints.byte
[1] & HINT_COMM)
if ( discovery->
data.hints
[1] & HINT_COMM)
len += sprintf( buf+len, "IrCOMM ");
if ( discovery->
hints.byte
[1] & HINT_OBEX)
if ( discovery->
data.hints
[1] & HINT_OBEX)
len += sprintf( buf+len, "IrOBEX ");
#endif
len
+=
sprintf
(
buf
+
len
,
", saddr: 0x%08x"
,
discovery
->
saddr
);
discovery
->
data
.
saddr
);
len
+=
sprintf
(
buf
+
len
,
", daddr: 0x%08x
\n
"
,
discovery
->
daddr
);
discovery
->
da
ta
.
da
ddr
);
len
+=
sprintf
(
buf
+
len
,
"
\n
"
);
...
...
net/irda/ircomm/ircomm_tty_attach.c
View file @
ac5ccb22
...
...
@@ -46,7 +46,7 @@
#include <net/irda/ircomm_tty_attach.h>
static
void
ircomm_tty_ias_register
(
struct
ircomm_tty_cb
*
self
);
static
void
ircomm_tty_discovery_indication
(
disc
overy
_t
*
discovery
,
static
void
ircomm_tty_discovery_indication
(
disc
info
_t
*
discovery
,
DISCOVERY_MODE
mode
,
void
*
priv
);
static
void
ircomm_tty_getvalue_confirm
(
int
result
,
__u16
obj_id
,
...
...
@@ -305,7 +305,7 @@ int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self)
* device it is, and which services it has.
*
*/
static
void
ircomm_tty_discovery_indication
(
disc
overy
_t
*
discovery
,
static
void
ircomm_tty_discovery_indication
(
disc
info
_t
*
discovery
,
DISCOVERY_MODE
mode
,
void
*
priv
)
{
...
...
net/irda/irlan/irlan_client.c
View file @
ac5ccb22
...
...
@@ -145,7 +145,7 @@ void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr)
* Remote device with IrLAN server support discovered
*
*/
void
irlan_client_discovery_indication
(
disc
overy
_t
*
discovery
,
void
irlan_client_discovery_indication
(
disc
info
_t
*
discovery
,
DISCOVERY_MODE
mode
,
void
*
priv
)
{
...
...
net/irda/irlap_event.c
View file @
ac5ccb22
...
...
@@ -419,7 +419,7 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
info
->
s
);
if
(
self
->
slot
==
info
->
s
)
{
discovery_rsp
=
irlmp_get_discovery_response
();
discovery_rsp
->
daddr
=
info
->
daddr
;
discovery_rsp
->
da
ta
.
da
ddr
=
info
->
daddr
;
irlap_send_discovery_xid_frame
(
self
,
info
->
S
,
self
->
slot
,
...
...
@@ -576,7 +576,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
ASSERT
(
info
->
discovery
!=
NULL
,
return
-
1
;);
IRDA_DEBUG
(
4
,
"%s(), daddr=%08x
\n
"
,
__FUNCTION__
,
info
->
discovery
->
daddr
);
info
->
discovery
->
da
ta
.
da
ddr
);
if
(
!
self
->
discovery_log
)
{
WARNING
(
"%s: discovery log is gone! "
...
...
@@ -586,7 +586,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
}
hashbin_insert
(
self
->
discovery_log
,
(
irda_queue_t
*
)
info
->
discovery
,
info
->
discovery
->
daddr
,
NULL
);
info
->
discovery
->
da
ta
.
da
ddr
,
NULL
);
/* Keep state */
/* irlap_next_state(self, LAP_QUERY); */
...
...
@@ -704,7 +704,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
irlap_discovery_indication
(
self
,
info
->
discovery
);
}
else
if
((
info
->
s
>=
self
->
slot
)
&&
(
!
self
->
frame_sent
))
{
discovery_rsp
=
irlmp_get_discovery_response
();
discovery_rsp
->
daddr
=
info
->
daddr
;
discovery_rsp
->
da
ta
.
da
ddr
=
info
->
daddr
;
irlap_send_discovery_xid_frame
(
self
,
info
->
S
,
self
->
slot
,
FALSE
,
...
...
@@ -982,15 +982,48 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
* Only send frame if send-window > 0.
*/
if
((
self
->
window
>
0
)
&&
(
!
self
->
remote_busy
))
{
int
nextfit
;
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
struct
sk_buff
*
skb_next
;
/* With DYNAMIC_WINDOW, we keep the window size
* maximum, and adapt on the packets we are sending.
* At 115k, we can send only 2 packets of 2048 bytes
* in a 500 ms turnaround. Without this option, we
* would always limit the window to 2. With this
* option, if we send smaller packets, we can send
* up to 7 of them (always depending on QoS).
* Jean II */
/* Look at the next skb. This is safe, as we are
* the only consumer of the Tx queue (if we are not,
* we have other problems) - Jean II */
skb_next
=
skb_peek
(
&
self
->
txq
);
/* Check if a subsequent skb exist and would fit in
* the current window (with respect to turnaround
* time).
* This allow us to properly mark the current packet
* with the pf bit, to avoid falling back on the
* second test below, and avoid waiting the
* end of the window and sending a extra RR.
* Note : (skb_next != NULL) <=> (skb_queue_len() > 0)
* Jean II */
nextfit
=
((
skb_next
!=
NULL
)
&&
((
skb_next
->
len
+
skb
->
len
)
<=
self
->
bytes_left
));
/*
* The current packet may not fit ! Because of test
* above, this should not happen any more !!!
* Test if we have transmitted more bytes over the
* link than its possible to do with the current
* speed and turn-around-time.
*/
if
(
skb
->
len
>
self
->
bytes_left
)
{
IRDA_DEBUG
(
4
,
"%s(), Not allowed to transmit"
if
((
!
nextfit
)
&&
(
skb
->
len
>
self
->
bytes_left
)
)
{
IRDA_DEBUG
(
0
,
"%s(), Not allowed to transmit"
" more bytes!
\n
"
,
__FUNCTION__
);
/* Requeue the skb */
skb_queue_head
(
&
self
->
txq
,
skb_get
(
skb
));
/*
* We should switch state to LAP_NRM_P, but
...
...
@@ -1000,20 +1033,33 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
* trigger anyway now, so we just wait for it
* DB
*/
/*
* Sorry, but that's not totally true. If
* we send 2000B packets, we may wait another
* 1000B until our turnaround expire. That's
* why we need to be proactive in avoiding
* comming here. - Jean II
*/
return
-
EPROTO
;
}
/* Substract space used by this skb */
self
->
bytes_left
-=
skb
->
len
;
#endif
/* CONFIG_IRDA_DYNAMIC_WINDOW */
#else
/* CONFIG_IRDA_DYNAMIC_WINDOW */
/* Window has been adjusted for the max packet
* size, so much simpler... - Jean II */
nextfit
=
(
skb_queue_len
(
&
self
->
txq
)
>
0
);
#endif
/* CONFIG_IRDA_DYNAMIC_WINDOW */
/*
* Send data with poll bit cleared only if window > 1
* and there is more frames after this one to be sent
*/
if
((
self
->
window
>
1
)
&&
skb_queue_len
(
&
self
->
txq
)
>
0
)
{
if
((
self
->
window
>
1
)
&&
(
nextfit
))
{
/* More packet to send in current window */
irlap_send_data_primary
(
self
,
skb
);
irlap_next_state
(
self
,
LAP_XMIT_P
);
}
else
{
/* Final packet of window */
irlap_send_data_primary_poll
(
self
,
skb
);
irlap_next_state
(
self
,
LAP_NRM_P
);
...
...
@@ -1683,16 +1729,37 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
switch
(
event
)
{
case
SEND_I_CMD
:
/*
* Send frame only if send window >
1
* Send frame only if send window >
0
*/
if
((
self
->
window
>
0
)
&&
(
!
self
->
remote_busy
))
{
int
nextfit
;
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
struct
sk_buff
*
skb_next
;
/*
* Same deal as in irlap_state_xmit_p(), so see
* the comments at that point.
* We are the secondary, so there are only subtle
* differences. - Jean II
*/
/* Check if a subsequent skb exist and would fit in
* the current window (with respect to turnaround
* time). - Jean II */
skb_next
=
skb_peek
(
&
self
->
txq
);
nextfit
=
((
skb_next
!=
NULL
)
&&
((
skb_next
->
len
+
skb
->
len
)
<=
self
->
bytes_left
));
/*
* Test if we have transmitted more bytes over the
* link than its possible to do with the current
* speed and turn-around-time.
*/
if
(
skb
->
len
>
self
->
bytes_left
)
{
if
((
!
nextfit
)
&&
(
skb
->
len
>
self
->
bytes_left
))
{
IRDA_DEBUG
(
0
,
"%s(), Not allowed to transmit"
" more bytes!
\n
"
,
__FUNCTION__
);
/* Requeue the skb */
skb_queue_head
(
&
self
->
txq
,
skb_get
(
skb
));
/*
...
...
@@ -1706,18 +1773,24 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
irlap_next_state
(
self
,
LAP_NRM_S
);
/* Slight difference with primary :
* here we would wait for the other side to
* expire the turnaround. - Jean II */
return
-
EPROTO
;
/* Try again later */
}
/* Substract space used by this skb */
self
->
bytes_left
-=
skb
->
len
;
#else
/* CONFIG_IRDA_DYNAMIC_WINDOW */
/* Window has been adjusted for the max packet
* size, so much simpler... - Jean II */
nextfit
=
(
skb_queue_len
(
&
self
->
txq
)
>
0
);
#endif
/* CONFIG_IRDA_DYNAMIC_WINDOW */
/*
* Send data with final bit cleared only if window > 1
* and there is more frames to be sent
*/
if
((
self
->
window
>
1
)
&&
skb_queue_len
(
&
self
->
txq
)
>
0
)
{
if
((
self
->
window
>
1
)
&&
(
nextfit
))
{
irlap_send_data_secondary
(
self
,
skb
);
irlap_next_state
(
self
,
LAP_XMIT_S
);
}
else
{
...
...
net/irda/irlap_frame.c
View file @
ac5ccb22
...
...
@@ -335,7 +335,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
if
(
command
)
frame
->
daddr
=
cpu_to_le32
(
bcast
);
else
frame
->
daddr
=
cpu_to_le32
(
discovery
->
daddr
);
frame
->
daddr
=
cpu_to_le32
(
discovery
->
da
ta
.
da
ddr
);
switch
(
S
)
{
case
1
:
...
...
@@ -366,20 +366,20 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
if
(
!
command
||
(
frame
->
slotnr
==
0xff
))
{
int
len
;
if
(
discovery
->
hints
.
byte
[
0
]
&
HINT_EXTENSION
)
{
if
(
discovery
->
data
.
hints
[
0
]
&
HINT_EXTENSION
)
{
info
=
skb_put
(
skb
,
2
);
info
[
0
]
=
discovery
->
hints
.
byte
[
0
];
info
[
1
]
=
discovery
->
hints
.
byte
[
1
];
info
[
0
]
=
discovery
->
data
.
hints
[
0
];
info
[
1
]
=
discovery
->
data
.
hints
[
1
];
}
else
{
info
=
skb_put
(
skb
,
1
);
info
[
0
]
=
discovery
->
hints
.
byte
[
0
];
info
[
0
]
=
discovery
->
data
.
hints
[
0
];
}
info
=
skb_put
(
skb
,
1
);
info
[
0
]
=
discovery
->
charset
;
info
[
0
]
=
discovery
->
data
.
charset
;
len
=
IRDA_MIN
(
discovery
->
name_len
,
skb_tailroom
(
skb
));
info
=
skb_put
(
skb
,
len
);
memcpy
(
info
,
discovery
->
nickname
,
len
);
memcpy
(
info
,
discovery
->
data
.
info
,
len
);
}
irlap_queue_xmit
(
self
,
skb
);
}
...
...
@@ -422,24 +422,25 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
}
memset
(
discovery
,
0
,
sizeof
(
discovery_t
));
discovery
->
daddr
=
info
->
daddr
;
discovery
->
saddr
=
self
->
saddr
;
discovery
->
da
ta
.
da
ddr
=
info
->
daddr
;
discovery
->
data
.
saddr
=
self
->
saddr
;
discovery
->
timestamp
=
jiffies
;
IRDA_DEBUG
(
4
,
"%s(), daddr=%08x
\n
"
,
__FUNCTION__
,
discovery
->
daddr
);
IRDA_DEBUG
(
4
,
"%s(), daddr=%08x
\n
"
,
__FUNCTION__
,
discovery
->
data
.
daddr
);
discovery_info
=
skb_pull
(
skb
,
sizeof
(
struct
xid_frame
));
/* Get info returned from peer */
discovery
->
hints
.
byte
[
0
]
=
discovery_info
[
0
];
discovery
->
data
.
hints
[
0
]
=
discovery_info
[
0
];
if
(
discovery_info
[
0
]
&
HINT_EXTENSION
)
{
IRDA_DEBUG
(
4
,
"EXTENSION
\n
"
);
discovery
->
hints
.
byte
[
1
]
=
discovery_info
[
1
];
discovery
->
charset
=
discovery_info
[
2
];
discovery
->
data
.
hints
[
1
]
=
discovery_info
[
1
];
discovery
->
data
.
charset
=
discovery_info
[
2
];
text
=
(
char
*
)
&
discovery_info
[
3
];
}
else
{
discovery
->
hints
.
byte
[
1
]
=
0
;
discovery
->
charset
=
discovery_info
[
1
];
discovery
->
data
.
hints
[
1
]
=
0
;
discovery
->
data
.
charset
=
discovery_info
[
1
];
text
=
(
char
*
)
&
discovery_info
[
2
];
}
/*
...
...
@@ -447,8 +448,8 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
* FCS bytes resides.
*/
skb
->
data
[
skb
->
len
]
=
'\0'
;
strncpy
(
discovery
->
nickname
,
text
,
NICKNAME_MAX_LEN
);
discovery
->
name_len
=
strlen
(
discovery
->
nickname
);
strncpy
(
discovery
->
data
.
info
,
text
,
NICKNAME_MAX_LEN
);
discovery
->
name_len
=
strlen
(
discovery
->
data
.
info
);
info
->
discovery
=
discovery
;
...
...
@@ -523,18 +524,18 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
return
;
}
discovery
->
daddr
=
info
->
daddr
;
discovery
->
saddr
=
self
->
saddr
;
discovery
->
da
ta
.
da
ddr
=
info
->
daddr
;
discovery
->
data
.
saddr
=
self
->
saddr
;
discovery
->
timestamp
=
jiffies
;
discovery
->
hints
.
byte
[
0
]
=
discovery_info
[
0
];
discovery
->
data
.
hints
[
0
]
=
discovery_info
[
0
];
if
(
discovery_info
[
0
]
&
HINT_EXTENSION
)
{
discovery
->
hints
.
byte
[
1
]
=
discovery_info
[
1
];
discovery
->
charset
=
discovery_info
[
2
];
discovery
->
data
.
hints
[
1
]
=
discovery_info
[
1
];
discovery
->
data
.
charset
=
discovery_info
[
2
];
text
=
(
char
*
)
&
discovery_info
[
3
];
}
else
{
discovery
->
hints
.
byte
[
1
]
=
0
;
discovery
->
charset
=
discovery_info
[
1
];
discovery
->
data
.
hints
[
1
]
=
0
;
discovery
->
data
.
charset
=
discovery_info
[
1
];
text
=
(
char
*
)
&
discovery_info
[
2
];
}
/*
...
...
@@ -542,8 +543,8 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
* FCS bytes resides.
*/
skb
->
data
[
skb
->
len
]
=
'\0'
;
strncpy
(
discovery
->
nickname
,
text
,
NICKNAME_MAX_LEN
);
discovery
->
name_len
=
strlen
(
discovery
->
nickname
);
strncpy
(
discovery
->
data
.
info
,
text
,
NICKNAME_MAX_LEN
);
discovery
->
name_len
=
strlen
(
discovery
->
data
.
info
);
info
->
discovery
=
discovery
;
}
else
...
...
net/irda/irlmp.c
View file @
ac5ccb22
...
...
@@ -401,8 +401,8 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
}
if
(
discovery
)
{
saddr
=
discovery
->
saddr
;
daddr
=
discovery
->
daddr
;
saddr
=
discovery
->
data
.
saddr
;
daddr
=
discovery
->
da
ta
.
da
ddr
;
}
spin_unlock_irqrestore
(
&
irlmp
->
cachelog
->
hb_spinlock
,
flags
);
}
...
...
@@ -793,17 +793,17 @@ void irlmp_do_discovery(int nslots)
}
/* Construct new discovery info to be used by IrLAP, */
irlmp
->
discovery_cmd
.
hints
.
word
=
irlmp
->
hints
.
word
;
u16ho
(
irlmp
->
discovery_cmd
.
data
.
hints
)
=
irlmp
->
hints
.
word
;
/*
* Set character set for device name (we use ASCII), and
* copy device name. Remember to make room for a \0 at the
* end
*/
irlmp
->
discovery_cmd
.
charset
=
CS_ASCII
;
strncpy
(
irlmp
->
discovery_cmd
.
nickname
,
sysctl_devname
,
irlmp
->
discovery_cmd
.
data
.
charset
=
CS_ASCII
;
strncpy
(
irlmp
->
discovery_cmd
.
data
.
info
,
sysctl_devname
,
NICKNAME_MAX_LEN
);
irlmp
->
discovery_cmd
.
name_len
=
strlen
(
irlmp
->
discovery_cmd
.
nickname
);
irlmp
->
discovery_cmd
.
name_len
=
strlen
(
irlmp
->
discovery_cmd
.
data
.
info
);
irlmp
->
discovery_cmd
.
nslots
=
nslots
;
/*
...
...
@@ -827,10 +827,13 @@ void irlmp_do_discovery(int nslots)
*
* Do a discovery of devices in front of the computer
*
* If the caller has registered a client discovery callback, this
* allow him to receive the full content of the discovery log through
* this callback (as normally he will receive only new discoveries).
*/
void
irlmp_discovery_request
(
int
nslots
)
{
/* Return current cached discovery log */
/* Return current cached discovery log
(in full)
*/
irlmp_discovery_confirm
(
irlmp
->
cachelog
,
DISCOVERY_LOG
);
/*
...
...
@@ -854,6 +857,8 @@ void irlmp_discovery_request(int nslots)
*
* Return the current discovery log
*
* If discovery is not enabled, you should call this function again
* after 1 or 2 seconds (i.e. after discovery has been done).
*/
struct
irda_device_info
*
irlmp_get_discoveries
(
int
*
pn
,
__u16
mask
,
int
nslots
)
{
...
...
@@ -875,49 +880,8 @@ struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots)
}
/* Return current cached discovery log */
return
(
irlmp_copy_discoveries
(
irlmp
->
cachelog
,
pn
,
mask
));
}
#if 0
/*
* Function irlmp_check_services (discovery)
*/
void irlmp_check_services(discovery_t *discovery)
{
struct irlmp_client *client;
__u8 *service_log;
__u8 service;
int i = 0;
IRDA_DEBUG(1, "IrDA Discovered: %s\n", discovery->info);
IRDA_DEBUG(1, " Services: ");
service_log = irlmp_hint_to_service(discovery->hints.byte);
if (!service_log)
return;
/*
* Check all services on the device
*/
while ((service = service_log[i++]) != S_END) {
IRDA_DEBUG( 4, "service=%02x\n", service);
client = hashbin_lock_find(irlmp->registry, service, NULL);
if (entry && entry->discovery_callback) {
IRDA_DEBUG( 4, "discovery_callback!\n");
entry->discovery_callback(discovery);
} else {
/* Don't notify about the ANY service */
if (service == S_ANY)
continue;
/*
* Found no clients for dealing with this service,
*/
}
}
kfree(service_log);
return
(
irlmp_copy_discoveries
(
irlmp
->
cachelog
,
pn
,
mask
,
TRUE
));
}
#endif
/*
* Function irlmp_notify_client (log)
...
...
@@ -935,7 +899,9 @@ static inline void
irlmp_notify_client
(
irlmp_client_t
*
client
,
hashbin_t
*
log
,
DISCOVERY_MODE
mode
)
{
discovery_t
*
discovery
;
discinfo_t
*
discoveries
;
/* Copy of the discovery log */
int
number
;
/* Number of nodes in the log */
int
i
;
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__FUNCTION__
);
...
...
@@ -943,29 +909,37 @@ irlmp_notify_client(irlmp_client_t *client,
if
(
!
client
->
disco_callback
)
return
;
/*
* Locking notes :
* the old code was manipulating the log directly, which was
* very racy. Now, we use copy_discoveries, that protects
* itself while dumping the log for us.
* The overhead of the copy is compensated by the fact that
* we only pass new discoveries in normal mode and don't
* pass the same old entry every 3s to the caller as we used
* to do (virtual function calling is expensive).
* Jean II
*/
/*
* Now, check all discovered devices (if any), and notify client
* only about the services that the client is interested in
* Note : most often, we will get called immediately following
* a discovery, so the log is not going to expire.
* On the other hand, comming here through irlmp_discovery_request()
* is *very* problematic - Jean II
* Can't use hashbin_find_next(), key is not unique. I'm running
* out of options :-( - Jean II
* We also notify only about the new devices unless the caller
* explicity request a dump of the log. Jean II
*/
discover
y
=
(
discovery_t
*
)
hashbin_get_first
(
log
);
while
(
discovery
!=
NULL
)
{
IRDA_DEBUG
(
3
,
"discovery->daddr = 0x%08x
\n
"
,
discovery
->
daddr
);
/*
* Any common hint bits? Remember to mask away the extension
* bits ;-)
*/
if
(
client
->
hint_mask
&
discovery
->
hints
.
word
&
0x7f7f
)
client
->
disco_callback
(
discovery
,
mode
,
client
->
priv
);
discovery
=
(
discovery_t
*
)
hashbin_get_next
(
log
);
}
discover
ies
=
irlmp_copy_discoveries
(
log
,
&
number
,
client
->
hint_mask
.
word
,
(
mode
==
DISCOVERY_LOG
)
);
/* Check if the we got some results */
if
(
discoveries
==
NULL
)
return
;
/* No nodes discovered */
/* Pass all entries to the listener
*/
for
(
i
=
0
;
i
<
number
;
i
++
)
client
->
disco_callback
(
&
(
discoveries
[
i
])
,
mode
,
client
->
priv
);
/* Free up our buffer */
kfree
(
discoveries
);
}
/*
...
...
@@ -987,6 +961,7 @@ void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
if
(
!
(
HASHBIN_GET_SIZE
(
log
)))
return
;
/* For each client - notify callback may touch client list */
client
=
(
irlmp_client_t
*
)
hashbin_get_first
(
irlmp
->
clients
);
while
(
NULL
!=
hashbin_find_next
(
irlmp
->
clients
,
(
long
)
client
,
NULL
,
(
void
*
)
&
client_next
)
)
{
...
...
@@ -1005,26 +980,34 @@ void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
* registered for this event...
*
* Note : called exclusively from discovery.c
* Note :
as we are currently processing the log, the clients callback
*
should *NOT* attempt to touch the log now
.
* Note :
this is no longer called under discovery spinlock, so the
*
client can do whatever he wants in the callback
.
*/
void
irlmp_discovery_expiry
(
disc
overy_t
*
expiry
)
void
irlmp_discovery_expiry
(
disc
info_t
*
expiries
,
int
number
)
{
irlmp_client_t
*
client
;
irlmp_client_t
*
client_next
;
int
i
;
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__FUNCTION__
);
ASSERT
(
expir
y
!=
NULL
,
return
;);
ASSERT
(
expir
ies
!=
NULL
,
return
;);
/* For each client - notify callback may touch client list */
client
=
(
irlmp_client_t
*
)
hashbin_get_first
(
irlmp
->
clients
);
while
(
NULL
!=
hashbin_find_next
(
irlmp
->
clients
,
(
long
)
client
,
NULL
,
(
void
*
)
&
client_next
)
)
{
/* Check if we should notify client */
if
((
client
->
expir_callback
)
&&
(
client
->
hint_mask
&
expiry
->
hints
.
word
&
0x7f7f
))
client
->
expir_callback
(
expiry
,
EXPIRY_TIMEOUT
,
client
->
priv
);
/* Pass all entries to the listener */
for
(
i
=
0
;
i
<
number
;
i
++
)
{
/* Check if we should notify client */
if
((
client
->
expir_callback
)
&&
(
client
->
hint_mask
.
word
&
u16ho
(
expiries
[
i
].
hints
)
&
0x7f7f
)
)
client
->
expir_callback
(
&
(
expiries
[
i
]),
EXPIRY_TIMEOUT
,
client
->
priv
);
}
/* Next client */
client
=
client_next
;
...
...
@@ -1043,18 +1026,18 @@ discovery_t *irlmp_get_discovery_response()
ASSERT
(
irlmp
!=
NULL
,
return
NULL
;);
irlmp
->
discovery_rsp
.
hints
.
word
=
irlmp
->
hints
.
word
;
u16ho
(
irlmp
->
discovery_rsp
.
data
.
hints
)
=
irlmp
->
hints
.
word
;
/*
* Set character set for device name (we use ASCII), and
* copy device name. Remember to make room for a \0 at the
* end
*/
irlmp
->
discovery_rsp
.
charset
=
CS_ASCII
;
irlmp
->
discovery_rsp
.
data
.
charset
=
CS_ASCII
;
strncpy
(
irlmp
->
discovery_rsp
.
nickname
,
sysctl_devname
,
strncpy
(
irlmp
->
discovery_rsp
.
data
.
info
,
sysctl_devname
,
NICKNAME_MAX_LEN
);
irlmp
->
discovery_rsp
.
name_len
=
strlen
(
irlmp
->
discovery_rsp
.
nickname
);
irlmp
->
discovery_rsp
.
name_len
=
strlen
(
irlmp
->
discovery_rsp
.
data
.
info
);
return
&
irlmp
->
discovery_rsp
;
}
...
...
@@ -1291,6 +1274,7 @@ void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow)
}
}
#if 0
/*
* Function irlmp_hint_to_service (hint)
*
...
...
@@ -1365,6 +1349,21 @@ __u8 *irlmp_hint_to_service(__u8 *hint)
return service;
}
#endif
const
__u16
service_hint_mapping
[
S_END
][
2
]
=
{
{
HINT_PNP
,
0
},
/* S_PNP */
{
HINT_PDA
,
0
},
/* S_PDA */
{
HINT_COMPUTER
,
0
},
/* S_COMPUTER */
{
HINT_PRINTER
,
0
},
/* S_PRINTER */
{
HINT_MODEM
,
0
},
/* S_MODEM */
{
HINT_FAX
,
0
},
/* S_FAX */
{
HINT_LAN
,
0
},
/* S_LAN */
{
HINT_EXTENSION
,
HINT_TELEPHONY
},
/* S_TELEPHONY */
{
HINT_EXTENSION
,
HINT_COMM
},
/* S_COMM */
{
HINT_EXTENSION
,
HINT_OBEX
},
/* S_OBEX */
{
0xFF
,
0xFF
},
/* S_ANY */
};
/*
* Function irlmp_service_to_hint (service)
...
...
@@ -1377,46 +1376,9 @@ __u16 irlmp_service_to_hint(int service)
{
__u16_host_order
hint
;
hint
.
word
=
0
;
hint
.
byte
[
0
]
=
service_hint_mapping
[
service
][
0
];
hint
.
byte
[
1
]
=
service_hint_mapping
[
service
][
1
];
switch
(
service
)
{
case
S_PNP
:
hint
.
byte
[
0
]
|=
HINT_PNP
;
break
;
case
S_PDA
:
hint
.
byte
[
0
]
|=
HINT_PDA
;
break
;
case
S_COMPUTER
:
hint
.
byte
[
0
]
|=
HINT_COMPUTER
;
break
;
case
S_PRINTER
:
hint
.
byte
[
0
]
|=
HINT_PRINTER
;
break
;
case
S_MODEM
:
hint
.
byte
[
0
]
|=
HINT_PRINTER
;
break
;
case
S_LAN
:
hint
.
byte
[
0
]
|=
HINT_LAN
;
break
;
case
S_COMM
:
hint
.
byte
[
0
]
|=
HINT_EXTENSION
;
hint
.
byte
[
1
]
|=
HINT_COMM
;
break
;
case
S_OBEX
:
hint
.
byte
[
0
]
|=
HINT_EXTENSION
;
hint
.
byte
[
1
]
|=
HINT_OBEX
;
break
;
case
S_TELEPHONY
:
hint
.
byte
[
0
]
|=
HINT_EXTENSION
;
hint
.
byte
[
1
]
|=
HINT_TELEPHONY
;
break
;
case
S_ANY
:
hint
.
word
=
0xffff
;
break
;
default:
IRDA_DEBUG
(
1
,
"%s(), Unknown service!
\n
"
,
__FUNCTION__
);
break
;
}
return
hint
.
word
;
}
...
...
@@ -1438,7 +1400,7 @@ void *irlmp_register_service(__u16 hints)
IRDA_DEBUG
(
1
,
"%s(), Unable to kmalloc!
\n
"
,
__FUNCTION__
);
return
0
;
}
service
->
hints
=
hints
;
service
->
hints
.
word
=
hints
;
hashbin_insert
(
irlmp
->
services
,
(
irda_queue_t
*
)
service
,
(
long
)
service
,
NULL
);
...
...
@@ -1481,7 +1443,7 @@ int irlmp_unregister_service(void *handle)
spin_lock_irqsave
(
&
irlmp
->
services
->
hb_spinlock
,
flags
);
service
=
(
irlmp_service_t
*
)
hashbin_get_first
(
irlmp
->
services
);
while
(
service
)
{
irlmp
->
hints
.
word
|=
service
->
hints
;
irlmp
->
hints
.
word
|=
service
->
hints
.
word
;
service
=
(
irlmp_service_t
*
)
hashbin_get_next
(
irlmp
->
services
);
}
...
...
@@ -1499,7 +1461,7 @@ int irlmp_unregister_service(void *handle)
* Returns: handle > 0 on success, 0 on error
*/
void
*
irlmp_register_client
(
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK
1
expir_clb
,
void
*
priv
)
DISCOVERY_CALLBACK
2
expir_clb
,
void
*
priv
)
{
irlmp_client_t
*
client
;
...
...
@@ -1514,7 +1476,7 @@ void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
}
/* Register the details */
client
->
hint_mask
=
hint_mask
;
client
->
hint_mask
.
word
=
hint_mask
;
client
->
disco_callback
=
disco_clb
;
client
->
expir_callback
=
expir_clb
;
client
->
priv
=
priv
;
...
...
@@ -1535,7 +1497,7 @@ void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
*/
int
irlmp_update_client
(
void
*
handle
,
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK
1
expir_clb
,
void
*
priv
)
DISCOVERY_CALLBACK
2
expir_clb
,
void
*
priv
)
{
irlmp_client_t
*
client
;
...
...
@@ -1548,7 +1510,7 @@ int irlmp_update_client(void *handle, __u16 hint_mask,
return
-
1
;
}
client
->
hint_mask
=
hint_mask
;
client
->
hint_mask
.
word
=
hint_mask
;
client
->
disco_callback
=
disco_clb
;
client
->
expir_callback
=
expir_clb
;
client
->
priv
=
priv
;
...
...
net/irda/irnet/irnet.h
View file @
ac5ccb22
...
...
@@ -225,6 +225,10 @@
*
* v13 - 30.5.02 - Jean II
* o Update module init code
*
* v14 - 20.2.03 - Jean II
* o Add discovery hint bits in the control channel.
* o Remove obsolete MOD_INC/DEC_USE_COUNT in favor of .owner
*/
/***************************** INCLUDES *****************************/
...
...
@@ -476,6 +480,7 @@ typedef struct irnet_log
__u32
saddr
;
__u32
daddr
;
char
name
[
NICKNAME_MAX_LEN
+
1
];
/* 21 + 1 */
__u16_host_order
hints
;
/* Discovery hint bits */
}
irnet_log
;
/*
...
...
net/irda/irnet/irnet_irda.c
View file @
ac5ccb22
...
...
@@ -28,7 +28,8 @@ irnet_post_event(irnet_socket * ap,
irnet_event
event
,
__u32
saddr
,
__u32
daddr
,
char
*
name
)
char
*
name
,
__u16
hints
)
{
unsigned
long
flags
;
/* For spinlock */
int
index
;
/* In the log */
...
...
@@ -52,6 +53,8 @@ irnet_post_event(irnet_socket * ap,
strcpy
(
irnet_events
.
log
[
index
].
name
,
name
);
else
irnet_events
.
log
[
index
].
name
[
0
]
=
'\0'
;
/* Copy hints */
irnet_events
.
log
[
index
].
hints
.
word
=
hints
;
/* Try to get ppp unit number */
if
((
ap
!=
(
irnet_socket
*
)
NULL
)
&&
(
ap
->
ppp_open
))
irnet_events
.
log
[
index
].
unit
=
ppp_unit_number
(
&
ap
->
chan
);
...
...
@@ -609,7 +612,7 @@ irda_irnet_destroy(irnet_socket * self)
* doesn't exist anymore when we post the event, so we need to pass
* NULL as the first arg... */
irnet_post_event
(
NULL
,
IRNET_DISCONNECT_TO
,
self
->
saddr
,
self
->
daddr
,
self
->
rname
);
self
->
saddr
,
self
->
daddr
,
self
->
rname
,
0
);
}
/* Prevent various IrDA callbacks from messing up things
...
...
@@ -862,7 +865,7 @@ irnet_connect_socket(irnet_socket * server,
/* Notify the control channel */
irnet_post_event
(
new
,
IRNET_CONNECT_FROM
,
new
->
saddr
,
new
->
daddr
,
server
->
rname
);
new
->
saddr
,
new
->
daddr
,
server
->
rname
,
0
);
DEXIT
(
IRDA_SERV_TRACE
,
"
\n
"
);
return
0
;
...
...
@@ -893,7 +896,7 @@ irnet_disconnect_server(irnet_socket * self,
/* Notify the control channel (see irnet_find_socket()) */
irnet_post_event
(
NULL
,
IRNET_REQUEST_FROM
,
self
->
saddr
,
self
->
daddr
,
self
->
rname
);
self
->
saddr
,
self
->
daddr
,
self
->
rname
,
0
);
/* Clean up the server to keep it in listen state */
irttp_listen
(
self
->
tsap
);
...
...
@@ -1108,12 +1111,12 @@ irnet_disconnect_indication(void * instance,
/* If we were active, notify the control channel */
if
(
test_open
)
irnet_post_event
(
self
,
IRNET_DISCONNECT_FROM
,
self
->
saddr
,
self
->
daddr
,
self
->
rname
);
self
->
saddr
,
self
->
daddr
,
self
->
rname
,
0
);
else
/* If we were trying to connect, notify the control channel */
if
((
self
->
tsap
)
&&
(
self
!=
&
irnet_server
.
s
))
irnet_post_event
(
self
,
IRNET_NOANSWER_FROM
,
self
->
saddr
,
self
->
daddr
,
self
->
rname
);
self
->
saddr
,
self
->
daddr
,
self
->
rname
,
0
);
/* Close our IrTTP connection, cleanup tsap */
if
((
self
->
tsap
)
&&
(
self
!=
&
irnet_server
.
s
))
...
...
@@ -1213,7 +1216,7 @@ irnet_connect_confirm(void * instance,
/* Notify the control channel */
irnet_post_event
(
self
,
IRNET_CONNECT_TO
,
self
->
saddr
,
self
->
daddr
,
self
->
rname
);
self
->
saddr
,
self
->
daddr
,
self
->
rname
,
0
);
DEXIT
(
IRDA_TCB_TRACE
,
"
\n
"
);
}
...
...
@@ -1282,7 +1285,7 @@ irnet_status_indication(void * instance,
{
case
STATUS_NO_ACTIVITY
:
irnet_post_event
(
self
,
IRNET_BLOCKED_LINK
,
self
->
saddr
,
self
->
daddr
,
self
->
rname
);
self
->
saddr
,
self
->
daddr
,
self
->
rname
,
0
);
break
;
default:
DEBUG
(
IRDA_CB_INFO
,
"Unknown status...
\n
"
);
...
...
@@ -1616,8 +1619,8 @@ irnet_discovervalue_confirm(int result,
*
* Got a discovery indication from IrLMP, post an event
*
* Note : IrLMP take care of matching the hint mask for us,
we only
* check if it is a "new" node...
* Note : IrLMP take care of matching the hint mask for us,
and also
* check if it is a "new" node
for us
...
*
* As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
* nodes, so it's only at connection time that we will know if the
...
...
@@ -1633,7 +1636,7 @@ irnet_discovervalue_confirm(int result,
* is to messy, so we leave that to user space...
*/
static
void
irnet_discovery_indication
(
disc
overy_t
*
discovery
,
irnet_discovery_indication
(
disc
info_t
*
discovery
,
DISCOVERY_MODE
mode
,
void
*
priv
)
{
...
...
@@ -1643,21 +1646,13 @@ irnet_discovery_indication(discovery_t * discovery,
DASSERT
(
priv
==
&
irnet_server
,
,
IRDA_OCB_ERROR
,
"Invalid instance (0x%X) !!!
\n
"
,
(
unsigned
int
)
priv
);
/* Check if node is discovered is a new one or an old one.
* We check when how long ago this node was discovered, with a
* coarse timeout (we may miss some discovery events or be delayed).
*/
if
((
jiffies
-
discovery
->
first_timestamp
)
>=
(
sysctl_discovery_timeout
*
HZ
))
{
return
;
/* Too old, not interesting -> goodbye */
}
DEBUG
(
IRDA_OCB_INFO
,
"Discovered new IrNET/IrLAN node %s...
\n
"
,
discovery
->
nickname
);
discovery
->
info
);
/* Notify the control channel */
irnet_post_event
(
NULL
,
IRNET_DISCOVER
,
discovery
->
saddr
,
discovery
->
daddr
,
discovery
->
nickname
);
discovery
->
saddr
,
discovery
->
daddr
,
discovery
->
info
,
u16ho
(
discovery
->
hints
));
DEXIT
(
IRDA_OCB_TRACE
,
"
\n
"
);
}
...
...
@@ -1672,7 +1667,7 @@ irnet_discovery_indication(discovery_t * discovery,
* check if it is a "new" node...
*/
static
void
irnet_expiry_indication
(
disc
overy
_t
*
expiry
,
irnet_expiry_indication
(
disc
info
_t
*
expiry
,
DISCOVERY_MODE
mode
,
void
*
priv
)
{
...
...
@@ -1683,11 +1678,12 @@ irnet_expiry_indication(discovery_t * expiry,
"Invalid instance (0x%X) !!!
\n
"
,
(
unsigned
int
)
priv
);
DEBUG
(
IRDA_OCB_INFO
,
"IrNET/IrLAN node %s expired...
\n
"
,
expiry
->
nickname
);
expiry
->
info
);
/* Notify the control channel */
irnet_post_event
(
NULL
,
IRNET_EXPIRE
,
expiry
->
saddr
,
expiry
->
daddr
,
expiry
->
nickname
);
expiry
->
saddr
,
expiry
->
daddr
,
expiry
->
info
,
u16ho
(
expiry
->
hints
));
DEXIT
(
IRDA_OCB_TRACE
,
"
\n
"
);
}
...
...
net/irda/irnet/irnet_irda.h
View file @
ac5ccb22
...
...
@@ -69,7 +69,8 @@ static void
irnet_event
,
__u32
,
__u32
,
char
*
);
char
*
,
__u16
);
/* ----------------------- IRDA SUBROUTINES ----------------------- */
static
inline
int
irnet_open_tsap
(
irnet_socket
*
);
...
...
@@ -150,11 +151,11 @@ static void
void
*
);
#ifdef DISCOVERY_EVENTS
static
void
irnet_discovery_indication
(
disc
overy
_t
*
,
irnet_discovery_indication
(
disc
info
_t
*
,
DISCOVERY_MODE
,
void
*
);
static
void
irnet_expiry_indication
(
disc
overy
_t
*
,
irnet_expiry_indication
(
disc
info
_t
*
,
DISCOVERY_MODE
,
void
*
);
#endif
...
...
net/irda/irnet/irnet_ppp.c
View file @
ac5ccb22
...
...
@@ -213,10 +213,12 @@ irnet_read_discovery_log(irnet_socket * ap,
if
(
ap
->
disco_index
<
ap
->
disco_number
)
{
/* Write an event */
sprintf
(
event
,
"Found %08x (%s) behind %08x
\n
"
,
sprintf
(
event
,
"Found %08x (%s) behind %08x
{hints %02X-%02X}
\n
"
,
ap
->
discoveries
[
ap
->
disco_index
].
daddr
,
ap
->
discoveries
[
ap
->
disco_index
].
info
,
ap
->
discoveries
[
ap
->
disco_index
].
saddr
);
ap
->
discoveries
[
ap
->
disco_index
].
saddr
,
ap
->
discoveries
[
ap
->
disco_index
].
hints
[
0
],
ap
->
discoveries
[
ap
->
disco_index
].
hints
[
1
]);
DEBUG
(
CTRL_INFO
,
"Writing discovery %d : %s
\n
"
,
ap
->
disco_index
,
ap
->
discoveries
[
ap
->
disco_index
].
info
);
...
...
@@ -313,16 +315,20 @@ irnet_ctrl_read(irnet_socket * ap,
switch
(
irnet_events
.
log
[
ap
->
event_index
].
event
)
{
case
IRNET_DISCOVER
:
sprintf
(
event
,
"Discovered %08x (%s) behind %08x
\n
"
,
sprintf
(
event
,
"Discovered %08x (%s) behind %08x
{hints %02X-%02X}
\n
"
,
irnet_events
.
log
[
ap
->
event_index
].
daddr
,
irnet_events
.
log
[
ap
->
event_index
].
name
,
irnet_events
.
log
[
ap
->
event_index
].
saddr
);
irnet_events
.
log
[
ap
->
event_index
].
saddr
,
irnet_events
.
log
[
ap
->
event_index
].
hints
.
byte
[
0
],
irnet_events
.
log
[
ap
->
event_index
].
hints
.
byte
[
1
]);
break
;
case
IRNET_EXPIRE
:
sprintf
(
event
,
"Expired %08x (%s) behind %08x
\n
"
,
sprintf
(
event
,
"Expired %08x (%s) behind %08x
{hints %02X-%02X}
\n
"
,
irnet_events
.
log
[
ap
->
event_index
].
daddr
,
irnet_events
.
log
[
ap
->
event_index
].
name
,
irnet_events
.
log
[
ap
->
event_index
].
saddr
);
irnet_events
.
log
[
ap
->
event_index
].
saddr
,
irnet_events
.
log
[
ap
->
event_index
].
hints
.
byte
[
0
],
irnet_events
.
log
[
ap
->
event_index
].
hints
.
byte
[
1
]);
break
;
case
IRNET_CONNECT_TO
:
sprintf
(
event
,
"Connected to %08x (%s) on ppp%d
\n
"
,
...
...
@@ -445,8 +451,6 @@ dev_irnet_open(struct inode * inode,
ap
=
kmalloc
(
sizeof
(
*
ap
),
GFP_KERNEL
);
DABORT
(
ap
==
NULL
,
-
ENOMEM
,
FS_ERROR
,
"Can't allocate struct irnet...
\n
"
);
MOD_INC_USE_COUNT
;
/* initialize the irnet structure */
memset
(
ap
,
0
,
sizeof
(
*
ap
));
ap
->
file
=
file
;
...
...
@@ -469,7 +473,6 @@ dev_irnet_open(struct inode * inode,
{
DERROR
(
FS_ERROR
,
"Can't setup IrDA link...
\n
"
);
kfree
(
ap
);
MOD_DEC_USE_COUNT
;
return
err
;
}
...
...
@@ -514,7 +517,6 @@ dev_irnet_close(struct inode * inode,
}
kfree
(
ap
);
MOD_DEC_USE_COUNT
;
DEXIT
(
FS_TRACE
,
"
\n
"
);
return
0
;
...
...
net/irda/irnet/irnet_ppp.h
View file @
ac5ccb22
...
...
@@ -98,6 +98,7 @@ static int
/* Filesystem callbacks (to call us) */
static
struct
file_operations
irnet_device_fops
=
{
.
owner
=
THIS_MODULE
,
.
read
=
dev_irnet_read
,
.
write
=
dev_irnet_write
,
.
poll
=
dev_irnet_poll
,
...
...
net/irda/timer.c
View file @
ac5ccb22
...
...
@@ -39,8 +39,8 @@ static void irlap_query_timer_expired(void* data);
static
void
irlap_final_timer_expired
(
void
*
data
);
static
void
irlap_wd_timer_expired
(
void
*
data
);
static
void
irlap_backoff_timer_expired
(
void
*
data
);
static
void
irlap_media_busy_expired
(
void
*
data
);
/*
* Function irda_start_timer (timer, timeout)
*
...
...
@@ -50,19 +50,18 @@ static void irlap_media_busy_expired(void* data);
void
irda_start_timer
(
struct
timer_list
*
ptimer
,
int
timeout
,
void
*
data
,
TIMER_CALLBACK
callback
)
{
del_timer
(
ptimer
);
ptimer
->
data
=
(
unsigned
long
)
data
;
/*
* For most architectures void * is the same as unsigned long, but
* at least we try to use void * as long as possible. Since the
* timer functions use unsigned long, we cast the function here
*/
ptimer
->
function
=
(
void
(
*
)(
unsigned
long
))
callback
;
ptimer
->
expires
=
jiffies
+
timeout
;
ptimer
->
data
=
(
unsigned
long
)
data
;
add_timer
(
ptimer
);
/* Set new value for timer (update or add timer).
* We use mod_timer() because it's more efficient and also
* safer with respect to race conditions - Jean II */
mod_timer
(
ptimer
,
jiffies
+
timeout
);
}
void
irlap_start_slot_timer
(
struct
irlap_cb
*
self
,
int
timeout
)
...
...
@@ -136,8 +135,7 @@ void irlmp_start_idle_timer(struct lap_cb *self, int timeout)
void
irlmp_stop_idle_timer
(
struct
lap_cb
*
self
)
{
/* If timer is activated, kill it! */
if
(
timer_pending
(
&
self
->
idle_timer
))
del_timer
(
&
self
->
idle_timer
);
del_timer
(
&
self
->
idle_timer
);
}
/*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment