AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
kdev.c File Reference

The device layer: devices by their numbers, and what calls them. More...

#include <core/system.h>
#include <dev/dev.h>
#include <fs/vfs.h>
#include <fs/posix.h>
#include <dev/blkcache.h>

Go to the source code of this file.

Functions

static struct dev * kdev_get (struct devid *dd)
 Returns the driver of a device number, picked by minor if the major's driver multiplexes several devices, or NULL if there is none.
struct fops * kdev_fops (struct devid *dd)
 Returns the file operations of a device.
int kdev_close (struct devid *dev)
 Closes a device: there is nothing to do.
ssize_t kdev_bread (struct devid *dd, off_t offset, size_t size, void *buf)
 Reads bytes from a block device, at any offset: the driver reads whole blocks, and the partial blocks at either end go through a buffer.
ssize_t kdev_bwrite (struct devid *dd, off_t offset, size_t size, void *buf)
 Writes bytes to a block device, at any offset: the driver writes whole blocks, and the partial blocks at either end are read, changed and written back.
static ssize_t kdev_blk_io (struct devid *dd, off_t offset, struct iobuf *io, int write)
 Reads or writes a block device's bytes from or to an iobuf (user memory), a page at a time through a kernel buffer; kdev_bread() and kdev_bwrite() make blocks of them.
ssize_t kdev_read (struct devid *dd, off_t offset, struct iobuf *io)
 Reads from a device: a character device through its driver, a block device in blocks.
ssize_t kdev_write (struct devid *dd, off_t offset, struct iobuf *io)
 Writes to a device: a character device through its driver, a block device in blocks.
int kdev_ioctl (struct devid *dd, int request, void *argp)
 Passes an ioctl() to a device's driver.
int kdev_map (struct devid *dd, struct vm_space *vm_space, struct vm_entry *vm_entry)
 Maps a device into an address space (mmap() of a framebuffer).
int kdev_file_open (struct devid *dd, struct file *file)
 Opens a device, through its driver's file operations.
ssize_t kdev_file_read (struct devid *dd, struct file *file, struct iobuf *io)
 Reads an open device file, through its driver's file operations.
ssize_t kdev_file_write (struct devid *dd, struct file *file, struct iobuf *io)
 Writes to an open device file, through its driver's file operations.
off_t kdev_file_lseek (struct devid *dd, struct file *file, off_t offset, int whence)
 Moves an open device file's offset, through its driver's file operations.
ssize_t kdev_file_close (struct devid *dd, struct file *file)
 Closes an open device file, through its driver's file operations.
int kdev_file_ioctl (struct devid *dd, struct file *file, int request, void *argp)
 Passes an ioctl() on an open device file to its driver's file operations.
int kdev_file_can_read (struct devid *dd, struct file *file, size_t size)
 Asks a device's driver whether a read wouldn't have to wait.
int kdev_file_can_write (struct devid *dd, struct file *file, size_t size)
 Asks a device's driver whether a write wouldn't have to wait.
int kdev_file_eof (struct devid *dd, struct file *file)
 Asks a device's driver whether a read that found no data is at the end of the file.
void kdev_chrdev_register (devid_t major, struct dev *dev)
 Registers a driver as the character device of a major number.
int kdev_sync (void)
 Writes what the block cache holds that was written, and what the block devices hold in their write caches, to the media.
void kdev_blkdev_register (devid_t major, struct dev *dev)
 Registers a driver as the block device of a major number.
void kdev_init ()
 Starts the device layer, at boot.

Variables

struct dev * chrdev [256]
struct dev * blkdev [256]

Detailed Description

The device layer: devices by their numbers, and what calls them.

A driver registers itself as the character or block device of a major number (kdev_chrdev_register(), kdev_blkdev_register()); a driver with several devices picks one by minor with its mux. The rest of the kernel reaches a device through these functions, by its number. Block devices are read and written in whole blocks: kdev_bread() and kdev_bwrite() make any range of bytes into blocks. See docs/kernel/devices.md.

Definition in file kdev.c.

