mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-13 23:15:09 +01:00
973d8b2005
*Converted every 4 spaces to a tab to make the source consistent on those
640 lines
15 KiB
C
640 lines
15 KiB
C
/*
|
|
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
|
|
*
|
|
* this file is part of GeckoOS for USB Gecko
|
|
* http://www.usbgecko.com
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <time.h>
|
|
#include <gcutil.h>
|
|
#include <ogc/lwp_queue.h>
|
|
#include <gccore.h>
|
|
|
|
#include "dvd_broadway.h"
|
|
|
|
#define DI_CMDCTX_CNT 4
|
|
|
|
#define DVD_DISKIDSIZE 0x20
|
|
#define DVD_DRVINFSIZE 0x20
|
|
|
|
#define IOCTL_DI_INQUIRY 0x12
|
|
#define IOCTL_DI_READID 0x70
|
|
#define IOCTL_DI_READ 0x71
|
|
#define IOCTL_DI_WAITCVRCLOSE 0x79
|
|
#define IOCTL_DI_COVER 0x7A
|
|
#define IOCTL_DI_RESETNOTIFY 0x7E
|
|
#define IOCTL_DI_RESET 0x8A
|
|
#define IOCTL_DI_OPENPART 0x8B
|
|
#define IOCTL_DI_CLOSEPART 0x8C
|
|
#define IOCTL_DI_UNENCREAD 0x8D
|
|
#define IOCTL_DI_ENABLE_DVD 0x8E
|
|
#define IOCTL_DI_SEEK 0xAB
|
|
#define IOCTL_DI_READ_DVDVIDEO 0xD0
|
|
#define IOCTL_DI_STOPLASER 0xD2
|
|
#define IOCTL_DI_OFFSET 0xD9
|
|
#define IOCTL_DI_REQERROR 0xE0
|
|
#define IOCTL_DI_STOPMOTOR 0xE3
|
|
#define IOCTL_DI_SETOFFBASE 0xF0
|
|
#define IOCTL_DI_GETOFFBASE 0xF1
|
|
#define IOCTL_DI_SETCRYPTMODE 0xF2
|
|
#define IOCTL_DI_GETCRYPTMODE 0xF3
|
|
#define IOCTL_DI_SETDVDROMMODE 0xF4
|
|
#define IOCTL_DI_GETDVDROMMODE 0xF5
|
|
|
|
#define _SHIFTL(v, s, w) \
|
|
((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
|
|
#define _SHIFTR(v, s, w) \
|
|
((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
|
|
|
|
struct dicommand
|
|
{
|
|
u32 diReg[8];
|
|
};
|
|
|
|
struct dicontext
|
|
{
|
|
lwp_node node;
|
|
dvdcallbacklow cb;
|
|
struct dicommand *cmd;
|
|
};
|
|
|
|
static s32 __dvd_fd = -1;
|
|
static u32 __dvd_spinupval = 1;
|
|
static lwp_queue __di_contextq;
|
|
static u32 __dvd_readlength = 0;
|
|
static u32 __dvd_cbinprogress = 0;
|
|
static u32 __dvd_reqinprogress = 0;
|
|
static u32 __dvd_lowinitcalled = 0;
|
|
static struct dicommand *__di_commands = NULL;
|
|
static struct dicontext __di_contexts[DI_CMDCTX_CNT];
|
|
static u32 __di_regbuffer[0x08] ATTRIBUTE_ALIGN( 32 );
|
|
static u32 __di_regvalcache[0x08] ATTRIBUTE_ALIGN( 32 );
|
|
static u32 __di_lastticketerror[0x08] ATTRIBUTE_ALIGN( 32 );
|
|
static ioctlv __di_iovector[0x08] ATTRIBUTE_ALIGN( 32 );
|
|
static char __di_fs[] ATTRIBUTE_ALIGN( 32 ) = "/dev/di";
|
|
|
|
extern u32 __IPC_ClntInit();
|
|
|
|
static __inline__ lwp_node* __lwp_queue_head(lwp_queue *queue)
|
|
{
|
|
return (lwp_node*) queue;
|
|
}
|
|
|
|
static __inline__ lwp_node* __lwp_queue_tail(lwp_queue *queue)
|
|
{
|
|
return (lwp_node*) &queue->perm_null;
|
|
}
|
|
|
|
static __inline__ void __lwp_queue_init_empty(lwp_queue *queue)
|
|
{
|
|
queue->first = __lwp_queue_tail(queue);
|
|
queue->perm_null = NULL;
|
|
queue->last = __lwp_queue_head(queue);
|
|
}
|
|
|
|
static struct dicontext* __dvd_getcontext(dvdcallbacklow cb)
|
|
{
|
|
struct dicontext *ctx;
|
|
|
|
ctx = (struct dicontext*) __lwp_queue_get(&__di_contextq);
|
|
if (ctx != NULL) ctx->cb = cb;
|
|
|
|
return ctx;
|
|
}
|
|
|
|
static s32 __dvd_iostransactionCB(s32 result, void *usrdata)
|
|
{
|
|
struct dicontext *ctx = (struct dicontext*) usrdata;
|
|
|
|
__dvd_reqinprogress = 0;
|
|
|
|
if (ctx->cb != NULL)
|
|
{
|
|
__dvd_cbinprogress = 1;
|
|
if (result != 0) __dvd_readlength = 0;
|
|
ctx->cb(result);
|
|
__dvd_cbinprogress = 0;
|
|
}
|
|
__lwp_queue_append(&__di_contextq, &ctx->node);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static s32 __dvd_ioscoverregisterCB(s32 result, void *usrdata)
|
|
{
|
|
struct dicontext *ctx = (struct dicontext*) usrdata;
|
|
|
|
__dvd_reqinprogress = 0;
|
|
__di_regvalcache[1] = __di_regbuffer[0];
|
|
|
|
if (ctx->cb != NULL)
|
|
{
|
|
__dvd_cbinprogress = 1;
|
|
ctx->cb(result);
|
|
__dvd_cbinprogress = 0;
|
|
}
|
|
__lwp_queue_append(&__di_contextq, &ctx->node);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static s32 __dvd_ioscovercloseCB(s32 result, void *usrdata)
|
|
{
|
|
struct dicontext *ctx = (struct dicontext*) usrdata;
|
|
|
|
__dvd_reqinprogress = 0;
|
|
|
|
if (ctx->cb != NULL)
|
|
{
|
|
__dvd_cbinprogress = 1;
|
|
ctx->cb(result);
|
|
__dvd_cbinprogress = 0;
|
|
}
|
|
__lwp_queue_append(&__di_contextq, &ctx->node);
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 bwDVD_LowInit()
|
|
{
|
|
s32 i, ret = 0;
|
|
u32 ipclo, ipchi;
|
|
lwp_queue inactives;
|
|
struct dicontext *ctx;
|
|
|
|
if (__dvd_lowinitcalled == 0)
|
|
{
|
|
ret = __IPC_ClntInit();
|
|
if (ret < 0) return ret;
|
|
|
|
ipclo = (((u32) IPC_GetBufferLo() + 0x1f) & ~0x1f);
|
|
ipchi = (u32) IPC_GetBufferHi();
|
|
if (ipchi >= (ipclo + (sizeof(struct dicommand) * DI_CMDCTX_CNT)))
|
|
{
|
|
__di_commands = (struct dicommand*) ipclo;
|
|
IPC_SetBufferLo((void*) (ipclo + (sizeof(struct dicommand) * DI_CMDCTX_CNT)));
|
|
|
|
memset(__di_commands, 0, (sizeof(struct dicommand) * DI_CMDCTX_CNT));
|
|
|
|
i = 0;
|
|
__lwp_queue_init_empty(&__di_contextq);
|
|
__lwp_queue_initialize(&inactives, __di_contexts, DI_CMDCTX_CNT, sizeof(struct dicontext));
|
|
while ((ctx = (struct dicontext*) __lwp_queue_get(&inactives)) != NULL)
|
|
{
|
|
ctx->cmd = &__di_commands[i];
|
|
ctx->cb = NULL;
|
|
__lwp_queue_append(&__di_contextq, &ctx->node);
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
ret = IOS_Open(__di_fs, 0);
|
|
if (ret < 0) return ret;
|
|
|
|
__dvd_fd = ret;
|
|
// __dvd_lowinitcalled = 1;
|
|
|
|
// printf("DVD_LowInit(%d)\n",ret);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 bwDVD_LowInquiry(dvddrvinfo *info, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_INQUIRY << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_INQUIRY, cmd->diReg, sizeof(struct dicommand), info, DVD_DRVINFSIZE,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowReadID(dvddiskid *diskID, dvdcallbacklow cb)
|
|
{
|
|
s32 ret = 0;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
// printf("DVD_LowReadID()\n");
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_READID << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_READID, cmd->diReg, sizeof(struct dicommand), diskID, DVD_DISKIDSIZE,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
// printf("DVD_LowReadID(%d)\n",ret);
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowRead(void *buf, u32 len, u32 offset, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
if (buf == NULL || ((u32) buf % 32) != 0) return -1;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
__dvd_readlength = len;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_READ << 24);
|
|
cmd->diReg[1] = len;
|
|
cmd->diReg[2] = offset;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_READ, cmd->diReg, sizeof(struct dicommand), buf, len,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// never got this function working, probably removed from wii
|
|
s32 bwDVD_LowReadVideo(void *buf, u32 len, u32 offset, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
__dvd_readlength = len;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_READ_DVDVIDEO << 24);
|
|
cmd->diReg[1] = len;
|
|
cmd->diReg[2] = offset;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_READ_DVDVIDEO, cmd->diReg, sizeof(struct dicommand), buf, len,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowStopLaser(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_STOPLASER << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_STOPLASER, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// never got this function working, probably removed from wii
|
|
s32 bwDVD_EnableVideo(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_ENABLE_DVD << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_ENABLE_DVD, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowSeek(u32 offset, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_SEEK << 24);
|
|
cmd->diReg[1] = offset;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_SEEK, cmd->diReg, sizeof(struct dicommand), NULL, 0,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowOffset(u64 offset, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
//u32 *off = (u32*)(void*)(&offset);
|
|
union
|
|
{
|
|
u64 off64;
|
|
u32 off32[2];
|
|
} off;
|
|
off.off64 = offset;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_OFFSET << 24);
|
|
cmd->diReg[1] = 0;
|
|
if (off.off32[0]) cmd->diReg[1] = 1;
|
|
cmd->diReg[2] = off.off32[1];
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_OFFSET, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowPrepareCoverRegister(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_COVER << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_COVER, cmd->diReg, sizeof(struct dicommand), __di_regbuffer, 0x20,
|
|
__dvd_ioscoverregisterCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowOpenPartition(u32 offset, void *eticket, u32 certin_len, void *certificate_in, void *certificate_out,
|
|
dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
if (eticket != NULL && ((u32) eticket % 32) != 0) return -1;
|
|
if (certificate_in != NULL && ((u32) certificate_in % 32) != 0) return -1;
|
|
if (certificate_out != NULL && ((u32) certificate_out % 32) != 0) return -1;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_OPENPART << 24);
|
|
cmd->diReg[1] = offset;
|
|
|
|
__di_iovector[0].data = cmd;
|
|
__di_iovector[0].len = sizeof(struct dicommand);
|
|
|
|
__di_iovector[1].data = eticket;
|
|
if (eticket == NULL)
|
|
__di_iovector[1].len = 0;
|
|
else __di_iovector[1].len = 676;
|
|
|
|
__di_iovector[2].data = certificate_in;
|
|
if (certificate_in == NULL)
|
|
__di_iovector[2].len = 0;
|
|
else __di_iovector[2].len = certin_len;
|
|
|
|
__di_iovector[3].data = certificate_out;
|
|
__di_iovector[3].len = 18916;
|
|
__di_iovector[4].data = __di_lastticketerror;
|
|
__di_iovector[4].len = 0x20;
|
|
ret = IOS_IoctlvAsync(__dvd_fd, IOCTL_DI_OPENPART, 3, 2, __di_iovector, __dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowClosePartition(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_CLOSEPART << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_CLOSEPART, cmd->diReg, sizeof(struct dicommand), NULL, 0,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowUnencryptedRead(void *buf, u32 len, u32 offset, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
__dvd_readlength = len;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_UNENCREAD << 24);
|
|
cmd->diReg[1] = len;
|
|
cmd->diReg[2] = offset;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_UNENCREAD, cmd->diReg, sizeof(struct dicommand), buf, len,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowWaitCoverClose(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_WAITCVRCLOSE << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_WAITCVRCLOSE, cmd->diReg, sizeof(struct dicommand), NULL, 0,
|
|
__dvd_ioscovercloseCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowResetNotify()
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
if (__dvd_cbinprogress == 1) return -1;
|
|
|
|
ctx = __dvd_getcontext(NULL);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_RESETNOTIFY << 24);
|
|
ret = IOS_Ioctl(__dvd_fd, IOCTL_DI_RESETNOTIFY, cmd->diReg, sizeof(struct dicommand), NULL, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowReset(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
// printf("DVD_LowReset()\n");
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_RESET << 24);
|
|
cmd->diReg[1] = __dvd_spinupval;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_RESET, cmd->diReg, sizeof(struct dicommand), NULL, 0,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
// printf("DVD_LowReset(%d)\n",ret);
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_LowStopMotor(u8 stop1, u8 stop2, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_STOPMOTOR << 24);
|
|
cmd->diReg[1] = (stop1 << 24);
|
|
cmd->diReg[2] = (stop2 << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_STOPMOTOR, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
s32 bwDVD_LowRequestError(dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_REQERROR << 24);
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_REQERROR, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 bwDVD_SetDecryption(s32 mode, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_SETCRYPTMODE << 24);
|
|
cmd->diReg[1] = mode;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_SETCRYPTMODE, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
s32 bwDVD_SetOffset(u32 offset, dvdcallbacklow cb)
|
|
{
|
|
s32 ret;
|
|
struct dicontext *ctx;
|
|
struct dicommand *cmd;
|
|
|
|
__dvd_reqinprogress = 1;
|
|
|
|
ctx = __dvd_getcontext(cb);
|
|
if (ctx == NULL) return IPC_ENOMEM;
|
|
|
|
cmd = ctx->cmd;
|
|
cmd->diReg[0] = (IOCTL_DI_SETOFFBASE << 24);
|
|
cmd->diReg[1] = offset;
|
|
ret = IOS_IoctlAsync(__dvd_fd, IOCTL_DI_SETOFFBASE, cmd->diReg, sizeof(struct dicommand), __di_regvalcache, 0x20,
|
|
__dvd_iostransactionCB, ctx);
|
|
|
|
return ret;
|
|
|
|
}
|