Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rapidio: move net allocation into core code

Make net allocation/release routines available to all components of
RapidIO subsystem by moving code from rio-scan enumerator.

Make destination ID allocation method private to existing enumerator
because other enumeration methods can use their own algorithm.

Setup net device object as a parent of all RapidIO devices residing in
it and register net as a child of active mport device.

Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alexandre Bounine and committed by
Linus Torvalds
e6b585ca b74ec56e

+133 -49
+68 -40
drivers/rapidio/rio-scan.c
··· 39 39 40 40 static void rio_init_em(struct rio_dev *rdev); 41 41 42 + struct rio_id_table { 43 + u16 start; /* logical minimal id */ 44 + u32 max; /* max number of IDs in table */ 45 + spinlock_t lock; 46 + unsigned long table[0]; 47 + }; 48 + 42 49 static int next_destid = 0; 43 50 static int next_comptag = 1; 44 51 ··· 69 62 static u16 rio_destid_alloc(struct rio_net *net) 70 63 { 71 64 int destid; 72 - struct rio_id_table *idtab = &net->destid_table; 65 + struct rio_id_table *idtab = (struct rio_id_table *)net->enum_data; 73 66 74 67 spin_lock(&idtab->lock); 75 68 destid = find_first_zero_bit(idtab->table, idtab->max); ··· 95 88 static int rio_destid_reserve(struct rio_net *net, u16 destid) 96 89 { 97 90 int oldbit; 98 - struct rio_id_table *idtab = &net->destid_table; 91 + struct rio_id_table *idtab = (struct rio_id_table *)net->enum_data; 99 92 100 93 destid -= idtab->start; 101 94 spin_lock(&idtab->lock); ··· 113 106 */ 114 107 static void rio_destid_free(struct rio_net *net, u16 destid) 115 108 { 116 - struct rio_id_table *idtab = &net->destid_table; 109 + struct rio_id_table *idtab = (struct rio_id_table *)net->enum_data; 117 110 118 111 destid -= idtab->start; 119 112 spin_lock(&idtab->lock); ··· 128 121 static u16 rio_destid_first(struct rio_net *net) 129 122 { 130 123 int destid; 131 - struct rio_id_table *idtab = &net->destid_table; 124 + struct rio_id_table *idtab = (struct rio_id_table *)net->enum_data; 132 125 133 126 spin_lock(&idtab->lock); 134 127 destid = find_first_bit(idtab->table, idtab->max); ··· 148 141 static u16 rio_destid_next(struct rio_net *net, u16 from) 149 142 { 150 143 int destid; 151 - struct rio_id_table *idtab = &net->destid_table; 144 + struct rio_id_table *idtab = (struct rio_id_table *)net->enum_data; 152 145 153 146 spin_lock(&idtab->lock); 154 147 destid = find_next_bit(idtab->table, idtab->max, from); ··· 465 458 rdev->comp_tag & RIO_CTAG_UDEVID); 466 459 } 467 460 468 - rdev->dev.parent = &port->dev; 461 + rdev->dev.parent = &net->dev; 469 462 rio_attach_device(rdev); 470 463 rdev->dev.release = rio_release_dev; 471 464 rdev->dma_mask = DMA_BIT_MASK(32); ··· 862 855 return result & RIO_PORT_N_ERR_STS_PORT_OK; 863 856 } 864 857 865 - /** 866 - * rio_alloc_net- Allocate and configure a new RIO network 867 - * @port: Master port associated with the RIO network 868 - * @do_enum: Enumeration/Discovery mode flag 869 - * @start: logical minimal start id for new net 870 - * 871 - * Allocates a RIO network structure, initializes per-network 872 - * list heads, and adds the associated master port to the 873 - * network list of associated master ports. Returns a 874 - * RIO network pointer on success or %NULL on failure. 875 - */ 876 - static struct rio_net *rio_alloc_net(struct rio_mport *port, 877 - int do_enum, u16 start) 858 + static void rio_scan_release_net(struct rio_net *net) 859 + { 860 + pr_debug("RIO-SCAN: %s: net_%d\n", __func__, net->id); 861 + kfree(net->enum_data); 862 + } 863 + 864 + static void rio_scan_release_dev(struct device *dev) 878 865 { 879 866 struct rio_net *net; 880 867 881 - net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); 882 - if (net && do_enum) { 883 - net->destid_table.table = kcalloc( 884 - BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)), 885 - sizeof(long), 886 - GFP_KERNEL); 868 + net = to_rio_net(dev); 869 + pr_debug("RIO-SCAN: %s: net_%d\n", __func__, net->id); 870 + kfree(net); 871 + } 887 872 888 - if (net->destid_table.table == NULL) { 873 + /* 874 + * rio_scan_alloc_net - Allocate and configure a new RIO network 875 + * @mport: Master port associated with the RIO network 876 + * @do_enum: Enumeration/Discovery mode flag 877 + * @start: logical minimal start id for new net 878 + * 879 + * Allocates a new RIO network structure and initializes enumerator-specific 880 + * part of it (if required). 881 + * Returns a RIO network pointer on success or %NULL on failure. 882 + */ 883 + static struct rio_net *rio_scan_alloc_net(struct rio_mport *mport, 884 + int do_enum, u16 start) 885 + { 886 + struct rio_net *net; 887 + 888 + net = rio_alloc_net(mport); 889 + 890 + if (net && do_enum) { 891 + struct rio_id_table *idtab; 892 + size_t size; 893 + 894 + size = sizeof(struct rio_id_table) + 895 + BITS_TO_LONGS( 896 + RIO_MAX_ROUTE_ENTRIES(mport->sys_size) 897 + ) * sizeof(long); 898 + 899 + idtab = kzalloc(size, GFP_KERNEL); 900 + 901 + if (idtab == NULL) { 889 902 pr_err("RIO: failed to allocate destID table\n"); 890 - kfree(net); 903 + rio_free_net(net); 891 904 net = NULL; 892 905 } else { 893 - net->destid_table.start = start; 894 - net->destid_table.max = 895 - RIO_MAX_ROUTE_ENTRIES(port->sys_size); 896 - spin_lock_init(&net->destid_table.lock); 906 + net->enum_data = idtab; 907 + net->release = rio_scan_release_net; 908 + idtab->start = start; 909 + idtab->max = RIO_MAX_ROUTE_ENTRIES(mport->sys_size); 910 + spin_lock_init(&idtab->lock); 897 911 } 898 912 } 899 913 900 914 if (net) { 901 - INIT_LIST_HEAD(&net->node); 902 - INIT_LIST_HEAD(&net->devices); 903 - INIT_LIST_HEAD(&net->switches); 904 - INIT_LIST_HEAD(&net->mports); 905 - list_add_tail(&port->nnode, &net->mports); 906 - net->hport = port; 907 - net->id = port->id; 915 + net->id = mport->id; 916 + net->hport = mport; 917 + dev_set_name(&net->dev, "rnet_%d", net->id); 918 + net->dev.parent = &mport->dev; 919 + net->dev.release = rio_scan_release_dev; 920 + rio_add_net(net); 908 921 } 922 + 909 923 return net; 910 924 } 911 925 ··· 1035 1007 1036 1008 /* If master port has an active link, allocate net and enum peers */ 1037 1009 if (rio_mport_is_active(mport)) { 1038 - net = rio_alloc_net(mport, 1, 0); 1010 + net = rio_scan_alloc_net(mport, 1, 0); 1039 1011 if (!net) { 1040 1012 printk(KERN_ERR "RIO: failed to allocate new net\n"); 1041 1013 rc = -ENOMEM; ··· 1152 1124 enum_done: 1153 1125 pr_debug("RIO: ... enumeration done\n"); 1154 1126 1155 - net = rio_alloc_net(mport, 0, 0); 1127 + net = rio_scan_alloc_net(mport, 0, 0); 1156 1128 if (!net) { 1157 1129 printk(KERN_ERR "RIO: Failed to allocate new net\n"); 1158 1130 goto bail;
+53
drivers/rapidio/rio.c
··· 42 42 "Destination ID assignment to local RapidIO controllers"); 43 43 44 44 static LIST_HEAD(rio_devices); 45 + static LIST_HEAD(rio_nets); 45 46 static DEFINE_SPINLOCK(rio_global_list_lock); 46 47 47 48 static LIST_HEAD(rio_mports); ··· 84 83 return port->ops->query_mport(port, mport_attr); 85 84 } 86 85 EXPORT_SYMBOL(rio_query_mport); 86 + 87 + /** 88 + * rio_alloc_net- Allocate and initialize a new RIO network data structure 89 + * @mport: Master port associated with the RIO network 90 + * 91 + * Allocates a RIO network structure, initializes per-network 92 + * list heads, and adds the associated master port to the 93 + * network list of associated master ports. Returns a 94 + * RIO network pointer on success or %NULL on failure. 95 + */ 96 + struct rio_net *rio_alloc_net(struct rio_mport *mport) 97 + { 98 + struct rio_net *net; 99 + 100 + net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); 101 + if (net) { 102 + INIT_LIST_HEAD(&net->node); 103 + INIT_LIST_HEAD(&net->devices); 104 + INIT_LIST_HEAD(&net->switches); 105 + INIT_LIST_HEAD(&net->mports); 106 + mport->net = net; 107 + } 108 + return net; 109 + } 110 + EXPORT_SYMBOL_GPL(rio_alloc_net); 111 + 112 + int rio_add_net(struct rio_net *net) 113 + { 114 + int err; 115 + 116 + err = device_register(&net->dev); 117 + if (err) 118 + return err; 119 + spin_lock(&rio_global_list_lock); 120 + list_add_tail(&net->node, &rio_nets); 121 + spin_unlock(&rio_global_list_lock); 122 + 123 + return 0; 124 + } 125 + EXPORT_SYMBOL_GPL(rio_add_net); 126 + 127 + void rio_free_net(struct rio_net *net) 128 + { 129 + spin_lock(&rio_global_list_lock); 130 + if (!list_empty(&net->node)) 131 + list_del(&net->node); 132 + spin_unlock(&rio_global_list_lock); 133 + if (net->release) 134 + net->release(net); 135 + device_unregister(&net->dev); 136 + } 137 + EXPORT_SYMBOL_GPL(rio_free_net); 87 138 88 139 /** 89 140 * rio_add_device- Adds a RIO device to the device model
+3
drivers/rapidio/rio.h
··· 39 39 extern int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock); 40 40 extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); 41 41 extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); 42 + extern struct rio_net *rio_alloc_net(struct rio_mport *mport); 43 + extern int rio_add_net(struct rio_net *net); 44 + extern void rio_free_net(struct rio_net *net); 42 45 extern int rio_add_device(struct rio_dev *rdev); 43 46 extern void rio_del_device(struct rio_dev *rdev); 44 47 extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
+9 -9
include/linux/rio.h
··· 202 202 #define to_rio_dev(n) container_of(n, struct rio_dev, dev) 203 203 #define sw_to_rio_dev(n) container_of(n, struct rio_dev, rswitch[0]) 204 204 #define to_rio_mport(n) container_of(n, struct rio_mport, dev) 205 + #define to_rio_net(n) container_of(n, struct rio_net, dev) 205 206 206 207 /** 207 208 * struct rio_msg - RIO message event ··· 238 237 * @dbells: List of doorbell events 239 238 * @node: Node in global list of master ports 240 239 * @nnode: Node in network list of master ports 240 + * @net: RIO net this mport is attached to 241 241 * @iores: I/O mem resource that this master port interface owns 242 242 * @riores: RIO resources that this master port interfaces owns 243 243 * @inb_msg: RIO inbound message event descriptors ··· 260 258 struct list_head dbells; /* list of doorbell events */ 261 259 struct list_head node; /* node in global list of ports */ 262 260 struct list_head nnode; /* node in net list of ports */ 261 + struct rio_net *net; /* RIO net this mport is attached to */ 263 262 struct resource iores; 264 263 struct resource riores[RIO_MAX_MPORT_RESOURCES]; 265 264 struct rio_msg inb_msg[RIO_MAX_MBOX]; ··· 290 287 */ 291 288 #define RIO_SCAN_ENUM_NO_WAIT 0x00000001 /* Do not wait for enum completed */ 292 289 293 - struct rio_id_table { 294 - u16 start; /* logical minimal id */ 295 - u32 max; /* max number of IDs in table */ 296 - spinlock_t lock; 297 - unsigned long *table; 298 - }; 299 - 300 290 /** 301 291 * struct rio_net - RIO network info 302 292 * @node: Node in global list of RIO networks ··· 298 302 * @mports: List of master ports accessing this network 299 303 * @hport: Default port for accessing this network 300 304 * @id: RIO network ID 301 - * @destid_table: destID allocation table 305 + * @dev: Device object 306 + * @enum_data: private data specific to a network enumerator 307 + * @release: enumerator-specific release callback 302 308 */ 303 309 struct rio_net { 304 310 struct list_head node; /* node in list of networks */ ··· 309 311 struct list_head mports; /* list of ports accessing net */ 310 312 struct rio_mport *hport; /* primary port for accessing net */ 311 313 unsigned char id; /* RIO network ID */ 312 - struct rio_id_table destid_table; /* destID allocation table */ 314 + struct device dev; 315 + void *enum_data; /* private data for enumerator of the network */ 316 + void (*release)(struct rio_net *net); 313 317 }; 314 318 315 319 enum rio_link_speed {