Subject: [PATCH 1/8] ide: always auto-tune PIO in legacy VLB host drivers

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/legacy/ali14xx.c | 2 +-
drivers/ide/legacy/dtc2278.c | 3 +--
drivers/ide/legacy/ht6560b.c | 1 -
drivers/ide/legacy/qd65xx.c | 5 +----
drivers/ide/legacy/umc8672.c | 2 +-
5 files changed, 4 insertions(+), 9 deletions(-)

Index: b/drivers/ide/legacy/ali14xx.c
===================================================================
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -202,7 +202,7 @@ static const struct ide_port_info ali14x
.name = DRV_NAME,
.chipset = ide_ali14xx,
.port_ops = &ali14xx_port_ops,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE,
+ .host_flags = IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};

Index: b/drivers/ide/legacy/dtc2278.c
===================================================================
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -101,8 +101,7 @@ static const struct ide_port_info dtc227
IDE_HFLAG_IO_32BIT |
/* disallow ->io_32bit changes */
IDE_HFLAG_NO_IO_32BIT |
- IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE,
+ IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};

Index: b/drivers/ide/legacy/ht6560b.c
===================================================================
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -340,7 +340,6 @@ static const struct ide_port_info ht6560
.port_ops = &ht6560b_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */
IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE |
IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO4,
};
Index: b/drivers/ide/legacy/qd65xx.c
===================================================================
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -12,8 +12,6 @@
* QDI QD6500/QD6580 EIDE controller fast support
*
* To activate controller support, use "ide0=qd65xx"
- * To enable tuning, use "hda=autotune hdb=autotune"
- * To enable 2nd channel tuning (qd6580 only), use "hdc=autotune hdd=autotune"
*/

/*
@@ -324,8 +322,7 @@ static const struct ide_port_info qd65xx
.name = DRV_NAME,
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
- IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE,
+ IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};

Index: b/drivers/ide/legacy/umc8672.c
===================================================================
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -130,7 +130,7 @@ static const struct ide_port_info umc867
.name = DRV_NAME,
.chipset = ide_umc8672,
.port_ops = &umc8672_port_ops,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE,
+ .host_flags = IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};


Subject: [PATCH 2/8] cmd640: always auto-tune PIO

* Default to tuning PIO0 and disabling prefetch prior to probing
devices for CONFIG_BLK_DEV_CMD640_ENHANCED=y case.

* Always auto-tune PIO.

* Remove no longer used retrieve_drive_counts().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/pci/cmd640.c | 67 ++++++++---------------------------------------
1 file changed, 12 insertions(+), 55 deletions(-)

Index: b/drivers/ide/pci/cmd640.c
===================================================================
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -380,6 +380,7 @@ static void cmd640_dump_regs(void)
}
#endif

+#ifndef CONFIG_BLK_DEV_CMD640_ENHANCED
/*
* Check whether prefetch is on for a drive,
* and initialize the unmask flags for safe operation.
@@ -400,9 +401,7 @@ static void __init check_prefetch(ide_dr
drive->no_io_32bit = 0;
}
}
-
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-
+#else
/*
* Sets prefetch mode for a drive.
*/
@@ -459,34 +458,6 @@ static inline u8 pack_nibbles(u8 upper,
}

/*
- * This routine retrieves the initial drive timings from the chipset.
- */
-static void __init retrieve_drive_counts(unsigned int index)
-{
- u8 b;
-
- /*
- * Get the internal setup timing, and convert to clock count
- */
- b = get_cmd640_reg(arttim_regs[index]) & ~0x3f;
- switch (b) {
- case 0x00: b = 4; break;
- case 0x80: b = 3; break;
- case 0x40: b = 2; break;
- default: b = 5; break;
- }
- setup_counts[index] = b;
-
- /*
- * Get the active/recovery counts
- */
- b = get_cmd640_reg(drwtim_regs[index]);
- active_counts[index] = (b >> 4) ? (b >> 4) : 0x10;
- recovery_counts[index] = (b & 0x0f) ? (b & 0x0f) : 0x10;
-}
-
-
-/*
* This routine writes the prepared setup/active/recovery counts
* for a drive into the cmd640 chipset registers to active them.
*/
@@ -681,7 +652,6 @@ static const struct ide_port_info cmd640
.chipset = ide_cmd640,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE |
IDE_HFLAG_ABUSE_PREFETCH |
IDE_HFLAG_ABUSE_FAST_DEVSEL,
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
@@ -864,29 +834,16 @@ static int __init cmd640x_init(void)
}

