diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rapidio/rio-driver.c | 1 | ||||
-rw-r--r-- | drivers/rapidio/rio-scan.c | 24 | ||||
-rw-r--r-- | drivers/rapidio/rio-sysfs.c | 45 | ||||
-rw-r--r-- | drivers/rapidio/rio.c | 28 | ||||
-rw-r--r-- | drivers/rapidio/rio.h | 2 |
5 files changed, 95 insertions, 5 deletions
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 55850bb21480..a0c875563d76 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c | |||
@@ -207,6 +207,7 @@ struct bus_type rio_bus_type = { | |||
207 | .name = "rapidio", | 207 | .name = "rapidio", |
208 | .match = rio_match_bus, | 208 | .match = rio_match_bus, |
209 | .dev_attrs = rio_dev_attrs, | 209 | .dev_attrs = rio_dev_attrs, |
210 | .bus_attrs = rio_bus_attrs, | ||
210 | .probe = rio_device_probe, | 211 | .probe = rio_device_probe, |
211 | .remove = rio_device_remove, | 212 | .remove = rio_device_remove, |
212 | }; | 213 | }; |
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 7bdc67419cc3..4c15dbf81087 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -1134,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable) | |||
1134 | /** | 1134 | /** |
1135 | * rio_enum_mport- Start enumeration through a master port | 1135 | * rio_enum_mport- Start enumeration through a master port |
1136 | * @mport: Master port to send transactions | 1136 | * @mport: Master port to send transactions |
1137 | * @flags: Enumeration control flags | ||
1137 | * | 1138 | * |
1138 | * Starts the enumeration process. If somebody has enumerated our | 1139 | * Starts the enumeration process. If somebody has enumerated our |
1139 | * master port device, then give up. If not and we have an active | 1140 | * master port device, then give up. If not and we have an active |
1140 | * link, then start recursive peer enumeration. Returns %0 if | 1141 | * link, then start recursive peer enumeration. Returns %0 if |
1141 | * enumeration succeeds or %-EBUSY if enumeration fails. | 1142 | * enumeration succeeds or %-EBUSY if enumeration fails. |
1142 | */ | 1143 | */ |
1143 | int rio_enum_mport(struct rio_mport *mport) | 1144 | int rio_enum_mport(struct rio_mport *mport, u32 flags) |
1144 | { | 1145 | { |
1145 | struct rio_net *net = NULL; | 1146 | struct rio_net *net = NULL; |
1146 | int rc = 0; | 1147 | int rc = 0; |
1147 | 1148 | ||
1148 | printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id, | 1149 | printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id, |
1149 | mport->name); | 1150 | mport->name); |
1151 | |||
1152 | /* | ||
1153 | * To avoid multiple start requests (repeat enumeration is not supported | ||
1154 | * by this method) check if enumeration/discovery was performed for this | ||
1155 | * mport: if mport was added into the list of mports for a net exit | ||
1156 | * with error. | ||
1157 | */ | ||
1158 | if (mport->nnode.next || mport->nnode.prev) | ||
1159 | return -EBUSY; | ||
1160 | |||
1150 | /* If somebody else enumerated our master port device, bail. */ | 1161 | /* If somebody else enumerated our master port device, bail. */ |
1151 | if (rio_enum_host(mport) < 0) { | 1162 | if (rio_enum_host(mport) < 0) { |
1152 | printk(KERN_INFO | 1163 | printk(KERN_INFO |
@@ -1236,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net) | |||
1236 | /** | 1247 | /** |
1237 | * rio_disc_mport- Start discovery through a master port | 1248 | * rio_disc_mport- Start discovery through a master port |
1238 | * @mport: Master port to send transactions | 1249 | * @mport: Master port to send transactions |
1250 | * @flags: discovery control flags | ||
1239 | * | 1251 | * |
1240 | * Starts the discovery process. If we have an active link, | 1252 | * Starts the discovery process. If we have an active link, |
1241 | * then wait for the signal that enumeration is complete. | 1253 | * then wait for the signal that enumeration is complete (if wait |
1254 | * is allowed). | ||
1242 | * When enumeration completion is signaled, start recursive | 1255 | * When enumeration completion is signaled, start recursive |
1243 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY | 1256 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY |
1244 | * on failure. | 1257 | * on failure. |
1245 | */ | 1258 | */ |
1246 | int rio_disc_mport(struct rio_mport *mport) | 1259 | int rio_disc_mport(struct rio_mport *mport, u32 flags) |
1247 | { | 1260 | { |
1248 | struct rio_net *net = NULL; | 1261 | struct rio_net *net = NULL; |
1249 | unsigned long to_end; | 1262 | unsigned long to_end; |
@@ -1253,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport) | |||
1253 | 1266 | ||
1254 | /* If master port has an active link, allocate net and discover peers */ | 1267 | /* If master port has an active link, allocate net and discover peers */ |
1255 | if (rio_mport_is_active(mport)) { | 1268 | if (rio_mport_is_active(mport)) { |
1269 | if (rio_enum_complete(mport)) | ||
1270 | goto enum_done; | ||
1271 | else if (flags & RIO_SCAN_ENUM_NO_WAIT) | ||
1272 | return -EAGAIN; | ||
1273 | |||
1256 | pr_debug("RIO: wait for enumeration to complete...\n"); | 1274 | pr_debug("RIO: wait for enumeration to complete...\n"); |
1257 | 1275 | ||
1258 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; | 1276 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; |
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 4dbe360989be..66d4acd5e18f 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c | |||
@@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev) | |||
285 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); | 285 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); |
286 | } | 286 | } |
287 | } | 287 | } |
288 | |||
289 | static ssize_t bus_scan_store(struct bus_type *bus, const char *buf, | ||
290 | size_t count) | ||
291 | { | ||
292 | long val; | ||
293 | struct rio_mport *port = NULL; | ||
294 | int rc; | ||
295 | |||
296 | if (kstrtol(buf, 0, &val) < 0) | ||
297 | return -EINVAL; | ||
298 | |||
299 | if (val == RIO_MPORT_ANY) { | ||
300 | rc = rio_init_mports(); | ||
301 | goto exit; | ||
302 | } | ||
303 | |||
304 | if (val < 0 || val >= RIO_MAX_MPORTS) | ||
305 | return -EINVAL; | ||
306 | |||
307 | port = rio_find_mport((int)val); | ||
308 | |||
309 | if (!port) { | ||
310 | pr_debug("RIO: %s: mport_%d not available\n", | ||
311 | __func__, (int)val); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | |||
315 | if (!port->nscan) | ||
316 | return -EINVAL; | ||
317 | |||
318 | if (port->host_deviceid >= 0) | ||
319 | rc = port->nscan->enumerate(port, 0); | ||
320 | else | ||
321 | rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT); | ||
322 | exit: | ||
323 | if (!rc) | ||
324 | rc = count; | ||
325 | |||
326 | return rc; | ||
327 | } | ||
328 | |||
329 | struct bus_attribute rio_bus_attrs[] = { | ||
330 | __ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store), | ||
331 | __ATTR_NULL | ||
332 | }; | ||
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 6e75dda34799..cb1c08996fbb 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -1383,6 +1383,30 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg); | |||
1383 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | 1383 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ |
1384 | 1384 | ||
1385 | /** | 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 | */ | ||
1393 | struct 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; | ||
1403 | found: | ||
1404 | mutex_unlock(&rio_mport_list_lock); | ||
1405 | |||
1406 | return port; | ||
1407 | } | ||
1408 | |||
1409 | /** | ||
1386 | * rio_register_scan - enumeration/discovery method registration interface | 1410 | * rio_register_scan - enumeration/discovery method registration interface |
1387 | * @mport_id: mport device ID for which fabric scan routine has to be set | 1411 | * @mport_id: mport device ID for which fabric scan routine has to be set |
1388 | * (RIO_MPORT_ANY = set for all available mports) | 1412 | * (RIO_MPORT_ANY = set for all available mports) |
@@ -1475,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work) | |||
1475 | work = container_of(_work, struct rio_disc_work, work); | 1499 | work = container_of(_work, struct rio_disc_work, work); |
1476 | pr_debug("RIO: discovery work for mport %d %s\n", | 1500 | pr_debug("RIO: discovery work for mport %d %s\n", |
1477 | work->mport->id, work->mport->name); | 1501 | work->mport->id, work->mport->name); |
1478 | work->mport->nscan->discover(work->mport); | 1502 | work->mport->nscan->discover(work->mport, 0); |
1479 | } | 1503 | } |
1480 | 1504 | ||
1481 | int rio_init_mports(void) | 1505 | int rio_init_mports(void) |
@@ -1495,7 +1519,7 @@ int rio_init_mports(void) | |||
1495 | list_for_each_entry(port, &rio_mports, node) { | 1519 | list_for_each_entry(port, &rio_mports, node) { |
1496 | if (port->host_deviceid >= 0) { | 1520 | if (port->host_deviceid >= 0) { |
1497 | if (port->nscan) | 1521 | if (port->nscan) |
1498 | port->nscan->enumerate(port); | 1522 | port->nscan->enumerate(port, 0); |
1499 | } else | 1523 | } else |
1500 | n++; | 1524 | n++; |
1501 | } | 1525 | } |
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index 0afdf482517e..c14f864dea5c 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h | |||
@@ -45,9 +45,11 @@ extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, | |||
45 | extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); | 45 | extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); |
46 | extern int rio_unregister_scan(int mport_id); | 46 | extern int rio_unregister_scan(int mport_id); |
47 | extern void rio_attach_device(struct rio_dev *rdev); | 47 | extern void rio_attach_device(struct rio_dev *rdev); |
48 | extern struct rio_mport *rio_find_mport(int mport_id); | ||
48 | 49 | ||
49 | /* Structures internal to the RIO core code */ | 50 | /* Structures internal to the RIO core code */ |
50 | extern struct device_attribute rio_dev_attrs[]; | 51 | extern struct device_attribute rio_dev_attrs[]; |
52 | extern struct bus_attribute rio_bus_attrs[]; | ||
51 | 53 | ||
52 | extern struct rio_switch_ops __start_rio_switch_ops[]; | 54 | extern struct rio_switch_ops __start_rio_switch_ops[]; |
53 | extern struct rio_switch_ops __end_rio_switch_ops[]; | 55 | extern struct rio_switch_ops __end_rio_switch_ops[]; |