2005-02-02 02:41:08

by Tejun Heo

[permalink] [raw]
Subject: [PATCH 2.6.11-rc2 0/29] ide: driver updates

Hello, B. Zolnierkiewicz.

These patches are various fixes/improvements to the ide driver. They
are against the 2.6 bk tree as of today (20050202).

01_ide_remove_adma100.patch

Removes drivers/ide/pci/adma100.[hc]. The driver isn't
compilable (missing functions) and no Kconfig actually enables
CONFIG_BLK_DEV_ADMA100.

02_ide_cleanup_it8172.patch

In drivers/ide/pci/it8172.h, it8172_ratefilter() and
init_setup_it8172() are declared and the latter is referenced
in it8172_chipsets. Both functions are not defined or used
anywhere. This patch removes the prototypes and reference.
it8172 should be compilable now.

03_ide_cleanup_opti621.patch

In drivers/ide/pci/opti612.[hc], init_setup_opt621() is
declared, defined and referenced but never actullay used.
Thie patch removes the function.

04_ide_cleanup_piix.patch

In drivers/ide/pci/piix.[hc], init_setup_piix() is defined and
used but only one init_setup function is defined and no
demultiplexing is done using init_setup callback. As other
drivers call ide_setup_pci_device() directly in such cases,
this patch removes init_setup_piix() and makes piix_init_one()
call ide_setup_pci_device() directly.

05_ide_merge_pci_driver_hc.patch

Merges drivers/ide/pci/*.h files into their corresponding *.c
files. Rationales are
1. There's no reason to separate pci drivers into header and
body. No header file is shared and they're simple enough.
2. struct pde_pci_device_t *_chipsets[] are _defined_ in the
header files. That isn't the custom and there's no good
reason to do differently in these drivers.
3. Tracking changelogs shows that the bugs fixed by 00 and 01
are introduced during mass-updating ide pci drivers by
forgetting to update *.h files.

06_ide_start_request_IDE_CONTROL_REG.patch

Replaced HWIF(drive)->io_ports[IDE_CONTROL_OFFSET] with
equivalent IDE_CONTROL_REG in ide-io.c.

07_ide_reg_valid_t_endian_fix.patch

ide_reg_valid_t contains bitfield flags but doesn't reverse
bit orders using __*_ENDIAN_BITFIELD macros. And constants
for ide_reg_valid_t, IDE_{TASKFILE|HOB}_STD_{IN|OUT}_FLAGS,
are defined as byte values which are correct only on
little-endian machines. This patch defines reversed constants
and .h byte union structure to make things correct on big
endian machines. The only code which uses above macros is in
flagged_taskfile() and the code is currently unused, so this
patch doesn't change any behavior. (The code will get used in
later patches.)

08_ide_do_identify_model_string_termination.patch

Terminates id->model string before invoking strstr() in
do_identify().

09_ide_do_rw_disk_lba48_dma_check_fix.patch

In __ide_do_rw_disk(), the shifted block, instead of the
original rq->sector, should be used when checking range for
lba48 dma.

10_ide_do_rw_disk_pre_task_out_intr_return_fix.patch

In __ide_do_rw_disk(), ide_started used to be returned blindly
after issusing PIO write. This can cause hang if
pre_task_out_intr() returns ide_stopped due to failed
ide_wait_stat() test. Fixed to pass the return value of
pre_task_out_intr().

11_ide_drive_sleeping_fix.patch

ide_drive_t.sleeping field added. 0 in sleep field used to
indicate inactive sleeping but because 0 is a valid jiffy
value, though slim, there's a chance that something can go
weird. And while at it, explicit jiffy comparisons are
converted to use time_{after|before} macros.

12_ide_hwgroup_t_polling.patch

ide_hwgroup_t.polling field added. 0 in poll_timeout field
used to indicate inactive polling but because 0 is a valid
jiffy value, though slim, there's a chance that something
weird can happen.

13_ide_tape_time_after.patch

Explicit jiffy comparision converted to time_after() macro.

14_ide_error_remove_NULL_test.patch

In ide_error(), drive cannot be NULL. ide_dump_status() can't
handle NULL drive.

15_ide_flagged_taskfile_data_byte_order_fix.patch

In flagged_taskfile(), when writing data register,
taskfile->data goes to the lower byte and hobfile->data goes
to the upper byte on little endian machines and the opposite
happens on big endian machines. This patch make
taskfile->data always go to the lower byte regardless of
endianess.

16_ide_flagged_taskfile_select_dev_bit_masking.patch

In flagged_taskfile(), make off DEV bit before OR'ing it with
drive->select.all when writing to IDE_SELECT_REG.

17_ide_flagged_taskfile_select_check.patch

In flagged_taskfile(), tf_out_flags.b.select should be checked
before using bits inside taskfile->device_head. When user
haven't specified the select register, the default
drive->select.all value should be used.

18_ide_comment_fixes.patch

Comment fixes.

19_ide_diag_taskfile_use_init_drive_cmd.patch

In ide_diag_taskfile(), when initializing taskfile rq,
ref_count wasn't initialized properly. Modified to use
ide_init_drive_cmd(). This doesn't really change any behavior
as the request isn't managed via the block layer.

20_ide_task_end_request_fix.patch

task_end_request() modified and made global. ide_dma_intr()
modified to use task_end_request(). These changes enable
TASKFILE ioctls to get valid register outputs on successful
completion. No in-kernel usage should be affected.

21_ide_do_taskfile.patch

Merged do_rw_taskfile() and flagged_taskfile() into
do_taskfile(). During the merge, the following changes took
place.
1. flagged taskfile now honors HOB feature register.
(do_rw_taskfile() did write to HOB feature.)
2. No do_rw_taskfile() HIHI check on select register. Except
for the DEV bit, all bits are honored.
3. Uses taskfile->data_phase to determine if dma trasfer is
requested. (do_rw_taskfile() directly switched on
taskfile->command for all dma commands)

22_ide_taskfile_flush.patch

All REQ_DRIVE_TASK users except ide_task_ioctl() converted
to use REQ_DRIVE_TASKFILE.
1. idedisk_issue_flush() converted to use REQ_DRIVE_TASKFILE.
This and the changes in ide_get_error_location() remove a
possible race condition between ide_get_error_location()
and other requests.
2. ide_queue_flush_cmd() converted to use REQ_DRIVE_TASKFILE.

23_ide_taskfile_task_ioctl.patch

ide_task_ioctl() modified to map to ide_taskfile_ioctl().
This is the last user of REQ_DRIVE_TASK.

24_ide_remove_task.patch

Unused REQ_DRIVE_TASK handling removed.

25_ide_taskfile_cmd.patch

All in-kernel REQ_DRIVE_CMD users except for ide_cmd_ioctl()
converted to use REQ_DRIVE_TASKFILE.

26_ide_taskfile_cmd_ioctl.patch

ide_cmd_ioctl() converted to use ide_taskfile_ioctl(). This
is the last user of REQ_DRIVE_CMD.

27_ide_remove_cmd.patch

Removed unused REQ_DRIVE_CMD handling.

28_ide_taskfile_init_drive_cmd.patch

ide_init_drive_cmd() now initializes rq->flags to
REQ_DRIVE_TASKFILE.

29_ide_explicit_TASKFILE_NO_DATA.patch

Make data_phase explicit in NO_DATA cases.

Thanks.

--
tejun


2005-02-02 02:44:11

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 01/29] ide: remove adma100

> 01_ide_remove_adma100.patch
>
> Removes drivers/ide/pci/adma100.[hc]. The driver isn't
> compilable (missing functions) and no Kconfig actually enables
> CONFIG_BLK_DEV_ADMA100.


Signed-off-by: Tejun Heo <[email protected]>

Index: linux-ide-export/drivers/ide/pci/Makefile
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/Makefile 2005-02-02 10:27:16.466108583 +0900
+++ linux-ide-export/drivers/ide/pci/Makefile 2005-02-02 10:28:01.257841491 +0900
@@ -1,5 +1,4 @@

-obj-$(CONFIG_BLK_DEV_ADMA100) += adma100.o
obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o
obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o
obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o
Index: linux-ide-export/drivers/ide/pci/adma100.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/adma100.c 2005-02-02 10:27:16.466108583 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
-/*
- * linux/drivers/ide/pci/adma100.c -- basic support for Pacific Digital ADMA-100 boards
- *
- * Created 09 Apr 2002 by Mark Lord
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/mm.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-
-void __init ide_init_adma100 (ide_hwif_t *hwif)
-{
- unsigned long phy_admctl = pci_resource_start(hwif->pci_dev, 4) + 0x80 + (hwif->channel * 0x20);
- void *v_admctl;
-
- hwif->autodma = 0; // not compatible with normal IDE DMA transfers
- hwif->dma_base = 0; // disable DMA completely
- hwif->io_ports[IDE_CONTROL_OFFSET] += 4; // chip needs offset of 6 instead of 2
- v_admctl = ioremap_nocache(phy_admctl, 1024); // map config regs, so we can turn on drive IRQs
- *((unsigned short *)v_admctl) &= 3; // enable aIEN; preserve PIO mode
- iounmap(v_admctl); // all done; unmap config regs
-}
Index: linux-ide-export/drivers/ide/pci/adma100.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/adma100.h 2005-02-02 10:27:16.466108583 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-#ifndef ADMA_100_H
-#define ADMA_100_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-extern void init_setup_pdcadma(struct pci_dev *, ide_pci_device_t *);
-extern unsigned int init_chipset_pdcadma(struct pci_dev *, const char *);
-extern void init_hwif_pdcadma(ide_hwif_t *);
-extern void init_dma_pdcadma(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t pdcadma_chipsets[] __devinitdata = {
- {
- .vendor = PCI_VENDOR_ID_PDC,
- .device = PCI_DEVICE_ID_PDC_1841,
- .name = "ADMA100",
- .init_setup = init_setup_pdcadma,
- .init_chipset = init_chipset_pdcadma,
- .init_hwif = init_hwif_pdcadma,
- .init_dma = init_dma_pdcadma,
- .channels = 2,
- .autodma = NODMA,
- .bootable = OFF_BOARD,
- }
-}
-
-#endif /* ADMA_100_H */

2005-02-02 02:45:11

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 02/29] ide: cleanup it8172

> 02_ide_cleanup_it8172.patch
>
> In drivers/ide/pci/it8172.h, it8172_ratefilter() and
> init_setup_it8172() are declared and the latter is referenced
> in it8172_chipsets. Both functions are not defined or used
> anywhere. This patch removes the prototypes and reference.
> it8172 should be compilable now.


Signed-off-by: Tejun Heo <[email protected]>

Index: linux-ide-export/drivers/ide/pci/it8172.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/it8172.h 2005-02-02 10:27:16.392120586 +0900
+++ linux-ide-export/drivers/ide/pci/it8172.h 2005-02-02 10:28:01.638779685 +0900
@@ -6,7 +6,6 @@
#include <linux/ide.h>

static u8 it8172_ratemask(ide_drive_t *drive);
-static u8 it8172_ratefilter(ide_drive_t *drive, u8 speed);
static void it8172_tune_drive(ide_drive_t *drive, u8 pio);
static u8 it8172_dma_2_pio(u8 xfer_rate);
static int it8172_tune_chipset(ide_drive_t *drive, u8 xferspeed);
@@ -14,14 +13,12 @@ static int it8172_tune_chipset(ide_drive
static int it8172_config_chipset_for_dma(ide_drive_t *drive);
#endif

-static void init_setup_it8172(struct pci_dev *, ide_pci_device_t *);
static unsigned int init_chipset_it8172(struct pci_dev *, const char *);
static void init_hwif_it8172(ide_hwif_t *);

static ide_pci_device_t it8172_chipsets[] __devinitdata = {
{ /* 0 */
.name = "IT8172G",
- .init_setup = init_setup_it8172,
.init_chipset = init_chipset_it8172,
.init_hwif = init_hwif_it8172,
.channels = 2,

2005-02-02 02:46:30

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 03/29] ide: cleanup opti621

> 03_ide_cleanup_opti621.patch
>
> In drivers/ide/pci/opti612.[hc], init_setup_opt621() is
> declared, defined and referenced but never actullay used.
> Thie patch removes the function.


Signed-off-by: Tejun Heo <[email protected]>

Index: linux-ide-export/drivers/ide/pci/opti621.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/opti621.c 2005-02-02 10:27:16.326131292 +0900
+++ linux-ide-export/drivers/ide/pci/opti621.c 2005-02-02 10:28:01.947729558 +0900
@@ -348,11 +348,6 @@ static void __init init_hwif_opti621 (id
hwif->drives[1].autodma = hwif->autodma;
}

-static int __init init_setup_opti621 (struct pci_dev *dev, ide_pci_device_t *d)
-{
- return ide_setup_pci_device(dev, d);
-}
-
static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]);
Index: linux-ide-export/drivers/ide/pci/opti621.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/opti621.h 2005-02-02 10:27:16.327131130 +0900
+++ linux-ide-export/drivers/ide/pci/opti621.h 2005-02-02 10:28:01.948729395 +0900
@@ -5,13 +5,11 @@
#include <linux/pci.h>
#include <linux/ide.h>

-static int init_setup_opti621(struct pci_dev *, ide_pci_device_t *);
static void init_hwif_opti621(ide_hwif_t *);

static ide_pci_device_t opti621_chipsets[] __devinitdata = {
{ /* 0 */
.name = "OPTI621",
- .init_setup = init_setup_opti621,
.init_hwif = init_hwif_opti621,
.channels = 2,
.autodma = AUTODMA,
@@ -19,7 +17,6 @@ static ide_pci_device_t opti621_chipsets
.bootable = ON_BOARD,
},{ /* 1 */
.name = "OPTI621X",
- .init_setup = init_setup_opti621,
.init_hwif = init_hwif_opti621,
.channels = 2,
.autodma = AUTODMA,

2005-02-02 02:48:39

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 04/29] ide: cleanup piix

> 04_ide_cleanup_piix.patch
>
> In drivers/ide/pci/piix.[hc], init_setup_piix() is defined and
> used but only one init_setup function is defined and no
> demultiplexing is done using init_setup callback. As other
> drivers call ide_setup_pci_device() directly in such cases,
> this patch removes init_setup_piix() and makes piix_init_one()
> call ide_setup_pci_device() directly.


Signed-off-by: Tejun Heo <[email protected]>

Index: linux-ide-export/drivers/ide/pci/piix.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/piix.c 2005-02-02 10:27:16.255142809 +0900
+++ linux-ide-export/drivers/ide/pci/piix.c 2005-02-02 10:28:02.317669535 +0900
@@ -531,20 +531,6 @@ static void __devinit init_hwif_piix(ide
}

/**
- * init_setup_piix - callback for IDE initialize
- * @dev: PIIX PCI device
- * @d: IDE pci info
- *
- * Enable the xp fixup for the PIIX controller and then perform
- * a standard ide PCI setup
- */
-
-static int __devinit init_setup_piix(struct pci_dev *dev, ide_pci_device_t *d)
-{
- return ide_setup_pci_device(dev, d);
-}
-
-/**
* piix_init_one - called when a PIIX is found
* @dev: the piix device
* @id: the matching pci id
@@ -557,7 +543,7 @@ static int __devinit piix_init_one(struc
{
ide_pci_device_t *d = &piix_pci_info[id->driver_data];

- return d->init_setup(dev, d);
+ return ide_setup_pci_device(dev, d);
}

/**
Index: linux-ide-export/drivers/ide/pci/piix.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/piix.h 2005-02-02 10:27:16.255142809 +0900
+++ linux-ide-export/drivers/ide/pci/piix.h 2005-02-02 10:28:02.317669535 +0900
@@ -5,14 +5,12 @@
#include <linux/pci.h>
#include <linux/ide.h>

-static int init_setup_piix(struct pci_dev *, ide_pci_device_t *);
static unsigned int __devinit init_chipset_piix(struct pci_dev *, const char *);
static void init_hwif_piix(ide_hwif_t *);

#define DECLARE_PIIX_DEV(name_str) \
{ \
.name = name_str, \
- .init_setup = init_setup_piix, \
.init_chipset = init_chipset_piix, \
.init_hwif = init_hwif_piix, \
.channels = 2, \
@@ -32,7 +30,6 @@ static ide_pci_device_t piix_pci_info[]

{ /* 2 */
.name = "MPIIX",
- .init_setup = init_setup_piix,
.init_hwif = init_hwif_piix,
.channels = 2,
.autodma = NODMA,

2005-02-02 02:50:48

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 06/29] ide: IDE_CONTROL_REG cleanup

> 06_ide_start_request_IDE_CONTROL_REG.patch
>
> Replaced HWIF(drive)->io_ports[IDE_CONTROL_OFFSET] with
> equivalent IDE_CONTROL_REG in ide-io.c.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:27:15.996184821 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:03.340503581 +0900
@@ -884,7 +884,7 @@ static ide_startstop_t start_request (id
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
SELECT_DRIVE(drive);
- HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
+ HWIF(drive)->OUTB(8, IDE_CONTROL_REG);
rc = ide_wait_not_busy(HWIF(drive), 10000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);

2005-02-02 03:02:35

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 05/29] ide: merge pci driver .h's into .c's

> 05_ide_merge_pci_driver_hc.patch
>
> Merges drivers/ide/pci/*.h files into their corresponding *.c
> files. Rationales are
> 1. There's no reason to separate pci drivers into header and
> body. No header file is shared and they're simple enough.
> 2. struct pde_pci_device_t *_chipsets[] are _defined_ in the
> header files. That isn't the custom and there's no good
> reason to do differently in these drivers.
> 3. Tracking changelogs shows that the bugs fixed by 00 and 01
> are introduced during mass-updating ide pci drivers by
> forgetting to update *.h files.


Signed-off-by: Tejun Heo <[email protected]>

Index: linux-ide-export/drivers/ide/pci/aec62xx.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/aec62xx.c 2005-02-02 10:27:16.177155461 +0900
+++ linux-ide-export/drivers/ide/pci/aec62xx.c 2005-02-02 10:28:02.661613731 +0900
@@ -16,7 +16,61 @@

#include <asm/io.h>

-#include "aec62xx.h"
+struct chipset_bus_clock_list_entry {
+ byte xfer_speed;
+ byte chipset_settings;
+ byte ultra_settings;
+};
+
+static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
+ { XFER_UDMA_6, 0x31, 0x07 },
+ { XFER_UDMA_5, 0x31, 0x06 },
+ { XFER_UDMA_4, 0x31, 0x05 },
+ { XFER_UDMA_3, 0x31, 0x04 },
+ { XFER_UDMA_2, 0x31, 0x03 },
+ { XFER_UDMA_1, 0x31, 0x02 },
+ { XFER_UDMA_0, 0x31, 0x01 },
+
+ { XFER_MW_DMA_2, 0x31, 0x00 },
+ { XFER_MW_DMA_1, 0x31, 0x00 },
+ { XFER_MW_DMA_0, 0x0a, 0x00 },
+ { XFER_PIO_4, 0x31, 0x00 },
+ { XFER_PIO_3, 0x33, 0x00 },
+ { XFER_PIO_2, 0x08, 0x00 },
+ { XFER_PIO_1, 0x0a, 0x00 },
+ { XFER_PIO_0, 0x00, 0x00 },
+ { 0, 0x00, 0x00 }
+};
+
+static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
+ { XFER_UDMA_6, 0x41, 0x06 },
+ { XFER_UDMA_5, 0x41, 0x05 },
+ { XFER_UDMA_4, 0x41, 0x04 },
+ { XFER_UDMA_3, 0x41, 0x03 },
+ { XFER_UDMA_2, 0x41, 0x02 },
+ { XFER_UDMA_1, 0x41, 0x01 },
+ { XFER_UDMA_0, 0x41, 0x01 },
+
+ { XFER_MW_DMA_2, 0x41, 0x00 },
+ { XFER_MW_DMA_1, 0x42, 0x00 },
+ { XFER_MW_DMA_0, 0x7a, 0x00 },
+ { XFER_PIO_4, 0x41, 0x00 },
+ { XFER_PIO_3, 0x43, 0x00 },
+ { XFER_PIO_2, 0x78, 0x00 },
+ { XFER_PIO_1, 0x7a, 0x00 },
+ { XFER_PIO_0, 0x70, 0x00 },
+ { 0, 0x00, 0x00 }
+};
+
+#ifndef SPLIT_BYTE
+#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
+#endif
+#ifndef MAKE_WORD
+#define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))
+#endif
+
+#define BUSCLOCK(D) \
+ ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))

#if 0
if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
@@ -343,6 +397,58 @@ static int __devinit init_setup_aec6x80(
return ide_setup_pci_device(dev, d);
}

+static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "AEC6210",
+ .init_setup = init_setup_aec62xx,
+ .init_chipset = init_chipset_aec62xx,
+ .init_hwif = init_hwif_aec62xx,
+ .init_dma = init_dma_aec62xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .bootable = OFF_BOARD,
+ },{ /* 1 */
+ .name = "AEC6260",
+ .init_setup = init_setup_aec62xx,
+ .init_chipset = init_chipset_aec62xx,
+ .init_hwif = init_hwif_aec62xx,
+ .init_dma = init_dma_aec62xx,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 2 */
+ .name = "AEC6260R",
+ .init_setup = init_setup_aec62xx,
+ .init_chipset = init_chipset_aec62xx,
+ .init_hwif = init_hwif_aec62xx,
+ .init_dma = init_dma_aec62xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .bootable = NEVER_BOARD,
+ },{ /* 3 */
+ .name = "AEC6X80",
+ .init_setup = init_setup_aec6x80,
+ .init_chipset = init_chipset_aec62xx,
+ .init_hwif = init_hwif_aec62xx,
+ .init_dma = init_dma_aec62xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 4 */
+ .name = "AEC6X80R",
+ .init_setup = init_setup_aec6x80,
+ .init_chipset = init_chipset_aec62xx,
+ .init_hwif = init_hwif_aec62xx,
+ .init_dma = init_dma_aec62xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .bootable = OFF_BOARD,
+ }
+};
+
/**
* aec62xx_init_one - called when a AEC is found
* @dev: the aec62xx device
Index: linux-ide-export/drivers/ide/pci/aec62xx.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/aec62xx.h 2005-02-02 10:27:16.177155461 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,122 +0,0 @@
-#ifndef AEC62XX_H
-#define AEC62XX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-struct chipset_bus_clock_list_entry {
- byte xfer_speed;
- byte chipset_settings;
- byte ultra_settings;
-};
-
-static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
- { XFER_UDMA_6, 0x31, 0x07 },
- { XFER_UDMA_5, 0x31, 0x06 },
- { XFER_UDMA_4, 0x31, 0x05 },
- { XFER_UDMA_3, 0x31, 0x04 },
- { XFER_UDMA_2, 0x31, 0x03 },
- { XFER_UDMA_1, 0x31, 0x02 },
- { XFER_UDMA_0, 0x31, 0x01 },
-
- { XFER_MW_DMA_2, 0x31, 0x00 },
- { XFER_MW_DMA_1, 0x31, 0x00 },
- { XFER_MW_DMA_0, 0x0a, 0x00 },
- { XFER_PIO_4, 0x31, 0x00 },
- { XFER_PIO_3, 0x33, 0x00 },
- { XFER_PIO_2, 0x08, 0x00 },
- { XFER_PIO_1, 0x0a, 0x00 },
- { XFER_PIO_0, 0x00, 0x00 },
- { 0, 0x00, 0x00 }
-};
-
-static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
- { XFER_UDMA_6, 0x41, 0x06 },
- { XFER_UDMA_5, 0x41, 0x05 },
- { XFER_UDMA_4, 0x41, 0x04 },
- { XFER_UDMA_3, 0x41, 0x03 },
- { XFER_UDMA_2, 0x41, 0x02 },
- { XFER_UDMA_1, 0x41, 0x01 },
- { XFER_UDMA_0, 0x41, 0x01 },
-
- { XFER_MW_DMA_2, 0x41, 0x00 },
- { XFER_MW_DMA_1, 0x42, 0x00 },
- { XFER_MW_DMA_0, 0x7a, 0x00 },
- { XFER_PIO_4, 0x41, 0x00 },
- { XFER_PIO_3, 0x43, 0x00 },
- { XFER_PIO_2, 0x78, 0x00 },
- { XFER_PIO_1, 0x7a, 0x00 },
- { XFER_PIO_0, 0x70, 0x00 },
- { 0, 0x00, 0x00 }
-};
-
-#ifndef SPLIT_BYTE
-#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
-#endif
-#ifndef MAKE_WORD
-#define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))
-#endif
-
-#define BUSCLOCK(D) \
- ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
-
-static int init_setup_aec6x80(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_aec62xx(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_aec62xx(struct pci_dev *, const char *);
-static void init_hwif_aec62xx(ide_hwif_t *);
-static void init_dma_aec62xx(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "AEC6210",
- .init_setup = init_setup_aec62xx,
- .init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
- .init_dma = init_dma_aec62xx,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = OFF_BOARD,
- },{ /* 1 */
- .name = "AEC6260",
- .init_setup = init_setup_aec62xx,
- .init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
- .init_dma = init_dma_aec62xx,
- .channels = 2,
- .autodma = NOAUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 2 */
- .name = "AEC6260R",
- .init_setup = init_setup_aec62xx,
- .init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
- .init_dma = init_dma_aec62xx,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = NEVER_BOARD,
- },{ /* 3 */
- .name = "AEC6X80",
- .init_setup = init_setup_aec6x80,
- .init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
- .init_dma = init_dma_aec62xx,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 4 */
- .name = "AEC6X80R",
- .init_setup = init_setup_aec6x80,
- .init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
- .init_dma = init_dma_aec62xx,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = OFF_BOARD,
- }
-};
-
-#endif /* AEC62XX_H */
Index: linux-ide-export/drivers/ide/pci/cmd64x.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/cmd64x.c 2005-02-02 10:27:16.178155299 +0900
+++ linux-ide-export/drivers/ide/pci/cmd64x.c 2005-02-02 10:28:02.663613406 +0900
@@ -25,7 +25,56 @@

#include <asm/io.h>

-#include "cmd64x.h"
+#define DISPLAY_CMD64X_TIMINGS
+
+#define CMD_DEBUG 0
+
+#if CMD_DEBUG
+#define cmdprintk(x...) printk(x)
+#else
+#define cmdprintk(x...)
+#endif
+
+/*
+ * CMD64x specific registers definition.
+ */
+#define CFR 0x50
+#define CFR_INTR_CH0 0x02
+#define CNTRL 0x51
+#define CNTRL_DIS_RA0 0x40
+#define CNTRL_DIS_RA1 0x80
+#define CNTRL_ENA_2ND 0x08
+
+#define CMDTIM 0x52
+#define ARTTIM0 0x53
+#define DRWTIM0 0x54
+#define ARTTIM1 0x55
+#define DRWTIM1 0x56
+#define ARTTIM23 0x57
+#define ARTTIM23_DIS_RA2 0x04
+#define ARTTIM23_DIS_RA3 0x08
+#define ARTTIM23_INTR_CH1 0x10
+#define ARTTIM2 0x57
+#define ARTTIM3 0x57
+#define DRWTIM23 0x58
+#define DRWTIM2 0x58
+#define BRST 0x59
+#define DRWTIM3 0x5b
+
+#define BMIDECR0 0x70
+#define MRDMODE 0x71
+#define MRDMODE_INTR_CH0 0x04
+#define MRDMODE_INTR_CH1 0x08
+#define MRDMODE_BLK_CH0 0x10
+#define MRDMODE_BLK_CH1 0x20
+#define BMIDESR0 0x72
+#define UDIDETCR0 0x73
+#define DTPR0 0x74
+#define BMIDECR1 0x78
+#define BMIDECSR 0x79
+#define BMIDESR1 0x7A
+#define UDIDETCR1 0x7B
+#define DTPR1 0x7C

#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
@@ -707,6 +756,39 @@ static void __devinit init_hwif_cmd64x(i
hwif->drives[1].autodma = hwif->autodma;
}

+static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "CMD643",
+ .init_chipset = init_chipset_cmd64x,
+ .init_hwif = init_hwif_cmd64x,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 1 */
+ .name = "CMD646",
+ .init_chipset = init_chipset_cmd64x,
+ .init_hwif = init_hwif_cmd64x,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}},
+ .bootable = ON_BOARD,
+ },{ /* 2 */
+ .name = "CMD648",
+ .init_chipset = init_chipset_cmd64x,
+ .init_hwif = init_hwif_cmd64x,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{
+ .name = "CMD649",
+ .init_chipset = init_chipset_cmd64x,
+ .init_hwif = init_hwif_cmd64x,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ }
+};
+
static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]);
Index: linux-ide-export/drivers/ide/pci/cmd64x.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/cmd64x.h 2005-02-02 10:27:16.178155299 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,95 +0,0 @@
-#ifndef CMD64X_H
-#define CMD64X_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#define DISPLAY_CMD64X_TIMINGS
-
-#define CMD_DEBUG 0
-
-#if CMD_DEBUG
-#define cmdprintk(x...) printk(x)
-#else
-#define cmdprintk(x...)
-#endif
-
-/*
- * CMD64x specific registers definition.
- */
-#define CFR 0x50
-#define CFR_INTR_CH0 0x02
-#define CNTRL 0x51
-#define CNTRL_DIS_RA0 0x40
-#define CNTRL_DIS_RA1 0x80
-#define CNTRL_ENA_2ND 0x08
-
-#define CMDTIM 0x52
-#define ARTTIM0 0x53
-#define DRWTIM0 0x54
-#define ARTTIM1 0x55
-#define DRWTIM1 0x56
-#define ARTTIM23 0x57
-#define ARTTIM23_DIS_RA2 0x04
-#define ARTTIM23_DIS_RA3 0x08
-#define ARTTIM23_INTR_CH1 0x10
-#define ARTTIM2 0x57
-#define ARTTIM3 0x57
-#define DRWTIM23 0x58
-#define DRWTIM2 0x58
-#define BRST 0x59
-#define DRWTIM3 0x5b
-
-#define BMIDECR0 0x70
-#define MRDMODE 0x71
-#define MRDMODE_INTR_CH0 0x04
-#define MRDMODE_INTR_CH1 0x08
-#define MRDMODE_BLK_CH0 0x10
-#define MRDMODE_BLK_CH1 0x20
-#define BMIDESR0 0x72
-#define UDIDETCR0 0x73
-#define DTPR0 0x74
-#define BMIDECR1 0x78
-#define BMIDECSR 0x79
-#define BMIDESR1 0x7A
-#define UDIDETCR1 0x7B
-#define DTPR1 0x7C
-
-static unsigned int init_chipset_cmd64x(struct pci_dev *, const char *);
-static void init_hwif_cmd64x(ide_hwif_t *);
-
-static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "CMD643",
- .init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 1 */
- .name = "CMD646",
- .init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}},
- .bootable = ON_BOARD,
- },{ /* 2 */
- .name = "CMD648",
- .init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{
- .name = "CMD649",
- .init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- }
-};
-
-#endif /* CMD64X_H */
Index: linux-ide-export/drivers/ide/pci/cy82c693.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/cy82c693.c 2005-02-02 10:27:16.178155299 +0900
+++ linux-ide-export/drivers/ide/pci/cy82c693.c 2005-02-02 10:28:02.664613244 +0900
@@ -54,7 +54,64 @@

#include <asm/io.h>

-#include "cy82c693.h"
+/* the current version */
+#define CY82_VERSION "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs ([email protected])"
+
+/*
+ * The following are used to debug the driver.
+ */
+#define CY82C693_DEBUG_LOGS 0
+#define CY82C693_DEBUG_INFO 0
+
+/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */
+#undef CY82C693_SETDMA_CLOCK
+
+/*
+ * NOTE: the value for busmaster timeout is tricky and I got it by
+ * trial and error! By using a to low value will cause DMA timeouts
+ * and drop IDE performance, and by using a to high value will cause
+ * audio playback to scatter.
+ * If you know a better value or how to calc it, please let me know.
+ */
+
+/* twice the value written in cy82c693ub datasheet */
+#define BUSMASTER_TIMEOUT 0x50
+/*
+ * the value above was tested on my machine and it seems to work okay
+ */
+
+/* here are the offset definitions for the registers */
+#define CY82_IDE_CMDREG 0x04
+#define CY82_IDE_ADDRSETUP 0x48
+#define CY82_IDE_MASTER_IOR 0x4C
+#define CY82_IDE_MASTER_IOW 0x4D
+#define CY82_IDE_SLAVE_IOR 0x4E
+#define CY82_IDE_SLAVE_IOW 0x4F
+#define CY82_IDE_MASTER_8BIT 0x50
+#define CY82_IDE_SLAVE_8BIT 0x51
+
+#define CY82_INDEX_PORT 0x22
+#define CY82_DATA_PORT 0x23
+
+#define CY82_INDEX_CTRLREG1 0x01
+#define CY82_INDEX_CHANNEL0 0x30
+#define CY82_INDEX_CHANNEL1 0x31
+#define CY82_INDEX_TIMEOUT 0x32
+
+/* the max PIO mode - from datasheet */
+#define CY82C693_MAX_PIO 4
+
+/* the min and max PCI bus speed in MHz - from datasheet */
+#define CY82C963_MIN_BUS_SPEED 25
+#define CY82C963_MAX_BUS_SPEED 33
+
+/* the struct for the PIO mode timings */
+typedef struct pio_clocks_s {
+ u8 address_time; /* Address setup (clocks) */
+ u8 time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
+ u8 time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
+ u8 time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
+} pio_clocks_t;

/*
* calc clocks using bus_speed
@@ -422,6 +479,18 @@ void __init init_iops_cy82c693(ide_hwif_
}
}

+static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "CY82C693",
+ .init_chipset = init_chipset_cy82c693,
+ .init_iops = init_iops_cy82c693,
+ .init_hwif = init_hwif_cy82c693,
+ .channels = 1,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ }
+};
+
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
Index: linux-ide-export/drivers/ide/pci/cy82c693.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/cy82c693.h 2005-02-02 10:27:16.178155299 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,83 +0,0 @@
-#ifndef CY82C693_H
-#define CY82C693_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-/* the current version */
-#define CY82_VERSION "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs ([email protected])"
-
-/*
- * The following are used to debug the driver.
- */
-#define CY82C693_DEBUG_LOGS 0
-#define CY82C693_DEBUG_INFO 0
-
-/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */
-#undef CY82C693_SETDMA_CLOCK
-
-/*
- * NOTE: the value for busmaster timeout is tricky and I got it by
- * trial and error! By using a to low value will cause DMA timeouts
- * and drop IDE performance, and by using a to high value will cause
- * audio playback to scatter.
- * If you know a better value or how to calc it, please let me know.
- */
-
-/* twice the value written in cy82c693ub datasheet */
-#define BUSMASTER_TIMEOUT 0x50
-/*
- * the value above was tested on my machine and it seems to work okay
- */
-
-/* here are the offset definitions for the registers */
-#define CY82_IDE_CMDREG 0x04
-#define CY82_IDE_ADDRSETUP 0x48
-#define CY82_IDE_MASTER_IOR 0x4C
-#define CY82_IDE_MASTER_IOW 0x4D
-#define CY82_IDE_SLAVE_IOR 0x4E
-#define CY82_IDE_SLAVE_IOW 0x4F
-#define CY82_IDE_MASTER_8BIT 0x50
-#define CY82_IDE_SLAVE_8BIT 0x51
-
-#define CY82_INDEX_PORT 0x22
-#define CY82_DATA_PORT 0x23
-
-#define CY82_INDEX_CTRLREG1 0x01
-#define CY82_INDEX_CHANNEL0 0x30
-#define CY82_INDEX_CHANNEL1 0x31
-#define CY82_INDEX_TIMEOUT 0x32
-
-/* the max PIO mode - from datasheet */
-#define CY82C693_MAX_PIO 4
-
-/* the min and max PCI bus speed in MHz - from datasheet */
-#define CY82C963_MIN_BUS_SPEED 25
-#define CY82C963_MAX_BUS_SPEED 33
-
-/* the struct for the PIO mode timings */
-typedef struct pio_clocks_s {
- u8 address_time; /* Address setup (clocks) */
- u8 time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
- u8 time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
- u8 time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
-} pio_clocks_t;
-
-static unsigned int init_chipset_cy82c693(struct pci_dev *, const char *);
-static void init_hwif_cy82c693(ide_hwif_t *);
-static void init_iops_cy82c693(ide_hwif_t *);
-
-static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "CY82C693",
- .init_chipset = init_chipset_cy82c693,
- .init_iops = init_iops_cy82c693,
- .init_hwif = init_hwif_cy82c693,
- .channels = 1,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- }
-};
-
-#endif /* CY82C693_H */
Index: linux-ide-export/drivers/ide/pci/generic.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/generic.c 2005-02-02 10:27:16.179155136 +0900
+++ linux-ide-export/drivers/ide/pci/generic.c 2005-02-02 10:28:02.665613082 +0900
@@ -39,8 +39,6 @@

#include <asm/io.h>

-#include "generic.h"
-
static unsigned int __devinit init_chipset_generic (struct pci_dev *dev, const char *name)
{
return 0;
@@ -83,6 +81,115 @@ static void __devinit init_hwif_generic
return 0;
#endif

+static ide_pci_device_t generic_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "NS87410",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
+ .bootable = ON_BOARD,
+ },{ /* 1 */
+ .name = "SAMURAI",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 2 */
+ .name = "HT6565",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 3 */
+ .name = "UM8673F",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NODMA,
+ .bootable = ON_BOARD,
+ },{ /* 4 */
+ .name = "UM8886A",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NODMA,
+ .bootable = ON_BOARD,
+ },{ /* 5 */
+ .name = "UM8886BF",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NODMA,
+ .bootable = ON_BOARD,
+ },{ /* 6 */
+ .name = "HINT_IDE",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 7 */
+ .name = "VIA_IDE",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 8 */
+ .name = "OPTI621V",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 9 */
+ .name = "VIA8237SATA",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 10 */
+ .name = "Piccolo0102",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 11 */
+ .name = "Piccolo0103",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 12 */
+ .name = "Piccolo0105",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = ON_BOARD,
+ }
+};
+
+#if 0
+static ide_pci_device_t unknown_chipset[] __devinitdata = {
+ { /* 0 */
+ .name = "PCI_IDE",
+ .init_chipset = init_chipset_generic,
+ .init_hwif = init_hwif_generic,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ }
+};
+#endif
+
/**
* generic_init_one - called when a PIIX is found
* @dev: the generic device
Index: linux-ide-export/drivers/ide/pci/generic.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/generic.h 2005-02-02 10:27:16.179155136 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,120 +0,0 @@
-#ifndef IDE_GENERIC_H
-#define IDE_GENERIC_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static unsigned int init_chipset_generic(struct pci_dev *, const char *);
-static void init_hwif_generic(ide_hwif_t *);
-
-static ide_pci_device_t generic_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "NS87410",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
- .bootable = ON_BOARD,
- },{ /* 1 */
- .name = "SAMURAI",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 2 */
- .name = "HT6565",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 3 */
- .name = "UM8673F",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NODMA,
- .bootable = ON_BOARD,
- },{ /* 4 */
- .name = "UM8886A",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NODMA,
- .bootable = ON_BOARD,
- },{ /* 5 */
- .name = "UM8886BF",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NODMA,
- .bootable = ON_BOARD,
- },{ /* 6 */
- .name = "HINT_IDE",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 7 */
- .name = "VIA_IDE",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 8 */
- .name = "OPTI621V",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 9 */
- .name = "VIA8237SATA",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 10 */
- .name = "Piccolo0102",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 11 */
- .name = "Piccolo0103",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 12 */
- .name = "Piccolo0105",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- }
-};
-
-#if 0
-static ide_pci_device_t unknown_chipset[] __devinitdata = {
- { /* 0 */
- .name = "PCI_IDE",
- .init_chipset = init_chipset_generic,
- .init_hwif = init_hwif_generic,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- }
-};
-#endif
-
-#endif /* IDE_GENERIC_H */
Index: linux-ide-export/drivers/ide/pci/hpt366.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/hpt366.c 2005-02-02 10:27:16.179155136 +0900
+++ linux-ide-export/drivers/ide/pci/hpt366.c 2005-02-02 10:28:02.667612757 +0900
@@ -70,7 +70,414 @@
#include <asm/io.h>
#include <asm/irq.h>

-#include "hpt366.h"
+/* various tuning parameters */
+#define HPT_RESET_STATE_ENGINE
+#undef HPT_DELAY_INTERRUPT
+#undef HPT_SERIALIZE_IO
+
+static const char *quirk_drives[] = {
+ "QUANTUM FIREBALLlct08 08",
+ "QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP LM20.4",
+ "QUANTUM FIREBALLP LM20.5",
+ NULL
+};
+
+static const char *bad_ata100_5[] = {
+ "IBM-DTLA-307075",
+ "IBM-DTLA-307060",
+ "IBM-DTLA-307045",
+ "IBM-DTLA-307030",
+ "IBM-DTLA-307020",
+ "IBM-DTLA-307015",
+ "IBM-DTLA-305040",
+ "IBM-DTLA-305030",
+ "IBM-DTLA-305020",
+ "IC35L010AVER07-0",
+ "IC35L020AVER07-0",
+ "IC35L030AVER07-0",
+ "IC35L040AVER07-0",
+ "IC35L060AVER07-0",
+ "WDC AC310200R",
+ NULL
+};
+
+static const char *bad_ata66_4[] = {
+ "IBM-DTLA-307075",
+ "IBM-DTLA-307060",
+ "IBM-DTLA-307045",
+ "IBM-DTLA-307030",
+ "IBM-DTLA-307020",
+ "IBM-DTLA-307015",
+ "IBM-DTLA-305040",
+ "IBM-DTLA-305030",
+ "IBM-DTLA-305020",
+ "IC35L010AVER07-0",
+ "IC35L020AVER07-0",
+ "IC35L030AVER07-0",
+ "IC35L040AVER07-0",
+ "IC35L060AVER07-0",
+ "WDC AC310200R",
+ NULL
+};
+
+static const char *bad_ata66_3[] = {
+ "WDC AC310200R",
+ NULL
+};
+
+static const char *bad_ata33[] = {
+ "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
+ "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
+ "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
+ "Maxtor 90510D4",
+ "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
+ "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
+ "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
+ NULL
+};
+
+struct chipset_bus_clock_list_entry {
+ byte xfer_speed;
+ unsigned int chipset_settings;
+};
+
+/* key for bus clock timings
+ * bit
+ * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
+ * DMA. cycles = value + 1
+ * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW
+ * DMA. cycles = value + 1
+ * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ * register access.
+ * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file
+ * register access.
+ * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer.
+ * during task file register access.
+ * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA
+ * xfer.
+ * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ * register access.
+ * 28 UDMA enable
+ * 29 DMA enable
+ * 30 PIO_MST enable. if set, the chip is in bus master mode during
+ * PIO.
+ * 31 FIFO enable.
+ */
+static struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
+ { XFER_UDMA_4, 0x900fd943 },
+ { XFER_UDMA_3, 0x900ad943 },
+ { XFER_UDMA_2, 0x900bd943 },
+ { XFER_UDMA_1, 0x9008d943 },
+ { XFER_UDMA_0, 0x9008d943 },
+
+ { XFER_MW_DMA_2, 0xa008d943 },
+ { XFER_MW_DMA_1, 0xa010d955 },
+ { XFER_MW_DMA_0, 0xa010d9fc },
+
+ { XFER_PIO_4, 0xc008d963 },
+ { XFER_PIO_3, 0xc010d974 },
+ { XFER_PIO_2, 0xc010d997 },
+ { XFER_PIO_1, 0xc010d9c7 },
+ { XFER_PIO_0, 0xc018d9d9 },
+ { 0, 0x0120d9d9 }
+};
+
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
+ { XFER_UDMA_4, 0x90c9a731 },
+ { XFER_UDMA_3, 0x90cfa731 },
+ { XFER_UDMA_2, 0x90caa731 },
+ { XFER_UDMA_1, 0x90cba731 },
+ { XFER_UDMA_0, 0x90c8a731 },
+
+ { XFER_MW_DMA_2, 0xa0c8a731 },
+ { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */
+ { XFER_MW_DMA_0, 0xa0c8a797 },
+
+ { XFER_PIO_4, 0xc0c8a731 },
+ { XFER_PIO_3, 0xc0c8a742 },
+ { XFER_PIO_2, 0xc0d0a753 },
+ { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */
+ { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */
+ { 0, 0x0120a7a7 }
+};
+
+static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
+
+ { XFER_UDMA_4, 0x90c98521 },
+ { XFER_UDMA_3, 0x90cf8521 },
+ { XFER_UDMA_2, 0x90cf8521 },
+ { XFER_UDMA_1, 0x90cb8521 },
+ { XFER_UDMA_0, 0x90cb8521 },
+
+ { XFER_MW_DMA_2, 0xa0ca8521 },
+ { XFER_MW_DMA_1, 0xa0ca8532 },
+ { XFER_MW_DMA_0, 0xa0ca8575 },
+
+ { XFER_PIO_4, 0xc0ca8521 },
+ { XFER_PIO_3, 0xc0ca8532 },
+ { XFER_PIO_2, 0xc0ca8542 },
+ { XFER_PIO_1, 0xc0d08572 },
+ { XFER_PIO_0, 0xc0d08585 },
+ { 0, 0x01208585 }
+};
+
+/* from highpoint documentation. these are old values */
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
+/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */
+ { XFER_UDMA_5, 0x16454e31 },
+ { XFER_UDMA_4, 0x16454e31 },
+ { XFER_UDMA_3, 0x166d4e31 },
+ { XFER_UDMA_2, 0x16494e31 },
+ { XFER_UDMA_1, 0x164d4e31 },
+ { XFER_UDMA_0, 0x16514e31 },
+
+ { XFER_MW_DMA_2, 0x26514e21 },
+ { XFER_MW_DMA_1, 0x26514e33 },
+ { XFER_MW_DMA_0, 0x26514e97 },
+
+ { XFER_PIO_4, 0x06514e21 },
+ { XFER_PIO_3, 0x06514e22 },
+ { XFER_PIO_2, 0x06514e33 },
+ { XFER_PIO_1, 0x06914e43 },
+ { XFER_PIO_0, 0x06914e57 },
+ { 0, 0x06514e57 }
+};
+
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
+ { XFER_UDMA_5, 0x14846231 },
+ { XFER_UDMA_4, 0x14886231 },
+ { XFER_UDMA_3, 0x148c6231 },
+ { XFER_UDMA_2, 0x148c6231 },
+ { XFER_UDMA_1, 0x14906231 },
+ { XFER_UDMA_0, 0x14986231 },
+
+ { XFER_MW_DMA_2, 0x26514e21 },
+ { XFER_MW_DMA_1, 0x26514e33 },
+ { XFER_MW_DMA_0, 0x26514e97 },
+
+ { XFER_PIO_4, 0x06514e21 },
+ { XFER_PIO_3, 0x06514e22 },
+ { XFER_PIO_2, 0x06514e33 },
+ { XFER_PIO_1, 0x06914e43 },
+ { XFER_PIO_0, 0x06914e57 },
+ { 0, 0x06514e57 }
+};
+
+/* these are the current (4 sep 2001) timings from highpoint */
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = {
+ { XFER_UDMA_5, 0x12446231 },
+ { XFER_UDMA_4, 0x12446231 },
+ { XFER_UDMA_3, 0x126c6231 },
+ { XFER_UDMA_2, 0x12486231 },
+ { XFER_UDMA_1, 0x124c6233 },
+ { XFER_UDMA_0, 0x12506297 },
+
+ { XFER_MW_DMA_2, 0x22406c31 },
+ { XFER_MW_DMA_1, 0x22406c33 },
+ { XFER_MW_DMA_0, 0x22406c97 },
+
+ { XFER_PIO_4, 0x06414e31 },
+ { XFER_PIO_3, 0x06414e42 },
+ { XFER_PIO_2, 0x06414e53 },
+ { XFER_PIO_1, 0x06814e93 },
+ { XFER_PIO_0, 0x06814ea7 },
+ { 0, 0x06814ea7 }
+};
+
+/* 2x 33MHz timings */
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = {
+ { XFER_UDMA_5, 0x1488e673 },
+ { XFER_UDMA_4, 0x1488e673 },
+ { XFER_UDMA_3, 0x1498e673 },
+ { XFER_UDMA_2, 0x1490e673 },
+ { XFER_UDMA_1, 0x1498e677 },
+ { XFER_UDMA_0, 0x14a0e73f },
+
+ { XFER_MW_DMA_2, 0x2480fa73 },
+ { XFER_MW_DMA_1, 0x2480fa77 },
+ { XFER_MW_DMA_0, 0x2480fb3f },
+
+ { XFER_PIO_4, 0x0c82be73 },
+ { XFER_PIO_3, 0x0c82be95 },
+ { XFER_PIO_2, 0x0c82beb7 },
+ { XFER_PIO_1, 0x0d02bf37 },
+ { XFER_PIO_0, 0x0d02bf5f },
+ { 0, 0x0d02bf5f }
+};
+
+static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = {
+ { XFER_UDMA_5, 0x12848242 },
+ { XFER_UDMA_4, 0x12ac8242 },
+ { XFER_UDMA_3, 0x128c8242 },
+ { XFER_UDMA_2, 0x120c8242 },
+ { XFER_UDMA_1, 0x12148254 },
+ { XFER_UDMA_0, 0x121882ea },
+
+ { XFER_MW_DMA_2, 0x22808242 },
+ { XFER_MW_DMA_1, 0x22808254 },
+ { XFER_MW_DMA_0, 0x228082ea },
+
+ { XFER_PIO_4, 0x0a81f442 },
+ { XFER_PIO_3, 0x0a81f443 },
+ { XFER_PIO_2, 0x0a81f454 },
+ { XFER_PIO_1, 0x0ac1f465 },
+ { XFER_PIO_0, 0x0ac1f48a },
+ { 0, 0x0ac1f48a }
+};
+
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
+ { XFER_UDMA_6, 0x1c81dc62 },
+ { XFER_UDMA_5, 0x1c6ddc62 },
+ { XFER_UDMA_4, 0x1c8ddc62 },
+ { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */
+ { XFER_UDMA_2, 0x1c91dc62 },
+ { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */
+ { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */
+
+ { XFER_MW_DMA_2, 0x2c829262 },
+ { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */
+ { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */
+
+ { XFER_PIO_4, 0x0c829c62 },
+ { XFER_PIO_3, 0x0c829c84 },
+ { XFER_PIO_2, 0x0c829ca6 },
+ { XFER_PIO_1, 0x0d029d26 },
+ { XFER_PIO_0, 0x0d029d5e },
+ { 0, 0x0d029d5e }
+};
+
+static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
+ { XFER_UDMA_5, 0x12848242 },
+ { XFER_UDMA_4, 0x12ac8242 },
+ { XFER_UDMA_3, 0x128c8242 },
+ { XFER_UDMA_2, 0x120c8242 },
+ { XFER_UDMA_1, 0x12148254 },
+ { XFER_UDMA_0, 0x121882ea },
+
+ { XFER_MW_DMA_2, 0x22808242 },
+ { XFER_MW_DMA_1, 0x22808254 },
+ { XFER_MW_DMA_0, 0x228082ea },
+
+ { XFER_PIO_4, 0x0a81f442 },
+ { XFER_PIO_3, 0x0a81f443 },
+ { XFER_PIO_2, 0x0a81f454 },
+ { XFER_PIO_1, 0x0ac1f465 },
+ { XFER_PIO_0, 0x0ac1f48a },
+ { 0, 0x0a81f443 }
+};
+
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
+ { XFER_UDMA_6, 0x1c869c62 },
+ { XFER_UDMA_5, 0x1cae9c62 },
+ { XFER_UDMA_4, 0x1c8a9c62 },
+ { XFER_UDMA_3, 0x1c8e9c62 },
+ { XFER_UDMA_2, 0x1c929c62 },
+ { XFER_UDMA_1, 0x1c9a9c62 },
+ { XFER_UDMA_0, 0x1c829c62 },
+
+ { XFER_MW_DMA_2, 0x2c829c62 },
+ { XFER_MW_DMA_1, 0x2c829c66 },
+ { XFER_MW_DMA_0, 0x2c829d2e },
+
+ { XFER_PIO_4, 0x0c829c62 },
+ { XFER_PIO_3, 0x0c829c84 },
+ { XFER_PIO_2, 0x0c829ca6 },
+ { XFER_PIO_1, 0x0d029d26 },
+ { XFER_PIO_0, 0x0d029d5e },
+ { 0, 0x0d029d26 }
+};
+
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
+ { XFER_UDMA_6, 0x12808242 },
+ { XFER_UDMA_5, 0x12848242 },
+ { XFER_UDMA_4, 0x12ac8242 },
+ { XFER_UDMA_3, 0x128c8242 },
+ { XFER_UDMA_2, 0x120c8242 },
+ { XFER_UDMA_1, 0x12148254 },
+ { XFER_UDMA_0, 0x121882ea },
+
+ { XFER_MW_DMA_2, 0x22808242 },
+ { XFER_MW_DMA_1, 0x22808254 },
+ { XFER_MW_DMA_0, 0x228082ea },
+
+ { XFER_PIO_4, 0x0a81f442 },
+ { XFER_PIO_3, 0x0a81f443 },
+ { XFER_PIO_2, 0x0a81f454 },
+ { XFER_PIO_1, 0x0ac1f465 },
+ { XFER_PIO_0, 0x0ac1f48a },
+ { 0, 0x06814e93 }
+};
+
+#if 0
+static struct chipset_bus_clock_list_entry fifty_base_hpt374[] = {
+ { XFER_UDMA_6, },
+ { XFER_UDMA_5, },
+ { XFER_UDMA_4, },
+ { XFER_UDMA_3, },
+ { XFER_UDMA_2, },
+ { XFER_UDMA_1, },
+ { XFER_UDMA_0, },
+ { XFER_MW_DMA_2, },
+ { XFER_MW_DMA_1, },
+ { XFER_MW_DMA_0, },
+ { XFER_PIO_4, },
+ { XFER_PIO_3, },
+ { XFER_PIO_2, },
+ { XFER_PIO_1, },
+ { XFER_PIO_0, },
+ { 0, }
+};
+#endif
+#if 0
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
+ { XFER_UDMA_6, 0x12406231 }, /* checkme */
+ { XFER_UDMA_5, 0x12446231 },
+ 0x14846231
+ { XFER_UDMA_4, 0x16814ea7 },
+ 0x14886231
+ { XFER_UDMA_3, 0x16814ea7 },
+ 0x148c6231
+ { XFER_UDMA_2, 0x16814ea7 },
+ 0x148c6231
+ { XFER_UDMA_1, 0x16814ea7 },
+ 0x14906231
+ { XFER_UDMA_0, 0x16814ea7 },
+ 0x14986231
+ { XFER_MW_DMA_2, 0x16814ea7 },
+ 0x26514e21
+ { XFER_MW_DMA_1, 0x16814ea7 },
+ 0x26514e97
+ { XFER_MW_DMA_0, 0x16814ea7 },
+ 0x26514e97
+ { XFER_PIO_4, 0x06814ea7 },
+ 0x06514e21
+ { XFER_PIO_3, 0x06814ea7 },
+ 0x06514e22
+ { XFER_PIO_2, 0x06814ea7 },
+ 0x06514e33
+ { XFER_PIO_1, 0x06814ea7 },
+ 0x06914e43
+ { XFER_PIO_0, 0x06814ea7 },
+ 0x06914e57
+ { 0, 0x06814ea7 }
+};
+#endif
+
+#define HPT366_DEBUG_DRIVE_INFO 0
+#define HPT374_ALLOW_ATA133_6 0
+#define HPT371_ALLOW_ATA133_6 0
+#define HPT302_ALLOW_ATA133_6 0
+#define HPT372_ALLOW_ATA133_6 1
+#define HPT370_ALLOW_ATA100_5 1
+#define HPT366_ALLOW_ATA66_4 1
+#define HPT366_ALLOW_ATA66_3 1
+#define HPT366_MAX_DEVS 8
+
+#define F_LOW_PCI_33 0x23
+#define F_LOW_PCI_40 0x29
+#define F_LOW_PCI_50 0x2d
+#define F_LOW_PCI_66 0x42

#if 0
if (hpt_minimum_revision(dev, 3)) {
@@ -1273,6 +1680,64 @@ init_single:
return ide_setup_pci_device(dev, d);
}

+static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "HPT366",
+ .init_setup = init_setup_hpt366,
+ .init_chipset = init_chipset_hpt366,
+ .init_hwif = init_hwif_hpt366,
+ .init_dma = init_dma_hpt366,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ .extra = 240
+ },{ /* 1 */
+ .name = "HPT372A",
+ .init_setup = init_setup_hpt37x,
+ .init_chipset = init_chipset_hpt366,
+ .init_hwif = init_hwif_hpt366,
+ .init_dma = init_dma_hpt366,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 2 */
+ .name = "HPT302",
+ .init_setup = init_setup_hpt37x,
+ .init_chipset = init_chipset_hpt366,
+ .init_hwif = init_hwif_hpt366,
+ .init_dma = init_dma_hpt366,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 3 */
+ .name = "HPT371",
+ .init_setup = init_setup_hpt37x,
+ .init_chipset = init_chipset_hpt366,
+ .init_hwif = init_hwif_hpt366,
+ .init_dma = init_dma_hpt366,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 4 */
+ .name = "HPT374",
+ .init_setup = init_setup_hpt374,
+ .init_chipset = init_chipset_hpt366,
+ .init_hwif = init_hwif_hpt366,
+ .init_dma = init_dma_hpt366,
+ .channels = 2, /* 4 */
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 5 */
+ .name = "HPT372N",
+ .init_setup = init_setup_hpt37x,
+ .init_chipset = init_chipset_hpt366,
+ .init_hwif = init_hwif_hpt366,
+ .init_dma = init_dma_hpt366,
+ .channels = 2, /* 4 */
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ }
+};

/**
* hpt366_init_one - called when an HPT366 is found
Index: linux-ide-export/drivers/ide/pci/hpt366.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/hpt366.h 2005-02-02 10:27:16.179155136 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,483 +0,0 @@
-#ifndef HPT366_H
-#define HPT366_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-/* various tuning parameters */
-#define HPT_RESET_STATE_ENGINE
-#undef HPT_DELAY_INTERRUPT
-#undef HPT_SERIALIZE_IO
-
-static const char *quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
-static const char *bad_ata100_5[] = {
- "IBM-DTLA-307075",
- "IBM-DTLA-307060",
- "IBM-DTLA-307045",
- "IBM-DTLA-307030",
- "IBM-DTLA-307020",
- "IBM-DTLA-307015",
- "IBM-DTLA-305040",
- "IBM-DTLA-305030",
- "IBM-DTLA-305020",
- "IC35L010AVER07-0",
- "IC35L020AVER07-0",
- "IC35L030AVER07-0",
- "IC35L040AVER07-0",
- "IC35L060AVER07-0",
- "WDC AC310200R",
- NULL
-};
-
-static const char *bad_ata66_4[] = {
- "IBM-DTLA-307075",
- "IBM-DTLA-307060",
- "IBM-DTLA-307045",
- "IBM-DTLA-307030",
- "IBM-DTLA-307020",
- "IBM-DTLA-307015",
- "IBM-DTLA-305040",
- "IBM-DTLA-305030",
- "IBM-DTLA-305020",
- "IC35L010AVER07-0",
- "IC35L020AVER07-0",
- "IC35L030AVER07-0",
- "IC35L040AVER07-0",
- "IC35L060AVER07-0",
- "WDC AC310200R",
- NULL
-};
-
-static const char *bad_ata66_3[] = {
- "WDC AC310200R",
- NULL
-};
-
-static const char *bad_ata33[] = {
- "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
- "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
- "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
- "Maxtor 90510D4",
- "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
- "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
- "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
- NULL
-};
-
-struct chipset_bus_clock_list_entry {
- byte xfer_speed;
- unsigned int chipset_settings;
-};
-
-/* key for bus clock timings
- * bit
- * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- * DMA. cycles = value + 1
- * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- * DMA. cycles = value + 1
- * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file
- * register access.
- * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file
- * register access.
- * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- * during task file register access.
- * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- * xfer.
- * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task
- * register access.
- * 28 UDMA enable
- * 29 DMA enable
- * 30 PIO_MST enable. if set, the chip is in bus master mode during
- * PIO.
- * 31 FIFO enable.
- */
-static struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
- { XFER_UDMA_4, 0x900fd943 },
- { XFER_UDMA_3, 0x900ad943 },
- { XFER_UDMA_2, 0x900bd943 },
- { XFER_UDMA_1, 0x9008d943 },
- { XFER_UDMA_0, 0x9008d943 },
-
- { XFER_MW_DMA_2, 0xa008d943 },
- { XFER_MW_DMA_1, 0xa010d955 },
- { XFER_MW_DMA_0, 0xa010d9fc },
-
- { XFER_PIO_4, 0xc008d963 },
- { XFER_PIO_3, 0xc010d974 },
- { XFER_PIO_2, 0xc010d997 },
- { XFER_PIO_1, 0xc010d9c7 },
- { XFER_PIO_0, 0xc018d9d9 },
- { 0, 0x0120d9d9 }
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
- { XFER_UDMA_4, 0x90c9a731 },
- { XFER_UDMA_3, 0x90cfa731 },
- { XFER_UDMA_2, 0x90caa731 },
- { XFER_UDMA_1, 0x90cba731 },
- { XFER_UDMA_0, 0x90c8a731 },
-
- { XFER_MW_DMA_2, 0xa0c8a731 },
- { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */
- { XFER_MW_DMA_0, 0xa0c8a797 },
-
- { XFER_PIO_4, 0xc0c8a731 },
- { XFER_PIO_3, 0xc0c8a742 },
- { XFER_PIO_2, 0xc0d0a753 },
- { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */
- { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */
- { 0, 0x0120a7a7 }
-};
-
-static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
-
- { XFER_UDMA_4, 0x90c98521 },
- { XFER_UDMA_3, 0x90cf8521 },
- { XFER_UDMA_2, 0x90cf8521 },
- { XFER_UDMA_1, 0x90cb8521 },
- { XFER_UDMA_0, 0x90cb8521 },
-
- { XFER_MW_DMA_2, 0xa0ca8521 },
- { XFER_MW_DMA_1, 0xa0ca8532 },
- { XFER_MW_DMA_0, 0xa0ca8575 },
-
- { XFER_PIO_4, 0xc0ca8521 },
- { XFER_PIO_3, 0xc0ca8532 },
- { XFER_PIO_2, 0xc0ca8542 },
- { XFER_PIO_1, 0xc0d08572 },
- { XFER_PIO_0, 0xc0d08585 },
- { 0, 0x01208585 }
-};
-
-/* from highpoint documentation. these are old values */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
-/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */
- { XFER_UDMA_5, 0x16454e31 },
- { XFER_UDMA_4, 0x16454e31 },
- { XFER_UDMA_3, 0x166d4e31 },
- { XFER_UDMA_2, 0x16494e31 },
- { XFER_UDMA_1, 0x164d4e31 },
- { XFER_UDMA_0, 0x16514e31 },
-
- { XFER_MW_DMA_2, 0x26514e21 },
- { XFER_MW_DMA_1, 0x26514e33 },
- { XFER_MW_DMA_0, 0x26514e97 },
-
- { XFER_PIO_4, 0x06514e21 },
- { XFER_PIO_3, 0x06514e22 },
- { XFER_PIO_2, 0x06514e33 },
- { XFER_PIO_1, 0x06914e43 },
- { XFER_PIO_0, 0x06914e57 },
- { 0, 0x06514e57 }
-};
-
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
- { XFER_UDMA_5, 0x14846231 },
- { XFER_UDMA_4, 0x14886231 },
- { XFER_UDMA_3, 0x148c6231 },
- { XFER_UDMA_2, 0x148c6231 },
- { XFER_UDMA_1, 0x14906231 },
- { XFER_UDMA_0, 0x14986231 },
-
- { XFER_MW_DMA_2, 0x26514e21 },
- { XFER_MW_DMA_1, 0x26514e33 },
- { XFER_MW_DMA_0, 0x26514e97 },
-
- { XFER_PIO_4, 0x06514e21 },
- { XFER_PIO_3, 0x06514e22 },
- { XFER_PIO_2, 0x06514e33 },
- { XFER_PIO_1, 0x06914e43 },
- { XFER_PIO_0, 0x06914e57 },
- { 0, 0x06514e57 }
-};
-
-/* these are the current (4 sep 2001) timings from highpoint */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = {
- { XFER_UDMA_5, 0x12446231 },
- { XFER_UDMA_4, 0x12446231 },
- { XFER_UDMA_3, 0x126c6231 },
- { XFER_UDMA_2, 0x12486231 },
- { XFER_UDMA_1, 0x124c6233 },
- { XFER_UDMA_0, 0x12506297 },
-
- { XFER_MW_DMA_2, 0x22406c31 },
- { XFER_MW_DMA_1, 0x22406c33 },
- { XFER_MW_DMA_0, 0x22406c97 },
-
- { XFER_PIO_4, 0x06414e31 },
- { XFER_PIO_3, 0x06414e42 },
- { XFER_PIO_2, 0x06414e53 },
- { XFER_PIO_1, 0x06814e93 },
- { XFER_PIO_0, 0x06814ea7 },
- { 0, 0x06814ea7 }
-};
-
-/* 2x 33MHz timings */
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = {
- { XFER_UDMA_5, 0x1488e673 },
- { XFER_UDMA_4, 0x1488e673 },
- { XFER_UDMA_3, 0x1498e673 },
- { XFER_UDMA_2, 0x1490e673 },
- { XFER_UDMA_1, 0x1498e677 },
- { XFER_UDMA_0, 0x14a0e73f },
-
- { XFER_MW_DMA_2, 0x2480fa73 },
- { XFER_MW_DMA_1, 0x2480fa77 },
- { XFER_MW_DMA_0, 0x2480fb3f },
-
- { XFER_PIO_4, 0x0c82be73 },
- { XFER_PIO_3, 0x0c82be95 },
- { XFER_PIO_2, 0x0c82beb7 },
- { XFER_PIO_1, 0x0d02bf37 },
- { XFER_PIO_0, 0x0d02bf5f },
- { 0, 0x0d02bf5f }
-};
-
-static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = {
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x0ac1f48a }
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
- { XFER_UDMA_6, 0x1c81dc62 },
- { XFER_UDMA_5, 0x1c6ddc62 },
- { XFER_UDMA_4, 0x1c8ddc62 },
- { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */
- { XFER_UDMA_2, 0x1c91dc62 },
- { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */
- { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */
-
- { XFER_MW_DMA_2, 0x2c829262 },
- { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */
- { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */
-
- { XFER_PIO_4, 0x0c829c62 },
- { XFER_PIO_3, 0x0c829c84 },
- { XFER_PIO_2, 0x0c829ca6 },
- { XFER_PIO_1, 0x0d029d26 },
- { XFER_PIO_0, 0x0d029d5e },
- { 0, 0x0d029d5e }
-};
-
-static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x0a81f443 }
-};
-
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
- { XFER_UDMA_6, 0x1c869c62 },
- { XFER_UDMA_5, 0x1cae9c62 },
- { XFER_UDMA_4, 0x1c8a9c62 },
- { XFER_UDMA_3, 0x1c8e9c62 },
- { XFER_UDMA_2, 0x1c929c62 },
- { XFER_UDMA_1, 0x1c9a9c62 },
- { XFER_UDMA_0, 0x1c829c62 },
-
- { XFER_MW_DMA_2, 0x2c829c62 },
- { XFER_MW_DMA_1, 0x2c829c66 },
- { XFER_MW_DMA_0, 0x2c829d2e },
-
- { XFER_PIO_4, 0x0c829c62 },
- { XFER_PIO_3, 0x0c829c84 },
- { XFER_PIO_2, 0x0c829ca6 },
- { XFER_PIO_1, 0x0d029d26 },
- { XFER_PIO_0, 0x0d029d5e },
- { 0, 0x0d029d26 }
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
- { XFER_UDMA_6, 0x12808242 },
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x06814e93 }
-};
-
-#if 0
-static struct chipset_bus_clock_list_entry fifty_base_hpt374[] = {
- { XFER_UDMA_6, },
- { XFER_UDMA_5, },
- { XFER_UDMA_4, },
- { XFER_UDMA_3, },
- { XFER_UDMA_2, },
- { XFER_UDMA_1, },
- { XFER_UDMA_0, },
- { XFER_MW_DMA_2, },
- { XFER_MW_DMA_1, },
- { XFER_MW_DMA_0, },
- { XFER_PIO_4, },
- { XFER_PIO_3, },
- { XFER_PIO_2, },
- { XFER_PIO_1, },
- { XFER_PIO_0, },
- { 0, }
-};
-#endif
-#if 0
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
- { XFER_UDMA_6, 0x12406231 }, /* checkme */
- { XFER_UDMA_5, 0x12446231 },
- 0x14846231
- { XFER_UDMA_4, 0x16814ea7 },
- 0x14886231
- { XFER_UDMA_3, 0x16814ea7 },
- 0x148c6231
- { XFER_UDMA_2, 0x16814ea7 },
- 0x148c6231
- { XFER_UDMA_1, 0x16814ea7 },
- 0x14906231
- { XFER_UDMA_0, 0x16814ea7 },
- 0x14986231
- { XFER_MW_DMA_2, 0x16814ea7 },
- 0x26514e21
- { XFER_MW_DMA_1, 0x16814ea7 },
- 0x26514e97
- { XFER_MW_DMA_0, 0x16814ea7 },
- 0x26514e97
- { XFER_PIO_4, 0x06814ea7 },
- 0x06514e21
- { XFER_PIO_3, 0x06814ea7 },
- 0x06514e22
- { XFER_PIO_2, 0x06814ea7 },
- 0x06514e33
- { XFER_PIO_1, 0x06814ea7 },
- 0x06914e43
- { XFER_PIO_0, 0x06814ea7 },
- 0x06914e57
- { 0, 0x06814ea7 }
-};
-#endif
-
-#define HPT366_DEBUG_DRIVE_INFO 0
-#define HPT374_ALLOW_ATA133_6 0
-#define HPT371_ALLOW_ATA133_6 0
-#define HPT302_ALLOW_ATA133_6 0
-#define HPT372_ALLOW_ATA133_6 1
-#define HPT370_ALLOW_ATA100_5 1
-#define HPT366_ALLOW_ATA66_4 1
-#define HPT366_ALLOW_ATA66_3 1
-#define HPT366_MAX_DEVS 8
-
-#define F_LOW_PCI_33 0x23
-#define F_LOW_PCI_40 0x29
-#define F_LOW_PCI_50 0x2d
-#define F_LOW_PCI_66 0x42
-
-static int init_setup_hpt366(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_hpt37x(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_hpt374(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_hpt366(struct pci_dev *, const char *);
-static void init_hwif_hpt366(ide_hwif_t *);
-static void init_dma_hpt366(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "HPT366",
- .init_setup = init_setup_hpt366,
- .init_chipset = init_chipset_hpt366,
- .init_hwif = init_hwif_hpt366,
- .init_dma = init_dma_hpt366,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .extra = 240
- },{ /* 1 */
- .name = "HPT372A",
- .init_setup = init_setup_hpt37x,
- .init_chipset = init_chipset_hpt366,
- .init_hwif = init_hwif_hpt366,
- .init_dma = init_dma_hpt366,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 2 */
- .name = "HPT302",
- .init_setup = init_setup_hpt37x,
- .init_chipset = init_chipset_hpt366,
- .init_hwif = init_hwif_hpt366,
- .init_dma = init_dma_hpt366,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 3 */
- .name = "HPT371",
- .init_setup = init_setup_hpt37x,
- .init_chipset = init_chipset_hpt366,
- .init_hwif = init_hwif_hpt366,
- .init_dma = init_dma_hpt366,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 4 */
- .name = "HPT374",
- .init_setup = init_setup_hpt374,
- .init_chipset = init_chipset_hpt366,
- .init_hwif = init_hwif_hpt366,
- .init_dma = init_dma_hpt366,
- .channels = 2, /* 4 */
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 5 */
- .name = "HPT372N",
- .init_setup = init_setup_hpt37x,
- .init_chipset = init_chipset_hpt366,
- .init_hwif = init_hwif_hpt366,
- .init_dma = init_dma_hpt366,
- .channels = 2, /* 4 */
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- }
-};
-
-#endif /* HPT366_H */
Index: linux-ide-export/drivers/ide/pci/it8172.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/it8172.c 2005-02-02 10:27:16.180154974 +0900
+++ linux-ide-export/drivers/ide/pci/it8172.c 2005-02-02 10:28:02.669612433 +0900
@@ -42,8 +42,6 @@
#include <asm/io.h>
#include <asm/it8172/it8172_int.h>

-#include "it8172.h"
-
/*
* Prototypes
*/
@@ -266,6 +264,18 @@ static void __init init_hwif_it8172 (ide
hwif->drives[1].autodma = hwif->autodma;
}

+static ide_pci_device_t it8172_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "IT8172G",
+ .init_chipset = init_chipset_it8172,
+ .init_hwif = init_hwif_it8172,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
+ .bootable = ON_BOARD,
+ }
+};
+
static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
if ((!(PCI_FUNC(dev->devfn) & 1) ||
Index: linux-ide-export/drivers/ide/pci/it8172.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/it8172.h 2005-02-02 10:28:01.638779685 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-#ifndef ITE8172G_H
-#define ITE8172G_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static u8 it8172_ratemask(ide_drive_t *drive);
-static void it8172_tune_drive(ide_drive_t *drive, u8 pio);
-static u8 it8172_dma_2_pio(u8 xfer_rate);
-static int it8172_tune_chipset(ide_drive_t *drive, u8 xferspeed);
-#ifdef CONFIG_BLK_DEV_IDEDMA
-static int it8172_config_chipset_for_dma(ide_drive_t *drive);
-#endif
-
-static unsigned int init_chipset_it8172(struct pci_dev *, const char *);
-static void init_hwif_it8172(ide_hwif_t *);
-
-static ide_pci_device_t it8172_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "IT8172G",
- .init_chipset = init_chipset_it8172,
- .init_hwif = init_hwif_it8172,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
- .bootable = ON_BOARD,
- }
-};
-
-#endif /* ITE8172G_H */
Index: linux-ide-export/drivers/ide/pci/opti621.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/opti621.c 2005-02-02 10:28:01.947729558 +0900
+++ linux-ide-export/drivers/ide/pci/opti621.c 2005-02-02 10:28:02.671612108 +0900
@@ -104,8 +104,6 @@