#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- if (drive->autotune || ((index > 1) && second_port_toggled)) {
- /*
- * Reset timing to the slowest speed and turn off
- * prefetch. This way, the drive identify code has
- * a better chance.
- */
- setup_counts [index] = 4; /* max possible */
- active_counts [index] = 16; /* max possible */
- recovery_counts [index] = 16; /* max possible */
- program_drive_counts(drive, index);
- set_prefetch_mode(drive, index, 0);
- printk("cmd640: drive%d timings/prefetch cleared\n", index);
- } else {
- /*
- * Record timings/prefetch without changing them.
- * This preserves any prior BIOS setup.
- */
- retrieve_drive_counts (index);
- check_prefetch(drive, index);
- printk("cmd640: drive%d timings/prefetch(%s) preserved",
- index, drive->no_io_32bit ? "off" : "on");
- display_clocks(index);
- }
+ /*
+ * Reset timing to the slowest speed and turn off prefetch.
+ * This way, the drive identify code has a better chance.
+ */
+ setup_counts [index] = 4; /* max possible */
+ active_counts [index] = 16; /* max possible */
+ recovery_counts [index] = 16; /* max possible */
+ program_drive_counts(drive, index);
+ set_prefetch_mode(drive, index, 0);
+ printk("cmd640: drive%d timings/prefetch cleared\n", index);
#else
/*
* Set the drive unmask flags to match the prefetch setting

Subject: [PATCH 3/8] ide: remove IDE_HFLAG_NO_AUTOTUNE host flag

* Don't set IDE_HFLAG_NO_AUTOTUNE host flag in sgiioc4 and icside
host drivers - there is no need for it as they don't implement
->set_pio_mode method.

* Remove no longer needed IDE_HFLAG_NO_AUTOTUNE host flag.

There should be no functional changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/arm/icside.c | 3 +--
drivers/ide/ide-probe.c | 3 +--
drivers/ide/pci/sgiioc4.c | 1 -
include/linux/ide.h | 2 --
4 files changed, 2 insertions(+), 7 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -480,8 +480,7 @@ static const struct ide_port_info icside
.init_dma = icside_dma_off_init,
.port_ops = &icside_v6_no_dma_port_ops,
.dma_ops = &icside_v6_dma_ops,
- .host_flags = IDE_HFLAG_SERIALIZE |
- IDE_HFLAG_NO_AUTOTUNE,
+ .host_flags = IDE_HFLAG_SERIALIZE,
.mwdma_mask = ATA_MWDMA2,
.swdma_mask = ATA_SWDMA2,
};
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1324,8 +1324,7 @@ static void ide_port_init_devices(ide_hw
drive->unmask = 1;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
drive->no_unmask = 1;
- if ((hwif->host_flags & IDE_HFLAG_NO_AUTOTUNE) == 0)
- drive->autotune = 1;
+ drive->autotune = 1;
}

if (port_ops && port_ops->port_init_devs)
Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -573,7 +573,6 @@ static const struct ide_port_info sgiioc
.init_dma = ide_dma_sgiioc4,
.port_ops = &sgiioc4_port_ops,
.dma_ops = &sgiioc4_dma_ops,
- .host_flags = IDE_HFLAG_NO_AUTOTUNE,
.mwdma_mask = ATA_MWDMA2_ONLY,
};

Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1062,8 +1062,6 @@ enum {
IDE_HFLAG_NO_DMA = (1 << 14),
/* check if host is PCI IDE device before allowing DMA */
IDE_HFLAG_NO_AUTODMA = (1 << 15),
- /* don't autotune PIO */
- IDE_HFLAG_NO_AUTOTUNE = (1 << 16),
/* host is CS5510/CS5520 */
IDE_HFLAG_CS5520 = IDE_HFLAG_VDMA,
/* no LBA48 */

Subject: [PATCH 4/8] ide: remove obsoleted "hdx=autotune" kernel parameter

* Remove obsoleted "hdx=autotune" kernel parameter
(we always auto-tune PIO if possible nowadays).

* Remove no longer needed ide_drive_t.autotune flag.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
Documentation/ide/ide.txt | 7 -------
drivers/ide/ide-probe.c | 4 +---
drivers/ide/ide.c | 5 +----
include/linux/ide.h | 1 -
4 files changed, 2 insertions(+), 15 deletions(-)

Index: b/Documentation/ide/ide.txt
===================================================================
--- a/Documentation/ide/ide.txt
+++ b/Documentation/ide/ide.txt
@@ -196,13 +196,6 @@ Summary of ide driver parameters for ker

"hdx=cyl,head,sect" : disk drive is present, with specified geometry

- "hdx=autotune" : driver will attempt to tune interface speed
- to the fastest PIO mode supported,
- if possible for this drive only.
- Not fully supported by all chipset types,
- and quite likely to cause trouble with
- older/odd IDE drives.
-
"hdx=nodma" : disallow DMA

"ide=doubler" : probe/support IDE doublers on Amiga
Index: b/drivers/ide/ide-probe.c
===================================================================
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -826,8 +826,7 @@ static void ide_port_tune_devices(ide_hw
ide_drive_t *drive = &hwif->drives[unit];

if (drive->present) {
- if (drive->autotune)
- ide_set_max_pio(drive);
+ ide_set_max_pio(drive);

drive->nice1 = 1;

@@ -1324,7 +1323,6 @@ static void ide_port_init_devices(ide_hw
drive->unmask = 1;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
drive->no_unmask = 1;
- drive->autotune = 1;
}

if (port_ops && port_ops->port_init_devs)
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -851,7 +851,7 @@ static int __init ide_setup(char *s)
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {
"none", "noprobe", "nowerr", "cdrom", "nodma",
- "autotune", "-7", "-8", "-9", "-10",
+ "-6", "-7", "-8", "-9", "-10",
"noflush", "remap", "remap63", "scsi", NULL };
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
@@ -879,9 +879,6 @@ static int __init ide_setup(char *s)
case -5: /* nodma */
drive->nodma = 1;
goto done;
- case -6: /* "autotune" */
- drive->autotune = 1;
- goto obsolete_option;
case -11: /* noflush */
drive->noflush = 1;
goto done;
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -322,7 +322,6 @@ typedef struct ide_drive_s {
unsigned atapi_overlap : 1; /* ATAPI overlap (not supported) */
unsigned doorlocking : 1; /* for removable only: door lock/unlock works */
unsigned nodma : 1; /* disallow DMA */
- unsigned autotune : 1; /* 0=default, 1=autotune */
unsigned remap_0_to_1 : 1; /* 0=noremap, 1=remap 0->1 (for EZDrive) */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
unsigned vdma : 1; /* 1=doing PIO over DMA 0=doing normal DMA */

Subject: [PATCH 5/8] ide: add "nodma|noflush|noprobe|nowerr=" parameters

* Add "nodma|noflush|noprobe|nowerr=" parameters.

* Obsolete "hdx=noprobe|none|nowerr|nodma|noflush" kernel parameters.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
Documentation/ide/ide.txt | 26 +++++++--------
drivers/ide/ide.c | 79 +++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 88 insertions(+), 17 deletions(-)

Index: b/Documentation/ide/ide.txt
===================================================================
--- a/Documentation/ide/ide.txt
+++ b/Documentation/ide/ide.txt
@@ -99,10 +99,10 @@ with hd.c but not with ide.c), then an c
for each drive for which you'd like the drive to skip the hardware
probe/identification sequence. For example:

- hdb=noprobe
+ ide_core.noprobe=0.1
or
hdc=768,16,32
- hdc=noprobe
+ ide_core.noprobe=1.0

Note that when only one IDE device is attached to an interface, it should be
jumpered as "single" or "master", *not* "slave". Many folks have had
@@ -174,9 +174,7 @@ to /etc/modprobe.conf.

When ide.c is used as a module, you can pass command line parameters to the
driver using the "options=" keyword to insmod, while replacing any ',' with
-';'. For example:
-
- insmod ide.o options="hda=nodma hdb=nodma"
+';'.


================================================================================
@@ -186,18 +184,10 @@ Summary of ide driver parameters for ker

"hdx=" is recognized for all "x" from "a" to "u", such as "hdc".

- "hdx=noprobe" : drive may be present, but do not probe for it
-
- "hdx=none" : drive is NOT present, ignore cmos and do not probe
-
- "hdx=nowerr" : ignore the WRERR_STAT bit on this drive
-
"hdx=cdrom" : drive is present, and is a cdrom drive

"hdx=cyl,head,sect" : disk drive is present, with specified geometry

- "hdx=nodma" : disallow DMA
-
"ide=doubler" : probe/support IDE doublers on Amiga

There may be more options than shown -- use the source, Luke!
@@ -230,6 +220,16 @@ a case please report it as a bug instead
* "ignore_cable=[interface_number]" module parameter (for ide_core module)
if IDE is compiled as module

+Other kernel parameters for ide_core are:
+
+* "nodma=[interface_number.device_number]" to disallow DMA for a device
+
+* "noflush=[interface_number.device_number]" to disable flush requests
+
+* "noprobe=[interface_number.device_number]" to skip probing
+
+* "nowerr=[interface_number.device_number]" to ignore the WRERR_STAT bit
+
================================================================================

Some Terminology
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -866,10 +866,10 @@ static int __init ide_setup(char *s)
case -1: /* "none" */
case -2: /* "noprobe" */
drive->noprobe = 1;
- goto done;
+ goto obsolete_option;
case -3: /* "nowerr" */
drive->bad_wstat = BAD_R_STAT;
- goto done;
+ goto obsolete_option;
case -4: /* "cdrom" */
drive->present = 1;
drive->media = ide_cdrom;
@@ -878,10 +878,10 @@ static int __init ide_setup(char *s)
goto done;
case -5: /* nodma */
drive->nodma = 1;
- goto done;
+ goto obsolete_option;
case -11: /* noflush */
drive->noflush = 1;
- goto done;
+ goto obsolete_option;
case -12: /* "remap" */
drive->remap_0_to_1 = 1;
goto obsolete_option;
@@ -1061,6 +1061,72 @@ EXPORT_SYMBOL_GPL(ide_pci_clk);
module_param_named(pci_clock, ide_pci_clk, int, 0);
MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)");

+static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
+{
+ int a, b, i, j = 1;
+ unsigned int *dev_param_mask = (unsigned int *)kp->arg;
+
+ if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 &&
+ sscanf(s, "%d.%d", &a, &b) != 2)
+ return -EINVAL;
+
+ i = a * MAX_DRIVES + b;
+
+ if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1)
+ return -EINVAL;
+
+ if (j)
+ *dev_param_mask |= (1 << i);
+ else
+ *dev_param_mask &= (1 << i);
+
+ return 0;
+}
+
+static unsigned int ide_nodma;
+
+module_param_call(nodma, ide_set_dev_param_mask, NULL, &ide_nodma, 0);
+MODULE_PARM_DESC(nodma, "disallow DMA for a device");
+
+static unsigned int ide_noflush;
+
+module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0);
+MODULE_PARM_DESC(noflush, "disable flush requests for a device");
+
+static unsigned int ide_noprobe;
+
+module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0);
+MODULE_PARM_DESC(noprobe, "skip probing for a device");
+
+static unsigned int ide_nowerr;
+
+module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0);
+MODULE_PARM_DESC(nowerr, "ignore the WRERR_STAT bit for a device");
+
+static void ide_dev_apply_params(ide_drive_t *drive)
+{
+ int i = drive->hwif->index * MAX_DRIVES + drive->select.b.unit;
+
+ if (ide_nodma & (1 << i)) {
+ printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name);
+ drive->nodma = 1;
+ }
+ if (ide_noflush & (1 << i)) {
+ printk(KERN_INFO "ide: disabling flush requests for %s\n",
+ drive->name);
+ drive->noflush = 1;
+ }
+ if (ide_noprobe & (1 << i)) {
+ printk(KERN_INFO "ide: skipping probe for %s\n", drive->name);
+ drive->noprobe = 1;
+ }
+ if (ide_nowerr & (1 << i)) {
+ printk(KERN_INFO "ide: ignoring the WRERR_STAT bit for %s\n",
+ drive->name);
+ drive->bad_wstat = BAD_R_STAT;
+ }
+}
+
static unsigned int ide_ignore_cable;

