1 # --- T2-COPYRIGHT-NOTE-BEGIN ---
2 # This copyright note is auto-generated by scripts/Create-CopyPatch.
4 # T2 SDE: architecture/powerpc64/package/.../0210-ps3encdec.patch
5 # Copyright (C) 2020 The T2 SDE Project
7 # More information can be found in the files COPYING and README.
9 # This patch file is dual-licensed. It is available under the license the
10 # patched project is licensed under, as long as it is an OpenSource license
11 # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
12 # of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
15 # --- T2-COPYRIGHT-NOTE-END ---
17 --- a/arch/powerpc/include/asm/ps3.h 2012-08-02 23:17:17.126972935 +0200
18 +++ b/arch/powerpc/include/asm/ps3.h 2012-08-06 19:41:56.754901977 +0200
20 PS3_MATCH_ID_LPM = 11,
21 PS3_MATCH_ID_STOR_NOR_FLASH = 12,
22 PS3_MATCH_ID_DISP_MANAGER = 13,
23 + PS3_MATCH_ID_STOR_ENCDEC = 14,
26 enum ps3_match_sub_id {
28 #define PS3_MODULE_ALIAS_LPM "ps3:11:0"
29 #define PS3_MODULE_ALIAS_STOR_NOR_FLASH "ps3:12:0"
30 #define PS3_MODULE_ALIAS_DISP_MANAGER "ps3:13:0"
31 +#define PS3_MODULE_ALIAS_STOR_ENCDEC "ps3:14:0"
33 enum ps3_system_bus_device_type {
34 PS3_DEVICE_TYPE_IOC0 = 1,
35 --- a/arch/powerpc/platforms/ps3/platform.h 2012-08-02 23:17:17.110306267 +0200
36 +++ b/arch/powerpc/platforms/ps3/platform.h 2012-08-06 19:42:30.948237298 +0200
38 PS3_DEV_TYPE_SB_GPIO = 6,
39 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
40 PS3_DEV_TYPE_STOR_NOR_FLASH = 254,
41 + PS3_DEV_TYPE_STOR_ENCDEC = 255,
44 int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
45 --- a/arch/powerpc/platforms/ps3/device-init.c 2012-08-02 23:17:17.130306269 +0200
46 +++ b/arch/powerpc/platforms/ps3/device-init.c 2012-08-06 19:43:12.538239719 +0200
51 + case PS3_DEV_TYPE_STOR_ENCDEC:
52 + result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ENCDEC);
54 + pr_debug("%s:%u ps3_setup_storage_dev failed\n",
55 + __func__, __LINE__);
60 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
61 --- a/arch/powerpc/platforms/ps3/system-bus.c 2012-08-02 23:17:17.126972935 +0200
62 +++ b/arch/powerpc/platforms/ps3/system-bus.c 2012-08-06 19:44:03.851576042 +0200
64 case PS3_MATCH_ID_STOR_ROM:
65 case PS3_MATCH_ID_STOR_FLASH:
66 case PS3_MATCH_ID_STOR_NOR_FLASH:
67 + case PS3_MATCH_ID_STOR_ENCDEC:
68 return ps3_open_hv_device_sb(dev);
70 case PS3_MATCH_ID_SOUND:
72 case PS3_MATCH_ID_STOR_ROM:
73 case PS3_MATCH_ID_STOR_FLASH:
74 case PS3_MATCH_ID_STOR_NOR_FLASH:
75 + case PS3_MATCH_ID_STOR_ENCDEC:
76 return ps3_close_hv_device_sb(dev);
78 case PS3_MATCH_ID_SOUND:
79 --- a/drivers/ps3/ps3stor_lib.c 2012-08-02 23:17:17.100306267 +0200
80 +++ b/drivers/ps3/ps3stor_lib.c 2012-08-06 20:43:55.981785017 +0200
85 - if (dev->sbd.match_id == PS3_MATCH_ID_STOR_ROM) {
86 - /* special case: CD-ROM is assumed always accessible */
87 + if ((dev->sbd.match_id == PS3_MATCH_ID_STOR_ROM) ||
88 + (dev->sbd.match_id == PS3_MATCH_ID_STOR_ENCDEC)) {
89 + /* special case: CD-ROM and ENCDEC are assumed always accessible */
90 dev->accessible_regions = 1;
93 --- a/arch/powerpc/platforms/ps3/Kconfig 2012-08-02 23:17:17.153639603 +0200
94 +++ b/arch/powerpc/platforms/ps3/Kconfig 2012-08-06 19:46:13.304916903 +0200
96 This driver allows you to create/delete/modify regions
97 on PS3 storage devices.
100 + tristate "PS3 ENCDEC Driver"
104 + Include support for the PS3 ENCDEC device.
106 + This support is required to access the PS3 ENCDEC device.
107 + In general, all users will say Y or M.
110 bool "PS3 udbg output via UDP broadcasts on Ethernet"
112 --- a/drivers/char/Makefile 2018-12-26 11:36:10.222679391 +0100
113 +++ b/drivers/char/Makefile 2018-12-26 11:37:07.674950989 +0100
116 obj-$(CONFIG_PS3_FLASH) += ps3flash.o
117 obj-$(CONFIG_PS3_STRGMNGR) += ps3strgmngr.o
118 +obj-$(CONFIG_PS3_ENCDEC) += ps3encdec.o
120 obj-$(CONFIG_XILLYBUS) += xillybus/
121 obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
122 --- /dev/null 2012-08-07 02:54:53.492474007 +0200
123 +++ b/drivers/char/ps3encdec.c 2012-08-07 02:56:38.822480157 +0200
126 + * PS3 ENCDEC Driver
128 + * Copyright (C) 2011 graf_chokolo <grafchokolo@gmail.com>
129 + * Copyright (C) 2011, 2012 glevand <geoffrey.levand@mail.ru>
130 + * Copyright (C) 2019-2021 René Rebe <rene@rebe.de>
131 + * All rights reserved.
133 + * This program is free software; you can redistribute it and/or modify it
134 + * under the terms of the GNU General Public License as published
135 + * by the Free Software Foundation; version 2 of the License.
137 + * This program is distributed in the hope that it will be useful, but
138 + * WITHOUT ANY WARRANTY; without even the implied warranty of
139 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
140 + * General Public License for more details.
142 + * You should have received a copy of the GNU General Public License along
143 + * with this program; if not, write to the Free Software Foundation, Inc.,
144 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
147 +#include <linux/module.h>
148 +#include <linux/kernel.h>
149 +#include <linux/init.h>
150 +#include <linux/slab.h>
151 +#include <linux/fs.h>
152 +#include <linux/sched.h>
153 +#include <linux/mutex.h>
154 +#include <linux/poll.h>
155 +#include <linux/uaccess.h>
156 +#include <linux/compat.h>
157 +#include <linux/miscdevice.h>
158 +#include <linux/sched/signal.h>
160 +#include <asm/ps3.h>
161 +#include <asm/lv1call.h>
162 +#include <asm/ps3stor.h>
163 +#include <asm/firmware.h>
165 +#define DEVICE_NAME "ps3encdec"
167 +#define BOUNCE_SIZE (4 * 1024)
169 +struct ps3encdec_private
171 + struct ps3_storage_device *dev;
172 + struct miscdevice misc;
178 + wait_queue_head_t read_wq;
179 + wait_queue_head_t write_wq;
182 + int cmd_data_avail;
185 +static struct ps3encdec_private *ps3encdec_priv;
187 +static ssize_t ps3encdec_read(struct file *file, char __user *usrbuf,
188 + size_t count, loff_t *pos)
190 + struct ps3encdec_private *priv = ps3encdec_priv;
193 + if (mutex_lock_interruptible(&priv->mtx))
194 + return (-ERESTARTSYS);
196 + if (file->f_flags & O_NONBLOCK) {
197 + if (!priv->cmd_done || priv->cmd_failed)
200 + DEFINE_WAIT(__wait);
203 + prepare_to_wait(&priv->read_wq, &__wait, TASK_INTERRUPTIBLE);
205 + if (priv->cmd_data_avail)
208 + mutex_unlock(&priv->mtx);
210 + if (signal_pending(current)) {
211 + finish_wait(&priv->read_wq, &__wait);
212 + return (-ERESTARTSYS);
217 + res = mutex_lock_interruptible(&priv->mtx);
219 + finish_wait(&priv->read_wq, &__wait);
224 + finish_wait(&priv->read_wq, &__wait);
230 + if (count > BOUNCE_SIZE)
231 + count = BOUNCE_SIZE;
233 + if (!count || (priv->cmd_done && priv->cmd_failed))
236 + if (copy_to_user(usrbuf, priv->bounce_rbuf + *pos, count)) {
241 + priv->cmd_data_avail = 0;
247 + mutex_unlock(&priv->mtx);
252 +static ssize_t ps3encdec_write(struct file *file, const char __user *usrbuf,
253 + size_t count, loff_t *pos)
255 + struct ps3encdec_private *priv = ps3encdec_priv;
256 + struct ps3_storage_device *dev = priv->dev;
260 + if (mutex_lock_interruptible(&priv->mtx))
261 + return (-ERESTARTSYS);
263 + if (file->f_flags & O_NONBLOCK) {
264 + if (!priv->cmd_done)
267 + DEFINE_WAIT(__wait);
270 + prepare_to_wait(&priv->write_wq, &__wait, TASK_INTERRUPTIBLE);
272 + if (priv->cmd_done)
275 + mutex_unlock(&priv->mtx);
277 + if (signal_pending(current)) {
278 + finish_wait(&priv->write_wq, &__wait);
279 + return (-ERESTARTSYS);
284 + res = mutex_lock_interruptible(&priv->mtx);
286 + finish_wait(&priv->write_wq, &__wait);
291 + finish_wait(&priv->write_wq, &__wait);
297 + if (count > BOUNCE_SIZE + sizeof(cmd))
298 + count = BOUNCE_SIZE + sizeof(cmd);
303 + if (count < sizeof(cmd)) {
308 + if (copy_from_user(&cmd, usrbuf, sizeof(cmd))) {
313 + if (copy_from_user(priv->bounce_wbuf, usrbuf + sizeof(cmd), count - sizeof(cmd))) {
318 + priv->cmd_done = 0;
319 + priv->cmd_failed = 1;
320 + priv->cmd_data_avail = 0;
322 + res = lv1_storage_send_device_command(dev->sbd.dev_id, cmd,
323 + priv->bounce_wlpar, count - sizeof(cmd),
324 + priv->bounce_rlpar, BOUNCE_SIZE, &dev->tag);
326 + dev_err(&dev->sbd.core, "%s:%u: res=%d\n",
327 + __func__, __LINE__, res);
328 + priv->cmd_done = 1;
337 + mutex_unlock(&priv->mtx);
342 +static unsigned int ps3encdec_poll(struct file *file, poll_table *wait)
344 + struct ps3encdec_private *priv = ps3encdec_priv;
345 + unsigned int mask = 0;
347 + mutex_lock(&priv->mtx);
349 + poll_wait(file, &priv->read_wq, wait);
350 + poll_wait(file, &priv->write_wq, wait);
352 + if (priv->cmd_data_avail)
353 + mask |= POLLIN | POLLRDNORM;
355 + if (priv->cmd_done)
356 + mask |= POLLOUT | POLLWRNORM;
358 + mutex_unlock(&priv->mtx);
363 +static irqreturn_t ps3encdec_interrupt(int irq, void *data)
365 + struct ps3_storage_device *dev = data;
366 + struct ps3encdec_private *priv;
370 + res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
372 + pr_info("%s:%d: res=%d status=%llx\n", __func__, __LINE__, res, status);
374 + if (tag != dev->tag) {
375 + dev_err(&dev->sbd.core,
376 + "%s:%u: tag mismatch, got %llx, expected %llx\n",
377 + __func__, __LINE__, tag, dev->tag);
381 + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
382 + __func__, __LINE__, res, status);
383 + return (IRQ_HANDLED);
386 + priv = ps3_system_bus_get_drvdata(&dev->sbd);
388 + priv->cmd_done = 1;
389 + priv->cmd_failed = (status != 0);
390 + priv->cmd_data_avail = !priv->cmd_failed;
392 + wake_up_interruptible(&priv->read_wq);
393 + wake_up_interruptible(&priv->write_wq);
395 + return (IRQ_HANDLED);
398 +static const struct file_operations ps3encdec_fops = {
399 + .owner = THIS_MODULE,
400 + .open = nonseekable_open,
401 + .read = ps3encdec_read,
402 + .write = ps3encdec_write,
403 + .poll = ps3encdec_poll,
406 +static int ps3encdec_probe(struct ps3_system_bus_device *_dev)
408 + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
409 + struct ps3encdec_private *priv;
412 + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
416 + ps3_system_bus_set_drvdata(_dev, priv);
418 + dev->bounce_size = BOUNCE_SIZE * 2;
419 + dev->bounce_buf = kmalloc(dev->bounce_size, GFP_DMA);
420 + if (!dev->bounce_buf) {
422 + goto fail_free_priv;
425 + res = ps3stor_setup(dev, ps3encdec_interrupt);
427 + goto fail_free_bounce;
429 + mutex_init(&priv->mtx);
431 + init_waitqueue_head(&priv->read_wq);
432 + init_waitqueue_head(&priv->write_wq);
434 + priv->cmd_done = 1;
435 + priv->cmd_failed = 0;
436 + priv->cmd_data_avail = 0;
438 + priv->misc.minor = MISC_DYNAMIC_MINOR,
439 + priv->misc.name = DEVICE_NAME,
440 + priv->misc.fops = &ps3encdec_fops,
442 + res = misc_register(&priv->misc);
444 + goto fail_teardown;
447 + priv->bounce_wbuf = dev->bounce_buf;
448 + priv->bounce_wlpar = dev->bounce_lpar;
449 + priv->bounce_rbuf = dev->bounce_buf + BOUNCE_SIZE;
450 + priv->bounce_rlpar = dev->bounce_lpar + BOUNCE_SIZE;
452 + ps3encdec_priv = priv;
458 + ps3stor_teardown(dev);
462 + kfree(dev->bounce_buf);
467 + ps3_system_bus_set_drvdata(_dev, NULL);
472 +static void ps3encdec_remove(struct ps3_system_bus_device *_dev)
474 + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
475 + struct ps3encdec_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
477 + ps3encdec_priv = NULL;
479 + misc_deregister(&priv->misc);
480 + ps3stor_teardown(dev);
481 + kfree(dev->bounce_buf);
483 + ps3_system_bus_set_drvdata(_dev, NULL);
486 +static struct ps3_system_bus_driver ps3encdec = {
487 + .match_id = PS3_MATCH_ID_STOR_ENCDEC,
488 + .core.name = DEVICE_NAME,
489 + .core.owner = THIS_MODULE,
490 + .probe = ps3encdec_probe,
491 + .remove = ps3encdec_remove,
492 + .shutdown = ps3encdec_remove,
495 +static int __init ps3encdec_init(void)
499 + if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
502 + res = ps3_system_bus_driver_register(&ps3encdec);
507 +static void __exit ps3encdec_exit(void)
509 + ps3_system_bus_driver_unregister(&ps3encdec);
512 +module_init(ps3encdec_init);
513 +module_exit(ps3encdec_exit);
515 +MODULE_AUTHOR("glevand");
516 +MODULE_DESCRIPTION("PS3 ENCDEC Driver");
517 +MODULE_LICENSE("GPL");
518 +MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_ENCDEC);