📄 drv_simul.c
字号:
/* @(#)drv_simul.c 1.4 98/09/05 Copyright 1998 J. Schilling */#ifndef lintstatic char sccsid[] = "@(#)drv_simul.c 1.4 98/09/05 Copyright 1998 J. Schilling";#endif/* * Simulation device driver * * Copyright (c) 1998 J. Schilling *//* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#define DEBUG#include <mconfig.h>#include <stdio.h>#include <standard.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/time.h>#include <utypes.h>#include <btorder.h>#include <scgio.h>#include <scsidefs.h>#include <scsireg.h>#include "cdrecord.h"extern int silent;extern int verbose;extern int lverbose;LOCAL int simul_load __PR((void));LOCAL int simul_unload __PR((void));LOCAL cdr_t *identify_simul __PR((cdr_t *, struct scsi_inquiry *));LOCAL int getdisktype_simul __PR((cdr_t *dp, dstat_t *dsp));LOCAL int speed_select_simul __PR((int speed, int dummy));LOCAL int next_wr_addr_simul __PR((int track, track_t *trackp, long *ap));LOCAL int cdr_write_simul __PR((caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));LOCAL int open_track_simul __PR((cdr_t *dp, int track, track_t *trackp));LOCAL int close_track_simul __PR((int track, track_t *trackp));LOCAL int open_session_simul __PR((int tracks, track_t *trackp, int toctype, int multi));LOCAL int fixate_simul __PR((int onp, int dummy, int toctype, int tracks, track_t *trackp));LOCAL void tv_sub __PR((struct timeval *tvp1, struct timeval *tvp2));LOCAL intsimul_load(){ return (0);}LOCAL intsimul_unload(){ return (0);}cdr_t cdr_cdr_simul = { 0, CDR_TAO|CDR_DAO|CDR_PACKET, "cdr_simul", "simulation CD-R driver for timing/speed tests", 0, identify_simul, drive_attach, getdisktype_simul, simul_load, simul_unload, recovery_needed, recover, speed_select_simul, select_secsize, next_wr_addr_simul, reserve_track, cdr_write_simul, open_track_simul, close_track_simul, open_session_simul, cmd_dummy, read_session_offset, fixate_simul, blank_dummy,};cdr_t cdr_dvd_simul = { 0, CDR_TAO|CDR_DAO|CDR_PACKET, "dvd_simul", "simulation DVD-R driver for timing/speed tests", 0, identify_simul, drive_attach, getdisktype_simul, simul_load, simul_unload, recovery_needed, recover, speed_select_simul, select_secsize, next_wr_addr_simul, reserve_track, cdr_write_simul, open_track_simul, close_track_simul, open_session_simul, cmd_dummy, read_session_offset, fixate_simul, blank_dummy,};LOCAL cdr_t *identify_simul(dp, ip) cdr_t *dp; struct scsi_inquiry *ip;{ return (dp);}LOCAL int simul_speed;LOCAL int simul_dummy;LOCAL int simul_isdvd;LOCAL int simul_bufsize = 1024;LOCAL Uint sleep_rest;LOCAL Uint sleep_max;LOCAL Uint sleep_min;LOCAL intgetdisktype_simul(dp, dsp) cdr_t *dp; dstat_t *dsp;{ if (strcmp(dp->cdr_drname, cdr_cdr_simul.cdr_drname) == 0) { dsp->ds_maxblocks = 333000; simul_isdvd = FALSE; } else { dsp->ds_maxblocks = 2464153; /* 4.7 GB *//* dsp->ds_maxblocks = 1927896;*/ /* 3.95 GB */ simul_isdvd = TRUE; } return (drive_getdisktype(dp, dsp));}LOCAL intspeed_select_simul(speed, dummy) int speed; int dummy;{ long val; char *p; simul_speed = speed; simul_dummy = dummy; if ((p = getenv("CDR_SIMUL_BUFSIZE")) != NULL) { if (getnum(p, &val) == 1) simul_bufsize = val / 1024; } /* * sleep_max is the time to empty the drive's buffer in 祍. * sector size is from 2048 bytes to 2352 bytes. * If sector size is 2048 bytes, 1k takes 6.666 ms. * If sector size is 2352 bytes, 1k takes 5.805 ms. * We take the 6 ms as an average between both values. * simul_bufsize is the number of kilobytes in drive buffer. */ sleep_max = 6 * 1000 * simul_bufsize / simul_speed; if (lverbose) { printf("Simulation drive buffer size: %d KB\n", simul_bufsize); printf("Mamimum reserve time in drive buffer: %d.%3.3d ms\n", sleep_max / 1000, sleep_max % 1000); } return (0);}LOCAL intnext_wr_addr_simul(track, trackp, ap) int track; track_t *trackp; long *ap;{ if (ap) *ap = 0L; return (0);}LOCAL intcdr_write_simul(bp, sectaddr, size, blocks, islast) caddr_t bp; /* address of buffer */ long sectaddr; /* disk address (sector) to put */ long size; /* number of bytes to transfer */ int blocks; /* sector count */ BOOL islast; /* last write for track */{ Uint sleep_time; Uint sleep_diff; struct timeval tv1;static struct timeval tv2; if (lverbose > 1 && islast) printf("\nWriting last record for this track.\n"); gettimeofday(&tv1, (struct timezone *)0); if (tv2.tv_sec != 0) { /* Already did gettimeofday(&tv2) */ tv_sub(&tv1, &tv2); if (sleep_rest != 0) { sleep_diff = tv1.tv_sec * 1000000 + tv1.tv_usec; if (sleep_min > (sleep_rest - sleep_diff)) sleep_min = (sleep_rest - sleep_diff); if (sleep_diff > sleep_rest) { printf("Buffer underrun: actual delay was %d.%3.3d ms, max delay was %d.%3.3d ms.\n", sleep_diff / 1000, sleep_diff % 1000, sleep_rest / 1000, sleep_rest % 1000); if (!simul_dummy) return (-1); } /* * If we spent time outside the write function * subtract this time. */ sleep_diff = tv1.tv_sec * 1000000 + tv1.tv_usec; if (sleep_rest >= sleep_diff) sleep_rest -= sleep_diff; else sleep_rest = 0; } } /* * Speed 1 ist 150 Sektoren/s */ sleep_time = 1000000 * blocks / 75 / simul_speed; sleep_time += sleep_rest; if (sleep_time > sleep_max) { int mod; sleep_rest = sleep_max; sleep_time -= sleep_rest; mod = sleep_time % 20000; sleep_rest += mod; sleep_time -= mod; if (sleep_time > 0) usleep(sleep_time); } else { sleep_rest = sleep_time; } gettimeofday(&tv2, (struct timezone *)0); return (size);}LOCAL intopen_track_simul(dp, track, trackp) cdr_t *dp; int track; track_t *trackp;{ sleep_min = 999 * 1000000; return (0);}LOCAL intclose_track_simul(track, trackp) int track; track_t *trackp;{ if (lverbose) { printf("Remaining reserve time in drive buffer: %d.%3.3d ms\n", sleep_rest / 1000, sleep_rest % 1000); printf("Minimum reserve time in drive buffer: %d.%3.3d ms\n", sleep_min / 1000, sleep_min % 1000); } usleep(sleep_rest); sleep_rest = 0; return (0);}LOCAL intopen_session_simul(tracks, trackp, toctype, multi) int tracks; track_t *trackp; int toctype; int multi;{ return (0);}LOCAL intfixate_simul(onp, dummy, toctype, tracks, trackp) int onp; int dummy; int toctype; int tracks; track_t *trackp;{ return (0);}LOCAL voidtv_sub(tvp1, tvp2) struct timeval *tvp1; struct timeval *tvp2;{ tvp1->tv_sec -= tvp2->tv_sec; tvp1->tv_usec -= tvp2->tv_usec; while (tvp1->tv_usec < 0) { tvp1->tv_usec += 1000000; tvp1->tv_sec -= 1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -