diff options
-rw-r--r-- | libdiskfs/console.c | 60 | ||||
-rw-r--r-- | libdiskfs/dev-globals.c | 46 | ||||
-rw-r--r-- | libdiskfs/dev-io.c | 54 | ||||
-rw-r--r-- | libdiskfs/dev-open.c | 66 |
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; +} |