diff options
Diffstat (limited to 'drivers/rapidio')
-rw-r--r-- | drivers/rapidio/rio-scan.c | 2 | ||||
-rw-r--r-- | drivers/rapidio/rio-sysfs.c | 42 | ||||
-rw-r--r-- | drivers/rapidio/rio.c | 84 |
3 files changed, 99 insertions, 29 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a50391b6ba2a..3a59d5f018d3 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -517,7 +517,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
517 | return rdev; | 517 | return rdev; |
518 | 518 | ||
519 | cleanup: | 519 | cleanup: |
520 | if (rswitch->route_table) | 520 | if (rio_is_switch(rdev)) |
521 | kfree(rswitch->route_table); | 521 | kfree(rswitch->route_table); |
522 | 522 | ||
523 | kfree(rdev); | 523 | kfree(rdev); |
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 1269fbd2deca..4dbe360989be 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/rio.h> | 14 | #include <linux/rio.h> |
15 | #include <linux/rio_drv.h> | 15 | #include <linux/rio_drv.h> |
16 | #include <linux/stat.h> | 16 | #include <linux/stat.h> |
17 | #include <linux/capability.h> | ||
17 | 18 | ||
18 | #include "rio.h" | 19 | #include "rio.h" |
19 | 20 | ||
@@ -33,6 +34,8 @@ rio_config_attr(device_rev, "0x%08x\n"); | |||
33 | rio_config_attr(asm_did, "0x%04x\n"); | 34 | rio_config_attr(asm_did, "0x%04x\n"); |
34 | rio_config_attr(asm_vid, "0x%04x\n"); | 35 | rio_config_attr(asm_vid, "0x%04x\n"); |
35 | rio_config_attr(asm_rev, "0x%04x\n"); | 36 | rio_config_attr(asm_rev, "0x%04x\n"); |
37 | rio_config_attr(destid, "0x%04x\n"); | ||
38 | rio_config_attr(hopcount, "0x%02x\n"); | ||
36 | 39 | ||
37 | static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf) | 40 | static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf) |
38 | { | 41 | { |
@@ -52,6 +55,35 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch | |||
52 | return (str - buf); | 55 | return (str - buf); |
53 | } | 56 | } |
54 | 57 | ||
58 | static ssize_t lprev_show(struct device *dev, | ||
59 | struct device_attribute *attr, char *buf) | ||
60 | { | ||
61 | struct rio_dev *rdev = to_rio_dev(dev); | ||
62 | |||
63 | return sprintf(buf, "%s\n", | ||
64 | (rdev->prev) ? rio_name(rdev->prev) : "root"); | ||
65 | } | ||
66 | |||
67 | static ssize_t lnext_show(struct device *dev, | ||
68 | struct device_attribute *attr, char *buf) | ||
69 | { | ||
70 | struct rio_dev *rdev = to_rio_dev(dev); | ||
71 | char *str = buf; | ||
72 | int i; | ||
73 | |||
74 | if (rdev->pef & RIO_PEF_SWITCH) { | ||
75 | for (i = 0; i < RIO_GET_TOTAL_PORTS(rdev->swpinfo); i++) { | ||
76 | if (rdev->rswitch->nextdev[i]) | ||
77 | str += sprintf(str, "%s\n", | ||
78 | rio_name(rdev->rswitch->nextdev[i])); | ||
79 | else | ||
80 | str += sprintf(str, "null\n"); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | return str - buf; | ||
85 | } | ||
86 | |||
55 | struct device_attribute rio_dev_attrs[] = { | 87 | struct device_attribute rio_dev_attrs[] = { |
56 | __ATTR_RO(did), | 88 | __ATTR_RO(did), |
57 | __ATTR_RO(vid), | 89 | __ATTR_RO(vid), |
@@ -59,10 +91,14 @@ struct device_attribute rio_dev_attrs[] = { | |||
59 | __ATTR_RO(asm_did), | 91 | __ATTR_RO(asm_did), |
60 | __ATTR_RO(asm_vid), | 92 | __ATTR_RO(asm_vid), |
61 | __ATTR_RO(asm_rev), | 93 | __ATTR_RO(asm_rev), |
94 | __ATTR_RO(lprev), | ||
95 | __ATTR_RO(destid), | ||
62 | __ATTR_NULL, | 96 | __ATTR_NULL, |
63 | }; | 97 | }; |
64 | 98 | ||
65 | static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL); | 99 | static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL); |
100 | static DEVICE_ATTR(lnext, S_IRUGO, lnext_show, NULL); | ||
101 | static DEVICE_ATTR(hopcount, S_IRUGO, hopcount_show, NULL); | ||
66 | 102 | ||
67 | static ssize_t | 103 | static ssize_t |
68 | rio_read_config(struct file *filp, struct kobject *kobj, | 104 | rio_read_config(struct file *filp, struct kobject *kobj, |
@@ -218,7 +254,9 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) | |||
218 | err = device_create_bin_file(&rdev->dev, &rio_config_attr); | 254 | err = device_create_bin_file(&rdev->dev, &rio_config_attr); |
219 | 255 | ||
220 | if (!err && (rdev->pef & RIO_PEF_SWITCH)) { | 256 | if (!err && (rdev->pef & RIO_PEF_SWITCH)) { |
221 | err = device_create_file(&rdev->dev, &dev_attr_routes); | 257 | err |= device_create_file(&rdev->dev, &dev_attr_routes); |
258 | err |= device_create_file(&rdev->dev, &dev_attr_lnext); | ||
259 | err |= device_create_file(&rdev->dev, &dev_attr_hopcount); | ||
222 | if (!err && rdev->rswitch->sw_sysfs) | 260 | if (!err && rdev->rswitch->sw_sysfs) |
223 | err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); | 261 | err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); |
224 | } | 262 | } |
@@ -241,6 +279,8 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev) | |||
241 | device_remove_bin_file(&rdev->dev, &rio_config_attr); | 279 | device_remove_bin_file(&rdev->dev, &rio_config_attr); |
242 | if (rdev->pef & RIO_PEF_SWITCH) { | 280 | if (rdev->pef & RIO_PEF_SWITCH) { |
243 | device_remove_file(&rdev->dev, &dev_attr_routes); | 281 | device_remove_file(&rdev->dev, &dev_attr_routes); |
282 | device_remove_file(&rdev->dev, &dev_attr_lnext); | ||
283 | device_remove_file(&rdev->dev, &dev_attr_hopcount); | ||
244 | if (rdev->rswitch->sw_sysfs) | 284 | if (rdev->rswitch->sw_sysfs) |
245 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); | 285 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); |
246 | } | 286 | } |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index cc2a3b74d0f0..c29719cacbca 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "rio.h" | 32 | #include "rio.h" |
33 | 33 | ||
34 | static LIST_HEAD(rio_mports); | 34 | static LIST_HEAD(rio_mports); |
35 | static unsigned char next_portid; | ||
35 | 36 | ||
36 | /** | 37 | /** |
37 | * rio_local_get_device_id - Get the base/extended device id for a port | 38 | * rio_local_get_device_id - Get the base/extended device id for a port |
@@ -68,9 +69,13 @@ int rio_request_inb_mbox(struct rio_mport *mport, | |||
68 | void (*minb) (struct rio_mport * mport, void *dev_id, int mbox, | 69 | void (*minb) (struct rio_mport * mport, void *dev_id, int mbox, |
69 | int slot)) | 70 | int slot)) |
70 | { | 71 | { |
71 | int rc = 0; | 72 | int rc = -ENOSYS; |
73 | struct resource *res; | ||
72 | 74 | ||
73 | struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); | 75 | if (mport->ops->open_inb_mbox == NULL) |
76 | goto out; | ||
77 | |||
78 | res = kmalloc(sizeof(struct resource), GFP_KERNEL); | ||
74 | 79 | ||
75 | if (res) { | 80 | if (res) { |
76 | rio_init_mbox_res(res, mbox, mbox); | 81 | rio_init_mbox_res(res, mbox, mbox); |
@@ -88,7 +93,7 @@ int rio_request_inb_mbox(struct rio_mport *mport, | |||
88 | /* Hook the inbound message callback */ | 93 | /* Hook the inbound message callback */ |
89 | mport->inb_msg[mbox].mcback = minb; | 94 | mport->inb_msg[mbox].mcback = minb; |
90 | 95 | ||
91 | rc = rio_open_inb_mbox(mport, dev_id, mbox, entries); | 96 | rc = mport->ops->open_inb_mbox(mport, dev_id, mbox, entries); |
92 | } else | 97 | } else |
93 | rc = -ENOMEM; | 98 | rc = -ENOMEM; |
94 | 99 | ||
@@ -106,10 +111,13 @@ int rio_request_inb_mbox(struct rio_mport *mport, | |||
106 | */ | 111 | */ |
107 | int rio_release_inb_mbox(struct rio_mport *mport, int mbox) | 112 | int rio_release_inb_mbox(struct rio_mport *mport, int mbox) |
108 | { | 113 | { |
109 | rio_close_inb_mbox(mport, mbox); | 114 | if (mport->ops->close_inb_mbox) { |
115 | mport->ops->close_inb_mbox(mport, mbox); | ||
110 | 116 | ||
111 | /* Release the mailbox resource */ | 117 | /* Release the mailbox resource */ |
112 | return release_resource(mport->inb_msg[mbox].res); | 118 | return release_resource(mport->inb_msg[mbox].res); |
119 | } else | ||
120 | return -ENOSYS; | ||
113 | } | 121 | } |
114 | 122 | ||
115 | /** | 123 | /** |
@@ -129,9 +137,13 @@ int rio_request_outb_mbox(struct rio_mport *mport, | |||
129 | int entries, | 137 | int entries, |
130 | void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot)) | 138 | void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot)) |
131 | { | 139 | { |
132 | int rc = 0; | 140 | int rc = -ENOSYS; |
141 | struct resource *res; | ||
133 | 142 | ||
134 | struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL); | 143 | if (mport->ops->open_outb_mbox == NULL) |
144 | goto out; | ||
145 | |||
146 | res = kmalloc(sizeof(struct resource), GFP_KERNEL); | ||
135 | 147 | ||
136 | if (res) { | 148 | if (res) { |
137 | rio_init_mbox_res(res, mbox, mbox); | 149 | rio_init_mbox_res(res, mbox, mbox); |
@@ -149,7 +161,7 @@ int rio_request_outb_mbox(struct rio_mport *mport, | |||
149 | /* Hook the inbound message callback */ | 161 | /* Hook the inbound message callback */ |
150 | mport->outb_msg[mbox].mcback = moutb; | 162 | mport->outb_msg[mbox].mcback = moutb; |
151 | 163 | ||
152 | rc = rio_open_outb_mbox(mport, dev_id, mbox, entries); | 164 | rc = mport->ops->open_outb_mbox(mport, dev_id, mbox, entries); |
153 | } else | 165 | } else |
154 | rc = -ENOMEM; | 166 | rc = -ENOMEM; |
155 | 167 | ||
@@ -167,10 +179,13 @@ int rio_request_outb_mbox(struct rio_mport *mport, | |||
167 | */ | 179 | */ |
168 | int rio_release_outb_mbox(struct rio_mport *mport, int mbox) | 180 | int rio_release_outb_mbox(struct rio_mport *mport, int mbox) |
169 | { | 181 | { |
170 | rio_close_outb_mbox(mport, mbox); | 182 | if (mport->ops->close_outb_mbox) { |
183 | mport->ops->close_outb_mbox(mport, mbox); | ||
171 | 184 | ||
172 | /* Release the mailbox resource */ | 185 | /* Release the mailbox resource */ |
173 | return release_resource(mport->outb_msg[mbox].res); | 186 | return release_resource(mport->outb_msg[mbox].res); |
187 | } else | ||
188 | return -ENOSYS; | ||
174 | } | 189 | } |
175 | 190 | ||
176 | /** | 191 | /** |
@@ -1120,36 +1135,51 @@ static int __devinit rio_init(void) | |||
1120 | return 0; | 1135 | return 0; |
1121 | } | 1136 | } |
1122 | 1137 | ||
1123 | device_initcall(rio_init); | ||
1124 | |||
1125 | int __devinit rio_init_mports(void) | 1138 | int __devinit rio_init_mports(void) |
1126 | { | 1139 | { |
1127 | int rc = 0; | ||
1128 | struct rio_mport *port; | 1140 | struct rio_mport *port; |
1129 | 1141 | ||
1130 | list_for_each_entry(port, &rio_mports, node) { | 1142 | list_for_each_entry(port, &rio_mports, node) { |
1131 | if (!request_mem_region(port->iores.start, | ||
1132 | resource_size(&port->iores), | ||
1133 | port->name)) { | ||
1134 | printk(KERN_ERR | ||
1135 | "RIO: Error requesting master port region 0x%016llx-0x%016llx\n", | ||
1136 | (u64)port->iores.start, (u64)port->iores.end); | ||
1137 | rc = -ENOMEM; | ||
1138 | goto out; | ||
1139 | } | ||
1140 | |||
1141 | if (port->host_deviceid >= 0) | 1143 | if (port->host_deviceid >= 0) |
1142 | rio_enum_mport(port); | 1144 | rio_enum_mport(port); |
1143 | else | 1145 | else |
1144 | rio_disc_mport(port); | 1146 | rio_disc_mport(port); |
1145 | } | 1147 | } |
1146 | 1148 | ||
1147 | out: | 1149 | rio_init(); |
1148 | return rc; | 1150 | |
1151 | return 0; | ||
1149 | } | 1152 | } |
1150 | 1153 | ||
1154 | device_initcall_sync(rio_init_mports); | ||
1155 | |||
1156 | static int hdids[RIO_MAX_MPORTS + 1]; | ||
1157 | |||
1158 | static int rio_get_hdid(int index) | ||
1159 | { | ||
1160 | if (!hdids[0] || hdids[0] <= index || index >= RIO_MAX_MPORTS) | ||
1161 | return -1; | ||
1162 | |||
1163 | return hdids[index + 1]; | ||
1164 | } | ||
1165 | |||
1166 | static int rio_hdid_setup(char *str) | ||
1167 | { | ||
1168 | (void)get_options(str, ARRAY_SIZE(hdids), hdids); | ||
1169 | return 1; | ||
1170 | } | ||
1171 | |||
1172 | __setup("riohdid=", rio_hdid_setup); | ||
1173 | |||
1151 | void rio_register_mport(struct rio_mport *port) | 1174 | void rio_register_mport(struct rio_mport *port) |
1152 | { | 1175 | { |
1176 | if (next_portid >= RIO_MAX_MPORTS) { | ||
1177 | pr_err("RIO: reached specified max number of mports\n"); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1181 | port->id = next_portid++; | ||
1182 | port->host_deviceid = rio_get_hdid(port->id); | ||
1153 | list_add_tail(&port->node, &rio_mports); | 1183 | list_add_tail(&port->node, &rio_mports); |
1154 | } | 1184 | } |
1155 | 1185 | ||