static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
@@ -1086,11 +1152,16 @@ MODULE_PARM_DESC(ignore_cable, "ignore c

void ide_port_apply_params(ide_hwif_t *hwif)
{
+ int i;
+
if (ide_ignore_cable & (1 << hwif->index)) {
printk(KERN_INFO "ide: ignoring cable detection for %s\n",
hwif->name);
hwif->cbl = ATA_CBL_PATA40_SHORT;
}
+
+ for (i = 0; i < MAX_DRIVES; i++)
+ ide_dev_apply_params(&hwif->drives[i]);
}

/*

Subject: [PATCH 6/8] ide: add "cdrom=" and "chs=" parameters

* Add "cdrom=" and "chs=" parameters.

* Obsolete "hdx=cdrom" and "hdx=cyls,heads,sects" kernel parameters.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
Documentation/ide/ide.txt | 31 +++++++++-----------
drivers/ide/ide.c | 71 ++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 80 insertions(+), 22 deletions(-)

Index: b/Documentation/ide/ide.txt
===================================================================
--- a/Documentation/ide/ide.txt
+++ b/Documentation/ide/ide.txt
@@ -82,17 +82,16 @@ Drives are normally found by auto-probin
For really weird situations, the apparent (fdisk) geometry can also be specified
on the kernel "command line" using LILO. The format of such lines is:

- hdx=cyls,heads,sects
-or hdx=cdrom
+ ide_core.chs=[interface_number.device_number]:cyls,heads,sects
+or ide_core.cdrom=[interface_number.device_number]

-where hdx can be any of hda through hdh, Three values are required
-(cyls,heads,sects). For example:
+For example:

- hdc=1050,32,64 hdd=cdrom
+ ide_core.chs=1.0:1050,32,64 ide_core.cdrom=1.1

-either {hda,hdb} or {hdc,hdd}. The results of successful auto-probing may
-override the physical geometry/irq specified, though the "original" geometry
-may be retained as the "logical" geometry for partitioning purposes (fdisk).
+The results of successful auto-probing may override the physical geometry/irq
+specified, though the "original" geometry may be retained as the "logical"
+geometry for partitioning purposes (fdisk).

If the auto-probing during boot time confuses a drive (ie. the drive works
with hd.c but not with ide.c), then an command line option may be specified
@@ -101,7 +100,7 @@ probe/identification sequence. For exam

ide_core.noprobe=0.1
or
- hdc=768,16,32
+ ide_core.chs=1.0:768,16,32
ide_core.noprobe=1.0

Note that when only one IDE device is attached to an interface, it should be
@@ -118,9 +117,9 @@ If for some reason your cdrom drive is *
the probe to look harder by supplying a kernel command line parameter
via LILO, such as:

- hdc=cdrom /* hdc = "master" on second interface */
+ ide_core.cdrom=1.0 /* "master" on second interface (hdc) */
or
- hdd=cdrom /* hdd = "slave" on second interface */
+ ide_core.cdrom=1.1 /* "slave" on second interface (hdd) */

For example, a GW2000 system might have a hard drive on the primary
interface (/dev/hda) and an IDE cdrom drive on the secondary interface
@@ -182,12 +181,6 @@ driver using the "options=" keyword to i
Summary of ide driver parameters for kernel command line
--------------------------------------------------------

- "hdx=" is recognized for all "x" from "a" to "u", such as "hdc".
-
- "hdx=cdrom" : drive is present, and is a cdrom drive
-
- "hdx=cyl,head,sect" : disk drive is present, with specified geometry
-
"ide=doubler" : probe/support IDE doublers on Amiga

There may be more options than shown -- use the source, Luke!
@@ -230,6 +223,10 @@ Other kernel parameters for ide_core are

* "nowerr=[interface_number.device_number]" to ignore the WRERR_STAT bit

+* "cdrom=[interface_number.device_number]" to force device as a CD-ROM
+
+* "chs=[interface_number.device_number]" to force device as a disk (using CHS)
+
================================================================================

Some Terminology
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -875,7 +875,7 @@ static int __init ide_setup(char *s)
drive->media = ide_cdrom;
/* an ATAPI device ignores DRDY */
drive->ready_stat = 0;
- goto done;
+ goto obsolete_option;
case -5: /* nodma */
drive->nodma = 1;
goto obsolete_option;
@@ -899,7 +899,7 @@ static int __init ide_setup(char *s)
drive->sect = drive->bios_sect = vals[2];
drive->present = 1;
drive->forced_geom = 1;
- goto done;
+ goto obsolete_option;
default:
goto bad_option;
}
@@ -911,9 +911,6 @@ bad_option:
obsolete_option:
printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n");
return 1;
-done:
- printk("\n");
- return 1;
}

