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