summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2003-10-21 10:36:10 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2003-10-21 10:36:10 -0700
commitd2cf3bd5b6a4a9a0eb2211a4fe628a7fa2438e9b (patch)
treeeb5e94eeea7baee1497f3a2d22bae4e624375517 /include/linux
parent887b31a4b14156f85613cf6d5e15f17bf9751e51 (diff)
parent4c7741125135293d76a811a2b0ebbbecf2a034b8 (diff)
Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
into nuts.ninka.net:/disk1/davem/BK/net-2.5
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ata.h179
-rw-r--r--include/linux/ioport.h1
-rw-r--r--include/linux/libata.h567
3 files changed, 747 insertions, 0 deletions
diff --git a/include/linux/ata.h b/include/linux/ata.h
new file mode 100644
index 000000000000..b4b4543bee53
--- /dev/null
+++ b/include/linux/ata.h
@@ -0,0 +1,179 @@
+
+/*
+ Copyright 2003 Red Hat, Inc. All rights reserved.
+ Copyright 2003 Jeff Garzik
+
+ The contents of this file are subject to the Open
+ Software License version 1.1 that can be found at
+ http://www.opensource.org/licenses/osl-1.1.txt and is included herein
+ by reference.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the GNU General Public License version 2 (the "GPL") as distributed
+ in the kernel source COPYING file, in which case the provisions of
+ the GPL are applicable instead of the above. If you wish to allow
+ the use of your version of this file only under the terms of the
+ GPL and not to allow others to use your version of this file under
+ the OSL, indicate your decision by deleting the provisions above and
+ replace them with the notice and other provisions required by the GPL.
+ If you do not delete the provisions above, a recipient may use your
+ version of this file under either the OSL or the GPL.
+
+ */
+
+#ifndef __LINUX_ATA_H__
+#define __LINUX_ATA_H__
+
+/* defines only for the constants which don't work well as enums */
+#define ATA_DMA_BOUNDARY 0xffffUL
+#define ATA_DMA_MASK 0xffffffffULL
+
+enum {
+ /* various global constants */
+ ATA_MAX_DEVICES = 2, /* per bus/port */
+ ATA_MAX_PRD = 256, /* we could make these 256/256 */
+ ATA_SECT_SIZE = 512,
+ ATA_SECT_SIZE_MASK = (ATA_SECT_SIZE - 1),
+ ATA_SECT_DWORDS = ATA_SECT_SIZE / sizeof(u32),
+
+ ATA_ID_WORDS = 256,
+ ATA_ID_PROD_OFS = 27,
+ ATA_ID_SERNO_OFS = 10,
+ ATA_ID_MAJOR_VER = 80,
+ ATA_ID_PIO_MODES = 64,
+ ATA_ID_UDMA_MODES = 88,
+ ATA_ID_PIO4 = (1 << 1),
+
+ ATA_PCI_CTL_OFS = 2,
+ ATA_SERNO_LEN = 20,
+ ATA_UDMA0 = (1 << 0),
+ ATA_UDMA1 = ATA_UDMA0 | (1 << 1),
+ ATA_UDMA2 = ATA_UDMA1 | (1 << 2),
+ ATA_UDMA3 = ATA_UDMA2 | (1 << 3),
+ ATA_UDMA4 = ATA_UDMA3 | (1 << 4),
+ ATA_UDMA5 = ATA_UDMA4 | (1 << 5),
+ ATA_UDMA6 = ATA_UDMA5 | (1 << 6),
+ ATA_UDMA7 = ATA_UDMA6 | (1 << 7),
+ /* ATA_UDMA7 is just for completeness... doesn't exist (yet?). */
+
+ ATA_UDMA_MASK_40C = ATA_UDMA2, /* udma0-2 */
+
+ /* DMA-related */
+ ATA_PRD_SZ = 8,
+ ATA_PRD_TBL_SZ = (ATA_MAX_PRD * ATA_PRD_SZ),
+ ATA_PRD_EOT = (1 << 31), /* end-of-table flag */
+
+ ATA_DMA_TABLE_OFS = 4,
+ ATA_DMA_STATUS = 2,
+ ATA_DMA_CMD = 0,
+ ATA_DMA_WR = (1 << 3),
+ ATA_DMA_START = (1 << 0),
+ ATA_DMA_INTR = (1 << 2),
+ ATA_DMA_ERR = (1 << 1),
+ ATA_DMA_ACTIVE = (1 << 0),
+
+ /* bits in ATA command block registers */
+ ATA_HOB = (1 << 7), /* LBA48 selector */
+ ATA_NIEN = (1 << 1), /* disable-irq flag */
+ ATA_LBA = (1 << 6), /* LBA28 selector */
+ ATA_DEV1 = (1 << 4), /* Select Device 1 (slave) */
+ ATA_BUSY = (1 << 7), /* BSY status bit */
+ ATA_DEVICE_OBS = (1 << 7) | (1 << 5), /* obs bits in dev reg */
+ ATA_DEVCTL_OBS = (1 << 3), /* obsolete bit in devctl reg */
+ ATA_DRQ = (1 << 3), /* data request i/o */
+ ATA_ERR = (1 << 0), /* have an error */
+ ATA_SRST = (1 << 2), /* software reset */
+ ATA_ABORTED = (1 << 2), /* command aborted */
+
+ /* ATA command block registers */
+ ATA_REG_DATA = 0x00,
+ ATA_REG_ERR = 0x01,
+ ATA_REG_NSECT = 0x02,
+ ATA_REG_LBAL = 0x03,
+ ATA_REG_LBAM = 0x04,
+ ATA_REG_LBAH = 0x05,
+ ATA_REG_DEVICE = 0x06,
+ ATA_REG_STATUS = 0x07,
+
+ ATA_REG_FEATURE = ATA_REG_ERR, /* and their aliases */
+ ATA_REG_CMD = ATA_REG_STATUS,
+ ATA_REG_BYTEL = ATA_REG_LBAM,
+ ATA_REG_BYTEH = ATA_REG_LBAH,
+ ATA_REG_DEVSEL = ATA_REG_DEVICE,
+ ATA_REG_IRQ = ATA_REG_NSECT,
+
+ /* ATA taskfile protocols */
+ ATA_PROT_UNKNOWN = 0,
+ ATA_PROT_NODATA = 1,
+ ATA_PROT_PIO_READ = 2,
+ ATA_PROT_PIO_WRITE = 3,
+ ATA_PROT_DMA_READ = 4,
+ ATA_PROT_DMA_WRITE = 5,
+ ATA_PROT_ATAPI = 6,
+ ATA_PROT_ATAPI_DMA = 7,
+
+ /* ATA device commands */
+ ATA_CMD_EDD = 0x90, /* execute device diagnostic */
+ ATA_CMD_ID_ATA = 0xEC,
+ ATA_CMD_ID_ATAPI = 0xA1,
+ ATA_CMD_READ = 0xC8,
+ ATA_CMD_READ_EXT = 0x25,
+ ATA_CMD_WRITE = 0xCA,
+ ATA_CMD_WRITE_EXT = 0x35,
+ ATA_CMD_PIO_READ = 0x20,
+ ATA_CMD_PIO_READ_EXT = 0x24,
+ ATA_CMD_PIO_WRITE = 0x30,
+ ATA_CMD_PIO_WRITE_EXT = 0x34,
+ ATA_CMD_SET_FEATURES = 0xEF,
+ ATA_CMD_PACKET = 0xA0,
+
+ /* SETFEATURES stuff */
+ SETFEATURES_XFER = 0x03,
+ XFER_UDMA_7 = 0x47,
+ XFER_UDMA_6 = 0x46,
+ XFER_UDMA_5 = 0x45,
+ XFER_UDMA_4 = 0x44,
+ XFER_UDMA_3 = 0x43,
+ XFER_UDMA_2 = 0x42,
+ XFER_UDMA_1 = 0x41,
+ XFER_UDMA_0 = 0x40,
+ XFER_PIO_4 = 0x0C,
+ XFER_PIO_3 = 0x0B,
+
+ /* ATAPI stuff */
+ ATAPI_PKT_DMA = (1 << 0),
+
+ /* cable types */
+ ATA_CBL_NONE = 0,
+ ATA_CBL_PATA40 = 1,
+ ATA_CBL_PATA80 = 2,
+ ATA_CBL_PATA_UNK = 3,
+ ATA_CBL_SATA = 4,
+
+ /* SATA Status and Control Registers */
+ SCR_STATUS = 0,
+ SCR_ERROR = 1,
+ SCR_CONTROL = 2,
+ SCR_ACTIVE = 3,
+ SCR_NOTIFICATION = 4,
+};
+
+/* core structures */
+struct ata_prd {
+ u32 addr;
+ u32 flags_len;
+} __attribute__((packed));
+
+#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
+#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
+#define ata_id_has_lba(dev) ((dev)->id[49] & (1 << 8))
+#define ata_id_has_dma(dev) ((dev)->id[49] & (1 << 9))
+#define ata_id_u32(dev,n) \
+ (((u32) (dev)->id[(n) + 1] << 16) | ((u32) (dev)->id[(n)]))
+#define ata_id_u64(dev,n) \
+ ( ((u64) dev->id[(n) + 3] << 48) | \
+ ((u64) dev->id[(n) + 2] << 32) | \
+ ((u64) dev->id[(n) + 1] << 16) | \
+ ((u64) dev->id[(n) + 0]) )
+
+#endif /* __LINUX_ATA_H__ */
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 236fce32581d..5ad913d3cd96 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -89,6 +89,7 @@ extern struct resource iomem_resource;
extern int get_resource_list(struct resource *, char *buf, int size);
extern int request_resource(struct resource *root, struct resource *new);
+extern struct resource * ____request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
extern int insert_resource(struct resource *parent, struct resource *new);
extern int allocate_resource(struct resource *root, struct resource *new,
diff --git a/include/linux/libata.h b/include/linux/libata.h
new file mode 100644
index 000000000000..a8377cb315ef
--- /dev/null
+++ b/include/linux/libata.h
@@ -0,0 +1,567 @@
+/*
+ Copyright 2003 Red Hat, Inc. All rights reserved.
+ Copyright 2003 Jeff Garzik
+
+ The contents of this file are subject to the Open
+ Software License version 1.1 that can be found at
+ http://www.opensource.org/licenses/osl-1.1.txt and is included herein
+ by reference.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the GNU General Public License version 2 (the "GPL") as distributed
+ in the kernel source COPYING file, in which case the provisions of
+ the GPL are applicable instead of the above. If you wish to allow
+ the use of your version of this file only under the terms of the
+ GPL and not to allow others to use your version of this file under
+ the OSL, indicate your decision by deleting the provisions above and
+ replace them with the notice and other provisions required by the GPL.
+ If you do not delete the provisions above, a recipient may use your
+ version of this file under either the OSL or the GPL.
+
+ */
+
+#ifndef __LINUX_LIBATA_H__
+#define __LINUX_LIBATA_H__
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <linux/ata.h>
+
+/*
+ * compile-time options
+ */
+#undef ATA_FORCE_PIO /* do not configure or use DMA */
+#undef ATA_DEBUG /* debugging output */
+#undef ATA_VERBOSE_DEBUG /* yet more debugging output */
+#undef ATA_IRQ_TRAP /* define to ack screaming irqs */
+#undef ATA_NDEBUG /* define to disable quick runtime checks */
+#undef ATA_ENABLE_ATAPI /* define to enable ATAPI support */
+#undef ATA_ENABLE_PATA /* define to enable PATA support in some
+ * low-level drivers */
+
+
+/* note: prints function name for you */
+#ifdef ATA_DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
+#ifdef ATA_VERBOSE_DEBUG
+#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
+#else
+#define VPRINTK(fmt, args...)
+#endif /* ATA_VERBOSE_DEBUG */
+#else
+#define DPRINTK(fmt, args...)
+#define VPRINTK(fmt, args...)
+#endif /* ATA_DEBUG */
+
+#ifdef ATA_NDEBUG
+#define assert(expr)
+#else
+#define assert(expr) \
+ if(unlikely(!(expr))) { \
+ printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
+ #expr,__FILE__,__FUNCTION__,__LINE__); \
+ }
+#endif
+
+/* defines only for the constants which don't work well as enums */
+#define ATA_TAG_POISON 0xfafbfcfdU
+#define ATA_DMA_BOUNDARY 0xffffUL
+#define ATA_DMA_MASK 0xffffffffULL
+
+enum {
+ /* various global constants */
+ ATA_MAX_PORTS = 8,
+ ATA_DEF_QUEUE = 1,
+ ATA_MAX_QUEUE = 1,
+ ATA_MAX_SECTORS = 200, /* FIXME */
+ ATA_MAX_BUS = 2,
+ ATA_DEF_BUSY_WAIT = 10000,
+ ATA_SHORT_PAUSE = (HZ >> 6) + 1,
+
+ ATA_SHT_EMULATED = 1,
+ ATA_SHT_CMD_PER_LUN = 1,
+ ATA_SHT_THIS_ID = -1,
+ ATA_SHT_USE_CLUSTERING = 1,
+
+ /* struct ata_device stuff */
+ ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */
+ ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */
+ ATA_DFLAG_MASTER = (1 << 2), /* is device 0? */
+ ATA_DFLAG_WCACHE = (1 << 3), /* has write cache we can
+ * (hopefully) flush? */
+
+ ATA_DEV_UNKNOWN = 0, /* unknown device */
+ ATA_DEV_ATA = 1, /* ATA device */
+ ATA_DEV_ATA_UNSUP = 2, /* ATA device (unsupported) */
+ ATA_DEV_ATAPI = 3, /* ATAPI device */
+ ATA_DEV_ATAPI_UNSUP = 4, /* ATAPI device (unsupported) */
+ ATA_DEV_NONE = 5, /* no device */
+
+ /* struct ata_port flags */
+ ATA_FLAG_SLAVE_POSS = (1 << 1), /* host supports slave dev */
+ /* (doesn't imply presence) */
+ ATA_FLAG_PORT_DISABLED = (1 << 2), /* port is disabled, ignore it */
+ ATA_FLAG_SATA = (1 << 3),
+ ATA_FLAG_NO_LEGACY = (1 << 4), /* no legacy mode check */
+ ATA_FLAG_SRST = (1 << 5), /* use ATA SRST, not E.D.D. */
+ ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */
+ ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */
+
+ /* struct ata_taskfile flags */
+ ATA_TFLAG_LBA48 = (1 << 0),
+ ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
+ ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
+
+ ATA_QCFLAG_WRITE = (1 << 0), /* read==0, write==1 */
+ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
+ ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */
+ ATA_QCFLAG_ATAPI = (1 << 3), /* is ATAPI packet command? */
+ ATA_QCFLAG_SG = (1 << 4), /* have s/g table? */
+ ATA_QCFLAG_POLL = (1 << 5), /* polling, no interrupts */
+
+ /* struct ata_engine atomic flags (use test_bit, etc.) */
+ ATA_EFLG_ACTIVE = 0, /* engine is active */
+
+ /* various lengths of time */
+ ATA_TMOUT_EDD = 5 * HZ, /* hueristic */
+ ATA_TMOUT_PIO = 30 * HZ,
+ ATA_TMOUT_BOOT = 30 * HZ, /* hueristic */
+ ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* hueristic */
+ ATA_TMOUT_CDB = 30 * HZ,
+ ATA_TMOUT_CDB_QUICK = 5 * HZ,
+
+ /* ATA bus states */
+ BUS_UNKNOWN = 0,
+ BUS_DMA = 1,
+ BUS_IDLE = 2,
+ BUS_NOINTR = 3,
+ BUS_NODATA = 4,
+ BUS_TIMER = 5,
+ BUS_PIO = 6,
+ BUS_EDD = 7,
+ BUS_IDENTIFY = 8,
+ BUS_PACKET = 9,
+
+ /* thread states */
+ THR_UNKNOWN = 0,
+ THR_PORT_RESET = (THR_UNKNOWN + 1),
+ THR_AWAIT_DEATH = (THR_PORT_RESET + 1),
+ THR_PROBE_FAILED = (THR_AWAIT_DEATH + 1),
+ THR_IDLE = (THR_PROBE_FAILED + 1),
+ THR_PROBE_SUCCESS = (THR_IDLE + 1),
+ THR_PROBE_START = (THR_PROBE_SUCCESS + 1),
+ THR_PIO_POLL = (THR_PROBE_START + 1),
+ THR_PIO_TMOUT = (THR_PIO_POLL + 1),
+ THR_PIO = (THR_PIO_TMOUT + 1),
+ THR_PIO_LAST = (THR_PIO + 1),
+ THR_PIO_LAST_POLL = (THR_PIO_LAST + 1),
+ THR_PIO_ERR = (THR_PIO_LAST_POLL + 1),
+ THR_PACKET = (THR_PIO_ERR + 1),
+
+ /* SATA port states */
+ PORT_UNKNOWN = 0,
+ PORT_ENABLED = 1,
+ PORT_DISABLED = 2,
+
+ /* ata_qc_cb_t flags - note uses above ATA_QCFLAG_xxx namespace,
+ * but not numberspace
+ */
+ ATA_QCFLAG_TIMEOUT = (1 << 0),
+};
+
+/* forward declarations */
+struct ata_port_operations;
+struct ata_port;
+struct ata_queued_cmd;
+
+/* typedefs */
+typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int flags);
+
+struct ata_ioports {
+ unsigned long cmd_addr;
+ unsigned long data_addr;
+ unsigned long error_addr;
+ unsigned long nsect_addr;
+ unsigned long lbal_addr;
+ unsigned long lbam_addr;
+ unsigned long lbah_addr;
+ unsigned long device_addr;
+ unsigned long cmdstat_addr;
+ unsigned long ctl_addr;
+ unsigned long bmdma_addr;
+ unsigned long scr_addr;
+};
+
+struct ata_probe_ent {
+ struct list_head node;
+ struct pci_dev *pdev;
+ struct ata_port_operations *port_ops;
+ Scsi_Host_Template *sht;
+ struct ata_ioports port[ATA_MAX_PORTS];
+ unsigned int n_ports;
+ unsigned int pio_mask;
+ unsigned int udma_mask;
+ unsigned int legacy_mode;
+ unsigned long irq;
+ unsigned int irq_flags;
+ unsigned long host_flags;
+ void *mmio_base;
+};
+
+struct ata_host_set {
+ spinlock_t lock;
+ struct pci_dev *pdev;
+ unsigned long irq;
+ void *mmio_base;
+ unsigned int n_ports;
+ struct ata_port * ports[0];
+};
+
+struct ata_taskfile {
+ unsigned long flags; /* ATA_TFLAG_xxx */
+ u8 protocol; /* ATA_PROT_xxx */
+
+ u8 ctl; /* control reg */
+
+ u8 hob_feature; /* additional data */
+ u8 hob_nsect; /* to support LBA48 */
+ u8 hob_lbal;
+ u8 hob_lbam;
+ u8 hob_lbah;
+
+ u8 feature;
+ u8 nsect;
+ u8 lbal;
+ u8 lbam;
+ u8 lbah;
+
+ u8 device;
+
+ u8 command; /* IO operation */
+};
+
+struct ata_queued_cmd {
+ struct ata_port *ap;
+ struct ata_device *dev;
+
+ Scsi_Cmnd *scsicmd;
+ void (*scsidone)(Scsi_Cmnd *);
+
+ struct list_head node;
+ unsigned long flags; /* ATA_QCFLAG_xxx */
+ unsigned int tag;
+ unsigned int n_elem;
+ unsigned int nsect;
+ unsigned int cursect;
+ unsigned int cursg;
+ unsigned int cursg_ofs;
+ struct ata_taskfile tf;
+ struct scatterlist sgent;
+
+ struct scatterlist *sg;
+
+ ata_qc_cb_t callback;
+
+ struct semaphore sem;
+};
+
+struct ata_host_stats {
+ unsigned long unhandled_irq;
+ unsigned long idle_irq;
+ unsigned long rw_reqbuf;
+};
+
+struct ata_device {
+ u64 n_sectors; /* size of device, if ATA */
+ unsigned long flags; /* ATA_DFLAG_xxx */
+ unsigned int class; /* ATA_DEV_xxx */
+ unsigned int devno; /* 0 or 1 */
+ u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
+ unsigned int pio_mode;
+ unsigned int udma_mode;
+
+ unsigned char vendor[8]; /* space-padded, not ASCIIZ */
+ unsigned char product[32]; /* WARNING: shorter than
+ * ATAPI7 spec size, 40 ASCII
+ * characters
+ */
+};
+
+struct ata_engine {
+ unsigned long flags;
+ struct list_head q;
+};
+
+struct ata_port {
+ struct Scsi_Host *host; /* our co-allocated scsi host */
+ struct ata_port_operations *ops;
+ unsigned long flags; /* ATA_FLAG_xxx */
+ unsigned int id; /* unique id req'd by scsi midlyr */
+ unsigned int port_no; /* unique port #; from zero */
+
+ struct ata_prd *prd; /* our SG list */
+ dma_addr_t prd_dma; /* and its DMA mapping */
+
+ struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
+
+ u8 ctl; /* cache of ATA control register */
+ unsigned int bus_state;
+ unsigned int port_state;
+ unsigned int pio_mask;
+ unsigned int udma_mask;
+ unsigned int cbl; /* cable type; ATA_CBL_xxx */
+
+ struct ata_engine eng;
+
+ struct ata_device device[ATA_MAX_DEVICES];
+
+ struct ata_queued_cmd qcmd[ATA_MAX_QUEUE];
+ unsigned long qactive;
+ unsigned int active_tag;
+
+ struct ata_host_stats stats;
+ struct ata_host_set *host_set;
+
+ struct semaphore sem;
+ struct semaphore probe_sem;
+
+ unsigned int thr_state;
+ int time_to_die;
+ pid_t thr_pid;
+ struct completion thr_exited;
+ struct semaphore thr_sem;
+ struct timer_list thr_timer;
+ unsigned long thr_timeout;
+};
+
+struct ata_port_operations {
+ void (*port_disable) (struct ata_port *);
+
+ void (*dev_config) (struct ata_port *, struct ata_device *);
+
+ void (*set_piomode) (struct ata_port *, struct ata_device *,
+ unsigned int);
+ void (*set_udmamode) (struct ata_port *, struct ata_device *,
+ unsigned int);
+
+ void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+
+ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+ u8 (*check_status)(struct ata_port *ap);
+
+ void (*phy_reset) (struct ata_port *ap);
+ void (*phy_config) (struct ata_port *ap);
+
+ void (*bmdma_start) (struct ata_queued_cmd *qc);
+ void (*fill_sg) (struct ata_queued_cmd *qc);
+ void (*eng_timeout) (struct ata_port *ap);
+
+ irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
+
+ u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
+ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
+ u32 val);
+};
+
+struct ata_port_info {
+ Scsi_Host_Template *sht;
+ unsigned long host_flags;
+ unsigned long pio_mask;
+ unsigned long udma_mask;
+ struct ata_port_operations *port_ops;
+};
+
+struct pci_bits {
+ unsigned int reg; /* PCI config register to read */
+ unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
+ unsigned long mask;
+ unsigned long val;
+};
+
+extern void ata_port_probe(struct ata_port *);
+extern void pata_phy_config(struct ata_port *ap);
+extern void sata_phy_reset(struct ata_port *ap);
+extern void ata_bus_reset(struct ata_port *ap);
+extern void ata_port_disable(struct ata_port *);
+extern void ata_std_ports(struct ata_ioports *ioaddr);
+extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
+ unsigned int n_ports);
+extern void ata_pci_remove_one (struct pci_dev *pdev);
+extern int ata_device_add(struct ata_probe_ent *ent);
+extern int ata_scsi_detect(Scsi_Host_Template *sht);
+extern int ata_scsi_queuecmd(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
+extern int ata_scsi_error(struct Scsi_Host *host);
+extern int ata_scsi_release(struct Scsi_Host *host);
+extern int ata_scsi_slave_config(struct scsi_device *sdev);
+/*
+ * Default driver ops implementations
+ */
+extern void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+extern u8 ata_check_status_pio(struct ata_port *ap);
+extern u8 ata_check_status_mmio(struct ata_port *ap);
+extern void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+extern void ata_fill_sg(struct ata_queued_cmd *qc);
+extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
+extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
+extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
+extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat, unsigned int done_late);
+extern void ata_eng_timeout(struct ata_port *ap);
+
+
+static inline unsigned long msecs_to_jiffies(unsigned long msecs)
+{
+ return ((HZ * msecs + 999) / 1000);
+}
+
+static inline unsigned int ata_tag_valid(unsigned int tag)
+{
+ return (tag < ATA_MAX_QUEUE) ? 1 : 0;
+}
+
+static inline unsigned int ata_dev_present(struct ata_device *dev)
+{
+ return ((dev->class == ATA_DEV_ATA) ||
+ (dev->class == ATA_DEV_ATAPI));
+}
+
+static inline u8 ata_chk_err(struct ata_port *ap)
+{
+ if (ap->flags & ATA_FLAG_MMIO) {
+ return readb((void *) ap->ioaddr.error_addr);
+ }
+ return inb(ap->ioaddr.error_addr);
+}
+
+static inline u8 ata_chk_status(struct ata_port *ap)
+{
+ return ap->ops->check_status(ap);
+}
+
+static inline u8 ata_altstatus(struct ata_port *ap)
+{
+ if (ap->flags & ATA_FLAG_MMIO)
+ return readb(ap->ioaddr.ctl_addr);
+ return inb(ap->ioaddr.ctl_addr);
+}
+
+static inline void ata_pause(struct ata_port *ap)
+{
+ ata_altstatus(ap);
+ ndelay(400);
+}
+
+static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
+ unsigned int max)
+{
+ u8 status;
+
+ do {
+ udelay(10);
+ status = ata_chk_status(ap);
+ max--;
+ } while ((status & bits) && (max > 0));
+
+ return status;
+}
+
+static inline u8 ata_wait_idle(struct ata_port *ap)
+{
+ u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+
+ if (status & (ATA_BUSY | ATA_DRQ)) {
+ unsigned long l = ap->ioaddr.cmdstat_addr;
+ printk(KERN_WARNING
+ "ATA: abnormal status 0x%X on port 0x%lX\n",
+ status, l);
+ }
+
+ return status;
+}
+
+static inline struct ata_queued_cmd *ata_qc_from_tag (struct ata_port *ap,
+ unsigned int tag)
+{
+ if (likely(ata_tag_valid(tag)))
+ return &ap->qcmd[tag];
+ return NULL;
+}
+
+static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, unsigned int device)
+{
+ memset(tf, 0, sizeof(*tf));
+
+ tf->ctl = ap->ctl;
+ if (device == 0)
+ tf->device = ATA_DEVICE_OBS;
+ else
+ tf->device = ATA_DEVICE_OBS | ATA_DEV1;
+}
+
+static inline u8 ata_irq_on(struct ata_port *ap)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ ap->ctl &= ~ATA_NIEN;
+
+ if (ap->flags & ATA_FLAG_MMIO)
+ writeb(ap->ctl, ioaddr->ctl_addr);
+ else
+ outb(ap->ctl, ioaddr->ctl_addr);
+
+ return ata_wait_idle(ap);
+}
+
+static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
+{
+ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
+ u8 host_stat, post_stat, status;
+
+ status = ata_busy_wait(ap, bits, 1000);
+ if (status & bits)
+ DPRINTK("abnormal status 0x%X\n", status);
+
+ /* get controller status; clear intr, err bits */
+ if (ap->flags & ATA_FLAG_MMIO) {
+ void *mmio = (void *) ap->ioaddr.bmdma_addr;
+ host_stat = readb(mmio + ATA_DMA_STATUS);
+ writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ mmio + ATA_DMA_STATUS);
+
+ post_stat = readb(mmio + ATA_DMA_STATUS);
+ } else {
+ host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+
+ post_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ }
+
+ VPRINTK("irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
+ host_stat, post_stat, status);
+
+ return status;
+}
+
+static inline u32 scr_read(struct ata_port *ap, unsigned int reg)
+{
+ return ap->ops->scr_read(ap, reg);
+}
+
+static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val)
+{
+ ap->ops->scr_write(ap, reg, val);
+}
+
+static inline unsigned int sata_dev_present(struct ata_port *ap)
+{
+ return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
+}
+
+#endif /* __LINUX_LIBATA_H__ */