int apaGetPartErrorName(s32 device, char *name) { u32 lba; int rv = 0; apa_cache_t *clink; if ((rv = apaGetPartErrorSector(device, APA_SECTOR_PART_ERROR, &lba)) <= 0) return rv; if (!(clink = apaCacheGetHeader(device, 0, APA_IO_MODE_READ, &rv))) return rv; while (clink) { if (clink->header->type != APA_TYPE_FREE && !(clink->header->flags & APA_CACHE_FLAG_DIRTY) && clink->header->start == lba) { if (name) { strncpy(name, clink->header->id, APA_IDMAX - 1); name[APA_IDMAX - 1] = '\0'; } apaCacheFree(clink); return 1; } clink = apaGetNextHeader(clink, &rv); } // clear error if no errors and partitions was not found... if (rv == 0) apaSetPartErrorSector(device, 0); return rv; }
int hddIoctl2(iop_file_t *f, int req, void *argp, unsigned int arglen, void *bufp, unsigned int buflen) { u32 rv=0, err_lba; hdd_file_slot_t *fileSlot=f->privdata; WaitSema(fioSema); switch(req) { // cmd set 1 case HIOCADDSUB: rv=ioctl2AddSub(fileSlot, (char *)argp); break; case HIOCDELSUB: rv=ioctl2DeleteLastSub(fileSlot); break; case HIOCNSUB: rv=fileSlot->nsub; break; case HIOCFLUSH: ata_device_flush_cache(f->unit); break; // cmd set 2 case HIOCTRANSFER: rv=ioctl2Transfer(f->unit, fileSlot, argp); break; case HIOCGETSIZE: rv=fileSlot->parts[*(u32 *)argp].length; break; case HIOCSETPARTERROR: apaSetPartErrorSector(f->unit, fileSlot->parts[0].start); rv=0; break; case HIOCGETPARTERROR: if((rv=apaGetPartErrorSector(f->unit, APA_SECTOR_PART_ERROR, &err_lba)) > 0) { if(err_lba==fileSlot->parts[0].start) { rv=0; apaSetPartErrorSector(f->unit, 0);// clear last error :) } } break; default: rv=-EINVAL; break; } SignalSema(fioSema); return rv; }
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; }