- introduce ioctl call
- pass open/close/lseek through to drivers
This commit is contained in:
parent
3f73e61600
commit
ee6d36a540
|
@ -120,6 +120,9 @@ int open_and_lseek(const char *filename, int mode, ulong pos)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pos)
|
||||||
|
return fd;
|
||||||
|
|
||||||
ret = lseek(fd, pos, SEEK_SET);
|
ret = lseek(fd, pos, SEEK_SET);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("lseek");
|
perror("lseek");
|
||||||
|
@ -525,22 +528,31 @@ static struct device_d mem_dev = {
|
||||||
static struct driver_d mem_drv = {
|
static struct driver_d mem_drv = {
|
||||||
.name = "mem",
|
.name = "mem",
|
||||||
.probe = dummy_probe,
|
.probe = dummy_probe,
|
||||||
|
.open = dev_open_default,
|
||||||
|
.close = dev_close_default,
|
||||||
.read = mem_read,
|
.read = mem_read,
|
||||||
.write = mem_write,
|
.write = mem_write,
|
||||||
|
.lseek = dev_lseek_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct driver_d ram_drv = {
|
static struct driver_d ram_drv = {
|
||||||
.name = "ram",
|
.name = "ram",
|
||||||
.probe = dummy_probe,
|
.probe = dummy_probe,
|
||||||
|
.open = dev_open_default,
|
||||||
|
.close = dev_close_default,
|
||||||
.read = mem_read,
|
.read = mem_read,
|
||||||
.write = mem_write,
|
.write = mem_write,
|
||||||
|
.lseek = dev_lseek_default,
|
||||||
.type = DEVICE_TYPE_DRAM,
|
.type = DEVICE_TYPE_DRAM,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct driver_d rom_drv = {
|
static struct driver_d rom_drv = {
|
||||||
.name = "rom",
|
.name = "rom",
|
||||||
.probe = dummy_probe,
|
.probe = dummy_probe,
|
||||||
|
.open = dev_open_default,
|
||||||
|
.close = dev_close_default,
|
||||||
.read = mem_read,
|
.read = mem_read,
|
||||||
|
.lseek = dev_lseek_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mem_init(void)
|
static int mem_init(void)
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <partition.h>
|
#include <partition.h>
|
||||||
#include <xfuncs.h>
|
#include <xfuncs.h>
|
||||||
|
#include <ioctl.h>
|
||||||
|
#include <nand.h>
|
||||||
|
#include <linux/mtd/mtd-abi.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add one partition on top of a device, as a device.
|
* Add one partition on top of a device, as a device.
|
||||||
|
@ -168,6 +171,43 @@ static ssize_t part_write(struct device_d *dev, const void *buf, size_t count,
|
||||||
return dev_write(part->physdev, buf, count, offset + part->offset, flags);
|
return dev_write(part->physdev, buf, count, offset + part->offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static off_t part_lseek(struct device_d *dev, off_t ofs)
|
||||||
|
{
|
||||||
|
struct partition *part = dev->type_data;
|
||||||
|
|
||||||
|
return dev_lseek(part->physdev, ofs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int part_open(struct device_d *dev, struct filep *f)
|
||||||
|
{
|
||||||
|
struct partition *part = dev->type_data;
|
||||||
|
|
||||||
|
return dev_open(part->physdev, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int part_close(struct device_d *dev, struct filep *f)
|
||||||
|
{
|
||||||
|
struct partition *part = dev->type_data;
|
||||||
|
|
||||||
|
return dev_close(part->physdev, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int part_ioctl(struct device_d *dev, int request,
|
||||||
|
void *buf)
|
||||||
|
{
|
||||||
|
struct partition *part = dev->type_data;
|
||||||
|
off_t offset;
|
||||||
|
|
||||||
|
switch (request) {
|
||||||
|
case MEMGETBADBLOCK:
|
||||||
|
offset = (off_t)buf;
|
||||||
|
offset += part->offset;
|
||||||
|
return dev_ioctl(part->physdev, request, (void *)offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME.
|
* FIXME.
|
||||||
* @param[in] dev The partition info as a device
|
* @param[in] dev The partition info as a device
|
||||||
|
@ -201,8 +241,12 @@ struct driver_d part_driver = {
|
||||||
.name = "partition",
|
.name = "partition",
|
||||||
.probe = part_probe,
|
.probe = part_probe,
|
||||||
.remove = part_remove,
|
.remove = part_remove,
|
||||||
|
.open = part_open,
|
||||||
|
.close = part_close,
|
||||||
|
.ioctl = part_ioctl,
|
||||||
.read = part_read,
|
.read = part_read,
|
||||||
.write = part_write,
|
.write = part_write,
|
||||||
|
.lseek = part_lseek,
|
||||||
.erase = part_erase,
|
.erase = part_erase,
|
||||||
.protect= part_protect,
|
.protect= part_protect,
|
||||||
.memmap = part_memmap,
|
.memmap = part_memmap,
|
||||||
|
|
|
@ -524,6 +524,9 @@ static struct driver_d cfi_driver = {
|
||||||
.probe = cfi_probe,
|
.probe = cfi_probe,
|
||||||
.read = mem_read,
|
.read = mem_read,
|
||||||
.write = cfi_write,
|
.write = cfi_write,
|
||||||
|
.lseek = dev_lseek_default,
|
||||||
|
.open = dev_open_default,
|
||||||
|
.close = dev_close_default,
|
||||||
.erase = cfi_erase,
|
.erase = cfi_erase,
|
||||||
.protect= cfi_protect,
|
.protect= cfi_protect,
|
||||||
.memmap = generic_memmap_ro,
|
.memmap = generic_memmap_ro,
|
||||||
|
|
|
@ -352,6 +352,12 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
|
||||||
return outsize;
|
return outsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static off_t cramfs_lseek(struct device_d *dev, FILE *f, off_t pos)
|
||||||
|
{
|
||||||
|
f->pos = pos;
|
||||||
|
return f->pos;
|
||||||
|
}
|
||||||
|
|
||||||
static int cramfs_stat(struct device_d *_dev, const char *filename, struct stat *stat)
|
static int cramfs_stat(struct device_d *_dev, const char *filename, struct stat *stat)
|
||||||
{
|
{
|
||||||
struct cramfs_priv *priv = _dev->priv;
|
struct cramfs_priv *priv = _dev->priv;
|
||||||
|
@ -443,6 +449,7 @@ static struct fs_driver_d cramfs_driver = {
|
||||||
.open = cramfs_open,
|
.open = cramfs_open,
|
||||||
.close = cramfs_close,
|
.close = cramfs_close,
|
||||||
.read = cramfs_read,
|
.read = cramfs_read,
|
||||||
|
.lseek = cramfs_lseek,
|
||||||
.opendir = cramfs_opendir,
|
.opendir = cramfs_opendir,
|
||||||
.readdir = cramfs_readdir,
|
.readdir = cramfs_readdir,
|
||||||
.closedir = cramfs_closedir,
|
.closedir = cramfs_closedir,
|
||||||
|
|
36
fs/devfs.c
36
fs/devfs.c
|
@ -44,6 +44,19 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s
|
||||||
return dev_write(dev, buf, size, f->pos, f->flags);
|
return dev_write(dev, buf, size, f->pos, f->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
|
||||||
|
{
|
||||||
|
struct device_d *dev = f->inode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dev_lseek(dev, pos);
|
||||||
|
|
||||||
|
if (ret >= 0)
|
||||||
|
f->pos = pos;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
|
static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
|
||||||
{
|
{
|
||||||
struct device_d *dev = f->inode;
|
struct device_d *dev = f->inode;
|
||||||
|
@ -65,21 +78,30 @@ static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
|
||||||
return dev_memmap(dev, map, flags);
|
return dev_memmap(dev, map, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devfs_open(struct device_d *_dev, FILE *file, const char *filename)
|
static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
|
||||||
{
|
{
|
||||||
struct device_d *dev = get_device_by_id(filename + 1);
|
struct device_d *dev = get_device_by_id(filename + 1);
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
file->size = dev->size;
|
f->size = dev->size;
|
||||||
file->inode = dev;
|
f->inode = dev;
|
||||||
return 0;
|
return dev_open(dev, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devfs_close(struct device_d *dev, FILE *f)
|
static int devfs_close(struct device_d *_dev, FILE *f)
|
||||||
{
|
{
|
||||||
return 0;
|
struct device_d *dev = f->inode;
|
||||||
|
|
||||||
|
return dev_close(dev, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
|
||||||
|
{
|
||||||
|
struct device_d *dev = f->inode;
|
||||||
|
|
||||||
|
return dev_ioctl(dev, request, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
|
static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
|
||||||
|
@ -156,8 +178,10 @@ static struct fs_driver_d devfs_driver = {
|
||||||
.type = FS_TYPE_DEVFS,
|
.type = FS_TYPE_DEVFS,
|
||||||
.read = devfs_read,
|
.read = devfs_read,
|
||||||
.write = devfs_write,
|
.write = devfs_write,
|
||||||
|
.lseek = devfs_lseek,
|
||||||
.open = devfs_open,
|
.open = devfs_open,
|
||||||
.close = devfs_close,
|
.close = devfs_close,
|
||||||
|
.ioctl = devfs_ioctl,
|
||||||
.opendir = devfs_opendir,
|
.opendir = devfs_opendir,
|
||||||
.readdir = devfs_readdir,
|
.readdir = devfs_readdir,
|
||||||
.truncate = devfs_truncate,
|
.truncate = devfs_truncate,
|
||||||
|
|
34
fs/fs.c
34
fs/fs.c
|
@ -451,6 +451,22 @@ int creat(const char *pathname, mode_t mode)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(creat);
|
EXPORT_SYMBOL(creat);
|
||||||
|
|
||||||
|
int ioctl(int fd, int request, void *buf)
|
||||||
|
{
|
||||||
|
struct device_d *dev;
|
||||||
|
struct fs_driver_d *fsdrv;
|
||||||
|
FILE *f = &files[fd];
|
||||||
|
|
||||||
|
dev = f->dev;
|
||||||
|
|
||||||
|
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||||
|
|
||||||
|
if (fsdrv->ioctl)
|
||||||
|
return fsdrv->ioctl(dev, f, request, buf);
|
||||||
|
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
int read(int fd, void *buf, size_t count)
|
int read(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct device_d *dev;
|
struct device_d *dev;
|
||||||
|
@ -496,30 +512,40 @@ EXPORT_SYMBOL(write);
|
||||||
|
|
||||||
off_t lseek(int fildes, off_t offset, int whence)
|
off_t lseek(int fildes, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
|
struct device_d *dev;
|
||||||
|
struct fs_driver_d *fsdrv;
|
||||||
FILE *f = &files[fildes];
|
FILE *f = &files[fildes];
|
||||||
|
ulong pos;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
|
dev = f->dev;
|
||||||
|
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||||
|
if (!fsdrv->lseek)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
switch(whence) {
|
switch(whence) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
if (offset > f->size)
|
if (offset > f->size)
|
||||||
goto out;
|
goto out;
|
||||||
f->pos = offset;
|
pos = offset;
|
||||||
break;
|
break;
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
if (offset + f->pos > f->size)
|
if (offset + f->pos > f->size)
|
||||||
goto out;
|
goto out;
|
||||||
f->pos += offset;
|
pos = f->pos + offset;
|
||||||
break;
|
break;
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
if (offset)
|
if (offset)
|
||||||
goto out;
|
goto out;
|
||||||
f->pos = f->size;
|
pos = f->size;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return fsdrv->lseek(dev, f, pos);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
errno = -EINVAL;
|
errno = -EINVAL;
|
||||||
return errno;
|
return errno;
|
||||||
|
|
|
@ -403,6 +403,12 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i
|
||||||
return insize;
|
return insize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static off_t ramfs_lseek(struct device_d *dev, FILE *f, off_t pos)
|
||||||
|
{
|
||||||
|
f->pos = pos;
|
||||||
|
return f->pos;
|
||||||
|
}
|
||||||
|
|
||||||
static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size)
|
static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size)
|
||||||
{
|
{
|
||||||
struct ramfs_inode *node = (struct ramfs_inode *)f->inode;
|
struct ramfs_inode *node = (struct ramfs_inode *)f->inode;
|
||||||
|
@ -540,6 +546,7 @@ static struct fs_driver_d ramfs_driver = {
|
||||||
.truncate = ramfs_truncate,
|
.truncate = ramfs_truncate,
|
||||||
.read = ramfs_read,
|
.read = ramfs_read,
|
||||||
.write = ramfs_write,
|
.write = ramfs_write,
|
||||||
|
.lseek = ramfs_lseek,
|
||||||
.mkdir = ramfs_mkdir,
|
.mkdir = ramfs_mkdir,
|
||||||
.rmdir = ramfs_rmdir,
|
.rmdir = ramfs_rmdir,
|
||||||
.opendir = ramfs_opendir,
|
.opendir = ramfs_opendir,
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
|
|
||||||
/*@{*/ /* do not delete, doxygen relevant */
|
/*@{*/ /* do not delete, doxygen relevant */
|
||||||
|
|
||||||
|
struct filep;
|
||||||
|
|
||||||
/** @brief Describes a particular device present in the system */
|
/** @brief Describes a particular device present in the system */
|
||||||
struct device_d {
|
struct device_d {
|
||||||
/*! This member (and 'type' described below) is used to match with a
|
/*! This member (and 'type' described below) is used to match with a
|
||||||
|
@ -131,6 +133,11 @@ struct driver_d {
|
||||||
/*! Called in response of write to this device. Required */
|
/*! Called in response of write to this device. Required */
|
||||||
ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
|
ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
|
||||||
|
|
||||||
|
int (*ioctl) (struct device_d*, int, void *);
|
||||||
|
|
||||||
|
off_t (*lseek) (struct device_d*, off_t);
|
||||||
|
int (*open) (struct device_d*, struct filep*);
|
||||||
|
int (*close) (struct device_d*, struct filep*);
|
||||||
|
|
||||||
int (*erase) (struct device_d*, size_t count, unsigned long offset);
|
int (*erase) (struct device_d*, size_t count, unsigned long offset);
|
||||||
int (*protect)(struct device_d*, size_t count, unsigned long offset, int prot);
|
int (*protect)(struct device_d*, size_t count, unsigned long offset, int prot);
|
||||||
|
@ -219,6 +226,10 @@ struct driver_d *get_driver_by_name(const char *name);
|
||||||
|
|
||||||
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||||
ssize_t dev_write(struct device_d *dev, const void *buf, size_t count, ulong offset, ulong flags);
|
ssize_t dev_write(struct device_d *dev, const void *buf, size_t count, ulong offset, ulong flags);
|
||||||
|
int dev_open(struct device_d *dev, struct filep *);
|
||||||
|
int dev_close(struct device_d *dev, struct filep *);
|
||||||
|
int dev_ioctl(struct device_d *dev, int, void *);
|
||||||
|
off_t dev_lseek(struct device_d *dev, off_t offset);
|
||||||
int dev_erase(struct device_d *dev, size_t count, unsigned long offset);
|
int dev_erase(struct device_d *dev, size_t count, unsigned long offset);
|
||||||
int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot);
|
int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot);
|
||||||
int dev_memmap(struct device_d *dev, void **map, int flags);
|
int dev_memmap(struct device_d *dev, void **map, int flags);
|
||||||
|
@ -233,5 +244,20 @@ int dummy_probe(struct device_d *);
|
||||||
int generic_memmap_ro(struct device_d *dev, void **map, int flags);
|
int generic_memmap_ro(struct device_d *dev, void **map, int flags);
|
||||||
int generic_memmap_rw(struct device_d *dev, void **map, int flags);
|
int generic_memmap_rw(struct device_d *dev, void **map, int flags);
|
||||||
|
|
||||||
|
static inline off_t dev_lseek_default(struct device_d *dev, off_t ofs)
|
||||||
|
{
|
||||||
|
return ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int dev_open_default(struct device_d *dev, struct filep *f)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int dev_close_default(struct device_d *dev, struct filep *f)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* DRIVER_H */
|
#endif /* DRIVER_H */
|
||||||
|
|
||||||
|
|
|
@ -58,12 +58,14 @@ struct fs_driver_d {
|
||||||
int (*close)(struct device_d *dev, FILE *f);
|
int (*close)(struct device_d *dev, FILE *f);
|
||||||
int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
|
int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
|
||||||
int (*write)(struct device_d *dev, FILE *f, const void *buf, size_t size);
|
int (*write)(struct device_d *dev, FILE *f, const void *buf, size_t size);
|
||||||
|
off_t (*lseek)(struct device_d *dev, FILE *f, off_t pos);
|
||||||
|
|
||||||
struct dir* (*opendir)(struct device_d *dev, const char *pathname);
|
struct dir* (*opendir)(struct device_d *dev, const char *pathname);
|
||||||
struct dirent* (*readdir)(struct device_d *dev, struct dir *dir);
|
struct dirent* (*readdir)(struct device_d *dev, struct dir *dir);
|
||||||
int (*closedir)(struct device_d *dev, DIR *dir);
|
int (*closedir)(struct device_d *dev, DIR *dir);
|
||||||
int (*stat)(struct device_d *dev, const char *file, struct stat *stat);
|
int (*stat)(struct device_d *dev, const char *file, struct stat *stat);
|
||||||
|
|
||||||
|
int (*ioctl)(struct device_d *dev, FILE *f, int request, void *buf);
|
||||||
int (*erase)(struct device_d *dev, FILE *f, size_t count,
|
int (*erase)(struct device_d *dev, FILE *f, size_t count,
|
||||||
unsigned long offset);
|
unsigned long offset);
|
||||||
int (*protect)(struct device_d *dev, FILE *f, size_t count,
|
int (*protect)(struct device_d *dev, FILE *f, size_t count,
|
||||||
|
@ -101,6 +103,7 @@ int unlink(const char *pathname);
|
||||||
int close(int fd);
|
int close(int fd);
|
||||||
int stat(const char *filename, struct stat *s);
|
int stat(const char *filename, struct stat *s);
|
||||||
int read(int fd, void *buf, size_t count);
|
int read(int fd, void *buf, size_t count);
|
||||||
|
int ioctl(int fd, int request, void *buf);
|
||||||
ssize_t write(int fd, const void *buf, size_t count);
|
ssize_t write(int fd, const void *buf, size_t count);
|
||||||
|
|
||||||
#define SEEK_SET 1
|
#define SEEK_SET 1
|
||||||
|
|
32
lib/driver.c
32
lib/driver.c
|
@ -212,6 +212,38 @@ ssize_t dev_write(struct device_d *dev, const void *buf, size_t count, unsigned
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
off_t dev_lseek(struct device_d *dev, off_t offset)
|
||||||
|
{
|
||||||
|
if (dev->driver->lseek)
|
||||||
|
return dev->driver->lseek(dev, offset);
|
||||||
|
errno = -ENOSYS;
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dev_open(struct device_d *dev, struct filep *f)
|
||||||
|
{
|
||||||
|
if (dev->driver->open)
|
||||||
|
return dev->driver->open(dev, f);
|
||||||
|
errno = -ENOSYS;
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dev_close(struct device_d *dev, struct filep *f)
|
||||||
|
{
|
||||||
|
if (dev->driver->close)
|
||||||
|
return dev->driver->close(dev, f);
|
||||||
|
errno = -ENOSYS;
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dev_ioctl(struct device_d *dev, int request, void *buf)
|
||||||
|
{
|
||||||
|
if (dev->driver->ioctl)
|
||||||
|
return dev->driver->ioctl(dev, request, buf);
|
||||||
|
errno = -ENOSYS;
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
int dev_erase(struct device_d *dev, size_t count, unsigned long offset)
|
int dev_erase(struct device_d *dev, size_t count, unsigned long offset)
|
||||||
{
|
{
|
||||||
if (dev->driver->erase)
|
if (dev->driver->erase)
|
||||||
|
|
Loading…
Reference in New Issue