| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Jeff Garzik | af36d7f | 2005-08-28 20:18:39 -0400 | [diff] [blame] | 2 | *  Copyright 2003-2005 Red Hat, Inc.  All rights reserved. | 
|  | 3 | *  Copyright 2003-2005 Jeff Garzik | 
|  | 4 | * | 
|  | 5 | * | 
|  | 6 | *  This program is free software; you can redistribute it and/or modify | 
|  | 7 | *  it under the terms of the GNU General Public License as published by | 
|  | 8 | *  the Free Software Foundation; either version 2, or (at your option) | 
|  | 9 | *  any later version. | 
|  | 10 | * | 
|  | 11 | *  This program is distributed in the hope that it will be useful, | 
|  | 12 | *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 13 | *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 14 | *  GNU General Public License for more details. | 
|  | 15 | * | 
|  | 16 | *  You should have received a copy of the GNU General Public License | 
|  | 17 | *  along with this program; see the file COPYING.  If not, write to | 
|  | 18 | *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | 19 | * | 
|  | 20 | * | 
|  | 21 | *  libata documentation is available via 'make {ps|pdf}docs', | 
|  | 22 | *  as Documentation/DocBook/libata.* | 
|  | 23 | * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 24 | */ | 
|  | 25 |  | 
|  | 26 | #ifndef __LINUX_LIBATA_H__ | 
|  | 27 | #define __LINUX_LIBATA_H__ | 
|  | 28 |  | 
|  | 29 | #include <linux/delay.h> | 
|  | 30 | #include <linux/interrupt.h> | 
|  | 31 | #include <linux/pci.h> | 
|  | 32 | #include <asm/io.h> | 
|  | 33 | #include <linux/ata.h> | 
|  | 34 | #include <linux/workqueue.h> | 
|  | 35 |  | 
|  | 36 | /* | 
|  | 37 | * compile-time options | 
|  | 38 | */ | 
|  | 39 | #undef ATA_DEBUG		/* debugging output */ | 
|  | 40 | #undef ATA_VERBOSE_DEBUG	/* yet more debugging output */ | 
|  | 41 | #undef ATA_IRQ_TRAP		/* define to ack screaming irqs */ | 
|  | 42 | #undef ATA_NDEBUG		/* define to disable quick runtime checks */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 43 | #undef ATA_ENABLE_PATA		/* define to enable PATA support in some | 
|  | 44 | * low-level drivers */ | 
|  | 45 | #undef ATAPI_ENABLE_DMADIR	/* enables ATAPI DMADIR bridge support */ | 
|  | 46 |  | 
|  | 47 |  | 
|  | 48 | /* note: prints function name for you */ | 
|  | 49 | #ifdef ATA_DEBUG | 
|  | 50 | #define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) | 
|  | 51 | #ifdef ATA_VERBOSE_DEBUG | 
|  | 52 | #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) | 
|  | 53 | #else | 
|  | 54 | #define VPRINTK(fmt, args...) | 
|  | 55 | #endif	/* ATA_VERBOSE_DEBUG */ | 
|  | 56 | #else | 
|  | 57 | #define DPRINTK(fmt, args...) | 
|  | 58 | #define VPRINTK(fmt, args...) | 
|  | 59 | #endif	/* ATA_DEBUG */ | 
|  | 60 |  | 
|  | 61 | #ifdef ATA_NDEBUG | 
|  | 62 | #define assert(expr) | 
|  | 63 | #else | 
|  | 64 | #define assert(expr) \ | 
|  | 65 | if(unlikely(!(expr))) {                                   \ | 
|  | 66 | printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ | 
|  | 67 | #expr,__FILE__,__FUNCTION__,__LINE__);          \ | 
|  | 68 | } | 
|  | 69 | #endif | 
|  | 70 |  | 
|  | 71 | /* defines only for the constants which don't work well as enums */ | 
|  | 72 | #define ATA_TAG_POISON		0xfafbfcfdU | 
|  | 73 |  | 
|  | 74 | /* move to PCI layer? */ | 
|  | 75 | static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) | 
|  | 76 | { | 
|  | 77 | return &pdev->dev; | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | enum { | 
|  | 81 | /* various global constants */ | 
|  | 82 | LIBATA_MAX_PRD		= ATA_MAX_PRD / 2, | 
|  | 83 | ATA_MAX_PORTS		= 8, | 
|  | 84 | ATA_DEF_QUEUE		= 1, | 
|  | 85 | ATA_MAX_QUEUE		= 1, | 
|  | 86 | ATA_MAX_SECTORS		= 200,	/* FIXME */ | 
|  | 87 | ATA_MAX_BUS		= 2, | 
|  | 88 | ATA_DEF_BUSY_WAIT	= 10000, | 
|  | 89 | ATA_SHORT_PAUSE		= (HZ >> 6) + 1, | 
|  | 90 |  | 
|  | 91 | ATA_SHT_EMULATED	= 1, | 
|  | 92 | ATA_SHT_CMD_PER_LUN	= 1, | 
|  | 93 | ATA_SHT_THIS_ID		= -1, | 
|  | 94 | ATA_SHT_USE_CLUSTERING	= 0, | 
|  | 95 |  | 
|  | 96 | /* struct ata_device stuff */ | 
|  | 97 | ATA_DFLAG_LBA48		= (1 << 0), /* device supports LBA48 */ | 
|  | 98 | ATA_DFLAG_PIO		= (1 << 1), /* device currently in PIO mode */ | 
|  | 99 | ATA_DFLAG_LOCK_SECTORS	= (1 << 2), /* don't adjust max_sectors */ | 
| Albert Lee | 312f7da | 2005-09-27 17:38:03 +0800 | [diff] [blame] | 100 | ATA_DFLAG_CDB_INTR	= (1 << 3), /* device asserts INTRQ when ready for CDB */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 101 |  | 
|  | 102 | ATA_DEV_UNKNOWN		= 0,	/* unknown device */ | 
|  | 103 | ATA_DEV_ATA		= 1,	/* ATA device */ | 
|  | 104 | ATA_DEV_ATA_UNSUP	= 2,	/* ATA device (unsupported) */ | 
|  | 105 | ATA_DEV_ATAPI		= 3,	/* ATAPI device */ | 
|  | 106 | ATA_DEV_ATAPI_UNSUP	= 4,	/* ATAPI device (unsupported) */ | 
|  | 107 | ATA_DEV_NONE		= 5,	/* no device */ | 
|  | 108 |  | 
|  | 109 | /* struct ata_port flags */ | 
|  | 110 | ATA_FLAG_SLAVE_POSS	= (1 << 1), /* host supports slave dev */ | 
|  | 111 | /* (doesn't imply presence) */ | 
|  | 112 | ATA_FLAG_PORT_DISABLED	= (1 << 2), /* port is disabled, ignore it */ | 
|  | 113 | ATA_FLAG_SATA		= (1 << 3), | 
|  | 114 | ATA_FLAG_NO_LEGACY	= (1 << 4), /* no legacy mode check */ | 
|  | 115 | ATA_FLAG_SRST		= (1 << 5), /* use ATA SRST, not E.D.D. */ | 
|  | 116 | ATA_FLAG_MMIO		= (1 << 6), /* use MMIO, not PIO */ | 
|  | 117 | ATA_FLAG_SATA_RESET	= (1 << 7), /* use COMRESET */ | 
|  | 118 | ATA_FLAG_PIO_DMA	= (1 << 8), /* PIO cmds via DMA */ | 
| Albert Lee | e50362e | 2005-09-27 17:39:50 +0800 | [diff] [blame] | 119 | ATA_FLAG_PIO_POLLING	= (1 << 9), /* use polling PIO if LLD | 
|  | 120 | * doesn't handle PIO interrupts */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 |  | 
|  | 122 | ATA_QCFLAG_ACTIVE	= (1 << 1), /* cmd not yet ack'd to scsi lyer */ | 
|  | 123 | ATA_QCFLAG_SG		= (1 << 3), /* have s/g table? */ | 
|  | 124 | ATA_QCFLAG_SINGLE	= (1 << 4), /* no s/g, just a single buffer */ | 
|  | 125 | ATA_QCFLAG_DMAMAP	= ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, | 
|  | 126 |  | 
|  | 127 | /* various lengths of time */ | 
|  | 128 | ATA_TMOUT_EDD		= 5 * HZ,	/* hueristic */ | 
|  | 129 | ATA_TMOUT_PIO		= 30 * HZ, | 
|  | 130 | ATA_TMOUT_BOOT		= 30 * HZ,	/* hueristic */ | 
|  | 131 | ATA_TMOUT_BOOT_QUICK	= 7 * HZ,	/* hueristic */ | 
|  | 132 | ATA_TMOUT_CDB		= 30 * HZ, | 
|  | 133 | ATA_TMOUT_CDB_QUICK	= 5 * HZ, | 
|  | 134 |  | 
|  | 135 | /* ATA bus states */ | 
|  | 136 | BUS_UNKNOWN		= 0, | 
|  | 137 | BUS_DMA			= 1, | 
|  | 138 | BUS_IDLE		= 2, | 
|  | 139 | BUS_NOINTR		= 3, | 
|  | 140 | BUS_NODATA		= 4, | 
|  | 141 | BUS_TIMER		= 5, | 
|  | 142 | BUS_PIO			= 6, | 
|  | 143 | BUS_EDD			= 7, | 
|  | 144 | BUS_IDENTIFY		= 8, | 
|  | 145 | BUS_PACKET		= 9, | 
|  | 146 |  | 
|  | 147 | /* SATA port states */ | 
|  | 148 | PORT_UNKNOWN		= 0, | 
|  | 149 | PORT_ENABLED		= 1, | 
|  | 150 | PORT_DISABLED		= 2, | 
|  | 151 |  | 
|  | 152 | /* encoding various smaller bitmaps into a single | 
|  | 153 | * unsigned long bitmap | 
|  | 154 | */ | 
|  | 155 | ATA_SHIFT_UDMA		= 0, | 
|  | 156 | ATA_SHIFT_MWDMA		= 8, | 
|  | 157 | ATA_SHIFT_PIO		= 11, | 
|  | 158 | }; | 
|  | 159 |  | 
| Albert Lee | 14be71f | 2005-09-27 17:36:35 +0800 | [diff] [blame] | 160 | enum hsm_task_states { | 
| Albert Lee | c56b14d2 | 2005-09-30 19:07:39 +0800 | [diff] [blame^] | 161 | HSM_ST_UNKNOWN,		/* state unknown */ | 
|  | 162 | HSM_ST_IDLE,		/* no command on going */ | 
|  | 163 | HSM_ST_POLL,		/* same as HSM_ST, waits longer */ | 
|  | 164 | HSM_ST_TMOUT,		/* timeout */ | 
|  | 165 | HSM_ST,			/* (waiting the device to) transfer data */ | 
|  | 166 | HSM_ST_LAST,		/* (waiting the device to) complete command */ | 
|  | 167 | HSM_ST_LAST_POLL,	/* same as HSM_ST_LAST, waits longer */ | 
|  | 168 | HSM_ST_ERR,		/* error */ | 
|  | 169 | HSM_ST_FIRST,		/* (waiting the device to) | 
|  | 170 | write CDB or first data block */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 171 | }; | 
|  | 172 |  | 
|  | 173 | /* forward declarations */ | 
|  | 174 | struct scsi_device; | 
|  | 175 | struct ata_port_operations; | 
|  | 176 | struct ata_port; | 
|  | 177 | struct ata_queued_cmd; | 
|  | 178 |  | 
|  | 179 | /* typedefs */ | 
|  | 180 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat); | 
|  | 181 |  | 
|  | 182 | struct ata_ioports { | 
|  | 183 | unsigned long		cmd_addr; | 
|  | 184 | unsigned long		data_addr; | 
|  | 185 | unsigned long		error_addr; | 
|  | 186 | unsigned long		feature_addr; | 
|  | 187 | unsigned long		nsect_addr; | 
|  | 188 | unsigned long		lbal_addr; | 
|  | 189 | unsigned long		lbam_addr; | 
|  | 190 | unsigned long		lbah_addr; | 
|  | 191 | unsigned long		device_addr; | 
|  | 192 | unsigned long		status_addr; | 
|  | 193 | unsigned long		command_addr; | 
|  | 194 | unsigned long		altstatus_addr; | 
|  | 195 | unsigned long		ctl_addr; | 
|  | 196 | unsigned long		bmdma_addr; | 
|  | 197 | unsigned long		scr_addr; | 
|  | 198 | }; | 
|  | 199 |  | 
|  | 200 | struct ata_probe_ent { | 
|  | 201 | struct list_head	node; | 
|  | 202 | struct device 		*dev; | 
|  | 203 | struct ata_port_operations	*port_ops; | 
|  | 204 | Scsi_Host_Template	*sht; | 
|  | 205 | struct ata_ioports	port[ATA_MAX_PORTS]; | 
|  | 206 | unsigned int		n_ports; | 
|  | 207 | unsigned int		hard_port_no; | 
|  | 208 | unsigned int		pio_mask; | 
|  | 209 | unsigned int		mwdma_mask; | 
|  | 210 | unsigned int		udma_mask; | 
|  | 211 | unsigned int		legacy_mode; | 
|  | 212 | unsigned long		irq; | 
|  | 213 | unsigned int		irq_flags; | 
|  | 214 | unsigned long		host_flags; | 
|  | 215 | void __iomem		*mmio_base; | 
|  | 216 | void			*private_data; | 
|  | 217 | }; | 
|  | 218 |  | 
|  | 219 | struct ata_host_set { | 
|  | 220 | spinlock_t		lock; | 
|  | 221 | struct device 		*dev; | 
|  | 222 | unsigned long		irq; | 
|  | 223 | void __iomem		*mmio_base; | 
|  | 224 | unsigned int		n_ports; | 
|  | 225 | void			*private_data; | 
|  | 226 | struct ata_port_operations *ops; | 
|  | 227 | struct ata_port *	ports[0]; | 
|  | 228 | }; | 
|  | 229 |  | 
|  | 230 | struct ata_queued_cmd { | 
|  | 231 | struct ata_port		*ap; | 
|  | 232 | struct ata_device	*dev; | 
|  | 233 |  | 
|  | 234 | struct scsi_cmnd	*scsicmd; | 
|  | 235 | void			(*scsidone)(struct scsi_cmnd *); | 
|  | 236 |  | 
|  | 237 | struct ata_taskfile	tf; | 
|  | 238 | u8			cdb[ATAPI_CDB_LEN]; | 
|  | 239 |  | 
|  | 240 | unsigned long		flags;		/* ATA_QCFLAG_xxx */ | 
|  | 241 | unsigned int		tag; | 
|  | 242 | unsigned int		n_elem; | 
|  | 243 |  | 
|  | 244 | int			dma_dir; | 
|  | 245 |  | 
|  | 246 | unsigned int		nsect; | 
|  | 247 | unsigned int		cursect; | 
|  | 248 |  | 
|  | 249 | unsigned int		nbytes; | 
|  | 250 | unsigned int		curbytes; | 
|  | 251 |  | 
|  | 252 | unsigned int		cursg; | 
|  | 253 | unsigned int		cursg_ofs; | 
|  | 254 |  | 
|  | 255 | struct scatterlist	sgent; | 
|  | 256 | void			*buf_virt; | 
|  | 257 |  | 
|  | 258 | struct scatterlist	*sg; | 
|  | 259 |  | 
|  | 260 | ata_qc_cb_t		complete_fn; | 
|  | 261 |  | 
|  | 262 | struct completion	*waiting; | 
|  | 263 |  | 
|  | 264 | void			*private_data; | 
|  | 265 | }; | 
|  | 266 |  | 
|  | 267 | struct ata_host_stats { | 
|  | 268 | unsigned long		unhandled_irq; | 
|  | 269 | unsigned long		idle_irq; | 
|  | 270 | unsigned long		rw_reqbuf; | 
|  | 271 | }; | 
|  | 272 |  | 
|  | 273 | struct ata_device { | 
|  | 274 | u64			n_sectors;	/* size of device, if ATA */ | 
|  | 275 | unsigned long		flags;		/* ATA_DFLAG_xxx */ | 
|  | 276 | unsigned int		class;		/* ATA_DEV_xxx */ | 
|  | 277 | unsigned int		devno;		/* 0 or 1 */ | 
|  | 278 | u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ | 
|  | 279 | u8			pio_mode; | 
|  | 280 | u8			dma_mode; | 
|  | 281 | u8			xfer_mode; | 
|  | 282 | unsigned int		xfer_shift;	/* ATA_SHIFT_xxx */ | 
|  | 283 |  | 
|  | 284 | /* cache info about current transfer mode */ | 
|  | 285 | u8			xfer_protocol;	/* taskfile xfer protocol */ | 
|  | 286 | u8			read_cmd;	/* opcode to use on read */ | 
|  | 287 | u8			write_cmd;	/* opcode to use on write */ | 
|  | 288 | }; | 
|  | 289 |  | 
|  | 290 | struct ata_port { | 
|  | 291 | struct Scsi_Host	*host;	/* our co-allocated scsi host */ | 
|  | 292 | struct ata_port_operations	*ops; | 
|  | 293 | unsigned long		flags;	/* ATA_FLAG_xxx */ | 
|  | 294 | unsigned int		id;	/* unique id req'd by scsi midlyr */ | 
|  | 295 | unsigned int		port_no; /* unique port #; from zero */ | 
|  | 296 | unsigned int		hard_port_no;	/* hardware port #; from zero */ | 
|  | 297 |  | 
|  | 298 | struct ata_prd		*prd;	 /* our SG list */ | 
|  | 299 | dma_addr_t		prd_dma; /* and its DMA mapping */ | 
|  | 300 |  | 
|  | 301 | struct ata_ioports	ioaddr;	/* ATA cmd/ctl/dma register blocks */ | 
|  | 302 |  | 
|  | 303 | u8			ctl;	/* cache of ATA control register */ | 
|  | 304 | u8			last_ctl;	/* Cache last written value */ | 
|  | 305 | unsigned int		bus_state; | 
|  | 306 | unsigned int		port_state; | 
|  | 307 | unsigned int		pio_mask; | 
|  | 308 | unsigned int		mwdma_mask; | 
|  | 309 | unsigned int		udma_mask; | 
|  | 310 | unsigned int		cbl;	/* cable type; ATA_CBL_xxx */ | 
|  | 311 | unsigned int		cdb_len; | 
|  | 312 |  | 
|  | 313 | struct ata_device	device[ATA_MAX_DEVICES]; | 
|  | 314 |  | 
|  | 315 | struct ata_queued_cmd	qcmd[ATA_MAX_QUEUE]; | 
|  | 316 | unsigned long		qactive; | 
|  | 317 | unsigned int		active_tag; | 
|  | 318 |  | 
|  | 319 | struct ata_host_stats	stats; | 
|  | 320 | struct ata_host_set	*host_set; | 
|  | 321 |  | 
|  | 322 | struct work_struct	packet_task; | 
|  | 323 |  | 
|  | 324 | struct work_struct	pio_task; | 
| Albert Lee | 14be71f | 2005-09-27 17:36:35 +0800 | [diff] [blame] | 325 | unsigned int		hsm_task_state; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 326 | unsigned long		pio_task_timeout; | 
|  | 327 |  | 
|  | 328 | void			*private_data; | 
|  | 329 | }; | 
|  | 330 |  | 
|  | 331 | struct ata_port_operations { | 
|  | 332 | void (*port_disable) (struct ata_port *); | 
|  | 333 |  | 
|  | 334 | void (*dev_config) (struct ata_port *, struct ata_device *); | 
|  | 335 |  | 
|  | 336 | void (*set_piomode) (struct ata_port *, struct ata_device *); | 
|  | 337 | void (*set_dmamode) (struct ata_port *, struct ata_device *); | 
|  | 338 |  | 
|  | 339 | void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf); | 
|  | 340 | void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); | 
|  | 341 |  | 
|  | 342 | void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); | 
|  | 343 | u8   (*check_status)(struct ata_port *ap); | 
|  | 344 | u8   (*check_altstatus)(struct ata_port *ap); | 
|  | 345 | u8   (*check_err)(struct ata_port *ap); | 
|  | 346 | void (*dev_select)(struct ata_port *ap, unsigned int device); | 
|  | 347 |  | 
|  | 348 | void (*phy_reset) (struct ata_port *ap); | 
|  | 349 | void (*post_set_mode) (struct ata_port *ap); | 
|  | 350 |  | 
|  | 351 | int (*check_atapi_dma) (struct ata_queued_cmd *qc); | 
|  | 352 |  | 
|  | 353 | void (*bmdma_setup) (struct ata_queued_cmd *qc); | 
|  | 354 | void (*bmdma_start) (struct ata_queued_cmd *qc); | 
|  | 355 |  | 
|  | 356 | void (*qc_prep) (struct ata_queued_cmd *qc); | 
|  | 357 | int (*qc_issue) (struct ata_queued_cmd *qc); | 
|  | 358 |  | 
|  | 359 | void (*eng_timeout) (struct ata_port *ap); | 
|  | 360 |  | 
|  | 361 | irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); | 
|  | 362 | void (*irq_clear) (struct ata_port *); | 
|  | 363 |  | 
|  | 364 | u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); | 
|  | 365 | void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | 
|  | 366 | u32 val); | 
|  | 367 |  | 
|  | 368 | int (*port_start) (struct ata_port *ap); | 
|  | 369 | void (*port_stop) (struct ata_port *ap); | 
|  | 370 |  | 
|  | 371 | void (*host_stop) (struct ata_host_set *host_set); | 
|  | 372 |  | 
| Alan Cox | b73fc89 | 2005-08-26 16:03:19 +0100 | [diff] [blame] | 373 | void (*bmdma_stop) (struct ata_queued_cmd *qc); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 374 | u8   (*bmdma_status) (struct ata_port *ap); | 
|  | 375 | }; | 
|  | 376 |  | 
|  | 377 | struct ata_port_info { | 
|  | 378 | Scsi_Host_Template	*sht; | 
|  | 379 | unsigned long		host_flags; | 
|  | 380 | unsigned long		pio_mask; | 
|  | 381 | unsigned long		mwdma_mask; | 
|  | 382 | unsigned long		udma_mask; | 
|  | 383 | struct ata_port_operations	*port_ops; | 
|  | 384 | }; | 
|  | 385 |  | 
|  | 386 |  | 
|  | 387 | extern void ata_port_probe(struct ata_port *); | 
|  | 388 | extern void __sata_phy_reset(struct ata_port *ap); | 
|  | 389 | extern void sata_phy_reset(struct ata_port *ap); | 
|  | 390 | extern void ata_bus_reset(struct ata_port *ap); | 
|  | 391 | extern void ata_port_disable(struct ata_port *); | 
|  | 392 | extern void ata_std_ports(struct ata_ioports *ioaddr); | 
|  | 393 | #ifdef CONFIG_PCI | 
|  | 394 | extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | 
|  | 395 | unsigned int n_ports); | 
|  | 396 | extern void ata_pci_remove_one (struct pci_dev *pdev); | 
|  | 397 | #endif /* CONFIG_PCI */ | 
|  | 398 | extern int ata_device_add(struct ata_probe_ent *ent); | 
| Alan Cox | 17b1445 | 2005-09-15 15:44:00 +0100 | [diff] [blame] | 399 | extern void ata_host_set_remove(struct ata_host_set *host_set); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 400 | extern int ata_scsi_detect(Scsi_Host_Template *sht); | 
|  | 401 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); | 
|  | 402 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); | 
|  | 403 | extern int ata_scsi_error(struct Scsi_Host *host); | 
|  | 404 | extern int ata_scsi_release(struct Scsi_Host *host); | 
|  | 405 | extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); | 
|  | 406 | /* | 
|  | 407 | * Default driver ops implementations | 
|  | 408 | */ | 
|  | 409 | extern void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf); | 
|  | 410 | extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | 
|  | 411 | extern void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp); | 
|  | 412 | extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf); | 
|  | 413 | extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); | 
|  | 414 | extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); | 
|  | 415 | extern u8 ata_check_status(struct ata_port *ap); | 
|  | 416 | extern u8 ata_altstatus(struct ata_port *ap); | 
|  | 417 | extern u8 ata_chk_err(struct ata_port *ap); | 
|  | 418 | extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); | 
|  | 419 | extern int ata_port_start (struct ata_port *ap); | 
|  | 420 | extern void ata_port_stop (struct ata_port *ap); | 
| Jeff Garzik | aa8f0dc | 2005-05-26 21:54:27 -0400 | [diff] [blame] | 421 | extern void ata_host_stop (struct ata_host_set *host_set); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 422 | extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 
|  | 423 | extern void ata_qc_prep(struct ata_queued_cmd *qc); | 
|  | 424 | extern int ata_qc_issue_prot(struct ata_queued_cmd *qc); | 
|  | 425 | extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, | 
|  | 426 | unsigned int buflen); | 
|  | 427 | extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | 
|  | 428 | unsigned int n_elem); | 
|  | 429 | extern unsigned int ata_dev_classify(struct ata_taskfile *tf); | 
|  | 430 | extern void ata_dev_id_string(u16 *id, unsigned char *s, | 
|  | 431 | unsigned int ofs, unsigned int len); | 
| Brad Campbell | 6f2f381 | 2005-05-12 15:07:47 -0400 | [diff] [blame] | 432 | extern void ata_dev_config(struct ata_port *ap, unsigned int i); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 433 | extern void ata_bmdma_setup (struct ata_queued_cmd *qc); | 
|  | 434 | extern void ata_bmdma_start (struct ata_queued_cmd *qc); | 
| Alan Cox | b73fc89 | 2005-08-26 16:03:19 +0100 | [diff] [blame] | 435 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 436 | extern u8   ata_bmdma_status(struct ata_port *ap); | 
|  | 437 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 
|  | 438 | extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); | 
|  | 439 | extern void ata_eng_timeout(struct ata_port *ap); | 
|  | 440 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, | 
|  | 441 | void (*done)(struct scsi_cmnd *)); | 
|  | 442 | extern int ata_std_bios_param(struct scsi_device *sdev, | 
|  | 443 | struct block_device *bdev, | 
|  | 444 | sector_t capacity, int geom[]); | 
|  | 445 | extern int ata_scsi_slave_config(struct scsi_device *sdev); | 
|  | 446 |  | 
|  | 447 |  | 
|  | 448 | #ifdef CONFIG_PCI | 
|  | 449 | struct pci_bits { | 
|  | 450 | unsigned int		reg;	/* PCI config register to read */ | 
|  | 451 | unsigned int		width;	/* 1 (8 bit), 2 (16 bit), 4 (32 bit) */ | 
|  | 452 | unsigned long		mask; | 
|  | 453 | unsigned long		val; | 
|  | 454 | }; | 
|  | 455 |  | 
| Jeff Garzik | 374b187 | 2005-08-30 05:42:52 -0400 | [diff] [blame] | 456 | extern void ata_pci_host_stop (struct ata_host_set *host_set); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 457 | extern struct ata_probe_ent * | 
|  | 458 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port); | 
|  | 459 | extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); | 
|  | 460 |  | 
|  | 461 | #endif /* CONFIG_PCI */ | 
|  | 462 |  | 
|  | 463 |  | 
|  | 464 | static inline unsigned int ata_tag_valid(unsigned int tag) | 
|  | 465 | { | 
|  | 466 | return (tag < ATA_MAX_QUEUE) ? 1 : 0; | 
|  | 467 | } | 
|  | 468 |  | 
|  | 469 | static inline unsigned int ata_dev_present(struct ata_device *dev) | 
|  | 470 | { | 
|  | 471 | return ((dev->class == ATA_DEV_ATA) || | 
|  | 472 | (dev->class == ATA_DEV_ATAPI)); | 
|  | 473 | } | 
|  | 474 |  | 
|  | 475 | static inline u8 ata_chk_status(struct ata_port *ap) | 
|  | 476 | { | 
|  | 477 | return ap->ops->check_status(ap); | 
|  | 478 | } | 
|  | 479 |  | 
| Edward Falk | 0baab86 | 2005-06-02 18:17:13 -0400 | [diff] [blame] | 480 |  | 
|  | 481 | /** | 
|  | 482 | *	ata_pause - Flush writes and pause 400 nanoseconds. | 
|  | 483 | *	@ap: Port to wait for. | 
|  | 484 | * | 
|  | 485 | *	LOCKING: | 
|  | 486 | *	Inherited from caller. | 
|  | 487 | */ | 
|  | 488 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 489 | static inline void ata_pause(struct ata_port *ap) | 
|  | 490 | { | 
|  | 491 | ata_altstatus(ap); | 
|  | 492 | ndelay(400); | 
|  | 493 | } | 
|  | 494 |  | 
| Edward Falk | 0baab86 | 2005-06-02 18:17:13 -0400 | [diff] [blame] | 495 |  | 
|  | 496 | /** | 
|  | 497 | *	ata_busy_wait - Wait for a port status register | 
|  | 498 | *	@ap: Port to wait for. | 
|  | 499 | * | 
|  | 500 | *	Waits up to max*10 microseconds for the selected bits in the port's | 
|  | 501 | *	status register to be cleared. | 
|  | 502 | *	Returns final value of status register. | 
|  | 503 | * | 
|  | 504 | *	LOCKING: | 
|  | 505 | *	Inherited from caller. | 
|  | 506 | */ | 
|  | 507 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 508 | static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, | 
|  | 509 | unsigned int max) | 
|  | 510 | { | 
|  | 511 | u8 status; | 
|  | 512 |  | 
|  | 513 | do { | 
|  | 514 | udelay(10); | 
|  | 515 | status = ata_chk_status(ap); | 
|  | 516 | max--; | 
|  | 517 | } while ((status & bits) && (max > 0)); | 
|  | 518 |  | 
|  | 519 | return status; | 
|  | 520 | } | 
|  | 521 |  | 
| Edward Falk | 0baab86 | 2005-06-02 18:17:13 -0400 | [diff] [blame] | 522 |  | 
|  | 523 | /** | 
|  | 524 | *	ata_wait_idle - Wait for a port to be idle. | 
|  | 525 | *	@ap: Port to wait for. | 
|  | 526 | * | 
|  | 527 | *	Waits up to 10ms for port's BUSY and DRQ signals to clear. | 
|  | 528 | *	Returns final value of status register. | 
|  | 529 | * | 
|  | 530 | *	LOCKING: | 
|  | 531 | *	Inherited from caller. | 
|  | 532 | */ | 
|  | 533 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 534 | static inline u8 ata_wait_idle(struct ata_port *ap) | 
|  | 535 | { | 
|  | 536 | u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); | 
|  | 537 |  | 
|  | 538 | if (status & (ATA_BUSY | ATA_DRQ)) { | 
|  | 539 | unsigned long l = ap->ioaddr.status_addr; | 
|  | 540 | printk(KERN_WARNING | 
|  | 541 | "ATA: abnormal status 0x%X on port 0x%lX\n", | 
|  | 542 | status, l); | 
|  | 543 | } | 
|  | 544 |  | 
|  | 545 | return status; | 
|  | 546 | } | 
|  | 547 |  | 
|  | 548 | static inline void ata_qc_set_polling(struct ata_queued_cmd *qc) | 
|  | 549 | { | 
|  | 550 | qc->tf.ctl |= ATA_NIEN; | 
|  | 551 | } | 
|  | 552 |  | 
|  | 553 | static inline struct ata_queued_cmd *ata_qc_from_tag (struct ata_port *ap, | 
|  | 554 | unsigned int tag) | 
|  | 555 | { | 
|  | 556 | if (likely(ata_tag_valid(tag))) | 
|  | 557 | return &ap->qcmd[tag]; | 
|  | 558 | return NULL; | 
|  | 559 | } | 
|  | 560 |  | 
|  | 561 | static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, unsigned int device) | 
|  | 562 | { | 
|  | 563 | memset(tf, 0, sizeof(*tf)); | 
|  | 564 |  | 
|  | 565 | tf->ctl = ap->ctl; | 
|  | 566 | if (device == 0) | 
|  | 567 | tf->device = ATA_DEVICE_OBS; | 
|  | 568 | else | 
|  | 569 | tf->device = ATA_DEVICE_OBS | ATA_DEV1; | 
|  | 570 | } | 
|  | 571 |  | 
| Edward Falk | 0baab86 | 2005-06-02 18:17:13 -0400 | [diff] [blame] | 572 |  | 
|  | 573 | /** | 
|  | 574 | *	ata_irq_on - Enable interrupts on a port. | 
|  | 575 | *	@ap: Port on which interrupts are enabled. | 
|  | 576 | * | 
|  | 577 | *	Enable interrupts on a legacy IDE device using MMIO or PIO, | 
|  | 578 | *	wait for idle, clear any pending interrupts. | 
|  | 579 | * | 
|  | 580 | *	LOCKING: | 
|  | 581 | *	Inherited from caller. | 
|  | 582 | */ | 
|  | 583 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 584 | static inline u8 ata_irq_on(struct ata_port *ap) | 
|  | 585 | { | 
|  | 586 | struct ata_ioports *ioaddr = &ap->ioaddr; | 
|  | 587 | u8 tmp; | 
|  | 588 |  | 
|  | 589 | ap->ctl &= ~ATA_NIEN; | 
|  | 590 | ap->last_ctl = ap->ctl; | 
|  | 591 |  | 
|  | 592 | if (ap->flags & ATA_FLAG_MMIO) | 
|  | 593 | writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); | 
|  | 594 | else | 
|  | 595 | outb(ap->ctl, ioaddr->ctl_addr); | 
|  | 596 | tmp = ata_wait_idle(ap); | 
|  | 597 |  | 
|  | 598 | ap->ops->irq_clear(ap); | 
|  | 599 |  | 
|  | 600 | return tmp; | 
|  | 601 | } | 
|  | 602 |  | 
| Edward Falk | 0baab86 | 2005-06-02 18:17:13 -0400 | [diff] [blame] | 603 |  | 
|  | 604 | /** | 
|  | 605 | *	ata_irq_ack - Acknowledge a device interrupt. | 
|  | 606 | *	@ap: Port on which interrupts are enabled. | 
|  | 607 | * | 
|  | 608 | *	Wait up to 10 ms for legacy IDE device to become idle (BUSY | 
|  | 609 | *	or BUSY+DRQ clear).  Obtain dma status and port status from | 
|  | 610 | *	device.  Clear the interrupt.  Return port status. | 
|  | 611 | * | 
|  | 612 | *	LOCKING: | 
|  | 613 | */ | 
|  | 614 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 615 | static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) | 
|  | 616 | { | 
|  | 617 | unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; | 
|  | 618 | u8 host_stat, post_stat, status; | 
|  | 619 |  | 
|  | 620 | status = ata_busy_wait(ap, bits, 1000); | 
|  | 621 | if (status & bits) | 
|  | 622 | DPRINTK("abnormal status 0x%X\n", status); | 
|  | 623 |  | 
|  | 624 | /* get controller status; clear intr, err bits */ | 
|  | 625 | if (ap->flags & ATA_FLAG_MMIO) { | 
|  | 626 | void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; | 
|  | 627 | host_stat = readb(mmio + ATA_DMA_STATUS); | 
|  | 628 | writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, | 
|  | 629 | mmio + ATA_DMA_STATUS); | 
|  | 630 |  | 
|  | 631 | post_stat = readb(mmio + ATA_DMA_STATUS); | 
|  | 632 | } else { | 
|  | 633 | host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); | 
|  | 634 | outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, | 
|  | 635 | ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); | 
|  | 636 |  | 
|  | 637 | post_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); | 
|  | 638 | } | 
|  | 639 |  | 
|  | 640 | VPRINTK("irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", | 
|  | 641 | host_stat, post_stat, status); | 
|  | 642 |  | 
|  | 643 | return status; | 
|  | 644 | } | 
|  | 645 |  | 
|  | 646 | static inline u32 scr_read(struct ata_port *ap, unsigned int reg) | 
|  | 647 | { | 
|  | 648 | return ap->ops->scr_read(ap, reg); | 
|  | 649 | } | 
|  | 650 |  | 
|  | 651 | static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val) | 
|  | 652 | { | 
|  | 653 | ap->ops->scr_write(ap, reg, val); | 
|  | 654 | } | 
|  | 655 |  | 
| Jeff Garzik | 8a60a07 | 2005-07-31 13:13:24 -0400 | [diff] [blame] | 656 | static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, | 
| Brett Russ | cdcca89e | 2005-03-28 15:10:27 -0500 | [diff] [blame] | 657 | u32 val) | 
|  | 658 | { | 
|  | 659 | ap->ops->scr_write(ap, reg, val); | 
|  | 660 | (void) ap->ops->scr_read(ap, reg); | 
|  | 661 | } | 
|  | 662 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 663 | static inline unsigned int sata_dev_present(struct ata_port *ap) | 
|  | 664 | { | 
|  | 665 | return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; | 
|  | 666 | } | 
|  | 667 |  | 
|  | 668 | static inline int ata_try_flush_cache(struct ata_device *dev) | 
|  | 669 | { | 
|  | 670 | return ata_id_wcache_enabled(dev->id) || | 
|  | 671 | ata_id_has_flush(dev->id) || | 
|  | 672 | ata_id_has_flush_ext(dev->id); | 
|  | 673 | } | 
|  | 674 |  | 
|  | 675 | #endif /* __LINUX_LIBATA_H__ */ |