UbixOS  2.0
devfs.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <devfs/devfs.h>
30 #include <vfs/vfs.h>
31 #include <sys/device.h>
32 #include <ubixos/spinlock.h>
33 #include <ubixos/kpanic.h>
34 #include <lib/kmalloc.h>
35 #include <string.h>
36 #include <lib/kprintf.h>
37 
38 /* Spinlock for devfs we should start converting to sem/mutex */
39 static struct spinLock devfsSpinLock = SPIN_LOCK_INITIALIZER;
40 
41 /* Length of dev list */
42 static int devfs_len = 0x0;
43 
48 static void devfs_initialize(struct vfs_mountPoint *mp) {
49  struct devfs_info *fsInfo = 0x0;
50 
51  /* Allocate memory for the fsInfo */
52  if ((mp->fsInfo = (struct devfs_info *) kmalloc(sizeof(struct devfs_info))) == 0x0)
53  K_PANIC("devfs: failed to allocate memor\n");
54 
55  fsInfo = mp->fsInfo;
56  fsInfo->deviceList = 0x0;
57 
58  /* Return */
59  return;
60 }
61 
69 static int devfs_open(char *file, fileDescriptor_t *fd) {
70  struct devfs_info *fsInfo = fd->mp->fsInfo;
71  struct devfs_devices *tmpDev = 0x0;
72  struct device_node *device = 0x0;
73 
74  spinLock(&devfsSpinLock);
75 
76  if (strcmp(file, "/") == 0x0) {
77  fd->start = -1;
78  fd->size = devfs_len;
79  spinUnlock(&devfsSpinLock);
80  return (0x1);
81  }
82  if (file[0] == '/')
83  file++;
84  for (tmpDev = fsInfo->deviceList; tmpDev != 0x0; tmpDev = tmpDev->next) {
85  if (strcmp(tmpDev->devName, file) == 0x0) {
86  switch ((fd->mode & 0x3)) {
87  case 0:
88  case 1:
89  device = device_find(tmpDev->devMajor, tmpDev->devMinor);
90  fd->start = (uint32_t *) tmpDev; /* MrOlsen (2016-01-19) FIX: I Don't Understand This */
91  fd->size = device->devInfo->size;
92  break;
93  default:
94  kprintf("Invalid File Mode\n");
95  spinUnlock(&devfsSpinLock);
96  return (-1);
97  break;
98  }
99  spinUnlock(&devfsSpinLock);
100  return (0x1);
101  }
102  }
103  spinUnlock(&devfsSpinLock);
104  return (0x0);
105 }
106 
112 static int devfs_read(fileDescriptor_t *fd, char *data, long offset, long size) {
113  int i = 0x0, x = 0x0;
114  uInt32 sectors = 0x0;
115  uInt16 diff = 0x0;
116  struct device_node *device = 0x0;
117  struct devfs_devices *tmpDev = (void *) fd->start;
118 
119  if (tmpDev == -1) {
120  kprintf("Hi Ubie [%i]!!!\n", size);
121  for (i = 0; i < size; i++) {
122  data[i] = 'a';
123  fd->buffer[i] = 'a';
124  }
125  data[size - 1] = '\n';
126  return (size);
127  }
128 
129  device = device_find(tmpDev->devMajor, tmpDev->devMinor);
130 
131  sectors = ((size + 511) / 512);
132  diff = (offset - ((offset / 512) * 512));
133 
134  for (i = 0x0; i < sectors; i++) {
135  device->devInfo->read(device->devInfo->info, fd->buffer, i + (offset / 512), 1);
136  for (x = 0x0; x < (size - (i * 512)); x++) {
137  if (diff > 0) {
138  data[x] = fd->buffer[x + diff];
139  }
140  else {
141  data[x] = fd->buffer[x];
142  }
143  }
144  diff = 0x0;
145  data += 512;
146  }
147 
148  return (size);
149 }
150 
151 /************************************************************************
152 
153  Function: int writeDevFS(fileDescriptor_t *fd,char *data,long offset,long size)
154  Description: Write Data Into File
155  Notes:
156 
157  ************************************************************************/
158 static int devfs_write(fileDescriptor_t *fd, char *data, long offset, long size) {
159  int i = 0x0, x = 0x0;
160  struct device_node *device = 0x0;
161  struct devfs_devices *tmpDev = (void *) fd->start;
162 
163  device = device_find(tmpDev->devMajor, tmpDev->devMinor);
164  for (i = 0x0; i < ((size + 511) / 512); i++) {
165  device->devInfo->read(device->devInfo->info, fd->buffer, i + (offset / 512), 1);
166  for (x = 0x0; ((x < 512) && ((x + (i * 512)) < size)); x++) {
167  fd->buffer[x] = data[x];
168  }
169  device->devInfo->write(device->devInfo->info, fd->buffer, i + (offset / 512), 1);
170  data += 512;
171  }
172  return (size);
173 }
174 
175 int devfs_makeNode(char *name, uInt8 type, uInt16 major, uInt16 minor) {
176  struct vfs_mountPoint *mp = 0x0;
177  struct devfs_info *fsInfo = 0x0;
178  struct devfs_devices *tmpDev = 0x0;
179 
180  spinLock(&devfsSpinLock);
181 
182  mp = vfs_findMount("devfs");
183 
184  if (mp == 0x0) {
185  kprintf("Error: Can't Find Mount Point\n");
186  spinUnlock(&devfsSpinLock);
187  return (-1);
188  }
189 
190  fsInfo = mp->fsInfo;
191 
192  tmpDev = (struct devfs_devices *) kmalloc(sizeof(struct devfs_devices));
193 
194  tmpDev->devType = type;
195  tmpDev->devMajor = major;
196  tmpDev->devMinor = minor;
197  sprintf(tmpDev->devName, name);
198  devfs_len += strlen(name) + 1;
199 
200  tmpDev->next = fsInfo->deviceList;
201  tmpDev->prev = 0x0;
202  if (fsInfo->deviceList != 0x0) {
203  fsInfo->deviceList->prev = tmpDev;
204  }
205 
206  fsInfo->deviceList = tmpDev;
207 
208  spinUnlock(&devfsSpinLock);
209  return (0x0);
210 }
211 
212 int devfs_init() {
213  /* Build our devfs struct */
214  struct fileSystem devFS = { NULL, /* prev */
215  NULL, /* next */
216  (void *) devfs_initialize, /* vfsInitFS */
217  (void *) devfs_read, /* vfsRead */
218  (void *) devfs_write, /* vfsWrite */
219  (void *) devfs_open, /* vfsOpenFile */
220  NULL, /* vfsUnlink */
221  NULL, /* vfsMakeDir */
222  NULL, /* vfsRemDir */
223  NULL, /* vfsSync */
224  1 /* vfsType */
225  }; /* devFS */
226 
227  if (vfsRegisterFS(devFS) != 0x0) {
228  //sysErr(systemErr,"Unable To Enable DevFS");
229  return (0x1);
230  }
231  /* Mount our devfs this will build the devfs container node */
232  vfs_mount(0x0, 0x0, 0x0, 0x1, "devfs", "rw"); // Mount Device File System
233 
234  /* Return */
235  return (0x0);
236 }
fileDescriptor::buffer
char * buffer
Definition: file.h:74
vfs_mount
int vfs_mount(int major, int minor, int partition, int vfsType, char *mountPoint, char *perms)
Definition: mount.c:45
spinlock.h
vfs_findMount
struct vfs_mountPoint * vfs_findMount(char *mountPoint)
Definition: mount.c:128
fileDescriptor::start
uint32_t start
Definition: file.h:72
uInt32
unsigned long int uInt32
Definition: objgfx30.h:49
vfs.h
devfs_devices::devType
uInt8 devType
Definition: devfs.h:38
K_PANIC
#define K_PANIC(msg)
Definition: kpanic.h:32
string.h
uInt16
unsigned short int uInt16
Definition: objgfx30.h:48
fileDescriptor::mode
uint16_t mode
Definition: file.h:68
fileDescriptor
Definition: file.h:62
file
Definition: descrip.h:67
strcmp
int strcmp(const char *str1, const char *str2)
spinUnlock
void spinUnlock(spinLock_t *lock)
Definition: spinlock.c:36
device
Definition: device.old.h:34
strlen
int strlen(const char *str)
Definition: strlen.c:55
SPIN_LOCK_INITIALIZER
#define SPIN_LOCK_INITIALIZER
Definition: spinlock.h:36
fileSystem
filesSystem Structure
Definition: vfs.h:59
devfs_devices::prev
struct devfs_devices * prev
Definition: devfs.h:37
devfs_devices
Definition: devfs.h:35
fileDescriptor::mp
struct vfs_mountPoint * mp
Definition: file.h:65
sprintf
int sprintf(char *buf, const char *fmt,...)
Definition: kprintf.c:278
spinLock
void spinLock(spinLock_t *lock)
Definition: spinlock.c:55
vfsRegisterFS
int vfsRegisterFS(struct fileSystem newFS)
register a file system
Definition: vfs.c:79
vfs_mountPoint
Definition: mount.h:66
kpanic.h
kprintf.h
devfs_devices::devMajor
uInt16 devMajor
Definition: devfs.h:39
device_node
Definition: device.h:34
uInt8
unsigned char uInt8
Definition: objgfx30.h:47
devfs_info::deviceList
struct devfs_devices * deviceList
Definition: devfs.h:45
devfs_devices::devName
char devName[32]
Definition: devfs.h:41
uint32_t
__uint32_t uint32_t
Definition: types.h:46
devfs_devices::next
struct devfs_devices * next
Definition: devfs.h:36
devfs_makeNode
int devfs_makeNode(char *name, uInt8 type, uInt16 major, uInt16 minor)
Definition: devfs.c:174
devfs.h
name
const char * name
Definition: pci.c:37
device.h
vfs_mountPoint::fsInfo
void * fsInfo
Definition: mount.h:72
device_find
struct device_node * device_find(int major, int minor)
Definition: device.c:82
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
spinLock
Definition: spinlock.h:41
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
devfs_info
Definition: devfs.h:44
devfs_devices::devMinor
uInt16 devMinor
Definition: devfs.h:40
fileDescriptor::size
uint32_t size
Definition: file.h:70
devfs_init
int devfs_init()
Definition: devfs.c:211
kmalloc.h
NULL
#define NULL
Definition: fat_string.h:17