⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bddrv.c

📁 linux1.0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
*****************************************************************************/
static int atapi_pause(ide_t *dev, bool cont)
{
    unsigned char pkt[12] =
        {
            ATAPI_CMD_PAUSE,
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0
        };
    request_t req;

    DEBUG(printf("atapi_pause\n");)
    memset(&req, 0, sizeof(req));
    req.dev = dev;
    pkt[8] = cont ? 1 : 0;
    return atapi_cmd(&req, pkt);
}
/*****************************************************************************
Use MODE SENSE (0x5A) to read page 0x2A
("CD-ROM Capabilities & Mechanical Status Page")
*****************************************************************************/
static int atapi_mode_sense(ide_t *dev)
{
    unsigned char buf[2048/*21*/], pkt[12] =
        {
            0x5A, 0, 0x2A,
            0, 0, 0, 0,
            0, 24,//21 //21 + 8,
            0, 0, 0
        };
    request_t req;

    DEBUG(printf("atapi_mode_sense:\n");)
    memset(&req, 0, sizeof(req));
    req.dev = dev;
    //	req.num_blks = 1;
    req.buf = buf;
    (void)atapi_cmd(&req, pkt);
    dump(buf + 8, 21);

    printf("\nmulti-session:\t\t%s\n",
           (buf[12] & 0x40) ? "YES" : "NO");
    printf("mode 2/form 2:\t\t%s\n",
           (buf[12] & 0x20) ? "YES" : "NO");
    printf("mode 2/form 1:\t\t%s\n",
           (buf[12] & 0x10) ? "YES" : "NO");
    printf("XA:\t\t\t%s\n",
           (buf[12] & 0x02) ? "YES" : "NO");
    printf("audio play:\t\t%s\n",
           (buf[12] & 0x01) ? "YES" : "NO");

    printf("UPC:\t\t\t%s\n",
           (buf[13] & 0x40) ? "YES" : "NO");
    printf("ISRC:\t\t\t%s\n",
           (buf[13] & 0x20) ? "YES" : "NO");
    printf("C2 pointers:\t\t%s\n",
           (buf[13] & 0x10) ? "YES" : "NO");
    printf("R-W deinterleave and\n  correction:\t\t%s\n",
           (buf[13] & 0x08) ? "YES" : "NO");
    printf("R-W:\t\t\t%s\n",
           (buf[13] & 0x04) ? "YES" : "NO");
    printf("accurate CD-DA stream:\t%s\n",
           (buf[13] & 0x02) ? "YES" : "NO");
    printf("CD-DA commands:\t\t%s\n",
           (buf[13] & 0x01) ? "YES" : "NO");

    printf("loading mechanism type:\t%u\n",
           buf[14] >> 5);
    printf("eject:\t\t\t%s\n",
           (buf[14] & 0x08) ? "YES" : "NO");
    printf("prevent jumper:\t\t%s\n",
           (buf[14] & 0x04) ? "YES" : "NO");
    printf("lock state:\t\t%s\n",
           (buf[14] & 0x02) ? "YES" : "NO");
    printf("lock:\t\t\t%s\n",
           (buf[14] & 0x01) ? "YES" : "NO");

    printf("separate channel:\t%s\n",
           (buf[15] & 0x02) ? "YES" : "NO");
    printf("separate volume:\t%s\n",
           (buf[15] & 0x01) ? "YES" : "NO");
    printf("max speed:\t\t%u KBps\n", read_be16(buf + 16));
    printf("volume levels:\t\t%u\n", read_be16(buf + 18));
    printf("buffer size:\t\t%uK\n", read_be16(buf + 20));
    printf("current speed:\t\t%u KBps\n", read_be16(buf + 22));

    return 0;
}
/*****************************************************************************
*****************************************************************************/
static int atapi_toc_ent(ide_t *dev, unsigned char *toc_ent,
                         unsigned short toc_ent_len)
{
    unsigned char pkt[12] =
        {
            0x43,	/* ATAPI_CMD_READTOC */
            2, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0
        };
    request_t req;

    DEBUG(printf("atapi_toc_ent\n");)
    memset(&req, 0, sizeof(req));
    req.dev = dev;
    /* xxx - pass toc_ent_len in req, somehow */
    //	req.num_blks = 1;
    req.buf = toc_ent;

    pkt[7] = toc_ent_len >> 8;
    pkt[8] = toc_ent_len;
    return atapi_cmd(&req, pkt);
}
/*****************************************************************************
*****************************************************************************/
#define	MAX_TRACKS	32

typedef struct /* one frame == 1/75 sec */
{
    unsigned char min, sec, frame;
} msf_t;

static int atapi_toc(ide_t *dev)
{
    unsigned char *entry, buf[4 + 8 * MAX_TRACKS];
    int temp;
    msf_t track[MAX_TRACKS];
    unsigned num_tracks;

    DEBUG(printf("atapi_toc:\n");)
    /* read just the 4-byte header at first
        16-bit table-of-contents length (?)
        8-bit first track
        8-bit last track */
    temp = 4;
    temp = atapi_toc_ent(dev, buf, temp);
    if(temp != 0)
        return temp;
    num_tracks = buf[3] - buf[2] + 1;
    if(num_tracks <= 0 || num_tracks > 99)
    {
        printf("atapi_toc: error: bad number of tracks %d\n",
               num_tracks);
        return -1;
    }
    if(num_tracks > MAX_TRACKS)
    {
        printf("atapi-toc: warning: too many tracks (%u); "
               "reducing to %u.\n", num_tracks, MAX_TRACKS);
        num_tracks = MAX_TRACKS;
    }
    /* read 4-byte header and 8-byte table-of-contents entries */
    temp = 4 + 8 * (num_tracks + 1);
    temp = atapi_toc_ent(dev, buf, temp);
    if(temp != 0)
        return temp;
    /* point to first TOC entry */
    entry = buf + 4;
    /* read num_tracks+1 entries
    the last entry is for the disk lead-out */
    for(temp = 0; temp < num_tracks + 2; temp++)
    {
        /* get track start time (minute, second, frame) from bytes 5..7 of entry */
        track[temp].min = entry[5];
        track[temp].sec = entry[6];
        track[temp].frame = entry[7];
        printf("%02u:%02u:%02u  ", track[temp].min,
               track[temp].sec, track[temp].frame);
        /* advance to next entry */
        entry += 8;
    }
    printf("\n");
    return 0;
}
//////////////////////////////////////////////////////////////////////////////
// DMA ROUTINES
//////////////////////////////////////////////////////////////////////////////
#define	NUM_DMAS	8
#define	DMA_READ	0x44
#define	DMA_WRITE	0x48

/* 8-bit DMAC registers */
#define	DMA_BASE	0
#define	DMA_MASK	0x0A	/* mask register (write only) */
#define	DMA_MODE	0x0B	/* mode register */
#define	DMA_FF		0x0C	/* MSB/LSB flip flop */
#define	DMA_RESET	0x0D	/* master clear */

/* Upper 4 bits (8 bits ?) of 20-bit (24-bit?) address
come from the DMAC page registers: */
static const unsigned char _page_reg_ioadr[NUM_DMAS] =
    {
        0x87, 0x83, 0x81, 0x82, 0, 0x8B, 0x89, 0x8A
    };
/****************************************************************************
****************************************************************************/
static int dma_read(unsigned char chan, unsigned long linear,
                    unsigned long tc)
{
    unsigned char scaled_chan, cmd;

    /* validate chan */
    if(chan > 3)
        return -1;
    /* set cmd byte  */
    cmd = DMA_READ + (chan & 3);
    /* make sure transfer doesn't exceed 16 meg or cross a 64K boundary */
    if(linear + tc >=  0x1000000L)
        return -1;
    if((linear & 0x10000L) != ((linear + tc) & 0x10000L))
        return -1;
    /* 8-bit transfers */
    scaled_chan = chan << 1;
    outportb(DMA_FF, 0);		/* set base adr */
    outportb(DMA_BASE + scaled_chan, linear);
    outportb(DMA_BASE + scaled_chan, linear >> 8);
    outportb(DMA_BASE + 1 +		/* set xfer len */
             scaled_chan, tc);
    outportb(DMA_BASE + 1 + scaled_chan, tc >> 8);
    outportb(_page_reg_ioadr[chan],	/* set page */
             linear >> 16);
    outportb(DMA_MODE, cmd);	/* do it */
    outportb(DMA_MASK, chan);
    return 0;
}
/****************************************************************************
****************************************************************************/
static int dma_write(unsigned char chan, unsigned long linear,
                     unsigned long tc)
{
    unsigned char scaled_chan, cmd;

    /* validate chan */
    if(chan > 3)
        return -1;
    /* set cmd byte  */
    cmd = DMA_WRITE + (chan & 3);
    /* make sure transfer doesn't exceed 16 meg or cross a 64K boundary */
    if(linear + tc >=  0x1000000L)
        return -1;
    if((linear & 0x10000L) != ((linear + tc) & 0x10000L))
        return -1;
    /* 8-bit transfers */
    scaled_chan = chan << 1;
    outportb(DMA_FF, 0);		/* set base adr */
    outportb(DMA_BASE + scaled_chan, linear);
    outportb(DMA_BASE + scaled_chan, linear >> 8);
    outportb(DMA_BASE + 1 +		/* set xfer len */
             scaled_chan, tc);
    outportb(DMA_BASE + 1 + scaled_chan, tc >> 8);
    outportb(_page_reg_ioadr[chan],	/* set page */
             linear >> 16);
    outportb(DMA_MODE, cmd);	/* do it */
    outportb(DMA_MASK, chan);
    return 0;
}
//////////////////////////////////////////////////////////////////////////////
// FLOPPY ROUTINES
//////////////////////////////////////////////////////////////////////////////
/* offsets from 0x3F0 */
#define FDC_DOR		2	/* Digital Output Register */
#define FDC_MSR		4	/* Main Status Register */
#define FDC_DATA	5	/* Data Register */

