rio-scan.c (e274e0ed0a2ac31d5eaf7c891e4e1d99197517b2) | rio-scan.c (af84ca38aff94061dd0711edbb99b0900a9c28fd) |
---|---|
1/* 2 * RapidIO enumeration and discovery support 3 * 4 * Copyright 2005 MontaVista Software, Inc. 5 * Matt Porter <mporter@kernel.crashing.org> 6 * 7 * Copyright 2009 Integrated Device Technology, Inc. 8 * Alex Bounine <alexandre.bounine@idt.com> --- 34 unchanged lines hidden (view full) --- 43 44static void rio_init_em(struct rio_dev *rdev); 45 46DEFINE_SPINLOCK(rio_global_list_lock); 47 48static int next_destid = 0; 49static int next_switchid = 0; 50static int next_net = 0; | 1/* 2 * RapidIO enumeration and discovery support 3 * 4 * Copyright 2005 MontaVista Software, Inc. 5 * Matt Porter <mporter@kernel.crashing.org> 6 * 7 * Copyright 2009 Integrated Device Technology, Inc. 8 * Alex Bounine <alexandre.bounine@idt.com> --- 34 unchanged lines hidden (view full) --- 43 44static void rio_init_em(struct rio_dev *rdev); 45 46DEFINE_SPINLOCK(rio_global_list_lock); 47 48static int next_destid = 0; 49static int next_switchid = 0; 50static int next_net = 0; |
51static int next_comptag; | 51static int next_comptag = 1; |
52 53static struct timer_list rio_enum_timer = 54TIMER_INITIALIZER(rio_enum_timeout, 0, 0); 55 56static int rio_mport_phys_table[] = { 57 RIO_EFB_PAR_EP_ID, 58 RIO_EFB_PAR_EP_REC_ID, 59 RIO_EFB_SER_EP_ID, --- 56 unchanged lines hidden (view full) --- 116 * each device. Returns 0 on success or %-EINVAL on failure. 117 */ 118static int rio_clear_locks(struct rio_mport *port) 119{ 120 struct rio_dev *rdev; 121 u32 result; 122 int ret = 0; 123 | 52 53static struct timer_list rio_enum_timer = 54TIMER_INITIALIZER(rio_enum_timeout, 0, 0); 55 56static int rio_mport_phys_table[] = { 57 RIO_EFB_PAR_EP_ID, 58 RIO_EFB_PAR_EP_REC_ID, 59 RIO_EFB_SER_EP_ID, --- 56 unchanged lines hidden (view full) --- 116 * each device. Returns 0 on success or %-EINVAL on failure. 117 */ 118static int rio_clear_locks(struct rio_mport *port) 119{ 120 struct rio_dev *rdev; 121 u32 result; 122 int ret = 0; 123 |
124 /* Assign component tag to all devices */ 125 next_comptag = 1; 126 rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, next_comptag++); 127 128 list_for_each_entry(rdev, &rio_devices, global_list) { 129 /* Mark device as discovered */ 130 rio_read_config_32(rdev, 131 rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, 132 &result); 133 rio_write_config_32(rdev, 134 rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, 135 result | RIO_PORT_GEN_DISCOVERED); 136 137 rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, next_comptag); 138 rdev->comp_tag = next_comptag++; 139 if (next_comptag >= 0x10000) { 140 pr_err("RIO: Component Tag Counter Overflow\n"); 141 break; 142 } 143 } 144 | |
145 /* Release host device id locks */ 146 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR, 147 port->host_deviceid); 148 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result); 149 if ((result & 0xffff) != 0xffff) { 150 printk(KERN_INFO 151 "RIO: badness when releasing host lock on master port, result %8.8x\n", 152 result); --- 4 unchanged lines hidden (view full) --- 157 port->host_deviceid); 158 rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result); 159 if ((result & 0xffff) != 0xffff) { 160 printk(KERN_INFO 161 "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n", 162 rdev->vid, rdev->did); 163 ret = -EINVAL; 164 } | 124 /* Release host device id locks */ 125 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR, 126 port->host_deviceid); 127 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result); 128 if ((result & 0xffff) != 0xffff) { 129 printk(KERN_INFO 130 "RIO: badness when releasing host lock on master port, result %8.8x\n", 131 result); --- 4 unchanged lines hidden (view full) --- 136 port->host_deviceid); 137 rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result); 138 if ((result & 0xffff) != 0xffff) { 139 printk(KERN_INFO 140 "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n", 141 rdev->vid, rdev->did); 142 ret = -EINVAL; 143 } |
144 145 /* Mark device as discovered and enable master */ 146 rio_read_config_32(rdev, 147 rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, 148 &result); 149 result |= RIO_PORT_GEN_DISCOVERED | RIO_PORT_GEN_MASTER; 150 rio_write_config_32(rdev, 151 rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, 152 result); |
|
165 } 166 167 return ret; 168} 169 170/** 171 * rio_enum_host- Set host lock and initialize host destination ID 172 * @port: Master port to issue transaction --- 252 unchanged lines hidden (view full) --- 425 RIO_SWP_INFO_CAR, &rdev->swpinfo); 426 } 427 428 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, 429 &rdev->src_ops); 430 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, 431 &rdev->dst_ops); 432 | 153 } 154 155 return ret; 156} 157 158/** 159 * rio_enum_host- Set host lock and initialize host destination ID 160 * @port: Master port to issue transaction --- 252 unchanged lines hidden (view full) --- 413 RIO_SWP_INFO_CAR, &rdev->swpinfo); 414 } 415 416 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, 417 &rdev->src_ops); 418 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, 419 &rdev->dst_ops); 420 |
421 if (do_enum) { 422 /* Assign component tag to device */ 423 if (next_comptag >= 0x10000) { 424 pr_err("RIO: Component Tag Counter Overflow\n"); 425 goto cleanup; 426 } 427 rio_mport_write_config_32(port, destid, hopcount, 428 RIO_COMPONENT_TAG_CSR, next_comptag); 429 rdev->comp_tag = next_comptag++; 430 } 431 |
|
433 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { 434 if (do_enum) { 435 rio_set_device_id(port, destid, hopcount, next_destid); 436 rdev->destid = next_destid++; 437 if (next_destid == port->host_deviceid) 438 next_destid++; 439 } else 440 rdev->destid = rio_get_device_id(port, destid, hopcount); --- 280 unchanged lines hidden (view full) --- 721 722 rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount, 723 RIO_HOST_DID_LOCK_CSR, &result); 724 725 return (u16) (result & 0xffff); 726} 727 728/** | 432 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { 433 if (do_enum) { 434 rio_set_device_id(port, destid, hopcount, next_destid); 435 rdev->destid = next_destid++; 436 if (next_destid == port->host_deviceid) 437 next_destid++; 438 } else 439 rdev->destid = rio_get_device_id(port, destid, hopcount); --- 280 unchanged lines hidden (view full) --- 720 721 rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount, 722 RIO_HOST_DID_LOCK_CSR, &result); 723 724 return (u16) (result & 0xffff); 725} 726 727/** |
729 * rio_net_add_mport- Add a master port to a RIO network 730 * @net: RIO network 731 * @port: Master port to add 732 * 733 * Adds a master port to the network list of associated master 734 * ports.. 735 */ 736static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port) 737{ 738 spin_lock(&rio_global_list_lock); 739 list_add_tail(&port->nnode, &net->mports); 740 spin_unlock(&rio_global_list_lock); 741} 742 743/** | |
744 * rio_enum_peer- Recursively enumerate a RIO network through a master port 745 * @net: RIO network being enumerated 746 * @port: Master port to send transactions 747 * @hopcount: Number of hops into the network 748 * @prev: Previous RIO device connected to the enumerated one 749 * @prev_port: Port on previous RIO device 750 * 751 * Recursively enumerates a RIO network. Transactions are sent via the 752 * master port passed in @port. 753 */ 754static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, 755 u8 hopcount, struct rio_dev *prev, int prev_port) 756{ 757 int port_num; 758 int cur_destid; 759 int sw_destid; 760 int sw_inport; 761 struct rio_dev *rdev; 762 u16 destid; | 728 * rio_enum_peer- Recursively enumerate a RIO network through a master port 729 * @net: RIO network being enumerated 730 * @port: Master port to send transactions 731 * @hopcount: Number of hops into the network 732 * @prev: Previous RIO device connected to the enumerated one 733 * @prev_port: Port on previous RIO device 734 * 735 * Recursively enumerates a RIO network. Transactions are sent via the 736 * master port passed in @port. 737 */ 738static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, 739 u8 hopcount, struct rio_dev *prev, int prev_port) 740{ 741 int port_num; 742 int cur_destid; 743 int sw_destid; 744 int sw_inport; 745 struct rio_dev *rdev; 746 u16 destid; |
747 u32 regval; |
|
763 int tmp; 764 765 if (rio_mport_chk_dev_access(port, 766 RIO_ANY_DESTID(port->sys_size), hopcount)) { 767 pr_debug("RIO: device access check failed\n"); 768 return -1; 769 } 770 771 if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) { 772 pr_debug("RIO: PE already discovered by this host\n"); 773 /* 774 * Already discovered by this host. Add it as another | 748 int tmp; 749 750 if (rio_mport_chk_dev_access(port, 751 RIO_ANY_DESTID(port->sys_size), hopcount)) { 752 pr_debug("RIO: device access check failed\n"); 753 return -1; 754 } 755 756 if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) { 757 pr_debug("RIO: PE already discovered by this host\n"); 758 /* 759 * Already discovered by this host. Add it as another |
775 * master port for the current network. | 760 * link to the existing device. |
776 */ | 761 */ |
777 rio_net_add_mport(net, port); | 762 rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), 763 hopcount, RIO_COMPONENT_TAG_CSR, ®val); 764 765 if (regval) { 766 rdev = rio_get_comptag((regval & 0xffff), NULL); 767 768 if (rdev && prev && rio_is_switch(prev)) { 769 pr_debug("RIO: redundant path to %s\n", 770 rio_name(rdev)); 771 prev->rswitch->nextdev[prev_port] = rdev; 772 } 773 } 774 |
778 return 0; 779 } 780 781 /* Attempt to acquire device lock */ 782 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size), 783 hopcount, 784 RIO_HOST_DID_LOCK_CSR, port->host_deviceid); 785 while ((tmp = rio_get_host_deviceid_lock(port, hopcount)) --- 134 unchanged lines hidden (view full) --- 920 * @port: Master port to send transaction 921 * 922 * Tests the Component Tag CSR for non-zero value (enumeration 923 * complete flag). Return %1 if enumeration is complete or %0 if 924 * enumeration is incomplete. 925 */ 926static int rio_enum_complete(struct rio_mport *port) 927{ | 775 return 0; 776 } 777 778 /* Attempt to acquire device lock */ 779 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size), 780 hopcount, 781 RIO_HOST_DID_LOCK_CSR, port->host_deviceid); 782 while ((tmp = rio_get_host_deviceid_lock(port, hopcount)) --- 134 unchanged lines hidden (view full) --- 917 * @port: Master port to send transaction 918 * 919 * Tests the Component Tag CSR for non-zero value (enumeration 920 * complete flag). Return %1 if enumeration is complete or %0 if 921 * enumeration is incomplete. 922 */ 923static int rio_enum_complete(struct rio_mport *port) 924{ |
928 u32 tag_csr; | 925 u32 regval; |
929 | 926 |
930 rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr); 931 return (tag_csr & 0xffff) ? 1 : 0; | 927 rio_local_read_config_32(port, port->phys_efptr + RIO_PORT_GEN_CTL_CSR, 928 ®val); 929 return (regval & RIO_PORT_GEN_MASTER) ? 1 : 0; |
932} 933 934/** 935 * rio_disc_peer- Recursively discovers a RIO network through a master port 936 * @net: RIO network being discovered 937 * @port: Master port to send transactions 938 * @destid: Current destination ID in network 939 * @hopcount: Number of hops into the network --- 46 unchanged lines hidden (view full) --- 986 rio_route_get_entry(port, rdev->rswitch, 987 RIO_GLOBAL_TABLE, 988 ndestid, 989 &route_port, 0); 990 if (route_port == port_num) 991 break; 992 } 993 | 930} 931 932/** 933 * rio_disc_peer- Recursively discovers a RIO network through a master port 934 * @net: RIO network being discovered 935 * @port: Master port to send transactions 936 * @destid: Current destination ID in network 937 * @hopcount: Number of hops into the network --- 46 unchanged lines hidden (view full) --- 984 rio_route_get_entry(port, rdev->rswitch, 985 RIO_GLOBAL_TABLE, 986 ndestid, 987 &route_port, 0); 988 if (route_port == port_num) 989 break; 990 } 991 |
992 if (ndestid == RIO_ANY_DESTID(port->sys_size)) 993 continue; |
|
994 rio_unlock_device(port, destid, hopcount); 995 if (rio_disc_peer 996 (net, port, ndestid, hopcount + 1) < 0) 997 return -1; 998 } 999 } 1000 } else 1001 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", --- 156 unchanged lines hidden (view full) --- 1158 printk(KERN_ERR "RIO: failed to allocate new net\n"); 1159 rc = -ENOMEM; 1160 goto out; 1161 } 1162 1163 /* Enable Input Output Port (transmitter reviever) */ 1164 rio_enable_rx_tx_port(mport, 1, 0, 0, 0); 1165 | 994 rio_unlock_device(port, destid, hopcount); 995 if (rio_disc_peer 996 (net, port, ndestid, hopcount + 1) < 0) 997 return -1; 998 } 999 } 1000 } else 1001 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", --- 156 unchanged lines hidden (view full) --- 1158 printk(KERN_ERR "RIO: failed to allocate new net\n"); 1159 rc = -ENOMEM; 1160 goto out; 1161 } 1162 1163 /* Enable Input Output Port (transmitter reviever) */ 1164 rio_enable_rx_tx_port(mport, 1, 0, 0, 0); 1165 |
1166 /* Set component tag for host */ 1167 rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, 1168 next_comptag++); 1169 |
|
1166 if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) { 1167 /* A higher priority host won enumeration, bail. */ 1168 printk(KERN_INFO 1169 "RIO: master port %d device has lost enumeration to a remote host\n", 1170 mport->id); 1171 rio_clear_locks(mport); 1172 rc = -EBUSY; 1173 goto out; --- 126 unchanged lines hidden --- | 1170 if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) { 1171 /* A higher priority host won enumeration, bail. */ 1172 printk(KERN_INFO 1173 "RIO: master port %d device has lost enumeration to a remote host\n", 1174 mport->id); 1175 rio_clear_locks(mport); 1176 rc = -EBUSY; 1177 goto out; --- 126 unchanged lines hidden --- |