drv_mmc.c
来自「刻录光盘的程序」· C语言 代码 · 共 1,299 行 · 第 1/3 页
C
1,299 行
/* @(#)drv_mmc.c 1.47 00/01/28 Copyright 1997 J. Schilling */#ifndef lintstatic char sccsid[] = "@(#)drv_mmc.c 1.47 00/01/28 Copyright 1997 J. Schilling";#endif/* * CDR device implementation for * SCSI-3/mmc conforming drives * e.g. Yamaha CDR-400, Ricoh MP6200 * * Copyright (c) 1997 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*/#define PRINT_ATIP#include <mconfig.h>#include <stdio.h>#include <standard.h>#include <fctldefs.h>#include <errno.h>#include <strdefs.h>#include <unixstd.h>#include <timedefs.h>#include <utypes.h>#include <btorder.h>#include <intcvt.h>#include <scg/scgcmd.h>#include <scg/scsidefs.h>#include <scg/scsireg.h>#include <scg/scsitransp.h>#include <scsimmc.h>#include "cdrecord.h"extern BOOL isgui;extern int debug;extern int lverbose;LOCAL int curspeed = 1;LOCAL int mmc_load __PR((SCSI *scgp));LOCAL int mmc_unload __PR((SCSI *scgp));LOCAL cdr_t *identify_mmc __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));LOCAL int attach_mmc __PR((SCSI *scgp, cdr_t *));LOCAL int get_diskinfo __PR((SCSI *scgp, struct disk_info *dip));LOCAL void di_to_dstat __PR((struct disk_info *dip, dstat_t *dsp));#ifdef PRINT_ATIPLOCAL int get_pma __PR((SCSI *scgp));#endifLOCAL int getdisktype_mmc __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));LOCAL int speed_select_mmc __PR((SCSI *scgp, int *speedp, int dummy));LOCAL int next_wr_addr_mmc __PR((SCSI *scgp, int track, track_t *trackp, long *ap));LOCAL int open_track_mmc __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));LOCAL int close_track_mmc __PR((SCSI *scgp, int track, track_t *trackp));LOCAL int open_session_mmc __PR((SCSI *scgp, int tracks, track_t *trackp, int toctype, int multi));LOCAL int waitfix_mmc __PR((SCSI *scgp, int secs));LOCAL int fixate_mmc __PR((SCSI *scgp, int onp, int dummy, int toctype, int tracks, track_t *trackp));LOCAL int blank_mmc __PR((SCSI *scgp, long addr, int blanktype));LOCAL int scsi_sony_write __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));LOCAL intmmc_load(scgp) SCSI *scgp;{ return (scsi_load_unload(scgp, 1));}LOCAL intmmc_unload(scgp) SCSI *scgp;{ return (scsi_load_unload(scgp, 0));}cdr_t cdr_mmc = { 0, CDR_TAO|CDR_DAO|CDR_PACKET|CDR_SWABAUDIO, "mmc_cdr", "generic SCSI-3/mmc CD-R driver", 0, identify_mmc, attach_mmc, getdisktype_mmc, scsi_load,/* mmc_load,*/ scsi_unload, read_buff_cap, (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */ (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */ speed_select_mmc, select_secsize, next_wr_addr_mmc, (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */ scsi_cdr_write, send_cue, open_track_mmc, close_track_mmc, open_session_mmc, cmd_dummy, read_session_offset, fixate_mmc, blank_mmc,};cdr_t cdr_mmc_sony = { 0, CDR_TAO|CDR_DAO|CDR_PACKET|CDR_SWABAUDIO, "mmc_cdr_sony", "generic SCSI-3/mmc CD-R driver (Sony 928 variant)", 0, identify_mmc, attach_mmc, getdisktype_mmc, scsi_load,/* mmc_load,*/ scsi_unload, read_buff_cap, (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */ (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */ speed_select_mmc, select_secsize, next_wr_addr_mmc, (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */ scsi_sony_write, send_cue, open_track_mmc, close_track_mmc, open_session_mmc, cmd_dummy, read_session_offset, fixate_mmc, blank_mmc,};/* * SCSI-3/mmc conformant CD drive */cdr_t cdr_cd = { 0, CDR_ISREADER|CDR_SWABAUDIO, "mmc_cd", "generic SCSI-3/mmc CD driver", 0, identify_mmc, attach_mmc, drive_getdisktype, scsi_load, scsi_unload, read_buff_cap, (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */ (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */ speed_select_mmc, select_secsize, (int(*)__PR((SCSI *scgp, int, track_t *, long *)))cmd_ill, /* next_wr_addr */ (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */ scsi_cdr_write, no_sendcue, open_track_mmc, close_track_mmc, (int(*)__PR((SCSI *scgp, int, track_t *, int, int)))cmd_dummy, cmd_dummy, read_session_offset, (int(*)__PR((SCSI *scgp, int, int, int, int, track_t *)))cmd_dummy, /* fixation */ blank_dummy,};/* * Old pre SCSI-3/mmc CD drive */cdr_t cdr_oldcd = { 0, CDR_ISREADER, "scsi2_cd", "generic SCSI-2 CD driver", 0, identify_mmc, drive_attach, drive_getdisktype, scsi_load, scsi_unload, buf_dummy, (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */ (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */ speed_select_mmc, select_secsize, (int(*)__PR((SCSI *scg, int, track_t *, long *)))cmd_ill, /* next_wr_addr */ (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */ scsi_cdr_write, no_sendcue, open_track_mmc, close_track_mmc, (int(*)__PR((SCSI *scgp, int, track_t *, int, int)))cmd_dummy, cmd_dummy, read_session_offset_philips, (int(*)__PR((SCSI *scgp, int, int, int, int, track_t *)))cmd_dummy, /* fixation */ blank_dummy,};LOCAL cdr_t *identify_mmc(scgp, dp, ip) SCSI *scgp; cdr_t *dp; struct scsi_inquiry *ip;{ BOOL cdrr = FALSE; /* Read CD-R */ BOOL cdwr = FALSE; /* Write CD-R */ BOOL cdrrw = FALSE; /* Read CD-RW */ BOOL cdwrw = FALSE; /* Write CD-RW */ Uchar mode[0x100]; struct cd_mode_page_2A *mp; if (ip->type != INQ_WORM && ip->type != INQ_ROMD) return ((cdr_t *)0); allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */ scgp->silent++; mp = mmc_cap(scgp, mode); /* Get MMC capabilities */ scgp->silent--; if (mp == NULL) return (&cdr_oldcd); /* Pre SCSI-3/mmc drive */ mmc_getval(mp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL); /* * At this point we know that we have a SCSI-3/mmc compliant drive. * Unfortunately ATAPI drives violate the SCSI spec in returning * a response data format of '1' which from the SCSI spec would * tell us not to use the "PF" bit in mode select. As ATAPI drives * require the "PF" bit to be set, we 'correct' the inquiry data. * * XXX xxx_identify() should not have any side_effects ?? */ if (ip->data_format < 2) ip->data_format = 2; if (strncmp(ip->vendor_info, "SONY", 4) == 0 && strncmp(ip->prod_ident, "CD-R CDU928E", 14) == 0) { dp = &cdr_mmc_sony; } if (!cdwr) /* SCSI-3/mmc CD drive */ dp = &cdr_cd; return (dp);}LOCAL intattach_mmc(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; return (0);}#ifdef PRINT_ATIPLOCAL int get_atip __PR((SCSI *scgp, struct atipinfo *atp)); void print_di __PR((struct disk_info *dip)); void print_atip __PR((SCSI *scgp, struct atipinfo *atp));#endif /* PRINT_ATIP */LOCAL intget_diskinfo(scgp, dip) SCSI *scgp; struct disk_info *dip;{ int len; int ret; fillbytes((caddr_t)dip, sizeof(*dip), '\0'); if (read_disk_info(scgp, (caddr_t)dip, 2) < 0) return (-1); len = a_to_u_2_byte(dip->data_len); len += 2; ret = read_disk_info(scgp, (caddr_t)dip, len);#ifdef DEBUG scsiprbytes("Disk info:", (u_char *)dip, len-scsigetresid(scgp));#endif return (ret);}LOCAL voiddi_to_dstat(dip, dsp) struct disk_info *dip; dstat_t *dsp;{ dsp->ds_diskid = a_to_u_4_byte(dip->disk_id); if (dip->did_v) dsp->ds_flags |= DSF_DID_V; dsp->ds_diskstat = dip->disk_status; dsp->ds_sessstat = dip->sess_status; dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1], dip->last_lead_out[2], dip->last_lead_out[3]); /* * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk */ if (dsp->ds_maxblocks == 716730) dsp->ds_maxblocks = -1L; if (dsp->ds_first_leadin == 0) { dsp->ds_first_leadin = msf_to_lba(dip->last_lead_in[1], dip->last_lead_in[2], dip->last_lead_in[3]); if (dsp->ds_first_leadin > 0) dsp->ds_first_leadin = 0; } if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0) dsp->ds_last_leadout = dsp->ds_maxblocks;}#ifdef PRINT_ATIPLOCAL intget_atip(scgp, atp) SCSI *scgp; struct atipinfo *atp;{ int len; int ret; fillbytes((caddr_t)atp, sizeof(*atp), '\0'); if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_ATIP) < 0) return (-1); len = a_to_u_2_byte(atp->hd.len); len += 2; ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_ATIP);#ifdef DEBUG scsiprbytes("ATIP info:", (u_char *)atp, len-scsigetresid(scgp));#endif /* * Yamaha sometimes returns zeroed ATIP info for disks without ATIP */ if (atp->desc.lead_in[1] == 0 && atp->desc.lead_in[2] == 0 && atp->desc.lead_in[3] == 0 && atp->desc.lead_out[1] == 0 && atp->desc.lead_out[2] == 0 && atp->desc.lead_out[3] == 0) return (-1); if (atp->desc.lead_in[1] >= 0x90 && debug) { /* * Only makes sense with buggy Ricoh firmware. */ errmsgno(EX_BAD, "Converting ATIP from BCD\n"); atp->desc.lead_in[1] = from_bcd(atp->desc.lead_in[1]); atp->desc.lead_in[2] = from_bcd(atp->desc.lead_in[2]); atp->desc.lead_in[3] = from_bcd(atp->desc.lead_in[3]); atp->desc.lead_out[1] = from_bcd(atp->desc.lead_out[1]); atp->desc.lead_out[2] = from_bcd(atp->desc.lead_out[2]); atp->desc.lead_out[3] = from_bcd(atp->desc.lead_out[3]); } return (ret);}LOCAL int/*get_pma(atp)*/get_pma(scgp) SCSI *scgp;/* struct atipinfo *atp;*/{ int len; int ret;char atp[1024]; fillbytes((caddr_t)atp, sizeof(*atp), '\0');/* if (read_toc(scgp, (caddr_t)atp, 0, 2, 1, FMT_PMA) < 0)*/ if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_PMA) < 0) return (-1);/* len = a_to_u_2_byte(atp->hd.len);*/ len = a_to_u_2_byte(atp); len += 2;/* ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);*/ ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_PMA);#ifdef DEBUG scsiprbytes("PMA:", (u_char *)atp, len-scsigetresid(scgp));#endif ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);#ifdef DEBUG scsiprbytes("PMA:", (u_char *)atp, len-scsigetresid(scgp));#endif return (ret);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?