* [Linux-ia64] GPT patch for parted 1.4.7
@ 2001-03-06 18:01 Matt_Domsch
0 siblings, 0 replies; only message in thread
From: Matt_Domsch @ 2001-03-06 18:01 UTC (permalink / raw)
To: linux-ia64
[-- Attachment #1: Type: text/plain, Size: 1294 bytes --]
Attached is a patch against GNU Parted 1.4.7 which adds EFI GPT support.
This has not yet been submitted to the GNU Parted team officially, I'm
waiting on a kernel IOCTL patch to be included first. A lot of people are
interested in this, so I'm making it available for testing. I haven't
tested this against newer versions of parted, but expect it to drop in with
minimal effort.
Notes:
- This works for all disks with an even number of 512-byte sectors.
- This works for SCSI disks with an odd number of 512-byte sectors by using
SCSI Generic (sg) commands to read/write the last odd sector. Odd-sized IDE
disks won't work.
- Pending the inclusion of a kernel patch to allow reading/writing the last
sector of any disk via a block layer IOCTL, I'll re-write this patch to
remove the sg hacks and use that instead.
Assistance:
If anyone wants to help, particularly in adding Unicode support to parted,
I'd appreciate it. Please join the bug-parted mailing list.
To subscribe or unsubscribe via the World Wide Web, visit
http://mail.gnu.org/mailman/listinfo/bug-parted
or, via email, send a message with subject or body 'help' to
bug-parted-request@gnu.org
Your feedback is encouraged.
Thanks,
Matt
--
Matt Domsch
Dell Linux Systems Group
Linux OS Development
www.dell.com/linux
[-- Attachment #2: parted-1.4.7-gpt-010124.patch --]
[-- Type: application/octet-stream, Size: 163242 bytes --]
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/include/parted/Makefile.am parted-1.4.7-gpt/include/parted/Makefile.am
--- parted-1.4.7/include/parted/Makefile.am Mon Dec 4 13:12:47 2000
+++ parted-1.4.7-gpt/include/parted/Makefile.am Thu Jan 18 11:24:42 2001
@@ -6,6 +6,7 @@
exception.h \
filesys.h \
natmath.h \
+ crc32.h \
parted.h
noinst_HEADERS = disk_bsd.h \
@@ -13,5 +14,6 @@
disk_loop.h \
disk_mac.h \
disk_pc98.h \
+ disk_gpt.h \
endian.h
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/include/parted/crc32.h parted-1.4.7-gpt/include/parted/crc32.h
--- parted-1.4.7/include/parted/crc32.h Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/include/parted/crc32.h Thu Jan 18 11:24:42 2001
@@ -0,0 +1,34 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ crc32.h
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _CRC32_H
+#define _CRC32_H
+
+#include <linux/types.h>
+
+/*
+ * This computes a 32 bit CRC of the data in the buffer, and returns the CRC.
+ * The polynomial used is 0xedb88320.
+ */
+
+extern __u32 crc32 (const void *buf, unsigned long len, __u32 seed);
+
+#endif /* _CRC32_H */
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/include/parted/disk_gpt.h parted-1.4.7-gpt/include/parted/disk_gpt.h
--- parted-1.4.7/include/parted/disk_gpt.h Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/include/parted/disk_gpt.h Wed Jan 24 11:23:31 2001
@@ -0,0 +1,195 @@
+/*
+ libparted - a library for manipulating disk partitions
+
+ Copyright (C) 2000-2001 Dell Computer Corporation
+ disk_gpt.[ch] by Matt Domsch <Matt_Domsch@dell.com>
+
+ EFI GUID Partition Table handling
+ Per Intel EFI Specification v1.02
+ http://developer.intel.com/technology/efi/efi.htm
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef EFI_GPT_H
+#define EFI_GPT_H
+
+
+#include <linux/types.h>
+
+#define EFI_PMBR_OSTYPE_EFI 0xEF
+#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+#define MSDOS_MBR_SIGNATURE 0xaa55
+#define GUID_PT_BLOCK_SIZE 512
+
+
+#define GUID_PT_HEADER_SIGNATURE 0x5452415020494645
+#define GUID_PT_HEADER_REVISION_V1_02 0x00010200
+#define GUID_PT_HEADER_REVISION_V1_00 0x00010000
+#define GUID_PT_HEADER_REVISION_V0_99 0x00009900
+
+typedef __u16 efi_char16_t; /* UNICODE character */
+
+typedef struct {
+ __u32 data1;
+ __u16 data2;
+ __u16 data3;
+ __u8 data4[8];
+} __attribute__ ((packed)) efi_guid_t;
+
+
+#define UNUSED_ENTRY_GUID \
+ ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }})
+#define PARTITION_SYSTEM_GUID \
+ ((efi_guid_t) { 0xC12A7328, 0xF81F, 0x11d2, { 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B }})
+#define LEGACY_MBR_PARTITION_GUID \
+ ((efi_guid_t) { 0x024DEE41, 0x33E7, 0x11d3, { 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F }})
+#define PARTITION_MSFT_RESERVED_GUID \
+ ((efi_guid_t) { 0xE3C9E316, 0x0B5C, 0x4DB8, { 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE }})
+#define PARTITION_BASIC_DATA_GUID \
+ ((efi_guid_t) { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }})
+#define PARTITION_RAID_GUID \
+ ((efi_guid_t) { 0xa19d880f, 0x05fc, 0x4d3b, { 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }})
+#define PARTITION_SWAP_GUID \
+ ((efi_guid_t) { 0x0657fd6d, 0xa4ab, 0x43c4, { 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f }})
+#define PARTITION_LVM_GUID \
+ ((efi_guid_t) { 0xe6d6d379, 0xf507, 0x44c2, { 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28 }})
+#define PARTITION_RESERVED_GUID \
+ ((efi_guid_t) { 0x8da63339, 0x0007, 0x60c0, { 0xc4, 0x36, 0x08, 0x3a, 0xc8, 0x23, 0x09, 0x08 }})
+
+typedef struct _GuidPartitionTableHeader_t {
+ __u64 Signature;
+ __u32 Revision;
+ __u32 HeaderSize;
+ __u32 HeaderCRC32;
+ __u32 Reserved1;
+ __u64 MyLBA;
+ __u64 AlternateLBA;
+ __u64 FirstUsableLBA;
+ __u64 LastUsableLBA;
+ efi_guid_t DiskGUID;
+ __u64 PartitionEntryLBA;
+ __u32 NumberOfPartitionEntries;
+ __u32 SizeOfPartitionEntry;
+ __u32 PartitionEntryArrayCRC32;
+ __u8 Reserved2[GUID_PT_BLOCK_SIZE - 92];
+} __attribute__ ((packed)) GuidPartitionTableHeader_t;
+
+typedef struct _GuidPartitionEntryAttributes_t {
+ __u64 RequiredToFunction:1;
+ __u64 Reserved:47;
+ __u64 GuidSpecific:16;
+} __attribute__ ((packed)) GuidPartitionEntryAttributes_t;
+
+typedef struct _GuidPartitionEntry_t {
+ efi_guid_t PartitionTypeGuid;
+ efi_guid_t UniquePartitionGuid;
+ __u64 StartingLBA;
+ __u64 EndingLBA;
+ GuidPartitionEntryAttributes_t Attributes;
+ efi_char16_t PartitionName[72 / sizeof(efi_char16_t)];
+} __attribute__ ((packed)) GuidPartitionEntry_t;
+
+
+/*
+ These values are only defaults. The actual on-disk structures
+ may define different sizes, so use those unless creating a new GPT disk!
+*/
+
+#define GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE 16384
+/*
+ Number of actual partition entries should be calculated
+ as:
+*/
+#define GPT_DEFAULT_RESERVED_PARTITION_ENTRIES \
+ (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE / \
+ sizeof(GuidPartitionEntry_t))
+
+
+typedef struct _PartitionRecord_t {
+ __u8 BootIndicator; /* Not used by EFI firmware. Set to 0x80 to indicate that this
+ is the bootable legacy partition. */
+ __u8 StartHead; /* Start of partition in CHS address, not used by EFI firmware. */
+ __u8 StartSector; /* Start of partition in CHS address, not used by EFI firmware. */
+ __u8 StartTrack; /* Start of partition in CHS address, not used by EFI firmware. */
+ __u8 OSType; /* OS type. A value of 0xEF defines an EFI system partition.
+ Other values are reserved for legacy operating systems, and
+ allocated independently of the EFI specification. */
+ __u8 EndHead; /* End of partition in CHS address, not used by EFI firmware. */
+ __u8 EndSector; /* End of partition in CHS address, not used by EFI firmware. */
+ __u8 EndTrack; /* End of partition in CHS address, not used by EFI firmware. */
+ __u32 StartingLBA; /* Starting LBA address of the partition on the disk. Used by
+ EFI firmware to define the start of the partition. */
+ __u32 SizeInLBA; /* Size of partition in LBA. Used by EFI firmware to determine
+ the size of the partition. */
+} __attribute__ ((packed)) PartitionRecord_t;
+
+
+/* Protected Master Boot Record & Legacy MBR share same structure */
+/* Needs to be packed because the u16s force misalignment. */
+
+typedef struct _LegacyMBR_t {
+ __u8 BootCode[440];
+ __u32 UniqueMBRSignature;
+ __u16 Unknown;
+ PartitionRecord_t PartitionRecord[4];
+ __u16 Signature;
+} __attribute__ ((packed)) LegacyMBR_t;
+
+
+
+
+#define EFI_GPT_PRIMARY_PARTITION_TABLE_LBA 1
+
+
+/* Parted has a PedDisk field disk_specific that we'll keep
+ our own useful info in.
+*/
+typedef struct _GPTDiskData {
+ GuidPartitionTableHeader_t *pgpt;
+ GuidPartitionTableHeader_t *agpt;
+ GuidPartitionEntry_t *ptes;
+} GPTDiskData;
+
+/* Parted has a PedPartition field disk_specific that we'll keep
+ our own useful info in.
+*/
+typedef struct _GPTPartitionData {
+ GuidPartitionEntry_t * pte;
+} GPTPartitionData;
+
+
+#define GPT_NAME "GPT"
+
+#endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/Makefile.am parted-1.4.7-gpt/libparted/Makefile.am
--- parted-1.4.7/libparted/Makefile.am Mon Jan 8 13:57:26 2001
+++ parted-1.4.7-gpt/libparted/Makefile.am Thu Jan 18 11:24:42 2001
@@ -15,12 +15,23 @@
llseek.c \
llseek.h \
natmath.c \
+ crc32.c \
disk.c \
disk_bsd.c \
disk_dos.c \
disk_loop.c \
disk_mac.c \
- disk_pc98.c
+ disk_pc98.c \
+ disk_gpt.c \
+ device_scsi.c \
+ device_scsi.h \
+ sg_map.c \
+ sg_map.h \
+ sg_dd.c \
+ sg_dd.h \
+ sg_err.c \
+ sg_err.h
+
libparted_la_LIBADD = fs_ext2/libext2.la \
fs_fat/libfat.la \
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/crc32.c parted-1.4.7-gpt/libparted/crc32.c
--- parted-1.4.7/libparted/crc32.c Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/crc32.c Thu Jan 18 11:24:42 2001
@@ -0,0 +1,125 @@
+/*
+ * Dec 5, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * - Copied crc32.c from the linux/drivers/net/cipe directory.
+ * - Now pass seed as an arg
+ * - changed unsigned long to __u32, added #include<linux/types.h>
+ * - changed len to be an unsigned long
+ * - changed crc32val to be a register
+ * - License remains unchanged! It's still GPL-compatable!
+ */
+
+ /* ============================================================= */
+ /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
+ /* code or tables extracted from it, as desired without restriction. */
+ /* */
+ /* First, the polynomial itself and its table of feedback terms. The */
+ /* polynomial is */
+ /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+ /* */
+ /* Note that we take it "backwards" and put the highest-order term in */
+ /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+ /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+ /* the MSB being 1. */
+ /* */
+ /* Note that the usual hardware shift register implementation, which */
+ /* is what we're using (we're merely optimizing it by doing eight-bit */
+ /* chunks at a time) shifts bits into the lowest-order term. In our */
+ /* implementation, that means shifting towards the right. Why do we */
+ /* do it this way? Because the calculated CRC must be transmitted in */
+ /* order from highest-order term to lowest-order term. UARTs transmit */
+ /* characters in order from LSB to MSB. By storing the CRC this way, */
+ /* we hand it to the UART in the order low-byte to high-byte; the UART */
+ /* sends each low-bit to hight-bit; and the result is transmission bit */
+ /* by bit from highest- to lowest-order term without requiring any bit */
+ /* shuffling on our part. Reception works similarly. */
+ /* */
+ /* The feedback terms table consists of 256, 32-bit entries. Notes: */
+ /* */
+ /* The table can be generated at runtime if desired; code to do so */
+ /* is shown later. It might not be obvious, but the feedback */
+ /* terms simply represent the results of eight shift/xor opera- */
+ /* tions for all combinations of data and CRC register values. */
+ /* */
+ /* The values must be right-shifted by eight bits by the "updcrc" */
+ /* logic; the shift must be unsigned (bring in zeroes). On some */
+ /* hardware you could probably optimize the shift in assembler by */
+ /* using byte-swap instructions. */
+ /* polynomial $edb88320 */
+ /* */
+ /* -------------------------------------------------------------------- */
+
+#include<linux/types.h>
+
+static __u32 crc32_tab[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+ };
+
+/* Return a 32-bit CRC of the contents of the buffer. */
+
+__u32
+crc32(const void *buf, unsigned long len, __u32 seed)
+{
+ unsigned long i;
+ register __u32 crc32val;
+ const unsigned char *s = buf;
+
+ crc32val = seed;
+ for (i = 0; i < len; i ++)
+ {
+ crc32val =
+ crc32_tab[(crc32val ^ s[i]) & 0xff] ^
+ (crc32val >> 8);
+ }
+ return crc32val;
+}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/device.c parted-1.4.7-gpt/libparted/device.c
--- parted-1.4.7/libparted/device.c Tue Jan 9 12:28:22 2001
+++ parted-1.4.7-gpt/libparted/device.c Thu Jan 18 11:24:42 2001
@@ -41,6 +41,7 @@
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <scsi/scsi.h>
+#include "device_scsi.h"
#include <parted/parted.h>
@@ -828,6 +829,20 @@
PED_ASSERT (!dev->external_mode, return 0);
PED_ASSERT (buffer != NULL, return 0);
+
+ /* Kludge. This is necessary to read/write the last
+ block of an odd-sized SCSI disk, until 2.5.x kernel fixes.
+ This is only used by disk_gpt.c, and only to read/write
+ one sector, so we don't have to be fancy.
+ */
+
+ if (dev->type == PED_DEVICE_SCSI &&
+ (dev->length & 1) &&
+ (count == 1) &&
+ start == dev->length - 1) {
+ return ped_device_read_scsi(dev, buffer, start, count);
+ }
+
while (1) {
if (ped_device_seek (dev, start))
break;
@@ -946,6 +961,19 @@
return 0;
else
return 1;
+ }
+
+ /* Kludge. This is necessary to read/write the last
+ block of an odd-sized SCSI disk, until 2.5.x kernel fixes.
+ This is only used by disk_gpt.c, and only to read/write
+ one sector, so we don't have to be fancy.
+ */
+
+ if (dev->type == PED_DEVICE_SCSI &&
+ (dev->length & 1) &&
+ (count == 1) &&
+ start == dev->length - 1) {
+ return ped_device_write_scsi(dev, buffer, start, count);
}
while (1) {
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/device_scsi.c parted-1.4.7-gpt/libparted/device_scsi.c
--- parted-1.4.7/libparted/device_scsi.c Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/device_scsi.c Thu Jan 18 11:24:42 2001
@@ -0,0 +1,102 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include <fcntl.h>
+
+#include <parted/parted.h>
+#include"sg_map.h"
+#include"sg_dd.h"
+
+static const char *
+sg_from_sd(const char *sd)
+{
+ int i;
+ for (i=0; i<MAX_SG_DEVS; i++)
+ if (!strncmp(sd, sg_to_sd[i].sd, 16)) return sg_to_sd[i].sg;
+ return NULL;
+}
+
+int
+ped_device_read_scsi (PedDevice* dev, const void* buffer, PedSector start,
+ PedSector count)
+{
+ const char *sg = NULL;
+ extern int sg_to_sd_map_made;
+ int rc;
+ int sg_fd, diop = 0;
+
+ // printf("in ped_device_read_scsi()\n");
+ PED_ASSERT(dev != NULL, return 0);
+ PED_ASSERT(dev->type == PED_DEVICE_SCSI, return 0);
+ PED_ASSERT(buffer != NULL, return 0);
+ PED_ASSERT(count == 1, return 0);
+
+ if (!sg_to_sd_map_made) make_sg_to_sd_map();
+
+ sg = sg_from_sd(dev->path);
+ if (!sg) return 0;
+
+ // printf("sg=%s\n", sg);
+ /* Must open RDRW because we write the command to the disk
+ then read the results */
+ if ((sg_fd = open(sg, O_RDWR)) < 0)
+ return 0;
+
+ rc = sg_read(sg_fd, (unsigned char *)buffer, count, start,
+ dev->sector_size, &diop);
+
+ close(sg_fd);
+ return !rc;
+}
+
+int
+ped_device_write_scsi (PedDevice* dev, const void* buffer, PedSector start,
+ PedSector count)
+{
+ char *sg = NULL;
+ extern int sg_to_sd_map_made;
+ int rc;
+ int sg_fd, diop = 0;
+
+ // printf("in ped_device_write_scsi()\n");
+ PED_ASSERT(dev != NULL, return 0);
+ PED_ASSERT(dev->type == PED_DEVICE_SCSI, return 0);
+ PED_ASSERT(buffer != NULL, return 0);
+ PED_ASSERT(count == 1, return 0);
+
+ if (!sg_to_sd_map_made) make_sg_to_sd_map();
+ sg = sg_from_sd(dev->path);
+ if (!sg) return 0;
+
+ // printf("sg=%s\n", sg);
+ /* Must open RDRW because we write the command to the disk
+ then read the results */
+ if ((sg_fd = open(sg, O_RDWR)) < 0)
+ return 0;
+
+ rc = sg_write(sg_fd, (unsigned char *)buffer, count, start,
+ dev->sector_size, &diop);
+
+ close(sg_fd);
+ return !rc;
+
+}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/device_scsi.h parted-1.4.7-gpt/libparted/device_scsi.h
--- parted-1.4.7/libparted/device_scsi.h Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/device_scsi.h Thu Jan 18 11:24:42 2001
@@ -0,0 +1,28 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "parted/device.h"
+
+int
+ped_device_read_scsi (PedDevice* dev, const void* buffer, PedSector start,
+ PedSector count);
+int
+ped_device_write_scsi (PedDevice* dev, const void* buffer, PedSector start,
+ PedSector count);
+
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/disk.c parted-1.4.7-gpt/libparted/disk.c
--- parted-1.4.7/libparted/disk.c Mon Jan 8 10:49:15 2001
+++ parted-1.4.7-gpt/libparted/disk.c Thu Jan 18 11:32:50 2001
@@ -174,6 +174,7 @@
disk->dev = dev;
disk->type = disk_type;
disk->update_mode = 0;
+ disk->disk_specific = NULL;
disk->part_list = ped_partition_new (
disk, PED_PARTITION_FREESPACE, NULL,
@@ -581,6 +582,7 @@
part->type = type;
part->part_list = NULL;
part->fs_type = fs_type;
+ part->disk_specific = NULL;
return part;
@@ -599,6 +601,8 @@
PedPartition* part;
PED_ASSERT (disk != NULL, return NULL);
+ PED_ASSERT (disk->type != NULL, return NULL);
+ PED_ASSERT (disk->type->ops != NULL, return NULL);
PED_ASSERT (disk->type->ops->partition_new != NULL, return NULL);
supports_extended = ped_disk_type_check_feature (disk->type,
@@ -1314,10 +1318,10 @@
PED_ASSERT (part != NULL, return 0);
#ifdef VERBOSE
- printf ("ped_disk_add_partition (dev=\"%s\", start=%d, end=%d,"
+ printf ("ped_disk_add_partition (dev=\"%s\", start=%llx, end=%llx,"
" type=%x)\n",
- disk->dev->path, (int) part->geom.start, (int) part->geom.end,
- (int) part->system);
+ disk->dev->path, part->geom.start, part->geom.end,
+ part->type);
#endif
if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/disk_dos.c parted-1.4.7-gpt/libparted/disk_dos.c
--- parted-1.4.7/libparted/disk_dos.c Tue Jan 9 12:29:52 2001
+++ parted-1.4.7-gpt/libparted/disk_dos.c Mon Jan 22 11:42:31 2001
@@ -232,6 +232,12 @@
return 0;
}
+ /* If this is a GPT disk, fail here */
+ for (i = 0; i < 4; i++) {
+ if (part_table.partitions[i].type == 0xEE)
+ return 0;
+ }
+
/* HACK: it's impossible to tell PC98 and msdos disk labels apart.
* Someone made the signatures the same (very clever). Since
* PC98 has some idiosyncracies with it's boot-loader, it's detection
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/disk_gpt.c parted-1.4.7-gpt/libparted/disk_gpt.c
--- parted-1.4.7/libparted/disk_gpt.c Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/disk_gpt.c Wed Jan 24 11:47:09 2001
@@ -0,0 +1,1738 @@
+/*
+ libparted - a library for manipulating disk partitions
+
+ Copyright (C) 2000-2001 Dell Computer Corporation
+ disk_gpt.[ch] by Matt Domsch <Matt_Domsch@dell.com>
+
+ EFI GUID Partition Table handling
+ Per Intel EFI Specification v1.02
+ http://developer.intel.com/technology/efi/efi.htm
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ TODO:
+ - Make partition labels get/set properly
+*/
+
+#include "config.h"
+
+#include <parted/parted.h>
+#include <parted/endian.h>
+#include <parted/crc32.h>
+#include <parted/disk_gpt.h>
+#include <parted/natmath.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <uuid/uuid.h>
+#include <unicode.h>
+
+#include <libintl.h>
+#if ENABLE_NLS
+# define _(String) gettext (String)
+#else
+# define _(String) (String)
+#endif /* ENABLE_NLS */
+
+
+void ped_disk_gpt_init();
+void ped_disk_gpt_done();
+
+static int gpt_probe(const PedDevice * dev);
+static PedDisk *gpt_open(PedDevice * dev);
+static PedDisk *gpt_create(PedDevice * dev);
+static int gpt_clobber(PedDevice * dev);
+static int gpt_close(PedDisk * disk);
+static int gpt_read(PedDisk * disk);
+static int gpt_write(PedDisk * disk);
+
+
+static PedPartition *gpt_partition_new(const PedDisk *disk,
+ PedPartitionType part_type,
+ const PedFileSystemType* fs_type,
+ PedSector start,
+ PedSector end);
+static void gpt_partition_destroy(PedPartition *part);
+static int gpt_partition_set_flag(PedPartition *part,
+ PedPartitionFlag flag,
+ int state);
+static int gpt_partition_get_flag(const PedPartition *part,
+ PedPartitionFlag flag);
+static int gpt_partition_is_flag_available(const PedPartition * part,
+ PedPartitionFlag flag);
+static void gpt_partition_set_name(PedPartition *part,
+ const char *name);
+static const char * gpt_partition_get_name (const PedPartition * part);
+static int gpt_partition_align(PedPartition * part,
+ const PedConstraint * constraint);
+static int gpt_partition_enumerate(PedPartition * part);
+
+static int gpt_alloc_metadata(PedDisk * disk);
+static int gpt_get_max_primary_partition_count(const PedDisk *disk);
+
+/* gpt private function */
+static PedDisk * gpt_new(PedDisk * disk);
+
+static PedDiskOps gpt_disk_ops = {
+ probe : gpt_probe,
+ open : gpt_open,
+ create : gpt_create,
+ clobber : gpt_clobber,
+ close : gpt_close,
+ read : gpt_read,
+ write : gpt_write,
+ partition_new : gpt_partition_new,
+ partition_destroy : gpt_partition_destroy,
+ partition_set_flag : gpt_partition_set_flag,
+ partition_get_flag : gpt_partition_get_flag,
+ partition_is_flag_available : gpt_partition_is_flag_available,
+ partition_set_name : gpt_partition_set_name,
+ partition_get_name : gpt_partition_get_name,
+ partition_align : gpt_partition_align,
+ partition_enumerate : gpt_partition_enumerate,
+ partition_set_extended_system : NULL,
+ alloc_metadata : gpt_alloc_metadata,
+ get_max_primary_partition_count : gpt_get_max_primary_partition_count
+
+};
+
+static PedDiskType gpt_disk_type = {
+ next:NULL,
+ name:GPT_NAME,
+ ops:&gpt_disk_ops,
+ features: PED_DISK_TYPE_PARTITION_NAME
+};
+
+
+
+/************************************************************
+ * efi_crc32()
+ * Requires:
+ * - a buffer of length len
+ * Modifies: nothing
+ * Returns:
+ * EFI-style CRC32 value for buf
+ *
+ * This function uses the crc32 function by Gary S. Brown,
+ * but seeds the function with ~0, and xor's with ~0 at the end.
+ ************************************************************/
+
+static inline __u32
+efi_crc32(const void *buf, unsigned long len)
+{
+ return (crc32(buf, len, ~0L) ^ ~0L);
+}
+
+
+static inline int
+IsLegacyMBRValid(LegacyMBR_t * mbr)
+{
+ return (mbr ? (mbr->Signature == MSDOS_MBR_SIGNATURE) : 0);
+}
+
+static inline int
+efi_guidcmp(efi_guid_t left, efi_guid_t right)
+{
+ return memcmp(&left, &right, sizeof(efi_guid_t));
+}
+
+
+/************************************************************
+ * LastLBA()
+ * Requires:
+ * - dev
+ * Modifies: nothing
+ * Returns:
+ * Last LBA value on success
+ * 0 on error
+ ************************************************************/
+
+
+static __u64
+LastLBA(const PedDevice * dev)
+{
+ __u64 lastlba;
+ PED_ASSERT(dev != NULL, return 0);
+ lastlba = dev->length - 1;
+ /* Kludge until either:
+ a) kernel can read/write last
+ block on an odd-sized disk, or
+ b) we use scsi-generic to do it.
+ */
+ // if (!(lastlba & 1)) lastlba--;
+ return lastlba;
+}
+
+
+
+/************************************************************
+ * IsLBAValid()
+ * Requires:
+ * - dev
+ * - lba is the logical block address desired
+ * Modifies: nothing
+ * Returns:
+ * - 1 if true
+ * - 0 if false
+ ************************************************************/
+
+
+
+static inline int
+IsLBAValid(PedDevice *dev, __u64 lba)
+{
+ return (lba <= LastLBA(dev));
+}
+
+
+/************************************************************
+ * WriteLBA()
+ * Requires:
+ * - dev
+ * - lba is the logical block address desired
+ * - buffer is a buffer of size size into which data is read
+ * - size_t count is size of the read (in bytes)
+ * Modifies:
+ * - dev
+ * Returns:
+ * - 1 on success
+ * - 0 on error
+ ************************************************************/
+
+static int
+WriteLBA(PedDevice * dev, __u64 lba, void *buffer, size_t count)
+{
+ size_t blocks;
+ //printf("WriteLBA(lba=%llx, count=%llx)\n", lba, count);
+ PED_ASSERT(dev != NULL, return 0);
+ PED_ASSERT(dev->sector_size != 0, return 0);
+ blocks = count / dev->sector_size;
+ if (count % dev->sector_size)
+ blocks++;
+ return ped_device_write(dev, buffer, lba, blocks);
+}
+
+/************************************************************
+ * ReadLBA()
+ * Requires:
+ * - dev
+ * - lba is the logical block address desired
+ * - buffer is a buffer of size size into which data is read
+ * - size_t count is size of the read (in bytes)
+ * Modifies:
+ * - dev
+ * Returns:
+ * - 1 on success
+ * - 0 on error
+ ************************************************************/
+
+static int
+ReadLBA(const PedDevice * dev, __u64 lba, void *buffer, size_t count)
+{
+ size_t blocks;
+ PED_ASSERT(dev != NULL, return 0);
+ PED_ASSERT(dev->sector_size != 0, return 0);
+ //printf("ReadLBA(lba=%llx, count=%llx)\n", lba, count);
+ blocks = count / dev->sector_size;
+ if (count % dev->sector_size)
+ blocks++;
+ return ped_device_read(dev, buffer, lba, blocks);
+}
+
+
+
+/************************************************************
+ * ReadGuidPartitionEntries()
+ * Requires:
+ * - dev
+ * - lba is the Logical Block Address of the partition table
+ * - gpt is a buffer into which the GPT will be put
+ * Modifies:
+ * - dev
+ * - gpt
+ * Returns:
+ * pte on success
+ * NULL on error
+ * Notes: remember to free pte when you're done!
+ ************************************************************/
+static GuidPartitionEntry_t *
+ReadGuidPartitionEntries(const PedDevice * dev,
+ GuidPartitionTableHeader_t *
+ gpt)
+{
+ GuidPartitionEntry_t *pte;
+
+ PED_ASSERT(dev != NULL, return NULL);
+ PED_ASSERT(gpt != NULL, return NULL);
+
+ pte = (GuidPartitionEntry_t *)
+ ped_malloc(gpt->NumberOfPartitionEntries *
+ gpt->SizeOfPartitionEntry);
+
+ PED_ASSERT(pte != NULL, return NULL);
+
+ memset(pte, 0, gpt->NumberOfPartitionEntries *
+ gpt->SizeOfPartitionEntry);
+
+
+ if (!ReadLBA(dev, gpt->PartitionEntryLBA, pte,
+ gpt->NumberOfPartitionEntries *
+ gpt->SizeOfPartitionEntry)) {
+ free(pte);
+ return NULL;
+ }
+ return pte;
+}
+
+/************************************************************
+ * WriteGuidPartitionEntries()
+ * Requires:
+ * - PedDevice *dev
+ * - gpt
+ * - pte is a buffer that will be written
+ * Modifies:
+ * - dev
+ * - gpt
+ * Returns:
+ * pte on success
+ * NULL on error
+ * Notes: remember to free pte when you're done!
+ ************************************************************/
+static GuidPartitionEntry_t *
+WriteGuidPartitionEntries(PedDevice * dev,
+ GuidPartitionTableHeader_t * gpt,
+ GuidPartitionEntry_t *ptes)
+{
+ PED_ASSERT(gpt != NULL, return NULL);
+ PED_ASSERT(ptes != NULL, return NULL);
+
+ if (!WriteLBA
+ (dev, gpt->PartitionEntryLBA, ptes,
+ gpt->NumberOfPartitionEntries *
+ gpt->SizeOfPartitionEntry)) return NULL;
+ return ptes;
+}
+
+
+static void
+PrintGuidPartitionEntry(GuidPartitionEntry_t * pte, int i)
+{
+ efi_guid_t unused_guid = UNUSED_ENTRY_GUID;
+ char uuid_buffer[40];
+ uuid_t uuid;
+ PED_ASSERT(pte != NULL, return);
+ if (!efi_guidcmp(pte->PartitionTypeGuid, unused_guid)) {
+ // printf("UNUSED_ENTRY_GUID\n");
+ return;
+ }
+ printf("GUID Partition Entry %d:\n", i);
+ memcpy(uuid, &pte->PartitionTypeGuid, sizeof(uuid_t));
+ uuid_unparse(uuid, uuid_buffer);
+ printf("\tPartitionTypeGuid : %s\n", uuid_buffer);
+ memcpy(uuid, &pte->UniquePartitionGuid, sizeof(uuid_t));
+ uuid_unparse(uuid, uuid_buffer);
+ printf("\tUniquePartitionGuid : %s\n", uuid_buffer);
+ printf("\tStartingLBA : %llx\n", pte->StartingLBA);
+ printf("\tEndingLBA : %llx\n", pte->EndingLBA);
+ printf("\tAttributes : ");
+ printf("\tRequiredToFunction: %x",
+ pte->Attributes.RequiredToFunction);
+ printf("\tGuidSpecific: %x\n",
+ pte->Attributes.GuidSpecific);
+
+ // printf("\tPartitionName : Unicode string.\n");
+ return;
+}
+
+
+static void
+PrintGuidPartitionTableHeader(GuidPartitionTableHeader_t * gpt)
+{
+ char uuid_buffer[40];
+ uuid_t uuid;
+ printf("GUID Partition Table Header\n");
+ PED_ASSERT(gpt != NULL, return);
+ printf("Signature : %llx\n", gpt->Signature);
+ printf("Revision : %x\n", gpt->Revision);
+ printf("HeaderSize : %x\n", gpt->HeaderSize);
+ printf("HeaderCRC32 : %x\n", gpt->HeaderCRC32);
+ printf("MyLBA : %llx\n", gpt->MyLBA);
+ printf("AlternateLBA : %llx\n", gpt->AlternateLBA);
+ printf("FirstUsableLBA : %llx\n", gpt->FirstUsableLBA);
+ printf("LastUsableLBA : %llx\n", gpt->LastUsableLBA);
+ memcpy(uuid, &gpt->DiskGUID, sizeof(uuid_t));
+ uuid_unparse(uuid, uuid_buffer);
+ printf("DiskGUID : %s\n", uuid_buffer);
+ printf("PartitionEntryLBA : %llx\n", gpt->PartitionEntryLBA);
+ printf("NumberOfPartitionEntries : %x\n",
+ gpt->NumberOfPartitionEntries);
+ printf("SizeOfPartitionEntry : %x\n", gpt->SizeOfPartitionEntry);
+ printf("PartitionEntryArrayCRC32 : %x\n",
+ gpt->PartitionEntryArrayCRC32); return;
+}
+
+
+/************************************************************
+ * ReadGuidPartitionTableHeader()
+ * Requires:
+ * - dev
+ * - lba is the Logical Block Address of the partition table
+ * Modifies:
+ * - dev
+ * Returns:
+ * GPTH on success
+ * NULL on error
+ ************************************************************/
+static GuidPartitionTableHeader_t *
+ReadGuidPartitionTableHeader(const PedDevice * dev,
+ __u64 lba)
+{
+ GuidPartitionTableHeader_t *gpt;
+ PED_ASSERT(dev != NULL, return 0);
+ gpt = (GuidPartitionTableHeader_t *)
+ ped_malloc(sizeof(GuidPartitionTableHeader_t));
+ if (!gpt) return NULL;
+ memset(gpt, 0, sizeof (*gpt));
+ if (!ReadLBA(dev, lba, gpt, sizeof(GuidPartitionTableHeader_t))) {
+ free(gpt);
+ return NULL;
+ }
+
+ return gpt;
+}
+
+/************************************************************
+ * WriteGuidPartitionTableHeader()
+ * Requires:
+ * - dev
+ * - lba is the Logical Block Address of the partition table
+ * - gpt is a buffer into which the GPT will be put
+ * Modifies:
+ * - dev
+ * Returns:
+ * 1 on success
+ * 0 on error
+ ************************************************************/
+static int
+WriteGuidPartitionTableHeader(PedDevice *dev,
+ GuidPartitionTableHeader_t * gpt)
+{
+ PED_ASSERT(gpt != NULL, return 0);
+ if (!WriteLBA
+ (dev, gpt->MyLBA, gpt,
+ sizeof(GuidPartitionTableHeader_t))) return 0;
+ return 1;
+}
+
+
+/************************************************************
+ * IsGuidPartitionTableValid()
+ * Requires:
+ * - dev
+ * - lba is the Logical Block Address of the partition table
+ * Modifies:
+ * - dev
+ * - gpt - reads data into gpt
+ * - ptes - reads data into ptes
+ * Returns:
+ * 1 if valid
+ * 0 on error
+ ************************************************************/
+
+
+static int
+IsGuidPartitionTableValid(const PedDevice * dev, __u64 lba,
+ GuidPartitionTableHeader_t ** gpt,
+ GuidPartitionEntry_t ** ptes)
+{
+ int rc = 0; /* default to not valid */
+ __u32 crc, origcrc;
+ PED_ASSERT(gpt != NULL, return 0);
+ PED_ASSERT(ptes != NULL, return 0);
+ // printf("IsGuidPartitionTableValid(%llx)\n", lba);
+ if (!(*gpt = ReadGuidPartitionTableHeader(dev, lba)))
+ return rc;
+ /* Check the GUID Partition Table Signature */
+ if ((*gpt)->Signature != GUID_PT_HEADER_SIGNATURE) {
+ /*
+ printf("GUID Partition Table Header Signature is wrong: %llx != %llx\n",
+ (*gpt)->Signature, GUID_PT_HEADER_SIGNATURE);
+ */
+ free(*gpt);
+ *gpt = NULL;
+ return rc;
+ }
+
+ /* Check the GUID Partition Table Header CRC */
+ origcrc = (*gpt)->HeaderCRC32;
+ (*gpt)->HeaderCRC32 = 0;
+ crc = efi_crc32(*gpt, (*gpt)->HeaderSize);
+ if (crc != origcrc) {
+ // printf( "GPTH CRC check failed, %x != %x.\n", origcrc, crc);
+ (*gpt)->HeaderCRC32 = origcrc;
+ PrintGuidPartitionTableHeader(*gpt);
+ free(*gpt);
+ *gpt = NULL;
+ return rc;
+ }
+ (*gpt)->HeaderCRC32 = origcrc;
+ /* Check that the MyLBA entry points to the LBA
+ that contains the GPT we read */
+ if ((*gpt)->MyLBA != lba) {
+ // printf( "MyLBA %llx != lba %llx.\n", (*gpt)->MyLBA, lba);
+ free(*gpt);
+ *gpt = NULL;
+ return rc;
+ }
+
+ if (!(*ptes = ReadGuidPartitionEntries(dev, *gpt))) {
+ free(*gpt);
+ *gpt = NULL;
+ return rc;
+ }
+
+
+ /* Check the GUID Partition Entry Array CRC */
+ crc = efi_crc32(*ptes, (*gpt)->NumberOfPartitionEntries *
+ (*gpt)->SizeOfPartitionEntry);
+ if (crc != (*gpt)->PartitionEntryArrayCRC32) {
+ // printf("GUID Partitition Entry Array CRC check failed.\n");
+ free(*gpt);
+ *gpt = NULL;
+ free(*ptes);
+ *ptes = NULL;
+ return rc;
+ }
+
+ /* We're done, all's well */
+ return 1;
+}
+
+/************************************************************
+ * CreateNewPMBR()
+ * Requires:
+ * - dev
+ * Modifies:
+ * - dev
+ * Returns:
+ * 1 on success
+ * 0 on error
+ ************************************************************/
+
+
+static int
+CreateNewPMBR(PedDevice * dev)
+{
+ LegacyMBR_t pmbr;
+ memset(&pmbr, 0, sizeof(pmbr));
+ pmbr.Signature = MSDOS_MBR_SIGNATURE;
+ pmbr.PartitionRecord[0].OSType = EFI_PMBR_OSTYPE_EFI_GPT;
+ pmbr.PartitionRecord[0].EndHead = 0xFF;
+ pmbr.PartitionRecord[0].EndSector = 0xFE;
+ pmbr.PartitionRecord[0].EndTrack = 0xFF;
+ pmbr.PartitionRecord[0].StartingLBA = 1;
+ pmbr.PartitionRecord[0].SizeInLBA = LastLBA(dev) + 1;
+ if (!WriteLBA(dev, 0, &pmbr, sizeof(pmbr))) {
+
+ // printf("CreateNewPMBR(): Unable to create new PMBR.\n");
+ return 0;
+ }
+
+ return 1;
+
+}
+
+
+#if 0
+static int
+UpdateGuidPartition(PedPartition *part)
+{
+ GPTPartitionData *gpt_part_data;
+ PED_ASSERT(part != NULL, return -1);
+ PED_ASSERT(part->disk_specific != NULL, return 0);
+
+ gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data->pte != NULL, return -1);
+
+ gpt_part_data->pte->StartingLBA = part->geom.start;
+ gpt_part_data->pte->EndingLBA = part->geom.end;
+ gpt_part_data->pte->PartitionTypeGuid = PARTITION_BASIC_DATA_GUID;
+
+ /* FIXME: need to change type to PARTITION_SYSTEM_GUID
+ or tag raid and lvm flags into attributes */
+
+ return 1;
+}
+#endif
+
+#if 0
+/***********************************
+ * CreateDefaultMSRGuidPartition()
+ *
+ * Returns: 1 on success, 0 on failure
+ *
+ */
+
+
+static int
+CreateDefaultMSRGuidPartition(GuidPartitionTableHeader_t * gpt,
+ GuidPartitionEntry_t * pte)
+{
+ __u64 size;
+ int i;
+ PED_ASSERT(gpt != NULL, return 0);
+ PED_ASSERT(pte != NULL, return 0);
+
+ /* The rule is :
+ On drives < 16GB, MSR is 32MB.
+ On drives >= 16GB, MSR is 128MB.
+ */
+
+ /* This accounts for block size == 512 */
+ if (gpt->LastUsableLBA < 16 * 1024 * 1024 * 2)
+ size = (16 * 1024 * 1024) / 512;
+ else
+ size = (128 * 1024 * 1024) / 512;
+
+ i = CreateNextGuidPartition(gpt, pte, size);
+ if (i == -1)
+ return 0;
+
+ pte[i].PartitionTypeGuid = PARTITION_MSFT_RESERVED_GUID;
+ return 1;
+}
+
+
+static int
+CreateDefaultEFIGuidPartition(GuidPartitionTableHeader_t * gpt,
+ GuidPartitionEntry_t * pte)
+{
+ int i;
+ __u64 size;
+ PED_ASSERT(gpt != NULL, return 0);
+ PED_ASSERT(pte != NULL, return 0);
+
+
+ /* The rule is :
+ size = MAX(100MB, MIN(1% of physical disk, 1GB))
+ */
+ size = PED_MAX((100 * 1024 * 1024) / 512;
+ PED_MIN(gpt->LastUsableLBA / 100,
+ (1024 * 1024 * 1024) / 512));
+
+ i = CreateNextGuidPartition(gpt, pte, size);
+ if (i == -1)
+ return 0;
+ pte[i].PartitionTypeGuid = PARTITION_SYSTEM_GUID;
+ return 1;
+}
+#endif
+
+/************************************************************n
+ * UpdateGuidPartitionTableHeaders()
+ * Updates the CRC fields for both primary and alternate GPTs
+ *
+ */
+static int
+UpdateGuidPartitionTableHeaders(GuidPartitionTableHeader_t *pgpt,
+ GuidPartitionTableHeader_t *agpt,
+ GuidPartitionEntry_t *ptes)
+{
+
+ // printf("in UpdateGuidPartitionTableHeaders()\n");
+ PED_ASSERT(pgpt != NULL, return 0);
+ PED_ASSERT(agpt != NULL, return 0);
+ PED_ASSERT(ptes != NULL, return 0);
+
+ pgpt->PartitionEntryArrayCRC32 =
+ agpt->PartitionEntryArrayCRC32 =
+ efi_crc32(ptes, pgpt->NumberOfPartitionEntries *
+ pgpt->SizeOfPartitionEntry);
+
+ pgpt->HeaderCRC32 = 0;
+ pgpt->HeaderCRC32 = efi_crc32(pgpt, pgpt->HeaderSize);
+ agpt->HeaderCRC32 = 0;
+ agpt->HeaderCRC32 = efi_crc32(agpt, agpt->HeaderSize);
+ return 1;
+}
+
+
+
+static int
+CreateNewGuidPartitionTableHeader(PedDevice *dev)
+{
+ __u64 size;
+ uuid_t uuid;
+ GuidPartitionTableHeader_t gpt, agpt;
+ GuidPartitionEntry_t ptes[GPT_DEFAULT_RESERVED_PARTITION_ENTRIES];
+ int count;
+
+ // printf("in CreateNewGuidPartitionTableHeader()\n");
+ memset(&gpt, 0, sizeof(gpt));
+ gpt.Signature = GUID_PT_HEADER_SIGNATURE;
+ gpt.Revision = GUID_PT_HEADER_REVISION_V1_02;
+ gpt.HeaderSize = 92; /* per 1.02 spec */
+ gpt.MyLBA = 1;
+ gpt.AlternateLBA = LastLBA(dev);
+ gpt.FirstUsableLBA = (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+ dev->sector_size) + 2;
+ gpt.LastUsableLBA =
+ gpt.AlternateLBA -
+ (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+ dev->sector_size) - 1;
+ uuid_generate(uuid);
+ memcpy(&(gpt.DiskGUID), uuid, sizeof(uuid));
+ gpt.PartitionEntryLBA = 2;
+ gpt.NumberOfPartitionEntries = GPT_DEFAULT_RESERVED_PARTITION_ENTRIES;
+ gpt.SizeOfPartitionEntry = sizeof(GuidPartitionEntry_t);
+
+ memset(ptes, 0,
+ gpt.NumberOfPartitionEntries * gpt.SizeOfPartitionEntry);
+
+ /* Fix up Alternate GPT */
+ memcpy(&agpt, &gpt, sizeof(gpt));
+ agpt.MyLBA = gpt.AlternateLBA;
+ agpt.AlternateLBA = gpt.MyLBA;
+ agpt.PartitionEntryLBA = agpt.MyLBA -
+ (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+ dev->sector_size);
+
+ if (!UpdateGuidPartitionTableHeaders(&gpt, &agpt, ptes))
+ return 0;
+
+ // printf("update successful\n");
+
+ /* Before the writes */
+ /* Write PTH and PTEs */
+ if (!WriteGuidPartitionTableHeader(dev, &gpt))
+ return 0;
+ if (!WriteGuidPartitionEntries(dev, &gpt, ptes))
+ return 0;
+
+
+ /* Write Alternate PTH & PTEs */
+ if (!WriteGuidPartitionEntries(dev, &agpt, ptes))
+ return 0;
+ if (!WriteGuidPartitionTableHeader(dev, &agpt))
+ return 0;
+
+ return 1;
+}
+
+
+
+static int
+CreateNewGPTDisk(PedDevice * dev)
+{
+ if (!CreateNewPMBR(dev))
+ return 0;
+ if (!CreateNewGuidPartitionTableHeader(dev))
+ return 0;
+ return 1;
+}
+
+
+/************************************************************
+ * FixPrimaryGuidPartitionTable()
+ * Uses values from alternate GPT and puts them in primary GPT.
+ * Requires:
+ * pgpt, agpt, ptes.
+ *
+ * Modifies:
+ * pgpt
+ *
+ * Returns:
+ * 1 if valid
+ * 0 on error
+ ************************************************************/
+
+static int
+FixBrokenGuidPartitionTable(PedDevice *dev,
+ GuidPartitionTableHeader_t **badgpt,
+ GuidPartitionTableHeader_t *goodgpt,
+ GuidPartitionEntry_t *ptes)
+{
+
+ PED_ASSERT(badgpt != NULL, return 0);
+ PED_ASSERT(goodgpt != NULL, return 0);
+ PED_ASSERT(ptes != NULL, return 0);
+
+ *badgpt = (GuidPartitionTableHeader_t *)
+ ped_malloc(sizeof(GuidPartitionTableHeader_t));
+ if (!*badgpt) return 0;
+ memset(*badgpt, 0, sizeof(**badgpt));
+
+ memcpy(*badgpt, goodgpt, sizeof(*goodgpt));
+
+ /* Change badgpt values */
+ (*badgpt)->MyLBA = goodgpt->AlternateLBA;
+ (*badgpt)->AlternateLBA = goodgpt->MyLBA;
+
+
+ if ((*badgpt)->MyLBA == 1)
+ (*badgpt)->PartitionEntryLBA = (*badgpt)->MyLBA + 1;
+ else
+ (*badgpt)->PartitionEntryLBA = (*badgpt)->MyLBA -
+ (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+ dev->sector_size);
+
+ return UpdateGuidPartitionTableHeaders(*badgpt, goodgpt, ptes);
+}
+
+
+
+
+static void
+PrintPartitionRecord(PartitionRecord_t * pr, int i)
+{
+ if (!pr)
+ return;
+ if (!(pr->OSType))
+ return;
+ printf("Legacy Partition Record %d\n", i);
+ printf("\tBootInd %02x", pr->BootIndicator);
+ printf("\tSHead %02x", pr->StartHead);
+ printf("\tSSector %02x", pr->StartSector);
+ printf("\tSTrack %02x\n", pr->StartTrack);
+ printf("\tOSType %02x", pr->OSType);
+ printf("\tEHead %02x", pr->EndHead);
+ printf("\tESector %02x", pr->EndSector);
+ printf("\tETrack %02x\n", pr->EndTrack);
+ printf("\tStartingLBA : %x", pr->StartingLBA);
+ printf("\tSizeInLBA : %x\n", pr->SizeInLBA);
+ return;
+}
+
+static void
+PrintLegacyMBR(LegacyMBR_t * mbr)
+{
+ int i;
+ if (!mbr)
+ return;
+ if (!IsLegacyMBRValid(mbr)) {
+ printf("MBR is invalid.\n");
+ return;
+ }
+
+ printf("UniqueMBRSignature: %x\n", mbr->UniqueMBRSignature);
+ for (i = 0; i < 4; i++)
+ PrintPartitionRecord(&(mbr->PartitionRecord[i]), i);
+ printf("Signature: %x\n", mbr->Signature);
+ return;
+}
+
+
+
+/************************************************************
+ * FindValidGPT()
+ * Requires:
+ * - dev
+ * - pgpt is a GPTH if it's valid
+ * - agpt is a GPTH if it's valid
+ * - ptes is a PTE
+ * Modifies:
+ * - gpt & ptes
+ * Returns:
+ * 1 if valid
+ * 0 on error
+ ************************************************************/
+static int
+FindValidGPT(const PedDevice * dev,
+ GuidPartitionTableHeader_t ** pgpt,
+ GuidPartitionTableHeader_t ** agpt,
+ GuidPartitionEntry_t ** ptes)
+{
+ int rc = 0;
+ GuidPartitionEntry_t *pptes = NULL, *aptes = NULL;
+ __u64 lastlba;
+
+ PED_ASSERT(dev != NULL, return 0);
+ PED_ASSERT(pgpt != NULL, return 0);
+ PED_ASSERT(agpt != NULL, return 0);
+ PED_ASSERT(ptes != NULL, return 0);
+
+ // printf("FindValidGPT()\n");
+ lastlba = LastLBA(dev);
+ /* Check the Primary GPT */
+ rc = IsGuidPartitionTableValid(dev, 1, pgpt, &pptes);
+ if (rc) {
+ /* Primary GPT is OK, check the alternate and warn if bad */
+ rc = IsGuidPartitionTableValid(dev, (*pgpt)->AlternateLBA,
+ agpt, &aptes);
+
+ if (!rc) {
+ *agpt = NULL;
+ printf("Alternate GPT is invalid, using primary GPT.\n");
+
+ }
+ if (aptes) free(aptes);
+ *ptes = pptes;
+ return 1;
+ } /* if primary is valid */
+ else {
+ /* Primary GPT is bad, check the Alternate GPT */
+ *pgpt = NULL;
+ rc = IsGuidPartitionTableValid(dev, lastlba,
+ agpt, &aptes);
+ if (rc) {
+ /* Primary is bad, alternate is good.
+ Return values from the alternate and warn.
+ */
+ printf
+ ("Primary GPT is invalid, using alternate GPT.\n");
+ *ptes = aptes;
+ return 1;
+ }
+ }
+ /* Both primary and alternate GPTs are bad.
+ * This isn't our disk, return 0.
+ */
+ *pgpt = NULL;
+ *agpt = NULL;
+ *ptes = NULL;
+ return 0;
+}
+
+
+static void
+PrintDiskInfo(PedDevice *dev)
+{
+ unsigned int i;
+ LegacyMBR_t mbr;
+ GuidPartitionTableHeader_t *pgpt = NULL, *agpt = NULL, *gpt = NULL;
+ GuidPartitionEntry_t *pte = NULL, zeropte;
+
+ // printf("PrintDiskInfo()\n");
+ memset(&zeropte, 0, sizeof(zeropte));
+ if (!ReadLBA(dev, 0, &mbr, sizeof(mbr))) {
+ printf("PrintDiskInfo error: ReadLBA(mbr) error.\n");
+ return;
+ }
+ PrintLegacyMBR(&mbr);
+ if (mbr.PartitionRecord[0].OSType == EFI_PMBR_OSTYPE_EFI_GPT) {
+ /* This is an EFI GPT disk */
+ if (!ReadLBA(dev, 1, &pgpt, sizeof(*pgpt))) {
+ printf("PrintDiskInfo error: ReadLBA(gpt) error.\n");
+ return;
+ }
+ printf("This is an EFI GPT disk.\n");
+ if (FindValidGPT(dev, &pgpt, &agpt, &pte)) {
+ if (pgpt) gpt = pgpt;
+ else if (agpt) gpt = agpt;
+ }
+ else {
+ printf("GUID Partition Table is invalid.\n");
+ return;
+ }
+ for (i = 0; pte && i < gpt->NumberOfPartitionEntries; i++) {
+ /* Partition entry is unused if all bytes are 0 */
+ if (memcmp(&zeropte, &pte[i], sizeof(zeropte)))
+ PrintGuidPartitionEntry(&pte[i], i);
+ }
+ if (pgpt) free(pgpt);
+ if (agpt) free(agpt);
+ if (pte) free(pte);
+ } else {
+ printf("This is not an EFI GPT disk. Try using fdisk.\n");
+ }
+ return;
+}
+
+
+
+
+
+
+void
+ped_disk_gpt_init()
+{
+ PED_ASSERT(sizeof(GuidPartitionTableHeader_t) == 512, return);
+ PED_ASSERT(sizeof(GuidPartitionEntryAttributes_t) == 8, return);
+ PED_ASSERT(sizeof(GuidPartitionEntry_t) == 128, return);
+
+ ped_register_disk_type(&gpt_disk_type);
+}
+
+void
+ped_disk_gpt_done()
+{
+ ped_unregister_disk_type(&gpt_disk_type);
+}
+
+static int
+gpt_probe(const PedDevice * dev)
+{
+ GuidPartitionTableHeader_t *pgpt = NULL, *agpt = NULL;
+ GuidPartitionEntry_t *ptes = NULL;
+
+ PED_ASSERT(dev != NULL, return 0);
+
+ // printf("gpt_probe()\n");
+
+ if (!ped_device_open((PedDevice *) dev))
+ return 0;
+
+ if (!(FindValidGPT(dev, &pgpt, &agpt, &ptes))) {
+ ped_device_close((PedDevice *) dev);
+ return 0;
+ }
+
+ ped_device_close((PedDevice *) dev);
+
+ if (pgpt) free(pgpt);
+ if (agpt) free(agpt);
+ if (ptes) free(ptes);
+ // printf("gpt_probe returning 1\n");
+ return 1;
+}
+
+static PedDisk *
+gpt_open(PedDevice * dev)
+{
+ PedDisk *disk;
+
+ // printf("gpt_open()\n");
+
+ PED_ASSERT(dev != NULL, return 0);
+
+ if (!gpt_probe(dev))
+ goto error;
+
+
+ ped_device_open((PedDevice *) dev);
+
+ // printf("gpt_open() called ped_device_open()\n");
+ disk = ped_disk_alloc(dev, &gpt_disk_type);
+ // printf("gpt_open called ped_disk_alloc()\n");
+
+ if (!disk)
+ goto error;
+
+ // printf("gpt_open: ped_disk_alloc() succeeded\n");
+
+ // printf("gpt_open() calling gpt_read()\n");
+ if (!gpt_read(disk))
+ goto error_free_disk_specific;
+
+ // printf("gpt_open returning disk\n");
+ return disk;
+
+ error_free_disk_specific:
+ ped_free(disk->disk_specific);
+ error_free_disk:
+ ped_free(disk);
+ error:
+ // printf("gpt_open() returning NULL\n");
+ return NULL;
+}
+
+static PedDisk *
+gpt_create(PedDevice * dev)
+{
+ PedDisk *newdisk;
+ PED_ASSERT(dev != NULL, return 0);
+
+ // printf("gpt_create()\n");
+ if (!ped_device_open(dev))
+ goto error;
+
+
+ CreateNewGPTDisk(dev);
+
+ if (!ped_device_sync(dev))
+ goto error_close_dev;
+
+ ped_device_close(dev);
+ newdisk = gpt_open(dev);
+ return newdisk;
+
+ error_close_dev:
+ ped_device_close(dev);
+ error:
+ return 0;
+}
+
+static int
+gpt_close(PedDisk * disk)
+{
+ // printf("in gpt_close()\n");
+ PED_ASSERT(disk != NULL, return 0);
+
+ ped_device_close(disk->dev);
+ ped_disk_delete_all(disk);
+ if (disk->disk_specific) ped_free(disk->disk_specific);
+ ped_free(disk);
+ return 1;
+}
+
+
+
+
+
+
+static int
+gpt_read(PedDisk * disk)
+{
+ PedPartition *part;
+ unsigned int i;
+ GPTDiskData *gpt_disk_data;
+ GPTPartitionData *gpt_part_data;
+ PedConstraint* constraint_exact;
+ efi_guid_t unused = UNUSED_ENTRY_GUID;
+
+ // printf("in gpt_read()\n");
+ PED_ASSERT(disk != NULL, return 0);
+ PED_ASSERT(disk->dev != NULL, return 0);
+
+
+ ped_disk_delete_all(disk);
+
+ // printf("gpt_read(): ped_disk_delete_all() returned.\n");
+
+ if (!disk->disk_specific) gpt_new(disk);
+ PED_ASSERT(disk->disk_specific != NULL, return 0);
+ gpt_disk_data = disk->disk_specific;
+
+
+ if (!FindValidGPT(disk->dev, &(gpt_disk_data->pgpt), &(gpt_disk_data->agpt), &(gpt_disk_data->ptes)))
+ return 0;
+
+ /* If one of the gpts are broken, fix it. */
+ if (!gpt_disk_data->pgpt) {
+ FixBrokenGuidPartitionTable(disk->dev,
+ &gpt_disk_data->pgpt,
+ gpt_disk_data->agpt,
+ gpt_disk_data->ptes);
+ }
+ else if (!gpt_disk_data->agpt) {
+ FixBrokenGuidPartitionTable(disk->dev,
+ &gpt_disk_data->agpt,
+ gpt_disk_data->pgpt,
+ gpt_disk_data->ptes);
+ }
+
+ for (i = 0; i < gpt_disk_data->pgpt->NumberOfPartitionEntries; i++) {
+
+ if (!efi_guidcmp(gpt_disk_data->ptes[i].PartitionTypeGuid,
+ unused)) continue;
+
+ // printf("calling ped_partition_alloc() in gpt_read(), i=%u\n", i);
+ // PrintGuidPartitionEntry(&gpt_disk_data->ptes[i], i);
+ part = ped_partition_alloc(disk, PED_PARTITION_PRIMARY, NULL,
+ gpt_disk_data->ptes[i].StartingLBA,
+ gpt_disk_data->ptes[i].EndingLBA);
+ if (!part)
+ return 0;
+
+ part->num = i+1;
+
+ gpt_part_data = part->disk_specific =
+ ped_malloc(sizeof(GPTPartitionData));
+ if (!gpt_part_data) {
+ ped_free(part);
+ return 0;
+ }
+ memset(gpt_part_data, 0, sizeof(*gpt_part_data));
+
+ gpt_part_data->pte = &(gpt_disk_data->ptes[i]);
+
+ // printf("handling constraints\n");
+ constraint_exact = ped_constraint_exact (&part->geom);
+ if (!ped_disk_add_partition(disk, part, constraint_exact)) {
+ ped_free(gpt_part_data);
+ ped_free(part);
+ // printf("gpt_read() returning 0 after ped_disk_add_partition()\n");
+ return 0;
+ }
+ ped_constraint_destroy (constraint_exact);
+
+ }
+ // printf("gpt_read() returning 1\n");
+ return 1;
+}
+
+
+static int
+gpt_write(PedDisk * disk)
+{
+
+ GPTDiskData *gpt_disk_data;
+ PedPartition *part = NULL;
+
+ // printf("!!!!!in gpt_write()\n");
+ PED_ASSERT(disk != NULL, return 0);
+ PED_ASSERT(disk->dev != NULL, return 0);
+ PED_ASSERT(disk->disk_specific != NULL, return 0);
+ gpt_disk_data = disk->disk_specific;
+
+ if (!CreateNewPMBR(disk->dev)) return 0;
+
+ UpdateGuidPartitionTableHeaders(gpt_disk_data->pgpt,
+ gpt_disk_data->agpt,
+ gpt_disk_data->ptes);
+
+ /* Write PTH and PTEs */
+ if (!WriteGuidPartitionTableHeader(disk->dev, gpt_disk_data->pgpt))
+ return 0;
+ if (!WriteGuidPartitionEntries(disk->dev, gpt_disk_data->pgpt, gpt_disk_data->ptes))
+ return 0;
+
+
+ /* Write Alternate PTH & PTEs */
+ if (!WriteGuidPartitionEntries(disk->dev, gpt_disk_data->agpt, gpt_disk_data->ptes))
+ return 0;
+ if (!WriteGuidPartitionTableHeader(disk->dev, gpt_disk_data->agpt))
+ return 0;
+
+
+
+
+ if (!ped_device_sync(disk->dev))
+ return 0;
+
+ return 1;
+}
+
+
+
+static int
+add_metadata_part(PedDisk * disk, PedPartitionType type, PedSector start,
+ PedSector length)
+{
+ PedPartition *new_part;
+ PedConstraint * constraint_exact;
+ PED_ASSERT(disk != NULL, return 0);
+
+
+ // printf("calling ped_partition_new() in add_metadata_part()\n");
+ new_part =
+ ped_partition_new(disk, type | PED_PARTITION_METADATA, NULL,
+ start, start + length - 1);
+ if (!new_part)
+ goto error;
+
+ constraint_exact = ped_constraint_exact (&new_part->geom);
+
+ if (!ped_disk_add_partition(disk, new_part, constraint_exact))
+ goto error_destroy_new_part;
+
+ return 1;
+
+ error_destroy_new_part:
+ ped_partition_destroy(new_part);
+ error:
+ return 0;
+}
+
+static PedPartition *
+gpt_partition_new(const PedDisk *disk,
+ PedPartitionType part_type,
+ const PedFileSystemType* fs_type,
+ PedSector start,
+ PedSector end)
+{
+ unsigned int i;
+ uuid_t uuid;
+ efi_guid_t unused_entry_guid = UNUSED_ENTRY_GUID;
+ GPTDiskData *gpt_disk_data;
+ GPTPartitionData *gpt_part_data;
+ PedPartition *part;
+
+ PED_ASSERT(disk != NULL, return NULL);
+
+
+ part = ped_partition_alloc (disk, part_type, fs_type, start, end);
+ if (!part) return NULL;
+
+ if (part_type != PED_PARTITION_PRIMARY)
+ return part;
+
+ if (!ped_disk_check_overlap(disk, part)) {
+ ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_CANCEL,
+ _("The new partition overlaps with another "
+ "partition."));
+ ped_free(part);
+ return NULL;
+ }
+
+ PED_ASSERT(disk->disk_specific != NULL, return NULL);
+
+ gpt_disk_data = disk->disk_specific;
+ // printf("in gpt_partition_new(s=%llx, e=%llx t=%d)\n", start, end, part_type);
+
+
+ PED_ASSERT(gpt_disk_data->pgpt != NULL, return NULL);
+ PED_ASSERT(gpt_disk_data->agpt != NULL, return NULL);
+ PED_ASSERT(gpt_disk_data->ptes != NULL, return NULL);
+
+
+ for (i = 0; i < gpt_disk_data->pgpt->NumberOfPartitionEntries; i++) {
+ if (!efi_guidcmp
+ (gpt_disk_data->ptes[i].PartitionTypeGuid, unused_entry_guid)) {
+ break;
+ }
+ }
+ /* No unused entries */
+ if (i == gpt_disk_data->pgpt->NumberOfPartitionEntries){
+ ped_free(part);
+ return NULL;
+ }
+
+ // printf("Found unused entry at i=%u\n", i);
+ part->num = i + 1;
+ gpt_disk_data->ptes[i].StartingLBA = part->geom.start;
+ gpt_disk_data->ptes[i].EndingLBA = part->geom.end;
+ uuid_generate(uuid);
+ memcpy(&(gpt_disk_data->ptes[i].UniquePartitionGuid), uuid, sizeof(uuid));
+
+ gpt_disk_data->ptes[i].PartitionTypeGuid = PARTITION_BASIC_DATA_GUID;
+
+ if (fs_type && fs_type->name && !strcmp(fs_type->name, "linux-swap"))
+ gpt_disk_data->ptes[i].PartitionTypeGuid =
+ PARTITION_SWAP_GUID;
+
+
+ gpt_part_data = part->disk_specific =
+ ped_malloc(sizeof(GPTPartitionData));
+ if (!gpt_part_data) return part;
+ memset(gpt_part_data, 0, sizeof(*gpt_part_data));
+
+ gpt_part_data->pte = &(gpt_disk_data->ptes[i]);
+
+ return part;
+}
+
+static void
+gpt_partition_destroy(PedPartition *part)
+{
+ GPTPartitionData *gpt_part_data;
+
+ PED_ASSERT(part != NULL, return);
+ // printf("in gpt_partition_destroy(type=%x)\n", part->type);
+
+ if (part->type != PED_PARTITION_PRIMARY)
+ return;
+
+ PED_ASSERT(part->disk_specific != NULL, return);
+ gpt_part_data = part->disk_specific;
+ if (gpt_part_data->pte)
+ memset(gpt_part_data->pte, 0, sizeof(*(gpt_part_data->pte)));
+
+ ped_free(part->disk_specific);
+ part->disk_specific = NULL;
+ ped_free(part);
+ // printf("returning from gpt_partition_destroy()\n");
+}
+
+/**********************************************************
+ * Allocate metadata partitions for the GPTH and PTES.
+ *
+ */
+static int
+_alloc_metadata_unknown(PedDisk * disk)
+{
+ __u64 pte_reserved_blocks;
+ PED_ASSERT(disk != NULL, return 0);
+ PED_ASSERT(disk->dev != NULL, return 0);
+
+ pte_reserved_blocks =
+ (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+ disk->dev->sector_size);
+
+
+ // printf("in _alloc_metadata_unknown()\n");
+ /* metadata at the start of the disk includes the MBR */
+ // printf("adding metadata at start of the disk.\n");
+ if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+ 0,
+ 1 + 1 + pte_reserved_blocks))
+ return 0;
+
+ /* metadata at the end of the disk */
+ // printf("adding metadata at end of the disk.\n");
+ if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+ LastLBA(disk->dev) -
+ pte_reserved_blocks,
+ 1 + pte_reserved_blocks))
+ return 0;
+
+ return 1;
+}
+
+
+/**********************************************************
+ * Allocate metadata partitions for the GPTH and PTES
+ * when we know the actual metadata size
+ */
+static int
+_alloc_metadata_known(PedDisk * disk)
+{
+ int i;
+ PedSector gptlength, pteslength = 0;
+ GPTDiskData *gpt_disk_data;
+
+ // printf("in _alloc_metadata_known()\n");
+ PED_ASSERT(disk != NULL, return 0);
+ PED_ASSERT(disk->dev != NULL, return 0);
+ PED_ASSERT(disk->disk_specific != NULL, return 0);
+ gpt_disk_data = disk->disk_specific;
+
+ /* allocate space for the header */
+ gptlength = gpt_disk_data->pgpt->HeaderSize / disk->dev->sector_size;
+ if (gpt_disk_data->pgpt->HeaderSize % disk->dev->sector_size)
+ gptlength++;
+ /* allocate space for the ptes */
+ pteslength =
+ (gpt_disk_data->pgpt->NumberOfPartitionEntries *
+ gpt_disk_data->pgpt->SizeOfPartitionEntry) /
+ disk->dev->sector_size;
+ if ((gpt_disk_data->pgpt->NumberOfPartitionEntries *
+ gpt_disk_data->pgpt->SizeOfPartitionEntry) %
+ disk->dev->sector_size)
+ pteslength++;
+
+ /* metadata at the start of the disk includes the MBR */
+ // printf("adding metadata at start of the disk.\n");
+ if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+ 0, 1 + gptlength + pteslength))
+ return 0;
+
+ /* metadata at the end of the disk */
+ // printf("adding metadata at end of the disk.\n");
+ if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+ LastLBA(disk->dev) - gptlength - pteslength + 1,
+ gptlength + pteslength))
+ return 0;
+
+ return 1;
+}
+
+
+
+
+/**********************************************************
+ * Allocate metadata partitions for the GPTH and PTES.
+ *
+ */
+static int
+gpt_alloc_metadata(PedDisk * disk)
+{
+ GPTDiskData *gpt_disk_data;
+ PED_ASSERT(disk != NULL, return 0);
+ PED_ASSERT(disk->dev != NULL, return 0);
+
+ gpt_disk_data = disk->disk_specific;
+
+ if (!gpt_disk_data ||
+ !gpt_disk_data->pgpt ||
+ !gpt_disk_data->agpt ||
+ !gpt_disk_data->ptes)
+ return _alloc_metadata_unknown(disk);
+
+ return _alloc_metadata_known(disk);
+}
+
+/************************************************************
+ * gpt_partition_enumerate()
+ * Requires:
+ * - part
+ * Modifies:
+ * - part->num
+ * Returns:
+ * 1 if valid
+ * 0 on error
+ * Actions:
+ * Does nothing, as the read/new/destroy functions maintain
+ * part->num.
+ *
+ *
+ ************************************************************/
+static int
+gpt_partition_enumerate(PedPartition * part)
+{
+ return 1;
+}
+
+
+/************************************************************
+ * gpt_clobber()
+ * Requires:
+ * - dev
+ * Modifies:
+ * - dev
+ * Returns:
+ * 1 if valid
+ * 0 on error
+ * Actions:
+ * This writes zeros to the PMBR and the primary and
+ * alternate GPTHs and PTEs.
+ ************************************************************/
+static int
+gpt_clobber(PedDevice * dev)
+{
+ LegacyMBR_t pmbr;
+ GuidPartitionTableHeader_t gpt;
+ GuidPartitionEntry_t ptes[GPT_DEFAULT_RESERVED_PARTITION_ENTRIES];
+ __u64 lastLBA, pte_reserved_blocks;
+
+
+ // printf("in gpt_clobber()\n");
+ PED_ASSERT (dev != NULL, return 0);
+ PED_ASSERT (gpt_probe(dev), return 0);
+
+ if (!ped_device_open(dev)) return 0;
+
+ PED_ASSERT(dev->sector_size != 0, return 0);
+ pte_reserved_blocks = GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+ dev->sector_size;
+
+
+ memset(&pmbr, 0, sizeof(pmbr));
+ memset(&gpt, 0, sizeof(gpt));
+ memset(ptes, 0,
+ GPT_DEFAULT_RESERVED_PARTITION_ENTRIES *
+ sizeof(GuidPartitionEntry_t));
+ lastLBA = LastLBA(dev);
+
+ if (!WriteLBA(dev, 0, &pmbr, sizeof(pmbr))) {
+ printf("gpt_clobber(): Unable to write empty PMBR.\n");
+ return 0;
+ }
+ if (!WriteLBA(dev, 1, &gpt, sizeof(gpt))) {
+ printf("gpt_clobber(): Unable to write empty PGPTH.\n");
+ return 0;
+ }
+ if (!WriteLBA(dev, 2, ptes, sizeof(ptes))) {
+ printf("gpt_clobber(): Unable to write empty PPTES.\n");
+ return 0;
+ }
+ if (!WriteLBA(dev, lastLBA-pte_reserved_blocks, ptes,
+ sizeof(ptes))) {
+ printf("gpt_clobber(): Unable to write empty APTES.\n");
+ return 0;
+ }
+ if (!WriteLBA(dev, lastLBA, &gpt, sizeof(gpt))) {
+ printf("gpt_clobber(): Unable to write empty AGPTH.\n");
+ return 0;
+ }
+ return 1;
+}
+
+
+static int
+gpt_partition_set_flag(PedPartition *part,
+ PedPartitionFlag flag,
+ int state)
+{
+ GPTPartitionData *gpt_part_data;
+ PED_ASSERT(part != NULL, return 0);
+ PED_ASSERT(part->disk_specific != NULL, return 0);
+ gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+
+
+ switch (flag) {
+ case PED_PARTITION_RAID:
+ if (state)
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_RAID_GUID;
+ else
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
+ break;
+ case PED_PARTITION_LVM:
+ if (state)
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_LVM_GUID;
+ else
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
+
+ break;
+ case PED_PARTITION_BOOT:
+ if (state)
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_SYSTEM_GUID;
+ else
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
+
+ break;
+ case PED_PARTITION_LBA:
+ if (!state) return 0;
+ break;
+ case PED_PARTITION_HIDDEN:
+ default:
+ return 0;
+ }
+
+ if (part->fs_type && part->fs_type->name &&
+ !strcmp(part->fs_type->name, "linux-swap"))
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_SWAP_GUID;
+
+
+ return 1;
+}
+
+static int
+gpt_partition_get_flag(const PedPartition *part,
+ PedPartitionFlag flag)
+{
+ GPTPartitionData *gpt_part_data = NULL;
+ PED_ASSERT(part->disk_specific != NULL, return 0);
+ gpt_part_data = part->disk_specific;
+
+ switch (flag) {
+ case PED_PARTITION_RAID:
+ return (!efi_guidcmp(gpt_part_data->pte->PartitionTypeGuid,
+ PARTITION_RAID_GUID));
+ case PED_PARTITION_LVM:
+ return (!efi_guidcmp(gpt_part_data->pte->PartitionTypeGuid,
+ PARTITION_LVM_GUID));
+ case PED_PARTITION_BOOT:
+ return (!efi_guidcmp(gpt_part_data->pte->PartitionTypeGuid,
+ PARTITION_SYSTEM_GUID));
+ case PED_PARTITION_LBA:
+ return 1;
+ case PED_PARTITION_HIDDEN:
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static int
+gpt_partition_is_flag_available(const PedPartition * part,
+ PedPartitionFlag flag)
+{
+ switch (flag) {
+ case PED_PARTITION_RAID:
+ case PED_PARTITION_LVM:
+ case PED_PARTITION_LBA:
+ case PED_PARTITION_BOOT:
+ return 1;
+ case PED_PARTITION_HIDDEN:
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static void
+gpt_partition_set_name(PedPartition *part,
+ const char *name)
+{
+ unsigned int i;
+ GPTPartitionData *gpt_part_data = NULL;
+ PED_ASSERT(part->disk_specific != NULL, return);
+ gpt_part_data = part->disk_specific;
+
+ if (!gpt_part_data->pte) return;
+
+ memset(gpt_part_data->pte->PartitionName, 0, sizeof(gpt_part_data->pte->PartitionName));
+
+ for (i=0; i < (72 / sizeof(efi_char16_t)) && i < strlen(name); i++) {
+ gpt_part_data->pte->PartitionName[i] = name[i];
+ }
+ return;
+}
+static const char *
+gpt_partition_get_name (const PedPartition * part)
+{
+ /* The name is stored in Unicode in the GPT entry */
+ char *name;
+ unsigned int i, namelen = (72 / sizeof(efi_char16_t));
+ GPTPartitionData *gpt_part_data = NULL;
+ PED_ASSERT(part->disk_specific != NULL, return 0);
+ gpt_part_data = part->disk_specific;
+
+ if (!gpt_part_data->pte) return NULL;
+
+ name = ped_malloc(namelen);
+ if (!name) return NULL;
+
+ memset(name, 0, namelen);
+
+ for (i=0; i < namelen ; i++) {
+ name[i] = gpt_part_data->pte->PartitionName[i];
+ }
+
+ return name;
+}
+
+
+static int
+gpt_get_max_primary_partition_count(const PedDisk *disk)
+{
+ int rc = GPT_DEFAULT_RESERVED_PARTITION_ENTRIES; /* 128 */
+ GPTDiskData *gpt_disk_data;
+ PED_ASSERT(disk != NULL, return 0);
+ gpt_disk_data = disk->disk_specific;
+
+ if (gpt_disk_data && gpt_disk_data->pgpt)
+ rc = gpt_disk_data->pgpt->NumberOfPartitionEntries;
+ return rc;
+}
+
+/* There are no alignment issues with GPT */
+static int
+gpt_partition_align(PedPartition * part,
+ const PedConstraint * constraint)
+{
+ // printf("in gpt_partition_align()\n");
+ return 1;
+}
+
+static PedDisk *
+gpt_new(PedDisk * disk)
+{
+ // printf("gpt_new(%p)\n", disk);
+ PED_ASSERT(disk != NULL, return NULL);
+ if (disk->disk_specific) return disk;
+
+ disk->disk_specific = ped_malloc(sizeof(GPTDiskData));
+ PED_ASSERT(disk->disk_specific != NULL, return NULL);
+ memset(disk->disk_specific, 0, sizeof(GPTDiskData));
+ return disk;
+}
+
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/fs_ext2/interface.c parted-1.4.7-gpt/libparted/fs_ext2/interface.c
--- parted-1.4.7/libparted/fs_ext2/interface.c Mon Dec 4 13:12:47 2000
+++ parted-1.4.7-gpt/libparted/fs_ext2/interface.c Thu Jan 18 11:45:14 2001
@@ -31,6 +31,7 @@
#include <parted/disk_pc98.h>
#include <parted/disk_mac.h>
#include <parted/disk_bsd.h>
+#include <parted/disk_gpt.h>
#include "ext2.h"
#include "parted_io.h"
@@ -342,6 +343,15 @@
if (strcmp (disk_type->name, BSD_NAME) == 0) {
BSDPartitionData* bsd_data = part->disk_specific;
bsd_data->type = 0x8;
+ return 1;
+ }
+
+ if (strcmp (disk_type->name, GPT_NAME) == 0) {
+ GPTPartitionData *gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data != NULL, return 0);
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
return 1;
}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/fs_fat/fat.c parted-1.4.7-gpt/libparted/fs_fat/fat.c
--- parted-1.4.7/libparted/fs_fat/fat.c Mon Dec 4 13:12:47 2000
+++ parted-1.4.7-gpt/libparted/fs_fat/fat.c Thu Jan 18 11:42:08 2001
@@ -22,6 +22,7 @@
#include <parted/disk_loop.h>
#include <parted/disk_pc98.h>
#include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
#include "fat.h"
#include "calc.h"
@@ -751,6 +752,15 @@
else
strcpy (mac_data->system_name, "FAT");
mac_data->status = 0x33;
+ return 1;
+ }
+
+ if (strcmp (disk_type->name, GPT_NAME) == 0) {
+ GPTPartitionData *gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data != NULL, return 0);
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
return 1;
}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/fs_hfs/hfs.c parted-1.4.7-gpt/libparted/fs_hfs/hfs.c
--- parted-1.4.7/libparted/fs_hfs/hfs.c Fri Jan 5 07:30:56 2001
+++ parted-1.4.7-gpt/libparted/fs_hfs/hfs.c Thu Jan 18 11:44:07 2001
@@ -25,6 +25,7 @@
#include <parted/disk_loop.h>
#include <parted/disk_pc98.h>
#include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
#include <libintl.h>
#if ENABLE_NLS
@@ -151,6 +152,15 @@
strcpy (mac_data->system_name, "Apple_HFS");
mac_data->status |= 0x7f;
}
+ return 1;
+ }
+
+ if (strcmp (disk_type->name, GPT_NAME) == 0) {
+ GPTPartitionData *gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data != NULL, return 0);
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
return 1;
}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/fs_linux_swap/linux_swap.c parted-1.4.7-gpt/libparted/fs_linux_swap/linux_swap.c
--- parted-1.4.7/libparted/fs_linux_swap/linux_swap.c Fri Jan 5 07:31:23 2001
+++ parted-1.4.7-gpt/libparted/fs_linux_swap/linux_swap.c Thu Jan 18 11:24:42 2001
@@ -28,6 +28,7 @@
#include <parted/disk_pc98.h>
#include <parted/disk_mac.h>
#include <parted/disk_bsd.h>
+#include <parted/disk_gpt.h>
#include <libintl.h>
#if ENABLE_NLS
@@ -565,6 +566,15 @@
if (strcmp (disk_type->name, BSD_NAME) == 0) {
BSDPartitionData* bsd_data = part->disk_specific;
bsd_data->type = 0x1;
+ return 1;
+ }
+
+ if (strcmp (disk_type->name, GPT_NAME) == 0) {
+ GPTPartitionData* gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data != NULL, return 0);
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_SWAP_GUID;
return 1;
}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/fs_ntfs/ntfs.c parted-1.4.7-gpt/libparted/fs_ntfs/ntfs.c
--- parted-1.4.7/libparted/fs_ntfs/ntfs.c Fri Jan 5 07:29:47 2001
+++ parted-1.4.7-gpt/libparted/fs_ntfs/ntfs.c Thu Jan 18 11:45:18 2001
@@ -25,6 +25,7 @@
#include <parted/disk_loop.h>
#include <parted/disk_pc98.h>
#include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
#include <libintl.h>
#if ENABLE_NLS
@@ -147,6 +148,15 @@
else
strcpy (mac_data->system_name, "Apple_UNIX_SVR2");
mac_data->status = 0x33;
+ return 1;
+ }
+
+ if (strcmp (disk_type->name, GPT_NAME) == 0) {
+ GPTPartitionData *gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data != NULL, return 0);
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
return 1;
}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/fs_reiserfs/reiserfs.c parted-1.4.7-gpt/libparted/fs_reiserfs/reiserfs.c
--- parted-1.4.7/libparted/fs_reiserfs/reiserfs.c Fri Jan 5 07:30:13 2001
+++ parted-1.4.7-gpt/libparted/fs_reiserfs/reiserfs.c Thu Jan 18 11:42:34 2001
@@ -25,6 +25,7 @@
#include <parted/disk_loop.h>
#include <parted/disk_pc98.h>
#include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
#include <libintl.h>
#if ENABLE_NLS
@@ -181,6 +182,15 @@
else
strcpy (mac_data->system_name, "Apple_UNIX_SVR2");
mac_data->status = 0x33;
+ return 1;
+ }
+
+ if (strcmp (disk_type->name, GPT_NAME) == 0) {
+ GPTPartitionData *gpt_part_data = part->disk_specific;
+ PED_ASSERT(gpt_part_data != NULL, return 0);
+ PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+ gpt_part_data->pte->PartitionTypeGuid =
+ PARTITION_BASIC_DATA_GUID;
return 1;
}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/libparted.c parted-1.4.7-gpt/libparted/libparted.c
--- parted-1.4.7/libparted/libparted.c Thu Jan 11 13:03:16 2001
+++ parted-1.4.7-gpt/libparted/libparted.c Thu Jan 18 11:24:42 2001
@@ -65,6 +65,7 @@
ped_disk_pc98_init ();
ped_disk_mac_init ();
ped_disk_bsd_init ();
+ ped_disk_gpt_init ();
}
static void
@@ -102,6 +103,7 @@
ped_disk_loop_done ();
ped_disk_mac_done ();
ped_disk_bsd_done ();
+ ped_disk_gpt_done ();
}
static void
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/sg_dd.c parted-1.4.7-gpt/libparted/sg_dd.c
--- parted-1.4.7/libparted/sg_dd.c Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/sg_dd.c Thu Jan 18 11:24:42 2001
@@ -0,0 +1,781 @@
+ /*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define _XOPEN_SOURCE 500
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <linux/../scsi/sg.h> /* cope with silly includes */
+#include <linux/major.h>
+typedef unsigned char u_char; /* horrible, for scsi.h */
+#include "sg_err.h"
+
+#if 0
+#include "sg_llseek.h"
+#endif
+
+/* A utility program for the Linux OS SCSI generic ("sg") device driver.
+* Copyright (C) 1999, 2000 D. Gilbert and P. Allworth
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+
+ This program is a specialization of the Unix "dd" command in which
+ either the input or the output file is a scsi generic device or a
+ raw device. The block size ('bs') is assumed to be 512 if not given.
+ This program complains if 'ibs' or 'obs' are given with a value
+ that differs from 'bs' (or the default 512).
+ If 'if' is not given or 'if=-' then stdin is assumed. If 'of' is
+ not given or 'of=-' then stdout assumed. Multipliers:
+ 'c','C' *1 'b','B' *512 'k' *1024 'K' *1000
+ 'm' *(1024^2) 'M' *(1000^2) 'g' *(1024^3) 'G' *(1000^3)
+
+ A non-standard argument "bpt" (blocks per transfer) is added to control
+ the maximum number of blocks in each transfer. The default value is 128.
+ For example if "bs=512" and "bpt=32" then a maximum of 32 blocks (16KB
+ in this case) is transferred to or from the sg device in a single SCSI
+ command.
+
+ This version should compile with Linux sg drivers with version numbers
+ >= 30000 .
+
+ Version 5.11 20001220
+*/
+
+#define DEF_BLOCK_SIZE 512
+#define DEF_BLOCKS_PER_TRANSFER 128
+
+// #define SG_DEBUG
+
+#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define READ_CAP_REPLY_LEN 8
+#define DEF_TIMEOUT 40000 /* 40,000 millisecs == 40 seconds */
+
+#ifndef RAW_MAJOR
+#define RAW_MAJOR 255 /*unlikey value */
+#endif
+
+#define FT_OTHER 0 /* filetype other than sg or raw device */
+#define FT_SG 1 /* filetype is sg char device */
+#define FT_RAW 2 /* filetype is raw char device */
+
+static int sum_of_resids = 0;
+
+static int dd_count = -1;
+static int in_full = 0;
+static int in_partial = 0;
+static int out_full = 0;
+static int out_partial = 0;
+
+static void install_handler (int sig_num, void (*sig_handler) (int sig))
+{
+ struct sigaction sigact;
+ sigaction (sig_num, NULL, &sigact);
+ if (sigact.sa_handler != SIG_IGN)
+ {
+ sigact.sa_handler = sig_handler;
+ sigemptyset (&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigaction (sig_num, &sigact, NULL);
+ }
+}
+
+static void print_stats()
+{
+ if (0 != dd_count)
+ fprintf(stderr, " remaining block count=%d\n", dd_count);
+ fprintf(stderr, "%d+%d records in\n", in_full, in_partial);
+ fprintf(stderr, "%d+%d records out\n", out_full, out_partial);
+}
+
+static void interrupt_handler(int sig)
+{
+ struct sigaction sigact;
+
+ sigact.sa_handler = SIG_DFL;
+ sigemptyset (&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigaction (sig, &sigact, NULL);
+ fprintf(stderr, "Interrupted by signal,");
+ print_stats ();
+ kill (getpid (), sig);
+}
+
+static void siginfo_handler(int sig)
+{
+ fprintf(stderr, "Progress report, continuing ...\n");
+ print_stats ();
+}
+
+static int dd_filetype(const char * filename)
+{
+ struct stat st;
+
+ if (stat(filename, &st) < 0)
+ return FT_OTHER;
+ if (S_ISCHR(st.st_mode)) {
+ if (RAW_MAJOR == major(st.st_rdev))
+ return FT_RAW;
+ else if (SCSI_GENERIC_MAJOR == major(st.st_rdev))
+ return FT_SG;
+ }
+ return FT_OTHER;
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: "
+ "sg_dd [if=<infile>] [skip=<n>] [of=<ofile>] [seek=<n>]\n"
+ " [bs=<num>] [bpt=<num>] [count=<n>]"
+ " [dio=<n>]\n"
+ " either 'if' or 'of' must be a sg or raw device\n"
+ " 'bpt' is blocks_per_transfer (default is 128)\n"
+ " 'dio' is direct IO, 1->attempt, 0->indirect IO (def)\n");
+}
+
+/* Return of 0 -> success, -1 -> failure, 2 -> try again */
+static int read_capacity(int sg_fd, int * num_sect, int * sect_sz)
+{
+ int res;
+ unsigned char rcCmdBlk [10] = {0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char rcBuff[READ_CAP_REPLY_LEN];
+ unsigned char sense_b[64];
+ sg_io_hdr_t io_hdr;
+
+ memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = sizeof(rcCmdBlk);
+ io_hdr.mx_sb_len = sizeof(sense_b);
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = sizeof(rcBuff);
+ io_hdr.dxferp = rcBuff;
+ io_hdr.cmdp = rcCmdBlk;
+ io_hdr.sbp = sense_b;
+ io_hdr.timeout = DEF_TIMEOUT;
+
+ if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
+ perror("read_capacity (SG_IO) error");
+ return -1;
+ }
+ res = sg_err_category3(&io_hdr);
+ if (SG_ERR_CAT_MEDIA_CHANGED == res)
+ return 2; /* probably have another go ... */
+ else if (SG_ERR_CAT_CLEAN != res) {
+ sg_chk_n_print3("read capacity", &io_hdr);
+ return -1;
+ }
+ *num_sect = 1 + ((rcBuff[0] << 24) | (rcBuff[1] << 16) |
+ (rcBuff[2] << 8) | rcBuff[3]);
+ *sect_sz = (rcBuff[4] << 24) | (rcBuff[5] << 16) |
+ (rcBuff[6] << 8) | rcBuff[7];
+ return 0;
+}
+
+/* -1 -> unrecoverable error, 0 -> successful, 1 -> recoverable (ENOMEM),
+ 2 -> try again */
+int sg_read(int sg_fd, unsigned char * buff, unsigned int blocks, unsigned int from_block,
+ int bs, int * diop)
+{
+ unsigned char rdCmd[10] = {0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char senseBuff[SENSE_BUFF_LEN];
+ sg_io_hdr_t io_hdr;
+ int res;
+
+ rdCmd[2] = (unsigned char)((from_block >> 24) & 0xFF);
+ rdCmd[3] = (unsigned char)((from_block >> 16) & 0xFF);
+ rdCmd[4] = (unsigned char)((from_block >> 8) & 0xFF);
+ rdCmd[5] = (unsigned char)(from_block & 0xFF);
+ rdCmd[7] = (unsigned char)((blocks >> 8) & 0xff);
+ rdCmd[8] = (unsigned char)(blocks & 0xff);
+
+ memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = sizeof(rdCmd);
+ io_hdr.cmdp = rdCmd;
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = bs * blocks;
+ io_hdr.dxferp = buff;
+ io_hdr.mx_sb_len = SENSE_BUFF_LEN;
+ io_hdr.sbp = senseBuff;
+ io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.pack_id = from_block;
+ if (diop && *diop)
+ io_hdr.flags |= SG_FLAG_DIRECT_IO;
+
+ while (((res = write(sg_fd, &io_hdr, sizeof(io_hdr))) < 0) &&
+ (EINTR == errno))
+ ;
+ if (res < 0) {
+ if (ENOMEM == errno)
+ return 1;
+ perror("reading (wr) on sg device, error");
+ return -1;
+ }
+
+ while (((res = read(sg_fd, &io_hdr, sizeof(io_hdr))) < 0) &&
+ (EINTR == errno))
+ ;
+ if (res < 0) {
+ perror("reading (rd) on sg device, error");
+ return -1;
+ }
+ switch (sg_err_category3(&io_hdr)) {
+ case SG_ERR_CAT_CLEAN:
+ break;
+ case SG_ERR_CAT_RECOVERED:
+ fprintf(stderr, "Recovered error while reading block=%d, num=%d\n",
+ from_block, blocks);
+ break;
+ case SG_ERR_CAT_MEDIA_CHANGED:
+ return 2;
+ default:
+ sg_chk_n_print3("reading", &io_hdr);
+ return -1;
+ }
+ if (diop && *diop &&
+ ((io_hdr.info & SG_INFO_DIRECT_IO_MASK) != SG_INFO_DIRECT_IO))
+ *diop = 0; /* flag that dio not done (completely) */
+ sum_of_resids += io_hdr.resid;
+#if SG_DEBUG
+ fprintf(stderr, "duration=%u ms\n", io_hdr.duration);
+#endif
+ return 0;
+}
+
+/* -1 -> unrecoverable error, 0 -> successful, 1 -> recoverable (ENOMEM),
+ 2 -> try again */
+int sg_write(int sg_fd, unsigned char * buff, unsigned int blocks, unsigned int to_block,
+ int bs, int * diop)
+{
+ unsigned char wrCmd[10] = {0x2a, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char senseBuff[SENSE_BUFF_LEN];
+ sg_io_hdr_t io_hdr;
+ int res;
+
+ wrCmd[2] = (unsigned char)((to_block >> 24) & 0xFF);
+ wrCmd[3] = (unsigned char)((to_block >> 16) & 0xFF);
+ wrCmd[4] = (unsigned char)((to_block >> 8) & 0xFF);
+ wrCmd[5] = (unsigned char)(to_block & 0xFF);
+ wrCmd[7] = (unsigned char)((blocks >> 8) & 0xff);
+ wrCmd[8] = (unsigned char)(blocks & 0xff);
+
+ memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = sizeof(wrCmd);
+ io_hdr.cmdp = wrCmd;
+ io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
+ io_hdr.dxfer_len = bs * blocks;
+ io_hdr.dxferp = buff;
+ io_hdr.mx_sb_len = SENSE_BUFF_LEN;
+ io_hdr.sbp = senseBuff;
+ io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.pack_id = to_block;
+ if (diop && *diop)
+ io_hdr.flags |= SG_FLAG_DIRECT_IO;
+
+ while (((res = write(sg_fd, &io_hdr, sizeof(io_hdr))) < 0) &&
+ (EINTR == errno))
+ ;
+ if (res < 0) {
+ if (ENOMEM == errno)
+ return 1;
+ perror("writing (wr) on sg device, error");
+ return -1;
+ }
+
+ while (((res = read(sg_fd, &io_hdr, sizeof(io_hdr))) < 0) &&
+ (EINTR == errno))
+ ;
+ if (res < 0) {
+ perror("writing (rd) on sg device, error");
+ return -1;
+ }
+ switch (sg_err_category3(&io_hdr)) {
+ case SG_ERR_CAT_CLEAN:
+ break;
+ case SG_ERR_CAT_RECOVERED:
+ fprintf(stderr, "Recovered error while writing block=%d, num=%d\n",
+ to_block, blocks);
+ break;
+ case SG_ERR_CAT_MEDIA_CHANGED:
+ return 2;
+ default:
+ sg_chk_n_print3("writing", &io_hdr);
+ return -1;
+ }
+ if (diop && *diop &&
+ ((io_hdr.info & SG_INFO_DIRECT_IO_MASK) != SG_INFO_DIRECT_IO))
+ *diop = 0; /* flag that dio not done (completely) */
+ return 0;
+}
+
+static int get_num(char * buf)
+{
+ int res, num;
+ char c;
+
+ res = sscanf(buf, "%d%c", &num, &c);
+ if (0 == res)
+ return -1;
+ else if (1 == res)
+ return num;
+ else {
+ switch (c) {
+ case 'c':
+ case 'C':
+ return num;
+ case 'b':
+ case 'B':
+ return num * 512;
+ case 'k':
+ return num * 1024;
+ case 'K':
+ return num * 1000;
+ case 'm':
+ return num * 1024 * 1024;
+ case 'M':
+ return num * 1000000;
+ case 'g':
+ return num * 1024 * 1024 * 1024;
+ case 'G':
+ return num * 1000000000;
+ default:
+ fprintf(stderr, "unrecognized multiplier\n");
+ return -1;
+ }
+ }
+}
+
+#if 0
+static int sg_dd_main(int argc, char * argv[])
+{
+ int skip = 0;
+ int seek = 0;
+ int bs = 0;
+ int ibs = 0;
+ int obs = 0;
+ int bpt = DEF_BLOCKS_PER_TRANSFER;
+ char str[512];
+ char * key;
+ char * buf;
+ char inf[512];
+ int in_type = FT_OTHER;
+ char outf[512];
+ int out_type = FT_OTHER;
+ int dio = 0;
+ int dio_incomplete = 0;
+ int res, k, t, buf_sz, dio_tmp;
+ int infd, outfd, blocks;
+ unsigned char * wrkBuff;
+ unsigned char * wrkPos;
+ int in_num_sect = 0;
+ int out_num_sect = 0;
+ int in_sect_sz, out_sect_sz;
+ char ebuff[256];
+ int blocks_per;
+
+ inf[0] = '\0';
+ outf[0] = '\0';
+ if (argc < 2) {
+ usage();
+ return 1;
+ }
+
+ for(k = 1; k < argc; k++) {
+ if (argv[k])
+ strcpy(str, argv[k]);
+ else
+ continue;
+ for(key = str, buf = key; *buf && *buf != '=';)
+ buf++;
+ if (*buf)
+ *buf++ = '\0';
+ if (strcmp(key,"if") == 0)
+ strcpy(inf, buf);
+ else if (strcmp(key,"of") == 0)
+ strcpy(outf, buf);
+ else if (0 == strcmp(key,"ibs"))
+ ibs = get_num(buf);
+ else if (0 == strcmp(key,"obs"))
+ obs = get_num(buf);
+ else if (0 == strcmp(key,"bs"))
+ bs = get_num(buf);
+ else if (0 == strcmp(key,"bpt"))
+ bpt = get_num(buf);
+ else if (0 == strcmp(key,"skip"))
+ skip = get_num(buf);
+ else if (0 == strcmp(key,"seek"))
+ seek = get_num(buf);
+ else if (0 == strcmp(key,"count"))
+ dd_count = get_num(buf);
+ else if (0 == strcmp(key,"dio"))
+ dio = get_num(buf);
+ else {
+ fprintf(stderr, "Unrecognized argument '%s'\n", key);
+ usage();
+ return 1;
+ }
+ }
+ if (bs <= 0) {
+ bs = DEF_BLOCK_SIZE;
+ fprintf(stderr, "Assume default 'bs' (block size) of %d bytes\n", bs);
+ }
+ if ((ibs && (ibs != bs)) || (obs && (obs != bs))) {
+ fprintf(stderr, "If 'ibs' or 'obs' given must be same as 'bs'\n");
+ usage();
+ return 1;
+ }
+ if ((skip < 0) || (seek < 0)) {
+ fprintf(stderr, "skip and seek cannot be negative\n");
+ return 1;
+ }
+#ifdef SG_DEBUG
+ fprintf(stderr, "sg_dd: if=%s skip=%d of=%s seek=%d count=%d\n",
+ inf, skip, outf, seek, dd_count);
+#endif
+ install_handler (SIGINT, interrupt_handler);
+ install_handler (SIGQUIT, interrupt_handler);
+ install_handler (SIGPIPE, interrupt_handler);
+ install_handler (SIGUSR1, siginfo_handler);
+
+ infd = STDIN_FILENO;
+ outfd = STDOUT_FILENO;
+ if (inf[0] && ('-' != inf[0])) {
+ in_type = dd_filetype(inf);
+
+ if (FT_SG == in_type) {
+ if ((infd = open(inf, O_RDWR)) < 0) {
+ sprintf(ebuff, "sg_dd: could not open %s for sg reading", inf);
+ perror(ebuff);
+ return 1;
+ }
+ t = bs * bpt;
+ res = ioctl(infd, SG_SET_RESERVED_SIZE, &t);
+ if (res < 0)
+ perror("sg_dd: SG_SET_RESERVED_SIZE error");
+ res = ioctl(infd, SG_GET_VERSION_NUM, &t);
+ if ((res < 0) || (t < 30000)) {
+ fprintf(stderr, "sg_dd: sg driver prior to 3.x.y\n");
+ return 1;
+ }
+ }
+ if (FT_SG != in_type) {
+ if ((infd = open(inf, O_RDONLY)) < 0) {
+ sprintf(ebuff, "sg_dd: could not open %s for reading", inf);
+ perror(ebuff);
+ return 1;
+ }
+ else if (skip > 0) {
+ llse_loff_t offset = skip;
+
+ offset *= bs; /* could exceed 32 bits here! */
+ if (llse_llseek(infd, offset, SEEK_SET) < 0) {
+ sprintf(ebuff,
+ "sg_dd: couldn't skip to required position on %s", inf);
+ perror(ebuff);
+ return 1;
+ }
+ }
+ }
+ }
+
+ if (outf[0] && ('-' != outf[0])) {
+ out_type = dd_filetype(outf);
+
+ if (FT_SG == out_type) {
+ if ((outfd = open(outf, O_RDWR)) < 0) {
+ sprintf(ebuff, "sg_dd: could not open %s for sg writing", outf);
+ perror(ebuff);
+ return 1;
+ }
+ t = bs * bpt;
+ res = ioctl(outfd, SG_SET_RESERVED_SIZE, &t);
+ if (res < 0)
+ perror("sg_dd: SG_SET_RESERVED_SIZE error");
+ res = ioctl(outfd, SG_GET_VERSION_NUM, &t);
+ if ((res < 0) || (t < 30000)) {
+ fprintf(stderr, "sg_dd: sg driver prior to 3.x.y\n");
+ return 1;
+ }
+ }
+ else {
+ if (FT_OTHER == out_type) {
+ if ((outfd = open(outf, O_WRONLY | O_CREAT, 0666)) < 0) {
+ sprintf(ebuff,
+ "sg_dd: could not open %s for writing", outf);
+ perror(ebuff);
+ return 1;
+ }
+ }
+ else {
+ if ((outfd = open(outf, O_WRONLY)) < 0) {
+ sprintf(ebuff,
+ "sg_dd: could not open %s for raw writing", outf);
+ perror(ebuff);
+ return 1;
+ }
+ }
+ if (seek > 0) {
+ llse_loff_t offset = seek;
+
+ offset *= bs; /* could exceed 32 bits here! */
+ if (llse_llseek(outfd, offset, SEEK_SET) < 0) {
+ sprintf(ebuff,
+ "sg_dd: couldn't seek to required position on %s", outf);
+ perror(ebuff);
+ return 1;
+ }
+ }
+ }
+ }
+ if ((STDIN_FILENO == infd) && (STDOUT_FILENO == outfd)) {
+ fprintf(stderr,
+ "Can't have both 'if' as stdin _and_ 'of' as stdout\n");
+ return 1;
+ }
+#if 1
+ if ((FT_OTHER == in_type) && (FT_OTHER == out_type)) {
+ fprintf(stderr, "Both 'if' and 'of' can't be ordinary files\n");
+ return 1;
+ }
+#endif
+ if (0 == dd_count)
+ return 0;
+ else if (dd_count < 0) {
+ if (FT_SG == in_type) {
+ res = read_capacity(infd, &in_num_sect, &in_sect_sz);
+ if (2 == res) {
+ fprintf(stderr,
+ "Unit attention, media changed(in), try again\n");
+ res = read_capacity(infd, &in_num_sect, &in_sect_sz);
+ }
+ if (0 != res) {
+ fprintf(stderr, "Unable to read capacity on %s\n", inf);
+ in_num_sect = -1;
+ }
+ else {
+#if 0
+ if (0 == in_sect_sz)
+ in_sect_sz = bs;
+ else if (in_sect_sz > bs)
+ in_num_sect *= (in_sect_sz / bs);
+ else if (in_sect_sz < bs)
+ in_num_sect /= (bs / in_sect_sz);
+#endif
+ if (in_num_sect > skip)
+ in_num_sect -= skip;
+ }
+ }
+ if (FT_SG == out_type) {
+ res = read_capacity(outfd, &out_num_sect, &out_sect_sz);
+ if (2 == res) {
+ fprintf(stderr,
+ "Unit attention, media changed(out), try again\n");
+ res = read_capacity(outfd, &out_num_sect, &out_sect_sz);
+ }
+ if (0 != res) {
+ fprintf(stderr, "Unable to read capacity on %s\n", outf);
+ out_num_sect = -1;
+ }
+ else {
+ if (out_num_sect > seek)
+ out_num_sect -= seek;
+ }
+ }
+#ifdef SG_DEBUG
+ fprintf(stderr,
+ "Start of loop, count=%d, in_num_sect=%d, out_num_sect=%d\n",
+ dd_count, in_num_sect, out_num_sect);
+#endif
+ if (in_num_sect > 0) {
+ if (out_num_sect > 0)
+ dd_count = (in_num_sect > out_num_sect) ? out_num_sect :
+ in_num_sect;
+ else
+ dd_count = in_num_sect;
+ }
+ else
+ dd_count = out_num_sect;
+ }
+ if (dd_count <= 0) {
+ fprintf(stderr, "Couldn't calculate count, please give one\n");
+ return 1;
+ }
+
+ if (dio || (FT_RAW == in_type) || (FT_RAW == out_type)) {
+ size_t psz = getpagesize();
+ wrkBuff = malloc(bs * bpt + psz);
+ if (0 == wrkBuff) {
+ fprintf(stderr, "Not enough user memory for raw\n");
+ return 1;
+ }
+ wrkPos = (unsigned char *)(((unsigned long)wrkBuff + psz - 1) &
+ (~(psz - 1)));
+ }
+ else {
+ wrkBuff = malloc(bs * bpt);
+ if (0 == wrkBuff) {
+ fprintf(stderr, "Not enough user memory\n");
+ return 1;
+ }
+ wrkPos = wrkBuff;
+ }
+
+ blocks_per = bpt;
+#ifdef SG_DEBUG
+ fprintf(stderr, "Start of loop, count=%d, blocks_per=%d\n",
+ dd_count, blocks_per);
+#endif
+ while (dd_count > 0) {
+ blocks = (dd_count > blocks_per) ? blocks_per : dd_count;
+ if (FT_SG == in_type) {
+ dio_tmp = dio;
+ res = sg_read(infd, wrkPos, blocks, skip, bs, &dio_tmp);
+ if (1 == res) { /* ENOMEM, find what's available+try that */
+ if (ioctl(infd, SG_GET_RESERVED_SIZE, &buf_sz) < 0) {
+ perror("RESERVED_SIZE ioctls failed");
+ break;
+ }
+ blocks_per = (buf_sz + bs - 1) / bs;
+ blocks = blocks_per;
+ fprintf(stderr,
+ "Reducing read to %d blocks per loop\n", blocks_per);
+ res = sg_read(infd, wrkPos, blocks, skip, bs, &dio_tmp);
+ }
+ else if (2 == res) {
+ fprintf(stderr,
+ "Unit attention, media changed, try again (r)\n");
+ res = sg_read(infd, wrkPos, blocks, skip, bs, &dio_tmp);
+ }
+ if (0 != res) {
+ fprintf(stderr, "sg_read failed, skip=%d\n", skip);
+ break;
+ }
+ else {
+ in_full += blocks;
+ if (dio && (0 == dio_tmp))
+ dio_incomplete++;
+ }
+ }
+ else {
+ while (((res = read(infd, wrkPos, blocks * bs)) < 0) &&
+ (EINTR == errno))
+ ;
+ if (res < 0) {
+ sprintf(ebuff, "sg_dd: reading, skip=%d ", skip);
+ perror(ebuff);
+ break;
+ }
+ else if (res < blocks * bs) {
+ dd_count = 0;
+ blocks = res / bs;
+ if ((res % bs) > 0) {
+ blocks++;
+ in_partial++;
+ }
+ }
+ in_full += blocks;
+ }
+
+ if (FT_SG == out_type) {
+ dio_tmp = dio;
+ res = sg_write(outfd, wrkPos, blocks, seek, bs, &dio_tmp);
+ if (1 == res) { /* ENOMEM, find what's available+try that */
+ if (ioctl(outfd, SG_GET_RESERVED_SIZE, &buf_sz) < 0) {
+ perror("RESERVED_SIZE ioctls failed");
+ break;
+ }
+ blocks_per = (buf_sz + bs - 1) / bs;
+ blocks = blocks_per;
+ fprintf(stderr,
+ "Reducing write to %d blocks per loop\n", blocks);
+ res = sg_write(outfd, wrkPos, blocks, seek, bs, &dio_tmp);
+ }
+ else if (2 == res) {
+ fprintf(stderr,
+ "Unit attention, media changed, try again (w)\n");
+ res = sg_write(outfd, wrkPos, blocks, seek, bs, &dio_tmp);
+ }
+ else if (0 != res) {
+ fprintf(stderr, "sg_write failed, seek=%d\n", seek);
+ break;
+ }
+ else {
+ out_full += blocks;
+ if (dio && (0 == dio_tmp))
+ dio_incomplete++;
+ }
+ }
+ else {
+ while (((res = write(outfd, wrkPos, blocks * bs)) < 0)
+ && (EINTR == errno))
+ ;
+ if (res < 0) {
+ sprintf(ebuff, "sg_dd: writing, seek=%d ", seek);
+ perror(ebuff);
+ break;
+ }
+ else if (res < blocks * bs) {
+ fprintf(stderr, "output file probably full, seek=%d ", seek);
+ blocks = res / bs;
+ out_full += blocks;
+ if ((res % bs) > 0)
+ out_partial++;
+ break;
+ }
+ else
+ out_full += blocks;
+ }
+ if (dd_count > 0)
+ dd_count -= blocks;
+ skip += blocks;
+ seek += blocks;
+ }
+
+ free(wrkBuff);
+ if (STDIN_FILENO != infd)
+ close(infd);
+ if (STDOUT_FILENO != outfd)
+ close(outfd);
+ res = 0;
+ if (0 != dd_count) {
+ fprintf(stderr, "Some error occurred,");
+ res = 2;
+ }
+ print_stats();
+ if (dio_incomplete)
+ fprintf(stderr, ">> Direct IO requested but incomplete %d times\n",
+ dio_incomplete);
+ if (sum_of_resids)
+ fprintf(stderr, ">> Non-zero sum of residual counts=%d\n",
+ sum_of_resids);
+ return res;
+}
+#endif
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/sg_dd.h parted-1.4.7-gpt/libparted/sg_dd.h
--- parted-1.4.7/libparted/sg_dd.h Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/sg_dd.h Thu Jan 18 11:24:42 2001
@@ -0,0 +1,23 @@
+ /*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+int sg_write(int sg_fd, unsigned char * buff, unsigned int blocks, unsigned int to_block,
+ int bs, int * diop);
+int sg_read(int sg_fd, unsigned char * buff, unsigned int blocks, unsigned int from_block,
+ int bs, int * diop);
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/sg_err.c parted-1.4.7-gpt/libparted/sg_err.c
--- parted-1.4.7/libparted/sg_err.c Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/sg_err.c Thu Jan 18 11:24:42 2001
@@ -0,0 +1,648 @@
+ /*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "sg_err.h"
+
+/* This file is a huge cut, paste and hack from linux/drivers/scsi/constant.c
+* which I guess was written by:
+* Copyright (C) 1993, 1994, 1995 Eric Youngdale
+
+* The rest of this is:
+* Copyright (C) 1999 D. Gilbert
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* ASCII values for a number of symbolic constants, printing functions, etc.
+*
+* Some of the tables have been updated for SCSI 2.
+*
+* Version 0.83 (991208)
+*/
+
+
+static const unsigned char scsi_command_size[8] = { 6, 10, 10, 12,
+ 12, 12, 10, 10 };
+
+#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
+
+static const char unknown[] = "UNKNOWN";
+
+static const char * group_0_commands[] = {
+/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
+/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
+/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
+/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
+/* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve",
+/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit",
+/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic",
+/* 1e-1f */ "Prevent/Allow Medium Removal", unknown,
+};
+
+
+static const char *group_1_commands[] = {
+/* 20-22 */ unknown, unknown, unknown,
+/* 23-28 */ unknown, "Define window parameters", "Read Capacity",
+ unknown, unknown, "Read (10)",
+/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase",
+ "Read updated block",
+/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal",
+/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position",
+/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data",
+/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer",
+ "Read Buffer",
+/* 3d-3f */ "Update Block", "Read Long", "Write Long",
+};
+
+static const char *group_2_commands[] = {
+/* 40-41 */ "Change Definition", "Write Same",
+/* 42-48 */ "Read sub-channel", "Read TOC", "Read header",
+ "Play audio (10)", unknown, "Play audio msf",
+ "Play audio track/index",
+/* 49-4f */ "Play track relative (10)", unknown, "Pause/resume",
+ "Log Select", "Log Sense", unknown, unknown,
+/* 50-55 */ unknown, unknown, unknown, unknown, unknown, "Mode Select (10)",
+/* 56-5b */ unknown, unknown, unknown, unknown, "Mode Sense (10)", unknown,
+/* 5c-5f */ unknown, unknown, unknown,
+};
+
+
+/* The following are 12 byte commands in group 5 */
+static const char *group_5_commands[] = {
+/* a0-a5 */ unknown, unknown, unknown, unknown, unknown,
+ "Move medium/play audio(12)",
+/* a6-a9 */ "Exchange medium", unknown, "Read(12)", "Play track relative(12)",
+/* aa-ae */ "Write(12)", unknown, "Erase(12)", unknown,
+ "Write and verify(12)",
+/* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
+/* b2-b4 */ "Search data low(12)", "Set limits(12)", unknown,
+/* b5-b6 */ "Request volume element address", "Send volume tag",
+/* b7-b9 */ "Read defect data(12)", "Read element status", unknown,
+/* ba-bf */ unknown, unknown, unknown, unknown, unknown, unknown,
+};
+
+
+
+
+#define group(opcode) (((opcode) >> 5) & 7)
+
+#define RESERVED_GROUP 0
+#define VENDOR_GROUP 1
+
+static const char **commands[] = {
+ group_0_commands, group_1_commands, group_2_commands,
+ (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP,
+ group_5_commands, (const char **) VENDOR_GROUP,
+ (const char **) VENDOR_GROUP
+};
+
+static const char reserved[] = "RESERVED";
+static const char vendor[] = "VENDOR SPECIFIC";
+
+static void print_opcode(int opcode) {
+ const char **table = commands[ group(opcode) ];
+ switch ((unsigned long) table) {
+ case RESERVED_GROUP:
+ printf("%s(0x%02x) ", reserved, opcode);
+ break;
+ case VENDOR_GROUP:
+ printf("%s(0x%02x) ", vendor, opcode);
+ break;
+ default:
+ if (table[opcode & 0x1f] != unknown)
+ printf("%s ",table[opcode & 0x1f]);
+ else
+ printf("%s(0x%02x) ", unknown, opcode);
+ break;
+ }
+}
+
+void sg_print_command (const unsigned char * command) {
+ int i,s;
+ print_opcode(command[0]);
+ for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
+ printf("%02x ", command[i]);
+ printf("\n");
+}
+
+static const char * statuses[] = {
+/* 0-4 */ "Good", "Check Condition", "Condition Met", unknown, "Busy",
+/* 5-9 */ unknown, unknown, unknown, "Intermediate", unknown,
+/* a-c */ "Intermediate-Condition Met", unknown, "Reservation Conflict",
+/* d-10 */ unknown, unknown, unknown, unknown,
+/* 11-14 */ "Command Terminated", unknown, unknown, "Queue Full",
+/* 15-1a */ unknown, unknown, unknown, unknown, unknown, unknown,
+/* 1b-1f */ unknown, unknown, unknown, unknown, unknown,
+};
+
+void sg_print_status (int masked_status) {
+ /* status = (status >> 1) & 0xf; */ /* already done */
+ printf("%s ",statuses[masked_status]);
+}
+
+#define D 0x001 /* DIRECT ACCESS DEVICE (disk) */
+#define T 0x002 /* SEQUENTIAL ACCESS DEVICE (tape) */
+#define L 0x004 /* PRINTER DEVICE */
+#define P 0x008 /* PROCESSOR DEVICE */
+#define W 0x010 /* WRITE ONCE READ MULTIPLE DEVICE */
+#define R 0x020 /* READ ONLY (CD-ROM) DEVICE */
+#define S 0x040 /* SCANNER DEVICE */
+#define O 0x080 /* OPTICAL MEMORY DEVICE */
+#define M 0x100 /* MEDIA CHANGER DEVICE */
+#define C 0x200 /* COMMUNICATION DEVICE */
+
+struct error_info{
+ unsigned char code1, code2;
+ unsigned short int devices;
+ const char * text;
+};
+
+struct error_info2{
+ unsigned char code1, code2_min, code2_max;
+ unsigned short int devices;
+ const char * text;
+};
+
+static struct error_info2 additional2[] =
+{
+ {0x40,0x00,0x7f,D,"Ram failure (%x)"},
+ {0x40,0x80,0xff,D|T|L|P|W|R|S|O|M|C,"Diagnostic failure on component (%x)"},
+ {0x41,0x00,0xff,D,"Data path failure (%x)"},
+ {0x42,0x00,0xff,D,"Power-on or self-test failure (%x)"},
+ {0, 0, 0, 0, NULL}
+};
+
+static struct error_info additional[] =
+{
+ {0x00,0x01,T,"Filemark detected"},
+ {0x00,0x02,T|S,"End-of-partition/medium detected"},
+ {0x00,0x03,T,"Setmark detected"},
+ {0x00,0x04,T|S,"Beginning-of-partition/medium detected"},
+ {0x00,0x05,T|S,"End-of-data detected"},
+ {0x00,0x06,D|T|L|P|W|R|S|O|M|C,"I/O process terminated"},
+ {0x00,0x11,R,"Audio play operation in progress"},
+ {0x00,0x12,R,"Audio play operation paused"},
+ {0x00,0x13,R,"Audio play operation successfully completed"},
+ {0x00,0x14,R,"Audio play operation stopped due to error"},
+ {0x00,0x15,R,"No current audio status to return"},
+ {0x01,0x00,D|W|O,"No index/sector signal"},
+ {0x02,0x00,D|W|R|O|M,"No seek complete"},
+ {0x03,0x00,D|T|L|W|S|O,"Peripheral device write fault"},
+ {0x03,0x01,T,"No write current"},
+ {0x03,0x02,T,"Excessive write errors"},
+ {0x04,0x00,D|T|L|P|W|R|S|O|M|C,
+ "Logical unit not ready, cause not reportable"},
+ {0x04,0x01,D|T|L|P|W|R|S|O|M|C,
+ "Logical unit is in process of becoming ready"},
+ {0x04,0x02,D|T|L|P|W|R|S|O|M|C,
+ "Logical unit not ready, initializing command required"},
+ {0x04,0x03,D|T|L|P|W|R|S|O|M|C,
+ "Logical unit not ready, manual intervention required"},
+ {0x04,0x04,D|T|L|O,"Logical unit not ready, format in progress"},
+ {0x05,0x00,D|T|L|W|R|S|O|M|C,"Logical unit does not respond to selection"},
+ {0x06,0x00,D|W|R|O|M,"No reference position found"},
+ {0x07,0x00,D|T|L|W|R|S|O|M,"Multiple peripheral devices selected"},
+ {0x08,0x00,D|T|L|W|R|S|O|M|C,"Logical unit communication failure"},
+ {0x08,0x01,D|T|L|W|R|S|O|M|C,"Logical unit communication time-out"},
+ {0x08,0x02,D|T|L|W|R|S|O|M|C,"Logical unit communication parity error"},
+ {0x09,0x00,D|T|W|R|O,"Track following error"},
+ {0x09,0x01,W|R|O,"Tracking servo failure"},
+ {0x09,0x02,W|R|O,"Focus servo failure"},
+ {0x09,0x03,W|R|O,"Spindle servo failure"},
+ {0x0A,0x00,D|T|L|P|W|R|S|O|M|C,"Error log overflow"},
+ {0x0C,0x00,T|S,"Write error"},
+ {0x0C,0x01,D|W|O,"Write error recovered with auto reallocation"},
+ {0x0C,0x02,D|W|O,"Write error - auto reallocation failed"},
+ {0x10,0x00,D|W|O,"Id crc or ecc error"},
+ {0x11,0x00,D|T|W|R|S|O,"Unrecovered read error"},
+ {0x11,0x01,D|T|W|S|O,"Read retries exhausted"},
+ {0x11,0x02,D|T|W|S|O,"Error too long to correct"},
+ {0x11,0x03,D|T|W|S|O,"Multiple read errors"},
+ {0x11,0x04,D|W|O,"Unrecovered read error - auto reallocate failed"},
+ {0x11,0x05,W|R|O,"L-ec uncorrectable error"},
+ {0x11,0x06,W|R|O,"Circ unrecovered error"},
+ {0x11,0x07,W|O,"Data resynchronization error"},
+ {0x11,0x08,T,"Incomplete block read"},
+ {0x11,0x09,T,"No gap found"},
+ {0x11,0x0A,D|T|O,"Miscorrected error"},
+ {0x11,0x0B,D|W|O,"Unrecovered read error - recommend reassignment"},
+ {0x11,0x0C,D|W|O,"Unrecovered read error - recommend rewrite the data"},
+ {0x12,0x00,D|W|O,"Address mark not found for id field"},
+ {0x13,0x00,D|W|O,"Address mark not found for data field"},
+ {0x14,0x00,D|T|L|W|R|S|O,"Recorded entity not found"},
+ {0x14,0x01,D|T|W|R|O,"Record not found"},
+ {0x14,0x02,T,"Filemark or setmark not found"},
+ {0x14,0x03,T,"End-of-data not found"},
+ {0x14,0x04,T,"Block sequence error"},
+ {0x15,0x00,D|T|L|W|R|S|O|M,"Random positioning error"},
+ {0x15,0x01,D|T|L|W|R|S|O|M,"Mechanical positioning error"},
+ {0x15,0x02,D|T|W|R|O,"Positioning error detected by read of medium"},
+ {0x16,0x00,D|W|O,"Data synchronization mark error"},
+ {0x17,0x00,D|T|W|R|S|O,"Recovered data with no error correction applied"},
+ {0x17,0x01,D|T|W|R|S|O,"Recovered data with retries"},
+ {0x17,0x02,D|T|W|R|O,"Recovered data with positive head offset"},
+ {0x17,0x03,D|T|W|R|O,"Recovered data with negative head offset"},
+ {0x17,0x04,W|R|O,"Recovered data with retries and/or circ applied"},
+ {0x17,0x05,D|W|R|O,"Recovered data using previous sector id"},
+ {0x17,0x06,D|W|O,"Recovered data without ecc - data auto-reallocated"},
+ {0x17,0x07,D|W|O,"Recovered data without ecc - recommend reassignment"},
+ {0x18,0x00,D|T|W|R|O,"Recovered data with error correction applied"},
+ {0x18,0x01,D|W|R|O,"Recovered data with error correction and retries applied"},
+ {0x18,0x02,D|W|R|O,"Recovered data - data auto-reallocated"},
+ {0x18,0x03,R,"Recovered data with circ"},
+ {0x18,0x04,R,"Recovered data with lec"},
+ {0x18,0x05,D|W|R|O,"Recovered data - recommend reassignment"},
+ {0x19,0x00,D|O,"Defect list error"},
+ {0x19,0x01,D|O,"Defect list not available"},
+ {0x19,0x02,D|O,"Defect list error in primary list"},
+ {0x19,0x03,D|O,"Defect list error in grown list"},
+ {0x1A,0x00,D|T|L|P|W|R|S|O|M|C,"Parameter list length error"},
+ {0x1B,0x00,D|T|L|P|W|R|S|O|M|C,"Synchronous data transfer error"},
+ {0x1C,0x00,D|O,"Defect list not found"},
+ {0x1C,0x01,D|O,"Primary defect list not found"},
+ {0x1C,0x02,D|O,"Grown defect list not found"},
+ {0x1D,0x00,D|W|O,"Miscompare during verify operation"},
+ {0x1E,0x00,D|W|O,"Recovered id with ecc correction"},
+ {0x20,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid command operation code"},
+ {0x21,0x00,D|T|W|R|O|M,"Logical block address out of range"},
+ {0x21,0x01,M,"Invalid element address"},
+ {0x22,0x00,D,"Illegal function (should use 20 00, 24 00, or 26 00)"},
+ {0x24,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid field in cdb"},
+ {0x25,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit not supported"},
+ {0x26,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid field in parameter list"},
+ {0x26,0x01,D|T|L|P|W|R|S|O|M|C,"Parameter not supported"},
+ {0x26,0x02,D|T|L|P|W|R|S|O|M|C,"Parameter value invalid"},
+ {0x26,0x03,D|T|L|P|W|R|S|O|M|C,"Threshold parameters not supported"},
+ {0x27,0x00,D|T|W|O,"Write protected"},
+ {0x28,0x00,D|T|L|P|W|R|S|O|M|C,"Not ready to ready transition (medium may have changed)"},
+ {0x28,0x01,M,"Import or export element accessed"},
+ {0x29,0x00,D|T|L|P|W|R|S|O|M|C,"Power on, reset, or bus device reset occurred"},
+ {0x2A,0x00,D|T|L|W|R|S|O|M|C,"Parameters changed"},
+ {0x2A,0x01,D|T|L|W|R|S|O|M|C,"Mode parameters changed"},
+ {0x2A,0x02,D|T|L|W|R|S|O|M|C,"Log parameters changed"},
+ {0x2B,0x00,D|T|L|P|W|R|S|O|C,"Copy cannot execute since host cannot disconnect"},
+ {0x2C,0x00,D|T|L|P|W|R|S|O|M|C,"Command sequence error"},
+ {0x2C,0x01,S,"Too many windows specified"},
+ {0x2C,0x02,S,"Invalid combination of windows specified"},
+ {0x2D,0x00,T,"Overwrite error on update in place"},
+ {0x2F,0x00,D|T|L|P|W|R|S|O|M|C,"Commands cleared by another initiator"},
+ {0x30,0x00,D|T|W|R|O|M,"Incompatible medium installed"},
+ {0x30,0x01,D|T|W|R|O,"Cannot read medium - unknown format"},
+ {0x30,0x02,D|T|W|R|O,"Cannot read medium - incompatible format"},
+ {0x30,0x03,D|T,"Cleaning cartridge installed"},
+ {0x31,0x00,D|T|W|O,"Medium format corrupted"},
+ {0x31,0x01,D|L|O,"Format command failed"},
+ {0x32,0x00,D|W|O,"No defect spare location available"},
+ {0x32,0x01,D|W|O,"Defect list update failure"},
+ {0x33,0x00,T,"Tape length error"},
+ {0x36,0x00,L,"Ribbon, ink, or toner failure"},
+ {0x37,0x00,D|T|L|W|R|S|O|M|C,"Rounded parameter"},
+ {0x39,0x00,D|T|L|W|R|S|O|M|C,"Saving parameters not supported"},
+ {0x3A,0x00,D|T|L|W|R|S|O|M,"Medium not present"},
+ {0x3B,0x00,T|L,"Sequential positioning error"},
+ {0x3B,0x01,T,"Tape position error at beginning-of-medium"},
+ {0x3B,0x02,T,"Tape position error at end-of-medium"},
+ {0x3B,0x03,L,"Tape or electronic vertical forms unit not ready"},
+ {0x3B,0x04,L,"Slew failure"},
+ {0x3B,0x05,L,"Paper jam"},
+ {0x3B,0x06,L,"Failed to sense top-of-form"},
+ {0x3B,0x07,L,"Failed to sense bottom-of-form"},
+ {0x3B,0x08,T,"Reposition error"},
+ {0x3B,0x09,S,"Read past end of medium"},
+ {0x3B,0x0A,S,"Read past beginning of medium"},
+ {0x3B,0x0B,S,"Position past end of medium"},
+ {0x3B,0x0C,S,"Position past beginning of medium"},
+ {0x3B,0x0D,M,"Medium destination element full"},
+ {0x3B,0x0E,M,"Medium source element empty"},
+ {0x3D,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid bits in identify message"},
+ {0x3E,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit has not self-configured yet"},
+ {0x3F,0x00,D|T|L|P|W|R|S|O|M|C,"Target operating conditions have changed"},
+ {0x3F,0x01,D|T|L|P|W|R|S|O|M|C,"Microcode has been changed"},
+ {0x3F,0x02,D|T|L|P|W|R|S|O|M|C,"Changed operating definition"},
+ {0x3F,0x03,D|T|L|P|W|R|S|O|M|C,"Inquiry data has changed"},
+ {0x43,0x00,D|T|L|P|W|R|S|O|M|C,"Message error"},
+ {0x44,0x00,D|T|L|P|W|R|S|O|M|C,"Internal target failure"},
+ {0x45,0x00,D|T|L|P|W|R|S|O|M|C,"Select or reselect failure"},
+ {0x46,0x00,D|T|L|P|W|R|S|O|M|C,"Unsuccessful soft reset"},
+ {0x47,0x00,D|T|L|P|W|R|S|O|M|C,"Scsi parity error"},
+ {0x48,0x00,D|T|L|P|W|R|S|O|M|C,"Initiator detected error message received"},
+ {0x49,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid message error"},
+ {0x4A,0x00,D|T|L|P|W|R|S|O|M|C,"Command phase error"},
+ {0x4B,0x00,D|T|L|P|W|R|S|O|M|C,"Data phase error"},
+ {0x4C,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit failed self-configuration"},
+ {0x4E,0x00,D|T|L|P|W|R|S|O|M|C,"Overlapped commands attempted"},
+ {0x50,0x00,T,"Write append error"},
+ {0x50,0x01,T,"Write append position error"},
+ {0x50,0x02,T,"Position error related to timing"},
+ {0x51,0x00,T|O,"Erase failure"},
+ {0x52,0x00,T,"Cartridge fault"},
+ {0x53,0x00,D|T|L|W|R|S|O|M,"Media load or eject failed"},
+ {0x53,0x01,T,"Unload tape failure"},
+ {0x53,0x02,D|T|W|R|O|M,"Medium removal prevented"},
+ {0x54,0x00,P,"Scsi to host system interface failure"},
+ {0x55,0x00,P,"System resource failure"},
+ {0x57,0x00,R,"Unable to recover table-of-contents"},
+ {0x58,0x00,O,"Generation does not exist"},
+ {0x59,0x00,O,"Updated block read"},
+ {0x5A,0x00,D|T|L|P|W|R|S|O|M,"Operator request or state change input (unspecified)"},
+ {0x5A,0x01,D|T|W|R|O|M,"Operator medium removal request"},
+ {0x5A,0x02,D|T|W|O,"Operator selected write protect"},
+ {0x5A,0x03,D|T|W|O,"Operator selected write permit"},
+ {0x5B,0x00,D|T|L|P|W|R|S|O|M,"Log exception"},
+ {0x5B,0x01,D|T|L|P|W|R|S|O|M,"Threshold condition met"},
+ {0x5B,0x02,D|T|L|P|W|R|S|O|M,"Log counter at maximum"},
+ {0x5B,0x03,D|T|L|P|W|R|S|O|M,"Log list codes exhausted"},
+ {0x5C,0x00,D|O,"Rpl status change"},
+ {0x5C,0x01,D|O,"Spindles synchronized"},
+ {0x5C,0x02,D|O,"Spindles not synchronized"},
+ {0x60,0x00,S,"Lamp failure"},
+ {0x61,0x00,S,"Video acquisition error"},
+ {0x61,0x01,S,"Unable to acquire video"},
+ {0x61,0x02,S,"Out of focus"},
+ {0x62,0x00,S,"Scan head positioning error"},
+ {0x63,0x00,R,"End of user area encountered on this track"},
+ {0x64,0x00,R,"Illegal mode for this track"},
+ {0, 0, 0, NULL}
+};
+
+static const char *snstext[] = {
+ "None", /* There is no sense information */
+ "Recovered Error", /* The last command completed successfully
+ but used error correction */
+ "Not Ready", /* The addressed target is not ready */
+ "Medium Error", /* Data error detected on the medium */
+ "Hardware Error", /* Controller or device failure */
+ "Illegal Request",
+ "Unit Attention", /* Removable medium was changed, or
+ the target has been reset */
+ "Data Protect", /* Access to the data is blocked */
+ "Blank Check", /* Reached unexpected written or unwritten
+ region of the medium */
+ "Key=9", /* Vendor specific */
+ "Copy Aborted", /* COPY or COMPARE was aborted */
+ "Aborted Command", /* The target aborted the command */
+ "Equal", /* A SEARCH DATA command found data equal */
+ "Volume Overflow", /* Medium full with still data to be written */
+ "Miscompare", /* Source data and data on the medium
+ do not agree */
+ "Key=15" /* Reserved */
+};
+
+/* Print sense information */
+void sg_print_sense(const char * leadin, const unsigned char * sense_buffer,
+ int sb_len)
+{
+ int i, s;
+ int sense_class, valid, code;
+ const char * error = NULL;
+
+ sense_class = (sense_buffer[0] >> 4) & 0x07;
+ code = sense_buffer[0] & 0xf;
+ valid = sense_buffer[0] & 0x80;
+
+ if (sense_class == 7) { /* extended sense data */
+ s = sense_buffer[7] + 8;
+ if(s > sb_len)
+ s = sb_len;
+
+ if (!valid)
+ printf("[valid=0] ");
+ printf("Info fld=0x%x, ", (int)((sense_buffer[3] << 24) |
+ (sense_buffer[4] << 16) | (sense_buffer[5] << 8) |
+ sense_buffer[6]));
+
+ if (sense_buffer[2] & 0x80)
+ printf( "FMK "); /* current command has read a filemark */
+ if (sense_buffer[2] & 0x40)
+ printf( "EOM "); /* end-of-medium condition exists */
+ if (sense_buffer[2] & 0x20)
+ printf( "ILI "); /* incorrect block length requested */
+
+ switch (code) {
+ case 0x0:
+ error = "Current"; /* error concerns current command */
+ break;
+ case 0x1:
+ error = "Deferred"; /* error concerns some earlier command */
+ /* e.g., an earlier write to disk cache succeeded, but
+ now the disk discovers that it cannot write the data */
+ break;
+ default:
+ error = "Invalid";
+ }
+
+ printf("%s ", error);
+
+ if (leadin)
+ printf("%s: ", leadin);
+ printf("sense key: %s\n", snstext[sense_buffer[2] & 0x0f]);
+
+ /* Check to see if additional sense information is available */
+ if(sense_buffer[7] + 7 < 13 ||
+ (sense_buffer[12] == 0 && sense_buffer[13] == 0)) goto done;
+
+ for(i=0; additional[i].text; i++)
+ if(additional[i].code1 == sense_buffer[12] &&
+ additional[i].code2 == sense_buffer[13])
+ printf("Additional sense indicates: %s\n",
+ additional[i].text);
+
+ for(i=0; additional2[i].text; i++)
+ if(additional2[i].code1 == sense_buffer[12] &&
+ additional2[i].code2_min >= sense_buffer[13] &&
+ additional2[i].code2_max <= sense_buffer[13]) {
+ printf("Additional sense indicates: ");
+ printf(additional2[i].text, sense_buffer[13]);
+ printf("\n");
+ };
+ } else { /* non-extended sense data */
+
+ /*
+ * Standard says:
+ * sense_buffer[0] & 0200 : address valid
+ * sense_buffer[0] & 0177 : vendor-specific error code
+ * sense_buffer[1] & 0340 : vendor-specific
+ * sense_buffer[1..3] : 21-bit logical block address
+ */
+
+ if (leadin)
+ printf("%s: ", leadin);
+ if (sense_buffer[0] < 15)
+ printf("old sense: key %s\n", snstext[sense_buffer[0] & 0x0f]);
+ else
+ printf("sns = %2x %2x\n", sense_buffer[0], sense_buffer[2]);
+
+ printf("Non-extended sense class %d code 0x%0x ", sense_class, code);
+ s = 4;
+ }
+
+ done:
+ printf("Raw sense data (in hex):\n ");
+ for (i = 0; i < s; ++i) {
+ if ((i > 0) && (0 == (i % 24)))
+ printf("\n ");
+ printf("%02x ", sense_buffer[i]);
+ }
+ printf("\n");
+ return;
+}
+
+static const char * hostbyte_table[]={
+"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
+"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
+"DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL};
+
+void sg_print_host_status(int host_status)
+{ static int maxcode=0;
+ int i;
+
+ if(! maxcode) {
+ for(i = 0; hostbyte_table[i]; i++) ;
+ maxcode = i-1;
+ }
+ printf("Host_status=0x%02x", host_status);
+ if(host_status > maxcode) {
+ printf("is invalid ");
+ return;
+ }
+ printf("(%s) ",hostbyte_table[host_status]);
+}
+
+static const char * driverbyte_table[]={
+"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
+"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE", NULL};
+
+static const char * driversuggest_table[]={"SUGGEST_OK",
+"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
+unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
+
+
+void sg_print_driver_status(int driver_status)
+{
+ static int driver_max =0 , suggest_max=0;
+ int i;
+ int dr = driver_status & SG_ERR_DRIVER_MASK;
+ int su = (driver_status & SG_ERR_SUGGEST_MASK) >> 4;
+
+ if(! driver_max) {
+ for(i = 0; driverbyte_table[i]; i++) ;
+ driver_max = i;
+ for(i = 0; driversuggest_table[i]; i++) ;
+ suggest_max = i;
+ }
+ printf("Driver_status=0x%02x",driver_status);
+ printf(" (%s,%s) ",
+ dr < driver_max ? driverbyte_table[dr]:"invalid",
+ su < suggest_max ? driversuggest_table[su]:"invalid");
+}
+
+#ifdef SG_IO
+int sg_chk_n_print3(const char * leadin, sg_io_hdr_t * hp)
+{
+ return sg_chk_n_print(leadin, hp->masked_status, hp->host_status,
+ hp->driver_status, hp->sbp, hp->sb_len_wr);
+}
+#endif
+
+int sg_chk_n_print(const char * leadin, int masked_status,
+ int host_status, int driver_status,
+ const unsigned char * sense_buffer, int sb_len)
+{
+ int done_leadin = 0;
+ int done_sense = 0;
+
+ if ((0 == masked_status) && (0 == host_status) &&
+ (0 == driver_status))
+ return 1; /* No problems */
+ if (0 != masked_status) {
+ if (leadin)
+ printf("%s: ", leadin);
+ done_leadin = 1;
+ sg_print_status(masked_status);
+ printf("\n");
+ if (sense_buffer && ((masked_status == CHECK_CONDITION) ||
+ (masked_status == COMMAND_TERMINATED))) {
+ sg_print_sense(0, sense_buffer, sb_len);
+ done_sense = 1;
+ }
+ }
+ if (0 != host_status) {
+ if (leadin && (! done_leadin))
+ printf("%s: ", leadin);
+ if (done_leadin)
+ printf("plus...: ");
+ else
+ done_leadin = 1;
+ sg_print_host_status(host_status);
+ printf("\n");
+ }
+ if (0 != driver_status) {
+ if (leadin && (! done_leadin))
+ printf("%s: ", leadin);
+ if (done_leadin)
+ printf("plus...: ");
+ else
+ done_leadin = 1;
+ sg_print_driver_status(driver_status);
+ printf("\n");
+ if (sense_buffer && (! done_sense) &&
+ (SG_ERR_DRIVER_SENSE & driver_status))
+ sg_print_sense(0, sense_buffer, sb_len);
+ }
+ return 0;
+}
+
+#ifdef SG_IO
+int sg_err_category3(sg_io_hdr_t * hp)
+{
+ return sg_err_category(hp->masked_status, hp->host_status,
+ hp->driver_status, hp->sbp, hp->sb_len_wr);
+}
+#endif
+
+int sg_err_category(int masked_status, int host_status,
+ int driver_status, const unsigned char * sense_buffer,
+ int sb_len)
+{
+ if ((0 == masked_status) && (0 == host_status) &&
+ (0 == driver_status))
+ return SG_ERR_CAT_CLEAN;
+ if ((CHECK_CONDITION == masked_status) ||
+ (COMMAND_TERMINATED == masked_status) ||
+ (SG_ERR_DRIVER_SENSE & driver_status)) {
+ if (sense_buffer && (sb_len > 2)) {
+ if(RECOVERED_ERROR == sense_buffer[2])
+ return SG_ERR_CAT_RECOVERED;
+ else if ((UNIT_ATTENTION == (0x0f & sense_buffer[2])) &&
+ (sb_len > 12)) {
+ if (0x28 == sense_buffer[12])
+ return SG_ERR_CAT_MEDIA_CHANGED;
+ if (0x29 == sense_buffer[12])
+ return SG_ERR_CAT_RESET;
+ }
+ }
+ return SG_ERR_CAT_SENSE;
+ }
+ if (0 != host_status) {
+ if ((SG_ERR_DID_NO_CONNECT == host_status) ||
+ (SG_ERR_DID_BUS_BUSY == host_status) ||
+ (SG_ERR_DID_TIME_OUT == host_status))
+ return SG_ERR_CAT_TIMEOUT;
+ }
+ if (0 != driver_status) {
+ if (SG_ERR_DRIVER_TIMEOUT == driver_status)
+ return SG_ERR_CAT_TIMEOUT;
+ }
+ return SG_ERR_CAT_OTHER;
+}
+
+int sg_get_command_size(unsigned char opcode)
+{
+ return COMMAND_SIZE(opcode);
+}
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/sg_err.h parted-1.4.7-gpt/libparted/sg_err.h
--- parted-1.4.7/libparted/sg_err.h Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/sg_err.h Thu Jan 18 11:24:42 2001
@@ -0,0 +1,156 @@
+ /*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef SG_ERR_H
+#define SG_ERR_H
+#include <linux/../scsi/scsi.h> /* cope with silly includes */
+#include <linux/../scsi/sg.h>
+
+/* Feel free to copy and modify this GPL-ed code into your applications. */
+
+/* Version 0.83 (991208) */
+
+
+/* Some of the following error/status codes are exchanged between the
+ various layers of the SCSI sub-system in Linux and should never
+ reach the user. They are placed here for completeness. What appears
+ here is copied from drivers/scsi/scsi.h which is not visible in
+ the user space. */
+
+/* The following are 'host_status' codes */
+#ifndef DID_OK
+#define DID_OK 0x00
+#endif
+#ifndef DID_NO_CONNECT
+#define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */
+#define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */
+#define DID_TIME_OUT 0x03 /* Timed out for some other reason */
+#define DID_BAD_TARGET 0x04 /* Bad target (id?) */
+#define DID_ABORT 0x05 /* Told to abort for some other reason */
+#define DID_PARITY 0x06 /* Parity error (on SCSI bus) */
+#define DID_ERROR 0x07 /* Internal error */
+#define DID_RESET 0x08 /* Reset by somebody */
+#define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */
+#define DID_PASSTHROUGH 0x0a /* Force command past mid-level */
+#define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */
+#endif
+
+/* These defines are to isolate applictaions from kernel define changes */
+#define SG_ERR_DID_OK DID_OK
+#define SG_ERR_DID_NO_CONNECT DID_NO_CONNECT
+#define SG_ERR_DID_BUS_BUSY DID_BUS_BUSY
+#define SG_ERR_DID_TIME_OUT DID_TIME_OUT
+#define SG_ERR_DID_BAD_TARGET DID_BAD_TARGET
+#define SG_ERR_DID_ABORT DID_ABORT
+#define SG_ERR_DID_PARITY DID_PARITY
+#define SG_ERR_DID_ERROR DID_ERROR
+#define SG_ERR_DID_RESET DID_RESET
+#define SG_ERR_DID_BAD_INTR DID_BAD_INTR
+#define SG_ERR_DID_PASSTHROUGH DID_PASSTHROUGH
+#define SG_ERR_DID_SOFT_ERROR DID_SOFT_ERROR
+
+/* The following are 'driver_status' codes */
+#ifndef DRIVER_OK
+#define DRIVER_OK 0x00
+#endif
+#ifndef DRIVER_BUSY
+#define DRIVER_BUSY 0x01
+#define DRIVER_SOFT 0x02
+#define DRIVER_MEDIA 0x03
+#define DRIVER_ERROR 0x04
+#define DRIVER_INVALID 0x05
+#define DRIVER_TIMEOUT 0x06
+#define DRIVER_HARD 0x07
+#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */
+
+/* Following "suggests" are "or-ed" with one of previous 8 entries */
+#define SUGGEST_RETRY 0x10
+#define SUGGEST_ABORT 0x20
+#define SUGGEST_REMAP 0x30
+#define SUGGEST_DIE 0x40
+#define SUGGEST_SENSE 0x80
+#define SUGGEST_IS_OK 0xff
+#endif
+#ifndef DRIVER_MASK
+#define DRIVER_MASK 0x0f
+#endif
+#ifndef SUGGEST_MASK
+#define SUGGEST_MASK 0xf0
+#endif
+
+/* These defines are to isolate applictaions from kernel define changes */
+#define SG_ERR_DRIVER_OK DRIVER_OK
+#define SG_ERR_DRIVER_BUSY DRIVER_BUSY
+#define SG_ERR_DRIVER_SOFT DRIVER_SOFT
+#define SG_ERR_DRIVER_MEDIA DRIVER_MEDIA
+#define SG_ERR_DRIVER_ERROR DRIVER_ERROR
+#define SG_ERR_DRIVER_INVALID DRIVER_INVALID
+#define SG_ERR_DRIVER_TIMEOUT DRIVER_TIMEOUT
+#define SG_ERR_DRIVER_HARD DRIVER_HARD
+#define SG_ERR_DRIVER_SENSE DRIVER_SENSE
+#define SG_ERR_SUGGEST_RETRY SUGGEST_RETRY
+#define SG_ERR_SUGGEST_ABORT SUGGEST_ABORT
+#define SG_ERR_SUGGEST_REMAP SUGGEST_REMAP
+#define SG_ERR_SUGGEST_DIE SUGGEST_DIE
+#define SG_ERR_SUGGEST_SENSE SUGGEST_SENSE
+#define SG_ERR_SUGGEST_IS_OK SUGGEST_IS_OK
+#define SG_ERR_DRIVER_MASK DRIVER_MASK
+#define SG_ERR_SUGGEST_MASK SUGGEST_MASK
+
+
+
+/* The following "print" functions send ACSII to stdout */
+extern void sg_print_command(const unsigned char * command);
+extern void sg_print_sense(const char * leadin,
+ const unsigned char * sense_buffer, int sb_len);
+extern void sg_print_status(int masked_status);
+extern void sg_print_host_status(int host_status);
+extern void sg_print_driver_status(int driver_status);
+
+/* sg_chk_n_print() returns 1 quietly if there are no errors/warnings
+ else it prints to standard output and returns 0. */
+extern int sg_chk_n_print(const char * leadin, int masked_status,
+ int host_status, int driver_status,
+ const unsigned char * sense_buffer, int sb_len);
+#ifdef SG_IO
+extern int sg_chk_n_print3(const char * leadin, sg_io_hdr_t * hp);
+#endif
+
+
+/* The following "category" function returns one of the following */
+#define SG_ERR_CAT_CLEAN 0 /* No errors or other information */
+#define SG_ERR_CAT_MEDIA_CHANGED 1 /* interpreted from sense buffer */
+#define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */
+#define SG_ERR_CAT_TIMEOUT 3
+#define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */
+#define SG_ERR_CAT_SENSE 98 /* Something else is in the sense buffer */
+#define SG_ERR_CAT_OTHER 99 /* Some other error/warning has occurred */
+
+extern int sg_err_category(int masked_status, int host_status,
+ int driver_status, const unsigned char * sense_buffer,
+ int sb_len);
+#ifdef SG_IO
+extern int sg_err_category3(sg_io_hdr_t * hp);
+#endif
+
+
+/* Returns length of SCSI command given the opcode (first byte) */
+int sg_get_command_size(unsigned char opcode);
+
+#endif
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/sg_map.c parted-1.4.7-gpt/libparted/sg_map.c
--- parted-1.4.7/libparted/sg_map.c Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/sg_map.c Thu Jan 18 11:24:42 2001
@@ -0,0 +1,422 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/../scsi/sg.h> /* cope with silly includes */
+#include <linux/../scsi/scsi.h>
+
+/* Test code for D. Gilbert's extensions to the Linux OS SCSI generic ("sg")
+ device driver.
+* Copyright (C) 2000 D. Gilbert
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+
+ This shows the mapping from "sg" devices to other scsi devices
+ (i.e. sd, scd or st) if any.
+ Options: -n numeric scan: scan /dev/sg0,1,2, .... [default]
+ -a alphabetical scan: scan /dev/sga,b,c, ....
+ -x also show bus,chan,id,lun and type
+ -sd only scan for sd devices (disks)
+ -st only scan for st devices (tapes)
+ -scd (or -sr) only scan for scd devices (cdroms)
+
+ Note: This program requires sg version 2 or better.
+
+ Version 0.12 20000415
+*/
+
+#include "sg_map.h"
+
+struct _sg_to_sd sg_to_sd[MAX_SG_DEVS];
+
+#ifndef SG_GET_RESERVED_SIZE
+#error "Need version 2 sg driver (linux kernel >= 2.2.6)"
+#endif
+
+static const char * devfs_id = "/dev/.devfsd";
+
+#define NUMERIC_SCAN_DEF 1 /* change to 0 to make alpha scan default */
+
+
+typedef struct my_map_info
+{
+ int active;
+ int lin_dev_type;
+ int oth_dev_num;
+ struct sg_scsi_id sg_dat;
+} my_map_info_t;
+
+
+#define MAX_SG_DEVS 128
+#define MAX_SD_DEVS 128
+#define MAX_SR_DEVS 128
+#define MAX_ST_DEVS 128
+#define MAX_ERRORS 4
+
+static my_map_info_t map_arr[MAX_SG_DEVS];
+
+#define LIN_DEV_TYPE_UNKNOWN 0
+#define LIN_DEV_TYPE_SD 1
+#define LIN_DEV_TYPE_SR 2
+#define LIN_DEV_TYPE_ST 3
+#define LIN_DEV_TYPE_SCD 4
+
+
+typedef struct my_scsi_idlun {
+/* why can't userland see this structure ??? */
+ int dev_id;
+ int host_unique_id;
+} My_scsi_idlun;
+
+
+#define EBUFF_LEN 256
+static char ebuff[EBUFF_LEN];
+
+static void scan_dev_type(const char * leadin, int max_dev, int do_numeric,
+ int lin_dev_type, int last_sg_ind);
+
+static void usage()
+{
+ printf("Usage: 'sg_map [-a] [-n] [-x] [-sd] [-scd or -sr] [-st]'\n");
+ printf(" where: -a do alphabetic scan (ie sga, sgb, sgc)\n");
+ printf(" -n do numeric scan (ie sg0, sg1, sg2)\n");
+ printf(" -x also show bus,chan,id,lun and type\n");
+ printf(" -sd show mapping to disks\n");
+ printf(" -scd show mapping to cdroms (look for /dev/scd<n>\n");
+ printf(" -sr show mapping to cdroms (look for /dev/sr<n>\n");
+ printf(" -st show mapping to tapes\n");
+ printf(" If no '-s*' arguments given then show all mappings\n");
+}
+
+
+static void make_dev_name(char * fname, const char * leadin, int k,
+ int do_numeric)
+{
+ char buff[64];
+ int big,little;
+
+ strcpy(fname, leadin ? leadin : "/dev/sg");
+ if (do_numeric) {
+ sprintf(buff, "%d", k);
+ strcat(fname, buff);
+ }
+ else {
+ if (k < 26) {
+ buff[0] = 'a' + (char)k;
+ buff[1] = '\0';
+ strcat(fname, buff);
+ }
+ else if (k <= 255) { /* assumes sequence goes x,y,z,aa,ab,ac etc */
+ big = k/26;
+ little = k - (26 * big);
+ big = big - 1;
+
+ buff[0] = 'a' + (char)big;
+ buff[1] = 'a' + (char)little;
+ buff[2] = '\0';
+ strcat(fname, buff);
+ }
+ else
+ strcat(fname, "xxxx");
+ }
+}
+
+int sg_to_sd_map_made = 0;
+
+int
+make_sg_to_sd_map()
+{
+ int sg_fd, res, k;
+ int do_numeric = NUMERIC_SCAN_DEF;
+ int do_all_s = 0;
+ int do_sd = 1;
+ int do_st = 0;
+ int do_sr = 0;
+ int do_scd = 0;
+ int do_extra = 0;
+ char fname[64];
+ int num_errors = 0;
+ int num_silent = 0;
+ int eacces_err = 0;
+ int last_sg_ind = -1;
+ struct stat stat_buf;
+
+ memset(&sg_to_sd, 0, MAX_SG_DEVS * sizeof(struct _sg_to_sd));
+
+#if 0
+ for (k = 1; k < argc; ++k) {
+ if (0 == strcmp("-n", argv[k]))
+ do_numeric = 1;
+ else if (0 == strcmp("-a", argv[k]))
+ do_numeric = 0;
+ else if (0 == strcmp("-x", argv[k]))
+ do_extra = 1;
+ else if (0 == strcmp("-sd", argv[k])) {
+ do_sd = 1;
+ do_all_s = 0;
+ }
+ else if (0 == strcmp("-st", argv[k])) {
+ do_st = 1;
+ do_all_s = 0;
+ }
+ else if (0 == strcmp("-sr", argv[k])) {
+ do_sr = 1;
+ do_all_s = 0;
+ }
+ else if (0 == strcmp("-scd", argv[k])) {
+ do_scd = 1;
+ do_all_s = 0;
+ }
+ else if ((0 == strcmp("-?", argv[k])) ||
+ (0 == strncmp("-h", argv[k], 2))) {
+ printf(
+ "Show mapping from sg devices to other scsi device names\n\n");
+ usage();
+ return 1;
+ }
+ else if (*argv[k] == '-') {
+ printf("Unknown switch: %s\n", argv[k]);
+ usage();
+ return 1;
+ }
+ else if (*argv[k] != '-') {
+ printf("Unknown argument\n");
+ usage();
+ return 1;
+ }
+ }
+#endif
+
+ if (stat(devfs_id, &stat_buf) == 0)
+ printf("# Note: the devfs pseudo file system is present\n");
+
+ for (k = 0, res = 0; (k < MAX_SG_DEVS) && (num_errors < MAX_ERRORS);
+ ++k, res = (sg_fd >= 0) ? close(sg_fd) : 0) {
+ if (res < 0) {
+ sprintf(ebuff, "Error closing %s ", fname);
+ perror("sg_map: close error");
+ return 1;
+ }
+ make_dev_name(fname, "/dev/sg", k, do_numeric);
+
+ sg_fd = open(fname, O_RDONLY | O_NONBLOCK);
+ if (sg_fd < 0) {
+ if (EBUSY == errno) {
+ map_arr[k].active = -2;
+ continue;
+ }
+ else if ((ENODEV == errno) || (ENOENT == errno) ||
+ (ENXIO == errno)) {
+ ++num_errors;
+ ++num_silent;
+ map_arr[k].active = -1;
+ continue;
+ }
+ else {
+ if (EACCES == errno)
+ eacces_err = 1;
+ sprintf(ebuff, "Error opening %s ", fname);
+ perror(ebuff);
+ ++num_errors;
+ continue;
+ }
+ }
+ res = ioctl(sg_fd, SG_GET_SCSI_ID, &map_arr[k].sg_dat);
+ if (res < 0) {
+ sprintf(ebuff, "device %s failed on sg ioctl, skip", fname);
+ perror(ebuff);
+ ++num_errors;
+ continue;
+ }
+ map_arr[k].active = 1;
+ map_arr[k].oth_dev_num = -1;
+ last_sg_ind = k;
+ }
+ if ((num_errors >= MAX_ERRORS) && (num_silent < num_errors)) {
+ printf("Stopping because there are too many error\n");
+ if (eacces_err)
+ printf(" root access may be required\n");
+ return 1;
+ }
+ if (last_sg_ind < 0) {
+ printf("Stopping because no sg devices found\n");
+ }
+
+ if (do_all_s || do_sd)
+ scan_dev_type("/dev/sd", MAX_SD_DEVS, 0, LIN_DEV_TYPE_SD, last_sg_ind);
+#if 0
+ if (do_all_s || do_sr)
+ scan_dev_type("/dev/sr", MAX_SR_DEVS, 1, LIN_DEV_TYPE_SR, last_sg_ind);
+ if (do_all_s || do_scd)
+ scan_dev_type("/dev/scd", MAX_SR_DEVS, 1, LIN_DEV_TYPE_SCD,
+ last_sg_ind);
+ if (do_all_s || do_st)
+ scan_dev_type("/dev/st", MAX_ST_DEVS, 1, LIN_DEV_TYPE_ST, last_sg_ind);
+#endif
+
+ for (k = 0; k <= last_sg_ind; ++k) {
+ make_dev_name(fname, "/dev/sg", k, do_numeric);
+ // printf("%s", fname);
+ snprintf(sg_to_sd[k].sg, 15, "%s", fname);
+ switch (map_arr[k].active)
+ {
+ case -2:
+ printf(do_extra ? " -2 -2 -2 -2 -2" : " busy");
+ break;
+ case -1:
+ printf(do_extra ? " -1 -1 -1 -1 -1" : " not present");
+ break;
+ case 0:
+ printf(do_extra ? " -3 -3 -3 -3 -3" : " some error\n");
+ break;
+ case 1:
+ if (do_extra)
+ printf(" %d %d %d %d %d", map_arr[k].sg_dat.host_no,
+ map_arr[k].sg_dat.channel, map_arr[k].sg_dat.scsi_id,
+ map_arr[k].sg_dat.lun, map_arr[k].sg_dat.scsi_type);
+ switch (map_arr[k].lin_dev_type)
+ {
+ case LIN_DEV_TYPE_SD:
+ make_dev_name(fname, "/dev/sd" , map_arr[k].oth_dev_num, 0);
+ // printf(" %s", fname);
+ snprintf(sg_to_sd[k].sd, 15, "%s", fname);
+ break;
+#if 0
+ case LIN_DEV_TYPE_ST:
+ make_dev_name(fname, "/dev/st" , map_arr[k].oth_dev_num, 1);
+ printf(" %s", fname);
+ break;
+ case LIN_DEV_TYPE_SR:
+ make_dev_name(fname, "/dev/sr" , map_arr[k].oth_dev_num, 1);
+ printf(" %s", fname);
+ break;
+ case LIN_DEV_TYPE_SCD:
+ make_dev_name(fname, "/dev/scd" , map_arr[k].oth_dev_num, 1);
+ printf(" %s", fname);
+ break;
+#endif
+ default:
+ break;
+ }
+ break;
+ default:
+ printf(" bad logic\n");
+ break;
+ }
+ // printf("\n");
+ }
+
+ sg_to_sd_map_made = 1;
+ return 0;
+}
+
+static int find_dev_in_sg_arr(My_scsi_idlun * my_idlun, int host_no,
+ int last_sg_ind)
+{
+ int k;
+ struct sg_scsi_id * sidp;
+
+ for (k = 0; k <= last_sg_ind; ++k) {
+ sidp = &(map_arr[k].sg_dat);
+ if ((host_no == sidp->host_no) &&
+ ((my_idlun->dev_id & 0xff) == sidp->scsi_id) &&
+ (((my_idlun->dev_id >> 8) & 0xff) == sidp->lun) &&
+ (((my_idlun->dev_id >> 16) & 0xff) == sidp->channel))
+ return k;
+ }
+ return -1;
+}
+
+static void scan_dev_type(const char * leadin, int max_dev, int do_numeric,
+ int lin_dev_type, int last_sg_ind)
+{
+ int k, res, ind, sg_fd;
+ int num_errors = 0;
+ int num_silent = 0;
+ int host_no = -1;
+ My_scsi_idlun my_idlun;
+ char fname[64];
+
+ for (k = 0, res = 0; (k < max_dev) && (num_errors < MAX_ERRORS);
+ ++k, res = (sg_fd >= 0) ? close(sg_fd) : 0) {
+ if (res < 0) {
+ sprintf(ebuff, "Error closing %s ", fname);
+ perror("sg_map: close error");
+ return;
+ }
+ make_dev_name(fname, leadin, k, do_numeric);
+
+ sg_fd = open(fname, O_RDONLY | O_NONBLOCK);
+ if (sg_fd < 0) {
+ if (EBUSY == errno) {
+ printf("Device %s is busy\n", fname);
+ ++num_errors;
+ continue;
+ }
+ else if ((ENODEV == errno) || (ENOENT == errno) ||
+ (ENXIO == errno)) {
+ ++num_errors;
+ ++num_silent;
+ continue;
+ }
+ else {
+ sprintf(ebuff, "Error opening %s ", fname);
+ perror(ebuff);
+ ++num_errors;
+ continue;
+ }
+ }
+
+ res = ioctl(sg_fd, SCSI_IOCTL_GET_IDLUN, &my_idlun);
+ if (res < 0) {
+ sprintf(ebuff, "device %s failed on scsi ioctl(idlun), skip",
+ fname);
+ perror(ebuff);
+ ++num_errors;
+ continue;
+ }
+ res = ioctl(sg_fd, SCSI_IOCTL_GET_BUS_NUMBER, &host_no);
+ if (res < 0) {
+ sprintf(ebuff, "device %s failed on scsi ioctl(bus_number), skip",
+ fname);
+ perror(ebuff);
+ ++num_errors;
+ continue;
+ }
+ ind = find_dev_in_sg_arr(&my_idlun, host_no, last_sg_ind);
+ if (ind >= 0) {
+ map_arr[ind].oth_dev_num = k;
+ map_arr[ind].lin_dev_type = lin_dev_type;
+ }
+ else
+ printf("Strange, could not find device %s mapped to sg device??\n",
+ fname);
+ }
+}
+
diff -BburN --exclude *.orig --exclude *.spec --exclude=*Makefile.in --exclude=*.po* parted-1.4.7/libparted/sg_map.h parted-1.4.7-gpt/libparted/sg_map.h
--- parted-1.4.7/libparted/sg_map.h Wed Dec 31 18:00:00 1969
+++ parted-1.4.7-gpt/libparted/sg_map.h Thu Jan 18 11:24:42 2001
@@ -0,0 +1,33 @@
+ /*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define MAX_SG_DEVS 128
+
+
+struct _sg_to_sd {
+ char sg[16];
+ char sd[16];
+};
+
+
+extern struct _sg_to_sd sg_to_sd[MAX_SG_DEVS];
+extern int sg_to_sd_map_made;
+
+int make_sg_to_sd_map();
+
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2001-03-06 18:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-03-06 18:01 [Linux-ia64] GPT patch for parted 1.4.7 Matt_Domsch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox