ide-dma.c 21.2 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2 3
 *  IDE DMA support (including IDE PCI BM-DMA).
 *
4 5 6
 *  Copyright (C) 1995-1998   Mark Lord
 *  Copyright (C) 1999-2000   Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 2004, 2007  Bartlomiej Zolnierkiewicz
7
 *
L
Linus Torvalds 已提交
8
 *  May be copied or modified under the terms of the GNU General Public License
9 10
 *
 *  DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies).
L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 */

/*
 *  Special Thanks to Mark for his Six years of work.
 */

/*
 * Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for
 * fixing the problem with the BIOS on some Acer motherboards.
 *
 * Thanks to "Benoit Poulot-Cazajous" <poulot@chorus.fr> for testing
 * "TX" chipset compatibility and for providing patches for the "TX" chipset.
 *
 * Thanks to Christian Brunner <chb@muc.de> for taking a good first crack
 * at generic DMA -- his patches were referred to when preparing this code.
 *
 * Most importantly, thanks to Robert Bringman <rob@mars.trion.com>
 * for supplying a Promise UDMA board & WD UDMA drive for this work!
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
35
#include <linux/dma-mapping.h>
L
Linus Torvalds 已提交
36 37 38 39 40

#include <asm/io.h>

static const struct drive_list_entry drive_whitelist [] = {

41 42 43 44
	{ "Micropolis 2112A"	,       NULL		},
	{ "CONNER CTMA 4000"	,       NULL		},
	{ "CONNER CTT8000-A"	,       NULL		},
	{ "ST34342A"		,	NULL		},
L
Linus Torvalds 已提交
45 46 47 48 49
	{ NULL			,	NULL		}
};

static const struct drive_list_entry drive_blacklist [] = {

50 51 52 53 54
	{ "WDC AC11000H"	,	NULL 		},
	{ "WDC AC22100H"	,	NULL 		},
	{ "WDC AC32500H"	,	NULL 		},
	{ "WDC AC33100H"	,	NULL 		},
	{ "WDC AC31600H"	,	NULL 		},
L
Linus Torvalds 已提交
55 56
	{ "WDC AC32100H"	,	"24.09P07"	},
	{ "WDC AC23200L"	,	"21.10N21"	},
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	{ "Compaq CRD-8241B"	,	NULL 		},
	{ "CRD-8400B"		,	NULL 		},
	{ "CRD-8480B",			NULL 		},
	{ "CRD-8482B",			NULL 		},
	{ "CRD-84"		,	NULL 		},
	{ "SanDisk SDP3B"	,	NULL 		},
	{ "SanDisk SDP3B-64"	,	NULL 		},
	{ "SANYO CD-ROM CRD"	,	NULL 		},
	{ "HITACHI CDR-8"	,	NULL 		},
	{ "HITACHI CDR-8335"	,	NULL 		},
	{ "HITACHI CDR-8435"	,	NULL 		},
	{ "Toshiba CD-ROM XM-6202B"	,	NULL 		},
	{ "TOSHIBA CD-ROM XM-1702BC",	NULL 		},
	{ "CD-532E-A"		,	NULL 		},
	{ "E-IDE CD-ROM CR-840",	NULL 		},
	{ "CD-ROM Drive/F5A",	NULL 		},
	{ "WPI CDD-820",		NULL 		},
	{ "SAMSUNG CD-ROM SC-148C",	NULL 		},
	{ "SAMSUNG CD-ROM SC",	NULL 		},
	{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",	NULL 		},
	{ "_NEC DV5800A",               NULL            },
78
	{ "SAMSUNG CD-ROM SN-124",	"N001" },
79
	{ "Seagate STT20000A",		NULL  },
80
	{ "CD-ROM CDR_U200",		"1.09" },
L
Linus Torvalds 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94
	{ NULL			,	NULL		}

};

/**
 *	ide_dma_intr	-	IDE DMA interrupt handler
 *	@drive: the drive the interrupt is for
 *
 *	Handle an interrupt completing a read/write DMA transfer on an 
 *	IDE device
 */
 
ide_startstop_t ide_dma_intr (ide_drive_t *drive)
{
95
	ide_hwif_t *hwif = drive->hwif;
L
Linus Torvalds 已提交
96 97
	u8 stat = 0, dma_stat = 0;

98
	dma_stat = hwif->dma_ops->dma_end(drive);
99
	stat = hwif->tp_ops->read_status(hwif);
100

101
	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
L
Linus Torvalds 已提交
102 103 104
		if (!dma_stat) {
			struct request *rq = HWGROUP(drive)->rq;

T
Tejun Heo 已提交
105
			task_end_request(drive, rq, stat);
L
Linus Torvalds 已提交
106 107 108 109 110 111 112 113 114 115
			return ide_stopped;
		}
		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
		       drive->name, dma_stat);
	}
	return ide_error(drive, "dma_intr", stat);
}

EXPORT_SYMBOL_GPL(ide_dma_intr);

116 117 118 119 120
static int ide_dma_good_drive(ide_drive_t *drive)
{
	return ide_in_drive_list(drive->id, drive_whitelist);
}

L
Linus Torvalds 已提交
121 122 123 124 125
/**
 *	ide_build_sglist	-	map IDE scatter gather for DMA I/O
 *	@drive: the drive to build the DMA table for
 *	@rq: the request holding the sg list
 *
126 127
 *	Perform the DMA mapping magic necessary to access the source or
 *	target buffers of a request via DMA.  The lower layers of the
L
Linus Torvalds 已提交
128
 *	kernel provide the necessary cache management so that we can
129
 *	operate in a portable fashion.
L
Linus Torvalds 已提交
130 131 132 133 134 135 136 137 138 139
 */

int ide_build_sglist(ide_drive_t *drive, struct request *rq)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct scatterlist *sg = hwif->sg_table;

	ide_map_sg(drive, rq);

	if (rq_data_dir(rq) == READ)
140
		hwif->sg_dma_direction = DMA_FROM_DEVICE;
L
Linus Torvalds 已提交
141
	else
142
		hwif->sg_dma_direction = DMA_TO_DEVICE;
L
Linus Torvalds 已提交
143

144 145
	return dma_map_sg(hwif->dev, sg, hwif->sg_nents,
			  hwif->sg_dma_direction);
L
Linus Torvalds 已提交
146 147 148 149
}

EXPORT_SYMBOL_GPL(ide_build_sglist);

150
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
L
Linus Torvalds 已提交
151 152 153 154 155
/**
 *	ide_build_dmatable	-	build IDE DMA table
 *
 *	ide_build_dmatable() prepares a dma request. We map the command
 *	to get the pci bus addresses of the buffers and then build up
156 157 158 159 160
 *	the PRD table that the IDE layer wants to be fed.
 *
 *	Most chipsets correctly interpret a length of 0x0000 as 64KB,
 *	but at least one (e.g. CS5530) misinterprets it as zero (!).
 *	So we break the 64KB entry into two 32KB entries instead.
L
Linus Torvalds 已提交
161 162 163 164 165 166 167 168 169 170
 *
 *	Returns the number of built PRD entries if all went okay,
 *	returns 0 otherwise.
 *
 *	May also be invoked from trm290.c
 */
 
int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
{
	ide_hwif_t *hwif	= HWIF(drive);
171
	__le32 *table = (__le32 *)hwif->dmatable_cpu;
L
Linus Torvalds 已提交
172 173 174 175 176
	unsigned int is_trm290	= (hwif->chipset == ide_trm290) ? 1 : 0;
	unsigned int count = 0;
	int i;
	struct scatterlist *sg;

177 178
	hwif->sg_nents = ide_build_sglist(drive, rq);
	if (hwif->sg_nents == 0)
L
Linus Torvalds 已提交
179 180
		return 0;

181 182
	for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
		u32 cur_addr, cur_len, xcount, bcount;
L
Linus Torvalds 已提交
183 184 185 186 187 188 189 190 191 192 193

		cur_addr = sg_dma_address(sg);
		cur_len = sg_dma_len(sg);

		/*
		 * Fill in the dma table, without crossing any 64kB boundaries.
		 * Most hardware requires 16-bit alignment of all blocks,
		 * but the trm290 requires 32-bit alignment.
		 */

		while (cur_len) {
194
			if (count++ >= PRD_ENTRIES)
L
Linus Torvalds 已提交
195
				goto use_pio_instead;
196 197 198 199 200 201 202 203 204 205 206 207 208 209

			bcount = 0x10000 - (cur_addr & 0xffff);
			if (bcount > cur_len)
				bcount = cur_len;
			*table++ = cpu_to_le32(cur_addr);
			xcount = bcount & 0xffff;
			if (is_trm290)
				xcount = ((xcount >> 2) - 1) << 16;
			if (xcount == 0x0000) {
				if (count++ >= PRD_ENTRIES)
					goto use_pio_instead;
				*table++ = cpu_to_le32(0x8000);
				*table++ = cpu_to_le32(cur_addr + 0x8000);
				xcount = 0x8000;
L
Linus Torvalds 已提交
210
			}
211 212 213
			*table++ = cpu_to_le32(xcount);
			cur_addr += bcount;
			cur_len -= bcount;
L
Linus Torvalds 已提交
214 215 216 217 218 219 220 221
		}
	}

	if (count) {
		if (!is_trm290)
			*--table |= cpu_to_le32(0x80000000);
		return count;
	}
222

L
Linus Torvalds 已提交
223
use_pio_instead:
224 225 226
	printk(KERN_ERR "%s: %s\n", drive->name,
		count ? "DMA table too small" : "empty DMA table?");

227 228
	ide_destroy_dmatable(drive);

L
Linus Torvalds 已提交
229 230 231
	return 0; /* revert to PIO for this request */
}
EXPORT_SYMBOL_GPL(ide_build_dmatable);
232
#endif
L
Linus Torvalds 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245 246

/**
 *	ide_destroy_dmatable	-	clean up DMA mapping
 *	@drive: The drive to unmap
 *
 *	Teardown mappings after DMA has completed. This must be called
 *	after the completion of each use of ide_build_dmatable and before
 *	the next use of ide_build_dmatable. Failure to do so will cause
 *	an oops as only one mapping can be live for each target at a given
 *	time.
 */
 
void ide_destroy_dmatable (ide_drive_t *drive)
{
247
	ide_hwif_t *hwif = drive->hwif;
L
Linus Torvalds 已提交
248

249
	dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents,
250
		     hwif->sg_dma_direction);
L
Linus Torvalds 已提交
251 252 253 254
}

EXPORT_SYMBOL_GPL(ide_destroy_dmatable);

255
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
L
Linus Torvalds 已提交
256 257 258 259 260 261 262 263 264 265 266 267 268
/**
 *	config_drive_for_dma	-	attempt to activate IDE DMA
 *	@drive: the drive to place in DMA mode
 *
 *	If the drive supports at least mode 2 DMA or UDMA of any kind
 *	then attempt to place it into DMA mode. Drives that are known to
 *	support DMA but predate the DMA properties or that are known
 *	to have DMA handling bugs are also set up appropriately based
 *	on the good/bad drive lists.
 */
 
static int config_drive_for_dma (ide_drive_t *drive)
{
269
	ide_hwif_t *hwif = drive->hwif;
270
	u16 *id = drive->id;
L
Linus Torvalds 已提交
271

272 273
	if (drive->media != ide_disk) {
		if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
274
			return 0;
275
	}
276

277 278 279 280
	/*
	 * Enable DMA on any drive that has
	 * UltraDMA (mode 0/1/2/3/4/5/6) enabled
	 */
281 282
	if ((id[ATA_ID_FIELD_VALID] & 4) &&
	    ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f))
283 284 285 286 287 288
		return 1;

	/*
	 * Enable DMA on any drive that has mode2 DMA
	 * (multi or single) enabled
	 */
289 290 291
	if (id[ATA_ID_FIELD_VALID] & 2)	/* regular DMA */
		if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
		    (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
292
			return 1;
293

294 295 296 297 298
	/* Consult the list of known "good" drives */
	if (ide_dma_good_drive(drive))
		return 1;

	return 0;
L
Linus Torvalds 已提交
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
}

