diff options
-rw-r--r-- | arch/sparc64/kernel/vio.c | 39 | ||||
-rw-r--r-- | include/asm-sparc64/mdesc.h | 22 | ||||
-rw-r--r-- | include/asm-sparc64/vio.h | 7 |
3 files changed, 53 insertions, 15 deletions
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c index 64f082555bcd..8b269aabff07 100644 --- a/arch/sparc64/kernel/vio.c +++ b/arch/sparc64/kernel/vio.c | |||
@@ -44,12 +44,11 @@ static const struct vio_device_id *vio_match_device( | |||
44 | 44 | ||
45 | while (matches->type[0] || matches->compat[0]) { | 45 | while (matches->type[0] || matches->compat[0]) { |
46 | int match = 1; | 46 | int match = 1; |
47 | if (matches->type[0]) { | 47 | if (matches->type[0]) |
48 | match &= type | 48 | match &= !strcmp(matches->type, type); |
49 | && !strcmp(matches->type, type); | 49 | |
50 | } | ||
51 | if (matches->compat[0]) { | 50 | if (matches->compat[0]) { |
52 | match &= compat && | 51 | match &= len && |
53 | find_in_proplist(compat, matches->compat, len); | 52 | find_in_proplist(compat, matches->compat, len); |
54 | } | 53 | } |
55 | if (match) | 54 | if (match) |
@@ -205,15 +204,30 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
205 | const char *type, *compat; | 204 | const char *type, *compat; |
206 | struct device_node *dp; | 205 | struct device_node *dp; |
207 | struct vio_dev *vdev; | 206 | struct vio_dev *vdev; |
208 | int err, clen; | 207 | int err, tlen, clen; |
209 | 208 | ||
210 | type = mdesc_get_property(hp, mp, "device-type", NULL); | 209 | type = mdesc_get_property(hp, mp, "device-type", &tlen); |
211 | if (!type) { | 210 | if (!type) { |
212 | type = mdesc_get_property(hp, mp, "name", NULL); | 211 | type = mdesc_get_property(hp, mp, "name", &tlen); |
213 | if (!type) | 212 | if (!type) { |
214 | type = mdesc_node_name(hp, mp); | 213 | type = mdesc_node_name(hp, mp); |
214 | tlen = strlen(type) + 1; | ||
215 | } | ||
216 | } | ||
217 | if (tlen > VIO_MAX_TYPE_LEN) { | ||
218 | printk(KERN_ERR "VIO: Type string [%s] is too long.\n", | ||
219 | type); | ||
220 | return NULL; | ||
215 | } | 221 | } |
222 | |||
216 | compat = mdesc_get_property(hp, mp, "device-type", &clen); | 223 | compat = mdesc_get_property(hp, mp, "device-type", &clen); |
224 | if (!compat) { | ||
225 | clen = 0; | ||
226 | } else if (clen > VIO_MAX_COMPAT_LEN) { | ||
227 | printk(KERN_ERR "VIO: Compat len %d for [%s] is too long.\n", | ||
228 | clen, type); | ||
229 | return NULL; | ||
230 | } | ||
217 | 231 | ||
218 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); | 232 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); |
219 | if (!vdev) { | 233 | if (!vdev) { |
@@ -222,8 +236,11 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
222 | } | 236 | } |
223 | 237 | ||
224 | vdev->mp = mp; | 238 | vdev->mp = mp; |
225 | vdev->type = type; | 239 | memcpy(vdev->type, type, tlen); |
226 | vdev->compat = compat; | 240 | if (compat) |
241 | memcpy(vdev->compat, compat, clen); | ||
242 | else | ||
243 | memset(vdev->compat, 0, sizeof(vdev->compat)); | ||
227 | vdev->compat_len = clen; | 244 | vdev->compat_len = clen; |
228 | 245 | ||
229 | vdev->channel_id = ~0UL; | 246 | vdev->channel_id = ~0UL; |
diff --git a/include/asm-sparc64/mdesc.h b/include/asm-sparc64/mdesc.h index bbb0c0bed486..dc372df23fb3 100644 --- a/include/asm-sparc64/mdesc.h +++ b/include/asm-sparc64/mdesc.h | |||
@@ -23,8 +23,28 @@ extern u64 mdesc_node_by_name(struct mdesc_handle *handle, | |||
23 | (__node) != MDESC_NODE_NULL; \ | 23 | (__node) != MDESC_NODE_NULL; \ |
24 | __node = mdesc_node_by_name(__hdl, __node, __name)) | 24 | __node = mdesc_node_by_name(__hdl, __node, __name)) |
25 | 25 | ||
26 | /* Access to property values returned from mdesc_get_property() are | ||
27 | * only valid inside of a mdesc_grab()/mdesc_release() sequence. | ||
28 | * Once mdesc_release() is called, the memory backed up by these | ||
29 | * pointers may reference freed up memory. | ||
30 | * | ||
31 | * Therefore callers must make copies of any property values | ||
32 | * they need. | ||
33 | * | ||
34 | * These same rules apply to mdesc_node_name(). | ||
35 | */ | ||
26 | extern const void *mdesc_get_property(struct mdesc_handle *handle, | 36 | extern const void *mdesc_get_property(struct mdesc_handle *handle, |
27 | u64 node, const char *name, int *lenp); | 37 | u64 node, const char *name, int *lenp); |
38 | extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node); | ||
39 | |||
40 | /* MD arc iteration, the standard sequence is: | ||
41 | * | ||
42 | * unsigned long arc; | ||
43 | * mdesc_for_each_arc(arc, handle, node, MDESC_ARC_TYPE_{FWD,BACK}) { | ||
44 | * unsigned long target = mdesc_arc_target(handle, arc); | ||
45 | * ... | ||
46 | * } | ||
47 | */ | ||
28 | 48 | ||
29 | #define MDESC_ARC_TYPE_FWD "fwd" | 49 | #define MDESC_ARC_TYPE_FWD "fwd" |
30 | #define MDESC_ARC_TYPE_BACK "back" | 50 | #define MDESC_ARC_TYPE_BACK "back" |
@@ -38,8 +58,6 @@ extern u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from, | |||
38 | 58 | ||
39 | extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc); | 59 | extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc); |
40 | 60 | ||
41 | extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node); | ||
42 | |||
43 | extern void mdesc_update(void); | 61 | extern void mdesc_update(void); |
44 | 62 | ||
45 | extern void sun4v_mdesc_init(void); | 63 | extern void sun4v_mdesc_init(void); |
diff --git a/include/asm-sparc64/vio.h b/include/asm-sparc64/vio.h index a8a53e6fc250..83c96422e9d6 100644 --- a/include/asm-sparc64/vio.h +++ b/include/asm-sparc64/vio.h | |||
@@ -264,12 +264,15 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr, | |||
264 | ((dr->prod - dr->cons) & (ring_size - 1))); | 264 | ((dr->prod - dr->cons) & (ring_size - 1))); |
265 | } | 265 | } |
266 | 266 | ||
267 | #define VIO_MAX_TYPE_LEN 64 | ||
268 | #define VIO_MAX_COMPAT_LEN 64 | ||
269 | |||
267 | struct vio_dev { | 270 | struct vio_dev { |
268 | u64 mp; | 271 | u64 mp; |
269 | struct device_node *dp; | 272 | struct device_node *dp; |
270 | 273 | ||
271 | const char *type; | 274 | char type[VIO_MAX_TYPE_LEN]; |
272 | const char *compat; | 275 | char compat[VIO_MAX_COMPAT_LEN]; |
273 | int compat_len; | 276 | int compat_len; |
274 | 277 | ||
275 | unsigned long channel_id; | 278 | unsigned long channel_id; |