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