apa_cache *apaFillHeader(u32 device, input_param *params, int start, int next, int prev, int length, int *err) { // used for makeing a new partition apa_cache *clink; if(!(clink=cacheGetHeader(device, start, 1, err))) return NULL; memset(clink->header, 0, sizeof(apa_header)); clink->header->magic=APA_MAGIC; clink->header->start=start; clink->header->next=next; clink->header->prev=prev; clink->header->length=length; clink->header->type=params->type; clink->header->flags=params->flags; clink->header->modver=APA_MODVER; memcpy(&clink->header->id, ¶ms->id, APA_IDMAX); if(params->flags & APA_FLAG_SUB) { clink->header->main=params->main; clink->header->number=params->number; } else { if(strncmp(clink->header->id, "_tmp", APA_IDMAX)!=0) { memcpy(&clink->header->rpwd, &myPassHash, APA_PASSMAX); memcpy(&clink->header->fpwd, &myPassHash, APA_PASSMAX); } } getPs2Time(&clink->header->created); clink->flags|=CACHE_FLAG_DIRTY; return clink; }
apa_cache *apaRemovePartition(u32 device, u32 start, u32 next, u32 prev, u32 length) { apa_cache *clink; u32 err; if((clink=cacheGetHeader(device, start, 1, (int *)&err))==NULL) return NULL; memset(clink->header, 0, sizeof(apa_header)); clink->header->magic=APA_MAGIC; clink->header->start=start; clink->header->next=next; clink->header->prev=prev; clink->header->length=length; strcpy(clink->header->id, "__empty"); getPs2Time(&clink->header->created); clink->flags|=CACHE_FLAG_DIRTY; return clink; }
void apaMakeEmpty(apa_cache *clink) { u32 saved_start; u32 saved_next; u32 saved_prev; u32 saved_length; saved_start = clink->header->start; saved_next = clink->header->next; saved_prev = clink->header->prev; saved_length = clink->header->length; memset(clink->header, 0, sizeof(apa_header)); clink->header->magic = APA_MAGIC; clink->header->start = saved_start; clink->header->next = saved_next; clink->header->prev = saved_prev; clink->header->length = saved_length; getPs2Time(&clink->header->created); strcpy(clink->header->id, "__empty"); clink->flags|=CACHE_FLAG_DIRTY; }
int _start(int argc, char **argv) { int i; char *input; int cacheSize=3; ps2time tm; t_shddInfo *hddInfo; printStartup(); // decode MBR Magic for(i=0;i!=0x20;i++) mbrMagic[i]^='x'; if((input=strrchr(argv[0], '/'))) input++; else input=argv[0]; argc--; argv++; while(argc) { if(argv[0][0] != '-') break; if(strcmp("-o", argv[0])==0){ argc--; argv++; if(!argc) return inputError(input); i=strtol(argv[0], 0, 10); if(i-1<32) maxOpen=i; } else if(strcmp("-n", argv[0])==0){ argc--; argv++; if(!argc) return inputError(input); i=strtol(*argv, 0, 10); if(cacheSize<i) cacheSize=i; } argc--; argv++; } printf("ps2hdd: max open = %ld, %d buffers\n", maxOpen, cacheSize); getPs2Time(&tm); printf("ps2hdd: %02d:%02d:%02d %02d/%02d/%d\n", tm.hour, tm.min, tm.sec, tm.month, tm.day, tm.year); for(i=0;i < 2;i++) { if(!(hddInfo=atadInit((u16)i))){ printf("ps2hdd: Error: ata initialization failed.\n"); return 0; } if(hddInfo->exists!=0 && hddInfo->has_packet==0){ hddDeviceBuf[i].status--; hddDeviceBuf[i].totalLBA=hddInfo->total_sectors; hddDeviceBuf[i].partitionMaxSize=apaGetPartitionMax(hddInfo->total_sectors); if(unlockDrive(i)==0) hddDeviceBuf[i].status--; printf("ps2hdd: disk%d: 0x%08lx sectors, max 0x%08lx\n", i, hddDeviceBuf[i].totalLBA, hddDeviceBuf[i].partitionMaxSize); } } fileSlots=allocMem(maxOpen*sizeof(hdd_file_slot_t)); if(fileSlots) memset(fileSlots, 0, maxOpen*sizeof(hdd_file_slot_t)); cacheInit(cacheSize); for(i=0;i < 2;i++) { if(hddDeviceBuf[i].status<2){ if(journalResetore(i)!=0) return 1; if(apaGetFormat(i, (int *)&hddDeviceBuf[i].format)) hddDeviceBuf[i].status--; printf("ps2hdd: drive status %ld, format version %08lx\n", hddDeviceBuf[i].status, hddDeviceBuf[i].format); } } DelDrv("hdd"); if(AddDrv(&hddFioDev)==0) { printf("ps2hdd: driver start.\n"); return 0; } return 1; }
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) { // cmd set 1 case APA_DEVCTL_DEV9_SHUTDOWN: atadUpdateAttrib(f->unit); dev9Shutdown(); break; case APA_DEVCTL_IDLE: rv=atadIdle(f->unit, *(char *)arg); break; case APA_DEVCTL_MAX_SECTORS: rv=hddDeviceBuf[f->unit].partitionMaxSize; break; case APA_DEVCTL_TOTAL_SECTORS: rv=hddDeviceBuf[f->unit].totalLBA; break; case APA_DEVCTL_FLUSH_CACHE: if(atadFlushCache(f->unit)) rv=-EIO; break; case APA_DEVCTL_SWAP_TMP: rv=devctlSwapTemp(f->unit, (char *)arg); break; case APA_DEVCTL_SMART_STAT: rv=atadGetStatus(f->unit); break; case APA_DEVCTL_STATUS: rv=hddDeviceBuf[f->unit].status; break; case APA_DEVCTL_FORMAT: rv=hddDeviceBuf[f->unit].format; break; // removed dos not work the way you like... use hddlib ;) //case APA_DEVCTL_FREE_SECTORS: //case APA_DEVCTL_FREE_SECTORS2: // rv=apaGetFreeSectors(f->unit, bufp); // break; // cmd set 2 :) case APA_DEVCTL_GETTIME: rv=getPs2Time((ps2time *)bufp); break; case APA_DEVCTL_SET_OSDMBR: rv=devctlSetOsdMBR(f->unit, (hddSetOsdMBR_t *)arg); break; case APA_DEVCTL_GET_SECTOR_ERROR: rv=getPartErrorSector(f->unit, APA_SECTOR_SECTOR_ERROR, 0); break; case APA_DEVCTL_GET_ERROR_PART_NAME: rv=getPartErrorName(f->unit, (char *)bufp); break; case APA_DEVCTL_ATA_READ: rv=atadDmaTransfer(f->unit, (void *)bufp, ((hddAtaTransfer_t *)arg)->lba, ((hddAtaTransfer_t *)arg)->size, ATAD_MODE_READ); break; case APA_DEVCTL_ATA_WRITE: rv=atadDmaTransfer(f->unit, ((hddAtaTransfer_t *)arg)->data, ((hddAtaTransfer_t *)arg)->lba, ((hddAtaTransfer_t *)arg)->size, ATAD_MODE_WRITE); break; case APA_DEVCTL_SCE_IDENTIFY_DRIVE: rv=atadSceIdentifyDrive(f->unit, (u16 *)bufp); break; case APA_DEVCTL_IS_48BIT: rv=atadIs48bit(f->unit); break; case APA_DEVCTL_SET_TRANSFER_MODE: rv=atadSetTransferMode(f->unit, ((hddAtaSetMode_t *)arg)->type, ((hddAtaSetMode_t *)arg)->mode); break; case APA_DEVCTL_ATA_IOP_WRITE: rv=atadDmaTransfer(f->unit, ((hddAtaIOPTransfer_t *)arg)->data, ((hddAtaIOPTransfer_t *)arg)->lba, ((hddAtaIOPTransfer_t *)arg)->size, ATAD_MODE_WRITE); break; default: rv=-EINVAL; break; } SignalSema(fioSema); return rv; }
int hddFormat(iop_file_t *f, const char *dev, const char *blockdev, void *arg, size_t arglen) { int rv=0; apa_cache *clink; int i; input_param params; u32 emptyBlocks[32]; if(f->unit >= 2) return -ENXIO; // clear all errors on hdd clink=cacheGetFree(); memset(clink->header, 0, sizeof(apa_header)); if(atadDmaTransfer(f->unit, clink->header, APA_SECTOR_SECTOR_ERROR, 1, ATAD_MODE_WRITE)){ cacheAdd(clink); return -EIO; } if(atadDmaTransfer(f->unit, clink->header, APA_SECTOR_PART_ERROR, 1, ATAD_MODE_WRITE)){ cacheAdd(clink); return -EIO; } // clear apa headers for(i=1024*8;i<hddDeviceBuf[f->unit].totalLBA;i+=(1024*256)) { atadDmaTransfer(f->unit, clink->header, i, sizeof(apa_header)/512, ATAD_MODE_WRITE); } cacheAdd(clink); if((rv=journalReset(f->unit))!=0) return rv; // set up mbr :) if((clink=cacheGetHeader(f->unit, 0, 1, &rv))){ apa_header *header=clink->header; memset(header, 0, sizeof(apa_header)); header->magic=APA_MAGIC; header->length=(1024*256); // 128MB header->type=APA_TYPE_MBR; strcpy(header->id,"__mbr"); memcpy(header->mbr.magic, mbrMagic, 32); header->mbr.version=APA_MBR_VERSION; header->mbr.nsector=0; getPs2Time(&header->created); getPs2Time(&header->mbr.created); header->checksum=apaCheckSum(header); clink->flags|=CACHE_FLAG_DIRTY; cacheFlushDirty(clink); atadFlushCache(f->unit); cacheAdd(clink); hddDeviceBuf[f->unit].status=0; hddDeviceBuf[f->unit].format=APA_MBR_VERSION; } memset(&emptyBlocks, 0, sizeof(emptyBlocks)); memset(¶ms, 0, sizeof(input_param)); 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=apaAddPartitionHere(f->unit, ¶ms, emptyBlocks, i ? clink->sector : 0, &rv))) return rv; cacheAdd(clink); params.size<<=1; if(hddDeviceBuf[f->unit].partitionMaxSize < params.size) params.size=hddDeviceBuf[f->unit].partitionMaxSize; } return rv; }