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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [orpmon/] [services/] [dos.c] - Blame information for rev 1020

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 922 rherveille
/*
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
 
23
//#include "common.h"
24
 
25
#include <stddef.h>
26
#include <string.h>
27
#include "dos.h"
28
#include "ata.h"
29
 
30
 
31
/*
32
  D O S _ O P E N
33
*/
34
int dos_open(struct dosparam *params)
35
{
36 1020 rherveille
  int error, start_sector, partition;
37 922 rherveille
  unsigned char buf[512];
38
 
39
  struct inode *inode = &params->inode;
40
  struct file  *filp  = &params->filp;
41
  struct request *request = &params->request;
42
 
43
  if( (error = ata_open(inode, filp)) )
44
    return error;
45
 
46
 
47 1020 rherveille
  /* device opened, read MBR                                          */
48 922 rherveille
  request->cmd = READ;
49
  request->sector = 0;
50
  request->nr_sectors = 1;
51
  request->buffer = buf;
52
 
53 1020 rherveille
  /* skip bootload (446) bytes                                        */
54
  /* currently only support the first partition (partition 4)         */
55
  /* This is OK, because CompactFLASH devices only have 1 partition   */
56 922 rherveille
  if ( (error = ata_request(inode, filp, request)) )
57
    return error;
58
 
59 1020 rherveille
  partition = 0;    /* first partition                                */
60
  partition *= 16;  /* 16 bytes per partition table                   */
61
  partition += 446; /* skip bootloader, go to partition table         */
62
  start_sector = buf[partition +11] << 24 |
63
                 buf[partition +10] << 16 |
64
                 buf[partition +9] << 8   |
65
                 buf[partition +8];
66
 
67
  /* device opened, read boot-sector                                  */
68
  request->cmd = READ;
69
  request->sector = start_sector;
70
  request->nr_sectors = 1;
71
  request->buffer = buf;
72
 
73
  if ( (error = ata_request(inode, filp, request)) )
74
    return error;
75
 
76 922 rherveille
  /* get the necessary data from the boot-sector                      */
77
  params->bytes_per_sector = (buf[12]<<8) | buf[11];
78
  params->fats = buf[16];
79
  params->sectors_per_fat = (buf[23]<<8) | buf[22];
80
  params->root_entries = (buf[18]<<8) | buf[17];
81
  params->sectors_per_cluster = buf[13];
82
 
83
 
84
  /* set start of current directory to start of root-directory        */
85 1020 rherveille
  params->ssector = start_sector + params->fats * params->sectors_per_fat +1;
86 922 rherveille
 
87
  /* set current sector to start of root-directory                    */
88
  params->csector = params->ssector;
89 1020 rherveille
 
90 922 rherveille
  /* set start-entry number                                           */
91
  params->sentry = 0;
92
 
93
  return 0;
94
}
95
 
96
/*
97
  D O S _ R E L E A S E
98
*/
99
int dos_release(struct dosparam *params)
100
{
101
  return 0;
102
}
103
 
104
/*
105
  D O S _ N A M E C M P
106
*/
107
int dos_namecmp(const char *sname, const char *name, const char *ext)
108
{
109
  char fname[9], fext[4], *p;
110
 
111
  /* filename :                                                       */
112
  /* copy the filename                                                */
113
  strncpy(fname, sname, 8);
114
 
115
  /* check if we copied the '.' already, if so terminate string       */
116
  if ( (p = strchr(fname, '.')) )
117
    *p = '\0';
118
 
119
  /* fill remaining chars with ' '                                    */
120
  strncat(fname, "        ", 8-strlen(fname) );
121
 
122
  fname[9] = '\0';
123
 
124
  /* file-extension                                                   */
125
  /* search for the '.' in the filename                               */
126
  if ( (p = strchr(sname, '.')) )
127
    strncpy(fext, p, 3);
128
  else
129
    fext[0] = fext[1] = fext[2] = ' ';
130
 
131
  fext[4] = '\0';
132
 
133
  return ( strcmp(fname, name) && strcmp(fext, ext) );
134
}
135
 
136
 
137
/*
138
  D O S _ D I R _ F I N D _ E N T R Y
139
*/
140
struct dos_dir_entry *dos_dir_find_entry(struct dosparam *params, const char *name)
141
{
142
  struct dos_dir_entry *entry;
143
  unsigned long entry_no = 0;
144
 
145
  /* go to start of current directory                                 */
146
  if (params->csector != params->ssector)
147
    dos_dir_cluster_reset(params);
148
 
149
  /* search for the requested entry                                   */
150
  while ( (entry = dos_dir_get_entry(params, entry_no)) && dos_namecmp(name, entry->name, entry->ext) )
151
    entry_no++;
152
 
153
  return entry;
154
}
155
 
156
 
157
/*
158
  D O S _ D I R _ G E T _ E N T R Y
159
*/
160
struct dos_dir_entry *dos_dir_get_entry(struct dosparam *params, unsigned long entry)
161
{
162
  char *buf = params->cbuf;
163
 
164
  if (entry < params->sentry)
165
    buf = dos_dir_cluster_reset(params);
166
 
167
  while ( entry >= (params->sentry + entries_per_cluster(params)) )
168
      if ( !(buf = dos_dir_cluster_read_nxt(params)) )
169
        return NULL;
170
 
171
  return (struct dos_dir_entry*)(buf + ( (entry - params->sentry) * sizeof(struct dos_dir_entry)) );
172
}
173
 
174
 
175
/*
176
  D O S _ R E A D _ C L U S T E R
177
*/
178
char *dos_read_cluster(struct dosparam *params, unsigned long ssector)
179
{
180
  int error;
181
 
182
  struct inode *inode = &params->inode;
183
  struct file  *filp  = &params->filp;
184
  struct request *request = &params->request;
185
 
186
  request->cmd = READ;
187
  request->sector = ssector;
188
  request->nr_sectors = params->sectors_per_cluster;
189
  request->buffer = params->cbuf;
190
 
191
  if ( (error = ata_request(inode, filp, request)) )
192
    return NULL;
193
 
194
  params->csector = ssector;
195
 
196
  return params->cbuf;
197
}
198
 
199
 
200
/*
201
  D O S _ D I R _ C L U S T E R _ R E A D _ N X T
202
*/
203
char *dos_dir_cluster_read_nxt(struct dosparam *params)
204
{
205
  char *p;
206
  unsigned long nxt_cluster_start;
207
 
208
  /* TODO: add FAT lookup */
209
 
210
  nxt_cluster_start = params->csector + params->sectors_per_cluster;
211
 
212
  if ( !(p = dos_read_cluster(params, nxt_cluster_start)) )
213
    return NULL;
214
 
215
 
216
  params->sentry += entries_per_cluster(params);
217
 
218
  return p;
219
}
220
 
221
 
222
/*
223
  D O S _ D I R _ C L U S T E R _ R E S E T
224
*/
225
char *dos_dir_cluster_reset(struct dosparam *params)
226
{
227
  params->sentry = 0;
228
  return dos_read_cluster(params, params->ssector);
229
}
230
 
231
 

powered by: WebSVN 2.1.0

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