Function Documentation

◆ kdev_blk_io()

ssize_t kdev_blk_io ( struct devid * dd,
off_t offset,
struct iobuf * io,
int write )
static

Reads or writes a block device's bytes from or to an iobuf (user memory), a page at a time through a kernel buffer; kdev_bread() and kdev_bwrite() make blocks of them.

Returns how many bytes were moved, or a negative errno if none were.

Definition at line 253 of file kdev.c.

References iobuf_in(), iobuf_out(), kdev_blk_io(), kdev_bread(), kdev_bwrite(), kfree(), kmalloc(), MIN, PAGE_SIZE, iobuf::resid, and dev::write.

Referenced by kdev_blk_io(), kdev_read(), and kdev_write().

◆ kdev_blkdev_register()

void kdev_blkdev_register ( devid_t major,
struct dev * dev )

Registers a driver as the block device of a major number.

A driver registered before for that major is replaced.

Parameters
majorthe major number
devthe driver

Definition at line 605 of file kdev.c.

References blkdev, kdev_blkdev_register(), dev::name, and printk().

Referenced by ata_probe(), kdev_blkdev_register(), and rd_probe().

◆ kdev_bread()

ssize_t kdev_bread ( struct devid * dd,
off_t offset,
size_t size,
void * buf )

Reads bytes from a block device, at any offset: the driver reads whole blocks, and the partial blocks at either end go through a buffer.

Parameters
ddthe device's number
offsetwhere to read from, in bytes
sizehow many bytes to read
bufwhere to put them
Returns
how many bytes were read (fewer at the device's end), or a negative errno if nothing could be

Definition at line 80 of file kdev.c.

References dev::bread, dev::getbs, kdev_bread(), kdev_get(), kfree(), kmalloc(), memcpy(), MIN, and NULL.

Referenced by kdev_blk_io(), and kdev_bread().

◆ kdev_bwrite()

ssize_t kdev_bwrite ( struct devid * dd,
off_t offset,
size_t size,
void * buf )

Writes bytes to a block device, at any offset: the driver writes whole blocks, and the partial blocks at either end are read, changed and written back.

Parameters
ddthe device's number
offsetwhere to write, in bytes
sizehow many bytes to write
bufthe bytes
Returns
how many bytes were written, or a negative errno if nothing could be (-ENOSPC past the device's end)

Definition at line 165 of file kdev.c.

References dev::bread, dev::bwrite, dev::getbs, kdev_bwrite(), kdev_get(), kfree(), kmalloc(), memcpy(), MIN, and NULL.

Referenced by kdev_blk_io(), and kdev_bwrite().

◆ kdev_chrdev_register()

void kdev_chrdev_register ( devid_t major,
struct dev * dev )

Registers a driver as the character device of a major number.

A driver registered before for that major is replaced.

Parameters
majorthe major number
devthe driver

Definition at line 575 of file kdev.c.

References chrdev, kdev_chrdev_register(), dev::name, and printk().

Referenced by fbdev_probe(), kdev_chrdev_register(), memdev_probe(), ps2mouse_probe(), pty_init(), ttydev_probe(), and vt_probe().

◆ kdev_close()

int kdev_close ( struct devid * dev)

Closes a device: there is nothing to do.

Parameters
devthe device's number
Returns
0

Definition at line 64 of file kdev.c.

References kdev_close().

Referenced by kdev_close().

◆ kdev_file_can_read()

int kdev_file_can_read ( struct devid * dd,
struct file * file,
size_t size )

Asks a device's driver whether a read wouldn't have to wait.

Parameters
ddthe device's number
filethe open file
sizehow much would be read
Returns
whether it can be read, or a negative errno

Definition at line 513 of file kdev.c.

References fops::can_read, dev::fops, kdev_file_can_read(), kdev_get(), and NULL.

Referenced by kdev_file_can_read(), and vfs_file_can_read().

◆ kdev_file_can_write()

int kdev_file_can_write ( struct devid * dd,
struct file * file,
size_t size )

Asks a device's driver whether a write wouldn't have to wait.

Parameters
ddthe device's number
filethe open file
sizehow much would be written
Returns
whether it can be written, or a negative errno

Definition at line 534 of file kdev.c.

References fops::can_write, dev::fops, kdev_file_can_write(), kdev_get(), and NULL.

Referenced by kdev_file_can_write(), and vfs_file_can_write().

◆ kdev_file_close()

ssize_t kdev_file_close ( struct devid * dd,
struct file * file )

Closes an open device file, through its driver's file operations.

Parameters
ddthe device's number
filethe open file
Returns
0, or a negative errno

Definition at line 468 of file kdev.c.

References fops::close, dev::fops, kdev_file_close(), kdev_get(), NULL, and posix_file_close().

Referenced by kdev_file_close(), and vfs_file_close().

◆ kdev_file_eof()

int kdev_file_eof ( struct devid * dd,
struct file * file )

Asks a device's driver whether a read that found no data is at the end of the file.

Parameters
ddthe device's number
filethe open file
Returns
whether it is, or a negative errno

Definition at line 555 of file kdev.c.

References fops::eof, dev::fops, kdev_file_eof(), kdev_get(), and NULL.

Referenced by kdev_file_eof(), and vfs_file_eof().

◆ kdev_file_ioctl()

int kdev_file_ioctl ( struct devid * dd,
struct file * file,
int request,
void * argp )

Passes an ioctl() on an open device file to its driver's file operations.

Parameters
ddthe device's number
filethe open file
requestthe request
argpits argument
Returns
what the driver returns, or a negative errno

Definition at line 492 of file kdev.c.

References dev::fops, fops::ioctl, kdev_file_ioctl(), kdev_get(), and NULL.

Referenced by kdev_file_ioctl(), and vfs_file_ioctl().

◆ kdev_file_lseek()

off_t kdev_file_lseek ( struct devid * dd,
struct file * file,
off_t offset,
int whence )

Moves an open device file's offset, through its driver's file operations.

Parameters
ddthe device's number
filethe open file
offsetthe offset
whencewhat it is from (SEEK_SET, SEEK_CUR, SEEK_END)
Returns
the new offset, or a negative errno (-ESPIPE for a device that can't seek)

Definition at line 447 of file kdev.c.

References dev::fops, kdev_file_lseek(), kdev_get(), fops::lseek, and NULL.

Referenced by kdev_file_lseek(), and vfs_file_lseek().

◆ kdev_file_open()

int kdev_file_open ( struct devid * dd,
struct file * file )

Opens a device, through its driver's file operations.

Parameters
ddthe device's number
filethe open file
Returns
0, or a negative errno (-ENXIO if there is no such device)

Definition at line 381 of file kdev.c.

References dev::fops, kdev_file_open(), kdev_get(), NULL, and fops::open.

Referenced by ctty_open(), kdev_file_open(), and vfs_file_open().

◆ kdev_file_read()

ssize_t kdev_file_read ( struct devid * dd,
struct file * file,
struct iobuf * io )

Reads an open device file, through its driver's file operations.

Parameters
ddthe device's number
filethe open file
iowhere to put what is read
Returns
how many bytes were read, or a negative errno

Definition at line 402 of file kdev.c.

References dev::fops, kdev_file_read(), kdev_get(), NULL, and fops::read.

Referenced by kdev_file_read(), and vfs_file_read().

◆ kdev_file_write()

ssize_t kdev_file_write ( struct devid * dd,
struct file * file,
struct iobuf * io )

Writes to an open device file, through its driver's file operations.

Parameters
ddthe device's number
filethe open file
iowhat to write
Returns
how many bytes were written, or a negative errno

Definition at line 423 of file kdev.c.

References dev::fops, kdev_file_write(), kdev_get(), NULL, and fops::write.

Referenced by kdev_file_write(), and vfs_file_write().

◆ kdev_fops()

struct fops * kdev_fops ( struct devid * dd)

Returns the file operations of a device.

Parameters
ddthe device's number
Returns
its file operations, or NULL if there is no such device

Definition at line 52 of file kdev.c.

References dev::fops, kdev_fops(), kdev_get(), and NULL.

Referenced by kdev_fops(), and posix_file_read().

◆ kdev_get()

struct dev * kdev_get ( struct devid * dd)
inlinestatic

Returns the driver of a device number, picked by minor if the major's driver multiplexes several devices, or NULL if there is none.

Definition at line 26 of file kdev.c.

References blkdev, chrdev, kdev_get(), devid::major, dev::mux, NULL, and devid::type.

Referenced by kdev_bread(), kdev_bwrite(), kdev_file_can_read(), kdev_file_can_write(), kdev_file_close(), kdev_file_eof(), kdev_file_ioctl(), kdev_file_lseek(), kdev_file_open(), kdev_file_read(), kdev_file_write(), kdev_fops(), kdev_get(), kdev_ioctl(), kdev_map(), kdev_read(), and kdev_write().

◆ kdev_init()

void kdev_init ( void )

Starts the device layer, at boot.

It has nothing to set up: the drivers register themselves.

Definition at line 615 of file kdev.c.

References kdev_init(), and printk().

Referenced by kdev_init(), and kmain().

◆ kdev_ioctl()

int kdev_ioctl ( struct devid * dd,
int request,
void * argp )

Passes an ioctl() to a device's driver.

Parameters
ddthe device's number
requestthe request
argpits argument
Returns
what the driver returns, or -ENXIO if it takes no ioctl()

Definition at line 340 of file kdev.c.

References dev::ioctl, kdev_get(), kdev_ioctl(), and NULL.

Referenced by kdev_ioctl(), and vfs_ioctl().

◆ kdev_map()

int kdev_map ( struct devid * dd,
struct vm_space * vm_space,
struct vm_entry * vm_entry )

Maps a device into an address space (mmap() of a framebuffer).

Parameters
ddthe device's number
vm_spacethe address space
vm_entrythe mapping
Returns
0, or a negative errno (-ENXIO if the device can't be mapped)

Definition at line 361 of file kdev.c.

References kdev_get(), kdev_map(), dev::map, and NULL.

Referenced by kdev_map(), and vfs_map().

◆ kdev_read()

ssize_t kdev_read ( struct devid * dd,
off_t offset,
struct iobuf * io )

Reads from a device: a character device through its driver, a block device in blocks.

Parameters
ddthe device's number
offsetwhere to read from, in bytes
iowhere to put what is read
Returns
how many bytes were read, or a negative errno

Definition at line 297 of file kdev.c.

References dev::bread, kdev_blk_io(), kdev_get(), kdev_read(), NULL, dev::read, and devid::type.

Referenced by kdev_read(), and vfs_read_io().

◆ kdev_sync()

int kdev_sync ( void )

Writes what the block cache holds that was written, and what the block devices hold in their write caches, to the media.

Returns
0, or a negative errno if a write failed

Definition at line 587 of file kdev.c.

References blkcache_flush(), blkdev, kdev_sync(), and dev::sync.

Referenced by kdev_sync(), kernel_reboot(), and sys_sync().

◆ kdev_write()

ssize_t kdev_write ( struct devid * dd,
off_t offset,
struct iobuf * io )

Writes to a device: a character device through its driver, a block device in blocks.

Parameters
ddthe device's number
offsetwhere to write, in bytes
iowhat to write
Returns
how many bytes were written, or a negative errno

Definition at line 319 of file kdev.c.

References dev::bwrite, kdev_blk_io(), kdev_get(), kdev_write(), NULL, devid::type, and dev::write.

Referenced by kdev_write(), and vfs_write_io().

Variable Documentation

◆ blkdev

struct dev* blkdev[256]

Definition at line 22 of file kdev.c.

Referenced by kdev_blkdev_register(), kdev_get(), kdev_sync(), and procfs_devices().

◆ chrdev

struct dev* chrdev[256]

Definition at line 21 of file kdev.c.

Referenced by kdev_chrdev_register(), kdev_get(), and procfs_devices().