Skip to content

Commit

Permalink
libata: Add a drivers/ide style DMA disable
Browse files Browse the repository at this point in the history
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: Alan Cox <alan@redhat.com>

[edited to work on SATA too, changing name from 'pata_dma' to 'dma']
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Alan Cox authored and Jeff Garzik committed Oct 12, 2007
1 parent 7100819 commit b3a7060
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
17 changes: 17 additions & 0 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)");
Expand Down Expand Up @@ -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);

Expand Down
6 changes: 6 additions & 0 deletions include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit b3a7060

Please sign in to comment.