EXPORT_SYMBOL(ide_lock);
@@ -1103,6 +1100,51 @@ static unsigned int ide_nowerr;
module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0);
MODULE_PARM_DESC(nowerr, "ignore the WRERR_STAT bit for a device");

+static unsigned int ide_cdroms;
+
+module_param_call(cdrom, ide_set_dev_param_mask, NULL, &ide_cdroms, 0);
+MODULE_PARM_DESC(cdrom, "force device as a CD-ROM");
+
+struct chs_geom {
+ unsigned int cyl;
+ u8 head;
+ u8 sect;
+};
+
+static unsigned int ide_disks;
+static struct chs_geom ide_disks_chs[MAX_HWIFS * MAX_DRIVES];
+
+static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
+{
+ int a, b, c = 0, h = 0, s = 0, i, j = 1;
+
+ if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 &&
+ sscanf(str, "%d.%d:%d", &a, &b, &j) != 3)
+ return -EINVAL;
+
+ i = a * MAX_DRIVES + b;
+
+ if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1)
+ return -EINVAL;
+
+ if (c > INT_MAX || h > 255 || s > 255)
+ return -EINVAL;
+
+ if (j)
+ ide_disks |= (1 << i);
+ else
+ ide_disks &= (1 << i);
+
+ ide_disks_chs[i].cyl = c;
+ ide_disks_chs[i].head = h;
+ ide_disks_chs[i].sect = s;
+
+ return 0;
+}
+
+module_param_call(chs, ide_set_disk_chs, NULL, NULL, 0);
+MODULE_PARM_DESC(chs, "force device as a disk (using CHS)");
+
static void ide_dev_apply_params(ide_drive_t *drive)
{
int i = drive->hwif->index * MAX_DRIVES + drive->select.b.unit;
@@ -1125,6 +1167,25 @@ static void ide_dev_apply_params(ide_dri
drive->name);
drive->bad_wstat = BAD_R_STAT;
}
+ if (ide_cdroms & (1 << i)) {
+ printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name);
+ drive->present = 1;
+ drive->media = ide_cdrom;
+ /* an ATAPI device ignores DRDY */
+ drive->ready_stat = 0;
+ }
+ if (ide_disks & (1 << i)) {
+ drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl;
+ drive->head = drive->bios_head = ide_disks_chs[i].head;
+ drive->sect = drive->bios_sect = ide_disks_chs[i].sect;
+ drive->forced_geom = 1;
+ printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n",
+ drive->name,
+ drive->cyl, drive->head, drive->sect);
+ drive->present = 1;
+ drive->media = ide_disk;
+ drive->ready_stat = READY_STAT;
+ }
}

static unsigned int ide_ignore_cable;

Subject: [PATCH 7/8] ide: remove obsoleted "hdx=" kernel parameters

* Remove obsoleted "hdx=" kernel parameters.

* Remove no longer used stridx() and match_parm().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
Documentation/kernel-parameters.txt | 3
drivers/ide/ide.c | 139 ------------------------------------
2 files changed, 1 insertion(+), 141 deletions(-)

Index: b/Documentation/kernel-parameters.txt
===================================================================
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -708,9 +708,6 @@ and is between 256 and 4096 characters.
hd= [EIDE] (E)IDE hard drive subsystem geometry
Format: <cyl>,<head>,<sect>

- hd?= [HW] (E)IDE subsystem
- hd?lun= See Documentation/ide/ide.txt.
-
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
size of <nn>. This works even on boxes that have no
highmem otherwise. This also works to reduce highmem
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -725,89 +725,13 @@ set_val:
EXPORT_SYMBOL(generic_ide_ioctl);

/*
- * stridx() returns the offset of c within s,
- * or -1 if c is '\0' or not found within s.
- */
-static int __init stridx (const char *s, char c)
-{
- char *i = strchr(s, c);
- return (i && c) ? i - s : -1;
-}
-
-/*
- * match_parm() does parsing for ide_setup():
- *
- * 1. the first char of s must be '='.
- * 2. if the remainder matches one of the supplied keywords,
- * the index (1 based) of the keyword is negated and returned.
- * 3. if the remainder is a series of no more than max_vals numbers
- * separated by commas, the numbers are saved in vals[] and a
- * count of how many were saved is returned. Base10 is assumed,
- * and base16 is allowed when prefixed with "0x".
- * 4. otherwise, zero is returned.
- */
-static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals)
-{
- static const char *decimal = "0123456789";
- static const char *hex = "0123456789abcdef";
- int i, n;
-
- if (*s++ == '=') {
- /*
- * Try matching against the supplied keywords,
- * and return -(index+1) if we match one
- */
- if (keywords != NULL) {
- for (i = 0; *keywords != NULL; ++i) {
- if (!strcmp(s, *keywords++))
- return -(i+1);
- }
- }
- /*
- * Look for a series of no more than "max_vals"
- * numeric values separated by commas, in base10,
- * or base16 when prefixed with "0x".
- * Return a count of how many were found.
- */
- for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
- vals[n] = i;
- while ((i = stridx(decimal, *++s)) >= 0)
- vals[n] = (vals[n] * 10) + i;
- if (*s == 'x' && !vals[n]) {
- while ((i = stridx(hex, *++s)) >= 0)
- vals[n] = (vals[n] * 0x10) + i;
- }
- if (++n == max_vals)
- break;
- if (*s == ',' || *s == ';')
- ++s;
- }
- if (!*s)
- return n;
- }
- return 0; /* zero = nothing matched */
-}
-
-/*
* ide_setup() gets called VERY EARLY during initialization,
- * to handle kernel "command line" strings beginning with "hdx=" or "ide".
+ * to handle kernel "command line" strings beginning with "ide".
*
* Remember to update Documentation/ide/ide.txt if you change something here.
*/
static int __init ide_setup(char *s)
{
- ide_hwif_t *hwif;
- ide_drive_t *drive;
- unsigned int hw, unit;
- int vals[3];
- const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
-
- if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */
- return 0; /* driver and not us */
-
- if (strncmp(s, "ide", 3) && strncmp(s, "hd", 2))
- return 0;
-
printk(KERN_INFO "ide_setup: %s", s);
init_ide_data ();

@@ -845,67 +769,6 @@ static int __init ide_setup(char *s)
}
#endif /* CONFIG_BLK_DEV_IDEACPI */

- /*
- * Look for drive options: "hdx="
- */
- if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
- const char *hd_words[] = {
- "none", "noprobe", "nowerr", "cdrom", "nodma",
- "-6", "-7", "-8", "-9", "-10",
- "noflush", "remap", "remap63", "scsi", NULL };
- unit = s[2] - 'a';
- hw = unit / MAX_DRIVES;
- unit = unit % MAX_DRIVES;
- hwif = &ide_hwifs[hw];
- drive = &hwif->drives[unit];
- if (strncmp(s + 4, "ide-", 4) == 0) {
- strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req));
- goto obsolete_option;
- }
- switch (match_parm(&s[3], hd_words, vals, 3)) {
- case -1: /* "none" */
- case -2: /* "noprobe" */
- drive->noprobe = 1;
- goto obsolete_option;
- case -3: /* "nowerr" */
- drive->bad_wstat = BAD_R_STAT;
- goto obsolete_option;
- case -4: /* "cdrom" */
- drive->present = 1;
- drive->media = ide_cdrom;
- /* an ATAPI device ignores DRDY */
- drive->ready_stat = 0;
- goto obsolete_option;
- case -5: /* nodma */
- drive->nodma = 1;
- goto obsolete_option;
- case -11: /* noflush */
- drive->noflush = 1;
- goto obsolete_option;
- case -12: /* "remap" */
- drive->remap_0_to_1 = 1;
- goto obsolete_option;
- case -13: /* "remap63" */
- drive->sect0 = 63;
- goto obsolete_option;
- case -14: /* "scsi" */
- drive->scsi = 1;
- goto obsolete_option;
- case 3: /* cyl,head,sect */
- drive->media = ide_disk;
- drive->ready_stat = READY_STAT;
- drive->cyl = drive->bios_cyl = vals[0];
- drive->head = drive->bios_head = vals[1];
- drive->sect = drive->bios_sect = vals[2];
- drive->present = 1;
- drive->forced_geom = 1;
- goto obsolete_option;
- default:
- goto bad_option;
- }
- }
-
-bad_option:
printk(" -- BAD OPTION\n");
return 1;
obsolete_option:

