PS2SDK
PS2 Homebrew Libraries
iomanX.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 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 
16 #ifdef _IOP
17 #include "irx_imports.h"
18 #else
19 #include <string.h>
20 #include <types.h>
21 #define index strchr
22 #include <intrman.h>
23 #include <stdio.h>
24 #define Kprintf printf
25 #endif
26 #include <iomanX.h>
27 
28 #include <errno.h>
29 #include <stdarg.h>
30 
31 #ifdef IOP
32 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
33 IRX_ID("IOX/File_Manager", 1, 1);
34 #else
35 IRX_ID("IO/File_Manager", 2, 3);
36 // Based on the module from SCE SDK 3.1.0.
37 #endif
38 #endif
39 #ifdef _IOP
40 #ifndef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
41 extern struct irx_export_table _exp_ioman;
42 #endif
43 extern struct irx_export_table _exp_iomanx;
44 #endif
45 
46 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
47 #define MAX_DEVICES 32
48 #define MAX_FILES 128
49 #else
50 #define MAX_DEVICES 16
51 #define MAX_FILES 32
52 #endif
53 
54 void iomanX_StdioInit(int mode);
55 static int open_tty_handles(const char *tty_name);
56 static int xx_stat(int op, const char *name, iox_stat_t *stat, unsigned int statmask);
57 static int xx_rename(int op, const char *oldname, const char *newname);
58 static int xx_dir(int op, const char *name, int mode);
59 static int _ioabort(const char *str1, const char *str2);
60 static iomanX_iop_file_t *new_iob(void);
61 static iomanX_iop_file_t *get_iob(int fd);
62 static iomanX_iop_device_t *lookup_dev(const char *name, int show_unkdev_msg);
63 static const char *parsefile(const char *path, iomanX_iop_device_t **p_device, int *p_unit);
64 static void ShowDrv(void);
65 static void register_tty(void);
66 #ifdef _IOP
67 static void register_dummytty(void);
68 #endif
69 
70 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
71 struct ioman_dev_listentry
72 {
73  struct ioman_dev_listentry *next;
74  iomanX_iop_device_t *device;
75 };
76 #endif
77 
78 static int showdrvflag = 1;
79 
80 IOMANX_RETURN_VALUE_IMPL(0);
81 
82 static iomanX_iop_device_ops_t dev_tty_dev_operations = {
83  IOMANX_RETURN_VALUE(0), // init
84  IOMANX_RETURN_VALUE(0), // deinit
85  IOMANX_RETURN_VALUE(0), // format
86  IOMANX_RETURN_VALUE(0), // open
87  IOMANX_RETURN_VALUE(0), // close
88  IOMANX_RETURN_VALUE(0), // read
89  IOMANX_RETURN_VALUE(0), // write
90  IOMANX_RETURN_VALUE(0), // lseek
91  IOMANX_RETURN_VALUE(0), // ioctl
92  IOMANX_RETURN_VALUE(0), // remove
93  IOMANX_RETURN_VALUE(0), // mkdir
94  IOMANX_RETURN_VALUE(0), // rmdir
95  IOMANX_RETURN_VALUE(0), // dopen
96  IOMANX_RETURN_VALUE(0), // dclose
97  IOMANX_RETURN_VALUE(0), // dread
98  IOMANX_RETURN_VALUE(0), // getstat
99  IOMANX_RETURN_VALUE(0), // chstat
100  IOMANX_RETURN_VALUE(0), // rename
101  IOMANX_RETURN_VALUE(0), // chdir
102  IOMANX_RETURN_VALUE(0), // sync
103  IOMANX_RETURN_VALUE(0), // mount
104  IOMANX_RETURN_VALUE(0), // umount
105  IOMANX_RETURN_VALUE_S64(0), // lseek64
106  IOMANX_RETURN_VALUE(0), // devctl
107  IOMANX_RETURN_VALUE(0), // symlink
108  IOMANX_RETURN_VALUE(0), // readlink
109  IOMANX_RETURN_VALUE(0), // ioctl2
110 };
111 static iomanX_iop_device_t dev_tty = {
112  "tty",
113  IOP_DT_CHAR,
114  1,
115  "CONSOLE",
116  &dev_tty_dev_operations,
117 };
118 #ifdef _IOP
119 static iomanX_iop_device_t dev_dummytty = {
120  "dummytty",
121  IOP_DT_CHAR,
122  1,
123  "CONSOLE",
124  &dev_tty_dev_operations,
125 };
126 #endif
127 static int adddeldrv_in_process;
128 #ifdef IOMANX_USE_ERRNO
129 static int errno_local;
130 #endif
131 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
132 static struct ioman_dev_listentry *device_entry_empty_list_head;
133 static struct ioman_dev_listentry *device_entry_used_list_head;
134 #endif
135 #ifndef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
136 static
137 #endif
138  iomanX_iop_file_t file_table[MAX_FILES];
139 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
140 static struct ioman_dev_listentry device_entry_list[MAX_DEVICES];
141 #else
142 static iomanX_iop_device_t *device_table[MAX_DEVICES];
143 #endif
144 
145 #ifndef isnum
146 #define isnum(c) ((c) >= '0' && (c) <= '9')
147 #endif
148 
149 #ifndef EUNSUP
150 #ifdef ENOTSUP
151 #define EUNSUP ENOTSUP
152 #else
153 #define EUNSUP 48
154 #endif
155 #endif
156 
157 #define HANDLE_RESULT_CLEAR_INFO 1
158 #define HANDLE_RESULT_CLEAR_INFO_ON_ERROR 2
159 #define HANDLE_RESULT_RETURN_ZERO 4
160 #define HANDLE_RESULT_RETURN_FD 8
161 
162 static inline void write_str_to_stdout(const char *in_str)
163 {
164  iomanX_write(1, (void *)in_str, strlen(in_str));
165 }
166 
167 static inline int set_errno(int in_errno)
168 {
169 #ifdef IOMANX_USE_ERRNO
170  errno_local = in_errno;
171 #endif
172  return -in_errno;
173 }
174 
175 static inline void handle_result_pre(int in_result, iomanX_iop_file_t *f, int op)
176 {
177  if ( (op & HANDLE_RESULT_CLEAR_INFO) )
178  {
179  if ( f )
180  {
181  // Unofficial: don't clear mode
182  f->device = NULL;
183  }
184  }
185  if ( (op & HANDLE_RESULT_CLEAR_INFO_ON_ERROR) )
186  {
187  if ( f && (in_result < 0) )
188  {
189  f->device = NULL;
190  }
191  }
192 }
193 
194 static inline int handle_result(int in_result, iomanX_iop_file_t *f, int op)
195 {
196  handle_result_pre(in_result, f, op);
197  if ( in_result < 0 )
198  return set_errno(-in_result);
199  if ( (op & HANDLE_RESULT_RETURN_ZERO) )
200  return 0;
201  if ( (op & HANDLE_RESULT_RETURN_FD) )
202  return f - file_table;
203  return in_result;
204 }
205 
206 static inline s64 handle_result64(s64 in_result, iomanX_iop_file_t *f, int op)
207 {
208  handle_result_pre(in_result, f, op);
209  if ( in_result < 0 )
210  return set_errno(-(int)in_result);
211  if ( (op & HANDLE_RESULT_RETURN_ZERO) )
212  return 0;
213  if ( (op & HANDLE_RESULT_RETURN_FD) )
214  return f - file_table;
215  return in_result;
216 }
217 
218 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
219 extern int hook_ioman(void);
220 extern int unhook_ioman(void);
221 #endif
222 
223 #ifndef IOMANX_ENTRYPOINT
224 #ifdef _IOP
225 #define IOMANX_ENTRYPOINT _start
226 #else
227 #define IOMANX_ENTRYPOINT iomanX_start
228 #endif
229 #endif
230 
231 #ifndef IOMANX_CLEANUP
232 #define IOMANX_CLEANUP shutdown
233 #endif
234 
235 int IOMANX_ENTRYPOINT(int ac, char **av)
236 {
237 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
238  unsigned int i;
239 #endif
240 #ifdef _IOP
241  int ioman_already_registered;
242  int state;
243 #endif
244 
245  (void)ac;
246  (void)av;
247 
248  adddeldrv_in_process = 0;
249 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
250  // Unofficial: memset instead of bzero
251  memset(device_entry_list, 0, sizeof(device_entry_list));
252  device_entry_used_list_head = NULL;
253  device_entry_empty_list_head = device_entry_list;
254  // Unofficial: link forwards instead of backwards
255  for ( i = 0; i < ((sizeof(device_entry_list) / sizeof(device_entry_list[0])) - 1); i += 1 )
256  device_entry_list[i].next = &device_entry_list[i + 1];
257 #else
258  memset(device_table, 0, sizeof(device_table));
259 #endif
260  // Unofficial: memset instead of bzero
261  memset(file_table, 0, sizeof(file_table));
262  iomanX_StdioInit(0);
263  // Unofficial: register libraries and hooks after initialization
264 #ifdef _IOP
265  CpuSuspendIntr(&state);
266  if ( RegisterLibraryEntries(&_exp_iomanx) )
267  return MODULE_NO_RESIDENT_END;
268 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
269  ioman_already_registered = hook_ioman();
270 #else
271  ioman_already_registered = RegisterLibraryEntries(&_exp_ioman);
272 #endif
273  if ( ioman_already_registered )
274  return MODULE_NO_RESIDENT_END;
275 #if 0
276  SetRebootTimeLibraryHandlingMode(&_exp_ioman, 2);
277 #else
278  // Call termination before disabling interrupts
279  _exp_iomanx.mode &= ~6;
280  _exp_iomanx.mode |= 2;
281  CpuResumeIntr(state);
282 #endif
283 #endif
284  return MODULE_RESIDENT_END;
285 }
286 
287 int IOMANX_CLEANUP(int arg)
288 {
289 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
290  struct ioman_dev_listentry *i;
291 #else
292  unsigned int i;
293 #endif
294 
295 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
296  unhook_ioman();
297 #endif
298 
299  if ( !arg )
300  {
301 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
302  for ( i = device_entry_used_list_head; i; i = i->next )
303  {
304  i->device->ops->deinit(i->device);
305  i->device = NULL;
306  }
307 #else
308  for ( i = 0; i < (sizeof(device_table) / sizeof(device_table[0])); i += 1 )
309  {
310  if ( device_table[i] )
311  {
312  device_table[i]->ops->deinit(device_table[i]);
313  device_table[i] = NULL;
314  }
315  }
316 #endif
317  }
318  return MODULE_RESIDENT_END;
319 }
320 
321 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
322 iomanX_iop_device_t **iomanX_GetDeviceList(void)
323 {
324  return device_table;
325 }
326 
327 int mode2modex(int mode)
328 {
329  int modex = 0;
330 
331  if ( (mode & FIO_SO_IFLNK) != 0 )
332  modex |= FIO_S_IFLNK;
333  if ( (mode & FIO_SO_IFREG) != 0 )
334  modex |= FIO_S_IFREG;
335  if ( (mode & FIO_SO_IFDIR) != 0 )
336  modex |= FIO_S_IFDIR;
337 
338  /* Convert the file access modes. */
339  if ( mode & FIO_SO_IROTH )
340  modex |= FIO_S_IRUSR | FIO_S_IRGRP | FIO_S_IROTH;
341  if ( mode & FIO_SO_IWOTH )
342  modex |= FIO_S_IWUSR | FIO_S_IWGRP | FIO_S_IWOTH;
343  if ( mode & FIO_SO_IXOTH )
344  modex |= FIO_S_IXUSR | FIO_S_IXGRP | FIO_S_IXOTH;
345 
346  return modex;
347 }
348 
349 int modex2mode(int modex)
350 {
351  int mode = 0;
352 
353  if ( (modex & FIO_S_IFLNK) != 0 )
354  mode |= FIO_SO_IFLNK;
355  if ( (modex & FIO_S_IFREG) != 0 )
356  mode |= FIO_SO_IFREG;
357  if ( (modex & FIO_S_IFDIR) != 0 )
358  mode |= FIO_SO_IFDIR;
359 
360  /* Convert the file access modes. */
361  if ( modex & (FIO_S_IRUSR | FIO_S_IRGRP | FIO_S_IROTH) )
362  mode |= FIO_SO_IROTH;
363  if ( modex & (FIO_S_IWUSR | FIO_S_IWGRP | FIO_S_IWOTH) )
364  mode |= FIO_SO_IWOTH;
365  if ( modex & (FIO_S_IXUSR | FIO_S_IXGRP | FIO_S_IXOTH) )
366  mode |= FIO_SO_IXOTH;
367 
368  return mode;
369 }
370 
371 iomanX_iop_file_t *get_file(int fd)
372 {
373  return get_iob(fd);
374 }
375 #endif
376 
377 void iomanX_StdioInit(int mode)
378 {
379 #ifdef _IOP
380  const int *BootMode;
381  iop_thread_info_t thinfo;
382 #endif
383 
384 #ifdef _IOP
385  BootMode = QueryBootMode(3);
386  if ( BootMode && (BootMode[1] & 4) )
387  return;
388  ReferThreadStatus(0, &thinfo);
389  ChangeThreadPriority(0, 4);
390 #endif
391 #ifdef _IOP
392  switch ( mode )
393  {
394  case 0:
395  {
396  iomanX_close(0);
397  iomanX_close(1);
398  register_tty();
399  open_tty_handles("tty:");
400  break;
401  }
402  case 1:
403  {
404  iomanX_close(0);
405  iomanX_close(1);
406  register_dummytty();
407  open_tty_handles("dummytty:");
408  break;
409  }
410  default:
411  break;
412  }
413 #else
414  iomanX_close(0);
415  iomanX_close(1);
416  register_tty();
417  open_tty_handles("tty:");
418 #endif
419 #ifdef _IOP
420  ChangeThreadPriority(0, thinfo.currentPriority);
421 #endif
422 }
423 
424 static int open_tty_handles(const char *tty_name)
425 {
426  if ( iomanX_open(tty_name, 3) != 0 || iomanX_open(tty_name, 2) != 1 )
427  return -1;
428  return 0;
429 }
430 
431 int iomanX_open(const char *name, int flags, ...)
432 {
434  const char *parsefile_res;
435  int mode;
436  va_list va;
437 
438  va_start(va, flags);
439  mode = va_arg(va, int);
440  va_end(va);
441  f = new_iob();
442  if ( !f )
443  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
444  parsefile_res = parsefile(name, &(f->device), &(f->unit));
445  if ( !parsefile_res )
446  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
447  f->mode = flags;
448  return handle_result(
449  f->device->ops->open(f, parsefile_res, flags, mode),
450  f,
451  HANDLE_RESULT_CLEAR_INFO_ON_ERROR | HANDLE_RESULT_RETURN_FD);
452 }
453 
454 int iomanX_lseek(int fd, int offset, int mode)
455 {
457 
458  f = get_iob(fd);
459  if ( !f )
460  return handle_result(-EBADF, f, 0);
461  switch ( mode )
462  {
463  case FIO_SEEK_SET:
464  case FIO_SEEK_CUR:
465  case FIO_SEEK_END:
466  return handle_result(f->device->ops->lseek(f, offset, mode), f, 0);
467  default:
468  write_str_to_stdout("invalid lseek arg\r\n");
469  return handle_result(-EINVAL, f, 0);
470  }
471 }
472 
473 s64 iomanX_lseek64(int fd, s64 offset, int whence)
474 {
476 
477  f = get_iob(fd);
478  if ( !f )
479  return handle_result(-EBADF, f, 0);
480  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
481  return handle_result(-EUNSUP, f, 0);
482  switch ( whence )
483  {
484  case FIO_SEEK_SET:
485  case FIO_SEEK_CUR:
486  case FIO_SEEK_END:
487  return handle_result64(f->device->ops->lseek64(f, offset, whence), f, 0);
488  default:
489  write_str_to_stdout("invalid lseek arg\r\n");
490  return handle_result(-EINVAL, f, 0);
491  }
492 }
493 
494 int iomanX_read(int fd, void *ptr, int size)
495 {
497 
498  f = get_iob(fd);
499  if ( !f || !(f->mode & FIO_O_RDONLY) )
500  return handle_result(-EBADF, f, 0);
501  return handle_result(f->device->ops->read(f, ptr, size), f, 0);
502 }
503 
504 int iomanX_write(int fd, void *ptr, int size)
505 {
507 
508  f = get_iob(fd);
509  if ( !f || !(f->mode & FIO_O_WRONLY) )
510  return handle_result(-EBADF, f, 0);
511  return handle_result(f->device->ops->write(f, ptr, size), f, 0);
512 }
513 
514 int iomanX_close(int fd)
515 {
517 
518  f = get_iob(fd);
519  if ( !f )
520  return handle_result(-EBADF, f, 0);
521  return handle_result(
522  (f->mode & FIO_O_DIROPEN) ? f->device->ops->dclose(f) : f->device->ops->close(f),
523  f,
524  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_FD);
525 }
526 
527 int iomanX_ioctl(int fd, int cmd, void *param)
528 {
530 
531  f = get_iob(fd);
532  if ( !f )
533  return handle_result(-EBADF, f, 0);
534  return handle_result(f->device->ops->ioctl(f, cmd, param), f, 0);
535 }
536 
537 int iomanX_ioctl2(int fd, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
538 {
540 
541  f = get_iob(fd);
542  if ( !f )
543  return handle_result(-EBADF, f, 0);
544  // The filesystem must support these ops.
545  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
546  return handle_result(-EUNSUP, f, 0);
547  return handle_result(f->device->ops->ioctl2(f, cmd, arg, arglen, buf, buflen), f, 0);
548 }
549 
550 int iomanX_dopen(const char *path)
551 {
553  const char *parsefile_res;
554 
555  f = new_iob();
556  if ( !f )
557  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
558  parsefile_res = parsefile(path, &(f->device), &(f->unit));
559  if ( !parsefile_res )
560  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
561  f->mode = FIO_O_DIROPEN;
562  return handle_result(
563  f->device->ops->dopen(f, parsefile_res), f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR | HANDLE_RESULT_RETURN_FD);
564 }
565 
566 int iomanX_dread(int fd, iox_dirent_t *buf)
567 {
569 
570  f = get_iob(fd);
571  if ( !f || !(f->mode & FIO_O_DIROPEN) )
572  return handle_result(-EBADF, f, 0);
573 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
574  /* If this is a legacy device (such as mc:) then we need to convert the mode
575  variable of the stat structure to iomanX's extended format. */
576  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
577  {
578  int res;
579  typedef int io_dread_t(iomanX_iop_file_t *, io_dirent_t *);
580  io_dirent_t io_dirent;
581  io_dread_t *io_dread;
582 
583  io_dread = (io_dread_t *)f->device->ops->dread;
584  res = io_dread(f, &io_dirent);
585 
586  buf->stat.mode = mode2modex(io_dirent.stat.mode);
587 
588  buf->stat.attr = io_dirent.stat.attr;
589  buf->stat.size = io_dirent.stat.size;
590  memcpy(buf->stat.ctime, io_dirent.stat.ctime, sizeof(io_dirent.stat.ctime));
591  memcpy(buf->stat.atime, io_dirent.stat.atime, sizeof(io_dirent.stat.atime));
592  memcpy(buf->stat.mtime, io_dirent.stat.mtime, sizeof(io_dirent.stat.mtime));
593  buf->stat.hisize = io_dirent.stat.hisize;
594 
595  strncpy(buf->name, io_dirent.name, sizeof(buf->name));
596  return handle_result(res, f, 0);
597  }
598 #endif
599  return handle_result(f->device->ops->dread(f, buf), f, 0);
600 }
601 
602 int iomanX_remove(const char *name)
603 {
605  const char *parsefile_res;
606 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
607  iomanX_iop_file_t f_stk;
608 #endif
609 
610 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
611  f = &f_stk;
612 #else
613  f = new_iob();
614  if ( !f )
615  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
616 #endif
617  parsefile_res = parsefile(name, &(f->device), &(f->unit));
618  if ( !parsefile_res )
619  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
620  return handle_result(
621  f->device->ops->remove(f, parsefile_res), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
622 }
623 
624 int iomanX_mkdir(const char *path, int mode)
625 {
626  return xx_dir(4, path, mode);
627 }
628 
629 int iomanX_rmdir(const char *path)
630 {
631  return xx_dir(5, path, 0);
632 }
633 
634 static int xx_stat(int op, const char *name, iox_stat_t *stat, unsigned int statmask)
635 {
637  const char *parsefile_res;
638 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
639  iomanX_iop_file_t f_stk;
640 #endif
641 
642 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
643  f = &f_stk;
644 #else
645  f = new_iob();
646  if ( !f )
647  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
648 #endif
649  parsefile_res = parsefile(name, &(f->device), &(f->unit));
650  if ( !parsefile_res )
651  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
652  switch ( op )
653  {
654  case 1:
655  {
656 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
657  /* If this is a legacy device (such as mc:) then we need to convert the mode
658  variable to iomanX's extended format. */
659  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
660  {
661  iox_stat_t stat_tmp;
662 
663  memcpy(&stat_tmp, stat, sizeof(stat_tmp));
664  stat_tmp.mode = modex2mode(stat->mode);
665  return handle_result(
666  f->device->ops->chstat(f, parsefile_res, &stat_tmp, statmask),
667  f,
668  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
669  }
670 #endif
671  return handle_result(
672  f->device->ops->chstat(f, parsefile_res, stat, statmask),
673  f,
674  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
675  }
676  case 2:
677  {
678 #ifdef IOMANX_ENABLE_LEGACY_IOMAN_HOOK
679  /* If this is a legacy device (such as mc:) then we need to convert the mode
680  variable to iomanX's extended format. */
681  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
682  {
683  int res;
684 
685  res = f->device->ops->getstat(f, parsefile_res, stat);
686  if ( res == 0 )
687  stat->mode = mode2modex(stat->mode);
688  return handle_result(res, f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
689  }
690 #endif
691  return handle_result(
692  f->device->ops->getstat(f, parsefile_res, stat), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
693  }
694  default:
695  // Unofficial: return negative instead of positive if op not found
696  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
697  }
698 }
699 
700 int iomanX_getstat(const char *name, iox_stat_t *stat)
701 {
702  return xx_stat(2, name, stat, 0);
703 }
704 
705 int iomanX_chstat(const char *name, iox_stat_t *stat, unsigned int statmask)
706 {
707  return xx_stat(1, name, stat, statmask);
708 }
709 
710 int iomanX_format(const char *dev, const char *blockdev, void *arg, int arglen)
711 {
713  const char *parsefile_res;
714 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
715  iomanX_iop_file_t f_stk;
716 #endif
717 
718 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
719  f = &f_stk;
720 #else
721  f = new_iob();
722  if ( !f )
723  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
724 #endif
725  parsefile_res = parsefile(dev, &(f->device), &(f->unit));
726  if ( !parsefile_res )
727  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
728  return handle_result(
729  f->device->ops->format(f, parsefile_res, blockdev, arg, arglen),
730  f,
731  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
732 }
733 
734 static int xx_rename(int op, const char *oldname, const char *newname)
735 {
737  const char *parsefile_res;
738  const char *parsefile_res_new;
739  iomanX_iop_device_t *device_new;
740  int unit_new;
741 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
742  iomanX_iop_file_t f_stk;
743 #endif
744 
745 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
746  f = &f_stk;
747 #else
748  f = new_iob();
749  if ( !f )
750  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
751 #endif
752  parsefile_res = parsefile(oldname, &(f->device), &(f->unit));
753  if ( !parsefile_res )
754  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
755  // Unofficial: initialize variables and check if newname is not NULL
756  parsefile_res_new = newname;
757  device_new = f->device;
758  unit_new = f->unit;
759  if ( newname && index(newname, ':') )
760  parsefile_res_new = parsefile(newname, &device_new, &unit_new);
761  // Make sure the user isn't attempting to link across devices.
762  if ( !parsefile_res_new || (device_new != f->device) || (unit_new != f->unit) )
763  return handle_result(-EXDEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
764  // The filesystem must support these ops.
765  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
766  return handle_result(-EUNSUP, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
767  switch ( op )
768  {
769  case 7:
770  return handle_result(
771  f->device->ops->rename(f, parsefile_res, parsefile_res_new),
772  f,
773  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
774  case 8:
775  return handle_result(
776  f->device->ops->symlink(f, parsefile_res, parsefile_res_new),
777  f,
778  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
779  default:
780  // Unofficial: return negative instead of positive if op not found
781  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
782  }
783 }
784 
785 // cppcheck-suppress funcArgNamesDifferent
786 int iomanX_rename(const char *oldname, const char *newname)
787 {
788  return xx_rename(7, oldname, newname);
789 }
790 
791 // cppcheck-suppress funcArgNamesDifferent
792 int iomanX_symlink(const char *oldname, const char *newname)
793 {
794  return xx_rename(8, oldname, newname);
795 }
796 
797 int iomanX_chdir(const char *name)
798 {
799  return xx_dir(0x103, name, 0);
800 }
801 
802 /* Because mkdir, rmdir, chdir, and sync have similiar arguments (each starts
803  with a path followed by an optional integer), we use a common routine to
804  handle all of them. */
805 static int xx_dir(int op, const char *name, int mode)
806 {
808  const char *parsefile_res;
809 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
810  iomanX_iop_file_t f_stk;
811 #endif
812 
813 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
814  f = &f_stk;
815 #else
816  f = new_iob();
817  if ( !f )
818  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
819 #endif
820  parsefile_res = parsefile(name, &(f->device), &(f->unit));
821  if ( !parsefile_res )
822  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
823  // The filesystem must support these ops.
824  if ( (op & 0x100) && ((f->device->type & 0xF0000000) != IOP_DT_FSEXT) )
825  return handle_result(-EUNSUP, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
826  switch ( op )
827  {
828  case 4:
829  return handle_result(
830  f->device->ops->mkdir(f, parsefile_res, mode), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
831  case 5:
832  return handle_result(
833  f->device->ops->rmdir(f, parsefile_res), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
834  case 0x103:
835  return handle_result(
836  f->device->ops->chdir(f, parsefile_res), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
837  case 0x106:
838  return handle_result(
839  f->device->ops->sync(f, parsefile_res, mode), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
840  default:
841  // Unofficial: return negative instead of positive if op not found
842  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
843  }
844 }
845 
846 int iomanX_sync(const char *dev, int flag)
847 {
848  return xx_dir(0x106, dev, flag);
849 }
850 
851 int iomanX_mount(const char *fsname, const char *devname, int flag, void *arg, int arglen)
852 {
854  const char *parsefile_res;
855 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
856  iomanX_iop_file_t f_stk;
857 #endif
858 
859 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
860  f = &f_stk;
861 #else
862  f = new_iob();
863  if ( !f )
864  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
865 #endif
866  parsefile_res = parsefile(fsname, &(f->device), &(f->unit));
867  if ( !parsefile_res )
868  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
869  // The filesystem must support these ops.
870  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
871  return handle_result(-EUNSUP, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
872  return handle_result(
873  f->device->ops->mount(f, parsefile_res, devname, flag, arg, arglen),
874  f,
875  HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
876 }
877 
878 int iomanX_umount(const char *fsname)
879 {
881  const char *parsefile_res;
882 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
883  iomanX_iop_file_t f_stk;
884 #endif
885 
886 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
887  f = &f_stk;
888 #else
889  f = new_iob();
890  if ( !f )
891  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
892 #endif
893  parsefile_res = parsefile(fsname, &(f->device), &(f->unit));
894  if ( !parsefile_res )
895  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
896  // The filesystem must support these ops.
897  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
898  return handle_result(-EUNSUP, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
899  return handle_result(
900  f->device->ops->umount(f, parsefile_res), f, HANDLE_RESULT_CLEAR_INFO | HANDLE_RESULT_RETURN_ZERO);
901 }
902 
903 int iomanX_devctl(const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
904 {
906  const char *parsefile_res;
907 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
908  iomanX_iop_file_t f_stk;
909 #endif
910 
911 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
912  f = &f_stk;
913 #else
914  f = new_iob();
915  if ( !f )
916  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
917 #endif
918  parsefile_res = parsefile(name, &(f->device), &(f->unit));
919  if ( !parsefile_res )
920  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
921  // The filesystem must support these ops.
922  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
923  return handle_result(-EUNSUP, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
924  return handle_result(
925  f->device->ops->devctl(f, parsefile_res, cmd, arg, arglen, buf, buflen), f, HANDLE_RESULT_CLEAR_INFO);
926 }
927 
928 int iomanX_readlink(const char *path, char *buf, unsigned int buflen)
929 {
931  const char *parsefile_res;
932 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
933  iomanX_iop_file_t f_stk;
934 #endif
935 
936 #ifdef IOMAN_USE_FILE_STRUCT_TEMP_STACK
937  f = &f_stk;
938 #else
939  f = new_iob();
940  if ( !f )
941  return handle_result(-EMFILE, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
942 #endif
943  parsefile_res = parsefile(path, &(f->device), &(f->unit));
944  if ( !parsefile_res )
945  return handle_result(-ENODEV, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
946  // The filesystem must support these ops.
947  if ( (f->device->type & 0xF0000000) != IOP_DT_FSEXT )
948  return handle_result(-EUNSUP, f, HANDLE_RESULT_CLEAR_INFO_ON_ERROR);
949  return handle_result(f->device->ops->readlink(f, parsefile_res, buf, buflen), f, HANDLE_RESULT_CLEAR_INFO);
950 }
951 
952 static int _ioabort(const char *str1, const char *str2)
953 {
954  return Kprintf("ioabort exit:%s %s\n", str1, str2);
955 }
956 
957 static iomanX_iop_file_t *new_iob(void)
958 {
959  iomanX_iop_file_t *file_table_entry;
960  int state;
961  int fd;
962 
963  fd = 0;
964  CpuSuspendIntr(&state);
965  file_table_entry = NULL;
966  while ( fd < (int)(sizeof(file_table) / sizeof(file_table[0])) )
967  {
968  if ( !file_table[fd].device )
969  {
970  file_table_entry = &file_table[fd];
971  break;
972  }
973  fd += 1;
974  }
975  // fill in "device" temporarily to mark the fd as allocated.
976  if ( file_table_entry )
977  file_table_entry->device = (iomanX_iop_device_t *)(uiptr)0xFFFFFFEC;
978  CpuResumeIntr(state);
979  if ( !file_table_entry )
980  _ioabort("out of file descriptors", "[too many open]");
981  return file_table_entry;
982 }
983 
984 static iomanX_iop_file_t *get_iob(int fd)
985 {
986  if ( (fd < 0) || (fd >= (int)(sizeof(file_table) / sizeof(file_table[0]))) || (!file_table[fd].device) )
987  return NULL;
988  return &file_table[fd];
989 }
990 
991 static iomanX_iop_device_t *lookup_dev(const char *name, int show_unkdev_msg)
992 {
993 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
994  struct ioman_dev_listentry *entry;
995 #else
996  iomanX_iop_device_t *device;
997  unsigned int i;
998 #endif
999  int state;
1000 
1001  CpuSuspendIntr(&state);
1002 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1003  entry = device_entry_used_list_head;
1004  while ( entry && strcmp(name, entry->device->name) )
1005  entry = entry->next;
1006  if ( !entry && show_unkdev_msg )
1007  {
1008  Kprintf("Unknown device '%s'\n", name);
1009  ShowDrv();
1010  }
1011 #else
1012  device = NULL;
1013  for ( i = 0; i < (sizeof(device_table) / sizeof(device_table[0])); i += 1 )
1014  {
1015  if ( device_table[i] && !strcmp(name, device_table[i]->name) )
1016  {
1017  device = device_table[i];
1018  break;
1019  }
1020  }
1021  if ( !device && show_unkdev_msg )
1022  {
1023  Kprintf("Unknown device '%s'\n", name);
1024  ShowDrv();
1025  }
1026 #endif
1027  CpuResumeIntr(state);
1028 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1029  return entry ? entry->device : NULL;
1030 #else
1031  return device;
1032 #endif
1033 }
1034 
1035 static const char *parsefile(const char *path, iomanX_iop_device_t **p_device, int *p_unit)
1036 {
1037  const char *path_trimmed;
1038  char *colon_index;
1039  size_t devname_len;
1040  iomanX_iop_device_t *device;
1041  int unit;
1042  char canon[32];
1043 
1044  path_trimmed = path;
1045  while ( *path_trimmed == ' ' )
1046  path_trimmed += 1;
1047  colon_index = index(path_trimmed, ':');
1048  // Unofficial: On error, return NULL instead of -1
1049  if ( !colon_index )
1050  {
1051  Kprintf("Unknown device '%s'\n", path_trimmed);
1052  return NULL;
1053  }
1054  devname_len = colon_index - path_trimmed;
1055  // Unofficial: bounds check
1056  if ( devname_len > (sizeof(canon) - 1) )
1057  return NULL;
1058  strncpy(canon, path_trimmed, devname_len);
1059  canon[devname_len] = 0;
1060  unit = 0;
1061  // Search backward for the unit number.
1062  while ( isnum(canon[devname_len - 1]) )
1063  devname_len -= 1;
1064  if ( isnum(canon[devname_len]) )
1065  unit = strtol(&canon[devname_len], 0, 10);
1066  canon[devname_len] = 0;
1067  // Find the actual device.
1068  device = lookup_dev(canon, 1);
1069  // Unofficial: On error, return NULL instead of -1
1070  if ( !device )
1071  return NULL;
1072  // Unofficial: set unit and device only after success
1073  *p_unit = unit;
1074  *p_device = device;
1075  // This is the name passed to the device op.
1076  return colon_index + 1;
1077 }
1078 
1079 // Unofficial: unused "io request for unsupported operation" func removed
1080 
1081 int iomanX_AddDrv(iomanX_iop_device_t *device)
1082 {
1083 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1084  struct ioman_dev_listentry *entry;
1085  struct ioman_dev_listentry *old_head;
1086 #else
1087  unsigned int i;
1088 #endif
1089  int state;
1090 
1091  CpuSuspendIntr(&state);
1092  if ( adddeldrv_in_process )
1093  {
1094  Kprintf("AddDrv()/DelDrv() recursive/mutithread call error !!");
1095  CpuResumeIntr(state);
1096  return -1;
1097  }
1098  // Unofficial: move list check out of interrupt disabled area
1099  adddeldrv_in_process = 1;
1100  CpuResumeIntr(state);
1101 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1102  entry = device_entry_empty_list_head;
1103  // Unofficial: check if entry exists first
1104  if ( !entry || lookup_dev(device->name, 0) )
1105  {
1106  adddeldrv_in_process = 0;
1107  return -1;
1108  }
1109  entry->device = device;
1110  device_entry_empty_list_head = entry->next;
1111  if ( device->ops->init(device) < 0 )
1112  {
1113  old_head = device_entry_empty_list_head;
1114  entry->device = NULL;
1115  device_entry_empty_list_head = entry;
1116  entry->next = old_head;
1117  adddeldrv_in_process = 0;
1118  return -1;
1119  }
1120  old_head = device_entry_used_list_head;
1121  device_entry_used_list_head = entry;
1122  entry->next = old_head;
1123 #else
1124  for ( i = 0; i < (sizeof(device_table) / sizeof(device_table[0])); i += 1 )
1125  {
1126  if ( !device_table[i] )
1127  break;
1128  }
1129 
1130  if ( i >= (sizeof(device_table) / sizeof(device_table[0])) )
1131  {
1132  adddeldrv_in_process = 0;
1133  return -1;
1134  }
1135 
1136  device_table[i] = device;
1137 #ifdef _IOP
1138  FlushIcache();
1139 #endif
1140  if ( device->ops->init(device) < 0 )
1141  {
1142  device_table[i] = NULL;
1143  adddeldrv_in_process = 0;
1144  return -1;
1145  }
1146 #endif
1147  showdrvflag = 1;
1148  adddeldrv_in_process = 0;
1149  return 0;
1150 }
1151 
1152 int iomanX_DelDrv(const char *name)
1153 {
1154 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1155  struct ioman_dev_listentry *entry;
1156  struct ioman_dev_listentry **p_next;
1157  struct ioman_dev_listentry *old_head;
1158 #else
1159  unsigned int i;
1160 #endif
1161  int state;
1162 
1163  CpuSuspendIntr(&state);
1164  if ( adddeldrv_in_process )
1165  {
1166  Kprintf("AddDrv()/DelDrv() recursive/mutithread call error !!");
1167  CpuResumeIntr(state);
1168  return -1;
1169  }
1170  adddeldrv_in_process = 1;
1171  CpuResumeIntr(state);
1172 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1173  entry = device_entry_used_list_head;
1174  p_next = &device_entry_used_list_head;
1175  while ( entry && strcmp(name, entry->device->name) )
1176  {
1177  p_next = &entry->next;
1178  entry = entry->next;
1179  }
1180  if ( !entry || entry->device->ops->deinit(entry->device) < 0 )
1181  {
1182  adddeldrv_in_process = 0;
1183  return -1;
1184  }
1185  old_head = device_entry_empty_list_head;
1186  entry->device = NULL;
1187  device_entry_empty_list_head = entry;
1188  *p_next = entry->next;
1189  entry->next = old_head;
1190  adddeldrv_in_process = 0;
1191  return 0;
1192 #else
1193  for ( i = 0; i < (sizeof(device_table) / sizeof(device_table[0])); i += 1 )
1194  {
1195  if ( device_table[i] && !strcmp(name, device_table[i]->name) )
1196  {
1197  device_table[i]->ops->deinit(device_table[i]);
1198  device_table[i] = NULL;
1199  adddeldrv_in_process = 0;
1200  return 0;
1201  }
1202  }
1203 
1204  adddeldrv_in_process = 0;
1205  return -1;
1206 #endif
1207 }
1208 
1209 unsigned int iomanX_GetDevType(int fd)
1210 {
1211  iomanX_iop_file_t *f;
1212 
1213  f = get_iob(fd);
1214  if ( !f )
1215  return handle_result(-EBADF, f, 0);
1216  return f->device->type;
1217 }
1218 
1219 static void ShowDrv(void)
1220 {
1221 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1222  struct ioman_dev_listentry *i;
1223 #else
1224  unsigned int i;
1225 #endif
1226 
1227  if ( !showdrvflag )
1228  return;
1229  Kprintf("Known devices are ");
1230 #ifdef IOMANX_USE_DEVICE_LINKED_LIST
1231  for ( i = device_entry_used_list_head; i; i = i->next )
1232  Kprintf(" %s:(%s) ", i->device->name, i->device->desc);
1233 #else
1234  for ( i = 0; i < (sizeof(device_table) / sizeof(device_table[0])); i += 1 )
1235  if ( device_table[i] != NULL && device_table[i]->name != NULL )
1236  Kprintf(" %s:(%s) ", device_table[i]->name, device_table[i]->desc);
1237 #endif
1238  Kprintf("\n");
1239  showdrvflag = 0;
1240 }
1241 
1242 static void register_tty(void)
1243 {
1244  iomanX_DelDrv(dev_tty.name);
1245  iomanX_AddDrv(&dev_tty);
1246 }
1247 
1248 #ifdef _IOP
1249 static void register_dummytty(void)
1250 {
1251  iomanX_DelDrv(dev_dummytty.name);
1252  iomanX_AddDrv(&dev_dummytty);
1253 }
1254 #endif
_iomanX_iop_file::unit
int unit
Definition: iomanX.h:74
iomanX.h
FIO_SO_IFREG
#define FIO_SO_IFREG
Definition: iox_stat.h:126
_iomanX_iop_file::device
struct _iomanX_iop_device * device
Definition: iomanX.h:76
iox_stat_t
Definition: iox_stat.h:92
IOP_DT_FSEXT
#define IOP_DT_FSEXT
Definition: iomanX.h:66
FIO_S_IFDIR
#define FIO_S_IFDIR
Definition: iox_stat.h:45
EUNSUP
#define EUNSUP
Definition: errno.h:117
FIO_SO_IXOTH
#define FIO_SO_IXOTH
Definition: iox_stat.h:135
_iomanX_iop_file
Definition: iomanX.h:70
FIO_S_IWGRP
#define FIO_S_IWGRP
Definition: iox_stat.h:69
FIO_S_IWUSR
#define FIO_S_IWUSR
Definition: iox_stat.h:60
EXDEV
#define EXDEV
Definition: errno.h:55
FIO_S_IFREG
#define FIO_S_IFREG
Definition: iox_stat.h:43
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
_iomanX_iop_file::mode
int mode
Definition: iomanX.h:72
FIO_S_IXOTH
#define FIO_S_IXOTH
Definition: iox_stat.h:80
_iomanX_iop_device_ops
Definition: iomanX.h:95
FIO_S_IXUSR
#define FIO_S_IXUSR
Definition: iox_stat.h:62
irx_export_table
Definition: irx.h:90
FIO_S_IXGRP
#define FIO_S_IXGRP
Definition: iox_stat.h:71
FIO_S_IROTH
#define FIO_S_IROTH
Definition: iox_stat.h:76
_iomanX_iop_device
Definition: iomanX.h:81
stdio.h
FIO_SO_IFDIR
#define FIO_SO_IFDIR
Definition: iox_stat.h:128
FIO_S_IRUSR
#define FIO_S_IRUSR
Definition: iox_stat.h:58
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
FIO_SO_IFLNK
#define FIO_SO_IFLNK
Definition: iox_stat.h:124
EBADF
#define EBADF
Definition: errno.h:37
iox_dirent_t
Definition: iox_stat.h:111
iomanX_format
int iomanX_format(const char *dev, const char *blockdev, void *arg, int arglen)
Definition: iomanX.c:710
io_dirent_t
Definition: io_common.h:58
FIO_S_IWOTH
#define FIO_S_IWOTH
Definition: iox_stat.h:78
EINVAL
#define EINVAL
Definition: errno.h:63
FIO_S_IFLNK
#define FIO_S_IFLNK
Definition: iox_stat.h:41
intrman.h
FIO_SO_IWOTH
#define FIO_SO_IWOTH
Definition: iox_stat.h:133
errno.h
_iop_thread_status
Definition: thbase.h:68
EMFILE
#define EMFILE
Definition: errno.h:67
ENODEV
#define ENODEV
Definition: errno.h:57
FIO_S_IRGRP
#define FIO_S_IRGRP
Definition: iox_stat.h:67
FIO_SO_IROTH
#define FIO_SO_IROTH
Definition: iox_stat.h:131