Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
5fc98610
Commit
5fc98610
authored
Jul 19, 2007
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC64]: Handle multiple domain-services-port nodes properly.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
58fb6666
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
157 additions
and
94 deletions
+157
-94
arch/sparc64/kernel/ds.c
arch/sparc64/kernel/ds.c
+157
-94
No files found.
arch/sparc64/kernel/ds.c
View file @
5fc98610
...
@@ -124,10 +124,11 @@ struct ds_data_nack {
...
@@ -124,10 +124,11 @@ struct ds_data_nack {
__u64
result
;
__u64
result
;
};
};
struct
ds_info
;
struct
ds_cap_state
{
struct
ds_cap_state
{
__u64
handle
;
__u64
handle
;
void
(
*
data
)(
struct
ldc_channel
*
l
p
,
void
(
*
data
)(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
...
@@ -139,27 +140,27 @@ struct ds_cap_state {
...
@@ -139,27 +140,27 @@ struct ds_cap_state {
#define CAP_STATE_REGISTERED 0x02
#define CAP_STATE_REGISTERED 0x02
};
};
static
void
md_update_data
(
struct
ldc_channel
*
l
p
,
struct
ds_cap_state
*
cp
,
static
void
md_update_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
static
void
domain_shutdown_data
(
struct
ldc_channel
*
l
p
,
static
void
domain_shutdown_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
static
void
domain_panic_data
(
struct
ldc_channel
*
l
p
,
static
void
domain_panic_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
#ifdef CONFIG_HOTPLUG_CPU
#ifdef CONFIG_HOTPLUG_CPU
static
void
dr_cpu_data
(
struct
ldc_channel
*
l
p
,
static
void
dr_cpu_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
#endif
#endif
static
void
ds_pri_data
(
struct
ldc_channel
*
l
p
,
static
void
ds_pri_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
static
void
ds_var_data
(
struct
ldc_channel
*
l
p
,
static
void
ds_var_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
void
*
buf
,
int
len
);
struct
ds_cap_state
ds_states
[]
=
{
struct
ds_cap_state
ds_states
_template
[]
=
{
{
{
.
service_id
=
"md-update"
,
.
service_id
=
"md-update"
,
.
data
=
md_update_data
,
.
data
=
md_update_data
,
...
@@ -200,30 +201,38 @@ struct ds_info {
...
@@ -200,30 +201,38 @@ struct ds_info {
#define DS_HS_START 0x01
#define DS_HS_START 0x01
#define DS_HS_DONE 0x02
#define DS_HS_DONE 0x02
u64
id
;
void
*
rcv_buf
;
void
*
rcv_buf
;
int
rcv_buf_len
;
int
rcv_buf_len
;
struct
ds_cap_state
*
ds_states
;
int
num_ds_states
;
struct
ds_info
*
next
;
};
};
static
struct
ds_info
*
ds_info
;
static
struct
ds_info
*
ds_info
_list
;
static
struct
ds_cap_state
*
find_cap
(
u64
handle
)
static
struct
ds_cap_state
*
find_cap
(
struct
ds_info
*
dp
,
u64
handle
)
{
{
unsigned
int
index
=
handle
>>
32
;
unsigned
int
index
=
handle
>>
32
;
if
(
index
>=
ARRAY_SIZE
(
ds_states
)
)
if
(
index
>=
dp
->
num_ds_states
)
return
NULL
;
return
NULL
;
return
&
ds_states
[
index
];
return
&
d
p
->
d
s_states
[
index
];
}
}
static
struct
ds_cap_state
*
find_cap_by_string
(
const
char
*
name
)
static
struct
ds_cap_state
*
find_cap_by_string
(
struct
ds_info
*
dp
,
const
char
*
name
)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
)
;
i
++
)
{
for
(
i
=
0
;
i
<
dp
->
num_ds_states
;
i
++
)
{
if
(
strcmp
(
ds_states
[
i
].
service_id
,
name
))
if
(
strcmp
(
d
p
->
d
s_states
[
i
].
service_id
,
name
))
continue
;
continue
;
return
&
ds_states
[
i
];
return
&
d
p
->
d
s_states
[
i
];
}
}
return
NULL
;
return
NULL
;
}
}
...
@@ -264,10 +273,11 @@ struct ds_md_update_res {
...
@@ -264,10 +273,11 @@ struct ds_md_update_res {
__u32
result
;
__u32
result
;
};
};
static
void
md_update_data
(
struct
ldc_channel
*
l
p
,
static
void
md_update_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
void
*
buf
,
int
len
)
{
{
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_md_update_req
*
rp
;
struct
ds_md_update_req
*
rp
;
struct
{
struct
{
...
@@ -277,14 +287,14 @@ static void md_update_data(struct ldc_channel *lp,
...
@@ -277,14 +287,14 @@ static void md_update_data(struct ldc_channel *lp,
rp
=
(
struct
ds_md_update_req
*
)
(
dpkt
+
1
);
rp
=
(
struct
ds_md_update_req
*
)
(
dpkt
+
1
);
printk
(
KERN_INFO
PFX
"Machine description update.
\n
"
);
printk
(
KERN_INFO
"ds-%lu: Machine description update.
\n
"
,
dp
->
id
);
mdesc_update
();
mdesc_update
();
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
.
tag
.
type
=
DS_DATA
;
pkt
.
data
.
tag
.
type
=
DS_DATA
;
pkt
.
data
.
tag
.
len
=
sizeof
(
pkt
)
-
sizeof
(
struct
ds_msg_tag
);
pkt
.
data
.
tag
.
len
=
sizeof
(
pkt
)
-
sizeof
(
struct
ds_msg_tag
);
pkt
.
data
.
handle
=
d
p
->
handle
;
pkt
.
data
.
handle
=
c
p
->
handle
;
pkt
.
res
.
req_num
=
rp
->
req_num
;
pkt
.
res
.
req_num
=
rp
->
req_num
;
pkt
.
res
.
result
=
DS_OK
;
pkt
.
res
.
result
=
DS_OK
;
...
@@ -302,10 +312,11 @@ struct ds_shutdown_res {
...
@@ -302,10 +312,11 @@ struct ds_shutdown_res {
char
reason
[
1
];
char
reason
[
1
];
};
};
static
void
domain_shutdown_data
(
struct
ldc_channel
*
l
p
,
static
void
domain_shutdown_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
void
*
buf
,
int
len
)
{
{
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_shutdown_req
*
rp
;
struct
ds_shutdown_req
*
rp
;
struct
{
struct
{
...
@@ -315,13 +326,13 @@ static void domain_shutdown_data(struct ldc_channel *lp,
...
@@ -315,13 +326,13 @@ static void domain_shutdown_data(struct ldc_channel *lp,
rp
=
(
struct
ds_shutdown_req
*
)
(
dpkt
+
1
);
rp
=
(
struct
ds_shutdown_req
*
)
(
dpkt
+
1
);
printk
(
KERN_ALERT
PFX
"
Shutdown request from "
printk
(
KERN_ALERT
"ds-%lu:
Shutdown request from "
"LDOM manager received.
\n
"
);
"LDOM manager received.
\n
"
,
dp
->
id
);
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
.
tag
.
type
=
DS_DATA
;
pkt
.
data
.
tag
.
type
=
DS_DATA
;
pkt
.
data
.
tag
.
len
=
sizeof
(
pkt
)
-
sizeof
(
struct
ds_msg_tag
);
pkt
.
data
.
tag
.
len
=
sizeof
(
pkt
)
-
sizeof
(
struct
ds_msg_tag
);
pkt
.
data
.
handle
=
d
p
->
handle
;
pkt
.
data
.
handle
=
c
p
->
handle
;
pkt
.
res
.
req_num
=
rp
->
req_num
;
pkt
.
res
.
req_num
=
rp
->
req_num
;
pkt
.
res
.
result
=
DS_OK
;
pkt
.
res
.
result
=
DS_OK
;
pkt
.
res
.
reason
[
0
]
=
0
;
pkt
.
res
.
reason
[
0
]
=
0
;
...
@@ -341,10 +352,11 @@ struct ds_panic_res {
...
@@ -341,10 +352,11 @@ struct ds_panic_res {
char
reason
[
1
];
char
reason
[
1
];
};
};
static
void
domain_panic_data
(
struct
ldc_channel
*
l
p
,
static
void
domain_panic_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
void
*
buf
,
int
len
)
{
{
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_panic_req
*
rp
;
struct
ds_panic_req
*
rp
;
struct
{
struct
{
...
@@ -354,13 +366,13 @@ static void domain_panic_data(struct ldc_channel *lp,
...
@@ -354,13 +366,13 @@ static void domain_panic_data(struct ldc_channel *lp,
rp
=
(
struct
ds_panic_req
*
)
(
dpkt
+
1
);
rp
=
(
struct
ds_panic_req
*
)
(
dpkt
+
1
);
printk
(
KERN_ALERT
PFX
"
Panic request from "
printk
(
KERN_ALERT
"ds-%lu:
Panic request from "
"LDOM manager received.
\n
"
);
"LDOM manager received.
\n
"
,
dp
->
id
);
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
.
tag
.
type
=
DS_DATA
;
pkt
.
data
.
tag
.
type
=
DS_DATA
;
pkt
.
data
.
tag
.
len
=
sizeof
(
pkt
)
-
sizeof
(
struct
ds_msg_tag
);
pkt
.
data
.
tag
.
len
=
sizeof
(
pkt
)
-
sizeof
(
struct
ds_msg_tag
);
pkt
.
data
.
handle
=
d
p
->
handle
;
pkt
.
data
.
handle
=
c
p
->
handle
;
pkt
.
res
.
req_num
=
rp
->
req_num
;
pkt
.
res
.
req_num
=
rp
->
req_num
;
pkt
.
res
.
result
=
DS_OK
;
pkt
.
res
.
result
=
DS_OK
;
pkt
.
res
.
reason
[
0
]
=
0
;
pkt
.
res
.
reason
[
0
]
=
0
;
...
@@ -403,10 +415,11 @@ struct dr_cpu_resp_entry {
...
@@ -403,10 +415,11 @@ struct dr_cpu_resp_entry {
__u32
str_off
;
__u32
str_off
;
};
};
static
void
__dr_cpu_send_error
(
struct
ds_cap_state
*
cp
,
struct
ds_data
*
data
)
static
void
__dr_cpu_send_error
(
struct
ds_info
*
dp
,
struct
ds_cap_state
*
cp
,
struct
ds_data
*
data
)
{
{
struct
dr_cpu_tag
*
tag
=
(
struct
dr_cpu_tag
*
)
(
data
+
1
);
struct
dr_cpu_tag
*
tag
=
(
struct
dr_cpu_tag
*
)
(
data
+
1
);
struct
ds_info
*
dp
=
ds_info
;
struct
{
struct
{
struct
ds_data
data
;
struct
ds_data
data
;
struct
dr_cpu_tag
tag
;
struct
dr_cpu_tag
tag
;
...
@@ -428,12 +441,14 @@ static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data)
...
@@ -428,12 +441,14 @@ static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data)
__ds_send
(
dp
->
lp
,
&
pkt
,
msg_len
);
__ds_send
(
dp
->
lp
,
&
pkt
,
msg_len
);
}
}
static
void
dr_cpu_send_error
(
struct
ds_cap_state
*
cp
,
struct
ds_data
*
data
)
static
void
dr_cpu_send_error
(
struct
ds_info
*
dp
,
struct
ds_cap_state
*
cp
,
struct
ds_data
*
data
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ds_lock
,
flags
);
spin_lock_irqsave
(
&
ds_lock
,
flags
);
__dr_cpu_send_error
(
cp
,
data
);
__dr_cpu_send_error
(
dp
,
cp
,
data
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
}
}
...
@@ -511,7 +526,9 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
...
@@ -511,7 +526,9 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
}
}
}
}
static
int
dr_cpu_configure
(
struct
ds_cap_state
*
cp
,
u64
req_num
,
static
int
dr_cpu_configure
(
struct
ds_info
*
dp
,
struct
ds_cap_state
*
cp
,
u64
req_num
,
cpumask_t
*
mask
)
cpumask_t
*
mask
)
{
{
struct
ds_data
*
resp
;
struct
ds_data
*
resp
;
...
@@ -533,7 +550,8 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
...
@@ -533,7 +550,8 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
for_each_cpu_mask
(
cpu
,
*
mask
)
{
for_each_cpu_mask
(
cpu
,
*
mask
)
{
int
err
;
int
err
;
printk
(
KERN_INFO
PFX
"Starting cpu %d...
\n
"
,
cpu
);
printk
(
KERN_INFO
"ds-%lu: Starting cpu %d...
\n
"
,
dp
->
id
,
cpu
);
err
=
cpu_up
(
cpu
);
err
=
cpu_up
(
cpu
);
if
(
err
)
{
if
(
err
)
{
__u32
res
=
DR_CPU_RES_FAILURE
;
__u32
res
=
DR_CPU_RES_FAILURE
;
...
@@ -548,14 +566,14 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
...
@@ -548,14 +566,14 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
res
=
DR_CPU_RES_CPU_NOT_RESPONDING
;
res
=
DR_CPU_RES_CPU_NOT_RESPONDING
;
}
}
printk
(
KERN_INFO
PFX
"
CPU startup failed err=%d
\n
"
,
printk
(
KERN_INFO
"ds-%lu:
CPU startup failed err=%d
\n
"
,
err
);
dp
->
id
,
err
);
dr_cpu_mark
(
resp
,
cpu
,
ncpus
,
res
,
stat
);
dr_cpu_mark
(
resp
,
cpu
,
ncpus
,
res
,
stat
);
}
}
}
}
spin_lock_irqsave
(
&
ds_lock
,
flags
);
spin_lock_irqsave
(
&
ds_lock
,
flags
);
__ds_send
(
d
s_info
->
lp
,
resp
,
resp_len
);
__ds_send
(
d
p
->
lp
,
resp
,
resp_len
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
kfree
(
resp
);
kfree
(
resp
);
...
@@ -566,7 +584,9 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
...
@@ -566,7 +584,9 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
return
0
;
return
0
;
}
}
static
int
dr_cpu_unconfigure
(
struct
ds_cap_state
*
cp
,
u64
req_num
,
static
int
dr_cpu_unconfigure
(
struct
ds_info
*
dp
,
struct
ds_cap_state
*
cp
,
u64
req_num
,
cpumask_t
*
mask
)
cpumask_t
*
mask
)
{
{
struct
ds_data
*
resp
;
struct
ds_data
*
resp
;
...
@@ -586,8 +606,8 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
...
@@ -586,8 +606,8 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
for_each_cpu_mask
(
cpu
,
*
mask
)
{
for_each_cpu_mask
(
cpu
,
*
mask
)
{
int
err
;
int
err
;
printk
(
KERN_INFO
PFX
"CPU[%d]
: Shutting down cpu %d...
\n
"
,
printk
(
KERN_INFO
"ds-%lu
: Shutting down cpu %d...
\n
"
,
smp_processor_id
()
,
cpu
);
dp
->
id
,
cpu
);
err
=
cpu_down
(
cpu
);
err
=
cpu_down
(
cpu
);
if
(
err
)
if
(
err
)
dr_cpu_mark
(
resp
,
cpu
,
ncpus
,
dr_cpu_mark
(
resp
,
cpu
,
ncpus
,
...
@@ -596,7 +616,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
...
@@ -596,7 +616,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
}
}
spin_lock_irqsave
(
&
ds_lock
,
flags
);
spin_lock_irqsave
(
&
ds_lock
,
flags
);
__ds_send
(
d
s_info
->
lp
,
resp
,
resp_len
);
__ds_send
(
d
p
->
lp
,
resp
,
resp_len
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
kfree
(
resp
);
kfree
(
resp
);
...
@@ -604,7 +624,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
...
@@ -604,7 +624,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
return
0
;
return
0
;
}
}
static
void
dr_cpu_data
(
struct
ldc_channel
*
l
p
,
static
void
dr_cpu_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
)
void
*
buf
,
int
len
)
{
{
...
@@ -623,7 +643,7 @@ static void dr_cpu_data(struct ldc_channel *lp,
...
@@ -623,7 +643,7 @@ static void dr_cpu_data(struct ldc_channel *lp,
break
;
break
;
default:
default:
dr_cpu_send_error
(
cp
,
data
);
dr_cpu_send_error
(
dp
,
cp
,
data
);
return
;
return
;
}
}
...
@@ -639,12 +659,12 @@ static void dr_cpu_data(struct ldc_channel *lp,
...
@@ -639,12 +659,12 @@ static void dr_cpu_data(struct ldc_channel *lp,
}
}
if
(
tag
->
type
==
DR_CPU_CONFIGURE
)
if
(
tag
->
type
==
DR_CPU_CONFIGURE
)
err
=
dr_cpu_configure
(
cp
,
req_num
,
&
mask
);
err
=
dr_cpu_configure
(
dp
,
cp
,
req_num
,
&
mask
);
else
else
err
=
dr_cpu_unconfigure
(
cp
,
req_num
,
&
mask
);
err
=
dr_cpu_unconfigure
(
dp
,
cp
,
req_num
,
&
mask
);
if
(
err
)
if
(
err
)
dr_cpu_send_error
(
cp
,
data
);
dr_cpu_send_error
(
dp
,
cp
,
data
);
}
}
#endif
/* CONFIG_HOTPLUG_CPU */
#endif
/* CONFIG_HOTPLUG_CPU */
...
@@ -656,8 +676,8 @@ struct ds_pri_msg {
...
@@ -656,8 +676,8 @@ struct ds_pri_msg {
#define DS_PRI_UPDATE 0x02
#define DS_PRI_UPDATE 0x02
};
};
static
void
ds_pri_data
(
struct
ldc_channel
*
l
p
,
static
void
ds_pri_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
void
*
buf
,
int
len
)
{
{
struct
ds_data
*
dpkt
=
buf
;
struct
ds_data
*
dpkt
=
buf
;
...
@@ -665,8 +685,8 @@ static void ds_pri_data(struct ldc_channel *lp,
...
@@ -665,8 +685,8 @@ static void ds_pri_data(struct ldc_channel *lp,
rp
=
(
struct
ds_pri_msg
*
)
(
dpkt
+
1
);
rp
=
(
struct
ds_pri_msg
*
)
(
dpkt
+
1
);
printk
(
KERN_INFO
PFX
"
PRI REQ [%lx:%lx], len=%d
\n
"
,
printk
(
KERN_INFO
"ds-%lu:
PRI REQ [%lx:%lx], len=%d
\n
"
,
rp
->
req_num
,
rp
->
type
,
len
);
dp
->
id
,
rp
->
req_num
,
rp
->
type
,
len
);
}
}
struct
ds_var_hdr
{
struct
ds_var_hdr
{
...
@@ -701,8 +721,8 @@ static DEFINE_MUTEX(ds_var_mutex);
...
@@ -701,8 +721,8 @@ static DEFINE_MUTEX(ds_var_mutex);
static
int
ds_var_doorbell
;
static
int
ds_var_doorbell
;
static
int
ds_var_response
;
static
int
ds_var_response
;
static
void
ds_var_data
(
struct
ldc_channel
*
l
p
,
static
void
ds_var_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
void
*
buf
,
int
len
)
{
{
struct
ds_data
*
dpkt
=
buf
;
struct
ds_data
*
dpkt
=
buf
;
...
@@ -721,14 +741,35 @@ static void ds_var_data(struct ldc_channel *lp,
...
@@ -721,14 +741,35 @@ static void ds_var_data(struct ldc_channel *lp,
void
ldom_set_var
(
const
char
*
var
,
const
char
*
value
)
void
ldom_set_var
(
const
char
*
var
,
const
char
*
value
)
{
{
struct
ds_info
*
dp
=
ds_info
;
struct
ds_cap_state
*
cp
;
struct
ds_cap_state
*
cp
;
struct
ds_info
*
dp
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
ds_lock
,
flags
);
cp
=
NULL
;
for
(
dp
=
ds_info_list
;
dp
;
dp
=
dp
->
next
)
{
struct
ds_cap_state
*
tmp
;
tmp
=
find_cap_by_string
(
dp
,
"var-config"
);
if
(
tmp
&&
tmp
->
state
==
CAP_STATE_REGISTERED
)
{
cp
=
tmp
;
break
;
}
}
if
(
!
cp
)
{
for
(
dp
=
ds_info_list
;
dp
;
dp
=
dp
->
next
)
{
struct
ds_cap_state
*
tmp
;
cp
=
find_cap_by_string
(
"var-config"
);
tmp
=
find_cap_by_string
(
dp
,
"var-config-backup"
);
if
(
cp
->
state
!=
CAP_STATE_REGISTERED
)
if
(
tmp
&&
tmp
->
state
==
CAP_STATE_REGISTERED
)
{
cp
=
find_cap_by_string
(
"var-config-backup"
);
cp
=
tmp
;
break
;
}
}
}
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
if
(
cp
->
state
==
CAP_STATE_REGISTERED
)
{
if
(
cp
)
{
union
{
union
{
struct
{
struct
{
struct
ds_data
data
;
struct
ds_data
data
;
...
@@ -736,7 +777,6 @@ void ldom_set_var(const char *var, const char *value)
...
@@ -736,7 +777,6 @@ void ldom_set_var(const char *var, const char *value)
}
header
;
}
header
;
char
all
[
512
];
char
all
[
512
];
}
pkt
;
}
pkt
;
unsigned
long
flags
;
char
*
base
,
*
p
;
char
*
base
,
*
p
;
int
msg_len
,
loops
;
int
msg_len
,
loops
;
...
@@ -777,9 +817,9 @@ void ldom_set_var(const char *var, const char *value)
...
@@ -777,9 +817,9 @@ void ldom_set_var(const char *var, const char *value)
if
(
ds_var_doorbell
==
0
||
if
(
ds_var_doorbell
==
0
||
ds_var_response
!=
DS_VAR_SUCCESS
)
ds_var_response
!=
DS_VAR_SUCCESS
)
printk
(
KERN_ERR
PFX
"
var-config [%s:%s] "
printk
(
KERN_ERR
"ds-%lu:
var-config [%s:%s] "
"failed, response(%d).
\n
"
,
"failed, response(%d).
\n
"
,
var
,
value
,
dp
->
id
,
var
,
value
,
ds_var_response
);
ds_var_response
);
}
else
{
}
else
{
printk
(
KERN_ERR
PFX
"var-config not registered so "
printk
(
KERN_ERR
PFX
"var-config not registered so "
...
@@ -811,8 +851,8 @@ void ldom_power_off(void)
...
@@ -811,8 +851,8 @@ void ldom_power_off(void)
static
void
ds_conn_reset
(
struct
ds_info
*
dp
)
static
void
ds_conn_reset
(
struct
ds_info
*
dp
)
{
{
printk
(
KERN_ERR
PFX
"
ds_conn_reset() from %p
\n
"
,
printk
(
KERN_ERR
"ds-%lu:
ds_conn_reset() from %p
\n
"
,
__builtin_return_address
(
0
));
dp
->
id
,
__builtin_return_address
(
0
));
}
}
static
int
register_services
(
struct
ds_info
*
dp
)
static
int
register_services
(
struct
ds_info
*
dp
)
...
@@ -820,12 +860,12 @@ static int register_services(struct ds_info *dp)
...
@@ -820,12 +860,12 @@ static int register_services(struct ds_info *dp)
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ldc_channel
*
lp
=
dp
->
lp
;
int
i
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
)
;
i
++
)
{
for
(
i
=
0
;
i
<
dp
->
num_ds_states
;
i
++
)
{
struct
{
struct
{
struct
ds_reg_req
req
;
struct
ds_reg_req
req
;
u8
id_buf
[
256
];
u8
id_buf
[
256
];
}
pbuf
;
}
pbuf
;
struct
ds_cap_state
*
cp
=
&
ds_states
[
i
];
struct
ds_cap_state
*
cp
=
&
d
p
->
d
s_states
[
i
];
int
err
,
msg_len
;
int
err
,
msg_len
;
u64
new_count
;
u64
new_count
;
...
@@ -870,28 +910,28 @@ static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
...
@@ -870,28 +910,28 @@ static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
if
(
pkt
->
type
==
DS_REG_ACK
)
{
if
(
pkt
->
type
==
DS_REG_ACK
)
{
struct
ds_reg_ack
*
ap
=
(
struct
ds_reg_ack
*
)
pkt
;
struct
ds_reg_ack
*
ap
=
(
struct
ds_reg_ack
*
)
pkt
;
struct
ds_cap_state
*
cp
=
find_cap
(
ap
->
handle
);
struct
ds_cap_state
*
cp
=
find_cap
(
dp
,
ap
->
handle
);
if
(
!
cp
)
{
if
(
!
cp
)
{
printk
(
KERN_ERR
PFX
"REG ACK for unknown handle %lx
\n
"
,
printk
(
KERN_ERR
"ds-%lu: REG ACK for unknown "
ap
->
handle
);
"handle %lx
\n
"
,
dp
->
id
,
ap
->
handle
);
return
0
;
return
0
;
}
}
printk
(
KERN_INFO
PFX
"
Registered %s service.
\n
"
,
printk
(
KERN_INFO
"ds-%lu:
Registered %s service.
\n
"
,
cp
->
service_id
);
dp
->
id
,
cp
->
service_id
);
cp
->
state
=
CAP_STATE_REGISTERED
;
cp
->
state
=
CAP_STATE_REGISTERED
;
}
else
if
(
pkt
->
type
==
DS_REG_NACK
)
{
}
else
if
(
pkt
->
type
==
DS_REG_NACK
)
{
struct
ds_reg_nack
*
np
=
(
struct
ds_reg_nack
*
)
pkt
;
struct
ds_reg_nack
*
np
=
(
struct
ds_reg_nack
*
)
pkt
;
struct
ds_cap_state
*
cp
=
find_cap
(
np
->
handle
);
struct
ds_cap_state
*
cp
=
find_cap
(
dp
,
np
->
handle
);
if
(
!
cp
)
{
if
(
!
cp
)
{
printk
(
KERN_ERR
PFX
"
REG NACK for "
printk
(
KERN_ERR
"ds-%lu:
REG NACK for "
"unknown handle %lx
\n
"
,
"unknown handle %lx
\n
"
,
np
->
handle
);
dp
->
id
,
np
->
handle
);
return
0
;
return
0
;
}
}
printk
(
KERN_INFO
PFX
"
Could not register %s service
\n
"
,
printk
(
KERN_INFO
"ds-%lu:
Could not register %s service
\n
"
,
cp
->
service_id
);
dp
->
id
,
cp
->
service_id
);
cp
->
state
=
CAP_STATE_UNKNOWN
;
cp
->
state
=
CAP_STATE_UNKNOWN
;
}
}
...
@@ -922,6 +962,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ds_wait);
...
@@ -922,6 +962,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ds_wait);
struct
ds_queue_entry
{
struct
ds_queue_entry
{
struct
list_head
list
;
struct
list_head
list
;
struct
ds_info
*
dp
;
int
req_len
;
int
req_len
;
int
__pad
;
int
__pad
;
u64
req
[
0
];
u64
req
[
0
];
...
@@ -930,7 +971,6 @@ struct ds_queue_entry {
...
@@ -930,7 +971,6 @@ struct ds_queue_entry {
static
void
process_ds_work
(
void
)
static
void
process_ds_work
(
void
)
{
{
struct
ds_queue_entry
*
qp
,
*
tmp
;
struct
ds_queue_entry
*
qp
,
*
tmp
;
static
struct
ds_info
*
dp
;
unsigned
long
flags
;
unsigned
long
flags
;
LIST_HEAD
(
todo
);
LIST_HEAD
(
todo
);
...
@@ -939,22 +979,22 @@ static void process_ds_work(void)
...
@@ -939,22 +979,22 @@ static void process_ds_work(void)
INIT_LIST_HEAD
(
&
ds_work_list
);
INIT_LIST_HEAD
(
&
ds_work_list
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
dp
=
ds_info
;
list_for_each_entry_safe
(
qp
,
tmp
,
&
todo
,
list
)
{
list_for_each_entry_safe
(
qp
,
tmp
,
&
todo
,
list
)
{
struct
ds_data
*
dpkt
=
(
struct
ds_data
*
)
qp
->
req
;
struct
ds_data
*
dpkt
=
(
struct
ds_data
*
)
qp
->
req
;
struct
ds_cap_state
*
cp
=
find_cap
(
dpkt
->
handle
);
struct
ds_info
*
dp
=
qp
->
dp
;
struct
ds_cap_state
*
cp
=
find_cap
(
dp
,
dpkt
->
handle
);
int
req_len
=
qp
->
req_len
;
int
req_len
=
qp
->
req_len
;
if
(
!
cp
)
{
if
(
!
cp
)
{
printk
(
KERN_ERR
PFX
"Data for unknown handle %lu
\n
"
,
printk
(
KERN_ERR
"ds-%lu: Data for unknown "
dpkt
->
handle
);
"handle %lu
\n
"
,
dp
->
id
,
dpkt
->
handle
);
spin_lock_irqsave
(
&
ds_lock
,
flags
);
spin_lock_irqsave
(
&
ds_lock
,
flags
);
__send_ds_nack
(
dp
,
dpkt
->
handle
);
__send_ds_nack
(
dp
,
dpkt
->
handle
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
}
else
{
}
else
{
cp
->
data
(
dp
->
lp
,
cp
,
dpkt
,
req_len
);
cp
->
data
(
dp
,
cp
,
dpkt
,
req_len
);
}
}
list_del
(
&
qp
->
list
);
list_del
(
&
qp
->
list
);
...
@@ -990,6 +1030,7 @@ static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
...
@@ -990,6 +1030,7 @@ static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
if
(
!
qp
)
{
if
(
!
qp
)
{
__send_ds_nack
(
dp
,
dpkt
->
handle
);
__send_ds_nack
(
dp
,
dpkt
->
handle
);
}
else
{
}
else
{
qp
->
dp
=
dp
;
memcpy
(
&
qp
->
req
,
pkt
,
len
);
memcpy
(
&
qp
->
req
,
pkt
,
len
);
list_add_tail
(
&
qp
->
list
,
&
ds_work_list
);
list_add_tail
(
&
qp
->
list
,
&
ds_work_list
);
wake_up
(
&
ds_wait
);
wake_up
(
&
ds_wait
);
...
@@ -1019,8 +1060,8 @@ static void ds_reset(struct ds_info *dp)
...
@@ -1019,8 +1060,8 @@ static void ds_reset(struct ds_info *dp)
dp
->
hs_state
=
0
;
dp
->
hs_state
=
0
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
)
;
i
++
)
{
for
(
i
=
0
;
i
<
dp
->
num_ds_states
;
i
++
)
{
struct
ds_cap_state
*
cp
=
&
ds_states
[
i
];
struct
ds_cap_state
*
cp
=
&
d
p
->
d
s_states
[
i
];
cp
->
state
=
CAP_STATE_UNKNOWN
;
cp
->
state
=
CAP_STATE_UNKNOWN
;
}
}
...
@@ -1048,7 +1089,8 @@ static void ds_event(void *arg, int event)
...
@@ -1048,7 +1089,8 @@ static void ds_event(void *arg, int event)
}
}
if
(
event
!=
LDC_EVENT_DATA_READY
)
{
if
(
event
!=
LDC_EVENT_DATA_READY
)
{
printk
(
KERN_WARNING
PFX
"Unexpected LDC event %d
\n
"
,
event
);
printk
(
KERN_WARNING
"ds-%lu: Unexpected LDC event %d
\n
"
,
dp
->
id
,
event
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
return
;
return
;
}
}
...
@@ -1099,9 +1141,11 @@ static int __devinit ds_probe(struct vio_dev *vdev,
...
@@ -1099,9 +1141,11 @@ static int __devinit ds_probe(struct vio_dev *vdev,
.
mtu
=
4096
,
.
mtu
=
4096
,
.
mode
=
LDC_MODE_STREAM
,
.
mode
=
LDC_MODE_STREAM
,
};
};
struct
mdesc_handle
*
hp
;
struct
ldc_channel
*
lp
;
struct
ldc_channel
*
lp
;
struct
ds_info
*
dp
;
struct
ds_info
*
dp
;
int
err
;
const
u64
*
val
;
int
err
,
i
;
if
(
ds_version_printed
++
==
0
)
if
(
ds_version_printed
++
==
0
)
printk
(
KERN_INFO
"%s"
,
version
);
printk
(
KERN_INFO
"%s"
,
version
);
...
@@ -1111,19 +1155,37 @@ static int __devinit ds_probe(struct vio_dev *vdev,
...
@@ -1111,19 +1155,37 @@ static int __devinit ds_probe(struct vio_dev *vdev,
if
(
!
dp
)
if
(
!
dp
)
goto
out_err
;
goto
out_err
;
hp
=
mdesc_grab
();
val
=
mdesc_get_property
(
hp
,
vdev
->
mp
,
"id"
,
NULL
);
if
(
val
)
dp
->
id
=
*
val
;
mdesc_release
(
hp
);
dp
->
rcv_buf
=
kzalloc
(
4096
,
GFP_KERNEL
);
dp
->
rcv_buf
=
kzalloc
(
4096
,
GFP_KERNEL
);
if
(
!
dp
->
rcv_buf
)
if
(
!
dp
->
rcv_buf
)
goto
out_free_dp
;
goto
out_free_dp
;
dp
->
rcv_buf_len
=
4096
;
dp
->
rcv_buf_len
=
4096
;
dp
->
ds_states
=
kzalloc
(
sizeof
(
ds_states_template
),
GFP_KERNEL
);
if
(
!
dp
->
ds_states
)
goto
out_free_rcv_buf
;
memcpy
(
dp
->
ds_states
,
ds_states_template
,
sizeof
(
ds_states_template
));
dp
->
num_ds_states
=
ARRAY_SIZE
(
ds_states_template
);
for
(
i
=
0
;
i
<
dp
->
num_ds_states
;
i
++
)
dp
->
ds_states
[
i
].
handle
=
((
u64
)
i
<<
32
);
ds_cfg
.
tx_irq
=
vdev
->
tx_irq
;
ds_cfg
.
tx_irq
=
vdev
->
tx_irq
;
ds_cfg
.
rx_irq
=
vdev
->
rx_irq
;
ds_cfg
.
rx_irq
=
vdev
->
rx_irq
;
lp
=
ldc_alloc
(
vdev
->
channel_id
,
&
ds_cfg
,
dp
);
lp
=
ldc_alloc
(
vdev
->
channel_id
,
&
ds_cfg
,
dp
);
if
(
IS_ERR
(
lp
))
{
if
(
IS_ERR
(
lp
))
{
err
=
PTR_ERR
(
lp
);
err
=
PTR_ERR
(
lp
);
goto
out_free_
rcv_buf
;
goto
out_free_
ds_states
;
}
}
dp
->
lp
=
lp
;
dp
->
lp
=
lp
;
...
@@ -1131,13 +1193,19 @@ static int __devinit ds_probe(struct vio_dev *vdev,
...
@@ -1131,13 +1193,19 @@ static int __devinit ds_probe(struct vio_dev *vdev,
if
(
err
)
if
(
err
)
goto
out_free_ldc
;
goto
out_free_ldc
;
ds_info
=
dp
;
spin_lock_irq
(
&
ds_lock
);
dp
->
next
=
ds_info_list
;
ds_info_list
=
dp
;
spin_unlock_irq
(
&
ds_lock
);
return
err
;
return
err
;
out_free_ldc:
out_free_ldc:
ldc_free
(
dp
->
lp
);
ldc_free
(
dp
->
lp
);
out_free_ds_states:
kfree
(
dp
->
ds_states
);
out_free_rcv_buf:
out_free_rcv_buf:
kfree
(
dp
->
rcv_buf
);
kfree
(
dp
->
rcv_buf
);
...
@@ -1172,11 +1240,6 @@ static struct vio_driver ds_driver = {
...
@@ -1172,11 +1240,6 @@ static struct vio_driver ds_driver = {
static
int
__init
ds_init
(
void
)
static
int
__init
ds_init
(
void
)
{
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
);
i
++
)
ds_states
[
i
].
handle
=
((
u64
)
i
<<
32
);
kthread_run
(
ds_thread
,
NULL
,
"kldomd"
);
kthread_run
(
ds_thread
,
NULL
,
"kldomd"
);
return
vio_register_driver
(
&
ds_driver
);
return
vio_register_driver
(
&
ds_driver
);
...
...
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