root/sys/dev/isa/mcdreg.h
/*      $NetBSD: mcdreg.h,v 1.9 2000/06/08 18:22:16 cgd Exp $   */

/*
 * Copyright 1993 by Holger Veit (data part)
 * Copyright 1993 by Brian Moore (audio part)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This software was developed by Holger Veit and Brian Moore
 *      for use with "386BSD" and similar operating systems.
 *    "Similar operating systems" includes mainly non-profit oriented
 *    systems for research and education, including but not restricted to
 *    "NetBSD", "FreeBSD", "Mach" (by CMU).
 * 4. Neither the name of the developer(s) nor the name "386BSD"
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPER(S) BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This file contains definitions for some cdrom control commands
 * and status codes. This info was "inherited" from the DOS MTMCDE.SYS
 * driver, and is thus not complete (and may even be wrong). Some day
 * the manufacturer or anyone else might provide better documentation,
 * so this file (and the driver) will then have a better quality.
 */

#if __GNUC__ >= 2
#pragma pack(1)
#endif

typedef unsigned char   bcd_t;
#define M_msf(msf)      msf[0]
#define S_msf(msf)      msf[1]
#define F_msf(msf)      msf[2]

#define MCD_COMMAND     0
#define MCD_STATUS      0
#define MCD_RDATA       0
#define MCD_RESET       1
#define MCD_XFER        1
#define MCD_CTL2        2 /* XXX Is this right? */
#define MCD_CONFIG      3
#define MCD_NPORT       4

#define MCD_MASK_DMA    0x07    /* bits 2-0 = DMA channel */
#define MCD_MASK_IRQ    0x70    /* bits 6-4 = INT number */
                                /* 001 = int 2,9 */
                                /* 010 = int 3 */
                                /* 011 = int 5 */
                                /* 100 = int 10 */
                                /* 101 = int 11 */

/* Status bits */
#define MCD_ST_DOOROPEN         0x80
#define MCD_ST_DSKIN            0x40
#define MCD_ST_DSKCHNG          0x20
#define MCD_ST_SPINNING         0x10
#define MCD_ST_AUDIODISK        0x08    /* audio disk is in */
#define MCD_ST_READERR          0x04
#define MCD_ST_AUDIOBSY         0x02    /* audio disk is playing */
#define MCD_ST_CMDCHECK         0x01    /* command error */

/* Xfer bits */
#define MCD_XF_STATUSUNAVAIL    0x04
#define MCD_XF_DATAUNAVAIL      0x02

/* Modes */
#define MCD_MD_TESTMODE         0x80    /* 0 = DATALENGTH is valid */
#define MCD_MD_DATALENGTH       0x40    /* 1 = read ECC data also */
#define MCD_MD_ECCMODE          0x20    /* 1 = disable secondary ECC */
#define MCD_MD_SPINDOWN         0x08    /* 1 = spin down */
#define MCD_MD_READTOC          0x04    /* 1 = read TOC on GETQCHN */
#define MCD_MD_PLAYAUDIO        0x01    /* 1 = play audio through headphones */

#define MCD_MD_RAW              (MCD_MD_PLAYAUDIO|MCD_MD_ECCMODE|MCD_MD_DATALENGTH)
#define MCD_MD_COOKED           (MCD_MD_PLAYAUDIO)
#define MCD_MD_TOC              (MCD_MD_PLAYAUDIO|MCD_MD_READTOC)
#define MCD_MD_SLEEP            (MCD_MD_PLAYAUDIO|MCD_MD_SPINDOWN)

#define MCD_BLKSIZE_RAW         sizeof(struct mcd_rawsector)
#define MCD_BLKSIZE_COOKED      2048

/* Lock states */
#define MCD_LK_UNLOCK           0x00
#define MCD_LK_LOCK             0x01
#define MCD_LK_TEST             0x02

/* Config commands */
#define MCD_CF_IRQENABLE        0x10
#define MCD_CF_DMATIMEOUT       0x08
#define MCD_CF_READUPC          0x04
#define MCD_CF_DMAENABLE        0x02
#define MCD_CF_BLOCKSIZE        0x01

/* UPC subcommands */
#define MCD_UPC_DISABLE         0x00
#define MCD_UPC_ENABLE          0x01

