diff --git a/common/include/Makefile.inc b/common/include/Makefile.inc index 25df3fa0a..81be73c6a 100644 --- a/common/include/Makefile.inc +++ b/common/include/Makefile.inc @@ -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 \ diff --git a/common/include/minix/audio_fw.h b/common/include/minix/audio_fw.h index d13126714..e93201ff2 100644 --- a/common/include/minix/audio_fw.h +++ b/common/include/minix/audio_fw.h @@ -2,7 +2,7 @@ #define AUDIO_FW_H #include -#include +#include #include diff --git a/common/include/minix/bdev.h b/common/include/minix/bdev.h index e0ef8067c..827f29399 100644 --- a/common/include/minix/bdev.h +++ b/common/include/minix/bdev.h @@ -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 index 000000000..2d212ec08 --- /dev/null +++ b/common/include/minix/blockdriver.h @@ -0,0 +1,54 @@ +#ifndef _MINIX_BLOCKDRIVER_H +#define _MINIX_BLOCKDRIVER_H + +#include + +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 index 000000000..143660f46 --- /dev/null +++ b/common/include/minix/blockdriver_mt.h @@ -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 + +/* 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 index 000000000..fe3f64d79 --- /dev/null +++ b/common/include/minix/chardriver.h @@ -0,0 +1,41 @@ +#ifndef _MINIX_CHARDRIVER_H +#define _MINIX_CHARDRIVER_H + +#include + +/* 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 */ diff --git a/common/include/minix/com.h b/common/include/minix/com.h index dad34cf16..d3d5d2809 100644 --- a/common/include/minix/com.h +++ b/common/include/minix/com.h @@ -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. */ @@ -182,12 +183,12 @@ /*===========================================================================* - * 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 */ @@ -215,7 +216,7 @@ #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 */ @@ -225,7 +226,7 @@ #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 */ @@ -1216,4 +1217,43 @@ #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 */ diff --git a/common/include/minix/devio.h b/common/include/minix/devio.h index f654a0ae1..8a2b3c8fe 100644 --- a/common/include/minix/devio.h +++ b/common/include/minix/devio.h @@ -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 ")"); \ } \ diff --git a/common/include/minix/driver.h b/common/include/minix/driver.h index 0e770c16c..1b9602d11 100644 --- a/common/include/minix/driver.h +++ b/common/include/minix/driver.h @@ -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 */ @@ -21,36 +19,13 @@ #include #include #include - #include #include #include #include #include - -#include #include - -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 /* 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 index 05c10f197..000000000 --- a/common/include/minix/driver_mt.h +++ /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 - -/* 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 */ diff --git a/common/include/minix/drvlib.h b/common/include/minix/drvlib.h index 013eca857..f83b7f369 100644 --- a/common/include/minix/drvlib.h +++ b/common/include/minix/drvlib.h @@ -4,19 +4,9 @@ #include -_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 diff --git a/common/include/minix/ipc.h b/common/include/minix/ipc.h index 8ce24a479..5f166346c 100644 --- a/common/include/minix/ipc.h +++ b/common/include/minix/ipc.h @@ -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). * *==========================================================================*/ diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 11beadb54..bfdc49357 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -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 diff --git a/drivers/ahci/Makefile b/drivers/ahci/Makefile index 336bd1bdb..3484b5b3e 100644 --- a/drivers/ahci/Makefile +++ b/drivers/ahci/Makefile @@ -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= diff --git a/drivers/ahci/ahci.c b/drivers/ahci/ahci.c index bb2267411..675d95e80 100644 --- a/drivers/ahci/ahci.c +++ b/drivers/ahci/ahci.c @@ -104,7 +104,7 @@ * vectors completely filled with 64KB-blocks. */ #include -#include +#include #include #include #include @@ -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; + if (r != OK) 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; - } - - 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 = ¤t_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 = ¤t_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(minor); - ps = ahci_get_port(m->DEVICE); - - 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; } diff --git a/drivers/amddev/Makefile b/drivers/amddev/Makefile index 731336a9b..c5ab636ed 100644 --- a/drivers/amddev/Makefile +++ b/drivers/amddev/Makefile @@ -2,8 +2,8 @@ PROG= amddev SRCS= amddev.c -DPADD+= ${LIBDRIVER} ${LIBSYS} -LDADD+= -ldriver -lsys +DPADD+= ${LIBSYS} +LDADD+= -lsys MAN= diff --git a/drivers/amddev/amddev.c b/drivers/amddev/amddev.c index 8f9528f24..30fb4b7fe 100644 --- a/drivers/amddev/amddev.c +++ b/drivers/amddev/amddev.c @@ -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; } diff --git a/drivers/at_wini/Makefile b/drivers/at_wini/Makefile index 25aece4c6..19556a45e 100644 --- a/drivers/at_wini/Makefile +++ b/drivers/at_wini/Makefile @@ -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= diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 382777993..400e801c6 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -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; ibase_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"); } diff --git a/drivers/at_wini/at_wini.h b/drivers/at_wini/at_wini.h index a4c5489c8..4b848fce7 100644 --- a/drivers/at_wini/at_wini.h +++ b/drivers/at_wini/at_wini.h @@ -1,5 +1,5 @@ #include -#include +#include #include #define VERBOSE 0 /* display identify messages during boot */ @@ -217,3 +217,8 @@ #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]) diff --git a/drivers/audio/Makefile.inc b/drivers/audio/Makefile.inc index 85ebc1bb6..704d229a3 100644 --- a/drivers/audio/Makefile.inc +++ b/drivers/audio/Makefile.inc @@ -1,7 +1,7 @@ .include -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" diff --git a/drivers/audio/es1370/Makefile b/drivers/audio/es1370/Makefile index 46136bcdd..d206c2de9 100644 --- a/drivers/audio/es1370/Makefile +++ b/drivers/audio/es1370/Makefile @@ -4,8 +4,6 @@ SRCS= es1370.c ak4531.c pci_helper.c MAN= -LIBS += -ldriver - BINDIR?= /usr/sbin .include diff --git a/drivers/audio/es1370/ak4531.c b/drivers/audio/es1370/ak4531.c index 027bc83f9..30d2e9507 100644 --- a/drivers/audio/es1370/ak4531.c +++ b/drivers/audio/es1370/ak4531.c @@ -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); diff --git a/drivers/audio/es1370/es1370.c b/drivers/audio/es1370/es1370.c index 8dc6a5f35..471f92bce 100644 --- a/drivers/audio/es1370/es1370.c +++ b/drivers/audio/es1370/es1370.c @@ -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; } diff --git a/drivers/audio/es1370/pci_helper.c b/drivers/audio/es1370/pci_helper.c index 6cea93c1e..ca45e9dad 100644 --- a/drivers/audio/es1370/pci_helper.c +++ b/drivers/audio/es1370/pci_helper.c @@ -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); diff --git a/drivers/audio/es1371/es1371.c b/drivers/audio/es1371/es1371.c index deaad9161..c63d5348a 100644 --- a/drivers/audio/es1371/es1371.c +++ b/drivers/audio/es1371/es1371.c @@ -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; } diff --git a/drivers/audio/es1371/pci_helper.c b/drivers/audio/es1371/pci_helper.c index ce9947171..df35bafe4 100644 --- a/drivers/audio/es1371/pci_helper.c +++ b/drivers/audio/es1371/pci_helper.c @@ -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); diff --git a/drivers/audio/es1371/sample_rate_converter.c b/drivers/audio/es1371/sample_rate_converter.c index 916d67685..dcf378eeb 100644 --- a/drivers/audio/es1371/sample_rate_converter.c +++ b/drivers/audio/es1371/sample_rate_converter.c @@ -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 */ diff --git a/drivers/audio/sb16/mixer.c b/drivers/audio/sb16/mixer.c index e46acc8c0..efc507672 100644 --- a/drivers/audio/sb16/mixer.c +++ b/drivers/audio/sb16/mixer.c @@ -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) { diff --git a/drivers/audio/sb16/sb16.c b/drivers/audio/sb16/sb16.c index 5b1ee1cdf..79110dcb0 100644 --- a/drivers/audio/sb16/sb16.c +++ b/drivers/audio/sb16/sb16.c @@ -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; diff --git a/drivers/bios_wini/Makefile b/drivers/bios_wini/Makefile index cb0f177ff..a0c5842ba 100644 --- a/drivers/bios_wini/Makefile +++ b/drivers/bios_wini/Makefile @@ -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= diff --git a/drivers/bios_wini/bios_wini.c b/drivers/bios_wini/bios_wini.c index ca4249e27..a9375e0a8 100644 --- a/drivers/bios_wini/bios_wini.c +++ b/drivers/bios_wini/bios_wini.c @@ -21,7 +21,7 @@ */ #include -#include +#include #include #include #include @@ -29,8 +29,6 @@ #include #include -#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; + int count; - if (m->m_type != DEV_IOCTL_S ) - return EINVAL; + if (w_prepare(minor) == NULL) return ENXIO; - 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 (request == DIOCOPENCT) { + count = w_wn->open_ct; + return sys_safecopyto(endpt, grant, 0, (vir_bytes)&count, + sizeof(count), D); + } - if(r != OK) - return r; - return OK; - } - - return EINVAL; + return EINVAL; } - - diff --git a/drivers/filter/Makefile b/drivers/filter/Makefile index 7d91a0f74..3c5ad08ba 100644 --- a/drivers/filter/Makefile +++ b/drivers/filter/Makefile @@ -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= diff --git a/drivers/filter/crc.c b/drivers/filter/crc.c index 356018b7e..68d064684 100644 --- a/drivers/filter/crc.c +++ b/drivers/filter/crc.c @@ -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 */ diff --git a/drivers/filter/driver.c b/drivers/filter/driver.c index 62abaf0dc..09293b3a1 100644 --- a/drivers/filter/driver.c +++ b/drivers/filter/driver.c @@ -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; } diff --git a/drivers/filter/inc.h b/drivers/filter/inc.h index ccd5f9e34..f93d86eb0 100644 --- a/drivers/filter/inc.h +++ b/drivers/filter/inc.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/filter/main.c b/drivers/filter/main.c index 2b36e7c6a..a2a6a404d 100644 --- a/drivers/filter/main.c +++ b/drivers/filter/main.c @@ -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); } diff --git a/drivers/filter/sum.c b/drivers/filter/sum.c index 18d3b2efd..06dba8563 100644 --- a/drivers/filter/sum.c +++ b/drivers/filter/sum.c @@ -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++; diff --git a/drivers/filter/util.c b/drivers/filter/util.c index 55fbec736..1c5b4ef21 100644 --- a/drivers/filter/util.c +++ b/drivers/filter/util.c @@ -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]; } diff --git a/drivers/floppy/Makefile b/drivers/floppy/Makefile index 62864941e..99b180ccc 100644 --- a/drivers/floppy/Makefile +++ b/drivers/floppy/Makefile @@ -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= diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index d79c0fe9c..8bf2ba2b6 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -135,7 +135,7 @@ #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; } - - diff --git a/drivers/floppy/floppy.h b/drivers/floppy/floppy.h index 4853818fd..7697eb3d6 100644 --- a/drivers/floppy/floppy.h +++ b/drivers/floppy/floppy.h @@ -1,4 +1,4 @@ #include -#include +#include #include diff --git a/drivers/floppy/liveupdate.c b/drivers/floppy/liveupdate.c index 870a9049a..81e521848 100644 --- a/drivers/floppy/liveupdate.c +++ b/drivers/floppy/liveupdate.c @@ -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); diff --git a/drivers/hello/Makefile b/drivers/hello/Makefile index c48a7c454..1a730e294 100644 --- a/drivers/hello/Makefile +++ b/drivers/hello/Makefile @@ -2,8 +2,8 @@ PROG= hello SRCS= hello.c -DPADD+= ${LIBDRIVER} ${LIBSYS} -LDADD+= -ldriver -lsys +DPADD+= ${LIBCHARDRIVER} ${LIBSYS} +LDADD+= -lchardriver -lsys MAN= diff --git a/drivers/hello/hello.c b/drivers/hello/hello.c index d842fa343..21f60b537 100644 --- a/drivers/hello/hello.c +++ b/drivers/hello/hello.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -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; } diff --git a/drivers/log/Makefile b/drivers/log/Makefile index bab063bcf..7e27ba91e 100644 --- a/drivers/log/Makefile +++ b/drivers/log/Makefile @@ -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= diff --git a/drivers/log/log.c b/drivers/log/log.c index 2882c9ee7..7d08dc405 100644 --- a/drivers/log/log.c +++ b/drivers/log/log.c @@ -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 diff --git a/drivers/log/log.h b/drivers/log/log.h index 11187fc56..c1a5e4cbf 100644 --- a/drivers/log/log.h +++ b/drivers/log/log.h @@ -1,6 +1,6 @@ /* Includes. */ #include -#include +#include #include #include #include diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index bf853cee7..248848883 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -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= diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index 4863ce2c4..f6c39beed 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -16,7 +16,8 @@ */ #include -#include +#include +#include #include #include #include @@ -39,41 +40,57 @@ 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) ); +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) ); -/* Entry points to this driver. */ -PRIVATE struct driver m_dtab = { - m_name, /* current device's name */ +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; - 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; + if (request != MIOCRAMSIZE) + return EINVAL; - /* 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); + /* 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; + } - /* 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; - - dv->dv_size = cvul64(ramdev_size); - - break; - } - - default: - return(do_diocntl(&m_dtab, m_ptr)); + /* 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[minor] = (vir_bytes) mem; + + dv->dv_size = cvul64(ramdev_size); + 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; -} - diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 2616cb20c..5b4e30396 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -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= diff --git a/drivers/printer/Makefile b/drivers/printer/Makefile index 762664a5d..beec640fa 100644 --- a/drivers/printer/Makefile +++ b/drivers/printer/Makefile @@ -2,8 +2,8 @@ PROG= printer SRCS= printer.c liveupdate.c -DPADD+= ${LIBDRIVER} ${LIBSYS} -LDADD+= -ldriver -lsys +DPADD+= ${LIBCHARDRIVER} ${LIBSYS} +LDADD+= -lchardriver -lsys MAN= diff --git a/drivers/printer/printer.c b/drivers/printer/printer.c index 1fb3ab2f1..bb1374885 100644 --- a/drivers/printer/printer.c +++ b/drivers/printer/printer.c @@ -34,7 +34,7 @@ #include #include -#include +#include /* 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; } diff --git a/drivers/random/Makefile b/drivers/random/Makefile index 9c8e14e25..eb329d339 100644 --- a/drivers/random/Makefile +++ b/drivers/random/Makefile @@ -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= diff --git a/drivers/random/main.c b/drivers/random/main.c index f6c59a026..492d19ff9 100644 --- a/drivers/random/main.c +++ b/drivers/random/main.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include #include "assert.h" @@ -16,35 +16,31 @@ #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,37 +209,18 @@ 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; +/*===========================================================================* + * r_do_open * + *===========================================================================*/ +PRIVATE int r_do_open(message *m_ptr) { -/* Check device number on open. +/* Check device number on open. */ if (r_prepare(m_ptr->DEVICE) == NULL) return(ENXIO); return(OK); } -/*===========================================================================* - * r_ioctl * - *===========================================================================*/ -PRIVATE int r_ioctl(dp, m_ptr) -struct driver *dp; /* pointer to driver structure */ -message *m_ptr; /* pointer to control message */ -{ - if (r_prepare(m_ptr->DEVICE) == NULL) return(ENXIO); - - switch (m_ptr->REQUEST) { - - default: - return(do_diocntl(&r_dtab, m_ptr)); - } - return(OK); -} - #define UPDATE(binnumber, bp, startitem, elems) { \ rand_t *r; \ int n = elems, item = startitem;\ @@ -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; -} - diff --git a/drivers/readclock/Makefile b/drivers/readclock/Makefile index a37a4fed2..d91e04815 100644 --- a/drivers/readclock/Makefile +++ b/drivers/readclock/Makefile @@ -2,8 +2,8 @@ PROG= readclock.drv SRCS= readclock.c -DPADD+= ${LIBDRIVER} ${LIBSYS} -LDADD+= -ldriver -lsys +DPADD+= ${LIBSYS} +LDADD+= -lsys MAN= diff --git a/drivers/ti1225/Makefile b/drivers/ti1225/Makefile index b2310f335..319488ed0 100644 --- a/drivers/ti1225/Makefile +++ b/drivers/ti1225/Makefile @@ -2,8 +2,8 @@ PROG= ti1225 SRCS= ti1225.c -DPADD+= ${LIBDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -ldriver -lsys -ltimers +DPADD+= ${LIBSYS} +LDADD+= -lsys MAN= diff --git a/drivers/ti1225/ti1225.c b/drivers/ti1225/ti1225.c index 3194fceac..358552723 100644 --- a/drivers/ti1225/ti1225.c +++ b/drivers/ti1225/ti1225.c @@ -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); } diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index aaf1b8977..42e74f97e 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -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= diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 5f77dcb9c..e9939b243 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -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. */ diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index d21b80e17..e2dab153d 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -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; diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 916b7b963..860fb8b2e 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -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; diff --git a/drivers/tty/rs232.c b/drivers/tty/rs232.c index f3311e3c0..a95a02db2 100644 --- a/drivers/tty/rs232.c +++ b/drivers/tty/rs232.c @@ -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; diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 39f4ee54a..1d31be457 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -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; diff --git a/lib/Makefile b/lib/Makefile index 1525a52f5..a4c2127cb 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -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 diff --git a/lib/libaudiodriver/audio_fw.c b/lib/libaudiodriver/audio_fw.c index a0ac41b82..8eced8007 100644 --- a/lib/libaudiodriver/audio_fw.c +++ b/lib/libaudiodriver/audio_fw.c @@ -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; } diff --git a/lib/libbdev/bdev.c b/lib/libbdev/bdev.c index 8182dcd55..e188aa383 100644 --- a/lib/libbdev/bdev.c +++ b/lib/libbdev/bdev.c @@ -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]); + for (i = m->BDEV_COUNT - 1; i >= 0; i--) + cpf_revoke(gvec[i].iov_grant); } -static int bdev_vrdwt_adjust(dev_t dev, iovec_s_t *gvec, int count, - vir_bytes *size) +static ssize_t bdev_vrdwt(int req, dev_t dev, u64_t pos, iovec_t *vec, + int count, int flags) { -/* 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; -} - -static int bdev_vrdwt(int req, dev_t dev, u64_t pos, iovec_t *vec, int count, - int flags, vir_bytes *size) -{ -/* 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) diff --git a/lib/libbdev/ipc.c b/lib/libbdev/ipc.c index 941d2e187..afff3e49a 100644 --- a/lib/libbdev/ipc.c +++ b/lib/libbdev/ipc.c @@ -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; } diff --git a/lib/libdriver/Makefile b/lib/libblockdriver/Makefile similarity index 78% rename from lib/libdriver/Makefile rename to lib/libblockdriver/Makefile index 2ff9ab7ba..0c153d218 100644 --- a/lib/libdriver/Makefile +++ b/lib/libblockdriver/Makefile @@ -1,7 +1,7 @@ -# Makefile for libdriver +# Makefile for libblockdriver .include -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 index 000000000..f63e9cbc1 --- /dev/null +++ b/lib/libblockdriver/driver.c @@ -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 +#include +#include +#include + +#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 index 000000000..4e1299e3d --- /dev/null +++ b/lib/libblockdriver/driver.h @@ -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 */ diff --git a/lib/libdriver/driver_mt.c b/lib/libblockdriver/driver_mt.c similarity index 74% rename from lib/libdriver/driver_mt.c rename to lib/libblockdriver/driver_mt.c index cb9d6a924..fd7cc0215 100644 --- a/lib/libdriver/driver_mt.c +++ b/lib/libblockdriver/driver_mt.c @@ -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 +#include #include #include @@ -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 index 000000000..b3b225b66 --- /dev/null +++ b/lib/libblockdriver/driver_st.c @@ -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 +#include + +#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); +} diff --git a/lib/libdriver/drvlib.c b/lib/libblockdriver/drvlib.c similarity index 75% rename from lib/libdriver/drvlib.c rename to lib/libblockdriver/drvlib.c index 43869cc05..94064388a 100644 --- a/lib/libdriver/drvlib.c +++ b/lib/libblockdriver/drvlib.c @@ -4,36 +4,36 @@ * partition: partition a disk to the partition table(s) on it. */ -#include +#include #include #include /* 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) { diff --git a/lib/libdriver/event.c b/lib/libblockdriver/event.c similarity index 65% rename from lib/libdriver/event.c rename to lib/libblockdriver/event.c index 5b81951ec..87751f57a 100644 --- a/lib/libdriver/event.c +++ b/lib/libblockdriver/event.c @@ -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 index 000000000..cfb082512 --- /dev/null +++ b/lib/libblockdriver/event.h @@ -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 */ diff --git a/lib/libdriver/mq.c b/lib/libblockdriver/mq.c similarity index 83% rename from lib/libdriver/mq.c rename to lib/libblockdriver/mq.c index 300361056..602fa3b10 100644 --- a/lib/libdriver/mq.c +++ b/lib/libblockdriver/mq.c @@ -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 +#include #include #include @@ -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 index 000000000..7d772e49e --- /dev/null +++ b/lib/libblockdriver/mq.h @@ -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 index 000000000..f3f0aa56e --- /dev/null +++ b/lib/libchardriver/Makefile @@ -0,0 +1,12 @@ +# Makefile for libchardriver +.include + +LIB= chardriver + +SRCS= chardriver.c + +.if ${USE_STATECTL} != "no" +CPPFLAGS+= -DUSE_STATECTL +.endif + +.include diff --git a/lib/libdriver/driver.c b/lib/libchardriver/chardriver.c similarity index 70% rename from lib/libdriver/driver.c rename to lib/libchardriver/chardriver.c index 08a0fb4f6..7f6256a34 100644 --- a/lib/libdriver/driver.c +++ b/lib/libchardriver/chardriver.c @@ -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): * @@ -25,8 +23,13 @@ * | 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) @@ -34,12 +37,10 @@ */ #include -#include -#include +#include #include -#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 * *===========================================================================*/ -PRIVATE void asyn_reply(message *mess, int r) +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 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,63 +350,84 @@ 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); + } +} + +/*===========================================================================* + * chardriver_task * + *===========================================================================*/ +PUBLIC void chardriver_task(struct chardriver *cdp, int driver_type) +{ +/* 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); + } } /*===========================================================================* * do_nop * *===========================================================================*/ -PUBLIC int do_nop(struct driver *UNUSED(dp), message *mp) +PUBLIC int do_nop(message *UNUSED(mp)) { -/* 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); - } + return(OK); } /*===========================================================================* * nop_ioctl * *===========================================================================*/ -PUBLIC int nop_ioctl(struct driver *UNUSED(dp), message *UNUSED(mp)) +PUBLIC int nop_ioctl(message *UNUSED(mp)) { return(ENOTTY); } @@ -434,20 +435,11 @@ PUBLIC int nop_ioctl(struct driver *UNUSED(dp), message *UNUSED(mp)) /*===========================================================================* * nop_alarm * *===========================================================================*/ -PUBLIC void nop_alarm(struct driver *UNUSED(dp), message *UNUSED(mp)) +PUBLIC void nop_alarm(message *UNUSED(mp)) { /* Ignore the leftover alarm. */ } -/*===========================================================================* - * nop_prepare * - *===========================================================================*/ -PUBLIC struct device *nop_prepare(int UNUSED(device)) -{ -/* Nothing to prepare for. */ - return(NULL); -} - /*===========================================================================* * nop_cleanup * *===========================================================================*/ @@ -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 index fe1392980..000000000 --- a/lib/libdriver/driver.h +++ /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 index b4d061364..000000000 --- a/lib/libdriver/driver_st.c +++ /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 -#include - -#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 index b0b8d75e0..000000000 --- a/lib/libdriver/event.h +++ /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 index e2c87459f..000000000 --- a/lib/libdriver/mq.h +++ /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 */ diff --git a/servers/apfs/Makefile b/servers/apfs/Makefile index b713d2dee..6c6cbe4d7 100644 --- a/servers/apfs/Makefile +++ b/servers/apfs/Makefile @@ -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= diff --git a/servers/apfs/main.c b/servers/apfs/main.c index 2f9f4d4ed..73dd0d09f 100644 --- a/servers/apfs/main.c +++ b/servers/apfs/main.c @@ -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); } diff --git a/servers/avfs/device.c b/servers/avfs/device.c index b75200a3b..c3af865a4 100644 --- a/servers/avfs/device.c +++ b/servers/avfs/device.c @@ -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 #include #include #include @@ -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); - } /*===========================================================================* diff --git a/servers/avfs/dmap.c b/servers/avfs/dmap.c index 687f0c2aa..eb5d13b1b 100644 --- a/servers/avfs/dmap.c +++ b/servers/avfs/dmap.c @@ -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); + } + } } /*===========================================================================* diff --git a/servers/avfs/filedes.c b/servers/avfs/filedes.c index dd788eaf9..c6482d2e8 100644 --- a/servers/avfs/filedes.c +++ b/servers/avfs/filedes.c @@ -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; } } diff --git a/servers/avfs/main.c b/servers/avfs/main.c index e07f66ef6..a6a1b24cc 100644 --- a/servers/avfs/main.c +++ b/servers/avfs/main.c @@ -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"); diff --git a/servers/avfs/misc.c b/servers/avfs/misc.c index 9e5edd213..849143563 100644 --- a/servers/avfs/misc.c +++ b/servers/avfs/misc.c @@ -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; + } + + 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); } - /* Only check for VFS driver up events. */ - if (strncmp(key, drv_prefix, sizeof(drv_prefix)) || value != DS_DRIVER_UP) - return; - - /* Perform up. */ - dmap_endpt_up(owner_endpoint); + if (r != ENOENT) printf("VFS: ds_event: ds_check failed: %d\n", r); } diff --git a/servers/avfs/open.c b/servers/avfs/open.c index dd88fed06..a85e2b50a 100644 --- a/servers/avfs/open.c +++ b/servers/avfs/open.c @@ -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; + /* 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) { unlock_bsf(); break; } - /* Send the driver endpoint (even when known already)*/ - 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(); diff --git a/servers/avfs/proto.h b/servers/avfs/proto.h index 207ede593..9046f04fc 100644 --- a/servers/avfs/proto.h +++ b/servers/avfs/proto.h @@ -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) ); diff --git a/servers/ext2/cache.c b/servers/ext2/cache.c index 9fb27ff4f..a09e1bd8b 100644 --- a/servers/ext2/cache.c +++ b/servers/ext2/cache.c @@ -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; diff --git a/servers/ext2/super.c b/servers/ext2/super.c index c1fc4279a..e0377b163 100644 --- a/servers/ext2/super.c +++ b/servers/ext2/super.c @@ -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]); } diff --git a/servers/inet/Makefile b/servers/inet/Makefile index 67ee96a2a..8dbe78db8 100644 --- a/servers/inet/Makefile +++ b/servers/inet/Makefile @@ -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= diff --git a/servers/inet/inet.c b/servers/inet/inet.c index bd84a54ca..82c290191 100644 --- a/servers/inet/inet.c +++ b/servers/inet/inet.c @@ -42,7 +42,7 @@ from DL_ETH: #include #include #include -#include +#include #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); } diff --git a/servers/iso9660fs/cache.c b/servers/iso9660fs/cache.c index b8f1e9a98..81a5c6936 100644 --- a/servers/iso9660fs/cache.c +++ b/servers/iso9660fs/cache.c @@ -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); diff --git a/servers/lwip/Makefile b/servers/lwip/Makefile index 4d06a045a..0847502d4 100644 --- a/servers/lwip/Makefile +++ b/servers/lwip/Makefile @@ -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= diff --git a/servers/lwip/lwip.c b/servers/lwip/lwip.c index dbe381b5b..39a2487f7 100644 --- a/servers/lwip/lwip.c +++ b/servers/lwip/lwip.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -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); } diff --git a/servers/mfs/cache.c b/servers/mfs/cache.c index a4f7c7adb..3adfec4c9 100644 --- a/servers/mfs/cache.c +++ b/servers/mfs/cache.c @@ -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; diff --git a/servers/mfs/main.c b/servers/mfs/main.c index 2d7d244d7..6b1e9a96f 100644 --- a/servers/mfs/main.c +++ b/servers/mfs/main.c @@ -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; diff --git a/servers/mfs/super.c b/servers/mfs/super.c index 0c97d0413..d7bc0038d 100644 --- a/servers/mfs/super.c +++ b/servers/mfs/super.c @@ -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)); diff --git a/servers/pfs/Makefile b/servers/pfs/Makefile index ac3312ba5..ff1a9fad7 100644 --- a/servers/pfs/Makefile +++ b/servers/pfs/Makefile @@ -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= diff --git a/servers/pfs/main.c b/servers/pfs/main.c index af5c47502..b449e1239 100644 --- a/servers/pfs/main.c +++ b/servers/pfs/main.c @@ -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); } diff --git a/servers/vfs/device.c b/servers/vfs/device.c index 8e918482c..d53825e46 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -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 #include #include #include @@ -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); - } diff --git a/servers/vfs/dmap.c b/servers/vfs/dmap.c index 42bc03743..fddb2fb79 100644 --- a/servers/vfs/dmap.c +++ b/servers/vfs/dmap.c @@ -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; iv_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; } diff --git a/servers/vfs/main.c b/servers/vfs/main.c index 05c3b035e..53a631b15 100644 --- a/servers/vfs/main.c +++ b/servers/vfs/main.c @@ -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"); } diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index 1b406e9fa..e7be635c7 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -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); } diff --git a/servers/vfs/open.c b/servers/vfs/open.c index d62e5bf4e..f5aa12b1f 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -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; diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index db95f0020..485dc35af 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -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, diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index a1b30e1b7..e5cbffff7 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -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" diff --git a/test/blocktest/blocktest.c b/test/blocktest/blocktest.c index 698e59bfe..2f8295387 100644 --- a/test/blocktest/blocktest.c +++ b/test/blocktest/blocktest.c @@ -1,7 +1,7 @@ /* Block Device Driver Test driver, by D.C. van Moolenbroek */ #include #include -#include +#include #include #include #include @@ -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]);