Subject: [PATCH 8/8] ide: cleanup init_ide_data()

* Remove no longer need init_ide_data() call from ide_setup().

* Cleanup init_ide_data().

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide.c | 24 ------------------------
1 file changed, 24 deletions(-)

Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -157,32 +157,9 @@ static void ide_port_init_devices_data(i
}
}

-/*
- * init_ide_data() sets reasonable default values into all fields
- * of all instances of the hwifs and drives, but only on the first call.
- * Subsequent calls have no effect (they don't wipe out anything).
- *
- * This routine is normally called at driver initialization time,
- * but may also be called MUCH earlier during kernel "command-line"
- * parameter processing. As such, we cannot depend on any other parts
- * of the kernel (such as memory allocation) to be functioning yet.
- *
- * This is too bad, as otherwise we could dynamically allocate the
- * ide_drive_t structs as needed, rather than always consuming memory
- * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
- *
- * FIXME: We should stuff the setup data into __init and copy the
- * relevant hwifs/allocate them properly during boot.
- */
-#define MAGIC_COOKIE 0x12345678
static void __init init_ide_data (void)
{
unsigned int index;
- static unsigned long magic_cookie = MAGIC_COOKIE;
-
- if (magic_cookie != MAGIC_COOKIE)
- return; /* already initialized */
- magic_cookie = 0;

/* Initialise all interface structures */
for (index = 0; index < MAX_HWIFS; ++index) {
@@ -733,7 +710,6 @@ EXPORT_SYMBOL(generic_ide_ioctl);
static int __init ide_setup(char *s)
{
printk(KERN_INFO "ide_setup: %s", s);
- init_ide_data ();

#ifdef CONFIG_BLK_DEV_IDEDOUBLER
if (!strcmp(s, "ide=doubler")) {

2008-03-24 02:27:43

by Bodo Eggert

[permalink] [raw]
Subject: Re: [PATCH 1/8] ide: always auto-tune PIO in legacy VLB host drivers

Bartlomiej Zolnierkiewicz <[email protected]> wrote:

|Subject: [PATCH 1/8] ide: always auto-tune PIO in legacy VLB host drivers

AFAIR this isn't safe for bus speeds above 33 MHz, is it?

Subject: Re: [PATCH 1/8] ide: always auto-tune PIO in legacy VLB host drivers

On Monday 24 March 2008, Bodo Eggert wrote:
> Bartlomiej Zolnierkiewicz <[email protected]> wrote:
>
> |Subject: [PATCH 1/8] ide: always auto-tune PIO in legacy VLB host drivers
>
> AFAIR this isn't safe for bus speeds above 33 MHz, is it?

It should be safe as VLB host drivers assume that bus speed is 50 MHz
(so the longest timings are used) if bus speed is not given by user
(using "idebus=" or "ide_core.vlb_clock=")?

Thanks,
Bart

2008-03-25 16:48:08

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 3/8] ide: remove IDE_HFLAG_NO_AUTOTUNE host flag

Bartlomiej Zolnierkiewicz wrote:

> * Don't set IDE_HFLAG_NO_AUTOTUNE host flag in sgiioc4 and icside
> host drivers - there is no need for it as they don't implement
> ->set_pio_mode method.

> * Remove no longer needed IDE_HFLAG_NO_AUTOTUNE host flag.

> There should be no functional changes caused by this patch.

> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei