Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ec3ba69 authored by Alexandre Bounine's avatar Alexandre Bounine Committed by Linus Torvalds
Browse files

rapidio: convert switch drivers to modules



Rework RapidIO switch drivers to add an option to build them as loadable
kernel modules.

This patch removes RapidIO-specific vmlinux section and converts switch
drivers to be compatible with LDM driver registration method.  To simplify
registration of device-specific callback routines this patch introduces
rio_switch_ops data structure.  The sw_sysfs() callback is removed from
the list of device-specific operations because under the new structure its
functions can be handled by switch driver's probe() and remove() routines.

If a specific switch device driver is not loaded the RapidIO subsystem
core will use default standard-based operations to configure a switch.
Because the current implementation of RapidIO enumeration/discovery method
relies on availability of device-specific operations for error management,
switch device drivers must be loaded before the RapidIO
enumeration/discovery starts.

This patch also moves several common routines from enumeration/discovery
module into the RapidIO core code to make switch-specific operations
accessible to all components of RapidIO subsystem.

Signed-off-by: default avatarAlexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
Cc: Stef van Os <stef.van.os@Prodrive.nl>
Cc: Jean Delvare <jdelvare@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 36f0efbb
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -67,4 +67,9 @@ config RAPIDIO_ENUM_BASIC

endchoice

menu "RapidIO Switch drivers"
	depends on RAPIDIO

source "drivers/rapidio/switches/Kconfig"

endmenu
+9 −162
Original line number Diff line number Diff line
@@ -406,6 +406,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
		rio_mport_write_config_32(port, destid, hopcount,
					  RIO_COMPONENT_TAG_CSR, next_comptag);
		rdev->comp_tag = next_comptag++;
		rdev->do_enum = true;
	}  else {
		rio_mport_read_config_32(port, destid, hopcount,
					 RIO_COMPONENT_TAG_CSR,
@@ -434,6 +435,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
		rswitch = rdev->rswitch;
		rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID;
		rswitch->port_ok = 0;
		spin_lock_init(&rswitch->lock);
		rswitch->route_table = kzalloc(sizeof(u8)*
					RIO_MAX_ROUTE_ENTRIES(port->sys_size),
					GFP_KERNEL);
@@ -445,11 +447,9 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
			rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
		dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
			     rswitch->switchid);
		rio_switch_init(rdev, do_enum);

		if (do_enum && rswitch->clr_table)
			rswitch->clr_table(port, destid, hopcount,
					   RIO_GLOBAL_TABLE);
		if (do_enum)
			rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0);

		list_add_tail(&rswitch->node, &net->switches);

@@ -532,156 +532,6 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
	return result & RIO_PORT_N_ERR_STS_PORT_OK;
}

/**
 * rio_lock_device - Acquires host device lock for specified device
 * @port: Master port to send transaction
 * @destid: Destination ID for device/switch
 * @hopcount: Hopcount to reach switch
 * @wait_ms: Max wait time in msec (0 = no timeout)
 *
 * Attepts to acquire host device lock for specified device
 * Returns 0 if device lock acquired or EINVAL if timeout expires.
 */
