ui/ncurses: Always provide a key definition for backtab
[petitboot] / ui / common / ps3.c
1 /*
2  *  Copyright (C) 2009 Sony Computer Entertainment Inc.
3  *  Copyright 2009 Sony Corp.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #if defined(HAVE_CONFIG_H)
20 #include "config.h"
21 #endif
22
23 #include <assert.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/ioctl.h>
29 #include <ps3-flash.h>
30 #include <ps3-av.h>
31
32 #include "log/log.h"
33 #include "ui-system.h"
34 #include "ps3.h"
35
36 static const char flash_dev[] = "/dev/ps3flash";
37 static const char fb_dev[] = "/dev/fb0";
38
39 static const struct os_area_db_id id_default_item =
40 {
41         .owner = OS_AREA_DB_OWNER_PETITBOOT, /* 3 */
42         .key = 1,
43 };
44 static const struct os_area_db_id id_video_mode =
45 {
46         .owner = OS_AREA_DB_OWNER_PETITBOOT, /* 3 */
47         .key = OS_AREA_DB_KEY_VIDEO_MODE,    /* 2 */
48 };
49 static const struct os_area_db_id id_flags =
50 {
51         .owner = OS_AREA_DB_OWNER_PETITBOOT, /* 3 */
52         .key = 3,
53 };
54 static const struct os_area_db_id id_timeout =
55 {
56         .owner = OS_AREA_DB_OWNER_PETITBOOT, /* 3 */
57         .key = 4,
58 };
59
60 struct ps3_flash_ctx {
61         FILE *dev;
62         struct os_area_header header;
63         struct os_area_params params;
64         struct os_area_db db;
65 };
66
67 static void ps3_flash_close(struct ps3_flash_ctx *fc)
68 {
69         assert(fc->dev);
70
71         fclose(fc->dev);
72         fc->dev = NULL;
73 }
74
75 static int ps3_flash_open(struct ps3_flash_ctx *fc, const char *mode)
76 {
77         int result;
78
79         fc->dev = fopen(flash_dev, mode);
80
81         if (!fc->dev) {
82                 pb_log("%s: fopen failed: %s: %s\n", __func__, strerror(errno),
83                         flash_dev);
84                 return -1;
85         }
86
87         os_area_set_log_stream(pb_log_get_stream());
88
89         result = os_area_fixed_read(&fc->header, &fc->params, fc->dev);
90
91         if (result) {
92                 pb_log("%s: os_area_fixed_read failed\n", __func__);
93                 goto fail;
94         }
95
96         return 0;
97
98 fail:
99         ps3_flash_close(fc);
100         return -1;
101 }
102
103 /**
104  * ps3_flash_get_values - Read values from the PS3 flash memory database.
105  *
106  * Returns zero on success.
107  */
108
109 int ps3_flash_get_values(struct ps3_flash_values *values)
110 {
111         int result;
112         int sum;
113         struct ps3_flash_ctx fc;
114         uint64_t tmp;
115
116         result = ps3_flash_open(&fc, "r");
117
118         if (result)
119                 goto fail;
120
121         result = os_area_db_read(&fc.db, &fc.header, fc.dev);
122
123         ps3_flash_close(&fc);
124
125         if (result) {
126                 pb_log("%s: os_area_db_read failed: %s\n", __func__,
127                         strerror(errno));
128                 goto fail;
129         }
130
131         sum = result = os_area_db_get(&fc.db, &id_default_item, &tmp);
132
133         if (!result)
134                 values->default_item = (uint32_t)tmp;
135
136         result = os_area_db_get(&fc.db, &id_timeout, &tmp);
137
138         if (!result)
139                 values->timeout = (uint8_t)tmp;
140
141         sum += result = os_area_db_get(&fc.db, &id_video_mode, &tmp);
142
143         if (!result)
144                 values->video_mode = (uint16_t)tmp;
145
146         pb_debug("%s: default_item: %x\n", __func__,
147                 (unsigned int)values->default_item);
148         pb_debug("%s: timeout: %u\n", __func__,
149                 (unsigned int)values->timeout);
150         pb_debug("%s: video_mode:   %u\n", __func__,
151                 (unsigned int)values->video_mode);
152 fail:
153         return (result || sum) ? -1 : 0;
154 }
155
156 /**
157  * ps3_flash_set_values - Writes values from the PS3 flash memory database.
158  *
159  * Formats the flash database before writing if a valid database if not found.
160  * Returns zero on success.
161  */
162
163 int ps3_flash_set_values(const struct ps3_flash_values *values)
164 {
165         int result;
166         struct ps3_flash_ctx fc;
167
168         pb_debug("%s: default_item: %u\n", __func__, values->default_item);
169         pb_debug("%s: video_mode:   %u\n", __func__, values->video_mode);
170
171         result = ps3_flash_open(&fc, "r+");
172
173         if (result)
174                 return result;
175
176         result = os_area_db_read(&fc.db, &fc.header, fc.dev);
177
178         if (result) {
179                 pb_log("%s: os_area_db_read failed: %s\n", __func__,
180                         strerror(errno));
181                 pb_log("%s: formating db\n", __func__);
182
183                 result = os_area_db_format(&fc.db, &fc.header, fc.dev);
184
185                 if (result) {
186                         pb_log("%s: db_format failed: %s\n", __func__,
187                                 strerror(errno));
188                         goto fail;
189                 }
190         }
191
192         /* timeout is currently read-only, set with ps3-bl-option */
193
194         result = os_area_db_set_32(&fc.db, &id_default_item,
195                 values->default_item);
196         result += os_area_db_set_16(&fc.db, &id_video_mode,
197                 values->video_mode);
198
199         result += os_area_db_write(&fc.db, &fc.header, fc.dev);
200
201         ps3_flash_close(&fc);
202         return result;
203
204 fail:
205         ps3_flash_close(&fc);
206         return -1;
207 }
208
209 /**
210  * ps3_video_ioctl - Low level ioctl helper.
211  *
212  * Use ps3_get_video_mode or ps3_set_video_mode().
213  */
214
215 static int ps3_video_ioctl(int request, unsigned int *mode_id)
216 {
217         int result;
218         int fd;
219
220         fd = open(fb_dev, O_RDWR);
221
222         if (fd < 0) {
223                 pb_log("%s: open failed: %s: %s\n", __func__, strerror(errno),
224                         fb_dev);
225                 return -1;
226         }
227
228         result = ioctl(fd, request, (unsigned long)mode_id);
229
230         close(fd);
231
232         if (result < 0) {
233                 pb_log("%s: ioctl failed: %s: %s\n", __func__, strerror(errno),
234                         fb_dev);
235                 return -1;
236         }
237
238         return 0;
239 }
240
241 /**
242  * ps3_set_video_mode - Set the PS3 video mode.
243  * @mode_id: The PS3 video mode_id as documented in the ps3-video-mode man page.
244  *
245  * Returns zero on success.
246  */
247
248 int ps3_set_video_mode(unsigned int mode_id)
249 {
250         pb_debug("%s: %u\n", __func__, mode_id);
251         return ps3_video_ioctl(PS3FB_IOCTL_SETMODE, &mode_id);
252 }
253
254 /**
255  * ps3_set_video_mode - Get the current PS3 video mode.
256  * @mode_id: The PS3 video mode_id as documented in the ps3-video-mode man page.
257  *
258  * Returns zero on success.
259  */
260
261 int ps3_get_video_mode(unsigned int *mode_id)
262 {
263         int result;
264
265         *mode_id = 0;
266
267         result =  ps3_video_ioctl(PS3FB_IOCTL_GETMODE, mode_id);
268
269         pb_log("%s: %u\n", __func__, *mode_id);
270         return result;
271 }