summaryrefslogtreecommitdiff
path: root/scsi/scsi_rom.c
diff options
context:
space:
mode:
Diffstat (limited to 'scsi/scsi_rom.c')
-rw-r--r--scsi/scsi_rom.c401
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 */