static int
rio_lock_device(struct rio_mport *port, u16 destid, u8 hopcount, int wait_ms)
{
	u32 result;
	int tcnt = 0;

	/* Attempt to acquire device lock */
	rio_mport_write_config_32(port, destid, hopcount,
				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
	rio_mport_read_config_32(port, destid, hopcount,
				 RIO_HOST_DID_LOCK_CSR, &result);

	while (result != port->host_deviceid) {
		if (wait_ms != 0 && tcnt == wait_ms) {
			pr_debug("RIO: timeout when locking device %x:%x\n",
				destid, hopcount);
			return -EINVAL;
		}

		/* Delay a bit */
		mdelay(1);
		tcnt++;
		/* Try to acquire device lock again */
		rio_mport_write_config_32(port, destid,
			hopcount,
			RIO_HOST_DID_LOCK_CSR,
			port->host_deviceid);
		rio_mport_read_config_32(port, destid,
			hopcount,
			RIO_HOST_DID_LOCK_CSR, &result);
	}

	return 0;
}

/**
 * rio_unlock_device - Releases host device lock for specified device
 * @port: Master port to send transaction
 * @destid: Destination ID for device/switch
 * @hopcount: Hopcount to reach switch
 *
 * Returns 0 if device lock released or EINVAL if fails.
 */
static int
rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
{
	u32 result;

	/* Release device lock */
	rio_mport_write_config_32(port, destid,
				  hopcount,
				  RIO_HOST_DID_LOCK_CSR,
				  port->host_deviceid);
	rio_mport_read_config_32(port, destid, hopcount,
		RIO_HOST_DID_LOCK_CSR, &result);
	if ((result & 0xffff) != 0xffff) {
		pr_debug("RIO: badness when releasing device lock %x:%x\n",
			 destid, hopcount);
		return -EINVAL;
	}

	return 0;
}

/**
 * rio_route_add_entry- Add a route entry to a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @route_destid: Destination ID to be routed
 * @route_port: Port number to be routed
 * @lock: lock switch device flag
 *
 * Calls the switch specific add_entry() method to add a route entry
 * on a switch. The route table can be specified using the @table
 * argument if a switch has per port routing tables or the normal
 * use is to specific all tables (or the global table) by passing
 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
 * on failure.
 */
static int
rio_route_add_entry(struct rio_dev *rdev,
		    u16 table, u16 route_destid, u8 route_port, int lock)
{
	int rc;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	rc = rdev->rswitch->add_entry(rdev->net->hport, rdev->destid,
				      rdev->hopcount, table,
				      route_destid, route_port);
	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);

	return rc;
}

/**
 * rio_route_get_entry- Read a route entry in a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @route_destid: Destination ID to be routed
 * @route_port: Pointer to read port number into
 * @lock: lock switch device flag
 *
 * Calls the switch specific get_entry() method to read a route entry
 * in a switch. The route table can be specified using the @table
 * argument if a switch has per port routing tables or the normal
 * use is to specific all tables (or the global table) by passing
 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
 * on failure.
 */
static int
rio_route_get_entry(struct rio_dev *rdev, u16 table,
		    u16 route_destid, u8 *route_port, int lock)
{
	int rc;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	rc = rdev->rswitch->get_entry(rdev->net->hport, rdev->destid,
				      rdev->hopcount, table,
				      route_destid, route_port);
	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);

	return rc;
}

/**
 * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
 * @port: Master port to send transaction
@@ -1094,16 +944,13 @@ static void rio_update_route_tables(struct rio_net *net)

				sport = RIO_GET_PORT_NUM(swrdev->swpinfo);

				if (rswitch->add_entry)	{
					rio_route_add_entry(swrdev,
						RIO_GLOBAL_TABLE, destid,
						sport, 0);
				rio_route_add_entry(swrdev, RIO_GLOBAL_TABLE,
						    destid, sport, 0);
				rswitch->route_table[destid] = sport;
			}
		}
	}
}
}

/**
 * rio_init_em - Initializes RIO Error Management (for switches)
@@ -1115,8 +962,8 @@ static void rio_update_route_tables(struct rio_net *net)
static void rio_init_em(struct rio_dev *rdev)
{
	if (rio_is_switch(rdev) && (rdev->em_efptr) &&
	    (rdev->rswitch->em_init)) {
		rdev->rswitch->em_init(rdev);
	    rdev->rswitch->ops && rdev->rswitch->ops->em_init) {
		rdev->rswitch->ops->em_init(rdev);
	}
}

+0 −4
Original line number Diff line number Diff line
@@ -257,8 +257,6 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
		err |= device_create_file(&rdev->dev, &dev_attr_routes);
		err |= device_create_file(&rdev->dev, &dev_attr_lnext);
		err |= device_create_file(&rdev->dev, &dev_attr_hopcount);
		if (!err && rdev->rswitch->sw_sysfs)
			err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE);
	}

	if (err)
@@ -281,8 +279,6 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
		device_remove_file(&rdev->dev, &dev_attr_routes);
		device_remove_file(&rdev->dev, &dev_attr_lnext);
		device_remove_file(&rdev->dev, &dev_attr_hopcount);
		if (rdev->rswitch->sw_sysfs)
			rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
	}
}

+239 −47
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@
 *
 * Copyright 2009 Integrated Device Technology, Inc.
 * Alex Bounine <alexandre.bounine@idt.com>
 * - Added Port-Write/Error Management initialization and handling
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
@@ -579,44 +578,6 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
}
EXPORT_SYMBOL_GPL(rio_set_port_lockout);

/**
 * rio_switch_init - Sets switch operations for a particular vendor switch
 * @rdev: RIO device
 * @do_enum: Enumeration/Discovery mode flag
 *
 * Searches the RIO switch ops table for known switch types. If the vid
 * and did match a switch table entry, then call switch initialization
 * routine to setup switch-specific routines.
 */
void rio_switch_init(struct rio_dev *rdev, int do_enum)
{
	struct rio_switch_ops *cur = __start_rio_switch_ops;
	struct rio_switch_ops *end = __end_rio_switch_ops;

	while (cur < end) {
		if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
			pr_debug("RIO: calling init routine for %s\n",
				 rio_name(rdev));
			cur->init_hook(rdev, do_enum);
			break;
		}
		cur++;
	}

	if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
		pr_debug("RIO: adding STD routing ops for %s\n",
			rio_name(rdev));
		rdev->rswitch->add_entry = rio_std_route_add_entry;
		rdev->rswitch->get_entry = rio_std_route_get_entry;
		rdev->rswitch->clr_table = rio_std_route_clr_table;
	}

	if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
		printk(KERN_ERR "RIO: missing routing ops for %s\n",
		       rio_name(rdev));
}
EXPORT_SYMBOL_GPL(rio_switch_init);

/**
 * rio_enable_rx_tx_port - enable input receiver and output transmitter of
 * given port
@@ -970,8 +931,8 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
	/*
	 * Process the port-write notification from switch
	 */
	if (rdev->rswitch->em_handle)
		rdev->rswitch->em_handle(rdev, portnum);
	if (rdev->rswitch->ops && rdev->rswitch->ops->em_handle)
		rdev->rswitch->ops->em_handle(rdev, portnum);

	rio_read_config_32(rdev,
			rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum),
@@ -1207,7 +1168,8 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
 * @route_destid: destID entry in the RT
 * @route_port: destination port for specified destID
 */