/**
 *	dma_timer_expiry	-	handle a DMA timeout
 *	@drive: Drive that timed out
 *
 *	An IDE DMA transfer timed out. In the event of an error we ask
 *	the driver to resolve the problem, if a DMA transfer is still
 *	in progress we continue to wait (arguably we need to add a 
 *	secondary 'I don't care what the drive thinks' timeout here)
 *	Finally if we have an interrupt we let it complete the I/O.
 *	But only one time - we clear expiry and if it's still not
 *	completed after WAIT_CMD, we error and retry in PIO.
 *	This can occur if an interrupt is lost or due to hang or bugs.
 */
 
static int dma_timer_expiry (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
318
	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);
L
Linus Torvalds 已提交
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

	printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n",
		drive->name, dma_stat);

	if ((dma_stat & 0x18) == 0x18)	/* BUSY Stupid Early Timer !! */
		return WAIT_CMD;

	HWGROUP(drive)->expiry = NULL;	/* one free ride for now */

	/* 1 dmaing, 2 error, 4 intr */
	if (dma_stat & 2)	/* ERROR */
		return -1;

	if (dma_stat & 1)	/* DMAing */
		return WAIT_CMD;

	if (dma_stat & 4)	/* Got an Interrupt */
		return WAIT_CMD;

	return 0;	/* Status is unknown -- reset the bus */
}

/**
342
 *	ide_dma_host_set	-	Enable/disable DMA on a host
L
Linus Torvalds 已提交
343 344
 *	@drive: drive to control
 *
345 346
 *	Enable/disable DMA on an IDE controller following generic
 *	bus-mastering IDE controller behaviour.
L
Linus Torvalds 已提交
347 348
 */

349
void ide_dma_host_set(ide_drive_t *drive, int on)
L
Linus Torvalds 已提交
350 351
{
	ide_hwif_t *hwif	= HWIF(drive);
352
	u8 unit			= drive->dn & 1;
353
	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);
L
Linus Torvalds 已提交
354

355 356 357 358 359
	if (on)
		dma_stat |= (1 << (5 + unit));
	else
		dma_stat &= ~(1 << (5 + unit));

360
	if (hwif->host_flags & IDE_HFLAG_MMIO)
361 362
		writeb(dma_stat,
		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
363
	else
364
		outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
L
Linus Torvalds 已提交
365 366
}

367
EXPORT_SYMBOL_GPL(ide_dma_host_set);
368
#endif /* CONFIG_BLK_DEV_IDEDMA_SFF  */
L
Linus Torvalds 已提交
369 370

/**
371
 *	ide_dma_off_quietly	-	Generic DMA kill
L
Linus Torvalds 已提交
372 373 374 375 376
 *	@drive: drive to control
 *
 *	Turn off the current DMA on this IDE controller. 
 */

377
void ide_dma_off_quietly(ide_drive_t *drive)
L
Linus Torvalds 已提交
378
{
B
Bartlomiej Zolnierkiewicz 已提交
379
	drive->dev_flags &= ~IDE_DFLAG_USING_DMA;
L
Linus Torvalds 已提交
380 381
	ide_toggle_bounce(drive, 0);

382
	drive->hwif->dma_ops->dma_host_set(drive, 0);
L
Linus Torvalds 已提交
383 384
}

385
EXPORT_SYMBOL(ide_dma_off_quietly);
L
Linus Torvalds 已提交
386 387

/**
388
 *	ide_dma_off	-	disable DMA on a device
L
Linus Torvalds 已提交
389 390 391 392 393 394
 *	@drive: drive to disable DMA on
 *
 *	Disable IDE DMA for a device on this IDE controller.
 *	Inform the user that DMA has been disabled.
 */

395
void ide_dma_off(ide_drive_t *drive)
L
Linus Torvalds 已提交
396 397
{
	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
398
	ide_dma_off_quietly(drive);
L
Linus Torvalds 已提交
399 400
}

