📄 ide.h
字号:
#ifndef _IDE_H#define _IDE_H/* * linux/include/linux/ide.h * * Copyright (C) 1994-1998 Linus Torvalds & authors */#include <linux/config.h>#include <linux/init.h>#include <linux/ioport.h>#include <linux/hdreg.h>#include <linux/hdsmart.h>#include <linux/blkdev.h>#include <linux/proc_fs.h>#include <linux/devfs_fs_kernel.h>#include <asm/hdreg.h>#ifdef CONFIG_TOSHIBA_JMR3927#include <asm/jmr3927/jmr3927.h>#endif/* * 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 1 /* 0 to reduce kernel size */#endif#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */#define SUPPORT_VLB_SYNC 1 /* 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 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 */#ifndef DISABLE_IRQ_NOSYNC#define DISABLE_IRQ_NOSYNC 0#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*/#define IDE_DRIVE_TASK 98/* * IDE_DRIVE_TASKFILE is used to implement many features needed for raw tasks */#define IDE_DRIVE_TASKFILE 97/* * "No user-serviceable parts" beyond this point :) *****************************************************************************/typedef 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 *//* * state flags */#define DMA_PIO_RETRY 1 /* retrying in PIO *//* * Ensure that various configuration flags have compatible settings */#ifdef REALLY_SLOW_IO#undef REALLY_FAST_IO#endif#define HWIF(drive) ((ide_hwif_t *)((drive)->hwif))#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))/* * Definitions for accessing IDE controller registers */#define IDE_NR_PORTS (10)#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_CONTROL_OFFSET (8)#define IDE_IRQ_OFFSET (9)#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET#define IDE_DATA_OFFSET_HOB (0)#define IDE_ERROR_OFFSET_HOB (1)#define IDE_NSECTOR_OFFSET_HOB (2)#define IDE_SECTOR_OFFSET_HOB (3)#define IDE_LCYL_OFFSET_HOB (4)#define IDE_HCYL_OFFSET_HOB (5)#define IDE_SELECT_OFFSET_HOB (6)#define IDE_CONTROL_OFFSET_HOB (7)#define IDE_FEATURE_OFFSET_HOB IDE_ERROR_OFFSET_HOB#define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET])#define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET])#define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])#define IDE_SECTOR_REG (HWIF(drive)->io_ports[IDE_SECTOR_OFFSET])#define IDE_LCYL_REG (HWIF(drive)->io_ports[IDE_LCYL_OFFSET])#define IDE_HCYL_REG (HWIF(drive)->io_ports[IDE_HCYL_OFFSET])#define IDE_SELECT_REG (HWIF(drive)->io_ports[IDE_SELECT_OFFSET])#define IDE_STATUS_REG (HWIF(drive)->io_ports[IDE_STATUS_OFFSET])#define IDE_CONTROL_REG (HWIF(drive)->io_ports[IDE_CONTROL_OFFSET])#define IDE_IRQ_REG (HWIF(drive)->io_ports[IDE_IRQ_OFFSET])#define IDE_DATA_REG_HOB (HWIF(drive)->io_ports[IDE_DATA_OFFSET])#define IDE_ERROR_REG_HOB (HWIF(drive)->io_ports[IDE_ERROR_OFFSET])#define IDE_NSECTOR_REG_HOB (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])#define IDE_SECTOR_REG_HOB (HWIF(drive)->io_ports[IDE_SECTOR_OFFSET])#define IDE_LCYL_REG_HOB (HWIF(drive)->io_ports[IDE_LCYL_OFFSET])#define IDE_HCYL_REG_HOB (HWIF(drive)->io_ports[IDE_HCYL_OFFSET])#define IDE_SELECT_REG_HOB (HWIF(drive)->io_ports[IDE_SELECT_OFFSET])#define IDE_STATUS_REG_HOB (HWIF(drive)->io_ports[IDE_STATUS_OFFSET])#define IDE_CONTROL_REG_HOB (HWIF(drive)->io_ports[IDE_CONTROL_OFFSET])#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#define GET_ERR() IN_BYTE(IDE_ERROR_REG)#define GET_STAT() IN_BYTE(IDE_STATUS_REG)#define GET_ALTSTAT() IN_BYTE(IDE_CONTROL_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 "hd" /* 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 */#define CASCADE_DRIVES 8 /* per interface; 8|2 assumed by lots of code */#define SECTOR_SIZE 512#define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */#define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))#define IDE_MIN(a,b) ((a)<(b) ? (a):(b))#define IDE_MAX(a,b) ((a)>(b) ? (a):(b))#ifndef SPLIT_WORD# define SPLIT_WORD(W,HB,LB) ((HB)=(W>>8), (LB)=(W-((W>>8)<<8)))#endif#ifndef MAKE_WORD# define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))#endif/* * Timeouts for various operations: */#define WAIT_DRQ (5*HZ/100) /* 50msec - spec allows up to 20ms */#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)#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 || CONFIG_APM_MODULE */#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?), if all ATAPI CD is closed at boot */#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */#define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */#define SELECT_DRIVE(hwif,drive) \{ \ if (hwif->selectproc) \ hwif->selectproc(drive); \ OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \}#define SELECT_INTERRUPT(hwif,drive) \{ \ if (hwif->intrproc) \ hwif->intrproc(drive); \ else \ OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]); \}#define SELECT_MASK(hwif,drive,mask) \{ \ if (hwif->maskproc) \ hwif->maskproc(drive,mask); \}#define SELECT_READ_WRITE(hwif,drive,func) \{ \ if (hwif->rwproc) \ hwif->rwproc(drive,func); \}#define QUIRK_LIST(hwif,drive) \{ \ if (hwif->quirkproc) \ (drive)->quirk_list = hwif->quirkproc(drive); \}#define HOST(hwif,chipset) \{ \ return ((hwif)->chipset == chipset) ? 1 : 0; \}#define IDE_DEBUG(lineno) \ printk("%s,%s,line=%d\n", __FILE__, __FUNCTION__, (lineno))/* * Check for an interrupt and acknowledge the interrupt status */struct hwif_s;struct ide_drive_s;typedef int (ide_ack_intr_t)(struct hwif_s *);typedef void (ide_xfer_data_t)(struct ide_drive_s *, void *, unsigned int);#ifndef NO_DMA#define NO_DMA 255#endif/* * hwif_chipset_t is used to keep track of the specific hardware * chipset used by each IDE interface, if known. */typedef enum { ide_unknown, ide_generic, ide_pci, ide_cmd640, ide_dtc2278, ide_ali14xx, ide_qd65xx, ide_umc8672, ide_ht6560b, ide_pdc4030, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, ide_pmac, ide_etrax100, ide_acorn,} hwif_chipset_t;/* * Structure to hold all information about the location of this port */typedef struct hw_regs_s { ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ int irq; /* our irq number */ int dma; /* our dma number */ ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ ide_xfer_data_t *ide_output_data; /* write data to i/face */ ide_xfer_data_t *ide_input_data; /* read data from i/face */ ide_xfer_data_t *atapi_output_bytes; /* write bytes to i/face */ ide_xfer_data_t *atapi_input_bytes; /* read bytes from i/face */ void *priv; /* interface specific data */ hwif_chipset_t chipset;} hw_regs_t;/* * Register new hardware with ide */int ide_register_hw(hw_regs_t *hw, struct hwif_s **hwifp);/* * Set up hw_regs_t structure before calling ide_register_hw (optional) */void ide_setup_ports( hw_regs_t *hw, ide_ioreg_t base, int *offsets, ide_ioreg_t ctrl, ide_ioreg_t intr, ide_ack_intr_t *ack_intr, int irq);#include <asm/ide.h>/* * If the arch-dependant ide.h did not declare/define any OUT_BYTE * or IN_BYTE functions, we make some defaults here. */#ifndef JMR3927_INIT_INDIRECT_PCI#ifndef HAVE_ARCH_OUT_BYTE#ifdef REALLY_FAST_IO#define OUT_BYTE(b,p) outb((b),(p))#define OUT_WORD(w,p) outw((w),(p))#else#define OUT_BYTE(b,p) outb_p((b),(p))#define OUT_WORD(w,p) outw_p((w),(p))#endif#endif#ifndef HAVE_ARCH_IN_BYTE#ifdef REALLY_FAST_IO#define IN_BYTE(p) (byte)inb(p)#define IN_WORD(p) (short)inw(p)#else#define IN_BYTE(p) (byte)inb_p(p)#define IN_WORD(p) (short)inw_p(p)#endif#endif#else /* JMR3927_INIT_INDIRECT_PCI */#define OUT_BYTE(b,p) tx_iooutb((b),(unsigned char *)(p))#define IN_BYTE(p) (unsigned char)tx_ioinb((unsigned char *)(p))#endif /* JMR3927_INIT_INDIRECT_PCI *//* * Now for the data we need to maintain per-drive: ide_drive_t */#define ide_scsi 0x21#define ide_disk 0x20#define ide_optical 0x7#define ide_cdrom 0x5#define ide_tape 0x1#define ide_floppy 0x0typedef 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 reserved : 4; /* unused */ } b;} special_t;typedef struct ide_drive_s { request_queue_t queue; /* request queue */ struct ide_drive_s *next; /* circular list of hwgroup drives */ unsigned long sleep; /* sleep until this time */ unsigned long service_start; /* time we started last request */ unsigned long service_time; /* service time of last request */ unsigned long timeout; /* max time to wait for irq */ special_t special; /* special action flags */ byte keep_settings; /* restore settings after drive reset */ byte using_dma; /* disk is using dma for read/write */ byte retry_pio; /* retrying dma capable host in pio */ byte state; /* retry state */ byte waiting_for_dma; /* dma currently in progress */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -