OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [services/] [dos.c] - Blame information for rev 406

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marcus.erl
/*
2
    dos.c -- provides simple access to FAT (dos) partitions
3
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
4
 
5
    This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program; if not, write to the Free Software
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22
//#include "common.h"
23
 
24
#include <stddef.h>
25
#include <string.h>
26
#include "dos.h"
27
#include "ata.h"
28
 
29
/*
30
  D O S _ O P E N
31
*/
32
int dos_open(struct dosparam *params)
33
{
34 406 julius
        int error, start_sector, partition;
35
        unsigned char buf[512];
36 2 marcus.erl
 
37 406 julius
        struct inode *inode = &params->inode;
38
        struct file *filp = &params->filp;
39
        struct request *request = &params->request;
40 2 marcus.erl
 
41 406 julius
        if ((error = ata_open(inode, filp)))
42
                return error;
43 2 marcus.erl
 
44 406 julius
        /* device opened, read MBR                                          */
45
        request->cmd = READ;
46
        request->sector = 0;
47
        request->nr_sectors = 1;
48
        request->buffer = buf;
49 2 marcus.erl
 
50 406 julius
        /* skip bootload (446) bytes                                        */
51
        /* currently only support the first partition (partition 4)         */
52
        /* This is OK, because CompactFLASH devices only have 1 partition   */
53
        if ((error = ata_request(inode, filp, request)))
54
                return error;
55 2 marcus.erl
 
56 406 julius
        partition = 0;           /* first partition                                */
57
        partition *= 16;        /* 16 bytes per partition table                   */
58
        partition += 446;       /* skip bootloader, go to partition table         */
59
        start_sector = buf[partition + 11] << 24 |
60
            buf[partition + 10] << 16 |
61
            buf[partition + 9] << 8 | buf[partition + 8];
62 2 marcus.erl
 
63 406 julius
        /* device opened, read boot-sector                                  */
64
        request->cmd = READ;
65
        request->sector = start_sector;
66
        request->nr_sectors = 1;
67
        request->buffer = buf;
68 2 marcus.erl
 
69 406 julius
        if ((error = ata_request(inode, filp, request)))
70
                return error;
71 2 marcus.erl
 
72 406 julius
        /* get the necessary data from the boot-sector                      */
73
        params->bytes_per_sector = (buf[12] << 8) | buf[11];
74
        params->fats = buf[16];
75
        params->sectors_per_fat = (buf[23] << 8) | buf[22];
76
        params->root_entries = (buf[18] << 8) | buf[17];
77
        params->sectors_per_cluster = buf[13];
78 2 marcus.erl
 
79 406 julius
        /* set start of current directory to start of root-directory        */
80
        params->ssector =
81
            start_sector + params->fats * params->sectors_per_fat + 1;
82 2 marcus.erl
 
83 406 julius
        /* set current sector to start of root-directory                    */
84
        params->csector = params->ssector;
85 2 marcus.erl
 
86 406 julius
        /* set start-entry number                                           */
87
        params->sentry = 0;
88 2 marcus.erl
 
89 406 julius
        return 0;
90 2 marcus.erl
}
91
 
92
/*
93
  D O S _ R E L E A S E
94
*/
95
int dos_release(struct dosparam *params)
96
{
97 406 julius
        return 0;
98 2 marcus.erl
}
99
 
100
/*
101
  D O S _ N A M E C M P
102
*/
103
int dos_namecmp(const char *sname, const char *name, const char *ext)
104
{
105 406 julius
        char fname[9], fext[4], *p;
106 2 marcus.erl
 
107 406 julius
        /* filename :                                                       */
108
        /* copy the filename                                                */
109
        strncpy(fname, sname, 8);
110 2 marcus.erl
 
111 406 julius
        /* check if we copied the '.' already, if so terminate string       */
112
        if ((p = strchr(fname, '.')))
113
                *p = '\0';
114 2 marcus.erl
 
115 406 julius
        /* fill remaining chars with ' '                                    */
116
        strncat(fname, "        ", 8 - strlen(fname));
117 2 marcus.erl
 
118 406 julius
        fname[9] = '\0';
119 2 marcus.erl
 
120 406 julius
        /* file-extension                                                   */
121
        /* search for the '.' in the filename                               */
122
        if ((p = strchr(sname, '.')))
123
                strncpy(fext, p, 3);
124
        else
125
                fext[0] = fext[1] = fext[2] = ' ';
126 2 marcus.erl
 
127 406 julius
        fext[4] = '\0';
128 2 marcus.erl
 
129 406 julius
        return (strcmp(fname, name) && strcmp(fext, ext));
130 2 marcus.erl
}
131
 
132
/*
133
  D O S _ D I R _ F I N D _ E N T R Y
134
*/
135 406 julius
struct dos_dir_entry *dos_dir_find_entry(struct dosparam *params,
136
                                         const char *name)
137 2 marcus.erl
{
138 406 julius
        struct dos_dir_entry *entry;
139
        unsigned long entry_no = 0;
140 2 marcus.erl
 
141 406 julius
        /* go to start of current directory                                 */
142
        if (params->csector != params->ssector)
143
                dos_dir_cluster_reset(params);
144 2 marcus.erl
 
145 406 julius
        /* search for the requested entry                                   */
146
        while ((entry = dos_dir_get_entry(params, entry_no))
147
               && dos_namecmp(name, entry->name, entry->ext))
148
                entry_no++;
149 2 marcus.erl
 
150 406 julius
        return entry;
151 2 marcus.erl
}
152
 
153
/*
154
  D O S _ D I R _ G E T _ E N T R Y
155
*/
156 406 julius
struct dos_dir_entry *dos_dir_get_entry(struct dosparam *params,
157
                                        unsigned long entry)
158 2 marcus.erl
{
159 406 julius
        char *buf = params->cbuf;
160 2 marcus.erl
 
161 406 julius
        if (entry < params->sentry)
162
                buf = dos_dir_cluster_reset(params);
163 2 marcus.erl
 
164 406 julius
        while (entry >= (params->sentry + entries_per_cluster(params)))
165
                if (!(buf = dos_dir_cluster_read_nxt(params)))
166
                        return NULL;
167 2 marcus.erl
 
168 406 julius
        return (struct dos_dir_entry *)(buf +
169
                                        ((entry -
170
                                          params->sentry) *
171
                                         sizeof(struct dos_dir_entry)));
172 2 marcus.erl
}
173
 
174
/*
175
  D O S _ R E A D _ C L U S T E R
176
*/
177
char *dos_read_cluster(struct dosparam *params, unsigned long ssector)
178
{
179 406 julius
        int error;
180 2 marcus.erl
 
181 406 julius
        struct inode *inode = &params->inode;
182
        struct file *filp = &params->filp;
183
        struct request *request = &params->request;
184 2 marcus.erl
 
185 406 julius
        request->cmd = READ;
186
        request->sector = ssector;
187
        request->nr_sectors = params->sectors_per_cluster;
188
        request->buffer = params->cbuf;
189 2 marcus.erl
 
190 406 julius
        if ((error = ata_request(inode, filp, request)))
191
                return NULL;
192 2 marcus.erl
 
193 406 julius
        params->csector = ssector;
194 2 marcus.erl
 
195 406 julius
        return params->cbuf;
196 2 marcus.erl
}
197
 
198
/*
199
  D O S _ D I R _ C L U S T E R _ R E A D _ N X T
200
*/
201
char *dos_dir_cluster_read_nxt(struct dosparam *params)
202
{
203 406 julius
        char *p;
204
        unsigned long nxt_cluster_start;
205 2 marcus.erl
 
206 406 julius
        /* TODO: add FAT lookup */
207 2 marcus.erl
 
208 406 julius
        nxt_cluster_start = params->csector + params->sectors_per_cluster;
209 2 marcus.erl
 
210 406 julius
        if (!(p = dos_read_cluster(params, nxt_cluster_start)))
211
                return NULL;
212 2 marcus.erl
 
213 406 julius
        params->sentry += entries_per_cluster(params);
214 2 marcus.erl
 
215 406 julius
        return p;
216 2 marcus.erl
}
217
 
218
/*
219
  D O S _ D I R _ C L U S T E R _ R E S E T
220
*/
221
char *dos_dir_cluster_reset(struct dosparam *params)
222
{
223 406 julius
        params->sentry = 0;
224
        return dos_read_cluster(params, params->ssector);
225 2 marcus.erl
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.