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
c08e4720
Commit
c08e4720
authored
Sep 18, 2002
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge mandrakesoft.com:/home/jgarzik/repo/linus-2.5
into mandrakesoft.com:/home/jgarzik/repo/irda-2.5
parents
343da22d
7567630b
Changes
37
Show whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
1405 additions
and
964 deletions
+1405
-964
drivers/net/irda/act200l.c
drivers/net/irda/act200l.c
+3
-3
drivers/net/irda/actisys.c
drivers/net/irda/actisys.c
+1
-1
drivers/net/irda/ali-ircc.c
drivers/net/irda/ali-ircc.c
+88
-84
drivers/net/irda/girbil.c
drivers/net/irda/girbil.c
+3
-3
drivers/net/irda/irda-usb.c
drivers/net/irda/irda-usb.c
+1
-1
drivers/net/irda/irport.c
drivers/net/irda/irport.c
+90
-60
drivers/net/irda/irtty.c
drivers/net/irda/irtty.c
+70
-27
drivers/net/irda/mcp2120.c
drivers/net/irda/mcp2120.c
+3
-3
drivers/net/irda/nsc-ircc.c
drivers/net/irda/nsc-ircc.c
+62
-70
drivers/net/irda/smc-ircc.c
drivers/net/irda/smc-ircc.c
+29
-15
drivers/net/irda/tekram.c
drivers/net/irda/tekram.c
+3
-3
drivers/net/irda/toshoboe.c
drivers/net/irda/toshoboe.c
+4
-4
drivers/net/irda/w83977af_ir.c
drivers/net/irda/w83977af_ir.c
+12
-15
include/net/irda/af_irda.h
include/net/irda/af_irda.h
+2
-2
include/net/irda/ircomm_tty.h
include/net/irda/ircomm_tty.h
+10
-2
include/net/irda/irlmp.h
include/net/irda/irlmp.h
+6
-9
include/net/irda/irqueue.h
include/net/irda/irqueue.h
+15
-20
include/net/irda/irtty.h
include/net/irda/irtty.h
+3
-0
include/net/irda/smc-ircc.h
include/net/irda/smc-ircc.h
+3
-1
include/net/irda/w83977af_ir.h
include/net/irda/w83977af_ir.h
+5
-0
net/irda/discovery.c
net/irda/discovery.c
+20
-14
net/irda/ircomm/ircomm_core.c
net/irda/ircomm/ircomm_core.c
+4
-5
net/irda/ircomm/ircomm_lmp.c
net/irda/ircomm/ircomm_lmp.c
+1
-1
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_param.c
+6
-5
net/irda/ircomm/ircomm_tty.c
net/irda/ircomm/ircomm_tty.c
+52
-32
net/irda/ircomm/ircomm_tty_attach.c
net/irda/ircomm/ircomm_tty_attach.c
+2
-0
net/irda/irda_device.c
net/irda/irda_device.c
+4
-4
net/irda/iriap.c
net/irda/iriap.c
+16
-9
net/irda/irias_object.c
net/irda/irias_object.c
+18
-6
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_common.c
+4
-5
net/irda/irlap.c
net/irda/irlap.c
+16
-8
net/irda/irlmp.c
net/irda/irlmp.c
+116
-97
net/irda/irlmp_event.c
net/irda/irlmp_event.c
+53
-57
net/irda/irlmp_frame.c
net/irda/irlmp_frame.c
+26
-15
net/irda/irqueue.c
net/irda/irqueue.c
+627
-372
net/irda/irsyms.c
net/irda/irsyms.c
+5
-2
net/irda/irttp.c
net/irda/irttp.c
+22
-9
No files found.
drivers/net/irda/act200l.c
View file @
c08e4720
...
...
@@ -158,7 +158,7 @@ static int act200l_change_speed(struct irda_task *task)
}
break
;
case
IRDA_TASK_CHILD_WAIT
:
WARNING
(
__FUNCTION__
"(), resetting dongle timed out!
\n
"
);
WARNING
(
"%s(), resetting dongle timed out!
\n
"
,
__FUNCTION__
);
ret
=
-
1
;
break
;
case
IRDA_TASK_CHILD_DONE
:
...
...
@@ -203,7 +203,7 @@ static int act200l_change_speed(struct irda_task *task)
self
->
speed_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
speed_task
=
NULL
;
ret
=
-
1
;
...
...
@@ -269,7 +269,7 @@ static int act200l_reset(struct irda_task *task)
self
->
reset_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
reset_task
=
NULL
;
ret
=
-
1
;
...
...
drivers/net/irda/actisys.c
View file @
c08e4720
...
...
@@ -259,7 +259,7 @@ static int actisys_reset(struct irda_task *task)
self
->
speed
=
9600
;
/* That's the default */
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
reset_task
=
NULL
;
ret
=
-
1
;
...
...
drivers/net/irda/ali-ircc.c
View file @
c08e4720
...
...
@@ -141,12 +141,12 @@ int __init ali_ircc_init(void)
int
reg
,
revision
;
int
i
=
0
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
/* Probe for all the ALi chipsets we know about */
for
(
chip
=
chips
;
chip
->
name
;
chip
++
,
i
++
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), Probing for %s ...
\n
"
,
chip
->
name
);
IRDA_DEBUG
(
2
,
"%s(), Probing for %s ...
\n
"
,
__FUNCTION__
,
chip
->
name
);
/* Try all config registers for this chip */
for
(
cfg
=
0
;
cfg
<
2
;
cfg
++
)
...
...
@@ -176,13 +176,11 @@ int __init ali_ircc_init(void)
if
(
reg
==
chip
->
cid_value
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), Chip found at 0x%03x
\n
"
,
cfg_base
);
IRDA_DEBUG
(
2
,
"%s(), Chip found at 0x%03x
\n
"
,
__FUNCTION__
,
cfg_base
);
outb
(
0x1F
,
cfg_base
);
revision
=
inb
(
cfg_base
+
1
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), Found %s chip, revision=%d
\n
"
,
IRDA_DEBUG
(
2
,
"%s(), Found %s chip, revision=%d
\n
"
,
__FUNCTION__
,
chip
->
name
,
revision
);
/*
...
...
@@ -205,15 +203,14 @@ int __init ali_ircc_init(void)
}
else
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), No %s chip at 0x%03x
\n
"
,
chip
->
name
,
cfg_base
);
IRDA_DEBUG
(
2
,
"%s(), No %s chip at 0x%03x
\n
"
,
__FUNCTION__
,
chip
->
name
,
cfg_base
);
}
/* Exit configuration */
outb
(
0xbb
,
cfg_base
);
}
}
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End -----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End -----------------
\n
"
,
__FUNCTION__
);
return
ret
;
}
...
...
@@ -227,7 +224,7 @@ static void __exit ali_ircc_cleanup(void)
{
int
i
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
pm_unregister_all
(
ali_ircc_pmproc
);
...
...
@@ -236,7 +233,7 @@ static void __exit ali_ircc_cleanup(void)
ali_ircc_close
(
dev_self
[
i
]);
}
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End -----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End -----------------
\n
"
,
__FUNCTION__
);
}
/*
...
...
@@ -251,9 +248,10 @@ static int ali_ircc_open(int i, chipio_t *info)
struct
ali_ircc_cb
*
self
;
struct
pm_dev
*
pmdev
;
int
dongle_id
;
int
ret
;
int
err
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
/* Set FIR FIFO and DMA Threshold */
if
((
ali_ircc_setup
(
info
))
==
-
1
)
...
...
@@ -263,7 +261,7 @@ static int ali_ircc_open(int i, chipio_t *info)
self
=
kmalloc
(
sizeof
(
struct
ali_ircc_cb
),
GFP_KERNEL
);
if
(
self
==
NULL
)
{
ERROR
(
__FUNCTION__
"(), can't allocate memory for control block!
\n
"
);
ERROR
(
"%s(), can't allocate memory for control block!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
}
memset
(
self
,
0
,
sizeof
(
struct
ali_ircc_cb
));
...
...
@@ -285,7 +283,7 @@ static int ali_ircc_open(int i, chipio_t *info)
/* Reserve the ioports that we need */
ret
=
check_region
(
self
->
io
.
fir_base
,
self
->
io
.
fir_ext
);
if
(
ret
<
0
)
{
WARNING
(
__FUNCTION__
"(), can't get iobase of 0x%03x
\n
"
,
WARNING
(
"%s(), can't get iobase of 0x%03x
\n
"
,
__FUNCTION__
,
self
->
io
.
fir_base
);
dev_self
[
i
]
=
NULL
;
kfree
(
self
);
...
...
@@ -339,7 +337,7 @@ static int ali_ircc_open(int i, chipio_t *info)
self
->
tx_fifo
.
tail
=
self
->
tx_buff
.
head
;
if
(
!
(
dev
=
dev_alloc
(
"irda%d"
,
&
err
)))
{
ERROR
(
__FUNCTION__
"(), dev_alloc() failed!
\n
"
);
ERROR
(
"%s(), dev_alloc() failed!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
}
...
...
@@ -358,14 +356,14 @@ static int ali_ircc_open(int i, chipio_t *info)
err
=
register_netdevice
(
dev
);
rtnl_unlock
();
if
(
err
)
{
ERROR
(
__FUNCTION__
"(), register_netdev() failed!
\n
"
);
ERROR
(
"%s(), register_netdev() failed!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
MESSAGE
(
"IrDA: Registered device %s
\n
"
,
dev
->
name
);
/* Check dongle id */
dongle_id
=
ali_ircc_read_dongle_id
(
i
,
info
);
MESSAGE
(
__FUNCTION__
"(), %s, Found dongle: %s
\n
"
,
driver_name
,
dongle_types
[
dongle_id
]);
MESSAGE
(
"%s(), %s, Found dongle: %s
\n
"
,
__FUNCTION__
,
driver_name
,
dongle_types
[
dongle_id
]);
self
->
io
.
dongle_id
=
dongle_id
;
...
...
@@ -373,7 +371,7 @@ static int ali_ircc_open(int i, chipio_t *info)
if
(
pmdev
)
pmdev
->
data
=
self
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End -----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End -----------------
\n
"
,
__FUNCTION__
);
return
0
;
}
...
...
@@ -389,7 +387,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self)
{
int
iobase
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
4
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
ASSERT
(
self
!=
NULL
,
return
-
1
;);
...
...
@@ -403,7 +401,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self)
}
/* Release the PORT that this driver is using */
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), Releasing Region %03x
\n
"
,
self
->
io
.
fir_base
);
IRDA_DEBUG
(
4
,
"%s(), Releasing Region %03x
\n
"
,
__FUNCTION__
,
self
->
io
.
fir_base
);
release_region
(
self
->
io
.
fir_base
,
self
->
io
.
fir_ext
);
if
(
self
->
tx_buff
.
head
)
...
...
@@ -415,7 +413,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self)
dev_self
[
self
->
index
]
=
NULL
;
kfree
(
self
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End -----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End -----------------
\n
"
,
__FUNCTION__
);
return
0
;
}
...
...
@@ -458,7 +456,7 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info)
int
cfg_base
=
info
->
cfg_base
;
int
hi
,
low
,
reg
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
/* Enter Configuration */
outb
(
chip
->
entr1
,
cfg_base
);
...
...
@@ -477,13 +475,13 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info)
info
->
sir_base
=
info
->
fir_base
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing fir_base=0x%03x
\n
"
,
info
->
fir_base
);
IRDA_DEBUG
(
2
,
"%s(), probing fir_base=0x%03x
\n
"
,
__FUNCTION__
,
info
->
fir_base
);
/* Read IRQ control register */
outb
(
0x70
,
cfg_base
);
reg
=
inb
(
cfg_base
+
1
);
info
->
irq
=
reg
&
0x0f
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing irq=%d
\n
"
,
info
->
irq
);
IRDA_DEBUG
(
2
,
"%s(), probing irq=%d
\n
"
,
__FUNCTION__
,
info
->
irq
);
/* Read DMA channel */
outb
(
0x74
,
cfg_base
);
...
...
@@ -491,26 +489,26 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info)
info
->
dma
=
reg
&
0x07
;
if
(
info
->
dma
==
0x04
)
WARNING
(
__FUNCTION__
"(), No DMA channel assigned !
\n
"
);
WARNING
(
"%s(), No DMA channel assigned !
\n
"
,
__FUNCTION__
);
else
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing dma=%d
\n
"
,
info
->
dma
);
IRDA_DEBUG
(
2
,
"%s(), probing dma=%d
\n
"
,
__FUNCTION__
,
info
->
dma
);
/* Read Enabled Status */
outb
(
0x30
,
cfg_base
);
reg
=
inb
(
cfg_base
+
1
);
info
->
enabled
=
(
reg
&
0x80
)
&&
(
reg
&
0x01
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing enabled=%d
\n
"
,
info
->
enabled
);
IRDA_DEBUG
(
2
,
"%s(), probing enabled=%d
\n
"
,
__FUNCTION__
,
info
->
enabled
);
/* Read Power Status */
outb
(
0x22
,
cfg_base
);
reg
=
inb
(
cfg_base
+
1
);
info
->
suspended
=
(
reg
&
0x20
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing suspended=%d
\n
"
,
info
->
suspended
);
IRDA_DEBUG
(
2
,
"%s(), probing suspended=%d
\n
"
,
__FUNCTION__
,
info
->
suspended
);
/* Exit configuration */
outb
(
0xbb
,
cfg_base
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End -----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End -----------------
\n
"
,
__FUNCTION__
);
return
0
;
}
...
...
@@ -528,7 +526,12 @@ static int ali_ircc_setup(chipio_t *info)
int
version
;
int
iobase
=
info
->
fir_base
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
/* Locking comments :
* Most operations here need to be protected. We are called before
* the device instance is created in ali_ircc_open(), therefore
* nobody can bother us - Jean II */
/* Switch to FIR space */
SIR2FIR
(
iobase
);
...
...
@@ -584,7 +587,7 @@ static int ali_ircc_setup(chipio_t *info)
// outb(UART_IER_RDI, iobase+UART_IER); //benjamin 2000/11/23 01:25PM
// Turn on the interrupts in ali_ircc_net_open
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End ------------------
\n
"
,
__FUNCTION__
);
return
0
;
}
...
...
@@ -601,7 +604,7 @@ static int ali_ircc_read_dongle_id (int i, chipio_t *info)
int
dongle_id
,
reg
;
int
cfg_base
=
info
->
cfg_base
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
/* Enter Configuration */
outb
(
chips
[
i
].
entr1
,
cfg_base
);
...
...
@@ -615,13 +618,13 @@ static int ali_ircc_read_dongle_id (int i, chipio_t *info)
outb
(
0xf0
,
cfg_base
);
reg
=
inb
(
cfg_base
+
1
);
dongle_id
=
((
reg
>>
6
)
&
0x02
)
|
((
reg
>>
5
)
&
0x01
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing dongle_id=%d, dongle_types=%s
\n
"
,
IRDA_DEBUG
(
2
,
"%s(), probing dongle_id=%d, dongle_types=%s
\n
"
,
__FUNCTION__
,
dongle_id
,
dongle_types
[
dongle_id
]);
/* Exit configuration */
outb
(
0xbb
,
cfg_base
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End ------------------
\n
"
,
__FUNCTION__
);
return
dongle_id
;
}
...
...
@@ -637,7 +640,7 @@ static void ali_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
ali_ircc_cb
*
self
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
if
(
!
dev
)
{
WARNING
(
"%s: irq %d for unknown device.
\n
"
,
driver_name
,
irq
);
...
...
@@ -656,7 +659,7 @@ static void ali_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock
(
&
self
->
lock
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End ------------------
\n
"
,
__FUNCTION__
);
}
/*
* Function ali_ircc_fir_interrupt(irq, struct ali_ircc_cb *self, regs)
...
...
@@ -669,7 +672,7 @@ static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
__u8
eir
,
OldMessageCount
;
int
iobase
,
tmp
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
iobase
=
self
->
io
.
fir_base
;
...
...
@@ -682,10 +685,10 @@ static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
//self->ier = inb(iobase+FIR_IER); 2000/12/1 04:32PM
eir
=
self
->
InterruptID
&
self
->
ier
;
/* Mask out the interesting ones */
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), self->InterruptID = %x
\n
"
,
self
->
InterruptID
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), self->LineStatus = %x
\n
"
,
self
->
LineStatus
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), self->ier = %x
\n
"
,
self
->
ier
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), eir = %x
\n
"
,
eir
);
IRDA_DEBUG
(
1
,
"%s(), self->InterruptID = %x
\n
"
,
__FUNCTION__
,
self
->
InterruptID
);
IRDA_DEBUG
(
1
,
"%s(), self->LineStatus = %x
\n
"
,
__FUNCTION__
,
self
->
LineStatus
);
IRDA_DEBUG
(
1
,
"%s(), self->ier = %x
\n
"
,
__FUNCTION__
,
self
->
ier
);
IRDA_DEBUG
(
1
,
"%s(), eir = %x
\n
"
,
__FUNCTION__
,
eir
);
/* Disable interrupts */
SetCOMInterrupts
(
self
,
FALSE
);
...
...
@@ -696,7 +699,7 @@ static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
{
if
(
self
->
io
.
direction
==
IO_XMIT
)
/* TX */
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ******* IIR_EOM (Tx) *******
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ******* IIR_EOM (Tx) *******
\n
"
,
__FUNCTION__
);
if
(
ali_ircc_dma_xmit_complete
(
self
))
{
...
...
@@ -715,23 +718,23 @@ static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
}
else
/* RX */
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ******* IIR_EOM (Rx) *******
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ******* IIR_EOM (Rx) *******
\n
"
,
__FUNCTION__
);
if
(
OldMessageCount
>
((
self
->
LineStatus
+
1
)
&
0x07
))
{
self
->
rcvFramesOverflow
=
TRUE
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ******* self->rcvFramesOverflow = TRUE ********
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ******* self->rcvFramesOverflow = TRUE ********
\n
"
,
__FUNCTION__
);
}
if
(
ali_ircc_dma_receive_complete
(
self
))
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ******* receive complete ********
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ******* receive complete ********
\n
"
,
__FUNCTION__
);
self
->
ier
=
IER_EOM
;
}
else
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ******* Not receive complete ********
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ******* Not receive complete ********
\n
"
,
__FUNCTION__
);
self
->
ier
=
IER_EOM
|
IER_TIMER
;
}
...
...
@@ -744,7 +747,7 @@ static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
if
(
OldMessageCount
>
((
self
->
LineStatus
+
1
)
&
0x07
))
{
self
->
rcvFramesOverflow
=
TRUE
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ******* self->rcvFramesOverflow = TRUE *******
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ******* self->rcvFramesOverflow = TRUE *******
\n
"
,
__FUNCTION__
);
}
/* Disable Timer */
switch_bank
(
iobase
,
BANK1
);
...
...
@@ -776,7 +779,7 @@ static void ali_ircc_fir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
/* Restore Interrupt */
SetCOMInterrupts
(
self
,
TRUE
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ----------------- End ---------------
\n
"
);
IRDA_DEBUG
(
1
,
"%s(), ----------------- End ---------------
\n
"
,
__FUNCTION__
);
}
/*
...
...
@@ -790,7 +793,7 @@ static void ali_ircc_sir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
int
iobase
;
int
iir
,
lsr
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
iobase
=
self
->
io
.
sir_base
;
...
...
@@ -799,14 +802,13 @@ static void ali_ircc_sir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
/* Clear interrupt */
lsr
=
inb
(
iobase
+
UART_LSR
);
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), iir=%02x, lsr=%02x, iobase=%#x
\n
"
,
IRDA_DEBUG
(
4
,
"%s(), iir=%02x, lsr=%02x, iobase=%#x
\n
"
,
__FUNCTION__
,
iir
,
lsr
,
iobase
);
switch
(
iir
)
{
case
UART_IIR_RLSI
:
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), RLSI
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), RLSI
\n
"
,
__FUNCTION__
);
break
;
case
UART_IIR_RDI
:
/* Receive interrupt */
...
...
@@ -820,14 +822,14 @@ static void ali_ircc_sir_interrupt(int irq, struct ali_ircc_cb *self, struct pt_
}
break
;
default:
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), unhandled IIR=%#x
\n
"
,
iir
);
IRDA_DEBUG
(
0
,
"%s(), unhandled IIR=%#x
\n
"
,
__FUNCTION__
,
iir
);
break
;
}
}
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ----------------- End ------------------
\n
"
,
__FUNCTION__
);
}
...
...
@@ -842,7 +844,7 @@ static void ali_ircc_sir_receive(struct ali_ircc_cb *self)
int
boguscount
=
0
;
int
iobase
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), ---------------- Start ----------------
\n
"
,
__FUNCTION__
);
ASSERT
(
self
!=
NULL
,
return
;);
iobase
=
self
->
io
.
sir_base
;
...
...
@@ -857,7 +859,7 @@ static void ali_ircc_sir_receive(struct ali_ircc_cb *self)
/* Make sure we don't stay here to long */
if
(
boguscount
++
>
32
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), breaking!
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), breaking!
\n
"
,
__FUNCTION__
);
break
;
}
}
while
(
inb
(
iobase
+
UART_LSR
)
&
UART_LSR_DR
);
...
...
@@ -937,6 +939,9 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), setting speed = %d
\n
"
,
baud
);
/* This function *must* be called with irq off and spin-lock.
* - Jean II */
iobase
=
self
->
io
.
fir_base
;
SetCOMInterrupts
(
self
,
FALSE
);
// 2000/11/24 11:43AM
...
...
@@ -1084,7 +1089,6 @@ static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed)
struct
ali_ircc_cb
*
self
=
(
struct
ali_ircc_cb
*
)
priv
;
int
iobase
,
dongle_id
;
unsigned
long
flags
;
int
tmp
=
0
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
...
...
@@ -1092,8 +1096,7 @@ static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed)
iobase
=
self
->
io
.
fir_base
;
/* or iobase = self->io.sir_base; */
dongle_id
=
self
->
io
.
dongle_id
;
save_flags
(
flags
);
cli
();
/* We are already locked, no need to do it again */
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), Set Speed for %s , Speed = %d
\n
"
,
dongle_types
[
dongle_id
],
speed
);
...
...
@@ -1259,8 +1262,6 @@ static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed)
switch_bank
(
iobase
,
BANK0
);
restore_flags
(
flags
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
}
...
...
@@ -1440,20 +1441,26 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue
(
dev
);
/* Make sure tests *& speed change are atomic */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Note : you should make sure that speed changes are not going
* to corrupt any outgoing frame. Look at nsc-ircc for the gory
* details - Jean II */
/* Check if we need to change the speed */
speed
=
irda_get_next_speed
(
skb
);
if
((
speed
!=
self
->
io
.
speed
)
&&
(
speed
!=
-
1
))
{
/* Check for empty frame */
if
(
!
skb
->
len
)
{
ali_ircc_change_speed
(
self
,
speed
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
dev_kfree_skb
(
skb
);
return
0
;
}
else
self
->
new_speed
=
speed
;
}
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Register and copy this frame to DMA memory */
self
->
tx_fifo
.
queue
[
self
->
tx_fifo
.
free
].
start
=
self
->
tx_fifo
.
tail
;
self
->
tx_fifo
.
queue
[
self
->
tx_fifo
.
free
].
len
=
skb
->
len
;
...
...
@@ -1651,7 +1658,7 @@ static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self)
if
((
inb
(
iobase
+
FIR_LSR
)
&
LSR_FRAME_ABORT
)
==
LSR_FRAME_ABORT
)
{
ERROR
(
__FUNCTION__
"(), ********* LSR_FRAME_ABORT *********
\n
"
);
ERROR
(
"%s(), ********* LSR_FRAME_ABORT *********
\n
"
,
__FUNCTION__
);
self
->
stats
.
tx_errors
++
;
self
->
stats
.
tx_fifo_errors
++
;
}
...
...
@@ -1898,8 +1905,8 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self)
skb
=
dev_alloc_skb
(
len
+
1
);
if
(
skb
==
NULL
)
{
WARNING
(
__FUNCTION__
"
(), memory squeeze, "
"dropping frame.
\n
"
);
WARNING
(
"%s
(), memory squeeze, "
"dropping frame.
\n
"
,
__FUNCTION__
);
self
->
stats
.
rx_dropped
++
;
return
FALSE
;
...
...
@@ -1957,20 +1964,26 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue
(
dev
);
/* Make sure tests *& speed change are atomic */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Note : you should make sure that speed changes are not going
* to corrupt any outgoing frame. Look at nsc-ircc for the gory
* details - Jean II */
/* Check if we need to change the speed */
speed
=
irda_get_next_speed
(
skb
);
if
((
speed
!=
self
->
io
.
speed
)
&&
(
speed
!=
-
1
))
{
/* Check for empty frame */
if
(
!
skb
->
len
)
{
ali_ircc_change_speed
(
self
,
speed
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
dev_kfree_skb
(
skb
);
return
0
;
}
else
self
->
new_speed
=
speed
;
}
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Init tx buffer */
self
->
tx_buff
.
data
=
self
->
tx_buff
.
head
;
...
...
@@ -2016,10 +2029,6 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), %s, (cmd=0x%X)
\n
"
,
dev
->
name
,
cmd
);
/* Disable interrupts & save flags */
save_flags
(
flags
);
cli
();
switch
(
cmd
)
{
case
SIOCSBANDWIDTH
:
/* Set bandwidth */
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), SIOCSBANDWIDTH
\n
"
);
...
...
@@ -2031,7 +2040,9 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if
(
!
in_interrupt
()
&&
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
ali_ircc_change_speed
(
self
,
irq
->
ifr_baudrate
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
break
;
case
SIOCSMEDIABUSY
:
/* Set media busy */
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), SIOCSMEDIABUSY
\n
"
);
...
...
@@ -2041,14 +2052,13 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break
;
case
SIOCGRECEIVING
:
/* Check if we are receiving right now */
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), SIOCGRECEIVING
\n
"
);
/* This is protected */
irq
->
ifr_receiving
=
ali_ircc_is_receiving
(
self
);
break
;
default:
ret
=
-
EOPNOTSUPP
;
}
restore_flags
(
flags
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
return
ret
;
...
...
@@ -2219,19 +2229,16 @@ static void SetCOMInterrupts(struct ali_ircc_cb *self , unsigned char enable)
static
void
SIR2FIR
(
int
iobase
)
{
//unsigned char tmp;
unsigned
long
flags
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
save_flags
(
flags
);
cli
();
/* Already protected (change_speed() or setup()), no need to lock.
* Jean II */
outb
(
0x28
,
iobase
+
UART_MCR
);
outb
(
0x68
,
iobase
+
UART_MCR
);
outb
(
0x88
,
iobase
+
UART_MCR
);
restore_flags
(
flags
);
outb
(
0x60
,
iobase
+
FIR_MCR
);
/* Master Reset */
outb
(
0x20
,
iobase
+
FIR_MCR
);
/* Master Interrupt Enable */
...
...
@@ -2245,12 +2252,11 @@ static void SIR2FIR(int iobase)
static
void
FIR2SIR
(
int
iobase
)
{
unsigned
char
val
;
unsigned
long
flags
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ---------------- Start ----------------
\n
"
);
save_flags
(
flags
);
cli
();
/* Already protected (change_speed() or setup()), no need to lock.
* Jean II */
outb
(
0x20
,
iobase
+
FIR_MCR
);
/* IRQ to low */
outb
(
0x00
,
iobase
+
UART_IER
);
...
...
@@ -2263,8 +2269,6 @@ static void FIR2SIR(int iobase)
val
=
inb
(
iobase
+
UART_LSR
);
val
=
inb
(
iobase
+
UART_MSR
);
restore_flags
(
flags
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), ----------------- End ------------------
\n
"
);
}
...
...
drivers/net/irda/girbil.c
View file @
c08e4720
...
...
@@ -129,7 +129,7 @@ static int girbil_change_speed(struct irda_task *task)
}
break
;
case
IRDA_TASK_CHILD_WAIT
:
WARNING
(
__FUNCTION__
"(), resetting dongle timed out!
\n
"
);
WARNING
(
"%s(), resetting dongle timed out!
\n
"
,
__FUNCTION__
);
ret
=
-
1
;
break
;
case
IRDA_TASK_CHILD_DONE
:
...
...
@@ -168,7 +168,7 @@ static int girbil_change_speed(struct irda_task *task)
self
->
speed_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
speed_task
=
NULL
;
ret
=
-
1
;
...
...
@@ -221,7 +221,7 @@ static int girbil_reset(struct irda_task *task)
self
->
reset_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
reset_task
=
NULL
;
ret
=
-
1
;
...
...
drivers/net/irda/irda-usb.c
View file @
c08e4720
...
...
@@ -1171,7 +1171,7 @@ static inline int irda_usb_open(struct irda_usb_cb *self)
irda_usb_init_qos
(
self
);
/* Initialise list of skb beeing curently transmitted */
self
->
tx_list
=
hashbin_new
(
HB_
GLOBAL
);
self
->
tx_list
=
hashbin_new
(
HB_
NOLOCK
);
/* unused */
/* Allocate the buffer for speed changes */
/* Don't change this buffer size and allocation without doing
...
...
drivers/net/irda/irport.c
View file @
c08e4720
...
...
@@ -124,7 +124,7 @@ static void __exit irport_cleanup(void)
{
int
i
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
4
,
"%s()
\n
"
,
__FUNCTION__
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
dev_self
[
i
])
...
...
@@ -140,15 +140,15 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
void
*
ret
;
int
err
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
1
,
"%s()
\n
"
,
__FUNCTION__
);
/*
* Allocate new instance of the driver
*/
self
=
kmalloc
(
sizeof
(
struct
irport_cb
),
GFP_KERNEL
);
if
(
!
self
)
{
ERROR
(
__FUNCTION__
"
(), can't allocate memory for "
"control block!
\n
"
);
ERROR
(
"%s
(), can't allocate memory for "
"control block!
\n
"
,
__FUNCTION__
);
return
NULL
;
}
memset
(
self
,
0
,
sizeof
(
struct
irport_cb
));
...
...
@@ -168,8 +168,8 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
/* Lock the port that we need */
ret
=
request_region
(
self
->
io
.
sir_base
,
self
->
io
.
sir_ext
,
driver_name
);
if
(
!
ret
)
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), can't get iobase of 0x%03x
\n
"
,
self
->
io
.
sir_base
);
IRDA_DEBUG
(
0
,
"%s
(), can't get iobase of 0x%03x
\n
"
,
__FUNCTION__
,
self
->
io
.
sir_base
);
return
NULL
;
}
...
...
@@ -212,7 +212,7 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
self
->
mode
=
IRDA_IRLAP
;
if
(
!
(
dev
=
dev_alloc
(
"irda%d"
,
&
err
)))
{
ERROR
(
__FUNCTION__
"(), dev_alloc() failed!
\n
"
);
ERROR
(
"%s(), dev_alloc() failed!
\n
"
,
__FUNCTION__
);
return
NULL
;
}
self
->
netdev
=
dev
;
...
...
@@ -240,7 +240,7 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
err
=
register_netdevice
(
dev
);
rtnl_unlock
();
if
(
err
)
{
ERROR
(
__FUNCTION__
"(), register_netdev() failed!
\n
"
);
ERROR
(
"%s(), register_netdev() failed!
\n
"
,
__FUNCTION__
);
return
NULL
;
}
MESSAGE
(
"IrDA: Registered device %s
\n
"
,
dev
->
name
);
...
...
@@ -265,8 +265,8 @@ int irport_close(struct irport_cb *self)
}
/* Release the IO-port that this driver is using */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), Releasing Region %03x
\n
"
,
self
->
io
.
sir_base
);
IRDA_DEBUG
(
0
,
"%s
(), Releasing Region %03x
\n
"
,
__FUNCTION__
,
self
->
io
.
sir_base
);
release_region
(
self
->
io
.
sir_base
,
self
->
io
.
sir_ext
);
if
(
self
->
tx_buff
.
head
)
...
...
@@ -284,14 +284,13 @@ int irport_close(struct irport_cb *self)
void
irport_start
(
struct
irport_cb
*
self
)
{
unsigned
long
flags
;
int
iobase
;
iobase
=
self
->
io
.
sir_base
;
irport_stop
(
self
);
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* We can't lock, we may be called from a FIR driver - Jean II */
/* Initialize UART */
outb
(
UART_LCR_WLEN8
,
iobase
+
UART_LCR
);
/* Reset DLAB */
...
...
@@ -299,26 +298,21 @@ void irport_start(struct irport_cb *self)
/* Turn on interrups */
outb
(
UART_IER_RLSI
|
UART_IER_RDI
|
UART_IER_THRI
,
iobase
+
UART_IER
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
}
void
irport_stop
(
struct
irport_cb
*
self
)
{
unsigned
long
flags
;
int
iobase
;
iobase
=
self
->
io
.
sir_base
;
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* We can't lock, we may be called from a FIR driver - Jean II */
/* Reset UART */
outb
(
0
,
iobase
+
UART_MCR
);
/* Turn off interrupts */
outb
(
0
,
iobase
+
UART_IER
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
}
/*
...
...
@@ -329,7 +323,7 @@ void irport_stop(struct irport_cb *self)
*/
int
irport_probe
(
int
iobase
)
{
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), iobase=%#x
\n
"
,
iobase
);
IRDA_DEBUG
(
4
,
"%s(), iobase=%#x
\n
"
,
__FUNCTION__
,
iobase
);
return
0
;
}
...
...
@@ -339,27 +333,28 @@ int irport_probe(int iobase)
*
* Set speed of IrDA port to specified baudrate
*
* This function should be called with irq off and spin-lock.
*/
void
irport_change_speed
(
void
*
priv
,
__u32
speed
)
{
struct
irport_cb
*
self
=
(
struct
irport_cb
*
)
priv
;
unsigned
long
flags
;
int
iobase
;
int
fcr
;
/* FIFO control reg */
int
lcr
;
/* Line control reg */
int
divisor
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), Setting speed to: %d
\n
"
,
speed
);
ASSERT
(
self
!=
NULL
,
return
;);
IRDA_DEBUG
(
1
,
"%s(), Setting speed to: %d - iobase=%#x
\n
"
,
__FUNCTION__
,
speed
,
self
->
io
.
sir_base
);
/* We can't lock, we may be called from a FIR driver - Jean II */
iobase
=
self
->
io
.
sir_base
;
/* Update accounting for new speed */
self
->
io
.
speed
=
speed
;
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Turn off interrupts */
outb
(
0
,
iobase
+
UART_IER
);
...
...
@@ -387,9 +382,9 @@ void irport_change_speed(void *priv, __u32 speed)
outb
(
fcr
,
iobase
+
UART_FCR
);
/* Enable FIFO's */
/* Turn on interrups */
outb
(
/*UART_IER_RLSI|*/
UART_IER_RDI
/*|UART_IER_THRI*/
,
iobase
+
UART_IER
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
/* This will generate a fata interrupt storm.
* People calling us will do that properly - Jean II */
//outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER
);
}
/*
...
...
@@ -397,19 +392,33 @@ void irport_change_speed(void *priv, __u32 speed)
*
* State machine for changing speed of the device. We do it this way since
* we cannot use schedule_timeout() when we are in interrupt context
*
*/
int
__irport_change_speed
(
struct
irda_task
*
task
)
{
struct
irport_cb
*
self
;
__u32
speed
=
(
__u32
)
task
->
param
;
unsigned
long
flags
=
0
;
int
wasunlocked
=
0
;
int
ret
=
0
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), <%ld>
\n
"
,
jiffies
);
IRDA_DEBUG
(
2
,
"%s(), <%ld>
\n
"
,
__FUNCTION__
,
jiffies
);
self
=
(
struct
irport_cb
*
)
task
->
instance
;
ASSERT
(
self
!=
NULL
,
return
-
1
;);
/* Locking notes : this function may be called from irq context with
* spinlock, via irport_write_wakeup(), or from non-interrupt without
* spinlock (from the task timer). Yuck !
* This is ugly, and unsafe is the spinlock is not already aquired.
* This will be fixed when irda-task get rewritten.
* Jean II */
if
(
!
spin_is_locked
(
&
self
->
lock
))
{
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
wasunlocked
=
1
;
}
switch
(
task
->
state
)
{
case
IRDA_TASK_INIT
:
case
IRDA_TASK_WAIT
:
...
...
@@ -446,8 +455,7 @@ int __irport_change_speed(struct irda_task *task)
irda_task_next_state
(
task
,
IRDA_TASK_CHILD_DONE
);
break
;
case
IRDA_TASK_CHILD_WAIT
:
WARNING
(
__FUNCTION__
"(), changing speed of dongle timed out!
\n
"
);
WARNING
(
"%s(), changing speed of dongle timed out!
\n
"
,
__FUNCTION__
);
ret
=
-
1
;
break
;
case
IRDA_TASK_CHILD_DONE
:
...
...
@@ -457,11 +465,16 @@ int __irport_change_speed(struct irda_task *task)
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
ret
=
-
1
;
break
;
}
/* Put stuff in the sate we found them - Jean II */
if
(
wasunlocked
)
{
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
}
return
ret
;
}
...
...
@@ -480,7 +493,7 @@ static void irport_write_wakeup(struct irport_cb *self)
ASSERT
(
self
!=
NULL
,
return
;);
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
4
,
"%s()
\n
"
,
__FUNCTION__
);
iobase
=
self
->
io
.
sir_base
;
...
...
@@ -491,6 +504,9 @@ static void irport_write_wakeup(struct irport_cb *self)
self
->
tx_buff
.
data
,
self
->
tx_buff
.
len
);
self
->
tx_buff
.
data
+=
actual
;
self
->
tx_buff
.
len
-=
actual
;
/* Turn on transmit finished interrupt. */
outb
(
UART_IER_THRI
,
iobase
+
UART_IER
);
}
else
{
/*
* Now serial buffer is almost free & we can start
...
...
@@ -498,11 +514,12 @@ static void irport_write_wakeup(struct irport_cb *self)
* if we need to change the speed of the hardware
*/
if
(
self
->
new_speed
)
{
IRDA_DEBUG
(
5
,
__FUNCTION__
"(), Changing speed!
\n
"
);
IRDA_DEBUG
(
5
,
"%s(), Changing speed!
\n
"
,
__FUNCTION__
);
irda_task_execute
(
self
,
__irport_change_speed
,
irport_change_speed_complete
,
NULL
,
(
void
*
)
self
->
new_speed
);
self
->
new_speed
=
0
;
IRDA_DEBUG
(
5
,
"%s(), Speed changed!
\n
"
,
__FUNCTION__
);
}
else
{
/* Tell network layer that we want more frames */
netif_wake_queue
(
self
->
netdev
);
...
...
@@ -538,7 +555,7 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
/* Tx FIFO should be empty! */
if
(
!
(
inb
(
iobase
+
UART_LSR
)
&
UART_LSR_THRE
))
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), failed, fifo not empty!
\n
"
);
IRDA_DEBUG
(
0
,
"%s(), failed, fifo not empty!
\n
"
,
__FUNCTION__
);
return
0
;
}
...
...
@@ -563,7 +580,7 @@ static int irport_change_speed_complete(struct irda_task *task)
{
struct
irport_cb
*
self
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
1
,
"%s()
\n
"
,
__FUNCTION__
);
self
=
(
struct
irport_cb
*
)
task
->
instance
;
...
...
@@ -589,13 +606,19 @@ static void irport_timeout(struct net_device *dev)
{
struct
irport_cb
*
self
;
int
iobase
;
unsigned
long
flags
;
self
=
(
struct
irport_cb
*
)
dev
->
priv
;
iobase
=
self
->
io
.
sir_base
;
WARNING
(
"%s: transmit timed out
\n
"
,
dev
->
name
);
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
irport_start
(
self
);
self
->
change_speed
(
self
->
priv
,
self
->
io
.
speed
);
/* This will re-enable irqs */
outb
(
/*UART_IER_RLSI|*/
UART_IER_RDI
/*|UART_IER_THRI*/
,
iobase
+
UART_IER
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
dev
->
trans_start
=
jiffies
;
netif_wake_queue
(
dev
);
}
...
...
@@ -614,7 +637,7 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
int
iobase
;
s32
speed
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
1
,
"%s()
\n
"
,
__FUNCTION__
);
ASSERT
(
dev
!=
NULL
,
return
0
;);
...
...
@@ -625,22 +648,25 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue
(
dev
);
/* Make sure tests *& speed change are atomic */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Check if we need to change the speed */
speed
=
irda_get_next_speed
(
skb
);
if
((
speed
!=
self
->
io
.
speed
)
&&
(
speed
!=
-
1
))
{
/* Check for empty frame */
if
(
!
skb
->
len
)
{
/* Better go there already locked - Jean II */
irda_task_execute
(
self
,
__irport_change_speed
,
irport_change_speed_complete
,
NULL
,
(
void
*
)
speed
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
dev_kfree_skb
(
skb
);
return
0
;
}
else
self
->
new_speed
=
speed
;
}
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Init tx buffer */
self
->
tx_buff
.
data
=
self
->
tx_buff
.
head
;
...
...
@@ -685,7 +711,7 @@ static void irport_receive(struct irport_cb *self)
/* Make sure we don't stay here to long */
if
(
boguscount
++
>
32
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), breaking!
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), breaking!
\n
"
,
__FUNCTION__
);
break
;
}
}
while
(
inb
(
iobase
+
UART_LSR
)
&
UART_LSR_DR
);
...
...
@@ -705,7 +731,7 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
int
iir
,
lsr
;
if
(
!
dev
)
{
WARNING
(
__FUNCTION__
"() irq %d for unknown device.
\n
"
,
irq
);
WARNING
(
"%s() irq %d for unknown device.
\n
"
,
__FUNCTION__
,
irq
);
return
;
}
self
=
(
struct
irport_cb
*
)
dev
->
priv
;
...
...
@@ -719,13 +745,12 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* Clear interrupt */
lsr
=
inb
(
iobase
+
UART_LSR
);
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), iir=%02x, lsr=%02x, iobase=%#x
\n
"
,
iir
,
lsr
,
iobase
);
IRDA_DEBUG
(
4
,
"%s(), iir=%02x, lsr=%02x, iobase=%#x
\n
"
,
__FUNCTION__
,
iir
,
lsr
,
iobase
);
switch
(
iir
)
{
case
UART_IIR_RLSI
:
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), RLSI
\n
"
);
IRDA_DEBUG
(
2
,
"%s(), RLSI
\n
"
,
__FUNCTION__
);
break
;
case
UART_IIR_RDI
:
/* Receive interrupt */
...
...
@@ -737,7 +762,7 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irport_write_wakeup
(
self
);
break
;
default:
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), unhandled IIR=%#x
\n
"
,
iir
);
IRDA_DEBUG
(
0
,
"%s(), unhandled IIR=%#x
\n
"
,
__FUNCTION__
,
iir
);
break
;
}
...
...
@@ -771,8 +796,9 @@ int irport_net_open(struct net_device *dev)
struct
irport_cb
*
self
;
int
iobase
;
char
hwname
[
16
];
unsigned
long
flags
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
1
,
"%s()
\n
"
,
__FUNCTION__
);
ASSERT
(
dev
!=
NULL
,
return
-
1
;);
self
=
(
struct
irport_cb
*
)
dev
->
priv
;
...
...
@@ -781,12 +807,14 @@ int irport_net_open(struct net_device *dev)
if
(
request_irq
(
self
->
io
.
irq
,
self
->
interrupt
,
0
,
dev
->
name
,
(
void
*
)
dev
))
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), unable to allocate irq=%d
\n
"
,
self
->
io
.
irq
);
IRDA_DEBUG
(
0
,
"%s
(), unable to allocate irq=%d
\n
"
,
__FUNCTION__
,
self
->
io
.
irq
);
return
-
EAGAIN
;
}
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
irport_start
(
self
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
/* Give self a hardware name */
...
...
@@ -818,8 +846,9 @@ int irport_net_close(struct net_device *dev)
{
struct
irport_cb
*
self
;
int
iobase
;
unsigned
long
flags
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
4
,
"%s()
\n
"
,
__FUNCTION__
);
ASSERT
(
dev
!=
NULL
,
return
-
1
;);
self
=
(
struct
irport_cb
*
)
dev
->
priv
;
...
...
@@ -836,7 +865,9 @@ int irport_net_close(struct net_device *dev)
irlap_close
(
self
->
irlap
);
self
->
irlap
=
NULL
;
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
irport_stop
(
self
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
free_irq
(
self
->
io
.
irq
,
dev
);
...
...
@@ -860,7 +891,7 @@ void irport_wait_until_sent(struct irport_cb *self)
/* Wait until Tx FIFO is empty */
while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
IRDA_DEBUG(2,
__FUNCTION__ "(), waiting!\n"
);
IRDA_DEBUG(2,
"%s(), waiting!\n", __FUNCTION__
);
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(MSECS_TO_JIFFIES(60));
}
...
...
@@ -915,7 +946,7 @@ static int irport_raw_write(struct net_device *dev, __u8 *buf, int len)
/* Tx FIFO should be empty! */
if
(
!
(
inb
(
iobase
+
UART_LSR
)
&
UART_LSR_THRE
))
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), failed, fifo not empty!
\n
"
);
IRDA_DEBUG
(
0
,
"%s(), failed, fifo not empty!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
...
...
@@ -949,11 +980,7 @@ static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
ASSERT
(
self
!=
NULL
,
return
-
1
;);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), %s, (cmd=0x%X)
\n
"
,
dev
->
name
,
cmd
);
/* Disable interrupts & save flags */
save_flags
(
flags
);
cli
();
IRDA_DEBUG
(
2
,
"%s(), %s, (cmd=0x%X)
\n
"
,
__FUNCTION__
,
dev
->
name
,
cmd
);
switch
(
cmd
)
{
case
SIOCSBANDWIDTH
:
/* Set bandwidth */
...
...
@@ -979,14 +1006,16 @@ static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
dongle
->
write
=
irport_raw_write
;
dongle
->
set_dtr_rts
=
irport_set_dtr_rts
;
self
->
dongle
=
dongle
;
/* Now initialize the dongle! */
dongle
->
issue
->
open
(
dongle
,
&
self
->
qos
);
/* Reset dongle */
irda_task_execute
(
dongle
,
dongle
->
issue
->
reset
,
NULL
,
NULL
,
NULL
);
/* Make dongle available to driver only now to avoid
* race conditions - Jean II */
self
->
dongle
=
dongle
;
break
;
case
SIOCSMEDIABUSY
:
/* Set media busy */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
...
...
@@ -1005,14 +1034,15 @@ static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break
;
}
/* No real need to lock... */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
irport_set_dtr_rts
(
dev
,
irq
->
ifr_dtr
,
irq
->
ifr_rts
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
break
;
default:
ret
=
-
EOPNOTSUPP
;
}
restore_flags
(
flags
);
return
ret
;
}
...
...
drivers/net/irda/irtty.c
View file @
c08e4720
...
...
@@ -75,7 +75,9 @@ int __init irtty_init(void)
{
int
status
;
irtty
=
hashbin_new
(
HB_LOCAL
);
/* Probably no need to lock here because all operations done in
* open()/close() which are already safe - Jean II */
irtty
=
hashbin_new
(
HB_NOLOCK
);
if
(
irtty
==
NULL
)
{
printk
(
KERN_WARNING
"IrDA: Can't allocate irtty hashbin!
\n
"
);
return
-
ENOMEM
;
...
...
@@ -118,9 +120,8 @@ static void __exit irtty_cleanup(void)
/* Unregister tty line-discipline */
if
((
ret
=
tty_register_ldisc
(
N_IRDA
,
NULL
)))
{
ERROR
(
__FUNCTION__
"(), can't unregister line discipline (err = %d)
\n
"
,
ret
);
ERROR
(
"%s(), can't unregister line discipline (err = %d)
\n
"
,
__FUNCTION__
,
ret
);
}
/*
...
...
@@ -163,6 +164,7 @@ static int irtty_open(struct tty_struct *tty)
return
-
ENOMEM
;
}
memset
(
self
,
0
,
sizeof
(
struct
irtty_cb
));
spin_lock_init
(
&
self
->
lock
);
self
->
tty
=
tty
;
tty
->
disc_data
=
self
;
...
...
@@ -226,7 +228,7 @@ static int irtty_open(struct tty_struct *tty)
self
->
rx_buff
.
data
=
self
->
rx_buff
.
head
;
if
(
!
(
dev
=
dev_alloc
(
"irda%d"
,
&
err
)))
{
ERROR
(
__FUNCTION__
"(), dev_alloc() failed!
\n
"
);
ERROR
(
"%s(), dev_alloc() failed!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
}
...
...
@@ -245,7 +247,7 @@ static int irtty_open(struct tty_struct *tty)
err
=
register_netdevice
(
dev
);
rtnl_unlock
();
if
(
err
)
{
ERROR
(
__FUNCTION__
"(), register_netdev() failed!
\n
"
);
ERROR
(
"%s(), register_netdev() failed!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
...
...
@@ -266,6 +268,7 @@ static int irtty_open(struct tty_struct *tty)
static
void
irtty_close
(
struct
tty_struct
*
tty
)
{
struct
irtty_cb
*
self
=
(
struct
irtty_cb
*
)
tty
->
disc_data
;
unsigned
long
flags
;
/* First make sure we're connected. */
ASSERT
(
self
!=
NULL
,
return
;);
...
...
@@ -287,6 +290,11 @@ static void irtty_close(struct tty_struct *tty)
rtnl_unlock
();
}
self
=
hashbin_remove
(
irtty
,
(
int
)
self
,
NULL
);
/* Protect access to self->task and self->?x_buff - Jean II */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Remove speed changing task if any */
if
(
self
->
task
)
irda_task_delete
(
self
->
task
);
...
...
@@ -294,13 +302,12 @@ static void irtty_close(struct tty_struct *tty)
self
->
tty
=
NULL
;
self
->
magic
=
0
;
self
=
hashbin_remove
(
irtty
,
(
int
)
self
,
NULL
);
if
(
self
->
tx_buff
.
head
)
kfree
(
self
->
tx_buff
.
head
);
if
(
self
->
rx_buff
.
head
)
kfree
(
self
->
rx_buff
.
head
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
kfree
(
self
);
...
...
@@ -326,6 +333,7 @@ static void irtty_stop_receiver(struct irtty_cb *self, int stop)
else
cflag
|=
CREAD
;
/* This is unsafe, but currently under discussion - Jean II */
self
->
tty
->
termios
->
c_cflag
=
cflag
;
self
->
tty
->
driver
.
set_termios
(
self
->
tty
,
&
old_termios
);
}
...
...
@@ -378,6 +386,7 @@ static void __irtty_change_speed(struct irtty_cb *self, __u32 speed)
break
;
}
/* This is unsafe, but currently under discussion - Jean II */
self
->
tty
->
termios
->
c_cflag
=
cflag
;
self
->
tty
->
driver
.
set_termios
(
self
->
tty
,
&
old_termios
);
...
...
@@ -393,6 +402,7 @@ static void __irtty_change_speed(struct irtty_cb *self, __u32 speed)
static
int
irtty_change_speed
(
struct
irda_task
*
task
)
{
struct
irtty_cb
*
self
;
unsigned
long
flags
;
__u32
speed
=
(
__u32
)
task
->
param
;
int
ret
=
0
;
...
...
@@ -401,12 +411,17 @@ static int irtty_change_speed(struct irda_task *task)
self
=
(
struct
irtty_cb
*
)
task
->
instance
;
ASSERT
(
self
!=
NULL
,
return
-
1
;);
/* Protect access to self->task - Jean II */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Check if busy */
if
(
self
->
task
&&
self
->
task
!=
task
)
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), busy!
\n
"
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
return
MSECS_TO_JIFFIES
(
10
);
}
else
self
->
task
=
task
;
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
switch
(
task
->
state
)
{
case
IRDA_TASK_INIT
:
...
...
@@ -451,8 +466,7 @@ static int irtty_change_speed(struct irda_task *task)
irda_task_next_state
(
task
,
IRDA_TASK_CHILD_DONE
);
break
;
case
IRDA_TASK_CHILD_WAIT
:
WARNING
(
__FUNCTION__
"(), changing speed of dongle timed out!
\n
"
);
WARNING
(
"%s(), changing speed of dongle timed out!
\n
"
,
__FUNCTION__
);
ret
=
-
1
;
break
;
case
IRDA_TASK_CHILD_DONE
:
...
...
@@ -463,7 +477,7 @@ static int irtty_change_speed(struct irda_task *task)
self
->
task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
task
=
NULL
;
ret
=
-
1
;
...
...
@@ -501,6 +515,7 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
switch
(
cmd
)
{
case
TCGETS
:
case
TCGETA
:
/* Unsure about locking here, to check - Jean II */
return
n_tty_ioctl
(
tty
,
(
struct
file
*
)
file
,
cmd
,
(
unsigned
long
)
arg
);
break
;
...
...
@@ -516,15 +531,16 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
dongle
->
write
=
irtty_raw_write
;
dongle
->
set_dtr_rts
=
irtty_set_dtr_rts
;
/* Bind dongle */
self
->
dongle
=
dongle
;
/* Now initialize the dongle! */
dongle
->
issue
->
open
(
dongle
,
&
self
->
qos
);
/* Reset dongle */
irda_task_execute
(
dongle
,
dongle
->
issue
->
reset
,
NULL
,
NULL
,
NULL
);
/* Make dongle available to driver only now to avoid
* race conditions - Jean II */
self
->
dongle
=
dongle
;
break
;
case
IRTTY_IOCGET
:
ASSERT
(
self
->
netdev
!=
NULL
,
return
-
1
;);
...
...
@@ -559,6 +575,9 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
return
;
}
// Are we in interrupt context ? What locking is done ? - Jean II
//spin_lock_irqsave(&self->lock, flags);
/* Read the characters out of the buffer */
while
(
count
--
)
{
/*
...
...
@@ -589,6 +608,7 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
break
;
}
}
//spin_unlock_irqrestore(&self->lock, flags);
}
/*
...
...
@@ -626,11 +646,13 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev)
struct
irtty_cb
*
self
;
int
actual
=
0
;
__s32
speed
;
unsigned
long
flags
;
self
=
(
struct
irtty_cb
*
)
dev
->
priv
;
ASSERT
(
self
!=
NULL
,
return
0
;);
/* Lock transmit buffer */
/* Lock transmit buffer
* this serialise operations, no need to spinlock - Jean II */
netif_stop_queue
(
dev
);
/* Check if we need to change the speed */
...
...
@@ -647,6 +669,9 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev)
self
->
new_speed
=
speed
;
}
/* Protect access to self->tx_buff - Jean II */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Init tx buffer*/
self
->
tx_buff
.
data
=
self
->
tx_buff
.
head
;
...
...
@@ -667,6 +692,8 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev)
self
->
tx_buff
.
data
+=
actual
;
self
->
tx_buff
.
len
-=
actual
;
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
dev_kfree_skb
(
skb
);
return
0
;
...
...
@@ -695,6 +722,7 @@ static void irtty_write_wakeup(struct tty_struct *tty)
{
struct
irtty_cb
*
self
=
(
struct
irtty_cb
*
)
tty
->
disc_data
;
int
actual
=
0
;
unsigned
long
flags
;
/*
* First make sure we're connected.
...
...
@@ -702,6 +730,11 @@ static void irtty_write_wakeup(struct tty_struct *tty)
ASSERT
(
self
!=
NULL
,
return
;);
ASSERT
(
self
->
magic
==
IRTTY_MAGIC
,
return
;);
/* Protected via netif_stop_queue(dev); - Jean II */
/* Protect access to self->tx_buff - Jean II */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* Finished with frame? */
if
(
self
->
tx_buff
.
len
>
0
)
{
/* Write data left in transmit buffer */
...
...
@@ -710,6 +743,7 @@ static void irtty_write_wakeup(struct tty_struct *tty)
self
->
tx_buff
.
data
+=
actual
;
self
->
tx_buff
.
len
-=
actual
;
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
}
else
{
/*
* Now serial buffer is almost free & we can start
...
...
@@ -721,6 +755,9 @@ static void irtty_write_wakeup(struct tty_struct *tty)
tty
->
flags
&=
~
(
1
<<
TTY_DO_WRITE_WAKEUP
);
/* Don't change speed with irq off */
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
if
(
self
->
new_speed
)
{
IRDA_DEBUG
(
5
,
__FUNCTION__
"(), Changing speed!
\n
"
);
irda_task_execute
(
self
,
irtty_change_speed
,
...
...
@@ -755,12 +792,17 @@ static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts)
{
struct
irtty_cb
*
self
;
struct
tty_struct
*
tty
;
//unsigned long flags;
mm_segment_t
fs
;
int
arg
=
0
;
self
=
(
struct
irtty_cb
*
)
dev
->
priv
;
tty
=
self
->
tty
;
/* Was protected in ioctl handler, but the serial driver doesn't
* like it. This may need to change. - Jean II */
//spin_lock_irqsave(&self->lock, flags);
#ifdef TIOCM_OUT2
/* Not defined for ARM */
arg
=
TIOCM_OUT2
;
#endif
...
...
@@ -780,11 +822,14 @@ static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts)
fs
=
get_fs
();
set_fs
(
get_ds
());
/* This is probably unsafe, but currently under discussion - Jean II */
if
(
tty
->
driver
.
ioctl
(
tty
,
NULL
,
TIOCMSET
,
(
unsigned
long
)
&
arg
))
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), error doing ioctl!
\n
"
);
}
set_fs
(
fs
);
//spin_unlock_irqrestore(&self->lock, flags);
return
0
;
}
...
...
@@ -799,6 +844,7 @@ static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts)
int
irtty_set_mode
(
struct
net_device
*
dev
,
int
mode
)
{
struct
irtty_cb
*
self
;
unsigned
long
flags
;
self
=
(
struct
irtty_cb
*
)
dev
->
priv
;
...
...
@@ -806,6 +852,9 @@ int irtty_set_mode(struct net_device *dev, int mode)
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), mode=%s
\n
"
,
infrared_mode
[
mode
]);
/* Protect access to self->rx_buff - Jean II */
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
/* save status for driver */
self
->
mode
=
mode
;
...
...
@@ -814,6 +863,8 @@ int irtty_set_mode(struct net_device *dev, int mode)
self
->
rx_buff
.
len
=
0
;
self
->
rx_buff
.
state
=
OUTSIDE_FRAME
;
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
return
0
;
}
...
...
@@ -955,7 +1006,6 @@ static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct
if_irda_req
*
irq
=
(
struct
if_irda_req
*
)
rq
;
struct
irtty_cb
*
self
;
dongle_t
*
dongle
;
unsigned
long
flags
;
int
ret
=
0
;
ASSERT
(
dev
!=
NULL
,
return
-
1
;);
...
...
@@ -971,8 +1021,7 @@ static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* irda_device_dongle_init() can't be locked.
* irda_task_execute() doesn't need to be locked (but
* irtty_change_speed() should protect itself).
* As this driver doesn't have spinlock protection, keep
* old fashion locking :-(
* Other calls protect themselves.
* Jean II
*/
...
...
@@ -1025,20 +1074,14 @@ static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if
(
!
capable
(
CAP_NET_ADMIN
))
ret
=
-
EPERM
;
else
{
save_flags
(
flags
);
cli
();
irtty_set_dtr_rts
(
dev
,
irq
->
ifr_dtr
,
irq
->
ifr_rts
);
restore_flags
(
flags
);
}
break
;
case
SIOCSMODE
:
if
(
!
capable
(
CAP_NET_ADMIN
))
ret
=
-
EPERM
;
else
{
save_flags
(
flags
);
cli
();
irtty_set_mode
(
dev
,
irq
->
ifr_mode
);
restore_flags
(
flags
);
}
break
;
default:
...
...
drivers/net/irda/mcp2120.c
View file @
c08e4720
...
...
@@ -109,7 +109,7 @@ static int mcp2120_change_speed(struct irda_task *task)
}
break
;
case
IRDA_TASK_CHILD_WAIT
:
WARNING
(
__FUNCTION__
"(), resetting dongle timed out!
\n
"
);
WARNING
(
"%s(), resetting dongle timed out!
\n
"
,
__FUNCTION__
);
ret
=
-
1
;
break
;
case
IRDA_TASK_CHILD_DONE
:
...
...
@@ -157,7 +157,7 @@ static int mcp2120_change_speed(struct irda_task *task)
//printk("mcp2120_change_speed irda_task_wait\n");
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
speed_task
=
NULL
;
ret
=
-
1
;
...
...
@@ -212,7 +212,7 @@ static int mcp2120_reset(struct irda_task *task)
self
->
reset_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
reset_task
=
NULL
;
ret
=
-
1
;
...
...
drivers/net/irda/nsc-ircc.c
View file @
c08e4720
...
...
@@ -161,7 +161,7 @@ int __init nsc_ircc_init(void)
/* Probe for all the NSC chipsets we know about */
for
(
chip
=
chips
;
chip
->
name
;
chip
++
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), Probing for %s ...
\n
"
,
IRDA_DEBUG
(
2
,
"%s(), Probing for %s ...
\n
"
,
__FUNCTION__
,
chip
->
name
);
/* Try all config registers for this chip */
...
...
@@ -179,8 +179,7 @@ int __init nsc_ircc_init(void)
/* Read index register */
reg
=
inb
(
cfg_base
);
if
(
reg
==
0xff
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"() no chip at 0x%03x
\n
"
,
cfg_base
);
IRDA_DEBUG
(
2
,
"%s() no chip at 0x%03x
\n
"
,
__FUNCTION__
,
cfg_base
);
continue
;
}
...
...
@@ -188,9 +187,8 @@ int __init nsc_ircc_init(void)
outb
(
chip
->
cid_index
,
cfg_base
);
id
=
inb
(
cfg_base
+
1
);
if
((
id
&
chip
->
cid_mask
)
==
chip
->
cid_value
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"() Found %s chip, revision=%d
\n
"
,
chip
->
name
,
id
&
~
chip
->
cid_mask
);
IRDA_DEBUG
(
2
,
"%s() Found %s chip, revision=%d
\n
"
,
__FUNCTION__
,
chip
->
name
,
id
&
~
chip
->
cid_mask
);
/*
* If the user supplies the base address, then
* we init the chip, if not we probe the values
...
...
@@ -205,8 +203,7 @@ int __init nsc_ircc_init(void)
ret
=
0
;
i
++
;
}
else
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), Wrong chip id=0x%02x
\n
"
,
id
);
IRDA_DEBUG
(
2
,
"%s(), Wrong chip id=0x%02x
\n
"
,
__FUNCTION__
,
id
);
}
}
...
...
@@ -247,7 +244,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
void
*
ret
;
int
err
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
2
,
"%s()
\n
"
,
__FUNCTION__
);
MESSAGE
(
"%s, Found chip at base=0x%03x
\n
"
,
driver_name
,
info
->
cfg_base
);
...
...
@@ -260,8 +257,8 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
/* Allocate new instance of the driver */
self
=
kmalloc
(
sizeof
(
struct
nsc_ircc_cb
),
GFP_KERNEL
);
if
(
self
==
NULL
)
{
ERROR
(
__FUNCTION__
"
(), can't allocate memory for "
"control block!
\n
"
);
ERROR
(
"%s
(), can't allocate memory for "
"control block!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
}
memset
(
self
,
0
,
sizeof
(
struct
nsc_ircc_cb
));
...
...
@@ -282,8 +279,8 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
/* Reserve the ioports that we need */
ret
=
request_region
(
self
->
io
.
fir_base
,
self
->
io
.
fir_ext
,
driver_name
);
if
(
!
ret
)
{
WARNING
(
__FUNCTION__
"
(), can't get iobase of 0x%03x
\n
"
,
self
->
io
.
fir_base
);
WARNING
(
"%s
(), can't get iobase of 0x%03x
\n
"
,
__FUNCTION__
,
self
->
io
.
fir_base
);
dev_self
[
i
]
=
NULL
;
kfree
(
self
);
return
-
ENODEV
;
...
...
@@ -333,7 +330,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
self
->
tx_fifo
.
tail
=
self
->
tx_buff
.
head
;
if
(
!
(
dev
=
dev_alloc
(
"irda%d"
,
&
err
)))
{
ERROR
(
__FUNCTION__
"(), dev_alloc() failed!
\n
"
);
ERROR
(
"%s(), dev_alloc() failed!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
}
...
...
@@ -352,7 +349,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
err
=
register_netdevice
(
dev
);
rtnl_unlock
();
if
(
err
)
{
ERROR
(
__FUNCTION__
"(), register_netdev() failed!
\n
"
);
ERROR
(
"%s(), register_netdev() failed!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
MESSAGE
(
"IrDA: Registered device %s
\n
"
,
dev
->
name
);
...
...
@@ -388,7 +385,7 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self)
{
int
iobase
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
IRDA_DEBUG
(
4
,
"%s()
\n
"
,
__FUNCTION__
);
ASSERT
(
self
!=
NULL
,
return
-
1
;);
...
...
@@ -402,8 +399,8 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self)
}
/* Release the PORT that this driver is using */
IRDA_DEBUG
(
4
,
__FUNCTION__
"
(), Releasing Region %03x
\n
"
,
self
->
io
.
fir_base
);
IRDA_DEBUG
(
4
,
"%s
(), Releasing Region %03x
\n
"
,
__FUNCTION__
,
self
->
io
.
fir_base
);
release_region
(
self
->
io
.
fir_base
,
self
->
io
.
fir_ext
);
if
(
self
->
tx_buff
.
head
)
...
...
@@ -439,7 +436,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info)
case
0x2e8
:
outb
(
0x15
,
cfg_base
+
1
);
break
;
case
0x3f8
:
outb
(
0x16
,
cfg_base
+
1
);
break
;
case
0x2f8
:
outb
(
0x17
,
cfg_base
+
1
);
break
;
default:
ERROR
(
__FUNCTION__
"(), invalid base_address"
);
default:
ERROR
(
"%s(), invalid base_address"
,
__FUNCTION__
);
}
/* Control Signal Routing Register (CSRT) */
...
...
@@ -451,7 +448,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info)
case
9
:
temp
=
0x05
;
break
;
case
11
:
temp
=
0x06
;
break
;
case
15
:
temp
=
0x07
;
break
;
default:
ERROR
(
__FUNCTION__
"(), invalid irq"
);
default:
ERROR
(
"%s(), invalid irq"
,
__FUNCTION__
);
}
outb
(
1
,
cfg_base
);
...
...
@@ -459,7 +456,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info)
case
0
:
outb
(
0x08
+
temp
,
cfg_base
+
1
);
break
;
case
1
:
outb
(
0x10
+
temp
,
cfg_base
+
1
);
break
;
case
3
:
outb
(
0x18
+
temp
,
cfg_base
+
1
);
break
;
default:
ERROR
(
__FUNCTION__
"(), invalid dma"
);
default:
ERROR
(
"%s(), invalid dma"
,
__FUNCTION__
);
}
outb
(
2
,
cfg_base
);
/* Mode Control Register (MCTL) */
...
...
@@ -498,7 +495,7 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info)
break
;
}
info
->
sir_base
=
info
->
fir_base
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing fir_base=0x%03x
\n
"
,
IRDA_DEBUG
(
2
,
"%s(), probing fir_base=0x%03x
\n
"
,
__FUNCTION__
,
info
->
fir_base
);
/* Read control signals routing register (CSRT) */
...
...
@@ -531,7 +528,7 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info)
info
->
irq
=
15
;
break
;
}
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing irq=%d
\n
"
,
info
->
irq
);
IRDA_DEBUG
(
2
,
"%s(), probing irq=%d
\n
"
,
__FUNCTION__
,
info
->
irq
);
/* Currently we only read Rx DMA but it will also be used for Tx */
switch
((
reg
>>
3
)
&
0x03
)
{
...
...
@@ -548,7 +545,7 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info)
info
->
dma
=
3
;
break
;
}
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), probing dma=%d
\n
"
,
info
->
dma
);
IRDA_DEBUG
(
2
,
"%s(), probing dma=%d
\n
"
,
__FUNCTION__
,
info
->
dma
);
/* Read mode control register (MCTL) */
outb
(
CFG_MCTL
,
cfg_base
);
...
...
@@ -694,8 +691,8 @@ static int nsc_ircc_setup(chipio_t *info)
switch_bank
(
iobase
,
BANK3
);
version
=
inb
(
iobase
+
MID
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"
() Driver %s Found chip version %02x
\n
"
,
driver_name
,
version
);
IRDA_DEBUG
(
2
,
"%s
() Driver %s Found chip version %02x
\n
"
,
__FUNCTION__
,
driver_name
,
version
);
/* Should be 0x2? */
if
(
0x20
!=
(
version
&
0xf0
))
{
...
...
@@ -797,39 +794,39 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id)
switch
(
dongle_id
)
{
case
0x00
:
/* same as */
case
0x01
:
/* Differential serial interface */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x02
:
/* same as */
case
0x03
:
/* Reserved */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x04
:
/* Sharp RY5HD01 */
break
;
case
0x05
:
/* Reserved, but this is what the Thinkpad reports */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x06
:
/* Single-ended serial interface */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x07
:
/* Consumer-IR only */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s is not for IrDA mode
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s is not for IrDA mode
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x08
:
/* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x09
:
/* IBM31T1100 or Temic TFDS6000/TFDS6500 */
outb
(
0x28
,
iobase
+
7
);
/* Set irsl[0-2] as output */
break
;
case
0x0A
:
/* same as */
case
0x0B
:
/* Reserved */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x0C
:
/* same as */
case
0x0D
:
/* HP HSDL-1100/HSDL-2100 */
...
...
@@ -843,15 +840,15 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id)
outb
(
0x28
,
iobase
+
7
);
/* Set irsl[0-2] as output */
break
;
case
0x0F
:
/* No dongle connected */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
switch_bank
(
iobase
,
BANK0
);
outb
(
0x62
,
iobase
+
MCR
);
break
;
default:
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), invalid dongle_id %#x"
,
dongle_id
);
IRDA_DEBUG
(
0
,
"%s
(), invalid dongle_id %#x"
,
__FUNCTION__
,
dongle_id
);
}
/* IRCFG1: IRSL1 and 2 are set to IrDA mode */
...
...
@@ -870,7 +867,6 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id)
*/
static
void
nsc_ircc_change_dongle_speed
(
int
iobase
,
int
speed
,
int
dongle_id
)
{
unsigned
long
flags
;
__u8
bank
;
/* Save current bank */
...
...
@@ -883,31 +879,31 @@ static void nsc_ircc_change_dongle_speed(int iobase, int speed, int dongle_id)
switch
(
dongle_id
)
{
case
0x00
:
/* same as */
case
0x01
:
/* Differential serial interface */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x02
:
/* same as */
case
0x03
:
/* Reserved */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x04
:
/* Sharp RY5HD01 */
break
;
case
0x05
:
/* Reserved */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x06
:
/* Single-ended serial interface */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s not defined by irda yet
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s not defined by irda yet
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x07
:
/* Consumer-IR only */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s is not for IrDA mode
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s is not for IrDA mode
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
break
;
case
0x08
:
/* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
IRDA_DEBUG
(
0
,
__FUNCTION__
"
(), %s
\n
"
,
dongle_types
[
dongle_id
]);
IRDA_DEBUG
(
0
,
"%s
(), %s
\n
"
,
__FUNCTION__
,
dongle_types
[
dongle_id
]);
outb
(
0x00
,
iobase
+
4
);
if
(
speed
>
115200
)
outb
(
0x01
,
iobase
+
4
);
...
...
@@ -916,11 +912,10 @@ static void nsc_ircc_change_dongle_speed(int iobase, int speed, int dongle_id)
outb
(
0x01
,
iobase
+
4
);
if
(
speed
==
4000000
)
{
save_flags
(
flags
);
cli
();
/* There was a cli() there, but we now are already
* under spin_lock_irqsave() - JeanII */
outb
(
0x81
,
iobase
+
4
);
outb
(
0x80
,
iobase
+
4
);
restore_flags
(
flags
);
}
else
outb
(
0x00
,
iobase
+
4
);
break
;
...
...
@@ -1538,8 +1533,8 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase)
skb
=
dev_alloc_skb
(
len
+
1
);
if
(
skb
==
NULL
)
{
WARNING
(
__FUNCTION__
"
(), memory squeeze, "
"dropping frame.
\n
"
);
WARNING
(
"%s
(), memory squeeze, "
"dropping frame.
\n
"
,
__FUNCTION__
);
self
->
stats
.
rx_dropped
++
;
/* Restore bank register */
...
...
@@ -1960,33 +1955,30 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), %s, (cmd=0x%X)
\n
"
,
dev
->
name
,
cmd
);
/* Disable interrupts & save flags */
save_flags
(
flags
);
cli
();
switch
(
cmd
)
{
case
SIOCSBANDWIDTH
:
/* Set bandwidth */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret
=
-
EPERM
;
goto
out
;
break
;
}
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
nsc_ircc_change_speed
(
self
,
irq
->
ifr_baudrate
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
break
;
case
SIOCSMEDIABUSY
:
/* Set media busy */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret
=
-
EPERM
;
goto
out
;
break
;
}
irda_device_set_media_busy
(
self
->
netdev
,
TRUE
);
break
;
case
SIOCGRECEIVING
:
/* Check if we are receiving right now */
/* This is already protected */
irq
->
ifr_receiving
=
nsc_ircc_is_receiving
(
self
);
break
;
default:
ret
=
-
EOPNOTSUPP
;
}
out:
restore_flags
(
flags
);
return
ret
;
}
...
...
drivers/net/irda/smc-ircc.c
View file @
c08e4720
...
...
@@ -431,6 +431,7 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base)
struct
ircc_cb
*
self
;
struct
irport_cb
*
irport
;
unsigned
char
low
,
high
,
chip
,
config
,
dma
,
irq
,
version
;
unsigned
long
flags
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"
\n
"
);
...
...
@@ -484,7 +485,6 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base)
return
-
ENOMEM
;
}
memset
(
self
,
0
,
sizeof
(
struct
ircc_cb
));
spin_lock_init
(
&
self
->
lock
);
/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
self
->
rx_buff
.
truesize
=
4000
;
...
...
@@ -555,6 +555,9 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base)
request_region
(
self
->
io
->
fir_base
,
CHIP_IO_EXTENT
,
driver_name
);
/* Don't allow irport to change under us - Jean II */
spin_lock_irqsave
(
&
self
->
irport
->
lock
,
flags
);
/* Initialize QoS for this device */
irda_init_max_qos_capabilies
(
&
irport
->
qos
);
...
...
@@ -581,6 +584,7 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base)
self
->
netdev
->
stop
=
&
ircc_net_close
;
irport_start
(
self
->
irport
);
spin_unlock_irqrestore
(
&
self
->
irport
->
lock
,
flags
);
self
->
pmdev
=
pm_register
(
PM_SYS_DEV
,
PM_SYS_IRDA
,
ircc_pmproc
);
if
(
self
->
pmdev
)
...
...
@@ -598,6 +602,7 @@ static int __init ircc_open(unsigned int fir_base, unsigned int sir_base)
*
* Change the speed of the device
*
* This function should be called with irq off and spin-lock.
*/
static
void
ircc_change_speed
(
void
*
priv
,
u32
speed
)
{
...
...
@@ -658,6 +663,7 @@ static void ircc_change_speed(void *priv, u32 speed)
/* Make special FIR init if necessary */
if
(
speed
>
115200
)
{
/* No need to lock, already locked - Jean II */
irport_stop
(
self
->
irport
);
/* Install FIR transmit handler */
...
...
@@ -674,6 +680,7 @@ static void ircc_change_speed(void *priv, u32 speed)
}
else
{
/* Install SIR transmit handler */
dev
->
hard_start_xmit
=
&
irport_hard_xmit
;
/* No need to lock, already locked - Jean II */
irport_start
(
self
->
irport
);
IRDA_DEBUG
(
0
,
__FUNCTION__
...
...
@@ -727,20 +734,26 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue
(
dev
);
/* Make sure tests *& speed change are atomic */
spin_lock_irqsave
(
&
self
->
irport
->
lock
,
flags
);
/* Note : you should make sure that speed changes are not going
* to corrupt any outgoing frame. Look at nsc-ircc for the gory
* details - Jean II */
/* Check if we need to change the speed after this frame */
speed
=
irda_get_next_speed
(
skb
);
if
((
speed
!=
self
->
io
->
speed
)
&&
(
speed
!=
-
1
))
{
/* Check for empty frame */
if
(
!
skb
->
len
)
{
ircc_change_speed
(
self
,
speed
);
spin_unlock_irqrestore
(
&
self
->
irport
->
lock
,
flags
);
dev_kfree_skb
(
skb
);
return
0
;
}
else
self
->
new_speed
=
speed
;
}
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
memcpy
(
self
->
tx_buff
.
head
,
skb
->
data
,
skb
->
len
);
self
->
tx_buff
.
len
=
skb
->
len
;
...
...
@@ -763,7 +776,7 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
/* Transmit frame */
ircc_dma_xmit
(
self
,
iobase
,
0
);
}
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
self
->
irport
->
lock
,
flags
);
dev_kfree_skb
(
skb
);
return
0
;
...
...
@@ -936,14 +949,14 @@ static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase)
len
-=
4
;
if
((
len
<
2
)
||
(
len
>
2050
))
{
WARNING
(
__FUNCTION__
"(), bogus len=%d
\n
"
,
len
);
WARNING
(
"%s(), bogus len=%d
\n
"
,
__FUNCTION__
,
len
);
return
;
}
IRDA_DEBUG
(
2
,
__FUNCTION__
": msgcnt = %d, len=%d
\n
"
,
msgcnt
,
len
);
skb
=
dev_alloc_skb
(
len
+
1
);
if
(
!
skb
)
{
WARNING
(
__FUNCTION__
"(), memory squeeze, dropping frame.
\n
"
);
WARNING
(
"%s(), memory squeeze, dropping frame.
\n
"
,
__FUNCTION__
);
return
;
}
/* Make sure IP header gets aligned */
...
...
@@ -985,12 +998,13 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* Check if we should use the SIR interrupt handler */
if
(
self
->
io
->
speed
<
576000
)
{
/* Will spinlock itself - Jean II */
irport_interrupt
(
irq
,
dev_id
,
regs
);
return
;
}
iobase
=
self
->
io
->
fir_base
;
spin_lock
(
&
self
->
lock
);
spin_lock
(
&
self
->
irport
->
lock
);
register_bank
(
iobase
,
0
);
iir
=
inb
(
iobase
+
IRCC_IIR
);
...
...
@@ -1013,7 +1027,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
register_bank
(
iobase
,
0
);
outb
(
IRCC_IER_ACTIVE_FRAME
|
IRCC_IER_EOM
,
iobase
+
IRCC_IER
);
spin_unlock
(
&
self
->
lock
);
spin_unlock
(
&
self
->
irport
->
lock
);
}
#if 0 /* unused */
...
...
@@ -1072,7 +1086,7 @@ static int ircc_net_open(struct net_device *dev)
if
(
request_dma
(
self
->
io
->
dma
,
dev
->
name
))
{
irport_net_close
(
dev
);
WARNING
(
__FUNCTION__
"(), unable to allocate DMA=%d
\n
"
,
self
->
io
->
dma
);
WARNING
(
"%s(), unable to allocate DMA=%d
\n
"
,
__FUNCTION__
,
self
->
io
->
dma
);
return
-
EAGAIN
;
}
...
...
@@ -1093,7 +1107,7 @@ static int ircc_net_close(struct net_device *dev)
struct
ircc_cb
*
self
;
int
iobase
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"
\n
"
);
IRDA_DEBUG
(
0
,
"%s()
\n
"
,
__FUNCTION__
);
ASSERT
(
dev
!=
NULL
,
return
-
1
;);
irport
=
(
struct
irport_cb
*
)
dev
->
priv
;
...
...
@@ -1128,17 +1142,15 @@ static void ircc_suspend(struct ircc_cb *self)
static
void
ircc_wakeup
(
struct
ircc_cb
*
self
)
{
unsigned
long
flags
;
if
(
!
self
->
io
->
suspended
)
return
;
save_flags
(
flags
);
cli
();
/* The code was doing a "cli()" here, but this can't be right.
* If you need protection, do it in net_open with a spinlock
* or give a good reason. - Jean II */
ircc_net_open
(
self
->
netdev
);
restore_flags
(
flags
);
MESSAGE
(
"%s, Waking up
\n
"
,
driver_name
);
}
...
...
@@ -1174,6 +1186,7 @@ static int __exit ircc_close(struct ircc_cb *self)
iobase
=
self
->
irport
->
io
.
fir_base
;
/* This will destroy irport */
irport_close
(
self
->
irport
);
/* Stop interrupts */
...
...
@@ -1187,6 +1200,7 @@ static int __exit ircc_close(struct ircc_cb *self)
outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase+IRCC_SCE_CFGA);
outb(IRCC_CFGB_IR, iobase+IRCC_SCE_CFGB);
#endif
/* Release the PORT that this driver is using */
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), releasing 0x%03x
\n
"
,
iobase
);
...
...
drivers/net/irda/tekram.c
View file @
c08e4720
...
...
@@ -161,7 +161,7 @@ static int tekram_change_speed(struct irda_task *task)
irda_task_next_state
(
task
,
IRDA_TASK_CHILD_DONE
);
break
;
case
IRDA_TASK_CHILD_WAIT
:
WARNING
(
__FUNCTION__
"(), resetting dongle timed out!
\n
"
);
WARNING
(
"%s(), resetting dongle timed out!
\n
"
,
__FUNCTION__
);
ret
=
-
1
;
break
;
case
IRDA_TASK_CHILD_DONE
:
...
...
@@ -187,7 +187,7 @@ static int tekram_change_speed(struct irda_task *task)
self
->
speed_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
speed_task
=
NULL
;
ret
=
-
1
;
...
...
@@ -255,7 +255,7 @@ int tekram_reset(struct irda_task *task)
self
->
reset_task
=
NULL
;
break
;
default:
ERROR
(
__FUNCTION__
"(), unknown state %d
\n
"
,
task
->
state
);
ERROR
(
"%s(), unknown state %d
\n
"
,
__FUNCTION__
,
task
->
state
);
irda_task_next_state
(
task
,
IRDA_TASK_DONE
);
self
->
reset_task
=
NULL
;
ret
=
-
1
;
...
...
drivers/net/irda/toshoboe.c
View file @
c08e4720
...
...
@@ -421,8 +421,8 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
}
else
{
printk
(
KERN_INFO
__FUNCTION__
"
(), memory squeeze, dropping frame.
\n
"
);
printk
(
KERN_INFO
"
%s(), memory squeeze, dropping frame.
\n
"
,
__FUNCTION__
);
}
self
->
taskfile
->
recv
[
self
->
rxs
].
control
=
0x83
;
...
...
@@ -824,7 +824,7 @@ toshoboe_probe (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
if
(
!
(
dev
=
dev_alloc
(
"irda%d"
,
&
err
)))
{
ERROR
(
__FUNCTION__
"(), dev_alloc() failed!
\n
"
);
ERROR
(
"%s(), dev_alloc() failed!
\n
"
,
__FUNCTION__
);
err
=
-
ENOMEM
;
goto
freebufs
;
}
...
...
@@ -843,7 +843,7 @@ toshoboe_probe (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
err
=
register_netdevice
(
dev
);
rtnl_unlock
();
if
(
err
)
{
ERROR
(
__FUNCTION__
"(), register_netdev() failed!
\n
"
);
ERROR
(
"%s(), register_netdev() failed!
\n
"
,
__FUNCTION__
);
/* XXX there is not freeing for dev? */
goto
freebufs
;
}
...
...
drivers/net/irda/w83977af_ir.c
View file @
c08e4720
...
...
@@ -175,6 +175,7 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
return
-
ENOMEM
;
}
memset
(
self
,
0
,
sizeof
(
struct
w83977af_ir
));
spin_lock_init
(
&
self
->
lock
);
/* Need to store self somewhere */
dev_self
[
i
]
=
self
;
...
...
@@ -236,7 +237,7 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
self
->
rx_buff
.
data
=
self
->
rx_buff
.
head
;
if
(
!
(
dev
=
dev_alloc
(
"irda%d"
,
&
err
)))
{
ERROR
(
__FUNCTION__
"(), dev_alloc() failed!
\n
"
);
ERROR
(
"%s(), dev_alloc() failed!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
}
dev
->
priv
=
(
void
*
)
self
;
...
...
@@ -254,7 +255,7 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
err
=
register_netdevice
(
dev
);
rtnl_unlock
();
if
(
err
)
{
ERROR
(
__FUNCTION__
"(), register_netdevice() failed!
\n
"
);
ERROR
(
"%s(), register_netdevice() failed!
\n
"
,
__FUNCTION__
);
return
-
1
;
}
MESSAGE
(
"IrDA: Registered device %s
\n
"
,
dev
->
name
);
...
...
@@ -603,8 +604,7 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
switch_bank
(
iobase
,
SET2
);
outb
(
ADCR1_D_CHSW
|
/*ADCR1_DMA_F|*/
ADCR1_ADV_SL
,
iobase
+
ADCR1
);
#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
disable_dma
(
self
->
io
.
dma
);
clear_dma_ff
(
self
->
io
.
dma
);
...
...
@@ -623,7 +623,7 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
hcr
=
inb
(
iobase
+
HCR
);
outb
(
hcr
|
HCR_EN_DMA
,
iobase
+
HCR
);
enable_dma
(
self
->
io
.
dma
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
#else
outb
(
inb
(
iobase
+
HCR
)
|
HCR_EN_DMA
|
HCR_TX_WT
,
iobase
+
HCR
);
#endif
...
...
@@ -761,8 +761,7 @@ int w83977af_dma_receive(struct w83977af_ir *self)
self
->
rx_buff
.
data
=
self
->
rx_buff
.
head
;
#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
disable_dma
(
self
->
io
.
dma
);
clear_dma_ff
(
self
->
io
.
dma
);
...
...
@@ -788,7 +787,7 @@ int w83977af_dma_receive(struct w83977af_ir *self)
hcr
=
inb
(
iobase
+
HCR
);
outb
(
hcr
|
HCR_EN_DMA
,
iobase
+
HCR
);
enable_dma
(
self
->
io
.
dma
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
#else
outb
(
inb
(
iobase
+
HCR
)
|
HCR_EN_DMA
,
iobase
+
HCR
);
#endif
...
...
@@ -892,8 +891,8 @@ int w83977af_dma_receive_complete(struct w83977af_ir *self)
skb
=
dev_alloc_skb
(
len
+
1
);
if
(
skb
==
NULL
)
{
printk
(
KERN_INFO
__FUNCTION__
"
(), memory squeeze, dropping frame.
\n
"
);
printk
(
KERN_INFO
"
%s(), memory squeeze, dropping frame.
\n
"
,
__FUNCTION__
);
/* Restore set register */
outb
(
set
,
iobase
+
SSR
);
...
...
@@ -1334,9 +1333,7 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), %s, (cmd=0x%X)
\n
"
,
dev
->
name
,
cmd
);
/* Disable interrupts & save flags */
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
lock
,
flags
);
switch
(
cmd
)
{
case
SIOCSBANDWIDTH
:
/* Set bandwidth */
...
...
@@ -1360,7 +1357,7 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
ret
=
-
EOPNOTSUPP
;
}
out:
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
lock
,
flags
);
return
ret
;
}
...
...
include/net/irda/af_irda.h
View file @
c08e4720
...
...
@@ -55,8 +55,8 @@ struct irda_sock {
__u16
mask
;
/* Hint bits mask */
__u16
hints
;
/* Hint bits */
__u32
ckey
;
/* IrLMP client handle */
__u32
skey
;
/* IrLMP service handle */
void
*
ckey
;
/* IrLMP client handle */
void
*
skey
;
/* IrLMP service handle */
struct
ias_object
*
ias_obj
;
/* Our service name + lsap in IAS */
struct
iriap_cb
*
iriap
;
/* Used to query remote IAS */
...
...
include/net/irda/ircomm_tty.h
View file @
c08e4720
...
...
@@ -86,8 +86,8 @@ struct ircomm_tty_cb {
struct
iriap_cb
*
iriap
;
/* Instance used for querying remote IAS */
struct
ias_object
*
obj
;
int
skey
;
int
ckey
;
void
*
skey
;
void
*
ckey
;
struct
termios
normal_termios
;
struct
termios
callout_termios
;
...
...
@@ -104,6 +104,14 @@ struct ircomm_tty_cb {
long
pgrp
;
/* pgrp of opening process */
int
open_count
;
int
blocked_open
;
/* # of blocked opens */
/* Protect concurent access to :
* o self->open_count
* o self->ctrl_skb
* o self->tx_skb
* Maybe other things may gain to be protected as well...
* Jean II */
spinlock_t
spinlock
;
};
void
ircomm_tty_start
(
struct
tty_struct
*
tty
);
...
...
include/net/irda/irlmp.h
View file @
c08e4720
...
...
@@ -183,7 +183,6 @@ struct irlmp_cb {
hashbin_t
*
services
;
hashbin_t
*
cachelog
;
/* Current discovery log */
spinlock_t
log_lock
;
/* discovery log spinlock */
int
running
;
...
...
@@ -197,12 +196,12 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid);
void
irlmp_close_lsap
(
struct
lsap_cb
*
self
);
__u16
irlmp_service_to_hint
(
int
service
);
__u32
irlmp_register_service
(
__u16
hints
);
int
irlmp_unregister_service
(
__u32
handle
);
__u32
irlmp_register_client
(
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
void
*
irlmp_register_service
(
__u16
hints
);
int
irlmp_unregister_service
(
void
*
handle
);
void
*
irlmp_register_client
(
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK1
expir_clb
,
void
*
priv
);
int
irlmp_unregister_client
(
__u32
handle
);
int
irlmp_update_client
(
__u32
handle
,
__u16
hint_mask
,
int
irlmp_unregister_client
(
void
*
handle
);
int
irlmp_update_client
(
void
*
handle
,
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK1
expir_clb
,
void
*
priv
);
...
...
@@ -221,7 +220,7 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
struct
sk_buff
*
userdata
);
int
irlmp_disconnect_request
(
struct
lsap_cb
*
,
struct
sk_buff
*
userdata
);
void
irlmp_discovery_confirm
(
hashbin_t
*
discovery_log
,
DISCOVERY_MODE
);
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
);
void
irlmp_do_expiry
(
void
);
...
...
@@ -258,8 +257,6 @@ extern int sysctl_discovery;
extern
int
sysctl_lap_keepalive_time
;
/* in ms, default is LM_IDLE_TIMEOUT */
extern
struct
irlmp_cb
*
irlmp
;
static
inline
hashbin_t
*
irlmp_get_cachelog
(
void
)
{
return
irlmp
->
cachelog
;
}
/* Check if LAP queue is full.
* Used by IrTTP for low control, see comments in irlap.h - Jean II */
static
inline
int
irlmp_lap_tx_queue_full
(
struct
lsap_cb
*
self
)
...
...
include/net/irda/irqueue.h
View file @
c08e4720
...
...
@@ -36,12 +36,12 @@
#define NAME_SIZE 32
/*
* Hash types
* Hash types (some flags can be xored)
* See comments in irqueue.c for which one to use...
*/
#define HB_NOLOCK 0
#define HB_GLOBAL 1
#define HB_LOCAL 2
#define HB_SORTED 4
#define HB_NOLOCK 0
/* No concurent access prevention */
#define HB_LOCK 1
/* Prevent concurent write with global lock */
#define HB_SORTED 4
/* Not yet supported */
/*
* Hash defines
...
...
@@ -57,17 +57,12 @@
typedef
void
(
*
FREE_FUNC
)(
void
*
arg
);
/*
* Hashbin
*/
#define GET_HASHBIN(x) ( x & HASHBIN_MASK )
struct
irda_queue
{
struct
irda_queue
*
q_next
;
struct
irda_queue
*
q_prev
;
char
q_name
[
NAME_SIZE
];
__u32
q_hash
;
long
q_hash
;
/* Must be able to cast a (void *) */
};
typedef
struct
irda_queue
irda_queue_t
;
...
...
@@ -75,8 +70,9 @@ typedef struct hashbin_t {
__u32
magic
;
int
hb_type
;
int
hb_size
;
spinlock_t
hb_mutex
[
HASHBIN_SIZE
]
IRDA_ALIGN
;
irda_queue_t
*
hb_queue
[
HASHBIN_SIZE
]
IRDA_ALIGN
;
spinlock_t
hb_spinlock
;
/* HB_LOCK - Can be used by the user */
irda_queue_t
*
hb_queue
[
HASHBIN_SIZE
]
IRDA_ALIGN
;
irda_queue_t
*
hb_current
;
}
hashbin_t
;
...
...
@@ -84,19 +80,18 @@ typedef struct hashbin_t {
hashbin_t
*
hashbin_new
(
int
type
);
int
hashbin_delete
(
hashbin_t
*
hashbin
,
FREE_FUNC
func
);
int
hashbin_clear
(
hashbin_t
*
hashbin
,
FREE_FUNC
free_func
);
void
hashbin_insert
(
hashbin_t
*
hashbin
,
irda_queue_t
*
entry
,
__u32
hashv
,
void
hashbin_insert
(
hashbin_t
*
hashbin
,
irda_queue_t
*
entry
,
long
hashv
,
char
*
name
);
void
*
hashbin_find
(
hashbin_t
*
hashbin
,
__u32
hashv
,
char
*
name
);
void
*
hashbin_remove
(
hashbin_t
*
hashbin
,
__u32
hashv
,
char
*
name
);
void
*
hashbin_remove
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
);
void
*
hashbin_remove_first
(
hashbin_t
*
hashbin
);
void
*
hashbin_remove_this
(
hashbin_t
*
hashbin
,
irda_queue_t
*
entry
);
void
*
hashbin_find
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
);
void
*
hashbin_lock_find
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
);
void
*
hashbin_find_next
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
,
void
**
pnext
);
irda_queue_t
*
hashbin_get_first
(
hashbin_t
*
hashbin
);
irda_queue_t
*
hashbin_get_next
(
hashbin_t
*
hashbin
);
void
enqueue_last
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
);
void
enqueue_first
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
);
irda_queue_t
*
dequeue_first
(
irda_queue_t
**
queue
);
#define HASHBIN_GET_SIZE(hashbin) hashbin->hb_size
#endif
include/net/irda/irtty.h
View file @
c08e4720
...
...
@@ -62,6 +62,9 @@ struct irtty_cb {
struct
qos_info
qos
;
/* QoS capabilities for this device */
dongle_t
*
dongle
;
/* Dongle driver */
spinlock_t
lock
;
/* For serializing operations */
__u32
new_speed
;
__u32
flags
;
/* Interface flags */
...
...
include/net/irda/smc-ircc.h
View file @
c08e4720
...
...
@@ -165,7 +165,9 @@ struct ircc_cb {
struct
irport_cb
*
irport
;
spinlock_t
lock
;
/* For serializing operations */
/* Locking : half of our operations are done with irport, so we
* use the irport spinlock to make sure *everything* is properly
* synchronised - Jean II */
__u32
new_speed
;
__u32
flags
;
/* Interface flags */
...
...
include/net/irda/w83977af_ir.h
View file @
c08e4720
...
...
@@ -180,6 +180,11 @@ struct w83977af_ir {
iobuff_t
tx_buff
;
/* Transmit buffer */
iobuff_t
rx_buff
;
/* Receive buffer */
/* Note : currently locking is *very* incomplete, but this
* will get you started. Check in nsc-ircc.c for a proper
* locking strategy. - Jean II */
spinlock_t
lock
;
/* For serializing operations */
__u32
flags
;
/* Interface flags */
__u32
new_speed
;
};
...
...
net/irda/discovery.c
View file @
c08e4720
...
...
@@ -61,7 +61,7 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
/* Set time of first discovery if node is new (see below) */
new
->
first_timestamp
=
new
->
timestamp
;
spin_lock_irqsave
(
&
irlmp
->
log_
lock
,
flags
);
spin_lock_irqsave
(
&
cachelog
->
hb_spin
lock
,
flags
);
/*
* Remove all discoveries of devices that has previously been
...
...
@@ -95,13 +95,13 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
/* Insert the new and updated version */
hashbin_insert
(
cachelog
,
(
irda_queue_t
*
)
new
,
new
->
daddr
,
NULL
);
spin_unlock_irqrestore
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
cachelog
->
hb_spin
lock
,
flags
);
}
/*
* Function irlmp_add_discovery_log (cachelog, log)
*
* Merge a disovery log into the cachlog.
* Merge a disovery log into the cach
e
log.
*
*/
void
irlmp_add_discovery_log
(
hashbin_t
*
cachelog
,
hashbin_t
*
log
)
...
...
@@ -115,11 +115,17 @@ void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log)
* discovery, so restart discovery again with just the half timeout
* of the normal one.
*/
/* Well... It means that there was nobody out there - Jean II */
if
(
log
==
NULL
)
{
/* irlmp_start_discovery_timer(irlmp, 150); */
return
;
}
/*
* Locking : we are the only owner of this discovery log, so
* no need to lock it.
* We just need to lock the global log in irlmp_add_discovery().
*/
discovery
=
(
discovery_t
*
)
hashbin_remove_first
(
log
);
while
(
discovery
!=
NULL
)
{
irlmp_add_discovery
(
cachelog
,
discovery
);
...
...
@@ -146,7 +152,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
spin_lock_irqsave
(
&
irlmp
->
log_
lock
,
flags
);
spin_lock_irqsave
(
&
log
->
hb_spin
lock
,
flags
);
discovery
=
(
discovery_t
*
)
hashbin_get_first
(
log
);
while
(
discovery
!=
NULL
)
{
...
...
@@ -169,7 +175,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
}
}
spin_unlock_irqrestore
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
log
->
hb_spin
lock
,
flags
);
}
/*
...
...
@@ -230,13 +236,13 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 m
return
NULL
;
/* Save spin lock - spinlock should be discovery specific */
spin_lock_irqsave
(
&
irlmp
->
log_
lock
,
flags
);
spin_lock_irqsave
(
&
log
->
hb_spin
lock
,
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
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
log
->
hb_spin
lock
,
flags
);
return
NULL
;
}
...
...
@@ -257,7 +263,7 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, __u16 m
discovery
=
(
discovery_t
*
)
hashbin_get_next
(
log
);
}
spin_unlock_irqrestore
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
log
->
hb_spin
lock
,
flags
);
/* Get the actual number of device in the buffer and return */
*
pn
=
i
;
...
...
@@ -276,7 +282,7 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr)
unsigned
long
flags
;
discovery_t
*
d
;
spin_lock_irqsave
(
&
irlmp
->
log_
lock
,
flags
);
spin_lock_irqsave
(
&
cachelog
->
hb_spin
lock
,
flags
);
/* Look at all discoveries for that link */
d
=
(
discovery_t
*
)
hashbin_get_first
(
cachelog
);
...
...
@@ -288,13 +294,13 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr)
if
(
strcmp
(
name
,
d
->
nickname
)
==
0
)
{
*
saddr
=
d
->
saddr
;
spin_unlock_irqrestore
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
cachelog
->
hb_spin
lock
,
flags
);
return
d
->
daddr
;
}
d
=
(
discovery_t
*
)
hashbin_get_next
(
cachelog
);
}
spin_unlock_irqrestore
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
cachelog
->
hb_spin
lock
,
flags
);
return
0
;
}
...
...
@@ -310,7 +316,7 @@ int discovery_proc_read(char *buf, char **start, off_t offset, int length,
{
discovery_t
*
discovery
;
unsigned
long
flags
;
hashbin_t
*
cachelog
=
irlmp
_get_cachelog
()
;
hashbin_t
*
cachelog
=
irlmp
->
cachelog
;
int
len
=
0
;
if
(
!
irlmp
)
...
...
@@ -318,7 +324,7 @@ int discovery_proc_read(char *buf, char **start, off_t offset, int length,
len
=
sprintf
(
buf
,
"IrLMP: Discovery log:
\n\n
"
);
spin_lock_irqsave
(
&
irlmp
->
log_
lock
,
flags
);
spin_lock_irqsave
(
&
cachelog
->
hb_spin
lock
,
flags
);
discovery
=
(
discovery_t
*
)
hashbin_get_first
(
cachelog
);
while
((
discovery
!=
NULL
)
&&
(
len
<
length
))
{
...
...
@@ -362,7 +368,7 @@ int discovery_proc_read(char *buf, char **start, off_t offset, int length,
discovery
=
(
discovery_t
*
)
hashbin_get_next
(
cachelog
);
}
spin_unlock_irqrestore
(
&
irlmp
->
log_
lock
,
flags
);
spin_unlock_irqrestore
(
&
cachelog
->
hb_spin
lock
,
flags
);
return
len
;
}
net/irda/ircomm/ircomm_core.c
View file @
c08e4720
...
...
@@ -61,7 +61,7 @@ hashbin_t *ircomm = NULL;
int
__init
ircomm_init
(
void
)
{
ircomm
=
hashbin_new
(
HB_LOC
AL
);
ircomm
=
hashbin_new
(
HB_LOC
K
);
if
(
ircomm
==
NULL
)
{
ERROR
(
__FUNCTION__
"(), can't allocate hashbin!
\n
"
);
return
-
ENOMEM
;
...
...
@@ -505,11 +505,10 @@ int ircomm_proc_read(char *buf, char **start, off_t offset, int len)
struct
ircomm_cb
*
self
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
len
=
0
;
spin_lock_irqsave
(
&
ircomm
->
hb_spinlock
,
flags
);
self
=
(
struct
ircomm_cb
*
)
hashbin_get_first
(
ircomm
);
while
(
self
!=
NULL
)
{
ASSERT
(
self
->
magic
==
IRCOMM_MAGIC
,
break
;);
...
...
@@ -535,7 +534,7 @@ int ircomm_proc_read(char *buf, char **start, off_t offset, int len)
self
=
(
struct
ircomm_cb
*
)
hashbin_get_next
(
ircomm
);
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
ircomm
->
hb_spinlock
,
flags
);
return
len
;
}
...
...
net/irda/ircomm/ircomm_lmp.c
View file @
c08e4720
...
...
@@ -177,7 +177,7 @@ void ircomm_lmp_flow_control(struct sk_buff *skb)
line
=
cb
->
line
;
self
=
(
struct
ircomm_cb
*
)
hashbin_find
(
ircomm
,
line
,
NULL
);
self
=
(
struct
ircomm_cb
*
)
hashbin_
lock_
find
(
ircomm
,
line
,
NULL
);
if
(
!
self
)
{
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), didn't find myself
\n
"
);
return
;
...
...
net/irda/ircomm/ircomm_param.c
View file @
c08e4720
...
...
@@ -99,6 +99,8 @@ pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 };
*/
int
ircomm_param_flush
(
struct
ircomm_tty_cb
*
self
)
{
/* we should lock here, but I guess this function is unused...
* Jean II */
if
(
self
->
ctrl_skb
)
{
ircomm_control_request
(
self
->
ircomm
,
self
->
ctrl_skb
);
self
->
ctrl_skb
=
NULL
;
...
...
@@ -132,14 +134,13 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
if
(
self
->
service_type
==
IRCOMM_3_WIRE_RAW
)
return
0
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
skb
=
self
->
ctrl_skb
;
if
(
!
skb
)
{
skb
=
dev_alloc_skb
(
256
);
if
(
!
skb
)
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
return
-
ENOMEM
;
}
...
...
@@ -154,12 +155,12 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
&
ircomm_param_info
);
if
(
count
<
0
)
{
WARNING
(
__FUNCTION__
"(), no room for parameter!
\n
"
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
return
-
1
;
}
skb_put
(
skb
,
count
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), skb->len=%d
\n
"
,
skb
->
len
);
...
...
net/irda/ircomm/ircomm_tty.c
View file @
c08e4720
...
...
@@ -90,7 +90,7 @@ hashbin_t *ircomm_tty = NULL;
*/
int
__init
ircomm_tty_init
(
void
)
{
ircomm_tty
=
hashbin_new
(
HB_LOC
AL
);
ircomm_tty
=
hashbin_new
(
HB_LOC
K
);
if
(
ircomm_tty
==
NULL
)
{
ERROR
(
__FUNCTION__
"(), can't allocate hashbin!
\n
"
);
return
-
ENOMEM
;
...
...
@@ -308,22 +308,25 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
IRDA_DEBUG
(
2
,
"%s(%d):block_til_ready before block on %s open_count=%d
\n
"
,
__FILE__
,
__LINE__
,
tty
->
driver
.
name
,
self
->
open_count
);
save_flags
(
flags
);
cli
();
/* As far as I can see, we protect open_count - Jean II */
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
if
(
!
tty_hung_up_p
(
filp
))
{
extra_count
=
1
;
self
->
open_count
--
;
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
self
->
blocked_open
++
;
while
(
1
)
{
if
(
!
(
self
->
flags
&
ASYNC_CALLOUT_ACTIVE
)
&&
(
tty
->
termios
->
c_cflag
&
CBAUD
))
{
save_flags
(
flags
);
cli
();
/* Here, we use to lock those two guys, but
* as ircomm_param_request() does it itself,
* I don't see the point (and I see the deadlock).
* Jean II */
self
->
settings
.
dte
|=
IRCOMM_RTS
+
IRCOMM_DTR
;
ircomm_param_request
(
self
,
IRCOMM_DTE
,
TRUE
);
restore_flags
(
flags
);
}
current
->
state
=
TASK_INTERRUPTIBLE
;
...
...
@@ -361,8 +364,12 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
__set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
self
->
open_wait
,
&
wait
);
if
(
extra_count
)
if
(
extra_count
)
{
/* ++ is not atomic, so this should be protected - Jean II */
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
self
->
open_count
++
;
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
}
self
->
blocked_open
--
;
IRDA_DEBUG
(
1
,
"%s(%d):block_til_ready after blocking on %s open_count=%d
\n
"
,
...
...
@@ -385,6 +392,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
{
struct
ircomm_tty_cb
*
self
;
unsigned
int
line
;
unsigned
long
flags
;
int
ret
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"()
\n
"
);
...
...
@@ -397,7 +405,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
}
/* Check if instance already exists */
self
=
hashbin_find
(
ircomm_tty
,
line
,
NULL
);
self
=
hashbin_
lock_
find
(
ircomm_tty
,
line
,
NULL
);
if
(
!
self
)
{
/* No, so make new instance */
self
=
kmalloc
(
sizeof
(
struct
ircomm_tty_cb
),
GFP_KERNEL
);
...
...
@@ -423,6 +431,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
init_timer
(
&
self
->
watchdog_timer
);
init_waitqueue_head
(
&
self
->
open_wait
);
init_waitqueue_head
(
&
self
->
close_wait
);
spin_lock_init
(
&
self
->
spinlock
);
/*
* Force TTY into raw mode by default which is usually what
...
...
@@ -435,10 +444,13 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
/* Insert into hash */
hashbin_insert
(
ircomm_tty
,
(
irda_queue_t
*
)
self
,
line
,
NULL
);
}
/* ++ is not atomic, so this should be protected - Jean II */
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
self
->
open_count
++
;
tty
->
driver_data
=
self
;
self
->
tty
=
tty
;
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), %s%d, count = %d
\n
"
,
tty
->
driver
.
name
,
self
->
line
,
self
->
open_count
);
...
...
@@ -526,12 +538,11 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
ASSERT
(
self
!=
NULL
,
return
;);
ASSERT
(
self
->
magic
==
IRCOMM_TTY_MAGIC
,
return
;);
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
if
(
tty_hung_up_p
(
filp
))
{
MOD_DEC_USE_COUNT
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), returning 1
\n
"
);
return
;
...
...
@@ -559,13 +570,19 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
}
if
(
self
->
open_count
)
{
MOD_DEC_USE_COUNT
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), open count > 0
\n
"
);
return
;
}
self
->
flags
|=
ASYNC_CLOSING
;
/* We need to unlock here (we were unlocking at the end of this
* function), because tty_wait_until_sent() may schedule.
* I don't know if the rest should be locked somehow,
* so someone should check. - Jean II */
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
/*
* Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
...
...
@@ -597,7 +614,6 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
wake_up_interruptible
(
&
self
->
close_wait
);
MOD_DEC_USE_COUNT
;
restore_flags
(
flags
);
}
/*
...
...
@@ -645,13 +661,12 @@ static void ircomm_tty_do_softint(void *private_)
return
;
/* Unlink control buffer */
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
ctrl_skb
=
self
->
ctrl_skb
;
self
->
ctrl_skb
=
NULL
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
/* Flush control buffer if any */
if
(
ctrl_skb
&&
self
->
flow
==
FLOW_START
)
...
...
@@ -661,13 +676,12 @@ static void ircomm_tty_do_softint(void *private_)
return
;
/* Unlink transmit buffer */
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
skb
=
self
->
tx_skb
;
self
->
tx_skb
=
NULL
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
/* Flush transmit buffer if any */
if
(
skb
)
...
...
@@ -720,8 +734,7 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
return
len
;
}
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
/* Fetch current transmit buffer */
skb
=
self
->
tx_skb
;
...
...
@@ -768,7 +781,7 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
skb
=
dev_alloc_skb
(
self
->
max_data_size
+
self
->
max_header_size
);
if
(
!
skb
)
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
return
-
ENOBUFS
;
}
skb_reserve
(
skb
,
self
->
max_header_size
);
...
...
@@ -785,7 +798,7 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
len
+=
size
;
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
/*
* Schedule a new thread which will transmit the frame as soon
...
...
@@ -824,13 +837,12 @@ static int ircomm_tty_write_room(struct tty_struct *tty)
(
self
->
max_header_size
==
IRCOMM_TTY_HDR_UNITIALISED
))
ret
=
0
;
else
{
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
if
(
self
->
tx_skb
)
ret
=
self
->
max_data_size
-
self
->
tx_skb
->
len
;
else
ret
=
self
->
max_data_size
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
}
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), ret=%d
\n
"
,
ret
);
...
...
@@ -946,13 +958,12 @@ static int ircomm_tty_chars_in_buffer(struct tty_struct *tty)
ASSERT
(
self
!=
NULL
,
return
-
1
;);
ASSERT
(
self
->
magic
==
IRCOMM_TTY_MAGIC
,
return
-
1
;);
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
if
(
self
->
tx_skb
)
len
=
self
->
tx_skb
->
len
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
return
len
;
}
...
...
@@ -969,8 +980,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
if
(
!
(
self
->
flags
&
ASYNC_INITIALIZED
))
return
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
del_timer
(
&
self
->
watchdog_timer
);
...
...
@@ -994,7 +1004,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
}
self
->
flags
&=
~
ASYNC_INITIALIZED
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
}
/*
...
...
@@ -1007,6 +1017,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
static
void
ircomm_tty_hangup
(
struct
tty_struct
*
tty
)
{
struct
ircomm_tty_cb
*
self
=
(
struct
ircomm_tty_cb
*
)
tty
->
driver_data
;
unsigned
long
flags
;
IRDA_DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
...
...
@@ -1019,9 +1030,13 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
/* ircomm_tty_flush_buffer(tty); */
ircomm_tty_shutdown
(
self
);
/* I guess we need to lock here - Jean II */
spin_lock_irqsave
(
&
self
->
spinlock
,
flags
);
self
->
flags
&=
~
(
ASYNC_NORMAL_ACTIVE
|
ASYNC_CALLOUT_ACTIVE
);
self
->
tty
=
0
;
self
->
open_count
=
0
;
spin_unlock_irqrestore
(
&
self
->
spinlock
,
flags
);
wake_up_interruptible
(
&
self
->
open_wait
);
}
...
...
@@ -1362,11 +1377,14 @@ static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
struct
ircomm_tty_cb
*
self
;
int
count
=
0
,
l
;
off_t
begin
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ircomm_tty
->
hb_spinlock
,
flags
);
self
=
(
struct
ircomm_tty_cb
*
)
hashbin_get_first
(
ircomm_tty
);
while
((
self
!=
NULL
)
&&
(
count
<
4000
))
{
if
(
self
->
magic
!=
IRCOMM_TTY_MAGIC
)
return
0
;
break
;
l
=
ircomm_tty_line_info
(
self
,
buf
+
count
);
count
+=
l
;
...
...
@@ -1381,6 +1399,8 @@ static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
}
*
eof
=
1
;
done:
spin_unlock_irqrestore
(
&
ircomm_tty
->
hb_spinlock
,
flags
);
if
(
offset
>=
count
+
begin
)
return
0
;
*
start
=
buf
+
(
offset
-
begin
);
...
...
net/irda/ircomm/ircomm_tty_attach.c
View file @
c08e4720
...
...
@@ -331,6 +331,8 @@ static void ircomm_tty_discovery_indication(discovery_t *discovery,
info
.
daddr
=
discovery
->
daddr
;
info
.
saddr
=
discovery
->
saddr
;
/* FIXME. We probably need to use hashbin_find_next(), but we first
* need to ensure that "line" is unique. - Jean II */
self
=
(
struct
ircomm_tty_cb
*
)
hashbin_get_first
(
ircomm_tty
);
while
(
self
!=
NULL
)
{
ASSERT
(
self
->
magic
==
IRCOMM_TTY_MAGIC
,
return
;);
...
...
net/irda/irda_device.c
View file @
c08e4720
...
...
@@ -91,13 +91,13 @@ int irda_device_proc_read(char *buf, char **start, off_t offset, int len,
int
__init
irda_device_init
(
void
)
{
dongles
=
hashbin_new
(
HB_
GLOBAL
);
dongles
=
hashbin_new
(
HB_
LOCK
);
if
(
dongles
==
NULL
)
{
printk
(
KERN_WARNING
"IrDA: Can't allocate dongles hashbin!
\n
"
);
return
-
ENOMEM
;
}
tasks
=
hashbin_new
(
HB_
GLOBAL
);
tasks
=
hashbin_new
(
HB_
LOCK
);
if
(
tasks
==
NULL
)
{
printk
(
KERN_WARNING
"IrDA: Can't allocate tasks hashbin!
\n
"
);
return
-
ENOMEM
;
...
...
@@ -438,7 +438,7 @@ dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
}
#endif
if
(
!
(
reg
=
hashbin_find
(
dongles
,
type
,
NULL
)))
{
if
(
!
(
reg
=
hashbin_
lock_
find
(
dongles
,
type
,
NULL
)))
{
ERROR
(
"IrDA: Unable to find requested dongle
\n
"
);
return
NULL
;
}
...
...
@@ -477,7 +477,7 @@ int irda_device_dongle_cleanup(dongle_t *dongle)
int
irda_device_register_dongle
(
struct
dongle_reg
*
new
)
{
/* Check if this dongle has been registred before */
if
(
hashbin_find
(
dongles
,
new
->
type
,
NULL
))
{
if
(
hashbin_
lock_
find
(
dongles
,
new
->
type
,
NULL
))
{
MESSAGE
(
"%s: Dongle already registered
\n
"
,
__FUNCTION__
);
return
0
;
}
...
...
net/irda/iriap.c
View file @
c08e4720
...
...
@@ -58,7 +58,7 @@ static const char *ias_charset_types[] = {
#endif
/* CONFIG_IRDA_DEBUG */
static
hashbin_t
*
iriap
=
NULL
;
static
__u32
service_handle
;
static
void
*
service_handle
;
extern
char
*
lmp_reasons
[];
...
...
@@ -91,11 +91,12 @@ int __init iriap_init(void)
__u16
hints
;
/* Allocate master array */
iriap
=
hashbin_new
(
HB_LOC
AL
);
iriap
=
hashbin_new
(
HB_LOC
K
);
if
(
!
iriap
)
return
-
ENOMEM
;
objects
=
hashbin_new
(
HB_LOCAL
);
/* Object repository - defined in irias_object.c */
objects
=
hashbin_new
(
HB_LOCK
);
if
(
!
objects
)
{
WARNING
(
"%s: Can't allocate objects hashbin!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
...
...
@@ -182,7 +183,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
init_timer
(
&
self
->
watchdog_timer
);
hashbin_insert
(
iriap
,
(
irda_queue_t
*
)
self
,
(
int
)
self
,
NULL
);
hashbin_insert
(
iriap
,
(
irda_queue_t
*
)
self
,
(
long
)
self
,
NULL
);
/* Initialize state machines */
iriap_next_client_state
(
self
,
S_DISCONNECT
);
...
...
@@ -235,7 +236,7 @@ void iriap_close(struct iriap_cb *self)
self
->
lsap
=
NULL
;
}
entry
=
(
struct
iriap_cb
*
)
hashbin_remove
(
iriap
,
(
int
)
self
,
NULL
);
entry
=
(
struct
iriap_cb
*
)
hashbin_remove
(
iriap
,
(
long
)
self
,
NULL
);
ASSERT
(
entry
==
self
,
return
;);
__iriap_close
(
self
);
...
...
@@ -973,13 +974,12 @@ int irias_proc_read(char *buf, char **start, off_t offset, int len)
ASSERT
(
objects
!=
NULL
,
return
0
;);
save_flags
(
flags
);
cli
();
len
=
0
;
len
+=
sprintf
(
buf
+
len
,
"LM-IAS Objects:
\n
"
);
spin_lock_irqsave
(
&
objects
->
hb_spinlock
,
flags
);
/* List all objects */
obj
=
(
struct
ias_object
*
)
hashbin_get_first
(
objects
);
while
(
obj
!=
NULL
)
{
...
...
@@ -989,6 +989,11 @@ int irias_proc_read(char *buf, char **start, off_t offset, int len)
len
+=
sprintf
(
buf
+
len
,
"id=%d"
,
obj
->
id
);
len
+=
sprintf
(
buf
+
len
,
"
\n
"
);
/* Careful for priority inversions here !
* All other uses of attrib spinlock are independant of
* the object spinlock, so we are safe. Jean II */
spin_lock
(
&
obj
->
attribs
->
hb_spinlock
);
/* List all attributes for this object */
attrib
=
(
struct
ias_attrib
*
)
hashbin_get_first
(
obj
->
attribs
);
...
...
@@ -1025,9 +1030,11 @@ int irias_proc_read(char *buf, char **start, off_t offset, int len)
attrib
=
(
struct
ias_attrib
*
)
hashbin_get_next
(
obj
->
attribs
);
}
spin_unlock
(
&
obj
->
attribs
->
hb_spinlock
);
obj
=
(
struct
ias_object
*
)
hashbin_get_next
(
objects
);
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
objects
->
hb_spinlock
,
flags
);
return
len
;
}
...
...
net/irda/irias_object.c
View file @
c08e4720
...
...
@@ -93,7 +93,10 @@ struct ias_object *irias_new_object( char *name, int id)
obj
->
name
=
strndup
(
name
,
IAS_MAX_CLASSNAME
);
obj
->
id
=
id
;
obj
->
attribs
=
hashbin_new
(
HB_LOCAL
);
/* Locking notes : the attrib spinlock has lower precendence
* than the objects spinlock. Never grap the objects spinlock
* while holding any attrib spinlock (risk of deadlock). Jean II */
obj
->
attribs
=
hashbin_new
(
HB_LOCK
);
return
obj
;
}
...
...
@@ -147,7 +150,7 @@ int irias_delete_object(struct ias_object *obj)
ASSERT
(
obj
!=
NULL
,
return
-
1
;);
ASSERT
(
obj
->
magic
==
IAS_OBJECT_MAGIC
,
return
-
1
;);
node
=
hashbin_remove
(
objects
,
0
,
obj
->
name
);
node
=
hashbin_remove
_this
(
objects
,
(
irda_queue_t
*
)
obj
);
if
(
!
node
)
return
0
;
/* Already removed */
...
...
@@ -172,7 +175,7 @@ int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib)
ASSERT
(
attrib
!=
NULL
,
return
-
1
;);
/* Remove attribute from object */
node
=
hashbin_remove
(
obj
->
attribs
,
0
,
attrib
->
name
);
node
=
hashbin_remove
_this
(
obj
->
attribs
,
(
irda_queue_t
*
)
attrib
);
if
(
!
node
)
return
0
;
/* Already removed or non-existent */
...
...
@@ -211,7 +214,8 @@ struct ias_object *irias_find_object(char *name)
{
ASSERT
(
name
!=
NULL
,
return
NULL
;);
return
hashbin_find
(
objects
,
0
,
name
);
/* Unsafe (locking), object might change */
return
hashbin_lock_find
(
objects
,
0
,
name
);
}
/*
...
...
@@ -228,10 +232,11 @@ struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
ASSERT
(
obj
->
magic
==
IAS_OBJECT_MAGIC
,
return
NULL
;);
ASSERT
(
name
!=
NULL
,
return
NULL
;);
attrib
=
hashbin_find
(
obj
->
attribs
,
0
,
name
);
attrib
=
hashbin_
lock_
find
(
obj
->
attribs
,
0
,
name
);
if
(
attrib
==
NULL
)
return
NULL
;
/* Unsafe (locking), attrib might change */
return
attrib
;
}
...
...
@@ -267,26 +272,32 @@ int irias_object_change_attribute(char *obj_name, char *attrib_name,
{
struct
ias_object
*
obj
;
struct
ias_attrib
*
attrib
;
unsigned
long
flags
;
/* Find object */
obj
=
hashbin_find
(
objects
,
0
,
obj_name
);
obj
=
hashbin_
lock_
find
(
objects
,
0
,
obj_name
);
if
(
obj
==
NULL
)
{
WARNING
(
"%s: Unable to find object: %s
\n
"
,
__FUNCTION__
,
obj_name
);
return
-
1
;
}
/* Slightly unsafe (obj might get removed under us) */
spin_lock_irqsave
(
&
obj
->
attribs
->
hb_spinlock
,
flags
);
/* Find attribute */
attrib
=
hashbin_find
(
obj
->
attribs
,
0
,
attrib_name
);
if
(
attrib
==
NULL
)
{
WARNING
(
"%s: Unable to find attribute: %s
\n
"
,
__FUNCTION__
,
attrib_name
);
spin_unlock_irqrestore
(
&
obj
->
attribs
->
hb_spinlock
,
flags
);
return
-
1
;
}
if
(
attrib
->
value
->
type
!=
new_value
->
type
)
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), changing value type not allowed!
\n
"
);
spin_unlock_irqrestore
(
&
obj
->
attribs
->
hb_spinlock
,
flags
);
return
-
1
;
}
...
...
@@ -297,6 +308,7 @@ int irias_object_change_attribute(char *obj_name, char *attrib_name,
attrib
->
value
=
new_value
;
/* Success */
spin_unlock_irqrestore
(
&
obj
->
attribs
->
hb_spinlock
,
flags
);
return
0
;
}
...
...
net/irda/irlan/irlan_common.c
View file @
c08e4720
...
...
@@ -124,7 +124,7 @@ int __init irlan_init(void)
IRDA_DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
/* Allocate master structure */
irlan
=
hashbin_new
(
HB_LOC
AL
);
irlan
=
hashbin_new
(
HB_LOC
K
);
/* protect from /proc */
if
(
irlan
==
NULL
)
{
printk
(
KERN_WARNING
"IrLAN: Can't allocate hashbin!
\n
"
);
return
-
ENOMEM
;
...
...
@@ -1089,11 +1089,10 @@ static int irlan_proc_read(char *buf, char **start, off_t offset, int len)
unsigned
long
flags
;
ASSERT
(
irlan
!=
NULL
,
return
0
;);
save_flags
(
flags
);
cli
();
len
=
0
;
spin_lock_irqsave
(
&
irlan
->
hb_spinlock
,
flags
);
len
+=
sprintf
(
buf
+
len
,
"IrLAN instances:
\n
"
);
self
=
(
struct
irlan_cb
*
)
hashbin_get_first
(
irlan
);
...
...
@@ -1129,7 +1128,7 @@ static int irlan_proc_read(char *buf, char **start, off_t offset, int len)
self
=
(
struct
irlan_cb
*
)
hashbin_get_next
(
irlan
);
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
irlan
->
hb_spinlock
,
flags
);
return
len
;
}
...
...
net/irda/irlap.c
View file @
c08e4720
...
...
@@ -80,7 +80,7 @@ int irlap_proc_read(char *, char **, off_t, int);
int
__init
irlap_init
(
void
)
{
/* Allocate master array */
irlap
=
hashbin_new
(
HB_LOC
AL
);
irlap
=
hashbin_new
(
HB_LOC
K
);
if
(
irlap
==
NULL
)
{
ERROR
(
"%s: can't allocate irlap hashbin!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
...
...
@@ -139,7 +139,15 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
skb_queue_head_init
(
&
self
->
wx_list
);
/* My unique IrLAP device address! */
/* We don't want the broadcast address, neither the NULL address
* (most often used to signify "invalid"), and we don't want an
* address already in use (otherwise connect won't be able
* to select the proper link). - Jean II */
do
{
get_random_bytes
(
&
self
->
saddr
,
sizeof
(
self
->
saddr
));
}
while
((
self
->
saddr
==
0x0
)
||
(
self
->
saddr
==
BROADCAST
)
||
(
hashbin_lock_find
(
irlap
,
self
->
saddr
,
NULL
))
);
/* Copy to the driver */
memcpy
(
dev
->
dev_addr
,
&
self
->
saddr
,
4
);
init_timer
(
&
self
->
slot_timer
);
...
...
@@ -522,7 +530,8 @@ void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery)
self
->
discovery_log
=
NULL
;
}
self
->
discovery_log
=
hashbin_new
(
HB_LOCAL
);
/* All operations will occur at predictable time, no need to lock */
self
->
discovery_log
=
hashbin_new
(
HB_NOLOCK
);
info
.
S
=
discovery
->
nslots
;
/* Number of slots */
info
.
s
=
0
;
/* Current slot */
...
...
@@ -1084,15 +1093,14 @@ int irlap_proc_read(char *buf, char **start, off_t offset, int len)
unsigned
long
flags
;
int
i
=
0
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
irlap
->
hb_spinlock
,
flags
);
len
=
0
;
self
=
(
struct
irlap_cb
*
)
hashbin_get_first
(
irlap
);
while
(
self
!=
NULL
)
{
ASSERT
(
self
!=
NULL
,
return
-
ENODEV
;);
ASSERT
(
self
->
magic
==
LAP_MAGIC
,
return
-
EBADR
;);
ASSERT
(
self
!=
NULL
,
break
;);
ASSERT
(
self
->
magic
==
LAP_MAGIC
,
break
;);
len
+=
sprintf
(
buf
+
len
,
"irlap%d "
,
i
++
);
len
+=
sprintf
(
buf
+
len
,
"state: %s
\n
"
,
...
...
@@ -1164,7 +1172,7 @@ int irlap_proc_read(char *buf, char **start, off_t offset, int len)
self
=
(
struct
irlap_cb
*
)
hashbin_get_next
(
irlap
);
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
irlap
->
hb_spinlock
,
flags
);
return
len
;
}
...
...
net/irda/irlmp.c
View file @
c08e4720
...
...
@@ -83,13 +83,13 @@ int __init irlmp_init(void)
memset
(
irlmp
,
0
,
sizeof
(
struct
irlmp_cb
));
irlmp
->
magic
=
LMP_MAGIC
;
spin_lock_init
(
&
irlmp
->
log_lock
);
irlmp
->
clients
=
hashbin_new
(
HB_GLOBAL
);
irlmp
->
services
=
hashbin_new
(
HB_GLOBAL
);
irlmp
->
links
=
hashbin_new
(
HB_GLOBAL
);
irlmp
->
unconnected_lsaps
=
hashbin_new
(
HB_GLOBAL
);
irlmp
->
cachelog
=
hashbin_new
(
HB_GLOBAL
);
irlmp
->
clients
=
hashbin_new
(
HB_LOCK
);
irlmp
->
services
=
hashbin_new
(
HB_LOCK
);
irlmp
->
links
=
hashbin_new
(
HB_LOCK
);
irlmp
->
unconnected_lsaps
=
hashbin_new
(
HB_LOCK
);
irlmp
->
cachelog
=
hashbin_new
(
HB_NOLOCK
);
spin_lock_init
(
&
irlmp
->
cachelog
->
hb_spinlock
);
irlmp
->
free_lsap_sel
=
0x10
;
/* Reserved 0x00-0x0f */
strcpy
(
sysctl_devname
,
"Linux"
);
...
...
@@ -177,8 +177,8 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid)
self
->
lsap_state
=
LSAP_DISCONNECTED
;
/* Insert into queue of unconnected LSAPs */
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
self
,
(
int
)
self
,
NULL
);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
self
,
(
long
)
self
,
NULL
);
return
self
;
}
...
...
@@ -238,7 +238,7 @@ void irlmp_close_lsap(struct lsap_cb *self)
LM_LAP_DISCONNECT_REQUEST
,
NULL
);
}
/* Now, remove from the link */
lsap
=
hashbin_remove
(
lap
->
lsaps
,
(
int
)
self
,
NULL
);
lsap
=
hashbin_remove
(
lap
->
lsaps
,
(
long
)
self
,
NULL
);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
lap
->
cache
.
valid
=
FALSE
;
#endif
...
...
@@ -246,7 +246,7 @@ void irlmp_close_lsap(struct lsap_cb *self)
self
->
lap
=
NULL
;
/* Check if we found the LSAP! If not then try the unconnected lsaps */
if
(
!
lsap
)
{
lsap
=
hashbin_remove
(
irlmp
->
unconnected_lsaps
,
(
int
)
self
,
lsap
=
hashbin_remove
(
irlmp
->
unconnected_lsaps
,
(
long
)
self
,
NULL
);
}
if
(
!
lsap
)
{
...
...
@@ -286,7 +286,7 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
lap
->
magic
=
LMP_LAP_MAGIC
;
lap
->
saddr
=
saddr
;
lap
->
daddr
=
DEV_ADDR_ANY
;
lap
->
lsaps
=
hashbin_new
(
HB_
GLOBAL
);
lap
->
lsaps
=
hashbin_new
(
HB_
LOCK
);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
lap
->
cache
.
valid
=
FALSE
;
#endif
...
...
@@ -347,7 +347,6 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
struct
sk_buff
*
skb
=
NULL
;
struct
lap_cb
*
lap
;
struct
lsap_cb
*
lsap
;
discovery_t
*
discovery
;
ASSERT
(
self
!=
NULL
,
return
-
EBADR
;);
ASSERT
(
self
->
magic
==
LMP_LSAP_MAGIC
,
return
-
EBADR
;);
...
...
@@ -388,6 +387,10 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
* device with the given daddr
*/
if
((
!
saddr
)
||
(
saddr
==
DEV_ADDR_ANY
))
{
discovery_t
*
discovery
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
irlmp
->
cachelog
->
hb_spinlock
,
flags
);
if
(
daddr
!=
DEV_ADDR_ANY
)
discovery
=
hashbin_find
(
irlmp
->
cachelog
,
daddr
,
NULL
);
else
{
...
...
@@ -400,8 +403,9 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
saddr
=
discovery
->
saddr
;
daddr
=
discovery
->
daddr
;
}
spin_unlock_irqrestore
(
&
irlmp
->
cachelog
->
hb_spinlock
,
flags
);
}
lap
=
hashbin_find
(
irlmp
->
links
,
saddr
,
NULL
);
lap
=
hashbin_
lock_
find
(
irlmp
->
links
,
saddr
,
NULL
);
if
(
lap
==
NULL
)
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), Unable to find a usable link!
\n
"
);
return
-
EHOSTUNREACH
;
...
...
@@ -411,11 +415,8 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
if
(
lap
->
daddr
==
DEV_ADDR_ANY
)
lap
->
daddr
=
daddr
;
else
if
(
lap
->
daddr
!=
daddr
)
{
struct
lsap_cb
*
any_lsap
;
/* Check if some LSAPs are active on this LAP */
any_lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
lap
->
lsaps
);
if
(
any_lsap
==
NULL
)
{
if
(
HASHBIN_GET_SIZE
(
lap
->
lsaps
)
==
0
)
{
/* No active connection, but LAP hasn't been
* disconnected yet (waiting for timeout in LAP).
* Maybe we could give LAP a bit of help in this case.
...
...
@@ -436,14 +437,15 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
* Remove LSAP from list of unconnected LSAPs and insert it into the
* list of connected LSAPs for the particular link
*/
lsap
=
hashbin_remove
(
irlmp
->
unconnected_lsaps
,
(
int
)
self
,
NULL
);
lsap
=
hashbin_remove
(
irlmp
->
unconnected_lsaps
,
(
long
)
self
,
NULL
);
ASSERT
(
lsap
!=
NULL
,
return
-
1
;);
ASSERT
(
lsap
->
magic
==
LMP_LSAP_MAGIC
,
return
-
1
;);
ASSERT
(
lsap
->
lap
!=
NULL
,
return
-
1
;);
ASSERT
(
lsap
->
lap
->
magic
==
LMP_LAP_MAGIC
,
return
-
1
;);
hashbin_insert
(
self
->
lap
->
lsaps
,
(
irda_queue_t
*
)
self
,
(
int
)
self
,
NULL
);
hashbin_insert
(
self
->
lap
->
lsaps
,
(
irda_queue_t
*
)
self
,
(
long
)
self
,
NULL
);
set_bit
(
0
,
&
self
->
connected
);
/* TRUE */
...
...
@@ -574,29 +576,41 @@ void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb)
struct
lsap_cb
*
irlmp_dup
(
struct
lsap_cb
*
orig
,
void
*
instance
)
{
struct
lsap_cb
*
new
;
unsigned
long
flags
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"()
\n
"
);
spin_lock_irqsave
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
/* Only allowed to duplicate unconnected LSAP's */
if
(
!
hashbin_find
(
irlmp
->
unconnected_lsaps
,
(
int
)
orig
,
NULL
))
{
if
(
!
hashbin_find
(
irlmp
->
unconnected_lsaps
,
(
long
)
orig
,
NULL
))
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), unable to find LSAP
\n
"
);
spin_unlock_irqrestore
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
return
NULL
;
}
/* Allocate a new instance */
new
=
kmalloc
(
sizeof
(
struct
lsap_cb
),
GFP_ATOMIC
);
if
(
!
new
)
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), unable to kmalloc
\n
"
);
spin_unlock_irqrestore
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
return
NULL
;
}
/* Dup */
memcpy
(
new
,
orig
,
sizeof
(
struct
lsap_cb
));
new
->
notify
.
instance
=
instance
;
/* new->lap = orig->lap; => done in the memcpy() */
/* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
spin_unlock_irqrestore
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
/* Not everything is the same */
new
->
notify
.
instance
=
instance
;
init_timer
(
&
new
->
watchdog_timer
);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
new
,
(
int
)
new
,
NULL
);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
new
,
(
long
)
new
,
NULL
);
/* Make sure that we invalidate the cache */
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
...
...
@@ -646,7 +660,7 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
ASSERT
(
self
->
lap
->
magic
==
LMP_LAP_MAGIC
,
return
-
1
;);
ASSERT
(
self
->
lap
->
lsaps
!=
NULL
,
return
-
1
;);
lsap
=
hashbin_remove
(
self
->
lap
->
lsaps
,
(
int
)
self
,
NULL
);
lsap
=
hashbin_remove
(
self
->
lap
->
lsaps
,
(
long
)
self
,
NULL
);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
self
->
lap
->
cache
.
valid
=
FALSE
;
#endif
...
...
@@ -655,8 +669,8 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
ASSERT
(
lsap
->
magic
==
LMP_LSAP_MAGIC
,
return
-
1
;);
ASSERT
(
lsap
==
self
,
return
-
1
;);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
self
,
(
int
)
self
,
NULL
);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
self
,
(
long
)
self
,
NULL
);
/* Reset some values */
self
->
dlsap_sel
=
LSAP_ANY
;
...
...
@@ -699,15 +713,15 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
ASSERT
(
self
->
lap
!=
NULL
,
return
;);
ASSERT
(
self
->
lap
->
lsaps
!=
NULL
,
return
;);
lsap
=
hashbin_remove
(
self
->
lap
->
lsaps
,
(
int
)
self
,
NULL
);
lsap
=
hashbin_remove
(
self
->
lap
->
lsaps
,
(
long
)
self
,
NULL
);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
self
->
lap
->
cache
.
valid
=
FALSE
;
#endif
ASSERT
(
lsap
!=
NULL
,
return
;);
ASSERT
(
lsap
==
self
,
return
;);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
lsap
,
(
int
)
lsap
,
NULL
);
hashbin_insert
(
irlmp
->
unconnected_lsaps
,
(
irda_queue_t
*
)
lsap
,
(
long
)
lsap
,
NULL
);
self
->
dlsap_sel
=
LSAP_ANY
;
self
->
lap
=
NULL
;
...
...
@@ -886,7 +900,7 @@ void irlmp_check_services(discovery_t *discovery)
*/
while ((service = service_log[i++]) != S_END) {
IRDA_DEBUG( 4, "service=%02x\n", service);
client = hashbin_find(irlmp->registry, service, NULL);
client = hashbin_
lock_
find(irlmp->registry, service, NULL);
if (entry && entry->discovery_callback) {
IRDA_DEBUG( 4, "discovery_callback!\n");
...
...
@@ -903,6 +917,7 @@ void irlmp_check_services(discovery_t *discovery)
kfree(service_log);
}
#endif
/*
* Function irlmp_notify_client (log)
*
...
...
@@ -930,6 +945,12 @@ irlmp_notify_client(irlmp_client_t *client,
/*
* 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
*/
discovery
=
(
discovery_t
*
)
hashbin_get_first
(
log
);
while
(
discovery
!=
NULL
)
{
...
...
@@ -956,6 +977,7 @@ irlmp_notify_client(irlmp_client_t *client,
void
irlmp_discovery_confirm
(
hashbin_t
*
log
,
DISCOVERY_MODE
mode
)
{
irlmp_client_t
*
client
;
irlmp_client_t
*
client_next
;
IRDA_DEBUG
(
3
,
__FUNCTION__
"()
\n
"
);
...
...
@@ -965,11 +987,12 @@ void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
return
;
client
=
(
irlmp_client_t
*
)
hashbin_get_first
(
irlmp
->
clients
);
while
(
client
!=
NULL
)
{
while
(
NULL
!=
hashbin_find_next
(
irlmp
->
clients
,
(
long
)
client
,
NULL
,
(
void
*
)
&
client_next
)
)
{
/* Check if we should notify client */
irlmp_notify_client
(
client
,
log
,
mode
);
client
=
(
irlmp_client_t
*
)
hashbin_get_next
(
irlmp
->
clients
)
;
client
=
client_next
;
}
}
...
...
@@ -987,13 +1010,15 @@ void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
void
irlmp_discovery_expiry
(
discovery_t
*
expiry
)
{
irlmp_client_t
*
client
;
irlmp_client_t
*
client_next
;
IRDA_DEBUG
(
3
,
__FUNCTION__
"()
\n
"
);
ASSERT
(
expiry
!=
NULL
,
return
;);
client
=
(
irlmp_client_t
*
)
hashbin_get_first
(
irlmp
->
clients
);
while
(
client
!=
NULL
)
{
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
))
...
...
@@ -1001,7 +1026,7 @@ void irlmp_discovery_expiry(discovery_t *expiry)
client
->
priv
);
/* Next client */
client
=
(
irlmp_client_t
*
)
hashbin_get_next
(
irlmp
->
clients
)
;
client
=
client_next
;
}
}
...
...
@@ -1196,11 +1221,9 @@ void irlmp_status_indication(struct lap_cb *self,
struct
lsap_cb
*
curr
;
/* Send status_indication to all LSAPs using this link */
next
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
next
!=
NULL
)
{
curr
=
next
;
next
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
curr
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
NULL
!=
hashbin_find_next
(
self
->
lsaps
,
(
long
)
curr
,
NULL
,
(
void
*
)
&
next
)
)
{
ASSERT
(
curr
->
magic
==
LMP_LSAP_MAGIC
,
return
;);
/*
* Inform service user if he has requested it
...
...
@@ -1210,6 +1233,8 @@ void irlmp_status_indication(struct lap_cb *self,
link
,
lock
);
else
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), no handler
\n
"
);
curr
=
next
;
}
}
...
...
@@ -1245,29 +1270,15 @@ void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow)
(
IRLAP_GET_TX_QUEUE_LEN
(
self
->
irlap
)
<
LAP_HIGH_THRESHOLD
))
{
/* Try to find the next lsap we should poll. */
next
=
self
->
flow_next
;
if
(
next
!=
NULL
)
{
/* Note that if there is only one LSAP on the LAP
* (most common case), self->flow_next is always NULL,
* so we always avoid this loop. - Jean II */
IRDA_DEBUG
(
4
,
__FUNCTION__
"() : searching my LSAP
\n
"
);
/* We look again in hashbins, because the lsap
* might have gone away... - Jean II */
curr
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
((
curr
!=
NULL
)
&&
(
curr
!=
next
))
curr
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
}
else
curr
=
NULL
;
/* If we have no lsap, restart from first one */
if
(
curr
==
NULL
)
curr
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
if
(
next
==
NULL
)
next
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
/* Verify current one and find the next one */
curr
=
hashbin_find_next
(
self
->
lsaps
,
(
long
)
next
,
NULL
,
(
void
*
)
&
self
->
flow_next
);
/* Uh-oh... Paranoia */
if
(
curr
==
NULL
)
break
;
/* Next time, we will get the next one (or the first one) */
self
->
flow_next
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
IRDA_DEBUG
(
4
,
__FUNCTION__
"() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d
\n
"
,
curr
,
next
,
self
->
flow_next
,
lsap_todo
,
IRLAP_GET_TX_QUEUE_LEN
(
self
->
irlap
));
/* Inform lsap user that it can send one more packet. */
...
...
@@ -1414,20 +1425,12 @@ __u16 irlmp_service_to_hint(int service)
* Register local service with IrLMP
*
*/
__u32
irlmp_register_service
(
__u16
hints
)
void
*
irlmp_register_service
(
__u16
hints
)
{
irlmp_service_t
*
service
;
__u32
handle
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), hints = %04x
\n
"
,
hints
);
/* Get a unique handle for this service */
get_random_bytes
(
&
handle
,
sizeof
(
handle
));
while
(
hashbin_find
(
irlmp
->
services
,
handle
,
NULL
)
||
!
handle
)
get_random_bytes
(
&
handle
,
sizeof
(
handle
));
irlmp
->
hints
.
word
|=
hints
;
/* Make a new registration */
service
=
kmalloc
(
sizeof
(
irlmp_service_t
),
GFP_ATOMIC
);
if
(
!
service
)
{
...
...
@@ -1435,9 +1438,12 @@ __u32 irlmp_register_service(__u16 hints)
return
0
;
}
service
->
hints
=
hints
;
hashbin_insert
(
irlmp
->
services
,
(
irda_queue_t
*
)
service
,
handle
,
NULL
);
hashbin_insert
(
irlmp
->
services
,
(
irda_queue_t
*
)
service
,
(
long
)
service
,
NULL
);
return
handle
;
irlmp
->
hints
.
word
|=
hints
;
return
(
void
*
)
service
;
}
/*
...
...
@@ -1447,35 +1453,38 @@ __u32 irlmp_register_service(__u16 hints)
*
* Returns: 0 on success, -1 on error
*/
int
irlmp_unregister_service
(
__u32
handle
)
int
irlmp_unregister_service
(
void
*
handle
)
{
irlmp_service_t
*
service
;
unsigned
long
flags
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
if
(
!
handle
)
return
-
1
;
service
=
hashbin_find
(
irlmp
->
services
,
handle
,
NULL
);
/* Caller may call with invalid handle (it's legal) - Jean II */
service
=
hashbin_lock_find
(
irlmp
->
services
,
(
long
)
handle
,
NULL
);
if
(
!
service
)
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), Unknown service!
\n
"
);
return
-
1
;
}
service
=
hashbin_remove
(
irlmp
->
services
,
handle
,
NULL
);
if
(
service
)
hashbin_remove_this
(
irlmp
->
services
,
(
irda_queue_t
*
)
service
);
kfree
(
service
);
/* Remove old hint bits */
irlmp
->
hints
.
word
=
0
;
/* Refresh current hint bits */
spin_lock_irqsave
(
&
irlmp
->
services
->
hb_spinlock
,
flags
);
service
=
(
irlmp_service_t
*
)
hashbin_get_first
(
irlmp
->
services
);
while
(
service
)
{
irlmp
->
hints
.
word
|=
service
->
hints
;
service
=
(
irlmp_service_t
*
)
hashbin_get_next
(
irlmp
->
services
);
}
spin_unlock_irqrestore
(
&
irlmp
->
services
->
hb_spinlock
,
flags
);
return
0
;
}
...
...
@@ -1488,20 +1497,14 @@ int irlmp_unregister_service(__u32 handle)
*
* Returns: handle > 0 on success, 0 on error
*/
__u32
irlmp_register_client
(
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
void
*
irlmp_register_client
(
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK1
expir_clb
,
void
*
priv
)
{
irlmp_client_t
*
client
;
__u32
handle
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"()
\n
"
);
ASSERT
(
irlmp
!=
NULL
,
return
0
;);
/* Get a unique handle for this client */
get_random_bytes
(
&
handle
,
sizeof
(
handle
));
while
(
hashbin_find
(
irlmp
->
clients
,
handle
,
NULL
)
||
!
handle
)
get_random_bytes
(
&
handle
,
sizeof
(
handle
));
/* Make a new registration */
client
=
kmalloc
(
sizeof
(
irlmp_client_t
),
GFP_ATOMIC
);
if
(
!
client
)
{
...
...
@@ -1515,9 +1518,10 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
client
->
expir_callback
=
expir_clb
;
client
->
priv
=
priv
;
hashbin_insert
(
irlmp
->
clients
,
(
irda_queue_t
*
)
client
,
handle
,
NULL
);
hashbin_insert
(
irlmp
->
clients
,
(
irda_queue_t
*
)
client
,
(
long
)
client
,
NULL
);
return
handle
;
return
(
void
*
)
client
;
}
/*
...
...
@@ -1528,7 +1532,7 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
*
* Returns: 0 on success, -1 on error
*/
int
irlmp_update_client
(
__u32
handle
,
__u16
hint_mask
,
int
irlmp_update_client
(
void
*
handle
,
__u16
hint_mask
,
DISCOVERY_CALLBACK1
disco_clb
,
DISCOVERY_CALLBACK1
expir_clb
,
void
*
priv
)
{
...
...
@@ -1537,7 +1541,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask,
if
(
!
handle
)
return
-
1
;
client
=
hashbin_
find
(
irlmp
->
clients
,
handle
,
NULL
);
client
=
hashbin_
lock_find
(
irlmp
->
clients
,
(
long
)
handle
,
NULL
);
if
(
!
client
)
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), Unknown client!
\n
"
);
return
-
1
;
...
...
@@ -1557,7 +1561,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask,
* Returns: 0 on success, -1 on error
*
*/
int
irlmp_unregister_client
(
__u32
handle
)
int
irlmp_unregister_client
(
void
*
handle
)
{
struct
irlmp_client
*
client
;
...
...
@@ -1566,15 +1570,15 @@ int irlmp_unregister_client(__u32 handle)
if
(
!
handle
)
return
-
1
;
client
=
hashbin_find
(
irlmp
->
clients
,
handle
,
NULL
);
/* Caller may call with invalid handle (it's legal) - Jean II */
client
=
hashbin_lock_find
(
irlmp
->
clients
,
(
long
)
handle
,
NULL
);
if
(
!
client
)
{
IRDA_DEBUG
(
1
,
__FUNCTION__
"(), Unknown client!
\n
"
);
return
-
1
;
}
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), removing client!
\n
"
);
client
=
hashbin_remove
(
irlmp
->
clients
,
handle
,
NULL
);
if
(
client
)
hashbin_remove_this
(
irlmp
->
clients
,
(
irda_queue_t
*
)
client
);
kfree
(
client
);
return
0
;
...
...
@@ -1589,6 +1593,7 @@ int irlmp_slsap_inuse(__u8 slsap_sel)
{
struct
lsap_cb
*
self
;
struct
lap_cb
*
lap
;
unsigned
long
flags
;
ASSERT
(
irlmp
!=
NULL
,
return
TRUE
;);
ASSERT
(
irlmp
->
magic
==
LMP_MAGIC
,
return
TRUE
;);
...
...
@@ -1611,10 +1616,16 @@ int irlmp_slsap_inuse(__u8 slsap_sel)
* every IrLAP connection and check every LSAP assosiated with each
* the connection.
*/
spin_lock_irqsave
(
&
irlmp
->
links
->
hb_spinlock
,
flags
);
lap
=
(
struct
lap_cb
*
)
hashbin_get_first
(
irlmp
->
links
);
while
(
lap
!=
NULL
)
{
ASSERT
(
lap
->
magic
==
LMP_LAP_MAGIC
,
return
TRUE
;);
/* Careful for priority inversions here !
* All other uses of attrib spinlock are independant of
* the object spinlock, so we are safe. Jean II */
spin_lock
(
&
lap
->
lsaps
->
hb_spinlock
);
self
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
lap
->
lsaps
);
while
(
self
!=
NULL
)
{
ASSERT
(
self
->
magic
==
LMP_LSAP_MAGIC
,
return
TRUE
;);
...
...
@@ -1626,8 +1637,11 @@ int irlmp_slsap_inuse(__u8 slsap_sel)
}
self
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
lap
->
lsaps
);
}
spin_unlock
(
&
lap
->
lsaps
->
hb_spinlock
);
/* Next LAP */
lap
=
(
struct
lap_cb
*
)
hashbin_get_next
(
irlmp
->
links
);
}
spin_unlock_irqrestore
(
&
irlmp
->
links
->
hb_spinlock
,
flags
);
return
FALSE
;
}
...
...
@@ -1736,15 +1750,13 @@ int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
ASSERT
(
irlmp
!=
NULL
,
return
0
;);
save_flags
(
flags
);
cli
();
len
=
0
;
len
+=
sprintf
(
buf
+
len
,
"Unconnected LSAPs:
\n
"
);
spin_lock_irqsave
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
self
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
irlmp
->
unconnected_lsaps
);
while
(
self
!=
NULL
)
{
ASSERT
(
self
->
magic
==
LMP_LSAP_MAGIC
,
return
0
;);
ASSERT
(
self
->
magic
==
LMP_LSAP_MAGIC
,
break
;);
len
+=
sprintf
(
buf
+
len
,
"lsap state: %s, "
,
irlsap_state
[
self
->
lsap_state
]);
len
+=
sprintf
(
buf
+
len
,
...
...
@@ -1756,9 +1768,10 @@ int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
self
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
irlmp
->
unconnected_lsaps
);
}
spin_unlock_irqrestore
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
len
+=
sprintf
(
buf
+
len
,
"
\n
Registred Link Layers:
\n
"
);
spin_lock_irqsave
(
&
irlmp
->
links
->
hb_spinlock
,
flags
);
lap
=
(
struct
lap_cb
*
)
hashbin_get_first
(
irlmp
->
links
);
while
(
lap
!=
NULL
)
{
len
+=
sprintf
(
buf
+
len
,
"lap state: %s, "
,
...
...
@@ -1770,10 +1783,15 @@ int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
HASHBIN_GET_SIZE
(
lap
->
lsaps
));
len
+=
sprintf
(
buf
+
len
,
"
\n
"
);
/* Careful for priority inversions here !
* All other uses of attrib spinlock are independant of
* the object spinlock, so we are safe. Jean II */
spin_lock
(
&
lap
->
lsaps
->
hb_spinlock
);
len
+=
sprintf
(
buf
+
len
,
"
\n
Connected LSAPs:
\n
"
);
self
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
lap
->
lsaps
);
while
(
self
!=
NULL
)
{
ASSERT
(
self
->
magic
==
LMP_LSAP_MAGIC
,
return
0
;);
ASSERT
(
self
->
magic
==
LMP_LSAP_MAGIC
,
break
;);
len
+=
sprintf
(
buf
+
len
,
" lsap state: %s, "
,
irlsap_state
[
self
->
lsap_state
]);
len
+=
sprintf
(
buf
+
len
,
...
...
@@ -1785,11 +1803,12 @@ int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
self
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
lap
->
lsaps
);
}
spin_unlock
(
&
lap
->
lsaps
->
hb_spinlock
);
len
+=
sprintf
(
buf
+
len
,
"
\n
"
);
lap
=
(
struct
lap_cb
*
)
hashbin_get_next
(
irlmp
->
links
);
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
irlmp
->
links
->
hb_spinlock
,
flags
);
return
len
;
}
...
...
net/irda/irlmp_event.c
View file @
c08e4720
...
...
@@ -207,6 +207,43 @@ void irlmp_idle_timer_expired(void *data)
irlmp_do_lap_event
(
self
,
LM_LAP_IDLE_TIMEOUT
,
NULL
);
}
/*
* Send an event on all LSAPs attached to this LAP.
*/
static
inline
void
irlmp_do_all_lsap_event
(
hashbin_t
*
lsap_hashbin
,
IRLMP_EVENT
event
)
{
struct
lsap_cb
*
lsap
;
struct
lsap_cb
*
lsap_next
;
/* Note : this function use the new hashbin_find_next()
* function, instead of the old hashbin_get_next().
* This make sure that we are always pointing one lsap
* ahead, so that if the current lsap is removed as the
* result of sending the event, we don't care.
* Also, as we store the context ourselves, if an enumeration
* of the same lsap hashbin happens as the result of sending the
* event, we don't care.
* The only problem is if the next lsap is removed. In that case,
* hashbin_find_next() will return NULL and we will abort the
* enumeration. - Jean II */
/* Also : we don't accept any skb in input. We can *NOT* pass
* the same skb to multiple clients safely, we would need to
* skb_clone() it. - Jean II */
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
lsap_hashbin
);
while
(
NULL
!=
hashbin_find_next
(
lsap_hashbin
,
(
long
)
lsap
,
NULL
,
(
void
*
)
&
lsap_next
)
)
{
irlmp_do_lsap_event
(
lsap
,
event
,
NULL
);
lsap
=
lsap_next
;
}
}
/*********************************************************************
*
* LAP connection control states
...
...
@@ -274,9 +311,6 @@ static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
static
void
irlmp_state_u_connect
(
struct
lap_cb
*
self
,
IRLMP_EVENT
event
,
struct
sk_buff
*
skb
)
{
struct
lsap_cb
*
lsap
;
struct
lsap_cb
*
lsap_current
;
IRDA_DEBUG
(
2
,
__FUNCTION__
"(), event=%s
\n
"
,
irlmp_event
[
event
]);
switch
(
event
)
{
...
...
@@ -290,11 +324,9 @@ static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
/* Just accept connection TODO, this should be fixed */
irlap_connect_response
(
self
->
irlap
,
skb
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
lsap
!=
NULL
)
{
irlmp_do_lsap_event
(
lsap
,
LM_LAP_CONNECT_CONFIRM
,
NULL
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
}
/* Tell LSAPs that they can start sending data */
irlmp_do_all_lsap_event
(
self
->
lsaps
,
LM_LAP_CONNECT_CONFIRM
);
/* Note : by the time we get there (LAP retries and co),
* the lsaps may already have gone. This avoid getting stuck
* forever in LAP_ACTIVE state - Jean II */
...
...
@@ -310,11 +342,9 @@ static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
/* For all lsap_ce E Associated do LS_Connect_confirm */
irlmp_next_lap_state
(
self
,
LAP_ACTIVE
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
lsap
!=
NULL
)
{
irlmp_do_lsap_event
(
lsap
,
LM_LAP_CONNECT_CONFIRM
,
NULL
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
}
/* Tell LSAPs that they can start sending data */
irlmp_do_all_lsap_event
(
self
->
lsaps
,
LM_LAP_CONNECT_CONFIRM
);
/* Note : by the time we get there (LAP retries and co),
* the lsaps may already have gone. This avoid getting stuck
* forever in LAP_ACTIVE state - Jean II */
...
...
@@ -328,18 +358,8 @@ static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
irlmp_next_lap_state
(
self
,
LAP_STANDBY
);
/* Send disconnect event to all LSAPs using this link */
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
lsap
!=
NULL
)
{
ASSERT
(
lsap
->
magic
==
LMP_LSAP_MAGIC
,
return
;);
lsap_current
=
lsap
;
/* Be sure to stay one item ahead */
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
irlmp_do_lsap_event
(
lsap_current
,
LM_LAP_DISCONNECT_INDICATION
,
NULL
);
}
irlmp_do_all_lsap_event
(
self
->
lsaps
,
LM_LAP_DISCONNECT_INDICATION
);
break
;
case
LM_LAP_DISCONNECT_REQUEST
:
IRDA_DEBUG
(
4
,
__FUNCTION__
"(), LM_LAP_DISCONNECT_REQUEST
\n
"
);
...
...
@@ -368,9 +388,6 @@ static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
static
void
irlmp_state_active
(
struct
lap_cb
*
self
,
IRLMP_EVENT
event
,
struct
sk_buff
*
skb
)
{
struct
lsap_cb
*
lsap
;
struct
lsap_cb
*
lsap_current
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
switch
(
event
)
{
...
...
@@ -383,22 +400,11 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
* notify all LSAPs using this LAP, but that should be safe to
* do anyway.
*/
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
lsap
!=
NULL
)
{
irlmp_do_lsap_event
(
lsap
,
LM_LAP_CONNECT_CONFIRM
,
NULL
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
}
irlmp_do_all_lsap_event
(
self
->
lsaps
,
LM_LAP_CONNECT_CONFIRM
);
/* Needed by connect indication */
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
irlmp
->
unconnected_lsaps
);
while
(
lsap
!=
NULL
)
{
lsap_current
=
lsap
;
/* Be sure to stay one item ahead */
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
irlmp
->
unconnected_lsaps
);
irlmp_do_lsap_event
(
lsap_current
,
LM_LAP_CONNECT_CONFIRM
,
NULL
);
}
irlmp_do_all_lsap_event
(
irlmp
->
unconnected_lsaps
,
LM_LAP_CONNECT_CONFIRM
);
/* Keep state */
break
;
case
LM_LAP_DISCONNECT_REQUEST
:
...
...
@@ -447,18 +453,8 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
/*
* Inform all connected LSAP's using this link
*/
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
self
->
lsaps
);
while
(
lsap
!=
NULL
)
{
ASSERT
(
lsap
->
magic
==
LMP_LSAP_MAGIC
,
return
;);
lsap_current
=
lsap
;
/* Be sure to stay one item ahead */
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
self
->
lsaps
);
irlmp_do_lsap_event
(
lsap_current
,
LM_LAP_DISCONNECT_INDICATION
,
NULL
);
}
irlmp_do_all_lsap_event
(
self
->
lsaps
,
LM_LAP_DISCONNECT_INDICATION
);
/* Force an expiry of the discovery log.
* Now that the LAP is free, the system may attempt to
...
...
@@ -581,15 +577,15 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
* Bind this LSAP to the IrLAP link where the connect was
* received
*/
lsap
=
hashbin_remove
(
irlmp
->
unconnected_lsaps
,
(
int
)
self
,
lsap
=
hashbin_remove
(
irlmp
->
unconnected_lsaps
,
(
long
)
self
,
NULL
);
ASSERT
(
lsap
==
self
,
return
-
1
;);
ASSERT
(
self
->
lap
!=
NULL
,
return
-
1
;);
ASSERT
(
self
->
lap
->
lsaps
!=
NULL
,
return
-
1
;);
hashbin_insert
(
self
->
lap
->
lsaps
,
(
irda_queue_t
*
)
self
,
(
int
)
self
,
NULL
);
hashbin_insert
(
self
->
lap
->
lsaps
,
(
irda_queue_t
*
)
self
,
(
long
)
self
,
NULL
);
irlmp_send_lcf_pdu
(
self
->
lap
,
self
->
dlsap_sel
,
self
->
slsap_sel
,
CONNECT_CNF
,
skb
);
...
...
net/irda/irlmp_frame.c
View file @
c08e4720
...
...
@@ -210,6 +210,7 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
__u8
dlsap_sel
;
/* Destination LSAP address */
__u8
pid
;
/* Protocol identifier */
__u8
*
fp
;
unsigned
long
flags
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
...
...
@@ -242,6 +243,8 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
return
;
}
/* Search the connectionless LSAP */
spin_lock_irqsave
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
irlmp
->
unconnected_lsaps
);
while
(
lsap
!=
NULL
)
{
/*
...
...
@@ -255,6 +258,8 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
}
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
irlmp
->
unconnected_lsaps
);
}
spin_unlock_irqrestore
(
&
irlmp
->
unconnected_lsaps
->
hb_spinlock
,
flags
);
if
(
lsap
)
irlmp_connless_data_indication
(
lsap
,
skb
);
else
{
...
...
@@ -374,6 +379,7 @@ void irlmp_link_discovery_indication(struct lap_cb *self,
ASSERT
(
self
!=
NULL
,
return
;);
ASSERT
(
self
->
magic
==
LMP_LAP_MAGIC
,
return
;);
/* Add to main log, cleanup */
irlmp_add_discovery
(
irlmp
->
cachelog
,
discovery
);
/* Just handle it the same way as a discovery confirm,
...
...
@@ -396,6 +402,7 @@ void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log)
ASSERT
(
self
!=
NULL
,
return
;);
ASSERT
(
self
->
magic
==
LMP_LAP_MAGIC
,
return
;);
/* Add to main log, cleanup */
irlmp_add_discovery_log
(
irlmp
->
cachelog
,
log
);
/* Propagate event to various LSAPs registered for it.
...
...
@@ -411,6 +418,8 @@ void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log)
static
inline
void
irlmp_update_cache
(
struct
lap_cb
*
lap
,
struct
lsap_cb
*
lsap
)
{
/* Prevent concurent read to get garbage */
lap
->
cache
.
valid
=
FALSE
;
/* Update cache entry */
lap
->
cache
.
dlsap_sel
=
lsap
->
dlsap_sel
;
lap
->
cache
.
slsap_sel
=
lsap
->
slsap_sel
;
...
...
@@ -441,6 +450,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
hashbin_t
*
queue
)
{
struct
lsap_cb
*
lsap
;
unsigned
long
flags
;
/*
* Optimize for the common case. We assume that the last frame
...
...
@@ -455,6 +465,9 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
return
(
self
->
cache
.
lsap
);
}
#endif
spin_lock_irqsave
(
&
queue
->
hb_spinlock
,
flags
);
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_first
(
queue
);
while
(
lsap
!=
NULL
)
{
/*
...
...
@@ -465,29 +478,27 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
*/
if
((
status
==
CONNECT_CMD
)
&&
(
lsap
->
slsap_sel
==
slsap_sel
)
&&
(
lsap
->
dlsap_sel
==
LSAP_ANY
))
{
(
lsap
->
dlsap_sel
==
LSAP_ANY
))
{
/* This is where the dest lsap sel is set on incomming
* lsaps */
lsap
->
dlsap_sel
=
dlsap_sel
;
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
irlmp_update_cache
(
self
,
lsap
);
#endif
return
lsap
;
break
;
}
/*
* Check if source LSAP and dest LSAP selectors match.
*/
if
((
lsap
->
slsap_sel
==
slsap_sel
)
&&
(
lsap
->
dlsap_sel
==
dlsap_sel
))
{
break
;
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
queue
);
}
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
if
(
lsap
)
irlmp_update_cache
(
self
,
lsap
);
#endif
return
lsap
;
}
lsap
=
(
struct
lsap_cb
*
)
hashbin_get_next
(
queue
);
}
spin_unlock_irqrestore
(
&
queue
->
hb_spinlock
,
flags
);
/*
Sorry not found!
*/
return
NULL
;
/*
Return what we've found or NULL
*/
return
lsap
;
}
net/irda/irqueue.c
View file @
c08e4720
...
...
@@ -34,11 +34,412 @@
*
********************************************************************/
/*
* NOTE :
* There are various problems with this package :
* o the hash function for ints is pathetic (but could be changed)
* o locking is sometime suspicious (especially during enumeration)
* o most users have only a few elements (== overhead)
* o most users never use seach, so don't benefit from hashing
* Problem already fixed :
* o not 64 bit compliant (most users do hashv = (int) self)
* o hashbin_remove() is broken => use hashbin_remove_this()
* I think most users would be better served by a simple linked list
* (like include/linux/list.h) with a global spinlock per list.
* Jean II
*/
/*
* Notes on the concurent access to hashbin and other SMP issues
* -------------------------------------------------------------
* Hashbins are very often in the IrDA stack a global repository of
* information, and therefore used in a very asynchronous manner following
* various events (driver calls, timers, user calls...).
* Therefore, very often it is highly important to consider the
* management of concurent access to the hashbin and how to guarantee the
* consistency of the operations on it.
*
* First, we need to define the objective of locking :
* 1) Protect user data (content pointed by the hashbin)
* 2) Protect hashbin structure itself (linked list in each bin)
*
* OLD LOCKING
* -----------
*
* The previous locking strategy, either HB_LOCAL or HB_GLOBAL were
* both inadequate in *both* aspect.
* o HB_GLOBAL was using a spinlock for each bin (local locking).
* o HB_LOCAL was disabling irq on *all* CPUs, so use a single
* global semaphore.
* The problems were :
* A) Global irq disabling is no longer supported by the kernel
* B) No protection for the hashbin struct global data
* o hashbin_delete()
* o hb_current
* C) No protection for user data in some cases
*
* A) HB_LOCAL use global irq disabling, so doesn't work on kernel
* 2.5.X. Even when it is supported (kernel 2.4.X and earlier), its
* performance is not satisfactory on SMP setups. Most hashbins were
* HB_LOCAL, so (A) definitely need fixing.
* B) HB_LOCAL could be modified to fix (B). However, because HB_GLOBAL
* lock only the individual bins, it will never be able to lock the
* global data, so can't do (B).
* C) Some functions return pointer to data that is still in the
* hashbin :
* o hashbin_find()
* o hashbin_get_first()
* o hashbin_get_next()
* As the data is still in the hashbin, it may be changed or free'd
* while the caller is examinimg the data. In those case, locking can't
* be done within the hashbin, but must include use of the data within
* the caller.
* The caller can easily do this with HB_LOCAL (just disable irqs).
* However, this is impossible with HB_GLOBAL because the caller has no
* way to know the proper bin, so don't know which spinlock to use.
*
* Quick summary : can no longer use HB_LOCAL, and HB_GLOBAL is
* fundamentally broken and will never work.
*
* NEW LOCKING
* -----------
*
* To fix those problems, I've introduce a few changes in the
* hashbin locking :
* 1) New HB_LOCK scheme
* 2) hashbin->hb_spinlock
* 3) New hashbin usage policy
*
* HB_LOCK :
* -------
* HB_LOCK is a locking scheme intermediate between the old HB_LOCAL
* and HB_GLOBAL. It uses a single spinlock to protect the whole content
* of the hashbin. As it is a single spinlock, it can protect the global
* data of the hashbin and not only the bins themselves.
* HB_LOCK can only protect some of the hashbin calls, so it only lock
* call that can be made 100% safe and leave other call unprotected.
* HB_LOCK in theory is slower than HB_GLOBAL, but as the hashbin
* content is always small contention is not high, so it doesn't matter
* much. HB_LOCK is probably faster than HB_LOCAL.
*
* hashbin->hb_spinlock :
* --------------------
* The spinlock that HB_LOCK uses is available for caller, so that
* the caller can protect unprotected calls (see below).
* If the caller want to do entirely its own locking (HB_NOLOCK), he
* can do so and may use safely this spinlock.
* Locking is done like this :
* spin_lock_irqsave(&hashbin->hb_spinlock, flags);
* Releasing the lock :
* spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
*
* Safe & Protected calls :
* ----------------------
* The following calls are safe or protected via HB_LOCK :
* o hashbin_new() -> safe
* o hashbin_delete()
* o hashbin_insert()
* o hashbin_remove_first()
* o hashbin_remove()
* o hashbin_remove_this()
* o HASHBIN_GET_SIZE() -> atomic
*
* The following calls only protect the hashbin itself :
* o hashbin_lock_find()
* o hashbin_find_next()
*
* Unprotected calls :
* -----------------
* The following calls need to be protected by the caller :
* o hashbin_find()
* o hashbin_get_first()
* o hashbin_get_next()
*
* Locking Policy :
* --------------
* If the hashbin is used only in a single thread of execution
* (explicitely or implicitely), you can use HB_NOLOCK
* If the calling module already provide concurent access protection,
* you may use HB_NOLOCK.
*
* In all other cases, you need to use HB_LOCK and lock the hashbin
* everytime before calling one of the unprotected calls. You also must
* use the pointer returned by the unprotected call within the locked
* region.
*
* Extra care for enumeration :
* --------------------------
* hashbin_get_first() and hashbin_get_next() use the hashbin to
* store the current position, in hb_current.
* As long as the hashbin remains locked, this is safe. If you unlock
* the hashbin, the current position may change if anybody else modify
* or enumerate the hashbin.
* Summary : do the full enumeration while locked.
*
* Alternatively, you may use hashbin_find_next(). But, this will
* be slower, is more complex to use and doesn't protect the hashbin
* content. So, care is needed here as well.
*
* Other issues :
* ------------
* I believe that we are overdoing it by using spin_lock_irqsave()
* and we should use only spin_lock_bh() or similar. But, I don't have
* the balls to try it out.
* Don't believe that because hashbin are now (somewhat) SMP safe
* that the rest of the code is. Higher layers tend to be safest,
* but LAP and LMP would need some serious dedicated love.
*
* Jean II
*/
#include <net/irda/irda.h>
#include <net/irda/irqueue.h>
static
irda_queue_t
*
dequeue_general
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
);
static
__u32
hash
(
char
*
name
);
/************************ QUEUE SUBROUTINES ************************/
/*
* Hashbin
*/
#define GET_HASHBIN(x) ( x & HASHBIN_MASK )
/*
* Function hash (name)
*
* This function hash the input string 'name' using the ELF hash
* function for strings.
*/
static
__u32
hash
(
char
*
name
)
{
__u32
h
=
0
;
__u32
g
;
while
(
*
name
)
{
h
=
(
h
<<
4
)
+
*
name
++
;
if
((
g
=
(
h
&
0xf0000000
)))
h
^=
g
>>
24
;
h
&=~
g
;
}
return
h
;
}
/*
* Function enqueue_first (queue, proc)
*
* Insert item first in queue.
*
*/
static
void
enqueue_first
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
/*
* Check if queue is empty.
*/
if
(
*
queue
==
NULL
)
{
/*
* Queue is empty. Insert one element into the queue.
*/
element
->
q_next
=
element
->
q_prev
=
*
queue
=
element
;
}
else
{
/*
* Queue is not empty. Insert element into front of queue.
*/
element
->
q_next
=
(
*
queue
);
(
*
queue
)
->
q_prev
->
q_next
=
element
;
element
->
q_prev
=
(
*
queue
)
->
q_prev
;
(
*
queue
)
->
q_prev
=
element
;
(
*
queue
)
=
element
;
}
}
#ifdef HASHBIN_UNUSED
/*
* Function enqueue_last (queue, proc)
*
* Insert item into end of queue.
*
*/
static
void
__enqueue_last
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
/*
* Check if queue is empty.
*/
if
(
*
queue
==
NULL
)
{
/*
* Queue is empty. Insert one element into the queue.
*/
element
->
q_next
=
element
->
q_prev
=
*
queue
=
element
;
}
else
{
/*
* Queue is not empty. Insert element into end of queue.
*/
element
->
q_prev
=
(
*
queue
)
->
q_prev
;
element
->
q_prev
->
q_next
=
element
;
(
*
queue
)
->
q_prev
=
element
;
element
->
q_next
=
*
queue
;
}
}
static
inline
void
enqueue_last
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
__enqueue_last
(
queue
,
element
);
restore_flags
(
flags
);
}
/*
* Function enqueue_queue (queue, list)
*
* Insert a queue (list) into the start of the first queue
*
*/
static
void
enqueue_queue
(
irda_queue_t
**
queue
,
irda_queue_t
**
list
)
{
irda_queue_t
*
tmp
;
/*
* Check if queue is empty
*/
if
(
*
queue
)
{
(
*
list
)
->
q_prev
->
q_next
=
(
*
queue
);
(
*
queue
)
->
q_prev
->
q_next
=
(
*
list
);
tmp
=
(
*
list
)
->
q_prev
;
(
*
list
)
->
q_prev
=
(
*
queue
)
->
q_prev
;
(
*
queue
)
->
q_prev
=
tmp
;
}
else
{
*
queue
=
(
*
list
);
}
(
*
list
)
=
NULL
;
}
/*
* Function enqueue_second (queue, proc)
*
* Insert item behind head of queue.
*
*/
static
void
enqueue_second
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
IRDA_DEBUG
(
0
,
"enqueue_second()
\n
"
);
/*
* Check if queue is empty.
*/
if
(
*
queue
==
NULL
)
{
/*
* Queue is empty. Insert one element into the queue.
*/
element
->
q_next
=
element
->
q_prev
=
*
queue
=
element
;
}
else
{
/*
* Queue is not empty. Insert element into ..
*/
element
->
q_prev
=
(
*
queue
);
(
*
queue
)
->
q_next
->
q_prev
=
element
;
element
->
q_next
=
(
*
queue
)
->
q_next
;
(
*
queue
)
->
q_next
=
element
;
}
}
#endif
/* HASHBIN_UNUSED */
/*
* Function dequeue (queue)
*
* Remove first entry in queue
*
*/
static
irda_queue_t
*
dequeue_first
(
irda_queue_t
**
queue
)
{
irda_queue_t
*
ret
;
IRDA_DEBUG
(
4
,
"dequeue_first()
\n
"
);
/*
* Set return value
*/
ret
=
*
queue
;
if
(
*
queue
==
NULL
)
{
/*
* Queue was empty.
*/
}
else
if
(
(
*
queue
)
->
q_next
==
*
queue
)
{
/*
* Queue only contained a single element. It will now be
* empty.
*/
*
queue
=
NULL
;
}
else
{
/*
* Queue contained several element. Remove the first one.
*/
(
*
queue
)
->
q_prev
->
q_next
=
(
*
queue
)
->
q_next
;
(
*
queue
)
->
q_next
->
q_prev
=
(
*
queue
)
->
q_prev
;
*
queue
=
(
*
queue
)
->
q_next
;
}
/*
* Return the removed entry (or NULL of queue was empty).
*/
return
ret
;
}
/*
* Function dequeue_general (queue, element)
*
*
*/
static
irda_queue_t
*
dequeue_general
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
irda_queue_t
*
ret
;
IRDA_DEBUG
(
4
,
"dequeue_general()
\n
"
);
/*
* Set return value
*/
ret
=
*
queue
;
if
(
*
queue
==
NULL
)
{
/*
* Queue was empty.
*/
}
else
if
(
(
*
queue
)
->
q_next
==
*
queue
)
{
/*
* Queue only contained a single element. It will now be
* empty.
*/
*
queue
=
NULL
;
}
else
{
/*
* Remove specific element.
*/
element
->
q_prev
->
q_next
=
element
->
q_next
;
element
->
q_next
->
q_prev
=
element
->
q_prev
;
if
(
(
*
queue
)
==
element
)
(
*
queue
)
=
element
->
q_next
;
}
/*
* Return the removed entry (or NULL of queue was empty).
*/
return
ret
;
}
/************************ HASHBIN MANAGEMENT ************************/
/*
* Function hashbin_create ( type, name )
...
...
@@ -49,7 +450,6 @@ static __u32 hash( char* name);
hashbin_t
*
hashbin_new
(
int
type
)
{
hashbin_t
*
hashbin
;
int
i
;
/*
* Allocate new hashbin
...
...
@@ -64,14 +464,17 @@ hashbin_t *hashbin_new(int type)
memset
(
hashbin
,
0
,
sizeof
(
hashbin_t
));
hashbin
->
hb_type
=
type
;
hashbin
->
magic
=
HB_MAGIC
;
//hashbin->hb_current = NULL;
/* Make sure all spinlock's are unlocked */
for
(
i
=
0
;
i
<
HASHBIN_SIZE
;
i
++
)
hashbin
->
hb_mutex
[
i
]
=
SPIN_LOCK_UNLOCKED
;
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_lock_init
(
&
hashbin
->
hb_spinlock
);
}
return
hashbin
;
}
#ifdef HASHBIN_UNUSED
/*
* Function hashbin_clear (hashbin, free_func)
*
...
...
@@ -102,7 +505,7 @@ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func)
return
0
;
}
#endif
/* HASHBIN_UNUSED */
/*
* Function hashbin_delete (hashbin, free_func)
...
...
@@ -114,11 +517,17 @@ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func)
int
hashbin_delete
(
hashbin_t
*
hashbin
,
FREE_FUNC
free_func
)
{
irda_queue_t
*
queue
;
unsigned
long
flags
=
0
;
int
i
;
ASSERT
(
hashbin
!=
NULL
,
return
-
1
;);
ASSERT
(
hashbin
->
magic
==
HB_MAGIC
,
return
-
1
;);
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/*
* Free the entries in the hashbin, TODO: use hashbin_clear when
* it has been shown to work
...
...
@@ -133,22 +542,32 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
}
}
/* Cleanup local data */
hashbin
->
hb_current
=
NULL
;
hashbin
->
magic
=
~
HB_MAGIC
;
/* Release lock */
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/*
* Free the hashbin structure
*/
hashbin
->
magic
=
~
HB_MAGIC
;
kfree
(
hashbin
);
return
0
;
}
/********************* HASHBIN LIST OPERATIONS *********************/
/*
* Function hashbin_insert (hashbin, entry, name)
*
* Insert an entry into the hashbin
*
*/
void
hashbin_insert
(
hashbin_t
*
hashbin
,
irda_queue_t
*
entry
,
__u32
hashv
,
char
*
name
)
void
hashbin_insert
(
hashbin_t
*
hashbin
,
irda_queue_t
*
entry
,
long
hashv
,
char
*
name
)
{
unsigned
long
flags
=
0
;
int
bin
;
...
...
@@ -166,12 +585,8 @@ void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char*
bin
=
GET_HASHBIN
(
hashv
);
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
save_flags
(
flags
);
cli
();
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
/*
...
...
@@ -194,102 +609,61 @@ void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char*
hashbin
->
hb_size
++
;
/* Release lock */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
restore_flags
(
flags
);
}
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
}
/*
*
Function hashbin_find (hashbin, hashv, name
)
*
Function hashbin_remove_first (hashbin
)
*
*
Find item with the given hashv or name
*
Remove first entry of the hashbin
*
* Note : this function no longer use hashbin_remove(), but does things
* similar to hashbin_remove_this(), so can be considered safe.
* Jean II
*/
void
*
hashbin_find
(
hashbin_t
*
hashbin
,
__u32
hashv
,
char
*
name
)
void
*
hashbin_remove_first
(
hashbin_t
*
hashbin
)
{
int
bin
,
found
=
FALSE
;
unsigned
long
flags
=
0
;
irda_queue_t
*
entry
;
IRDA_DEBUG
(
4
,
"hashbin_find()
\n
"
);
irda_queue_t
*
entry
=
NULL
;
ASSERT
(
hashbin
!=
NULL
,
return
NULL
;);
ASSERT
(
hashbin
->
magic
==
HB_MAGIC
,
return
NULL
;);
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
entry
=
hashbin_get_first
(
hashbin
);
if
(
entry
!=
NULL
)
{
int
bin
;
long
hashv
;
/*
* Locate hashbin
*/
if
(
name
)
hashv
=
hash
(
name
);
hashv
=
entry
->
q_hash
;
bin
=
GET_HASHBIN
(
hashv
);
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
save_flags
(
flags
);
cli
();
}
/* Default is no-lock */
/*
* Search for entry
*/
entry
=
hashbin
->
hb_queue
[
bin
];
if
(
entry
)
{
do
{
/*
* Check for key
* Dequeue the entry...
*/
if
(
entry
->
q_hash
==
hashv
)
{
dequeue_general
(
(
irda_queue_t
**
)
&
hashbin
->
hb_queue
[
bin
],
(
irda_queue_t
*
)
entry
);
hashbin
->
hb_size
--
;
entry
->
q_next
=
NULL
;
entry
->
q_prev
=
NULL
;
/*
* Name compare too?
* Check if this item is the currently selected item, and in
* that case we must reset hb_current
*/
if
(
name
)
{
if
(
strcmp
(
entry
->
q_name
,
name
)
==
0
)
{
found
=
TRUE
;
break
;
}
}
else
{
found
=
TRUE
;
break
;
}
}
entry
=
entry
->
q_next
;
}
while
(
entry
!=
hashbin
->
hb_queue
[
bin
]
);
if
(
entry
==
hashbin
->
hb_current
)
hashbin
->
hb_current
=
NULL
;
}
/* Release lock */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
restore_flags
(
flags
);
}
if
(
found
)
return
entry
;
else
return
NULL
;
}
void
*
hashbin_remove_first
(
hashbin_t
*
hashbin
)
{
unsigned
long
flags
;
irda_queue_t
*
entry
=
NULL
;
save_flags
(
flags
);
cli
();
entry
=
hashbin_get_first
(
hashbin
);
if
(
entry
!=
NULL
)
hashbin_remove
(
hashbin
,
entry
->
q_hash
,
NULL
);
restore_flags
(
flags
);
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
return
entry
;
}
...
...
@@ -300,8 +674,16 @@ void *hashbin_remove_first( hashbin_t *hashbin)
*
* Remove entry with the given name
*
* The use of this function is highly discouraged, because the whole
* concept behind hashbin_remove() is broken. In many cases, it's not
* possible to guarantee the unicity of the index (either hashv or name),
* leading to removing the WRONG entry.
* The only simple safe use is :
* hashbin_remove(hasbin, (int) self, NULL);
* In other case, you must think hard to guarantee unicity of the index.
* Jean II
*/
void
*
hashbin_remove
(
hashbin_t
*
hashbin
,
__u32
hashv
,
char
*
name
)
void
*
hashbin_remove
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
)
{
int
bin
,
found
=
FALSE
;
unsigned
long
flags
=
0
;
...
...
@@ -320,12 +702,8 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name)
bin
=
GET_HASHBIN
(
hashv
);
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
save_flags
(
flags
);
cli
();
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
/*
...
...
@@ -373,12 +751,9 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name)
}
/* Release lock */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
restore_flags
(
flags
);
}
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
/* Return */
...
...
@@ -390,7 +765,7 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name)
}
/*
* Function hashbin_remove
(hashbin, hashv, name
)
* Function hashbin_remove
_this (hashbin, entry
)
*
* Remove entry with the given name
*
...
...
@@ -404,7 +779,7 @@ void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry)
{
unsigned
long
flags
=
0
;
int
bin
;
__u32
hashv
;
long
hashv
;
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
...
...
@@ -412,6 +787,11 @@ void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry)
ASSERT
(
hashbin
->
magic
==
HB_MAGIC
,
return
NULL
;);
ASSERT
(
entry
!=
NULL
,
return
NULL
;);
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
/* Check if valid and not already removed... */
if
((
entry
->
q_next
==
NULL
)
||
(
entry
->
q_prev
==
NULL
))
return
NULL
;
...
...
@@ -419,41 +799,151 @@ void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry)
/*
* Locate hashbin
*/
hashv
=
entry
->
q_hash
;
bin
=
GET_HASHBIN
(
hashv
);
hashv
=
entry
->
q_hash
;
bin
=
GET_HASHBIN
(
hashv
);
/*
* Dequeue the entry...
*/
dequeue_general
(
(
irda_queue_t
**
)
&
hashbin
->
hb_queue
[
bin
],
(
irda_queue_t
*
)
entry
);
hashbin
->
hb_size
--
;
entry
->
q_next
=
NULL
;
entry
->
q_prev
=
NULL
;
/*
* Check if this item is the currently selected item, and in
* that case we must reset hb_current
*/
if
(
entry
==
hashbin
->
hb_current
)
hashbin
->
hb_current
=
NULL
;
/* Release lock */
if
(
hashbin
->
hb_type
&
HB_LOCK
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
}
/* Default is no-lock */
return
entry
;
}
/*********************** HASHBIN ENUMERATION ***********************/
/*
* Function hashbin_common_find (hashbin, hashv, name)
*
* Find item with the given hashv or name
*
*/
void
*
hashbin_find
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
)
{
int
bin
;
irda_queue_t
*
entry
;
IRDA_DEBUG
(
4
,
"hashbin_find()
\n
"
);
ASSERT
(
hashbin
!=
NULL
,
return
NULL
;);
ASSERT
(
hashbin
->
magic
==
HB_MAGIC
,
return
NULL
;);
/*
* Locate hashbin
*/
if
(
name
)
hashv
=
hash
(
name
);
bin
=
GET_HASHBIN
(
hashv
);
/*
* Search for entry
*/
entry
=
hashbin
->
hb_queue
[
bin
];
if
(
entry
)
{
do
{
/*
* Check for key
*/
if
(
entry
->
q_hash
==
hashv
)
{
/*
* Name compare too?
*/
if
(
name
)
{
if
(
strcmp
(
entry
->
q_name
,
name
)
==
0
)
{
return
entry
;
}
}
else
{
return
entry
;
}
}
entry
=
entry
->
q_next
;
}
while
(
entry
!=
hashbin
->
hb_queue
[
bin
]
);
}
return
NULL
;
}
/*
* Function hashbin_lock_find (hashbin, hashv, name)
*
* Find item with the given hashv or name
*
* Same, but with spinlock protection...
* I call it safe, but it's only safe with respect to the hashbin, not its
* content. - Jean II
*/
void
*
hashbin_lock_find
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
)
{
unsigned
long
flags
=
0
;
irda_queue_t
*
entry
;
/* Synchronize */
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
/*
* Search for entry
*/
entry
=
(
irda_queue_t
*
)
hashbin_find
(
hashbin
,
hashv
,
name
);
/* Release lock */
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
return
entry
;
}
/*
* Function hashbin_find (hashbin, hashv, name, pnext)
*
* Find an item with the given hashv or name, and its successor
*
* This function allow to do concurent enumerations without the
* need to lock over the whole session, because the caller keep the
* context of the search. On the other hand, it might fail and return
* NULL if the entry is removed. - Jean II
*/
void
*
hashbin_find_next
(
hashbin_t
*
hashbin
,
long
hashv
,
char
*
name
,
void
**
pnext
)
{
unsigned
long
flags
=
0
;
irda_queue_t
*
entry
;
/* Synchronize */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_lock_irqsave
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
save_flags
(
flags
);
cli
();
}
/* Default is no-lock */
spin_lock_irqsave
(
&
hashbin
->
hb_spinlock
,
flags
);
/*
* Dequeue the entry...
* Search for current entry
* This allow to check if the current item is still in the
* hashbin or has been removed.
*/
dequeue_general
(
(
irda_queue_t
**
)
&
hashbin
->
hb_queue
[
bin
],
(
irda_queue_t
*
)
entry
);
hashbin
->
hb_size
--
;
entry
->
q_next
=
NULL
;
entry
->
q_prev
=
NULL
;
entry
=
(
irda_queue_t
*
)
hashbin_find
(
hashbin
,
hashv
,
name
);
/*
* Check if this item is the currently selected item, and in
* that case we must reset hb_current
* Trick hashbin_get_next() to return what we want
*/
if
(
entry
==
hashbin
->
hb_current
)
hashbin
->
hb_current
=
NULL
;
if
(
entry
)
{
hashbin
->
hb_current
=
entry
;
*
pnext
=
hashbin_get_next
(
hashbin
);
}
else
*
pnext
=
NULL
;
/* Release lock */
if
(
hashbin
->
hb_type
&
HB_GLOBAL
)
{
spin_unlock_irqrestore
(
&
hashbin
->
hb_mutex
[
bin
],
flags
);
}
else
if
(
hashbin
->
hb_type
&
HB_LOCAL
)
{
restore_flags
(
flags
);
}
spin_unlock_irqrestore
(
&
hashbin
->
hb_spinlock
,
flags
);
return
entry
;
}
...
...
@@ -496,6 +986,8 @@ irda_queue_t *hashbin_get_first( hashbin_t* hashbin)
* be started by a call to hashbin_get_first(). The function returns
* NULL when all items have been traversed
*
* The context of the search is stored within the hashbin, so you must
* protect yourself from concurent enumerations. - Jean II
*/
irda_queue_t
*
hashbin_get_next
(
hashbin_t
*
hashbin
)
{
...
...
@@ -543,240 +1035,3 @@ irda_queue_t *hashbin_get_next( hashbin_t *hashbin)
}
return
NULL
;
}
/*
* Function enqueue_last (queue, proc)
*
* Insert item into end of queue.
*
*/
static
void
__enqueue_last
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
/*
* Check if queue is empty.
*/
if
(
*
queue
==
NULL
)
{
/*
* Queue is empty. Insert one element into the queue.
*/
element
->
q_next
=
element
->
q_prev
=
*
queue
=
element
;
}
else
{
/*
* Queue is not empty. Insert element into end of queue.
*/
element
->
q_prev
=
(
*
queue
)
->
q_prev
;
element
->
q_prev
->
q_next
=
element
;
(
*
queue
)
->
q_prev
=
element
;
element
->
q_next
=
*
queue
;
}
}
inline
void
enqueue_last
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
__enqueue_last
(
queue
,
element
);
restore_flags
(
flags
);
}
/*
* Function enqueue_first (queue, proc)
*
* Insert item first in queue.
*
*/
void
enqueue_first
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
IRDA_DEBUG
(
4
,
__FUNCTION__
"()
\n
"
);
/*
* Check if queue is empty.
*/
if
(
*
queue
==
NULL
)
{
/*
* Queue is empty. Insert one element into the queue.
*/
element
->
q_next
=
element
->
q_prev
=
*
queue
=
element
;
}
else
{
/*
* Queue is not empty. Insert element into front of queue.
*/
element
->
q_next
=
(
*
queue
);
(
*
queue
)
->
q_prev
->
q_next
=
element
;
element
->
q_prev
=
(
*
queue
)
->
q_prev
;
(
*
queue
)
->
q_prev
=
element
;
(
*
queue
)
=
element
;
}
}
/*
* Function enqueue_queue (queue, list)
*
* Insert a queue (list) into the start of the first queue
*
*/
void
enqueue_queue
(
irda_queue_t
**
queue
,
irda_queue_t
**
list
)
{
irda_queue_t
*
tmp
;
/*
* Check if queue is empty
*/
if
(
*
queue
)
{
(
*
list
)
->
q_prev
->
q_next
=
(
*
queue
);
(
*
queue
)
->
q_prev
->
q_next
=
(
*
list
);
tmp
=
(
*
list
)
->
q_prev
;
(
*
list
)
->
q_prev
=
(
*
queue
)
->
q_prev
;
(
*
queue
)
->
q_prev
=
tmp
;
}
else
{
*
queue
=
(
*
list
);
}
(
*
list
)
=
NULL
;
}
/*
* Function enqueue_second (queue, proc)
*
* Insert item behind head of queue.
*
*/
#if 0
static void enqueue_second(irda_queue_t **queue, irda_queue_t* element)
{
IRDA_DEBUG( 0, "enqueue_second()\n");
/*
* Check if queue is empty.
*/
if ( *queue == NULL ) {
/*
* Queue is empty. Insert one element into the queue.
*/
element->q_next = element->q_prev = *queue = element;
} else {
/*
* Queue is not empty. Insert element into ..
*/
element->q_prev = (*queue);
(*queue)->q_next->q_prev = element;
element->q_next = (*queue)->q_next;
(*queue)->q_next = element;
}
}
#endif
/*
* Function dequeue (queue)
*
* Remove first entry in queue
*
*/
irda_queue_t
*
dequeue_first
(
irda_queue_t
**
queue
)
{
irda_queue_t
*
ret
;
IRDA_DEBUG
(
4
,
"dequeue_first()
\n
"
);
/*
* Set return value
*/
ret
=
*
queue
;
if
(
*
queue
==
NULL
)
{
/*
* Queue was empty.
*/
}
else
if
(
(
*
queue
)
->
q_next
==
*
queue
)
{
/*
* Queue only contained a single element. It will now be
* empty.
*/
*
queue
=
NULL
;
}
else
{
/*
* Queue contained several element. Remove the first one.
*/
(
*
queue
)
->
q_prev
->
q_next
=
(
*
queue
)
->
q_next
;
(
*
queue
)
->
q_next
->
q_prev
=
(
*
queue
)
->
q_prev
;
*
queue
=
(
*
queue
)
->
q_next
;
}
/*
* Return the removed entry (or NULL of queue was empty).
*/
return
ret
;
}
/*
* Function dequeue_general (queue, element)
*
*
*/
static
irda_queue_t
*
dequeue_general
(
irda_queue_t
**
queue
,
irda_queue_t
*
element
)
{
irda_queue_t
*
ret
;
IRDA_DEBUG
(
4
,
"dequeue_general()
\n
"
);
/*
* Set return value
*/
ret
=
*
queue
;
if
(
*
queue
==
NULL
)
{
/*
* Queue was empty.
*/
}
else
if
(
(
*
queue
)
->
q_next
==
*
queue
)
{
/*
* Queue only contained a single element. It will now be
* empty.
*/
*
queue
=
NULL
;
}
else
{
/*
* Remove specific element.
*/
element
->
q_prev
->
q_next
=
element
->
q_next
;
element
->
q_next
->
q_prev
=
element
->
q_prev
;
if
(
(
*
queue
)
==
element
)
(
*
queue
)
=
element
->
q_next
;
}
/*
* Return the removed entry (or NULL of queue was empty).
*/
return
ret
;
}
/*
* Function hash (name)
*
* This function hash the input string 'name' using the ELF hash
* function for strings.
*/
static
__u32
hash
(
char
*
name
)
{
__u32
h
=
0
;
__u32
g
;
while
(
*
name
)
{
h
=
(
h
<<
4
)
+
*
name
++
;
if
((
g
=
(
h
&
0xf0000000
)))
h
^=
g
>>
24
;
h
&=~
g
;
}
return
h
;
}
net/irda/irsyms.c
View file @
c08e4720
...
...
@@ -132,12 +132,14 @@ EXPORT_SYMBOL(irlmp_dup);
EXPORT_SYMBOL
(
lmp_reasons
);
/* Queue */
EXPORT_SYMBOL
(
hashbin_find
);
EXPORT_SYMBOL
(
hashbin_new
);
EXPORT_SYMBOL
(
hashbin_insert
);
EXPORT_SYMBOL
(
hashbin_delete
);
EXPORT_SYMBOL
(
hashbin_remove
);
EXPORT_SYMBOL
(
hashbin_remove_this
);
EXPORT_SYMBOL
(
hashbin_find
);
EXPORT_SYMBOL
(
hashbin_lock_find
);
EXPORT_SYMBOL
(
hashbin_find_next
);
EXPORT_SYMBOL
(
hashbin_get_next
);
EXPORT_SYMBOL
(
hashbin_get_first
);
...
...
@@ -328,7 +330,8 @@ void __exit irda_cleanup(void)
* On the other hand, it needs to be initialised *after* the basic
* networking, the /proc/net filesystem and sysctl module. Those are
* currently initialised in .../init/main.c (before initcalls).
* Also, it needs to be initialised *after* the random number generator.
* Also, IrDA drivers needs to be initialised *after* the random number
* generator (main stack and higher layer init don't need it anymore).
*
* Jean II
*/
...
...
net/irda/irttp.c
View file @
c08e4720
...
...
@@ -91,7 +91,7 @@ int __init irttp_init(void)
irttp
->
magic
=
TTP_MAGIC
;
irttp
->
tsaps
=
hashbin_new
(
HB_LOC
AL
);
irttp
->
tsaps
=
hashbin_new
(
HB_LOC
K
);
if
(
!
irttp
->
tsaps
)
{
ERROR
(
"%s: can't allocate IrTTP hashbin!
\n
"
,
__FUNCTION__
);
return
-
ENOMEM
;
...
...
@@ -433,7 +433,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
self
->
notify
=
*
notify
;
self
->
lsap
=
lsap
;
hashbin_insert
(
irttp
->
tsaps
,
(
irda_queue_t
*
)
self
,
(
int
)
self
,
NULL
);
hashbin_insert
(
irttp
->
tsaps
,
(
irda_queue_t
*
)
self
,
(
long
)
self
,
NULL
);
if
(
credit
>
TTP_RX_MAX_CREDIT
)
self
->
initial_credit
=
TTP_RX_MAX_CREDIT
;
...
...
@@ -503,7 +503,7 @@ int irttp_close_tsap(struct tsap_cb *self)
return
0
;
/* Will be back! */
}
tsap
=
hashbin_remove
(
irttp
->
tsaps
,
(
int
)
self
,
NULL
);
tsap
=
hashbin_remove
(
irttp
->
tsaps
,
(
long
)
self
,
NULL
);
ASSERT
(
tsap
==
self
,
return
-
1
;);
...
...
@@ -1365,31 +1365,44 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
struct
tsap_cb
*
irttp_dup
(
struct
tsap_cb
*
orig
,
void
*
instance
)
{
struct
tsap_cb
*
new
;
unsigned
long
flags
;
IRDA_DEBUG
(
1
,
__FUNCTION__
"()
\n
"
);
/* Protect our access to the old tsap instance */
spin_lock_irqsave
(
&
irttp
->
tsaps
->
hb_spinlock
,
flags
);
/* Find the old instance */
if
(
!
hashbin_find
(
irttp
->
tsaps
,
(
int
)
orig
,
NULL
))
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), unable to find TSAP
\n
"
);
spin_unlock_irqrestore
(
&
irttp
->
tsaps
->
hb_spinlock
,
flags
);
return
NULL
;
}
/* Allocate a new instance */
new
=
kmalloc
(
sizeof
(
struct
tsap_cb
),
GFP_ATOMIC
);
if
(
!
new
)
{
IRDA_DEBUG
(
0
,
__FUNCTION__
"(), unable to kmalloc
\n
"
);
spin_unlock_irqrestore
(
&
irttp
->
tsaps
->
hb_spinlock
,
flags
);
return
NULL
;
}
/* Dup */
memcpy
(
new
,
orig
,
sizeof
(
struct
tsap_cb
));
new
->
notify
.
instance
=
instance
;
new
->
lsap
=
irlmp_dup
(
orig
->
lsap
,
new
);
/* We don't need the old instance any more */
spin_unlock_irqrestore
(
&
irttp
->
tsaps
->
hb_spinlock
,
flags
);
/* Not everything should be copied */
new
->
notify
.
instance
=
instance
;
new
->
lsap
=
irlmp_dup
(
orig
->
lsap
,
new
);
init_timer
(
&
new
->
todo_timer
);
skb_queue_head_init
(
&
new
->
rx_queue
);
skb_queue_head_init
(
&
new
->
tx_queue
);
skb_queue_head_init
(
&
new
->
rx_fragments
);
hashbin_insert
(
irttp
->
tsaps
,
(
irda_queue_t
*
)
new
,
(
int
)
new
,
NULL
);
/* This is locked */
hashbin_insert
(
irttp
->
tsaps
,
(
irda_queue_t
*
)
new
,
(
long
)
new
,
NULL
);
return
new
;
}
...
...
@@ -1723,8 +1736,8 @@ int irttp_proc_read(char *buf, char **start, off_t offset, int len)
len
=
0
;
save_flags
(
flags
);
cli
(
);
/* Protect our access to the tsap list */
spin_lock_irqsave
(
&
irttp
->
tsaps
->
hb_spinlock
,
flags
);
self
=
(
struct
tsap_cb
*
)
hashbin_get_first
(
irttp
->
tsaps
);
while
(
self
!=
NULL
)
{
...
...
@@ -1770,7 +1783,7 @@ int irttp_proc_read(char *buf, char **start, off_t offset, int len)
self
=
(
struct
tsap_cb
*
)
hashbin_get_next
(
irttp
->
tsaps
);
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
irttp
->
tsaps
->
hb_spinlock
,
flags
);
return
len
;
}
...
...
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