1 /* This file is part of the program psim.
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "device_table.h"
34 cdrom - readable block device
36 disk - readable block device that should be writeable
38 floppy - readable block device that should be writeable
42 Block I/O devices that model the behavour of a fixed or removable
45 Creating an instance of this device with no arguments will provide
46 access to primative read/write operators. If arguments are
47 specified then the disk-label package is used to perform abstract
48 disk I/O. The disk-label package will then use this devices
51 For hardware I/O, this device would normally be attached to a
52 parent `bus' and that bus would use the I/O methods to read and
53 write raw data. The bus might actually be a SCSI or IDE device.
54 It is assumed that the parent bus can take care of DMA.
58 reg = <address> (required)
60 <address> is parent bus dependant.
64 name = "disk" | "cdrom" | "fd"
66 file = <file-name> (required)
68 The name of the file that contains the disk image.
72 typedef struct _hw_disk_device
{
79 typedef struct _hw_disk_instance
{
86 hw_disk_init_address(device
*me
)
88 hw_disk_device
*disk
= device_data(me
);
89 generic_device_init_address(me
);
90 if (disk
->image
!= NULL
)
92 disk
->name
= device_find_string_property(me
, "file");
93 if (strcmp(device_name(me
), "disk") == 0) {
95 disk
->image
= fopen(disk
->name
, "r+");
99 disk
->image
= fopen(disk
->name
, "r");
101 if (disk
->image
== NULL
) {
102 perror(device_name(me
));
103 device_error(me
, "open %s failed\n", disk
->name
);
108 hw_disk_io_read_buffer(device
*me
,
116 hw_disk_device
*disk
= device_data(me
);
119 if (addr
+ nr_bytes
> disk
->size
)
121 if (fseek(disk
->image
, addr
, SEEK_SET
) < 0)
123 if (fread(dest
, nr_bytes
, 1, disk
->image
) != 1)
130 hw_disk_io_write_buffer(device
*me
,
138 hw_disk_device
*disk
= device_data(me
);
143 if (addr
+ nr_bytes
> disk
->size
)
145 if (fseek(disk
->image
, addr
, SEEK_SET
) < 0)
147 if (fwrite(source
, nr_bytes
, 1, disk
->image
) != 1)
153 /* instances of the hw_disk device */
156 hw_disk_instance_delete(device_instance
*instance
)
158 hw_disk_instance
*data
= device_instance_data(instance
);
163 hw_disk_instance_read(device_instance
*instance
,
167 hw_disk_instance
*data
= device_instance_data(instance
);
168 if (fseek(data
->disk
->image
, data
->pos
, SEEK_SET
) < 0)
170 if (fread(buf
, len
, 1, data
->disk
->image
) != 1)
172 data
->pos
= ftell(data
->disk
->image
);
177 hw_disk_instance_write(device_instance
*instance
,
181 hw_disk_instance
*data
= device_instance_data(instance
);
182 if (data
->disk
->read_only
)
184 if (fseek(data
->disk
->image
, data
->pos
, SEEK_SET
) < 0)
186 if (fwrite(buf
, len
, 1, data
->disk
->image
) != 1)
188 data
->pos
= ftell(data
->disk
->image
);
193 hw_disk_instance_seek(device_instance
*instance
,
194 unsigned_word pos_hi
,
195 unsigned_word pos_lo
)
197 hw_disk_instance
*data
= device_instance_data(instance
);
202 static const device_instance_callbacks hw_disk_instance_callbacks
= {
203 hw_disk_instance_delete
,
204 hw_disk_instance_read
,
205 hw_disk_instance_write
,
206 hw_disk_instance_seek
,
209 static device_instance
*
210 hw_disk_create_instance(device
*me
,
214 device_instance
*disk_instance
;
215 hw_disk_device
*disk
= device_data(me
);
216 hw_disk_instance
*data
= ZALLOC(hw_disk_instance
);
219 disk_instance
= device_create_instance_from(me
, NULL
,
222 &hw_disk_instance_callbacks
);
223 return pk_disklabel_create_instance(disk_instance
, args
);
226 static device_callbacks
const hw_disk_callbacks
= {
227 { hw_disk_init_address
, NULL
},
228 { NULL
, }, /* address */
229 { hw_disk_io_read_buffer
,
230 hw_disk_io_write_buffer
, },
232 { NULL
, }, /* interrupt */
233 { NULL
, }, /* unit */
234 hw_disk_create_instance
,
239 hw_disk_create(const char *name
,
240 const device_unit
*unit_address
,
244 /* create the descriptor */
245 hw_disk_device
*hw_disk
= ZALLOC(hw_disk_device
);
250 const device_descriptor hw_disk_device_descriptor
[] = {
251 { "disk", hw_disk_create
, &hw_disk_callbacks
},
255 #endif /* _HW_DISK_C_ */