aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2005-12-06 17:31:30 -0500
committerLen Brown <len.brown@intel.com>2005-12-06 17:31:30 -0500
commit3d5271f9883cba7b54762bc4fe027d4172f06db7 (patch)
treeab8a881a14478598a0c8bda0d26c62cdccfffd6d /drivers/rapidio
parent378b2556f4e09fa6f87ff0cb5c4395ff28257d02 (diff)
parent9115a6c787596e687df03010d97fccc5e0762506 (diff)
Pull release into acpica branch
Diffstat (limited to 'drivers/rapidio')
-rw-r--r--drivers/rapidio/Kconfig18
-rw-r--r--drivers/rapidio/Makefile6
-rw-r--r--drivers/rapidio/rio-access.c175
-rw-r--r--drivers/rapidio/rio-driver.c229
-rw-r--r--drivers/rapidio/rio-scan.c945
-rw-r--r--drivers/rapidio/rio-sysfs.c230
-rw-r--r--drivers/rapidio/rio.c510
-rw-r--r--drivers/rapidio/rio.h60
-rw-r--r--drivers/rapidio/switches/Makefile5
-rw-r--r--drivers/rapidio/switches/tsi500.c60
10 files changed, 2238 insertions, 0 deletions
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
new file mode 100644
index 000000000000..0b2d2c3579a7
--- /dev/null
+++ b/drivers/rapidio/Kconfig
@@ -0,0 +1,18 @@
1#
2# RapidIO configuration
3#
4config RAPIDIO_8_BIT_TRANSPORT
5 bool "8-bit transport addressing"
6 depends on RAPIDIO
7 ---help---
8 By default, the kernel assumes a 16-bit addressed RapidIO
9 network. By selecting this option, the kernel will support
10 an 8-bit addressed network.
11
12config RAPIDIO_DISC_TIMEOUT
13 int "Discovery timeout duration (seconds)"
14 depends on RAPIDIO
15 default "30"
16 ---help---
17 Amount of time a discovery node waits for a host to complete
18 enumeration beforing giving up.
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
new file mode 100644
index 000000000000..7c0e1818de51
--- /dev/null
+++ b/drivers/rapidio/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for RapidIO interconnect services
3#
4obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
5
6obj-$(CONFIG_RAPIDIO) += switches/
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
new file mode 100644
index 000000000000..b9fab2ae3a36
--- /dev/null
+++ b/drivers/rapidio/rio-access.c
@@ -0,0 +1,175 @@
1/*
2 * RapidIO configuration space access support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/rio.h>
14#include <linux/module.h>
15
16/*
17 * These interrupt-safe spinlocks protect all accesses to RIO
18 * configuration space and doorbell access.
19 */
20static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED;
21static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED;
22
23/*
24 * Wrappers for all RIO configuration access functions. They just check
25 * alignment, do locking and call the low-level functions pointed to
26 * by rio_mport->ops.
27 */
28
29#define RIO_8_BAD 0
30#define RIO_16_BAD (offset & 1)
31#define RIO_32_BAD (offset & 3)
32
33/**
34 * RIO_LOP_READ - Generate rio_local_read_config_* functions
35 * @size: Size of configuration space read (8, 16, 32 bits)
36 * @type: C type of value argument
37 * @len: Length of configuration space read (1, 2, 4 bytes)
38 *
39 * Generates rio_local_read_config_* functions used to access
40 * configuration space registers on the local device.
41 */
42#define RIO_LOP_READ(size,type,len) \
43int __rio_local_read_config_##size \
44 (struct rio_mport *mport, u32 offset, type *value) \
45{ \
46 int res; \
47 unsigned long flags; \
48 u32 data = 0; \
49 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
50 spin_lock_irqsave(&rio_config_lock, flags); \
51 res = mport->ops->lcread(mport->id, offset, len, &data); \
52 *value = (type)data; \
53 spin_unlock_irqrestore(&rio_config_lock, flags); \
54 return res; \
55}
56
57/**
58 * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
59 * @size: Size of configuration space write (8, 16, 32 bits)
60 * @type: C type of value argument
61 * @len: Length of configuration space write (1, 2, 4 bytes)
62 *
63 * Generates rio_local_write_config_* functions used to access
64 * configuration space registers on the local device.
65 */
66#define RIO_LOP_WRITE(size,type,len) \
67int __rio_local_write_config_##size \
68 (struct rio_mport *mport, u32 offset, type value) \
69{ \
70 int res; \
71 unsigned long flags; \
72 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
73 spin_lock_irqsave(&rio_config_lock, flags); \
74 res = mport->ops->lcwrite(mport->id, offset, len, value); \
75 spin_unlock_irqrestore(&rio_config_lock, flags); \
76 return res; \
77}
78
79RIO_LOP_READ(8, u8, 1)
80RIO_LOP_READ(16, u16, 2)
81RIO_LOP_READ(32, u32, 4)
82RIO_LOP_WRITE(8, u8, 1)
83RIO_LOP_WRITE(16, u16, 2)
84RIO_LOP_WRITE(32, u32, 4)
85
86EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
87EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
88EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
89EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
90EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
91EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
92
93/**
94 * RIO_OP_READ - Generate rio_mport_read_config_* functions
95 * @size: Size of configuration space read (8, 16, 32 bits)
96 * @type: C type of value argument
97 * @len: Length of configuration space read (1, 2, 4 bytes)
98 *
99 * Generates rio_mport_read_config_* functions used to access
100 * configuration space registers on the local device.
101 */
102#define RIO_OP_READ(size,type,len) \
103int rio_mport_read_config_##size \
104 (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
105{ \
106 int res; \
107 unsigned long flags; \
108 u32 data = 0; \
109 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
110 spin_lock_irqsave(&rio_config_lock, flags); \
111 res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
112 *value = (type)data; \
113 spin_unlock_irqrestore(&rio_config_lock, flags); \
114 return res; \
115}
116
117/**
118 * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
119 * @size: Size of configuration space write (8, 16, 32 bits)
120 * @type: C type of value argument
121 * @len: Length of configuration space write (1, 2, 4 bytes)
122 *
123 * Generates rio_mport_write_config_* functions used to access
124 * configuration space registers on the local device.
125 */
126#define RIO_OP_WRITE(size,type,len) \
127int rio_mport_write_config_##size \
128 (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
129{ \
130 int res; \
131 unsigned long flags; \
132 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
133 spin_lock_irqsave(&rio_config_lock, flags); \
134 res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
135 spin_unlock_irqrestore(&rio_config_lock, flags); \
136 return res; \
137}
138
139RIO_OP_READ(8, u8, 1)
140RIO_OP_READ(16, u16, 2)
141RIO_OP_READ(32, u32, 4)
142RIO_OP_WRITE(8, u8, 1)
143RIO_OP_WRITE(16, u16, 2)
144RIO_OP_WRITE(32, u32, 4)
145
146EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
147EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
148EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
149EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
150EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
151EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
152
153/**
154 * rio_mport_send_doorbell - Send a doorbell message
155 *
156 * @mport: RIO master port
157 * @destid: RIO device destination ID
158 * @data: Doorbell message data
159 *
160 * Send a doorbell message to a RIO device. The doorbell message
161 * has a 16-bit info field provided by the data argument.
162 */
163int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
164{
165 int res;
166 unsigned long flags;
167
168 spin_lock_irqsave(&rio_doorbell_lock, flags);
169 res = mport->ops->dsend(mport->id, destid, data);
170 spin_unlock_irqrestore(&rio_doorbell_lock, flags);
171
172 return res;
173}
174
175EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
new file mode 100644
index 000000000000..dc749609699a
--- /dev/null
+++ b/drivers/rapidio/rio-driver.c
@@ -0,0 +1,229 @@
1/*
2 * RapidIO driver support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/rio.h>
16#include <linux/rio_ids.h>
17
18#include "rio.h"
19
20/**
21 * rio_match_device - Tell if a RIO device has a matching RIO device id structure
22 * @id: the RIO device id structure to match against
23 * @rdev: the RIO device structure to match against
24 *
25 * Used from driver probe and bus matching to check whether a RIO device
26 * matches a device id structure provided by a RIO driver. Returns the
27 * matching &struct rio_device_id or %NULL if there is no match.
28 */
29static const struct rio_device_id *rio_match_device(const struct rio_device_id
30 *id,
31 const struct rio_dev *rdev)
32{
33 while (id->vid || id->asm_vid) {
34 if (((id->vid == RIO_ANY_ID) || (id->vid == rdev->vid)) &&
35 ((id->did == RIO_ANY_ID) || (id->did == rdev->did)) &&
36 ((id->asm_vid == RIO_ANY_ID)
37 || (id->asm_vid == rdev->asm_vid))
38 && ((id->asm_did == RIO_ANY_ID)
39 || (id->asm_did == rdev->asm_did)))
40 return id;
41 id++;
42 }
43 return NULL;
44}
45
46/**
47 * rio_dev_get - Increments the reference count of the RIO device structure
48 *
49 * @rdev: RIO device being referenced
50 *
51 * Each live reference to a device should be refcounted.
52 *
53 * Drivers for RIO devices should normally record such references in
54 * their probe() methods, when they bind to a device, and release
55 * them by calling rio_dev_put(), in their disconnect() methods.
56 */
57struct rio_dev *rio_dev_get(struct rio_dev *rdev)
58{
59 if (rdev)
60 get_device(&rdev->dev);
61
62 return rdev;
63}
64
65/**
66 * rio_dev_put - Release a use of the RIO device structure
67 *
68 * @rdev: RIO device being disconnected
69 *
70 * Must be called when a user of a device is finished with it.
71 * When the last user of the device calls this function, the
72 * memory of the device is freed.
73 */
74void rio_dev_put(struct rio_dev *rdev)
75{
76 if (rdev)
77 put_device(&rdev->dev);
78}
79
80/**
81 * rio_device_probe - Tell if a RIO device structure has a matching RIO
82 * device id structure
83 * @id: the RIO device id structure to match against
84 * @dev: the RIO device structure to match against
85 *
86 * return 0 and set rio_dev->driver when drv claims rio_dev, else error
87 */
88static int rio_device_probe(struct device *dev)
89{
90 struct rio_driver *rdrv = to_rio_driver(dev->driver);
91 struct rio_dev *rdev = to_rio_dev(dev);
92 int error = -ENODEV;
93 const struct rio_device_id *id;
94
95 if (!rdev->driver && rdrv->probe) {
96 if (!rdrv->id_table)
97 return error;
98 id = rio_match_device(rdrv->id_table, rdev);
99 rio_dev_get(rdev);
100 if (id)
101 error = rdrv->probe(rdev, id);
102 if (error >= 0) {
103 rdev->driver = rdrv;
104 error = 0;
105 rio_dev_put(rdev);
106 }
107 }
108 return error;
109}
110
111/**
112 * rio_device_remove - Remove a RIO device from the system
113 *
114 * @dev: the RIO device structure to match against
115 *
116 * Remove a RIO device from the system. If it has an associated
117 * driver, then run the driver remove() method. Then update
118 * the reference count.
119 */
120static int rio_device_remove(struct device *dev)
121{
122 struct rio_dev *rdev = to_rio_dev(dev);
123 struct rio_driver *rdrv = rdev->driver;
124
125 if (rdrv) {
126 if (rdrv->remove)
127 rdrv->remove(rdev);
128 rdev->driver = NULL;
129 }
130
131 rio_dev_put(rdev);
132
133 return 0;
134}
135
136/**
137 * rio_register_driver - register a new RIO driver
138 * @rdrv: the RIO driver structure to register
139 *
140 * Adds a &struct rio_driver to the list of registered drivers
141 * Returns a negative value on error, otherwise 0. If no error
142 * occurred, the driver remains registered even if no device
143 * was claimed during registration.
144 */
145int rio_register_driver(struct rio_driver *rdrv)
146{
147 /* initialize common driver fields */
148 rdrv->driver.name = rdrv->name;
149 rdrv->driver.bus = &rio_bus_type;
150 rdrv->driver.probe = rio_device_probe;
151 rdrv->driver.remove = rio_device_remove;
152
153 /* register with core */
154 return driver_register(&rdrv->driver);
155}
156
157/**
158 * rio_unregister_driver - unregister a RIO driver
159 * @rdrv: the RIO driver structure to unregister
160 *
161 * Deletes the &struct rio_driver from the list of registered RIO
162 * drivers, gives it a chance to clean up by calling its remove()
163 * function for each device it was responsible for, and marks those
164 * devices as driverless.
165 */
166void rio_unregister_driver(struct rio_driver *rdrv)
167{
168 driver_unregister(&rdrv->driver);
169}
170
171/**
172 * rio_match_bus - Tell if a RIO device structure has a matching RIO
173 * driver device id structure
174 * @dev: the standard device structure to match against
175 * @drv: the standard driver structure containing the ids to match against
176 *
177 * Used by a driver to check whether a RIO device present in the
178 * system is in its list of supported devices. Returns 1 if
179 * there is a matching &struct rio_device_id or 0 if there is
180 * no match.
181 */
182static int rio_match_bus(struct device *dev, struct device_driver *drv)
183{
184 struct rio_dev *rdev = to_rio_dev(dev);
185 struct rio_driver *rdrv = to_rio_driver(drv);
186 const struct rio_device_id *id = rdrv->id_table;
187 const struct rio_device_id *found_id;
188
189 if (!id)
190 goto out;
191
192 found_id = rio_match_device(id, rdev);
193
194 if (found_id)
195 return 1;
196
197 out:return 0;
198}
199
200static struct device rio_bus = {
201 .bus_id = "rapidio",
202};
203
204struct bus_type rio_bus_type = {
205 .name = "rapidio",
206 .match = rio_match_bus,
207 .dev_attrs = rio_dev_attrs
208};
209
210/**
211 * rio_bus_init - Register the RapidIO bus with the device model
212 *
213 * Registers the RIO bus device and RIO bus type with the Linux
214 * device model.
215 */
216static int __init rio_bus_init(void)
217{
218 if (device_register(&rio_bus) < 0)
219 printk("RIO: failed to register RIO bus device\n");
220 return bus_register(&rio_bus_type);
221}
222
223postcore_initcall(rio_bus_init);
224
225EXPORT_SYMBOL_GPL(rio_register_driver);
226EXPORT_SYMBOL_GPL(rio_unregister_driver);
227EXPORT_SYMBOL_GPL(rio_bus_type);
228EXPORT_SYMBOL_GPL(rio_dev_get);
229EXPORT_SYMBOL_GPL(rio_dev_put);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
new file mode 100644
index 000000000000..4f7ed4bd3be9
--- /dev/null
+++ b/drivers/rapidio/rio-scan.c
@@ -0,0 +1,945 @@
1/*
2 * RapidIO enumeration and discovery support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16
17#include <linux/delay.h>
18#include <linux/dma-mapping.h>
19#include <linux/init.h>
20#include <linux/rio.h>
21#include <linux/rio_drv.h>
22#include <linux/rio_ids.h>
23#include <linux/rio_regs.h>
24#include <linux/module.h>
25#include <linux/spinlock.h>
26#include <linux/timer.h>
27
28#include "rio.h"
29
30LIST_HEAD(rio_devices);
31static LIST_HEAD(rio_switches);
32
33#define RIO_ENUM_CMPL_MAGIC 0xdeadbeef
34
35static void rio_enum_timeout(unsigned long);
36
37DEFINE_SPINLOCK(rio_global_list_lock);
38
39static int next_destid = 0;
40static int next_switchid = 0;
41static int next_net = 0;
42
43static struct timer_list rio_enum_timer =
44TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
45
46static int rio_mport_phys_table[] = {
47 RIO_EFB_PAR_EP_ID,
48 RIO_EFB_PAR_EP_REC_ID,
49 RIO_EFB_SER_EP_ID,
50 RIO_EFB_SER_EP_REC_ID,
51 -1,
52};
53
54static int rio_sport_phys_table[] = {
55 RIO_EFB_PAR_EP_FREE_ID,
56 RIO_EFB_SER_EP_FREE_ID,
57 -1,
58};
59
60/**
61 * rio_get_device_id - Get the base/extended device id for a device
62 * @port: RIO master port
63 * @destid: Destination ID of device
64 * @hopcount: Hopcount to device
65 *
66 * Reads the base/extended device id from a device. Returns the
67 * 8/16-bit device ID.
68 */
69static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
70{
71 u32 result;
72
73 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
74
75 return RIO_GET_DID(result);
76}
77
78/**
79 * rio_set_device_id - Set the base/extended device id for a device
80 * @port: RIO master port
81 * @destid: Destination ID of device
82 * @hopcount: Hopcount to device
83 * @did: Device ID value to be written
84 *
85 * Writes the base/extended device id from a device.
86 */
87static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
88{
89 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
90 RIO_SET_DID(did));
91}
92
93/**
94 * rio_local_set_device_id - Set the base/extended device id for a port
95 * @port: RIO master port
96 * @did: Device ID value to be written
97 *
98 * Writes the base/extended device id from a device.
99 */
100static void rio_local_set_device_id(struct rio_mport *port, u16 did)
101{
102 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
103}
104
105/**
106 * rio_clear_locks- Release all host locks and signal enumeration complete
107 * @port: Master port to issue transaction
108 *
109 * Marks the component tag CSR on each device with the enumeration
110 * complete flag. When complete, it then release the host locks on
111 * each device. Returns 0 on success or %-EINVAL on failure.
112 */
113static int rio_clear_locks(struct rio_mport *port)
114{
115 struct rio_dev *rdev;
116 u32 result;
117 int ret = 0;
118
119 /* Write component tag CSR magic complete value */
120 rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR,
121 RIO_ENUM_CMPL_MAGIC);
122 list_for_each_entry(rdev, &rio_devices, global_list)
123 rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR,
124 RIO_ENUM_CMPL_MAGIC);
125
126 /* Release host device id locks */
127 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
128 port->host_deviceid);
129 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
130 if ((result & 0xffff) != 0xffff) {
131 printk(KERN_INFO
132 "RIO: badness when releasing host lock on master port, result %8.8x\n",
133 result);
134 ret = -EINVAL;
135 }
136 list_for_each_entry(rdev, &rio_devices, global_list) {
137 rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
138 port->host_deviceid);
139 rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
140 if ((result & 0xffff) != 0xffff) {
141 printk(KERN_INFO
142 "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
143 rdev->vid, rdev->did);
144 ret = -EINVAL;
145 }
146 }
147
148 return ret;
149}
150
151/**
152 * rio_enum_host- Set host lock and initialize host destination ID
153 * @port: Master port to issue transaction
154 *
155 * Sets the local host master port lock and destination ID register
156 * with the host device ID value. The host device ID value is provided
157 * by the platform. Returns %0 on success or %-1 on failure.
158 */
159static int rio_enum_host(struct rio_mport *port)
160{
161 u32 result;
162
163 /* Set master port host device id lock */
164 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
165 port->host_deviceid);
166
167 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
168 if ((result & 0xffff) != port->host_deviceid)
169 return -1;
170
171 /* Set master port destid and init destid ctr */
172 rio_local_set_device_id(port, port->host_deviceid);
173
174 if (next_destid == port->host_deviceid)
175 next_destid++;
176
177 return 0;
178}
179
180/**
181 * rio_device_has_destid- Test if a device contains a destination ID register
182 * @port: Master port to issue transaction
183 * @src_ops: RIO device source operations
184 * @dst_ops: RIO device destination operations
185 *
186 * Checks the provided @src_ops and @dst_ops for the necessary transaction
187 * capabilities that indicate whether or not a device will implement a
188 * destination ID register. Returns 1 if true or 0 if false.
189 */
190static int rio_device_has_destid(struct rio_mport *port, int src_ops,
191 int dst_ops)
192{
193 u32 mask = RIO_OPS_READ | RIO_OPS_WRITE | RIO_OPS_ATOMIC_TST_SWP | RIO_OPS_ATOMIC_INC | RIO_OPS_ATOMIC_DEC | RIO_OPS_ATOMIC_SET | RIO_OPS_ATOMIC_CLR;
194
195 return !!((src_ops | dst_ops) & mask);
196}
197
198/**
199 * rio_release_dev- Frees a RIO device struct
200 * @dev: LDM device associated with a RIO device struct
201 *
202 * Gets the RIO device struct associated a RIO device struct.
203 * The RIO device struct is freed.
204 */
205static void rio_release_dev(struct device *dev)
206{
207 struct rio_dev *rdev;
208
209 rdev = to_rio_dev(dev);
210 kfree(rdev);
211}
212
213/**
214 * rio_is_switch- Tests if a RIO device has switch capabilities
215 * @rdev: RIO device
216 *
217 * Gets the RIO device Processing Element Features register
218 * contents and tests for switch capabilities. Returns 1 if
219 * the device is a switch or 0 if it is not a switch.
220 * The RIO device struct is freed.
221 */
222static int rio_is_switch(struct rio_dev *rdev)
223{
224 if (rdev->pef & RIO_PEF_SWITCH)
225 return 1;
226 return 0;
227}
228
229/**
230 * rio_route_set_ops- Sets routing operations for a particular vendor switch
231 * @rdev: RIO device
232 *
233 * Searches the RIO route ops table for known switch types. If the vid
234 * and did match a switch table entry, then set the add_entry() and
235 * get_entry() ops to the table entry values.
236 */
237static void rio_route_set_ops(struct rio_dev *rdev)
238{
239 struct rio_route_ops *cur = __start_rio_route_ops;
240 struct rio_route_ops *end = __end_rio_route_ops;
241
242 while (cur < end) {
243 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
244 pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
245 rdev->rswitch->add_entry = cur->add_hook;
246 rdev->rswitch->get_entry = cur->get_hook;
247 }
248 cur++;
249 }
250
251 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
252 printk(KERN_ERR "RIO: missing routing ops for %s\n",
253 rio_name(rdev));
254}
255
256/**
257 * rio_add_device- Adds a RIO device to the device model
258 * @rdev: RIO device
259 *
260 * Adds the RIO device to the global device list and adds the RIO
261 * device to the RIO device list. Creates the generic sysfs nodes
262 * for an RIO device.
263 */
264static void __devinit rio_add_device(struct rio_dev *rdev)
265{
266 device_add(&rdev->dev);
267
268 spin_lock(&rio_global_list_lock);
269 list_add_tail(&rdev->global_list, &rio_devices);
270 spin_unlock(&rio_global_list_lock);
271
272 rio_create_sysfs_dev_files(rdev);
273}
274
275/**
276 * rio_setup_device- Allocates and sets up a RIO device
277 * @net: RIO network
278 * @port: Master port to send transactions
279 * @destid: Current destination ID
280 * @hopcount: Current hopcount
281 * @do_enum: Enumeration/Discovery mode flag
282 *
283 * Allocates a RIO device and configures fields based on configuration
284 * space contents. If device has a destination ID register, a destination
285 * ID is either assigned in enumeration mode or read from configuration
286 * space in discovery mode. If the device has switch capabilities, then
287 * a switch is allocated and configured appropriately. Returns a pointer
288 * to a RIO device on success or NULL on failure.
289 *
290 */
291static struct rio_dev *rio_setup_device(struct rio_net *net,
292 struct rio_mport *port, u16 destid,
293 u8 hopcount, int do_enum)
294{
295 struct rio_dev *rdev;
296 struct rio_switch *rswitch;
297 int result, rdid;
298
299 rdev = kmalloc(sizeof(struct rio_dev), GFP_KERNEL);
300 if (!rdev)
301 goto out;
302
303 memset(rdev, 0, sizeof(struct rio_dev));
304 rdev->net = net;
305 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
306 &result);
307 rdev->did = result >> 16;
308 rdev->vid = result & 0xffff;
309 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
310 &rdev->device_rev);
311 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
312 &result);
313 rdev->asm_did = result >> 16;
314 rdev->asm_vid = result & 0xffff;
315 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
316 &result);
317 rdev->asm_rev = result >> 16;
318 rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
319 &rdev->pef);
320 if (rdev->pef & RIO_PEF_EXT_FEATURES)
321 rdev->efptr = result & 0xffff;
322
323 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
324 &rdev->src_ops);
325 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
326 &rdev->dst_ops);
327
328 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
329 && do_enum) {
330 rio_set_device_id(port, destid, hopcount, next_destid);
331 rdev->destid = next_destid++;
332 if (next_destid == port->host_deviceid)
333 next_destid++;
334 } else
335 rdev->destid = rio_get_device_id(port, destid, hopcount);
336
337 /* If a PE has both switch and other functions, show it as a switch */
338 if (rio_is_switch(rdev)) {
339 rio_mport_read_config_32(port, destid, hopcount,
340 RIO_SWP_INFO_CAR, &rdev->swpinfo);
341 rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
342 if (!rswitch) {
343 kfree(rdev);
344 rdev = NULL;
345 goto out;
346 }
347 rswitch->switchid = next_switchid;
348 rswitch->hopcount = hopcount;
349 rswitch->destid = 0xffff;
350 /* Initialize switch route table */
351 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
352 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
353 rdev->rswitch = rswitch;
354 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
355 rdev->rswitch->switchid);
356 rio_route_set_ops(rdev);
357
358 list_add_tail(&rswitch->node, &rio_switches);
359
360 } else
361 sprintf(rio_name(rdev), "%02x:e:%04x", rdev->net->id,
362 rdev->destid);
363
364 rdev->dev.bus = &rio_bus_type;
365
366 device_initialize(&rdev->dev);
367 rdev->dev.release = rio_release_dev;
368 rio_dev_get(rdev);
369
370 rdev->dma_mask = DMA_32BIT_MASK;
371 rdev->dev.dma_mask = &rdev->dma_mask;
372 rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
373
374 if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
375 (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
376 rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
377 0, 0xffff);
378
379 rio_add_device(rdev);
380
381 out:
382 return rdev;
383}
384
385/**
386 * rio_sport_is_active- Tests if a switch port has an active connection.
387 * @port: Master port to send transaction
388 * @destid: Associated destination ID for switch
389 * @hopcount: Hopcount to reach switch
390 * @sport: Switch port number
391 *
392 * Reads the port error status CSR for a particular switch port to
393 * determine if the port has an active link. Returns
394 * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
395 * inactive.
396 */
397static int
398rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
399{
400 u32 result;
401 u32 ext_ftr_ptr;
402
403 int *entry = rio_sport_phys_table;
404
405 do {
406 if ((ext_ftr_ptr =
407 rio_mport_get_feature(port, 0, destid, hopcount, *entry)))
408
409 break;
410 } while (*++entry >= 0);
411
412 if (ext_ftr_ptr)
413 rio_mport_read_config_32(port, destid, hopcount,
414 ext_ftr_ptr +
415 RIO_PORT_N_ERR_STS_CSR(sport),
416 &result);
417
418 return (result & PORT_N_ERR_STS_PORT_OK);
419}
420
421/**
422 * rio_route_add_entry- Add a route entry to a switch routing table
423 * @mport: Master port to send transaction
424 * @rdev: Switch device
425 * @table: Routing table ID
426 * @route_destid: Destination ID to be routed
427 * @route_port: Port number to be routed
428 *
429 * Calls the switch specific add_entry() method to add a route entry
430 * on a switch. The route table can be specified using the @table
431 * argument if a switch has per port routing tables or the normal
432 * use is to specific all tables (or the global table) by passing
433 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
434 * on failure.
435 */
436static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
437 u16 table, u16 route_destid, u8 route_port)
438{
439 return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
440 rdev->rswitch->hopcount, table,
441 route_destid, route_port);
442}
443
444/**
445 * rio_route_get_entry- Read a route entry in a switch routing table
446 * @mport: Master port to send transaction
447 * @rdev: Switch device
448 * @table: Routing table ID
449 * @route_destid: Destination ID to be routed
450 * @route_port: Pointer to read port number into
451 *
452 * Calls the switch specific get_entry() method to read a route entry
453 * in a switch. The route table can be specified using the @table
454 * argument if a switch has per port routing tables or the normal
455 * use is to specific all tables (or the global table) by passing
456 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
457 * on failure.
458 */
459static int
460rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
461 u16 route_destid, u8 * route_port)
462{
463 return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
464 rdev->rswitch->hopcount, table,
465 route_destid, route_port);
466}
467
468/**
469 * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
470 * @port: Master port to send transaction
471 * @hopcount: Number of hops to the device
472 *
473 * Used during enumeration to read the Host Device ID Lock CSR on a
474 * RIO device. Returns the value of the lock register.
475 */
476static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
477{
478 u32 result;
479
480 rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
481 RIO_HOST_DID_LOCK_CSR, &result);
482
483 return (u16) (result & 0xffff);
484}
485
486/**
487 * rio_get_swpinfo_inport- Gets the ingress port number
488 * @mport: Master port to send transaction
489 * @destid: Destination ID associated with the switch
490 * @hopcount: Number of hops to the device
491 *
492 * Returns port number being used to access the switch device.
493 */
494static u8
495rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
496{
497 u32 result;
498
499 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
500 &result);
501
502 return (u8) (result & 0xff);
503}
504
505/**
506 * rio_get_swpinfo_tports- Gets total number of ports on the switch
507 * @mport: Master port to send transaction
508 * @destid: Destination ID associated with the switch
509 * @hopcount: Number of hops to the device
510 *
511 * Returns total numbers of ports implemented by the switch device.
512 */
513static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
514 u8 hopcount)
515{
516 u32 result;
517
518 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
519 &result);
520
521 return RIO_GET_TOTAL_PORTS(result);
522}
523
524/**
525 * rio_net_add_mport- Add a master port to a RIO network
526 * @net: RIO network
527 * @port: Master port to add
528 *
529 * Adds a master port to the network list of associated master
530 * ports..
531 */
532static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
533{
534 spin_lock(&rio_global_list_lock);
535 list_add_tail(&port->nnode, &net->mports);
536 spin_unlock(&rio_global_list_lock);
537}
538
539/**
540 * rio_enum_peer- Recursively enumerate a RIO network through a master port
541 * @net: RIO network being enumerated
542 * @port: Master port to send transactions
543 * @hopcount: Number of hops into the network
544 *
545 * Recursively enumerates a RIO network. Transactions are sent via the
546 * master port passed in @port.
547 */
548static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
549 u8 hopcount)
550{
551 int port_num;
552 int num_ports;
553 int cur_destid;
554 struct rio_dev *rdev;
555 u16 destid;
556 int tmp;
557
558 if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
559 pr_debug("RIO: PE already discovered by this host\n");
560 /*
561 * Already discovered by this host. Add it as another
562 * master port for the current network.
563 */
564 rio_net_add_mport(net, port);
565 return 0;
566 }
567
568 /* Attempt to acquire device lock */
569 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
570 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
571 while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
572 < port->host_deviceid) {
573 /* Delay a bit */
574 mdelay(1);
575 /* Attempt to acquire device lock again */
576 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
577 RIO_HOST_DID_LOCK_CSR,
578 port->host_deviceid);
579 }
580
581 if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
582 pr_debug(
583 "RIO: PE locked by a higher priority host...retreating\n");
584 return -1;
585 }
586
587 /* Setup new RIO device */
588 if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
589 /* Add device to the global and bus/net specific list. */
590 list_add_tail(&rdev->net_list, &net->devices);
591 } else
592 return -1;
593
594 if (rio_is_switch(rdev)) {
595 next_switchid++;
596
597 for (destid = 0; destid < next_destid; destid++) {
598 rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
599 destid, rio_get_swpinfo_inport(port,
600 RIO_ANY_DESTID,
601 hopcount));
602 rdev->rswitch->route_table[destid] =
603 rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
604 hopcount);
605 }
606
607 num_ports =
608 rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
609 pr_debug(
610 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
611 rio_name(rdev), rdev->vid, rdev->did, num_ports);
612 for (port_num = 0; port_num < num_ports; port_num++) {
613 if (rio_get_swpinfo_inport
614 (port, RIO_ANY_DESTID, hopcount) == port_num)
615 continue;
616
617 cur_destid = next_destid;
618
619 if (rio_sport_is_active
620 (port, RIO_ANY_DESTID, hopcount, port_num)) {
621 pr_debug(
622 "RIO: scanning device on port %d\n",
623 port_num);
624 rio_route_add_entry(port, rdev,
625 RIO_GLOBAL_TABLE,
626 RIO_ANY_DESTID, port_num);
627
628 if (rio_enum_peer(net, port, hopcount + 1) < 0)
629 return -1;
630
631 /* Update routing tables */
632 if (next_destid > cur_destid) {
633 for (destid = cur_destid;
634 destid < next_destid; destid++) {
635 rio_route_add_entry(port, rdev,
636 RIO_GLOBAL_TABLE,
637 destid,
638 port_num);
639 rdev->rswitch->
640 route_table[destid] =
641 port_num;
642 }
643 rdev->rswitch->destid = cur_destid;
644 }
645 }
646 }
647 } else
648 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
649 rio_name(rdev), rdev->vid, rdev->did);
650
651 return 0;
652}
653
654/**
655 * rio_enum_complete- Tests if enumeration of a network is complete
656 * @port: Master port to send transaction
657 *
658 * Tests the Component Tag CSR for presence of the magic enumeration
659 * complete flag. Return %1 if enumeration is complete or %0 if
660 * enumeration is incomplete.
661 */
662static int rio_enum_complete(struct rio_mport *port)
663{
664 u32 tag_csr;
665 int ret = 0;
666
667 rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
668
669 if (tag_csr == RIO_ENUM_CMPL_MAGIC)
670 ret = 1;
671
672 return ret;
673}
674
675/**
676 * rio_disc_peer- Recursively discovers a RIO network through a master port
677 * @net: RIO network being discovered
678 * @port: Master port to send transactions
679 * @destid: Current destination ID in network
680 * @hopcount: Number of hops into the network
681 *
682 * Recursively discovers a RIO network. Transactions are sent via the
683 * master port passed in @port.
684 */
685static int
686rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
687 u8 hopcount)
688{
689 u8 port_num, route_port;
690 int num_ports;
691 struct rio_dev *rdev;
692 u16 ndestid;
693
694 /* Setup new RIO device */
695 if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
696 /* Add device to the global and bus/net specific list. */
697 list_add_tail(&rdev->net_list, &net->devices);
698 } else
699 return -1;
700
701 if (rio_is_switch(rdev)) {
702 next_switchid++;
703
704 /* Associated destid is how we accessed this switch */
705 rdev->rswitch->destid = destid;
706
707 num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
708 pr_debug(
709 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
710 rio_name(rdev), rdev->vid, rdev->did, num_ports);
711 for (port_num = 0; port_num < num_ports; port_num++) {
712 if (rio_get_swpinfo_inport(port, destid, hopcount) ==
713 port_num)
714 continue;
715
716 if (rio_sport_is_active
717 (port, destid, hopcount, port_num)) {
718 pr_debug(
719 "RIO: scanning device on port %d\n",
720 port_num);
721 for (ndestid = 0; ndestid < RIO_ANY_DESTID;
722 ndestid++) {
723 rio_route_get_entry(port, rdev,
724 RIO_GLOBAL_TABLE,
725 ndestid,
726 &route_port);
727 if (route_port == port_num)
728 break;
729 }
730
731 if (rio_disc_peer
732 (net, port, ndestid, hopcount + 1) < 0)
733 return -1;
734 }
735 }
736 } else
737 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
738 rio_name(rdev), rdev->vid, rdev->did);
739
740 return 0;
741}
742
743/**
744 * rio_mport_is_active- Tests if master port link is active
745 * @port: Master port to test
746 *
747 * Reads the port error status CSR for the master port to
748 * determine if the port has an active link. Returns
749 * %PORT_N_ERR_STS_PORT_OK if the master port is active
750 * or %0 if it is inactive.
751 */
752static int rio_mport_is_active(struct rio_mport *port)
753{
754 u32 result = 0;
755 u32 ext_ftr_ptr;
756 int *entry = rio_mport_phys_table;
757
758 do {
759 if ((ext_ftr_ptr =
760 rio_mport_get_feature(port, 1, 0, 0, *entry)))
761 break;
762 } while (*++entry >= 0);
763
764 if (ext_ftr_ptr)
765 rio_local_read_config_32(port,
766 ext_ftr_ptr +
767 RIO_PORT_N_ERR_STS_CSR(port->index),
768 &result);
769
770 return (result & PORT_N_ERR_STS_PORT_OK);
771}
772
773/**
774 * rio_alloc_net- Allocate and configure a new RIO network
775 * @port: Master port associated with the RIO network
776 *
777 * Allocates a RIO network structure, initializes per-network
778 * list heads, and adds the associated master port to the
779 * network list of associated master ports. Returns a
780 * RIO network pointer on success or %NULL on failure.
781 */
782static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
783{
784 struct rio_net *net;
785
786 net = kmalloc(sizeof(struct rio_net), GFP_KERNEL);
787 if (net) {
788 memset(net, 0, sizeof(struct rio_net));
789 INIT_LIST_HEAD(&net->node);
790 INIT_LIST_HEAD(&net->devices);
791 INIT_LIST_HEAD(&net->mports);
792 list_add_tail(&port->nnode, &net->mports);
793 net->hport = port;
794 net->id = next_net++;
795 }
796 return net;
797}
798
799/**
800 * rio_enum_mport- Start enumeration through a master port
801 * @mport: Master port to send transactions
802 *
803 * Starts the enumeration process. If somebody has enumerated our
804 * master port device, then give up. If not and we have an active
805 * link, then start recursive peer enumeration. Returns %0 if
806 * enumeration succeeds or %-EBUSY if enumeration fails.
807 */
808int rio_enum_mport(struct rio_mport *mport)
809{
810 struct rio_net *net = NULL;
811 int rc = 0;
812
813 printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
814 mport->name);
815 /* If somebody else enumerated our master port device, bail. */
816 if (rio_enum_host(mport) < 0) {
817 printk(KERN_INFO
818 "RIO: master port %d device has been enumerated by a remote host\n",
819 mport->id);
820 rc = -EBUSY;
821 goto out;
822 }
823
824 /* If master port has an active link, allocate net and enum peers */
825 if (rio_mport_is_active(mport)) {
826 if (!(net = rio_alloc_net(mport))) {
827 printk(KERN_ERR "RIO: failed to allocate new net\n");
828 rc = -ENOMEM;
829 goto out;
830 }
831 if (rio_enum_peer(net, mport, 0) < 0) {
832 /* A higher priority host won enumeration, bail. */
833 printk(KERN_INFO
834 "RIO: master port %d device has lost enumeration to a remote host\n",
835 mport->id);
836 rio_clear_locks(mport);
837 rc = -EBUSY;
838 goto out;
839 }
840 rio_clear_locks(mport);
841 } else {
842 printk(KERN_INFO "RIO: master port %d link inactive\n",
843 mport->id);
844 rc = -EINVAL;
845 }
846
847 out:
848 return rc;
849}
850
851/**
852 * rio_build_route_tables- Generate route tables from switch route entries
853 *
854 * For each switch device, generate a route table by copying existing
855 * route entries from the switch.
856 */
857static void rio_build_route_tables(void)
858{
859 struct rio_dev *rdev;
860 int i;
861 u8 sport;
862
863 list_for_each_entry(rdev, &rio_devices, global_list)
864 if (rio_is_switch(rdev))
865 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
866 if (rio_route_get_entry
867 (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
868 &sport) < 0)
869 continue;
870 rdev->rswitch->route_table[i] = sport;
871 }
872}
873
874/**
875 * rio_enum_timeout- Signal that enumeration timed out
876 * @data: Address of timeout flag.
877 *
878 * When the enumeration complete timer expires, set a flag that
879 * signals to the discovery process that enumeration did not
880 * complete in a sane amount of time.
881 */
882static void rio_enum_timeout(unsigned long data)
883{
884 /* Enumeration timed out, set flag */
885 *(int *)data = 1;
886}
887
888/**
889 * rio_disc_mport- Start discovery through a master port
890 * @mport: Master port to send transactions
891 *
892 * Starts the discovery process. If we have an active link,
893 * then wait for the signal that enumeration is complete.
894 * When enumeration completion is signaled, start recursive
895 * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
896 * on failure.
897 */
898int rio_disc_mport(struct rio_mport *mport)
899{
900 struct rio_net *net = NULL;
901 int enum_timeout_flag = 0;
902
903 printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
904 mport->name);
905
906 /* If master port has an active link, allocate net and discover peers */
907 if (rio_mport_is_active(mport)) {
908 if (!(net = rio_alloc_net(mport))) {
909 printk(KERN_ERR "RIO: Failed to allocate new net\n");
910 goto bail;
911 }
912
913 pr_debug("RIO: wait for enumeration complete...");
914
915 rio_enum_timer.expires =
916 jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
917 rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
918 add_timer(&rio_enum_timer);
919 while (!rio_enum_complete(mport)) {
920 mdelay(1);
921 if (enum_timeout_flag) {
922 del_timer_sync(&rio_enum_timer);
923 goto timeout;
924 }
925 }
926 del_timer_sync(&rio_enum_timer);
927
928 pr_debug("done\n");
929 if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
930 printk(KERN_INFO
931 "RIO: master port %d device has failed discovery\n",
932 mport->id);
933 goto bail;
934 }
935
936 rio_build_route_tables();
937 }
938
939 return 0;
940
941 timeout:
942 pr_debug("timeout\n");
943 bail:
944 return -EBUSY;
945}
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
new file mode 100644
index 000000000000..30a11436e241
--- /dev/null
+++ b/drivers/rapidio/rio-sysfs.c
@@ -0,0 +1,230 @@
1/*
2 * RapidIO sysfs attributes and support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/rio.h>
16#include <linux/rio_drv.h>
17#include <linux/stat.h>
18
19#include "rio.h"
20
21/* Sysfs support */
22#define rio_config_attr(field, format_string) \
23static ssize_t \
24field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
25{ \
26 struct rio_dev *rdev = to_rio_dev(dev); \
27 \
28 return sprintf(buf, format_string, rdev->field); \
29} \
30
31rio_config_attr(did, "0x%04x\n");
32rio_config_attr(vid, "0x%04x\n");
33rio_config_attr(device_rev, "0x%08x\n");
34rio_config_attr(asm_did, "0x%04x\n");
35rio_config_attr(asm_vid, "0x%04x\n");
36rio_config_attr(asm_rev, "0x%04x\n");
37
38static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
39{
40 struct rio_dev *rdev = to_rio_dev(dev);
41 char *str = buf;
42 int i;
43
44 if (!rdev->rswitch)
45 goto out;
46
47 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
48 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
49 continue;
50 str +=
51 sprintf(str, "%04x %02x\n", i,
52 rdev->rswitch->route_table[i]);
53 }
54
55 out:
56 return (str - buf);
57}
58
59struct device_attribute rio_dev_attrs[] = {
60 __ATTR_RO(did),
61 __ATTR_RO(vid),
62 __ATTR_RO(device_rev),
63 __ATTR_RO(asm_did),
64 __ATTR_RO(asm_vid),
65 __ATTR_RO(asm_rev),
66 __ATTR_RO(routes),
67 __ATTR_NULL,
68};
69
70static ssize_t
71rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
72{
73 struct rio_dev *dev =
74 to_rio_dev(container_of(kobj, struct device, kobj));
75 unsigned int size = 0x100;
76 loff_t init_off = off;
77 u8 *data = (u8 *) buf;
78
79 /* Several chips lock up trying to read undefined config space */
80 if (capable(CAP_SYS_ADMIN))
81 size = 0x200000;
82
83 if (off > size)
84 return 0;
85 if (off + count > size) {
86 size -= off;
87 count = size;
88 } else {
89 size = count;
90 }
91
92 if ((off & 1) && size) {
93 u8 val;
94 rio_read_config_8(dev, off, &val);
95 data[off - init_off] = val;
96 off++;
97 size--;
98 }
99
100 if ((off & 3) && size > 2) {
101 u16 val;
102 rio_read_config_16(dev, off, &val);
103 data[off - init_off] = (val >> 8) & 0xff;
104 data[off - init_off + 1] = val & 0xff;
105 off += 2;
106 size -= 2;
107 }
108
109 while (size > 3) {
110 u32 val;
111 rio_read_config_32(dev, off, &val);
112 data[off - init_off] = (val >> 24) & 0xff;
113 data[off - init_off + 1] = (val >> 16) & 0xff;
114 data[off - init_off + 2] = (val >> 8) & 0xff;
115 data[off - init_off + 3] = val & 0xff;
116 off += 4;
117 size -= 4;
118 }
119
120 if (size >= 2) {
121 u16 val;
122 rio_read_config_16(dev, off, &val);
123 data[off - init_off] = (val >> 8) & 0xff;
124 data[off - init_off + 1] = val & 0xff;
125 off += 2;
126 size -= 2;
127 }
128
129 if (size > 0) {
130 u8 val;
131 rio_read_config_8(dev, off, &val);
132 data[off - init_off] = val;
133 off++;
134 --size;
135 }
136
137 return count;
138}
139
140static ssize_t
141rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
142{
143 struct rio_dev *dev =
144 to_rio_dev(container_of(kobj, struct device, kobj));
145 unsigned int size = count;
146 loff_t init_off = off;
147 u8 *data = (u8 *) buf;
148
149 if (off > 0x200000)
150 return 0;
151 if (off + count > 0x200000) {
152 size = 0x200000 - off;
153 count = size;
154 }
155
156 if ((off & 1) && size) {
157 rio_write_config_8(dev, off, data[off - init_off]);
158 off++;
159 size--;
160 }
161
162 if ((off & 3) && (size > 2)) {
163 u16 val = data[off - init_off + 1];
164 val |= (u16) data[off - init_off] << 8;
165 rio_write_config_16(dev, off, val);
166 off += 2;
167 size -= 2;
168 }
169
170 while (size > 3) {
171 u32 val = data[off - init_off + 3];
172 val |= (u32) data[off - init_off + 2] << 8;
173 val |= (u32) data[off - init_off + 1] << 16;
174 val |= (u32) data[off - init_off] << 24;
175 rio_write_config_32(dev, off, val);
176 off += 4;
177 size -= 4;
178 }
179
180 if (size >= 2) {
181 u16 val = data[off - init_off + 1];
182 val |= (u16) data[off - init_off] << 8;
183 rio_write_config_16(dev, off, val);
184 off += 2;
185 size -= 2;
186 }
187
188 if (size) {
189 rio_write_config_8(dev, off, data[off - init_off]);
190 off++;
191 --size;
192 }
193
194 return count;
195}
196
197static struct bin_attribute rio_config_attr = {
198 .attr = {
199 .name = "config",
200 .mode = S_IRUGO | S_IWUSR,
201 .owner = THIS_MODULE,
202 },
203 .size = 0x200000,
204 .read = rio_read_config,
205 .write = rio_write_config,
206};
207
208/**
209 * rio_create_sysfs_dev_files - create RIO specific sysfs files
210 * @rdev: device whose entries should be created
211 *
212 * Create files when @rdev is added to sysfs.
213 */
214int rio_create_sysfs_dev_files(struct rio_dev *rdev)
215{
216 sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
217
218 return 0;
219}
220
221/**
222 * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
223 * @rdev: device whose entries we should free
224 *
225 * Cleanup when @rdev is removed from sysfs.
226 */
227void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
228{
229 sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
230}
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
new file mode 100644
index 000000000000..3ca1011ceaac
--- /dev/null
+++ b/drivers/rapidio/rio.c
@@ -0,0 +1,510 @@
1/*
2 * RapidIO interconnect services
3 * (RapidIO Interconnect Specification, http://www.rapidio.org)
4 *
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17
18#include <linux/delay.h>
19#include <linux/init.h>
20#include <linux/rio.h>
21#include <linux/rio_drv.h>
22#include <linux/rio_ids.h>
23#include <linux/rio_regs.h>
24#include <linux/module.h>
25#include <linux/spinlock.h>
26
27#include "rio.h"
28
29static LIST_HEAD(rio_mports);
30
31/**
32 * rio_local_get_device_id - Get the base/extended device id for a port
33 * @port: RIO master port from which to get the deviceid
34 *
35 * Reads the base/extended device id from the local device
36 * implementing the master port. Returns the 8/16-bit device
37 * id.
38 */
39u16 rio_local_get_device_id(struct rio_mport *port)
40{
41 u32 result;
42
43 rio_local_read_config_32(port, RIO_DID_CSR, &result);
44
45 return (RIO_GET_DID(result));
46}
47
48/**
49 * rio_request_inb_mbox - request inbound mailbox service
50 * @mport: RIO master port from which to allocate the mailbox resource
51 * @dev_id: Device specific pointer to pass on event
52 * @mbox: Mailbox number to claim
53 * @entries: Number of entries in inbound mailbox queue
54 * @minb: Callback to execute when inbound message is received
55 *
56 * Requests ownership of an inbound mailbox resource and binds
57 * a callback function to the resource. Returns %0 on success.
58 */
59int rio_request_inb_mbox(struct rio_mport *mport,
60 void *dev_id,
61 int mbox,
62 int entries,
63 void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
64 int slot))
65{
66 int rc = 0;
67
68 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
69
70 if (res) {
71 rio_init_mbox_res(res, mbox, mbox);
72
73 /* Make sure this mailbox isn't in use */
74 if ((rc =
75 request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
76 res)) < 0) {
77 kfree(res);
78 goto out;
79 }
80
81 mport->inb_msg[mbox].res = res;
82
83 /* Hook the inbound message callback */
84 mport->inb_msg[mbox].mcback = minb;
85
86 rc = rio_open_inb_mbox(mport, dev_id, mbox, entries);
87 } else
88 rc = -ENOMEM;
89
90 out:
91 return rc;
92}
93
94/**
95 * rio_release_inb_mbox - release inbound mailbox message service
96 * @mport: RIO master port from which to release the mailbox resource
97 * @mbox: Mailbox number to release
98 *
99 * Releases ownership of an inbound mailbox resource. Returns 0
100 * if the request has been satisfied.
101 */
102int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
103{
104 rio_close_inb_mbox(mport, mbox);
105
106 /* Release the mailbox resource */
107 return release_resource(mport->inb_msg[mbox].res);
108}
109
110/**
111 * rio_request_outb_mbox - request outbound mailbox service
112 * @mport: RIO master port from which to allocate the mailbox resource
113 * @dev_id: Device specific pointer to pass on event
114 * @mbox: Mailbox number to claim
115 * @entries: Number of entries in outbound mailbox queue
116 * @moutb: Callback to execute when outbound message is sent
117 *
118 * Requests ownership of an outbound mailbox resource and binds
119 * a callback function to the resource. Returns 0 on success.
120 */
121int rio_request_outb_mbox(struct rio_mport *mport,
122 void *dev_id,
123 int mbox,
124 int entries,
125 void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
126{
127 int rc = 0;
128
129 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
130
131 if (res) {
132 rio_init_mbox_res(res, mbox, mbox);
133
134 /* Make sure this outbound mailbox isn't in use */
135 if ((rc =
136 request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
137 res)) < 0) {
138 kfree(res);
139 goto out;
140 }
141
142 mport->outb_msg[mbox].res = res;
143
144 /* Hook the inbound message callback */
145 mport->outb_msg[mbox].mcback = moutb;
146
147 rc = rio_open_outb_mbox(mport, dev_id, mbox, entries);
148 } else
149 rc = -ENOMEM;
150
151 out:
152 return rc;
153}
154
155/**
156 * rio_release_outb_mbox - release outbound mailbox message service
157 * @mport: RIO master port from which to release the mailbox resource
158 * @mbox: Mailbox number to release
159 *
160 * Releases ownership of an inbound mailbox resource. Returns 0
161 * if the request has been satisfied.
162 */
163int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
164{
165 rio_close_outb_mbox(mport, mbox);
166
167 /* Release the mailbox resource */
168 return release_resource(mport->outb_msg[mbox].res);
169}
170
171/**
172 * rio_setup_inb_dbell - bind inbound doorbell callback
173 * @mport: RIO master port to bind the doorbell callback
174 * @dev_id: Device specific pointer to pass on event
175 * @res: Doorbell message resource
176 * @dinb: Callback to execute when doorbell is received
177 *
178 * Adds a doorbell resource/callback pair into a port's
179 * doorbell event list. Returns 0 if the request has been
180 * satisfied.
181 */
182static int
183rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
184 void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
185 u16 info))
186{
187 int rc = 0;
188 struct rio_dbell *dbell;
189
190 if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
191 rc = -ENOMEM;
192 goto out;
193 }
194
195 dbell->res = res;
196 dbell->dinb = dinb;
197 dbell->dev_id = dev_id;
198
199 list_add_tail(&dbell->node, &mport->dbells);
200
201 out:
202 return rc;
203}
204
205/**
206 * rio_request_inb_dbell - request inbound doorbell message service
207 * @mport: RIO master port from which to allocate the doorbell resource
208 * @dev_id: Device specific pointer to pass on event
209 * @start: Doorbell info range start
210 * @end: Doorbell info range end
211 * @dinb: Callback to execute when doorbell is received
212 *
213 * Requests ownership of an inbound doorbell resource and binds
214 * a callback function to the resource. Returns 0 if the request
215 * has been satisfied.
216 */
217int rio_request_inb_dbell(struct rio_mport *mport,
218 void *dev_id,
219 u16 start,
220 u16 end,
221 void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
222 u16 dst, u16 info))
223{
224 int rc = 0;
225
226 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
227
228 if (res) {
229 rio_init_dbell_res(res, start, end);
230
231 /* Make sure these doorbells aren't in use */
232 if ((rc =
233 request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
234 res)) < 0) {
235 kfree(res);
236 goto out;
237 }
238
239 /* Hook the doorbell callback */
240 rc = rio_setup_inb_dbell(mport, dev_id, res, dinb);
241 } else
242 rc = -ENOMEM;
243
244 out:
245 return rc;
246}
247
248/**
249 * rio_release_inb_dbell - release inbound doorbell message service
250 * @mport: RIO master port from which to release the doorbell resource
251 * @start: Doorbell info range start
252 * @end: Doorbell info range end
253 *
254 * Releases ownership of an inbound doorbell resource and removes
255 * callback from the doorbell event list. Returns 0 if the request
256 * has been satisfied.
257 */
258int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
259{
260 int rc = 0, found = 0;
261 struct rio_dbell *dbell;
262
263 list_for_each_entry(dbell, &mport->dbells, node) {
264 if ((dbell->res->start == start) && (dbell->res->end == end)) {
265 found = 1;
266 break;
267 }
268 }
269
270 /* If we can't find an exact match, fail */
271 if (!found) {
272 rc = -EINVAL;
273 goto out;
274 }
275
276 /* Delete from list */
277 list_del(&dbell->node);
278
279 /* Release the doorbell resource */
280 rc = release_resource(dbell->res);
281
282 /* Free the doorbell event */
283 kfree(dbell);
284
285 out:
286 return rc;
287}
288
289/**
290 * rio_request_outb_dbell - request outbound doorbell message range
291 * @rdev: RIO device from which to allocate the doorbell resource
292 * @start: Doorbell message range start
293 * @end: Doorbell message range end
294 *
295 * Requests ownership of a doorbell message range. Returns a resource
296 * if the request has been satisfied or %NULL on failure.
297 */
298struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
299 u16 end)
300{
301 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
302
303 if (res) {
304 rio_init_dbell_res(res, start, end);
305
306 /* Make sure these doorbells aren't in use */
307 if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
308 < 0) {
309 kfree(res);
310 res = NULL;
311 }
312 }
313
314 return res;
315}
316
317/**
318 * rio_release_outb_dbell - release outbound doorbell message range
319 * @rdev: RIO device from which to release the doorbell resource
320 * @res: Doorbell resource to be freed
321 *
322 * Releases ownership of a doorbell message range. Returns 0 if the
323 * request has been satisfied.
324 */
325int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
326{
327 int rc = release_resource(res);
328
329 kfree(res);
330
331 return rc;
332}
333
334/**
335 * rio_mport_get_feature - query for devices' extended features
336 * @port: Master port to issue transaction
337 * @local: Indicate a local master port or remote device access
338 * @destid: Destination ID of the device
339 * @hopcount: Number of switch hops to the device
340 * @ftr: Extended feature code
341 *
342 * Tell if a device supports a given RapidIO capability.
343 * Returns the offset of the requested extended feature
344 * block within the device's RIO configuration space or
345 * 0 in case the device does not support it. Possible
346 * values for @ftr:
347 *
348 * %RIO_EFB_PAR_EP_ID LP/LVDS EP Devices
349 *
350 * %RIO_EFB_PAR_EP_REC_ID LP/LVDS EP Recovery Devices
351 *
352 * %RIO_EFB_PAR_EP_FREE_ID LP/LVDS EP Free Devices
353 *
354 * %RIO_EFB_SER_EP_ID LP/Serial EP Devices
355 *
356 * %RIO_EFB_SER_EP_REC_ID LP/Serial EP Recovery Devices
357 *
358 * %RIO_EFB_SER_EP_FREE_ID LP/Serial EP Free Devices
359 */
360u32
361rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
362 u8 hopcount, int ftr)
363{
364 u32 asm_info, ext_ftr_ptr, ftr_header;
365
366 if (local)
367 rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info);
368 else
369 rio_mport_read_config_32(port, destid, hopcount,
370 RIO_ASM_INFO_CAR, &asm_info);
371
372 ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK;
373
374 while (ext_ftr_ptr) {
375 if (local)
376 rio_local_read_config_32(port, ext_ftr_ptr,
377 &ftr_header);
378 else
379 rio_mport_read_config_32(port, destid, hopcount,
380 ext_ftr_ptr, &ftr_header);
381 if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
382 return ext_ftr_ptr;
383 if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
384 break;
385 }
386
387 return 0;
388}
389
390/**
391 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
392 * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
393 * @did: RIO did to match or %RIO_ANY_ID to match all dids
394 * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids
395 * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids
396 * @from: Previous RIO device found in search, or %NULL for new search
397 *
398 * Iterates through the list of known RIO devices. If a RIO device is
399 * found with a matching @vid, @did, @asm_vid, @asm_did, the reference
400 * count to the device is incrememted and a pointer to its device
401 * structure is returned. Otherwise, %NULL is returned. A new search
402 * is initiated by passing %NULL to the @from argument. Otherwise, if
403 * @from is not %NULL, searches continue from next device on the global
404 * list. The reference count for @from is always decremented if it is
405 * not %NULL.
406 */
407struct rio_dev *rio_get_asm(u16 vid, u16 did,
408 u16 asm_vid, u16 asm_did, struct rio_dev *from)
409{
410 struct list_head *n;
411 struct rio_dev *rdev;
412
413 WARN_ON(in_interrupt());
414 spin_lock(&rio_global_list_lock);
415 n = from ? from->global_list.next : rio_devices.next;
416
417 while (n && (n != &rio_devices)) {
418 rdev = rio_dev_g(n);
419 if ((vid == RIO_ANY_ID || rdev->vid == vid) &&
420 (did == RIO_ANY_ID || rdev->did == did) &&
421 (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) &&
422 (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did))
423 goto exit;
424 n = n->next;
425 }
426 rdev = NULL;
427 exit:
428 rio_dev_put(from);
429 rdev = rio_dev_get(rdev);
430 spin_unlock(&rio_global_list_lock);
431 return rdev;
432}
433
434/**
435 * rio_get_device - Begin or continue searching for a RIO device by vid/did
436 * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
437 * @did: RIO did to match or %RIO_ANY_ID to match all dids
438 * @from: Previous RIO device found in search, or %NULL for new search
439 *
440 * Iterates through the list of known RIO devices. If a RIO device is
441 * found with a matching @vid and @did, the reference count to the
442 * device is incrememted and a pointer to its device structure is returned.
443 * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
444 * to the @from argument. Otherwise, if @from is not %NULL, searches
445 * continue from next device on the global list. The reference count for
446 * @from is always decremented if it is not %NULL.
447 */
448struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
449{
450 return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
451}
452
453static void rio_fixup_device(struct rio_dev *dev)
454{
455}
456
457static int __devinit rio_init(void)
458{
459 struct rio_dev *dev = NULL;
460
461 while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) {
462 rio_fixup_device(dev);
463 }
464 return 0;
465}
466
467device_initcall(rio_init);
468
469int rio_init_mports(void)
470{
471 int rc = 0;
472 struct rio_mport *port;
473
474 list_for_each_entry(port, &rio_mports, node) {
475 if (!request_mem_region(port->iores.start,
476 port->iores.end - port->iores.start,
477 port->name)) {
478 printk(KERN_ERR
479 "RIO: Error requesting master port region %8.8lx-%8.8lx\n",
480 port->iores.start, port->iores.end - 1);
481 rc = -ENOMEM;
482 goto out;
483 }
484
485 if (port->host_deviceid >= 0)
486 rio_enum_mport(port);
487 else
488 rio_disc_mport(port);
489 }
490
491 out:
492 return rc;
493}
494
495void rio_register_mport(struct rio_mport *port)
496{
497 list_add_tail(&port->node, &rio_mports);
498}
499
500EXPORT_SYMBOL_GPL(rio_local_get_device_id);
501EXPORT_SYMBOL_GPL(rio_get_device);
502EXPORT_SYMBOL_GPL(rio_get_asm);
503EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
504EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
505EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
506EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
507EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
508EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
509EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
510EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
new file mode 100644
index 000000000000..b242cee656e7
--- /dev/null
+++ b/drivers/rapidio/rio.h
@@ -0,0 +1,60 @@
1/*
2 * RapidIO interconnect services
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/device.h>
14#include <linux/list.h>
15#include <linux/rio.h>
16
17/* Functions internal to the RIO core code */
18
19extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
20 u8 hopcount, int ftr);
21extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
22extern int rio_enum_mport(struct rio_mport *mport);
23extern int rio_disc_mport(struct rio_mport *mport);
24
25/* Structures internal to the RIO core code */
26extern struct device_attribute rio_dev_attrs[];
27extern spinlock_t rio_global_list_lock;
28
29extern struct rio_route_ops __start_rio_route_ops[];
30extern struct rio_route_ops __end_rio_route_ops[];
31
32/* Helpers internal to the RIO core code */
33#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \
34 static struct rio_route_ops __rio_route_ops __attribute_used__ \
35 __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook };
36
37/**
38 * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
39 * @vid: RIO vendor ID
40 * @did: RIO device ID
41 * @add_hook: Callback that adds a route entry
42 * @get_hook: Callback that gets a route entry
43 *
44 * Manipulating switch route tables in RIO is switch specific. This
45 * registers a switch by vendor and device ID with two callbacks for
46 * modifying and retrieving route entries in a switch. A &struct
47 * rio_route_ops is initialized with the ops and placed into a
48 * RIO-specific kernel section.
49 */
50#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook) \
51 DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
52 vid, did, add_hook, get_hook)
53
54#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
55#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16)
56#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
57#else
58#define RIO_GET_DID(x) (x & 0xffff)
59#define RIO_SET_DID(x) (x & 0xffff)
60#endif
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
new file mode 100644
index 000000000000..b924f8301761
--- /dev/null
+++ b/drivers/rapidio/switches/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for RIO switches
3#
4
5obj-$(CONFIG_RAPIDIO) += tsi500.o
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
new file mode 100644
index 000000000000..c77c23bd9840
--- /dev/null
+++ b/drivers/rapidio/switches/tsi500.c
@@ -0,0 +1,60 @@
1/*
2 * RapidIO Tsi500 switch support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/rio.h>
14#include <linux/rio_drv.h>
15#include <linux/rio_ids.h>
16#include "../rio.h"
17
18static int
19tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
20{
21 int i;
22 u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
23 u32 result;
24
25 if (table == 0xff) {
26 rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
27 result &= ~(0xf << (4*(route_destid & 0x7)));
28 for (i=0;i<4;i++)
29 rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
30 }
31 else {
32 rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
33 result &= ~(0xf << (4*(route_destid & 0x7)));
34 rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
35 }
36
37 return 0;
38}
39
40static int
41tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
42{
43 int ret = 0;
44 u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
45 u32 result;
46
47 if (table == 0xff)
48 rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
49 else
50 rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
51
52 result &= 0xf << (4*(route_destid & 0x7));
53 *route_port = result >> (4*(route_destid & 0x7));
54 if (*route_port > 3)
55 ret = -1;
56
57 return ret;
58}
59
60DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);