Commit a925c40f authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] IDE 17 (not just cleanup)

This is actually an attempt to remove some stall code from
this driver. However if some *real* users complain (Not just
the usuall: "Hey - if someone!" but the "Hey I'm using this!")
I'm all open to reenable it. Since I prepared this patch
yerstoday it doesn't contain the ide_module.h fixup. This will
follow later.

- Don't use the convoluted byte type in ide-pci.c. Just use the proper
   u8instead.

- Move ide_get_or_set_dma_base to the only place where it's used and
   reorganize the code there by killing the unnecessary
   CONFIG_BLK_DEV_IDEDMA_FORCED configuration option.

- Remove unfunctional CONFIG_PKT_TASK_IOCTL code.

- Kill unused ALTSTAT_SCREW_UP code.

- Tons of dead code removed from ide-taskfile.c (#if 0 #endif and
   friends)

- Remove unused IDE_DEBUG macro as well as lots of other name space
   pollution from ide.h.

- Start using the ide_lock spin-lock for protecting access to data
   structures instead of the excessive interrupt disabling games.

- Shorten the proc ouput of the piix initialization module.

- Remove special /proc tape "name" output from ide-tape.c. This was
   redundant data which should only show up on syslog anyway.

- Kill the REALLY_FAST_IO undef from the ide.h. This was a mistake
   present since far too many years in this driver. The proper way to
   deal with broken systems is to define REALLY_SLOW_IO in system
   dependent headers or particular driver files.  We can always
   reintroduce it easy if real users will complain, since OUT_BYTE() and
   similar can be used as hooks. But I don't expect anybody reporting
   about this. Even on the most broken IDE chip in the world (cmd640
   at VLB) undefining this *always* worked for me. Nearly all the code
   pieces in the ide driver code *reverted* it's effects explicitly
   anyway.

- Remove the obsolete CONFIG_BLK_DEV_4DRIVES support. This was supposed
   to support 4 drivers attached at one channel on some older chipsets,
   in esp. Tekram 690CD, in the last century. They where all supposed to
   work at a register set starting at the base address 0x1f0.  Before
   complaining that this is removing functionality, please note that this
   must have been broken for already quite a long time, since the ide
   driver didn't contain the special device selection methods implicated
   by this any longer.  It didn't scan   this port too if PCI host chip
   support was enabled (as it is in all those distributions around
   there).  On the other hand this is the most prominent case of
   incoherent use of the mate member in the struct hwif_s. And please
   think about how big the probability is, that there are systems out
   there, where there are actually 4 drivers on such a channel?

- Streamline module initialization code by removing one shoot functions.

- Make the WAIT_READY value used in case of CONFIG_APM or
   CONFIG_APM_MODULE the default, since this is what really reflects the
   behavior of modern drives. It won't hurt any other case and finally
   removing it is reducing the necessary coverage for overall driver code
   testing/analysis.

- Move the IDE_LARGE_SEEK macro to the only place where it's actually
   used. Replace the IDE_MIN() and IDE_MAX() drivers with the obvious.
   Remove unused SPLIT_WORD and MAKE WORD from the local header.

- Remove CMD640_DUMP_REGS from global scope, since there is no
   development done on this any longer. Finally, the way the host chip
   initialization routines are called changed in the time between allows
   this to remain fully local to the host chip driver in question.

- Some spell checking of comments in the code. (Yeep I have extended my
   Vim to do this the "Word" way with nice undercurl lines... mozilla
   remains to be fixed...)
