PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
pfs.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9#
10# PFS startup and misc code
11*/
12
13#include <stdio.h>
14#ifdef _IOP
15#include <sysclib.h>
16#include <loadcore.h>
17#else
18#include <string.h>
19#include <stdlib.h>
20#endif
21#include <irx.h>
22#include <iomanX.h>
23#include <errno.h>
24#include <thsemap.h>
25
26#include "libpfs.h"
27#include "pfs.h"
28#include "pfs_fio.h"
29#include "pfs_fioctl.h"
30
31#ifdef _IOP
32IRX_ID("pfs_driver", PFS_MAJOR, PFS_MINOR);
33#endif
34
36// Globals
37
38static iomanX_iop_device_ops_t pfsOps = {
39 &pfsFioInit, // init
40 &pfsFioDeinit, // deinit
41 &pfsFioFormat, // format
42 &pfsFioOpen, // open
43 &pfsFioClose, // close
44 &pfsFioRead, // read
45 &pfsFioWrite, // write
46 &pfsFioLseek, // lseek
47 &pfsFioIoctl, // ioctl
48 &pfsFioRemove, // remove
49 &pfsFioMkdir, // mkdir
50 &pfsFioRmdir, // rmdir
51 &pfsFioDopen, // dopen
52 &pfsFioClose, // dclose
53 &pfsFioDread, // dread
54 &pfsFioGetstat, // getstat
55 &pfsFioChstat, // chstat
56 &pfsFioRename, // rename
57 &pfsFioChdir, // chdir
58 &pfsFioSync, // sync
59 &pfsFioMount, // mount
60 &pfsFioUmount, // umount
61 &pfsFioLseek64, // lseek64
62 &pfsFioDevctl, // devctl
63 &pfsFioSymlink, // symlink
64 &pfsFioReadlink, // readlink
65 &pfsFioIoctl2, // ioctl2
66};
67
68static iomanX_iop_device_t pfsFioDev = {
69 "pfs",
70 (IOP_DT_FS | IOP_DT_FSEXT),
71 1,
72 "PFS",
73 &pfsOps,
74};
75
76pfs_config_t pfsConfig = { 1, 2 };
77pfs_mount_t *pfsMountBuf;
78char *pfsFilename = NULL;
79
80extern u32 pfsMetaSize;
81extern pfs_file_slot_t *pfsFileSlots;
82extern pfs_config_t pfsConfig;
83
85// Local function declerations
86
87static int printPfsArgError(void);
88static int allocateMountBuffer(int size);
89
91// Function defenitions
92
93static int printPfsArgError(void)
94{
95 PFS_PRINTF(PFS_DRV_NAME" ERROR: Usage: %s [-m <maxmount>] [-o <maxopen>] [-n <numbuffer>]\n", pfsFilename);
96
97 return MODULE_NO_RESIDENT_END;
98}
99
100static int allocateMountBuffer(int size)
101{
102 int tsize = size * sizeof(pfs_mount_t);
103
104 pfsMountBuf = pfsAllocMem(tsize);
105 if(!pfsMountBuf)
106 return -ENOMEM;
107
108 memset(pfsMountBuf, 0, tsize);
109
110 return 0;
111}
112
113static int freeMountBuffer()
114{
115 pfsFreeMem(pfsMountBuf);
116 return 0;
117}
118
119void pfsClearMount(pfs_mount_t *pfsMount)
120{
121 memset(pfsMount, 0, sizeof(pfs_mount_t));
122}
123
124pfs_mount_t *pfsGetMountedUnit(s32 unit)
125{ // get mounted unit
126 if((u32)unit>=pfsConfig.maxMount)
127 return NULL;
128
129 if(!(pfsMountBuf[unit].flags & PFS_MOUNT_BUSY))
130 return NULL;
131
132 return &pfsMountBuf[unit];
133}
134
135#ifdef _IOP
136int PFS_ENTRYPOINT(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
137#else
138int PFS_ENTRYPOINT(int argc, char *argv[])
139#endif
140{
141 char *filename;
142 int number;
143 int numBuf = 8;
144 int reqBuf;
145 int size, ret;
146
147#ifdef _IOP
148 (void)startaddr;
149 if (argc < 0)
150 {
151 int i;
152
153 for ( i = 0; i < pfsConfig.maxOpen; i += 1 )
154 {
155 if ( pfsFileSlots[i].clink )
156 {
157 PFS_PRINTF(PFS_DRV_NAME": error: can't stop module(fd busy)\n");
158 return MODULE_REMOVABLE_END;
159 }
160 }
161 iomanX_DelDrv(pfsFioDev.name);
162 freeMountBuffer();
163 pfsFreeMem(pfsFileSlots);
164 pfsCacheDeinit();
165 PFS_PRINTF(PFS_DRV_NAME": stopped module\n");
166 return MODULE_NO_RESIDENT_END;
167 }
168#endif
169
170 PFS_PRINTF(PFS_DRV_NAME" Playstation Filesystem Driver v%d.%d\nps2fs: (c) 2003 Sjeep, Vector and Florin Sasu\n", PFS_MAJOR, PFS_MINOR);
171
172 // Get filename of IRX
173 filename = strrchr(argv[0], '/');
174 if(filename++)
175 pfsFilename = filename;
176 else
177 pfsFilename = argv[0];
178
179 argc--;
180 argv++;
181
182 // Parse arguments
183 while(argc > 0)
184 {
185 if(argv[0][0] != '-')
186 break;
187
188 if(!strcmp(argv[0], "-m"))
189 {
190 if(--argc <= 0)
191 return printPfsArgError();
192 argv++;
193
194 number = strtol(argv[0], 0, 10);
195
196 if(number <= 32)
197 pfsConfig.maxMount = number;
198 }
199 else if(!strcmp(argv[0], "-o"))
200 {
201 if(--argc <= 0)
202 return printPfsArgError();
203 argv++;
204
205 number = strtol(argv[0], NULL, 10);
206
207 if(number <= 32)
208 pfsConfig.maxOpen = number;
209 }
210 else if(!strcmp(argv[0], "-n"))
211 {
212 if(--argc <= 0)
213 return printPfsArgError();
214 argv++;
215
216 number = strtol(argv[0], NULL, 10);
217
218 if(number > numBuf)
219 numBuf = number;
220
221 if(numBuf > 127) {
222 PFS_PRINTF(PFS_DRV_NAME" ERROR: Number of buffers is larger than 127!\n");
223 return -EINVAL;
224 }
225 }
226 else
227 return printPfsArgError();
228
229 argc--;
230 argv++;
231 }
232
233 PFS_PRINTF(PFS_DRV_NAME" Max mount: %ld, Max open: %ld, Number of buffers: %d\n", pfsConfig.maxMount,
234 pfsConfig.maxOpen, numBuf);
235
236 // Do we have enough buffers ?
237 reqBuf = (pfsConfig.maxOpen * 2) + 8;
238 if(numBuf < reqBuf)
239 PFS_PRINTF(PFS_DRV_NAME" Warning: %d buffers may be needed, but only %d buffers are allocated\n", reqBuf, numBuf);
240
241 if(allocateMountBuffer(pfsConfig.maxMount) < 0)
242 return MODULE_NO_RESIDENT_END;
243
244 // Allocate and zero memory for file slots
245 size = pfsConfig.maxOpen * sizeof(pfs_file_slot_t);
246 pfsFileSlots = pfsAllocMem(size);
247 ret = (pfsFileSlots == NULL) ? -ENOMEM : 0;
248 if(ret != 0)
249 { //Official PFS module does not print an error message here.
250 PFS_PRINTF(PFS_DRV_NAME" Error: Failed to allocate memory for file descriptors!\n");
251 return MODULE_NO_RESIDENT_END;
252 }
253
254 memset(pfsFileSlots, 0, size);
255
256 if(pfsCacheInit(numBuf, pfsMetaSize) < 0)
257 return MODULE_NO_RESIDENT_END;
258
259 iomanX_DelDrv(pfsFioDev.name);
260 if(iomanX_AddDrv(&pfsFioDev) == 0) {
261#if defined(PFS_XOSD_VER)
262 PFS_PRINTF(PFS_DRV_NAME" version %04x driver start. This is OSD LBA48 VERSION !!!!!!!!!!!\n", IRX_VER(PFS_MAJOR, PFS_MINOR));
263#elif defined(PFS_OSD_VER)
264 PFS_PRINTF(PFS_DRV_NAME" version %04x driver start. This is OSD version!\n", IRX_VER(PFS_MAJOR, PFS_MINOR));
265#else
266 PFS_PRINTF(PFS_DRV_NAME" version %04x driver start.\n", IRX_VER(PFS_MAJOR, PFS_MINOR));
267#endif
268#ifdef _IOP
269 if (mi && ((mi->newflags & 2) != 0))
270 mi->newflags |= 0x10;
271#endif
272 return MODULE_RESIDENT_END;
273 }
274
275 return MODULE_NO_RESIDENT_END;
276}
#define EINVAL
Definition errno.h:63
#define ENOMEM
Definition errno.h:43
#define IOP_DT_FSEXT
Definition iomanX.h:66
u16 newflags
Definition loadcore.h:36