119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * dosio.c -- Disk I/O module for the ext2fs/DOS library. 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (c) 1997 by Theodore Ts'o. 53984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (c) 1997 Mark Habersack 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %Begin-Header% 98558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library 108558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2. 118558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %End-Header% 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <bios.h> 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h> 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <io.h> 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ext2fs/ext2_types.h> 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "utils.h" 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "dosio.h" 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "et/com_err.h" 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_err.h" 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs/io.h" 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Some helper macros 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LINUX_EXT2FS 0x83 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LINUX_SWAP 0x82 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define WRITE_ERR(_msg_) write(2, _msg_, strlen(_msg_)) 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define WRITE_ERR_S(_msg_) write(2, _msg_, sizeof(_msg_)) 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Exported variables 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectunsigned long _dio_error; 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectunsigned long _dio_hw_error; 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Array of all opened partitions 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic PARTITION **partitions = NULL; 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned short npart = 0; /* Number of mapped partitions */ 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic PARTITION *active = NULL; 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * I/O Manager routine prototypes 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_open(const char *dev, int flags, io_channel *channel); 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_close(io_channel channel); 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_set_blksize(io_channel channel, int blksize); 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_read_blk(io_channel channel, unsigned long block, 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, void *buf); 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_write_blk(io_channel channel, unsigned long block, 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, const void *buf); 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_flush(io_channel channel); 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic struct struct_io_manager struct_dos_manager = { 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_ET_MAGIC_IO_MANAGER, 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "DOS I/O Manager", 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dos_open, 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dos_close, 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dos_set_blksize, 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dos_read_blk, 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dos_write_blk, 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dos_flush 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectio_manager dos_io_manager = &struct_dos_manager; 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Macro taken from unix_io.c 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * For checking structure magic numbers... 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define EXT2_CHECK_MAGIC(struct, code) \ 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((struct)->magic != (code)) return (code) 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Calculates a CHS address of a sector from its LBA 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * offset for the given partition. 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void lba2chs(unsigned long lba_addr, CHS *chs, PARTITION *part) 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long abss; 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs->offset = lba_addr & 0x000001FF; 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project abss = (lba_addr >> 9) + part->start; 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs->cyl = abss / (part->sects * part->heads); 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs->head = (abss / part->sects) % part->heads; 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs->sector = (abss % part->sects) + 1; 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__ 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#pragma argsused 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Scans the passed partition table looking for *pno partition 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * that has LINUX_EXT2FS type. 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * TODO: 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * For partition numbers >5 Linux uses DOS extended partitions - 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * dive into them an return an appropriate entry. Also dive into 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * extended partitions when scanning for a first Linux/ext2fs. 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic PTABLE_ENTRY *scan_partition_table(PTABLE_ENTRY *pentry, 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned short phys, 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char *pno) 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned i; 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(*pno != 0xFF && *pno >= 5) 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return NULL; /* We don't support extended partitions for now */ 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(*pno != 0xFF) 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(pentry[*pno].type == LINUX_EXT2FS) 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return &pentry[*pno]; 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!pentry[*pno].type) 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *pno = 0xFE; 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if(pentry[*pno].type == LINUX_SWAP) 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *pno = 0xFD; 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return NULL; 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for(i = 0; i < 4; i++) 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(pentry[i].type == LINUX_EXT2FS) 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *pno = i; 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return &pentry[i]; 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return NULL; 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Allocate libext2fs structures associated with I/O manager 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic io_channel alloc_io_channel(PARTITION *part) 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project io_channel ioch; 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch = (io_channel)malloc(sizeof(struct struct_io_channel)); 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ioch) 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return NULL; 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(ioch, 0, sizeof(struct struct_io_channel)); 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->magic = EXT2_ET_MAGIC_IO_CHANNEL; 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->manager = dos_io_manager; 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->name = (char *)malloc(strlen(part->dev)+1); 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ioch->name) { 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(ioch); 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return NULL; 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strcpy(ioch->name, part->dev); 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->private_data = part; 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->block_size = 1024; /* The smallest ext2fs block size */ 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->read_error = 0; 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ioch->write_error = 0; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ioch; 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__ 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#pragma argsused 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Open the 'name' partition, initialize all information structures 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * we need to keep and create libext2fs I/O manager. 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_open(const char *dev, int flags, io_channel *channel) 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char *tmp, sec[512]; 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project PARTITION *part; 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project PTABLE_ENTRY *pent; 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project PARTITION **newparts; 1853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!dev) 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_BADDEV; 18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_BAD_DEVICE_NAME; 19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * First check whether the dev name is OK 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project tmp = (unsigned char*)strrchr(dev, '/'); 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!tmp) 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_BADDEV; 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_BAD_DEVICE_NAME; 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *tmp = 0; 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(strcmp(dev, "/dev")) 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_BADDEV; 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EXT2_ET_BAD_DEVICE_NAME; 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *tmp++ = '/'; 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check whether the partition data is already in cache 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part = (PARTITION*)malloc(sizeof(PARTITION)); 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!part) 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENOMEM; 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i = 0; 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for(;i < npart; i++) 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!strcmp(partitions[i]->dev, dev)) 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Found it! Make it the active one */ 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project active = partitions[i]; 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *channel = alloc_io_channel(active); 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!*channel) 22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENOMEM; 22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Drive number & optionally partn number 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project switch(tmp[0]) 23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'h': 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 's': 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys = 0x80; 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys += toupper(tmp[2]) - 'A'; 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Do we have the partition number? 24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(tmp[3]) 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->pno = isdigit((int)tmp[3]) ? tmp[3] - '0' - 1: 0; 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->pno = 0xFF; 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'f': 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(tmp[2]) 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys = isdigit((int)tmp[2]) ? tmp[2] - '0' : 0; 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys = 0x00; /* We'll assume /dev/fd0 */ 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project default: 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_BADDEV; 25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENODEV; 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(part->phys < 0x80) 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* We don't support floppies for now */ 26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_NOTSUPP; 26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EINVAL; 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->dev = strdup(dev); 26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Get drive's geometry 27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_hw_error = biosdisk(DISK_GET_GEOMETRY, 27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys, 27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 0, /* head */ 27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 0, /* cylinder */ 27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1, /* sector */ 27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1, /* just one sector */ 27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sec); 28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!HW_OK()) 28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_HARDWARE; 2843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(part->dev); 2853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(part); 28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EFAULT; 28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Calculate the geometry 29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->cyls = (unsigned short)(((sec[0] >> 6) << 8) + sec[1] + 1); 29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->heads = sec[3] + 1; 29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->sects = sec[0] & 0x3F; 29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Now that we know all we need, let's look for the partition 29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_hw_error = biosdisk(DISK_READ, part->phys, 0, 0, 1, 1, sec); 30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!HW_OK()) 30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_HARDWARE; 3043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(part->dev); 3053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(part); 30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EFAULT; 30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pent = (PTABLE_ENTRY*)&sec[0x1BE]; 31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pent = scan_partition_table(pent, part->phys, &part->pno); 31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!pent) 31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = part->pno == 0xFE ? ERR_EMPTYPART : 31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->pno == 0xFD ? ERR_LINUXSWAP : ERR_NOTEXT2FS; 3163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(part->dev); 3173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(part); 31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENODEV; 31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Calculate the remaining figures 32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long fsec, fhead, fcyl; 32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fsec = (unsigned long)(pent->start_sec & 0x3F); 32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fhead = (unsigned long)pent->start_head; 32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fcyl = ((pent->start_sec >> 6) << 8) + pent->start_cyl; 33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->start = fsec + fhead * part->sects + fcyl * 33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (part->heads * part->sects) - 1; 33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->len = pent->size; 33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Add the partition to the table 33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project newparts = (PARTITION**)realloc(partitions, sizeof(PARTITION) * npart); 33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!newparts) { 34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(part); 34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENOMEM; 34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project partitions = newparts; 34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project partitions[npart++] = active = part; 34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Now alloc all libe2fs structures 34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *channel = alloc_io_channel(active); 35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!*channel) 35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENOMEM; 35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_close(io_channel channel) 35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 3583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(channel->name); 3593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(channel); 36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 36419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_set_blksize(io_channel channel, int blksize) 36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project channel->block_size = blksize; 36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_read_blk(io_channel channel, unsigned long block, 37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, void *buf) 37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project PARTITION *part; 37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t size; 37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_loff_t loc; 37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project CHS chs; 37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 37919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 38019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part = (PARTITION*)channel->private_data; 38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size = (size_t)((count < 0) ? -count : count * channel->block_size); 38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project loc = (ext2_loff_t) block * channel->block_size; 38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project lba2chs(loc, &chs, part); 38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Potential bug here: 38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If DJGPP is used then reads of >18 sectors will fail! 38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Have to rewrite biosdisk. 39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_hw_error = biosdisk(DISK_READ, 39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys, 39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs.head, 39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs.cyl, 39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs.sector, 39619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size < 512 ? 1 : size/512, 39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf); 39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!HW_OK()) 40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_HARDWARE; 40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EFAULT; 40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_write_blk(io_channel channel, unsigned long block, 40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, const void *buf) 41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project PARTITION *part; 41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t size; 41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_loff_t loc; 41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project CHS chs; 41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); 41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part = (PARTITION*)channel->private_data; 41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(count == 1) 42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size = (size_t)channel->block_size; 42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (count < 0) 42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size = (size_t)-count; 42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size = (size_t)(count * channel->block_size); 42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project loc = (ext2_loff_t)block * channel->block_size; 43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project lba2chs(loc, &chs, part); 43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_hw_error = biosdisk(DISK_WRITE, 43219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project part->phys, 43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs.head, 43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs.cyl, 43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project chs.sector, 43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size < 512 ? 1 : size/512, 43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (void*)buf); 43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if(!HW_OK()) 44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _dio_error = ERR_HARDWARE; 44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return EFAULT; 44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__ 44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#pragma argsused 45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_flush(io_channel channel) 45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * No buffers, no flush... 45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 45619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 458