int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
static int
rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
			u16 table, u16 route_destid, u8 route_port)
{
	if (table == RIO_GLOBAL_TABLE) {
@@ -1234,7 +1196,8 @@ int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
 * @route_destid: destID entry in the RT
 * @route_port: returned destination port for specified destID
 */
int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
static int
rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
			u16 table, u16 route_destid, u8 *route_port)
{
	u32 result;
@@ -1259,7 +1222,8 @@ int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
 * @hopcount: Number of switch hops to the device
 * @table: routing table ID (global or port-specific)
 */
int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
static int
rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
			u16 table)
{
	u32 max_destid = 0xff;
@@ -1301,6 +1265,234 @@ int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
	return 0;
}

/**
 * rio_lock_device - Acquires host device lock for specified device
 * @port: Master port to send transaction
 * @destid: Destination ID for device/switch
 * @hopcount: Hopcount to reach switch
 * @wait_ms: Max wait time in msec (0 = no timeout)
 *
 * Attepts to acquire host device lock for specified device
 * Returns 0 if device lock acquired or EINVAL if timeout expires.
 */
int rio_lock_device(struct rio_mport *port, u16 destid,
		    u8 hopcount, int wait_ms)
{
	u32 result;
	int tcnt = 0;

	/* Attempt to acquire device lock */
	rio_mport_write_config_32(port, destid, hopcount,
				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
	rio_mport_read_config_32(port, destid, hopcount,
				 RIO_HOST_DID_LOCK_CSR, &result);

	while (result != port->host_deviceid) {
		if (wait_ms != 0 && tcnt == wait_ms) {
			pr_debug("RIO: timeout when locking device %x:%x\n",
				destid, hopcount);
			return -EINVAL;
		}

		/* Delay a bit */
		mdelay(1);
		tcnt++;
		/* Try to acquire device lock again */
		rio_mport_write_config_32(port, destid,
			hopcount,
			RIO_HOST_DID_LOCK_CSR,
			port->host_deviceid);
		rio_mport_read_config_32(port, destid,
			hopcount,
			RIO_HOST_DID_LOCK_CSR, &result);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rio_lock_device);

/**
 * rio_unlock_device - Releases host device lock for specified device
 * @port: Master port to send transaction
 * @destid: Destination ID for device/switch
 * @hopcount: Hopcount to reach switch
 *
 * Returns 0 if device lock released or EINVAL if fails.
 */
int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
{
	u32 result;

	/* Release device lock */
	rio_mport_write_config_32(port, destid,
				  hopcount,
				  RIO_HOST_DID_LOCK_CSR,
				  port->host_deviceid);
	rio_mport_read_config_32(port, destid, hopcount,
		RIO_HOST_DID_LOCK_CSR, &result);
	if ((result & 0xffff) != 0xffff) {
		pr_debug("RIO: badness when releasing device lock %x:%x\n",
			 destid, hopcount);
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rio_unlock_device);

/**
 * rio_route_add_entry- Add a route entry to a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @route_destid: Destination ID to be routed
 * @route_port: Port number to be routed
 * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
 *
 * If available calls the switch specific add_entry() method to add a route
 * entry into a switch routing table. Otherwise uses standard RT update method
 * as defined by RapidIO specification. A specific routing table can be selected
 * using the @table argument if a switch has per port routing tables or
 * the standard (or global) table may be used by passing
 * %RIO_GLOBAL_TABLE in @table.
 *
 * Returns %0 on success or %-EINVAL on failure.
 */
int rio_route_add_entry(struct rio_dev *rdev,
			u16 table, u16 route_destid, u8 route_port, int lock)
{
	int rc = -EINVAL;
	struct rio_switch_ops *ops = rdev->rswitch->ops;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	spin_lock(&rdev->rswitch->lock);

	if (ops == NULL || ops->add_entry == NULL) {
		rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid,
					     rdev->hopcount, table,
					     route_destid, route_port);
	} else if (try_module_get(ops->owner)) {
		rc = ops->add_entry(rdev->net->hport, rdev->destid,
				    rdev->hopcount, table, route_destid,
				    route_port);
		module_put(ops->owner);
	}

	spin_unlock(&rdev->rswitch->lock);

	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_route_add_entry);

/**
 * rio_route_get_entry- Read an entry from a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @route_destid: Destination ID to be routed
 * @route_port: Pointer to read port number into
 * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
 *
 * If available calls the switch specific get_entry() method to fetch a route
 * entry from a switch routing table. Otherwise uses standard RT read method
 * as defined by RapidIO specification. A specific routing table can be selected
 * using the @table argument if a switch has per port routing tables or
 * the standard (or global) table may be used by passing
 * %RIO_GLOBAL_TABLE in @table.
 *
 * Returns %0 on success or %-EINVAL on failure.
 */
int rio_route_get_entry(struct rio_dev *rdev, u16 table,
			u16 route_destid, u8 *route_port, int lock)
{
	int rc = -EINVAL;
	struct rio_switch_ops *ops = rdev->rswitch->ops;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	spin_lock(&rdev->rswitch->lock);

	if (ops == NULL || ops->get_entry == NULL) {
		rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid,
					     rdev->hopcount, table,
					     route_destid, route_port);
	} else if (try_module_get(ops->owner)) {
		rc = ops->get_entry(rdev->net->hport, rdev->destid,
				    rdev->hopcount, table, route_destid,
				    route_port);
		module_put(ops->owner);
	}

	spin_unlock(&rdev->rswitch->lock);

	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);
	return rc;
}
EXPORT_SYMBOL_GPL(rio_route_get_entry);

/**
 * rio_route_clr_table - Clear a switch routing table
 * @rdev: RIO device
 * @table: Routing table ID
 * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
 *
 * If available calls the switch specific clr_table() method to clear a switch
 * routing table. Otherwise uses standard RT write method as defined by RapidIO
 * specification. A specific routing table can be selected using the @table
 * argument if a switch has per port routing tables or the standard (or global)
 * table may be used by passing %RIO_GLOBAL_TABLE in @table.
 *
 * Returns %0 on success or %-EINVAL on failure.
 */
int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock)
{
	int rc = -EINVAL;
	struct rio_switch_ops *ops = rdev->rswitch->ops;

	if (lock) {
		rc = rio_lock_device(rdev->net->hport, rdev->destid,
				     rdev->hopcount, 1000);
		if (rc)
			return rc;
	}

	spin_lock(&rdev->rswitch->lock);

	if (ops == NULL || ops->clr_table == NULL) {
		rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid,
					     rdev->hopcount, table);
	} else if (try_module_get(ops->owner)) {
		rc = ops->clr_table(rdev->net->hport, rdev->destid,
				    rdev->hopcount, table);

		module_put(ops->owner);
	}

	spin_unlock(&rdev->rswitch->lock);

	if (lock)
		rio_unlock_device(rdev->net->hport, rdev->destid,
				  rdev->hopcount);

	return rc;
}
EXPORT_SYMBOL_GPL(rio_route_clr_table);

