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