Add 2 new ioctls: WORMIOCREADSESSIONINFO and WORMIOCWRITESESSION.
These commands are required for the "Disk-At-Once" write process: WORMIOCREADSESSIONINFO returns the length of the lead-in and lead-out areas and WORMIOCWRITESESSION is used to send the table of contents of the disk.
This commit is contained in:
parent
1a26f4c024
commit
7344a61e7b
@ -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.
|
||||
|
@ -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 */
|
||||
|
150
sys/scsi/worm.c
150
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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user