parent 6aa0c79e
...@@ -249,7 +249,6 @@ CONFIG_BLK_DEV_IDEPCI=y ...@@ -249,7 +249,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y CONFIG_BLK_DEV_IDEDMA=y
......
...@@ -94,8 +94,6 @@ ...@@ -94,8 +94,6 @@
* device can't do DMA handshaking for some stupid reason. We don't need to do that. * device can't do DMA handshaking for some stupid reason. We don't need to do that.
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
......
...@@ -252,7 +252,6 @@ CONFIG_BLK_DEV_IDEPCI=y ...@@ -252,7 +252,6 @@ CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y CONFIG_BLK_DEV_IDEDMA=y
......
...@@ -285,7 +285,6 @@ CONFIG_BLK_DEV_IDEPCI=y ...@@ -285,7 +285,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_IDEDMA_ONLYDISK=y CONFIG_IDEDMA_ONLYDISK=y
CONFIG_BLK_DEV_IDEDMA=y CONFIG_BLK_DEV_IDEDMA=y
......
...@@ -581,13 +581,6 @@ CONFIG_IDE_CHIPSETS ...@@ -581,13 +581,6 @@ CONFIG_IDE_CHIPSETS
People with SCSI-only systems can say N here. People with SCSI-only systems can say N here.
CONFIG_BLK_DEV_4DRIVES
Certain older chipsets, including the Tekram 690CD, use a single set
of I/O ports at 0x1f0 to control up to four drives, instead of the
customary two drives per port. Support for this can be enabled at
runtime using the "ide0=four" kernel boot parameter if you say Y
here.
CONFIG_BLK_DEV_ALI14XX CONFIG_BLK_DEV_ALI14XX
This driver is enabled at runtime using the "ide0=ali14xx" kernel This driver is enabled at runtime using the "ide0=ali14xx" kernel
boot parameter. It enables support for the secondary IDE interface boot parameter. It enables support for the secondary IDE interface
...@@ -807,11 +800,6 @@ CONFIG_IDEDISK_STROKE ...@@ -807,11 +800,6 @@ CONFIG_IDEDISK_STROKE
If you are unsure, say N here. If you are unsure, say N here.
CONFIG_BLK_DEV_IDEDMA_FORCED
This is an old piece of lost code from Linux 2.0 Kernels.
Generally say N here.
CONFIG_IDEDMA_ONLYDISK CONFIG_IDEDMA_ONLYDISK
This is used if you know your ATAPI Devices are going to fail DMA This is used if you know your ATAPI Devices are going to fail DMA
Transfers. Transfers.
......
...@@ -45,7 +45,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -45,7 +45,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
dep_bool ' Force enable legacy 2.0.X HOSTS to use DMA' CONFIG_BLK_DEV_IDEDMA_FORCED $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
...@@ -141,7 +140,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -141,7 +140,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS
if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
comment 'Note: most of these also require special kernel boot parameters' comment 'Note: most of these also require special kernel boot parameters'
bool ' Generic 4 drives/port support' CONFIG_BLK_DEV_4DRIVES
bool ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX bool ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX
bool ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278 bool ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278
bool ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B bool ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B
......
/* /*
* linux/drivers/ide/ali14xx.c Version 0.03 Feb 09, 1996
*
* Copyright (C) 1996 Linus Torvalds & author (see below) * Copyright (C) 1996 Linus Torvalds & author (see below)
*/ */
...@@ -37,8 +35,6 @@ ...@@ -37,8 +35,6 @@
* mode 4 for a while now with no trouble.) -Derek * mode 4 for a while now with no trouble.) -Derek
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
......
/* /*
* linux/drivers/ide/cmd640.c Version 1.02 Sep 01, 1996
*
* Copyright (C) 1995-1996 Linus Torvalds & authors (see below) * Copyright (C) 1995-1996 Linus Torvalds & authors (see below)
*/ */
/* /*
* Original authors: abramov@cecmow.enet.dec.com (Igor Abramov) * Original authors: abramov@cecmow.enet.dec.com (Igor Abramov)
* mlord@pobox.com (Mark Lord) * mlord@pobox.com (Mark Lord)
* *
* See linux/MAINTAINERS for address of current maintainer. * See linux/MAINTAINERS for address of current maintainer.
* *
...@@ -98,7 +96,6 @@ ...@@ -98,7 +96,6 @@
* (patch courtesy of Zoltan Hidvegi) * (patch courtesy of Zoltan Hidvegi)
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#define CMD640_PREFETCH_MASKS 1 #define CMD640_PREFETCH_MASKS 1
#include <linux/config.h> #include <linux/config.h>
......
...@@ -238,7 +238,7 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ ...@@ -238,7 +238,7 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
*/ */
if (channel) { if (channel) {
drive->drive_data = setup_count; drive->drive_data = setup_count;
setup_count = IDE_MAX(drives[0].drive_data, drives[1].drive_data); setup_count = max(drives[0].drive_data, drives[1].drive_data);
cmdprintk("Secondary interface, setup_count = %d\n", setup_count); cmdprintk("Secondary interface, setup_count = %d\n", setup_count);
} }
......
/* /*
* linux/drivers/ide/dtc2278.c Version 0.02 Feb 10, 1996
*
* Copyright (C) 1996 Linus Torvalds & author (see below) * Copyright (C) 1996 Linus Torvalds & author (see below)
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
......
/* /*
* linux/drivers/ide/ht6560b.c Version 0.07 Feb 1, 2000
*
* Copyright (C) 1995-2000 Linus Torvalds & author (see below) * Copyright (C) 1995-2000 Linus Torvalds & author (see below)
*/
/*
* *
* Version 0.01 Initial version hacked out of ide.c * Version 0.01 Initial version hacked out of ide.c
* *
...@@ -36,8 +31,6 @@ ...@@ -36,8 +31,6 @@
#define HT6560B_VERSION "v0.07" #define HT6560B_VERSION "v0.07"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -1633,6 +1633,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) ...@@ -1633,6 +1633,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
return startstop; return startstop;
} }
#define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
/**************************************************************************** /****************************************************************************
* cdrom driver request routine. * cdrom driver request routine.
......
/* /*
* linux/drivers/ide/ide-disk.c Version 1.13 Nov 28, 2001
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below) * Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/ *
/*
* Mostly written by Mark Lord <mlord@pobox.com> * Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il> * and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org> * and Andre Hedrick <andre@linux-ide.org>
...@@ -34,8 +30,6 @@ ...@@ -34,8 +30,6 @@
#define IDEDISK_VERSION "1.13" #define IDEDISK_VERSION "1.13"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -720,7 +714,7 @@ static int get_smart_values(ide_drive_t *drive, byte *buf) ...@@ -720,7 +714,7 @@ static int get_smart_values(ide_drive_t *drive, byte *buf)
taskfile.low_cylinder = SMART_LCYL_PASS; taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS; taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART; taskfile.command = WIN_SMART;
(void) smart_enable(drive); smart_enable(drive);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf); return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
} }
...@@ -735,7 +729,7 @@ static int get_smart_thresholds(ide_drive_t *drive, byte *buf) ...@@ -735,7 +729,7 @@ static int get_smart_thresholds(ide_drive_t *drive, byte *buf)
taskfile.low_cylinder = SMART_LCYL_PASS; taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS; taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART; taskfile.command = WIN_SMART;
(void) smart_enable(drive); smart_enable(drive);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf); return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
} }
...@@ -844,7 +838,7 @@ static int write_cache (ide_drive_t *drive, int arg) ...@@ -844,7 +838,7 @@ static int write_cache (ide_drive_t *drive, int arg)
if (!(drive->id->cfs_enable_2 & 0x3000)) if (!(drive->id->cfs_enable_2 & 0x3000))
return 1; return 1;
(void) ide_wait_taskfile(drive, &taskfile, &hobfile, NULL); ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
drive->wcache = arg; drive->wcache = arg;
return 0; return 0;
} }
...@@ -870,7 +864,7 @@ static int set_acoustic (ide_drive_t *drive, int arg) ...@@ -870,7 +864,7 @@ static int set_acoustic (ide_drive_t *drive, int arg)
taskfile.sector_count = arg; taskfile.sector_count = arg;
taskfile.command = WIN_SETFEATURES; taskfile.command = WIN_SETFEATURES;
(void) ide_wait_taskfile(drive, &taskfile, &hobfile, NULL); ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
drive->acoustic = arg; drive->acoustic = arg;
return 0; return 0;
} }
......
/* /*
* linux/drivers/ide/ide-dma.c Version 4.10 June 9, 2000
*
* Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
*/ */
...@@ -15,7 +13,7 @@ ...@@ -15,7 +13,7 @@
/* /*
* This module provides support for the bus-master IDE DMA functions * This module provides support for the bus-master IDE DMA functions
* of various PCI chipsets, including the Intel PIIX (i82371FB for * of various PCI chipsets, including the Intel PIIX (i82371FB for
* the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and
* 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset) * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset)
* ("PIIX" stands for "PCI ISA IDE Xcellerator"). * ("PIIX" stands for "PCI ISA IDE Xcellerator").
* *
...@@ -73,8 +71,6 @@ ...@@ -73,8 +71,6 @@
* check_drive_lists(ide_drive_t *drive, int good_bad) * check_drive_lists(ide_drive_t *drive, int good_bad)
* *
* ATA-66/100 and recovery functions, I forgot the rest...... * ATA-66/100 and recovery functions, I forgot the rest......
* SELECT_READ_WRITE(hwif,drive,func) for active tuning based on IO direction.
*
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -426,7 +422,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad) ...@@ -426,7 +422,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad)
return 0; return 0;
} }
int report_drive_dmaing (ide_drive_t *drive) static int report_drive_dmaing (ide_drive_t *drive)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
...@@ -606,7 +602,10 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -606,7 +602,10 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_read: case ide_dma_read:
reading = 1 << 3; reading = 1 << 3;
case ide_dma_write: case ide_dma_write:
SELECT_READ_WRITE(hwif,drive,func); /* active tuning based on IO direction */
if (hwif->rwproc)
hwif->rwproc(drive, func);
if (!(count = ide_build_dmatable(drive, func))) if (!(count = ide_build_dmatable(drive, func)))
return 1; /* try PIO instead of DMA */ return 1; /* try PIO instead of DMA */
outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
...@@ -617,9 +616,9 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -617,9 +616,9 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
return 0; return 0;
#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT #ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* issue cmd to drive */ ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* issue cmd to drive */
#else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ #else
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ #endif
if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) && if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
(drive->addressing == 1)) { (drive->addressing == 1)) {
ide_task_t *args = HWGROUP(drive)->rq->special; ide_task_t *args = HWGROUP(drive)->rq->special;
...@@ -728,9 +727,8 @@ int ide_release_dma (ide_hwif_t *hwif) ...@@ -728,9 +727,8 @@ int ide_release_dma (ide_hwif_t *hwif)
} }
/* /*
* This can be called for a dynamically installed interface. Don't __init it * This can be called for a dynamically installed interface. Don't __init it
*/ */
void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports) void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)
{ {
printk(" %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1); printk(" %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1);
...@@ -768,81 +766,3 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p ...@@ -768,81 +766,3 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
dma_alloc_failure: dma_alloc_failure:
printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n"); printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n");
} }
/*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
*/
unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name)
{
unsigned long dma_base = 0;
struct pci_dev *dev = hwif->pci_dev;
#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
int second_chance = 0;
second_chance_to_dma:
#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
if (hwif->mate && hwif->mate->dma_base) {
dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
} else {
dma_base = pci_resource_start(dev, 4);
if (!dma_base) {
printk("%s: dma_base is invalid (0x%04lx)\n", name, dma_base);
dma_base = 0;
}
}
#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
if ((!dma_base) && (!second_chance)) {
unsigned long set_bmiba = 0;
second_chance++;
switch(dev->vendor) {
case PCI_VENDOR_ID_AL:
set_bmiba = DEFAULT_BMALIBA; break;
case PCI_VENDOR_ID_VIA:
set_bmiba = DEFAULT_BMCRBA; break;
case PCI_VENDOR_ID_INTEL:
set_bmiba = DEFAULT_BMIBA; break;
default:
return dma_base;
}
pci_write_config_dword(dev, 0x20, set_bmiba|1);
goto second_chance_to_dma;
}
#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
if (dma_base) {
if (extra) /* PDC20246, PDC20262, HPT343, & HPT366 */
request_region(dma_base+16, extra, name);
dma_base += hwif->channel ? 8 : 0;
hwif->dma_extra = extra;
switch(dev->device) {
case PCI_DEVICE_ID_AL_M5219:
case PCI_DEVICE_ID_AMD_VIPER_7409:
case PCI_DEVICE_ID_CMD_643:
outb(inb(dma_base+2) & 0x60, dma_base+2);
if (inb(dma_base+2) & 0x80) {
printk("%s: simplex device: DMA forced\n", name);
}
break;
default:
/*
* If the device claims "simplex" DMA,
* this means only one of the two interfaces
* can be trusted with DMA at any point in time.
* So we should enable DMA only on one of the
* two interfaces.
*/
if ((inb(dma_base+2) & 0x80)) { /* simplex device? */
if ((!hwif->drives[0].present && !hwif->drives[1].present) ||
(hwif->mate && hwif->mate->dma_base)) {
printk("%s: simplex device: DMA disabled\n", name);
dma_base = 0;
}
}
}
}
return dma_base;
}
...@@ -1113,7 +1113,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p ...@@ -1113,7 +1113,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
pc->retries++; pc->retries++;
pc->actually_transferred=0; /* We haven't transferred any data yet */ pc->actually_transferred=0; /* We haven't transferred any data yet */
pc->current_position=pc->buffer; pc->current_position=pc->buffer;
bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024); bcount.all = min(pc->request_transfer, 63 * 1024);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) { if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
......
/* /*
* linux/drivers/ide/ide-pci.c Version 1.05 June 9, 2000
*
* Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org>
*
* Copyright (c) 1995-1998 Mark Lord * Copyright (c) 1995-1998 Mark Lord
*
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
*/ */
...@@ -168,9 +166,9 @@ extern void ide_dmacapable_via82cxxx(ide_hwif_t *, unsigned long); ...@@ -168,9 +166,9 @@ extern void ide_dmacapable_via82cxxx(ide_hwif_t *, unsigned long);
#endif #endif
typedef struct ide_pci_enablebit_s { typedef struct ide_pci_enablebit_s {
byte reg; /* byte pci reg holding the enable-bit */ u8 reg; /* pci configuration register holding the enable-bit */
byte mask; /* mask to isolate the enable-bit */ u8 mask; /* mask used to isolate the enable-bit */
byte val; /* value of masked reg when "enabled" */ u8 val; /* expected value of masked register when "enabled" */
} ide_pci_enablebit_t; } ide_pci_enablebit_t;
/* Flags used to untangle quirk handling. /* Flags used to untangle quirk handling.
...@@ -230,9 +228,10 @@ static ide_pci_device_t pci_chipsets[] __initdata = { ...@@ -230,9 +228,10 @@ static ide_pci_device_t pci_chipsets[] __initdata = {
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48, ATA_F_IRQ | ATA_F_DMA }, {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48, ATA_F_IRQ | ATA_F_DMA },
# endif # endif
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA }, {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
/* Promise used a different PCI ident for the raid card apparently to try and /* Promise used a different PCI identification for the raid card
prevent Linux detecting it and using our own raid code. We want to detect * apparently to try and prevent Linux detecting it and using our own
it for the ataraid drivers, so we have to list both here.. */ * raid code. We want to detect it for the ataraid drivers, so we have
* to list both here.. */
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA }, {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA }, {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA }, {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
...@@ -319,7 +318,7 @@ static ide_pci_device_t pci_chipsets[] __initdata = { ...@@ -319,7 +318,7 @@ static ide_pci_device_t pci_chipsets[] __initdata = {
{0, 0, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; {0, 0, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }};
/* /*
* This allows offboard ide-pci cards the enable a BIOS, verify interrupt * This allows off board ide-pci cards the enable a BIOS, verify interrupt
* settings of split-mirror pci-config space, place chipset into init-mode, * settings of split-mirror pci-config space, place chipset into init-mode,
* and/or preserve an interrupt if the card is not native ide support. * and/or preserve an interrupt if the card is not native ide support.
*/ */
...@@ -335,7 +334,7 @@ static unsigned int __init trust_pci_irq(ide_pci_device_t *d, struct pci_dev *de ...@@ -335,7 +334,7 @@ static unsigned int __init trust_pci_irq(ide_pci_device_t *d, struct pci_dev *de
* Match a PCI IDE port against an entry in ide_hwifs[], * Match a PCI IDE port against an entry in ide_hwifs[],
* based on io_base port if possible. * based on io_base port if possible.
*/ */
static ide_hwif_t __init *lookup_hwif (unsigned long io_base, byte bootable, const char *name) static ide_hwif_t __init *lookup_hwif (unsigned long io_base, int bootable, const char *name)
{ {
int h; int h;
ide_hwif_t *hwif; ide_hwif_t *hwif;
...@@ -399,7 +398,8 @@ static ide_hwif_t __init *lookup_hwif (unsigned long io_base, byte bootable, con ...@@ -399,7 +398,8 @@ static ide_hwif_t __init *lookup_hwif (unsigned long io_base, byte bootable, con
static int __init setup_pci_baseregs (struct pci_dev *dev, const char *name) static int __init setup_pci_baseregs (struct pci_dev *dev, const char *name)
{ {
byte reg, progif = 0; u8 reg;
u8 progif = 0;
/* /*
* Place both IDE interfaces into PCI "native" mode: * Place both IDE interfaces into PCI "native" mode:
...@@ -431,10 +431,111 @@ static int __init setup_pci_baseregs (struct pci_dev *dev, const char *name) ...@@ -431,10 +431,111 @@ static int __init setup_pci_baseregs (struct pci_dev *dev, const char *name)
return 0; return 0;
} }
#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
*/
static unsigned long __init get_dma_base(ide_hwif_t *hwif, int extra, const char *name)
{
unsigned long dma_base = 0;
struct pci_dev *dev = hwif->pci_dev;
/*
* If we are on the second channel, the dma base address will be one
* entry away from the primary interface.
*/
if (hwif->mate && hwif->mate->dma_base)
dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
else
dma_base = pci_resource_start(dev, 4);
if (!dma_base)
return 0;
if (extra) /* PDC20246, PDC20262, HPT343, & HPT366 */
request_region(dma_base + 16, extra, name);
dma_base += hwif->channel ? 8 : 0;
hwif->dma_extra = extra;
if ((dev->vendor == PCI_VENDOR_ID_AL && dev->device == PCI_DEVICE_ID_AL_M5219) ||
(dev->vendor == PCI_VENDOR_ID_AMD && dev->device == PCI_DEVICE_ID_AMD_VIPER_7409) ||
(dev->vendor == PCI_VENDOR_ID_CMD && dev->device == PCI_DEVICE_ID_CMD_643)) {
outb(inb(dma_base + 2) & 0x60, dma_base+2);
if (inb(dma_base + 2) & 0x80)
printk(KERN_INFO "%s: simplex device: DMA forced\n", name);
} else {
/*
* If the device claims "simplex" DMA, this means only one of
* the two interfaces can be trusted with DMA at any point in
* time. So we should enable DMA only on one of the two
* interfaces.
*/
if ((inb(dma_base + 2) & 0x80)) {
if ((!hwif->drives[0].present && !hwif->drives[1].present) ||
(hwif->mate && hwif->mate->dma_base)) {
printk("%s: simplex device: DMA disabled\n", name);
dma_base = 0;
}
}
}
return dma_base;
}
/*
* Setup DMA transfers on a channel.
*/
static void __init setup_channel_dma(ide_hwif_t *hwif, struct pci_dev *dev,
ide_pci_device_t *d,
int port,
u8 class_rev,
int pciirq, ide_hwif_t **mate,
int autodma, unsigned short *pcicmd)
{
unsigned long dma_base;
if (d->flags & ATA_F_NOADMA)
autodma = 0;
if (autodma)
hwif->autodma = 1;
if (!((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))))
return;
dma_base = get_dma_base(hwif, (!*mate && d->extra) ? d->extra : 0, dev->name);
if (dma_base && !(*pcicmd & PCI_COMMAND_MASTER)) {
/*
* Set up BM-DMA capability (PnP BIOS should have done this already)
*/
if (!(d->vendor == PCI_VENDOR_ID_CYRIX && d->device == PCI_DEVICE_ID_CYRIX_5530_IDE))
hwif->autodma = 0; /* default DMA off if we had to configure it here */
pci_write_config_word(dev, PCI_COMMAND, *pcicmd | PCI_COMMAND_MASTER);
if (pci_read_config_word(dev, PCI_COMMAND, pcicmd) || !(*pcicmd & PCI_COMMAND_MASTER)) {
printk("%s: %s error updating PCICMD\n", hwif->name, dev->name);
dma_base = 0;
}
}
if (dma_base) {
if (d->dma_init)
d->dma_init(hwif, dma_base);
else
ide_setup_dma(hwif, dma_base, 8);
} else
printk("%s: %s Bus-Master DMA was disabled by BIOS\n", hwif->name, dev->name);
}
#endif
/* /*
* Setup a particular port on an ATA host controller. * Setup a particular port on an ATA host controller.
* *
* This get's called once for the master and for the slave interface. * This gets called once for the master and for the slave interface.
*/ */
static int __init setup_host_channel(struct pci_dev *dev, static int __init setup_host_channel(struct pci_dev *dev,
ide_pci_device_t *d, ide_pci_device_t *d,
...@@ -528,9 +629,9 @@ static int __init setup_host_channel(struct pci_dev *dev, ...@@ -528,9 +629,9 @@ static int __init setup_host_channel(struct pci_dev *dev,
} }
} }
/* Hard wired IRQ lines on UMC chips and no DMA transfers.*/ /* Cross wired IRQ lines on UMC chips and no DMA transfers.*/
if (d->flags & ATA_F_FIXIRQ) { if (d->flags & ATA_F_FIXIRQ) {
hwif->irq = hwif->channel ? 15 : 14; hwif->irq = port ? 15 : 14;
goto no_dma; goto no_dma;
} }
if (d->flags & ATA_F_NODMA) if (d->flags & ATA_F_NODMA)
...@@ -543,53 +644,22 @@ static int __init setup_host_channel(struct pci_dev *dev, ...@@ -543,53 +644,22 @@ static int __init setup_host_channel(struct pci_dev *dev,
if (d->ata66_check) if (d->ata66_check)
hwif->udma_four = d->ata66_check(hwif); hwif->udma_four = d->ata66_check(hwif);
} }
#ifdef CONFIG_BLK_DEV_IDEDMA
if (d->flags & ATA_F_NOADMA)
autodma = 0;
if (autodma)
hwif->autodma = 1;
if ((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) {
unsigned long dma_base;
dma_base = ide_get_or_set_dma_base(hwif, (!*mate && d->extra) ? d->extra : 0, dev->name);
if (dma_base && !(*pcicmd & PCI_COMMAND_MASTER)) {
/* #ifdef CONFIG_BLK_DEV_IDEDMA
* Set up BM-DMA capability (PnP BIOS should have done this already) setup_channel_dma(hwif, dev, d, port, class_rev, pciirq, mate, autodma, pcicmd);
*/
if (!(d->vendor == PCI_VENDOR_ID_CYRIX && d->device == PCI_DEVICE_ID_CYRIX_5530_IDE))
hwif->autodma = 0; /* default DMA off if we had to configure it here */
pci_write_config_word(dev, PCI_COMMAND, *pcicmd | PCI_COMMAND_MASTER);
if (pci_read_config_word(dev, PCI_COMMAND, pcicmd) || !(*pcicmd & PCI_COMMAND_MASTER)) {
printk("%s: %s error updating PCICMD\n", hwif->name, dev->name);
dma_base = 0;
}
}
if (dma_base) {
if (d->dma_init)
d->dma_init(hwif, dma_base);
else /* FIXME: use a generic device descriptor instead */
ide_setup_dma(hwif, dma_base, 8);
} else {
printk("%s: %s Bus-Master DMA was disabled by BIOS\n", hwif->name, dev->name);
}
}
#endif #endif
no_dma: no_dma:
if (d->init_hwif) /* Call chipset-specific routine for each enabled hwif */ if (d->init_hwif) /* Call chipset-specific routine for each enabled hwif */
d->init_hwif(hwif); d->init_hwif(hwif);
*mate = hwif; *mate = hwif;
/* we are done */
return 0; return 0;
} }
/* /*
* Looks at the primary/secondary chanells on a PCI IDE device and, if they * Looks at the primary/secondary channels on a PCI IDE device and, if they
* are enabled, prepares the IDE driver for use with them. This generic code * are enabled, prepares the IDE driver for use with them. This generic code
* works for most PCI chipsets. * works for most PCI chipsets.
* *
...@@ -631,10 +701,11 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) ...@@ -631,10 +701,11 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */ if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */
/* /*
* PnP BIOS was *supposed* to have set this device up for us, * PnP BIOS was *supposed* to have set this device up for us,
* but we can do it ourselves, so long as the BIOS has assigned an IRQ * but we can do it ourselves, so long as the BIOS has assigned
* (or possibly the device is using a "legacy header" for IRQs). * an IRQ (or possibly the device is using a "legacy header"
* Maybe the user deliberately *disabled* the device, * for IRQs). Maybe the user deliberately *disabled* the
* but we'll eventually ignore it again if no drives respond. * device, but we'll eventually ignore it again if no drives
* respond.
*/ */
if (tried_config++ if (tried_config++
|| setup_pci_baseregs(dev, dev->name) || setup_pci_baseregs(dev, dev->name)
...@@ -666,7 +737,7 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) ...@@ -666,7 +737,7 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) { if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) {
/* By rights we want to ignore these, but the Promise Fastrak /* By rights we want to ignore these, but the Promise Fastrak
people have some strange ideas about proprietary so we have people have some strange ideas about proprietary so we have
to act otherwise on those. The supertrak however we need to act otherwise on those. The Supertrak however we need
to skip */ to skip */
if (d->vendor == PCI_VENDOR_ID_PROMISE && d->device == PCI_DEVICE_ID_PROMISE_20265) { if (d->vendor == PCI_VENDOR_ID_PROMISE && d->device == PCI_DEVICE_ID_PROMISE_20265) {
printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n"); printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n");
...@@ -683,7 +754,7 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) ...@@ -683,7 +754,7 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
printk("%s: not 100%% native mode: will probe irqs later\n", dev->name); printk("%s: not 100%% native mode: will probe irqs later\n", dev->name);
/* /*
* This allows offboard ide-pci cards the enable a BIOS, * This allows off board ide-pci cards the enable a BIOS,
* verify interrupt settings of split-mirror pci-config * verify interrupt settings of split-mirror pci-config
* space, place chipset into init-mode, and/or preserve * space, place chipset into init-mode, and/or preserve
* an interrupt if the card is not native ide support. * an interrupt if the card is not native ide support.
...@@ -693,10 +764,10 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) ...@@ -693,10 +764,10 @@ static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
else else
pciirq = trust_pci_irq(d, dev); pciirq = trust_pci_irq(d, dev);
} else if (tried_config) { } else if (tried_config) {
printk("%s: will probe irqs later\n", dev->name); printk("%s: will probe IRQs later\n", dev->name);
pciirq = 0; pciirq = 0;
} else if (!pciirq) { } else if (!pciirq) {
printk("%s: bad irq (%d): will probe later\n", dev->name, pciirq); printk("%s: bad IRQ (%d): will probe later\n", dev->name, pciirq);
pciirq = 0; pciirq = 0;
} else { } else {
if (d->init_chipset) if (d->init_chipset)
...@@ -732,7 +803,8 @@ static void __init pdc20270_device_order_fixup (struct pci_dev *dev, ide_pci_dev ...@@ -732,7 +803,8 @@ static void __init pdc20270_device_order_fixup (struct pci_dev *dev, ide_pci_dev
if ((findev->vendor == dev->vendor) && if ((findev->vendor == dev->vendor) &&
(findev->device == dev->device) && (findev->device == dev->device) &&
(PCI_SLOT(findev->devfn) & 2)) { (PCI_SLOT(findev->devfn) & 2)) {
byte irq = 0, irq2 = 0; u8 irq = 0;
u8 irq2 = 0;
dev2 = findev; dev2 = findev;
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2); pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2);
...@@ -808,7 +880,7 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic ...@@ -808,7 +880,7 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
} }
/* /*
* This finds all PCI IDE controllers and calls appriopriate initialization * This finds all PCI IDE controllers and calls appropriate initialization
* functions for them. * functions for them.
*/ */
static void __init ide_scan_pcidev(struct pci_dev *dev) static void __init ide_scan_pcidev(struct pci_dev *dev)
......
/* /*
* linux/drivers/ide/ide-probe.c Version 1.07 March 18, 2001
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below) * Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/ *
/*
* Mostly written by Mark Lord <mlord@pobox.com> * Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il> * and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org> * and Andre Hedrick <andre@linux-ide.org>
...@@ -26,11 +22,9 @@ ...@@ -26,11 +22,9 @@
* with new flag : drive->ata_flash : 1; * with new flag : drive->ata_flash : 1;
* Version 1.06 stream line request queue and prep for cascade project. * Version 1.06 stream line request queue and prep for cascade project.
* Version 1.07 max_sect <= 255; slower disks would get behind and * Version 1.07 max_sect <= 255; slower disks would get behind and
* then fall over when they get to 256. Paul G. * then fall over when they get to 256. Paul G.
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -94,7 +88,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -94,7 +88,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
goto err_misc; goto err_misc;
} }
#endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */ #endif
/* /*
* WIN_IDENTIFY returns little-endian info, * WIN_IDENTIFY returns little-endian info,
...@@ -128,7 +122,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -128,7 +122,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
printk(" -- not supported on 2nd Promise port\n"); printk(" -- not supported on 2nd Promise port\n");
goto err_misc; goto err_misc;
} }
#endif /* CONFIG_BLK_DEV_PDC4030 */ #endif
switch (type) { switch (type) {
case ATA_FLOPPY: case ATA_FLOPPY:
if (!strstr(id->model, "CD-ROM")) { if (!strstr(id->model, "CD-ROM")) {
...@@ -186,7 +180,11 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -186,7 +180,11 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
} }
drive->type = ATA_DISK; drive->type = ATA_DISK;
printk("ATA DISK drive\n"); printk("ATA DISK drive\n");
QUIRK_LIST(HWIF(drive),drive);
/* Initialize our quirk list. */
if (HWIF(drive)->quirkproc)
drive->quirk_list = HWIF(drive)->quirkproc(drive);
return; return;
err_misc: err_misc:
...@@ -282,24 +280,15 @@ static int try_to_identify (ide_drive_t *drive, byte cmd) ...@@ -282,24 +280,15 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
if (autoprobe) { if (autoprobe) {
int irq; int irq;
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */ OUT_BYTE(drive->ctl | 0x02, IDE_CONTROL_REG); /* mask device irq */
(void) GET_STAT(); /* clear drive IRQ */ GET_STAT(); /* clear drive IRQ */
udelay(5); udelay(5);
irq = probe_irq_off(cookie); irq = probe_irq_off(cookie);
if (!HWIF(drive)->irq) { if (!HWIF(drive)->irq) {
if (irq > 0) { if (irq > 0)
HWIF(drive)->irq = irq; HWIF(drive)->irq = irq;
} else { /* Mmmm.. multiple IRQs.. don't know which was ours */ else /* Mmmm.. multiple IRQs.. don't know which was ours */
printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie); printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie);
#ifdef CONFIG_BLK_DEV_CMD640
#ifdef CMD640_DUMP_REGS
if (HWIF(drive)->chipset == ide_cmd640) {
printk("%s: Hmmm.. probably a driver problem.\n", drive->name);
CMD640_DUMP_REGS;
}
#endif /* CMD640_DUMP_REGS */
#endif /* CONFIG_BLK_DEV_CMD640 */
}
} }
} }
return retval; return retval;
...@@ -522,11 +511,11 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -522,11 +511,11 @@ static void probe_hwif (ide_hwif_t *hwif)
if (hwif->noprobe) if (hwif->noprobe)
return; return;
if ((hwif->chipset != ide_4drives || !hwif->mate->present) && if (
#if CONFIG_BLK_DEV_PDC4030 #if CONFIG_BLK_DEV_PDC4030
(hwif->chipset != ide_pdc4030 || hwif->channel == 0) && (hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
#endif /* CONFIG_BLK_DEV_PDC4030 */ #endif
(hwif_check_regions(hwif))) { hwif_check_regions(hwif)) {
int msgout = 0; int msgout = 0;
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
...@@ -552,9 +541,7 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -552,9 +541,7 @@ static void probe_hwif (ide_hwif_t *hwif)
probe_for_drive (drive); probe_for_drive (drive);
if (drive->present && !hwif->present) { if (drive->present && !hwif->present) {
hwif->present = 1; hwif->present = 1;
if (hwif->chipset != ide_4drives || !hwif->mate->present) { hwif_register(hwif);
hwif_register(hwif);
}
} }
} }
if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
...@@ -582,32 +569,6 @@ static void probe_hwif (ide_hwif_t *hwif) ...@@ -582,32 +569,6 @@ static void probe_hwif (ide_hwif_t *hwif)
} }
} }
#if MAX_HWIFS > 1
/*
* save_match() is used to simplify logic in init_irq() below.
*
* A loophole here is that we may not know about a particular
* hwif's irq until after that hwif is actually probed/initialized..
* This could be a problem for the case where an hwif is on a
* dual interface that requires serialization (eg. cmd640) and another
* hwif using one of the same irqs is initialized beforehand.
*
* This routine detects and reports such situations, but does not fix them.
*/
static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
{
ide_hwif_t *m = *match;
if (m && m->hwgroup && m->hwgroup != new->hwgroup) {
if (!new->hwgroup)
return;
printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name);
}
if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
*match = new;
}
#endif /* MAX_HWIFS > 1 */
/* /*
* init request queue * init request queue
*/ */
...@@ -636,6 +597,33 @@ static void ide_init_queue(ide_drive_t *drive) ...@@ -636,6 +597,33 @@ static void ide_init_queue(ide_drive_t *drive)
blk_queue_max_phys_segments(q, PRD_ENTRIES); blk_queue_max_phys_segments(q, PRD_ENTRIES);
} }
#if MAX_HWIFS > 1
/*
* This is used to simplify logic in init_irq() below.
*
* A loophole here is that we may not know about a particular hwif's irq until
* after that hwif is actually probed/initialized.. This could be a problem
* for the case where an hwif is on a dual interface that requires
* serialization (eg. cmd640) and another hwif using one of the same irqs is
* initialized beforehand.
*
* This routine detects and reports such situations, but does not fix them.
*/
static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
{
ide_hwif_t *m = *match;
if (m && m->hwgroup && m->hwgroup != new->hwgroup) {
if (!new->hwgroup)
return;
printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name);
}
if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
*match = new;
}
#endif
/* /*
* This routine sets up the irq for an ide interface, and creates a new * This routine sets up the irq for an ide interface, and creates a new
* hwgroup for the irq/hwif if none was previously assigned. * hwgroup for the irq/hwif if none was previously assigned.
...@@ -656,15 +644,14 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -656,15 +644,14 @@ static int init_irq (ide_hwif_t *hwif)
ide_hwgroup_t *hwgroup, *new_hwgroup; ide_hwgroup_t *hwgroup, *new_hwgroup;
ide_hwif_t *match = NULL; ide_hwif_t *match = NULL;
/* Allocate the buffer and potentially sleep first */ /* Allocate the buffer and potentially sleep first */
new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL); new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
spin_lock_irqsave(&ide_lock, flags);
hwif->hwgroup = NULL; hwif->hwgroup = NULL;
#if MAX_HWIFS > 1 #if MAX_HWIFS > 1
/* /*
* Group up with any other hwifs that share our irq(s). * Group up with any other hwifs that share our irq(s).
...@@ -674,9 +661,8 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -674,9 +661,8 @@ static int init_irq (ide_hwif_t *hwif)
if (h->hwgroup) { /* scan only initialized hwif's */ if (h->hwgroup) { /* scan only initialized hwif's */
if (hwif->irq == h->irq) { if (hwif->irq == h->irq) {
hwif->sharing_irq = h->sharing_irq = 1; hwif->sharing_irq = h->sharing_irq = 1;
if (hwif->chipset != ide_pci || h->chipset != ide_pci) { if (hwif->chipset != ide_pci || h->chipset != ide_pci)
save_match(hwif, h, &match); save_match(hwif, h, &match);
}
} }
if (hwif->serialized) { if (hwif->serialized) {
if (hwif->mate && hwif->mate->irq == h->irq) if (hwif->mate && hwif->mate->irq == h->irq)
...@@ -688,7 +674,7 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -688,7 +674,7 @@ static int init_irq (ide_hwif_t *hwif)
} }
} }
} }
#endif /* MAX_HWIFS > 1 */ #endif
/* /*
* If we are still without a hwgroup, then form a new one * If we are still without a hwgroup, then form a new one
*/ */
...@@ -699,7 +685,7 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -699,7 +685,7 @@ static int init_irq (ide_hwif_t *hwif)
} else { } else {
hwgroup = new_hwgroup; hwgroup = new_hwgroup;
if (!hwgroup) { if (!hwgroup) {
restore_flags(flags); /* all CPUs */ spin_unlock_irqrestore(&ide_lock, flags);
return 1; return 1;
} }
memset(hwgroup, 0, sizeof(ide_hwgroup_t)); memset(hwgroup, 0, sizeof(ide_hwgroup_t));
...@@ -719,9 +705,9 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -719,9 +705,9 @@ static int init_irq (ide_hwif_t *hwif)
if (!match || match->irq != hwif->irq) { if (!match || match->irq != hwif->irq) {
#ifdef CONFIG_IDEPCI_SHARE_IRQ #ifdef CONFIG_IDEPCI_SHARE_IRQ
int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_SHIRQ : SA_INTERRUPT; int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_SHIRQ : SA_INTERRUPT;
#else /* !CONFIG_IDEPCI_SHARE_IRQ */ #else
int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
#endif /* CONFIG_IDEPCI_SHARE_IRQ */ #endif
if (hwif->io_ports[IDE_CONTROL_OFFSET]) if (hwif->io_ports[IDE_CONTROL_OFFSET])
OUT_BYTE(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */ OUT_BYTE(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */
...@@ -729,13 +715,13 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -729,13 +715,13 @@ static int init_irq (ide_hwif_t *hwif)
if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) { if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) {
if (!match) if (!match)
kfree(hwgroup); kfree(hwgroup);
restore_flags(flags); /* all CPUs */ spin_unlock_irqrestore(&ide_lock, flags);
return 1; return 1;
} }
} }
/* /*
* Everything is okay, so link us into the hwgroup * Everything is okay, so link us into the hwgroup.
*/ */
hwif->hwgroup = hwgroup; hwif->hwgroup = hwgroup;
hwif->next = hwgroup->hwif->next; hwif->next = hwgroup->hwif->next;
...@@ -757,7 +743,7 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -757,7 +743,7 @@ static int init_irq (ide_hwif_t *hwif)
printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name); printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);
#endif #endif
} }
restore_flags(flags); /* all CPUs; safe now that hwif->hwgroup is set up */ spin_unlock_irqrestore(&ide_lock, flags);
#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name, printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
......
...@@ -161,7 +161,6 @@ static int proc_ide_read_imodel ...@@ -161,7 +161,6 @@ static int proc_ide_read_imodel
case ide_trm290: name = "trm290"; break; case ide_trm290: name = "trm290"; break;
case ide_cmd646: name = "cmd646"; break; case ide_cmd646: name = "cmd646"; break;
case ide_cy82c693: name = "cy82c693"; break; case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break; case ide_pmac: name = "mac-io"; break;
default: name = "(unknown)"; break; default: name = "(unknown)"; break;
} }
...@@ -298,8 +297,8 @@ static int proc_ide_write_settings ...@@ -298,8 +297,8 @@ static int proc_ide_write_settings
} }
if (*p != ':') if (*p != ':')
goto parse_error; goto parse_error;
len = IDE_MIN(p - start, MAX_LEN); len = min(p - start, MAX_LEN);
strncpy(name, start, IDE_MIN(len, MAX_LEN)); strncpy(name, start, min(len, MAX_LEN));
name[len] = 0; name[len] = 0;
if (n > 0) { if (n > 0) {
...@@ -307,7 +306,7 @@ static int proc_ide_write_settings ...@@ -307,7 +306,7 @@ static int proc_ide_write_settings
p++; p++;
} else } else
goto parse_error; goto parse_error;
digits = 0; digits = 0;
while (n > 0 && (d = ide_getdigit(*p)) >= 0) { while (n > 0 && (d = ide_getdigit(*p)) >= 0) {
val = (val * 10) + d; val = (val * 10) + d;
......
...@@ -1504,7 +1504,7 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne ...@@ -1504,7 +1504,7 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
count = IDE_MIN (bio->bi_size - pc->b_count, bcount); count = min(bio->bi_size - pc->b_count, bcount);
atapi_input_bytes (drive, bio_data(bio) + pc->b_count, count); atapi_input_bytes (drive, bio_data(bio) + pc->b_count, count);
bcount -= count; bcount -= count;
pc->b_count += bio->bi_size; pc->b_count += bio->bi_size;
...@@ -1529,7 +1529,7 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign ...@@ -1529,7 +1529,7 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
count = IDE_MIN (pc->b_count, bcount); count = min(pc->b_count, bcount);
atapi_output_bytes (drive, bio_data(bio), count); atapi_output_bytes (drive, bio_data(bio), count);
bcount -= count; bcount -= count;
pc->b_data += count; pc->b_data += count;
...@@ -1559,7 +1559,7 @@ static void idetape_update_buffers (idetape_pc_t *pc) ...@@ -1559,7 +1559,7 @@ static void idetape_update_buffers (idetape_pc_t *pc)
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
count = IDE_MIN (bio->bi_size, bcount); count = min(bio->bi_size, bcount);
pc->b_count = count; pc->b_count = count;
if (pc->b_count == bio->bi_size) if (pc->b_count == bio->bi_size)
bio = bio->bi_next; bio = bio->bi_next;
...@@ -1759,8 +1759,8 @@ static void idetape_increase_max_pipeline_stages (ide_drive_t *drive) ...@@ -1759,8 +1759,8 @@ static void idetape_increase_max_pipeline_stages (ide_drive_t *drive)
#endif /* IDETAPE_DEBUG_LOG */ #endif /* IDETAPE_DEBUG_LOG */
tape->max_stages += increase; tape->max_stages += increase;
tape->max_stages = IDE_MAX(tape->max_stages, tape->min_pipeline); tape->max_stages = max(tape->max_stages, tape->min_pipeline);
tape->max_stages = IDE_MIN(tape->max_stages, tape->max_pipeline); tape->max_stages = min(tape->max_stages, tape->max_pipeline);
} }
/* /*
...@@ -2084,7 +2084,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) ...@@ -2084,7 +2084,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
if (!status.b.drq) { /* No more interrupts */ if (!status.b.drq) { /* No more interrupts */
cmd_time = (jiffies - tape->cmd_start_time) * 1000 / HZ; cmd_time = (jiffies - tape->cmd_start_time) * 1000 / HZ;
tape->max_cmd_time = IDE_MAX(cmd_time, tape->max_cmd_time); tape->max_cmd_time = max(cmd_time, tape->max_cmd_time);
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred); printk (KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred);
...@@ -2442,7 +2442,7 @@ static void calculate_speeds(ide_drive_t *drive) ...@@ -2442,7 +2442,7 @@ static void calculate_speeds(ide_drive_t *drive)
tape->uncontrolled_pipeline_head_time = jiffies; tape->uncontrolled_pipeline_head_time = jiffies;
} }
} }
tape->pipeline_head_speed = IDE_MAX(tape->uncontrolled_pipeline_head_speed, tape->controlled_pipeline_head_speed); tape->pipeline_head_speed = max(tape->uncontrolled_pipeline_head_speed, tape->controlled_pipeline_head_speed);
if (tape->speed_control == 0) { if (tape->speed_control == 0) {
tape->max_insert_speed = 5000; tape->max_insert_speed = 5000;
} else if (tape->speed_control == 1) { } else if (tape->speed_control == 1) {
...@@ -2459,7 +2459,7 @@ static void calculate_speeds(ide_drive_t *drive) ...@@ -2459,7 +2459,7 @@ static void calculate_speeds(ide_drive_t *drive)
(tape->pipeline_head_speed * full / 100 - tape->pipeline_head_speed * empty / 100) * tape->nr_pending_stages / tape->max_stages; (tape->pipeline_head_speed * full / 100 - tape->pipeline_head_speed * empty / 100) * tape->nr_pending_stages / tape->max_stages;
} else } else
tape->max_insert_speed = tape->speed_control; tape->max_insert_speed = tape->speed_control;
tape->max_insert_speed = IDE_MAX(tape->max_insert_speed, 500); tape->max_insert_speed = max(tape->max_insert_speed, 500);
} }
static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive) static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive)
...@@ -2920,7 +2920,7 @@ static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t ...@@ -2920,7 +2920,7 @@ static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
count = IDE_MIN (bio->bi_size - tape->b_count, n); count = min(bio->bi_size - tape->b_count, n);
copy_from_user (bio_data(bio) + tape->b_count, buf, count); copy_from_user (bio_data(bio) + tape->b_count, buf, count);
n -= count; n -= count;
bio->bi_size += count; bio->bi_size += count;
...@@ -2946,7 +2946,7 @@ static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape ...@@ -2946,7 +2946,7 @@ static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
count = IDE_MIN (tape->b_count, n); count = min(tape->b_count, n);
copy_to_user (buf, tape->b_data, count); copy_to_user (buf, tape->b_data, count);
n -= count; n -= count;
tape->b_data += count; tape->b_data += count;
...@@ -3878,7 +3878,7 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive) ...@@ -3878,7 +3878,7 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
printk(KERN_INFO "ide-tape: bug, bio NULL\n"); printk(KERN_INFO "ide-tape: bug, bio NULL\n");
break; break;
} }
min = IDE_MIN(i, bio->bi_size - atomic_read(&bio->bi_cnt)); min = min(i, bio->bi_size - atomic_read(&bio->bi_cnt));
memset(bio_data(bio) + bio->bi_size, 0, min); memset(bio_data(bio) + bio->bi_size, 0, min);
atomic_add(min, &bio->bi_cnt); atomic_add(min, &bio->bi_cnt);
i -= min; i -= min;
...@@ -4149,11 +4149,11 @@ static void idetape_pad_zeros (ide_drive_t *drive, int bcount) ...@@ -4149,11 +4149,11 @@ static void idetape_pad_zeros (ide_drive_t *drive, int bcount)
while (bcount) { while (bcount) {
bio = tape->merge_stage->bio; bio = tape->merge_stage->bio;
count = IDE_MIN (tape->stage_size, bcount); count = min(tape->stage_size, bcount);
bcount -= count; bcount -= count;
blocks = count / tape->tape_block_size; blocks = count / tape->tape_block_size;
while (count) { while (count) {
atomic_set(&bio->bi_cnt, IDE_MIN (count, bio->bi_size)); atomic_set(&bio->bi_cnt, min(count, bio->bi_size));
memset (bio_data(bio), 0, bio->bi_size); memset (bio_data(bio), 0, bio->bi_size);
count -= atomic_read(&bio->bi_cnt); count -= atomic_read(&bio->bi_cnt);
bio = bio->bi_next; bio = bio->bi_next;
...@@ -4596,7 +4596,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char *buf, ...@@ -4596,7 +4596,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char *buf,
if (count == 0) if (count == 0)
return (0); return (0);
if (tape->merge_stage_size) { if (tape->merge_stage_size) {
actually_read = IDE_MIN (tape->merge_stage_size, count); actually_read = min(tape->merge_stage_size, count);
idetape_copy_stage_to_user (tape, buf, tape->merge_stage, actually_read); idetape_copy_stage_to_user (tape, buf, tape->merge_stage, actually_read);
buf += actually_read; buf += actually_read;
tape->merge_stage_size -= actually_read; tape->merge_stage_size -= actually_read;
...@@ -4615,7 +4615,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char *buf, ...@@ -4615,7 +4615,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char *buf,
bytes_read=idetape_add_chrdev_read_request (drive, tape->capabilities.ctl); bytes_read=idetape_add_chrdev_read_request (drive, tape->capabilities.ctl);
if (bytes_read <= 0) if (bytes_read <= 0)
goto finish; goto finish;
temp = IDE_MIN (count, bytes_read); temp = min(count, bytes_read);
idetape_copy_stage_to_user (tape, buf, tape->merge_stage, temp); idetape_copy_stage_to_user (tape, buf, tape->merge_stage, temp);
actually_read += temp; actually_read += temp;
tape->merge_stage_size = bytes_read-temp; tape->merge_stage_size = bytes_read-temp;
...@@ -4890,7 +4890,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char *buf, ...@@ -4890,7 +4890,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char *buf,
tape->merge_stage_size = 0; tape->merge_stage_size = 0;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
actually_written = IDE_MIN (tape->stage_size - tape->merge_stage_size, count); actually_written = min(tape->stage_size - tape->merge_stage_size, count);
idetape_copy_stage_from_user (tape, tape->merge_stage, buf, actually_written); idetape_copy_stage_from_user (tape, tape->merge_stage, buf, actually_written);
buf += actually_written; buf += actually_written;
tape->merge_stage_size += actually_written; tape->merge_stage_size += actually_written;
...@@ -6049,7 +6049,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -6049,7 +6049,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
* Select the "best" DSC read/write polling frequency * Select the "best" DSC read/write polling frequency
* and pipeline size. * and pipeline size.
*/ */
speed = IDE_MAX (tape->capabilities.speed, tape->capabilities.max_speed); speed = max(tape->capabilities.speed, tape->capabilities.max_speed);
tape->max_stages = speed * 1000 * 10 / tape->stage_size; tape->max_stages = speed * 1000 * 10 / tape->stage_size;
...@@ -6075,7 +6075,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -6075,7 +6075,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
* Ensure that the number we got makes sense; limit * Ensure that the number we got makes sense; limit
* it within IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. * it within IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX.
*/ */
tape->best_dsc_rw_frequency = IDE_MAX (IDE_MIN (t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN); tape->best_dsc_rw_frequency = max(min(t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN);
printk (KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, %dkB pipeline, %lums tDSC%s\n", printk (KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, %dkB pipeline, %lums tDSC%s\n",
drive->name, tape->name, tape->capabilities.speed, (tape->capabilities.buffer_size * 512) / tape->stage_size, drive->name, tape->name, tape->capabilities.speed, (tape->capabilities.buffer_size * 512) / tape->stage_size,
tape->stage_size / 1024, tape->max_stages * tape->stage_size / 1024, tape->stage_size / 1024, tape->max_stages * tape->stage_size / 1024,
......
/* /*
* linux/drivers/ide/ide-taskfile.c Version 0.20 Oct 11, 2000
*
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* *
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
*
* IDE_DEBUG(__LINE__);
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -48,7 +44,7 @@ ...@@ -48,7 +44,7 @@
static inline char *ide_map_rq(struct request *rq, unsigned long *flags) static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
{ {
if (rq->bio) if (rq->bio)
return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
else else
return rq->buffer + task_rq_offset(rq); return rq->buffer + task_rq_offset(rq);
} }
...@@ -60,13 +56,6 @@ static inline void ide_unmap_rq(struct request *rq, char *to, ...@@ -60,13 +56,6 @@ static inline void ide_unmap_rq(struct request *rq, char *to,
bio_kunmap_irq(to, flags); bio_kunmap_irq(to, flags);
} }
inline u32 task_read_24 (ide_drive_t *drive)
{
return (IN_BYTE(IDE_HCYL_REG)<<16) |
(IN_BYTE(IDE_LCYL_REG)<<8) |
IN_BYTE(IDE_SECTOR_REG);
}
static void ata_bswap_data (void *buffer, int wcount) static void ata_bswap_data (void *buffer, int wcount)
{ {
u16 *p = buffer; u16 *p = buffer;
...@@ -85,12 +74,13 @@ static void ata_bswap_data (void *buffer, int wcount) ...@@ -85,12 +74,13 @@ static void ata_bswap_data (void *buffer, int wcount)
* of the sector count register location, with interrupts disabled * of the sector count register location, with interrupts disabled
* to ensure that the reads all happen together. * to ensure that the reads all happen together.
*/ */
static inline void task_vlb_sync (ide_ioreg_t port) { static inline void task_vlb_sync(ide_ioreg_t port)
(void) IN_BYTE (port); {
(void) IN_BYTE (port); IN_BYTE (port);
(void) IN_BYTE (port); IN_BYTE (port);
IN_BYTE (port);
} }
#endif /* SUPPORT_VLB_SYNC */ #endif
/* /*
* This is used for most PIO data transfers *from* the IDE interface * This is used for most PIO data transfers *from* the IDE interface
...@@ -121,7 +111,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -121,7 +111,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
insl(IDE_DATA_REG, buffer, wcount); insl(IDE_DATA_REG, buffer, wcount);
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
} else } else
#endif /* SUPPORT_VLB_SYNC */ #endif
insl(IDE_DATA_REG, buffer, wcount); insl(IDE_DATA_REG, buffer, wcount);
} else { } else {
#if SUPPORT_SLOW_DATA_PORTS #if SUPPORT_SLOW_DATA_PORTS
...@@ -132,7 +122,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -132,7 +122,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
*ptr++ = inw_p(IDE_DATA_REG); *ptr++ = inw_p(IDE_DATA_REG);
} }
} else } else
#endif /* SUPPORT_SLOW_DATA_PORTS */ #endif
insw(IDE_DATA_REG, buffer, wcount<<1); insw(IDE_DATA_REG, buffer, wcount<<1);
} }
} }
...@@ -161,7 +151,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -161,7 +151,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
outsl(IDE_DATA_REG, buffer, wcount); outsl(IDE_DATA_REG, buffer, wcount);
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
} else } else
#endif /* SUPPORT_VLB_SYNC */ #endif
outsl(IDE_DATA_REG, buffer, wcount); outsl(IDE_DATA_REG, buffer, wcount);
} else { } else {
#if SUPPORT_SLOW_DATA_PORTS #if SUPPORT_SLOW_DATA_PORTS
...@@ -172,7 +162,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -172,7 +162,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
outw_p(*ptr++, IDE_DATA_REG); outw_p(*ptr++, IDE_DATA_REG);
} }
} else } else
#endif /* SUPPORT_SLOW_DATA_PORTS */ #endif
outsw(IDE_DATA_REG, buffer, wcount<<1); outsw(IDE_DATA_REG, buffer, wcount<<1);
} }
} }
...@@ -273,7 +263,90 @@ int drive_is_ready (ide_drive_t *drive) ...@@ -273,7 +263,90 @@ int drive_is_ready (ide_drive_t *drive)
return 1; /* drive ready: *might* be interrupting */ return 1; /* drive ready: *might* be interrupting */
} }
ide_startstop_t bio_mulout_intr (ide_drive_t *drive); /*
* Polling wait until the drive is ready.
*
* Stuff the first sector(s) by implicitly calling the handler driectly
* therafter.
*/
void ata_poll_drive_ready(ide_drive_t *drive)
{
int i;
if (drive_is_ready(drive))
return;
/* FIXME: Replace hard-coded 100, what about error handling?
*/
for (i = 0; i < 100; ++i) {
if (drive_is_ready(drive))
break;
}
}
static ide_startstop_t bio_mulout_intr(ide_drive_t *drive);
/*
* Handler for command write multiple
* Called directly from execute_drive_cmd for the first bunch of sectors,
* afterwards only by the ISR
*/
static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
{
unsigned int msect, nsect;
byte stat = GET_STAT();
byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
char *pBuf = NULL;
unsigned long flags;
/*
* (ks/hs): Handle last IRQ on multi-sector transfer,
* occurs after all data was sent in this chunk
*/
if (rq->current_nr_sectors == 0) {
if (stat & (ERR_STAT|DRQ_STAT))
return ide_error(drive, "task_mulout_intr", stat);
/*
* there may be more, ide_do_request will restart it if
* necessary
*/
ide_end_request(drive, 1);
return ide_stopped;
}
if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_mulout_intr", stat);
}
/* no data yet, so wait for another interrupt */
if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
/* (ks/hs): See task_mulin_intr */
msect = drive->mult_count;
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
pBuf = ide_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
{ {
task_struct_t *taskfile = (task_struct_t *) task->tfRegister; task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
...@@ -311,7 +384,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -311,7 +384,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_set_handler (drive, task->handler, WAIT_CMD, NULL); ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG); OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
/* /*
* warning check for race between handler and prehandler for * Warning check for race between handler and prehandler for
* writing first block of data. however since we are well * writing first block of data. however since we are well
* inside the boundaries of the seek, we should be okay. * inside the boundaries of the seek, we should be okay.
*/ */
...@@ -366,310 +439,12 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct ...@@ -366,310 +439,12 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct
} }
} }
#if 0
ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
{
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
struct hd_driveid *id = drive->id;
/*
* (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.all = IDE_TASKFILE_STD_OUT_FLAGS;
if ((id->command_set_2 & 0x0400) &&
(id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) {
task->tf_out_flags.all != (IDE_HOB_STD_OUT_FLAGS << 8);
}
}
if (task->tf_in_flags.all == 0) {
task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if ((id->command_set_2 & 0x0400) &&
(id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) {
task->tf_in_flags.all != (IDE_HOB_STD_IN_FLAGS << 8);
}
}
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(HWIF(drive), drive, 0);
if (task->tf_out_flags.b.data) {
unsigned short data = taskfile->data + (hobfile->data << 8);
OUT_WORD (data, IDE_DATA_REG);
}
/* (KS) send hob registers first */
if (task->tf_out_flags.b.nsector_hob)
OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
if (task->tf_out_flags.b.sector_hob)
OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
if (task->tf_out_flags.b.lcyl_hob)
OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
if (task->tf_out_flags.b.hcyl_hob)
OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
/* (KS) Send now the standard registers */
if (task->tf_out_flags.b.error_feature)
OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
/* refers to number of sectors to transfer */
if (task->tf_out_flags.b.nsector)
OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
/* refers to sector offset or start sector */
if (task->tf_out_flags.b.sector)
OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
if (task->tf_out_flags.b.lcyl)
OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
if (task->tf_out_flags.b.hcyl)
OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
/*
* (KS) Do not modify the specified taskfile. We want to have a
* universal pass through, so we must execute ALL specified values.
*
* (KS) The drive head register is mandatory.
* Don't care about the out flags !
*/
OUT_BYTE(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
if (task->handler != NULL) {
ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
/*
* warning check for race between handler and prehandler for
* writing first block of data. however since we are well
* inside the boundaries of the seek, we should be okay.
*/
if (task->prehandler != NULL) {
return task->prehandler(drive, task->rq);
}
} else {
/* for dma commands we down set the handler */
if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
}
return ide_started;
}
#endif
#if 0
/*
* Error reporting, in human readable form (luxurious, but a memory hog).
*/
byte taskfile_dump_status (ide_drive_t *drive, const char *msg, byte stat)
{
unsigned long flags;
byte err = 0;
__save_flags (flags); /* local CPU only */
ide__sti(); /* local CPU only */
printk("%s: %s: status=0x%02x", drive->name, msg, stat);
#if FANCY_STATUS_DUMPS
printk(" { ");
if (stat & BUSY_STAT)
printk("Busy ");
else {
if (stat & READY_STAT) printk("DriveReady ");
if (stat & WRERR_STAT) printk("DeviceFault ");
if (stat & SEEK_STAT) printk("SeekComplete ");
if (stat & DRQ_STAT) printk("DataRequest ");
if (stat & ECC_STAT) printk("CorrectedError ");
if (stat & INDEX_STAT) printk("Index ");
if (stat & ERR_STAT) printk("Error ");
}
printk("}");
#endif /* FANCY_STATUS_DUMPS */
printk("\n");
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
err = GET_ERR();
printk("%s: %s: error=0x%02x", drive->name, msg, err);
#if FANCY_STATUS_DUMPS
if (drive->media == ide_disk) {
printk(" { ");
if (err & ABRT_ERR) printk("DriveStatusError ");
if (err & ICRC_ERR) printk("%s", (err & ABRT_ERR) ? "BadCRC " : "BadSector ");
if (err & ECC_ERR) printk("UncorrectableError ");
if (err & ID_ERR) printk("SectorIdNotFound ");
if (err & TRK0_ERR) printk("TrackZeroNotFound ");
if (err & MARK_ERR) printk("AddrMarkNotFound ");
printk("}");
if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
if ((drive->id->command_set_2 & 0x0400) &&
(drive->id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) {
__u64 sectors = 0;
u32 low = 0, high = 0;
low = task_read_24(drive);
OUT_BYTE(0x80, IDE_CONTROL_REG);
high = task_read_24(drive);
sectors = ((__u64)high << 24) | low;
printk(", LBAsect=%lld", sectors);
} else {
byte cur = IN_BYTE(IDE_SELECT_REG);
if (cur & 0x40) { /* using LBA? */
printk(", LBAsect=%ld", (unsigned long)
((cur&0xf)<<24)
|(IN_BYTE(IDE_HCYL_REG)<<16)
|(IN_BYTE(IDE_LCYL_REG)<<8)
| IN_BYTE(IDE_SECTOR_REG));
} else {
printk(", CHS=%d/%d/%d",
(IN_BYTE(IDE_HCYL_REG)<<8) +
IN_BYTE(IDE_LCYL_REG),
cur & 0xf,
IN_BYTE(IDE_SECTOR_REG));
}
}
if (HWGROUP(drive)->rq)
printk(", sector=%llu", (__u64) HWGROUP(drive)->rq->sector);
}
}
#endif /* FANCY_STATUS_DUMPS */
printk("\n");
}
__restore_flags (flags); /* local CPU only */
return err;
}
/*
* Clean up after success/failure of an explicit taskfile operation.
*/
void ide_end_taskfile (ide_drive_t *drive, byte stat, byte err)
{
unsigned long flags;
struct request *rq;
ide_task_t *args;
task_ioreg_t command;
spin_lock_irqsave(&ide_lock, flags);
rq = HWGROUP(drive)->rq;
spin_unlock_irqrestore(&ide_lock, flags);
args = (ide_task_t *) rq->special;
command = args->tfRegister[IDE_COMMAND_OFFSET];
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
args->tfRegister[IDE_ERROR_OFFSET] = err;
args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG);
args->tfRegister[IDE_SECTOR_OFFSET] = IN_BYTE(IDE_SECTOR_REG);
args->tfRegister[IDE_LCYL_OFFSET] = IN_BYTE(IDE_LCYL_REG);
args->tfRegister[IDE_HCYL_OFFSET] = IN_BYTE(IDE_HCYL_REG);
args->tfRegister[IDE_SELECT_OFFSET] = IN_BYTE(IDE_SELECT_REG);
args->tfRegister[IDE_STATUS_OFFSET] = stat;
if ((drive->id->command_set_2 & 0x0400) &&
(drive->id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) {
OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
args->hobRegister[IDE_FEATURE_OFFSET_HOB] = IN_BYTE(IDE_FEATURE_REG);
args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = IN_BYTE(IDE_NSECTOR_REG);
args->hobRegister[IDE_SECTOR_OFFSET_HOB] = IN_BYTE(IDE_SECTOR_REG);
args->hobRegister[IDE_LCYL_OFFSET_HOB] = IN_BYTE(IDE_LCYL_REG);
args->hobRegister[IDE_HCYL_OFFSET_HOB] = IN_BYTE(IDE_HCYL_REG);
}
/* taskfile_settings_update(drive, args, command); */
spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
end_that_request_last(rq);
spin_unlock_irqrestore(&ide_lock, flags);
}
/*
* try_to_flush_leftover_data() is invoked in response to a drive
* unexpectedly having its DRQ_STAT bit set. As an alternative to
* resetting the drive, this routine tries to clear the condition
* by read a sector's worth of data from the drive. Of course,
* this may not help if the drive is *waiting* for data from *us*.
*/
void task_try_to_flush_leftover_data (ide_drive_t *drive)
{
int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
if (drive->media != ide_disk)
return;
while (i > 0) {
u32 buffer[16];
unsigned int wcount = (i > 16) ? 16 : i;
i -= wcount;
taskfile_input_data (drive, buffer, wcount);
}
}
/*
* taskfile_error() takes action based on the error returned by the drive.
*/
ide_startstop_t taskfile_error (ide_drive_t *drive, const char *msg, byte stat)
{
struct request *rq;
byte err;
err = taskfile_dump_status(drive, msg, stat);
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
/* retry only "normal" I/O: */
if (rq->flags & REQ_DRIVE_TASKFILE) {
rq->errors = 1;
ide_end_taskfile(drive, stat, err);
return ide_stopped;
}
if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */
rq->errors |= ERROR_RESET;
} else {
if (drive->media == ide_disk && (stat & ERR_STAT)) {
/* err has different meaning on cdrom and tape */
if (err == ABRT_ERR) {
if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY)
return ide_stopped; /* some newer drives don't support WIN_SPECIFY */
} else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) {
drive->crc_count++; /* UDMA crc error -- just retry the operation */
} else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
rq->errors = ERROR_MAX;
else if (err & TRK0_ERR) /* help it find track zero */
rq->errors |= ERROR_RECAL;
}
/* pre bio (rq->cmd != WRITE) */
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
task_try_to_flush_leftover_data(drive);
}
if (GET_STAT() & (BUSY_STAT|DRQ_STAT))
OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */
if (rq->errors >= ERROR_MAX) {
if (drive->driver != NULL)
ata_ops(drive)->end_request(0, HWGROUP(drive));
else
ide_end_request(drive, 0);
} else {
if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
++rq->errors;
return ide_do_reset(drive);
}
if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
drive->special.b.recalibrate = 1;
++rq->errors;
}
return ide_stopped;
}
#endif
/* /*
* Handler for special commands without a data phase from ide-disk * Handler for special commands without a data phase from ide-disk
*/ */
/* /*
* set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. * This is invoked on completion of a WIN_SETMULT cmd.
*/ */
ide_startstop_t set_multmode_intr (ide_drive_t *drive) ide_startstop_t set_multmode_intr (ide_drive_t *drive)
{ {
...@@ -680,15 +455,15 @@ ide_startstop_t set_multmode_intr (ide_drive_t *drive) ...@@ -680,15 +455,15 @@ ide_startstop_t set_multmode_intr (ide_drive_t *drive)
} else { } else {
drive->mult_req = drive->mult_count = 0; drive->mult_req = drive->mult_count = 0;
drive->special.b.recalibrate = 1; drive->special.b.recalibrate = 1;
(void) ide_dump_status(drive, "set_multmode", stat); ide_dump_status(drive, "set_multmode", stat);
} }
return ide_stopped; return ide_stopped;
} }
/* /*
* set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. * This is invoked on completion of a WIN_SPECIFY cmd.
*/ */
ide_startstop_t set_geometry_intr (ide_drive_t *drive) static ide_startstop_t set_geometry_intr (ide_drive_t *drive)
{ {
byte stat; byte stat;
...@@ -703,9 +478,9 @@ ide_startstop_t set_geometry_intr (ide_drive_t *drive) ...@@ -703,9 +478,9 @@ ide_startstop_t set_geometry_intr (ide_drive_t *drive)
} }
/* /*
* recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. * This is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
*/ */
ide_startstop_t recal_intr (ide_drive_t *drive) static ide_startstop_t recal_intr (ide_drive_t *drive)
{ {
byte stat = GET_STAT(); byte stat = GET_STAT();
...@@ -736,7 +511,7 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive) ...@@ -736,7 +511,7 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive)
/* /*
* Handler for command with PIO data-in phase * Handler for command with PIO data-in phase
*/ */
ide_startstop_t task_in_intr (ide_drive_t *drive) static ide_startstop_t task_in_intr (ide_drive_t *drive)
{ {
byte stat = GET_STAT(); byte stat = GET_STAT();
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
...@@ -751,7 +526,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) ...@@ -751,7 +526,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
if (!(stat & BUSY_STAT)) { if (!(stat & BUSY_STAT)) {
DTF("task_in_intr to Soon wait for next interrupt\n"); DTF("task_in_intr to Soon wait for next interrupt\n");
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
} }
DTF("stat: %02x\n", stat); DTF("stat: %02x\n", stat);
...@@ -772,139 +547,12 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) ...@@ -772,139 +547,12 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
} }
} else { } else {
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
return ide_stopped; return ide_stopped;
}
#undef ALTSTAT_SCREW_UP
#ifdef ALTSTAT_SCREW_UP
/*
* (ks/hs): Poll Alternate Status Register to ensure
* that drive is not busy.
*/
byte altstat_multi_busy (ide_drive_t *drive, byte stat, const char *msg)
{
int i;
DTF("multi%s: ASR = %x\n", msg, stat);
if (stat & BUSY_STAT) {
/* (ks/hs): FIXME: Replace hard-coded 100, error handling? */
for (i=0; i<100; i++) {
stat = GET_ALTSTAT();
if ((stat & BUSY_STAT) == 0)
break;
}
}
/*
* (ks/hs): Read Status AFTER Alternate Status Register
*/
return(GET_STAT());
}
/*
* (ks/hs): Poll Alternate status register to wait for drive
* to become ready for next transfer
*/
byte altstat_multi_poll (ide_drive_t *drive, byte stat, const char *msg)
{
/* (ks/hs): FIXME: Error handling, time-out? */
while (stat & BUSY_STAT)
stat = GET_ALTSTAT();
DTF("multi%s: nsect=1, ASR = %x\n", msg, stat);
return(GET_STAT()); /* (ks/hs): Clear pending IRQ */
}
#endif /* ALTSTAT_SCREW_UP */
/*
* Handler for command with Read Multiple
*/
ide_startstop_t task_mulin_intr (ide_drive_t *drive)
{
unsigned int msect, nsect;
#ifdef ALTSTAT_SCREW_UP
byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "read");
#else
byte stat = GET_STAT();
#endif /* ALTSTAT_SCREW_UP */
byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq;
char *pBuf = NULL;
unsigned long flags;
if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_mulin_intr", stat);
}
/* no data yet, so wait for another interrupt */
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
return ide_started;
}
/* (ks/hs): Fixed Multi-Sector transfer */
msect = drive->mult_count;
#ifdef ALTSTAT_SCREW_UP
/*
* Screw the request we do not support bad data-phase setups!
* Either read and learn the ATA standard or crash yourself!
*/
if (!msect) {
/*
* (ks/hs): Drive supports multi-sector transfer,
* drive->mult_count was not set
*/
nsect = 1;
while (rq->current_nr_sectors) {
pBuf = ide_map_rq(rq, &flags);
DTF("Multiread: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
stat = altstat_multi_poll(drive, GET_ALTSTAT(), "read");
}
ide_end_request(drive, 1);
return ide_stopped;
}
#endif /* ALTSTAT_SCREW_UP */
do {
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
pBuf = ide_map_rq(rq, &flags);
DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
msect -= nsect;
if (!rq->current_nr_sectors) {
if (!ide_end_request(drive, 1))
return ide_stopped;
}
} while (msect);
/*
* more data left
*/
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
return ide_started;
} }
ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) static ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
{ {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -924,21 +572,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) ...@@ -924,21 +572,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
rq->current_nr_sectors--; rq->current_nr_sectors--;
ide_unmap_rq(rq, buf, &flags); ide_unmap_rq(rq, buf, &flags);
} else { } else {
/* ata_poll_drive_ready(drive);
* (ks/hs): Stuff the first sector(s)
* by implicitly calling the handler
*/
if (!(drive_is_ready(drive))) {
int i;
/*
* (ks/hs): FIXME: Replace hard-coded
* 100, error handling?
*/
for (i=0; i<100; i++) {
if (drive_is_ready(drive))
break;
}
}
return args->handler(drive); return args->handler(drive);
} }
return ide_started; return ide_started;
...@@ -947,7 +581,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) ...@@ -947,7 +581,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
/* /*
* Handler for command with PIO data-out phase * Handler for command with PIO data-out phase
*/ */
ide_startstop_t task_out_intr (ide_drive_t *drive) static ide_startstop_t task_out_intr(ide_drive_t *drive)
{ {
byte stat = GET_STAT(); byte stat = GET_STAT();
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
...@@ -978,98 +612,7 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) ...@@ -978,98 +612,7 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
return ide_started; return ide_started;
} }
/* static ide_startstop_t pre_bio_out_intr(ide_drive_t *drive, struct request *rq)
* Handler for command write multiple
* Called directly from execute_drive_cmd for the first bunch of sectors,
* afterwards only by the ISR
*/
ide_startstop_t task_mulout_intr (ide_drive_t *drive)
{
unsigned int msect, nsect;
#ifdef ALTSTAT_SCREW_UP
byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "write");
#else
byte stat = GET_STAT();
#endif /* ALTSTAT_SCREW_UP */
byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
char *pBuf = NULL;
unsigned long flags;
/*
* (ks/hs): Handle last IRQ on multi-sector transfer,
* occurs after all data was sent in this chunk
*/
if (rq->current_nr_sectors == 0) {
if (stat & (ERR_STAT|DRQ_STAT))
return ide_error(drive, "task_mulout_intr", stat);
/*
* there may be more, ide_do_request will restart it if
* necessary
*/
ide_end_request(drive, 1);
return ide_stopped;
}
if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_mulout_intr", stat);
}
/* no data yet, so wait for another interrupt */
if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
/* (ks/hs): See task_mulin_intr */
msect = drive->mult_count;
#ifdef ALTSTAT_SCREW_UP
/*
* Screw the request we do not support bad data-phase setups!
* Either read and learn the ATA standard or crash yourself!
*/
if (!msect) {
nsect = 1;
while (rq->current_nr_sectors) {
pBuf = ide_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
stat = altstat_multi_poll(drive, GET_ALTSTAT(), "write");
}
ide_end_request(drive, 1);
return ide_stopped;
}
#endif /* ALTSTAT_SCREW_UP */
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
pBuf = ide_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
ide_startstop_t pre_bio_out_intr (ide_drive_t *drive, struct request *rq)
{ {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -1082,34 +625,14 @@ ide_startstop_t pre_bio_out_intr (ide_drive_t *drive, struct request *rq) ...@@ -1082,34 +625,14 @@ ide_startstop_t pre_bio_out_intr (ide_drive_t *drive, struct request *rq)
if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ))
return startstop; return startstop;
/* ata_poll_drive_ready(drive);
* (ks/hs): Stuff the first sector(s)
* by implicitly calling the handler
*/
if (!(drive_is_ready(drive))) {
int i;
/*
* (ks/hs): FIXME: Replace hard-coded
* 100, error handling?
*/
for (i=0; i<100; i++) {
if (drive_is_ready(drive))
break;
}
}
return args->handler(drive); return args->handler(drive);
} }
ide_startstop_t bio_mulout_intr (ide_drive_t *drive) static ide_startstop_t bio_mulout_intr (ide_drive_t *drive)
{ {
#ifdef ALTSTAT_SCREW_UP
byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "write");
#else
byte stat = GET_STAT(); byte stat = GET_STAT();
#endif /* ALTSTAT_SCREW_UP */
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
struct request *rq = &HWGROUP(drive)->wrq; struct request *rq = &HWGROUP(drive)->wrq;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
...@@ -1147,8 +670,8 @@ ide_startstop_t bio_mulout_intr (ide_drive_t *drive) ...@@ -1147,8 +670,8 @@ ide_startstop_t bio_mulout_intr (ide_drive_t *drive)
} }
do { do {
char *buffer; char *buffer;
int nsect = rq->current_nr_sectors; int nsect = rq->current_nr_sectors;
unsigned long flags; unsigned long flags;
if (nsect > mcount) if (nsect > mcount)
...@@ -1221,6 +744,60 @@ ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, ...@@ -1221,6 +744,60 @@ ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile,
return(NULL); return(NULL);
} }
/*
* Handler for command with Read Multiple
*/
static ide_startstop_t task_mulin_intr(ide_drive_t *drive)
{
unsigned int msect, nsect;
byte stat = GET_STAT();
byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq;
char *pBuf = NULL;
unsigned long flags;
if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "task_mulin_intr", stat);
}
/* no data yet, so wait for another interrupt */
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
return ide_started;
}
/* (ks/hs): Fixed Multi-Sector transfer */
msect = drive->mult_count;
do {
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
pBuf = ide_map_rq(rq, &flags);
DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
msect -= nsect;
if (!rq->current_nr_sectors) {
if (!ide_end_request(drive, 1))
return ide_stopped;
}
} while (msect);
/*
* more data left
*/
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
return ide_started;
}
/* Called by internal to feature out type of command being called */ /* Called by internal to feature out type of command being called */
ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile) ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile)
{ {
...@@ -1316,8 +893,8 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h ...@@ -1316,8 +893,8 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h
case WIN_QUEUED_SERVICE: case WIN_QUEUED_SERVICE:
case WIN_PACKETCMD: case WIN_PACKETCMD:
default: default:
return(NULL); return NULL;
} }
} }
/* Called by ioctl to feature out type of command being called */ /* Called by ioctl to feature out type of command being called */
...@@ -1450,7 +1027,7 @@ int ide_cmd_type_parser (ide_task_t *args) ...@@ -1450,7 +1027,7 @@ int ide_cmd_type_parser (ide_task_t *args)
/* /*
* This function is intended to be used prior to invoking ide_do_drive_cmd(). * This function is intended to be used prior to invoking ide_do_drive_cmd().
*/ */
void ide_init_drive_taskfile (struct request *rq) static void ide_init_drive_taskfile (struct request *rq)
{ {
memset(rq, 0, sizeof(*rq)); memset(rq, 0, sizeof(*rq));
rq->flags = REQ_DRIVE_TASKFILE; rq->flags = REQ_DRIVE_TASKFILE;
...@@ -1463,7 +1040,7 @@ void ide_init_drive_taskfile (struct request *rq) ...@@ -1463,7 +1040,7 @@ void ide_init_drive_taskfile (struct request *rq)
* *
* ide_raw_taskfile is the one that user-space executes. * ide_raw_taskfile is the one that user-space executes.
*/ */
int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf) int ide_wait_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf)
{ {
struct request rq; struct request rq;
ide_task_t args; ide_task_t args;
...@@ -1499,7 +1076,7 @@ int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, s ...@@ -1499,7 +1076,7 @@ int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, s
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, byte *buf) int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *args, byte *buf)
{ {
struct request rq; struct request rq;
ide_init_drive_taskfile(&rq); ide_init_drive_taskfile(&rq);
...@@ -1512,24 +1089,11 @@ int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, byte *buf) ...@@ -1512,24 +1089,11 @@ int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, byte *buf)
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
char * ide_ioctl_verbose (unsigned int cmd)
{
return("unknown");
}
char * ide_task_cmd_verbose (byte task)
{
return("unknown");
}
#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
/* /*
* The taskfile glue table * The taskfile glue table
* *
* reqtask.data_phase reqtask.req_cmd * reqtask.data_phase reqtask.req_cmd
* args.command_type args.handler * args.command_type args.handler
* *
* TASKFILE_P_OUT_DMAQ ?? ?? * TASKFILE_P_OUT_DMAQ ?? ??
* TASKFILE_P_IN_DMAQ ?? ?? * TASKFILE_P_IN_DMAQ ?? ??
...@@ -1555,201 +1119,11 @@ char * ide_task_cmd_verbose (byte task) ...@@ -1555,201 +1119,11 @@ char * ide_task_cmd_verbose (byte task)
* TASKFILE_IN IDE_DRIVE_TASK_IN task_in_intr * TASKFILE_IN IDE_DRIVE_TASK_IN task_in_intr
* TASKFILE_NO_DATA IDE_DRIVE_TASK_NO_DATA task_no_data_intr * TASKFILE_NO_DATA IDE_DRIVE_TASK_NO_DATA task_no_data_intr
* *
* IDE_DRIVE_TASK_SET_XFER task_no_data_intr * IDE_DRIVE_TASK_SET_XFER task_no_data_intr
* IDE_DRIVE_TASK_INVALID * IDE_DRIVE_TASK_INVALID
* *
*/ */
#define MAX_DMA (256*SECTOR_WORDS)
int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
ide_task_request_t *req_task;
ide_task_t args;
byte *outbuf = NULL;
byte *inbuf = NULL;
task_ioreg_t *argsptr = args.tfRegister;
task_ioreg_t *hobsptr = args.hobRegister;
int err = 0;
int tasksize = sizeof(struct ide_task_request_s);
int taskin = 0;
int taskout = 0;
req_task = kmalloc(tasksize, GFP_KERNEL);
if (req_task == NULL) return -ENOMEM;
memset(req_task, 0, tasksize);
if (copy_from_user(req_task, (void *) arg, tasksize)) {
kfree(req_task);
return -EFAULT;
}
taskout = (int) req_task->out_size;
taskin = (int) req_task->in_size;
if (taskout) {
int outtotal = tasksize;
outbuf = kmalloc(taskout, GFP_KERNEL);
if (outbuf == NULL) {
err = -ENOMEM;
goto abort;
}
memset(outbuf, 0, taskout);
if (copy_from_user(outbuf, (void *)arg + outtotal, taskout)) {
err = -EFAULT;
goto abort;
}
}
if (taskin) {
int intotal = tasksize + taskout;
inbuf = kmalloc(taskin, GFP_KERNEL);
if (inbuf == NULL) {
err = -ENOMEM;
goto abort;
}
memset(inbuf, 0, taskin);
if (copy_from_user(inbuf, (void *)arg + intotal , taskin)) {
err = -EFAULT;
goto abort;
}
}
memset(argsptr, 0, HDIO_DRIVE_TASK_HDR_SIZE);
memset(hobsptr, 0, HDIO_DRIVE_HOB_HDR_SIZE);
memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE);
args.tf_in_flags = req_task->in_flags;
args.tf_out_flags = req_task->out_flags;
args.data_phase = req_task->data_phase;
args.command_type = req_task->req_cmd;
#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
DTF("%s: ide_ioctl_cmd %s: ide_task_cmd %s\n",
drive->name,
ide_ioctl_verbose(cmd),
ide_task_cmd_verbose(args.tfRegister[IDE_COMMAND_OFFSET]));
#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
switch(req_task->data_phase) {
case TASKFILE_OUT_DMAQ:
case TASKFILE_OUT_DMA:
args.prehandler = NULL;
args.handler = NULL;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, outbuf);
break;
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
args.prehandler = NULL;
args.handler = NULL;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, inbuf);
break;
case TASKFILE_IN_OUT:
#if 0
args.prehandler = &pre_task_out_intr;
args.handler = &task_out_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, outbuf);
args.prehandler = NULL;
args.handler = &task_in_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, inbuf);
break;
#else
err = -EFAULT;
goto abort;
#endif
case TASKFILE_MULTI_OUT:
if (drive->mult_count) {
args.prehandler = &pre_task_out_intr;
args.handler = &task_mulout_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, outbuf);
} else {
/* (hs): give up if multcount is not set */
printk("%s: %s Multimode Write " \
"multcount is not set\n",
drive->name, __FUNCTION__);
err = -EPERM;
goto abort;
}
break;
case TASKFILE_OUT:
args.prehandler = &pre_task_out_intr;
args.handler = &task_out_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, outbuf);
break;
case TASKFILE_MULTI_IN:
if (drive->mult_count) {
args.prehandler = NULL;
args.handler = &task_mulin_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, inbuf);
} else {
/* (hs): give up if multcount is not set */
printk("%s: %s Multimode Read failure " \
"multcount is not set\n",
drive->name, __FUNCTION__);
err = -EPERM;
goto abort;
}
break;
case TASKFILE_IN:
args.prehandler = NULL;
args.handler = &task_in_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, inbuf);
break;
case TASKFILE_NO_DATA:
args.prehandler = NULL;
args.handler = &task_no_data_intr;
args.posthandler = NULL;
err = ide_raw_taskfile(drive, &args, NULL);
break;
default:
args.prehandler = NULL;
args.handler = NULL;
args.posthandler = NULL;
err = -EFAULT;
goto abort;
}
memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE);
memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE);
req_task->in_flags = args.tf_in_flags;
req_task->out_flags = args.tf_out_flags;
if (copy_to_user((void *)arg, req_task, tasksize)) {
err = -EFAULT;
goto abort;
}
if (taskout) {
int outtotal = tasksize;
if (copy_to_user((void *)arg+outtotal, outbuf, taskout)) {
err = -EFAULT;
goto abort;
}
}
if (taskin) {
int intotal = tasksize + taskout;
if (copy_to_user((void *)arg+intotal, inbuf, taskin)) {
err = -EFAULT;
goto abort;
}
}
abort:
kfree(req_task);
if (outbuf != NULL)
kfree(outbuf);
if (inbuf != NULL)
kfree(inbuf);
return err;
}
/* /*
* Issue ATA command and wait for completion. use for implementing commands in * Issue ATA command and wait for completion. use for implementing commands in
* kernel. * kernel.
...@@ -1773,7 +1147,7 @@ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int ...@@ -1773,7 +1147,7 @@ static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{ {
int err = 0; int err = 0;
byte args[4], *argbuf = args; byte args[4], *argbuf = args;
...@@ -1849,7 +1223,6 @@ int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, ...@@ -1849,7 +1223,6 @@ int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
} }
EXPORT_SYMBOL(drive_is_ready); EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(task_read_24);
EXPORT_SYMBOL(ata_input_data); EXPORT_SYMBOL(ata_input_data);
EXPORT_SYMBOL(ata_output_data); EXPORT_SYMBOL(ata_output_data);
EXPORT_SYMBOL(atapi_input_bytes); EXPORT_SYMBOL(atapi_input_bytes);
...@@ -1858,166 +1231,15 @@ EXPORT_SYMBOL(taskfile_input_data); ...@@ -1858,166 +1231,15 @@ EXPORT_SYMBOL(taskfile_input_data);
EXPORT_SYMBOL(taskfile_output_data); EXPORT_SYMBOL(taskfile_output_data);
EXPORT_SYMBOL(do_rw_taskfile); EXPORT_SYMBOL(do_rw_taskfile);
EXPORT_SYMBOL(do_taskfile); EXPORT_SYMBOL(do_taskfile);
// EXPORT_SYMBOL(flagged_taskfile);
//EXPORT_SYMBOL(ide_end_taskfile);
EXPORT_SYMBOL(set_multmode_intr); EXPORT_SYMBOL(set_multmode_intr);
EXPORT_SYMBOL(set_geometry_intr);
EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(task_no_data_intr); EXPORT_SYMBOL(task_no_data_intr);
EXPORT_SYMBOL(task_in_intr);
EXPORT_SYMBOL(task_mulin_intr);
EXPORT_SYMBOL(pre_task_out_intr);
EXPORT_SYMBOL(task_out_intr);
EXPORT_SYMBOL(task_mulout_intr);
EXPORT_SYMBOL(ide_init_drive_taskfile);
EXPORT_SYMBOL(ide_wait_taskfile); EXPORT_SYMBOL(ide_wait_taskfile);
EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_raw_taskfile);
EXPORT_SYMBOL(ide_pre_handler_parser); EXPORT_SYMBOL(ide_pre_handler_parser);
EXPORT_SYMBOL(ide_handler_parser); EXPORT_SYMBOL(ide_handler_parser);
EXPORT_SYMBOL(ide_cmd_type_parser); EXPORT_SYMBOL(ide_cmd_type_parser);
EXPORT_SYMBOL(ide_taskfile_ioctl);
EXPORT_SYMBOL(ide_cmd_ioctl); EXPORT_SYMBOL(ide_cmd_ioctl);
EXPORT_SYMBOL(ide_task_ioctl); EXPORT_SYMBOL(ide_task_ioctl);
#ifdef CONFIG_PKT_TASK_IOCTL
#if 0
{
{ /* start cdrom */
struct cdrom_info *info = drive->driver_data;
if (info->dma) {
if (info->cmd == READ) {
info->dma = !HWIF(drive)->dmaproc(ide_dma_read, drive);
} else if (info->cmd == WRITE) {
info->dma = !HWIF(drive)->dmaproc(ide_dma_write, drive);
} else {
printk("ide-cd: DMA set, but not allowed\n");
}
}
/* Set up the controller registers. */
OUT_BYTE (info->dma, IDE_FEATURE_REG);
OUT_BYTE (0, IDE_NSECTOR_REG);
OUT_BYTE (0, IDE_SECTOR_REG);
OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG);
OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG);
if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
if (info->dma)
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
return ide_started;
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
return (*handler) (drive);
}
} /* end cdrom */
{ /* start floppy */
idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_bcount_reg_t bcount;
int dma_ok = 0;
floppy->pc=pc; /* Set the current packet command */
pc->retries++;
pc->actually_transferred=0; /* We haven't transferred any data yet */
pc->current_position=pc->buffer;
bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024);
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
}
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */
OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
OUT_BYTE (drive->select.all,IDE_SELECT_REG);
#ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */
set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
} /* end floppy */
{ /* start tape */
idetape_tape_t *tape = drive->driver_data;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
}
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */
OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
OUT_BYTE (drive->select.all,IDE_SELECT_REG);
#ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */
set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
return ide_started;
} else {
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
return idetape_transfer_pc(drive);
}
} /* end tape */
}
#endif
int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
#if 0
switch(req_task->data_phase) {
case TASKFILE_P_OUT_DMAQ:
case TASKFILE_P_IN_DMAQ:
case TASKFILE_P_OUT_DMA:
case TASKFILE_P_IN_DMA:
case TASKFILE_P_OUT:
case TASKFILE_P_IN:
}
#endif
return -ENOMSG;
}
EXPORT_SYMBOL(pkt_taskfile_ioctl);
#endif /* CONFIG_PKT_TASK_IOCTL */
/* /*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below) * Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/ *
/*
* Mostly written by Mark Lord <mlord@pobox.com> * Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il> * and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org> * and Andre Hedrick <andre@linux-ide.org>
...@@ -119,8 +117,6 @@ ...@@ -119,8 +117,6 @@
#define VERSION "7.0.0" #define VERSION "7.0.0"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -135,8 +131,8 @@ ...@@ -135,8 +131,8 @@
#include <linux/blkpg.h> #include <linux/blkpg.h>
#include <linux/slab.h> #include <linux/slab.h>
#ifndef MODULE #ifndef MODULE
#include <linux/init.h> # include <linux/init.h>
#endif /* MODULE */ #endif
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ide.h> #include <linux/ide.h>
...@@ -155,9 +151,52 @@ ...@@ -155,9 +151,52 @@
#include "ide_modes.h" #include "ide_modes.h"
/* Constant tables for PIO mode programming: /*
* Those will be moved into separate header files eventually.
*/ */
#ifdef CONFIG_BLK_DEV_RZ1000
extern void ide_probe_for_rz100x(void);
#endif
#ifdef CONFIG_ETRAX_IDE
extern void init_e100_ide(void);
#endif
#ifdef CONFIG_BLK_DEV_CMD640
extern void ide_probe_for_cmd640x(void);
#endif
#ifdef CONFIG_BLK_DEV_PDC4030
extern int ide_probe_for_pdc4030(void);
#endif
#ifdef CONFIG_BLK_DEV_IDE_PMAC
extern void pmac_ide_probe(void);
#endif
#ifdef CONFIG_BLK_DEV_IDE_ICSIDE
extern void icside_init(void);
#endif
#ifdef CONFIG_BLK_DEV_IDE_RAPIDE
extern void rapide_init(void);
#endif
#ifdef CONFIG_BLK_DEV_GAYLE
extern void gayle_init(void);
#endif
#ifdef CONFIG_BLK_DEV_FALCON_IDE
extern void falconide_init(void);
#endif
#ifdef CONFIG_BLK_DEV_MAC_IDE
extern void macide_init(void);
#endif
#ifdef CONFIG_BLK_DEV_Q40IDE
extern void q40ide_init(void);
#endif
#ifdef CONFIG_BLK_DEV_BUDDHA
extern void buddha_init(void);
#endif
#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP)
extern void pnpide_init(int);
#endif
/*
* Constant tables for PIO mode programming:
*/
const ide_pio_timings_t ide_pio_timings[6] = { const ide_pio_timings_t ide_pio_timings[6] = {
{ 70, 165, 600 }, /* PIO Mode 0 */ { 70, 165, 600 }, /* PIO Mode 0 */
{ 50, 125, 383 }, /* PIO Mode 1 */ { 50, 125, 383 }, /* PIO Mode 1 */
...@@ -174,7 +213,7 @@ const ide_pio_timings_t ide_pio_timings[6] = { ...@@ -174,7 +213,7 @@ const ide_pio_timings_t ide_pio_timings[6] = {
static struct ide_pio_info { static struct ide_pio_info {
const char *name; const char *name;
int pio; int pio;
} ide_pio_blacklist [] = { } ide_pio_blacklist[] = {
/* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */ /* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */
{ "Conner Peripherals 540MB - CFS540A", 3 }, { "Conner Peripherals 540MB - CFS540A", 3 },
...@@ -224,8 +263,8 @@ static struct ide_pio_info { ...@@ -224,8 +263,8 @@ static struct ide_pio_info {
{ "ST3600A", 1 }, { "ST3600A", 1 },
{ "ST3290A", 0 }, { "ST3290A", 0 },
{ "ST3144A", 0 }, { "ST3144A", 0 },
{ "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on */ { "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on
/* drive) according to Seagates FIND-ATA program */ * drive) according to Seagates FIND-ATA program */
{ "QUANTUM ELS127A", 0 }, { "QUANTUM ELS127A", 0 },
{ "QUANTUM ELS170A", 0 }, { "QUANTUM ELS170A", 0 },
...@@ -238,7 +277,7 @@ static struct ide_pio_info { ...@@ -238,7 +277,7 @@ static struct ide_pio_info {
{ "QUANTUM LIGHTNING 730A", 3 }, { "QUANTUM LIGHTNING 730A", 3 },
{ "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */ { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
{ "QUANTUM FIREBALL_640", 3 }, { "QUANTUM FIREBALL_640", 3 },
{ "QUANTUM FIREBALL_1080", 3 }, { "QUANTUM FIREBALL_1080", 3 },
{ "QUANTUM FIREBALL_1280", 3 }, { "QUANTUM FIREBALL_1280", 3 },
{ NULL, 0 } { NULL, 0 }
...@@ -247,34 +286,33 @@ static struct ide_pio_info { ...@@ -247,34 +286,33 @@ static struct ide_pio_info {
/* default maximum number of failures */ /* default maximum number of failures */
#define IDE_DEFAULT_MAX_FAILURES 1 #define IDE_DEFAULT_MAX_FAILURES 1
static int idebus_parameter; /* holds the "idebus=" parameter */ static int idebus_parameter; /* holds the "idebus=" parameter */
int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
static int initializing; /* set while initializing built-in drivers */ static int initializing; /* set while initializing built-in drivers */
/* /*
* protects global structures etc, we want to split this into per-hwgroup * Protects access to global structures etc.
* instead.
*/ */
spinlock_t ide_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; spinlock_t ide_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
#ifdef CONFIG_BLK_DEV_IDEPCI #ifdef CONFIG_BLK_DEV_IDEPCI
static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
#endif /* CONFIG_BLK_DEV_IDEPCI */ #endif
#if defined(__mc68000__) || defined(CONFIG_APUS) #if defined(__mc68000__) || defined(CONFIG_APUS)
/* /*
* ide_lock is used by the Atari code to obtain access to the IDE interrupt, * This is used by the Atari code to obtain access to the IDE interrupt,
* which is shared between several drivers. * which is shared between several drivers.
*/ */
static int ide_intr_lock; static int ide_intr_lock;
#endif /* __mc68000__ || CONFIG_APUS */ #endif
int noautodma = 0; int noautodma = 0;
/* /*
* This is declared extern in ide.h, for access by other IDE modules: * This is declared extern in ide.h, for access by other IDE modules:
*/ */
ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
/* /*
...@@ -378,7 +416,7 @@ byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode, ...@@ -378,7 +416,7 @@ byte ide_get_best_pio_mode (ide_drive_t *drive, byte mode_wanted, byte max_mode,
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
/* /*
* For really screwy hardware (hey, at least it *can* be used with Linux) * For really screwed hardware (hey, at least it *can* be used with Linux)
* we can enforce a minimum delay time between successive operations. * we can enforce a minimum delay time between successive operations.
*/ */
static unsigned long read_timer (void) static unsigned long read_timer (void)
...@@ -389,7 +427,7 @@ static unsigned long read_timer (void) ...@@ -389,7 +427,7 @@ static unsigned long read_timer (void)
__save_flags(flags); /* local CPU only */ __save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */ __cli(); /* local CPU only */
t = jiffies * 11932; t = jiffies * 11932;
outb_p(0, 0x43); outb_p(0, 0x43);
i = inb_p(0x40); i = inb_p(0x40);
i |= inb(0x40) << 8; i |= inb(0x40) << 8;
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
...@@ -476,7 +514,7 @@ static void __init init_ide_data (void) ...@@ -476,7 +514,7 @@ static void __init init_ide_data (void)
return; /* already initialized */ return; /* already initialized */
magic_cookie = 0; magic_cookie = 0;
/* Initialise all interface structures */ /* Initialize all interface structures */
for (index = 0; index < MAX_HWIFS; ++index) for (index = 0; index < MAX_HWIFS; ++index)
init_hwif_data(index); init_hwif_data(index);
...@@ -487,11 +525,13 @@ static void __init init_ide_data (void) ...@@ -487,11 +525,13 @@ static void __init init_ide_data (void)
} }
/* /*
* CompactFlash cards and their brethern pretend to be removable hard disks, except: * CompactFlash cards and their relatives pretend to be removable hard disks, except:
* (1) they never have a slave unit, and * (1) they never have a slave unit, and
* (2) they don't have doorlock mechanisms. * (2) they don't have a door lock mechanisms.
* This test catches them, and is invoked elsewhere when setting appropriate config bits. * This test catches them, and is invoked elsewhere when setting appropriate config bits.
* *
* FIXME FIXME: Yes this is for certain applicable for all of them as time has shown.
*
* FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD) devices, * FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD) devices,
* so in linux 2.3.x we should change this to just treat all PCMCIA drives this way, * so in linux 2.3.x we should change this to just treat all PCMCIA drives this way,
* and get rid of the model-name tests below (too big of an interface change for 2.2.x). * and get rid of the model-name tests below (too big of an interface change for 2.2.x).
...@@ -503,7 +543,8 @@ int drive_is_flashcard (ide_drive_t *drive) ...@@ -503,7 +543,8 @@ int drive_is_flashcard (ide_drive_t *drive)
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
if (drive->removable && id != NULL) { if (drive->removable && id != NULL) {
if (id->config == 0x848a) return 1; /* CompactFlash */ if (id->config == 0x848a)
return 1; /* CompactFlash */
if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */ if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */
|| !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */ || !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */
|| !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */ || !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */
...@@ -681,8 +722,8 @@ void ide_geninit (ide_hwif_t *hwif) ...@@ -681,8 +722,8 @@ void ide_geninit (ide_hwif_t *hwif)
static ide_startstop_t do_reset1 (ide_drive_t *, int); /* needed below */ static ide_startstop_t do_reset1 (ide_drive_t *, int); /* needed below */
/* /*
* atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms * ATAPI_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
* during an atapi drive reset operation. If the drive has not yet responded, * during an ATAPI drive reset operation. If the drive has not yet responded,
* and we have not yet hit our maximum waiting time, then the timer is restarted * and we have not yet hit our maximum waiting time, then the timer is restarted
* for another 50ms. * for another 50ms.
*/ */
...@@ -755,7 +796,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) ...@@ -755,7 +796,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
printk("\n"); printk("\n");
#else #else
printk("failed\n"); printk("failed\n");
#endif /* FANCY_STATUS_DUMPS */ #endif
} }
} }
hwgroup->poll_timeout = 0; /* done polling */ hwgroup->poll_timeout = 0; /* done polling */
...@@ -774,7 +815,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) ...@@ -774,7 +815,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
* Unfortunately, the IDE interface does not generate an interrupt to let * Unfortunately, the IDE interface does not generate an interrupt to let
* us know when the reset operation has finished, so we must poll for this. * us know when the reset operation has finished, so we must poll for this.
* Equally poor, though, is the fact that this may a very long time to complete, * Equally poor, though, is the fact that this may a very long time to complete,
* (up to 30 seconds worstcase). So, instead of busy-waiting here for it, * (up to 30 seconds worst case). So, instead of busy-waiting here for it,
* we set a timer to poll at 50ms intervals. * we set a timer to poll at 50ms intervals.
*/ */
static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
...@@ -838,7 +879,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) ...@@ -838,7 +879,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
if (hwif->resetproc != NULL) if (hwif->resetproc != NULL)
hwif->resetproc(drive); hwif->resetproc(drive);
#endif /* OK_TO_RESET_CONTROLLER */ #endif
__restore_flags (flags); /* local CPU only */ __restore_flags (flags); /* local CPU only */
return ide_started; return ide_started;
...@@ -1040,11 +1081,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat) ...@@ -1040,11 +1081,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
/* retry only "normal" I/O: */ /* retry only "normal" I/O: */
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
rq->errors = 1; rq->errors = 1;
#if 0
if (rq->flags & REQ_DRIVE_TASKFILE)
ide_end_taskfile(drive, stat, err);
else
#endif
ide_end_drive_cmd(drive, stat, err); ide_end_drive_cmd(drive, stat, err);
return ide_stopped; return ide_stopped;
} }
...@@ -1144,7 +1180,7 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by ...@@ -1144,7 +1180,7 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by
byte stat; byte stat;
int i; int i;
unsigned long flags; unsigned long flags;
/* bail early if we've exceeded max_failures */ /* bail early if we've exceeded max_failures */
if (drive->max_failures && (drive->failures > drive->max_failures)) { if (drive->max_failures && (drive->failures > drive->max_failures)) {
*startstop = ide_stopped; *startstop = ide_stopped;
...@@ -1190,39 +1226,13 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq ...@@ -1190,39 +1226,13 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
if (!(args)) goto args_error; if (!(args))
goto args_error;
#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG do_taskfile(drive,
{
printk(KERN_INFO "%s: ", drive->name);
// printk("TF.0=x%02x ", args->tfRegister[IDE_DATA_OFFSET]);
printk("TF.1=x%02x ", args->tfRegister[IDE_FEATURE_OFFSET]);
printk("TF.2=x%02x ", args->tfRegister[IDE_NSECTOR_OFFSET]);
printk("TF.3=x%02x ", args->tfRegister[IDE_SECTOR_OFFSET]);
printk("TF.4=x%02x ", args->tfRegister[IDE_LCYL_OFFSET]);
printk("TF.5=x%02x ", args->tfRegister[IDE_HCYL_OFFSET]);
printk("TF.6=x%02x ", args->tfRegister[IDE_SELECT_OFFSET]);
printk("TF.7=x%02x\n", args->tfRegister[IDE_COMMAND_OFFSET]);
printk(KERN_INFO "%s: ", drive->name);
// printk("HTF.0=x%02x ", args->hobRegister[IDE_DATA_OFFSET_HOB]);
printk("HTF.1=x%02x ", args->hobRegister[IDE_FEATURE_OFFSET_HOB]);
printk("HTF.2=x%02x ", args->hobRegister[IDE_NSECTOR_OFFSET_HOB]);
printk("HTF.3=x%02x ", args->hobRegister[IDE_SECTOR_OFFSET_HOB]);
printk("HTF.4=x%02x ", args->hobRegister[IDE_LCYL_OFFSET_HOB]);
printk("HTF.5=x%02x ", args->hobRegister[IDE_HCYL_OFFSET_HOB]);
printk("HTF.6=x%02x ", args->hobRegister[IDE_SELECT_OFFSET_HOB]);
printk("HTF.7=x%02x\n", args->hobRegister[IDE_CONTROL_OFFSET_HOB]);
}
#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
// if (args->tf_out_flags.all == 0) {
do_taskfile(drive,
(struct hd_drive_task_hdr *)&args->tfRegister, (struct hd_drive_task_hdr *)&args->tfRegister,
(struct hd_drive_hob_hdr *)&args->hobRegister, (struct hd_drive_hob_hdr *)&args->hobRegister,
args->handler); args->handler);
// } else {
// return flagged_taskfile(drive, args);
// }
if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) || if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
(args->command_type == IDE_DRIVE_TASK_OUT)) && (args->command_type == IDE_DRIVE_TASK_OUT)) &&
...@@ -1398,7 +1408,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) ...@@ -1398,7 +1408,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
{ {
ide_drive_t *drive, *best; ide_drive_t *drive, *best;
repeat: repeat:
best = NULL; best = NULL;
drive = hwgroup->drive; drive = hwgroup->drive;
do { do {
...@@ -1425,7 +1435,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) ...@@ -1425,7 +1435,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
&& 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time)) && 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time))
&& 0 < (signed long)((jiffies + t) - WAKEUP(drive))) && 0 < (signed long)((jiffies + t) - WAKEUP(drive)))
{ {
ide_stall_queue(best, IDE_MIN(t, 10 * WAIT_MIN_SLEEP)); ide_stall_queue(best, min(t, 10 * WAIT_MIN_SLEEP));
goto repeat; goto repeat;
} }
} while ((drive = drive->next) != best); } while ((drive = drive->next) != best);
...@@ -1464,7 +1474,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) ...@@ -1464,7 +1474,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
* will start the next request from the queue. If no more work remains, * will start the next request from the queue. If no more work remains,
* the driver will clear the hwgroup->flags IDE_BUSY flag and exit. * the driver will clear the hwgroup->flags IDE_BUSY flag and exit.
*/ */
static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
{ {
ide_drive_t *drive; ide_drive_t *drive;
ide_hwif_t *hwif; ide_hwif_t *hwif;
...@@ -1511,7 +1521,11 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1511,7 +1521,11 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
hwif = HWIF(drive); hwif = HWIF(drive);
if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) { if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) {
/* set nIEN for previous hwif */ /* set nIEN for previous hwif */
SELECT_INTERRUPT(hwif, drive);
if (hwif->intrproc)
hwif->intrproc(drive);
else
OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]);
} }
hwgroup->hwif = hwif; hwgroup->hwif = hwif;
hwgroup->drive = drive; hwgroup->drive = drive;
...@@ -1548,7 +1562,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1548,7 +1562,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
} }
/* /*
* ide_get_queue() returns the queue which corresponds to a given device. * Returns the queue which corresponds to a given device.
*/ */
request_queue_t *ide_get_queue (kdev_t dev) request_queue_t *ide_get_queue (kdev_t dev)
{ {
...@@ -1567,7 +1581,7 @@ void do_ide_request(request_queue_t *q) ...@@ -1567,7 +1581,7 @@ void do_ide_request(request_queue_t *q)
/* /*
* un-busy the hwgroup etc, and clear any pending DMA status. we want to * un-busy the hwgroup etc, and clear any pending DMA status. we want to
* retry the current request in pio mode instead of risking tossing it * retry the current request in PIO mode instead of risking tossing it
* all away * all away
*/ */
void ide_dma_timeout_retry(ide_drive_t *drive) void ide_dma_timeout_retry(ide_drive_t *drive)
...@@ -1992,13 +2006,14 @@ int ide_revalidate_disk (kdev_t i_rdev) ...@@ -1992,13 +2006,14 @@ int ide_revalidate_disk (kdev_t i_rdev)
/* /*
* Look again for all drives in the system on all interfaces. This is used * Look again for all drives in the system on all interfaces. This is used
* after a new driver cathegory has been loaded as module. * after a new driver category has been loaded as module.
*/ */
void revalidate_drives (void) void revalidate_drives(void)
{ {
ide_hwif_t *hwif; ide_hwif_t *hwif;
ide_drive_t *drive; ide_drive_t *drive;
int index, unit; int index;
int unit;
for (index = 0; index < MAX_HWIFS; ++index) { for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index]; hwif = &ide_hwifs[index];
...@@ -2013,7 +2028,7 @@ void revalidate_drives (void) ...@@ -2013,7 +2028,7 @@ void revalidate_drives (void)
} }
} }
static void ide_probe_module (void) static void ide_probe_module(void)
{ {
ideprobe_init(); ideprobe_init();
revalidate_drives(); revalidate_drives();
...@@ -2032,7 +2047,7 @@ static void ide_driver_module (void) ...@@ -2032,7 +2047,7 @@ static void ide_driver_module (void)
revalidate_drives(); revalidate_drives();
} }
static int ide_open (struct inode * inode, struct file * filp) static int ide_open(struct inode * inode, struct file * filp)
{ {
ide_drive_t *drive; ide_drive_t *drive;
...@@ -2050,29 +2065,31 @@ static int ide_open (struct inode * inode, struct file * filp) ...@@ -2050,29 +2065,31 @@ static int ide_open (struct inode * inode, struct file * filp)
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
if (drive->driver == NULL) { if (drive->driver == NULL) {
char *module = NULL;
switch (drive->type) { switch (drive->type) {
case ATA_DISK: case ATA_DISK:
request_module("ide-disk"); module = "ide-disk";
break; break;
case ATA_ROM: case ATA_ROM:
request_module("ide-cd"); module = "ide-cd";
break; break;
case ATA_TAPE: case ATA_TAPE:
request_module("ide-tape"); module = "ide-tape";
break; break;
case ATA_FLOPPY: case ATA_FLOPPY:
request_module("ide-floppy"); module = "ide-floppy";
break; break;
#if defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI)
case ATA_SCSI: case ATA_SCSI:
request_module("ide-scsi"); module = "ide-scsi";
break; break;
#endif
default: default:
/* nothing to be done about it */ ; /* nothing we can do about it */ ;
} }
if (module)
request_module(module);
} }
#endif /* CONFIG_KMOD */ #endif
while (drive->busy) while (drive->busy)
sleep_on(&drive->wqueue); sleep_on(&drive->wqueue);
++drive->usage; ++drive->usage;
...@@ -2083,7 +2100,7 @@ static int ide_open (struct inode * inode, struct file * filp) ...@@ -2083,7 +2100,7 @@ static int ide_open (struct inode * inode, struct file * filp)
return -ENODEV; return -ENODEV;
} }
printk ("%s: driver not present\n", drive->name); printk(KERN_INFO "%s: driver not present\n", drive->name);
drive->usage--; drive->usage--;
return -ENXIO; return -ENXIO;
} }
...@@ -2144,7 +2161,7 @@ static void hwif_unregister(ide_hwif_t *hwif) ...@@ -2144,7 +2161,7 @@ static void hwif_unregister(ide_hwif_t *hwif)
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (hwif->io_ports[IDE_IRQ_OFFSET]) if (hwif->io_ports[IDE_IRQ_OFFSET])
ide_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1); ide_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ #endif
} }
void ide_unregister (unsigned int index) void ide_unregister (unsigned int index)
...@@ -2176,9 +2193,8 @@ void ide_unregister (unsigned int index) ...@@ -2176,9 +2193,8 @@ void ide_unregister (unsigned int index)
if (ata_ops(drive)->cleanup) { if (ata_ops(drive)->cleanup) {
if (ata_ops(drive)->cleanup(drive)) if (ata_ops(drive)->cleanup(drive))
goto abort; goto abort;
} else { } else
ide_unregister_subdriver(drive); ide_unregister_subdriver(drive);
}
} }
} }
hwif->present = 0; hwif->present = 0;
...@@ -2282,7 +2298,7 @@ void ide_unregister (unsigned int index) ...@@ -2282,7 +2298,7 @@ void ide_unregister (unsigned int index)
hwif->gd = NULL; hwif->gd = NULL;
} }
old_hwif = *hwif; old_hwif = *hwif;
init_hwif_data (index); /* restore hwif data to pristine status */ init_hwif_data(index); /* restore hwif data to pristine status */
hwif->hwgroup = old_hwif.hwgroup; hwif->hwgroup = old_hwif.hwgroup;
hwif->tuneproc = old_hwif.tuneproc; hwif->tuneproc = old_hwif.tuneproc;
hwif->speedproc = old_hwif.speedproc; hwif->speedproc = old_hwif.speedproc;
...@@ -2303,14 +2319,14 @@ void ide_unregister (unsigned int index) ...@@ -2303,14 +2319,14 @@ void ide_unregister (unsigned int index)
hwif->proc = old_hwif.proc; hwif->proc = old_hwif.proc;
#ifndef CONFIG_BLK_DEV_IDECS #ifndef CONFIG_BLK_DEV_IDECS
hwif->irq = old_hwif.irq; hwif->irq = old_hwif.irq;
#endif /* CONFIG_BLK_DEV_IDECS */ #endif
hwif->major = old_hwif.major; hwif->major = old_hwif.major;
hwif->chipset = old_hwif.chipset; hwif->chipset = old_hwif.chipset;
hwif->autodma = old_hwif.autodma; hwif->autodma = old_hwif.autodma;
hwif->udma_four = old_hwif.udma_four; hwif->udma_four = old_hwif.udma_four;
#ifdef CONFIG_BLK_DEV_IDEPCI #ifdef CONFIG_BLK_DEV_IDEPCI
hwif->pci_dev = old_hwif.pci_dev; hwif->pci_dev = old_hwif.pci_dev;
#endif /* CONFIG_BLK_DEV_IDEPCI */ #endif
hwif->straight8 = old_hwif.straight8; hwif->straight8 = old_hwif.straight8;
abort: abort:
restore_flags(flags); /* all CPUs */ restore_flags(flags); /* all CPUs */
...@@ -2356,7 +2372,7 @@ void ide_setup_ports ( hw_regs_t *hw, ...@@ -2356,7 +2372,7 @@ void ide_setup_ports ( hw_regs_t *hw,
* Register an IDE interface, specifing exactly the registers etc * Register an IDE interface, specifing exactly the registers etc
* Set init=1 iff calling before probes have taken place. * Set init=1 iff calling before probes have taken place.
*/ */
int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) int ide_register_hw(hw_regs_t *hw, ide_hwif_t **hwifp)
{ {
int index, retry = 1; int index, retry = 1;
ide_hwif_t *hwif; ide_hwif_t *hwif;
...@@ -2406,7 +2422,7 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) ...@@ -2406,7 +2422,7 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp)
* Compatability function with existing drivers. If you want * Compatability function with existing drivers. If you want
* something different, use the function above. * something different, use the function above.
*/ */
int ide_register (int arg1, int arg2, int irq) int ide_register(int arg1, int arg2, int irq)
{ {
hw_regs_t hw; hw_regs_t hw;
ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL); ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
...@@ -2517,7 +2533,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive) ...@@ -2517,7 +2533,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
/* /*
* FIXME: This should be changed to enqueue a special request * FIXME: This should be changed to enqueue a special request
* to the driver to change settings, and then wait on a sema for completion. * to the driver to change settings, and then wait on a semaphore for completion.
* The current scheme of polling is kludgey, though safe enough. * The current scheme of polling is kludgey, though safe enough.
*/ */
int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val) int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
...@@ -2730,24 +2746,6 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2730,24 +2746,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
drive->nice2 << IDE_NICE_2, drive->nice2 << IDE_NICE_2,
(long *) arg); (long *) arg);
#ifdef CONFIG_IDE_TASK_IOCTL
case HDIO_DRIVE_TASKFILE:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
switch(drive->type) {
case ATA_DISK:
return ide_taskfile_ioctl(drive, inode, file, cmd, arg);
#ifdef CONFIG_PKT_TASK_IOCTL
case ATA_CDROM:
case ATA_TAPE:
case ATA_FLOPPY:
return pkt_taskfile_ioctl(drive, inode, file, cmd, arg);
#endif
default:
return -ENOMSG;
}
#endif /* CONFIG_IDE_TASK_IOCTL */
case HDIO_DRIVE_CMD: case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES; return -EACCES;
...@@ -2795,28 +2793,15 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2795,28 +2793,15 @@ static int ide_ioctl (struct inode *inode, struct file *file,
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (hwgroup->handler != NULL) { if (hwgroup->handler != NULL) {
printk("%s: ide_set_handler: handler not null; %p\n", drive->name, hwgroup->handler); printk("%s: ide_set_handler: handler not null; %p\n", drive->name, hwgroup->handler);
(void) hwgroup->handler(drive); hwgroup->handler(drive);
// hwgroup->handler = NULL;
// hwgroup->expiry = NULL;
hwgroup->timer.expires = jiffies + 0;; hwgroup->timer.expires = jiffies + 0;;
del_timer(&hwgroup->timer); del_timer(&hwgroup->timer);
} }
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
#endif #endif
(void) ide_do_reset(drive); ide_do_reset(drive);
if (drive->suspend_reset) { if (drive->suspend_reset)
/*
* APM WAKE UP todo !!
* int nogoodpower = 1;
* while(nogoodpower) {
* check_power1() or check_power2()
* nogoodpower = 0;
* }
* HWIF(drive)->multiproc(drive);
*/
return ide_revalidate_disk(inode->i_rdev); return ide_revalidate_disk(inode->i_rdev);
}
return 0; return 0;
} }
case BLKGETSIZE: case BLKGETSIZE:
...@@ -2969,9 +2954,11 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m ...@@ -2969,9 +2954,11 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
} }
/* /*
* ide_setup() gets called VERY EARLY during initialization, * This gets called VERY EARLY during initialization, to handle kernel "command
* to handle kernel "command line" strings beginning with "hdx=" * line" strings beginning with "hdx=" or "ide".It gets called even before the
* or "ide". Here is the complete set currently supported: * actual module gets initialized.
*
* Here is the complete set currently supported comand line options:
* *
* "hdx=" is recognized for all "x" from "a" to "h", such as "hdc". * "hdx=" is recognized for all "x" from "a" to "h", such as "hdc".
* "idex=" is recognized for all "x" from "0" to "3", such as "ide1". * "idex=" is recognized for all "x" from "0" to "3", such as "ide1".
...@@ -3011,7 +2998,7 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m ...@@ -3011,7 +2998,7 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
* As for VLB, it is safest to not specify it. * As for VLB, it is safest to not specify it.
* *
* "idex=noprobe" : do not attempt to access/use this interface * "idex=noprobe" : do not attempt to access/use this interface
* "idex=base" : probe for an interface at the addr specified, * "idex=base" : probe for an interface at the address specified,
* where "base" is usually 0x1f0 or 0x170 * where "base" is usually 0x1f0 or 0x170
* and "ctl" is assumed to be "base"+0x206 * and "ctl" is assumed to be "base"+0x206
* "idex=base,ctl" : specify both base and ctl * "idex=base,ctl" : specify both base and ctl
...@@ -3057,8 +3044,8 @@ int __init ide_setup (char *s) ...@@ -3057,8 +3044,8 @@ int __init ide_setup (char *s)
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
const char max_hwif = '0' + (MAX_HWIFS - 1); const char max_hwif = '0' + (MAX_HWIFS - 1);
if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ if (!strncmp(s, "hd=", 3)) /* hd= is for hd.c driver and not us */
return 0; /* driver and not us */ return 0;
if (strncmp(s,"ide",3) && if (strncmp(s,"ide",3) &&
strncmp(s,"idebus",6) && strncmp(s,"idebus",6) &&
...@@ -3076,7 +3063,7 @@ int __init ide_setup (char *s) ...@@ -3076,7 +3063,7 @@ int __init ide_setup (char *s)
ide_doubler = 1; ide_doubler = 1;
return 1; return 1;
} }
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ #endif
if (!strcmp(s, "ide=nodma")) { if (!strcmp(s, "ide=nodma")) {
printk("IDE: Prevented DMA\n"); printk("IDE: Prevented DMA\n");
...@@ -3208,8 +3195,8 @@ int __init ide_setup (char *s) ...@@ -3208,8 +3195,8 @@ int __init ide_setup (char *s)
*/ */
const char *ide_words[] = { const char *ide_words[] = {
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66", "noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66",
"minus8", "minus9", "minus10", "minus8", "minus9", "minus10", "minus11",
"four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL }; "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
hw = s[3] - '0'; hw = s[3] - '0';
hwif = &ide_hwifs[hw]; hwif = &ide_hwifs[hw];
i = match_parm(&s[4], ide_words, vals, 3); i = match_parm(&s[4], ide_words, vals, 3);
...@@ -3284,18 +3271,7 @@ int __init ide_setup (char *s) ...@@ -3284,18 +3271,7 @@ int __init ide_setup (char *s)
goto done; goto done;
} }
#endif /* CONFIG_BLK_DEV_QD65XX */ #endif /* CONFIG_BLK_DEV_QD65XX */
#ifdef CONFIG_BLK_DEV_4DRIVES case -11: /* minus11 */
case -11: /* "four" drives on one set of ports */
{
ide_hwif_t *mate = &ide_hwifs[hw^1];
mate->drives[0].select.all ^= 0x20;
mate->drives[1].select.all ^= 0x20;
hwif->chipset = mate->chipset = ide_4drives;
mate->irq = hwif->irq;
memcpy(mate->io_ports, hwif->io_ports, sizeof(hwif->io_ports));
goto do_serialize;
}
#endif /* CONFIG_BLK_DEV_4DRIVES */
case -10: /* minus10 */ case -10: /* minus10 */
case -9: /* minus9 */ case -9: /* minus9 */
case -8: /* minus8 */ case -8: /* minus8 */
...@@ -3362,155 +3338,6 @@ int __init ide_setup (char *s) ...@@ -3362,155 +3338,6 @@ int __init ide_setup (char *s)
return 1; return 1;
} }
/*
* probe_for_hwifs() finds/initializes "known" IDE interfaces
*/
static void __init probe_for_hwifs (void)
{
#ifdef CONFIG_PCI
if (pci_present())
{
#ifdef CONFIG_BLK_DEV_IDEPCI
ide_scan_pcibus(ide_scan_direction);
#else
#ifdef CONFIG_BLK_DEV_RZ1000
{
extern void ide_probe_for_rz100x(void);
ide_probe_for_rz100x();
}
#endif /* CONFIG_BLK_DEV_RZ1000 */
#endif /* CONFIG_BLK_DEV_IDEPCI */
}
#endif /* CONFIG_PCI */
#ifdef CONFIG_ETRAX_IDE
{
extern void init_e100_ide(void);
init_e100_ide();
}
#endif /* CONFIG_ETRAX_IDE */
#ifdef CONFIG_BLK_DEV_CMD640
{
extern void ide_probe_for_cmd640x(void);
ide_probe_for_cmd640x();
}
#endif /* CONFIG_BLK_DEV_CMD640 */
#ifdef CONFIG_BLK_DEV_PDC4030
{
extern int ide_probe_for_pdc4030(void);
(void) ide_probe_for_pdc4030();
}
#endif /* CONFIG_BLK_DEV_PDC4030 */
#ifdef CONFIG_BLK_DEV_IDE_PMAC
{
extern void pmac_ide_probe(void);
pmac_ide_probe();
}
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
#ifdef CONFIG_BLK_DEV_IDE_ICSIDE
{
extern void icside_init(void);
icside_init();
}
#endif /* CONFIG_BLK_DEV_IDE_ICSIDE */
#ifdef CONFIG_BLK_DEV_IDE_RAPIDE
{
extern void rapide_init(void);
rapide_init();
}
#endif /* CONFIG_BLK_DEV_IDE_RAPIDE */
#ifdef CONFIG_BLK_DEV_GAYLE
{
extern void gayle_init(void);
gayle_init();
}
#endif /* CONFIG_BLK_DEV_GAYLE */
#ifdef CONFIG_BLK_DEV_FALCON_IDE
{
extern void falconide_init(void);
falconide_init();
}
#endif /* CONFIG_BLK_DEV_FALCON_IDE */
#ifdef CONFIG_BLK_DEV_MAC_IDE
{
extern void macide_init(void);
macide_init();
}
#endif /* CONFIG_BLK_DEV_MAC_IDE */
#ifdef CONFIG_BLK_DEV_Q40IDE
{
extern void q40ide_init(void);
q40ide_init();
}
#endif /* CONFIG_BLK_DEV_Q40IDE */
#ifdef CONFIG_BLK_DEV_BUDDHA
{
extern void buddha_init(void);
buddha_init();
}
#endif /* CONFIG_BLK_DEV_BUDDHA */
#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP)
{
extern void pnpide_init(int enable);
pnpide_init(1);
}
#endif /* CONFIG_BLK_DEV_ISAPNP */
}
void __init ide_init_builtin_drivers (void)
{
/*
* Probe for special PCI and other "known" interface chipsets
*/
probe_for_hwifs ();
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULES)
# if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
ide_get_lock(&ide_intr_lock, NULL, NULL);/* for atari only */
disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */
// disable_irq_nosync(ide_hwifs[0].irq);
}
# endif
ideprobe_init();
# if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
enable_irq(ide_hwifs[0].irq);
ide_release_lock(&ide_intr_lock);/* for atari only */
}
# endif
#endif
#ifdef CONFIG_PROC_FS
proc_ide_create();
#endif
/*
* Initialize all device type driver modules.
*/
#ifdef CONFIG_BLK_DEV_IDEDISK
idedisk_init();
#endif
#ifdef CONFIG_BLK_DEV_IDECD
ide_cdrom_init();
#endif
#ifdef CONFIG_BLK_DEV_IDETAPE
idetape_init();
#endif
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
idefloppy_init();
#endif
#ifdef CONFIG_BLK_DEV_IDESCSI
#ifdef CONFIG_SCSI
idescsi_init();
#else
#warning ide scsi-emulation selected but no SCSI-subsystem in kernel
#endif
#endif
}
/* This is the default end request function as well */ /* This is the default end request function as well */
int ide_end_request(ide_drive_t *drive, int uptodate) int ide_end_request(ide_drive_t *drive, int uptodate)
{ {
...@@ -3518,7 +3345,7 @@ int ide_end_request(ide_drive_t *drive, int uptodate) ...@@ -3518,7 +3345,7 @@ int ide_end_request(ide_drive_t *drive, int uptodate)
} }
/* /*
* Lookup IDE devices, which requested a particular deriver * Lookup IDE devices, which requested a particular driver
*/ */
ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n) ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
{ {
...@@ -3787,7 +3614,103 @@ static int __init ata_module_init(void) ...@@ -3787,7 +3614,103 @@ static int __init ata_module_init(void)
initializing = 1; initializing = 1;
ide_init_builtin_drivers(); /*
* Detect and initialize "known" IDE host chip types.
*/
#ifdef CONFIG_PCI
if (pci_present()) {
# ifdef CONFIG_BLK_DEV_IDEPCI
ide_scan_pcibus(ide_scan_direction);
# else
# ifdef CONFIG_BLK_DEV_RZ1000
ide_probe_for_rz100x();
# endif
# endif
}
#endif
#ifdef CONFIG_ETRAX_IDE
init_e100_ide();
#endif
#ifdef CONFIG_BLK_DEV_CMD640
ide_probe_for_cmd640x();
#endif
#ifdef CONFIG_BLK_DEV_PDC4030
ide_probe_for_pdc4030();
#endif
#ifdef CONFIG_BLK_DEV_IDE_PMAC
pmac_ide_probe();
#endif
#ifdef CONFIG_BLK_DEV_IDE_ICSIDE
icside_init();
#endif
#ifdef CONFIG_BLK_DEV_IDE_RAPIDE
rapide_init();
#endif
#ifdef CONFIG_BLK_DEV_GAYLE
gayle_init();
#endif
#ifdef CONFIG_BLK_DEV_FALCON_IDE
falconide_init();
#endif
#ifdef CONFIG_BLK_DEV_MAC_IDE
macide_init();
#endif
#ifdef CONFIG_BLK_DEV_Q40IDE
q40ide_init();
#endif
#ifdef CONFIG_BLK_DEV_BUDDHA
buddha_init();
#endif
#if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP)
pnpide_init(1);
#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULES)
# if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
ide_get_lock(&ide_intr_lock, NULL, NULL);/* for atari only */
disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */
// disable_irq_nosync(ide_hwifs[0].irq);
}
# endif
ideprobe_init();
# if defined(__mc68000__) || defined(CONFIG_APUS)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
enable_irq(ide_hwifs[0].irq);
ide_release_lock(&ide_intr_lock);/* for atari only */
}
# endif
#endif
#ifdef CONFIG_PROC_FS
proc_ide_create();
#endif
/*
* Initialize all device type driver modules.
*/
#ifdef CONFIG_BLK_DEV_IDEDISK
idedisk_init();
#endif
#ifdef CONFIG_BLK_DEV_IDECD
ide_cdrom_init();
#endif
#ifdef CONFIG_BLK_DEV_IDETAPE
idetape_init();
#endif
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
idefloppy_init();
#endif
#ifdef CONFIG_BLK_DEV_IDESCSI
# ifdef CONFIG_SCSI
idescsi_init();
# else
#warning ATA SCSI emulation selected but no SCSI-subsystem in kernel
# endif
#endif
initializing = 0; initializing = 0;
......
/* /*
* linux/drivers/ide/opti621.c Version 0.6 Jan 02, 1999
*
* Copyright (C) 1996-1998 Linus Torvalds & authors (see below) * Copyright (C) 1996-1998 Linus Torvalds & authors (see below)
*/ *
/*
* Authors: * Authors:
* Jaromir Koutek <miri@punknet.cz>, * Jaromir Koutek <miri@punknet.cz>,
* Jan Harkes <jaharkes@cwi.nl>, * Jan Harkes <jaharkes@cwi.nl>,
...@@ -62,9 +58,9 @@ ...@@ -62,9 +58,9 @@
* by hdparm. * by hdparm.
* *
* Version 0.1, Nov 8, 1996 * Version 0.1, Nov 8, 1996
* by Jaromir Koutek, for 2.1.8. * by Jaromir Koutek, for 2.1.8.
* Initial version of driver. * Initial version of driver.
* *
* Version 0.2 * Version 0.2
* Number 0.2 skipped. * Number 0.2 skipped.
* *
...@@ -80,14 +76,13 @@ ...@@ -80,14 +76,13 @@
* by Jaromir Koutek * by Jaromir Koutek
* Updates for use with (again) new IDE block driver. * Updates for use with (again) new IDE block driver.
* Update of documentation. * Update of documentation.
* *
* Version 0.6, Jan 2, 1999 * Version 0.6, Jan 2, 1999
* by Jaromir Koutek * by Jaromir Koutek
* Reversed to version 0.3 of the driver, because * Reversed to version 0.3 of the driver, because
* 0.5 doesn't work. * 0.5 doesn't work.
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#define OPTI621_DEBUG /* define for debug messages */ #define OPTI621_DEBUG /* define for debug messages */
#include <linux/types.h> #include <linux/types.h>
......
/* /*
* linux/drivers/ide/qd65xx.c Version 0.07 Sep 30, 2001
*
* Copyright (C) 1996-2001 Linus Torvalds & author (see below) * Copyright (C) 1996-2001 Linus Torvalds & author (see below)
*/ */
...@@ -9,24 +7,20 @@ ...@@ -9,24 +7,20 @@
* Version 0.04 Added second channel tuning * Version 0.04 Added second channel tuning
* Version 0.05 Enhanced tuning ; added qd6500 support * Version 0.05 Enhanced tuning ; added qd6500 support
* Version 0.06 Added dos driver's list * Version 0.06 Added dos driver's list
* Version 0.07 Second channel bug fix * Version 0.07 Second channel bug fix
* *
* QDI QD6500/QD6580 EIDE controller fast support * QDI QD6500/QD6580 EIDE controller fast support
* *
* Please set local bus speed using kernel parameter idebus * Please set local bus speed using kernel parameter idebus
* for example, "idebus=33" stands for 33Mhz VLbus * for example, "idebus=33" stands for 33Mhz VLbus
* To activate controller support, use "ide0=qd65xx" * To activate controller support, use "ide0=qd65xx"
* To enable tuning, use "ide0=autotune" * To enable tuning, use "ide0=autotune"
* To enable second channel tuning (qd6580 only), use "ide1=autotune" * To enable second channel tuning (qd6580 only), use "ide1=autotune"
*/ *
/*
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
* Samuel Thibault <samuel.thibault@fnac.net> * Samuel Thibault <samuel.thibault@fnac.net>
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -262,7 +256,7 @@ static void qd6580_tune_drive (ide_drive_t *drive, byte pio) ...@@ -262,7 +256,7 @@ static void qd6580_tune_drive (ide_drive_t *drive, byte pio)
if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)) { if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)) {
pio = ide_get_best_pio_mode(drive, pio, 255, &d); pio = ide_get_best_pio_mode(drive, pio, 255, &d);
pio = IDE_MIN(pio,4); pio = min(pio,4);
switch (pio) { switch (pio) {
case 0: break; case 0: break;
......
/* /*
* linux/drivers/ide/rz1000.c Version 0.05 December 8, 1997
*
* Copyright (C) 1995-1998 Linus Torvalds & author (see below) * Copyright (C) 1995-1998 Linus Torvalds & author (see below)
*/ *
/*
* Principal Author: mlord@pobox.com (Mark Lord) * Principal Author: mlord@pobox.com (Mark Lord)
* *
* See linux/MAINTAINERS for address of current maintainer. * See linux/MAINTAINERS for address of current maintainer.
...@@ -15,8 +11,6 @@ ...@@ -15,8 +11,6 @@
* Dunno if this fixes both ports, or only the primary port (?). * Dunno if this fixes both ports, or only the primary port (?).
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */ #include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
......
...@@ -138,7 +138,7 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne ...@@ -138,7 +138,7 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
idescsi_discard_data (drive, bcount); idescsi_discard_data (drive, bcount);
return; return;
} }
count = IDE_MIN (pc->sg->length - pc->b_count, bcount); count = min(pc->sg->length - pc->b_count, bcount);
buf = page_address(pc->sg->page) + pc->sg->offset; buf = page_address(pc->sg->page) + pc->sg->offset;
atapi_input_bytes (drive, buf + pc->b_count, count); atapi_input_bytes (drive, buf + pc->b_count, count);
bcount -= count; pc->b_count += count; bcount -= count; pc->b_count += count;
...@@ -160,7 +160,7 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign ...@@ -160,7 +160,7 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
idescsi_output_zeros (drive, bcount); idescsi_output_zeros (drive, bcount);
return; return;
} }
count = IDE_MIN (pc->sg->length - pc->b_count, bcount); count = min(pc->sg->length - pc->b_count, bcount);
buf = page_address(pc->sg->page) + pc->sg->offset; buf = page_address(pc->sg->page) + pc->sg->offset;
atapi_output_bytes (drive, buf + pc->b_count, count); atapi_output_bytes (drive, buf + pc->b_count, count);
bcount -= count; pc->b_count += count; bcount -= count; pc->b_count += count;
...@@ -290,7 +290,7 @@ static int idescsi_end_request(ide_drive_t *drive, int uptodate) ...@@ -290,7 +290,7 @@ static int idescsi_end_request(ide_drive_t *drive, int uptodate)
if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) { if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
printk(", rst = "); printk(", rst = ");
scsi_buf = pc->scsi_cmd->request_buffer; scsi_buf = pc->scsi_cmd->request_buffer;
hexdump(scsi_buf, IDE_MIN(16, pc->scsi_cmd->request_bufflen)); hexdump(scsi_buf, min(16, pc->scsi_cmd->request_bufflen));
} else printk("\n"); } else printk("\n");
} }
} }
...@@ -307,7 +307,7 @@ static int idescsi_end_request(ide_drive_t *drive, int uptodate) ...@@ -307,7 +307,7 @@ static int idescsi_end_request(ide_drive_t *drive, int uptodate)
static inline unsigned long get_timeout(idescsi_pc_t *pc) static inline unsigned long get_timeout(idescsi_pc_t *pc)
{ {
return IDE_MAX(WAIT_CMD, pc->timeout - jiffies); return max(WAIT_CMD, pc->timeout - jiffies);
} }
/* /*
...@@ -431,7 +431,7 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -431,7 +431,7 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
scsi->pc=pc; /* Set the current packet command */ scsi->pc=pc; /* Set the current packet command */
pc->actually_transferred=0; /* We haven't transferred any data yet */ pc->actually_transferred=0; /* We haven't transferred any data yet */
pc->current_position=pc->buffer; pc->current_position=pc->buffer;
bcount = IDE_MIN (pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ bcount = min(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */
if (drive->using_dma && rq->bio) if (drive->using_dma && rq->bio)
dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
...@@ -613,9 +613,9 @@ int idescsi_detect (Scsi_Host_Template *host_template) ...@@ -613,9 +613,9 @@ int idescsi_detect (Scsi_Host_Template *host_template)
host = scsi_register(host_template, 0); host = scsi_register(host_template, 0);
if(host == NULL) if(host == NULL)
return 0; return 0;
for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++) for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++)
last_lun = IDE_MAX(last_lun, idescsi_drives[id]->last_lun); last_lun = max(last_lun, idescsi_drives[id]->last_lun);
host->max_id = id; host->max_id = id;
host->max_lun = last_lun + 1; host->max_lun = last_lun + 1;
host->can_queue = host->cmd_per_lun * id; host->can_queue = host->cmd_per_lun * id;
......
...@@ -146,8 +146,7 @@ void OUT_BYTE(unsigned char data, ide_ioreg_t reg); ...@@ -146,8 +146,7 @@ void OUT_BYTE(unsigned char data, ide_ioreg_t reg);
unsigned char IN_BYTE(ide_ioreg_t reg); unsigned char IN_BYTE(ide_ioreg_t reg);
/* this tells ide.h not to define the standard macros */ /* this tells ide.h not to define the standard macros */
#define HAVE_ARCH_OUT_BYTE #define HAVE_ARCH_IN_OUT 1
#define HAVE_ARCH_IN_BYTE
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
/* /*
* Command Header sizes for IOCTL commands * Command Header sizes for IOCTL commands
* HDIO_DRIVE_CMD, HDIO_DRIVE_TASK, and HDIO_DRIVE_TASKFILE * HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
*/ */
#if 0 #if 0
...@@ -355,7 +355,6 @@ struct hd_big_geometry { ...@@ -355,7 +355,6 @@ struct hd_big_geometry {
#define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */ #define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */
#define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */ #define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */
#define HDIO_DRIVE_RESET 0x031c /* execute a device reset */ #define HDIO_DRIVE_RESET 0x031c /* execute a device reset */
#define HDIO_DRIVE_TASKFILE 0x031d /* execute raw taskfile */
#define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */ #define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */
#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */ #define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
......
...@@ -28,10 +28,7 @@ ...@@ -28,10 +28,7 @@
/****************************************************************************** /******************************************************************************
* IDE driver configuration options (play with these as desired): * IDE driver configuration options (play with these as desired):
*
* REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary
*/ */
#undef REALLY_FAST_IO /* define if ide ports are perfect */
#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ #define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */
#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */ #ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */
...@@ -49,20 +46,12 @@ ...@@ -49,20 +46,12 @@
#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ #ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ #define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#endif #endif
#ifdef CONFIG_BLK_DEV_CMD640
# if 0 /* change to 1 when debugging cmd640 problems */
void cmd640_dump_regs (void);
# define CMD640_DUMP_REGS cmd640_dump_regs() /* for debugging cmd640 chipset */
# endif
#endif
#ifndef DISABLE_IRQ_NOSYNC #ifndef DISABLE_IRQ_NOSYNC
# define DISABLE_IRQ_NOSYNC 0 #define DISABLE_IRQ_NOSYNC 0
#endif #endif
/* /*
* "No user-serviceable parts" beyond this point :) * "No user-serviceable parts" beyond this point
*****************************************************************************/ *****************************************************************************/
typedef unsigned char byte; /* used everywhere */ typedef unsigned char byte; /* used everywhere */
...@@ -79,13 +68,6 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -79,13 +68,6 @@ typedef unsigned char byte; /* used everywhere */
*/ */
#define DMA_PIO_RETRY 1 /* retrying in PIO */ #define DMA_PIO_RETRY 1 /* retrying in PIO */
/*
* Ensure that various configuration flags have compatible settings
*/
#ifdef REALLY_SLOW_IO
# undef REALLY_FAST_IO
#endif
#define HWIF(drive) ((drive)->hwif) #define HWIF(drive) ((drive)->hwif)
#define HWGROUP(drive) (HWIF(drive)->hwgroup) #define HWGROUP(drive) (HWIF(drive)->hwgroup)
...@@ -180,33 +162,17 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -180,33 +162,17 @@ typedef unsigned char byte; /* used everywhere */
#define PARTN_BITS 6 /* number of minor dev bits for partitions */ #define PARTN_BITS 6 /* number of minor dev bits for partitions */
#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */ #define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */
#define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */ #define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */
#define CASCADE_DRIVES 8 /* per interface; 8|2 assumed by lots of code */
#define SECTOR_SIZE 512 #define SECTOR_SIZE 512
#define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */ #define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */
#define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
#define IDE_MIN(a,b) ((a)<(b) ? (a):(b))
#define IDE_MAX(a,b) ((a)>(b) ? (a):(b))
#ifndef SPLIT_WORD
# define SPLIT_WORD(W,HB,LB) ((HB)=(W>>8), (LB)=(W-((W>>8)<<8)))
#endif
#ifndef MAKE_WORD
# define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))
#endif
/* /*
* Timeouts for various operations: * Timeouts for various operations:
*/ */
#define WAIT_DRQ (5*HZ/100) /* 50msec - spec allows up to 20ms */ #define WAIT_DRQ (5*HZ/100) /* 50msec - spec allows up to 20ms */
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) #define WAIT_READY (5*HZ) /* 5sec - some laptops are very slow */
#define WAIT_READY (5*HZ) /* 5sec - some laptops are very slow */ #define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?), if all ATAPI CD is closed at boot */
#else #define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */
#define WAIT_READY (3*HZ/100) /* 30msec - should be instantaneous */ #define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */
#endif /* CONFIG_APM || CONFIG_APM_MODULE */
#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?), if all ATAPI CD is closed at boot */
#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */
#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */
#define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ #define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */
#define SELECT_DRIVE(hwif,drive) \ #define SELECT_DRIVE(hwif,drive) \
...@@ -216,40 +182,12 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -216,40 +182,12 @@ typedef unsigned char byte; /* used everywhere */
OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \ OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \
} }
#define SELECT_INTERRUPT(hwif,drive) \
{ \
if (hwif->intrproc) \
hwif->intrproc(drive); \
else \
OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]); \
}
#define SELECT_MASK(hwif,drive,mask) \ #define SELECT_MASK(hwif,drive,mask) \
{ \ { \
if (hwif->maskproc) \ if (hwif->maskproc) \
hwif->maskproc(drive,mask); \ hwif->maskproc(drive,mask); \
} }
#define SELECT_READ_WRITE(hwif,drive,func) \
{ \
if (hwif->rwproc) \
hwif->rwproc(drive,func); \
}
#define QUIRK_LIST(hwif,drive) \
{ \
if (hwif->quirkproc) \
(drive)->quirk_list = hwif->quirkproc(drive); \
}
#define HOST(hwif,chipset) \
{ \
return ((hwif)->chipset == chipset) ? 1 : 0; \
}
#define IDE_DEBUG(lineno) \
printk("%s,%s,line=%d\n", __FILE__, __FUNCTION__, (lineno))
/* /*
* Check for an interrupt and acknowledge the interrupt status * Check for an interrupt and acknowledge the interrupt status
*/ */
...@@ -257,19 +195,31 @@ struct hwif_s; ...@@ -257,19 +195,31 @@ struct hwif_s;
typedef int (ide_ack_intr_t)(struct hwif_s *); typedef int (ide_ack_intr_t)(struct hwif_s *);
#ifndef NO_DMA #ifndef NO_DMA
#define NO_DMA 255 # define NO_DMA 255
#endif #endif
/* /*
* hwif_chipset_t is used to keep track of the specific hardware * This is used to keep track of the specific hardware chipset used by each IDE
* chipset used by each IDE interface, if known. * interface, if known. Please note that we don't discriminate between
* different PCI host chips here.
*/ */
typedef enum { ide_unknown, ide_generic, ide_pci, typedef enum {
ide_cmd640, ide_dtc2278, ide_ali14xx, ide_unknown,
ide_qd65xx, ide_umc8672, ide_ht6560b, ide_generic,
ide_pdc4030, ide_rz1000, ide_trm290, ide_pci,
ide_cmd646, ide_cy82c693, ide_4drives, ide_cmd640,
ide_pmac, ide_etrax100 ide_dtc2278,
ide_ali14xx,
ide_qd65xx,
ide_umc8672,
ide_ht6560b,
ide_pdc4030,
ide_rz1000,
ide_trm290,
ide_cmd646,
ide_cy82c693,
ide_pmac,
ide_etrax100
} hwif_chipset_t; } hwif_chipset_t;
...@@ -297,7 +247,7 @@ int ide_register_hw(hw_regs_t *hw, struct hwif_s **hwifp); ...@@ -297,7 +247,7 @@ int ide_register_hw(hw_regs_t *hw, struct hwif_s **hwifp);
/* /*
* Set up hw_regs_t structure before calling ide_register_hw (optional) * Set up hw_regs_t structure before calling ide_register_hw (optional)
*/ */
void ide_setup_ports( hw_regs_t *hw, void ide_setup_ports(hw_regs_t *hw,
ide_ioreg_t base, ide_ioreg_t base,
int *offsets, int *offsets,
ide_ioreg_t ctrl, ide_ioreg_t ctrl,
...@@ -308,28 +258,16 @@ void ide_setup_ports( hw_regs_t *hw, ...@@ -308,28 +258,16 @@ void ide_setup_ports( hw_regs_t *hw,
#include <asm/ide.h> #include <asm/ide.h>
/* /*
* If the arch-dependant ide.h did not declare/define any OUT_BYTE * If the arch-dependant ide.h did not declare/define any OUT_BYTE or IN_BYTE
* or IN_BYTE functions, we make some defaults here. * functions, we make some defaults here. The only architecture currently
* needing this is Cris.
*/ */
#ifndef HAVE_ARCH_OUT_BYTE #ifndef HAVE_ARCH_IN_OUT
#ifdef REALLY_FAST_IO # define OUT_BYTE(b,p) outb((b),(p))
#define OUT_BYTE(b,p) outb((b),(p)) # define OUT_WORD(w,p) outw((w),(p))
#define OUT_WORD(w,p) outw((w),(p)) # define IN_BYTE(p) (u8)inb(p)
#else # define IN_WORD(p) (u16)inw(p)
#define OUT_BYTE(b,p) outb_p((b),(p))
#define OUT_WORD(w,p) outw_p((w),(p))
#endif
#endif
#ifndef HAVE_ARCH_IN_BYTE
#ifdef REALLY_FAST_IO
#define IN_BYTE(p) (byte)inb(p)
#define IN_WORD(p) (short)inw(p)
#else
#define IN_BYTE(p) (byte)inb_p(p)
#define IN_WORD(p) (short)inw_p(p)
#endif
#endif #endif
/* /*
...@@ -358,6 +296,7 @@ typedef union { ...@@ -358,6 +296,7 @@ typedef union {
struct ide_settings_s; struct ide_settings_s;
typedef struct ide_drive_s { typedef struct ide_drive_s {
unsigned int usage; /* current "open()" count for drive */
char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */ char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */
/* NOTE: If we had proper separation between channel and host chip, we /* NOTE: If we had proper separation between channel and host chip, we
...@@ -376,14 +315,14 @@ typedef struct ide_drive_s { ...@@ -376,14 +315,14 @@ typedef struct ide_drive_s {
byte using_dma; /* disk is using dma for read/write */ byte using_dma; /* disk is using dma for read/write */
byte retry_pio; /* retrying dma capable host in pio */ byte retry_pio; /* retrying dma capable host in pio */
byte state; /* retry state */ byte state; /* retry state */
byte waiting_for_dma; /* dma currently in progress */
byte unmask; /* flag: okay to unmask other irqs */ byte unmask; /* flag: okay to unmask other irqs */
byte slow; /* flag: slow data port */ byte slow; /* flag: slow data port */
byte bswap; /* flag: byte swap data */ byte bswap; /* flag: byte swap data */
byte dsc_overlap; /* flag: DSC overlap */ byte dsc_overlap; /* flag: DSC overlap */
byte nice1; /* flag: give potential excess bandwidth */ byte nice1; /* flag: give potential excess bandwidth */
unsigned waiting_for_dma: 1; /* dma currently in progress */
unsigned present : 1; /* drive is physically present */ unsigned present : 1; /* drive is physically present */
unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned noprobe : 1; /* from: hdx=noprobe */
unsigned busy : 1; /* currently doing revalidate_disk() */ unsigned busy : 1; /* currently doing revalidate_disk() */
unsigned removable : 1; /* 1 if need to do check_media_change */ unsigned removable : 1; /* 1 if need to do check_media_change */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
...@@ -410,7 +349,6 @@ typedef struct ide_drive_s { ...@@ -410,7 +349,6 @@ typedef struct ide_drive_s {
byte bad_wstat; /* used for ignoring WRERR_STAT */ byte bad_wstat; /* used for ignoring WRERR_STAT */
byte nowerr; /* used for ignoring WRERR_STAT */ byte nowerr; /* used for ignoring WRERR_STAT */
byte sect0; /* offset of first sector for DM6:DDO */ byte sect0; /* offset of first sector for DM6:DDO */
unsigned int usage; /* current "open()" count for drive */
byte head; /* "real" number of heads */ byte head; /* "real" number of heads */
byte sect; /* "real" sectors per track */ byte sect; /* "real" sectors per track */
byte bios_head; /* BIOS/fdisk/LILO number of heads */ byte bios_head; /* BIOS/fdisk/LILO number of heads */
...@@ -543,12 +481,12 @@ typedef struct hwif_s { ...@@ -543,12 +481,12 @@ typedef struct hwif_s {
unsigned long select_data; /* for use by chipset-specific code */ unsigned long select_data; /* for use by chipset-specific code */
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
int irq; /* our irq number */ int irq; /* our irq number */
byte major; /* our major number */ int major; /* our major number */
char name[80]; /* name of interface */ char name[80]; /* name of interface */
byte index; /* 0 for ide0; 1 for ide1; ... */ int index; /* 0 for ide0; 1 for ide1; ... */
hwif_chipset_t chipset; /* sub-module for tuning.. */ hwif_chipset_t chipset; /* sub-module for tuning.. */
unsigned noprobe : 1; /* don't probe for this interface */ unsigned noprobe : 1; /* don't probe for this interface */
unsigned present : 1; /* this interface exists */ unsigned present : 1; /* there is a device on this interface */
unsigned serialized : 1; /* serialized operation with mate hwif */ unsigned serialized : 1; /* serialized operation with mate hwif */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
unsigned reset : 1; /* reset after probe */ unsigned reset : 1; /* reset after probe */
...@@ -909,15 +847,7 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct ...@@ -909,15 +847,7 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct
*/ */
ide_startstop_t set_multmode_intr (ide_drive_t *drive); ide_startstop_t set_multmode_intr (ide_drive_t *drive);
ide_startstop_t set_geometry_intr (ide_drive_t *drive);
ide_startstop_t recal_intr (ide_drive_t *drive);
ide_startstop_t task_no_data_intr (ide_drive_t *drive); ide_startstop_t task_no_data_intr (ide_drive_t *drive);
ide_startstop_t task_in_intr (ide_drive_t *drive);
ide_startstop_t task_mulin_intr (ide_drive_t *drive);
ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq);
ide_startstop_t task_out_intr (ide_drive_t *drive);
ide_startstop_t task_mulout_intr (ide_drive_t *drive);
void ide_init_drive_taskfile (struct request *rq);
int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf); int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf);
...@@ -928,14 +858,9 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h ...@@ -928,14 +858,9 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h
/* Expects args is a full set of TF registers and parses the command type */ /* Expects args is a full set of TF registers and parses the command type */
int ide_cmd_type_parser (ide_task_t *args); int ide_cmd_type_parser (ide_task_t *args);
int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
#ifdef CONFIG_PKT_TASK_IOCTL
int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
#endif /* CONFIG_PKT_TASK_IOCTL */
void ide_delay_50ms (void); void ide_delay_50ms (void);
byte ide_auto_reduce_xfer (ide_drive_t *drive); byte ide_auto_reduce_xfer (ide_drive_t *drive);
...@@ -962,14 +887,16 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout); ...@@ -962,14 +887,16 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout);
/* /*
* ide_get_queue() returns the queue which corresponds to a given device. * ide_get_queue() returns the queue which corresponds to a given device.
*/ */
request_queue_t *ide_get_queue (kdev_t dev); request_queue_t *ide_get_queue(kdev_t dev);
/* /*
* CompactFlash cards and their brethern pretend to be removable hard disks, * CompactFlash cards and their brethern pretend to be removable hard disks,
* but they never have a slave unit, and they don't have doorlock mechanisms. * but they never have a slave unit, and they don't have doorlock mechanisms.
* This test catches them, and is invoked elsewhere when setting appropriate config bits. * This test catches them, and is invoked elsewhere when setting appropriate
* config bits.
*/ */
int drive_is_flashcard (ide_drive_t *drive);
extern int drive_is_flashcard(ide_drive_t *drive);
int ide_spin_wait_hwgroup (ide_drive_t *drive); int ide_spin_wait_hwgroup (ide_drive_t *drive);
void ide_timer_expiry (unsigned long data); void ide_timer_expiry (unsigned long data);
...@@ -1009,26 +936,23 @@ extern int ide_unregister_subdriver(ide_drive_t *drive); ...@@ -1009,26 +936,23 @@ extern int ide_unregister_subdriver(ide_drive_t *drive);
#define ON_BOARD 1 #define ON_BOARD 1
#define NEVER_BOARD 0 #define NEVER_BOARD 0
#ifdef CONFIG_BLK_DEV_OFFBOARD #ifdef CONFIG_BLK_DEV_OFFBOARD
# define OFF_BOARD ON_BOARD # define OFF_BOARD ON_BOARD
#else /* CONFIG_BLK_DEV_OFFBOARD */ #else
# define OFF_BOARD NEVER_BOARD # define OFF_BOARD NEVER_BOARD
#endif /* CONFIG_BLK_DEV_OFFBOARD */ #endif
void __init ide_scan_pcibus(int scan_direction); void __init ide_scan_pcibus(int scan_direction);
#endif #endif
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
#define BAD_DMA_DRIVE 0 # define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1 # define GOOD_DMA_DRIVE 1
int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func); int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func);
void ide_destroy_dmatable (ide_drive_t *drive); void ide_destroy_dmatable (ide_drive_t *drive);
ide_startstop_t ide_dma_intr (ide_drive_t *drive); ide_startstop_t ide_dma_intr (ide_drive_t *drive);
int check_drive_lists (ide_drive_t *drive, int good_bad); int check_drive_lists (ide_drive_t *drive, int good_bad);
int report_drive_dmaing (ide_drive_t *drive);
int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive); int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
int ide_release_dma (ide_hwif_t *hwif); int ide_release_dma (ide_hwif_t *hwif);
void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init; void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init;
/* FIXME spilt this up into a get and set function */
extern unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init;
#endif #endif
extern spinlock_t ide_lock; extern spinlock_t ide_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment