Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3a70601 authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik
Browse files

libata: Add a drivers/ide style DMA disable



This is useful when debugging, handling problem systems, or for
distributions just to get the system installed so it can be sorted
out later.

This is a bit smarter than the old IDE one and lets you do

libata.dma=0	Disable all PATA DMA like old IDE
libata.dma=1	Disk DMA only
libata.dma=2	ATAPI DMA only
libata.dma=4	CF DMA only

(or combinations thereof - 0,1,3 being the useful ones I suspect)

(I've split CF as it seems to be a seperate case of pain and suffering
different to the others and caused by assorted PIO wired adapters etc)

Signed-off-by: default avatarAlan Cox <alan@redhat.com>

[edited to work on SATA too, changing name from 'pata_dma' to 'dma']
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 7100819f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -97,6 +97,10 @@ static int ata_ignore_hpa = 0;
module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");

static int libata_dma_mask = ATA_DMA_MASK_ATA|ATA_DMA_MASK_ATAPI|ATA_DMA_MASK_CFA;
module_param_named(dma, libata_dma_mask, int, 0444);
MODULE_PARM_DESC(dma, "DMA enable/disable (0x1==ATA, 0x2==ATAPI, 0x4==CF)");

static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
module_param(ata_probe_timeout, int, 0444);
MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
@@ -2917,14 +2921,27 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
	/* step 1: calculate xfer_mask */
	ata_link_for_each_dev(dev, link) {
		unsigned int pio_mask, dma_mask;
		unsigned int mode_mask;

		if (!ata_dev_enabled(dev))
			continue;

		mode_mask = ATA_DMA_MASK_ATA;
		if (dev->class == ATA_DEV_ATAPI)
			mode_mask = ATA_DMA_MASK_ATAPI;
		else if (ata_id_is_cfa(dev->id))
			mode_mask = ATA_DMA_MASK_CFA;

		ata_dev_xfermask(dev);

		pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
		dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);

		if (libata_dma_mask & mode_mask)
			dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
		else
			dma_mask = 0;

		dev->pio_mode = ata_xfer_mask2mode(pio_mask);
		dev->dma_mode = ata_xfer_mask2mode(dma_mask);

+6 −0
Original line number Diff line number Diff line
@@ -331,6 +331,12 @@ enum {
	ATA_HORKAGE_BROKEN_HPA	= (1 << 4),	/* Broken HPA */
	ATA_HORKAGE_SKIP_PM	= (1 << 5),	/* Skip PM operations */
	ATA_HORKAGE_HPA_SIZE	= (1 << 6),	/* native size off by one */

	 /* DMA mask for user DMA control: User visible values; DO NOT 
	    renumber */
	ATA_DMA_MASK_ATA	= (1 << 0),	/* DMA on ATA Disk */
	ATA_DMA_MASK_ATAPI	= (1 << 1),	/* DMA on ATAPI */
	ATA_DMA_MASK_CFA	= (1 << 2),	/* DMA on CF Card */
};

enum hsm_task_states {