Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  PS3 device registration routines.
0004  *
0005  *  Copyright (C) 2007 Sony Computer Entertainment Inc.
0006  *  Copyright 2007 Sony Corp.
0007  */
0008 
0009 #include <linux/delay.h>
0010 #include <linux/freezer.h>
0011 #include <linux/kernel.h>
0012 #include <linux/kthread.h>
0013 #include <linux/init.h>
0014 #include <linux/slab.h>
0015 #include <linux/reboot.h>
0016 #include <linux/rcuwait.h>
0017 
0018 #include <asm/firmware.h>
0019 #include <asm/lv1call.h>
0020 #include <asm/ps3stor.h>
0021 
0022 #include "platform.h"
0023 
0024 static int __init ps3_register_lpm_devices(void)
0025 {
0026     int result;
0027     u64 tmp1;
0028     u64 tmp2;
0029     struct ps3_system_bus_device *dev;
0030 
0031     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0032 
0033     dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0034     if (!dev)
0035         return -ENOMEM;
0036 
0037     dev->match_id = PS3_MATCH_ID_LPM;
0038     dev->dev_type = PS3_DEVICE_TYPE_LPM;
0039 
0040     /* The current lpm driver only supports a single BE processor. */
0041 
0042     result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id);
0043 
0044     if (result) {
0045         pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n",
0046             __func__, __LINE__);
0047         goto fail_read_repo;
0048     }
0049 
0050     result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1,
0051         &dev->lpm.rights);
0052 
0053     if (result) {
0054         pr_debug("%s:%d: ps3_repository_read_lpm_privileges failed\n",
0055             __func__, __LINE__);
0056         goto fail_read_repo;
0057     }
0058 
0059     lv1_get_logical_partition_id(&tmp2);
0060 
0061     if (tmp1 != tmp2) {
0062         pr_debug("%s:%d: wrong lpar\n",
0063             __func__, __LINE__);
0064         result = -ENODEV;
0065         goto fail_rights;
0066     }
0067 
0068     if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) {
0069         pr_debug("%s:%d: don't have rights to use lpm\n",
0070             __func__, __LINE__);
0071         result = -EPERM;
0072         goto fail_rights;
0073     }
0074 
0075     pr_debug("%s:%d: pu_id %llu, rights %llu(%llxh)\n",
0076         __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights,
0077         dev->lpm.rights);
0078 
0079     result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id);
0080 
0081     if (result) {
0082         pr_debug("%s:%d: ps3_repository_read_pu_id failed \n",
0083             __func__, __LINE__);
0084         goto fail_read_repo;
0085     }
0086 
0087     result = ps3_system_bus_device_register(dev);
0088 
0089     if (result) {
0090         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0091             __func__, __LINE__);
0092         goto fail_register;
0093     }
0094 
0095     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0096     return 0;
0097 
0098 
0099 fail_register:
0100 fail_rights:
0101 fail_read_repo:
0102     kfree(dev);
0103     pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
0104     return result;
0105 }
0106 
0107 /**
0108  * ps3_setup_gelic_device - Setup and register a gelic device instance.
0109  *
0110  * Allocates memory for a struct ps3_system_bus_device instance, initialises the
0111  * structure members, and registers the device instance with the system bus.
0112  */
0113 
0114 static int __init ps3_setup_gelic_device(
0115     const struct ps3_repository_device *repo)
0116 {
0117     int result;
0118     struct layout {
0119         struct ps3_system_bus_device dev;
0120         struct ps3_dma_region d_region;
0121     } *p;
0122 
0123     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0124 
0125     BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
0126     BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
0127 
0128     p = kzalloc(sizeof(struct layout), GFP_KERNEL);
0129 
0130     if (!p) {
0131         result = -ENOMEM;
0132         goto fail_malloc;
0133     }
0134 
0135     p->dev.match_id = PS3_MATCH_ID_GELIC;
0136     p->dev.dev_type = PS3_DEVICE_TYPE_SB;
0137     p->dev.bus_id = repo->bus_id;
0138     p->dev.dev_id = repo->dev_id;
0139     p->dev.d_region = &p->d_region;
0140 
0141     result = ps3_repository_find_interrupt(repo,
0142         PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
0143 
0144     if (result) {
0145         pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
0146             __func__, __LINE__);
0147         goto fail_find_interrupt;
0148     }
0149 
0150     BUG_ON(p->dev.interrupt_id != 0);
0151 
0152     result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
0153         PS3_DMA_OTHER, NULL, 0);
0154 
0155     if (result) {
0156         pr_debug("%s:%d ps3_dma_region_init failed\n",
0157             __func__, __LINE__);
0158         goto fail_dma_init;
0159     }
0160 
0161     result = ps3_system_bus_device_register(&p->dev);
0162 
0163     if (result) {
0164         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0165             __func__, __LINE__);
0166         goto fail_device_register;
0167     }
0168 
0169     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0170     return result;
0171 
0172 fail_device_register:
0173 fail_dma_init:
0174 fail_find_interrupt:
0175     kfree(p);
0176 fail_malloc:
0177     pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
0178     return result;
0179 }
0180 
0181 static int __ref ps3_setup_uhc_device(
0182     const struct ps3_repository_device *repo, enum ps3_match_id match_id,
0183     enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
0184 {
0185     int result;
0186     struct layout {
0187         struct ps3_system_bus_device dev;
0188         struct ps3_dma_region d_region;
0189         struct ps3_mmio_region m_region;
0190     } *p;
0191     u64 bus_addr;
0192     u64 len;
0193 
0194     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0195 
0196     BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
0197     BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
0198 
0199     p = kzalloc(sizeof(struct layout), GFP_KERNEL);
0200 
0201     if (!p) {
0202         result = -ENOMEM;
0203         goto fail_malloc;
0204     }
0205 
0206     p->dev.match_id = match_id;
0207     p->dev.dev_type = PS3_DEVICE_TYPE_SB;
0208     p->dev.bus_id = repo->bus_id;
0209     p->dev.dev_id = repo->dev_id;
0210     p->dev.d_region = &p->d_region;
0211     p->dev.m_region = &p->m_region;
0212 
0213     result = ps3_repository_find_interrupt(repo,
0214         interrupt_type, &p->dev.interrupt_id);
0215 
0216     if (result) {
0217         pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
0218             __func__, __LINE__);
0219         goto fail_find_interrupt;
0220     }
0221 
0222     result = ps3_repository_find_reg(repo, reg_type,
0223         &bus_addr, &len);
0224 
0225     if (result) {
0226         pr_debug("%s:%d ps3_repository_find_reg failed\n",
0227             __func__, __LINE__);
0228         goto fail_find_reg;
0229     }
0230 
0231     result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
0232         PS3_DMA_INTERNAL, NULL, 0);
0233 
0234     if (result) {
0235         pr_debug("%s:%d ps3_dma_region_init failed\n",
0236             __func__, __LINE__);
0237         goto fail_dma_init;
0238     }
0239 
0240     result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
0241         PS3_MMIO_4K);
0242 
0243     if (result) {
0244         pr_debug("%s:%d ps3_mmio_region_init failed\n",
0245             __func__, __LINE__);
0246         goto fail_mmio_init;
0247     }
0248 
0249     result = ps3_system_bus_device_register(&p->dev);
0250 
0251     if (result) {
0252         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0253             __func__, __LINE__);
0254         goto fail_device_register;
0255     }
0256 
0257     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0258     return result;
0259 
0260 fail_device_register:
0261 fail_mmio_init:
0262 fail_dma_init:
0263 fail_find_reg:
0264 fail_find_interrupt:
0265     kfree(p);
0266 fail_malloc:
0267     pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
0268     return result;
0269 }
0270 
0271 static int __init ps3_setup_ehci_device(
0272     const struct ps3_repository_device *repo)
0273 {
0274     return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
0275         PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
0276 }
0277 
0278 static int __init ps3_setup_ohci_device(
0279     const struct ps3_repository_device *repo)
0280 {
0281     return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
0282         PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
0283 }
0284 
0285 static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
0286     unsigned int port_number)
0287 {
0288     int result;
0289     struct layout {
0290         struct ps3_system_bus_device dev;
0291     } *p;
0292 
0293     pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
0294         match_id, port_number);
0295 
0296     p = kzalloc(sizeof(struct layout), GFP_KERNEL);
0297 
0298     if (!p)
0299         return -ENOMEM;
0300 
0301     p->dev.match_id = match_id;
0302     p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
0303     p->dev.port_number = port_number;
0304 
0305     result = ps3_system_bus_device_register(&p->dev);
0306 
0307     if (result) {
0308         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0309             __func__, __LINE__);
0310         goto fail_device_register;
0311     }
0312     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0313     return 0;
0314 
0315 fail_device_register:
0316     kfree(p);
0317     pr_debug(" <- %s:%d fail\n", __func__, __LINE__);
0318     return result;
0319 }
0320 
0321 static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
0322                  enum ps3_match_id match_id)
0323 {
0324     int result;
0325     struct ps3_storage_device *p;
0326     u64 port, blk_size, num_blocks;
0327     unsigned int num_regions, i;
0328 
0329     pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);
0330 
0331     result = ps3_repository_read_stor_dev_info(repo->bus_index,
0332                            repo->dev_index, &port,
0333                            &blk_size, &num_blocks,
0334                            &num_regions);
0335     if (result) {
0336         printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",
0337                __func__, __LINE__, result);
0338         return -ENODEV;
0339     }
0340 
0341     pr_debug("%s:%u: (%u:%u:%u): port %llu blk_size %llu num_blocks %llu "
0342          "num_regions %u\n", __func__, __LINE__, repo->bus_index,
0343          repo->dev_index, repo->dev_type, port, blk_size, num_blocks,
0344          num_regions);
0345 
0346     p = kzalloc(struct_size(p, regions, num_regions), GFP_KERNEL);
0347     if (!p) {
0348         result = -ENOMEM;
0349         goto fail_malloc;
0350     }
0351 
0352     p->sbd.match_id = match_id;
0353     p->sbd.dev_type = PS3_DEVICE_TYPE_SB;
0354     p->sbd.bus_id = repo->bus_id;
0355     p->sbd.dev_id = repo->dev_id;
0356     p->sbd.d_region = &p->dma_region;
0357     p->blk_size = blk_size;
0358     p->num_regions = num_regions;
0359 
0360     result = ps3_repository_find_interrupt(repo,
0361                            PS3_INTERRUPT_TYPE_EVENT_PORT,
0362                            &p->sbd.interrupt_id);
0363     if (result) {
0364         printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,
0365                __LINE__, result);
0366         result = -ENODEV;
0367         goto fail_find_interrupt;
0368     }
0369 
0370     for (i = 0; i < num_regions; i++) {
0371         unsigned int id;
0372         u64 start, size;
0373 
0374         result = ps3_repository_read_stor_dev_region(repo->bus_index,
0375                                  repo->dev_index,
0376                                  i, &id, &start,
0377                                  &size);
0378         if (result) {
0379             printk(KERN_ERR
0380                    "%s:%u: read_stor_dev_region failed %d\n",
0381                    __func__, __LINE__, result);
0382             result = -ENODEV;
0383             goto fail_read_region;
0384         }
0385         pr_debug("%s:%u: region %u: id %u start %llu size %llu\n",
0386              __func__, __LINE__, i, id, start, size);
0387 
0388         p->regions[i].id = id;
0389         p->regions[i].start = start;
0390         p->regions[i].size = size;
0391     }
0392 
0393     result = ps3_system_bus_device_register(&p->sbd);
0394     if (result) {
0395         pr_debug("%s:%u ps3_system_bus_device_register failed\n",
0396              __func__, __LINE__);
0397         goto fail_device_register;
0398     }
0399 
0400     pr_debug(" <- %s:%u\n", __func__, __LINE__);
0401     return 0;
0402 
0403 fail_device_register:
0404 fail_read_region:
0405 fail_find_interrupt:
0406     kfree(p);
0407 fail_malloc:
0408     pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);
0409     return result;
0410 }
0411 
0412 static int __init ps3_register_vuart_devices(void)
0413 {
0414     int result;
0415     unsigned int port_number;
0416 
0417     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0418 
0419     result = ps3_repository_read_vuart_av_port(&port_number);
0420     if (result)
0421         port_number = 0; /* av default */
0422 
0423     result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
0424     WARN_ON(result);
0425 
0426     result = ps3_repository_read_vuart_sysmgr_port(&port_number);
0427     if (result)
0428         port_number = 2; /* sysmgr default */
0429 
0430     result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
0431         port_number);
0432     WARN_ON(result);
0433 
0434     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0435     return result;
0436 }
0437 
0438 static int __init ps3_register_sound_devices(void)
0439 {
0440     int result;
0441     struct layout {
0442         struct ps3_system_bus_device dev;
0443         struct ps3_dma_region d_region;
0444         struct ps3_mmio_region m_region;
0445     } *p;
0446 
0447     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0448 
0449     p = kzalloc(sizeof(*p), GFP_KERNEL);
0450     if (!p)
0451         return -ENOMEM;
0452 
0453     p->dev.match_id = PS3_MATCH_ID_SOUND;
0454     p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
0455     p->dev.d_region = &p->d_region;
0456     p->dev.m_region = &p->m_region;
0457 
0458     result = ps3_system_bus_device_register(&p->dev);
0459 
0460     if (result) {
0461         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0462             __func__, __LINE__);
0463         goto fail_device_register;
0464     }
0465     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0466     return 0;
0467 
0468 fail_device_register:
0469     kfree(p);
0470     pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
0471     return result;
0472 }
0473 
0474 static int __init ps3_register_graphics_devices(void)
0475 {
0476     int result;
0477     struct layout {
0478         struct ps3_system_bus_device dev;
0479     } *p;
0480 
0481     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0482 
0483     p = kzalloc(sizeof(struct layout), GFP_KERNEL);
0484 
0485     if (!p)
0486         return -ENOMEM;
0487 
0488     p->dev.match_id = PS3_MATCH_ID_GPU;
0489     p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_FB;
0490     p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
0491 
0492     result = ps3_system_bus_device_register(&p->dev);
0493 
0494     if (result) {
0495         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0496             __func__, __LINE__);
0497         goto fail_device_register;
0498     }
0499 
0500     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0501     return 0;
0502 
0503 fail_device_register:
0504     kfree(p);
0505     pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
0506     return result;
0507 }
0508 
0509 static int __init ps3_register_ramdisk_device(void)
0510 {
0511     int result;
0512     struct layout {
0513         struct ps3_system_bus_device dev;
0514     } *p;
0515 
0516     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0517 
0518     p = kzalloc(sizeof(struct layout), GFP_KERNEL);
0519 
0520     if (!p)
0521         return -ENOMEM;
0522 
0523     p->dev.match_id = PS3_MATCH_ID_GPU;
0524     p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK;
0525     p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
0526 
0527     result = ps3_system_bus_device_register(&p->dev);
0528 
0529     if (result) {
0530         pr_debug("%s:%d ps3_system_bus_device_register failed\n",
0531             __func__, __LINE__);
0532         goto fail_device_register;
0533     }
0534 
0535     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0536     return 0;
0537 
0538 fail_device_register:
0539     kfree(p);
0540     pr_debug(" <- %s:%d failed\n", __func__, __LINE__);
0541     return result;
0542 }
0543 
0544 /**
0545  * ps3_setup_dynamic_device - Setup a dynamic device from the repository
0546  */
0547 
0548 static int ps3_setup_dynamic_device(const struct ps3_repository_device *repo)
0549 {
0550     int result;
0551 
0552     switch (repo->dev_type) {
0553     case PS3_DEV_TYPE_STOR_DISK:
0554         result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);
0555 
0556         /* Some devices are not accessible from the Other OS lpar. */
0557         if (result == -ENODEV) {
0558             result = 0;
0559             pr_debug("%s:%u: not accessible\n", __func__,
0560                  __LINE__);
0561         }
0562 
0563         if (result)
0564             pr_debug("%s:%u ps3_setup_storage_dev failed\n",
0565                  __func__, __LINE__);
0566         break;
0567 
0568     case PS3_DEV_TYPE_STOR_ROM:
0569         result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);
0570         if (result)
0571             pr_debug("%s:%u ps3_setup_storage_dev failed\n",
0572                  __func__, __LINE__);
0573         break;
0574 
0575     case PS3_DEV_TYPE_STOR_FLASH:
0576         result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);
0577         if (result)
0578             pr_debug("%s:%u ps3_setup_storage_dev failed\n",
0579                  __func__, __LINE__);
0580         break;
0581 
0582     default:
0583         result = 0;
0584         pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
0585             repo->dev_type);
0586     }
0587 
0588     return result;
0589 }
0590 
0591 /**
0592  * ps3_setup_static_device - Setup a static device from the repository
0593  */
0594 
0595 static int __init ps3_setup_static_device(const struct ps3_repository_device *repo)
0596 {
0597     int result;
0598 
0599     switch (repo->dev_type) {
0600     case PS3_DEV_TYPE_SB_GELIC:
0601         result = ps3_setup_gelic_device(repo);
0602         if (result) {
0603             pr_debug("%s:%d ps3_setup_gelic_device failed\n",
0604                 __func__, __LINE__);
0605         }
0606         break;
0607     case PS3_DEV_TYPE_SB_USB:
0608 
0609         /* Each USB device has both an EHCI and an OHCI HC */
0610 
0611         result = ps3_setup_ehci_device(repo);
0612 
0613         if (result) {
0614             pr_debug("%s:%d ps3_setup_ehci_device failed\n",
0615                 __func__, __LINE__);
0616         }
0617 
0618         result = ps3_setup_ohci_device(repo);
0619 
0620         if (result) {
0621             pr_debug("%s:%d ps3_setup_ohci_device failed\n",
0622                 __func__, __LINE__);
0623         }
0624         break;
0625 
0626     default:
0627         return ps3_setup_dynamic_device(repo);
0628     }
0629 
0630     return result;
0631 }
0632 
0633 static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
0634 {
0635     struct ps3_repository_device repo;
0636     int res;
0637     unsigned int retries;
0638     unsigned long rem;
0639 
0640     /*
0641      * On some firmware versions (e.g. 1.90), the device may not show up
0642      * in the repository immediately
0643      */
0644     for (retries = 0; retries < 10; retries++) {
0645         res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
0646         if (!res)
0647             goto found;
0648 
0649         rem = msleep_interruptible(100);
0650         if (rem)
0651             break;
0652     }
0653     pr_warn("%s:%u: device %llu:%llu not found\n",
0654         __func__, __LINE__, bus_id, dev_id);
0655     return;
0656 
0657 found:
0658     if (retries)
0659         pr_debug("%s:%u: device %llu:%llu found after %u retries\n",
0660              __func__, __LINE__, bus_id, dev_id, retries);
0661 
0662     ps3_setup_dynamic_device(&repo);
0663     return;
0664 }
0665 
0666 #define PS3_NOTIFICATION_DEV_ID     ULONG_MAX
0667 #define PS3_NOTIFICATION_INTERRUPT_ID   0
0668 
0669 struct ps3_notification_device {
0670     struct ps3_system_bus_device sbd;
0671     spinlock_t lock;
0672     u64 tag;
0673     u64 lv1_status;
0674     struct rcuwait wait;
0675     bool done;
0676 };
0677 
0678 enum ps3_notify_type {
0679     notify_device_ready = 0,
0680     notify_region_probe = 1,
0681     notify_region_update = 2,
0682 };
0683 
0684 struct ps3_notify_cmd {
0685     u64 operation_code;     /* must be zero */
0686     u64 event_mask;         /* OR of 1UL << enum ps3_notify_type */
0687 };
0688 
0689 struct ps3_notify_event {
0690     u64 event_type;         /* enum ps3_notify_type */
0691     u64 bus_id;
0692     u64 dev_id;
0693     u64 dev_type;
0694     u64 dev_port;
0695 };
0696 
0697 static irqreturn_t ps3_notification_interrupt(int irq, void *data)
0698 {
0699     struct ps3_notification_device *dev = data;
0700     int res;
0701     u64 tag, status;
0702 
0703     spin_lock(&dev->lock);
0704     res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag,
0705                        &status);
0706     if (tag != dev->tag)
0707         pr_err("%s:%u: tag mismatch, got %llx, expected %llx\n",
0708                __func__, __LINE__, tag, dev->tag);
0709 
0710     if (res) {
0711         pr_err("%s:%u: res %d status 0x%llx\n", __func__, __LINE__, res,
0712                status);
0713     } else {
0714         pr_debug("%s:%u: completed, status 0x%llx\n", __func__,
0715              __LINE__, status);
0716         dev->lv1_status = status;
0717         dev->done = true;
0718         rcuwait_wake_up(&dev->wait);
0719     }
0720     spin_unlock(&dev->lock);
0721     return IRQ_HANDLED;
0722 }
0723 
0724 static int ps3_notification_read_write(struct ps3_notification_device *dev,
0725                        u64 lpar, int write)
0726 {
0727     const char *op = write ? "write" : "read";
0728     unsigned long flags;
0729     int res;
0730 
0731     spin_lock_irqsave(&dev->lock, flags);
0732     res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
0733                     &dev->tag)
0734             : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
0735                        &dev->tag);
0736     dev->done = false;
0737     spin_unlock_irqrestore(&dev->lock, flags);
0738     if (res) {
0739         pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res);
0740         return -EPERM;
0741     }
0742     pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op);
0743 
0744     rcuwait_wait_event(&dev->wait, dev->done || kthread_should_stop(), TASK_IDLE);
0745 
0746     if (kthread_should_stop())
0747         res = -EINTR;
0748 
0749     if (dev->lv1_status) {
0750         pr_err("%s:%u: %s not completed, status 0x%llx\n", __func__,
0751                __LINE__, op, dev->lv1_status);
0752         return -EIO;
0753     }
0754     pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op);
0755 
0756     return 0;
0757 }
0758 
0759 static struct task_struct *probe_task;
0760 
0761 /**
0762  * ps3_probe_thread - Background repository probing at system startup.
0763  *
0764  * This implementation only supports background probing on a single bus.
0765  * It uses the hypervisor's storage device notification mechanism to wait until
0766  * a storage device is ready.  The device notification mechanism uses a
0767  * pseudo device to asynchronously notify the guest when storage devices become
0768  * ready.  The notification device has a block size of 512 bytes.
0769  */
0770 
0771 static int ps3_probe_thread(void *data)
0772 {
0773     struct ps3_notification_device dev;
0774     int res;
0775     unsigned int irq;
0776     u64 lpar;
0777     void *buf;
0778     struct ps3_notify_cmd *notify_cmd;
0779     struct ps3_notify_event *notify_event;
0780 
0781     pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
0782 
0783     buf = kzalloc(512, GFP_KERNEL);
0784     if (!buf)
0785         return -ENOMEM;
0786 
0787     lpar = ps3_mm_phys_to_lpar(__pa(buf));
0788     notify_cmd = buf;
0789     notify_event = buf;
0790 
0791     /* dummy system bus device */
0792     dev.sbd.bus_id = (u64)data;
0793     dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
0794     dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
0795 
0796     res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
0797     if (res) {
0798         pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
0799                __LINE__, ps3_result(res));
0800         goto fail_free;
0801     }
0802 
0803     res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
0804                           &irq);
0805     if (res) {
0806         pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
0807                __func__, __LINE__, res);
0808            goto fail_close_device;
0809     }
0810 
0811     spin_lock_init(&dev.lock);
0812     rcuwait_init(&dev.wait);
0813 
0814     res = request_irq(irq, ps3_notification_interrupt, 0,
0815               "ps3_notification", &dev);
0816     if (res) {
0817         pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
0818                res);
0819         goto fail_sb_event_receive_port_destroy;
0820     }
0821 
0822     /* Setup and write the request for device notification. */
0823     notify_cmd->operation_code = 0; /* must be zero */
0824     notify_cmd->event_mask = 1UL << notify_region_probe;
0825 
0826     res = ps3_notification_read_write(&dev, lpar, 1);
0827     if (res)
0828         goto fail_free_irq;
0829 
0830     /* Loop here processing the requested notification events. */
0831     do {
0832         try_to_freeze();
0833 
0834         memset(notify_event, 0, sizeof(*notify_event));
0835 
0836         res = ps3_notification_read_write(&dev, lpar, 0);
0837         if (res)
0838             break;
0839 
0840         pr_debug("%s:%u: notify event type 0x%llx bus id %llu dev id %llu"
0841              " type %llu port %llu\n", __func__, __LINE__,
0842              notify_event->event_type, notify_event->bus_id,
0843              notify_event->dev_id, notify_event->dev_type,
0844              notify_event->dev_port);
0845 
0846         if (notify_event->event_type != notify_region_probe ||
0847             notify_event->bus_id != dev.sbd.bus_id) {
0848             pr_warn("%s:%u: bad notify_event: event %llu, dev_id %llu, dev_type %llu\n",
0849                 __func__, __LINE__, notify_event->event_type,
0850                 notify_event->dev_id, notify_event->dev_type);
0851             continue;
0852         }
0853 
0854         ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
0855 
0856     } while (!kthread_should_stop());
0857 
0858 fail_free_irq:
0859     free_irq(irq, &dev);
0860 fail_sb_event_receive_port_destroy:
0861     ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
0862 fail_close_device:
0863     lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
0864 fail_free:
0865     kfree(buf);
0866 
0867     probe_task = NULL;
0868 
0869     pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
0870 
0871     return 0;
0872 }
0873 
0874 /**
0875  * ps3_stop_probe_thread - Stops the background probe thread.
0876  *
0877  */
0878 
0879 static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code,
0880                  void *data)
0881 {
0882     if (probe_task)
0883         kthread_stop(probe_task);
0884     return 0;
0885 }
0886 
0887 static struct notifier_block nb = {
0888     .notifier_call = ps3_stop_probe_thread
0889 };
0890 
0891 /**
0892  * ps3_start_probe_thread - Starts the background probe thread.
0893  *
0894  */
0895 
0896 static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
0897 {
0898     int result;
0899     struct task_struct *task;
0900     struct ps3_repository_device repo;
0901 
0902     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0903 
0904     memset(&repo, 0, sizeof(repo));
0905 
0906     repo.bus_type = bus_type;
0907 
0908     result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
0909 
0910     if (result) {
0911         printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
0912         return -ENODEV;
0913     }
0914 
0915     result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
0916 
0917     if (result) {
0918         printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
0919             result);
0920         return -ENODEV;
0921     }
0922 
0923     task = kthread_run(ps3_probe_thread, (void *)repo.bus_id,
0924                "ps3-probe-%u", bus_type);
0925 
0926     if (IS_ERR(task)) {
0927         result = PTR_ERR(task);
0928         printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
0929                result);
0930         return result;
0931     }
0932 
0933     probe_task = task;
0934     register_reboot_notifier(&nb);
0935 
0936     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0937     return 0;
0938 }
0939 
0940 /**
0941  * ps3_register_devices - Probe the system and register devices found.
0942  *
0943  * A device_initcall() routine.
0944  */
0945 
0946 static int __init ps3_register_devices(void)
0947 {
0948     int result;
0949 
0950     if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
0951         return -ENODEV;
0952 
0953     pr_debug(" -> %s:%d\n", __func__, __LINE__);
0954 
0955     /* ps3_repository_dump_bus_info(); */
0956 
0957     result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
0958 
0959     ps3_register_vuart_devices();
0960 
0961     ps3_register_graphics_devices();
0962 
0963     ps3_repository_find_devices(PS3_BUS_TYPE_SB, ps3_setup_static_device);
0964 
0965     ps3_register_sound_devices();
0966 
0967     ps3_register_lpm_devices();
0968 
0969     ps3_register_ramdisk_device();
0970 
0971     pr_debug(" <- %s:%d\n", __func__, __LINE__);
0972     return 0;
0973 }
0974 
0975 device_initcall(ps3_register_devices);