diff -Naur linux-source-2.6.32-orig/fs/partitions/Kconfig linux-source-2.6.32/fs/partitions/Kconfig --- linux-source-2.6.32-orig/fs/partitions/Kconfig 2009-12-03 03:51:21.000000000 +0000 +++ linux-source-2.6.32/fs/partitions/Kconfig 2011-11-20 14:04:28.000000000 +0000 @@ -83,11 +83,19 @@ were partitioned under AmigaOS. config ATARI_PARTITION - bool "Atari partition table support" if PARTITION_ADVANCED + bool "Atari ST/TT/Falcon partition table support" if PARTITION_ADVANCED default y if ATARI help Say Y here if you would like to use hard disks under Linux which - were partitioned under the Atari OS. + were partitioned under the 16/32-bit Atari OS. + +config ATARI8_PARTITION + bool "Atari 400/800/XL/XE partition table support" if PARTITION_ADVANCED + default y if ATARI8 + help + Say Y here if you would like to use hard disks under Linux which + were partitioned under the 8-bit Atari OS. + It supports KMK/IDEA and APT partition tables. config IBM_PARTITION bool "IBM disk label and partition support" diff -Naur linux-source-2.6.32-orig/fs/partitions/Makefile linux-source-2.6.32/fs/partitions/Makefile --- linux-source-2.6.32-orig/fs/partitions/Makefile 2009-12-03 03:51:21.000000000 +0000 +++ linux-source-2.6.32/fs/partitions/Makefile 2011-10-26 02:03:17.000000000 +0000 @@ -7,6 +7,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o obj-$(CONFIG_AMIGA_PARTITION) += amiga.o obj-$(CONFIG_ATARI_PARTITION) += atari.o +obj-$(CONFIG_ATARI8_PARTITION) += atari8.o obj-$(CONFIG_MAC_PARTITION) += mac.o obj-$(CONFIG_LDM_PARTITION) += ldm.o obj-$(CONFIG_MSDOS_PARTITION) += msdos.o diff -Naur linux-source-2.6.32-orig/fs/partitions/atari8.c linux-source-2.6.32/fs/partitions/atari8.c --- linux-source-2.6.32-orig/fs/partitions/atari8.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-source-2.6.32/fs/partitions/atari8.c 2011-11-20 17:37:20.000000000 +0000 @@ -0,0 +1,207 @@ +/* + * fs/partitions/atari8.c + * + * Copyright (C) 2011 Jerzy Kut + * + * Support for Atari 8-bit KMK/IDEA and APT partition tables. + */ + +#include +#include +#include "check.h" +#include "atari8.h" + +#define MSDOS_LABEL_MAGIC 0xaa55 + +struct msdos_partition +{ + u8 status; + u8 firstchs[3]; + u8 type; + u8 lastchs[3]; + u32 beg; + u32 len; +} __attribute__((__packed__)); + +struct msdos_rootsector +{ + u8 code[0x1b8]; + u32 dsign; + u16 nulls; + struct msdos_partition parts[4]; + u16 magic; +} __attribute__((__packed__)); + +static inline int is_kmk_idea_partition_table(struct kmk_idea_rootsector *rs) +{ + return rs->pmagic == KMK_IDEA_PMAGIC_SIGNATURE; +} + +static inline int is_valid_kmk_idea_partition(u8 pstats, u32 pbeg, u32 plen, u32 hd_size) +{ + return ((pstats & KMK_IDEA_PSTATS_ACTIVE) != 0) && (pbeg < hd_size) && (plen > 0) && ((pbeg + plen) <= hd_size); +} + +static inline int is_msdos_protective_mbr(struct msdos_rootsector *msrs) +{ + return msrs->magic == MSDOS_LABEL_MAGIC; +} + +static inline int is_partition_table_link(struct msdos_partition *mspart) +{ + return ((mspart->status & 0x7f) == 0) && (mspart->type == 0x7f); +} + +static inline int is_apt_partition_table(struct apt_header *ah) +{ + /* printk("'%3s' $%06x\n", ah->hsign, *((unsigned int*)ah->hsign)); */ + return strncmp("APT", ah->hsign, 3) == 0; +} + +static inline int is_valid_apt_partition(u8 pflags, u8 ptype, u8 daflags, u16 poff, u32 pbeg, u32 plen, u32 hd_size) +{ + return ((pflags & APT_PFLAGS_RESERVED) == 0) && ((pflags & APT_PFLAGS_SECT) != 0) && + (ptype == APT_PTYPE_DOS) && ((daflags & APT_DAFLAGS_ACTIVE) != 0) && + ((poff + pbeg) < hd_size) && (plen > 0) && ((poff + pbeg + plen) <= hd_size); +} + +/* static void print_sector(void *sector) +{ + int i; + printk("\n"); + for (i = 0; i < 0x200; i++) + { + printk(" $%02x", *((u8 *)(sector + i))); + if (i % 16 == 15) + printk("%16s\n", (char *)(sector + (i & 0x1f0))); + } +} */ + +int atari8_partition(struct parsed_partitions *state, struct block_device *bdev) +{ + Sector sect, aptsect; + struct kmk_idea_rootsector *rs; + struct msdos_rootsector *msrs; + struct msdos_partition *mspart; + struct apt_rootsector *ars; + struct apt_header *ahead; + struct apt_partition *apart; + u8 pstats, pflags, ptype, daflags, pindex, pclsize, aslot, aoff; + u16 poff; + u32 hd_size, pbeg, plen, i, slot; + + /* printk("Discover Atari 8-bit partition table "); */ + + rs = (struct kmk_idea_rootsector *) read_dev_sector(bdev, 0, §); + if (!rs) + { + /* printk("ERROR!\n"); */ + return -1; + } + /* print_sector(rs); */ + + hd_size = bdev->bd_inode->i_size >> 9; + if (is_kmk_idea_partition_table(rs)) + { + printk(" KMK/IDEA<"); + + /* printk("Hard disk size is %i\n", hd_size); */ + for (slot = 1, i = 0; (i < 16) && (slot < state->limit); slot++, i++) + { + pstats = rs->pstats[i]; + pindex = rs->pindex[i]; + pclsize = rs->pclsize[i]; + pbeg = ((u32)rs->pbeglo[i] | ((u32)rs->pbegmd[i] << 8) | ((u32)rs->pbeghi[i] << 16)); + plen = (u32)rs->plenlo[i] | ((u32)rs->plenmd[i] << 8) | ((u32)rs->plenhi[i] << 16); + /* printk("Partition %i (pbeg %i, plen %i, pclsize $%02x, pindex %i, pstats $%02x) in slot %i", i, pbeg, plen, pclsize, pindex, pstats, slot); */ + pbeg++; + if (pclsize == KMK_IDEA_PCLSIZE_256) + plen >>= 1; /* because IDE has 512bps only */ + if (is_valid_kmk_idea_partition(pstats, pbeg, plen, hd_size)) + { + put_partition(state, slot, pbeg, plen); + /* printk(" added\n"); */ + } + /* else + printk(" passed\n"); */ + } + printk(" >\n"); + + put_dev_sector(sect); + return 1; + } + + msrs = (struct msdos_rootsector *)rs; + if (is_msdos_protective_mbr(msrs)) + { + printk(" [PMBR]"); + ars = NULL; + for (i = 0; i < 4; i++) + { + mspart = &msrs->parts[i]; + if (is_partition_table_link(mspart)) + { + /* printk("#%i", i); */ + ars = (struct apt_rootsector *) read_dev_sector(bdev, mspart->beg, &aptsect); + /* if (ars) + print_sector(ars); */ + break; + } + } + } + else + ars = (struct apt_rootsector *)rs; + + if ((ars != NULL) && is_apt_partition_table(ars->head)) + { + printk(" APT<"); + + /* printk("Hard disk size is %i\n", hd_size); + printk("Partition table revision %i\n", (ars->head->hflags & APT_HFLAGS_REV) >> APT_HFLAGS_REV_BIT); */ + aoff = 0; + slot = 1; + while (ars != NULL) + { + ahead = &ars->head[aoff]; + aslot = 1 + (ahead->hflags & APT_HFLAGS_MAPSLOTS); /* at nonfirst partition sector mapping slots number should be 0 */ + for (i = aslot; i < ahead->entries; i++) + { + apart = &ars->part[aoff + i]; + pbeg = apart->pbeg; + plen = apart->plen; + pflags = apart->pflags; + ptype = apart->ptype; + daflags = apart->pdos.daflags; + poff = apart->pdos.offset; + /* printk("Partition entry %i (poff %i, pbeg %i, plen %i, ptype $%02x, pflags $%02x, daflags $%02x) in slot %i", + aoff + i, poff, pbeg, plen, ptype, pflags, daflags, slot); */ + if (is_valid_apt_partition(pflags, ptype, daflags, poff, pbeg, plen, hd_size)) + { + put_partition(state, slot, poff + pbeg, plen); + /* printk(" added\n"); */ + } + /* else + printk(" passed\n"); */ + slot++; + } + if (ahead->nextsec > 0) + { + /* printk("Next partition sector %i\n", ahead->nextsec); */ + aoff = ahead->nextent; + ars = (struct apt_rootsector *) read_dev_sector(bdev, ahead->nextsec, &aptsect); + /* print_sector(ars); */ + } + else + ars = NULL; + } + printk(" >\n"); + + put_dev_sector(sect); + return 1; + } + + printk("\n"); + put_dev_sector(sect); + return 0; +} + diff -Naur linux-source-2.6.32-orig/fs/partitions/atari8.h linux-source-2.6.32/fs/partitions/atari8.h --- linux-source-2.6.32-orig/fs/partitions/atari8.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-source-2.6.32/fs/partitions/atari8.h 2011-10-26 21:34:07.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * fs/partitions/atari8.h + * Created by Jerzy Kut + * Based on 16/32-bit Atari partition table support. + */ + +#define KMK_IDEA_PMAGIC_SIGNATURE 0x728 + +#define KMK_IDEA_PSTATS_ACTIVE (1 << 7) +#define KMK_IDEA_PSTATS_READONLY (1 << 5) +#define KMK_IDEA_PSTATS_SLAVE (1 << 4) + +#define KMK_IDEA_PINDEX_MASTER 0 +#define KMK_IDEA_PINDEX_SLAVE 1 + +#define KMK_IDEA_BOOTMODE_D1 0 +#define KMK_IDEA_BOOTMODE_BOOTDRV 1 + +#define KMK_IDEA_PCLSIZE_256 0 +#define KMK_IDEA_PCLSIZE_512 0xff + +struct kmk_idea_rootsector +{ + u8 pstats[16]; /* partition flags */ + u8 pindex[16]; /* partition mapped index */ + u8 pbeglo[16]; /* first sector of partition */ + u8 pbegmd[16]; + u8 pbeghi[16]; + u8 plenlo[16]; /* partition size */ + u8 plenmd[16]; + u8 plenhi[16]; + u16 pmagic; /* magic KMK/IDEA signature */ + u8 ignore1[0x95-0x82]; + u8 pidestr[3]; /* "IDE" string */ + u8 ignore2[0x9b-0x98]; + u8 retries; /* retries operation count - 1 */ + u8 ignore3[0xa6-0x9c]; + u8 bootdrv; /* boot drive number */ + u8 bootmod; /* boot mode */ + u8 ignore4[0xab-0xa8]; + u8 redir; /* disk number mapped as D1: */ + u8 pclsize[16]; /* cluster size flag */ + u8 ignore5[0xc6-0xbc]; + u8 pcllo[16]; /* cluster size in bytes */ + u8 pclhi[16]; + u8 ignore6[0x200-0xe6]; +} __attribute__((__packed__)); + +#define APT_HFLAGS_REV_BIT 5 + +#define APT_HFLAGS_LO (1 << 7) +#define APT_HFLAGS_REV (3 << APT_HFLAGS_REV_BIT) +#define APT_HFLAGS_MAPSLOTS 0xf + +#define APT_PFLAGS_RESERVED (1 << 7) +#define APT_PFLAGS_META (1 << 6) +#define APT_PFLAGS_MAP (3 << 2) +#define APT_PFLAGS_MAPLOBYTE (0 << 2) +#define APT_PFLAGS_MAPLOPAD (1 << 2) +#define APT_PFLAGS_MAPINTLBYTE (2 << 2) +#define APT_PFLAGS_MAPINTLSECT (3 << 2) +#define APT_PFLAGS_SECT (3 << 0) +#define APT_PFLAGS_END 0 +#define APT_PFLAGS_SECT128 1 +#define APT_PFLAGS_SECT256 2 +#define APT_PFLAGS_SECT512 3 + +#define APT_PTYPE_DOS 0 +#define APT_PTYPE_CONFIG 1 +#define APT_PTYPE_FLOPPY 2 + +#define APT_DAFLAGS_WPROTECT (1 << 7) +#define APT_DAFLAGS_ACTIVE (1 << 6) + +struct apt_header +{ + u8 hflags; /* header flags */ + u8 hsign[3]; /* "APT" signature */ + u8 bootdrv; /* boot drive number */ + u8 entries; /* number of entries in current table sector */ + u8 nextent; /* offset of next entry in next partition table sector (in paragraphs) */ + u8 prevent; /* offset of previous entry in previous partition table sector (in paragraphs) */ + u32 nextsec; /* next partition table sector */ + u32 prevsec; /* previous partition table sector */ +} __attribute__((__packed__)); + +struct apt_dos +{ + u8 daflags; /* DOS access flags */ + u8 reserved; + u16 offset; /* offset to a sector */ +} __attribute__((__packed__)); + +struct apt_floppy +{ + u16 chsize; /* chunk size */ + u16 reserved; +} __attribute__((__packed__)); + +struct apt_partition +{ + u8 pflags; /* partition flags */ + u8 ptype; /* partition type */ + u32 pbeg; /* first sector of partition */ + u32 plen; /* partition size (in sectors) */ + u16 pid; /* partition ID */ + union + { + struct apt_dos pdos; + struct apt_floppy pflop; + }; +} __attribute__((__packed__)); + +struct apt_rootsector +{ + union + { + struct apt_header head[32]; + struct apt_partition part[32]; + }; +} __attribute__((__packed__)); + +int atari8_partition(struct parsed_partitions *state, struct block_device *bdev); + diff -Naur linux-source-2.6.32-orig/fs/partitions/check.c linux-source-2.6.32/fs/partitions/check.c --- linux-source-2.6.32-orig/fs/partitions/check.c 2009-12-03 03:51:21.000000000 +0000 +++ linux-source-2.6.32/fs/partitions/check.c 2011-10-26 21:34:12.000000000 +0000 @@ -26,6 +26,7 @@ #include "acorn.h" #include "amiga.h" #include "atari.h" +#include "atari8.h" #include "ldm.h" #include "mac.h" #include "msdos.h" @@ -81,6 +82,9 @@ #ifdef CONFIG_LDM_PARTITION ldm_partition, /* this must come before msdos */ #endif +#ifdef CONFIG_ATARI8_PARTITION + atari8_partition, /* this must come before msdos */ +#endif #ifdef CONFIG_MSDOS_PARTITION msdos_partition, #endif