401
EXPORT_SYMBOL(ide_dma_off);
L
Linus Torvalds 已提交
402 403

/**
404
 *	ide_dma_on		-	Enable DMA on a device
L
Linus Torvalds 已提交
405 406 407 408
 *	@drive: drive to enable DMA on
 *
 *	Enable IDE DMA for a device on this IDE controller.
 */
409 410

void ide_dma_on(ide_drive_t *drive)
L
Linus Torvalds 已提交
411
{
B
Bartlomiej Zolnierkiewicz 已提交
412
	drive->dev_flags |= IDE_DFLAG_USING_DMA;
L
Linus Torvalds 已提交
413 414
	ide_toggle_bounce(drive, 1);

415
	drive->hwif->dma_ops->dma_host_set(drive, 1);
L
Linus Torvalds 已提交
416 417
}

418
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
L
Linus Torvalds 已提交
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
/**
 *	ide_dma_setup	-	begin a DMA phase
 *	@drive: target device
 *
 *	Build an IDE DMA PRD (IDE speak for scatter gather table)
 *	and then set up the DMA transfer registers for a device
 *	that follows generic IDE PCI DMA behaviour. Controllers can
 *	override this function if they need to
 *
 *	Returns 0 on success. If a PIO fallback is required then 1
 *	is returned. 
 */

int ide_dma_setup(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	struct request *rq = HWGROUP(drive)->rq;
	unsigned int reading;
437
	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
L
Linus Torvalds 已提交
438 439 440 441 442 443 444 445 446 447 448 449 450 451
	u8 dma_stat;

	if (rq_data_dir(rq))
		reading = 0;
	else
		reading = 1 << 3;

	/* fall back to pio! */
	if (!ide_build_dmatable(drive, rq)) {
		ide_map_sg(drive, rq);
		return 1;
	}

	/* PRD table */
452
	if (hwif->host_flags & IDE_HFLAG_MMIO)
453 454
		writel(hwif->dmatable_dma,
		       (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
455
	else
456
		outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS);
L
Linus Torvalds 已提交
457 458

	/* specify r/w */
459
	if (mmio)
460
		writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
461
	else
462
		outb(reading, hwif->dma_base + ATA_DMA_CMD);
L
Linus Torvalds 已提交
463

464
	/* read DMA status for INTR & ERROR flags */
465
	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
L
Linus Torvalds 已提交
466 467

	/* clear INTR & ERROR flags */
468
	if (mmio)
469 470
		writeb(dma_stat | 6,
		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
471
	else
472
		outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
473

L
Linus Torvalds 已提交
474 475 476 477 478 479
	drive->waiting_for_dma = 1;
	return 0;
}

EXPORT_SYMBOL_GPL(ide_dma_setup);

480
void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
L
Linus Torvalds 已提交
481 482 483 484
{
	/* issue cmd to drive */
	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
}
485
EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
L
Linus Torvalds 已提交
486 487 488

void ide_dma_start(ide_drive_t *drive)
{
489 490
	ide_hwif_t *hwif = drive->hwif;
	u8 dma_cmd;
L
Linus Torvalds 已提交
491 492 493 494 495 496

	/* Note that this is done *after* the cmd has
	 * been issued to the drive, as per the BM-IDE spec.
	 * The Promise Ultra33 doesn't work correctly when
	 * we do this part before issuing the drive cmd.
	 */
497
	if (hwif->host_flags & IDE_HFLAG_MMIO) {
498
		dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
499
		/* start DMA */
500 501
		writeb(dma_cmd | 1,
		       (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
502
	} else {
503 504
		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
		outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD);
505 506
	}

L
Linus Torvalds 已提交
507 508 509 510 511 512
	wmb();
}

EXPORT_SYMBOL_GPL(ide_dma_start);

/* returns 1 on error, 0 otherwise */
513
int ide_dma_end(ide_drive_t *drive)
L
Linus Torvalds 已提交
514
{
515 516
	ide_hwif_t *hwif = drive->hwif;
	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
L
Linus Torvalds 已提交
517 518 519
	u8 dma_stat = 0, dma_cmd = 0;

	drive->waiting_for_dma = 0;
520 521 522

	if (mmio) {
		/* get DMA command mode */
523
		dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
524
		/* stop DMA */
525 526
		writeb(dma_cmd & ~1,
		       (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
527
	} else {
528 529
		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
		outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
530 531
	}

L
Linus Torvalds 已提交
532
	/* get DMA status */
533
	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
534 535 536

	if (mmio)
		/* clear the INTR & ERROR bits */
537 538
		writeb(dma_stat | 6,
		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
539
	else
540
		outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
541

L
Linus Torvalds 已提交
542 543 544 545 546 547
	/* purge DMA mappings */
	ide_destroy_dmatable(drive);
	/* verify good DMA status */
	wmb();
	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
}
548
EXPORT_SYMBOL_GPL(ide_dma_end);
L
Linus Torvalds 已提交
549 550

/* returns 1 if dma irq issued, 0 otherwise */
551
int ide_dma_test_irq(ide_drive_t *drive)
L
Linus Torvalds 已提交
552 553
{
	ide_hwif_t *hwif	= HWIF(drive);
554
	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);
L
Linus Torvalds 已提交
555 556 557 558

	/* return 1 if INTR asserted */
	if ((dma_stat & 4) == 4)
		return 1;
559

L
Linus Torvalds 已提交
560 561
	return 0;
}
562
EXPORT_SYMBOL_GPL(ide_dma_test_irq);
563 564
#else
static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
565
#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
L
Linus Torvalds 已提交
566 567 568

int __ide_dma_bad_drive (ide_drive_t *drive)
{
569
	u16 *id = drive->id;
L
Linus Torvalds 已提交
570

571
	int blacklist = ide_in_drive_list(id, drive_blacklist);
L
Linus Torvalds 已提交
572 573
	if (blacklist) {
		printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n",
574
				    drive->name, (char *)&id[ATA_ID_PROD]);
L
Linus Torvalds 已提交
575 576 577 578 579 580 581
		return blacklist;
	}
	return 0;
}

EXPORT_SYMBOL(__ide_dma_bad_drive);

582 583 584 585 586 587
static const u8 xfer_mode_bases[] = {
	XFER_UDMA_0,
	XFER_MW_DMA_0,
	XFER_SW_DMA_0,
};

588
static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
589
{
590
	u16 *id = drive->id;
591
	ide_hwif_t *hwif = drive->hwif;
592
	const struct ide_port_ops *port_ops = hwif->port_ops;
593 594 595 596
	unsigned int mask = 0;

	switch(base) {
	case XFER_UDMA_0:
597
		if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
598 599
			break;

600 601
		if (port_ops && port_ops->udma_filter)
			mask = port_ops->udma_filter(drive);
602 603
		else
			mask = hwif->ultra_mask;
604
		mask &= id[ATA_ID_UDMA_MODES];
605

606 607 608 609 610 611 612
		/*
		 * avoid false cable warning from eighty_ninty_three()
		 */
		if (req_mode > XFER_UDMA_2) {
			if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
				mask &= 0x07;
		}
613 614
		break;
	case XFER_MW_DMA_0:
615
		if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
616
			break;
617 618
		if (port_ops && port_ops->mdma_filter)
			mask = port_ops->mdma_filter(drive);
619 620
		else
			mask = hwif->mwdma_mask;
621
		mask &= id[ATA_ID_MWDMA_MODES];
622 623
		break;
	case XFER_SW_DMA_0:
624 625
		if (id[ATA_ID_FIELD_VALID] & 2) {
			mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
626 627
		} else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
			u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
628 629 630 631 632 633 634 635

			/*
			 * if the mode is valid convert it to the mask
			 * (the maximum allowed mode is XFER_SW_DMA_2)
			 */
			if (mode <= 2)
				mask = ((2 << mode) - 1) & hwif->swdma_mask;
		}
636 637 638 639 640 641 642 643 644 645
		break;
	default:
		BUG();
		break;
	}

	return mask;
}

/**
646
 *	ide_find_dma_mode	-	compute DMA speed
647
 *	@drive: IDE device
648 649 650 651
 *	@req_mode: requested mode
 *
 *	Checks the drive/host capabilities and finds the speed to use for
 *	the DMA transfer.  The speed is then limited by the requested mode.
652
 *
653 654
 *	Returns 0 if the drive/host combination is incapable of DMA transfers
 *	or if the requested mode is not a DMA mode.
655 656
 */

657
u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
658 659 660 661 662 663
{
	ide_hwif_t *hwif = drive->hwif;
	unsigned int mask;
	int x, i;
	u8 mode = 0;

664 665 666 667
	if (drive->media != ide_disk) {
		if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
			return 0;
	}
668 669

	for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
670 671 672
		if (req_mode < xfer_mode_bases[i])
			continue;
		mask = ide_get_mode_mask(drive, xfer_mode_bases[i], req_mode);
673 674 675 676 677 678 679
		x = fls(mask) - 1;
		if (x >= 0) {
			mode = xfer_mode_bases[i] + x;
			break;
		}
	}

680 681 682 683
	if (hwif->chipset == ide_acorn && mode == 0) {
		/*
		 * is this correct?
		 */
684 685
		if (ide_dma_good_drive(drive) &&
		    drive->id[ATA_ID_EIDE_DMA_TIME] < 150)
686 687 688
			mode = XFER_MW_DMA_1;
	}

689 690 691
	mode = min(mode, req_mode);

	printk(KERN_INFO "%s: %s mode selected\n", drive->name,
692
			  mode ? ide_xfer_verbose(mode) : "no DMA");
693

694
	return mode;
695 696
}

697
EXPORT_SYMBOL_GPL(ide_find_dma_mode);
698

699
static int ide_tune_dma(ide_drive_t *drive)
700
{
701
	ide_hwif_t *hwif = drive->hwif;
702 703
	u8 speed;

B
Bartlomiej Zolnierkiewicz 已提交
704 705
	if (ata_id_has_dma(drive->id) == 0 ||
	    (drive->dev_flags & IDE_DFLAG_NODMA))
706 707 708 709
		return 0;

	/* consult the list of known "bad" drives */
	if (__ide_dma_bad_drive(drive))
710 711
		return 0;

712 713 714
	if (ide_id_dma_bug(drive))
		return 0;

715
	if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
716 717
		return config_drive_for_dma(drive);

718 719
	speed = ide_max_dma_mode(drive);

720 721
	if (!speed)
		return 0;
722

723
	if (ide_set_dma_mode(drive, speed))
724
		return 0;
725

726
	return 1;
727 728
}

729 730 731 732
static int ide_dma_check(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;

733
	if (ide_tune_dma(drive))
734 735 736 737 738 739 740 741
		return 0;

	/* TODO: always do PIO fallback */
	if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
		return -1;

	ide_set_max_pio(drive);

742
	return -1;
743 744
}

745
int ide_id_dma_bug(ide_drive_t *drive)
L
Linus Torvalds 已提交
746
{
747
	u16 *id = drive->id;
L
Linus Torvalds 已提交
748

749 750 751
	if (id[ATA_ID_FIELD_VALID] & 4) {
		if ((id[ATA_ID_UDMA_MODES] >> 8) &&
		    (id[ATA_ID_MWDMA_MODES] >> 8))
752
			goto err_out;
753 754 755
	} else if (id[ATA_ID_FIELD_VALID] & 2) {
		if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
		    (id[ATA_ID_SWDMA_MODES] >> 8))
756
			goto err_out;
L
Linus Torvalds 已提交
757
	}
758 759 760 761
	return 0;
err_out:
	printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
	return 1;
L
Linus Torvalds 已提交
762 763
}

764 765 766 767
int ide_set_dma(ide_drive_t *drive)
{
	int rc;

768 769 770 771 772 773
	/*
	 * Force DMAing for the beginning of the check.
	 * Some chipsets appear to do interesting
	 * things, if not checked and cleared.
	 *   PARANOIA!!!
	 */
774
	ide_dma_off_quietly(drive);
775

776 777 778
	rc = ide_dma_check(drive);
	if (rc)
		return rc;
779

780 781 782
	ide_dma_on(drive);

	return 0;
783 784
}

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
void ide_check_dma_crc(ide_drive_t *drive)
{
	u8 mode;

	ide_dma_off_quietly(drive);
	drive->crc_count = 0;
	mode = drive->current_speed;
	/*
	 * Don't try non Ultra-DMA modes without iCRC's.  Force the
	 * device to PIO and make the user enable SWDMA/MWDMA modes.
	 */
	if (mode > XFER_UDMA_0 && mode <= XFER_UDMA_7)
		mode--;
	else
		mode = XFER_PIO_4;
	ide_set_xfer_rate(drive, mode);
	if (drive->current_speed >= XFER_SW_DMA_0)
		ide_dma_on(drive);
}

805
void ide_dma_lost_irq(ide_drive_t *drive)
L
Linus Torvalds 已提交
806
{
807
	printk(KERN_ERR "%s: DMA interrupt recovery\n", drive->name);
L
Linus Torvalds 已提交
808
}
809
EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
L
Linus Torvalds 已提交
810

811
void ide_dma_timeout(ide_drive_t *drive)
L
Linus Torvalds 已提交
812
{
813 814
	ide_hwif_t *hwif = HWIF(drive);

L
Linus Torvalds 已提交
815 816
	printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);

817
	if (hwif->dma_ops->dma_test_irq(drive))
818 819
		return;

820 821
	ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));

822
	hwif->dma_ops->dma_end(drive);
L
Linus Torvalds 已提交
823
}
824
EXPORT_SYMBOL_GPL(ide_dma_timeout);
L
Linus Torvalds 已提交
825

826
void ide_release_dma_engine(ide_hwif_t *hwif)
L
Linus Torvalds 已提交
827 828
{
	if (hwif->dmatable_cpu) {
829
		int prd_size = hwif->prd_max_nents * hwif->prd_ent_size;
830

831 832
		dma_free_coherent(hwif->dev, prd_size,
				  hwif->dmatable_cpu, hwif->dmatable_dma);
L
Linus Torvalds 已提交
833 834 835
		hwif->dmatable_cpu = NULL;
	}
}
836
EXPORT_SYMBOL_GPL(ide_release_dma_engine);
L
Linus Torvalds 已提交
837

838
int ide_allocate_dma_engine(ide_hwif_t *hwif)
L
Linus Torvalds 已提交
839
{
840
	int prd_size;
841

842 843 844 845
	if (hwif->prd_max_nents == 0)
		hwif->prd_max_nents = PRD_ENTRIES;
	if (hwif->prd_ent_size == 0)
		hwif->prd_ent_size = PRD_BYTES;
L
Linus Torvalds 已提交
846

847
	prd_size = hwif->prd_max_nents * hwif->prd_ent_size;
L
Linus Torvalds 已提交
848

849 850 851 852 853
	hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev, prd_size,
						&hwif->dmatable_dma,
						GFP_ATOMIC);
	if (hwif->dmatable_cpu == NULL) {
		printk(KERN_ERR "%s: unable to allocate PRD table\n",
854
			hwif->name);
855 856
		return -ENOMEM;
	}
L
Linus Torvalds 已提交
857

858
	return 0;
L
Linus Torvalds 已提交
859
}
860
EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
L
Linus Torvalds 已提交
861

862
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
863
const struct ide_dma_ops sff_dma_ops = {
864 865 866 867
	.dma_host_set		= ide_dma_host_set,
	.dma_setup		= ide_dma_setup,
	.dma_exec_cmd		= ide_dma_exec_cmd,
	.dma_start		= ide_dma_start,
868
	.dma_end		= ide_dma_end,
869
	.dma_test_irq		= ide_dma_test_irq,
870 871 872
	.dma_timeout		= ide_dma_timeout,
	.dma_lost_irq		= ide_dma_lost_irq,
};
873
EXPORT_SYMBOL_GPL(sff_dma_ops);
874
#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */