cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

device-init.c (22786B)


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