📄 ide.h
字号:
/* * linux/drivers/block/ide.h * * Copyright (C) 1994, 1995 Linus Torvalds & authors */#include <linux/config.h>/* * This is the multiple IDE interface driver, as evolved from hd.c. * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). * There can be up to two drives per interface, as per the ATA-2 spec. * * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64 * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64 * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64 * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64 *//****************************************************************************** * IDE driver configuration options (play with these as desired): * * REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary */#undef REALLY_FAST_IO /* define if ide ports are perfect */#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */#define SUPPORT_SLOW_DATA_PORTS 0 /* 0 to reduce kernel size */#endif#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */#define SUPPORT_VLB_SYNC 0 /* 0 to reduce kernel size */#endif#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */#endif#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */#endif#ifndef FAKE_FDISK_FOR_EZDRIVE /* 1 to help linux fdisk with EZDRIVE */#define FAKE_FDISK_FOR_EZDRIVE 1 /* 0 to reduce kernel size */#endif#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */#endif#ifdef CONFIG_BLK_DEV_CMD640#if 0 /* change to 1 when debugging cmd640 problems */void cmd640_dump_regs (void);#define CMD640_DUMP_REGS cmd640_dump_regs() /* for debugging cmd640 chipset */#endif#endif /* CONFIG_BLK_DEV_CMD640 */#if defined(CONFIG_BLK_DEV_IDECD) || defined(CONFIG_BLK_DEV_IDETAPE) || \ defined(CONFIG_BLK_DEV_IDEFLOPPY) || defined(CONFIG_BLK_DEV_IDESCSI)#define CONFIG_BLK_DEV_IDEATAPI 1#endif/* * IDE_DRIVE_CMD is used to implement many features of the hdparm utility */#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*//* * "No user-serviceable parts" beyond this point :) *****************************************************************************/#if defined(CONFIG_BLK_DEV_IDESCSI) && !defined(CONFIG_SCSI)#error "SCSI must also be selected"#endiftypedef unsigned char byte; /* used everywhere *//* * Probably not wise to fiddle with these */#define ERROR_MAX 8 /* Max read/write errors per sector */#define ERROR_RESET 3 /* Reset controller every 4th retry */#define ERROR_RECAL 1 /* Recalibrate every 2nd retry *//* * Ensure that various configuration flags have compatible settings */#ifdef REALLY_SLOW_IO#undef REALLY_FAST_IO#endif/* * Definitions for accessing IDE controller registers */#define HWIF(drive) ((ide_hwif_t *)((drive)->hwif))#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))#define IDE_DATA_OFFSET (0)#define IDE_ERROR_OFFSET (1)#define IDE_NSECTOR_OFFSET (2)#define IDE_SECTOR_OFFSET (3)#define IDE_LCYL_OFFSET (4)#define IDE_HCYL_OFFSET (5)#define IDE_SELECT_OFFSET (6)#define IDE_STATUS_OFFSET (7)#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET#define IDE_DATA_REG (HWIF(drive)->io.io_base+(IDE_DATA_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_ERROR_REG (HWIF(drive)->io.io_base+(IDE_ERROR_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_NSECTOR_REG (HWIF(drive)->io.io_base+(IDE_NSECTOR_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_SECTOR_REG (HWIF(drive)->io.io_base+(IDE_SECTOR_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_LCYL_REG (HWIF(drive)->io.io_base+(IDE_LCYL_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_HCYL_REG (HWIF(drive)->io.io_base+(IDE_HCYL_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_SELECT_REG (HWIF(drive)->io.io_base+(IDE_SELECT_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_STATUS_REG (HWIF(drive)->io.io_base+(IDE_STATUS_OFFSET<<HWIF(drive)->io.io_shift))#define IDE_CONTROL_REG (HWIF(drive)->io.ctl_port)#define IDE_FEATURE_REG IDE_ERROR_REG#define IDE_COMMAND_REG IDE_STATUS_REG#define IDE_ALTSTATUS_REG IDE_CONTROL_REG#define IDE_IREASON_REG IDE_NSECTOR_REG#define IDE_BCOUNTL_REG IDE_LCYL_REG#define IDE_BCOUNTH_REG IDE_HCYL_REG#ifdef REALLY_FAST_IO#define OUT_BYTE(b,p) outb((b),(p))#define IN_BYTE(p) (byte)inb(p)#else#define OUT_BYTE(b,p) outb_p((b),(p))#define IN_BYTE(p) (byte)inb_p(p)#endif /* REALLY_FAST_IO */#define GET_ERR() IN_BYTE(IDE_ERROR_REG)#define GET_STAT() IN_BYTE(IDE_STATUS_REG)#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))#define BAD_R_STAT (BUSY_STAT | ERR_STAT)#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT)#define BAD_STAT (BAD_R_STAT | DRQ_STAT)#define DRIVE_READY (READY_STAT | SEEK_STAT)#define DATA_READY (DRQ_STAT)/* * Some more useful definitions */#define IDE_MAJOR_NAME "ide" /* the same for all i/f; see also genhd.c */#define MAJOR_NAME IDE_MAJOR_NAME#define PARTN_BITS 6 /* number of minor dev bits for partitions */#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */#define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */#ifndef MAX_HWIFS#define MAX_HWIFS 4 /* an arbitrary, but realistic limit */#endif#define SECTOR_WORDS (512 / 4) /* number of 32bit words per sector *//* * Timeouts for various operations: */#define WAIT_DRQ (5*HZ/100) /* 50msec - spec allows up to 20ms */#ifdef CONFIG_APM#define WAIT_READY (5*HZ) /* 5sec - some laptops are very slow */#else#define WAIT_READY (3*HZ/100) /* 30msec - should be instantaneous */#endif /* CONFIG_APM */#define WAIT_PIDENTIFY (1*HZ) /* 1sec - should be less than 3ms (?) */#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */#if defined(CONFIG_BLK_DEV_HT6560B) || defined(CONFIG_BLK_DEV_PROMISE)#define SELECT_DRIVE(hwif,drive) \{ \ if (hwif->selectproc) \ hwif->selectproc(drive); \ else \ OUT_BYTE((drive)->select.all, hwif->io_base + (IDE_SELECT_OFFSET << hwif->io.io_shift)); \}#else#define SELECT_DRIVE(hwif,drive) OUT_BYTE((drive)->select.all, hwif->io.io_base + (IDE_SELECT_OFFSET << hwif->io.io_shift));#endif /* CONFIG_BLK_DEV_HT6560B || CONFIG_BLK_DEV_PROMISE */ #ifdef CONFIG_BLK_DEV_IDETAPE#include "ide-tape.h"#endif /* CONFIG_BLK_DEV_IDETAPE */#ifdef CONFIG_BLK_DEV_IDECDstruct atapi_request_sense { unsigned char error_code : 7; unsigned char valid : 1; byte reserved1; unsigned char sense_key : 4; unsigned char reserved2 : 1; unsigned char ili : 1; unsigned char reserved3 : 2; byte info[4]; byte sense_len; byte command_info[4]; byte asc; byte ascq; byte fru; byte sense_key_specific[3];};struct packet_command { char *buffer; int buflen; int stat; struct atapi_request_sense *sense_data; unsigned char c[12];};/* Structure of a MSF cdrom address. */struct atapi_msf { byte reserved; byte minute; byte second; byte frame;};/* Space to hold the disk TOC. */#define MAX_TRACKS 99struct atapi_toc_header { unsigned short toc_length; byte first_track; byte last_track;};struct atapi_toc_entry { byte reserved1; unsigned control : 4; unsigned adr : 4; byte track; byte reserved2; union { unsigned lba; struct atapi_msf msf; } addr;};struct atapi_toc { int last_session_lba; int xa_flag; unsigned capacity; struct atapi_toc_header hdr; struct atapi_toc_entry ent[MAX_TRACKS+1]; /* One extra for the leadout. */};/* This structure is annoyingly close to, but not identical with, the cdrom_subchnl structure from cdrom.h. */struct atapi_cdrom_subchnl { u_char acdsc_reserved; u_char acdsc_audiostatus; u_short acdsc_length; u_char acdsc_format; u_char acdsc_adr: 4; u_char acdsc_ctrl: 4; u_char acdsc_trk; u_char acdsc_ind; union { struct atapi_msf msf; int lba; } acdsc_absaddr; union { struct atapi_msf msf; int lba; } acdsc_reladdr;};/* Extra per-device info for cdrom drives. */struct cdrom_info { /* Buffer for table of contents. NULL if we haven't allocated a TOC buffer for this device yet. */ struct atapi_toc *toc; /* Sector buffer. If a read request wants only the first part of a cdrom block, we cache the rest of the block here, in the expectation that that data is going to be wanted soon. SECTOR_BUFFERED is the number of the first buffered sector, and NSECTORS_BUFFERED is the number of sectors in the buffer. Before the buffer is allocated, we should have SECTOR_BUFFER == NULL and NSECTORS_BUFFERED == 0. */ unsigned long sector_buffered; unsigned long nsectors_buffered; char *sector_buffer; /* The result of the last successful request sense command on this device. */ struct atapi_request_sense sense_data; int max_sectors;};#endif /* CONFIG_BLK_DEV_IDECD *//* * Now for the data we need to maintain per-drive: ide_drive_t */typedef enum {ide_disk, ide_cdrom, ide_tape, ide_floppy, ide_scsi} ide_media_t;typedef union { unsigned all : 8; /* all of the bits together */ struct { unsigned set_geometry : 1; /* respecify drive geometry */ unsigned recalibrate : 1; /* seek to cyl 0 */ unsigned set_multmode : 1; /* set multmode count */ unsigned set_tune : 1; /* tune interface for drive */ unsigned mc : 1; /* acknowledge media change */ unsigned reserved : 3; /* unused */ } b; } special_t;typedef union { unsigned all : 8; /* all of the bits together */ struct { unsigned head : 4; /* always zeros here */ unsigned unit : 1; /* drive select number, 0 or 1 */ unsigned bit5 : 1; /* always 1 */ unsigned lba : 1; /* using LBA instead of CHS */ unsigned bit7 : 1; /* always 1 */ } b; } select_t;typedef struct ide_drive_s { special_t special; /* special action flags */ unsigned present : 1; /* drive is physically present */ unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned keep_settings : 1; /* restore settings after drive reset */ unsigned busy : 1; /* currently doing revalidate_disk() */ unsigned removable : 1; /* 1 if need to do check_media_change */ unsigned using_dma : 1; /* disk is using dma for read/write */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned unmask : 1; /* flag: okay to unmask other irqs */ unsigned no_unmask : 1; /* disallow setting unmask bit */ unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ unsigned nobios : 1; /* flag: do not probe bios for drive */ unsigned slow : 1; /* flag: slow data port */ unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */#if FAKE_FDISK_FOR_EZDRIVE unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */#endif /* FAKE_FDISK_FOR_EZDRIVE */ unsigned no_geom : 1; /* flag: do not set geometry */ ide_media_t media; /* disk, cdrom, tape, floppy */ select_t select; /* basic drive/head select reg value */ byte ctl; /* "normal" value for IDE_CONTROL_REG */ byte ready_stat; /* min status value for drive ready */ byte mult_count; /* current multiple sector setting */ byte mult_req; /* requested multiple sector setting */ byte tune_req; /* requested drive tuning setting */ byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ byte bad_wstat; /* used for ignoring WRERR_STAT */ byte sect0; /* offset of first sector for DM6:DDO */ byte usage; /* current "open()" count for drive */ byte head; /* "real" number of heads */ byte sect; /* "real" sectors per track */ byte bios_head; /* BIOS/fdisk/LILO number of heads */ byte bios_sect; /* BIOS/fdisk/LILO sectors per track */ unsigned short bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned short cyl; /* "real" number of cyls */ void *hwif; /* actually (ide_hwif_t *) */ struct wait_queue *wqueue; /* used to wait for drive in open() */ struct hd_driveid *id; /* drive model identification info */ struct hd_struct *part; /* drive partition table */ char name[4]; /* drive name, such as "hda" */#ifdef CONFIG_BLK_DEV_IDECD struct cdrom_info cdrom_info; /* for ide-cd.c */#endif /* CONFIG_BLK_DEV_IDECD */#ifdef CONFIG_BLK_DEV_IDETAPE idetape_tape_t tape; /* for ide-tape.c */#endif /* CONFIG_BLK_DEV_IDETAPE */#ifdef CONFIG_BLK_DEV_IDEFLOPPY void *floppy; /* for ide-floppy.c */#endif /* CONFIG_BLK_DEV_IDEFLOPPY */#ifdef CONFIG_BLK_DEV_IDESCSI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -