summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/worm.473
-rw-r--r--sys/scsi/scsi_worm.h24
-rw-r--r--sys/scsi/worm.c150
-rw-r--r--sys/sys/wormio.h17
4 files changed, 258 insertions, 6 deletions
diff --git a/share/man/man4/worm.4 b/share/man/man4/worm.4
index eaeda1a..a8d6da6 100644
--- a/share/man/man4/worm.4
+++ b/share/man/man4/worm.4
@@ -32,7 +32,7 @@
.\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
.\" DAMAGE.
.\"
-.\" $Id: worm.4,v 1.10 1997/02/22 13:24:55 peter Exp $
+.\" $Id: worm.4,v 1.11 1997/05/19 17:30:50 jmz Exp $
.\" "
.Dd January 27, 1996
.Dt WORM 4
@@ -233,6 +233,77 @@ data track, you can just set
to
.Dv BLOCK_MODE_1 .
+.It Dv WORMIOCREADSESSIONINFO
+This command returns the information needed for writing a complete
+session at once. The argument structure,
+.Dv struct wormio_session_info ,
+is as follows:
+.Bd -literal -offset indent
+struct wormio_session_info {
+ u_short lead_in;
+ u_short lead_out;
+};
+.Ed
+.Dv lead_in
+gives the length (in blocks) of the lead-in area.
+.Dv lead_out
+gives the length (in blocks) of the lead-out area.
+
+.It WORMIOCWRITESESSION
+This command enables to write a session without interruption. You must
+then supply raw data blocks for the lead-in, the program area
+(including pregaps) and the lead-out. The session is closed with a
+.Dv WORMIOCFINISHTRACK
+command. The argument structure,
+.Dv wormio_write_session ,
+is as follows:
+.Bd -literal -offset indent
+struct wormio_write_session {
+ int toc_type;
+ int onp;
+ int lofp;
+ int length;
+ char catalog[13];
+ u_char *track_desc;
+};
+.Ed
+.Dv toc_type
+determines what type of table of contents will be recorded in the
+lead-in. Possible values are:
+
+.Bl -tag -width XXX
+.It Dv 0
+CD-DA
+.It Dv 1
+CD_ROM
+.It Dv 2
+CD-ROM XA with first track in mode 1
+.It Dv 3
+CD-ROM XA with first track in mode 2
+.It Dv 4
+CDI
+.El
+
+.Dv onp ,
+if set to 1 requests a new program area to be opened. This implies
+that the start time of the new program area is included in the lead-in
+of the current session.
+.Dv lofp
+is a parameter only valid when
+.Dv toc_type
+is equal to 1 and specifies whether the lead-out must be written in
+mode 1 or mode 2. The mode of the lead-out must be equal to the mode
+of the last track of the session.
+.Dv length
+specifies the length of the track descriptor.
+.Dv catalog
+can be used to set the catalog number information and is composed of
+13 digits. If this array is composed of null bytes, no catalog will be
+written.
+.Dv track_desc
+is a pointer to the array containing the encoding of the table of
+contents.
+
.It Dv WORMIOCFINISHTRACK
Will terminate the track. It takes no argument. Note that closing the
device will also terminate the track.
diff --git a/sys/scsi/scsi_worm.h b/sys/scsi/scsi_worm.h
index b2fa774..0b2b876 100644
--- a/sys/scsi/scsi_worm.h
+++ b/sys/scsi/scsi_worm.h
@@ -15,6 +15,8 @@
#define WRITE_TRACK 0xe6 /* open the write channel */
#define LOAD_UNLOAD 0xe7 /* resembles part of START_STOP */
#define FIXATION 0xe9 /* write leadin/leadout */
+#define WRITE_SESSION 0xed /* guide to write a new session */
+#define READ_SESSION_INFO 0xee /* read leadin/leadout lengths */
struct scsi_rezero_unit
{
@@ -90,4 +92,26 @@ struct scsi_fixation
u_char control;
};
+struct scsi_write_session
+{
+ u_char op_code;
+ u_char byte2;
+ u_char reserved[4];
+ u_char action; /* see scsi_fixation above */
+#define WORM_LOFP_MODE_MODE1 0x10
+#define WORM_LOFP_MODE_MODE2 0x20
+ u_char transfer_length_2; /* number of blocks to transfer, MSB */
+ u_char transfer_length_1; /* LSB */
+ u_char control;
+};
+
+struct scsi_read_session_info
+{
+ u_char op_code;
+ u_char byte2;
+ u_char reserved[6];
+ u_char transfer_length;
+ u_char control;
+};
+
#endif /* _SCSI_SCSI_WORM_H */
diff --git a/sys/scsi/worm.c b/sys/scsi/worm.c
index f568a43..e6a2957 100644
--- a/sys/scsi/worm.c
+++ b/sys/scsi/worm.c
@@ -43,7 +43,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: worm.c,v 1.39 1997/05/19 17:30:40 jmz Exp $
+ * $Id: worm.c,v 1.40 1997/05/28 21:25:49 jmz Exp $
*/
#include "opt_bounce.h"
@@ -80,6 +80,7 @@ struct worm_quirks
errval (*prepare_track)(struct scsi_link *, struct wormio_prepare_track *t);
errval (*finalize_track)(struct scsi_link *);
errval (*finalize_disk)(struct scsi_link *, int toc_type, int onp);
+ errval (*write_session)(struct scsi_link *, struct wormio_write_session *);
};
@@ -138,6 +139,7 @@ static errval worm_read_toc(struct scsi_link *sc_link,
u_int32_t mode, u_int32_t start,
struct cd_toc_entry *data, u_int32_t len);
static errval worm_rezero_unit(struct scsi_link *sc_link);
+static errval worm_read_session_info(struct scsi_link *, struct wormio_session_info *);
static int worm_sense_handler(struct scsi_xfer *);
/* XXX should be moved out to an LKM */
@@ -150,6 +152,7 @@ static errval hp4020i_prepare_disk(struct scsi_link *, int dummy, int speed);
static errval hp4020i_prepare_track(struct scsi_link *, struct wormio_prepare_track *);
static errval hp4020i_finalize_track(struct scsi_link *);
static errval hp4020i_finalize_disk(struct scsi_link *, int toc_type, int onp);
+static errval hp4020i_write_session(struct scsi_link *, struct wormio_write_session *);
static worm_devsw_installed = 0;
@@ -199,11 +202,13 @@ static struct scsi_device worm_switch =
static struct worm_quirks worm_quirks_plasmon = {
rf4100_prepare_disk, rf4100_prepare_track,
- rf4100_finalize_track, rf4100_finalize_disk
+ rf4100_finalize_track, rf4100_finalize_disk,
+ 0
};
static struct worm_quirks worm_quirks_philips = {
hp4020i_prepare_disk, hp4020i_prepare_track,
- hp4020i_finalize_track, hp4020i_finalize_disk
+ hp4020i_finalize_track, hp4020i_finalize_disk,
+ hp4020i_write_session
};
static inline void
@@ -675,6 +680,28 @@ worm_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
}
break;
+ case WORMIOCREADSESSIONINFO:
+ {
+ struct wormio_session_info si;
+ error = worm_read_session_info(sc_link, &si);
+ if (error)
+ break;
+ NTOHS(si.lead_in);
+ NTOHS(si.lead_out);
+ bcopy(&si, addr, sizeof si);
+ }
+ break;
+
+ case WORMIOCWRITESESSION:
+ if (worm->quirks->write_session) {
+ error = (worm->quirks->write_session)
+ (sc_link, (struct wormio_write_session *) addr);
+ if (!error)
+ worm->worm_flags |= WORMFL_TRACK_PREPED;
+ } else
+ error = ENXIO;
+ break;
+
case WORMIOERROR:
bcopy(&(worm->error), addr, sizeof (int));
break;
@@ -854,6 +881,27 @@ worm_rezero_unit(struct scsi_link *sc_link)
0);
}
+static errval
+worm_read_session_info(struct scsi_link *sc_link, struct wormio_session_info *data)
+{
+ struct scsi_read_session_info cmd;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("worm_read_session_info"));
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.op_code = READ_SESSION_INFO;
+ cmd.transfer_length = sizeof(struct wormio_session_info);
+ return scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd,
+ sizeof(cmd),
+ (u_char *) data,
+ sizeof(struct wormio_session_info),
+ /*WORMRETRY*/ 4,
+ 5000,
+ NULL,
+ SCSI_DATA_IN);
+}
+
/*
* Read table of contents
*
@@ -1269,7 +1317,17 @@ struct hp_4020i_pages
u_char reserved2[2];
}
page_0x21;
- /* mode page 0x22 omitted by now */
+ struct
+ {
+ u_char catalog_valid;
+ u_char catalog_c1_c2; /* catalog number, BCD */
+ u_char catalog_c3_c4;
+ u_char catalog_c5_c6;
+ u_char catalog_c7_c8;
+ u_char catalog_c9_c10;
+ u_char catalog_c11_c12;
+ u_char catalog_c13_0;
+ } page_0x22;
struct
{
u_char speed_select;
@@ -1285,7 +1343,6 @@ struct hp_4020i_pages
pages;
};
-
static errval
hp4020i_prepare_disk(struct scsi_link *sc_link, int dummy, int speed)
{
@@ -1514,7 +1571,90 @@ hp4020i_finalize_disk(struct scsi_link *sc_link, int toc_type, int onp)
NULL,
0);
}
+static errval
+hp4020i_write_session(struct scsi_link *sc_link, struct wormio_write_session *ws)
+{
+ struct {
+ struct scsi_mode_header header;
+ struct blk_desc blk_desc;
+ struct hp_4020i_pages page;
+ } dat;
+ struct scsi_mode_select cmd1;
+ struct scsi_write_session cmd2;
+ struct scsi_data *worm;
+ u_int32_t pagelen, dat_len, blk_len;
+ errval error;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("hp4020i_write_session"));
+
+ if (ws->toc_type < 0 || ws->toc_type > WORM_TOC_TYPE_CDI || ws->lofp & ~3)
+ return EINVAL;
+
+ pagelen = sizeof(dat.page.pages.page_0x22) + PAGE_HEADERLEN;
+ dat_len = sizeof(struct scsi_mode_header)
+ + sizeof(struct blk_desc)
+ + pagelen;
+
+ worm = sc_link->sd;
+
+ /* set the block size to 2352 and the catalog */
+ bzero(&dat, sizeof(dat));
+ bzero(&cmd1, sizeof(cmd1));
+ cmd1.op_code = MODE_SELECT;
+ cmd1.byte2 |= SMS_PF;
+ cmd1.length = dat_len;
+ dat.header.blk_desc_len = sizeof(struct blk_desc);
+ dat.page.page_code = HP4020I_PAGE_CODE_22;
+ dat.page.param_len = sizeof(dat.page.pages.page_0x22);
+ blk_len = 2352;
+ if (ws->catalog[0] >= '0' && ws->catalog[0] <= '9') {
+ dat.page.pages.page_0x22.catalog_valid = 1;
+ dat.page.pages.page_0x22.catalog_c1_c2 = ((ws->catalog[0]-'0') << 4)
+ | ((ws->catalog[1]-'0') << 4);
+ dat.page.pages.page_0x22.catalog_c3_c4 = ((ws->catalog[2]-'0') << 4)
+ | ((ws->catalog[3]-'0') << 4);
+ dat.page.pages.page_0x22.catalog_c5_c6 = ((ws->catalog[4]-'0') << 4)
+ | ((ws->catalog[5]-'0') << 4);
+ dat.page.pages.page_0x22.catalog_c7_c8 = ((ws->catalog[6]-'0') << 4)
+ | ((ws->catalog[7]-'0') << 4);
+ dat.page.pages.page_0x22.catalog_c9_c10 = ((ws->catalog[8]-'0') << 4)
+ | ((ws->catalog[9]-'0') << 4);
+ dat.page.pages.page_0x22.catalog_c11_c12 = ((ws->catalog[10]-'0') << 4)
+ | ((ws->catalog[11]-'0') << 4);
+ dat.page.pages.page_0x22.catalog_c13_0 = ((ws->catalog[12]-'0') << 4);
+ }
+ scsi_uto3b(blk_len, dat.blk_desc.blklen);
+
+ error = scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd1,
+ sizeof(cmd1),
+ (u_char *) &dat,
+ dat_len,
+ /*WORM_RETRIES*/ 4,
+ 5000,
+ NULL,
+ SCSI_DATA_OUT);
+
+ if (!error) {
+ worm->blk_size = blk_len;
+ bzero(&cmd2, sizeof(cmd2));
+ cmd2.op_code = WRITE_SESSION;
+ cmd2.action = (ws->lofp << 4) | (ws->onp? WORM_FIXATION_ONP: 0) + ws->toc_type;
+ scsi_uto2b(ws->length, &cmd2.transfer_length_2);
+ error = scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd2,
+ sizeof(cmd2),
+ ws->track_desc,
+ ws->length,
+ 1,
+ 5000,
+ NULL,
+ SCSI_DATA_OUT);
+ }
+ return error;
+}
+
/*
* End HP C4324/C4325 (4020i) section.
*/
diff --git a/sys/sys/wormio.h b/sys/sys/wormio.h
index 646247b..2498523 100644
--- a/sys/sys/wormio.h
+++ b/sys/sys/wormio.h
@@ -72,6 +72,23 @@ struct wormio_fixation
*/
#define WORMIOCFINISHTRACK _IO('W', 23)
+
+struct wormio_session_info {
+ u_short lead_in;
+ u_short lead_out;
+};
+#define WORMIOCREADSESSIONINFO _IOR('W', 31, struct wormio_session_info)
+
+struct wormio_write_session {
+ int toc_type;
+ int onp;
+ int lofp;
+ int length;
+ char catalog[13];
+ u_char *track_desc;
+};
+#define WORMIOCWRITESESSION _IOW('W', 32, struct wormio_write_session)
+
/* Errors/warnings */
#define WORM_SEQUENCE_ERROR 1
#define WORM_DUMMY_BLOCKS_ADDED 2
OpenPOWER on IntegriCloud