/* commands known by the controller */
#define MCD_CMDRESET            0x00
#define MCD_CMDGETVOLINFO       0x10    /* gets mcd_volinfo */
#define MCD_CMDGETDISKINFO      0x11    /* gets mcd_disk */
#define MCD_CMDGETQCHN          0x20    /* gets mcd_qchninfo */
#define MCD_CMDGETSENSE         0x30    /* gets sense info */
#define MCD_CMDGETSTAT          0x40    /* gets a byte of status */
#define MCD_CMDSETMODE          0x50    /* set transmission mode, needs byte */
#define MCD_CMDSTOPAUDIO        0x70
#define MCD_CMDSTOPAUDIOTIME    0x80
#define MCD_CMDGETVOLUME        0x8E    /* gets mcd_volume */
#define MCD_CMDCONFIGDRIVE      0x90
#define MCD_CMDSETDRIVEMODE     0xa0    /* set drive mode */
#define MCD_CMDSETVOLUME        0xae    /* sets mcd_volume */
#define MCD_CMDREAD1            0xb0    /* read n sectors */
#define MCD_CMDREADSINGLESPEED  0xc0    /* read (single speed) */
#define MCD_CMDREADDOUBLESPEED  0xc1    /* read (double speed) */
#define MCD_CMDGETDRIVEMODE     0xc2    /* get drive mode */
#define MCD_CMDREAD3            0xc3    /* ? */
#define MCD_CMDSETINTERLEAVE    0xc8    /* set interleave for read */
#define MCD_CMDCONTINFO         0xdc    /* get controller info */
#define MCD_CMDSTOP             0xf0    /* stop everything */
#define MCD_CMDEJECTDISK        0xf6
#define MCD_CMDCLOSETRAY        0xf8
#define MCD_CMDSETLOCK          0xfe    /* needs byte */

union mcd_qchninfo {
        struct {
                u_char  control:4;
                u_char  addr_type:4;
                u_char  trk_no;
                u_char  idx_no;
                bcd_t   track_size[3];
                u_char  :8;
                bcd_t   absolute_pos[3];
        } toc;
        struct {
                u_char  control:4;
                u_char  addr_type:4;
                u_char  trk_no;
                u_char  idx_no;
                bcd_t   relative_pos[3];
                u_char  :8;
                bcd_t   absolute_pos[3];
        } current;
        struct {
                u_char  control:4;
                u_char  addr_type:4;
                u_char  upccode[7];
                u_char  junk[2];
        } upc;
};

struct mcd_volinfo {
        bcd_t   trk_low;
        bcd_t   trk_high;
        bcd_t   vol_msf[3];
        bcd_t   trk1_msf[3];
};

struct mcd_result {
        u_char  length;
        union {
                struct {
                        u_char  data[1];
                } raw;
                struct {
                        u_char  code;
                        u_char  version;
                } continfo;
                union mcd_qchninfo qchninfo;
                struct mcd_volinfo volinfo;
        } data;
};

struct mcd_command {
        u_char  opcode;
        u_char  length;
        union {
                struct {
                        u_char  data[1];
                } raw;
                struct {
                        bcd_t   start_msf[3];
                        bcd_t   reserved[3];
                } seek;
                struct {
                        bcd_t   start_msf[3];
                        bcd_t   length[3];
                } read;
                struct {
                        bcd_t   start_msf[3];
                        bcd_t   end_msf[3];
                } play;
                struct {
                        u_char  mode;
                } datamode;
                struct {
                        u_char  time;
                } hold;
                struct {
                        u_char  mode;
                } drivemode;
                struct {
                        u_char  mode;
                } lockmode;
                struct {
                        u_char  subcommand;
                        u_char  data1, data2;
                } config;
        } data;
};

struct mcd_mbox {
        struct mcd_command cmd;
        struct mcd_result res;
};

struct mcd_volume {
        u_char  v0l;
        u_char  v0rs;
        u_char  v0r;
        u_char  v0ls;
};

struct mcd_rawsector {
        u_char  sync1[12];
        u_char  header[4];
        u_char  subheader1[4];
        u_char  subheader2[4];
        u_char  data[MCD_BLKSIZE_COOKED];
        u_char  ecc_bits[280];
};

#if __GNUC__ >= 2
#pragma pack()
#endif