diff options
Diffstat (limited to 'drivers/rapidio/rio-scan.c')
| -rw-r--r-- | drivers/rapidio/rio-scan.c | 190 |
1 files changed, 60 insertions, 130 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a965acd3c0e4..4c15dbf81087 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
| @@ -37,12 +37,8 @@ | |||
| 37 | 37 | ||
| 38 | #include "rio.h" | 38 | #include "rio.h" |
| 39 | 39 | ||
| 40 | LIST_HEAD(rio_devices); | ||
| 41 | |||
| 42 | static void rio_init_em(struct rio_dev *rdev); | 40 | static void rio_init_em(struct rio_dev *rdev); |
| 43 | 41 | ||
| 44 | DEFINE_SPINLOCK(rio_global_list_lock); | ||
| 45 | |||
| 46 | static int next_destid = 0; | 42 | static int next_destid = 0; |
| 47 | static int next_comptag = 1; | 43 | static int next_comptag = 1; |
| 48 | 44 | ||
| @@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev) | |||
| 327 | } | 323 | } |
| 328 | 324 | ||
| 329 | /** | 325 | /** |
| 330 | * rio_switch_init - Sets switch operations for a particular vendor switch | ||
| 331 | * @rdev: RIO device | ||
| 332 | * @do_enum: Enumeration/Discovery mode flag | ||
| 333 | * | ||
| 334 | * Searches the RIO switch ops table for known switch types. If the vid | ||
| 335 | * and did match a switch table entry, then call switch initialization | ||
| 336 | * routine to setup switch-specific routines. | ||
| 337 | */ | ||
| 338 | static void rio_switch_init(struct rio_dev *rdev, int do_enum) | ||
| 339 | { | ||
| 340 | struct rio_switch_ops *cur = __start_rio_switch_ops; | ||
| 341 | struct rio_switch_ops *end = __end_rio_switch_ops; | ||
| 342 | |||
| 343 | while (cur < end) { | ||
| 344 | if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { | ||
| 345 | pr_debug("RIO: calling init routine for %s\n", | ||
| 346 | rio_name(rdev)); | ||
| 347 | cur->init_hook(rdev, do_enum); | ||
| 348 | break; | ||
| 349 | } | ||
| 350 | cur++; | ||
| 351 | } | ||
| 352 | |||
| 353 | if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { | ||
| 354 | pr_debug("RIO: adding STD routing ops for %s\n", | ||
| 355 | rio_name(rdev)); | ||
| 356 | rdev->rswitch->add_entry = rio_std_route_add_entry; | ||
| 357 | rdev->rswitch->get_entry = rio_std_route_get_entry; | ||
| 358 | rdev->rswitch->clr_table = rio_std_route_clr_table; | ||
| 359 | } | ||
| 360 | |||
| 361 | if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) | ||
| 362 | printk(KERN_ERR "RIO: missing routing ops for %s\n", | ||
| 363 | rio_name(rdev)); | ||
| 364 | } | ||
| 365 | |||
| 366 | /** | ||
| 367 | * rio_add_device- Adds a RIO device to the device model | ||
| 368 | * @rdev: RIO device | ||
| 369 | * | ||
| 370 | * Adds the RIO device to the global device list and adds the RIO | ||
| 371 | * device to the RIO device list. Creates the generic sysfs nodes | ||
| 372 | * for an RIO device. | ||
| 373 | */ | ||
| 374 | static int rio_add_device(struct rio_dev *rdev) | ||
| 375 | { | ||
| 376 | int err; | ||
| 377 | |||
| 378 | err = device_add(&rdev->dev); | ||
| 379 | if (err) | ||
| 380 | return err; | ||
| 381 | |||
| 382 | spin_lock(&rio_global_list_lock); | ||
| 383 | list_add_tail(&rdev->global_list, &rio_devices); | ||
| 384 | spin_unlock(&rio_global_list_lock); | ||
| 385 | |||
| 386 | rio_create_sysfs_dev_files(rdev); | ||
| 387 | |||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | |||
| 391 | /** | ||
| 392 | * rio_enable_rx_tx_port - enable input receiver and output transmitter of | ||
| 393 | * given port | ||
| 394 | * @port: Master port associated with the RIO network | ||
| 395 | * @local: local=1 select local port otherwise a far device is reached | ||
| 396 | * @destid: Destination ID of the device to check host bit | ||
| 397 | * @hopcount: Number of hops to reach the target | ||
| 398 | * @port_num: Port (-number on switch) to enable on a far end device | ||
| 399 | * | ||
| 400 | * Returns 0 or 1 from on General Control Command and Status Register | ||
| 401 | * (EXT_PTR+0x3C) | ||
| 402 | */ | ||
| 403 | inline int rio_enable_rx_tx_port(struct rio_mport *port, | ||
| 404 | int local, u16 destid, | ||
| 405 | u8 hopcount, u8 port_num) { | ||
| 406 | #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS | ||
| 407 | u32 regval; | ||
| 408 | u32 ext_ftr_ptr; | ||
| 409 | |||
| 410 | /* | ||
| 411 | * enable rx input tx output port | ||
| 412 | */ | ||
| 413 | pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " | ||
| 414 | "%d, port_num = %d)\n", local, destid, hopcount, port_num); | ||
| 415 | |||
| 416 | ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); | ||
| 417 | |||
| 418 | if (local) { | ||
| 419 | rio_local_read_config_32(port, ext_ftr_ptr + | ||
| 420 | RIO_PORT_N_CTL_CSR(0), | ||
| 421 | ®val); | ||
| 422 | } else { | ||
| 423 | if (rio_mport_read_config_32(port, destid, hopcount, | ||
| 424 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) | ||
| 425 | return -EIO; | ||
| 426 | } | ||
| 427 | |||
| 428 | if (regval & RIO_PORT_N_CTL_P_TYP_SER) { | ||
| 429 | /* serial */ | ||
| 430 | regval = regval | RIO_PORT_N_CTL_EN_RX_SER | ||
| 431 | | RIO_PORT_N_CTL_EN_TX_SER; | ||
| 432 | } else { | ||
| 433 | /* parallel */ | ||
| 434 | regval = regval | RIO_PORT_N_CTL_EN_RX_PAR | ||
| 435 | | RIO_PORT_N_CTL_EN_TX_PAR; | ||
| 436 | } | ||
| 437 | |||
| 438 | if (local) { | ||
| 439 | rio_local_write_config_32(port, ext_ftr_ptr + | ||
| 440 | RIO_PORT_N_CTL_CSR(0), regval); | ||
| 441 | } else { | ||
| 442 | if (rio_mport_write_config_32(port, destid, hopcount, | ||
| 443 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) | ||
| 444 | return -EIO; | ||
| 445 | } | ||
| 446 | #endif | ||
| 447 | return 0; | ||
| 448 | } | ||
| 449 | |||
| 450 | /** | ||
| 451 | * rio_setup_device- Allocates and sets up a RIO device | 326 | * rio_setup_device- Allocates and sets up a RIO device |
| 452 | * @net: RIO network | 327 | * @net: RIO network |
| 453 | * @port: Master port to send transactions | 328 | * @port: Master port to send transactions |
| @@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
| 587 | rdev->destid); | 462 | rdev->destid); |
| 588 | } | 463 | } |
| 589 | 464 | ||
| 590 | rdev->dev.bus = &rio_bus_type; | 465 | rio_attach_device(rdev); |
| 591 | rdev->dev.parent = &rio_bus; | ||
| 592 | 466 | ||
| 593 | device_initialize(&rdev->dev); | 467 | device_initialize(&rdev->dev); |
| 594 | rdev->dev.release = rio_release_dev; | 468 | rdev->dev.release = rio_release_dev; |
| @@ -1260,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable) | |||
| 1260 | /** | 1134 | /** |
| 1261 | * rio_enum_mport- Start enumeration through a master port | 1135 | * rio_enum_mport- Start enumeration through a master port |
| 1262 | * @mport: Master port to send transactions | 1136 | * @mport: Master port to send transactions |
| 1137 | * @flags: Enumeration control flags | ||
| 1263 | * | 1138 | * |
| 1264 | * Starts the enumeration process. If somebody has enumerated our | 1139 | * Starts the enumeration process. If somebody has enumerated our |
| 1265 | * 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 |
| 1266 | * link, then start recursive peer enumeration. Returns %0 if | 1141 | * link, then start recursive peer enumeration. Returns %0 if |
| 1267 | * enumeration succeeds or %-EBUSY if enumeration fails. | 1142 | * enumeration succeeds or %-EBUSY if enumeration fails. |
| 1268 | */ | 1143 | */ |
| 1269 | int rio_enum_mport(struct rio_mport *mport) | 1144 | int rio_enum_mport(struct rio_mport *mport, u32 flags) |
| 1270 | { | 1145 | { |
| 1271 | struct rio_net *net = NULL; | 1146 | struct rio_net *net = NULL; |
| 1272 | int rc = 0; | 1147 | int rc = 0; |
| 1273 | 1148 | ||
| 1274 | 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, |
| 1275 | 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 | |||
| 1276 | /* If somebody else enumerated our master port device, bail. */ | 1161 | /* If somebody else enumerated our master port device, bail. */ |
| 1277 | if (rio_enum_host(mport) < 0) { | 1162 | if (rio_enum_host(mport) < 0) { |
| 1278 | printk(KERN_INFO | 1163 | printk(KERN_INFO |
| @@ -1362,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net) | |||
| 1362 | /** | 1247 | /** |
| 1363 | * rio_disc_mport- Start discovery through a master port | 1248 | * rio_disc_mport- Start discovery through a master port |
| 1364 | * @mport: Master port to send transactions | 1249 | * @mport: Master port to send transactions |
| 1250 | * @flags: discovery control flags | ||
| 1365 | * | 1251 | * |
| 1366 | * Starts the discovery process. If we have an active link, | 1252 | * Starts the discovery process. If we have an active link, |
| 1367 | * then wait for the signal that enumeration is complete. | 1253 | * then wait for the signal that enumeration is complete (if wait |
| 1254 | * is allowed). | ||
| 1368 | * When enumeration completion is signaled, start recursive | 1255 | * When enumeration completion is signaled, start recursive |
| 1369 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY | 1256 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY |
| 1370 | * on failure. | 1257 | * on failure. |
| 1371 | */ | 1258 | */ |
| 1372 | int rio_disc_mport(struct rio_mport *mport) | 1259 | int rio_disc_mport(struct rio_mport *mport, u32 flags) |
| 1373 | { | 1260 | { |
| 1374 | struct rio_net *net = NULL; | 1261 | struct rio_net *net = NULL; |
| 1375 | unsigned long to_end; | 1262 | unsigned long to_end; |
| @@ -1379,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport) | |||
| 1379 | 1266 | ||
| 1380 | /* 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 */ |
| 1381 | 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 | |||
| 1382 | pr_debug("RIO: wait for enumeration to complete...\n"); | 1274 | pr_debug("RIO: wait for enumeration to complete...\n"); |
| 1383 | 1275 | ||
| 1384 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; | 1276 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; |
| @@ -1421,3 +1313,41 @@ enum_done: | |||
| 1421 | bail: | 1313 | bail: |
| 1422 | return -EBUSY; | 1314 | return -EBUSY; |
| 1423 | } | 1315 | } |
| 1316 | |||
| 1317 | static struct rio_scan rio_scan_ops = { | ||
| 1318 | .enumerate = rio_enum_mport, | ||
| 1319 | .discover = rio_disc_mport, | ||
| 1320 | }; | ||
| 1321 | |||
| 1322 | static bool scan; | ||
| 1323 | module_param(scan, bool, 0); | ||
| 1324 | MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery " | ||
| 1325 | "(default = 0)"); | ||
| 1326 | |||
| 1327 | /** | ||
| 1328 | * rio_basic_attach: | ||
| 1329 | * | ||
| 1330 | * When this enumeration/discovery method is loaded as a module this function | ||
| 1331 | * registers its specific enumeration and discover routines for all available | ||
| 1332 | * RapidIO mport devices. The "scan" command line parameter controls ability of | ||
| 1333 | * the module to start RapidIO enumeration/discovery automatically. | ||
| 1334 | * | ||
| 1335 | * Returns 0 for success or -EIO if unable to register itself. | ||
| 1336 | * | ||
| 1337 | * This enumeration/discovery method cannot be unloaded and therefore does not | ||
| 1338 | * provide a matching cleanup_module routine. | ||
| 1339 | */ | ||
| 1340 | |||
| 1341 | static int __init rio_basic_attach(void) | ||
| 1342 | { | ||
| 1343 | if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops)) | ||
| 1344 | return -EIO; | ||
| 1345 | if (scan) | ||
| 1346 | rio_init_mports(); | ||
| 1347 | return 0; | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | late_initcall(rio_basic_attach); | ||
| 1351 | |||
| 1352 | MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery"); | ||
| 1353 | MODULE_LICENSE("GPL"); | ||
