Пример #1
0
int apaJournalRestore(s32 device)
{	// copys apa headers from apal to apa system
	int i;
	u32 sector;
	apa_cache_t *clink;

	APA_PRINTF(APA_DRV_NAME": checking log...\n");
	if(ata_device_sector_io(device, &journalBuf, APA_SECTOR_APAL, sizeof(apa_journal_t)/512, ATA_DIR_READ)){
		apaJournalReset(device);
		return -EIO;
	}
	if(journalBuf.magic==APAL_MAGIC)
	{
		if(journalBuf.num==0)
			return 0;
		clink=apaCacheAlloc();
		for(i=0, sector=APA_SECTOR_APAL_HEADERS;i<journalBuf.num;i++, sector+=2)
		{
			if(ata_device_sector_io(device, clink->header, sector, 2, ATA_DIR_READ))
				break;
			if(ata_device_sector_io(device, clink->header, journalBuf.sectors[i], 2, ATA_DIR_WRITE))
				break;
		}
		apaCacheFree(clink);
		return apaJournalReset(device);// only do if journal..
	}
	memset(&journalBuf, 0, sizeof(apa_journal_t));// safe e
	journalBuf.magic=APAL_MAGIC;
	return 0;//-EINVAL;
}
Пример #2
0
static int apaOpen(s32 device, hdd_file_slot_t *fileSlot, apa_params_t *params, int mode)
{
	int				rv=0;
	u32				emptyBlocks[32];
	apa_cache_t		*clink;
	apa_cache_t		*clink2;
	u32				sector=0;

	// walk all looking for any empty blocks & look for partition
	clink=apaCacheGetHeader(device, 0, APA_IO_MODE_READ, &rv);
	memset(&emptyBlocks, 0, sizeof(emptyBlocks));
	while(clink)
	{
		sector=clink->sector;
		if(!(clink->header->flags & APA_FLAG_SUB)) {
			if(memcmp(clink->header->id, params->id, APA_IDMAX) == 0)
				break;	// found :)
		}
		apaAddEmptyBlock(clink->header, emptyBlocks);
		clink=apaGetNextHeader(clink, &rv);
	}

	if(rv!=0)
		return rv;
	rv=-ENOENT;

	if(clink==NULL && (mode & O_CREAT))
	{
		if((rv=hddCheckPartitionMax(device, params->size))>=0) {
			if((clink=hddAddPartitionHere(device, params, emptyBlocks, sector, &rv))!=NULL)
			{
				sector=clink->header->start;
				clink2=apaCacheAlloc();
				memset(clink2->header, 0, sizeof(apa_header_t));
				ata_device_sector_io(device, clink2->header, sector+8     , 2, ATA_DIR_WRITE);
				ata_device_sector_io(device, clink2->header, sector+0x2000, 2, ATA_DIR_WRITE);
				apaCacheFree(clink2);
			}
		}
	}
	if(clink==NULL)
		return rv;
	fileSlot->parts[0].start=clink->header->start;
	fileSlot->parts[0].length=clink->header->length;
	memcpy(&fileSlot->parts[1], &clink->header->subs, APA_MAXSUB*sizeof(apa_sub_t));
	fileSlot->type=clink->header->type;
	fileSlot->nsub=clink->header->nsub;
	memcpy(&fileSlot->id, &clink->header->id, APA_IDMAX);
	apaCacheFree(clink);
	if(apaPassCmp(clink->header->fpwd, params->fpwd)!=0)
	{
		rv = (!(mode & O_WRONLY)) ? apaPassCmp(clink->header->rpwd, params->rpwd) : -EACCES;
	} else
		rv = 0;

	return rv;
}
Пример #3
0
static int fioDataTransfer(iop_file_t *f, void *buf, int size, int mode)
{
	hdd_file_slot_t *fileSlot=(hdd_file_slot_t *)f->privdata;

	if((size & 0x1FF))
		return -EINVAL;
	size>>=9;	// size/512

	if(fileSlot->post+size>=0x1FF9)// no over reading
		size=0x1FF8-fileSlot->post;

	if(size!=0) {
		int rv=0;

		WaitSema(fioSema);
		if(ata_device_sector_io(f->unit, buf, fileSlot->post+fileSlot->parts[0].start+8, size, mode))
			rv=-EIO;
		SignalSema(fioSema);
		if(rv==0)
		{
			fileSlot->post+=size;
			return size<<9;
		}

		return rv;
	}
	return 0;
}
Пример #4
0
void apaSaveError(s32 device, void *buffer, u32 lba, u32 err_lba)
{
    memset(buffer, 0, 512);
    *(u32 *)buffer = err_lba;
    ata_device_sector_io(device, buffer, lba, 1, ATA_DIR_WRITE);
    ata_device_flush_cache(device);
}
Пример #5
0
int apaJournalWrite(apa_cache_t *clink)
{
	clink->header->checksum=journalCheckSum(clink->header);
	if(ata_device_sector_io(clink->device, clink->header,
		(journalBuf.num << 1)+APA_SECTOR_APAL_HEADERS, 2, ATA_DIR_WRITE))
			return -EIO;
	journalBuf.sectors[journalBuf.num]=clink->sector;
	journalBuf.num++;
	return 0;
}
Пример #6
0
int apaJournalFlush(s32 device)
{// this write any thing that in are journal buffer :)
	if(ata_device_flush_cache(device))
		return -EIO;
	if(ata_device_sector_io(device, &journalBuf, APA_SECTOR_APAL, 1, ATA_DIR_WRITE))
		return -EIO;
	if(ata_device_flush_cache(device))
		return -EIO;
	return 0;
}
Пример #7
0
int apaReadHeader(s32 device, apa_header_t *header, u32 lba)
{
    if (ata_device_sector_io(device, header, lba, 2, ATA_DIR_READ) != 0)
        return -EIO;
    if (header->magic != APA_MAGIC)
        return -EIO;
    if (apaCheckSum(header) != header->checksum)
        return -EIO;
    if (lba == APA_SECTOR_MBR) {
        if (strncmp(header->mbr.magic, apaMBRMagic, sizeof(header->mbr.magic)) == 0)
            return 0;
        APA_PRINTF(APA_DRV_NAME ": error: invalid partition table or version newer than I know.\n");
        return -EIO;
    }
    return 0;
}
Пример #8
0
int apaGetPartErrorSector(s32 device, u32 lba, u32 *lba_out)
{
    apa_cache_t *clink;
    int rv = 0;

    if (!(clink = apaCacheAlloc()))
        return -ENOMEM;

    if (ata_device_sector_io(device, clink->header, lba, 1, ATA_DIR_READ))
        return -EIO;

    if (lba_out)
        *lba_out = *clink->error_lba;
    if (*clink->error_lba)
        rv = 1; // error is set ;)
    apaCacheFree(clink);
    return rv;
}
Пример #9
0
static int ioctl2Transfer(s32 device, hdd_file_slot_t *fileSlot, hddIoctl2Transfer_t *arg)
{
	if(fileSlot->nsub<arg->sub)
		return -ENODEV;

	// main partitions can only be read starting from the 4MB offset.
	if(arg->sub==0 && (arg->sector < 0x2000))
		return -EINVAL;
	 // sub-partitions can only be read starting from after the header.
	if(arg->sub!=0 && (arg->sector < 2))
		return -EINVAL;

	if(fileSlot->parts[arg->sub].length<arg->sector+arg->size)
		return -ENXIO;

	if(ata_device_sector_io(device, arg->buffer,
		fileSlot->parts[arg->sub].start+arg->sector, arg->size, arg->mode))
		return -EIO;

	return 0;
}
Пример #10
0
int apaGetFormat(s32 device, int *format)
{
    apa_cache_t *clink;
    int rv = 0;
    u32 *pDW, i;

    clink = apaCacheAlloc();
    *format = 0;
    if ((rv = apaReadHeader(device, clink->header, 0)) == 0) {
        *format = clink->header->mbr.version;
        if (ata_device_sector_io(device, clink->header, APA_SECTOR_SECTOR_ERROR, 2, ATA_DIR_READ))
            rv = -EIO; // return -EIO;
        if (rv == 0) {
            pDW = (u32 *)clink->header;
            for (i = 0; i < 256; i++) {
                if ((i & 0x7F) && pDW[i] != 0)
                    rv = 1;
            }
        }
    }
    apaCacheFree(clink);
    return rv == 0;
}
Пример #11
0
int hddDevctl(iop_file_t *f, const char *devname, int cmd, void *arg,
			  unsigned int arglen, void *bufp, unsigned int buflen)
{
	int	rv=0;

	WaitSema(fioSema);
	switch(cmd)
	{
	// Command set 1 ('H')
	case HDIOC_DEV9OFF:
		//Early versions called ata_device_smart_save_attr() here, when their old dev9 versions did not support the pre-shutdown callback.
		dev9Shutdown();
		break;

	case HDIOC_IDLE:
		rv=ata_device_idle(f->unit, *(char *)arg);
		break;

	case HDIOC_MAXSECTOR:
		rv=hddDevices[f->unit].partitionMaxSize;
		break;

	case HDIOC_TOTALSECTOR:
		rv=hddDevices[f->unit].totalLBA;
		break;

	case HDIOC_FLUSH:
		if(ata_device_flush_cache(f->unit))
			rv=-EIO;
		break;

	case HDIOC_SWAPTMP:
		rv=devctlSwapTemp(f->unit, (char *)arg);
		break;

	case HDIOC_SMARTSTAT:
		rv=ata_device_smart_get_status(f->unit);
		break;

	case HDIOC_STATUS:
		rv=hddDevices[f->unit].status;
		break;

	case HDIOC_FORMATVER:
		rv=hddDevices[f->unit].format;
		break;

	case HDIOC_FREESECTOR:
		rv=apaGetFreeSectors(f->unit, bufp, hddDevices);
		break;

	case HDIOC_IDLEIMM:
		rv=ata_device_idle_immediate(f->unit);
		break;

	// Command set 2 ('h')
	case HDIOC_GETTIME:
		rv=apaGetTime((apa_ps2time_t *)bufp);
		break;

	case HDIOC_SETOSDMBR:
		rv=devctlSetOsdMBR(f->unit, (hddSetOsdMBR_t *)arg);
		break;

	case HDIOC_GETSECTORERROR:
		rv=apaGetPartErrorSector(f->unit, APA_SECTOR_SECTOR_ERROR, 0);
		break;

	case HDIOC_GETERRORPARTNAME:
		rv=apaGetPartErrorName(f->unit, (char *)bufp);
		break;

	case HDIOC_READSECTOR:
		rv=ata_device_sector_io(f->unit, (void *)bufp, ((hddAtaTransfer_t *)arg)->lba,
			((hddAtaTransfer_t *)arg)->size, ATA_DIR_READ);
		break;

	case HDIOC_WRITESECTOR:
		rv=ata_device_sector_io(f->unit, ((hddAtaTransfer_t *)arg)->data,
			((hddAtaTransfer_t *)arg)->lba, ((hddAtaTransfer_t *)arg)->size,
				ATA_DIR_WRITE);
		break;

	case HDIOC_SCEIDENTIFY:
		rv=ata_device_sce_identify_drive(f->unit, (u16 *)bufp);
		break;

	default:
		rv=-EINVAL;
		break;
	}
	SignalSema(fioSema);

	return rv;
}
Пример #12
0
int hddFormat(iop_file_t *f, const char *dev, const char *blockdev, void *arg, int arglen)
{
	int				rv=0;
	apa_cache_t		*clink;
	u32			i;
#ifdef APA_FORMAT_MAKE_PARTITIONS
	apa_params_t		params;
	u32				emptyBlocks[32];
#endif

	if(f->unit >= 2)
		return -ENXIO;

	// clear all errors on hdd
	clink=apaCacheAlloc();
	memset(clink->header, 0, sizeof(apa_header_t));
	if(ata_device_sector_io(f->unit, clink->header, APA_SECTOR_SECTOR_ERROR, 1, ATA_DIR_WRITE)){
		apaCacheFree(clink);
		return -EIO;
	}
	if(ata_device_sector_io(f->unit, clink->header, APA_SECTOR_PART_ERROR, 1, ATA_DIR_WRITE)){
		apaCacheFree(clink);
		return -EIO;
	}
	// clear apa headers
	for(i=1024*8;i<hddDevices[f->unit].totalLBA;i+=(1024*256))
	{
		ata_device_sector_io(f->unit, clink->header, i, sizeof(apa_header_t)/512,
			ATA_DIR_WRITE);
	}
	apaCacheFree(clink);
	if((rv=apaJournalReset(f->unit))!=0)
		return rv;

	// set up mbr :)
	if((clink=apaCacheGetHeader(f->unit, 0, APA_IO_MODE_WRITE, &rv))){
		apa_header_t *header=clink->header;
		memset(header, 0, sizeof(apa_header_t));
		header->magic=APA_MAGIC;
		header->length=(1024*256);	// 128MB
		header->type=APA_TYPE_MBR;
		strcpy(header->id,"__mbr");
#ifdef APA_FORMAT_LOCK_MBR
		apaEncryptPassword(header->id, header->fpwd, "sce_mbr");
		apaEncryptPassword(header->id, header->rpwd, "sce_mbr");
#endif
		memcpy(header->mbr.magic, apaMBRMagic, sizeof(header->mbr.magic));

		header->mbr.version=APA_MBR_VERSION;
		header->mbr.nsector=0;
		apaGetTime(&header->created);
		apaGetTime(&header->mbr.created);
		header->checksum=apaCheckSum(header);
		clink->flags|=APA_CACHE_FLAG_DIRTY;
		apaCacheFlushDirty(clink);
		ata_device_flush_cache(f->unit);
		apaCacheFree(clink);
		hddDevices[f->unit].status=0;
		hddDevices[f->unit].format=APA_MBR_VERSION;
	}
#ifdef APA_FORMAT_MAKE_PARTITIONS
	memset(&emptyBlocks, 0, sizeof(emptyBlocks));
	memset(&params, 0, sizeof(apa_params_t));
	params.size=(1024*256);
	params.type=APA_TYPE_PFS;

	// add __net, __system....
	for(i=0;formatPartList[i];i++)
	{
		memset(params.id, 0, APA_IDMAX);
		strcpy(params.id, formatPartList[i]);
		if(!(clink=hddAddPartitionHere(f->unit, &params, emptyBlocks, i ? clink->sector : 0, &rv)))
			return rv;
		apaCacheFree(clink);

		params.size<<=1;
		if(hddDevices[f->unit].partitionMaxSize < params.size)
			params.size=hddDevices[f->unit].partitionMaxSize;
	}
#endif
	return rv;
}
Пример #13
0
int apaWriteHeader(s32 device, apa_header_t *header, u32 lba)
{
    if (ata_device_sector_io(device, header, lba, 2, ATA_DIR_WRITE))
        return -EIO;
    return 0;
}