0001
0002
0003
0004
0005
0006
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
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
0109
0110
0111
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;
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;
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
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
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
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
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
0642
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;
0686 u64 event_mask;
0687 };
0688
0689 struct ps3_notify_event {
0690 u64 event_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
0763
0764
0765
0766
0767
0768
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
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
0823 notify_cmd->operation_code = 0;
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
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
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
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
0942
0943
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
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);