Remove last vestiges of old wd driver. ata works well on pc98 and

there was no objection on the pc98 list when I asked if it could be
removed a while ago.
This commit is contained in:
Warner Losh 2005-01-04 06:25:24 +00:00
parent 944d0f0ff2
commit c35aafff95
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=139660
8 changed files with 0 additions and 5551 deletions

View File

@ -344,7 +344,6 @@ pc98/apm/apm_bioscall.s optional apm
pc98/i386/busio.s standard
pc98/i386/busiosubr.c standard
pc98/i386/machdep.c standard
pc98/pc98/atapi.c optional wdc
pc98/pc98/canbepm.c optional canbepm
pc98/pc98/canbus.c optional canbus
pc98/pc98/canbus_if.m optional canbus
@ -365,8 +364,6 @@ pc98/pc98/scvtbpc98.c optional sc
pc98/pc98/sio.c optional sio
pc98/pc98/sio_cbus.c optional sio isa
pc98/pc98/syscons_pc98.c optional sc
pc98/pc98/wd.c optional wdc
pc98/pc98/wd_cd.c optional wcd wdc
pccard/pccard.c optional card
pccard/pccard_beep.c optional card
pccard/pccard_nbk.c optional card

View File

@ -1,965 +0,0 @@
/*
* Device-independent level for ATAPI drivers.
*
* Copyright (C) 1995 Cronyx Ltd.
* Author Serge Vakulenko, <vak@cronyx.ru>
*
* This software is distributed with NO WARRANTIES, not even the implied
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Authors grant any other persons or organisations permission to use
* or modify this software as long as this message is kept with the software,
* all derivative works or modified versions.
*
* Version 1.9, Mon Oct 9 22:34:47 MSK 1995
*
* $FreeBSD$
*/
/*
* The ATAPI level is implemented as a machine-dependent layer
* between the device driver and the IDE controller.
* All the machine- and controller dependency is isolated inside
* the ATAPI level, while all the device dependency is located
* in the device subdriver.
*
* It seems that an ATAPI bus will became popular for medium-speed
* storage devices such as CD-ROMs, magneto-optical disks, tape streamers etc.
*
* To ease the development of new ATAPI drivers, the subdriver
* interface was designed to be as simple as possible.
*
* Three routines are available for the subdriver to access the device:
*
* struct atapires atapi_request_wait (ata, unit, cmd, a1, a2, a3, a4, a5,
* a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, addr, count);
* struct atapi *ata; -- atapi controller descriptor
* int unit; -- device unit number on the IDE bus
* u_char cmd; -- ATAPI command code
* u_char a1..a15; -- ATAPI command arguments
* char *addr; -- address of the data buffer for i/o
* int count; -- data length, >0 for read ops, <0 for write ops
*
* The atapi_request_wait() function puts the op in the queue of ATAPI
* commands for the IDE controller, starts the controller, the waits for
* operation to be completed (using tsleep).
* The function should be called from the user phase only (open(), close(),
* ioctl() etc).
* Ata and unit args are the values which the subdriver gets from the ATAPI
* level via attach() call.
* Buffer pointed to by *addr should be placed in core memory, static
* or dynamic, but not in stack.
* The function returns the error code structure, which consists of:
* - atapi driver code value
* - controller status port value
* - controller error port value
*
* struct atapires atapi_request_immediate (ata, unit, cmd, a1, a2, a3,
* a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
* addr, count);
*
* The atapi_request_immediate() function is similar to atapi_request_wait(),
* but it does not use interrupts for performing the request.
* It should be used during an attach phase to get parameters from the device.
*
* void atapi_request_callback (ata, unit, cmd, a1, a2, a3, a4, a5,
* a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
* addr, count, done, x, y);
* struct atapi *ata; -- atapi controller descriptor
* int unit; -- device unit number on the IDE bus
* u_char cmd; -- ATAPI command code
* u_char a1..a15; -- ATAPI command arguments
* char *addr; -- address of the data buffer for i/o
* int count; -- data length, >0 for read ops, <0 for write ops
* void (*done)(); -- function to call when op finished
* void *x, *y; -- arguments for done() function
*
* The atapi_request_callback() function puts the op in the queue of ATAPI
* commands for the IDE controller, starts the controller, then returns.
* When the operation finishes, then the callback function done()
* will be called on the interrupt level.
* The function is designed to be callable from the interrupt phase.
* The done() functions is called with the following arguments:
* (void) (*done) (x, y, count, errcode)
* void *x, *y; -- arguments from the atapi_request_callback()
* int count; -- the data residual count
* struct atapires errcode; -- error code structure, see above
*
* The new driver could be added in three steps:
* 1. Add entries for the new driver to bdevsw and cdevsw tables in conf.c.
* You will need to make at least three routines: open(), close(),
* strategy() and possibly ioctl().
* 2. Make attach() routine, which should allocate all the needed data
* structures and print the device description string (see xxxattach()).
* 3. Add an appropriate case to the switch in atapi_attach() routine,
* call attach() routine of the new driver here. Add the appropriate
* #include line at the top of attach.c.
* That's all!
*
* Use #define DEBUG in atapi.c to enable tracing of all i/o operations
* on the IDE bus.
*/
#undef DEBUG
#include "opt_wcd.h"
#include "opt_wdc.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <pc98/pc98/atapi.h>
/* this code is compiled part of the module */
#ifdef DEBUG
# define print(s) printf s
#else
# define print(s) {/*void*/}
#endif
/*
* ATAPI packet command phase.
*/
#define PHASE_CMDOUT (ARS_DRQ | ARI_CMD)
#define PHASE_DATAIN (ARS_DRQ | ARI_IN)
#define PHASE_DATAOUT ARS_DRQ
#define PHASE_COMPLETED (ARI_IN | ARI_CMD)
#define PHASE_ABORTED 0 /* nonstandard - for NEC 260 */
static struct atapi atapitab[NWDC];
static struct atapi_params *atapi_probe (int port, int unit);
static int atapi_wait (int port, u_char bits_wanted);
static void atapi_send_cmd (struct atapi *ata, struct atapicmd *ac);
static int atapi_io (struct atapi *ata, struct atapicmd *ac);
static int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac);
static int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac);
extern void wdstart (int ctrlr);
extern int acdattach(struct atapi*, int, struct atapi_params*, int);
extern int wfdattach(struct atapi*, int, struct atapi_params*, int);
extern int wstattach(struct atapi*, int, struct atapi_params*, int);
/*
* Probe the ATAPI device at IDE controller `ctlr', drive `unit'.
* Called at splbio().
*/
int atapi_attach (int ctlr, int unit, int port)
{
struct atapi *ata = atapitab + ctlr;
struct atapi_params *ap;
char buf [sizeof(ap->model) + 1];
char revbuf [sizeof(ap->revision) + 1];
struct atapicmd *ac;
print (("atapi%d.%d at 0x%x: attach called\n", ctlr, unit, port));
ap = atapi_probe (port, unit);
if (! ap)
return (0);
bcopy (ap->model, buf, sizeof(buf)-1);
buf[sizeof(buf)-1] = 0;
bcopy (ap->revision, revbuf, sizeof(revbuf)-1);
revbuf[sizeof(revbuf)-1] = 0;
printf ("wdc%d: unit %d (atapi): <%s/%s>", ctlr, unit, buf, revbuf);
/* device is removable */
if (ap->removable)
printf (", removable");
/* packet command size */
switch (ap->cmdsz) {
case AT_PSIZE_12: break;
case AT_PSIZE_16: printf (", cmd16"); ata->cmd16 = 1; break;
default: printf (", cmd%d", ap->cmdsz);
}
/* DRQ type */
switch (ap->drqtype) {
case AT_DRQT_MPROC: ata->slow = 1; break;
case AT_DRQT_INTR: printf (", intr"); ata->intrcmd = 1; break;
case AT_DRQT_ACCEL: printf (", accel"); ata->accel = 1; break;
default: printf (", drq%d", ap->drqtype);
}
if (ata->slow)
ata->intrcmd = 0;
/*
* If we have two devices, one supporting INTR and one ACCEL, we
* have to pessimise - clear INTR and set slow.
*/
if (ata->accel && ata->intrcmd) {
ata->intrcmd = 0;
ata->slow = 1;
}
/* overlap operation supported */
if (ap->ovlapflag)
printf (", ovlap");
/* interleaved DMA supported */
if (ap->idmaflag)
printf (", idma");
/* DMA supported */
else if (ap->dmaflag)
printf (", dma");
/* IORDY can be disabled */
if (ap->iordydis)
printf (", iordis");
/* IORDY supported */
else if (ap->iordyflag)
printf (", iordy");
printf ("\n");
ata->port = port;
ata->ctrlr = ctlr;
ata->attached[unit] = 0;
#ifdef DEBUG
ata->debug = 1;
#else
ata->debug = 0;
#endif
/* Initialize free queue. */
ata->cmdrq[15].next = 0;
for (ac = ata->cmdrq+14; ac >= ata->cmdrq; --ac)
ac->next = ac+1;
ata->free = ata->cmdrq;
if (ap->proto != AT_PROTO_ATAPI) {
printf ("wdc%d: unit %d: unknown ATAPI protocol=%d\n",
ctlr, unit, ap->proto);
free (ap, M_TEMP);
return (0);
}
switch (ap->devtype) {
default:
/* unknown ATAPI device */
printf ("wdc%d: unit %d: unknown ATAPI type=%d\n",
ctlr, unit, ap->devtype);
break;
case AT_TYPE_DIRECT: /* direct-access */
#ifdef DEV_WCD
/* FALLTHROUGH */
#else
printf ("wdc%d: ATAPI Floppies not configured\n", ctlr);
break;
#endif
case AT_TYPE_CDROM: /* CD-ROM device */
#ifdef DEV_WCD
/* ATAPI CD-ROM & CD-R/RW drives */
if (acdattach (ata, unit, ap, ata->debug) < 0)
break;
ata->attached[unit] = 1;
return (1);
#else
printf ("wdc%d: ATAPI CD-ROMs not configured\n", ctlr);
break;
#endif
case AT_TYPE_TAPE: /* streaming tape */
printf ("wdc%d: ATAPI streaming tapes not configured\n", ctlr);
break;
case AT_TYPE_OPTICAL: /* optical disk */
#if NWMD > 0
/* Add your driver here */
#else
printf ("wdc%d: ATAPI optical disks not supported yet\n", ctlr);
#endif
break;
}
/* Attach failed. */
free (ap, M_TEMP);
return (0);
}
static char *cmdname (u_char cmd)
{
static char buf[8];
switch (cmd) {
case 0x00: return ("TEST_UNIT_READY");
case 0x01: return ("REZERO_UNIT");
case 0x03: return ("REQUEST_SENSE");
case 0x04: return ("FORMAT_UNIT");
case 0x1b: return ("START_STOP");
case 0x1e: return ("PREVENT_ALLOW");
case 0x25: return ("READ_CAPACITY");
case 0x28: return ("READ_BIG");
case 0x2a: return ("WRITE_BIG");
case 0x35: return ("SYNCHRONIZE_CACHE");
case 0x42: return ("READ_SUBCHANNEL");
case 0x43: return ("READ_TOC");
case 0x51: return ("READ_DISC_INFO");
case 0x52: return ("READ_TRACK_INFO");
case 0x53: return ("RESERVE_TRACK");
case 0x54: return ("SEND_OPC_INFO");
case 0x55: return ("MODE_SELECT");
case 0x58: return ("REPAIR_TRACK");
case 0x59: return ("READ_MASTER_CUE");
case 0x5a: return ("MODE_SENSE");
case 0x5b: return ("CLOSE_TRACK/SESSION");
case 0x5c: return ("READ_BUFFER_CAPACITY");
case 0x5d: return ("SEND_CUE_SHEET");
case 0x47: return ("PLAY_MSF");
case 0x4b: return ("PAUSE");
case 0x48: return ("PLAY_TRACK");
case 0xa1: return ("BLANK_CMD");
case 0xa5: return ("PLAY_BIG");
case 0xb4: return ("PLAY_CD");
case 0xbd: return ("ATAPI_MECH_STATUS");
case 0xbe: return ("READ_CD");
}
snprintf (buf, sizeof(buf), "[0x%x]", cmd);
return (buf);
}
static void bswap (char *buf, int len)
{
u_short *p = (u_short*) (buf + len);
while (--p >= (u_short*) buf)
*p = ntohs (*p);
}
static void btrim (char *buf, int len)
{
char *p;
/* Remove the trailing spaces. */
for (p=buf; p<buf+len; ++p)
if (! *p)
*p = ' ';
for (p=buf+len-1; p>=buf && *p==' '; --p)
*p = 0;
}
/*
* Issue IDENTIFY command to ATAPI drive to ask it what it is.
*/
static struct atapi_params *atapi_probe (int port, int unit)
{
struct atapi_params *ap;
char tb [DEV_BSIZE];
#ifdef PC98
int cnt;
outb(0x432,unit%2);
print(("unit = %d,select %d\n",unit,unit%2));
#endif
/* Wait for controller not busy. */
#ifdef PC98
outb (port + AR_DRIVE, unit / 2 ? ARD_DRIVE1 : ARD_DRIVE0);
#else
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
#endif
if (atapi_wait (port, 0) < 0) {
print (("atapiX.%d at 0x%x: controller busy, status=%b\n",
unit, port, inb (port + AR_STATUS), ARS_BITS));
return (0);
}
/* Issue ATAPI IDENTIFY command. */
#ifdef PC98
outb (port + AR_DRIVE, unit/2 ? ARD_DRIVE1 : ARD_DRIVE0);
/* Wait for DRQ deassert. */
for (cnt=2000; cnt>0; --cnt)
if (! (inb (port + AR_STATUS) & ARS_DRQ))
break;
outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
DELAY(500);
#else
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
#endif
/* Check that device is present. */
if (inb (port + AR_STATUS) == 0xff) {
print (("atapiX.%d at 0x%x: no device\n", unit, port));
#ifdef PC98
if (unit / 2)
#else
if (unit == 1)
#endif
/* Select unit 0. */
outb (port + AR_DRIVE, ARD_DRIVE0);
return (0);
}
/* Wait for data ready. */
if (atapi_wait (port, ARS_DRQ) != 0) {
print (("atapiX.%d at 0x%x: identify not ready, status=%b\n",
unit, port, inb (port + AR_STATUS), ARS_BITS));
#ifdef PC98
if (unit / 2)
#else
if (unit == 1)
#endif
/* Select unit 0. */
outb (port + AR_DRIVE, ARD_DRIVE0);
return (0);
}
/* check that DRQ isn't a fake */
if (inb (port + AR_STATUS) == 0xff) {
print (("atapiX.%d at 0x%x: no device\n", unit, port));
#ifdef PC98
if (unit / 2)
#else
if (unit == 1)
#endif
/* Select unit 0. */
outb (port + AR_DRIVE, ARD_DRIVE0);
return (0);
}
/* Obtain parameters. */
insw (port + AR_DATA, tb, sizeof(tb) / sizeof(short));
ap = malloc (sizeof *ap, M_TEMP, M_NOWAIT);
if (! ap)
return (0);
bcopy (tb, ap, sizeof *ap);
#ifdef PC98
/*
* Check model string.
* If all of it makes unprintable characters, ignore this device.
*/
for (cnt = 0; cnt < sizeof(ap->model)-1; cnt++) {
if (ap->model[cnt] >= ' ')
break;
}
if (cnt >= sizeof(ap->model)-1) {
free (ap, M_TEMP);
return (0);
}
#endif
/*
* Shuffle string byte order.
* Mitsumi and NEC drives don't need this.
*/
if (! ((ap->model[0] == 'N' && ap->model[1] == 'E') ||
(ap->model[0] == 'F' && ap->model[1] == 'X')))
bswap (ap->model, sizeof(ap->model));
bswap (ap->serial, sizeof(ap->serial));
bswap (ap->revision, sizeof(ap->revision));
/* Clean up the model name, serial and revision numbers. */
btrim (ap->model, sizeof(ap->model));
btrim (ap->serial, sizeof(ap->serial));
btrim (ap->revision, sizeof(ap->revision));
return (ap);
}
/*
* Wait uninterruptibly until controller is not busy and certain
* status bits are set.
* The wait is usually short unless it is for the controller to process
* an entire critical command.
* Return 1 for (possibly stale) controller errors, -1 for timeout errors,
* or 0 for no errors.
*/
static int atapi_wait (int port, u_char bits_wanted)
{
int cnt;
u_char s;
/* Wait 5 sec for BUSY deassert. */
for (cnt=500000; cnt>0; --cnt) {
s = inb (port + AR_STATUS);
if (! (s & ARS_BSY))
break;
DELAY (10);
}
if (cnt <= 0)
return (-1);
if (! bits_wanted)
return (s & ARS_CHECK);
/* Wait 50 msec for bits wanted. */
for (cnt=5000; cnt>0; --cnt) {
s = inb (port + AR_STATUS);
if ((s & bits_wanted) == bits_wanted)
return (s & ARS_CHECK);
DELAY (10);
}
return (-1);
}
void atapi_debug (struct atapi *ata, int on)
{
ata->debug = on;
}
static struct atapicmd *atapi_alloc (struct atapi *ata)
{
struct atapicmd *ac;
while (! ata->free)
tsleep (ata, PRIBIO, "atacmd", 100);
ac = ata->free;
ata->free = ac->next;
ac->busy = 1;
return (ac);
}
static void atapi_free (struct atapi *ata, struct atapicmd *ac)
{
if (! ata->free)
wakeup (ata);
ac->busy = 0;
ac->next = ata->free;
ata->free = ac;
}
/*
* Add new command request to the end of the queue.
*/
static void atapi_enqueue (struct atapi *ata, struct atapicmd *ac)
{
ac->next = 0;
if (ata->tail)
ata->tail->next = ac;
else
ata->queue = ac;
ata->tail = ac;
}
static void atapi_done (struct atapi *ata)
{
struct atapicmd *ac = ata->queue;
if (! ac)
return; /* cannot happen */
ata->queue = ac->next;
if (! ata->queue)
ata->tail = 0;
if (ac->callback) {
(*ac->callback) (ac->cbarg1, ac->cbarg2, ac->count, ac->result);
atapi_free (ata, ac);
} else
wakeup (ac);
}
/*
* Start new packet op. Called from wdstart().
* Return 1 if op started, and we are waiting for interrupt.
* Return 0 when idle.
*/
int atapi_start (int ctrlr)
{
struct atapi *ata = atapitab + ctrlr;
struct atapicmd *ac;
again:
ac = ata->queue;
if (! ac)
return (0);
/* Start packet command. */
if (atapi_start_cmd (ata, ac) < 0) {
atapi_done (ata);
goto again;
}
if (ata->intrcmd)
/* Wait for interrupt before sending packet command */
return (1);
/* Wait for DRQ. */
if (atapi_wait_cmd (ata, ac) < 0) {
atapi_done (ata);
goto again;
}
/* Send packet command. */
atapi_send_cmd (ata, ac);
return (1);
}
/*
* Start new packet op. Returns -1 on errors.
*/
int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac)
{
ac->result.error = 0;
ac->result.status = 0;
#ifdef PC98
outb(0x432,(ac->unit)%2);
print(("(ac->unit) = %d,select %d (2) \n",(ac->unit),(ac->unit)%2));
outb (ata->port + AR_DRIVE, (ac->unit)/2 ? ARD_DRIVE1 : ARD_DRIVE0);
#else
outb (ata->port + AR_DRIVE, ac->unit ? ARD_DRIVE1 : ARD_DRIVE0);
#endif
if (atapi_wait (ata->port, 0) < 0) {
printf ("atapi%d.%d: controller not ready for cmd\n",
ata->ctrlr, ac->unit);
ac->result.code = RES_NOTRDY;
return (-1);
}
/* Set up the controller registers. */
outb (ata->port + AR_FEATURES, 0);
outb (ata->port + AR_IREASON, 0);
outb (ata->port + AR_TAG, 0);
outb (ata->port + AR_CNTLO, ac->count & 0xff);
outb (ata->port + AR_CNTHI, ac->count >> 8);
outb (ata->port + AR_COMMAND, ATAPIC_PACKET);
if (ata->debug)
printf ("atapi%d.%d: start\n", ata->ctrlr, ac->unit);
return (0);
}
/*
* Wait for DRQ before sending packet cmd. Returns -1 on errors.
*/
int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
{
/* Wait for DRQ from 100 usec to 3 msec for slow devices */
int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000 : 100;
int ireason = 0, phase = 0;
/* Wait for command phase. */
for (; cnt>0; cnt-=10) {
ireason = inb (ata->port + AR_IREASON);
ac->result.status = inb (ata->port + AR_STATUS);
phase = (ireason & (ARI_CMD | ARI_IN)) |
(ac->result.status & (ARS_DRQ | ARS_BSY));
if (phase == PHASE_CMDOUT)
break;
DELAY (10);
}
if (phase != PHASE_CMDOUT) {
ac->result.code = RES_NODRQ;
ac->result.error = inb (ata->port + AR_ERROR);
printf ("atapi%d.%d: invalid command phase, ireason=0x%x, status=%b, error=%b\n",
ata->ctrlr, ac->unit, ireason,
ac->result.status, ARS_BITS,
ac->result.error, AER_BITS);
return (-1);
}
return (0);
}
/*
* Send packet cmd.
*/
void atapi_send_cmd (struct atapi *ata, struct atapicmd *ac)
{
outsw (ata->port + AR_DATA, ac->cmd, ata->cmd16 ? 8 : 6);
if (ata->debug)
printf ("atapi%d.%d: send cmd %s %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x\n",
ata->ctrlr, ac->unit, cmdname (ac->cmd[0]), ac->cmd[0],
ac->cmd[1], ac->cmd[2], ac->cmd[3], ac->cmd[4],
ac->cmd[5], ac->cmd[6], ac->cmd[7], ac->cmd[8],
ac->cmd[9], ac->cmd[10], ac->cmd[11], ac->cmd[12],
ac->cmd[13], ac->cmd[14], ac->cmd[15]);
}
/*
* Interrupt routine for the controller. Called from wdintr().
* Finish the started op, wakeup wait-type commands,
* run callbacks for callback-type commands, then return.
* Do not start new op here, it will be done by wdstart,
* which is called just after us.
* Return 1 if op continues, and we are waiting for new interrupt.
* Return 0 when idle.
*/
int atapi_intr (int ctrlr)
{
struct atapi *ata = atapitab + ctrlr;
struct atapicmd *ac = ata->queue;
#ifdef PC98
outb(0x432,(ac->unit)%2);
print(("atapi_intr:(ac->unit)= %d,select %d\n",ac->unit,(ac->unit)%2));
#endif
if (! ac) {
printf ("atapi%d: stray interrupt\n", ata->ctrlr);
return (0);
}
if (atapi_io (ata, ac) > 0)
return (1);
atapi_done (ata);
return (0);
}
/*
* Process the i/o phase, transferring the command/data to/from the device.
* Return 1 if op continues, and we are waiting for new interrupt.
* Return 0 when idle.
*/
int atapi_io (struct atapi *ata, struct atapicmd *ac)
{
u_char ireason;
u_short len, i;
if (atapi_wait (ata->port, 0) < 0) {
ac->result.status = inb (ata->port + AR_STATUS);
ac->result.error = inb (ata->port + AR_ERROR);
ac->result.code = RES_NOTRDY;
printf ("atapi%d.%d: controller not ready, status=%b, error=%b\n",
ata->ctrlr, ac->unit, ac->result.status, ARS_BITS,
ac->result.error, AER_BITS);
return (0);
}
ac->result.status = inb (ata->port + AR_STATUS);
ac->result.error = inb (ata->port + AR_ERROR);
len = inb (ata->port + AR_CNTLO);
len |= inb (ata->port + AR_CNTHI) << 8;
ireason = inb (ata->port + AR_IREASON);
if (ata->debug) {
printf ("atapi%d.%d: intr ireason=0x%x, len=%d, status=%b, error=%b\n",
ata->ctrlr, ac->unit, ireason, len,
ac->result.status, ARS_BITS,
ac->result.error, AER_BITS);
}
switch ((ireason & (ARI_CMD | ARI_IN)) | (ac->result.status & ARS_DRQ)) {
default:
printf ("atapi%d.%d: unknown phase\n", ata->ctrlr, ac->unit);
ac->result.code = RES_ERR;
break;
case PHASE_CMDOUT:
/* Send packet command. */
if (! (ac->result.status & ARS_DRQ)) {
printf ("atapi%d.%d: no cmd drq\n",
ata->ctrlr, ac->unit);
ac->result.code = RES_NODRQ;
break;
}
atapi_send_cmd (ata, ac);
return (1);
case PHASE_DATAOUT:
/* Write data */
if (ac->count > 0) {
printf ("atapi%d.%d: invalid data direction\n",
ata->ctrlr, ac->unit);
ac->result.code = RES_INVDIR;
break;
}
if (-ac->count < len) {
print (("atapi%d.%d: send data underrun, %d bytes left\n",
ata->ctrlr, ac->unit, -ac->count));
ac->result.code = RES_UNDERRUN;
outsw (ata->port + AR_DATA, ac->addr,
-ac->count / sizeof(short));
for (i= -ac->count; i<len; i+=sizeof(short))
outw (ata->port + AR_DATA, 0);
} else
outsw (ata->port + AR_DATA, ac->addr,
len / sizeof(short));
ac->addr += len;
ac->count += len;
return (1);
case PHASE_DATAIN:
/* Read data */
if (ac->count < 0) {
printf ("atapi%d.%d: invalid data direction\n",
ata->ctrlr, ac->unit);
ac->result.code = RES_INVDIR;
break;
}
if (ac->count < len) {
print (("atapi%d.%d: recv data overrun, %d bytes left\n",
ata->ctrlr, ac->unit, ac->count));
ac->result.code = RES_OVERRUN;
insw (ata->port + AR_DATA, ac->addr,
ac->count / sizeof(short));
for (i=ac->count; i<len; i+=sizeof(short))
inw (ata->port + AR_DATA);
} else
insw (ata->port + AR_DATA, ac->addr,
len / sizeof(short));
ac->addr += len;
ac->count -= len;
return (1);
case PHASE_ABORTED:
case PHASE_COMPLETED:
if (ac->result.status & (ARS_CHECK | ARS_DF))
ac->result.code = RES_ERR;
else if (ac->count < 0) {
print (("atapi%d.%d: send data overrun, %d bytes left\n",
ata->ctrlr, ac->unit, -ac->count));
ac->result.code = RES_OVERRUN;
} else if (ac->count > 0) {
print (("atapi%d.%d: recv data underrun, %d bytes left\n",
ata->ctrlr, ac->unit, ac->count));
ac->result.code = RES_UNDERRUN;
bzero (ac->addr, ac->count);
} else
ac->result.code = RES_OK;
break;
}
return (0);
}
/*
* Queue new packet request, then call wdstart().
* Called on splbio().
*/
void atapi_request_callback (struct atapi *ata, int unit,
u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
char *addr, int count, atapi_callback_t *done, void *x, void *y)
{
struct atapicmd *ac;
ac = atapi_alloc (ata);
ac->cmd[0] = cmd; ac->cmd[1] = a1;
ac->cmd[2] = a2; ac->cmd[3] = a3;
ac->cmd[4] = a4; ac->cmd[5] = a5;
ac->cmd[6] = a6; ac->cmd[7] = a7;
ac->cmd[8] = a8; ac->cmd[9] = a9;
ac->cmd[10] = a10; ac->cmd[11] = a11;
ac->cmd[12] = a12; ac->cmd[13] = a13;
ac->cmd[14] = a14; ac->cmd[15] = a15;
ac->unit = unit;
ac->addr = addr;
ac->count = count;
ac->callback = done;
ac->cbarg1 = x;
ac->cbarg2 = y;
if (ata->debug)
printf ("atapi%d.%d: req cb %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
ac->cmd[10], ac->cmd[11], ac->cmd[12],
ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
atapi_enqueue (ata, ac);
wdstart (ata->ctrlr);
}
/*
* Queue new packet request, then call wdstart().
* Wait until the request is finished.
* Called on spl0().
* Return atapi error.
* Buffer pointed to by *addr should be placed in core memory, not in stack!
*/
struct atapires atapi_request_wait (struct atapi *ata, int unit,
u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
char *addr, int count)
{
struct atapicmd *ac;
int x = splbio ();
struct atapires result;
ac = atapi_alloc (ata);
ac->cmd[0] = cmd; ac->cmd[1] = a1;
ac->cmd[2] = a2; ac->cmd[3] = a3;
ac->cmd[4] = a4; ac->cmd[5] = a5;
ac->cmd[6] = a6; ac->cmd[7] = a7;
ac->cmd[8] = a8; ac->cmd[9] = a9;
ac->cmd[10] = a10; ac->cmd[11] = a11;
ac->cmd[12] = a12; ac->cmd[13] = a13;
ac->cmd[14] = a14; ac->cmd[15] = a15;
ac->unit = unit;
ac->addr = addr;
ac->count = count;
ac->callback = 0;
ac->cbarg1 = 0;
ac->cbarg2 = 0;
if (ata->debug)
printf ("atapi%d.%d: req w %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
ac->cmd[10], ac->cmd[11], ac->cmd[12],
ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
atapi_enqueue (ata, ac);
wdstart (ata->ctrlr);
if (ata->tail == ac)
tsleep (ac, PRIBIO, "atareq", 0);
result = ac->result;
atapi_free (ata, ac);
splx (x);
return (result);
}
/*
* Perform a packet command on the device.
* Should be called on splbio().
* Return atapi error.
*/
struct atapires atapi_request_immediate (struct atapi *ata, int unit,
u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
char *addr, int count)
{
struct atapicmd cmdbuf, *ac = &cmdbuf;
int cnt;
ac->cmd[0] = cmd; ac->cmd[1] = a1;
ac->cmd[2] = a2; ac->cmd[3] = a3;
ac->cmd[4] = a4; ac->cmd[5] = a5;
ac->cmd[6] = a6; ac->cmd[7] = a7;
ac->cmd[8] = a8; ac->cmd[9] = a9;
ac->cmd[10] = a10; ac->cmd[11] = a11;
ac->cmd[12] = a12; ac->cmd[13] = a13;
ac->cmd[14] = a14; ac->cmd[15] = a15;
ac->unit = unit;
ac->addr = addr;
ac->count = count;
ac->callback = 0;
ac->cbarg1 = 0;
ac->cbarg2 = 0;
if (ata->debug)
printf ("atapi%d.%d: req im %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
ac->cmd[10], ac->cmd[11], ac->cmd[12],
ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
/* Start packet command, wait for DRQ. */
if (atapi_start_cmd (ata, ac) >= 0 && atapi_wait_cmd (ata, ac) >= 0) {
/* Send packet command. */
atapi_send_cmd (ata, ac);
/* Wait for data i/o phase. */
for (cnt=20000; cnt>0; --cnt)
if (((inb (ata->port + AR_IREASON) & (ARI_CMD | ARI_IN)) |
(inb (ata->port + AR_STATUS) & ARS_DRQ)) != PHASE_CMDOUT)
break;
/* Do all needed i/o. */
while (atapi_io (ata, ac))
/* Wait for DRQ deassert. */
for (cnt=2000; cnt>0; --cnt) {
if (! (inb (ata->port + AR_STATUS) & ARS_DRQ))
break;
DELAY(10);
}
}
return (ac->result);
}

View File

@ -1,294 +0,0 @@
/*
* Device-independent level for ATAPI drivers.
*
* Copyright (C) 1995 Cronyx Ltd.
* Author Serge Vakulenko, <vak@cronyx.ru>
*
* This software is distributed with NO WARRANTIES, not even the implied
* warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Authors grant any other persons or organizations permission to use
* or modify this software as long as this message is kept with the software,
* all derivative works or modified versions.
*
* Version 1.9, Thu Oct 12 15:53:50 MSK 1995
* $FreeBSD$
*/
#define atapi_attach wdc_atapi_attach
#define acdattach wdc_acdattach
/*
* Disk Controller ATAPI register definitions.
*/
#ifdef PC98
#define AR_DATA 0x0 /* RW - data register (16 bits) */
#define AR_ERROR 0x2 /* R - error register */
#define AR_FEATURES 0x2 /* W - features */
#define AR_IREASON 0x4 /* RW - interrupt reason */
#define AR_TAG 0x6 /* - reserved for SAM TAG byte */
#define AR_CNTLO 0x8 /* RW - byte count, low byte */
#define AR_CNTHI 0xa /* RW - byte count, high byte */
#define AR_DRIVE 0xc /* RW - drive select */
#define AR_COMMAND 0xe /* W - command register */
#define AR_STATUS 0xe /* R - immediate status */
#else
#define AR_DATA 0x0 /* RW - data register (16 bits) */
#define AR_ERROR 0x1 /* R - error register */
#define AR_FEATURES 0x1 /* W - features */
#define AR_IREASON 0x2 /* RW - interrupt reason */
#define AR_TAG 0x3 /* - reserved for SAM TAG byte */
#define AR_CNTLO 0x4 /* RW - byte count, low byte */
#define AR_CNTHI 0x5 /* RW - byte count, high byte */
#define AR_DRIVE 0x6 /* RW - drive select */
#define AR_COMMAND 0x7 /* W - command register */
#define AR_STATUS 0x7 /* R - immediate status */
#endif
/*
* Status register bits
*/
#define ARS_CHECK 0x01 /* error occured, see sense key/code */
/* bit 0x02 reserved */
#define ARS_CORR 0x04 /* correctable error occured */
#define ARS_DRQ 0x08 /* data request / ireason valid */
#define ARS_DSC 0x10 /* immediate operation completed */
#define ARS_DF 0x20 /* drive fault */
#define ARS_DRDY 0x40 /* ready to get command */
#define ARS_BSY 0x80 /* registers busy */
/* for overlap mode only: */
#define ARS_SERVICE 0x10 /* service is requested */
#define ARS_DMARDY 0x20 /* ready to start a DMA transfer */
#define ARS_BITS "\20\010busy\7ready\6fault\5opdone\4drq\3corr\1check"
/*
* Error register bits
*/
#define AER_ILI 0x01 /* illegal length indication */
#define AER_EOM 0x02 /* end of media detected */
#define AER_ABRT 0x04 /* command aborted */
#define AER_MCR 0x08 /* media change requested */
#define AER_SKEY 0xf0 /* sense key mask */
#define AER_SK_NO_SENSE 0x00 /* no specific sense key info */
#define AER_SK_RECOVERED_ERROR 0x10 /* command succeeded, data recovered */
#define AER_SK_NOT_READY 0x20 /* no access to drive */
#define AER_SK_MEDIUM_ERROR 0x30 /* non-recovered data error */
#define AER_SK_HARDWARE_ERROR 0x40 /* non-recoverable hardware failure */
#define AER_SK_ILLEGAL_REQUEST 0x50 /* invalid command parameter(s) */
#define AER_SK_UNIT_ATTENTION 0x60 /* media changed */
#define AER_SK_DATA_PROTECT 0x70 /* reading read-protected sector */
#define AER_SK_BLANK_CHECK 0x80 /* blank check */
#define AER_SK_VENDOR_SPECIFIC 0x90 /* vendor specific skey */
#define AER_SK_COPY_ABORTED 0xa0 /* copy aborted */
#define AER_SK_ABORTED_COMMAND 0xb0 /* command aborted, try again */
#define AER_SK_EQUAL 0xc0 /* equal */
#define AER_SK_VOLUME_OVERFLOW 0xd0 /* volume overflow */
#define AER_SK_MISCOMPARE 0xe0 /* data did not match the medium */
#define AER_SK_RESERVED 0xf0
#define AER_BITS "\20\4mchg\3abort\2eom\1ili"
/*
* Feature register bits
*/
#define ARF_DMA 0x01 /* transfer data via DMA */
#define ARF_OVERLAP 0x02 /* release the bus until completion */
/*
* Interrupt reason register bits
*/
#define ARI_CMD 0x01 /* command(1) or data(0) */
#define ARI_IN 0x02 /* transfer to(1) or from(0) the host */
#define ARI_RELEASE 0x04 /* bus released until completion */
/*
* Drive register values
*/
#define ARD_DRIVE0 0xa0 /* drive 0 selected */
#define ARD_DRIVE1 0xb0 /* drive 1 selected */
/*
* ATA commands
*/
#define ATAPIC_IDENTIFY 0xa1 /* get drive parameters */
#define ATAPIC_PACKET 0xa0 /* execute packet command */
/*
* Mandatory packet commands
*/
#define ATAPI_TEST_UNIT_READY 0x00 /* check if the device is ready */
#define ATAPI_REZERO_UNIT 0x01 /* reinit device */
#define ATAPI_REQUEST_SENSE 0x03 /* get sense data */
#define ATAPI_START_STOP 0x1b /* start/stop the media */
#define ATAPI_PREVENT_ALLOW 0x1e /* prevent/allow media removal */
#define ATAPI_READ_CAPACITY 0x25 /* get volume capacity */
#define ATAPI_READ_BIG 0x28 /* read data */
#define ATAPI_WRITE_BIG 0x2a /* write data */
#define ATAPI_SYNCHRONIZE_CACHE 0x35 /* flush write buf, close write chan */
#define ATAPI_READ_SUBCHANNEL 0x42 /* get subchannel info */
#define ATAPI_READ_TOC 0x43 /* get table of contents */
#define ATAPI_READ_TRACK_INFO 0x52 /* get track information structure */
#define ATAPI_MODE_SELECT 0x55 /* set device parameters */
#define ATAPI_MODE_SENSE 0x5a /* get device parameters */
#define ATAPI_CLOSE_TRACK 0x5b /* close track/session */
#define ATAPI_LOAD_UNLOAD 0xa6 /* changer control command */
#define ATAPI_PLAY_CD 0xb4 /* universal play command */
#define ATAPI_MECH_STATUS 0xbd /* get changer mechanism status */
#define ATAPI_READ_CD 0xbe /* read data */
/*
* Optional packet commands
*/
#define ATAPI_PLAY_MSF 0x47 /* play by MSF address */
#define ATAPI_PAUSE 0x4b /* stop/start audio operation */
/*
* Nonstandard packet commands
*/
#define ATAPI_PLAY_TRACK 0x48 /* play by track number */
#define ATAPI_PLAY_BIG 0xa5 /* play by logical block address */
#define DSC_POLL_INTERVAL 10
/*
* Drive parameter information
*/
struct atapi_params {
unsigned cmdsz : 2; /* packet command size */
#define AT_PSIZE_12 0 /* 12 bytes */
#define AT_PSIZE_16 1 /* 16 bytes */
unsigned : 3;
unsigned drqtype : 2; /* DRQ type */
#define AT_DRQT_MPROC 0 /* microprocessor DRQ - 3 msec delay */
#define AT_DRQT_INTR 1 /* interrupt DRQ - 10 msec delay */
#define AT_DRQT_ACCEL 2 /* accelerated DRQ - 50 usec delay */
unsigned removable : 1; /* device is removable */
unsigned devtype : 5; /* device type */
#define AT_TYPE_DIRECT 0 /* direct-access (magnetic disk) */
#define AT_TYPE_TAPE 1 /* streaming tape (QIC-121 model) */
#define AT_TYPE_CDROM 5 /* CD-ROM device */
#define AT_TYPE_OPTICAL 7 /* optical disk */
unsigned : 1;
unsigned proto : 2; /* command protocol */
#define AT_PROTO_ATAPI 2
short reserved1[9];
char serial[20]; /* serial number - optional */
short reserved2[3];
char revision[8]; /* firmware revision */
char model[40]; /* model name */
short reserved3[2];
u_char vendor_cap; /* vendor unique capabilities */
unsigned dmaflag : 1; /* DMA supported */
unsigned lbaflag : 1; /* LBA supported - always 1 */
unsigned iordydis : 1; /* IORDY can be disabled */
unsigned iordyflag : 1; /* IORDY supported */
unsigned : 1;
unsigned ovlapflag : 1; /* overlap operation supported */
unsigned : 1;
unsigned idmaflag : 1; /* interleaved DMA supported */
short reserved4;
u_short pio_timing; /* PIO cycle timing */
u_short dma_timing; /* DMA cycle timing */
u_short flags;
#define AT_FLAG_54_58 1 /* words 54-58 valid */
#define AT_FLAG_64_70 2 /* words 64-70 valid */
short reserved5[8];
u_char swdma_flag; /* singleword DMA mode supported */
u_char swdma_active; /* singleword DMA mode active */
u_char mwdma_flag; /* multiword DMA mode supported */
u_char mwdma_active; /* multiword DMA mode active */
u_char apio_flag; /* advanced PIO mode supported */
u_char reserved6;
u_short mwdma_min; /* min. M/W DMA time per word (ns) */
u_short mwdma_dflt; /* recommended M/W DMA time (ns) - optional */
u_short pio_nfctl_min; /* min. PIO cycle time w/o flow ctl - optional */
u_short pio_iordy_min; /* min. PIO c/t with IORDY flow ctl - optional */
short reserved7[2];
u_short rls_ovlap; /* release time (us) for overlap cmd - optional */
u_short rls_service; /* release time (us) for service cmd - optional */
};
/*
* ATAPI operation result structure
*/
struct atapires {
u_char code; /* result code */
#define RES_OK 0 /* i/o done */
#define RES_ERR 1 /* i/o finished with error */
#define RES_NOTRDY 2 /* controller not ready */
#define RES_NODRQ 3 /* no data request */
#define RES_INVDIR 4 /* invalid bus phase direction */
#define RES_OVERRUN 5 /* data overrun */
#define RES_UNDERRUN 6 /* data underrun */
u_char status; /* status register contents */
u_char error; /* error register contents */
};
struct atapidrv { /* delayed attach info */
int ctlr; /* IDE controller, 0/1 */
int unit; /* drive unit, 0/1 */
int port; /* controller base port */
int attached; /* the drive is attached */
};
struct buf;
struct dmy;
typedef void atapi_callback_t(struct dmy *, struct buf *, int, struct atapires);
struct atapicmd { /* ATAPI command block */
struct atapicmd *next; /* next command in queue */
int busy; /* busy flag */
u_char cmd[16]; /* command and args */
int unit; /* drive unit number */
int count; /* byte count, >0 - read, <0 - write */
char *addr; /* data to transfer */
atapi_callback_t *callback; /* call when done */
void *cbarg1; /* callback arg 1 */
void *cbarg2; /* callback arg 1 */
struct atapires result; /* resulting error code */
};
struct atapi { /* ATAPI controller data */
u_short port; /* i/o port base */
u_char ctrlr; /* physical controller number */
u_char debug : 1; /* trace enable flag */
u_char cmd16 : 1; /* 16-byte command flag */
u_char intrcmd : 1; /* interrupt before cmd flag */
u_char slow : 1; /* slow reaction device */
u_char accel : 1; /* accelerated reaction device */
u_char use_dsc : 1; /* use DSC completition handeling */
u_char wait_for_dsc : 1;
u_int dsc_timeout;
u_char attached[2]; /* units are attached to subdrivers */
struct atapi_params *params[2]; /* params for units 0,1 */
struct atapicmd *queue; /* queue of commands to perform */
struct atapicmd *tail; /* tail of queue */
struct atapicmd *free; /* queue of free command blocks */
struct atapicmd cmdrq[16]; /* pool of command requests */
};
#ifdef _KERNEL
struct atapi;
extern struct atapidrv atapi_drvtab[4]; /* delayed attach info */
extern int atapi_ndrv; /* the number of potential drives */
extern struct atapi *atapi_tab; /* the table of atapi controllers */
int atapi_attach (int ctlr, int unit, int port);
int atapi_start (int ctrlr);
int atapi_intr (int ctrlr);
void atapi_debug (struct atapi *ata, int on);
struct atapires atapi_request_wait (struct atapi *ata, int unit,
u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
char *addr, int count);
void atapi_request_callback (struct atapi *ata, int unit,
u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
char *addr, int count, atapi_callback_t *done, void *x, void *y);
struct atapires atapi_request_immediate (struct atapi *ata, int unit,
u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
char *addr, int count);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,358 +0,0 @@
/*-
* Copyright (c) 1998, 1999 Søren Schmidt
* 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,
* without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* $FreeBSD$
*/
/*
* CDROM Table Of Contents
*/
#define MAXTRK 99
struct toc {
struct ioc_toc_header hdr;
struct cd_toc_entry tab[MAXTRK + 1];
};
/*
* CDROM Audio Control Parameters Page
*/
struct audiopage {
/* Mode Page data header */
u_short data_length;
u_char medium_type;
u_char dev_spec;
u_char unused[2];
u_short blk_desc_len;
/* Audio control page */
u_char page_code;
#define CDROM_AUDIO_PAGE 0x0e
#define CDROM_AUDIO_PAGE_MASK 0x4e
u_char param_len;
u_char flags;
#define CD_PA_SOTC 0x02
#define CD_PA_IMMED 0x04
u_char reserved3;
u_char reserved4;
u_char reserved5;
u_short lb_per_sec;
struct port_control {
u_char channels:4;
#define CHANNEL_0 1
#define CHANNEL_1 2
#define CHANNEL_2 4
#define CHANNEL_3 8
u_char volume;
} port[4];
};
/*
* CDROM Capabilities and Mechanical Status Page
*/
struct cappage {
/* Mode data header */
u_short data_length;
u_char medium_type; /* Present media type */
#define MST_TYPE_MASK_LOW 0x0f
#define MST_FMT_NONE 0x00
#define MST_DATA_120 0x01
#define MST_AUDIO_120 0x02
#define MST_COMB_120 0x03
#define MST_PHOTO_120 0x04
#define MST_DATA_80 0x05
#define MST_AUDIO_80 0x06
#define MST_COMB_80 0x07
#define MST_PHOTO_80 0x08
#define MST_TYPE_MASK_HIGH 0x70
#define MST_CDROM 0x00
#define MST_CDR 0x10
#define MST_CDRW 0x20
#define MST_NO_DISC 0x70
#define MST_DOOR_OPEN 0x71
#define MST_FMT_ERROR 0x72
u_char dev_spec;
u_char unused[2];
u_short blk_desc_len;
/* Capabilities page */
u_char page_code;
#define ATAPI_CDROM_CAP_PAGE 0x2a
u_char param_len;
u_char read_cdr:1; /* Supports CD-R read */
u_char read_cdrw:1; /* Supports CD-RW read */
u_char method2:1; /* Supports reading packet tracks */
u_char byte2_37:5;
u_char write_cdr:1; /* Supports CD-R write */
u_char write_cdrw:1; /* Supports CD-RW write */
u_char test_write:1; /* Supports test writing */
u_char byte3_37:5;
u_char audio_play:1; /* Audio play supported */
u_char composite:1; /* Composite audio/video supported */
u_char dport1:1; /* Digital audio on port 1 */
u_char dport2:1; /* Digital audio on port 2 */
u_char mode2_form1:1; /* Mode 2 form 1 (XA) read */
u_char mode2_form2:1; /* Mode 2 form 2 format */
u_char multisession:1; /* Multi-session photo-CD */
u_char:1;
u_char cd_da:1; /* Audio-CD read supported */
u_char cd_da_stream:1; /* CD-DA streaming */
u_char rw:1; /* Combined R-W subchannels */
u_char rw_corr:1; /* R-W subchannel data corrected */
u_char c2:1; /* C2 error pointers supported */
u_char isrc:1; /* Can return the ISRC info */
u_char upc:1; /* Can return the catalog number UPC */
u_char:1;
u_char lock:1; /* Can be locked */
u_char locked:1; /* Current lock state */
u_char prevent:1; /* Prevent jumper installed */
u_char eject:1; /* Can eject */
u_char:1;
u_char mech:3; /* Loading mechanism type */
#define MST_MECH_CADDY 0
#define MST_MECH_TRAY 1
#define MST_MECH_POPUP 2
#define MST_MECH_CHANGER 4
#define MST_MECH_CARTRIDGE 5
u_char sep_vol:1; /* Independent volume of channels */
u_char sep_mute:1; /* Independent mute of channels */
u_char:6;
u_short max_speed; /* Max raw data rate in bytes/1000 */
u_short max_vol_levels; /* Number of discrete volume levels */
u_short buf_size; /* Internal buffer size in bytes/1024 */
u_short cur_speed; /* Current data rate in bytes/1000 */
u_char reserved3;
u_char bckf:1; /* Data valid on failing edge of BCK */
u_char rch:1; /* High LRCK indicates left channel */
u_char lsbf:1; /* Set if LSB first */
u_char dlen:2;
#define MST_DLEN_32 0
#define MST_DLEN_16 1
#define MST_DLEN_24 2
#define MST_DLEN_24_I2S 3
u_char:3;
u_char reserved4[2];
};
/*
* CDROM Changer mechanism status structure
*/
struct changer {
u_char current_slot:5; /* Active changer slot */
u_char mech_state:2; /* Current changer state */
#define CH_READY 0
#define CH_LOADING 1
#define CH_UNLOADING 2
#define CH_INITIALIZING 3
u_char fault:1; /* Fault in last operation */
u_char reserved0:5;
u_char cd_state:3; /* Current mechanism state */
#define CD_IDLE 0
#define CD_AUDIO_ACTIVE 1
#define CD_AUDIO_SCAN 2
#define CD_HOST_ACTIVE 3
#define CD_NO_STATE 7
u_char current_lba[3]; /* Current LBA */
u_char slots; /* Number of available slots */
u_short table_length; /* Slot table length */
struct {
u_char changed:1; /* Media has changed in this slot */
u_char unused:6;
u_char present:1; /* Slot has a CD present */
u_char reserved0;
u_char reserved1;
u_char reserved2;
} slot[32];
};
/*
* CDROM Write Parameters Mode Page (Burners ONLY)
*/
struct write_param {
/* Mode Page data header */
u_short data_length;
u_char medium_type;
u_char dev_spec;
u_char unused[2];
u_short blk_desc_len;
/* Write Parameters mode page */
u_char page_code; /* 0x05 */
u_char page_length; /* 0x32 */
u_char write_type:4; /* Write stream type */
#define CDR_WTYPE_PACKET 0x00
#define CDR_WTYPE_TRACK 0x01
#define CDR_WTYPE_SESSION 0x02
#define CDR_WTYPE_RAW 0x03
u_char test_write:1; /* Test write enable */
u_char reserved2_567:3;
u_char track_mode:4; /* Track mode */
#define CDR_TMODE_AUDIO 0x01
#define CDR_TMODE_INCR_DATA 0x01
#define CDR_TMODE_ALLOW_COPY 0x02
#define CDR_TMODE_DATA 0x04
#define CDR_TMODE_QUAD_AUDIO 0x08
u_char copy:1; /* Generation stamp */
u_char fp:1; /* Fixed packet type */
u_char multi_session:2; /* Multi-session type */
#define CDR_MSES_NONE 0x00
#define CDR_MSES_FINAL 0x01
#define CDR_MSES_RESERVED 0x02
#define CDR_MSES_NULTI 0x03
u_char data_block_type:4; /* Data block type code */
#define CDR_DB_RAW 0x0 /* 2352 bytes of raw data */
#define CDR_DB_RAW_PQ 0x1 /* 2368 bytes raw data + P/Q subchan */
#define CDR_DB_RAW_PW 0x2 /* 2448 bytes raw data + P-W subchan */
#define CDR_DB_RAW_PW_R 0x3 /* 2448 bytes raw data + P-W raw sub */
#define CDR_DB_RES_4 0x4 /* Reserved */
#define CDR_DB_RES_5 0x5 /* Reserved */
#define CDR_DB_RES_6 0x6 /* Reserved */
#define CDR_DB_VS_7 0x7 /* Vendor specific */
#define CDR_DB_ROM_MODE1 0x8 /* 2048 bytes Mode 1 (ISO/IEC 10149) */
#define CDR_DB_ROM_MODE2 0x9 /* 2336 bytes Mode 2 (ISO/IEC 10149) */
#define CDR_DB_XA_MODE1 0x10 /* 2048 bytes Mode 1 (CD-ROM XA 1) */
#define CDR_DB_XA_MODE2_F1 0x11 /* 2056 bytes Mode 2 (CD-ROM XA 1) */
#define CDR_DB_XA_MODE2_F2 0x12 /* 2324 bytes Mode 2 (CD-ROM XA 2) */
#define CDR_DB_XA_MODE2_MIX 0x13 /* 2332 bytes Mode 2 (CD-ROM XA 1/2) */
#define CDR_DB_RES_14 0x14 /* Reserved */
#define CDR_DB_VS_15 0x15 /* Vendor specific */
u_char reserved4_4567:4;
u_char reserved5;
u_char reserved6;
u_char host_app_code:6; /* Host application code */
u_char reserved7_67:2;
u_char session_format; /* Session format */
#define CDR_SESS_CDROM 0x00
#define CDR_SESS_CDI 0x10
#define CDR_SESS_CDROM_XA 0x20
u_char reserved9;
u_int packet_size; /* Packet size in bytes */
u_short audio_pause_length; /* Audio pause length in secs */
u_char media_catalog_number[16];
u_char isr_code[16];
u_char sub_hdr_byte0;
u_char sub_hdr_byte1;
u_char sub_hdr_byte2;
u_char sub_hdr_byte3;
/*
u_char vendor_specific_byte0;
u_char vendor_specific_byte1;
u_char vendor_specific_byte2;
u_char vendor_specific_byte3;
*/
} __packed;
/*
* CDROM Read Track Information structure
*/
struct acd_track_info {
u_short data_length;
u_char track_number; /* Current track number */
u_char session_number; /* Current session number */
u_char reserved4;
u_char track_mode:4; /* Mode of this track */
u_char copy:1; /* Generation stamp */
u_char damage:1; /* Damaged track */
u_char reserved5_67:2;
u_char data_mode:4; /* Data mode of this disc */
u_char fp:1; /* Fixed packet */
u_char packet:1; /* Packet track */
u_char blank:1; /* Blank (empty) track */
u_char rt:1; /* Reserved track */
u_char nwa_valid:1; /* next_writeable_addr field valid */
u_char reserved7_17:7;
u_int track_start_addr; /* Start of this track */
u_int next_writeable_addr; /* Next writeable addr on this disc */
u_int free_blocks; /* Free block on this disc */
u_int fixed_packet_size; /* Size of packets on this track */
u_int track_length; /* Length of this track */
};
/*
* Structure describing an ATAPI CDROM device
*/
struct acd {
int unit; /* IDE bus drive unit */
int lun; /* Logical device unit */
int flags; /* Device state flags */
int refcnt; /* The number of raw opens */
struct atapi *ata; /* Controller structure */
struct bio_queue_head bio_queue; /* Queue of i/o requests */
struct atapi_params *param; /* Drive parameters table */
struct toc toc; /* Table of disc contents */
struct {
u_long volsize; /* Volume size in blocks */
u_long blksize; /* Block size in bytes */
} info;
struct audiopage au; /* Audio page info */
struct cappage cap; /* Capabilities page info */
struct audiopage aumask; /* Audio page mask */
struct { /* Subchannel info */
u_char void0;
u_char audio_status;
u_short data_length;
u_char data_format;
u_char control;
u_char track;
u_char indx;
u_long abslba;
u_long rellba;
} subchan;
struct changer *changer_info; /* Changer info */
int slot; /* This lun's slot number */
struct devstat *device_stats; /* Devstat parameters */
u_int block_size; /* Blocksize currently used */
u_char dummy; /* Use dummy writes */
u_char speed; /* Select drive speed */
u_int next_writeable_lba; /* Next writable position */
struct wormio_prepare_track preptrack; /* Scratch region */
};
struct ioc_read_audio {
u_char address_format;
union msf_lba address;
int nframes;
u_char* buffer;
};
#define CDIOCREADAUDIO _IOWR('c',31,struct ioc_read_audio)

View File

@ -1,316 +0,0 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* from: @(#)wdreg.h 7.1 (Berkeley) 5/9/91
* $FreeBSD$
*/
/*
* modified for PC9801 by F.Ukai
* Kyoto University Microcomputer Club (KMC)
*/
/*
* Disk Controller register definitions.
*/
#ifdef PC98
#define wd_data 0x0 /* data register (R/W - 16 bits) */
#define wd_error 0x2 /* error register (R) */
#define wd_precomp wd_error /* write precompensation (W) */
#define wd_features wd_error /* features register (W) */
#define wd_seccnt 0x4 /* sector count (R/W) */
#define wd_sector 0x6 /* first sector number (R/W) */
#define wd_cyl_lo 0x8 /* cylinder address, low byte (R/W) */
#define wd_cyl_hi 0xa /* cylinder address, high byte (R/W)*/
#define wd_sdh 0xc /* sector size/drive/head (R/W)*/
#define wd_command 0xe /* command register (W) */
#define wd_status wd_command /* immediate status (R) */
#define wd_altsts_nec 0x10c /*alternate fixed disk status(via 1015) (R)*/
#define wd_ctlr_nec 0x10c /*fixed disk controller control(via 1015) (W)*/
#define wd_altsts_epson 0x3 /*alternate fixed disk status(via 1015) (R)*/
#define wd_ctlr_epson 0x3 /*fixed disk controller control(via 1015) (W)*/
#define wd_altsts wd_altsts_nec
#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */
#define WDCTL_RST 0x4 /* reset the controller */
#define WDCTL_IDS 0x2 /* disable controller interrupts */
#define wd_digin 0x10e /* disk controller input(via 1015) (R)*/
#else /* IBM-PC */
#define wd_data 0x0 /* data register (R/W - 16 bits) */
#define wd_error 0x1 /* error register (R) */
#define wd_precomp wd_error /* write precompensation (W) */
#define wd_features wd_error /* features register (W) */
#define wd_seccnt 0x2 /* sector count (R/W) */
#define wd_sector 0x3 /* first sector number (R/W) */
#define wd_cyl_lo 0x4 /* cylinder address, low byte (R/W) */
#define wd_cyl_hi 0x5 /* cylinder address, high byte (R/W)*/
#define wd_sdh 0x6 /* sector size/drive/head (R/W)*/
#define wd_command 0x7 /* command register (W) */
#define wd_status wd_command /* immediate status (R) */
#define wd_altsts 0x206 /*alternate fixed disk status(via 1015) (R)*/
#define wd_ctlr 0x206 /*fixed disk controller control(via 1015) (W)*/
#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */
#define WDCTL_RST 0x4 /* reset the controller */
#define WDCTL_IDS 0x2 /* disable controller interrupts */
#define wd_digin 0x207 /* disk controller input(via 1015) (R)*/
#endif /* PC98 */
/*
* Status Bits.
*/
#define WDCS_BUSY 0x80 /* Controller busy bit. */
#define WDCS_READY 0x40 /* Selected drive is ready */
#define WDCS_WRTFLT 0x20 /* Write fault */
#define WDCS_SEEKCMPLT 0x10 /* Seek complete */
#define WDCS_DRQ 0x08 /* Data request bit. */
#define WDCS_ECCCOR 0x04 /* ECC correction made in data */
#define WDCS_INDEX 0x02 /* Index pulse from selected drive */
#define WDCS_ERR 0x01 /* Error detect bit. */
#define WDCS_BITS "\020\010busy\007rdy\006wrtflt\005seekdone\004drq\003ecc_cor\002index\001err"
#define WDERR_ABORT 0x04
#define WDERR_BITS "\020\010badblk\007uncorr\006id_crc\005no_id\003abort\002tr000\001no_dam"
/*
* Commands for Disk Controller.
*/
#define WDCC_RESTORE 0x10 /* disk restore code -- resets cntlr */
#define WDCC_READ 0x20 /* disk read code */
#define WDCC_WRITE 0x30 /* disk write code */
#define WDCC__LONG 0x02 /* modifier -- access ecc bytes */
#define WDCC__NORETRY 0x01 /* modifier -- no retrys */
#define WDCC_FORMAT 0x50 /* disk format code */
#define WDCC_DIAGNOSE 0x90 /* controller diagnostic */
#define WDCC_IDC 0x91 /* initialize drive command */
#define WDCC_READ_MULTI 0xC4 /* read multiple */
#define WDCC_WRITE_MULTI 0xC5 /* write multiple */
#define WDCC_SET_MULTI 0xC6 /* set multiple count */
#define WDCC_READ_DMA 0xC8 /* read using DMA */
#define WDCC_WRITE_DMA 0xCA /* write using DMA */
#define WDCC_EXTDCMD 0xE0 /* send extended command */
#define WDCC_READP 0xEC /* read parameters from controller */
#define WDCC_FEATURES 0xEF /* features control */
#define WDCC_DEFECT 0xF0 /* read defect list */
#define WDFEA_NORCACHE 0x55 /* read cache disable */
#define WDFEA_RCACHE 0xAA /* read cache enable */
#define WDFEA_NOWCACHE 0x82 /* write cache disable */
#define WDFEA_WCACHE 0x02 /* write cache enable */
#define WDFEA_SETXFER 0x03 /* set transfer mode */
#define WD_STEP 0 /* winchester- default 35us step */
#define WDSD_IBM 0xa0 /* forced to 512 byte sector, ecc */
#define WDSD_LBA 0x40 /* use Logical Block Adressing */
#ifdef _KERNEL
/*
* read parameters command returns this:
*/
struct wdparams {
/*
* XXX partly based on DRAFT X3T13/1153D rev 14.
* by the time you read this it will have changed.
* Offsets in words
* (as that's how they are usually presented in tables
* e.g. QUANTUM Product manuals)
*/
/* drive info */
short wdp_config; /*0 general configuration bits */
u_short wdp_cylinders; /*1 number of cylinders */
short wdp_reserved2; /*2*/
u_short wdp_heads; /*3 number of heads */
short wdp_unfbytespertrk; /*4 number of unformatted bytes/track */
short wdp_unfbytes; /*5 number of unformatted bytes/sec */
u_short wdp_sectors; /*6 number of sectors per track */
short wdp_vendorunique[3]; /*7,8,9*/
/* controller info */
char wdp_serial[20]; /*10-19 serial number */
short wdp_buffertype; /*20 buffer type */
#define WDTYPE_SINGLEPORTSECTOR 1 /* single port, single sector buffer */
#define WDTYPE_DUALPORTMULTI 2 /* dual port, multiple sector buffer */
#define WDTYPE_DUALPORTMULTICACHE 3 /* above plus track cache */
short wdp_buffersize; /*21 buffer size, in 512-byte units */
short wdp_necc; /*22 ecc bytes appended */
char wdp_rev[8]; /*23-26 firmware revision */
char wdp_model[40]; /*27-46 model name */
char wdp_nsecperint; /*47L sectors per interrupt */
char wdp_vendorunique1; /*47H*/
short wdp_usedmovsd; /*48 can use double word read/write? */
char wdp_vendorunique2; /*49L*/
char wdp_capability; /*49H various capability bits */
short wdp_cap_validate; /*50 validation for above */
char wdp_vendorunique3; /*51L*/
char wdp_opiomode; /*51H PIO modes 0-2 */
char wdp_vendorunique4; /*52*/
char wdp_odmamode; /*52 old DMA modes, not in ATA-3 */
short wdp_atavalid; /*53 validation for newer fields */
short wdp_currcyls; /*54 */
short wdp_currheads; /*55 */
short wdp_currsectors; /*56 */
short wdp_currsize0; /*57 CHS size*/
short wdp_currsize1; /*58 CHS size*/
char wdp_currmultsect; /*59L */
char wdp_multsectvalid; /*59H */
int wdp_lbasize; /*60,61*/
short wdp_dmasword; /*62 obsolete in ATA-3 */
short wdp_dmamword; /*63 multiword DMA modes */
short wdp_eidepiomodes; /*64 advanced PIO modes */
short wdp_eidedmamin; /*65 fastest possible DMA timing */
short wdp_eidedmanorm; /*66 recommended DMA timing */
short wdp_eidepioblind; /*67 fastest possible blind PIO */
short wdp_eidepioacked; /*68 fastest possible IORDY PIO */
short wdp_reserved69; /*69*/
short wdp_reserved70; /*70*/
short wdp_reserved71; /*71*/
short wdp_reserved72; /*72*/
short wdp_reserved73; /*73*/
short wdp_reserved74; /*74*/
short wdp_queuelen; /*75*/
short wdp_reserved76; /*76*/
short wdp_reserved77; /*77*/
short wdp_reserved78; /*78*/
short wdp_reserved79; /*79*/
short wdp_versmaj; /*80*/
short wdp_versmin; /*81*/
short wdp_featsupp1; /*82*/
short wdp_featsupp2; /*83*/
short wdp_featsupp3; /*84*/
short wdp_featenab1; /*85*/
short wdp_featenab2; /*86*/
short wdp_featenab3; /*87*/
short wdp_udmamode; /*88 UltraDMA modes */
short wdp_erasetime; /*89*/
short wdp_enherasetime; /*90*/
short wdp_apmlevel; /*91*/
short wdp_reserved92[34]; /*92*/
short wdp_rmvcap; /*93*/
short wdp_securelevel; /*94*/
};
/*
* IDE DMA support.
* This is based on what is needed for the IDE DMA function of the Intel
* Triton chipset; hopefully it's general enough to be used for other
* chipsets as well.
*
* To use this:
* For each drive which you might want to do DMA on, call wdd_candma()
* to get a cookie. If it returns a null pointer, then the drive
* can't do DMA. Then call wdd_dmainit() to initialize the controller
* and drive. wdd_dmainit should leave PIO modes operational, though
* perhaps with suboptimal performance.
*
* Check the transfer by calling wdd_dmaverify(). The cookie is what
* you got before; vaddr is the virtual address of the buffer to be
* written; len is the length of the buffer; and direction is either
* B_READ or B_WRITE. This function verifies that the DMA hardware is
* capable of handling the request you've made.
*
* Setup the transfer by calling wdd_dmaprep(). This takes the same
* paramaters as wdd_dmaverify().
*
* Send a read/write DMA command to the drive.
*
* Call wdd_dmastart().
*
* Wait for an interrupt. Multi-sector transfers will only interrupt
* at the end of the transfer.
*
* Call wdd_dmadone(). It will return the status as defined by the
* WDDS_* constants below.
*/
struct wddma {
void *(*wdd_candma) /* returns a cookie if PCI */
(int iobase_wd, int ctlr, int unit);
int (*wdd_dmaverify) /* verify that request is DMA-able */
(void *cookie, char *vaddr, u_long len, int direction);
int (*wdd_dmaprep) /* prepare DMA hardware */
(void *cookie, char *vaddr, u_long len, int direction);
void (*wdd_dmastart) /* begin DMA transfer */
(void *cookie);
int (*wdd_dmadone) /* DMA transfer completed */
(void *cookie);
int (*wdd_dmastatus) /* return status of DMA */
(void *cookie);
int (*wdd_dmainit) /* initialize controller and drive */
(void *cookie,
struct wdparams *wp,
int(wdcmd)(int mode, void *wdinfo),
void *wdinfo);
int (*wdd_iobase) /* returns iobase address */
(void *cookie);
int (*wdd_altiobase) /* returns altiobase address */
(void *cookie);
};
/* logical status bits returned by wdd_dmastatus */
#define WDDS_ACTIVE 0x0001
#define WDDS_ERROR 0x0002
#define WDDS_INTERRUPT 0x0004
#define WDDS_BITS "\20\4interrupt\2error\1active"
/* defines for ATA timing modes */
#define WDDMA_GRPMASK 0xf8
#define WDDMA_MODEMASK 0x07
/* flow-controlled PIO modes */
#define WDDMA_PIO 0x10
#define WDDMA_PIO3 0x10
#define WDDMA_PIO4 0x11
/* multi-word DMA timing modes */
#define WDDMA_MDMA 0x20
#define WDDMA_MDMA0 0x20
#define WDDMA_MDMA1 0x21
#define WDDMA_MDMA2 0x22
/* Ultra DMA timing modes */
#define WDDMA_UDMA 0x40
#define WDDMA_UDMA0 0x40
#define WDDMA_UDMA1 0x41
#define WDDMA_UDMA2 0x42
#define Q_CMD640B 0x00000001 /* CMD640B quirk: serialize IDE channels */
void wdc_pci(int quirks);
extern struct wddma wddma[];
void wdintr(void *unit);
#endif /* _KERNEL */

View File

@ -1,117 +0,0 @@
/* Shared between kernel & process */
/* $FreeBSD$ */
#ifndef _SYS_WORMIO_H_
#define _SYS_WORMIO_H_
#include <sys/ioccom.h>
/***************************************************************\
* Ioctls for the WORM drive *
\***************************************************************/
/*
* Prepare disk-wide parameters.
*/
struct wormio_prepare_disk
{
int dummy; /* use dummy writes, laser turned off */
int speed; /* drive speed selection */
};
#define WORMIOCPREPDISK _IOW('W', 20, struct wormio_prepare_disk)
/*
* Prepare track-specific parameters.
*/
struct wormio_prepare_track
{
int audio; /* audio track (data track if 0) */
int preemp; /* audio with preemphasis */
#define BLOCK_RAW 0 /* 2352 bytes, raw data */
#define BLOCK_RAWPQ 1 /* 2368 bytes, raw data with P and Q subchannels */
#define BLOCK_RAWPW 2 /* 2448 bytes, raw data with P-W subchannel appended */
#define BLOCK_MODE_1 8 /* 2048 bytes, mode 1 (ISO/IEC 10149) */
#define BLOCK_MODE_2 9 /* 2336 bytes, mode 2 (ISO/IEC 10149) */
#define BLOCK_MODE_2_FORM_1 10 /* 2048 bytes, CD-ROM XA form 1 */
#define BLOCK_MODE_2_FORM_1b 11 /* 2056 bytes, CD-ROM XA form 1 */
#define BLOCK_MODE_2_FORM_2 12 /* 2324 bytes, CD-ROM XA form 2 */
#define BLOCK_MODE_2_FORM_2b 13 /* 2332 bytes, CD-ROM XA form 2 */
int track_type; /* defines the number of bytes in a block */
#define COPY_INHIBIT 0 /* no copy allowed */
#define COPY_PERMITTED 1 /* track can be copied */
#define COPY_SCMS 2 /* alternate copy */
int copy_bits; /* define the possibilities for copying */
int track_number;
char ISRC_country[2]; /* country code (2 chars) */
char ISRC_owner[3]; /* owner code (3 chars) */
int ISRC_year; /* year of recording */
char ISRC_serial[5]; /* serial number */
};
#define WORMIOCPREPTRACK _IOW('W', 21, struct wormio_prepare_track)
/*
* Fixation: write leadins and leadouts. Select table-of-contents
* type for this session. If onp is != 0, another session will be
* opened.
*/
struct wormio_fixation
{
int toc_type; /* TOC type */
int onp; /* open next program area */
};
#define WORMIOCFIXATION _IOW('W', 22, struct wormio_fixation)
/*
* Finalize track
*/
#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)
struct wormio_first_writable_addr {
int track;
int mode;
int raw;
int audio;
int *addr;
};
#define WORMIOCFIRSTWRITABLEADDR _IOWR('W', 33, struct wormio_first_writable_addr)
#define CDRIOCBLANK _IO('c', 100)
#define CDRIOCNEXTWRITEABLEADDR _IOR('c', 101, int)
/* Errors/warnings */
#define WORM_SEQUENCE_ERROR 1
#define WORM_DUMMY_BLOCKS_ADDED 2
#define WORM_CALIBRATION_AREA_ALMOST_FULL 3
#define WORM_CALIBRATION_AREA_FULL 4
#define WORM_BUFFER_UNDERRUN 5
#define WORM_ABSORPTION_CONTROL_ERROR 6
#define WORM_END_OF_MEDIUM 7
#define WORM_OPTIMUM_POWER_CALIBRATION_ERROR 8
#define WORMIOERROR _IOR('W', 24, int)
#endif /* !_SYS_WORMIO_H_ */