drv_sony.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:23k
- /* @(#)drv_sony.c 1.37 99/10/17 Copyright 1997 J. Schilling */
- #ifndef lint
- static char sccsid[] =
- "@(#)drv_sony.c 1.37 99/10/17 Copyright 1997 J. Schilling";
- #endif
- /*
- * CDR device implementation for
- * Sony
- *
- * 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 SONY_DEBUG*/
- #include <mconfig.h>
- #include <stdio.h>
- #include <standard.h>
- #include <fctldefs.h>
- #include <errno.h>
- #include <strdefs.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 "cdrecord.h"
- #ifdef SONY_DEBUG
- # define inc_verbose() scgp->verbose++
- # define dec_verbose() scgp->verbose--
- #else
- # define inc_verbose()
- # define dec_verbose()
- #endif
- extern int lverbose;
- #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
- struct sony_924_mode_page_20 { /* mastering information */
- MP_P_CODE; /* parsave & pagecode */
- u_char p_len; /* 0x06 = 6 Bytes */
- u_char subcode_header_off;
- Ucbit res3_0 : 1;
- Ucbit speudo : 1;
- Ucbit res3_2 : 1;
- Ucbit c2po : 1;
- Ucbit subcode_ecc : 1;
- Ucbit res3_567 : 3;
- u_char res_4;
- u_char cue_sheet_opt;
- u_char res[2];
- };
- #else /* Motorola byteorder */
- struct sony_924_mode_page_20 { /* mastering information */
- MP_P_CODE; /* parsave & pagecode */
- u_char p_len; /* 0x06 = 6 Bytes */
- u_char subcode_header_off;
- Ucbit res3_567 : 3;
- Ucbit subcode_ecc : 1;
- Ucbit c2po : 1;
- Ucbit res3_2 : 1;
- Ucbit speudo : 1;
- Ucbit res3_0 : 1;
- u_char res_4;
- u_char cue_sheet_opt;
- u_char res[2];
- };
- #endif
- struct sony_924_mode_page_22 { /* disk information */
- MP_P_CODE; /* parsave & pagecode */
- u_char p_len; /* 0x1E = 30 Bytes */
- u_char disk_style;
- u_char disk_type;
- u_char first_track;
- u_char last_track;
- u_char numsess;
- u_char res_7;
- u_char disk_appl_code[4];
- u_char last_start_time[4];
- u_char disk_status;
- u_char num_valid_nra;
- u_char track_info_track;
- u_char post_gap;
- u_char disk_id_code[4];
- u_char lead_in_start[4];
- u_char res[4];
- };
- struct sony_924_mode_page_23 { /* track information */
- MP_P_CODE; /* parsave & pagecode */
- u_char p_len; /* 0x22 = 34 Bytes */
- u_char res_2;
- u_char track_num;
- u_char data_form;
- u_char write_method;
- u_char session;
- u_char track_status;
- u_char start_lba[4];
- u_char next_recordable_addr[4];
- u_char blank_area_cap[4];
- u_char fixed_packet_size[4];
- u_char res_24;
- u_char starting_msf[3];
- u_char res_28;
- u_char ending_msf[3];
- u_char res_32;
- u_char next_rec_time[3];
- };
- struct sony_924_mode_page_31 { /* drive speed */
- MP_P_CODE; /* parsave & pagecode */
- u_char p_len; /* 0x02 = 2 Bytes */
- u_char speed;
- u_char res;
- };
- struct cdd_52x_mode_data {
- struct scsi_mode_header header;
- union cdd_pagex {
- struct sony_924_mode_page_20 page_s20;
- struct sony_924_mode_page_22 page_s22;
- struct sony_924_mode_page_23 page_s23;
- struct sony_924_mode_page_31 page_s31;
- } pagex;
- };
- LOCAL int write_continue_sony __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
- LOCAL int write_track_sony __PR((SCSI *scgp, long track, int sectype));
- LOCAL int close_track_sony __PR((SCSI *scgp, int track, track_t *trackp));
- LOCAL int finalize_sony __PR((SCSI *scgp, int onp, int dummy, int type, int tracks, track_t *trackp));
- LOCAL int recover_sony __PR((SCSI *scgp, int track));
- LOCAL int next_wr_addr_sony __PR((SCSI *scgp, int track, track_t *trackp, long *ap));
- LOCAL int reserve_track_sony __PR((SCSI *scgp, unsigned long len));
- LOCAL int getdisktype_sony __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));
- LOCAL void di_to_dstat_sony __PR((struct sony_924_mode_page_22 *dip, dstat_t *dsp));
- LOCAL int speed_select_sony __PR((SCSI *scgp, int *speedp, int dummy));
- LOCAL int next_writable_address_sony __PR((SCSI *scgp, long *ap, int track, int sectype, int tracktype));
- LOCAL int new_track_sony __PR((SCSI *scgp, int track, int sectype, int tracktype));
- LOCAL int open_track_sony __PR((SCSI *scgp, cdr_t *dp, int track, track_t *track_info));
- LOCAL int open_session_sony __PR((SCSI *scgp, int tracks, track_t *trackp, int toctype, int multi));
- LOCAL int get_page22_sony __PR((SCSI *scgp, char *mode));
- LOCAL int sony_attach __PR((SCSI *scgp, cdr_t *dp));
- #ifdef SONY_DEBUG
- LOCAL void print_sony_mp22 __PR((struct sony_924_mode_page_22 *xp, int len));
- LOCAL void print_sony_mp23 __PR((struct sony_924_mode_page_23 *xp, int len));
- #endif
- LOCAL int buf_cap_sony __PR((SCSI *scgp, long *, long *));
- cdr_t cdr_sony_cdu924 = {
- 0,
- CDR_TAO|CDR_DAO|CDR_CADDYLOAD|CDR_SWABAUDIO,
- "sony_cdu924",
- "driver for Sony CDU-924",
- 0,
- drive_identify,
- sony_attach,
- getdisktype_sony,
- scsi_load,
- scsi_unload,
- buf_cap_sony,
- (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
- recover_sony,
- speed_select_sony,
- select_secsize,
- next_wr_addr_sony,
- reserve_track_sony,
- write_continue_sony,
- no_sendcue,
- open_track_sony,
- close_track_sony,
- open_session_sony,
- cmd_dummy,
- read_session_offset_philips,
- finalize_sony,
- blank_dummy,
- };
- LOCAL int
- write_continue_sony(scgp, bp, sectaddr, size, blocks, islast)
- SCSI *scgp;
- 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 */
- {
- register struct scg_cmd *scmd = scgp->scmd;
- fillbytes((caddr_t)scmd, sizeof(*scmd), ' ');
- scmd->addr = bp;
- scmd->size = size;
- scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
- scmd->cdb_len = SC_G1_CDBLEN;
- scmd->sense_len = CCS_SENSE_LEN;
- scmd->target = scgp->target;
- scmd->cdb.g1_cdb.cmd = 0xE1;
- scmd->cdb.g1_cdb.lun = scgp->lun;
- g0_cdbaddr(&scmd->cdb.g0_cdb, size); /* Hack, but Sony is silly */
-
- scgp->cmdname = "write_continue";
- if (scsicmd(scgp) < 0)
- return (-1);
- return (size - scsigetresid(scgp));
- }
- LOCAL int
- write_track_sony(scgp, track, sectype)
- SCSI *scgp;
- long track; /* track number 0 == new track */
- int sectype; /* no sectype for Sony write track */
- {
- register struct scg_cmd *scmd = scgp->scmd;
- fillbytes((caddr_t)scmd, sizeof(*scmd), ' ');
- scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
- scmd->cdb_len = SC_G1_CDBLEN;
- scmd->sense_len = CCS_SENSE_LEN;
- scmd->target = scgp->target;
- scmd->cdb.g1_cdb.cmd = 0xF5;
- scmd->cdb.g1_cdb.lun = scgp->lun;
- g1_cdbaddr(&scmd->cdb.g1_cdb, track);
-
- scgp->cmdname = "write_track";
- if (scsicmd(scgp) < 0)
- return (-1);
- return (0);
- }
- /* XXX NOCH NICHT FERTIG */
- LOCAL int
- close_track_sony(scgp, track, trackp)
- SCSI *scgp;
- int track;
- track_t *trackp;
- {
- register struct scg_cmd *scmd = scgp->scmd;
- track = 0;
- fillbytes((caddr_t)scmd, sizeof(*scmd), ' ');
- scmd->flags = SCG_DISRE_ENA;
- scmd->cdb_len = SC_G1_CDBLEN;
- scmd->sense_len = CCS_SENSE_LEN;
- scmd->target = scgp->target;
- scmd->cdb.g1_cdb.cmd = 0xF0;
- scmd->cdb.g1_cdb.lun = scgp->lun;
- g1_cdbaddr(&scmd->cdb.g1_cdb, track);
- /* XXX Padding ??? (bit 0 in addr[0]) */
-
- scgp->cmdname = "close_track";
- if (scsicmd(scgp) < 0)
- return (-1);
- /*
- * Clear the silly "error situation" from Sony