aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/rio-scan.c
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 /drivers/rapidio/rio-scan.c
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>
Diffstat (limited to 'drivers/rapidio/rio-scan.c')
-rw-r--r--drivers/rapidio/rio-scan.c59
1 files changed, 32 insertions, 27 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;