00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
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 
00041 static spinLock_t devfsSpinLock = SPIN_LOCK_INITIALIZER;
00042 
00043 
00044 static int devfs_len = 0x0;
00045 
00046 static void devfs_initialize(vfs_mountPoint_t *mp) {
00047   struct devfs_info *fsInfo = 0x0;
00048   
00049   
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   
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 
00101 
00102 
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 
00147 
00148 
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   vfs_mountPoint_t  *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   
00208   struct fileSystem devFS =
00209    {NULL,                         
00210     NULL,                         
00211     (void *)devfs_initialize,     
00212     (void *)devfs_read,           
00213     (void *)devfs_write,          
00214     (void *)devfs_open,           
00215     NULL,                         
00216     NULL,                         
00217     NULL,                         
00218     NULL,                         
00219     1                             
00220    }; 
00221 
00222     if (vfsRegisterFS(devFS) != 0x0) {
00223     
00224     return(0x1);
00225     }
00226   
00227   vfs_mount(0x0,0x0,0x0,0x1,"devfs","rw"); 
00228   
00229   
00230   return(0x0);
00231   }
00232 
00233 
00234 
00235