aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2011-01-12 20:00:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 11:03:17 -0500
commitded05782719d0f7e79af98be7cf88c7e23a90435 (patch)
tree5f3fd7ed0d7f9903748b41edefcd3294de81bd5b
parenta93192a5d245a262dc52fa426de5b20467308a77 (diff)
rapidio: integrate rio_switch into rio_dev
Convert RIO switches device structures (rio_dev + rio_switch) into a single allocation unit. This change is based on the fact that RIO switches are using common RIO device objects anyway. Allocating RIO switch objects as RIO devices with added space for switch information simplifies handling of RIO switch devices. Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Cc: Kumar Gala <galak@kernel.crashing.org> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Li Yang <leoli@freescale.com> Cc: Thomas Moll <thomas.moll@sysgo.com> Cc: Micha Nelissen <micha@neli.hopto.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/rapidio/rio-scan.c59
-rw-r--r--drivers/rapidio/rio-sysfs.c4
-rw-r--r--include/linux/rio.h82
3 files changed, 75 insertions, 70 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 51f0af241eb7..45d14cd6b356 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -378,12 +378,30 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
378 struct rio_dev *rdev; 378 struct rio_dev *rdev;
379 struct rio_switch *rswitch = NULL; 379 struct rio_switch *rswitch = NULL;
380 int result, rdid; 380 int result, rdid;
381 size_t size;
382 u32 swpinfo = 0;
381 383
382 rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL); 384 size = sizeof(struct rio_dev);
385 if (rio_mport_read_config_32(port, destid, hopcount,
386 RIO_PEF_CAR, &result))
387 return NULL;
388
389 if (result & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) {
390 rio_mport_read_config_32(port, destid, hopcount,
391 RIO_SWP_INFO_CAR, &swpinfo);
392 if (result & RIO_PEF_SWITCH) {
393 size += (RIO_GET_TOTAL_PORTS(swpinfo) *
394 sizeof(rswitch->nextdev[0])) + sizeof(*rswitch);
395 }
396 }
397
398 rdev = kzalloc(size, GFP_KERNEL);
383 if (!rdev) 399 if (!rdev)
384 return NULL; 400 return NULL;
385 401
386 rdev->net = net; 402 rdev->net = net;
403 rdev->pef = result;
404 rdev->swpinfo = swpinfo;
387 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR, 405 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
388 &result); 406 &result);
389 rdev->did = result >> 16; 407 rdev->did = result >> 16;
@@ -397,8 +415,6 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
397 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR, 415 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
398 &result); 416 &result);
399 rdev->asm_rev = result >> 16; 417 rdev->asm_rev = result >> 16;
400 rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
401 &rdev->pef);
402 if (rdev->pef & RIO_PEF_EXT_FEATURES) { 418 if (rdev->pef & RIO_PEF_EXT_FEATURES) {
403 rdev->efptr = result & 0xffff; 419 rdev->efptr = result & 0xffff;
404 rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid, 420 rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid,
@@ -408,11 +424,6 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
408 hopcount, RIO_EFB_ERR_MGMNT); 424 hopcount, RIO_EFB_ERR_MGMNT);
409 } 425 }
410 426
411 if (rdev->pef & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) {
412 rio_mport_read_config_32(port, destid, hopcount,
413 RIO_SWP_INFO_CAR, &rdev->swpinfo);
414 }
415
416 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, 427 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
417 &rdev->src_ops); 428 &rdev->src_ops);
418 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, 429 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
@@ -449,12 +460,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
449 460
450 /* If a PE has both switch and other functions, show it as a switch */ 461 /* If a PE has both switch and other functions, show it as a switch */
451 if (rio_is_switch(rdev)) { 462 if (rio_is_switch(rdev)) {
452 rswitch = kzalloc(sizeof(*rswitch) + 463 rswitch = rdev->rswitch;
453 RIO_GET_TOTAL_PORTS(rdev->swpinfo) *
454 sizeof(rswitch->nextdev[0]),
455 GFP_KERNEL);
456 if (!rswitch)
457 goto cleanup;
458 rswitch->switchid = next_switchid; 464 rswitch->switchid = next_switchid;
459 rswitch->port_ok = 0; 465 rswitch->port_ok = 0;
460 rswitch->route_table = kzalloc(sizeof(u8)* 466 rswitch->route_table = kzalloc(sizeof(u8)*
@@ -466,15 +472,13 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
466 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size); 472 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
467 rdid++) 473 rdid++)
468 rswitch->route_table[rdid] = RIO_INVALID_ROUTE; 474 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
469 rdev->rswitch = rswitch;
470 rswitch->rdev = rdev;
471 dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, 475 dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
472 rdev->rswitch->switchid); 476 rswitch->switchid);
473 rio_switch_init(rdev, do_enum); 477 rio_switch_init(rdev, do_enum);
474 478
475 if (do_enum && rdev->rswitch->clr_table) 479 if (do_enum && rswitch->clr_table)
476 rdev->rswitch->clr_table(port, destid, hopcount, 480 rswitch->clr_table(port, destid, hopcount,
477 RIO_GLOBAL_TABLE); 481 RIO_GLOBAL_TABLE);
478 482
479 list_add_tail(&rswitch->node, &rio_switches); 483 list_add_tail(&rswitch->node, &rio_switches);
480 484
@@ -510,10 +514,9 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
510 return rdev; 514 return rdev;
511 515
512cleanup: 516cleanup:
513 if (rswitch) { 517 if (rswitch->route_table)
514 kfree(rswitch->route_table); 518 kfree(rswitch->route_table);
515 kfree(rswitch); 519
516 }
517 kfree(rdev); 520 kfree(rdev);
518 return NULL; 521 return NULL;
519} 522}
@@ -1072,7 +1075,7 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
1072 */ 1075 */
1073static void rio_update_route_tables(struct rio_mport *port) 1076static void rio_update_route_tables(struct rio_mport *port)
1074{ 1077{
1075 struct rio_dev *rdev; 1078 struct rio_dev *rdev, *swrdev;
1076 struct rio_switch *rswitch; 1079 struct rio_switch *rswitch;
1077 u8 sport; 1080 u8 sport;
1078 u16 destid; 1081 u16 destid;
@@ -1087,14 +1090,16 @@ static void rio_update_route_tables(struct rio_mport *port)
1087 continue; 1090 continue;
1088 1091
1089 if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) { 1092 if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {
1093 swrdev = sw_to_rio_dev(rswitch);
1094
1090 /* Skip if destid ends in empty switch*/ 1095 /* Skip if destid ends in empty switch*/
1091 if (rswitch->rdev->destid == destid) 1096 if (swrdev->destid == destid)
1092 continue; 1097 continue;
1093 1098
1094 sport = RIO_GET_PORT_NUM(rswitch->rdev->swpinfo); 1099 sport = RIO_GET_PORT_NUM(swrdev->swpinfo);
1095 1100
1096 if (rswitch->add_entry) { 1101 if (rswitch->add_entry) {
1097 rio_route_add_entry(rswitch->rdev, 1102 rio_route_add_entry(swrdev,
1098 RIO_GLOBAL_TABLE, destid, 1103 RIO_GLOBAL_TABLE, destid,
1099 sport, 0); 1104 sport, 0);
1100 rswitch->route_table[destid] = sport; 1105 rswitch->route_table[destid] = sport;
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 137ed93ee33f..76b41853a877 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -217,7 +217,7 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
217 217
218 err = device_create_bin_file(&rdev->dev, &rio_config_attr); 218 err = device_create_bin_file(&rdev->dev, &rio_config_attr);
219 219
220 if (!err && rdev->rswitch) { 220 if (!err && (rdev->pef & RIO_PEF_SWITCH)) {
221 err = device_create_file(&rdev->dev, &dev_attr_routes); 221 err = device_create_file(&rdev->dev, &dev_attr_routes);
222 if (!err && rdev->rswitch->sw_sysfs) 222 if (!err && rdev->rswitch->sw_sysfs)
223 err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); 223 err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE);
@@ -239,7 +239,7 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev)
239void rio_remove_sysfs_dev_files(struct rio_dev *rdev) 239void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
240{ 240{
241 device_remove_bin_file(&rdev->dev, &rio_config_attr); 241 device_remove_bin_file(&rdev->dev, &rio_config_attr);
242 if (rdev->rswitch) { 242 if (rdev->pef & RIO_PEF_SWITCH) {
243 device_remove_file(&rdev->dev, &dev_attr_routes); 243 device_remove_file(&rdev->dev, &dev_attr_routes);
244 if (rdev->rswitch->sw_sysfs) 244 if (rdev->rswitch->sw_sysfs)
245 rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); 245 rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index f6e25b3a6967..9b558856a8b6 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -71,9 +71,47 @@ extern struct device rio_bus;
71extern struct list_head rio_devices; /* list of all devices */ 71extern struct list_head rio_devices; /* list of all devices */
72 72
73struct rio_mport; 73struct rio_mport;
74struct rio_dev;
74union rio_pw_msg; 75union rio_pw_msg;
75 76
76/** 77/**
78 * struct rio_switch - RIO switch info
79 * @node: Node in global list of switches
80 * @switchid: Switch ID that is unique across a network
81 * @route_table: Copy of switch routing table
82 * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0
83 * @add_entry: Callback for switch-specific route add function
84 * @get_entry: Callback for switch-specific route get function
85 * @clr_table: Callback for switch-specific clear route table function
86 * @set_domain: Callback for switch-specific domain setting function
87 * @get_domain: Callback for switch-specific domain get function
88 * @em_init: Callback for switch-specific error management init function
89 * @em_handle: Callback for switch-specific error management handler function
90 * @sw_sysfs: Callback that initializes switch-specific sysfs attributes
91 * @nextdev: Array of per-port pointers to the next attached device
92 */
93struct rio_switch {
94 struct list_head node;
95 u16 switchid;
96 u8 *route_table;
97 u32 port_ok;
98 int (*add_entry) (struct rio_mport *mport, u16 destid, u8 hopcount,
99 u16 table, u16 route_destid, u8 route_port);
100 int (*get_entry) (struct rio_mport *mport, u16 destid, u8 hopcount,
101 u16 table, u16 route_destid, u8 *route_port);
102 int (*clr_table) (struct rio_mport *mport, u16 destid, u8 hopcount,
103 u16 table);
104 int (*set_domain) (struct rio_mport *mport, u16 destid, u8 hopcount,
105 u8 sw_domain);
106 int (*get_domain) (struct rio_mport *mport, u16 destid, u8 hopcount,
107 u8 *sw_domain);
108 int (*em_init) (struct rio_dev *dev);
109 int (*em_handle) (struct rio_dev *dev, u8 swport);
110 int (*sw_sysfs) (struct rio_dev *dev, int create);
111 struct rio_dev *nextdev[0];
112};
113
114/**
77 * struct rio_dev - RIO device info 115 * struct rio_dev - RIO device info
78 * @global_list: Node in list of all RIO devices 116 * @global_list: Node in list of all RIO devices
79 * @net_list: Node in list of RIO devices in a network 117 * @net_list: Node in list of RIO devices in a network
@@ -93,7 +131,6 @@ union rio_pw_msg;
93 * @phys_efptr: RIO device extended features pointer 131 * @phys_efptr: RIO device extended features pointer
94 * @em_efptr: RIO Error Management features pointer 132 * @em_efptr: RIO Error Management features pointer
95 * @dma_mask: Mask of bits of RIO address this device implements 133 * @dma_mask: Mask of bits of RIO address this device implements
96 * @rswitch: Pointer to &struct rio_switch if valid for this device
97 * @driver: Driver claiming this device 134 * @driver: Driver claiming this device
98 * @dev: Device model device 135 * @dev: Device model device
99 * @riores: RIO resources this device owns 136 * @riores: RIO resources this device owns
@@ -101,6 +138,7 @@ union rio_pw_msg;
101 * @destid: Network destination ID (or associated destid for switch) 138 * @destid: Network destination ID (or associated destid for switch)
102 * @hopcount: Hopcount to this device 139 * @hopcount: Hopcount to this device
103 * @prev: Previous RIO device connected to the current one 140 * @prev: Previous RIO device connected to the current one
141 * @rswitch: struct rio_switch (if valid for this device)
104 */ 142 */
105struct rio_dev { 143struct rio_dev {
106 struct list_head global_list; /* node in list of all RIO devices */ 144 struct list_head global_list; /* node in list of all RIO devices */
@@ -121,7 +159,6 @@ struct rio_dev {
121 u32 phys_efptr; 159 u32 phys_efptr;
122 u32 em_efptr; 160 u32 em_efptr;
123 u64 dma_mask; 161 u64 dma_mask;
124 struct rio_switch *rswitch; /* RIO switch info */
125 struct rio_driver *driver; /* RIO driver claiming this device */ 162 struct rio_driver *driver; /* RIO driver claiming this device */
126 struct device dev; /* LDM device structure */ 163 struct device dev; /* LDM device structure */
127 struct resource riores[RIO_MAX_DEV_RESOURCES]; 164 struct resource riores[RIO_MAX_DEV_RESOURCES];
@@ -129,11 +166,13 @@ struct rio_dev {
129 u16 destid; 166 u16 destid;
130 u8 hopcount; 167 u8 hopcount;
131 struct rio_dev *prev; 168 struct rio_dev *prev;
169 struct rio_switch rswitch[0]; /* RIO switch info */
132}; 170};
133 171
134#define rio_dev_g(n) list_entry(n, struct rio_dev, global_list) 172#define rio_dev_g(n) list_entry(n, struct rio_dev, global_list)
135#define rio_dev_f(n) list_entry(n, struct rio_dev, net_list) 173#define rio_dev_f(n) list_entry(n, struct rio_dev, net_list)
136#define to_rio_dev(n) container_of(n, struct rio_dev, dev) 174#define to_rio_dev(n) container_of(n, struct rio_dev, dev)
175#define sw_to_rio_dev(n) container_of(n, struct rio_dev, rswitch[0])
137 176
138/** 177/**
139 * struct rio_msg - RIO message event 178 * struct rio_msg - RIO message event
@@ -226,45 +265,6 @@ struct rio_net {
226#define RIO_SW_SYSFS_CREATE 1 /* Create switch attributes */ 265#define RIO_SW_SYSFS_CREATE 1 /* Create switch attributes */
227#define RIO_SW_SYSFS_REMOVE 0 /* Remove switch attributes */ 266#define RIO_SW_SYSFS_REMOVE 0 /* Remove switch attributes */
228 267
229/**
230 * struct rio_switch - RIO switch info
231 * @node: Node in global list of switches
232 * @rdev: Associated RIO device structure
233 * @switchid: Switch ID that is unique across a network
234 * @route_table: Copy of switch routing table
235 * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0
236 * @add_entry: Callback for switch-specific route add function
237 * @get_entry: Callback for switch-specific route get function
238 * @clr_table: Callback for switch-specific clear route table function
239 * @set_domain: Callback for switch-specific domain setting function
240 * @get_domain: Callback for switch-specific domain get function
241 * @em_init: Callback for switch-specific error management initialization function
242 * @em_handle: Callback for switch-specific error management handler function
243 * @sw_sysfs: Callback that initializes switch-specific sysfs attributes
244 * @nextdev: Array of per-port pointers to the next attached device
245 */
246struct rio_switch {
247 struct list_head node;
248 struct rio_dev *rdev;
249 u16 switchid;
250 u8 *route_table;
251 u32 port_ok;
252 int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
253 u16 table, u16 route_destid, u8 route_port);
254 int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
255 u16 table, u16 route_destid, u8 * route_port);
256 int (*clr_table) (struct rio_mport *mport, u16 destid, u8 hopcount,
257 u16 table);
258 int (*set_domain) (struct rio_mport *mport, u16 destid, u8 hopcount,
259 u8 sw_domain);
260 int (*get_domain) (struct rio_mport *mport, u16 destid, u8 hopcount,
261 u8 *sw_domain);
262 int (*em_init) (struct rio_dev *dev);
263 int (*em_handle) (struct rio_dev *dev, u8 swport);
264 int (*sw_sysfs) (struct rio_dev *dev, int create);
265 struct rio_dev *nextdev[0];
266};
267
268/* Low-level architecture-dependent routines */ 268/* Low-level architecture-dependent routines */
269 269
270/** 270/**