aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rapidio')
-rw-r--r--drivers/rapidio/rio-scan.c2
-rw-r--r--drivers/rapidio/rio-sysfs.c42
-rw-r--r--drivers/rapidio/rio.c84
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
519cleanup: 519cleanup:
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");
33rio_config_attr(asm_did, "0x%04x\n"); 34rio_config_attr(asm_did, "0x%04x\n");
34rio_config_attr(asm_vid, "0x%04x\n"); 35rio_config_attr(asm_vid, "0x%04x\n");
35rio_config_attr(asm_rev, "0x%04x\n"); 36rio_config_attr(asm_rev, "0x%04x\n");
37rio_config_attr(destid, "0x%04x\n");
38rio_config_attr(hopcount, "0x%02x\n");
36 39
37static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf) 40static 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
58static 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
67static 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
55struct device_attribute rio_dev_attrs[] = { 87struct 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
65static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL); 99static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
100static DEVICE_ATTR(lnext, S_IRUGO, lnext_show, NULL);
101static DEVICE_ATTR(hopcount, S_IRUGO, hopcount_show, NULL);
66 102
67static ssize_t 103static ssize_t
68rio_read_config(struct file *filp, struct kobject *kobj, 104rio_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
34static LIST_HEAD(rio_mports); 34static LIST_HEAD(rio_mports);
35static 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 */
107int rio_release_inb_mbox(struct rio_mport *mport, int mbox) 112int 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 */
168int rio_release_outb_mbox(struct rio_mport *mport, int mbox) 180int 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
1123device_initcall(rio_init);
1124
1125int __devinit rio_init_mports(void) 1138int __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
1154device_initcall_sync(rio_init_mports);
1155
1156static int hdids[RIO_MAX_MPORTS + 1];
1157
1158static 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
1166static 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
1151void rio_register_mport(struct rio_mport *port) 1174void 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