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
This commit is contained in:
David van Moolenbroek 2013-09-11 13:33:00 +02:00 committed by Lionel Sambuc
parent 26cb85535e
commit 0f7f3c0d54
14 changed files with 313 additions and 356 deletions

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -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;

View file

@ -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;

View file

@ -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:

View file

@ -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];

View file

@ -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;
}
/*

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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 */

View file

@ -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();

View file

@ -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);
}
/*===========================================================================*