Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / hdd / ps2hdd / hdd_fio.c
blob270f95276604994a520890bcca15ba836c3590a9
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
10 # $Id: hdd_fio.c 1511 2009-01-15 09:11:30Z radad $
11 # APA File System routines
14 #include "hdd.h"
16 hdd_file_slot_t *fileSlots;
17 int fioSema;
19 static const char *formatPartList[]={
20 "__net", "__system", "__sysconf", "__common", NULL
23 #define APA_NUMBER_OF_SIZES 9
24 static const char *sizeList[APA_NUMBER_OF_SIZES]={
25 "128M", "256M", "512M", "1G", "2G", "4G", "8G", "16G", "32G"
28 int fioPartitionSizeLookUp(char *str)
30 int i;
32 for(i=0;i<APA_NUMBER_OF_SIZES;i++){
33 if(strcmp(str, sizeList[i])==0)
34 return (256*1024) << i;
36 dprintf1("ps2hdd: Error: Invalid partition size, %s.\n", str);
37 return -EINVAL;
40 int fioInputBreaker(char const **arg, char *outBuf, int maxout)
42 u32 len;
43 char *p;
45 if((p=strchr(arg[0], ','))) {
46 if(maxout < (len=p-arg[0]))
47 return -EINVAL;
48 memcpy(outBuf, arg[0], len);
49 arg[0]=p+1;
50 while(arg[0][0]==' ') arg[0]+=1;
51 return 0;
52 }// else
53 if(maxout < (len=strlen(arg[0])))
54 return -EINVAL;
55 memcpy(outBuf, arg[0], len); arg[0]+=len;
56 return 0;
59 // NOTE: Changed so format = partitionID,size (used to be partitionID,fpswd,rpswd,size,filesystem)
60 int fioGetInput(const char *arg, input_param *params)
62 char szBuf[32];
63 int rv=0;
65 if(params==NULL)
66 return -EINVAL;
67 memset(params, 0, sizeof(input_param));
69 while(arg[0]==' ') arg++;
71 if(arg[0]==0 || arg[0]==',')
72 return -EINVAL;
73 if((rv=fioInputBreaker(&arg, params->id, APA_IDMAX))!=0)
74 return rv;
75 if((params->id[0]==0) || (arg[0]==0))
76 return 0;
78 memset(szBuf, 0, sizeof(szBuf));
79 if((rv=fioInputBreaker(&arg, szBuf, sizeof(szBuf)))!=0)
80 return rv;
82 if((rv=fioPartitionSizeLookUp(szBuf))<0)
83 return rv;
84 params->size=rv;
86 // Filesystem type is fixed to PFS!
87 params->type = APA_TYPE_PFS;
88 return rv;
91 int getFileSlot(input_param *params, hdd_file_slot_t **fileSlot)
93 int i;
95 for(i=0;i<maxOpen;i++)
97 if(fileSlots[i].f)
98 if(memcmp(fileSlots[i].id, &params->id, APA_IDMAX)==0)
99 return -EBUSY;// file is open
101 for(i=0;i<maxOpen;i++)
103 if(!fileSlots[i].f){
104 *fileSlot=&fileSlots[i];
105 return 0;
108 return -EMFILE;// no file slots free :(
111 int fioDataTransfer(iop_file_t *f, void *buf, int size, int mode)
113 hdd_file_slot_t *fileSlot=(hdd_file_slot_t *)f->privdata;
115 if((size & 0x1FF))
116 return -EINVAL;
117 size>>=9; // size/512
119 if(fileSlot->post+size>=0x1FF9)// no over reading
120 size=0x1FF8-fileSlot->post;
122 if(size!=0) {
123 int rv=0;
125 WaitSema(fioSema);
126 if(atadDmaTransfer(f->unit, buf, fileSlot->post+fileSlot->start+8, size, mode))
127 rv=-EIO;
128 SignalSema(fioSema);
129 if(rv==0)
131 fileSlot->post+=size;
132 return size<<9;
135 return 0;
138 int ioctl2Transfer(u32 device, hdd_file_slot_t *fileSlot, hddIoctl2Transfer_t *arg)
140 apa_subs *subs;
142 if(fileSlot->nsub<arg->sub)
143 return -ENODEV;//-EINVAL;
145 // main partitions only can read 4MB on :P
146 if(arg->sub==0 && (arg->sector < 0x2000))
147 return -EINVAL;
148 // subs partitions only can read header on...
149 if(arg->sub!=0 && (arg->sector < 2))
150 return -EINVAL;
152 subs=((apa_subs *)(&fileSlot->start)); // !HACK!
153 if(subs[arg->sub].length<arg->sector+arg->size)
154 return -ENXIO;
156 if(atadDmaTransfer(device, arg->buffer,
157 subs[arg->sub].start+arg->sector, arg->size, arg->mode))
158 return -EIO;
160 return 0;
163 void hddPowerOffHandler(void* data)
165 printf("hdd flush cache\n");
166 atadFlushCache(0);
169 int hddInit(iop_device_t *f)
171 iop_sema_t sema;
173 sema.attr=1;
174 sema.initial=1;
175 sema.max=1;
176 sema.option=0;
177 fioSema=CreateSema(&sema);
179 AddPowerOffHandler(hddPowerOffHandler, 0);
180 return 0;
183 int hddDeinit(iop_device_t *f)
185 DeleteSema(fioSema);
186 return 0;
189 int hddFormat(iop_file_t *f, const char *dev, const char *blockdev, void *arg, size_t arglen)
191 int rv=0;
192 apa_cache *clink;
193 int i;
194 input_param params;
195 u32 emptyBlocks[32];
197 if(f->unit >= 2)
198 return -ENXIO;
200 // clear all errors on hdd
201 clink=cacheGetFree();
202 memset(clink->header, 0, sizeof(apa_header));
203 if(atadDmaTransfer(f->unit, clink->header, APA_SECTOR_SECTOR_ERROR, 1, ATAD_MODE_WRITE)){
204 cacheAdd(clink);
205 return -EIO;
207 if(atadDmaTransfer(f->unit, clink->header, APA_SECTOR_PART_ERROR, 1, ATAD_MODE_WRITE)){
208 cacheAdd(clink);
209 return -EIO;
211 // clear apa headers
212 for(i=1024*8;i<hddDeviceBuf[f->unit].totalLBA;i+=(1024*256))
214 atadDmaTransfer(f->unit, clink->header, i, sizeof(apa_header)/512,
215 ATAD_MODE_WRITE);
217 cacheAdd(clink);
218 if((rv=journalReset(f->unit))!=0)
219 return rv;
221 // set up mbr :)
222 if((clink=cacheGetHeader(f->unit, 0, 1, &rv))){
223 apa_header *header=clink->header;
224 memset(header, 0, sizeof(apa_header));
225 header->magic=APA_MAGIC;
226 header->length=(1024*256); // 128MB
227 header->type=APA_TYPE_MBR;
228 strcpy(header->id,"__mbr");
229 memcpy(header->mbr.magic, mbrMagic, 32);
231 header->mbr.version=APA_MBR_VERSION;
232 header->mbr.nsector=0;
233 getPs2Time(&header->created);
234 getPs2Time(&header->mbr.created);
235 header->checksum=apaCheckSum(header);
236 clink->flags|=CACHE_FLAG_DIRTY;
237 cacheFlushDirty(clink);
238 atadFlushCache(f->unit);
239 cacheAdd(clink);
240 hddDeviceBuf[f->unit].status=0;
241 hddDeviceBuf[f->unit].format=APA_MBR_VERSION;
243 memset(&emptyBlocks, 0, sizeof(emptyBlocks));
244 memset(&params, 0, sizeof(input_param));
245 params.size=(1024*256);
246 params.type=APA_TYPE_PFS;
248 // add __net, __system....
249 for(i=0;formatPartList[i];i++)
251 memset(params.id, 0, APA_IDMAX);
252 strcpy(params.id, formatPartList[i]);
253 if(!(clink=apaAddPartitionHere(f->unit, &params, emptyBlocks, i ? clink->sector : 0, &rv)))
254 return rv;
255 cacheAdd(clink);
257 params.size<<=1;
258 if(hddDeviceBuf[f->unit].partitionMaxSize < params.size)
259 params.size=hddDeviceBuf[f->unit].partitionMaxSize;
261 return rv;
264 int hddRemove(iop_file_t *f, const char *name)
266 int rv;
267 input_param params;
269 if((rv=fioGetInput(name, &params)) < 0)
270 return rv;
272 WaitSema(fioSema);
273 apaRemove(f->unit, params.id);
274 return SignalSema(fioSema);
277 int hddOpen(iop_file_t *f, const char *name, int mode, int other_mode)
279 int rv;
280 input_param params;
281 hdd_file_slot_t *fileSlot;
283 if(f->unit >= 2 || hddDeviceBuf[f->unit].status!=0)
284 return -ENODEV;
286 if(!(f->mode & O_DIROPEN))
287 if((rv=fioGetInput(name, &params)) < 0)
288 return rv;
290 WaitSema(fioSema);
291 if((rv=getFileSlot(&params, &fileSlot))==0) {
292 if(!(f->mode & O_DIROPEN)) {
293 if((rv=apaOpen(f->unit, fileSlot, &params, mode))==0){
294 fileSlot->f=f;
295 f->privdata=fileSlot;
298 else
300 fileSlot->f=f;
301 f->privdata=fileSlot;
304 SignalSema(fioSema);
305 return rv;
308 int hddClose(iop_file_t *f)
310 WaitSema(fioSema);
311 memset(f->privdata, 0, sizeof(hdd_file_slot_t));
312 SignalSema(fioSema);
313 return 0;
316 int hddRead(iop_file_t *f, void *buf, int size)
318 return fioDataTransfer(f, buf, size, ATAD_MODE_READ);
321 int hddWrite(iop_file_t *f, void *buf, int size)
323 if(!(f->mode & O_WRONLY))
324 return -EACCES;
325 return fioDataTransfer(f, buf, size, ATAD_MODE_WRITE);
328 int hddLseek(iop_file_t *f, unsigned long post, int whence)
330 int rv=0;
331 hdd_file_slot_t *fileSlot;
333 // test input( no seeking to end point less :P )
334 if(whence==SEEK_END)
335 return -EINVAL;
336 if((post & 0x1FF))
337 return -EINVAL;
339 post>>=9;// post/512
341 WaitSema(fioSema);
342 fileSlot=f->privdata;
343 if(whence==SEEK_CUR)
345 if((fileSlot->post+post) < 0 || (fileSlot->post+post)>=0x1FF9)
346 rv=-EINVAL;
347 else
349 fileSlot->post+=post;
350 rv=fileSlot->post<<9;
353 else if(whence==SEEK_SET)
355 if(post < 0 || post>=0x1FF9)
356 rv=-EINVAL;
357 else
359 fileSlot->post=post;
360 rv=fileSlot->post<<9;
364 SignalSema(fioSema);
365 return rv;
368 void fioGetStatFiller(apa_cache *clink, iox_stat_t *stat)
370 apa_header *header;
372 stat->mode=clink->header->type;
373 stat->attr=clink->header->flags;
374 stat->hisize=0;
375 u64 size = clink->header->length;
376 size *= 1024;
377 stat->size=size & 0xFFFFFFFF;
378 size >>= 32;
379 stat->hisize=size & 0xFFFFFFFF;
380 header=clink->header;
381 memcpy(&stat->ctime, &clink->header->created, sizeof(ps2time));
382 memcpy(&stat->atime, &clink->header->created, sizeof(ps2time));
383 memcpy(&stat->mtime, &clink->header->created, sizeof(ps2time));
384 if(clink->header->flags & APA_FLAG_SUB)
385 stat->private_0=clink->header->number;
386 else
387 stat->private_0=clink->header->nsub;
388 stat->private_1=0;
389 stat->private_2=0;
390 stat->private_3=0;
391 stat->private_4=0;
392 //stat->private_5=0;// game ver
393 stat->private_5=clink->header->start;// sony ver
396 int hddGetStat(iop_file_t *f, const char *name, iox_stat_t *stat)
398 apa_cache *clink;
399 input_param params;
400 int rv;
402 if((rv=fioGetInput(name, &params))<0)
403 return rv;
405 WaitSema(fioSema);
406 if((clink=apaFindPartition(f->unit, params.id, &rv))){
407 if((rv=passcmp(clink->header->rpwd, NULL))==0)
408 fioGetStatFiller(clink, stat);
409 cacheAdd(clink);
411 SignalSema(fioSema);
412 return rv;
415 int hddDopen(iop_file_t *f, const char *name)
417 return hddOpen(f, name, 0, 0);
420 int hddDread(iop_file_t *f, iox_dirent_t *dirent)
422 int rv;
423 hdd_file_slot_t *fileSlot=f->privdata;
424 apa_cache *clink;
426 if(!(f->mode & O_DIROPEN))
427 return -ENOTDIR;
429 if(fileSlot->start==-1)
430 return 0;// end :)
432 WaitSema(fioSema);
433 if((clink=cacheGetHeader(f->unit, fileSlot->start, 0, &rv)) &&
434 clink->header->length)
436 if(clink->header->flags & APA_FLAG_SUB) {
437 // if sub get id from main header...
438 apa_cache *cmain=cacheGetHeader(f->unit, clink->header->main, 0, &rv);
439 if(cmain!=NULL){
440 rv=strlen(cmain->header->id);
441 strcpy(dirent->name, cmain->header->id);
442 cacheAdd(cmain);
445 else {
446 rv=strlen(clink->header->id);
447 strcpy(dirent->name, clink->header->id);
449 fioGetStatFiller(clink, &dirent->stat);
450 if(clink->header->next==0)
451 fileSlot->start=-1; // mark end
452 else
453 fileSlot->start=clink->header->next;// set next
454 cacheAdd(clink);
456 SignalSema(fioSema);
457 return rv;
460 int hddReName(iop_file_t *f, const char *oldname, const char *newname)
462 int rv;
463 int i;
464 apa_cache *clink;
465 char tmpBuf[APA_IDMAX];
467 if(f->unit >= 2 || hddDeviceBuf[f->unit].status!=0)
468 return -ENODEV;// No such device
470 WaitSema(fioSema);
471 // look to see if can make(newname) or not...
472 memset(tmpBuf, 0, APA_IDMAX);
473 strncpy(tmpBuf, newname, APA_IDMAX - 1);
474 tmpBuf[APA_IDMAX - 1] = '\0';
475 if((clink=apaFindPartition(f->unit, tmpBuf, &rv))){
476 cacheAdd(clink);
477 SignalSema(fioSema);
478 return -EEXIST; // File exists
481 // look to see if open(oldname)
482 memset(tmpBuf, 0, APA_IDMAX);
483 strncpy(tmpBuf, oldname, APA_IDMAX - 1);
484 tmpBuf[APA_IDMAX - 1] = '\0';
485 for(i=0;i<maxOpen;i++)
487 if(fileSlots[i].f!=0)
488 if(fileSlots[i].f->unit==f->unit)
489 if(memcmp(fileSlots[i].id, oldname, APA_IDMAX)==0)
491 SignalSema(fioSema);
492 return -EBUSY;
496 // find :)
497 if(!(clink=apaFindPartition(f->unit, tmpBuf, &rv)))
499 SignalSema(fioSema);
500 return -ENOENT;
503 // do the renameing :) note: subs have no names!!
504 memset(clink->header->id, 0, APA_IDMAX); // all cmp are done with memcmp!
505 strncpy(clink->header->id, newname, APA_IDMAX - 1);
506 clink->header->id[APA_IDMAX - 1] = '\0';
508 clink->flags|=CACHE_FLAG_DIRTY;
509 cacheFlushAllDirty(f->unit);
510 cacheAdd(clink);
511 SignalSema(fioSema);
512 return 0;
515 int ioctl2AddSub(hdd_file_slot_t *fileSlot, char *argp)
517 int rv;
518 u32 device=fileSlot->f->unit;
519 input_param params;
520 u32 emptyBlocks[32];
521 apa_cache *clink;
522 u32 sector=0;
523 u32 length;
525 if(!(fileSlot->f->mode & O_WRONLY))
526 return -EACCES;
528 if(!(fileSlot->nsub < APA_MAXSUB))
529 return -EFBIG;
531 memset(&params, 0, sizeof(input_param));
533 if((rv=fioPartitionSizeLookUp(argp)) < 0)
534 return rv;
536 params.size=rv;
537 params.flags=APA_FLAG_SUB;
538 params.type=fileSlot->type;
539 params.main=fileSlot->start;
540 params.number=fileSlot->nsub+1;
541 if((rv=apaCheckPartitionMax(device, params.size)) < 0)
542 return rv;
544 // walk all looking for any empty blocks
545 memset(&emptyBlocks, 0, sizeof(emptyBlocks));
546 clink=cacheGetHeader(device, 0, 0, &rv);
547 while(clink){
548 sector=clink->sector;
549 addEmptyBlock(clink->header, emptyBlocks);
550 clink=apaGetNextHeader(clink, &rv);
552 if(rv!=0)
553 return rv;
555 if(!(clink=apaAddPartitionHere(device, &params, emptyBlocks, sector, &rv)))
556 return rv;
558 sector=clink->header->start;
559 length=clink->header->length;
560 cacheAdd(clink);
561 if(!(clink=cacheGetHeader(device, fileSlot->start, 0, &rv)))
562 return rv;
564 clink->header->subs[clink->header->nsub].start=sector;
565 clink->header->subs[clink->header->nsub].length=length;
566 clink->header->nsub++;
567 fileSlot->nsub++;
568 ((apa_subs *)(&fileSlot->start))[fileSlot->nsub].start=sector; // !HACK!
569 ((apa_subs *)(&fileSlot->start))[fileSlot->nsub].length=length; // !HACK!
570 clink->flags|=CACHE_FLAG_DIRTY;
571 cacheFlushAllDirty(device);
572 cacheAdd(clink);
573 return rv;
576 int ioctl2DeleteLastSub(hdd_file_slot_t *fileSlot)
578 int rv;
579 u32 device=fileSlot->f->unit;
580 apa_cache *mainPart;
581 apa_cache *subPart;
583 if(!(fileSlot->f->mode & O_WRONLY))
584 return -EACCES;
586 if(fileSlot->nsub==0)
587 return -ENOENT;
589 if(!(mainPart=cacheGetHeader(device, fileSlot->start, 0, &rv)))
590 return rv;
592 if((subPart=cacheGetHeader(device,
593 mainPart->header->subs[mainPart->header->nsub-1].start, 0, &rv))) {
594 fileSlot->nsub--;
595 mainPart->header->nsub--;
596 mainPart->flags|=CACHE_FLAG_DIRTY;
597 cacheFlushAllDirty(device);
598 rv=apaDelete(subPart);
600 cacheAdd(mainPart);
601 return rv;
604 int hddIoctl2(iop_file_t *f, int req, void *argp, unsigned int arglen,
605 void *bufp, unsigned int buflen)
607 u32 rv=0;
608 hdd_file_slot_t *fileSlot=f->privdata;
610 WaitSema(fioSema);
611 switch(req)
613 // cmd set 1
614 case APA_IOCTL2_ADD_SUB:
615 rv=ioctl2AddSub(fileSlot, (char *)argp);
616 break;
618 case APA_IOCTL2_DELETE_LAST_SUB:
619 rv=ioctl2DeleteLastSub(fileSlot);
620 break;
622 case APA_IOCTL2_NUMBER_OF_SUBS:
623 rv=fileSlot->nsub;
624 break;
626 case APA_IOCTL2_FLUSH_CACHE:
627 atadFlushCache(f->unit);
628 break;
630 // cmd set 2
631 case APA_IOCTL2_TRANSFER_DATA:
632 rv=ioctl2Transfer(f->unit, fileSlot, argp);
633 break;
635 case APA_IOCTL2_GETSIZE:
636 // rv=fileSlot->subs[*(u32 *)argp].length;
637 rv=((apa_subs *)(&fileSlot->start))[*(u32 *)argp].length; // !HACK!
638 break;
640 case APA_IOCTL2_GETHEADER:
641 if(atadDmaTransfer(f->unit, bufp, fileSlot->start, sizeof(apa_header)/512, ATAD_MODE_READ))
642 rv=-EIO;
643 rv=sizeof(apa_header);
644 break;
646 case APA_IOCTL2_SET_PART_ERROR:
647 setPartErrorSector(f->unit, fileSlot->start); rv=0;
648 break;
650 case APA_IOCTL2_GET_PART_ERROR:
651 if((rv=getPartErrorSector(f->unit, APA_SECTOR_PART_ERROR, bufp)) > 0) {
652 if(*(u32 *)bufp==fileSlot->start) {
653 rv=0; setPartErrorSector(f->unit, 0);// clear last error :)
656 break;
658 default:
659 rv=-EINVAL;
660 break;
662 SignalSema(fioSema);
663 return rv;
666 int devctlSwapTemp(u32 device, char *argp)
668 int rv;
669 input_param params;
670 char szBuf[APA_IDMAX];
671 apa_cache *partTemp;
672 apa_cache *partNew;
675 if((rv=fioGetInput(argp, &params)) < 0)
676 return rv;
678 if(*(u16 *)(params.id)==(u16)0x5F5F)// test for '__' system partition
679 return -EINVAL;
681 memset(szBuf, 0, APA_IDMAX);
682 strcpy(szBuf, "_tmp");
683 if(!(partTemp=apaFindPartition(device, szBuf, &rv)))
684 return rv;
686 if((partNew=apaFindPartition(device, params.id, &rv))) {
687 if((rv=passcmp(partNew->header->fpwd, NULL))==0) {
688 memcpy(partTemp->header->id, partNew->header->id, APA_IDMAX);
689 memcpy(partTemp->header->rpwd, partNew->header->rpwd, APA_PASSMAX);
690 memcpy(partTemp->header->fpwd, partNew->header->fpwd, APA_PASSMAX);
691 //memset(partNew->header->id, 0, 8);// BUG! can make it so can not open!!
692 memset(partNew->header->id, 0, APA_IDMAX);
693 strcpy(partNew->header->id, "_tmp");
694 memset(partNew->header->rpwd, 0, APA_PASSMAX);
695 memset(partNew->header->fpwd, 0, APA_PASSMAX);
696 partTemp->flags|=CACHE_FLAG_DIRTY;
697 partNew->flags|=CACHE_FLAG_DIRTY;
698 cacheFlushAllDirty(device);
700 cacheAdd(partNew);
702 cacheAdd(partTemp);
703 return rv;
706 int devctlSetOsdMBR(u32 device, hddSetOsdMBR_t *mbrInfo)
708 int rv;
709 apa_cache *clink;
711 if(!(clink=cacheGetHeader(device, APA_SECTOR_MBR, 0, &rv)))
712 return rv;
714 dprintf1("ps2hdd: mbr start: %ld\n"
715 "ps2hdd: mbr size : %ld\n", mbrInfo->start, mbrInfo->size);
716 clink->header->mbr.osdStart=mbrInfo->start;
717 clink->header->mbr.osdSize=mbrInfo->size;
718 clink->flags|=CACHE_FLAG_DIRTY;
719 cacheFlushAllDirty(device);
720 cacheAdd(clink);
721 return rv;
724 int hddDevctl(iop_file_t *f, const char *devname, int cmd, void *arg,
725 unsigned int arglen, void *bufp, unsigned int buflen)
727 int rv=0;
729 WaitSema(fioSema);
730 switch(cmd)
732 // cmd set 1
733 case APA_DEVCTL_DEV9_SHUTDOWN:
734 atadUpdateAttrib(f->unit);
735 dev9Shutdown();
736 break;
738 case APA_DEVCTL_IDLE:
739 rv=atadIdle(f->unit, *(char *)arg);
740 break;
742 case APA_DEVCTL_MAX_SECTORS:
743 rv=hddDeviceBuf[f->unit].partitionMaxSize;
744 break;
746 case APA_DEVCTL_TOTAL_SECTORS:
747 rv=hddDeviceBuf[f->unit].totalLBA;
748 break;
750 case APA_DEVCTL_FLUSH_CACHE:
751 if(atadFlushCache(f->unit))
752 rv=-EIO;
753 break;
755 case APA_DEVCTL_SWAP_TMP:
756 rv=devctlSwapTemp(f->unit, (char *)arg);
757 break;
759 case APA_DEVCTL_SMART_STAT:
760 rv=atadGetStatus(f->unit);
761 break;
763 case APA_DEVCTL_STATUS:
764 rv=hddDeviceBuf[f->unit].status;
765 break;
767 case APA_DEVCTL_FORMAT:
768 rv=hddDeviceBuf[f->unit].format;
769 break;
771 // removed dos not work the way you like... use hddlib ;)
772 //case APA_DEVCTL_FREE_SECTORS:
773 //case APA_DEVCTL_FREE_SECTORS2:
774 // rv=apaGetFreeSectors(f->unit, bufp);
775 // break;
777 // cmd set 2 :)
778 case APA_DEVCTL_GETTIME:
779 rv=getPs2Time((ps2time *)bufp);
780 break;
782 case APA_DEVCTL_SET_OSDMBR:
783 rv=devctlSetOsdMBR(f->unit, (hddSetOsdMBR_t *)arg);
784 break;
786 case APA_DEVCTL_GET_SECTOR_ERROR:
787 rv=getPartErrorSector(f->unit, APA_SECTOR_SECTOR_ERROR, 0);
788 break;
790 case APA_DEVCTL_GET_ERROR_PART_NAME:
791 rv=getPartErrorName(f->unit, (char *)bufp);
792 break;
794 case APA_DEVCTL_ATA_READ:
795 rv=atadDmaTransfer(f->unit, (void *)bufp, ((hddAtaTransfer_t *)arg)->lba,
796 ((hddAtaTransfer_t *)arg)->size, ATAD_MODE_READ);
797 break;
799 case APA_DEVCTL_ATA_WRITE:
800 rv=atadDmaTransfer(f->unit, ((hddAtaTransfer_t *)arg)->data,
801 ((hddAtaTransfer_t *)arg)->lba, ((hddAtaTransfer_t *)arg)->size,
802 ATAD_MODE_WRITE);
803 break;
805 case APA_DEVCTL_SCE_IDENTIFY_DRIVE:
806 rv=atadSceIdentifyDrive(f->unit, (u16 *)bufp);
807 break;
809 case APA_DEVCTL_IS_48BIT:
810 rv=atadIs48bit(f->unit);
811 break;
813 case APA_DEVCTL_SET_TRANSFER_MODE:
814 rv=atadSetTransferMode(f->unit, ((hddAtaSetMode_t *)arg)->type, ((hddAtaSetMode_t *)arg)->mode);
815 break;
817 case APA_DEVCTL_ATA_IOP_WRITE:
818 rv=atadDmaTransfer(f->unit, ((hddAtaIOPTransfer_t *)arg)->data,
819 ((hddAtaIOPTransfer_t *)arg)->lba, ((hddAtaIOPTransfer_t *)arg)->size,
820 ATAD_MODE_WRITE);
821 break;
823 default:
824 rv=-EINVAL;
825 break;
827 SignalSema(fioSema);
829 return rv;
832 int hddUnsupported(iop_file_t *f){return -1;}