Re: Bug#181028: cdrecord: promotes non-free software
Since I am a strong believer in put-up or shut-up, I've forward ported
the DVD-R support patch to cdrtools-2.0. This small simple patch applies
to the cdrtools in unstable. It also removes the offending message about
using dvdpro. I just wasted 5 DVD-R's testing burns (all worked) of
random files on my harddrive, aswell as 1 DVD-R for burning a home
movie mpeg2 converted with dvdauthor to correct DVD-video format (piped
through mkisofs --dvd-video). So I've got around $10 invested in this.
I honestly don't care if this patch is accepted upstream. I really
expect that it wont be, for whatever reason. I do expect it to be
applied to the Debian source though. The cdrtools author has been kind
enough to give a mechanism for creating a binary that is known to be
modified from the original source which might contain bugs, and even
supply an email address for where to send bug reports.
Because of that mechanism, it completely alleviates most fears regarding
the author having to support our patches, so I don't want to hear such
complaints.
--
Debian - http://www.debian.org/
Linux 1394 - http://www.linux1394.org/
Subversion - http://subversion.tigris.org/
Deqo - http://www.deqo.com/
--- cdrtools-2.0.orig/cdda2wav/scsi_cdr.c 2002-11-03 10:32:56.000000000 -0500
+++ cdrtools-2.0/cdda2wav/scsi_cdr.c 2003-02-23 01:12:27.000000000 -0500
@@ -753,6 +753,37 @@
return (scg_cmd(scgp));
}
+
+EXPORT int
+read_rzone_info(scgp, bp, track, cnt)
+ SCSI *scgp;
+ caddr_t bp;
+ int track;
+ int cnt;
+
+{
+ register struct scg_cmd *scmd = scgp->scmd;
+
+ fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+ scmd->addr = bp;
+ scmd->size = cnt;
+ scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
+ scmd->cdb_len = SC_G1_CDBLEN;
+ scmd->sense_len = CCS_SENSE_LEN;
+ scmd->timeout = 4 * 60; /* Needs up to 2 minutes */
+ scmd->cdb.g1_cdb.cmd = 0x52;
+ scmd->cdb.g1_cdb.lun = scg_lun(scgp);
+ scmd->cdb.g1_cdb.reladr = 1;
+ g1_cdbaddr(&scmd->cdb.g1_cdb, track);
+ g1_cdblen(&scmd->cdb.g1_cdb, cnt);
+
+ scgp->cmdname = "read rzone info";
+
+ if (scg_cmd(scgp) < 0)
+ return (-1);
+ return (0);
+}
+
EXPORT int
read_subchannel(scgp, bp, track, cnt, msf, subq, fmt)
SCSI *scgp;
@@ -948,6 +979,30 @@
}
EXPORT int
+reserve_track(scgp, size)
+ SCSI *scgp;
+ Ulong size;
+
+{
+ register struct scg_cmd *scmd = scgp->scmd;
+
+ fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+ scmd->flags = SCG_DISRE_ENA;
+ scmd->cdb_len = SC_G1_CDBLEN;
+ scmd->sense_len = CCS_SENSE_LEN;
+ scmd->cdb.g1_cdb.cmd = 0x53;
+ scmd->cdb.g1_cdb.lun = scg_lun(scgp);
+ i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], size);
+
+ scgp->cmdname = "reserve track";
+
+ if (scg_cmd(scgp) < 0)
+ return (-1);
+
+ return (0);
+}
+
+EXPORT int
read_dvd_structure(scgp, bp, cnt, fmt)
SCSI *scgp;
caddr_t bp;
--- cdrtools-2.0.orig/cdrecord/cdr_drv.c 2002-09-25 07:22:30.000000000 -0400
+++ cdrtools-2.0/cdrecord/cdr_drv.c 2003-02-22 21:06:16.000000000 -0500
@@ -42,6 +42,7 @@
extern cdr_t cdr_oldcd;
extern cdr_t cdr_cd;
extern cdr_t cdr_mmc;
+extern cdr_t cdr_dvd;
extern cdr_t cdr_mmc_sony;
extern cdr_t cdr_cd_dvd;
extern cdr_t cdr_philips_cdd521O;
@@ -78,6 +79,7 @@
cdr_t *drivers[] = {
&cdr_cd_dvd,
&cdr_mmc,
+ &cdr_dvd,
&cdr_mmc_sony,
&cdr_cd,
&cdr_oldcd,
--- cdrtools-2.0.orig/cdrecord/cdrecord.c 2002-12-24 08:16:39.000000000 -0500
+++ cdrtools-2.0/cdrecord/cdrecord.c 2003-02-23 02:06:13.000000000 -0500
@@ -4,7 +4,7 @@
"@(#)cdrecord.c 1.216 02/12/24 Copyright 1995-2002 J. Schilling";
#endif
/*
- * Record data on a CD/CVD-Recorder
+ * Record data on a CD/DVD-Recorder
*
* Copyright (c) 1995-2002 J. Schilling
*/
@@ -542,12 +542,6 @@
if (!is_mmc(scgp, &is_cdwr, &is_dvdwr))
is_cdwr = TRUE; /* If it is not MMC, it must be a CD writer */
- if (is_dvdwr && !set_cdrcmds("mmc_dvd", (cdr_t **)NULL)) {
- errmsgno(EX_BAD,
- "This version of cdrecord does not include DVD-R/DVD-RW support code.\n");
- errmsgno(EX_BAD,
- "If you need DVD-R/DVD-RW support, ask the Author for cdrecord-ProDVD.\n");
- }
/*
* Only exit if this is not the ProDVD test binary.
*/
@@ -620,6 +614,21 @@
}
scgp->silent--;
+ /* If it is DVD, the information in TOC is fabricated :)
+ * The real information is from read disk info command. */
+ if (dp->cdr_dstat->ds_flags & DSF_DVD) {
+ /* If it is DVD, the information in TOC is fabricated :)
+ * The real information is from read disk info command. */
+ if (dp->cdr_dstat->ds_trlast > 0) {
+ trackno = dp->cdr_dstat->ds_trlast - 1;
+ printf("Track Number : %d\n", trackno);
+ }
+
+ /* Disable TAO. DVD's don't need this in order to support
+ * packet writing. XXX */
+ //track[1].flags &= ~TI_TAO;
+ }
+
if (tracks > 0 && (debug || lverbose))
printf("FIFO size : %lu = %lu KB\n", fs, fs >> 10);
@@ -3061,7 +3070,7 @@
flags &= ~TI_SHORT_TRACK;
if (bswab)
flags |= TI_SWAB;
- if (ispacket)
+ if (ispacket)
flags |= TI_PACKET;
if (noclose)
flags |= TI_NOCLOSE;
--- cdrtools-2.0.orig/cdrecord/cdrecord.h 2002-11-03 10:32:55.000000000 -0500
+++ cdrtools-2.0/cdrecord/cdrecord.h 2003-02-22 22:42:11.000000000 -0500
@@ -819,6 +819,9 @@
BOOL *cdrrwp, BOOL *cdwrwp,
BOOL *dvdp, BOOL *dvdwp));
extern void print_capabilities __PR((SCSI *scgp));
+
+extern int read_rzone_info __PR((SCSI *scgp, caddr_t bp, int track, int cnt));
+extern int reserve_track __PR((SCSI *scgp, Ulong size));
#endif
/*
--- cdrtools-2.0.orig/cdrecord/drv_mmc.c 2002-11-30 07:01:30.000000000 -0500
+++ cdrtools-2.0/cdrecord/drv_mmc.c 2003-02-23 03:50:48.000000000 -0500
@@ -82,6 +82,7 @@
EXPORT char *hasdrvopt __PR((char *optstr, char *optname));
LOCAL cdr_t *identify_mmc __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));
LOCAL int attach_mmc __PR((SCSI *scgp, cdr_t *));
+LOCAL int attach_dvd __PR((SCSI *scgp, cdr_t *));
EXPORT int check_writemodes_mmc __PR((SCSI *scgp, cdr_t *dp));
LOCAL int deflt_writemodes_mmc __PR((SCSI *scgp, BOOL reset_dummy));
LOCAL int get_diskinfo __PR((SCSI *scgp, struct disk_info *dip));
@@ -91,15 +92,22 @@
LOCAL int get_pma __PR((SCSI *scgp));
#endif
LOCAL int getdisktype_mmc __PR((SCSI *scgp, cdr_t *dp));
+LOCAL int getdisktype_dvd __PR((SCSI *scgp, cdr_t *dp));
LOCAL int speed_select_mmc __PR((SCSI *scgp, cdr_t *dp, int *speedp, int dummy));
+LOCAL int speed_select_dvd __PR((SCSI *scgp, cdr_t *dp, int *speedp, int dummy));
LOCAL int mmc_set_speed __PR((SCSI *scgp, int readspeed, int writespeed, int rotctl));
LOCAL int next_wr_addr_mmc __PR((SCSI *scgp, track_t *trackp, long *ap));
+LOCAL int next_wr_addr_dvd __PR((SCSI *scgp, track_t *trackp, long *ap));
LOCAL int write_leadin_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
LOCAL int open_track_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
+LOCAL int open_track_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
LOCAL int close_track_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
+LOCAL int close_track_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
LOCAL int open_session_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp, int toctype, int multi));
+LOCAL int open_session_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp, int toctype, int multi));
LOCAL int waitfix_mmc __PR((SCSI *scgp, int secs));
LOCAL int fixate_mmc __PR((SCSI *scgp, cdr_t *dp, int onp, int dummy, int toctype, track_t *trackp));
+LOCAL int fixate_dvd __PR((SCSI *scgp, cdr_t *dp, int onp, int dummy, int toctype, track_t *trackp));
LOCAL int blank_mmc __PR((SCSI *scgp, cdr_t *dp, long addr, int blanktype));
LOCAL int send_opc_mmc __PR((SCSI *scgp, caddr_t, int cnt, int doopc));
LOCAL int opt1_mmc __PR((SCSI *scgp, cdr_t *dp));
@@ -174,6 +182,41 @@
opt1_mmc,
};
+cdr_t cdr_dvd = {
+ 0, 0,
+ CDR_SWABAUDIO|CDR_DVD,
+ 372, 372,
+ "mmc_dvd",
+ "generic SCSI-3/mmc DVD-R driver",
+ 0,
+ (dstat_t *)0,
+ identify_mmc,
+ attach_dvd,
+ getdisktype_dvd,
+ scsi_load,
+ scsi_unload,
+ read_buff_cap,
+ (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
+ (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */
+ speed_select_dvd,
+ select_secsize,
+ next_wr_addr_dvd,
+ (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
+ scsi_cdr_write,
+ (int(*)__PR((SCSI *scgp, track_t *trackp)))cmd_dummy, /* send_cue */
+ (int(*)__PR((SCSI *scgp, cdr_t *dp, track_t *trackp)))cmd_dummy, /* write_leadin_mmc */
+ open_track_dvd,
+ close_track_dvd,
+ open_session_dvd,
+ cmd_dummy,
+ read_session_offset,
+ fixate_dvd,
+ (int(*)__PR((SCSI *, cdr_t *)))cmd_dummy,/* stats */
+ blank_mmc,
+ send_opc_mmc,
+ (int(*)__PR((SCSI *, cdr_t *)))cmd_dummy,/* opt1 */
+};
+
cdr_t cdr_mmc_sony = {
0, 0,
/* CDR_TAO|CDR_SAO|CDR_PACKET|CDR_SWABAUDIO,*/
@@ -494,7 +537,7 @@
#ifndef DVD_DEBUG
scgp->silent++;
#else
- error("identify_dvd: checking for DVD media\n");
+ error("identify_mmc: checking for DVD media\n");
#endif
if (read_dvd_structure(scgp, (caddr_t)xb, 32, 0) >= 0) {
/*
@@ -521,13 +564,12 @@
#ifndef DVD_DEBUG
scgp->silent--;
#else
- error("identify_dvd: is_dvd: %d\n", is_dvd);
+ error("identify_mmc: is_dvd: %d\n", is_dvd);
#endif
}
- if (is_dvd) {
- errmsgno(EX_BAD,
- "Found DVD media but DVD-R/DVD-RW support code is missing.\n");
- }
+ if (is_dvd)
+ dp = &cdr_dvd;
+
return (dp);
}
@@ -684,6 +726,44 @@
}
+LOCAL int
+attach_dvd(scgp, dp)
+ SCSI *scgp;
+ cdr_t *dp;
+{
+ struct cd_mode_page_2A *mp;
+
+ allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */
+
+ scgp->silent++;
+ mp = mmc_cap(scgp, NULL);/* Get MMC capabilities in allocated mp */
+ scgp->silent--;
+ if (mp == NULL)
+ return (-1); /* Pre SCSI-3/mmc drive */
+
+ dp->cdr_cdcap = mp; /* Store MMC cap pointer */
+
+ if (mp->loading_type == LT_TRAY)
+ dp->cdr_flags |= CDR_TRAYLOAD;
+ else if (mp->loading_type == LT_CADDY)
+ dp->cdr_flags |= CDR_CADDYLOAD;
+
+ if (mp->BUF != 0)
+ dp->cdr_flags |= CDR_BURNFREE;
+
+ check_writemodes_mmc(scgp, dp);
+ dp->cdr_dstat->ds_flags |= DSF_DVD;
+
+ if (driveropts != NULL) {
+ if (strcmp(driveropts, "help") == 0) {
+ mmc_opthelp(dp, 0);
+ }
+ }
+
+ return (0);
+}
+
+
EXPORT int
check_writemodes_mmc(scgp, dp)
SCSI *scgp;
@@ -974,6 +1054,10 @@
if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)
dsp->ds_last_leadout = dsp->ds_maxblocks;
+
+ dsp->ds_trfirst=dip->first_track;
+ dsp->ds_trlast=dip->last_track_ls;
+ dsp->ds_trfirst_ls=dip->first_track_ls;
}
LOCAL int
@@ -1076,6 +1160,27 @@
#endif /* PRINT_ATIP */
LOCAL int
+getdisktype_dvd(scgp, dp)
+ SCSI *scgp;
+ cdr_t *dp;
+{
+ struct track_info track_info;
+
+ if (getdisktype_mmc(scgp, dp) < 0)
+ return -1;
+
+ /* Read rzone info to get the space left on disk. ds_trlast is the last
+ * rzone on disk, can be invisible */
+ if (read_rzone_info(scgp, (caddr_t)&track_info, dp->cdr_dstat->ds_trlast,
+ sizeof(track_info)) >= 0)
+ dp->cdr_dstat->ds_maxblocks = a_to_u_4_byte(track_info.free_blocks) +
+ a_to_4_byte(track_info.next_writable_addr);
+
+ return 0;
+}
+
+
+LOCAL int
getdisktype_mmc(scgp, dp)
SCSI *scgp;
cdr_t *dp;
@@ -1565,6 +1670,29 @@
return (ret);
}
+
+LOCAL int
+speed_select_dvd(scgp, dp, speedp, dummy)
+ SCSI *scgp;
+ cdr_t *dp;
+ int *speedp;
+ int dummy;
+{
+ int retcode;
+ /* For the moment we just divide the CD speed by 7*/
+
+ if (speedp != NULL)
+ (*speedp) = (*speedp) * 8;
+
+ retcode = speed_select_mmc(scgp,dp,speedp,dummy);
+
+ if (speedp != NULL)
+ (*speedp) = (*speedp) / 7;
+
+ return retcode;
+}
+
+
LOCAL int
next_wr_addr_mmc(scgp, trackp, ap)
SCSI *scgp;
@@ -1604,6 +1732,47 @@
return (0);
}
+
+LOCAL int
+next_wr_addr_dvd(scgp, trackp, ap)
+ SCSI *scgp;
+ track_t *trackp;
+ long *ap;
+{
+ struct track_info track_info;
+ long next_addr;
+ int result = -1;
+ struct disk_info disk_info;
+
+ if (trackp != 0 && trackp->track > 0 && is_packet(trackp)) {
+ scgp->silent++;
+ result = read_rzone_info(scgp, (caddr_t)&track_info,
+ trackp->track, sizeof(track_info));
+ scgp->silent--;
+ if (scsi_in_progress(scgp)){
+ return -1;
+ }
+ }
+
+ if (result < 0) {
+ /* Get the last rzone*/
+ if(read_disk_info(scgp,(caddr_t)&disk_info,8) < 0)
+ return (-1);
+
+ if (read_rzone_info(scgp, (caddr_t)&track_info,
+ disk_info.last_track_ls, sizeof(track_info)) < 0)
+ return (-1);
+ }
+ if (scgp->verbose)
+ scg_prbytes("track info:", (Uchar *)&track_info,
+ sizeof(track_info)-scg_getresid(scgp));
+ next_addr = a_to_4_byte(track_info.next_writable_addr);
+ if (ap)
+ *ap = next_addr;
+ return (0);
+}
+
+
LOCAL int
write_leadin_mmc(scgp, dp, trackp)
SCSI *scgp;
@@ -1773,6 +1942,50 @@
return (0);
}
+
+LOCAL int
+open_track_dvd(scgp, dp, trackp)
+ SCSI *scgp;
+ cdr_t *dp;
+ track_t *trackp;
+{
+ Uchar mode[0x100];
+ int len;
+ struct cd_mode_page_05 *mp;
+
+ if (is_packet(trackp)) {
+ fillbytes((caddr_t)mode, sizeof(mode), '\0');
+
+ trackp[0].flags &= ~TI_TAO;
+
+ if (!get_mode_params(scgp, 0x05, "DVD write parameter",
+ mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
+ return (-1);
+ if (len == 0)
+ return (-1);
+
+ mp = (struct cd_mode_page_05 *)
+ (mode + sizeof(struct scsi_mode_header) +
+ ((struct scsi_mode_header *)mode)->blockdesc_len);
+
+ mp->write_type = WT_PACKET;
+ mp->LS_V = 1;
+ /* For now we set the link size to 0x10(32k) because
+ * Pioneer-A03 only support this */
+ mp->link_size=0x10;
+ mp->fp = 1;
+ i_to_4_byte(mp->packet_size, trackp->pktsize);
+ } else {
+ return 0;
+ }
+
+ if (!set_mode_params(scgp, "DVD write parameter", mode, len, 0, trackp->secsize))
+ return (-1);
+
+ return (0);
+}
+
+
LOCAL int
close_track_mmc(scgp, dp, trackp)
SCSI *scgp;
@@ -1808,6 +2021,31 @@
SES_DA_ROM, /* Invalid - use default */
};
+
+LOCAL int
+close_track_dvd(scgp, dp, trackp)
+ SCSI *scgp;
+ cdr_t *dp;
+ track_t *trackp;
+{
+ int ret;
+
+ if (!is_packet(trackp))
+ return (0);
+
+ if (scsi_flush_cache(scgp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
+ printf("Trouble flushing the cache\n");
+ return (-1);
+ }
+ if (!is_noclose(trackp)) {
+ ret = scsi_close_tr_session(scgp, 1, trackp->track, FALSE);
+ wait_unit_ready(scgp, 300);
+ return (ret);
+ }
+ return (0);
+}
+
+
LOCAL int
open_session_mmc(scgp, dp, trackp, toctype, multi)
SCSI *scgp;
@@ -1923,6 +2161,81 @@
return (0);
}
+
+LOCAL int
+open_session_dvd(scgp, dp, trackp, toctype, multi)
+ SCSI *scgp;
+ cdr_t *dp;
+ track_t *trackp;
+ int toctype;
+ int multi;
+{
+ Uchar mode[0x100];
+ int len;
+ struct cd_mode_page_05 *mp;
+ Ulong totalsize;
+ int i;
+ struct track_info track_info;
+
+ fillbytes((caddr_t)mode, sizeof(mode), '\0');
+
+ if (!get_mode_params(scgp, 0x05, "DVD write parameter",
+ mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
+ return (-1);
+ if (len == 0)
+ return (-1);
+
+ mp = (struct cd_mode_page_05 *)
+ (mode + sizeof(struct scsi_mode_header) +
+ ((struct scsi_mode_header *)mode)->blockdesc_len);
+ if (is_packet(trackp)){
+ mp->write_type=WT_PACKET;
+ mp->multi_session = (multi != 0) ? MS_MULTI : MS_NONE;
+ mp->fp=0;
+ mp->BUFE=1;
+ mp->track_mode=1;
+ } else {
+ mp->write_type = WT_SAO;
+ }
+
+ if (lverbose && dp->cdr_cdcap->BUF != 0)
+ printf("BURN-Free is %s.\n", mp->BUFE?"ON":"OFF");
+ if (driveropts != NULL) {
+ if ((strcmp(driveropts, "burnproof") == 0 ||
+ strcmp(driveropts, "burnfree") == 0) && dp->cdr_cdcap->BUF != 0) {
+ errmsgno(EX_BAD, "Turning BURN-Free on\n");
+ mp->BUFE = 1;
+ } else if ((strcmp(driveropts, "noburnproof") == 0 ||
+ strcmp(driveropts, "noburnfree") == 0)) {
+ errmsgno(EX_BAD, "Turning BURN-Free off\n");
+ mp->BUFE = 0;
+ } else if (strcmp(driveropts, "help") == 0) {
+ mmc_opthelp(dp, 0);
+ } else {
+ errmsgno(EX_BAD, "Bad driver opts '%s'.\n", driveropts);
+ mmc_opthelp(dp, EX_BAD);
+ }
+ }
+
+
+ if (!set_mode_params(scgp, "DVD write parameter", mode, len, 0, -1))
+ return (-1);
+
+ totalsize = 0;
+ for (i = 1; i <= trackp->tracks; i++) {
+ totalsize += trackp[i].tracksecs;
+ }
+
+ if (!is_packet(trackp)) {
+ /* in DAO mode we need to reserve space for the track*/
+ if (reserve_track(scgp, totalsize)<0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+
LOCAL int
waitfix_mmc(scgp, secs)
SCSI *scgp;
@@ -1949,6 +2262,33 @@
#undef W_SLEEP
}
+
+LOCAL int
+fixate_dvd(scgp, dp, onp, dummy, toctype, trackp)
+ SCSI *scgp;
+ cdr_t *dp;
+ int onp;
+ int dummy;
+ int toctype;
+ track_t *trackp;
+{
+ int ret;
+
+ /* Set a really BIG timeout and call fixate_mmc. The BIG
+ * timeout is needed in case there was a very short rzone to
+ * write at the beginning of the disk, because lead-out needs
+ * to be at some distance. */
+ scg_settimeout(scgp, 1000);
+ if (is_packet(trackp)) {
+ scsi_close_tr_session(scgp, 2, 0, FALSE);
+ }
+ ret = fixate_mmc(scgp, dp, onp, dummy, toctype, trackp);
+ scg_settimeout(scgp, 200);
+
+ return ret;
+}
+
+
LOCAL int
fixate_mmc(scgp, dp, onp, dummy, toctype, trackp)
SCSI *scgp;
--- cdrtools-2.0.orig/cdrecord/scsi_cdr.c 2002-11-03 10:32:56.000000000 -0500
+++ cdrtools-2.0/cdrecord/scsi_cdr.c 2003-02-23 01:12:27.000000000 -0500
@@ -753,6 +753,37 @@
return (scg_cmd(scgp));
}
+
+EXPORT int
+read_rzone_info(scgp, bp, track, cnt)
+ SCSI *scgp;
+ caddr_t bp;
+ int track;
+ int cnt;
+
+{
+ register struct scg_cmd *scmd = scgp->scmd;
+
+ fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+ scmd->addr = bp;
+ scmd->size = cnt;
+ scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
+ scmd->cdb_len = SC_G1_CDBLEN;
+ scmd->sense_len = CCS_SENSE_LEN;
+ scmd->timeout = 4 * 60; /* Needs up to 2 minutes */
+ scmd->cdb.g1_cdb.cmd = 0x52;
+ scmd->cdb.g1_cdb.lun = scg_lun(scgp);
+ scmd->cdb.g1_cdb.reladr = 1;
+ g1_cdbaddr(&scmd->cdb.g1_cdb, track);
+ g1_cdblen(&scmd->cdb.g1_cdb, cnt);
+
+ scgp->cmdname = "read rzone info";
+
+ if (scg_cmd(scgp) < 0)
+ return (-1);
+ return (0);
+}
+
EXPORT int
read_subchannel(scgp, bp, track, cnt, msf, subq, fmt)
SCSI *scgp;
@@ -948,6 +979,30 @@
}
EXPORT int
+reserve_track(scgp, size)
+ SCSI *scgp;
+ Ulong size;
+
+{
+ register struct scg_cmd *scmd = scgp->scmd;
+
+ fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+ scmd->flags = SCG_DISRE_ENA;
+ scmd->cdb_len = SC_G1_CDBLEN;
+ scmd->sense_len = CCS_SENSE_LEN;
+ scmd->cdb.g1_cdb.cmd = 0x53;
+ scmd->cdb.g1_cdb.lun = scg_lun(scgp);
+ i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], size);
+
+ scgp->cmdname = "reserve track";
+
+ if (scg_cmd(scgp) < 0)
+ return (-1);
+
+ return (0);
+}
+
+EXPORT int
read_dvd_structure(scgp, bp, cnt, fmt)
SCSI *scgp;
caddr_t bp;
Reply to: