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:
parent
26cb85535e
commit
0f7f3c0d54
14 changed files with 313 additions and 356 deletions
|
@ -236,32 +236,29 @@ static void port_timeout(struct timer *tp);
|
||||||
static void port_disconnect(struct port_state *ps);
|
static void port_disconnect(struct port_state *ps);
|
||||||
|
|
||||||
static char *ahci_portname(struct port_state *ps);
|
static char *ahci_portname(struct port_state *ps);
|
||||||
static int ahci_open(dev_t minor, int access);
|
static int ahci_open(devminor_t minor, int access);
|
||||||
static int ahci_close(dev_t minor);
|
static int ahci_close(devminor_t minor);
|
||||||
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);
|
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 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);
|
cp_grant_id_t grant);
|
||||||
static void ahci_intr(unsigned int mask);
|
static void ahci_intr(unsigned int mask);
|
||||||
static int ahci_device(dev_t minor, device_id_t *id);
|
static int ahci_device(devminor_t minor, device_id_t *id);
|
||||||
static struct port_state *ahci_get_port(dev_t minor);
|
static struct port_state *ahci_get_port(devminor_t minor);
|
||||||
|
|
||||||
/* AHCI driver table. */
|
/* AHCI driver table. */
|
||||||
static struct blockdriver ahci_dtab = {
|
static struct blockdriver ahci_dtab = {
|
||||||
BLOCKDRIVER_TYPE_DISK,
|
.bdr_type = BLOCKDRIVER_TYPE_DISK,
|
||||||
ahci_open,
|
.bdr_open = ahci_open,
|
||||||
ahci_close,
|
.bdr_close = ahci_close,
|
||||||
ahci_transfer,
|
.bdr_transfer = ahci_transfer,
|
||||||
ahci_ioctl,
|
.bdr_ioctl = ahci_ioctl,
|
||||||
NULL, /* bdr_cleanup */
|
.bdr_part = ahci_part,
|
||||||
ahci_part,
|
.bdr_intr = ahci_intr,
|
||||||
NULL, /* bdr_geometry */
|
.bdr_alarm = ahci_alarm,
|
||||||
ahci_intr,
|
.bdr_device = ahci_device
|
||||||
ahci_alarm,
|
|
||||||
NULL, /* bdr_other */
|
|
||||||
ahci_device
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -2422,7 +2419,7 @@ static char *ahci_portname(struct port_state *ps)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ahci_map_minor *
|
* 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
|
/* 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
|
* 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;
|
ps = NULL;
|
||||||
|
|
||||||
if (minor < NR_MINORS) {
|
if (minor >= 0 && minor < NR_MINORS) {
|
||||||
port = ahci_map[minor / DEV_PER_DRIVE];
|
port = ahci_map[minor / DEV_PER_DRIVE];
|
||||||
|
|
||||||
if (port == NO_PORT)
|
if (port == NO_PORT)
|
||||||
|
@ -2458,7 +2455,7 @@ static struct port_state *ahci_map_minor(dev_t minor, struct device **dvp)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ahci_part *
|
* 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
|
/* Return a pointer to the partition information structure of the given
|
||||||
* minor device.
|
* minor device.
|
||||||
|
@ -2474,7 +2471,7 @@ static struct device *ahci_part(dev_t minor)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ahci_open *
|
* ahci_open *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int ahci_open(dev_t minor, int access)
|
static int ahci_open(devminor_t minor, int access)
|
||||||
{
|
{
|
||||||
/* Open a device.
|
/* Open a device.
|
||||||
*/
|
*/
|
||||||
|
@ -2543,7 +2540,7 @@ static int ahci_open(dev_t minor, int access)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ahci_close *
|
* ahci_close *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int ahci_close(dev_t minor)
|
static int ahci_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
/* Close a device.
|
/* Close a device.
|
||||||
*/
|
*/
|
||||||
|
@ -2599,7 +2596,7 @@ static int ahci_close(dev_t minor)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ahci_transfer *
|
* 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)
|
endpoint_t endpt, iovec_t *iovec, unsigned int count, int flags)
|
||||||
{
|
{
|
||||||
/* Perform data transfer on the selected device.
|
/* 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 *
|
* 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)
|
cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
/* Process I/O control requests.
|
/* Process I/O control requests.
|
||||||
|
@ -2691,7 +2688,7 @@ static int ahci_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ahci_device *
|
* 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.
|
/* 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 *
|
* 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.
|
/* Get the port structure associated with the given minor device.
|
||||||
* Called only from worker threads, so the minor device is already
|
* Called only from worker threads, so the minor device is already
|
||||||
|
|
|
@ -140,14 +140,14 @@ static void init_params(void);
|
||||||
static void init_drive(struct wini *w, int base_cmd, int base_ctl, int
|
static void init_drive(struct wini *w, int base_cmd, int base_ctl, int
|
||||||
base_dma, int irq, int ack, int hook, int drive);
|
base_dma, int irq, int ack, int hook, int drive);
|
||||||
static void init_params_pci(int);
|
static void init_params_pci(int);
|
||||||
static int w_do_open(dev_t minor, int access);
|
static int w_do_open(devminor_t minor, int access);
|
||||||
static struct device *w_prepare(dev_t dev);
|
static struct device *w_prepare(devminor_t dev);
|
||||||
static struct device *w_part(dev_t minor);
|
static struct device *w_part(devminor_t minor);
|
||||||
static int w_identify(void);
|
static int w_identify(void);
|
||||||
static char *w_name(void);
|
static char *w_name(void);
|
||||||
static int w_specify(void);
|
static int w_specify(void);
|
||||||
static int w_io_test(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);
|
endpoint_t proc_nr, iovec_t *iov, unsigned int nr_req, int flags);
|
||||||
static int com_out(struct command *cmd);
|
static int com_out(struct command *cmd);
|
||||||
static int com_out_ext(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);
|
size_t addr_offset, int do_write);
|
||||||
static void w_need_reset(void);
|
static void w_need_reset(void);
|
||||||
static void ack_irqs(unsigned int);
|
static void ack_irqs(unsigned int);
|
||||||
static int w_do_close(dev_t minor);
|
static int w_do_close(devminor_t minor);
|
||||||
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);
|
cp_grant_id_t grant);
|
||||||
static void w_hw_int(unsigned int irqs);
|
static void w_hw_int(unsigned int irqs);
|
||||||
static int com_simple(struct command *cmd);
|
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 at_intr_wait(void);
|
||||||
static int w_waitfor(int mask, int value);
|
static int w_waitfor(int mask, int value);
|
||||||
static int w_waitfor_dma(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
|
#if ENABLE_ATAPI
|
||||||
static int atapi_sendpacket(u8_t *packet, unsigned cnt, int do_dma);
|
static int atapi_sendpacket(u8_t *packet, unsigned cnt, int do_dma);
|
||||||
static int atapi_intr_wait(int dma, size_t max);
|
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. */
|
/* Entry points to this driver. */
|
||||||
static struct blockdriver w_dtab = {
|
static struct blockdriver w_dtab = {
|
||||||
BLOCKDRIVER_TYPE_DISK,/* handle partition requests */
|
.bdr_type = BLOCKDRIVER_TYPE_DISK, /* handle partition requests */
|
||||||
w_do_open, /* open or mount request, initialize device */
|
.bdr_open = w_do_open, /* open or mount request, initialize device */
|
||||||
w_do_close, /* release device */
|
.bdr_close = w_do_close, /* release device */
|
||||||
w_transfer, /* do the I/O */
|
.bdr_transfer = w_transfer, /* do the I/O */
|
||||||
w_ioctl, /* I/O control requests */
|
.bdr_ioctl = w_ioctl, /* I/O control requests */
|
||||||
NULL, /* nothing to clean up */
|
.bdr_part = w_part, /* return partition information */
|
||||||
w_part, /* return partition information */
|
.bdr_geometry = w_geometry, /* tell the geometry of the disk */
|
||||||
w_geometry, /* tell the geometry of the disk */
|
.bdr_intr = w_hw_int, /* leftover hardware interrupts */
|
||||||
w_hw_int, /* leftover hardware interrupts */
|
|
||||||
NULL, /* ignore leftover alarms */
|
|
||||||
NULL, /* ignore unrecognized messages */
|
|
||||||
NULL /* no multithreading support */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SEF functions and variables. */
|
/* SEF functions and variables. */
|
||||||
|
@ -583,7 +579,7 @@ static void init_params_pci(int skip)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* w_do_open *
|
* 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. */
|
/* 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 *
|
* 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. */
|
/* Prepare for I/O on a device. */
|
||||||
w_device = (int) 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_drive = device / DEV_PER_DRIVE; /* save drive number */
|
||||||
w_wn = &wini[w_drive];
|
w_wn = &wini[w_drive];
|
||||||
w_dv = &w_wn->part[device % DEV_PER_DRIVE];
|
w_dv = &w_wn->part[device % DEV_PER_DRIVE];
|
||||||
|
@ -676,7 +672,7 @@ static struct device *w_prepare(dev_t device)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* w_part *
|
* 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. */
|
/* 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 *
|
* w_transfer *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static ssize_t 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? */
|
int do_write, /* read or write? */
|
||||||
u64_t position, /* offset on device to read or write */
|
u64_t position, /* offset on device to read or write */
|
||||||
endpoint_t proc_nr, /* process doing the request */
|
endpoint_t proc_nr, /* process doing the request */
|
||||||
|
@ -1640,7 +1636,7 @@ static void w_need_reset(void)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* w_do_close *
|
* w_do_close *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int w_do_close(dev_t minor)
|
static int w_do_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
/* Device close: Release a device. */
|
/* Device close: Release a device. */
|
||||||
if (w_prepare(minor) == NULL)
|
if (w_prepare(minor) == NULL)
|
||||||
|
@ -1882,7 +1878,7 @@ int value; /* required status */
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* w_geometry *
|
* 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;
|
struct wini *wn;
|
||||||
|
|
||||||
|
@ -2215,7 +2211,7 @@ int do_dma;
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* w_ioctl *
|
* 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)
|
cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int r, timeout, prev, count;
|
int r, timeout, prev, count;
|
||||||
|
|
|
@ -29,14 +29,14 @@ static int sef_cb_lu_state_save(int);
|
||||||
static int lu_state_restore(void);
|
static int lu_state_restore(void);
|
||||||
|
|
||||||
/* libblockdriver callbacks */
|
/* libblockdriver callbacks */
|
||||||
static int cat24c256_blk_open(dev_t minor, int access);
|
static int cat24c256_blk_open(devminor_t minor, int access);
|
||||||
static int cat24c256_blk_close(dev_t minor);
|
static int cat24c256_blk_close(devminor_t minor);
|
||||||
static ssize_t cat24c256_blk_transfer(dev_t minor, int do_write, u64_t pos,
|
static ssize_t cat24c256_blk_transfer(devminor_t minor, int do_write,
|
||||||
endpoint_t endpt, iovec_t * iov, unsigned count, int flags);
|
u64_t pos, endpoint_t endpt, iovec_t * iov, unsigned int count, int flags);
|
||||||
static int cat24c256_blk_ioctl(dev_t minor, unsigned int request,
|
static int cat24c256_blk_ioctl(devminor_t minor, unsigned int request,
|
||||||
endpoint_t endpt, cp_grant_id_t grant);
|
endpoint_t endpt, cp_grant_id_t grant);
|
||||||
static struct device *cat24c256_blk_part(dev_t minor);
|
static struct device *cat24c256_blk_part(devminor_t minor);
|
||||||
static int cat24c256_blk_other(message * m);
|
static void cat24c256_blk_other(message * m, int ipc_status);
|
||||||
|
|
||||||
/* Entry points into the device dependent code of block drivers. */
|
/* Entry points into the device dependent code of block drivers. */
|
||||||
struct blockdriver cat24c256_tab = {
|
struct blockdriver cat24c256_tab = {
|
||||||
|
@ -44,14 +44,9 @@ struct blockdriver cat24c256_tab = {
|
||||||
.bdr_open = cat24c256_blk_open,
|
.bdr_open = cat24c256_blk_open,
|
||||||
.bdr_close = cat24c256_blk_close,
|
.bdr_close = cat24c256_blk_close,
|
||||||
.bdr_transfer = cat24c256_blk_transfer,
|
.bdr_transfer = cat24c256_blk_transfer,
|
||||||
.bdr_ioctl = cat24c256_blk_ioctl, /* nop -- always returns EINVAL */
|
.bdr_ioctl = cat24c256_blk_ioctl, /* always returns ENOTTY */
|
||||||
.bdr_cleanup = NULL, /* nothing allocated -- nothing to clean up */
|
|
||||||
.bdr_part = cat24c256_blk_part,
|
.bdr_part = cat24c256_blk_part,
|
||||||
.bdr_geometry = NULL, /* no geometry (cylinders, heads, sectors, etc) */
|
.bdr_other = cat24c256_blk_other /* for notify events from DS */
|
||||||
.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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cat24c256_read128(uint16_t memaddr, void *buf, size_t buflen, int flags);
|
static int cat24c256_read128(uint16_t memaddr, void *buf, size_t buflen, int flags);
|
||||||
|
@ -84,7 +79,7 @@ static struct log log = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
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);
|
log_trace(&log, "cat24c256_blk_open(%d,%d)\n", minor, access);
|
||||||
if (cat24c256_blk_part(minor) == NULL) {
|
if (cat24c256_blk_part(minor) == NULL) {
|
||||||
|
@ -97,7 +92,7 @@ cat24c256_blk_open(dev_t minor, int access)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cat24c256_blk_close(dev_t minor)
|
cat24c256_blk_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
log_trace(&log, "cat24c256_blk_close(%d)\n", minor);
|
log_trace(&log, "cat24c256_blk_close(%d)\n", minor);
|
||||||
if (cat24c256_blk_part(minor) == NULL) {
|
if (cat24c256_blk_part(minor) == NULL) {
|
||||||
|
@ -114,11 +109,11 @@ cat24c256_blk_close(dev_t minor)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
cat24c256_blk_transfer(dev_t minor, int do_write, u64_t pos64,
|
cat24c256_blk_transfer(devminor_t minor, int do_write, u64_t pos64,
|
||||||
endpoint_t endpt, iovec_t * iov, unsigned nr_req, int flags)
|
endpoint_t endpt, iovec_t * iov, unsigned int nr_req, int flags)
|
||||||
{
|
{
|
||||||
/* Read or write one the driver's block devices. */
|
/* Read or write one the driver's block devices. */
|
||||||
unsigned count;
|
unsigned int count;
|
||||||
struct device *dv;
|
struct device *dv;
|
||||||
u64_t dv_size;
|
u64_t dv_size;
|
||||||
int r;
|
int r;
|
||||||
|
@ -214,7 +209,7 @@ cat24c256_blk_transfer(dev_t minor, int do_write, u64_t pos64,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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)
|
cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
log_trace(&log, "cat24c256_blk_ioctl(%d)\n", minor);
|
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 *
|
static struct device *
|
||||||
cat24c256_blk_part(dev_t minor)
|
cat24c256_blk_part(devminor_t minor)
|
||||||
{
|
{
|
||||||
log_trace(&log, "cat24c256_blk_part(%d)\n", minor);
|
log_trace(&log, "cat24c256_blk_part(%d)\n", minor);
|
||||||
|
|
||||||
if (minor >= NR_DEVS) {
|
if (minor < 0 || minor >= NR_DEVS) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &geom[minor];
|
return &geom[minor];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
cat24c256_blk_other(message * m)
|
cat24c256_blk_other(message * m, int ipc_status)
|
||||||
{
|
{
|
||||||
int r;
|
|
||||||
|
|
||||||
log_trace(&log, "cat24c256_blk_other(0x%x)\n", m->m_type);
|
log_trace(&log, "cat24c256_blk_other(0x%x)\n", m->m_type);
|
||||||
|
|
||||||
switch (m->m_type) {
|
if (is_ipc_notify(ipc_status)) {
|
||||||
case NOTIFY_MESSAGE:
|
|
||||||
if (m->m_source == DS_PROC_NR) {
|
if (m->m_source == DS_PROC_NR) {
|
||||||
log_debug(&log,
|
log_debug(&log,
|
||||||
"bus driver changed state, update endpoint\n");
|
"bus driver changed state, update endpoint\n");
|
||||||
i2cdriver_handle_bus_update(&bus_endpoint, bus,
|
i2cdriver_handle_bus_update(&bus_endpoint, bus,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
r = OK;
|
} else
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log_warn(&log, "Invalid message type (0x%x)\n", m->m_type);
|
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.
|
/* The lower level i2c interface can only read/write 128 bytes at a time.
|
||||||
|
|
|
@ -15,34 +15,27 @@
|
||||||
#define BUF_SIZE (NR_IOREQS * CLICK_SIZE) /* 256k */
|
#define BUF_SIZE (NR_IOREQS * CLICK_SIZE) /* 256k */
|
||||||
|
|
||||||
/* Function declarations. */
|
/* Function declarations. */
|
||||||
static int fbd_open(dev_t minor, int access);
|
static int fbd_open(devminor_t minor, int access);
|
||||||
static int fbd_close(dev_t minor);
|
static int fbd_close(devminor_t minor);
|
||||||
static int fbd_transfer(dev_t minor, int do_write, u64_t position,
|
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);
|
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);
|
cp_grant_id_t grant);
|
||||||
|
|
||||||
/* Variables. */
|
/* Variables. */
|
||||||
static char *fbd_buf; /* scratch buffer */
|
static char *fbd_buf; /* scratch buffer */
|
||||||
|
|
||||||
static char driver_label[32] = ""; /* driver DS label */
|
static char driver_label[32] = ""; /* driver DS label */
|
||||||
static dev_t driver_minor = -1; /* driver's partition minor to use */
|
static devminor_t driver_minor = -1; /* driver's partition minor to use */
|
||||||
static endpoint_t driver_endpt; /* driver endpoint */
|
static endpoint_t driver_endpt; /* driver endpoint */
|
||||||
|
|
||||||
/* Entry points to this driver. */
|
/* Entry points to this driver. */
|
||||||
static struct blockdriver fbd_dtab = {
|
static struct blockdriver fbd_dtab = {
|
||||||
BLOCKDRIVER_TYPE_OTHER, /* do not handle partition requests */
|
.bdr_type = BLOCKDRIVER_TYPE_OTHER,/* do not handle part. reqs */
|
||||||
fbd_open, /* open or mount request, initialize device */
|
.bdr_open = fbd_open, /* open request, initialize device */
|
||||||
fbd_close, /* release device */
|
.bdr_close = fbd_close, /* release device */
|
||||||
fbd_transfer, /* do the I/O */
|
.bdr_transfer = fbd_transfer, /* do the I/O */
|
||||||
fbd_ioctl, /* perform I/O control request */
|
.bdr_ioctl = 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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Options supported by this driver. */
|
/* Options supported by this driver. */
|
||||||
|
@ -147,7 +140,7 @@ int main(int argc, char **argv)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* fbd_open *
|
* 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. */
|
/* Open a device. */
|
||||||
message m;
|
message m;
|
||||||
|
@ -172,7 +165,7 @@ static int fbd_open(dev_t UNUSED(minor), int access)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* fbd_close *
|
* fbd_close *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int fbd_close(dev_t UNUSED(minor))
|
static int fbd_close(devminor_t UNUSED(minor))
|
||||||
{
|
{
|
||||||
/* Close a device. */
|
/* Close a device. */
|
||||||
message m;
|
message m;
|
||||||
|
@ -196,7 +189,7 @@ static int fbd_close(dev_t UNUSED(minor))
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* fbd_ioctl *
|
* 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)
|
endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
/* Handle an I/O control request. */
|
/* Handle an I/O control request. */
|
||||||
|
@ -406,11 +399,11 @@ static ssize_t fbd_transfer_copy(int do_write, u64_t position,
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* fbd_transfer *
|
* 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)
|
endpoint_t endpt, iovec_t *iov, unsigned int nr_req, int flags)
|
||||||
{
|
{
|
||||||
/* Transfer data from or to the device. */
|
/* Transfer data from or to the device. */
|
||||||
unsigned count;
|
unsigned int count;
|
||||||
size_t size, osize;
|
size_t size, osize;
|
||||||
int i, hooks;
|
int i, hooks;
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
|
|
@ -242,10 +242,10 @@ static void f_expire_tmrs(clock_t stamp);
|
||||||
static void stop_motor(timer_t *tp);
|
static void stop_motor(timer_t *tp);
|
||||||
static void f_timeout(timer_t *tp);
|
static void f_timeout(timer_t *tp);
|
||||||
|
|
||||||
static struct device *f_prepare(dev_t device);
|
static struct device *f_prepare(devminor_t device);
|
||||||
static struct device *f_part(dev_t minor);
|
static struct device *f_part(devminor_t minor);
|
||||||
static void f_cleanup(void);
|
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);
|
endpoint_t proc_nr, iovec_t *iov, unsigned int nr_req, int flags);
|
||||||
static int dma_setup(int do_write);
|
static int dma_setup(int do_write);
|
||||||
static void start_motor(void);
|
static void start_motor(void);
|
||||||
|
@ -258,25 +258,21 @@ static int recalibrate(void);
|
||||||
static void f_reset(void);
|
static void f_reset(void);
|
||||||
static int f_intr_wait(void);
|
static int f_intr_wait(void);
|
||||||
static int read_id(void);
|
static int read_id(void);
|
||||||
static int f_do_open(dev_t minor, int access);
|
static int f_do_open(devminor_t minor, int access);
|
||||||
static int f_do_close(dev_t minor);
|
static int f_do_close(devminor_t minor);
|
||||||
static int test_read(int density);
|
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. */
|
/* Entry points to this driver. */
|
||||||
static struct blockdriver f_dtab = {
|
static struct blockdriver f_dtab = {
|
||||||
BLOCKDRIVER_TYPE_DISK, /* handle partition requests */
|
.bdr_type = BLOCKDRIVER_TYPE_DISK, /* handle partition requests */
|
||||||
f_do_open, /* open or mount request, sense type of diskette */
|
.bdr_open = f_do_open, /* open request, sense type of diskette */
|
||||||
f_do_close, /* nothing on a close */
|
.bdr_close = f_do_close, /* nothing on a close */
|
||||||
f_transfer, /* do the I/O */
|
.bdr_transfer = f_transfer, /* do the I/O */
|
||||||
NULL, /* no other I/O control requests are supported */
|
.bdr_cleanup = f_cleanup, /* cleanup before sending reply to caller */
|
||||||
f_cleanup, /* cleanup before sending reply to user process */
|
.bdr_part = f_part, /* return partition information structure */
|
||||||
f_part, /* return partition information structure */
|
.bdr_geometry = f_geometry, /* tell the geometry of the diskette */
|
||||||
f_geometry, /* tell the geometry of the diskette */
|
.bdr_alarm = f_expire_tmrs /* expire all alarm timers */
|
||||||
NULL, /* no processing of hardware interrupts */
|
|
||||||
f_expire_tmrs,/* expire all alarm timers */
|
|
||||||
NULL, /* no processing of other messages */
|
|
||||||
NULL /* no threading support */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *floppy_buf;
|
static char *floppy_buf;
|
||||||
|
@ -397,13 +393,13 @@ static void f_expire_tmrs(clock_t stamp)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* f_prepare *
|
* 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. */
|
/* Prepare for I/O on a device. */
|
||||||
|
|
||||||
f_device = device;
|
f_device = device;
|
||||||
f_drive = device & ~(DEV_TYPE_BITS | FORMAT_DEV_BIT);
|
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_fp = &floppy[f_drive];
|
||||||
f_dv = &f_fp->fl_geom;
|
f_dv = &f_fp->fl_geom;
|
||||||
|
@ -424,7 +420,7 @@ static struct device *f_prepare(dev_t device)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* f_part *
|
* 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. */
|
/* Return a pointer to the partition information of the given minor device. */
|
||||||
|
|
||||||
|
@ -447,7 +443,7 @@ static void f_cleanup(void)
|
||||||
* f_transfer *
|
* f_transfer *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static ssize_t 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? */
|
int do_write, /* read or write? */
|
||||||
u64_t pos64, /* offset on device to read or write */
|
u64_t pos64, /* offset on device to read or write */
|
||||||
endpoint_t proc_nr, /* process doing the request */
|
endpoint_t proc_nr, /* process doing the request */
|
||||||
|
@ -1251,7 +1247,7 @@ static int read_id(void)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* f_do_open *
|
* 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. */
|
/* 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 *
|
* 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. */
|
/* Handle a close on a floppy. Nothing to do here. */
|
||||||
|
|
||||||
|
@ -1350,7 +1346,7 @@ static int test_read(int density)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* f_geometry *
|
* 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;
|
if (f_prepare(minor) == NULL) return;
|
||||||
|
|
||||||
|
|
|
@ -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_open(message *m_ptr);
|
||||||
static int m_do_close(message *m_ptr);
|
static int m_do_close(message *m_ptr);
|
||||||
|
|
||||||
static struct device *m_block_part(dev_t minor);
|
static struct device *m_block_part(devminor_t minor);
|
||||||
static int m_block_transfer(dev_t minor, int do_write, u64_t position,
|
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);
|
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_open(devminor_t minor, int access);
|
||||||
static int m_block_close(dev_t minor);
|
static int m_block_close(devminor_t minor);
|
||||||
static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t
|
static int m_block_ioctl(devminor_t minor, unsigned int request, endpoint_t
|
||||||
endpt, cp_grant_id_t grant);
|
endpt, cp_grant_id_t grant);
|
||||||
|
|
||||||
/* Entry points to the CHARACTER part of this driver. */
|
/* 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. */
|
/* Entry points to the BLOCK part of this driver. */
|
||||||
static struct blockdriver m_bdtab = {
|
static struct blockdriver m_bdtab = {
|
||||||
BLOCKDRIVER_TYPE_DISK,/* handle partition requests */
|
.bdr_type = BLOCKDRIVER_TYPE_DISK,/* handle partition requests */
|
||||||
m_block_open, /* open or mount */
|
.bdr_open = m_block_open, /* open device */
|
||||||
m_block_close, /* nothing on a close */
|
.bdr_close = m_block_close, /* nothing on a close */
|
||||||
m_block_transfer, /* do the I/O */
|
.bdr_transfer = m_block_transfer, /* do the I/O */
|
||||||
m_block_ioctl, /* ram disk I/O control */
|
.bdr_ioctl = m_block_ioctl, /* ram disk I/O control */
|
||||||
NULL, /* no need to clean up */
|
.bdr_part = m_block_part /* return partition information */
|
||||||
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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define click_to_round_k(n) \
|
#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 *
|
* 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. */
|
/* 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 *
|
* 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. */
|
/* 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]);
|
return(&m_geom[minor]);
|
||||||
}
|
}
|
||||||
|
@ -421,7 +415,7 @@ static struct device *m_block_part(dev_t minor)
|
||||||
* m_block_transfer *
|
* m_block_transfer *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int 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? */
|
int do_write, /* read or write? */
|
||||||
u64_t pos64, /* offset on device to read or write */
|
u64_t pos64, /* offset on device to read or write */
|
||||||
endpoint_t endpt, /* process doing the request */
|
endpoint_t endpt, /* process doing the request */
|
||||||
|
@ -487,7 +481,7 @@ static int m_block_transfer(
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* m_block_open *
|
* 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. */
|
/* Open a memory block device. */
|
||||||
if (m_block_part(minor) == NULL) return(ENXIO);
|
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 *
|
* m_block_close *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int m_block_close(dev_t minor)
|
static int m_block_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
/* Close a memory block device. */
|
/* Close a memory block device. */
|
||||||
if (m_block_part(minor) == NULL) return(ENXIO);
|
if (m_block_part(minor) == NULL) return(ENXIO);
|
||||||
|
@ -517,8 +511,8 @@ static int m_block_close(dev_t minor)
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* m_block_ioctl *
|
* m_block_ioctl *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int m_block_ioctl(dev_t minor, unsigned int request, endpoint_t endpt,
|
static int m_block_ioctl(devminor_t minor, unsigned int request,
|
||||||
cp_grant_id_t grant)
|
endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
/* I/O controls for the block devices of the memory driver. Currently there is
|
/* I/O controls for the block devices of the memory driver. Currently there is
|
||||||
* one I/O control specific to the memory driver:
|
* one I/O control specific to the memory driver:
|
||||||
|
|
|
@ -39,19 +39,19 @@ static struct mmc_host host;
|
||||||
#define COPYBUFF_SIZE 0x1000 /* 4k buff */
|
#define COPYBUFF_SIZE 0x1000 /* 4k buff */
|
||||||
static unsigned char copybuff[COPYBUFF_SIZE];
|
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 */
|
/* Prototypes for the block device */
|
||||||
static int block_open(dev_t minor, int access);
|
static int block_open(devminor_t minor, int access);
|
||||||
static int block_close(dev_t minor);
|
static int block_close(devminor_t minor);
|
||||||
static int block_transfer(dev_t minor,
|
static int block_transfer(devminor_t minor,
|
||||||
int do_write,
|
int do_write,
|
||||||
u64_t position,
|
u64_t position,
|
||||||
endpoint_t endpt, iovec_t * iov, unsigned int nr_req, int flags);
|
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);
|
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 */
|
/* System even handling */
|
||||||
static void sef_local_startup();
|
static void sef_local_startup();
|
||||||
|
@ -72,18 +72,14 @@ static void set_log_level(int level);
|
||||||
|
|
||||||
/* Entry points for the BLOCK driver. */
|
/* Entry points for the BLOCK driver. */
|
||||||
static struct blockdriver mmc_driver = {
|
static struct blockdriver mmc_driver = {
|
||||||
BLOCKDRIVER_TYPE_DISK, /* handle partition requests */
|
.bdr_type = BLOCKDRIVER_TYPE_DISK,/* handle partition requests */
|
||||||
block_open, /* open or mount */
|
.bdr_open = block_open, /* device open */
|
||||||
block_close, /* on a close */
|
.bdr_close = block_close, /* on a close */
|
||||||
block_transfer, /* does the I/O */
|
.bdr_transfer = block_transfer, /* does the I/O */
|
||||||
block_ioctl, /* ioclt's */
|
.bdr_ioctl = block_ioctl, /* ioctls */
|
||||||
NULL, /* no need to clean up (yet) */
|
.bdr_part = block_part, /* get partition information */
|
||||||
block_part, /* return partition information */
|
.bdr_intr = hw_intr, /* left over interrupts */
|
||||||
NULL, /* no geometry */
|
.bdr_alarm = bdr_alarm /* no alarm processing */
|
||||||
hw_intr, /* left over interrupts */
|
|
||||||
bdr_alarm, /* no alarm processing */
|
|
||||||
NULL, /* no processing of other messages */
|
|
||||||
NULL /* no threading support */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -141,7 +137,7 @@ apply_env()
|
||||||
* block_open *
|
* block_open *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int
|
static int
|
||||||
block_open(dev_t minor, int access)
|
block_open(devminor_t minor, int access)
|
||||||
{
|
{
|
||||||
struct sd_slot *slot;
|
struct sd_slot *slot;
|
||||||
slot = get_slot(minor);
|
slot = get_slot(minor);
|
||||||
|
@ -213,7 +209,7 @@ block_open(dev_t minor, int access)
|
||||||
* block_close *
|
* block_close *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int
|
static int
|
||||||
block_close(dev_t minor)
|
block_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
struct sd_slot *slot;
|
struct sd_slot *slot;
|
||||||
|
|
||||||
|
@ -280,7 +276,8 @@ copyfrom(endpoint_t src_e,
|
||||||
* block_transfer *
|
* block_transfer *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int
|
static int
|
||||||
block_transfer(dev_t minor, /* minor device number */
|
block_transfer(
|
||||||
|
devminor_t minor, /* minor device number */
|
||||||
int do_write, /* read or write? */
|
int do_write, /* read or write? */
|
||||||
u64_t position, /* offset on device to read or write */
|
u64_t position, /* offset on device to read or write */
|
||||||
endpoint_t endpt, /* process doing the request */
|
endpoint_t endpt, /* process doing the request */
|
||||||
|
@ -438,7 +435,7 @@ block_transfer(dev_t minor, /* minor device number */
|
||||||
* block_ioctl *
|
* block_ioctl *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static int
|
static int
|
||||||
block_ioctl(dev_t minor,
|
block_ioctl(devminor_t minor,
|
||||||
unsigned int request, endpoint_t endpt, cp_grant_id_t grant)
|
unsigned int request, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
/* IOCTL handling */
|
/* IOCTL handling */
|
||||||
|
@ -476,7 +473,7 @@ block_ioctl(dev_t minor,
|
||||||
* block_part *
|
* block_part *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static struct device *
|
static struct device *
|
||||||
block_part(dev_t minor)
|
block_part(devminor_t minor)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Reuse the existing MINIX major/minor partitioning scheme.
|
* 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 )
|
#define IS_MINIX_SUB_PARTITION_MINOR(minor) (minor >= MINOR_d0p0s0 )
|
||||||
|
|
||||||
static struct sd_slot *
|
static struct sd_slot *
|
||||||
get_slot(dev_t minor)
|
get_slot(devminor_t minor)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Get an sd_slot based on the minor number.
|
* 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.
|
* number 128 till 144 for sub partitions.
|
||||||
*/
|
*/
|
||||||
/* If this is a minor for the first disk (e.g. minor 0 till 5) */
|
/* 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
|
/* we are talking about the first disk and that is all we
|
||||||
* support */
|
* support */
|
||||||
return &host.slot[0];
|
return &host.slot[0];
|
||||||
|
|
|
@ -163,14 +163,14 @@ static int check_revision(void);
|
||||||
static int read_edid(uint8_t * data, size_t count);
|
static int read_edid(uint8_t * data, size_t count);
|
||||||
|
|
||||||
/* libblockdriver callbacks */
|
/* libblockdriver callbacks */
|
||||||
static int tda19988_blk_open(dev_t minor, int access);
|
static int tda19988_blk_open(devminor_t minor, int access);
|
||||||
static int tda19988_blk_close(dev_t minor);
|
static int tda19988_blk_close(devminor_t minor);
|
||||||
static ssize_t tda19988_blk_transfer(dev_t minor, int do_write, u64_t pos,
|
static ssize_t tda19988_blk_transfer(devminor_t minor, int do_write, u64_t pos,
|
||||||
endpoint_t endpt, iovec_t * iov, unsigned count, int flags);
|
endpoint_t endpt, iovec_t * iov, unsigned int count, int flags);
|
||||||
static int tda19988_blk_ioctl(dev_t minor, unsigned int request,
|
static int tda19988_blk_ioctl(devminor_t minor, unsigned int request,
|
||||||
endpoint_t endpt, cp_grant_id_t grant);
|
endpoint_t endpt, cp_grant_id_t grant);
|
||||||
static struct device *tda19988_blk_part(dev_t minor);
|
static struct device *tda19988_blk_part(devminor_t minor);
|
||||||
static int tda19988_blk_other(message * m);
|
static void tda19988_blk_other(message * m, int ipc_status);
|
||||||
|
|
||||||
/* Entry points into the device dependent code of block drivers. */
|
/* Entry points into the device dependent code of block drivers. */
|
||||||
struct blockdriver tda19988_tab = {
|
struct blockdriver tda19988_tab = {
|
||||||
|
@ -178,14 +178,9 @@ struct blockdriver tda19988_tab = {
|
||||||
.bdr_open = tda19988_blk_open,
|
.bdr_open = tda19988_blk_open,
|
||||||
.bdr_close = tda19988_blk_close,
|
.bdr_close = tda19988_blk_close,
|
||||||
.bdr_transfer = tda19988_blk_transfer,
|
.bdr_transfer = tda19988_blk_transfer,
|
||||||
.bdr_ioctl = tda19988_blk_ioctl, /* nop -- always returns ENOTTY */
|
.bdr_ioctl = tda19988_blk_ioctl, /* always returns ENOTTY */
|
||||||
.bdr_cleanup = NULL, /* nothing allocated -- nothing to clean up */
|
|
||||||
.bdr_part = tda19988_blk_part,
|
.bdr_part = tda19988_blk_part,
|
||||||
.bdr_geometry = NULL, /* no geometry (cylinders, heads, sectors, etc) */
|
.bdr_other = tda19988_blk_other /* for notify events from DS */
|
||||||
.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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* counts the number of times a device file is open */
|
/* 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 struct device geom[NR_DEVS];
|
||||||
|
|
||||||
static int
|
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);
|
log_trace(&log, "tda19988_blk_open(%d,%d)\n", minor, access);
|
||||||
if (tda19988_blk_part(minor) == NULL) {
|
if (tda19988_blk_part(minor) == NULL) {
|
||||||
|
@ -208,7 +203,7 @@ tda19988_blk_open(dev_t minor, int access)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tda19988_blk_close(dev_t minor)
|
tda19988_blk_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
log_trace(&log, "tda19988_blk_close(%d)\n", minor);
|
log_trace(&log, "tda19988_blk_close(%d)\n", minor);
|
||||||
if (tda19988_blk_part(minor) == NULL) {
|
if (tda19988_blk_part(minor) == NULL) {
|
||||||
|
@ -225,8 +220,8 @@ tda19988_blk_close(dev_t minor)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
tda19988_blk_transfer(dev_t minor, int do_write, u64_t pos64,
|
tda19988_blk_transfer(devminor_t minor, int do_write, u64_t pos64,
|
||||||
endpoint_t endpt, iovec_t * iov, unsigned nr_req, int flags)
|
endpoint_t endpt, iovec_t * iov, unsigned int nr_req, int flags)
|
||||||
{
|
{
|
||||||
unsigned count;
|
unsigned count;
|
||||||
struct device *dv;
|
struct device *dv;
|
||||||
|
@ -319,7 +314,7 @@ tda19988_blk_transfer(dev_t minor, int do_write, u64_t pos64,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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)
|
cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
log_trace(&log, "tda19988_blk_ioctl(%d)\n", minor);
|
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 *
|
static struct device *
|
||||||
tda19988_blk_part(dev_t minor)
|
tda19988_blk_part(devminor_t minor)
|
||||||
{
|
{
|
||||||
log_trace(&log, "tda19988_blk_part(%d)\n", minor);
|
log_trace(&log, "tda19988_blk_part(%d)\n", minor);
|
||||||
|
|
||||||
if (minor >= NR_DEVS) {
|
if (minor < 0 || minor >= NR_DEVS) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &geom[minor];
|
return &geom[minor];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
tda19988_blk_other(message * m)
|
tda19988_blk_other(message * m, int ipc_status)
|
||||||
{
|
{
|
||||||
int r;
|
|
||||||
|
|
||||||
log_trace(&log, "tda19988_blk_other(0x%x)\n", m->m_type);
|
log_trace(&log, "tda19988_blk_other(0x%x)\n", m->m_type);
|
||||||
|
|
||||||
switch (m->m_type) {
|
if (is_ipc_notify(ipc_status)) {
|
||||||
case NOTIFY_MESSAGE:
|
|
||||||
if (m->m_source == DS_PROC_NR) {
|
if (m->m_source == DS_PROC_NR) {
|
||||||
log_debug(&log,
|
log_debug(&log,
|
||||||
"bus driver changed state, update endpoint\n");
|
"bus driver changed state, update endpoint\n");
|
||||||
|
@ -356,15 +348,9 @@ tda19988_blk_other(message * m)
|
||||||
i2cdriver_handle_bus_update(&hdmi_bus_endpoint,
|
i2cdriver_handle_bus_update(&hdmi_bus_endpoint,
|
||||||
hdmi_bus, hdmi_address);
|
hdmi_bus, hdmi_address);
|
||||||
}
|
}
|
||||||
r = OK;
|
} else {
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log_warn(&log, "Invalid message type (0x%x)\n", m->m_type);
|
log_warn(&log, "Invalid message type (0x%x)\n", m->m_type);
|
||||||
r = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -77,19 +77,19 @@ static u16_t *status_vir;
|
||||||
static phys_bytes status_phys;
|
static phys_bytes status_phys;
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
static int virtio_blk_open(dev_t minor, int access);
|
static int virtio_blk_open(devminor_t minor, int access);
|
||||||
static int virtio_blk_close(dev_t minor);
|
static int virtio_blk_close(devminor_t minor);
|
||||||
static ssize_t virtio_blk_transfer(dev_t minor, int write, u64_t position,
|
static ssize_t virtio_blk_transfer(devminor_t minor, int write, u64_t position,
|
||||||
endpoint_t endpt, iovec_t *iovec,
|
endpoint_t endpt, iovec_t *iovec,
|
||||||
unsigned int cnt, int flags);
|
unsigned int cnt, int flags);
|
||||||
static int virtio_blk_ioctl(dev_t minor, unsigned int req, endpoint_t endpt,
|
static int virtio_blk_ioctl(devminor_t minor, unsigned int req,
|
||||||
cp_grant_id_t grant);
|
endpoint_t endpt, cp_grant_id_t grant);
|
||||||
static struct device * virtio_blk_part(dev_t minor);
|
static struct device * virtio_blk_part(devminor_t minor);
|
||||||
static void virtio_blk_geometry(dev_t minor, struct part_geom *entry);
|
static void virtio_blk_geometry(devminor_t minor, struct part_geom *entry);
|
||||||
static void virtio_blk_device_intr(void);
|
static void virtio_blk_device_intr(void);
|
||||||
static void virtio_blk_spurious_intr(void);
|
static void virtio_blk_spurious_intr(void);
|
||||||
static void virtio_blk_intr(unsigned int irqs);
|
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 int virtio_blk_flush(void);
|
||||||
static void virtio_blk_terminate(void);
|
static void virtio_blk_terminate(void);
|
||||||
|
@ -103,22 +103,19 @@ static int virtio_blk_probe(int skip);
|
||||||
|
|
||||||
/* libblockdriver driver tab */
|
/* libblockdriver driver tab */
|
||||||
static struct blockdriver virtio_blk_dtab = {
|
static struct blockdriver virtio_blk_dtab = {
|
||||||
BLOCKDRIVER_TYPE_DISK,
|
.bdr_type = BLOCKDRIVER_TYPE_DISK,
|
||||||
virtio_blk_open,
|
.bdr_open = virtio_blk_open,
|
||||||
virtio_blk_close,
|
.bdr_close = virtio_blk_close,
|
||||||
virtio_blk_transfer,
|
.bdr_transfer = virtio_blk_transfer,
|
||||||
virtio_blk_ioctl,
|
.bdr_ioctl = virtio_blk_ioctl,
|
||||||
NULL, /* bdr_cleanup */
|
.bdr_part = virtio_blk_part,
|
||||||
virtio_blk_part,
|
.bdr_geometry = virtio_blk_geometry,
|
||||||
virtio_blk_geometry,
|
.bdr_intr = virtio_blk_intr,
|
||||||
virtio_blk_intr,
|
.bdr_device = virtio_blk_device
|
||||||
NULL, /* bdr_alarm */
|
|
||||||
NULL, /* bdr_other */
|
|
||||||
virtio_blk_device
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
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);
|
struct device *dev = virtio_blk_part(minor);
|
||||||
|
|
||||||
|
@ -146,7 +143,7 @@ virtio_blk_open(dev_t minor, int access)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virtio_blk_close(dev_t minor)
|
virtio_blk_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
struct device *dev = virtio_blk_part(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
|
static ssize_t
|
||||||
virtio_blk_transfer(dev_t minor, int write, u64_t position, endpoint_t endpt,
|
virtio_blk_transfer(devminor_t minor, int write, u64_t position,
|
||||||
iovec_t *iovec, unsigned int cnt, int flags)
|
endpoint_t endpt, iovec_t *iovec, unsigned int cnt,
|
||||||
|
int flags)
|
||||||
{
|
{
|
||||||
/* Need to translate vir to phys */
|
/* Need to translate vir to phys */
|
||||||
struct vumap_vir vir[NR_IOREQS];
|
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
|
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)
|
cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
switch (req) {
|
switch (req) {
|
||||||
|
@ -394,24 +392,22 @@ virtio_blk_ioctl(dev_t minor, unsigned int req, endpoint_t endpt,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device *
|
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.
|
/* There's only a single drive attached to this device, alyways.
|
||||||
* Lets take some shortcuts...
|
* Lets take some shortcuts...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Take care of d0 d0p0 ... */
|
/* Take care of d0 d0p0 ... */
|
||||||
if (minor < 5)
|
if (minor >= 0 && minor < DEV_PER_DRIVE)
|
||||||
return &part[minor];
|
return &part[minor];
|
||||||
|
|
||||||
/* subparts start at 128 */
|
/* subparts start at MINOR_d0p0s0 */
|
||||||
if (minor >= 128) {
|
if (minor >= MINOR_d0p0s0) {
|
||||||
|
minor -= MINOR_d0p0s0;
|
||||||
/* Mask away upper bits */
|
|
||||||
minor = minor & 0x7F;
|
|
||||||
|
|
||||||
/* Only for the first disk */
|
/* Only for the first disk */
|
||||||
if (minor > 15)
|
if (minor >= SUB_PER_DRIVE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return &subpart[minor];
|
return &subpart[minor];
|
||||||
|
@ -421,7 +417,7 @@ virtio_blk_part(dev_t minor)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 */
|
/* Only for the drive */
|
||||||
if (minor != 0)
|
if (minor != 0)
|
||||||
|
@ -470,7 +466,7 @@ virtio_blk_intr(unsigned int irqs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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);
|
struct device *dev = virtio_blk_part(minor);
|
||||||
|
|
||||||
|
|
|
@ -15,19 +15,19 @@ typedef enum {
|
||||||
/* Entry points into the device dependent code of block drivers. */
|
/* Entry points into the device dependent code of block drivers. */
|
||||||
struct blockdriver {
|
struct blockdriver {
|
||||||
blockdriver_type_t bdr_type;
|
blockdriver_type_t bdr_type;
|
||||||
int(*bdr_open) (dev_t minor, int access);
|
int (*bdr_open)(devminor_t minor, int access);
|
||||||
int(*bdr_close) (dev_t minor);
|
int (*bdr_close)(devminor_t minor);
|
||||||
ssize_t(*bdr_transfer) (dev_t minor, int do_write, u64_t pos,
|
ssize_t (*bdr_transfer)(devminor_t minor, int do_write, u64_t pos,
|
||||||
endpoint_t endpt, iovec_t *iov, unsigned count, int flags);
|
endpoint_t endpt, iovec_t *iov, unsigned int count, int flags);
|
||||||
int(*bdr_ioctl) (dev_t minor, unsigned int request, endpoint_t endpt,
|
int (*bdr_ioctl)(devminor_t minor, unsigned int request, endpoint_t endpt,
|
||||||
cp_grant_id_t grant);
|
cp_grant_id_t grant);
|
||||||
void(*bdr_cleanup) (void);
|
void (*bdr_cleanup)(void);
|
||||||
struct device *(*bdr_part)(dev_t minor);
|
struct device *(*bdr_part)(devminor_t minor);
|
||||||
void(*bdr_geometry) (dev_t minor, struct part_geom *part);
|
void (*bdr_geometry)(devminor_t minor, struct part_geom *part);
|
||||||
void(*bdr_intr) (unsigned int irqs);
|
void (*bdr_intr)(unsigned int mask);
|
||||||
void(*bdr_alarm) (clock_t stamp);
|
void (*bdr_alarm)(clock_t stamp);
|
||||||
int(*bdr_other) (message *m_ptr);
|
void (*bdr_other)(message *m_ptr, int ipc_status);
|
||||||
int(*bdr_device) (dev_t minor, device_id_t *id);
|
int (*bdr_device)(devminor_t minor, device_id_t *id);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Functions defined by libblockdriver. These can be used for both
|
/* Functions defined by libblockdriver. These can be used for both
|
||||||
|
|
|
@ -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. */
|
/* Send a reply message to a request. */
|
||||||
endpoint_t caller_e;
|
|
||||||
long id;
|
|
||||||
int r;
|
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
|
/* 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
|
* 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
|
* async comm), and the asynchronous reply could otherwise end up satisfying
|
||||||
* the SENDREC's receive part, after which our next SENDNB call would fail.
|
* the SENDREC's receive part, after which our next SENDNB call would fail.
|
||||||
*/
|
*/
|
||||||
if (IPC_STATUS_CALL(ipc_status) == SENDREC)
|
if (IPC_STATUS_CALL(ipc_status) == SENDREC)
|
||||||
r = sendnb(caller_e, m_ptr);
|
r = sendnb(endpt, m_ptr);
|
||||||
else
|
else
|
||||||
r = asynsend3(caller_e, m_ptr, AMF_NOREPLY);
|
r = asynsend3(endpt, m_ptr, AMF_NOREPLY);
|
||||||
|
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
printf("blockdriver_reply: unable to send reply to %d: %d\n",
|
printf("blockdriver: unable to send reply to %d: %d\n", endpt, r);
|
||||||
caller_e, 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)
|
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. */
|
/* Carry out an device read or write to/from a vector of buffers. */
|
||||||
iovec_t iovec[NR_IOREQS];
|
iovec_t iovec[NR_IOREQS];
|
||||||
unsigned nr_req;
|
unsigned int nr_req;
|
||||||
u64_t position;
|
u64_t position;
|
||||||
int i, do_write;
|
int i, do_write;
|
||||||
ssize_t r, size;
|
ssize_t r, size;
|
||||||
|
@ -290,7 +295,7 @@ static int do_dioctl(struct blockdriver *bdp, dev_t minor,
|
||||||
(*bdp->bdr_geometry)(minor, &entry);
|
(*bdp->bdr_geometry)(minor, &entry);
|
||||||
} else {
|
} else {
|
||||||
/* The driver doesn't care -- make up fake geometry. */
|
/* 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.heads = 64;
|
||||||
entry.sectors = 32;
|
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
|
/* Reply to a character driver open request stating there is no such device. */
|
||||||
* the appropiate callback functions. Never send a reply.
|
message m_reply;
|
||||||
*/
|
|
||||||
|
|
||||||
/* Call the appropriate function for this notification. */
|
memset(&m_reply, 0, sizeof(m_reply));
|
||||||
switch (_ENDPOINT_P(m_ptr->m_source)) {
|
|
||||||
case HARDWARE:
|
|
||||||
if (bdp->bdr_intr)
|
|
||||||
(*bdp->bdr_intr)(m_ptr->NOTIFY_ARG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLOCK:
|
m_reply.m_type = DEV_OPEN_REPL;
|
||||||
if (bdp->bdr_alarm)
|
m_reply.REP_ENDPT = m_ptr->USER_ENDPT;
|
||||||
(*bdp->bdr_alarm)(m_ptr->NOTIFY_TIMESTAMP);
|
m_reply.REP_STATUS = ENXIO;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
send_reply(m_ptr->m_source, &m_reply, ipc_status);
|
||||||
if (bdp->bdr_other)
|
|
||||||
(void) (*bdp->bdr_other)(m_ptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* blockdriver_handle_request *
|
* blockdriver_process_on_thread *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr,
|
void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr,
|
||||||
thread_id_t id)
|
int ipc_status, thread_id_t id)
|
||||||
{
|
{
|
||||||
/* Call the appropiate driver function, based on the type of request. Return
|
/* Call the appropiate driver function, based on the type of request. Send
|
||||||
* the result code that is to be sent back to the caller, or EDONTREPLY if no
|
* a result code to the caller. The call is processed in the context of the
|
||||||
* reply is to be sent.
|
* given thread ID, which may be SINGLE_THREAD for single-threaded callers.
|
||||||
*/
|
*/
|
||||||
int r;
|
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
|
/* We might get spurious requests if the driver has been restarted. Deny any
|
||||||
* requests on devices that have not previously been opened, signaling the
|
* requests on devices that have not previously been opened, signaling the
|
||||||
* caller that something went wrong.
|
* caller that something went wrong.
|
||||||
*/
|
*/
|
||||||
if (IS_BDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->BDEV_MINOR)) {
|
if (IS_BDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->BDEV_MINOR)) {
|
||||||
/* Reply ERESTART to spurious requests for unopened devices. */
|
/* Reply ERESTART to spurious requests for unopened devices. */
|
||||||
if (m_ptr->m_type != BDEV_OPEN)
|
if (m_ptr->m_type != BDEV_OPEN) {
|
||||||
return ERESTART;
|
blockdriver_reply(m_ptr, ipc_status, ERESTART);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark the device as opened otherwise. */
|
/* Mark the device as opened otherwise. */
|
||||||
set_open_dev(m_ptr->BDEV_MINOR);
|
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_SCATTER: r = do_vrdwt(bdp, m_ptr, id); break;
|
||||||
case BDEV_IOCTL: r = do_ioctl(bdp, m_ptr); break;
|
case BDEV_IOCTL: r = do_ioctl(bdp, m_ptr); break;
|
||||||
default:
|
default:
|
||||||
if (bdp->bdr_other)
|
if (bdp->bdr_other != NULL)
|
||||||
r = bdp->bdr_other(m_ptr);
|
(*bdp->bdr_other)(m_ptr, ipc_status);
|
||||||
else
|
|
||||||
r = EINVAL;
|
return; /* do not send a reply */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let the driver perform any cleanup. */
|
/* Let the driver perform any cleanup. */
|
||||||
|
@ -427,5 +456,5 @@ int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr,
|
||||||
|
|
||||||
trace_finish(id, r);
|
trace_finish(id, r);
|
||||||
|
|
||||||
return r;
|
blockdriver_reply(m_ptr, ipc_status, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#ifndef _BLOCKDRIVER_DRIVER_H
|
#ifndef _BLOCKDRIVER_DRIVER_H
|
||||||
#define _BLOCKDRIVER_DRIVER_H
|
#define _BLOCKDRIVER_DRIVER_H
|
||||||
|
|
||||||
void blockdriver_handle_notify(struct blockdriver *bdp, message *m_ptr);
|
void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr,
|
||||||
int blockdriver_handle_request(struct blockdriver *bdp, message *m_ptr,
|
int ipc_status, thread_id_t thread);
|
||||||
thread_id_t thread);
|
|
||||||
void blockdriver_reply(message *m_ptr, int ipc_status, int reply);
|
void blockdriver_reply(message *m_ptr, int ipc_status, int reply);
|
||||||
|
|
||||||
#endif /* _BLOCKDRIVER_DRIVER_H */
|
#endif /* _BLOCKDRIVER_DRIVER_H */
|
||||||
|
|
|
@ -184,9 +184,7 @@ static void *worker_thread(void *param)
|
||||||
mthread_rwlock_wrlock(&dp->barrier);
|
mthread_rwlock_wrlock(&dp->barrier);
|
||||||
|
|
||||||
/* Handle the request and send a reply. */
|
/* Handle the request and send a reply. */
|
||||||
r = blockdriver_handle_request(bdtab, &m, tid);
|
blockdriver_process_on_thread(bdtab, &m, ipc_status, tid);
|
||||||
|
|
||||||
blockdriver_reply(&m, ipc_status, r);
|
|
||||||
|
|
||||||
/* Switch the thread back to running state, and unlock the barrier. */
|
/* Switch the thread back to running state, and unlock the barrier. */
|
||||||
wp->state = STATE_RUNNING;
|
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
|
/* 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
|
* 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;
|
device_id_t id;
|
||||||
worker_t *wp;
|
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
|
* 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.
|
* 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. */
|
/* Process as 'other' message. */
|
||||||
r = blockdriver_handle_request(bdtab, m_ptr, MAIN_THREAD);
|
blockdriver_process_on_thread(bdtab, m_ptr, ipc_status, MAIN_THREAD);
|
||||||
|
|
||||||
blockdriver_reply(m_ptr, ipc_status, r);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -423,10 +420,7 @@ void blockdriver_mt_task(struct blockdriver *driver_tab)
|
||||||
blockdriver_mt_receive(&mess, &ipc_status);
|
blockdriver_mt_receive(&mess, &ipc_status);
|
||||||
|
|
||||||
/* Dispatch the message. */
|
/* Dispatch the message. */
|
||||||
if (is_ipc_notify(ipc_status))
|
master_handle_message(&mess, ipc_status);
|
||||||
blockdriver_handle_notify(bdtab, &mess);
|
|
||||||
else
|
|
||||||
master_handle_request(&mess, ipc_status);
|
|
||||||
|
|
||||||
/* Let other threads run. */
|
/* Let other threads run. */
|
||||||
mthread_yield_all();
|
mthread_yield_all();
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
* The entry points into this file are:
|
* The entry points into this file are:
|
||||||
* blockdriver_task: the main message loop of the driver
|
* blockdriver_task: the main message loop of the driver
|
||||||
* blockdriver_terminate: break out of the main message loop
|
* 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_receive_mq: message receive interface with message queueing
|
||||||
* blockdriver_mq_queue: queue an incoming message for later processing
|
* 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. */
|
/* Break out of the main driver loop after finishing the current request. */
|
||||||
|
|
||||||
running = FALSE;
|
running = FALSE;
|
||||||
|
|
||||||
|
sef_cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -60,8 +61,12 @@ void blockdriver_task(struct blockdriver *bdp)
|
||||||
* it out, and sends a reply.
|
* it out, and sends a reply.
|
||||||
*/
|
*/
|
||||||
while (running) {
|
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);
|
panic("blockdriver_receive_mq failed: %d", r);
|
||||||
|
}
|
||||||
|
|
||||||
blockdriver_process(bdp, &mess, ipc_status);
|
blockdriver_process(bdp, &mess, ipc_status);
|
||||||
}
|
}
|
||||||
|
@ -74,18 +79,8 @@ void blockdriver_process(struct blockdriver *bdp, message *m_ptr,
|
||||||
int ipc_status)
|
int ipc_status)
|
||||||
{
|
{
|
||||||
/* Handle the given received message. */
|
/* Handle the given received message. */
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Process the notification or request. */
|
blockdriver_process_on_thread(bdp, m_ptr, ipc_status, SINGLE_THREAD);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
|
Loading…
Reference in a new issue