Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
R128
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Ermine
R128
Commits
5fc98610
Commit
5fc98610
authored
17 years ago
by
David S. Miller
Browse files
Options
Downloads
Patches
Plain Diff
[SPARC64]: Handle multiple domain-services-port nodes properly.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
58fb6666
Loading
Loading
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
arch/sparc64/kernel/ds.c
+157
-94
157 additions, 94 deletions
arch/sparc64/kernel/ds.c
with
157 additions
and
94 deletions
arch/sparc64/kernel/ds.c
+
157
−
94
View file @
5fc98610
...
...
@@ -124,10 +124,11 @@ struct ds_data_nack {
__u64
result
;
};
struct
ds_info
;
struct
ds_cap_state
{
__u64
handle
;
void
(
*
data
)(
struct
ldc_channel
*
l
p
,
void
(
*
data
)(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
cp
,
void
*
buf
,
int
len
);
...
...
@@ -139,27 +140,27 @@ struct ds_cap_state {
#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
);
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
,
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
,
void
*
buf
,
int
len
);
#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
,
void
*
buf
,
int
len
);
#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
,
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
,
void
*
buf
,
int
len
);
struct
ds_cap_state
ds_states
[]
=
{
struct
ds_cap_state
ds_states
_template
[]
=
{
{
.
service_id
=
"md-update"
,
.
data
=
md_update_data
,
...
...
@@ -200,30 +201,38 @@ struct ds_info {
#define DS_HS_START 0x01
#define DS_HS_DONE 0x02
u64
id
;
void
*
rcv_buf
;
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
;
if
(
index
>=
ARRAY_SIZE
(
ds_states
)
)
if
(
index
>=
dp
->
num_
ds_states
)
return
NULL
;
return
&
ds_states
[
index
];
return
&
dp
->
ds_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
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
)
;
i
++
)
{
if
(
strcmp
(
ds_states
[
i
].
service_id
,
name
))
for
(
i
=
0
;
i
<
dp
->
num_
ds_states
;
i
++
)
{
if
(
strcmp
(
dp
->
ds_states
[
i
].
service_id
,
name
))
continue
;
return
&
ds_states
[
i
];
return
&
dp
->
ds_states
[
i
];
}
return
NULL
;
}
...
...
@@ -264,10 +273,11 @@ struct ds_md_update_res {
__u32
result
;
};
static
void
md_update_data
(
struct
ldc_channel
*
l
p
,
struct
ds_cap_state
*
d
p
,
static
void
md_update_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
{
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_md_update_req
*
rp
;
struct
{
...
...
@@ -277,14 +287,14 @@ static void md_update_data(struct ldc_channel *lp,
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
();
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
.
tag
.
type
=
DS_DATA
;
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
.
result
=
DS_OK
;
...
...
@@ -302,10 +312,11 @@ struct ds_shutdown_res {
char
reason
[
1
];
};
static
void
domain_shutdown_data
(
struct
ldc_channel
*
l
p
,
struct
ds_cap_state
*
d
p
,
static
void
domain_shutdown_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
{
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_shutdown_req
*
rp
;
struct
{
...
...
@@ -315,13 +326,13 @@ static void domain_shutdown_data(struct ldc_channel *lp,
rp
=
(
struct
ds_shutdown_req
*
)
(
dpkt
+
1
);
printk
(
KERN_ALERT
PFX
"
Shutdown request from "
"LDOM manager received.
\n
"
);
printk
(
KERN_ALERT
"ds-%lu:
Shutdown request from "
"LDOM manager received.
\n
"
,
dp
->
id
);
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
.
tag
.
type
=
DS_DATA
;
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
.
result
=
DS_OK
;
pkt
.
res
.
reason
[
0
]
=
0
;
...
...
@@ -341,10 +352,11 @@ struct ds_panic_res {
char
reason
[
1
];
};
static
void
domain_panic_data
(
struct
ldc_channel
*
l
p
,
struct
ds_cap_state
*
d
p
,
static
void
domain_panic_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
{
struct
ldc_channel
*
lp
=
dp
->
lp
;
struct
ds_data
*
dpkt
=
buf
;
struct
ds_panic_req
*
rp
;
struct
{
...
...
@@ -354,13 +366,13 @@ static void domain_panic_data(struct ldc_channel *lp,
rp
=
(
struct
ds_panic_req
*
)
(
dpkt
+
1
);
printk
(
KERN_ALERT
PFX
"
Panic request from "
"LDOM manager received.
\n
"
);
printk
(
KERN_ALERT
"ds-%lu:
Panic request from "
"LDOM manager received.
\n
"
,
dp
->
id
);
memset
(
&
pkt
,
0
,
sizeof
(
pkt
));
pkt
.
data
.
tag
.
type
=
DS_DATA
;
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
.
result
=
DS_OK
;
pkt
.
res
.
reason
[
0
]
=
0
;
...
...
@@ -403,10 +415,11 @@ struct dr_cpu_resp_entry {
__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
ds_info
*
dp
=
ds_info
;
struct
{
struct
ds_data
data
;
struct
dr_cpu_tag
tag
;
...
...
@@ -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
);
}
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
;
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
);
}
...
...
@@ -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
)
{
struct
ds_data
*
resp
;
...
...
@@ -533,7 +550,8 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
for_each_cpu_mask
(
cpu
,
*
mask
)
{
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
);
if
(
err
)
{
__u32
res
=
DR_CPU_RES_FAILURE
;
...
...
@@ -548,14 +566,14 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
res
=
DR_CPU_RES_CPU_NOT_RESPONDING
;
}
printk
(
KERN_INFO
PFX
"
CPU startup failed err=%d
\n
"
,
err
);
printk
(
KERN_INFO
"ds-%lu:
CPU startup failed err=%d
\n
"
,
dp
->
id
,
err
);
dr_cpu_mark
(
resp
,
cpu
,
ncpus
,
res
,
stat
);
}
}
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
);
kfree
(
resp
);
...
...
@@ -566,7 +584,9 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
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
)
{
struct
ds_data
*
resp
;
...
...
@@ -586,8 +606,8 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
for_each_cpu_mask
(
cpu
,
*
mask
)
{
int
err
;
printk
(
KERN_INFO
PFX
"CPU[%d]
: Shutting down cpu %d...
\n
"
,
smp_processor_id
()
,
cpu
);
printk
(
KERN_INFO
"ds-%lu
: Shutting down cpu %d...
\n
"
,
dp
->
id
,
cpu
);
err
=
cpu_down
(
cpu
);
if
(
err
)
dr_cpu_mark
(
resp
,
cpu
,
ncpus
,
...
...
@@ -596,7 +616,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
}
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
);
kfree
(
resp
);
...
...
@@ -604,7 +624,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
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
,
void
*
buf
,
int
len
)
{
...
...
@@ -623,7 +643,7 @@ static void dr_cpu_data(struct ldc_channel *lp,
break
;
default:
dr_cpu_send_error
(
cp
,
data
);
dr_cpu_send_error
(
dp
,
cp
,
data
);
return
;
}
...
...
@@ -639,12 +659,12 @@ static void dr_cpu_data(struct ldc_channel *lp,
}
if
(
tag
->
type
==
DR_CPU_CONFIGURE
)
err
=
dr_cpu_configure
(
cp
,
req_num
,
&
mask
);
err
=
dr_cpu_configure
(
dp
,
cp
,
req_num
,
&
mask
);
else
err
=
dr_cpu_unconfigure
(
cp
,
req_num
,
&
mask
);
err
=
dr_cpu_unconfigure
(
dp
,
cp
,
req_num
,
&
mask
);
if
(
err
)
dr_cpu_send_error
(
cp
,
data
);
dr_cpu_send_error
(
dp
,
cp
,
data
);
}
#endif
/* CONFIG_HOTPLUG_CPU */
...
...
@@ -656,8 +676,8 @@ struct ds_pri_msg {
#define DS_PRI_UPDATE 0x02
};
static
void
ds_pri_data
(
struct
ldc_channel
*
l
p
,
struct
ds_cap_state
*
d
p
,
static
void
ds_pri_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
{
struct
ds_data
*
dpkt
=
buf
;
...
...
@@ -665,8 +685,8 @@ static void ds_pri_data(struct ldc_channel *lp,
rp
=
(
struct
ds_pri_msg
*
)
(
dpkt
+
1
);
printk
(
KERN_INFO
PFX
"
PRI REQ [%lx:%lx], len=%d
\n
"
,
rp
->
req_num
,
rp
->
type
,
len
);
printk
(
KERN_INFO
"ds-%lu:
PRI REQ [%lx:%lx], len=%d
\n
"
,
dp
->
id
,
rp
->
req_num
,
rp
->
type
,
len
);
}
struct
ds_var_hdr
{
...
...
@@ -701,8 +721,8 @@ static DEFINE_MUTEX(ds_var_mutex);
static
int
ds_var_doorbell
;
static
int
ds_var_response
;
static
void
ds_var_data
(
struct
ldc_channel
*
l
p
,
struct
ds_cap_state
*
d
p
,
static
void
ds_var_data
(
struct
ds_info
*
d
p
,
struct
ds_cap_state
*
c
p
,
void
*
buf
,
int
len
)
{
struct
ds_data
*
dpkt
=
buf
;
...
...
@@ -721,14 +741,35 @@ static void ds_var_data(struct ldc_channel *lp,
void
ldom_set_var
(
const
char
*
var
,
const
char
*
value
)
{
struct
ds_info
*
dp
=
ds_info
;
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"
);
if
(
cp
->
state
!=
CAP_STATE_REGISTERED
)
cp
=
find_cap_by_string
(
"var-config-backup"
);
tmp
=
find_cap_by_string
(
dp
,
"var-config-backup"
);
if
(
tmp
&&
tmp
->
state
==
CAP_STATE_REGISTERED
)
{
cp
=
tmp
;
break
;
}
}
}
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
if
(
cp
->
state
==
CAP_STATE_REGISTERED
)
{
if
(
cp
)
{
union
{
struct
{
struct
ds_data
data
;
...
...
@@ -736,7 +777,6 @@ void ldom_set_var(const char *var, const char *value)
}
header
;
char
all
[
512
];
}
pkt
;
unsigned
long
flags
;
char
*
base
,
*
p
;
int
msg_len
,
loops
;
...
...
@@ -777,9 +817,9 @@ void ldom_set_var(const char *var, const char *value)
if
(
ds_var_doorbell
==
0
||
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
"
,
var
,
value
,
dp
->
id
,
var
,
value
,
ds_var_response
);
}
else
{
printk
(
KERN_ERR
PFX
"var-config not registered so "
...
...
@@ -811,8 +851,8 @@ void ldom_power_off(void)
static
void
ds_conn_reset
(
struct
ds_info
*
dp
)
{
printk
(
KERN_ERR
PFX
"
ds_conn_reset() from %p
\n
"
,
__builtin_return_address
(
0
));
printk
(
KERN_ERR
"ds-%lu:
ds_conn_reset() from %p
\n
"
,
dp
->
id
,
__builtin_return_address
(
0
));
}
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
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
)
;
i
++
)
{
for
(
i
=
0
;
i
<
dp
->
num_
ds_states
;
i
++
)
{
struct
{
struct
ds_reg_req
req
;
u8
id_buf
[
256
];
}
pbuf
;
struct
ds_cap_state
*
cp
=
&
ds_states
[
i
];
struct
ds_cap_state
*
cp
=
&
dp
->
ds_states
[
i
];
int
err
,
msg_len
;
u64
new_count
;
...
...
@@ -870,28 +910,28 @@ static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
if
(
pkt
->
type
==
DS_REG_ACK
)
{
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
)
{
printk
(
KERN_ERR
PFX
"
REG ACK for unknown
handle %lx
\n
"
,
ap
->
handle
);
printk
(
KERN_ERR
"ds-%lu:
REG ACK for unknown
"
"handle %lx
\n
"
,
dp
->
id
,
ap
->
handle
);
return
0
;
}
printk
(
KERN_INFO
PFX
"
Registered %s service.
\n
"
,
cp
->
service_id
);
printk
(
KERN_INFO
"ds-%lu:
Registered %s service.
\n
"
,
dp
->
id
,
cp
->
service_id
);
cp
->
state
=
CAP_STATE_REGISTERED
;
}
else
if
(
pkt
->
type
==
DS_REG_NACK
)
{
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
)
{
printk
(
KERN_ERR
PFX
"
REG NACK for "
printk
(
KERN_ERR
"ds-%lu:
REG NACK for "
"unknown handle %lx
\n
"
,
np
->
handle
);
dp
->
id
,
np
->
handle
);
return
0
;
}
printk
(
KERN_INFO
PFX
"
Could not register %s service
\n
"
,
cp
->
service_id
);
printk
(
KERN_INFO
"ds-%lu:
Could not register %s service
\n
"
,
dp
->
id
,
cp
->
service_id
);
cp
->
state
=
CAP_STATE_UNKNOWN
;
}
...
...
@@ -922,6 +962,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ds_wait);
struct
ds_queue_entry
{
struct
list_head
list
;
struct
ds_info
*
dp
;
int
req_len
;
int
__pad
;
u64
req
[
0
];
...
...
@@ -930,7 +971,6 @@ struct ds_queue_entry {
static
void
process_ds_work
(
void
)
{
struct
ds_queue_entry
*
qp
,
*
tmp
;
static
struct
ds_info
*
dp
;
unsigned
long
flags
;
LIST_HEAD
(
todo
);
...
...
@@ -939,22 +979,22 @@ static void process_ds_work(void)
INIT_LIST_HEAD
(
&
ds_work_list
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
dp
=
ds_info
;
list_for_each_entry_safe
(
qp
,
tmp
,
&
todo
,
list
)
{
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
;
if
(
!
cp
)
{
printk
(
KERN_ERR
PFX
"Data for unknown handle %lu
\n
"
,
dpkt
->
handle
);
printk
(
KERN_ERR
"ds-%lu: Data for unknown "
"handle %lu
\n
"
,
dp
->
id
,
dpkt
->
handle
);
spin_lock_irqsave
(
&
ds_lock
,
flags
);
__send_ds_nack
(
dp
,
dpkt
->
handle
);
spin_unlock_irqrestore
(
&
ds_lock
,
flags
);
}
else
{
cp
->
data
(
dp
->
lp
,
cp
,
dpkt
,
req_len
);
cp
->
data
(
dp
,
cp
,
dpkt
,
req_len
);
}
list_del
(
&
qp
->
list
);
...
...
@@ -990,6 +1030,7 @@ static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
if
(
!
qp
)
{
__send_ds_nack
(
dp
,
dpkt
->
handle
);
}
else
{
qp
->
dp
=
dp
;
memcpy
(
&
qp
->
req
,
pkt
,
len
);
list_add_tail
(
&
qp
->
list
,
&
ds_work_list
);
wake_up
(
&
ds_wait
);
...
...
@@ -1019,8 +1060,8 @@ static void ds_reset(struct ds_info *dp)
dp
->
hs_state
=
0
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ds_states
)
;
i
++
)
{
struct
ds_cap_state
*
cp
=
&
ds_states
[
i
];
for
(
i
=
0
;
i
<
dp
->
num_
ds_states
;
i
++
)
{
struct
ds_cap_state
*
cp
=
&
dp
->
ds_states
[
i
];
cp
->
state
=
CAP_STATE_UNKNOWN
;
}
...
...
@@ -1048,7 +1089,8 @@ static void ds_event(void *arg, int event)
}
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
);
return
;
}
...
...
@@ -1099,9 +1141,11 @@ static int __devinit ds_probe(struct vio_dev *vdev,
.
mtu
=
4096
,
.
mode
=
LDC_MODE_STREAM
,
};
struct
mdesc_handle
*
hp
;
struct
ldc_channel
*
lp
;
struct
ds_info
*
dp
;
int
err
;
const
u64
*
val
;
int
err
,
i
;
if
(
ds_version_printed
++
==
0
)
printk
(
KERN_INFO
"%s"
,
version
);
...
...
@@ -1111,19 +1155,37 @@ static int __devinit ds_probe(struct vio_dev *vdev,
if
(
!
dp
)
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
);
if
(
!
dp
->
rcv_buf
)
goto
out_free_dp
;
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
.
rx_irq
=
vdev
->
rx_irq
;
lp
=
ldc_alloc
(
vdev
->
channel_id
,
&
ds_cfg
,
dp
);
if
(
IS_ERR
(
lp
))
{
err
=
PTR_ERR
(
lp
);
goto
out_free_
rcv_buf
;
goto
out_free_
ds_states
;
}
dp
->
lp
=
lp
;
...
...
@@ -1131,13 +1193,19 @@ static int __devinit ds_probe(struct vio_dev *vdev,
if
(
err
)
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
;
out_free_ldc:
ldc_free
(
dp
->
lp
);
out_free_ds_states:
kfree
(
dp
->
ds_states
);
out_free_rcv_buf:
kfree
(
dp
->
rcv_buf
);
...
...
@@ -1172,11 +1240,6 @@ static struct vio_driver ds_driver = {
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"
);
return
vio_register_driver
(
&
ds_driver
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment