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

📄 detect.c

📁 freedos32的源代码
💻 C
字号:
/* ATA Driver for FD32 * by Luca Abeni & Nils Labugt * * This is free software; see GPL.txt */#include <dr-env.h>#include "ata.h"#include "disk.h"#include "ata-detect.h"#include "ata-ops.h"#include "ata-wait.h"extern int ata_global_flags;extern int max_pio_mode;extern BYTE standby_timer;extern int block_mode;#define _DEBUG_#define _LOGGER_#ifdef _LOGGER_#define MSG fd32_log_printf#define WAIT#else#define MSG fd32_message#define WAIT ata_wait(10*1000*1000)#endifstatic void string_parse(char *dst, WORD *src, int len){    int k;    for (k = 0; k < len; k++)    {        dst[2 * k] = (src[k] >> 8) & 0xFF;        dst[2 * k + 1] = src[k] & 0xFF;    }    dst[2 * len] = 0;}static void ata_irq_enable(struct ide_interface *p){    extern void ata_irq(int n);    fd32_irq_bind(p->irq, ata_irq);    fd32_outb(p->control_port, 0x08);}int ata_detect_single(int device_no, struct ide_interface* intf, struct ata_device** d, int* detected_drives_p){    WORD drvdata[256];    int res;    BYTE b;    int pi_device = FALSE;    if(*d == NULL)    {        *d = fd32_kmem_get(sizeof(struct ata_device));        if (*d == NULL)        {            fd32_message("Unable to allocate disk structure!\n");            return 0;        }    }    if(device_no == 1)        (*d)->dev_bit = ATA_DEVHEAD_DEV;    else        (*d)->dev_bit = 0;    (*d)->interface = intf;    if(ata_global_flags & ATA_GFLAG_POLL)        (*d)->polled_mode = TRUE;    else        (*d)->polled_mode = FALSE;    (*d)->sectors_per_block = 0;    (*d)->flags = 0;#ifdef _DEBUG_    MSG("IDENTIFY DEVICE command on device %i\n", device_no);#endif    res = pio_data_in(200 * 1000, 1, 0, (void*)drvdata, *d, ATA_CMD_IDENTIFY, FALSE);    if(res<0)    {        /* PI device? */        /* Checking the signature */#ifdef _DEBUG_        MSG("IDENTIFY DEVICE failed, returned %i, st=%x, err=%x\n", res, (*d)->status_reg, (*d)->error_reg);#endif        b = fd32_inb((*d)->interface->command_port + CMD_CYL_L);        if(b != 0x14)            return 0;        b = fd32_inb((*d)->interface->command_port + CMD_CYL_H);        if(b != 0xEB)            return 0;#ifdef _DEBUG_        MSG("Signature present, executing IDENTIFY PACET DEVICE command\n");#endif         res = pio_data_in(200 * 1000, 1, 0, (void*)drvdata, *d, ATA_CMD_IDENTIFY_PD, FALSE);        if(res<0)        {#ifdef _DEBUG_            MSG("IDENTIFY PACKET DEVICE failed, returned %i, st=%x, err=%x\n", res, (*d)->status_reg, (*d)->error_reg);#endif            fd32_message("Error: Detection of PI device failed!\n");            return 0;        }        pi_device = TRUE;    }    (*d)->first_sector = 0;    if(detected_drives_p != NULL)    {        (*detected_drives_p)++;        (*d)->drv_number = *detected_drives_p;        /* Device name */        ksprintf((*d)->device_name, "hd%c", intf->basename + device_no);    }    (*d)->interface = intf;    (*d)->capabilities = drvdata[49];    (*d)->multiboot_id = 0;    string_parse((*d)->model, drvdata + 27, 20);    (*d)->model[40] = '\0';    string_parse((*d)->serial, drvdata + 10, 10);    (*d)->serial[20] = '\0';    string_parse((*d)->revision, drvdata + 23, 4);    (*d)->revision[8] = '\0';    /* Supported PIO modes */    drvdata[51] &= 3;    if(drvdata[51] > 0)        (*d)->flags |= 1 << DEV_FLG_SUPP_PIO_BITS;    if(drvdata[51] > 1)        (*d)->flags |= 1 << (DEV_FLG_SUPP_PIO_BITS + 1);    if(drvdata[53] & 2)        (*d)->flags |= ((int)drvdata[64]) << (DEV_FLG_SUPP_PIO_BITS + 2);    (*d)->type = 0xFFFFFFFF;    if(pi_device == FALSE)    {        (*d)->cyls = drvdata[1];        (*d)->heads = drvdata[3];        (*d)->sectors = drvdata[6];        (*d)->bytes_per_sector = 512;        (*d)->max_multiple_rw = drvdata[47] & 0xFF;        if((*d)->capabilities & ATA_CAPAB_LBA)        {            (*d)->total_blocks = *((int*)&(drvdata[60]));            if( drvdata[83] & (1 << 10) )                (*d)->flags |= DEV_FLG_48BIT_LBA;        }        else            (*d)->total_blocks = (*d)->cyls * (*d)->heads * (*d)->sectors;        /* Enable block mode */        if((ata_global_flags & ATA_GFLAG_BLOCK_MODE) && ((*d)->max_multiple_rw > block_mode) )            (*d)->max_multiple_rw = block_mode;        if((*d)->max_multiple_rw != 0)        {            if(ata_set_multiple( *d, (*d)->max_multiple_rw ) < 0)                fd32_message("Error: Unable to enable block mode for %s!\n", (*d)->device_name);            else                (*d)->sectors_per_block = (*d)->max_multiple_rw;        }        /* Set standby timer */        if(ata_global_flags & ATA_GFLAG_STANDBY_EN)        {            if(ata_idle( *d, standby_timer) < 0)                fd32_message("Error: Failed to enable standby timer for %s!\n", (*d)->device_name);            else                (*d)->flags |= DEV_FLG_ST_TIMER_ACTIVE;        }    }    else    {        (*d)->flags |= DEV_FLG_PI_DEV;        (*d)->general_config = drvdata[0];        (*d)->type = ((*d)->general_config >> 8) & 0x1F;        if( ( (*d)->general_config & (3 << 5)) == (1 << 5))            (*d)->flags |= DEV_FLG_IRQ_ON_PCMD;    }    /* Set PIO mode */    if(ata_global_flags & ATA_GFLAG_PIO_MODE)    {        int i = 4, j = (*d)->flags;        j |= 1 << (DEV_FLG_SUPP_PIO_BITS - 1); /* allways supports mode 0 */        while(i >= 0)        {            if(i <= max_pio_mode && (j & (1 << 31)))            {                if(ata_set_pio_mode( *d, i ) < 0)                    fd32_message("Error: Failed to set PIO transfer mode %i for %s!\n", i, (*d)->device_name);                break;            }            i--;            j <<= 1;        }    }    return 1;}int ata_detect(struct ide_interface *intf, void (*disk_add)(struct ata_device *d, char *name)){    int detected_drives = 0;    struct ata_device* d = NULL;#ifdef _DEBUG_    MSG("Staring detection: cmd=%x, ctrl=%x, irq=%u\n", (unsigned)intf->command_port, (unsigned)intf->control_port, intf->irq);#endif    intf->dev0 = NULL;    intf->dev1 = NULL;    if(ata_poll(MAX_WAIT_DETECT, &dev_is_busy, intf) < 0)    {#ifdef _DEBUG_        MSG("Timeout on BSY bit, aborting detection\n");#endif        return 0;    }    delay(400);    /* Read and discard ALT SATUS, then compare STATUS and ALT STATUS */    fd32_inb(intf->control_port);    if((fd32_inb(intf->command_port + CMD_STATUS) & ~0x02) != (fd32_inb(intf->control_port) & ~0x02))    {#ifdef _DEBUG_        MSG("STATUS snd ALT STATUS different, aborting detection\n");#endif        return 0;    }    fd32_outb(intf->command_port + CMD_DEVHEAD, 0xF0);    if(!(ata_global_flags & ATA_GFLAG_POLL))        ata_irq_enable(intf);    delay(400);    intf->current_dev_bit = ATA_DEVHEAD_DEV;    if(ata_detect_single(0, intf, &d, &detected_drives) == 1)    {        disk_add(d, d->device_name);        intf->dev0 = d;        d = NULL;#ifdef _DEBUG_        MSG("Master device detected\n");        WAIT;#endif    }    if(ata_detect_single(1, intf, &d, &detected_drives) == 1)    {        disk_add(d, d->device_name);        intf->dev1 = d;#ifdef _DEBUG_        MSG("Slave device detected\n");        WAIT;#endif    }    else        fd32_kmem_free((void*)d, sizeof(struct ata_device));    return detected_drives;}

⌨️ 快捷键说明

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