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$
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 
00046 static void devfs_initialize(struct vfs_mountPoint *mp) {
00047   struct devfs_info *fsInfo = 0x0;
00048   
00049   /* Allocate memory for the fsInfo */
00050   if ((mp->fsInfo = (struct devfs_info *)kmalloc(sizeof(struct devfs_info))) == 0x0)
00051     kpanic("devfs: failed to allocate memor\n");
00052   
00053   fsInfo = mp->fsInfo;
00054   fsInfo->deviceList = 0x0;
00055 
00056   //Return
00057   return;
00058   }
00059 
00060 static int devfs_open(char *file,fileDescriptor *fd) {
00061   struct devfs_info    *fsInfo  = fd->mp->fsInfo;
00062   struct devfs_devices *tmpDev = 0x0;
00063   struct device_node   *device = 0x0;
00064 
00065   spinLock(&devfsSpinLock);
00066 
00067   if (strcmp(file,"/") == 0x0) {
00068     fd->start = -1;
00069     fd->size  = devfs_len;
00070     spinUnlock(&devfsSpinLock);
00071     return(0x1);
00072     }
00073   if (file[0] == '/')
00074     file++;  
00075   for (tmpDev = fsInfo->deviceList;tmpDev != 0x0;tmpDev = tmpDev->next) {
00076     if (strcmp(tmpDev->devName,file) == 0x0) {
00077       switch ((fd->mode & 0x3)) {
00078         case 0:
00079         case 1:
00080           device = device_find(tmpDev->devMajor,tmpDev->devMinor);
00081           (void *)fd->start = tmpDev;
00082           fd->size  = device->devInfo->size;
00083           break;
00084         default:
00085           kprintf("Invalid File Mode\n");
00086           spinUnlock(&devfsSpinLock);
00087           return(-1);
00088           break;
00089           }
00090         spinUnlock(&devfsSpinLock);
00091         return(0x1);
00092       }
00093     }
00094   spinUnlock(&devfsSpinLock);
00095   return(0x0);
00096   }
00097 
00098 /************************************************************************
00099 
00100 Function: int readDevFS(fileDescriptor *fd,char *data,long offset,long size)
00101 Description: Read File Into Data
00102 Notes:
00103 
00104 ************************************************************************/
00105 static int devfs_read(fileDescriptor *fd,char *data,long offset,long size) {
00106   int i = 0x0,x = 0x0;
00107   uInt32 sectors = 0x0;
00108   uInt16 diff    = 0x0;
00109   struct device_node   *device = 0x0;
00110   struct devfs_devices *tmpDev = (void *)fd->start;
00111 
00112   if (tmpDev == -1) {
00113     kprintf("Hi Ubie [%i]!!!\n", size);
00114     for (i = 0;i < size;i++) {
00115       data[i] = 'a';
00116       fd->buffer[i] = 'a';
00117       }
00118     data[size - 1] = '\n';
00119     return(size);
00120     }
00121   
00122   device = device_find(tmpDev->devMajor,tmpDev->devMinor);
00123 
00124   sectors = ((size+511)/512);
00125   diff    = (offset - ((offset/512)*512));
00126 
00127   for (i=0x0;i<sectors;i++) {
00128     device->devInfo->read(device->devInfo->info,fd->buffer,i + (offset/512),1);
00129     for (x=0x0;x<(size - (i*512));x++) {
00130       if (diff > 0) {
00131         data[x] = fd->buffer[x + diff];
00132         }
00133       else {
00134         data[x] = fd->buffer[x];
00135         }
00136       }
00137     diff  = 0x0;
00138     data += 512;
00139     }
00140   
00141   return(size);
00142   }
00143 
00144 /************************************************************************
00145 
00146 Function: int writeDevFS(fileDescriptor *fd,char *data,long offset,long size)
00147 Description: Write Data Into File
00148 Notes:
00149 
00150 ************************************************************************/
00151 static int devfs_write(fileDescriptor *fd,char *data,long offset,long size) {
00152   int i = 0x0,x = 0x0;
00153   struct device_node   *device = 0x0;
00154   struct devfs_devices *tmpDev = (void *)fd->start;
00155 
00156   device = device_find(tmpDev->devMajor,tmpDev->devMinor);
00157   for (i=0x0;i<((size+511)/512);i++) {
00158     device->devInfo->read(device->devInfo->info,fd->buffer,i + (offset/512),1);
00159     for (x=0x0;((x < 512) && ((x + (i * 512))  < size));x++) {
00160       fd->buffer[x] = data[x];
00161       }
00162     device->devInfo->write(device->devInfo->info,fd->buffer,i + (offset/512),1);
00163     data += 512;
00164     }
00165   return(size);
00166   }
00167 
00168   
00169 int devfs_makeNode(char *name,uInt8 type,uInt16 major,uInt16 minor) {
00170   struct vfs_mountPoint  *mp     = 0x0;
00171   struct devfs_info    *fsInfo = 0x0;
00172   struct devfs_devices *tmpDev = 0x0;
00173 
00174   spinLock(&devfsSpinLock);
00175   
00176   mp = vfs_findMount("devfs");
00177   
00178   if (mp == 0x0) {
00179     kprintf("Error: Can't Find Mount Point\n");
00180     spinUnlock(&devfsSpinLock);
00181     return(-1);
00182     }
00183     
00184   fsInfo = mp->fsInfo;
00185 
00186   tmpDev = (struct devfs_devices *)kmalloc(sizeof(struct devfs_devices));
00187 
00188   tmpDev->devType  = type;
00189   tmpDev->devMajor = major;
00190   tmpDev->devMinor = minor;
00191   sprintf(tmpDev->devName,name);
00192   devfs_len += strlen(name) + 1;
00193 
00194   tmpDev->next = fsInfo->deviceList;
00195   tmpDev->prev = 0x0;
00196   if (fsInfo->deviceList != 0x0) {
00197     fsInfo->deviceList->prev = tmpDev;
00198     }
00199     
00200   fsInfo->deviceList       = tmpDev;
00201   
00202   spinUnlock(&devfsSpinLock);
00203   return(0x0);
00204   }  
00205   
00206 int devfs_init() {
00207   /* Build our devfs struct */
00208   struct fileSystem devFS =
00209    {NULL,                         /* prev        */
00210     NULL,                         /* next        */
00211     (void *)devfs_initialize,     /* vfsInitFS   */
00212     (void *)devfs_read,           /* vfsRead     */
00213     (void *)devfs_write,          /* vfsWrite    */
00214     (void *)devfs_open,           /* vfsOpenFile */
00215     NULL,                         /* vfsUnlink   */
00216     NULL,                         /* vfsMakeDir  */
00217     NULL,                         /* vfsRemDir   */
00218     NULL,                         /* vfsSync     */
00219     1                             /* vfsType     */
00220    }; /* devFS */
00221 
00222     if (vfsRegisterFS(devFS) != 0x0) {
00223     //sysErr(systemErr,"Unable To Enable DevFS");
00224     return(0x1);
00225     }
00226   /* Mount our devfs this will build the devfs container node */
00227   vfs_mount(0x0,0x0,0x0,0x1,"devfs","rw"); // Mount Device File System
00228   
00229   /* Return */
00230   return(0x0);
00231   }
00232 
00233 /***
00234  END
00235  ***/

Generated on Tue Dec 5 09:28:03 2006 for UbixOS V2 by  doxygen 1.4.7