/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2002 by Björn Stenberg * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include #include "ata.h" #include "debug.h" #include "fat.h" #ifdef HAVE_HOTSWAP #include "hotswap.h" #include "dir.h" /* for release_dirs() */ #include "file.h" /* for release_files() */ #endif #include "disk.h" #include /* Partition table entry layout: ----------------------- 0: 0x80 - active 1: starting head 2: starting sector 3: starting cylinder 4: partition type 5: end head 6: end sector 7: end cylinder 8-11: starting sector (LBA) 12-15: nr of sectors in partition */ #define BYTES2INT32(array,pos) \ ((long)array[pos] | ((long)array[pos+1] << 8 ) | \ ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 )) static struct partinfo part[8]; /* space for 4 partitions on 2 drives */ static int vol_drive[NUM_VOLUMES]; /* mounted to which drive (-1 if none) */ #ifdef MAX_LOG_SECTOR_SIZE int disk_sector_multiplier = 1; #endif struct partinfo* disk_init(IF_MV_NONVOID(int drive)) { int i; unsigned char sector[512]; #ifdef HAVE_MULTIVOLUME /* For each drive, start at a different position, in order not to destroy the first entry of drive 0. That one is needed to calculate config sector position. */ struct partinfo* pinfo = &part[drive*4]; if ((size_t)drive >= sizeof(part)/sizeof(*part)/4) return NULL; /* out of space in table */ #else struct partinfo* pinfo = part; #endif ata_read_sectors(IF_MV2(drive,) 0,1, §or); #ifndef CREATIVE_ZVx /* check that the boot sector is initialized */ if ( (sector[510] != 0x55) || (sector[511] != 0xaa)) { DEBUGF("Bad boot sector signature\n"); return NULL; } /* parse partitions */ for ( i=0; i<4; i++ ) { unsigned char* ptr = sector + 0x1be + 16*i; pinfo[i].type = ptr[4]; pinfo[i].start = BYTES2INT32(ptr, 8); pinfo[i].size = BYTES2INT32(ptr, 12); DEBUGF("Part%d: Type %02x, start: %08lx size: %08lx\n", i,pinfo[i].type,pinfo[i].start,pinfo[i].size); /* extended? */ if ( pinfo[i].type == 5 ) { /* not handled yet */ } } #else struct partition_struct { unsigned int end; unsigned int start; char name[8]; }; struct hdd_struct { unsigned char MBLK[4]; int sector_size; long long total_disk_size; struct partition_struct partitions[4]; }; struct hdd_struct* hdd_struct = (struct hdd_struct*)sector; if(hdd_struct->MBLK[0] != 0x4B || hdd_struct->MBLK[1] != 0x4C || hdd_struct->MBLK[2] != 0x42 || hdd_struct->MBLK[3] != 0x4D) /* 0x4B4C424D = KLBM */ { DEBUGF("Bad boot sector signature\n"); return NULL; } else { /* parse partitions */ for ( i=0; i<4; i++ ) { if(hdd_struct->partitions[i].name[0] != 0) { pinfo[i].type = ( strcmp(hdd_struct->partitions[i].name, "cfs") == 0 ? PARTITION_TYPE_FAT32_LBA : 0); pinfo[i].start = hdd_struct->partitions[i].start; pinfo[i].size = (hdd_struct->partitions[i].end - hdd_struct->partitions[i].start); DEBUGF("Part%d: Type %02x, start: %08lx size: %08lx\n", i,pinfo[i].type,pinfo[i].start,pinfo[i].size); } } } #endif return pinfo; } struct partinfo* disk_partinfo(int partition) { return &part[partition]; } int disk_mount_all(void) { int mounted; int i; #ifdef HAVE_HOTSWAP card_enable_monitoring(false); #endif fat_init(); /* reset all mounted partitions */ for (i=0; i