Implement volume unmounting, collecting VFS volume info, usb Add eject command
This commit is contained in:
@@ -39,5 +39,7 @@
|
|||||||
#define SYS_STREAM_READ 36
|
#define SYS_STREAM_READ 36
|
||||||
#define SYS_GET_PROC_INFO 37
|
#define SYS_GET_PROC_INFO 37
|
||||||
#define SYS_GET_DEVICE_INFO 38
|
#define SYS_GET_DEVICE_INFO 38
|
||||||
|
#define SYS_GET_VOLUME_INFO 39
|
||||||
|
#define SYS_VOLUME_DELETE 40
|
||||||
|
|
||||||
#endif // _M_SYSCALL_DEFS_H
|
#endif // _M_SYSCALL_DEFS_H
|
||||||
|
|||||||
11
include/volume_info.h
Normal file
11
include/volume_info.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef _VOLUME_INFO_H
|
||||||
|
#define _VOLUME_INFO_H
|
||||||
|
|
||||||
|
#include <path_defs.h>
|
||||||
|
|
||||||
|
struct volume_info {
|
||||||
|
char volume_name[VOLUME_MAX];
|
||||||
|
char device_key[0x100];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _VOLUME_INFO_H
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
int name (struct vfs_volume* UNUSED volume, struct proc* UNUSED proc, \
|
int name (struct vfs_volume* UNUSED volume, struct proc* UNUSED proc, \
|
||||||
struct reschedule_ctx* UNUSED rctx, bool UNUSED format)
|
struct reschedule_ctx* UNUSED rctx, bool UNUSED format)
|
||||||
|
|
||||||
|
#define DEFINE_VFS_UNMOUNT(name) int name (struct vfs_volume* UNUSED volume)
|
||||||
|
|
||||||
#define DEFINE_VFS_FORMAT(name) \
|
#define DEFINE_VFS_FORMAT(name) \
|
||||||
int name (struct vfs_volume* UNUSED volume, struct proc* UNUSED proc, \
|
int name (struct vfs_volume* UNUSED volume, struct proc* UNUSED proc, \
|
||||||
struct reschedule_ctx* UNUSED rctx)
|
struct reschedule_ctx* UNUSED rctx)
|
||||||
|
|||||||
@@ -122,6 +122,14 @@ DEFINE_VFS_MOUNT (fatfs_mount) {
|
|||||||
return ST_OK;
|
return ST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_VFS_UNMOUNT (fatfs_unmount) {
|
||||||
|
struct fatfs_ctx* fatfs_ctx = volume->udata;
|
||||||
|
|
||||||
|
free (fatfs_ctx);
|
||||||
|
|
||||||
|
return ST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (fatfs16_format) {
|
DEFINE_VFS_FORMAT (fatfs16_format) {
|
||||||
uint64_t fd;
|
uint64_t fd;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ struct vfs_volume;
|
|||||||
|
|
||||||
DEFINE_VFS_MOUNT (fatfs_mount);
|
DEFINE_VFS_MOUNT (fatfs_mount);
|
||||||
|
|
||||||
|
DEFINE_VFS_UNMOUNT (fatfs_unmount);
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (fatfs16_format);
|
DEFINE_VFS_FORMAT (fatfs16_format);
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (fatfs32_format);
|
DEFINE_VFS_FORMAT (fatfs32_format);
|
||||||
|
|||||||
@@ -145,6 +145,14 @@ DEFINE_VFS_MOUNT (iso9660fs_mount) {
|
|||||||
return ST_OK;
|
return ST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_VFS_UNMOUNT (iso9660fs_unmount) {
|
||||||
|
l9660_fs* fs_ctx = volume->udata;
|
||||||
|
|
||||||
|
free (fs_ctx);
|
||||||
|
|
||||||
|
return ST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (iso9660fs_format) { return -ST_FORMAT_ERROR; }
|
DEFINE_VFS_FORMAT (iso9660fs_format) { return -ST_FORMAT_ERROR; }
|
||||||
|
|
||||||
DEFINE_VFS_DESCRIBE (iso9660fs_describe) {
|
DEFINE_VFS_DESCRIBE (iso9660fs_describe) {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ struct vfs_volume;
|
|||||||
|
|
||||||
DEFINE_VFS_MOUNT (iso9660fs_mount);
|
DEFINE_VFS_MOUNT (iso9660fs_mount);
|
||||||
|
|
||||||
|
DEFINE_VFS_UNMOUNT (iso9660fs_unmount);
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (iso9660fs_format);
|
DEFINE_VFS_FORMAT (iso9660fs_format);
|
||||||
|
|
||||||
DEFINE_VFS_DESCRIBE (iso9660fs_describe);
|
DEFINE_VFS_DESCRIBE (iso9660fs_describe);
|
||||||
|
|||||||
@@ -128,6 +128,14 @@ DEFINE_VFS_MOUNT (tarfs_mount) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_VFS_UNMOUNT (tarfs_unmount) {
|
||||||
|
struct tarfs* tarfs = volume->udata;
|
||||||
|
|
||||||
|
free (tarfs);
|
||||||
|
|
||||||
|
return ST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (tarfs_format) { return ST_OK; }
|
DEFINE_VFS_FORMAT (tarfs_format) { return ST_OK; }
|
||||||
|
|
||||||
DEFINE_VFS_DESCRIBE (tarfs_describe) {
|
DEFINE_VFS_DESCRIBE (tarfs_describe) {
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ struct vfs_volume;
|
|||||||
|
|
||||||
DEFINE_VFS_MOUNT (tarfs_mount);
|
DEFINE_VFS_MOUNT (tarfs_mount);
|
||||||
|
|
||||||
|
DEFINE_VFS_UNMOUNT (tarfs_unmount);
|
||||||
|
|
||||||
DEFINE_VFS_FORMAT (tarfs_format);
|
DEFINE_VFS_FORMAT (tarfs_format);
|
||||||
|
|
||||||
DEFINE_VFS_DESCRIBE (tarfs_describe);
|
DEFINE_VFS_DESCRIBE (tarfs_describe);
|
||||||
|
|||||||
@@ -19,9 +19,46 @@
|
|||||||
#include <status.h>
|
#include <status.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
|
#include <volume_info.h>
|
||||||
|
|
||||||
static struct vfs_volume_table volume_table;
|
static struct vfs_volume_table volume_table;
|
||||||
|
|
||||||
|
size_t volume_populate_volume_infos (struct volume_info* infos, size_t count) {
|
||||||
|
uint64_t fvt, fv, fd;
|
||||||
|
|
||||||
|
if (count >= lengthof (volume_table.volume_buckets))
|
||||||
|
count = lengthof (volume_table.volume_buckets);
|
||||||
|
|
||||||
|
spin_lock (&volume_table.lock, &fvt);
|
||||||
|
|
||||||
|
size_t j = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < lengthof (volume_table.volume_buckets); i++) {
|
||||||
|
struct hash_node_link* hash_link = volume_table.volume_buckets[i];
|
||||||
|
|
||||||
|
while (hash_link != NULL && j < count) {
|
||||||
|
struct vfs_volume* volume = hash_entry (hash_link, struct vfs_volume, volume_table_link);
|
||||||
|
struct volume_info* info = &infos[j];
|
||||||
|
|
||||||
|
spin_lock (&volume->lock, &fv);
|
||||||
|
spin_lock (&volume->back_device->lock, &fd);
|
||||||
|
|
||||||
|
memcpy (info->volume_name, volume->key, sizeof (info->volume_name));
|
||||||
|
memcpy (info->device_key, volume->back_device->key, sizeof (info->device_key));
|
||||||
|
|
||||||
|
spin_unlock (&volume->back_device->lock, fd);
|
||||||
|
spin_unlock (&volume->lock, fv);
|
||||||
|
|
||||||
|
hash_link = hash_link->next;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock (&volume_table.lock, fvt);
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
static struct vfs_volume* vfs_find_volume (const char* volume) {
|
static struct vfs_volume* vfs_find_volume (const char* volume) {
|
||||||
uint64_t fvt;
|
uint64_t fvt;
|
||||||
|
|
||||||
@@ -62,6 +99,7 @@ int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const cha
|
|||||||
switch (volume->fs_type) {
|
switch (volume->fs_type) {
|
||||||
case FS_TARFS:
|
case FS_TARFS:
|
||||||
volume->driver_ops.mount = &tarfs_mount;
|
volume->driver_ops.mount = &tarfs_mount;
|
||||||
|
volume->driver_ops.unmount = &tarfs_unmount;
|
||||||
volume->driver_ops.format = &tarfs_format;
|
volume->driver_ops.format = &tarfs_format;
|
||||||
volume->driver_ops.describe = &tarfs_describe;
|
volume->driver_ops.describe = &tarfs_describe;
|
||||||
volume->driver_ops.read_file = &tarfs_read_file;
|
volume->driver_ops.read_file = &tarfs_read_file;
|
||||||
@@ -73,6 +111,7 @@ int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const cha
|
|||||||
break;
|
break;
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
volume->driver_ops.mount = &fatfs_mount;
|
volume->driver_ops.mount = &fatfs_mount;
|
||||||
|
volume->driver_ops.unmount = &fatfs_unmount;
|
||||||
volume->driver_ops.format = &fatfs16_format;
|
volume->driver_ops.format = &fatfs16_format;
|
||||||
volume->driver_ops.describe = &fatfs_describe;
|
volume->driver_ops.describe = &fatfs_describe;
|
||||||
volume->driver_ops.read_file = &fatfs_read_file;
|
volume->driver_ops.read_file = &fatfs_read_file;
|
||||||
@@ -84,6 +123,7 @@ int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const cha
|
|||||||
break;
|
break;
|
||||||
case FS_FAT32:
|
case FS_FAT32:
|
||||||
volume->driver_ops.mount = &fatfs_mount;
|
volume->driver_ops.mount = &fatfs_mount;
|
||||||
|
volume->driver_ops.unmount = &fatfs_unmount;
|
||||||
volume->driver_ops.format = &fatfs32_format;
|
volume->driver_ops.format = &fatfs32_format;
|
||||||
volume->driver_ops.describe = &fatfs_describe;
|
volume->driver_ops.describe = &fatfs_describe;
|
||||||
volume->driver_ops.read_file = &fatfs_read_file;
|
volume->driver_ops.read_file = &fatfs_read_file;
|
||||||
@@ -95,6 +135,7 @@ int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const cha
|
|||||||
break;
|
break;
|
||||||
case FS_ISO9660:
|
case FS_ISO9660:
|
||||||
volume->driver_ops.mount = &iso9660fs_mount;
|
volume->driver_ops.mount = &iso9660fs_mount;
|
||||||
|
volume->driver_ops.unmount = &iso9660fs_unmount;
|
||||||
volume->driver_ops.format = &iso9660fs_format;
|
volume->driver_ops.format = &iso9660fs_format;
|
||||||
volume->driver_ops.describe = &iso9660fs_describe;
|
volume->driver_ops.describe = &iso9660fs_describe;
|
||||||
volume->driver_ops.read_file = &iso9660fs_read_file;
|
volume->driver_ops.read_file = &iso9660fs_read_file;
|
||||||
@@ -128,6 +169,52 @@ int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const cha
|
|||||||
return ST_OK;
|
return ST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vfs_volume_delete (const char* key) {
|
||||||
|
uint64_t fv, fvt;
|
||||||
|
|
||||||
|
struct hash_node_link* found_link = NULL;
|
||||||
|
size_t key_len = strlen_null (key);
|
||||||
|
uint32_t hash = hash_fnv32 (key, key_len);
|
||||||
|
|
||||||
|
spin_lock (&volume_table.lock, &fvt);
|
||||||
|
|
||||||
|
hash_find (&volume_table, key, key_len, hash, lengthof (volume_table.volume_buckets),
|
||||||
|
volume_buckets, struct vfs_volume, volume_table_link, key, found_link);
|
||||||
|
|
||||||
|
if (found_link == NULL) {
|
||||||
|
spin_unlock (&volume_table.lock, fvt);
|
||||||
|
return -ST_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vfs_volume* volume = hash_entry (found_link, struct vfs_volume, volume_table_link);
|
||||||
|
|
||||||
|
if (volume == NULL) {
|
||||||
|
spin_unlock (&volume_table.lock, fvt);
|
||||||
|
return -ST_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock (&volume->lock, &fv);
|
||||||
|
|
||||||
|
if (volume->locked) {
|
||||||
|
spin_unlock (&volume->lock, fv);
|
||||||
|
spin_unlock (&volume_table.lock, fvt);
|
||||||
|
return -ST_TRY_AGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_delete (&volume_table, key, strlen_null (key), hash, lengthof (volume_table.volume_buckets),
|
||||||
|
volume_buckets, struct vfs_volume, volume_table_link, key, found_link);
|
||||||
|
|
||||||
|
int ret = volume->driver_ops.unmount (volume);
|
||||||
|
|
||||||
|
spin_unlock (&volume->lock, fv);
|
||||||
|
|
||||||
|
free (volume);
|
||||||
|
|
||||||
|
spin_unlock (&volume_table.lock, fvt);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int vfs_volume_open (struct proc* proc, const char* volume_name, struct reschedule_ctx* rctx) {
|
int vfs_volume_open (struct proc* proc, const char* volume_name, struct reschedule_ctx* rctx) {
|
||||||
uint64_t fv;
|
uint64_t fv;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <proc/reschedule.h>
|
#include <proc/reschedule.h>
|
||||||
#include <proc/suspension_q.h>
|
#include <proc/suspension_q.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
#include <volume_info.h>
|
||||||
|
|
||||||
struct vfs_volume;
|
struct vfs_volume;
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ struct vfs_volume {
|
|||||||
int (*mount) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx,
|
int (*mount) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx,
|
||||||
bool format);
|
bool format);
|
||||||
|
|
||||||
|
int (*unmount) (struct vfs_volume* volume);
|
||||||
|
|
||||||
int (*format) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx);
|
int (*format) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx);
|
||||||
|
|
||||||
int (*describe) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx,
|
int (*describe) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx,
|
||||||
@@ -66,6 +69,8 @@ struct vfs_volume_table {
|
|||||||
int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const char* key, int fs_type,
|
int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const char* key, int fs_type,
|
||||||
struct device* back_device, bool format);
|
struct device* back_device, bool format);
|
||||||
|
|
||||||
|
int vfs_volume_delete (const char* key);
|
||||||
|
|
||||||
int vfs_volume_open (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
|
int vfs_volume_open (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
|
||||||
|
|
||||||
int vfs_volume_close (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
|
int vfs_volume_close (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
|
||||||
@@ -98,4 +103,6 @@ void vfs_init (void);
|
|||||||
void vfs_translate (size_t fs_block, size_t fs_block_count, size_t fs_block_size,
|
void vfs_translate (size_t fs_block, size_t fs_block_count, size_t fs_block_size,
|
||||||
size_t device_sector_size, size_t* out_phys_sector, size_t* out_sector_count);
|
size_t device_sector_size, size_t* out_phys_sector, size_t* out_sector_count);
|
||||||
|
|
||||||
|
size_t volume_populate_volume_infos (struct volume_info* infos, size_t count);
|
||||||
|
|
||||||
#endif // _KERNEL_FS_VFS_H
|
#endif // _KERNEL_FS_VFS_H
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <syscall/syscall.h>
|
#include <syscall/syscall.h>
|
||||||
#include <syscall_defs.h>
|
#include <syscall_defs.h>
|
||||||
|
#include <volume_info.h>
|
||||||
#include <write_file.h>
|
#include <write_file.h>
|
||||||
|
|
||||||
#define DEFINE_SYSCALL(name) \
|
#define DEFINE_SYSCALL(name) \
|
||||||
@@ -1097,6 +1098,57 @@ DEFINE_SYSCALL (sys_get_device_info) {
|
|||||||
return SYSRESULT (device_populate_device_infos (infos, infos_count));
|
return SYSRESULT (device_populate_device_infos (infos, infos_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* int get_volume_info (struct volume_info* infos, size_t count) */
|
||||||
|
DEFINE_SYSCALL (sys_get_volume_info) {
|
||||||
|
uint64_t fp;
|
||||||
|
|
||||||
|
uintptr_t uvaddr_infos = a1;
|
||||||
|
size_t infos_count = (size_t)a2;
|
||||||
|
|
||||||
|
spin_lock (&proc->lock, &fp);
|
||||||
|
struct procgroup* procgroup = proc->procgroup;
|
||||||
|
spin_unlock (&proc->lock, fp);
|
||||||
|
|
||||||
|
struct volume_info* infos =
|
||||||
|
sys_get_user_buffer (procgroup, uvaddr_infos, infos_count * sizeof (struct volume_info));
|
||||||
|
|
||||||
|
if (infos == NULL)
|
||||||
|
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||||
|
|
||||||
|
return SYSRESULT (volume_populate_volume_infos (infos, infos_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int volume_delete (const char* volume) */
|
||||||
|
DEFINE_SYSCALL (sys_volume_delete) {
|
||||||
|
uint64_t fpg, fp;
|
||||||
|
|
||||||
|
uintptr_t uvaddr_volume = a1;
|
||||||
|
|
||||||
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
|
uintptr_t out_paddr;
|
||||||
|
|
||||||
|
spin_lock (&proc->lock, &fp);
|
||||||
|
struct procgroup* procgroup = proc->procgroup;
|
||||||
|
spin_unlock (&proc->lock, fp);
|
||||||
|
|
||||||
|
spin_lock (&procgroup->lock, &fpg);
|
||||||
|
out_paddr = mm_v2p (&procgroup->pd, uvaddr_volume);
|
||||||
|
spin_unlock (&procgroup->lock, fpg);
|
||||||
|
|
||||||
|
if (out_paddr == 0)
|
||||||
|
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
|
||||||
|
|
||||||
|
const char* volume = (const char*)((uintptr_t)hhdm->offset + out_paddr);
|
||||||
|
|
||||||
|
int ret = vfs_volume_delete (volume);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return SYSRESULT (ret);
|
||||||
|
|
||||||
|
return SYSRESULT (ST_OK);
|
||||||
|
}
|
||||||
|
|
||||||
static syscall_handler_func_t handler_table[] = {
|
static syscall_handler_func_t handler_table[] = {
|
||||||
[SYS_QUIT] = &sys_quit,
|
[SYS_QUIT] = &sys_quit,
|
||||||
[SYS_TEST] = &sys_test,
|
[SYS_TEST] = &sys_test,
|
||||||
@@ -1136,6 +1188,8 @@ static syscall_handler_func_t handler_table[] = {
|
|||||||
[SYS_STREAM_READ] = &sys_stream_read,
|
[SYS_STREAM_READ] = &sys_stream_read,
|
||||||
[SYS_GET_PROC_INFO] = &sys_get_proc_info,
|
[SYS_GET_PROC_INFO] = &sys_get_proc_info,
|
||||||
[SYS_GET_DEVICE_INFO] = &sys_get_device_info,
|
[SYS_GET_DEVICE_INFO] = &sys_get_device_info,
|
||||||
|
[SYS_GET_VOLUME_INFO] = &sys_get_volume_info,
|
||||||
|
[SYS_VOLUME_DELETE] = &sys_volume_delete,
|
||||||
};
|
};
|
||||||
|
|
||||||
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
||||||
|
|||||||
@@ -118,3 +118,9 @@ int get_proc_info (struct proc_info* infos, size_t count) {
|
|||||||
int get_device_info (struct device_info* infos, size_t count) {
|
int get_device_info (struct device_info* infos, size_t count) {
|
||||||
return (int)do_syscall (SYS_GET_DEVICE_INFO, infos, count);
|
return (int)do_syscall (SYS_GET_DEVICE_INFO, infos, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_volume_info (struct volume_info* infos, size_t count) {
|
||||||
|
return (int)do_syscall (SYS_GET_VOLUME_INFO, infos, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int volume_delete (const char* key) { return (int)do_syscall (SYS_VOLUME_DELETE, key); }
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <proc_info.h>
|
#include <proc_info.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <volume_info.h>
|
||||||
|
|
||||||
/* Quit the current running process */
|
/* Quit the current running process */
|
||||||
int quit (void);
|
int quit (void);
|
||||||
@@ -122,4 +123,10 @@ int get_proc_info (struct proc_info* infos, size_t count);
|
|||||||
/* get device information */
|
/* get device information */
|
||||||
int get_device_info (struct device_info* infos, size_t count);
|
int get_device_info (struct device_info* infos, size_t count);
|
||||||
|
|
||||||
|
/* get volume information */
|
||||||
|
int get_volume_info (struct volume_info* infos, size_t count);
|
||||||
|
|
||||||
|
/* delete a volume */
|
||||||
|
int volume_delete (const char* key);
|
||||||
|
|
||||||
#endif // _LIBMSL_M_SYSTEM_H
|
#endif // _LIBMSL_M_SYSTEM_H
|
||||||
|
|||||||
81
usb/usb.c
81
usb/usb.c
@@ -5,14 +5,68 @@
|
|||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <process_self.h>
|
#include <process_self.h>
|
||||||
#include <status.h>
|
#include <status.h>
|
||||||
|
#include <str_status.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
#include <volume_info.h>
|
||||||
|
|
||||||
|
static void usb_poll (void) {
|
||||||
|
struct device_info* infos = malloc (sizeof (struct device_info) * 1024);
|
||||||
|
memset (infos, 0, sizeof (struct device_info) * 1024);
|
||||||
|
|
||||||
|
int device_count = get_device_info (infos, 1024);
|
||||||
|
struct device_info info;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (int dev = 0; dev < device_count; dev++) {
|
||||||
|
info = infos[dev];
|
||||||
|
|
||||||
|
if (info.type == DEVICE_TYPE_USB_CTRL) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
mprintf ("Polling device %s\n", info.key);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
device_do (info.key, XUSBCTRL_POLL_DRIVER, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
for (volatile int i = 0; i < 500; i++)
|
||||||
|
sched ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free (infos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usb_eject (const char* dev_key) {
|
||||||
|
struct volume_info* volume_infos = malloc (sizeof (*volume_infos) * 100);
|
||||||
|
memset (volume_infos, 0, sizeof (*volume_infos) * 100);
|
||||||
|
|
||||||
|
size_t count = get_volume_info (volume_infos, 100);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
struct volume_info* info = &volume_infos[i];
|
||||||
|
|
||||||
|
if (strcmp (info->device_key, dev_key) == 0) {
|
||||||
|
int ret = volume_delete (info->volume_name);
|
||||||
|
mprintf ("Deleted volume %s: %s", info->volume_name, str_status[ret < 0 ? -ret : ret]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free (volume_infos);
|
||||||
|
}
|
||||||
|
|
||||||
void app_main (void) {
|
void app_main (void) {
|
||||||
libprocess_self_init ();
|
libprocess_self_init ();
|
||||||
|
|
||||||
char commandbuf[32];
|
char commandbuf[32];
|
||||||
memset (commandbuf, 0, sizeof (commandbuf));
|
memset (commandbuf, 0, sizeof (commandbuf));
|
||||||
|
char devnamebuf[32];
|
||||||
|
memset (devnamebuf, 0, sizeof (devnamebuf));
|
||||||
|
|
||||||
if (env_get (process_get_pgid (), "C", (void*)commandbuf, sizeof (commandbuf)) != ST_OK) {
|
if (env_get (process_get_pgid (), "C", (void*)commandbuf, sizeof (commandbuf)) != ST_OK) {
|
||||||
mprintf ("ERROR C=???. No command provided\n");
|
mprintf ("ERROR C=???. No command provided\n");
|
||||||
@@ -20,29 +74,14 @@ void app_main (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp (commandbuf, "poll") == 0) {
|
if (strcmp (commandbuf, "poll") == 0) {
|
||||||
struct device_info* infos = malloc (sizeof (struct device_info) * 1024);
|
usb_poll ();
|
||||||
memset (infos, 0, sizeof (struct device_info) * 1024);
|
} else if (strcmp (commandbuf, "eject") == 0) {
|
||||||
|
if (env_get (process_get_pgid (), "dev", (void*)devnamebuf, sizeof (devnamebuf)) != ST_OK) {
|
||||||
int device_count = get_device_info (infos, 1024);
|
mprintf ("ERROR No device provided\n");
|
||||||
|
return;
|
||||||
for (int dev = 0; dev < device_count; dev++) {
|
|
||||||
struct device_info* info = &infos[dev];
|
|
||||||
|
|
||||||
if (info->type != DEVICE_TYPE_USB_CTRL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
mprintf ("Polling device %s\n", info->key);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
device_do (info->key, XUSBCTRL_POLL_DRIVER, NULL, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
for (volatile int i = 0; i < 500; i++)
|
|
||||||
sched ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (infos);
|
usb_eject (devnamebuf);
|
||||||
} else {
|
} else {
|
||||||
mprintf ("ERROR unknown command %s\n", commandbuf);
|
mprintf ("ERROR unknown command %s\n", commandbuf);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user