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, &regval);
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 &regval);
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 ---