aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/rio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rapidio/rio.c')
-rw-r--r--drivers/rapidio/rio.c246
1 files changed, 239 insertions, 7 deletions
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d553b5d13722..cb1c08996fbb 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -31,7 +31,11 @@
31 31
32#include "rio.h" 32#include "rio.h"
33 33
34static LIST_HEAD(rio_devices);
35static DEFINE_SPINLOCK(rio_global_list_lock);
36
34static LIST_HEAD(rio_mports); 37static LIST_HEAD(rio_mports);
38static DEFINE_MUTEX(rio_mport_list_lock);
35static unsigned char next_portid; 39static unsigned char next_portid;
36static DEFINE_SPINLOCK(rio_mmap_lock); 40static DEFINE_SPINLOCK(rio_mmap_lock);
37 41
@@ -53,6 +57,32 @@ u16 rio_local_get_device_id(struct rio_mport *port)
53} 57}
54 58
55/** 59/**
60 * rio_add_device- Adds a RIO device to the device model
61 * @rdev: RIO device
62 *
63 * Adds the RIO device to the global device list and adds the RIO
64 * device to the RIO device list. Creates the generic sysfs nodes
65 * for an RIO device.
66 */
67int rio_add_device(struct rio_dev *rdev)
68{
69 int err;
70
71 err = device_add(&rdev->dev);
72 if (err)
73 return err;
74
75 spin_lock(&rio_global_list_lock);
76 list_add_tail(&rdev->global_list, &rio_devices);
77 spin_unlock(&rio_global_list_lock);
78
79 rio_create_sysfs_dev_files(rdev);
80
81 return 0;
82}
83EXPORT_SYMBOL_GPL(rio_add_device);
84
85/**
56 * rio_request_inb_mbox - request inbound mailbox service 86 * rio_request_inb_mbox - request inbound mailbox service
57 * @mport: RIO master port from which to allocate the mailbox resource 87 * @mport: RIO master port from which to allocate the mailbox resource
58 * @dev_id: Device specific pointer to pass on event 88 * @dev_id: Device specific pointer to pass on event
@@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local,
489 519
490 return ext_ftr_ptr; 520 return ext_ftr_ptr;
491} 521}
522EXPORT_SYMBOL_GPL(rio_mport_get_physefb);
492 523
493/** 524/**
494 * rio_get_comptag - Begin or continue searching for a RIO device by component tag 525 * rio_get_comptag - Begin or continue searching for a RIO device by component tag
@@ -521,6 +552,7 @@ exit:
521 spin_unlock(&rio_global_list_lock); 552 spin_unlock(&rio_global_list_lock);
522 return rdev; 553 return rdev;
523} 554}
555EXPORT_SYMBOL_GPL(rio_get_comptag);
524 556
525/** 557/**
526 * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. 558 * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port.
@@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
545 regval); 577 regval);
546 return 0; 578 return 0;
547} 579}
580EXPORT_SYMBOL_GPL(rio_set_port_lockout);
581
582/**
583 * rio_switch_init - Sets switch operations for a particular vendor switch
584 * @rdev: RIO device
585 * @do_enum: Enumeration/Discovery mode flag
586 *
587 * Searches the RIO switch ops table for known switch types. If the vid
588 * and did match a switch table entry, then call switch initialization
589 * routine to setup switch-specific routines.
590 */
591void rio_switch_init(struct rio_dev *rdev, int do_enum)
592{
593 struct rio_switch_ops *cur = __start_rio_switch_ops;
594 struct rio_switch_ops *end = __end_rio_switch_ops;
595
596 while (cur < end) {
597 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
598 pr_debug("RIO: calling init routine for %s\n",
599 rio_name(rdev));
600 cur->init_hook(rdev, do_enum);
601 break;
602 }
603 cur++;
604 }
605
606 if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
607 pr_debug("RIO: adding STD routing ops for %s\n",
608 rio_name(rdev));
609 rdev->rswitch->add_entry = rio_std_route_add_entry;
610 rdev->rswitch->get_entry = rio_std_route_get_entry;
611 rdev->rswitch->clr_table = rio_std_route_clr_table;
612 }
613
614 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
615 printk(KERN_ERR "RIO: missing routing ops for %s\n",
616 rio_name(rdev));
617}
618EXPORT_SYMBOL_GPL(rio_switch_init);
619
620/**
621 * rio_enable_rx_tx_port - enable input receiver and output transmitter of
622 * given port
623 * @port: Master port associated with the RIO network
624 * @local: local=1 select local port otherwise a far device is reached
625 * @destid: Destination ID of the device to check host bit
626 * @hopcount: Number of hops to reach the target
627 * @port_num: Port (-number on switch) to enable on a far end device
628 *
629 * Returns 0 or 1 from on General Control Command and Status Register
630 * (EXT_PTR+0x3C)
631 */
632int rio_enable_rx_tx_port(struct rio_mport *port,
633 int local, u16 destid,
634 u8 hopcount, u8 port_num)
635{
636#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
637 u32 regval;
638 u32 ext_ftr_ptr;
639
640 /*
641 * enable rx input tx output port
642 */
643 pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
644 "%d, port_num = %d)\n", local, destid, hopcount, port_num);
645
646 ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
647
648 if (local) {
649 rio_local_read_config_32(port, ext_ftr_ptr +
650 RIO_PORT_N_CTL_CSR(0),
651 &regval);
652 } else {
653 if (rio_mport_read_config_32(port, destid, hopcount,
654 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
655 return -EIO;
656 }
657
658 if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
659 /* serial */
660 regval = regval | RIO_PORT_N_CTL_EN_RX_SER
661 | RIO_PORT_N_CTL_EN_TX_SER;
662 } else {
663 /* parallel */
664 regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
665 | RIO_PORT_N_CTL_EN_TX_PAR;
666 }
667
668 if (local) {
669 rio_local_write_config_32(port, ext_ftr_ptr +
670 RIO_PORT_N_CTL_CSR(0), regval);
671 } else {
672 if (rio_mport_write_config_32(port, destid, hopcount,
673 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
674 return -EIO;
675 }
676#endif
677 return 0;
678}
679EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port);
680
548 681
549/** 682/**
550 * rio_chk_dev_route - Validate route to the specified device. 683 * rio_chk_dev_route - Validate route to the specified device.
@@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
610 743
611 return 0; 744 return 0;
612} 745}
746EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access);
613 747
614/** 748/**
615 * rio_chk_dev_access - Validate access to the specified device. 749 * rio_chk_dev_access - Validate access to the specified device.
@@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
941 return RIO_GET_BLOCK_ID(reg_val); 1075 return RIO_GET_BLOCK_ID(reg_val);
942 } 1076 }
943} 1077}
1078EXPORT_SYMBOL_GPL(rio_mport_get_efb);
944 1079
945/** 1080/**
946 * rio_mport_get_feature - query for devices' extended features 1081 * rio_mport_get_feature - query for devices' extended features
@@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
997 1132
998 return 0; 1133 return 0;
999} 1134}
1135EXPORT_SYMBOL_GPL(rio_mport_get_feature);
1000 1136
1001/** 1137/**
1002 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did 1138 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
@@ -1246,6 +1382,95 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
1246 1382
1247#endif /* CONFIG_RAPIDIO_DMA_ENGINE */ 1383#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
1248 1384
1385/**
1386 * rio_find_mport - find RIO mport by its ID
1387 * @mport_id: number (ID) of mport device
1388 *
1389 * Given a RIO mport number, the desired mport is located
1390 * in the global list of mports. If the mport is found, a pointer to its
1391 * data structure is returned. If no mport is found, %NULL is returned.
1392 */
1393struct rio_mport *rio_find_mport(int mport_id)
1394{
1395 struct rio_mport *port;
1396
1397 mutex_lock(&rio_mport_list_lock);
1398 list_for_each_entry(port, &rio_mports, node) {
1399 if (port->id == mport_id)
1400 goto found;
1401 }
1402 port = NULL;
1403found:
1404 mutex_unlock(&rio_mport_list_lock);
1405
1406 return port;
1407}
1408
1409/**
1410 * rio_register_scan - enumeration/discovery method registration interface
1411 * @mport_id: mport device ID for which fabric scan routine has to be set
1412 * (RIO_MPORT_ANY = set for all available mports)
1413 * @scan_ops: enumeration/discovery control structure
1414 *
1415 * Assigns enumeration or discovery method to the specified mport device (or all
1416 * available mports if RIO_MPORT_ANY is specified).
1417 * Returns error if the mport already has an enumerator attached to it.
1418 * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
1419 * an error if was unable to find at least one available mport.
1420 */
1421int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
1422{
1423 struct rio_mport *port;
1424 int rc = -EBUSY;
1425
1426 mutex_lock(&rio_mport_list_lock);
1427 list_for_each_entry(port, &rio_mports, node) {
1428 if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
1429 if (port->nscan && mport_id == RIO_MPORT_ANY)
1430 continue;
1431 else if (port->nscan)
1432 break;
1433
1434 port->nscan = scan_ops;
1435 rc = 0;
1436
1437 if (mport_id != RIO_MPORT_ANY)
1438 break;
1439 }
1440 }
1441 mutex_unlock(&rio_mport_list_lock);
1442
1443 return rc;
1444}
1445EXPORT_SYMBOL_GPL(rio_register_scan);
1446
1447/**
1448 * rio_unregister_scan - removes enumeration/discovery method from mport
1449 * @mport_id: mport device ID for which fabric scan routine has to be
1450 * unregistered (RIO_MPORT_ANY = set for all available mports)
1451 *
1452 * Removes enumeration or discovery method assigned to the specified mport
1453 * device (or all available mports if RIO_MPORT_ANY is specified).
1454 */
1455int rio_unregister_scan(int mport_id)
1456{
1457 struct rio_mport *port;
1458
1459 mutex_lock(&rio_mport_list_lock);
1460 list_for_each_entry(port, &rio_mports, node) {
1461 if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
1462 if (port->nscan)
1463 port->nscan = NULL;
1464 if (mport_id != RIO_MPORT_ANY)
1465 break;
1466 }
1467 }
1468 mutex_unlock(&rio_mport_list_lock);
1469
1470 return 0;
1471}
1472EXPORT_SYMBOL_GPL(rio_unregister_scan);
1473
1249static void rio_fixup_device(struct rio_dev *dev) 1474static void rio_fixup_device(struct rio_dev *dev)
1250{ 1475{
1251} 1476}
@@ -1274,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work)
1274 work = container_of(_work, struct rio_disc_work, work); 1499 work = container_of(_work, struct rio_disc_work, work);
1275 pr_debug("RIO: discovery work for mport %d %s\n", 1500 pr_debug("RIO: discovery work for mport %d %s\n",
1276 work->mport->id, work->mport->name); 1501 work->mport->id, work->mport->name);
1277 rio_disc_mport(work->mport); 1502 work->mport->nscan->discover(work->mport, 0);
1278} 1503}
1279 1504
1280int rio_init_mports(void) 1505int rio_init_mports(void)
@@ -1290,12 +1515,15 @@ int rio_init_mports(void)
1290 * First, run enumerations and check if we need to perform discovery 1515 * First, run enumerations and check if we need to perform discovery
1291 * on any of the registered mports. 1516 * on any of the registered mports.
1292 */ 1517 */
1518 mutex_lock(&rio_mport_list_lock);
1293 list_for_each_entry(port, &rio_mports, node) { 1519 list_for_each_entry(port, &rio_mports, node) {
1294 if (port->host_deviceid >= 0) 1520 if (port->host_deviceid >= 0) {
1295 rio_enum_mport(port); 1521 if (port->nscan)
1296 else 1522 port->nscan->enumerate(port, 0);
1523 } else
1297 n++; 1524 n++;
1298 } 1525 }
1526 mutex_unlock(&rio_mport_list_lock);
1299 1527
1300 if (!n) 1528 if (!n)
1301 goto no_disc; 1529 goto no_disc;
@@ -1322,14 +1550,16 @@ int rio_init_mports(void)
1322 } 1550 }
1323 1551
1324 n = 0; 1552 n = 0;
1553 mutex_lock(&rio_mport_list_lock);
1325 list_for_each_entry(port, &rio_mports, node) { 1554 list_for_each_entry(port, &rio_mports, node) {
1326 if (port->host_deviceid < 0) { 1555 if (port->host_deviceid < 0 && port->nscan) {
1327 work[n].mport = port; 1556 work[n].mport = port;
1328 INIT_WORK(&work[n].work, disc_work_handler); 1557 INIT_WORK(&work[n].work, disc_work_handler);
1329 queue_work(rio_wq, &work[n].work); 1558 queue_work(rio_wq, &work[n].work);
1330 n++; 1559 n++;
1331 } 1560 }
1332 } 1561 }
1562 mutex_unlock(&rio_mport_list_lock);
1333 1563
1334 flush_workqueue(rio_wq); 1564 flush_workqueue(rio_wq);
1335 pr_debug("RIO: destroy discovery workqueue\n"); 1565 pr_debug("RIO: destroy discovery workqueue\n");
@@ -1342,8 +1572,6 @@ no_disc:
1342 return 0; 1572 return 0;
1343} 1573}
1344 1574
1345device_initcall_sync(rio_init_mports);
1346
1347static int hdids[RIO_MAX_MPORTS + 1]; 1575static int hdids[RIO_MAX_MPORTS + 1];
1348 1576
1349static int rio_get_hdid(int index) 1577static int rio_get_hdid(int index)
@@ -1371,7 +1599,10 @@ int rio_register_mport(struct rio_mport *port)
1371 1599
1372 port->id = next_portid++; 1600 port->id = next_portid++;
1373 port->host_deviceid = rio_get_hdid(port->id); 1601 port->host_deviceid = rio_get_hdid(port->id);
1602 port->nscan = NULL;
1603 mutex_lock(&rio_mport_list_lock);
1374 list_add_tail(&port->node, &rio_mports); 1604 list_add_tail(&port->node, &rio_mports);
1605 mutex_unlock(&rio_mport_list_lock);
1375 return 0; 1606 return 0;
1376} 1607}
1377 1608
@@ -1386,3 +1617,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
1386EXPORT_SYMBOL_GPL(rio_release_inb_mbox); 1617EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
1387EXPORT_SYMBOL_GPL(rio_request_outb_mbox); 1618EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
1388EXPORT_SYMBOL_GPL(rio_release_outb_mbox); 1619EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
1620EXPORT_SYMBOL_GPL(rio_init_mports);