root/arch/powerpc/platforms/ps3/device-init.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ps3_register_lpm_devices
  2. ps3_setup_gelic_device
  3. ps3_setup_uhc_device
  4. ps3_setup_ehci_device
  5. ps3_setup_ohci_device
  6. ps3_setup_vuart_device
  7. ps3_setup_storage_dev
  8. ps3_register_vuart_devices
  9. ps3_register_sound_devices
  10. ps3_register_graphics_devices
  11. ps3_register_ramdisk_device
  12. ps3_setup_dynamic_device
  13. ps3_setup_static_device
  14. ps3_find_and_add_device
  15. ps3_notification_interrupt
  16. ps3_notification_read_write
  17. ps3_probe_thread
  18. ps3_stop_probe_thread
  19. ps3_start_probe_thread
  20. ps3_register_devices

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  PS3 device registration routines.
   4  *
   5  *  Copyright (C) 2007 Sony Computer Entertainment Inc.
   6  *  Copyright 2007 Sony Corp.
   7  */
   8 
   9 #include <linux/delay.h>
  10 #include <linux/freezer.h>
  11 #include <linux/kernel.h>
  12 #include <linux/kthread.h>
  13 #include <linux/init.h>
  14 #include <linux/slab.h>
  15 #include <linux/reboot.h>
  16 
  17 #include <asm/firmware.h>
  18 #include <asm/lv1call.h>
  19 #include <asm/ps3stor.h>
  20 
  21 #include "platform.h"
  22 
  23 static int __init ps3_register_lpm_devices(void)
  24 {
  25         int result;
  26         u64 tmp1;
  27         u64 tmp2;
  28         struct ps3_system_bus_device *dev;
  29 
  30         pr_debug(" -> %s:%d\n", __func__, __LINE__);
  31 
  32         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  33         if (!dev)
  34                 return -ENOMEM;
  35 
  36         dev->match_id = PS3_MATCH_ID_LPM;
  37         dev->dev_type = PS3_DEVICE_TYPE_LPM;
  38 
  39         /* The current lpm driver only supports a single BE processor. */
  40 
  41         result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id);
  42 
  43         if (result) {
  44                 pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n",
  45                         __func__, __LINE__);
  46                 goto fail_read_repo;
  47         }
  48 
  49         result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1,
  50                 &dev->lpm.rights);
  51 
  52         if (result) {
  53                 pr_debug("%s:%d: ps3_repository_read_lpm_privileges failed\n",
  54                         __func__, __LINE__);
  55                 goto fail_read_repo;
  56         }
  57 
  58         lv1_get_logical_partition_id(&tmp2);
  59 
  60         if (tmp1 != tmp2) {
  61                 pr_debug("%s:%d: wrong lpar\n",
  62                         __func__, __LINE__);
  63                 result = -ENODEV;
  64                 goto fail_rights;
  65         }
  66 
  67         if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) {
  68                 pr_debug("%s:%d: don't have rights to use lpm\n",
  69                         __func__, __LINE__);
  70                 result = -EPERM;
  71                 goto fail_rights;
  72         }
  73 
  74         pr_debug("%s:%d: pu_id %llu, rights %llu(%llxh)\n",
  75                 __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights,
  76                 dev->lpm.rights);
  77 
  78         result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id);
  79 
  80         if (result) {
  81                 pr_debug("%s:%d: ps3_repository_read_pu_id failed \n",
  82                         __func__, __LINE__);
  83                 goto fail_read_repo;
  84         }
  85 
  86         result = ps3_system_bus_device_register(dev);
  87 
  88         if (result) {
  89                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
  90                         __func__, __LINE__);
  91                 goto fail_register;
  92         }
  93 
  94         pr_debug(" <- %s:%d\n", __func__, __LINE__);
  95         return 0;
  96 
  97 
  98 fail_register:
  99 fail_rights:
 100 fail_read_repo:
 101         kfree(dev);
 102         pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
 103         return result;
 104 }
 105 
 106 /**
 107  * ps3_setup_gelic_device - Setup and register a gelic device instance.
 108  *
 109  * Allocates memory for a struct ps3_system_bus_device instance, initialises the
 110  * structure members, and registers the device instance with the system bus.
 111  */
 112 
 113 static int __init ps3_setup_gelic_device(
 114         const struct ps3_repository_device *repo)
 115 {
 116         int result;
 117         struct layout {
 118                 struct ps3_system_bus_device dev;
 119                 struct ps3_dma_region d_region;
 120         } *p;
 121 
 122         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 123 
 124         BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
 125         BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
 126 
 127         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
 128 
 129         if (!p) {
 130                 result = -ENOMEM;
 131                 goto fail_malloc;
 132         }
 133 
 134         p->dev.match_id = PS3_MATCH_ID_GELIC;
 135         p->dev.dev_type = PS3_DEVICE_TYPE_SB;
 136         p->dev.bus_id = repo->bus_id;
 137         p->dev.dev_id = repo->dev_id;
 138         p->dev.d_region = &p->d_region;
 139 
 140         result = ps3_repository_find_interrupt(repo,
 141                 PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
 142 
 143         if (result) {
 144                 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
 145                         __func__, __LINE__);
 146                 goto fail_find_interrupt;
 147         }
 148 
 149         BUG_ON(p->dev.interrupt_id != 0);
 150 
 151         result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
 152                 PS3_DMA_OTHER, NULL, 0);
 153 
 154         if (result) {
 155                 pr_debug("%s:%d ps3_dma_region_init failed\n",
 156                         __func__, __LINE__);
 157                 goto fail_dma_init;
 158         }
 159 
 160         result = ps3_system_bus_device_register(&p->dev);
 161 
 162         if (result) {
 163                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
 164                         __func__, __LINE__);
 165                 goto fail_device_register;
 166         }
 167 
 168         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 169         return result;
 170 
 171 fail_device_register:
 172 fail_dma_init:
 173 fail_find_interrupt:
 174         kfree(p);
 175 fail_malloc:
 176         pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
 177         return result;
 178 }
 179 
 180 static int __ref ps3_setup_uhc_device(
 181         const struct ps3_repository_device *repo, enum ps3_match_id match_id,
 182         enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
 183 {
 184         int result;
 185         struct layout {
 186                 struct ps3_system_bus_device dev;
 187                 struct ps3_dma_region d_region;
 188                 struct ps3_mmio_region m_region;
 189         } *p;
 190         u64 bus_addr;
 191         u64 len;
 192 
 193         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 194 
 195         BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
 196         BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
 197 
 198         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
 199 
 200         if (!p) {
 201                 result = -ENOMEM;
 202                 goto fail_malloc;
 203         }
 204 
 205         p->dev.match_id = match_id;
 206         p->dev.dev_type = PS3_DEVICE_TYPE_SB;
 207         p->dev.bus_id = repo->bus_id;
 208         p->dev.dev_id = repo->dev_id;
 209         p->dev.d_region = &p->d_region;
 210         p->dev.m_region = &p->m_region;
 211 
 212         result = ps3_repository_find_interrupt(repo,
 213                 interrupt_type, &p->dev.interrupt_id);
 214 
 215         if (result) {
 216                 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
 217                         __func__, __LINE__);
 218                 goto fail_find_interrupt;
 219         }
 220 
 221         result = ps3_repository_find_reg(repo, reg_type,
 222                 &bus_addr, &len);
 223 
 224         if (result) {
 225                 pr_debug("%s:%d ps3_repository_find_reg failed\n",
 226                         __func__, __LINE__);
 227                 goto fail_find_reg;
 228         }
 229 
 230         result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
 231                 PS3_DMA_INTERNAL, NULL, 0);
 232 
 233         if (result) {
 234                 pr_debug("%s:%d ps3_dma_region_init failed\n",
 235                         __func__, __LINE__);
 236                 goto fail_dma_init;
 237         }
 238 
 239         result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
 240                 PS3_MMIO_4K);
 241 
 242         if (result) {
 243                 pr_debug("%s:%d ps3_mmio_region_init failed\n",
 244                         __func__, __LINE__);
 245                 goto fail_mmio_init;
 246         }
 247 
 248         result = ps3_system_bus_device_register(&p->dev);
 249 
 250         if (result) {
 251                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
 252                         __func__, __LINE__);
 253                 goto fail_device_register;
 254         }
 255 
 256         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 257         return result;
 258 
 259 fail_device_register:
 260 fail_mmio_init:
 261 fail_dma_init:
 262 fail_find_reg:
 263 fail_find_interrupt:
 264         kfree(p);
 265 fail_malloc:
 266         pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
 267         return result;
 268 }
 269 
 270 static int __init ps3_setup_ehci_device(
 271         const struct ps3_repository_device *repo)
 272 {
 273         return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
 274                 PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
 275 }
 276 
 277 static int __init ps3_setup_ohci_device(
 278         const struct ps3_repository_device *repo)
 279 {
 280         return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
 281                 PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
 282 }
 283 
 284 static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
 285         unsigned int port_number)
 286 {
 287         int result;
 288         struct layout {
 289                 struct ps3_system_bus_device dev;
 290         } *p;
 291 
 292         pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
 293                 match_id, port_number);
 294 
 295         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
 296 
 297         if (!p)
 298                 return -ENOMEM;
 299 
 300         p->dev.match_id = match_id;
 301         p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
 302         p->dev.port_number = port_number;
 303 
 304         result = ps3_system_bus_device_register(&p->dev);
 305 
 306         if (result) {
 307                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
 308                         __func__, __LINE__);
 309                 goto fail_device_register;
 310         }
 311         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 312         return 0;
 313 
 314 fail_device_register:
 315         kfree(p);
 316         pr_debug(" <- %s:%d fail\n", __func__, __LINE__);
 317         return result;
 318 }
 319 
 320 static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
 321                                  enum ps3_match_id match_id)
 322 {
 323         int result;
 324         struct ps3_storage_device *p;
 325         u64 port, blk_size, num_blocks;
 326         unsigned int num_regions, i;
 327 
 328         pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);
 329 
 330         result = ps3_repository_read_stor_dev_info(repo->bus_index,
 331                                                    repo->dev_index, &port,
 332                                                    &blk_size, &num_blocks,
 333                                                    &num_regions);
 334         if (result) {
 335                 printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",
 336                        __func__, __LINE__, result);
 337                 return -ENODEV;
 338         }
 339 
 340         pr_debug("%s:%u: (%u:%u:%u): port %llu blk_size %llu num_blocks %llu "
 341                  "num_regions %u\n", __func__, __LINE__, repo->bus_index,
 342                  repo->dev_index, repo->dev_type, port, blk_size, num_blocks,
 343                  num_regions);
 344 
 345         p = kzalloc(struct_size(p, regions, num_regions), GFP_KERNEL);
 346         if (!p) {
 347                 result = -ENOMEM;
 348                 goto fail_malloc;
 349         }
 350 
 351         p->sbd.match_id = match_id;
 352         p->sbd.dev_type = PS3_DEVICE_TYPE_SB;
 353         p->sbd.bus_id = repo->bus_id;
 354         p->sbd.dev_id = repo->dev_id;
 355         p->sbd.d_region = &p->dma_region;
 356         p->blk_size = blk_size;
 357         p->num_regions = num_regions;
 358 
 359         result = ps3_repository_find_interrupt(repo,
 360                                                PS3_INTERRUPT_TYPE_EVENT_PORT,
 361                                                &p->sbd.interrupt_id);
 362         if (result) {
 363                 printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,
 364                        __LINE__, result);
 365                 result = -ENODEV;
 366                 goto fail_find_interrupt;
 367         }
 368 
 369         for (i = 0; i < num_regions; i++) {
 370                 unsigned int id;
 371                 u64 start, size;
 372 
 373                 result = ps3_repository_read_stor_dev_region(repo->bus_index,
 374                                                              repo->dev_index,
 375                                                              i, &id, &start,
 376                                                              &size);
 377                 if (result) {
 378                         printk(KERN_ERR
 379                                "%s:%u: read_stor_dev_region failed %d\n",
 380                                __func__, __LINE__, result);
 381                         result = -ENODEV;
 382                         goto fail_read_region;
 383                 }
 384                 pr_debug("%s:%u: region %u: id %u start %llu size %llu\n",
 385                          __func__, __LINE__, i, id, start, size);
 386 
 387                 p->regions[i].id = id;
 388                 p->regions[i].start = start;
 389                 p->regions[i].size = size;
 390         }
 391 
 392         result = ps3_system_bus_device_register(&p->sbd);
 393         if (result) {
 394                 pr_debug("%s:%u ps3_system_bus_device_register failed\n",
 395                          __func__, __LINE__);
 396                 goto fail_device_register;
 397         }
 398 
 399         pr_debug(" <- %s:%u\n", __func__, __LINE__);
 400         return 0;
 401 
 402 fail_device_register:
 403 fail_read_region:
 404 fail_find_interrupt:
 405         kfree(p);
 406 fail_malloc:
 407         pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);
 408         return result;
 409 }
 410 
 411 static int __init ps3_register_vuart_devices(void)
 412 {
 413         int result;
 414         unsigned int port_number;
 415 
 416         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 417 
 418         result = ps3_repository_read_vuart_av_port(&port_number);
 419         if (result)
 420                 port_number = 0; /* av default */
 421 
 422         result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
 423         WARN_ON(result);
 424 
 425         result = ps3_repository_read_vuart_sysmgr_port(&port_number);
 426         if (result)
 427                 port_number = 2; /* sysmgr default */
 428 
 429         result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
 430                 port_number);
 431         WARN_ON(result);
 432 
 433         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 434         return result;
 435 }
 436 
 437 static int __init ps3_register_sound_devices(void)
 438 {
 439         int result;
 440         struct layout {
 441                 struct ps3_system_bus_device dev;
 442                 struct ps3_dma_region d_region;
 443                 struct ps3_mmio_region m_region;
 444         } *p;
 445 
 446         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 447 
 448         p = kzalloc(sizeof(*p), GFP_KERNEL);
 449         if (!p)
 450                 return -ENOMEM;
 451 
 452         p->dev.match_id = PS3_MATCH_ID_SOUND;
 453         p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
 454         p->dev.d_region = &p->d_region;
 455         p->dev.m_region = &p->m_region;
 456 
 457         result = ps3_system_bus_device_register(&p->dev);
 458 
 459         if (result) {
 460                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
 461                         __func__, __LINE__);
 462                 goto fail_device_register;
 463         }
 464         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 465         return 0;
 466 
 467 fail_device_register:
 468         kfree(p);
 469         pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
 470         return result;
 471 }
 472 
 473 static int __init ps3_register_graphics_devices(void)
 474 {
 475         int result;
 476         struct layout {
 477                 struct ps3_system_bus_device dev;
 478         } *p;
 479 
 480         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 481 
 482         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
 483 
 484         if (!p)
 485                 return -ENOMEM;
 486 
 487         p->dev.match_id = PS3_MATCH_ID_GPU;
 488         p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_FB;
 489         p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
 490 
 491         result = ps3_system_bus_device_register(&p->dev);
 492 
 493         if (result) {
 494                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
 495                         __func__, __LINE__);
 496                 goto fail_device_register;
 497         }
 498 
 499         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 500         return 0;
 501 
 502 fail_device_register:
 503         kfree(p);
 504         pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
 505         return result;
 506 }
 507 
 508 static int __init ps3_register_ramdisk_device(void)
 509 {
 510         int result;
 511         struct layout {
 512                 struct ps3_system_bus_device dev;
 513         } *p;
 514 
 515         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 516 
 517         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
 518 
 519         if (!p)
 520                 return -ENOMEM;
 521 
 522         p->dev.match_id = PS3_MATCH_ID_GPU;
 523         p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK;
 524         p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
 525 
 526         result = ps3_system_bus_device_register(&p->dev);
 527 
 528         if (result) {
 529                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
 530                         __func__, __LINE__);
 531                 goto fail_device_register;
 532         }
 533 
 534         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 535         return 0;
 536 
 537 fail_device_register:
 538         kfree(p);
 539         pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
 540         return result;
 541 }
 542 
 543 /**
 544  * ps3_setup_dynamic_device - Setup a dynamic device from the repository
 545  */
 546 
 547 static int ps3_setup_dynamic_device(const struct ps3_repository_device *repo)
 548 {
 549         int result;
 550 
 551         switch (repo->dev_type) {
 552         case PS3_DEV_TYPE_STOR_DISK:
 553                 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);
 554 
 555                 /* Some devices are not accessible from the Other OS lpar. */
 556                 if (result == -ENODEV) {
 557                         result = 0;
 558                         pr_debug("%s:%u: not accessible\n", __func__,
 559                                  __LINE__);
 560                 }
 561 
 562                 if (result)
 563                         pr_debug("%s:%u ps3_setup_storage_dev failed\n",
 564                                  __func__, __LINE__);
 565                 break;
 566 
 567         case PS3_DEV_TYPE_STOR_ROM:
 568                 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);
 569                 if (result)
 570                         pr_debug("%s:%u ps3_setup_storage_dev failed\n",
 571                                  __func__, __LINE__);
 572                 break;
 573 
 574         case PS3_DEV_TYPE_STOR_FLASH:
 575                 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);
 576                 if (result)
 577                         pr_debug("%s:%u ps3_setup_storage_dev failed\n",
 578                                  __func__, __LINE__);
 579                 break;
 580 
 581         default:
 582                 result = 0;
 583                 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
 584                         repo->dev_type);
 585         }
 586 
 587         return result;
 588 }
 589 
 590 /**
 591  * ps3_setup_static_device - Setup a static device from the repository
 592  */
 593 
 594 static int __init ps3_setup_static_device(const struct ps3_repository_device *repo)
 595 {
 596         int result;
 597 
 598         switch (repo->dev_type) {
 599         case PS3_DEV_TYPE_SB_GELIC:
 600                 result = ps3_setup_gelic_device(repo);
 601                 if (result) {
 602                         pr_debug("%s:%d ps3_setup_gelic_device failed\n",
 603                                 __func__, __LINE__);
 604                 }
 605                 break;
 606         case PS3_DEV_TYPE_SB_USB:
 607 
 608                 /* Each USB device has both an EHCI and an OHCI HC */
 609 
 610                 result = ps3_setup_ehci_device(repo);
 611 
 612                 if (result) {
 613                         pr_debug("%s:%d ps3_setup_ehci_device failed\n",
 614                                 __func__, __LINE__);
 615                 }
 616 
 617                 result = ps3_setup_ohci_device(repo);
 618 
 619                 if (result) {
 620                         pr_debug("%s:%d ps3_setup_ohci_device failed\n",
 621                                 __func__, __LINE__);
 622                 }
 623                 break;
 624 
 625         default:
 626                 return ps3_setup_dynamic_device(repo);
 627         }
 628 
 629         return result;
 630 }
 631 
 632 static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
 633 {
 634         struct ps3_repository_device repo;
 635         int res;
 636         unsigned int retries;
 637         unsigned long rem;
 638 
 639         /*
 640          * On some firmware versions (e.g. 1.90), the device may not show up
 641          * in the repository immediately
 642          */
 643         for (retries = 0; retries < 10; retries++) {
 644                 res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
 645                 if (!res)
 646                         goto found;
 647 
 648                 rem = msleep_interruptible(100);
 649                 if (rem)
 650                         break;
 651         }
 652         pr_warn("%s:%u: device %llu:%llu not found\n",
 653                 __func__, __LINE__, bus_id, dev_id);
 654         return;
 655 
 656 found:
 657         if (retries)
 658                 pr_debug("%s:%u: device %llu:%llu found after %u retries\n",
 659                          __func__, __LINE__, bus_id, dev_id, retries);
 660 
 661         ps3_setup_dynamic_device(&repo);
 662         return;
 663 }
 664 
 665 #define PS3_NOTIFICATION_DEV_ID         ULONG_MAX
 666 #define PS3_NOTIFICATION_INTERRUPT_ID   0
 667 
 668 struct ps3_notification_device {
 669         struct ps3_system_bus_device sbd;
 670         spinlock_t lock;
 671         u64 tag;
 672         u64 lv1_status;
 673         struct completion done;
 674 };
 675 
 676 enum ps3_notify_type {
 677         notify_device_ready = 0,
 678         notify_region_probe = 1,
 679         notify_region_update = 2,
 680 };
 681 
 682 struct ps3_notify_cmd {
 683         u64 operation_code;             /* must be zero */
 684         u64 event_mask;                 /* OR of 1UL << enum ps3_notify_type */
 685 };
 686 
 687 struct ps3_notify_event {
 688         u64 event_type;                 /* enum ps3_notify_type */
 689         u64 bus_id;
 690         u64 dev_id;
 691         u64 dev_type;
 692         u64 dev_port;
 693 };
 694 
 695 static irqreturn_t ps3_notification_interrupt(int irq, void *data)
 696 {
 697         struct ps3_notification_device *dev = data;
 698         int res;
 699         u64 tag, status;
 700 
 701         spin_lock(&dev->lock);
 702         res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag,
 703                                            &status);
 704         if (tag != dev->tag)
 705                 pr_err("%s:%u: tag mismatch, got %llx, expected %llx\n",
 706                        __func__, __LINE__, tag, dev->tag);
 707 
 708         if (res) {
 709                 pr_err("%s:%u: res %d status 0x%llx\n", __func__, __LINE__, res,
 710                        status);
 711         } else {
 712                 pr_debug("%s:%u: completed, status 0x%llx\n", __func__,
 713                          __LINE__, status);
 714                 dev->lv1_status = status;
 715                 complete(&dev->done);
 716         }
 717         spin_unlock(&dev->lock);
 718         return IRQ_HANDLED;
 719 }
 720 
 721 static int ps3_notification_read_write(struct ps3_notification_device *dev,
 722                                        u64 lpar, int write)
 723 {
 724         const char *op = write ? "write" : "read";
 725         unsigned long flags;
 726         int res;
 727 
 728         init_completion(&dev->done);
 729         spin_lock_irqsave(&dev->lock, flags);
 730         res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
 731                                         &dev->tag)
 732                     : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
 733                                        &dev->tag);
 734         spin_unlock_irqrestore(&dev->lock, flags);
 735         if (res) {
 736                 pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res);
 737                 return -EPERM;
 738         }
 739         pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op);
 740 
 741         res = wait_event_interruptible(dev->done.wait,
 742                                        dev->done.done || kthread_should_stop());
 743         if (kthread_should_stop())
 744                 res = -EINTR;
 745         if (res) {
 746                 pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op);
 747                 return res;
 748         }
 749 
 750         if (dev->lv1_status) {
 751                 pr_err("%s:%u: %s not completed, status 0x%llx\n", __func__,
 752                        __LINE__, op, dev->lv1_status);
 753                 return -EIO;
 754         }
 755         pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op);
 756 
 757         return 0;
 758 }
 759 
 760 static struct task_struct *probe_task;
 761 
 762 /**
 763  * ps3_probe_thread - Background repository probing at system startup.
 764  *
 765  * This implementation only supports background probing on a single bus.
 766  * It uses the hypervisor's storage device notification mechanism to wait until
 767  * a storage device is ready.  The device notification mechanism uses a
 768  * pseudo device to asynchronously notify the guest when storage devices become
 769  * ready.  The notification device has a block size of 512 bytes.
 770  */
 771 
 772 static int ps3_probe_thread(void *data)
 773 {
 774         struct ps3_notification_device dev;
 775         int res;
 776         unsigned int irq;
 777         u64 lpar;
 778         void *buf;
 779         struct ps3_notify_cmd *notify_cmd;
 780         struct ps3_notify_event *notify_event;
 781 
 782         pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
 783 
 784         buf = kzalloc(512, GFP_KERNEL);
 785         if (!buf)
 786                 return -ENOMEM;
 787 
 788         lpar = ps3_mm_phys_to_lpar(__pa(buf));
 789         notify_cmd = buf;
 790         notify_event = buf;
 791 
 792         /* dummy system bus device */
 793         dev.sbd.bus_id = (u64)data;
 794         dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
 795         dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
 796 
 797         res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
 798         if (res) {
 799                 pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
 800                        __LINE__, ps3_result(res));
 801                 goto fail_free;
 802         }
 803 
 804         res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
 805                                               &irq);
 806         if (res) {
 807                 pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
 808                        __func__, __LINE__, res);
 809                goto fail_close_device;
 810         }
 811 
 812         spin_lock_init(&dev.lock);
 813 
 814         res = request_irq(irq, ps3_notification_interrupt, 0,
 815                           "ps3_notification", &dev);
 816         if (res) {
 817                 pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
 818                        res);
 819                 goto fail_sb_event_receive_port_destroy;
 820         }
 821 
 822         /* Setup and write the request for device notification. */
 823         notify_cmd->operation_code = 0; /* must be zero */
 824         notify_cmd->event_mask = 1UL << notify_region_probe;
 825 
 826         res = ps3_notification_read_write(&dev, lpar, 1);
 827         if (res)
 828                 goto fail_free_irq;
 829 
 830         /* Loop here processing the requested notification events. */
 831         do {
 832                 try_to_freeze();
 833 
 834                 memset(notify_event, 0, sizeof(*notify_event));
 835 
 836                 res = ps3_notification_read_write(&dev, lpar, 0);
 837                 if (res)
 838                         break;
 839 
 840                 pr_debug("%s:%u: notify event type 0x%llx bus id %llu dev id %llu"
 841                          " type %llu port %llu\n", __func__, __LINE__,
 842                          notify_event->event_type, notify_event->bus_id,
 843                          notify_event->dev_id, notify_event->dev_type,
 844                          notify_event->dev_port);
 845 
 846                 if (notify_event->event_type != notify_region_probe ||
 847                     notify_event->bus_id != dev.sbd.bus_id) {
 848                         pr_warn("%s:%u: bad notify_event: event %llu, dev_id %llu, dev_type %llu\n",
 849                                 __func__, __LINE__, notify_event->event_type,
 850                                 notify_event->dev_id, notify_event->dev_type);
 851                         continue;
 852                 }
 853 
 854                 ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
 855 
 856         } while (!kthread_should_stop());
 857 
 858 fail_free_irq:
 859         free_irq(irq, &dev);
 860 fail_sb_event_receive_port_destroy:
 861         ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
 862 fail_close_device:
 863         lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
 864 fail_free:
 865         kfree(buf);
 866 
 867         probe_task = NULL;
 868 
 869         pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
 870 
 871         return 0;
 872 }
 873 
 874 /**
 875  * ps3_stop_probe_thread - Stops the background probe thread.
 876  *
 877  */
 878 
 879 static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code,
 880                                  void *data)
 881 {
 882         if (probe_task)
 883                 kthread_stop(probe_task);
 884         return 0;
 885 }
 886 
 887 static struct notifier_block nb = {
 888         .notifier_call = ps3_stop_probe_thread
 889 };
 890 
 891 /**
 892  * ps3_start_probe_thread - Starts the background probe thread.
 893  *
 894  */
 895 
 896 static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
 897 {
 898         int result;
 899         struct task_struct *task;
 900         struct ps3_repository_device repo;
 901 
 902         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 903 
 904         memset(&repo, 0, sizeof(repo));
 905 
 906         repo.bus_type = bus_type;
 907 
 908         result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
 909 
 910         if (result) {
 911                 printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
 912                 return -ENODEV;
 913         }
 914 
 915         result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
 916 
 917         if (result) {
 918                 printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
 919                         result);
 920                 return -ENODEV;
 921         }
 922 
 923         task = kthread_run(ps3_probe_thread, (void *)repo.bus_id,
 924                            "ps3-probe-%u", bus_type);
 925 
 926         if (IS_ERR(task)) {
 927                 result = PTR_ERR(task);
 928                 printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
 929                        result);
 930                 return result;
 931         }
 932 
 933         probe_task = task;
 934         register_reboot_notifier(&nb);
 935 
 936         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 937         return 0;
 938 }
 939 
 940 /**
 941  * ps3_register_devices - Probe the system and register devices found.
 942  *
 943  * A device_initcall() routine.
 944  */
 945 
 946 static int __init ps3_register_devices(void)
 947 {
 948         int result;
 949 
 950         if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 951                 return -ENODEV;
 952 
 953         pr_debug(" -> %s:%d\n", __func__, __LINE__);
 954 
 955         /* ps3_repository_dump_bus_info(); */
 956 
 957         result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
 958 
 959         ps3_register_vuart_devices();
 960 
 961         ps3_register_graphics_devices();
 962 
 963         ps3_repository_find_devices(PS3_BUS_TYPE_SB, ps3_setup_static_device);
 964 
 965         ps3_register_sound_devices();
 966 
 967         ps3_register_lpm_devices();
 968 
 969         ps3_register_ramdisk_device();
 970 
 971         pr_debug(" <- %s:%d\n", __func__, __LINE__);
 972         return 0;
 973 }
 974 
 975 device_initcall(ps3_register_devices);

/* [<][>][^][v][top][bottom][index][help] */