# devfs.c

Go to the documentation of this file.

    00001 /*****************************************************************************************
    00002  Copyright (c) 2002-2004 The UbixOS Project
    00003  All rights reserved.
    00004
    00005  Redistribution and use in source and binary forms, with or without modification, are
    00006  permitted provided that the following conditions are met:
    00007
    00008  Redistributions of source code must retain the above copyright notice, this list of
    00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
    00010  form must reproduce the above copyright notice, this list of conditions, the following
    00011  disclaimer and the list of authors in the documentation and/or other materials provided
    00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
    00013  contributors may be used to endorse or promote products derived from this software
    00014  without specific prior written permission.
    00015
    00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
    00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
    00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00025
    00026  $Id: devfs_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
    00027
    00028 *****************************************************************************************/
    00029
    00030 #include <devfs/devfs.h>
    00031 #include <vfs/vfs.h>
    00032 #include <sys/device.h>
    00033 #include <ubixos/types.h>
    00034 #include <ubixos/spinlock.h>
    00035 #include <ubixos/kpanic.h>
    00036 #include <lib/kmalloc.h>
    00037 #include <lib/string.h>
    00038 #include <lib/kprintf.h>
    00039
    00040 /* Spinlock for devfs we should start converting to sem/mutex */
    00041 static spinLock_t devfsSpinLock = SPIN_LOCK_INITIALIZER;
    00042
    00043 /* Length of dev list */
    00044 static int devfs_len = 0x0;
    00045
    00050 static void devfs_initialize(struct vfs_mountPoint *mp) {
    00051   struct devfs_info *fsInfo = 0x0;
    00052
    00053   /* Allocate memory for the fsInfo */
    00054   if ((mp->fsInfo = (struct devfs_info *)kmalloc(sizeof(struct devfs_info))) == 0x0)
    00055     K_PANIC("devfs: failed to allocate memor\n");
    00056
    00057   fsInfo = mp->fsInfo;
    00058   fsInfo->deviceList = 0x0;
    00059
    00060   /* Return */
    00061   return;
    00062   }
    00063
    00071 static int devfs_open(char *file,fileDescriptor *fd) {
    00072   struct devfs_info    *fsInfo  = fd->mp->fsInfo;
    00073   struct devfs_devices *tmpDev = 0x0;
    00074   struct device_node   *device = 0x0;
    00075
    00076   spinLock(&devfsSpinLock);
    00077
    00078   if (strcmp(file,"/") == 0x0) {
    00079     fd->start = -1;
    00080     fd->size  = devfs_len;
    00081     spinUnlock(&devfsSpinLock);
    00082     return(0x1);
    00083     }
    00084   if (file[0] == '/')
    00085     file++;
    00086   for (tmpDev = fsInfo->deviceList;tmpDev != 0x0;tmpDev = tmpDev->next) {
    00087     if (strcmp(tmpDev->devName,file) == 0x0) {
    00088       switch ((fd->mode & 0x3)) {
    00089         case 0:
    00090         case 1:
    00091           device = device_find(tmpDev->devMajor,tmpDev->devMinor);
    00092           (void *)fd->start = tmpDev;
    00093           fd->size  = device->devInfo->size;
    00094           break;
    00095         default:
    00096           kprintf("Invalid File Mode\n");
    00097           spinUnlock(&devfsSpinLock);
    00098           return(-1);
    00099           break;
    00100           }
    00101         spinUnlock(&devfsSpinLock);
    00102         return(0x1);
    00103       }
    00104     }
    00105   spinUnlock(&devfsSpinLock);
    00106   return(0x0);
    00107   }
    00108
    00114 static int devfs_read(fileDescriptor *fd,char *data,long offset,long size) {
    00115   int i = 0x0,x = 0x0;
    00116   uInt32 sectors = 0x0;
    00117   uInt16 diff    = 0x0;
    00118   struct device_node   *device = 0x0;
    00119   struct devfs_devices *tmpDev = (void *)fd->start;
    00120
    00121   if (tmpDev == -1) {
    00122     kprintf("Hi Ubie [%i]!!!\n", size);
    00123     for (i = 0;i < size;i++) {
    00124       data[i] = 'a';
    00125       fd->buffer[i] = 'a';
    00126       }
    00127     data[size - 1] = '\n';
    00128     return(size);
    00129     }
    00130
    00131   device = device_find(tmpDev->devMajor,tmpDev->devMinor);
    00132
    00133   sectors = ((size+511)/512);
    00134   diff    = (offset - ((offset/512)*512));
    00135
    00136   for (i=0x0;i<sectors;i++) {
    00137     device->devInfo->read(device->devInfo->info,fd->buffer,i + (offset/512),1);
    00138     for (x=0x0;x<(size - (i*512));x++) {
    00139       if (diff > 0) {
    00140         data[x] = fd->buffer[x + diff];
    00141         }
    00142       else {
    00143         data[x] = fd->buffer[x];
    00144         }
    00145       }
    00146     diff  = 0x0;
    00147     data += 512;
    00148     }
    00149
    00150   return(size);
    00151   }
    00152
    00153 /************************************************************************
    00154
    00155 Function: int writeDevFS(fileDescriptor *fd,char *data,long offset,long size)
    00156 Description: Write Data Into File
    00157 Notes:
    00158
    00159 ************************************************************************/
    00160 static int devfs_write(fileDescriptor *fd,char *data,long offset,long size) {
    00161   int i = 0x0,x = 0x0;
    00162   struct device_node   *device = 0x0;
    00163   struct devfs_devices *tmpDev = (void *)fd->start;
    00164
    00165   device = device_find(tmpDev->devMajor,tmpDev->devMinor);
    00166   for (i=0x0;i<((size+511)/512);i++) {
    00167     device->devInfo->read(device->devInfo->info,fd->buffer,i + (offset/512),1);
    00168     for (x=0x0;((x < 512) && ((x + (i * 512))  < size));x++) {
    00169       fd->buffer[x] = data[x];
    00170       }
    00171     device->devInfo->write(device->devInfo->info,fd->buffer,i + (offset/512),1);
    00172     data += 512;
    00173     }
    00174   return(size);
    00175   }
    00176
    00177
    00178 int devfs_makeNode(char *name,uInt8 type,uInt16 major,uInt16 minor) {
    00179   struct vfs_mountPoint  *mp     = 0x0;
    00180   struct devfs_info    *fsInfo = 0x0;
    00181   struct devfs_devices *tmpDev = 0x0;
    00182
    00183   spinLock(&devfsSpinLock);
    00184
    00185   mp = vfs_findMount("devfs");
    00186
    00187   if (mp == 0x0) {
    00188     kprintf("Error: Can't Find Mount Point\n");
    00189     spinUnlock(&devfsSpinLock);
    00190     return(-1);
    00191     }
    00192
    00193   fsInfo = mp->fsInfo;
    00194
    00195   tmpDev = (struct devfs_devices *)kmalloc(sizeof(struct devfs_devices));
    00196
    00197   tmpDev->devType  = type;
    00198   tmpDev->devMajor = major;
    00199   tmpDev->devMinor = minor;
    00200   sprintf(tmpDev->devName,name);
    00201   devfs_len += strlen(name) + 1;
    00202
    00203   tmpDev->next = fsInfo->deviceList;
    00204   tmpDev->prev = 0x0;
    00205   if (fsInfo->deviceList != 0x0) {
    00206     fsInfo->deviceList->prev = tmpDev;
    00207     }
    00208
    00209   fsInfo->deviceList       = tmpDev;
    00210
    00211   spinUnlock(&devfsSpinLock);
    00212   return(0x0);
    00213   }
    00214
    00215 int devfs_init() {
    00216   /* Build our devfs struct */
    00217   struct fileSystem devFS =
    00218    {NULL,                         /* prev        */
    00219     NULL,                         /* next        */
    00220     (void *)devfs_initialize,     /* vfsInitFS   */
    00221     (void *)devfs_read,           /* vfsRead     */
    00222     (void *)devfs_write,          /* vfsWrite    */
    00223     (void *)devfs_open,           /* vfsOpenFile */
    00224     NULL,                         /* vfsUnlink   */
    00225     NULL,                         /* vfsMakeDir  */
    00226     NULL,                         /* vfsRemDir   */
    00227     NULL,                         /* vfsSync     */
    00228     1                             /* vfsType     */
    00229    }; /* devFS */
    00230
    00231     if (vfsRegisterFS(devFS) != 0x0) {
    00232     //sysErr(systemErr,"Unable To Enable DevFS");
    00233     return(0x1);
    00234     }
    00235   /* Mount our devfs this will build the devfs container node */
    00236   vfs_mount(0x0,0x0,0x0,0x1,"devfs","rw"); // Mount Device File System
    00237
    00238   /* Return */
    00239   return(0x0);
    00240   }
    00241
    00242 /***
    00243  END
    00244  ***/