From: David van Moolenbroek Date: Wed, 11 Sep 2013 11:33:00 +0000 (+0200) Subject: libblockdriver: various updates X-Git-Tag: v3.3.0~595 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/index.css?a=commitdiff_plain;h=0f7f3c0d549734d0e4e12338ea5dad4685522784;p=minix.git libblockdriver: various updates - internal structure rearrangement; - respond to char device open requests to avoid hanging VFS threads; - make drivers use designated initializers; - use devminor_t for all minor device numbers; - change bdr_other hook to take ipc_status and return nothing; - fix default geometry computation; - add support for sef_cancel. Change-Id: Ia063a136a3ddb2b78de36180feda870605753d70 --- diff --git a/drivers/ahci/ahci.c b/drivers/ahci/ahci.c index 0c108e42a..81dd59e3e 100644 --- a/drivers/ahci/ahci.c +++ b/drivers/ahci/ahci.c @@ -236,32 +236,29 @@ static void port_timeout(struct timer *tp); static void port_disconnect(struct port_state *ps); static char *ahci_portname(struct port_state *ps); -static int ahci_open(dev_t minor, int access); -static int ahci_close(dev_t minor); -static ssize_t ahci_transfer(dev_t minor, int do_write, u64_t position, +static int ahci_open(devminor_t minor, int access); +static int ahci_close(devminor_t minor); +static ssize_t ahci_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t endpt, iovec_t *iovec, unsigned int count, int flags); -static struct device *ahci_part(dev_t minor); +static struct device *ahci_part(devminor_t minor); static void ahci_alarm(clock_t stamp); -static int ahci_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +static int ahci_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); static void ahci_intr(unsigned int mask); -static int ahci_device(dev_t minor, device_id_t *id); -static struct port_state *ahci_get_port(dev_t minor); +static int ahci_device(devminor_t minor, device_id_t *id); +static struct port_state *ahci_get_port(devminor_t minor); /* AHCI driver table. */ static struct blockdriver ahci_dtab = { - BLOCKDRIVER_TYPE_DISK, - ahci_open, - ahci_close, - ahci_transfer, - ahci_ioctl, - NULL, /* bdr_cleanup */ - ahci_part, - NULL, /* bdr_geometry */ - ahci_intr, - ahci_alarm, - NULL, /* bdr_other */ - ahci_device + .bdr_type = BLOCKDRIVER_TYPE_DISK, + .bdr_open = ahci_open, + .bdr_close = ahci_close, + .bdr_transfer = ahci_transfer, + .bdr_ioctl = ahci_ioctl, + .bdr_part = ahci_part, + .bdr_intr = ahci_intr, + .bdr_alarm = ahci_alarm, + .bdr_device = ahci_device }; /*===========================================================================* @@ -2422,7 +2419,7 @@ static char *ahci_portname(struct port_state *ps) /*===========================================================================* * ahci_map_minor * *===========================================================================*/ -static struct port_state *ahci_map_minor(dev_t minor, struct device **dvp) +static struct port_state *ahci_map_minor(devminor_t minor, struct device **dvp) { /* 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 @@ -2433,7 +2430,7 @@ static struct port_state *ahci_map_minor(dev_t minor, struct device **dvp) ps = NULL; - if (minor < NR_MINORS) { + if (minor >= 0 && minor < NR_MINORS) { port = ahci_map[minor / DEV_PER_DRIVE]; if (port == NO_PORT) @@ -2458,7 +2455,7 @@ static struct port_state *ahci_map_minor(dev_t minor, struct device **dvp) /*===========================================================================* * ahci_part * *===========================================================================*/ -static struct device *ahci_part(dev_t minor) +static struct device *ahci_part(devminor_t minor) { /* Return a pointer to the partition information structure of the given * minor device. @@ -2474,7 +2471,7 @@ static struct device *ahci_part(dev_t minor) /*===========================================================================* * ahci_open * *===========================================================================*/ -static int ahci_open(dev_t minor, int access) +static int ahci_open(devminor_t minor, int access) { /* Open a device. */ @@ -2543,7 +2540,7 @@ static int ahci_open(dev_t minor, int access) /*===========================================================================* * ahci_close * *===========================================================================*/ -static int ahci_close(dev_t minor) +static int ahci_close(devminor_t minor) { /* Close a device. */ @@ -2599,7 +2596,7 @@ static int ahci_close(dev_t minor) /*===========================================================================* * ahci_transfer * *===========================================================================*/ -static ssize_t ahci_transfer(dev_t minor, int do_write, u64_t position, +static ssize_t ahci_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t endpt, iovec_t *iovec, unsigned int count, int flags) { /* Perform data transfer on the selected device. @@ -2634,7 +2631,7 @@ static ssize_t ahci_transfer(dev_t minor, int do_write, u64_t position, /*===========================================================================* * ahci_ioctl * *===========================================================================*/ -static int ahci_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +static int ahci_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { /* Process I/O control requests. @@ -2691,7 +2688,7 @@ static int ahci_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, /*===========================================================================* * ahci_device * *===========================================================================*/ -static int ahci_device(dev_t minor, device_id_t *id) +static int ahci_device(devminor_t minor, device_id_t *id) { /* Map a minor device number to a device ID. */ @@ -2709,7 +2706,7 @@ static int ahci_device(dev_t minor, device_id_t *id) /*===========================================================================* * ahci_get_port * *===========================================================================*/ -static struct port_state *ahci_get_port(dev_t minor) +static struct port_state *ahci_get_port(devminor_t minor) { /* Get the port structure associated with the given minor device. * Called only from worker threads, so the minor device is already diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 349ffeb91..23b822723 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -140,14 +140,14 @@ static void init_params(void); static void init_drive(struct wini *w, int base_cmd, int base_ctl, int base_dma, int irq, int ack, int hook, int drive); static void init_params_pci(int); -static int w_do_open(dev_t minor, int access); -static struct device *w_prepare(dev_t dev); -static struct device *w_part(dev_t minor); +static int w_do_open(devminor_t minor, int access); +static struct device *w_prepare(devminor_t dev); +static struct device *w_part(devminor_t minor); static int w_identify(void); static char *w_name(void); static int w_specify(void); static int w_io_test(void); -static ssize_t w_transfer(dev_t minor, int do_write, u64_t position, +static ssize_t w_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t proc_nr, iovec_t *iov, unsigned int nr_req, int flags); static int com_out(struct command *cmd); static int com_out_ext(struct command *cmd); @@ -155,8 +155,8 @@ static int setup_dma(unsigned *sizep, endpoint_t proc_nr, iovec_t *iov, size_t addr_offset, int do_write); static void w_need_reset(void); static void ack_irqs(unsigned int); -static int w_do_close(dev_t minor); -static int w_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +static int w_do_close(devminor_t minor); +static int w_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); static void w_hw_int(unsigned int irqs); static int com_simple(struct command *cmd); @@ -166,7 +166,7 @@ static void w_intr_wait(void); static int at_intr_wait(void); static int w_waitfor(int mask, int value); static int w_waitfor_dma(int mask, int value); -static void w_geometry(dev_t minor, struct part_geom *entry); +static void w_geometry(devminor_t minor, struct part_geom *entry); #if ENABLE_ATAPI static int atapi_sendpacket(u8_t *packet, unsigned cnt, int do_dma); static int atapi_intr_wait(int dma, size_t max); @@ -196,18 +196,14 @@ static int at_in(int line, u32_t port, u32_t *value, char *typename, /* Entry points to this driver. */ static struct blockdriver w_dtab = { - BLOCKDRIVER_TYPE_DISK,/* handle partition requests */ - w_do_open, /* open or mount request, initialize device */ - w_do_close, /* release device */ - w_transfer, /* do the I/O */ - w_ioctl, /* I/O control requests */ - NULL, /* nothing to clean up */ - w_part, /* return partition information */ - w_geometry, /* tell the geometry of the disk */ - w_hw_int, /* leftover hardware interrupts */ - NULL, /* ignore leftover alarms */ - NULL, /* ignore unrecognized messages */ - NULL /* no multithreading support */ + .bdr_type = BLOCKDRIVER_TYPE_DISK, /* handle partition requests */ + .bdr_open = w_do_open, /* open or mount request, initialize device */ + .bdr_close = w_do_close, /* release device */ + .bdr_transfer = w_transfer, /* do the I/O */ + .bdr_ioctl = w_ioctl, /* I/O control requests */ + .bdr_part = w_part, /* return partition information */ + .bdr_geometry = w_geometry, /* tell the geometry of the disk */ + .bdr_intr = w_hw_int, /* leftover hardware interrupts */ }; /* SEF functions and variables. */ @@ -583,7 +579,7 @@ static void init_params_pci(int skip) /*===========================================================================* * w_do_open * *===========================================================================*/ -static int w_do_open(dev_t minor, int access) +static int w_do_open(devminor_t minor, int access) { /* Device open: Initialize the controller and read the partition table. */ @@ -652,12 +648,12 @@ static int w_do_open(dev_t minor, int access) /*===========================================================================* * w_prepare * *===========================================================================*/ -static struct device *w_prepare(dev_t device) +static struct device *w_prepare(devminor_t device) { /* Prepare for I/O on a device. */ w_device = (int) device; - if (device < NR_MINORS) { /* d0, d0p[0-3], d1, ... */ + if (device >= 0 && device < NR_MINORS) { /* d0, d0p[0-3], d1, ... */ w_drive = device / DEV_PER_DRIVE; /* save drive number */ w_wn = &wini[w_drive]; w_dv = &w_wn->part[device % DEV_PER_DRIVE]; @@ -676,7 +672,7 @@ static struct device *w_prepare(dev_t device) /*===========================================================================* * w_part * *===========================================================================*/ -static struct device *w_part(dev_t device) +static struct device *w_part(devminor_t device) { /* Return a pointer to the partition information of the given minor device. */ @@ -1172,7 +1168,7 @@ static int error_dma(const struct wini *wn) * w_transfer * *===========================================================================*/ static ssize_t w_transfer( - dev_t minor, /* minor device to perform the transfer on */ + devminor_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 */ @@ -1640,7 +1636,7 @@ static void w_need_reset(void) /*===========================================================================* * w_do_close * *===========================================================================*/ -static int w_do_close(dev_t minor) +static int w_do_close(devminor_t minor) { /* Device close: Release a device. */ if (w_prepare(minor) == NULL) @@ -1882,7 +1878,7 @@ int value; /* required status */ /*===========================================================================* * w_geometry * *===========================================================================*/ -static void w_geometry(dev_t minor, struct part_geom *entry) +static void w_geometry(devminor_t minor, struct part_geom *entry) { struct wini *wn; @@ -2215,7 +2211,7 @@ int do_dma; /*===========================================================================* * w_ioctl * *===========================================================================*/ -static int w_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +static int w_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { int r, timeout, prev, count; diff --git a/drivers/cat24c256/cat24c256.c b/drivers/cat24c256/cat24c256.c index ba5d4b44b..fbd4eb081 100644 --- a/drivers/cat24c256/cat24c256.c +++ b/drivers/cat24c256/cat24c256.c @@ -29,14 +29,14 @@ static int sef_cb_lu_state_save(int); static int lu_state_restore(void); /* libblockdriver callbacks */ -static int cat24c256_blk_open(dev_t minor, int access); -static int cat24c256_blk_close(dev_t minor); -static ssize_t cat24c256_blk_transfer(dev_t minor, int do_write, u64_t pos, - endpoint_t endpt, iovec_t * iov, unsigned count, int flags); -static int cat24c256_blk_ioctl(dev_t minor, unsigned int request, +static int cat24c256_blk_open(devminor_t minor, int access); +static int cat24c256_blk_close(devminor_t minor); +static ssize_t cat24c256_blk_transfer(devminor_t minor, int do_write, + u64_t pos, endpoint_t endpt, iovec_t * iov, unsigned int count, int flags); +static int cat24c256_blk_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); -static struct device *cat24c256_blk_part(dev_t minor); -static int cat24c256_blk_other(message * m); +static struct device *cat24c256_blk_part(devminor_t minor); +static void cat24c256_blk_other(message * m, int ipc_status); /* Entry points into the device dependent code of block drivers. */ struct blockdriver cat24c256_tab = { @@ -44,14 +44,9 @@ struct blockdriver cat24c256_tab = { .bdr_open = cat24c256_blk_open, .bdr_close = cat24c256_blk_close, .bdr_transfer = cat24c256_blk_transfer, - .bdr_ioctl = cat24c256_blk_ioctl, /* nop -- always returns EINVAL */ - .bdr_cleanup = NULL, /* nothing allocated -- nothing to clean up */ + .bdr_ioctl = cat24c256_blk_ioctl, /* always returns ENOTTY */ .bdr_part = cat24c256_blk_part, - .bdr_geometry = NULL, /* no geometry (cylinders, heads, sectors, etc) */ - .bdr_intr = NULL, /* i2c devices don't generate interrupts */ - .bdr_alarm = NULL, /* alarm not needed */ - .bdr_other = cat24c256_blk_other, /* to recv notify events from DS */ - .bdr_device = NULL /* 1 insance per bus, threads not needed */ + .bdr_other = cat24c256_blk_other /* for notify events from DS */ }; static int cat24c256_read128(uint16_t memaddr, void *buf, size_t buflen, int flags); @@ -84,7 +79,7 @@ static struct log log = { }; static int -cat24c256_blk_open(dev_t minor, int access) +cat24c256_blk_open(devminor_t minor, int access) { log_trace(&log, "cat24c256_blk_open(%d,%d)\n", minor, access); if (cat24c256_blk_part(minor) == NULL) { @@ -97,7 +92,7 @@ cat24c256_blk_open(dev_t minor, int access) } static int -cat24c256_blk_close(dev_t minor) +cat24c256_blk_close(devminor_t minor) { log_trace(&log, "cat24c256_blk_close(%d)\n", minor); if (cat24c256_blk_part(minor) == NULL) { @@ -114,11 +109,11 @@ cat24c256_blk_close(dev_t minor) } static ssize_t -cat24c256_blk_transfer(dev_t minor, int do_write, u64_t pos64, - endpoint_t endpt, iovec_t * iov, unsigned nr_req, int flags) +cat24c256_blk_transfer(devminor_t minor, int do_write, u64_t pos64, + endpoint_t endpt, iovec_t * iov, unsigned int nr_req, int flags) { /* Read or write one the driver's block devices. */ - unsigned count; + unsigned int count; struct device *dv; u64_t dv_size; int r; @@ -214,7 +209,7 @@ cat24c256_blk_transfer(dev_t minor, int do_write, u64_t pos64, } static int -cat24c256_blk_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +cat24c256_blk_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { log_trace(&log, "cat24c256_blk_ioctl(%d)\n", minor); @@ -223,41 +218,31 @@ cat24c256_blk_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, } static struct device * -cat24c256_blk_part(dev_t minor) +cat24c256_blk_part(devminor_t minor) { log_trace(&log, "cat24c256_blk_part(%d)\n", minor); - if (minor >= NR_DEVS) { + if (minor < 0 || minor >= NR_DEVS) { return NULL; } return &geom[minor]; } -static int -cat24c256_blk_other(message * m) +static void +cat24c256_blk_other(message * m, int ipc_status) { - int r; - log_trace(&log, "cat24c256_blk_other(0x%x)\n", m->m_type); - switch (m->m_type) { - case NOTIFY_MESSAGE: + if (is_ipc_notify(ipc_status)) { if (m->m_source == DS_PROC_NR) { log_debug(&log, "bus driver changed state, update endpoint\n"); i2cdriver_handle_bus_update(&bus_endpoint, bus, address); } - r = OK; - break; - default: + } else log_warn(&log, "Invalid message type (0x%x)\n", m->m_type); - r = EINVAL; - break; - } - - return r; } /* The lower level i2c interface can only read/write 128 bytes at a time. diff --git a/drivers/fbd/fbd.c b/drivers/fbd/fbd.c index 700fe92b9..9b0dbdc4d 100644 --- a/drivers/fbd/fbd.c +++ b/drivers/fbd/fbd.c @@ -15,34 +15,27 @@ #define BUF_SIZE (NR_IOREQS * CLICK_SIZE) /* 256k */ /* Function declarations. */ -static int fbd_open(dev_t minor, int access); -static int fbd_close(dev_t minor); -static int fbd_transfer(dev_t minor, int do_write, u64_t position, +static int fbd_open(devminor_t minor, int access); +static int fbd_close(devminor_t minor); +static int fbd_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t endpt, iovec_t *iov, unsigned int nr_req, int flags); -static int fbd_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +static int fbd_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); /* Variables. */ static char *fbd_buf; /* scratch buffer */ static char driver_label[32] = ""; /* driver DS label */ -static dev_t driver_minor = -1; /* driver's partition minor to use */ -static endpoint_t driver_endpt; /* driver endpoint */ +static devminor_t driver_minor = -1; /* driver's partition minor to use */ +static endpoint_t driver_endpt; /* driver endpoint */ /* Entry points to this driver. */ static struct blockdriver fbd_dtab = { - BLOCKDRIVER_TYPE_OTHER, /* do not handle partition requests */ - fbd_open, /* open or mount request, initialize device */ - fbd_close, /* release device */ - fbd_transfer, /* do the I/O */ - fbd_ioctl, /* perform I/O control request */ - NULL, /* nothing to clean up */ - NULL, /* we will not be asked about partitions */ - NULL, /* we will not be asked for geometry */ - NULL, /* ignore leftover hardware interrupts */ - NULL, /* ignore alarms */ - NULL, /* ignore other messages */ - NULL /* no multithreading support */ + .bdr_type = BLOCKDRIVER_TYPE_OTHER,/* do not handle part. reqs */ + .bdr_open = fbd_open, /* open request, initialize device */ + .bdr_close = fbd_close, /* release device */ + .bdr_transfer = fbd_transfer, /* do the I/O */ + .bdr_ioctl = fbd_ioctl /* perform I/O control request */ }; /* Options supported by this driver. */ @@ -147,7 +140,7 @@ int main(int argc, char **argv) /*===========================================================================* * fbd_open * *===========================================================================*/ -static int fbd_open(dev_t UNUSED(minor), int access) +static int fbd_open(devminor_t UNUSED(minor), int access) { /* Open a device. */ message m; @@ -172,7 +165,7 @@ static int fbd_open(dev_t UNUSED(minor), int access) /*===========================================================================* * fbd_close * *===========================================================================*/ -static int fbd_close(dev_t UNUSED(minor)) +static int fbd_close(devminor_t UNUSED(minor)) { /* Close a device. */ message m; @@ -196,7 +189,7 @@ static int fbd_close(dev_t UNUSED(minor)) /*===========================================================================* * fbd_ioctl * *===========================================================================*/ -static int fbd_ioctl(dev_t UNUSED(minor), unsigned int request, +static int fbd_ioctl(devminor_t UNUSED(minor), unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { /* Handle an I/O control request. */ @@ -406,11 +399,11 @@ static ssize_t fbd_transfer_copy(int do_write, u64_t position, /*===========================================================================* * fbd_transfer * *===========================================================================*/ -static int fbd_transfer(dev_t UNUSED(minor), int do_write, u64_t position, +static int fbd_transfer(devminor_t UNUSED(minor), int do_write, u64_t position, endpoint_t endpt, iovec_t *iov, unsigned int nr_req, int flags) { /* Transfer data from or to the device. */ - unsigned count; + unsigned int count; size_t size, osize; int i, hooks; ssize_t r; diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index f62790f11..d36c52cc2 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -242,10 +242,10 @@ static void f_expire_tmrs(clock_t stamp); static void stop_motor(timer_t *tp); static void f_timeout(timer_t *tp); -static struct device *f_prepare(dev_t device); -static struct device *f_part(dev_t minor); +static struct device *f_prepare(devminor_t device); +static struct device *f_part(devminor_t minor); static void f_cleanup(void); -static ssize_t f_transfer(dev_t minor, int do_write, u64_t position, +static ssize_t f_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t proc_nr, iovec_t *iov, unsigned int nr_req, int flags); static int dma_setup(int do_write); static void start_motor(void); @@ -258,25 +258,21 @@ static int recalibrate(void); static void f_reset(void); static int f_intr_wait(void); static int read_id(void); -static int f_do_open(dev_t minor, int access); -static int f_do_close(dev_t minor); +static int f_do_open(devminor_t minor, int access); +static int f_do_close(devminor_t minor); static int test_read(int density); -static void f_geometry(dev_t minor, struct part_geom *entry); +static void f_geometry(devminor_t minor, struct part_geom *entry); /* Entry points to this driver. */ static struct blockdriver f_dtab = { - BLOCKDRIVER_TYPE_DISK, /* handle partition requests */ - f_do_open, /* open or mount request, sense type of diskette */ - 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 */ - NULL, /* no processing of other messages */ - NULL /* no threading support */ + .bdr_type = BLOCKDRIVER_TYPE_DISK, /* handle partition requests */ + .bdr_open = f_do_open, /* open request, sense type of diskette */ + .bdr_close = f_do_close, /* nothing on a close */ + .bdr_transfer = f_transfer, /* do the I/O */ + .bdr_cleanup = f_cleanup, /* cleanup before sending reply to caller */ + .bdr_part = f_part, /* return partition information structure */ + .bdr_geometry = f_geometry, /* tell the geometry of the diskette */ + .bdr_alarm = f_expire_tmrs /* expire all alarm timers */ }; static char *floppy_buf; @@ -397,13 +393,13 @@ static void f_expire_tmrs(clock_t stamp) /*===========================================================================* * f_prepare * *===========================================================================*/ -static struct device *f_prepare(dev_t device) +static struct device *f_prepare(devminor_t device) { /* Prepare for I/O on a device. */ f_device = device; f_drive = device & ~(DEV_TYPE_BITS | FORMAT_DEV_BIT); - if (f_drive >= NR_DRIVES) return(NULL); + if (device < 0 || f_drive >= NR_DRIVES) return(NULL); f_fp = &floppy[f_drive]; f_dv = &f_fp->fl_geom; @@ -424,7 +420,7 @@ static struct device *f_prepare(dev_t device) /*===========================================================================* * f_part * *===========================================================================*/ -static struct device *f_part(dev_t minor) +static struct device *f_part(devminor_t minor) { /* Return a pointer to the partition information of the given minor device. */ @@ -447,7 +443,7 @@ static void f_cleanup(void) * f_transfer * *===========================================================================*/ static ssize_t f_transfer( - dev_t minor, /* minor device number */ + devminor_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 */ @@ -1251,7 +1247,7 @@ static int read_id(void) /*===========================================================================* * f_do_open * *===========================================================================*/ -static int f_do_open(dev_t minor, int UNUSED(access)) +static int f_do_open(devminor_t minor, int UNUSED(access)) { /* Handle an open on a floppy. Determine diskette type if need be. */ @@ -1310,7 +1306,7 @@ static int f_do_open(dev_t minor, int UNUSED(access)) /*===========================================================================* * f_do_close * *===========================================================================*/ -static int f_do_close(dev_t UNUSED(minor)) +static int f_do_close(devminor_t UNUSED(minor)) { /* Handle a close on a floppy. Nothing to do here. */ @@ -1350,7 +1346,7 @@ static int test_read(int density) /*===========================================================================* * f_geometry * *===========================================================================*/ -static void f_geometry(dev_t minor, struct part_geom *entry) +static void f_geometry(devminor_t minor, struct part_geom *entry) { if (f_prepare(minor) == NULL) return; diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index d985b2efb..3c8e5bdef 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -52,12 +52,12 @@ static int m_transfer(endpoint_t endpt, int opcode, u64_t position, static int m_do_open(message *m_ptr); static int m_do_close(message *m_ptr); -static struct device *m_block_part(dev_t minor); -static int m_block_transfer(dev_t minor, int do_write, u64_t position, +static struct device *m_block_part(devminor_t minor); +static int m_block_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t endpt, iovec_t *iov, unsigned int nr_req, int flags); -static int m_block_open(dev_t minor, int access); -static int m_block_close(dev_t minor); -static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t +static int m_block_open(devminor_t minor, int access); +static int m_block_close(devminor_t minor); +static int m_block_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); /* Entry points to the CHARACTER part of this driver. */ @@ -76,18 +76,12 @@ static struct chardriver m_cdtab = { /* Entry points to the BLOCK part of this driver. */ static struct blockdriver m_bdtab = { - BLOCKDRIVER_TYPE_DISK,/* handle partition requests */ - 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 */ + .bdr_type = BLOCKDRIVER_TYPE_DISK,/* handle partition requests */ + .bdr_open = m_block_open, /* open device */ + .bdr_close = m_block_close, /* nothing on a close */ + .bdr_transfer = m_block_transfer, /* do the I/O */ + .bdr_ioctl = m_block_ioctl, /* ram disk I/O control */ + .bdr_part = m_block_part /* return partition information */ }; #define click_to_round_k(n) \ @@ -185,7 +179,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) /*===========================================================================* * m_is_block * *===========================================================================*/ -static int m_is_block(dev_t minor) +static int m_is_block(devminor_t minor) { /* Return TRUE iff the given minor device number is for a block device. */ @@ -409,10 +403,10 @@ static int m_do_close(message *m_ptr) /*===========================================================================* * m_block_part * *===========================================================================*/ -static struct device *m_block_part(dev_t minor) +static struct device *m_block_part(devminor_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); + if (minor < 0 || minor >= NR_DEVS || !m_is_block(minor)) return(NULL); return(&m_geom[minor]); } @@ -421,7 +415,7 @@ static struct device *m_block_part(dev_t minor) * m_block_transfer * *===========================================================================*/ static int m_block_transfer( - dev_t minor, /* minor device number */ + devminor_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 */ @@ -487,7 +481,7 @@ static int m_block_transfer( /*===========================================================================* * m_block_open * *===========================================================================*/ -static int m_block_open(dev_t minor, int UNUSED(access)) +static int m_block_open(devminor_t minor, int UNUSED(access)) { /* Open a memory block device. */ if (m_block_part(minor) == NULL) return(ENXIO); @@ -500,7 +494,7 @@ static int m_block_open(dev_t minor, int UNUSED(access)) /*===========================================================================* * m_block_close * *===========================================================================*/ -static int m_block_close(dev_t minor) +static int m_block_close(devminor_t minor) { /* Close a memory block device. */ if (m_block_part(minor) == NULL) return(ENXIO); @@ -517,8 +511,8 @@ static int m_block_close(dev_t minor) /*===========================================================================* * m_block_ioctl * *===========================================================================*/ -static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, - cp_grant_id_t grant) +static int m_block_ioctl(devminor_t minor, unsigned int request, + endpoint_t endpt, cp_grant_id_t grant) { /* I/O controls for the block devices of the memory driver. Currently there is * one I/O control specific to the memory driver: diff --git a/drivers/mmc/mmcblk.c b/drivers/mmc/mmcblk.c index c40143995..71ce29a1d 100644 --- a/drivers/mmc/mmcblk.c +++ b/drivers/mmc/mmcblk.c @@ -39,19 +39,19 @@ static struct mmc_host host; #define COPYBUFF_SIZE 0x1000 /* 4k buff */ static unsigned char copybuff[COPYBUFF_SIZE]; -static struct sd_slot *get_slot(dev_t minor); +static struct sd_slot *get_slot(devminor_t minor); /* Prototypes for the block device */ -static int block_open(dev_t minor, int access); -static int block_close(dev_t minor); -static int block_transfer(dev_t minor, +static int block_open(devminor_t minor, int access); +static int block_close(devminor_t minor); +static int block_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t endpt, iovec_t * iov, unsigned int nr_req, int flags); -static int block_ioctl(dev_t minor, +static int block_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); -static struct device *block_part(dev_t minor); +static struct device *block_part(devminor_t minor); /* System even handling */ static void sef_local_startup(); @@ -72,18 +72,14 @@ static void set_log_level(int level); /* Entry points for the BLOCK driver. */ static struct blockdriver mmc_driver = { - BLOCKDRIVER_TYPE_DISK, /* handle partition requests */ - block_open, /* open or mount */ - block_close, /* on a close */ - block_transfer, /* does the I/O */ - block_ioctl, /* ioclt's */ - NULL, /* no need to clean up (yet) */ - block_part, /* return partition information */ - NULL, /* no geometry */ - hw_intr, /* left over interrupts */ - bdr_alarm, /* no alarm processing */ - NULL, /* no processing of other messages */ - NULL /* no threading support */ + .bdr_type = BLOCKDRIVER_TYPE_DISK,/* handle partition requests */ + .bdr_open = block_open, /* device open */ + .bdr_close = block_close, /* on a close */ + .bdr_transfer = block_transfer, /* does the I/O */ + .bdr_ioctl = block_ioctl, /* ioctls */ + .bdr_part = block_part, /* get partition information */ + .bdr_intr = hw_intr, /* left over interrupts */ + .bdr_alarm = bdr_alarm /* no alarm processing */ }; static void @@ -141,7 +137,7 @@ apply_env() * block_open * *===========================================================================*/ static int -block_open(dev_t minor, int access) +block_open(devminor_t minor, int access) { struct sd_slot *slot; slot = get_slot(minor); @@ -213,7 +209,7 @@ block_open(dev_t minor, int access) * block_close * *===========================================================================*/ static int -block_close(dev_t minor) +block_close(devminor_t minor) { struct sd_slot *slot; @@ -280,7 +276,8 @@ copyfrom(endpoint_t src_e, * block_transfer * *===========================================================================*/ static int -block_transfer(dev_t minor, /* minor device number */ +block_transfer( + devminor_t minor, /* minor device number */ int do_write, /* read or write? */ u64_t position, /* offset on device to read or write */ endpoint_t endpt, /* process doing the request */ @@ -438,7 +435,7 @@ block_transfer(dev_t minor, /* minor device number */ * block_ioctl * *===========================================================================*/ static int -block_ioctl(dev_t minor, +block_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { /* IOCTL handling */ @@ -476,7 +473,7 @@ block_ioctl(dev_t minor, * block_part * *===========================================================================*/ static struct device * -block_part(dev_t minor) +block_part(devminor_t minor) { /* * Reuse the existing MINIX major/minor partitioning scheme. @@ -614,7 +611,7 @@ block_signal_handler_cb(int signo) #define IS_MINIX_SUB_PARTITION_MINOR(minor) (minor >= MINOR_d0p0s0 ) static struct sd_slot * -get_slot(dev_t minor) +get_slot(devminor_t minor) { /* * Get an sd_slot based on the minor number. @@ -626,7 +623,7 @@ get_slot(dev_t minor) * number 128 till 144 for sub partitions. */ /* If this is a minor for the first disk (e.g. minor 0 till 5) */ - if (minor / DEV_PER_DRIVE == 0) { + if (minor >= 0 && minor / DEV_PER_DRIVE == 0) { /* we are talking about the first disk and that is all we * support */ return &host.slot[0]; diff --git a/drivers/tda19988/tda19988.c b/drivers/tda19988/tda19988.c index c02c36946..551ee4f9e 100644 --- a/drivers/tda19988/tda19988.c +++ b/drivers/tda19988/tda19988.c @@ -163,14 +163,14 @@ static int check_revision(void); static int read_edid(uint8_t * data, size_t count); /* libblockdriver callbacks */ -static int tda19988_blk_open(dev_t minor, int access); -static int tda19988_blk_close(dev_t minor); -static ssize_t tda19988_blk_transfer(dev_t minor, int do_write, u64_t pos, - endpoint_t endpt, iovec_t * iov, unsigned count, int flags); -static int tda19988_blk_ioctl(dev_t minor, unsigned int request, +static int tda19988_blk_open(devminor_t minor, int access); +static int tda19988_blk_close(devminor_t minor); +static ssize_t tda19988_blk_transfer(devminor_t minor, int do_write, u64_t pos, + endpoint_t endpt, iovec_t * iov, unsigned int count, int flags); +static int tda19988_blk_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); -static struct device *tda19988_blk_part(dev_t minor); -static int tda19988_blk_other(message * m); +static struct device *tda19988_blk_part(devminor_t minor); +static void tda19988_blk_other(message * m, int ipc_status); /* Entry points into the device dependent code of block drivers. */ struct blockdriver tda19988_tab = { @@ -178,14 +178,9 @@ struct blockdriver tda19988_tab = { .bdr_open = tda19988_blk_open, .bdr_close = tda19988_blk_close, .bdr_transfer = tda19988_blk_transfer, - .bdr_ioctl = tda19988_blk_ioctl, /* nop -- always returns ENOTTY */ - .bdr_cleanup = NULL, /* nothing allocated -- nothing to clean up */ + .bdr_ioctl = tda19988_blk_ioctl, /* always returns ENOTTY */ .bdr_part = tda19988_blk_part, - .bdr_geometry = NULL, /* no geometry (cylinders, heads, sectors, etc) */ - .bdr_intr = NULL, /* i2c devices don't generate interrupts */ - .bdr_alarm = NULL, /* alarm not needed */ - .bdr_other = tda19988_blk_other, /* to recv notify events from DS */ - .bdr_device = NULL /* 1 insance per device, threads not needed */ + .bdr_other = tda19988_blk_other /* for notify events from DS */ }; /* counts the number of times a device file is open */ @@ -195,7 +190,7 @@ static int openct[NR_DEVS]; static struct device geom[NR_DEVS]; static int -tda19988_blk_open(dev_t minor, int access) +tda19988_blk_open(devminor_t minor, int access) { log_trace(&log, "tda19988_blk_open(%d,%d)\n", minor, access); if (tda19988_blk_part(minor) == NULL) { @@ -208,7 +203,7 @@ tda19988_blk_open(dev_t minor, int access) } static int -tda19988_blk_close(dev_t minor) +tda19988_blk_close(devminor_t minor) { log_trace(&log, "tda19988_blk_close(%d)\n", minor); if (tda19988_blk_part(minor) == NULL) { @@ -225,8 +220,8 @@ tda19988_blk_close(dev_t minor) } static ssize_t -tda19988_blk_transfer(dev_t minor, int do_write, u64_t pos64, - endpoint_t endpt, iovec_t * iov, unsigned nr_req, int flags) +tda19988_blk_transfer(devminor_t minor, int do_write, u64_t pos64, + endpoint_t endpt, iovec_t * iov, unsigned int nr_req, int flags) { unsigned count; struct device *dv; @@ -319,7 +314,7 @@ tda19988_blk_transfer(dev_t minor, int do_write, u64_t pos64, } static int -tda19988_blk_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, +tda19988_blk_ioctl(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { log_trace(&log, "tda19988_blk_ioctl(%d)\n", minor); @@ -328,26 +323,23 @@ tda19988_blk_ioctl(dev_t minor, unsigned int request, endpoint_t endpt, } static struct device * -tda19988_blk_part(dev_t minor) +tda19988_blk_part(devminor_t minor) { log_trace(&log, "tda19988_blk_part(%d)\n", minor); - if (minor >= NR_DEVS) { + if (minor < 0 || minor >= NR_DEVS) { return NULL; } return &geom[minor]; } -static int -tda19988_blk_other(message * m) +static void +tda19988_blk_other(message * m, int ipc_status) { - int r; - log_trace(&log, "tda19988_blk_other(0x%x)\n", m->m_type); - switch (m->m_type) { - case NOTIFY_MESSAGE: + if (is_ipc_notify(ipc_status)) { if (m->m_source == DS_PROC_NR) { log_debug(&log, "bus driver changed state, update endpoint\n"); @@ -356,15 +348,9 @@ tda19988_blk_other(message * m) i2cdriver_handle_bus_update(&hdmi_bus_endpoint, hdmi_bus, hdmi_address); } - r = OK; - break; - default: + } else { log_warn(&log, "Invalid message type (0x%x)\n", m->m_type); - r = EINVAL; - break; } - - return r; } /* diff --git a/drivers/virtio_blk/virtio_blk.c b/drivers/virtio_blk/virtio_blk.c index a4ce7e176..652f8691c 100644 --- a/drivers/virtio_blk/virtio_blk.c +++ b/drivers/virtio_blk/virtio_blk.c @@ -77,19 +77,19 @@ static u16_t *status_vir; static phys_bytes status_phys; /* Prototypes */ -static int virtio_blk_open(dev_t minor, int access); -static int virtio_blk_close(dev_t minor); -static ssize_t virtio_blk_transfer(dev_t minor, int write, u64_t position, +static int virtio_blk_open(devminor_t minor, int access); +static int virtio_blk_close(devminor_t minor); +static ssize_t virtio_blk_transfer(devminor_t minor, int write, u64_t position, endpoint_t endpt, iovec_t *iovec, unsigned int cnt, int flags); -static int virtio_blk_ioctl(dev_t minor, unsigned int req, endpoint_t endpt, - cp_grant_id_t grant); -static struct device * virtio_blk_part(dev_t minor); -static void virtio_blk_geometry(dev_t minor, struct part_geom *entry); +static int virtio_blk_ioctl(devminor_t minor, unsigned int req, + endpoint_t endpt, cp_grant_id_t grant); +static struct device * virtio_blk_part(devminor_t minor); +static void virtio_blk_geometry(devminor_t minor, struct part_geom *entry); static void virtio_blk_device_intr(void); static void virtio_blk_spurious_intr(void); static void virtio_blk_intr(unsigned int irqs); -static int virtio_blk_device(dev_t minor, device_id_t *id); +static int virtio_blk_device(devminor_t minor, device_id_t *id); static int virtio_blk_flush(void); static void virtio_blk_terminate(void); @@ -103,22 +103,19 @@ static int virtio_blk_probe(int skip); /* libblockdriver driver tab */ static struct blockdriver virtio_blk_dtab = { - BLOCKDRIVER_TYPE_DISK, - virtio_blk_open, - virtio_blk_close, - virtio_blk_transfer, - virtio_blk_ioctl, - NULL, /* bdr_cleanup */ - virtio_blk_part, - virtio_blk_geometry, - virtio_blk_intr, - NULL, /* bdr_alarm */ - NULL, /* bdr_other */ - virtio_blk_device + .bdr_type = BLOCKDRIVER_TYPE_DISK, + .bdr_open = virtio_blk_open, + .bdr_close = virtio_blk_close, + .bdr_transfer = virtio_blk_transfer, + .bdr_ioctl = virtio_blk_ioctl, + .bdr_part = virtio_blk_part, + .bdr_geometry = virtio_blk_geometry, + .bdr_intr = virtio_blk_intr, + .bdr_device = virtio_blk_device }; static int -virtio_blk_open(dev_t minor, int access) +virtio_blk_open(devminor_t minor, int access) { struct device *dev = virtio_blk_part(minor); @@ -146,7 +143,7 @@ virtio_blk_open(dev_t minor, int access) } static int -virtio_blk_close(dev_t minor) +virtio_blk_close(devminor_t minor) { struct device *dev = virtio_blk_part(minor); @@ -237,8 +234,9 @@ prepare_vir_vec(endpoint_t endpt, struct vumap_vir *vir, iovec_s_t *iv, } static ssize_t -virtio_blk_transfer(dev_t minor, int write, u64_t position, endpoint_t endpt, - iovec_t *iovec, unsigned int cnt, int flags) +virtio_blk_transfer(devminor_t minor, int write, u64_t position, + endpoint_t endpt, iovec_t *iovec, unsigned int cnt, + int flags) { /* Need to translate vir to phys */ struct vumap_vir vir[NR_IOREQS]; @@ -376,7 +374,7 @@ virtio_blk_transfer(dev_t minor, int write, u64_t position, endpoint_t endpt, } static int -virtio_blk_ioctl(dev_t minor, unsigned int req, endpoint_t endpt, +virtio_blk_ioctl(devminor_t minor, unsigned int req, endpoint_t endpt, cp_grant_id_t grant) { switch (req) { @@ -394,24 +392,22 @@ virtio_blk_ioctl(dev_t minor, unsigned int req, endpoint_t endpt, } static struct device * -virtio_blk_part(dev_t minor) +virtio_blk_part(devminor_t minor) { /* There's only a single drive attached to this device, alyways. * Lets take some shortcuts... */ /* Take care of d0 d0p0 ... */ - if (minor < 5) + if (minor >= 0 && minor < DEV_PER_DRIVE) return &part[minor]; - /* subparts start at 128 */ - if (minor >= 128) { - - /* Mask away upper bits */ - minor = minor & 0x7F; + /* subparts start at MINOR_d0p0s0 */ + if (minor >= MINOR_d0p0s0) { + minor -= MINOR_d0p0s0; /* Only for the first disk */ - if (minor > 15) + if (minor >= SUB_PER_DRIVE) return NULL; return &subpart[minor]; @@ -421,7 +417,7 @@ virtio_blk_part(dev_t minor) } static void -virtio_blk_geometry(dev_t minor, struct part_geom *entry) +virtio_blk_geometry(devminor_t minor, struct part_geom *entry) { /* Only for the drive */ if (minor != 0) @@ -470,7 +466,7 @@ virtio_blk_intr(unsigned int irqs) } static int -virtio_blk_device(dev_t minor, device_id_t *id) +virtio_blk_device(devminor_t minor, device_id_t *id) { struct device *dev = virtio_blk_part(minor); diff --git a/include/minix/blockdriver.h b/include/minix/blockdriver.h index 6d28265ee..3bc058cf3 100644 --- a/include/minix/blockdriver.h +++ b/include/minix/blockdriver.h @@ -15,19 +15,19 @@ typedef enum { /* Entry points into the device dependent code of block drivers. */ struct blockdriver { blockdriver_type_t bdr_type; - int(*bdr_open) (dev_t minor, int access); - int(*bdr_close) (dev_t minor); - ssize_t(*bdr_transfer) (dev_t minor, int do_write, u64_t pos, - endpoint_t endpt, iovec_t *iov, unsigned count, int flags); - int(*bdr_ioctl) (dev_t minor, unsigned int request, endpoint_t endpt, + int (*bdr_open)(devminor_t minor, int access); + int (*bdr_close)(devminor_t minor); + ssize_t (*bdr_transfer)(devminor_t minor, int do_write, u64_t pos, + endpoint_t endpt, iovec_t *iov, unsigned int count, int flags); + int (*bdr_ioctl)(devminor_t minor, unsigned int request, endpoint_t endpt, cp_grant_id_t grant); - void(*bdr_cleanup) (void); - struct device *(*bdr_part)(dev_t minor); - void(*bdr_geometry) (dev_t minor, struct part_geom *part); - void(*bdr_intr) (unsigned int irqs); - void(*bdr_alarm) (clock_t stamp); - int(*bdr_other) (message *m_ptr); - int(*bdr_device) (dev_t minor, device_id_t *id); + void (*bdr_cleanup)(void); + struct device *(*bdr_part)(devminor_t minor); + void (*bdr_geometry)(devminor_t minor, struct part_geom *part); + void (*bdr_intr)(unsigned int mask); + void (*bdr_alarm)(clock_t stamp); + void (*bdr_other)(message *m_ptr, int ipc_status); + int (*bdr_device)(devminor_t minor, device_id_t *id); }; /* Functions defined by libblockdriver. These can be used for both diff --git a/lib/libblockdriver/driver.c b/lib/libblockdriver/driver.c index eb3f479c8..04a095df0 100644 --- a/lib/libblockdriver/driver.c +++ b/lib/libblockdriver/driver.c @@ -128,40 +128,45 @@ void blockdriver_announce(int type) } /*===========================================================================* - * blockdriver_reply * + * send_reply * *===========================================================================*/ -void blockdriver_reply(message *m_ptr, int ipc_status, int reply) +static void send_reply(endpoint_t endpt, message *m_ptr, int ipc_status) { -/* Reply to a block request sent to the driver. */ - endpoint_t caller_e; - long id; +/* Send a reply message to a request. */ 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. The NOREPLY * flag is set because the caller may also issue a SENDREC (mixing sync and * async comm), and the asynchronous reply could otherwise end up satisfying * the SENDREC's receive part, after which our next SENDNB call would fail. */ if (IPC_STATUS_CALL(ipc_status) == SENDREC) - r = sendnb(caller_e, m_ptr); + r = sendnb(endpt, m_ptr); else - r = asynsend3(caller_e, m_ptr, AMF_NOREPLY); + r = asynsend3(endpt, m_ptr, AMF_NOREPLY); if (r != OK) - printf("blockdriver_reply: unable to send reply to %d: %d\n", - caller_e, r); + printf("blockdriver: unable to send reply to %d: %d\n", endpt, r); +} + +/*===========================================================================* + * blockdriver_reply * + *===========================================================================*/ +void blockdriver_reply(message *m_ptr, int ipc_status, int reply) +{ +/* Reply to a block request sent to the driver. */ + message m_reply; + + if (reply == EDONTREPLY) + return; + + memset(&m_reply, 0, sizeof(m_reply)); + + m_reply.m_type = BDEV_REPLY; + m_reply.BDEV_STATUS = reply; + m_reply.BDEV_ID = m_ptr->BDEV_ID; + + send_reply(m_ptr->m_source, &m_reply, ipc_status); } /*===========================================================================* @@ -175,7 +180,7 @@ static int do_open(struct blockdriver *bdp, message *mp) } /*===========================================================================* - * do_close * + * do_close * *===========================================================================*/ static int do_close(struct blockdriver *bdp, message *mp) { @@ -220,7 +225,7 @@ static int do_vrdwt(struct blockdriver *bdp, message *mp, thread_id_t id) { /* Carry out an device read or write to/from a vector of buffers. */ iovec_t iovec[NR_IOREQS]; - unsigned nr_req; + unsigned int nr_req; u64_t position; int i, do_write; ssize_t r, size; @@ -290,7 +295,7 @@ static int do_dioctl(struct blockdriver *bdp, dev_t minor, (*bdp->bdr_geometry)(minor, &entry); } else { /* The driver doesn't care -- make up fake geometry. */ - entry.cylinders = div64u(entry.size, SECTOR_SIZE); + entry.cylinders = div64u(entry.size, SECTOR_SIZE) / (64 * 32); entry.heads = 64; entry.sectors = 32; } @@ -352,52 +357,76 @@ static int do_ioctl(struct blockdriver *bdp, message *mp) } /*===========================================================================* - * blockdriver_handle_notify * + * do_char_open * *===========================================================================*/ -void blockdriver_handle_notify(struct blockdriver *bdp, message *m_ptr) +static void do_char_open(message *m_ptr, int ipc_status) { -/* Take care of the notifications (interrupt and clock messages) by calling - * the appropiate callback functions. Never send a reply. - */ +/* Reply to a character driver open request stating there is no such device. */ + message m_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; + memset(&m_reply, 0, sizeof(m_reply)); - case CLOCK: - if (bdp->bdr_alarm) - (*bdp->bdr_alarm)(m_ptr->NOTIFY_TIMESTAMP); - break; + m_reply.m_type = DEV_OPEN_REPL; + m_reply.REP_ENDPT = m_ptr->USER_ENDPT; + m_reply.REP_STATUS = ENXIO; - default: - if (bdp->bdr_other) - (void) (*bdp->bdr_other)(m_ptr); - } + send_reply(m_ptr->m_source, &m_reply, ipc_status); } /*===========================================================================* - * blockdriver_handle_request * + * blockdriver_process_on_thread * *===========================================================================*/ -int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr, - thread_id_t id) +void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr, + int ipc_status, thread_id_t id) { -/* 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. +/* Call the appropiate driver function, based on the type of request. Send + * a result code to the caller. The call is processed in the context of the + * given thread ID, which may be SINGLE_THREAD for single-threaded callers. */ int r; + /* Check for notifications first. We never reply to notifications. */ + if (is_ipc_notify(ipc_status)) { + 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) + (*bdp->bdr_other)(m_ptr, ipc_status); + } + + return; /* do not send a reply */ + } + + /* Reply to character driver open requests with an error code. Otherwise, if + * someone creates a character device node for a block driver, opening that + * device node will cause the corresponding VFS thread to block forever. + */ + if (m_ptr->m_type == DEV_OPEN) { + do_char_open(m_ptr, ipc_status); + + return; + } + /* 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; + if (m_ptr->m_type != BDEV_OPEN) { + blockdriver_reply(m_ptr, ipc_status, ERESTART); + + return; + } /* Mark the device as opened otherwise. */ set_open_dev(m_ptr->BDEV_MINOR); @@ -415,10 +444,10 @@ int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr, case BDEV_SCATTER: r = do_vrdwt(bdp, m_ptr, id); 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; + if (bdp->bdr_other != NULL) + (*bdp->bdr_other)(m_ptr, ipc_status); + + return; /* do not send a reply */ } /* Let the driver perform any cleanup. */ @@ -427,5 +456,5 @@ int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr, trace_finish(id, r); - return r; + blockdriver_reply(m_ptr, ipc_status, r); } diff --git a/lib/libblockdriver/driver.h b/lib/libblockdriver/driver.h index 92dfb8cad..d02f5f71f 100644 --- a/lib/libblockdriver/driver.h +++ b/lib/libblockdriver/driver.h @@ -1,9 +1,8 @@ #ifndef _BLOCKDRIVER_DRIVER_H #define _BLOCKDRIVER_DRIVER_H -void blockdriver_handle_notify(struct blockdriver *bdp, message *m_ptr); -int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr, - thread_id_t thread); +void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr, + int ipc_status, thread_id_t thread); void blockdriver_reply(message *m_ptr, int ipc_status, int reply); #endif /* _BLOCKDRIVER_DRIVER_H */ diff --git a/lib/libblockdriver/driver_mt.c b/lib/libblockdriver/driver_mt.c index 31be86fec..6a8a5ef67 100644 --- a/lib/libblockdriver/driver_mt.c +++ b/lib/libblockdriver/driver_mt.c @@ -184,9 +184,7 @@ static void *worker_thread(void *param) mthread_rwlock_wrlock(&dp->barrier); /* Handle the request and send a reply. */ - r = blockdriver_handle_request(bdtab, &m, tid); - - blockdriver_reply(&m, ipc_status, r); + blockdriver_process_on_thread(bdtab, &m, ipc_status, tid); /* Switch the thread back to running state, and unlock the barrier. */ wp->state = STATE_RUNNING; @@ -274,13 +272,14 @@ static void master_handle_exits(void) } /*===========================================================================* - * master_handle_request * + * master_handle_message * *===========================================================================*/ -static void master_handle_request(message *m_ptr, int ipc_status) +static void master_handle_message(message *m_ptr, int ipc_status) { /* For real request messages, query the device ID, start a thread if none is * free and the maximum number of threads for that device has not yet been - * reached, and enqueue the message in the devices's message queue. + * reached, and enqueue the message in the devices's message queue. All other + * messages are handled immediately from the main thread. */ device_id_t id; worker_t *wp; @@ -291,11 +290,9 @@ static void master_handle_request(message *m_ptr, int ipc_status) * 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_BDEV_RQ(m_ptr->m_type)) { + if (is_ipc_notify(ipc_status) || !IS_BDEV_RQ(m_ptr->m_type)) { /* Process as 'other' message. */ - r = blockdriver_handle_request(bdtab, m_ptr, MAIN_THREAD); - - blockdriver_reply(m_ptr, ipc_status, r); + blockdriver_process_on_thread(bdtab, m_ptr, ipc_status, MAIN_THREAD); return; } @@ -423,10 +420,7 @@ void blockdriver_mt_task(struct blockdriver *driver_tab) blockdriver_mt_receive(&mess, &ipc_status); /* Dispatch the message. */ - if (is_ipc_notify(ipc_status)) - blockdriver_handle_notify(bdtab, &mess); - else - master_handle_request(&mess, ipc_status); + master_handle_message(&mess, ipc_status); /* Let other threads run. */ mthread_yield_all(); diff --git a/lib/libblockdriver/driver_st.c b/lib/libblockdriver/driver_st.c index 3fb10632e..4b105a31a 100644 --- a/lib/libblockdriver/driver_st.c +++ b/lib/libblockdriver/driver_st.c @@ -6,7 +6,6 @@ * 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 */ @@ -43,6 +42,8 @@ void blockdriver_terminate(void) /* Break out of the main driver loop after finishing the current request. */ running = FALSE; + + sef_cancel(); } /*===========================================================================* @@ -60,8 +61,12 @@ void blockdriver_task(struct blockdriver *bdp) * it out, and sends a reply. */ while (running) { - if ((r = blockdriver_receive_mq(&mess, &ipc_status)) != OK) + if ((r = blockdriver_receive_mq(&mess, &ipc_status)) != OK) { + if (r == EINTR && !running) + break; + panic("blockdriver_receive_mq failed: %d", r); + } blockdriver_process(bdp, &mess, ipc_status); } @@ -74,18 +79,8 @@ 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, SINGLE_THREAD); - - blockdriver_reply(m_ptr, ipc_status, r); - } + blockdriver_process_on_thread(bdp, m_ptr, ipc_status, SINGLE_THREAD); } /*===========================================================================*