/* * lib/scheme/eesox.c * * Partition backend for Eesox SCSI partitioning scheme on the * Acorn machines. * * Copyright (C) 1998 Russell King */ #include <assert.h> #include <stdlib.h> #include <string.h> #include "util/debug.h" #include "util/error.h" #include "util/types.h" #include "part/part.h" #include "part/utils.h" #define EESOX_SECTOR_SIZE 512 #define EESOX_PART_SECTOR 7 #define EESOX_NR_PARTITIONS 8 #define NOSAVE_POWERTEC 00025 typedef struct { char magic[6]; char discname[10]; u32 start; u32 unused6; u32 unused7; u32 unused8; } ep_t; 00034 typedef union { ep_t ep[EESOX_NR_PARTITIONS]; u8 sector[EESOX_SECTOR_SIZE]; } eesox_psect_t; static const char eesox_name[] = { 'N', 'e', 'i', 'l', ' ', 'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' ' }; /* Prototype: u_int eesox_detect(part_t *part) * Function : detect a drive partitioned with an ICS IDE table * Params : part - partitionable device * Returns : FALSE if not detected */ static u_int eesox_detect(part_t *part) { eesox_psect_t sector; u_int ret = 0; dbg_printf("eesox_detect()"); dbg_level_up(); assert(part != NULL); do { u_int i; if (blkio_setblocksize(part->blkio, EESOX_SECTOR_SIZE) != EESOX_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector.sector, EESOX_PART_SECTOR, 1) != 1) break; for (i = 0; i < EESOX_SECTOR_SIZE; i++) sector.sector[i] ^= eesox_name[i & 15]; if (memcmp(sector.sector, "Eesox", 6) == 0) ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } /* Prototype: u_int eesox_readinfo(part_t *part) * Function : read all partition information from the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int eesox_readinfo(part_t *part) { u_int ret = 0; dbg_printf("eesox_readinfo()"); dbg_level_up(); assert(part != NULL); do { eesox_psect_t sector; partinfo_i_t pinfo; u_int part_no, i; if (blkio_read(part->blkio, sector.sector, EESOX_PART_SECTOR, 1) != 1) break; for (i = 0; i < EESOX_SECTOR_SIZE; i++) sector.sector[i] ^= eesox_name[i & 15]; ret = 1; for (part_no = 0; part_no < EESOX_NR_PARTITIONS; part_no++) if (memcmp(sector.ep[part_no].magic, "Eesox", 6) == 0) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.ep[part_no].start; pinfo.info.blk_end = sector.ep[part_no].start + 1; pinfo.info.kern_part_no = part_no + 1; pinfo.info.type = ptyp_filecore; dbg_memdump(§or.ep[part_no], sizeof(sector.ep[part_no])); if (!part_add(part, part_no + 1, &pinfo)) { ret = 0; break; } /* should we check the filecore boot sector? */ } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int eesox_writeinfo(part_t *part) * Function : write all partition information back to the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int eesox_writeinfo(part_t *part) { u_int ret = 0; dbg_printf("eesox_writeinfo()"); dbg_level_up(); assert(part != NULL); assert(part->nr_partitions <= EESOX_NR_PARTITIONS); set_error("EESOX partition information cannot be saved with this build"); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int eesox_allocate(part_t *part, partinfo_t *pnew) * Function : allocate a partition entry number and a kernel * partition number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int eesox_allocate(part_t *part, partinfo_t *pnew) { u_int parn = PARN_ERROR; assert(part != NULL); dbg_printf("eesox_allocate()"); dbg_level_up(); dbg_level_down(); dbg_printf("ret %d", parn); return parn; } /* Prototype: u_int eesox_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int eesox_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("eesox_validate_change(parn=%d)", parn); dbg_level_up(); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int eesox_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int eesox_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("eesox_validate_creation(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int eesox_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Function : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int eesox_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("eesox_validate_deletion(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int eesox_validate_partno(part_t *part, u_int parn) * Function : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int eesox_validate_partno(part_t *part, u_int parn) { u_int ret = 0; assert(part != NULL); dbg_printf("eesox_validate_partno(parn=%d)", parn); dbg_level_up(); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: ptyp_t eesox_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : return next valid partition type for an entry * Params : part - partitionable device * : parn - partition number * : current - currently selected partition type * : dir - next/previous flag * Returns : next valid partition type */ static ptyp_t eesox_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { ptyp_t ptype = current; dbg_printf("eesox_nexttype(parn=%d, current=0x%X, %s)", parn, current, dir > 0 ? "next" : dir < 0 ? "previous" : "???"); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); dbg_level_down(); dbg_printf("ret 0x%X", ptype); return ptype; } scheme_t eesox_scheme = { "EESOX", eesox_detect, eesox_readinfo, eesox_writeinfo, eesox_allocate, eesox_validate_change, eesox_validate_creation, eesox_validate_deletion, eesox_validate_partno, eesox_nexttype };