⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskdevs.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * diskdevs.c - Physical and logical block devices (disks) support * * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov <vvv@oktet.ru> * * @(#) $Id: diskdevs.c,v 1.2 2002/11/15 14:18:28 ralf Exp $ */#include <rtems.h>#include <rtems/libio.h>#include <stdlib.h>#include <unistd.h>	/* unlink */#include <string.h>#include "rtems/diskdevs.h"#include "rtems/bdbuf.h"#define DISKTAB_INITIAL_SIZE 32/* Table of disk devices having the same major number */struct disk_device_table {    disk_device **minor; /* minor-indexed disk device table */    int size;            /* Number of entries in the table */};/* Pointer to [major].minor[minor] indexed array of disk devices */static struct disk_device_table *disktab;/* Number of allocated entries in disktab table */static int disktab_size;/* Mutual exclusion semaphore for disk devices table */static rtems_id diskdevs_mutex;/* Flag meaning that disk I/O, buffering etc. already has been initialized. */static boolean disk_io_initialized = FALSE;/* diskdevs data structures protection flag. * Normally, only table lookup operations performed. It is quite fast, so * it is possible to done lookups when interrupts are disabled, avoiding * obtaining the semaphore. This flags sets immediately after entering in * mutex-protected section and cleared before leaving this section in * "big" primitives like add/delete new device etc. Lookup function first * disable interrupts and check this flag. If it is set, lookup function * will be blocked on semaphore and lookup operation will be performed in * semaphore-protected code. If it is not set (very-very frequent case), * we can do lookup safely, enable interrupts and return result. */static volatile rtems_boolean diskdevs_protected;/* create_disk_entry -- *     Return pointer to the disk_entry structure for the specified device, or *     create one if it is not exists. * * PARAMETERS: *     dev - device id (major, minor) * * RETURNS: *     pointer to the disk device descirptor entry, or NULL if no memory *     available for its creation. */static disk_device *create_disk_entry(dev_t dev){    rtems_device_major_number major;    rtems_device_minor_number minor;    struct disk_device **d;    rtems_filesystem_split_dev_t (dev, major, minor);        if (major >= disktab_size)    {        struct disk_device_table *p;        int newsize;        int i;        newsize = disktab_size * 2;        if (major >= newsize)            newsize = major + 1;        p = realloc(disktab, sizeof(struct disk_device_table) * newsize);        if (p == NULL)            return NULL;        p += disktab_size;        for (i = disktab_size; i < newsize; i++, p++)        {            p->minor = NULL;            p->size = 0;        }        disktab_size = newsize;    }        if ((disktab[major].minor == NULL) ||        (minor >= disktab[major].size))    {        int newsize;        disk_device **p;        int i;        int s = disktab[major].size;                if (s == 0)            newsize = DISKTAB_INITIAL_SIZE;        else            newsize = s * 2;        if (minor >= newsize)            newsize = minor + 1;                p = realloc(disktab[major].minor, sizeof(disk_device *) * newsize);        if (p == NULL)            return NULL;        disktab[major].minor = p;        p += s;        for (i = s; i < newsize; i++, p++)            *p = NULL;        disktab[major].size = newsize;    }        d = disktab[major].minor + minor;    if (*d == NULL)    {        *d = calloc(1, sizeof(disk_device));    }    return *d;}/* get_disk_entry -- *     Get disk device descriptor by device number. * * PARAMETERS: *     dev - block device number * * RETURNS: *     Pointer to the disk device descriptor corresponding to the specified *     device number, or NULL if disk device with such number not exists. */static inline disk_device *get_disk_entry(dev_t dev){    rtems_device_major_number major;    rtems_device_minor_number minor;    struct disk_device_table *dtab;    rtems_filesystem_split_dev_t (dev, major, minor);        if ((major >= disktab_size) || (disktab == NULL))        return NULL;            dtab = disktab + major;        if ((minor >= dtab->size) || (dtab->minor == NULL))        return NULL;        return dtab->minor[minor];}/* create_disk -- *     Check that disk entry for specified device number is not defined *     and create it. * * PARAMETERS: *     dev        - device identifier (major, minor numbers) *     name       - character name of device (e.g. /dev/hda) *     disdev     - placeholder for pointer to created disk descriptor * * RETURNS: *     RTEMS_SUCCESSFUL if disk entry successfully created, or *     error code if error occured (device already registered, *     no memory available). */static rtems_status_codecreate_disk(dev_t dev, char *name, disk_device **diskdev){    disk_device *dd;    char *n;        dd = get_disk_entry(dev);    if (dd != NULL)    {        return RTEMS_RESOURCE_IN_USE;    }        if (name == NULL)    {        n = NULL;    }    else    {        int nlen = strlen(name) + 1;        n = malloc(nlen);        if (n == NULL)            return RTEMS_NO_MEMORY;        strncpy(n, name, nlen);    }        dd = create_disk_entry(dev);    if (dd == NULL)    {        free(n);        return RTEMS_NO_MEMORY;    }        dd->dev = dev;    dd->name = n;        *diskdev = dd;        return RTEMS_SUCCESSFUL;}/* rtems_disk_create_phys -- *     Create physical disk entry. This function usually invoked from *     block device driver initialization code when physical device *     detected in the system. Device driver should provide ioctl handler *     to allow block device access operations. This primitive will register *     device in rtems (invoke rtems_io_register_name). * * PARAMETERS: *     dev        - device identifier (major, minor numbers) *     block_size - size of disk block (minimum data transfer unit); must be *                  power of 2 *     disk_size  - number of blocks on device *     handler    - IOCTL handler (function providing basic block input/output *                  request handling BIOREQUEST and other device management *                  operations) *     name       - character name of device (e.g. /dev/hda) * * RETURNS: *     RTEMS_SUCCESSFUL if information about new physical disk added, or *     error code if error occured (device already registered, wrong block *     size value, no memory available). */rtems_status_codertems_disk_create_phys(dev_t dev, int block_size, int disk_size,                       block_device_ioctl handler,                       char *name){    int bs_log2;    int i;    disk_device *dd;    rtems_status_code rc;    rtems_bdpool_id pool;    rtems_device_major_number major;    rtems_device_minor_number minor;    rtems_filesystem_split_dev_t (dev, major, minor);        for (bs_log2 = 0, i = block_size; (i & 1) == 0; i >>= 1, bs_log2++);    if ((bs_log2 < 9) || (i != 1)) /* block size < 512 or not power of 2 */        return RTEMS_INVALID_NUMBER;        rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);    if (rc != RTEMS_SUCCESSFUL)        return rc;    diskdevs_protected = TRUE;    rc = rtems_bdbuf_find_pool(block_size, &pool);    if (rc != RTEMS_SUCCESSFUL)    {        diskdevs_protected = FALSE;        rtems_semaphore_release(diskdevs_mutex);        return rc;    }        rc = create_disk(dev, name, &dd);    if (rc != RTEMS_SUCCESSFUL)    {        diskdevs_protected = FALSE;        rtems_semaphore_release(diskdevs_mutex);        return rc;    }        dd->phys_dev = dd;    dd->uses = 0;    dd->start = 0;    dd->size = disk_size;    dd->block_size = block_size;    dd->block_size_log2 = bs_log2;    dd->ioctl = handler;    dd->pool = pool;    rc = rtems_io_register_name(name, major, minor);        diskdevs_protected = FALSE;    rtems_semaphore_release(diskdevs_mutex);    return rc;}/* rtems_disk_create_log -- *     Create logical disk entry. Logical disk is contiguous area on physical *     disk. Disk may be splitted to several logical disks in several ways: *     manually or using information stored in blocks on physical disk *     (DOS-like partition table, BSD disk label, etc). This function usually *     invoked from application when application-specific splitting are in use, *     or from generic code which handle different logical disk organizations. *     This primitive will register device in rtems (invoke  *     rtems_io_register_name). * * PARAMETERS: *     dev   - logical device identifier (major, minor numbers) *     phys  - physical device (block device which holds this logical disk) *             identifier  *     start - starting block number on the physical device *     size  - logical disk size in blocks *     name  - logical disk name * * RETURNS: *     RTEMS_SUCCESSFUL if logical device successfully added, or error code *     if error occured (device already registered, no physical device *     exists, logical disk is out of physical disk boundaries, no memory  *     available). */rtems_status_codertems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name){    disk_device *dd;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -