Subversion Repositories HelenOS

Rev

Rev 3253 | Rev 3272 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3253 Rev 3257
Line 37... Line 37...
37
 
37
 
38
#include "fat.h"
38
#include "fat.h"
39
#include "../../vfs/vfs.h"
39
#include "../../vfs/vfs.h"
40
#include <libfs.h>
40
#include <libfs.h>
41
#include <ipc/ipc.h>
41
#include <ipc/ipc.h>
-
 
42
#include <ipc/services.h>
-
 
43
#include <ipc/devmap.h>
42
#include <async.h>
44
#include <async.h>
43
#include <errno.h>
45
#include <errno.h>
44
#include <string.h>
46
#include <string.h>
45
#include <byteorder.h>
47
#include <byteorder.h>
46
#include <libadt/hash_table.h>
48
#include <libadt/hash_table.h>
47
#include <libadt/list.h>
49
#include <libadt/list.h>
48
#include <assert.h>
50
#include <assert.h>
49
#include <futex.h>
51
#include <futex.h>
-
 
52
#include <sys/mman.h>
50
 
53
 
51
#define BS_BLOCK        0
54
#define BS_BLOCK        0
52
#define BS_SIZE         512
55
#define BS_SIZE         512
53
 
56
 
54
/** Futex protecting the list of cached free FAT nodes. */
57
/** Futex protecting the list of cached free FAT nodes. */
Line 93... Line 96...
93
        else
96
        else
94
            *buf++ = d->ext[i];
97
            *buf++ = d->ext[i];
95
    }
98
    }
96
}
99
}
97
 
100
 
-
 
101
static int dev_phone = -1;      /* FIXME */
-
 
102
static void *dev_buffer = NULL;     /* FIXME */
-
 
103
 
98
/* TODO move somewhere else */
104
/* TODO move somewhere else */
99
typedef struct {
105
typedef struct {
100
    void *data;
106
    void *data;
-
 
107
    size_t size;
101
} block_t;
108
} block_t;
102
 
109
 
103
static block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
110
static block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
104
{
111
{
-
 
112
    /* FIXME */
-
 
113
    block_t *b;
-
 
114
    off_t bufpos = 0;
-
 
115
    size_t buflen = 0;
-
 
116
 
-
 
117
    assert(dev_phone != -1);
-
 
118
    assert(dev_buffer);
-
 
119
 
-
 
120
    b = malloc(sizeof(block_t));
-
 
121
    if (!b)
105
    return NULL;    /* TODO */
122
        return NULL;
-
 
123
   
-
 
124
    b->data = malloc(bs);
-
 
125
    if (!b->data) {
-
 
126
        free(b);
-
 
127
        return NULL;
-
 
128
    }
-
 
129
    b->size = bs;
-
 
130
 
-
 
131
    if (!libfs_blockread(dev_phone, dev_buffer, &bufpos, &buflen, &offset,
-
 
132
        b->data, bs, bs)) {
-
 
133
        free(b->data);
-
 
134
        free(b);
-
 
135
        return NULL;
-
 
136
    }
-
 
137
 
-
 
138
    return b;
106
}
139
}
107
 
140
 
108
static void block_put(block_t *block)
141
static void block_put(block_t *block)
109
{
142
{
110
    /* TODO */
143
    /* FIXME */
-
 
144
    free(block->data);
-
 
145
    free(block);
111
}
146
}
112
 
147
 
113
#define FAT_BS(b)       ((fat_bs_t *)((b)->data))
148
#define FAT_BS(b)       ((fat_bs_t *)((b)->data))
114
 
149
 
115
#define FAT_CLST_RES0   0x0000
150
#define FAT_CLST_RES0   0x0000
Line 566... Line 601...
566
 
601
 
567
void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
602
void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
568
{
603
{
569
    dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
604
    dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
570
    block_t *bb;
605
    block_t *bb;
-
 
606
    uint16_t bps;
571
    uint16_t rde;
607
    uint16_t rde;
572
    int rc;
608
    int rc;
573
 
609
 
-
 
610
    /*
-
 
611
     * For now, we don't bother to remember dev_handle, dev_phone or
-
 
612
     * dev_buffer in some data structure. We use global variables because we
-
 
613
     * know there will be at most one mount on this file system.
-
 
614
     * Of course, this is a huge TODO item.
-
 
615
     */
-
 
616
    dev_buffer = mmap(NULL, BS_SIZE, PROTO_READ | PROTO_WRITE,
-
 
617
        MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
-
 
618
   
-
 
619
    if (!dev_buffer) {
-
 
620
        ipc_answer_0(rid, ENOMEM);
-
 
621
        return;
-
 
622
    }
-
 
623
 
-
 
624
    dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
-
 
625
        DEVMAP_CONNECT_TO_DEVICE, dev_handle);
-
 
626
 
-
 
627
    if (dev_phone < 0) {
-
 
628
        munmap(dev_buffer, BS_SIZE);
-
 
629
        ipc_answer_0(rid, dev_phone);
-
 
630
        return;
-
 
631
    }
-
 
632
 
-
 
633
    rc = ipc_share_out_start(dev_phone, dev_buffer,
-
 
634
        AS_AREA_READ | AS_AREA_WRITE);
-
 
635
    if (rc != EOK) {
-
 
636
            munmap(dev_buffer, BS_SIZE);
-
 
637
        ipc_answer_0(rid, rc);
-
 
638
        return;
-
 
639
    }
-
 
640
 
574
    /* Read the number of root directory entries. */
641
    /* Read the number of root directory entries. */
575
    bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
642
    bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
-
 
643
    bps = uint16_t_le2host(FAT_BS(bb)->bps);
576
    rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
644
    rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
577
    block_put(bb);
645
    block_put(bb);
578
 
646
 
-
 
647
    if (bps != BS_SIZE) {
-
 
648
        munmap(dev_buffer, BS_SIZE);
-
 
649
        ipc_answer_0(rid, ENOTSUP);
-
 
650
        return;
-
 
651
    }
-
 
652
 
579
    rc = fat_idx_init_by_dev_handle(dev_handle);
653
    rc = fat_idx_init_by_dev_handle(dev_handle);
580
    if (rc != EOK) {
654
    if (rc != EOK) {
-
 
655
            munmap(dev_buffer, BS_SIZE);
581
        ipc_answer_0(rid, rc);
656
        ipc_answer_0(rid, rc);
582
        return;
657
        return;
583
    }
658
    }
584
 
659
 
585
    /* Initialize the root node. */
660
    /* Initialize the root node. */
586
    fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
661
    fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
587
    if (!rootp) {
662
    if (!rootp) {
-
 
663
            munmap(dev_buffer, BS_SIZE);
588
        fat_idx_fini_by_dev_handle(dev_handle);
664
        fat_idx_fini_by_dev_handle(dev_handle);
589
        ipc_answer_0(rid, ENOMEM);
665
        ipc_answer_0(rid, ENOMEM);
590
        return;
666
        return;
591
    }
667
    }
592
    fat_node_initialize(rootp);
668
    fat_node_initialize(rootp);
593
 
669
 
594
    fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0);
670
    fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0);
595
    if (!ridxp) {
671
    if (!ridxp) {
-
 
672
            munmap(dev_buffer, BS_SIZE);
596
        free(rootp);
673
        free(rootp);
597
        fat_idx_fini_by_dev_handle(dev_handle);
674
        fat_idx_fini_by_dev_handle(dev_handle);
598
        ipc_answer_0(rid, ENOMEM);
675
        ipc_answer_0(rid, ENOMEM);
599
        return;
676
        return;
600
    }
677
    }