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 
00050 static void devfs_initialize(struct vfs_mountPoint *mp) {
00051   struct devfs_info *fsInfo = 0x0;
00052 
00053   
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   
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 
00156 
00157 
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   
00217   struct fileSystem devFS =
00218    {NULL,                         
00219     NULL,                         
00220     (void *)devfs_initialize,     
00221     (void *)devfs_read,           
00222     (void *)devfs_write,          
00223     (void *)devfs_open,           
00224     NULL,                         
00225     NULL,                         
00226     NULL,                         
00227     NULL,                         
00228     1                             
00229    }; 
00230 
00231     if (vfsRegisterFS(devFS) != 0x0) {
00232     
00233     return(0x1);
00234     }
00235   
00236   vfs_mount(0x0,0x0,0x0,0x1,"devfs","rw"); 
00237   
00238   
00239   return(0x0);
00240   }
00241 
00242 
00243 
00244