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