#include <asm/io.h>

-#include "opti621.h"
-
#define OPTI621_MAX_PIO 3
/* In fact, I do not have any PIO 4 drive
* (address: 25 ns, data: 70 ns, recovery: 35 ns),
@@ -348,6 +346,24 @@ static void __init init_hwif_opti621 (id
hwif->drives[1].autodma = hwif->autodma;
}

+static ide_pci_device_t opti621_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "OPTI621",
+ .init_hwif = init_hwif_opti621,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
+ .bootable = ON_BOARD,
+ },{ /* 1 */
+ .name = "OPTI621X",
+ .init_hwif = init_hwif_opti621,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
+ .bootable = ON_BOARD,
+ }
+};
+
static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]);
Index: linux-ide-export/drivers/ide/pci/opti621.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/opti621.h 2005-02-02 10:28:01.948729395 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-#ifndef OPTI621_H
-#define OPTI621_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static void init_hwif_opti621(ide_hwif_t *);
-
-static ide_pci_device_t opti621_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "OPTI621",
- .init_hwif = init_hwif_opti621,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
- .bootable = ON_BOARD,
- },{ /* 1 */
- .name = "OPTI621X",
- .init_hwif = init_hwif_opti621,
- .channels = 2,
- .autodma = AUTODMA,
- .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
- .bootable = ON_BOARD,
- }
-};
-
-#endif /* OPTI621_H */
Index: linux-ide-export/drivers/ide/pci/pdc202xx_new.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/pdc202xx_new.c 2005-02-02 10:27:16.181154812 +0900
+++ linux-ide-export/drivers/ide/pci/pdc202xx_new.c 2005-02-02 10:28:02.672611946 +0900
@@ -37,10 +37,46 @@
#include <asm/pci-bridge.h>
#endif

-#include "pdc202xx_new.h"
-
#define PDC202_DEBUG_CABLE 0

+const static char *pdc_quirk_drives[] = {
+ "QUANTUM FIREBALLlct08 08",
+ "QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP KA9.1",
+ "QUANTUM FIREBALLP LM20.4",
+ "QUANTUM FIREBALLP KX13.6",
+ "QUANTUM FIREBALLP KX20.5",
+ "QUANTUM FIREBALLP KX27.3",
+ "QUANTUM FIREBALLP LM20.5",
+ NULL
+};
+
+#define set_2regs(a, b) \
+ do { \
+ hwif->OUTB((a + adj), indexreg); \
+ hwif->OUTB(b, datareg); \
+ } while(0)
+
+#define set_ultra(a, b, c) \
+ do { \
+ set_2regs(0x10,(a)); \
+ set_2regs(0x11,(b)); \
+ set_2regs(0x12,(c)); \
+ } while(0)
+
+#define set_ata2(a, b) \
+ do { \
+ set_2regs(0x0e,(a)); \
+ set_2regs(0x0f,(b)); \
+ } while(0)
+
+#define set_pio(a, b, c) \
+ do { \
+ set_2regs(0x0c,(a)); \
+ set_2regs(0x0d,(b)); \
+ set_2regs(0x13,(c)); \
+ } while(0)
+
static u8 pdcnew_ratemask (ide_drive_t *drive)
{
u8 mode;
@@ -360,6 +396,72 @@ static int __devinit init_setup_pdc20276
return ide_setup_pci_device(dev, d);
}

+static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "PDC20268",
+ .init_setup = init_setup_pdcnew,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 1 */
+ .name = "PDC20269",
+ .init_setup = init_setup_pdcnew,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 2 */
+ .name = "PDC20270",
+ .init_setup = init_setup_pdc20270,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ },{ /* 3 */
+ .name = "PDC20271",
+ .init_setup = init_setup_pdcnew,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 4 */
+ .name = "PDC20275",
+ .init_setup = init_setup_pdcnew,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ },{ /* 5 */
+ .name = "PDC20276",
+ .init_setup = init_setup_pdc20276,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ },{ /* 6 */
+ .name = "PDC20277",
+ .init_setup = init_setup_pdcnew,
+ .init_chipset = init_chipset_pdcnew,
+ .init_hwif = init_hwif_pdc202new,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = OFF_BOARD,
+ }
+};
+
/**
* pdc202new_init_one - called when a pdc202xx is found
* @dev: the pdc202new device
Index: linux-ide-export/drivers/ide/pci/pdc202xx_new.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/pdc202xx_new.h 2005-02-02 10:27:16.181154812 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,118 +0,0 @@
-#ifndef PDC202XX_H
-#define PDC202XX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-const static char *pdc_quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP KA9.1",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP KX13.6",
- "QUANTUM FIREBALLP KX20.5",
- "QUANTUM FIREBALLP KX27.3",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
-#define set_2regs(a, b) \
- do { \
- hwif->OUTB((a + adj), indexreg); \
- hwif->OUTB(b, datareg); \
- } while(0)
-
-#define set_ultra(a, b, c) \
- do { \
- set_2regs(0x10,(a)); \
- set_2regs(0x11,(b)); \
- set_2regs(0x12,(c)); \
- } while(0)
-
-#define set_ata2(a, b) \
- do { \
- set_2regs(0x0e,(a)); \
- set_2regs(0x0f,(b)); \
- } while(0)
-
-#define set_pio(a, b, c) \
- do { \
- set_2regs(0x0c,(a)); \
- set_2regs(0x0d,(b)); \
- set_2regs(0x13,(c)); \
- } while(0)
-
-static int init_setup_pdcnew(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_pdc20270(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d);
-static unsigned int init_chipset_pdcnew(struct pci_dev *, const char *);
-static void init_hwif_pdc202new(ide_hwif_t *);
-
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "PDC20268",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 1 */
- .name = "PDC20269",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 2 */
- .name = "PDC20270",
- .init_setup = init_setup_pdc20270,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- },{ /* 3 */
- .name = "PDC20271",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 4 */
- .name = "PDC20275",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 5 */
- .name = "PDC20276",
- .init_setup = init_setup_pdc20276,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- },{ /* 6 */
- .name = "PDC20277",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- }
-};
-
-#endif /* PDC202XX_H */
Index: linux-ide-export/drivers/ide/pci/pdc202xx_old.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/pdc202xx_old.c 2005-02-02 10:27:16.181154812 +0900
+++ linux-ide-export/drivers/ide/pci/pdc202xx_old.c 2005-02-02 10:28:02.674611622 +0900
@@ -46,9 +46,64 @@
#include <asm/io.h>
#include <asm/irq.h>

-#include "pdc202xx_old.h"
+#define PDC202_DEBUG_CABLE 0
+#define PDC202XX_DEBUG_DRIVE_INFO 0

-#define PDC202_DEBUG_CABLE 0
+static const char *pdc_quirk_drives[] = {
+ "QUANTUM FIREBALLlct08 08",
+ "QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP KA9.1",
+ "QUANTUM FIREBALLP LM20.4",
+ "QUANTUM FIREBALLP KX13.6",
+ "QUANTUM FIREBALLP KX20.5",
+ "QUANTUM FIREBALLP KX27.3",
+ "QUANTUM FIREBALLP LM20.5",
+ NULL
+};
+
+#ifndef SPLIT_BYTE
+#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
+#endif
+
+/* A Register */
+#define SYNC_ERRDY_EN 0xC0
+
+#define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */
+#define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */
+#define IORDY_EN 0x20 /* PIO: IOREADY */
+#define PREFETCH_EN 0x10 /* PIO: PREFETCH */
+
+#define PA3 0x08 /* PIO"A" timing */
+#define PA2 0x04 /* PIO"A" timing */
+#define PA1 0x02 /* PIO"A" timing */
+#define PA0 0x01 /* PIO"A" timing */
+
+/* B Register */
+
+#define MB2 0x80 /* DMA"B" timing */
+#define MB1 0x40 /* DMA"B" timing */
+#define MB0 0x20 /* DMA"B" timing */
+
+#define PB4 0x10 /* PIO_FORCE 1:0 */
+
+#define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */
+#define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */
+#define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */
+#define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */
+
+/* C Register */
+#define IORDYp_NO_SPEED 0x4F
+#define SPEED_DIS 0x0F
+
+#define DMARQp 0x80
+#define IORDYp 0x40
+#define DMAR_EN 0x20
+#define DMAW_EN 0x10
+
+#define MC3 0x08 /* DMA"C" timing */
+#define MC2 0x04 /* DMA"C" timing */
+#define MC1 0x02 /* DMA"C" timing */
+#define MC0 0x01 /* DMA"C" timing */

#if 0
unsigned long bibma = pci_resource_start(dev, 4);
@@ -725,6 +780,77 @@ static int __devinit init_setup_pdc202xx
return ide_setup_pci_device(dev, d);
}

+static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "PDC20246",
+ .init_setup = init_setup_pdc202ata4,
+ .init_chipset = init_chipset_pdc202xx,
+ .init_hwif = init_hwif_pdc202xx,
+ .init_dma = init_dma_pdc202xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ .extra = 16,
+ },{ /* 1 */
+ .name = "PDC20262",
+ .init_setup = init_setup_pdc202ata4,
+ .init_chipset = init_chipset_pdc202xx,
+ .init_hwif = init_hwif_pdc202xx,
+ .init_dma = init_dma_pdc202xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ .extra = 48,
+ .flags = IDEPCI_FLAG_FORCE_PDC,
+ },{ /* 2 */
+ .name = "PDC20263",
+ .init_setup = init_setup_pdc202ata4,
+ .init_chipset = init_chipset_pdc202xx,
+ .init_hwif = init_hwif_pdc202xx,
+ .init_dma = init_dma_pdc202xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ .extra = 48,
+ },{ /* 3 */
+ .name = "PDC20265",
+ .init_setup = init_setup_pdc20265,
+ .init_chipset = init_chipset_pdc202xx,
+ .init_hwif = init_hwif_pdc202xx,
+ .init_dma = init_dma_pdc202xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ .extra = 48,
+ .flags = IDEPCI_FLAG_FORCE_PDC,
+ },{ /* 4 */
+ .name = "PDC20267",
+ .init_setup = init_setup_pdc202xx,
+ .init_chipset = init_chipset_pdc202xx,
+ .init_hwif = init_hwif_pdc202xx,
+ .init_dma = init_dma_pdc202xx,
+ .channels = 2,
+ .autodma = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+ .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+ .bootable = OFF_BOARD,
+ .extra = 48,
+ }
+};
+
/**
* pdc202xx_init_one - called when a PDC202xx is found
* @dev: the pdc202xx device
Index: linux-ide-export/drivers/ide/pci/pdc202xx_old.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/pdc202xx_old.h 2005-02-02 10:27:16.182154650 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,144 +0,0 @@
-#ifndef PDC202XX_H
-#define PDC202XX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#ifndef SPLIT_BYTE
-#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
-#endif
-
-#define PDC202XX_DEBUG_DRIVE_INFO 0
-
-static const char *pdc_quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP KA9.1",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP KX13.6",
- "QUANTUM FIREBALLP KX20.5",
- "QUANTUM FIREBALLP KX27.3",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
-/* A Register */
-#define SYNC_ERRDY_EN 0xC0
-
-#define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */
-#define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */
-#define IORDY_EN 0x20 /* PIO: IOREADY */
-#define PREFETCH_EN 0x10 /* PIO: PREFETCH */
-
-#define PA3 0x08 /* PIO"A" timing */
-#define PA2 0x04 /* PIO"A" timing */
-#define PA1 0x02 /* PIO"A" timing */
-#define PA0 0x01 /* PIO"A" timing */
-
-/* B Register */
-
-#define MB2 0x80 /* DMA"B" timing */
-#define MB1 0x40 /* DMA"B" timing */
-#define MB0 0x20 /* DMA"B" timing */
-
-#define PB4 0x10 /* PIO_FORCE 1:0 */
-
-#define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */
-#define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */
-#define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */
-#define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */
-
-/* C Register */
-#define IORDYp_NO_SPEED 0x4F
-#define SPEED_DIS 0x0F
-
-#define DMARQp 0x80
-#define IORDYp 0x40
-#define DMAR_EN 0x20
-#define DMAW_EN 0x10
-
-#define MC3 0x08 /* DMA"C" timing */
-#define MC2 0x04 /* DMA"C" timing */
-#define MC1 0x02 /* DMA"C" timing */
-#define MC0 0x01 /* DMA"C" timing */
-
-static int init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d);
-static int init_setup_pdc20265(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_pdc202xx(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_pdc202xx(struct pci_dev *, const char *);
-static void init_hwif_pdc202xx(ide_hwif_t *);
-static void init_dma_pdc202xx(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "PDC20246",
- .init_setup = init_setup_pdc202ata4,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- .extra = 16,
- },{ /* 1 */
- .name = "PDC20262",
- .init_setup = init_setup_pdc202ata4,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- .extra = 48,
- .flags = IDEPCI_FLAG_FORCE_PDC,
- },{ /* 2 */
- .name = "PDC20263",
- .init_setup = init_setup_pdc202ata4,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- .extra = 48,
- },{ /* 3 */
- .name = "PDC20265",
- .init_setup = init_setup_pdc20265,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- .extra = 48,
- .flags = IDEPCI_FLAG_FORCE_PDC,
- },{ /* 4 */
- .name = "PDC20267",
- .init_setup = init_setup_pdc202xx,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .channels = 2,
- .autodma = AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
- .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
- .bootable = OFF_BOARD,
- .extra = 48,
- }
-};
-
-#endif /* PDC202XX_H */
Index: linux-ide-export/drivers/ide/pci/piix.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/piix.c 2005-02-02 10:28:02.317669535 +0900
+++ linux-ide-export/drivers/ide/pci/piix.c 2005-02-02 10:28:02.676611297 +0900
@@ -103,8 +103,6 @@

#include <asm/io.h>

-#include "piix.h"
-
static int no_piix_dma;

/**
@@ -530,6 +528,56 @@ static void __devinit init_hwif_piix(ide
hwif->drives[0].autodma = hwif->autodma;
}

+/*
+ * Table of the various PIIX capability blocks
+ */
+
+#define DECLARE_PIIX_DEV(name_str) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_piix, \
+ .init_hwif = init_hwif_piix, \
+ .channels = 2, \
+ .autodma = AUTODMA, \
+ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+ .bootable = ON_BOARD, \
+ }
+
+static ide_pci_device_t piix_pci_info[] __devinitdata = {
+ /* 0 */ DECLARE_PIIX_DEV("PIIXa"),
+ /* 1 */ DECLARE_PIIX_DEV("PIIXb"),
+
+ { /* 2 */
+ .name = "MPIIX",
+ .init_hwif = init_hwif_piix,
+ .channels = 2,
+ .autodma = NODMA,
+ .enablebits = {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},
+ .bootable = ON_BOARD,
+ },
+
+ /* 3 */ DECLARE_PIIX_DEV("PIIX3"),
+ /* 4 */ DECLARE_PIIX_DEV("PIIX4"),
+ /* 5 */ DECLARE_PIIX_DEV("ICH0"),
+ /* 6 */ DECLARE_PIIX_DEV("PIIX4"),
+ /* 7 */ DECLARE_PIIX_DEV("ICH"),
+ /* 8 */ DECLARE_PIIX_DEV("PIIX4"),
+ /* 9 */ DECLARE_PIIX_DEV("PIIX4"),
+ /* 10 */ DECLARE_PIIX_DEV("ICH2"),
+ /* 11 */ DECLARE_PIIX_DEV("ICH2M"),
+ /* 12 */ DECLARE_PIIX_DEV("ICH3M"),
+ /* 13 */ DECLARE_PIIX_DEV("ICH3"),
+ /* 14 */ DECLARE_PIIX_DEV("ICH4"),
+ /* 15 */ DECLARE_PIIX_DEV("ICH5"),
+ /* 16 */ DECLARE_PIIX_DEV("C-ICH"),
+ /* 17 */ DECLARE_PIIX_DEV("ICH4"),
+ /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA"),
+ /* 19 */ DECLARE_PIIX_DEV("ICH5"),
+ /* 20 */ DECLARE_PIIX_DEV("ICH6"),
+ /* 21 */ DECLARE_PIIX_DEV("ICH7"),
+ /* 22 */ DECLARE_PIIX_DEV("ICH4"),
+};
+
/**
* piix_init_one - called when a PIIX is found
* @dev: the piix device
Index: linux-ide-export/drivers/ide/pci/piix.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/piix.h 2005-02-02 10:28:02.317669535 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,62 +0,0 @@
-#ifndef PIIX_H
-#define PIIX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static unsigned int __devinit init_chipset_piix(struct pci_dev *, const char *);
-static void init_hwif_piix(ide_hwif_t *);
-
-#define DECLARE_PIIX_DEV(name_str) \
- { \
- .name = name_str, \
- .init_chipset = init_chipset_piix, \
- .init_hwif = init_hwif_piix, \
- .channels = 2, \
- .autodma = AUTODMA, \
- .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
- .bootable = ON_BOARD, \
- }
-
-/*
- * Table of the various PIIX capability blocks
- *
- */
-
-static ide_pci_device_t piix_pci_info[] __devinitdata = {
- /* 0 */ DECLARE_PIIX_DEV("PIIXa"),
- /* 1 */ DECLARE_PIIX_DEV("PIIXb"),
-
- { /* 2 */
- .name = "MPIIX",
- .init_hwif = init_hwif_piix,
- .channels = 2,
- .autodma = NODMA,
- .enablebits = {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},
- .bootable = ON_BOARD,
- },
-
- /* 3 */ DECLARE_PIIX_DEV("PIIX3"),
- /* 4 */ DECLARE_PIIX_DEV("PIIX4"),
- /* 5 */ DECLARE_PIIX_DEV("ICH0"),
- /* 6 */ DECLARE_PIIX_DEV("PIIX4"),
- /* 7 */ DECLARE_PIIX_DEV("ICH"),
- /* 8 */ DECLARE_PIIX_DEV("PIIX4"),
- /* 9 */ DECLARE_PIIX_DEV("PIIX4"),
- /* 10 */ DECLARE_PIIX_DEV("ICH2"),
- /* 11 */ DECLARE_PIIX_DEV("ICH2M"),
- /* 12 */ DECLARE_PIIX_DEV("ICH3M"),
- /* 13 */ DECLARE_PIIX_DEV("ICH3"),
- /* 14 */ DECLARE_PIIX_DEV("ICH4"),
- /* 15 */ DECLARE_PIIX_DEV("ICH5"),
- /* 16 */ DECLARE_PIIX_DEV("C-ICH"),
- /* 17 */ DECLARE_PIIX_DEV("ICH4"),
- /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA"),
- /* 19 */ DECLARE_PIIX_DEV("ICH5"),
- /* 20 */ DECLARE_PIIX_DEV("ICH6"),
- /* 21 */ DECLARE_PIIX_DEV("ICH7"),
- /* 22 */ DECLARE_PIIX_DEV("ICH4"),
-};
-
-#endif /* PIIX_H */
Index: linux-ide-export/drivers/ide/pci/serverworks.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/serverworks.c 2005-02-02 10:27:16.182154650 +0900
+++ linux-ide-export/drivers/ide/pci/serverworks.c 2005-02-02 10:28:02.677611135 +0900
@@ -39,7 +39,20 @@

#include <asm/io.h>

-#include "serverworks.h"
+#undef SVWKS_DEBUG_DRIVE_INFO
+
+#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
+#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
+
+/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
+ * can overrun their FIFOs when used with the CSB5 */
+static const char *svwks_bad_ata100[] = {
+ "ST320011A",
+ "ST340016A",
+ "ST360021A",
+ "ST380021A",
+ NULL
+};

static u8 svwks_revision = 0;
static struct pci_dev *isa_dev;
@@ -582,6 +595,48 @@ static int __init init_setup_csb6 (struc
return ide_setup_pci_device(dev, d);
}

+/*
+ * Table of the various serverworks capability blocks
+ */
+
+static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "SvrWks OSB4",
+ .init_setup = init_setup_svwks,
+ .init_chipset = init_chipset_svwks,
+ .init_hwif = init_hwif_svwks,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 1 */
+ .name = "SvrWks CSB5",
+ .init_setup = init_setup_svwks,
+ .init_chipset = init_chipset_svwks,
+ .init_hwif = init_hwif_svwks,
+ .init_dma = init_dma_svwks,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 2 */
+ .name = "SvrWks CSB6",
+ .init_setup = init_setup_csb6,
+ .init_chipset = init_chipset_svwks,
+ .init_hwif = init_hwif_svwks,
+ .init_dma = init_dma_svwks,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ },{ /* 3 */
+ .name = "SvrWks CSB6",
+ .init_setup = init_setup_csb6,
+ .init_chipset = init_chipset_svwks,
+ .init_hwif = init_hwif_svwks,
+ .init_dma = init_dma_svwks,
+ .channels = 1, /* 2 */
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ }
+};

/**
* svwks_init_one - called when a OSB/CSB is found
Index: linux-ide-export/drivers/ide/pci/serverworks.h
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/serverworks.h 2005-02-02 10:27:16.183154488 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,69 +0,0 @@
-
-#ifndef SERVERWORKS_H
-#define SERVERWORKS_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#undef SVWKS_DEBUG_DRIVE_INFO
-
-#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
-#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
-
-/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
- * can overrun their FIFOs when used with the CSB5 */
-static const char *svwks_bad_ata100[] = {
- "ST320011A",
- "ST340016A",
- "ST360021A",
- "ST380021A",
- NULL
-};
-
-static int init_setup_svwks(struct pci_dev *, ide_pci_device_t *);
-static int init_setup_csb6(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_svwks(struct pci_dev *, const char *);
-static void init_hwif_svwks(ide_hwif_t *);
-static void init_dma_svwks(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "SvrWks OSB4",
- .init_setup = init_setup_svwks,
- .init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 1 */
- .name = "SvrWks CSB5",
- .init_setup = init_setup_svwks,
- .init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
- .init_dma = init_dma_svwks,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 2 */
- .name = "SvrWks CSB6",
- .init_setup = init_setup_csb6,
- .init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
- .init_dma = init_dma_svwks,
- .channels = 2,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 3 */
- .name = "SvrWks CSB6",
- .init_setup = init_setup_csb6,
- .init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
- .init_dma = init_dma_svwks,
- .channels = 1, /* 2 */
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- }
-};
-
-#endif /* SERVERWORKS_H */

2005-02-02 03:02:45

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 8/29] ide: driver updates

> 08_ide_do_identify_model_string_termination.patch
>
> Terminates id->model string before invoking strstr() in
> do_identify().


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-probe.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-probe.c 2005-02-02 10:27:15.858207205 +0900
+++ linux-ide-export/drivers/ide/ide-probe.c 2005-02-02 10:28:03.719442099 +0900
@@ -165,11 +165,12 @@ static inline void do_identify (ide_driv
ide_fixstring(id->fw_rev, sizeof(id->fw_rev), bswap);
ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);

+ /* we depend on this a lot! */
+ id->model[sizeof(id->model)-1] = '\0';
+
if (strstr(id->model, "E X A B Y T E N E S T"))
goto err_misc;

- /* we depend on this a lot! */
- id->model[sizeof(id->model)-1] = '\0';
printk("%s: %s, ", drive->name, id->model);
drive->present = 1;
drive->dead = 0;

2005-02-02 03:06:38

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 16/29] ide: flagged_taskfile select register dev bit masking

