Date: Sun, 12 Oct 1997 10:12:09 -0700 (PDT) From: <nsayer@quack.kfu.com> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/4746: Yamaha CDR support Message-ID: <199710121712.KAA00366@morpheus.kfu.com> Resent-Message-ID: <199710121720.KAA03711@hub.freebsd.org>
index | next in thread | raw e-mail
>Number: 4746
>Category: kern
>Synopsis: Yamaha CDR support
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Class: support
>Submitter-Id: current-users
>Arrival-Date: Sun Oct 12 10:20:01 PDT 1997
>Last-Modified:
>Originator: Nick Sayer
>Organization:
just me
>Release: FreeBSD 2.2.2-RELEASE i386
>Environment:
Unknown Yamaha CD Worm bunrer
>Description:
This code is untested. I tried it on a Yamaha CDR-400 I just bought,
but that drive does not appear to be getting along with my SCSI controller,
so my lack of success may not mean anything.
This is a port of the relevant sections of cdwrite-2.0.
>How-To-Repeat:
>Fix:
--- worm.c- Sat Oct 11 16:24:33 1997
+++ worm.c Sun Oct 12 10:07:22 1997
@@ -142,6 +142,11 @@
static errval hp4020i_finalize_track(struct scsi_link *);
static errval hp4020i_finalize_disk(struct scsi_link *, int toc_type, int onp);
+static errval yamaha_prepare_disk(struct scsi_link *, int dummy, int speed);
+static errval yamaha_prepare_track(struct scsi_link *, int audio, int preemp);
+static errval yamaha_finalize_track(struct scsi_link *);
+static errval yamaha_finalize_disk(struct scsi_link *, int toc_type, int onp);
+
static worm_devsw_installed = 0;
static d_open_t wormopen;
@@ -205,6 +210,11 @@
hp4020i_prepare_disk, hp4020i_prepare_track,
hp4020i_finalize_track, hp4020i_finalize_disk
},
+ {
+ "YAMAHA", "CDR100",
+ yamaha_prepare_disk, yamaha_prepare_track,
+ yamaha_finalize_track, yamaha_finalize_disk
+ },
{0}
};
@@ -1152,6 +1162,172 @@
/*
* End Plasmon RF4100/4102 section.
*/
+
+/*
+ * YAMAHA CDR400c
+ * Most of this was cribbed out of cdwrite.
+ */
+
+struct yamaha_pages
+{
+ u_char page_code;
+#define YAMAHA_PAGE_CODE_31 0x31
+ u_char param_len;
+ union
+ {
+ struct
+ {
+ u_char reserved;
+ u_char speed_dummy;
+#define YAMAHA_QUAD_SPEED 0x20
+#define YAMAHA_DOUBLE_SPEED 0x10
+#define YAMAHA_DUMMY_WRITE 0x01
+ }
+ page_0x31;
+ }
+ pages;
+};
+
+static errval
+yamaha_prepare_disk(struct scsi_link *sc_link, int dummy, int speed)
+{
+ struct scsi_mode_select scsi_cmd;
+ struct {
+ struct scsi_mode_header header;
+ struct yamaha_pages page;
+ } dat;
+ u_int32_t pagelen, dat_len;
+
+ pagelen = sizeof(dat.page.pages.page_0x31) + PAGE_HEADERLEN;
+ dat_len = sizeof(struct scsi_mode_header) + pagelen;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("yamaha_prepare_disk"));
+
+ if (speed > 4 || speed < 1 || speed == 3)
+ return EINVAL;
+
+ bzero(&dat, sizeof(dat));
+ bzero(&scsi_cmd, sizeof(scsi_cmd));
+ scsi_cmd.op_code = MODE_SELECT;
+ scsi_cmd.byte2 |= SMS_PF;
+ scsi_cmd.length = dat_len;
+ /* dat.header.dev_spec = host application code; (see spec) */
+ dat.page.page_code = YAMAHA_PAGE_CODE_31;
+ dat.page.param_len = sizeof(dat.page.pages.page_0x31);
+ dat.page.pages.page_0x31.speed_dummy =
+ ( speed == 4 ? YAMAHA_QUAD_SPEED :
+ ( speed == 2 ? YAMAHA_DOUBLE_SPEED : 0 ) ) |
+ ( dummy ? YAMAHA_DUMMY_WRITE : 0 );
+ /*
+ * Fire it off.
+ */
+ return scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &scsi_cmd,
+ sizeof(scsi_cmd),
+ (u_char *) &dat,
+ dat_len,
+ /*WORM_RETRIES*/ 4,
+ 5000,
+ NULL,
+ SCSI_DATA_OUT);
+}
+static errval
+yamaha_prepare_track(struct scsi_link *sc_link, int audio, int preemp)
+{
+ struct scsi_mode_select scsi_cmd;
+ struct {
+ struct scsi_mode_header header;
+ struct blk_desc blk_desc;
+ } dat;
+ u_int32_t pagelen, dat_len, blk_len;
+
+ dat_len = sizeof(struct scsi_mode_header)
+ + sizeof(struct blk_desc);
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("yamaha_prepare_track"));
+
+ if (preemp)
+ return EINVAL; /* Don't know how */
+
+ /*
+ * By now, make a simple decision about the block length to be
+ * used. It's just only Red Book (Audio) == 2352 bytes, or
+ * Yellow Book (CD-ROM) Mode 1 == 2048 bytes.
+ */
+ blk_len = audio ? 2352 : 2048 ;
+
+ bzero(&dat, sizeof(dat));
+ bzero(&scsi_cmd, sizeof(scsi_cmd));
+ scsi_cmd.op_code = MODE_SELECT;
+ scsi_cmd.byte2 |= SMS_PF;
+ scsi_cmd.length = dat_len;
+ dat.header.blk_desc_len = sizeof(struct blk_desc);
+ /* dat.header.dev_spec = host application code; (see spec) */
+ scsi_uto3b(blk_len, dat.blk_desc.blklen);
+ /*
+ * Fire it off.
+ */
+ return scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &scsi_cmd,
+ sizeof(scsi_cmd),
+ (u_char *) &dat,
+ dat_len,
+ /*WORM_RETRIES*/ 4,
+ 5000,
+ NULL,
+ SCSI_DATA_OUT);
+}
+static errval
+yamaha_finalize_track(struct scsi_link *sc_link)
+{
+ struct scsi_synchronize_cache cmd;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("yamaha_finalize_track"));
+
+ /*
+ * Only a "synchronize cache" is needed.
+ */
+ bzero(&cmd, sizeof(cmd));
+ cmd.op_code = SYNCHRONIZE_CACHE;
+ return scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd,
+ sizeof(cmd),
+ 0, /* no data transfer */
+ 0,
+ 1,
+ 60000, /* this may take a while */
+ NULL,
+ 0);
+}
+static errval
+yamaha_finalize_disk(struct scsi_link *sc_link, int toc_type, int onp)
+{
+ struct scsi_fixation cmd;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("yamaha_finalize_disk"));
+
+ if (toc_type < 0 || toc_type > WORM_TOC_TYPE_CDI)
+ return EINVAL;
+
+ /*
+ * Fixate this session. Mark the next one as opened if onp
+ * is true. Otherwise, the disk will be finalized once and
+ * for all. ONP stands for "open next program area".
+ */
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.op_code = FIXATION;
+ cmd.action = (onp? WORM_FIXATION_ONP: 0) + toc_type;
+ return scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd,
+ sizeof(cmd),
+ 0, /* no data transfer */
+ 0,
+ 1,
+ 20*60*1000, /* takes a huge amount of time */
+ NULL,
+ 0);
+}
/*
* HP C4324/C4325 (This is what the scsi spec. and firmware says)
>Audit-Trail:
>Unformatted:
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710121712.KAA00366>
