dsk_err_t linux_xseek(DSK_DRIVER *self, const DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head) { struct floppy_raw_cmd raw_cmd; LINUX_DSK_DRIVER *lxself; if (!self || !geom) return DSK_ERR_BADPTR; if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR; lxself = (LINUX_DSK_DRIVER *)self; if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY; init_raw_cmd(&raw_cmd); raw_cmd.flags = FD_RAW_INTR; raw_cmd.flags |= FD_RAW_NEED_SEEK; raw_cmd.track = cylinder; if (lxself->lx_doublestep) raw_cmd.track *= 2; raw_cmd.rate = get_rate(geom); raw_cmd.cmd[raw_cmd.cmd_count++] = FD_SEEK; raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head); raw_cmd.cmd[raw_cmd.cmd_count++] = cylinder; if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR; memcpy(lxself->lx_status, raw_cmd.reply, 4); if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply); lxself->lx_cylinder = cylinder; return DSK_ERR_OK; }
/* encode type 1002: extended L1-only gps rtk observables --------------------*/ static int encode_type1002(rtcm_t *rtcm, int sync) { int i, j; int code1, pr1, ppr1, lock1, amb, cnr1; /* encode header */ i = encode_head(1002, rtcm, sync, rtcm->n); for (j = 0; j < rtcm->n; j++) { /* generate obs field data gps */ gen_obs_gps(rtcm, &(rtcm->obs[j]), &code1, &pr1, &ppr1, &lock1, &amb, &cnr1); setbitu(rtcm->buff, i, 6, rtcm->obs[j].prn+1 ); i += 6; setbitu(rtcm->buff, i, 1, code1); i += 1; setbitu(rtcm->buff, i, 24, pr1 ); i += 24; setbits(rtcm->buff, i, 20, ppr1 ); i += 20; setbitu(rtcm->buff, i, 7, lock1); i += 7; setbitu(rtcm->buff, i, 8, amb ); i += 8; setbitu(rtcm->buff, i, 8, cnr1 ); i += 8; } rtcm->nbit = i; return 1; }
dsk_err_t ntwdm_xwrite(DSK_DRIVER *self, const DSK_GEOMETRY *geom, const void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_pcyl_t cyl_expected, dsk_phead_t head_expected, dsk_psect_t sector, size_t sector_size, int deleted) { NTWDM_DSK_DRIVER *ntself; FD_READ_WRITE_PARAMS rwp; LPVOID iobuffer; dsk_err_t err; DWORD dwIoCode; if (!self || !geom || !buf) return DSK_ERR_BADPTR; if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR; ntself = (NTWDM_DSK_DRIVER *)self; if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY; err = check_geom(ntself, geom); if (err) return err; rwp.flags = 0; if (!geom->dg_noskip) rwp.flags |= FD_OPTION_SKIP; /* Skip deleted data */ if (!geom->dg_fm) rwp.flags |= FD_OPTION_MFM; /* MFM recording mode */ if (!geom->dg_nomulti) rwp.flags |= FD_OPTION_MULTI_TRACK; /* Enable multitrack */ rwp.phead = encode_head(self, head); rwp.cyl = cyl_expected; rwp.head = head_expected; rwp.sector = sector; rwp.size = dsk_get_psh(sector_size); /* [JCE] v1.1.5 */ rwp.eot = sector+1; rwp.gap = geom->dg_rwgap; rwp.datalen = (sector_size < 255) ? sector_size : 0xFF; if (cylinder != ntself->nt_cylinder) { UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder; if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl), NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError()); ntself->nt_cylinder = cylinder; } /* v1.1.11: Use passed sector size, not geometry sector size */ iobuffer = VirtualAlloc(NULL, sector_size, MEM_COMMIT, PAGE_READWRITE); if (!iobuffer) return DSK_ERR_NOMEM; memcpy(iobuffer, buf, sector_size); dwIoCode = deleted ? IOCTL_FDCMD_WRITE_DELETED_DATA : IOCTL_FDCMD_WRITE_DATA; if (!DeviceIoControl(ntself->nt_hdisk, dwIoCode, &rwp, sizeof(rwp), iobuffer, sector_size, &dwRet, NULL)) err = xlt_error(GetLastError()); VirtualFree(iobuffer, 0, MEM_RELEASE); return err; }
dsk_err_t linux_format(DSK_DRIVER *self, DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, const DSK_FORMAT *format, unsigned char filler) { struct floppy_raw_cmd raw_cmd; LINUX_DSK_DRIVER *lxself; int n; dsk_err_t err; unsigned char *buf; unsigned char mask = 0xFF; if (!self || !geom || !format) return DSK_ERR_BADPTR; if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR; lxself = (LINUX_DSK_DRIVER *)self; if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY; err = check_geom(lxself, geom); if (err) return err; if (geom->dg_fm) mask &= ~0x40; if (geom->dg_nomulti) mask &= ~0x80; buf = dsk_malloc(geom->dg_sectors * 4); if (!buf) return DSK_ERR_NOMEM; for (n = 0; n < geom->dg_sectors; n++) { buf[n*4] = format[n].fmt_cylinder; buf[n*4+1] = format[n].fmt_head; buf[n*4+2] = format[n].fmt_sector; buf[n*4+3] = dsk_get_psh(format[n].fmt_secsize); } init_raw_cmd(&raw_cmd); raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR; if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK; raw_cmd.track = cylinder; if (lxself->lx_doublestep) raw_cmd.track *= 2; raw_cmd.rate = get_rate(geom); raw_cmd.length= 4 * geom->dg_sectors; raw_cmd.data = buf; raw_cmd.cmd[raw_cmd.cmd_count++] = FD_FORMAT & mask; raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head); raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(geom->dg_secsize); raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_sectors; raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_fmtgap; raw_cmd.cmd[raw_cmd.cmd_count++] = filler; if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR; memcpy(lxself->lx_status, raw_cmd.reply, 4); if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply); lxself->lx_cylinder = cylinder; return DSK_ERR_OK; }
dsk_err_t linux_xread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_pcyl_t cyl_expected, dsk_phead_t head_expected, dsk_psect_t sector, size_t sector_size, int *deleted) { struct floppy_raw_cmd raw_cmd; LINUX_DSK_DRIVER *lxself; dsk_err_t err; unsigned char mask = 0xFF; if (!self || !geom || !buf) return DSK_ERR_BADPTR; if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR; lxself = (LINUX_DSK_DRIVER *)self; if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY; err = check_geom(lxself, geom); if (err) return err; if (geom->dg_noskip) mask &= ~0x20; /* Don't skip deleted data */ if (geom->dg_fm) mask &= ~0x40; /* FM recording mode */ if (geom->dg_nomulti) mask &= ~0x80; /* Disable multitrack */ init_raw_cmd(&raw_cmd); raw_cmd.flags = FD_RAW_READ | FD_RAW_INTR; if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK; raw_cmd.track = cylinder; if (lxself->lx_doublestep) raw_cmd.track *= 2; raw_cmd.rate = get_rate(geom); raw_cmd.length= sector_size; raw_cmd.data = buf; if (deleted && (*deleted)) raw_cmd.cmd[raw_cmd.cmd_count++] = 0xEC & mask; else raw_cmd.cmd[raw_cmd.cmd_count++] = FD_READ & mask; raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head); raw_cmd.cmd[raw_cmd.cmd_count++] = cyl_expected; raw_cmd.cmd[raw_cmd.cmd_count++] = head_expected; raw_cmd.cmd[raw_cmd.cmd_count++] = sector; raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(sector_size); raw_cmd.cmd[raw_cmd.cmd_count++] = sector; raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_rwgap; raw_cmd.cmd[raw_cmd.cmd_count++] = (sector_size < 255) ? sector_size : 0xFF; if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR; memcpy(lxself->lx_status, raw_cmd.reply, 4); if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply); if (deleted) deleted[0] = (raw_cmd.reply[2] & 0x40) ? 1 : 0; lxself->lx_cylinder = cylinder; return DSK_ERR_OK; }
dsk_err_t ntwdm_format(DSK_DRIVER *self, DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, const DSK_FORMAT *format, unsigned char filler) { NTWDM_DSK_DRIVER *ntself; unsigned u, fsize; dsk_err_t err; FD_FORMAT_PARAMS *pfp; FD_ID_HEADER *ph; if (!self || !geom || !format) return DSK_ERR_BADPTR; if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR; ntself = (NTWDM_DSK_DRIVER *)self; if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY; err = check_geom(ntself, geom); if (err) return err; fsize = sizeof(FD_FORMAT_PARAMS) + geom->dg_sectors * sizeof(FD_ID_HEADER); pfp = (FD_FORMAT_PARAMS *)dsk_malloc(fsize); if (!pfp) return DSK_ERR_NOMEM; pfp->flags = geom->dg_fm ? 0 : FD_OPTION_MFM; pfp->phead = encode_head(self, head); pfp->size = dsk_get_psh(geom->dg_secsize); pfp->sectors = geom->dg_sectors; pfp->gap = geom->dg_fmtgap; pfp->fill = filler; ph = (FD_ID_HEADER *)(pfp+1); for (u = 0; u < geom->dg_sectors; u++) { ph[u].cyl = format[u].fmt_cylinder; ph[u].head = format[u].fmt_head; ph[u].sector = format[u].fmt_sector; ph[u].size = dsk_get_psh(format[u].fmt_secsize); } if (cylinder != ntself->nt_cylinder) { UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder; if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl), NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError()); ntself->nt_cylinder = cylinder; } if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_FORMAT_TRACK, pfp, fsize, NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError()); return DSK_ERR_OK; }
/* Get a driver-specific option */ dsk_err_t ntwdm_option_get(DSK_DRIVER *self, const char *optname, int *value) { NTWDM_DSK_DRIVER *ntself; FD_CMD_RESULT res; if (!self || !optname) return DSK_ERR_BADPTR; if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR; ntself = (NTWDM_DSK_DRIVER *)self; if (!strcmp(optname, "HEAD")) { if (value) *value = ntself->nt_forcehead; } else if (!strcmp(optname, "DOUBLESTEP")) { if (value) *value = ntself->nt_doublestep; } else if (!strcmp(optname, "ST0")) { if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FD_GET_RESULT, NULL, 0, &res, sizeof(res), &dwRet, NULL)) return DSK_ERR_SYSERR; if (value) *value = res.st0; } else if (!strcmp(optname, "ST1")) { if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FD_GET_RESULT, NULL, 0, &res, sizeof(res), &dwRet, NULL)) return DSK_ERR_SYSERR; if (value) *value = res.st1; } else if (!strcmp(optname, "ST2")) { if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FD_GET_RESULT, NULL, 0, &res, sizeof(res), &dwRet, NULL)) return DSK_ERR_SYSERR; if (value) *value = res.st2; } else if (!strcmp(optname, "ST3")) { FD_SENSE_PARAMS sp; FD_SENSE_RESULT res; sp.head = encode_head(self, 0); if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SENSE_DRIVE_STATUS, NULL, 0, &res, sizeof(res), &dwRet, NULL)) return DSK_ERR_SYSERR; if (value) *value = res.st3; } else return DSK_ERR_BADOPT; return DSK_ERR_OK; }
/* Read a track (FDC765 READ TRACK command) */ dsk_err_t linux_xtread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_pcyl_t cyl_expected, dsk_phead_t head_expected) { struct floppy_raw_cmd raw_cmd; LINUX_DSK_DRIVER *lxself; dsk_err_t err; unsigned char mask = 0xFF; if (!self || !geom || !buf) return DSK_ERR_BADPTR; if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR; lxself = (LINUX_DSK_DRIVER *)self; if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY; err = check_geom(lxself, geom); if (err) return err; if (geom->dg_fm) mask &= ~0x40; if (geom->dg_nomulti) mask &= ~0x80; init_raw_cmd(&raw_cmd); raw_cmd.flags = FD_RAW_READ | FD_RAW_INTR; if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK; raw_cmd.track = cylinder; if (lxself->lx_doublestep) raw_cmd.track *= 2; raw_cmd.rate = get_rate(geom); raw_cmd.length= geom->dg_secsize * geom->dg_sectors; raw_cmd.data = buf; /* fdreg.h doesn't define the Read Track command, but here it is */ raw_cmd.cmd[raw_cmd.cmd_count++] = 0x62 & mask; raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head); raw_cmd.cmd[raw_cmd.cmd_count++] = cyl_expected; raw_cmd.cmd[raw_cmd.cmd_count++] = head_expected; raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_secbase; raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(geom->dg_secsize); raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_secbase + geom->dg_sectors; raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_rwgap; raw_cmd.cmd[raw_cmd.cmd_count++] = 0xFF; if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR; memcpy(lxself->lx_status, raw_cmd.reply, 4); if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply); lxself->lx_cylinder = cylinder; return DSK_ERR_OK; }
/* Read a track (FDC765 READ TRACK command) */ dsk_err_t ntwdm_xtread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf, dsk_pcyl_t cylinder, dsk_phead_t head, dsk_pcyl_t cyl_expected, dsk_phead_t head_expected) { NTWDM_DSK_DRIVER *ntself; FD_READ_WRITE_PARAMS rwp; LPVOID iobuffer; DWORD tracksize; dsk_err_t err; if (!self || !geom || !buf) return DSK_ERR_BADPTR; if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR; ntself = (NTWDM_DSK_DRIVER *)self; if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY; err = check_geom(ntself, geom); if (err) return err; rwp.flags = 0; if (!geom->dg_fm) rwp.flags |= FD_OPTION_MFM; /* MFM recording mode */ if (!geom->dg_nomulti) rwp.flags |= FD_OPTION_MULTI_TRACK; /* Enable multitrack */ rwp.phead = encode_head(self, head); rwp.cyl = cyl_expected; rwp.head = head_expected; rwp.sector = geom->dg_secbase; rwp.size = dsk_get_psh(geom->dg_secsize); rwp.eot = geom->dg_secbase + geom->dg_sectors; rwp.gap = geom->dg_rwgap; rwp.datalen = 0xFF; tracksize = rwp.size * geom->dg_sectors; iobuffer = VirtualAlloc(NULL, tracksize, MEM_COMMIT, PAGE_READWRITE); if (!iobuffer) return DSK_ERR_NOMEM; if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_READ_TRACK, &rwp, sizeof(rwp), iobuffer, geom->dg_secsize, &dwRet, NULL)) err = xlt_error(GetLastError()); memcpy(buf, iobuffer, geom->dg_secsize); VirtualFree(iobuffer, 0, MEM_RELEASE); return err; }
dsk_err_t linux_secid(DSK_DRIVER *self, const DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, DSK_FORMAT *result) { struct floppy_raw_cmd raw_cmd; LINUX_DSK_DRIVER *lxself; unsigned char mask = 0xFF; dsk_err_t err; if (!self || !geom || !result) return DSK_ERR_BADPTR; if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR; lxself = (LINUX_DSK_DRIVER *)self; if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY; if (geom->dg_fm) mask &= ~0x40; if (geom->dg_nomulti) mask &= ~0x80; /* [v0.8.3] It was necessary to add this check correctly to detect 100k * FM-recorded discs in a 5.25" drive */ err = check_geom(lxself, geom); if (err) return err; init_raw_cmd(&raw_cmd); raw_cmd.flags = FD_RAW_INTR; if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK; raw_cmd.track = cylinder; if (lxself->lx_doublestep) raw_cmd.track *= 2; raw_cmd.rate = get_rate(geom); raw_cmd.cmd[raw_cmd.cmd_count++] = FD_READID & mask; raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head); if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR; memcpy(lxself->lx_status, raw_cmd.reply, 4); if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply); result->fmt_cylinder = raw_cmd.reply[3]; result->fmt_head = raw_cmd.reply[4]; result->fmt_sector = raw_cmd.reply[5]; result->fmt_secsize = 128 << raw_cmd.reply[6]; lxself->lx_cylinder = cylinder; return DSK_ERR_OK; }
dsk_err_t ntwdm_status(DSK_DRIVER *self, const DSK_GEOMETRY *geom, dsk_phead_t head, unsigned char *result) { NTWDM_DSK_DRIVER *ntself; FD_SENSE_PARAMS sp; FD_SENSE_RESULT res; if (!self || !geom || !result) return DSK_ERR_BADPTR; if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR; ntself = (NTWDM_DSK_DRIVER *)self; if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY; sp.head = encode_head(self, head); if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SENSE_DRIVE_STATUS, &sp, sizeof(sp), &res, sizeof(res), &dwRet, NULL)) return xlt_error(GetLastError()); *result = res.st3; return DSK_ERR_OK; }
dsk_err_t linux_status(DSK_DRIVER *self, const DSK_GEOMETRY *geom, dsk_phead_t head, unsigned char *result) { struct floppy_raw_cmd raw_cmd; LINUX_DSK_DRIVER *lxself; if (!self || !geom || !result) return DSK_ERR_BADPTR; if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR; lxself = (LINUX_DSK_DRIVER *)self; if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY; init_raw_cmd(&raw_cmd); raw_cmd.flags = FD_RAW_INTR; raw_cmd.rate = get_rate(geom); raw_cmd.cmd[raw_cmd.cmd_count++] = FD_GETSTATUS; raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head); if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR; *result = raw_cmd.reply[0]; return DSK_ERR_OK; }
dsk_err_t ntwdm_secid(DSK_DRIVER *self, const DSK_GEOMETRY *geom, dsk_pcyl_t cylinder, dsk_phead_t head, DSK_FORMAT *result) { NTWDM_DSK_DRIVER *ntself; FD_READ_ID_PARAMS rip; FD_CMD_RESULT res; dsk_err_t err; if (!self || !geom || !result) return DSK_ERR_BADPTR; if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR; ntself = (NTWDM_DSK_DRIVER *)self; if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY; err = check_geom(ntself, geom); if (err) return err; if (cylinder != ntself->nt_cylinder) { UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder; if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl), NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError()); ntself->nt_cylinder = cylinder; } rip.flags = geom->dg_fm ? 0 : FD_OPTION_MFM; rip.head = encode_head(self, head); if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_READ_ID, &rip, sizeof(rip), &res, sizeof(res), &dwRet, NULL)) return xlt_error(GetLastError()); result->fmt_cylinder = res.cyl; result->fmt_head = res.head; result->fmt_sector = res.sector; result->fmt_secsize = 128 << res.size; return DSK_ERR_OK; }