diff options
Diffstat (limited to 'scsi/scsi_rom.c')
-rw-r--r-- | scsi/scsi_rom.c | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/scsi/scsi_rom.c b/scsi/scsi_rom.c new file mode 100644 index 0000000..1a8dec9 --- /dev/null +++ b/scsi/scsi_rom.c @@ -0,0 +1,401 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * File: scsi_rom.c + * Author: Alessandro Forin, Carnegie Mellon University + * Date: 10/90 + * + * Middle layer of the SCSI driver: SCSI protocol implementation + * + * This file contains code for SCSI commands for CD-ROM devices. + */ + +#include <mach/std_types.h> +#include <scsi/compat_30.h> + +#include <scsi/scsi.h> +#include <scsi/scsi2.h> +#include <scsi/scsi_defs.h> + +#if (NSCSI > 0) + +char *sccdrom_name( + boolean_t internal) +{ + return internal ? "rz" : "CD-ROM"; +} + +int scsi_pause_resume( + target_info_t *tgt, + boolean_t stop_it, + io_req_t ior) +{ + scsi_cmd_pausres_t *cmd; + + cmd = (scsi_cmd_pausres_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PAUSE_RESUME; + cmd->scsi_cmd_lun_and_relbit = 0; + cmd->scsi_cmd_lba1 = 0; + cmd->scsi_cmd_lba2 = 0; + cmd->scsi_cmd_lba3 = 0; + cmd->scsi_cmd_lba4 = 0; + cmd->scsi_cmd_xxx = 0; + cmd->scsi_cmd_xfer_len_1 = 0; + cmd->scsi_cmd_pausres_res = stop_it ? 0 : SCSI_CMD_PAUSRES_RESUME; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PAUSE_RESUME; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_play_audio( + target_info_t *tgt, + unsigned int start, + unsigned int len, + boolean_t relative_address, + io_req_t ior) +{ + scsi_cmd_play_audio_t *cmd; + + cmd = (scsi_cmd_play_audio_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO; + cmd->scsi_cmd_lun_and_relbit = relative_address ? SCSI_RELADR : 0; + cmd->scsi_cmd_lba1 = start >> 24; + cmd->scsi_cmd_lba2 = start >> 16; + cmd->scsi_cmd_lba3 = start >> 8; + cmd->scsi_cmd_lba4 = start >> 0; + cmd->scsi_cmd_xxx = 0; + cmd->scsi_cmd_xfer_len_1 = len >> 8; + cmd->scsi_cmd_xfer_len_2 = len >> 0; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_play_audio_long( + target_info_t *tgt, + unsigned int start, + unsigned int len, + boolean_t relative_address, + io_req_t ior) +{ + scsi_cmd_play_audio_l_t *cmd; + + cmd = (scsi_cmd_play_audio_l_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_LONG; + cmd->scsi_cmd_lun_and_relbit = relative_address ? SCSI_RELADR : 0; + cmd->scsi_cmd_lba1 = start >> 24; + cmd->scsi_cmd_lba2 = start >> 16; + cmd->scsi_cmd_lba3 = start >> 8; + cmd->scsi_cmd_lba4 = start >> 0; + cmd->scsi_cmd_xfer_len_1 = len >> 24; + cmd->scsi_cmd_xfer_len_2 = len >> 16; + cmd->scsi_cmd_xfer_len_3 = len >> 8; + cmd->scsi_cmd_xfer_len_4 = len >> 0; + cmd->scsi_cmd_xxx1 = 0; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_LONG; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_play_audio_msf( + target_info_t *tgt, + int sm, + int ss, + int sf, + int em, + int es, + int ef, + io_req_t ior) +{ + scsi_cmd_play_audio_msf_t *cmd; + + cmd = (scsi_cmd_play_audio_msf_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_MSF; + cmd->scsi_cmd_lun_and_relbit = 0; + cmd->scsi_cmd_lba1 = 0; + cmd->scsi_cmd_pamsf_startM = sm; + cmd->scsi_cmd_pamsf_startS = ss; + cmd->scsi_cmd_pamsf_startF = sf; + cmd->scsi_cmd_pamsf_endM = em; + cmd->scsi_cmd_pamsf_endS = es; + cmd->scsi_cmd_pamsf_endF = ef; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_MSF; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_play_audio_track_index( + target_info_t *tgt, + int st, + int si, + int et, + int ei, + io_req_t ior) +{ + scsi_cmd_play_audio_ti_t *cmd; + + cmd = (scsi_cmd_play_audio_ti_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TI; + cmd->scsi_cmd_lun_and_relbit = 0; + cmd->scsi_cmd_lba1 = 0; + cmd->scsi_cmd_lba2 = 0; + cmd->scsi_cmd_pati_startT = st; + cmd->scsi_cmd_pati_startI = si; + cmd->scsi_cmd_xxx = 0; + cmd->scsi_cmd_pati_endT = et; + cmd->scsi_cmd_pati_endI = ei; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TI; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_play_audio_track_relative( + target_info_t *tgt, + unsigned int lba, + int st, + unsigned int len, + io_req_t ior) +{ + scsi_cmd_play_audio_tr_t *cmd; + + cmd = (scsi_cmd_play_audio_tr_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TR; + cmd->scsi_cmd_lun_and_relbit = 0; + cmd->scsi_cmd_lba1 = lba >> 24; + cmd->scsi_cmd_lba2 = lba >> 16; + cmd->scsi_cmd_lba3 = lba >> 8; + cmd->scsi_cmd_lba4 = lba >> 0; + cmd->scsi_cmd_patr_startT = st; + cmd->scsi_cmd_xfer_len_1 = len >> 8; + cmd->scsi_cmd_xfer_len_2 = len >> 0; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TR; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_play_audio_track_relative_long( + target_info_t *tgt, + unsigned int lba, + int st, + unsigned int len, + io_req_t ior) +{ + scsi_cmd_play_audio_tr_l_t *cmd; + + cmd = (scsi_cmd_play_audio_tr_l_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TR_LONG; + cmd->scsi_cmd_lun_and_relbit = 0; + cmd->scsi_cmd_lba1 = lba >> 24; + cmd->scsi_cmd_lba2 = lba >> 16; + cmd->scsi_cmd_lba3 = lba >> 8; + cmd->scsi_cmd_lba4 = lba >> 0; + cmd->scsi_cmd_xfer_len_1 = len >> 24; + cmd->scsi_cmd_xfer_len_2 = len >> 16; + cmd->scsi_cmd_xfer_len_3 = len >> 8; + cmd->scsi_cmd_xfer_len_4 = len >> 0; + cmd->scsi_cmd_patrl_startT = st; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TR_LONG; + + scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); + + return tgt->done; +} + +scsi_read_header( + target_info_t *tgt, + boolean_t msf_format, + unsigned int lba, + unsigned int allocsize, + io_req_t ior) +{ + scsi_cmd_read_header_t *cmd; + + cmd = (scsi_cmd_read_header_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_READ_HEADER; + cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0; + cmd->scsi_cmd_lba1 = lba >> 24; + cmd->scsi_cmd_lba2 = lba >> 16; + cmd->scsi_cmd_lba3 = lba >> 8; + cmd->scsi_cmd_lba4 = lba >> 0; + cmd->scsi_cmd_xxx = 0; + cmd->scsi_cmd_xfer_len_1 = allocsize >> 8; + cmd->scsi_cmd_xfer_len_2 = allocsize >> 0; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_READ_HEADER; + + scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior); + + return tgt->done; +} + +scsi_read_subchannel( + target_info_t *tgt, + boolean_t msf_format, + unsigned int data_format, + unsigned int trackno, + io_req_t ior) +{ + scsi_cmd_read_subch_t *cmd; + int allocsize; + + switch (data_format) { + case SCSI_CMD_RS_FMT_SUBQ: + allocsize = sizeof(cdrom_chan_data_t); + trackno = 0; break; + case SCSI_CMD_RS_FMT_CURPOS: + allocsize = sizeof(cdrom_chan_curpos_t); + trackno = 0; break; + case SCSI_CMD_RS_FMT_CATALOG: + allocsize = sizeof(cdrom_chan_catalog_t); + trackno = 0; break; + case SCSI_CMD_RS_FMT_ISRC: + allocsize = sizeof(cdrom_chan_isrc_t); break; + } + + cmd = (scsi_cmd_read_subch_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_READ_SUBCH; + cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0; + cmd->scsi_cmd_lba1 = SCSI_CMD_RS_SUBQ; + cmd->scsi_cmd_rs_format = data_format; + cmd->scsi_cmd_lba3 = 0; + cmd->scsi_cmd_lba4 = 0; + cmd->scsi_cmd_rs_trackno = trackno; + cmd->scsi_cmd_xfer_len_1 = allocsize >> 8; + cmd->scsi_cmd_xfer_len_2 = allocsize >> 0; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_READ_SUBCH; + + scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior); + + return tgt->done; +} + +scsi_read_toc( + target_info_t *tgt, + boolean_t msf_format, + int trackno, + int allocsize, + io_req_t ior) +{ + scsi_cmd_read_toc_t *cmd; + + cmd = (scsi_cmd_read_toc_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_READ_TOC; + cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0; + cmd->scsi_cmd_lba1 = 0; + cmd->scsi_cmd_lba2 = 0; + cmd->scsi_cmd_lba3 = 0; + cmd->scsi_cmd_lba4 = 0; + cmd->scsi_cmd_rtoc_startT = trackno; + cmd->scsi_cmd_xfer_len_1 = allocsize >> 8; + cmd->scsi_cmd_xfer_len_2 = allocsize >> 0; + cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ + + tgt->cur_cmd = SCSI_CMD_READ_TOC; + + scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior); + + return tgt->done; +} + +/* move elsewhere ifworks */ +scsi2_mode_select( + target_info_t *tgt, + boolean_t save, + unsigned char *page, + int pagesize, + io_req_t ior) +{ + scsi_cmd_mode_select_t *cmd; + scsi2_mode_param_t *parm; + + bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm)); + cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr); + cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT; + cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF | (save ? SCSI_CMD_MSL_SP : 0); + cmd->scsi_cmd_xfer_len = pagesize; + + parm = (scsi2_mode_param_t*) (cmd + 1); + + bcopy(page, parm, pagesize); + + tgt->cur_cmd = SCSI_CMD_MODE_SELECT; + + scsi_go_and_wait(tgt, sizeof(*cmd) + pagesize, 0, ior); + + return tgt->done; +} + +/* + * obnoxious + */ +cdrom_vendor_specific( + target_info_t *tgt, + scsi_command_group_2 *cmd, + unsigned char *params, + int paramlen, + int retlen, + io_req_t ior) +{ + bcopy(cmd, tgt->cmd_ptr, sizeof(*cmd)); + if (paramlen) + bcopy(params, tgt->cmd_ptr + sizeof(*cmd), paramlen); + + tgt->cur_cmd = cmd->scsi_cmd_code; + + scsi_go_and_wait(tgt, sizeof(*cmd) + paramlen, retlen, ior); + + return tgt->done; +} +#endif /* NSCSI > 0 */ |