2
libparted - a library for manipulating disk partitions
3
Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
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 3 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, see <http://www.gnu.org/licenses/>.
21
#include <parted/parted.h>
22
#include <parted/debug.h>
33
#include <drivers/Drivers.h>
36
#if B_ZETA_VERSION >= B_ZETA_VERSION_1_0_0
37
# include <device/ata_info.h>
42
# define _(String) dgettext (PACKAGE, String)
44
# define _(String) (String)
45
#endif /* ENABLE_NLS */
47
#include "../architecture.h"
49
#define BEOS_SPECIFIC(dev) ((BEOSSpecific*) (dev)->arch_specific)
51
typedef struct _BEOSSpecific BEOSSpecific;
53
struct _BEOSSpecific {
58
_scan_for_disks(const char* path)
60
char subdir[PATH_MAX];
65
if ((dirp=opendir(path)) != NULL)
67
/* Build first part of path */
72
/* Check all directory entries.. */
73
while((entp=readdir(dirp)) != NULL)
75
/* If they start with '.' just skip */
76
if (entp->d_name[0] == '.')
79
strcpy(subdir+pos, entp->d_name);
81
/* /dev/disk/.../raw are the complete disks
82
we're interested in */
83
if (strcmp(entp->d_name, "raw") == 0)
84
_ped_device_probe(subdir);
85
else /* If not 'raw', it most often will
87
_scan_for_disks(subdir);
95
_flush_cache(PedDevice* dev)
98
if ((fd=open(dev->path, O_RDONLY)) < 0)
100
ioctl(fd, B_FLUSH_DRIVE_CACHE);
105
#if B_ZETA_VERSION >= B_ZETA_VERSION_1_0_0
107
_device_init_ata(PedDevice* dev)
109
ata_device_infoblock ide_info;
110
int maxlen, len, idx, fd;
113
/* Try and get information about device from ATA(PI) driver */
114
if ((fd=open(dev->path, O_RDONLY)) < 0)
117
if (ioctl(fd, B_ATA_GET_DEVICE_INFO, &ide_info, sizeof(ide_info)) < 0)
118
goto ata_error_close;
122
/* Copy 'logical' dimensions */
123
dev->bios_geom.cylinders = ide_info.cylinders;
124
dev->bios_geom.heads = ide_info.heads;
125
dev->bios_geom.sectors = ide_info.sectors;
127
/* Copy used dimensions */
128
dev->hw_geom.cylinders = ide_info.current_cylinders;
129
dev->hw_geom.heads = ide_info.current_heads;
130
dev->hw_geom.sectors = ide_info.current_sectors;
132
/* Copy total number of sectors */
133
if (ide_info._48_bit_addresses_supported)
134
dev->length = ide_info.LBA48_total_sectors;
135
else if (ide_info.LBA_supported)
136
dev->length = ide_info.LBA_total_sectors;
138
dev->length = ide_info.cylinders *
143
dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
145
/* Use sensible model */
146
maxlen=sizeof(ide_info.model_number);
147
strncpy(buf, ide_info.model_number, maxlen);
150
for (len=-1, idx=maxlen-1; idx > 0 && len < 0; idx--)
154
buf[(len == -1) ? 0 : len+1] = '\0';
156
dev->model = strdup(buf);
158
return PED_DEVICE_IDE;
169
_device_init_generic_blkdev(PedDevice* dev)
171
device_geometry bios, os;
172
int got_bios_info = 0;
175
/* Try and get information about device from ATA(PI) driver */
176
if ((fd=open(dev->path, O_RDONLY)) < 0)
179
/* B_GET_GEOMETRY is mandatory */
180
if (ioctl(fd, B_GET_GEOMETRY, &os, sizeof(os)) < 0)
181
goto blkdev_error_close;
183
/* B_GET_BIOS_GEOMETRY is optional */
184
if (!ioctl(fd, B_GET_BIOS_GEOMETRY, &bios, sizeof(bios)))
189
dev->hw_geom.cylinders = os.cylinder_count;
190
dev->hw_geom.heads = os.head_count;
191
dev->hw_geom.sectors = os.sectors_per_track;
194
dev->phys_sector_size = os.bytes_per_sector;
198
dev->bios_geom.cylinders = bios.cylinder_count;
199
dev->bios_geom.heads = bios.head_count;
200
dev->bios_geom.sectors = bios.sectors_per_track;
203
dev->bios_geom = dev->hw_geom;
205
dev->model = strdup("");
207
return PED_DEVICE_IDE;
217
_device_init_blkdev(PedDevice* dev)
221
#if B_ZETA_VERSION >= B_ZETA_VERSION_1_0_0
222
if (!(type=_device_init_ata(dev)))
224
type = _device_init_generic_blkdev(dev);
230
_device_init_file(PedDevice* dev, struct stat* dev_statp)
232
if (!dev_statp->st_size)
236
dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
238
dev->length = dev_statp->st_size / PED_SECTOR_SIZE_DEFAULT;
240
dev->bios_geom.cylinders = dev->length / (4 * 32);
241
dev->bios_geom.heads = 4;
242
dev->bios_geom.sectors = 32;
243
dev->hw_geom = dev->bios_geom;
245
dev->model = strdup(_("Disk Image"));
247
return PED_DEVICE_FILE;
251
_device_init(PedDevice* dev)
253
struct stat dev_stat;
256
/* Check if we're a regular file */
257
if (stat(dev->path, &dev_stat) < 0)
260
if (S_ISBLK(dev_stat.st_mode) || S_ISCHR(dev_stat.st_mode))
261
type = _device_init_blkdev(dev);
262
else if (S_ISREG(dev_stat.st_mode))
263
type = _device_init_file(dev,&dev_stat);
271
beos_new (const char* path)
273
struct stat stat_info;
276
PED_ASSERT(path != NULL);
278
dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
282
dev->path = strdup(path);
287
= (BEOSSpecific*) ped_malloc(sizeof(BEOSSpecific));
288
if (dev->arch_specific == NULL)
289
goto error_free_path;
293
dev->external_mode = 0;
297
if ((dev->type=_device_init(dev)) <= 0)
298
goto error_free_arch_specific;
303
error_free_arch_specific:
304
free (dev->arch_specific);
317
beos_destroy (PedDevice* dev)
319
free (dev->arch_specific);
326
beos_is_busy (PedDevice* dev)
332
beos_open (PedDevice* dev)
334
BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
337
arch_specific->fd = open(dev->path, O_RDWR);
338
if (arch_specific->fd == -1) {
339
char* rw_error_msg = strerror(errno);
341
arch_specific->fd = open (dev->path, O_RDONLY);
342
if (arch_specific->fd == -1) {
343
if (ped_exception_throw (
345
PED_EXCEPTION_RETRY_CANCEL,
346
_("Error opening %s: %s"),
347
dev->path, strerror (errno))
348
!= PED_EXCEPTION_RETRY) {
354
ped_exception_throw (
355
PED_EXCEPTION_WARNING,
357
_("Unable to open %s read-write (%s). %s has "
358
"been opened read-only."),
359
dev->path, rw_error_msg, dev->path);
372
beos_refresh_open (PedDevice* dev)
378
beos_close (PedDevice* dev)
380
BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
385
close (arch_specific->fd);
391
beos_refresh_close (PedDevice* dev)
400
beos_read (const PedDevice* dev, void* buffer, PedSector start, PedSector count)
402
BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
404
PedExceptionOption ex_status;
405
size_t read_length = count * dev->sector_size;
407
PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
409
/* First, try to seek */
412
if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET)
413
== start * dev->sector_size)
416
ex_status = ped_exception_throw (
418
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
419
_("%s during seek for read on %s"),
420
strerror (errno), dev->path);
424
case PED_EXCEPTION_IGNORE:
426
case PED_EXCEPTION_RETRY:
427
break /* out of switch */;
428
case PED_EXCEPTION_UNHANDLED:
429
ped_exception_catch ();
430
case PED_EXCEPTION_CANCEL:
435
/* If we seeked ok, now is the time to read */
438
status = read(arch_specific->fd, buffer, read_length);
439
if (status == count * dev->sector_size)
444
read_length -= status;
449
ex_status = ped_exception_throw (
451
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
452
_("%s during read on %s"),
458
case PED_EXCEPTION_IGNORE:
460
case PED_EXCEPTION_RETRY:
462
case PED_EXCEPTION_UNHANDLED:
463
ped_exception_catch ();
464
case PED_EXCEPTION_CANCEL:
473
beos_write (PedDevice* dev, const void* buffer, PedSector start,
476
BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
478
PedExceptionOption ex_status;
479
size_t write_length = count * dev->sector_size;
481
PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
485
if (ped_exception_throw (
487
PED_EXCEPTION_IGNORE_CANCEL,
488
_("Can't write to %s, because it is opened read-only."),
490
!= PED_EXCEPTION_IGNORE)
498
if (lseek(arch_specific->fd,start * dev->sector_size,SEEK_SET)
499
== start * dev->sector_size)
502
ex_status = ped_exception_throw (
503
PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
504
_("%s during seek for write on %s"),
505
strerror (errno), dev->path);
509
case PED_EXCEPTION_IGNORE:
511
case PED_EXCEPTION_RETRY:
513
case PED_EXCEPTION_UNHANDLED:
514
ped_exception_catch ();
515
case PED_EXCEPTION_CANCEL:
521
printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
522
dev->path, buffer, (int) start, (int) count);
527
status = write (arch_specific->fd, buffer, write_length);
528
if (status == count * dev->sector_size)
533
write_length -= status;
538
ex_status = ped_exception_throw (
540
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
541
_("%s during write on %s"),
542
strerror (errno), dev->path);
546
case PED_EXCEPTION_IGNORE:
548
case PED_EXCEPTION_RETRY:
550
case PED_EXCEPTION_UNHANDLED:
551
ped_exception_catch ();
552
case PED_EXCEPTION_CANCEL:
556
#endif /* !READ_ONLY */
562
beos_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
564
BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev);
568
PED_ASSERT(dev != NULL);
570
if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET)
571
!= start * dev->sector_size)
574
for (done = 0; done < count; done += status / dev->sector_size)
576
status = read (arch_specific->fd, buffer,
577
(size_t) ((count-done) * dev->sector_size));
586
beos_sync (PedDevice* dev)
592
beos_sync_fast (PedDevice* dev)
597
/* Probe for all available disks */
601
/* For BeOS/ZETA/Haiku, all disks are published under /dev/disk */
602
_scan_for_disks("/dev/disk");
606
beos_partition_get_path (const PedPartition* part)
612
beos_partition_is_busy (const PedPartition* part)
618
beos_disk_commit (PedDisk* disk)
623
static PedDeviceArchOps beos_dev_ops = {
625
destroy: beos_destroy,
626
is_busy: beos_is_busy,
628
refresh_open: beos_refresh_open,
630
refresh_close: beos_refresh_close,
635
sync_fast: beos_sync_fast,
636
probe_all: beos_probe_all
639
static PedDiskArchOps beos_disk_ops = {
640
partition_get_path: beos_partition_get_path,
641
partition_is_busy: beos_partition_is_busy,
642
disk_commit: beos_disk_commit
645
PedArchitecture ped_beos_arch = {
646
dev_ops: &beos_dev_ops,
647
disk_ops: &beos_disk_ops