> 16_ide_flagged_taskfile_select_dev_bit_masking.patch
>
> In flagged_taskfile(), make off DEV bit before OR'ing it with
> drive->select.all when writing to IDE_SELECT_REG.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.093219204 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.273190003 +0900
@@ -858,7 +858,8 @@ ide_startstop_t flagged_taskfile (ide_dr
* select bit (master/slave) in the drive_head register. We must make
* sure that the desired drive is selected.
*/
- hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
+ hwif->OUTB((taskfile->device_head & ~0x10) | drive->select.all,
+ IDE_SELECT_REG);
switch(task->data_phase) {

case TASKFILE_OUT_DMAQ:

2005-02-02 03:05:18

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 14/29] ide: remove NULL checking in ide_error()

> 14_ide_error_remove_NULL_test.patch
>
> In ide_error(), drive cannot be NULL. ide_dump_status() can't
> handle NULL drive.


Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:04.465321080 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:04.904249864 +0900
@@ -555,7 +555,7 @@ ide_startstop_t ide_error (ide_drive_t *

err = ide_dump_status(drive, msg, stat);

- if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+ if ((rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;

/* retry only "normal" I/O: */

2005-02-02 03:11:37

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 21/29] ide: Merge do_rw_taskfile() and flagged_taskfile().

> 21_ide_do_taskfile.patch
>
> Merged do_rw_taskfile() and flagged_taskfile() into
> do_taskfile(). During the merge, the following changes took
> place.
> 1. flagged taskfile now honors HOB feature register.
> (do_rw_taskfile() did write to HOB feature.)
> 2. No do_rw_taskfile() HIHI check on select register. Except
> for the DEV bit, all bits are honored.
> 3. Uses taskfile->data_phase to determine if dma trasfer is
> requested. (do_rw_taskfile() directly switched on
> taskfile->command for all dma commands)


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:04.080383536 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:06.272027942 +0900
@@ -535,7 +535,7 @@ static ide_startstop_t idedisk_special (
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
args.handler = &set_geometry_intr;
- do_rw_taskfile(drive, &args);
+ do_taskfile(drive, &args);
}
} else if (s->b.recalibrate) {
s->b.recalibrate = 0;
@@ -546,7 +546,7 @@ static ide_startstop_t idedisk_special (
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
args.handler = &recal_intr;
- do_rw_taskfile(drive, &args);
+ do_taskfile(drive, &args);
}
} else if (s->b.set_multmode) {
s->b.set_multmode = 0;
@@ -559,7 +559,7 @@ static ide_startstop_t idedisk_special (
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
args.handler = &set_multmode_intr;
- do_rw_taskfile(drive, &args);
+ do_taskfile(drive, &args);
}
} else if (s->all) {
int special = s->all;
@@ -905,19 +905,19 @@ static ide_startstop_t idedisk_start_pow
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = &task_no_data_intr;
- return do_rw_taskfile(drive, args);
+ return do_taskfile(drive, args);

case idedisk_pm_standby: /* Suspend step 2 (standby) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = &task_no_data_intr;
- return do_rw_taskfile(drive, args);
+ return do_taskfile(drive, args);

case idedisk_pm_idle: /* Resume step 1 (idle) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
args->handler = task_no_data_intr;
- return do_rw_taskfile(drive, args);
+ return do_taskfile(drive, args);

case idedisk_pm_restore_dma: /* Resume step 2 (restore DMA) */
/*
Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:04.904249864 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:06.273027780 +0900
@@ -756,9 +756,7 @@ static ide_startstop_t execute_drive_cmd
break;
}

- if (args->tf_out_flags.all != 0)
- return flagged_taskfile(drive, args);
- return do_rw_taskfile(drive, args);
+ return do_taskfile(drive, args);
} else if (rq->flags & REQ_DRIVE_TASK) {
u8 *args = rq->buffer;
u8 sel;
Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.035066389 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.273027780 +0900
@@ -96,35 +96,92 @@ int taskfile_lib_get_identify (ide_drive
return ide_raw_taskfile(drive, &args, buf);
}

-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t do_taskfile (ide_drive_t *drive, ide_task_t *task)
{
ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
- u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF;

- /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
+ if (task->data_phase == TASKFILE_MULTI_IN ||
+ task->data_phase == TASKFILE_MULTI_OUT) {
+ if (!drive->mult_count) {
+ printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+ return ide_stopped;
+ }
+ }
+
+ /*
+ * (ks) Check taskfile in/out flags.
+ * If set, then execute as it is defined.
+ * If not set, then define default settings.
+ * The default values are:
+ * write and read all taskfile registers (except data)
+ * write and read the hob registers (sector,nsector,lcyl,hcyl)
+ */
+ if (task->tf_out_flags.all == 0) {
+ task->tf_out_flags.h.taskfile = IDE_TASKFILE_STD_OUT_FLAGS;
+ if (drive->addressing == 1)
+ task->tf_out_flags.h.hob = IDE_HOB_STD_OUT_FLAGS;
+ }
+
+ if (task->tf_in_flags.all == 0) {
+ task->tf_in_flags.h.taskfile = IDE_TASKFILE_STD_IN_FLAGS;
+ if (drive->addressing == 1)
+ task->tf_in_flags.h.hob = IDE_HOB_STD_IN_FLAGS;
+ }
+
+ /* ALL Command Block Executions SHALL clear nIEN, unless
+ * otherwise specified.*/
if (IDE_CONTROL_REG) {
/* clear nIEN */
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
}
SELECT_MASK(drive, 0);

+ if (task->tf_out_flags.b.data) {
+ u16 data = taskfile->data + (hobfile->data << 8);
+ /* We want hobfile->data to go to the upper address,
+ so the cpu_to_le16(). - tj */
+ hwif->OUTW(cpu_to_le16(data), IDE_DATA_REG);
+ }
+
if (drive->addressing == 1) {
- hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
- hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
- hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
- hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
- hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
+ /* (ks) send hob registers first */
+ if (task->tf_out_flags.b.error_feature)
+ hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
+ if (task->tf_out_flags.b.nsector_hob)
+ hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
+ if (task->tf_out_flags.b.sector_hob)
+ hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
+ if (task->tf_out_flags.b.lcyl_hob)
+ hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
+ if (task->tf_out_flags.b.hcyl_hob)
+ hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
}

- hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
- hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
- hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
- hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
- hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
+ /* (ks) Send now the standard registers */
+ if (task->tf_out_flags.b.error_feature)
+ hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
+ if (task->tf_out_flags.b.nsector)
+ hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
+ if (task->tf_out_flags.b.sector)
+ hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
+ if (task->tf_out_flags.b.lcyl)
+ hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
+ if (task->tf_out_flags.b.hcyl)
+ hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);

- hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
+ /*
+ * (ks) In the taskfile approch, we will use all specified
+ * registers and the register value will not be changed, except
+ * the select bit (master/slave) in the drive_head register.
+ * We must make sure that the desired drive is selected.
+ */
+ if (task->tf_out_flags.b.select)
+ hwif->OUTB((taskfile->device_head & ~0x10) | drive->select.all,
+ IDE_SELECT_REG);
+ else
+ hwif->OUTB(drive->select.all, IDE_SELECT_REG);

if (task->handler != NULL) {
if (task->prehandler != NULL) {
@@ -136,32 +193,23 @@ ide_startstop_t do_rw_taskfile (ide_driv
return ide_started;
}

- if (!drive->using_dma)
+ switch (task->data_phase) {
+ case TASKFILE_OUT_DMAQ:
+ case TASKFILE_OUT_DMA:
+ case TASKFILE_IN_DMAQ:
+ case TASKFILE_IN_DMA:
+ if (!hwif->dma_setup(drive)) {
+ hwif->dma_exec_cmd(drive, taskfile->command);
+ hwif->dma_start(drive);
+ return ide_started;
+ }
+ return ide_stopped;
+ default:
return ide_stopped;
-
- switch (taskfile->command) {
- case WIN_WRITEDMA_ONCE:
- case WIN_WRITEDMA:
- case WIN_WRITEDMA_EXT:
- case WIN_READDMA_ONCE:
- case WIN_READDMA:
- case WIN_READDMA_EXT:
- case WIN_IDENTIFY_DMA:
- if (!hwif->dma_setup(drive)) {
- hwif->dma_exec_cmd(drive, taskfile->command);
- hwif->dma_start(drive);
- return ide_started;
- }
- break;
- default:
- if (task->handler == NULL)
- return ide_stopped;
}
-
- return ide_stopped;
}

-EXPORT_SYMBOL(do_rw_taskfile);
+EXPORT_SYMBOL(do_taskfile);

/*
* set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
@@ -757,131 +805,3 @@ int ide_task_ioctl (ide_drive_t *drive,
err = -EFAULT;
return err;
}
-
-/*
- * NOTICE: This is additions from IBM to provide a discrete interface,
- * for selective taskregister access operations. Nice JOB Klaus!!!
- * Glad to be able to work and co-develop this with you and IBM.
- */
-ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = HWIF(drive);
- task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
- hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
-#if DEBUG_TASKFILE
- u8 status;
-#endif
-
- if (task->data_phase == TASKFILE_MULTI_IN ||
- task->data_phase == TASKFILE_MULTI_OUT) {
- if (!drive->mult_count) {
- printk(KERN_ERR "%s: multimode not set!\n", drive->name);
- return ide_stopped;
- }
- }
-
- /*
- * (ks) Check taskfile in/out flags.
- * If set, then execute as it is defined.
- * If not set, then define default settings.
- * The default values are:
- * write and read all taskfile registers (except data)
- * write and read the hob registers (sector,nsector,lcyl,hcyl)
- */
- if (task->tf_out_flags.all == 0) {
- task->tf_out_flags.h.taskfile = IDE_TASKFILE_STD_OUT_FLAGS;
- if (drive->addressing == 1)
- task->tf_out_flags.h.hob = IDE_HOB_STD_OUT_FLAGS;
- }
-
- if (task->tf_in_flags.all == 0) {
- task->tf_in_flags.h.taskfile = IDE_TASKFILE_STD_IN_FLAGS;
- if (drive->addressing == 1)
- task->tf_in_flags.h.hob = IDE_HOB_STD_IN_FLAGS;
- }
-
- /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
- if (IDE_CONTROL_REG)
- /* clear nIEN */
- hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
- SELECT_MASK(drive, 0);
-
-#if DEBUG_TASKFILE
- status = hwif->INB(IDE_STATUS_REG);
- if (status & 0x80) {
- printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
- udelay(100);
- status = hwif->INB(IDE_STATUS_REG);
- printk("flagged_taskfile -> Status = %02x\n", status);
- }
-#endif
-
- if (task->tf_out_flags.b.data) {
- u16 data = taskfile->data + (hobfile->data << 8);
- /* We want hobfile->data to go to the upper address,
- so the cpu_to_le16(). - tj */
- hwif->OUTW(cpu_to_le16(data), IDE_DATA_REG);
- }
-
- /* (ks) send hob registers first */
- if (task->tf_out_flags.b.nsector_hob)
- hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
- if (task->tf_out_flags.b.sector_hob)
- hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
- if (task->tf_out_flags.b.lcyl_hob)
- hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
- if (task->tf_out_flags.b.hcyl_hob)
- hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
-
- /* (ks) Send now the standard registers */
- if (task->tf_out_flags.b.error_feature)
- hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
- /* refers to number of sectors to transfer */
- if (task->tf_out_flags.b.nsector)
- hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
- /* refers to sector offset or start sector */
- if (task->tf_out_flags.b.sector)
- hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
- if (task->tf_out_flags.b.lcyl)
- hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
- if (task->tf_out_flags.b.hcyl)
- hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
-
- /*
- * (ks) In the flagged taskfile approch, we will use all specified
- * registers and the register value will not be changed, except the
- * select bit (master/slave) in the drive_head register. We must make
- * sure that the desired drive is selected.
- */
- if (task->tf_out_flags.b.select)
- hwif->OUTB((taskfile->device_head & ~0x10) | drive->select.all,
- IDE_SELECT_REG);
- else
- hwif->OUTB(drive->select.all, IDE_SELECT_REG);
-
- switch(task->data_phase) {
-
- case TASKFILE_OUT_DMAQ:
- case TASKFILE_OUT_DMA:
- case TASKFILE_IN_DMAQ:
- case TASKFILE_IN_DMA:
- hwif->dma_setup(drive);
- hwif->dma_exec_cmd(drive, taskfile->command);
- hwif->dma_start(drive);
- break;
-
- default:
- if (task->handler == NULL)
- return ide_stopped;
-
- /* Issue the command */
- if (task->prehandler) {
- hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG);
- ndelay(400); /* FIXME */
- return task->prehandler(drive, task->rq);
- }
- ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
- }
-
- return ide_started;
-}
Index: linux-ide-export/include/linux/ide.h
===================================================================
--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.036066227 +0900
+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:06.274027617 +0900
@@ -1067,7 +1067,7 @@ static inline void destroy_proc_ide_inte
* - ide_started : In this case, the channel is left busy until an
* async event (interrupt) occurs.
* Typically, start_power_step() will issue a taskfile request with
- * do_rw_taskfile().
+ * do_taskfile().
*
* Upon reception of the interrupt, the core will call complete_power_step()
* with the error code if any. This routine should update the step value
@@ -1311,12 +1311,7 @@ extern int wait_for_ready(ide_drive_t *,
/*
* taskfile io for disks for now...and builds request from ide_ioctl
*/
-extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
-
-/*
- * Special Flagged Register Validation Caller
- */
-extern ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *);
+extern ide_startstop_t do_taskfile(ide_drive_t *, ide_task_t *);

extern void task_end_request(ide_drive_t *, struct request *, u8);
extern ide_startstop_t set_multmode_intr(ide_drive_t *);

2005-02-02 03:12:24

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 20/29] ide: task_end_request() fix

> 20_ide_task_end_request_fix.patch
>
> task_end_request() modified and made global. ide_dma_intr()
> modified to use task_end_request(). These changes enable
> TASKFILE ioctls to get valid register outputs on successful
> completion. No in-kernel usage should be affected.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-dma.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-dma.c 2005-02-02 10:28:05.642130143 +0900
+++ linux-ide-export/drivers/ide/ide-dma.c 2005-02-02 10:28:06.035066389 +0900
@@ -175,8 +175,7 @@ ide_startstop_t ide_dma_intr (ide_drive_
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
struct request *rq = HWGROUP(drive)->rq;
-
- DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
+ task_end_request(drive, rq, stat);
return ide_stopped;
}
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.851096238 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.035066389 +0900
@@ -366,18 +366,13 @@ static ide_startstop_t task_error(ide_dr
return ide_error(drive, s, stat);
}

-static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
+void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
{
if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *task = rq->special;
-
- if (task->tf_out_flags.all) {
- u8 err = drive->hwif->INB(IDE_ERROR_REG);
- ide_end_drive_cmd(drive, stat, err);
- return;
- }
- }
- drive->driver->end_request(drive, 1, rq->hard_nr_sectors);
+ u8 err = drive->hwif->INB(IDE_ERROR_REG);
+ ide_end_drive_cmd(drive, stat, err);
+ } else
+ drive->driver->end_request(drive, 1, rq->hard_nr_sectors);
}

/*
Index: linux-ide-export/include/linux/ide.h
===================================================================
--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:04.467320756 +0900
+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:06.036066227 +0900
@@ -1318,6 +1318,7 @@ extern ide_startstop_t do_rw_taskfile(id
*/
extern ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *);

+extern void task_end_request(ide_drive_t *, struct request *, u8);
extern ide_startstop_t set_multmode_intr(ide_drive_t *);
extern ide_startstop_t set_geometry_intr(ide_drive_t *);
extern ide_startstop_t recal_intr(ide_drive_t *);

2005-02-02 03:16:33

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 28/29] ide: ide_init_drive_cmd() now defaults to REQ_DRIVE_TASKFILE

> 28_ide_taskfile_init_drive_cmd.patch
>
> ide_init_drive_cmd() now initializes rq->flags to
> REQ_DRIVE_TASKFILE.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:07.204876587 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:07.852771465 +0900
@@ -750,7 +750,6 @@ static int set_multcount(ide_drive_t *dr
if (drive->special.b.set_multmode)
return -EBUSY;
ide_init_drive_cmd (&rq);
- rq.flags = REQ_DRIVE_TASKFILE;
drive->mult_req = arg;
drive->special.b.set_multmode = 1;
(void) ide_do_drive_cmd (drive, &rq, ide_wait);
Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:07.650804235 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:07.853771303 +0900
@@ -75,7 +75,7 @@ static struct request *ide_queue_flush_c
}

ide_init_drive_cmd(flush_rq);
- flush_rq->flags = REQ_DRIVE_TASKFILE | REQ_STARTED;
+ flush_rq->flags |= REQ_STARTED;
flush_rq->nr_sectors = rq->nr_sectors;
flush_rq->special = args;
HWGROUP(drive)->flush_real_rq = rq;
@@ -1401,7 +1401,7 @@ irqreturn_t ide_intr (int irq, void *dev
void ide_init_drive_cmd (struct request *rq)
{
memset(rq, 0, sizeof(*rq));
- rq->flags = REQ_DRIVE_CMD;
+ rq->flags = REQ_DRIVE_TASKFILE;
rq->ref_count = 1;
}

Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:07.407843655 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:07.854771141 +0900
@@ -515,7 +515,6 @@ static int ide_diag_taskfile(ide_drive_t
struct request rq;

ide_init_drive_cmd(&rq);
- rq.flags = REQ_DRIVE_TASKFILE;
rq.buffer = buf;

/*
@@ -716,7 +715,6 @@ int ide_cmd_ioctl (ide_drive_t *drive, u
if ((void *)arg == NULL) {
struct request rq;
ide_init_drive_cmd(&rq);
- rq.flags = REQ_DRIVE_TASKFILE;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}

Index: linux-ide-export/drivers/ide/ide.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide.c 2005-02-02 10:28:07.205876425 +0900
+++ linux-ide-export/drivers/ide/ide.c 2005-02-02 10:28:07.855770979 +0900
@@ -1255,7 +1255,6 @@ static int set_pio_mode (ide_drive_t *dr
if (drive->special.b.set_tune)
return -EBUSY;
ide_init_drive_cmd(&rq);
- rq.flags = REQ_DRIVE_TASKFILE;
drive->tune_req = (u8) arg;
drive->special.b.set_tune = 1;
(void) ide_do_drive_cmd(drive, &rq, ide_wait);

2005-02-02 03:21:32

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 25/29] ide: convert REQ_DRIVE_CMD to REQ_DRIVE_TASKFILE

> 25_ide_taskfile_cmd.patch
>
> All in-kernel REQ_DRIVE_CMD users except for ide_cmd_ioctl()
> converted to use REQ_DRIVE_TASKFILE.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:07.204876587 +0900
@@ -750,7 +750,7 @@ static int set_multcount(ide_drive_t *dr
if (drive->special.b.set_multmode)
return -EBUSY;
ide_init_drive_cmd (&rq);
- rq.flags = REQ_DRIVE_CMD;
+ rq.flags = REQ_DRIVE_TASKFILE;
drive->mult_req = arg;
drive->special.b.set_multmode = 1;
(void) ide_do_drive_cmd (drive, &rq, ide_wait);
Index: linux-ide-export/drivers/ide/ide.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide.c 2005-02-02 10:27:14.652402828 +0900
+++ linux-ide-export/drivers/ide/ide.c 2005-02-02 10:28:07.205876425 +0900
@@ -1255,6 +1255,7 @@ static int set_pio_mode (ide_drive_t *dr
if (drive->special.b.set_tune)
return -EBUSY;
ide_init_drive_cmd(&rq);
+ rq.flags = REQ_DRIVE_TASKFILE;
drive->tune_req = (u8) arg;
drive->special.b.set_tune = 1;
(void) ide_do_drive_cmd(drive, &rq, ide_wait);
@@ -1263,9 +1264,17 @@ static int set_pio_mode (ide_drive_t *dr

static int set_xfer_rate (ide_drive_t *drive, int arg)
{
- int err = ide_wait_cmd(drive,
- WIN_SETFEATURES, (u8) arg,
- SETFEATURES_XFER, 0, NULL);
+ ide_task_t args;
+ int err;
+
+ memset(&args, 0, sizeof(args));
+ args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES;
+ args.tfRegister[IDE_FEATURE_OFFSET] = SETFEATURES_XFER;
+ args.tfRegister[IDE_NSECTOR_OFFSET] = arg;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.handler = task_no_data_intr;
+
+ err = ide_raw_taskfile(drive, &args, NULL);

if (!err && arg) {
ide_set_xfer_rate(drive, (u8) arg);

2005-02-02 03:22:06

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 22/29] ide: convert REQ_DRIVE_TASK to REQ_DRIVE_TASKFILE

> 22_ide_taskfile_flush.patch
>
> All REQ_DRIVE_TASK users except ide_task_ioctl() converted
> to use REQ_DRIVE_TASKFILE.
> 1. idedisk_issue_flush() converted to use REQ_DRIVE_TASKFILE.
> This and the changes in ide_get_error_location() remove a
> possible race condition between ide_get_error_location()
> and other requests.
> 2. ide_queue_flush_cmd() converted to use REQ_DRIVE_TASKFILE.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.272027942 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
@@ -705,24 +705,26 @@ static int idedisk_issue_flush(request_q
{
ide_drive_t *drive = q->queuedata;
struct request *rq;
+ ide_task_t args;
int ret;

if (!drive->wcache)
return 0;

- rq = blk_get_request(q, WRITE, __GFP_WAIT);
-
- memset(rq->cmd, 0, sizeof(rq->cmd));
+ memset(&args, 0, sizeof(args));

if (ide_id_has_flush_cache_ext(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
- rq->cmd[0] = WIN_FLUSH_CACHE_EXT;
+ args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
else
- rq->cmd[0] = WIN_FLUSH_CACHE;
+ args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;

+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.handler = task_no_data_intr;

- rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER;
- rq->buffer = rq->cmd;
+ rq = blk_get_request(q, WRITE, __GFP_WAIT);
+ rq->flags |= REQ_DRIVE_TASKFILE | REQ_SOFTBARRIER;
+ rq->special = &args;

ret = blk_execute_rq(q, disk, rq);

@@ -730,8 +732,9 @@ static int idedisk_issue_flush(request_q
* if we failed and caller wants error offset, get it
*/
if (ret && error_sector)
- *error_sector = ide_get_error_location(drive, rq->cmd);
+ *error_sector = ide_get_error_location(drive, &args);

+ rq->special = NULL; /* just in case */
blk_put_request(rq);
return ret;
}
Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:06.273027780 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:06.528986250 +0900
@@ -55,24 +55,6 @@
#include <asm/io.h>
#include <asm/bitops.h>

-static void ide_fill_flush_cmd(ide_drive_t *drive, struct request *rq)
-{
- char *buf = rq->cmd;
-
- /*
- * reuse cdb space for ata command
- */
- memset(buf, 0, sizeof(rq->cmd));
-
- rq->flags |= REQ_DRIVE_TASK | REQ_STARTED;
- rq->buffer = buf;
- rq->buffer[0] = WIN_FLUSH_CACHE;
-
- if (ide_id_has_flush_cache_ext(drive->id) &&
- (drive->capacity64 >= (1UL << 28)))
- rq->buffer[0] = WIN_FLUSH_CACHE_EXT;
-}
-
/*
* preempt pending requests, and store this cache flush for immediate
* execution
@@ -80,7 +62,8 @@ static void ide_fill_flush_cmd(ide_drive
static struct request *ide_queue_flush_cmd(ide_drive_t *drive,
struct request *rq, int post)
{
- struct request *flush_rq = &HWGROUP(drive)->wrq;
+ struct request *flush_rq = &HWGROUP(drive)->flush_rq;
+ ide_task_t *args = &HWGROUP(drive)->flush_args;

/*
* write cache disabled, clear the barrier bit and treat it like
@@ -92,10 +75,22 @@ static struct request *ide_queue_flush_c
}

ide_init_drive_cmd(flush_rq);
- ide_fill_flush_cmd(drive, flush_rq);
-
- flush_rq->special = rq;
+ flush_rq->flags = REQ_DRIVE_TASKFILE | REQ_STARTED;
flush_rq->nr_sectors = rq->nr_sectors;
+ flush_rq->special = args;
+ HWGROUP(drive)->flush_real_rq = rq;
+
+ memset(args, 0, sizeof(*args));
+
+ if (ide_id_has_flush_cache_ext(drive->id) &&
+ (drive->capacity64 >= (1UL << 28)))
+ args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
+ else
+ args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
+
+ args->command_type = IDE_DRIVE_TASK_NO_DATA;
+ args->data_phase = TASKFILE_NO_DATA;
+ args->handler = task_no_data_intr;

if (!post) {
drive->doing_barrier = 1;
@@ -175,7 +170,7 @@ int ide_end_request (ide_drive_t *drive,
if (!blk_barrier_rq(rq) || !drive->wcache)
ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
else {
- struct request *flush_rq = &HWGROUP(drive)->wrq;
+ struct request *flush_rq = &HWGROUP(drive)->flush_rq;

flush_rq->nr_sectors -= nr_sectors;
if (!flush_rq->nr_sectors) {
@@ -221,41 +216,37 @@ static void ide_complete_pm_request (ide
/*
* FIXME: probably move this somewhere else, name is bad too :)
*/
-u64 ide_get_error_location(ide_drive_t *drive, char *args)
+u64 ide_get_error_location(ide_drive_t *drive, ide_task_t *args)
{
u32 high, low;
u8 hcyl, lcyl, sect;
- u64 sector;

- high = 0;
- hcyl = args[5];
- lcyl = args[4];
- sect = args[3];
-
- if (ide_id_has_flush_cache_ext(drive->id)) {
- low = (hcyl << 16) | (lcyl << 8) | sect;
- HWIF(drive)->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
- high = ide_read_24(drive);
- } else {
- u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
- if (cur & 0x40)
- low = (hcyl << 16) | (lcyl << 8) | sect;
- else {
- low = hcyl * drive->head * drive->sect;
- low += lcyl * drive->sect;
- low += sect - 1;
- }
- }
+ if (ide_id_has_flush_cache_ext(drive->id) &&
+ (drive->capacity64 >= (1UL << 28)))
+ high = (args->hobRegister[IDE_HCYL_OFFSET] << 16) |
+ (args->hobRegister[IDE_LCYL_OFFSET] << 8 ) |
+ args->hobRegister[IDE_SECTOR_OFFSET];
+ else
+ high = 0;
+
+ hcyl = args->tfRegister[IDE_HCYL_OFFSET];
+ lcyl = args->tfRegister[IDE_LCYL_OFFSET];
+ sect = args->tfRegister[IDE_SECTOR_OFFSET];
+
+ if (args->tfRegister[IDE_SELECT_OFFSET] & 0x40)
+ low = (hcyl << 16) | (lcyl << 8 ) | sect;
+ else
+ low = hcyl * drive->head * drive->sect +
+ lcyl * drive->sect + sect - 1;

- sector = ((u64) high << 24) | low;
- return sector;
+ return ((u64)high << 24) | low;
}
EXPORT_SYMBOL(ide_get_error_location);

static void ide_complete_barrier(ide_drive_t *drive, struct request *rq,
int error)
{
- struct request *real_rq = rq->special;
+ struct request *real_rq = HWGROUP(drive)->flush_real_rq;
int good_sectors, bad_sectors;
sector_t sector;

@@ -302,7 +293,7 @@ static void ide_complete_barrier(ide_dri
*/
good_sectors = 0;
if (blk_barrier_postflush(rq)) {
- sector = ide_get_error_location(drive, rq->buffer);
+ sector = ide_get_error_location(drive, rq->special);

if ((sector >= real_rq->hard_sector) &&
(sector < real_rq->hard_sector + real_rq->hard_nr_sectors))
Index: linux-ide-export/include/linux/ide.h
===================================================================
--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.274027617 +0900
+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:06.529986088 +0900
@@ -930,6 +930,39 @@ typedef ide_startstop_t (ide_pre_handler
typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
typedef int (ide_expiry_t)(ide_drive_t *);

+typedef struct ide_task_s {
+/*
+ * struct hd_drive_task_hdr tf;
+ * task_struct_t tf;
+ * struct hd_drive_hob_hdr hobf;
+ * hob_struct_t hobf;
+ */
+ task_ioreg_t tfRegister[8];
+ task_ioreg_t hobRegister[8];
+ ide_reg_valid_t tf_out_flags;
+ ide_reg_valid_t tf_in_flags;
+ int data_phase;
+ int command_type;
+ ide_pre_handler_t *prehandler;
+ ide_handler_t *handler;
+ struct request *rq; /* copy of request */
+ void *special; /* valid_t generally */
+} ide_task_t;
+
+typedef struct pkt_task_s {
+/*
+ * struct hd_drive_task_hdr pktf;
+ * task_struct_t pktf;
+ * u8 pkcdb[12];
+ */
+ task_ioreg_t tfRegister[8];
+ int data_phase;
+ int command_type;
+ ide_handler_t *handler;
+ struct request *rq; /* copy of request */
+ void *special;
+} pkt_task_t;
+
typedef struct hwgroup_s {
/* irq handler, if active */
ide_startstop_t (*handler)(ide_drive_t *);
@@ -955,8 +988,12 @@ typedef struct hwgroup_s {
struct request *rq;
/* failsafe timer */
struct timer_list timer;
- /* local copy of current write rq */
- struct request wrq;
+ /* rq used for flushing */
+ struct request flush_rq;
+ /* task used for flushing */
+ ide_task_t flush_args;
+ /* real_rq for flushing */
+ struct request *flush_real_rq;
/* timeout value during long polls */
unsigned long poll_timeout;
/* queried upon timeouts */
@@ -1203,7 +1240,7 @@ extern void ide_init_drive_cmd (struct r
/*
* this function returns error location sector offset in case of a write error
*/
-extern u64 ide_get_error_location(ide_drive_t *, char *);
+extern u64 ide_get_error_location(ide_drive_t *, ide_task_t *);

/*
* "action" parameter type for ide_do_drive_cmd() below.
@@ -1260,39 +1297,6 @@ extern void ide_end_drive_cmd(ide_drive_
*/
extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);

-typedef struct ide_task_s {
-/*
- * struct hd_drive_task_hdr tf;
- * task_struct_t tf;
- * struct hd_drive_hob_hdr hobf;
- * hob_struct_t hobf;
- */
- task_ioreg_t tfRegister[8];
- task_ioreg_t hobRegister[8];
- ide_reg_valid_t tf_out_flags;
- ide_reg_valid_t tf_in_flags;
- int data_phase;
- int command_type;
- ide_pre_handler_t *prehandler;
- ide_handler_t *handler;
- struct request *rq; /* copy of request */
- void *special; /* valid_t generally */
-} ide_task_t;
-
-typedef struct pkt_task_s {
-/*
- * struct hd_drive_task_hdr pktf;
- * task_struct_t pktf;
- * u8 pkcdb[12];
- */
- task_ioreg_t tfRegister[8];
- int data_phase;
- int command_type;
- ide_handler_t *handler;
- struct request *rq; /* copy of request */
- void *special;
-} pkt_task_t;
-
extern u32 ide_read_24(ide_drive_t *);

extern void SELECT_DRIVE(ide_drive_t *);

2005-02-02 03:25:18

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 23/29] ide: map ide_task_ioctl() to ide_taskfile_ioctl()

> 23_ide_taskfile_task_ioctl.patch
>
> ide_task_ioctl() modified to map to ide_taskfile_ioctl().
> This is the last user of REQ_DRIVE_TASK.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.273027780 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.751950074 +0900
@@ -778,30 +778,51 @@ abort:
return err;
}

-static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
-{
- struct request rq;
-
- ide_init_drive_cmd(&rq);
- rq.flags = REQ_DRIVE_TASK;
- rq.buffer = buf;
- return ide_do_drive_cmd(drive, &rq, ide_wait);
-}
-
-/*
- * FIXME : this needs to map into at taskfile. <[email protected]>
- */
int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
{
void __user *p = (void __user *)arg;
- int err = 0;
- u8 args[7], *argbuf = args;
- int argsize = 7;
+ u8 args[7];
+ ide_task_request_t task_req;
+ task_ioreg_t *io_ports;
+ mm_segment_t orig_fs;
+ int ret;

if (copy_from_user(args, p, 7))
return -EFAULT;
- err = ide_wait_cmd_task(drive, argbuf);
- if (copy_to_user(p, argbuf, argsize))
- err = -EFAULT;
- return err;
+
+ memset(&task_req, 0, sizeof(task_req));
+ task_req.out_flags.h.taskfile = IDE_TASKFILE_STD_OUT_FLAGS;
+ task_req.in_flags.h.taskfile = IDE_TASKFILE_STD_IN_FLAGS;
+
+ io_ports = task_req.io_ports;
+ io_ports[IDE_COMMAND_OFFSET] = args[0];
+ io_ports[IDE_FEATURE_OFFSET] = args[1];
+ io_ports[IDE_NSECTOR_OFFSET] = args[2];
+ io_ports[IDE_SECTOR_OFFSET] = args[3];
+ io_ports[IDE_LCYL_OFFSET] = args[4];
+ io_ports[IDE_HCYL_OFFSET] = args[5];
+ io_ports[IDE_SELECT_OFFSET] = args[6];
+
+ task_req.req_cmd = IDE_DRIVE_TASK_NO_DATA;
+ task_req.data_phase = TASKFILE_NO_DATA;
+
+ orig_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ ret = ide_taskfile_ioctl(drive, cmd, (unsigned long)&task_req);
+
+ set_fs(orig_fs);
+
+ args[0] = io_ports[IDE_COMMAND_OFFSET];
+ args[1] = io_ports[IDE_FEATURE_OFFSET];
+ args[2] = io_ports[IDE_NSECTOR_OFFSET];
+ args[3] = io_ports[IDE_SECTOR_OFFSET];
+ args[4] = io_ports[IDE_LCYL_OFFSET];
+ args[5] = io_ports[IDE_HCYL_OFFSET];
+ args[6] = io_ports[IDE_SELECT_OFFSET];
+
+ if (copy_to_user(p, args, 7))
+ ret = -EFAULT;
+
+ return ret;
}

2005-02-02 03:25:37

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 24/29] ide: remove REQ_DRIVE_TASK handling

> 24_ide_remove_task.patch
>
> Unused REQ_DRIVE_TASK handling removed.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:06.528986250 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:06.952917467 +0900
@@ -350,20 +350,6 @@ void ide_end_drive_cmd (ide_drive_t *dri
args[1] = err;
args[2] = hwif->INB(IDE_NSECTOR_REG);
}
- } else if (rq->flags & REQ_DRIVE_TASK) {
- u8 *args = (u8 *) rq->buffer;
- if (rq->errors == 0)
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
- if (args) {
- args[0] = stat;
- args[1] = err;
- args[2] = hwif->INB(IDE_NSECTOR_REG);
- args[3] = hwif->INB(IDE_SECTOR_REG);
- args[4] = hwif->INB(IDE_LCYL_REG);
- args[5] = hwif->INB(IDE_HCYL_REG);
- args[6] = hwif->INB(IDE_SELECT_REG);
- }
} else if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = (ide_task_t *) rq->special;
if (rq->errors == 0)
@@ -550,7 +536,7 @@ ide_startstop_t ide_error (ide_drive_t *
return ide_stopped;

/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
rq->errors = 1;
ide_end_drive_cmd(drive, stat, err);
return ide_stopped;
@@ -592,7 +578,7 @@ ide_startstop_t ide_abort(ide_drive_t *d
return ide_stopped;

/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
rq->errors = 1;
ide_end_drive_cmd(drive, BUSY_STAT, 0);
return ide_stopped;
@@ -748,33 +734,7 @@ static ide_startstop_t execute_drive_cmd
}

return do_taskfile(drive, args);
- } else if (rq->flags & REQ_DRIVE_TASK) {
- u8 *args = rq->buffer;
- u8 sel;
-
- if (!args)
- goto done;
-#ifdef DEBUG
- printk("%s: DRIVE_TASK_CMD ", drive->name);
- printk("cmd=0x%02x ", args[0]);
- printk("fr=0x%02x ", args[1]);
- printk("ns=0x%02x ", args[2]);
- printk("sc=0x%02x ", args[3]);
- printk("lcyl=0x%02x ", args[4]);
- printk("hcyl=0x%02x ", args[5]);
- printk("sel=0x%02x\n", args[6]);
-#endif
- hwif->OUTB(args[1], IDE_FEATURE_REG);
- hwif->OUTB(args[3], IDE_SECTOR_REG);
- hwif->OUTB(args[4], IDE_LCYL_REG);
- hwif->OUTB(args[5], IDE_HCYL_REG);
- sel = (args[6] & ~0x10);
- if (drive->select.b.unit)
- sel |= 0x10;
- hwif->OUTB(sel, IDE_SELECT_REG);
- ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
- return ide_started;
- } else if (rq->flags & REQ_DRIVE_CMD) {
+ } else if (rq->flags & REQ_DRIVE_CMD) {
u8 *args = rq->buffer;

if (!args)
@@ -885,7 +845,7 @@ static ide_startstop_t start_request (id
return startstop;
}
if (!drive->special.all) {
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK))
+ if (rq->flags & REQ_DRIVE_CMD)
return execute_drive_cmd(drive, rq);
else if (rq->flags & REQ_DRIVE_TASKFILE)
return execute_drive_cmd(drive, rq);
Index: linux-ide-export/drivers/ide/ide-lib.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-lib.c 2005-02-02 10:27:14.733389689 +0900
+++ linux-ide-export/drivers/ide/ide-lib.c 2005-02-02 10:28:06.953917305 +0900
@@ -458,7 +458,7 @@ static void ide_dump_opcode(ide_drive_t
spin_unlock(&ide_lock);
if (!rq)
return;
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+ if (rq->flags & REQ_DRIVE_CMD) {
char *args = rq->buffer;
if (args) {
opcode = args[0];
Index: linux-ide-export/include/linux/blkdev.h
===================================================================
--- linux-ide-export.orig/include/linux/blkdev.h 2005-02-02 10:27:14.733389689 +0900
+++ linux-ide-export/include/linux/blkdev.h 2005-02-02 10:28:06.954917143 +0900
@@ -202,7 +202,7 @@ enum rq_flag_bits {
__REQ_QUIET, /* don't worry about errors */
__REQ_SPECIAL, /* driver suplied command */
__REQ_DRIVE_CMD,
- __REQ_DRIVE_TASK,
+ __REQ_DRIVE_TASK, /* obsolete, unused anymore - tj */
__REQ_DRIVE_TASKFILE,
__REQ_PREEMPT, /* set for "ide_preempt" requests */
__REQ_PM_SUSPEND, /* suspend request */

2005-02-02 03:30:09

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 26/29] ide: map ide_cmd_ioctl() to ide_taskfile_ioctl()

> 26_ide_taskfile_cmd_ioctl.patch
>
> ide_cmd_ioctl() converted to use ide_taskfile_ioctl(). This
> is the last user of REQ_DRIVE_CMD.


Index: linux-ide-export/drivers/ide/ide-iops.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-iops.c 2005-02-02 10:28:04.466320918 +0900
+++ linux-ide-export/drivers/ide/ide-iops.c 2005-02-02 10:28:07.406843817 +0900
@@ -648,11 +648,11 @@ u8 eighty_ninty_three (ide_drive_t *driv

EXPORT_SYMBOL(eighty_ninty_three);

-int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
+int ide_ata66_check (ide_drive_t *drive, task_ioreg_t *regs)
{
- if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
- (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
- (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
+ if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
+ (regs[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
+ (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
#ifndef CONFIG_IDEDMA_IVB
if ((drive->id->hw_config & 0x6000) == 0) {
#else /* !CONFIG_IDEDMA_IVB */
@@ -678,11 +678,11 @@ int ide_ata66_check (ide_drive_t *drive,
* 1 : Safe to update drive->id DMA registers.
* 0 : OOPs not allowed.
*/
-int set_transfer (ide_drive_t *drive, ide_task_t *args)
+int set_transfer (ide_drive_t *drive, task_ioreg_t *regs)
{
- if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
- (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
- (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
+ if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
+ (regs[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
+ (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
(drive->id->dma_ultra ||
drive->id->dma_mword ||
drive->id->dma_1word))
Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.751950074 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:07.407843655 +0900
@@ -704,78 +704,90 @@ abort:
return err;
}

-int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
-{
- struct request rq;
- u8 buffer[4];
-
- if (!buf)
- buf = buffer;
- memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
- ide_init_drive_cmd(&rq);
- rq.buffer = buf;
- *buf++ = cmd;
- *buf++ = nsect;
- *buf++ = feature;
- *buf++ = sectors;
- return ide_do_drive_cmd(drive, &rq, ide_wait);
-}
-
-/*
- * FIXME : this needs to map into at taskfile. <[email protected]>
- */
int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
{
- int err = 0;
- u8 args[4], *argbuf = args;
+ u8 args[4];
+ ide_task_request_t *task_req;
+ task_ioreg_t *io_ports;
u8 xfer_rate = 0;
- int argsize = 4;
- ide_task_t tfargs;
+ mm_segment_t orig_fs;
+ int in_size, ret;

- if (NULL == (void *) arg) {
+ if ((void *)arg == NULL) {
struct request rq;
ide_init_drive_cmd(&rq);
+ rq.flags = REQ_DRIVE_TASKFILE;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}

if (copy_from_user(args, (void __user *)arg, 4))
return -EFAULT;

- memset(&tfargs, 0, sizeof(ide_task_t));
- tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
- tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
- tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1];
- tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00;
- tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00;
- tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00;
- tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
-
- if (args[3]) {
- argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
- argbuf = kmalloc(argsize, GFP_KERNEL);
- if (argbuf == NULL)
- return -ENOMEM;
- memcpy(argbuf, args, 4);
+ in_size = 4 * SECTOR_WORDS * args[3];
+
+ task_req = kmalloc(sizeof(*task_req) + in_size, GFP_KERNEL);
+ if (task_req == NULL)
+ return -ENOMEM;
+
+ memset(task_req, 0, sizeof(*task_req) + in_size);
+
+ task_req->out_flags.b.status_command = 1;
+ task_req->out_flags.b.sector = 1;
+ task_req->out_flags.b.error_feature = 1;
+ task_req->out_flags.b.nsector = 1;
+
+ task_req->in_flags.b.status_command = 1;
+ task_req->in_flags.b.error_feature = 1;
+ task_req->in_flags.b.nsector = 1;
+
+ io_ports = task_req->io_ports;
+ io_ports[IDE_COMMAND_OFFSET] = args[0];
+ io_ports[IDE_SECTOR_OFFSET] = args[1];
+ io_ports[IDE_FEATURE_OFFSET] = args[2];
+ io_ports[IDE_NSECTOR_OFFSET] = args[3];
+
+ if (in_size) {
+ task_req->req_cmd = IDE_DRIVE_TASK_IN;
+ task_req->data_phase = TASKFILE_IN;
+ task_req->in_size = in_size;
+ } else {
+ task_req->req_cmd = IDE_DRIVE_TASK_NO_DATA;
+ task_req->data_phase = TASKFILE_NO_DATA;
}
- if (set_transfer(drive, &tfargs)) {
+
+ if (set_transfer(drive, io_ports)) {
xfer_rate = args[1];
- if (ide_ata66_check(drive, &tfargs))
+ if (ide_ata66_check(drive, io_ports)) {
+ ret = -EIO;
goto abort;
+ }
}

- err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
+ orig_fs = get_fs();
+ set_fs(KERNEL_DS);

- if (!err && xfer_rate) {
+ ret = ide_taskfile_ioctl(drive, cmd, (unsigned long)task_req);
+
+ set_fs(orig_fs);
+
+ if (!ret && xfer_rate) {
/* active-retuning-calls future */
ide_set_xfer_rate(drive, xfer_rate);
ide_driveid_update(drive);
}
+
+ args[0] = io_ports[IDE_STATUS_OFFSET];
+ args[1] = io_ports[IDE_ERROR_OFFSET];
+ args[2] = io_ports[IDE_NSECTOR_OFFSET];
+ args[3] = 0;
+
+ if (copy_to_user((void __user *)arg, args, 4) ||
+ copy_to_user((void __user *)arg + 4,
+ (void *)task_req + sizeof(*task_req), in_size))
+ ret = -EFAULT;
abort:
- if (copy_to_user((void __user *)arg, argbuf, argsize))
- err = -EFAULT;
- if (argsize > 4)
- kfree(argbuf);
- return err;
+ kfree(task_req);
+ return ret;
}

int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
Index: linux-ide-export/include/linux/ide.h
===================================================================
--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.529986088 +0900
+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:07.408843493 +0900
@@ -1289,14 +1289,6 @@ extern int ide_do_drive_cmd(ide_drive_t
*/
extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);

-/*
- * Issue ATA command and wait for completion.
- * Use for implementing commands in kernel
- *
- * (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
- */
-extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
-
extern u32 ide_read_24(ide_drive_t *);

extern void SELECT_DRIVE(ide_drive_t *);
@@ -1334,10 +1326,10 @@ int ide_task_ioctl(ide_drive_t *, unsign
extern int system_bus_clock(void);

extern int ide_driveid_update(ide_drive_t *);
-extern int ide_ata66_check(ide_drive_t *, ide_task_t *);
+extern int ide_ata66_check(ide_drive_t *, task_ioreg_t *);
extern int ide_config_drive_speed(ide_drive_t *, u8);
extern u8 eighty_ninty_three (ide_drive_t *);
-extern int set_transfer(ide_drive_t *, ide_task_t *);
+extern int set_transfer(ide_drive_t *, task_ioreg_t *);
extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);

extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);

2005-02-02 03:34:24

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 08/29] ide: do_identify() string termination fix

Sorry, this is the same 08 patch with the correct subject line.

> 08_ide_do_identify_model_string_termination.patch
>
> Terminates id->model string before invoking strstr() in
> do_identify().


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-probe.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-probe.c 2005-02-02 10:27:15.858207205 +0900
+++ linux-ide-export/drivers/ide/ide-probe.c 2005-02-02 10:28:03.719442099 +0900
@@ -165,11 +165,12 @@ static inline void do_identify (ide_driv
ide_fixstring(id->fw_rev, sizeof(id->fw_rev), bswap);
ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);

+ /* we depend on this a lot! */
+ id->model[sizeof(id->model)-1] = '\0';
+
if (strstr(id->model, "E X A B Y T E N E S T"))
goto err_misc;

- /* we depend on this a lot! */
- id->model[sizeof(id->model)-1] = '\0';
printk("%s: %s, ", drive->name, id->model);
drive->present = 1;
drive->dead = 0;

2005-02-02 03:33:51

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 27/29] ide: remove REQ_DRIVE_CMD handling

> 27_ide_remove_cmd.patch
>
> Removed unused REQ_DRIVE_CMD handling.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:06.952917467 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:07.650804235 +0900
@@ -340,17 +340,7 @@ void ide_end_drive_cmd (ide_drive_t *dri
rq = HWGROUP(drive)->rq;
spin_unlock_irqrestore(&ide_lock, flags);

- if (rq->flags & REQ_DRIVE_CMD) {
- u8 *args = (u8 *) rq->buffer;
- if (rq->errors == 0)
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
- if (args) {
- args[0] = stat;
- args[1] = err;
- args[2] = hwif->INB(IDE_NSECTOR_REG);
- }
- } else if (rq->flags & REQ_DRIVE_TASKFILE) {
+ if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = (ide_task_t *) rq->special;
if (rq->errors == 0)
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
@@ -536,7 +526,7 @@ ide_startstop_t ide_error (ide_drive_t *
return ide_stopped;

/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
+ if (rq->flags & REQ_DRIVE_TASKFILE) {
rq->errors = 1;
ide_end_drive_cmd(drive, stat, err);
return ide_stopped;
@@ -578,7 +568,7 @@ ide_startstop_t ide_abort(ide_drive_t *d
return ide_stopped;

/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
+ if (rq->flags & REQ_DRIVE_TASKFILE) {
rq->errors = 1;
ide_end_drive_cmd(drive, BUSY_STAT, 0);
return ide_stopped;
@@ -588,63 +578,6 @@ ide_startstop_t ide_abort(ide_drive_t *d
}

/**
- * ide_cmd - issue a simple drive command
- * @drive: drive the command is for
- * @cmd: command byte
- * @nsect: sector byte
- * @handler: handler for the command completion
- *
- * Issue a simple drive command with interrupts.
- * The drive must be selected beforehand.
- */
-
-static void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect,
- ide_handler_t *handler)
-{
- ide_hwif_t *hwif = HWIF(drive);
- if (IDE_CONTROL_REG)
- hwif->OUTB(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
- SELECT_MASK(drive,0);
- hwif->OUTB(nsect,IDE_NSECTOR_REG);
- ide_execute_command(drive, cmd, handler, WAIT_CMD, NULL);
-}
-
-/**
- * drive_cmd_intr - drive command completion interrupt
- * @drive: drive the completion interrupt occurred on
- *
- * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- * We do any necessary daya reading and then wait for the drive to
- * go non busy. At that point we may read the error data and complete
- * the request
- */
-
-static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
- ide_hwif_t *hwif = HWIF(drive);
- u8 *args = (u8 *) rq->buffer;
- u8 stat = hwif->INB(IDE_STATUS_REG);
- int retries = 10;
-
- local_irq_enable();
- if ((stat & DRQ_STAT) && args && args[3]) {
- u8 io_32bit = drive->io_32bit;
- drive->io_32bit = 0;
- hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
- drive->io_32bit = io_32bit;
- while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
- udelay(100);
- }
-
- if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL)
- return ide_error(drive, "drive_cmd", stat);
- /* calls ide_end_drive_cmd */
- ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
- return ide_stopped;
-}
-
-/**
* do_special - issue some special commands
* @drive: drive the command is for
*
@@ -699,78 +632,50 @@ void ide_init_sg_cmd(ide_drive_t *drive,
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);

/**
- * execute_drive_command - issue special drive command
+ * execute_drive_taskfile - issue special drive command
* @drive: the drive to issue th command on
* @rq: the request structure holding the command
*
- * execute_drive_cmd() issues a special drive command, usually
- * initiated by ioctl() from the external hdparm program. The
- * command can be a drive command, drive task or taskfile
- * operation. Weirdly you can call it with NULL to wait for
- * all commands to finish. Don't do this as that is due to change
+ * execute_drive_taskfile() issues a special drive command,
+ * usually initiated by ioctl() from the external hdparm program.
+ * Weirdly you can call it with NULL to wait for all commands to
+ * finish. Don't do this as that is due to change
*/

-static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
- struct request *rq)
+static ide_startstop_t execute_drive_taskfile (ide_drive_t *drive,
+ struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
- if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *args = rq->special;
-
- if (!args)
- goto done;
-
- hwif->data_phase = args->data_phase;
-
- switch (hwif->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- default:
- break;
- }
+ ide_task_t *args = rq->special;

- return do_taskfile(drive, args);
- } else if (rq->flags & REQ_DRIVE_CMD) {
- u8 *args = rq->buffer;
-
- if (!args)
- goto done;
-#ifdef DEBUG
- printk("%s: DRIVE_CMD ", drive->name);
- printk("cmd=0x%02x ", args[0]);
- printk("sc=0x%02x ", args[1]);
- printk("fr=0x%02x ", args[2]);
- printk("xx=0x%02x\n", args[3]);
-#endif
- if (args[0] == WIN_SMART) {
- hwif->OUTB(0x4f, IDE_LCYL_REG);
- hwif->OUTB(0xc2, IDE_HCYL_REG);
- hwif->OUTB(args[2],IDE_FEATURE_REG);
- hwif->OUTB(args[1],IDE_SECTOR_REG);
- ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
- return ide_started;
- }
- hwif->OUTB(args[2],IDE_FEATURE_REG);
- ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
- return ide_started;
- }
-
-done:
- /*
- * NULL is actually a valid way of waiting for
- * all current requests to be flushed from the queue.
- */
+ if (!args) {
+ /*
+ * NULL is actually a valid way of waiting for
+ * all current requests to be flushed from the queue.
+ */
#ifdef DEBUG
- printk("%s: DRIVE_CMD (null)\n", drive->name);
+ printk("%s: DRIVE_TASKFILE (null)\n", drive->name);
#endif
- ide_end_drive_cmd(drive,
- hwif->INB(IDE_STATUS_REG),
- hwif->INB(IDE_ERROR_REG));
- return ide_stopped;
+ ide_end_drive_cmd(drive,
+ hwif->INB(IDE_STATUS_REG),
+ hwif->INB(IDE_ERROR_REG));
+ return ide_stopped;
+ }
+
+ hwif->data_phase = args->data_phase;
+
+ switch (hwif->data_phase) {
+ case TASKFILE_MULTI_OUT:
+ case TASKFILE_OUT:
+ case TASKFILE_MULTI_IN:
+ case TASKFILE_IN:
+ ide_init_sg_cmd(drive, rq);
+ ide_map_sg(drive, rq);
+ default:
+ break;
+ }
+
+ return do_taskfile(drive, args);
}

/**
@@ -845,10 +750,8 @@ static ide_startstop_t start_request (id
return startstop;
}
if (!drive->special.all) {
- if (rq->flags & REQ_DRIVE_CMD)
- return execute_drive_cmd(drive, rq);
- else if (rq->flags & REQ_DRIVE_TASKFILE)
- return execute_drive_cmd(drive, rq);
+ if (rq->flags & REQ_DRIVE_TASKFILE)
+ return execute_drive_taskfile(drive, rq);
else if (blk_pm_request(rq)) {
#ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n",
Index: linux-ide-export/include/linux/blkdev.h
===================================================================
--- linux-ide-export.orig/include/linux/blkdev.h 2005-02-02 10:28:06.954917143 +0900
+++ linux-ide-export/include/linux/blkdev.h 2005-02-02 10:28:07.651804072 +0900
@@ -201,7 +201,7 @@ enum rq_flag_bits {
__REQ_FAILED, /* set if the request failed */
__REQ_QUIET, /* don't worry about errors */
__REQ_SPECIAL, /* driver suplied command */
- __REQ_DRIVE_CMD,
+ __REQ_DRIVE_CMD, /* obsolete, unused anymore - tj */
__REQ_DRIVE_TASK, /* obsolete, unused anymore - tj */
__REQ_DRIVE_TASKFILE,
__REQ_PREEMPT, /* set for "ide_preempt" requests */

2005-02-02 03:06:39

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 15/29] ide: flagged_taskfile() data byte order fix

> 15_ide_flagged_taskfile_data_byte_order_fix.patch
>
> In flagged_taskfile(), when writing data register,
> taskfile->data goes to the lower byte and hobfile->data goes
> to the upper byte on little endian machines and the opposite
> happens on big endian machines. This patch make
> taskfile->data always go to the lower byte regardless of
> endianess.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:03.518474705 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.093219204 +0900
@@ -823,7 +823,9 @@ ide_startstop_t flagged_taskfile (ide_dr

if (task->tf_out_flags.b.data) {
u16 data = taskfile->data + (hobfile->data << 8);
- hwif->OUTW(data, IDE_DATA_REG);
+ /* We want hobfile->data to go to the upper address,
+ so the cpu_to_le16(). - tj */
+ hwif->OUTW(cpu_to_le16(data), IDE_DATA_REG);
}

/* (ks) send hob registers first */

2005-02-02 03:12:25

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 17/29] ide: flagged_taskfile() tf_out_flags.b.select check

> 17_ide_flagged_taskfile_select_check.patch
>
> In flagged_taskfile(), tf_out_flags.b.select should be checked
> before using bits inside taskfile->device_head. When user
> haven't specified the select register, the default
> drive->select.all value should be used.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.273190003 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.463159181 +0900
@@ -858,8 +858,12 @@ ide_startstop_t flagged_taskfile (ide_dr
* select bit (master/slave) in the drive_head register. We must make
* sure that the desired drive is selected.
*/
- hwif->OUTB((taskfile->device_head & ~0x10) | drive->select.all,
- IDE_SELECT_REG);
+ if (task->tf_out_flags.b.select)
+ hwif->OUTB((taskfile->device_head & ~0x10) | drive->select.all,
+ IDE_SELECT_REG);
+ else
+ hwif->OUTB(drive->select.all, IDE_SELECT_REG);
+
switch(task->data_phase) {

case TASKFILE_OUT_DMAQ:

2005-02-02 03:42:33

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 29/29] ide: make data_phase explicit in NO_DATA cases

> 29_ide_explicit_TASKFILE_NO_DATA.patch
>
> Make data_phase explicit in NO_DATA cases.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:07.852771465 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:08.121727827 +0900
@@ -300,6 +300,7 @@ static unsigned long idedisk_read_native
args.tfRegister[IDE_SELECT_OFFSET] = 0x40;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
@@ -326,6 +327,7 @@ static unsigned long long idedisk_read_n
args.tfRegister[IDE_SELECT_OFFSET] = 0x40;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX_EXT;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
@@ -362,6 +364,7 @@ static unsigned long idedisk_set_max_add
args.tfRegister[IDE_SELECT_OFFSET] = ((addr_req >> 24) & 0x0f) | 0x40;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SET_MAX;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
@@ -395,6 +398,7 @@ static unsigned long long idedisk_set_ma
args.hobRegister[IDE_SELECT_OFFSET] = 0x40;
args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80);
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
@@ -534,6 +538,7 @@ static ide_startstop_t idedisk_special (
args.tfRegister[IDE_SELECT_OFFSET] = ((drive->head-1)|drive->select.all)&0xBF;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &set_geometry_intr;
do_taskfile(drive, &args);
}
@@ -545,6 +550,7 @@ static ide_startstop_t idedisk_special (
args.tfRegister[IDE_NSECTOR_OFFSET] = drive->sect;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &recal_intr;
do_taskfile(drive, &args);
}
@@ -558,6 +564,7 @@ static ide_startstop_t idedisk_special (
args.tfRegister[IDE_NSECTOR_OFFSET] = drive->mult_req;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &set_multmode_intr;
do_taskfile(drive, &args);
}
@@ -597,6 +604,7 @@ static int smart_enable(ide_drive_t *dri
args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
return ide_raw_taskfile(drive, &args, NULL);
}
@@ -720,6 +728,7 @@ static int idedisk_issue_flush(request_q
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;

args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = task_no_data_intr;

rq = blk_get_request(q, WRITE, __GFP_WAIT);
@@ -779,6 +788,7 @@ static int write_cache(ide_drive_t *driv
SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;

err = ide_raw_taskfile(drive, &args, NULL);
@@ -799,6 +809,7 @@ static int do_idedisk_flushcache (ide_dr
else
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
return ide_raw_taskfile(drive, &args, NULL);
}
@@ -813,6 +824,7 @@ static int set_acoustic (ide_drive_t *dr
args.tfRegister[IDE_NSECTOR_OFFSET] = arg;
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
ide_raw_taskfile(drive, &args, NULL);
drive->acoustic = arg;
@@ -906,19 +918,22 @@ static ide_startstop_t idedisk_start_pow
else
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
+ args->data_phase = TASKFILE_NO_DATA;
args->handler = &task_no_data_intr;
return do_taskfile(drive, args);

case idedisk_pm_standby: /* Suspend step 2 (standby) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
+ args->data_phase = TASKFILE_NO_DATA;
args->handler = &task_no_data_intr;
return do_taskfile(drive, args);

case idedisk_pm_idle: /* Resume step 1 (idle) */
args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
- args->handler = task_no_data_intr;
+ args->data_phase = TASKFILE_NO_DATA;
+ args->handler = task_no_data_intr;
return do_taskfile(drive, args);

case idedisk_pm_restore_dma: /* Resume step 2 (restore DMA) */
@@ -1195,6 +1210,7 @@ static int idedisk_open(struct inode *in
memset(&args, 0, sizeof(ide_task_t));
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
check_disk_change(inode->i_bdev);
/*
@@ -1218,6 +1234,7 @@ static int idedisk_release(struct inode
memset(&args, 0, sizeof(ide_task_t));
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0;
Index: linux-ide-export/drivers/ide/ide.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide.c 2005-02-02 10:28:07.855770979 +0900
+++ linux-ide-export/drivers/ide/ide.c 2005-02-02 10:28:08.122727665 +0900
@@ -1271,6 +1271,7 @@ static int set_xfer_rate (ide_drive_t *d
args.tfRegister[IDE_FEATURE_OFFSET] = SETFEATURES_XFER;
args.tfRegister[IDE_NSECTOR_OFFSET] = arg;
args.command_type = IDE_DRIVE_TASK_NO_DATA;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = task_no_data_intr;

err = ide_raw_taskfile(drive, &args, NULL);

2005-02-02 03:46:52

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 13/29] ide: use time_after() macro

> 13_ide_tape_time_after.patch
>
> Explicit jiffy comparision converted to time_after() macro.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-tape.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-tape.c 2005-02-02 10:27:15.513263167 +0900
+++ linux-ide-export/drivers/ide/ide-tape.c 2005-02-02 10:28:04.720279713 +0900
@@ -2439,7 +2439,7 @@ static ide_startstop_t idetape_do_reques
tape->dsc_polling_start = jiffies;
tape->dsc_polling_frequency = tape->best_dsc_rw_frequency;
tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
- } else if ((signed long) (jiffies - tape->dsc_timeout) > 0) {
+ } else if (time_after(jiffies, tape->dsc_timeout)) {
printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
tape->name);
if (rq->cmd[0] & REQ_IDETAPE_PC2) {

2005-02-02 03:50:45

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 12/29] ide: add ide_hwgroup_t.polling

> 12_ide_hwgroup_t_polling.patch
>
> ide_hwgroup_t.polling field added. 0 in poll_timeout field
> used to indicate inactive polling but because 0 is a valid
> jiffy value, though slim, there's a chance that something
> weird can happen.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:04.260354336 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:04.465321080 +0900
@@ -1314,7 +1314,7 @@ void ide_timer_expiry (unsigned long dat
/* local CPU only,
* as if we were handling an interrupt */
local_irq_disable();
- if (hwgroup->poll_timeout != 0) {
+ if (hwgroup->polling) {
startstop = handler(drive);
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
@@ -1442,8 +1442,7 @@ irqreturn_t ide_intr (int irq, void *dev
return IRQ_NONE;
}

- if ((handler = hwgroup->handler) == NULL ||
- hwgroup->poll_timeout != 0) {
+ if ((handler = hwgroup->handler) == NULL || hwgroup->polling) {
/*
* Not expecting an interrupt from this drive.
* That means this could be:
Index: linux-ide-export/drivers/ide/ide-iops.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-iops.c 2005-02-02 10:27:15.612247109 +0900
+++ linux-ide-export/drivers/ide/ide-iops.c 2005-02-02 10:28:04.466320918 +0900
@@ -1028,14 +1028,14 @@ static ide_startstop_t atapi_reset_pollf
return ide_started;
}
/* end of polling */
- hwgroup->poll_timeout = 0;
+ hwgroup->polling = 0;
printk("%s: ATAPI reset timed-out, status=0x%02x\n",
drive->name, stat);
/* do it the old fashioned way */
return do_reset1(drive, 1);
}
/* done polling */
- hwgroup->poll_timeout = 0;
+ hwgroup->polling = 0;
return ide_stopped;
}

@@ -1095,7 +1095,7 @@ static ide_startstop_t reset_pollfunc (i
printk("\n");
}
}
- hwgroup->poll_timeout = 0; /* done polling */
+ hwgroup->polling = 0; /* done polling */
return ide_stopped;
}

@@ -1170,6 +1170,7 @@ static ide_startstop_t do_reset1 (ide_dr
udelay (20);
hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwgroup->polling = 1;
__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
spin_unlock_irqrestore(&ide_lock, flags);
return ide_started;
@@ -1210,6 +1211,7 @@ static ide_startstop_t do_reset1 (ide_dr
/* more than enough time */
udelay(10);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwgroup->polling = 1;
__ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);

/*
Index: linux-ide-export/drivers/ide/pci/siimage.c
===================================================================
--- linux-ide-export.orig/drivers/ide/pci/siimage.c 2005-02-02 10:27:15.612247109 +0900
+++ linux-ide-export/drivers/ide/pci/siimage.c 2005-02-02 10:28:04.466320918 +0900
@@ -590,7 +590,7 @@ static int siimage_reset_poll (ide_drive
if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {
printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
hwif->name, hwif->INL(SATA_STATUS_REG));
- HWGROUP(drive)->poll_timeout = 0;
+ HWGROUP(drive)->polling = 0;
return ide_started;
}
return 0;
Index: linux-ide-export/include/linux/ide.h
===================================================================
--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:04.261354174 +0900
+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:04.467320756 +0900
@@ -938,7 +938,9 @@ typedef struct hwgroup_s {
/* BOOL: protects all fields below */
volatile int busy;
/* BOOL: wake us up on timer expiry */
- int sleeping;
+ int sleeping : 1;
+ /* BOOL: polling active & poll_timeout field valid */
+ int polling : 1;
/* current drive */
ide_drive_t *drive;
/* ptr to current hwif in linked-list */

2005-02-02 03:55:56

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

> 11_ide_drive_sleeping_fix.patch
>
> ide_drive_t.sleeping field added. 0 in sleep field used to
> indicate inactive sleeping but because 0 is a valid jiffy
> value, though slim, there's a chance that something can go
> weird. And while at it, explicit jiffy comparisons are
> converted to use time_{after|before} macros.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-io.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:03.340503581 +0900
+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:04.260354336 +0900
@@ -933,6 +933,7 @@ void ide_stall_queue (ide_drive_t *drive
if (timeout > WAIT_WORSTCASE)
timeout = WAIT_WORSTCASE;
drive->sleep = timeout + jiffies;
+ drive->sleeping = 1;
}

EXPORT_SYMBOL(ide_stall_queue);
@@ -972,18 +973,18 @@ repeat:
}

do {
- if ((!drive->sleep || time_after_eq(jiffies, drive->sleep))
+ if ((!drive->sleeping || time_after_eq(jiffies, drive->sleep))
&& !elv_queue_empty(drive->queue)) {
if (!best
- || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
- || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
+ || (drive->sleeping && (!best->sleeping || time_before(drive->sleep, best->sleep)))
+ || (!best->sleeping && time_before(WAKEUP(drive), WAKEUP(best))))
{
if (!blk_queue_plugged(drive->queue))
best = drive;
}
}
} while ((drive = drive->next) != hwgroup->drive);
- if (best && best->nice1 && !best->sleep && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
+ if (best && best->nice1 && !best->sleeping && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
long t = (signed long)(WAKEUP(best) - jiffies);
if (t >= WAIT_MIN_SLEEP) {
/*
@@ -992,10 +993,9 @@ repeat:
*/
drive = best->next;
do {
- if (!drive->sleep
- /* FIXME: use time_before */
- && 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time))
- && 0 < (signed long)((jiffies + t) - WAKEUP(drive)))
+ if (!drive->sleeping
+ && time_before(jiffies - best->service_time, WAKEUP(drive))
+ && time_before(WAKEUP(drive), jiffies + t))
{
ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));
goto repeat;
@@ -1058,14 +1058,17 @@ static void ide_do_request (ide_hwgroup_
hwgroup->busy = 1;
drive = choose_drive(hwgroup);
if (drive == NULL) {
- unsigned long sleep = 0;
+ int sleeping = 0;
+ unsigned long sleep = 0; /* shut up, gcc */
hwgroup->rq = NULL;
drive = hwgroup->drive;
do {
- if (drive->sleep && (!sleep || 0 < (signed long)(sleep - drive->sleep)))
+ if (drive->sleeping && (!sleeping || time_before(drive->sleep, sleep))) {
+ sleeping = 1;
sleep = drive->sleep;
+ }
} while ((drive = drive->next) != hwgroup->drive);
- if (sleep) {
+ if (sleeping) {
/*
* Take a short snooze, and then wake up this hwgroup again.
* This gives other hwgroups on the same a chance to
@@ -1105,7 +1108,7 @@ static void ide_do_request (ide_hwgroup_
}
hwgroup->hwif = hwif;
hwgroup->drive = drive;
- drive->sleep = 0;
+ drive->sleeping = 0;
drive->service_start = jiffies;

if (blk_queue_plugged(drive->queue)) {
Index: linux-ide-export/include/linux/ide.h
===================================================================
--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:27:15.687234943 +0900
+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:04.261354174 +0900
@@ -721,6 +721,7 @@ typedef struct ide_drive_s {
* 3=64-bit
*/
unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */
+ unsigned sleeping : 1; /* 1=sleeping & sleep field valid */

u8 quirk_list; /* considered quirky, set for a specific host */
u8 init_speed; /* transfer rate set at boot */

2005-02-02 03:59:51

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 19/29] ide: ide_diag_taskfile() rq initialization fix

> 19_ide_diag_taskfile_use_init_drive_cmd.patch
>
> In ide_diag_taskfile(), when initializing taskfile rq,
> ref_count wasn't initialized properly. Modified to use
> ide_init_drive_cmd(). This doesn't really change any behavior
> as the request isn't managed via the block layer.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.642130143 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.851096238 +0900
@@ -471,7 +471,7 @@ static int ide_diag_taskfile(ide_drive_t
{
struct request rq;

- memset(&rq, 0, sizeof(rq));
+ ide_init_drive_cmd(&rq);
rq.flags = REQ_DRIVE_TASKFILE;
rq.buffer = buf;

2005-02-02 04:00:33

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 10/29] ide: __ide_do_rw_disk() return value fix

> 10_ide_do_rw_disk_pre_task_out_intr_return_fix.patch
>
> In __ide_do_rw_disk(), ide_started used to be returned blindly
> after issusing PIO write. This can cause hang if
> pre_task_out_intr() returns ide_stopped due to failed
> ide_wait_stat() test. Fixed to pass the return value of
> pre_task_out_intr().


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:03.898413061 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:04.080383536 +0900
@@ -253,8 +253,7 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
/* FIXME: ->OUTBSYNC ? */
hwif->OUTB(command, IDE_COMMAND_REG);

- pre_task_out_intr(drive, rq);
- return ide_started;
+ return pre_task_out_intr(drive, rq);
}
}
EXPORT_SYMBOL_GPL(__ide_do_rw_disk);

2005-02-02 04:00:34

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 07/29] ide: ide_reg_valid_t endian fix

> 07_ide_reg_valid_t_endian_fix.patch
>
> ide_reg_valid_t contains bitfield flags but doesn't reverse
> bit orders using __*_ENDIAN_BITFIELD macros. And constants
> for ide_reg_valid_t, IDE_{TASKFILE|HOB}_STD_{IN|OUT}_FLAGS,
> are defined as byte values which are correct only on
> little-endian machines. This patch defines reversed constants
> and .h byte union structure to make things correct on big
> endian machines. The only code which uses above macros is in
> flagged_taskfile() and the code is currently unused, so this
> patch doesn't change any behavior. (The code will get used in
> later patches.)


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:27:15.930195526 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:03.518474705 +0900
@@ -794,15 +794,15 @@ ide_startstop_t flagged_taskfile (ide_dr
* write and read the hob registers (sector,nsector,lcyl,hcyl)
*/
if (task->tf_out_flags.all == 0) {
- task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
+ task->tf_out_flags.h.taskfile = IDE_TASKFILE_STD_OUT_FLAGS;
if (drive->addressing == 1)
- task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
+ task->tf_out_flags.h.hob = IDE_HOB_STD_OUT_FLAGS;
}

if (task->tf_in_flags.all == 0) {
- task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
+ task->tf_in_flags.h.taskfile = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->addressing == 1)
- task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
+ task->tf_in_flags.h.hob = IDE_HOB_STD_IN_FLAGS;
}

/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
Index: linux-ide-export/include/linux/hdreg.h
===================================================================
--- linux-ide-export.orig/include/linux/hdreg.h 2005-02-02 10:27:15.931195364 +0900
+++ linux-ide-export/include/linux/hdreg.h 2005-02-02 10:28:03.519474543 +0900
@@ -1,6 +1,8 @@
#ifndef _LINUX_HDREG_H
#define _LINUX_HDREG_H

+#include <asm/byteorder.h>
+
#ifdef __KERNEL__
#include <linux/ata.h>

@@ -79,11 +81,26 @@

/*
* Define standard taskfile in/out register
+ *
+ * ide_reg_valid_t should have been defined conditionally using
+ * __*_ENDIAN_BITFIELD macros. But ide_reg_valid_t and the following
+ * macros are already out in the wild. Defining reversed constants on
+ * big endian machines and adding .h.{taskfile|hob} to ide_reg_valid_t
+ * seem to be the least disrupting solution. - tj
*/
+#if defined(__LITTLE_ENDIAN_BITFIELD)
#define IDE_TASKFILE_STD_OUT_FLAGS 0xFE
#define IDE_TASKFILE_STD_IN_FLAGS 0xFE
#define IDE_HOB_STD_OUT_FLAGS 0x3C
#define IDE_HOB_STD_IN_FLAGS 0x3C
+#elif defined(__BIG_ENDIAN_BITFIELD)
+#define IDE_TASKFILE_STD_OUT_FLAGS 0x7F
+#define IDE_TASKFILE_STD_IN_FLAGS 0x7F
+#define IDE_HOB_STD_OUT_FLAGS 0x3C
+#define IDE_HOB_STD_IN_FLAGS 0x3C
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif

typedef unsigned char task_ioreg_t;
typedef unsigned long sata_ioreg_t;
@@ -91,6 +108,10 @@ typedef unsigned long sata_ioreg_t;
typedef union ide_reg_valid_s {
unsigned all : 16;
struct {
+ unsigned taskfile : 8;
+ unsigned hob : 8;
+ } h;
+ struct {
unsigned data : 1;
unsigned error_feature : 1;
unsigned sector : 1;

2005-02-02 04:00:32

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 09/29] ide: __ide_do_rw_disk() lba48 dma check fix

> 09_ide_do_rw_disk_lba48_dma_check_fix.patch
>
> In __ide_do_rw_disk(), the shifted block, instead of the
> original rq->sector, should be used when checking range for
> lba48 dma.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-disk.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:27:15.819213531 +0900
+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:03.898413061 +0900
@@ -132,7 +132,7 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
nsectors.all = (u16) rq->nr_sectors;

if (hwif->no_lba48_dma && lba48 && dma) {
- if (rq->sector + rq->nr_sectors > 1ULL << 28)
+ if (block + rq->nr_sectors > 1ULL << 28)
dma = 0;
}

2005-02-02 04:09:36

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 18/29] ide: comment fixes

> 18_ide_comment_fixes.patch
>
> Comment fixes.


Signed-off-by: Tejun Heo <[email protected]>


Index: linux-ide-export/drivers/ide/ide-dma.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-dma.c 2005-02-02 10:27:15.202313614 +0900
+++ linux-ide-export/drivers/ide/ide-dma.c 2005-02-02 10:28:05.642130143 +0900
@@ -227,7 +227,9 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
* the PRD table that the IDE layer wants to be fed. The code
* knows about the 64K wrap bug in the CS5530.
*
- * Returns 0 if all went okay, returns 1 otherwise.
+ * Returns the number of built PRD entries if all went okay,
+ * returns 0 otherwise.
+ *
* May also be invoked from trm290.c
*/

Index: linux-ide-export/drivers/ide/ide-taskfile.c
===================================================================
--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.463159181 +0900
+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:05.642130143 +0900
@@ -853,8 +853,8 @@ ide_startstop_t flagged_taskfile (ide_dr
hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);

/*
- * (ks) In the flagged taskfile approch, we will used all specified
- * registers and the register value will not be changed. Except the
+ * (ks) In the flagged taskfile approch, we will use all specified
+ * registers and the register value will not be changed, except the
* select bit (master/slave) in the drive_head register. We must make
* sure that the desired drive is selected.
*/

2005-02-02 08:33:17

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 0/29] ide: driver updates

Tejun Heo wrote:
> Hello, B. Zolnierkiewicz.
>
> These patches are various fixes/improvements to the ide driver. They
> are against the 2.6 bk tree as of today (20050202).
>
> 01_ide_remove_adma100.patch
>
> Removes drivers/ide/pci/adma100.[hc]. The driver isn't
> compilable (missing functions) and no Kconfig actually enables
> CONFIG_BLK_DEV_ADMA100.

Also, the libata-dev-2.6 tree has an "ata_adma" driver which is
complete, but needs some testing (and I have h/w).

> 05_ide_merge_pci_driver_hc.patch
>
> Merges drivers/ide/pci/*.h files into their corresponding *.c
> files. Rationales are
> 1. There's no reason to separate pci drivers into header and
> body. No header file is shared and they're simple enough.
> 2. struct pde_pci_device_t *_chipsets[] are _defined_ in the
> header files. That isn't the custom and there's no good
> reason to do differently in these drivers.
> 3. Tracking changelogs shows that the bugs fixed by 00 and 01
> are introduced during mass-updating ide pci drivers by
> forgetting to update *.h files.

Personally, I agree. However, I would ask Alan for his rationale before
applying this...


> 07_ide_reg_valid_t_endian_fix.patch
>
> ide_reg_valid_t contains bitfield flags but doesn't reverse
> bit orders using __*_ENDIAN_BITFIELD macros. And constants
> for ide_reg_valid_t, IDE_{TASKFILE|HOB}_STD_{IN|OUT}_FLAGS,
> are defined as byte values which are correct only on
> little-endian machines. This patch defines reversed constants
> and .h byte union structure to make things correct on big
> endian machines. The only code which uses above macros is in
> flagged_taskfile() and the code is currently unused, so this
> patch doesn't change any behavior. (The code will get used in
> later patches.)

doesn't this "fix" change behavior on existing big endian machines?


> 15_ide_flagged_taskfile_data_byte_order_fix.patch
>
> In flagged_taskfile(), when writing data register,
> taskfile->data goes to the lower byte and hobfile->data goes
> to the upper byte on little endian machines and the opposite
> happens on big endian machines. This patch make
> taskfile->data always go to the lower byte regardless of
> endianess.

ditto


> 16_ide_flagged_taskfile_select_dev_bit_masking.patch
>
> In flagged_taskfile(), make off DEV bit before OR'ing it with
> drive->select.all when writing to IDE_SELECT_REG.

Probably the right thing to do, but be very very careful you have
audited all uses...


> 21_ide_do_taskfile.patch
>
> Merged do_rw_taskfile() and flagged_taskfile() into
> do_taskfile(). During the merge, the following changes took
> place.
> 1. flagged taskfile now honors HOB feature register.
> (do_rw_taskfile() did write to HOB feature.)
> 2. No do_rw_taskfile() HIHI check on select register. Except
> for the DEV bit, all bits are honored.
> 3. Uses taskfile->data_phase to determine if dma trasfer is
> requested. (do_rw_taskfile() directly switched on
> taskfile->command for all dma commands)

I think Bart already had plans for this (similar to your patch)?


> 22_ide_taskfile_flush.patch
>
> All REQ_DRIVE_TASK users except ide_task_ioctl() converted
> to use REQ_DRIVE_TASKFILE.

Rationale?


> 24_ide_remove_task.patch
>
> Unused REQ_DRIVE_TASK handling removed.

this series is nice.


> 25_ide_taskfile_cmd.patch
>
> All in-kernel REQ_DRIVE_CMD users except for ide_cmd_ioctl()
> converted to use REQ_DRIVE_TASKFILE.
> 26_ide_taskfile_cmd_ioctl.patch
>
> ide_cmd_ioctl() converted to use ide_taskfile_ioctl(). This
> is the last user of REQ_DRIVE_CMD.

ditto


> 27_ide_remove_cmd.patch
>
> Removed unused REQ_DRIVE_CMD handling.
>
> 28_ide_taskfile_init_drive_cmd.patch
>
> ide_init_drive_cmd() now initializes rq->flags to
> REQ_DRIVE_TASKFILE.
>
> 29_ide_explicit_TASKFILE_NO_DATA.patch
>
> Make data_phase explicit in NO_DATA cases.

I would make sure this series gets some amount of testing in -mm before
pushing upstream, though...

Jeff


Subject: Re: [PATCH 2.6.11-rc2 01/29] ide: remove adma100

On Wed, 2 Feb 2005 11:43:53 +0900, Tejun Heo <[email protected]> wrote:
> > 01_ide_remove_adma100.patch
> >
> > Removes drivers/ide/pci/adma100.[hc]. The driver isn't
> > compilable (missing functions) and no Kconfig actually enables
> > CONFIG_BLK_DEV_ADMA100.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 02/29] ide: cleanup it8172

On Wed, 2 Feb 2005 11:44:54 +0900, Tejun Heo <[email protected]> wrote:
> > 02_ide_cleanup_it8172.patch
> >
> > In drivers/ide/pci/it8172.h, it8172_ratefilter() and
> > init_setup_it8172() are declared and the latter is referenced
> > in it8172_chipsets. Both functions are not defined or used
> > anywhere. This patch removes the prototypes and reference.
> > it8172 should be compilable now.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied, also this trivial patch is needed to fix it8172 build:

diff -Nru a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
--- a/drivers/ide/pci/it8172.c 2005-02-03 01:00:22 +01:00
+++ b/drivers/ide/pci/it8172.c 2005-02-03 01:00:22 +01:00
@@ -56,7 +56,7 @@
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- int is_slave = (hwif->drives[1] == drive);
+ int is_slave = (&hwif->drives[1] == drive);
unsigned long flags;
u16 drive_enables;
u32 drive_timing;
@@ -94,7 +94,7 @@
}

pci_write_config_word(dev, 0x40, drive_enables);
- spin_unlock_irqrestore(&ide_lock, flags)
+ spin_unlock_irqrestore(&ide_lock, flags);
}

static u8 it8172_dma_2_pio (u8 xfer_rate)

Subject: Re: [PATCH 2.6.11-rc2 03/29] ide: cleanup opti621

On Wed, 2 Feb 2005 11:45:38 +0900, Tejun Heo <[email protected]> wrote:
> > 03_ide_cleanup_opti621.patch
> >
> > In drivers/ide/pci/opti612.[hc], init_setup_opt621() is
> > declared, defined and referenced but never actullay used.
> > Thie patch removes the function.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 06/29] ide: IDE_CONTROL_REG cleanup

On Wed, 2 Feb 2005 11:48:30 +0900, Tejun Heo <[email protected]> wrote:
> > 06_ide_start_request_IDE_CONTROL_REG.patch
> >
> > Replaced HWIF(drive)->io_ports[IDE_CONTROL_OFFSET] with
> > equivalent IDE_CONTROL_REG in ide-io.c.
>
> Signed-off-by: Tejun Heo <[email protected]>
>
> Index: linux-ide-export/drivers/ide/ide-io.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:27:15.996184821 +0900
> +++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:03.340503581 +0900
> @@ -884,7 +884,7 @@ static ide_startstop_t start_request (id
> if (rc)
> printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
> SELECT_DRIVE(drive);
> - HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
> + HWIF(drive)->OUTB(8, IDE_CONTROL_REG);
> rc = ide_wait_not_busy(HWIF(drive), 10000);
> if (rc)
> printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);

IDE_CONTROL_REG macro and co. are obfuscations and should die...

Subject: Re: [PATCH 2.6.11-rc2 10/29] ide: __ide_do_rw_disk() return value fix

On Wed, 2 Feb 2005 11:52:48 +0900, Tejun Heo <[email protected]> wrote:
> > 10_ide_do_rw_disk_pre_task_out_intr_return_fix.patch
> >
> > In __ide_do_rw_disk(), ide_started used to be returned blindly
> > after issusing PIO write. This can cause hang if
> > pre_task_out_intr() returns ide_stopped due to failed
> > ide_wait_stat() test. Fixed to pass the return value of
> > pre_task_out_intr().
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 12/29] ide: add ide_hwgroup_t.polling

On Wed, 2 Feb 2005 11:55:38 +0900, Tejun Heo <[email protected]> wrote:
> > 12_ide_hwgroup_t_polling.patch
> >
> > ide_hwgroup_t.polling field added. 0 in poll_timeout field
> > used to indicate inactive polling but because 0 is a valid
> > jiffy value, though slim, there's a chance that something
> > weird can happen.

Is there really a possibility of something weird?

I'm not claiming that I like this way of coding but poll_timeout
is assigned either to '0' or to 'jiffies + WAIT_WORSTCASE'.

Bartlomiej

Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> > 11_ide_drive_sleeping_fix.patch
> >
> > ide_drive_t.sleeping field added. 0 in sleep field used to
> > indicate inactive sleeping but because 0 is a valid jiffy
> > value, though slim, there's a chance that something can go
> > weird. And while at it, explicit jiffy comparisons are
> > converted to use time_{after|before} macros.

Same question as for "add ide_hwgroup_t.polling" patch.
AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)

Subject: Re: [PATCH 2.6.11-rc2 09/29] ide: __ide_do_rw_disk() lba48 dma check fix

On Wed, 2 Feb 2005 11:51:42 +0900, Tejun Heo <[email protected]> wrote:
> > 09_ide_do_rw_disk_lba48_dma_check_fix.patch
> >
> > In __ide_do_rw_disk(), the shifted block, instead of the
> > original rq->sector, should be used when checking range for
> > lba48 dma.
>
> Signed-off-by: Tejun Heo <[email protected]>

good catch! applied

Subject: Re: [PATCH 2.6.11-rc2 13/29] ide: use time_after() macro

On Wed, 2 Feb 2005 11:56:49 +0900, Tejun Heo <[email protected]> wrote:
> > 13_ide_tape_time_after.patch
> >
> > Explicit jiffy comparision converted to time_after() macro.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 14/29] ide: remove NULL checking in ide_error()

On Wed, 2 Feb 2005 11:57:28 +0900, Tejun Heo <[email protected]> wrote:
> > 14_ide_error_remove_NULL_test.patch
> >
> > In ide_error(), drive cannot be NULL. ide_dump_status() can't
> > handle NULL drive.

applied, you missed Signed-off-by line

Subject: Re: [PATCH 2.6.11-rc2 18/29] ide: comment fixes

On Wed, 2 Feb 2005 12:02:54 +0900, Tejun Heo <[email protected]> wrote:
> > 18_ide_comment_fixes.patch
> >
> > Comment fixes.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 0/29] ide: driver updates

On Wed, 2 Feb 2005 11:40:17 +0900, Tejun Heo <[email protected]> wrote:
> Hello, B. Zolnierkiewicz.

Hi,

> These patches are various fixes/improvements to the ide driver. They
> are against the 2.6 bk tree as of today (20050202).

Nice series. As you probably already know I merged most
of the easy stuff. I will comment on the real stuff soon.

Thanks,
Bartlomiej

Subject: Re: [PATCH 2.6.11-rc2 04/29] ide: cleanup piix

On Wed, 2 Feb 2005 11:46:11 +0900, Tejun Heo <[email protected]> wrote:
> > 04_ide_cleanup_piix.patch
> >
> > In drivers/ide/pci/piix.[hc], init_setup_piix() is defined and
> > used but only one init_setup function is defined and no
> > demultiplexing is done using init_setup callback. As other
> > drivers call ide_setup_pci_device() directly in such cases,
> > this patch removes init_setup_piix() and makes piix_init_one()
> > call ide_setup_pci_device() directly.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

2005-02-03 11:23:42

by Alan

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 0/29] ide: driver updates

On Mer, 2005-02-02 at 08:31, Jeff Garzik wrote:
> > Merges drivers/ide/pci/*.h files into their corresponding *.c
> > files. Rationales are
> > 1. There's no reason to separate pci drivers into header and
> > body. No header file is shared and they're simple enough.
> > 2. struct pde_pci_device_t *_chipsets[] are _defined_ in the
> > header files. That isn't the custom and there's no good
> > reason to do differently in these drivers.
> > 3. Tracking changelogs shows that the bugs fixed by 00 and 01
> > are introduced during mass-updating ide pci drivers by
> > forgetting to update *.h files.
>
> Personally, I agree. However, I would ask Alan for his rationale before
> applying this...

Historically they were split so they stayed split. SCSI has mostly (c/o
hch) switched away from that and it seems sensible for IDE to do so.

>
> > 07_ide_reg_valid_t_endian_fix.patch
> >
> > ide_reg_valid_t contains bitfield flags but doesn't reverse
> > bit orders using __*_ENDIAN_BITFIELD macros. And constants
> > for ide_reg_valid_t, IDE_{TASKFILE|HOB}_STD_{IN|OUT}_FLAGS,
> > are defined as byte values which are correct only on
> > little-endian machines. This patch defines reversed constants
> > and .h byte union structure to make things correct on big
> > endian machines. The only code which uses above macros is in
> > flagged_taskfile() and the code is currently unused, so this
> > patch doesn't change any behavior. (The code will get used in
> > later patches.)
>
> doesn't this "fix" change behavior on existing big endian machines?

My question too, remember that there is I/O byte order swizzling afoot
in
the I/O macros.



Generally looks good IMHO.

2005-02-03 11:38:52

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> > > 11_ide_drive_sleeping_fix.patch
> > >
> > > ide_drive_t.sleeping field added. 0 in sleep field used to
> > > indicate inactive sleeping but because 0 is a valid jiffy
> > > value, though slim, there's a chance that something can go
> > > weird. And while at it, explicit jiffy comparisons are
> > > converted to use time_{after|before} macros.
>
> Same question as for "add ide_hwgroup_t.polling" patch.
> AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)

Hmm, what if jiffies + timeout == 0?

--
Jens Axboe

Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Thu, 3 Feb 2005 12:37:10 +0100, Jens Axboe <[email protected]> wrote:
> On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> > On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> > > > 11_ide_drive_sleeping_fix.patch
> > > >
> > > > ide_drive_t.sleeping field added. 0 in sleep field used to
> > > > indicate inactive sleeping but because 0 is a valid jiffy
> > > > value, though slim, there's a chance that something can go
> > > > weird. And while at it, explicit jiffy comparisons are
> > > > converted to use time_{after|before} macros.
> >
> > Same question as for "add ide_hwgroup_t.polling" patch.
> > AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)
>
> Hmm, what if jiffies + timeout == 0?

Hm, jiffies is unsigned and timeout is always > 0
but this is still possible if jiffies + timeout wraps, right?

2005-02-03 13:33:06

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> On Thu, 3 Feb 2005 12:37:10 +0100, Jens Axboe <[email protected]> wrote:
> > On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> > > On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> > > > > 11_ide_drive_sleeping_fix.patch
> > > > >
> > > > > ide_drive_t.sleeping field added. 0 in sleep field used to
> > > > > indicate inactive sleeping but because 0 is a valid jiffy
> > > > > value, though slim, there's a chance that something can go
> > > > > weird. And while at it, explicit jiffy comparisons are
> > > > > converted to use time_{after|before} macros.
> > >
> > > Same question as for "add ide_hwgroup_t.polling" patch.
> > > AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)
> >
> > Hmm, what if jiffies + timeout == 0?
>
> Hm, jiffies is unsigned and timeout is always > 0
> but this is still possible if jiffies + timeout wraps, right?

Precisely, if jiffies is exactly 'timeout' away from wrapping to 0 it
could happen. So I think the fix looks sane.

--
Jens Axboe

Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Thu, 3 Feb 2005 14:32:29 +0100, Jens Axboe <[email protected]> wrote:
> On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> > On Thu, 3 Feb 2005 12:37:10 +0100, Jens Axboe <[email protected]> wrote:
> > > On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> > > > On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> > > > > > 11_ide_drive_sleeping_fix.patch
> > > > > >
> > > > > > ide_drive_t.sleeping field added. 0 in sleep field used to
> > > > > > indicate inactive sleeping but because 0 is a valid jiffy
> > > > > > value, though slim, there's a chance that something can go
> > > > > > weird. And while at it, explicit jiffy comparisons are
> > > > > > converted to use time_{after|before} macros.
> > > >
> > > > Same question as for "add ide_hwgroup_t.polling" patch.
> > > > AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)
> > >
> > > Hmm, what if jiffies + timeout == 0?
> >
> > Hm, jiffies is unsigned and timeout is always > 0
> > but this is still possible if jiffies + timeout wraps, right?
>
> Precisely, if jiffies is exactly 'timeout' away from wrapping to 0 it
> could happen. So I think the fix looks sane.

agreed

Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> > 11_ide_drive_sleeping_fix.patch
> >
> > ide_drive_t.sleeping field added. 0 in sleep field used to
> > indicate inactive sleeping but because 0 is a valid jiffy
> > value, though slim, there's a chance that something can go
> > weird. And while at it, explicit jiffy comparisons are
> > converted to use time_{after|before} macros.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 12/29] ide: add ide_hwgroup_t.polling

On Wed, 2 Feb 2005 11:55:38 +0900, Tejun Heo <[email protected]> wrote:
> > 12_ide_hwgroup_t_polling.patch
> >
> > ide_hwgroup_t.polling field added. 0 in poll_timeout field
> > used to indicate inactive polling but because 0 is a valid
> > jiffy value, though slim, there's a chance that something
> > weird can happen.
>
> Signed-off-by: Tejun Heo <[email protected]>

applied

Subject: Re: [PATCH 2.6.11-rc2 23/29] ide: map ide_task_ioctl() to ide_taskfile_ioctl()

On Wed, 2 Feb 2005 12:08:13 +0900, Tejun Heo <[email protected]> wrote:
> > 23_ide_taskfile_task_ioctl.patch
> >
> > ide_task_ioctl() modified to map to ide_taskfile_ioctl().
> > This is the last user of REQ_DRIVE_TASK.

ide_task_ioctl() should map to taskfile transport not ide_taskfile_ioctl()

> Signed-off-by: Tejun Heo <[email protected]>
>
> Index: linux-ide-export/drivers/ide/ide-taskfile.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.273027780 +0900
> +++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.751950074 +0900
> @@ -778,30 +778,51 @@ abort:
> return err;
> }
>
> -static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
> -{
> - struct request rq;
> -
> - ide_init_drive_cmd(&rq);
> - rq.flags = REQ_DRIVE_TASK;
> - rq.buffer = buf;
> - return ide_do_drive_cmd(drive, &rq, ide_wait);
> -}
> -
> -/*
> - * FIXME : this needs to map into at taskfile. <[email protected]>
> - */
> int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
> {
> void __user *p = (void __user *)arg;
> - int err = 0;
> - u8 args[7], *argbuf = args;
> - int argsize = 7;
> + u8 args[7];
> + ide_task_request_t task_req;
> + task_ioreg_t *io_ports;
> + mm_segment_t orig_fs;
> + int ret;
>
> if (copy_from_user(args, p, 7))
> return -EFAULT;
> - err = ide_wait_cmd_task(drive, argbuf);
> - if (copy_to_user(p, argbuf, argsize))
> - err = -EFAULT;
> - return err;
> +
> + memset(&task_req, 0, sizeof(task_req));
> + task_req.out_flags.h.taskfile = IDE_TASKFILE_STD_OUT_FLAGS;
> + task_req.in_flags.h.taskfile = IDE_TASKFILE_STD_IN_FLAGS;
> +
> + io_ports = task_req.io_ports;
> + io_ports[IDE_COMMAND_OFFSET] = args[0];
> + io_ports[IDE_FEATURE_OFFSET] = args[1];
> + io_ports[IDE_NSECTOR_OFFSET] = args[2];
> + io_ports[IDE_SECTOR_OFFSET] = args[3];
> + io_ports[IDE_LCYL_OFFSET] = args[4];
> + io_ports[IDE_HCYL_OFFSET] = args[5];
> + io_ports[IDE_SELECT_OFFSET] = args[6];
> +
> + task_req.req_cmd = IDE_DRIVE_TASK_NO_DATA;
> + task_req.data_phase = TASKFILE_NO_DATA;
> +
> + orig_fs = get_fs();
> + set_fs(KERNEL_DS);
> +
> + ret = ide_taskfile_ioctl(drive, cmd, (unsigned long)&task_req);
> +
> + set_fs(orig_fs);

as HDIO_DRIVE_TASKFILE only supports no-data protocol
it should be easy to add missing bits here and get rid of calling
ide_taskfile_ioctl()

> + args[0] = io_ports[IDE_COMMAND_OFFSET];
> + args[1] = io_ports[IDE_FEATURE_OFFSET];
> + args[2] = io_ports[IDE_NSECTOR_OFFSET];
> + args[3] = io_ports[IDE_SECTOR_OFFSET];
> + args[4] = io_ports[IDE_LCYL_OFFSET];
> + args[5] = io_ports[IDE_HCYL_OFFSET];
> + args[6] = io_ports[IDE_SELECT_OFFSET];
> +
> + if (copy_to_user(p, args, 7))
> + ret = -EFAULT;
> +
> + return ret;
> }

Subject: Re: [PATCH 2.6.11-rc2 22/29] ide: convert REQ_DRIVE_TASK to REQ_DRIVE_TASKFILE

On Wed, 2 Feb 2005 12:07:27 +0900, Tejun Heo <[email protected]> wrote:
> > 22_ide_taskfile_flush.patch
> >
> > All REQ_DRIVE_TASK users except ide_task_ioctl() converted
> > to use REQ_DRIVE_TASKFILE.
> > 1. idedisk_issue_flush() converted to use REQ_DRIVE_TASKFILE.
> > This and the changes in ide_get_error_location() remove a
> > possible race condition between ide_get_error_location()
> > and other requests.

What race condition?

> > 2. ide_queue_flush_cmd() converted to use REQ_DRIVE_TASKFILE.
>
> Signed-off-by: Tejun Heo <[email protected]>
>
> Index: linux-ide-export/drivers/ide/ide-disk.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.272027942 +0900
> +++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
> @@ -705,24 +705,26 @@ static int idedisk_issue_flush(request_q
> {
> ide_drive_t *drive = q->queuedata;
> struct request *rq;
> + ide_task_t args;
> int ret;
>
> if (!drive->wcache)
> return 0;
>
> - rq = blk_get_request(q, WRITE, __GFP_WAIT);
> -
> - memset(rq->cmd, 0, sizeof(rq->cmd));
> + memset(&args, 0, sizeof(args));
>
> if (ide_id_has_flush_cache_ext(drive->id) &&
> (drive->capacity64 >= (1UL << 28)))
> - rq->cmd[0] = WIN_FLUSH_CACHE_EXT;
> + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
> else
> - rq->cmd[0] = WIN_FLUSH_CACHE;
> + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
>
> + args.command_type = IDE_DRIVE_TASK_NO_DATA;

.data_phase is missed

> + args.handler = task_no_data_intr;

Please compare the code above to the code you've added to
ide_queue_flush_cmd() - it is identical. It would be nice to add
some helper for doing this i.e. ide_init_flush_cmd().

> - rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER;
> - rq->buffer = rq->cmd;
> + rq = blk_get_request(q, WRITE, __GFP_WAIT);
> + rq->flags |= REQ_DRIVE_TASKFILE | REQ_SOFTBARRIER;
> + rq->special = &args;
>
> ret = blk_execute_rq(q, disk, rq);
>
> @@ -730,8 +732,9 @@ static int idedisk_issue_flush(request_q
> * if we failed and caller wants error offset, get it
> */
> if (ret && error_sector)
> - *error_sector = ide_get_error_location(drive, rq->cmd);
> + *error_sector = ide_get_error_location(drive, &args);
>
> + rq->special = NULL; /* just in case */
> blk_put_request(rq);
> return ret;
> }
> Index: linux-ide-export/drivers/ide/ide-io.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:06.273027780 +0900
> +++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:06.528986250 +0900
> @@ -55,24 +55,6 @@
> #include <asm/io.h>
> #include <asm/bitops.h>
>
> -static void ide_fill_flush_cmd(ide_drive_t *drive, struct request *rq)
> -{
> - char *buf = rq->cmd;
> -
> - /*
> - * reuse cdb space for ata command
> - */
> - memset(buf, 0, sizeof(rq->cmd));
> -
> - rq->flags |= REQ_DRIVE_TASK | REQ_STARTED;
> - rq->buffer = buf;
> - rq->buffer[0] = WIN_FLUSH_CACHE;
> -
> - if (ide_id_has_flush_cache_ext(drive->id) &&
> - (drive->capacity64 >= (1UL << 28)))
> - rq->buffer[0] = WIN_FLUSH_CACHE_EXT;
> -}
> -
> /*
> * preempt pending requests, and store this cache flush for immediate
> * execution
> @@ -80,7 +62,8 @@ static void ide_fill_flush_cmd(ide_drive
> static struct request *ide_queue_flush_cmd(ide_drive_t *drive,
> struct request *rq, int post)
> {
> - struct request *flush_rq = &HWGROUP(drive)->wrq;
> + struct request *flush_rq = &HWGROUP(drive)->flush_rq;
> + ide_task_t *args = &HWGROUP(drive)->flush_args;

please don't use HWGROUP() macro,
just use drive->hwif->hwgroup directly

> /*
> * write cache disabled, clear the barrier bit and treat it like
> @@ -92,10 +75,22 @@ static struct request *ide_queue_flush_c
> }
>
> ide_init_drive_cmd(flush_rq);
> - ide_fill_flush_cmd(drive, flush_rq);
> -
> - flush_rq->special = rq;
> + flush_rq->flags = REQ_DRIVE_TASKFILE | REQ_STARTED;
> flush_rq->nr_sectors = rq->nr_sectors;
> + flush_rq->special = args;
> + HWGROUP(drive)->flush_real_rq = rq;

ditto

> + memset(args, 0, sizeof(*args));
> +
> + if (ide_id_has_flush_cache_ext(drive->id) &&
> + (drive->capacity64 >= (1UL << 28)))
> + args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
> + else
> + args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
> +
> + args->command_type = IDE_DRIVE_TASK_NO_DATA;
> + args->data_phase = TASKFILE_NO_DATA;
> + args->handler = task_no_data_intr;
>
> if (!post) {
> drive->doing_barrier = 1;
> @@ -175,7 +170,7 @@ int ide_end_request (ide_drive_t *drive,
> if (!blk_barrier_rq(rq) || !drive->wcache)
> ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
> else {
> - struct request *flush_rq = &HWGROUP(drive)->wrq;
> + struct request *flush_rq = &HWGROUP(drive)->flush_rq;

ditto

> flush_rq->nr_sectors -= nr_sectors;
> if (!flush_rq->nr_sectors) {
> @@ -221,41 +216,37 @@ static void ide_complete_pm_request (ide
> /*
> * FIXME: probably move this somewhere else, name is bad too :)
> */
> -u64 ide_get_error_location(ide_drive_t *drive, char *args)
> +u64 ide_get_error_location(ide_drive_t *drive, ide_task_t *args)
> {
> u32 high, low;
> u8 hcyl, lcyl, sect;
> - u64 sector;
>
> - high = 0;
> - hcyl = args[5];
> - lcyl = args[4];
> - sect = args[3];
> -
> - if (ide_id_has_flush_cache_ext(drive->id)) {
> - low = (hcyl << 16) | (lcyl << 8) | sect;
> - HWIF(drive)->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
> - high = ide_read_24(drive);
> - } else {
> - u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
> - if (cur & 0x40)
> - low = (hcyl << 16) | (lcyl << 8) | sect;
> - else {
> - low = hcyl * drive->head * drive->sect;
> - low += lcyl * drive->sect;
> - low += sect - 1;
> - }
> - }
> + if (ide_id_has_flush_cache_ext(drive->id) &&
> + (drive->capacity64 >= (1UL << 28)))
> + high = (args->hobRegister[IDE_HCYL_OFFSET] << 16) |
> + (args->hobRegister[IDE_LCYL_OFFSET] << 8 ) |
> + args->hobRegister[IDE_SECTOR_OFFSET];
> + else
> + high = 0;
> +
> + hcyl = args->tfRegister[IDE_HCYL_OFFSET];
> + lcyl = args->tfRegister[IDE_LCYL_OFFSET];
> + sect = args->tfRegister[IDE_SECTOR_OFFSET];
> +
> + if (args->tfRegister[IDE_SELECT_OFFSET] & 0x40)
> + low = (hcyl << 16) | (lcyl << 8 ) | sect;
> + else
> + low = hcyl * drive->head * drive->sect +
> + lcyl * drive->sect + sect - 1;
>
> - sector = ((u64) high << 24) | low;
> - return sector;
> + return ((u64)high << 24) | low;
> }
> EXPORT_SYMBOL(ide_get_error_location);
>
> static void ide_complete_barrier(ide_drive_t *drive, struct request *rq,
> int error)
> {
> - struct request *real_rq = rq->special;
> + struct request *real_rq = HWGROUP(drive)->flush_real_rq;

ditto

> int good_sectors, bad_sectors;
> sector_t sector;
>
> @@ -302,7 +293,7 @@ static void ide_complete_barrier(ide_dri
> */
> good_sectors = 0;
> if (blk_barrier_postflush(rq)) {
> - sector = ide_get_error_location(drive, rq->buffer);
> + sector = ide_get_error_location(drive, rq->special);
>
> if ((sector >= real_rq->hard_sector) &&
> (sector < real_rq->hard_sector + real_rq->hard_nr_sectors))
> Index: linux-ide-export/include/linux/ide.h
> ===================================================================
> --- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.274027617 +0900
> +++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:06.529986088 +0900
> @@ -930,6 +930,39 @@ typedef ide_startstop_t (ide_pre_handler
> typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
> typedef int (ide_expiry_t)(ide_drive_t *);
>
> +typedef struct ide_task_s {
> +/*
> + * struct hd_drive_task_hdr tf;
> + * task_struct_t tf;
> + * struct hd_drive_hob_hdr hobf;
> + * hob_struct_t hobf;
> + */
> + task_ioreg_t tfRegister[8];
> + task_ioreg_t hobRegister[8];
> + ide_reg_valid_t tf_out_flags;
> + ide_reg_valid_t tf_in_flags;
> + int data_phase;
> + int command_type;
> + ide_pre_handler_t *prehandler;
> + ide_handler_t *handler;
> + struct request *rq; /* copy of request */
> + void *special; /* valid_t generally */
> +} ide_task_t;

please don't move this around,
adding struct ide_task_s; should do the trick

> +typedef struct pkt_task_s {
> +/*
> + * struct hd_drive_task_hdr pktf;
> + * task_struct_t pktf;
> + * u8 pkcdb[12];
> + */
> + task_ioreg_t tfRegister[8];
> + int data_phase;
> + int command_type;
> + ide_handler_t *handler;
> + struct request *rq; /* copy of request */
> + void *special;
> +} pkt_task_t;

there is no need to move pkt_task_t around
(moreover no code uses it currently)

> typedef struct hwgroup_s {
> /* irq handler, if active */
> ide_startstop_t (*handler)(ide_drive_t *);
> @@ -955,8 +988,12 @@ typedef struct hwgroup_s {
> struct request *rq;
> /* failsafe timer */
> struct timer_list timer;
> - /* local copy of current write rq */
> - struct request wrq;
> + /* rq used for flushing */
> + struct request flush_rq;
> + /* task used for flushing */
> + ide_task_t flush_args;
> + /* real_rq for flushing */
> + struct request *flush_real_rq;
> /* timeout value during long polls */
> unsigned long poll_timeout;
> /* queried upon timeouts */
> @@ -1203,7 +1240,7 @@ extern void ide_init_drive_cmd (struct r
> /*
> * this function returns error location sector offset in case of a write error
> */
> -extern u64 ide_get_error_location(ide_drive_t *, char *);
> +extern u64 ide_get_error_location(ide_drive_t *, ide_task_t *);

extern is not needed

> /*
> * "action" parameter type for ide_do_drive_cmd() below.
> @@ -1260,39 +1297,6 @@ extern void ide_end_drive_cmd(ide_drive_
> */
> extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
>
> -typedef struct ide_task_s {
> -/*
> - * struct hd_drive_task_hdr tf;
> - * task_struct_t tf;
> - * struct hd_drive_hob_hdr hobf;
> - * hob_struct_t hobf;
> - */
> - task_ioreg_t tfRegister[8];
> - task_ioreg_t hobRegister[8];
> - ide_reg_valid_t tf_out_flags;
> - ide_reg_valid_t tf_in_flags;
> - int data_phase;
> - int command_type;
> - ide_pre_handler_t *prehandler;
> - ide_handler_t *handler;
> - struct request *rq; /* copy of request */
> - void *special; /* valid_t generally */
> -} ide_task_t;
> -
> -typedef struct pkt_task_s {
> -/*
> - * struct hd_drive_task_hdr pktf;
> - * task_struct_t pktf;
> - * u8 pkcdb[12];
> - */
> - task_ioreg_t tfRegister[8];
> - int data_phase;
> - int command_type;
> - ide_handler_t *handler;
> - struct request *rq; /* copy of request */
> - void *special;
> -} pkt_task_t;
> -
> extern u32 ide_read_24(ide_drive_t *);
>
> extern void SELECT_DRIVE(ide_drive_t *);

rest of the patch looks fine

Subject: Re: [PATCH 2.6.11-rc2 29/29] ide: make data_phase explicit in NO_DATA cases

On Wed, 2 Feb 2005 12:12:38 +0900, Tejun Heo <[email protected]> wrote:
> > 29_ide_explicit_TASKFILE_NO_DATA.patch
> >
> > Make data_phase explicit in NO_DATA cases.
>
> Signed-off-by: Tejun Heo <[email protected]>
>
> Index: linux-ide-export/drivers/ide/ide-disk.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:07.852771465 +0900
> +++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:08.121727827 +0900
> @@ -300,6 +300,7 @@ static unsigned long idedisk_read_native
> args.tfRegister[IDE_SELECT_OFFSET] = 0x40;
> args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX;
> args.command_type = IDE_DRIVE_TASK_NO_DATA;
> + args.data_phase = TASKFILE_NO_DATA;
> args.handler = &task_no_data_intr;

Could you add small helper to ide.h for doing this?

static inline void ide_prep_no_data_cmd(ide_task_t *task)
{
task->command_type = IDE_DRIVE_TASK_NO_DATA;
task->data_phase = TASKFILE_NO_DATA;
task->handler = &task_no_data_intr;
}

Also please move this patch earlier in the series
so I can merge it quickly.

Thanks.

Subject: Re: [PATCH 2.6.11-rc2 23/29] ide: map ide_task_ioctl() to ide_taskfile_ioctl()

On Thu, 3 Feb 2005 18:37:04 +0100, Bartlomiej Zolnierkiewicz
<[email protected]> wrote:

> as HDIO_DRIVE_TASKFILE only supports no-data protocol
> it should be easy to add missing bits here and get rid of calling
> ide_taskfile_ioctl()

stupid typo: s/HDIO_DRIVE_TASKFILE/HDIO_DRIVE_TASK/

Subject: Re: [PATCH 2.6.11-rc2 21/29] ide: Merge do_rw_taskfile() and flagged_taskfile().

On Wed, 2 Feb 2005 12:06:03 +0900, Tejun Heo <[email protected]> wrote:
> > 21_ide_do_taskfile.patch
> >
> > Merged do_rw_taskfile() and flagged_taskfile() into
> > do_taskfile(). During the merge, the following changes took
> > place.
> > 1. flagged taskfile now honors HOB feature register.
> > (do_rw_taskfile() did write to HOB feature.)
> > 2. No do_rw_taskfile() HIHI check on select register. Except
> > for the DEV bit, all bits are honored.
> > 3. Uses taskfile->data_phase to determine if dma trasfer is
> > requested. (do_rw_taskfile() directly switched on
> > taskfile->command for all dma commands)
>
> Signed-off-by: Tejun Heo <[email protected]>

do_rw_taskfile() is going to be used by fs requests once
__ide_do_rw_disk() is converted to taskfile transport.

I don't think that do_rw_taskfile() and flagged_taskfile() merge
is a good thing as it adds unnecessary overhead for hot path
(fs requests).

Subject: Re: [PATCH 2.6.11-rc2 25/29] ide: convert REQ_DRIVE_CMD to REQ_DRIVE_TASKFILE

On Wed, 2 Feb 2005 12:15:59 +0900, Tejun Heo <[email protected]> wrote:
> > 25_ide_taskfile_cmd.patch
> >
> > All in-kernel REQ_DRIVE_CMD users except for ide_cmd_ioctl()
> > converted to use REQ_DRIVE_TASKFILE.
>
> Signed-off-by: Tejun Heo <[email protected]>
>
> Index: linux-ide-export/drivers/ide/ide-disk.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
> +++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:07.204876587 +0900
> @@ -750,7 +750,7 @@ static int set_multcount(ide_drive_t *dr
> if (drive->special.b.set_multmode)
> return -EBUSY;
> ide_init_drive_cmd (&rq);
> - rq.flags = REQ_DRIVE_CMD;
> + rq.flags = REQ_DRIVE_TASKFILE;

Please instead fix ide_init_drive_cmd() to set REQ_DRIVE_TASKFILE
and add set REQ_DRIVE_CMD only in ide_cmd_ioctl().

> drive->mult_req = arg;
> drive->special.b.set_multmode = 1;
> (void) ide_do_drive_cmd (drive, &rq, ide_wait);
> Index: linux-ide-export/drivers/ide/ide.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide.c 2005-02-02 10:27:14.652402828 +0900
> +++ linux-ide-export/drivers/ide/ide.c 2005-02-02 10:28:07.205876425 +0900
> @@ -1255,6 +1255,7 @@ static int set_pio_mode (ide_drive_t *dr
> if (drive->special.b.set_tune)
> return -EBUSY;
> ide_init_drive_cmd(&rq);
> + rq.flags = REQ_DRIVE_TASKFILE;
> drive->tune_req = (u8) arg;
> drive->special.b.set_tune = 1;
> (void) ide_do_drive_cmd(drive, &rq, ide_wait);

2005-02-03 22:35:32

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

Bartlomiej Zolnierkiewicz wrote:
> On Thu, 3 Feb 2005 14:32:29 +0100, Jens Axboe <[email protected]> wrote:
>
>>On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
>>
>>>On Thu, 3 Feb 2005 12:37:10 +0100, Jens Axboe <[email protected]> wrote:
>>>
>>>>On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
>>>>
>>>>>On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
>>>>>
>>>>>>>11_ide_drive_sleeping_fix.patch
>>>>>>>
>>>>>>> ide_drive_t.sleeping field added. 0 in sleep field used to
>>>>>>> indicate inactive sleeping but because 0 is a valid jiffy
>>>>>>> value, though slim, there's a chance that something can go
>>>>>>> weird. And while at it, explicit jiffy comparisons are
>>>>>>> converted to use time_{after|before} macros.
>>>>>
>>>>>Same question as for "add ide_hwgroup_t.polling" patch.
>>>>>AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)
>>>>
>>>>Hmm, what if jiffies + timeout == 0?
>>>
>>>Hm, jiffies is unsigned and timeout is always > 0
>>>but this is still possible if jiffies + timeout wraps, right?
>>
>>Precisely, if jiffies is exactly 'timeout' away from wrapping to 0 it
>>could happen. So I think the fix looks sane.
>
>
> agreed

Actually, jiffies is initialized to INITIAL_JIFFIES which is defined in
such a way that it overflows after 5 min after boot to help finding bugs
related to jiffies wrap. So, the chance of something weird happening in
the bugs fixed in patches 11 and 12 isn't that exteremely slim. :-)

--
tejun

2005-02-04 00:31:35

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 21/29] ide: Merge do_rw_taskfile() and flagged_taskfile().

Hello,

Bartlomiej Zolnierkiewicz wrote:
> On Wed, 2 Feb 2005 12:06:03 +0900, Tejun Heo <[email protected]> wrote:
>
>>>21_ide_do_taskfile.patch
>>>
>>> Merged do_rw_taskfile() and flagged_taskfile() into
>>> do_taskfile(). During the merge, the following changes took
>>> place.
>>> 1. flagged taskfile now honors HOB feature register.
>>> (do_rw_taskfile() did write to HOB feature.)
>>> 2. No do_rw_taskfile() HIHI check on select register. Except
>>> for the DEV bit, all bits are honored.
>>> 3. Uses taskfile->data_phase to determine if dma trasfer is
>>> requested. (do_rw_taskfile() directly switched on
>>> taskfile->command for all dma commands)
>>
>>Signed-off-by: Tejun Heo <[email protected]>
>
>
> do_rw_taskfile() is going to be used by fs requests once
> __ide_do_rw_disk() is converted to taskfile transport.
>
> I don't think that do_rw_taskfile() and flagged_taskfile() merge
> is a good thing as it adds unnecessary overhead for hot path
> (fs requests).

Yeah, I also thought about that, but here are reasons why I still think
merging is better.

1. The added overhead is small. It's just a dozen more if's per every
disk io. I don't think it will make any noticeable difference.

2. If hot path optimization is needed, it can be easily done inside one
do_taskfile() function with one or two more if's.

3. Currently, do_rw_taskfile() isn't used by __ide_do_rw_disk(). We can
think about optimization when actually converting it to use taskfile
transport. And IMHO, if hot path optimization is needed, leaving hot
path optimization where it is now (inside __ide_do_rw_disk()) is better
than moving it to separate taskfile function (do_rw_taskfile()).

--
tejun

2005-02-04 01:19:12

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 22/29] ide: convert REQ_DRIVE_TASK to REQ_DRIVE_TASKFILE

Hello again, Bartlomiej.

Bartlomiej Zolnierkiewicz wrote:
> On Wed, 2 Feb 2005 12:07:27 +0900, Tejun Heo <[email protected]> wrote:
>
>>>22_ide_taskfile_flush.patch
>>>
>>> All REQ_DRIVE_TASK users except ide_task_ioctl() converted
>>> to use REQ_DRIVE_TASKFILE.
>>> 1. idedisk_issue_flush() converted to use REQ_DRIVE_TASKFILE.
>>> This and the changes in ide_get_error_location() remove a
>>> possible race condition between ide_get_error_location()
>>> and other requests.
>
>
> What race condition?

The old ide_get_error_location() acceses hardware registers after the
flush request is finished, so the registers could have been crobbered by
other on-going or finished requests.

>>> 2. ide_queue_flush_cmd() converted to use REQ_DRIVE_TASKFILE.
>>
>>Signed-off-by: Tejun Heo <[email protected]>
>>
>>Index: linux-ide-export/drivers/ide/ide-disk.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.272027942 +0900
>>+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
>>@@ -705,24 +705,26 @@ static int idedisk_issue_flush(request_q
>> {
>> ide_drive_t *drive = q->queuedata;
>> struct request *rq;
>>+ ide_task_t args;
>> int ret;
>>
>> if (!drive->wcache)
>> return 0;
>>
>>- rq = blk_get_request(q, WRITE, __GFP_WAIT);
>>-
>>- memset(rq->cmd, 0, sizeof(rq->cmd));
>>+ memset(&args, 0, sizeof(args));
>>
>> if (ide_id_has_flush_cache_ext(drive->id) &&
>> (drive->capacity64 >= (1UL << 28)))
>>- rq->cmd[0] = WIN_FLUSH_CACHE_EXT;
>>+ args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
>> else
>>- rq->cmd[0] = WIN_FLUSH_CACHE;
>>+ args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
>>
>>+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
>
>
> .data_phase is missed

Yeah, it was kind of intentional as all other functions which do
IDE_DRIVE_TASK_NO_DATA don't initialize args.data_phase explicitly.
patch #29 makes this change for all such cases including this one.

>
>>+ args.handler = task_no_data_intr;
>
>
> Please compare the code above to the code you've added to
> ide_queue_flush_cmd() - it is identical. It would be nice to add
> some helper for doing this i.e. ide_init_flush_cmd().
>

Sure.

>
>>- rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER;
>>- rq->buffer = rq->cmd;
>>+ rq = blk_get_request(q, WRITE, __GFP_WAIT);
>>+ rq->flags |= REQ_DRIVE_TASKFILE | REQ_SOFTBARRIER;
>>+ rq->special = &args;
>>
>> ret = blk_execute_rq(q, disk, rq);
>>
>>@@ -730,8 +732,9 @@ static int idedisk_issue_flush(request_q
>> * if we failed and caller wants error offset, get it
>> */
>> if (ret && error_sector)
>>- *error_sector = ide_get_error_location(drive, rq->cmd);
>>+ *error_sector = ide_get_error_location(drive, &args);
>>
>>+ rq->special = NULL; /* just in case */
>> blk_put_request(rq);
>> return ret;
>> }
>>Index: linux-ide-export/drivers/ide/ide-io.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide-io.c 2005-02-02 10:28:06.273027780 +0900
>>+++ linux-ide-export/drivers/ide/ide-io.c 2005-02-02 10:28:06.528986250 +0900
>>@@ -55,24 +55,6 @@
>> #include <asm/io.h>
>> #include <asm/bitops.h>
>>
>>-static void ide_fill_flush_cmd(ide_drive_t *drive, struct request *rq)
>>-{
>>- char *buf = rq->cmd;
>>-
>>- /*
>>- * reuse cdb space for ata command
>>- */
>>- memset(buf, 0, sizeof(rq->cmd));
>>-
>>- rq->flags |= REQ_DRIVE_TASK | REQ_STARTED;
>>- rq->buffer = buf;
>>- rq->buffer[0] = WIN_FLUSH_CACHE;
>>-
>>- if (ide_id_has_flush_cache_ext(drive->id) &&
>>- (drive->capacity64 >= (1UL << 28)))
>>- rq->buffer[0] = WIN_FLUSH_CACHE_EXT;
>>-}
>>-
>> /*
>> * preempt pending requests, and store this cache flush for immediate
>> * execution
>>@@ -80,7 +62,8 @@ static void ide_fill_flush_cmd(ide_drive
>> static struct request *ide_queue_flush_cmd(ide_drive_t *drive,
>> struct request *rq, int post)
>> {
>>- struct request *flush_rq = &HWGROUP(drive)->wrq;
>>+ struct request *flush_rq = &HWGROUP(drive)->flush_rq;
>>+ ide_task_t *args = &HWGROUP(drive)->flush_args;
>
>
> please don't use HWGROUP() macro,
> just use drive->hwif->hwgroup directly
>

I think I'll leave the code like above here and make another patch which
removes all uses of HWGROUP() and HWGROUP() itself. What do you think
about that?

>
>> /*
>> * write cache disabled, clear the barrier bit and treat it like
>>@@ -92,10 +75,22 @@ static struct request *ide_queue_flush_c
>> }
>>
>> ide_init_drive_cmd(flush_rq);
>>- ide_fill_flush_cmd(drive, flush_rq);
>>-
>>- flush_rq->special = rq;
>>+ flush_rq->flags = REQ_DRIVE_TASKFILE | REQ_STARTED;
>> flush_rq->nr_sectors = rq->nr_sectors;
>>+ flush_rq->special = args;
>>+ HWGROUP(drive)->flush_real_rq = rq;
>
>
> ditto
>
>
>>+ memset(args, 0, sizeof(*args));
>>+
>>+ if (ide_id_has_flush_cache_ext(drive->id) &&
>>+ (drive->capacity64 >= (1UL << 28)))
>>+ args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
>>+ else
>>+ args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
>>+
>>+ args->command_type = IDE_DRIVE_TASK_NO_DATA;
>>+ args->data_phase = TASKFILE_NO_DATA;
>>+ args->handler = task_no_data_intr;
>>
>> if (!post) {
>> drive->doing_barrier = 1;
>>@@ -175,7 +170,7 @@ int ide_end_request (ide_drive_t *drive,
>> if (!blk_barrier_rq(rq) || !drive->wcache)
>> ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
>> else {
>>- struct request *flush_rq = &HWGROUP(drive)->wrq;
>>+ struct request *flush_rq = &HWGROUP(drive)->flush_rq;
>
>
> ditto
>
>
>> flush_rq->nr_sectors -= nr_sectors;
>> if (!flush_rq->nr_sectors) {
>>@@ -221,41 +216,37 @@ static void ide_complete_pm_request (ide
>> /*
>> * FIXME: probably move this somewhere else, name is bad too :)
>> */
>>-u64 ide_get_error_location(ide_drive_t *drive, char *args)
>>+u64 ide_get_error_location(ide_drive_t *drive, ide_task_t *args)
>> {
>> u32 high, low;
>> u8 hcyl, lcyl, sect;
>>- u64 sector;
>>
>>- high = 0;
>>- hcyl = args[5];
>>- lcyl = args[4];
>>- sect = args[3];
>>-
>>- if (ide_id_has_flush_cache_ext(drive->id)) {
>>- low = (hcyl << 16) | (lcyl << 8) | sect;
>>- HWIF(drive)->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
>>- high = ide_read_24(drive);
>>- } else {
>>- u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
>>- if (cur & 0x40)
>>- low = (hcyl << 16) | (lcyl << 8) | sect;
>>- else {
>>- low = hcyl * drive->head * drive->sect;
>>- low += lcyl * drive->sect;
>>- low += sect - 1;
>>- }
>>- }
>>+ if (ide_id_has_flush_cache_ext(drive->id) &&
>>+ (drive->capacity64 >= (1UL << 28)))
>>+ high = (args->hobRegister[IDE_HCYL_OFFSET] << 16) |
>>+ (args->hobRegister[IDE_LCYL_OFFSET] << 8 ) |
>>+ args->hobRegister[IDE_SECTOR_OFFSET];
>>+ else
>>+ high = 0;
>>+
>>+ hcyl = args->tfRegister[IDE_HCYL_OFFSET];
>>+ lcyl = args->tfRegister[IDE_LCYL_OFFSET];
>>+ sect = args->tfRegister[IDE_SECTOR_OFFSET];
>>+
>>+ if (args->tfRegister[IDE_SELECT_OFFSET] & 0x40)
>>+ low = (hcyl << 16) | (lcyl << 8 ) | sect;
>>+ else
>>+ low = hcyl * drive->head * drive->sect +
>>+ lcyl * drive->sect + sect - 1;
>>
>>- sector = ((u64) high << 24) | low;
>>- return sector;
>>+ return ((u64)high << 24) | low;
>> }
>> EXPORT_SYMBOL(ide_get_error_location);
>>
>> static void ide_complete_barrier(ide_drive_t *drive, struct request *rq,
>> int error)
>> {
>>- struct request *real_rq = rq->special;
>>+ struct request *real_rq = HWGROUP(drive)->flush_real_rq;
>
>
> ditto
>
>
>> int good_sectors, bad_sectors;
>> sector_t sector;
>>
>>@@ -302,7 +293,7 @@ static void ide_complete_barrier(ide_dri
>> */
>> good_sectors = 0;
>> if (blk_barrier_postflush(rq)) {
>>- sector = ide_get_error_location(drive, rq->buffer);
>>+ sector = ide_get_error_location(drive, rq->special);
>>
>> if ((sector >= real_rq->hard_sector) &&
>> (sector < real_rq->hard_sector + real_rq->hard_nr_sectors))
>>Index: linux-ide-export/include/linux/ide.h
>>===================================================================
>>--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.274027617 +0900
>>+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:06.529986088 +0900
>>@@ -930,6 +930,39 @@ typedef ide_startstop_t (ide_pre_handler
>> typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
>> typedef int (ide_expiry_t)(ide_drive_t *);
>>
>>+typedef struct ide_task_s {
>>+/*
>>+ * struct hd_drive_task_hdr tf;
>>+ * task_struct_t tf;
>>+ * struct hd_drive_hob_hdr hobf;
>>+ * hob_struct_t hobf;
>>+ */
>>+ task_ioreg_t tfRegister[8];
>>+ task_ioreg_t hobRegister[8];
>>+ ide_reg_valid_t tf_out_flags;
>>+ ide_reg_valid_t tf_in_flags;
>>+ int data_phase;
>>+ int command_type;
>>+ ide_pre_handler_t *prehandler;
>>+ ide_handler_t *handler;
>>+ struct request *rq; /* copy of request */
>>+ void *special; /* valid_t generally */
>>+} ide_task_t;
>
>
> please don't move this around,
> adding struct ide_task_s; should do the trick
>

No, I added ide_task_t flush_args to hwgroup_t not a pointer to
ide_task_t, so the definition of ide_task_t has to come before the
definition of hwgroup_t.

>
>>+typedef struct pkt_task_s {
>>+/*
>>+ * struct hd_drive_task_hdr pktf;
>>+ * task_struct_t pktf;
>>+ * u8 pkcdb[12];
>>+ */
>>+ task_ioreg_t tfRegister[8];
>>+ int data_phase;
>>+ int command_type;
>>+ ide_handler_t *handler;
>>+ struct request *rq; /* copy of request */
>>+ void *special;
>>+} pkt_task_t;
>
>
> there is no need to move pkt_task_t around
> (moreover no code uses it currently)
>

And it seemd kind of lonely after ide_task_t moved upward. :-) How
about modifying this patch such that it moves only the ide_task_t and
adding another patch to kill pkt_task_t?

>
>> typedef struct hwgroup_s {
>> /* irq handler, if active */
>> ide_startstop_t (*handler)(ide_drive_t *);
>>@@ -955,8 +988,12 @@ typedef struct hwgroup_s {
>> struct request *rq;
>> /* failsafe timer */
>> struct timer_list timer;
>>- /* local copy of current write rq */
>>- struct request wrq;
>>+ /* rq used for flushing */
>>+ struct request flush_rq;
>>+ /* task used for flushing */
>>+ ide_task_t flush_args;
>>+ /* real_rq for flushing */
>>+ struct request *flush_real_rq;
>> /* timeout value during long polls */
>> unsigned long poll_timeout;
>> /* queried upon timeouts */
>>@@ -1203,7 +1240,7 @@ extern void ide_init_drive_cmd (struct r
>> /*
>> * this function returns error location sector offset in case of a write error
>> */
>>-extern u64 ide_get_error_location(ide_drive_t *, char *);
>>+extern u64 ide_get_error_location(ide_drive_t *, ide_task_t *);
>
>
> extern is not needed
>

Yeah, it isn't needed. I was trying to be conformant with other
declarations in the file. I'll leave above line as it is now and write
another patch to remove all extern's in front of function prototypes in
ide drivers. What do you think?

>
>> /*
>> * "action" parameter type for ide_do_drive_cmd() below.
>>@@ -1260,39 +1297,6 @@ extern void ide_end_drive_cmd(ide_drive_
>> */
>> extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
>>
>>-typedef struct ide_task_s {
>>-/*
>>- * struct hd_drive_task_hdr tf;
>>- * task_struct_t tf;
>>- * struct hd_drive_hob_hdr hobf;
>>- * hob_struct_t hobf;
>>- */
>>- task_ioreg_t tfRegister[8];
>>- task_ioreg_t hobRegister[8];
>>- ide_reg_valid_t tf_out_flags;
>>- ide_reg_valid_t tf_in_flags;
>>- int data_phase;
>>- int command_type;
>>- ide_pre_handler_t *prehandler;
>>- ide_handler_t *handler;
>>- struct request *rq; /* copy of request */
>>- void *special; /* valid_t generally */
>>-} ide_task_t;
>>-
>>-typedef struct pkt_task_s {
>>-/*
>>- * struct hd_drive_task_hdr pktf;
>>- * task_struct_t pktf;
>>- * u8 pkcdb[12];
>>- */
>>- task_ioreg_t tfRegister[8];
>>- int data_phase;
>>- int command_type;
>>- ide_handler_t *handler;
>>- struct request *rq; /* copy of request */
>>- void *special;
>>-} pkt_task_t;
>>-
>> extern u32 ide_read_24(ide_drive_t *);
>>
>> extern void SELECT_DRIVE(ide_drive_t *);
>
>
> rest of the patch looks fine

Thanks.

--
tejun

2005-02-04 01:20:30

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 29/29] ide: make data_phase explicit in NO_DATA cases

Bartlomiej Zolnierkiewicz wrote:
> On Wed, 2 Feb 2005 12:12:38 +0900, Tejun Heo <[email protected]> wrote:
>
>>>29_ide_explicit_TASKFILE_NO_DATA.patch
>>>
>>> Make data_phase explicit in NO_DATA cases.
>>
>>Signed-off-by: Tejun Heo <[email protected]>
>>
>>Index: linux-ide-export/drivers/ide/ide-disk.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:07.852771465 +0900
>>+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:08.121727827 +0900
>>@@ -300,6 +300,7 @@ static unsigned long idedisk_read_native
>> args.tfRegister[IDE_SELECT_OFFSET] = 0x40;
>> args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX;
>> args.command_type = IDE_DRIVE_TASK_NO_DATA;
>>+ args.data_phase = TASKFILE_NO_DATA;
>> args.handler = &task_no_data_intr;
>
>
> Could you add small helper to ide.h for doing this?
>
> static inline void ide_prep_no_data_cmd(ide_task_t *task)
> {
> task->command_type = IDE_DRIVE_TASK_NO_DATA;
> task->data_phase = TASKFILE_NO_DATA;
> task->handler = &task_no_data_intr;
> }

I am thinking about removing task->handler initialization. Such that it
defaults to task_no_data_intr if data_phase == TASKFILE_NO_DATA and so
on for all other data_phases. Currently, the same information is
specified repeatedly. What do you think?

> Also please move this patch earlier in the series
> so I can merge it quickly.
>
> Thanks.

Sure.

--
tejun

Subject: Re: [PATCH 2.6.11-rc2 29/29] ide: make data_phase explicit in NO_DATA cases

On Fri, 04 Feb 2005 09:59:22 +0900, Tejun Heo <[email protected]> wrote:
> Bartlomiej Zolnierkiewicz wrote:
> > On Wed, 2 Feb 2005 12:12:38 +0900, Tejun Heo <[email protected]> wrote:
> >
> >>>29_ide_explicit_TASKFILE_NO_DATA.patch
> >>>
> >>> Make data_phase explicit in NO_DATA cases.
> >>
> >>Signed-off-by: Tejun Heo <[email protected]>
> >>
> >>Index: linux-ide-export/drivers/ide/ide-disk.c
> >>===================================================================
> >>--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:07.852771465 +0900
> >>+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:08.121727827 +0900
> >>@@ -300,6 +300,7 @@ static unsigned long idedisk_read_native
> >> args.tfRegister[IDE_SELECT_OFFSET] = 0x40;
> >> args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX;
> >> args.command_type = IDE_DRIVE_TASK_NO_DATA;
> >>+ args.data_phase = TASKFILE_NO_DATA;
> >> args.handler = &task_no_data_intr;
> >
> >
> > Could you add small helper to ide.h for doing this?
> >
> > static inline void ide_prep_no_data_cmd(ide_task_t *task)
> > {
> > task->command_type = IDE_DRIVE_TASK_NO_DATA;
> > task->data_phase = TASKFILE_NO_DATA;
> > task->handler = &task_no_data_intr;
> > }
>
> I am thinking about removing task->handler initialization. Such that it
> defaults to task_no_data_intr if data_phase == TASKFILE_NO_DATA and so
> on for all other data_phases. Currently, the same information is
> specified repeatedly. What do you think?

Please do it.

Subject: Re: [PATCH 2.6.11-rc2 25/29] ide: convert REQ_DRIVE_CMD to REQ_DRIVE_TASKFILE

On Fri, 04 Feb 2005 10:06:29 +0900, Tejun Heo <[email protected]> wrote:
> Hello,
>
> Bartlomiej Zolnierkiewicz wrote:
> > On Wed, 2 Feb 2005 12:15:59 +0900, Tejun Heo <[email protected]> wrote:
> >
> >>>25_ide_taskfile_cmd.patch
> >>>
> >>> All in-kernel REQ_DRIVE_CMD users except for ide_cmd_ioctl()
> >>> converted to use REQ_DRIVE_TASKFILE.
> >>
> >>Signed-off-by: Tejun Heo <[email protected]>
> >>
> >>Index: linux-ide-export/drivers/ide/ide-disk.c
> >>===================================================================
> >>--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
> >>+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:07.204876587 +0900
> >>@@ -750,7 +750,7 @@ static int set_multcount(ide_drive_t *dr
> >> if (drive->special.b.set_multmode)
> >> return -EBUSY;
> >> ide_init_drive_cmd (&rq);
> >>- rq.flags = REQ_DRIVE_CMD;
> >>+ rq.flags = REQ_DRIVE_TASKFILE;
> >
> >
> > Please instead fix ide_init_drive_cmd() to set REQ_DRIVE_TASKFILE
> > and add set REQ_DRIVE_CMD only in ide_cmd_ioctl().
> >
>
> This is done in patch #28. If you don't like the ordering of the
> patches, I can change the orders but I don't think that improves
> anything. This order is as good as the other order.

Actually no - if you change this then patch #28 becomes NOP.

So please do it, thanks.

Subject: Re: [PATCH 2.6.11-rc2 22/29] ide: convert REQ_DRIVE_TASK to REQ_DRIVE_TASKFILE

On Fri, 04 Feb 2005 09:54:23 +0900, Tejun Heo <[email protected]> wrote:
> Hello again, Bartlomiej.
>
> Bartlomiej Zolnierkiewicz wrote:
> > On Wed, 2 Feb 2005 12:07:27 +0900, Tejun Heo <[email protected]> wrote:
> >
> >>>22_ide_taskfile_flush.patch
> >>>
> >>> All REQ_DRIVE_TASK users except ide_task_ioctl() converted
> >>> to use REQ_DRIVE_TASKFILE.
> >>> 1. idedisk_issue_flush() converted to use REQ_DRIVE_TASKFILE.
> >>> This and the changes in ide_get_error_location() remove a
> >>> possible race condition between ide_get_error_location()
> >>> and other requests.
> >
> >
> > What race condition?
>
> The old ide_get_error_location() acceses hardware registers after the
> flush request is finished, so the registers could have been crobbered by
> other on-going or finished requests.

yep, you are right

> >>@@ -80,7 +62,8 @@ static void ide_fill_flush_cmd(ide_drive
> >> static struct request *ide_queue_flush_cmd(ide_drive_t *drive,
> >> struct request *rq, int post)
> >> {
> >>- struct request *flush_rq = &HWGROUP(drive)->wrq;
> >>+ struct request *flush_rq = &HWGROUP(drive)->flush_rq;
> >>+ ide_task_t *args = &HWGROUP(drive)->flush_args;
> >
> >
> > please don't use HWGROUP() macro,
> > just use drive->hwif->hwgroup directly
> >
>
> I think I'll leave the code like above here and make another patch which
> removes all uses of HWGROUP() and HWGROUP() itself. What do you think
> about that?

I prefer gradual changes because IMHO such global find'n'replace
changes have high noise ratio and are bad for maintainability
(also most of the code it would touch need some other fixes anyway).

> >>@@ -930,6 +930,39 @@ typedef ide_startstop_t (ide_pre_handler
> >> typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
> >> typedef int (ide_expiry_t)(ide_drive_t *);
> >>
> >>+typedef struct ide_task_s {
> >>+/*
> >>+ * struct hd_drive_task_hdr tf;
> >>+ * task_struct_t tf;
> >>+ * struct hd_drive_hob_hdr hobf;
> >>+ * hob_struct_t hobf;
> >>+ */
> >>+ task_ioreg_t tfRegister[8];
> >>+ task_ioreg_t hobRegister[8];
> >>+ ide_reg_valid_t tf_out_flags;
> >>+ ide_reg_valid_t tf_in_flags;
> >>+ int data_phase;
> >>+ int command_type;
> >>+ ide_pre_handler_t *prehandler;
> >>+ ide_handler_t *handler;
> >>+ struct request *rq; /* copy of request */
> >>+ void *special; /* valid_t generally */
> >>+} ide_task_t;
> >
> >
> > please don't move this around,
> > adding struct ide_task_s; should do the trick
> >
>
> No, I added ide_task_t flush_args to hwgroup_t not a pointer to
> ide_task_t, so the definition of ide_task_t has to come before the
> definition of hwgroup_t.

OK

> >
> >>+typedef struct pkt_task_s {
> >>+/*
> >>+ * struct hd_drive_task_hdr pktf;
> >>+ * task_struct_t pktf;
> >>+ * u8 pkcdb[12];
> >>+ */
> >>+ task_ioreg_t tfRegister[8];
> >>+ int data_phase;
> >>+ int command_type;
> >>+ ide_handler_t *handler;
> >>+ struct request *rq; /* copy of request */
> >>+ void *special;
> >>+} pkt_task_t;
> >
> >
> > there is no need to move pkt_task_t around
> > (moreover no code uses it currently)
> >
>
> And it seemd kind of lonely after ide_task_t moved upward. :-) How
> about modifying this patch such that it moves only the ide_task_t and
> adding another patch to kill pkt_task_t?

sounds good

> >
> >> typedef struct hwgroup_s {
> >> /* irq handler, if active */
> >> ide_startstop_t (*handler)(ide_drive_t *);
> >>@@ -955,8 +988,12 @@ typedef struct hwgroup_s {
> >> struct request *rq;
> >> /* failsafe timer */
> >> struct timer_list timer;
> >>- /* local copy of current write rq */
> >>- struct request wrq;
> >>+ /* rq used for flushing */
> >>+ struct request flush_rq;
> >>+ /* task used for flushing */
> >>+ ide_task_t flush_args;
> >>+ /* real_rq for flushing */
> >>+ struct request *flush_real_rq;
> >> /* timeout value during long polls */
> >> unsigned long poll_timeout;
> >> /* queried upon timeouts */
> >>@@ -1203,7 +1240,7 @@ extern void ide_init_drive_cmd (struct r
> >> /*
> >> * this function returns error location sector offset in case of a write error
> >> */
> >>-extern u64 ide_get_error_location(ide_drive_t *, char *);
> >>+extern u64 ide_get_error_location(ide_drive_t *, ide_task_t *);
> >
> >
> > extern is not needed
> >
>
> Yeah, it isn't needed. I was trying to be conformant with other
> declarations in the file. I'll leave above line as it is now and write
> another patch to remove all extern's in front of function prototypes in
> ide drivers. What do you think?

I think the same as for HWGROUP() change - better to do it gradually.

Subject: Re: [PATCH 2.6.11-rc2 05/29] ide: merge pci driver .h's into .c's

On Wed, 2 Feb 2005 11:47:12 +0900, Tejun Heo <[email protected]> wrote:
> > 05_ide_merge_pci_driver_hc.patch
> >
> > Merges drivers/ide/pci/*.h files into their corresponding *.c
> > files. Rationales are
> > 1. There's no reason to separate pci drivers into header and
> > body. No header file is shared and they're simple enough.
> > 2. struct pde_pci_device_t *_chipsets[] are _defined_ in the
> > header files. That isn't the custom and there's no good
> > reason to do differently in these drivers.
> > 3. Tracking changelogs shows that the bugs fixed by 00 and 01
> > are introduced during mass-updating ide pci drivers by
> > forgetting to update *.h files.
>
> Signed-off-by: Tejun Heo <[email protected]>

Please kill crap in these .h files before mering them with .c files,
also split this patch on per driver changes.

crap example looks like this: ;)

> +#ifndef SPLIT_BYTE
> +#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
> +#endif
> +#ifndef MAKE_WORD
> +#define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))
> +#endif

2005-02-04 02:17:46

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 26/29] ide: map ide_cmd_ioctl() to ide_taskfile_ioctl()

Bartlomiej Zolnierkiewicz wrote:
> On Wed, 2 Feb 2005 12:10:37 +0900, Tejun Heo <[email protected]> wrote:
>
>>>26_ide_taskfile_cmd_ioctl.patch
>>>
>>> ide_cmd_ioctl() converted to use ide_taskfile_ioctl(). This
>>> is the last user of REQ_DRIVE_CMD.
>
>
> ide_cmd_ioctl() needs to map to taskfile transport not ide_taskfile_ioctl()
>
>
>>Index: linux-ide-export/drivers/ide/ide-iops.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide-iops.c 2005-02-02 10:28:04.466320918 +0900
>>+++ linux-ide-export/drivers/ide/ide-iops.c 2005-02-02 10:28:07.406843817 +0900
>>@@ -648,11 +648,11 @@ u8 eighty_ninty_three (ide_drive_t *driv
>>
>> EXPORT_SYMBOL(eighty_ninty_three);
>>
>>-int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
>>+int ide_ata66_check (ide_drive_t *drive, task_ioreg_t *regs)
>
>
> nitpick: int ide_ata66_check()
>

meaning...?

>
>> {
>>- if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
>>- (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
>>- (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
>>+ if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
>>+ (regs[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
>>+ (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
>
>
> nitpick: please drop brackets
>

Parenthese?

>
>> #ifndef CONFIG_IDEDMA_IVB
>> if ((drive->id->hw_config & 0x6000) == 0) {
>> #else /* !CONFIG_IDEDMA_IVB */
>>@@ -678,11 +678,11 @@ int ide_ata66_check (ide_drive_t *drive,
>> * 1 : Safe to update drive->id DMA registers.
>> * 0 : OOPs not allowed.
>> */
>>-int set_transfer (ide_drive_t *drive, ide_task_t *args)
>>+int set_transfer (ide_drive_t *drive, task_ioreg_t *regs)
>
>
> nitpick: int set_transfer()
>

??

>
>> {
>>- if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
>>- (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
>>- (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
>>+ if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
>>+ (regs[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
>>+ (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
>
>
> nitpick: brackets
>

Parentheses?

>
>> (drive->id->dma_ultra ||
>> drive->id->dma_mword ||
>> drive->id->dma_1word))
>>Index: linux-ide-export/drivers/ide/ide-taskfile.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.751950074 +0900
>>+++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:07.407843655 +0900
>>@@ -704,78 +704,90 @@ abort:
>> return err;
>> }
>>
>>-int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
>>-{
>>- struct request rq;
>>- u8 buffer[4];
>>-
>>- if (!buf)
>>- buf = buffer;
>>- memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
>>- ide_init_drive_cmd(&rq);
>>- rq.buffer = buf;
>>- *buf++ = cmd;
>>- *buf++ = nsect;
>>- *buf++ = feature;
>>- *buf++ = sectors;
>>- return ide_do_drive_cmd(drive, &rq, ide_wait);
>>-}
>>-
>>-/*
>>- * FIXME : this needs to map into at taskfile. <[email protected]>
>>- */
>> int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
>> {
>>- int err = 0;
>>- u8 args[4], *argbuf = args;
>>+ u8 args[4];
>>+ ide_task_request_t *task_req;
>>+ task_ioreg_t *io_ports;
>> u8 xfer_rate = 0;
>>- int argsize = 4;
>>- ide_task_t tfargs;
>>+ mm_segment_t orig_fs;
>>+ int in_size, ret;
>>
>>- if (NULL == (void *) arg) {
>>+ if ((void *)arg == NULL) {
>> struct request rq;
>> ide_init_drive_cmd(&rq);
>>+ rq.flags = REQ_DRIVE_TASKFILE;
>> return ide_do_drive_cmd(drive, &rq, ide_wait);
>> }
>>
>> if (copy_from_user(args, (void __user *)arg, 4))
>> return -EFAULT;
>>
>>- memset(&tfargs, 0, sizeof(ide_task_t));
>>- tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
>>- tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
>>- tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1];
>>- tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00;
>>- tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00;
>>- tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00;
>>- tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
>>-
>>- if (args[3]) {
>>- argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
>>- argbuf = kmalloc(argsize, GFP_KERNEL);
>>- if (argbuf == NULL)
>>- return -ENOMEM;
>>- memcpy(argbuf, args, 4);
>>+ in_size = 4 * SECTOR_WORDS * args[3];
>>+
>>+ task_req = kmalloc(sizeof(*task_req) + in_size, GFP_KERNEL);
>>+ if (task_req == NULL)
>>+ return -ENOMEM;
>>+
>>+ memset(task_req, 0, sizeof(*task_req) + in_size);
>>+
>>+ task_req->out_flags.b.status_command = 1;
>>+ task_req->out_flags.b.sector = 1;
>>+ task_req->out_flags.b.error_feature = 1;
>>+ task_req->out_flags.b.nsector = 1;
>>+
>>+ task_req->in_flags.b.status_command = 1;
>>+ task_req->in_flags.b.error_feature = 1;
>>+ task_req->in_flags.b.nsector = 1;
>>+
>>+ io_ports = task_req->io_ports;
>>+ io_ports[IDE_COMMAND_OFFSET] = args[0];
>>+ io_ports[IDE_SECTOR_OFFSET] = args[1];
>>+ io_ports[IDE_FEATURE_OFFSET] = args[2];
>>+ io_ports[IDE_NSECTOR_OFFSET] = args[3];
>
>
> Please handle WIN_SMART hack here (see execute_drive_cmd()),
> your next patch just kills it - it can break legacy applications.
>

Thanks, I missed that.

>
>>+ if (in_size) {
>>+ task_req->req_cmd = IDE_DRIVE_TASK_IN;
>>+ task_req->data_phase = TASKFILE_IN;
>>+ task_req->in_size = in_size;
>>+ } else {
>>+ task_req->req_cmd = IDE_DRIVE_TASK_NO_DATA;
>>+ task_req->data_phase = TASKFILE_NO_DATA;
>> }
>>- if (set_transfer(drive, &tfargs)) {
>>+
>>+ if (set_transfer(drive, io_ports)) {
>> xfer_rate = args[1];
>>- if (ide_ata66_check(drive, &tfargs))
>>+ if (ide_ata66_check(drive, io_ports)) {
>>+ ret = -EIO;
>> goto abort;
>>+ }
>> }
>>
>>- err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
>>+ orig_fs = get_fs();
>>+ set_fs(KERNEL_DS);
>>
>>- if (!err && xfer_rate) {
>>+ ret = ide_taskfile_ioctl(drive, cmd, (unsigned long)task_req);
>>+
>>+ set_fs(orig_fs);
>
>
> as ide_cmd_ioctl() only handles no-data and PIO-in protocols it should
> be easy to add missing bits here and get rid of calling ide_taskfile_ioctl()
>

Okay.

>
>>+ if (!ret && xfer_rate) {
>> /* active-retuning-calls future */
>> ide_set_xfer_rate(drive, xfer_rate);
>> ide_driveid_update(drive);
>> }
>>+
>>+ args[0] = io_ports[IDE_STATUS_OFFSET];
>>+ args[1] = io_ports[IDE_ERROR_OFFSET];
>>+ args[2] = io_ports[IDE_NSECTOR_OFFSET];
>>+ args[3] = 0;
>>+
>>+ if (copy_to_user((void __user *)arg, args, 4) ||
>>+ copy_to_user((void __user *)arg + 4,
>>+ (void *)task_req + sizeof(*task_req), in_size))
>>+ ret = -EFAULT;
>> abort:
>>- if (copy_to_user((void __user *)arg, argbuf, argsize))
>>- err = -EFAULT;
>>- if (argsize > 4)
>>- kfree(argbuf);
>>- return err;
>>+ kfree(task_req);
>>+ return ret;
>> }
>>
>> int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
>>Index: linux-ide-export/include/linux/ide.h
>>===================================================================
>>--- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.529986088 +0900
>>+++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:07.408843493 +0900
>>@@ -1289,14 +1289,6 @@ extern int ide_do_drive_cmd(ide_drive_t
>> */
>> extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
>>
>>-/*
>>- * Issue ATA command and wait for completion.
>>- * Use for implementing commands in kernel
>>- *
>>- * (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
>>- */
>>-extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
>>-
>> extern u32 ide_read_24(ide_drive_t *);
>>
>> extern void SELECT_DRIVE(ide_drive_t *);
>>@@ -1334,10 +1326,10 @@ int ide_task_ioctl(ide_drive_t *, unsign
>> extern int system_bus_clock(void);
>>
>> extern int ide_driveid_update(ide_drive_t *);
>>-extern int ide_ata66_check(ide_drive_t *, ide_task_t *);
>>+extern int ide_ata66_check(ide_drive_t *, task_ioreg_t *);
>> extern int ide_config_drive_speed(ide_drive_t *, u8);
>> extern u8 eighty_ninty_three (ide_drive_t *);
>>-extern int set_transfer(ide_drive_t *, ide_task_t *);
>>+extern int set_transfer(ide_drive_t *, task_ioreg_t *);
>> extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
>
>
> extern-s are not needed
>
>
>> extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);

Okay.

--
tejun

2005-02-04 01:24:09

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 25/29] ide: convert REQ_DRIVE_CMD to REQ_DRIVE_TASKFILE

Hello,

Bartlomiej Zolnierkiewicz wrote:
> On Wed, 2 Feb 2005 12:15:59 +0900, Tejun Heo <[email protected]> wrote:
>
>>>25_ide_taskfile_cmd.patch
>>>
>>> All in-kernel REQ_DRIVE_CMD users except for ide_cmd_ioctl()
>>> converted to use REQ_DRIVE_TASKFILE.
>>
>>Signed-off-by: Tejun Heo <[email protected]>
>>
>>Index: linux-ide-export/drivers/ide/ide-disk.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide-disk.c 2005-02-02 10:28:06.527986413 +0900
>>+++ linux-ide-export/drivers/ide/ide-disk.c 2005-02-02 10:28:07.204876587 +0900
>>@@ -750,7 +750,7 @@ static int set_multcount(ide_drive_t *dr
>> if (drive->special.b.set_multmode)
>> return -EBUSY;
>> ide_init_drive_cmd (&rq);
>>- rq.flags = REQ_DRIVE_CMD;
>>+ rq.flags = REQ_DRIVE_TASKFILE;
>
>
> Please instead fix ide_init_drive_cmd() to set REQ_DRIVE_TASKFILE
> and add set REQ_DRIVE_CMD only in ide_cmd_ioctl().
>

This is done in patch #28. If you don't like the ordering of the
patches, I can change the orders but I don't think that improves
anything. This order is as good as the other order.

>
>> drive->mult_req = arg;
>> drive->special.b.set_multmode = 1;
>> (void) ide_do_drive_cmd (drive, &rq, ide_wait);
>>Index: linux-ide-export/drivers/ide/ide.c
>>===================================================================
>>--- linux-ide-export.orig/drivers/ide/ide.c 2005-02-02 10:27:14.652402828 +0900
>>+++ linux-ide-export/drivers/ide/ide.c 2005-02-02 10:28:07.205876425 +0900
>>@@ -1255,6 +1255,7 @@ static int set_pio_mode (ide_drive_t *dr
>> if (drive->special.b.set_tune)
>> return -EBUSY;
>> ide_init_drive_cmd(&rq);
>>+ rq.flags = REQ_DRIVE_TASKFILE;
>> drive->tune_req = (u8) arg;
>> drive->special.b.set_tune = 1;
>> (void) ide_do_drive_cmd(drive, &rq, ide_wait);

Thanks.

--
tejun

Subject: Re: [PATCH 2.6.11-rc2 26/29] ide: map ide_cmd_ioctl() to ide_taskfile_ioctl()

On Fri, 04 Feb 2005 11:11:57 +0900, Tejun Heo <[email protected]> wrote:
> Bartlomiej Zolnierkiewicz wrote:
> > On Wed, 2 Feb 2005 12:10:37 +0900, Tejun Heo <[email protected]> wrote:
> >
> >>>26_ide_taskfile_cmd_ioctl.patch
> >>>
> >>> ide_cmd_ioctl() converted to use ide_taskfile_ioctl(). This
> >>> is the last user of REQ_DRIVE_CMD.
> >
> >
> > ide_cmd_ioctl() needs to map to taskfile transport not ide_taskfile_ioctl()
> >
> >
> >>Index: linux-ide-export/drivers/ide/ide-iops.c
> >>===================================================================
> >>--- linux-ide-export.orig/drivers/ide/ide-iops.c 2005-02-02 10:28:04.466320918 +0900
> >>+++ linux-ide-export/drivers/ide/ide-iops.c 2005-02-02 10:28:07.406843817 +0900
> >>@@ -648,11 +648,11 @@ u8 eighty_ninty_three (ide_drive_t *driv
> >>
> >> EXPORT_SYMBOL(eighty_ninty_three);
> >>
> >>-int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
> >>+int ide_ata66_check (ide_drive_t *drive, task_ioreg_t *regs)
> >
> >
> > nitpick: int ide_ata66_check()
> >
>
> meaning...?

silly minor nitpick - please drop extra space while at it:
int ide_ata66_check(ide_drive_t *drive, task_ioreg_t *regs)

> >
> >> {
> >>- if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> >>- (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
> >>- (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
> >>+ if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> >>+ (regs[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
> >>+ (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
> >
> >
> > nitpick: please drop brackets
> >
>
> Parenthese?

doh, yes

> >
> >> #ifndef CONFIG_IDEDMA_IVB
> >> if ((drive->id->hw_config & 0x6000) == 0) {
> >> #else /* !CONFIG_IDEDMA_IVB */
> >>@@ -678,11 +678,11 @@ int ide_ata66_check (ide_drive_t *drive,
> >> * 1 : Safe to update drive->id DMA registers.
> >> * 0 : OOPs not allowed.
> >> */
> >>-int set_transfer (ide_drive_t *drive, ide_task_t *args)
> >>+int set_transfer (ide_drive_t *drive, task_ioreg_t *regs)
> >
> >
> > nitpick: int set_transfer()
> >
>
> ??

extra space

> >
> >> {
> >>- if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> >>- (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
> >>- (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
> >>+ if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> >>+ (regs[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
> >>+ (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
> >
> >
> > nitpick: brackets
> >
>
> Parentheses?

yep

Subject: Re: [PATCH 2.6.11-rc2 26/29] ide: map ide_cmd_ioctl() to ide_taskfile_ioctl()

On Wed, 2 Feb 2005 12:10:37 +0900, Tejun Heo <[email protected]> wrote:
> > 26_ide_taskfile_cmd_ioctl.patch
> >
> > ide_cmd_ioctl() converted to use ide_taskfile_ioctl(). This
> > is the last user of REQ_DRIVE_CMD.

ide_cmd_ioctl() needs to map to taskfile transport not ide_taskfile_ioctl()

> Index: linux-ide-export/drivers/ide/ide-iops.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-iops.c 2005-02-02 10:28:04.466320918 +0900
> +++ linux-ide-export/drivers/ide/ide-iops.c 2005-02-02 10:28:07.406843817 +0900
> @@ -648,11 +648,11 @@ u8 eighty_ninty_three (ide_drive_t *driv
>
> EXPORT_SYMBOL(eighty_ninty_three);
>
> -int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
> +int ide_ata66_check (ide_drive_t *drive, task_ioreg_t *regs)

nitpick: int ide_ata66_check()

> {
> - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> - (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
> - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
> + if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> + (regs[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
> + (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {

nitpick: please drop brackets

> #ifndef CONFIG_IDEDMA_IVB
> if ((drive->id->hw_config & 0x6000) == 0) {
> #else /* !CONFIG_IDEDMA_IVB */
> @@ -678,11 +678,11 @@ int ide_ata66_check (ide_drive_t *drive,
> * 1 : Safe to update drive->id DMA registers.
> * 0 : OOPs not allowed.
> */
> -int set_transfer (ide_drive_t *drive, ide_task_t *args)
> +int set_transfer (ide_drive_t *drive, task_ioreg_t *regs)

nitpick: int set_transfer()

> {
> - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> - (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
> - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
> + if ((regs[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
> + (regs[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
> + (regs[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&

nitpick: brackets

> (drive->id->dma_ultra ||
> drive->id->dma_mword ||
> drive->id->dma_1word))
> Index: linux-ide-export/drivers/ide/ide-taskfile.c
> ===================================================================
> --- linux-ide-export.orig/drivers/ide/ide-taskfile.c 2005-02-02 10:28:06.751950074 +0900
> +++ linux-ide-export/drivers/ide/ide-taskfile.c 2005-02-02 10:28:07.407843655 +0900
> @@ -704,78 +704,90 @@ abort:
> return err;
> }
>
> -int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
> -{
> - struct request rq;
> - u8 buffer[4];
> -
> - if (!buf)
> - buf = buffer;
> - memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
> - ide_init_drive_cmd(&rq);
> - rq.buffer = buf;
> - *buf++ = cmd;
> - *buf++ = nsect;
> - *buf++ = feature;
> - *buf++ = sectors;
> - return ide_do_drive_cmd(drive, &rq, ide_wait);
> -}
> -
> -/*
> - * FIXME : this needs to map into at taskfile. <[email protected]>
> - */
> int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
> {
> - int err = 0;
> - u8 args[4], *argbuf = args;
> + u8 args[4];
> + ide_task_request_t *task_req;
> + task_ioreg_t *io_ports;
> u8 xfer_rate = 0;
> - int argsize = 4;
> - ide_task_t tfargs;
> + mm_segment_t orig_fs;
> + int in_size, ret;
>
> - if (NULL == (void *) arg) {
> + if ((void *)arg == NULL) {
> struct request rq;
> ide_init_drive_cmd(&rq);
> + rq.flags = REQ_DRIVE_TASKFILE;
> return ide_do_drive_cmd(drive, &rq, ide_wait);
> }
>
> if (copy_from_user(args, (void __user *)arg, 4))
> return -EFAULT;
>
> - memset(&tfargs, 0, sizeof(ide_task_t));
> - tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
> - tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
> - tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1];
> - tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00;
> - tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00;
> - tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00;
> - tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
> -
> - if (args[3]) {
> - argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
> - argbuf = kmalloc(argsize, GFP_KERNEL);
> - if (argbuf == NULL)
> - return -ENOMEM;
> - memcpy(argbuf, args, 4);
> + in_size = 4 * SECTOR_WORDS * args[3];
> +
> + task_req = kmalloc(sizeof(*task_req) + in_size, GFP_KERNEL);
> + if (task_req == NULL)
> + return -ENOMEM;
> +
> + memset(task_req, 0, sizeof(*task_req) + in_size);
> +
> + task_req->out_flags.b.status_command = 1;
> + task_req->out_flags.b.sector = 1;
> + task_req->out_flags.b.error_feature = 1;
> + task_req->out_flags.b.nsector = 1;
> +
> + task_req->in_flags.b.status_command = 1;
> + task_req->in_flags.b.error_feature = 1;
> + task_req->in_flags.b.nsector = 1;
> +
> + io_ports = task_req->io_ports;
> + io_ports[IDE_COMMAND_OFFSET] = args[0];
> + io_ports[IDE_SECTOR_OFFSET] = args[1];
> + io_ports[IDE_FEATURE_OFFSET] = args[2];
> + io_ports[IDE_NSECTOR_OFFSET] = args[3];

Please handle WIN_SMART hack here (see execute_drive_cmd()),
your next patch just kills it - it can break legacy applications.

> + if (in_size) {
> + task_req->req_cmd = IDE_DRIVE_TASK_IN;
> + task_req->data_phase = TASKFILE_IN;
> + task_req->in_size = in_size;
> + } else {
> + task_req->req_cmd = IDE_DRIVE_TASK_NO_DATA;
> + task_req->data_phase = TASKFILE_NO_DATA;
> }
> - if (set_transfer(drive, &tfargs)) {
> +
> + if (set_transfer(drive, io_ports)) {
> xfer_rate = args[1];
> - if (ide_ata66_check(drive, &tfargs))
> + if (ide_ata66_check(drive, io_ports)) {
> + ret = -EIO;
> goto abort;
> + }
> }
>
> - err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
> + orig_fs = get_fs();
> + set_fs(KERNEL_DS);
>
> - if (!err && xfer_rate) {
> + ret = ide_taskfile_ioctl(drive, cmd, (unsigned long)task_req);
> +
> + set_fs(orig_fs);

as ide_cmd_ioctl() only handles no-data and PIO-in protocols it should
be easy to add missing bits here and get rid of calling ide_taskfile_ioctl()

> + if (!ret && xfer_rate) {
> /* active-retuning-calls future */
> ide_set_xfer_rate(drive, xfer_rate);
> ide_driveid_update(drive);
> }
> +
> + args[0] = io_ports[IDE_STATUS_OFFSET];
> + args[1] = io_ports[IDE_ERROR_OFFSET];
> + args[2] = io_ports[IDE_NSECTOR_OFFSET];
> + args[3] = 0;
> +
> + if (copy_to_user((void __user *)arg, args, 4) ||
> + copy_to_user((void __user *)arg + 4,
> + (void *)task_req + sizeof(*task_req), in_size))
> + ret = -EFAULT;
> abort:
> - if (copy_to_user((void __user *)arg, argbuf, argsize))
> - err = -EFAULT;
> - if (argsize > 4)
> - kfree(argbuf);
> - return err;
> + kfree(task_req);
> + return ret;
> }
>
> int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
> Index: linux-ide-export/include/linux/ide.h
> ===================================================================
> --- linux-ide-export.orig/include/linux/ide.h 2005-02-02 10:28:06.529986088 +0900
> +++ linux-ide-export/include/linux/ide.h 2005-02-02 10:28:07.408843493 +0900
> @@ -1289,14 +1289,6 @@ extern int ide_do_drive_cmd(ide_drive_t
> */
> extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
>
> -/*
> - * Issue ATA command and wait for completion.
> - * Use for implementing commands in kernel
> - *
> - * (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
> - */
> -extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
> -
> extern u32 ide_read_24(ide_drive_t *);
>
> extern void SELECT_DRIVE(ide_drive_t *);
> @@ -1334,10 +1326,10 @@ int ide_task_ioctl(ide_drive_t *, unsign
> extern int system_bus_clock(void);
>
> extern int ide_driveid_update(ide_drive_t *);
> -extern int ide_ata66_check(ide_drive_t *, ide_task_t *);
> +extern int ide_ata66_check(ide_drive_t *, task_ioreg_t *);
> extern int ide_config_drive_speed(ide_drive_t *, u8);
> extern u8 eighty_ninty_three (ide_drive_t *);
> -extern int set_transfer(ide_drive_t *, ide_task_t *);
> +extern int set_transfer(ide_drive_t *, task_ioreg_t *);
> extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);

extern-s are not needed

> extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);

2005-02-04 08:39:29

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH 2.6.11-rc2 11/29] ide: add ide_drive_t.sleeping

On Fri, Feb 04 2005, Tejun Heo wrote:
> Bartlomiej Zolnierkiewicz wrote:
> >On Thu, 3 Feb 2005 14:32:29 +0100, Jens Axboe <[email protected]> wrote:
> >
> >>On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> >>
> >>>On Thu, 3 Feb 2005 12:37:10 +0100, Jens Axboe <[email protected]> wrote:
> >>>
> >>>>On Thu, Feb 03 2005, Bartlomiej Zolnierkiewicz wrote:
> >>>>
> >>>>>On Wed, 2 Feb 2005 11:54:48 +0900, Tejun Heo <[email protected]> wrote:
> >>>>>
> >>>>>>>11_ide_drive_sleeping_fix.patch
> >>>>>>>
> >>>>>>> ide_drive_t.sleeping field added. 0 in sleep field used to
> >>>>>>> indicate inactive sleeping but because 0 is a valid jiffy
> >>>>>>> value, though slim, there's a chance that something can go
> >>>>>>> weird. And while at it, explicit jiffy comparisons are
> >>>>>>> converted to use time_{after|before} macros.
> >>>>>
> >>>>>Same question as for "add ide_hwgroup_t.polling" patch.
> >>>>>AFAICS drive->sleep is either '0' or 'timeout + jiffies' (always > 0)
> >>>>
> >>>>Hmm, what if jiffies + timeout == 0?
> >>>
> >>>Hm, jiffies is unsigned and timeout is always > 0
> >>>but this is still possible if jiffies + timeout wraps, right?
> >>
> >>Precisely, if jiffies is exactly 'timeout' away from wrapping to 0 it
> >>could happen. So I think the fix looks sane.
> >
> >
> >agreed
>
> Actually, jiffies is initialized to INITIAL_JIFFIES which is defined in
> such a way that it overflows after 5 min after boot to help finding bugs
> related to jiffies wrap. So, the chance of something weird happening in
> the bugs fixed in patches 11 and 12 isn't that exteremely slim. :-)

And repeat after 49 days, sure. But the odds of it triggering are still
extremely slim :)

--
Jens Axboe