#ifdef CONFIG_RAPIDIO_DMA_ENGINE

static bool rio_chan_filter(struct dma_chan *chan, void *arg)
+8 −33
Original line number Diff line number Diff line
@@ -28,18 +28,17 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
				    u8 hopcount);
extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
				   u8 hopcount, u16 table, u16 route_destid,
				   u8 route_port);
extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid,
				   u8 hopcount, u16 table, u16 route_destid,
				   u8 *route_port);
extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
				   u8 hopcount, u16 table);
extern int rio_lock_device(struct rio_mport *port, u16 destid,
			u8 hopcount, int wait_ms);
extern int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount);
extern int rio_route_add_entry(struct rio_dev *rdev,
			u16 table, u16 route_destid, u8 route_port, int lock);
extern int rio_route_get_entry(struct rio_dev *rdev, u16 table,
			u16 route_destid, u8 *route_port, int lock);
extern int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock);
extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock);
extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from);
extern int rio_add_device(struct rio_dev *rdev);
extern void rio_switch_init(struct rio_dev *rdev, int do_enum);
extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
				 u8 hopcount, u8 port_num);
extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops);
@@ -51,29 +50,5 @@ extern struct rio_mport *rio_find_mport(int mport_id);
extern struct device_attribute rio_dev_attrs[];
extern struct bus_attribute rio_bus_attrs[];

extern struct rio_switch_ops __start_rio_switch_ops[];
extern struct rio_switch_ops __end_rio_switch_ops[];

/* Helpers internal to the RIO core code */
#define DECLARE_RIO_SWITCH_SECTION(section, name, vid, did, init_hook) \
	static const struct rio_switch_ops __rio_switch_##name __used \
	__section(section) = { vid, did, init_hook };

/**
 * DECLARE_RIO_SWITCH_INIT - Registers switch initialization routine
 * @vid: RIO vendor ID
 * @did: RIO device ID
 * @init_hook: Callback that performs switch-specific initialization
 *
 * Manipulating switch route tables and error management in RIO
 * is switch specific. This registers a switch by vendor and device ID with
 * initialization callback for setting up switch operations and (if required)
 * hardware initialization. A &struct rio_switch_ops is initialized with
 * pointer to the init routine and placed into a RIO-specific kernel section.
 */
#define DECLARE_RIO_SWITCH_INIT(vid, did, init_hook)		\
	DECLARE_RIO_SWITCH_SECTION(.rio_switch_ops, vid##did, \
			vid, did, init_hook)

#define RIO_GET_DID(size, x)	(size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
#define RIO_SET_DID(size, x)	(size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
Loading