summaryrefslogtreecommitdiff
path: root/libdiskfs
diff options
context:
space:
mode:
Diffstat (limited to 'libdiskfs')
-rw-r--r--libdiskfs/console.c60
-rw-r--r--libdiskfs/dev-globals.c46
-rw-r--r--libdiskfs/dev-io.c54
-rw-r--r--libdiskfs/dev-open.c66
4 files changed, 226 insertions, 0 deletions
diff --git a/libdiskfs/console.c b/libdiskfs/console.c
new file mode 100644
index 00000000..4364617c
--- /dev/null
+++ b/libdiskfs/console.c
@@ -0,0 +1,60 @@
+/* Redirect stdio to the console if possible
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <mach/mach.h>
+#include <device/device.h>
+
+/* Make errors go somewhere reasonable. */
+void
+diskfs_console_stdio ()
+{
+ if (getpid () > 0)
+ {
+ int fd = open ("/dev/console", O_RDWR);
+
+ dup2 (fd, 0);
+ dup2 (fd, 1);
+ dup2 (fd, 2);
+ if (fd > 2)
+ close (fd);
+ }
+ else
+ {
+ mach_port_t dev, cons;
+ error_t err;
+ err = get_privileged_ports (NULL, &dev);
+ assert_perror (err);
+ err = device_open (dev, D_READ|D_WRITE, "console", &cons);
+ mach_port_deallocate (mach_task_self (), dev);
+ assert_perror (err);
+ stdin = mach_open_devstream (cons, "r");
+ stdout = stderr = mach_open_devstream (cons, "w");
+ mach_port_deallocate (mach_task_self (), cons);
+ }
+}
diff --git a/libdiskfs/dev-globals.c b/libdiskfs/dev-globals.c
new file mode 100644
index 00000000..c32b6a59
--- /dev/null
+++ b/libdiskfs/dev-globals.c
@@ -0,0 +1,46 @@
+/* Standard device global variables
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <diskfs.h>
+
+/* A mach device port for the device we're using. */
+mach_port_t diskfs_device = MACH_PORT_NULL;
+
+/* The mach device name of DISKFS_DEVICE. May be 0 if unknown. */
+char *diskfs_device_name = 0;
+
+/* The first valid block of DISKFS_DEVICE, in units of
+ DISKFS_DEVICE_BLOCK_SIZE. */
+off_t diskfs_device_start = 0;
+
+/* The usable size of DISKFS_DEVICE, in units of DISKFS_DEVICE_BLOCK_SIZE. */
+off_t diskfs_device_size = 0;
+
+/* The unit of addressing for DISKFS_DEVICE. */
+unsigned diskfs_device_block_size = 0;
+
+/* Some handy calculations based on DISKFS_DEVICE_BLOCK_SIZE. */
+/* Log base 2 of DEVICE_BLOCK_SIZE, or 0 if it's not a power of two. */
+unsigned diskfs_log2_device_block_size = 0;
+/* Log base 2 of the number of device blocks in a vm page, or 0 if it's not a
+ power of two. */
+unsigned diskfs_log2_device_blocks_per_page = 0;
diff --git a/libdiskfs/dev-io.c b/libdiskfs/dev-io.c
new file mode 100644
index 00000000..9d0ed9d0
--- /dev/null
+++ b/libdiskfs/dev-io.c
@@ -0,0 +1,54 @@
+/* Device input and output
+ Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU Hurd.
+
+The GNU Hurd is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+The GNU Hurd is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the GNU Hurd; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <device/device.h>
+#include <device/device_request.h>
+
+#include <diskfs.h>
+
+/* Write disk block ADDR with DATA of LEN bytes to DISKFS_DEVICE, waiting for
+ completion. ADDR is offset by DISKFS_DEVICE_START. If an error occurs,
+ EIO is returned. */
+error_t
+diskfs_device_write_sync (off_t addr, vm_address_t data, size_t len)
+{
+ int written;
+ assert (!diskfs_readonly);
+ if (device_write (diskfs_device, 0, diskfs_device_start + addr,
+ (io_buf_ptr_t) data, len, &written)
+ || written != len)
+ return EIO;
+ return 0;
+}
+
+/* Read disk block ADDR from DISKFS_DEVICE; put the address of the data in
+ DATA; read LEN bytes. Always *DATA should be a full page no matter what.
+ ADDR is offset by DISKFS_DEVICE_START. If an error occurs, EIO is
+ returned. */
+error_t
+diskfs_device_read_sync (off_t addr, vm_address_t *data, size_t len)
+{
+ unsigned read;
+ if (device_read (diskfs_device, 0, diskfs_device_start + addr, len,
+ (io_buf_ptr_t *)data, &read)
+ || read != len)
+ return EIO;
+ return 0;
+}
+
diff --git a/libdiskfs/dev-open.c b/libdiskfs/dev-open.c
new file mode 100644
index 00000000..5b45c30e
--- /dev/null
+++ b/libdiskfs/dev-open.c
@@ -0,0 +1,66 @@
+/* Standard device opening
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <diskfs.h>
+
+/* Uses the values of DISKFS_DEVICE_ARG and DISKFS_USE_MACH_DEVICE, and
+ attempts to open the device and set the values of DISKFS_DEVICE,
+ DISKFS_DEVICE_NAME, DISKFS_DEVICE_START, DISKFS_DEVICE_SIZE, and
+ DISKFS_DEVICE_BLOCK_SIZE. */
+error_t
+diskfs_device_open ()
+{
+ error_t err;
+ if (diskfs_use_mach_device)
+ {
+ diskfs_device_name = diskfs_device_arg;
+ err =
+ diskfs_get_mach_device (diskfs_device_name, &diskfs_device,
+ &diskfs_device_start, &diskfs_device_size,
+ &diskfs_device_block_size);
+ }
+ else
+ err =
+ diskfs_get_file_device (diskfs_device_arg,
+ &diskfs_device_name, &diskfs_device,
+ &diskfs_device_start, &diskfs_device_size,
+ &diskfs_device_block_size);
+
+ if (! err)
+ {
+ diskfs_log2_device_block_size = 0;
+ while ((1 << diskfs_log2_device_block_size) < diskfs_device_block_size)
+ diskfs_log2_device_block_size++;
+ while ((1 << diskfs_log2_device_block_size) != diskfs_device_block_size)
+ diskfs_log2_device_block_size = 0;
+
+ diskfs_log2_device_blocks_per_page = 0;
+ while ((diskfs_device_block_size << diskfs_log2_device_blocks_per_page)
+ < vm_page_size)
+ diskfs_log2_device_blocks_per_page++;
+ if ((diskfs_device_block_size << diskfs_log2_device_blocks_per_page)
+ != vm_page_size)
+ diskfs_log2_device_blocks_per_page = 0;
+ }
+
+ return err;
+}