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
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
......
......@@ -94,8 +94,6 @@
* 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/types.h>
#include <linux/kernel.h>
......
......@@ -252,7 +252,6 @@ CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
......
......@@ -285,7 +285,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_IDEDMA_ONLYDISK=y
CONFIG_BLK_DEV_IDEDMA=y
......
......@@ -581,13 +581,6 @@ CONFIG_IDE_CHIPSETS
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
This driver is enabled at runtime using the "ide0=ali14xx" kernel
boot parameter. It enables support for the secondary IDE interface
......@@ -807,11 +800,6 @@ CONFIG_IDEDISK_STROKE
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
This is used if you know your ATAPI Devices are going to fail DMA
Transfers.
......
......@@ -45,7 +45,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
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 ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
......@@ -141,7 +140,6 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS
if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
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 ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278
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)
*/
......@@ -37,8 +35,6 @@
* 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/kernel.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)
*/
/*
* 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.
*
......@@ -98,7 +96,6 @@
* (patch courtesy of Zoltan Hidvegi)
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#define CMD640_PREFETCH_MASKS 1
#include <linux/config.h>
......
......@@ -238,7 +238,7 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
*/
if (channel) {
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);
}
......
/*
* linux/drivers/ide/dtc2278.c Version 0.02 Feb 10, 1996
*
* Copyright (C) 1996 Linus Torvalds & author (see below)
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.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)
*/
/*
*
* Version 0.01 Initial version hacked out of ide.c
*
......@@ -36,8 +31,6 @@
#define HT6560B_VERSION "v0.07"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
......
......@@ -1633,6 +1633,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
return startstop;
}
#define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
/****************************************************************************
* 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)
*/
/*
*
* Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org>
......@@ -34,8 +30,6 @@
#define IDEDISK_VERSION "1.13"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
......@@ -720,7 +714,7 @@ static int get_smart_values(ide_drive_t *drive, byte *buf)
taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART;
(void) smart_enable(drive);
smart_enable(drive);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
}
......@@ -735,7 +729,7 @@ static int get_smart_thresholds(ide_drive_t *drive, byte *buf)
taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART;
(void) smart_enable(drive);
smart_enable(drive);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
}
......@@ -844,7 +838,7 @@ static int write_cache (ide_drive_t *drive, int arg)
if (!(drive->id->cfs_enable_2 & 0x3000))
return 1;
(void) ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
drive->wcache = arg;
return 0;
}
......@@ -870,7 +864,7 @@ static int set_acoustic (ide_drive_t *drive, int arg)
taskfile.sector_count = arg;
taskfile.command = WIN_SETFEATURES;
(void) ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
drive->acoustic = arg;
return 0;
}
......
/*
* linux/drivers/ide/ide-dma.c Version 4.10 June 9, 2000
*
* Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*/
......@@ -15,7 +13,7 @@
/*
* This module provides support for the bus-master IDE DMA functions
* 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)
* ("PIIX" stands for "PCI ISA IDE Xcellerator").
*
......@@ -73,8 +71,6 @@
* check_drive_lists(ide_drive_t *drive, int good_bad)
*
* 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>
......@@ -426,7 +422,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad)
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;
......@@ -606,7 +602,10 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_read:
reading = 1 << 3;
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)))
return 1; /* try PIO instead of DMA */
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)
return 0;
#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
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 */
#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
#endif
if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
(drive->addressing == 1)) {
ide_task_t *args = HWGROUP(drive)->rq->special;
......@@ -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)
{
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
dma_alloc_failure:
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
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);
bcount.all = min(pc->request_transfer, 63 * 1024);
#ifdef CONFIG_BLK_DEV_IDEDMA
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) 1995-1998 Mark Lord
*
* 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);
#endif
typedef struct ide_pci_enablebit_s {
byte reg; /* byte pci reg holding the enable-bit */
byte mask; /* mask to isolate the enable-bit */
byte val; /* value of masked reg when "enabled" */
u8 reg; /* pci configuration register holding the enable-bit */
u8 mask; /* mask used to isolate the enable-bit */
u8 val; /* expected value of masked register when "enabled" */
} ide_pci_enablebit_t;
/* Flags used to untangle quirk handling.
......@@ -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 },
# 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 },
/* Promise used a different PCI ident for the raid card apparently to try and
prevent Linux detecting it and using our own raid code. We want to detect
it for the ataraid drivers, so we have to list both here.. */
/* Promise used a different PCI identification for the raid card
* apparently to try and prevent Linux detecting it and using our own
* 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_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 },
......@@ -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 }};
/*
* 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,
* 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
* Match a PCI IDE port against an entry in ide_hwifs[],
* 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;
ide_hwif_t *hwif;
......@@ -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)
{
byte reg, progif = 0;
u8 reg;
u8 progif = 0;
/*
* 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)
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.
*
* 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,
ide_pci_device_t *d,
......@@ -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) {
hwif->irq = hwif->channel ? 15 : 14;
hwif->irq = port ? 15 : 14;
goto no_dma;
}
if (d->flags & ATA_F_NODMA)
......@@ -543,53 +644,22 @@ static int __init setup_host_channel(struct pci_dev *dev,
if (d->ata66_check)
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)) {
/*
* 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 /* 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);
}
}
#ifdef CONFIG_BLK_DEV_IDEDMA
setup_channel_dma(hwif, dev, d, port, class_rev, pciirq, mate, autodma, pcicmd);
#endif
no_dma:
if (d->init_hwif) /* Call chipset-specific routine for each enabled hwif */
d->init_hwif(hwif);
*mate = hwif;
/* we are done */
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
* works for most PCI chipsets.
*
......@@ -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? */
/*
* 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
* (or possibly the device is using a "legacy header" for IRQs).
* Maybe the user deliberately *disabled* the device,
* but we'll eventually ignore it again if no drives respond.
* but we can do it ourselves, so long as the BIOS has assigned
* an IRQ (or possibly the device is using a "legacy header"
* for IRQs). Maybe the user deliberately *disabled* the
* device, but we'll eventually ignore it again if no drives
* respond.
*/
if (tried_config++
|| 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)
if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) {
/* By rights we want to ignore these, but the Promise Fastrak
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 */
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");
......@@ -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)) {
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
* space, place chipset into init-mode, and/or preserve
* 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)
else
pciirq = trust_pci_irq(d, dev);
} else if (tried_config) {
printk("%s: will probe irqs later\n", dev->name);
printk("%s: will probe IRQs later\n", dev->name);
pciirq = 0;
} 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;
} else {
if (d->init_chipset)
......@@ -732,7 +803,8 @@ static void __init pdc20270_device_order_fixup (struct pci_dev *dev, ide_pci_dev
if ((findev->vendor == dev->vendor) &&
(findev->device == dev->device) &&
(PCI_SLOT(findev->devfn) & 2)) {
byte irq = 0, irq2 = 0;
u8 irq = 0;
u8 irq2 = 0;
dev2 = findev;
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
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
}
/*
* This finds all PCI IDE controllers and calls appriopriate initialization
* This finds all PCI IDE controllers and calls appropriate initialization
* functions for them.
*/
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)
*/
/*
*
* Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org>
......@@ -26,11 +22,9 @@
* with new flag : drive->ata_flash : 1;
* Version 1.06 stream line request queue and prep for cascade project.
* 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/module.h>
#include <linux/types.h>
......@@ -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);
goto err_misc;
}
#endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */
#endif
/*
* WIN_IDENTIFY returns little-endian info,
......@@ -128,7 +122,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
printk(" -- not supported on 2nd Promise port\n");
goto err_misc;
}
#endif /* CONFIG_BLK_DEV_PDC4030 */
#endif
switch (type) {
case ATA_FLOPPY:
if (!strstr(id->model, "CD-ROM")) {
......@@ -186,7 +180,11 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
}
drive->type = ATA_DISK;
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;
err_misc:
......@@ -282,24 +280,15 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
if (autoprobe) {
int irq;
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
(void) GET_STAT(); /* clear drive IRQ */
OUT_BYTE(drive->ctl | 0x02, IDE_CONTROL_REG); /* mask device irq */
GET_STAT(); /* clear drive IRQ */
udelay(5);
irq = probe_irq_off(cookie);
if (!HWIF(drive)->irq) {
if (irq > 0) {
if (irq > 0)
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);
#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;
......@@ -522,11 +511,11 @@ static void probe_hwif (ide_hwif_t *hwif)
if (hwif->noprobe)
return;
if ((hwif->chipset != ide_4drives || !hwif->mate->present) &&
if (
#if CONFIG_BLK_DEV_PDC4030
(hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
#endif /* CONFIG_BLK_DEV_PDC4030 */
(hwif_check_regions(hwif))) {
#endif
hwif_check_regions(hwif)) {
int msgout = 0;
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
......@@ -552,9 +541,7 @@ static void probe_hwif (ide_hwif_t *hwif)
probe_for_drive (drive);
if (drive->present && !hwif->present) {
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) {
......@@ -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
*/
......@@ -636,6 +597,33 @@ static void ide_init_queue(ide_drive_t *drive)
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
* hwgroup for the irq/hwif if none was previously assigned.
......@@ -656,15 +644,14 @@ static int init_irq (ide_hwif_t *hwif)
ide_hwgroup_t *hwgroup, *new_hwgroup;
ide_hwif_t *match = NULL;
/* Allocate the buffer and potentially sleep first */
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;
#if MAX_HWIFS > 1
/*
* Group up with any other hwifs that share our irq(s).
......@@ -674,9 +661,8 @@ static int init_irq (ide_hwif_t *hwif)
if (h->hwgroup) { /* scan only initialized hwif's */
if (hwif->irq == h->irq) {
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);
}
}
if (hwif->serialized) {
if (hwif->mate && hwif->mate->irq == h->irq)
......@@ -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
*/
......@@ -699,7 +685,7 @@ static int init_irq (ide_hwif_t *hwif)
} else {
hwgroup = new_hwgroup;
if (!hwgroup) {
restore_flags(flags); /* all CPUs */
spin_unlock_irqrestore(&ide_lock, flags);
return 1;
}
memset(hwgroup, 0, sizeof(ide_hwgroup_t));
......@@ -719,9 +705,9 @@ static int init_irq (ide_hwif_t *hwif)
if (!match || match->irq != hwif->irq) {
#ifdef CONFIG_IDEPCI_SHARE_IRQ
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;
#endif /* CONFIG_IDEPCI_SHARE_IRQ */
#endif
if (hwif->io_ports[IDE_CONTROL_OFFSET])
OUT_BYTE(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */
......@@ -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 (!match)
kfree(hwgroup);
restore_flags(flags); /* all CPUs */
spin_unlock_irqrestore(&ide_lock, flags);
return 1;
}
}
/*
* Everything is okay, so link us into the hwgroup
* Everything is okay, so link us into the hwgroup.
*/
hwif->hwgroup = hwgroup;
hwif->next = hwgroup->hwif->next;
......@@ -757,7 +743,7 @@ static int init_irq (ide_hwif_t *hwif)
printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);
#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__)
printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
......
......@@ -161,7 +161,6 @@ static int proc_ide_read_imodel
case ide_trm290: name = "trm290"; break;
case ide_cmd646: name = "cmd646"; break;
case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
default: name = "(unknown)"; break;
}
......@@ -298,8 +297,8 @@ static int proc_ide_write_settings
}
if (*p != ':')
goto parse_error;
len = IDE_MIN(p - start, MAX_LEN);
strncpy(name, start, IDE_MIN(len, MAX_LEN));
len = min(p - start, MAX_LEN);
strncpy(name, start, min(len, MAX_LEN));
name[len] = 0;
if (n > 0) {
......@@ -307,7 +306,7 @@ static int proc_ide_write_settings
p++;
} else
goto parse_error;
digits = 0;
while (n > 0 && (d = ide_getdigit(*p)) >= 0) {
val = (val * 10) + d;
......
......@@ -1504,7 +1504,7 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne
return;
}
#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);
bcount -= count;
pc->b_count += bio->bi_size;
......@@ -1529,7 +1529,7 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign
return;
}
#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);
bcount -= count;
pc->b_data += count;
......@@ -1559,7 +1559,7 @@ static void idetape_update_buffers (idetape_pc_t *pc)
return;
}
#endif /* IDETAPE_DEBUG_BUGS */
count = IDE_MIN (bio->bi_size, bcount);
count = min(bio->bi_size, bcount);
pc->b_count = count;
if (pc->b_count == bio->bi_size)
bio = bio->bi_next;
......@@ -1759,8 +1759,8 @@ static void idetape_increase_max_pipeline_stages (ide_drive_t *drive)
#endif /* IDETAPE_DEBUG_LOG */
tape->max_stages += increase;
tape->max_stages = IDE_MAX(tape->max_stages, tape->min_pipeline);
tape->max_stages = IDE_MIN(tape->max_stages, tape->max_pipeline);
tape->max_stages = max(tape->max_stages, tape->min_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)
if (!status.b.drq) { /* No more interrupts */
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 (tape->debug_level >= 2)
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)
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) {
tape->max_insert_speed = 5000;
} else if (tape->speed_control == 1) {
......@@ -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;
} else
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)
......@@ -2920,7 +2920,7 @@ static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t
return;
}
#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);
n -= count;
bio->bi_size += count;
......@@ -2946,7 +2946,7 @@ static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape
return;
}
#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);
n -= count;
tape->b_data += count;
......@@ -3878,7 +3878,7 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
printk(KERN_INFO "ide-tape: bug, bio NULL\n");
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);
atomic_add(min, &bio->bi_cnt);
i -= min;
......@@ -4149,11 +4149,11 @@ static void idetape_pad_zeros (ide_drive_t *drive, int bcount)
while (bcount) {
bio = tape->merge_stage->bio;
count = IDE_MIN (tape->stage_size, bcount);
count = min(tape->stage_size, bcount);
bcount -= count;
blocks = count / tape->tape_block_size;
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);
count -= atomic_read(&bio->bi_cnt);
bio = bio->bi_next;
......@@ -4596,7 +4596,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char *buf,
if (count == 0)
return (0);
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);
buf += actually_read;
tape->merge_stage_size -= actually_read;
......@@ -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);
if (bytes_read <= 0)
goto finish;
temp = IDE_MIN (count, bytes_read);
temp = min(count, bytes_read);
idetape_copy_stage_to_user (tape, buf, tape->merge_stage, temp);
actually_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,
tape->merge_stage_size = 0;
}
#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);
buf += 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)
* Select the "best" DSC read/write polling frequency
* 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;
......@@ -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
* 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",
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,
......
/*
* linux/drivers/ide/ide-taskfile.c Version 0.20 Oct 11, 2000
*
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
*
* May be copied or modified under the terms of the GNU General Public License
*
* IDE_DEBUG(__LINE__);
*/
#include <linux/config.h>
......@@ -48,7 +44,7 @@
static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
{
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
return rq->buffer + task_rq_offset(rq);
}
......@@ -60,13 +56,6 @@ static inline void ide_unmap_rq(struct request *rq, char *to,
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)
{
u16 *p = buffer;
......@@ -85,12 +74,13 @@ static void ata_bswap_data (void *buffer, int wcount)
* of the sector count register location, with interrupts disabled
* to ensure that the reads all happen together.
*/
static inline void task_vlb_sync (ide_ioreg_t port) {
(void) IN_BYTE (port);
(void) IN_BYTE (port);
(void) IN_BYTE (port);
static inline void task_vlb_sync(ide_ioreg_t port)
{
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
......@@ -121,7 +111,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
insl(IDE_DATA_REG, buffer, wcount);
__restore_flags(flags); /* local CPU only */
} else
#endif /* SUPPORT_VLB_SYNC */
#endif
insl(IDE_DATA_REG, buffer, wcount);
} else {
#if SUPPORT_SLOW_DATA_PORTS
......@@ -132,7 +122,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
*ptr++ = inw_p(IDE_DATA_REG);
}
} else
#endif /* SUPPORT_SLOW_DATA_PORTS */
#endif
insw(IDE_DATA_REG, buffer, wcount<<1);
}
}
......@@ -161,7 +151,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
outsl(IDE_DATA_REG, buffer, wcount);
__restore_flags(flags); /* local CPU only */
} else
#endif /* SUPPORT_VLB_SYNC */
#endif
outsl(IDE_DATA_REG, buffer, wcount);
} else {
#if SUPPORT_SLOW_DATA_PORTS
......@@ -172,7 +162,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
outw_p(*ptr++, IDE_DATA_REG);
}
} else
#endif /* SUPPORT_SLOW_DATA_PORTS */
#endif
outsw(IDE_DATA_REG, buffer, wcount<<1);
}
}
......@@ -273,7 +263,90 @@ int drive_is_ready (ide_drive_t *drive)
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)
{
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)
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
* 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.
*/
......@@ -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
*/
/*
* 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)
{
......@@ -680,15 +455,15 @@ ide_startstop_t set_multmode_intr (ide_drive_t *drive)
} else {
drive->mult_req = drive->mult_count = 0;
drive->special.b.recalibrate = 1;
(void) ide_dump_status(drive, "set_multmode", stat);
ide_dump_status(drive, "set_multmode", stat);
}
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;
......@@ -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();
......@@ -736,7 +511,7 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive)
/*
* 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 io_32bit = drive->io_32bit;
......@@ -751,7 +526,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
if (!(stat & BUSY_STAT)) {
DTF("task_in_intr to Soon wait for next interrupt\n");
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started;
return ide_started;
}
}
DTF("stat: %02x\n", stat);
......@@ -772,139 +547,12 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
}
} else {
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started;
}
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;
return ide_started;
}
return ide_stopped;
}
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_startstop_t startstop;
......@@ -924,21 +572,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
rq->current_nr_sectors--;
ide_unmap_rq(rq, buf, &flags);
} else {
/*
* (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;
}
}
ata_poll_drive_ready(drive);
return args->handler(drive);
}
return ide_started;
......@@ -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
*/
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 io_32bit = drive->io_32bit;
......@@ -978,98 +612,7 @@ ide_startstop_t task_out_intr (ide_drive_t *drive)
return ide_started;
}
/*
* 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)
static ide_startstop_t pre_bio_out_intr(ide_drive_t *drive, struct request *rq)
{
ide_task_t *args = rq->special;
ide_startstop_t startstop;
......@@ -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))
return startstop;
/*
* (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;
}
}
ata_poll_drive_ready(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();
#endif /* ALTSTAT_SCREW_UP */
byte io_32bit = drive->io_32bit;
struct request *rq = &HWGROUP(drive)->wrq;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
......@@ -1147,8 +670,8 @@ ide_startstop_t bio_mulout_intr (ide_drive_t *drive)
}
do {
char *buffer;
int nsect = rq->current_nr_sectors;
char *buffer;
int nsect = rq->current_nr_sectors;
unsigned long flags;
if (nsect > mcount)
......@@ -1221,6 +744,60 @@ ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile,
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 */
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
case WIN_QUEUED_SERVICE:
case WIN_PACKETCMD:
default:
return(NULL);
}
return NULL;
}
}
/* Called by ioctl to feature out type of command being called */
......@@ -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().
*/
void ide_init_drive_taskfile (struct request *rq)
static void ide_init_drive_taskfile (struct request *rq)
{
memset(rq, 0, sizeof(*rq));
rq->flags = REQ_DRIVE_TASKFILE;
......@@ -1463,7 +1040,7 @@ void ide_init_drive_taskfile (struct request *rq)
*
* 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;
ide_task_t args;
......@@ -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);
}
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;
ide_init_drive_taskfile(&rq);
......@@ -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);
}
#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
*
* reqtask.data_phase reqtask.req_cmd
* args.command_type args.handler
* args.command_type args.handler
*
* TASKFILE_P_OUT_DMAQ ?? ??
* TASKFILE_P_IN_DMAQ ?? ??
......@@ -1555,201 +1119,11 @@ char * ide_task_cmd_verbose (byte task)
* TASKFILE_IN IDE_DRIVE_TASK_IN task_in_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_INVALID
* IDE_DRIVE_TASK_SET_XFER task_no_data_intr
* 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
* kernel.
......@@ -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);
}
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;
byte args[4], *argbuf = args;
......@@ -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(task_read_24);
EXPORT_SYMBOL(ata_input_data);
EXPORT_SYMBOL(ata_output_data);
EXPORT_SYMBOL(atapi_input_bytes);
......@@ -1858,166 +1231,15 @@ EXPORT_SYMBOL(taskfile_input_data);
EXPORT_SYMBOL(taskfile_output_data);
EXPORT_SYMBOL(do_rw_taskfile);
EXPORT_SYMBOL(do_taskfile);
// EXPORT_SYMBOL(flagged_taskfile);
//EXPORT_SYMBOL(ide_end_taskfile);
EXPORT_SYMBOL(set_multmode_intr);
EXPORT_SYMBOL(set_geometry_intr);
EXPORT_SYMBOL(recal_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_raw_taskfile);
EXPORT_SYMBOL(ide_pre_handler_parser);
EXPORT_SYMBOL(ide_handler_parser);
EXPORT_SYMBOL(ide_cmd_type_parser);
EXPORT_SYMBOL(ide_taskfile_ioctl);
EXPORT_SYMBOL(ide_cmd_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)
*/
/*
*
* Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org>
......@@ -119,8 +117,6 @@
#define VERSION "7.0.0"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
......@@ -135,8 +131,8 @@
#include <linux/blkpg.h>
#include <linux/slab.h>
#ifndef MODULE
#include <linux/init.h>
#endif /* MODULE */
# include <linux/init.h>
#endif
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
......@@ -155,9 +151,52 @@
#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] = {
{ 70, 165, 600 }, /* PIO Mode 0 */
{ 50, 125, 383 }, /* PIO Mode 1 */
......@@ -174,7 +213,7 @@ const ide_pio_timings_t ide_pio_timings[6] = {
static struct ide_pio_info {
const char *name;
int pio;
} ide_pio_blacklist [] = {
} ide_pio_blacklist[] = {
/* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */
{ "Conner Peripherals 540MB - CFS540A", 3 },
......@@ -224,8 +263,8 @@ static struct ide_pio_info {
{ "ST3600A", 1 },
{ "ST3290A", 0 },
{ "ST3144A", 0 },
{ "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on */
/* drive) according to Seagates FIND-ATA program */
{ "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on
* drive) according to Seagates FIND-ATA program */
{ "QUANTUM ELS127A", 0 },
{ "QUANTUM ELS170A", 0 },
......@@ -238,7 +277,7 @@ static struct ide_pio_info {
{ "QUANTUM LIGHTNING 730A", 3 },
{ "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
{ "QUANTUM FIREBALL_640", 3 },
{ "QUANTUM FIREBALL_640", 3 },
{ "QUANTUM FIREBALL_1080", 3 },
{ "QUANTUM FIREBALL_1280", 3 },
{ NULL, 0 }
......@@ -247,34 +286,33 @@ static struct ide_pio_info {
/* default maximum number of failures */
#define IDE_DEFAULT_MAX_FAILURES 1
static int idebus_parameter; /* holds the "idebus=" parameter */
int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
static int initializing; /* set while initializing built-in drivers */
static int idebus_parameter; /* holds the "idebus=" parameter */
int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
static int initializing; /* set while initializing built-in drivers */
/*
* protects global structures etc, we want to split this into per-hwgroup
* instead.
* Protects access to global structures etc.
*/
spinlock_t ide_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
#ifdef CONFIG_BLK_DEV_IDEPCI
static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
#endif /* CONFIG_BLK_DEV_IDEPCI */
static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
#endif
#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.
*/
static int ide_intr_lock;
#endif /* __mc68000__ || CONFIG_APUS */
#endif
int noautodma = 0;
/*
* 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,
#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.
*/
static unsigned long read_timer (void)
......@@ -389,7 +427,7 @@ static unsigned long read_timer (void)
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
t = jiffies * 11932;
outb_p(0, 0x43);
outb_p(0, 0x43);
i = inb_p(0x40);
i |= inb(0x40) << 8;
__restore_flags(flags); /* local CPU only */
......@@ -476,7 +514,7 @@ static void __init init_ide_data (void)
return; /* already initialized */
magic_cookie = 0;
/* Initialise all interface structures */
/* Initialize all interface structures */
for (index = 0; index < MAX_HWIFS; ++index)
init_hwif_data(index);
......@@ -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
* (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.
*
* 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,
* 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).
......@@ -503,7 +543,8 @@ int drive_is_flashcard (ide_drive_t *drive)
struct hd_driveid *id = drive->id;
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 */
|| !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */
|| !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */
......@@ -681,8 +722,8 @@ void ide_geninit (ide_hwif_t *hwif)
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
* during an atapi drive reset operation. If the drive has not yet responded,
* 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,
* and we have not yet hit our maximum waiting time, then the timer is restarted
* for another 50ms.
*/
......@@ -755,7 +796,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
printk("\n");
#else
printk("failed\n");
#endif /* FANCY_STATUS_DUMPS */
#endif
}
}
hwgroup->poll_timeout = 0; /* done polling */
......@@ -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
* 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,
* (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.
*/
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)
hwif->resetproc(drive);
#endif /* OK_TO_RESET_CONTROLLER */
#endif
__restore_flags (flags); /* local CPU only */
return ide_started;
......@@ -1040,11 +1081,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
/* retry only "normal" I/O: */
if (!(rq->flags & REQ_CMD)) {
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);
return ide_stopped;
}
......@@ -1144,7 +1180,7 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by
byte stat;
int i;
unsigned long flags;
/* bail early if we've exceeded max_failures */
if (drive->max_failures && (drive->failures > drive->max_failures)) {
*startstop = ide_stopped;
......@@ -1190,39 +1226,13 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq
if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special;
if (!(args)) goto args_error;
if (!(args))
goto args_error;
#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
{
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,
do_taskfile(drive,
(struct hd_drive_task_hdr *)&args->tfRegister,
(struct hd_drive_hob_hdr *)&args->hobRegister,
args->handler);
// } else {
// return flagged_taskfile(drive, args);
// }
if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
(args->command_type == IDE_DRIVE_TASK_OUT)) &&
......@@ -1398,7 +1408,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
{
ide_drive_t *drive, *best;
repeat:
repeat:
best = NULL;
drive = hwgroup->drive;
do {
......@@ -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)((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;
}
} while ((drive = drive->next) != best);
......@@ -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,
* 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_hwif_t *hwif;
......@@ -1511,7 +1521,11 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
hwif = HWIF(drive);
if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) {
/* 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->drive = drive;
......@@ -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)
{
......@@ -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
* 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
*/
void ide_dma_timeout_retry(ide_drive_t *drive)
......@@ -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
* 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_drive_t *drive;
int index, unit;
int index;
int unit;
for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index];
......@@ -2013,7 +2028,7 @@ void revalidate_drives (void)
}
}
static void ide_probe_module (void)
static void ide_probe_module(void)
{
ideprobe_init();
revalidate_drives();
......@@ -2032,7 +2047,7 @@ static void ide_driver_module (void)
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;
......@@ -2050,29 +2065,31 @@ static int ide_open (struct inode * inode, struct file * filp)
#ifdef CONFIG_KMOD
if (drive->driver == NULL) {
char *module = NULL;
switch (drive->type) {
case ATA_DISK:
request_module("ide-disk");
module = "ide-disk";
break;
case ATA_ROM:
request_module("ide-cd");
module = "ide-cd";
break;
case ATA_TAPE:
request_module("ide-tape");
module = "ide-tape";
break;
case ATA_FLOPPY:
request_module("ide-floppy");
module = "ide-floppy";
break;
#if defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI)
case ATA_SCSI:
request_module("ide-scsi");
module = "ide-scsi";
break;
#endif
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)
sleep_on(&drive->wqueue);
++drive->usage;
......@@ -2083,7 +2100,7 @@ static int ide_open (struct inode * inode, struct file * filp)
return -ENODEV;
}
printk ("%s: driver not present\n", drive->name);
printk(KERN_INFO "%s: driver not present\n", drive->name);
drive->usage--;
return -ENXIO;
}
......@@ -2144,7 +2161,7 @@ static void hwif_unregister(ide_hwif_t *hwif)
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (hwif->io_ports[IDE_IRQ_OFFSET])
ide_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
#endif
}
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(drive))
goto abort;
} else {
} else
ide_unregister_subdriver(drive);
}
}
}
hwif->present = 0;
......@@ -2282,7 +2298,7 @@ void ide_unregister (unsigned int index)
hwif->gd = NULL;
}
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->tuneproc = old_hwif.tuneproc;
hwif->speedproc = old_hwif.speedproc;
......@@ -2303,14 +2319,14 @@ void ide_unregister (unsigned int index)
hwif->proc = old_hwif.proc;
#ifndef CONFIG_BLK_DEV_IDECS
hwif->irq = old_hwif.irq;
#endif /* CONFIG_BLK_DEV_IDECS */
#endif
hwif->major = old_hwif.major;
hwif->chipset = old_hwif.chipset;
hwif->autodma = old_hwif.autodma;
hwif->udma_four = old_hwif.udma_four;
#ifdef CONFIG_BLK_DEV_IDEPCI
hwif->pci_dev = old_hwif.pci_dev;
#endif /* CONFIG_BLK_DEV_IDEPCI */
#endif
hwif->straight8 = old_hwif.straight8;
abort:
restore_flags(flags); /* all CPUs */
......@@ -2356,7 +2372,7 @@ void ide_setup_ports ( hw_regs_t *hw,
* Register an IDE interface, specifing exactly the registers etc
* 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;
ide_hwif_t *hwif;
......@@ -2406,7 +2422,7 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp)
* Compatability function with existing drivers. If you want
* 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;
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)
/*
* 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.
*/
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,
drive->nice2 << IDE_NICE_2,
(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:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
......@@ -2795,28 +2793,15 @@ static int ide_ioctl (struct inode *inode, struct file *file,
spin_lock_irqsave(&ide_lock, flags);
if (hwgroup->handler != NULL) {
printk("%s: ide_set_handler: handler not null; %p\n", drive->name, hwgroup->handler);
(void) hwgroup->handler(drive);
// hwgroup->handler = NULL;
// hwgroup->expiry = NULL;
hwgroup->handler(drive);
hwgroup->timer.expires = jiffies + 0;;
del_timer(&hwgroup->timer);
}
spin_unlock_irqrestore(&ide_lock, flags);
#endif
(void) ide_do_reset(drive);
if (drive->suspend_reset) {
/*
* APM WAKE UP todo !!
* int nogoodpower = 1;
* while(nogoodpower) {
* check_power1() or check_power2()
* nogoodpower = 0;
* }
* HWIF(drive)->multiproc(drive);
*/
ide_do_reset(drive);
if (drive->suspend_reset)
return ide_revalidate_disk(inode->i_rdev);
}
return 0;
}
case BLKGETSIZE:
......@@ -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,
* to handle kernel "command line" strings beginning with "hdx="
* or "ide". Here is the complete set currently supported:
* This gets called VERY EARLY during initialization, to handle kernel "command
* line" strings beginning with "hdx=" or "ide".It gets called even before the
* 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".
* "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
* As for VLB, it is safest to not specify it.
*
* "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
* and "ctl" is assumed to be "base"+0x206
* "idex=base,ctl" : specify both base and ctl
......@@ -3057,8 +3044,8 @@ int __init ide_setup (char *s)
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
const char max_hwif = '0' + (MAX_HWIFS - 1);
if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */
return 0; /* driver and not us */
if (!strncmp(s, "hd=", 3)) /* hd= is for hd.c driver and not us */
return 0;
if (strncmp(s,"ide",3) &&
strncmp(s,"idebus",6) &&
......@@ -3076,7 +3063,7 @@ int __init ide_setup (char *s)
ide_doubler = 1;
return 1;
}
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
#endif
if (!strcmp(s, "ide=nodma")) {
printk("IDE: Prevented DMA\n");
......@@ -3208,8 +3195,8 @@ int __init ide_setup (char *s)
*/
const char *ide_words[] = {
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66",
"minus8", "minus9", "minus10",
"four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
"minus8", "minus9", "minus10", "minus11",
"qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
hw = s[3] - '0';
hwif = &ide_hwifs[hw];
i = match_parm(&s[4], ide_words, vals, 3);
......@@ -3284,18 +3271,7 @@ int __init ide_setup (char *s)
goto done;
}
#endif /* CONFIG_BLK_DEV_QD65XX */
#ifdef CONFIG_BLK_DEV_4DRIVES
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 -11: /* minus11 */
case -10: /* minus10 */
case -9: /* minus9 */
case -8: /* minus8 */
......@@ -3362,155 +3338,6 @@ int __init ide_setup (char *s)
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 */
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)
{
......@@ -3787,7 +3614,103 @@ static int __init ata_module_init(void)
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;
......
/*
* linux/drivers/ide/opti621.c Version 0.6 Jan 02, 1999
*
* Copyright (C) 1996-1998 Linus Torvalds & authors (see below)
*/
/*
*
* Authors:
* Jaromir Koutek <miri@punknet.cz>,
* Jan Harkes <jaharkes@cwi.nl>,
......@@ -62,9 +58,9 @@
* by hdparm.
*
* Version 0.1, Nov 8, 1996
* by Jaromir Koutek, for 2.1.8.
* by Jaromir Koutek, for 2.1.8.
* Initial version of driver.
*
*
* Version 0.2
* Number 0.2 skipped.
*
......@@ -80,14 +76,13 @@
* by Jaromir Koutek
* Updates for use with (again) new IDE block driver.
* Update of documentation.
*
*
* Version 0.6, Jan 2, 1999
* by Jaromir Koutek
* Reversed to version 0.3 of the driver, because
* 0.5 doesn't work.
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#define OPTI621_DEBUG /* define for debug messages */
#include <linux/types.h>
......
/*
* linux/drivers/ide/qd65xx.c Version 0.07 Sep 30, 2001
*
* Copyright (C) 1996-2001 Linus Torvalds & author (see below)
*/
......@@ -9,24 +7,20 @@
* Version 0.04 Added second channel tuning
* Version 0.05 Enhanced tuning ; added qd6500 support
* 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
*
* 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 enable tuning, use "ide0=autotune"
* To enable second channel tuning (qd6580 only), use "ide1=autotune"
*/
/*
*
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
* Samuel Thibault <samuel.thibault@fnac.net>
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
......@@ -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)) {
pio = ide_get_best_pio_mode(drive, pio, 255, &d);
pio = IDE_MIN(pio,4);
pio = min(pio,4);
switch (pio) {
case 0: break;
......
/*
* linux/drivers/ide/rz1000.c Version 0.05 December 8, 1997
*
* Copyright (C) 1995-1998 Linus Torvalds & author (see below)
*/
/*
*
* Principal Author: mlord@pobox.com (Mark Lord)
*
* See linux/MAINTAINERS for address of current maintainer.
......@@ -15,8 +11,6 @@
* 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/types.h>
#include <linux/kernel.h>
......
......@@ -138,7 +138,7 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
idescsi_discard_data (drive, bcount);
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;
atapi_input_bytes (drive, buf + 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
idescsi_output_zeros (drive, bcount);
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;
atapi_output_bytes (drive, buf + 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)
if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
printk(", rst = ");
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");
}
}
......@@ -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)
{
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)
scsi->pc=pc; /* Set the current packet command */
pc->actually_transferred=0; /* We haven't transferred any data yet */
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)
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)
host = scsi_register(host_template, 0);
if(host == NULL)
return 0;
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_lun = last_lun + 1;
host->can_queue = host->cmd_per_lun * id;
......
......@@ -146,8 +146,7 @@ void OUT_BYTE(unsigned char data, ide_ioreg_t reg);
unsigned char IN_BYTE(ide_ioreg_t reg);
/* this tells ide.h not to define the standard macros */
#define HAVE_ARCH_OUT_BYTE
#define HAVE_ARCH_IN_BYTE
#define HAVE_ARCH_IN_OUT 1
#endif /* __KERNEL__ */
......
......@@ -51,7 +51,7 @@
/*
* 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
......@@ -355,7 +355,6 @@ struct hd_big_geometry {
#define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */
#define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */
#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_CMD 0x031f /* execute a special drive command */
......
......@@ -28,10 +28,7 @@
/******************************************************************************
* 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.. */
#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */
......@@ -49,20 +46,12 @@
#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#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
# define DISABLE_IRQ_NOSYNC 0
#define DISABLE_IRQ_NOSYNC 0
#endif
/*
* "No user-serviceable parts" beyond this point :)
* "No user-serviceable parts" beyond this point
*****************************************************************************/
typedef unsigned char byte; /* used everywhere */
......@@ -79,13 +68,6 @@ typedef unsigned char byte; /* used everywhere */
*/
#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 HWGROUP(drive) (HWIF(drive)->hwgroup)
......@@ -180,33 +162,17 @@ typedef unsigned char byte; /* used everywhere */
#define PARTN_BITS 6 /* number of minor dev bits for partitions */
#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */
#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_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:
*/
#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 */
#else
#define WAIT_READY (3*HZ/100) /* 30msec - should be instantaneous */
#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_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 */
#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 SELECT_DRIVE(hwif,drive) \
......@@ -216,40 +182,12 @@ typedef unsigned char byte; /* used everywhere */
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) \
{ \
if (hwif->maskproc) \
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
*/
......@@ -257,19 +195,31 @@ struct hwif_s;
typedef int (ide_ack_intr_t)(struct hwif_s *);
#ifndef NO_DMA
#define NO_DMA 255
# define NO_DMA 255
#endif
/*
* hwif_chipset_t is used to keep track of the specific hardware
* chipset used by each IDE interface, if known.
* This is used to keep track of the specific hardware chipset used by each IDE
* interface, if known. Please note that we don't discriminate between
* different PCI host chips here.
*/
typedef enum { ide_unknown, ide_generic, ide_pci,
ide_cmd640, ide_dtc2278, ide_ali14xx,
ide_qd65xx, ide_umc8672, ide_ht6560b,
ide_pdc4030, ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100
typedef enum {
ide_unknown,
ide_generic,
ide_pci,
ide_cmd640,
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;
......@@ -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)
*/
void ide_setup_ports( hw_regs_t *hw,
void ide_setup_ports(hw_regs_t *hw,
ide_ioreg_t base,
int *offsets,
ide_ioreg_t ctrl,
......@@ -308,28 +258,16 @@ void ide_setup_ports( hw_regs_t *hw,
#include <asm/ide.h>
/*
* If the arch-dependant ide.h did not declare/define any OUT_BYTE
* or IN_BYTE functions, we make some defaults here.
* If the arch-dependant ide.h did not declare/define any OUT_BYTE or IN_BYTE
* functions, we make some defaults here. The only architecture currently
* needing this is Cris.
*/
#ifndef HAVE_ARCH_OUT_BYTE
#ifdef REALLY_FAST_IO
#define OUT_BYTE(b,p) outb((b),(p))
#define OUT_WORD(w,p) outw((w),(p))
#else
#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
#ifndef HAVE_ARCH_IN_OUT
# define OUT_BYTE(b,p) outb((b),(p))
# define OUT_WORD(w,p) outw((w),(p))
# define IN_BYTE(p) (u8)inb(p)
# define IN_WORD(p) (u16)inw(p)
#endif
/*
......@@ -358,6 +296,7 @@ typedef union {
struct ide_settings_s;
typedef struct ide_drive_s {
unsigned int usage; /* current "open()" count for drive */
char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */
/* NOTE: If we had proper separation between channel and host chip, we
......@@ -376,14 +315,14 @@ typedef struct ide_drive_s {
byte using_dma; /* disk is using dma for read/write */
byte retry_pio; /* retrying dma capable host in pio */
byte state; /* retry state */
byte waiting_for_dma; /* dma currently in progress */
byte unmask; /* flag: okay to unmask other irqs */
byte slow; /* flag: slow data port */
byte bswap; /* flag: byte swap data */
byte dsc_overlap; /* flag: DSC overlap */
byte nice1; /* flag: give potential excess bandwidth */
unsigned waiting_for_dma: 1; /* dma currently in progress */
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 removable : 1; /* 1 if need to do check_media_change */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
......@@ -410,7 +349,6 @@ typedef struct ide_drive_s {
byte bad_wstat; /* used for ignoring WRERR_STAT */
byte nowerr; /* used for ignoring WRERR_STAT */
byte sect0; /* offset of first sector for DM6:DDO */
unsigned int usage; /* current "open()" count for drive */
byte head; /* "real" number of heads */
byte sect; /* "real" sectors per track */
byte bios_head; /* BIOS/fdisk/LILO number of heads */
......@@ -543,12 +481,12 @@ typedef struct hwif_s {
unsigned long select_data; /* for use by chipset-specific code */
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
int irq; /* our irq number */
byte major; /* our major number */
char name[80]; /* name of interface */
byte index; /* 0 for ide0; 1 for ide1; ... */
int major; /* our major number */
char name[80]; /* name of interface */
int index; /* 0 for ide0; 1 for ide1; ... */
hwif_chipset_t chipset; /* sub-module for tuning.. */
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 sharing_irq: 1; /* 1 = sharing irq with another hwif */
unsigned reset : 1; /* reset after probe */
......@@ -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_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_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);
......@@ -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 */
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_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);
byte ide_auto_reduce_xfer (ide_drive_t *drive);
......@@ -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.
*/
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,
* 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);
void ide_timer_expiry (unsigned long data);
......@@ -1009,26 +936,23 @@ extern int ide_unregister_subdriver(ide_drive_t *drive);
#define ON_BOARD 1
#define NEVER_BOARD 0
#ifdef CONFIG_BLK_DEV_OFFBOARD
# define OFF_BOARD ON_BOARD
#else /* CONFIG_BLK_DEV_OFFBOARD */
# define OFF_BOARD NEVER_BOARD
#endif /* CONFIG_BLK_DEV_OFFBOARD */
# define OFF_BOARD ON_BOARD
#else
# define OFF_BOARD NEVER_BOARD
#endif
void __init ide_scan_pcibus(int scan_direction);
#endif
#ifdef CONFIG_BLK_DEV_IDEDMA
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
# define BAD_DMA_DRIVE 0
# define GOOD_DMA_DRIVE 1
int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func);
void ide_destroy_dmatable (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 report_drive_dmaing (ide_drive_t *drive);
int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
int ide_release_dma (ide_hwif_t *hwif);
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
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