1 |
/********************************************************************* |
2 |
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se) |
3 |
* Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) |
4 |
* This file is subject to the terms and conditions of the PS2Link License. |
5 |
* See the file LICENSE in the main directory of this distribution for more |
6 |
* details. |
7 |
*/ |
8 |
|
9 |
#include <types.h> |
10 |
#include <thbase.h> |
11 |
#include <ioman.h> |
12 |
#include <sysclib.h> |
13 |
#include <stdio.h> |
14 |
#include <intrman.h> |
15 |
#include <loadcore.h> |
16 |
#include <thsemap.h> |
17 |
|
18 |
#include "net_fio.h" |
19 |
|
20 |
#define IOCTL_RENAME 0xFEEDC0DE //dlanor: Used for the Ioctl request code => Rename |
21 |
|
22 |
#ifdef DEBUG |
23 |
#define dbgprintf(args...) printf(args) |
24 |
#else |
25 |
#define dbgprintf(args...) do { } while(0) |
26 |
#endif |
27 |
|
28 |
static char fsname[] = "host"; |
29 |
|
30 |
//---------------------------------------------------------------------------- |
31 |
|
32 |
/* File desc struct is probably larger than this, but we only |
33 |
* need to access the word @ offset 0x0C (in which we put our identifier) |
34 |
*/ |
35 |
struct filedesc_info |
36 |
{ |
37 |
int unkn0; |
38 |
int unkn4; |
39 |
int device_id; // the X in hostX |
40 |
int own_fd; |
41 |
}; |
42 |
//dlanor: In fact this struct is declared elsewhere as iop_file_t, with |
43 |
//dlanor: well known fields. The one declared as "int own_fd;" above is |
44 |
//dlanor: there declared as "void *privdata;" but it doesn't matter, as |
45 |
//dlanor: it is up to each driver how to use that field. So using it as |
46 |
//dlanor: a simple "int" instead of a pointer will work fine. |
47 |
|
48 |
|
49 |
//---------------------------------------------------------------------------- |
50 |
/* We need(?) to protect the net access, so the server doesn't get |
51 |
* confused if two processes calls a fsys func at the same time |
52 |
*/ |
53 |
static int fsys_sema; |
54 |
static int fsys_pid = 0; |
55 |
|
56 |
//---------------------------------------------------------------------------- |
57 |
//dlanor: We need variables to remember a file/folder descriptor used |
58 |
//dlanor: with the Ioctl Rename function, so that we can avoid passing |
59 |
//dlanor: the following fioClose call to PC, where it's already closed. |
60 |
//dlanor: We also need a flag to note when we must ignore an Mkdir call |
61 |
//dlanor: because it is caused by the bug IOMAN.IRX has for fioRemove. |
62 |
// |
63 |
int lastopen_fd; //descriptor of the most recently opened file/folder |
64 |
int renamed_fd; //descriptor of renamed file/folder awaiting closure |
65 |
int remove_flag=0; //Set in fsysRemove, cleared by all other fsysXXXXX |
66 |
int remove_result; //Set in fsysRemove, so fsysMkdir can use it for bug |
67 |
|
68 |
typedef void (*th_func_p)(void *); //dlanor: added to suppress warnings |
69 |
|
70 |
//---------------------------------------------------------------------------- |
71 |
static void fsysInit(iop_device_t *driver) |
72 |
{ |
73 |
struct _iop_thread mythread; |
74 |
int pid; |
75 |
int i; |
76 |
|
77 |
dbgprintf("initializing %s\n", driver->name); |
78 |
|
79 |
remove_flag = 0; |
80 |
|
81 |
// Start socket server thread |
82 |
|
83 |
mythread.attr = 0x02000000; // attr |
84 |
mythread.option = 0; // option |
85 |
mythread.thread = (th_func_p) pko_file_serv; // entry |
86 |
mythread.stacksize = 0x800; |
87 |
mythread.priority = 0x45; // We really should choose prio w more effort |
88 |
|
89 |
pid = CreateThread(&mythread); |
90 |
|
91 |
if (pid > 0) { |
92 |
if ((i=StartThread(pid, NULL)) < 0) { |
93 |
printf("StartThread failed (%d)\n", i); |
94 |
} |
95 |
} |
96 |
else { |
97 |
printf("CreateThread failed (%d)\n", pid); |
98 |
} |
99 |
|
100 |
fsys_pid = pid; |
101 |
dbgprintf("Thread id: %x\n", pid); |
102 |
} |
103 |
//---------------------------------------------------------------------------- |
104 |
static int fsysDestroy(void) |
105 |
{ |
106 |
remove_flag = 0; |
107 |
|
108 |
WaitSema(fsys_sema); |
109 |
pko_close_fsys(); |
110 |
// ExitDeleteThread(fsys_pid); |
111 |
SignalSema(fsys_sema); |
112 |
DeleteSema(fsys_sema); |
113 |
return 0; |
114 |
} |
115 |
|
116 |
|
117 |
//---------------------------------------------------------------------------- |
118 |
static int dummyFormat() |
119 |
{ |
120 |
remove_flag = 0; |
121 |
|
122 |
printf("dummy Format function called\n"); |
123 |
return -5; |
124 |
} |
125 |
//---------------------------------------------------------------------------- |
126 |
static int fsysOpen( int fd, char *name, int mode) |
127 |
{ |
128 |
struct filedesc_info *fd_info; |
129 |
int fsys_fd; |
130 |
|
131 |
dbgprintf("fsysOpen..\n"); |
132 |
dbgprintf(" fd: %x, name: %s, mode: %d\n\n", fd, name, mode); |
133 |
|
134 |
remove_flag = 0; |
135 |
|
136 |
fd_info = (struct filedesc_info *)fd; |
137 |
|
138 |
WaitSema(fsys_sema); |
139 |
fsys_fd = pko_open_file(name, mode); |
140 |
SignalSema(fsys_sema); |
141 |
fd_info->own_fd = fsys_fd; |
142 |
renamed_fd = -1; |
143 |
lastopen_fd = fsys_fd; |
144 |
|
145 |
return fsys_fd; |
146 |
} |
147 |
//---------------------------------------------------------------------------- |
148 |
static int fsysClose( int fd) |
149 |
{ |
150 |
int remote_fd = ((struct filedesc_info *)fd)->own_fd; |
151 |
int ret; |
152 |
|
153 |
dbgprintf("fsys_close..\n" |
154 |
" fd: %x\n\n", fd); |
155 |
|
156 |
remove_flag = 0; |
157 |
|
158 |
if (remote_fd != renamed_fd){ |
159 |
WaitSema(fsys_sema); |
160 |
ret = pko_close_file(remote_fd); |
161 |
SignalSema(fsys_sema); |
162 |
} else ret = 0; |
163 |
renamed_fd = -1; |
164 |
|
165 |
return ret; |
166 |
} |
167 |
//---------------------------------------------------------------------------- |
168 |
static int fsysRead( int fd, char *buf, int size) |
169 |
{ |
170 |
struct filedesc_info *fd_info; |
171 |
int ret; |
172 |
|
173 |
fd_info = (struct filedesc_info *)fd; |
174 |
|
175 |
dbgprintf("fsysRead..." |
176 |
" fd: %x\n" |
177 |
" bf: %x\n" |
178 |
" sz: %d\n" |
179 |
" ow: %d\n\n", fd, (int)buf, size, fd_info->own_fd); |
180 |
|
181 |
remove_flag = 0; |
182 |
|
183 |
WaitSema(fsys_sema); |
184 |
ret = pko_read_file(fd_info->own_fd, buf, size); |
185 |
SignalSema(fsys_sema); |
186 |
|
187 |
return ret; |
188 |
} |
189 |
//---------------------------------------------------------------------------- |
190 |
static int fsysWrite( int fd, char *buf, int size) |
191 |
{ |
192 |
struct filedesc_info *fd_info; |
193 |
int ret; |
194 |
|
195 |
dbgprintf("fsysWrite..." |
196 |
" fd: %x\n", fd); |
197 |
|
198 |
remove_flag = 0; |
199 |
|
200 |
fd_info = (struct filedesc_info *)fd; |
201 |
WaitSema(fsys_sema); |
202 |
ret = pko_write_file(fd_info->own_fd, buf, size); |
203 |
SignalSema(fsys_sema); |
204 |
return ret; |
205 |
} |
206 |
//---------------------------------------------------------------------------- |
207 |
static int fsysLseek( int fd, unsigned int offset, int whence) |
208 |
{ |
209 |
struct filedesc_info *fd_info; |
210 |
int ret; |
211 |
|
212 |
dbgprintf("fsysLseek..\n" |
213 |
" fd: %x\n" |
214 |
" of: %x\n" |
215 |
" wh: %x\n\n", fd, offset, whence); |
216 |
|
217 |
remove_flag = 0; |
218 |
|
219 |
fd_info = (struct filedesc_info *)fd; |
220 |
WaitSema(fsys_sema); |
221 |
ret = pko_lseek_file(fd_info->own_fd, offset, whence); |
222 |
SignalSema(fsys_sema); |
223 |
return ret; |
224 |
} |
225 |
//---------------------------------------------------------------------------- |
226 |
static int fsysIoctl(iop_file_t* file, unsigned long request, void *data) |
227 |
{ |
228 |
int remote_fd = ((struct filedesc_info *) file)->own_fd; |
229 |
int ret; |
230 |
dbgprintf("fsysioctl..\n"); |
231 |
dbgprintf(" fd: %x\n" |
232 |
" rq: %x\n" |
233 |
" dp: %x\n\n", ); |
234 |
|
235 |
remove_flag = 0; |
236 |
|
237 |
if (request == IOCTL_RENAME){ |
238 |
if (lastopen_fd == remote_fd){ |
239 |
WaitSema(fsys_sema); |
240 |
ret = pko_ioctl(remote_fd, request, data); |
241 |
SignalSema(fsys_sema); |
242 |
if ((ret == 0) || (ret == -6)) |
243 |
renamed_fd = remote_fd; |
244 |
} else { |
245 |
printf("Ioctl Rename function used incorrectly.\n"); |
246 |
ret = -5; |
247 |
|
248 |
} |
249 |
} else { |
250 |
printf("Ioctl function called with invalid request code\n"); |
251 |
ret = -5; |
252 |
} |
253 |
return ret; |
254 |
} |
255 |
//---------------------------------------------------------------------------- |
256 |
static int fsysRemove(iop_file_t* file, char *name) |
257 |
{ |
258 |
int ret; |
259 |
dbgprintf("fsysRemove..\n"); |
260 |
dbgprintf(" name: %s\n\n", name); |
261 |
|
262 |
remove_flag = 1; |
263 |
|
264 |
WaitSema(fsys_sema); |
265 |
ret = pko_remove(name); |
266 |
SignalSema(fsys_sema); |
267 |
|
268 |
remove_result = ret; |
269 |
return ret; |
270 |
} |
271 |
//---------------------------------------------------------------------------- |
272 |
static int fsysMkdir(iop_file_t* file, char *name, int mode) |
273 |
{ |
274 |
int ret; |
275 |
dbgprintf("fsysMkdir..\n"); |
276 |
dbgprintf(" name: '%s'\n\n", name); |
277 |
|
278 |
if (remove_flag == 0){ |
279 |
WaitSema(fsys_sema); |
280 |
ret = pko_mkdir(name, mode); |
281 |
SignalSema(fsys_sema); |
282 |
} else { |
283 |
remove_flag = 0; |
284 |
ret = remove_result; |
285 |
} |
286 |
|
287 |
return ret; |
288 |
} |
289 |
//---------------------------------------------------------------------------- |
290 |
static int fsysRmdir(iop_file_t* file, char *name) |
291 |
{ |
292 |
int ret; |
293 |
dbgprintf("fsysRmdir..\n"); |
294 |
dbgprintf(" name: %s\n\n", name); |
295 |
|
296 |
remove_flag = 0; |
297 |
|
298 |
WaitSema(fsys_sema); |
299 |
ret = pko_rmdir(name); |
300 |
SignalSema(fsys_sema); |
301 |
|
302 |
return ret; |
303 |
} |
304 |
//---------------------------------------------------------------------------- |
305 |
static int fsysDopen(int fd, char *name) |
306 |
{ |
307 |
struct filedesc_info *fd_info; |
308 |
int fsys_fd; |
309 |
|
310 |
dbgprintf("fsysDopen..\n"); |
311 |
dbgprintf(" fd: %x, name: %s\n\n", fd, name); |
312 |
|
313 |
fd_info = (struct filedesc_info *)fd; |
314 |
|
315 |
remove_flag = 0; |
316 |
|
317 |
WaitSema(fsys_sema); |
318 |
fsys_fd = pko_open_dir(name); |
319 |
SignalSema(fsys_sema); |
320 |
fd_info->own_fd = fsys_fd; |
321 |
renamed_fd = -1; |
322 |
lastopen_fd = fsys_fd; |
323 |
|
324 |
return fsys_fd; |
325 |
} |
326 |
//---------------------------------------------------------------------------- |
327 |
static int fsysDclose(int fd) |
328 |
{ |
329 |
int remote_fd = ((struct filedesc_info *)fd)->own_fd; |
330 |
int ret; |
331 |
|
332 |
dbgprintf("fsys_dclose..\n" |
333 |
" fd: %x\n\n", fd); |
334 |
|
335 |
remove_flag = 0; |
336 |
|
337 |
if (remote_fd != renamed_fd){ |
338 |
WaitSema(fsys_sema); |
339 |
ret = pko_close_dir(remote_fd); |
340 |
SignalSema(fsys_sema); |
341 |
} else ret = 0; |
342 |
renamed_fd = -1; |
343 |
|
344 |
return ret; |
345 |
} |
346 |
//---------------------------------------------------------------------------- |
347 |
static int fsysDread(int fd, void *buf) |
348 |
{ |
349 |
struct filedesc_info *fd_info; |
350 |
int ret; |
351 |
|
352 |
fd_info = (struct filedesc_info *)fd; |
353 |
|
354 |
dbgprintf("fsysDread..." |
355 |
" fd: %x\n" |
356 |
" bf: %x\n" |
357 |
" ow: %d\n\n", fd, (int)buf, fd_info->own_fd); |
358 |
|
359 |
remove_flag = 0; |
360 |
|
361 |
WaitSema(fsys_sema); |
362 |
ret = pko_read_dir(fd_info->own_fd, buf); |
363 |
SignalSema(fsys_sema); |
364 |
|
365 |
return ret; |
366 |
|
367 |
} |
368 |
//---------------------------------------------------------------------------- |
369 |
static int dummyGetstat() |
370 |
{ |
371 |
remove_flag = 0; |
372 |
|
373 |
printf("dummy Getstat function called\n"); |
374 |
return -5; |
375 |
} |
376 |
//---------------------------------------------------------------------------- |
377 |
static int dummyChstat() |
378 |
{ |
379 |
remove_flag = 0; |
380 |
|
381 |
printf("dummy Chstat function called\n"); |
382 |
return -5; |
383 |
} |
384 |
//---------------------------------------------------------------------------- |
385 |
iop_device_ops_t fsys_functarray = |
386 |
{ (void *)fsysInit, |
387 |
(void *)fsysDestroy, |
388 |
(void *)dummyFormat, //init, deinit, format |
389 |
(void *)fsysOpen, |
390 |
(void *)fsysClose, |
391 |
(void *)fsysRead, //open, close, read, |
392 |
(void *)fsysWrite, |
393 |
(void *)fsysLseek, |
394 |
(void *)fsysIoctl, //write, lseek, ioctl |
395 |
(void *)fsysRemove, |
396 |
(void *)fsysMkdir, |
397 |
(void *)fsysRmdir, //remove, mkdir, rmdir |
398 |
(void *)fsysDopen, |
399 |
(void *)fsysDclose, |
400 |
(void *)fsysDread, //dopen, dclose, dread |
401 |
(void *)dummyGetstat, |
402 |
(void *)dummyChstat }; //getstat, chstat |
403 |
|
404 |
iop_device_t fsys_driver = { fsname, 16, 1, "fsys driver", |
405 |
&fsys_functarray }; |
406 |
//---------------------------------------------------------------------------- |
407 |
// Entry point for mounting the file system |
408 |
int fsysMount(void) |
409 |
{ |
410 |
iop_sema_t sema_info; |
411 |
|
412 |
sema_info.attr = 1; |
413 |
sema_info.option = 0; |
414 |
sema_info.initial = 1; |
415 |
sema_info.max = 1; |
416 |
fsys_sema = CreateSema(&sema_info); |
417 |
|
418 |
DelDrv(fsname); |
419 |
AddDrv(&fsys_driver); |
420 |
|
421 |
return 0; |
422 |
} |
423 |
|
424 |
//---------------------------------------------------------------------------- |
425 |
int fsysUnmount(void) |
426 |
{ |
427 |
DelDrv(fsname); |
428 |
return 0; |
429 |
} |
430 |
//---------------------------------------------------------------------------- |
431 |
//End of file: net_fsys.c |
432 |
//---------------------------------------------------------------------------- |