From 79b2577a004ca2763bc007edbb3545b83a9f9641 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 11 Sep 2002 12:54:13 +0200 Subject: ide core updates, and addition of ide-iops.c --- include/linux/ide.h | 1431 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 951 insertions(+), 480 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 1843237adf4a..32409745ded5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -3,7 +3,7 @@ /* * linux/include/linux/ide.h * - * Copyright (C) 1994-1998 Linus Torvalds & authors + * Copyright (C) 1994-2002 Linus Torvalds & authors */ #include @@ -14,18 +14,14 @@ #include #include #include +#include +#include #include #include #include #include #include -#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT -# define __IDEDMA_TIMEOUT -#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ -# undef __IDEDMA_TIMEOUT -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ - /* * 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). @@ -42,7 +38,7 @@ * * 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 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 */ @@ -170,9 +166,6 @@ typedef unsigned char byte; /* used everywhere */ #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) @@ -180,6 +173,43 @@ typedef unsigned char byte; /* used everywhere */ #define DRIVE_READY (READY_STAT | SEEK_STAT) #define DATA_READY (DRQ_STAT) +#define BAD_CRC (ABRT_ERR | ICRC_ERR) + +#define SATA_NR_PORTS (3) /* 16 possible ?? */ + +#define SATA_STATUS_OFFSET (0) +#define SATA_STATUS_REG (HWIF(drive)->sata_scr[SATA_STATUS_OFFSET]) +#define SATA_ERROR_OFFSET (1) +#define SATA_ERROR_REG (HWIF(drive)->sata_scr[SATA_ERROR_OFFSET]) +#define SATA_CONTROL_OFFSET (2) +#define SATA_CONTROL_REG (HWIF(drive)->sata_scr[SATA_CONTROL_OFFSET]) + +#define SATA_MISC_OFFSET (0) +#define SATA_MISC_REG (HWIF(drive)->sata_misc[SATA_MISC_OFFSET]) +#define SATA_PHY_OFFSET (1) +#define SATA_PHY_REG (HWIF(drive)->sata_misc[SATA_PHY_OFFSET]) +#define SATA_IEN_OFFSET (2) +#define SATA_IEN_REG (HWIF(drive)->sata_misc[SATA_IEN_OFFSET]) + +/* + * Our Physical Region Descriptor (PRD) table should be large enough + * to handle the biggest I/O request we are likely to see. Since requests + * can have no more than 256 sectors, and since the typical blocksize is + * two or more sectors, we could get by with a limit of 128 entries here for + * the usual worst case. Most requests seem to include some contiguous blocks, + * further reducing the number of table entries required. + * + * The driver reverts to PIO mode for individual requests that exceed + * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling + * 100% of all crazy scenarios here is not necessary. + * + * As it turns out though, we must allocate a full 4KB page for this, + * so the two PRD tables (ide0 & ide1) will each get half of that, + * allowing each to have about 256 entries (8 bytes each) from this. + */ +#define PRD_BYTES 8 +#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES)) + /* * sector count bits */ @@ -215,21 +245,12 @@ typedef unsigned char byte; /* used everywhere */ #define PARTN_BITS 6 /* number of minor dev bits for partitions */ #define PARTN_MASK ((1< (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: */ @@ -244,39 +265,6 @@ typedef unsigned char byte; /* used everywhere */ #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; \ @@ -304,9 +292,34 @@ typedef enum { ide_unknown, ide_generic, ide_pci, ide_qd65xx, ide_umc8672, ide_ht6560b, ide_pdc4030, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, - ide_pmac, ide_etrax100 + ide_pmac, ide_etrax100, ide_acorn } hwif_chipset_t; +typedef struct ide_io_ops_s { + /* insert io operations here! */ + void (*OUTB)(u8 addr, u32 port); + void (*OUTW)(u16 addr, u32 port); + void (*OUTL)(u32 addr, u32 port); + void (*OUTBP)(u8 addr, u32 port); + void (*OUTWP)(u16 addr, u32 port); + void (*OUTLP)(u32 addr, u32 port); + void (*OUTSW)(u32 port, void *addr, u32 count); + void (*OUTSWP)(u32 port, void *addr, u32 count); + void (*OUTSL)(u32 port, void *addr, u32 count); + void (*OUTSLP)(u32 port, void *addr, u32 count); + + u8 (*INB)(u32 port); + u16 (*INW)(u32 port); + u32 (*INL)(u32 port); + u8 (*INBP)(u32 port); + u16 (*INWP)(u32 port); + u32 (*INLP)(u32 port); + void (*INSW)(u32 port, void *addr, u32 count); + void (*INSWP)(u32 port, void *addr, u32 count); + void (*INSL)(u32 port, void *addr, u32 count); + void (*INSLP)(u32 port, void *addr, u32 count); +} ide_io_ops_t; + /* * Structure to hold all information about the location of this port */ @@ -317,6 +330,11 @@ typedef struct hw_regs_s { ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ void *priv; /* interface specific data */ hwif_chipset_t chipset; +#if 0 + ide_io_ops_t *iops; /* */ +#endif + sata_ioreg_t sata_scr[SATA_NR_PORTS]; + sata_ioreg_t sata_misc[SATA_NR_PORTS]; } hw_regs_t; /* @@ -333,10 +351,27 @@ void ide_setup_ports( hw_regs_t *hw, ide_ioreg_t ctrl, ide_ioreg_t intr, ide_ack_intr_t *ack_intr, +#if 0 + ide_io_ops_t *iops, +#endif int irq); #include +/* Currently only m68k, apus and m8xx need it */ +#ifdef IDE_ARCH_ACK_INTR +extern int ide_irq_lock; +# define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1) +#else +# define ide_ack_intr(hwif) (1) +#endif + +/* Currently only Atari needs it */ +#ifndef IDE_ARCH_LOCK +# define ide_release_lock(lock) do {} while (0) +# define ide_get_lock(lock, hdlr, data) do {} while (0) +#endif /* IDE_ARCH_LOCK */ + /* * If the arch-dependant ide.h did not declare/define any OUT_BYTE * or IN_BYTE functions, we make some defaults here. @@ -346,20 +381,30 @@ void ide_setup_ports( hw_regs_t *hw, # ifdef REALLY_FAST_IO # define OUT_BYTE(b,p) outb((b),(p)) # define OUT_WORD(w,p) outw((w),(p)) +# define OUT_LONG(l,p) outl((l),(p)) # else # define OUT_BYTE(b,p) outb_p((b),(p)) # define OUT_WORD(w,p) outw_p((w),(p)) +# define OUT_LONG(l,p) outl_p((l),(p)) # endif +# define OUT_BYTE_P(b,p) outb_p((b),(p)) +# define OUT_WORD_P(w,p) outw_p((w),(p)) +# define OUT_LONG_P(l,p) outl_p((l),(p)) #endif #ifndef HAVE_ARCH_IN_BYTE # ifdef REALLY_FAST_IO -# define IN_BYTE(p) (byte)inb(p) -# define IN_WORD(p) (short)inw(p) +# define IN_BYTE(p) (u8) inb(p) +# define IN_WORD(p) (u16) inw(p) +# define IN_LONG(p) (u32) inl(p) # else -# define IN_BYTE(p) (byte)inb_p(p) -# define IN_WORD(p) (short)inw_p(p) +# define IN_BYTE(p) (u8) inb_p(p) +# define IN_WORD(p) (u16) inw_p(p) +# define IN_LONG(p) (u32) inl_p(p) # endif +# define IN_BYTE_P(p) (u8) inb_p(p) +# define IN_WORD_P(p) (u16) inw_p(p) +# define IN_LONG_P(p) (u32) inl_p(p) #endif /* @@ -373,201 +418,453 @@ void ide_setup_ports( hw_regs_t *hw, #define ide_tape 0x1 #define ide_floppy 0x0 +/* + * Special Driver Flags + * + * set_geometry : respecify drive geometry + * recalibrate : seek to cyl 0 + * set_multmode : set multmode count + * set_tune : tune interface for drive + * serviced : service command + * reserved : unused + */ typedef union { - unsigned all : 8; /* all of the bits together */ + unsigned all : 8; struct { #if defined(__LITTLE_ENDIAN_BITFIELD) - 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 serviced : 1; /* service command */ - unsigned reserved : 3; /* unused */ + unsigned set_geometry : 1; + unsigned recalibrate : 1; + unsigned set_multmode : 1; + unsigned set_tune : 1; + unsigned serviced : 1; + unsigned reserved : 3; #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned reserved : 3; /* unused */ - unsigned serviced : 1; /* service command */ - unsigned set_tune : 1; /* tune interface for drive */ - unsigned set_multmode : 1; /* set multmode count */ - unsigned recalibrate : 1; /* seek to cyl 0 */ - unsigned set_geometry : 1; /* respecify drive geometry */ + unsigned reserved : 3; + unsigned serviced : 1; + unsigned set_tune : 1; + unsigned set_multmode : 1; + unsigned recalibrate : 1; + unsigned set_geometry : 1; #else #error "Please fix " #endif } b; } special_t; +/* + * ATA DATA Register Special. + * ATA NSECTOR Count Register(). + * ATAPI Byte Count Register. + * Channel index ordering pairs. + */ +typedef union { + unsigned all :16; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned low :8; /* LSB */ + unsigned high :8; /* MSB */ +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned high :8; /* MSB */ + unsigned low :8; /* LSB */ +#else +#error "Please fix " +#endif + } b; +} ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t; + +/* + * ATA-IDE Error Register + * + * mark : Bad address mark + * tzero : Couldn't find track 0 + * abrt : Aborted Command + * mcr : Media Change Request + * id : ID field not found + * mce : Media Change Event + * ecc : Uncorrectable ECC error + * bdd : dual meaing + */ typedef union { - unsigned all : 8; /* all of the bits together */ + unsigned all :8; struct { #if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned head : 4; /* always zeros here */ - unsigned unit : 1; /* drive select number: 0/1 */ - unsigned bit5 : 1; /* always 1 */ - unsigned lba : 1; /* using LBA instead of CHS */ - unsigned bit7 : 1; /* always 1 */ + unsigned mark :1; + unsigned tzero :1; + unsigned abrt :1; + unsigned mcr :1; + unsigned id :1; + unsigned mce :1; + unsigned ecc :1; + unsigned bdd :1; #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned bit7 : 1; /* always 1 */ - unsigned lba : 1; /* using LBA instead of CHS */ - unsigned bit5 : 1; /* always 1 */ - unsigned unit : 1; /* drive select number: 0/1 */ - unsigned head : 4; /* always zeros here */ + unsigned bdd :1; + unsigned ecc :1; + unsigned mce :1; + unsigned id :1; + unsigned mcr :1; + unsigned abrt :1; + unsigned tzero :1; + unsigned mark :1; #else #error "Please fix " #endif } b; -} select_t; +} ata_error_t; +/* + * ATA-IDE Select Register, aka Device-Head + * + * head : always zeros here + * unit : drive select number: 0/1 + * bit5 : always 1 + * lba : using LBA instead of CHS + * bit7 : always 1 + */ typedef union { - unsigned all : 8; /* all of the bits together */ + unsigned all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned head : 4; + unsigned unit : 1; + unsigned bit5 : 1; + unsigned lba : 1; + unsigned bit7 : 1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bit7 : 1; + unsigned lba : 1; + unsigned bit5 : 1; + unsigned unit : 1; + unsigned head : 4; +#else +#error "Please fix " +#endif + } b; +} select_t, ata_select_t; + +/* + * The ATA-IDE Status Register. + * The ATAPI Status Register. + * + * check : Error occurred + * idx : Index Error + * corr : Correctable error occurred + * drq : Data is request by the device + * dsc : Disk Seek Complete : ata + * : Media access command finished : atapi + * df : Device Fault : ata + * : Reserved : atapi + * drdy : Ready, Command Mode Capable : ata + * : Ignored for ATAPI commands : atapi + * bsy : Disk is Busy + * : The device has access to the command block + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned check :1; + unsigned idx :1; + unsigned corr :1; + unsigned drq :1; + unsigned dsc :1; + unsigned df :1; + unsigned drdy :1; + unsigned bsy :1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bsy :1; + unsigned drdy :1; + unsigned df :1; + unsigned dsc :1; + unsigned drq :1; + unsigned corr :1; + unsigned idx :1; + unsigned check :1; +#else +#error "Please fix " +#endif + } b; +} ata_status_t, atapi_status_t; + +/* + * ATA-IDE Control Register + * + * bit0 : Should be set to zero + * nIEN : device INTRQ to host + * SRST : host soft reset bit + * bit3 : ATA-2 thingy, Should be set to 1 + * reserved456 : Reserved + * HOB : 48-bit address ordering, High Ordered Bit + */ +typedef union { + unsigned all : 8; struct { #if defined(__LITTLE_ENDIAN_BITFIELD) unsigned bit0 : 1; - unsigned nIEN : 1; /* device INTRQ to host */ - unsigned SRST : 1; /* host soft reset bit */ - unsigned bit3 : 1; /* ATA-2 thingy */ - unsigned reserved456 : 3; - unsigned HOB : 1; /* 48-bit address ordering */ + unsigned nIEN : 1; + unsigned SRST : 1; + unsigned bit3 : 1; + unsigned reserved456 : 3; + unsigned HOB : 1; #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned HOB : 1; /* 48-bit address ordering */ + unsigned HOB : 1; unsigned reserved456 : 3; - unsigned bit3 : 1; /* ATA-2 thingy */ - unsigned SRST : 1; /* host soft reset bit */ - unsigned nIEN : 1; /* device INTRQ to host */ + unsigned bit3 : 1; + unsigned SRST : 1; + unsigned nIEN : 1; unsigned bit0 : 1; #else #error "Please fix " #endif } b; -} control_t; +} ata_control_t; +/* + * ATAPI Feature Register + * + * dma : Using DMA or PIO + * reserved321 : Reserved + * reserved654 : Reserved (Tag Type) + * reserved7 : Reserved + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned dma :1; + unsigned reserved321 :3; + unsigned reserved654 :3; + unsigned reserved7 :1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned reserved7 :1; + unsigned reserved654 :3; + unsigned reserved321 :3; + unsigned dma :1; +#else +#error "Please fix " +#endif + } b; +} atapi_feature_t; + +/* + * ATAPI Interrupt Reason Register. + * + * cod : Information transferred is command (1) or data (0) + * io : The device requests us to read (1) or write (0) + * reserved : Reserved + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned cod :1; + unsigned io :1; + unsigned reserved :6; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned reserved :6; + unsigned io :1; + unsigned cod :1; +#else +#error "Please fix " +#endif + } b; +} atapi_ireason_t; + +/* + * The ATAPI error register. + * + * ili : Illegal Length Indication + * eom : End Of Media Detected + * abrt : Aborted command - As defined by ATA + * mcr : Media Change Requested - As defined by ATA + * sense_key : Sense key of the last failed packet command + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned ili :1; + unsigned eom :1; + unsigned abrt :1; + unsigned mcr :1; + unsigned sense_key :4; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned sense_key :4; + unsigned mcr :1; + unsigned abrt :1; + unsigned eom :1; + unsigned ili :1; +#else +#error "Please fix " +#endif + } b; +} atapi_error_t; + +/* + * ATAPI floppy Drive Select Register + * + * sam_lun : Logical unit number + * reserved3 : Reserved + * drv : The responding drive will be drive 0 (0) or drive 1 (1) + * one5 : Should be set to 1 + * reserved6 : Reserved + * one7 : Should be set to 1 + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned sam_lun :3; + unsigned reserved3 :1; + unsigned drv :1; + unsigned one5 :1; + unsigned reserved6 :1; + unsigned one7 :1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned one7 :1; + unsigned reserved6 :1; + unsigned one5 :1; + unsigned drv :1; + unsigned reserved3 :1; + unsigned sam_lun :3; +#else +#error "Please fix " +#endif + } b; +} atapi_select_t; struct ide_driver_s; struct ide_settings_s; typedef struct ide_drive_s { - request_queue_t queue; /* request queue */ + char name[4]; /* drive name, such as "hda" */ + char driver_req[10]; /* requests specific driver */ + + request_queue_t queue; /* request queue */ + + struct request *rq; /* current request */ struct ide_drive_s *next; /* circular list of hwgroup drives */ + struct ide_driver_s *driver;/* (ide_driver_t *) */ + void *driver_data; /* extra driver data */ + struct hd_driveid *id; /* drive model identification info */ + struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ + struct ide_settings_s *settings;/* /proc/ide/ drive settings */ + devfs_handle_t de; /* directory for device */ + + struct hwif_s *hwif; /* actually (ide_hwif_t *) */ + 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 */ - byte unmask; /* flag: okay to unmask other irqs */ - byte slow; /* flag: slow data port */ - byte bswap; /* flag: byte swap data */ - byte dsc_overlap; /* flag: DSC overlap */ - byte nice1; /* flag: give potential excess bandwidth */ + select_t select; /* basic drive/head select reg value */ + + u8 keep_settings; /* restore settings after drive reset */ + u8 autodma; /* device can safely use dma on host */ + u8 using_dma; /* disk is using dma for read/write */ + u8 using_tcq; /* disk is using queueing */ + u8 retry_pio; /* retrying dma capable host in pio */ + u8 state; /* retry state */ + u8 waiting_for_dma; /* dma currently in progress */ + u8 unmask; /* okay to unmask other irqs */ + u8 slow; /* slow data port */ + u8 bswap; /* byte swap data */ + u8 dsc_overlap; /* DSC overlap */ + u8 nice1; /* give potential excess bandwidth */ + unsigned present : 1; /* drive is physically present */ unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned removable : 1; /* 1 if need to do check_media_change */ + unsigned is_flash : 1; /* 1 if probed as flash */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ 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 atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */ - unsigned nice0 : 1; /* flag: give obvious excess bandwidth */ - unsigned nice2 : 1; /* flag: give a share in our own bandwidth */ - unsigned doorlocking : 1; /* flag: for removable only: door lock/unlock works */ + unsigned nobios : 1; /* do not probe bios for drive */ + unsigned atapi_overlap : 1; /* ATAPI overlap (not supported) */ + unsigned nice0 : 1; /* give obvious excess bandwidth */ + unsigned nice2 : 1; /* give a share in our own bandwidth */ + unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ unsigned ata_flash : 1; /* 1=present, 0=default */ - unsigned addressing; /* : 3; + unsigned addressing; /* : 3; * 0=28-bit * 1=48-bit * 2=48-bit doing 28-bit * 3=64-bit */ - byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ - byte 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 nowerr; /* used for ignoring WRERR_STAT */ - byte sect0; /* offset of first sector for DM6:DDO */ - unsigned int 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 */ + + u8 scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ + u8 quirk_list; /* considered quirky, set for a specific host */ + u8 suspend_reset; /* drive suspend mode flag, soft-reset recovers */ + u8 init_speed; /* transfer rate set at boot */ + u8 current_speed; /* current transfer rate set */ + u8 dn; /* now wide spread use */ + u8 wcache; /* status of write cache */ + u8 acoustic; /* acoustic management */ + u8 media; /* disk, cdrom, tape, floppy, ... */ + u8 ctl; /* "normal" value for IDE_CONTROL_REG */ + u8 ready_stat; /* min status value for drive ready */ + u8 mult_count; /* current multiple sector setting */ + u8 mult_req; /* requested multiple sector setting */ + u8 tune_req; /* requested drive tuning setting */ + u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ + u8 bad_wstat; /* used for ignoring WRERR_STAT */ + u8 nowerr; /* used for ignoring WRERR_STAT */ + u8 sect0; /* offset of first sector for DM6:DDO */ + u8 head; /* "real" number of heads */ + u8 sect; /* "real" sectors per track */ + u8 bios_head; /* BIOS/fdisk/LILO number of heads */ + u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */ + unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int cyl; /* "real" number of cyls */ - unsigned long capacity; /* total number of sectors */ - unsigned long long capacity48; /* total number of sectors */ - unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ - struct hwif_s *hwif; /* actually (ide_hwif_t *) */ - struct hd_driveid *id; /* drive model identification info */ - char name[4]; /* drive name, such as "hda" */ - struct ide_driver_s *driver; /* (ide_driver_t *) */ - void *driver_data; /* extra driver data */ - devfs_handle_t de; /* directory for device */ - struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - struct ide_settings_s *settings; /* /proc/ide/ drive settings */ - char driver_req[10]; /* requests specific driver */ + unsigned int drive_data; /* use by tuneproc/selectproc */ + unsigned int usage; /* current "open()" count for drive */ + unsigned int failures; /* current failure count */ + unsigned int max_failures; /* maximum allowed failure count */ + + u32 capacity; /* total number of sectors */ + u64 capacity48; /* total number of sectors */ + int last_lun; /* last logical unit */ int forced_lun; /* if hdxlun was given at boot */ int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ - byte quirk_list; /* drive is considered quirky if set for a specific host */ - byte suspend_reset; /* drive suspend mode flag, soft-reset recovers */ - byte init_speed; /* transfer rate set at boot */ - byte current_speed; /* current transfer rate set */ - byte dn; /* now wide spread use */ - byte wcache; /* status of write cache */ - byte acoustic; /* acoustic management */ - unsigned int failures; /* current failure count */ - unsigned int max_failures; /* maximum allowed failure count */ struct list_head list; struct gendisk *disk; } ide_drive_t; -/* - * An ide_dmaproc_t() initiates/aborts DMA read/write operations on a drive. - * - * The caller is assumed to have selected the drive and programmed the drive's - * sector address using CHS or LBA. All that remains is to prepare for DMA - * and then issue the actual read/write DMA/PIO command to the drive. - * - * Returns 0 if all went well. - * Returns 1 if DMA read/write could not be started, in which case the caller - * should either try again later, or revert to PIO for the current request. - */ -typedef enum { ide_dma_read, ide_dma_write, ide_dma_begin, - ide_dma_end, ide_dma_check, ide_dma_on, - ide_dma_off, ide_dma_off_quietly, ide_dma_test_irq, - ide_dma_host_on, ide_dma_host_off, - ide_dma_bad_drive, ide_dma_good_drive, - ide_dma_verbose, ide_dma_retune, - ide_dma_lostirq, ide_dma_timeout -} ide_dma_action_t; - -typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *); - -/* - * An ide_ideproc_t() performs CPU-polled transfers to/from a drive. - * Arguments are: the drive, the buffer pointer, and the length (in bytes or - * words depending on if it's an IDE or ATAPI call). - * - * If it is not defined for a controller, standard-code is used from ide.c. - * - * Controllers which are not memory-mapped in the standard way need to - * override that mechanism using this function to work. - * - */ -typedef enum { ideproc_ide_input_data, ideproc_ide_output_data, - ideproc_atapi_input_bytes, ideproc_atapi_output_bytes -} ide_ide_action_t; - -typedef void (ide_ideproc_t)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); +typedef struct ide_pio_ops_s { + void (*ata_input_data)(ide_drive_t *, void *, u32); + void (*ata_output_data)(ide_drive_t *, void *, u32); + + void (*atapi_input_bytes)(ide_drive_t *, void *, u32); + void (*atapi_output_bytes)(ide_drive_t *, void *, u32); +} ide_pio_ops_t; + +typedef struct ide_dma_ops_s { + /* insert dma operations here! */ + int (*ide_dma_read)(ide_drive_t *drive); + int (*ide_dma_write)(ide_drive_t *drive); + int (*ide_dma_begin)(ide_drive_t *drive); + int (*ide_dma_end)(ide_drive_t *drive); + int (*ide_dma_check)(ide_drive_t *drive); + int (*ide_dma_on)(ide_drive_t *drive); + int (*ide_dma_off)(ide_drive_t *drive); + int (*ide_dma_off_quietly)(ide_drive_t *drive); + int (*ide_dma_test_irq)(ide_drive_t *drive); + int (*ide_dma_host_on)(ide_drive_t *drive); + int (*ide_dma_host_off)(ide_drive_t *drive); + int (*ide_dma_bad_drive)(ide_drive_t *drive); + int (*ide_dma_good_drive)(ide_drive_t *drive); + int (*ide_dma_count)(ide_drive_t *drive); + int (*ide_dma_verbose)(ide_drive_t *drive); + int (*ide_dma_retune)(ide_drive_t *drive); + int (*ide_dma_lostirq)(ide_drive_t *drive); + int (*ide_dma_timeout)(ide_drive_t *drive); +} ide_dma_ops_t; /* * mapping stuff, prepare for highmem... @@ -602,166 +899,182 @@ extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags) bio_kunmap_irq(buffer, flags); } -/* - * A Verbose noise maker for debugging on the attempted transfer rates. - */ -extern inline char *ide_xfer_verbose (byte xfer_rate) -{ - switch(xfer_rate) { - case XFER_UDMA_7: return("UDMA 7"); - case XFER_UDMA_6: return("UDMA 6"); - case XFER_UDMA_5: return("UDMA 5"); - case XFER_UDMA_4: return("UDMA 4"); - case XFER_UDMA_3: return("UDMA 3"); - case XFER_UDMA_2: return("UDMA 2"); - case XFER_UDMA_1: return("UDMA 1"); - case XFER_UDMA_0: return("UDMA 0"); - case XFER_MW_DMA_2: return("MW DMA 2"); - case XFER_MW_DMA_1: return("MW DMA 1"); - case XFER_MW_DMA_0: return("MW DMA 0"); - case XFER_SW_DMA_2: return("SW DMA 2"); - case XFER_SW_DMA_1: return("SW DMA 1"); - case XFER_SW_DMA_0: return("SW DMA 0"); - case XFER_PIO_4: return("PIO 4"); - case XFER_PIO_3: return("PIO 3"); - case XFER_PIO_2: return("PIO 2"); - case XFER_PIO_1: return("PIO 1"); - case XFER_PIO_0: return("PIO 0"); - case XFER_PIO_SLOW: return("PIO SLOW"); - default: return("XFER ERROR"); - } -} - -/* - * A Verbose noise maker for debugging on the attempted dmaing calls. - */ -extern inline char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) -{ - switch (dmafunc) { - case ide_dma_read: return("ide_dma_read"); - case ide_dma_write: return("ide_dma_write"); - case ide_dma_begin: return("ide_dma_begin"); - case ide_dma_end: return("ide_dma_end:"); - case ide_dma_check: return("ide_dma_check"); - case ide_dma_on: return("ide_dma_on"); - case ide_dma_off: return("ide_dma_off"); - case ide_dma_off_quietly: return("ide_dma_off_quietly"); - case ide_dma_test_irq: return("ide_dma_test_irq"); - case ide_dma_host_on: return("ide_dma_host_on"); - case ide_dma_host_off: return("ide_dma_host_off"); - case ide_dma_bad_drive: return("ide_dma_bad_drive"); - case ide_dma_good_drive: return("ide_dma_good_drive"); - case ide_dma_verbose: return("ide_dma_verbose"); - case ide_dma_retune: return("ide_dma_retune"); - case ide_dma_lostirq: return("ide_dma_lostirq"); - case ide_dma_timeout: return("ide_dma_timeout"); - default: return("unknown"); - } -} - -/* - * An ide_tuneproc_t() is used to set the speed of an IDE interface - * to a particular PIO mode. The "byte" parameter is used - * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255 - * indicates that the interface driver should "auto-tune" the PIO mode - * according to the drive capabilities in drive->id; - * - * Not all interface types support tuning, and not all of those - * support all possible PIO settings. They may silently ignore - * or round values as they see fit. - */ -typedef void (ide_tuneproc_t) (ide_drive_t *, byte); -typedef int (ide_speedproc_t) (ide_drive_t *, byte); - -/* - * This is used to provide support for strange interfaces - */ -typedef void (ide_selectproc_t) (ide_drive_t *); -typedef void (ide_resetproc_t) (ide_drive_t *); -typedef int (ide_quirkproc_t) (ide_drive_t *); -typedef void (ide_intrproc_t) (ide_drive_t *); -typedef void (ide_maskproc_t) (ide_drive_t *, int); -typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t); - -/* - * ide soft-power support - */ -typedef int (ide_busproc_t) (ide_drive_t *, int); - #define IDE_CHIPSET_PCI_MASK \ ((1<> (c)) & 1) #ifdef CONFIG_BLK_DEV_IDEPCI -typedef struct ide_pci_devid_s { - unsigned short vid; - unsigned short did; -} ide_pci_devid_t; - -#define IDE_PCI_DEVID_NULL ((ide_pci_devid_t){0,0}) -#define IDE_PCI_DEVID_EQ(a,b) (a.vid == b.vid && a.did == b.did) +struct ide_pci_device_s; #endif /* CONFIG_BLK_DEV_IDEPCI */ typedef struct hwif_s { - struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ + struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ + struct hwif_s *mate; /* other hwif from same PCI chip */ struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ - ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ -/* - * FIXME!! need a generic register set :-/ PPC guys ideas?? - * - * ide_mmioreg_t mm_ports[IDE_NR_PORTS]; "task file registers" - * - */ + struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ + + char name[6]; /* name of interface, eg. "ide0" */ + + /* task file registers for pata and sata */ + ide_ioreg_t io_ports[IDE_NR_PORTS]; + sata_ioreg_t sata_scr[SATA_NR_PORTS]; + sata_ioreg_t sata_misc[SATA_NR_PORTS]; + hw_regs_t hw; /* Hardware info */ ide_drive_t drives[MAX_DRIVES]; /* drive info */ - int addressing; /* hosts addressing */ - void (*tuneproc)(ide_drive_t *, byte); /* routine to tune PIO mode for drives */ - int (*speedproc)(ide_drive_t *, byte); /* routine to retune DMA modes for drives */ - void (*selectproc)(ide_drive_t *); /* tweaks hardware to select drive */ - void (*resetproc)(ide_drive_t *); /* routine to reset controller after a disk reset */ - void (*intrproc)(ide_drive_t *); /* special interrupt handling for shared pci interrupts */ - void (*maskproc)(ide_drive_t *, int); /* special host masking for drive selection */ - int (*quirkproc)(ide_drive_t *); /* check host's drive quirk list */ - void (*rwproc)(ide_drive_t *, ide_dma_action_t); /* adjust timing based upon rq->cmd direction */ - void (*ideproc)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); /* CPU-polled transfer routine */ - int (*dmaproc)(ide_dma_action_t, ide_drive_t *); /* dma read/write/abort routine */ - int (*busproc)(ide_drive_t *, int); /* driver soft-power interface */ - unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */ - dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */ - struct scatterlist *sg_table; /* Scatter-gather list used to build the above */ + + u8 major; /* our major number */ + u8 index; /* 0 for ide0; 1 for ide1; ... */ + u8 channel; /* for dual-port chips: 0=primary, 1=secondary */ + u8 straight8; /* Alan's straight 8 check */ + u8 bus_state; /* power state of the IDE bus */ + + u8 atapi_dma; /* host supports atapi_dma */ + u8 ultra_mask; + u8 mwdma_mask; + u8 swdma_mask; + + hwif_chipset_t chipset; /* sub-module for tuning.. */ + +#ifdef CONFIG_BLK_DEV_IDEPCI + struct pci_dev *pci_dev; /* for pci chipsets */ + struct ide_pci_device_s *cds; /* chipset device struct */ +#endif /* CONFIG_BLK_DEV_IDEPCI */ + +#if 0 + ide_hwif_ops_t *hwifops; +#else + /* routine is for HBA specific IDENTITY operations */ + int (*identify)(ide_drive_t *); + /* routine to tune PIO mode for drives */ + void (*tuneproc)(ide_drive_t *, u8); + /* routine to retune DMA modes for drives */ + int (*speedproc)(ide_drive_t *, u8); + /* tweaks hardware to select drive */ + void (*selectproc)(ide_drive_t *); + /* chipset polling based on hba specifics */ + int (*reset_poll)(ide_drive_t *); + /* chipset specific changes to default for device-hba resets */ + void (*pre_reset)(ide_drive_t *); + /* routine to reset controller after a disk reset */ + void (*resetproc)(ide_drive_t *); + /* special interrupt handling for shared pci interrupts */ + void (*intrproc)(ide_drive_t *); + /* special host masking for drive selection */ + void (*maskproc)(ide_drive_t *, int); + /* check host's drive quirk list */ + int (*quirkproc)(ide_drive_t *); + /* driver soft-power interface */ + int (*busproc)(ide_drive_t *, int); +// /* host rate limiter */ +// u8 (*ratemask)(ide_drive_t *); +// /* device rate limiter */ +// u8 (*ratefilter)(ide_drive_t *, u8); +#endif + +#if 0 + ide_pio_ops_t *pioops; +#else + void (*ata_input_data)(ide_drive_t *, void *, u32); + void (*ata_output_data)(ide_drive_t *, void *, u32); + + void (*atapi_input_bytes)(ide_drive_t *, void *, u32); + void (*atapi_output_bytes)(ide_drive_t *, void *, u32); +#endif + +#if 0 + ide_dma_ops_t *dmaops; +#else + int (*ide_dma_read)(ide_drive_t *drive); + int (*ide_dma_write)(ide_drive_t *drive); + int (*ide_dma_begin)(ide_drive_t *drive); + int (*ide_dma_end)(ide_drive_t *drive); + int (*ide_dma_check)(ide_drive_t *drive); + int (*ide_dma_on)(ide_drive_t *drive); + int (*ide_dma_off)(ide_drive_t *drive); + int (*ide_dma_off_quietly)(ide_drive_t *drive); + int (*ide_dma_test_irq)(ide_drive_t *drive); + int (*ide_dma_host_on)(ide_drive_t *drive); + int (*ide_dma_host_off)(ide_drive_t *drive); + int (*ide_dma_bad_drive)(ide_drive_t *drive); + int (*ide_dma_good_drive)(ide_drive_t *drive); + int (*ide_dma_count)(ide_drive_t *drive); + int (*ide_dma_verbose)(ide_drive_t *drive); + int (*ide_dma_retune)(ide_drive_t *drive); + int (*ide_dma_lostirq)(ide_drive_t *drive); + int (*ide_dma_timeout)(ide_drive_t *drive); +#endif + +#if 0 + ide_io_ops_t *iops; +#else + void (*OUTB)(u8 addr, u32 port); + void (*OUTW)(u16 addr, u32 port); + void (*OUTL)(u32 addr, u32 port); + void (*OUTBP)(u8 addr, u32 port); + void (*OUTWP)(u16 addr, u32 port); + void (*OUTLP)(u32 addr, u32 port); + void (*OUTSW)(u32 port, void *addr, u32 count); + void (*OUTSWP)(u32 port, void *addr, u32 count); + void (*OUTSL)(u32 port, void *addr, u32 count); + void (*OUTSLP)(u32 port, void *addr, u32 count); + + u8 (*INB)(u32 port); + u16 (*INW)(u32 port); + u32 (*INL)(u32 port); + u8 (*INBP)(u32 port); + u16 (*INWP)(u32 port); + u32 (*INLP)(u32 port); + void (*INSW)(u32 port, void *addr, u32 count); + void (*INSWP)(u32 port, void *addr, u32 count); + void (*INSL)(u32 port, void *addr, u32 count); + void (*INSLP)(u32 port, void *addr, u32 count); +#endif + + /* dma physical region descriptor table (cpu view) */ + unsigned int *dmatable_cpu; + /* dma physical region descriptor table (dma view) */ + dma_addr_t dmatable_dma; + /* Scatter-gather list used to build the above */ + struct scatterlist *sg_table; int sg_nents; /* Current number of entries in it */ int sg_dma_direction; /* dma transfer direction */ int sg_dma_active; /* is it in use */ - struct hwif_s *mate; /* other hwif from same PCI chip */ + + int mmio; /* hosts iomio (0), mmio (1) or custom (2) select */ + int rqsize; /* max sectors per request */ + int addressing; /* hosts addressing */ + int irq; /* our irq number */ + int initializing; /* set while initializing self */ + + unsigned long dma_master; /* reference base addr dmabase */ unsigned long dma_base; /* base addr for dma ports */ + unsigned long dma_command; /* dma command register */ + unsigned long dma_vendor1; /* dma vendor 1 register */ + unsigned long dma_status; /* dma status register */ + unsigned long dma_vendor3; /* dma vendor 3 register */ + unsigned long dma_prdtable; /* actual prd table address */ + unsigned long dma_base2; /* extended base addr for dma ports */ + unsigned dma_extra; /* extra addr for dma ports */ unsigned long config_data; /* for use by chipset-specific code */ unsigned long select_data; /* for use by chipset-specific code */ - struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - int irq; /* our irq number */ - byte major; /* our major number */ - char name[6]; /* name of interface, eg. "ide0" */ - byte index; /* 0 for ide0; 1 for ide1; ... */ - hwif_chipset_t chipset; /* sub-module for tuning.. */ +#if (DISK_RECOVERY_TIME > 0) + unsigned long last_time; /* time when previous rq was done */ +#endif + + unsigned noprobe : 1; /* don't probe for this interface */ unsigned present : 1; /* this interface exists */ - unsigned serialized : 1; /* serialized operation with mate hwif */ + unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned reset : 1; /* reset after probe */ - unsigned autodma : 1; /* automatically try to enable DMA at boot */ + unsigned autodma : 1; /* auto-attempt using DMA at boot */ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ - unsigned no_highmem : 1; /* always use high i/o bounce */ - byte channel; /* for dual-port chips: 0=primary, 1=secondary */ -#ifdef CONFIG_BLK_DEV_IDEPCI - struct pci_dev *pci_dev; /* for pci chipsets */ - ide_pci_devid_t pci_devid; /* for pci chipsets: {VID,DID} */ -#endif /* CONFIG_BLK_DEV_IDEPCI */ -#if (DISK_RECOVERY_TIME > 0) - unsigned long last_time; /* time when previous rq was done */ -#endif - byte straight8; /* Alan's straight 8 check */ + unsigned highmem : 1; /* can do full 32-bit dma */ + unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */ + void *hwif_data; /* extra hwif data */ - byte bus_state; /* power state of the IDE bus */ } ide_hwif_t; /* @@ -769,7 +1082,7 @@ typedef struct hwif_s { */ typedef enum { ide_stopped, /* no drive operation was started */ - ide_started /* a drive operation was started, and a handler was set */ + ide_started /* a drive operation was started, handler was set */ } ide_startstop_t; /* @@ -778,26 +1091,41 @@ typedef enum { typedef ide_startstop_t (ide_pre_handler_t)(ide_drive_t *, struct request *); typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); typedef ide_startstop_t (ide_post_handler_t)(ide_drive_t *); - -/* - * when ide_timer_expiry fires, invoke a handler of this type - * to decide what to do. - */ typedef int (ide_expiry_t)(ide_drive_t *); typedef struct hwgroup_s { - ide_handler_t *handler;/* irq handler, if active */ - ide_handler_t *handler_save;/* irq handler, if active */ - volatile int busy; /* BOOL: protects all fields below */ - int sleeping; /* BOOL: wake us up on timer expiry */ - ide_drive_t *drive; /* current drive */ - ide_hwif_t *hwif; /* ptr to current hwif in linked-list */ - struct request *rq; /* current request */ - struct timer_list timer; /* failsafe timer */ - struct request wrq; /* local copy of current write rq */ - unsigned long poll_timeout; /* timeout value during long polls */ - ide_expiry_t *expiry; /* queried upon timeouts */ - int pio_clock; /* ide_system_bus_speed */ + /* irq handler, if active */ + ide_startstop_t (*handler)(ide_drive_t *); + /* irq handler, suspended if active */ + ide_startstop_t (*handler_save)(ide_drive_t *); + /* BOOL: protects all fields below */ + volatile int busy; + /* BOOL: wake us up on timer expiry */ + int sleeping; + /* current drive */ + ide_drive_t *drive; + /* ptr to current hwif in linked-list */ + ide_hwif_t *hwif; + +#ifdef CONFIG_BLK_DEV_IDEPCI + /* for pci chipsets */ + struct pci_dev *pci_dev; + /* chipset device struct */ + struct ide_pci_device_s *cds; +#endif /* CONFIG_BLK_DEV_IDEPCI */ + + /* current request */ + struct request *rq; + /* failsafe timer */ + struct timer_list timer; + /* local copy of current write rq */ + struct request wrq; + /* timeout value during long polls */ + unsigned long poll_timeout; + /* queried upon timeouts */ + int (*expiry)(ide_drive_t *); + /* ide_system_bus_speed */ + int pio_clock; } ide_hwgroup_t; /* structure attached to the request for IDE_TASK_CMDS */ @@ -850,14 +1178,14 @@ typedef struct { } ide_proc_entry_t; #ifdef CONFIG_PROC_FS -void proc_ide_create(void); -void proc_ide_destroy(void); -void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *); -void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *); -void destroy_proc_ide_drives(ide_hwif_t *); -void create_proc_ide_interfaces(void); -void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data); -void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p); +extern void proc_ide_create(void); +extern void proc_ide_destroy(void); +extern void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *); +extern void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *); +extern void destroy_proc_ide_drives(ide_hwif_t *); +extern void create_proc_ide_interfaces(void); +extern void ide_add_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *, void *); +extern void ide_remove_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *); read_proc_t proc_ide_read_capacity; read_proc_t proc_ide_read_geometry; @@ -889,7 +1217,7 @@ typedef struct ide_driver_s { struct module *owner; const char *name; const char *version; - byte media; + u8 media; unsigned busy : 1; unsigned supports_dma : 1; unsigned supports_dsc_overlap : 1; @@ -899,9 +1227,9 @@ typedef struct ide_driver_s { int (*resume)(ide_drive_t *); int (*flushcache)(ide_drive_t *); ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long); - int (*end_request)(ide_drive_t *, int); - byte (*sense)(ide_drive_t *, const char *, byte); - ide_startstop_t (*error)(ide_drive_t *, const char *, byte); + int (*end_request)(ide_drive_t *, int, int); + u8 (*sense)(ide_drive_t *, const char *, u8); + ide_startstop_t (*error)(ide_drive_t *, const char *, u8); int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); int (*open)(struct inode *, struct file *, ide_drive_t *); void (*release)(struct inode *, struct file *, ide_drive_t *); @@ -910,8 +1238,8 @@ typedef struct ide_driver_s { void (*pre_reset)(ide_drive_t *); unsigned long (*capacity)(ide_drive_t *); ide_startstop_t (*special)(ide_drive_t *); - ide_proc_entry_t *proc; - int (*reinit)(ide_drive_t *); + ide_proc_entry_t *proc; + int (*attach)(ide_drive_t *); void (*ata_prebuilder)(ide_drive_t *); void (*atapi_prebuilder)(ide_drive_t *); struct list_head drives; @@ -935,6 +1263,13 @@ typedef struct ide_module_s { struct ide_module_s *next; } ide_module_t; +typedef struct ide_devices_s { + char name[4]; /* hdX */ + unsigned attached : 1; /* native */ + unsigned alttached : 1; /* alternate */ + struct ide_devices_s *next; +} ide_devices_t; + /* * ide_hwifs[] is the master data structure used to keep track * of just about everything in ide.c. Whenever possible, routines @@ -945,7 +1280,15 @@ typedef struct ide_module_s { */ #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ +extern ide_module_t *ide_chipsets; extern ide_module_t *ide_probe; + +extern ide_devices_t *idedisk; +extern ide_devices_t *idecd; +extern ide_devices_t *idefloppy; +extern ide_devices_t *idetape; +extern ide_devices_t *idescsi; + #endif extern int noautodma; @@ -957,38 +1300,47 @@ extern int noautodma; #define DEVICE_NR(device) (minor(device) >> PARTN_BITS) #include -int ide_end_request (ide_drive_t *drive, int uptodate); +extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); /* * This is used on exit from the driver, to designate the next irq handler * and also to start the safety timer. */ -void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry); +extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry); /* * Error reporting, in human readable form (luxurious, but a memory hog). + * + * (drive, msg, status) */ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat); /* * ide_error() takes action based on the error returned by the controller. * The caller should return immediately after invoking this. + * + * (drive, msg, status) */ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat); /* * Issue a simple drive command * The drive must be selected beforehand. + * + * (drive, command, nsector, handler) */ -void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler); +extern void ide_cmd(ide_drive_t *, u8, u8, ide_handler_t *); +extern void ide_fix_driveid(struct hd_driveid *); /* * ide_fixstring() cleans up and (optionally) byte-swaps a text string, * removing leading/trailing blanks and compressing internal blanks. * It is primarily used to tidy up the model name/number fields as * returned by the WIN_[P]IDENTIFY commands. + * + * (s, bytecount, byteswap) */ -void ide_fixstring (byte *s, const int bytecount, const int byteswap); +extern void ide_fixstring(u8 *, const int, const int); /* * This routine busy-waits for the drive status to be not "busy". @@ -997,43 +1349,44 @@ void ide_fixstring (byte *s, const int bytecount, const int byteswap); * cases return 1 after doing "*startstop = ide_error()", and the * caller should return the updated value of "startstop" in this case. * "startstop" is unchanged when the function returns 0; + * (startstop, drive, good, bad, timeout) */ -int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout); +extern int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); /* * This routine is called from the partition-table code in genhd.c * to "convert" a drive to a logical geometry with fewer than 1024 cyls. */ -int ide_xlate_1024 (kdev_t, int, int, const char *); +extern int ide_xlate_1024 (kdev_t, int, int, const char *); /* * Convert kdev_t structure into ide_drive_t * one. */ -ide_drive_t *get_info_ptr (kdev_t i_rdev); +extern ide_drive_t *get_info_ptr (kdev_t i_rdev); /* * Return the current idea about the total capacity of this drive. */ -unsigned long current_capacity (ide_drive_t *drive); +extern unsigned long current_capacity (ide_drive_t *drive); -void ide_revalidate_drive (ide_drive_t *drive); +extern void ide_revalidate_drive (ide_drive_t *drive); /* * Start a reset operation for an IDE interface. * The caller should return immediately after invoking this. */ -ide_startstop_t ide_do_reset (ide_drive_t *); +extern ide_startstop_t ide_do_reset (ide_drive_t *); /* * Re-Start an operation for an IDE interface. * The caller should return immediately after invoking this. */ -int restart_request (ide_drive_t *, struct request *); +extern int restart_request (ide_drive_t *, struct request *); /* * This function is intended to be used prior to invoking ide_do_drive_cmd(). */ -void ide_init_drive_cmd (struct request *rq); +extern void ide_init_drive_cmd (struct request *rq); /* * "action" parameter type for ide_do_drive_cmd() below. @@ -1070,23 +1423,35 @@ typedef enum { * for the new rq to be completed. This is again intended for careful * use by the ATAPI tape/cdrom driver code. */ -int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action); +extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t); /* * Clean up after success/failure of an explicit drive cmd. * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD). * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK). + * + * (ide_drive_t *drive, u8 stat, u8 err) */ -void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err); +extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); /* - * Issue ATA command and wait for completion. use for implementing commands in kernel + * Issue ATA command and wait for completion. + * Use for implementing commands in kernel + * + * (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf) */ -int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf); +extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *); + +/* (ide_drive_t *drive, u8 *buf) */ +extern int ide_wait_cmd_task(ide_drive_t *, u8 *); -int ide_wait_cmd_task (ide_drive_t *drive, byte *buf); - typedef struct ide_task_s { +/* + * struct hd_drive_task_hdr tf; + * task_struct_t tf; + * struct hd_drive_hob_hdr hobf; + * hob_struct_t hobf; + */ task_ioreg_t tfRegister[8]; task_ioreg_t hobRegister[8]; ide_reg_valid_t tf_out_flags; @@ -1101,6 +1466,11 @@ typedef struct ide_task_s { } ide_task_t; typedef struct pkt_task_s { +/* + * struct hd_drive_task_hdr pktf; + * task_struct_t pktf; + * u8 pkcdb[12]; + */ task_ioreg_t tfRegister[8]; int data_phase; int command_type; @@ -1109,66 +1479,129 @@ typedef struct pkt_task_s { void *special; } pkt_task_t; -void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); -void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); +extern inline void SELECT_DRIVE(ide_drive_t *); +extern inline void SELECT_INTERRUPT(ide_drive_t *); +extern inline void SELECT_MASK(ide_drive_t *, int); +extern inline void QUIRK_LIST(ide_drive_t *); -int drive_is_ready (ide_drive_t *drive); -int wait_for_ready (ide_drive_t *drive, int timeout); +extern void ata_input_data(ide_drive_t *, void *, u32); +extern void ata_output_data(ide_drive_t *, void *, u32); +extern void atapi_input_bytes(ide_drive_t *, void *, u32); +extern void atapi_output_bytes(ide_drive_t *, void *, u32); +extern void taskfile_input_data(ide_drive_t *, void *, u32); +extern void taskfile_output_data(ide_drive_t *, void *, u32); + +extern int drive_is_ready(ide_drive_t *); +extern int wait_for_ready(ide_drive_t *, int /* timeout */); /* * taskfile io for disks for now...and builds request from ide_ioctl */ -ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task); +extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -void ide_end_taskfile (ide_drive_t *drive, byte stat, byte err); +/* (ide_drive_t *drive, u8 stat, u8 err) */ +extern void ide_end_taskfile(ide_drive_t *, u8, u8); /* * Special Flagged Register Validation Caller */ -ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task); - -ide_startstop_t set_multmode_intr (ide_drive_t *drive); -ide_startstop_t set_geometry_intr (ide_drive_t *drive); -ide_startstop_t recal_intr (ide_drive_t *drive); -ide_startstop_t task_no_data_intr (ide_drive_t *drive); -ide_startstop_t task_in_intr (ide_drive_t *drive); -ide_startstop_t task_mulin_intr (ide_drive_t *drive); -ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq); -ide_startstop_t task_out_intr (ide_drive_t *drive); -ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq); -ide_startstop_t task_mulout_intr (ide_drive_t *drive); -void ide_init_drive_taskfile (struct request *rq); - -int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *cmd, byte *buf); - -ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); -ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); -ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); +extern ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *); + +extern ide_startstop_t set_multmode_intr(ide_drive_t *); +extern ide_startstop_t set_geometry_intr(ide_drive_t *); +extern ide_startstop_t recal_intr(ide_drive_t *); +extern ide_startstop_t task_no_data_intr(ide_drive_t *); +extern ide_startstop_t task_in_intr(ide_drive_t *); +extern ide_startstop_t task_mulin_intr(ide_drive_t *); +extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); +extern ide_startstop_t task_out_intr(ide_drive_t *); +extern ide_startstop_t pre_task_mulout_intr(ide_drive_t *, struct request *); +extern ide_startstop_t task_mulout_intr(ide_drive_t *); +extern void ide_init_drive_taskfile(struct request *); + +extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *); + +extern ide_pre_handler_t * ide_pre_handler_parser(struct hd_drive_task_hdr *, struct hd_drive_hob_hdr *); + +extern ide_handler_t * ide_handler_parser(struct hd_drive_task_hdr *, struct hd_drive_hob_hdr *); + +extern ide_post_handler_t * ide_post_handler_parser(struct hd_drive_task_hdr *, struct hd_drive_hob_hdr *); + /* Expects args is a full set of TF registers and parses the command type */ -int ide_cmd_type_parser (ide_task_t *args); +extern int ide_cmd_type_parser(ide_task_t *); + +int ide_taskfile_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); +int ide_cmd_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); +int ide_task_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); + +#if 0 + +#define IDEFLOPPY_PC_BUFFER_SIZE 256 +#define IDETAPE_PC_BUFFER_SIZE 256 +#define IDE_PC_BUFFER_SIZE 256 + +typedef struct ide_packet_command_s { + /* Actual packet bytes */ + u8 c[12]; + /* On each retry, we increment retries */ + int retries; + /* Error code */ + int error; + /* Bytes to transfer */ + int request_transfer; + /* Bytes actually transferred */ + int actually_transferred; + /* Size of our data buffer */ + int buffer_size; + + struct buffer_head *bh; + u8 *b_data; + /* The corresponding request */ + struct request *rq; +# if 0 + /* Scatter gather table */ + struct scatterlist *sg; +# endif + int b_count; + /* Data buffer */ + u8 *buffer; + /* Pointer into the above buffer */ + u8 *current_position; + /* Called when this packet command is completed */ + ide_startstop_t (*callback) (ide_drive_t *); + /* Temporary buffer */ + u8 pc_buffer[IDE_PC_BUFFER_SIZE]; + /* Status/Action bit flags: long for set_bit */ + unsigned long flags; +} ide_pc_t; + +ide-cd orthoginal :-/ +struct packet_command { + char *buffer; + int buflen; + int stat; + int quiet; + int timeout; + struct request_sense *sense; + unsigned char c[12]; +}; -int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +#endif #ifdef CONFIG_PKT_TASK_IOCTL -int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +extern int pkt_taskfile_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); #endif /* CONFIG_PKT_TASK_IOCTL */ -void ide_delay_50ms (void); -int system_bus_clock(void); +extern void ide_delay_50ms(void); +extern int system_bus_clock(void); -byte ide_auto_reduce_xfer (ide_drive_t *drive); -int ide_driveid_update (ide_drive_t *drive); -int ide_ata66_check (ide_drive_t *drive, ide_task_t *args); -int ide_config_drive_speed (ide_drive_t *drive, byte speed); -byte eighty_ninty_three (ide_drive_t *drive); -int set_transfer (ide_drive_t *drive, ide_task_t *args); -int taskfile_lib_get_identify (ide_drive_t *drive, byte *buf); +extern u8 ide_auto_reduce_xfer(ide_drive_t *); +extern int ide_driveid_update(ide_drive_t *); +extern int ide_ata66_check(ide_drive_t *, ide_task_t *); +extern int ide_config_drive_speed(ide_drive_t *, u8); +extern u8 eighty_ninty_three (ide_drive_t *); +extern int set_transfer(ide_drive_t *, ide_task_t *); +extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *); /* * ide_system_bus_speed() returns what we think is the system VESA/PCI @@ -1176,45 +1609,55 @@ int taskfile_lib_get_identify (ide_drive_t *drive, byte *buf); * The default is 40 for known PCI systems, 50 otherwise. * The "idebus=xx" parameter can be used to override this value. */ -int ide_system_bus_speed (void); +extern int ide_system_bus_speed(void); /* * ide_stall_queue() can be used by a drive to give excess bandwidth back * to the hwgroup by sleeping for timeout jiffies. */ -void ide_stall_queue (ide_drive_t *drive, unsigned long timeout); +extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); /* * ide_get_queue() returns the queue which corresponds to a given device. */ -request_queue_t *ide_get_queue (kdev_t dev); +extern request_queue_t *ide_get_queue (kdev_t dev); /* * CompactFlash cards and their brethern pretend to be removable hard disks, * but they never have a slave unit, and they don't have doorlock mechanisms. - * This test catches them, and is invoked elsewhere when setting appropriate config bits. + * This test catches them, and is invoked elsewhere when setting appropriate + * config bits. */ -int drive_is_flashcard (ide_drive_t *drive); +extern int drive_is_flashcard (ide_drive_t *drive); -int ide_spin_wait_hwgroup (ide_drive_t *drive); -void ide_timer_expiry (unsigned long data); -void ide_intr (int irq, void *dev_id, struct pt_regs *regs); -void do_ide_request (request_queue_t * q); -void ide_init_subdrivers (void); +extern int ide_spin_wait_hwgroup(ide_drive_t *); +extern void ide_timer_expiry(unsigned long); +extern void ide_intr(int irq, void *dev_id, struct pt_regs *regs); +extern void do_ide_request(request_queue_t *); +extern void ide_init_subdrivers(void); #ifndef _IDE_C extern struct block_device_operations ide_fops[]; extern ide_proc_entry_t generic_subdriver_entries[]; #endif -int ata_attach(ide_drive_t *drive); +extern int ata_attach(ide_drive_t *); #ifdef _IDE_C #ifdef CONFIG_BLK_DEV_IDE -int ideprobe_init (void); +extern int ideprobe_init(void); + +#ifdef CONFIG_BLK_DEV_IDEPCI +extern void ide_scan_pcibus(int scan_direction) __init; +#endif /* CONFIG_BLK_DEV_IDEPCI */ + #endif /* CONFIG_BLK_DEV_IDE */ #endif /* _IDE_C */ +extern void default_hwif_iops(ide_hwif_t *); +extern void default_hwif_mmiops(ide_hwif_t *); +extern void default_hwif_transport(ide_hwif_t *); + int ide_register_driver(ide_driver_t *driver); void ide_unregister_driver(ide_driver_t *driver); int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int version); @@ -1222,85 +1665,113 @@ int ide_unregister_subdriver (ide_drive_t *drive); int ide_replace_subdriver(ide_drive_t *drive, const char *driver); #ifdef CONFIG_BLK_DEV_IDEPCI + +#ifdef CONFIG_PROC_FS +typedef struct ide_pci_host_proc_s { + char *name; + u8 set; + get_info_t *get_info; + struct proc_dir_entry *parent; + struct ide_pci_host_proc_s *next; +} ide_pci_host_proc_t; + +void ide_pci_register_host_proc(ide_pci_host_proc_t *); +#endif /* CONFIG_PROC_FS */ + #define ON_BOARD 1 #define NEVER_BOARD 0 + #ifdef CONFIG_BLK_DEV_OFFBOARD # define OFF_BOARD ON_BOARD #else /* CONFIG_BLK_DEV_OFFBOARD */ # define OFF_BOARD NEVER_BOARD #endif /* CONFIG_BLK_DEV_OFFBOARD */ +#define NODMA 0 +#define NOAUTODMA 1 +#define AUTODMA 2 +#define EOL 255 typedef struct ide_pci_enablebit_s { - byte reg; /* byte pci reg holding the enable-bit */ - byte mask; /* mask to isolate the enable-bit */ - byte val; /* value of masked reg when "enabled" */ + u8 reg; /* byte pci reg holding the enable-bit */ + u8 mask; /* mask to isolate the enable-bit */ + u8 val; /* value of masked reg when "enabled" */ } ide_pci_enablebit_t; typedef struct ide_pci_device_s { - ide_pci_devid_t devid; + u16 vendor; + u16 device; char *name; - void (*fixup_device)(struct pci_dev *, struct ide_pci_device_s *); + void (*init_setup)(struct pci_dev *, struct ide_pci_device_s *); unsigned int (*init_chipset)(struct pci_dev *, const char *); - unsigned int (*ata66_check)(ide_hwif_t *); - void (*init_hwif)(ide_hwif_t *); - void (*dma_init)(ide_hwif_t *, unsigned long); + void (*init_iops)(ide_hwif_t *); + void (*init_hwif)(ide_hwif_t *); + void (*init_dma)(ide_hwif_t *, unsigned long); + u8 channels; + u8 autodma; ide_pci_enablebit_t enablebits[2]; - byte bootable; + u8 bootable; unsigned int extra; + struct ide_pci_device_s *next; } ide_pci_device_t; #ifdef LINUX_PCI_H -extern inline void ide_register_xp_fix(struct pci_dev *dev) -{ - int i; - unsigned short cmd; - unsigned long flags; - unsigned long base_address[4] = { 0x1f0, 0x3f4, 0x170, 0x374 }; - - local_irq_save(flags); - pci_read_config_word(dev, PCI_COMMAND, &cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); - for (i=0; i<4; i++) { - dev->resource[i].start = 0; - dev->resource[i].end = 0; - dev->resource[i].flags = 0; - } - for (i=0; i<4; i++) { - dev->resource[i].start = base_address[i]; - dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; - pci_write_config_dword(dev, - (PCI_BASE_ADDRESS_0 + (i * 4)), - dev->resource[i].start); - } - pci_write_config_word(dev, PCI_COMMAND, cmd); - local_irq_restore(flags); -} - -void ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) __init; +extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); +extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *); #endif /* LINUX_PCI_H */ -unsigned long ide_find_free_region (unsigned short size) __init; -void ide_scan_pcibus (int scan_direction) __init; -#endif +#endif /* CONFIG_BLK_DEV_IDEPCI */ + #ifdef CONFIG_BLK_DEV_IDEDMA #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 -int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func); -void ide_destroy_dmatable (ide_drive_t *drive); -ide_startstop_t ide_dma_intr (ide_drive_t *drive); -int check_drive_lists (ide_drive_t *drive, int good_bad); -int report_drive_dmaing (ide_drive_t *drive); -int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive); -int ide_release_dma (ide_hwif_t *hwif); -void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init; -unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init; -#endif /* CONFIG_BLK_DEV_IDEPCI */ +extern int ide_build_dmatable(ide_drive_t *, struct request *); +extern void ide_destroy_dmatable(ide_drive_t *); +extern ide_startstop_t ide_dma_intr(ide_drive_t *); +extern int ide_release_dma(ide_hwif_t *); +extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); + +extern int __ide_dma_host_off(ide_drive_t *); +extern int __ide_dma_off_quietly(ide_drive_t *); +extern int __ide_dma_off(ide_drive_t *); +extern int __ide_dma_host_on(ide_drive_t *); +extern int __ide_dma_on(ide_drive_t *); +extern int __ide_dma_check(ide_drive_t *); +extern int __ide_dma_read(ide_drive_t *); +extern int __ide_dma_write(ide_drive_t *); +extern int __ide_dma_begin(ide_drive_t *); +extern int __ide_dma_end(ide_drive_t *); +extern int __ide_dma_test_irq(ide_drive_t *); +extern int __ide_dma_bad_drive(ide_drive_t *); +extern int __ide_dma_good_drive(ide_drive_t *); +extern int __ide_dma_count(ide_drive_t *); +extern int __ide_dma_verbose(ide_drive_t *); +extern int __ide_dma_retune(ide_drive_t *); +extern int __ide_dma_lostirq(ide_drive_t *); +extern int __ide_dma_timeout(ide_drive_t *); +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +extern void hwif_unregister(ide_hwif_t *); + +extern void export_ide_init_queue(ide_drive_t *); +extern u8 export_probe_for_drive(ide_drive_t *); +extern int probe_hwif_init(ide_hwif_t *); + +static inline void *ide_get_hwifdata (ide_hwif_t * hwif) +{ + return hwif->hwif_data; +} -void hwif_unregister (ide_hwif_t *hwif); +static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data) +{ + hwif->hwif_data = data; +} -void export_ide_init_queue (ide_drive_t *drive); -byte export_probe_for_drive (ide_drive_t *drive); +/* ide-lib.c */ +extern u8 ide_dma_speed(ide_drive_t *drive, u8 mode); +extern u8 ide_rate_filter(u8 mode, u8 speed); +extern int ide_dma_enable(ide_drive_t *drive); +extern char *ide_xfer_verbose(u8 xfer_rate); extern spinlock_t ide_lock; -- cgit v1.2.3