#define	FDC_DIR		7	/* Digital Input Register (input) */
#define FDC_CCR		7	/* Configuration Control Register (output) */

typedef struct
{
    /* generic block device info */
    blkdev_t blkdev;
    /* information specific to floppy drive */
    unsigned short timeout;
    unsigned char curr_track, sr0;
} floppy_t;
/*****************************************************************************
floppy controller chips:

Intel 8272a	==NEC 765
NEC 765ED	Non-Intel 1MB-compatible FDC, can't detect
Intel 87072	==8272a + FIFO + DUMPREGS
82072a		only on Sparcs?
82077AA		no LOCK (?)
82077AA-1
82078		44-pin 82078 or 64-pin 82078SL
82078-1		2 Mbps
S82078B		first seen on Adaptec AVA-2825 VLB SCSI/EIDE/Floppy ctrl
87306
*****************************************************************************/
static void floppy_send_byte(unsigned short ioadr, unsigned char byte)
{
    unsigned char msr;
    unsigned timeout;

    for(timeout = 128; timeout != 0; timeout--)
    {
        msr = inportb(ioadr + FDC_MSR);
        if((msr & 0xC0) == 0x80)
        {
            outportb(ioadr + FDC_DATA, byte);
            return;
        }
    }
    /* xxx - else? */
}
/*****************************************************************************
*****************************************************************************/
static int floppy_get_byte(unsigned short ioadr)
{
    unsigned char msr;
    unsigned timeout;

    for(timeout = 128; timeout != 0; timeout--)
    {
        msr = inportb(ioadr + FDC_MSR);
        if((msr & 0xD0) == 0xD0)
            return inportb(ioadr + FDC_DATA);
    }
    return -1; /* timeout */
}
/*****************************************************************************
*****************************************************************************/
static void floppy_motor_on(floppy_t *dev)
{
    unsigned short ioadr, t;
    unsigned char unit;

    DEBUG(printf("floppy_motor_on:\n");)
    ioadr = dev->blkdev.io.adr[0];
    unit = dev->blkdev.unit;
    t = dev->timeout;
    /* cancel motor-off timeout.
    -1 tells timer interrupt not to decrement  */
    dev->timeout = -1;
    if(t != 0)
        return; /* motor already on */
    /* xxx - top four bits enable motors, b3 enables DMA and I/O,
    b2 enables the the FDC chip, b1 and b0 are drive select

    xxx - need a static global variable to cache the value written to FDC_DOR

    xxx - floppy_select_drive() should be a separate function, maybe */
    outportb(ioadr + FDC_DOR, 0x1C);//unit?);
    /* delay 500ms for motor to spin up
    xxx - use interrupts here? */
    msleep(500);
}
/*****************************************************************************
*****************************************************************************/
static void floppy_motor_off(floppy_t *dev)
{
    DEBUG(printf("floppy_motor_off:\n");)
    dev->timeout = 36; /* 18 ticks, ~2 sec */
}
/*****************************************************************************
*****************************************************************************/
static int floppy_await_interrupt(floppy_t *fdev)
{
    unsigned short irq, ioadr;
    unsigned char status[7];
    int temp;

    ioadr = fdev->blkdev.io.adr[0];
    irq = fdev->blkdev.io.irq;
    DEBUG(printf("floppy_await_interrupt:\n");)
    /* wait up to 1 second for IRQ 6 */
    temp = await_interrupt(irq, 1000);
    if(temp == 0) /* timeout */
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -