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(struct vfs_mountPoint *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 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
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