]> Zhao Yanbai Git Server - minix.git/commitdiff
Split block/character protocols and libdriver
authorDavid van Moolenbroek <david@minix3.org>
Tue, 22 Nov 2011 12:27:53 +0000 (13:27 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 23 Nov 2011 13:06:37 +0000 (14:06 +0100)
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.

The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.

After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
  in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
  reintroduced

As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.

Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.

114 files changed:
common/include/Makefile.inc
common/include/minix/audio_fw.h
common/include/minix/bdev.h
common/include/minix/blockdriver.h [new file with mode: 0644]
common/include/minix/blockdriver_mt.h [new file with mode: 0644]
common/include/minix/chardriver.h [new file with mode: 0644]
common/include/minix/com.h
common/include/minix/devio.h
common/include/minix/driver.h
common/include/minix/driver_mt.h [deleted file]
common/include/minix/drvlib.h
common/include/minix/ipc.h
drivers/acpi/Makefile
drivers/ahci/Makefile
drivers/ahci/ahci.c
drivers/amddev/Makefile
drivers/amddev/amddev.c
drivers/at_wini/Makefile
drivers/at_wini/at_wini.c
drivers/at_wini/at_wini.h
drivers/audio/Makefile.inc
drivers/audio/es1370/Makefile
drivers/audio/es1370/ak4531.c
drivers/audio/es1370/es1370.c
drivers/audio/es1370/pci_helper.c
drivers/audio/es1371/es1371.c
drivers/audio/es1371/pci_helper.c
drivers/audio/es1371/sample_rate_converter.c
drivers/audio/sb16/mixer.c
drivers/audio/sb16/sb16.c
drivers/bios_wini/Makefile
drivers/bios_wini/bios_wini.c
drivers/filter/Makefile
drivers/filter/crc.c
drivers/filter/driver.c
drivers/filter/inc.h
drivers/filter/main.c
drivers/filter/sum.c
drivers/filter/util.c
drivers/floppy/Makefile
drivers/floppy/floppy.c
drivers/floppy/floppy.h
drivers/floppy/liveupdate.c
drivers/hello/Makefile
drivers/hello/hello.c
drivers/log/Makefile
drivers/log/log.c
drivers/log/log.h
drivers/memory/Makefile
drivers/memory/memory.c
drivers/pci/Makefile
drivers/printer/Makefile
drivers/printer/printer.c
drivers/random/Makefile
drivers/random/main.c
drivers/readclock/Makefile
drivers/ti1225/Makefile
drivers/ti1225/ti1225.c
drivers/tty/Makefile
drivers/tty/console.c
drivers/tty/keyboard.c
drivers/tty/pty.c
drivers/tty/rs232.c
drivers/tty/tty.c
lib/Makefile
lib/libaudiodriver/audio_fw.c
lib/libbdev/bdev.c
lib/libbdev/ipc.c
lib/libblockdriver/Makefile [moved from lib/libdriver/Makefile with 78% similarity]
lib/libblockdriver/driver.c [new file with mode: 0644]
lib/libblockdriver/driver.h [new file with mode: 0644]
lib/libblockdriver/driver_mt.c [moved from lib/libdriver/driver_mt.c with 74% similarity]
lib/libblockdriver/driver_st.c [new file with mode: 0644]
lib/libblockdriver/drvlib.c [moved from lib/libdriver/drvlib.c with 75% similarity]
lib/libblockdriver/event.c [moved from lib/libdriver/event.c with 65% similarity]
lib/libblockdriver/event.h [new file with mode: 0644]
lib/libblockdriver/mq.c [moved from lib/libdriver/mq.c with 83% similarity]
lib/libblockdriver/mq.h [new file with mode: 0644]
lib/libchardriver/Makefile [new file with mode: 0644]
lib/libchardriver/chardriver.c [moved from lib/libdriver/driver.c with 70% similarity]
lib/libdriver/driver.h [deleted file]
lib/libdriver/driver_st.c [deleted file]
lib/libdriver/event.h [deleted file]
lib/libdriver/mq.h [deleted file]
servers/apfs/Makefile
servers/apfs/main.c
servers/avfs/device.c
servers/avfs/dmap.c
servers/avfs/filedes.c
servers/avfs/main.c
servers/avfs/misc.c
servers/avfs/open.c
servers/avfs/proto.h
servers/ext2/cache.c
servers/ext2/super.c
servers/inet/Makefile
servers/inet/inet.c
servers/iso9660fs/cache.c
servers/lwip/Makefile
servers/lwip/lwip.c
servers/mfs/cache.c
servers/mfs/main.c
servers/mfs/super.c
servers/pfs/Makefile
servers/pfs/main.c
servers/vfs/device.c
servers/vfs/dmap.c
servers/vfs/filedes.c
servers/vfs/main.c
servers/vfs/misc.c
servers/vfs/open.c
servers/vfs/proto.h
share/mk/bsd.prog.mk
test/blocktest/blocktest.c

index 25df3fa0aa62997f2a5a562c8859205aa177562e..81be73c6a3093b5c04774a7ef5521953e13acd97 100644 (file)
@@ -5,11 +5,11 @@
 INCS+=  env.h fetch.h hgfs.h lib.h libutil.h timers.h
 
 INCS+=         minix/acpi.h minix/ansi.h minix/audio_fw.h minix/bitmap.h \
-       minix/bdev.h \
-       minix/callnr.h minix/com.h minix/compiler.h minix/config.h \
-       minix/const.h minix/cpufeature.h minix/crtso.h minix/debug.h \
-       minix/devio.h minix/devman.h minix/dmap.h minix/driver.h \
-       minix/driver_mt.h minix/drivers.h minix/drvlib.h minix/ds.h \
+       minix/bdev.h minix/blockdriver.h minix/blockdriver_mt.h \
+       minix/callnr.h minix/chardriver.h minix/com.h minix/compiler.h \
+       minix/config.h minix/const.h minix/cpufeature.h minix/crtso.h \
+       minix/debug.h minix/devio.h minix/devman.h minix/dmap.h \
+       minix/driver.h minix/drivers.h minix/drvlib.h minix/ds.h \
        minix/endpoint.h minix/fslib.h minix/gcov.h minix/hash.h \
        minix/ioctl.h minix/input.h minix/ipc.h minix/ipcconst.h \
        minix/keymap.h minix/limits.h minix/mthread.h minix/minlib.h \
index d1312671424c42183c6e16054d0b51813e904036..e93201ff27d689b21862f3a36339b3834f5242fb 100644 (file)
@@ -2,7 +2,7 @@
 #define AUDIO_FW_H
 
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 #include <sys/ioc_sound.h>
 
 
index e0ef8067c98b4198b29b2cc1794fe91cb6b2fc4c..827f293995d096b9686bb56ea759032eb8bfb8a7 100644 (file)
@@ -1,19 +1,19 @@
 #ifndef __MINIX_BDEV_H
 #define __MINIX_BDEV_H
 
-#define BDEV_NOFLAGS   0
-
 extern void bdev_driver(dev_t dev, endpoint_t endpt);
 
 extern int bdev_open(dev_t dev, int access);
 extern int bdev_close(dev_t dev);
 
-extern int bdev_read(dev_t dev, u64_t pos, char *buf, int count, int flags);
-extern int bdev_write(dev_t dev, u64_t pos, char *buf, int count, int flags);
-extern int bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count,
-       int flags, vir_bytes *size);
-extern int bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count,
-       int flags, vir_bytes *size);
+extern ssize_t bdev_read(dev_t dev, u64_t pos, char *buf, size_t count,
+       int flags);
+extern ssize_t bdev_write(dev_t dev, u64_t pos, char *buf, size_t count,
+       int flags);
+extern ssize_t bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count,
+       int flags);
+extern ssize_t bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count,
+       int flags);
 extern int bdev_ioctl(dev_t dev, int request, void *buf);
 
 #endif /* __MINIX_BDEV_H */
diff --git a/common/include/minix/blockdriver.h b/common/include/minix/blockdriver.h
new file mode 100644 (file)
index 0000000..2d212ec
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef _MINIX_BLOCKDRIVER_H
+#define _MINIX_BLOCKDRIVER_H
+
+#include <minix/driver.h>
+
+typedef int thread_id_t;
+
+/* Entry points into the device dependent code of block drivers. */
+struct blockdriver {
+  _PROTOTYPE( int (*bdr_open), (dev_t minor, int access) );
+  _PROTOTYPE( int (*bdr_close), (dev_t minor) );
+  _PROTOTYPE( ssize_t (*bdr_transfer), (dev_t minor, int do_write, u64_t pos,
+       endpoint_t endpt, iovec_t *iov, unsigned count, int flags) );
+  _PROTOTYPE( int (*bdr_ioctl), (dev_t minor, unsigned int request,
+       endpoint_t endpt, cp_grant_id_t grant) );
+  _PROTOTYPE( void (*bdr_cleanup), (void) );
+  _PROTOTYPE( struct device *(*bdr_part), (dev_t minor) );
+  _PROTOTYPE( void (*bdr_geometry), (dev_t minor, struct partition *part) );
+  _PROTOTYPE( void (*bdr_intr), (unsigned int irqs) );
+  _PROTOTYPE( void (*bdr_alarm), (clock_t stamp) );
+  _PROTOTYPE( int (*bdr_other), (message *m_ptr) );
+  _PROTOTYPE( int (*bdr_thread), (dev_t minor, thread_id_t *threadp) );
+};
+
+/* Functions defined by libblockdriver. These can be used for both
+ * singlethreaded and multithreaded drivers.
+ */
+_PROTOTYPE( void blockdriver_announce, (void) );
+
+#ifndef _DRIVER_MT_API
+/* Additional functions for the singlethreaded version. These allow the driver
+ * to either use the stock driver_task(), or implement its own message loop.
+ * To avoid accidents, these functions are not exposed when minix/driver_mt.h
+ * has been included previously.
+ */
+_PROTOTYPE( int blockdriver_receive_mq, (message *m_ptr, int *status_ptr) );
+_PROTOTYPE( void blockdriver_process, (struct blockdriver *dp, message *m_ptr,
+       int ipc_status) );
+_PROTOTYPE( void blockdriver_terminate, (void) );
+_PROTOTYPE( void blockdriver_task, (struct blockdriver *bdp) );
+_PROTOTYPE( int blockdriver_mq_queue, (message *m_ptr, int status) );
+#endif /* !_DRIVER_MT_API */
+
+/* Parameters for the disk drive. */
+#define SECTOR_SIZE      512   /* physical sector size in bytes */
+#define SECTOR_SHIFT       9   /* for division */
+#define SECTOR_MASK      511   /* and remainder */
+
+#define CD_SECTOR_SIZE  2048   /* sector size of a CD-ROM in bytes */
+
+/* Size of the DMA buffer buffer in bytes. */
+#define DMA_BUF_SIZE   (DMA_SECTORS * SECTOR_SIZE)
+
+#endif /* _MINIX_BLOCKDRIVER_H */
diff --git a/common/include/minix/blockdriver_mt.h b/common/include/minix/blockdriver_mt.h
new file mode 100644 (file)
index 0000000..143660f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _MINIX_BLOCKDRIVER_MT_H
+#define _MINIX_BLOCKDRIVER_MT_H
+
+#define DRIVER_MT_API 1                /* do not expose the singlethreaded API */
+#include <minix/blockdriver.h>
+
+/* The maximum number of worker threads. */
+#define DRIVER_MT_MAX_WORKERS  32
+
+_PROTOTYPE( void blockdriver_mt_task, (struct blockdriver *driver_tab) );
+_PROTOTYPE( void blockdriver_mt_sleep, (void) );
+_PROTOTYPE( void blockdriver_mt_wakeup, (thread_id_t id) );
+_PROTOTYPE( void blockdriver_mt_stop, (void) );
+_PROTOTYPE( void blockdriver_mt_terminate, (void) );
+
+#endif /* _MINIX_BLOCKDRIVER_MT_H */
diff --git a/common/include/minix/chardriver.h b/common/include/minix/chardriver.h
new file mode 100644 (file)
index 0000000..fe3f64d
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _MINIX_CHARDRIVER_H
+#define _MINIX_CHARDRIVER_H
+
+#include <minix/driver.h>
+
+/* Entry points into the device dependent code of character drivers. */
+struct chardriver {
+  _PROTOTYPE( int (*cdr_open), (message *m_ptr) );
+  _PROTOTYPE( int (*cdr_close), (message *m_ptr) );
+  _PROTOTYPE( int (*cdr_ioctl), (message *m_ptr) );
+  _PROTOTYPE( struct device *(*cdr_prepare), (dev_t device) );
+  _PROTOTYPE( int (*cdr_transfer), (endpoint_t endpt, int opcode,
+       u64_t position, iovec_t *iov, unsigned int nr_req,
+       endpoint_t user_endpt) );
+  _PROTOTYPE( void (*cdr_cleanup), (void) );
+  _PROTOTYPE( void (*cdr_alarm), (message *m_ptr) );
+  _PROTOTYPE( int (*cdr_cancel), (message *m_ptr) );
+  _PROTOTYPE( int (*cdr_select), (message *m_ptr) );
+  _PROTOTYPE( int (*cdr_other), (message *m_ptr) );
+};
+
+#define CHARDRIVER_SYNC                0       /* use the synchronous protocol */
+#define CHARDRIVER_ASYNC       1       /* use the asynchronous protocol */
+
+#define IS_CDEV_MINOR_RQ(type) (IS_DEV_RQ(type) && (type) != DEV_STATUS)
+
+/* Functions defined by libchardriver. */
+_PROTOTYPE( void chardriver_announce, (void) );
+_PROTOTYPE( void chardriver_process, (struct chardriver *cdp, int driver_type,
+       message *m_ptr, int ipc_status) );
+_PROTOTYPE( void chardriver_terminate, (void) );
+_PROTOTYPE( void chardriver_task, (struct chardriver *cdp, int driver_type) );
+
+_PROTOTYPE( int do_nop, (message *m_ptr) );
+_PROTOTYPE( void nop_cleanup, (void) );
+_PROTOTYPE( void nop_alarm, (message *m_ptr) );
+_PROTOTYPE( int nop_cancel, (message *m_ptr) );
+_PROTOTYPE( int nop_select, (message *m_ptr) );
+_PROTOTYPE( int nop_ioctl, (message *m_ptr) );
+
+#endif /* _MINIX_CHARDRIVER_H */
index dad34cf169339b5c9f6b059e0b5156fbe9caa135..d3d5d2809ec690875ae3e1bed4354de6adcb6ee7 100644 (file)
@@ -8,8 +8,8 @@
  *        1 -   0xFF   POSIX requests (see callnr.h)
  *    0x200 -  0x2FF   Data link layer requests and responses
  *    0x300 -  0x3FF   Bus controller requests and responses
- *    0x400 -  0x4FF   Block and character device requests
- *    0x500 -  0x5FF   Block and character device responses
+ *    0x400 -  0x4FF   Character device requests
+ *    0x500 -  0x5FF   Character device responses
  *    0x600 -  0x6FF   Kernel calls to SYSTEM task
  *    0x700 -  0x7FF   Reincarnation Server (RS) requests
  *    0x800 -  0x8FF   Data Store (DS) requests
@@ -25,6 +25,7 @@
  *   0x1200 - 0x12FF    Devman
  *   0x1300 - 0x13FF    TTY Input
  *   0x1400 - 0x14FF   VFS-FS transaction IDs
+ *   0x1500 - 0x15FF   Block device requests and responses
  *
  * Zero and negative values are widely used for OK and error responses.
  */
 
 
 /*===========================================================================*
- *                Messages for BLOCK and CHARACTER device drivers           *
+ *                Messages for CHARACTER device drivers                             *
  *===========================================================================*/
 
-/* Message types for device drivers. */
-#define DEV_RQ_BASE   0x400    /* base for device request types */
-#define DEV_RS_BASE   0x500    /* base for device response types */
+/* Message types for character device drivers. */
+#define DEV_RQ_BASE   0x400    /* base for character device request types */
+#define DEV_RS_BASE   0x500    /* base for character device response types */
 
 #define CANCEL         (DEV_RQ_BASE +  0) /* force a task to cancel */
 #define DEV_OPEN       (DEV_RQ_BASE +  6) /* open a minor device */
 
 #define IS_DEV_RS(type) (((type) & ~0xff) == DEV_RS_BASE)
 
-/* Field names for messages to block and character device drivers. */
+/* Field names for messages to character device drivers. */
 #define DEVICE         m2_i1   /* major-minor device */
 #define USER_ENDPT     m2_i2   /* which endpoint initiated this call? */
 #define COUNT          m2_i3   /* how many bytes to transfer */
 #define ADDRESS        m2_p1   /* core buffer address */
 #define IO_GRANT       m2_p1   /* grant id (for DEV_*_S variants) */
 
-/* Field names for DEV_SELECT messages to device drivers. */
+/* Field names for DEV_SELECT messages to character device drivers. */
 #define DEV_MINOR      m2_i1   /* minor device */
 #define DEV_SEL_OPS    m2_i2   /* which select operations are requested */
 
 #define VFS_TRANSID    (VFS_TRANSACTION_BASE + 1)
 #define IS_VFS_FS_TRANSID(type) (((type) & ~0xff) == VFS_TRANSACTION_BASE)
 
+/*===========================================================================*
+ *                     Messages for block devices                           *
+ *===========================================================================*/
+
+/* Base type for block device requests and responses. */
+#define BDEV_RQ_BASE   0x1500
+#define BDEV_RS_BASE   0x1580
+
+#define IS_BDEV_RQ(type) (((type) & ~0x7f) == BDEV_RQ_BASE)
+#define IS_BDEV_RS(type) (((type) & ~0x7f) == BDEV_RS_BASE)
+
+/* Message types for block device requests. */
+#define BDEV_OPEN      (BDEV_RQ_BASE + 0)      /* open a minor device */
+#define BDEV_CLOSE     (BDEV_RQ_BASE + 1)      /* close a minor device */
+#define BDEV_READ      (BDEV_RQ_BASE + 2)      /* read into a buffer */
+#define BDEV_WRITE     (BDEV_RQ_BASE + 3)      /* write from a buffer */
+#define BDEV_GATHER    (BDEV_RQ_BASE + 4)      /* read into a vector */
+#define BDEV_SCATTER   (BDEV_RQ_BASE + 5)      /* write from a vector */
+#define BDEV_IOCTL     (BDEV_RQ_BASE + 6)      /* I/O control operation */
+
+/* Message types for block device responses. */
+#define BDEV_REPLY     (BDEV_RS_BASE + 0)      /* general reply code */
+
+/* Field names for block device messages. */
+#define BDEV_MINOR     m10_i1  /* minor device number */
+#define BDEV_STATUS    m10_i1  /* OK or error code */
+#define BDEV_ACCESS    m10_i2  /* access bits for open requests */
+#define BDEV_REQUEST   m10_i2  /* I/O control request */
+#define BDEV_COUNT     m10_i2  /* number of bytes or elements in transfer */
+#define BDEV_GRANT     m10_i3  /* grant ID of buffer or vector */
+#define BDEV_FLAGS     m10_i4  /* transfer flags */
+#define BDEV_ID                m10_l1  /* opaque request ID */
+#define BDEV_POS_LO    m10_l2  /* transfer position (low bits) */
+#define BDEV_POS_HI    m10_l3  /* transfer position (high bits) */
+
+/* Bits in 'BDEV_FLAGS' field of block device transfer requests. */
+#  define BDEV_NOFLAGS         0x00    /* no flags are set */
+#  define BDEV_FORCEWRITE      0x01    /* force write to disk immediately */
+
 /* _MINIX_COM_H */
index f654a0ae1b34f61fea8e8ee580f8c97276db82ec..8a2b3c8fe5e42a87c6e0c76c16e026ecf2a8eb59 100644 (file)
@@ -28,8 +28,8 @@ typedef struct { u16_t port; u32_t value; } pvl_pair_t;
        (pv).port = _p;                                         \
        (pv).value = _v;                                        \
        if((pv).port != _p || (pv).value != _v) {               \
-               printf("%s:%d: actual port: 0x%x != 0x%lx || "  \
-                       "actual value: 0x%x != 0x%lx\n",        \
+               printf("%s:%d: actual port: 0x%x != 0x%x || "   \
+                       "actual value: 0x%x != 0x%x\n", \
                        __FILE__, __LINE__, (pv).port, _p, (pv).value, _v); \
                panic("pv_set(" #pv ", " #p ", " #v ")"); \
        }                                                       \
index 0e770c16caa32434e67685ab975b5c609a2cef36..1b9602d11842f792760267da8cdcfccf2b77e4d8 100644 (file)
@@ -1,9 +1,7 @@
-#ifndef __MINIX_DRIVER_H__
-#define __MINIX_DRIVER_H__
+#ifndef _MINIX_DRIVER_H
+#define _MINIX_DRIVER_H
 
-/* Types and constants shared between the generic and device dependent
- * device driver code.
- */
+/* Types and constants shared between block and character drivers. */
 
 #define _POSIX_SOURCE      1   /* tell headers to include POSIX stuff */
 #define _MINIX             1   /* tell headers to include MINIX stuff */
 #include <minix/syslib.h>
 #include <minix/sysutil.h>
 #include <minix/endpoint.h>
-
 #include <string.h>
 #include <limits.h>
 #include <stddef.h>
 #include <errno.h>
 #include <sys/param.h>
-
-#include <minix/partition.h>
 #include <minix/u64.h>
-
-typedef int thread_id_t;
-
-/* Info about and entry points into the device dependent code. */
-struct driver {
-  _PROTOTYPE( char *(*dr_name), (void) );
-  _PROTOTYPE( int (*dr_open), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( struct device *(*dr_prepare), (int device) );
-  _PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, u64_t position,
-                                       iovec_t *iov, unsigned nr_req) );
-  _PROTOTYPE( void (*dr_cleanup), (void) );
-  _PROTOTYPE( void (*dr_geometry), (struct partition *entry) );
-  _PROTOTYPE( void (*dr_alarm), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( int (*dr_cancel), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( int (*dr_select), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( int (*dr_other), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( void (*dr_hw_int), (struct driver *dp, message *m_ptr) );
-  _PROTOTYPE( int (*dr_thread), (dev_t dev, thread_id_t *threadp) );
-};
+#include <minix/partition.h>
 
 /* Base and size of a partition in bytes. */
 struct device {
@@ -58,52 +33,12 @@ struct device {
   u64_t dv_size;
 };
 
-#define DRIVER_STD     0       /* Use the standard reply protocol */
-#define DRIVER_ASYN    1       /* Use the new asynchronous protocol */
+/* Generic receive function for all drivers. */
+#ifndef driver_receive
+#define driver_receive sef_receive_status
+#endif
 
+/* Maximum supported number of concurrently opened minor devices. */
 #define MAX_NR_OPEN_DEVICES 256
 
-#define IS_DEV_MINOR_RQ(type) (IS_DEV_RQ(type) && (type) != DEV_STATUS)
-
-/* Functions defined by libdriver. These can be used for both singlethreaded
- * and multithreaded drivers.
- */
-_PROTOTYPE( void driver_announce, (void) );
-_PROTOTYPE( char *no_name, (void) );
-_PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( struct device *nop_prepare, (int device) );
-_PROTOTYPE( void nop_cleanup, (void) );
-_PROTOTYPE( void nop_task, (void) );
-_PROTOTYPE( void nop_alarm, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( int nop_cancel, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr) );
-
-#ifndef _DRIVER_MT_API
-/* Additional functions for the singlethreaded version. These allow the driver
- * to either use the stock driver_task(), or implement its own message loop.
- * To avoid accidents, these functions are not exposed when minix/driver_mt.h
- * has been included previously.
- */
-_PROTOTYPE( int driver_receive, (endpoint_t src, message *m_ptr,
-       int *status_ptr) );
-_PROTOTYPE( int driver_receive_mq, (message *m_ptr, int *status_ptr) );
-_PROTOTYPE( void driver_handle_msg, (struct driver *dp, int type,
-       message *m_ptr, int ipc_status) );
-_PROTOTYPE( void driver_terminate, (void) );
-_PROTOTYPE( void driver_task, (struct driver *dr, int type) );
-_PROTOTYPE( int driver_mq_queue, (message *m_ptr, int status) );
-#endif /* !_DRIVER_MT_API */
-
-/* Parameters for the disk drive. */
-#define SECTOR_SIZE      512   /* physical sector size in bytes */
-#define SECTOR_SHIFT       9   /* for division */
-#define SECTOR_MASK      511   /* and remainder */
-
-#define CD_SECTOR_SIZE  2048   /* sector size of a CD-ROM in bytes */
-
-/* Size of the DMA buffer buffer in bytes. */
-#define DMA_BUF_SIZE   (DMA_SECTORS * SECTOR_SIZE)
-
-#endif /* __MINIX_DRIVER_H__ */
+#endif /* _MINIX_DRIVER_H */
diff --git a/common/include/minix/driver_mt.h b/common/include/minix/driver_mt.h
deleted file mode 100644 (file)
index 05c10f1..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _MINIX_DRIVER_MT_H
-#define _MINIX_DRIVER_MT_H
-
-#define DRIVER_MT_API 1                /* do not expose the singlethreaded API */
-#include <minix/driver.h>
-
-/* The maximum number of worker threads. */
-#define DRIVER_MT_MAX_WORKERS  32
-
-_PROTOTYPE( void driver_mt_task, (struct driver *driver_p, int driver_type) );
-_PROTOTYPE( void driver_mt_sleep, (void) );
-_PROTOTYPE( void driver_mt_wakeup, (thread_id_t id) );
-_PROTOTYPE( void driver_mt_stop, (void) );
-_PROTOTYPE( void driver_mt_terminate, (void) );
-
-#endif /* _MINIX_DRIVER_MT_H */
index 013eca8572dda107924bfda99dd1b3186928f2a6..f83b7f369cb4895e7dbb0f0e77aac849e53ea842 100644 (file)
@@ -4,19 +4,9 @@
 
 #include <machine/partition.h>
 
-_PROTOTYPE( void partition, (struct driver *dr, int device, int style, int atapi) );
+_PROTOTYPE( void partition, (struct blockdriver *bdr, int device, int style,
+       int atapi) );
 
-/* BIOS parameter table layout. */
-#define bp_cylinders(t)                (* (u16_t *) (&(t)[0]))
-#define bp_heads(t)            (* (u8_t *)  (&(t)[2]))
-#define bp_reduced_wr(t)       (* (u16_t *) (&(t)[3]))
-#define bp_precomp(t)          (* (u16_t *) (&(t)[5]))
-#define bp_max_ecc(t)          (* (u8_t *)  (&(t)[7]))
-#define bp_ctlbyte(t)          (* (u8_t *)  (&(t)[8]))
-#define bp_landingzone(t)      (* (u16_t *) (&(t)[12]))
-#define bp_sectors(t)          (* (u8_t *)  (&(t)[14]))
-
-/* Miscellaneous. */
 #define DEV_PER_DRIVE  (1 + NR_PARTITIONS)
 #define MINOR_t0       64
 #define MINOR_r0       120
index 8ce24a47964a04a941588c9c862df98703aa1fc1..5f166346c1d933019cec162c00b40f457b8f2b1e 100644 (file)
@@ -29,6 +29,8 @@ typedef struct {int m7i1, m7i2, m7i3, m7i4, m7i5; char *m7p1, *m7p2;} mess_7;
 typedef struct {int m8i1, m8i2; char *m8p1, *m8p2, *m8p3, *m8p4;} mess_8;
 typedef struct {long m9l1, m9l2, m9l3, m9l4, m9l5;
        short m9s1, m9s2, m9s3, m9s4; } mess_9;
+typedef struct {int m10i1, m10i2, m10i3, m10i4;
+       long m10l1, m10l2, m10l3; } mess_10;
 
 typedef struct {
   endpoint_t m_source;         /* who sent the message */
@@ -43,6 +45,7 @@ typedef struct {
        mess_8 m_m8;
        mess_6 m_m6;
        mess_9 m_m9;
+       mess_10 m_m10;
   } m_u;
 } message;
 
@@ -118,6 +121,14 @@ typedef struct {
 #define m9_s3  m_u.m_m9.m9s3
 #define m9_s4  m_u.m_m9.m9s4
 
+#define m10_i1 m_u.m_m10.m10i1
+#define m10_i2 m_u.m_m10.m10i2
+#define m10_i3 m_u.m_m10.m10i3
+#define m10_i4 m_u.m_m10.m10i4
+#define m10_l1 m_u.m_m10.m10l1
+#define m10_l2 m_u.m_m10.m10l2
+#define m10_l3 m_u.m_m10.m10l3
+
 /*==========================================================================* 
  * Minix run-time system (IPC).                                            *
  *==========================================================================*/ 
index 11beadb5465b7f0ca23b14436ba34ef6cf47f2ab..bfdc49357730c74e8e3621d1171f7d0658aec93c 100644 (file)
@@ -138,8 +138,8 @@ ACPICA_SRCS= \
 
 SRCS+=${ACPICA_SRCS} 
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+=        ${LIBSYS}
+LDADD+=        -lsys
 
 CPPFLAGS += -I${.CURDIR}/include
 CFLAGS += -DACPI_LIBRARY
index 336bd1bdbd887e759c82fa2687ea1e0d30af929e..3484b5b3e9a11092de4ecc18822dbc03dc744d33 100644 (file)
@@ -2,8 +2,12 @@
 PROG=  ahci
 SRCS=  ahci.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys -ltimers -lmthread
+DPADD+=        ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBTIMERS} ${LIBMTHREAD}
+LDADD+=        -lblockdriver -lsys -ltimers -lmthread
+
+.if ${COMPILER_TYPE} == "gnu"
+LDADD+=        -lc
+.endif
 
 MAN=
 
index bb22674110c567425220cd0717a35817a6d85935..675d95e80c2ecfd68f0ed9d83f1aef4ac6b526de 100644 (file)
  *   vectors completely filled with 64KB-blocks.
  */
 #include <minix/drivers.h>
-#include <minix/driver_mt.h>
+#include <minix/blockdriver_mt.h>
 #include <minix/drvlib.h>
 #include <machine/pci.h>
 #include <sys/ioc_disk.h>
@@ -180,9 +180,6 @@ PRIVATE int ahci_map[MAX_DRIVES];           /* device-to-port mapping */
 
 PRIVATE int ahci_exiting = FALSE;              /* exit after last close? */
 
-PRIVATE struct port_state *current_port;       /* currently selected port */
-PRIVATE struct device *current_dev;            /* currently selected device */
-
 #define dprintf(v,s) do {              \
        if (ahci_verbose >= (v))        \
                printf s;               \
@@ -195,35 +192,32 @@ PRIVATE int port_exec(struct port_state *ps, int cmd, clock_t timeout);
 PRIVATE void port_timeout(struct timer *tp);
 PRIVATE void port_disconnect(struct port_state *ps);
 
-PRIVATE char *ahci_name(void);
 PRIVATE char *ahci_portname(struct port_state *ps);
-PRIVATE int ahci_open(struct driver *UNUSED(dp), message *m);
-PRIVATE int ahci_close(struct driver *UNUSED(dp), message *m);
-PRIVATE struct device *ahci_prepare(int minor);
-PRIVATE int ahci_transfer(endpoint_t endpt, int opcode, u64_t position,
-       iovec_t *iovec, unsigned int nr_req);
-PRIVATE void ahci_geometry(struct partition *part);
-PRIVATE void ahci_alarm(struct driver *UNUSED(dp), message *m);
-PRIVATE int ahci_other(struct driver *UNUSED(dp), message *m);
-PRIVATE void ahci_intr(struct driver *UNUSED(dp), message *m);
+PRIVATE int ahci_open(dev_t minor, int access);
+PRIVATE int ahci_close(dev_t minor);
+PRIVATE ssize_t ahci_transfer(dev_t minor, int do_write, u64_t position,
+       endpoint_t endpt, iovec_t *iovec, unsigned int count,
+       int flags);
+PRIVATE struct device *ahci_part(dev_t minor);
+PRIVATE void ahci_alarm(clock_t stamp);
+PRIVATE int ahci_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
+       cp_grant_id_t grant);
+PRIVATE void ahci_intr(unsigned int irqs);
 PRIVATE int ahci_thread(dev_t minor, thread_id_t *id);
 PRIVATE struct port_state *ahci_get_port(dev_t minor);
 
 /* AHCI driver table. */
-PRIVATE struct driver ahci_dtab = {
-       ahci_name,
+PRIVATE struct blockdriver ahci_dtab = {
        ahci_open,
        ahci_close,
-       do_diocntl,
-       ahci_prepare,
        ahci_transfer,
-       nop_cleanup,
-       ahci_geometry,
-       ahci_alarm,
-       nop_cancel,
-       nop_select,
-       ahci_other,
+       ahci_ioctl,
+       NULL,           /* bdr_cleanup */
+       ahci_part,
+       NULL,           /* bdr_geometry */
        ahci_intr,
+       ahci_alarm,
+       NULL,           /* bdr_other */
        ahci_thread
 };
 
@@ -950,16 +944,16 @@ PRIVATE int setup_prdt(struct port_state *ps, endpoint_t endpt,
 /*===========================================================================*
  *                             port_transfer                                *
  *===========================================================================*/
-PRIVATE int port_transfer(struct port_state *ps, int cmd, u64_t pos, u64_t eof,
-       endpoint_t endpt, iovec_s_t *iovec, int nr_req, int write)
+PRIVATE ssize_t port_transfer(struct port_state *ps, int cmd, u64_t pos,
+       u64_t eof, endpoint_t endpt, iovec_s_t *iovec, int nr_req, int write)
 {
        /* Perform an I/O transfer on a port.
         */
        prd_t prdt[NR_PRDS];
-       vir_bytes size, lead, chunk;
+       vir_bytes size, lead;
        unsigned int count, nr_prds;
        u64_t start_lba;
-       int i, r;
+       int r;
 
        /* Get the total request size from the I/O vector. */
        if ((r = sum_iovec(ps, endpt, iovec, nr_req, &size)) != OK)
@@ -996,7 +990,7 @@ PRIVATE int port_transfer(struct port_state *ps, int cmd, u64_t pos, u64_t eof,
        if ((lead & 1) || (write && lead != 0)) {
                dprintf(V_ERR, ("%s: unaligned position from %d\n",
                        ahci_portname(ps), endpt));
-               return EIO;
+               return EINVAL;
        }
 
        /* Write requests must be sector-aligned. Word alignment of the size is
@@ -1005,7 +999,7 @@ PRIVATE int port_transfer(struct port_state *ps, int cmd, u64_t pos, u64_t eof,
        if (write && (size % ps->sector_size) != 0) {
                dprintf(V_ERR, ("%s: unaligned size %lu from %d\n",
                        ahci_portname(ps), size, endpt));
-               return EIO;
+               return EINVAL;
        }
 
        /* Create a vector of physical addresses and sizes for the transfer. */
@@ -1021,17 +1015,9 @@ PRIVATE int port_transfer(struct port_state *ps, int cmd, u64_t pos, u64_t eof,
                r = ata_transfer(ps, cmd, start_lba, count, write, prdt,
                        nr_prds);
 
-       if (r < 0) return r;
-
-       /* The entire operation succeeded; update the original vector. */
-       for (i = 0; i < nr_req && size > 0; i++) {
-               chunk = MIN(iovec[i].iov_size, size);
-
-               iovec[i].iov_size -= chunk;
-               size -= chunk;
-       }
+       if (r != OK) return r;
 
-       return OK;
+       return size;
 }
 
 /*===========================================================================*
@@ -1478,7 +1464,7 @@ PRIVATE void port_timeout(struct timer *tp)
         * is suspended.
         */
        if (ps->flags & FLAG_SUSPENDED)
-               driver_mt_wakeup(ps->device);
+               blockdriver_mt_wakeup(ps->device);
 
        /* If detection of a device after startup timed out, give up on initial
         * detection and only look for hot plug events from now on.
@@ -1554,7 +1540,7 @@ PRIVATE void port_wait(struct port_state *ps)
        ps->flags |= FLAG_SUSPENDED;
 
        while (ps->flags & FLAG_BUSY)
-               driver_mt_sleep();
+               blockdriver_mt_sleep();
 
        ps->flags &= ~FLAG_SUSPENDED;
 }
@@ -1865,9 +1851,9 @@ PRIVATE void ahci_init(int devind)
        hba_state.nr_cmds = MIN(NR_CMDS,
                ((cap >> AHCI_HBA_CAP_NCS_SHIFT) & AHCI_HBA_CAP_NCS_MASK) + 1);
 
-       dprintf(V_INFO, ("%s: HBA v%d.%d%d, %ld ports, %ld commands, "
+       dprintf(V_INFO, ("AHCI%u: HBA v%d.%d%d, %ld ports, %ld commands, "
                "%s queuing, IRQ %d\n",
-               ahci_name(),
+               ahci_instance,
                (int) (hba_state.base[AHCI_HBA_VS] >> 16),
                (int) ((hba_state.base[AHCI_HBA_VS] >> 8) & 0xFF),
                (int) (hba_state.base[AHCI_HBA_VS] & 0xFF),
@@ -1875,8 +1861,8 @@ PRIVATE void ahci_init(int devind)
                ((cap >> AHCI_HBA_CAP_NCS_SHIFT) & AHCI_HBA_CAP_NCS_MASK) + 1,
                (cap & AHCI_HBA_CAP_SNCQ) ? "supports" : "no",
                hba_state.irq));
-       dprintf(V_INFO, ("%s: CAP %08x, CAP2 %08x, PI %08x\n",
-               ahci_name(), cap, hba_state.base[AHCI_HBA_CAP2],
+       dprintf(V_INFO, ("AHCI%u: CAP %08x, CAP2 %08x, PI %08x\n",
+               ahci_instance, cap, hba_state.base[AHCI_HBA_CAP2],
                hba_state.base[AHCI_HBA_PI]));
 
        /* Initialize each of the implemented ports. We ignore CAP.NP. */
@@ -1924,19 +1910,19 @@ PRIVATE void ahci_stop(void)
 /*===========================================================================*
  *                             ahci_alarm                                   *
  *===========================================================================*/
-PRIVATE void ahci_alarm(struct driver *UNUSED(dp), message *m)
+PRIVATE void ahci_alarm(clock_t stamp)
 {
        /* Process an alarm.
         */
 
        /* Call the port-specific handler for each port that timed out. */
-       expire_timers(m->NOTIFY_TIMESTAMP);
+       expire_timers(stamp);
 }
 
 /*===========================================================================*
  *                             ahci_intr                                    *
  *===========================================================================*/
-PRIVATE void ahci_intr(struct driver *UNUSED(dr), message *UNUSED(m))
+PRIVATE void ahci_intr(unsigned int UNUSED(irqs))
 {
        /* Process an interrupt.
         */
@@ -1958,7 +1944,7 @@ PRIVATE void ahci_intr(struct driver *UNUSED(dr), message *UNUSED(m))
                         */
                        if ((ps->flags & (FLAG_SUSPENDED | FLAG_BUSY)) ==
                                        FLAG_SUSPENDED)
-                               driver_mt_wakeup(ps->device);
+                               blockdriver_mt_wakeup(ps->device);
                }
        }
 
@@ -2093,8 +2079,8 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
        /* Create a mapping from device nodes to port numbers. */
        ahci_set_mapping();
 
-       /* Announce we are up. */
-       driver_announce();
+       /* Announce that we are up. */
+       blockdriver_announce();
 
        return OK;
 }
@@ -2145,21 +2131,6 @@ PRIVATE void sef_local_startup(void)
        sef_startup();
 }
 
-/*===========================================================================*
- *                             ahci_name                                    *
- *===========================================================================*/
-PRIVATE char *ahci_name(void)
-{
-       /* Return a printable name for the controller. We avoid the use of the
-        * currently selected port, as it may not be accurate.
-        */
-       static char name[] = "AHCI0";
-
-       name[4] = '0' + ahci_instance;
-
-       return name;
-}
-
 /*===========================================================================*
  *                             ahci_portname                                *
  *===========================================================================*/
@@ -2188,17 +2159,18 @@ PRIVATE char *ahci_portname(struct port_state *ps)
 }
 
 /*===========================================================================*
- *                             ahci_prepare                                 *
+ *                             ahci_map_minor                               *
  *===========================================================================*/
-PRIVATE struct device *ahci_prepare(int minor)
+PRIVATE struct port_state *ahci_map_minor(dev_t minor, struct device **dvp)
 {
-       /* Select a device, in the form of a port and (sub)partition, based on
-        * the given minor device number and the device-to-port mapping.
+       /* Map a minor device number to a port and a pointer to the partition's
+        * device structure. Return NULL if this minor device number does not
+        * identify an actual device.
         */
+       struct port_state *ps;
        int port;
 
-       current_port = NULL;
-       current_dev = NULL;
+       ps = NULL;
 
        if (minor < NR_MINORS) {
                port = ahci_map[minor / DEV_PER_DRIVE];
@@ -2206,8 +2178,8 @@ PRIVATE struct device *ahci_prepare(int minor)
                if (port == NO_PORT)
                        return NULL;
 
-               current_port = &port_state[port];
-               current_dev = &current_port->part[minor % DEV_PER_DRIVE];
+               ps = &port_state[port];
+               *dvp = &ps->part[minor % DEV_PER_DRIVE];
        }
        else if ((unsigned) (minor -= MINOR_d0p0s0) < NR_SUBDEVS) {
                port = ahci_map[minor / SUB_PER_DRIVE];
@@ -2215,24 +2187,40 @@ PRIVATE struct device *ahci_prepare(int minor)
                if (port == NO_PORT)
                        return NULL;
 
-               current_port = &port_state[port];
-               current_dev = &current_port->subpart[minor % SUB_PER_DRIVE];
+               ps = &port_state[port];
+               *dvp = &ps->subpart[minor % SUB_PER_DRIVE];
        }
 
-       return current_dev;
+       return ps;
+}
+
+/*===========================================================================*
+ *                             ahci_part                                    *
+ *===========================================================================*/
+PRIVATE struct device *ahci_part(dev_t minor)
+{
+       /* Return a pointer to the partition information structure of the given
+        * minor device.
+        */
+       struct device *dv;
+
+       if (ahci_map_minor(minor, &dv) == NULL)
+               return NULL;
+
+       return dv;
 }
 
 /*===========================================================================*
  *                             ahci_open                                    *
  *===========================================================================*/
-PRIVATE int ahci_open(struct driver *UNUSED(dp), message *m)
+PRIVATE int ahci_open(dev_t minor, int access)
 {
        /* Open a device.
         */
        struct port_state *ps;
        int r;
 
-       ps = ahci_get_port(m->DEVICE);
+       ps = ahci_get_port(minor);
 
        /* If we are still in the process of initializing this port or device,
         * wait for completion of that phase first.
@@ -2247,7 +2235,7 @@ PRIVATE int ahci_open(struct driver *UNUSED(dp), message *m)
        }
 
        /* Some devices may only be opened in read-only mode. */
-       if ((ps->flags & FLAG_READONLY) && (m->COUNT & W_BIT)) {
+       if ((ps->flags & FLAG_READONLY) && (access & W_BIT)) {
                r = EACCES;
                goto err_stop;
        }
@@ -2290,7 +2278,7 @@ PRIVATE int ahci_open(struct driver *UNUSED(dp), message *m)
 err_stop:
        /* Stop the thread if the device is now fully closed. */
        if (ps->open_count == 0)
-               driver_mt_stop();
+               blockdriver_mt_stop();
 
        return r;
 }
@@ -2298,14 +2286,14 @@ err_stop:
 /*===========================================================================*
  *                             ahci_close                                   *
  *===========================================================================*/
-PRIVATE int ahci_close(struct driver *UNUSED(dp), message *m)
+PRIVATE int ahci_close(dev_t minor)
 {
        /* Close a device.
         */
        struct port_state *ps;
        int port;
 
-       ps = ahci_get_port(m->DEVICE);
+       ps = ahci_get_port(minor);
 
        /* Decrease the open count. */
        if (ps->open_count <= 0) {
@@ -2323,7 +2311,7 @@ PRIVATE int ahci_close(struct driver *UNUSED(dp), message *m)
        /* The device is now fully closed. That also means that the thread for
         * this device is not needed anymore.
         */
-       driver_mt_stop();
+       blockdriver_mt_stop();
 
        if (ps->state == STATE_GOOD_DEV && !(ps->flags & FLAG_BARRIER)) {
                dprintf(V_INFO, ("%s: flushing write cache\n",
@@ -2333,8 +2321,8 @@ PRIVATE int ahci_close(struct driver *UNUSED(dp), message *m)
        }
 
        /* If the entire driver has been told to terminate, check whether all
-        * devices are now closed. If so, tell libdriver to quit after replying
-        * to the close request.
+        * devices are now closed. If so, tell libblockdriver to quit after
+        * replying to the close request.
         */
        if (ahci_exiting) {
                for (port = 0; port < hba_state.nr_ports; port++)
@@ -2344,7 +2332,7 @@ PRIVATE int ahci_close(struct driver *UNUSED(dp), message *m)
                if (port == hba_state.nr_ports) {
                        ahci_stop();
 
-                       driver_mt_terminate();
+                       blockdriver_mt_terminate();
                }
        }
 
@@ -2354,76 +2342,53 @@ PRIVATE int ahci_close(struct driver *UNUSED(dp), message *m)
 /*===========================================================================*
  *                             ahci_transfer                                *
  *===========================================================================*/
-PRIVATE int ahci_transfer(endpoint_t endpt, int opcode, u64_t position,
-       iovec_t *iovec, unsigned int nr_req)
+PRIVATE ssize_t ahci_transfer(dev_t minor, int do_write, u64_t position,
+       endpoint_t endpt, iovec_t *iovec, unsigned int count,
+       int UNUSED(flags))
 {
        /* Perform data transfer on the selected device.
         */
+       struct port_state *ps;
+       struct device *dv;
        u64_t pos, eof;
 
-       /* We can safely use current_port, as we won't get interrupted until
-        * the call to port_transfer(), after which it is no longer used.
-        * Nonpreemptive threading guarantees that we will not be descheduled
-        * before then.
-        */
-       assert(current_port != NULL);
-       assert(current_dev != NULL);
+       ps = ahci_get_port(minor);
+       dv = ahci_part(minor);
 
-       if (current_port->state != STATE_GOOD_DEV ||
-               (current_port->flags & FLAG_BARRIER))
+       if (ps->state != STATE_GOOD_DEV || (ps->flags & FLAG_BARRIER))
                return EIO;
 
-       if (nr_req > NR_IOREQS)
+       if (count > NR_IOREQS)
                return EINVAL;
 
        /* Check for basic end-of-partition condition: if the start position of
         * the request is outside the partition, return success immediately.
         * The size of the request is obtained, and possibly reduced, later.
         */
-       if (cmp64(position, current_dev->dv_size) >= 0)
+       if (cmp64(position, dv->dv_size) >= 0)
                return OK;
 
-       pos = add64(current_dev->dv_base, position);
-       eof = add64(current_dev->dv_base, current_dev->dv_size);
+       pos = add64(dv->dv_base, position);
+       eof = add64(dv->dv_base, dv->dv_size);
 
-       return port_transfer(current_port, 0, pos, eof, endpt,
-               (iovec_s_t *) iovec, nr_req, opcode == DEV_SCATTER_S);
+       return port_transfer(ps, 0, pos, eof, endpt, (iovec_s_t *) iovec,
+               count, do_write);
 }
 
 /*===========================================================================*
- *                             ahci_geometry                                *
+ *                             ahci_ioctl                                   *
  *===========================================================================*/
-PRIVATE void ahci_geometry(struct partition *part)
+PRIVATE int ahci_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
+       cp_grant_id_t grant)
 {
-       /* Fill in old-style geometry. We have to supply nonzero numbers, or
-        * part(8) crashes.
-        */
-
-       assert(current_port->sector_size != 0);
-
-       part->cylinders = div64u(current_port->part[0].dv_size,
-               current_port->sector_size) / (64 * 32);
-       part->heads = 64;
-       part->sectors = 32;
-}
-
-/*===========================================================================*
- *                             ahci_other                                   *
- *===========================================================================*/
-PRIVATE int ahci_other(struct driver *UNUSED(dp), message *m)
-{
-       /* Process any messages not covered by the other calls.
-        * This function only implements IOCTLs.
+       /* Process I/O control requests.
         */
        struct port_state *ps;
        int r, val;
 
-       if (m->m_type != DEV_IOCTL_S)
-               return EINVAL;
-
-       ps = ahci_get_port(m->DEVICE);
+       ps = ahci_get_port(minor);
 
-       switch (m->REQUEST) {
+       switch (request) {
        case DIOCEJECT:
                if (ps->state != STATE_GOOD_DEV || (ps->flags & FLAG_BARRIER))
                        return EIO;
@@ -2434,9 +2399,8 @@ PRIVATE int ahci_other(struct driver *UNUSED(dp), message *m)
                return atapi_load_eject(ps, 0, FALSE /*load*/);
 
        case DIOCOPENCT:
-               return sys_safecopyto(m->m_source, (cp_grant_id_t) m->IO_GRANT,
-                       0, (vir_bytes) &ps->open_count, sizeof(ps->open_count),
-                       D);
+               return sys_safecopyto(endpt, grant, 0,
+                       (vir_bytes) &ps->open_count, sizeof(ps->open_count), D);
 
        case DIOCFLUSH:
                if (ps->state != STATE_GOOD_DEV || (ps->flags & FLAG_BARRIER))
@@ -2448,8 +2412,7 @@ PRIVATE int ahci_other(struct driver *UNUSED(dp), message *m)
                if (ps->state != STATE_GOOD_DEV || (ps->flags & FLAG_BARRIER))
                        return EIO;
 
-               if ((r = sys_safecopyfrom(m->m_source,
-                       (cp_grant_id_t) m->IO_GRANT, 0, (vir_bytes) &val,
+               if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &val,
                        sizeof(val), D)) != OK)
                        return r;
 
@@ -2462,8 +2425,8 @@ PRIVATE int ahci_other(struct driver *UNUSED(dp), message *m)
                if ((r = gen_get_wcache(ps, 0, &val)) != OK)
                        return r;
 
-               return sys_safecopyto(m->m_source, (cp_grant_id_t) m->IO_GRANT,
-                       0, (vir_bytes) &val, sizeof(val), D);
+               return sys_safecopyto(endpt, grant, 0, (vir_bytes) &val,
+                       sizeof(val), D);
        }
 
        return EINVAL;
@@ -2476,11 +2439,13 @@ PRIVATE int ahci_thread(dev_t minor, thread_id_t *id)
 {
        /* Map a device number to a worker thread number. 
         */
+       struct port_state *ps;
+       struct device *dv;
 
-       if (ahci_prepare(minor) == NULL)
+       if ((ps = ahci_map_minor(minor, &dv)) == NULL)
                return ENXIO;
 
-       *id = current_port->device;
+       *id = ps->device;
 
        return OK;
 }
@@ -2494,11 +2459,13 @@ PRIVATE struct port_state *ahci_get_port(dev_t minor)
         * Called only from worker threads, so the minor device is already
         * guaranteed to map to a port.
         */
+       struct port_state *ps;
+       struct device *dv;
 
-       if (ahci_prepare(minor) == NULL)
+       if ((ps = ahci_map_minor(minor, &dv)) == NULL)
                panic("device mapping for minor %d disappeared", minor);
 
-       return current_port;
+       return ps;
 }
 
 /*===========================================================================*
@@ -2512,7 +2479,7 @@ PUBLIC int main(int argc, char **argv)
        env_setargs(argc, argv);
        sef_local_startup();
 
-       driver_mt_task(&ahci_dtab, DRIVER_STD);
+       blockdriver_mt_task(&ahci_dtab);
 
        return 0;
 }
index 731336a9bc2dbc939f2b3e81345a549862a3bf7e..c5ab636ed5b08333017558fe03cdc3c8eaf3c5e0 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  amddev
 SRCS=  amddev.c
 
-DPADD+= ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+= ${LIBSYS}
+LDADD+=        -lsys
 
 MAN=
 
index 8f9528f24938794755f12fc957c090561d11ec95..30fb4b7fe2fd935fde6a1e5fea47584c5a68c1fb 100644 (file)
@@ -113,7 +113,7 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the amddev driver. */
        int r, n_maps, n_domains, revision;
@@ -150,9 +150,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
 
        printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0));
 
-       /* Announce we are up! */
-       driver_announce();
-
        return(OK);
 }
 
@@ -184,7 +181,7 @@ PRIVATE void sef_cb_signal_handler(int signo)
                }
 
                printf(
-               "amddev: deleting 0x%x@0x%x for proc %d\n",
+               "amddev: deleting 0x%lx@0x%lx for proc %d\n",
                        size, base, proc_e);
                del_range(base, size);
                r= deldma(proc_e, base, size);
@@ -302,7 +299,7 @@ static void init_domain(int index)
                memset(table, 0x00, size);
        }
 
-printf("init_domain: busaddr = %p\n", busaddr);
+printf("init_domain: busaddr = 0x%lx\n", busaddr);
 
        write_reg(DEVF_BASE_HI, index, 0);
        write_reg(DEVF_BASE_LO, index, busaddr | 3);
@@ -387,12 +384,12 @@ static int do_add4pci(const message *m)
        pci_func= m->m1_i3;
 
        printf(
-"amddev`do_add4pci: got request for 0x%x@0x%x from %d for pci dev %u.%u.%u\n",
+"amddev`do_add4pci: got request for 0x%x@0x%lx from %d for pci dev %u.%u.%u\n",
                size, start, proc, pci_bus, pci_dev, pci_func);
 
        if (start % I386_PAGE_SIZE)
        {
-               printf("amddev`do_add4pci: bad start 0x%x from proc %d\n",
+               printf("amddev`do_add4pci: bad start 0x%lx from proc %d\n",
                        start, proc);
                return EINVAL;
        }
@@ -409,7 +406,7 @@ static int do_add4pci(const message *m)
        if (r != OK)
        {
                printf(
-               "amddev`do_add4pci: umap failed for 0x%x@0x%x, proc %d: %d\n",
+               "amddev`do_add4pci: umap failed for 0x%x@0x%lx, proc %d: %d\n",
                        size, start, proc, r);
                return r;
        }
@@ -419,7 +416,7 @@ static int do_add4pci(const message *m)
        {
                r= -errno;
                printf(
-               "amddev`do_add4pci: adddma failed for 0x%x@0x%x, proc %d: %d\n",
+               "amddev`do_add4pci: adddma failed for 0x%x@0x%lx, proc %d: %d\n",
                        size, start, proc, r);
                return r;
        }
index 25aece4c62884409d149f2d2773519cfdc3d672f..19556a45e7ee8d10a403d7c5744e748b912128dc 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  at_wini
 SRCS=  at_wini.c liveupdate.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
-LDADD+=        -ldriver -lsys -ltimers
+DPADD+=        ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+=        -lblockdriver -lsys -ltimers
 
 MAN=
 
index 38277799392f1b4a9161c9099b4a0c1baf4f70f0..400e801c6f5f51a598ca4afb860df4d62c26225d 100644 (file)
@@ -133,7 +133,7 @@ PRIVATE struct quirk
        { 0x01, 0x04,   0x00,   0x1106, 0x3149  },      /* VIA VT6420 */
        { 0x01, 0x04,   0x00,   0x1095, 0x3512  },
        { 0x01, 0x80,   -1,     0x1095, 0x3114  },      /* Silicon Image SATA */
-       { 0,    0,      0,      0       }       /* end of list */
+       { 0,    0,      0,      0,      0       }       /* end of list */
 };
 
 FORWARD _PROTOTYPE( void init_params, (void)                           );
@@ -141,23 +141,26 @@ FORWARD _PROTOTYPE( void init_drive, (struct wini *w, int base_cmd,
        int base_ctl, int base_dma, int irq, int ack, int hook,
                                                        int drive)      );
 FORWARD _PROTOTYPE( void init_params_pci, (int)                        );
-FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr)         );
-FORWARD _PROTOTYPE( struct device *w_prepare, (int dev)                );
+FORWARD _PROTOTYPE( int w_do_open, (dev_t minor, int access)           );
+FORWARD _PROTOTYPE( struct device *w_prepare, (dev_t dev)              );
+FORWARD _PROTOTYPE( struct device *w_part, (dev_t minor)                       );
 FORWARD _PROTOTYPE( int w_identify, (void)                             );
 FORWARD _PROTOTYPE( char *w_name, (void)                               );
 FORWARD _PROTOTYPE( int w_specify, (void)                              );
 FORWARD _PROTOTYPE( int w_io_test, (void)                              );
-FORWARD _PROTOTYPE( int w_transfer, (endpoint_t proc_nr, int opcode,
-              u64_t position, iovec_t *iov, unsigned nr_req)            );
+FORWARD _PROTOTYPE( ssize_t w_transfer, (dev_t minor, int do_write,
+       u64_t position, endpoint_t proc_nr, iovec_t *iov,
+       unsigned int nr_req, int flags)                                 );
 FORWARD _PROTOTYPE( int com_out, (struct command *cmd)                         );
 FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd)             );
 FORWARD _PROTOTYPE( int setup_dma, (unsigned *sizep, endpoint_t proc_nr,
                        iovec_t *iov, size_t addr_offset, int do_write) );
 FORWARD _PROTOTYPE( void w_need_reset, (void)                          );
 FORWARD _PROTOTYPE( void ack_irqs, (unsigned int)                      );
-FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr)        );
-FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr)   );
-FORWARD _PROTOTYPE( void w_hw_int, (struct driver *dp, message *m_ptr)         );
+FORWARD _PROTOTYPE( int w_do_close, (dev_t minor)                      );
+FORWARD _PROTOTYPE( int w_ioctl, (dev_t minor, unsigned int request,
+       endpoint_t endpt, cp_grant_id_t grant)                          );
+FORWARD _PROTOTYPE( void w_hw_int, (unsigned int irqs)                 );
 FORWARD _PROTOTYPE( int com_simple, (struct command *cmd)              );
 FORWARD _PROTOTYPE( void w_timeout, (void)                             );
 FORWARD _PROTOTYPE( int w_reset, (void)                                );
@@ -165,28 +168,30 @@ FORWARD _PROTOTYPE( void w_intr_wait, (void)                              );
 FORWARD _PROTOTYPE( int at_intr_wait, (void)                           );
 FORWARD _PROTOTYPE( int w_waitfor, (int mask, int value)               );
 FORWARD _PROTOTYPE( int w_waitfor_dma, (int mask, int value)           );
-FORWARD _PROTOTYPE( void w_geometry, (struct partition *entry)                 );
+FORWARD _PROTOTYPE( void w_geometry, (dev_t minor,
+                                       struct partition *entry)                );
 #if ENABLE_ATAPI
-FORWARD _PROTOTYPE( int atapi_sendpacket, (u8_t *packet, unsigned cnt, int do_dma)     );
+FORWARD _PROTOTYPE( int atapi_sendpacket, (u8_t *packet, unsigned cnt,
+                                                       int do_dma)     );
 FORWARD _PROTOTYPE( int atapi_intr_wait, (int dma, size_t max)         );
 FORWARD _PROTOTYPE( int atapi_open, (void)                             );
 FORWARD _PROTOTYPE( void atapi_close, (void)                           );
-FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode,
-               u64_t position, iovec_t *iov, unsigned nr_req)          );
+FORWARD _PROTOTYPE( int atapi_transfer, (int do_write, u64_t position,
+       endpoint_t endpt, iovec_t *iov, unsigned int nr_req)            );
 #endif
 
-#define sys_voutb(out, n) at_voutb(__LINE__, (out), (n))
-FORWARD _PROTOTYPE( int at_voutb, (int line, pvb_pair_t *, int n));
-#define sys_vinb(in, n) at_vinb(__LINE__, (in), (n))
-FORWARD _PROTOTYPE( int at_vinb, (int line, pvb_pair_t *, int n));
+#define sys_voutb(out, n) at_voutb((out), (n))
+FORWARD _PROTOTYPE( int at_voutb, (pvb_pair_t *, int n));
+#define sys_vinb(in, n) at_vinb((in), (n))
+FORWARD _PROTOTYPE( int at_vinb, (pvb_pair_t *, int n));
 
 #undef sys_outb
 #undef sys_inb
 #undef sys_outl
 
-FORWARD _PROTOTYPE( int at_out, (int line, u32_t port, u32_t value,
+FORWARD _PROTOTYPE( int at_out, (int line, u32_t port, unsigned long value,
        char *typename, int type));
-FORWARD _PROTOTYPE( int at_in, (int line, u32_t port, u32_t *value,
+FORWARD _PROTOTYPE( int at_in, (int line, u32_t port, unsigned long *value,
        char *typename, int type));
 
 #define sys_outb(p, v) at_out(__LINE__, (p), (v), "outb", _DIO_BYTE)
@@ -194,20 +199,18 @@ FORWARD _PROTOTYPE( int at_in, (int line, u32_t port, u32_t *value,
 #define sys_outl(p, v) at_out(__LINE__, (p), (v), "outl", _DIO_LONG)
 
 /* Entry points to this driver. */
-PRIVATE struct driver w_dtab = {
-  w_name,              /* current device's name */
+PRIVATE struct blockdriver w_dtab = {
   w_do_open,           /* open or mount request, initialize device */
   w_do_close,          /* release device */
-  do_diocntl,          /* get or set a partition's geometry */
-  w_prepare,           /* prepare for I/O on a given minor device */
   w_transfer,          /* do the I/O */
-  nop_cleanup,         /* nothing to clean up */
+  w_ioctl,             /* I/O control requests */
+  NULL,                        /* nothing to clean up */
+  w_part,              /* return partition information */
   w_geometry,          /* tell the geometry of the disk */
-  nop_alarm,           /* ignore leftover alarms */
-  nop_cancel,          /* ignore CANCELs */
-  nop_select,          /* ignore selects */
-  w_other,             /* catch-all for unrecognized commands and ioctls */
-  w_hw_int             /* leftover hardware interrupts */
+  w_hw_int,            /* leftover hardware interrupts */
+  NULL,                        /* ignore leftover alarms */
+  NULL,                        /* ignore unrecognized messages */
+  NULL                 /* no multithreading support */
 };
 
 /* SEF functions and variables. */
@@ -227,7 +230,7 @@ PUBLIC int main(int argc, char *argv[])
   sef_local_startup();
 
   /* Call the generic receive loop. */
-  driver_task(&w_dtab, DRIVER_STD);
+  blockdriver_task(&w_dtab);
 
   return(OK);
 }
@@ -235,7 +238,7 @@ PUBLIC int main(int argc, char *argv[])
 /*===========================================================================*
  *                            sef_local_startup                             *
  *===========================================================================*/
-PRIVATE void sef_local_startup()
+PRIVATE void sef_local_startup(void)
 {
   /* Register init callbacks. */
   sef_setcb_init_fresh(sef_cb_init_fresh);
@@ -269,7 +272,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
   init_params();
 
   /* Announce we are up! */
-  driver_announce();
+  blockdriver_announce();
 
   return(OK);
 }
@@ -277,7 +280,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 /*===========================================================================*
  *                             init_params                                  *
  *===========================================================================*/
-PRIVATE void init_params()
+PRIVATE void init_params(void)
 {
 /* This routine is called at startup to initialize the drive parameters. */
 
@@ -304,20 +307,20 @@ PRIVATE void init_params()
        panic("atapi_debug");
 
   if(w_identify_wakeup_ticks <= 0) {
-       printf("changing wakeup from %d to %d ticks.\n",
+       printf("changing wakeup from %ld to %d ticks.\n",
                w_identify_wakeup_ticks, WAKEUP_TICKS);
        w_identify_wakeup_ticks = WAKEUP_TICKS;
   }
 
   if (disable_dma) {
-       printf("at_wini%d: DMA for ATA devices is disabled.\n", w_instance);
+       printf("at_wini%ld: DMA for ATA devices is disabled.\n", w_instance);
   } else {
        /* Ask for anonymous memory for DMA, that is physically contiguous. */
        dma_buf = alloc_contig(ATA_DMA_BUF_SIZE, 0, &dma_buf_phys);
        prdt = alloc_contig(PRDT_BYTES, 0, &prdt_phys);
        if(!dma_buf || !prdt) {
                disable_dma = 1;
-               printf("at_wini%d: no dma\n", w_instance);
+               printf("at_wini%ld: no dma\n", w_instance);
        }
   }
 
@@ -386,7 +389,7 @@ PRIVATE void init_drive(struct wini *w, int base_cmd, int base_ctl,
        w->base_ctl = base_ctl;
        w->base_dma = base_dma;
        if(w_pci_debug)
-          printf("at_wini%d: drive %d: base_cmd 0x%x, base_ctl 0x%x, base_dma 0x%x\n",
+          printf("at_wini%ld: drive %d: base_cmd 0x%x, base_ctl 0x%x, base_dma 0x%x\n",
                w_instance, w-wini, w->base_cmd, w->base_ctl, w->base_dma);
        w->irq = irq;
        w->irq_need_ack = ack;
@@ -471,7 +474,7 @@ PRIVATE void init_params_pci(int skip)
                        continue;
                }
                if(pci_reserve_ok(devind) != OK) {
-                       printf("at_wini%d: pci_reserve %d failed - "
+                       printf("at_wini%ld: pci_reserve %d failed - "
                                "ignoring controller!\n",
                                w_instance, devind);
                        continue;
@@ -502,9 +505,10 @@ PRIVATE void init_params_pci(int skip)
                                base_cmd, base_ctl+PCI_CTL_OFF,
                                base_dma, irq, 1, irq_hook, 1);
                        if (w_pci_debug)
-                               printf("at_wini%d: atapci %d: 0x%x 0x%x irq %d\n", w_instance, devind, base_cmd, base_ctl, irq);
+                               printf("at_wini%ld: atapci %d: 0x%x 0x%x irq %d\n",
+                                       w_instance, devind, base_cmd, base_ctl, irq);
                        w_next_drive += 2;
-               } else printf("at_wini%d: atapci: ignored drives on primary channel, base %x\n", w_instance, base_cmd);
+               } else printf("at_wini%ld: atapci: ignored drives on primary channel, base %x\n", w_instance, base_cmd);
        }
        else
        {
@@ -514,7 +518,7 @@ PRIVATE void init_params_pci(int skip)
                        if (wini[i].base_cmd == REG_CMD_BASE0) {
                                wini[i].base_dma= base_dma;
                                if(w_pci_debug)
-                                 printf("at_wini%d: drive %d: base_dma 0x%x\n",
+                                       printf("at_wini%ld: drive %d: base_dma 0x%x\n",
                                        w_instance, i, wini[i].base_dma);
                                pci_compat = 1;
                        }
@@ -537,10 +541,10 @@ PRIVATE void init_params_pci(int skip)
                                base_cmd, base_ctl+PCI_CTL_OFF, base_dma,
                                irq, 1, irq_hook, 3);
                        if (w_pci_debug)
-                         printf("at_wini%d: atapci %d: 0x%x 0x%x irq %d\n",
+                         printf("at_wini%ld: atapci %d: 0x%x 0x%x irq %d\n",
                                w_instance, devind, base_cmd, base_ctl, irq);
                        w_next_drive += 2;
-               } else printf("at_wini%d: atapci: ignored drives on "
+               } else printf("at_wini%ld: atapci: ignored drives on "
                        "secondary channel, base %x\n", w_instance, base_cmd);
        }
        else
@@ -551,7 +555,7 @@ PRIVATE void init_params_pci(int skip)
                        if (wini[i].base_cmd == REG_CMD_BASE1 && base_dma != 0) {
                                wini[i].base_dma= base_dma+PCI_DMA_2ND_OFF;
                                if (w_pci_debug)
-                                 printf("at_wini%d: drive %d: base_dma 0x%x\n",
+                                       printf("at_wini%ld: drive %d: base_dma 0x%x\n",
                                        w_instance, i, wini[i].base_dma);
                                pci_compat = 1;
                        }
@@ -560,7 +564,7 @@ PRIVATE void init_params_pci(int skip)
 
        if(pci_compat) {
                if(pci_reserve_ok(devind) != OK) {
-                       printf("at_wini%d (compat): pci_reserve %d failed!\n",
+                       printf("at_wini%ld (compat): pci_reserve %d failed!\n",
                                w_instance, devind);
                }
        }
@@ -570,13 +574,13 @@ PRIVATE void init_params_pci(int skip)
 /*===========================================================================*
  *                             w_do_open                                    *
  *===========================================================================*/
-PRIVATE int w_do_open(struct driver *dp, message *m_ptr)
+PRIVATE int w_do_open(dev_t minor, int access)
 {
 /* Device open: Initialize the controller and read the partition table. */
 
   struct wini *wn;
 
-  if (w_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
+  if (w_prepare(minor) == NULL) return(ENXIO);
 
   wn = w_wn;
 
@@ -613,7 +617,7 @@ PRIVATE int w_do_open(struct driver *dp, message *m_ptr)
   }
 
 #if ENABLE_ATAPI
-   if ((wn->state & ATAPI) && (m_ptr->COUNT & W_BIT))
+   if ((wn->state & ATAPI) && (access & W_BIT))
        return(EACCES);
 #endif
 
@@ -629,7 +633,8 @@ PRIVATE int w_do_open(struct driver *dp, message *m_ptr)
 #endif
 
        /* Partition the disk. */
-       partition(&w_dtab, w_drive * DEV_PER_DRIVE, P_PRIMARY, wn->state & ATAPI);
+       partition(&w_dtab, w_drive * DEV_PER_DRIVE, P_PRIMARY,
+               wn->state & ATAPI);
   }
   wn->open_ct++;
   return(OK);
@@ -638,10 +643,10 @@ PRIVATE int w_do_open(struct driver *dp, message *m_ptr)
 /*===========================================================================*
  *                             w_prepare                                    *
  *===========================================================================*/
-PRIVATE struct device *w_prepare(int device)
+PRIVATE struct device *w_prepare(dev_t device)
 {
   /* Prepare for I/O on a device. */
-  w_device = device;
+  w_device = (int) device;
 
   if (device < NR_MINORS) {                    /* d0, d0p[0-3], d1, ... */
        w_drive = device / DEV_PER_DRIVE;       /* save drive number */
@@ -659,6 +664,16 @@ PRIVATE struct device *w_prepare(int device)
   return(w_dv);
 }
 
+/*===========================================================================*
+ *                             w_part                                       *
+ *===========================================================================*/
+PRIVATE struct device *w_part(dev_t device)
+{
+/* Return a pointer to the partition information of the given minor device. */
+
+  return w_prepare(device);
+}
+
 #define id_byte(n)     (&tmp_buf[2 * (n)])
 #define id_word(n)     (((u16_t) id_byte(n)[0] <<  0) \
                        |((u16_t) id_byte(n)[1] <<  8))
@@ -754,7 +769,7 @@ check_dma(struct wini *wn)
 /*===========================================================================*
  *                             w_identify                                   *
  *===========================================================================*/
-PRIVATE int w_identify()
+PRIVATE int w_identify(void)
 {
 /* Find out if a device exists, if it is an old AT disk, or a newer ATA
  * drive, a removable media device, etc.
@@ -906,7 +921,7 @@ PRIVATE int w_identify()
 /*===========================================================================*
  *                             w_name                                       *
  *===========================================================================*/
-PRIVATE char *w_name()
+PRIVATE char *w_name(void)
 {
 /* Return a name for the current device. */
   static char name[] = "AT0-D0";
@@ -921,10 +936,11 @@ PRIVATE char *w_name()
  *===========================================================================*/
 PRIVATE int w_io_test(void)
 {
-       int r, save_dev;
+       int save_dev;
        int save_timeout, save_errors, save_wakeup;
        iovec_t iov;
        static char *buf;
+       ssize_t r;
 
 #ifdef CD_SECTOR_SIZE
 #define BUFSIZE CD_SECTOR_SIZE
@@ -951,10 +967,8 @@ PRIVATE int w_io_test(void)
        w_testing = 1;
 
        /* Try I/O on the actual drive (not any (sub)partition). */
-       if (w_prepare(w_drive * DEV_PER_DRIVE) == NULL)
-               panic("Couldn't switch devices");
-
-       r = w_transfer(SELF, DEV_GATHER_S, cvu64(0), &iov, 1);
+       r = w_transfer(w_drive * DEV_PER_DRIVE, FALSE /*do_write*/, cvu64(0),
+               SELF, &iov, 1, BDEV_NOFLAGS);
 
        /* Switch back. */
        if (w_prepare(save_dev) == NULL)
@@ -967,19 +981,18 @@ PRIVATE int w_io_test(void)
        w_testing = 0;
 
        /* Test if everything worked. */
-       if (r != OK || iov.iov_size != 0) {
+       if (r != BUFSIZE) {
                return ERR;
        }
 
        /* Everything worked. */
-
        return OK;
 }
 
 /*===========================================================================*
  *                             w_specify                                    *
  *===========================================================================*/
-PRIVATE int w_specify()
+PRIVATE int w_specify(void)
 {
 /* Routine to initialize the drive after boot or when a reset is needed. */
 
@@ -1020,7 +1033,7 @@ PRIVATE int w_specify()
  *===========================================================================*/
 PRIVATE int do_transfer(const struct wini *wn, unsigned int precomp,
        unsigned int count, unsigned int sector,
-       unsigned int opcode, int do_dma)
+       unsigned int do_write, int do_dma)
 {
        struct command cmd;
        unsigned int sector_high;
@@ -1045,21 +1058,20 @@ PRIVATE int do_transfer(const struct wini *wn, unsigned int precomp,
        cmd.count   = count;
        if (do_dma)
        {
-               cmd.command = opcode == DEV_SCATTER_S ? CMD_WRITE_DMA :
-                       CMD_READ_DMA;
+               cmd.command = do_write ? CMD_WRITE_DMA : CMD_READ_DMA;
        }
        else
-               cmd.command = opcode == DEV_SCATTER_S ? CMD_WRITE : CMD_READ;
+               cmd.command = do_write ? CMD_WRITE : CMD_READ;
 
        if (do_lba48) {
                if (do_dma)
                {
-                       cmd.command = ((opcode == DEV_SCATTER_S) ?
+                       cmd.command = (do_write ?
                                CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT);
                }
                else
                {
-                       cmd.command = ((opcode == DEV_SCATTER_S) ?
+                       cmd.command = (do_write ?
                                CMD_WRITE_EXT : CMD_READ_EXT);
                }
                cmd.count_prev= (count >> 8);
@@ -1119,12 +1131,12 @@ PRIVATE void start_dma(const struct wini *wn, int do_write)
 PRIVATE int error_dma(const struct wini *wn)
 {
        int r;
-       u32_t v;
+       unsigned long v;
 
 #define DMAERR(msg) \
-       printf("at_wini%d: bad DMA: %s. Disabling DMA for drive %d.\n", \
+       printf("at_wini%ld: bad DMA: %s. Disabling DMA for drive %d.\n",        \
                w_instance, msg, wn - wini);                            \
-       printf("at_wini%d: workaround: set %s=1 in boot monitor.\n", \
+       printf("at_wini%ld: workaround: set %s=1 in boot monitor.\n", \
                w_instance, NO_DMA_VAR); \
        return 1;       \
 
@@ -1151,25 +1163,34 @@ PRIVATE int error_dma(const struct wini *wn)
 /*===========================================================================*
  *                             w_transfer                                   *
  *===========================================================================*/
-PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req)
-endpoint_t proc_nr;            /* process doing the request */
-int opcode;                    /* DEV_GATHER_S or DEV_SCATTER_S */
-u64_t position;                        /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE ssize_t w_transfer(
+  dev_t minor,                 /* minor device to perform the transfer on */
+  int do_write,                        /* read or write? */
+  u64_t position,              /* offset on device to read or write */
+  endpoint_t proc_nr,          /* process doing the request */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  int UNUSED(flags)            /* transfer flags */
+)
 {
-  struct wini *wn = w_wn;
+  struct wini *wn;
   iovec_t *iop, *iov_end = iov + nr_req;
-  int n, r, s, errors, do_dma, do_write;
+  int n, r, s, errors, do_dma;
   unsigned long block, w_status;
-  u64_t dv_size = w_dv->dv_size;
+  u64_t dv_size;
   unsigned nbytes;
   unsigned dma_buf_offset;
+  ssize_t total = 0;
   size_t addr_offset = 0;
 
+  if (w_prepare(minor) == NULL) return(ENXIO);
+
+  wn = w_wn;
+  dv_size = w_dv->dv_size;
+
 #if ENABLE_ATAPI
   if (w_wn->state & ATAPI) {
-       return atapi_transfer(proc_nr, opcode, position, iov, nr_req);
+       return atapi_transfer(do_write, position, proc_nr, iov, nr_req);
   }
 #endif
 
@@ -1185,12 +1206,11 @@ unsigned nr_req;                /* length of request vector */
        if ((nbytes & SECTOR_MASK) != 0) return(EINVAL);
 
        /* Which block on disk and how close to EOF? */
-       if (cmp64(position, dv_size) >= 0) return(OK);          /* At EOF */
+       if (cmp64(position, dv_size) >= 0) return(total);       /* At EOF */
        if (cmp64(add64ul(position, nbytes), dv_size) > 0)
                nbytes = diff64(dv_size, position);
        block = div64u(add64(w_dv->dv_base, position), SECTOR_SIZE);
 
-       do_write= (opcode == DEV_SCATTER_S);
        do_dma= wn->dma;
        
        if (nbytes >= wn->max_count) {
@@ -1213,12 +1233,12 @@ unsigned nr_req;                /* length of request vector */
 
        /* Tell the controller to transfer nbytes bytes. */
        r = do_transfer(wn, wn->precomp, (nbytes >> SECTOR_SHIFT),
-               block, opcode, do_dma);
+               block, do_write, do_dma);
 
        if (do_dma)
                start_dma(wn, do_write);
 
-       if (opcode == DEV_SCATTER_S) {
+       if (do_write) {
                /* The specs call for a 400 ns wait after issuing the command.
                 * Reading the alternate status register is the suggested 
                 * way to implement this wait.
@@ -1268,6 +1288,7 @@ unsigned nr_req;          /* length of request vector */
                        /* Book the bytes successfully transferred. */
                        nbytes -= n;
                        position= add64ul(position, n);
+                       total += n;
                        addr_offset += n;
                        if ((iov->iov_size -= n) == 0) {
                                iov++; nr_req--; addr_offset = 0;
@@ -1282,7 +1303,7 @@ unsigned nr_req;          /* length of request vector */
                 * interrupt (write).
                 */
 
-               if (opcode == DEV_GATHER_S) {
+               if (!do_write) {
                        /* First an interrupt, then data. */
                        if ((r = at_intr_wait()) != OK) {
                                /* An error, send data to the bit bucket. */
@@ -1304,7 +1325,7 @@ unsigned nr_req;          /* length of request vector */
                if (!w_waitfor(STATUS_DRQ, STATUS_DRQ)) { r = ERR; break; }
 
                /* Copy bytes to or from the device's buffer. */
-               if (opcode == DEV_GATHER_S) {
+               if (!do_write) {
                   if(proc_nr != SELF) {
                        s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr, 
                                (void *) (iov->iov_addr), addr_offset,
@@ -1340,6 +1361,7 @@ unsigned nr_req;          /* length of request vector */
                nbytes -= SECTOR_SIZE;
                position= add64u(position, SECTOR_SIZE);
                addr_offset += SECTOR_SIZE;
+               total += SECTOR_SIZE;
                if ((iov->iov_size -= SECTOR_SIZE) == 0) {
                        iov++;
                        nr_req--;
@@ -1358,7 +1380,7 @@ unsigned nr_req;          /* length of request vector */
   }
 
   w_command = CMD_IDLE;
-  return(OK);
+  return(total);
 }
 
 /*===========================================================================*
@@ -1469,12 +1491,13 @@ struct command *cmd;            /* Command block */
 /*===========================================================================*
  *                             setup_dma                                    *
  *===========================================================================*/
-PRIVATE int setup_dma(sizep, proc_nr, iov, addr_offset, do_write)
-unsigned *sizep;
-endpoint_t proc_nr;
-iovec_t *iov;
-size_t addr_offset;
-int do_write;
+PRIVATE int setup_dma(
+  unsigned *sizep,
+  endpoint_t proc_nr,
+  iovec_t *iov,
+  size_t addr_offset,
+  int UNUSED(do_write)
+)
 {
        phys_bytes user_phys;
        unsigned n, offset, size;
@@ -1494,11 +1517,11 @@ int do_write;
 
        while (size > 0)
        {
-          if(verbose)  {
-               printf(
-               "at_wini: setup_dma: iov[%d]: addr 0x%x, size %d offset %d, size %d\n",
+               if(verbose)  {
+                       printf(
+       "at_wini: setup_dma: iov[%d]: addr 0x%lx, size %ld offset %d, size %d\n",
                        i, iov[i].iov_addr, iov[i].iov_size, offset, size);
-          }
+               }
                        
                n= iov[i].iov_size-offset;
                if (n > size)
@@ -1557,18 +1580,18 @@ int do_write;
                size -= n;
        }
 
-               if (j <= 0 || j > N_PRDTE)
-                       panic("bad prdt index: %d", j);
-               prdt[j-1].prdte_flags |= PRDTE_FL_EOT;
+       if (j <= 0 || j > N_PRDTE)
+               panic("bad prdt index: %d", j);
+       prdt[j-1].prdte_flags |= PRDTE_FL_EOT;
 
-          if(verbose) {
+       if(verbose) {
                printf("dma not bad\n");
                for (i= 0; i<j; i++) {
-                       printf("prdt[%d]: base 0x%x, size %d, flags 0x%x\n",
+                       printf("prdt[%d]: base 0x%lx, size %d, flags 0x%x\n",
                                i, prdt[i].prdte_base, prdt[i].prdte_count,
                                prdt[i].prdte_flags);
                }
-          }
+       }
 
        /* Verify that the bus master is not active */
        r= sys_inb(wn->base_dma + DMA_STATUS, &v);
@@ -1592,7 +1615,7 @@ int do_write;
 /*===========================================================================*
  *                             w_need_reset                                 *
  *===========================================================================*/
-PRIVATE void w_need_reset()
+PRIVATE void w_need_reset(void)
 {
 /* The controller needs to be reset. */
   struct wini *wn;
@@ -1608,10 +1631,10 @@ PRIVATE void w_need_reset()
 /*===========================================================================*
  *                             w_do_close                                   *
  *===========================================================================*/
-PRIVATE int w_do_close(struct driver *dp, message *m_ptr)
+PRIVATE int w_do_close(dev_t minor)
 {
 /* Device close: Release a device. */
-  if (w_prepare(m_ptr->DEVICE) == NULL)
+  if (w_prepare(minor) == NULL)
        return(ENXIO);
   w_wn->open_ct--;
 #if ENABLE_ATAPI
@@ -1672,7 +1695,7 @@ PRIVATE void w_timeout(void)
 /*===========================================================================*
  *                             w_reset                                      *
  *===========================================================================*/
-PRIVATE int w_reset()
+PRIVATE int w_reset(void)
 {
 /* Issue a reset to the controller.  This is done after any catastrophe,
  * like the controller refusing to respond.
@@ -1718,7 +1741,7 @@ PRIVATE int w_reset()
 /*===========================================================================*
  *                             w_intr_wait                                  *
  *===========================================================================*/
-PRIVATE void w_intr_wait()
+PRIVATE void w_intr_wait(void)
 {
 /* Wait for a task completion interrupt. */
 
@@ -1753,17 +1776,17 @@ PRIVATE void w_intr_wait()
                                default:
                                        /* 
                                         * unhandled message.  queue it and
-                                        * handle it in the libdriver loop.
+                                        * handle it in the blockdriver loop.
                                         */
-                                       driver_mq_queue(&m, ipc_status);
+                                       blockdriver_mq_queue(&m, ipc_status);
                        }
                }
                else {
                        /* 
                         * unhandled message.  queue it and handle it in the
-                        * libdriver loop.
+                        * blockdriver loop.
                         */
-                       driver_mq_queue(&m, ipc_status);
+                       blockdriver_mq_queue(&m, ipc_status);
                }
        }
   } else {
@@ -1775,7 +1798,7 @@ PRIVATE void w_intr_wait()
 /*===========================================================================*
  *                             at_intr_wait                                 *
  *===========================================================================*/
-PRIVATE int at_intr_wait()
+PRIVATE int at_intr_wait(void)
 {
 /* Wait for an interrupt, study the status bits and return error/success. */
   int r, s;
@@ -1850,10 +1873,13 @@ int value;                      /* required status */
 /*===========================================================================*
  *                             w_geometry                                   *
  *===========================================================================*/
-PRIVATE void w_geometry(entry)
-struct partition *entry;
+PRIVATE void w_geometry(dev_t minor, struct partition *entry)
 {
-  struct wini *wn = w_wn;
+  struct wini *wn;
+
+  if (w_prepare(minor) == NULL) return;
+
+  wn = w_wn;
 
   if (wn->state & ATAPI) {             /* Make up some numbers. */
        entry->cylinders = div64u(wn->part[0].dv_size, SECTOR_SIZE) / (64*32);
@@ -1870,7 +1896,7 @@ struct partition *entry;
 /*===========================================================================*
  *                             atapi_open                                   *
  *===========================================================================*/
-PRIVATE int atapi_open()
+PRIVATE int atapi_open(void)
 {
 /* Should load and lock the device and obtain its size.  For now just set the
  * size of the device to something big.  What is really needed is a generic
@@ -1883,7 +1909,7 @@ PRIVATE int atapi_open()
 /*===========================================================================*
  *                             atapi_close                                  *
  *===========================================================================*/
-PRIVATE void atapi_close()
+PRIVATE void atapi_close(void)
 {
 /* Should unlock the device.  For now do nothing.  (XXX) */
 }
@@ -1921,12 +1947,13 @@ PRIVATE void sense_request(void)
 /*===========================================================================*
  *                             atapi_transfer                               *
  *===========================================================================*/
-PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req)
-int proc_nr;                   /* process doing the request */
-int opcode;                    /* DEV_GATHER_S or DEV_SCATTER_S */
-u64_t position;                        /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE int atapi_transfer(
+  int do_write,                        /* read or write? */
+  u64_t position,              /* offset on device to read or write */
+  endpoint_t proc_nr,          /* process doing the request */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req          /* length of request vector */
+)
 {
   struct wini *wn = w_wn;
   iovec_t *iop, *iov_end = iov + nr_req;
@@ -1938,6 +1965,9 @@ unsigned nr_req;          /* length of request vector */
   static u8_t packet[ATAPI_PACKETSIZE];
   size_t addr_offset = 0;
   int dmabytes = 0, piobytes = 0;
+  ssize_t total = 0;
+
+  if (do_write) return(EINVAL);
 
   errors = fresh = 0;
 
@@ -1965,7 +1995,7 @@ unsigned nr_req;          /* length of request vector */
        if ((before | nbytes) & 1) return(EINVAL);
 
        /* Which block on disk and how close to EOF? */
-       if (cmp64(position, dv_size) >= 0) return(OK);          /* At EOF */
+       if (cmp64(position, dv_size) >= 0) return(total);       /* At EOF */
        if (cmp64(add64ul(position, nbytes), dv_size) > 0)
                nbytes = diff64(dv_size, position);
 
@@ -2023,6 +2053,7 @@ unsigned nr_req;          /* length of request vector */
                                        chunk = iov->iov_size;
                                position= add64ul(position, chunk);
                                nbytes -= chunk;
+                               total += chunk;
                                if ((iov->iov_size -= chunk) == 0) {
                                        iov++;
                                        nr_req--;
@@ -2069,6 +2100,7 @@ unsigned nr_req;          /* length of request vector */
                        addr_offset += chunk;
                        piobytes += chunk;
                        fresh = 0;
+                       total += chunk;
                        if ((iov->iov_size -= chunk) == 0) {
                                iov++;
                                nr_req--;
@@ -2107,7 +2139,7 @@ unsigned nr_req;          /* length of request vector */
 #endif
 
   w_command = CMD_IDLE;
-  return(OK);
+  return(total);
 }
 
 /*===========================================================================*
@@ -2174,21 +2206,18 @@ int do_dma;
 #endif /* ENABLE_ATAPI */
 
 /*===========================================================================*
- *                             w_other                                      *
+ *                             w_ioctl                                      *
  *===========================================================================*/
-PRIVATE int w_other(dr, m)
-struct driver *dr;
-message *m;
+PRIVATE int w_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
+       cp_grant_id_t grant)
 {
-       int r, timeout, prev;
+       int r, timeout, prev, count;
        struct command cmd;
 
-       if (m->m_type != DEV_IOCTL_S )
-               return EINVAL;
-
-       if (m->REQUEST == DIOCTIMEOUT) {
-               r= sys_safecopyfrom(m->m_source, (cp_grant_id_t) m->IO_GRANT,
-                       0, (vir_bytes)&timeout, sizeof(timeout), D);
+       switch (request) {
+       case DIOCTIMEOUT:
+               r= sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&timeout,
+                       sizeof(timeout), D);
 
                if(r != OK)
                    return r;
@@ -2218,28 +2247,28 @@ message *m;
                                        timeout_usecs = timeout;
                        }
        
-                       r= sys_safecopyto(m->m_source,
-                               (cp_grant_id_t) m->IO_GRANT,
-                               0, (vir_bytes)&prev, sizeof(prev), D);
+                       r= sys_safecopyto(endpt, grant, 0, (vir_bytes)&prev,
+                               sizeof(prev), D);
 
                        if(r != OK)
                                return r;
                }
        
                return OK;
-       } else  if (m->REQUEST == DIOCOPENCT) {
-               int count;
-               if (w_prepare(m->DEVICE) == NULL) return ENXIO;
+
+       case DIOCOPENCT:
+               if (w_prepare(minor) == NULL) return ENXIO;
                count = w_wn->open_ct;
-               r= sys_safecopyto(m->m_source, (cp_grant_id_t) m->IO_GRANT,
-                       0, (vir_bytes)&count, sizeof(count), D);
+               r= sys_safecopyto(endpt, grant, 0, (vir_bytes)&count,
+                       sizeof(count), D);
 
                if(r != OK)
                        return r;
 
                return OK;
-       } else if (m->REQUEST == DIOCFLUSH) {
-               if (w_prepare(m->DEVICE) == NULL) return ENXIO;
+
+       case DIOCFLUSH:
+               if (w_prepare(minor) == NULL) return ENXIO;
 
                if (w_wn->state & ATAPI) return EINVAL;
 
@@ -2253,18 +2282,17 @@ message *m;
 
                return (w_wn->w_status & (STATUS_ERR|STATUS_WF)) ? EIO : OK;
        }
+
        return EINVAL;
 }
 
 /*===========================================================================*
  *                             w_hw_int                                     *
  *===========================================================================*/
-PRIVATE void w_hw_int(dr, m)
-struct driver *dr;
-message *m;
+PRIVATE void w_hw_int(unsigned int irqs)
 {
   /* Leftover interrupt(s) received; ack it/them. */
-  ack_irqs(m->NOTIFY_ARG);
+  ack_irqs(irqs);
 }
 
 
@@ -2334,7 +2362,7 @@ PRIVATE char *strerr(int e)
 /*===========================================================================*
  *                             atapi_intr_wait                              *
  *===========================================================================*/
-PRIVATE int atapi_intr_wait(int do_dma, size_t max)
+PRIVATE int atapi_intr_wait(int UNUSED(do_dma), size_t UNUSED(max))
 {
 /* Wait for an interrupt and study the results.  Returns a number of bytes
  * that need to be transferred, or an error code.
@@ -2407,49 +2435,49 @@ PRIVATE int atapi_intr_wait(int do_dma, size_t max)
 #undef sys_voutb
 #undef sys_vinb
 
-PRIVATE int at_voutb(int line, pvb_pair_t *pvb, int n)
+PRIVATE int at_voutb(pvb_pair_t *pvb, int n)
 {
   int s, i;
   if ((s=sys_voutb(pvb,n)) == OK)
        return OK;
-  printf("at_wini%d: sys_voutb failed: %d pvb (%d):\n", w_instance, s, n);
+  printf("at_wini%ld: sys_voutb failed: %d pvb (%d):\n", w_instance, s, n);
   for(i = 0; i < n; i++)
        printf("%2d: %4x -> %4x\n", i, pvb[i].value, pvb[i].port);
   panic("sys_voutb failed");
 }
 
-PRIVATE int at_vinb(int line, pvb_pair_t *pvb, int n)
+PRIVATE int at_vinb(pvb_pair_t *pvb, int n)
 {
   int s, i;
   if ((s=sys_vinb(pvb,n)) == OK)
        return OK;
-  printf("at_wini%d: sys_vinb failed: %d pvb (%d):\n", w_instance, s, n);
+  printf("at_wini%ld: sys_vinb failed: %d pvb (%d):\n", w_instance, s, n);
   for(i = 0; i < n; i++)
        printf("%2d: %4x\n", i, pvb[i].port);
   panic("sys_vinb failed");
 }
 
-PRIVATE int at_out(int line, u32_t port, u32_t value,
+PRIVATE int at_out(int line, u32_t port, unsigned long value,
        char *typename, int type)
 {
        int s;
        s = sys_out(port, value, type);
        if(s == OK)
                return OK;
-       printf("at_wini%d: line %d: %s failed: %d; %x -> %x\n", 
+       printf("at_wini%ld: line %d: %s failed: %d; %lx -> %x\n",
                w_instance, line, typename, s, value, port);
         panic("sys_out failed");
 }
 
 
-PRIVATE int at_in(int line, u32_t port, u32_t *value,
+PRIVATE int at_in(int line, u32_t port, unsigned long *value,
        char *typename, int type)
 {
        int s;
        s = sys_in(port, value, type);
        if(s == OK)
                return OK;
-       printf("at_wini%d: line %d: %s failed: %d; port %x\n", 
+       printf("at_wini%ld: line %d: %s failed: %d; port %x\n",
                w_instance, line, typename, s, port);
         panic("sys_in failed");
 }
index a4c5489c8e3a446c57b55cfaac925d8dedb4c19a..4b848fce75c636ecdbd667dc23a87f16178df8ad 100644 (file)
@@ -1,5 +1,5 @@
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/blockdriver.h>
 #include <minix/drvlib.h>
 
 #define VERBOSE                   0    /* display identify messages during boot */
 
 #define NO_DMA_VAR     "ata_no_dma"
 
+/* BIOS parameter table layout. */
+#define bp_cylinders(t)        (t[0] | (t[1] << 8))
+#define bp_heads(t)    (t[2])
+#define bp_precomp(t)  (t[5] | (t[6] << 8))
+#define bp_sectors(t)  (t[14])
index 85ebc1bb653becd8ac5b70ba89355ab41631fbce..704d229a38d00b070a67d1f087ae6f758c9ac8bb 100644 (file)
@@ -1,7 +1,7 @@
 .include <bsd.own.mk>
 
-DPADD+= ${LIBAUDIODRIVER} ${LIBDRIVER} ${LIBSYS}
-LDADD+= -laudiodriver -ldriver -lsys
+DPADD+= ${LIBAUDIODRIVER} ${LIBCHARDRIVER} ${LIBSYS}
+LDADD+= -laudiodriver -lchardriver -lsys
 
 .if exists(${.CURDIR}/../../Makefile.inc)
 .include "${.CURDIR}/../../Makefile.inc"
index 46136bcdd836cf079f3e9e91ab656ea239c824ac..d206c2de9d0ceb881b44b13572aa7fbfdb45d6aa 100644 (file)
@@ -4,8 +4,6 @@ SRCS=   es1370.c ak4531.c pci_helper.c
 
 MAN=
 
-LIBS += -ldriver
-
 BINDIR?= /usr/sbin
 
 .include <bsd.prog.mk>
index 027bc83f95d6d84a1f770277663313f26ed874a4..30d2e9507050af2ce9f8b2db3fa4c754a3979b1b 100644 (file)
@@ -70,7 +70,7 @@ PRIVATE int ak4531_write (u8_t address, u8_t data) {
        u16_t to_be_written;
 
 
-       if (address < MASTER_VOLUME_LCH || address > MIC_AMP_GAIN) return -1;
+       if (address > MIC_AMP_GAIN) return -1;
 
        to_be_written = (u16_t)((address << 8) | data);
 
index 8dc6a5f35e4b63f0982ff7eb27ecaa1ba0d091aa..471f92bce5f92dd91d2d7289c28e00f3c1a782ac 100644 (file)
@@ -225,7 +225,7 @@ int drv_reset() {
 }
 
 
-int drv_start(int sub_dev, int DmaMode) {
+int drv_start(int sub_dev, int UNUSED(DmaMode)) {
        u32_t enable_bit, result = 0;
 
        /* Write default values to device in case user failed to configure.
@@ -503,7 +503,7 @@ PRIVATE int set_stereo(u32_t stereo, int sub_dev) {
 }
 
 
-PRIVATE int set_sign(u32_t val, int sub_dev) {
+PRIVATE int set_sign(u32_t UNUSED(val), int UNUSED(sub_dev)) {
        return OK;
 }
 
index 6cea93c1e363e8bca3f94aa418db934af15acf57..ca45e9dada3556e0e841b38bb9e03efac2154af3 100644 (file)
@@ -15,7 +15,7 @@
  *                     helper functions for I/O                                                                                 *
  *===========================================================================*/
 PUBLIC unsigned pci_inb(u16_t port) {
-       u32_t value;
+       unsigned long value;
        int s;
        if ((s=sys_inb(port, &value)) !=OK)
                printf("%s: warning, sys_inb failed: %d\n", DRIVER_NAME, s);
@@ -24,7 +24,7 @@ PUBLIC unsigned pci_inb(u16_t port) {
 
 
 PUBLIC unsigned pci_inw(u16_t port) {
-       u32_t value;
+       unsigned long value;
        int s;
        if ((s=sys_inw(port, &value)) !=OK)
                printf("%s: warning, sys_inw failed: %d\n", DRIVER_NAME, s);
@@ -33,7 +33,7 @@ PUBLIC unsigned pci_inw(u16_t port) {
 
 
 PUBLIC unsigned pci_inl(u16_t port) {
-       u32_t value;
+       unsigned long value;
        int s;
        if ((s=sys_inl(port, &value)) !=OK)
                printf("%s: warning, sys_inl failed: %d\n", DRIVER_NAME, s);
index deaad91619a3d10b0db8445c125e7184955372ea..c63d5348aa441399ce14da2463d18ccb2130ab5c 100644 (file)
@@ -227,7 +227,7 @@ int drv_reset() {
 }
 
 
-int drv_start(int sub_dev, int DmaMode) {
+int drv_start(int sub_dev, int UNUSED(DmaMode)) {
        u32_t enable_bit, result = 0;
 
        /* Write default values to device in case user failed to configure.
@@ -504,7 +504,7 @@ PRIVATE int set_stereo(u32_t stereo, int sub_dev) {
 }
 
 
-PRIVATE int set_sign(u32_t val, int sub_dev) {
+PRIVATE int set_sign(u32_t UNUSED(val), int UNUSED(sub_dev)) {
        return OK;
 }
 
index ce9947171e0ffd9c5afe84593e5f7d2347ca46cd..df35bafe4c9a25ea5ce459200161039dd6e004ba 100644 (file)
@@ -15,7 +15,7 @@
  *                     helper functions for I/O                                                                                 *
  *===========================================================================*/
 PUBLIC unsigned pci_inb(u16_t port) {
-       u32_t value;
+       unsigned long value;
        int s;
        if ((s=sys_inb(port, &value)) !=OK)
                printf("%s: warning, sys_inb failed: %d\n", DRIVER_NAME, s);
@@ -24,7 +24,7 @@ PUBLIC unsigned pci_inb(u16_t port) {
 
 
 PUBLIC unsigned pci_inw(u16_t port) {
-       u32_t value;
+       unsigned long value;
        int s;
        if ((s=sys_inw(port, &value)) !=OK)
                printf("%s: warning, sys_inw failed: %d\n", DRIVER_NAME, s);
@@ -33,7 +33,7 @@ PUBLIC unsigned pci_inw(u16_t port) {
 
 
 PUBLIC unsigned pci_inl(u16_t port) {
-       u32_t value;
+       unsigned long value;
        int s;
        if ((s=sys_inl(port, &value)) !=OK)
                printf("%s: warning, sys_inl failed: %d\n", DRIVER_NAME, s);
index 916d67685881a17c5b3a91ca8b817514795c1232..dcf378eebba435835d86006d527f31f658a317ae 100644 (file)
@@ -170,7 +170,7 @@ void src_set_rate(const DEV_STRUCT * DSP, char base, u16_t rate) {
 
                src_reg_write(DSP, base + SRC_INT_REGS_OFF,
                                (wtemp & 0x00ffU) |
-                               (u16_t) (freq >> 6) & 0xfc00);
+                               ((u16_t) (freq >> 6) & 0xfc00));
 
                src_reg_write(DSP, base + SRC_VFREQ_FRAC_OFF, (u16_t) freq >> 1);
 
@@ -226,7 +226,7 @@ void src_set_rate(const DEV_STRUCT * DSP, char base, u16_t rate) {
                src_reg_read(DSP, base + SRC_INT_REGS_OFF, &wtemp);
                src_reg_write(DSP, base + SRC_INT_REGS_OFF,
                                (wtemp & 0x00ffU) |
-                               (u16_t) (freq >> 6) & 0xfc00);
+                               ((u16_t) (freq >> 6) & 0xfc00));
                src_reg_write(DSP, base + SRC_VFREQ_FRAC_OFF, (u16_t) freq >> 1);
 
                /* un-freeze the channel */
index e46acc8c008075048519486390a61c5c0ba9fa4f..efc507672b902e7a9092f6ef0f68f23405c73fbc 100644 (file)
@@ -13,7 +13,7 @@ FORWARD _PROTOTYPE( int get_set_output, (struct inout_ctrl *output, int flag));
 /*=========================================================================*
  *                             mixer_ioctl                                     
  *=========================================================================*/
-PUBLIC int mixer_ioctl(int request, void *val, int *len) {
+PUBLIC int mixer_ioctl(int request, void *val, int *UNUSED(len)) {
        int status;
 
        switch(request) {
index 5b1ee1cdff0e731efcb202ceff47e920aa201bb6..79110dcb0c7d8f15ba8642c26f187cbdc31cd616 100644 (file)
@@ -190,7 +190,7 @@ PUBLIC int drv_stop(int sub_dev) {
 
 
 
-PUBLIC int drv_set_dma(u32_t dma, u32_t length, int chan) {
+PUBLIC int drv_set_dma(u32_t dma, u32_t UNUSED(length), int UNUSED(chan)) {
        Dprint(("drv_set_dma():\n"));
        DmaPhys = dma;
        return OK;
@@ -198,7 +198,7 @@ PUBLIC int drv_set_dma(u32_t dma, u32_t length, int chan) {
 
 
 
-PUBLIC int drv_reenable_int(int chan) {
+PUBLIC int drv_reenable_int(int UNUSED(chan)) {
        Dprint(("drv_reenable_int()\n"));
        sb16_inb((DspBits == 8 ? DSP_DATA_AVL : DSP_DATA16_AVL));
        return OK;
@@ -225,7 +225,7 @@ PUBLIC int drv_pause(int chan) {
 
 
 
-PUBLIC int drv_resume(int chan) {
+PUBLIC int drv_resume(int UNUSED(chan)) {
        dsp_command((DspBits == 8 ? DSP_CMD_DMA8CONT : DSP_CMD_DMA16CONT));
        return OK;
 }
@@ -254,7 +254,7 @@ PUBLIC int drv_get_irq(char *irq) {
 
 
 
-PUBLIC int drv_get_frag_size(u32_t *frag_size, int sub_dev) {
+PUBLIC int drv_get_frag_size(u32_t *frag_size, int UNUSED(sub_dev)) {
        Dprint(("drv_get_frag_size():\n"));
        *frag_size = DspFragmentSize;
        return OK;
index cb0f177ffa4b066465bb4b8b4a0d8e3d1cecceda..a0c5842baa8b7ee5d03942c2e95627f70b999d89 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  bios_wini
 SRCS=  bios_wini.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
-LDADD+=        -ldriver -lsys -ltimers
+DPADD+=        ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+=        -lblockdriver -lsys -ltimers
 
 MAN=
 
index ca4249e27e2f89006c625e60e1c1d0bdc168744c..a9375e0a83b0cfc2ed64d66e439745ddd781a004 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/blockdriver.h>
 #include <minix/drvlib.h>
 #include <minix/sysutil.h>
 #include <minix/safecopies.h>
@@ -29,8 +29,6 @@
 #include <machine/int86.h>
 #include <assert.h>
 
-#define ME "BIOS_WINI"
-
 /* Parameters for the disk drive. */
 #define MAX_DRIVES         8   /* this driver supports 8 drives (d0 - d7)*/
 #define NR_MINORS      (MAX_DRIVES * DEV_PER_DRIVE)
@@ -58,31 +56,31 @@ PRIVATE int remap_first = 0;                /* Remap drives for CD HD emulation */
 #define BIOSBUF 16384
 
 _PROTOTYPE(int main, (void) );
-FORWARD _PROTOTYPE( struct device *w_prepare, (int device) );
-FORWARD _PROTOTYPE( char *w_name, (void) );
-FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position,
-                               iovec_t *iov, unsigned nr_req) );
-FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
+FORWARD _PROTOTYPE( struct device *w_prepare, (dev_t device) );
+FORWARD _PROTOTYPE( struct device *w_part, (dev_t minor) );
+FORWARD _PROTOTYPE( ssize_t w_transfer, (dev_t minor, int do_write,
+       u64_t position, endpoint_t endpt, iovec_t *iov, unsigned int nr_req,
+       int flags) );
+FORWARD _PROTOTYPE( int w_do_open, (dev_t minor, int access) );
+FORWARD _PROTOTYPE( int w_do_close, (dev_t minor) );
 FORWARD _PROTOTYPE( void w_init, (void) );
-FORWARD _PROTOTYPE( void w_geometry, (struct partition *entry));
-FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr) );
+FORWARD _PROTOTYPE( void w_geometry, (dev_t minor, struct partition *entry));
+FORWARD _PROTOTYPE( int w_ioctl, (dev_t minor, unsigned int request,
+       endpoint_t endpt, cp_grant_id_t grant) );
 
 /* Entry points to this driver. */
-PRIVATE struct driver w_dtab = {
-  w_name,      /* current device's name */
+PRIVATE struct blockdriver w_dtab = {
   w_do_open,   /* open or mount request, initialize device */
   w_do_close,  /* release device */
-  do_diocntl,  /* get or set a partition's geometry */
-  w_prepare,   /* prepare for I/O on a given minor device */
   w_transfer,  /* do the I/O */
-  nop_cleanup, /* no cleanup needed */
+  w_ioctl,     /* I/O control */
+  NULL,                /* no cleanup needed */
+  w_part,      /* return partition information structure */
   w_geometry,  /* tell the geometry of the disk */
-  nop_alarm,           /* ignore leftover alarms */
-  nop_cancel,          /* ignore CANCELs */
-  nop_select,          /* ignore selects */
-  w_other,             /* catch-all for unrecognized commands and ioctls */
-  NULL                 /* leftover hardware interrupts */
+  NULL,                /* leftover hardware interrupts */
+  NULL,                /* ignore leftover alarms */
+  NULL,                /* catch-all for unrecognized commands */
+  NULL         /* no threading support */
 };
 
 /* SEF functions and variables. */
@@ -92,13 +90,13 @@ FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
 /*===========================================================================*
  *                             bios_winchester_task                         *
  *===========================================================================*/
-PUBLIC int main()
+PUBLIC int main(void)
 {
   /* SEF local startup. */
   sef_local_startup();
 
   /* Call the generic receive loop. */
-  driver_task(&w_dtab, DRIVER_STD);
+  blockdriver_task(&w_dtab);
 
   return(OK);
 }
@@ -106,7 +104,7 @@ PUBLIC int main()
 /*===========================================================================*
  *                            sef_local_startup                             *
  *===========================================================================*/
-PRIVATE void sef_local_startup()
+PRIVATE void sef_local_startup(void)
 {
   /* Register init callbacks. */
   sef_setcb_init_fresh(sef_cb_init_fresh);
@@ -124,7 +122,7 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the bios_wini driver. */
   long v;
@@ -134,7 +132,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
   remap_first = v;
 
   /* Announce we are up! */
-  driver_announce();
+  blockdriver_announce();
 
   return(OK);
 }
@@ -142,8 +140,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
 /*===========================================================================*
  *                             w_prepare                                    *
  *===========================================================================*/
-PRIVATE struct device *w_prepare(device)
-int device;
+PRIVATE struct device *w_prepare(dev_t device)
 {
 /* Prepare for I/O on a device. */
 
@@ -165,35 +162,36 @@ int device;
 }
 
 /*===========================================================================*
- *                             w_name                                       *
+ *                             w_part                                       *
  *===========================================================================*/
-PRIVATE char *w_name()
+PRIVATE struct device *w_part(dev_t minor)
 {
-/* Return a name for the current device. */
-  static char name[] = "bios-d0";
+/* Return a pointer to the partition information of the given minor device. */
 
-  name[6] = '0' + w_drive;
-  return name;
+  return w_prepare(minor);
 }
 
 /*===========================================================================*
  *                             w_transfer                                   *
  *===========================================================================*/
-PRIVATE int w_transfer(proc_nr, opcode, pos64, iov, nr_req)
-int proc_nr;                   /* process doing the request */
-int opcode;                    /* DEV_GATHER or DEV_SCATTER */
-u64_t pos64;                   /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE ssize_t w_transfer(
+  dev_t minor,                 /* minor device number */
+  int do_write,                        /* read or write? */
+  u64_t pos64,                 /* offset on device to read or write */
+  endpoint_t proc_nr,          /* process doing the request */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  int UNUSED(flags)            /* transfer flags */
+)
 {
-  struct wini *wn = w_wn;
+  struct wini *wn;
   iovec_t *iop, *iov_end = iov + nr_req;
   int r, errors;
   unsigned count;
   vir_bytes chunk, nbytes;
   unsigned long block;
   vir_bytes i13e_rw_off, rem_buf_size;
-  unsigned secspcyl = wn->heads * wn->sectors;
+  unsigned secspcyl;
   struct int13ext_rw {
        u8_t    len;
        u8_t    res1;
@@ -203,12 +201,19 @@ unsigned nr_req;          /* length of request vector */
   } *i13e_rw;
   struct reg86u reg86;
   u32_t lopos;
+  ssize_t total;
+
+  if (w_prepare(minor) == NULL) return(ENXIO);
+
+  wn = w_wn;
+  secspcyl = wn->heads * wn->sectors;
 
   lopos= ex64lo(pos64);
 
   /* Check disk address. */
   if ((lopos & SECTOR_MASK) != 0) return(EINVAL);
 
+  total = 0;
   errors = 0;
 
   i13e_rw_off= BIOSBUF-sizeof(*i13e_rw);
@@ -230,7 +235,7 @@ unsigned nr_req;            /* length of request vector */
        if ((nbytes & SECTOR_MASK) != 0) return(EINVAL);
 
        /* Which block on disk and how close to EOF? */
-       if (cmp64(pos64, w_dv->dv_size) >= 0) return(OK);       /* At EOF */
+       if (cmp64(pos64, w_dv->dv_size) >= 0) return(total);    /* At EOF */
        if (cmp64(add64u(pos64, nbytes), w_dv->dv_size) > 0) {
                u64_t n;
                n = sub64(w_dv->dv_size, pos64);
@@ -242,7 +247,7 @@ unsigned nr_req;            /* length of request vector */
        /* Degrade to per-sector mode if there were errors. */
        if (errors > 0) nbytes = SECTOR_SIZE;
 
-       if (opcode == DEV_SCATTER_S) {
+       if (do_write) {
                /* Copy from user space to the DMA buffer. */
                count = 0;
                for (iop = iov; count < nbytes; iop++) {
@@ -277,7 +282,7 @@ unsigned nr_req;            /* length of request vector */
 
                /* Set up an extended read or write BIOS call. */
                reg86.u.b.intno = 0x13;
-               reg86.u.w.ax = opcode == DEV_SCATTER_S ? 0x4300 : 0x4200;
+               reg86.u.w.ax = do_write ? 0x4300 : 0x4200;
                reg86.u.b.dl = wn->drive_id;
                reg86.u.w.si = (bios_buf_phys + i13e_rw_off) % HCLICK_SIZE;
                reg86.u.w.ds = (bios_buf_phys + i13e_rw_off) / HCLICK_SIZE;
@@ -288,7 +293,7 @@ unsigned nr_req;            /* length of request vector */
                unsigned head = (block % secspcyl) / wn->sectors;
 
                reg86.u.b.intno = 0x13;
-               reg86.u.b.ah = opcode == DEV_SCATTER_S ? 0x03 : 0x02;
+               reg86.u.b.ah = do_write ? 0x03 : 0x02;
                reg86.u.b.al = nbytes >> SECTOR_SHIFT;
                reg86.u.w.bx = bios_buf_phys % HCLICK_SIZE;
                reg86.u.w.es = bios_buf_phys / HCLICK_SIZE;
@@ -308,7 +313,7 @@ unsigned nr_req;            /* length of request vector */
                continue;
        }
 
-       if (opcode == DEV_GATHER_S) {
+       if (!do_write) {
                /* Copy from the DMA buffer to user space. */
                count = 0;
                for (iop = iov; count < nbytes; iop++) {
@@ -333,7 +338,8 @@ unsigned nr_req;            /* length of request vector */
 
        /* Book the bytes successfully transferred. */
        pos64 = add64ul(pos64, nbytes);
-       for (;;) {
+       total += nbytes;
+       while (nbytes > 0) {
                if (nbytes < iov->iov_size) {
                        /* Not done with this one yet. */
                        iov->iov_size -= nbytes;
@@ -341,25 +347,17 @@ unsigned nr_req;          /* length of request vector */
                }
                nbytes -= iov->iov_size;
                iov->iov_size = 0;
-               if (nbytes == 0) {
-                       /* The rest is optional, so we return to give FS a
-                        * chance to think it over.
-                        */
-                       return(OK);
-               }
                iov++;
                nr_req--;
        }
   }
-  return(OK);
+  return(total);
 }
 
 /*============================================================================*
  *                             w_do_open                                     *
  *============================================================================*/
-PRIVATE int w_do_open(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int w_do_open(dev_t minor, int UNUSED(access))
 {
 /* Device open: Initialize the controller and read the partition table. */
 
@@ -367,7 +365,7 @@ message *m_ptr;
 
   if (!init_done) { w_init(); init_done = TRUE; }
 
-  if (w_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
+  if (w_prepare(minor) == NULL) return(ENXIO);
 
   if (w_wn->open_ct++ == 0) {
        /* Partition the disk. */
@@ -379,13 +377,11 @@ message *m_ptr;
 /*============================================================================*
  *                             w_do_close                                    *
  *============================================================================*/
-PRIVATE int w_do_close(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int w_do_close(dev_t minor)
 {
 /* Device close: Release a device. */
 
-  if (w_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
+  if (w_prepare(minor) == NULL) return(ENXIO);
   w_wn->open_ct--;
   return(OK);
 }
@@ -393,7 +389,7 @@ message *m_ptr;
 /*===========================================================================*
  *                             w_init                                       *
  *===========================================================================*/
-PRIVATE void w_init()
+PRIVATE void w_init(void)
 {
 /* This routine is called at startup to initialize the drive parameters. */
 
@@ -490,10 +486,11 @@ PRIVATE void w_init()
        }
 
        if (wn->int13ext) {
-               printf("%s: %lu sectors\n", w_name(), capacity);
+               printf("bios-d%u: %lu sectors\n", w_drive, capacity);
        } else {
-               printf("%s: %d cylinders, %d heads, %d sectors per track\n",
-                       w_name(), wn->cylinders, wn->heads, wn->sectors);
+               printf("bios-d%u: %d cylinders, %d heads, "
+                       "%d sectors per track\n",
+                       w_drive, wn->cylinders, wn->heads, wn->sectors);
        }
        wn->part[0].dv_size = mul64u(capacity, SECTOR_SIZE);
   }
@@ -502,37 +499,30 @@ PRIVATE void w_init()
 /*============================================================================*
  *                             w_geometry                                    *
  *============================================================================*/
-PRIVATE void w_geometry(entry)
-struct partition *entry;
+PRIVATE void w_geometry(dev_t minor, struct partition *entry)
 {
+  if (w_prepare(minor) == NULL) return;
+
   entry->cylinders = w_wn->cylinders;
   entry->heads = w_wn->heads;
   entry->sectors = w_wn->sectors;
 }
 
 /*============================================================================*
- *                             w_other                               *
+ *                             w_ioctl                                       *
  *============================================================================*/
-PRIVATE int w_other(struct driver *UNUSED(dr), message *m)
+PRIVATE int w_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
+       cp_grant_id_t grant)
 {
-        int r;
-
-        if (m->m_type != DEV_IOCTL_S )
-                return EINVAL;
+       int count;
 
-       if (m->REQUEST == DIOCOPENCT) {
-                int count;
-                if (w_prepare(m->DEVICE) == NULL) return ENXIO;
-                count = w_wn->open_ct;
-               r=sys_safecopyto(m->m_source, (cp_grant_id_t)m->IO_GRANT,
-                      0, (vir_bytes)&count, sizeof(count), D);
+       if (w_prepare(minor) == NULL) return ENXIO;
 
-               if(r != OK)
-                        return r;
-                return OK;
-        }
+       if (request == DIOCOPENCT) {
+               count = w_wn->open_ct;
+               return sys_safecopyto(endpt, grant, 0, (vir_bytes)&count,
+                       sizeof(count), D);
+       }
 
-        return EINVAL;
+       return EINVAL;
 }
-
-
index 7d91a0f74d66fc30e6722f08858af5607617d915..3c5ad08ba9108f5f7863c5685dd1327024609ca8 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  filter
 SRCS=  main.c sum.c driver.c util.c crc.c md5.c
 
-DPADD+= ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+= ${LIBBLOCKDRIVER} ${LIBSYS}
+LDADD+=        -lblockdriver -lsys
 
 MAN=
 
index 356018b7ebd06608e09ac700694789e6dead59fc..68d06468415a8bc22af61a7d33d3c7adfadac540 100644 (file)
@@ -77,7 +77,7 @@ unsigned long compute_crc(const unsigned char *b, size_t n)
       /* Replace an intermediate zero with the next value
        * from the sequence */
       i = aux++;
-      if (aux >= sizeof(crctab) / sizeof(crctab[0])) aux = 0;
+      if ((size_t) aux >= sizeof(crctab) / sizeof(crctab[0])) aux = 0;
     }
 
     /* New checksum value */
index 62abaf0dcf6681ad38c22bb15c6e30809c6c41ba..09293b3a113743a52934df40908ef10453750671 100644 (file)
@@ -6,7 +6,6 @@
 static struct driverinfo driver[2];
 
 /* State variables. */
-static endpoint_t self_ep;
 static asynmsg_t amsgtable[2];
 
 static int size_known = 0;
@@ -29,9 +28,11 @@ static int driver_open(int which)
        sector_t sectors;
        int r;
 
-       msg.m_type = DEV_OPEN;
-       msg.DEVICE = driver[which].minor;
-       msg.USER_ENDPT = self_ep;
+       memset(&msg, 0, sizeof(msg));
+       msg.m_type = BDEV_OPEN;
+       msg.BDEV_MINOR = driver[which].minor;
+       msg.BDEV_ACCESS = R_BIT | W_BIT;
+       msg.BDEV_ID = 0;
        r = sendrec(driver[which].endpt, &msg);
 
        if (r != OK) {
@@ -41,9 +42,9 @@ static int driver_open(int which)
                return RET_REDO;
        }
 
-       if(msg.m_type != TASK_REPLY || msg.REP_STATUS != OK) {
+       if(msg.m_type != BDEV_REPLY || msg.BDEV_STATUS != OK) {
                printf("Filter: driver_open: sendrec returned %d, %d\n",
-                       msg.m_type, msg.REP_STATUS);
+                       msg.m_type, msg.BDEV_STATUS);
 
                return RET_REDO;
        }
@@ -54,17 +55,18 @@ static int driver_open(int which)
        if(!GRANT_VALID(gid))
                panic("invalid grant: %d", gid);
 
-       msg.m_type = DEV_IOCTL_S;
-       msg.REQUEST = DIOCGETP;
-       msg.DEVICE = driver[which].minor;
-       msg.USER_ENDPT = self_ep;
-       msg.IO_GRANT = (char *) gid;
+       memset(&msg, 0, sizeof(msg));
+       msg.m_type = BDEV_IOCTL;
+       msg.BDEV_MINOR = driver[which].minor;
+       msg.BDEV_REQUEST = DIOCGETP;
+       msg.BDEV_GRANT = gid;
+       msg.BDEV_ID = 0;
 
        r = sendrec(driver[which].endpt, &msg);
 
        cpf_revoke(gid);
 
-       if (r != OK || msg.m_type != TASK_REPLY || msg.REP_STATUS != OK) {
+       if (r != OK || msg.m_type != BDEV_REPLY || msg.BDEV_STATUS != OK) {
                /* Not sure what to do here, either. */
                printf("Filter: ioctl(DIOCGETP) returned (%d, %d)\n", 
                        r, msg.m_type);
@@ -105,9 +107,10 @@ static int driver_close(int which)
        message msg;
        int r;
 
-       msg.m_type = DEV_CLOSE;
-       msg.DEVICE = driver[which].minor;
-       msg.USER_ENDPT = self_ep;
+       memset(&msg, 0, sizeof(msg));
+       msg.m_type = BDEV_CLOSE;
+       msg.BDEV_MINOR = driver[which].minor;
+       msg.BDEV_ID = 0;
        r = sendrec(driver[which].endpt, &msg);
 
        if (r != OK) {
@@ -117,9 +120,9 @@ static int driver_close(int which)
                return RET_REDO;
        }
 
-       if(msg.m_type != TASK_REPLY || msg.REP_STATUS != OK) {
+       if(msg.m_type != BDEV_REPLY || msg.BDEV_STATUS != OK) {
                printf("Filter: driver_close: sendrec returned %d, %d\n",
-                       msg.m_type, msg.REP_STATUS);
+                       msg.m_type, msg.BDEV_STATUS);
 
                return RET_REDO;
        }
@@ -135,8 +138,6 @@ void driver_init(void)
        /* Initialize the driver layer. */
        int r;
 
-       self_ep = getprocnr();
-
        memset(driver, 0, sizeof(driver));
 
        /* Endpoints unknown. */
@@ -200,11 +201,11 @@ void driver_shutdown(void)
 #endif
 
        if(driver_close(DRIVER_MAIN) != OK)
-               printf("Filter: DEV_CLOSE failed on shutdown (1)\n");
+               printf("Filter: BDEV_CLOSE failed on shutdown (1)\n");
 
        if(USE_MIRROR)
                if(driver_close(DRIVER_BACKUP) != OK)
-                       printf("Filter: DEV_CLOSE failed on shutdown (2)\n");
+                       printf("Filter: BDEV_CLOSE failed on shutdown (2)\n");
 }
 
 /*===========================================================================*
@@ -520,8 +521,8 @@ static int flt_senda(message *mess, int which)
        asynmsg_t *amp;
 
        /* Fill in the last bits of the message. */
-       mess->DEVICE = driver[which].minor;
-       mess->USER_ENDPT = self_ep;
+       mess->BDEV_MINOR = driver[which].minor;
+       mess->BDEV_ID = 0;
 
        /* Send the message asynchronously. */
        amp = &amsgtable[which];
@@ -745,7 +746,7 @@ static int do_sendrec_both(message *m1, message *m2)
 /*===========================================================================*
  *                             do_sendrec_one                               *
  *===========================================================================*/
-static int do_sendrec_one(message *m1, const message *m2)
+static int do_sendrec_one(message *m1)
 {
        /* Only talk to the main driver. If something goes wrong, it will
         * be fixed elsewhere.
@@ -768,14 +769,14 @@ static int paired_sendrec(message *m1, message *m2, int both)
 
 #if DEBUG2
        printf("paired_sendrec(%d) - <%d,%x:%x,%d> - %x,%x\n",
-               both, m1->m_type, m1->HIGHPOS, m1->POSITION, m1->COUNT,
-               m1->IO_GRANT, m2->IO_GRANT);
+               both, m1->m_type, m1->BDEV_POS_HI, m1->BDEV_POS_LO,
+               m1->BDEV_COUNT, m1->BDEV_GRANT, m2->BDEV_GRANT);
 #endif
 
        if (both)
                r = do_sendrec_both(m1, m2);
        else
-               r = do_sendrec_one(m1, m2);
+               r = do_sendrec_one(m1);
 
 #if DEBUG2
        if (r != OK)
@@ -789,16 +790,14 @@ static int paired_sendrec(message *m1, message *m2, int both)
  *                             single_grant                                 *
  *===========================================================================*/
 static int single_grant(endpoint_t endpt, vir_bytes buf, int access,
-       cp_grant_id_t *gid, iovec_s_t vector[NR_IOREQS], const size_t *sizep)
+       cp_grant_id_t *gid, iovec_s_t vector[NR_IOREQS], size_t size)
 {
        /* Create grants for a vectored request to a single driver.
         */
        cp_grant_id_t grant;
-       size_t size, chunk;
+       size_t chunk;
        int count;
 
-       size = *sizep;
-
        /* Split up the request into chunks, if requested. This makes no
         * difference at all, except that this works around a weird performance
         * bug with large DMA PRDs on some machines.
@@ -825,7 +824,7 @@ static int single_grant(endpoint_t endpt, vir_bytes buf, int access,
 
        /* Then create a grant for the vector itself. */
        *gid = cpf_grant_direct(endpt, (vir_bytes) vector,
-               sizeof(vector[0]) * count, CPF_READ | CPF_WRITE);
+               sizeof(vector[0]) * count, CPF_READ);
 
        if (!GRANT_VALID(*gid))
                panic("invalid grant: %d", *gid);
@@ -837,7 +836,7 @@ static int single_grant(endpoint_t endpt, vir_bytes buf, int access,
  *                             paired_grant                                 *
  *===========================================================================*/
 static int paired_grant(char *buf1, char *buf2, int request,
-       cp_grant_id_t *gids, iovec_s_t vectors[2][NR_IOREQS], size_t *sizes,
+       cp_grant_id_t *gids, iovec_s_t vectors[2][NR_IOREQS], size_t size,
        int both)
 {
        /* Create memory grants, either to one or to both drivers.
@@ -849,15 +848,14 @@ static int paired_grant(char *buf1, char *buf2, int request,
 
        if(driver[DRIVER_MAIN].endpt > 0) {
                count = single_grant(driver[DRIVER_MAIN].endpt,
-                       (vir_bytes) buf1, access, &gids[0], vectors[0],
-                       &sizes[0]);
+                       (vir_bytes) buf1, access, &gids[0], vectors[0], size);
        }
 
        if (both) {
                if(driver[DRIVER_BACKUP].endpt > 0) {
                        count = single_grant(driver[DRIVER_BACKUP].endpt,
                                (vir_bytes) buf2, access, &gids[1],
-                               vectors[1], &sizes[1]);
+                               vectors[1], size);
                }
        }
         return count;
@@ -866,8 +864,8 @@ static int paired_grant(char *buf1, char *buf2, int request,
 /*===========================================================================*
  *                             single_revoke                                *
  *===========================================================================*/
-PRIVATE void single_revoke(cp_grant_id_t gid, const iovec_s_t vector[NR_IOREQS],
-       size_t *sizep, int count)
+PRIVATE void single_revoke(cp_grant_id_t gid,
+       const iovec_s_t vector[NR_IOREQS], int count)
 {
        /* Revoke all grants associated with a request to a single driver.
         * Modify the given size to reflect the actual I/O performed.
@@ -875,10 +873,8 @@ PRIVATE void single_revoke(cp_grant_id_t gid, const iovec_s_t vector[NR_IOREQS],
        int i;
 
        /* Revoke the grants for all the elements of the vector. */
-       for (i = 0; i < count; i++) {
+       for (i = 0; i < count; i++)
                cpf_revoke(vector[i].iov_grant);
-               *sizep -= vector[i].iov_size;
-       }
 
        /* Then revoke the grant for the vector itself. */
        cpf_revoke(gid);
@@ -888,16 +884,15 @@ PRIVATE void single_revoke(cp_grant_id_t gid, const iovec_s_t vector[NR_IOREQS],
  *                             paired_revoke                                *
  *===========================================================================*/
 static void paired_revoke(const cp_grant_id_t *gids,
-        iovec_s_t vectors[2][NR_IOREQS],
-       size_t *sizes, int count, int both)
+        iovec_s_t vectors[2][NR_IOREQS], int count, int both)
 {
        /* Revoke grants to drivers for a single request.
         */
 
-       single_revoke(gids[0], vectors[0], &sizes[0], count);
+       single_revoke(gids[0], vectors[0], count);
 
        if (both)
-               single_revoke(gids[1], vectors[1], &sizes[1], count);
+               single_revoke(gids[1], vectors[1], count);
 }
 
 /*===========================================================================*
@@ -908,32 +903,31 @@ int read_write(u64_t pos, char *bufa, char *bufb, size_t *sizep, int request)
        iovec_s_t vectors[2][NR_IOREQS];
        message m1, m2;
        cp_grant_id_t gids[2];
-       size_t sizes[2];
        int r, both, count;
 
        gids[0] = gids[1] = GRANT_INVALID;
-       sizes[0] = sizes[1] = *sizep;
 
        /* Send two requests only if mirroring is enabled and the given request
         * is either FLT_READ2 or FLT_WRITE.
         */
        both = (USE_MIRROR && request != FLT_READ);
 
-       count = paired_grant(bufa, bufb, request, gids, vectors, sizes, both);
+       count = paired_grant(bufa, bufb, request, gids, vectors, *sizep, both);
 
-       m1.m_type = (request == FLT_WRITE) ? DEV_SCATTER_S : DEV_GATHER_S;
-       m1.COUNT = count;
-       m1.POSITION = ex64lo(pos);
-       m1.HIGHPOS = ex64hi(pos);
+       memset(&m1, 0, sizeof(m1));
+       m1.m_type = (request == FLT_WRITE) ? BDEV_SCATTER : BDEV_GATHER;
+       m1.BDEV_COUNT = count;
+       m1.BDEV_POS_LO = ex64lo(pos);
+       m1.BDEV_POS_HI = ex64hi(pos);
 
        m2 = m1;
 
-       m1.IO_GRANT = (char *) gids[0];
-       m2.IO_GRANT = (char *) gids[1];
+       m1.BDEV_GRANT = gids[0];
+       m2.BDEV_GRANT = gids[1];
 
        r = paired_sendrec(&m1, &m2, both);
 
-       paired_revoke(gids, vectors, sizes, count, both);
+       paired_revoke(gids, vectors, count, both);
 
        if(r != OK) {
 #if DEBUG
@@ -943,51 +937,52 @@ int read_write(u64_t pos, char *bufa, char *bufb, size_t *sizep, int request)
                return r;
        }
 
-       if (m1.m_type != TASK_REPLY || m1.REP_STATUS != OK) {
+       if (m1.m_type != BDEV_REPLY || m1.BDEV_STATUS < 0) {
                printf("Filter: unexpected/invalid reply from main driver: "
-                       "(%x, %d)\n", m1.m_type, m1.REP_STATUS);
+                       "(%x, %d)\n", m1.m_type, m1.BDEV_STATUS);
 
                return bad_driver(DRIVER_MAIN, BD_PROTO,
-                       (m1.m_type == TASK_REPLY) ? m1.REP_STATUS : EFAULT);
+                       (m1.m_type == BDEV_REPLY) ? m1.BDEV_STATUS : EFAULT);
        }
 
-       if (sizes[0] != *sizep) {
+       if (m1.BDEV_STATUS != (ssize_t) *sizep) {
                printf("Filter: truncated reply from main driver\n");
 
                /* If the driver returned a value *larger* than we requested,
                 * OR if we did NOT exceed the disk size, then we should
                 * report the driver for acting strangely!
                 */
-               if (sizes[0] > *sizep ||
-                       cmp64(add64u(pos, sizes[0]), disk_size) < 0)
+               if (m1.BDEV_STATUS > (ssize_t) *sizep ||
+                       cmp64(add64u(pos, m1.BDEV_STATUS), disk_size) < 0)
                        return bad_driver(DRIVER_MAIN, BD_PROTO, EFAULT);
 
                /* Return the actual size. */
-               *sizep = sizes[0];
+               *sizep = m1.BDEV_STATUS;
        }
 
        if (both) {
-               if (m2.m_type != TASK_REPLY || m2.REP_STATUS != OK) {
+               if (m2.m_type != BDEV_REPLY || m2.BDEV_STATUS < 0) {
                        printf("Filter: unexpected/invalid reply from "
                                "backup driver (%x, %d)\n",
-                               m2.m_type, m2.REP_STATUS);
+                               m2.m_type, m2.BDEV_STATUS);
 
                        return bad_driver(DRIVER_BACKUP, BD_PROTO,
-                               m2.m_type == TASK_REPLY ? m2.REP_STATUS :
+                               m2.m_type == BDEV_REPLY ? m2.BDEV_STATUS :
                                EFAULT);
                }
-               if (sizes[1] != *sizep) {
+               if (m2.BDEV_STATUS != (ssize_t) *sizep) {
                        printf("Filter: truncated reply from backup driver\n");
 
                        /* As above */
-                       if (sizes[1] > *sizep ||
-                               cmp64(add64u(pos, sizes[1]), disk_size) < 0)
+                       if (m2.BDEV_STATUS > (ssize_t) *sizep ||
+                                       cmp64(add64u(pos, m2.BDEV_STATUS),
+                                       disk_size) < 0)
                                return bad_driver(DRIVER_BACKUP, BD_PROTO,
                                        EFAULT);
 
                        /* Return the actual size. */
-                       if (*sizep >= sizes[1])
-                               *sizep = sizes[1];
+                       if ((ssize_t) *sizep >= m2.BDEV_STATUS)
+                               *sizep = m2.BDEV_STATUS;
                }
        }
 
@@ -1000,7 +995,7 @@ int read_write(u64_t pos, char *bufa, char *bufb, size_t *sizep, int request)
 void ds_event()
 {
        char key[DS_MAX_KEYLEN];
-       char *driver_prefix = "drv.vfs.";
+       char *blkdriver_prefix = "drv.blk.";
        u32_t value;
        int type;
        endpoint_t owner_endpoint;
@@ -1021,7 +1016,7 @@ void ds_event()
        }
 
        /* Only check for VFS driver up events. */
-       if(strncmp(key, driver_prefix, sizeof(driver_prefix))
+       if(strncmp(key, blkdriver_prefix, strlen(blkdriver_prefix))
           || value != DS_DRIVER_UP) {
                return;
        }
index ccd5f9e34a2cb50dce5ea509dcd7a3f62d2a1d45..f93d86eb0cce367d9dddc4b05ff78fb7b5603a08 100644 (file)
@@ -12,7 +12,7 @@
 #include <minix/partition.h>
 #include <minix/ds.h>
 #include <minix/callnr.h>
-#include <minix/driver.h>
+#include <minix/blockdriver.h>
 #include <minix/optset.h>
 #include <unistd.h>
 #include <stdio.h>
index 2b36e7c6aa3ac701f17e4c7d8ff31242902e6b90..a2a6a404d97981b04e937ddbd4d25c9aa5e69cba 100644 (file)
@@ -60,14 +60,14 @@ PRIVATE struct optset optset_table[] = {
   { "timeout", OPT_INT,        &DRIVER_TIMEOUT,        10              },
   { "T",       OPT_INT,        &DRIVER_TIMEOUT,        10              },
   { "chunk",   OPT_INT,        &CHUNK_SIZE,            10              },
-  { NULL                                                               }
+  { NULL,      0,              NULL,                   0               }
 };
 
 /* Request message. */
 static message m_in;
 static endpoint_t who_e;                       /* m_source */
-static endpoint_t proc_e;                      /* USER_ENDPT */
-static cp_grant_id_t grant_id;                 /* IO_GRANT */
+static long req_id;                            /* BDEV_ID */
+static cp_grant_id_t grant_id;                 /* BDEV_GRANT */
 
 /* Data buffers. */
 static char *buf_array, *buffer;               /* contiguous buffer */
@@ -136,8 +136,8 @@ static int do_rdwt(int flag_rw)
        u64_t pos;
        int r;
 
-       pos = make64(m_in.POSITION, m_in.HIGHPOS);
-       size = m_in.COUNT;
+       pos = make64(m_in.BDEV_POS_LO, m_in.BDEV_POS_HI);
+       size = m_in.BDEV_COUNT;
 
        if (rem64u(pos, SECTOR_SIZE) != 0 || size % SECTOR_SIZE != 0) {
                printf("Filter: unaligned request from caller!\n");
@@ -169,7 +169,11 @@ static int do_rdwt(int flag_rw)
                carry(size_ret, flag_rw);
 
        flt_free(buffer, size, buf_array);
-       return r != OK ? r : size_ret;
+
+       if (r != OK)
+               return r;
+
+       return size_ret;
 }
 
 /*===========================================================================*
@@ -177,20 +181,20 @@ static int do_rdwt(int flag_rw)
  *===========================================================================*/
 static int do_vrdwt(int flag_rw)
 {
-       size_t size, size_ret, bytes;
+       size_t size, size_ret;
        int grants;
        int r, i;
        u64_t pos;
        iovec_t iov_proc[NR_IOREQS];
 
        /* Extract informations. */
-       grants = m_in.COUNT;
+       grants = m_in.BDEV_COUNT;
        if((r = sys_safecopyfrom(who_e, grant_id, 0, (vir_bytes) iov_proc,
                grants * sizeof(iovec_t), D)) != OK) {
                panic("copying in grant vector failed: %d", r);
        }
 
-       pos = make64(m_in.POSITION, m_in.HIGHPOS);
+       pos = make64(m_in.BDEV_POS_LO, m_in.BDEV_POS_HI);
        for(size = 0, i = 0; i < grants; i++)
                size += iov_proc[i].iov_size;
 
@@ -227,22 +231,9 @@ static int do_vrdwt(int flag_rw)
        if(flag_rw == FLT_READ)
                vcarry(grants, iov_proc, flag_rw, size_ret);
 
-       /* Set the result-iovec. */
-       for(i = 0; i < grants && size_ret > 0; i++) {
-               bytes = MIN(size_ret, iov_proc[i].iov_size);
-
-               iov_proc[i].iov_size -= bytes;
-               size_ret -= bytes;
-       }
-
-       /* Copy the caller's grant-table back. */
-       if((r = sys_safecopyto(who_e, grant_id, 0, (vir_bytes) iov_proc,
-               grants * sizeof(iovec_t), D)) != OK) {
-               panic("copying out grant vector failed: %d", r);
-       }
-
        flt_free(buffer, size, buf_array);
-       return OK;
+
+       return size_ret;
 }
 
 /*===========================================================================*
@@ -252,7 +243,7 @@ static int do_ioctl(message *m)
 {
        struct partition sizepart;
 
-       switch(m->REQUEST) {
+       switch(m->BDEV_REQUEST) {
        case DIOCSETP:
        case DIOCTIMEOUT:
        case DIOCOPENCT:
@@ -276,7 +267,8 @@ static int do_ioctl(message *m)
                break;
 
        default:
-               printf("Filter: unknown ioctl request: %d!\n", m->REQUEST);
+               printf("Filter: unknown ioctl request: %d!\n",
+                       m->BDEV_REQUEST);
                return EINVAL;
        }
 
@@ -372,8 +364,8 @@ static int parse_arguments(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
        message m_out;
-       int ipc_status;
-       int r;
+       int r, ipc_status;
+       size_t size;
 
        /* SEF local startup. */
        env_setargs(argc, argv);
@@ -396,18 +388,19 @@ int main(int argc, char *argv[])
                }
 
                who_e = m_in.m_source;
-               proc_e = m_in.USER_ENDPT;
-               grant_id = (cp_grant_id_t) m_in.IO_GRANT;
+               req_id = m_in.BDEV_ID;
+               grant_id = m_in.BDEV_GRANT;
+               size = 0;
 
                /* Forword the request message to the drivers. */
                switch(m_in.m_type) {
-               case DEV_OPEN:          /* open/close is a noop for filter. */
-               case DEV_CLOSE:         r = OK;                         break;
-               case DEV_READ_S:        r = do_rdwt(FLT_READ);          break;
-               case DEV_WRITE_S:       r = do_rdwt(FLT_WRITE);         break;
-               case DEV_GATHER_S:      r = do_vrdwt(FLT_READ);         break;
-               case DEV_SCATTER_S:     r = do_vrdwt(FLT_WRITE);        break;
-               case DEV_IOCTL_S:       r = do_ioctl(&m_in);            break;
+               case BDEV_OPEN:         /* open/close is a noop for filter. */
+               case BDEV_CLOSE:        r = OK;                         break;
+               case BDEV_READ:         r = do_rdwt(FLT_READ);          break;
+               case BDEV_WRITE:        r = do_rdwt(FLT_WRITE);         break;
+               case BDEV_GATHER:       r = do_vrdwt(FLT_READ);         break;
+               case BDEV_SCATTER:      r = do_vrdwt(FLT_WRITE);        break;
+               case BDEV_IOCTL:        r = do_ioctl(&m_in);            break;
 
                default:
                        printf("Filter: ignoring unknown request %d from %d\n", 
@@ -420,9 +413,9 @@ int main(int argc, char *argv[])
 #endif
 
                /* Send back reply message. */
-               m_out.m_type = TASK_REPLY;
-               m_out.REP_ENDPT = proc_e;
-               m_out.REP_STATUS = r;
+               m_out.m_type = BDEV_REPLY;
+               m_out.BDEV_ID = req_id;
+               m_out.BDEV_STATUS = r;
                send(who_e, &m_out);
        }
 
@@ -450,7 +443,7 @@ PRIVATE void sef_local_startup(void)
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the filter driver. */
        int r;
@@ -468,14 +461,14 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
 
        driver_init();
 
-       /* Subscribe to driver events for VFS drivers. */
-       r = ds_subscribe("drv\\.vfs\\..*", DSF_INITIAL | DSF_OVERWRITE);
+       /* Subscribe to block driver events. */
+       r = ds_subscribe("drv\\.blk\\..*", DSF_INITIAL | DSF_OVERWRITE);
        if(r != OK) {
                panic("Filter: can't subscribe to driver events");
        }
 
        /* Announce we are up! */
-       driver_announce();
+       blockdriver_announce();
 
        return(OK);
 }
index 18d3b2efdbb495f61a7824ef93f72efda4b66f89..06dba85636ed1d27f1dd5136bf5db5dd5f380458 100644 (file)
@@ -59,7 +59,7 @@ static void calc_sum(unsigned sector, char *data, char *sum)
                memset(sum, 0, SUM_SIZE);
                for(i = 0; i < SECTOR_SIZE / SUM_SIZE; i++) {
                        q = (unsigned long *) sum;
-                       for(j = 0; j < SUM_SIZE / sizeof(*p); j++) {
+                       for(j = 0; (size_t) j < SUM_SIZE / sizeof(*p); j++) {
                                *q ^= *p;
                                q++;
                                p++;
index 55fbec736290f44e5a487916e4eb119dcbd55437..1c5b4ef21ab3e5f0fa70a61f7ed64adbec0c2c33 100644 (file)
@@ -48,8 +48,8 @@ char *print64(u64_t p)
        static char buf[NB][100];
        u32_t lo = ex64lo(p), hi = ex64hi(p);
        n = (n+1) % NB;
-       if(!hi) sprintf(buf[n], "%lx", lo);
-       else sprintf(buf[n], "%lx%08lx", hi, lo);
+       if(!hi) sprintf(buf[n], "%x", lo);
+       else sprintf(buf[n], "%x%08x", hi, lo);
        return buf[n];
 }
 
index 62864941e1618c8094d374a12746e3ec06a7e1ec..99b180ccc232fe602e482767e3c7bfc10d48f4de 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  floppy
 SRCS=  floppy.c liveupdate.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
-LDADD+=        -ldriver -lsys -ltimers
+DPADD+=        ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+=        -lblockdriver -lsys -ltimers
 
 MAN=
 
index d79c0fe9c83e6ee0ab92bd9e580c2c6d4d82e96a..8bf2ba2b6d29c21d9a52eeffb8f4bdb4c33c4e4e 100644 (file)
 #define UNCALIBRATED       0   /* drive needs to be calibrated at next use */
 #define CALIBRATED         1   /* no calibration needed */
 #define BASE_SECTOR        1   /* sectors are numbered starting at 1 */
-#define NO_SECTOR        (-1)  /* current sector unknown */
+#define NO_SECTOR ((unsigned) -1)      /* current sector unknown */
 #define NO_CYL          (-1)   /* current cylinder unknown, must seek */
 #define NO_DENS                 100    /* current media unknown */
 #define BSY_IDLE          0    /* busy doing nothing */
@@ -238,19 +238,20 @@ PRIVATE u8_t f_results[MAX_RESULTS];/* the controller can give lots of output */
  */
 PRIVATE timer_t f_tmr_timeout;         /* timer for various timeouts */
 PRIVATE u32_t system_hz;               /* system clock frequency */
-FORWARD _PROTOTYPE( void f_expire_tmrs, (struct driver *dp, message *m_ptr) );
+FORWARD _PROTOTYPE( void f_expire_tmrs, (clock_t stamp)                        );
 FORWARD _PROTOTYPE( void stop_motor, (timer_t *tp)                     );
 FORWARD _PROTOTYPE( void f_timeout, (timer_t *tp)                      );
 
-FORWARD _PROTOTYPE( struct device *f_prepare, (int device)             );
-FORWARD _PROTOTYPE( char *f_name, (void)                               );
+FORWARD _PROTOTYPE( struct device *f_prepare, (dev_t device)           );
+FORWARD _PROTOTYPE( struct device *f_part, (dev_t minor)               );
 FORWARD _PROTOTYPE( void f_cleanup, (void)                             );
-FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, u64_t position,
-                                       iovec_t *iov, unsigned nr_req)  );
-FORWARD _PROTOTYPE( int dma_setup, (int opcode)                        );
+FORWARD _PROTOTYPE( ssize_t f_transfer, (dev_t minor, int do_write,
+       u64_t position, endpoint_t proc_nr, iovec_t *iov,
+       unsigned int nr_req, int flags)                                 );
+FORWARD _PROTOTYPE( int dma_setup, (int do_write)                      );
 FORWARD _PROTOTYPE( void start_motor, (void)                           );
 FORWARD _PROTOTYPE( int seek, (void)                                   );
-FORWARD _PROTOTYPE( int fdc_transfer, (int opcode)                     );
+FORWARD _PROTOTYPE( int fdc_transfer, (int do_write)                   );
 FORWARD _PROTOTYPE( int fdc_results, (void)                            );
 FORWARD _PROTOTYPE( int fdc_command, (const u8_t *cmd, int len)        );
 FORWARD _PROTOTYPE( void fdc_out, (int val)                            );
@@ -258,25 +259,25 @@ FORWARD _PROTOTYPE( int recalibrate, (void)                               );
 FORWARD _PROTOTYPE( void f_reset, (void)                               );
 FORWARD _PROTOTYPE( int f_intr_wait, (void)                            );
 FORWARD _PROTOTYPE( int read_id, (void)                                );
-FORWARD _PROTOTYPE( int f_do_open, (struct driver *dp, message *m_ptr)         );
+FORWARD _PROTOTYPE( int f_do_open, (dev_t minor, int access)           );
+FORWARD _PROTOTYPE( int f_do_close, (dev_t minor)                      );
 FORWARD _PROTOTYPE( int test_read, (int density)                       );
-FORWARD _PROTOTYPE( void f_geometry, (struct partition *entry)         );
+FORWARD _PROTOTYPE( void f_geometry, (dev_t minor,
+       struct partition *entry)                                        );
 
 /* Entry points to this driver. */
-PRIVATE struct driver f_dtab = {
-  f_name,      /* current device's name */
+PRIVATE struct blockdriver f_dtab = {
   f_do_open,   /* open or mount request, sense type of diskette */
-  do_nop,      /* nothing on a close */
-  do_diocntl,  /* get or set a partitions geometry */
-  f_prepare,   /* prepare for I/O on a given minor device */
+  f_do_close,  /* nothing on a close */
   f_transfer,  /* do the I/O */
+  NULL,                /* no other I/O control requests are supported */
   f_cleanup,   /* cleanup before sending reply to user process */
+  f_part,      /* return partition information structure */
   f_geometry,  /* tell the geometry of the diskette */
+  NULL,                /* no processing of hardware interrupts */
   f_expire_tmrs,/* expire all alarm timers */
-  nop_cancel,
-  nop_select,
-  NULL,
-  NULL
+  NULL,                /* no processing of other messages */
+  NULL         /* no threading support */
 };
 
 static char *floppy_buf;
@@ -289,7 +290,7 @@ FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
 EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
 EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
 EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
-PUBLIC int last_transfer_opcode;
+PUBLIC int last_was_write;
 
 /*===========================================================================*
  *                             floppy_task                                  *
@@ -300,7 +301,7 @@ PUBLIC int main(void)
   sef_local_startup();
 
   /* Call the generic receive loop. */
-  driver_task(&f_dtab, DRIVER_STD);
+  blockdriver_task(&f_dtab);
 
   return(OK);
 }
@@ -330,7 +331,7 @@ PRIVATE void sef_local_startup(void)
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the floppy driver. */
   struct floppy *fp;
@@ -362,7 +363,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
        panic("Couldn't enable IRQs: %d", s);
 
   /* Announce we are up! */
-  driver_announce();
+  blockdriver_announce();
 
   return(OK);
 }
@@ -386,25 +387,25 @@ PRIVATE void sef_cb_signal_handler(int signo)
 /*===========================================================================*
  *                             f_expire_tmrs                                *
  *===========================================================================*/
-PRIVATE void f_expire_tmrs(struct driver *dp, message *m_ptr)
+PRIVATE void f_expire_tmrs(clock_t stamp)
 {
 /* A synchronous alarm message was received. Call the watchdog function for
  * each expired timer, if any.
  */
 
-  expire_timers(m_ptr->NOTIFY_TIMESTAMP);
+  expire_timers(stamp);
 }
 
 /*===========================================================================*
  *                             f_prepare                                    *
  *===========================================================================*/
-PRIVATE struct device *f_prepare(int device)
+PRIVATE struct device *f_prepare(dev_t device)
 {
 /* Prepare for I/O on a device. */
 
   f_device = device;
   f_drive = device & ~(DEV_TYPE_BITS | FORMAT_DEV_BIT);
-  if (f_drive < 0 || f_drive >= NR_DRIVES) return(NULL);
+  if (f_drive >= NR_DRIVES) return(NULL);
 
   f_fp = &floppy[f_drive];
   f_dv = &f_fp->fl_geom;
@@ -423,15 +424,13 @@ PRIVATE struct device *f_prepare(int device)
 }
 
 /*===========================================================================*
- *                             f_name                                       *
+ *                             f_part                                       *
  *===========================================================================*/
-PRIVATE char *f_name(void)
+PRIVATE struct device *f_part(dev_t minor)
 {
-/* Return a name for the current device. */
-  static char name[] = "fd0";
+/* Return a pointer to the partition information of the given minor device. */
 
-  name[2] = '0' + f_drive;
-  return name;
+  return f_prepare(minor);
 }
 
 /*===========================================================================*
@@ -449,32 +448,41 @@ PRIVATE void f_cleanup(void)
 /*===========================================================================*
  *                             f_transfer                                   *
  *===========================================================================*/
-PRIVATE int f_transfer(proc_nr, opcode, pos64, iov, nr_req)
-int proc_nr;                   /* process doing the request */
-int opcode;                    /* DEV_GATHER_S or DEV_SCATTER_S */
-u64_t pos64;                   /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE ssize_t f_transfer(
+  dev_t minor,                 /* minor device number */
+  int do_write,                        /* read or write? */
+  u64_t pos64,                 /* offset on device to read or write */
+  endpoint_t proc_nr,          /* process doing the request */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  int UNUSED(flags)            /* transfer flags */
+)
 {
 #define NO_OFFSET -1
-  struct floppy *fp = f_fp;
+  struct floppy *fp;
   iovec_t *iop, *iov_end = iov + nr_req;
   int s, r, errors, nr;
-  unsigned block;      /* Seen any 32M floppies lately? */
-  unsigned nbytes, count, chunk, sector;
-  unsigned long dv_size = cv64ul(f_dv->dv_size);
+  unsigned block, nbytes, count, chunk, sector;
+  unsigned long dv_size;
   vir_bytes user_offset, iov_offset = 0, iop_offset;
-  off_t position;
+  unsigned long position;
   signed long uoffsets[MAX_SECTORS], *up;
-  cp_grant_id_t ugrants[MAX_SECTORS], *ug;
+  cp_grant_id_t ugrants[MAX_SECTORS], *ug = NULL;
   u8_t cmd[3];
+  ssize_t total;
+
+  if (f_prepare(minor) == NULL) return(ENXIO);
+
+  fp = f_fp;
+  dv_size = cv64ul(f_dv->dv_size);
 
   if (ex64hi(pos64) != 0)
        return OK;      /* Way beyond EOF */
   position= cv64ul(pos64);
+  total = 0;
 
-  /* Record the opcode of the last transfer performed. */
-  last_transfer_opcode = opcode;
+  /* Record the direction of the last transfer performed. */
+  last_was_write = do_write;
 
   /* Check disk address. */
   if ((position & SECTOR_MASK) != 0) return(EINVAL);
@@ -492,7 +500,7 @@ unsigned nr_req;            /* length of request vector */
        for (iop = iov; iop < iov_end; iop++) nbytes += iop->iov_size;
 
        /* Which block on disk and how close to EOF? */
-       if (position >= dv_size) return(OK);            /* At EOF */
+       if (position >= dv_size) return(total);         /* At EOF */
        if (position + nbytes > dv_size) nbytes = dv_size - position;
        block = div64u(add64ul(f_dv->dv_base, position), SECTOR_SIZE);
 
@@ -500,7 +508,7 @@ unsigned nr_req;            /* length of request vector */
 
        /* Using a formatting device? */
        if (f_device & FORMAT_DEV_BIT) {
-               if (opcode != DEV_SCATTER_S) return(EIO);
+               if (!do_write) return(EIO);
                if (iov->iov_size < SECTOR_SIZE + sizeof(fmt_param))
                        return(EINVAL);
 
@@ -607,7 +615,7 @@ unsigned nr_req;            /* length of request vector */
                                fp->fl_sector++;
                        }
 
-                       if (opcode == DEV_SCATTER_S) {
+                       if (do_write) {
                                /* Copy the user bytes to the DMA buffer. */
                                if(proc_nr != SELF) {
                                   s=sys_safecopyfrom(proc_nr, *ug, *up,
@@ -623,17 +631,17 @@ unsigned nr_req;          /* length of request vector */
 
                /* Set up the DMA chip and perform the transfer. */
                if (r == OK) {
-                       if (dma_setup(opcode) != OK) {
+                       if (dma_setup(do_write) != OK) {
                                /* This can only fail for addresses above 16MB
                                 * that cannot be handled by the controller, 
                                 * because it uses 24-bit addressing.
                                 */
                                return(EIO);
                        }
-                       r = fdc_transfer(opcode);
+                       r = fdc_transfer(do_write);
                }
 
-               if (r == OK && opcode == DEV_GATHER_S) {
+               if (r == OK && !do_write) {
                        /* Copy the DMA buffer to user space. */
                        if(proc_nr != SELF) {
                           s=sys_safecopyto(proc_nr, *ug, *up,
@@ -663,7 +671,8 @@ unsigned nr_req;            /* length of request vector */
 
        /* Book the bytes successfully transferred. */
        position += nbytes;
-       for (;;) {
+       total += nbytes;
+       while (nbytes > 0) {
                if (nbytes < iov->iov_size) {
                        /* Not done with this one yet. */
                        iov_offset += nbytes;
@@ -673,25 +682,17 @@ unsigned nr_req;          /* length of request vector */
                iov_offset = 0;
                nbytes -= iov->iov_size;
                iov->iov_size = 0;
-               if (nbytes == 0) {
-                       /* The rest is optional, so we return to give FS a
-                        * chance to think it over.
-                        */
-                       return(OK);
-               }
                iov++;
                nr_req--;
        }
   }
-  return(OK);
+  return(total);
 }
 
 /*===========================================================================*
  *                             dma_setup                                    *
  *===========================================================================*/
-PRIVATE int dma_setup(
-  int opcode                   /* DEV_GATHER_S or DEV_SCATTER_S */
-)
+PRIVATE int dma_setup(int do_write)
 {
 /* The IBM PC can perform DMA operations by using the DMA chip.  To use it,
  * the DMA (Direct Memory Access) chip is loaded with the 20-bit memory address
@@ -719,7 +720,7 @@ PRIVATE int dma_setup(
    */
   pv_set(byte_out[0], DMA_INIT, DMA_RESET_VAL);        /* reset the dma controller */
   pv_set(byte_out[1], DMA_FLIPFLOP, 0);                /* write anything to reset it */
-  pv_set(byte_out[2], DMA_MODE, opcode == DEV_SCATTER_S ? DMA_WRITE : DMA_READ);
+  pv_set(byte_out[2], DMA_MODE, do_write ? DMA_WRITE : DMA_READ);
   pv_set(byte_out[3], DMA_ADDR, (unsigned) (floppy_buf_phys >>  0) & 0xff);
   pv_set(byte_out[4], DMA_ADDR, (unsigned) (floppy_buf_phys >>  8) & 0xff);
   pv_set(byte_out[5], DMA_TOP,  (unsigned) (floppy_buf_phys >> 16) & 0xff);
@@ -773,7 +774,7 @@ PRIVATE void start_motor(void)
        if (is_ipc_notify(ipc_status)) {
                switch (_ENDPOINT_P(mess.m_source)) {
                        case CLOCK:
-                               f_expire_tmrs(NULL, &mess);
+                               f_expire_tmrs(mess.NOTIFY_TIMESTAMP);
                                break;
                        default :
                                f_busy = BSY_IDLE;
@@ -848,7 +849,7 @@ PRIVATE int seek(void)
                if (is_ipc_notify(ipc_status)) {
                        switch (_ENDPOINT_P(mess.m_source)) {
                                case CLOCK:
-                                       f_expire_tmrs(NULL, &mess);
+                                       f_expire_tmrs(mess.NOTIFY_TIMESTAMP);
                                        break;
                                default :
                                        f_busy = BSY_IDLE;
@@ -867,9 +868,7 @@ PRIVATE int seek(void)
 /*===========================================================================*
  *                             fdc_transfer                                 *
  *===========================================================================*/
-PRIVATE int fdc_transfer(
-  int opcode                   /* DEV_GATHER_S or DEV_SCATTER_S */
-)
+PRIVATE int fdc_transfer(int do_write)
 {
 /* The drive is now on the proper cylinder.  Read, write or format 1 block. */
 
@@ -892,7 +891,7 @@ PRIVATE int fdc_transfer(
        cmd[5] = fmt_param.fill_byte_for_format;
        if (fdc_command(cmd, 6) != OK) return(ERR_TRANSFER);
   } else {
-       cmd[0] = opcode == DEV_SCATTER_S ? FDC_WRITE : FDC_READ;
+       cmd[0] = do_write ? FDC_WRITE : FDC_READ;
        cmd[1] = (fp->fl_head << 2) | f_drive;
        cmd[2] = fp->fl_cylinder;
        cmd[3] = fp->fl_head;
@@ -906,7 +905,7 @@ PRIVATE int fdc_transfer(
 
   /* Block, waiting for disk interrupt. */
   if (f_intr_wait() != OK) {
-       printf("%s: disk interrupt timed out.\n", f_name());
+       printf("fd%u: disk interrupt timed out.\n", f_drive);
        return(ERR_TIMEOUT);
   }
 
@@ -915,7 +914,7 @@ PRIVATE int fdc_transfer(
   if (r != OK) return(r);
 
   if (f_results[ST1] & WRITE_PROTECT) {
-       printf("%s: diskette is write protected.\n", f_name());
+       printf("fd%u: diskette is write protected.\n", f_drive);
        return(ERR_WR_PROTECT);
   }
 
@@ -1127,7 +1126,7 @@ PRIVATE void f_reset(void)
        if (is_ipc_notify(ipc_status)) {
                switch (_ENDPOINT_P(mess.m_source)) {
                        case CLOCK:
-                               f_expire_tmrs(NULL, &mess);
+                               f_expire_tmrs(mess.NOTIFY_TIMESTAMP);
                                break;
                        default :
                                f_busy = BSY_IDLE;
@@ -1177,7 +1176,7 @@ PRIVATE int f_intr_wait(void)
        if (is_ipc_notify(ipc_status)) {
                switch (_ENDPOINT_P(mess.m_source)) {
                        case CLOCK:
-                               f_expire_tmrs(NULL, &mess);
+                               f_expire_tmrs(mess.NOTIFY_TIMESTAMP);
                                break;
                        default :
                                f_busy = BSY_IDLE;
@@ -1202,7 +1201,7 @@ PRIVATE int f_intr_wait(void)
 /*===========================================================================*
  *                             f_timeout                                    *
  *===========================================================================*/
-PRIVATE void f_timeout(timer_t *tp)
+PRIVATE void f_timeout(timer_t *UNUSED(tp))
 {
 /* This routine is called when a timer expires.  Usually to tell that a
  * motor has spun up, but also to forge an interrupt when it takes too long
@@ -1250,9 +1249,7 @@ PRIVATE int read_id(void)
 /*===========================================================================*
  *                             f_do_open                                    *
  *===========================================================================*/
-PRIVATE int f_do_open(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;                        /* pointer to open message */
+PRIVATE int f_do_open(dev_t minor, int UNUSED(access))
 {
 /* Handle an open on a floppy.  Determine diskette type if need be. */
 
@@ -1260,7 +1257,7 @@ message *m_ptr;                   /* pointer to open message */
   struct test_order *top;
 
   /* Decode the message parameters. */
-  if (f_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
+  if (f_prepare(minor) == NULL) return(ENXIO);
 
   dtype = f_device & DEV_TYPE_BITS;    /* get density from minor dev */
   if (dtype >= MINOR_fd0p0) dtype = 0;
@@ -1308,6 +1305,16 @@ message *m_ptr;                  /* pointer to open message */
   return(EIO);                 /* nothing worked */
 }
 
+/*===========================================================================*
+ *                             f_do_close                                   *
+ *===========================================================================*/
+PRIVATE int f_do_close(dev_t UNUSED(minor))
+{
+/* Handle a close on a floppy.  Nothing to do here. */
+
+  return(OK);
+}
+
 /*===========================================================================*
  *                             test_read                                    *
  *===========================================================================*/
@@ -1320,7 +1327,7 @@ PRIVATE int test_read(int density)
   int device;
   off_t position;
   iovec_t iovec1;
-  int result;
+  ssize_t result;
 
   f_fp->fl_density = density;
   device = ((density + 1) << DEV_TYPE_SHIFT) + f_drive;
@@ -1329,9 +1336,10 @@ PRIVATE int test_read(int density)
   position = (off_t) f_dp->test << SECTOR_SHIFT;
   iovec1.iov_addr = (vir_bytes) floppy_buf;
   iovec1.iov_size = SECTOR_SIZE;
-  result = f_transfer(SELF, DEV_GATHER_S, cvul64(position), &iovec1, 1);
+  result = f_transfer(device, FALSE /*do_write*/, cvul64(position), SELF,
+       &iovec1, 1, BDEV_NOFLAGS);
 
-  if (iovec1.iov_size != 0) return(EIO);
+  if (result != SECTOR_SIZE) return(EIO);
 
   partition(&f_dtab, f_drive, P_FLOPPY, 0);
   return(OK);
@@ -1340,11 +1348,11 @@ PRIVATE int test_read(int density)
 /*===========================================================================*
  *                             f_geometry                                   *
  *===========================================================================*/
-PRIVATE void f_geometry(struct partition *entry)
+PRIVATE void f_geometry(dev_t minor, struct partition *entry)
 {
+  if (f_prepare(minor) == NULL) return;
+
   entry->cylinders = f_dp->cyls;
   entry->heads = NR_HEADS;
   entry->sectors = f_sectors;
 }
-
-
index 4853818fd46e0df8848bb892ce5a38d769b82306..7697eb3d683eb3c6ca11a7cdee8040b30a61de29 100644 (file)
@@ -1,4 +1,4 @@
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/blockdriver.h>
 #include <minix/drvlib.h>
 
index 870a9049af2bba211bd65b71f1f089ae0cf14d16..81e521848979808500294f41155ae41ac13ac2d5 100644 (file)
@@ -4,7 +4,7 @@
 EXTERN u16_t f_busy;
 EXTERN int motor_status;
 EXTERN unsigned f_drive;
-EXTERN int last_transfer_opcode;
+EXTERN int last_was_write;
 #define BSY_IO      1   /* busy doing I/O */
 
 /* State management helpers. */
@@ -63,8 +63,7 @@ PUBLIC void sef_cb_lu_state_dump(int state)
   sef_lu_dprint("floppy: f_busy = %d\n", f_busy);
   sef_lu_dprint("floppy: motor_status = 0x%02X\n", motor_status);
   sef_lu_dprint("floppy: f_drive = %d\n", f_drive);
-  sef_lu_dprint("floppy: last_transfer_opcode = 0x%02X\n",
-      last_transfer_opcode);
+  sef_lu_dprint("floppy: last_was_write = %d\n", last_was_write);
 
   sef_lu_dprint("floppy: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n",
       SEF_LU_STATE_WORK_FREE, TRUE);
index c48a7c454ba9bcd69d3fe09390b543435c21014e..1a730e2946adb4682aa9b527549bb51f27bc8a55 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  hello
 SRCS=  hello.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+=        ${LIBCHARDRIVER} ${LIBSYS}
+LDADD+=        -lchardriver -lsys
 
 MAN=
 
index d842fa343c77939c8b0c298f4492c3d70d0eb357..21f60b537742a870d7c973dd014fc6da7c5ac619 100644 (file)
@@ -1,5 +1,5 @@
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <minix/ds.h>
@@ -8,14 +8,13 @@
 /*
  * Function prototypes for the hello driver.
  */
-FORWARD _PROTOTYPE( char * hello_name,   (void) );
-FORWARD _PROTOTYPE( int hello_open,      (struct driver *d, message *m) );
-FORWARD _PROTOTYPE( int hello_close,     (struct driver *d, message *m) );
-FORWARD _PROTOTYPE( struct device * hello_prepare, (int device) );
-FORWARD _PROTOTYPE( int hello_transfer,  (int procnr, int opcode,
+FORWARD _PROTOTYPE( int hello_open,      (message *m) );
+FORWARD _PROTOTYPE( int hello_close,     (message *m) );
+FORWARD _PROTOTYPE( struct device * hello_prepare, (dev_t device) );
+FORWARD _PROTOTYPE( int hello_transfer,  (endpoint_t endpt, int opcode,
                                           u64_t position, iovec_t *iov,
-                                          unsigned nr_req) );
-FORWARD _PROTOTYPE( void hello_geometry, (struct partition *entry) );
+                                          unsigned int nr_req,
+                                          endpoint_t user_endpt) );
 
 /* SEF functions and variables. */
 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
@@ -24,21 +23,17 @@ FORWARD _PROTOTYPE( int sef_cb_lu_state_save, (int) );
 FORWARD _PROTOTYPE( int lu_state_restore, (void) );
 
 /* Entry points to the hello driver. */
-PRIVATE struct driver hello_tab =
+PRIVATE struct chardriver hello_tab =
 {
-    hello_name,
     hello_open,
     hello_close,
     nop_ioctl,
     hello_prepare,
     hello_transfer,
     nop_cleanup,
-    hello_geometry,
     nop_alarm,
     nop_cancel,
     nop_select,
-    nop_ioctl,
-    NULL,
     NULL
 };
 
@@ -48,47 +43,38 @@ PRIVATE struct device hello_device;
 /** State variable to count the number of times the device has been opened. */
 PRIVATE int open_counter;
 
-PRIVATE char * hello_name(void)
-{
-    printf("hello_name()\n");
-    return "hello";
-}
-
-PRIVATE int hello_open(d, m)
-    struct driver *d;
-    message *m;
+PRIVATE int hello_open(message *UNUSED(m))
 {
     printf("hello_open(). Called %d time(s).\n", ++open_counter);
     return OK;
 }
 
-PRIVATE int hello_close(d, m)
-    struct driver *d;
-    message *m;
+PRIVATE int hello_close(message *UNUSED(m))
 {
     printf("hello_close()\n");
     return OK;
 }
 
-PRIVATE struct device * hello_prepare(dev)
-    int dev;
+PRIVATE struct device * hello_prepare(dev_t UNUSED(dev))
 {
     hello_device.dv_base = make64(0, 0);
     hello_device.dv_size = make64(strlen(HELLO_MESSAGE), 0);
     return &hello_device;
 }
 
-PRIVATE int hello_transfer(proc_nr, opcode, position, iov, nr_req)
-    int proc_nr;
-    int opcode;
-    u64_t position;
-    iovec_t *iov;
-    unsigned nr_req;
+PRIVATE int hello_transfer(endpoint_t endpt, int opcode, u64_t position,
+    iovec_t *iov, unsigned nr_req, endpoint_t UNUSED(user_endpt))
 {
     int bytes, ret;
 
     printf("hello_transfer()\n");
 
+    if (nr_req != 1)
+    {
+        /* This should never trigger for character drivers at the moment. */
+        printf("HELLO: vectored transfer request, using first element only\n");
+    }
+
     bytes = strlen(HELLO_MESSAGE) - ex64lo(position) < iov->iov_size ?
             strlen(HELLO_MESSAGE) - ex64lo(position) : iov->iov_size;
 
@@ -99,7 +85,7 @@ PRIVATE int hello_transfer(proc_nr, opcode, position, iov, nr_req)
     switch (opcode)
     {
         case DEV_GATHER_S:
-            ret = sys_safecopyto(proc_nr, iov->iov_addr, 0,
+            ret = sys_safecopyto(endpt, (cp_grant_id_t) iov->iov_addr, 0,
                                 (vir_bytes) (HELLO_MESSAGE + ex64lo(position)),
                                  bytes, D);
             iov->iov_size -= bytes;
@@ -111,16 +97,7 @@ PRIVATE int hello_transfer(proc_nr, opcode, position, iov, nr_req)
     return ret;
 }
 
-PRIVATE void hello_geometry(entry)
-    struct partition *entry;
-{
-    printf("hello_geometry()\n");
-    entry->cylinders = 0;
-    entry->heads     = 0;
-    entry->sectors   = 0;
-}
-
-PRIVATE int sef_cb_lu_state_save(int state) {
+PRIVATE int sef_cb_lu_state_save(int UNUSED(state)) {
 /* Save the state. */
     ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE);
 
@@ -161,7 +138,7 @@ PRIVATE void sef_local_startup()
     sef_startup();
 }
 
-PRIVATE int sef_cb_init(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init(int type, sef_init_info_t *UNUSED(info))
 {
 /* Initialize the hello driver. */
     int do_announce_driver = TRUE;
@@ -187,14 +164,14 @@ PRIVATE int sef_cb_init(int type, sef_init_info_t *info)
 
     /* Announce we are up when necessary. */
     if (do_announce_driver) {
-        driver_announce();
+        chardriver_announce();
     }
 
     /* Initialization completed successfully. */
     return OK;
 }
 
-PUBLIC int main(int argc, char **argv)
+PUBLIC int main(void)
 {
     /*
      * Perform initialization.
@@ -204,7 +181,7 @@ PUBLIC int main(int argc, char **argv)
     /*
      * Run the main loop.
      */
-    driver_task(&hello_tab, DRIVER_STD);
+    chardriver_task(&hello_tab, CHARDRIVER_SYNC);
     return OK;
 }
 
index bab063bcf7338dca17beaab6b27eaf466546d006..7e27ba91e6f84b9ed0cbae2b9b8d9261a2c0fcc3 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  log
 SRCS=  log.c diag.c liveupdate.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+=        ${LIBCHARDRIVER} ${LIBSYS}
+LDADD+=        -lchardriver -lsys
 
 MAN=
 
index 2882c9ee787a2bf5615005101a8808f57dba1f95..7d08dc4054974024e65c9104aa39e16ee1bf19bb 100644 (file)
@@ -22,36 +22,31 @@ PUBLIC struct logdevice logdevices[NR_DEVS];
 PRIVATE struct device log_geom[NR_DEVS];       /* base and size of devices */
 PRIVATE int log_device = -1;                   /* current device */
 
-FORWARD _PROTOTYPE( char *log_name, (void) );
-FORWARD _PROTOTYPE( struct device *log_prepare, (int device) );
-FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, u64_t position,
-                       iovec_t *iov, unsigned nr_req) );
-FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) );
-FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, cp_grant_id_t grant, size_t) );
+FORWARD _PROTOTYPE( struct device *log_prepare, (dev_t device) );
+FORWARD _PROTOTYPE( int log_transfer, (endpoint_t endpt, int opcode,
+       u64_t position, iovec_t *iov, unsigned int nr_req,
+       endpoint_t user_endpt) );
+FORWARD _PROTOTYPE( int log_do_open, (message *m_ptr) );
+FORWARD _PROTOTYPE( int log_cancel, (message *m_ptr) );
+FORWARD _PROTOTYPE( int log_select, (message *m_ptr) );
+FORWARD _PROTOTYPE( int log_other, (message *m_ptr) );
+FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count,
+       endpoint_t endpt, cp_grant_id_t grant, size_t) );
 
 /* Entry points to this driver. */
-PRIVATE struct driver log_dtab = {
-  log_name,    /* current device's name */
+PRIVATE struct chardriver log_dtab = {
   log_do_open, /* open or mount */
   do_nop,      /* nothing on a close */
   nop_ioctl,   /* ioctl nop */
   log_prepare, /* prepare for I/O on a given minor device */
   log_transfer,        /* do the I/O */
   nop_cleanup, /* no need to clean up */
-  log_geometry,        /* geometry */
-  nop_alarm,   /* no alarm */
+  nop_alarm,   /* no alarm */
   log_cancel,  /* CANCEL request */
   log_select,  /* DEV_SELECT request */
-  log_other,   /* Unrecognized messages */
-  NULL         /* HW int */
+  log_other    /* Unrecognized messages */
 };
 
-extern int device_endpt;
-
 /* SEF functions and variables. */
 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
 FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
@@ -69,7 +64,7 @@ PUBLIC int main(void)
   sef_local_startup();
 
   /* Call the generic receive loop. */
-  driver_task(&log_dtab, DRIVER_ASYN);
+  chardriver_task(&log_dtab, CHARDRIVER_ASYNC);
 
   return(OK);
 }
@@ -99,7 +94,7 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the log driver. */
   int i;
@@ -131,26 +126,15 @@ PRIVATE void sef_cb_signal_handler(int signo)
   do_new_kmess();
 }
 
-/*===========================================================================*
- *                              log_name                                    *
- *===========================================================================*/
-PRIVATE char *log_name()
-{
-/* Return a name for the current device. */
-  static char name[] = "log";
-  return name;  
-}
-
 /*===========================================================================*
  *                             log_prepare                                  *
  *===========================================================================*/
-PRIVATE struct device *log_prepare(device)
-int device;
+PRIVATE struct device *log_prepare(dev_t device)
 {
 /* Prepare for I/O on a device: check if the minor device number is ok. */
 
-  if (device < 0 || device >= NR_DEVS) return(NULL);
-  log_device = device;
+  if (device >= NR_DEVS) return(NULL);
+  log_device = (int) device;
 
   return(&log_geom[device]);
 }
@@ -159,7 +143,7 @@ int device;
  *                             subwrite                                     *
  *===========================================================================*/
 PRIVATE int
-subwrite(struct logdevice *log, int count, int proc_nr,
+subwrite(struct logdevice *log, int count, endpoint_t endpt,
        cp_grant_id_t grant, size_t offset, char *localbuf)
 {
        int d, r;
@@ -174,7 +158,7 @@ subwrite(struct logdevice *log, int count, int proc_nr,
                memcpy(buf, localbuf, count);
        }
        else {
-               if((r=sys_safecopyfrom(proc_nr, grant, offset,
+               if((r=sys_safecopyfrom(endpt, grant, offset,
                        (vir_bytes)buf, count, D)) != OK)
                        return r;
        }
@@ -267,7 +251,7 @@ log_append(char *buf, int count)
  *                             subread                                      *
  *===========================================================================*/
 PRIVATE int
-subread(struct logdevice *log, int count, int proc_nr,
+subread(struct logdevice *log, int count, endpoint_t endpt,
        cp_grant_id_t grant, size_t offset)
 {
        char *buf;
@@ -278,7 +262,7 @@ subread(struct logdevice *log, int count, int proc_nr,
                count = LOG_SIZE - log->log_read;
 
        buf = log->log_buffer + log->log_read;
-       if((r=sys_safecopyto(proc_nr, grant, offset,
+       if((r=sys_safecopyto(endpt, grant, offset,
                (vir_bytes)buf, count, D)) != OK)
                return r;
 
@@ -291,12 +275,14 @@ subread(struct logdevice *log, int count, int proc_nr,
 /*===========================================================================*
  *                             log_transfer                                 *
  *===========================================================================*/
-PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req)
-int proc_nr;                   /* process doing the request */
-int opcode;                    /* DEV_GATHER_S or DEV_SCATTER_S */
-u64_t position;                        /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE int log_transfer(
+  endpoint_t endpt,            /* endpoint of grant owner */
+  int opcode,                  /* DEV_GATHER_S or DEV_SCATTER_S */
+  u64_t UNUSED(position),      /* offset on device to read or write */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  endpoint_t user_endpt                /* endpoint of user process */
+)
 {
 /* Read or write one the driver's minor devices. */
   int count;
@@ -331,27 +317,25 @@ unsigned nr_req;          /* length of request vector */
                        if(accumulated_read)
                                return OK;
                        /* No data available; let caller block. */
-                       log->log_source = proc_nr;
+                       log->log_source = endpt;
                        log->log_iosize = count;
                        log->log_user_grant = grant;
                        log->log_user_offset = 0;
                        log->log_revive_alerted = 0;
-
-                       /* device_endpt is a global in drivers library. */
-                       log->log_proc_nr = device_endpt;
+                       log->log_proc_nr = user_endpt;
 #if LOG_DEBUG
                        printf("blocked %d (%d)\n", 
                                log->log_source, log->log_proc_nr);
 #endif
                        return(EDONTREPLY);
                }
-               count = subread(log, count, proc_nr, grant, vir_offset);
+               count = subread(log, count, endpt, grant, vir_offset);
                if(count < 0) {
                        return count;
                }
                accumulated_read += count;
            } else {
-               count = subwrite(log, count, proc_nr, grant, vir_offset, NULL);
+               count = subwrite(log, count, endpt, grant, vir_offset, NULL);
                if(count < 0)
                        return count;
            }
@@ -371,33 +355,16 @@ unsigned nr_req;          /* length of request vector */
 /*============================================================================*
  *                             log_do_open                                   *
  *============================================================================*/
-PRIVATE int log_do_open(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int log_do_open(message *m_ptr)
 {
   if (log_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
   return(OK);
 }
 
-/*============================================================================*
- *                             log_geometry                                  *
- *============================================================================*/
-PRIVATE void log_geometry(entry)
-struct partition *entry;
-{
-  /* take a page from the fake memory device geometry */
-  entry->heads = 64;
-  entry->sectors = 32;
-  entry->cylinders = div64u(log_geom[log_device].dv_size, SECTOR_SIZE) /
-       (entry->heads * entry->sectors);
-}
-
 /*============================================================================*
  *                             log_cancel                                    *
  *============================================================================*/
-PRIVATE int log_cancel(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int log_cancel(message *m_ptr)
 {
   int d;
   d = m_ptr->TTY_LINE;
@@ -411,9 +378,7 @@ message *m_ptr;
 /*============================================================================*
  *                             log_other                                     *
  *============================================================================*/
-PRIVATE int log_other(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int log_other(message *m_ptr)
 {
        int r;
 
@@ -440,9 +405,7 @@ message *m_ptr;
 /*============================================================================*
  *                             log_select                                    *
  *============================================================================*/
-PRIVATE int log_select(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int log_select(message *m_ptr)
 {
   int d, ready_ops = 0, ops = 0;
   d = m_ptr->TTY_LINE;
@@ -455,15 +418,15 @@ message *m_ptr;
 
   ops = m_ptr->USER_ENDPT & (SEL_RD|SEL_WR|SEL_ERR);
 
-       /* Read blocks when there is no log. */
+  /* Read blocks when there is no log. */
   if((m_ptr->USER_ENDPT & SEL_RD) && logdevices[d].log_size > 0) {
 #if LOG_DEBUG
        printf("log can read; size %d\n", logdevices[d].log_size);
 #endif
        ready_ops |= SEL_RD; /* writes never block */
- }
 }
 
-       /* Write never blocks. */
+  /* Write never blocks. */
   if(m_ptr->USER_ENDPT & SEL_WR) ready_ops |= SEL_WR;
 
        /* Enable select calback if no operations were
index 11187fc56a61e2b5688b43e436d2a21109d54946..c1a5e4cbfc120964b9f0c95a58318c00494b9ee7 100644 (file)
@@ -1,6 +1,6 @@
 /* Includes. */
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 #include <minix/type.h>
 #include <minix/const.h>
 #include <minix/com.h>
index bf853cee743e41f3bf252fd78c3b6533ce46d029..248848883fe393535585fe3dd5e6453c9342431c 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  memory
 SRCS=  memory.c imgrd.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+=        ${LIBBLOCKDRIVER} ${LIBCHARDRIVER} ${LIBSYS}
+LDADD+=        -lblockdriver -lchardriver -lsys
 
 MAN=
 
index 4863ce2c4038dc6ec3cd0856ae915c7be3728cbe..f6c39beed182f04aeddc25303492ad8a3edd69ef 100644 (file)
@@ -16,7 +16,8 @@
  */
 
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
+#include <minix/blockdriver.h>
 #include <sys/ioc_memory.h>
 #include <minix/ds.h>
 #include <minix/vm.h>
 
 PRIVATE struct device m_geom[NR_DEVS];  /* base and size of each device */
 PRIVATE vir_bytes m_vaddrs[NR_DEVS];
-PRIVATE int m_device;                  /* current device */
-PRIVATE struct kinfo kinfo;            /* kernel information */ 
-
-extern int errno;                      /* error number for PM calls */
+PRIVATE dev_t m_device;                        /* current minor character device */
 
 PRIVATE int openct[NR_DEVS];
 
-FORWARD _PROTOTYPE( char *m_name, (void)                               );
-FORWARD _PROTOTYPE( struct device *m_prepare, (int device)             );
-FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode,
-                       u64_t position, iovec_t *iov, unsigned nr_req)  );
-FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr)         );
-FORWARD _PROTOTYPE( int m_do_close, (struct driver *dp, message *m_ptr)        );
-FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr)   );
-FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry)                 );
-
-/* Entry points to this driver. */
-PRIVATE struct driver m_dtab = {
-  m_name,      /* current device's name */
+FORWARD _PROTOTYPE( struct device *m_prepare, (dev_t device)           );
+FORWARD _PROTOTYPE( int m_transfer, (endpoint_t endpt, int opcode,
+       u64_t position, iovec_t *iov, unsigned int nr_req,
+       endpoint_t user_endpt)                                          );
+FORWARD _PROTOTYPE( int m_do_open, (message *m_ptr)                    );
+FORWARD _PROTOTYPE( int m_do_close, (message *m_ptr)                   );
+
+FORWARD _PROTOTYPE( struct device *m_block_part, (dev_t minor)         );
+FORWARD _PROTOTYPE( int m_block_transfer, (dev_t minor, int do_write,
+       u64_t position, endpoint_t endpt, iovec_t *iov,
+       unsigned int nr_req, int flags)                                 );
+FORWARD _PROTOTYPE( int m_block_open, (dev_t minor, int access)                );
+FORWARD _PROTOTYPE( int m_block_close, (dev_t minor)                   );
+FORWARD _PROTOTYPE( int m_block_ioctl, (dev_t minor,
+       unsigned int request, endpoint_t endpt, cp_grant_id_t grant)    );
+
+/* Entry points to the CHARACTER part of this driver. */
+PRIVATE struct chardriver m_cdtab = {
   m_do_open,   /* open or mount */
   m_do_close,  /* nothing on a close */
-  m_ioctl,     /* specify ram disk geometry */
+  nop_ioctl,   /* no I/O control */
   m_prepare,   /* prepare for I/O on a given minor device */
   m_transfer,  /* do the I/O */
   nop_cleanup, /* no need to clean up */
-  m_geometry,  /* memory device "geometry" */
-  nop_alarm,
-  nop_cancel,
-  nop_select,
-  NULL,
-  NULL
+  nop_alarm,   /* no alarms */
+  nop_cancel,  /* no blocking operations */
+  nop_select,  /* select not supported */
+  NULL         /* other messages not supported */
+};
+
+/* Entry points to the BLOCK part of this driver. */
+PRIVATE struct blockdriver m_bdtab = {
+  m_block_open,                /* open or mount */
+  m_block_close,       /* nothing on a close */
+  m_block_transfer,    /* do the I/O */
+  m_block_ioctl,       /* ram disk I/O control */
+  NULL,                        /* no need to clean up */
+  m_block_part,                /* return partition information */
+  NULL,                        /* no geometry */
+  NULL,                        /* no interrupt processing */
+  NULL,                        /* no alarm processing */
+  NULL,                        /* no processing of other messages */
+  NULL                 /* no threading support */
 };
 
 /* Buffer for the /dev/zero null byte feed. */
-#define ZERO_BUF_SIZE                  1024
+#define ZERO_BUF_SIZE                  1024
 PRIVATE char dev_zero[ZERO_BUF_SIZE];
 
 #define click_to_round_k(n) \
@@ -88,11 +105,23 @@ FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
  *===========================================================================*/
 PUBLIC int main(void)
 {
+  message msg;
+  int r, ipc_status;
+
   /* SEF local startup. */
   sef_local_startup();
 
-  /* Call the generic receive loop. */
-  driver_task(&m_dtab, DRIVER_STD);
+  /* The receive loop. */
+  for (;;) {
+       if ((r = driver_receive(ANY, &msg, &ipc_status)) != OK)
+               panic("memory: driver_receive failed (%d)", r);
+
+       if (IS_BDEV_RQ(msg.m_type))
+               blockdriver_process(&m_bdtab, &msg, ipc_status);
+       else
+               chardriver_process(&m_cdtab, CHARDRIVER_SYNC, &msg,
+                       ipc_status);
+  }
 
   return(OK);
 }
@@ -118,17 +147,18 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the memory driver. */
-  int i, s;
+  int i;
+#if 0
+  struct kinfo kinfo;          /* kernel information */
+  int s;
 
-  /* Initialize all minor devices one by one. */
   if (OK != (s=sys_getkinfo(&kinfo))) {
       panic("Couldn't get kernel information: %d", s);
   }
 
-#if 0
   /* Map in kernel memory for /dev/kmem. */
   m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
   m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
@@ -161,23 +191,31 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
 }
 
 /*===========================================================================*
- *                              m_name                                      *
+ *                             m_is_block                                   *
  *===========================================================================*/
-PRIVATE char *m_name()
+PRIVATE int m_is_block(dev_t minor)
 {
-/* Return a name for the current device. */
-  static char name[] = "memory";
-  return name;  
+/* Return TRUE iff the given minor device number is for a block device. */
+
+  switch (minor) {
+  case MEM_DEV:
+  case KMEM_DEV:
+  case NULL_DEV:
+  case ZERO_DEV:
+       return FALSE;
+
+  default:
+       return TRUE;
+  }
 }
 
 /*===========================================================================*
  *                             m_prepare                                    *
  *===========================================================================*/
-PRIVATE struct device *m_prepare(device)
-int device;
+PRIVATE struct device *m_prepare(dev_t device)
 {
 /* Prepare for I/O on a device: check if the minor device number is ok. */
-  if (device < 0 || device >= NR_DEVS) return(NULL);
+  if (device >= NR_DEVS || m_is_block(device)) return(NULL);
   m_device = device;
 
   return(&m_geom[device]);
@@ -186,20 +224,23 @@ int device;
 /*===========================================================================*
  *                             m_transfer                                   *
  *===========================================================================*/
-PRIVATE int m_transfer(proc_nr, opcode, pos64, iov, nr_req)
-int proc_nr;                   /* process doing the request */
-int opcode;                    /* DEV_GATHER_S or DEV_SCATTER_S */
-u64_t pos64;                   /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE int m_transfer(
+  endpoint_t endpt,            /* endpoint of grant owner */
+  int opcode,                  /* DEV_GATHER_S or DEV_SCATTER_S */
+  u64_t pos64,                 /* offset on device to read or write */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  endpoint_t UNUSED(user_endpt)        /* endpoint of user process */
+)
 {
-/* Read or write one the driver's minor devices. */
+/* Read or write one the driver's character devices. */
   unsigned count, left, chunk;
-  vir_bytes user_vir, vir_offset = 0;
+  vir_bytes vir_offset = 0;
   struct device *dv;
   unsigned long dv_size;
   int s, r;
   off_t position;
+  cp_grant_id_t grant;
   vir_bytes dev_vaddr;
 
   /* ZERO_DEV and NULL_DEV are infinite in size. */
@@ -216,7 +257,7 @@ unsigned nr_req;            /* length of request vector */
 
        /* How much to transfer and where to / from. */
        count = iov->iov_size;
-       user_vir = iov->iov_addr;
+       grant = (cp_grant_id_t) iov->iov_addr;
 
        switch (m_device) {
 
@@ -225,27 +266,21 @@ unsigned nr_req;          /* length of request vector */
            if (opcode == DEV_GATHER_S) return(OK);     /* always at EOF */
            break;
 
-       /* Virtual copying. For RAM disks, kernel memory and internal FS. */
+       /* Virtual copying. For kernel memory. */
        default:
        case KMEM_DEV:
-       case RAM_DEV_OLD:
-       case IMGRD_DEV:
-           /* Bogus number. */
-           if(m_device < 0 || m_device >= NR_DEVS) {
-                   return(EINVAL);
-           }
-           if(!dev_vaddr || dev_vaddr == (vir_bytes) MAP_FAILED) {
+           if(!dev_vaddr || dev_vaddr == (vir_bytes) MAP_FAILED) {
                printf("MEM: dev %d not initialized\n", m_device);
                return EIO;
            }
-           if (position >= dv_size) return(OK);        /* check for EOF */
+           if (position >= dv_size) return(OK);        /* check for EOF */
            if (position + count > dv_size) count = dv_size - position;
            if (opcode == DEV_GATHER_S) {       /* copy actual data */
-               r=sys_safecopyto(proc_nr, user_vir, vir_offset,
-                 dev_vaddr + position, count, D);
+               r=sys_safecopyto(endpt, grant, vir_offset,
+                 dev_vaddr + position, count, D);
            } else {
-               r=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
-                 dev_vaddr + position, count, D);
+               r=sys_safecopyfrom(endpt, grant, vir_offset,
+                 dev_vaddr + position, count, D);
            }
            if(r != OK) {
               panic("I/O copy failed: %d", r);
@@ -263,10 +298,10 @@ unsigned nr_req;          /* length of request vector */
            static char *vaddr;
            int r;
            u32_t subcount;
-           phys_bytes mem_phys;
+           phys_bytes mem_phys;
 
            if (position >= dv_size)
-               return(OK);     /* check for EOF */
+               return(OK);     /* check for EOF */
            if (position + count > dv_size)
                count = dv_size - position;
            mem_phys = position;
@@ -280,7 +315,7 @@ unsigned nr_req;            /* length of request vector */
            if(!any_mapped || pagestart_mapped != pagestart) {
             if(any_mapped) {
                if(vm_unmap_phys(SELF, vaddr, I386_PAGE_SIZE) != OK)
-                       panic("vm_unmap_phys failed");
+                       panic("vm_unmap_phys failed");
                any_mapped = 0;
             }
             vaddr = vm_map_phys(SELF, (void *) pagestart, I386_PAGE_SIZE);
@@ -302,10 +337,10 @@ unsigned nr_req;          /* length of request vector */
                subcount = count;
 
            if (opcode == DEV_GATHER_S) {                       /* copy data */
-                  s=sys_safecopyto(proc_nr, user_vir,
+                  s=sys_safecopyto(endpt, grant,
                       vir_offset, (vir_bytes) vaddr+page_off, subcount, D);
            } else {
-                  s=sys_safecopyfrom(proc_nr, user_vir,
+                  s=sys_safecopyfrom(endpt, grant,
                       vir_offset, (vir_bytes) vaddr+page_off, subcount, D);
            }
            if(s != OK)
@@ -319,15 +354,15 @@ unsigned nr_req;          /* length of request vector */
            if (opcode == DEV_GATHER_S) {
                size_t suboffset = 0;
                left = count;
-               while (left > 0) {
-                   chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
-                    s=sys_safecopyto(proc_nr, user_vir,
+               while (left > 0) {
+                   chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
+                    s=sys_safecopyto(endpt, grant,
                       vir_offset+suboffset, (vir_bytes) dev_zero, chunk, D);
                    if(s != OK)
-                       return s;
-                   left -= chunk;
-                   suboffset += chunk;
-               }
+                       return s;
+                   left -= chunk;
+                   suboffset += chunk;
+               }
            }
            break;
 
@@ -336,7 +371,7 @@ unsigned nr_req;            /* length of request vector */
        /* Book the number of bytes transferred. */
        position += count;
        vir_offset += count;
-       if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; }
+       if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; }
 
   }
   return(OK);
@@ -345,10 +380,9 @@ unsigned nr_req;           /* length of request vector */
 /*===========================================================================*
  *                             m_do_open                                    *
  *===========================================================================*/
-PRIVATE int m_do_open(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int m_do_open(message *m_ptr)
 {
+/* Open a memory character device. */
   int r;
 
 /* Check device number on open. */
@@ -364,10 +398,6 @@ message *m_ptr;
        }
   }
 
-  if(m_device < 0 || m_device >= NR_DEVS) {
-      panic("wrong m_device: %d", m_device);
-  }
-
   openct[m_device]++;
 
   return(OK);
@@ -376,24 +406,128 @@ message *m_ptr;
 /*===========================================================================*
  *                             m_do_close                                   *
  *===========================================================================*/
-PRIVATE int m_do_close(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
+PRIVATE int m_do_close(message *m_ptr)
 {
+/* Close a memory character device. */
   if (m_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
 
-  if(m_device < 0 || m_device >= NR_DEVS) {
-      panic("wrong m_device: %d", m_device);
-  }
-
   if(openct[m_device] < 1) {
-      panic("closed too often");
+       printf("MEMORY: closing unopened device %d\n", m_device);
+       return(EINVAL);
   }
   openct[m_device]--;
 
+  return(OK);
+}
+
+/*===========================================================================*
+ *                             m_block_part                                 *
+ *===========================================================================*/
+PRIVATE struct device *m_block_part(dev_t minor)
+{
+/* Prepare for I/O on a device: check if the minor device number is ok. */
+  if (minor >= NR_DEVS || !m_is_block(minor)) return(NULL);
+
+  return(&m_geom[minor]);
+}
+
+/*===========================================================================*
+ *                             m_block_transfer                             *
+ *===========================================================================*/
+PRIVATE int m_block_transfer(
+  dev_t minor,                 /* minor device number */
+  int do_write,                        /* read or write? */
+  u64_t pos64,                 /* offset on device to read or write */
+  endpoint_t endpt,            /* process doing the request */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  int UNUSED(flags)            /* transfer flags */
+)
+{
+/* Read or write one the driver's block devices. */
+  unsigned count;
+  vir_bytes vir_offset = 0;
+  struct device *dv;
+  unsigned long dv_size;
+  int r;
+  off_t position;
+  vir_bytes dev_vaddr;
+  cp_grant_id_t grant;
+  ssize_t total = 0;
+
+  /* Get minor device information. */
+  if ((dv = m_block_part(minor)) == NULL) return(ENXIO);
+  dv_size = cv64ul(dv->dv_size);
+  dev_vaddr = m_vaddrs[minor];
+
+  if (ex64hi(pos64) != 0)
+       return OK;      /* Beyond EOF */
+  position= cv64ul(pos64);
+
+  while (nr_req > 0) {
+
+       /* How much to transfer and where to / from. */
+       count = iov->iov_size;
+       grant = (cp_grant_id_t) iov->iov_addr;
+
+       /* Virtual copying. For RAM disks and internal FS. */
+       if(!dev_vaddr || dev_vaddr == (vir_bytes) MAP_FAILED) {
+               printf("MEM: dev %d not initialized\n", minor);
+               return EIO;
+       }
+       if (position >= dv_size) return(total); /* check for EOF */
+       if (position + count > dv_size) count = dv_size - position;
+       if (!do_write) {        /* copy actual data */
+               r=sys_safecopyto(endpt, grant, vir_offset,
+                 dev_vaddr + position, count, D);
+       } else {
+               r=sys_safecopyfrom(endpt, grant, vir_offset,
+                 dev_vaddr + position, count, D);
+       }
+       if(r != OK) {
+               panic("I/O copy failed: %d", r);
+       }
+
+       /* Book the number of bytes transferred. */
+       position += count;
+       vir_offset += count;
+       total += count;
+       if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; }
+
+  }
+  return(total);
+}
+
+/*===========================================================================*
+ *                             m_block_open                                 *
+ *===========================================================================*/
+PRIVATE int m_block_open(dev_t minor, int UNUSED(access))
+{
+/* Open a memory block device. */
+  if (m_block_part(minor) == NULL) return(ENXIO);
+
+  openct[minor]++;
+
+  return(OK);
+}
+
+/*===========================================================================*
+ *                             m_block_close                                *
+ *===========================================================================*/
+PRIVATE int m_block_close(dev_t minor)
+{
+/* Close a memory block device. */
+  if (m_block_part(minor) == NULL) return(ENXIO);
+
+  if(openct[minor] < 1) {
+       printf("MEMORY: closing unopened device %d\n", minor);
+       return(EINVAL);
+  }
+  openct[minor]--;
+
   /* Special case: free initial ramdisk after it's been unmounted once. */
-  if(m_device == IMGRD_DEV && openct[m_device] == 0 && m_vaddrs[IMGRD_DEV]) {
-       vir_bytes vaddr, vlen;
+  if(minor == IMGRD_DEV && openct[minor] == 0 && m_vaddrs[IMGRD_DEV]) {
+       vir_bytes vaddr, vlen;
        vaddr = m_vaddrs[IMGRD_DEV];
        vlen = imgrd_size;
        /* Align `inwards' so as to not unmap more than the initial
@@ -417,91 +551,70 @@ message *m_ptr;
 }
 
 /*===========================================================================*
- *                             m_ioctl                                      *
+ *                             m_block_ioctl                                *
  *===========================================================================*/
-PRIVATE int m_ioctl(dp, m_ptr)
-struct driver *dp;                     /* pointer to driver structure */
-message *m_ptr;                                /* pointer to control message */
+PRIVATE int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
+       cp_grant_id_t grant)
 {
-/* I/O controls for the memory driver. Currently there is one I/O control:
+/* I/O controls for the block devices of the memory driver. Currently there is
+ * one I/O control specific to the memory driver:
  * - MIOCRAMSIZE: to set the size of the RAM disk.
  */
   struct device *dv;
+  u32_t ramdev_size;
+  int s;
+  void *mem;
+
+  if (request != MIOCRAMSIZE)
+       return EINVAL;
+
+  /* Someone wants to create a new RAM disk with the given size.
+   * A ramdisk can be created only once, and only on RAM disk device.
+   */
+  if ((dv = m_block_part(minor)) == NULL) return ENXIO;
+  if((minor < RAM_DEV_FIRST || minor > RAM_DEV_LAST) && minor != RAM_DEV_OLD) {
+       printf("MEM: MIOCRAMSIZE: %d not a ramdisk\n", minor);
+       return EINVAL;
+  }
 
-  switch (m_ptr->REQUEST) {
-    case MIOCRAMSIZE: {
-       /* Someone wants to create a new RAM disk with the given size. */
-       u32_t ramdev_size;
-       int s, dev;
-       void *mem;
-
-       /* A ramdisk can be created only once, and only on RAM disk device. */
-       dev = m_ptr->DEVICE;
-       if(dev < 0 || dev >= NR_DEVS) {
-               printf("MEM: MIOCRAMSIZE: %d not a valid device\n", dev);
-       }
-       if((dev < RAM_DEV_FIRST || dev > RAM_DEV_LAST) && dev != RAM_DEV_OLD) {
-               printf("MEM: MIOCRAMSIZE: %d not a ramdisk\n", dev);
-       }
-        if ((dv = m_prepare(dev)) == NULL) return(ENXIO);
-
-       /* Get request structure */
-          s= sys_safecopyfrom(m_ptr->m_source, (vir_bytes)m_ptr->IO_GRANT,
-               0, (vir_bytes)&ramdev_size, sizeof(ramdev_size), D);
-       if (s != OK)
-               return s;
-       if(m_vaddrs[dev] && !cmp64(dv->dv_size, cvul64(ramdev_size))) {
-               return(OK);
-       }
-       /* openct is 1 for the ioctl(). */
-       if(openct[dev] != 1) {
-               printf("MEM: MIOCRAMSIZE: %d in use (count %d)\n",
-                       dev, openct[dev]);
-               return(EBUSY);
-       }
-       if(m_vaddrs[dev]) {
-               u32_t size;
-               if(ex64hi(dv->dv_size)) {
-                       panic("huge old ramdisk");
-               }
-               size = ex64lo(dv->dv_size);
-               minix_munmap((void *) m_vaddrs[dev], size);
-               m_vaddrs[dev] = (vir_bytes) NULL;
+  /* Get request structure */
+  s= sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&ramdev_size,
+       sizeof(ramdev_size), D);
+  if (s != OK)
+       return s;
+  if(m_vaddrs[minor] && !cmp64(dv->dv_size, cvul64(ramdev_size))) {
+       return(OK);
+  }
+  /* openct is 1 for the ioctl(). */
+  if(openct[minor] != 1) {
+       printf("MEM: MIOCRAMSIZE: %d in use (count %d)\n",
+               minor, openct[minor]);
+       return(EBUSY);
+  }
+  if(m_vaddrs[minor]) {
+       u32_t size;
+       if(ex64hi(dv->dv_size)) {
+               panic("huge old ramdisk");
        }
+       size = ex64lo(dv->dv_size);
+       minix_munmap((void *) m_vaddrs[minor], size);
+       m_vaddrs[minor] = (vir_bytes) NULL;
+  }
 
 #if DEBUG
-       printf("MEM:%d: allocating ramdisk of size 0x%x\n", dev, ramdev_size);
+  printf("MEM:%d: allocating ramdisk of size 0x%x\n", minor, ramdev_size);
 #endif
 
-       /* Try to allocate a piece of memory for the RAM disk. */
-       if((mem = minix_mmap(NULL, ramdev_size, PROT_READ|PROT_WRITE,
-         MAP_PREALLOC|MAP_ANON, -1, 0)) == MAP_FAILED) {
-           printf("MEM: failed to get memory for ramdisk\n");
-            return(ENOMEM);
-        }
-
-       m_vaddrs[dev] = (vir_bytes) mem;
+  /* Try to allocate a piece of memory for the RAM disk. */
+  if((mem = minix_mmap(NULL, ramdev_size, PROT_READ|PROT_WRITE,
+               MAP_PREALLOC|MAP_ANON, -1, 0)) == MAP_FAILED) {
+       printf("MEM: failed to get memory for ramdisk\n");
+       return(ENOMEM);
+  }
 
-       dv->dv_size = cvul64(ramdev_size);
+  m_vaddrs[minor] = (vir_bytes) mem;
 
-       break;
-    }
+  dv->dv_size = cvul64(ramdev_size);
 
-    default:
-       return(do_diocntl(&m_dtab, m_ptr));
-  }
   return(OK);
 }
-
-/*===========================================================================*
- *                             m_geometry                                   *
- *===========================================================================*/
-PRIVATE void m_geometry(entry)
-struct partition *entry;
-{
-  /* Memory devices don't have a geometry, but the outside world insists. */
-  entry->cylinders = div64u(m_geom[m_device].dv_size, SECTOR_SIZE) / (64 * 32);
-  entry->heads = 64;
-  entry->sectors = 32;
-}
-
index 2616cb20c03b645db0c64c9bb814fc58fd16b8b9..5b4e30396409ceef6b37ce0bc38a56fdc52622bb 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  pci
 SRCS=  main.c pci.c pci_table.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
-LDADD+=        -ldriver -lsys -ltimers
+DPADD+=        ${LIBSYS} ${LIBTIMERS}
+LDADD+=        -lsys -ltimers
 
 MAN=
 
index 762664a5dfb63999ec2a99918bbdab45776855ca..beec640fae938137a0b672a2078599fb777ace7d 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  printer
 SRCS=  printer.c liveupdate.c
 
-DPADD+= ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
+LDADD+=        -lchardriver -lsys
 
 MAN=
 
index 1fb3ab2f184e26acbc62cc59a777cb7142df1977..bb1374885ba13393bd76e8f50d08dbd91e788081 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <minix/endpoint.h>
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 
 /* Control bits (in port_base + 2).  "+" means positive logic and "-" means
  * negative logic.  Most of the signals are negative logic on the pins but
@@ -122,7 +122,7 @@ PUBLIC int is_status_msg_expected = FALSE;
 /*===========================================================================*
  *                             printer_task                                 *
  *===========================================================================*/
-PUBLIC int main(int argc, char *argv[])
+PUBLIC int main(void)
 {
 /* Main routine of the printer task. */
   message pr_mess;             /* buffer for all incoming messages */
@@ -190,11 +190,11 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the printer driver. */
   /* Announce we are up! */
-  driver_announce();
+  chardriver_announce();
 
   return OK;
 }
index 9c8e14e25d5410553244f6259fb99383638a3d98..eb329d3394adf5aca782df6ba9117b8589730e31 100644 (file)
@@ -4,8 +4,8 @@ SRCS=   main.c random.c rijndael_api.c rijndael_alg.c
 
 .PATH: ${.CURDIR}/aes
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBMINIXUTIL}
-LDADD+=        -ldriver -lsys -lminixutil
+DPADD+=        ${LIBCHARDRIVER} ${LIBSYS} ${LIBMINIXUTIL}
+LDADD+=        -lchardriver -lsys -lminixutil
 
 MAN=
 
index f6c59a026de915441aba45cf1fff9f63eac585e7..492d19ff9c7353066de8fd6e6789b10d0beae0d8 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <minix/drivers.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 #include <minix/type.h>
 
 #include "assert.h"
 #define KRANDOM_PERIOD    1            /* ticks between krandom calls */
 
 PRIVATE struct device m_geom[NR_DEVS];  /* base and size of each device */
-PRIVATE int m_device;                  /* current device */
+PRIVATE dev_t m_device;                        /* current device */
 
 extern int errno;                      /* error number for PM calls */
 
-FORWARD _PROTOTYPE( char *r_name, (void) );
-FORWARD _PROTOTYPE( struct device *r_prepare, (int device) );
-FORWARD _PROTOTYPE( int r_transfer, (int proc_nr, int opcode, u64_t position,
-                               iovec_t *iov, unsigned nr_req) );
-FORWARD _PROTOTYPE( int r_do_open, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( int r_ioctl, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) );
-FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( void r_updatebin, (int source, struct k_randomness_bin *rb));
+FORWARD _PROTOTYPE( struct device *r_prepare, (dev_t device) );
+FORWARD _PROTOTYPE( int r_transfer, (endpoint_t endpt, int opcode,
+       u64_t position, iovec_t *iov, unsigned int nr_req,
+       endpoint_t user_endpt) );
+FORWARD _PROTOTYPE( int r_do_open, (message *m_ptr) );
+FORWARD _PROTOTYPE( void r_random, (message *m_ptr) );
+FORWARD _PROTOTYPE( void r_updatebin, (int source,
+       struct k_randomness_bin *rb) );
 
 /* Entry points to this driver. */
-PRIVATE struct driver r_dtab = {
-  r_name,      /* current device's name */
+PRIVATE struct chardriver r_dtab = {
   r_do_open,   /* open or mount */
   do_nop,      /* nothing on a close */
-  r_ioctl,     /* specify ram disk geometry */
+  nop_ioctl,   /* no I/O controls supported */
   r_prepare,   /* prepare for I/O on a given minor device */
   r_transfer,  /* do the I/O */
   nop_cleanup, /* no need to clean up */
-  r_geometry,  /* device "geometry" */
   r_random,    /* get randomness from kernel (alarm) */
-  nop_cancel,
-  nop_select,
-  NULL,
-  NULL
+  nop_cancel,  /* cancel not supported */
+  nop_select,  /* select not supported */
+  NULL,                /* other messages not supported */
 };
 
 /* Buffer for the /dev/random number generator. */
@@ -64,7 +60,7 @@ PUBLIC int main(void)
   sef_local_startup();
 
   /* Call the generic receive loop. */
-  driver_task(&r_dtab, DRIVER_ASYN);
+  chardriver_task(&r_dtab, CHARDRIVER_ASYNC);
 
   return(OK);
 }
@@ -90,14 +86,14 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the random driver. */
   static struct k_randomness krandom;
   int i, s;
 
   random_init();
-  r_random(NULL, NULL);                                /* also set periodic timer */
+  r_random(NULL);                              /* also set periodic timer */
 
   /* Retrieve first randomness buffer with parameters. */
   if (OK != (s=sys_getrandomness(&krandom))) {
@@ -119,30 +115,19 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
        r_updatebin(i, &krandom.bin[i]);
 
   /* Announce we are up! */
-  driver_announce();
+  chardriver_announce();
 
   return(OK);
 }
 
-/*===========================================================================*
- *                              r_name                                      *
- *===========================================================================*/
-PRIVATE char *r_name()
-{
-/* Return a name for the current device. */
-  static char name[] = "random";
-  return name;  
-}
-
 /*===========================================================================*
  *                             r_prepare                                    *
  *===========================================================================*/
-PRIVATE struct device *r_prepare(device)
-int device;
+PRIVATE struct device *r_prepare(dev_t device)
 {
 /* Prepare for I/O on a device: check if the minor device number is ok. */
 
-  if (device < 0 || device >= NR_DEVS) return(NULL);
+  if (device >= NR_DEVS) return(NULL);
   m_device = device;
 
   return(&m_geom[device]);
@@ -151,16 +136,18 @@ int device;
 /*===========================================================================*
  *                             r_transfer                                   *
  *===========================================================================*/
-PRIVATE int r_transfer(proc_nr, opcode, position, iov, nr_req)
-int proc_nr;                   /* process doing the request */
-int opcode;                    /* DEV_GATHER or DEV_SCATTER */
-u64_t position;                        /* offset on device to read or write */
-iovec_t *iov;                  /* pointer to read or write request vector */
-unsigned nr_req;               /* length of request vector */
+PRIVATE int r_transfer(
+  endpoint_t endpt,            /* endpoint of grant owner */
+  int opcode,                  /* DEV_GATHER or DEV_SCATTER */
+  u64_t position,              /* offset on device to read or write */
+  iovec_t *iov,                        /* pointer to read or write request vector */
+  unsigned int nr_req,         /* length of request vector */
+  endpoint_t UNUSED(user_endpt)        /* endpoint of user process */
+)
 {
 /* Read or write one the driver's minor devices. */
   unsigned count, left, chunk;
-  vir_bytes user_vir;
+  cp_grant_id_t grant;
   struct device *dv;
   int r;
   size_t vir_offset = 0;
@@ -172,7 +159,7 @@ unsigned nr_req;            /* length of request vector */
 
        /* How much to transfer and where to / from. */
        count = iov->iov_size;
-       user_vir = iov->iov_addr;
+       grant = (cp_grant_id_t) iov->iov_addr;
 
        switch (m_device) {
 
@@ -185,23 +172,21 @@ unsigned nr_req;          /* length of request vector */
                chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
                if (opcode == DEV_GATHER_S) {
                    random_getbytes(random_buf, chunk);
-                   r= sys_safecopyto(proc_nr, user_vir, vir_offset,
+                   r= sys_safecopyto(endpt, grant, vir_offset,
                        (vir_bytes) random_buf, chunk, D);
                    if (r != OK)
                    {
-                       printf(
-                       "random: sys_safecopyto failed for proc %d, grant %d\n",
-                               proc_nr, user_vir);
+                       printf("random: sys_safecopyto failed for proc %d, "
+                               "grant %d\n", endpt, grant);
                        return r;
                    }
                } else if (opcode == DEV_SCATTER_S) {
-                   r= sys_safecopyfrom(proc_nr, user_vir, vir_offset,
+                   r= sys_safecopyfrom(endpt, grant, vir_offset,
                        (vir_bytes) random_buf, chunk, D);
                    if (r != OK)
                    {
-                       printf(
-               "random: sys_safecopyfrom failed for proc %d, grant %d\n",
-                               proc_nr, user_vir);
+                       printf("random: sys_safecopyfrom failed for proc %d, "
+                               "grant %d\n", endpt, grant);
                        return r;
                    }
                    random_putbytes(random_buf, chunk);
@@ -224,34 +209,15 @@ unsigned nr_req;          /* length of request vector */
   return(OK);
 }
 
-/*============================================================================*
- *                             r_do_open                                     *
- *============================================================================*/
-PRIVATE int r_do_open(dp, m_ptr)
-struct driver *dp;
-message *m_ptr;
-{
-/* Check device number on open.  
- */
-  if (r_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
-
-  return(OK);
-}
-
 /*===========================================================================*
- *                             r_ioctl                                      *
+ *                             r_do_open                                    *
  *===========================================================================*/
-PRIVATE int r_ioctl(dp, m_ptr)
-struct driver *dp;                     /* pointer to driver structure */
-message *m_ptr;                                /* pointer to control message */
+PRIVATE int r_do_open(message *m_ptr)
 {
+/* Check device number on open.
+ */
   if (r_prepare(m_ptr->DEVICE) == NULL) return(ENXIO);
 
-  switch (m_ptr->REQUEST) {
-
-    default:
-       return(do_diocntl(&r_dtab, m_ptr));
-  }
   return(OK);
 }
 
@@ -270,6 +236,9 @@ message *m_ptr;                             /* pointer to control message */
                }                                                       \
 }
 
+/*===========================================================================*
+ *                             r_updatebin                                  *
+ *===========================================================================*/
 PRIVATE void r_updatebin(int source, struct k_randomness_bin *rb)
 {
        int r_next, r_size, r_high;
@@ -293,12 +262,10 @@ PRIVATE void r_updatebin(int source, struct k_randomness_bin *rb)
        return;
 }
 
-/*============================================================================*
- *                             r_random                                      *
- *============================================================================*/
-PRIVATE void r_random(dp, m_ptr)
-struct driver *dp;                     /* pointer to driver structure */
-message *m_ptr;                                /* pointer to alarm message */
+/*===========================================================================*
+ *                             r_random                                     *
+ *===========================================================================*/
+PRIVATE void r_random(message *UNUSED(m_ptr))
 {
   /* Fetch random information from the kernel to update /dev/random. */
   int s;
@@ -322,14 +289,3 @@ message *m_ptr;                            /* pointer to alarm message */
        printf("RANDOM: sys_setalarm failed: %d\n", s);
 }
 
-/*============================================================================*
- *                             r_geometry                                    *
- *============================================================================*/
-PRIVATE void r_geometry(struct partition *entry)
-{
-  /* Memory devices don't have a geometry, but the outside world insists. */
-  entry->cylinders = div64u(m_geom[m_device].dv_size, SECTOR_SIZE) / (64 * 32);
-  entry->heads = 64;
-  entry->sectors = 32;
-}
-
index a37a4fed2c7ce7b68ee7612cc867f1155b1d7be4..d91e048156c2873ce79b5cb5c85dc077abd27f8e 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  readclock.drv
 SRCS=  readclock.c
 
-DPADD+= ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+= ${LIBSYS}
+LDADD+=        -lsys
 
 MAN=
 
index b2310f335b6b24fad8b9f05735dd21d42c2ca324..319488ed033863631d1f1c345e58ac9442d83d2d 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  ti1225
 SRCS=  ti1225.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
-LDADD+=        -ldriver -lsys -ltimers
+DPADD+=        ${LIBSYS}
+LDADD+=        -lsys
 
 MAN=
 
index 3194fceac0653878ceb0033c34ffddd1183c355f..35855272318d84d86c49ee4b97e2f6dc59206aee 100644 (file)
@@ -104,7 +104,7 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the ti1225 driver. */
        int c, i, r, first, devind, port;
@@ -175,9 +175,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
                hw_init(&ports[i]);
        }
 
-       /* Announce we are up! */
-       driver_announce();
-
        return(OK);
 }
 
index aaf1b8977fbd15e52e259667c539bc7a6d198205..42e74f97edd206e6c84bb21632fcfdf03181e3dd 100644 (file)
@@ -3,8 +3,8 @@
 PROG=  tty
 SRCS=  tty.c console.c keyboard.c pty.c rs232.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS}
-LDADD+=        -ldriver -lsys -ltimers
+DPADD+=        ${LIBSYS} ${LIBTIMERS}
+LDADD+=        -lsys -ltimers
 
 MAN=
 
index 5f77dcb9c525c7009b13e21348299faf9b1c7969..e9939b243b9d0a1108f5d763bc372d55c712c8a0 100644 (file)
@@ -896,8 +896,7 @@ clock_t dur;
 /*===========================================================================*
  *                             stop_beep                                    *
  *===========================================================================*/
-PRIVATE void stop_beep(tmrp)
-timer_t *tmrp;
+PRIVATE void stop_beep(timer_t *UNUSED(tmrp))
 {
 /* Turn off the beeper by turning off bits 0 and 1 in PORT_B. */
   unsigned long port_b_val;
@@ -1234,9 +1233,7 @@ struct sequence *seq;
 /*===========================================================================*
  *                             cons_ioctl                                   *
  *===========================================================================*/
-PRIVATE int cons_ioctl(tp, try)
-tty_t *tp;
-int try;
+PRIVATE int cons_ioctl(tty_t *tp, int UNUSED(try))
 {
 /* Set the screen dimensions. */
 
index d21b80e17af04e1a4fe6e8e2d8a1af6c919bddcf..e2dab153d9ba8562ef6af87be0e4aa76acbb068d 100644 (file)
@@ -481,8 +481,7 @@ int scode;
 /*===========================================================================*
  *                             kbd_interrupt                                *
  *===========================================================================*/
-PUBLIC void kbd_interrupt(m_ptr)
-message *m_ptr;
+PUBLIC void kbd_interrupt(message *UNUSED(m_ptr))
 {
 /* A keyboard interrupt has occurred.  Process it. */
   int o, isaux;
@@ -911,9 +910,9 @@ PRIVATE int kbc_read()
                        if(sys_inb(KEYBD, &byte) != OK)
                                printf("kbc_read: 2 sys_inb failed\n");
                        if (st & KB_AUX_BYTE)
-                               printf("kbc_read: aux byte 0x%x\n", byte);
+                               printf("kbc_read: aux byte 0x%lx\n", byte);
 #if DEBUG
-                       printf("keyboard`kbc_read: returning byte 0x%x\n",
+                       printf("keyboard`kbc_read: returning byte 0x%lx\n",
                                byte);
 #endif
                        return byte;
@@ -1296,8 +1295,7 @@ int *isauxp;
 /*===========================================================================*
  *                             kbd_watchdog                                 *
  *===========================================================================*/
-PRIVATE void kbd_watchdog(tmrp)
-timer_t *tmrp;
+PRIVATE void kbd_watchdog(timer_t *UNUSED(tmrp))
 {
 
        kbd_watchdog_set= 0;
index 916b7b963d1fcdf8031d3c035f6002cf18056e8f..860fb8b2e52ae1a018af8cbd9b8226925eaf8144 100644 (file)
@@ -405,7 +405,7 @@ PRIVATE int pty_read(tty_t *tp, int try)
 /*===========================================================================*
  *                             pty_close                                    *
  *===========================================================================*/
-PRIVATE int pty_close(tty_t *tp, int try)
+PRIVATE int pty_close(tty_t *tp, int UNUSED(try))
 {
 /* The tty side has closed, so shut down the pty side. */
   pty_t *pp = tp->tty_priv;
@@ -430,7 +430,7 @@ PRIVATE int pty_close(tty_t *tp, int try)
 /*===========================================================================*
  *                             pty_icancel                                  *
  *===========================================================================*/
-PRIVATE int pty_icancel(tty_t *tp, int try)
+PRIVATE int pty_icancel(tty_t *tp, int UNUSED(try))
 {
 /* Discard waiting input. */
   pty_t *pp = tp->tty_priv;
@@ -447,7 +447,7 @@ PRIVATE int pty_icancel(tty_t *tp, int try)
 /*===========================================================================*
  *                             pty_ocancel                                  *
  *===========================================================================*/
-PRIVATE int pty_ocancel(tty_t *tp, int try)
+PRIVATE int pty_ocancel(tty_t *tp, int UNUSED(try))
 {
 /* Drain the output buffer. */
   pty_t *pp = tp->tty_priv;
index f3311e3c0355eacbb3604cfe154d9f86a31f724f..a95a02db29b55d5fae0fecd14cd564a10c9cac70 100644 (file)
@@ -324,7 +324,7 @@ int c;                              /* character to echo */
 /*===========================================================================*
  *                             rs_ioctl                                     *
  *===========================================================================*/
-PRIVATE int rs_ioctl(tty_t *tp, int dummy)
+PRIVATE int rs_ioctl(tty_t *tp, int UNUSED(dummy))
 /* tp;                 which TTY */
 {
 /* Reconfigure the line as soon as the output has drained. */
@@ -544,7 +544,7 @@ PUBLIC void rs_interrupt(message *m)
 /*===========================================================================*
  *                             rs_icancel                                   *
  *===========================================================================*/
-PRIVATE int rs_icancel(tty_t *tp, int dummy)
+PRIVATE int rs_icancel(tty_t *tp, int UNUSED(dummy))
 {
 /* Cancel waiting input. */
   rs232_t *rs = tp->tty_priv;
@@ -561,7 +561,7 @@ PRIVATE int rs_icancel(tty_t *tp, int dummy)
 /*===========================================================================*
  *                             rs_ocancel                                   *
  *===========================================================================*/
-PRIVATE int rs_ocancel(tty_t *tp, int dummy)
+PRIVATE int rs_ocancel(tty_t *tp, int UNUSED(dummy))
 {
 /* Cancel pending output. */
   rs232_t *rs = tp->tty_priv;
@@ -636,7 +636,7 @@ PRIVATE void rs_ostart(rs232_t *rs)
 /*===========================================================================*
  *                             rs_break                                     *
  *===========================================================================*/
-PRIVATE int rs_break(tty_t *tp, int dummy)
+PRIVATE int rs_break(tty_t *tp, int UNUSED(dummy))
 {
 /* Generate a break condition by setting the BREAK bit for 0.4 sec. */
   rs232_t *rs = tp->tty_priv;
@@ -654,7 +654,7 @@ PRIVATE int rs_break(tty_t *tp, int dummy)
 /*===========================================================================*
  *                             rs_close                                     *
  *===========================================================================*/
-PRIVATE int rs_close(tty_t *tp, int dummy)
+PRIVATE int rs_close(tty_t *tp, int UNUSED(dummy))
 {
 /* The line is closed; optionally hang up. */
   rs232_t *rs = tp->tty_priv;
index 39f4ee54a53dbba2232c3185ba4a75af388bf232..1d31be457d1c41dddbd29f0579ec52c87019b658 100644 (file)
@@ -309,7 +309,7 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the tty driver. */
   int r;
@@ -1524,7 +1524,7 @@ register tty_t *tp;
 /*===========================================================================*
  *                             tty_devnop                                   *
  *===========================================================================*/
-PRIVATE int tty_devnop(tty_t *tp, int try)
+PRIVATE int tty_devnop(tty_t *UNUSED(tp), int UNUSED(try))
 {
   /* Some functions need not be implemented at the device level. */
   return 0;
index 1525a52f52dec56d7ac65180bf51965b264acc7b..a4c2127cb5e11d468d672feb1b561503d2bc71d4 100644 (file)
@@ -16,9 +16,9 @@ LIBCOMPAT_DIR?=
 LIBMINLIB_DIR?=
 LIBASYN_DIR?=
 
-SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libdriver libnetdriver \
-       libedit ${LIBM_DIR} libsys libtimers ${LIBUTIL_DIR} libl libhgfs  \
-       libz libfetch libvtreefs libaudiodriver libmthread     \
+SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libblockdriver libchardriver     \
+       libnetdriver libedit ${LIBM_DIR} libsys libtimers ${LIBUTIL_DIR}  \
+       libl libhgfs libz libfetch libvtreefs libaudiodriver libmthread   \
        libexec libdevman libusb ${LIBMINLIB_DIR} ${LIBASYN_DIR}          \
        libddekit libminixfs libbdev
 
index a0ac41b82c55108a21d7a759190832df0faf69a7..8eced800710c9f15b4a5c0cae406d0b0c477b787 100644 (file)
@@ -83,7 +83,7 @@ EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
 EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
 PUBLIC int is_status_msg_expected = FALSE;
 
-PUBLIC int main(int argc, char *argv[]) 
+PUBLIC int main(void)
 {
        int r, caller;
        message mess, repl_mess;
@@ -255,7 +255,7 @@ PRIVATE int init_driver(void) {
        irq_hook_set = TRUE; /* now signal handler knows it must unregister policy*/
 
        /* Announce we are up! */
-       driver_announce();
+       chardriver_announce();
 
        return OK;
 }
index 8182dcd5598b0e85bb21aad0daed637d60337316..e188aa38317c806e9449118fd16235566e868c36 100644 (file)
@@ -32,9 +32,10 @@ static int bdev_opcl(int req, dev_t dev, int access)
  */
   message m;
 
+  memset(&m, 0, sizeof(m));
   m.m_type = req;
-  m.DEVICE = minor(dev);
-  m.COUNT = access;
+  m.BDEV_MINOR = minor(dev);
+  m.BDEV_ACCESS = access;
 
   return bdev_sendrec(dev, &m);
 }
@@ -45,7 +46,7 @@ int bdev_open(dev_t dev, int access)
  * File system usage note: typically called from mount, after bdev_driver.
  */
 
-  return bdev_opcl(DEV_OPEN, dev, access);
+  return bdev_opcl(BDEV_OPEN, dev, access);
 }
 
 int bdev_close(dev_t dev)
@@ -54,11 +55,11 @@ int bdev_close(dev_t dev)
  * File system usage note: typically called from unmount.
  */
 
-  return bdev_opcl(DEV_CLOSE, dev, 0);
+  return bdev_opcl(BDEV_CLOSE, dev, 0);
 }
 
-static int bdev_rdwt_setup(int req, dev_t dev, u64_t pos, char *buf, int count,
-  int UNUSED(flags), message *m)
+static int bdev_rdwt_setup(int req, dev_t dev, u64_t pos, char *buf,
+  size_t count, int flags, message *m)
 {
 /* Set up a single-buffer read/write request.
  */
@@ -66,10 +67,12 @@ static int bdev_rdwt_setup(int req, dev_t dev, u64_t pos, char *buf, int count,
   cp_grant_id_t grant;
   int access;
 
+  assert((ssize_t) count >= 0);
+
   if ((endpt = bdev_driver_get(dev)) == NONE)
        return EDEADSRCDST;
 
-  access = (req == DEV_READ_S) ? CPF_WRITE : CPF_READ;
+  access = (req == BDEV_READ) ? CPF_WRITE : CPF_READ;
 
   grant = cpf_grant_direct(endpt, (vir_bytes) buf, count, access);
 
@@ -78,12 +81,14 @@ static int bdev_rdwt_setup(int req, dev_t dev, u64_t pos, char *buf, int count,
        return EINVAL;
   }
 
+  memset(m, 0, sizeof(*m));
   m->m_type = req;
-  m->DEVICE = minor(dev);
-  m->POSITION = ex64lo(pos);
-  m->HIGHPOS = ex64hi(pos);
-  m->COUNT = count;
-  m->IO_GRANT = (void *) grant;
+  m->BDEV_MINOR = minor(dev);
+  m->BDEV_POS_LO = ex64lo(pos);
+  m->BDEV_POS_HI = ex64hi(pos);
+  m->BDEV_COUNT = count;
+  m->BDEV_GRANT = grant;
+  m->BDEV_FLAGS = flags;
 
   return OK;
 }
@@ -92,15 +97,12 @@ static void bdev_rdwt_cleanup(message *m)
 {
 /* Clean up a single-buffer read/write request.
  */
-  cp_grant_id_t grant;
-
-  grant = (cp_grant_id_t) m->IO_GRANT;
 
-  cpf_revoke(grant);
+  cpf_revoke(m->BDEV_GRANT);
 }
 
-static int bdev_rdwt(int req, dev_t dev, u64_t pos, char *buf, int count,
-  int flags)
+static ssize_t bdev_rdwt(int req, dev_t dev, u64_t pos, char *buf,
+  size_t count, int flags)
 {
 /* Perform a read or write call using a single buffer.
  */
@@ -118,11 +120,11 @@ static int bdev_rdwt(int req, dev_t dev, u64_t pos, char *buf, int count,
 }
 
 static int bdev_vrdwt_setup(int req, dev_t dev, u64_t pos, iovec_t *vec,
-  int count, int UNUSED(flags), message *m, iovec_s_t *gvec,
-  cp_grant_id_t *grants, vir_bytes *size)
+  int count, int flags, message *m, iovec_s_t *gvec)
 {
 /* Set up a vectored read/write request.
  */
+  ssize_t size;
   endpoint_t endpt;
   cp_grant_id_t grant;
   int i, access;
@@ -132,154 +134,118 @@ static int bdev_vrdwt_setup(int req, dev_t dev, u64_t pos, iovec_t *vec,
   if ((endpt = bdev_driver_get(dev)) == NONE)
        return EDEADSRCDST;
 
-  access = (req == DEV_GATHER_S) ? CPF_WRITE : CPF_READ;
-  *size = 0;
+  access = (req == BDEV_GATHER) ? CPF_WRITE : CPF_READ;
+  size = 0;
 
   for (i = 0; i < count; i++) {
-       grants[i] = cpf_grant_direct(endpt, vec[i].iov_addr, vec[i].iov_size,
+       grant = cpf_grant_direct(endpt, vec[i].iov_addr, vec[i].iov_size,
                access);
 
-       if (!GRANT_VALID(grants[i])) {
+       if (!GRANT_VALID(grant)) {
                printf("bdev: unable to allocate grant!\n");
 
                for (i--; i >= 0; i--)
-                       cpf_revoke(grants[i]);
+                       cpf_revoke(gvec[i].iov_grant);
 
                return EINVAL;
        }
 
-       /* We keep a separate grants array to prevent local leaks if the driver
-        * ends up clobbering the grant vector. Future protocol updates should
-        * make the grant for the vector read-only.
-        */
-       gvec[i].iov_grant = grants[i];
+       gvec[i].iov_grant = grant;
        gvec[i].iov_size = vec[i].iov_size;
 
-       assert(*size + vec[i].iov_size > *size);
+       assert((ssize_t) (size + vec[i].iov_size) > size);
 
-       *size += vec[i].iov_size;
+       size += vec[i].iov_size;
   }
 
   grant = cpf_grant_direct(endpt, (vir_bytes) gvec, sizeof(gvec[0]) * count,
-       CPF_READ | CPF_WRITE);
+       CPF_READ);
 
   if (!GRANT_VALID(grant)) {
        printf("bdev: unable to allocate grant!\n");
 
        for (i = count - 1; i >= 0; i--)
-               cpf_revoke(grants[i]);
+               cpf_revoke(gvec[i].iov_grant);
 
        return EINVAL;
   }
 
+  memset(m, 0, sizeof(*m));
   m->m_type = req;
-  m->DEVICE = minor(dev);
-  m->POSITION = ex64lo(pos);
-  m->HIGHPOS = ex64hi(pos);
-  m->COUNT = count;
-  m->IO_GRANT = (void *) grant;
+  m->BDEV_MINOR = minor(dev);
+  m->BDEV_POS_LO = ex64lo(pos);
+  m->BDEV_POS_HI = ex64hi(pos);
+  m->BDEV_COUNT = count;
+  m->BDEV_GRANT = grant;
+  m->BDEV_FLAGS = flags;
 
   return OK;
 }
 
-static void bdev_vrdwt_cleanup(message *m, cp_grant_id_t *grants)
+static void bdev_vrdwt_cleanup(message *m, iovec_s_t *gvec)
 {
 /* Clean up a vectored read/write request.
  */
   cp_grant_id_t grant;
   int i;
 
-  grant = (cp_grant_id_t) m->IO_GRANT;
+  grant = m->BDEV_GRANT;
 
   cpf_revoke(grant);
 
-  for (i = m->COUNT - 1; i >= 0; i--)
-       cpf_revoke(grants[i]);
-}
-
-static int bdev_vrdwt_adjust(dev_t dev, iovec_s_t *gvec, int count,
-  vir_bytes *size)
-{
-/* Adjust the number of bytes transferred, by subtracting from it the number of
- * bytes *not* transferred according to the result vector.
- */
-  int i;
-
-  for (i = 0; i < count; i++) {
-       if (*size < gvec[i].iov_size) {
-               printf("bdev: driver (%d) returned bad vector\n",
-                       bdev_driver_get(dev));
-
-               return FALSE;
-       }
-
-       *size -= gvec[i].iov_size;
-  }
-
-  return TRUE;
+  for (i = m->BDEV_COUNT - 1; i >= 0; i--)
+       cpf_revoke(gvec[i].iov_grant);
 }
 
-static int bdev_vrdwt(int req, dev_t dev, u64_t pos, iovec_t *vec, int count,
-  int flags, vir_bytes *size)
+static ssize_t bdev_vrdwt(int req, dev_t dev, u64_t pos, iovec_t *vec,
+  int count, int flags)
 {
-/* Perform a read or write call using a vector of buffer.
+/* Perform a read or write call using a vector of buffers.
  */
   iovec_s_t gvec[NR_IOREQS];
-  cp_grant_id_t grants[NR_IOREQS];
   message m;
   int r;
 
-  if ((r = bdev_vrdwt_setup(req, dev, pos, vec, count, flags, &m, gvec,
-               grants, size)) != OK) {
-       *size = 0;
+  if ((r = bdev_vrdwt_setup(req, dev, pos, vec, count, flags, &m, gvec)) != OK)
        return r;
-  }
 
   r = bdev_sendrec(dev, &m);
 
-  bdev_vrdwt_cleanup(&m, grants);
-
-  /* Also return the number of bytes transferred. */
-  if (!bdev_vrdwt_adjust(dev, gvec, count, size)) {
-       *size = 0;
-       r = EIO;
-  }
+  bdev_vrdwt_cleanup(&m, gvec);
 
   return r;
 }
 
-int bdev_read(dev_t dev, u64_t pos, char *buf, int count, int flags)
+ssize_t bdev_read(dev_t dev, u64_t pos, char *buf, size_t count, int flags)
 {
 /* Perform a read call into a single buffer.
  */
 
-  return bdev_rdwt(DEV_READ_S, dev, pos, buf, count, flags);
+  return bdev_rdwt(BDEV_READ, dev, pos, buf, count, flags);
 }
 
-int bdev_write(dev_t dev, u64_t pos, char *buf, int count, int flags)
+ssize_t bdev_write(dev_t dev, u64_t pos, char *buf, size_t count, int flags)
 {
 /* Perform a write call from a single buffer.
  */
 
-  return bdev_rdwt(DEV_WRITE_S, dev, pos, buf, count, flags);
+  return bdev_rdwt(BDEV_WRITE, dev, pos, buf, count, flags);
 }
 
-int bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags,
-  vir_bytes *size)
+ssize_t bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags)
 {
 /* Perform a read call into a vector of buffers.
  */
 
-  return bdev_vrdwt(DEV_GATHER_S, dev, pos, vec, count, flags, size);
+  return bdev_vrdwt(BDEV_GATHER, dev, pos, vec, count, flags);
 }
 
-int bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags,
-  vir_bytes *size)
+ssize_t bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags)
 {
 /* Perform a write call from a vector of buffers.
  */
 
-  return bdev_vrdwt(DEV_SCATTER_S, dev, pos, vec, count, flags, size);
+  return bdev_vrdwt(BDEV_SCATTER, dev, pos, vec, count, flags);
 }
 
 static int bdev_ioctl_setup(dev_t dev, int request, void *buf, message *m)
@@ -311,10 +277,11 @@ static int bdev_ioctl_setup(dev_t dev, int request, void *buf, message *m)
        return EINVAL;
   }
 
-  m->m_type = DEV_IOCTL_S;
-  m->DEVICE = minor(dev);
-  m->REQUEST = request;
-  m->IO_GRANT = (void *) grant;
+  memset(m, 0, sizeof(*m));
+  m->m_type = BDEV_IOCTL;
+  m->BDEV_MINOR = minor(dev);
+  m->BDEV_REQUEST = request;
+  m->BDEV_GRANT = grant;
 
   return OK;
 }
@@ -323,11 +290,8 @@ static void bdev_ioctl_cleanup(message *m)
 {
 /* Clean up an I/O control request.
  */
-  cp_grant_id_t grant;
 
-  grant = (cp_grant_id_t) m->IO_GRANT;
-
-  cpf_revoke(grant);
+  cpf_revoke(m->BDEV_GRANT);
 }
 
 int bdev_ioctl(dev_t dev, int request, void *buf)
index 941d2e187b6769039389d5add725045306ec7299..afff3e49ab5932b00f23092a78731df25bb69ea7 100644 (file)
@@ -12,7 +12,8 @@ static void bdev_cancel(dev_t dev)
  * permanently unusable, and clean up any associated calls and resources.
  */
 
-  printf("bdev: driver for major %d crashed\n", major(dev));
+  printf("bdev: driver for major %d (endpoint %d) crashed\n",
+       major(dev), bdev_driver_get(dev));
 
   /* Mark the driver as unusable. */
   bdev_driver_clear(dev);
@@ -27,18 +28,13 @@ void bdev_update(dev_t dev, endpoint_t endpt)
   old_endpt = bdev_driver_get(dev);
 
   bdev_driver_set(dev, endpt);
-
-  /* If updating the driver causes an endpoint change, the driver has
-   * restarted.
-   */
-  if (old_endpt != NONE && old_endpt != endpt)
-       bdev_cancel(dev);
 }
 
 int bdev_sendrec(dev_t dev, const message *m_orig)
 {
 /* Send a request to the given device, and wait for the reply.
  */
+  static long id = 0;
   endpoint_t endpt;
   message m;
   int r;
@@ -49,7 +45,7 @@ int bdev_sendrec(dev_t dev, const message *m_orig)
 
   /* Send the request and block until we receive a reply. */
   m = *m_orig;
-  m.USER_ENDPT = (endpoint_t) -1; /* synchronous request; no ID */
+  m.BDEV_ID = ++id;
 
   r = sendrec(endpt, &m);
 
@@ -65,25 +61,25 @@ int bdev_sendrec(dev_t dev, const message *m_orig)
        return r;
   }
 
-  if (m.m_type != TASK_REPLY) {
+  if (m.m_type != BDEV_REPLY) {
        printf("bdev: driver (%d) sent weird response (%d)\n",
                endpt, m.m_type);
        return EIO;
   }
 
   /* ERESTART signifies a driver restart. Again, we do not support this yet. */
-  if (m.REP_STATUS == ERESTART) {
+  if (m.BDEV_STATUS == ERESTART) {
        bdev_cancel(dev);
 
        return EDEADSRCDST;
   }
 
-  if (m.REP_ENDPT != (endpoint_t) -1) {
-       printf("bdev: driver (%d) sent invalid response (%d)\n",
-               endpt, m.REP_ENDPT);
+  if (m.BDEV_ID != id) {
+       printf("bdev: driver (%d) sent invalid response (%ld)\n",
+               endpt, m.BDEV_ID);
        return EIO;
   }
 
-  /* We got a reply to our request. */
-  return m.REP_STATUS;
+  /* Return the result of our request. */
+  return m.BDEV_STATUS;
 }
similarity index 78%
rename from lib/libdriver/Makefile
rename to lib/libblockdriver/Makefile
index 2ff9ab7ba065529c6d748d4147264425d4a0061b..0c153d21872e9ed478f58221eab4b1cd4def3c3f 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile for libdriver
+# Makefile for libblockdriver
 .include <bsd.own.mk>
 
-LIB=   driver
+LIB=   blockdriver
 
 SRCS=  driver.c drvlib.c driver_st.c driver_mt.c mq.c event.c
 
diff --git a/lib/libblockdriver/driver.c b/lib/libblockdriver/driver.c
new file mode 100644 (file)
index 0000000..f63e9cb
--- /dev/null
@@ -0,0 +1,382 @@
+/* This file contains the device independent block driver interface.
+ *
+ * Block drivers support the following requests. Message format m10 is used.
+ * Field names are prefixed with BDEV_. Separate field names are used for the
+ * "access" and "request" fields.
+ *
+ *    m_type        MINOR     COUNT     GRANT   FLAGS    ID   POS_LO POS_HI
+ * +--------------+--------+----------+-------+-------+------+------+------+
+ * | BDEV_OPEN    | minor  |  access  |       |       |  id  |      |      |
+ * |--------------+--------+----------+-------+-------+------+------+------|
+ * | BDEV_CLOSE   | minor  |          |       |       |  id  |      |      |
+ * |--------------+--------+----------+-------+-------+------+------+------|
+ * | BDEV_READ    | minor  |  bytes   | grant | flags |  id  |  position   |
+ * |--------------+--------+----------+-------+-------+------+------+------|
+ * | BDEV_WRITE   | minor  |  bytes   | grant | flags |  id  |  position   |
+ * |--------------+--------+----------+-------+-------+------+------+------|
+ * | BDEV_GATHER  | minor  | elements | grant | flags |  id  |  position   |
+ * |--------------+--------+----------+-------+-------+------+------+------|
+ * | BDEV_SCATTER | minor  | elements | grant | flags |  id  |  position   |
+ * |--------------+--------+----------+-------+-------+------+------+------|
+ * | BDEV_IOCTL   | minor  | request  | grant | flags |  id  |      |      |
+ * -------------------------------------------------------------------------
+ *
+ * The following reply message is used for all requests.
+ *
+ *    m_type        STATUS                              ID
+ * +--------------+--------+----------+-------+-------+------+------+------+
+ * | BDEV_REPLY   | status |          |       |       |  id  |      |      |
+ * -------------------------------------------------------------------------
+ *
+ * Changes:
+ *   Oct 16, 2011   split character and block protocol  (D.C. van Moolenbroek)
+ *   Aug 27, 2011   move common functions into driver.c  (A. Welzel)
+ *   Jul 25, 2005   added SYS_SIG type for signals  (Jorrit N. Herder)
+ *   Sep 15, 2004   added SYN_ALARM type for timeouts  (Jorrit N. Herder)
+ *   Jul 23, 2004   removed kernel dependencies  (Jorrit N. Herder)
+ *   Apr 02, 1992   constructed from AT wini and floppy driver  (Kees J. Bot)
+ */
+
+#include <minix/drivers.h>
+#include <minix/blockdriver.h>
+#include <minix/ds.h>
+#include <sys/ioc_disk.h>
+
+#include "driver.h"
+#include "mq.h"
+
+/* Management data for opened devices. */
+PRIVATE int open_devs[MAX_NR_OPEN_DEVICES];
+PRIVATE int next_open_devs_slot = 0;
+
+/*===========================================================================*
+ *                             clear_open_devs                              *
+ *===========================================================================*/
+PRIVATE void clear_open_devs(void)
+{
+/* Reset the set of previously opened minor devices. */
+  next_open_devs_slot = 0;
+}
+
+/*===========================================================================*
+ *                             is_open_dev                                  *
+ *===========================================================================*/
+PRIVATE int is_open_dev(int device)
+{
+/* Check whether the given minor device has previously been opened. */
+  int i;
+
+  for (i = 0; i < next_open_devs_slot; i++)
+       if (open_devs[i] == device)
+               return TRUE;
+
+  return FALSE;
+}
+
+/*===========================================================================*
+ *                             set_open_dev                                 *
+ *===========================================================================*/
+PRIVATE void set_open_dev(int device)
+{
+/* Mark the given minor device as having been opened. */
+
+  if (next_open_devs_slot >= MAX_NR_OPEN_DEVICES)
+       panic("out of slots for open devices");
+
+  open_devs[next_open_devs_slot] = device;
+  next_open_devs_slot++;
+}
+
+/*===========================================================================*
+ *                             blockdriver_announce                         *
+ *===========================================================================*/
+PUBLIC void blockdriver_announce(void)
+{
+/* Announce we are up after a fresh start or a restart. */
+  int r;
+  char key[DS_MAX_KEYLEN];
+  char label[DS_MAX_KEYLEN];
+  char *driver_prefix = "drv.blk.";
+
+  /* Callers are allowed to use sendrec to communicate with drivers.
+   * For this reason, there may blocked callers when a driver restarts.
+   * Ask the kernel to unblock them (if any).
+   */
+#if USE_STATECTL
+  if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK)
+       panic("blockdriver_init: sys_statectl failed: %d", r);
+#endif
+
+  /* Publish a driver up event. */
+  if ((r = ds_retrieve_label_name(label, getprocnr())) != OK)
+       panic("blockdriver_init: unable to get own label: %d", r);
+
+  snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label);
+  if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK)
+       panic("blockdriver_init: unable to publish driver up event: %d", r);
+
+  /* Expect an open for any device before serving regular driver requests. */
+  clear_open_devs();
+
+  /* Initialize or reset the message queue. */
+  mq_init();
+}
+
+/*===========================================================================*
+ *                             blockdriver_reply                            *
+ *===========================================================================*/
+PUBLIC void blockdriver_reply(message *m_ptr, int ipc_status, int reply)
+{
+/* Reply to a block request sent to the driver. */
+  endpoint_t caller_e;
+  long id;
+  int r;
+
+  if (reply == EDONTREPLY)
+       return;
+
+  caller_e = m_ptr->m_source;
+  id = m_ptr->BDEV_ID;
+
+  memset(m_ptr, 0, sizeof(*m_ptr));
+
+  m_ptr->m_type = BDEV_REPLY;
+  m_ptr->BDEV_STATUS = reply;
+  m_ptr->BDEV_ID = id;
+
+  /* If we would block sending the message, send it asynchronously. */
+  if (IPC_STATUS_CALL(ipc_status) == SENDREC)
+       r = sendnb(caller_e, m_ptr);
+  else
+       r = asynsend(caller_e, m_ptr);
+
+  if (r != OK)
+       printf("blockdriver_reply: unable to send reply to %d: %d\n",
+               caller_e, r);
+}
+
+/*===========================================================================*
+ *                             do_open                                      *
+ *===========================================================================*/
+PRIVATE int do_open(struct blockdriver *bdp, message *mp)
+{
+/* Open a minor device. */
+
+  return (*bdp->bdr_open)(mp->BDEV_MINOR, mp->BDEV_ACCESS);
+}
+
+/*===========================================================================*
+ *                             do_close                                             *
+ *===========================================================================*/
+PRIVATE int do_close(struct blockdriver *bdp, message *mp)
+{
+/* Close a minor device. */
+
+  return (*bdp->bdr_close)(mp->BDEV_MINOR);
+}
+
+/*===========================================================================*
+ *                             do_rdwt                                      *
+ *===========================================================================*/
+PRIVATE int do_rdwt(struct blockdriver *bdp, message *mp)
+{
+/* Carry out a single read or write request. */
+  iovec_t iovec1;
+  u64_t position;
+  int do_write;
+  ssize_t r;
+
+  /* Disk address?  Address and length of the user buffer? */
+  if (mp->BDEV_COUNT < 0) return EINVAL;
+
+  /* Create a one element scatter/gather vector for the buffer. */
+  iovec1.iov_addr = mp->BDEV_GRANT;
+  iovec1.iov_size = mp->BDEV_COUNT;
+
+  /* Transfer bytes from/to the device. */
+  do_write = (mp->m_type == BDEV_WRITE);
+  position = make64(mp->BDEV_POS_LO, mp->BDEV_POS_HI);
+
+  r = (*bdp->bdr_transfer)(mp->BDEV_MINOR, do_write, position, mp->m_source,
+       &iovec1, 1, mp->BDEV_FLAGS);
+
+  /* Return the number of bytes transferred or an error code. */
+  return r;
+}
+
+/*===========================================================================*
+ *                             do_vrdwt                                     *
+ *===========================================================================*/
+PRIVATE int do_vrdwt(struct blockdriver *bdp, message *mp)
+{
+/* Carry out an device read or write to/from a vector of buffers. */
+  iovec_t iovec[NR_IOREQS];
+  unsigned nr_req;
+  u64_t position;
+  int i, do_write;
+  ssize_t r, size;
+
+  /* Copy the vector from the caller to kernel space. */
+  nr_req = mp->BDEV_COUNT;     /* Length of I/O vector */
+  if (nr_req > NR_IOREQS) nr_req = NR_IOREQS;
+
+  if (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->BDEV_GRANT,
+               0, (vir_bytes) iovec, nr_req * sizeof(iovec[0]), D)) {
+       printf("blockdriver: bad I/O vector by: %d\n", mp->m_source);
+       return EINVAL;
+  }
+
+  /* Check for overflow condition. */
+  for (i = size = 0; i < nr_req; i++) {
+       if ((ssize_t) (size + iovec[i].iov_size) < size) return EINVAL;
+       size += iovec[i].iov_size;
+  }
+
+  /* Transfer bytes from/to the device. */
+  do_write = (mp->m_type == BDEV_SCATTER);
+  position = make64(mp->BDEV_POS_LO, mp->BDEV_POS_HI);
+
+  r = (*bdp->bdr_transfer)(mp->BDEV_MINOR, do_write, position, mp->m_source,
+       iovec, nr_req, mp->BDEV_FLAGS);
+
+  /* Return the number of bytes transferred or an error code. */
+  return r;
+}
+
+/*===========================================================================*
+ *                             do_ioctl                                     *
+ *===========================================================================*/
+PRIVATE int do_ioctl(struct blockdriver *bdp, message *mp)
+{
+/* Carry out an I/O control request. For now, we handle setting/getting
+ * partitions here, and let the driver handle any other requests.
+ */
+  struct device *dv;
+  struct partition entry;
+  unsigned int request;
+  cp_grant_id_t grant;
+  dev_t minor;
+  int r;
+
+  minor = mp->BDEV_MINOR;
+  request = mp->BDEV_REQUEST;
+  grant = mp->BDEV_GRANT;
+
+  switch (request) {
+  case DIOCSETP:
+       /* Copy just this one partition table entry. */
+       r = sys_safecopyfrom(mp->m_source, grant, 0, (vir_bytes) &entry,
+               sizeof(entry), D);
+       if (r != OK)
+               return r;
+
+       if ((dv = (*bdp->bdr_part)(minor)) == NULL)
+               return ENXIO;
+       dv->dv_base = entry.base;
+       dv->dv_size = entry.size;
+
+       break;
+
+  case DIOCGETP:
+       /* Return a partition table entry and the geometry of the drive. */
+       if ((dv = (*bdp->bdr_part)(minor)) == NULL)
+               return ENXIO;
+       entry.base = dv->dv_base;
+       entry.size = dv->dv_size;
+       if (bdp->bdr_geometry) {
+               (*bdp->bdr_geometry)(minor, &entry);
+       } else {
+               /* The driver doesn't care -- make up fake geometry. */
+               entry.cylinders = div64u(entry.size, SECTOR_SIZE);
+               entry.heads = 64;
+               entry.sectors = 32;
+       }
+
+       r = sys_safecopyto(mp->m_source, grant, 0, (vir_bytes) &entry,
+               sizeof(entry), D);
+
+       break;
+
+  default:
+       if (bdp->bdr_ioctl)
+               r = (*bdp->bdr_ioctl)(minor, request, mp->m_source, grant);
+       else
+               r = EINVAL;
+  }
+
+  return r;
+}
+
+/*===========================================================================*
+ *                             blockdriver_handle_notify                    *
+ *===========================================================================*/
+PUBLIC void blockdriver_handle_notify(struct blockdriver *bdp, message *m_ptr)
+{
+/* Take care of the notifications (interrupt and clock messages) by calling
+ * the appropiate callback functions. Never send a reply.
+ */
+
+  /* Call the appropriate function for this notification. */
+  switch (_ENDPOINT_P(m_ptr->m_source)) {
+  case HARDWARE:
+       if (bdp->bdr_intr)
+               (*bdp->bdr_intr)(m_ptr->NOTIFY_ARG);
+       break;
+
+  case CLOCK:
+       if (bdp->bdr_alarm)
+               (*bdp->bdr_alarm)(m_ptr->NOTIFY_TIMESTAMP);
+       break;
+
+  default:
+       if (bdp->bdr_other)
+               (void) (*bdp->bdr_other)(m_ptr);
+  }
+}
+
+/*===========================================================================*
+ *                             blockdriver_handle_request                   *
+ *===========================================================================*/
+PUBLIC int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr)
+{
+/* Call the appropiate driver function, based on the type of request. Return
+ * the result code that is to be sent back to the caller, or EDONTREPLY if no
+ * reply is to be sent.
+ */
+  int r;
+
+  /* We might get spurious requests if the driver has been restarted. Deny any
+   * requests on devices that have not previously been opened, signaling the
+   * caller that something went wrong.
+   */
+  if (IS_BDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->BDEV_MINOR)) {
+       /* Reply ERESTART to spurious requests for unopened devices. */
+       if (m_ptr->m_type != BDEV_OPEN)
+               return ERESTART;
+
+       /* Mark the device as opened otherwise. */
+       set_open_dev(m_ptr->BDEV_MINOR);
+  }
+
+  /* Call the appropriate function(s) for this request. */
+  switch (m_ptr->m_type) {
+  case BDEV_OPEN:      r = do_open(bdp, m_ptr);        break;
+  case BDEV_CLOSE:     r = do_close(bdp, m_ptr);       break;
+  case BDEV_READ:
+  case BDEV_WRITE:     r = do_rdwt(bdp, m_ptr);        break;
+  case BDEV_GATHER:
+  case BDEV_SCATTER:   r = do_vrdwt(bdp, m_ptr);       break;
+  case BDEV_IOCTL:     r = do_ioctl(bdp, m_ptr);       break;
+  default:
+       if (bdp->bdr_other)
+               r = bdp->bdr_other(m_ptr);
+       else
+               r = EINVAL;
+  }
+
+  /* Let the driver perform any cleanup. */
+  if (bdp->bdr_cleanup != NULL)
+       (*bdp->bdr_cleanup)();
+
+  return r;
+}
diff --git a/lib/libblockdriver/driver.h b/lib/libblockdriver/driver.h
new file mode 100644 (file)
index 0000000..4e1299e
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _BLOCKDRIVER_DRIVER_H
+#define _BLOCKDRIVER_DRIVER_H
+
+_PROTOTYPE( void blockdriver_handle_notify, (struct blockdriver *bdp,
+       message *m_ptr) );
+_PROTOTYPE( int blockdriver_handle_request, (struct blockdriver *bdp,
+       message *m_ptr) );
+_PROTOTYPE( void blockdriver_reply, (message *m_ptr, int ipc_status,
+       int reply) );
+
+#endif /* _BLOCKDRIVER_DRIVER_H */
similarity index 74%
rename from lib/libdriver/driver_mt.c
rename to lib/libblockdriver/driver_mt.c
index cb9d6a924aee66a826acb4d5740fa53946294064..fd7cc0215a5b00915ee1bf5437a7ef80e7c2b056 100644 (file)
@@ -1,17 +1,17 @@
-/* This file contains the multithreaded device independent driver interface.
+/* This file contains the multithreaded driver interface.
  *
  * Changes:
  *   Aug 27, 2011   created (A. Welzel)
  *
  * The entry points into this file are:
- *   driver_mt_task:           the main message loop of the driver
- *   driver_mt_terminate:      break out of the main message loop
- *   driver_mt_sleep:          put the current thread to sleep
- *   driver_mt_wakeup:         wake up a sleeping thread
- *   driver_mt_stop:           put up the current thread for termination
+ *   blockdriver_mt_task:      the main message loop of the driver
+ *   blockdriver_mt_terminate: break out of the main message loop
+ *   blockdriver_mt_sleep:     put the current thread to sleep
+ *   blockdriver_mt_wakeup:    wake up a sleeping thread
+ *   blockdriver_mt_stop:      put up the current thread for termination
  */
 
-#include <minix/driver_mt.h>
+#include <minix/blockdriver_mt.h>
 #include <minix/mthread.h>
 #include <assert.h>
 
@@ -35,9 +35,8 @@ typedef struct {
   event_t sleep_event;
 } worker_t;
 
-PRIVATE struct driver *driver_cb;
-PRIVATE int driver_mt_type;
-PRIVATE int driver_mt_running = FALSE;
+PRIVATE struct blockdriver *bdtab;
+PRIVATE int running = FALSE;
 
 PRIVATE mthread_key_t worker_key;
 
@@ -57,10 +56,10 @@ PRIVATE void enqueue(worker_t *wp, const message *m_src, int ipc_status)
 
   assert(wp->state == STATE_RUNNING || wp->state == STATE_STOPPING);
 
-  if (!driver_mq_enqueue(wp->id, m_src, ipc_status))
-       panic("driver_mt: enqueue failed (message queue full)");
+  if (!mq_enqueue(wp->id, m_src, ipc_status))
+       panic("blockdriver_mt: enqueue failed (message queue full)");
 
-  driver_event_fire(&wp->queue_event);
+  event_fire(&wp->queue_event);
 }
 
 /*===========================================================================*
@@ -73,7 +72,7 @@ PRIVATE int try_dequeue(worker_t *wp, message *m_dst, int *ipc_status)
  * called from a worker thread. Does not block.
  */
 
-  return driver_mq_dequeue(wp->id, m_dst, ipc_status);
+  return mq_dequeue(wp->id, m_dst, ipc_status);
 }
 
 /*===========================================================================*
@@ -86,7 +85,7 @@ PRIVATE void dequeue(worker_t *wp, message *m_dst, int *ipc_status)
  */
 
   while (!try_dequeue(wp, m_dst, ipc_status))
-       driver_event_wait(&wp->queue_event);
+       event_wait(&wp->queue_event);
 }
 
 /*===========================================================================*
@@ -102,14 +101,14 @@ PRIVATE void *worker_thread(void *param)
   worker_t *wp;
   message m;
   int ipc_status, r;
+
   wp = (worker_t *) param;
   assert(wp != NULL);
 
   if (mthread_setspecific(worker_key, wp))
-       panic("driver_mt: could not save local thread pointer");
+       panic("blockdriver_mt: could not save local thread pointer");
 
-  while (driver_mt_running) {
+  while (running) {
        /* See if a new message is available right away. */
        if (!try_dequeue(wp, &m, &ipc_status)) {
                /* If not, and this thread should be stopped, stop now. */
@@ -119,7 +118,7 @@ PRIVATE void *worker_thread(void *param)
                /* Otherwise, block waiting for a new message. */
                dequeue(wp, &m, &ipc_status);
 
-               if (!driver_mt_running)
+               if (!running)
                        break;
        }
 
@@ -127,14 +126,14 @@ PRIVATE void *worker_thread(void *param)
        wp->state = STATE_RUNNING;
 
        /* Handle the request, and send a reply. */
-       r = driver_handle_request(driver_cb, &m);
+       r = blockdriver_handle_request(bdtab, &m);
 
-       driver_reply(driver_mt_type, &m, ipc_status, r);
+       blockdriver_reply(&m, ipc_status, r);
   }
 
   /* Clean up and terminate this thread. */
   if (mthread_setspecific(worker_key, NULL))
-       panic("driver_mt: could not delete local thread pointer");
+       panic("blockdriver_mt: could not delete local thread pointer");
 
   wp->state = STATE_EXITED;
 
@@ -156,13 +155,13 @@ PRIVATE void master_create_worker(worker_t *wp, thread_id_t id)
   wp->state = STATE_RUNNING;
 
   /* Initialize synchronization primitives. */
-  driver_event_init(&wp->queue_event);
-  driver_event_init(&wp->sleep_event);
+  event_init(&wp->queue_event);
+  event_init(&wp->sleep_event);
 
   r = mthread_create(&wp->mthread, NULL /*attr*/, worker_thread, (void *) wp);
 
   if (r != 0)
-       panic("driver_mt: could not start thread %d (%d)", id, r);
+       panic("blockdriver_mt: could not start thread %d (%d)", id, r);
 }
 
 /*===========================================================================*
@@ -177,15 +176,15 @@ PRIVATE void master_destroy_worker(worker_t *wp)
 
   assert(wp != NULL);
   assert(wp->state == STATE_EXITED);
-  assert(!driver_mq_dequeue(wp->id, &m, &ipc_status));
+  assert(!mq_dequeue(wp->id, &m, &ipc_status));
 
   /* Join the thread. */
   if (mthread_join(wp->mthread, NULL))
-       panic("driver_mt: could not join thread %d", wp->id);
+       panic("blockdriver_mt: could not join thread %d", wp->id);
 
   /* Destroy resources. */
-  driver_event_destroy(&wp->sleep_event);
-  driver_event_destroy(&wp->queue_event);
+  event_destroy(&wp->sleep_event);
+  event_destroy(&wp->queue_event);
 
   wp->state = STATE_DEAD;
 }
@@ -218,26 +217,24 @@ PRIVATE void master_handle_request(message *m_ptr, int ipc_status)
   worker_t *wp;
   int r;
 
-  /* If this is not a request that has a minor device associated with it, we
-   * can not tell which thread should process it either. In that case, the
-   * master thread has to handle it instead.
+  /* If this is not a block driver request, we cannot get the minor device
+   * associated with it, and thus we can not tell which thread should process
+   * it either. In that case, the master thread has to handle it instead.
    */
-  if (!IS_DEV_MINOR_RQ(m_ptr->m_type)) {
-       if (driver_cb->dr_other)
-               r = (*driver_cb->dr_other)(driver_cb, m_ptr);
-       else
-               r = EINVAL;
+  if (!IS_BDEV_RQ(m_ptr->m_type)) {
+       /* Process as 'other' message. */
+       r = blockdriver_handle_request(bdtab, m_ptr);
 
-       driver_reply(driver_mt_type, m_ptr, ipc_status, r);
+       blockdriver_reply(m_ptr, ipc_status, r);
 
        return;
   }
 
   /* Query the thread ID. Upon failure, send the error code to the caller. */
-  r = driver_cb->dr_thread(m_ptr->DEVICE, &thread_id);
+  r = (*bdtab->bdr_thread)(m_ptr->DEVICE, &thread_id);
 
   if (r != OK) {
-       driver_reply(driver_mt_type, m_ptr, ipc_status, r);
+       blockdriver_reply(m_ptr, ipc_status, r);
 
        return;
   }
@@ -259,19 +256,18 @@ PRIVATE void master_handle_request(message *m_ptr, int ipc_status)
 /*===========================================================================*
  *                             master_init                                  *
  *===========================================================================*/
-PRIVATE void master_init(struct driver *dp, int type)
+PRIVATE void master_init(struct blockdriver *bdp)
 {
 /* Initialize the state of the master thread.
  */
   int i;
 
-  assert(dp != NULL);
-  assert(dp->dr_thread != NULL);
+  assert(bdp != NULL);
+  assert(bdp->bdr_thread != NULL);
 
   mthread_init();
 
-  driver_mt_type = type;
-  driver_cb = dp;
+  bdtab = bdp;
 
   for (i = 0; i < DRIVER_MT_MAX_WORKERS; i++)
        worker[i].state = STATE_DEAD;
@@ -280,13 +276,13 @@ PRIVATE void master_init(struct driver *dp, int type)
    * reference to the worker structure.
    */
   if (mthread_key_create(&worker_key, NULL))
-       panic("driver_mt: error initializing worker key");
+       panic("blockdriver_mt: error initializing worker key");
 }
 
 /*===========================================================================*
- *                             driver_mt_receive                            *
+ *                             blockdriver_mt_receive                       *
  *===========================================================================*/
-PRIVATE void driver_mt_receive(message *m_ptr, int *ipc_status)
+PRIVATE void blockdriver_mt_receive(message *m_ptr, int *ipc_status)
 {
 /* Receive a message.
  */
@@ -295,13 +291,13 @@ PRIVATE void driver_mt_receive(message *m_ptr, int *ipc_status)
   r = sef_receive_status(ANY, m_ptr, ipc_status);
 
   if (r != OK)
-       panic("driver_mt: sef_receive_status() returned %d", r);
+       panic("blockdriver_mt: sef_receive_status() returned %d", r);
 }
 
 /*===========================================================================*
- *                             driver_mt_task                               *
+ *                             blockdriver_mt_task                          *
  *===========================================================================*/
-PUBLIC void driver_mt_task(struct driver *driver_p, int driver_type)
+PUBLIC void blockdriver_mt_task(struct blockdriver *driver_tab)
 {
 /* The multithreaded driver task.
  */
@@ -309,20 +305,20 @@ PUBLIC void driver_mt_task(struct driver *driver_p, int driver_type)
   message mess;
 
   /* Initialize first if necessary. */
-  if (!driver_mt_running) {
-       master_init(driver_p, driver_type);
+  if (!running) {
+       master_init(driver_tab);
 
-       driver_mt_running = TRUE;
+       running = TRUE;
   }
 
   /* The main message loop. */
-  while (driver_mt_running) {
+  while (running) {
        /* Receive a message. */
-       driver_mt_receive(&mess, &ipc_status);
+       blockdriver_mt_receive(&mess, &ipc_status);
 
        /* Dispatch the message. */
        if (is_ipc_notify(ipc_status))
-               driver_handle_notify(driver_cb, &mess);
+               blockdriver_handle_notify(bdtab, &mess);
        else
                master_handle_request(&mess, ipc_status);
 
@@ -336,20 +332,20 @@ PUBLIC void driver_mt_task(struct driver *driver_p, int driver_type)
 }
 
 /*===========================================================================*
- *                             driver_mt_terminate                          *
+ *                             blockdriver_mt_terminate                     *
  *===========================================================================*/
-PUBLIC void driver_mt_terminate(void)
+PUBLIC void blockdriver_mt_terminate(void)
 {
-/* Instruct libdriver to shut down.
+/* Instruct libblockdriver to shut down.
  */
 
-  driver_mt_running = FALSE;
+  running = FALSE;
 }
 
 /*===========================================================================*
- *                             driver_mt_sleep                              *
+ *                             blockdriver_mt_sleep                         *
  *===========================================================================*/
-PUBLIC void driver_mt_sleep(void)
+PUBLIC void blockdriver_mt_sleep(void)
 {
 /* Let the current thread sleep until it gets woken up by the master thread.
  */
@@ -358,15 +354,15 @@ PUBLIC void driver_mt_sleep(void)
   wp = (worker_t *) mthread_getspecific(worker_key);
 
   if (wp == NULL)
-       panic("driver_mt: master thread cannot sleep");
+       panic("blockdriver_mt: master thread cannot sleep");
 
-  driver_event_wait(&wp->sleep_event);
+  event_wait(&wp->sleep_event);
 }
 
 /*===========================================================================*
- *                             driver_mt_wakeup                             *
+ *                             blockdriver_mt_wakeup                        *
  *===========================================================================*/
-PUBLIC void driver_mt_wakeup(thread_id_t id)
+PUBLIC void blockdriver_mt_wakeup(thread_id_t id)
 {
 /* Wake up a sleeping worker thread from the master thread.
  */
@@ -378,13 +374,13 @@ PUBLIC void driver_mt_wakeup(thread_id_t id)
 
   assert(wp->state == STATE_RUNNING || wp->state == STATE_STOPPING);
 
-  driver_event_fire(&wp->sleep_event);
+  event_fire(&wp->sleep_event);
 }
 
 /*===========================================================================*
- *                             driver_mt_stop                               *
+ *                             blockdriver_mt_stop                          *
  *===========================================================================*/
-PUBLIC void driver_mt_stop(void)
+PUBLIC void blockdriver_mt_stop(void)
 {
 /* Put up the current worker thread for termination. Once the current dispatch
  * call has finished, and there are no more messages in the thread's message
@@ -392,7 +388,7 @@ PUBLIC void driver_mt_stop(void)
  * the effect of this call.
  */
   worker_t *wp;
-       
+
   wp = (worker_t *) mthread_getspecific(worker_key);
 
   assert(wp != NULL);
diff --git a/lib/libblockdriver/driver_st.c b/lib/libblockdriver/driver_st.c
new file mode 100644 (file)
index 0000000..b3b225b
--- /dev/null
@@ -0,0 +1,98 @@
+/* This file contains the singlethreaded device driver interface.
+ *
+ * Changes:
+ *   Aug 27, 2011   extracted from driver.c (A. Welzel)
+ *
+ * The entry points into this file are:
+ *   blockdriver_task:         the main message loop of the driver
+ *   blockdriver_terminate:    break out of the main message loop
+ *   blockdriver_handle_msg:   handle a single received message
+ *   blockdriver_receive_mq:   message receive interface with message queueing
+ *   blockdriver_mq_queue:     queue an incoming message for later processing
+ */
+
+#include <minix/drivers.h>
+#include <minix/blockdriver.h>
+
+#include "driver.h"
+#include "mq.h"
+
+PRIVATE int running;
+
+/*===========================================================================*
+ *                            blockdriver_receive_mq                        *
+ *===========================================================================*/
+PUBLIC int blockdriver_receive_mq(message *m_ptr, int *status_ptr)
+{
+/* receive() interface for drivers with message queueing. */
+
+  /* Any queued messages? */
+  if (mq_dequeue(MQ_SINGLE, m_ptr, status_ptr))
+       return OK;
+
+  /* Fall back to standard receive() interface otherwise. */
+  return driver_receive(ANY, m_ptr, status_ptr);
+}
+
+/*===========================================================================*
+ *                             blockdriver_terminate                        *
+ *===========================================================================*/
+PUBLIC void blockdriver_terminate(void)
+{
+/* Break out of the main driver loop after finishing the current request. */
+
+  running = FALSE;
+}
+
+/*===========================================================================*
+ *                             blockdriver_task                                     *
+ *===========================================================================*/
+PUBLIC void blockdriver_task(struct blockdriver *bdp)
+{
+/* Main program of any block device driver task. */
+  int r, ipc_status;
+  message mess;
+
+  running = TRUE;
+
+  /* Here is the main loop of the disk task.  It waits for a message, carries
+   * it out, and sends a reply.
+   */
+  while (running) {
+       if ((r = blockdriver_receive_mq(&mess, &ipc_status)) != OK)
+               panic("blockdriver_receive_mq failed: %d", r);
+
+       blockdriver_process(bdp, &mess, ipc_status);
+  }
+}
+
+/*===========================================================================*
+ *                             blockdriver_process                          *
+ *===========================================================================*/
+PUBLIC void blockdriver_process(struct blockdriver *bdp, message *m_ptr,
+  int ipc_status)
+{
+/* Handle the given received message. */
+  int r;
+
+  /* Process the notification or request. */
+  if (is_ipc_notify(ipc_status)) {
+       blockdriver_handle_notify(bdp, m_ptr);
+
+       /* Do not reply to notifications. */
+  } else {
+       r = blockdriver_handle_request(bdp, m_ptr);
+
+       blockdriver_reply(m_ptr, ipc_status, r);
+  }
+}
+
+/*===========================================================================*
+ *                             blockdriver_mq_queue                         *
+ *===========================================================================*/
+PUBLIC int blockdriver_mq_queue(message *m, int status)
+{
+/* Queue a message for later processing. */
+
+  return mq_enqueue(MQ_SINGLE, m, status);
+}
similarity index 75%
rename from lib/libdriver/drvlib.c
rename to lib/libblockdriver/drvlib.c
index 43869cc05f3b2c2daf71cd6474df7432d48f3a91..94064388a627b84e8111c56471220967dd745f2a 100644 (file)
@@ -4,36 +4,36 @@
  *   partition:        partition a disk to the partition table(s) on it.
  */
 
-#include <minix/driver.h>
+#include <minix/blockdriver.h>
 #include <minix/drvlib.h>
 #include <unistd.h>
 
 /* Extended partition? */
 #define ext_part(s)    ((s) == 0x05 || (s) == 0x0F)
 
-FORWARD _PROTOTYPE( void parse_part_table, (struct driver *dp, int device,
-                               int style, int atapi, u8_t *tmp_buf) );
-FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
-                               unsigned long extbase, u8_t *tmp_buf) );
-FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
+FORWARD _PROTOTYPE( void parse_part_table, (struct blockdriver *bdp,
+       int device, int style, int atapi, u8_t *tmp_buf) );
+FORWARD _PROTOTYPE( void extpartition, (struct blockdriver *bdp, int extdev,
+       unsigned long extbase, u8_t *tmp_buf) );
+FORWARD _PROTOTYPE( int get_part_table, (struct blockdriver *bdp, int device,
        unsigned long offset, struct part_entry *table, u8_t *tmp_buf) );
 FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
 
 /*============================================================================*
  *                             partition                                     *
  *============================================================================*/
-PUBLIC void partition(dp, device, style, atapi)
-struct driver *dp;     /* device dependent entry points */
-int device;            /* device to partition */
-int style;             /* partitioning style: floppy, primary, sub. */
-int atapi;             /* atapi device */
+PUBLIC void partition(bdp, device, style, atapi)
+struct blockdriver *bdp;       /* device dependent entry points */
+int device;                    /* device to partition */
+int style;                     /* partitioning style: floppy, primary, sub. */
+int atapi;                     /* atapi device */
 {
 /* This routine is called on first open to initialize the partition tables
  * of a device.
  */
   u8_t *tmp_buf;
 
-  if ((*dp->dr_prepare)(device) == NULL)
+  if ((*bdp->bdr_part)(device) == NULL)
        return;
 
   /* For multithreaded drivers, multiple partition() calls may be made on
@@ -43,7 +43,7 @@ int atapi;            /* atapi device */
   if (!(tmp_buf = alloc_contig(CD_SECTOR_SIZE, AC_ALIGN4K, NULL)))
        panic("partition: unable to allocate temporary buffer");
 
-  parse_part_table(dp, device, style, atapi, tmp_buf);
+  parse_part_table(bdp, device, style, atapi, tmp_buf);
 
   free_contig(tmp_buf, CD_SECTOR_SIZE);
 }
@@ -51,12 +51,12 @@ int atapi;          /* atapi device */
 /*============================================================================*
  *                             parse_part_table                              *
  *============================================================================*/
-PRIVATE void parse_part_table(dp, device, style, atapi, tmp_buf)
-struct driver *dp;     /* device dependent entry points */
-int device;            /* device to partition */
-int style;             /* partitioning style: floppy, primary, sub. */
-int atapi;             /* atapi device */
-u8_t *tmp_buf;         /* temporary buffer */
+PRIVATE void parse_part_table(bdp, device, style, atapi, tmp_buf)
+struct blockdriver *bdp;       /* device dependent entry points */
+int device;                    /* device to partition */
+int style;                     /* partitioning style: floppy, primary, sub. */
+int atapi;                     /* atapi device */
+u8_t *tmp_buf;                 /* temporary buffer */
 {
 /* This routine reads and parses a partition table.  It may be called
  * recursively.  It makes sure that each partition falls safely within the
@@ -71,13 +71,13 @@ u8_t *tmp_buf;              /* temporary buffer */
   unsigned long base, limit, part_limit;
 
   /* Get the geometry of the device to partition */
-  if ((dv = (*dp->dr_prepare)(device)) == NULL
+  if ((dv = (*bdp->bdr_part)(device)) == NULL
                                || cmp64u(dv->dv_size, 0) == 0) return;
   base = div64u(dv->dv_base, SECTOR_SIZE);
   limit = base + div64u(dv->dv_size, SECTOR_SIZE);
 
   /* Read the partition table for the device. */
-  if(!get_part_table(dp, device, 0L, table, tmp_buf)) {
+  if(!get_part_table(bdp, device, 0L, table, tmp_buf)) {
          return;
   }
 
@@ -97,7 +97,7 @@ u8_t *tmp_buf;                /* temporary buffer */
   }
 
   /* Find an array of devices. */
-  if ((dv = (*dp->dr_prepare)(device)) == NULL) return;
+  if ((dv = (*bdp->bdr_part)(device)) == NULL) return;
 
   /* Set the geometry of the partitions from the partition table. */
   for (par = 0; par < NR_PARTITIONS; par++, dv++) {
@@ -115,12 +115,12 @@ u8_t *tmp_buf;            /* temporary buffer */
        if (style == P_PRIMARY) {
                /* Each Minix primary partition can be subpartitioned. */
                if (pe->sysind == MINIX_PART)
-                       parse_part_table(dp, device + par, P_SUB, atapi,
+                       parse_part_table(bdp, device + par, P_SUB, atapi,
                                tmp_buf);
 
                /* An extended partition has logical partitions. */
                if (ext_part(pe->sysind))
-                       extpartition(dp, device + par, pe->lowsec, tmp_buf);
+                       extpartition(bdp, device + par, pe->lowsec, tmp_buf);
        }
   }
 }
@@ -128,11 +128,11 @@ u8_t *tmp_buf;            /* temporary buffer */
 /*============================================================================*
  *                             extpartition                                  *
  *============================================================================*/
-PRIVATE void extpartition(dp, extdev, extbase, tmp_buf)
-struct driver *dp;     /* device dependent entry points */
-int extdev;            /* extended partition to scan */
-unsigned long extbase; /* sector offset of the base extended partition */
-u8_t *tmp_buf;         /* temporary buffer */
+PRIVATE void extpartition(bdp, extdev, extbase, tmp_buf)
+struct blockdriver *bdp;       /* device dependent entry points */
+int extdev;                    /* extended partition to scan */
+unsigned long extbase;         /* sector offset of the base ext. partition */
+u8_t *tmp_buf;                 /* temporary buffer */
 {
 /* Extended partitions cannot be ignored alas, because people like to move
  * files to and from DOS partitions.  Avoid reading this code, it's no fun.
@@ -148,7 +148,7 @@ u8_t *tmp_buf;              /* temporary buffer */
 
   offset = 0;
   do {
-       if (!get_part_table(dp, extdev, offset, table, tmp_buf)) return;
+       if (!get_part_table(bdp, extdev, offset, table, tmp_buf)) return;
        sort(table);
 
        /* The table should contain one logical partition and optionally
@@ -161,7 +161,7 @@ u8_t *tmp_buf;              /* temporary buffer */
                        nextoffset = pe->lowsec;
                } else
                if (pe->sysind != NO_PART) {
-                       if ((dv = (*dp->dr_prepare)(subdev)) == NULL) return;
+                       if ((dv = (*bdp->bdr_part)(subdev)) == NULL) return;
 
                        dv->dv_base = mul64u(extbase + offset + pe->lowsec,
                                                                SECTOR_SIZE);
@@ -177,8 +177,8 @@ u8_t *tmp_buf;              /* temporary buffer */
 /*============================================================================*
  *                             get_part_table                                *
  *============================================================================*/
-PRIVATE int get_part_table(dp, device, offset, table, tmp_buf)
-struct driver *dp;
+PRIVATE int get_part_table(bdp, device, offset, table, tmp_buf)
+struct blockdriver *bdp;
 int device;
 unsigned long offset;          /* sector offset to the table */
 struct part_entry *table;      /* four entries */
@@ -189,14 +189,14 @@ u8_t *tmp_buf;                    /* temporary buffer */
  */
   iovec_t iovec1;
   u64_t position;
+  int r;
 
   position = mul64u(offset, SECTOR_SIZE);
   iovec1.iov_addr = (vir_bytes) tmp_buf;
   iovec1.iov_size = CD_SECTOR_SIZE;
-  if ((*dp->dr_prepare)(device) != NULL) {
-       (void) (*dp->dr_transfer)(SELF, DEV_GATHER_S, position, &iovec1, 1);
-  }
-  if (iovec1.iov_size != 0) {
+  r = (*bdp->bdr_transfer)(device, FALSE /*do_write*/, position, SELF,
+       &iovec1, 1, BDEV_NOFLAGS);
+  if (r != CD_SECTOR_SIZE) {
        return 0;
   }
   if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) {
similarity index 65%
rename from lib/libdriver/event.c
rename to lib/libblockdriver/event.c
index 5b81951ecbe253d52480bbc1f37d842ee02527d2..87751f57a5ade263acc9c45d0449826410bb0770 100644 (file)
@@ -7,65 +7,65 @@
 #include "event.h"
 
 /*===========================================================================*
- *                             driver_event_init                            *
+ *                             event_init                                   *
  *===========================================================================*/
-PUBLIC void driver_event_init(event_t *event)
+PUBLIC void event_init(event_t *event)
 {
 /* Initialize an event object.
  */
   int r;
 
   if ((r = mthread_mutex_init(&event->mutex, NULL)) != 0)
-       panic("libdriver: error initializing mutex (%d)", r);
+       panic("libblockdriver: error initializing mutex (%d)", r);
   if ((r = mthread_cond_init(&event->cond, NULL)) != 0)
-       panic("libdriver: error initializing condvar (%d)", r);
+       panic("libblockdriver: error initializing condvar (%d)", r);
 }
 
 /*===========================================================================*
- *                             driver_event_destroy                         *
+ *                             event_destroy                                *
  *===========================================================================*/
-PUBLIC void driver_event_destroy(event_t *event)
+PUBLIC void event_destroy(event_t *event)
 {
 /* Destroy an event object.
  */
   int r;
 
   if ((r = mthread_cond_destroy(&event->cond)) != 0)
-       panic("libdriver: error destroying condvar (%d)", r);
+       panic("libblockdriver: error destroying condvar (%d)", r);
   if ((r = mthread_mutex_destroy(&event->mutex)) != 0)
-       panic("libdriver: error destroying mutex (%d)", r);
+       panic("libblockdriver: error destroying mutex (%d)", r);
 }
 
 /*===========================================================================*
- *                             driver_event_wait                            *
+ *                             event_wait                                   *
  *===========================================================================*/
-PUBLIC void driver_event_wait(event_t *event)
+PUBLIC void event_wait(event_t *event)
 {
 /* Wait for an event, blocking the current thread in the process.
  */
   int r;
 
   if ((r = mthread_mutex_lock(&event->mutex)) != 0)
-       panic("libdriver: error locking mutex (%d)", r);
+       panic("libblockdriver: error locking mutex (%d)", r);
   if ((r = mthread_cond_wait(&event->cond, &event->mutex)) != 0)
-       panic("libdriver: error waiting for condvar (%d)", r);
+       panic("libblockdriver: error waiting for condvar (%d)", r);
   if ((r = mthread_mutex_unlock(&event->mutex)) != 0)
-       panic("libdriver: error unlocking mutex (%d)", r);
+       panic("libblockdriver: error unlocking mutex (%d)", r);
 }
 
 /*===========================================================================*
- *                             driver_event_fire                            *
+ *                             event_fire                                   *
  *===========================================================================*/
-PUBLIC void driver_event_fire(event_t *event)
+PUBLIC void event_fire(event_t *event)
 {
 /* Fire an event, waking up any thread blocked on it without scheduling it.
  */
   int r;
 
   if ((r = mthread_mutex_lock(&event->mutex)) != 0)
-       panic("libdriver: error locking mutex (%d)", r);
+       panic("libblockdriver: error locking mutex (%d)", r);
   if ((r = mthread_cond_signal(&event->cond)) != 0)
-       panic("libdriver: error signaling condvar (%d)", r);
+       panic("libblockdriver: error signaling condvar (%d)", r);
   if ((r = mthread_mutex_unlock(&event->mutex)) != 0)
-       panic("libdriver: error unlocking mutex (%d)", r);
+       panic("libblockdriver: error unlocking mutex (%d)", r);
 }
diff --git a/lib/libblockdriver/event.h b/lib/libblockdriver/event.h
new file mode 100644 (file)
index 0000000..cfb0825
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _BLOCKDRIVER_EVENT_H
+#define _BLOCKDRIVER_EVENT_H
+
+typedef struct {
+  mthread_mutex_t mutex;
+  mthread_cond_t cond;
+} event_t;
+
+_PROTOTYPE( void event_init, (event_t *event) );
+_PROTOTYPE( void event_destroy, (event_t *event) );
+_PROTOTYPE( void event_wait, (event_t *event) );
+_PROTOTYPE( void event_fire, (event_t *event) );
+
+#endif /* _BLOCKDRIVER_EVENT_H */
similarity index 83%
rename from lib/libdriver/mq.c
rename to lib/libblockdriver/mq.c
index 300361056292100f43df1bb863ef5b56ac13c433..602fa3b1096f290756dc27d3105e90ea0ba0d707 100644 (file)
@@ -3,10 +3,10 @@
  *
  * Changes:
  *   Oct 27, 2011   rewritten to use sys/queue.h (D.C. van Moolenbroek)
- *   Aug 27, 2011   integrated into libdriver (A. Welzel)
+ *   Aug 27, 2011   integrated into libblockdriver (A. Welzel)
  */
 
-#include <minix/driver_mt.h>
+#include <minix/blockdriver_mt.h>
 #include <sys/queue.h>
 #include <assert.h>
 
@@ -26,11 +26,11 @@ PRIVATE STAILQ_HEAD(queue, mq_cell) queue[DRIVER_MT_MAX_WORKERS];
 PRIVATE STAILQ_HEAD(free_list, mq_cell) free_list;
 
 /*===========================================================================*
- *                             driver_mq_init                               *
+ *                             mq_init                                      *
  *===========================================================================*/
-PUBLIC void driver_mq_init(void)
+PUBLIC void mq_init(void)
 {
-/* Initialize the message queues and message cells. 
+/* Initialize the message queues and message cells.
  */
   int i;
 
@@ -44,9 +44,9 @@ PUBLIC void driver_mq_init(void)
 }
 
 /*===========================================================================*
- *                             driver_mq_enqueue                            *
+ *                             mq_enqueue                                   *
  *===========================================================================*/
-PUBLIC int driver_mq_enqueue(thread_id_t thread_id, const message *mess,
+PUBLIC int mq_enqueue(thread_id_t thread_id, const message *mess,
   int ipc_status)
 {
 /* Add a message, including its IPC status, to the message queue of a thread.
@@ -71,10 +71,9 @@ PUBLIC int driver_mq_enqueue(thread_id_t thread_id, const message *mess,
 }
 
 /*===========================================================================*
- *                             driver_mq_dequeue                            *
+ *                             mq_dequeue                                   *
  *===========================================================================*/
-PUBLIC int driver_mq_dequeue(thread_id_t thread_id, message *mess,
-  int *ipc_status)
+PUBLIC int mq_dequeue(thread_id_t thread_id, message *mess, int *ipc_status)
 {
 /* Return and remove a message, including its IPC status, from the message
  * queue of a thread. Return TRUE iff a message was available.
diff --git a/lib/libblockdriver/mq.h b/lib/libblockdriver/mq.h
new file mode 100644 (file)
index 0000000..7d772e4
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _BLOCKDRIVER_MQ_H
+#define _BLOCKDRIVER_MQ_H
+
+#define MQ_SINGLE      0       /* thread ID for single-threading */
+
+_PROTOTYPE( void mq_init, (void) );
+_PROTOTYPE( int mq_enqueue, (thread_id_t thread_id, const message *mess,
+       int ipc_status) );
+_PROTOTYPE( int mq_dequeue, (thread_id_t thread_id, message *mess,
+       int *ipc_status) );
+
+#endif /* _BLOCKDRIVER_MQ_H */
diff --git a/lib/libchardriver/Makefile b/lib/libchardriver/Makefile
new file mode 100644 (file)
index 0000000..f3f0aa5
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for libchardriver
+.include <bsd.own.mk>
+
+LIB=   chardriver
+
+SRCS=  chardriver.c
+
+.if ${USE_STATECTL} != "no"
+CPPFLAGS+= -DUSE_STATECTL
+.endif
+
+.include <bsd.lib.mk>
similarity index 70%
rename from lib/libdriver/driver.c
rename to lib/libchardriver/chardriver.c
index 08a0fb4f62cd4e46a49a33b56fe0664c7d0266c6..7f6256a340bf0a9114aa299fa97458fcd04942a3 100644 (file)
@@ -1,6 +1,4 @@
-/* This file contains the common part of the device driver interface.
- * In addition, callers get to choose between the singlethreaded API
- * (in driver_st.c) and the multithreaded API (in driver_mt.c).
+/* This file contains the device independent character driver interface.
  *
  * The drivers support the following operations (using message format m2):
  *
  * | DEV_SELECT    | device |   ops   |         |        |        |           |
  * ----------------------------------------------------------------------------
  *
+ * The entry points into this file are:
+ *   driver_task:      the main message loop of the driver
+ *   driver_receive:   message receive interface for drivers
+ *
  * Changes:
- *   Aug 27, 2011   split common functions into driver_common.c (A. Welzel)
+ *   Oct 16, 2011   split character and block protocol  (D.C. van Moolenbroek)
+ *   Aug 27, 2011   move common functions into driver.c  (A. Welzel)
  *   Jul 25, 2005   added SYS_SIG type for signals  (Jorrit N. Herder)
  *   Sep 15, 2004   added SYN_ALARM type for timeouts  (Jorrit N. Herder)
  *   Jul 23, 2004   removed kernel dependencies  (Jorrit N. Herder)
  */
 
 #include <minix/drivers.h>
-#include <sys/ioc_disk.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 #include <minix/ds.h>
 
-#include "driver.h"
-#include "mq.h"
+PRIVATE int running;
 
 /* Management data for opened devices. */
 PRIVATE int open_devs[MAX_NR_OPEN_DEVICES];
@@ -84,9 +85,41 @@ PRIVATE void set_open_dev(int device)
 }
 
 /*===========================================================================*
- *                             asyn_reply                                   *
+ *                             chardriver_announce                          *
+ *===========================================================================*/
+PUBLIC void chardriver_announce(void)
+{
+/* Announce we are up after a fresh start or restart. */
+  int r;
+  char key[DS_MAX_KEYLEN];
+  char label[DS_MAX_KEYLEN];
+  char *driver_prefix = "drv.chr.";
+
+  /* Callers are allowed to use sendrec to communicate with drivers.
+   * For this reason, there may blocked callers when a driver restarts.
+   * Ask the kernel to unblock them (if any).
+   */
+#if USE_STATECTL
+  if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK)
+       panic("chardriver_init: sys_statectl failed: %d", r);
+#endif
+
+  /* Publish a driver up event. */
+  if ((r = ds_retrieve_label_name(label, getprocnr())) != OK)
+       panic("chardriver_init: unable to get own label: %d", r);
+
+  snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label);
+  if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK)
+       panic("chardriver_init: unable to publish driver up event: %d", r);
+
+  /* Expect a DEV_OPEN for any device before serving regular driver requests. */
+  clear_open_devs();
+}
+
+/*===========================================================================*
+ *                             async_reply                                  *
  *===========================================================================*/
-PRIVATE void asyn_reply(message *mess, int r)
+PRIVATE void async_reply(message *mess, int r)
 {
 /* Send a reply using the asynchronous character device protocol. */
   message reply_mess;
@@ -150,9 +183,9 @@ PRIVATE void asyn_reply(message *mess, int r)
 }
 
 /*===========================================================================*
- *                             standard_reply                               *
+ *                             sync_reply                                   *
  *===========================================================================*/
-PRIVATE void standard_reply(message *m_ptr, int ipc_status, int reply)
+PRIVATE void sync_reply(message *m_ptr, int ipc_status, int reply)
 {
 /* Reply to a message sent to the driver. */
   endpoint_t caller_e, user_e;
@@ -176,75 +209,25 @@ PRIVATE void standard_reply(message *m_ptr, int ipc_status, int reply)
 }
 
 /*===========================================================================*
- *                             driver_reply                                 *
+ *                             send_reply                                   *
  *===========================================================================*/
-PUBLIC void driver_reply(int driver_type, message *m_ptr, int ipc_status,
-  int reply)
+PRIVATE void send_reply(int type, message *m_ptr, int ipc_status, int reply)
 {
 /* Prepare and send a reply message. */
 
   if (reply == EDONTREPLY)
        return;
 
-  switch (driver_type) {
-  case DRIVER_STD:
-       standard_reply(m_ptr, ipc_status, reply);
-
-       break;
-
-  case DRIVER_ASYN:
-       asyn_reply(m_ptr, reply);
-
-       break;
-
-  default:
-       panic("unknown driver type: %d", driver_type);
-  }
-}
-
-/*===========================================================================*
- *                             driver_announce                              *
- *===========================================================================*/
-PUBLIC void driver_announce(void)
-{
-/* Announce we are up after a fresh start or restart. */
-  int r;
-  char key[DS_MAX_KEYLEN];
-  char label[DS_MAX_KEYLEN];
-  char *driver_prefix = "drv.vfs.";
-
-  /* Callers are allowed to use sendrec to communicate with drivers.
-   * For this reason, there may blocked callers when a driver restarts.
-   * Ask the kernel to unblock them (if any).
-   */
-#if USE_STATECTL
-  r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS);
-  if (r != OK) {
-       panic("driver_announce: sys_statectl failed: %d\n", r);
-  }
-#endif
-
-  /* Publish a driver up event. */
-  r = ds_retrieve_label_name(label, getprocnr());
-  if (r != OK) {
-       panic("driver_announce: unable to get own label: %d\n", r);
-  }
-  snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label);
-  r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE);
-  if (r != OK) {
-       panic("driver_announce: unable to publish driver up event: %d\n", r);
-  }
-
-  /* Expect a DEV_OPEN for any device before serving regular driver requests. */
-  clear_open_devs();
-
-  driver_mq_init();
+  if (type == CHARDRIVER_ASYNC)
+       async_reply(m_ptr, reply);
+  else
+       sync_reply(m_ptr, ipc_status, reply);
 }
 
 /*===========================================================================*
  *                             do_rdwt                                      *
  *===========================================================================*/
-PRIVATE int do_rdwt(struct driver *dp, message *mp)
+PRIVATE int do_rdwt(struct chardriver *cdp, message *mp)
 {
 /* Carry out a single read or write request. */
   iovec_t iovec1;
@@ -255,7 +238,7 @@ PRIVATE int do_rdwt(struct driver *dp, message *mp)
   if (mp->COUNT < 0) return(EINVAL);
 
   /* Prepare for I/O. */
-  if ((*dp->dr_prepare)(mp->DEVICE) == NULL) return(ENXIO);
+  if ((*cdp->cdr_prepare)(mp->DEVICE) == NULL) return(ENXIO);
 
   /* Create a one element scatter/gather vector for the buffer. */
   if(mp->m_type == DEV_READ_S) opcode = DEV_GATHER_S;
@@ -266,7 +249,8 @@ PRIVATE int do_rdwt(struct driver *dp, message *mp)
 
   /* Transfer bytes from/to the device. */
   position= make64(mp->POSITION, mp->HIGHPOS);
-  r = (*dp->dr_transfer)(mp->m_source, opcode, position, &iovec1, 1);
+  r = (*cdp->cdr_transfer)(mp->m_source, opcode, position, &iovec1, 1,
+       mp->USER_ENDPT);
 
   /* Return the number of bytes transferred or an error code. */
   return(r == OK ? (int) (mp->COUNT - iovec1.iov_size) : r);
@@ -275,7 +259,7 @@ PRIVATE int do_rdwt(struct driver *dp, message *mp)
 /*===========================================================================*
  *                             do_vrdwt                                     *
  *===========================================================================*/
-PRIVATE int do_vrdwt(struct driver *dp, message *mp)
+PRIVATE int do_vrdwt(struct chardriver *cdp, message *mp)
 {
 /* Carry out an device read or write to/from a vector of user addresses.
  * The "user addresses" are assumed to be safe, i.e. FS transferring to/from
@@ -293,22 +277,23 @@ PRIVATE int do_vrdwt(struct driver *dp, message *mp)
   if (nr_req > NR_IOREQS) nr_req = NR_IOREQS;
   iovec_size = (phys_bytes) (nr_req * sizeof(iovec[0]));
 
-  if (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT, 
+  if (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT,
                0, (vir_bytes) iovec, iovec_size, D)) {
        printf("bad I/O vector by: %d\n", mp->m_source);
        return(EINVAL);
   }
 
   /* Prepare for I/O. */
-  if ((*dp->dr_prepare)(mp->DEVICE) == NULL) return(ENXIO);
+  if ((*cdp->cdr_prepare)(mp->DEVICE) == NULL) return(ENXIO);
 
   /* Transfer bytes from/to the device. */
   opcode = mp->m_type;
   position= make64(mp->POSITION, mp->HIGHPOS);
-  r = (*dp->dr_transfer)(mp->m_source, opcode, position, iovec, nr_req);
+  r = (*cdp->cdr_transfer)(mp->m_source, opcode, position, iovec, nr_req,
+       mp->USER_ENDPT);
 
   /* Copy the I/O vector back to the caller. */
-  if (OK != sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT, 
+  if (OK != sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT,
                0, (vir_bytes) iovec, iovec_size, D)) {
        printf("couldn't return I/O vector: %d\n", mp->m_source);
        return(EINVAL);
@@ -318,9 +303,9 @@ PRIVATE int do_vrdwt(struct driver *dp, message *mp)
 }
 
 /*===========================================================================*
- *                             driver_handle_notify                         *
+ *                             handle_notify                                *
  *===========================================================================*/
-PUBLIC void driver_handle_notify(struct driver *dp, message *m_ptr)
+PRIVATE void handle_notify(struct chardriver *cdp, message *m_ptr)
 {
 /* Take care of the notifications (interrupt and clock messages) by calling the
  * appropiate callback functions. Never send a reply.
@@ -328,26 +313,21 @@ PUBLIC void driver_handle_notify(struct driver *dp, message *m_ptr)
 
   /* Call the appropriate function for this notification. */
   switch (_ENDPOINT_P(m_ptr->m_source)) {
-  case HARDWARE:
-       if (dp->dr_hw_int)
-               dp->dr_hw_int(dp, m_ptr);
-       break;
-
   case CLOCK:
-       if (dp->dr_alarm)
-               dp->dr_alarm(dp, m_ptr);
+       if (cdp->cdr_alarm)
+               cdp->cdr_alarm(m_ptr);
        break;
 
   default:
-       if (dp->dr_other)
-               (void) dp->dr_other(dp, m_ptr);
+       if (cdp->cdr_other)
+               (void) cdp->cdr_other(m_ptr);
   }
 }
 
 /*===========================================================================*
- *                             driver_handle_request                        *
+ *                             handle_request                               *
  *===========================================================================*/
-PUBLIC int driver_handle_request(struct driver *dp, message *m_ptr)
+PRIVATE int handle_request(struct chardriver *cdp, message *m_ptr)
 {
 /* Call the appropiate driver function, based on the type of request. Return
  * the result code that is to be sent back to the caller, or EDONTREPLY if no
@@ -359,7 +339,7 @@ PUBLIC int driver_handle_request(struct driver *dp, message *m_ptr)
    * requests on devices that have not previously been opened, signaling the
    * caller that something went wrong.
    */
-  if (IS_DEV_MINOR_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
+  if (IS_CDEV_MINOR_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
        /* Reply ERESTART to spurious requests for unopened devices. */
        if (m_ptr->m_type != DEV_OPEN)
                return ERESTART;
@@ -370,82 +350,94 @@ PUBLIC int driver_handle_request(struct driver *dp, message *m_ptr)
 
   /* Call the appropriate function(s) for this request. */
   switch (m_ptr->m_type) {
-  case DEV_OPEN:       r = (*dp->dr_open)(dp, m_ptr);          break;  
-  case DEV_CLOSE:      r = (*dp->dr_close)(dp, m_ptr);         break;
-  case DEV_IOCTL_S:    r = (*dp->dr_ioctl)(dp, m_ptr);         break;
-  case CANCEL:         r = (*dp->dr_cancel)(dp, m_ptr);        break;
-  case DEV_SELECT:     r = (*dp->dr_select)(dp, m_ptr);        break;
+  case DEV_OPEN:       r = (*cdp->cdr_open)(m_ptr);    break;
+  case DEV_CLOSE:      r = (*cdp->cdr_close)(m_ptr);   break;
+  case DEV_IOCTL_S:    r = (*cdp->cdr_ioctl)(m_ptr);   break;
+  case CANCEL:         r = (*cdp->cdr_cancel)(m_ptr);  break;
+  case DEV_SELECT:     r = (*cdp->cdr_select)(m_ptr);  break;
   case DEV_READ_S:
-  case DEV_WRITE_S:    r = do_rdwt(dp, m_ptr);                 break;
+  case DEV_WRITE_S:    r = do_rdwt(cdp, m_ptr);        break;
   case DEV_GATHER_S:
-  case DEV_SCATTER_S:  r = do_vrdwt(dp, m_ptr);                break;
+  case DEV_SCATTER_S:  r = do_vrdwt(cdp, m_ptr);       break;
   default:
-       if (dp->dr_other)
-               r = dp->dr_other(dp, m_ptr);
+       if (cdp->cdr_other)
+               r = cdp->cdr_other(m_ptr);
        else
                r = EINVAL;
   }
 
   /* Let the driver perform any cleanup. */
-  (*dp->dr_cleanup)();
+  if (cdp->cdr_cleanup)
+       (*cdp->cdr_cleanup)();
 
   return r;
 }
 
 /*===========================================================================*
- *                             no_name                                      *
+ *                             chardriver_process                           *
  *===========================================================================*/
-PUBLIC char *no_name(void)
+PUBLIC void chardriver_process(struct chardriver *cdp, int driver_type,
+  message *m_ptr, int ipc_status)
 {
-/* Use this default name if there is no specific name for the device. This was
- * originally done by fetching the name from the task table for this process: 
- * "return(tasktab[proc_number(proc_ptr) + NR_TASKS].name);", but currently a
- * real "noname" is returned. Perhaps, some system information service can be
- * queried for a name at a later time.
- */
-  static char name[] = "noname";
-  return name;
+/* Handle the given received message. */
+  int r;
+
+  /* Process the notification or request. */
+  if (is_ipc_notify(ipc_status)) {
+       handle_notify(cdp, m_ptr);
+
+       /* Do not reply to notifications. */
+  } else {
+       r = handle_request(cdp, m_ptr);
+
+       send_reply(driver_type, m_ptr, ipc_status, r);
+  }
 }
 
 /*===========================================================================*
- *                             do_nop                                       *
+ *                             chardriver_task                              *
  *===========================================================================*/
-PUBLIC int do_nop(struct driver *UNUSED(dp), message *mp)
+PUBLIC void chardriver_task(struct chardriver *cdp, int driver_type)
 {
-/* Nothing there, or nothing to do. */
-
-  switch (mp->m_type) {
-  case DEV_OPEN:       return(ENODEV);
-  case DEV_CLOSE:      return(OK);
-  case DEV_IOCTL_S:    
-  default:             printf("nop: ignoring code %d\n", mp->m_type);
-                       return(EIO);
+/* Main program of any device driver task. */
+  int r, ipc_status;
+  message mess;
+
+  running = TRUE;
+
+  /* Here is the main loop of the disk task.  It waits for a message, carries
+   * it out, and sends a reply.
+   */
+  while (running) {
+       if ((r = sef_receive_status(ANY, &mess, &ipc_status)) != OK)
+               panic("driver_receive failed: %d", r);
+
+       chardriver_process(cdp, driver_type, &mess, ipc_status);
   }
 }
 
 /*===========================================================================*
- *                             nop_ioctl                                    *
+ *                             do_nop                                       *
  *===========================================================================*/
-PUBLIC int nop_ioctl(struct driver *UNUSED(dp), message *UNUSED(mp))
+PUBLIC int do_nop(message *UNUSED(mp))
 {
-  return(ENOTTY);
+  return(OK);
 }
 
 /*===========================================================================*
- *                             nop_alarm                                    *
+ *                             nop_ioctl                                    *
  *===========================================================================*/
-PUBLIC void nop_alarm(struct driver *UNUSED(dp), message *UNUSED(mp))
+PUBLIC int nop_ioctl(message *UNUSED(mp))
 {
-/* Ignore the leftover alarm. */
+  return(ENOTTY);
 }
 
 /*===========================================================================*
- *                             nop_prepare                                  *
+ *                             nop_alarm                                    *
  *===========================================================================*/
-PUBLIC struct device *nop_prepare(int UNUSED(device))
+PUBLIC void nop_alarm(message *UNUSED(mp))
 {
-/* Nothing to prepare for. */
-  return(NULL);
+/* Ignore the leftover alarm. */
 }
 
 /*===========================================================================*
@@ -459,7 +451,7 @@ PUBLIC void nop_cleanup(void)
 /*===========================================================================*
  *                             nop_cancel                                   *
  *===========================================================================*/
-PUBLIC int nop_cancel(struct driver *UNUSED(dr), message *UNUSED(m))
+PUBLIC int nop_cancel(message *UNUSED(m))
 {
 /* Nothing to do for cancel. */
    return(OK);
@@ -468,52 +460,8 @@ PUBLIC int nop_cancel(struct driver *UNUSED(dr), message *UNUSED(m))
 /*===========================================================================*
  *                             nop_select                                   *
  *===========================================================================*/
-PUBLIC int nop_select(struct driver *UNUSED(dr), message *UNUSED(m))
+PUBLIC int nop_select(message *UNUSED(m))
 {
 /* Nothing to do for select. */
    return(OK);
 }
-
-/*===========================================================================*
- *                             do_diocntl                                   *
- *===========================================================================*/
-PUBLIC int do_diocntl(struct driver *dp, message *mp)
-{
-/* Carry out a partition setting/getting request. */
-  struct device *dv;
-  struct partition entry;
-  unsigned int request;
-  int s;
-
-  request = mp->REQUEST;
-
-  if (request != DIOCSETP && request != DIOCGETP) {
-       if(dp->dr_other)
-               return dp->dr_other(dp, mp);
-       else
-               return(ENOTTY);
-  }
-
-  /* Decode the message parameters. */
-  if ((dv = (*dp->dr_prepare)(mp->DEVICE)) == NULL) return(ENXIO);
-
-  if (request == DIOCSETP) {
-       /* Copy just this one partition table entry. */
-       s=sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT, 
-               0, (vir_bytes) &entry, sizeof(entry), D);
-       if(s != OK)
-           return s;
-       dv->dv_base = entry.base;
-       dv->dv_size = entry.size;
-  } else {
-       /* Return a partition table entry and the geometry of the drive. */
-       entry.base = dv->dv_base;
-       entry.size = dv->dv_size;
-       (*dp->dr_geometry)(&entry);
-       s=sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT, 
-               0, (vir_bytes) &entry, sizeof(entry), D);
-        if (OK != s) 
-           return s;
-  }
-  return(OK);
-}
diff --git a/lib/libdriver/driver.h b/lib/libdriver/driver.h
deleted file mode 100644 (file)
index fe13929..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _DRIVER_DRIVER_H
-#define _DRIVER_DRIVER_H
-
-_PROTOTYPE( void driver_handle_notify, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( int driver_handle_request, (struct driver *dp, message *m_ptr) );
-_PROTOTYPE( void driver_reply, (int driver_type, message *m_ptr,
-       int ipc_status, int reply) );
-
-#endif /* _DRIVER_DRIVER_H */
diff --git a/lib/libdriver/driver_st.c b/lib/libdriver/driver_st.c
deleted file mode 100644 (file)
index b4d0613..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* This file contains the singlethreaded device independent driver interface.
- *
- * Changes:
- *   Aug 27, 2011   extracted from driver.c (A. Welzel)
- *
- * The entry points into this file are:
- *   driver_task:      the main message loop of the driver
- *   driver_terminate: break out of the main message loop
- *   driver_handle_msg:        handle a single received message
- *   driver_receive:   message receive interface for drivers
- *   driver_receive_mq:        message receive interface; try the message queue first
- *   driver_mq_queue:  queue an incoming message for later processing
- */
-
-#include <minix/drivers.h>
-#include <minix/driver.h>
-
-#include "driver.h"
-#include "mq.h"
-
-PUBLIC endpoint_t device_endpt;                /* used externally by log driver */
-PRIVATE int driver_running;
-
-/*===========================================================================*
- *                             driver_receive                               *
- *===========================================================================*/
-PUBLIC int driver_receive(endpoint_t src, message *m_ptr, int *status_ptr)
-{
-/* receive() interface for drivers. */
-
-  return sef_receive_status(src, m_ptr, status_ptr);
-}
-
-/*===========================================================================*
- *                            driver_receive_mq                             *
- *===========================================================================*/
-PUBLIC int driver_receive_mq(message *m_ptr, int *status_ptr)
-{
-/* receive() interface for drivers with message queueing. */
-
-  /* Any queued messages? */
-  if (driver_mq_dequeue(DRIVER_MQ_SINGLE, m_ptr, status_ptr))
-       return OK;
-
-  /* Fall back to standard receive() interface otherwise. */
-  return driver_receive(ANY, m_ptr, status_ptr);
-}
-
-/*===========================================================================*
- *                             driver_terminate                             *
- *===========================================================================*/
-PUBLIC void driver_terminate(void)
-{
-/* Break out of the main driver loop after finishing the current request. */
-
-  driver_running = FALSE;
-}
-
-/*===========================================================================*
- *                             driver_task                                  *
- *===========================================================================*/
-PUBLIC void driver_task(dp, type)
-struct driver *dp;     /* Device dependent entry points. */
-int type;              /* Driver type (DRIVER_STD or DRIVER_ASYN) */
-{
-/* Main program of any device driver task. */
-  int r, ipc_status;
-  message mess;
-
-  driver_running = TRUE;
-
-  /* Here is the main loop of the disk task.  It waits for a message, carries
-   * it out, and sends a reply.
-   */
-  while (driver_running) {
-       if ((r = driver_receive_mq(&mess, &ipc_status)) != OK)
-               panic("driver_receive_mq failed: %d", r);
-
-       driver_handle_msg(dp, type, &mess, ipc_status);
-  }
-}
-
-/*===========================================================================*
- *                             driver_handle_msg                            *
- *===========================================================================*/
-PUBLIC void driver_handle_msg(struct driver *dp, int driver_type,
-  message *m_ptr, int ipc_status)
-{
-/* Handle the given received message. */
-  int r;
-
-  /* Dirty hack: set a global variable for the log driver. */
-  device_endpt = m_ptr->USER_ENDPT;
-
-  /* Process the notification or request. */
-  if (is_ipc_notify(ipc_status)) {
-       driver_handle_notify(dp, m_ptr);
-
-       /* Do not reply to notifications. */
-  } else {
-       r = driver_handle_request(dp, m_ptr);
-
-       driver_reply(driver_type, m_ptr, ipc_status, r);
-  }
-}
-
-/*===========================================================================*
- *                             driver_mq_queue                              *
- *===========================================================================*/
-PUBLIC int driver_mq_queue(message *m, int status)
-{
-/* Queue a message for later processing. */
-
-  return driver_mq_enqueue(DRIVER_MQ_SINGLE, m, status);
-}
diff --git a/lib/libdriver/event.h b/lib/libdriver/event.h
deleted file mode 100644 (file)
index b0b8d75..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _DRIVER_EVENT_H
-#define _DRIVER_EVENT_H
-
-typedef struct {
-  mthread_mutex_t mutex;
-  mthread_cond_t cond;
-} event_t;
-
-_PROTOTYPE( void driver_event_init, (event_t *event) );
-_PROTOTYPE( void driver_event_destroy, (event_t *event) );
-_PROTOTYPE( void driver_event_wait, (event_t *event) );
-_PROTOTYPE( void driver_event_fire, (event_t *event) );
-
-#endif /* _DRIVER_EVENT_H */
diff --git a/lib/libdriver/mq.h b/lib/libdriver/mq.h
deleted file mode 100644 (file)
index e2c8745..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _DRIVER_MQ_H
-#define _DRIVER_MQ_H
-
-#define DRIVER_MQ_SINGLE       0       /* thread ID for single-threading */
-
-_PROTOTYPE( void driver_mq_init, (void) );
-_PROTOTYPE( int driver_mq_enqueue, (thread_id_t thread_id, const message *mess,
-       int ipc_status) );
-_PROTOTYPE( int driver_mq_dequeue, (thread_id_t thread_id, message *mess,
-       int *ipc_status) );
-
-#endif /* _DRIVER_MQ_H */
index b713d2deeca369b3dc1929754fda7bc21ad22279..6c6cbe4d7fb7fd9bdac5223acdd814f268741dc8 100644 (file)
@@ -4,8 +4,8 @@ SRCS=   open.c table.c inode.c main.c super.c link.c \
        buffer.c read.c misc.c mount.c utility.c stadir.c \
        uds.c dev_uds.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+=        ${LIBSYS}
+LDADD+=        -lsys
 
 MAN=
 
index 2f9f4d4ed516d373ccdd38a4d78e20d092e80eb5..73dd0d09fd70e944271e389c596443828839b812 100644 (file)
@@ -135,8 +135,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
   SELF_E = getprocnr();
   buf_pool();
 
-  driver_announce();
-
   return(OK);
 }
 
index b75200a3b80934df6872a06990040942447f930b..c3af865a415ff96ddea3794ad145767910511242 100644 (file)
@@ -2,8 +2,11 @@
  * Special character files also require I/O.  The routines for these are here.
  *
  * The entry points in this file are:
- *   dev_open:   FS opens a device
- *   dev_close:  FS closes a device
+ *   dev_open:   open a character device
+ *   dev_reopen: reopen a character device after a driver crash
+ *   dev_close:  close a character device
+ *   bdev_open:  open a block device
+ *   bdev_close: close a block device
  *   dev_io:    FS does a read or write on a device
  *   dev_status: FS processes callback request alert
  *   gen_opcl:   generic call to a task to perform an open/close
@@ -18,6 +21,7 @@
  */
 
 #include "fs.h"
+#include <string.h>
 #include <fcntl.h>
 #include <assert.h>
 #include <sys/stat.h>
@@ -52,9 +56,10 @@ PUBLIC int dev_open(
   int flags                    /* mode bits and flags */
 )
 {
+/* Open a character device. */
   int major, r;
 
-  /* Determine the major device number call the device class specific
+  /* Determine the major device number so as to call the device class specific
    * open/close routine.  (This is the only routine that must check the
    * device number for being in range.  All others can trust this check.)
    */
@@ -75,7 +80,7 @@ PUBLIC int dev_reopen(
   int flags                    /* mode bits and flags */
 )
 {
-/* Reopen a device after a failing device driver */
+/* Reopen a character device after a failing device driver. */
 
   int major, r;
   struct dmap *dp;
@@ -103,7 +108,7 @@ PUBLIC int dev_close(
   int filp_no
 )
 {
-/* Close a device */
+/* Close a character device. */
   int r, major;
 
   /* See if driver is roughly valid. */
@@ -115,6 +120,90 @@ PUBLIC int dev_close(
 }
 
 
+/*===========================================================================*
+ *                             dev_open                                     *
+ *===========================================================================*/
+PUBLIC int bdev_open(dev_t dev, int access)
+{
+/* Open a block device. */
+  int major;
+
+  major = major(dev);
+  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
+  if (dmap[major].dmap_driver == NONE) return(ENXIO);
+
+  return (*dmap[major].dmap_opcl)(BDEV_OPEN, dev, 0, access);
+}
+
+
+/*===========================================================================*
+ *                             bdev_close                                   *
+ *===========================================================================*/
+PUBLIC int bdev_close(dev_t dev)
+{
+/* Close a block device. */
+  int major;
+
+  major = major(dev);
+  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
+  if (dmap[major].dmap_driver == NONE) return(ENXIO);
+
+  return (*dmap[major].dmap_opcl)(BDEV_CLOSE, dev, 0, 0);
+}
+
+
+/*===========================================================================*
+ *                             bdev_ioctl                                   *
+ *===========================================================================*/
+PRIVATE int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
+{
+/* Perform an I/O control operation on a block device. */
+  struct dmap *dp;
+  u32_t dummy;
+  cp_grant_id_t gid;
+  message dev_mess;
+  int op, major_dev, minor_dev;
+
+  major_dev = major(dev);
+  minor_dev = minor(dev);
+
+  /* Determine task dmap. */
+  dp = &dmap[major_dev];
+  if (dp->dmap_driver == NONE) {
+       printf("VFS: dev_io: no driver for major %d\n", major_dev);
+       return(ENXIO);
+  }
+
+  /* Set up a grant if necessary. */
+  op = VFS_DEV_IOCTL;
+  (void) safe_io_conversion(dp->dmap_driver, &gid, &op, &proc_e, &buf, 0,
+       &dummy);
+
+  /* Set up the message passed to the task. */
+  memset(&dev_mess, 0, sizeof(dev_mess));
+
+  dev_mess.m_type = BDEV_IOCTL;
+  dev_mess.BDEV_MINOR = minor_dev;
+  dev_mess.BDEV_REQUEST = req;
+  dev_mess.BDEV_GRANT = gid;
+  dev_mess.BDEV_ID = 0;
+
+  /* Call the task. */
+  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+
+  /* Clean up. */
+  if (GRANT_VALID(gid)) cpf_revoke(gid);
+
+  if (dp->dmap_driver == NONE) {
+       printf("VFS: block driver gone!?\n");
+       return(EIO);
+  }
+
+  /* Return the result. */
+  return(dev_mess.BDEV_STATUS);
+}
+
+
 /*===========================================================================*
  *                             find_suspended_ep                            *
  *===========================================================================*/
@@ -418,37 +507,47 @@ PUBLIC int dev_io(
  *                             gen_opcl                                     *
  *===========================================================================*/
 PUBLIC int gen_opcl(
-  int op,                      /* operation, DEV_OPEN or DEV_CLOSE */
+  int op,                      /* operation, (B)DEV_OPEN or (B)DEV_CLOSE */
   dev_t dev,                   /* device to open or close */
   endpoint_t proc_e,           /* process to open/close for */
   int flags                    /* mode bits and flags */
 )
 {
 /* Called from the dmap struct on opens & closes of special files.*/
-  int r, minor_dev, major_dev;
+  int r, minor_dev, major_dev, is_bdev;
   struct dmap *dp;
   message dev_mess;
 
   /* Determine task dmap. */
   major_dev = major(dev);
   minor_dev = minor(dev);
-  if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
+  assert(major_dev >= 0 && major_dev < NR_DEVICES);
   dp = &dmap[major_dev];
-  if (dp->dmap_driver == NONE) {
-       printf("VFS: gen_opcl: no driver for major %d\n", major_dev);
-       return(ENXIO);
-  }
+  assert(dp->dmap_driver != NONE);
 
-  dev_mess.m_type   = op;
-  dev_mess.DEVICE   = minor_dev;
-  dev_mess.USER_ENDPT = proc_e;
-  dev_mess.COUNT    = flags;
+  is_bdev = IS_BDEV_RQ(op);
+
+  if (is_bdev) {
+       memset(&dev_mess, 0, sizeof(dev_mess));
+       dev_mess.m_type = op;
+       dev_mess.BDEV_MINOR = minor_dev;
+       dev_mess.BDEV_ACCESS = flags;
+       dev_mess.BDEV_ID = 0;
+  } else {
+       dev_mess.m_type = op;
+       dev_mess.DEVICE = minor_dev;
+       dev_mess.USER_ENDPT = proc_e;
+       dev_mess.COUNT = flags;
+  }
 
   /* Call the task. */
   r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
   if (r != OK) return(r);
 
-  return(dev_mess.REP_STATUS);
+  if (is_bdev)
+       return(dev_mess.BDEV_STATUS);
+  else
+       return(dev_mess.REP_STATUS);
 }
 
 /*===========================================================================*
@@ -466,6 +565,8 @@ PUBLIC int tty_opcl(
   int r;
   register struct fproc *rfp;
 
+  assert(!IS_BDEV_RQ(op));
+
   /* Add O_NOCTTY to the flags if this process is not a session leader, or
    * if it already has a controlling tty, or if it is someone elses
    * controlling tty.
@@ -505,6 +606,8 @@ PUBLIC int ctty_opcl(
  * /dev/tty, the magic device that translates to the controlling tty.
  */
 
+  assert(!IS_BDEV_RQ(op));
+
   return(fp->fp_tty == 0 ? ENXIO : OK);
 }
 
@@ -552,7 +655,10 @@ PUBLIC int do_ioctl()
        suspend_reopen = (f->filp_state != FS_NORMAL);
        dev = (dev_t) vp->v_sdev;
 
-       r = dev_io(VFS_DEV_IOCTL, dev, who_e, m_in.ADDRESS, cvu64(0),
+       if ((vp->v_mode & I_TYPE) == I_BLOCK_SPECIAL)
+               r = bdev_ioctl(dev, who_e, m_in.REQUEST, m_in.ADDRESS);
+       else
+               r = dev_io(VFS_DEV_IOCTL, dev, who_e, m_in.ADDRESS, cvu64(0),
                   m_in.REQUEST, f->filp_flags, suspend_reopen);
   }
 
@@ -572,13 +678,21 @@ message *mess_ptr;                /* pointer to message for task */
 /* All file system I/O ultimately comes down to I/O on major/minor device
  * pairs.  These lead to calls on the following routines via the dmap table.
  */
+  int r, status, proc_e = NONE, is_bdev;
 
-  int r, proc_e;
+  is_bdev = IS_BDEV_RQ(mess_ptr->m_type);
 
-  proc_e = mess_ptr->USER_ENDPT;
+  if (!is_bdev) proc_e = mess_ptr->USER_ENDPT;
 
   r = sendrec(driver_e, mess_ptr);
-  if (r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADEPT;
+  if (r == OK) {
+       if (is_bdev)
+               status = mess_ptr->BDEV_STATUS;
+       else
+               status = mess_ptr->REP_STATUS;
+       if (status == ERESTART)
+               r = EDEADEPT;
+  }
   if (r != OK) {
        if (r == EDEADSRCDST || r == EDEADEPT) {
                printf("VFS: dead driver %d\n", driver_e);
@@ -592,7 +706,7 @@ message *mess_ptr;          /* pointer to message for task */
   }
 
   /* Did the process we did the sendrec() for get a result? */
-  if (mess_ptr->REP_ENDPT != proc_e) {
+  if (!is_bdev && mess_ptr->REP_ENDPT != proc_e) {
        printf("VFS: strange device reply from %d, type = %d, "
                "proc = %d (not %d) (2) ignored\n", mess_ptr->m_source,
                mess_ptr->m_type, proc_e, mess_ptr->REP_ENDPT);
@@ -617,6 +731,8 @@ message *mess_ptr;          /* pointer to message for task */
 
   int r;
 
+  assert(!IS_BDEV_RQ(mess_ptr->m_type));
+
   fp->fp_sendrec = mess_ptr;   /* Remember where result should be stored */
   r = asynsend3(task_nr, mess_ptr, AMF_NOREPLY);
 
@@ -711,15 +827,14 @@ PUBLIC int clone_opcl(
   int r, minor_dev, major_dev;
   message dev_mess;
 
+  assert(!IS_BDEV_RQ(op));
+
   /* Determine task dmap. */
   minor_dev = minor(dev);
   major_dev = major(dev);
-  if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
+  assert(major_dev >= 0 && major_dev < NR_DEVICES);
   dp = &dmap[major_dev];
-  if (dp->dmap_driver == NONE) {
-       printf("VFS clone_opcl: no driver for major %d\n", major_dev);
-       return(ENXIO);
-  }
+  assert(dp->dmap_driver != NONE);
 
   dev_mess.m_type   = op;
   dev_mess.DEVICE   = minor_dev;
@@ -789,23 +904,18 @@ PUBLIC int clone_opcl(
 
 
 /*===========================================================================*
- *                             dev_up                                       *
+ *                             bdev_up                                      *
  *===========================================================================*/
-PUBLIC void dev_up(int maj)
+PUBLIC void bdev_up(int maj)
 {
-  /* A new device driver has been mapped in. This function
-   * checks if any filesystems are mounted on it, and if so,
-   * dev_open()s them so the filesystem can be reused.
-  */
-  int r, new_driver_e, needs_reopen, fd_nr, found;
+  /* A new block device driver has been mapped in. This may affect both mounted
+   * file systems and open block-special files.
+   */
+  int r, new_driver_e, found;
   struct filp *rfilp;
   struct vmnt *vmp;
-  struct fproc *rfp;
   struct vnode *vp;
 
-  /* First deal with block devices. We need to consider both mounted file
-   * systems and open block-special files.
-   */
   if (maj < 0 || maj >= NR_DEVICES) panic("VFS: out-of-bound major");
   new_driver_e = dmap[maj].dmap_driver;
 
@@ -813,10 +923,7 @@ PUBLIC void dev_up(int maj)
    * is currently useless, as driver endpoints do not change across restarts.
    */
   for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
-       int minor_dev, major_dev;
-       major_dev = major(vmp->m_dev);
-       minor_dev = minor(vmp->m_dev);
-       if (major_dev != maj) continue;
+       if (major(vmp->m_dev) != maj) continue;
 
        /* Send the new driver endpoint to the mounted file system. */
        if (OK != req_newdriver(vmp->m_fs_e, vmp->m_dev, new_driver_e))
@@ -834,7 +941,7 @@ PUBLIC void dev_up(int maj)
        if (!S_ISBLK(vp->v_mode)) continue;
 
        /* Reopen the device on the driver, once per filp. */
-       if ((r = dev_open(vp->v_sdev, VFS_PROC_NR, rfilp->filp_mode)) != OK)
+       if ((r = bdev_open(vp->v_sdev, rfilp->filp_mode & O_ACCMODE)) != OK)
                printf("VFS: mounted dev %d/%d re-open failed: %d.\n",
                        maj, minor(vp->v_sdev), r);
 
@@ -851,9 +958,22 @@ PUBLIC void dev_up(int maj)
                printf("VFSdev_up: error sending new driver endpoint."
                       " FS_e: %d req_nr: %d\n", ROOT_FS_E, REQ_NEW_DRIVER);
   }
+}
+
 
-  /* The rest of the code deals with character-special files. To start with,
-   * look for processes that are suspened in an OPEN call. Set FP_SUSP_REOPEN
+/*===========================================================================*
+ *                             cdev_up                                      *
+ *===========================================================================*/
+PUBLIC void cdev_up(int maj)
+{
+  /* A new character device driver has been mapped in.
+  */
+  int needs_reopen, fd_nr;
+  struct filp *rfilp;
+  struct fproc *rfp;
+  struct vnode *vp;
+
+  /* Look for processes that are suspened in an OPEN call. Set FP_SUSP_REOPEN
    * to indicate that this process was suspended before the call to dev_up.
    */
   for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
@@ -884,7 +1004,6 @@ PUBLIC void dev_up(int maj)
 
   if (needs_reopen)
        restart_reopen(maj);
-
 }
 
 /*===========================================================================*
index 687f0c2aa26c12107ff04a8f1f647b2956adb2ef..eb5d13b1b65bcd6b35b38e27f09ec31843475db0 100644 (file)
@@ -232,17 +232,21 @@ PUBLIC int dmap_driver_match(endpoint_t proc, int major)
 /*===========================================================================*
  *                             dmap_endpt_up                                *
  *===========================================================================*/
-PUBLIC void dmap_endpt_up(endpoint_t proc_e)
+PUBLIC void dmap_endpt_up(endpoint_t proc_e, int is_blk)
 {
 /* A device driver with endpoint proc_e has been restarted. Go tell everyone
  * that might be blocking on it that this device is 'up'.
  */
 
   int major;
-  for (major = 0; major < NR_DEVICES; major++)
-       if (dmap_driver_match(proc_e, major))
-               dev_up(major);
-
+  for (major = 0; major < NR_DEVICES; major++) {
+       if (dmap_driver_match(proc_e, major)) {
+               if (is_blk)
+                       bdev_up(major);
+               else
+                       cdev_up(major);
+       }
+  }
 }
 
 /*===========================================================================*
index dd788eaf92d502a2a814e00896895953979fafcd..c6482d2e82557f545dee13da1481008339c92b65 100644 (file)
@@ -521,9 +521,15 @@ struct filp *f;
                        }
                        unlock_bsf();
                }
-               /* Do any special processing on device close. */
-               (void) dev_close(dev, f-filp); /* Ignore any errors, even
-                                                * SUSPEND. */
+
+               /* Do any special processing on device close.
+                * Ignore any errors, even SUSPEND.
+                 */
+               if (mode_word == I_BLOCK_SPECIAL)
+                       (void) bdev_close(dev);
+               else
+                       (void) dev_close(dev, f-filp);
+
                f->filp_mode = FILP_CLOSED;
        }
   }
index e07f66ef629b3ea58562c544967748c64f9e9cb4..a6a1b24cc582eea8d2bd3c011fc4850f336e7d64 100644 (file)
@@ -538,10 +538,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
        }
   }
 
-  /* Subscribe to driver events for VFS drivers. */
-  if ((s = ds_subscribe("drv\\.vfs\\..*", DSF_INITIAL | DSF_OVERWRITE) != OK)){
-       panic("VFS: can't subscribe to driver events (%d)", s);
-  }
+  /* Subscribe to block and character driver events. */
+  s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE);
+  if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s);
 
 #if DO_SANITYCHECKS
   FIXME("VFS: DO_SANITYCHECKS is on");
index 9e5edd2137125291f9dffd8adc27ebfe525c6ab6..84914356359068079789f49754a1fecdf3655953 100644 (file)
@@ -600,28 +600,35 @@ struct mem_map *seg_ptr;
 /*===========================================================================*
  *                              ds_event                                    *
  *===========================================================================*/
-PUBLIC void ds_event()
+PUBLIC void ds_event(void)
 {
   char key[DS_MAX_KEYLEN];
-  char *drv_prefix = "drv.vfs.";
+  char *blkdrv_prefix = "drv.blk.";
+  char *chrdrv_prefix = "drv.chr.";
   u32_t value;
-  int type, r;
+  int type, r, is_blk;
   endpoint_t owner_endpoint;
 
   /* Get the event and the owner from DS. */
-  if ((r = ds_check(key, &type, &owner_endpoint)) != OK) {
-       if(r != ENOENT) printf("VFS: ds_event: ds_check failed: %d\n", r);
-       return;
-  }
-  if ((r = ds_retrieve_u32(key, &value)) != OK) {
-       printf("VFS: ds_event: ds_retrieve_u32 failed\n");
-       return;
-  }
+  while ((r = ds_check(key, &type, &owner_endpoint)) == OK) {
+       /* Only check for block and character driver up events. */
+       if (!strncmp(key, blkdrv_prefix, strlen(blkdrv_prefix))) {
+               is_blk = TRUE;
+       } else if (!strncmp(key, chrdrv_prefix, strlen(chrdrv_prefix))) {
+               is_blk = FALSE;
+       } else {
+               continue;
+       }
 
-  /* Only check for VFS driver up events. */
-  if (strncmp(key, drv_prefix, sizeof(drv_prefix)) || value != DS_DRIVER_UP)
-       return;
+       if ((r = ds_retrieve_u32(key, &value)) != OK) {
+               printf("VFS: ds_event: ds_retrieve_u32 failed\n");
+               return;
+       }
+       if (value != DS_DRIVER_UP) continue;
+
+       /* Perform up. */
+       dmap_endpt_up(owner_endpoint, is_blk);
+  }
 
-  /* Perform up. */
-  dmap_endpt_up(owner_endpoint);
+  if (r != ENOENT) printf("VFS: ds_event: ds_check failed: %d\n", r);
 }
index dd88fed06b1a731e73a623b878768a3450575e04..a85e2b50ac206af212a124dc74a200269cefa9bf 100644 (file)
@@ -169,12 +169,21 @@ PRIVATE int common_open(char path[PATH_MAX], int oflags, mode_t omode)
 
                        /* Invoke the driver for special processing. */
                        dev = (dev_t) vp->v_sdev;
-                       r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE));
+                       r = bdev_open(dev, bits);
                        if (r != OK) {
                                unlock_bsf();
                                break;
                        }
 
+                       major_dev = major(vp->v_sdev);
+                       dp = &dmap[major_dev];
+                       if (dp->dmap_driver == NONE) {
+                               printf("VFS: block driver disappeared!\n");
+                               unlock_bsf();
+                               r = ENXIO;
+                               break;
+                       }
+
                        /* Check whether the device is mounted or not. If so,
                         * then that FS is responsible for this device. Else
                         * we default to ROOT_FS. */
@@ -185,29 +194,21 @@ PRIVATE int common_open(char path[PATH_MAX], int oflags, mode_t omode)
                                        vp->v_bfs_e = vmp->m_fs_e;
                                }
 
-                       /* Get the driver endpoint of the block spec device */
-                       major_dev = major(vp->v_sdev);
-                       if (major_dev < 0 || major_dev >= NR_DEVICES)
-                               r = ENXIO;
-                       else
-                               dp = &dmap[major_dev];
-                       if (r != OK || dp->dmap_driver == NONE) {
-                               printf("VFS: driver not found for device %d\n",
-                                       vp->v_sdev);
-                               r = ENXIO;
-                               unlock_bsf();
-                               break;
-                       }
-
-                       /* Send the driver endpoint (even when known already)*/
+                       /* Send the driver endpoint to the file system that
+                        * will handle the block I/O requests (even when its
+                        * endpoint is known already), but only when it is the
+                        * root file system. Other file systems will already
+                        * have it anyway.
+                        */
                        if (vp->v_bfs_e != ROOT_FS_E) {
-                               /* but only when it's the ROOT_FS */
                                unlock_bsf();
                                break;
                        }
-                       if ((r = req_newdriver(vp->v_bfs_e, vp->v_sdev,
-                                              dp->dmap_driver)) != OK) {
+
+                       if (req_newdriver(vp->v_bfs_e, vp->v_sdev,
+                                              dp->dmap_driver) != OK) {
                                printf("VFS: error sending driver endpoint\n");
+                               bdev_close(dev);
                                r = ENXIO;
                        }
                        unlock_bsf();
index 207ede5932f49d1ecab82426bf53c98c31c5151d..9046f04fc730c374626cb38c5db5f920b096884c 100644 (file)
@@ -29,6 +29,8 @@ _PROTOTYPE(void send_work, (void)                                     );
 _PROTOTYPE( int dev_open, (dev_t dev, endpoint_t proc_e, int flags)    );
 _PROTOTYPE( int dev_reopen, (dev_t dev, int filp_no, int flags)                );
 _PROTOTYPE( int dev_close, (dev_t dev, int filp_no)                    );
+_PROTOTYPE( int bdev_open, (dev_t dev, int access)                     );
+_PROTOTYPE( int bdev_close, (dev_t dev)                                        );
 _PROTOTYPE( int dev_io, (int op, dev_t dev, endpoint_t proc_e, void *buf,
                u64_t pos, size_t bytes, int flags, int suspend_reopen) );
 _PROTOTYPE( int gen_opcl, (int op, dev_t dev, endpoint_t task_nr, int flags));
@@ -43,7 +45,8 @@ _PROTOTYPE( int ctty_io, (int task_nr, message *mess_ptr)             );
 _PROTOTYPE( int do_ioctl, (void)                                       );
 _PROTOTYPE( void pm_setsid, (int proc_e)                               );
 _PROTOTYPE( void dev_status, (message *)                               );
-_PROTOTYPE( void dev_up, (int major)                                   );
+_PROTOTYPE( void bdev_up, (int major)                                  );
+_PROTOTYPE( void cdev_up, (int major)                                  );
 _PROTOTYPE( endpoint_t find_suspended_ep, (endpoint_t driver,
                                           cp_grant_id_t g)             );
 _PROTOTYPE( void reopen_reply, (void)                                  );
@@ -53,7 +56,7 @@ _PROTOTYPE( void open_reply, (void)                                   );
 _PROTOTYPE( int do_mapdriver, (void)                                   );
 _PROTOTYPE( void init_dmap, (void)                                     );
 _PROTOTYPE( int dmap_driver_match, (endpoint_t proc, int major)                );
-_PROTOTYPE( void dmap_endpt_up, (int proc_nr)                          );
+_PROTOTYPE( void dmap_endpt_up, (int proc_nr, int is_blk)              );
 _PROTOTYPE( void dmap_unmap_by_endpt, (int proc_nr)                    );
 _PROTOTYPE( struct dmap *get_dmap, (endpoint_t proc_e)                 );
 _PROTOTYPE( int do_mapdriver, (void)                                   );
index 9fb27ff4fb25ee43d8f14144e89c3243445e9c48..a09e1bd8b19ac2f76b2e1b5cbc0463348d9ad7e1 100644 (file)
@@ -307,7 +307,7 @@ PRIVATE void rw_block(
                printf("Ext2(%d) I/O error on device %d/%d, block %u\n",
                        SELF_E, major(dev), minor(dev), bp->b_blocknr);
                op_failed = 1;
-       } else if( (unsigned) r != fs_block_size) {
+       } else if (r != (ssize_t) fs_block_size) {
                r = END_OF_FILE;
                op_failed = 1;
        }
@@ -387,7 +387,6 @@ PUBLIC void rw_scattered(
   register int i;
   register iovec_t *iop;
   static iovec_t *iovec = NULL;
-  vir_bytes size;
   u64_t pos;
   int j, r;
 
@@ -423,21 +422,22 @@ PUBLIC void rw_scattered(
        }
        pos = mul64u(bufq[0]->b_blocknr, fs_block_size);
        if (rw_flag == READING)
-               r = bdev_gather(dev, pos, iovec, j, BDEV_NOFLAGS, &size);
+               r = bdev_gather(dev, pos, iovec, j, BDEV_NOFLAGS);
        else
-               r = bdev_scatter(dev, pos, iovec, j, BDEV_NOFLAGS, &size);
+               r = bdev_scatter(dev, pos, iovec, j, BDEV_NOFLAGS);
 
-       /* Harvest the results.  Dev_io reports the first error it may have
-        * encountered, but we only care if it's the first block that failed.
+       /* Harvest the results.  The driver may have returned an error, or it
+        * may have done less than what we asked for.
         */
-       for (i = 0, iop = iovec; i < j; i++, iop++) {
+       if (r < 0) {
+               printf("ext2: I/O error %d on device %d/%d, block %u\n",
+                       r, major(dev), minor(dev), bufq[0]->b_blocknr);
+       }
+       for (i = 0; i < j; i++) {
                bp = bufq[i];
-               if (size < iop->iov_size) {
-                       /* Transfer failed. An error? Do we care? */
-                       if (r != OK && i == 0) {
-                               printf(
-                               "fs: I/O error on device %d/%d, block %u\n",
-                                       major(dev), minor(dev), bp->b_blocknr);
+               if (r < (ssize_t) fs_block_size) {
+                       /* Transfer failed. */
+                       if (i == 0) {
                                bp->b_dev = NO_DEV;     /* invalidate block */
                                vm_forgetblocks();
                        }
@@ -449,7 +449,7 @@ PUBLIC void rw_scattered(
                } else {
                        bp->b_dirt = CLEAN;
                }
-               size -= iop->iov_size;
+               r -= fs_block_size;
        }
        bufq += i;
        bufqsize -= i;
index c1fc4279a046a21c664696053a73b48272656ed8..e0377b163d115d3b5f5443b58a67708a095f0950 100644 (file)
@@ -180,7 +180,7 @@ register struct super_block *sp; /* pointer to a superblock */
 
   r = bdev_read(dev, cvu64(gdt_position), (char*) ondisk_group_descs,
        gd_size, BDEV_NOFLAGS);
-  if (r != gd_size) {
+  if (r != (ssize_t) gd_size) {
        printf("Can not read group descriptors\n");
        return(EINVAL);
   }
@@ -251,7 +251,7 @@ struct super_block *sp; /* pointer to a superblock */
 
        r = bdev_write(sp->s_dev, cvu64(gdt_position),
                (char*) ondisk_group_descs, gd_size, BDEV_NOFLAGS);
-       if (r != gd_size) {
+       if (r != (ssize_t) gd_size) {
                printf("Can not write group descriptors\n");
        }
        group_descriptors_dirty = CLEAN;
@@ -275,7 +275,7 @@ struct group_desc* get_group_desc(unsigned int bnum)
 PRIVATE u32_t ext2_count_dirs(struct super_block *sp)
 {
   u32_t count = 0;
-  int i;
+  unsigned int i;
 
   for (i = 0; i < sp->s_groups_count; i++) {
        struct group_desc *desc = get_group_desc(i);
@@ -441,7 +441,7 @@ PRIVATE void copy_group_descriptors(
   unsigned int ngroups
 )
 {
-  int i;
+  unsigned int i;
   for (i = 0; i < ngroups; i++)
        gd_copy(&dest_array[i], &source_array[i]);
 }
index 67ee96a2a2a4a1ddf6f1890b9cb298e1cea3e148..8dbe78db811a6c3b2bdfc9fd4b7a216ae70bdc55 100644 (file)
@@ -12,8 +12,8 @@ SRCS= buf.c clock.c inet.c inet_config.c \
 
 .PATH: ${.CURDIR}/generic
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBMINIXUTIL}
-LDADD+=        -ldriver -lsys -lminixutil
+DPADD+=        ${LIBCHARDRIVER} ${LIBSYS} ${LIBMINIXUTIL}
+LDADD+=        -lchardriver -lsys -lminixutil
 
 MAN=
 
index bd84a54ca751cbb31f2cadfd3ed62c56c61a3a27..82c29019149fc6fd3af108dc630cb79f5fdd5348 100644 (file)
@@ -42,7 +42,7 @@ from DL_ETH:
 #include <sys/svrctl.h>
 #include <minix/ds.h>
 #include <minix/endpoint.h>
-#include <minix/driver.h>
+#include <minix/chardriver.h>
 
 #include "mq.h"
 #include "qp.h"
@@ -282,9 +282,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
        }
 
        /* Announce we are up. INET announces its presence to VFS just like
-        * any other driver.
+        * any other character driver.
         */
-       driver_announce();
+       chardriver_announce();
 
        return(OK);
 }
index b8f1e9a98581cbf0cc7c1081cfe41f0523cebea4..81a5c69365a3aeba4ebf4a405b00ee836c6ec9e6 100644 (file)
@@ -92,7 +92,7 @@ register struct buf *bp;      /* buffer pointer */
 {
   int r;
   u64_t pos;
-  int block_size;
+  vir_bytes block_size;
 
   block_size = v_pri.logical_block_size_l; /* The block size is indicated by
                                            * the superblock */
@@ -100,10 +100,9 @@ register struct buf *bp;   /* buffer pointer */
 
   pos = mul64u(bp->b_blocknr, block_size); /* get absolute position */
   r = bdev_read(fs_dev, pos, bp->b_data, block_size, BDEV_NOFLAGS);
-  if (r != block_size) {
-    if (r >= 0) r = END_OF_FILE;
-    if (r != END_OF_FILE)
-      printf("ISOFS(%d) I/O error on device %d/%d, block %u\n",
+  if (r != (ssize_t) block_size) {
+    if (r == OK) r = END_OF_FILE;
+    else printf("ISOFS(%d) I/O error on device %d/%d, block %u\n",
             SELF_E, (fs_dev>>MAJOR)&BYTE, (fs_dev>>MINOR)&BYTE,
             bp->b_blocknr);
 
index 4d06a045a21ca8b8d902bc4307551120b0f498dc..0847502d46fcb85cceceee3342a4549093daa8e0 100644 (file)
@@ -11,8 +11,8 @@ SRCS= lwip.c          \
 
 .PATH: ${.CURDIR}/generic
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS} ${LIBMINIXUTIL} ${LIBLWIP}
-LDADD+=        -ldriver -lsys -lminixutil -ltimers -llwip
+DPADD+=        ${LIBCHARDRIVER} ${LIBSYS} ${LIBMINIXUTIL} ${LIBTIMERS} ${LIBLWIP}
+LDADD+=        -lchardriver -lsys -lminixutil -ltimers -llwip
 
 MAN=
 
index dbe381b5b1631296786a83d3ccb7c8355b498837..39a2487f7de90891d2119f8c640dd2221744e4d2 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <minix/chardriver.h>
 #include <minix/syslib.h>
 #include <minix/sysutil.h>
 #include <minix/timers.h>
@@ -29,29 +30,6 @@ static int arp_ticks, tcp_fticks, tcp_sticks;
 
 static struct netif * netif_lo;
 
-static void driver_announce()
-{
-       /* Announce we are up after a fresh start or restart. */
-       int err;
-       char key[DS_MAX_KEYLEN];
-       char label[DS_MAX_KEYLEN];
-       char *driver_prefix = "drv.vfs.";
-
-       /* Callers are allowed to use sendrec to communicate with drivers.
-        * For this reason, there may blocked callers when a driver restarts.
-        * Ask the kernel to unblock them (if any).
-        */
-       if ((err = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK)
-               panic("LWIP : sys_statectl failed: %d\n", err);
-
-       /* Publish a driver up event. */
-       if ((err = ds_retrieve_label_name(label, getprocnr())) != OK)
-               panic("LWIP : unable to get own label: %d\n", err);
-       snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label);
-       if ((err = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)))
-               panic("LWIP : unable to publish driver up event: %d\n", err);
-}
-
 void sys_init(void)
 {
 }
@@ -155,10 +133,10 @@ static int sef_cb_init_fresh(__unused int type, __unused sef_init_info_t *info)
                                        DSF_INITIAL | DSF_OVERWRITE)) != OK)
                panic(("inet: can't subscribe to driver events"));
 
-       /* Announce we are up. INET announces its presence to VFS just like
-        * any other driver.
+       /* Announce we are up. LWIP announces its presence to VFS just like
+        * any other character driver.
         */
-       driver_announce();
+       chardriver_announce();
 
        return(OK);
 }
index a4f7c7adb81f7b0049d3de522e55544613e4cb30..3adfec4c982976426debab3020dcb3b9c39eee88 100644 (file)
@@ -345,7 +345,7 @@ int rw_flag;                        /* READING or WRITING */
                printf("MFS(%d) I/O error on device %d/%d, block %u\n",
                SELF_E, major(dev), minor(dev), bp->b_blocknr);
                op_failed = 1;
-       } else if( (unsigned) r != fs_block_size) {
+       } else if (r != (ssize_t) fs_block_size) {
                r = END_OF_FILE;
                op_failed = 1;
        }
@@ -425,7 +425,6 @@ PUBLIC void rw_scattered(
   register int i;
   register iovec_t *iop;
   static iovec_t *iovec = NULL;
-  vir_bytes size;
   u64_t pos;
   int j, r;
 
@@ -461,23 +460,24 @@ PUBLIC void rw_scattered(
        }
        pos = mul64u(bufq[0]->b_blocknr, fs_block_size);
        if (rw_flag == READING)
-               r = bdev_gather(dev, pos, iovec, j, BDEV_NOFLAGS, &size);
+               r = bdev_gather(dev, pos, iovec, j, BDEV_NOFLAGS);
        else
-               r = bdev_scatter(dev, pos, iovec, j, BDEV_NOFLAGS, &size);
+               r = bdev_scatter(dev, pos, iovec, j, BDEV_NOFLAGS);
 
-       /* Harvest the results.  libbdev reports the first error it may have
-        * encountered, but we only care if it's the first block that failed.
+       /* Harvest the results.  The driver may have returned an error, or it
+        * may have done less than what we asked for.
         */
-       for (i = 0, iop = iovec; i < j; i++, iop++) {
+       if (r < 0) {
+               printf("MFS: I/O error %d on device %d/%d, block %u\n",
+                       r, major(dev), minor(dev), bufq[0]->b_blocknr);
+       }
+       for (i = 0; i < j; i++) {
                bp = bufq[i];
-               if (size < iop->iov_size) {
-                       /* Transfer failed. An error? Do we care? */
-                       if (r != OK && i == 0) {
-                               printf(
-                               "MFS: I/O error on device %d/%d, block %u\n",
-                                       major(dev), minor(dev), bp->b_blocknr);
-                               bp->b_dev = NO_DEV;     /* invalidate block */
-                               vm_forgetblocks();
+               if (r < (ssize_t) fs_block_size) {
+                       /* Transfer failed. */
+                       if (i == 0) {
+                               bp->b_dev = NO_DEV;     /* Invalidate block */
+                               vm_forgetblocks();
                        }
                        break;
                }
@@ -487,7 +487,7 @@ PUBLIC void rw_scattered(
                } else {
                        bp->b_dirt = CLEAN;
                }
-               size -= iop->iov_size;
+               r -= fs_block_size;
        }
        bufq += i;
        bufqsize -= i;
index 2d7d244d77da8ed0afa96e81d0452d82e734cbc1..6b1e9a96f33e7898fac25cb7834ab3a00e47ce14 100644 (file)
@@ -102,7 +102,7 @@ PRIVATE void sef_local_startup()
 /*===========================================================================*
  *                         sef_cb_init_fresh                                *
  *===========================================================================*/
-PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
 /* Initialize the Minix file server. */
   int i;
index 0c97d04135eb88ee37ce1656e2772009ab7dee07..d7bc0038d9b86c27a8120b1b56294b978bcdcf5c 100644 (file)
@@ -197,7 +197,7 @@ register struct super_block *sp; /* pointer to a superblock */
   
   r = bdev_read(dev, cvu64(SUPER_BLOCK_BYTES), sbbuf, _MIN_BLOCK_SIZE,
        BDEV_NOFLAGS);
-  if (r != _MIN_BLOCK_SIZE) 
+  if (r != _MIN_BLOCK_SIZE)
        return(EINVAL);
   
   memcpy(sp, sbbuf, sizeof(*sp));
index ac3312ba571a586c4483f874eabee63baf8b6cc1..ff1a9fad7b3276b25a7455323f093b7acf09924b 100644 (file)
@@ -4,8 +4,8 @@ SRCS=   open.c table.c inode.c main.c super.c link.c \
        buffer.c read.c misc.c utility.c stadir.c \
        uds.c dev_uds.c
 
-DPADD+=        ${LIBDRIVER} ${LIBSYS}
-LDADD+=        -ldriver -lsys
+DPADD+=        ${LIBSYS}
+LDADD+=        -lsys
 
 MAN=
 
index af5c47502e26f67ddde758f7e3b583c8f392ecef..b449e1239cd229b617c35e0a092feab470c4786f 100644 (file)
@@ -124,8 +124,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
   SELF_E = getprocnr();
   buf_pool();
 
-  driver_announce();
-
   return(OK);
 }
 
index 8e918482ccba459daabad54c6b5996947f9846de..d53825e46fa62c509d5307efa5e3776edc8d306a 100644 (file)
@@ -2,8 +2,11 @@
  * Special character files also require I/O.  The routines for these are here.
  *
  * The entry points in this file are:
- *   dev_open:   FS opens a device
- *   dev_close:  FS closes a device
+ *   dev_open:   open a character device
+ *   dev_reopen: reopen a character device after a driver crash
+ *   dev_close:  close a character device
+ *   bdev_open:  open a block device
+ *   bdev_close: close a block device
  *   dev_io:    FS does a read or write on a device
  *   dev_status: FS processes callback request alert
  *   gen_opcl:   generic call to a task to perform an open/close
@@ -18,6 +21,7 @@
  */
 
 #include "fs.h"
+#include <string.h>
 #include <fcntl.h>
 #include <assert.h>
 #include <sys/stat.h>
@@ -56,10 +60,11 @@ PUBLIC int dev_open(
   int flags                    /* mode bits and flags */
 )
 {
+/* Open a character device. */
   int major, r;
   struct dmap *dp;
 
-  /* Determine the major device number call the device class specific
+  /* Determine the major device number so as to call the device class specific
    * open/close routine.  (This is the only routine that must check the
    * device number for being in range.  All others can trust this check.)
    */
@@ -81,6 +86,7 @@ PUBLIC int dev_reopen(
   int flags                    /* mode bits and flags */
 )
 {
+/* Reopen a character device after a failing device driver. */
   int major, r;
   struct dmap *dp;
 
@@ -107,6 +113,7 @@ PUBLIC int dev_close(
   int filp_no
 )
 {
+/* Close a character device. */
   int r;
 
   /* See if driver is roughly valid. */
@@ -116,6 +123,90 @@ PUBLIC int dev_close(
 }
 
 
+/*===========================================================================*
+ *                             bdev_open                                    *
+ *===========================================================================*/
+PUBLIC int bdev_open(dev_t dev, int access)
+{
+/* Open a block device. */
+  int major;
+
+  major = major(dev);
+  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
+  if (dmap[major].dmap_driver == NONE) return(ENXIO);
+
+  return (*dmap[major].dmap_opcl)(BDEV_OPEN, dev, 0, access);
+}
+
+
+/*===========================================================================*
+ *                             bdev_close                                   *
+ *===========================================================================*/
+PUBLIC int bdev_close(dev_t dev)
+{
+/* Close a block device. */
+  int major;
+
+  major = major(dev);
+  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
+  if (dmap[major].dmap_driver == NONE) return(ENXIO);
+
+  return (*dmap[major].dmap_opcl)(BDEV_CLOSE, dev, 0, 0);
+}
+
+
+/*===========================================================================*
+ *                             bdev_ioctl                                   *
+ *===========================================================================*/
+PRIVATE int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
+{
+/* Perform an I/O control operation on a block device. */
+  struct dmap *dp;
+  u32_t dummy;
+  cp_grant_id_t gid;
+  message dev_mess;
+  int op, safe, major_dev, minor_dev, vec_grants;
+
+  major_dev = major(dev);
+  minor_dev = minor(dev);
+
+  /* Determine task dmap. */
+  dp = &dmap[major_dev];
+  if (dp->dmap_driver == NONE) {
+       printf("VFS: dev_io: no driver for major %d\n", major_dev);
+       return(ENXIO);
+  }
+
+  /* Set up a grant if necessary. */
+  op = VFS_DEV_IOCTL;
+  safe = safe_io_conversion(dp->dmap_driver, &gid, &op, NULL, 0, &proc_e, &buf,
+       &vec_grants, 0, &dummy);
+
+  /* Set up the message passed to the task. */
+  memset(&dev_mess, 0, sizeof(dev_mess));
+
+  dev_mess.m_type = BDEV_IOCTL;
+  dev_mess.BDEV_MINOR = minor_dev;
+  dev_mess.BDEV_REQUEST = req;
+  dev_mess.BDEV_GRANT = gid;
+  dev_mess.BDEV_ID = 0;
+
+  /* Call the task. */
+  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+
+  /* Clean up. */
+  if (safe) safe_io_cleanup(gid, NULL, vec_grants);
+
+  if (dp->dmap_driver == NONE) {
+       printf("VFS: block driver gone!?\n");
+       return(EIO);
+  }
+
+  /* Return the result. */
+  return dev_mess.BDEV_STATUS;
+}
+
+
 /*===========================================================================*
  *                             suspended_ep                                 *
  *===========================================================================*/
@@ -477,24 +568,34 @@ PUBLIC int dev_io(
  *                             gen_opcl                                     *
  *===========================================================================*/
 PUBLIC int gen_opcl(
-  int op,                      /* operation, DEV_OPEN or DEV_CLOSE */
+  int op,                      /* operation, (B)DEV_OPEN or (B)DEV_CLOSE */
   dev_t dev,                   /* device to open or close */
   int proc_e,                  /* process to open/close for */
   int flags                    /* mode bits and flags */
 )
 {
 /* Called from the dmap struct in table.c on opens & closes of special files.*/
-  int r;
+  int r, is_bdev;
   struct dmap *dp;
   message dev_mess;
 
   /* Determine task dmap. */
-  dp = &dmap[(dev >> MAJOR) & BYTE];
+  dp = &dmap[major(dev)];
 
-  dev_mess.m_type   = op;
-  dev_mess.DEVICE   = (dev >> MINOR) & BYTE;
-  dev_mess.USER_ENDPT = proc_e;
-  dev_mess.COUNT    = flags;
+  is_bdev = IS_BDEV_RQ(op);
+
+  if (is_bdev) {
+       memset(&dev_mess, 0, sizeof(dev_mess));
+       dev_mess.m_type = op;
+       dev_mess.BDEV_MINOR = minor(dev);
+       dev_mess.BDEV_ACCESS = flags;
+       dev_mess.BDEV_ID = 0;
+  } else {
+       dev_mess.m_type = op;
+       dev_mess.DEVICE = minor(dev);
+       dev_mess.USER_ENDPT = proc_e;
+       dev_mess.COUNT = flags;
+  }
 
   if (dp->dmap_driver == NONE) {
        printf("FS: gen_opcl: no driver for dev %x\n", dev);
@@ -505,7 +606,10 @@ PUBLIC int gen_opcl(
   r= (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
   if (r != OK) return(r);
 
-  return(dev_mess.REP_STATUS);
+  if (is_bdev)
+       return(dev_mess.BDEV_STATUS);
+  else
+       return(dev_mess.REP_STATUS);
 }
 
 /*===========================================================================*
@@ -523,6 +627,8 @@ PUBLIC int tty_opcl(
   int r;
   register struct fproc *rfp;
 
+  assert(!IS_BDEV_RQ(op));
+
   /* Add O_NOCTTY to the flags if this process is not a session leader, or
    * if it already has a controlling tty, or if it is someone elses
    * controlling tty.
@@ -561,6 +667,8 @@ PUBLIC int ctty_opcl(
  * /dev/tty, the magic device that translates to the controlling tty.
  */
  
+  assert(!IS_BDEV_RQ(op));
+
   return(fp->fp_tty == 0 ? ENXIO : OK);
 }
 
@@ -604,6 +712,9 @@ PUBLIC int do_ioctl()
   suspend_reopen= (f->filp_state != FS_NORMAL);
   dev = (dev_t) vp->v_sdev;
 
+  if ((vp->v_mode & I_TYPE) == I_BLOCK_SPECIAL)
+       return bdev_ioctl(dev, who_e, m_in.REQUEST, m_in.ADDRESS);
+
   return dev_io(VFS_DEV_IOCTL, dev, who_e, m_in.ADDRESS, cvu64(0),
                m_in.REQUEST, f->filp_flags, suspend_reopen);
 }
@@ -620,18 +731,26 @@ message *mess_ptr;                /* pointer to message for task */
  * pairs.  These lead to calls on the following routines via the dmap table.
  */
 
-  int r, proc_e;
+  int r, status, proc_e, is_bdev;
 
   if(task_nr == SYSTEM) {
        printf("VFS: sending %d to SYSTEM\n", mess_ptr->m_type);
   }
 
-  proc_e = mess_ptr->USER_ENDPT;
+  is_bdev = IS_BDEV_RQ(mess_ptr->m_type);
+
+  if (!is_bdev) proc_e = mess_ptr->USER_ENDPT;
 
   for (;;) {
 
        r = sendrec(task_nr, mess_ptr);
-       if(r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADEPT;
+       if(r == OK) {
+               if (is_bdev)
+                       status = mess_ptr->BDEV_STATUS;
+               else
+                       status = mess_ptr->REP_STATUS;
+               if (status == ERESTART) r = EDEADEPT;
+       }
        if (r != OK) {
                if (r == EDEADSRCDST || r == EDEADEPT) {
                        printf("fs: dead driver %d\n", task_nr);
@@ -646,7 +765,8 @@ message *mess_ptr;          /* pointer to message for task */
        }
 
        /* Did the process we did the sendrec() for get a result? */
-       if (mess_ptr->REP_ENDPT != proc_e && VFS_PROC_NR != proc_e) {
+       if (!is_bdev &&
+               mess_ptr->REP_ENDPT != proc_e && VFS_PROC_NR != proc_e) {
 
                printf("fs: strange device reply from %d, type = %d, "
                "proc = %d (not %d) (2) ignored\n", mess_ptr->m_source, 
@@ -657,6 +777,7 @@ message *mess_ptr;          /* pointer to message for task */
 
        if (mess_ptr->m_type == TASK_REPLY ||
                IS_DEV_RS(mess_ptr->m_type) ||
+               IS_BDEV_RS(mess_ptr->m_type) ||
                mess_ptr->m_type <= 0) {
 
                break; /* reply */
@@ -683,6 +804,8 @@ message *mess_ptr;          /* pointer to message for task */
 
   int r;
 
+  assert(!IS_BDEV_RQ(mess_ptr->m_type));
+
   r = asynsend(task_nr, mess_ptr);
   if (r != OK) panic("asyn_io: asynsend failed: %d", r);
 
@@ -774,6 +897,8 @@ PUBLIC int clone_opcl(
   int r, minor;
   message dev_mess;
 
+  assert(!IS_BDEV_RQ(op));
+
   /* Determine task dmap. */
   dp = &dmap[(dev >> MAJOR) & BYTE];
   minor = (dev >> MINOR) & BYTE;
@@ -844,23 +969,18 @@ PUBLIC int clone_opcl(
 
 
 /*===========================================================================*
- *                             dev_up                                       *
+ *                             bdev_up                                      *
  *===========================================================================*/
-PUBLIC void dev_up(int maj)
+PUBLIC void bdev_up(int maj)
 {
-  /* A new device driver has been mapped in. This function
-   * checks if any filesystems are mounted on it, and if so,
-   * dev_open()s them so the filesystem can be reused.
-  */
-  int r, new_driver_e, needs_reopen, fd_nr, found;
+  /* A new block device driver has been mapped in. This may affect both mounted
+   * file systems and open block-special files.
+   */
+  int r, new_driver_e, found;
   struct filp *fp;
   struct vmnt *vmp;
-  struct fproc *rfp;
   struct vnode *vp;
 
-  /* First deal with block devices. We need to consider both mounted file
-   * systems and open block-special files.
-   */
   new_driver_e = dmap[maj].dmap_driver;
 
   /* Tell each affected mounted file system about the new endpoint. This code
@@ -885,7 +1005,7 @@ PUBLIC void dev_up(int maj)
        if(!S_ISBLK(vp->v_mode)) continue;
 
        /* Reopen the device on the driver, once per filp. */
-       if ((r = dev_open(vp->v_sdev, VFS_PROC_NR, fp->filp_mode)) != OK)
+       if ((r = bdev_open(vp->v_sdev, fp->filp_mode & O_ACCMODE)) != OK)
                printf("VFS: mounted dev %d/%d re-open failed: %d.\n",
                        maj, minor(vp->v_sdev), r);
 
@@ -902,9 +1022,22 @@ PUBLIC void dev_up(int maj)
                printf("VFSdev_up: error sending new driver endpoint."
                       " FS_e: %d req_nr: %d\n", ROOT_FS_E, REQ_NEW_DRIVER);
   }
+}
+
 
-  /* The rest of the code deals with character-special files. To start with,
-   * look for processes that are suspened in an OPEN call. Set SUSP_REOPEN
+/*===========================================================================*
+ *                             cdev_up                                      *
+ *===========================================================================*/
+PUBLIC void cdev_up(int maj)
+{
+  /* A new character device driver has been mapped in.
+   */
+  int needs_reopen, fd_nr;
+  struct filp *fp;
+  struct fproc *rfp;
+  struct vnode *vp;
+
+  /* Look for processes that are suspened in an OPEN call. Set SUSP_REOPEN
    * to indicate that this process was suspended before the call to dev_up.
    */
   for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
@@ -935,7 +1068,6 @@ PUBLIC void dev_up(int maj)
 
   if (needs_reopen)
        restart_reopen(maj);
-
 }
 
 
index 42bc03743b6bed15dd94d6d8101b883d976b3a88..fddb2fb79e0b94efa0c8eb394cdb305b34e2336c 100644 (file)
@@ -232,16 +232,19 @@ PUBLIC int dmap_driver_match(endpoint_t proc, int major)
 /*===========================================================================*
  *                             dmap_endpt_up                                *
  *===========================================================================*/ 
-PUBLIC void dmap_endpt_up(int proc_e)
+PUBLIC void dmap_endpt_up(int proc_e, int is_blk)
 {
        int i;
        for (i=0; i<NR_DEVICES; i++) {
                if(dmap[i].dmap_driver != NONE
                        && dmap[i].dmap_driver == proc_e) {
-                       dev_up(i);
+
+                       if (is_blk)
+                               bdev_up(i);
+                       else
+                               cdev_up(i);
                }
        }
-       return;
 }
 
 /*===========================================================================*
index dbae456824360f6e4297ae2aa526c3f2e3ee2ec7..a8e85dc1b908012866ddc2f27d57bca985398940 100644 (file)
@@ -322,9 +322,14 @@ struct filp *fp;
                                req_flush(vp->v_bfs_e, dev);
                        }
                }
-               /* Do any special processing on device close. */
-               (void) dev_close(dev, fp-filp);
-               /* Ignore any errors, even SUSPEND. */
+
+               /* Do any special processing on device close.
+                * Ignore any errors, even SUSPEND.
+                */
+               if (mode_word == I_BLOCK_SPECIAL)
+                       (void) bdev_close(dev);
+               else
+                       (void) dev_close(dev, fp-filp);
 
                fp->filp_mode = FILP_CLOSED;
        }
index 05c3b035e0c2932cbb5f9c40b1469ddce8afc50f..53a631b15172146abe4a2d146fb7a64b4105b760 100644 (file)
@@ -300,8 +300,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
 
   system_hz = sys_hz();
 
-  /* Subscribe to driver events for VFS drivers. */
-  s = ds_subscribe("drv\\.vfs\\..*", DSF_INITIAL | DSF_OVERWRITE);
+  /* Subscribe to block and character driver events. */
+  s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE);
   if(s != OK) {
        panic("vfs: can't subscribe to driver events");
   }
index 1b406e9fa5a5a436da6bd9e6167f44590aef0af2..e7be635c75c098271b49c18c267a3b0991dd71af 100644 (file)
@@ -618,14 +618,15 @@ char *exe_name;
 /*===========================================================================*
  *                              ds_event                                    *
  *===========================================================================*/
-PUBLIC void ds_event()
+PUBLIC void ds_event(void)
 {
        char key[DS_MAX_KEYLEN];
-       char *driver_prefix = "drv.vfs.";
+       char *blkdrv_prefix = "drv.blk.";
+       char *chrdrv_prefix = "drv.chr.";
        u32_t value;
        int type;
        endpoint_t owner_endpoint;
-       int r;
+       int r, is_blk;
 
        /* Get the event and the owner from DS. */
        r = ds_check(key, &type, &owner_endpoint);
@@ -634,19 +635,24 @@ PUBLIC void ds_event()
                        printf("vfs: ds_event: ds_check failed: %d\n", r);
                return;
        }
+
+       /* Only check for block and character driver up events. */
+       if (!strncmp(key, blkdrv_prefix, strlen(blkdrv_prefix))) {
+               is_blk = TRUE;
+       } else if (!strncmp(key, chrdrv_prefix, strlen(chrdrv_prefix))) {
+               is_blk = FALSE;
+       } else {
+               return;         /* neither block nor character driver */
+       }
+
        r = ds_retrieve_u32(key, &value);
        if(r != OK) {
                printf("vfs: ds_event: ds_retrieve_u32 failed\n");
                return;
        }
-
-       /* Only check for VFS driver up events. */
-       if(strncmp(key, driver_prefix, sizeof(driver_prefix))
-          || value != DS_DRIVER_UP) {
-               return;
-       }
+       if (value != DS_DRIVER_UP) return;
 
        /* Perform up. */
-       dmap_endpt_up(owner_endpoint);
+       dmap_endpt_up(owner_endpoint, is_blk);
 }
 
index d62e5bf4ef3d6e4b03cf5c23f83bf3122dce8a62..f5aa12b1f50bb9b4b217541d9f5c128dcd57ee4e 100644 (file)
@@ -140,7 +140,7 @@ PUBLIC int common_open(register int oflags, mode_t omode)
                   case I_BLOCK_SPECIAL:
                        /* Invoke the driver for special processing. */
                        dev = (dev_t) vp->v_sdev;
-                       r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE));
+                       r = bdev_open(dev, bits);
                        if (r != OK) break;
 
                        /* Check whether the device is mounted or not. If so,
@@ -152,18 +152,15 @@ PUBLIC int common_open(register int oflags, mode_t omode)
                                        vp->v_bfs_e = vmp->m_fs_e;
 
                        /* Get the driver endpoint of the block spec device */
-                       dp = &dmap[(vp->v_sdev >> MAJOR) & BYTE];
-                       if (dp->dmap_driver == NONE) {
-                               printf("VFS: driver not found for device %d\n",
-                                       vp->v_sdev);
-                               r = ENXIO;
-                               break;
-                       }
+                       dp = &dmap[major(vp->v_sdev)];
 
-                       /* Send the driver endpoint (even when known already)*/
+                       /* Send the driver endpoint to the file system (even
+                        * when known already).
+                        */
                        if ((r = req_newdriver(vp->v_bfs_e, vp->v_sdev,
                                               dp->dmap_driver)) != OK) {
                                printf("VFS: error sending driver endpoint\n");
+                               bdev_close(dev);
                                r = ENXIO;
                        }
                        break;
index db95f0020bbe2235586edf48375353058351a5e5..485dc35af710c8c4209c1b0623817df2f12c1626 100644 (file)
@@ -16,6 +16,8 @@ typedef struct filp * filp_id_t;
 _PROTOTYPE( int dev_open, (dev_t dev, int proc, int flags)             );
 _PROTOTYPE( int dev_reopen, (dev_t dev, int filp_no, int flags)                );
 _PROTOTYPE( int dev_close, (dev_t dev, int filp_no)                    );
+_PROTOTYPE( int bdev_open, (dev_t dev, int flags)                      );
+_PROTOTYPE( int bdev_close, (dev_t dev)                                        );
 _PROTOTYPE( int dev_io, (int op, dev_t dev, int proc, void *buf,
                u64_t pos, int bytes, int flags, int suspend_reopen)    );
 _PROTOTYPE( int gen_opcl, (int op, dev_t dev, int proc, int flags)     );
@@ -30,7 +32,8 @@ _PROTOTYPE( int ctty_io, (int task_nr, message *mess_ptr)             );
 _PROTOTYPE( int do_ioctl, (void)                                       );
 _PROTOTYPE( void pm_setsid, (int proc_e)                               );
 _PROTOTYPE( void dev_status, (message *)                               );
-_PROTOTYPE( void dev_up, (int major)                                   );
+_PROTOTYPE( void bdev_up, (int major)                                  );
+_PROTOTYPE( void cdev_up, (int major)                                  );
 _PROTOTYPE( endpoint_t suspended_ep, (endpoint_t driver,
                                                cp_grant_id_t g)        );
 _PROTOTYPE( void reopen_reply, (void)                                  );
@@ -39,7 +42,7 @@ _PROTOTYPE( void reopen_reply, (void)                                 );
 _PROTOTYPE( void build_dmap, (void)                                    );
 _PROTOTYPE( int do_mapdriver, (void)                                   );
 _PROTOTYPE( int dmap_driver_match, (endpoint_t proc, int major)                );
-_PROTOTYPE( void dmap_endpt_up, (int proc_nr)                          );
+_PROTOTYPE( void dmap_endpt_up, (int proc_nr, int is_blk)              );
 _PROTOTYPE( void dmap_unmap_by_endpt, (int proc_nr)                    );
 _PROTOTYPE( struct dmap *get_dmap, (endpoint_t proc_e)                 );
 _PROTOTYPE( int map_driver, (const char *label, int major, endpoint_t proc_nr,
index a1b30e1b7a3949bdb60eb7dadc4ddf52cc6f0039..e5cbffff7f0a9f64a02288a7fa2cdae3b3afb9bb 100644 (file)
@@ -58,8 +58,8 @@ MKDEP_SUFFIXES?=      .o .ln
 #      rumpfs_lfs rumpfs_msdosfs rumpfs_nfs rumpfs_ntfs rumpfs_syspuffs \
 #      rumpfs_tmpfs rumpfs_udf rumpfs_ufs
 .for _lib in \
-       c curses driver netdriver edit end m sys timers util bz2 l hgfs \
-       audiodriver exec ddekit devman usb elf
+       c curses blockdriver chardriver netdriver edit end m sys timers util \
+       bz2 l hgfs audiodriver exec ddekit devman usb elf bdev
 .ifndef LIB${_lib:tu}
 LIB${_lib:tu}= ${DESTDIR}/usr/lib/lib${_lib}.a
 .if ${COMPILER_TYPE} == "ack"
index 698e59bfe6ce48d18aa580c82d1a30bae4d22998..2f82953878d22b67ff901c44e90cbf9158fc0e28 100644 (file)
@@ -1,7 +1,7 @@
 /* Block Device Driver Test driver, by D.C. van Moolenbroek */
 #include <stdlib.h>
 #include <sys/stat.h>
-#include <minix/driver.h>
+#include <minix/blockdriver.h>
 #include <minix/drvlib.h>
 #include <minix/dmap.h>
 #include <minix/sysinfo.h>
@@ -18,10 +18,9 @@ enum {
        RESULT_OK,                      /* exactly as expected */
        RESULT_COMMFAIL,                /* communication failed */
        RESULT_BADTYPE,                 /* bad type in message */
-       RESULT_BADENDPT,                /* bad endpoint in message */
+       RESULT_BADID,                   /* bad request ID in message */
        RESULT_BADSTATUS,               /* bad/unexpected status in message */
        RESULT_TRUNC,                   /* request truncated unexpectedly */
-       RESULT_TOUCHED,                 /* result iovec changed unexpectedly */
        RESULT_CORRUPT,                 /* buffer touched erroneously */
        RESULT_MISSING,                 /* buffer left untouched erroneously */
        RESULT_OVERFLOW,                /* area around buffer touched */
@@ -37,7 +36,6 @@ PRIVATE char device_path[PATH_MAX];   /* path to device node to use */
 PRIVATE char driver_label[LABEL_MAX];  /* driver DS label */
 PRIVATE dev_t driver_minor;            /* driver's partition minor to use */
 PRIVATE endpoint_t driver_endpt;       /* driver endpoint */
-PRIVATE endpoint_t my_endpt;           /* this process's endpoint */
 
 PRIVATE int may_write = FALSE;         /* may we write to the device? */
 PRIVATE int sector_size = 512;         /* size of a single disk sector */
@@ -110,8 +108,8 @@ PRIVATE void got_result(result_t *res, char *desc)
        case RESULT_BADTYPE:
                printf("- bad type %d in reply message\n", res->value);
                break;
-       case RESULT_BADENDPT:
-               printf("- bad endpoint %u in reply message\n", res->value);
+       case RESULT_BADID:
+               printf("- mismatched ID %d in reply message\n", res->value);
                break;
        case RESULT_BADSTATUS:
                printf("- bad or unexpected status %d in reply message\n",
@@ -121,9 +119,6 @@ PRIVATE void got_result(result_t *res, char *desc)
                printf("- result size not as expected (%u bytes left)\n",
                        res->value);
                break;
-       case RESULT_TOUCHED:
-               printf("- resulting I/O vector changed unexpectedly\n");
-               break;
        case RESULT_CORRUPT:
                printf("- buffer has been modified erroneously\n");
                break;
@@ -158,10 +153,11 @@ PRIVATE void reopen_device(dev_t minor)
         */
        message m;
 
-       m.m_type = DEV_OPEN;
-       m.DEVICE = minor;
-       m.USER_ENDPT = my_endpt;
-       m.COUNT = (may_write) ? (R_BIT | W_BIT) : R_BIT;
+       memset(&m, 0, sizeof(m));
+       m.m_type = BDEV_OPEN;
+       m.BDEV_MINOR = minor;
+       m.BDEV_ACCESS = (may_write) ? (R_BIT | W_BIT) : R_BIT;
+       m.BDEV_ID = 0;
 
        (void) sendrec(driver_endpt, &m);
 }
@@ -185,14 +181,13 @@ PRIVATE int sendrec_driver(message *m_ptr, ssize_t exp, result_t *res)
                if (r != OK)
                        return set_result(res, RESULT_COMMFAIL, r);
 
-               if (m_ptr->m_type != TASK_REPLY)
+               if (m_ptr->m_type != BDEV_REPLY)
                        return set_result(res, RESULT_BADTYPE, m_ptr->m_type);
 
-               if (m_ptr->REP_ENDPT != m_orig.USER_ENDPT)
-                       return set_result(res, RESULT_BADENDPT,
-                               m_ptr->REP_ENDPT);
+               if (m_ptr->BDEV_ID != m_orig.BDEV_ID)
+                       return set_result(res, RESULT_BADID, m_ptr->BDEV_ID);
 
-               if (m_ptr->REP_STATUS != ERESTART) break;
+               if (m_ptr->BDEV_STATUS != ERESTART) break;
 
                /* The driver has died. Reopen all devices that we opened
                 * earlier, and resend the request. Up to three times.
@@ -212,9 +207,9 @@ PRIVATE int sendrec_driver(message *m_ptr, ssize_t exp, result_t *res)
                exit(1);
        }
 
-       if ((exp < 0 && m_ptr->REP_STATUS == 0) ||
-                       (exp >= 0 && m_ptr->REP_STATUS != 0))
-               return set_result(res, RESULT_BADSTATUS, m_ptr->REP_STATUS);
+       if ((exp < 0 && m_ptr->BDEV_STATUS >= 0) ||
+                       (exp >= 0 && m_ptr->BDEV_STATUS < 0))
+               return set_result(res, RESULT_BADSTATUS, m_ptr->BDEV_STATUS);
 
        return set_result(res, RESULT_OK, 0);
 }
@@ -225,29 +220,24 @@ PRIVATE int raw_xfer(dev_t minor, u64_t pos, iovec_s_t *iovec, int nr_req,
        /* Perform a transfer with a safecopy iovec already supplied.
         */
        cp_grant_id_t grant;
-       iovec_s_t iov_orig[NR_IOREQS];
        message m;
-       ssize_t left;
-       int i, r;
+       int r;
 
        assert(nr_req <= NR_IOREQS);
        assert(!write || may_write);
 
-       memcpy(iov_orig, iovec, sizeof(*iovec) * nr_req);
-
        if ((grant = cpf_grant_direct(driver_endpt, (vir_bytes) iovec,
-                       sizeof(*iovec) * nr_req, CPF_READ | CPF_WRITE)) ==
-                       GRANT_INVALID)
+                       sizeof(*iovec) * nr_req, CPF_READ)) == GRANT_INVALID)
                panic("unable to allocate grant");
 
        memset(&m, 0, sizeof(m));
-       m.m_type = write ? DEV_SCATTER_S : DEV_GATHER_S;
-       m.DEVICE = minor;
-       m.POSITION = ex64lo(pos);
-       m.HIGHPOS = ex64hi(pos);
-       m.COUNT = nr_req;
-       m.USER_ENDPT = my_endpt;
-       m.IO_GRANT = (void *) grant;
+       m.m_type = write ? BDEV_SCATTER : BDEV_GATHER;
+       m.BDEV_MINOR = minor;
+       m.BDEV_POS_LO = ex64lo(pos);
+       m.BDEV_POS_HI = ex64hi(pos);
+       m.BDEV_COUNT = nr_req;
+       m.BDEV_GRANT = grant;
+       m.BDEV_ID = rand();
 
        r = sendrec_driver(&m, exp, res);
 
@@ -257,38 +247,8 @@ PRIVATE int raw_xfer(dev_t minor, u64_t pos, iovec_s_t *iovec, int nr_req,
        if (r != RESULT_OK)
                return r;
 
-       if (exp >= 0) {
-               left = exp;
-
-               for (i = 0; i < nr_req; i++) {
-                       if (iov_orig[i].iov_grant != iovec[i].iov_grant) {
-                               /* Don't panic because we can't free them. */
-                               for ( ; i < nr_req; i++)
-                                       iovec[i].iov_grant =
-                                               iov_orig[i].iov_grant;
-
-                               return set_result(res, RESULT_TOUCHED, 0);
-                       }
-
-                       if ((left == 0 &&
-                               iov_orig[i].iov_size != iovec[i].iov_size) ||
-                               ((vir_bytes) left >= iov_orig[i].iov_size &&
-                               iovec[i].iov_size != 0) ||
-                               ((vir_bytes) left < iov_orig[i].iov_size &&
-                               iov_orig[i].iov_size - iovec[i].iov_size >
-                               (vir_bytes) left)) {
-
-                               return set_result(res, RESULT_TRUNC, left);
-                       }
-
-                       left -= iov_orig[i].iov_size - iovec[i].iov_size;
-               }
-
-               /* do we need this? */
-               if (left != 0) return set_result(res, RESULT_TRUNC, left);
-       }
-       else if (memcmp(iovec, iov_orig, sizeof(*iovec) * nr_req))
-               return set_result(res, RESULT_TOUCHED, 0);
+       if (m.BDEV_STATUS != exp)
+               return set_result(res, RESULT_TRUNC, exp - m.BDEV_STATUS);
 
        return r;
 }
@@ -382,20 +342,20 @@ PRIVATE void bad_read1(void)
        alloc_buf_and_grant(&buf_ptr, &grant2, buf_size, CPF_WRITE);
 
        if ((grant = cpf_grant_direct(driver_endpt, (vir_bytes) &iov,
-                       sizeof(iov), CPF_READ | CPF_WRITE)) == GRANT_INVALID)
+                       sizeof(iov), CPF_READ)) == GRANT_INVALID)
                panic("unable to allocate grant");
 
        /* Initialize the defaults for some of the tests.
         * This is a legitimate request for the first block of the partition.
         */
        memset(&mt, 0, sizeof(mt));
-       mt.m_type = DEV_GATHER_S;
-       mt.DEVICE = driver_minor;
-       mt.POSITION = 0L;
-       mt.HIGHPOS = 0L;
-       mt.COUNT = 1;
-       mt.USER_ENDPT = my_endpt;
-       mt.IO_GRANT = (void *) grant;
+       mt.m_type = BDEV_GATHER;
+       mt.BDEV_MINOR = driver_minor;
+       mt.BDEV_POS_LO = 0L;
+       mt.BDEV_POS_HI = 0L;
+       mt.BDEV_COUNT = 1;
+       mt.BDEV_GRANT = grant;
+       mt.BDEV_ID = rand();
 
        memset(&iovt, 0, sizeof(iovt));
        iovt.iov_grant = grant2;
@@ -407,9 +367,9 @@ PRIVATE void bad_read1(void)
 
        sendrec_driver(&m, OK, &res);
 
-       if (res.type == RESULT_OK && iov.iov_size != 0) {
+       if (res.type == RESULT_OK && m.BDEV_STATUS != (ssize_t) iov.iov_size) {
                res.type = RESULT_TRUNC;
-               res.value = iov.iov_size;
+               res.value = m.BDEV_STATUS;
        }
 
        got_result(&res, "normal request");
@@ -418,7 +378,7 @@ PRIVATE void bad_read1(void)
        m = mt;
        iov = iovt;
 
-       m.COUNT = 0;
+       m.BDEV_COUNT = 0;
 
        sendrec_driver(&m, EINVAL, &res);
 
@@ -427,7 +387,7 @@ PRIVATE void bad_read1(void)
        /* Test bad iovec grant. */
        m = mt;
 
-       m.IO_GRANT = (void *) GRANT_INVALID;
+       m.BDEV_GRANT = GRANT_INVALID;
 
        sendrec_driver(&m, EINVAL, &res);
 
@@ -438,42 +398,26 @@ PRIVATE void bad_read1(void)
        iov = iovt;
 
        if ((grant3 = cpf_grant_direct(driver_endpt, (vir_bytes) &iov,
-                       sizeof(iov), CPF_READ | CPF_WRITE)) == GRANT_INVALID)
+                       sizeof(iov), CPF_READ)) == GRANT_INVALID)
                panic("unable to allocate grant");
 
        cpf_revoke(grant3);
 
-       m.IO_GRANT = (void *) grant3;
+       m.BDEV_GRANT = grant3;
 
        sendrec_driver(&m, EINVAL, &res);
 
        got_result(&res, "revoked iovec grant");
 
-       /* Test read-only iovec grant. */
-       m = mt;
-       iov = iovt;
-
-       if ((grant3 = cpf_grant_direct(driver_endpt, (vir_bytes) &iov,
-                       sizeof(iov), CPF_READ)) == GRANT_INVALID)
-               panic("unable to allocate grant");
-
-       m.IO_GRANT = (void *) grant3;
-
-       sendrec_driver(&m, EINVAL, &res);
-
-       got_result(&res, "read-only iovec grant");
-
-       cpf_revoke(grant3);
-
        /* Test normal request (final check). */
        m = mt;
        iov = iovt;
 
        sendrec_driver(&m, OK, &res);
 
-       if (res.type == RESULT_OK && iov.iov_size != 0) {
+       if (res.type == RESULT_OK && m.BDEV_STATUS != (ssize_t) iov.iov_size) {
                res.type = RESULT_TRUNC;
-               res.value = iov.iov_size;
+               res.value = m.BDEV_STATUS;
        }
 
        got_result(&res, "normal request");
@@ -1036,10 +980,11 @@ PRIVATE void open_device(dev_t minor)
        message m;
        result_t res;
 
-       m.m_type = DEV_OPEN;
-       m.DEVICE = minor;
-       m.USER_ENDPT = my_endpt;
-       m.COUNT = (may_write) ? (R_BIT | W_BIT) : R_BIT;
+       memset(&m, 0, sizeof(m));
+       m.m_type = BDEV_OPEN;
+       m.BDEV_MINOR = minor;
+       m.BDEV_ACCESS = may_write ? (R_BIT | W_BIT) : R_BIT;
+       m.BDEV_ID = rand();
 
        sendrec_driver(&m, OK, &res);
 
@@ -1062,10 +1007,10 @@ PRIVATE void close_device(dev_t minor)
        result_t res;
        int i;
 
-       m.m_type = DEV_CLOSE;
-       m.DEVICE = minor;
-       m.USER_ENDPT = my_endpt;
-       m.COUNT = 0;
+       memset(&m, 0, sizeof(m));
+       m.m_type = BDEV_CLOSE;
+       m.BDEV_MINOR = minor;
+       m.BDEV_ID = rand();
 
        sendrec_driver(&m, OK, &res);
 
@@ -1100,13 +1045,14 @@ PRIVATE int vir_ioctl(dev_t minor, int req, void *ptr, ssize_t exp,
                        _MINIX_IOCTL_SIZE(req), perm)) == GRANT_INVALID)
                panic("unable to allocate grant");
 
-       m.m_type = DEV_IOCTL_S;
-       m.DEVICE = minor;
-       m.POSITION = 0L;
-       m.HIGHPOS = 0L;
-       m.REQUEST = req;
-       m.USER_ENDPT = my_endpt;
-       m.IO_GRANT = (void *) grant;
+       memset(&m, 0, sizeof(m));
+       m.m_type = BDEV_IOCTL;
+       m.BDEV_MINOR = minor;
+       m.BDEV_POS_LO = 0L;
+       m.BDEV_POS_HI = 0L;
+       m.BDEV_REQUEST = req;
+       m.BDEV_GRANT = grant;
+       m.BDEV_ID = rand();
 
        r = sendrec_driver(&m, exp, res);
 
@@ -2662,17 +2608,9 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 {
        /* Initialize.
         */
-       char name[32];
-       int r, flags;
+       int r;
        clock_t now;
 
-       /* Get my own endpoint, to use as grant owner. This means that we
-        * cannot test whether a driver correctly distinguishes between senders
-        * and grant holders.
-        */
-       if ((r = sys_whoami(&my_endpt, name, sizeof(name), &flags)) != OK)
-               panic("whoami failed: %d", r);
-
        if (env_argc > 1)
                optset_parse(optset_table, env_argv[1]);